52909 lines
No EOL
4.6 MiB
52909 lines
No EOL
4.6 MiB
/******/ (function(modules) { // webpackBootstrap
|
||
/******/ // The module cache
|
||
/******/ var installedModules = {};
|
||
/******/
|
||
/******/ // The require function
|
||
/******/ function __webpack_require__(moduleId) {
|
||
/******/
|
||
/******/ // Check if module is in cache
|
||
/******/ if(installedModules[moduleId]) {
|
||
/******/ return installedModules[moduleId].exports;
|
||
/******/ }
|
||
/******/ // Create a new module (and put it into the cache)
|
||
/******/ var module = installedModules[moduleId] = {
|
||
/******/ i: moduleId,
|
||
/******/ l: false,
|
||
/******/ exports: {}
|
||
/******/ };
|
||
/******/
|
||
/******/ // Execute the module function
|
||
/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
|
||
/******/
|
||
/******/ // Flag the module as loaded
|
||
/******/ module.l = true;
|
||
/******/
|
||
/******/ // Return the exports of the module
|
||
/******/ return module.exports;
|
||
/******/ }
|
||
/******/
|
||
/******/
|
||
/******/ // expose the modules object (__webpack_modules__)
|
||
/******/ __webpack_require__.m = modules;
|
||
/******/
|
||
/******/ // expose the module cache
|
||
/******/ __webpack_require__.c = installedModules;
|
||
/******/
|
||
/******/ // define getter function for harmony exports
|
||
/******/ __webpack_require__.d = function(exports, name, getter) {
|
||
/******/ if(!__webpack_require__.o(exports, name)) {
|
||
/******/ Object.defineProperty(exports, name, {
|
||
/******/ configurable: false,
|
||
/******/ enumerable: true,
|
||
/******/ get: getter
|
||
/******/ });
|
||
/******/ }
|
||
/******/ };
|
||
/******/
|
||
/******/ // getDefaultExport function for compatibility with non-harmony modules
|
||
/******/ __webpack_require__.n = function(module) {
|
||
/******/ var getter = module && module.__esModule ?
|
||
/******/ function getDefault() { return module['default']; } :
|
||
/******/ function getModuleExports() { return module; };
|
||
/******/ __webpack_require__.d(getter, 'a', getter);
|
||
/******/ return getter;
|
||
/******/ };
|
||
/******/
|
||
/******/ // Object.prototype.hasOwnProperty.call
|
||
/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
|
||
/******/
|
||
/******/ // __webpack_public_path__
|
||
/******/ __webpack_require__.p = "";
|
||
/******/
|
||
/******/ // Load entry module and return exports
|
||
/******/ return __webpack_require__(__webpack_require__.s = 5);
|
||
/******/ })
|
||
/************************************************************************/
|
||
/******/ ([
|
||
/* 0 */
|
||
/***/ (function(module, exports) {
|
||
|
||
/*
|
||
MIT License http://www.opensource.org/licenses/mit-license.php
|
||
Author Tobias Koppers @sokra
|
||
*/
|
||
// css base code, injected by the css-loader
|
||
module.exports = function(useSourceMap) {
|
||
var list = [];
|
||
|
||
// return the list of modules as css string
|
||
list.toString = function toString() {
|
||
return this.map(function (item) {
|
||
var content = cssWithMappingToString(item, useSourceMap);
|
||
if(item[2]) {
|
||
return "@media " + item[2] + "{" + content + "}";
|
||
} else {
|
||
return content;
|
||
}
|
||
}).join("");
|
||
};
|
||
|
||
// import a list of modules into the list
|
||
list.i = function(modules, mediaQuery) {
|
||
if(typeof modules === "string")
|
||
modules = [[null, modules, ""]];
|
||
var alreadyImportedModules = {};
|
||
for(var i = 0; i < this.length; i++) {
|
||
var id = this[i][0];
|
||
if(typeof id === "number")
|
||
alreadyImportedModules[id] = true;
|
||
}
|
||
for(i = 0; i < modules.length; i++) {
|
||
var item = modules[i];
|
||
// skip already imported module
|
||
// this implementation is not 100% perfect for weird media query combinations
|
||
// when a module is imported multiple times with different media queries.
|
||
// I hope this will never occur (Hey this way we have smaller bundles)
|
||
if(typeof item[0] !== "number" || !alreadyImportedModules[item[0]]) {
|
||
if(mediaQuery && !item[2]) {
|
||
item[2] = mediaQuery;
|
||
} else if(mediaQuery) {
|
||
item[2] = "(" + item[2] + ") and (" + mediaQuery + ")";
|
||
}
|
||
list.push(item);
|
||
}
|
||
}
|
||
};
|
||
return list;
|
||
};
|
||
|
||
function cssWithMappingToString(item, useSourceMap) {
|
||
var content = item[1] || '';
|
||
var cssMapping = item[3];
|
||
if (!cssMapping) {
|
||
return content;
|
||
}
|
||
|
||
if (useSourceMap && typeof btoa === 'function') {
|
||
var sourceMapping = toComment(cssMapping);
|
||
var sourceURLs = cssMapping.sources.map(function (source) {
|
||
return '/*# sourceURL=' + cssMapping.sourceRoot + source + ' */'
|
||
});
|
||
|
||
return [content].concat(sourceURLs).concat([sourceMapping]).join('\n');
|
||
}
|
||
|
||
return [content].join('\n');
|
||
}
|
||
|
||
// Adapted from convert-source-map (MIT)
|
||
function toComment(sourceMap) {
|
||
// eslint-disable-next-line no-undef
|
||
var base64 = btoa(unescape(encodeURIComponent(JSON.stringify(sourceMap))));
|
||
var data = 'sourceMappingURL=data:application/json;charset=utf-8;base64,' + base64;
|
||
|
||
return '/*# ' + data + ' */';
|
||
}
|
||
|
||
|
||
/***/ }),
|
||
/* 1 */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
/*
|
||
MIT License http://www.opensource.org/licenses/mit-license.php
|
||
Author Tobias Koppers @sokra
|
||
Modified by Evan You @yyx990803
|
||
*/
|
||
|
||
var hasDocument = typeof document !== 'undefined'
|
||
|
||
if (typeof DEBUG !== 'undefined' && DEBUG) {
|
||
if (!hasDocument) {
|
||
throw new Error(
|
||
'vue-style-loader cannot be used in a non-browser environment. ' +
|
||
"Use { target: 'node' } in your Webpack config to indicate a server-rendering environment."
|
||
) }
|
||
}
|
||
|
||
var listToStyles = __webpack_require__(18)
|
||
|
||
/*
|
||
type StyleObject = {
|
||
id: number;
|
||
parts: Array<StyleObjectPart>
|
||
}
|
||
|
||
type StyleObjectPart = {
|
||
css: string;
|
||
media: string;
|
||
sourceMap: ?string
|
||
}
|
||
*/
|
||
|
||
var stylesInDom = {/*
|
||
[id: number]: {
|
||
id: number,
|
||
refs: number,
|
||
parts: Array<(obj?: StyleObjectPart) => void>
|
||
}
|
||
*/}
|
||
|
||
var head = hasDocument && (document.head || document.getElementsByTagName('head')[0])
|
||
var singletonElement = null
|
||
var singletonCounter = 0
|
||
var isProduction = false
|
||
var noop = function () {}
|
||
|
||
// Force single-tag solution on IE6-9, which has a hard limit on the # of <style>
|
||
// tags it will allow on a page
|
||
var isOldIE = typeof navigator !== 'undefined' && /msie [6-9]\b/.test(navigator.userAgent.toLowerCase())
|
||
|
||
module.exports = function (parentId, list, _isProduction) {
|
||
isProduction = _isProduction
|
||
|
||
var styles = listToStyles(parentId, list)
|
||
addStylesToDom(styles)
|
||
|
||
return function update (newList) {
|
||
var mayRemove = []
|
||
for (var i = 0; i < styles.length; i++) {
|
||
var item = styles[i]
|
||
var domStyle = stylesInDom[item.id]
|
||
domStyle.refs--
|
||
mayRemove.push(domStyle)
|
||
}
|
||
if (newList) {
|
||
styles = listToStyles(parentId, newList)
|
||
addStylesToDom(styles)
|
||
} else {
|
||
styles = []
|
||
}
|
||
for (var i = 0; i < mayRemove.length; i++) {
|
||
var domStyle = mayRemove[i]
|
||
if (domStyle.refs === 0) {
|
||
for (var j = 0; j < domStyle.parts.length; j++) {
|
||
domStyle.parts[j]()
|
||
}
|
||
delete stylesInDom[domStyle.id]
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
function addStylesToDom (styles /* Array<StyleObject> */) {
|
||
for (var i = 0; i < styles.length; i++) {
|
||
var item = styles[i]
|
||
var domStyle = stylesInDom[item.id]
|
||
if (domStyle) {
|
||
domStyle.refs++
|
||
for (var j = 0; j < domStyle.parts.length; j++) {
|
||
domStyle.parts[j](item.parts[j])
|
||
}
|
||
for (; j < item.parts.length; j++) {
|
||
domStyle.parts.push(addStyle(item.parts[j]))
|
||
}
|
||
if (domStyle.parts.length > item.parts.length) {
|
||
domStyle.parts.length = item.parts.length
|
||
}
|
||
} else {
|
||
var parts = []
|
||
for (var j = 0; j < item.parts.length; j++) {
|
||
parts.push(addStyle(item.parts[j]))
|
||
}
|
||
stylesInDom[item.id] = { id: item.id, refs: 1, parts: parts }
|
||
}
|
||
}
|
||
}
|
||
|
||
function createStyleElement () {
|
||
var styleElement = document.createElement('style')
|
||
styleElement.type = 'text/css'
|
||
head.appendChild(styleElement)
|
||
return styleElement
|
||
}
|
||
|
||
function addStyle (obj /* StyleObjectPart */) {
|
||
var update, remove
|
||
var styleElement = document.querySelector('style[data-vue-ssr-id~="' + obj.id + '"]')
|
||
|
||
if (styleElement) {
|
||
if (isProduction) {
|
||
// has SSR styles and in production mode.
|
||
// simply do nothing.
|
||
return noop
|
||
} else {
|
||
// has SSR styles but in dev mode.
|
||
// for some reason Chrome can't handle source map in server-rendered
|
||
// style tags - source maps in <style> only works if the style tag is
|
||
// created and inserted dynamically. So we remove the server rendered
|
||
// styles and inject new ones.
|
||
styleElement.parentNode.removeChild(styleElement)
|
||
}
|
||
}
|
||
|
||
if (isOldIE) {
|
||
// use singleton mode for IE9.
|
||
var styleIndex = singletonCounter++
|
||
styleElement = singletonElement || (singletonElement = createStyleElement())
|
||
update = applyToSingletonTag.bind(null, styleElement, styleIndex, false)
|
||
remove = applyToSingletonTag.bind(null, styleElement, styleIndex, true)
|
||
} else {
|
||
// use multi-style-tag mode in all other cases
|
||
styleElement = createStyleElement()
|
||
update = applyToTag.bind(null, styleElement)
|
||
remove = function () {
|
||
styleElement.parentNode.removeChild(styleElement)
|
||
}
|
||
}
|
||
|
||
update(obj)
|
||
|
||
return function updateStyle (newObj /* StyleObjectPart */) {
|
||
if (newObj) {
|
||
if (newObj.css === obj.css &&
|
||
newObj.media === obj.media &&
|
||
newObj.sourceMap === obj.sourceMap) {
|
||
return
|
||
}
|
||
update(obj = newObj)
|
||
} else {
|
||
remove()
|
||
}
|
||
}
|
||
}
|
||
|
||
var replaceText = (function () {
|
||
var textStore = []
|
||
|
||
return function (index, replacement) {
|
||
textStore[index] = replacement
|
||
return textStore.filter(Boolean).join('\n')
|
||
}
|
||
})()
|
||
|
||
function applyToSingletonTag (styleElement, index, remove, obj) {
|
||
var css = remove ? '' : obj.css
|
||
|
||
if (styleElement.styleSheet) {
|
||
styleElement.styleSheet.cssText = replaceText(index, css)
|
||
} else {
|
||
var cssNode = document.createTextNode(css)
|
||
var childNodes = styleElement.childNodes
|
||
if (childNodes[index]) styleElement.removeChild(childNodes[index])
|
||
if (childNodes.length) {
|
||
styleElement.insertBefore(cssNode, childNodes[index])
|
||
} else {
|
||
styleElement.appendChild(cssNode)
|
||
}
|
||
}
|
||
}
|
||
|
||
function applyToTag (styleElement, obj) {
|
||
var css = obj.css
|
||
var media = obj.media
|
||
var sourceMap = obj.sourceMap
|
||
|
||
if (media) {
|
||
styleElement.setAttribute('media', media)
|
||
}
|
||
|
||
if (sourceMap) {
|
||
// https://developer.chrome.com/devtools/docs/javascript-debugging
|
||
// this makes source maps inside style tags work properly in Chrome
|
||
css += '\n/*# sourceURL=' + sourceMap.sources[0] + ' */'
|
||
// http://stackoverflow.com/a/26603875
|
||
css += '\n/*# sourceMappingURL=data:application/json;base64,' + btoa(unescape(encodeURIComponent(JSON.stringify(sourceMap)))) + ' */'
|
||
}
|
||
|
||
if (styleElement.styleSheet) {
|
||
styleElement.styleSheet.cssText = css
|
||
} else {
|
||
while (styleElement.firstChild) {
|
||
styleElement.removeChild(styleElement.firstChild)
|
||
}
|
||
styleElement.appendChild(document.createTextNode(css))
|
||
}
|
||
}
|
||
|
||
|
||
/***/ }),
|
||
/* 2 */
|
||
/***/ (function(module, exports) {
|
||
|
||
/* globals __VUE_SSR_CONTEXT__ */
|
||
|
||
// this module is a runtime utility for cleaner component module output and will
|
||
// be included in the final webpack user bundle
|
||
|
||
module.exports = function normalizeComponent (
|
||
rawScriptExports,
|
||
compiledTemplate,
|
||
injectStyles,
|
||
scopeId,
|
||
moduleIdentifier /* server only */
|
||
) {
|
||
var esModule
|
||
var scriptExports = rawScriptExports = rawScriptExports || {}
|
||
|
||
// ES6 modules interop
|
||
var type = typeof rawScriptExports.default
|
||
if (type === 'object' || type === 'function') {
|
||
esModule = rawScriptExports
|
||
scriptExports = rawScriptExports.default
|
||
}
|
||
|
||
// Vue.extend constructor export interop
|
||
var options = typeof scriptExports === 'function'
|
||
? scriptExports.options
|
||
: scriptExports
|
||
|
||
// render functions
|
||
if (compiledTemplate) {
|
||
options.render = compiledTemplate.render
|
||
options.staticRenderFns = compiledTemplate.staticRenderFns
|
||
}
|
||
|
||
// scopedId
|
||
if (scopeId) {
|
||
options._scopeId = scopeId
|
||
}
|
||
|
||
var hook
|
||
if (moduleIdentifier) { // server build
|
||
hook = function (context) {
|
||
// 2.3 injection
|
||
context =
|
||
context || // cached call
|
||
(this.$vnode && this.$vnode.ssrContext) || // stateful
|
||
(this.parent && this.parent.$vnode && this.parent.$vnode.ssrContext) // functional
|
||
// 2.2 with runInNewContext: true
|
||
if (!context && typeof __VUE_SSR_CONTEXT__ !== 'undefined') {
|
||
context = __VUE_SSR_CONTEXT__
|
||
}
|
||
// inject component styles
|
||
if (injectStyles) {
|
||
injectStyles.call(this, context)
|
||
}
|
||
// register component module identifier for async chunk inferrence
|
||
if (context && context._registeredComponents) {
|
||
context._registeredComponents.add(moduleIdentifier)
|
||
}
|
||
}
|
||
// used by ssr in case component is cached and beforeCreate
|
||
// never gets called
|
||
options._ssrRegister = hook
|
||
} else if (injectStyles) {
|
||
hook = injectStyles
|
||
}
|
||
|
||
if (hook) {
|
||
var functional = options.functional
|
||
var existing = functional
|
||
? options.render
|
||
: options.beforeCreate
|
||
if (!functional) {
|
||
// inject component registration as beforeCreate hook
|
||
options.beforeCreate = existing
|
||
? [].concat(existing, hook)
|
||
: [hook]
|
||
} else {
|
||
// register for functioal component in vue file
|
||
options.render = function renderWithStyleInjection (h, context) {
|
||
hook.call(context)
|
||
return existing(h, context)
|
||
}
|
||
}
|
||
}
|
||
|
||
return {
|
||
esModule: esModule,
|
||
exports: scriptExports,
|
||
options: options
|
||
}
|
||
}
|
||
|
||
|
||
/***/ }),
|
||
/* 3 */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/*!
|
||
* jQuery JavaScript Library v3.2.1
|
||
* https://jquery.com/
|
||
*
|
||
* Includes Sizzle.js
|
||
* https://sizzlejs.com/
|
||
*
|
||
* Copyright JS Foundation and other contributors
|
||
* Released under the MIT license
|
||
* https://jquery.org/license
|
||
*
|
||
* Date: 2017-03-20T18:59Z
|
||
*/
|
||
( function( global, factory ) {
|
||
|
||
"use strict";
|
||
|
||
if ( typeof module === "object" && typeof module.exports === "object" ) {
|
||
|
||
// For CommonJS and CommonJS-like environments where a proper `window`
|
||
// is present, execute the factory and get jQuery.
|
||
// For environments that do not have a `window` with a `document`
|
||
// (such as Node.js), expose a factory as module.exports.
|
||
// This accentuates the need for the creation of a real `window`.
|
||
// e.g. var jQuery = require("jquery")(window);
|
||
// See ticket #14549 for more info.
|
||
module.exports = global.document ?
|
||
factory( global, true ) :
|
||
function( w ) {
|
||
if ( !w.document ) {
|
||
throw new Error( "jQuery requires a window with a document" );
|
||
}
|
||
return factory( w );
|
||
};
|
||
} else {
|
||
factory( global );
|
||
}
|
||
|
||
// Pass this if window is not defined yet
|
||
} )( typeof window !== "undefined" ? window : this, function( window, noGlobal ) {
|
||
|
||
// Edge <= 12 - 13+, Firefox <=18 - 45+, IE 10 - 11, Safari 5.1 - 9+, iOS 6 - 9.1
|
||
// throw exceptions when non-strict code (e.g., ASP.NET 4.5) accesses strict mode
|
||
// arguments.callee.caller (trac-13335). But as of jQuery 3.0 (2016), strict mode should be common
|
||
// enough that all such attempts are guarded in a try block.
|
||
"use strict";
|
||
|
||
var arr = [];
|
||
|
||
var document = window.document;
|
||
|
||
var getProto = Object.getPrototypeOf;
|
||
|
||
var slice = arr.slice;
|
||
|
||
var concat = arr.concat;
|
||
|
||
var push = arr.push;
|
||
|
||
var indexOf = arr.indexOf;
|
||
|
||
var class2type = {};
|
||
|
||
var toString = class2type.toString;
|
||
|
||
var hasOwn = class2type.hasOwnProperty;
|
||
|
||
var fnToString = hasOwn.toString;
|
||
|
||
var ObjectFunctionString = fnToString.call( Object );
|
||
|
||
var support = {};
|
||
|
||
|
||
|
||
function DOMEval( code, doc ) {
|
||
doc = doc || document;
|
||
|
||
var script = doc.createElement( "script" );
|
||
|
||
script.text = code;
|
||
doc.head.appendChild( script ).parentNode.removeChild( script );
|
||
}
|
||
/* global Symbol */
|
||
// Defining this global in .eslintrc.json would create a danger of using the global
|
||
// unguarded in another place, it seems safer to define global only for this module
|
||
|
||
|
||
|
||
var
|
||
version = "3.2.1",
|
||
|
||
// Define a local copy of jQuery
|
||
jQuery = function( selector, context ) {
|
||
|
||
// The jQuery object is actually just the init constructor 'enhanced'
|
||
// Need init if jQuery is called (just allow error to be thrown if not included)
|
||
return new jQuery.fn.init( selector, context );
|
||
},
|
||
|
||
// Support: Android <=4.0 only
|
||
// Make sure we trim BOM and NBSP
|
||
rtrim = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,
|
||
|
||
// Matches dashed string for camelizing
|
||
rmsPrefix = /^-ms-/,
|
||
rdashAlpha = /-([a-z])/g,
|
||
|
||
// Used by jQuery.camelCase as callback to replace()
|
||
fcamelCase = function( all, letter ) {
|
||
return letter.toUpperCase();
|
||
};
|
||
|
||
jQuery.fn = jQuery.prototype = {
|
||
|
||
// The current version of jQuery being used
|
||
jquery: version,
|
||
|
||
constructor: jQuery,
|
||
|
||
// The default length of a jQuery object is 0
|
||
length: 0,
|
||
|
||
toArray: function() {
|
||
return slice.call( this );
|
||
},
|
||
|
||
// Get the Nth element in the matched element set OR
|
||
// Get the whole matched element set as a clean array
|
||
get: function( num ) {
|
||
|
||
// Return all the elements in a clean array
|
||
if ( num == null ) {
|
||
return slice.call( this );
|
||
}
|
||
|
||
// Return just the one element from the set
|
||
return num < 0 ? this[ num + this.length ] : this[ num ];
|
||
},
|
||
|
||
// Take an array of elements and push it onto the stack
|
||
// (returning the new matched element set)
|
||
pushStack: function( elems ) {
|
||
|
||
// Build a new jQuery matched element set
|
||
var ret = jQuery.merge( this.constructor(), elems );
|
||
|
||
// Add the old object onto the stack (as a reference)
|
||
ret.prevObject = this;
|
||
|
||
// Return the newly-formed element set
|
||
return ret;
|
||
},
|
||
|
||
// Execute a callback for every element in the matched set.
|
||
each: function( callback ) {
|
||
return jQuery.each( this, callback );
|
||
},
|
||
|
||
map: function( callback ) {
|
||
return this.pushStack( jQuery.map( this, function( elem, i ) {
|
||
return callback.call( elem, i, elem );
|
||
} ) );
|
||
},
|
||
|
||
slice: function() {
|
||
return this.pushStack( slice.apply( this, arguments ) );
|
||
},
|
||
|
||
first: function() {
|
||
return this.eq( 0 );
|
||
},
|
||
|
||
last: function() {
|
||
return this.eq( -1 );
|
||
},
|
||
|
||
eq: function( i ) {
|
||
var len = this.length,
|
||
j = +i + ( i < 0 ? len : 0 );
|
||
return this.pushStack( j >= 0 && j < len ? [ this[ j ] ] : [] );
|
||
},
|
||
|
||
end: function() {
|
||
return this.prevObject || this.constructor();
|
||
},
|
||
|
||
// For internal use only.
|
||
// Behaves like an Array's method, not like a jQuery method.
|
||
push: push,
|
||
sort: arr.sort,
|
||
splice: arr.splice
|
||
};
|
||
|
||
jQuery.extend = jQuery.fn.extend = function() {
|
||
var options, name, src, copy, copyIsArray, clone,
|
||
target = arguments[ 0 ] || {},
|
||
i = 1,
|
||
length = arguments.length,
|
||
deep = false;
|
||
|
||
// Handle a deep copy situation
|
||
if ( typeof target === "boolean" ) {
|
||
deep = target;
|
||
|
||
// Skip the boolean and the target
|
||
target = arguments[ i ] || {};
|
||
i++;
|
||
}
|
||
|
||
// Handle case when target is a string or something (possible in deep copy)
|
||
if ( typeof target !== "object" && !jQuery.isFunction( target ) ) {
|
||
target = {};
|
||
}
|
||
|
||
// Extend jQuery itself if only one argument is passed
|
||
if ( i === length ) {
|
||
target = this;
|
||
i--;
|
||
}
|
||
|
||
for ( ; i < length; i++ ) {
|
||
|
||
// Only deal with non-null/undefined values
|
||
if ( ( options = arguments[ i ] ) != null ) {
|
||
|
||
// Extend the base object
|
||
for ( name in options ) {
|
||
src = target[ name ];
|
||
copy = options[ name ];
|
||
|
||
// Prevent never-ending loop
|
||
if ( target === copy ) {
|
||
continue;
|
||
}
|
||
|
||
// Recurse if we're merging plain objects or arrays
|
||
if ( deep && copy && ( jQuery.isPlainObject( copy ) ||
|
||
( copyIsArray = Array.isArray( copy ) ) ) ) {
|
||
|
||
if ( copyIsArray ) {
|
||
copyIsArray = false;
|
||
clone = src && Array.isArray( src ) ? src : [];
|
||
|
||
} else {
|
||
clone = src && jQuery.isPlainObject( src ) ? src : {};
|
||
}
|
||
|
||
// Never move original objects, clone them
|
||
target[ name ] = jQuery.extend( deep, clone, copy );
|
||
|
||
// Don't bring in undefined values
|
||
} else if ( copy !== undefined ) {
|
||
target[ name ] = copy;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
// Return the modified object
|
||
return target;
|
||
};
|
||
|
||
jQuery.extend( {
|
||
|
||
// Unique for each copy of jQuery on the page
|
||
expando: "jQuery" + ( version + Math.random() ).replace( /\D/g, "" ),
|
||
|
||
// Assume jQuery is ready without the ready module
|
||
isReady: true,
|
||
|
||
error: function( msg ) {
|
||
throw new Error( msg );
|
||
},
|
||
|
||
noop: function() {},
|
||
|
||
isFunction: function( obj ) {
|
||
return jQuery.type( obj ) === "function";
|
||
},
|
||
|
||
isWindow: function( obj ) {
|
||
return obj != null && obj === obj.window;
|
||
},
|
||
|
||
isNumeric: function( obj ) {
|
||
|
||
// As of jQuery 3.0, isNumeric is limited to
|
||
// strings and numbers (primitives or objects)
|
||
// that can be coerced to finite numbers (gh-2662)
|
||
var type = jQuery.type( obj );
|
||
return ( type === "number" || type === "string" ) &&
|
||
|
||
// parseFloat NaNs numeric-cast false positives ("")
|
||
// ...but misinterprets leading-number strings, particularly hex literals ("0x...")
|
||
// subtraction forces infinities to NaN
|
||
!isNaN( obj - parseFloat( obj ) );
|
||
},
|
||
|
||
isPlainObject: function( obj ) {
|
||
var proto, Ctor;
|
||
|
||
// Detect obvious negatives
|
||
// Use toString instead of jQuery.type to catch host objects
|
||
if ( !obj || toString.call( obj ) !== "[object Object]" ) {
|
||
return false;
|
||
}
|
||
|
||
proto = getProto( obj );
|
||
|
||
// Objects with no prototype (e.g., `Object.create( null )`) are plain
|
||
if ( !proto ) {
|
||
return true;
|
||
}
|
||
|
||
// Objects with prototype are plain iff they were constructed by a global Object function
|
||
Ctor = hasOwn.call( proto, "constructor" ) && proto.constructor;
|
||
return typeof Ctor === "function" && fnToString.call( Ctor ) === ObjectFunctionString;
|
||
},
|
||
|
||
isEmptyObject: function( obj ) {
|
||
|
||
/* eslint-disable no-unused-vars */
|
||
// See https://github.com/eslint/eslint/issues/6125
|
||
var name;
|
||
|
||
for ( name in obj ) {
|
||
return false;
|
||
}
|
||
return true;
|
||
},
|
||
|
||
type: function( obj ) {
|
||
if ( obj == null ) {
|
||
return obj + "";
|
||
}
|
||
|
||
// Support: Android <=2.3 only (functionish RegExp)
|
||
return typeof obj === "object" || typeof obj === "function" ?
|
||
class2type[ toString.call( obj ) ] || "object" :
|
||
typeof obj;
|
||
},
|
||
|
||
// Evaluates a script in a global context
|
||
globalEval: function( code ) {
|
||
DOMEval( code );
|
||
},
|
||
|
||
// Convert dashed to camelCase; used by the css and data modules
|
||
// Support: IE <=9 - 11, Edge 12 - 13
|
||
// Microsoft forgot to hump their vendor prefix (#9572)
|
||
camelCase: function( string ) {
|
||
return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase );
|
||
},
|
||
|
||
each: function( obj, callback ) {
|
||
var length, i = 0;
|
||
|
||
if ( isArrayLike( obj ) ) {
|
||
length = obj.length;
|
||
for ( ; i < length; i++ ) {
|
||
if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) {
|
||
break;
|
||
}
|
||
}
|
||
} else {
|
||
for ( i in obj ) {
|
||
if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) {
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
|
||
return obj;
|
||
},
|
||
|
||
// Support: Android <=4.0 only
|
||
trim: function( text ) {
|
||
return text == null ?
|
||
"" :
|
||
( text + "" ).replace( rtrim, "" );
|
||
},
|
||
|
||
// results is for internal usage only
|
||
makeArray: function( arr, results ) {
|
||
var ret = results || [];
|
||
|
||
if ( arr != null ) {
|
||
if ( isArrayLike( Object( arr ) ) ) {
|
||
jQuery.merge( ret,
|
||
typeof arr === "string" ?
|
||
[ arr ] : arr
|
||
);
|
||
} else {
|
||
push.call( ret, arr );
|
||
}
|
||
}
|
||
|
||
return ret;
|
||
},
|
||
|
||
inArray: function( elem, arr, i ) {
|
||
return arr == null ? -1 : indexOf.call( arr, elem, i );
|
||
},
|
||
|
||
// Support: Android <=4.0 only, PhantomJS 1 only
|
||
// push.apply(_, arraylike) throws on ancient WebKit
|
||
merge: function( first, second ) {
|
||
var len = +second.length,
|
||
j = 0,
|
||
i = first.length;
|
||
|
||
for ( ; j < len; j++ ) {
|
||
first[ i++ ] = second[ j ];
|
||
}
|
||
|
||
first.length = i;
|
||
|
||
return first;
|
||
},
|
||
|
||
grep: function( elems, callback, invert ) {
|
||
var callbackInverse,
|
||
matches = [],
|
||
i = 0,
|
||
length = elems.length,
|
||
callbackExpect = !invert;
|
||
|
||
// Go through the array, only saving the items
|
||
// that pass the validator function
|
||
for ( ; i < length; i++ ) {
|
||
callbackInverse = !callback( elems[ i ], i );
|
||
if ( callbackInverse !== callbackExpect ) {
|
||
matches.push( elems[ i ] );
|
||
}
|
||
}
|
||
|
||
return matches;
|
||
},
|
||
|
||
// arg is for internal usage only
|
||
map: function( elems, callback, arg ) {
|
||
var length, value,
|
||
i = 0,
|
||
ret = [];
|
||
|
||
// Go through the array, translating each of the items to their new values
|
||
if ( isArrayLike( elems ) ) {
|
||
length = elems.length;
|
||
for ( ; i < length; i++ ) {
|
||
value = callback( elems[ i ], i, arg );
|
||
|
||
if ( value != null ) {
|
||
ret.push( value );
|
||
}
|
||
}
|
||
|
||
// Go through every key on the object,
|
||
} else {
|
||
for ( i in elems ) {
|
||
value = callback( elems[ i ], i, arg );
|
||
|
||
if ( value != null ) {
|
||
ret.push( value );
|
||
}
|
||
}
|
||
}
|
||
|
||
// Flatten any nested arrays
|
||
return concat.apply( [], ret );
|
||
},
|
||
|
||
// A global GUID counter for objects
|
||
guid: 1,
|
||
|
||
// Bind a function to a context, optionally partially applying any
|
||
// arguments.
|
||
proxy: function( fn, context ) {
|
||
var tmp, args, proxy;
|
||
|
||
if ( typeof context === "string" ) {
|
||
tmp = fn[ context ];
|
||
context = fn;
|
||
fn = tmp;
|
||
}
|
||
|
||
// Quick check to determine if target is callable, in the spec
|
||
// this throws a TypeError, but we will just return undefined.
|
||
if ( !jQuery.isFunction( fn ) ) {
|
||
return undefined;
|
||
}
|
||
|
||
// Simulated bind
|
||
args = slice.call( arguments, 2 );
|
||
proxy = function() {
|
||
return fn.apply( context || this, args.concat( slice.call( arguments ) ) );
|
||
};
|
||
|
||
// Set the guid of unique handler to the same of original handler, so it can be removed
|
||
proxy.guid = fn.guid = fn.guid || jQuery.guid++;
|
||
|
||
return proxy;
|
||
},
|
||
|
||
now: Date.now,
|
||
|
||
// jQuery.support is not used in Core but other projects attach their
|
||
// properties to it so it needs to exist.
|
||
support: support
|
||
} );
|
||
|
||
if ( typeof Symbol === "function" ) {
|
||
jQuery.fn[ Symbol.iterator ] = arr[ Symbol.iterator ];
|
||
}
|
||
|
||
// Populate the class2type map
|
||
jQuery.each( "Boolean Number String Function Array Date RegExp Object Error Symbol".split( " " ),
|
||
function( i, name ) {
|
||
class2type[ "[object " + name + "]" ] = name.toLowerCase();
|
||
} );
|
||
|
||
function isArrayLike( obj ) {
|
||
|
||
// Support: real iOS 8.2 only (not reproducible in simulator)
|
||
// `in` check used to prevent JIT error (gh-2145)
|
||
// hasOwn isn't used here due to false negatives
|
||
// regarding Nodelist length in IE
|
||
var length = !!obj && "length" in obj && obj.length,
|
||
type = jQuery.type( obj );
|
||
|
||
if ( type === "function" || jQuery.isWindow( obj ) ) {
|
||
return false;
|
||
}
|
||
|
||
return type === "array" || length === 0 ||
|
||
typeof length === "number" && length > 0 && ( length - 1 ) in obj;
|
||
}
|
||
var Sizzle =
|
||
/*!
|
||
* Sizzle CSS Selector Engine v2.3.3
|
||
* https://sizzlejs.com/
|
||
*
|
||
* Copyright jQuery Foundation and other contributors
|
||
* Released under the MIT license
|
||
* http://jquery.org/license
|
||
*
|
||
* Date: 2016-08-08
|
||
*/
|
||
(function( window ) {
|
||
|
||
var i,
|
||
support,
|
||
Expr,
|
||
getText,
|
||
isXML,
|
||
tokenize,
|
||
compile,
|
||
select,
|
||
outermostContext,
|
||
sortInput,
|
||
hasDuplicate,
|
||
|
||
// Local document vars
|
||
setDocument,
|
||
document,
|
||
docElem,
|
||
documentIsHTML,
|
||
rbuggyQSA,
|
||
rbuggyMatches,
|
||
matches,
|
||
contains,
|
||
|
||
// Instance-specific data
|
||
expando = "sizzle" + 1 * new Date(),
|
||
preferredDoc = window.document,
|
||
dirruns = 0,
|
||
done = 0,
|
||
classCache = createCache(),
|
||
tokenCache = createCache(),
|
||
compilerCache = createCache(),
|
||
sortOrder = function( a, b ) {
|
||
if ( a === b ) {
|
||
hasDuplicate = true;
|
||
}
|
||
return 0;
|
||
},
|
||
|
||
// Instance methods
|
||
hasOwn = ({}).hasOwnProperty,
|
||
arr = [],
|
||
pop = arr.pop,
|
||
push_native = arr.push,
|
||
push = arr.push,
|
||
slice = arr.slice,
|
||
// Use a stripped-down indexOf as it's faster than native
|
||
// https://jsperf.com/thor-indexof-vs-for/5
|
||
indexOf = function( list, elem ) {
|
||
var i = 0,
|
||
len = list.length;
|
||
for ( ; i < len; i++ ) {
|
||
if ( list[i] === elem ) {
|
||
return i;
|
||
}
|
||
}
|
||
return -1;
|
||
},
|
||
|
||
booleans = "checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",
|
||
|
||
// Regular expressions
|
||
|
||
// http://www.w3.org/TR/css3-selectors/#whitespace
|
||
whitespace = "[\\x20\\t\\r\\n\\f]",
|
||
|
||
// http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier
|
||
identifier = "(?:\\\\.|[\\w-]|[^\0-\\xa0])+",
|
||
|
||
// Attribute selectors: http://www.w3.org/TR/selectors/#attribute-selectors
|
||
attributes = "\\[" + whitespace + "*(" + identifier + ")(?:" + whitespace +
|
||
// Operator (capture 2)
|
||
"*([*^$|!~]?=)" + whitespace +
|
||
// "Attribute values must be CSS identifiers [capture 5] or strings [capture 3 or capture 4]"
|
||
"*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|(" + identifier + "))|)" + whitespace +
|
||
"*\\]",
|
||
|
||
pseudos = ":(" + identifier + ")(?:\\((" +
|
||
// To reduce the number of selectors needing tokenize in the preFilter, prefer arguments:
|
||
// 1. quoted (capture 3; capture 4 or capture 5)
|
||
"('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|" +
|
||
// 2. simple (capture 6)
|
||
"((?:\\\\.|[^\\\\()[\\]]|" + attributes + ")*)|" +
|
||
// 3. anything else (capture 2)
|
||
".*" +
|
||
")\\)|)",
|
||
|
||
// Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter
|
||
rwhitespace = new RegExp( whitespace + "+", "g" ),
|
||
rtrim = new RegExp( "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + whitespace + "+$", "g" ),
|
||
|
||
rcomma = new RegExp( "^" + whitespace + "*," + whitespace + "*" ),
|
||
rcombinators = new RegExp( "^" + whitespace + "*([>+~]|" + whitespace + ")" + whitespace + "*" ),
|
||
|
||
rattributeQuotes = new RegExp( "=" + whitespace + "*([^\\]'\"]*?)" + whitespace + "*\\]", "g" ),
|
||
|
||
rpseudo = new RegExp( pseudos ),
|
||
ridentifier = new RegExp( "^" + identifier + "$" ),
|
||
|
||
matchExpr = {
|
||
"ID": new RegExp( "^#(" + identifier + ")" ),
|
||
"CLASS": new RegExp( "^\\.(" + identifier + ")" ),
|
||
"TAG": new RegExp( "^(" + identifier + "|[*])" ),
|
||
"ATTR": new RegExp( "^" + attributes ),
|
||
"PSEUDO": new RegExp( "^" + pseudos ),
|
||
"CHILD": new RegExp( "^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" + whitespace +
|
||
"*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" + whitespace +
|
||
"*(\\d+)|))" + whitespace + "*\\)|)", "i" ),
|
||
"bool": new RegExp( "^(?:" + booleans + ")$", "i" ),
|
||
// For use in libraries implementing .is()
|
||
// We use this for POS matching in `select`
|
||
"needsContext": new RegExp( "^" + whitespace + "*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" +
|
||
whitespace + "*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)", "i" )
|
||
},
|
||
|
||
rinputs = /^(?:input|select|textarea|button)$/i,
|
||
rheader = /^h\d$/i,
|
||
|
||
rnative = /^[^{]+\{\s*\[native \w/,
|
||
|
||
// Easily-parseable/retrievable ID or TAG or CLASS selectors
|
||
rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,
|
||
|
||
rsibling = /[+~]/,
|
||
|
||
// CSS escapes
|
||
// http://www.w3.org/TR/CSS21/syndata.html#escaped-characters
|
||
runescape = new RegExp( "\\\\([\\da-f]{1,6}" + whitespace + "?|(" + whitespace + ")|.)", "ig" ),
|
||
funescape = function( _, escaped, escapedWhitespace ) {
|
||
var high = "0x" + escaped - 0x10000;
|
||
// NaN means non-codepoint
|
||
// Support: Firefox<24
|
||
// Workaround erroneous numeric interpretation of +"0x"
|
||
return high !== high || escapedWhitespace ?
|
||
escaped :
|
||
high < 0 ?
|
||
// BMP codepoint
|
||
String.fromCharCode( high + 0x10000 ) :
|
||
// Supplemental Plane codepoint (surrogate pair)
|
||
String.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 );
|
||
},
|
||
|
||
// CSS string/identifier serialization
|
||
// https://drafts.csswg.org/cssom/#common-serializing-idioms
|
||
rcssescape = /([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g,
|
||
fcssescape = function( ch, asCodePoint ) {
|
||
if ( asCodePoint ) {
|
||
|
||
// U+0000 NULL becomes U+FFFD REPLACEMENT CHARACTER
|
||
if ( ch === "\0" ) {
|
||
return "\uFFFD";
|
||
}
|
||
|
||
// Control characters and (dependent upon position) numbers get escaped as code points
|
||
return ch.slice( 0, -1 ) + "\\" + ch.charCodeAt( ch.length - 1 ).toString( 16 ) + " ";
|
||
}
|
||
|
||
// Other potentially-special ASCII characters get backslash-escaped
|
||
return "\\" + ch;
|
||
},
|
||
|
||
// Used for iframes
|
||
// See setDocument()
|
||
// Removing the function wrapper causes a "Permission Denied"
|
||
// error in IE
|
||
unloadHandler = function() {
|
||
setDocument();
|
||
},
|
||
|
||
disabledAncestor = addCombinator(
|
||
function( elem ) {
|
||
return elem.disabled === true && ("form" in elem || "label" in elem);
|
||
},
|
||
{ dir: "parentNode", next: "legend" }
|
||
);
|
||
|
||
// Optimize for push.apply( _, NodeList )
|
||
try {
|
||
push.apply(
|
||
(arr = slice.call( preferredDoc.childNodes )),
|
||
preferredDoc.childNodes
|
||
);
|
||
// Support: Android<4.0
|
||
// Detect silently failing push.apply
|
||
arr[ preferredDoc.childNodes.length ].nodeType;
|
||
} catch ( e ) {
|
||
push = { apply: arr.length ?
|
||
|
||
// Leverage slice if possible
|
||
function( target, els ) {
|
||
push_native.apply( target, slice.call(els) );
|
||
} :
|
||
|
||
// Support: IE<9
|
||
// Otherwise append directly
|
||
function( target, els ) {
|
||
var j = target.length,
|
||
i = 0;
|
||
// Can't trust NodeList.length
|
||
while ( (target[j++] = els[i++]) ) {}
|
||
target.length = j - 1;
|
||
}
|
||
};
|
||
}
|
||
|
||
function Sizzle( selector, context, results, seed ) {
|
||
var m, i, elem, nid, match, groups, newSelector,
|
||
newContext = context && context.ownerDocument,
|
||
|
||
// nodeType defaults to 9, since context defaults to document
|
||
nodeType = context ? context.nodeType : 9;
|
||
|
||
results = results || [];
|
||
|
||
// Return early from calls with invalid selector or context
|
||
if ( typeof selector !== "string" || !selector ||
|
||
nodeType !== 1 && nodeType !== 9 && nodeType !== 11 ) {
|
||
|
||
return results;
|
||
}
|
||
|
||
// Try to shortcut find operations (as opposed to filters) in HTML documents
|
||
if ( !seed ) {
|
||
|
||
if ( ( context ? context.ownerDocument || context : preferredDoc ) !== document ) {
|
||
setDocument( context );
|
||
}
|
||
context = context || document;
|
||
|
||
if ( documentIsHTML ) {
|
||
|
||
// If the selector is sufficiently simple, try using a "get*By*" DOM method
|
||
// (excepting DocumentFragment context, where the methods don't exist)
|
||
if ( nodeType !== 11 && (match = rquickExpr.exec( selector )) ) {
|
||
|
||
// ID selector
|
||
if ( (m = match[1]) ) {
|
||
|
||
// Document context
|
||
if ( nodeType === 9 ) {
|
||
if ( (elem = context.getElementById( m )) ) {
|
||
|
||
// Support: IE, Opera, Webkit
|
||
// TODO: identify versions
|
||
// getElementById can match elements by name instead of ID
|
||
if ( elem.id === m ) {
|
||
results.push( elem );
|
||
return results;
|
||
}
|
||
} else {
|
||
return results;
|
||
}
|
||
|
||
// Element context
|
||
} else {
|
||
|
||
// Support: IE, Opera, Webkit
|
||
// TODO: identify versions
|
||
// getElementById can match elements by name instead of ID
|
||
if ( newContext && (elem = newContext.getElementById( m )) &&
|
||
contains( context, elem ) &&
|
||
elem.id === m ) {
|
||
|
||
results.push( elem );
|
||
return results;
|
||
}
|
||
}
|
||
|
||
// Type selector
|
||
} else if ( match[2] ) {
|
||
push.apply( results, context.getElementsByTagName( selector ) );
|
||
return results;
|
||
|
||
// Class selector
|
||
} else if ( (m = match[3]) && support.getElementsByClassName &&
|
||
context.getElementsByClassName ) {
|
||
|
||
push.apply( results, context.getElementsByClassName( m ) );
|
||
return results;
|
||
}
|
||
}
|
||
|
||
// Take advantage of querySelectorAll
|
||
if ( support.qsa &&
|
||
!compilerCache[ selector + " " ] &&
|
||
(!rbuggyQSA || !rbuggyQSA.test( selector )) ) {
|
||
|
||
if ( nodeType !== 1 ) {
|
||
newContext = context;
|
||
newSelector = selector;
|
||
|
||
// qSA looks outside Element context, which is not what we want
|
||
// Thanks to Andrew Dupont for this workaround technique
|
||
// Support: IE <=8
|
||
// Exclude object elements
|
||
} else if ( context.nodeName.toLowerCase() !== "object" ) {
|
||
|
||
// Capture the context ID, setting it first if necessary
|
||
if ( (nid = context.getAttribute( "id" )) ) {
|
||
nid = nid.replace( rcssescape, fcssescape );
|
||
} else {
|
||
context.setAttribute( "id", (nid = expando) );
|
||
}
|
||
|
||
// Prefix every selector in the list
|
||
groups = tokenize( selector );
|
||
i = groups.length;
|
||
while ( i-- ) {
|
||
groups[i] = "#" + nid + " " + toSelector( groups[i] );
|
||
}
|
||
newSelector = groups.join( "," );
|
||
|
||
// Expand context for sibling selectors
|
||
newContext = rsibling.test( selector ) && testContext( context.parentNode ) ||
|
||
context;
|
||
}
|
||
|
||
if ( newSelector ) {
|
||
try {
|
||
push.apply( results,
|
||
newContext.querySelectorAll( newSelector )
|
||
);
|
||
return results;
|
||
} catch ( qsaError ) {
|
||
} finally {
|
||
if ( nid === expando ) {
|
||
context.removeAttribute( "id" );
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
// All others
|
||
return select( selector.replace( rtrim, "$1" ), context, results, seed );
|
||
}
|
||
|
||
/**
|
||
* Create key-value caches of limited size
|
||
* @returns {function(string, object)} Returns the Object data after storing it on itself with
|
||
* property name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength)
|
||
* deleting the oldest entry
|
||
*/
|
||
function createCache() {
|
||
var keys = [];
|
||
|
||
function cache( key, value ) {
|
||
// Use (key + " ") to avoid collision with native prototype properties (see Issue #157)
|
||
if ( keys.push( key + " " ) > Expr.cacheLength ) {
|
||
// Only keep the most recent entries
|
||
delete cache[ keys.shift() ];
|
||
}
|
||
return (cache[ key + " " ] = value);
|
||
}
|
||
return cache;
|
||
}
|
||
|
||
/**
|
||
* Mark a function for special use by Sizzle
|
||
* @param {Function} fn The function to mark
|
||
*/
|
||
function markFunction( fn ) {
|
||
fn[ expando ] = true;
|
||
return fn;
|
||
}
|
||
|
||
/**
|
||
* Support testing using an element
|
||
* @param {Function} fn Passed the created element and returns a boolean result
|
||
*/
|
||
function assert( fn ) {
|
||
var el = document.createElement("fieldset");
|
||
|
||
try {
|
||
return !!fn( el );
|
||
} catch (e) {
|
||
return false;
|
||
} finally {
|
||
// Remove from its parent by default
|
||
if ( el.parentNode ) {
|
||
el.parentNode.removeChild( el );
|
||
}
|
||
// release memory in IE
|
||
el = null;
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Adds the same handler for all of the specified attrs
|
||
* @param {String} attrs Pipe-separated list of attributes
|
||
* @param {Function} handler The method that will be applied
|
||
*/
|
||
function addHandle( attrs, handler ) {
|
||
var arr = attrs.split("|"),
|
||
i = arr.length;
|
||
|
||
while ( i-- ) {
|
||
Expr.attrHandle[ arr[i] ] = handler;
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Checks document order of two siblings
|
||
* @param {Element} a
|
||
* @param {Element} b
|
||
* @returns {Number} Returns less than 0 if a precedes b, greater than 0 if a follows b
|
||
*/
|
||
function siblingCheck( a, b ) {
|
||
var cur = b && a,
|
||
diff = cur && a.nodeType === 1 && b.nodeType === 1 &&
|
||
a.sourceIndex - b.sourceIndex;
|
||
|
||
// Use IE sourceIndex if available on both nodes
|
||
if ( diff ) {
|
||
return diff;
|
||
}
|
||
|
||
// Check if b follows a
|
||
if ( cur ) {
|
||
while ( (cur = cur.nextSibling) ) {
|
||
if ( cur === b ) {
|
||
return -1;
|
||
}
|
||
}
|
||
}
|
||
|
||
return a ? 1 : -1;
|
||
}
|
||
|
||
/**
|
||
* Returns a function to use in pseudos for input types
|
||
* @param {String} type
|
||
*/
|
||
function createInputPseudo( type ) {
|
||
return function( elem ) {
|
||
var name = elem.nodeName.toLowerCase();
|
||
return name === "input" && elem.type === type;
|
||
};
|
||
}
|
||
|
||
/**
|
||
* Returns a function to use in pseudos for buttons
|
||
* @param {String} type
|
||
*/
|
||
function createButtonPseudo( type ) {
|
||
return function( elem ) {
|
||
var name = elem.nodeName.toLowerCase();
|
||
return (name === "input" || name === "button") && elem.type === type;
|
||
};
|
||
}
|
||
|
||
/**
|
||
* Returns a function to use in pseudos for :enabled/:disabled
|
||
* @param {Boolean} disabled true for :disabled; false for :enabled
|
||
*/
|
||
function createDisabledPseudo( disabled ) {
|
||
|
||
// Known :disabled false positives: fieldset[disabled] > legend:nth-of-type(n+2) :can-disable
|
||
return function( elem ) {
|
||
|
||
// Only certain elements can match :enabled or :disabled
|
||
// https://html.spec.whatwg.org/multipage/scripting.html#selector-enabled
|
||
// https://html.spec.whatwg.org/multipage/scripting.html#selector-disabled
|
||
if ( "form" in elem ) {
|
||
|
||
// Check for inherited disabledness on relevant non-disabled elements:
|
||
// * listed form-associated elements in a disabled fieldset
|
||
// https://html.spec.whatwg.org/multipage/forms.html#category-listed
|
||
// https://html.spec.whatwg.org/multipage/forms.html#concept-fe-disabled
|
||
// * option elements in a disabled optgroup
|
||
// https://html.spec.whatwg.org/multipage/forms.html#concept-option-disabled
|
||
// All such elements have a "form" property.
|
||
if ( elem.parentNode && elem.disabled === false ) {
|
||
|
||
// Option elements defer to a parent optgroup if present
|
||
if ( "label" in elem ) {
|
||
if ( "label" in elem.parentNode ) {
|
||
return elem.parentNode.disabled === disabled;
|
||
} else {
|
||
return elem.disabled === disabled;
|
||
}
|
||
}
|
||
|
||
// Support: IE 6 - 11
|
||
// Use the isDisabled shortcut property to check for disabled fieldset ancestors
|
||
return elem.isDisabled === disabled ||
|
||
|
||
// Where there is no isDisabled, check manually
|
||
/* jshint -W018 */
|
||
elem.isDisabled !== !disabled &&
|
||
disabledAncestor( elem ) === disabled;
|
||
}
|
||
|
||
return elem.disabled === disabled;
|
||
|
||
// Try to winnow out elements that can't be disabled before trusting the disabled property.
|
||
// Some victims get caught in our net (label, legend, menu, track), but it shouldn't
|
||
// even exist on them, let alone have a boolean value.
|
||
} else if ( "label" in elem ) {
|
||
return elem.disabled === disabled;
|
||
}
|
||
|
||
// Remaining elements are neither :enabled nor :disabled
|
||
return false;
|
||
};
|
||
}
|
||
|
||
/**
|
||
* Returns a function to use in pseudos for positionals
|
||
* @param {Function} fn
|
||
*/
|
||
function createPositionalPseudo( fn ) {
|
||
return markFunction(function( argument ) {
|
||
argument = +argument;
|
||
return markFunction(function( seed, matches ) {
|
||
var j,
|
||
matchIndexes = fn( [], seed.length, argument ),
|
||
i = matchIndexes.length;
|
||
|
||
// Match elements found at the specified indexes
|
||
while ( i-- ) {
|
||
if ( seed[ (j = matchIndexes[i]) ] ) {
|
||
seed[j] = !(matches[j] = seed[j]);
|
||
}
|
||
}
|
||
});
|
||
});
|
||
}
|
||
|
||
/**
|
||
* Checks a node for validity as a Sizzle context
|
||
* @param {Element|Object=} context
|
||
* @returns {Element|Object|Boolean} The input node if acceptable, otherwise a falsy value
|
||
*/
|
||
function testContext( context ) {
|
||
return context && typeof context.getElementsByTagName !== "undefined" && context;
|
||
}
|
||
|
||
// Expose support vars for convenience
|
||
support = Sizzle.support = {};
|
||
|
||
/**
|
||
* Detects XML nodes
|
||
* @param {Element|Object} elem An element or a document
|
||
* @returns {Boolean} True iff elem is a non-HTML XML node
|
||
*/
|
||
isXML = Sizzle.isXML = function( elem ) {
|
||
// documentElement is verified for cases where it doesn't yet exist
|
||
// (such as loading iframes in IE - #4833)
|
||
var documentElement = elem && (elem.ownerDocument || elem).documentElement;
|
||
return documentElement ? documentElement.nodeName !== "HTML" : false;
|
||
};
|
||
|
||
/**
|
||
* Sets document-related variables once based on the current document
|
||
* @param {Element|Object} [doc] An element or document object to use to set the document
|
||
* @returns {Object} Returns the current document
|
||
*/
|
||
setDocument = Sizzle.setDocument = function( node ) {
|
||
var hasCompare, subWindow,
|
||
doc = node ? node.ownerDocument || node : preferredDoc;
|
||
|
||
// Return early if doc is invalid or already selected
|
||
if ( doc === document || doc.nodeType !== 9 || !doc.documentElement ) {
|
||
return document;
|
||
}
|
||
|
||
// Update global variables
|
||
document = doc;
|
||
docElem = document.documentElement;
|
||
documentIsHTML = !isXML( document );
|
||
|
||
// Support: IE 9-11, Edge
|
||
// Accessing iframe documents after unload throws "permission denied" errors (jQuery #13936)
|
||
if ( preferredDoc !== document &&
|
||
(subWindow = document.defaultView) && subWindow.top !== subWindow ) {
|
||
|
||
// Support: IE 11, Edge
|
||
if ( subWindow.addEventListener ) {
|
||
subWindow.addEventListener( "unload", unloadHandler, false );
|
||
|
||
// Support: IE 9 - 10 only
|
||
} else if ( subWindow.attachEvent ) {
|
||
subWindow.attachEvent( "onunload", unloadHandler );
|
||
}
|
||
}
|
||
|
||
/* Attributes
|
||
---------------------------------------------------------------------- */
|
||
|
||
// Support: IE<8
|
||
// Verify that getAttribute really returns attributes and not properties
|
||
// (excepting IE8 booleans)
|
||
support.attributes = assert(function( el ) {
|
||
el.className = "i";
|
||
return !el.getAttribute("className");
|
||
});
|
||
|
||
/* getElement(s)By*
|
||
---------------------------------------------------------------------- */
|
||
|
||
// Check if getElementsByTagName("*") returns only elements
|
||
support.getElementsByTagName = assert(function( el ) {
|
||
el.appendChild( document.createComment("") );
|
||
return !el.getElementsByTagName("*").length;
|
||
});
|
||
|
||
// Support: IE<9
|
||
support.getElementsByClassName = rnative.test( document.getElementsByClassName );
|
||
|
||
// Support: IE<10
|
||
// Check if getElementById returns elements by name
|
||
// The broken getElementById methods don't pick up programmatically-set names,
|
||
// so use a roundabout getElementsByName test
|
||
support.getById = assert(function( el ) {
|
||
docElem.appendChild( el ).id = expando;
|
||
return !document.getElementsByName || !document.getElementsByName( expando ).length;
|
||
});
|
||
|
||
// ID filter and find
|
||
if ( support.getById ) {
|
||
Expr.filter["ID"] = function( id ) {
|
||
var attrId = id.replace( runescape, funescape );
|
||
return function( elem ) {
|
||
return elem.getAttribute("id") === attrId;
|
||
};
|
||
};
|
||
Expr.find["ID"] = function( id, context ) {
|
||
if ( typeof context.getElementById !== "undefined" && documentIsHTML ) {
|
||
var elem = context.getElementById( id );
|
||
return elem ? [ elem ] : [];
|
||
}
|
||
};
|
||
} else {
|
||
Expr.filter["ID"] = function( id ) {
|
||
var attrId = id.replace( runescape, funescape );
|
||
return function( elem ) {
|
||
var node = typeof elem.getAttributeNode !== "undefined" &&
|
||
elem.getAttributeNode("id");
|
||
return node && node.value === attrId;
|
||
};
|
||
};
|
||
|
||
// Support: IE 6 - 7 only
|
||
// getElementById is not reliable as a find shortcut
|
||
Expr.find["ID"] = function( id, context ) {
|
||
if ( typeof context.getElementById !== "undefined" && documentIsHTML ) {
|
||
var node, i, elems,
|
||
elem = context.getElementById( id );
|
||
|
||
if ( elem ) {
|
||
|
||
// Verify the id attribute
|
||
node = elem.getAttributeNode("id");
|
||
if ( node && node.value === id ) {
|
||
return [ elem ];
|
||
}
|
||
|
||
// Fall back on getElementsByName
|
||
elems = context.getElementsByName( id );
|
||
i = 0;
|
||
while ( (elem = elems[i++]) ) {
|
||
node = elem.getAttributeNode("id");
|
||
if ( node && node.value === id ) {
|
||
return [ elem ];
|
||
}
|
||
}
|
||
}
|
||
|
||
return [];
|
||
}
|
||
};
|
||
}
|
||
|
||
// Tag
|
||
Expr.find["TAG"] = support.getElementsByTagName ?
|
||
function( tag, context ) {
|
||
if ( typeof context.getElementsByTagName !== "undefined" ) {
|
||
return context.getElementsByTagName( tag );
|
||
|
||
// DocumentFragment nodes don't have gEBTN
|
||
} else if ( support.qsa ) {
|
||
return context.querySelectorAll( tag );
|
||
}
|
||
} :
|
||
|
||
function( tag, context ) {
|
||
var elem,
|
||
tmp = [],
|
||
i = 0,
|
||
// By happy coincidence, a (broken) gEBTN appears on DocumentFragment nodes too
|
||
results = context.getElementsByTagName( tag );
|
||
|
||
// Filter out possible comments
|
||
if ( tag === "*" ) {
|
||
while ( (elem = results[i++]) ) {
|
||
if ( elem.nodeType === 1 ) {
|
||
tmp.push( elem );
|
||
}
|
||
}
|
||
|
||
return tmp;
|
||
}
|
||
return results;
|
||
};
|
||
|
||
// Class
|
||
Expr.find["CLASS"] = support.getElementsByClassName && function( className, context ) {
|
||
if ( typeof context.getElementsByClassName !== "undefined" && documentIsHTML ) {
|
||
return context.getElementsByClassName( className );
|
||
}
|
||
};
|
||
|
||
/* QSA/matchesSelector
|
||
---------------------------------------------------------------------- */
|
||
|
||
// QSA and matchesSelector support
|
||
|
||
// matchesSelector(:active) reports false when true (IE9/Opera 11.5)
|
||
rbuggyMatches = [];
|
||
|
||
// qSa(:focus) reports false when true (Chrome 21)
|
||
// We allow this because of a bug in IE8/9 that throws an error
|
||
// whenever `document.activeElement` is accessed on an iframe
|
||
// So, we allow :focus to pass through QSA all the time to avoid the IE error
|
||
// See https://bugs.jquery.com/ticket/13378
|
||
rbuggyQSA = [];
|
||
|
||
if ( (support.qsa = rnative.test( document.querySelectorAll )) ) {
|
||
// Build QSA regex
|
||
// Regex strategy adopted from Diego Perini
|
||
assert(function( el ) {
|
||
// Select is set to empty string on purpose
|
||
// This is to test IE's treatment of not explicitly
|
||
// setting a boolean content attribute,
|
||
// since its presence should be enough
|
||
// https://bugs.jquery.com/ticket/12359
|
||
docElem.appendChild( el ).innerHTML = "<a id='" + expando + "'></a>" +
|
||
"<select id='" + expando + "-\r\\' msallowcapture=''>" +
|
||
"<option selected=''></option></select>";
|
||
|
||
// Support: IE8, Opera 11-12.16
|
||
// Nothing should be selected when empty strings follow ^= or $= or *=
|
||
// The test attribute must be unknown in Opera but "safe" for WinRT
|
||
// https://msdn.microsoft.com/en-us/library/ie/hh465388.aspx#attribute_section
|
||
if ( el.querySelectorAll("[msallowcapture^='']").length ) {
|
||
rbuggyQSA.push( "[*^$]=" + whitespace + "*(?:''|\"\")" );
|
||
}
|
||
|
||
// Support: IE8
|
||
// Boolean attributes and "value" are not treated correctly
|
||
if ( !el.querySelectorAll("[selected]").length ) {
|
||
rbuggyQSA.push( "\\[" + whitespace + "*(?:value|" + booleans + ")" );
|
||
}
|
||
|
||
// Support: Chrome<29, Android<4.4, Safari<7.0+, iOS<7.0+, PhantomJS<1.9.8+
|
||
if ( !el.querySelectorAll( "[id~=" + expando + "-]" ).length ) {
|
||
rbuggyQSA.push("~=");
|
||
}
|
||
|
||
// Webkit/Opera - :checked should return selected option elements
|
||
// http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked
|
||
// IE8 throws error here and will not see later tests
|
||
if ( !el.querySelectorAll(":checked").length ) {
|
||
rbuggyQSA.push(":checked");
|
||
}
|
||
|
||
// Support: Safari 8+, iOS 8+
|
||
// https://bugs.webkit.org/show_bug.cgi?id=136851
|
||
// In-page `selector#id sibling-combinator selector` fails
|
||
if ( !el.querySelectorAll( "a#" + expando + "+*" ).length ) {
|
||
rbuggyQSA.push(".#.+[+~]");
|
||
}
|
||
});
|
||
|
||
assert(function( el ) {
|
||
el.innerHTML = "<a href='' disabled='disabled'></a>" +
|
||
"<select disabled='disabled'><option/></select>";
|
||
|
||
// Support: Windows 8 Native Apps
|
||
// The type and name attributes are restricted during .innerHTML assignment
|
||
var input = document.createElement("input");
|
||
input.setAttribute( "type", "hidden" );
|
||
el.appendChild( input ).setAttribute( "name", "D" );
|
||
|
||
// Support: IE8
|
||
// Enforce case-sensitivity of name attribute
|
||
if ( el.querySelectorAll("[name=d]").length ) {
|
||
rbuggyQSA.push( "name" + whitespace + "*[*^$|!~]?=" );
|
||
}
|
||
|
||
// FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled)
|
||
// IE8 throws error here and will not see later tests
|
||
if ( el.querySelectorAll(":enabled").length !== 2 ) {
|
||
rbuggyQSA.push( ":enabled", ":disabled" );
|
||
}
|
||
|
||
// Support: IE9-11+
|
||
// IE's :disabled selector does not pick up the children of disabled fieldsets
|
||
docElem.appendChild( el ).disabled = true;
|
||
if ( el.querySelectorAll(":disabled").length !== 2 ) {
|
||
rbuggyQSA.push( ":enabled", ":disabled" );
|
||
}
|
||
|
||
// Opera 10-11 does not throw on post-comma invalid pseudos
|
||
el.querySelectorAll("*,:x");
|
||
rbuggyQSA.push(",.*:");
|
||
});
|
||
}
|
||
|
||
if ( (support.matchesSelector = rnative.test( (matches = docElem.matches ||
|
||
docElem.webkitMatchesSelector ||
|
||
docElem.mozMatchesSelector ||
|
||
docElem.oMatchesSelector ||
|
||
docElem.msMatchesSelector) )) ) {
|
||
|
||
assert(function( el ) {
|
||
// Check to see if it's possible to do matchesSelector
|
||
// on a disconnected node (IE 9)
|
||
support.disconnectedMatch = matches.call( el, "*" );
|
||
|
||
// This should fail with an exception
|
||
// Gecko does not error, returns false instead
|
||
matches.call( el, "[s!='']:x" );
|
||
rbuggyMatches.push( "!=", pseudos );
|
||
});
|
||
}
|
||
|
||
rbuggyQSA = rbuggyQSA.length && new RegExp( rbuggyQSA.join("|") );
|
||
rbuggyMatches = rbuggyMatches.length && new RegExp( rbuggyMatches.join("|") );
|
||
|
||
/* Contains
|
||
---------------------------------------------------------------------- */
|
||
hasCompare = rnative.test( docElem.compareDocumentPosition );
|
||
|
||
// Element contains another
|
||
// Purposefully self-exclusive
|
||
// As in, an element does not contain itself
|
||
contains = hasCompare || rnative.test( docElem.contains ) ?
|
||
function( a, b ) {
|
||
var adown = a.nodeType === 9 ? a.documentElement : a,
|
||
bup = b && b.parentNode;
|
||
return a === bup || !!( bup && bup.nodeType === 1 && (
|
||
adown.contains ?
|
||
adown.contains( bup ) :
|
||
a.compareDocumentPosition && a.compareDocumentPosition( bup ) & 16
|
||
));
|
||
} :
|
||
function( a, b ) {
|
||
if ( b ) {
|
||
while ( (b = b.parentNode) ) {
|
||
if ( b === a ) {
|
||
return true;
|
||
}
|
||
}
|
||
}
|
||
return false;
|
||
};
|
||
|
||
/* Sorting
|
||
---------------------------------------------------------------------- */
|
||
|
||
// Document order sorting
|
||
sortOrder = hasCompare ?
|
||
function( a, b ) {
|
||
|
||
// Flag for duplicate removal
|
||
if ( a === b ) {
|
||
hasDuplicate = true;
|
||
return 0;
|
||
}
|
||
|
||
// Sort on method existence if only one input has compareDocumentPosition
|
||
var compare = !a.compareDocumentPosition - !b.compareDocumentPosition;
|
||
if ( compare ) {
|
||
return compare;
|
||
}
|
||
|
||
// Calculate position if both inputs belong to the same document
|
||
compare = ( a.ownerDocument || a ) === ( b.ownerDocument || b ) ?
|
||
a.compareDocumentPosition( b ) :
|
||
|
||
// Otherwise we know they are disconnected
|
||
1;
|
||
|
||
// Disconnected nodes
|
||
if ( compare & 1 ||
|
||
(!support.sortDetached && b.compareDocumentPosition( a ) === compare) ) {
|
||
|
||
// Choose the first element that is related to our preferred document
|
||
if ( a === document || a.ownerDocument === preferredDoc && contains(preferredDoc, a) ) {
|
||
return -1;
|
||
}
|
||
if ( b === document || b.ownerDocument === preferredDoc && contains(preferredDoc, b) ) {
|
||
return 1;
|
||
}
|
||
|
||
// Maintain original order
|
||
return sortInput ?
|
||
( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) :
|
||
0;
|
||
}
|
||
|
||
return compare & 4 ? -1 : 1;
|
||
} :
|
||
function( a, b ) {
|
||
// Exit early if the nodes are identical
|
||
if ( a === b ) {
|
||
hasDuplicate = true;
|
||
return 0;
|
||
}
|
||
|
||
var cur,
|
||
i = 0,
|
||
aup = a.parentNode,
|
||
bup = b.parentNode,
|
||
ap = [ a ],
|
||
bp = [ b ];
|
||
|
||
// Parentless nodes are either documents or disconnected
|
||
if ( !aup || !bup ) {
|
||
return a === document ? -1 :
|
||
b === document ? 1 :
|
||
aup ? -1 :
|
||
bup ? 1 :
|
||
sortInput ?
|
||
( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) :
|
||
0;
|
||
|
||
// If the nodes are siblings, we can do a quick check
|
||
} else if ( aup === bup ) {
|
||
return siblingCheck( a, b );
|
||
}
|
||
|
||
// Otherwise we need full lists of their ancestors for comparison
|
||
cur = a;
|
||
while ( (cur = cur.parentNode) ) {
|
||
ap.unshift( cur );
|
||
}
|
||
cur = b;
|
||
while ( (cur = cur.parentNode) ) {
|
||
bp.unshift( cur );
|
||
}
|
||
|
||
// Walk down the tree looking for a discrepancy
|
||
while ( ap[i] === bp[i] ) {
|
||
i++;
|
||
}
|
||
|
||
return i ?
|
||
// Do a sibling check if the nodes have a common ancestor
|
||
siblingCheck( ap[i], bp[i] ) :
|
||
|
||
// Otherwise nodes in our document sort first
|
||
ap[i] === preferredDoc ? -1 :
|
||
bp[i] === preferredDoc ? 1 :
|
||
0;
|
||
};
|
||
|
||
return document;
|
||
};
|
||
|
||
Sizzle.matches = function( expr, elements ) {
|
||
return Sizzle( expr, null, null, elements );
|
||
};
|
||
|
||
Sizzle.matchesSelector = function( elem, expr ) {
|
||
// Set document vars if needed
|
||
if ( ( elem.ownerDocument || elem ) !== document ) {
|
||
setDocument( elem );
|
||
}
|
||
|
||
// Make sure that attribute selectors are quoted
|
||
expr = expr.replace( rattributeQuotes, "='$1']" );
|
||
|
||
if ( support.matchesSelector && documentIsHTML &&
|
||
!compilerCache[ expr + " " ] &&
|
||
( !rbuggyMatches || !rbuggyMatches.test( expr ) ) &&
|
||
( !rbuggyQSA || !rbuggyQSA.test( expr ) ) ) {
|
||
|
||
try {
|
||
var ret = matches.call( elem, expr );
|
||
|
||
// IE 9's matchesSelector returns false on disconnected nodes
|
||
if ( ret || support.disconnectedMatch ||
|
||
// As well, disconnected nodes are said to be in a document
|
||
// fragment in IE 9
|
||
elem.document && elem.document.nodeType !== 11 ) {
|
||
return ret;
|
||
}
|
||
} catch (e) {}
|
||
}
|
||
|
||
return Sizzle( expr, document, null, [ elem ] ).length > 0;
|
||
};
|
||
|
||
Sizzle.contains = function( context, elem ) {
|
||
// Set document vars if needed
|
||
if ( ( context.ownerDocument || context ) !== document ) {
|
||
setDocument( context );
|
||
}
|
||
return contains( context, elem );
|
||
};
|
||
|
||
Sizzle.attr = function( elem, name ) {
|
||
// Set document vars if needed
|
||
if ( ( elem.ownerDocument || elem ) !== document ) {
|
||
setDocument( elem );
|
||
}
|
||
|
||
var fn = Expr.attrHandle[ name.toLowerCase() ],
|
||
// Don't get fooled by Object.prototype properties (jQuery #13807)
|
||
val = fn && hasOwn.call( Expr.attrHandle, name.toLowerCase() ) ?
|
||
fn( elem, name, !documentIsHTML ) :
|
||
undefined;
|
||
|
||
return val !== undefined ?
|
||
val :
|
||
support.attributes || !documentIsHTML ?
|
||
elem.getAttribute( name ) :
|
||
(val = elem.getAttributeNode(name)) && val.specified ?
|
||
val.value :
|
||
null;
|
||
};
|
||
|
||
Sizzle.escape = function( sel ) {
|
||
return (sel + "").replace( rcssescape, fcssescape );
|
||
};
|
||
|
||
Sizzle.error = function( msg ) {
|
||
throw new Error( "Syntax error, unrecognized expression: " + msg );
|
||
};
|
||
|
||
/**
|
||
* Document sorting and removing duplicates
|
||
* @param {ArrayLike} results
|
||
*/
|
||
Sizzle.uniqueSort = function( results ) {
|
||
var elem,
|
||
duplicates = [],
|
||
j = 0,
|
||
i = 0;
|
||
|
||
// Unless we *know* we can detect duplicates, assume their presence
|
||
hasDuplicate = !support.detectDuplicates;
|
||
sortInput = !support.sortStable && results.slice( 0 );
|
||
results.sort( sortOrder );
|
||
|
||
if ( hasDuplicate ) {
|
||
while ( (elem = results[i++]) ) {
|
||
if ( elem === results[ i ] ) {
|
||
j = duplicates.push( i );
|
||
}
|
||
}
|
||
while ( j-- ) {
|
||
results.splice( duplicates[ j ], 1 );
|
||
}
|
||
}
|
||
|
||
// Clear input after sorting to release objects
|
||
// See https://github.com/jquery/sizzle/pull/225
|
||
sortInput = null;
|
||
|
||
return results;
|
||
};
|
||
|
||
/**
|
||
* Utility function for retrieving the text value of an array of DOM nodes
|
||
* @param {Array|Element} elem
|
||
*/
|
||
getText = Sizzle.getText = function( elem ) {
|
||
var node,
|
||
ret = "",
|
||
i = 0,
|
||
nodeType = elem.nodeType;
|
||
|
||
if ( !nodeType ) {
|
||
// If no nodeType, this is expected to be an array
|
||
while ( (node = elem[i++]) ) {
|
||
// Do not traverse comment nodes
|
||
ret += getText( node );
|
||
}
|
||
} else if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) {
|
||
// Use textContent for elements
|
||
// innerText usage removed for consistency of new lines (jQuery #11153)
|
||
if ( typeof elem.textContent === "string" ) {
|
||
return elem.textContent;
|
||
} else {
|
||
// Traverse its children
|
||
for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {
|
||
ret += getText( elem );
|
||
}
|
||
}
|
||
} else if ( nodeType === 3 || nodeType === 4 ) {
|
||
return elem.nodeValue;
|
||
}
|
||
// Do not include comment or processing instruction nodes
|
||
|
||
return ret;
|
||
};
|
||
|
||
Expr = Sizzle.selectors = {
|
||
|
||
// Can be adjusted by the user
|
||
cacheLength: 50,
|
||
|
||
createPseudo: markFunction,
|
||
|
||
match: matchExpr,
|
||
|
||
attrHandle: {},
|
||
|
||
find: {},
|
||
|
||
relative: {
|
||
">": { dir: "parentNode", first: true },
|
||
" ": { dir: "parentNode" },
|
||
"+": { dir: "previousSibling", first: true },
|
||
"~": { dir: "previousSibling" }
|
||
},
|
||
|
||
preFilter: {
|
||
"ATTR": function( match ) {
|
||
match[1] = match[1].replace( runescape, funescape );
|
||
|
||
// Move the given value to match[3] whether quoted or unquoted
|
||
match[3] = ( match[3] || match[4] || match[5] || "" ).replace( runescape, funescape );
|
||
|
||
if ( match[2] === "~=" ) {
|
||
match[3] = " " + match[3] + " ";
|
||
}
|
||
|
||
return match.slice( 0, 4 );
|
||
},
|
||
|
||
"CHILD": function( match ) {
|
||
/* matches from matchExpr["CHILD"]
|
||
1 type (only|nth|...)
|
||
2 what (child|of-type)
|
||
3 argument (even|odd|\d*|\d*n([+-]\d+)?|...)
|
||
4 xn-component of xn+y argument ([+-]?\d*n|)
|
||
5 sign of xn-component
|
||
6 x of xn-component
|
||
7 sign of y-component
|
||
8 y of y-component
|
||
*/
|
||
match[1] = match[1].toLowerCase();
|
||
|
||
if ( match[1].slice( 0, 3 ) === "nth" ) {
|
||
// nth-* requires argument
|
||
if ( !match[3] ) {
|
||
Sizzle.error( match[0] );
|
||
}
|
||
|
||
// numeric x and y parameters for Expr.filter.CHILD
|
||
// remember that false/true cast respectively to 0/1
|
||
match[4] = +( match[4] ? match[5] + (match[6] || 1) : 2 * ( match[3] === "even" || match[3] === "odd" ) );
|
||
match[5] = +( ( match[7] + match[8] ) || match[3] === "odd" );
|
||
|
||
// other types prohibit arguments
|
||
} else if ( match[3] ) {
|
||
Sizzle.error( match[0] );
|
||
}
|
||
|
||
return match;
|
||
},
|
||
|
||
"PSEUDO": function( match ) {
|
||
var excess,
|
||
unquoted = !match[6] && match[2];
|
||
|
||
if ( matchExpr["CHILD"].test( match[0] ) ) {
|
||
return null;
|
||
}
|
||
|
||
// Accept quoted arguments as-is
|
||
if ( match[3] ) {
|
||
match[2] = match[4] || match[5] || "";
|
||
|
||
// Strip excess characters from unquoted arguments
|
||
} else if ( unquoted && rpseudo.test( unquoted ) &&
|
||
// Get excess from tokenize (recursively)
|
||
(excess = tokenize( unquoted, true )) &&
|
||
// advance to the next closing parenthesis
|
||
(excess = unquoted.indexOf( ")", unquoted.length - excess ) - unquoted.length) ) {
|
||
|
||
// excess is a negative index
|
||
match[0] = match[0].slice( 0, excess );
|
||
match[2] = unquoted.slice( 0, excess );
|
||
}
|
||
|
||
// Return only captures needed by the pseudo filter method (type and argument)
|
||
return match.slice( 0, 3 );
|
||
}
|
||
},
|
||
|
||
filter: {
|
||
|
||
"TAG": function( nodeNameSelector ) {
|
||
var nodeName = nodeNameSelector.replace( runescape, funescape ).toLowerCase();
|
||
return nodeNameSelector === "*" ?
|
||
function() { return true; } :
|
||
function( elem ) {
|
||
return elem.nodeName && elem.nodeName.toLowerCase() === nodeName;
|
||
};
|
||
},
|
||
|
||
"CLASS": function( className ) {
|
||
var pattern = classCache[ className + " " ];
|
||
|
||
return pattern ||
|
||
(pattern = new RegExp( "(^|" + whitespace + ")" + className + "(" + whitespace + "|$)" )) &&
|
||
classCache( className, function( elem ) {
|
||
return pattern.test( typeof elem.className === "string" && elem.className || typeof elem.getAttribute !== "undefined" && elem.getAttribute("class") || "" );
|
||
});
|
||
},
|
||
|
||
"ATTR": function( name, operator, check ) {
|
||
return function( elem ) {
|
||
var result = Sizzle.attr( elem, name );
|
||
|
||
if ( result == null ) {
|
||
return operator === "!=";
|
||
}
|
||
if ( !operator ) {
|
||
return true;
|
||
}
|
||
|
||
result += "";
|
||
|
||
return operator === "=" ? result === check :
|
||
operator === "!=" ? result !== check :
|
||
operator === "^=" ? check && result.indexOf( check ) === 0 :
|
||
operator === "*=" ? check && result.indexOf( check ) > -1 :
|
||
operator === "$=" ? check && result.slice( -check.length ) === check :
|
||
operator === "~=" ? ( " " + result.replace( rwhitespace, " " ) + " " ).indexOf( check ) > -1 :
|
||
operator === "|=" ? result === check || result.slice( 0, check.length + 1 ) === check + "-" :
|
||
false;
|
||
};
|
||
},
|
||
|
||
"CHILD": function( type, what, argument, first, last ) {
|
||
var simple = type.slice( 0, 3 ) !== "nth",
|
||
forward = type.slice( -4 ) !== "last",
|
||
ofType = what === "of-type";
|
||
|
||
return first === 1 && last === 0 ?
|
||
|
||
// Shortcut for :nth-*(n)
|
||
function( elem ) {
|
||
return !!elem.parentNode;
|
||
} :
|
||
|
||
function( elem, context, xml ) {
|
||
var cache, uniqueCache, outerCache, node, nodeIndex, start,
|
||
dir = simple !== forward ? "nextSibling" : "previousSibling",
|
||
parent = elem.parentNode,
|
||
name = ofType && elem.nodeName.toLowerCase(),
|
||
useCache = !xml && !ofType,
|
||
diff = false;
|
||
|
||
if ( parent ) {
|
||
|
||
// :(first|last|only)-(child|of-type)
|
||
if ( simple ) {
|
||
while ( dir ) {
|
||
node = elem;
|
||
while ( (node = node[ dir ]) ) {
|
||
if ( ofType ?
|
||
node.nodeName.toLowerCase() === name :
|
||
node.nodeType === 1 ) {
|
||
|
||
return false;
|
||
}
|
||
}
|
||
// Reverse direction for :only-* (if we haven't yet done so)
|
||
start = dir = type === "only" && !start && "nextSibling";
|
||
}
|
||
return true;
|
||
}
|
||
|
||
start = [ forward ? parent.firstChild : parent.lastChild ];
|
||
|
||
// non-xml :nth-child(...) stores cache data on `parent`
|
||
if ( forward && useCache ) {
|
||
|
||
// Seek `elem` from a previously-cached index
|
||
|
||
// ...in a gzip-friendly way
|
||
node = parent;
|
||
outerCache = node[ expando ] || (node[ expando ] = {});
|
||
|
||
// Support: IE <9 only
|
||
// Defend against cloned attroperties (jQuery gh-1709)
|
||
uniqueCache = outerCache[ node.uniqueID ] ||
|
||
(outerCache[ node.uniqueID ] = {});
|
||
|
||
cache = uniqueCache[ type ] || [];
|
||
nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ];
|
||
diff = nodeIndex && cache[ 2 ];
|
||
node = nodeIndex && parent.childNodes[ nodeIndex ];
|
||
|
||
while ( (node = ++nodeIndex && node && node[ dir ] ||
|
||
|
||
// Fallback to seeking `elem` from the start
|
||
(diff = nodeIndex = 0) || start.pop()) ) {
|
||
|
||
// When found, cache indexes on `parent` and break
|
||
if ( node.nodeType === 1 && ++diff && node === elem ) {
|
||
uniqueCache[ type ] = [ dirruns, nodeIndex, diff ];
|
||
break;
|
||
}
|
||
}
|
||
|
||
} else {
|
||
// Use previously-cached element index if available
|
||
if ( useCache ) {
|
||
// ...in a gzip-friendly way
|
||
node = elem;
|
||
outerCache = node[ expando ] || (node[ expando ] = {});
|
||
|
||
// Support: IE <9 only
|
||
// Defend against cloned attroperties (jQuery gh-1709)
|
||
uniqueCache = outerCache[ node.uniqueID ] ||
|
||
(outerCache[ node.uniqueID ] = {});
|
||
|
||
cache = uniqueCache[ type ] || [];
|
||
nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ];
|
||
diff = nodeIndex;
|
||
}
|
||
|
||
// xml :nth-child(...)
|
||
// or :nth-last-child(...) or :nth(-last)?-of-type(...)
|
||
if ( diff === false ) {
|
||
// Use the same loop as above to seek `elem` from the start
|
||
while ( (node = ++nodeIndex && node && node[ dir ] ||
|
||
(diff = nodeIndex = 0) || start.pop()) ) {
|
||
|
||
if ( ( ofType ?
|
||
node.nodeName.toLowerCase() === name :
|
||
node.nodeType === 1 ) &&
|
||
++diff ) {
|
||
|
||
// Cache the index of each encountered element
|
||
if ( useCache ) {
|
||
outerCache = node[ expando ] || (node[ expando ] = {});
|
||
|
||
// Support: IE <9 only
|
||
// Defend against cloned attroperties (jQuery gh-1709)
|
||
uniqueCache = outerCache[ node.uniqueID ] ||
|
||
(outerCache[ node.uniqueID ] = {});
|
||
|
||
uniqueCache[ type ] = [ dirruns, diff ];
|
||
}
|
||
|
||
if ( node === elem ) {
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
// Incorporate the offset, then check against cycle size
|
||
diff -= last;
|
||
return diff === first || ( diff % first === 0 && diff / first >= 0 );
|
||
}
|
||
};
|
||
},
|
||
|
||
"PSEUDO": function( pseudo, argument ) {
|
||
// pseudo-class names are case-insensitive
|
||
// http://www.w3.org/TR/selectors/#pseudo-classes
|
||
// Prioritize by case sensitivity in case custom pseudos are added with uppercase letters
|
||
// Remember that setFilters inherits from pseudos
|
||
var args,
|
||
fn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] ||
|
||
Sizzle.error( "unsupported pseudo: " + pseudo );
|
||
|
||
// The user may use createPseudo to indicate that
|
||
// arguments are needed to create the filter function
|
||
// just as Sizzle does
|
||
if ( fn[ expando ] ) {
|
||
return fn( argument );
|
||
}
|
||
|
||
// But maintain support for old signatures
|
||
if ( fn.length > 1 ) {
|
||
args = [ pseudo, pseudo, "", argument ];
|
||
return Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ?
|
||
markFunction(function( seed, matches ) {
|
||
var idx,
|
||
matched = fn( seed, argument ),
|
||
i = matched.length;
|
||
while ( i-- ) {
|
||
idx = indexOf( seed, matched[i] );
|
||
seed[ idx ] = !( matches[ idx ] = matched[i] );
|
||
}
|
||
}) :
|
||
function( elem ) {
|
||
return fn( elem, 0, args );
|
||
};
|
||
}
|
||
|
||
return fn;
|
||
}
|
||
},
|
||
|
||
pseudos: {
|
||
// Potentially complex pseudos
|
||
"not": markFunction(function( selector ) {
|
||
// Trim the selector passed to compile
|
||
// to avoid treating leading and trailing
|
||
// spaces as combinators
|
||
var input = [],
|
||
results = [],
|
||
matcher = compile( selector.replace( rtrim, "$1" ) );
|
||
|
||
return matcher[ expando ] ?
|
||
markFunction(function( seed, matches, context, xml ) {
|
||
var elem,
|
||
unmatched = matcher( seed, null, xml, [] ),
|
||
i = seed.length;
|
||
|
||
// Match elements unmatched by `matcher`
|
||
while ( i-- ) {
|
||
if ( (elem = unmatched[i]) ) {
|
||
seed[i] = !(matches[i] = elem);
|
||
}
|
||
}
|
||
}) :
|
||
function( elem, context, xml ) {
|
||
input[0] = elem;
|
||
matcher( input, null, xml, results );
|
||
// Don't keep the element (issue #299)
|
||
input[0] = null;
|
||
return !results.pop();
|
||
};
|
||
}),
|
||
|
||
"has": markFunction(function( selector ) {
|
||
return function( elem ) {
|
||
return Sizzle( selector, elem ).length > 0;
|
||
};
|
||
}),
|
||
|
||
"contains": markFunction(function( text ) {
|
||
text = text.replace( runescape, funescape );
|
||
return function( elem ) {
|
||
return ( elem.textContent || elem.innerText || getText( elem ) ).indexOf( text ) > -1;
|
||
};
|
||
}),
|
||
|
||
// "Whether an element is represented by a :lang() selector
|
||
// is based solely on the element's language value
|
||
// being equal to the identifier C,
|
||
// or beginning with the identifier C immediately followed by "-".
|
||
// The matching of C against the element's language value is performed case-insensitively.
|
||
// The identifier C does not have to be a valid language name."
|
||
// http://www.w3.org/TR/selectors/#lang-pseudo
|
||
"lang": markFunction( function( lang ) {
|
||
// lang value must be a valid identifier
|
||
if ( !ridentifier.test(lang || "") ) {
|
||
Sizzle.error( "unsupported lang: " + lang );
|
||
}
|
||
lang = lang.replace( runescape, funescape ).toLowerCase();
|
||
return function( elem ) {
|
||
var elemLang;
|
||
do {
|
||
if ( (elemLang = documentIsHTML ?
|
||
elem.lang :
|
||
elem.getAttribute("xml:lang") || elem.getAttribute("lang")) ) {
|
||
|
||
elemLang = elemLang.toLowerCase();
|
||
return elemLang === lang || elemLang.indexOf( lang + "-" ) === 0;
|
||
}
|
||
} while ( (elem = elem.parentNode) && elem.nodeType === 1 );
|
||
return false;
|
||
};
|
||
}),
|
||
|
||
// Miscellaneous
|
||
"target": function( elem ) {
|
||
var hash = window.location && window.location.hash;
|
||
return hash && hash.slice( 1 ) === elem.id;
|
||
},
|
||
|
||
"root": function( elem ) {
|
||
return elem === docElem;
|
||
},
|
||
|
||
"focus": function( elem ) {
|
||
return elem === document.activeElement && (!document.hasFocus || document.hasFocus()) && !!(elem.type || elem.href || ~elem.tabIndex);
|
||
},
|
||
|
||
// Boolean properties
|
||
"enabled": createDisabledPseudo( false ),
|
||
"disabled": createDisabledPseudo( true ),
|
||
|
||
"checked": function( elem ) {
|
||
// In CSS3, :checked should return both checked and selected elements
|
||
// http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked
|
||
var nodeName = elem.nodeName.toLowerCase();
|
||
return (nodeName === "input" && !!elem.checked) || (nodeName === "option" && !!elem.selected);
|
||
},
|
||
|
||
"selected": function( elem ) {
|
||
// Accessing this property makes selected-by-default
|
||
// options in Safari work properly
|
||
if ( elem.parentNode ) {
|
||
elem.parentNode.selectedIndex;
|
||
}
|
||
|
||
return elem.selected === true;
|
||
},
|
||
|
||
// Contents
|
||
"empty": function( elem ) {
|
||
// http://www.w3.org/TR/selectors/#empty-pseudo
|
||
// :empty is negated by element (1) or content nodes (text: 3; cdata: 4; entity ref: 5),
|
||
// but not by others (comment: 8; processing instruction: 7; etc.)
|
||
// nodeType < 6 works because attributes (2) do not appear as children
|
||
for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {
|
||
if ( elem.nodeType < 6 ) {
|
||
return false;
|
||
}
|
||
}
|
||
return true;
|
||
},
|
||
|
||
"parent": function( elem ) {
|
||
return !Expr.pseudos["empty"]( elem );
|
||
},
|
||
|
||
// Element/input types
|
||
"header": function( elem ) {
|
||
return rheader.test( elem.nodeName );
|
||
},
|
||
|
||
"input": function( elem ) {
|
||
return rinputs.test( elem.nodeName );
|
||
},
|
||
|
||
"button": function( elem ) {
|
||
var name = elem.nodeName.toLowerCase();
|
||
return name === "input" && elem.type === "button" || name === "button";
|
||
},
|
||
|
||
"text": function( elem ) {
|
||
var attr;
|
||
return elem.nodeName.toLowerCase() === "input" &&
|
||
elem.type === "text" &&
|
||
|
||
// Support: IE<8
|
||
// New HTML5 attribute values (e.g., "search") appear with elem.type === "text"
|
||
( (attr = elem.getAttribute("type")) == null || attr.toLowerCase() === "text" );
|
||
},
|
||
|
||
// Position-in-collection
|
||
"first": createPositionalPseudo(function() {
|
||
return [ 0 ];
|
||
}),
|
||
|
||
"last": createPositionalPseudo(function( matchIndexes, length ) {
|
||
return [ length - 1 ];
|
||
}),
|
||
|
||
"eq": createPositionalPseudo(function( matchIndexes, length, argument ) {
|
||
return [ argument < 0 ? argument + length : argument ];
|
||
}),
|
||
|
||
"even": createPositionalPseudo(function( matchIndexes, length ) {
|
||
var i = 0;
|
||
for ( ; i < length; i += 2 ) {
|
||
matchIndexes.push( i );
|
||
}
|
||
return matchIndexes;
|
||
}),
|
||
|
||
"odd": createPositionalPseudo(function( matchIndexes, length ) {
|
||
var i = 1;
|
||
for ( ; i < length; i += 2 ) {
|
||
matchIndexes.push( i );
|
||
}
|
||
return matchIndexes;
|
||
}),
|
||
|
||
"lt": createPositionalPseudo(function( matchIndexes, length, argument ) {
|
||
var i = argument < 0 ? argument + length : argument;
|
||
for ( ; --i >= 0; ) {
|
||
matchIndexes.push( i );
|
||
}
|
||
return matchIndexes;
|
||
}),
|
||
|
||
"gt": createPositionalPseudo(function( matchIndexes, length, argument ) {
|
||
var i = argument < 0 ? argument + length : argument;
|
||
for ( ; ++i < length; ) {
|
||
matchIndexes.push( i );
|
||
}
|
||
return matchIndexes;
|
||
})
|
||
}
|
||
};
|
||
|
||
Expr.pseudos["nth"] = Expr.pseudos["eq"];
|
||
|
||
// Add button/input type pseudos
|
||
for ( i in { radio: true, checkbox: true, file: true, password: true, image: true } ) {
|
||
Expr.pseudos[ i ] = createInputPseudo( i );
|
||
}
|
||
for ( i in { submit: true, reset: true } ) {
|
||
Expr.pseudos[ i ] = createButtonPseudo( i );
|
||
}
|
||
|
||
// Easy API for creating new setFilters
|
||
function setFilters() {}
|
||
setFilters.prototype = Expr.filters = Expr.pseudos;
|
||
Expr.setFilters = new setFilters();
|
||
|
||
tokenize = Sizzle.tokenize = function( selector, parseOnly ) {
|
||
var matched, match, tokens, type,
|
||
soFar, groups, preFilters,
|
||
cached = tokenCache[ selector + " " ];
|
||
|
||
if ( cached ) {
|
||
return parseOnly ? 0 : cached.slice( 0 );
|
||
}
|
||
|
||
soFar = selector;
|
||
groups = [];
|
||
preFilters = Expr.preFilter;
|
||
|
||
while ( soFar ) {
|
||
|
||
// Comma and first run
|
||
if ( !matched || (match = rcomma.exec( soFar )) ) {
|
||
if ( match ) {
|
||
// Don't consume trailing commas as valid
|
||
soFar = soFar.slice( match[0].length ) || soFar;
|
||
}
|
||
groups.push( (tokens = []) );
|
||
}
|
||
|
||
matched = false;
|
||
|
||
// Combinators
|
||
if ( (match = rcombinators.exec( soFar )) ) {
|
||
matched = match.shift();
|
||
tokens.push({
|
||
value: matched,
|
||
// Cast descendant combinators to space
|
||
type: match[0].replace( rtrim, " " )
|
||
});
|
||
soFar = soFar.slice( matched.length );
|
||
}
|
||
|
||
// Filters
|
||
for ( type in Expr.filter ) {
|
||
if ( (match = matchExpr[ type ].exec( soFar )) && (!preFilters[ type ] ||
|
||
(match = preFilters[ type ]( match ))) ) {
|
||
matched = match.shift();
|
||
tokens.push({
|
||
value: matched,
|
||
type: type,
|
||
matches: match
|
||
});
|
||
soFar = soFar.slice( matched.length );
|
||
}
|
||
}
|
||
|
||
if ( !matched ) {
|
||
break;
|
||
}
|
||
}
|
||
|
||
// Return the length of the invalid excess
|
||
// if we're just parsing
|
||
// Otherwise, throw an error or return tokens
|
||
return parseOnly ?
|
||
soFar.length :
|
||
soFar ?
|
||
Sizzle.error( selector ) :
|
||
// Cache the tokens
|
||
tokenCache( selector, groups ).slice( 0 );
|
||
};
|
||
|
||
function toSelector( tokens ) {
|
||
var i = 0,
|
||
len = tokens.length,
|
||
selector = "";
|
||
for ( ; i < len; i++ ) {
|
||
selector += tokens[i].value;
|
||
}
|
||
return selector;
|
||
}
|
||
|
||
function addCombinator( matcher, combinator, base ) {
|
||
var dir = combinator.dir,
|
||
skip = combinator.next,
|
||
key = skip || dir,
|
||
checkNonElements = base && key === "parentNode",
|
||
doneName = done++;
|
||
|
||
return combinator.first ?
|
||
// Check against closest ancestor/preceding element
|
||
function( elem, context, xml ) {
|
||
while ( (elem = elem[ dir ]) ) {
|
||
if ( elem.nodeType === 1 || checkNonElements ) {
|
||
return matcher( elem, context, xml );
|
||
}
|
||
}
|
||
return false;
|
||
} :
|
||
|
||
// Check against all ancestor/preceding elements
|
||
function( elem, context, xml ) {
|
||
var oldCache, uniqueCache, outerCache,
|
||
newCache = [ dirruns, doneName ];
|
||
|
||
// We can't set arbitrary data on XML nodes, so they don't benefit from combinator caching
|
||
if ( xml ) {
|
||
while ( (elem = elem[ dir ]) ) {
|
||
if ( elem.nodeType === 1 || checkNonElements ) {
|
||
if ( matcher( elem, context, xml ) ) {
|
||
return true;
|
||
}
|
||
}
|
||
}
|
||
} else {
|
||
while ( (elem = elem[ dir ]) ) {
|
||
if ( elem.nodeType === 1 || checkNonElements ) {
|
||
outerCache = elem[ expando ] || (elem[ expando ] = {});
|
||
|
||
// Support: IE <9 only
|
||
// Defend against cloned attroperties (jQuery gh-1709)
|
||
uniqueCache = outerCache[ elem.uniqueID ] || (outerCache[ elem.uniqueID ] = {});
|
||
|
||
if ( skip && skip === elem.nodeName.toLowerCase() ) {
|
||
elem = elem[ dir ] || elem;
|
||
} else if ( (oldCache = uniqueCache[ key ]) &&
|
||
oldCache[ 0 ] === dirruns && oldCache[ 1 ] === doneName ) {
|
||
|
||
// Assign to newCache so results back-propagate to previous elements
|
||
return (newCache[ 2 ] = oldCache[ 2 ]);
|
||
} else {
|
||
// Reuse newcache so results back-propagate to previous elements
|
||
uniqueCache[ key ] = newCache;
|
||
|
||
// A match means we're done; a fail means we have to keep checking
|
||
if ( (newCache[ 2 ] = matcher( elem, context, xml )) ) {
|
||
return true;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
return false;
|
||
};
|
||
}
|
||
|
||
function elementMatcher( matchers ) {
|
||
return matchers.length > 1 ?
|
||
function( elem, context, xml ) {
|
||
var i = matchers.length;
|
||
while ( i-- ) {
|
||
if ( !matchers[i]( elem, context, xml ) ) {
|
||
return false;
|
||
}
|
||
}
|
||
return true;
|
||
} :
|
||
matchers[0];
|
||
}
|
||
|
||
function multipleContexts( selector, contexts, results ) {
|
||
var i = 0,
|
||
len = contexts.length;
|
||
for ( ; i < len; i++ ) {
|
||
Sizzle( selector, contexts[i], results );
|
||
}
|
||
return results;
|
||
}
|
||
|
||
function condense( unmatched, map, filter, context, xml ) {
|
||
var elem,
|
||
newUnmatched = [],
|
||
i = 0,
|
||
len = unmatched.length,
|
||
mapped = map != null;
|
||
|
||
for ( ; i < len; i++ ) {
|
||
if ( (elem = unmatched[i]) ) {
|
||
if ( !filter || filter( elem, context, xml ) ) {
|
||
newUnmatched.push( elem );
|
||
if ( mapped ) {
|
||
map.push( i );
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
return newUnmatched;
|
||
}
|
||
|
||
function setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) {
|
||
if ( postFilter && !postFilter[ expando ] ) {
|
||
postFilter = setMatcher( postFilter );
|
||
}
|
||
if ( postFinder && !postFinder[ expando ] ) {
|
||
postFinder = setMatcher( postFinder, postSelector );
|
||
}
|
||
return markFunction(function( seed, results, context, xml ) {
|
||
var temp, i, elem,
|
||
preMap = [],
|
||
postMap = [],
|
||
preexisting = results.length,
|
||
|
||
// Get initial elements from seed or context
|
||
elems = seed || multipleContexts( selector || "*", context.nodeType ? [ context ] : context, [] ),
|
||
|
||
// Prefilter to get matcher input, preserving a map for seed-results synchronization
|
||
matcherIn = preFilter && ( seed || !selector ) ?
|
||
condense( elems, preMap, preFilter, context, xml ) :
|
||
elems,
|
||
|
||
matcherOut = matcher ?
|
||
// If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results,
|
||
postFinder || ( seed ? preFilter : preexisting || postFilter ) ?
|
||
|
||
// ...intermediate processing is necessary
|
||
[] :
|
||
|
||
// ...otherwise use results directly
|
||
results :
|
||
matcherIn;
|
||
|
||
// Find primary matches
|
||
if ( matcher ) {
|
||
matcher( matcherIn, matcherOut, context, xml );
|
||
}
|
||
|
||
// Apply postFilter
|
||
if ( postFilter ) {
|
||
temp = condense( matcherOut, postMap );
|
||
postFilter( temp, [], context, xml );
|
||
|
||
// Un-match failing elements by moving them back to matcherIn
|
||
i = temp.length;
|
||
while ( i-- ) {
|
||
if ( (elem = temp[i]) ) {
|
||
matcherOut[ postMap[i] ] = !(matcherIn[ postMap[i] ] = elem);
|
||
}
|
||
}
|
||
}
|
||
|
||
if ( seed ) {
|
||
if ( postFinder || preFilter ) {
|
||
if ( postFinder ) {
|
||
// Get the final matcherOut by condensing this intermediate into postFinder contexts
|
||
temp = [];
|
||
i = matcherOut.length;
|
||
while ( i-- ) {
|
||
if ( (elem = matcherOut[i]) ) {
|
||
// Restore matcherIn since elem is not yet a final match
|
||
temp.push( (matcherIn[i] = elem) );
|
||
}
|
||
}
|
||
postFinder( null, (matcherOut = []), temp, xml );
|
||
}
|
||
|
||
// Move matched elements from seed to results to keep them synchronized
|
||
i = matcherOut.length;
|
||
while ( i-- ) {
|
||
if ( (elem = matcherOut[i]) &&
|
||
(temp = postFinder ? indexOf( seed, elem ) : preMap[i]) > -1 ) {
|
||
|
||
seed[temp] = !(results[temp] = elem);
|
||
}
|
||
}
|
||
}
|
||
|
||
// Add elements to results, through postFinder if defined
|
||
} else {
|
||
matcherOut = condense(
|
||
matcherOut === results ?
|
||
matcherOut.splice( preexisting, matcherOut.length ) :
|
||
matcherOut
|
||
);
|
||
if ( postFinder ) {
|
||
postFinder( null, results, matcherOut, xml );
|
||
} else {
|
||
push.apply( results, matcherOut );
|
||
}
|
||
}
|
||
});
|
||
}
|
||
|
||
function matcherFromTokens( tokens ) {
|
||
var checkContext, matcher, j,
|
||
len = tokens.length,
|
||
leadingRelative = Expr.relative[ tokens[0].type ],
|
||
implicitRelative = leadingRelative || Expr.relative[" "],
|
||
i = leadingRelative ? 1 : 0,
|
||
|
||
// The foundational matcher ensures that elements are reachable from top-level context(s)
|
||
matchContext = addCombinator( function( elem ) {
|
||
return elem === checkContext;
|
||
}, implicitRelative, true ),
|
||
matchAnyContext = addCombinator( function( elem ) {
|
||
return indexOf( checkContext, elem ) > -1;
|
||
}, implicitRelative, true ),
|
||
matchers = [ function( elem, context, xml ) {
|
||
var ret = ( !leadingRelative && ( xml || context !== outermostContext ) ) || (
|
||
(checkContext = context).nodeType ?
|
||
matchContext( elem, context, xml ) :
|
||
matchAnyContext( elem, context, xml ) );
|
||
// Avoid hanging onto element (issue #299)
|
||
checkContext = null;
|
||
return ret;
|
||
} ];
|
||
|
||
for ( ; i < len; i++ ) {
|
||
if ( (matcher = Expr.relative[ tokens[i].type ]) ) {
|
||
matchers = [ addCombinator(elementMatcher( matchers ), matcher) ];
|
||
} else {
|
||
matcher = Expr.filter[ tokens[i].type ].apply( null, tokens[i].matches );
|
||
|
||
// Return special upon seeing a positional matcher
|
||
if ( matcher[ expando ] ) {
|
||
// Find the next relative operator (if any) for proper handling
|
||
j = ++i;
|
||
for ( ; j < len; j++ ) {
|
||
if ( Expr.relative[ tokens[j].type ] ) {
|
||
break;
|
||
}
|
||
}
|
||
return setMatcher(
|
||
i > 1 && elementMatcher( matchers ),
|
||
i > 1 && toSelector(
|
||
// If the preceding token was a descendant combinator, insert an implicit any-element `*`
|
||
tokens.slice( 0, i - 1 ).concat({ value: tokens[ i - 2 ].type === " " ? "*" : "" })
|
||
).replace( rtrim, "$1" ),
|
||
matcher,
|
||
i < j && matcherFromTokens( tokens.slice( i, j ) ),
|
||
j < len && matcherFromTokens( (tokens = tokens.slice( j )) ),
|
||
j < len && toSelector( tokens )
|
||
);
|
||
}
|
||
matchers.push( matcher );
|
||
}
|
||
}
|
||
|
||
return elementMatcher( matchers );
|
||
}
|
||
|
||
function matcherFromGroupMatchers( elementMatchers, setMatchers ) {
|
||
var bySet = setMatchers.length > 0,
|
||
byElement = elementMatchers.length > 0,
|
||
superMatcher = function( seed, context, xml, results, outermost ) {
|
||
var elem, j, matcher,
|
||
matchedCount = 0,
|
||
i = "0",
|
||
unmatched = seed && [],
|
||
setMatched = [],
|
||
contextBackup = outermostContext,
|
||
// We must always have either seed elements or outermost context
|
||
elems = seed || byElement && Expr.find["TAG"]( "*", outermost ),
|
||
// Use integer dirruns iff this is the outermost matcher
|
||
dirrunsUnique = (dirruns += contextBackup == null ? 1 : Math.random() || 0.1),
|
||
len = elems.length;
|
||
|
||
if ( outermost ) {
|
||
outermostContext = context === document || context || outermost;
|
||
}
|
||
|
||
// Add elements passing elementMatchers directly to results
|
||
// Support: IE<9, Safari
|
||
// Tolerate NodeList properties (IE: "length"; Safari: <number>) matching elements by id
|
||
for ( ; i !== len && (elem = elems[i]) != null; i++ ) {
|
||
if ( byElement && elem ) {
|
||
j = 0;
|
||
if ( !context && elem.ownerDocument !== document ) {
|
||
setDocument( elem );
|
||
xml = !documentIsHTML;
|
||
}
|
||
while ( (matcher = elementMatchers[j++]) ) {
|
||
if ( matcher( elem, context || document, xml) ) {
|
||
results.push( elem );
|
||
break;
|
||
}
|
||
}
|
||
if ( outermost ) {
|
||
dirruns = dirrunsUnique;
|
||
}
|
||
}
|
||
|
||
// Track unmatched elements for set filters
|
||
if ( bySet ) {
|
||
// They will have gone through all possible matchers
|
||
if ( (elem = !matcher && elem) ) {
|
||
matchedCount--;
|
||
}
|
||
|
||
// Lengthen the array for every element, matched or not
|
||
if ( seed ) {
|
||
unmatched.push( elem );
|
||
}
|
||
}
|
||
}
|
||
|
||
// `i` is now the count of elements visited above, and adding it to `matchedCount`
|
||
// makes the latter nonnegative.
|
||
matchedCount += i;
|
||
|
||
// Apply set filters to unmatched elements
|
||
// NOTE: This can be skipped if there are no unmatched elements (i.e., `matchedCount`
|
||
// equals `i`), unless we didn't visit _any_ elements in the above loop because we have
|
||
// no element matchers and no seed.
|
||
// Incrementing an initially-string "0" `i` allows `i` to remain a string only in that
|
||
// case, which will result in a "00" `matchedCount` that differs from `i` but is also
|
||
// numerically zero.
|
||
if ( bySet && i !== matchedCount ) {
|
||
j = 0;
|
||
while ( (matcher = setMatchers[j++]) ) {
|
||
matcher( unmatched, setMatched, context, xml );
|
||
}
|
||
|
||
if ( seed ) {
|
||
// Reintegrate element matches to eliminate the need for sorting
|
||
if ( matchedCount > 0 ) {
|
||
while ( i-- ) {
|
||
if ( !(unmatched[i] || setMatched[i]) ) {
|
||
setMatched[i] = pop.call( results );
|
||
}
|
||
}
|
||
}
|
||
|
||
// Discard index placeholder values to get only actual matches
|
||
setMatched = condense( setMatched );
|
||
}
|
||
|
||
// Add matches to results
|
||
push.apply( results, setMatched );
|
||
|
||
// Seedless set matches succeeding multiple successful matchers stipulate sorting
|
||
if ( outermost && !seed && setMatched.length > 0 &&
|
||
( matchedCount + setMatchers.length ) > 1 ) {
|
||
|
||
Sizzle.uniqueSort( results );
|
||
}
|
||
}
|
||
|
||
// Override manipulation of globals by nested matchers
|
||
if ( outermost ) {
|
||
dirruns = dirrunsUnique;
|
||
outermostContext = contextBackup;
|
||
}
|
||
|
||
return unmatched;
|
||
};
|
||
|
||
return bySet ?
|
||
markFunction( superMatcher ) :
|
||
superMatcher;
|
||
}
|
||
|
||
compile = Sizzle.compile = function( selector, match /* Internal Use Only */ ) {
|
||
var i,
|
||
setMatchers = [],
|
||
elementMatchers = [],
|
||
cached = compilerCache[ selector + " " ];
|
||
|
||
if ( !cached ) {
|
||
// Generate a function of recursive functions that can be used to check each element
|
||
if ( !match ) {
|
||
match = tokenize( selector );
|
||
}
|
||
i = match.length;
|
||
while ( i-- ) {
|
||
cached = matcherFromTokens( match[i] );
|
||
if ( cached[ expando ] ) {
|
||
setMatchers.push( cached );
|
||
} else {
|
||
elementMatchers.push( cached );
|
||
}
|
||
}
|
||
|
||
// Cache the compiled function
|
||
cached = compilerCache( selector, matcherFromGroupMatchers( elementMatchers, setMatchers ) );
|
||
|
||
// Save selector and tokenization
|
||
cached.selector = selector;
|
||
}
|
||
return cached;
|
||
};
|
||
|
||
/**
|
||
* A low-level selection function that works with Sizzle's compiled
|
||
* selector functions
|
||
* @param {String|Function} selector A selector or a pre-compiled
|
||
* selector function built with Sizzle.compile
|
||
* @param {Element} context
|
||
* @param {Array} [results]
|
||
* @param {Array} [seed] A set of elements to match against
|
||
*/
|
||
select = Sizzle.select = function( selector, context, results, seed ) {
|
||
var i, tokens, token, type, find,
|
||
compiled = typeof selector === "function" && selector,
|
||
match = !seed && tokenize( (selector = compiled.selector || selector) );
|
||
|
||
results = results || [];
|
||
|
||
// Try to minimize operations if there is only one selector in the list and no seed
|
||
// (the latter of which guarantees us context)
|
||
if ( match.length === 1 ) {
|
||
|
||
// Reduce context if the leading compound selector is an ID
|
||
tokens = match[0] = match[0].slice( 0 );
|
||
if ( tokens.length > 2 && (token = tokens[0]).type === "ID" &&
|
||
context.nodeType === 9 && documentIsHTML && Expr.relative[ tokens[1].type ] ) {
|
||
|
||
context = ( Expr.find["ID"]( token.matches[0].replace(runescape, funescape), context ) || [] )[0];
|
||
if ( !context ) {
|
||
return results;
|
||
|
||
// Precompiled matchers will still verify ancestry, so step up a level
|
||
} else if ( compiled ) {
|
||
context = context.parentNode;
|
||
}
|
||
|
||
selector = selector.slice( tokens.shift().value.length );
|
||
}
|
||
|
||
// Fetch a seed set for right-to-left matching
|
||
i = matchExpr["needsContext"].test( selector ) ? 0 : tokens.length;
|
||
while ( i-- ) {
|
||
token = tokens[i];
|
||
|
||
// Abort if we hit a combinator
|
||
if ( Expr.relative[ (type = token.type) ] ) {
|
||
break;
|
||
}
|
||
if ( (find = Expr.find[ type ]) ) {
|
||
// Search, expanding context for leading sibling combinators
|
||
if ( (seed = find(
|
||
token.matches[0].replace( runescape, funescape ),
|
||
rsibling.test( tokens[0].type ) && testContext( context.parentNode ) || context
|
||
)) ) {
|
||
|
||
// If seed is empty or no tokens remain, we can return early
|
||
tokens.splice( i, 1 );
|
||
selector = seed.length && toSelector( tokens );
|
||
if ( !selector ) {
|
||
push.apply( results, seed );
|
||
return results;
|
||
}
|
||
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
// Compile and execute a filtering function if one is not provided
|
||
// Provide `match` to avoid retokenization if we modified the selector above
|
||
( compiled || compile( selector, match ) )(
|
||
seed,
|
||
context,
|
||
!documentIsHTML,
|
||
results,
|
||
!context || rsibling.test( selector ) && testContext( context.parentNode ) || context
|
||
);
|
||
return results;
|
||
};
|
||
|
||
// One-time assignments
|
||
|
||
// Sort stability
|
||
support.sortStable = expando.split("").sort( sortOrder ).join("") === expando;
|
||
|
||
// Support: Chrome 14-35+
|
||
// Always assume duplicates if they aren't passed to the comparison function
|
||
support.detectDuplicates = !!hasDuplicate;
|
||
|
||
// Initialize against the default document
|
||
setDocument();
|
||
|
||
// Support: Webkit<537.32 - Safari 6.0.3/Chrome 25 (fixed in Chrome 27)
|
||
// Detached nodes confoundingly follow *each other*
|
||
support.sortDetached = assert(function( el ) {
|
||
// Should return 1, but returns 4 (following)
|
||
return el.compareDocumentPosition( document.createElement("fieldset") ) & 1;
|
||
});
|
||
|
||
// Support: IE<8
|
||
// Prevent attribute/property "interpolation"
|
||
// https://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx
|
||
if ( !assert(function( el ) {
|
||
el.innerHTML = "<a href='#'></a>";
|
||
return el.firstChild.getAttribute("href") === "#" ;
|
||
}) ) {
|
||
addHandle( "type|href|height|width", function( elem, name, isXML ) {
|
||
if ( !isXML ) {
|
||
return elem.getAttribute( name, name.toLowerCase() === "type" ? 1 : 2 );
|
||
}
|
||
});
|
||
}
|
||
|
||
// Support: IE<9
|
||
// Use defaultValue in place of getAttribute("value")
|
||
if ( !support.attributes || !assert(function( el ) {
|
||
el.innerHTML = "<input/>";
|
||
el.firstChild.setAttribute( "value", "" );
|
||
return el.firstChild.getAttribute( "value" ) === "";
|
||
}) ) {
|
||
addHandle( "value", function( elem, name, isXML ) {
|
||
if ( !isXML && elem.nodeName.toLowerCase() === "input" ) {
|
||
return elem.defaultValue;
|
||
}
|
||
});
|
||
}
|
||
|
||
// Support: IE<9
|
||
// Use getAttributeNode to fetch booleans when getAttribute lies
|
||
if ( !assert(function( el ) {
|
||
return el.getAttribute("disabled") == null;
|
||
}) ) {
|
||
addHandle( booleans, function( elem, name, isXML ) {
|
||
var val;
|
||
if ( !isXML ) {
|
||
return elem[ name ] === true ? name.toLowerCase() :
|
||
(val = elem.getAttributeNode( name )) && val.specified ?
|
||
val.value :
|
||
null;
|
||
}
|
||
});
|
||
}
|
||
|
||
return Sizzle;
|
||
|
||
})( window );
|
||
|
||
|
||
|
||
jQuery.find = Sizzle;
|
||
jQuery.expr = Sizzle.selectors;
|
||
|
||
// Deprecated
|
||
jQuery.expr[ ":" ] = jQuery.expr.pseudos;
|
||
jQuery.uniqueSort = jQuery.unique = Sizzle.uniqueSort;
|
||
jQuery.text = Sizzle.getText;
|
||
jQuery.isXMLDoc = Sizzle.isXML;
|
||
jQuery.contains = Sizzle.contains;
|
||
jQuery.escapeSelector = Sizzle.escape;
|
||
|
||
|
||
|
||
|
||
var dir = function( elem, dir, until ) {
|
||
var matched = [],
|
||
truncate = until !== undefined;
|
||
|
||
while ( ( elem = elem[ dir ] ) && elem.nodeType !== 9 ) {
|
||
if ( elem.nodeType === 1 ) {
|
||
if ( truncate && jQuery( elem ).is( until ) ) {
|
||
break;
|
||
}
|
||
matched.push( elem );
|
||
}
|
||
}
|
||
return matched;
|
||
};
|
||
|
||
|
||
var siblings = function( n, elem ) {
|
||
var matched = [];
|
||
|
||
for ( ; n; n = n.nextSibling ) {
|
||
if ( n.nodeType === 1 && n !== elem ) {
|
||
matched.push( n );
|
||
}
|
||
}
|
||
|
||
return matched;
|
||
};
|
||
|
||
|
||
var rneedsContext = jQuery.expr.match.needsContext;
|
||
|
||
|
||
|
||
function nodeName( elem, name ) {
|
||
|
||
return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase();
|
||
|
||
};
|
||
var rsingleTag = ( /^<([a-z][^\/\0>:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i );
|
||
|
||
|
||
|
||
var risSimple = /^.[^:#\[\.,]*$/;
|
||
|
||
// Implement the identical functionality for filter and not
|
||
function winnow( elements, qualifier, not ) {
|
||
if ( jQuery.isFunction( qualifier ) ) {
|
||
return jQuery.grep( elements, function( elem, i ) {
|
||
return !!qualifier.call( elem, i, elem ) !== not;
|
||
} );
|
||
}
|
||
|
||
// Single element
|
||
if ( qualifier.nodeType ) {
|
||
return jQuery.grep( elements, function( elem ) {
|
||
return ( elem === qualifier ) !== not;
|
||
} );
|
||
}
|
||
|
||
// Arraylike of elements (jQuery, arguments, Array)
|
||
if ( typeof qualifier !== "string" ) {
|
||
return jQuery.grep( elements, function( elem ) {
|
||
return ( indexOf.call( qualifier, elem ) > -1 ) !== not;
|
||
} );
|
||
}
|
||
|
||
// Simple selector that can be filtered directly, removing non-Elements
|
||
if ( risSimple.test( qualifier ) ) {
|
||
return jQuery.filter( qualifier, elements, not );
|
||
}
|
||
|
||
// Complex selector, compare the two sets, removing non-Elements
|
||
qualifier = jQuery.filter( qualifier, elements );
|
||
return jQuery.grep( elements, function( elem ) {
|
||
return ( indexOf.call( qualifier, elem ) > -1 ) !== not && elem.nodeType === 1;
|
||
} );
|
||
}
|
||
|
||
jQuery.filter = function( expr, elems, not ) {
|
||
var elem = elems[ 0 ];
|
||
|
||
if ( not ) {
|
||
expr = ":not(" + expr + ")";
|
||
}
|
||
|
||
if ( elems.length === 1 && elem.nodeType === 1 ) {
|
||
return jQuery.find.matchesSelector( elem, expr ) ? [ elem ] : [];
|
||
}
|
||
|
||
return jQuery.find.matches( expr, jQuery.grep( elems, function( elem ) {
|
||
return elem.nodeType === 1;
|
||
} ) );
|
||
};
|
||
|
||
jQuery.fn.extend( {
|
||
find: function( selector ) {
|
||
var i, ret,
|
||
len = this.length,
|
||
self = this;
|
||
|
||
if ( typeof selector !== "string" ) {
|
||
return this.pushStack( jQuery( selector ).filter( function() {
|
||
for ( i = 0; i < len; i++ ) {
|
||
if ( jQuery.contains( self[ i ], this ) ) {
|
||
return true;
|
||
}
|
||
}
|
||
} ) );
|
||
}
|
||
|
||
ret = this.pushStack( [] );
|
||
|
||
for ( i = 0; i < len; i++ ) {
|
||
jQuery.find( selector, self[ i ], ret );
|
||
}
|
||
|
||
return len > 1 ? jQuery.uniqueSort( ret ) : ret;
|
||
},
|
||
filter: function( selector ) {
|
||
return this.pushStack( winnow( this, selector || [], false ) );
|
||
},
|
||
not: function( selector ) {
|
||
return this.pushStack( winnow( this, selector || [], true ) );
|
||
},
|
||
is: function( selector ) {
|
||
return !!winnow(
|
||
this,
|
||
|
||
// If this is a positional/relative selector, check membership in the returned set
|
||
// so $("p:first").is("p:last") won't return true for a doc with two "p".
|
||
typeof selector === "string" && rneedsContext.test( selector ) ?
|
||
jQuery( selector ) :
|
||
selector || [],
|
||
false
|
||
).length;
|
||
}
|
||
} );
|
||
|
||
|
||
// Initialize a jQuery object
|
||
|
||
|
||
// A central reference to the root jQuery(document)
|
||
var rootjQuery,
|
||
|
||
// A simple way to check for HTML strings
|
||
// Prioritize #id over <tag> to avoid XSS via location.hash (#9521)
|
||
// Strict HTML recognition (#11290: must start with <)
|
||
// Shortcut simple #id case for speed
|
||
rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]+))$/,
|
||
|
||
init = jQuery.fn.init = function( selector, context, root ) {
|
||
var match, elem;
|
||
|
||
// HANDLE: $(""), $(null), $(undefined), $(false)
|
||
if ( !selector ) {
|
||
return this;
|
||
}
|
||
|
||
// Method init() accepts an alternate rootjQuery
|
||
// so migrate can support jQuery.sub (gh-2101)
|
||
root = root || rootjQuery;
|
||
|
||
// Handle HTML strings
|
||
if ( typeof selector === "string" ) {
|
||
if ( selector[ 0 ] === "<" &&
|
||
selector[ selector.length - 1 ] === ">" &&
|
||
selector.length >= 3 ) {
|
||
|
||
// Assume that strings that start and end with <> are HTML and skip the regex check
|
||
match = [ null, selector, null ];
|
||
|
||
} else {
|
||
match = rquickExpr.exec( selector );
|
||
}
|
||
|
||
// Match html or make sure no context is specified for #id
|
||
if ( match && ( match[ 1 ] || !context ) ) {
|
||
|
||
// HANDLE: $(html) -> $(array)
|
||
if ( match[ 1 ] ) {
|
||
context = context instanceof jQuery ? context[ 0 ] : context;
|
||
|
||
// Option to run scripts is true for back-compat
|
||
// Intentionally let the error be thrown if parseHTML is not present
|
||
jQuery.merge( this, jQuery.parseHTML(
|
||
match[ 1 ],
|
||
context && context.nodeType ? context.ownerDocument || context : document,
|
||
true
|
||
) );
|
||
|
||
// HANDLE: $(html, props)
|
||
if ( rsingleTag.test( match[ 1 ] ) && jQuery.isPlainObject( context ) ) {
|
||
for ( match in context ) {
|
||
|
||
// Properties of context are called as methods if possible
|
||
if ( jQuery.isFunction( this[ match ] ) ) {
|
||
this[ match ]( context[ match ] );
|
||
|
||
// ...and otherwise set as attributes
|
||
} else {
|
||
this.attr( match, context[ match ] );
|
||
}
|
||
}
|
||
}
|
||
|
||
return this;
|
||
|
||
// HANDLE: $(#id)
|
||
} else {
|
||
elem = document.getElementById( match[ 2 ] );
|
||
|
||
if ( elem ) {
|
||
|
||
// Inject the element directly into the jQuery object
|
||
this[ 0 ] = elem;
|
||
this.length = 1;
|
||
}
|
||
return this;
|
||
}
|
||
|
||
// HANDLE: $(expr, $(...))
|
||
} else if ( !context || context.jquery ) {
|
||
return ( context || root ).find( selector );
|
||
|
||
// HANDLE: $(expr, context)
|
||
// (which is just equivalent to: $(context).find(expr)
|
||
} else {
|
||
return this.constructor( context ).find( selector );
|
||
}
|
||
|
||
// HANDLE: $(DOMElement)
|
||
} else if ( selector.nodeType ) {
|
||
this[ 0 ] = selector;
|
||
this.length = 1;
|
||
return this;
|
||
|
||
// HANDLE: $(function)
|
||
// Shortcut for document ready
|
||
} else if ( jQuery.isFunction( selector ) ) {
|
||
return root.ready !== undefined ?
|
||
root.ready( selector ) :
|
||
|
||
// Execute immediately if ready is not present
|
||
selector( jQuery );
|
||
}
|
||
|
||
return jQuery.makeArray( selector, this );
|
||
};
|
||
|
||
// Give the init function the jQuery prototype for later instantiation
|
||
init.prototype = jQuery.fn;
|
||
|
||
// Initialize central reference
|
||
rootjQuery = jQuery( document );
|
||
|
||
|
||
var rparentsprev = /^(?:parents|prev(?:Until|All))/,
|
||
|
||
// Methods guaranteed to produce a unique set when starting from a unique set
|
||
guaranteedUnique = {
|
||
children: true,
|
||
contents: true,
|
||
next: true,
|
||
prev: true
|
||
};
|
||
|
||
jQuery.fn.extend( {
|
||
has: function( target ) {
|
||
var targets = jQuery( target, this ),
|
||
l = targets.length;
|
||
|
||
return this.filter( function() {
|
||
var i = 0;
|
||
for ( ; i < l; i++ ) {
|
||
if ( jQuery.contains( this, targets[ i ] ) ) {
|
||
return true;
|
||
}
|
||
}
|
||
} );
|
||
},
|
||
|
||
closest: function( selectors, context ) {
|
||
var cur,
|
||
i = 0,
|
||
l = this.length,
|
||
matched = [],
|
||
targets = typeof selectors !== "string" && jQuery( selectors );
|
||
|
||
// Positional selectors never match, since there's no _selection_ context
|
||
if ( !rneedsContext.test( selectors ) ) {
|
||
for ( ; i < l; i++ ) {
|
||
for ( cur = this[ i ]; cur && cur !== context; cur = cur.parentNode ) {
|
||
|
||
// Always skip document fragments
|
||
if ( cur.nodeType < 11 && ( targets ?
|
||
targets.index( cur ) > -1 :
|
||
|
||
// Don't pass non-elements to Sizzle
|
||
cur.nodeType === 1 &&
|
||
jQuery.find.matchesSelector( cur, selectors ) ) ) {
|
||
|
||
matched.push( cur );
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
return this.pushStack( matched.length > 1 ? jQuery.uniqueSort( matched ) : matched );
|
||
},
|
||
|
||
// Determine the position of an element within the set
|
||
index: function( elem ) {
|
||
|
||
// No argument, return index in parent
|
||
if ( !elem ) {
|
||
return ( this[ 0 ] && this[ 0 ].parentNode ) ? this.first().prevAll().length : -1;
|
||
}
|
||
|
||
// Index in selector
|
||
if ( typeof elem === "string" ) {
|
||
return indexOf.call( jQuery( elem ), this[ 0 ] );
|
||
}
|
||
|
||
// Locate the position of the desired element
|
||
return indexOf.call( this,
|
||
|
||
// If it receives a jQuery object, the first element is used
|
||
elem.jquery ? elem[ 0 ] : elem
|
||
);
|
||
},
|
||
|
||
add: function( selector, context ) {
|
||
return this.pushStack(
|
||
jQuery.uniqueSort(
|
||
jQuery.merge( this.get(), jQuery( selector, context ) )
|
||
)
|
||
);
|
||
},
|
||
|
||
addBack: function( selector ) {
|
||
return this.add( selector == null ?
|
||
this.prevObject : this.prevObject.filter( selector )
|
||
);
|
||
}
|
||
} );
|
||
|
||
function sibling( cur, dir ) {
|
||
while ( ( cur = cur[ dir ] ) && cur.nodeType !== 1 ) {}
|
||
return cur;
|
||
}
|
||
|
||
jQuery.each( {
|
||
parent: function( elem ) {
|
||
var parent = elem.parentNode;
|
||
return parent && parent.nodeType !== 11 ? parent : null;
|
||
},
|
||
parents: function( elem ) {
|
||
return dir( elem, "parentNode" );
|
||
},
|
||
parentsUntil: function( elem, i, until ) {
|
||
return dir( elem, "parentNode", until );
|
||
},
|
||
next: function( elem ) {
|
||
return sibling( elem, "nextSibling" );
|
||
},
|
||
prev: function( elem ) {
|
||
return sibling( elem, "previousSibling" );
|
||
},
|
||
nextAll: function( elem ) {
|
||
return dir( elem, "nextSibling" );
|
||
},
|
||
prevAll: function( elem ) {
|
||
return dir( elem, "previousSibling" );
|
||
},
|
||
nextUntil: function( elem, i, until ) {
|
||
return dir( elem, "nextSibling", until );
|
||
},
|
||
prevUntil: function( elem, i, until ) {
|
||
return dir( elem, "previousSibling", until );
|
||
},
|
||
siblings: function( elem ) {
|
||
return siblings( ( elem.parentNode || {} ).firstChild, elem );
|
||
},
|
||
children: function( elem ) {
|
||
return siblings( elem.firstChild );
|
||
},
|
||
contents: function( elem ) {
|
||
if ( nodeName( elem, "iframe" ) ) {
|
||
return elem.contentDocument;
|
||
}
|
||
|
||
// Support: IE 9 - 11 only, iOS 7 only, Android Browser <=4.3 only
|
||
// Treat the template element as a regular one in browsers that
|
||
// don't support it.
|
||
if ( nodeName( elem, "template" ) ) {
|
||
elem = elem.content || elem;
|
||
}
|
||
|
||
return jQuery.merge( [], elem.childNodes );
|
||
}
|
||
}, function( name, fn ) {
|
||
jQuery.fn[ name ] = function( until, selector ) {
|
||
var matched = jQuery.map( this, fn, until );
|
||
|
||
if ( name.slice( -5 ) !== "Until" ) {
|
||
selector = until;
|
||
}
|
||
|
||
if ( selector && typeof selector === "string" ) {
|
||
matched = jQuery.filter( selector, matched );
|
||
}
|
||
|
||
if ( this.length > 1 ) {
|
||
|
||
// Remove duplicates
|
||
if ( !guaranteedUnique[ name ] ) {
|
||
jQuery.uniqueSort( matched );
|
||
}
|
||
|
||
// Reverse order for parents* and prev-derivatives
|
||
if ( rparentsprev.test( name ) ) {
|
||
matched.reverse();
|
||
}
|
||
}
|
||
|
||
return this.pushStack( matched );
|
||
};
|
||
} );
|
||
var rnothtmlwhite = ( /[^\x20\t\r\n\f]+/g );
|
||
|
||
|
||
|
||
// Convert String-formatted options into Object-formatted ones
|
||
function createOptions( options ) {
|
||
var object = {};
|
||
jQuery.each( options.match( rnothtmlwhite ) || [], function( _, flag ) {
|
||
object[ flag ] = true;
|
||
} );
|
||
return object;
|
||
}
|
||
|
||
/*
|
||
* Create a callback list using the following parameters:
|
||
*
|
||
* options: an optional list of space-separated options that will change how
|
||
* the callback list behaves or a more traditional option object
|
||
*
|
||
* By default a callback list will act like an event callback list and can be
|
||
* "fired" multiple times.
|
||
*
|
||
* Possible options:
|
||
*
|
||
* once: will ensure the callback list can only be fired once (like a Deferred)
|
||
*
|
||
* memory: will keep track of previous values and will call any callback added
|
||
* after the list has been fired right away with the latest "memorized"
|
||
* values (like a Deferred)
|
||
*
|
||
* unique: will ensure a callback can only be added once (no duplicate in the list)
|
||
*
|
||
* stopOnFalse: interrupt callings when a callback returns false
|
||
*
|
||
*/
|
||
jQuery.Callbacks = function( options ) {
|
||
|
||
// Convert options from String-formatted to Object-formatted if needed
|
||
// (we check in cache first)
|
||
options = typeof options === "string" ?
|
||
createOptions( options ) :
|
||
jQuery.extend( {}, options );
|
||
|
||
var // Flag to know if list is currently firing
|
||
firing,
|
||
|
||
// Last fire value for non-forgettable lists
|
||
memory,
|
||
|
||
// Flag to know if list was already fired
|
||
fired,
|
||
|
||
// Flag to prevent firing
|
||
locked,
|
||
|
||
// Actual callback list
|
||
list = [],
|
||
|
||
// Queue of execution data for repeatable lists
|
||
queue = [],
|
||
|
||
// Index of currently firing callback (modified by add/remove as needed)
|
||
firingIndex = -1,
|
||
|
||
// Fire callbacks
|
||
fire = function() {
|
||
|
||
// Enforce single-firing
|
||
locked = locked || options.once;
|
||
|
||
// Execute callbacks for all pending executions,
|
||
// respecting firingIndex overrides and runtime changes
|
||
fired = firing = true;
|
||
for ( ; queue.length; firingIndex = -1 ) {
|
||
memory = queue.shift();
|
||
while ( ++firingIndex < list.length ) {
|
||
|
||
// Run callback and check for early termination
|
||
if ( list[ firingIndex ].apply( memory[ 0 ], memory[ 1 ] ) === false &&
|
||
options.stopOnFalse ) {
|
||
|
||
// Jump to end and forget the data so .add doesn't re-fire
|
||
firingIndex = list.length;
|
||
memory = false;
|
||
}
|
||
}
|
||
}
|
||
|
||
// Forget the data if we're done with it
|
||
if ( !options.memory ) {
|
||
memory = false;
|
||
}
|
||
|
||
firing = false;
|
||
|
||
// Clean up if we're done firing for good
|
||
if ( locked ) {
|
||
|
||
// Keep an empty list if we have data for future add calls
|
||
if ( memory ) {
|
||
list = [];
|
||
|
||
// Otherwise, this object is spent
|
||
} else {
|
||
list = "";
|
||
}
|
||
}
|
||
},
|
||
|
||
// Actual Callbacks object
|
||
self = {
|
||
|
||
// Add a callback or a collection of callbacks to the list
|
||
add: function() {
|
||
if ( list ) {
|
||
|
||
// If we have memory from a past run, we should fire after adding
|
||
if ( memory && !firing ) {
|
||
firingIndex = list.length - 1;
|
||
queue.push( memory );
|
||
}
|
||
|
||
( function add( args ) {
|
||
jQuery.each( args, function( _, arg ) {
|
||
if ( jQuery.isFunction( arg ) ) {
|
||
if ( !options.unique || !self.has( arg ) ) {
|
||
list.push( arg );
|
||
}
|
||
} else if ( arg && arg.length && jQuery.type( arg ) !== "string" ) {
|
||
|
||
// Inspect recursively
|
||
add( arg );
|
||
}
|
||
} );
|
||
} )( arguments );
|
||
|
||
if ( memory && !firing ) {
|
||
fire();
|
||
}
|
||
}
|
||
return this;
|
||
},
|
||
|
||
// Remove a callback from the list
|
||
remove: function() {
|
||
jQuery.each( arguments, function( _, arg ) {
|
||
var index;
|
||
while ( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) {
|
||
list.splice( index, 1 );
|
||
|
||
// Handle firing indexes
|
||
if ( index <= firingIndex ) {
|
||
firingIndex--;
|
||
}
|
||
}
|
||
} );
|
||
return this;
|
||
},
|
||
|
||
// Check if a given callback is in the list.
|
||
// If no argument is given, return whether or not list has callbacks attached.
|
||
has: function( fn ) {
|
||
return fn ?
|
||
jQuery.inArray( fn, list ) > -1 :
|
||
list.length > 0;
|
||
},
|
||
|
||
// Remove all callbacks from the list
|
||
empty: function() {
|
||
if ( list ) {
|
||
list = [];
|
||
}
|
||
return this;
|
||
},
|
||
|
||
// Disable .fire and .add
|
||
// Abort any current/pending executions
|
||
// Clear all callbacks and values
|
||
disable: function() {
|
||
locked = queue = [];
|
||
list = memory = "";
|
||
return this;
|
||
},
|
||
disabled: function() {
|
||
return !list;
|
||
},
|
||
|
||
// Disable .fire
|
||
// Also disable .add unless we have memory (since it would have no effect)
|
||
// Abort any pending executions
|
||
lock: function() {
|
||
locked = queue = [];
|
||
if ( !memory && !firing ) {
|
||
list = memory = "";
|
||
}
|
||
return this;
|
||
},
|
||
locked: function() {
|
||
return !!locked;
|
||
},
|
||
|
||
// Call all callbacks with the given context and arguments
|
||
fireWith: function( context, args ) {
|
||
if ( !locked ) {
|
||
args = args || [];
|
||
args = [ context, args.slice ? args.slice() : args ];
|
||
queue.push( args );
|
||
if ( !firing ) {
|
||
fire();
|
||
}
|
||
}
|
||
return this;
|
||
},
|
||
|
||
// Call all the callbacks with the given arguments
|
||
fire: function() {
|
||
self.fireWith( this, arguments );
|
||
return this;
|
||
},
|
||
|
||
// To know if the callbacks have already been called at least once
|
||
fired: function() {
|
||
return !!fired;
|
||
}
|
||
};
|
||
|
||
return self;
|
||
};
|
||
|
||
|
||
function Identity( v ) {
|
||
return v;
|
||
}
|
||
function Thrower( ex ) {
|
||
throw ex;
|
||
}
|
||
|
||
function adoptValue( value, resolve, reject, noValue ) {
|
||
var method;
|
||
|
||
try {
|
||
|
||
// Check for promise aspect first to privilege synchronous behavior
|
||
if ( value && jQuery.isFunction( ( method = value.promise ) ) ) {
|
||
method.call( value ).done( resolve ).fail( reject );
|
||
|
||
// Other thenables
|
||
} else if ( value && jQuery.isFunction( ( method = value.then ) ) ) {
|
||
method.call( value, resolve, reject );
|
||
|
||
// Other non-thenables
|
||
} else {
|
||
|
||
// Control `resolve` arguments by letting Array#slice cast boolean `noValue` to integer:
|
||
// * false: [ value ].slice( 0 ) => resolve( value )
|
||
// * true: [ value ].slice( 1 ) => resolve()
|
||
resolve.apply( undefined, [ value ].slice( noValue ) );
|
||
}
|
||
|
||
// For Promises/A+, convert exceptions into rejections
|
||
// Since jQuery.when doesn't unwrap thenables, we can skip the extra checks appearing in
|
||
// Deferred#then to conditionally suppress rejection.
|
||
} catch ( value ) {
|
||
|
||
// Support: Android 4.0 only
|
||
// Strict mode functions invoked without .call/.apply get global-object context
|
||
reject.apply( undefined, [ value ] );
|
||
}
|
||
}
|
||
|
||
jQuery.extend( {
|
||
|
||
Deferred: function( func ) {
|
||
var tuples = [
|
||
|
||
// action, add listener, callbacks,
|
||
// ... .then handlers, argument index, [final state]
|
||
[ "notify", "progress", jQuery.Callbacks( "memory" ),
|
||
jQuery.Callbacks( "memory" ), 2 ],
|
||
[ "resolve", "done", jQuery.Callbacks( "once memory" ),
|
||
jQuery.Callbacks( "once memory" ), 0, "resolved" ],
|
||
[ "reject", "fail", jQuery.Callbacks( "once memory" ),
|
||
jQuery.Callbacks( "once memory" ), 1, "rejected" ]
|
||
],
|
||
state = "pending",
|
||
promise = {
|
||
state: function() {
|
||
return state;
|
||
},
|
||
always: function() {
|
||
deferred.done( arguments ).fail( arguments );
|
||
return this;
|
||
},
|
||
"catch": function( fn ) {
|
||
return promise.then( null, fn );
|
||
},
|
||
|
||
// Keep pipe for back-compat
|
||
pipe: function( /* fnDone, fnFail, fnProgress */ ) {
|
||
var fns = arguments;
|
||
|
||
return jQuery.Deferred( function( newDefer ) {
|
||
jQuery.each( tuples, function( i, tuple ) {
|
||
|
||
// Map tuples (progress, done, fail) to arguments (done, fail, progress)
|
||
var fn = jQuery.isFunction( fns[ tuple[ 4 ] ] ) && fns[ tuple[ 4 ] ];
|
||
|
||
// deferred.progress(function() { bind to newDefer or newDefer.notify })
|
||
// deferred.done(function() { bind to newDefer or newDefer.resolve })
|
||
// deferred.fail(function() { bind to newDefer or newDefer.reject })
|
||
deferred[ tuple[ 1 ] ]( function() {
|
||
var returned = fn && fn.apply( this, arguments );
|
||
if ( returned && jQuery.isFunction( returned.promise ) ) {
|
||
returned.promise()
|
||
.progress( newDefer.notify )
|
||
.done( newDefer.resolve )
|
||
.fail( newDefer.reject );
|
||
} else {
|
||
newDefer[ tuple[ 0 ] + "With" ](
|
||
this,
|
||
fn ? [ returned ] : arguments
|
||
);
|
||
}
|
||
} );
|
||
} );
|
||
fns = null;
|
||
} ).promise();
|
||
},
|
||
then: function( onFulfilled, onRejected, onProgress ) {
|
||
var maxDepth = 0;
|
||
function resolve( depth, deferred, handler, special ) {
|
||
return function() {
|
||
var that = this,
|
||
args = arguments,
|
||
mightThrow = function() {
|
||
var returned, then;
|
||
|
||
// Support: Promises/A+ section 2.3.3.3.3
|
||
// https://promisesaplus.com/#point-59
|
||
// Ignore double-resolution attempts
|
||
if ( depth < maxDepth ) {
|
||
return;
|
||
}
|
||
|
||
returned = handler.apply( that, args );
|
||
|
||
// Support: Promises/A+ section 2.3.1
|
||
// https://promisesaplus.com/#point-48
|
||
if ( returned === deferred.promise() ) {
|
||
throw new TypeError( "Thenable self-resolution" );
|
||
}
|
||
|
||
// Support: Promises/A+ sections 2.3.3.1, 3.5
|
||
// https://promisesaplus.com/#point-54
|
||
// https://promisesaplus.com/#point-75
|
||
// Retrieve `then` only once
|
||
then = returned &&
|
||
|
||
// Support: Promises/A+ section 2.3.4
|
||
// https://promisesaplus.com/#point-64
|
||
// Only check objects and functions for thenability
|
||
( typeof returned === "object" ||
|
||
typeof returned === "function" ) &&
|
||
returned.then;
|
||
|
||
// Handle a returned thenable
|
||
if ( jQuery.isFunction( then ) ) {
|
||
|
||
// Special processors (notify) just wait for resolution
|
||
if ( special ) {
|
||
then.call(
|
||
returned,
|
||
resolve( maxDepth, deferred, Identity, special ),
|
||
resolve( maxDepth, deferred, Thrower, special )
|
||
);
|
||
|
||
// Normal processors (resolve) also hook into progress
|
||
} else {
|
||
|
||
// ...and disregard older resolution values
|
||
maxDepth++;
|
||
|
||
then.call(
|
||
returned,
|
||
resolve( maxDepth, deferred, Identity, special ),
|
||
resolve( maxDepth, deferred, Thrower, special ),
|
||
resolve( maxDepth, deferred, Identity,
|
||
deferred.notifyWith )
|
||
);
|
||
}
|
||
|
||
// Handle all other returned values
|
||
} else {
|
||
|
||
// Only substitute handlers pass on context
|
||
// and multiple values (non-spec behavior)
|
||
if ( handler !== Identity ) {
|
||
that = undefined;
|
||
args = [ returned ];
|
||
}
|
||
|
||
// Process the value(s)
|
||
// Default process is resolve
|
||
( special || deferred.resolveWith )( that, args );
|
||
}
|
||
},
|
||
|
||
// Only normal processors (resolve) catch and reject exceptions
|
||
process = special ?
|
||
mightThrow :
|
||
function() {
|
||
try {
|
||
mightThrow();
|
||
} catch ( e ) {
|
||
|
||
if ( jQuery.Deferred.exceptionHook ) {
|
||
jQuery.Deferred.exceptionHook( e,
|
||
process.stackTrace );
|
||
}
|
||
|
||
// Support: Promises/A+ section 2.3.3.3.4.1
|
||
// https://promisesaplus.com/#point-61
|
||
// Ignore post-resolution exceptions
|
||
if ( depth + 1 >= maxDepth ) {
|
||
|
||
// Only substitute handlers pass on context
|
||
// and multiple values (non-spec behavior)
|
||
if ( handler !== Thrower ) {
|
||
that = undefined;
|
||
args = [ e ];
|
||
}
|
||
|
||
deferred.rejectWith( that, args );
|
||
}
|
||
}
|
||
};
|
||
|
||
// Support: Promises/A+ section 2.3.3.3.1
|
||
// https://promisesaplus.com/#point-57
|
||
// Re-resolve promises immediately to dodge false rejection from
|
||
// subsequent errors
|
||
if ( depth ) {
|
||
process();
|
||
} else {
|
||
|
||
// Call an optional hook to record the stack, in case of exception
|
||
// since it's otherwise lost when execution goes async
|
||
if ( jQuery.Deferred.getStackHook ) {
|
||
process.stackTrace = jQuery.Deferred.getStackHook();
|
||
}
|
||
window.setTimeout( process );
|
||
}
|
||
};
|
||
}
|
||
|
||
return jQuery.Deferred( function( newDefer ) {
|
||
|
||
// progress_handlers.add( ... )
|
||
tuples[ 0 ][ 3 ].add(
|
||
resolve(
|
||
0,
|
||
newDefer,
|
||
jQuery.isFunction( onProgress ) ?
|
||
onProgress :
|
||
Identity,
|
||
newDefer.notifyWith
|
||
)
|
||
);
|
||
|
||
// fulfilled_handlers.add( ... )
|
||
tuples[ 1 ][ 3 ].add(
|
||
resolve(
|
||
0,
|
||
newDefer,
|
||
jQuery.isFunction( onFulfilled ) ?
|
||
onFulfilled :
|
||
Identity
|
||
)
|
||
);
|
||
|
||
// rejected_handlers.add( ... )
|
||
tuples[ 2 ][ 3 ].add(
|
||
resolve(
|
||
0,
|
||
newDefer,
|
||
jQuery.isFunction( onRejected ) ?
|
||
onRejected :
|
||
Thrower
|
||
)
|
||
);
|
||
} ).promise();
|
||
},
|
||
|
||
// Get a promise for this deferred
|
||
// If obj is provided, the promise aspect is added to the object
|
||
promise: function( obj ) {
|
||
return obj != null ? jQuery.extend( obj, promise ) : promise;
|
||
}
|
||
},
|
||
deferred = {};
|
||
|
||
// Add list-specific methods
|
||
jQuery.each( tuples, function( i, tuple ) {
|
||
var list = tuple[ 2 ],
|
||
stateString = tuple[ 5 ];
|
||
|
||
// promise.progress = list.add
|
||
// promise.done = list.add
|
||
// promise.fail = list.add
|
||
promise[ tuple[ 1 ] ] = list.add;
|
||
|
||
// Handle state
|
||
if ( stateString ) {
|
||
list.add(
|
||
function() {
|
||
|
||
// state = "resolved" (i.e., fulfilled)
|
||
// state = "rejected"
|
||
state = stateString;
|
||
},
|
||
|
||
// rejected_callbacks.disable
|
||
// fulfilled_callbacks.disable
|
||
tuples[ 3 - i ][ 2 ].disable,
|
||
|
||
// progress_callbacks.lock
|
||
tuples[ 0 ][ 2 ].lock
|
||
);
|
||
}
|
||
|
||
// progress_handlers.fire
|
||
// fulfilled_handlers.fire
|
||
// rejected_handlers.fire
|
||
list.add( tuple[ 3 ].fire );
|
||
|
||
// deferred.notify = function() { deferred.notifyWith(...) }
|
||
// deferred.resolve = function() { deferred.resolveWith(...) }
|
||
// deferred.reject = function() { deferred.rejectWith(...) }
|
||
deferred[ tuple[ 0 ] ] = function() {
|
||
deferred[ tuple[ 0 ] + "With" ]( this === deferred ? undefined : this, arguments );
|
||
return this;
|
||
};
|
||
|
||
// deferred.notifyWith = list.fireWith
|
||
// deferred.resolveWith = list.fireWith
|
||
// deferred.rejectWith = list.fireWith
|
||
deferred[ tuple[ 0 ] + "With" ] = list.fireWith;
|
||
} );
|
||
|
||
// Make the deferred a promise
|
||
promise.promise( deferred );
|
||
|
||
// Call given func if any
|
||
if ( func ) {
|
||
func.call( deferred, deferred );
|
||
}
|
||
|
||
// All done!
|
||
return deferred;
|
||
},
|
||
|
||
// Deferred helper
|
||
when: function( singleValue ) {
|
||
var
|
||
|
||
// count of uncompleted subordinates
|
||
remaining = arguments.length,
|
||
|
||
// count of unprocessed arguments
|
||
i = remaining,
|
||
|
||
// subordinate fulfillment data
|
||
resolveContexts = Array( i ),
|
||
resolveValues = slice.call( arguments ),
|
||
|
||
// the master Deferred
|
||
master = jQuery.Deferred(),
|
||
|
||
// subordinate callback factory
|
||
updateFunc = function( i ) {
|
||
return function( value ) {
|
||
resolveContexts[ i ] = this;
|
||
resolveValues[ i ] = arguments.length > 1 ? slice.call( arguments ) : value;
|
||
if ( !( --remaining ) ) {
|
||
master.resolveWith( resolveContexts, resolveValues );
|
||
}
|
||
};
|
||
};
|
||
|
||
// Single- and empty arguments are adopted like Promise.resolve
|
||
if ( remaining <= 1 ) {
|
||
adoptValue( singleValue, master.done( updateFunc( i ) ).resolve, master.reject,
|
||
!remaining );
|
||
|
||
// Use .then() to unwrap secondary thenables (cf. gh-3000)
|
||
if ( master.state() === "pending" ||
|
||
jQuery.isFunction( resolveValues[ i ] && resolveValues[ i ].then ) ) {
|
||
|
||
return master.then();
|
||
}
|
||
}
|
||
|
||
// Multiple arguments are aggregated like Promise.all array elements
|
||
while ( i-- ) {
|
||
adoptValue( resolveValues[ i ], updateFunc( i ), master.reject );
|
||
}
|
||
|
||
return master.promise();
|
||
}
|
||
} );
|
||
|
||
|
||
// These usually indicate a programmer mistake during development,
|
||
// warn about them ASAP rather than swallowing them by default.
|
||
var rerrorNames = /^(Eval|Internal|Range|Reference|Syntax|Type|URI)Error$/;
|
||
|
||
jQuery.Deferred.exceptionHook = function( error, stack ) {
|
||
|
||
// Support: IE 8 - 9 only
|
||
// Console exists when dev tools are open, which can happen at any time
|
||
if ( window.console && window.console.warn && error && rerrorNames.test( error.name ) ) {
|
||
window.console.warn( "jQuery.Deferred exception: " + error.message, error.stack, stack );
|
||
}
|
||
};
|
||
|
||
|
||
|
||
|
||
jQuery.readyException = function( error ) {
|
||
window.setTimeout( function() {
|
||
throw error;
|
||
} );
|
||
};
|
||
|
||
|
||
|
||
|
||
// The deferred used on DOM ready
|
||
var readyList = jQuery.Deferred();
|
||
|
||
jQuery.fn.ready = function( fn ) {
|
||
|
||
readyList
|
||
.then( fn )
|
||
|
||
// Wrap jQuery.readyException in a function so that the lookup
|
||
// happens at the time of error handling instead of callback
|
||
// registration.
|
||
.catch( function( error ) {
|
||
jQuery.readyException( error );
|
||
} );
|
||
|
||
return this;
|
||
};
|
||
|
||
jQuery.extend( {
|
||
|
||
// Is the DOM ready to be used? Set to true once it occurs.
|
||
isReady: false,
|
||
|
||
// A counter to track how many items to wait for before
|
||
// the ready event fires. See #6781
|
||
readyWait: 1,
|
||
|
||
// Handle when the DOM is ready
|
||
ready: function( wait ) {
|
||
|
||
// Abort if there are pending holds or we're already ready
|
||
if ( wait === true ? --jQuery.readyWait : jQuery.isReady ) {
|
||
return;
|
||
}
|
||
|
||
// Remember that the DOM is ready
|
||
jQuery.isReady = true;
|
||
|
||
// If a normal DOM Ready event fired, decrement, and wait if need be
|
||
if ( wait !== true && --jQuery.readyWait > 0 ) {
|
||
return;
|
||
}
|
||
|
||
// If there are functions bound, to execute
|
||
readyList.resolveWith( document, [ jQuery ] );
|
||
}
|
||
} );
|
||
|
||
jQuery.ready.then = readyList.then;
|
||
|
||
// The ready event handler and self cleanup method
|
||
function completed() {
|
||
document.removeEventListener( "DOMContentLoaded", completed );
|
||
window.removeEventListener( "load", completed );
|
||
jQuery.ready();
|
||
}
|
||
|
||
// Catch cases where $(document).ready() is called
|
||
// after the browser event has already occurred.
|
||
// Support: IE <=9 - 10 only
|
||
// Older IE sometimes signals "interactive" too soon
|
||
if ( document.readyState === "complete" ||
|
||
( document.readyState !== "loading" && !document.documentElement.doScroll ) ) {
|
||
|
||
// Handle it asynchronously to allow scripts the opportunity to delay ready
|
||
window.setTimeout( jQuery.ready );
|
||
|
||
} else {
|
||
|
||
// Use the handy event callback
|
||
document.addEventListener( "DOMContentLoaded", completed );
|
||
|
||
// A fallback to window.onload, that will always work
|
||
window.addEventListener( "load", completed );
|
||
}
|
||
|
||
|
||
|
||
|
||
// Multifunctional method to get and set values of a collection
|
||
// The value/s can optionally be executed if it's a function
|
||
var access = function( elems, fn, key, value, chainable, emptyGet, raw ) {
|
||
var i = 0,
|
||
len = elems.length,
|
||
bulk = key == null;
|
||
|
||
// Sets many values
|
||
if ( jQuery.type( key ) === "object" ) {
|
||
chainable = true;
|
||
for ( i in key ) {
|
||
access( elems, fn, i, key[ i ], true, emptyGet, raw );
|
||
}
|
||
|
||
// Sets one value
|
||
} else if ( value !== undefined ) {
|
||
chainable = true;
|
||
|
||
if ( !jQuery.isFunction( value ) ) {
|
||
raw = true;
|
||
}
|
||
|
||
if ( bulk ) {
|
||
|
||
// Bulk operations run against the entire set
|
||
if ( raw ) {
|
||
fn.call( elems, value );
|
||
fn = null;
|
||
|
||
// ...except when executing function values
|
||
} else {
|
||
bulk = fn;
|
||
fn = function( elem, key, value ) {
|
||
return bulk.call( jQuery( elem ), value );
|
||
};
|
||
}
|
||
}
|
||
|
||
if ( fn ) {
|
||
for ( ; i < len; i++ ) {
|
||
fn(
|
||
elems[ i ], key, raw ?
|
||
value :
|
||
value.call( elems[ i ], i, fn( elems[ i ], key ) )
|
||
);
|
||
}
|
||
}
|
||
}
|
||
|
||
if ( chainable ) {
|
||
return elems;
|
||
}
|
||
|
||
// Gets
|
||
if ( bulk ) {
|
||
return fn.call( elems );
|
||
}
|
||
|
||
return len ? fn( elems[ 0 ], key ) : emptyGet;
|
||
};
|
||
var acceptData = function( owner ) {
|
||
|
||
// Accepts only:
|
||
// - Node
|
||
// - Node.ELEMENT_NODE
|
||
// - Node.DOCUMENT_NODE
|
||
// - Object
|
||
// - Any
|
||
return owner.nodeType === 1 || owner.nodeType === 9 || !( +owner.nodeType );
|
||
};
|
||
|
||
|
||
|
||
|
||
function Data() {
|
||
this.expando = jQuery.expando + Data.uid++;
|
||
}
|
||
|
||
Data.uid = 1;
|
||
|
||
Data.prototype = {
|
||
|
||
cache: function( owner ) {
|
||
|
||
// Check if the owner object already has a cache
|
||
var value = owner[ this.expando ];
|
||
|
||
// If not, create one
|
||
if ( !value ) {
|
||
value = {};
|
||
|
||
// We can accept data for non-element nodes in modern browsers,
|
||
// but we should not, see #8335.
|
||
// Always return an empty object.
|
||
if ( acceptData( owner ) ) {
|
||
|
||
// If it is a node unlikely to be stringify-ed or looped over
|
||
// use plain assignment
|
||
if ( owner.nodeType ) {
|
||
owner[ this.expando ] = value;
|
||
|
||
// Otherwise secure it in a non-enumerable property
|
||
// configurable must be true to allow the property to be
|
||
// deleted when data is removed
|
||
} else {
|
||
Object.defineProperty( owner, this.expando, {
|
||
value: value,
|
||
configurable: true
|
||
} );
|
||
}
|
||
}
|
||
}
|
||
|
||
return value;
|
||
},
|
||
set: function( owner, data, value ) {
|
||
var prop,
|
||
cache = this.cache( owner );
|
||
|
||
// Handle: [ owner, key, value ] args
|
||
// Always use camelCase key (gh-2257)
|
||
if ( typeof data === "string" ) {
|
||
cache[ jQuery.camelCase( data ) ] = value;
|
||
|
||
// Handle: [ owner, { properties } ] args
|
||
} else {
|
||
|
||
// Copy the properties one-by-one to the cache object
|
||
for ( prop in data ) {
|
||
cache[ jQuery.camelCase( prop ) ] = data[ prop ];
|
||
}
|
||
}
|
||
return cache;
|
||
},
|
||
get: function( owner, key ) {
|
||
return key === undefined ?
|
||
this.cache( owner ) :
|
||
|
||
// Always use camelCase key (gh-2257)
|
||
owner[ this.expando ] && owner[ this.expando ][ jQuery.camelCase( key ) ];
|
||
},
|
||
access: function( owner, key, value ) {
|
||
|
||
// In cases where either:
|
||
//
|
||
// 1. No key was specified
|
||
// 2. A string key was specified, but no value provided
|
||
//
|
||
// Take the "read" path and allow the get method to determine
|
||
// which value to return, respectively either:
|
||
//
|
||
// 1. The entire cache object
|
||
// 2. The data stored at the key
|
||
//
|
||
if ( key === undefined ||
|
||
( ( key && typeof key === "string" ) && value === undefined ) ) {
|
||
|
||
return this.get( owner, key );
|
||
}
|
||
|
||
// When the key is not a string, or both a key and value
|
||
// are specified, set or extend (existing objects) with either:
|
||
//
|
||
// 1. An object of properties
|
||
// 2. A key and value
|
||
//
|
||
this.set( owner, key, value );
|
||
|
||
// Since the "set" path can have two possible entry points
|
||
// return the expected data based on which path was taken[*]
|
||
return value !== undefined ? value : key;
|
||
},
|
||
remove: function( owner, key ) {
|
||
var i,
|
||
cache = owner[ this.expando ];
|
||
|
||
if ( cache === undefined ) {
|
||
return;
|
||
}
|
||
|
||
if ( key !== undefined ) {
|
||
|
||
// Support array or space separated string of keys
|
||
if ( Array.isArray( key ) ) {
|
||
|
||
// If key is an array of keys...
|
||
// We always set camelCase keys, so remove that.
|
||
key = key.map( jQuery.camelCase );
|
||
} else {
|
||
key = jQuery.camelCase( key );
|
||
|
||
// If a key with the spaces exists, use it.
|
||
// Otherwise, create an array by matching non-whitespace
|
||
key = key in cache ?
|
||
[ key ] :
|
||
( key.match( rnothtmlwhite ) || [] );
|
||
}
|
||
|
||
i = key.length;
|
||
|
||
while ( i-- ) {
|
||
delete cache[ key[ i ] ];
|
||
}
|
||
}
|
||
|
||
// Remove the expando if there's no more data
|
||
if ( key === undefined || jQuery.isEmptyObject( cache ) ) {
|
||
|
||
// Support: Chrome <=35 - 45
|
||
// Webkit & Blink performance suffers when deleting properties
|
||
// from DOM nodes, so set to undefined instead
|
||
// https://bugs.chromium.org/p/chromium/issues/detail?id=378607 (bug restricted)
|
||
if ( owner.nodeType ) {
|
||
owner[ this.expando ] = undefined;
|
||
} else {
|
||
delete owner[ this.expando ];
|
||
}
|
||
}
|
||
},
|
||
hasData: function( owner ) {
|
||
var cache = owner[ this.expando ];
|
||
return cache !== undefined && !jQuery.isEmptyObject( cache );
|
||
}
|
||
};
|
||
var dataPriv = new Data();
|
||
|
||
var dataUser = new Data();
|
||
|
||
|
||
|
||
// Implementation Summary
|
||
//
|
||
// 1. Enforce API surface and semantic compatibility with 1.9.x branch
|
||
// 2. Improve the module's maintainability by reducing the storage
|
||
// paths to a single mechanism.
|
||
// 3. Use the same single mechanism to support "private" and "user" data.
|
||
// 4. _Never_ expose "private" data to user code (TODO: Drop _data, _removeData)
|
||
// 5. Avoid exposing implementation details on user objects (eg. expando properties)
|
||
// 6. Provide a clear path for implementation upgrade to WeakMap in 2014
|
||
|
||
var rbrace = /^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,
|
||
rmultiDash = /[A-Z]/g;
|
||
|
||
function getData( data ) {
|
||
if ( data === "true" ) {
|
||
return true;
|
||
}
|
||
|
||
if ( data === "false" ) {
|
||
return false;
|
||
}
|
||
|
||
if ( data === "null" ) {
|
||
return null;
|
||
}
|
||
|
||
// Only convert to a number if it doesn't change the string
|
||
if ( data === +data + "" ) {
|
||
return +data;
|
||
}
|
||
|
||
if ( rbrace.test( data ) ) {
|
||
return JSON.parse( data );
|
||
}
|
||
|
||
return data;
|
||
}
|
||
|
||
function dataAttr( elem, key, data ) {
|
||
var name;
|
||
|
||
// If nothing was found internally, try to fetch any
|
||
// data from the HTML5 data-* attribute
|
||
if ( data === undefined && elem.nodeType === 1 ) {
|
||
name = "data-" + key.replace( rmultiDash, "-$&" ).toLowerCase();
|
||
data = elem.getAttribute( name );
|
||
|
||
if ( typeof data === "string" ) {
|
||
try {
|
||
data = getData( data );
|
||
} catch ( e ) {}
|
||
|
||
// Make sure we set the data so it isn't changed later
|
||
dataUser.set( elem, key, data );
|
||
} else {
|
||
data = undefined;
|
||
}
|
||
}
|
||
return data;
|
||
}
|
||
|
||
jQuery.extend( {
|
||
hasData: function( elem ) {
|
||
return dataUser.hasData( elem ) || dataPriv.hasData( elem );
|
||
},
|
||
|
||
data: function( elem, name, data ) {
|
||
return dataUser.access( elem, name, data );
|
||
},
|
||
|
||
removeData: function( elem, name ) {
|
||
dataUser.remove( elem, name );
|
||
},
|
||
|
||
// TODO: Now that all calls to _data and _removeData have been replaced
|
||
// with direct calls to dataPriv methods, these can be deprecated.
|
||
_data: function( elem, name, data ) {
|
||
return dataPriv.access( elem, name, data );
|
||
},
|
||
|
||
_removeData: function( elem, name ) {
|
||
dataPriv.remove( elem, name );
|
||
}
|
||
} );
|
||
|
||
jQuery.fn.extend( {
|
||
data: function( key, value ) {
|
||
var i, name, data,
|
||
elem = this[ 0 ],
|
||
attrs = elem && elem.attributes;
|
||
|
||
// Gets all values
|
||
if ( key === undefined ) {
|
||
if ( this.length ) {
|
||
data = dataUser.get( elem );
|
||
|
||
if ( elem.nodeType === 1 && !dataPriv.get( elem, "hasDataAttrs" ) ) {
|
||
i = attrs.length;
|
||
while ( i-- ) {
|
||
|
||
// Support: IE 11 only
|
||
// The attrs elements can be null (#14894)
|
||
if ( attrs[ i ] ) {
|
||
name = attrs[ i ].name;
|
||
if ( name.indexOf( "data-" ) === 0 ) {
|
||
name = jQuery.camelCase( name.slice( 5 ) );
|
||
dataAttr( elem, name, data[ name ] );
|
||
}
|
||
}
|
||
}
|
||
dataPriv.set( elem, "hasDataAttrs", true );
|
||
}
|
||
}
|
||
|
||
return data;
|
||
}
|
||
|
||
// Sets multiple values
|
||
if ( typeof key === "object" ) {
|
||
return this.each( function() {
|
||
dataUser.set( this, key );
|
||
} );
|
||
}
|
||
|
||
return access( this, function( value ) {
|
||
var data;
|
||
|
||
// The calling jQuery object (element matches) is not empty
|
||
// (and therefore has an element appears at this[ 0 ]) and the
|
||
// `value` parameter was not undefined. An empty jQuery object
|
||
// will result in `undefined` for elem = this[ 0 ] which will
|
||
// throw an exception if an attempt to read a data cache is made.
|
||
if ( elem && value === undefined ) {
|
||
|
||
// Attempt to get data from the cache
|
||
// The key will always be camelCased in Data
|
||
data = dataUser.get( elem, key );
|
||
if ( data !== undefined ) {
|
||
return data;
|
||
}
|
||
|
||
// Attempt to "discover" the data in
|
||
// HTML5 custom data-* attrs
|
||
data = dataAttr( elem, key );
|
||
if ( data !== undefined ) {
|
||
return data;
|
||
}
|
||
|
||
// We tried really hard, but the data doesn't exist.
|
||
return;
|
||
}
|
||
|
||
// Set the data...
|
||
this.each( function() {
|
||
|
||
// We always store the camelCased key
|
||
dataUser.set( this, key, value );
|
||
} );
|
||
}, null, value, arguments.length > 1, null, true );
|
||
},
|
||
|
||
removeData: function( key ) {
|
||
return this.each( function() {
|
||
dataUser.remove( this, key );
|
||
} );
|
||
}
|
||
} );
|
||
|
||
|
||
jQuery.extend( {
|
||
queue: function( elem, type, data ) {
|
||
var queue;
|
||
|
||
if ( elem ) {
|
||
type = ( type || "fx" ) + "queue";
|
||
queue = dataPriv.get( elem, type );
|
||
|
||
// Speed up dequeue by getting out quickly if this is just a lookup
|
||
if ( data ) {
|
||
if ( !queue || Array.isArray( data ) ) {
|
||
queue = dataPriv.access( elem, type, jQuery.makeArray( data ) );
|
||
} else {
|
||
queue.push( data );
|
||
}
|
||
}
|
||
return queue || [];
|
||
}
|
||
},
|
||
|
||
dequeue: function( elem, type ) {
|
||
type = type || "fx";
|
||
|
||
var queue = jQuery.queue( elem, type ),
|
||
startLength = queue.length,
|
||
fn = queue.shift(),
|
||
hooks = jQuery._queueHooks( elem, type ),
|
||
next = function() {
|
||
jQuery.dequeue( elem, type );
|
||
};
|
||
|
||
// If the fx queue is dequeued, always remove the progress sentinel
|
||
if ( fn === "inprogress" ) {
|
||
fn = queue.shift();
|
||
startLength--;
|
||
}
|
||
|
||
if ( fn ) {
|
||
|
||
// Add a progress sentinel to prevent the fx queue from being
|
||
// automatically dequeued
|
||
if ( type === "fx" ) {
|
||
queue.unshift( "inprogress" );
|
||
}
|
||
|
||
// Clear up the last queue stop function
|
||
delete hooks.stop;
|
||
fn.call( elem, next, hooks );
|
||
}
|
||
|
||
if ( !startLength && hooks ) {
|
||
hooks.empty.fire();
|
||
}
|
||
},
|
||
|
||
// Not public - generate a queueHooks object, or return the current one
|
||
_queueHooks: function( elem, type ) {
|
||
var key = type + "queueHooks";
|
||
return dataPriv.get( elem, key ) || dataPriv.access( elem, key, {
|
||
empty: jQuery.Callbacks( "once memory" ).add( function() {
|
||
dataPriv.remove( elem, [ type + "queue", key ] );
|
||
} )
|
||
} );
|
||
}
|
||
} );
|
||
|
||
jQuery.fn.extend( {
|
||
queue: function( type, data ) {
|
||
var setter = 2;
|
||
|
||
if ( typeof type !== "string" ) {
|
||
data = type;
|
||
type = "fx";
|
||
setter--;
|
||
}
|
||
|
||
if ( arguments.length < setter ) {
|
||
return jQuery.queue( this[ 0 ], type );
|
||
}
|
||
|
||
return data === undefined ?
|
||
this :
|
||
this.each( function() {
|
||
var queue = jQuery.queue( this, type, data );
|
||
|
||
// Ensure a hooks for this queue
|
||
jQuery._queueHooks( this, type );
|
||
|
||
if ( type === "fx" && queue[ 0 ] !== "inprogress" ) {
|
||
jQuery.dequeue( this, type );
|
||
}
|
||
} );
|
||
},
|
||
dequeue: function( type ) {
|
||
return this.each( function() {
|
||
jQuery.dequeue( this, type );
|
||
} );
|
||
},
|
||
clearQueue: function( type ) {
|
||
return this.queue( type || "fx", [] );
|
||
},
|
||
|
||
// Get a promise resolved when queues of a certain type
|
||
// are emptied (fx is the type by default)
|
||
promise: function( type, obj ) {
|
||
var tmp,
|
||
count = 1,
|
||
defer = jQuery.Deferred(),
|
||
elements = this,
|
||
i = this.length,
|
||
resolve = function() {
|
||
if ( !( --count ) ) {
|
||
defer.resolveWith( elements, [ elements ] );
|
||
}
|
||
};
|
||
|
||
if ( typeof type !== "string" ) {
|
||
obj = type;
|
||
type = undefined;
|
||
}
|
||
type = type || "fx";
|
||
|
||
while ( i-- ) {
|
||
tmp = dataPriv.get( elements[ i ], type + "queueHooks" );
|
||
if ( tmp && tmp.empty ) {
|
||
count++;
|
||
tmp.empty.add( resolve );
|
||
}
|
||
}
|
||
resolve();
|
||
return defer.promise( obj );
|
||
}
|
||
} );
|
||
var pnum = ( /[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/ ).source;
|
||
|
||
var rcssNum = new RegExp( "^(?:([+-])=|)(" + pnum + ")([a-z%]*)$", "i" );
|
||
|
||
|
||
var cssExpand = [ "Top", "Right", "Bottom", "Left" ];
|
||
|
||
var isHiddenWithinTree = function( elem, el ) {
|
||
|
||
// isHiddenWithinTree might be called from jQuery#filter function;
|
||
// in that case, element will be second argument
|
||
elem = el || elem;
|
||
|
||
// Inline style trumps all
|
||
return elem.style.display === "none" ||
|
||
elem.style.display === "" &&
|
||
|
||
// Otherwise, check computed style
|
||
// Support: Firefox <=43 - 45
|
||
// Disconnected elements can have computed display: none, so first confirm that elem is
|
||
// in the document.
|
||
jQuery.contains( elem.ownerDocument, elem ) &&
|
||
|
||
jQuery.css( elem, "display" ) === "none";
|
||
};
|
||
|
||
var swap = function( elem, options, callback, args ) {
|
||
var ret, name,
|
||
old = {};
|
||
|
||
// Remember the old values, and insert the new ones
|
||
for ( name in options ) {
|
||
old[ name ] = elem.style[ name ];
|
||
elem.style[ name ] = options[ name ];
|
||
}
|
||
|
||
ret = callback.apply( elem, args || [] );
|
||
|
||
// Revert the old values
|
||
for ( name in options ) {
|
||
elem.style[ name ] = old[ name ];
|
||
}
|
||
|
||
return ret;
|
||
};
|
||
|
||
|
||
|
||
|
||
function adjustCSS( elem, prop, valueParts, tween ) {
|
||
var adjusted,
|
||
scale = 1,
|
||
maxIterations = 20,
|
||
currentValue = tween ?
|
||
function() {
|
||
return tween.cur();
|
||
} :
|
||
function() {
|
||
return jQuery.css( elem, prop, "" );
|
||
},
|
||
initial = currentValue(),
|
||
unit = valueParts && valueParts[ 3 ] || ( jQuery.cssNumber[ prop ] ? "" : "px" ),
|
||
|
||
// Starting value computation is required for potential unit mismatches
|
||
initialInUnit = ( jQuery.cssNumber[ prop ] || unit !== "px" && +initial ) &&
|
||
rcssNum.exec( jQuery.css( elem, prop ) );
|
||
|
||
if ( initialInUnit && initialInUnit[ 3 ] !== unit ) {
|
||
|
||
// Trust units reported by jQuery.css
|
||
unit = unit || initialInUnit[ 3 ];
|
||
|
||
// Make sure we update the tween properties later on
|
||
valueParts = valueParts || [];
|
||
|
||
// Iteratively approximate from a nonzero starting point
|
||
initialInUnit = +initial || 1;
|
||
|
||
do {
|
||
|
||
// If previous iteration zeroed out, double until we get *something*.
|
||
// Use string for doubling so we don't accidentally see scale as unchanged below
|
||
scale = scale || ".5";
|
||
|
||
// Adjust and apply
|
||
initialInUnit = initialInUnit / scale;
|
||
jQuery.style( elem, prop, initialInUnit + unit );
|
||
|
||
// Update scale, tolerating zero or NaN from tween.cur()
|
||
// Break the loop if scale is unchanged or perfect, or if we've just had enough.
|
||
} while (
|
||
scale !== ( scale = currentValue() / initial ) && scale !== 1 && --maxIterations
|
||
);
|
||
}
|
||
|
||
if ( valueParts ) {
|
||
initialInUnit = +initialInUnit || +initial || 0;
|
||
|
||
// Apply relative offset (+=/-=) if specified
|
||
adjusted = valueParts[ 1 ] ?
|
||
initialInUnit + ( valueParts[ 1 ] + 1 ) * valueParts[ 2 ] :
|
||
+valueParts[ 2 ];
|
||
if ( tween ) {
|
||
tween.unit = unit;
|
||
tween.start = initialInUnit;
|
||
tween.end = adjusted;
|
||
}
|
||
}
|
||
return adjusted;
|
||
}
|
||
|
||
|
||
var defaultDisplayMap = {};
|
||
|
||
function getDefaultDisplay( elem ) {
|
||
var temp,
|
||
doc = elem.ownerDocument,
|
||
nodeName = elem.nodeName,
|
||
display = defaultDisplayMap[ nodeName ];
|
||
|
||
if ( display ) {
|
||
return display;
|
||
}
|
||
|
||
temp = doc.body.appendChild( doc.createElement( nodeName ) );
|
||
display = jQuery.css( temp, "display" );
|
||
|
||
temp.parentNode.removeChild( temp );
|
||
|
||
if ( display === "none" ) {
|
||
display = "block";
|
||
}
|
||
defaultDisplayMap[ nodeName ] = display;
|
||
|
||
return display;
|
||
}
|
||
|
||
function showHide( elements, show ) {
|
||
var display, elem,
|
||
values = [],
|
||
index = 0,
|
||
length = elements.length;
|
||
|
||
// Determine new display value for elements that need to change
|
||
for ( ; index < length; index++ ) {
|
||
elem = elements[ index ];
|
||
if ( !elem.style ) {
|
||
continue;
|
||
}
|
||
|
||
display = elem.style.display;
|
||
if ( show ) {
|
||
|
||
// Since we force visibility upon cascade-hidden elements, an immediate (and slow)
|
||
// check is required in this first loop unless we have a nonempty display value (either
|
||
// inline or about-to-be-restored)
|
||
if ( display === "none" ) {
|
||
values[ index ] = dataPriv.get( elem, "display" ) || null;
|
||
if ( !values[ index ] ) {
|
||
elem.style.display = "";
|
||
}
|
||
}
|
||
if ( elem.style.display === "" && isHiddenWithinTree( elem ) ) {
|
||
values[ index ] = getDefaultDisplay( elem );
|
||
}
|
||
} else {
|
||
if ( display !== "none" ) {
|
||
values[ index ] = "none";
|
||
|
||
// Remember what we're overwriting
|
||
dataPriv.set( elem, "display", display );
|
||
}
|
||
}
|
||
}
|
||
|
||
// Set the display of the elements in a second loop to avoid constant reflow
|
||
for ( index = 0; index < length; index++ ) {
|
||
if ( values[ index ] != null ) {
|
||
elements[ index ].style.display = values[ index ];
|
||
}
|
||
}
|
||
|
||
return elements;
|
||
}
|
||
|
||
jQuery.fn.extend( {
|
||
show: function() {
|
||
return showHide( this, true );
|
||
},
|
||
hide: function() {
|
||
return showHide( this );
|
||
},
|
||
toggle: function( state ) {
|
||
if ( typeof state === "boolean" ) {
|
||
return state ? this.show() : this.hide();
|
||
}
|
||
|
||
return this.each( function() {
|
||
if ( isHiddenWithinTree( this ) ) {
|
||
jQuery( this ).show();
|
||
} else {
|
||
jQuery( this ).hide();
|
||
}
|
||
} );
|
||
}
|
||
} );
|
||
var rcheckableType = ( /^(?:checkbox|radio)$/i );
|
||
|
||
var rtagName = ( /<([a-z][^\/\0>\x20\t\r\n\f]+)/i );
|
||
|
||
var rscriptType = ( /^$|\/(?:java|ecma)script/i );
|
||
|
||
|
||
|
||
// We have to close these tags to support XHTML (#13200)
|
||
var wrapMap = {
|
||
|
||
// Support: IE <=9 only
|
||
option: [ 1, "<select multiple='multiple'>", "</select>" ],
|
||
|
||
// XHTML parsers do not magically insert elements in the
|
||
// same way that tag soup parsers do. So we cannot shorten
|
||
// this by omitting <tbody> or other required elements.
|
||
thead: [ 1, "<table>", "</table>" ],
|
||
col: [ 2, "<table><colgroup>", "</colgroup></table>" ],
|
||
tr: [ 2, "<table><tbody>", "</tbody></table>" ],
|
||
td: [ 3, "<table><tbody><tr>", "</tr></tbody></table>" ],
|
||
|
||
_default: [ 0, "", "" ]
|
||
};
|
||
|
||
// Support: IE <=9 only
|
||
wrapMap.optgroup = wrapMap.option;
|
||
|
||
wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead;
|
||
wrapMap.th = wrapMap.td;
|
||
|
||
|
||
function getAll( context, tag ) {
|
||
|
||
// Support: IE <=9 - 11 only
|
||
// Use typeof to avoid zero-argument method invocation on host objects (#15151)
|
||
var ret;
|
||
|
||
if ( typeof context.getElementsByTagName !== "undefined" ) {
|
||
ret = context.getElementsByTagName( tag || "*" );
|
||
|
||
} else if ( typeof context.querySelectorAll !== "undefined" ) {
|
||
ret = context.querySelectorAll( tag || "*" );
|
||
|
||
} else {
|
||
ret = [];
|
||
}
|
||
|
||
if ( tag === undefined || tag && nodeName( context, tag ) ) {
|
||
return jQuery.merge( [ context ], ret );
|
||
}
|
||
|
||
return ret;
|
||
}
|
||
|
||
|
||
// Mark scripts as having already been evaluated
|
||
function setGlobalEval( elems, refElements ) {
|
||
var i = 0,
|
||
l = elems.length;
|
||
|
||
for ( ; i < l; i++ ) {
|
||
dataPriv.set(
|
||
elems[ i ],
|
||
"globalEval",
|
||
!refElements || dataPriv.get( refElements[ i ], "globalEval" )
|
||
);
|
||
}
|
||
}
|
||
|
||
|
||
var rhtml = /<|&#?\w+;/;
|
||
|
||
function buildFragment( elems, context, scripts, selection, ignored ) {
|
||
var elem, tmp, tag, wrap, contains, j,
|
||
fragment = context.createDocumentFragment(),
|
||
nodes = [],
|
||
i = 0,
|
||
l = elems.length;
|
||
|
||
for ( ; i < l; i++ ) {
|
||
elem = elems[ i ];
|
||
|
||
if ( elem || elem === 0 ) {
|
||
|
||
// Add nodes directly
|
||
if ( jQuery.type( elem ) === "object" ) {
|
||
|
||
// Support: Android <=4.0 only, PhantomJS 1 only
|
||
// push.apply(_, arraylike) throws on ancient WebKit
|
||
jQuery.merge( nodes, elem.nodeType ? [ elem ] : elem );
|
||
|
||
// Convert non-html into a text node
|
||
} else if ( !rhtml.test( elem ) ) {
|
||
nodes.push( context.createTextNode( elem ) );
|
||
|
||
// Convert html into DOM nodes
|
||
} else {
|
||
tmp = tmp || fragment.appendChild( context.createElement( "div" ) );
|
||
|
||
// Deserialize a standard representation
|
||
tag = ( rtagName.exec( elem ) || [ "", "" ] )[ 1 ].toLowerCase();
|
||
wrap = wrapMap[ tag ] || wrapMap._default;
|
||
tmp.innerHTML = wrap[ 1 ] + jQuery.htmlPrefilter( elem ) + wrap[ 2 ];
|
||
|
||
// Descend through wrappers to the right content
|
||
j = wrap[ 0 ];
|
||
while ( j-- ) {
|
||
tmp = tmp.lastChild;
|
||
}
|
||
|
||
// Support: Android <=4.0 only, PhantomJS 1 only
|
||
// push.apply(_, arraylike) throws on ancient WebKit
|
||
jQuery.merge( nodes, tmp.childNodes );
|
||
|
||
// Remember the top-level container
|
||
tmp = fragment.firstChild;
|
||
|
||
// Ensure the created nodes are orphaned (#12392)
|
||
tmp.textContent = "";
|
||
}
|
||
}
|
||
}
|
||
|
||
// Remove wrapper from fragment
|
||
fragment.textContent = "";
|
||
|
||
i = 0;
|
||
while ( ( elem = nodes[ i++ ] ) ) {
|
||
|
||
// Skip elements already in the context collection (trac-4087)
|
||
if ( selection && jQuery.inArray( elem, selection ) > -1 ) {
|
||
if ( ignored ) {
|
||
ignored.push( elem );
|
||
}
|
||
continue;
|
||
}
|
||
|
||
contains = jQuery.contains( elem.ownerDocument, elem );
|
||
|
||
// Append to fragment
|
||
tmp = getAll( fragment.appendChild( elem ), "script" );
|
||
|
||
// Preserve script evaluation history
|
||
if ( contains ) {
|
||
setGlobalEval( tmp );
|
||
}
|
||
|
||
// Capture executables
|
||
if ( scripts ) {
|
||
j = 0;
|
||
while ( ( elem = tmp[ j++ ] ) ) {
|
||
if ( rscriptType.test( elem.type || "" ) ) {
|
||
scripts.push( elem );
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
return fragment;
|
||
}
|
||
|
||
|
||
( function() {
|
||
var fragment = document.createDocumentFragment(),
|
||
div = fragment.appendChild( document.createElement( "div" ) ),
|
||
input = document.createElement( "input" );
|
||
|
||
// Support: Android 4.0 - 4.3 only
|
||
// Check state lost if the name is set (#11217)
|
||
// Support: Windows Web Apps (WWA)
|
||
// `name` and `type` must use .setAttribute for WWA (#14901)
|
||
input.setAttribute( "type", "radio" );
|
||
input.setAttribute( "checked", "checked" );
|
||
input.setAttribute( "name", "t" );
|
||
|
||
div.appendChild( input );
|
||
|
||
// Support: Android <=4.1 only
|
||
// Older WebKit doesn't clone checked state correctly in fragments
|
||
support.checkClone = div.cloneNode( true ).cloneNode( true ).lastChild.checked;
|
||
|
||
// Support: IE <=11 only
|
||
// Make sure textarea (and checkbox) defaultValue is properly cloned
|
||
div.innerHTML = "<textarea>x</textarea>";
|
||
support.noCloneChecked = !!div.cloneNode( true ).lastChild.defaultValue;
|
||
} )();
|
||
var documentElement = document.documentElement;
|
||
|
||
|
||
|
||
var
|
||
rkeyEvent = /^key/,
|
||
rmouseEvent = /^(?:mouse|pointer|contextmenu|drag|drop)|click/,
|
||
rtypenamespace = /^([^.]*)(?:\.(.+)|)/;
|
||
|
||
function returnTrue() {
|
||
return true;
|
||
}
|
||
|
||
function returnFalse() {
|
||
return false;
|
||
}
|
||
|
||
// Support: IE <=9 only
|
||
// See #13393 for more info
|
||
function safeActiveElement() {
|
||
try {
|
||
return document.activeElement;
|
||
} catch ( err ) { }
|
||
}
|
||
|
||
function on( elem, types, selector, data, fn, one ) {
|
||
var origFn, type;
|
||
|
||
// Types can be a map of types/handlers
|
||
if ( typeof types === "object" ) {
|
||
|
||
// ( types-Object, selector, data )
|
||
if ( typeof selector !== "string" ) {
|
||
|
||
// ( types-Object, data )
|
||
data = data || selector;
|
||
selector = undefined;
|
||
}
|
||
for ( type in types ) {
|
||
on( elem, type, selector, data, types[ type ], one );
|
||
}
|
||
return elem;
|
||
}
|
||
|
||
if ( data == null && fn == null ) {
|
||
|
||
// ( types, fn )
|
||
fn = selector;
|
||
data = selector = undefined;
|
||
} else if ( fn == null ) {
|
||
if ( typeof selector === "string" ) {
|
||
|
||
// ( types, selector, fn )
|
||
fn = data;
|
||
data = undefined;
|
||
} else {
|
||
|
||
// ( types, data, fn )
|
||
fn = data;
|
||
data = selector;
|
||
selector = undefined;
|
||
}
|
||
}
|
||
if ( fn === false ) {
|
||
fn = returnFalse;
|
||
} else if ( !fn ) {
|
||
return elem;
|
||
}
|
||
|
||
if ( one === 1 ) {
|
||
origFn = fn;
|
||
fn = function( event ) {
|
||
|
||
// Can use an empty set, since event contains the info
|
||
jQuery().off( event );
|
||
return origFn.apply( this, arguments );
|
||
};
|
||
|
||
// Use same guid so caller can remove using origFn
|
||
fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ );
|
||
}
|
||
return elem.each( function() {
|
||
jQuery.event.add( this, types, fn, data, selector );
|
||
} );
|
||
}
|
||
|
||
/*
|
||
* Helper functions for managing events -- not part of the public interface.
|
||
* Props to Dean Edwards' addEvent library for many of the ideas.
|
||
*/
|
||
jQuery.event = {
|
||
|
||
global: {},
|
||
|
||
add: function( elem, types, handler, data, selector ) {
|
||
|
||
var handleObjIn, eventHandle, tmp,
|
||
events, t, handleObj,
|
||
special, handlers, type, namespaces, origType,
|
||
elemData = dataPriv.get( elem );
|
||
|
||
// Don't attach events to noData or text/comment nodes (but allow plain objects)
|
||
if ( !elemData ) {
|
||
return;
|
||
}
|
||
|
||
// Caller can pass in an object of custom data in lieu of the handler
|
||
if ( handler.handler ) {
|
||
handleObjIn = handler;
|
||
handler = handleObjIn.handler;
|
||
selector = handleObjIn.selector;
|
||
}
|
||
|
||
// Ensure that invalid selectors throw exceptions at attach time
|
||
// Evaluate against documentElement in case elem is a non-element node (e.g., document)
|
||
if ( selector ) {
|
||
jQuery.find.matchesSelector( documentElement, selector );
|
||
}
|
||
|
||
// Make sure that the handler has a unique ID, used to find/remove it later
|
||
if ( !handler.guid ) {
|
||
handler.guid = jQuery.guid++;
|
||
}
|
||
|
||
// Init the element's event structure and main handler, if this is the first
|
||
if ( !( events = elemData.events ) ) {
|
||
events = elemData.events = {};
|
||
}
|
||
if ( !( eventHandle = elemData.handle ) ) {
|
||
eventHandle = elemData.handle = function( e ) {
|
||
|
||
// Discard the second event of a jQuery.event.trigger() and
|
||
// when an event is called after a page has unloaded
|
||
return typeof jQuery !== "undefined" && jQuery.event.triggered !== e.type ?
|
||
jQuery.event.dispatch.apply( elem, arguments ) : undefined;
|
||
};
|
||
}
|
||
|
||
// Handle multiple events separated by a space
|
||
types = ( types || "" ).match( rnothtmlwhite ) || [ "" ];
|
||
t = types.length;
|
||
while ( t-- ) {
|
||
tmp = rtypenamespace.exec( types[ t ] ) || [];
|
||
type = origType = tmp[ 1 ];
|
||
namespaces = ( tmp[ 2 ] || "" ).split( "." ).sort();
|
||
|
||
// There *must* be a type, no attaching namespace-only handlers
|
||
if ( !type ) {
|
||
continue;
|
||
}
|
||
|
||
// If event changes its type, use the special event handlers for the changed type
|
||
special = jQuery.event.special[ type ] || {};
|
||
|
||
// If selector defined, determine special event api type, otherwise given type
|
||
type = ( selector ? special.delegateType : special.bindType ) || type;
|
||
|
||
// Update special based on newly reset type
|
||
special = jQuery.event.special[ type ] || {};
|
||
|
||
// handleObj is passed to all event handlers
|
||
handleObj = jQuery.extend( {
|
||
type: type,
|
||
origType: origType,
|
||
data: data,
|
||
handler: handler,
|
||
guid: handler.guid,
|
||
selector: selector,
|
||
needsContext: selector && jQuery.expr.match.needsContext.test( selector ),
|
||
namespace: namespaces.join( "." )
|
||
}, handleObjIn );
|
||
|
||
// Init the event handler queue if we're the first
|
||
if ( !( handlers = events[ type ] ) ) {
|
||
handlers = events[ type ] = [];
|
||
handlers.delegateCount = 0;
|
||
|
||
// Only use addEventListener if the special events handler returns false
|
||
if ( !special.setup ||
|
||
special.setup.call( elem, data, namespaces, eventHandle ) === false ) {
|
||
|
||
if ( elem.addEventListener ) {
|
||
elem.addEventListener( type, eventHandle );
|
||
}
|
||
}
|
||
}
|
||
|
||
if ( special.add ) {
|
||
special.add.call( elem, handleObj );
|
||
|
||
if ( !handleObj.handler.guid ) {
|
||
handleObj.handler.guid = handler.guid;
|
||
}
|
||
}
|
||
|
||
// Add to the element's handler list, delegates in front
|
||
if ( selector ) {
|
||
handlers.splice( handlers.delegateCount++, 0, handleObj );
|
||
} else {
|
||
handlers.push( handleObj );
|
||
}
|
||
|
||
// Keep track of which events have ever been used, for event optimization
|
||
jQuery.event.global[ type ] = true;
|
||
}
|
||
|
||
},
|
||
|
||
// Detach an event or set of events from an element
|
||
remove: function( elem, types, handler, selector, mappedTypes ) {
|
||
|
||
var j, origCount, tmp,
|
||
events, t, handleObj,
|
||
special, handlers, type, namespaces, origType,
|
||
elemData = dataPriv.hasData( elem ) && dataPriv.get( elem );
|
||
|
||
if ( !elemData || !( events = elemData.events ) ) {
|
||
return;
|
||
}
|
||
|
||
// Once for each type.namespace in types; type may be omitted
|
||
types = ( types || "" ).match( rnothtmlwhite ) || [ "" ];
|
||
t = types.length;
|
||
while ( t-- ) {
|
||
tmp = rtypenamespace.exec( types[ t ] ) || [];
|
||
type = origType = tmp[ 1 ];
|
||
namespaces = ( tmp[ 2 ] || "" ).split( "." ).sort();
|
||
|
||
// Unbind all events (on this namespace, if provided) for the element
|
||
if ( !type ) {
|
||
for ( type in events ) {
|
||
jQuery.event.remove( elem, type + types[ t ], handler, selector, true );
|
||
}
|
||
continue;
|
||
}
|
||
|
||
special = jQuery.event.special[ type ] || {};
|
||
type = ( selector ? special.delegateType : special.bindType ) || type;
|
||
handlers = events[ type ] || [];
|
||
tmp = tmp[ 2 ] &&
|
||
new RegExp( "(^|\\.)" + namespaces.join( "\\.(?:.*\\.|)" ) + "(\\.|$)" );
|
||
|
||
// Remove matching events
|
||
origCount = j = handlers.length;
|
||
while ( j-- ) {
|
||
handleObj = handlers[ j ];
|
||
|
||
if ( ( mappedTypes || origType === handleObj.origType ) &&
|
||
( !handler || handler.guid === handleObj.guid ) &&
|
||
( !tmp || tmp.test( handleObj.namespace ) ) &&
|
||
( !selector || selector === handleObj.selector ||
|
||
selector === "**" && handleObj.selector ) ) {
|
||
handlers.splice( j, 1 );
|
||
|
||
if ( handleObj.selector ) {
|
||
handlers.delegateCount--;
|
||
}
|
||
if ( special.remove ) {
|
||
special.remove.call( elem, handleObj );
|
||
}
|
||
}
|
||
}
|
||
|
||
// Remove generic event handler if we removed something and no more handlers exist
|
||
// (avoids potential for endless recursion during removal of special event handlers)
|
||
if ( origCount && !handlers.length ) {
|
||
if ( !special.teardown ||
|
||
special.teardown.call( elem, namespaces, elemData.handle ) === false ) {
|
||
|
||
jQuery.removeEvent( elem, type, elemData.handle );
|
||
}
|
||
|
||
delete events[ type ];
|
||
}
|
||
}
|
||
|
||
// Remove data and the expando if it's no longer used
|
||
if ( jQuery.isEmptyObject( events ) ) {
|
||
dataPriv.remove( elem, "handle events" );
|
||
}
|
||
},
|
||
|
||
dispatch: function( nativeEvent ) {
|
||
|
||
// Make a writable jQuery.Event from the native event object
|
||
var event = jQuery.event.fix( nativeEvent );
|
||
|
||
var i, j, ret, matched, handleObj, handlerQueue,
|
||
args = new Array( arguments.length ),
|
||
handlers = ( dataPriv.get( this, "events" ) || {} )[ event.type ] || [],
|
||
special = jQuery.event.special[ event.type ] || {};
|
||
|
||
// Use the fix-ed jQuery.Event rather than the (read-only) native event
|
||
args[ 0 ] = event;
|
||
|
||
for ( i = 1; i < arguments.length; i++ ) {
|
||
args[ i ] = arguments[ i ];
|
||
}
|
||
|
||
event.delegateTarget = this;
|
||
|
||
// Call the preDispatch hook for the mapped type, and let it bail if desired
|
||
if ( special.preDispatch && special.preDispatch.call( this, event ) === false ) {
|
||
return;
|
||
}
|
||
|
||
// Determine handlers
|
||
handlerQueue = jQuery.event.handlers.call( this, event, handlers );
|
||
|
||
// Run delegates first; they may want to stop propagation beneath us
|
||
i = 0;
|
||
while ( ( matched = handlerQueue[ i++ ] ) && !event.isPropagationStopped() ) {
|
||
event.currentTarget = matched.elem;
|
||
|
||
j = 0;
|
||
while ( ( handleObj = matched.handlers[ j++ ] ) &&
|
||
!event.isImmediatePropagationStopped() ) {
|
||
|
||
// Triggered event must either 1) have no namespace, or 2) have namespace(s)
|
||
// a subset or equal to those in the bound event (both can have no namespace).
|
||
if ( !event.rnamespace || event.rnamespace.test( handleObj.namespace ) ) {
|
||
|
||
event.handleObj = handleObj;
|
||
event.data = handleObj.data;
|
||
|
||
ret = ( ( jQuery.event.special[ handleObj.origType ] || {} ).handle ||
|
||
handleObj.handler ).apply( matched.elem, args );
|
||
|
||
if ( ret !== undefined ) {
|
||
if ( ( event.result = ret ) === false ) {
|
||
event.preventDefault();
|
||
event.stopPropagation();
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
// Call the postDispatch hook for the mapped type
|
||
if ( special.postDispatch ) {
|
||
special.postDispatch.call( this, event );
|
||
}
|
||
|
||
return event.result;
|
||
},
|
||
|
||
handlers: function( event, handlers ) {
|
||
var i, handleObj, sel, matchedHandlers, matchedSelectors,
|
||
handlerQueue = [],
|
||
delegateCount = handlers.delegateCount,
|
||
cur = event.target;
|
||
|
||
// Find delegate handlers
|
||
if ( delegateCount &&
|
||
|
||
// Support: IE <=9
|
||
// Black-hole SVG <use> instance trees (trac-13180)
|
||
cur.nodeType &&
|
||
|
||
// Support: Firefox <=42
|
||
// Suppress spec-violating clicks indicating a non-primary pointer button (trac-3861)
|
||
// https://www.w3.org/TR/DOM-Level-3-Events/#event-type-click
|
||
// Support: IE 11 only
|
||
// ...but not arrow key "clicks" of radio inputs, which can have `button` -1 (gh-2343)
|
||
!( event.type === "click" && event.button >= 1 ) ) {
|
||
|
||
for ( ; cur !== this; cur = cur.parentNode || this ) {
|
||
|
||
// Don't check non-elements (#13208)
|
||
// Don't process clicks on disabled elements (#6911, #8165, #11382, #11764)
|
||
if ( cur.nodeType === 1 && !( event.type === "click" && cur.disabled === true ) ) {
|
||
matchedHandlers = [];
|
||
matchedSelectors = {};
|
||
for ( i = 0; i < delegateCount; i++ ) {
|
||
handleObj = handlers[ i ];
|
||
|
||
// Don't conflict with Object.prototype properties (#13203)
|
||
sel = handleObj.selector + " ";
|
||
|
||
if ( matchedSelectors[ sel ] === undefined ) {
|
||
matchedSelectors[ sel ] = handleObj.needsContext ?
|
||
jQuery( sel, this ).index( cur ) > -1 :
|
||
jQuery.find( sel, this, null, [ cur ] ).length;
|
||
}
|
||
if ( matchedSelectors[ sel ] ) {
|
||
matchedHandlers.push( handleObj );
|
||
}
|
||
}
|
||
if ( matchedHandlers.length ) {
|
||
handlerQueue.push( { elem: cur, handlers: matchedHandlers } );
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
// Add the remaining (directly-bound) handlers
|
||
cur = this;
|
||
if ( delegateCount < handlers.length ) {
|
||
handlerQueue.push( { elem: cur, handlers: handlers.slice( delegateCount ) } );
|
||
}
|
||
|
||
return handlerQueue;
|
||
},
|
||
|
||
addProp: function( name, hook ) {
|
||
Object.defineProperty( jQuery.Event.prototype, name, {
|
||
enumerable: true,
|
||
configurable: true,
|
||
|
||
get: jQuery.isFunction( hook ) ?
|
||
function() {
|
||
if ( this.originalEvent ) {
|
||
return hook( this.originalEvent );
|
||
}
|
||
} :
|
||
function() {
|
||
if ( this.originalEvent ) {
|
||
return this.originalEvent[ name ];
|
||
}
|
||
},
|
||
|
||
set: function( value ) {
|
||
Object.defineProperty( this, name, {
|
||
enumerable: true,
|
||
configurable: true,
|
||
writable: true,
|
||
value: value
|
||
} );
|
||
}
|
||
} );
|
||
},
|
||
|
||
fix: function( originalEvent ) {
|
||
return originalEvent[ jQuery.expando ] ?
|
||
originalEvent :
|
||
new jQuery.Event( originalEvent );
|
||
},
|
||
|
||
special: {
|
||
load: {
|
||
|
||
// Prevent triggered image.load events from bubbling to window.load
|
||
noBubble: true
|
||
},
|
||
focus: {
|
||
|
||
// Fire native event if possible so blur/focus sequence is correct
|
||
trigger: function() {
|
||
if ( this !== safeActiveElement() && this.focus ) {
|
||
this.focus();
|
||
return false;
|
||
}
|
||
},
|
||
delegateType: "focusin"
|
||
},
|
||
blur: {
|
||
trigger: function() {
|
||
if ( this === safeActiveElement() && this.blur ) {
|
||
this.blur();
|
||
return false;
|
||
}
|
||
},
|
||
delegateType: "focusout"
|
||
},
|
||
click: {
|
||
|
||
// For checkbox, fire native event so checked state will be right
|
||
trigger: function() {
|
||
if ( this.type === "checkbox" && this.click && nodeName( this, "input" ) ) {
|
||
this.click();
|
||
return false;
|
||
}
|
||
},
|
||
|
||
// For cross-browser consistency, don't fire native .click() on links
|
||
_default: function( event ) {
|
||
return nodeName( event.target, "a" );
|
||
}
|
||
},
|
||
|
||
beforeunload: {
|
||
postDispatch: function( event ) {
|
||
|
||
// Support: Firefox 20+
|
||
// Firefox doesn't alert if the returnValue field is not set.
|
||
if ( event.result !== undefined && event.originalEvent ) {
|
||
event.originalEvent.returnValue = event.result;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
};
|
||
|
||
jQuery.removeEvent = function( elem, type, handle ) {
|
||
|
||
// This "if" is needed for plain objects
|
||
if ( elem.removeEventListener ) {
|
||
elem.removeEventListener( type, handle );
|
||
}
|
||
};
|
||
|
||
jQuery.Event = function( src, props ) {
|
||
|
||
// Allow instantiation without the 'new' keyword
|
||
if ( !( this instanceof jQuery.Event ) ) {
|
||
return new jQuery.Event( src, props );
|
||
}
|
||
|
||
// Event object
|
||
if ( src && src.type ) {
|
||
this.originalEvent = src;
|
||
this.type = src.type;
|
||
|
||
// Events bubbling up the document may have been marked as prevented
|
||
// by a handler lower down the tree; reflect the correct value.
|
||
this.isDefaultPrevented = src.defaultPrevented ||
|
||
src.defaultPrevented === undefined &&
|
||
|
||
// Support: Android <=2.3 only
|
||
src.returnValue === false ?
|
||
returnTrue :
|
||
returnFalse;
|
||
|
||
// Create target properties
|
||
// Support: Safari <=6 - 7 only
|
||
// Target should not be a text node (#504, #13143)
|
||
this.target = ( src.target && src.target.nodeType === 3 ) ?
|
||
src.target.parentNode :
|
||
src.target;
|
||
|
||
this.currentTarget = src.currentTarget;
|
||
this.relatedTarget = src.relatedTarget;
|
||
|
||
// Event type
|
||
} else {
|
||
this.type = src;
|
||
}
|
||
|
||
// Put explicitly provided properties onto the event object
|
||
if ( props ) {
|
||
jQuery.extend( this, props );
|
||
}
|
||
|
||
// Create a timestamp if incoming event doesn't have one
|
||
this.timeStamp = src && src.timeStamp || jQuery.now();
|
||
|
||
// Mark it as fixed
|
||
this[ jQuery.expando ] = true;
|
||
};
|
||
|
||
// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding
|
||
// https://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html
|
||
jQuery.Event.prototype = {
|
||
constructor: jQuery.Event,
|
||
isDefaultPrevented: returnFalse,
|
||
isPropagationStopped: returnFalse,
|
||
isImmediatePropagationStopped: returnFalse,
|
||
isSimulated: false,
|
||
|
||
preventDefault: function() {
|
||
var e = this.originalEvent;
|
||
|
||
this.isDefaultPrevented = returnTrue;
|
||
|
||
if ( e && !this.isSimulated ) {
|
||
e.preventDefault();
|
||
}
|
||
},
|
||
stopPropagation: function() {
|
||
var e = this.originalEvent;
|
||
|
||
this.isPropagationStopped = returnTrue;
|
||
|
||
if ( e && !this.isSimulated ) {
|
||
e.stopPropagation();
|
||
}
|
||
},
|
||
stopImmediatePropagation: function() {
|
||
var e = this.originalEvent;
|
||
|
||
this.isImmediatePropagationStopped = returnTrue;
|
||
|
||
if ( e && !this.isSimulated ) {
|
||
e.stopImmediatePropagation();
|
||
}
|
||
|
||
this.stopPropagation();
|
||
}
|
||
};
|
||
|
||
// Includes all common event props including KeyEvent and MouseEvent specific props
|
||
jQuery.each( {
|
||
altKey: true,
|
||
bubbles: true,
|
||
cancelable: true,
|
||
changedTouches: true,
|
||
ctrlKey: true,
|
||
detail: true,
|
||
eventPhase: true,
|
||
metaKey: true,
|
||
pageX: true,
|
||
pageY: true,
|
||
shiftKey: true,
|
||
view: true,
|
||
"char": true,
|
||
charCode: true,
|
||
key: true,
|
||
keyCode: true,
|
||
button: true,
|
||
buttons: true,
|
||
clientX: true,
|
||
clientY: true,
|
||
offsetX: true,
|
||
offsetY: true,
|
||
pointerId: true,
|
||
pointerType: true,
|
||
screenX: true,
|
||
screenY: true,
|
||
targetTouches: true,
|
||
toElement: true,
|
||
touches: true,
|
||
|
||
which: function( event ) {
|
||
var button = event.button;
|
||
|
||
// Add which for key events
|
||
if ( event.which == null && rkeyEvent.test( event.type ) ) {
|
||
return event.charCode != null ? event.charCode : event.keyCode;
|
||
}
|
||
|
||
// Add which for click: 1 === left; 2 === middle; 3 === right
|
||
if ( !event.which && button !== undefined && rmouseEvent.test( event.type ) ) {
|
||
if ( button & 1 ) {
|
||
return 1;
|
||
}
|
||
|
||
if ( button & 2 ) {
|
||
return 3;
|
||
}
|
||
|
||
if ( button & 4 ) {
|
||
return 2;
|
||
}
|
||
|
||
return 0;
|
||
}
|
||
|
||
return event.which;
|
||
}
|
||
}, jQuery.event.addProp );
|
||
|
||
// Create mouseenter/leave events using mouseover/out and event-time checks
|
||
// so that event delegation works in jQuery.
|
||
// Do the same for pointerenter/pointerleave and pointerover/pointerout
|
||
//
|
||
// Support: Safari 7 only
|
||
// Safari sends mouseenter too often; see:
|
||
// https://bugs.chromium.org/p/chromium/issues/detail?id=470258
|
||
// for the description of the bug (it existed in older Chrome versions as well).
|
||
jQuery.each( {
|
||
mouseenter: "mouseover",
|
||
mouseleave: "mouseout",
|
||
pointerenter: "pointerover",
|
||
pointerleave: "pointerout"
|
||
}, function( orig, fix ) {
|
||
jQuery.event.special[ orig ] = {
|
||
delegateType: fix,
|
||
bindType: fix,
|
||
|
||
handle: function( event ) {
|
||
var ret,
|
||
target = this,
|
||
related = event.relatedTarget,
|
||
handleObj = event.handleObj;
|
||
|
||
// For mouseenter/leave call the handler if related is outside the target.
|
||
// NB: No relatedTarget if the mouse left/entered the browser window
|
||
if ( !related || ( related !== target && !jQuery.contains( target, related ) ) ) {
|
||
event.type = handleObj.origType;
|
||
ret = handleObj.handler.apply( this, arguments );
|
||
event.type = fix;
|
||
}
|
||
return ret;
|
||
}
|
||
};
|
||
} );
|
||
|
||
jQuery.fn.extend( {
|
||
|
||
on: function( types, selector, data, fn ) {
|
||
return on( this, types, selector, data, fn );
|
||
},
|
||
one: function( types, selector, data, fn ) {
|
||
return on( this, types, selector, data, fn, 1 );
|
||
},
|
||
off: function( types, selector, fn ) {
|
||
var handleObj, type;
|
||
if ( types && types.preventDefault && types.handleObj ) {
|
||
|
||
// ( event ) dispatched jQuery.Event
|
||
handleObj = types.handleObj;
|
||
jQuery( types.delegateTarget ).off(
|
||
handleObj.namespace ?
|
||
handleObj.origType + "." + handleObj.namespace :
|
||
handleObj.origType,
|
||
handleObj.selector,
|
||
handleObj.handler
|
||
);
|
||
return this;
|
||
}
|
||
if ( typeof types === "object" ) {
|
||
|
||
// ( types-object [, selector] )
|
||
for ( type in types ) {
|
||
this.off( type, selector, types[ type ] );
|
||
}
|
||
return this;
|
||
}
|
||
if ( selector === false || typeof selector === "function" ) {
|
||
|
||
// ( types [, fn] )
|
||
fn = selector;
|
||
selector = undefined;
|
||
}
|
||
if ( fn === false ) {
|
||
fn = returnFalse;
|
||
}
|
||
return this.each( function() {
|
||
jQuery.event.remove( this, types, fn, selector );
|
||
} );
|
||
}
|
||
} );
|
||
|
||
|
||
var
|
||
|
||
/* eslint-disable max-len */
|
||
|
||
// See https://github.com/eslint/eslint/issues/3229
|
||
rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([a-z][^\/\0>\x20\t\r\n\f]*)[^>]*)\/>/gi,
|
||
|
||
/* eslint-enable */
|
||
|
||
// Support: IE <=10 - 11, Edge 12 - 13
|
||
// In IE/Edge using regex groups here causes severe slowdowns.
|
||
// See https://connect.microsoft.com/IE/feedback/details/1736512/
|
||
rnoInnerhtml = /<script|<style|<link/i,
|
||
|
||
// checked="checked" or checked
|
||
rchecked = /checked\s*(?:[^=]|=\s*.checked.)/i,
|
||
rscriptTypeMasked = /^true\/(.*)/,
|
||
rcleanScript = /^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g;
|
||
|
||
// Prefer a tbody over its parent table for containing new rows
|
||
function manipulationTarget( elem, content ) {
|
||
if ( nodeName( elem, "table" ) &&
|
||
nodeName( content.nodeType !== 11 ? content : content.firstChild, "tr" ) ) {
|
||
|
||
return jQuery( ">tbody", elem )[ 0 ] || elem;
|
||
}
|
||
|
||
return elem;
|
||
}
|
||
|
||
// Replace/restore the type attribute of script elements for safe DOM manipulation
|
||
function disableScript( elem ) {
|
||
elem.type = ( elem.getAttribute( "type" ) !== null ) + "/" + elem.type;
|
||
return elem;
|
||
}
|
||
function restoreScript( elem ) {
|
||
var match = rscriptTypeMasked.exec( elem.type );
|
||
|
||
if ( match ) {
|
||
elem.type = match[ 1 ];
|
||
} else {
|
||
elem.removeAttribute( "type" );
|
||
}
|
||
|
||
return elem;
|
||
}
|
||
|
||
function cloneCopyEvent( src, dest ) {
|
||
var i, l, type, pdataOld, pdataCur, udataOld, udataCur, events;
|
||
|
||
if ( dest.nodeType !== 1 ) {
|
||
return;
|
||
}
|
||
|
||
// 1. Copy private data: events, handlers, etc.
|
||
if ( dataPriv.hasData( src ) ) {
|
||
pdataOld = dataPriv.access( src );
|
||
pdataCur = dataPriv.set( dest, pdataOld );
|
||
events = pdataOld.events;
|
||
|
||
if ( events ) {
|
||
delete pdataCur.handle;
|
||
pdataCur.events = {};
|
||
|
||
for ( type in events ) {
|
||
for ( i = 0, l = events[ type ].length; i < l; i++ ) {
|
||
jQuery.event.add( dest, type, events[ type ][ i ] );
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
// 2. Copy user data
|
||
if ( dataUser.hasData( src ) ) {
|
||
udataOld = dataUser.access( src );
|
||
udataCur = jQuery.extend( {}, udataOld );
|
||
|
||
dataUser.set( dest, udataCur );
|
||
}
|
||
}
|
||
|
||
// Fix IE bugs, see support tests
|
||
function fixInput( src, dest ) {
|
||
var nodeName = dest.nodeName.toLowerCase();
|
||
|
||
// Fails to persist the checked state of a cloned checkbox or radio button.
|
||
if ( nodeName === "input" && rcheckableType.test( src.type ) ) {
|
||
dest.checked = src.checked;
|
||
|
||
// Fails to return the selected option to the default selected state when cloning options
|
||
} else if ( nodeName === "input" || nodeName === "textarea" ) {
|
||
dest.defaultValue = src.defaultValue;
|
||
}
|
||
}
|
||
|
||
function domManip( collection, args, callback, ignored ) {
|
||
|
||
// Flatten any nested arrays
|
||
args = concat.apply( [], args );
|
||
|
||
var fragment, first, scripts, hasScripts, node, doc,
|
||
i = 0,
|
||
l = collection.length,
|
||
iNoClone = l - 1,
|
||
value = args[ 0 ],
|
||
isFunction = jQuery.isFunction( value );
|
||
|
||
// We can't cloneNode fragments that contain checked, in WebKit
|
||
if ( isFunction ||
|
||
( l > 1 && typeof value === "string" &&
|
||
!support.checkClone && rchecked.test( value ) ) ) {
|
||
return collection.each( function( index ) {
|
||
var self = collection.eq( index );
|
||
if ( isFunction ) {
|
||
args[ 0 ] = value.call( this, index, self.html() );
|
||
}
|
||
domManip( self, args, callback, ignored );
|
||
} );
|
||
}
|
||
|
||
if ( l ) {
|
||
fragment = buildFragment( args, collection[ 0 ].ownerDocument, false, collection, ignored );
|
||
first = fragment.firstChild;
|
||
|
||
if ( fragment.childNodes.length === 1 ) {
|
||
fragment = first;
|
||
}
|
||
|
||
// Require either new content or an interest in ignored elements to invoke the callback
|
||
if ( first || ignored ) {
|
||
scripts = jQuery.map( getAll( fragment, "script" ), disableScript );
|
||
hasScripts = scripts.length;
|
||
|
||
// Use the original fragment for the last item
|
||
// instead of the first because it can end up
|
||
// being emptied incorrectly in certain situations (#8070).
|
||
for ( ; i < l; i++ ) {
|
||
node = fragment;
|
||
|
||
if ( i !== iNoClone ) {
|
||
node = jQuery.clone( node, true, true );
|
||
|
||
// Keep references to cloned scripts for later restoration
|
||
if ( hasScripts ) {
|
||
|
||
// Support: Android <=4.0 only, PhantomJS 1 only
|
||
// push.apply(_, arraylike) throws on ancient WebKit
|
||
jQuery.merge( scripts, getAll( node, "script" ) );
|
||
}
|
||
}
|
||
|
||
callback.call( collection[ i ], node, i );
|
||
}
|
||
|
||
if ( hasScripts ) {
|
||
doc = scripts[ scripts.length - 1 ].ownerDocument;
|
||
|
||
// Reenable scripts
|
||
jQuery.map( scripts, restoreScript );
|
||
|
||
// Evaluate executable scripts on first document insertion
|
||
for ( i = 0; i < hasScripts; i++ ) {
|
||
node = scripts[ i ];
|
||
if ( rscriptType.test( node.type || "" ) &&
|
||
!dataPriv.access( node, "globalEval" ) &&
|
||
jQuery.contains( doc, node ) ) {
|
||
|
||
if ( node.src ) {
|
||
|
||
// Optional AJAX dependency, but won't run scripts if not present
|
||
if ( jQuery._evalUrl ) {
|
||
jQuery._evalUrl( node.src );
|
||
}
|
||
} else {
|
||
DOMEval( node.textContent.replace( rcleanScript, "" ), doc );
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
return collection;
|
||
}
|
||
|
||
function remove( elem, selector, keepData ) {
|
||
var node,
|
||
nodes = selector ? jQuery.filter( selector, elem ) : elem,
|
||
i = 0;
|
||
|
||
for ( ; ( node = nodes[ i ] ) != null; i++ ) {
|
||
if ( !keepData && node.nodeType === 1 ) {
|
||
jQuery.cleanData( getAll( node ) );
|
||
}
|
||
|
||
if ( node.parentNode ) {
|
||
if ( keepData && jQuery.contains( node.ownerDocument, node ) ) {
|
||
setGlobalEval( getAll( node, "script" ) );
|
||
}
|
||
node.parentNode.removeChild( node );
|
||
}
|
||
}
|
||
|
||
return elem;
|
||
}
|
||
|
||
jQuery.extend( {
|
||
htmlPrefilter: function( html ) {
|
||
return html.replace( rxhtmlTag, "<$1></$2>" );
|
||
},
|
||
|
||
clone: function( elem, dataAndEvents, deepDataAndEvents ) {
|
||
var i, l, srcElements, destElements,
|
||
clone = elem.cloneNode( true ),
|
||
inPage = jQuery.contains( elem.ownerDocument, elem );
|
||
|
||
// Fix IE cloning issues
|
||
if ( !support.noCloneChecked && ( elem.nodeType === 1 || elem.nodeType === 11 ) &&
|
||
!jQuery.isXMLDoc( elem ) ) {
|
||
|
||
// We eschew Sizzle here for performance reasons: https://jsperf.com/getall-vs-sizzle/2
|
||
destElements = getAll( clone );
|
||
srcElements = getAll( elem );
|
||
|
||
for ( i = 0, l = srcElements.length; i < l; i++ ) {
|
||
fixInput( srcElements[ i ], destElements[ i ] );
|
||
}
|
||
}
|
||
|
||
// Copy the events from the original to the clone
|
||
if ( dataAndEvents ) {
|
||
if ( deepDataAndEvents ) {
|
||
srcElements = srcElements || getAll( elem );
|
||
destElements = destElements || getAll( clone );
|
||
|
||
for ( i = 0, l = srcElements.length; i < l; i++ ) {
|
||
cloneCopyEvent( srcElements[ i ], destElements[ i ] );
|
||
}
|
||
} else {
|
||
cloneCopyEvent( elem, clone );
|
||
}
|
||
}
|
||
|
||
// Preserve script evaluation history
|
||
destElements = getAll( clone, "script" );
|
||
if ( destElements.length > 0 ) {
|
||
setGlobalEval( destElements, !inPage && getAll( elem, "script" ) );
|
||
}
|
||
|
||
// Return the cloned set
|
||
return clone;
|
||
},
|
||
|
||
cleanData: function( elems ) {
|
||
var data, elem, type,
|
||
special = jQuery.event.special,
|
||
i = 0;
|
||
|
||
for ( ; ( elem = elems[ i ] ) !== undefined; i++ ) {
|
||
if ( acceptData( elem ) ) {
|
||
if ( ( data = elem[ dataPriv.expando ] ) ) {
|
||
if ( data.events ) {
|
||
for ( type in data.events ) {
|
||
if ( special[ type ] ) {
|
||
jQuery.event.remove( elem, type );
|
||
|
||
// This is a shortcut to avoid jQuery.event.remove's overhead
|
||
} else {
|
||
jQuery.removeEvent( elem, type, data.handle );
|
||
}
|
||
}
|
||
}
|
||
|
||
// Support: Chrome <=35 - 45+
|
||
// Assign undefined instead of using delete, see Data#remove
|
||
elem[ dataPriv.expando ] = undefined;
|
||
}
|
||
if ( elem[ dataUser.expando ] ) {
|
||
|
||
// Support: Chrome <=35 - 45+
|
||
// Assign undefined instead of using delete, see Data#remove
|
||
elem[ dataUser.expando ] = undefined;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
} );
|
||
|
||
jQuery.fn.extend( {
|
||
detach: function( selector ) {
|
||
return remove( this, selector, true );
|
||
},
|
||
|
||
remove: function( selector ) {
|
||
return remove( this, selector );
|
||
},
|
||
|
||
text: function( value ) {
|
||
return access( this, function( value ) {
|
||
return value === undefined ?
|
||
jQuery.text( this ) :
|
||
this.empty().each( function() {
|
||
if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {
|
||
this.textContent = value;
|
||
}
|
||
} );
|
||
}, null, value, arguments.length );
|
||
},
|
||
|
||
append: function() {
|
||
return domManip( this, arguments, function( elem ) {
|
||
if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {
|
||
var target = manipulationTarget( this, elem );
|
||
target.appendChild( elem );
|
||
}
|
||
} );
|
||
},
|
||
|
||
prepend: function() {
|
||
return domManip( this, arguments, function( elem ) {
|
||
if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {
|
||
var target = manipulationTarget( this, elem );
|
||
target.insertBefore( elem, target.firstChild );
|
||
}
|
||
} );
|
||
},
|
||
|
||
before: function() {
|
||
return domManip( this, arguments, function( elem ) {
|
||
if ( this.parentNode ) {
|
||
this.parentNode.insertBefore( elem, this );
|
||
}
|
||
} );
|
||
},
|
||
|
||
after: function() {
|
||
return domManip( this, arguments, function( elem ) {
|
||
if ( this.parentNode ) {
|
||
this.parentNode.insertBefore( elem, this.nextSibling );
|
||
}
|
||
} );
|
||
},
|
||
|
||
empty: function() {
|
||
var elem,
|
||
i = 0;
|
||
|
||
for ( ; ( elem = this[ i ] ) != null; i++ ) {
|
||
if ( elem.nodeType === 1 ) {
|
||
|
||
// Prevent memory leaks
|
||
jQuery.cleanData( getAll( elem, false ) );
|
||
|
||
// Remove any remaining nodes
|
||
elem.textContent = "";
|
||
}
|
||
}
|
||
|
||
return this;
|
||
},
|
||
|
||
clone: function( dataAndEvents, deepDataAndEvents ) {
|
||
dataAndEvents = dataAndEvents == null ? false : dataAndEvents;
|
||
deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents;
|
||
|
||
return this.map( function() {
|
||
return jQuery.clone( this, dataAndEvents, deepDataAndEvents );
|
||
} );
|
||
},
|
||
|
||
html: function( value ) {
|
||
return access( this, function( value ) {
|
||
var elem = this[ 0 ] || {},
|
||
i = 0,
|
||
l = this.length;
|
||
|
||
if ( value === undefined && elem.nodeType === 1 ) {
|
||
return elem.innerHTML;
|
||
}
|
||
|
||
// See if we can take a shortcut and just use innerHTML
|
||
if ( typeof value === "string" && !rnoInnerhtml.test( value ) &&
|
||
!wrapMap[ ( rtagName.exec( value ) || [ "", "" ] )[ 1 ].toLowerCase() ] ) {
|
||
|
||
value = jQuery.htmlPrefilter( value );
|
||
|
||
try {
|
||
for ( ; i < l; i++ ) {
|
||
elem = this[ i ] || {};
|
||
|
||
// Remove element nodes and prevent memory leaks
|
||
if ( elem.nodeType === 1 ) {
|
||
jQuery.cleanData( getAll( elem, false ) );
|
||
elem.innerHTML = value;
|
||
}
|
||
}
|
||
|
||
elem = 0;
|
||
|
||
// If using innerHTML throws an exception, use the fallback method
|
||
} catch ( e ) {}
|
||
}
|
||
|
||
if ( elem ) {
|
||
this.empty().append( value );
|
||
}
|
||
}, null, value, arguments.length );
|
||
},
|
||
|
||
replaceWith: function() {
|
||
var ignored = [];
|
||
|
||
// Make the changes, replacing each non-ignored context element with the new content
|
||
return domManip( this, arguments, function( elem ) {
|
||
var parent = this.parentNode;
|
||
|
||
if ( jQuery.inArray( this, ignored ) < 0 ) {
|
||
jQuery.cleanData( getAll( this ) );
|
||
if ( parent ) {
|
||
parent.replaceChild( elem, this );
|
||
}
|
||
}
|
||
|
||
// Force callback invocation
|
||
}, ignored );
|
||
}
|
||
} );
|
||
|
||
jQuery.each( {
|
||
appendTo: "append",
|
||
prependTo: "prepend",
|
||
insertBefore: "before",
|
||
insertAfter: "after",
|
||
replaceAll: "replaceWith"
|
||
}, function( name, original ) {
|
||
jQuery.fn[ name ] = function( selector ) {
|
||
var elems,
|
||
ret = [],
|
||
insert = jQuery( selector ),
|
||
last = insert.length - 1,
|
||
i = 0;
|
||
|
||
for ( ; i <= last; i++ ) {
|
||
elems = i === last ? this : this.clone( true );
|
||
jQuery( insert[ i ] )[ original ]( elems );
|
||
|
||
// Support: Android <=4.0 only, PhantomJS 1 only
|
||
// .get() because push.apply(_, arraylike) throws on ancient WebKit
|
||
push.apply( ret, elems.get() );
|
||
}
|
||
|
||
return this.pushStack( ret );
|
||
};
|
||
} );
|
||
var rmargin = ( /^margin/ );
|
||
|
||
var rnumnonpx = new RegExp( "^(" + pnum + ")(?!px)[a-z%]+$", "i" );
|
||
|
||
var getStyles = function( elem ) {
|
||
|
||
// Support: IE <=11 only, Firefox <=30 (#15098, #14150)
|
||
// IE throws on elements created in popups
|
||
// FF meanwhile throws on frame elements through "defaultView.getComputedStyle"
|
||
var view = elem.ownerDocument.defaultView;
|
||
|
||
if ( !view || !view.opener ) {
|
||
view = window;
|
||
}
|
||
|
||
return view.getComputedStyle( elem );
|
||
};
|
||
|
||
|
||
|
||
( function() {
|
||
|
||
// Executing both pixelPosition & boxSizingReliable tests require only one layout
|
||
// so they're executed at the same time to save the second computation.
|
||
function computeStyleTests() {
|
||
|
||
// This is a singleton, we need to execute it only once
|
||
if ( !div ) {
|
||
return;
|
||
}
|
||
|
||
div.style.cssText =
|
||
"box-sizing:border-box;" +
|
||
"position:relative;display:block;" +
|
||
"margin:auto;border:1px;padding:1px;" +
|
||
"top:1%;width:50%";
|
||
div.innerHTML = "";
|
||
documentElement.appendChild( container );
|
||
|
||
var divStyle = window.getComputedStyle( div );
|
||
pixelPositionVal = divStyle.top !== "1%";
|
||
|
||
// Support: Android 4.0 - 4.3 only, Firefox <=3 - 44
|
||
reliableMarginLeftVal = divStyle.marginLeft === "2px";
|
||
boxSizingReliableVal = divStyle.width === "4px";
|
||
|
||
// Support: Android 4.0 - 4.3 only
|
||
// Some styles come back with percentage values, even though they shouldn't
|
||
div.style.marginRight = "50%";
|
||
pixelMarginRightVal = divStyle.marginRight === "4px";
|
||
|
||
documentElement.removeChild( container );
|
||
|
||
// Nullify the div so it wouldn't be stored in the memory and
|
||
// it will also be a sign that checks already performed
|
||
div = null;
|
||
}
|
||
|
||
var pixelPositionVal, boxSizingReliableVal, pixelMarginRightVal, reliableMarginLeftVal,
|
||
container = document.createElement( "div" ),
|
||
div = document.createElement( "div" );
|
||
|
||
// Finish early in limited (non-browser) environments
|
||
if ( !div.style ) {
|
||
return;
|
||
}
|
||
|
||
// Support: IE <=9 - 11 only
|
||
// Style of cloned element affects source element cloned (#8908)
|
||
div.style.backgroundClip = "content-box";
|
||
div.cloneNode( true ).style.backgroundClip = "";
|
||
support.clearCloneStyle = div.style.backgroundClip === "content-box";
|
||
|
||
container.style.cssText = "border:0;width:8px;height:0;top:0;left:-9999px;" +
|
||
"padding:0;margin-top:1px;position:absolute";
|
||
container.appendChild( div );
|
||
|
||
jQuery.extend( support, {
|
||
pixelPosition: function() {
|
||
computeStyleTests();
|
||
return pixelPositionVal;
|
||
},
|
||
boxSizingReliable: function() {
|
||
computeStyleTests();
|
||
return boxSizingReliableVal;
|
||
},
|
||
pixelMarginRight: function() {
|
||
computeStyleTests();
|
||
return pixelMarginRightVal;
|
||
},
|
||
reliableMarginLeft: function() {
|
||
computeStyleTests();
|
||
return reliableMarginLeftVal;
|
||
}
|
||
} );
|
||
} )();
|
||
|
||
|
||
function curCSS( elem, name, computed ) {
|
||
var width, minWidth, maxWidth, ret,
|
||
|
||
// Support: Firefox 51+
|
||
// Retrieving style before computed somehow
|
||
// fixes an issue with getting wrong values
|
||
// on detached elements
|
||
style = elem.style;
|
||
|
||
computed = computed || getStyles( elem );
|
||
|
||
// getPropertyValue is needed for:
|
||
// .css('filter') (IE 9 only, #12537)
|
||
// .css('--customProperty) (#3144)
|
||
if ( computed ) {
|
||
ret = computed.getPropertyValue( name ) || computed[ name ];
|
||
|
||
if ( ret === "" && !jQuery.contains( elem.ownerDocument, elem ) ) {
|
||
ret = jQuery.style( elem, name );
|
||
}
|
||
|
||
// A tribute to the "awesome hack by Dean Edwards"
|
||
// Android Browser returns percentage for some values,
|
||
// but width seems to be reliably pixels.
|
||
// This is against the CSSOM draft spec:
|
||
// https://drafts.csswg.org/cssom/#resolved-values
|
||
if ( !support.pixelMarginRight() && rnumnonpx.test( ret ) && rmargin.test( name ) ) {
|
||
|
||
// Remember the original values
|
||
width = style.width;
|
||
minWidth = style.minWidth;
|
||
maxWidth = style.maxWidth;
|
||
|
||
// Put in the new values to get a computed value out
|
||
style.minWidth = style.maxWidth = style.width = ret;
|
||
ret = computed.width;
|
||
|
||
// Revert the changed values
|
||
style.width = width;
|
||
style.minWidth = minWidth;
|
||
style.maxWidth = maxWidth;
|
||
}
|
||
}
|
||
|
||
return ret !== undefined ?
|
||
|
||
// Support: IE <=9 - 11 only
|
||
// IE returns zIndex value as an integer.
|
||
ret + "" :
|
||
ret;
|
||
}
|
||
|
||
|
||
function addGetHookIf( conditionFn, hookFn ) {
|
||
|
||
// Define the hook, we'll check on the first run if it's really needed.
|
||
return {
|
||
get: function() {
|
||
if ( conditionFn() ) {
|
||
|
||
// Hook not needed (or it's not possible to use it due
|
||
// to missing dependency), remove it.
|
||
delete this.get;
|
||
return;
|
||
}
|
||
|
||
// Hook needed; redefine it so that the support test is not executed again.
|
||
return ( this.get = hookFn ).apply( this, arguments );
|
||
}
|
||
};
|
||
}
|
||
|
||
|
||
var
|
||
|
||
// Swappable if display is none or starts with table
|
||
// except "table", "table-cell", or "table-caption"
|
||
// See here for display values: https://developer.mozilla.org/en-US/docs/CSS/display
|
||
rdisplayswap = /^(none|table(?!-c[ea]).+)/,
|
||
rcustomProp = /^--/,
|
||
cssShow = { position: "absolute", visibility: "hidden", display: "block" },
|
||
cssNormalTransform = {
|
||
letterSpacing: "0",
|
||
fontWeight: "400"
|
||
},
|
||
|
||
cssPrefixes = [ "Webkit", "Moz", "ms" ],
|
||
emptyStyle = document.createElement( "div" ).style;
|
||
|
||
// Return a css property mapped to a potentially vendor prefixed property
|
||
function vendorPropName( name ) {
|
||
|
||
// Shortcut for names that are not vendor prefixed
|
||
if ( name in emptyStyle ) {
|
||
return name;
|
||
}
|
||
|
||
// Check for vendor prefixed names
|
||
var capName = name[ 0 ].toUpperCase() + name.slice( 1 ),
|
||
i = cssPrefixes.length;
|
||
|
||
while ( i-- ) {
|
||
name = cssPrefixes[ i ] + capName;
|
||
if ( name in emptyStyle ) {
|
||
return name;
|
||
}
|
||
}
|
||
}
|
||
|
||
// Return a property mapped along what jQuery.cssProps suggests or to
|
||
// a vendor prefixed property.
|
||
function finalPropName( name ) {
|
||
var ret = jQuery.cssProps[ name ];
|
||
if ( !ret ) {
|
||
ret = jQuery.cssProps[ name ] = vendorPropName( name ) || name;
|
||
}
|
||
return ret;
|
||
}
|
||
|
||
function setPositiveNumber( elem, value, subtract ) {
|
||
|
||
// Any relative (+/-) values have already been
|
||
// normalized at this point
|
||
var matches = rcssNum.exec( value );
|
||
return matches ?
|
||
|
||
// Guard against undefined "subtract", e.g., when used as in cssHooks
|
||
Math.max( 0, matches[ 2 ] - ( subtract || 0 ) ) + ( matches[ 3 ] || "px" ) :
|
||
value;
|
||
}
|
||
|
||
function augmentWidthOrHeight( elem, name, extra, isBorderBox, styles ) {
|
||
var i,
|
||
val = 0;
|
||
|
||
// If we already have the right measurement, avoid augmentation
|
||
if ( extra === ( isBorderBox ? "border" : "content" ) ) {
|
||
i = 4;
|
||
|
||
// Otherwise initialize for horizontal or vertical properties
|
||
} else {
|
||
i = name === "width" ? 1 : 0;
|
||
}
|
||
|
||
for ( ; i < 4; i += 2 ) {
|
||
|
||
// Both box models exclude margin, so add it if we want it
|
||
if ( extra === "margin" ) {
|
||
val += jQuery.css( elem, extra + cssExpand[ i ], true, styles );
|
||
}
|
||
|
||
if ( isBorderBox ) {
|
||
|
||
// border-box includes padding, so remove it if we want content
|
||
if ( extra === "content" ) {
|
||
val -= jQuery.css( elem, "padding" + cssExpand[ i ], true, styles );
|
||
}
|
||
|
||
// At this point, extra isn't border nor margin, so remove border
|
||
if ( extra !== "margin" ) {
|
||
val -= jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles );
|
||
}
|
||
} else {
|
||
|
||
// At this point, extra isn't content, so add padding
|
||
val += jQuery.css( elem, "padding" + cssExpand[ i ], true, styles );
|
||
|
||
// At this point, extra isn't content nor padding, so add border
|
||
if ( extra !== "padding" ) {
|
||
val += jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles );
|
||
}
|
||
}
|
||
}
|
||
|
||
return val;
|
||
}
|
||
|
||
function getWidthOrHeight( elem, name, extra ) {
|
||
|
||
// Start with computed style
|
||
var valueIsBorderBox,
|
||
styles = getStyles( elem ),
|
||
val = curCSS( elem, name, styles ),
|
||
isBorderBox = jQuery.css( elem, "boxSizing", false, styles ) === "border-box";
|
||
|
||
// Computed unit is not pixels. Stop here and return.
|
||
if ( rnumnonpx.test( val ) ) {
|
||
return val;
|
||
}
|
||
|
||
// Check for style in case a browser which returns unreliable values
|
||
// for getComputedStyle silently falls back to the reliable elem.style
|
||
valueIsBorderBox = isBorderBox &&
|
||
( support.boxSizingReliable() || val === elem.style[ name ] );
|
||
|
||
// Fall back to offsetWidth/Height when value is "auto"
|
||
// This happens for inline elements with no explicit setting (gh-3571)
|
||
if ( val === "auto" ) {
|
||
val = elem[ "offset" + name[ 0 ].toUpperCase() + name.slice( 1 ) ];
|
||
}
|
||
|
||
// Normalize "", auto, and prepare for extra
|
||
val = parseFloat( val ) || 0;
|
||
|
||
// Use the active box-sizing model to add/subtract irrelevant styles
|
||
return ( val +
|
||
augmentWidthOrHeight(
|
||
elem,
|
||
name,
|
||
extra || ( isBorderBox ? "border" : "content" ),
|
||
valueIsBorderBox,
|
||
styles
|
||
)
|
||
) + "px";
|
||
}
|
||
|
||
jQuery.extend( {
|
||
|
||
// Add in style property hooks for overriding the default
|
||
// behavior of getting and setting a style property
|
||
cssHooks: {
|
||
opacity: {
|
||
get: function( elem, computed ) {
|
||
if ( computed ) {
|
||
|
||
// We should always get a number back from opacity
|
||
var ret = curCSS( elem, "opacity" );
|
||
return ret === "" ? "1" : ret;
|
||
}
|
||
}
|
||
}
|
||
},
|
||
|
||
// Don't automatically add "px" to these possibly-unitless properties
|
||
cssNumber: {
|
||
"animationIterationCount": true,
|
||
"columnCount": true,
|
||
"fillOpacity": true,
|
||
"flexGrow": true,
|
||
"flexShrink": true,
|
||
"fontWeight": true,
|
||
"lineHeight": true,
|
||
"opacity": true,
|
||
"order": true,
|
||
"orphans": true,
|
||
"widows": true,
|
||
"zIndex": true,
|
||
"zoom": true
|
||
},
|
||
|
||
// Add in properties whose names you wish to fix before
|
||
// setting or getting the value
|
||
cssProps: {
|
||
"float": "cssFloat"
|
||
},
|
||
|
||
// Get and set the style property on a DOM Node
|
||
style: function( elem, name, value, extra ) {
|
||
|
||
// Don't set styles on text and comment nodes
|
||
if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) {
|
||
return;
|
||
}
|
||
|
||
// Make sure that we're working with the right name
|
||
var ret, type, hooks,
|
||
origName = jQuery.camelCase( name ),
|
||
isCustomProp = rcustomProp.test( name ),
|
||
style = elem.style;
|
||
|
||
// Make sure that we're working with the right name. We don't
|
||
// want to query the value if it is a CSS custom property
|
||
// since they are user-defined.
|
||
if ( !isCustomProp ) {
|
||
name = finalPropName( origName );
|
||
}
|
||
|
||
// Gets hook for the prefixed version, then unprefixed version
|
||
hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];
|
||
|
||
// Check if we're setting a value
|
||
if ( value !== undefined ) {
|
||
type = typeof value;
|
||
|
||
// Convert "+=" or "-=" to relative numbers (#7345)
|
||
if ( type === "string" && ( ret = rcssNum.exec( value ) ) && ret[ 1 ] ) {
|
||
value = adjustCSS( elem, name, ret );
|
||
|
||
// Fixes bug #9237
|
||
type = "number";
|
||
}
|
||
|
||
// Make sure that null and NaN values aren't set (#7116)
|
||
if ( value == null || value !== value ) {
|
||
return;
|
||
}
|
||
|
||
// If a number was passed in, add the unit (except for certain CSS properties)
|
||
if ( type === "number" ) {
|
||
value += ret && ret[ 3 ] || ( jQuery.cssNumber[ origName ] ? "" : "px" );
|
||
}
|
||
|
||
// background-* props affect original clone's values
|
||
if ( !support.clearCloneStyle && value === "" && name.indexOf( "background" ) === 0 ) {
|
||
style[ name ] = "inherit";
|
||
}
|
||
|
||
// If a hook was provided, use that value, otherwise just set the specified value
|
||
if ( !hooks || !( "set" in hooks ) ||
|
||
( value = hooks.set( elem, value, extra ) ) !== undefined ) {
|
||
|
||
if ( isCustomProp ) {
|
||
style.setProperty( name, value );
|
||
} else {
|
||
style[ name ] = value;
|
||
}
|
||
}
|
||
|
||
} else {
|
||
|
||
// If a hook was provided get the non-computed value from there
|
||
if ( hooks && "get" in hooks &&
|
||
( ret = hooks.get( elem, false, extra ) ) !== undefined ) {
|
||
|
||
return ret;
|
||
}
|
||
|
||
// Otherwise just get the value from the style object
|
||
return style[ name ];
|
||
}
|
||
},
|
||
|
||
css: function( elem, name, extra, styles ) {
|
||
var val, num, hooks,
|
||
origName = jQuery.camelCase( name ),
|
||
isCustomProp = rcustomProp.test( name );
|
||
|
||
// Make sure that we're working with the right name. We don't
|
||
// want to modify the value if it is a CSS custom property
|
||
// since they are user-defined.
|
||
if ( !isCustomProp ) {
|
||
name = finalPropName( origName );
|
||
}
|
||
|
||
// Try prefixed name followed by the unprefixed name
|
||
hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];
|
||
|
||
// If a hook was provided get the computed value from there
|
||
if ( hooks && "get" in hooks ) {
|
||
val = hooks.get( elem, true, extra );
|
||
}
|
||
|
||
// Otherwise, if a way to get the computed value exists, use that
|
||
if ( val === undefined ) {
|
||
val = curCSS( elem, name, styles );
|
||
}
|
||
|
||
// Convert "normal" to computed value
|
||
if ( val === "normal" && name in cssNormalTransform ) {
|
||
val = cssNormalTransform[ name ];
|
||
}
|
||
|
||
// Make numeric if forced or a qualifier was provided and val looks numeric
|
||
if ( extra === "" || extra ) {
|
||
num = parseFloat( val );
|
||
return extra === true || isFinite( num ) ? num || 0 : val;
|
||
}
|
||
|
||
return val;
|
||
}
|
||
} );
|
||
|
||
jQuery.each( [ "height", "width" ], function( i, name ) {
|
||
jQuery.cssHooks[ name ] = {
|
||
get: function( elem, computed, extra ) {
|
||
if ( computed ) {
|
||
|
||
// Certain elements can have dimension info if we invisibly show them
|
||
// but it must have a current display style that would benefit
|
||
return rdisplayswap.test( jQuery.css( elem, "display" ) ) &&
|
||
|
||
// Support: Safari 8+
|
||
// Table columns in Safari have non-zero offsetWidth & zero
|
||
// getBoundingClientRect().width unless display is changed.
|
||
// Support: IE <=11 only
|
||
// Running getBoundingClientRect on a disconnected node
|
||
// in IE throws an error.
|
||
( !elem.getClientRects().length || !elem.getBoundingClientRect().width ) ?
|
||
swap( elem, cssShow, function() {
|
||
return getWidthOrHeight( elem, name, extra );
|
||
} ) :
|
||
getWidthOrHeight( elem, name, extra );
|
||
}
|
||
},
|
||
|
||
set: function( elem, value, extra ) {
|
||
var matches,
|
||
styles = extra && getStyles( elem ),
|
||
subtract = extra && augmentWidthOrHeight(
|
||
elem,
|
||
name,
|
||
extra,
|
||
jQuery.css( elem, "boxSizing", false, styles ) === "border-box",
|
||
styles
|
||
);
|
||
|
||
// Convert to pixels if value adjustment is needed
|
||
if ( subtract && ( matches = rcssNum.exec( value ) ) &&
|
||
( matches[ 3 ] || "px" ) !== "px" ) {
|
||
|
||
elem.style[ name ] = value;
|
||
value = jQuery.css( elem, name );
|
||
}
|
||
|
||
return setPositiveNumber( elem, value, subtract );
|
||
}
|
||
};
|
||
} );
|
||
|
||
jQuery.cssHooks.marginLeft = addGetHookIf( support.reliableMarginLeft,
|
||
function( elem, computed ) {
|
||
if ( computed ) {
|
||
return ( parseFloat( curCSS( elem, "marginLeft" ) ) ||
|
||
elem.getBoundingClientRect().left -
|
||
swap( elem, { marginLeft: 0 }, function() {
|
||
return elem.getBoundingClientRect().left;
|
||
} )
|
||
) + "px";
|
||
}
|
||
}
|
||
);
|
||
|
||
// These hooks are used by animate to expand properties
|
||
jQuery.each( {
|
||
margin: "",
|
||
padding: "",
|
||
border: "Width"
|
||
}, function( prefix, suffix ) {
|
||
jQuery.cssHooks[ prefix + suffix ] = {
|
||
expand: function( value ) {
|
||
var i = 0,
|
||
expanded = {},
|
||
|
||
// Assumes a single number if not a string
|
||
parts = typeof value === "string" ? value.split( " " ) : [ value ];
|
||
|
||
for ( ; i < 4; i++ ) {
|
||
expanded[ prefix + cssExpand[ i ] + suffix ] =
|
||
parts[ i ] || parts[ i - 2 ] || parts[ 0 ];
|
||
}
|
||
|
||
return expanded;
|
||
}
|
||
};
|
||
|
||
if ( !rmargin.test( prefix ) ) {
|
||
jQuery.cssHooks[ prefix + suffix ].set = setPositiveNumber;
|
||
}
|
||
} );
|
||
|
||
jQuery.fn.extend( {
|
||
css: function( name, value ) {
|
||
return access( this, function( elem, name, value ) {
|
||
var styles, len,
|
||
map = {},
|
||
i = 0;
|
||
|
||
if ( Array.isArray( name ) ) {
|
||
styles = getStyles( elem );
|
||
len = name.length;
|
||
|
||
for ( ; i < len; i++ ) {
|
||
map[ name[ i ] ] = jQuery.css( elem, name[ i ], false, styles );
|
||
}
|
||
|
||
return map;
|
||
}
|
||
|
||
return value !== undefined ?
|
||
jQuery.style( elem, name, value ) :
|
||
jQuery.css( elem, name );
|
||
}, name, value, arguments.length > 1 );
|
||
}
|
||
} );
|
||
|
||
|
||
function Tween( elem, options, prop, end, easing ) {
|
||
return new Tween.prototype.init( elem, options, prop, end, easing );
|
||
}
|
||
jQuery.Tween = Tween;
|
||
|
||
Tween.prototype = {
|
||
constructor: Tween,
|
||
init: function( elem, options, prop, end, easing, unit ) {
|
||
this.elem = elem;
|
||
this.prop = prop;
|
||
this.easing = easing || jQuery.easing._default;
|
||
this.options = options;
|
||
this.start = this.now = this.cur();
|
||
this.end = end;
|
||
this.unit = unit || ( jQuery.cssNumber[ prop ] ? "" : "px" );
|
||
},
|
||
cur: function() {
|
||
var hooks = Tween.propHooks[ this.prop ];
|
||
|
||
return hooks && hooks.get ?
|
||
hooks.get( this ) :
|
||
Tween.propHooks._default.get( this );
|
||
},
|
||
run: function( percent ) {
|
||
var eased,
|
||
hooks = Tween.propHooks[ this.prop ];
|
||
|
||
if ( this.options.duration ) {
|
||
this.pos = eased = jQuery.easing[ this.easing ](
|
||
percent, this.options.duration * percent, 0, 1, this.options.duration
|
||
);
|
||
} else {
|
||
this.pos = eased = percent;
|
||
}
|
||
this.now = ( this.end - this.start ) * eased + this.start;
|
||
|
||
if ( this.options.step ) {
|
||
this.options.step.call( this.elem, this.now, this );
|
||
}
|
||
|
||
if ( hooks && hooks.set ) {
|
||
hooks.set( this );
|
||
} else {
|
||
Tween.propHooks._default.set( this );
|
||
}
|
||
return this;
|
||
}
|
||
};
|
||
|
||
Tween.prototype.init.prototype = Tween.prototype;
|
||
|
||
Tween.propHooks = {
|
||
_default: {
|
||
get: function( tween ) {
|
||
var result;
|
||
|
||
// Use a property on the element directly when it is not a DOM element,
|
||
// or when there is no matching style property that exists.
|
||
if ( tween.elem.nodeType !== 1 ||
|
||
tween.elem[ tween.prop ] != null && tween.elem.style[ tween.prop ] == null ) {
|
||
return tween.elem[ tween.prop ];
|
||
}
|
||
|
||
// Passing an empty string as a 3rd parameter to .css will automatically
|
||
// attempt a parseFloat and fallback to a string if the parse fails.
|
||
// Simple values such as "10px" are parsed to Float;
|
||
// complex values such as "rotate(1rad)" are returned as-is.
|
||
result = jQuery.css( tween.elem, tween.prop, "" );
|
||
|
||
// Empty strings, null, undefined and "auto" are converted to 0.
|
||
return !result || result === "auto" ? 0 : result;
|
||
},
|
||
set: function( tween ) {
|
||
|
||
// Use step hook for back compat.
|
||
// Use cssHook if its there.
|
||
// Use .style if available and use plain properties where available.
|
||
if ( jQuery.fx.step[ tween.prop ] ) {
|
||
jQuery.fx.step[ tween.prop ]( tween );
|
||
} else if ( tween.elem.nodeType === 1 &&
|
||
( tween.elem.style[ jQuery.cssProps[ tween.prop ] ] != null ||
|
||
jQuery.cssHooks[ tween.prop ] ) ) {
|
||
jQuery.style( tween.elem, tween.prop, tween.now + tween.unit );
|
||
} else {
|
||
tween.elem[ tween.prop ] = tween.now;
|
||
}
|
||
}
|
||
}
|
||
};
|
||
|
||
// Support: IE <=9 only
|
||
// Panic based approach to setting things on disconnected nodes
|
||
Tween.propHooks.scrollTop = Tween.propHooks.scrollLeft = {
|
||
set: function( tween ) {
|
||
if ( tween.elem.nodeType && tween.elem.parentNode ) {
|
||
tween.elem[ tween.prop ] = tween.now;
|
||
}
|
||
}
|
||
};
|
||
|
||
jQuery.easing = {
|
||
linear: function( p ) {
|
||
return p;
|
||
},
|
||
swing: function( p ) {
|
||
return 0.5 - Math.cos( p * Math.PI ) / 2;
|
||
},
|
||
_default: "swing"
|
||
};
|
||
|
||
jQuery.fx = Tween.prototype.init;
|
||
|
||
// Back compat <1.8 extension point
|
||
jQuery.fx.step = {};
|
||
|
||
|
||
|
||
|
||
var
|
||
fxNow, inProgress,
|
||
rfxtypes = /^(?:toggle|show|hide)$/,
|
||
rrun = /queueHooks$/;
|
||
|
||
function schedule() {
|
||
if ( inProgress ) {
|
||
if ( document.hidden === false && window.requestAnimationFrame ) {
|
||
window.requestAnimationFrame( schedule );
|
||
} else {
|
||
window.setTimeout( schedule, jQuery.fx.interval );
|
||
}
|
||
|
||
jQuery.fx.tick();
|
||
}
|
||
}
|
||
|
||
// Animations created synchronously will run synchronously
|
||
function createFxNow() {
|
||
window.setTimeout( function() {
|
||
fxNow = undefined;
|
||
} );
|
||
return ( fxNow = jQuery.now() );
|
||
}
|
||
|
||
// Generate parameters to create a standard animation
|
||
function genFx( type, includeWidth ) {
|
||
var which,
|
||
i = 0,
|
||
attrs = { height: type };
|
||
|
||
// If we include width, step value is 1 to do all cssExpand values,
|
||
// otherwise step value is 2 to skip over Left and Right
|
||
includeWidth = includeWidth ? 1 : 0;
|
||
for ( ; i < 4; i += 2 - includeWidth ) {
|
||
which = cssExpand[ i ];
|
||
attrs[ "margin" + which ] = attrs[ "padding" + which ] = type;
|
||
}
|
||
|
||
if ( includeWidth ) {
|
||
attrs.opacity = attrs.width = type;
|
||
}
|
||
|
||
return attrs;
|
||
}
|
||
|
||
function createTween( value, prop, animation ) {
|
||
var tween,
|
||
collection = ( Animation.tweeners[ prop ] || [] ).concat( Animation.tweeners[ "*" ] ),
|
||
index = 0,
|
||
length = collection.length;
|
||
for ( ; index < length; index++ ) {
|
||
if ( ( tween = collection[ index ].call( animation, prop, value ) ) ) {
|
||
|
||
// We're done with this property
|
||
return tween;
|
||
}
|
||
}
|
||
}
|
||
|
||
function defaultPrefilter( elem, props, opts ) {
|
||
var prop, value, toggle, hooks, oldfire, propTween, restoreDisplay, display,
|
||
isBox = "width" in props || "height" in props,
|
||
anim = this,
|
||
orig = {},
|
||
style = elem.style,
|
||
hidden = elem.nodeType && isHiddenWithinTree( elem ),
|
||
dataShow = dataPriv.get( elem, "fxshow" );
|
||
|
||
// Queue-skipping animations hijack the fx hooks
|
||
if ( !opts.queue ) {
|
||
hooks = jQuery._queueHooks( elem, "fx" );
|
||
if ( hooks.unqueued == null ) {
|
||
hooks.unqueued = 0;
|
||
oldfire = hooks.empty.fire;
|
||
hooks.empty.fire = function() {
|
||
if ( !hooks.unqueued ) {
|
||
oldfire();
|
||
}
|
||
};
|
||
}
|
||
hooks.unqueued++;
|
||
|
||
anim.always( function() {
|
||
|
||
// Ensure the complete handler is called before this completes
|
||
anim.always( function() {
|
||
hooks.unqueued--;
|
||
if ( !jQuery.queue( elem, "fx" ).length ) {
|
||
hooks.empty.fire();
|
||
}
|
||
} );
|
||
} );
|
||
}
|
||
|
||
// Detect show/hide animations
|
||
for ( prop in props ) {
|
||
value = props[ prop ];
|
||
if ( rfxtypes.test( value ) ) {
|
||
delete props[ prop ];
|
||
toggle = toggle || value === "toggle";
|
||
if ( value === ( hidden ? "hide" : "show" ) ) {
|
||
|
||
// Pretend to be hidden if this is a "show" and
|
||
// there is still data from a stopped show/hide
|
||
if ( value === "show" && dataShow && dataShow[ prop ] !== undefined ) {
|
||
hidden = true;
|
||
|
||
// Ignore all other no-op show/hide data
|
||
} else {
|
||
continue;
|
||
}
|
||
}
|
||
orig[ prop ] = dataShow && dataShow[ prop ] || jQuery.style( elem, prop );
|
||
}
|
||
}
|
||
|
||
// Bail out if this is a no-op like .hide().hide()
|
||
propTween = !jQuery.isEmptyObject( props );
|
||
if ( !propTween && jQuery.isEmptyObject( orig ) ) {
|
||
return;
|
||
}
|
||
|
||
// Restrict "overflow" and "display" styles during box animations
|
||
if ( isBox && elem.nodeType === 1 ) {
|
||
|
||
// Support: IE <=9 - 11, Edge 12 - 13
|
||
// Record all 3 overflow attributes because IE does not infer the shorthand
|
||
// from identically-valued overflowX and overflowY
|
||
opts.overflow = [ style.overflow, style.overflowX, style.overflowY ];
|
||
|
||
// Identify a display type, preferring old show/hide data over the CSS cascade
|
||
restoreDisplay = dataShow && dataShow.display;
|
||
if ( restoreDisplay == null ) {
|
||
restoreDisplay = dataPriv.get( elem, "display" );
|
||
}
|
||
display = jQuery.css( elem, "display" );
|
||
if ( display === "none" ) {
|
||
if ( restoreDisplay ) {
|
||
display = restoreDisplay;
|
||
} else {
|
||
|
||
// Get nonempty value(s) by temporarily forcing visibility
|
||
showHide( [ elem ], true );
|
||
restoreDisplay = elem.style.display || restoreDisplay;
|
||
display = jQuery.css( elem, "display" );
|
||
showHide( [ elem ] );
|
||
}
|
||
}
|
||
|
||
// Animate inline elements as inline-block
|
||
if ( display === "inline" || display === "inline-block" && restoreDisplay != null ) {
|
||
if ( jQuery.css( elem, "float" ) === "none" ) {
|
||
|
||
// Restore the original display value at the end of pure show/hide animations
|
||
if ( !propTween ) {
|
||
anim.done( function() {
|
||
style.display = restoreDisplay;
|
||
} );
|
||
if ( restoreDisplay == null ) {
|
||
display = style.display;
|
||
restoreDisplay = display === "none" ? "" : display;
|
||
}
|
||
}
|
||
style.display = "inline-block";
|
||
}
|
||
}
|
||
}
|
||
|
||
if ( opts.overflow ) {
|
||
style.overflow = "hidden";
|
||
anim.always( function() {
|
||
style.overflow = opts.overflow[ 0 ];
|
||
style.overflowX = opts.overflow[ 1 ];
|
||
style.overflowY = opts.overflow[ 2 ];
|
||
} );
|
||
}
|
||
|
||
// Implement show/hide animations
|
||
propTween = false;
|
||
for ( prop in orig ) {
|
||
|
||
// General show/hide setup for this element animation
|
||
if ( !propTween ) {
|
||
if ( dataShow ) {
|
||
if ( "hidden" in dataShow ) {
|
||
hidden = dataShow.hidden;
|
||
}
|
||
} else {
|
||
dataShow = dataPriv.access( elem, "fxshow", { display: restoreDisplay } );
|
||
}
|
||
|
||
// Store hidden/visible for toggle so `.stop().toggle()` "reverses"
|
||
if ( toggle ) {
|
||
dataShow.hidden = !hidden;
|
||
}
|
||
|
||
// Show elements before animating them
|
||
if ( hidden ) {
|
||
showHide( [ elem ], true );
|
||
}
|
||
|
||
/* eslint-disable no-loop-func */
|
||
|
||
anim.done( function() {
|
||
|
||
/* eslint-enable no-loop-func */
|
||
|
||
// The final step of a "hide" animation is actually hiding the element
|
||
if ( !hidden ) {
|
||
showHide( [ elem ] );
|
||
}
|
||
dataPriv.remove( elem, "fxshow" );
|
||
for ( prop in orig ) {
|
||
jQuery.style( elem, prop, orig[ prop ] );
|
||
}
|
||
} );
|
||
}
|
||
|
||
// Per-property setup
|
||
propTween = createTween( hidden ? dataShow[ prop ] : 0, prop, anim );
|
||
if ( !( prop in dataShow ) ) {
|
||
dataShow[ prop ] = propTween.start;
|
||
if ( hidden ) {
|
||
propTween.end = propTween.start;
|
||
propTween.start = 0;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
function propFilter( props, specialEasing ) {
|
||
var index, name, easing, value, hooks;
|
||
|
||
// camelCase, specialEasing and expand cssHook pass
|
||
for ( index in props ) {
|
||
name = jQuery.camelCase( index );
|
||
easing = specialEasing[ name ];
|
||
value = props[ index ];
|
||
if ( Array.isArray( value ) ) {
|
||
easing = value[ 1 ];
|
||
value = props[ index ] = value[ 0 ];
|
||
}
|
||
|
||
if ( index !== name ) {
|
||
props[ name ] = value;
|
||
delete props[ index ];
|
||
}
|
||
|
||
hooks = jQuery.cssHooks[ name ];
|
||
if ( hooks && "expand" in hooks ) {
|
||
value = hooks.expand( value );
|
||
delete props[ name ];
|
||
|
||
// Not quite $.extend, this won't overwrite existing keys.
|
||
// Reusing 'index' because we have the correct "name"
|
||
for ( index in value ) {
|
||
if ( !( index in props ) ) {
|
||
props[ index ] = value[ index ];
|
||
specialEasing[ index ] = easing;
|
||
}
|
||
}
|
||
} else {
|
||
specialEasing[ name ] = easing;
|
||
}
|
||
}
|
||
}
|
||
|
||
function Animation( elem, properties, options ) {
|
||
var result,
|
||
stopped,
|
||
index = 0,
|
||
length = Animation.prefilters.length,
|
||
deferred = jQuery.Deferred().always( function() {
|
||
|
||
// Don't match elem in the :animated selector
|
||
delete tick.elem;
|
||
} ),
|
||
tick = function() {
|
||
if ( stopped ) {
|
||
return false;
|
||
}
|
||
var currentTime = fxNow || createFxNow(),
|
||
remaining = Math.max( 0, animation.startTime + animation.duration - currentTime ),
|
||
|
||
// Support: Android 2.3 only
|
||
// Archaic crash bug won't allow us to use `1 - ( 0.5 || 0 )` (#12497)
|
||
temp = remaining / animation.duration || 0,
|
||
percent = 1 - temp,
|
||
index = 0,
|
||
length = animation.tweens.length;
|
||
|
||
for ( ; index < length; index++ ) {
|
||
animation.tweens[ index ].run( percent );
|
||
}
|
||
|
||
deferred.notifyWith( elem, [ animation, percent, remaining ] );
|
||
|
||
// If there's more to do, yield
|
||
if ( percent < 1 && length ) {
|
||
return remaining;
|
||
}
|
||
|
||
// If this was an empty animation, synthesize a final progress notification
|
||
if ( !length ) {
|
||
deferred.notifyWith( elem, [ animation, 1, 0 ] );
|
||
}
|
||
|
||
// Resolve the animation and report its conclusion
|
||
deferred.resolveWith( elem, [ animation ] );
|
||
return false;
|
||
},
|
||
animation = deferred.promise( {
|
||
elem: elem,
|
||
props: jQuery.extend( {}, properties ),
|
||
opts: jQuery.extend( true, {
|
||
specialEasing: {},
|
||
easing: jQuery.easing._default
|
||
}, options ),
|
||
originalProperties: properties,
|
||
originalOptions: options,
|
||
startTime: fxNow || createFxNow(),
|
||
duration: options.duration,
|
||
tweens: [],
|
||
createTween: function( prop, end ) {
|
||
var tween = jQuery.Tween( elem, animation.opts, prop, end,
|
||
animation.opts.specialEasing[ prop ] || animation.opts.easing );
|
||
animation.tweens.push( tween );
|
||
return tween;
|
||
},
|
||
stop: function( gotoEnd ) {
|
||
var index = 0,
|
||
|
||
// If we are going to the end, we want to run all the tweens
|
||
// otherwise we skip this part
|
||
length = gotoEnd ? animation.tweens.length : 0;
|
||
if ( stopped ) {
|
||
return this;
|
||
}
|
||
stopped = true;
|
||
for ( ; index < length; index++ ) {
|
||
animation.tweens[ index ].run( 1 );
|
||
}
|
||
|
||
// Resolve when we played the last frame; otherwise, reject
|
||
if ( gotoEnd ) {
|
||
deferred.notifyWith( elem, [ animation, 1, 0 ] );
|
||
deferred.resolveWith( elem, [ animation, gotoEnd ] );
|
||
} else {
|
||
deferred.rejectWith( elem, [ animation, gotoEnd ] );
|
||
}
|
||
return this;
|
||
}
|
||
} ),
|
||
props = animation.props;
|
||
|
||
propFilter( props, animation.opts.specialEasing );
|
||
|
||
for ( ; index < length; index++ ) {
|
||
result = Animation.prefilters[ index ].call( animation, elem, props, animation.opts );
|
||
if ( result ) {
|
||
if ( jQuery.isFunction( result.stop ) ) {
|
||
jQuery._queueHooks( animation.elem, animation.opts.queue ).stop =
|
||
jQuery.proxy( result.stop, result );
|
||
}
|
||
return result;
|
||
}
|
||
}
|
||
|
||
jQuery.map( props, createTween, animation );
|
||
|
||
if ( jQuery.isFunction( animation.opts.start ) ) {
|
||
animation.opts.start.call( elem, animation );
|
||
}
|
||
|
||
// Attach callbacks from options
|
||
animation
|
||
.progress( animation.opts.progress )
|
||
.done( animation.opts.done, animation.opts.complete )
|
||
.fail( animation.opts.fail )
|
||
.always( animation.opts.always );
|
||
|
||
jQuery.fx.timer(
|
||
jQuery.extend( tick, {
|
||
elem: elem,
|
||
anim: animation,
|
||
queue: animation.opts.queue
|
||
} )
|
||
);
|
||
|
||
return animation;
|
||
}
|
||
|
||
jQuery.Animation = jQuery.extend( Animation, {
|
||
|
||
tweeners: {
|
||
"*": [ function( prop, value ) {
|
||
var tween = this.createTween( prop, value );
|
||
adjustCSS( tween.elem, prop, rcssNum.exec( value ), tween );
|
||
return tween;
|
||
} ]
|
||
},
|
||
|
||
tweener: function( props, callback ) {
|
||
if ( jQuery.isFunction( props ) ) {
|
||
callback = props;
|
||
props = [ "*" ];
|
||
} else {
|
||
props = props.match( rnothtmlwhite );
|
||
}
|
||
|
||
var prop,
|
||
index = 0,
|
||
length = props.length;
|
||
|
||
for ( ; index < length; index++ ) {
|
||
prop = props[ index ];
|
||
Animation.tweeners[ prop ] = Animation.tweeners[ prop ] || [];
|
||
Animation.tweeners[ prop ].unshift( callback );
|
||
}
|
||
},
|
||
|
||
prefilters: [ defaultPrefilter ],
|
||
|
||
prefilter: function( callback, prepend ) {
|
||
if ( prepend ) {
|
||
Animation.prefilters.unshift( callback );
|
||
} else {
|
||
Animation.prefilters.push( callback );
|
||
}
|
||
}
|
||
} );
|
||
|
||
jQuery.speed = function( speed, easing, fn ) {
|
||
var opt = speed && typeof speed === "object" ? jQuery.extend( {}, speed ) : {
|
||
complete: fn || !fn && easing ||
|
||
jQuery.isFunction( speed ) && speed,
|
||
duration: speed,
|
||
easing: fn && easing || easing && !jQuery.isFunction( easing ) && easing
|
||
};
|
||
|
||
// Go to the end state if fx are off
|
||
if ( jQuery.fx.off ) {
|
||
opt.duration = 0;
|
||
|
||
} else {
|
||
if ( typeof opt.duration !== "number" ) {
|
||
if ( opt.duration in jQuery.fx.speeds ) {
|
||
opt.duration = jQuery.fx.speeds[ opt.duration ];
|
||
|
||
} else {
|
||
opt.duration = jQuery.fx.speeds._default;
|
||
}
|
||
}
|
||
}
|
||
|
||
// Normalize opt.queue - true/undefined/null -> "fx"
|
||
if ( opt.queue == null || opt.queue === true ) {
|
||
opt.queue = "fx";
|
||
}
|
||
|
||
// Queueing
|
||
opt.old = opt.complete;
|
||
|
||
opt.complete = function() {
|
||
if ( jQuery.isFunction( opt.old ) ) {
|
||
opt.old.call( this );
|
||
}
|
||
|
||
if ( opt.queue ) {
|
||
jQuery.dequeue( this, opt.queue );
|
||
}
|
||
};
|
||
|
||
return opt;
|
||
};
|
||
|
||
jQuery.fn.extend( {
|
||
fadeTo: function( speed, to, easing, callback ) {
|
||
|
||
// Show any hidden elements after setting opacity to 0
|
||
return this.filter( isHiddenWithinTree ).css( "opacity", 0 ).show()
|
||
|
||
// Animate to the value specified
|
||
.end().animate( { opacity: to }, speed, easing, callback );
|
||
},
|
||
animate: function( prop, speed, easing, callback ) {
|
||
var empty = jQuery.isEmptyObject( prop ),
|
||
optall = jQuery.speed( speed, easing, callback ),
|
||
doAnimation = function() {
|
||
|
||
// Operate on a copy of prop so per-property easing won't be lost
|
||
var anim = Animation( this, jQuery.extend( {}, prop ), optall );
|
||
|
||
// Empty animations, or finishing resolves immediately
|
||
if ( empty || dataPriv.get( this, "finish" ) ) {
|
||
anim.stop( true );
|
||
}
|
||
};
|
||
doAnimation.finish = doAnimation;
|
||
|
||
return empty || optall.queue === false ?
|
||
this.each( doAnimation ) :
|
||
this.queue( optall.queue, doAnimation );
|
||
},
|
||
stop: function( type, clearQueue, gotoEnd ) {
|
||
var stopQueue = function( hooks ) {
|
||
var stop = hooks.stop;
|
||
delete hooks.stop;
|
||
stop( gotoEnd );
|
||
};
|
||
|
||
if ( typeof type !== "string" ) {
|
||
gotoEnd = clearQueue;
|
||
clearQueue = type;
|
||
type = undefined;
|
||
}
|
||
if ( clearQueue && type !== false ) {
|
||
this.queue( type || "fx", [] );
|
||
}
|
||
|
||
return this.each( function() {
|
||
var dequeue = true,
|
||
index = type != null && type + "queueHooks",
|
||
timers = jQuery.timers,
|
||
data = dataPriv.get( this );
|
||
|
||
if ( index ) {
|
||
if ( data[ index ] && data[ index ].stop ) {
|
||
stopQueue( data[ index ] );
|
||
}
|
||
} else {
|
||
for ( index in data ) {
|
||
if ( data[ index ] && data[ index ].stop && rrun.test( index ) ) {
|
||
stopQueue( data[ index ] );
|
||
}
|
||
}
|
||
}
|
||
|
||
for ( index = timers.length; index--; ) {
|
||
if ( timers[ index ].elem === this &&
|
||
( type == null || timers[ index ].queue === type ) ) {
|
||
|
||
timers[ index ].anim.stop( gotoEnd );
|
||
dequeue = false;
|
||
timers.splice( index, 1 );
|
||
}
|
||
}
|
||
|
||
// Start the next in the queue if the last step wasn't forced.
|
||
// Timers currently will call their complete callbacks, which
|
||
// will dequeue but only if they were gotoEnd.
|
||
if ( dequeue || !gotoEnd ) {
|
||
jQuery.dequeue( this, type );
|
||
}
|
||
} );
|
||
},
|
||
finish: function( type ) {
|
||
if ( type !== false ) {
|
||
type = type || "fx";
|
||
}
|
||
return this.each( function() {
|
||
var index,
|
||
data = dataPriv.get( this ),
|
||
queue = data[ type + "queue" ],
|
||
hooks = data[ type + "queueHooks" ],
|
||
timers = jQuery.timers,
|
||
length = queue ? queue.length : 0;
|
||
|
||
// Enable finishing flag on private data
|
||
data.finish = true;
|
||
|
||
// Empty the queue first
|
||
jQuery.queue( this, type, [] );
|
||
|
||
if ( hooks && hooks.stop ) {
|
||
hooks.stop.call( this, true );
|
||
}
|
||
|
||
// Look for any active animations, and finish them
|
||
for ( index = timers.length; index--; ) {
|
||
if ( timers[ index ].elem === this && timers[ index ].queue === type ) {
|
||
timers[ index ].anim.stop( true );
|
||
timers.splice( index, 1 );
|
||
}
|
||
}
|
||
|
||
// Look for any animations in the old queue and finish them
|
||
for ( index = 0; index < length; index++ ) {
|
||
if ( queue[ index ] && queue[ index ].finish ) {
|
||
queue[ index ].finish.call( this );
|
||
}
|
||
}
|
||
|
||
// Turn off finishing flag
|
||
delete data.finish;
|
||
} );
|
||
}
|
||
} );
|
||
|
||
jQuery.each( [ "toggle", "show", "hide" ], function( i, name ) {
|
||
var cssFn = jQuery.fn[ name ];
|
||
jQuery.fn[ name ] = function( speed, easing, callback ) {
|
||
return speed == null || typeof speed === "boolean" ?
|
||
cssFn.apply( this, arguments ) :
|
||
this.animate( genFx( name, true ), speed, easing, callback );
|
||
};
|
||
} );
|
||
|
||
// Generate shortcuts for custom animations
|
||
jQuery.each( {
|
||
slideDown: genFx( "show" ),
|
||
slideUp: genFx( "hide" ),
|
||
slideToggle: genFx( "toggle" ),
|
||
fadeIn: { opacity: "show" },
|
||
fadeOut: { opacity: "hide" },
|
||
fadeToggle: { opacity: "toggle" }
|
||
}, function( name, props ) {
|
||
jQuery.fn[ name ] = function( speed, easing, callback ) {
|
||
return this.animate( props, speed, easing, callback );
|
||
};
|
||
} );
|
||
|
||
jQuery.timers = [];
|
||
jQuery.fx.tick = function() {
|
||
var timer,
|
||
i = 0,
|
||
timers = jQuery.timers;
|
||
|
||
fxNow = jQuery.now();
|
||
|
||
for ( ; i < timers.length; i++ ) {
|
||
timer = timers[ i ];
|
||
|
||
// Run the timer and safely remove it when done (allowing for external removal)
|
||
if ( !timer() && timers[ i ] === timer ) {
|
||
timers.splice( i--, 1 );
|
||
}
|
||
}
|
||
|
||
if ( !timers.length ) {
|
||
jQuery.fx.stop();
|
||
}
|
||
fxNow = undefined;
|
||
};
|
||
|
||
jQuery.fx.timer = function( timer ) {
|
||
jQuery.timers.push( timer );
|
||
jQuery.fx.start();
|
||
};
|
||
|
||
jQuery.fx.interval = 13;
|
||
jQuery.fx.start = function() {
|
||
if ( inProgress ) {
|
||
return;
|
||
}
|
||
|
||
inProgress = true;
|
||
schedule();
|
||
};
|
||
|
||
jQuery.fx.stop = function() {
|
||
inProgress = null;
|
||
};
|
||
|
||
jQuery.fx.speeds = {
|
||
slow: 600,
|
||
fast: 200,
|
||
|
||
// Default speed
|
||
_default: 400
|
||
};
|
||
|
||
|
||
// Based off of the plugin by Clint Helfers, with permission.
|
||
// https://web.archive.org/web/20100324014747/http://blindsignals.com/index.php/2009/07/jquery-delay/
|
||
jQuery.fn.delay = function( time, type ) {
|
||
time = jQuery.fx ? jQuery.fx.speeds[ time ] || time : time;
|
||
type = type || "fx";
|
||
|
||
return this.queue( type, function( next, hooks ) {
|
||
var timeout = window.setTimeout( next, time );
|
||
hooks.stop = function() {
|
||
window.clearTimeout( timeout );
|
||
};
|
||
} );
|
||
};
|
||
|
||
|
||
( function() {
|
||
var input = document.createElement( "input" ),
|
||
select = document.createElement( "select" ),
|
||
opt = select.appendChild( document.createElement( "option" ) );
|
||
|
||
input.type = "checkbox";
|
||
|
||
// Support: Android <=4.3 only
|
||
// Default value for a checkbox should be "on"
|
||
support.checkOn = input.value !== "";
|
||
|
||
// Support: IE <=11 only
|
||
// Must access selectedIndex to make default options select
|
||
support.optSelected = opt.selected;
|
||
|
||
// Support: IE <=11 only
|
||
// An input loses its value after becoming a radio
|
||
input = document.createElement( "input" );
|
||
input.value = "t";
|
||
input.type = "radio";
|
||
support.radioValue = input.value === "t";
|
||
} )();
|
||
|
||
|
||
var boolHook,
|
||
attrHandle = jQuery.expr.attrHandle;
|
||
|
||
jQuery.fn.extend( {
|
||
attr: function( name, value ) {
|
||
return access( this, jQuery.attr, name, value, arguments.length > 1 );
|
||
},
|
||
|
||
removeAttr: function( name ) {
|
||
return this.each( function() {
|
||
jQuery.removeAttr( this, name );
|
||
} );
|
||
}
|
||
} );
|
||
|
||
jQuery.extend( {
|
||
attr: function( elem, name, value ) {
|
||
var ret, hooks,
|
||
nType = elem.nodeType;
|
||
|
||
// Don't get/set attributes on text, comment and attribute nodes
|
||
if ( nType === 3 || nType === 8 || nType === 2 ) {
|
||
return;
|
||
}
|
||
|
||
// Fallback to prop when attributes are not supported
|
||
if ( typeof elem.getAttribute === "undefined" ) {
|
||
return jQuery.prop( elem, name, value );
|
||
}
|
||
|
||
// Attribute hooks are determined by the lowercase version
|
||
// Grab necessary hook if one is defined
|
||
if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) {
|
||
hooks = jQuery.attrHooks[ name.toLowerCase() ] ||
|
||
( jQuery.expr.match.bool.test( name ) ? boolHook : undefined );
|
||
}
|
||
|
||
if ( value !== undefined ) {
|
||
if ( value === null ) {
|
||
jQuery.removeAttr( elem, name );
|
||
return;
|
||
}
|
||
|
||
if ( hooks && "set" in hooks &&
|
||
( ret = hooks.set( elem, value, name ) ) !== undefined ) {
|
||
return ret;
|
||
}
|
||
|
||
elem.setAttribute( name, value + "" );
|
||
return value;
|
||
}
|
||
|
||
if ( hooks && "get" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) {
|
||
return ret;
|
||
}
|
||
|
||
ret = jQuery.find.attr( elem, name );
|
||
|
||
// Non-existent attributes return null, we normalize to undefined
|
||
return ret == null ? undefined : ret;
|
||
},
|
||
|
||
attrHooks: {
|
||
type: {
|
||
set: function( elem, value ) {
|
||
if ( !support.radioValue && value === "radio" &&
|
||
nodeName( elem, "input" ) ) {
|
||
var val = elem.value;
|
||
elem.setAttribute( "type", value );
|
||
if ( val ) {
|
||
elem.value = val;
|
||
}
|
||
return value;
|
||
}
|
||
}
|
||
}
|
||
},
|
||
|
||
removeAttr: function( elem, value ) {
|
||
var name,
|
||
i = 0,
|
||
|
||
// Attribute names can contain non-HTML whitespace characters
|
||
// https://html.spec.whatwg.org/multipage/syntax.html#attributes-2
|
||
attrNames = value && value.match( rnothtmlwhite );
|
||
|
||
if ( attrNames && elem.nodeType === 1 ) {
|
||
while ( ( name = attrNames[ i++ ] ) ) {
|
||
elem.removeAttribute( name );
|
||
}
|
||
}
|
||
}
|
||
} );
|
||
|
||
// Hooks for boolean attributes
|
||
boolHook = {
|
||
set: function( elem, value, name ) {
|
||
if ( value === false ) {
|
||
|
||
// Remove boolean attributes when set to false
|
||
jQuery.removeAttr( elem, name );
|
||
} else {
|
||
elem.setAttribute( name, name );
|
||
}
|
||
return name;
|
||
}
|
||
};
|
||
|
||
jQuery.each( jQuery.expr.match.bool.source.match( /\w+/g ), function( i, name ) {
|
||
var getter = attrHandle[ name ] || jQuery.find.attr;
|
||
|
||
attrHandle[ name ] = function( elem, name, isXML ) {
|
||
var ret, handle,
|
||
lowercaseName = name.toLowerCase();
|
||
|
||
if ( !isXML ) {
|
||
|
||
// Avoid an infinite loop by temporarily removing this function from the getter
|
||
handle = attrHandle[ lowercaseName ];
|
||
attrHandle[ lowercaseName ] = ret;
|
||
ret = getter( elem, name, isXML ) != null ?
|
||
lowercaseName :
|
||
null;
|
||
attrHandle[ lowercaseName ] = handle;
|
||
}
|
||
return ret;
|
||
};
|
||
} );
|
||
|
||
|
||
|
||
|
||
var rfocusable = /^(?:input|select|textarea|button)$/i,
|
||
rclickable = /^(?:a|area)$/i;
|
||
|
||
jQuery.fn.extend( {
|
||
prop: function( name, value ) {
|
||
return access( this, jQuery.prop, name, value, arguments.length > 1 );
|
||
},
|
||
|
||
removeProp: function( name ) {
|
||
return this.each( function() {
|
||
delete this[ jQuery.propFix[ name ] || name ];
|
||
} );
|
||
}
|
||
} );
|
||
|
||
jQuery.extend( {
|
||
prop: function( elem, name, value ) {
|
||
var ret, hooks,
|
||
nType = elem.nodeType;
|
||
|
||
// Don't get/set properties on text, comment and attribute nodes
|
||
if ( nType === 3 || nType === 8 || nType === 2 ) {
|
||
return;
|
||
}
|
||
|
||
if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) {
|
||
|
||
// Fix name and attach hooks
|
||
name = jQuery.propFix[ name ] || name;
|
||
hooks = jQuery.propHooks[ name ];
|
||
}
|
||
|
||
if ( value !== undefined ) {
|
||
if ( hooks && "set" in hooks &&
|
||
( ret = hooks.set( elem, value, name ) ) !== undefined ) {
|
||
return ret;
|
||
}
|
||
|
||
return ( elem[ name ] = value );
|
||
}
|
||
|
||
if ( hooks && "get" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) {
|
||
return ret;
|
||
}
|
||
|
||
return elem[ name ];
|
||
},
|
||
|
||
propHooks: {
|
||
tabIndex: {
|
||
get: function( elem ) {
|
||
|
||
// Support: IE <=9 - 11 only
|
||
// elem.tabIndex doesn't always return the
|
||
// correct value when it hasn't been explicitly set
|
||
// https://web.archive.org/web/20141116233347/http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/
|
||
// Use proper attribute retrieval(#12072)
|
||
var tabindex = jQuery.find.attr( elem, "tabindex" );
|
||
|
||
if ( tabindex ) {
|
||
return parseInt( tabindex, 10 );
|
||
}
|
||
|
||
if (
|
||
rfocusable.test( elem.nodeName ) ||
|
||
rclickable.test( elem.nodeName ) &&
|
||
elem.href
|
||
) {
|
||
return 0;
|
||
}
|
||
|
||
return -1;
|
||
}
|
||
}
|
||
},
|
||
|
||
propFix: {
|
||
"for": "htmlFor",
|
||
"class": "className"
|
||
}
|
||
} );
|
||
|
||
// Support: IE <=11 only
|
||
// Accessing the selectedIndex property
|
||
// forces the browser to respect setting selected
|
||
// on the option
|
||
// The getter ensures a default option is selected
|
||
// when in an optgroup
|
||
// eslint rule "no-unused-expressions" is disabled for this code
|
||
// since it considers such accessions noop
|
||
if ( !support.optSelected ) {
|
||
jQuery.propHooks.selected = {
|
||
get: function( elem ) {
|
||
|
||
/* eslint no-unused-expressions: "off" */
|
||
|
||
var parent = elem.parentNode;
|
||
if ( parent && parent.parentNode ) {
|
||
parent.parentNode.selectedIndex;
|
||
}
|
||
return null;
|
||
},
|
||
set: function( elem ) {
|
||
|
||
/* eslint no-unused-expressions: "off" */
|
||
|
||
var parent = elem.parentNode;
|
||
if ( parent ) {
|
||
parent.selectedIndex;
|
||
|
||
if ( parent.parentNode ) {
|
||
parent.parentNode.selectedIndex;
|
||
}
|
||
}
|
||
}
|
||
};
|
||
}
|
||
|
||
jQuery.each( [
|
||
"tabIndex",
|
||
"readOnly",
|
||
"maxLength",
|
||
"cellSpacing",
|
||
"cellPadding",
|
||
"rowSpan",
|
||
"colSpan",
|
||
"useMap",
|
||
"frameBorder",
|
||
"contentEditable"
|
||
], function() {
|
||
jQuery.propFix[ this.toLowerCase() ] = this;
|
||
} );
|
||
|
||
|
||
|
||
|
||
// Strip and collapse whitespace according to HTML spec
|
||
// https://html.spec.whatwg.org/multipage/infrastructure.html#strip-and-collapse-whitespace
|
||
function stripAndCollapse( value ) {
|
||
var tokens = value.match( rnothtmlwhite ) || [];
|
||
return tokens.join( " " );
|
||
}
|
||
|
||
|
||
function getClass( elem ) {
|
||
return elem.getAttribute && elem.getAttribute( "class" ) || "";
|
||
}
|
||
|
||
jQuery.fn.extend( {
|
||
addClass: function( value ) {
|
||
var classes, elem, cur, curValue, clazz, j, finalValue,
|
||
i = 0;
|
||
|
||
if ( jQuery.isFunction( value ) ) {
|
||
return this.each( function( j ) {
|
||
jQuery( this ).addClass( value.call( this, j, getClass( this ) ) );
|
||
} );
|
||
}
|
||
|
||
if ( typeof value === "string" && value ) {
|
||
classes = value.match( rnothtmlwhite ) || [];
|
||
|
||
while ( ( elem = this[ i++ ] ) ) {
|
||
curValue = getClass( elem );
|
||
cur = elem.nodeType === 1 && ( " " + stripAndCollapse( curValue ) + " " );
|
||
|
||
if ( cur ) {
|
||
j = 0;
|
||
while ( ( clazz = classes[ j++ ] ) ) {
|
||
if ( cur.indexOf( " " + clazz + " " ) < 0 ) {
|
||
cur += clazz + " ";
|
||
}
|
||
}
|
||
|
||
// Only assign if different to avoid unneeded rendering.
|
||
finalValue = stripAndCollapse( cur );
|
||
if ( curValue !== finalValue ) {
|
||
elem.setAttribute( "class", finalValue );
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
return this;
|
||
},
|
||
|
||
removeClass: function( value ) {
|
||
var classes, elem, cur, curValue, clazz, j, finalValue,
|
||
i = 0;
|
||
|
||
if ( jQuery.isFunction( value ) ) {
|
||
return this.each( function( j ) {
|
||
jQuery( this ).removeClass( value.call( this, j, getClass( this ) ) );
|
||
} );
|
||
}
|
||
|
||
if ( !arguments.length ) {
|
||
return this.attr( "class", "" );
|
||
}
|
||
|
||
if ( typeof value === "string" && value ) {
|
||
classes = value.match( rnothtmlwhite ) || [];
|
||
|
||
while ( ( elem = this[ i++ ] ) ) {
|
||
curValue = getClass( elem );
|
||
|
||
// This expression is here for better compressibility (see addClass)
|
||
cur = elem.nodeType === 1 && ( " " + stripAndCollapse( curValue ) + " " );
|
||
|
||
if ( cur ) {
|
||
j = 0;
|
||
while ( ( clazz = classes[ j++ ] ) ) {
|
||
|
||
// Remove *all* instances
|
||
while ( cur.indexOf( " " + clazz + " " ) > -1 ) {
|
||
cur = cur.replace( " " + clazz + " ", " " );
|
||
}
|
||
}
|
||
|
||
// Only assign if different to avoid unneeded rendering.
|
||
finalValue = stripAndCollapse( cur );
|
||
if ( curValue !== finalValue ) {
|
||
elem.setAttribute( "class", finalValue );
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
return this;
|
||
},
|
||
|
||
toggleClass: function( value, stateVal ) {
|
||
var type = typeof value;
|
||
|
||
if ( typeof stateVal === "boolean" && type === "string" ) {
|
||
return stateVal ? this.addClass( value ) : this.removeClass( value );
|
||
}
|
||
|
||
if ( jQuery.isFunction( value ) ) {
|
||
return this.each( function( i ) {
|
||
jQuery( this ).toggleClass(
|
||
value.call( this, i, getClass( this ), stateVal ),
|
||
stateVal
|
||
);
|
||
} );
|
||
}
|
||
|
||
return this.each( function() {
|
||
var className, i, self, classNames;
|
||
|
||
if ( type === "string" ) {
|
||
|
||
// Toggle individual class names
|
||
i = 0;
|
||
self = jQuery( this );
|
||
classNames = value.match( rnothtmlwhite ) || [];
|
||
|
||
while ( ( className = classNames[ i++ ] ) ) {
|
||
|
||
// Check each className given, space separated list
|
||
if ( self.hasClass( className ) ) {
|
||
self.removeClass( className );
|
||
} else {
|
||
self.addClass( className );
|
||
}
|
||
}
|
||
|
||
// Toggle whole class name
|
||
} else if ( value === undefined || type === "boolean" ) {
|
||
className = getClass( this );
|
||
if ( className ) {
|
||
|
||
// Store className if set
|
||
dataPriv.set( this, "__className__", className );
|
||
}
|
||
|
||
// If the element has a class name or if we're passed `false`,
|
||
// then remove the whole classname (if there was one, the above saved it).
|
||
// Otherwise bring back whatever was previously saved (if anything),
|
||
// falling back to the empty string if nothing was stored.
|
||
if ( this.setAttribute ) {
|
||
this.setAttribute( "class",
|
||
className || value === false ?
|
||
"" :
|
||
dataPriv.get( this, "__className__" ) || ""
|
||
);
|
||
}
|
||
}
|
||
} );
|
||
},
|
||
|
||
hasClass: function( selector ) {
|
||
var className, elem,
|
||
i = 0;
|
||
|
||
className = " " + selector + " ";
|
||
while ( ( elem = this[ i++ ] ) ) {
|
||
if ( elem.nodeType === 1 &&
|
||
( " " + stripAndCollapse( getClass( elem ) ) + " " ).indexOf( className ) > -1 ) {
|
||
return true;
|
||
}
|
||
}
|
||
|
||
return false;
|
||
}
|
||
} );
|
||
|
||
|
||
|
||
|
||
var rreturn = /\r/g;
|
||
|
||
jQuery.fn.extend( {
|
||
val: function( value ) {
|
||
var hooks, ret, isFunction,
|
||
elem = this[ 0 ];
|
||
|
||
if ( !arguments.length ) {
|
||
if ( elem ) {
|
||
hooks = jQuery.valHooks[ elem.type ] ||
|
||
jQuery.valHooks[ elem.nodeName.toLowerCase() ];
|
||
|
||
if ( hooks &&
|
||
"get" in hooks &&
|
||
( ret = hooks.get( elem, "value" ) ) !== undefined
|
||
) {
|
||
return ret;
|
||
}
|
||
|
||
ret = elem.value;
|
||
|
||
// Handle most common string cases
|
||
if ( typeof ret === "string" ) {
|
||
return ret.replace( rreturn, "" );
|
||
}
|
||
|
||
// Handle cases where value is null/undef or number
|
||
return ret == null ? "" : ret;
|
||
}
|
||
|
||
return;
|
||
}
|
||
|
||
isFunction = jQuery.isFunction( value );
|
||
|
||
return this.each( function( i ) {
|
||
var val;
|
||
|
||
if ( this.nodeType !== 1 ) {
|
||
return;
|
||
}
|
||
|
||
if ( isFunction ) {
|
||
val = value.call( this, i, jQuery( this ).val() );
|
||
} else {
|
||
val = value;
|
||
}
|
||
|
||
// Treat null/undefined as ""; convert numbers to string
|
||
if ( val == null ) {
|
||
val = "";
|
||
|
||
} else if ( typeof val === "number" ) {
|
||
val += "";
|
||
|
||
} else if ( Array.isArray( val ) ) {
|
||
val = jQuery.map( val, function( value ) {
|
||
return value == null ? "" : value + "";
|
||
} );
|
||
}
|
||
|
||
hooks = jQuery.valHooks[ this.type ] || jQuery.valHooks[ this.nodeName.toLowerCase() ];
|
||
|
||
// If set returns undefined, fall back to normal setting
|
||
if ( !hooks || !( "set" in hooks ) || hooks.set( this, val, "value" ) === undefined ) {
|
||
this.value = val;
|
||
}
|
||
} );
|
||
}
|
||
} );
|
||
|
||
jQuery.extend( {
|
||
valHooks: {
|
||
option: {
|
||
get: function( elem ) {
|
||
|
||
var val = jQuery.find.attr( elem, "value" );
|
||
return val != null ?
|
||
val :
|
||
|
||
// Support: IE <=10 - 11 only
|
||
// option.text throws exceptions (#14686, #14858)
|
||
// Strip and collapse whitespace
|
||
// https://html.spec.whatwg.org/#strip-and-collapse-whitespace
|
||
stripAndCollapse( jQuery.text( elem ) );
|
||
}
|
||
},
|
||
select: {
|
||
get: function( elem ) {
|
||
var value, option, i,
|
||
options = elem.options,
|
||
index = elem.selectedIndex,
|
||
one = elem.type === "select-one",
|
||
values = one ? null : [],
|
||
max = one ? index + 1 : options.length;
|
||
|
||
if ( index < 0 ) {
|
||
i = max;
|
||
|
||
} else {
|
||
i = one ? index : 0;
|
||
}
|
||
|
||
// Loop through all the selected options
|
||
for ( ; i < max; i++ ) {
|
||
option = options[ i ];
|
||
|
||
// Support: IE <=9 only
|
||
// IE8-9 doesn't update selected after form reset (#2551)
|
||
if ( ( option.selected || i === index ) &&
|
||
|
||
// Don't return options that are disabled or in a disabled optgroup
|
||
!option.disabled &&
|
||
( !option.parentNode.disabled ||
|
||
!nodeName( option.parentNode, "optgroup" ) ) ) {
|
||
|
||
// Get the specific value for the option
|
||
value = jQuery( option ).val();
|
||
|
||
// We don't need an array for one selects
|
||
if ( one ) {
|
||
return value;
|
||
}
|
||
|
||
// Multi-Selects return an array
|
||
values.push( value );
|
||
}
|
||
}
|
||
|
||
return values;
|
||
},
|
||
|
||
set: function( elem, value ) {
|
||
var optionSet, option,
|
||
options = elem.options,
|
||
values = jQuery.makeArray( value ),
|
||
i = options.length;
|
||
|
||
while ( i-- ) {
|
||
option = options[ i ];
|
||
|
||
/* eslint-disable no-cond-assign */
|
||
|
||
if ( option.selected =
|
||
jQuery.inArray( jQuery.valHooks.option.get( option ), values ) > -1
|
||
) {
|
||
optionSet = true;
|
||
}
|
||
|
||
/* eslint-enable no-cond-assign */
|
||
}
|
||
|
||
// Force browsers to behave consistently when non-matching value is set
|
||
if ( !optionSet ) {
|
||
elem.selectedIndex = -1;
|
||
}
|
||
return values;
|
||
}
|
||
}
|
||
}
|
||
} );
|
||
|
||
// Radios and checkboxes getter/setter
|
||
jQuery.each( [ "radio", "checkbox" ], function() {
|
||
jQuery.valHooks[ this ] = {
|
||
set: function( elem, value ) {
|
||
if ( Array.isArray( value ) ) {
|
||
return ( elem.checked = jQuery.inArray( jQuery( elem ).val(), value ) > -1 );
|
||
}
|
||
}
|
||
};
|
||
if ( !support.checkOn ) {
|
||
jQuery.valHooks[ this ].get = function( elem ) {
|
||
return elem.getAttribute( "value" ) === null ? "on" : elem.value;
|
||
};
|
||
}
|
||
} );
|
||
|
||
|
||
|
||
|
||
// Return jQuery for attributes-only inclusion
|
||
|
||
|
||
var rfocusMorph = /^(?:focusinfocus|focusoutblur)$/;
|
||
|
||
jQuery.extend( jQuery.event, {
|
||
|
||
trigger: function( event, data, elem, onlyHandlers ) {
|
||
|
||
var i, cur, tmp, bubbleType, ontype, handle, special,
|
||
eventPath = [ elem || document ],
|
||
type = hasOwn.call( event, "type" ) ? event.type : event,
|
||
namespaces = hasOwn.call( event, "namespace" ) ? event.namespace.split( "." ) : [];
|
||
|
||
cur = tmp = elem = elem || document;
|
||
|
||
// Don't do events on text and comment nodes
|
||
if ( elem.nodeType === 3 || elem.nodeType === 8 ) {
|
||
return;
|
||
}
|
||
|
||
// focus/blur morphs to focusin/out; ensure we're not firing them right now
|
||
if ( rfocusMorph.test( type + jQuery.event.triggered ) ) {
|
||
return;
|
||
}
|
||
|
||
if ( type.indexOf( "." ) > -1 ) {
|
||
|
||
// Namespaced trigger; create a regexp to match event type in handle()
|
||
namespaces = type.split( "." );
|
||
type = namespaces.shift();
|
||
namespaces.sort();
|
||
}
|
||
ontype = type.indexOf( ":" ) < 0 && "on" + type;
|
||
|
||
// Caller can pass in a jQuery.Event object, Object, or just an event type string
|
||
event = event[ jQuery.expando ] ?
|
||
event :
|
||
new jQuery.Event( type, typeof event === "object" && event );
|
||
|
||
// Trigger bitmask: & 1 for native handlers; & 2 for jQuery (always true)
|
||
event.isTrigger = onlyHandlers ? 2 : 3;
|
||
event.namespace = namespaces.join( "." );
|
||
event.rnamespace = event.namespace ?
|
||
new RegExp( "(^|\\.)" + namespaces.join( "\\.(?:.*\\.|)" ) + "(\\.|$)" ) :
|
||
null;
|
||
|
||
// Clean up the event in case it is being reused
|
||
event.result = undefined;
|
||
if ( !event.target ) {
|
||
event.target = elem;
|
||
}
|
||
|
||
// Clone any incoming data and prepend the event, creating the handler arg list
|
||
data = data == null ?
|
||
[ event ] :
|
||
jQuery.makeArray( data, [ event ] );
|
||
|
||
// Allow special events to draw outside the lines
|
||
special = jQuery.event.special[ type ] || {};
|
||
if ( !onlyHandlers && special.trigger && special.trigger.apply( elem, data ) === false ) {
|
||
return;
|
||
}
|
||
|
||
// Determine event propagation path in advance, per W3C events spec (#9951)
|
||
// Bubble up to document, then to window; watch for a global ownerDocument var (#9724)
|
||
if ( !onlyHandlers && !special.noBubble && !jQuery.isWindow( elem ) ) {
|
||
|
||
bubbleType = special.delegateType || type;
|
||
if ( !rfocusMorph.test( bubbleType + type ) ) {
|
||
cur = cur.parentNode;
|
||
}
|
||
for ( ; cur; cur = cur.parentNode ) {
|
||
eventPath.push( cur );
|
||
tmp = cur;
|
||
}
|
||
|
||
// Only add window if we got to document (e.g., not plain obj or detached DOM)
|
||
if ( tmp === ( elem.ownerDocument || document ) ) {
|
||
eventPath.push( tmp.defaultView || tmp.parentWindow || window );
|
||
}
|
||
}
|
||
|
||
// Fire handlers on the event path
|
||
i = 0;
|
||
while ( ( cur = eventPath[ i++ ] ) && !event.isPropagationStopped() ) {
|
||
|
||
event.type = i > 1 ?
|
||
bubbleType :
|
||
special.bindType || type;
|
||
|
||
// jQuery handler
|
||
handle = ( dataPriv.get( cur, "events" ) || {} )[ event.type ] &&
|
||
dataPriv.get( cur, "handle" );
|
||
if ( handle ) {
|
||
handle.apply( cur, data );
|
||
}
|
||
|
||
// Native handler
|
||
handle = ontype && cur[ ontype ];
|
||
if ( handle && handle.apply && acceptData( cur ) ) {
|
||
event.result = handle.apply( cur, data );
|
||
if ( event.result === false ) {
|
||
event.preventDefault();
|
||
}
|
||
}
|
||
}
|
||
event.type = type;
|
||
|
||
// If nobody prevented the default action, do it now
|
||
if ( !onlyHandlers && !event.isDefaultPrevented() ) {
|
||
|
||
if ( ( !special._default ||
|
||
special._default.apply( eventPath.pop(), data ) === false ) &&
|
||
acceptData( elem ) ) {
|
||
|
||
// Call a native DOM method on the target with the same name as the event.
|
||
// Don't do default actions on window, that's where global variables be (#6170)
|
||
if ( ontype && jQuery.isFunction( elem[ type ] ) && !jQuery.isWindow( elem ) ) {
|
||
|
||
// Don't re-trigger an onFOO event when we call its FOO() method
|
||
tmp = elem[ ontype ];
|
||
|
||
if ( tmp ) {
|
||
elem[ ontype ] = null;
|
||
}
|
||
|
||
// Prevent re-triggering of the same event, since we already bubbled it above
|
||
jQuery.event.triggered = type;
|
||
elem[ type ]();
|
||
jQuery.event.triggered = undefined;
|
||
|
||
if ( tmp ) {
|
||
elem[ ontype ] = tmp;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
return event.result;
|
||
},
|
||
|
||
// Piggyback on a donor event to simulate a different one
|
||
// Used only for `focus(in | out)` events
|
||
simulate: function( type, elem, event ) {
|
||
var e = jQuery.extend(
|
||
new jQuery.Event(),
|
||
event,
|
||
{
|
||
type: type,
|
||
isSimulated: true
|
||
}
|
||
);
|
||
|
||
jQuery.event.trigger( e, null, elem );
|
||
}
|
||
|
||
} );
|
||
|
||
jQuery.fn.extend( {
|
||
|
||
trigger: function( type, data ) {
|
||
return this.each( function() {
|
||
jQuery.event.trigger( type, data, this );
|
||
} );
|
||
},
|
||
triggerHandler: function( type, data ) {
|
||
var elem = this[ 0 ];
|
||
if ( elem ) {
|
||
return jQuery.event.trigger( type, data, elem, true );
|
||
}
|
||
}
|
||
} );
|
||
|
||
|
||
jQuery.each( ( "blur focus focusin focusout resize scroll click dblclick " +
|
||
"mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " +
|
||
"change select submit keydown keypress keyup contextmenu" ).split( " " ),
|
||
function( i, name ) {
|
||
|
||
// Handle event binding
|
||
jQuery.fn[ name ] = function( data, fn ) {
|
||
return arguments.length > 0 ?
|
||
this.on( name, null, data, fn ) :
|
||
this.trigger( name );
|
||
};
|
||
} );
|
||
|
||
jQuery.fn.extend( {
|
||
hover: function( fnOver, fnOut ) {
|
||
return this.mouseenter( fnOver ).mouseleave( fnOut || fnOver );
|
||
}
|
||
} );
|
||
|
||
|
||
|
||
|
||
support.focusin = "onfocusin" in window;
|
||
|
||
|
||
// Support: Firefox <=44
|
||
// Firefox doesn't have focus(in | out) events
|
||
// Related ticket - https://bugzilla.mozilla.org/show_bug.cgi?id=687787
|
||
//
|
||
// Support: Chrome <=48 - 49, Safari <=9.0 - 9.1
|
||
// focus(in | out) events fire after focus & blur events,
|
||
// which is spec violation - http://www.w3.org/TR/DOM-Level-3-Events/#events-focusevent-event-order
|
||
// Related ticket - https://bugs.chromium.org/p/chromium/issues/detail?id=449857
|
||
if ( !support.focusin ) {
|
||
jQuery.each( { focus: "focusin", blur: "focusout" }, function( orig, fix ) {
|
||
|
||
// Attach a single capturing handler on the document while someone wants focusin/focusout
|
||
var handler = function( event ) {
|
||
jQuery.event.simulate( fix, event.target, jQuery.event.fix( event ) );
|
||
};
|
||
|
||
jQuery.event.special[ fix ] = {
|
||
setup: function() {
|
||
var doc = this.ownerDocument || this,
|
||
attaches = dataPriv.access( doc, fix );
|
||
|
||
if ( !attaches ) {
|
||
doc.addEventListener( orig, handler, true );
|
||
}
|
||
dataPriv.access( doc, fix, ( attaches || 0 ) + 1 );
|
||
},
|
||
teardown: function() {
|
||
var doc = this.ownerDocument || this,
|
||
attaches = dataPriv.access( doc, fix ) - 1;
|
||
|
||
if ( !attaches ) {
|
||
doc.removeEventListener( orig, handler, true );
|
||
dataPriv.remove( doc, fix );
|
||
|
||
} else {
|
||
dataPriv.access( doc, fix, attaches );
|
||
}
|
||
}
|
||
};
|
||
} );
|
||
}
|
||
var location = window.location;
|
||
|
||
var nonce = jQuery.now();
|
||
|
||
var rquery = ( /\?/ );
|
||
|
||
|
||
|
||
// Cross-browser xml parsing
|
||
jQuery.parseXML = function( data ) {
|
||
var xml;
|
||
if ( !data || typeof data !== "string" ) {
|
||
return null;
|
||
}
|
||
|
||
// Support: IE 9 - 11 only
|
||
// IE throws on parseFromString with invalid input.
|
||
try {
|
||
xml = ( new window.DOMParser() ).parseFromString( data, "text/xml" );
|
||
} catch ( e ) {
|
||
xml = undefined;
|
||
}
|
||
|
||
if ( !xml || xml.getElementsByTagName( "parsererror" ).length ) {
|
||
jQuery.error( "Invalid XML: " + data );
|
||
}
|
||
return xml;
|
||
};
|
||
|
||
|
||
var
|
||
rbracket = /\[\]$/,
|
||
rCRLF = /\r?\n/g,
|
||
rsubmitterTypes = /^(?:submit|button|image|reset|file)$/i,
|
||
rsubmittable = /^(?:input|select|textarea|keygen)/i;
|
||
|
||
function buildParams( prefix, obj, traditional, add ) {
|
||
var name;
|
||
|
||
if ( Array.isArray( obj ) ) {
|
||
|
||
// Serialize array item.
|
||
jQuery.each( obj, function( i, v ) {
|
||
if ( traditional || rbracket.test( prefix ) ) {
|
||
|
||
// Treat each array item as a scalar.
|
||
add( prefix, v );
|
||
|
||
} else {
|
||
|
||
// Item is non-scalar (array or object), encode its numeric index.
|
||
buildParams(
|
||
prefix + "[" + ( typeof v === "object" && v != null ? i : "" ) + "]",
|
||
v,
|
||
traditional,
|
||
add
|
||
);
|
||
}
|
||
} );
|
||
|
||
} else if ( !traditional && jQuery.type( obj ) === "object" ) {
|
||
|
||
// Serialize object item.
|
||
for ( name in obj ) {
|
||
buildParams( prefix + "[" + name + "]", obj[ name ], traditional, add );
|
||
}
|
||
|
||
} else {
|
||
|
||
// Serialize scalar item.
|
||
add( prefix, obj );
|
||
}
|
||
}
|
||
|
||
// Serialize an array of form elements or a set of
|
||
// key/values into a query string
|
||
jQuery.param = function( a, traditional ) {
|
||
var prefix,
|
||
s = [],
|
||
add = function( key, valueOrFunction ) {
|
||
|
||
// If value is a function, invoke it and use its return value
|
||
var value = jQuery.isFunction( valueOrFunction ) ?
|
||
valueOrFunction() :
|
||
valueOrFunction;
|
||
|
||
s[ s.length ] = encodeURIComponent( key ) + "=" +
|
||
encodeURIComponent( value == null ? "" : value );
|
||
};
|
||
|
||
// If an array was passed in, assume that it is an array of form elements.
|
||
if ( Array.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) {
|
||
|
||
// Serialize the form elements
|
||
jQuery.each( a, function() {
|
||
add( this.name, this.value );
|
||
} );
|
||
|
||
} else {
|
||
|
||
// If traditional, encode the "old" way (the way 1.3.2 or older
|
||
// did it), otherwise encode params recursively.
|
||
for ( prefix in a ) {
|
||
buildParams( prefix, a[ prefix ], traditional, add );
|
||
}
|
||
}
|
||
|
||
// Return the resulting serialization
|
||
return s.join( "&" );
|
||
};
|
||
|
||
jQuery.fn.extend( {
|
||
serialize: function() {
|
||
return jQuery.param( this.serializeArray() );
|
||
},
|
||
serializeArray: function() {
|
||
return this.map( function() {
|
||
|
||
// Can add propHook for "elements" to filter or add form elements
|
||
var elements = jQuery.prop( this, "elements" );
|
||
return elements ? jQuery.makeArray( elements ) : this;
|
||
} )
|
||
.filter( function() {
|
||
var type = this.type;
|
||
|
||
// Use .is( ":disabled" ) so that fieldset[disabled] works
|
||
return this.name && !jQuery( this ).is( ":disabled" ) &&
|
||
rsubmittable.test( this.nodeName ) && !rsubmitterTypes.test( type ) &&
|
||
( this.checked || !rcheckableType.test( type ) );
|
||
} )
|
||
.map( function( i, elem ) {
|
||
var val = jQuery( this ).val();
|
||
|
||
if ( val == null ) {
|
||
return null;
|
||
}
|
||
|
||
if ( Array.isArray( val ) ) {
|
||
return jQuery.map( val, function( val ) {
|
||
return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
|
||
} );
|
||
}
|
||
|
||
return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
|
||
} ).get();
|
||
}
|
||
} );
|
||
|
||
|
||
var
|
||
r20 = /%20/g,
|
||
rhash = /#.*$/,
|
||
rantiCache = /([?&])_=[^&]*/,
|
||
rheaders = /^(.*?):[ \t]*([^\r\n]*)$/mg,
|
||
|
||
// #7653, #8125, #8152: local protocol detection
|
||
rlocalProtocol = /^(?:about|app|app-storage|.+-extension|file|res|widget):$/,
|
||
rnoContent = /^(?:GET|HEAD)$/,
|
||
rprotocol = /^\/\//,
|
||
|
||
/* Prefilters
|
||
* 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example)
|
||
* 2) These are called:
|
||
* - BEFORE asking for a transport
|
||
* - AFTER param serialization (s.data is a string if s.processData is true)
|
||
* 3) key is the dataType
|
||
* 4) the catchall symbol "*" can be used
|
||
* 5) execution will start with transport dataType and THEN continue down to "*" if needed
|
||
*/
|
||
prefilters = {},
|
||
|
||
/* Transports bindings
|
||
* 1) key is the dataType
|
||
* 2) the catchall symbol "*" can be used
|
||
* 3) selection will start with transport dataType and THEN go to "*" if needed
|
||
*/
|
||
transports = {},
|
||
|
||
// Avoid comment-prolog char sequence (#10098); must appease lint and evade compression
|
||
allTypes = "*/".concat( "*" ),
|
||
|
||
// Anchor tag for parsing the document origin
|
||
originAnchor = document.createElement( "a" );
|
||
originAnchor.href = location.href;
|
||
|
||
// Base "constructor" for jQuery.ajaxPrefilter and jQuery.ajaxTransport
|
||
function addToPrefiltersOrTransports( structure ) {
|
||
|
||
// dataTypeExpression is optional and defaults to "*"
|
||
return function( dataTypeExpression, func ) {
|
||
|
||
if ( typeof dataTypeExpression !== "string" ) {
|
||
func = dataTypeExpression;
|
||
dataTypeExpression = "*";
|
||
}
|
||
|
||
var dataType,
|
||
i = 0,
|
||
dataTypes = dataTypeExpression.toLowerCase().match( rnothtmlwhite ) || [];
|
||
|
||
if ( jQuery.isFunction( func ) ) {
|
||
|
||
// For each dataType in the dataTypeExpression
|
||
while ( ( dataType = dataTypes[ i++ ] ) ) {
|
||
|
||
// Prepend if requested
|
||
if ( dataType[ 0 ] === "+" ) {
|
||
dataType = dataType.slice( 1 ) || "*";
|
||
( structure[ dataType ] = structure[ dataType ] || [] ).unshift( func );
|
||
|
||
// Otherwise append
|
||
} else {
|
||
( structure[ dataType ] = structure[ dataType ] || [] ).push( func );
|
||
}
|
||
}
|
||
}
|
||
};
|
||
}
|
||
|
||
// Base inspection function for prefilters and transports
|
||
function inspectPrefiltersOrTransports( structure, options, originalOptions, jqXHR ) {
|
||
|
||
var inspected = {},
|
||
seekingTransport = ( structure === transports );
|
||
|
||
function inspect( dataType ) {
|
||
var selected;
|
||
inspected[ dataType ] = true;
|
||
jQuery.each( structure[ dataType ] || [], function( _, prefilterOrFactory ) {
|
||
var dataTypeOrTransport = prefilterOrFactory( options, originalOptions, jqXHR );
|
||
if ( typeof dataTypeOrTransport === "string" &&
|
||
!seekingTransport && !inspected[ dataTypeOrTransport ] ) {
|
||
|
||
options.dataTypes.unshift( dataTypeOrTransport );
|
||
inspect( dataTypeOrTransport );
|
||
return false;
|
||
} else if ( seekingTransport ) {
|
||
return !( selected = dataTypeOrTransport );
|
||
}
|
||
} );
|
||
return selected;
|
||
}
|
||
|
||
return inspect( options.dataTypes[ 0 ] ) || !inspected[ "*" ] && inspect( "*" );
|
||
}
|
||
|
||
// A special extend for ajax options
|
||
// that takes "flat" options (not to be deep extended)
|
||
// Fixes #9887
|
||
function ajaxExtend( target, src ) {
|
||
var key, deep,
|
||
flatOptions = jQuery.ajaxSettings.flatOptions || {};
|
||
|
||
for ( key in src ) {
|
||
if ( src[ key ] !== undefined ) {
|
||
( flatOptions[ key ] ? target : ( deep || ( deep = {} ) ) )[ key ] = src[ key ];
|
||
}
|
||
}
|
||
if ( deep ) {
|
||
jQuery.extend( true, target, deep );
|
||
}
|
||
|
||
return target;
|
||
}
|
||
|
||
/* Handles responses to an ajax request:
|
||
* - finds the right dataType (mediates between content-type and expected dataType)
|
||
* - returns the corresponding response
|
||
*/
|
||
function ajaxHandleResponses( s, jqXHR, responses ) {
|
||
|
||
var ct, type, finalDataType, firstDataType,
|
||
contents = s.contents,
|
||
dataTypes = s.dataTypes;
|
||
|
||
// Remove auto dataType and get content-type in the process
|
||
while ( dataTypes[ 0 ] === "*" ) {
|
||
dataTypes.shift();
|
||
if ( ct === undefined ) {
|
||
ct = s.mimeType || jqXHR.getResponseHeader( "Content-Type" );
|
||
}
|
||
}
|
||
|
||
// Check if we're dealing with a known content-type
|
||
if ( ct ) {
|
||
for ( type in contents ) {
|
||
if ( contents[ type ] && contents[ type ].test( ct ) ) {
|
||
dataTypes.unshift( type );
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
|
||
// Check to see if we have a response for the expected dataType
|
||
if ( dataTypes[ 0 ] in responses ) {
|
||
finalDataType = dataTypes[ 0 ];
|
||
} else {
|
||
|
||
// Try convertible dataTypes
|
||
for ( type in responses ) {
|
||
if ( !dataTypes[ 0 ] || s.converters[ type + " " + dataTypes[ 0 ] ] ) {
|
||
finalDataType = type;
|
||
break;
|
||
}
|
||
if ( !firstDataType ) {
|
||
firstDataType = type;
|
||
}
|
||
}
|
||
|
||
// Or just use first one
|
||
finalDataType = finalDataType || firstDataType;
|
||
}
|
||
|
||
// If we found a dataType
|
||
// We add the dataType to the list if needed
|
||
// and return the corresponding response
|
||
if ( finalDataType ) {
|
||
if ( finalDataType !== dataTypes[ 0 ] ) {
|
||
dataTypes.unshift( finalDataType );
|
||
}
|
||
return responses[ finalDataType ];
|
||
}
|
||
}
|
||
|
||
/* Chain conversions given the request and the original response
|
||
* Also sets the responseXXX fields on the jqXHR instance
|
||
*/
|
||
function ajaxConvert( s, response, jqXHR, isSuccess ) {
|
||
var conv2, current, conv, tmp, prev,
|
||
converters = {},
|
||
|
||
// Work with a copy of dataTypes in case we need to modify it for conversion
|
||
dataTypes = s.dataTypes.slice();
|
||
|
||
// Create converters map with lowercased keys
|
||
if ( dataTypes[ 1 ] ) {
|
||
for ( conv in s.converters ) {
|
||
converters[ conv.toLowerCase() ] = s.converters[ conv ];
|
||
}
|
||
}
|
||
|
||
current = dataTypes.shift();
|
||
|
||
// Convert to each sequential dataType
|
||
while ( current ) {
|
||
|
||
if ( s.responseFields[ current ] ) {
|
||
jqXHR[ s.responseFields[ current ] ] = response;
|
||
}
|
||
|
||
// Apply the dataFilter if provided
|
||
if ( !prev && isSuccess && s.dataFilter ) {
|
||
response = s.dataFilter( response, s.dataType );
|
||
}
|
||
|
||
prev = current;
|
||
current = dataTypes.shift();
|
||
|
||
if ( current ) {
|
||
|
||
// There's only work to do if current dataType is non-auto
|
||
if ( current === "*" ) {
|
||
|
||
current = prev;
|
||
|
||
// Convert response if prev dataType is non-auto and differs from current
|
||
} else if ( prev !== "*" && prev !== current ) {
|
||
|
||
// Seek a direct converter
|
||
conv = converters[ prev + " " + current ] || converters[ "* " + current ];
|
||
|
||
// If none found, seek a pair
|
||
if ( !conv ) {
|
||
for ( conv2 in converters ) {
|
||
|
||
// If conv2 outputs current
|
||
tmp = conv2.split( " " );
|
||
if ( tmp[ 1 ] === current ) {
|
||
|
||
// If prev can be converted to accepted input
|
||
conv = converters[ prev + " " + tmp[ 0 ] ] ||
|
||
converters[ "* " + tmp[ 0 ] ];
|
||
if ( conv ) {
|
||
|
||
// Condense equivalence converters
|
||
if ( conv === true ) {
|
||
conv = converters[ conv2 ];
|
||
|
||
// Otherwise, insert the intermediate dataType
|
||
} else if ( converters[ conv2 ] !== true ) {
|
||
current = tmp[ 0 ];
|
||
dataTypes.unshift( tmp[ 1 ] );
|
||
}
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
// Apply converter (if not an equivalence)
|
||
if ( conv !== true ) {
|
||
|
||
// Unless errors are allowed to bubble, catch and return them
|
||
if ( conv && s.throws ) {
|
||
response = conv( response );
|
||
} else {
|
||
try {
|
||
response = conv( response );
|
||
} catch ( e ) {
|
||
return {
|
||
state: "parsererror",
|
||
error: conv ? e : "No conversion from " + prev + " to " + current
|
||
};
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
return { state: "success", data: response };
|
||
}
|
||
|
||
jQuery.extend( {
|
||
|
||
// Counter for holding the number of active queries
|
||
active: 0,
|
||
|
||
// Last-Modified header cache for next request
|
||
lastModified: {},
|
||
etag: {},
|
||
|
||
ajaxSettings: {
|
||
url: location.href,
|
||
type: "GET",
|
||
isLocal: rlocalProtocol.test( location.protocol ),
|
||
global: true,
|
||
processData: true,
|
||
async: true,
|
||
contentType: "application/x-www-form-urlencoded; charset=UTF-8",
|
||
|
||
/*
|
||
timeout: 0,
|
||
data: null,
|
||
dataType: null,
|
||
username: null,
|
||
password: null,
|
||
cache: null,
|
||
throws: false,
|
||
traditional: false,
|
||
headers: {},
|
||
*/
|
||
|
||
accepts: {
|
||
"*": allTypes,
|
||
text: "text/plain",
|
||
html: "text/html",
|
||
xml: "application/xml, text/xml",
|
||
json: "application/json, text/javascript"
|
||
},
|
||
|
||
contents: {
|
||
xml: /\bxml\b/,
|
||
html: /\bhtml/,
|
||
json: /\bjson\b/
|
||
},
|
||
|
||
responseFields: {
|
||
xml: "responseXML",
|
||
text: "responseText",
|
||
json: "responseJSON"
|
||
},
|
||
|
||
// Data converters
|
||
// Keys separate source (or catchall "*") and destination types with a single space
|
||
converters: {
|
||
|
||
// Convert anything to text
|
||
"* text": String,
|
||
|
||
// Text to html (true = no transformation)
|
||
"text html": true,
|
||
|
||
// Evaluate text as a json expression
|
||
"text json": JSON.parse,
|
||
|
||
// Parse text as xml
|
||
"text xml": jQuery.parseXML
|
||
},
|
||
|
||
// For options that shouldn't be deep extended:
|
||
// you can add your own custom options here if
|
||
// and when you create one that shouldn't be
|
||
// deep extended (see ajaxExtend)
|
||
flatOptions: {
|
||
url: true,
|
||
context: true
|
||
}
|
||
},
|
||
|
||
// Creates a full fledged settings object into target
|
||
// with both ajaxSettings and settings fields.
|
||
// If target is omitted, writes into ajaxSettings.
|
||
ajaxSetup: function( target, settings ) {
|
||
return settings ?
|
||
|
||
// Building a settings object
|
||
ajaxExtend( ajaxExtend( target, jQuery.ajaxSettings ), settings ) :
|
||
|
||
// Extending ajaxSettings
|
||
ajaxExtend( jQuery.ajaxSettings, target );
|
||
},
|
||
|
||
ajaxPrefilter: addToPrefiltersOrTransports( prefilters ),
|
||
ajaxTransport: addToPrefiltersOrTransports( transports ),
|
||
|
||
// Main method
|
||
ajax: function( url, options ) {
|
||
|
||
// If url is an object, simulate pre-1.5 signature
|
||
if ( typeof url === "object" ) {
|
||
options = url;
|
||
url = undefined;
|
||
}
|
||
|
||
// Force options to be an object
|
||
options = options || {};
|
||
|
||
var transport,
|
||
|
||
// URL without anti-cache param
|
||
cacheURL,
|
||
|
||
// Response headers
|
||
responseHeadersString,
|
||
responseHeaders,
|
||
|
||
// timeout handle
|
||
timeoutTimer,
|
||
|
||
// Url cleanup var
|
||
urlAnchor,
|
||
|
||
// Request state (becomes false upon send and true upon completion)
|
||
completed,
|
||
|
||
// To know if global events are to be dispatched
|
||
fireGlobals,
|
||
|
||
// Loop variable
|
||
i,
|
||
|
||
// uncached part of the url
|
||
uncached,
|
||
|
||
// Create the final options object
|
||
s = jQuery.ajaxSetup( {}, options ),
|
||
|
||
// Callbacks context
|
||
callbackContext = s.context || s,
|
||
|
||
// Context for global events is callbackContext if it is a DOM node or jQuery collection
|
||
globalEventContext = s.context &&
|
||
( callbackContext.nodeType || callbackContext.jquery ) ?
|
||
jQuery( callbackContext ) :
|
||
jQuery.event,
|
||
|
||
// Deferreds
|
||
deferred = jQuery.Deferred(),
|
||
completeDeferred = jQuery.Callbacks( "once memory" ),
|
||
|
||
// Status-dependent callbacks
|
||
statusCode = s.statusCode || {},
|
||
|
||
// Headers (they are sent all at once)
|
||
requestHeaders = {},
|
||
requestHeadersNames = {},
|
||
|
||
// Default abort message
|
||
strAbort = "canceled",
|
||
|
||
// Fake xhr
|
||
jqXHR = {
|
||
readyState: 0,
|
||
|
||
// Builds headers hashtable if needed
|
||
getResponseHeader: function( key ) {
|
||
var match;
|
||
if ( completed ) {
|
||
if ( !responseHeaders ) {
|
||
responseHeaders = {};
|
||
while ( ( match = rheaders.exec( responseHeadersString ) ) ) {
|
||
responseHeaders[ match[ 1 ].toLowerCase() ] = match[ 2 ];
|
||
}
|
||
}
|
||
match = responseHeaders[ key.toLowerCase() ];
|
||
}
|
||
return match == null ? null : match;
|
||
},
|
||
|
||
// Raw string
|
||
getAllResponseHeaders: function() {
|
||
return completed ? responseHeadersString : null;
|
||
},
|
||
|
||
// Caches the header
|
||
setRequestHeader: function( name, value ) {
|
||
if ( completed == null ) {
|
||
name = requestHeadersNames[ name.toLowerCase() ] =
|
||
requestHeadersNames[ name.toLowerCase() ] || name;
|
||
requestHeaders[ name ] = value;
|
||
}
|
||
return this;
|
||
},
|
||
|
||
// Overrides response content-type header
|
||
overrideMimeType: function( type ) {
|
||
if ( completed == null ) {
|
||
s.mimeType = type;
|
||
}
|
||
return this;
|
||
},
|
||
|
||
// Status-dependent callbacks
|
||
statusCode: function( map ) {
|
||
var code;
|
||
if ( map ) {
|
||
if ( completed ) {
|
||
|
||
// Execute the appropriate callbacks
|
||
jqXHR.always( map[ jqXHR.status ] );
|
||
} else {
|
||
|
||
// Lazy-add the new callbacks in a way that preserves old ones
|
||
for ( code in map ) {
|
||
statusCode[ code ] = [ statusCode[ code ], map[ code ] ];
|
||
}
|
||
}
|
||
}
|
||
return this;
|
||
},
|
||
|
||
// Cancel the request
|
||
abort: function( statusText ) {
|
||
var finalText = statusText || strAbort;
|
||
if ( transport ) {
|
||
transport.abort( finalText );
|
||
}
|
||
done( 0, finalText );
|
||
return this;
|
||
}
|
||
};
|
||
|
||
// Attach deferreds
|
||
deferred.promise( jqXHR );
|
||
|
||
// Add protocol if not provided (prefilters might expect it)
|
||
// Handle falsy url in the settings object (#10093: consistency with old signature)
|
||
// We also use the url parameter if available
|
||
s.url = ( ( url || s.url || location.href ) + "" )
|
||
.replace( rprotocol, location.protocol + "//" );
|
||
|
||
// Alias method option to type as per ticket #12004
|
||
s.type = options.method || options.type || s.method || s.type;
|
||
|
||
// Extract dataTypes list
|
||
s.dataTypes = ( s.dataType || "*" ).toLowerCase().match( rnothtmlwhite ) || [ "" ];
|
||
|
||
// A cross-domain request is in order when the origin doesn't match the current origin.
|
||
if ( s.crossDomain == null ) {
|
||
urlAnchor = document.createElement( "a" );
|
||
|
||
// Support: IE <=8 - 11, Edge 12 - 13
|
||
// IE throws exception on accessing the href property if url is malformed,
|
||
// e.g. http://example.com:80x/
|
||
try {
|
||
urlAnchor.href = s.url;
|
||
|
||
// Support: IE <=8 - 11 only
|
||
// Anchor's host property isn't correctly set when s.url is relative
|
||
urlAnchor.href = urlAnchor.href;
|
||
s.crossDomain = originAnchor.protocol + "//" + originAnchor.host !==
|
||
urlAnchor.protocol + "//" + urlAnchor.host;
|
||
} catch ( e ) {
|
||
|
||
// If there is an error parsing the URL, assume it is crossDomain,
|
||
// it can be rejected by the transport if it is invalid
|
||
s.crossDomain = true;
|
||
}
|
||
}
|
||
|
||
// Convert data if not already a string
|
||
if ( s.data && s.processData && typeof s.data !== "string" ) {
|
||
s.data = jQuery.param( s.data, s.traditional );
|
||
}
|
||
|
||
// Apply prefilters
|
||
inspectPrefiltersOrTransports( prefilters, s, options, jqXHR );
|
||
|
||
// If request was aborted inside a prefilter, stop there
|
||
if ( completed ) {
|
||
return jqXHR;
|
||
}
|
||
|
||
// We can fire global events as of now if asked to
|
||
// Don't fire events if jQuery.event is undefined in an AMD-usage scenario (#15118)
|
||
fireGlobals = jQuery.event && s.global;
|
||
|
||
// Watch for a new set of requests
|
||
if ( fireGlobals && jQuery.active++ === 0 ) {
|
||
jQuery.event.trigger( "ajaxStart" );
|
||
}
|
||
|
||
// Uppercase the type
|
||
s.type = s.type.toUpperCase();
|
||
|
||
// Determine if request has content
|
||
s.hasContent = !rnoContent.test( s.type );
|
||
|
||
// Save the URL in case we're toying with the If-Modified-Since
|
||
// and/or If-None-Match header later on
|
||
// Remove hash to simplify url manipulation
|
||
cacheURL = s.url.replace( rhash, "" );
|
||
|
||
// More options handling for requests with no content
|
||
if ( !s.hasContent ) {
|
||
|
||
// Remember the hash so we can put it back
|
||
uncached = s.url.slice( cacheURL.length );
|
||
|
||
// If data is available, append data to url
|
||
if ( s.data ) {
|
||
cacheURL += ( rquery.test( cacheURL ) ? "&" : "?" ) + s.data;
|
||
|
||
// #9682: remove data so that it's not used in an eventual retry
|
||
delete s.data;
|
||
}
|
||
|
||
// Add or update anti-cache param if needed
|
||
if ( s.cache === false ) {
|
||
cacheURL = cacheURL.replace( rantiCache, "$1" );
|
||
uncached = ( rquery.test( cacheURL ) ? "&" : "?" ) + "_=" + ( nonce++ ) + uncached;
|
||
}
|
||
|
||
// Put hash and anti-cache on the URL that will be requested (gh-1732)
|
||
s.url = cacheURL + uncached;
|
||
|
||
// Change '%20' to '+' if this is encoded form body content (gh-2658)
|
||
} else if ( s.data && s.processData &&
|
||
( s.contentType || "" ).indexOf( "application/x-www-form-urlencoded" ) === 0 ) {
|
||
s.data = s.data.replace( r20, "+" );
|
||
}
|
||
|
||
// Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
|
||
if ( s.ifModified ) {
|
||
if ( jQuery.lastModified[ cacheURL ] ) {
|
||
jqXHR.setRequestHeader( "If-Modified-Since", jQuery.lastModified[ cacheURL ] );
|
||
}
|
||
if ( jQuery.etag[ cacheURL ] ) {
|
||
jqXHR.setRequestHeader( "If-None-Match", jQuery.etag[ cacheURL ] );
|
||
}
|
||
}
|
||
|
||
// Set the correct header, if data is being sent
|
||
if ( s.data && s.hasContent && s.contentType !== false || options.contentType ) {
|
||
jqXHR.setRequestHeader( "Content-Type", s.contentType );
|
||
}
|
||
|
||
// Set the Accepts header for the server, depending on the dataType
|
||
jqXHR.setRequestHeader(
|
||
"Accept",
|
||
s.dataTypes[ 0 ] && s.accepts[ s.dataTypes[ 0 ] ] ?
|
||
s.accepts[ s.dataTypes[ 0 ] ] +
|
||
( s.dataTypes[ 0 ] !== "*" ? ", " + allTypes + "; q=0.01" : "" ) :
|
||
s.accepts[ "*" ]
|
||
);
|
||
|
||
// Check for headers option
|
||
for ( i in s.headers ) {
|
||
jqXHR.setRequestHeader( i, s.headers[ i ] );
|
||
}
|
||
|
||
// Allow custom headers/mimetypes and early abort
|
||
if ( s.beforeSend &&
|
||
( s.beforeSend.call( callbackContext, jqXHR, s ) === false || completed ) ) {
|
||
|
||
// Abort if not done already and return
|
||
return jqXHR.abort();
|
||
}
|
||
|
||
// Aborting is no longer a cancellation
|
||
strAbort = "abort";
|
||
|
||
// Install callbacks on deferreds
|
||
completeDeferred.add( s.complete );
|
||
jqXHR.done( s.success );
|
||
jqXHR.fail( s.error );
|
||
|
||
// Get transport
|
||
transport = inspectPrefiltersOrTransports( transports, s, options, jqXHR );
|
||
|
||
// If no transport, we auto-abort
|
||
if ( !transport ) {
|
||
done( -1, "No Transport" );
|
||
} else {
|
||
jqXHR.readyState = 1;
|
||
|
||
// Send global event
|
||
if ( fireGlobals ) {
|
||
globalEventContext.trigger( "ajaxSend", [ jqXHR, s ] );
|
||
}
|
||
|
||
// If request was aborted inside ajaxSend, stop there
|
||
if ( completed ) {
|
||
return jqXHR;
|
||
}
|
||
|
||
// Timeout
|
||
if ( s.async && s.timeout > 0 ) {
|
||
timeoutTimer = window.setTimeout( function() {
|
||
jqXHR.abort( "timeout" );
|
||
}, s.timeout );
|
||
}
|
||
|
||
try {
|
||
completed = false;
|
||
transport.send( requestHeaders, done );
|
||
} catch ( e ) {
|
||
|
||
// Rethrow post-completion exceptions
|
||
if ( completed ) {
|
||
throw e;
|
||
}
|
||
|
||
// Propagate others as results
|
||
done( -1, e );
|
||
}
|
||
}
|
||
|
||
// Callback for when everything is done
|
||
function done( status, nativeStatusText, responses, headers ) {
|
||
var isSuccess, success, error, response, modified,
|
||
statusText = nativeStatusText;
|
||
|
||
// Ignore repeat invocations
|
||
if ( completed ) {
|
||
return;
|
||
}
|
||
|
||
completed = true;
|
||
|
||
// Clear timeout if it exists
|
||
if ( timeoutTimer ) {
|
||
window.clearTimeout( timeoutTimer );
|
||
}
|
||
|
||
// Dereference transport for early garbage collection
|
||
// (no matter how long the jqXHR object will be used)
|
||
transport = undefined;
|
||
|
||
// Cache response headers
|
||
responseHeadersString = headers || "";
|
||
|
||
// Set readyState
|
||
jqXHR.readyState = status > 0 ? 4 : 0;
|
||
|
||
// Determine if successful
|
||
isSuccess = status >= 200 && status < 300 || status === 304;
|
||
|
||
// Get response data
|
||
if ( responses ) {
|
||
response = ajaxHandleResponses( s, jqXHR, responses );
|
||
}
|
||
|
||
// Convert no matter what (that way responseXXX fields are always set)
|
||
response = ajaxConvert( s, response, jqXHR, isSuccess );
|
||
|
||
// If successful, handle type chaining
|
||
if ( isSuccess ) {
|
||
|
||
// Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
|
||
if ( s.ifModified ) {
|
||
modified = jqXHR.getResponseHeader( "Last-Modified" );
|
||
if ( modified ) {
|
||
jQuery.lastModified[ cacheURL ] = modified;
|
||
}
|
||
modified = jqXHR.getResponseHeader( "etag" );
|
||
if ( modified ) {
|
||
jQuery.etag[ cacheURL ] = modified;
|
||
}
|
||
}
|
||
|
||
// if no content
|
||
if ( status === 204 || s.type === "HEAD" ) {
|
||
statusText = "nocontent";
|
||
|
||
// if not modified
|
||
} else if ( status === 304 ) {
|
||
statusText = "notmodified";
|
||
|
||
// If we have data, let's convert it
|
||
} else {
|
||
statusText = response.state;
|
||
success = response.data;
|
||
error = response.error;
|
||
isSuccess = !error;
|
||
}
|
||
} else {
|
||
|
||
// Extract error from statusText and normalize for non-aborts
|
||
error = statusText;
|
||
if ( status || !statusText ) {
|
||
statusText = "error";
|
||
if ( status < 0 ) {
|
||
status = 0;
|
||
}
|
||
}
|
||
}
|
||
|
||
// Set data for the fake xhr object
|
||
jqXHR.status = status;
|
||
jqXHR.statusText = ( nativeStatusText || statusText ) + "";
|
||
|
||
// Success/Error
|
||
if ( isSuccess ) {
|
||
deferred.resolveWith( callbackContext, [ success, statusText, jqXHR ] );
|
||
} else {
|
||
deferred.rejectWith( callbackContext, [ jqXHR, statusText, error ] );
|
||
}
|
||
|
||
// Status-dependent callbacks
|
||
jqXHR.statusCode( statusCode );
|
||
statusCode = undefined;
|
||
|
||
if ( fireGlobals ) {
|
||
globalEventContext.trigger( isSuccess ? "ajaxSuccess" : "ajaxError",
|
||
[ jqXHR, s, isSuccess ? success : error ] );
|
||
}
|
||
|
||
// Complete
|
||
completeDeferred.fireWith( callbackContext, [ jqXHR, statusText ] );
|
||
|
||
if ( fireGlobals ) {
|
||
globalEventContext.trigger( "ajaxComplete", [ jqXHR, s ] );
|
||
|
||
// Handle the global AJAX counter
|
||
if ( !( --jQuery.active ) ) {
|
||
jQuery.event.trigger( "ajaxStop" );
|
||
}
|
||
}
|
||
}
|
||
|
||
return jqXHR;
|
||
},
|
||
|
||
getJSON: function( url, data, callback ) {
|
||
return jQuery.get( url, data, callback, "json" );
|
||
},
|
||
|
||
getScript: function( url, callback ) {
|
||
return jQuery.get( url, undefined, callback, "script" );
|
||
}
|
||
} );
|
||
|
||
jQuery.each( [ "get", "post" ], function( i, method ) {
|
||
jQuery[ method ] = function( url, data, callback, type ) {
|
||
|
||
// Shift arguments if data argument was omitted
|
||
if ( jQuery.isFunction( data ) ) {
|
||
type = type || callback;
|
||
callback = data;
|
||
data = undefined;
|
||
}
|
||
|
||
// The url can be an options object (which then must have .url)
|
||
return jQuery.ajax( jQuery.extend( {
|
||
url: url,
|
||
type: method,
|
||
dataType: type,
|
||
data: data,
|
||
success: callback
|
||
}, jQuery.isPlainObject( url ) && url ) );
|
||
};
|
||
} );
|
||
|
||
|
||
jQuery._evalUrl = function( url ) {
|
||
return jQuery.ajax( {
|
||
url: url,
|
||
|
||
// Make this explicit, since user can override this through ajaxSetup (#11264)
|
||
type: "GET",
|
||
dataType: "script",
|
||
cache: true,
|
||
async: false,
|
||
global: false,
|
||
"throws": true
|
||
} );
|
||
};
|
||
|
||
|
||
jQuery.fn.extend( {
|
||
wrapAll: function( html ) {
|
||
var wrap;
|
||
|
||
if ( this[ 0 ] ) {
|
||
if ( jQuery.isFunction( html ) ) {
|
||
html = html.call( this[ 0 ] );
|
||
}
|
||
|
||
// The elements to wrap the target around
|
||
wrap = jQuery( html, this[ 0 ].ownerDocument ).eq( 0 ).clone( true );
|
||
|
||
if ( this[ 0 ].parentNode ) {
|
||
wrap.insertBefore( this[ 0 ] );
|
||
}
|
||
|
||
wrap.map( function() {
|
||
var elem = this;
|
||
|
||
while ( elem.firstElementChild ) {
|
||
elem = elem.firstElementChild;
|
||
}
|
||
|
||
return elem;
|
||
} ).append( this );
|
||
}
|
||
|
||
return this;
|
||
},
|
||
|
||
wrapInner: function( html ) {
|
||
if ( jQuery.isFunction( html ) ) {
|
||
return this.each( function( i ) {
|
||
jQuery( this ).wrapInner( html.call( this, i ) );
|
||
} );
|
||
}
|
||
|
||
return this.each( function() {
|
||
var self = jQuery( this ),
|
||
contents = self.contents();
|
||
|
||
if ( contents.length ) {
|
||
contents.wrapAll( html );
|
||
|
||
} else {
|
||
self.append( html );
|
||
}
|
||
} );
|
||
},
|
||
|
||
wrap: function( html ) {
|
||
var isFunction = jQuery.isFunction( html );
|
||
|
||
return this.each( function( i ) {
|
||
jQuery( this ).wrapAll( isFunction ? html.call( this, i ) : html );
|
||
} );
|
||
},
|
||
|
||
unwrap: function( selector ) {
|
||
this.parent( selector ).not( "body" ).each( function() {
|
||
jQuery( this ).replaceWith( this.childNodes );
|
||
} );
|
||
return this;
|
||
}
|
||
} );
|
||
|
||
|
||
jQuery.expr.pseudos.hidden = function( elem ) {
|
||
return !jQuery.expr.pseudos.visible( elem );
|
||
};
|
||
jQuery.expr.pseudos.visible = function( elem ) {
|
||
return !!( elem.offsetWidth || elem.offsetHeight || elem.getClientRects().length );
|
||
};
|
||
|
||
|
||
|
||
|
||
jQuery.ajaxSettings.xhr = function() {
|
||
try {
|
||
return new window.XMLHttpRequest();
|
||
} catch ( e ) {}
|
||
};
|
||
|
||
var xhrSuccessStatus = {
|
||
|
||
// File protocol always yields status code 0, assume 200
|
||
0: 200,
|
||
|
||
// Support: IE <=9 only
|
||
// #1450: sometimes IE returns 1223 when it should be 204
|
||
1223: 204
|
||
},
|
||
xhrSupported = jQuery.ajaxSettings.xhr();
|
||
|
||
support.cors = !!xhrSupported && ( "withCredentials" in xhrSupported );
|
||
support.ajax = xhrSupported = !!xhrSupported;
|
||
|
||
jQuery.ajaxTransport( function( options ) {
|
||
var callback, errorCallback;
|
||
|
||
// Cross domain only allowed if supported through XMLHttpRequest
|
||
if ( support.cors || xhrSupported && !options.crossDomain ) {
|
||
return {
|
||
send: function( headers, complete ) {
|
||
var i,
|
||
xhr = options.xhr();
|
||
|
||
xhr.open(
|
||
options.type,
|
||
options.url,
|
||
options.async,
|
||
options.username,
|
||
options.password
|
||
);
|
||
|
||
// Apply custom fields if provided
|
||
if ( options.xhrFields ) {
|
||
for ( i in options.xhrFields ) {
|
||
xhr[ i ] = options.xhrFields[ i ];
|
||
}
|
||
}
|
||
|
||
// Override mime type if needed
|
||
if ( options.mimeType && xhr.overrideMimeType ) {
|
||
xhr.overrideMimeType( options.mimeType );
|
||
}
|
||
|
||
// X-Requested-With header
|
||
// For cross-domain requests, seeing as conditions for a preflight are
|
||
// akin to a jigsaw puzzle, we simply never set it to be sure.
|
||
// (it can always be set on a per-request basis or even using ajaxSetup)
|
||
// For same-domain requests, won't change header if already provided.
|
||
if ( !options.crossDomain && !headers[ "X-Requested-With" ] ) {
|
||
headers[ "X-Requested-With" ] = "XMLHttpRequest";
|
||
}
|
||
|
||
// Set headers
|
||
for ( i in headers ) {
|
||
xhr.setRequestHeader( i, headers[ i ] );
|
||
}
|
||
|
||
// Callback
|
||
callback = function( type ) {
|
||
return function() {
|
||
if ( callback ) {
|
||
callback = errorCallback = xhr.onload =
|
||
xhr.onerror = xhr.onabort = xhr.onreadystatechange = null;
|
||
|
||
if ( type === "abort" ) {
|
||
xhr.abort();
|
||
} else if ( type === "error" ) {
|
||
|
||
// Support: IE <=9 only
|
||
// On a manual native abort, IE9 throws
|
||
// errors on any property access that is not readyState
|
||
if ( typeof xhr.status !== "number" ) {
|
||
complete( 0, "error" );
|
||
} else {
|
||
complete(
|
||
|
||
// File: protocol always yields status 0; see #8605, #14207
|
||
xhr.status,
|
||
xhr.statusText
|
||
);
|
||
}
|
||
} else {
|
||
complete(
|
||
xhrSuccessStatus[ xhr.status ] || xhr.status,
|
||
xhr.statusText,
|
||
|
||
// Support: IE <=9 only
|
||
// IE9 has no XHR2 but throws on binary (trac-11426)
|
||
// For XHR2 non-text, let the caller handle it (gh-2498)
|
||
( xhr.responseType || "text" ) !== "text" ||
|
||
typeof xhr.responseText !== "string" ?
|
||
{ binary: xhr.response } :
|
||
{ text: xhr.responseText },
|
||
xhr.getAllResponseHeaders()
|
||
);
|
||
}
|
||
}
|
||
};
|
||
};
|
||
|
||
// Listen to events
|
||
xhr.onload = callback();
|
||
errorCallback = xhr.onerror = callback( "error" );
|
||
|
||
// Support: IE 9 only
|
||
// Use onreadystatechange to replace onabort
|
||
// to handle uncaught aborts
|
||
if ( xhr.onabort !== undefined ) {
|
||
xhr.onabort = errorCallback;
|
||
} else {
|
||
xhr.onreadystatechange = function() {
|
||
|
||
// Check readyState before timeout as it changes
|
||
if ( xhr.readyState === 4 ) {
|
||
|
||
// Allow onerror to be called first,
|
||
// but that will not handle a native abort
|
||
// Also, save errorCallback to a variable
|
||
// as xhr.onerror cannot be accessed
|
||
window.setTimeout( function() {
|
||
if ( callback ) {
|
||
errorCallback();
|
||
}
|
||
} );
|
||
}
|
||
};
|
||
}
|
||
|
||
// Create the abort callback
|
||
callback = callback( "abort" );
|
||
|
||
try {
|
||
|
||
// Do send the request (this may raise an exception)
|
||
xhr.send( options.hasContent && options.data || null );
|
||
} catch ( e ) {
|
||
|
||
// #14683: Only rethrow if this hasn't been notified as an error yet
|
||
if ( callback ) {
|
||
throw e;
|
||
}
|
||
}
|
||
},
|
||
|
||
abort: function() {
|
||
if ( callback ) {
|
||
callback();
|
||
}
|
||
}
|
||
};
|
||
}
|
||
} );
|
||
|
||
|
||
|
||
|
||
// Prevent auto-execution of scripts when no explicit dataType was provided (See gh-2432)
|
||
jQuery.ajaxPrefilter( function( s ) {
|
||
if ( s.crossDomain ) {
|
||
s.contents.script = false;
|
||
}
|
||
} );
|
||
|
||
// Install script dataType
|
||
jQuery.ajaxSetup( {
|
||
accepts: {
|
||
script: "text/javascript, application/javascript, " +
|
||
"application/ecmascript, application/x-ecmascript"
|
||
},
|
||
contents: {
|
||
script: /\b(?:java|ecma)script\b/
|
||
},
|
||
converters: {
|
||
"text script": function( text ) {
|
||
jQuery.globalEval( text );
|
||
return text;
|
||
}
|
||
}
|
||
} );
|
||
|
||
// Handle cache's special case and crossDomain
|
||
jQuery.ajaxPrefilter( "script", function( s ) {
|
||
if ( s.cache === undefined ) {
|
||
s.cache = false;
|
||
}
|
||
if ( s.crossDomain ) {
|
||
s.type = "GET";
|
||
}
|
||
} );
|
||
|
||
// Bind script tag hack transport
|
||
jQuery.ajaxTransport( "script", function( s ) {
|
||
|
||
// This transport only deals with cross domain requests
|
||
if ( s.crossDomain ) {
|
||
var script, callback;
|
||
return {
|
||
send: function( _, complete ) {
|
||
script = jQuery( "<script>" ).prop( {
|
||
charset: s.scriptCharset,
|
||
src: s.url
|
||
} ).on(
|
||
"load error",
|
||
callback = function( evt ) {
|
||
script.remove();
|
||
callback = null;
|
||
if ( evt ) {
|
||
complete( evt.type === "error" ? 404 : 200, evt.type );
|
||
}
|
||
}
|
||
);
|
||
|
||
// Use native DOM manipulation to avoid our domManip AJAX trickery
|
||
document.head.appendChild( script[ 0 ] );
|
||
},
|
||
abort: function() {
|
||
if ( callback ) {
|
||
callback();
|
||
}
|
||
}
|
||
};
|
||
}
|
||
} );
|
||
|
||
|
||
|
||
|
||
var oldCallbacks = [],
|
||
rjsonp = /(=)\?(?=&|$)|\?\?/;
|
||
|
||
// Default jsonp settings
|
||
jQuery.ajaxSetup( {
|
||
jsonp: "callback",
|
||
jsonpCallback: function() {
|
||
var callback = oldCallbacks.pop() || ( jQuery.expando + "_" + ( nonce++ ) );
|
||
this[ callback ] = true;
|
||
return callback;
|
||
}
|
||
} );
|
||
|
||
// Detect, normalize options and install callbacks for jsonp requests
|
||
jQuery.ajaxPrefilter( "json jsonp", function( s, originalSettings, jqXHR ) {
|
||
|
||
var callbackName, overwritten, responseContainer,
|
||
jsonProp = s.jsonp !== false && ( rjsonp.test( s.url ) ?
|
||
"url" :
|
||
typeof s.data === "string" &&
|
||
( s.contentType || "" )
|
||
.indexOf( "application/x-www-form-urlencoded" ) === 0 &&
|
||
rjsonp.test( s.data ) && "data"
|
||
);
|
||
|
||
// Handle iff the expected data type is "jsonp" or we have a parameter to set
|
||
if ( jsonProp || s.dataTypes[ 0 ] === "jsonp" ) {
|
||
|
||
// Get callback name, remembering preexisting value associated with it
|
||
callbackName = s.jsonpCallback = jQuery.isFunction( s.jsonpCallback ) ?
|
||
s.jsonpCallback() :
|
||
s.jsonpCallback;
|
||
|
||
// Insert callback into url or form data
|
||
if ( jsonProp ) {
|
||
s[ jsonProp ] = s[ jsonProp ].replace( rjsonp, "$1" + callbackName );
|
||
} else if ( s.jsonp !== false ) {
|
||
s.url += ( rquery.test( s.url ) ? "&" : "?" ) + s.jsonp + "=" + callbackName;
|
||
}
|
||
|
||
// Use data converter to retrieve json after script execution
|
||
s.converters[ "script json" ] = function() {
|
||
if ( !responseContainer ) {
|
||
jQuery.error( callbackName + " was not called" );
|
||
}
|
||
return responseContainer[ 0 ];
|
||
};
|
||
|
||
// Force json dataType
|
||
s.dataTypes[ 0 ] = "json";
|
||
|
||
// Install callback
|
||
overwritten = window[ callbackName ];
|
||
window[ callbackName ] = function() {
|
||
responseContainer = arguments;
|
||
};
|
||
|
||
// Clean-up function (fires after converters)
|
||
jqXHR.always( function() {
|
||
|
||
// If previous value didn't exist - remove it
|
||
if ( overwritten === undefined ) {
|
||
jQuery( window ).removeProp( callbackName );
|
||
|
||
// Otherwise restore preexisting value
|
||
} else {
|
||
window[ callbackName ] = overwritten;
|
||
}
|
||
|
||
// Save back as free
|
||
if ( s[ callbackName ] ) {
|
||
|
||
// Make sure that re-using the options doesn't screw things around
|
||
s.jsonpCallback = originalSettings.jsonpCallback;
|
||
|
||
// Save the callback name for future use
|
||
oldCallbacks.push( callbackName );
|
||
}
|
||
|
||
// Call if it was a function and we have a response
|
||
if ( responseContainer && jQuery.isFunction( overwritten ) ) {
|
||
overwritten( responseContainer[ 0 ] );
|
||
}
|
||
|
||
responseContainer = overwritten = undefined;
|
||
} );
|
||
|
||
// Delegate to script
|
||
return "script";
|
||
}
|
||
} );
|
||
|
||
|
||
|
||
|
||
// Support: Safari 8 only
|
||
// In Safari 8 documents created via document.implementation.createHTMLDocument
|
||
// collapse sibling forms: the second one becomes a child of the first one.
|
||
// Because of that, this security measure has to be disabled in Safari 8.
|
||
// https://bugs.webkit.org/show_bug.cgi?id=137337
|
||
support.createHTMLDocument = ( function() {
|
||
var body = document.implementation.createHTMLDocument( "" ).body;
|
||
body.innerHTML = "<form></form><form></form>";
|
||
return body.childNodes.length === 2;
|
||
} )();
|
||
|
||
|
||
// Argument "data" should be string of html
|
||
// context (optional): If specified, the fragment will be created in this context,
|
||
// defaults to document
|
||
// keepScripts (optional): If true, will include scripts passed in the html string
|
||
jQuery.parseHTML = function( data, context, keepScripts ) {
|
||
if ( typeof data !== "string" ) {
|
||
return [];
|
||
}
|
||
if ( typeof context === "boolean" ) {
|
||
keepScripts = context;
|
||
context = false;
|
||
}
|
||
|
||
var base, parsed, scripts;
|
||
|
||
if ( !context ) {
|
||
|
||
// Stop scripts or inline event handlers from being executed immediately
|
||
// by using document.implementation
|
||
if ( support.createHTMLDocument ) {
|
||
context = document.implementation.createHTMLDocument( "" );
|
||
|
||
// Set the base href for the created document
|
||
// so any parsed elements with URLs
|
||
// are based on the document's URL (gh-2965)
|
||
base = context.createElement( "base" );
|
||
base.href = document.location.href;
|
||
context.head.appendChild( base );
|
||
} else {
|
||
context = document;
|
||
}
|
||
}
|
||
|
||
parsed = rsingleTag.exec( data );
|
||
scripts = !keepScripts && [];
|
||
|
||
// Single tag
|
||
if ( parsed ) {
|
||
return [ context.createElement( parsed[ 1 ] ) ];
|
||
}
|
||
|
||
parsed = buildFragment( [ data ], context, scripts );
|
||
|
||
if ( scripts && scripts.length ) {
|
||
jQuery( scripts ).remove();
|
||
}
|
||
|
||
return jQuery.merge( [], parsed.childNodes );
|
||
};
|
||
|
||
|
||
/**
|
||
* Load a url into a page
|
||
*/
|
||
jQuery.fn.load = function( url, params, callback ) {
|
||
var selector, type, response,
|
||
self = this,
|
||
off = url.indexOf( " " );
|
||
|
||
if ( off > -1 ) {
|
||
selector = stripAndCollapse( url.slice( off ) );
|
||
url = url.slice( 0, off );
|
||
}
|
||
|
||
// If it's a function
|
||
if ( jQuery.isFunction( params ) ) {
|
||
|
||
// We assume that it's the callback
|
||
callback = params;
|
||
params = undefined;
|
||
|
||
// Otherwise, build a param string
|
||
} else if ( params && typeof params === "object" ) {
|
||
type = "POST";
|
||
}
|
||
|
||
// If we have elements to modify, make the request
|
||
if ( self.length > 0 ) {
|
||
jQuery.ajax( {
|
||
url: url,
|
||
|
||
// If "type" variable is undefined, then "GET" method will be used.
|
||
// Make value of this field explicit since
|
||
// user can override it through ajaxSetup method
|
||
type: type || "GET",
|
||
dataType: "html",
|
||
data: params
|
||
} ).done( function( responseText ) {
|
||
|
||
// Save response for use in complete callback
|
||
response = arguments;
|
||
|
||
self.html( selector ?
|
||
|
||
// If a selector was specified, locate the right elements in a dummy div
|
||
// Exclude scripts to avoid IE 'Permission Denied' errors
|
||
jQuery( "<div>" ).append( jQuery.parseHTML( responseText ) ).find( selector ) :
|
||
|
||
// Otherwise use the full result
|
||
responseText );
|
||
|
||
// If the request succeeds, this function gets "data", "status", "jqXHR"
|
||
// but they are ignored because response was set above.
|
||
// If it fails, this function gets "jqXHR", "status", "error"
|
||
} ).always( callback && function( jqXHR, status ) {
|
||
self.each( function() {
|
||
callback.apply( this, response || [ jqXHR.responseText, status, jqXHR ] );
|
||
} );
|
||
} );
|
||
}
|
||
|
||
return this;
|
||
};
|
||
|
||
|
||
|
||
|
||
// Attach a bunch of functions for handling common AJAX events
|
||
jQuery.each( [
|
||
"ajaxStart",
|
||
"ajaxStop",
|
||
"ajaxComplete",
|
||
"ajaxError",
|
||
"ajaxSuccess",
|
||
"ajaxSend"
|
||
], function( i, type ) {
|
||
jQuery.fn[ type ] = function( fn ) {
|
||
return this.on( type, fn );
|
||
};
|
||
} );
|
||
|
||
|
||
|
||
|
||
jQuery.expr.pseudos.animated = function( elem ) {
|
||
return jQuery.grep( jQuery.timers, function( fn ) {
|
||
return elem === fn.elem;
|
||
} ).length;
|
||
};
|
||
|
||
|
||
|
||
|
||
jQuery.offset = {
|
||
setOffset: function( elem, options, i ) {
|
||
var curPosition, curLeft, curCSSTop, curTop, curOffset, curCSSLeft, calculatePosition,
|
||
position = jQuery.css( elem, "position" ),
|
||
curElem = jQuery( elem ),
|
||
props = {};
|
||
|
||
// Set position first, in-case top/left are set even on static elem
|
||
if ( position === "static" ) {
|
||
elem.style.position = "relative";
|
||
}
|
||
|
||
curOffset = curElem.offset();
|
||
curCSSTop = jQuery.css( elem, "top" );
|
||
curCSSLeft = jQuery.css( elem, "left" );
|
||
calculatePosition = ( position === "absolute" || position === "fixed" ) &&
|
||
( curCSSTop + curCSSLeft ).indexOf( "auto" ) > -1;
|
||
|
||
// Need to be able to calculate position if either
|
||
// top or left is auto and position is either absolute or fixed
|
||
if ( calculatePosition ) {
|
||
curPosition = curElem.position();
|
||
curTop = curPosition.top;
|
||
curLeft = curPosition.left;
|
||
|
||
} else {
|
||
curTop = parseFloat( curCSSTop ) || 0;
|
||
curLeft = parseFloat( curCSSLeft ) || 0;
|
||
}
|
||
|
||
if ( jQuery.isFunction( options ) ) {
|
||
|
||
// Use jQuery.extend here to allow modification of coordinates argument (gh-1848)
|
||
options = options.call( elem, i, jQuery.extend( {}, curOffset ) );
|
||
}
|
||
|
||
if ( options.top != null ) {
|
||
props.top = ( options.top - curOffset.top ) + curTop;
|
||
}
|
||
if ( options.left != null ) {
|
||
props.left = ( options.left - curOffset.left ) + curLeft;
|
||
}
|
||
|
||
if ( "using" in options ) {
|
||
options.using.call( elem, props );
|
||
|
||
} else {
|
||
curElem.css( props );
|
||
}
|
||
}
|
||
};
|
||
|
||
jQuery.fn.extend( {
|
||
offset: function( options ) {
|
||
|
||
// Preserve chaining for setter
|
||
if ( arguments.length ) {
|
||
return options === undefined ?
|
||
this :
|
||
this.each( function( i ) {
|
||
jQuery.offset.setOffset( this, options, i );
|
||
} );
|
||
}
|
||
|
||
var doc, docElem, rect, win,
|
||
elem = this[ 0 ];
|
||
|
||
if ( !elem ) {
|
||
return;
|
||
}
|
||
|
||
// Return zeros for disconnected and hidden (display: none) elements (gh-2310)
|
||
// Support: IE <=11 only
|
||
// Running getBoundingClientRect on a
|
||
// disconnected node in IE throws an error
|
||
if ( !elem.getClientRects().length ) {
|
||
return { top: 0, left: 0 };
|
||
}
|
||
|
||
rect = elem.getBoundingClientRect();
|
||
|
||
doc = elem.ownerDocument;
|
||
docElem = doc.documentElement;
|
||
win = doc.defaultView;
|
||
|
||
return {
|
||
top: rect.top + win.pageYOffset - docElem.clientTop,
|
||
left: rect.left + win.pageXOffset - docElem.clientLeft
|
||
};
|
||
},
|
||
|
||
position: function() {
|
||
if ( !this[ 0 ] ) {
|
||
return;
|
||
}
|
||
|
||
var offsetParent, offset,
|
||
elem = this[ 0 ],
|
||
parentOffset = { top: 0, left: 0 };
|
||
|
||
// Fixed elements are offset from window (parentOffset = {top:0, left: 0},
|
||
// because it is its only offset parent
|
||
if ( jQuery.css( elem, "position" ) === "fixed" ) {
|
||
|
||
// Assume getBoundingClientRect is there when computed position is fixed
|
||
offset = elem.getBoundingClientRect();
|
||
|
||
} else {
|
||
|
||
// Get *real* offsetParent
|
||
offsetParent = this.offsetParent();
|
||
|
||
// Get correct offsets
|
||
offset = this.offset();
|
||
if ( !nodeName( offsetParent[ 0 ], "html" ) ) {
|
||
parentOffset = offsetParent.offset();
|
||
}
|
||
|
||
// Add offsetParent borders
|
||
parentOffset = {
|
||
top: parentOffset.top + jQuery.css( offsetParent[ 0 ], "borderTopWidth", true ),
|
||
left: parentOffset.left + jQuery.css( offsetParent[ 0 ], "borderLeftWidth", true )
|
||
};
|
||
}
|
||
|
||
// Subtract parent offsets and element margins
|
||
return {
|
||
top: offset.top - parentOffset.top - jQuery.css( elem, "marginTop", true ),
|
||
left: offset.left - parentOffset.left - jQuery.css( elem, "marginLeft", true )
|
||
};
|
||
},
|
||
|
||
// This method will return documentElement in the following cases:
|
||
// 1) For the element inside the iframe without offsetParent, this method will return
|
||
// documentElement of the parent window
|
||
// 2) For the hidden or detached element
|
||
// 3) For body or html element, i.e. in case of the html node - it will return itself
|
||
//
|
||
// but those exceptions were never presented as a real life use-cases
|
||
// and might be considered as more preferable results.
|
||
//
|
||
// This logic, however, is not guaranteed and can change at any point in the future
|
||
offsetParent: function() {
|
||
return this.map( function() {
|
||
var offsetParent = this.offsetParent;
|
||
|
||
while ( offsetParent && jQuery.css( offsetParent, "position" ) === "static" ) {
|
||
offsetParent = offsetParent.offsetParent;
|
||
}
|
||
|
||
return offsetParent || documentElement;
|
||
} );
|
||
}
|
||
} );
|
||
|
||
// Create scrollLeft and scrollTop methods
|
||
jQuery.each( { scrollLeft: "pageXOffset", scrollTop: "pageYOffset" }, function( method, prop ) {
|
||
var top = "pageYOffset" === prop;
|
||
|
||
jQuery.fn[ method ] = function( val ) {
|
||
return access( this, function( elem, method, val ) {
|
||
|
||
// Coalesce documents and windows
|
||
var win;
|
||
if ( jQuery.isWindow( elem ) ) {
|
||
win = elem;
|
||
} else if ( elem.nodeType === 9 ) {
|
||
win = elem.defaultView;
|
||
}
|
||
|
||
if ( val === undefined ) {
|
||
return win ? win[ prop ] : elem[ method ];
|
||
}
|
||
|
||
if ( win ) {
|
||
win.scrollTo(
|
||
!top ? val : win.pageXOffset,
|
||
top ? val : win.pageYOffset
|
||
);
|
||
|
||
} else {
|
||
elem[ method ] = val;
|
||
}
|
||
}, method, val, arguments.length );
|
||
};
|
||
} );
|
||
|
||
// Support: Safari <=7 - 9.1, Chrome <=37 - 49
|
||
// Add the top/left cssHooks using jQuery.fn.position
|
||
// Webkit bug: https://bugs.webkit.org/show_bug.cgi?id=29084
|
||
// Blink bug: https://bugs.chromium.org/p/chromium/issues/detail?id=589347
|
||
// getComputedStyle returns percent when specified for top/left/bottom/right;
|
||
// rather than make the css module depend on the offset module, just check for it here
|
||
jQuery.each( [ "top", "left" ], function( i, prop ) {
|
||
jQuery.cssHooks[ prop ] = addGetHookIf( support.pixelPosition,
|
||
function( elem, computed ) {
|
||
if ( computed ) {
|
||
computed = curCSS( elem, prop );
|
||
|
||
// If curCSS returns percentage, fallback to offset
|
||
return rnumnonpx.test( computed ) ?
|
||
jQuery( elem ).position()[ prop ] + "px" :
|
||
computed;
|
||
}
|
||
}
|
||
);
|
||
} );
|
||
|
||
|
||
// Create innerHeight, innerWidth, height, width, outerHeight and outerWidth methods
|
||
jQuery.each( { Height: "height", Width: "width" }, function( name, type ) {
|
||
jQuery.each( { padding: "inner" + name, content: type, "": "outer" + name },
|
||
function( defaultExtra, funcName ) {
|
||
|
||
// Margin is only for outerHeight, outerWidth
|
||
jQuery.fn[ funcName ] = function( margin, value ) {
|
||
var chainable = arguments.length && ( defaultExtra || typeof margin !== "boolean" ),
|
||
extra = defaultExtra || ( margin === true || value === true ? "margin" : "border" );
|
||
|
||
return access( this, function( elem, type, value ) {
|
||
var doc;
|
||
|
||
if ( jQuery.isWindow( elem ) ) {
|
||
|
||
// $( window ).outerWidth/Height return w/h including scrollbars (gh-1729)
|
||
return funcName.indexOf( "outer" ) === 0 ?
|
||
elem[ "inner" + name ] :
|
||
elem.document.documentElement[ "client" + name ];
|
||
}
|
||
|
||
// Get document width or height
|
||
if ( elem.nodeType === 9 ) {
|
||
doc = elem.documentElement;
|
||
|
||
// Either scroll[Width/Height] or offset[Width/Height] or client[Width/Height],
|
||
// whichever is greatest
|
||
return Math.max(
|
||
elem.body[ "scroll" + name ], doc[ "scroll" + name ],
|
||
elem.body[ "offset" + name ], doc[ "offset" + name ],
|
||
doc[ "client" + name ]
|
||
);
|
||
}
|
||
|
||
return value === undefined ?
|
||
|
||
// Get width or height on the element, requesting but not forcing parseFloat
|
||
jQuery.css( elem, type, extra ) :
|
||
|
||
// Set width or height on the element
|
||
jQuery.style( elem, type, value, extra );
|
||
}, type, chainable ? margin : undefined, chainable );
|
||
};
|
||
} );
|
||
} );
|
||
|
||
|
||
jQuery.fn.extend( {
|
||
|
||
bind: function( types, data, fn ) {
|
||
return this.on( types, null, data, fn );
|
||
},
|
||
unbind: function( types, fn ) {
|
||
return this.off( types, null, fn );
|
||
},
|
||
|
||
delegate: function( selector, types, data, fn ) {
|
||
return this.on( types, selector, data, fn );
|
||
},
|
||
undelegate: function( selector, types, fn ) {
|
||
|
||
// ( namespace ) or ( selector, types [, fn] )
|
||
return arguments.length === 1 ?
|
||
this.off( selector, "**" ) :
|
||
this.off( types, selector || "**", fn );
|
||
}
|
||
} );
|
||
|
||
jQuery.holdReady = function( hold ) {
|
||
if ( hold ) {
|
||
jQuery.readyWait++;
|
||
} else {
|
||
jQuery.ready( true );
|
||
}
|
||
};
|
||
jQuery.isArray = Array.isArray;
|
||
jQuery.parseJSON = JSON.parse;
|
||
jQuery.nodeName = nodeName;
|
||
|
||
|
||
|
||
|
||
// Register as a named AMD module, since jQuery can be concatenated with other
|
||
// files that may use define, but not via a proper concatenation script that
|
||
// understands anonymous AMD modules. A named AMD is safest and most robust
|
||
// way to register. Lowercase jquery is used because AMD module names are
|
||
// derived from file names, and jQuery is normally delivered in a lowercase
|
||
// file name. Do this after creating the global so that if an AMD module wants
|
||
// to call noConflict to hide this version of jQuery, it will work.
|
||
|
||
// Note that for maximum portability, libraries that are not jQuery should
|
||
// declare themselves as anonymous modules, and avoid setting a global if an
|
||
// AMD loader is present. jQuery is a special case. For more information, see
|
||
// https://github.com/jrburke/requirejs/wiki/Updating-existing-libraries#wiki-anon
|
||
|
||
if ( true ) {
|
||
!(__WEBPACK_AMD_DEFINE_ARRAY__ = [], __WEBPACK_AMD_DEFINE_RESULT__ = function() {
|
||
return jQuery;
|
||
}.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__),
|
||
__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
|
||
}
|
||
|
||
|
||
|
||
|
||
var
|
||
|
||
// Map over jQuery in case of overwrite
|
||
_jQuery = window.jQuery,
|
||
|
||
// Map over the $ in case of overwrite
|
||
_$ = window.$;
|
||
|
||
jQuery.noConflict = function( deep ) {
|
||
if ( window.$ === jQuery ) {
|
||
window.$ = _$;
|
||
}
|
||
|
||
if ( deep && window.jQuery === jQuery ) {
|
||
window.jQuery = _jQuery;
|
||
}
|
||
|
||
return jQuery;
|
||
};
|
||
|
||
// Expose jQuery and $ identifiers, even in AMD
|
||
// (#7102#comment:10, https://github.com/jquery/jquery/pull/557)
|
||
// and CommonJS for browser emulators (#13566)
|
||
if ( !noGlobal ) {
|
||
window.jQuery = window.$ = jQuery;
|
||
}
|
||
|
||
|
||
|
||
|
||
return jQuery;
|
||
} );
|
||
|
||
|
||
/***/ }),
|
||
/* 4 */
|
||
/***/ (function(module, exports) {
|
||
|
||
var g;
|
||
|
||
// This works in non-strict mode
|
||
g = (function() {
|
||
return this;
|
||
})();
|
||
|
||
try {
|
||
// This works if eval is allowed (see CSP)
|
||
g = g || Function("return this")() || (1,eval)("this");
|
||
} catch(e) {
|
||
// This works if the window reference is available
|
||
if(typeof window === "object")
|
||
g = window;
|
||
}
|
||
|
||
// g can still be undefined, but nothing to do about it...
|
||
// We return undefined, instead of nothing here, so it's
|
||
// easier to handle this case. if(!global) { ...}
|
||
|
||
module.exports = g;
|
||
|
||
|
||
/***/ }),
|
||
/* 5 */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
__webpack_require__(6);
|
||
__webpack_require__(59);
|
||
__webpack_require__(60);
|
||
module.exports = __webpack_require__(61);
|
||
|
||
|
||
/***/ }),
|
||
/* 6 */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
|
||
/**
|
||
* First we will load all of this project's JavaScript dependencies which
|
||
* include Vue and Vue Resource. This gives a great starting point for
|
||
* building robust, powerful web applications using Vue and Laravel.
|
||
*/
|
||
__webpack_require__(7);
|
||
__webpack_require__(8);
|
||
|
||
/**
|
||
* Next, we will create a fresh Vue application instance and attach it to
|
||
* the page. Then, you may begin adding components to this application
|
||
* or customize the JavaScript scaffolding to fit your unique needs.
|
||
*/
|
||
Vue.component('passport-clients', __webpack_require__(15));
|
||
|
||
Vue.component('passport-authorized-clients', __webpack_require__(21));
|
||
|
||
Vue.component('passport-personal-access-tokens', __webpack_require__(26));
|
||
|
||
Vue.component('importer', __webpack_require__(31));
|
||
|
||
// Commented out currently to avoid trying to load vue everywhere.
|
||
// const app = new Vue({
|
||
// el: '#app'
|
||
// });
|
||
|
||
/***/ }),
|
||
/* 7 */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/*! jQuery UI - v1.12.1 - 2017-03-19
|
||
* http://jqueryui.com
|
||
* Includes: widget.js, position.js, data.js, disable-selection.js, focusable.js, form-reset-mixin.js, jquery-1-7.js, keycode.js, labels.js, scroll-parent.js, tabbable.js, unique-id.js, widgets/draggable.js, widgets/droppable.js, widgets/resizable.js, widgets/selectable.js, widgets/sortable.js, widgets/accordion.js, widgets/autocomplete.js, widgets/button.js, widgets/checkboxradio.js, widgets/controlgroup.js, widgets/datepicker.js, widgets/dialog.js, widgets/menu.js, widgets/mouse.js, widgets/progressbar.js, widgets/selectmenu.js, widgets/slider.js, widgets/spinner.js, widgets/tabs.js, widgets/tooltip.js, effect.js, effects/effect-blind.js, effects/effect-bounce.js, effects/effect-clip.js, effects/effect-drop.js, effects/effect-explode.js, effects/effect-fade.js, effects/effect-fold.js, effects/effect-highlight.js, effects/effect-puff.js, effects/effect-pulsate.js, effects/effect-scale.js, effects/effect-shake.js, effects/effect-size.js, effects/effect-slide.js, effects/effect-transfer.js
|
||
* Copyright jQuery Foundation and other contributors; Licensed MIT */
|
||
|
||
(function(t){ true?!(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(3)], __WEBPACK_AMD_DEFINE_FACTORY__ = (t),
|
||
__WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ?
|
||
(__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__),
|
||
__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)):t(jQuery)})(function(t){function e(t){for(var e=t.css("visibility");"inherit"===e;)t=t.parent(),e=t.css("visibility");return"hidden"!==e}function i(t){for(var e,i;t.length&&t[0]!==document;){if(e=t.css("position"),("absolute"===e||"relative"===e||"fixed"===e)&&(i=parseInt(t.css("zIndex"),10),!isNaN(i)&&0!==i))return i;t=t.parent()}return 0}function s(){this._curInst=null,this._keyEvent=!1,this._disabledInputs=[],this._datepickerShowing=!1,this._inDialog=!1,this._mainDivId="ui-datepicker-div",this._inlineClass="ui-datepicker-inline",this._appendClass="ui-datepicker-append",this._triggerClass="ui-datepicker-trigger",this._dialogClass="ui-datepicker-dialog",this._disableClass="ui-datepicker-disabled",this._unselectableClass="ui-datepicker-unselectable",this._currentClass="ui-datepicker-current-day",this._dayOverClass="ui-datepicker-days-cell-over",this.regional=[],this.regional[""]={closeText:"Done",prevText:"Prev",nextText:"Next",currentText:"Today",monthNames:["January","February","March","April","May","June","July","August","September","October","November","December"],monthNamesShort:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],dayNames:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],dayNamesShort:["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],dayNamesMin:["Su","Mo","Tu","We","Th","Fr","Sa"],weekHeader:"Wk",dateFormat:"mm/dd/yy",firstDay:0,isRTL:!1,showMonthAfterYear:!1,yearSuffix:""},this._defaults={showOn:"focus",showAnim:"fadeIn",showOptions:{},defaultDate:null,appendText:"",buttonText:"...",buttonImage:"",buttonImageOnly:!1,hideIfNoPrevNext:!1,navigationAsDateFormat:!1,gotoCurrent:!1,changeMonth:!1,changeYear:!1,yearRange:"c-10:c+10",showOtherMonths:!1,selectOtherMonths:!1,showWeek:!1,calculateWeek:this.iso8601Week,shortYearCutoff:"+10",minDate:null,maxDate:null,duration:"fast",beforeShowDay:null,beforeShow:null,onSelect:null,onChangeMonthYear:null,onClose:null,numberOfMonths:1,showCurrentAtPos:0,stepMonths:1,stepBigMonths:12,altField:"",altFormat:"",constrainInput:!0,showButtonPanel:!1,autoSize:!1,disabled:!1},t.extend(this._defaults,this.regional[""]),this.regional.en=t.extend(!0,{},this.regional[""]),this.regional["en-US"]=t.extend(!0,{},this.regional.en),this.dpDiv=n(t("<div id='"+this._mainDivId+"' class='ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all'></div>"))}function n(e){var i="button, .ui-datepicker-prev, .ui-datepicker-next, .ui-datepicker-calendar td a";return e.on("mouseout",i,function(){t(this).removeClass("ui-state-hover"),-1!==this.className.indexOf("ui-datepicker-prev")&&t(this).removeClass("ui-datepicker-prev-hover"),-1!==this.className.indexOf("ui-datepicker-next")&&t(this).removeClass("ui-datepicker-next-hover")}).on("mouseover",i,o)}function o(){t.datepicker._isDisabledDatepicker(p.inline?p.dpDiv.parent()[0]:p.input[0])||(t(this).parents(".ui-datepicker-calendar").find("a").removeClass("ui-state-hover"),t(this).addClass("ui-state-hover"),-1!==this.className.indexOf("ui-datepicker-prev")&&t(this).addClass("ui-datepicker-prev-hover"),-1!==this.className.indexOf("ui-datepicker-next")&&t(this).addClass("ui-datepicker-next-hover"))}function a(e,i){t.extend(e,i);for(var s in i)null==i[s]&&(e[s]=i[s]);return e}function r(t){return function(){var e=this.element.val();t.apply(this,arguments),this._refresh(),e!==this.element.val()&&this._trigger("change")}}t.ui=t.ui||{},t.ui.version="1.12.1";var h=0,l=Array.prototype.slice;t.cleanData=function(e){return function(i){var s,n,o;for(o=0;null!=(n=i[o]);o++)try{s=t._data(n,"events"),s&&s.remove&&t(n).triggerHandler("remove")}catch(a){}e(i)}}(t.cleanData),t.widget=function(e,i,s){var n,o,a,r={},h=e.split(".")[0];e=e.split(".")[1];var l=h+"-"+e;return s||(s=i,i=t.Widget),t.isArray(s)&&(s=t.extend.apply(null,[{}].concat(s))),t.expr[":"][l.toLowerCase()]=function(e){return!!t.data(e,l)},t[h]=t[h]||{},n=t[h][e],o=t[h][e]=function(t,e){return this._createWidget?(arguments.length&&this._createWidget(t,e),void 0):new o(t,e)},t.extend(o,n,{version:s.version,_proto:t.extend({},s),_childConstructors:[]}),a=new i,a.options=t.widget.extend({},a.options),t.each(s,function(e,s){return t.isFunction(s)?(r[e]=function(){function t(){return i.prototype[e].apply(this,arguments)}function n(t){return i.prototype[e].apply(this,t)}return function(){var e,i=this._super,o=this._superApply;return this._super=t,this._superApply=n,e=s.apply(this,arguments),this._super=i,this._superApply=o,e}}(),void 0):(r[e]=s,void 0)}),o.prototype=t.widget.extend(a,{widgetEventPrefix:n?a.widgetEventPrefix||e:e},r,{constructor:o,namespace:h,widgetName:e,widgetFullName:l}),n?(t.each(n._childConstructors,function(e,i){var s=i.prototype;t.widget(s.namespace+"."+s.widgetName,o,i._proto)}),delete n._childConstructors):i._childConstructors.push(o),t.widget.bridge(e,o),o},t.widget.extend=function(e){for(var i,s,n=l.call(arguments,1),o=0,a=n.length;a>o;o++)for(i in n[o])s=n[o][i],n[o].hasOwnProperty(i)&&void 0!==s&&(e[i]=t.isPlainObject(s)?t.isPlainObject(e[i])?t.widget.extend({},e[i],s):t.widget.extend({},s):s);return e},t.widget.bridge=function(e,i){var s=i.prototype.widgetFullName||e;t.fn[e]=function(n){var o="string"==typeof n,a=l.call(arguments,1),r=this;return o?this.length||"instance"!==n?this.each(function(){var i,o=t.data(this,s);return"instance"===n?(r=o,!1):o?t.isFunction(o[n])&&"_"!==n.charAt(0)?(i=o[n].apply(o,a),i!==o&&void 0!==i?(r=i&&i.jquery?r.pushStack(i.get()):i,!1):void 0):t.error("no such method '"+n+"' for "+e+" widget instance"):t.error("cannot call methods on "+e+" prior to initialization; "+"attempted to call method '"+n+"'")}):r=void 0:(a.length&&(n=t.widget.extend.apply(null,[n].concat(a))),this.each(function(){var e=t.data(this,s);e?(e.option(n||{}),e._init&&e._init()):t.data(this,s,new i(n,this))})),r}},t.Widget=function(){},t.Widget._childConstructors=[],t.Widget.prototype={widgetName:"widget",widgetEventPrefix:"",defaultElement:"<div>",options:{classes:{},disabled:!1,create:null},_createWidget:function(e,i){i=t(i||this.defaultElement||this)[0],this.element=t(i),this.uuid=h++,this.eventNamespace="."+this.widgetName+this.uuid,this.bindings=t(),this.hoverable=t(),this.focusable=t(),this.classesElementLookup={},i!==this&&(t.data(i,this.widgetFullName,this),this._on(!0,this.element,{remove:function(t){t.target===i&&this.destroy()}}),this.document=t(i.style?i.ownerDocument:i.document||i),this.window=t(this.document[0].defaultView||this.document[0].parentWindow)),this.options=t.widget.extend({},this.options,this._getCreateOptions(),e),this._create(),this.options.disabled&&this._setOptionDisabled(this.options.disabled),this._trigger("create",null,this._getCreateEventData()),this._init()},_getCreateOptions:function(){return{}},_getCreateEventData:t.noop,_create:t.noop,_init:t.noop,destroy:function(){var e=this;this._destroy(),t.each(this.classesElementLookup,function(t,i){e._removeClass(i,t)}),this.element.off(this.eventNamespace).removeData(this.widgetFullName),this.widget().off(this.eventNamespace).removeAttr("aria-disabled"),this.bindings.off(this.eventNamespace)},_destroy:t.noop,widget:function(){return this.element},option:function(e,i){var s,n,o,a=e;if(0===arguments.length)return t.widget.extend({},this.options);if("string"==typeof e)if(a={},s=e.split("."),e=s.shift(),s.length){for(n=a[e]=t.widget.extend({},this.options[e]),o=0;s.length-1>o;o++)n[s[o]]=n[s[o]]||{},n=n[s[o]];if(e=s.pop(),1===arguments.length)return void 0===n[e]?null:n[e];n[e]=i}else{if(1===arguments.length)return void 0===this.options[e]?null:this.options[e];a[e]=i}return this._setOptions(a),this},_setOptions:function(t){var e;for(e in t)this._setOption(e,t[e]);return this},_setOption:function(t,e){return"classes"===t&&this._setOptionClasses(e),this.options[t]=e,"disabled"===t&&this._setOptionDisabled(e),this},_setOptionClasses:function(e){var i,s,n;for(i in e)n=this.classesElementLookup[i],e[i]!==this.options.classes[i]&&n&&n.length&&(s=t(n.get()),this._removeClass(n,i),s.addClass(this._classes({element:s,keys:i,classes:e,add:!0})))},_setOptionDisabled:function(t){this._toggleClass(this.widget(),this.widgetFullName+"-disabled",null,!!t),t&&(this._removeClass(this.hoverable,null,"ui-state-hover"),this._removeClass(this.focusable,null,"ui-state-focus"))},enable:function(){return this._setOptions({disabled:!1})},disable:function(){return this._setOptions({disabled:!0})},_classes:function(e){function i(i,o){var a,r;for(r=0;i.length>r;r++)a=n.classesElementLookup[i[r]]||t(),a=e.add?t(t.unique(a.get().concat(e.element.get()))):t(a.not(e.element).get()),n.classesElementLookup[i[r]]=a,s.push(i[r]),o&&e.classes[i[r]]&&s.push(e.classes[i[r]])}var s=[],n=this;return e=t.extend({element:this.element,classes:this.options.classes||{}},e),this._on(e.element,{remove:"_untrackClassesElement"}),e.keys&&i(e.keys.match(/\S+/g)||[],!0),e.extra&&i(e.extra.match(/\S+/g)||[]),s.join(" ")},_untrackClassesElement:function(e){var i=this;t.each(i.classesElementLookup,function(s,n){-1!==t.inArray(e.target,n)&&(i.classesElementLookup[s]=t(n.not(e.target).get()))})},_removeClass:function(t,e,i){return this._toggleClass(t,e,i,!1)},_addClass:function(t,e,i){return this._toggleClass(t,e,i,!0)},_toggleClass:function(t,e,i,s){s="boolean"==typeof s?s:i;var n="string"==typeof t||null===t,o={extra:n?e:i,keys:n?t:e,element:n?this.element:t,add:s};return o.element.toggleClass(this._classes(o),s),this},_on:function(e,i,s){var n,o=this;"boolean"!=typeof e&&(s=i,i=e,e=!1),s?(i=n=t(i),this.bindings=this.bindings.add(i)):(s=i,i=this.element,n=this.widget()),t.each(s,function(s,a){function r(){return e||o.options.disabled!==!0&&!t(this).hasClass("ui-state-disabled")?("string"==typeof a?o[a]:a).apply(o,arguments):void 0}"string"!=typeof a&&(r.guid=a.guid=a.guid||r.guid||t.guid++);var h=s.match(/^([\w:-]*)\s*(.*)$/),l=h[1]+o.eventNamespace,c=h[2];c?n.on(l,c,r):i.on(l,r)})},_off:function(e,i){i=(i||"").split(" ").join(this.eventNamespace+" ")+this.eventNamespace,e.off(i).off(i),this.bindings=t(this.bindings.not(e).get()),this.focusable=t(this.focusable.not(e).get()),this.hoverable=t(this.hoverable.not(e).get())},_delay:function(t,e){function i(){return("string"==typeof t?s[t]:t).apply(s,arguments)}var s=this;return setTimeout(i,e||0)},_hoverable:function(e){this.hoverable=this.hoverable.add(e),this._on(e,{mouseenter:function(e){this._addClass(t(e.currentTarget),null,"ui-state-hover")},mouseleave:function(e){this._removeClass(t(e.currentTarget),null,"ui-state-hover")}})},_focusable:function(e){this.focusable=this.focusable.add(e),this._on(e,{focusin:function(e){this._addClass(t(e.currentTarget),null,"ui-state-focus")},focusout:function(e){this._removeClass(t(e.currentTarget),null,"ui-state-focus")}})},_trigger:function(e,i,s){var n,o,a=this.options[e];if(s=s||{},i=t.Event(i),i.type=(e===this.widgetEventPrefix?e:this.widgetEventPrefix+e).toLowerCase(),i.target=this.element[0],o=i.originalEvent)for(n in o)n in i||(i[n]=o[n]);return this.element.trigger(i,s),!(t.isFunction(a)&&a.apply(this.element[0],[i].concat(s))===!1||i.isDefaultPrevented())}},t.each({show:"fadeIn",hide:"fadeOut"},function(e,i){t.Widget.prototype["_"+e]=function(s,n,o){"string"==typeof n&&(n={effect:n});var a,r=n?n===!0||"number"==typeof n?i:n.effect||i:e;n=n||{},"number"==typeof n&&(n={duration:n}),a=!t.isEmptyObject(n),n.complete=o,n.delay&&s.delay(n.delay),a&&t.effects&&t.effects.effect[r]?s[e](n):r!==e&&s[r]?s[r](n.duration,n.easing,o):s.queue(function(i){t(this)[e](),o&&o.call(s[0]),i()})}}),t.widget,function(){function e(t,e,i){return[parseFloat(t[0])*(u.test(t[0])?e/100:1),parseFloat(t[1])*(u.test(t[1])?i/100:1)]}function i(e,i){return parseInt(t.css(e,i),10)||0}function s(e){var i=e[0];return 9===i.nodeType?{width:e.width(),height:e.height(),offset:{top:0,left:0}}:t.isWindow(i)?{width:e.width(),height:e.height(),offset:{top:e.scrollTop(),left:e.scrollLeft()}}:i.preventDefault?{width:0,height:0,offset:{top:i.pageY,left:i.pageX}}:{width:e.outerWidth(),height:e.outerHeight(),offset:e.offset()}}var n,o=Math.max,a=Math.abs,r=/left|center|right/,h=/top|center|bottom/,l=/[\+\-]\d+(\.[\d]+)?%?/,c=/^\w+/,u=/%$/,d=t.fn.position;t.position={scrollbarWidth:function(){if(void 0!==n)return n;var e,i,s=t("<div style='display:block;position:absolute;width:50px;height:50px;overflow:hidden;'><div style='height:100px;width:auto;'></div></div>"),o=s.children()[0];return t("body").append(s),e=o.offsetWidth,s.css("overflow","scroll"),i=o.offsetWidth,e===i&&(i=s[0].clientWidth),s.remove(),n=e-i},getScrollInfo:function(e){var i=e.isWindow||e.isDocument?"":e.element.css("overflow-x"),s=e.isWindow||e.isDocument?"":e.element.css("overflow-y"),n="scroll"===i||"auto"===i&&e.width<e.element[0].scrollWidth,o="scroll"===s||"auto"===s&&e.height<e.element[0].scrollHeight;return{width:o?t.position.scrollbarWidth():0,height:n?t.position.scrollbarWidth():0}},getWithinInfo:function(e){var i=t(e||window),s=t.isWindow(i[0]),n=!!i[0]&&9===i[0].nodeType,o=!s&&!n;return{element:i,isWindow:s,isDocument:n,offset:o?t(e).offset():{left:0,top:0},scrollLeft:i.scrollLeft(),scrollTop:i.scrollTop(),width:i.outerWidth(),height:i.outerHeight()}}},t.fn.position=function(n){if(!n||!n.of)return d.apply(this,arguments);n=t.extend({},n);var u,p,f,g,m,_,v=t(n.of),b=t.position.getWithinInfo(n.within),y=t.position.getScrollInfo(b),w=(n.collision||"flip").split(" "),k={};return _=s(v),v[0].preventDefault&&(n.at="left top"),p=_.width,f=_.height,g=_.offset,m=t.extend({},g),t.each(["my","at"],function(){var t,e,i=(n[this]||"").split(" ");1===i.length&&(i=r.test(i[0])?i.concat(["center"]):h.test(i[0])?["center"].concat(i):["center","center"]),i[0]=r.test(i[0])?i[0]:"center",i[1]=h.test(i[1])?i[1]:"center",t=l.exec(i[0]),e=l.exec(i[1]),k[this]=[t?t[0]:0,e?e[0]:0],n[this]=[c.exec(i[0])[0],c.exec(i[1])[0]]}),1===w.length&&(w[1]=w[0]),"right"===n.at[0]?m.left+=p:"center"===n.at[0]&&(m.left+=p/2),"bottom"===n.at[1]?m.top+=f:"center"===n.at[1]&&(m.top+=f/2),u=e(k.at,p,f),m.left+=u[0],m.top+=u[1],this.each(function(){var s,r,h=t(this),l=h.outerWidth(),c=h.outerHeight(),d=i(this,"marginLeft"),_=i(this,"marginTop"),x=l+d+i(this,"marginRight")+y.width,C=c+_+i(this,"marginBottom")+y.height,D=t.extend({},m),I=e(k.my,h.outerWidth(),h.outerHeight());"right"===n.my[0]?D.left-=l:"center"===n.my[0]&&(D.left-=l/2),"bottom"===n.my[1]?D.top-=c:"center"===n.my[1]&&(D.top-=c/2),D.left+=I[0],D.top+=I[1],s={marginLeft:d,marginTop:_},t.each(["left","top"],function(e,i){t.ui.position[w[e]]&&t.ui.position[w[e]][i](D,{targetWidth:p,targetHeight:f,elemWidth:l,elemHeight:c,collisionPosition:s,collisionWidth:x,collisionHeight:C,offset:[u[0]+I[0],u[1]+I[1]],my:n.my,at:n.at,within:b,elem:h})}),n.using&&(r=function(t){var e=g.left-D.left,i=e+p-l,s=g.top-D.top,r=s+f-c,u={target:{element:v,left:g.left,top:g.top,width:p,height:f},element:{element:h,left:D.left,top:D.top,width:l,height:c},horizontal:0>i?"left":e>0?"right":"center",vertical:0>r?"top":s>0?"bottom":"middle"};l>p&&p>a(e+i)&&(u.horizontal="center"),c>f&&f>a(s+r)&&(u.vertical="middle"),u.important=o(a(e),a(i))>o(a(s),a(r))?"horizontal":"vertical",n.using.call(this,t,u)}),h.offset(t.extend(D,{using:r}))})},t.ui.position={fit:{left:function(t,e){var i,s=e.within,n=s.isWindow?s.scrollLeft:s.offset.left,a=s.width,r=t.left-e.collisionPosition.marginLeft,h=n-r,l=r+e.collisionWidth-a-n;e.collisionWidth>a?h>0&&0>=l?(i=t.left+h+e.collisionWidth-a-n,t.left+=h-i):t.left=l>0&&0>=h?n:h>l?n+a-e.collisionWidth:n:h>0?t.left+=h:l>0?t.left-=l:t.left=o(t.left-r,t.left)},top:function(t,e){var i,s=e.within,n=s.isWindow?s.scrollTop:s.offset.top,a=e.within.height,r=t.top-e.collisionPosition.marginTop,h=n-r,l=r+e.collisionHeight-a-n;e.collisionHeight>a?h>0&&0>=l?(i=t.top+h+e.collisionHeight-a-n,t.top+=h-i):t.top=l>0&&0>=h?n:h>l?n+a-e.collisionHeight:n:h>0?t.top+=h:l>0?t.top-=l:t.top=o(t.top-r,t.top)}},flip:{left:function(t,e){var i,s,n=e.within,o=n.offset.left+n.scrollLeft,r=n.width,h=n.isWindow?n.scrollLeft:n.offset.left,l=t.left-e.collisionPosition.marginLeft,c=l-h,u=l+e.collisionWidth-r-h,d="left"===e.my[0]?-e.elemWidth:"right"===e.my[0]?e.elemWidth:0,p="left"===e.at[0]?e.targetWidth:"right"===e.at[0]?-e.targetWidth:0,f=-2*e.offset[0];0>c?(i=t.left+d+p+f+e.collisionWidth-r-o,(0>i||a(c)>i)&&(t.left+=d+p+f)):u>0&&(s=t.left-e.collisionPosition.marginLeft+d+p+f-h,(s>0||u>a(s))&&(t.left+=d+p+f))},top:function(t,e){var i,s,n=e.within,o=n.offset.top+n.scrollTop,r=n.height,h=n.isWindow?n.scrollTop:n.offset.top,l=t.top-e.collisionPosition.marginTop,c=l-h,u=l+e.collisionHeight-r-h,d="top"===e.my[1],p=d?-e.elemHeight:"bottom"===e.my[1]?e.elemHeight:0,f="top"===e.at[1]?e.targetHeight:"bottom"===e.at[1]?-e.targetHeight:0,g=-2*e.offset[1];0>c?(s=t.top+p+f+g+e.collisionHeight-r-o,(0>s||a(c)>s)&&(t.top+=p+f+g)):u>0&&(i=t.top-e.collisionPosition.marginTop+p+f+g-h,(i>0||u>a(i))&&(t.top+=p+f+g))}},flipfit:{left:function(){t.ui.position.flip.left.apply(this,arguments),t.ui.position.fit.left.apply(this,arguments)},top:function(){t.ui.position.flip.top.apply(this,arguments),t.ui.position.fit.top.apply(this,arguments)}}}}(),t.ui.position,t.extend(t.expr[":"],{data:t.expr.createPseudo?t.expr.createPseudo(function(e){return function(i){return!!t.data(i,e)}}):function(e,i,s){return!!t.data(e,s[3])}}),t.fn.extend({disableSelection:function(){var t="onselectstart"in document.createElement("div")?"selectstart":"mousedown";return function(){return this.on(t+".ui-disableSelection",function(t){t.preventDefault()})}}(),enableSelection:function(){return this.off(".ui-disableSelection")}}),t.ui.focusable=function(i,s){var n,o,a,r,h,l=i.nodeName.toLowerCase();return"area"===l?(n=i.parentNode,o=n.name,i.href&&o&&"map"===n.nodeName.toLowerCase()?(a=t("img[usemap='#"+o+"']"),a.length>0&&a.is(":visible")):!1):(/^(input|select|textarea|button|object)$/.test(l)?(r=!i.disabled,r&&(h=t(i).closest("fieldset")[0],h&&(r=!h.disabled))):r="a"===l?i.href||s:s,r&&t(i).is(":visible")&&e(t(i)))},t.extend(t.expr[":"],{focusable:function(e){return t.ui.focusable(e,null!=t.attr(e,"tabindex"))}}),t.ui.focusable,t.fn.form=function(){return"string"==typeof this[0].form?this.closest("form"):t(this[0].form)},t.ui.formResetMixin={_formResetHandler:function(){var e=t(this);setTimeout(function(){var i=e.data("ui-form-reset-instances");t.each(i,function(){this.refresh()})})},_bindFormResetHandler:function(){if(this.form=this.element.form(),this.form.length){var t=this.form.data("ui-form-reset-instances")||[];t.length||this.form.on("reset.ui-form-reset",this._formResetHandler),t.push(this),this.form.data("ui-form-reset-instances",t)}},_unbindFormResetHandler:function(){if(this.form.length){var e=this.form.data("ui-form-reset-instances");e.splice(t.inArray(this,e),1),e.length?this.form.data("ui-form-reset-instances",e):this.form.removeData("ui-form-reset-instances").off("reset.ui-form-reset")}}},"1.7"===t.fn.jquery.substring(0,3)&&(t.each(["Width","Height"],function(e,i){function s(e,i,s,o){return t.each(n,function(){i-=parseFloat(t.css(e,"padding"+this))||0,s&&(i-=parseFloat(t.css(e,"border"+this+"Width"))||0),o&&(i-=parseFloat(t.css(e,"margin"+this))||0)}),i}var n="Width"===i?["Left","Right"]:["Top","Bottom"],o=i.toLowerCase(),a={innerWidth:t.fn.innerWidth,innerHeight:t.fn.innerHeight,outerWidth:t.fn.outerWidth,outerHeight:t.fn.outerHeight};t.fn["inner"+i]=function(e){return void 0===e?a["inner"+i].call(this):this.each(function(){t(this).css(o,s(this,e)+"px")})},t.fn["outer"+i]=function(e,n){return"number"!=typeof e?a["outer"+i].call(this,e):this.each(function(){t(this).css(o,s(this,e,!0,n)+"px")})}}),t.fn.addBack=function(t){return this.add(null==t?this.prevObject:this.prevObject.filter(t))}),t.ui.keyCode={BACKSPACE:8,COMMA:188,DELETE:46,DOWN:40,END:35,ENTER:13,ESCAPE:27,HOME:36,LEFT:37,PAGE_DOWN:34,PAGE_UP:33,PERIOD:190,RIGHT:39,SPACE:32,TAB:9,UP:38},t.ui.escapeSelector=function(){var t=/([!"#$%&'()*+,./:;<=>?@[\]^`{|}~])/g;return function(e){return e.replace(t,"\\$1")}}(),t.fn.labels=function(){var e,i,s,n,o;return this[0].labels&&this[0].labels.length?this.pushStack(this[0].labels):(n=this.eq(0).parents("label"),s=this.attr("id"),s&&(e=this.eq(0).parents().last(),o=e.add(e.length?e.siblings():this.siblings()),i="label[for='"+t.ui.escapeSelector(s)+"']",n=n.add(o.find(i).addBack(i))),this.pushStack(n))},t.fn.scrollParent=function(e){var i=this.css("position"),s="absolute"===i,n=e?/(auto|scroll|hidden)/:/(auto|scroll)/,o=this.parents().filter(function(){var e=t(this);return s&&"static"===e.css("position")?!1:n.test(e.css("overflow")+e.css("overflow-y")+e.css("overflow-x"))}).eq(0);return"fixed"!==i&&o.length?o:t(this[0].ownerDocument||document)},t.extend(t.expr[":"],{tabbable:function(e){var i=t.attr(e,"tabindex"),s=null!=i;return(!s||i>=0)&&t.ui.focusable(e,s)}}),t.fn.extend({uniqueId:function(){var t=0;return function(){return this.each(function(){this.id||(this.id="ui-id-"+ ++t)})}}(),removeUniqueId:function(){return this.each(function(){/^ui-id-\d+$/.test(this.id)&&t(this).removeAttr("id")})}}),t.ui.ie=!!/msie [\w.]+/.exec(navigator.userAgent.toLowerCase());var c=!1;t(document).on("mouseup",function(){c=!1}),t.widget("ui.mouse",{version:"1.12.1",options:{cancel:"input, textarea, button, select, option",distance:1,delay:0},_mouseInit:function(){var e=this;this.element.on("mousedown."+this.widgetName,function(t){return e._mouseDown(t)}).on("click."+this.widgetName,function(i){return!0===t.data(i.target,e.widgetName+".preventClickEvent")?(t.removeData(i.target,e.widgetName+".preventClickEvent"),i.stopImmediatePropagation(),!1):void 0}),this.started=!1},_mouseDestroy:function(){this.element.off("."+this.widgetName),this._mouseMoveDelegate&&this.document.off("mousemove."+this.widgetName,this._mouseMoveDelegate).off("mouseup."+this.widgetName,this._mouseUpDelegate)},_mouseDown:function(e){if(!c){this._mouseMoved=!1,this._mouseStarted&&this._mouseUp(e),this._mouseDownEvent=e;var i=this,s=1===e.which,n="string"==typeof this.options.cancel&&e.target.nodeName?t(e.target).closest(this.options.cancel).length:!1;return s&&!n&&this._mouseCapture(e)?(this.mouseDelayMet=!this.options.delay,this.mouseDelayMet||(this._mouseDelayTimer=setTimeout(function(){i.mouseDelayMet=!0},this.options.delay)),this._mouseDistanceMet(e)&&this._mouseDelayMet(e)&&(this._mouseStarted=this._mouseStart(e)!==!1,!this._mouseStarted)?(e.preventDefault(),!0):(!0===t.data(e.target,this.widgetName+".preventClickEvent")&&t.removeData(e.target,this.widgetName+".preventClickEvent"),this._mouseMoveDelegate=function(t){return i._mouseMove(t)},this._mouseUpDelegate=function(t){return i._mouseUp(t)},this.document.on("mousemove."+this.widgetName,this._mouseMoveDelegate).on("mouseup."+this.widgetName,this._mouseUpDelegate),e.preventDefault(),c=!0,!0)):!0}},_mouseMove:function(e){if(this._mouseMoved){if(t.ui.ie&&(!document.documentMode||9>document.documentMode)&&!e.button)return this._mouseUp(e);if(!e.which)if(e.originalEvent.altKey||e.originalEvent.ctrlKey||e.originalEvent.metaKey||e.originalEvent.shiftKey)this.ignoreMissingWhich=!0;else if(!this.ignoreMissingWhich)return this._mouseUp(e)}return(e.which||e.button)&&(this._mouseMoved=!0),this._mouseStarted?(this._mouseDrag(e),e.preventDefault()):(this._mouseDistanceMet(e)&&this._mouseDelayMet(e)&&(this._mouseStarted=this._mouseStart(this._mouseDownEvent,e)!==!1,this._mouseStarted?this._mouseDrag(e):this._mouseUp(e)),!this._mouseStarted)},_mouseUp:function(e){this.document.off("mousemove."+this.widgetName,this._mouseMoveDelegate).off("mouseup."+this.widgetName,this._mouseUpDelegate),this._mouseStarted&&(this._mouseStarted=!1,e.target===this._mouseDownEvent.target&&t.data(e.target,this.widgetName+".preventClickEvent",!0),this._mouseStop(e)),this._mouseDelayTimer&&(clearTimeout(this._mouseDelayTimer),delete this._mouseDelayTimer),this.ignoreMissingWhich=!1,c=!1,e.preventDefault()},_mouseDistanceMet:function(t){return Math.max(Math.abs(this._mouseDownEvent.pageX-t.pageX),Math.abs(this._mouseDownEvent.pageY-t.pageY))>=this.options.distance},_mouseDelayMet:function(){return this.mouseDelayMet},_mouseStart:function(){},_mouseDrag:function(){},_mouseStop:function(){},_mouseCapture:function(){return!0}}),t.ui.plugin={add:function(e,i,s){var n,o=t.ui[e].prototype;for(n in s)o.plugins[n]=o.plugins[n]||[],o.plugins[n].push([i,s[n]])},call:function(t,e,i,s){var n,o=t.plugins[e];if(o&&(s||t.element[0].parentNode&&11!==t.element[0].parentNode.nodeType))for(n=0;o.length>n;n++)t.options[o[n][0]]&&o[n][1].apply(t.element,i)}},t.ui.safeActiveElement=function(t){var e;try{e=t.activeElement}catch(i){e=t.body}return e||(e=t.body),e.nodeName||(e=t.body),e},t.ui.safeBlur=function(e){e&&"body"!==e.nodeName.toLowerCase()&&t(e).trigger("blur")},t.widget("ui.draggable",t.ui.mouse,{version:"1.12.1",widgetEventPrefix:"drag",options:{addClasses:!0,appendTo:"parent",axis:!1,connectToSortable:!1,containment:!1,cursor:"auto",cursorAt:!1,grid:!1,handle:!1,helper:"original",iframeFix:!1,opacity:!1,refreshPositions:!1,revert:!1,revertDuration:500,scope:"default",scroll:!0,scrollSensitivity:20,scrollSpeed:20,snap:!1,snapMode:"both",snapTolerance:20,stack:!1,zIndex:!1,drag:null,start:null,stop:null},_create:function(){"original"===this.options.helper&&this._setPositionRelative(),this.options.addClasses&&this._addClass("ui-draggable"),this._setHandleClassName(),this._mouseInit()},_setOption:function(t,e){this._super(t,e),"handle"===t&&(this._removeHandleClassName(),this._setHandleClassName())},_destroy:function(){return(this.helper||this.element).is(".ui-draggable-dragging")?(this.destroyOnClear=!0,void 0):(this._removeHandleClassName(),this._mouseDestroy(),void 0)},_mouseCapture:function(e){var i=this.options;return this.helper||i.disabled||t(e.target).closest(".ui-resizable-handle").length>0?!1:(this.handle=this._getHandle(e),this.handle?(this._blurActiveElement(e),this._blockFrames(i.iframeFix===!0?"iframe":i.iframeFix),!0):!1)},_blockFrames:function(e){this.iframeBlocks=this.document.find(e).map(function(){var e=t(this);return t("<div>").css("position","absolute").appendTo(e.parent()).outerWidth(e.outerWidth()).outerHeight(e.outerHeight()).offset(e.offset())[0]})},_unblockFrames:function(){this.iframeBlocks&&(this.iframeBlocks.remove(),delete this.iframeBlocks)},_blurActiveElement:function(e){var i=t.ui.safeActiveElement(this.document[0]),s=t(e.target);s.closest(i).length||t.ui.safeBlur(i)},_mouseStart:function(e){var i=this.options;return this.helper=this._createHelper(e),this._addClass(this.helper,"ui-draggable-dragging"),this._cacheHelperProportions(),t.ui.ddmanager&&(t.ui.ddmanager.current=this),this._cacheMargins(),this.cssPosition=this.helper.css("position"),this.scrollParent=this.helper.scrollParent(!0),this.offsetParent=this.helper.offsetParent(),this.hasFixedAncestor=this.helper.parents().filter(function(){return"fixed"===t(this).css("position")}).length>0,this.positionAbs=this.element.offset(),this._refreshOffsets(e),this.originalPosition=this.position=this._generatePosition(e,!1),this.originalPageX=e.pageX,this.originalPageY=e.pageY,i.cursorAt&&this._adjustOffsetFromHelper(i.cursorAt),this._setContainment(),this._trigger("start",e)===!1?(this._clear(),!1):(this._cacheHelperProportions(),t.ui.ddmanager&&!i.dropBehaviour&&t.ui.ddmanager.prepareOffsets(this,e),this._mouseDrag(e,!0),t.ui.ddmanager&&t.ui.ddmanager.dragStart(this,e),!0)},_refreshOffsets:function(t){this.offset={top:this.positionAbs.top-this.margins.top,left:this.positionAbs.left-this.margins.left,scroll:!1,parent:this._getParentOffset(),relative:this._getRelativeOffset()},this.offset.click={left:t.pageX-this.offset.left,top:t.pageY-this.offset.top}},_mouseDrag:function(e,i){if(this.hasFixedAncestor&&(this.offset.parent=this._getParentOffset()),this.position=this._generatePosition(e,!0),this.positionAbs=this._convertPositionTo("absolute"),!i){var s=this._uiHash();if(this._trigger("drag",e,s)===!1)return this._mouseUp(new t.Event("mouseup",e)),!1;this.position=s.position}return this.helper[0].style.left=this.position.left+"px",this.helper[0].style.top=this.position.top+"px",t.ui.ddmanager&&t.ui.ddmanager.drag(this,e),!1},_mouseStop:function(e){var i=this,s=!1;return t.ui.ddmanager&&!this.options.dropBehaviour&&(s=t.ui.ddmanager.drop(this,e)),this.dropped&&(s=this.dropped,this.dropped=!1),"invalid"===this.options.revert&&!s||"valid"===this.options.revert&&s||this.options.revert===!0||t.isFunction(this.options.revert)&&this.options.revert.call(this.element,s)?t(this.helper).animate(this.originalPosition,parseInt(this.options.revertDuration,10),function(){i._trigger("stop",e)!==!1&&i._clear()}):this._trigger("stop",e)!==!1&&this._clear(),!1},_mouseUp:function(e){return this._unblockFrames(),t.ui.ddmanager&&t.ui.ddmanager.dragStop(this,e),this.handleElement.is(e.target)&&this.element.trigger("focus"),t.ui.mouse.prototype._mouseUp.call(this,e)},cancel:function(){return this.helper.is(".ui-draggable-dragging")?this._mouseUp(new t.Event("mouseup",{target:this.element[0]})):this._clear(),this},_getHandle:function(e){return this.options.handle?!!t(e.target).closest(this.element.find(this.options.handle)).length:!0},_setHandleClassName:function(){this.handleElement=this.options.handle?this.element.find(this.options.handle):this.element,this._addClass(this.handleElement,"ui-draggable-handle")},_removeHandleClassName:function(){this._removeClass(this.handleElement,"ui-draggable-handle")},_createHelper:function(e){var i=this.options,s=t.isFunction(i.helper),n=s?t(i.helper.apply(this.element[0],[e])):"clone"===i.helper?this.element.clone().removeAttr("id"):this.element;return n.parents("body").length||n.appendTo("parent"===i.appendTo?this.element[0].parentNode:i.appendTo),s&&n[0]===this.element[0]&&this._setPositionRelative(),n[0]===this.element[0]||/(fixed|absolute)/.test(n.css("position"))||n.css("position","absolute"),n},_setPositionRelative:function(){/^(?:r|a|f)/.test(this.element.css("position"))||(this.element[0].style.position="relative")},_adjustOffsetFromHelper:function(e){"string"==typeof e&&(e=e.split(" ")),t.isArray(e)&&(e={left:+e[0],top:+e[1]||0}),"left"in e&&(this.offset.click.left=e.left+this.margins.left),"right"in e&&(this.offset.click.left=this.helperProportions.width-e.right+this.margins.left),"top"in e&&(this.offset.click.top=e.top+this.margins.top),"bottom"in e&&(this.offset.click.top=this.helperProportions.height-e.bottom+this.margins.top)},_isRootNode:function(t){return/(html|body)/i.test(t.tagName)||t===this.document[0]},_getParentOffset:function(){var e=this.offsetParent.offset(),i=this.document[0];return"absolute"===this.cssPosition&&this.scrollParent[0]!==i&&t.contains(this.scrollParent[0],this.offsetParent[0])&&(e.left+=this.scrollParent.scrollLeft(),e.top+=this.scrollParent.scrollTop()),this._isRootNode(this.offsetParent[0])&&(e={top:0,left:0}),{top:e.top+(parseInt(this.offsetParent.css("borderTopWidth"),10)||0),left:e.left+(parseInt(this.offsetParent.css("borderLeftWidth"),10)||0)}},_getRelativeOffset:function(){if("relative"!==this.cssPosition)return{top:0,left:0};var t=this.element.position(),e=this._isRootNode(this.scrollParent[0]);return{top:t.top-(parseInt(this.helper.css("top"),10)||0)+(e?0:this.scrollParent.scrollTop()),left:t.left-(parseInt(this.helper.css("left"),10)||0)+(e?0:this.scrollParent.scrollLeft())}},_cacheMargins:function(){this.margins={left:parseInt(this.element.css("marginLeft"),10)||0,top:parseInt(this.element.css("marginTop"),10)||0,right:parseInt(this.element.css("marginRight"),10)||0,bottom:parseInt(this.element.css("marginBottom"),10)||0}},_cacheHelperProportions:function(){this.helperProportions={width:this.helper.outerWidth(),height:this.helper.outerHeight()}},_setContainment:function(){var e,i,s,n=this.options,o=this.document[0];return this.relativeContainer=null,n.containment?"window"===n.containment?(this.containment=[t(window).scrollLeft()-this.offset.relative.left-this.offset.parent.left,t(window).scrollTop()-this.offset.relative.top-this.offset.parent.top,t(window).scrollLeft()+t(window).width()-this.helperProportions.width-this.margins.left,t(window).scrollTop()+(t(window).height()||o.body.parentNode.scrollHeight)-this.helperProportions.height-this.margins.top],void 0):"document"===n.containment?(this.containment=[0,0,t(o).width()-this.helperProportions.width-this.margins.left,(t(o).height()||o.body.parentNode.scrollHeight)-this.helperProportions.height-this.margins.top],void 0):n.containment.constructor===Array?(this.containment=n.containment,void 0):("parent"===n.containment&&(n.containment=this.helper[0].parentNode),i=t(n.containment),s=i[0],s&&(e=/(scroll|auto)/.test(i.css("overflow")),this.containment=[(parseInt(i.css("borderLeftWidth"),10)||0)+(parseInt(i.css("paddingLeft"),10)||0),(parseInt(i.css("borderTopWidth"),10)||0)+(parseInt(i.css("paddingTop"),10)||0),(e?Math.max(s.scrollWidth,s.offsetWidth):s.offsetWidth)-(parseInt(i.css("borderRightWidth"),10)||0)-(parseInt(i.css("paddingRight"),10)||0)-this.helperProportions.width-this.margins.left-this.margins.right,(e?Math.max(s.scrollHeight,s.offsetHeight):s.offsetHeight)-(parseInt(i.css("borderBottomWidth"),10)||0)-(parseInt(i.css("paddingBottom"),10)||0)-this.helperProportions.height-this.margins.top-this.margins.bottom],this.relativeContainer=i),void 0):(this.containment=null,void 0)
|
||
},_convertPositionTo:function(t,e){e||(e=this.position);var i="absolute"===t?1:-1,s=this._isRootNode(this.scrollParent[0]);return{top:e.top+this.offset.relative.top*i+this.offset.parent.top*i-("fixed"===this.cssPosition?-this.offset.scroll.top:s?0:this.offset.scroll.top)*i,left:e.left+this.offset.relative.left*i+this.offset.parent.left*i-("fixed"===this.cssPosition?-this.offset.scroll.left:s?0:this.offset.scroll.left)*i}},_generatePosition:function(t,e){var i,s,n,o,a=this.options,r=this._isRootNode(this.scrollParent[0]),h=t.pageX,l=t.pageY;return r&&this.offset.scroll||(this.offset.scroll={top:this.scrollParent.scrollTop(),left:this.scrollParent.scrollLeft()}),e&&(this.containment&&(this.relativeContainer?(s=this.relativeContainer.offset(),i=[this.containment[0]+s.left,this.containment[1]+s.top,this.containment[2]+s.left,this.containment[3]+s.top]):i=this.containment,t.pageX-this.offset.click.left<i[0]&&(h=i[0]+this.offset.click.left),t.pageY-this.offset.click.top<i[1]&&(l=i[1]+this.offset.click.top),t.pageX-this.offset.click.left>i[2]&&(h=i[2]+this.offset.click.left),t.pageY-this.offset.click.top>i[3]&&(l=i[3]+this.offset.click.top)),a.grid&&(n=a.grid[1]?this.originalPageY+Math.round((l-this.originalPageY)/a.grid[1])*a.grid[1]:this.originalPageY,l=i?n-this.offset.click.top>=i[1]||n-this.offset.click.top>i[3]?n:n-this.offset.click.top>=i[1]?n-a.grid[1]:n+a.grid[1]:n,o=a.grid[0]?this.originalPageX+Math.round((h-this.originalPageX)/a.grid[0])*a.grid[0]:this.originalPageX,h=i?o-this.offset.click.left>=i[0]||o-this.offset.click.left>i[2]?o:o-this.offset.click.left>=i[0]?o-a.grid[0]:o+a.grid[0]:o),"y"===a.axis&&(h=this.originalPageX),"x"===a.axis&&(l=this.originalPageY)),{top:l-this.offset.click.top-this.offset.relative.top-this.offset.parent.top+("fixed"===this.cssPosition?-this.offset.scroll.top:r?0:this.offset.scroll.top),left:h-this.offset.click.left-this.offset.relative.left-this.offset.parent.left+("fixed"===this.cssPosition?-this.offset.scroll.left:r?0:this.offset.scroll.left)}},_clear:function(){this._removeClass(this.helper,"ui-draggable-dragging"),this.helper[0]===this.element[0]||this.cancelHelperRemoval||this.helper.remove(),this.helper=null,this.cancelHelperRemoval=!1,this.destroyOnClear&&this.destroy()},_trigger:function(e,i,s){return s=s||this._uiHash(),t.ui.plugin.call(this,e,[i,s,this],!0),/^(drag|start|stop)/.test(e)&&(this.positionAbs=this._convertPositionTo("absolute"),s.offset=this.positionAbs),t.Widget.prototype._trigger.call(this,e,i,s)},plugins:{},_uiHash:function(){return{helper:this.helper,position:this.position,originalPosition:this.originalPosition,offset:this.positionAbs}}}),t.ui.plugin.add("draggable","connectToSortable",{start:function(e,i,s){var n=t.extend({},i,{item:s.element});s.sortables=[],t(s.options.connectToSortable).each(function(){var i=t(this).sortable("instance");i&&!i.options.disabled&&(s.sortables.push(i),i.refreshPositions(),i._trigger("activate",e,n))})},stop:function(e,i,s){var n=t.extend({},i,{item:s.element});s.cancelHelperRemoval=!1,t.each(s.sortables,function(){var t=this;t.isOver?(t.isOver=0,s.cancelHelperRemoval=!0,t.cancelHelperRemoval=!1,t._storedCSS={position:t.placeholder.css("position"),top:t.placeholder.css("top"),left:t.placeholder.css("left")},t._mouseStop(e),t.options.helper=t.options._helper):(t.cancelHelperRemoval=!0,t._trigger("deactivate",e,n))})},drag:function(e,i,s){t.each(s.sortables,function(){var n=!1,o=this;o.positionAbs=s.positionAbs,o.helperProportions=s.helperProportions,o.offset.click=s.offset.click,o._intersectsWith(o.containerCache)&&(n=!0,t.each(s.sortables,function(){return this.positionAbs=s.positionAbs,this.helperProportions=s.helperProportions,this.offset.click=s.offset.click,this!==o&&this._intersectsWith(this.containerCache)&&t.contains(o.element[0],this.element[0])&&(n=!1),n})),n?(o.isOver||(o.isOver=1,s._parent=i.helper.parent(),o.currentItem=i.helper.appendTo(o.element).data("ui-sortable-item",!0),o.options._helper=o.options.helper,o.options.helper=function(){return i.helper[0]},e.target=o.currentItem[0],o._mouseCapture(e,!0),o._mouseStart(e,!0,!0),o.offset.click.top=s.offset.click.top,o.offset.click.left=s.offset.click.left,o.offset.parent.left-=s.offset.parent.left-o.offset.parent.left,o.offset.parent.top-=s.offset.parent.top-o.offset.parent.top,s._trigger("toSortable",e),s.dropped=o.element,t.each(s.sortables,function(){this.refreshPositions()}),s.currentItem=s.element,o.fromOutside=s),o.currentItem&&(o._mouseDrag(e),i.position=o.position)):o.isOver&&(o.isOver=0,o.cancelHelperRemoval=!0,o.options._revert=o.options.revert,o.options.revert=!1,o._trigger("out",e,o._uiHash(o)),o._mouseStop(e,!0),o.options.revert=o.options._revert,o.options.helper=o.options._helper,o.placeholder&&o.placeholder.remove(),i.helper.appendTo(s._parent),s._refreshOffsets(e),i.position=s._generatePosition(e,!0),s._trigger("fromSortable",e),s.dropped=!1,t.each(s.sortables,function(){this.refreshPositions()}))})}}),t.ui.plugin.add("draggable","cursor",{start:function(e,i,s){var n=t("body"),o=s.options;n.css("cursor")&&(o._cursor=n.css("cursor")),n.css("cursor",o.cursor)},stop:function(e,i,s){var n=s.options;n._cursor&&t("body").css("cursor",n._cursor)}}),t.ui.plugin.add("draggable","opacity",{start:function(e,i,s){var n=t(i.helper),o=s.options;n.css("opacity")&&(o._opacity=n.css("opacity")),n.css("opacity",o.opacity)},stop:function(e,i,s){var n=s.options;n._opacity&&t(i.helper).css("opacity",n._opacity)}}),t.ui.plugin.add("draggable","scroll",{start:function(t,e,i){i.scrollParentNotHidden||(i.scrollParentNotHidden=i.helper.scrollParent(!1)),i.scrollParentNotHidden[0]!==i.document[0]&&"HTML"!==i.scrollParentNotHidden[0].tagName&&(i.overflowOffset=i.scrollParentNotHidden.offset())},drag:function(e,i,s){var n=s.options,o=!1,a=s.scrollParentNotHidden[0],r=s.document[0];a!==r&&"HTML"!==a.tagName?(n.axis&&"x"===n.axis||(s.overflowOffset.top+a.offsetHeight-e.pageY<n.scrollSensitivity?a.scrollTop=o=a.scrollTop+n.scrollSpeed:e.pageY-s.overflowOffset.top<n.scrollSensitivity&&(a.scrollTop=o=a.scrollTop-n.scrollSpeed)),n.axis&&"y"===n.axis||(s.overflowOffset.left+a.offsetWidth-e.pageX<n.scrollSensitivity?a.scrollLeft=o=a.scrollLeft+n.scrollSpeed:e.pageX-s.overflowOffset.left<n.scrollSensitivity&&(a.scrollLeft=o=a.scrollLeft-n.scrollSpeed))):(n.axis&&"x"===n.axis||(e.pageY-t(r).scrollTop()<n.scrollSensitivity?o=t(r).scrollTop(t(r).scrollTop()-n.scrollSpeed):t(window).height()-(e.pageY-t(r).scrollTop())<n.scrollSensitivity&&(o=t(r).scrollTop(t(r).scrollTop()+n.scrollSpeed))),n.axis&&"y"===n.axis||(e.pageX-t(r).scrollLeft()<n.scrollSensitivity?o=t(r).scrollLeft(t(r).scrollLeft()-n.scrollSpeed):t(window).width()-(e.pageX-t(r).scrollLeft())<n.scrollSensitivity&&(o=t(r).scrollLeft(t(r).scrollLeft()+n.scrollSpeed)))),o!==!1&&t.ui.ddmanager&&!n.dropBehaviour&&t.ui.ddmanager.prepareOffsets(s,e)}}),t.ui.plugin.add("draggable","snap",{start:function(e,i,s){var n=s.options;s.snapElements=[],t(n.snap.constructor!==String?n.snap.items||":data(ui-draggable)":n.snap).each(function(){var e=t(this),i=e.offset();this!==s.element[0]&&s.snapElements.push({item:this,width:e.outerWidth(),height:e.outerHeight(),top:i.top,left:i.left})})},drag:function(e,i,s){var n,o,a,r,h,l,c,u,d,p,f=s.options,g=f.snapTolerance,m=i.offset.left,_=m+s.helperProportions.width,v=i.offset.top,b=v+s.helperProportions.height;for(d=s.snapElements.length-1;d>=0;d--)h=s.snapElements[d].left-s.margins.left,l=h+s.snapElements[d].width,c=s.snapElements[d].top-s.margins.top,u=c+s.snapElements[d].height,h-g>_||m>l+g||c-g>b||v>u+g||!t.contains(s.snapElements[d].item.ownerDocument,s.snapElements[d].item)?(s.snapElements[d].snapping&&s.options.snap.release&&s.options.snap.release.call(s.element,e,t.extend(s._uiHash(),{snapItem:s.snapElements[d].item})),s.snapElements[d].snapping=!1):("inner"!==f.snapMode&&(n=g>=Math.abs(c-b),o=g>=Math.abs(u-v),a=g>=Math.abs(h-_),r=g>=Math.abs(l-m),n&&(i.position.top=s._convertPositionTo("relative",{top:c-s.helperProportions.height,left:0}).top),o&&(i.position.top=s._convertPositionTo("relative",{top:u,left:0}).top),a&&(i.position.left=s._convertPositionTo("relative",{top:0,left:h-s.helperProportions.width}).left),r&&(i.position.left=s._convertPositionTo("relative",{top:0,left:l}).left)),p=n||o||a||r,"outer"!==f.snapMode&&(n=g>=Math.abs(c-v),o=g>=Math.abs(u-b),a=g>=Math.abs(h-m),r=g>=Math.abs(l-_),n&&(i.position.top=s._convertPositionTo("relative",{top:c,left:0}).top),o&&(i.position.top=s._convertPositionTo("relative",{top:u-s.helperProportions.height,left:0}).top),a&&(i.position.left=s._convertPositionTo("relative",{top:0,left:h}).left),r&&(i.position.left=s._convertPositionTo("relative",{top:0,left:l-s.helperProportions.width}).left)),!s.snapElements[d].snapping&&(n||o||a||r||p)&&s.options.snap.snap&&s.options.snap.snap.call(s.element,e,t.extend(s._uiHash(),{snapItem:s.snapElements[d].item})),s.snapElements[d].snapping=n||o||a||r||p)}}),t.ui.plugin.add("draggable","stack",{start:function(e,i,s){var n,o=s.options,a=t.makeArray(t(o.stack)).sort(function(e,i){return(parseInt(t(e).css("zIndex"),10)||0)-(parseInt(t(i).css("zIndex"),10)||0)});a.length&&(n=parseInt(t(a[0]).css("zIndex"),10)||0,t(a).each(function(e){t(this).css("zIndex",n+e)}),this.css("zIndex",n+a.length))}}),t.ui.plugin.add("draggable","zIndex",{start:function(e,i,s){var n=t(i.helper),o=s.options;n.css("zIndex")&&(o._zIndex=n.css("zIndex")),n.css("zIndex",o.zIndex)},stop:function(e,i,s){var n=s.options;n._zIndex&&t(i.helper).css("zIndex",n._zIndex)}}),t.ui.draggable,t.widget("ui.droppable",{version:"1.12.1",widgetEventPrefix:"drop",options:{accept:"*",addClasses:!0,greedy:!1,scope:"default",tolerance:"intersect",activate:null,deactivate:null,drop:null,out:null,over:null},_create:function(){var e,i=this.options,s=i.accept;this.isover=!1,this.isout=!0,this.accept=t.isFunction(s)?s:function(t){return t.is(s)},this.proportions=function(){return arguments.length?(e=arguments[0],void 0):e?e:e={width:this.element[0].offsetWidth,height:this.element[0].offsetHeight}},this._addToManager(i.scope),i.addClasses&&this._addClass("ui-droppable")},_addToManager:function(e){t.ui.ddmanager.droppables[e]=t.ui.ddmanager.droppables[e]||[],t.ui.ddmanager.droppables[e].push(this)},_splice:function(t){for(var e=0;t.length>e;e++)t[e]===this&&t.splice(e,1)},_destroy:function(){var e=t.ui.ddmanager.droppables[this.options.scope];this._splice(e)},_setOption:function(e,i){if("accept"===e)this.accept=t.isFunction(i)?i:function(t){return t.is(i)};else if("scope"===e){var s=t.ui.ddmanager.droppables[this.options.scope];this._splice(s),this._addToManager(i)}this._super(e,i)},_activate:function(e){var i=t.ui.ddmanager.current;this._addActiveClass(),i&&this._trigger("activate",e,this.ui(i))},_deactivate:function(e){var i=t.ui.ddmanager.current;this._removeActiveClass(),i&&this._trigger("deactivate",e,this.ui(i))},_over:function(e){var i=t.ui.ddmanager.current;i&&(i.currentItem||i.element)[0]!==this.element[0]&&this.accept.call(this.element[0],i.currentItem||i.element)&&(this._addHoverClass(),this._trigger("over",e,this.ui(i)))},_out:function(e){var i=t.ui.ddmanager.current;i&&(i.currentItem||i.element)[0]!==this.element[0]&&this.accept.call(this.element[0],i.currentItem||i.element)&&(this._removeHoverClass(),this._trigger("out",e,this.ui(i)))},_drop:function(e,i){var s=i||t.ui.ddmanager.current,n=!1;return s&&(s.currentItem||s.element)[0]!==this.element[0]?(this.element.find(":data(ui-droppable)").not(".ui-draggable-dragging").each(function(){var i=t(this).droppable("instance");return i.options.greedy&&!i.options.disabled&&i.options.scope===s.options.scope&&i.accept.call(i.element[0],s.currentItem||s.element)&&u(s,t.extend(i,{offset:i.element.offset()}),i.options.tolerance,e)?(n=!0,!1):void 0}),n?!1:this.accept.call(this.element[0],s.currentItem||s.element)?(this._removeActiveClass(),this._removeHoverClass(),this._trigger("drop",e,this.ui(s)),this.element):!1):!1},ui:function(t){return{draggable:t.currentItem||t.element,helper:t.helper,position:t.position,offset:t.positionAbs}},_addHoverClass:function(){this._addClass("ui-droppable-hover")},_removeHoverClass:function(){this._removeClass("ui-droppable-hover")},_addActiveClass:function(){this._addClass("ui-droppable-active")},_removeActiveClass:function(){this._removeClass("ui-droppable-active")}});var u=t.ui.intersect=function(){function t(t,e,i){return t>=e&&e+i>t}return function(e,i,s,n){if(!i.offset)return!1;var o=(e.positionAbs||e.position.absolute).left+e.margins.left,a=(e.positionAbs||e.position.absolute).top+e.margins.top,r=o+e.helperProportions.width,h=a+e.helperProportions.height,l=i.offset.left,c=i.offset.top,u=l+i.proportions().width,d=c+i.proportions().height;switch(s){case"fit":return o>=l&&u>=r&&a>=c&&d>=h;case"intersect":return o+e.helperProportions.width/2>l&&u>r-e.helperProportions.width/2&&a+e.helperProportions.height/2>c&&d>h-e.helperProportions.height/2;case"pointer":return t(n.pageY,c,i.proportions().height)&&t(n.pageX,l,i.proportions().width);case"touch":return(a>=c&&d>=a||h>=c&&d>=h||c>a&&h>d)&&(o>=l&&u>=o||r>=l&&u>=r||l>o&&r>u);default:return!1}}}();t.ui.ddmanager={current:null,droppables:{"default":[]},prepareOffsets:function(e,i){var s,n,o=t.ui.ddmanager.droppables[e.options.scope]||[],a=i?i.type:null,r=(e.currentItem||e.element).find(":data(ui-droppable)").addBack();t:for(s=0;o.length>s;s++)if(!(o[s].options.disabled||e&&!o[s].accept.call(o[s].element[0],e.currentItem||e.element))){for(n=0;r.length>n;n++)if(r[n]===o[s].element[0]){o[s].proportions().height=0;continue t}o[s].visible="none"!==o[s].element.css("display"),o[s].visible&&("mousedown"===a&&o[s]._activate.call(o[s],i),o[s].offset=o[s].element.offset(),o[s].proportions({width:o[s].element[0].offsetWidth,height:o[s].element[0].offsetHeight}))}},drop:function(e,i){var s=!1;return t.each((t.ui.ddmanager.droppables[e.options.scope]||[]).slice(),function(){this.options&&(!this.options.disabled&&this.visible&&u(e,this,this.options.tolerance,i)&&(s=this._drop.call(this,i)||s),!this.options.disabled&&this.visible&&this.accept.call(this.element[0],e.currentItem||e.element)&&(this.isout=!0,this.isover=!1,this._deactivate.call(this,i)))}),s},dragStart:function(e,i){e.element.parentsUntil("body").on("scroll.droppable",function(){e.options.refreshPositions||t.ui.ddmanager.prepareOffsets(e,i)})},drag:function(e,i){e.options.refreshPositions&&t.ui.ddmanager.prepareOffsets(e,i),t.each(t.ui.ddmanager.droppables[e.options.scope]||[],function(){if(!this.options.disabled&&!this.greedyChild&&this.visible){var s,n,o,a=u(e,this,this.options.tolerance,i),r=!a&&this.isover?"isout":a&&!this.isover?"isover":null;r&&(this.options.greedy&&(n=this.options.scope,o=this.element.parents(":data(ui-droppable)").filter(function(){return t(this).droppable("instance").options.scope===n}),o.length&&(s=t(o[0]).droppable("instance"),s.greedyChild="isover"===r)),s&&"isover"===r&&(s.isover=!1,s.isout=!0,s._out.call(s,i)),this[r]=!0,this["isout"===r?"isover":"isout"]=!1,this["isover"===r?"_over":"_out"].call(this,i),s&&"isout"===r&&(s.isout=!1,s.isover=!0,s._over.call(s,i)))}})},dragStop:function(e,i){e.element.parentsUntil("body").off("scroll.droppable"),e.options.refreshPositions||t.ui.ddmanager.prepareOffsets(e,i)}},t.uiBackCompat!==!1&&t.widget("ui.droppable",t.ui.droppable,{options:{hoverClass:!1,activeClass:!1},_addActiveClass:function(){this._super(),this.options.activeClass&&this.element.addClass(this.options.activeClass)},_removeActiveClass:function(){this._super(),this.options.activeClass&&this.element.removeClass(this.options.activeClass)},_addHoverClass:function(){this._super(),this.options.hoverClass&&this.element.addClass(this.options.hoverClass)},_removeHoverClass:function(){this._super(),this.options.hoverClass&&this.element.removeClass(this.options.hoverClass)}}),t.ui.droppable,t.widget("ui.resizable",t.ui.mouse,{version:"1.12.1",widgetEventPrefix:"resize",options:{alsoResize:!1,animate:!1,animateDuration:"slow",animateEasing:"swing",aspectRatio:!1,autoHide:!1,classes:{"ui-resizable-se":"ui-icon ui-icon-gripsmall-diagonal-se"},containment:!1,ghost:!1,grid:!1,handles:"e,s,se",helper:!1,maxHeight:null,maxWidth:null,minHeight:10,minWidth:10,zIndex:90,resize:null,start:null,stop:null},_num:function(t){return parseFloat(t)||0},_isNumber:function(t){return!isNaN(parseFloat(t))},_hasScroll:function(e,i){if("hidden"===t(e).css("overflow"))return!1;var s=i&&"left"===i?"scrollLeft":"scrollTop",n=!1;return e[s]>0?!0:(e[s]=1,n=e[s]>0,e[s]=0,n)},_create:function(){var e,i=this.options,s=this;this._addClass("ui-resizable"),t.extend(this,{_aspectRatio:!!i.aspectRatio,aspectRatio:i.aspectRatio,originalElement:this.element,_proportionallyResizeElements:[],_helper:i.helper||i.ghost||i.animate?i.helper||"ui-resizable-helper":null}),this.element[0].nodeName.match(/^(canvas|textarea|input|select|button|img)$/i)&&(this.element.wrap(t("<div class='ui-wrapper' style='overflow: hidden;'></div>").css({position:this.element.css("position"),width:this.element.outerWidth(),height:this.element.outerHeight(),top:this.element.css("top"),left:this.element.css("left")})),this.element=this.element.parent().data("ui-resizable",this.element.resizable("instance")),this.elementIsWrapper=!0,e={marginTop:this.originalElement.css("marginTop"),marginRight:this.originalElement.css("marginRight"),marginBottom:this.originalElement.css("marginBottom"),marginLeft:this.originalElement.css("marginLeft")},this.element.css(e),this.originalElement.css("margin",0),this.originalResizeStyle=this.originalElement.css("resize"),this.originalElement.css("resize","none"),this._proportionallyResizeElements.push(this.originalElement.css({position:"static",zoom:1,display:"block"})),this.originalElement.css(e),this._proportionallyResize()),this._setupHandles(),i.autoHide&&t(this.element).on("mouseenter",function(){i.disabled||(s._removeClass("ui-resizable-autohide"),s._handles.show())}).on("mouseleave",function(){i.disabled||s.resizing||(s._addClass("ui-resizable-autohide"),s._handles.hide())}),this._mouseInit()},_destroy:function(){this._mouseDestroy();var e,i=function(e){t(e).removeData("resizable").removeData("ui-resizable").off(".resizable").find(".ui-resizable-handle").remove()};return this.elementIsWrapper&&(i(this.element),e=this.element,this.originalElement.css({position:e.css("position"),width:e.outerWidth(),height:e.outerHeight(),top:e.css("top"),left:e.css("left")}).insertAfter(e),e.remove()),this.originalElement.css("resize",this.originalResizeStyle),i(this.originalElement),this},_setOption:function(t,e){switch(this._super(t,e),t){case"handles":this._removeHandles(),this._setupHandles();break;default:}},_setupHandles:function(){var e,i,s,n,o,a=this.options,r=this;if(this.handles=a.handles||(t(".ui-resizable-handle",this.element).length?{n:".ui-resizable-n",e:".ui-resizable-e",s:".ui-resizable-s",w:".ui-resizable-w",se:".ui-resizable-se",sw:".ui-resizable-sw",ne:".ui-resizable-ne",nw:".ui-resizable-nw"}:"e,s,se"),this._handles=t(),this.handles.constructor===String)for("all"===this.handles&&(this.handles="n,e,s,w,se,sw,ne,nw"),s=this.handles.split(","),this.handles={},i=0;s.length>i;i++)e=t.trim(s[i]),n="ui-resizable-"+e,o=t("<div>"),this._addClass(o,"ui-resizable-handle "+n),o.css({zIndex:a.zIndex}),this.handles[e]=".ui-resizable-"+e,this.element.append(o);this._renderAxis=function(e){var i,s,n,o;e=e||this.element;for(i in this.handles)this.handles[i].constructor===String?this.handles[i]=this.element.children(this.handles[i]).first().show():(this.handles[i].jquery||this.handles[i].nodeType)&&(this.handles[i]=t(this.handles[i]),this._on(this.handles[i],{mousedown:r._mouseDown})),this.elementIsWrapper&&this.originalElement[0].nodeName.match(/^(textarea|input|select|button)$/i)&&(s=t(this.handles[i],this.element),o=/sw|ne|nw|se|n|s/.test(i)?s.outerHeight():s.outerWidth(),n=["padding",/ne|nw|n/.test(i)?"Top":/se|sw|s/.test(i)?"Bottom":/^e$/.test(i)?"Right":"Left"].join(""),e.css(n,o),this._proportionallyResize()),this._handles=this._handles.add(this.handles[i])},this._renderAxis(this.element),this._handles=this._handles.add(this.element.find(".ui-resizable-handle")),this._handles.disableSelection(),this._handles.on("mouseover",function(){r.resizing||(this.className&&(o=this.className.match(/ui-resizable-(se|sw|ne|nw|n|e|s|w)/i)),r.axis=o&&o[1]?o[1]:"se")}),a.autoHide&&(this._handles.hide(),this._addClass("ui-resizable-autohide"))},_removeHandles:function(){this._handles.remove()},_mouseCapture:function(e){var i,s,n=!1;for(i in this.handles)s=t(this.handles[i])[0],(s===e.target||t.contains(s,e.target))&&(n=!0);return!this.options.disabled&&n},_mouseStart:function(e){var i,s,n,o=this.options,a=this.element;return this.resizing=!0,this._renderProxy(),i=this._num(this.helper.css("left")),s=this._num(this.helper.css("top")),o.containment&&(i+=t(o.containment).scrollLeft()||0,s+=t(o.containment).scrollTop()||0),this.offset=this.helper.offset(),this.position={left:i,top:s},this.size=this._helper?{width:this.helper.width(),height:this.helper.height()}:{width:a.width(),height:a.height()},this.originalSize=this._helper?{width:a.outerWidth(),height:a.outerHeight()}:{width:a.width(),height:a.height()},this.sizeDiff={width:a.outerWidth()-a.width(),height:a.outerHeight()-a.height()},this.originalPosition={left:i,top:s},this.originalMousePosition={left:e.pageX,top:e.pageY},this.aspectRatio="number"==typeof o.aspectRatio?o.aspectRatio:this.originalSize.width/this.originalSize.height||1,n=t(".ui-resizable-"+this.axis).css("cursor"),t("body").css("cursor","auto"===n?this.axis+"-resize":n),this._addClass("ui-resizable-resizing"),this._propagate("start",e),!0},_mouseDrag:function(e){var i,s,n=this.originalMousePosition,o=this.axis,a=e.pageX-n.left||0,r=e.pageY-n.top||0,h=this._change[o];return this._updatePrevProperties(),h?(i=h.apply(this,[e,a,r]),this._updateVirtualBoundaries(e.shiftKey),(this._aspectRatio||e.shiftKey)&&(i=this._updateRatio(i,e)),i=this._respectSize(i,e),this._updateCache(i),this._propagate("resize",e),s=this._applyChanges(),!this._helper&&this._proportionallyResizeElements.length&&this._proportionallyResize(),t.isEmptyObject(s)||(this._updatePrevProperties(),this._trigger("resize",e,this.ui()),this._applyChanges()),!1):!1},_mouseStop:function(e){this.resizing=!1;var i,s,n,o,a,r,h,l=this.options,c=this;return this._helper&&(i=this._proportionallyResizeElements,s=i.length&&/textarea/i.test(i[0].nodeName),n=s&&this._hasScroll(i[0],"left")?0:c.sizeDiff.height,o=s?0:c.sizeDiff.width,a={width:c.helper.width()-o,height:c.helper.height()-n},r=parseFloat(c.element.css("left"))+(c.position.left-c.originalPosition.left)||null,h=parseFloat(c.element.css("top"))+(c.position.top-c.originalPosition.top)||null,l.animate||this.element.css(t.extend(a,{top:h,left:r})),c.helper.height(c.size.height),c.helper.width(c.size.width),this._helper&&!l.animate&&this._proportionallyResize()),t("body").css("cursor","auto"),this._removeClass("ui-resizable-resizing"),this._propagate("stop",e),this._helper&&this.helper.remove(),!1},_updatePrevProperties:function(){this.prevPosition={top:this.position.top,left:this.position.left},this.prevSize={width:this.size.width,height:this.size.height}},_applyChanges:function(){var t={};return this.position.top!==this.prevPosition.top&&(t.top=this.position.top+"px"),this.position.left!==this.prevPosition.left&&(t.left=this.position.left+"px"),this.size.width!==this.prevSize.width&&(t.width=this.size.width+"px"),this.size.height!==this.prevSize.height&&(t.height=this.size.height+"px"),this.helper.css(t),t},_updateVirtualBoundaries:function(t){var e,i,s,n,o,a=this.options;o={minWidth:this._isNumber(a.minWidth)?a.minWidth:0,maxWidth:this._isNumber(a.maxWidth)?a.maxWidth:1/0,minHeight:this._isNumber(a.minHeight)?a.minHeight:0,maxHeight:this._isNumber(a.maxHeight)?a.maxHeight:1/0},(this._aspectRatio||t)&&(e=o.minHeight*this.aspectRatio,s=o.minWidth/this.aspectRatio,i=o.maxHeight*this.aspectRatio,n=o.maxWidth/this.aspectRatio,e>o.minWidth&&(o.minWidth=e),s>o.minHeight&&(o.minHeight=s),o.maxWidth>i&&(o.maxWidth=i),o.maxHeight>n&&(o.maxHeight=n)),this._vBoundaries=o},_updateCache:function(t){this.offset=this.helper.offset(),this._isNumber(t.left)&&(this.position.left=t.left),this._isNumber(t.top)&&(this.position.top=t.top),this._isNumber(t.height)&&(this.size.height=t.height),this._isNumber(t.width)&&(this.size.width=t.width)},_updateRatio:function(t){var e=this.position,i=this.size,s=this.axis;return this._isNumber(t.height)?t.width=t.height*this.aspectRatio:this._isNumber(t.width)&&(t.height=t.width/this.aspectRatio),"sw"===s&&(t.left=e.left+(i.width-t.width),t.top=null),"nw"===s&&(t.top=e.top+(i.height-t.height),t.left=e.left+(i.width-t.width)),t},_respectSize:function(t){var e=this._vBoundaries,i=this.axis,s=this._isNumber(t.width)&&e.maxWidth&&e.maxWidth<t.width,n=this._isNumber(t.height)&&e.maxHeight&&e.maxHeight<t.height,o=this._isNumber(t.width)&&e.minWidth&&e.minWidth>t.width,a=this._isNumber(t.height)&&e.minHeight&&e.minHeight>t.height,r=this.originalPosition.left+this.originalSize.width,h=this.originalPosition.top+this.originalSize.height,l=/sw|nw|w/.test(i),c=/nw|ne|n/.test(i);return o&&(t.width=e.minWidth),a&&(t.height=e.minHeight),s&&(t.width=e.maxWidth),n&&(t.height=e.maxHeight),o&&l&&(t.left=r-e.minWidth),s&&l&&(t.left=r-e.maxWidth),a&&c&&(t.top=h-e.minHeight),n&&c&&(t.top=h-e.maxHeight),t.width||t.height||t.left||!t.top?t.width||t.height||t.top||!t.left||(t.left=null):t.top=null,t},_getPaddingPlusBorderDimensions:function(t){for(var e=0,i=[],s=[t.css("borderTopWidth"),t.css("borderRightWidth"),t.css("borderBottomWidth"),t.css("borderLeftWidth")],n=[t.css("paddingTop"),t.css("paddingRight"),t.css("paddingBottom"),t.css("paddingLeft")];4>e;e++)i[e]=parseFloat(s[e])||0,i[e]+=parseFloat(n[e])||0;return{height:i[0]+i[2],width:i[1]+i[3]}},_proportionallyResize:function(){if(this._proportionallyResizeElements.length)for(var t,e=0,i=this.helper||this.element;this._proportionallyResizeElements.length>e;e++)t=this._proportionallyResizeElements[e],this.outerDimensions||(this.outerDimensions=this._getPaddingPlusBorderDimensions(t)),t.css({height:i.height()-this.outerDimensions.height||0,width:i.width()-this.outerDimensions.width||0})},_renderProxy:function(){var e=this.element,i=this.options;this.elementOffset=e.offset(),this._helper?(this.helper=this.helper||t("<div style='overflow:hidden;'></div>"),this._addClass(this.helper,this._helper),this.helper.css({width:this.element.outerWidth(),height:this.element.outerHeight(),position:"absolute",left:this.elementOffset.left+"px",top:this.elementOffset.top+"px",zIndex:++i.zIndex}),this.helper.appendTo("body").disableSelection()):this.helper=this.element},_change:{e:function(t,e){return{width:this.originalSize.width+e}},w:function(t,e){var i=this.originalSize,s=this.originalPosition;return{left:s.left+e,width:i.width-e}},n:function(t,e,i){var s=this.originalSize,n=this.originalPosition;return{top:n.top+i,height:s.height-i}},s:function(t,e,i){return{height:this.originalSize.height+i}},se:function(e,i,s){return t.extend(this._change.s.apply(this,arguments),this._change.e.apply(this,[e,i,s]))},sw:function(e,i,s){return t.extend(this._change.s.apply(this,arguments),this._change.w.apply(this,[e,i,s]))},ne:function(e,i,s){return t.extend(this._change.n.apply(this,arguments),this._change.e.apply(this,[e,i,s]))},nw:function(e,i,s){return t.extend(this._change.n.apply(this,arguments),this._change.w.apply(this,[e,i,s]))}},_propagate:function(e,i){t.ui.plugin.call(this,e,[i,this.ui()]),"resize"!==e&&this._trigger(e,i,this.ui())},plugins:{},ui:function(){return{originalElement:this.originalElement,element:this.element,helper:this.helper,position:this.position,size:this.size,originalSize:this.originalSize,originalPosition:this.originalPosition}}}),t.ui.plugin.add("resizable","animate",{stop:function(e){var i=t(this).resizable("instance"),s=i.options,n=i._proportionallyResizeElements,o=n.length&&/textarea/i.test(n[0].nodeName),a=o&&i._hasScroll(n[0],"left")?0:i.sizeDiff.height,r=o?0:i.sizeDiff.width,h={width:i.size.width-r,height:i.size.height-a},l=parseFloat(i.element.css("left"))+(i.position.left-i.originalPosition.left)||null,c=parseFloat(i.element.css("top"))+(i.position.top-i.originalPosition.top)||null;i.element.animate(t.extend(h,c&&l?{top:c,left:l}:{}),{duration:s.animateDuration,easing:s.animateEasing,step:function(){var s={width:parseFloat(i.element.css("width")),height:parseFloat(i.element.css("height")),top:parseFloat(i.element.css("top")),left:parseFloat(i.element.css("left"))};n&&n.length&&t(n[0]).css({width:s.width,height:s.height}),i._updateCache(s),i._propagate("resize",e)}})}}),t.ui.plugin.add("resizable","containment",{start:function(){var e,i,s,n,o,a,r,h=t(this).resizable("instance"),l=h.options,c=h.element,u=l.containment,d=u instanceof t?u.get(0):/parent/.test(u)?c.parent().get(0):u;d&&(h.containerElement=t(d),/document/.test(u)||u===document?(h.containerOffset={left:0,top:0},h.containerPosition={left:0,top:0},h.parentData={element:t(document),left:0,top:0,width:t(document).width(),height:t(document).height()||document.body.parentNode.scrollHeight}):(e=t(d),i=[],t(["Top","Right","Left","Bottom"]).each(function(t,s){i[t]=h._num(e.css("padding"+s))}),h.containerOffset=e.offset(),h.containerPosition=e.position(),h.containerSize={height:e.innerHeight()-i[3],width:e.innerWidth()-i[1]},s=h.containerOffset,n=h.containerSize.height,o=h.containerSize.width,a=h._hasScroll(d,"left")?d.scrollWidth:o,r=h._hasScroll(d)?d.scrollHeight:n,h.parentData={element:d,left:s.left,top:s.top,width:a,height:r}))},resize:function(e){var i,s,n,o,a=t(this).resizable("instance"),r=a.options,h=a.containerOffset,l=a.position,c=a._aspectRatio||e.shiftKey,u={top:0,left:0},d=a.containerElement,p=!0;d[0]!==document&&/static/.test(d.css("position"))&&(u=h),l.left<(a._helper?h.left:0)&&(a.size.width=a.size.width+(a._helper?a.position.left-h.left:a.position.left-u.left),c&&(a.size.height=a.size.width/a.aspectRatio,p=!1),a.position.left=r.helper?h.left:0),l.top<(a._helper?h.top:0)&&(a.size.height=a.size.height+(a._helper?a.position.top-h.top:a.position.top),c&&(a.size.width=a.size.height*a.aspectRatio,p=!1),a.position.top=a._helper?h.top:0),n=a.containerElement.get(0)===a.element.parent().get(0),o=/relative|absolute/.test(a.containerElement.css("position")),n&&o?(a.offset.left=a.parentData.left+a.position.left,a.offset.top=a.parentData.top+a.position.top):(a.offset.left=a.element.offset().left,a.offset.top=a.element.offset().top),i=Math.abs(a.sizeDiff.width+(a._helper?a.offset.left-u.left:a.offset.left-h.left)),s=Math.abs(a.sizeDiff.height+(a._helper?a.offset.top-u.top:a.offset.top-h.top)),i+a.size.width>=a.parentData.width&&(a.size.width=a.parentData.width-i,c&&(a.size.height=a.size.width/a.aspectRatio,p=!1)),s+a.size.height>=a.parentData.height&&(a.size.height=a.parentData.height-s,c&&(a.size.width=a.size.height*a.aspectRatio,p=!1)),p||(a.position.left=a.prevPosition.left,a.position.top=a.prevPosition.top,a.size.width=a.prevSize.width,a.size.height=a.prevSize.height)},stop:function(){var e=t(this).resizable("instance"),i=e.options,s=e.containerOffset,n=e.containerPosition,o=e.containerElement,a=t(e.helper),r=a.offset(),h=a.outerWidth()-e.sizeDiff.width,l=a.outerHeight()-e.sizeDiff.height;e._helper&&!i.animate&&/relative/.test(o.css("position"))&&t(this).css({left:r.left-n.left-s.left,width:h,height:l}),e._helper&&!i.animate&&/static/.test(o.css("position"))&&t(this).css({left:r.left-n.left-s.left,width:h,height:l})}}),t.ui.plugin.add("resizable","alsoResize",{start:function(){var e=t(this).resizable("instance"),i=e.options;t(i.alsoResize).each(function(){var e=t(this);e.data("ui-resizable-alsoresize",{width:parseFloat(e.width()),height:parseFloat(e.height()),left:parseFloat(e.css("left")),top:parseFloat(e.css("top"))})})},resize:function(e,i){var s=t(this).resizable("instance"),n=s.options,o=s.originalSize,a=s.originalPosition,r={height:s.size.height-o.height||0,width:s.size.width-o.width||0,top:s.position.top-a.top||0,left:s.position.left-a.left||0};
|
||
t(n.alsoResize).each(function(){var e=t(this),s=t(this).data("ui-resizable-alsoresize"),n={},o=e.parents(i.originalElement[0]).length?["width","height"]:["width","height","top","left"];t.each(o,function(t,e){var i=(s[e]||0)+(r[e]||0);i&&i>=0&&(n[e]=i||null)}),e.css(n)})},stop:function(){t(this).removeData("ui-resizable-alsoresize")}}),t.ui.plugin.add("resizable","ghost",{start:function(){var e=t(this).resizable("instance"),i=e.size;e.ghost=e.originalElement.clone(),e.ghost.css({opacity:.25,display:"block",position:"relative",height:i.height,width:i.width,margin:0,left:0,top:0}),e._addClass(e.ghost,"ui-resizable-ghost"),t.uiBackCompat!==!1&&"string"==typeof e.options.ghost&&e.ghost.addClass(this.options.ghost),e.ghost.appendTo(e.helper)},resize:function(){var e=t(this).resizable("instance");e.ghost&&e.ghost.css({position:"relative",height:e.size.height,width:e.size.width})},stop:function(){var e=t(this).resizable("instance");e.ghost&&e.helper&&e.helper.get(0).removeChild(e.ghost.get(0))}}),t.ui.plugin.add("resizable","grid",{resize:function(){var e,i=t(this).resizable("instance"),s=i.options,n=i.size,o=i.originalSize,a=i.originalPosition,r=i.axis,h="number"==typeof s.grid?[s.grid,s.grid]:s.grid,l=h[0]||1,c=h[1]||1,u=Math.round((n.width-o.width)/l)*l,d=Math.round((n.height-o.height)/c)*c,p=o.width+u,f=o.height+d,g=s.maxWidth&&p>s.maxWidth,m=s.maxHeight&&f>s.maxHeight,_=s.minWidth&&s.minWidth>p,v=s.minHeight&&s.minHeight>f;s.grid=h,_&&(p+=l),v&&(f+=c),g&&(p-=l),m&&(f-=c),/^(se|s|e)$/.test(r)?(i.size.width=p,i.size.height=f):/^(ne)$/.test(r)?(i.size.width=p,i.size.height=f,i.position.top=a.top-d):/^(sw)$/.test(r)?(i.size.width=p,i.size.height=f,i.position.left=a.left-u):((0>=f-c||0>=p-l)&&(e=i._getPaddingPlusBorderDimensions(this)),f-c>0?(i.size.height=f,i.position.top=a.top-d):(f=c-e.height,i.size.height=f,i.position.top=a.top+o.height-f),p-l>0?(i.size.width=p,i.position.left=a.left-u):(p=l-e.width,i.size.width=p,i.position.left=a.left+o.width-p))}}),t.ui.resizable,t.widget("ui.selectable",t.ui.mouse,{version:"1.12.1",options:{appendTo:"body",autoRefresh:!0,distance:0,filter:"*",tolerance:"touch",selected:null,selecting:null,start:null,stop:null,unselected:null,unselecting:null},_create:function(){var e=this;this._addClass("ui-selectable"),this.dragged=!1,this.refresh=function(){e.elementPos=t(e.element[0]).offset(),e.selectees=t(e.options.filter,e.element[0]),e._addClass(e.selectees,"ui-selectee"),e.selectees.each(function(){var i=t(this),s=i.offset(),n={left:s.left-e.elementPos.left,top:s.top-e.elementPos.top};t.data(this,"selectable-item",{element:this,$element:i,left:n.left,top:n.top,right:n.left+i.outerWidth(),bottom:n.top+i.outerHeight(),startselected:!1,selected:i.hasClass("ui-selected"),selecting:i.hasClass("ui-selecting"),unselecting:i.hasClass("ui-unselecting")})})},this.refresh(),this._mouseInit(),this.helper=t("<div>"),this._addClass(this.helper,"ui-selectable-helper")},_destroy:function(){this.selectees.removeData("selectable-item"),this._mouseDestroy()},_mouseStart:function(e){var i=this,s=this.options;this.opos=[e.pageX,e.pageY],this.elementPos=t(this.element[0]).offset(),this.options.disabled||(this.selectees=t(s.filter,this.element[0]),this._trigger("start",e),t(s.appendTo).append(this.helper),this.helper.css({left:e.pageX,top:e.pageY,width:0,height:0}),s.autoRefresh&&this.refresh(),this.selectees.filter(".ui-selected").each(function(){var s=t.data(this,"selectable-item");s.startselected=!0,e.metaKey||e.ctrlKey||(i._removeClass(s.$element,"ui-selected"),s.selected=!1,i._addClass(s.$element,"ui-unselecting"),s.unselecting=!0,i._trigger("unselecting",e,{unselecting:s.element}))}),t(e.target).parents().addBack().each(function(){var s,n=t.data(this,"selectable-item");return n?(s=!e.metaKey&&!e.ctrlKey||!n.$element.hasClass("ui-selected"),i._removeClass(n.$element,s?"ui-unselecting":"ui-selected")._addClass(n.$element,s?"ui-selecting":"ui-unselecting"),n.unselecting=!s,n.selecting=s,n.selected=s,s?i._trigger("selecting",e,{selecting:n.element}):i._trigger("unselecting",e,{unselecting:n.element}),!1):void 0}))},_mouseDrag:function(e){if(this.dragged=!0,!this.options.disabled){var i,s=this,n=this.options,o=this.opos[0],a=this.opos[1],r=e.pageX,h=e.pageY;return o>r&&(i=r,r=o,o=i),a>h&&(i=h,h=a,a=i),this.helper.css({left:o,top:a,width:r-o,height:h-a}),this.selectees.each(function(){var i=t.data(this,"selectable-item"),l=!1,c={};i&&i.element!==s.element[0]&&(c.left=i.left+s.elementPos.left,c.right=i.right+s.elementPos.left,c.top=i.top+s.elementPos.top,c.bottom=i.bottom+s.elementPos.top,"touch"===n.tolerance?l=!(c.left>r||o>c.right||c.top>h||a>c.bottom):"fit"===n.tolerance&&(l=c.left>o&&r>c.right&&c.top>a&&h>c.bottom),l?(i.selected&&(s._removeClass(i.$element,"ui-selected"),i.selected=!1),i.unselecting&&(s._removeClass(i.$element,"ui-unselecting"),i.unselecting=!1),i.selecting||(s._addClass(i.$element,"ui-selecting"),i.selecting=!0,s._trigger("selecting",e,{selecting:i.element}))):(i.selecting&&((e.metaKey||e.ctrlKey)&&i.startselected?(s._removeClass(i.$element,"ui-selecting"),i.selecting=!1,s._addClass(i.$element,"ui-selected"),i.selected=!0):(s._removeClass(i.$element,"ui-selecting"),i.selecting=!1,i.startselected&&(s._addClass(i.$element,"ui-unselecting"),i.unselecting=!0),s._trigger("unselecting",e,{unselecting:i.element}))),i.selected&&(e.metaKey||e.ctrlKey||i.startselected||(s._removeClass(i.$element,"ui-selected"),i.selected=!1,s._addClass(i.$element,"ui-unselecting"),i.unselecting=!0,s._trigger("unselecting",e,{unselecting:i.element})))))}),!1}},_mouseStop:function(e){var i=this;return this.dragged=!1,t(".ui-unselecting",this.element[0]).each(function(){var s=t.data(this,"selectable-item");i._removeClass(s.$element,"ui-unselecting"),s.unselecting=!1,s.startselected=!1,i._trigger("unselected",e,{unselected:s.element})}),t(".ui-selecting",this.element[0]).each(function(){var s=t.data(this,"selectable-item");i._removeClass(s.$element,"ui-selecting")._addClass(s.$element,"ui-selected"),s.selecting=!1,s.selected=!0,s.startselected=!0,i._trigger("selected",e,{selected:s.element})}),this._trigger("stop",e),this.helper.remove(),!1}}),t.widget("ui.sortable",t.ui.mouse,{version:"1.12.1",widgetEventPrefix:"sort",ready:!1,options:{appendTo:"parent",axis:!1,connectWith:!1,containment:!1,cursor:"auto",cursorAt:!1,dropOnEmpty:!0,forcePlaceholderSize:!1,forceHelperSize:!1,grid:!1,handle:!1,helper:"original",items:"> *",opacity:!1,placeholder:!1,revert:!1,scroll:!0,scrollSensitivity:20,scrollSpeed:20,scope:"default",tolerance:"intersect",zIndex:1e3,activate:null,beforeStop:null,change:null,deactivate:null,out:null,over:null,receive:null,remove:null,sort:null,start:null,stop:null,update:null},_isOverAxis:function(t,e,i){return t>=e&&e+i>t},_isFloating:function(t){return/left|right/.test(t.css("float"))||/inline|table-cell/.test(t.css("display"))},_create:function(){this.containerCache={},this._addClass("ui-sortable"),this.refresh(),this.offset=this.element.offset(),this._mouseInit(),this._setHandleClassName(),this.ready=!0},_setOption:function(t,e){this._super(t,e),"handle"===t&&this._setHandleClassName()},_setHandleClassName:function(){var e=this;this._removeClass(this.element.find(".ui-sortable-handle"),"ui-sortable-handle"),t.each(this.items,function(){e._addClass(this.instance.options.handle?this.item.find(this.instance.options.handle):this.item,"ui-sortable-handle")})},_destroy:function(){this._mouseDestroy();for(var t=this.items.length-1;t>=0;t--)this.items[t].item.removeData(this.widgetName+"-item");return this},_mouseCapture:function(e,i){var s=null,n=!1,o=this;return this.reverting?!1:this.options.disabled||"static"===this.options.type?!1:(this._refreshItems(e),t(e.target).parents().each(function(){return t.data(this,o.widgetName+"-item")===o?(s=t(this),!1):void 0}),t.data(e.target,o.widgetName+"-item")===o&&(s=t(e.target)),s?!this.options.handle||i||(t(this.options.handle,s).find("*").addBack().each(function(){this===e.target&&(n=!0)}),n)?(this.currentItem=s,this._removeCurrentsFromItems(),!0):!1:!1)},_mouseStart:function(e,i,s){var n,o,a=this.options;if(this.currentContainer=this,this.refreshPositions(),this.helper=this._createHelper(e),this._cacheHelperProportions(),this._cacheMargins(),this.scrollParent=this.helper.scrollParent(),this.offset=this.currentItem.offset(),this.offset={top:this.offset.top-this.margins.top,left:this.offset.left-this.margins.left},t.extend(this.offset,{click:{left:e.pageX-this.offset.left,top:e.pageY-this.offset.top},parent:this._getParentOffset(),relative:this._getRelativeOffset()}),this.helper.css("position","absolute"),this.cssPosition=this.helper.css("position"),this.originalPosition=this._generatePosition(e),this.originalPageX=e.pageX,this.originalPageY=e.pageY,a.cursorAt&&this._adjustOffsetFromHelper(a.cursorAt),this.domPosition={prev:this.currentItem.prev()[0],parent:this.currentItem.parent()[0]},this.helper[0]!==this.currentItem[0]&&this.currentItem.hide(),this._createPlaceholder(),a.containment&&this._setContainment(),a.cursor&&"auto"!==a.cursor&&(o=this.document.find("body"),this.storedCursor=o.css("cursor"),o.css("cursor",a.cursor),this.storedStylesheet=t("<style>*{ cursor: "+a.cursor+" !important; }</style>").appendTo(o)),a.opacity&&(this.helper.css("opacity")&&(this._storedOpacity=this.helper.css("opacity")),this.helper.css("opacity",a.opacity)),a.zIndex&&(this.helper.css("zIndex")&&(this._storedZIndex=this.helper.css("zIndex")),this.helper.css("zIndex",a.zIndex)),this.scrollParent[0]!==this.document[0]&&"HTML"!==this.scrollParent[0].tagName&&(this.overflowOffset=this.scrollParent.offset()),this._trigger("start",e,this._uiHash()),this._preserveHelperProportions||this._cacheHelperProportions(),!s)for(n=this.containers.length-1;n>=0;n--)this.containers[n]._trigger("activate",e,this._uiHash(this));return t.ui.ddmanager&&(t.ui.ddmanager.current=this),t.ui.ddmanager&&!a.dropBehaviour&&t.ui.ddmanager.prepareOffsets(this,e),this.dragging=!0,this._addClass(this.helper,"ui-sortable-helper"),this._mouseDrag(e),!0},_mouseDrag:function(e){var i,s,n,o,a=this.options,r=!1;for(this.position=this._generatePosition(e),this.positionAbs=this._convertPositionTo("absolute"),this.lastPositionAbs||(this.lastPositionAbs=this.positionAbs),this.options.scroll&&(this.scrollParent[0]!==this.document[0]&&"HTML"!==this.scrollParent[0].tagName?(this.overflowOffset.top+this.scrollParent[0].offsetHeight-e.pageY<a.scrollSensitivity?this.scrollParent[0].scrollTop=r=this.scrollParent[0].scrollTop+a.scrollSpeed:e.pageY-this.overflowOffset.top<a.scrollSensitivity&&(this.scrollParent[0].scrollTop=r=this.scrollParent[0].scrollTop-a.scrollSpeed),this.overflowOffset.left+this.scrollParent[0].offsetWidth-e.pageX<a.scrollSensitivity?this.scrollParent[0].scrollLeft=r=this.scrollParent[0].scrollLeft+a.scrollSpeed:e.pageX-this.overflowOffset.left<a.scrollSensitivity&&(this.scrollParent[0].scrollLeft=r=this.scrollParent[0].scrollLeft-a.scrollSpeed)):(e.pageY-this.document.scrollTop()<a.scrollSensitivity?r=this.document.scrollTop(this.document.scrollTop()-a.scrollSpeed):this.window.height()-(e.pageY-this.document.scrollTop())<a.scrollSensitivity&&(r=this.document.scrollTop(this.document.scrollTop()+a.scrollSpeed)),e.pageX-this.document.scrollLeft()<a.scrollSensitivity?r=this.document.scrollLeft(this.document.scrollLeft()-a.scrollSpeed):this.window.width()-(e.pageX-this.document.scrollLeft())<a.scrollSensitivity&&(r=this.document.scrollLeft(this.document.scrollLeft()+a.scrollSpeed))),r!==!1&&t.ui.ddmanager&&!a.dropBehaviour&&t.ui.ddmanager.prepareOffsets(this,e)),this.positionAbs=this._convertPositionTo("absolute"),this.options.axis&&"y"===this.options.axis||(this.helper[0].style.left=this.position.left+"px"),this.options.axis&&"x"===this.options.axis||(this.helper[0].style.top=this.position.top+"px"),i=this.items.length-1;i>=0;i--)if(s=this.items[i],n=s.item[0],o=this._intersectsWithPointer(s),o&&s.instance===this.currentContainer&&n!==this.currentItem[0]&&this.placeholder[1===o?"next":"prev"]()[0]!==n&&!t.contains(this.placeholder[0],n)&&("semi-dynamic"===this.options.type?!t.contains(this.element[0],n):!0)){if(this.direction=1===o?"down":"up","pointer"!==this.options.tolerance&&!this._intersectsWithSides(s))break;this._rearrange(e,s),this._trigger("change",e,this._uiHash());break}return this._contactContainers(e),t.ui.ddmanager&&t.ui.ddmanager.drag(this,e),this._trigger("sort",e,this._uiHash()),this.lastPositionAbs=this.positionAbs,!1},_mouseStop:function(e,i){if(e){if(t.ui.ddmanager&&!this.options.dropBehaviour&&t.ui.ddmanager.drop(this,e),this.options.revert){var s=this,n=this.placeholder.offset(),o=this.options.axis,a={};o&&"x"!==o||(a.left=n.left-this.offset.parent.left-this.margins.left+(this.offsetParent[0]===this.document[0].body?0:this.offsetParent[0].scrollLeft)),o&&"y"!==o||(a.top=n.top-this.offset.parent.top-this.margins.top+(this.offsetParent[0]===this.document[0].body?0:this.offsetParent[0].scrollTop)),this.reverting=!0,t(this.helper).animate(a,parseInt(this.options.revert,10)||500,function(){s._clear(e)})}else this._clear(e,i);return!1}},cancel:function(){if(this.dragging){this._mouseUp(new t.Event("mouseup",{target:null})),"original"===this.options.helper?(this.currentItem.css(this._storedCSS),this._removeClass(this.currentItem,"ui-sortable-helper")):this.currentItem.show();for(var e=this.containers.length-1;e>=0;e--)this.containers[e]._trigger("deactivate",null,this._uiHash(this)),this.containers[e].containerCache.over&&(this.containers[e]._trigger("out",null,this._uiHash(this)),this.containers[e].containerCache.over=0)}return this.placeholder&&(this.placeholder[0].parentNode&&this.placeholder[0].parentNode.removeChild(this.placeholder[0]),"original"!==this.options.helper&&this.helper&&this.helper[0].parentNode&&this.helper.remove(),t.extend(this,{helper:null,dragging:!1,reverting:!1,_noFinalSort:null}),this.domPosition.prev?t(this.domPosition.prev).after(this.currentItem):t(this.domPosition.parent).prepend(this.currentItem)),this},serialize:function(e){var i=this._getItemsAsjQuery(e&&e.connected),s=[];return e=e||{},t(i).each(function(){var i=(t(e.item||this).attr(e.attribute||"id")||"").match(e.expression||/(.+)[\-=_](.+)/);i&&s.push((e.key||i[1]+"[]")+"="+(e.key&&e.expression?i[1]:i[2]))}),!s.length&&e.key&&s.push(e.key+"="),s.join("&")},toArray:function(e){var i=this._getItemsAsjQuery(e&&e.connected),s=[];return e=e||{},i.each(function(){s.push(t(e.item||this).attr(e.attribute||"id")||"")}),s},_intersectsWith:function(t){var e=this.positionAbs.left,i=e+this.helperProportions.width,s=this.positionAbs.top,n=s+this.helperProportions.height,o=t.left,a=o+t.width,r=t.top,h=r+t.height,l=this.offset.click.top,c=this.offset.click.left,u="x"===this.options.axis||s+l>r&&h>s+l,d="y"===this.options.axis||e+c>o&&a>e+c,p=u&&d;return"pointer"===this.options.tolerance||this.options.forcePointerForContainers||"pointer"!==this.options.tolerance&&this.helperProportions[this.floating?"width":"height"]>t[this.floating?"width":"height"]?p:e+this.helperProportions.width/2>o&&a>i-this.helperProportions.width/2&&s+this.helperProportions.height/2>r&&h>n-this.helperProportions.height/2},_intersectsWithPointer:function(t){var e,i,s="x"===this.options.axis||this._isOverAxis(this.positionAbs.top+this.offset.click.top,t.top,t.height),n="y"===this.options.axis||this._isOverAxis(this.positionAbs.left+this.offset.click.left,t.left,t.width),o=s&&n;return o?(e=this._getDragVerticalDirection(),i=this._getDragHorizontalDirection(),this.floating?"right"===i||"down"===e?2:1:e&&("down"===e?2:1)):!1},_intersectsWithSides:function(t){var e=this._isOverAxis(this.positionAbs.top+this.offset.click.top,t.top+t.height/2,t.height),i=this._isOverAxis(this.positionAbs.left+this.offset.click.left,t.left+t.width/2,t.width),s=this._getDragVerticalDirection(),n=this._getDragHorizontalDirection();return this.floating&&n?"right"===n&&i||"left"===n&&!i:s&&("down"===s&&e||"up"===s&&!e)},_getDragVerticalDirection:function(){var t=this.positionAbs.top-this.lastPositionAbs.top;return 0!==t&&(t>0?"down":"up")},_getDragHorizontalDirection:function(){var t=this.positionAbs.left-this.lastPositionAbs.left;return 0!==t&&(t>0?"right":"left")},refresh:function(t){return this._refreshItems(t),this._setHandleClassName(),this.refreshPositions(),this},_connectWith:function(){var t=this.options;return t.connectWith.constructor===String?[t.connectWith]:t.connectWith},_getItemsAsjQuery:function(e){function i(){r.push(this)}var s,n,o,a,r=[],h=[],l=this._connectWith();if(l&&e)for(s=l.length-1;s>=0;s--)for(o=t(l[s],this.document[0]),n=o.length-1;n>=0;n--)a=t.data(o[n],this.widgetFullName),a&&a!==this&&!a.options.disabled&&h.push([t.isFunction(a.options.items)?a.options.items.call(a.element):t(a.options.items,a.element).not(".ui-sortable-helper").not(".ui-sortable-placeholder"),a]);for(h.push([t.isFunction(this.options.items)?this.options.items.call(this.element,null,{options:this.options,item:this.currentItem}):t(this.options.items,this.element).not(".ui-sortable-helper").not(".ui-sortable-placeholder"),this]),s=h.length-1;s>=0;s--)h[s][0].each(i);return t(r)},_removeCurrentsFromItems:function(){var e=this.currentItem.find(":data("+this.widgetName+"-item)");this.items=t.grep(this.items,function(t){for(var i=0;e.length>i;i++)if(e[i]===t.item[0])return!1;return!0})},_refreshItems:function(e){this.items=[],this.containers=[this];var i,s,n,o,a,r,h,l,c=this.items,u=[[t.isFunction(this.options.items)?this.options.items.call(this.element[0],e,{item:this.currentItem}):t(this.options.items,this.element),this]],d=this._connectWith();if(d&&this.ready)for(i=d.length-1;i>=0;i--)for(n=t(d[i],this.document[0]),s=n.length-1;s>=0;s--)o=t.data(n[s],this.widgetFullName),o&&o!==this&&!o.options.disabled&&(u.push([t.isFunction(o.options.items)?o.options.items.call(o.element[0],e,{item:this.currentItem}):t(o.options.items,o.element),o]),this.containers.push(o));for(i=u.length-1;i>=0;i--)for(a=u[i][1],r=u[i][0],s=0,l=r.length;l>s;s++)h=t(r[s]),h.data(this.widgetName+"-item",a),c.push({item:h,instance:a,width:0,height:0,left:0,top:0})},refreshPositions:function(e){this.floating=this.items.length?"x"===this.options.axis||this._isFloating(this.items[0].item):!1,this.offsetParent&&this.helper&&(this.offset.parent=this._getParentOffset());var i,s,n,o;for(i=this.items.length-1;i>=0;i--)s=this.items[i],s.instance!==this.currentContainer&&this.currentContainer&&s.item[0]!==this.currentItem[0]||(n=this.options.toleranceElement?t(this.options.toleranceElement,s.item):s.item,e||(s.width=n.outerWidth(),s.height=n.outerHeight()),o=n.offset(),s.left=o.left,s.top=o.top);if(this.options.custom&&this.options.custom.refreshContainers)this.options.custom.refreshContainers.call(this);else for(i=this.containers.length-1;i>=0;i--)o=this.containers[i].element.offset(),this.containers[i].containerCache.left=o.left,this.containers[i].containerCache.top=o.top,this.containers[i].containerCache.width=this.containers[i].element.outerWidth(),this.containers[i].containerCache.height=this.containers[i].element.outerHeight();return this},_createPlaceholder:function(e){e=e||this;var i,s=e.options;s.placeholder&&s.placeholder.constructor!==String||(i=s.placeholder,s.placeholder={element:function(){var s=e.currentItem[0].nodeName.toLowerCase(),n=t("<"+s+">",e.document[0]);return e._addClass(n,"ui-sortable-placeholder",i||e.currentItem[0].className)._removeClass(n,"ui-sortable-helper"),"tbody"===s?e._createTrPlaceholder(e.currentItem.find("tr").eq(0),t("<tr>",e.document[0]).appendTo(n)):"tr"===s?e._createTrPlaceholder(e.currentItem,n):"img"===s&&n.attr("src",e.currentItem.attr("src")),i||n.css("visibility","hidden"),n},update:function(t,n){(!i||s.forcePlaceholderSize)&&(n.height()||n.height(e.currentItem.innerHeight()-parseInt(e.currentItem.css("paddingTop")||0,10)-parseInt(e.currentItem.css("paddingBottom")||0,10)),n.width()||n.width(e.currentItem.innerWidth()-parseInt(e.currentItem.css("paddingLeft")||0,10)-parseInt(e.currentItem.css("paddingRight")||0,10)))}}),e.placeholder=t(s.placeholder.element.call(e.element,e.currentItem)),e.currentItem.after(e.placeholder),s.placeholder.update(e,e.placeholder)},_createTrPlaceholder:function(e,i){var s=this;e.children().each(function(){t("<td> </td>",s.document[0]).attr("colspan",t(this).attr("colspan")||1).appendTo(i)})},_contactContainers:function(e){var i,s,n,o,a,r,h,l,c,u,d=null,p=null;for(i=this.containers.length-1;i>=0;i--)if(!t.contains(this.currentItem[0],this.containers[i].element[0]))if(this._intersectsWith(this.containers[i].containerCache)){if(d&&t.contains(this.containers[i].element[0],d.element[0]))continue;d=this.containers[i],p=i}else this.containers[i].containerCache.over&&(this.containers[i]._trigger("out",e,this._uiHash(this)),this.containers[i].containerCache.over=0);if(d)if(1===this.containers.length)this.containers[p].containerCache.over||(this.containers[p]._trigger("over",e,this._uiHash(this)),this.containers[p].containerCache.over=1);else{for(n=1e4,o=null,c=d.floating||this._isFloating(this.currentItem),a=c?"left":"top",r=c?"width":"height",u=c?"pageX":"pageY",s=this.items.length-1;s>=0;s--)t.contains(this.containers[p].element[0],this.items[s].item[0])&&this.items[s].item[0]!==this.currentItem[0]&&(h=this.items[s].item.offset()[a],l=!1,e[u]-h>this.items[s][r]/2&&(l=!0),n>Math.abs(e[u]-h)&&(n=Math.abs(e[u]-h),o=this.items[s],this.direction=l?"up":"down"));if(!o&&!this.options.dropOnEmpty)return;if(this.currentContainer===this.containers[p])return this.currentContainer.containerCache.over||(this.containers[p]._trigger("over",e,this._uiHash()),this.currentContainer.containerCache.over=1),void 0;o?this._rearrange(e,o,null,!0):this._rearrange(e,null,this.containers[p].element,!0),this._trigger("change",e,this._uiHash()),this.containers[p]._trigger("change",e,this._uiHash(this)),this.currentContainer=this.containers[p],this.options.placeholder.update(this.currentContainer,this.placeholder),this.containers[p]._trigger("over",e,this._uiHash(this)),this.containers[p].containerCache.over=1}},_createHelper:function(e){var i=this.options,s=t.isFunction(i.helper)?t(i.helper.apply(this.element[0],[e,this.currentItem])):"clone"===i.helper?this.currentItem.clone():this.currentItem;return s.parents("body").length||t("parent"!==i.appendTo?i.appendTo:this.currentItem[0].parentNode)[0].appendChild(s[0]),s[0]===this.currentItem[0]&&(this._storedCSS={width:this.currentItem[0].style.width,height:this.currentItem[0].style.height,position:this.currentItem.css("position"),top:this.currentItem.css("top"),left:this.currentItem.css("left")}),(!s[0].style.width||i.forceHelperSize)&&s.width(this.currentItem.width()),(!s[0].style.height||i.forceHelperSize)&&s.height(this.currentItem.height()),s},_adjustOffsetFromHelper:function(e){"string"==typeof e&&(e=e.split(" ")),t.isArray(e)&&(e={left:+e[0],top:+e[1]||0}),"left"in e&&(this.offset.click.left=e.left+this.margins.left),"right"in e&&(this.offset.click.left=this.helperProportions.width-e.right+this.margins.left),"top"in e&&(this.offset.click.top=e.top+this.margins.top),"bottom"in e&&(this.offset.click.top=this.helperProportions.height-e.bottom+this.margins.top)},_getParentOffset:function(){this.offsetParent=this.helper.offsetParent();var e=this.offsetParent.offset();return"absolute"===this.cssPosition&&this.scrollParent[0]!==this.document[0]&&t.contains(this.scrollParent[0],this.offsetParent[0])&&(e.left+=this.scrollParent.scrollLeft(),e.top+=this.scrollParent.scrollTop()),(this.offsetParent[0]===this.document[0].body||this.offsetParent[0].tagName&&"html"===this.offsetParent[0].tagName.toLowerCase()&&t.ui.ie)&&(e={top:0,left:0}),{top:e.top+(parseInt(this.offsetParent.css("borderTopWidth"),10)||0),left:e.left+(parseInt(this.offsetParent.css("borderLeftWidth"),10)||0)}},_getRelativeOffset:function(){if("relative"===this.cssPosition){var t=this.currentItem.position();return{top:t.top-(parseInt(this.helper.css("top"),10)||0)+this.scrollParent.scrollTop(),left:t.left-(parseInt(this.helper.css("left"),10)||0)+this.scrollParent.scrollLeft()}}return{top:0,left:0}},_cacheMargins:function(){this.margins={left:parseInt(this.currentItem.css("marginLeft"),10)||0,top:parseInt(this.currentItem.css("marginTop"),10)||0}},_cacheHelperProportions:function(){this.helperProportions={width:this.helper.outerWidth(),height:this.helper.outerHeight()}},_setContainment:function(){var e,i,s,n=this.options;"parent"===n.containment&&(n.containment=this.helper[0].parentNode),("document"===n.containment||"window"===n.containment)&&(this.containment=[0-this.offset.relative.left-this.offset.parent.left,0-this.offset.relative.top-this.offset.parent.top,"document"===n.containment?this.document.width():this.window.width()-this.helperProportions.width-this.margins.left,("document"===n.containment?this.document.height()||document.body.parentNode.scrollHeight:this.window.height()||this.document[0].body.parentNode.scrollHeight)-this.helperProportions.height-this.margins.top]),/^(document|window|parent)$/.test(n.containment)||(e=t(n.containment)[0],i=t(n.containment).offset(),s="hidden"!==t(e).css("overflow"),this.containment=[i.left+(parseInt(t(e).css("borderLeftWidth"),10)||0)+(parseInt(t(e).css("paddingLeft"),10)||0)-this.margins.left,i.top+(parseInt(t(e).css("borderTopWidth"),10)||0)+(parseInt(t(e).css("paddingTop"),10)||0)-this.margins.top,i.left+(s?Math.max(e.scrollWidth,e.offsetWidth):e.offsetWidth)-(parseInt(t(e).css("borderLeftWidth"),10)||0)-(parseInt(t(e).css("paddingRight"),10)||0)-this.helperProportions.width-this.margins.left,i.top+(s?Math.max(e.scrollHeight,e.offsetHeight):e.offsetHeight)-(parseInt(t(e).css("borderTopWidth"),10)||0)-(parseInt(t(e).css("paddingBottom"),10)||0)-this.helperProportions.height-this.margins.top])},_convertPositionTo:function(e,i){i||(i=this.position);var s="absolute"===e?1:-1,n="absolute"!==this.cssPosition||this.scrollParent[0]!==this.document[0]&&t.contains(this.scrollParent[0],this.offsetParent[0])?this.scrollParent:this.offsetParent,o=/(html|body)/i.test(n[0].tagName);return{top:i.top+this.offset.relative.top*s+this.offset.parent.top*s-("fixed"===this.cssPosition?-this.scrollParent.scrollTop():o?0:n.scrollTop())*s,left:i.left+this.offset.relative.left*s+this.offset.parent.left*s-("fixed"===this.cssPosition?-this.scrollParent.scrollLeft():o?0:n.scrollLeft())*s}},_generatePosition:function(e){var i,s,n=this.options,o=e.pageX,a=e.pageY,r="absolute"!==this.cssPosition||this.scrollParent[0]!==this.document[0]&&t.contains(this.scrollParent[0],this.offsetParent[0])?this.scrollParent:this.offsetParent,h=/(html|body)/i.test(r[0].tagName);return"relative"!==this.cssPosition||this.scrollParent[0]!==this.document[0]&&this.scrollParent[0]!==this.offsetParent[0]||(this.offset.relative=this._getRelativeOffset()),this.originalPosition&&(this.containment&&(e.pageX-this.offset.click.left<this.containment[0]&&(o=this.containment[0]+this.offset.click.left),e.pageY-this.offset.click.top<this.containment[1]&&(a=this.containment[1]+this.offset.click.top),e.pageX-this.offset.click.left>this.containment[2]&&(o=this.containment[2]+this.offset.click.left),e.pageY-this.offset.click.top>this.containment[3]&&(a=this.containment[3]+this.offset.click.top)),n.grid&&(i=this.originalPageY+Math.round((a-this.originalPageY)/n.grid[1])*n.grid[1],a=this.containment?i-this.offset.click.top>=this.containment[1]&&i-this.offset.click.top<=this.containment[3]?i:i-this.offset.click.top>=this.containment[1]?i-n.grid[1]:i+n.grid[1]:i,s=this.originalPageX+Math.round((o-this.originalPageX)/n.grid[0])*n.grid[0],o=this.containment?s-this.offset.click.left>=this.containment[0]&&s-this.offset.click.left<=this.containment[2]?s:s-this.offset.click.left>=this.containment[0]?s-n.grid[0]:s+n.grid[0]:s)),{top:a-this.offset.click.top-this.offset.relative.top-this.offset.parent.top+("fixed"===this.cssPosition?-this.scrollParent.scrollTop():h?0:r.scrollTop()),left:o-this.offset.click.left-this.offset.relative.left-this.offset.parent.left+("fixed"===this.cssPosition?-this.scrollParent.scrollLeft():h?0:r.scrollLeft())}},_rearrange:function(t,e,i,s){i?i[0].appendChild(this.placeholder[0]):e.item[0].parentNode.insertBefore(this.placeholder[0],"down"===this.direction?e.item[0]:e.item[0].nextSibling),this.counter=this.counter?++this.counter:1;var n=this.counter;this._delay(function(){n===this.counter&&this.refreshPositions(!s)})},_clear:function(t,e){function i(t,e,i){return function(s){i._trigger(t,s,e._uiHash(e))}}this.reverting=!1;var s,n=[];if(!this._noFinalSort&&this.currentItem.parent().length&&this.placeholder.before(this.currentItem),this._noFinalSort=null,this.helper[0]===this.currentItem[0]){for(s in this._storedCSS)("auto"===this._storedCSS[s]||"static"===this._storedCSS[s])&&(this._storedCSS[s]="");this.currentItem.css(this._storedCSS),this._removeClass(this.currentItem,"ui-sortable-helper")}else this.currentItem.show();for(this.fromOutside&&!e&&n.push(function(t){this._trigger("receive",t,this._uiHash(this.fromOutside))}),!this.fromOutside&&this.domPosition.prev===this.currentItem.prev().not(".ui-sortable-helper")[0]&&this.domPosition.parent===this.currentItem.parent()[0]||e||n.push(function(t){this._trigger("update",t,this._uiHash())}),this!==this.currentContainer&&(e||(n.push(function(t){this._trigger("remove",t,this._uiHash())}),n.push(function(t){return function(e){t._trigger("receive",e,this._uiHash(this))}}.call(this,this.currentContainer)),n.push(function(t){return function(e){t._trigger("update",e,this._uiHash(this))}}.call(this,this.currentContainer)))),s=this.containers.length-1;s>=0;s--)e||n.push(i("deactivate",this,this.containers[s])),this.containers[s].containerCache.over&&(n.push(i("out",this,this.containers[s])),this.containers[s].containerCache.over=0);if(this.storedCursor&&(this.document.find("body").css("cursor",this.storedCursor),this.storedStylesheet.remove()),this._storedOpacity&&this.helper.css("opacity",this._storedOpacity),this._storedZIndex&&this.helper.css("zIndex","auto"===this._storedZIndex?"":this._storedZIndex),this.dragging=!1,e||this._trigger("beforeStop",t,this._uiHash()),this.placeholder[0].parentNode.removeChild(this.placeholder[0]),this.cancelHelperRemoval||(this.helper[0]!==this.currentItem[0]&&this.helper.remove(),this.helper=null),!e){for(s=0;n.length>s;s++)n[s].call(this,t);this._trigger("stop",t,this._uiHash())}return this.fromOutside=!1,!this.cancelHelperRemoval},_trigger:function(){t.Widget.prototype._trigger.apply(this,arguments)===!1&&this.cancel()},_uiHash:function(e){var i=e||this;return{helper:i.helper,placeholder:i.placeholder||t([]),position:i.position,originalPosition:i.originalPosition,offset:i.positionAbs,item:i.currentItem,sender:e?e.element:null}}}),t.widget("ui.accordion",{version:"1.12.1",options:{active:0,animate:{},classes:{"ui-accordion-header":"ui-corner-top","ui-accordion-header-collapsed":"ui-corner-all","ui-accordion-content":"ui-corner-bottom"},collapsible:!1,event:"click",header:"> li > :first-child, > :not(li):even",heightStyle:"auto",icons:{activeHeader:"ui-icon-triangle-1-s",header:"ui-icon-triangle-1-e"},activate:null,beforeActivate:null},hideProps:{borderTopWidth:"hide",borderBottomWidth:"hide",paddingTop:"hide",paddingBottom:"hide",height:"hide"},showProps:{borderTopWidth:"show",borderBottomWidth:"show",paddingTop:"show",paddingBottom:"show",height:"show"},_create:function(){var e=this.options;this.prevShow=this.prevHide=t(),this._addClass("ui-accordion","ui-widget ui-helper-reset"),this.element.attr("role","tablist"),e.collapsible||e.active!==!1&&null!=e.active||(e.active=0),this._processPanels(),0>e.active&&(e.active+=this.headers.length),this._refresh()},_getCreateEventData:function(){return{header:this.active,panel:this.active.length?this.active.next():t()}},_createIcons:function(){var e,i,s=this.options.icons;s&&(e=t("<span>"),this._addClass(e,"ui-accordion-header-icon","ui-icon "+s.header),e.prependTo(this.headers),i=this.active.children(".ui-accordion-header-icon"),this._removeClass(i,s.header)._addClass(i,null,s.activeHeader)._addClass(this.headers,"ui-accordion-icons"))
|
||
},_destroyIcons:function(){this._removeClass(this.headers,"ui-accordion-icons"),this.headers.children(".ui-accordion-header-icon").remove()},_destroy:function(){var t;this.element.removeAttr("role"),this.headers.removeAttr("role aria-expanded aria-selected aria-controls tabIndex").removeUniqueId(),this._destroyIcons(),t=this.headers.next().css("display","").removeAttr("role aria-hidden aria-labelledby").removeUniqueId(),"content"!==this.options.heightStyle&&t.css("height","")},_setOption:function(t,e){return"active"===t?(this._activate(e),void 0):("event"===t&&(this.options.event&&this._off(this.headers,this.options.event),this._setupEvents(e)),this._super(t,e),"collapsible"!==t||e||this.options.active!==!1||this._activate(0),"icons"===t&&(this._destroyIcons(),e&&this._createIcons()),void 0)},_setOptionDisabled:function(t){this._super(t),this.element.attr("aria-disabled",t),this._toggleClass(null,"ui-state-disabled",!!t),this._toggleClass(this.headers.add(this.headers.next()),null,"ui-state-disabled",!!t)},_keydown:function(e){if(!e.altKey&&!e.ctrlKey){var i=t.ui.keyCode,s=this.headers.length,n=this.headers.index(e.target),o=!1;switch(e.keyCode){case i.RIGHT:case i.DOWN:o=this.headers[(n+1)%s];break;case i.LEFT:case i.UP:o=this.headers[(n-1+s)%s];break;case i.SPACE:case i.ENTER:this._eventHandler(e);break;case i.HOME:o=this.headers[0];break;case i.END:o=this.headers[s-1]}o&&(t(e.target).attr("tabIndex",-1),t(o).attr("tabIndex",0),t(o).trigger("focus"),e.preventDefault())}},_panelKeyDown:function(e){e.keyCode===t.ui.keyCode.UP&&e.ctrlKey&&t(e.currentTarget).prev().trigger("focus")},refresh:function(){var e=this.options;this._processPanels(),e.active===!1&&e.collapsible===!0||!this.headers.length?(e.active=!1,this.active=t()):e.active===!1?this._activate(0):this.active.length&&!t.contains(this.element[0],this.active[0])?this.headers.length===this.headers.find(".ui-state-disabled").length?(e.active=!1,this.active=t()):this._activate(Math.max(0,e.active-1)):e.active=this.headers.index(this.active),this._destroyIcons(),this._refresh()},_processPanels:function(){var t=this.headers,e=this.panels;this.headers=this.element.find(this.options.header),this._addClass(this.headers,"ui-accordion-header ui-accordion-header-collapsed","ui-state-default"),this.panels=this.headers.next().filter(":not(.ui-accordion-content-active)").hide(),this._addClass(this.panels,"ui-accordion-content","ui-helper-reset ui-widget-content"),e&&(this._off(t.not(this.headers)),this._off(e.not(this.panels)))},_refresh:function(){var e,i=this.options,s=i.heightStyle,n=this.element.parent();this.active=this._findActive(i.active),this._addClass(this.active,"ui-accordion-header-active","ui-state-active")._removeClass(this.active,"ui-accordion-header-collapsed"),this._addClass(this.active.next(),"ui-accordion-content-active"),this.active.next().show(),this.headers.attr("role","tab").each(function(){var e=t(this),i=e.uniqueId().attr("id"),s=e.next(),n=s.uniqueId().attr("id");e.attr("aria-controls",n),s.attr("aria-labelledby",i)}).next().attr("role","tabpanel"),this.headers.not(this.active).attr({"aria-selected":"false","aria-expanded":"false",tabIndex:-1}).next().attr({"aria-hidden":"true"}).hide(),this.active.length?this.active.attr({"aria-selected":"true","aria-expanded":"true",tabIndex:0}).next().attr({"aria-hidden":"false"}):this.headers.eq(0).attr("tabIndex",0),this._createIcons(),this._setupEvents(i.event),"fill"===s?(e=n.height(),this.element.siblings(":visible").each(function(){var i=t(this),s=i.css("position");"absolute"!==s&&"fixed"!==s&&(e-=i.outerHeight(!0))}),this.headers.each(function(){e-=t(this).outerHeight(!0)}),this.headers.next().each(function(){t(this).height(Math.max(0,e-t(this).innerHeight()+t(this).height()))}).css("overflow","auto")):"auto"===s&&(e=0,this.headers.next().each(function(){var i=t(this).is(":visible");i||t(this).show(),e=Math.max(e,t(this).css("height","").height()),i||t(this).hide()}).height(e))},_activate:function(e){var i=this._findActive(e)[0];i!==this.active[0]&&(i=i||this.active[0],this._eventHandler({target:i,currentTarget:i,preventDefault:t.noop}))},_findActive:function(e){return"number"==typeof e?this.headers.eq(e):t()},_setupEvents:function(e){var i={keydown:"_keydown"};e&&t.each(e.split(" "),function(t,e){i[e]="_eventHandler"}),this._off(this.headers.add(this.headers.next())),this._on(this.headers,i),this._on(this.headers.next(),{keydown:"_panelKeyDown"}),this._hoverable(this.headers),this._focusable(this.headers)},_eventHandler:function(e){var i,s,n=this.options,o=this.active,a=t(e.currentTarget),r=a[0]===o[0],h=r&&n.collapsible,l=h?t():a.next(),c=o.next(),u={oldHeader:o,oldPanel:c,newHeader:h?t():a,newPanel:l};e.preventDefault(),r&&!n.collapsible||this._trigger("beforeActivate",e,u)===!1||(n.active=h?!1:this.headers.index(a),this.active=r?t():a,this._toggle(u),this._removeClass(o,"ui-accordion-header-active","ui-state-active"),n.icons&&(i=o.children(".ui-accordion-header-icon"),this._removeClass(i,null,n.icons.activeHeader)._addClass(i,null,n.icons.header)),r||(this._removeClass(a,"ui-accordion-header-collapsed")._addClass(a,"ui-accordion-header-active","ui-state-active"),n.icons&&(s=a.children(".ui-accordion-header-icon"),this._removeClass(s,null,n.icons.header)._addClass(s,null,n.icons.activeHeader)),this._addClass(a.next(),"ui-accordion-content-active")))},_toggle:function(e){var i=e.newPanel,s=this.prevShow.length?this.prevShow:e.oldPanel;this.prevShow.add(this.prevHide).stop(!0,!0),this.prevShow=i,this.prevHide=s,this.options.animate?this._animate(i,s,e):(s.hide(),i.show(),this._toggleComplete(e)),s.attr({"aria-hidden":"true"}),s.prev().attr({"aria-selected":"false","aria-expanded":"false"}),i.length&&s.length?s.prev().attr({tabIndex:-1,"aria-expanded":"false"}):i.length&&this.headers.filter(function(){return 0===parseInt(t(this).attr("tabIndex"),10)}).attr("tabIndex",-1),i.attr("aria-hidden","false").prev().attr({"aria-selected":"true","aria-expanded":"true",tabIndex:0})},_animate:function(t,e,i){var s,n,o,a=this,r=0,h=t.css("box-sizing"),l=t.length&&(!e.length||t.index()<e.index()),c=this.options.animate||{},u=l&&c.down||c,d=function(){a._toggleComplete(i)};return"number"==typeof u&&(o=u),"string"==typeof u&&(n=u),n=n||u.easing||c.easing,o=o||u.duration||c.duration,e.length?t.length?(s=t.show().outerHeight(),e.animate(this.hideProps,{duration:o,easing:n,step:function(t,e){e.now=Math.round(t)}}),t.hide().animate(this.showProps,{duration:o,easing:n,complete:d,step:function(t,i){i.now=Math.round(t),"height"!==i.prop?"content-box"===h&&(r+=i.now):"content"!==a.options.heightStyle&&(i.now=Math.round(s-e.outerHeight()-r),r=0)}}),void 0):e.animate(this.hideProps,o,n,d):t.animate(this.showProps,o,n,d)},_toggleComplete:function(t){var e=t.oldPanel,i=e.prev();this._removeClass(e,"ui-accordion-content-active"),this._removeClass(i,"ui-accordion-header-active")._addClass(i,"ui-accordion-header-collapsed"),e.length&&(e.parent()[0].className=e.parent()[0].className),this._trigger("activate",null,t)}}),t.widget("ui.menu",{version:"1.12.1",defaultElement:"<ul>",delay:300,options:{icons:{submenu:"ui-icon-caret-1-e"},items:"> *",menus:"ul",position:{my:"left top",at:"right top"},role:"menu",blur:null,focus:null,select:null},_create:function(){this.activeMenu=this.element,this.mouseHandled=!1,this.element.uniqueId().attr({role:this.options.role,tabIndex:0}),this._addClass("ui-menu","ui-widget ui-widget-content"),this._on({"mousedown .ui-menu-item":function(t){t.preventDefault()},"click .ui-menu-item":function(e){var i=t(e.target),s=t(t.ui.safeActiveElement(this.document[0]));!this.mouseHandled&&i.not(".ui-state-disabled").length&&(this.select(e),e.isPropagationStopped()||(this.mouseHandled=!0),i.has(".ui-menu").length?this.expand(e):!this.element.is(":focus")&&s.closest(".ui-menu").length&&(this.element.trigger("focus",[!0]),this.active&&1===this.active.parents(".ui-menu").length&&clearTimeout(this.timer)))},"mouseenter .ui-menu-item":function(e){if(!this.previousFilter){var i=t(e.target).closest(".ui-menu-item"),s=t(e.currentTarget);i[0]===s[0]&&(this._removeClass(s.siblings().children(".ui-state-active"),null,"ui-state-active"),this.focus(e,s))}},mouseleave:"collapseAll","mouseleave .ui-menu":"collapseAll",focus:function(t,e){var i=this.active||this.element.find(this.options.items).eq(0);e||this.focus(t,i)},blur:function(e){this._delay(function(){var i=!t.contains(this.element[0],t.ui.safeActiveElement(this.document[0]));i&&this.collapseAll(e)})},keydown:"_keydown"}),this.refresh(),this._on(this.document,{click:function(t){this._closeOnDocumentClick(t)&&this.collapseAll(t),this.mouseHandled=!1}})},_destroy:function(){var e=this.element.find(".ui-menu-item").removeAttr("role aria-disabled"),i=e.children(".ui-menu-item-wrapper").removeUniqueId().removeAttr("tabIndex role aria-haspopup");this.element.removeAttr("aria-activedescendant").find(".ui-menu").addBack().removeAttr("role aria-labelledby aria-expanded aria-hidden aria-disabled tabIndex").removeUniqueId().show(),i.children().each(function(){var e=t(this);e.data("ui-menu-submenu-caret")&&e.remove()})},_keydown:function(e){var i,s,n,o,a=!0;switch(e.keyCode){case t.ui.keyCode.PAGE_UP:this.previousPage(e);break;case t.ui.keyCode.PAGE_DOWN:this.nextPage(e);break;case t.ui.keyCode.HOME:this._move("first","first",e);break;case t.ui.keyCode.END:this._move("last","last",e);break;case t.ui.keyCode.UP:this.previous(e);break;case t.ui.keyCode.DOWN:this.next(e);break;case t.ui.keyCode.LEFT:this.collapse(e);break;case t.ui.keyCode.RIGHT:this.active&&!this.active.is(".ui-state-disabled")&&this.expand(e);break;case t.ui.keyCode.ENTER:case t.ui.keyCode.SPACE:this._activate(e);break;case t.ui.keyCode.ESCAPE:this.collapse(e);break;default:a=!1,s=this.previousFilter||"",o=!1,n=e.keyCode>=96&&105>=e.keyCode?""+(e.keyCode-96):String.fromCharCode(e.keyCode),clearTimeout(this.filterTimer),n===s?o=!0:n=s+n,i=this._filterMenuItems(n),i=o&&-1!==i.index(this.active.next())?this.active.nextAll(".ui-menu-item"):i,i.length||(n=String.fromCharCode(e.keyCode),i=this._filterMenuItems(n)),i.length?(this.focus(e,i),this.previousFilter=n,this.filterTimer=this._delay(function(){delete this.previousFilter},1e3)):delete this.previousFilter}a&&e.preventDefault()},_activate:function(t){this.active&&!this.active.is(".ui-state-disabled")&&(this.active.children("[aria-haspopup='true']").length?this.expand(t):this.select(t))},refresh:function(){var e,i,s,n,o,a=this,r=this.options.icons.submenu,h=this.element.find(this.options.menus);this._toggleClass("ui-menu-icons",null,!!this.element.find(".ui-icon").length),s=h.filter(":not(.ui-menu)").hide().attr({role:this.options.role,"aria-hidden":"true","aria-expanded":"false"}).each(function(){var e=t(this),i=e.prev(),s=t("<span>").data("ui-menu-submenu-caret",!0);a._addClass(s,"ui-menu-icon","ui-icon "+r),i.attr("aria-haspopup","true").prepend(s),e.attr("aria-labelledby",i.attr("id"))}),this._addClass(s,"ui-menu","ui-widget ui-widget-content ui-front"),e=h.add(this.element),i=e.find(this.options.items),i.not(".ui-menu-item").each(function(){var e=t(this);a._isDivider(e)&&a._addClass(e,"ui-menu-divider","ui-widget-content")}),n=i.not(".ui-menu-item, .ui-menu-divider"),o=n.children().not(".ui-menu").uniqueId().attr({tabIndex:-1,role:this._itemRole()}),this._addClass(n,"ui-menu-item")._addClass(o,"ui-menu-item-wrapper"),i.filter(".ui-state-disabled").attr("aria-disabled","true"),this.active&&!t.contains(this.element[0],this.active[0])&&this.blur()},_itemRole:function(){return{menu:"menuitem",listbox:"option"}[this.options.role]},_setOption:function(t,e){if("icons"===t){var i=this.element.find(".ui-menu-icon");this._removeClass(i,null,this.options.icons.submenu)._addClass(i,null,e.submenu)}this._super(t,e)},_setOptionDisabled:function(t){this._super(t),this.element.attr("aria-disabled",t+""),this._toggleClass(null,"ui-state-disabled",!!t)},focus:function(t,e){var i,s,n;this.blur(t,t&&"focus"===t.type),this._scrollIntoView(e),this.active=e.first(),s=this.active.children(".ui-menu-item-wrapper"),this._addClass(s,null,"ui-state-active"),this.options.role&&this.element.attr("aria-activedescendant",s.attr("id")),n=this.active.parent().closest(".ui-menu-item").children(".ui-menu-item-wrapper"),this._addClass(n,null,"ui-state-active"),t&&"keydown"===t.type?this._close():this.timer=this._delay(function(){this._close()},this.delay),i=e.children(".ui-menu"),i.length&&t&&/^mouse/.test(t.type)&&this._startOpening(i),this.activeMenu=e.parent(),this._trigger("focus",t,{item:e})},_scrollIntoView:function(e){var i,s,n,o,a,r;this._hasScroll()&&(i=parseFloat(t.css(this.activeMenu[0],"borderTopWidth"))||0,s=parseFloat(t.css(this.activeMenu[0],"paddingTop"))||0,n=e.offset().top-this.activeMenu.offset().top-i-s,o=this.activeMenu.scrollTop(),a=this.activeMenu.height(),r=e.outerHeight(),0>n?this.activeMenu.scrollTop(o+n):n+r>a&&this.activeMenu.scrollTop(o+n-a+r))},blur:function(t,e){e||clearTimeout(this.timer),this.active&&(this._removeClass(this.active.children(".ui-menu-item-wrapper"),null,"ui-state-active"),this._trigger("blur",t,{item:this.active}),this.active=null)},_startOpening:function(t){clearTimeout(this.timer),"true"===t.attr("aria-hidden")&&(this.timer=this._delay(function(){this._close(),this._open(t)},this.delay))},_open:function(e){var i=t.extend({of:this.active},this.options.position);clearTimeout(this.timer),this.element.find(".ui-menu").not(e.parents(".ui-menu")).hide().attr("aria-hidden","true"),e.show().removeAttr("aria-hidden").attr("aria-expanded","true").position(i)},collapseAll:function(e,i){clearTimeout(this.timer),this.timer=this._delay(function(){var s=i?this.element:t(e&&e.target).closest(this.element.find(".ui-menu"));s.length||(s=this.element),this._close(s),this.blur(e),this._removeClass(s.find(".ui-state-active"),null,"ui-state-active"),this.activeMenu=s},this.delay)},_close:function(t){t||(t=this.active?this.active.parent():this.element),t.find(".ui-menu").hide().attr("aria-hidden","true").attr("aria-expanded","false")},_closeOnDocumentClick:function(e){return!t(e.target).closest(".ui-menu").length},_isDivider:function(t){return!/[^\-\u2014\u2013\s]/.test(t.text())},collapse:function(t){var e=this.active&&this.active.parent().closest(".ui-menu-item",this.element);e&&e.length&&(this._close(),this.focus(t,e))},expand:function(t){var e=this.active&&this.active.children(".ui-menu ").find(this.options.items).first();e&&e.length&&(this._open(e.parent()),this._delay(function(){this.focus(t,e)}))},next:function(t){this._move("next","first",t)},previous:function(t){this._move("prev","last",t)},isFirstItem:function(){return this.active&&!this.active.prevAll(".ui-menu-item").length},isLastItem:function(){return this.active&&!this.active.nextAll(".ui-menu-item").length},_move:function(t,e,i){var s;this.active&&(s="first"===t||"last"===t?this.active["first"===t?"prevAll":"nextAll"](".ui-menu-item").eq(-1):this.active[t+"All"](".ui-menu-item").eq(0)),s&&s.length&&this.active||(s=this.activeMenu.find(this.options.items)[e]()),this.focus(i,s)},nextPage:function(e){var i,s,n;return this.active?(this.isLastItem()||(this._hasScroll()?(s=this.active.offset().top,n=this.element.height(),this.active.nextAll(".ui-menu-item").each(function(){return i=t(this),0>i.offset().top-s-n}),this.focus(e,i)):this.focus(e,this.activeMenu.find(this.options.items)[this.active?"last":"first"]())),void 0):(this.next(e),void 0)},previousPage:function(e){var i,s,n;return this.active?(this.isFirstItem()||(this._hasScroll()?(s=this.active.offset().top,n=this.element.height(),this.active.prevAll(".ui-menu-item").each(function(){return i=t(this),i.offset().top-s+n>0}),this.focus(e,i)):this.focus(e,this.activeMenu.find(this.options.items).first())),void 0):(this.next(e),void 0)},_hasScroll:function(){return this.element.outerHeight()<this.element.prop("scrollHeight")},select:function(e){this.active=this.active||t(e.target).closest(".ui-menu-item");var i={item:this.active};this.active.has(".ui-menu").length||this.collapseAll(e,!0),this._trigger("select",e,i)},_filterMenuItems:function(e){var i=e.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g,"\\$&"),s=RegExp("^"+i,"i");return this.activeMenu.find(this.options.items).filter(".ui-menu-item").filter(function(){return s.test(t.trim(t(this).children(".ui-menu-item-wrapper").text()))})}}),t.widget("ui.autocomplete",{version:"1.12.1",defaultElement:"<input>",options:{appendTo:null,autoFocus:!1,delay:300,minLength:1,position:{my:"left top",at:"left bottom",collision:"none"},source:null,change:null,close:null,focus:null,open:null,response:null,search:null,select:null},requestIndex:0,pending:0,_create:function(){var e,i,s,n=this.element[0].nodeName.toLowerCase(),o="textarea"===n,a="input"===n;this.isMultiLine=o||!a&&this._isContentEditable(this.element),this.valueMethod=this.element[o||a?"val":"text"],this.isNewMenu=!0,this._addClass("ui-autocomplete-input"),this.element.attr("autocomplete","off"),this._on(this.element,{keydown:function(n){if(this.element.prop("readOnly"))return e=!0,s=!0,i=!0,void 0;e=!1,s=!1,i=!1;var o=t.ui.keyCode;switch(n.keyCode){case o.PAGE_UP:e=!0,this._move("previousPage",n);break;case o.PAGE_DOWN:e=!0,this._move("nextPage",n);break;case o.UP:e=!0,this._keyEvent("previous",n);break;case o.DOWN:e=!0,this._keyEvent("next",n);break;case o.ENTER:this.menu.active&&(e=!0,n.preventDefault(),this.menu.select(n));break;case o.TAB:this.menu.active&&this.menu.select(n);break;case o.ESCAPE:this.menu.element.is(":visible")&&(this.isMultiLine||this._value(this.term),this.close(n),n.preventDefault());break;default:i=!0,this._searchTimeout(n)}},keypress:function(s){if(e)return e=!1,(!this.isMultiLine||this.menu.element.is(":visible"))&&s.preventDefault(),void 0;if(!i){var n=t.ui.keyCode;switch(s.keyCode){case n.PAGE_UP:this._move("previousPage",s);break;case n.PAGE_DOWN:this._move("nextPage",s);break;case n.UP:this._keyEvent("previous",s);break;case n.DOWN:this._keyEvent("next",s)}}},input:function(t){return s?(s=!1,t.preventDefault(),void 0):(this._searchTimeout(t),void 0)},focus:function(){this.selectedItem=null,this.previous=this._value()},blur:function(t){return this.cancelBlur?(delete this.cancelBlur,void 0):(clearTimeout(this.searching),this.close(t),this._change(t),void 0)}}),this._initSource(),this.menu=t("<ul>").appendTo(this._appendTo()).menu({role:null}).hide().menu("instance"),this._addClass(this.menu.element,"ui-autocomplete","ui-front"),this._on(this.menu.element,{mousedown:function(e){e.preventDefault(),this.cancelBlur=!0,this._delay(function(){delete this.cancelBlur,this.element[0]!==t.ui.safeActiveElement(this.document[0])&&this.element.trigger("focus")})},menufocus:function(e,i){var s,n;return this.isNewMenu&&(this.isNewMenu=!1,e.originalEvent&&/^mouse/.test(e.originalEvent.type))?(this.menu.blur(),this.document.one("mousemove",function(){t(e.target).trigger(e.originalEvent)}),void 0):(n=i.item.data("ui-autocomplete-item"),!1!==this._trigger("focus",e,{item:n})&&e.originalEvent&&/^key/.test(e.originalEvent.type)&&this._value(n.value),s=i.item.attr("aria-label")||n.value,s&&t.trim(s).length&&(this.liveRegion.children().hide(),t("<div>").text(s).appendTo(this.liveRegion)),void 0)},menuselect:function(e,i){var s=i.item.data("ui-autocomplete-item"),n=this.previous;this.element[0]!==t.ui.safeActiveElement(this.document[0])&&(this.element.trigger("focus"),this.previous=n,this._delay(function(){this.previous=n,this.selectedItem=s})),!1!==this._trigger("select",e,{item:s})&&this._value(s.value),this.term=this._value(),this.close(e),this.selectedItem=s}}),this.liveRegion=t("<div>",{role:"status","aria-live":"assertive","aria-relevant":"additions"}).appendTo(this.document[0].body),this._addClass(this.liveRegion,null,"ui-helper-hidden-accessible"),this._on(this.window,{beforeunload:function(){this.element.removeAttr("autocomplete")}})},_destroy:function(){clearTimeout(this.searching),this.element.removeAttr("autocomplete"),this.menu.element.remove(),this.liveRegion.remove()},_setOption:function(t,e){this._super(t,e),"source"===t&&this._initSource(),"appendTo"===t&&this.menu.element.appendTo(this._appendTo()),"disabled"===t&&e&&this.xhr&&this.xhr.abort()},_isEventTargetInWidget:function(e){var i=this.menu.element[0];return e.target===this.element[0]||e.target===i||t.contains(i,e.target)},_closeOnClickOutside:function(t){this._isEventTargetInWidget(t)||this.close()},_appendTo:function(){var e=this.options.appendTo;return e&&(e=e.jquery||e.nodeType?t(e):this.document.find(e).eq(0)),e&&e[0]||(e=this.element.closest(".ui-front, dialog")),e.length||(e=this.document[0].body),e},_initSource:function(){var e,i,s=this;t.isArray(this.options.source)?(e=this.options.source,this.source=function(i,s){s(t.ui.autocomplete.filter(e,i.term))}):"string"==typeof this.options.source?(i=this.options.source,this.source=function(e,n){s.xhr&&s.xhr.abort(),s.xhr=t.ajax({url:i,data:e,dataType:"json",success:function(t){n(t)},error:function(){n([])}})}):this.source=this.options.source},_searchTimeout:function(t){clearTimeout(this.searching),this.searching=this._delay(function(){var e=this.term===this._value(),i=this.menu.element.is(":visible"),s=t.altKey||t.ctrlKey||t.metaKey||t.shiftKey;(!e||e&&!i&&!s)&&(this.selectedItem=null,this.search(null,t))},this.options.delay)},search:function(t,e){return t=null!=t?t:this._value(),this.term=this._value(),t.length<this.options.minLength?this.close(e):this._trigger("search",e)!==!1?this._search(t):void 0},_search:function(t){this.pending++,this._addClass("ui-autocomplete-loading"),this.cancelSearch=!1,this.source({term:t},this._response())},_response:function(){var e=++this.requestIndex;return t.proxy(function(t){e===this.requestIndex&&this.__response(t),this.pending--,this.pending||this._removeClass("ui-autocomplete-loading")},this)},__response:function(t){t&&(t=this._normalize(t)),this._trigger("response",null,{content:t}),!this.options.disabled&&t&&t.length&&!this.cancelSearch?(this._suggest(t),this._trigger("open")):this._close()},close:function(t){this.cancelSearch=!0,this._close(t)},_close:function(t){this._off(this.document,"mousedown"),this.menu.element.is(":visible")&&(this.menu.element.hide(),this.menu.blur(),this.isNewMenu=!0,this._trigger("close",t))},_change:function(t){this.previous!==this._value()&&this._trigger("change",t,{item:this.selectedItem})},_normalize:function(e){return e.length&&e[0].label&&e[0].value?e:t.map(e,function(e){return"string"==typeof e?{label:e,value:e}:t.extend({},e,{label:e.label||e.value,value:e.value||e.label})})},_suggest:function(e){var i=this.menu.element.empty();this._renderMenu(i,e),this.isNewMenu=!0,this.menu.refresh(),i.show(),this._resizeMenu(),i.position(t.extend({of:this.element},this.options.position)),this.options.autoFocus&&this.menu.next(),this._on(this.document,{mousedown:"_closeOnClickOutside"})},_resizeMenu:function(){var t=this.menu.element;t.outerWidth(Math.max(t.width("").outerWidth()+1,this.element.outerWidth()))},_renderMenu:function(e,i){var s=this;t.each(i,function(t,i){s._renderItemData(e,i)})},_renderItemData:function(t,e){return this._renderItem(t,e).data("ui-autocomplete-item",e)},_renderItem:function(e,i){return t("<li>").append(t("<div>").text(i.label)).appendTo(e)},_move:function(t,e){return this.menu.element.is(":visible")?this.menu.isFirstItem()&&/^previous/.test(t)||this.menu.isLastItem()&&/^next/.test(t)?(this.isMultiLine||this._value(this.term),this.menu.blur(),void 0):(this.menu[t](e),void 0):(this.search(null,e),void 0)},widget:function(){return this.menu.element},_value:function(){return this.valueMethod.apply(this.element,arguments)},_keyEvent:function(t,e){(!this.isMultiLine||this.menu.element.is(":visible"))&&(this._move(t,e),e.preventDefault())},_isContentEditable:function(t){if(!t.length)return!1;var e=t.prop("contentEditable");return"inherit"===e?this._isContentEditable(t.parent()):"true"===e}}),t.extend(t.ui.autocomplete,{escapeRegex:function(t){return t.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g,"\\$&")},filter:function(e,i){var s=RegExp(t.ui.autocomplete.escapeRegex(i),"i");return t.grep(e,function(t){return s.test(t.label||t.value||t)})}}),t.widget("ui.autocomplete",t.ui.autocomplete,{options:{messages:{noResults:"No search results.",results:function(t){return t+(t>1?" results are":" result is")+" available, use up and down arrow keys to navigate."}}},__response:function(e){var i;this._superApply(arguments),this.options.disabled||this.cancelSearch||(i=e&&e.length?this.options.messages.results(e.length):this.options.messages.noResults,this.liveRegion.children().hide(),t("<div>").text(i).appendTo(this.liveRegion))}}),t.ui.autocomplete;var d=/ui-corner-([a-z]){2,6}/g;t.widget("ui.controlgroup",{version:"1.12.1",defaultElement:"<div>",options:{direction:"horizontal",disabled:null,onlyVisible:!0,items:{button:"input[type=button], input[type=submit], input[type=reset], button, a",controlgroupLabel:".ui-controlgroup-label",checkboxradio:"input[type='checkbox'], input[type='radio']",selectmenu:"select",spinner:".ui-spinner-input"}},_create:function(){this._enhance()},_enhance:function(){this.element.attr("role","toolbar"),this.refresh()},_destroy:function(){this._callChildMethod("destroy"),this.childWidgets.removeData("ui-controlgroup-data"),this.element.removeAttr("role"),this.options.items.controlgroupLabel&&this.element.find(this.options.items.controlgroupLabel).find(".ui-controlgroup-label-contents").contents().unwrap()},_initWidgets:function(){var e=this,i=[];t.each(this.options.items,function(s,n){var o,a={};return n?"controlgroupLabel"===s?(o=e.element.find(n),o.each(function(){var e=t(this);e.children(".ui-controlgroup-label-contents").length||e.contents().wrapAll("<span class='ui-controlgroup-label-contents'></span>")}),e._addClass(o,null,"ui-widget ui-widget-content ui-state-default"),i=i.concat(o.get()),void 0):(t.fn[s]&&(a=e["_"+s+"Options"]?e["_"+s+"Options"]("middle"):{classes:{}},e.element.find(n).each(function(){var n=t(this),o=n[s]("instance"),r=t.widget.extend({},a);if("button"!==s||!n.parent(".ui-spinner").length){o||(o=n[s]()[s]("instance")),o&&(r.classes=e._resolveClassesValues(r.classes,o)),n[s](r);var h=n[s]("widget");t.data(h[0],"ui-controlgroup-data",o?o:n[s]("instance")),i.push(h[0])}})),void 0):void 0}),this.childWidgets=t(t.unique(i)),this._addClass(this.childWidgets,"ui-controlgroup-item")},_callChildMethod:function(e){this.childWidgets.each(function(){var i=t(this),s=i.data("ui-controlgroup-data");s&&s[e]&&s[e]()})},_updateCornerClass:function(t,e){var i="ui-corner-top ui-corner-bottom ui-corner-left ui-corner-right ui-corner-all",s=this._buildSimpleOptions(e,"label").classes.label;this._removeClass(t,null,i),this._addClass(t,null,s)},_buildSimpleOptions:function(t,e){var i="vertical"===this.options.direction,s={classes:{}};return s.classes[e]={middle:"",first:"ui-corner-"+(i?"top":"left"),last:"ui-corner-"+(i?"bottom":"right"),only:"ui-corner-all"}[t],s},_spinnerOptions:function(t){var e=this._buildSimpleOptions(t,"ui-spinner");return e.classes["ui-spinner-up"]="",e.classes["ui-spinner-down"]="",e},_buttonOptions:function(t){return this._buildSimpleOptions(t,"ui-button")},_checkboxradioOptions:function(t){return this._buildSimpleOptions(t,"ui-checkboxradio-label")},_selectmenuOptions:function(t){var e="vertical"===this.options.direction;return{width:e?"auto":!1,classes:{middle:{"ui-selectmenu-button-open":"","ui-selectmenu-button-closed":""},first:{"ui-selectmenu-button-open":"ui-corner-"+(e?"top":"tl"),"ui-selectmenu-button-closed":"ui-corner-"+(e?"top":"left")},last:{"ui-selectmenu-button-open":e?"":"ui-corner-tr","ui-selectmenu-button-closed":"ui-corner-"+(e?"bottom":"right")},only:{"ui-selectmenu-button-open":"ui-corner-top","ui-selectmenu-button-closed":"ui-corner-all"}}[t]}},_resolveClassesValues:function(e,i){var s={};return t.each(e,function(n){var o=i.options.classes[n]||"";o=t.trim(o.replace(d,"")),s[n]=(o+" "+e[n]).replace(/\s+/g," ")}),s},_setOption:function(t,e){return"direction"===t&&this._removeClass("ui-controlgroup-"+this.options.direction),this._super(t,e),"disabled"===t?(this._callChildMethod(e?"disable":"enable"),void 0):(this.refresh(),void 0)},refresh:function(){var e,i=this;this._addClass("ui-controlgroup ui-controlgroup-"+this.options.direction),"horizontal"===this.options.direction&&this._addClass(null,"ui-helper-clearfix"),this._initWidgets(),e=this.childWidgets,this.options.onlyVisible&&(e=e.filter(":visible")),e.length&&(t.each(["first","last"],function(t,s){var n=e[s]().data("ui-controlgroup-data");if(n&&i["_"+n.widgetName+"Options"]){var o=i["_"+n.widgetName+"Options"](1===e.length?"only":s);o.classes=i._resolveClassesValues(o.classes,n),n.element[n.widgetName](o)}else i._updateCornerClass(e[s](),s)}),this._callChildMethod("refresh"))}}),t.widget("ui.checkboxradio",[t.ui.formResetMixin,{version:"1.12.1",options:{disabled:null,label:null,icon:!0,classes:{"ui-checkboxradio-label":"ui-corner-all","ui-checkboxradio-icon":"ui-corner-all"}},_getCreateOptions:function(){var e,i,s=this,n=this._super()||{};return this._readType(),i=this.element.labels(),this.label=t(i[i.length-1]),this.label.length||t.error("No label found for checkboxradio widget"),this.originalLabel="",this.label.contents().not(this.element[0]).each(function(){s.originalLabel+=3===this.nodeType?t(this).text():this.outerHTML}),this.originalLabel&&(n.label=this.originalLabel),e=this.element[0].disabled,null!=e&&(n.disabled=e),n},_create:function(){var t=this.element[0].checked;this._bindFormResetHandler(),null==this.options.disabled&&(this.options.disabled=this.element[0].disabled),this._setOption("disabled",this.options.disabled),this._addClass("ui-checkboxradio","ui-helper-hidden-accessible"),this._addClass(this.label,"ui-checkboxradio-label","ui-button ui-widget"),"radio"===this.type&&this._addClass(this.label,"ui-checkboxradio-radio-label"),this.options.label&&this.options.label!==this.originalLabel?this._updateLabel():this.originalLabel&&(this.options.label=this.originalLabel),this._enhance(),t&&(this._addClass(this.label,"ui-checkboxradio-checked","ui-state-active"),this.icon&&this._addClass(this.icon,null,"ui-state-hover")),this._on({change:"_toggleClasses",focus:function(){this._addClass(this.label,null,"ui-state-focus ui-visual-focus")},blur:function(){this._removeClass(this.label,null,"ui-state-focus ui-visual-focus")}})},_readType:function(){var e=this.element[0].nodeName.toLowerCase();this.type=this.element[0].type,"input"===e&&/radio|checkbox/.test(this.type)||t.error("Can't create checkboxradio on element.nodeName="+e+" and element.type="+this.type)},_enhance:function(){this._updateIcon(this.element[0].checked)},widget:function(){return this.label},_getRadioGroup:function(){var e,i=this.element[0].name,s="input[name='"+t.ui.escapeSelector(i)+"']";return i?(e=this.form.length?t(this.form[0].elements).filter(s):t(s).filter(function(){return 0===t(this).form().length}),e.not(this.element)):t([])},_toggleClasses:function(){var e=this.element[0].checked;this._toggleClass(this.label,"ui-checkboxradio-checked","ui-state-active",e),this.options.icon&&"checkbox"===this.type&&this._toggleClass(this.icon,null,"ui-icon-check ui-state-checked",e)._toggleClass(this.icon,null,"ui-icon-blank",!e),"radio"===this.type&&this._getRadioGroup().each(function(){var e=t(this).checkboxradio("instance");e&&e._removeClass(e.label,"ui-checkboxradio-checked","ui-state-active")})},_destroy:function(){this._unbindFormResetHandler(),this.icon&&(this.icon.remove(),this.iconSpace.remove())},_setOption:function(t,e){return"label"!==t||e?(this._super(t,e),"disabled"===t?(this._toggleClass(this.label,null,"ui-state-disabled",e),this.element[0].disabled=e,void 0):(this.refresh(),void 0)):void 0},_updateIcon:function(e){var i="ui-icon ui-icon-background ";this.options.icon?(this.icon||(this.icon=t("<span>"),this.iconSpace=t("<span> </span>"),this._addClass(this.iconSpace,"ui-checkboxradio-icon-space")),"checkbox"===this.type?(i+=e?"ui-icon-check ui-state-checked":"ui-icon-blank",this._removeClass(this.icon,null,e?"ui-icon-blank":"ui-icon-check")):i+="ui-icon-blank",this._addClass(this.icon,"ui-checkboxradio-icon",i),e||this._removeClass(this.icon,null,"ui-icon-check ui-state-checked"),this.icon.prependTo(this.label).after(this.iconSpace)):void 0!==this.icon&&(this.icon.remove(),this.iconSpace.remove(),delete this.icon)
|
||
},_updateLabel:function(){var t=this.label.contents().not(this.element[0]);this.icon&&(t=t.not(this.icon[0])),this.iconSpace&&(t=t.not(this.iconSpace[0])),t.remove(),this.label.append(this.options.label)},refresh:function(){var t=this.element[0].checked,e=this.element[0].disabled;this._updateIcon(t),this._toggleClass(this.label,"ui-checkboxradio-checked","ui-state-active",t),null!==this.options.label&&this._updateLabel(),e!==this.options.disabled&&this._setOptions({disabled:e})}}]),t.ui.checkboxradio,t.widget("ui.button",{version:"1.12.1",defaultElement:"<button>",options:{classes:{"ui-button":"ui-corner-all"},disabled:null,icon:null,iconPosition:"beginning",label:null,showLabel:!0},_getCreateOptions:function(){var t,e=this._super()||{};return this.isInput=this.element.is("input"),t=this.element[0].disabled,null!=t&&(e.disabled=t),this.originalLabel=this.isInput?this.element.val():this.element.html(),this.originalLabel&&(e.label=this.originalLabel),e},_create:function(){!this.option.showLabel&!this.options.icon&&(this.options.showLabel=!0),null==this.options.disabled&&(this.options.disabled=this.element[0].disabled||!1),this.hasTitle=!!this.element.attr("title"),this.options.label&&this.options.label!==this.originalLabel&&(this.isInput?this.element.val(this.options.label):this.element.html(this.options.label)),this._addClass("ui-button","ui-widget"),this._setOption("disabled",this.options.disabled),this._enhance(),this.element.is("a")&&this._on({keyup:function(e){e.keyCode===t.ui.keyCode.SPACE&&(e.preventDefault(),this.element[0].click?this.element[0].click():this.element.trigger("click"))}})},_enhance:function(){this.element.is("button")||this.element.attr("role","button"),this.options.icon&&(this._updateIcon("icon",this.options.icon),this._updateTooltip())},_updateTooltip:function(){this.title=this.element.attr("title"),this.options.showLabel||this.title||this.element.attr("title",this.options.label)},_updateIcon:function(e,i){var s="iconPosition"!==e,n=s?this.options.iconPosition:i,o="top"===n||"bottom"===n;this.icon?s&&this._removeClass(this.icon,null,this.options.icon):(this.icon=t("<span>"),this._addClass(this.icon,"ui-button-icon","ui-icon"),this.options.showLabel||this._addClass("ui-button-icon-only")),s&&this._addClass(this.icon,null,i),this._attachIcon(n),o?(this._addClass(this.icon,null,"ui-widget-icon-block"),this.iconSpace&&this.iconSpace.remove()):(this.iconSpace||(this.iconSpace=t("<span> </span>"),this._addClass(this.iconSpace,"ui-button-icon-space")),this._removeClass(this.icon,null,"ui-wiget-icon-block"),this._attachIconSpace(n))},_destroy:function(){this.element.removeAttr("role"),this.icon&&this.icon.remove(),this.iconSpace&&this.iconSpace.remove(),this.hasTitle||this.element.removeAttr("title")},_attachIconSpace:function(t){this.icon[/^(?:end|bottom)/.test(t)?"before":"after"](this.iconSpace)},_attachIcon:function(t){this.element[/^(?:end|bottom)/.test(t)?"append":"prepend"](this.icon)},_setOptions:function(t){var e=void 0===t.showLabel?this.options.showLabel:t.showLabel,i=void 0===t.icon?this.options.icon:t.icon;e||i||(t.showLabel=!0),this._super(t)},_setOption:function(t,e){"icon"===t&&(e?this._updateIcon(t,e):this.icon&&(this.icon.remove(),this.iconSpace&&this.iconSpace.remove())),"iconPosition"===t&&this._updateIcon(t,e),"showLabel"===t&&(this._toggleClass("ui-button-icon-only",null,!e),this._updateTooltip()),"label"===t&&(this.isInput?this.element.val(e):(this.element.html(e),this.icon&&(this._attachIcon(this.options.iconPosition),this._attachIconSpace(this.options.iconPosition)))),this._super(t,e),"disabled"===t&&(this._toggleClass(null,"ui-state-disabled",e),this.element[0].disabled=e,e&&this.element.blur())},refresh:function(){var t=this.element.is("input, button")?this.element[0].disabled:this.element.hasClass("ui-button-disabled");t!==this.options.disabled&&this._setOptions({disabled:t}),this._updateTooltip()}}),t.uiBackCompat!==!1&&(t.widget("ui.button",t.ui.button,{options:{text:!0,icons:{primary:null,secondary:null}},_create:function(){this.options.showLabel&&!this.options.text&&(this.options.showLabel=this.options.text),!this.options.showLabel&&this.options.text&&(this.options.text=this.options.showLabel),this.options.icon||!this.options.icons.primary&&!this.options.icons.secondary?this.options.icon&&(this.options.icons.primary=this.options.icon):this.options.icons.primary?this.options.icon=this.options.icons.primary:(this.options.icon=this.options.icons.secondary,this.options.iconPosition="end"),this._super()},_setOption:function(t,e){return"text"===t?(this._super("showLabel",e),void 0):("showLabel"===t&&(this.options.text=e),"icon"===t&&(this.options.icons.primary=e),"icons"===t&&(e.primary?(this._super("icon",e.primary),this._super("iconPosition","beginning")):e.secondary&&(this._super("icon",e.secondary),this._super("iconPosition","end"))),this._superApply(arguments),void 0)}}),t.fn.button=function(e){return function(){return!this.length||this.length&&"INPUT"!==this[0].tagName||this.length&&"INPUT"===this[0].tagName&&"checkbox"!==this.attr("type")&&"radio"!==this.attr("type")?e.apply(this,arguments):(t.ui.checkboxradio||t.error("Checkboxradio widget missing"),0===arguments.length?this.checkboxradio({icon:!1}):this.checkboxradio.apply(this,arguments))}}(t.fn.button),t.fn.buttonset=function(){return t.ui.controlgroup||t.error("Controlgroup widget missing"),"option"===arguments[0]&&"items"===arguments[1]&&arguments[2]?this.controlgroup.apply(this,[arguments[0],"items.button",arguments[2]]):"option"===arguments[0]&&"items"===arguments[1]?this.controlgroup.apply(this,[arguments[0],"items.button"]):("object"==typeof arguments[0]&&arguments[0].items&&(arguments[0].items={button:arguments[0].items}),this.controlgroup.apply(this,arguments))}),t.ui.button,t.extend(t.ui,{datepicker:{version:"1.12.1"}});var p;t.extend(s.prototype,{markerClassName:"hasDatepicker",maxRows:4,_widgetDatepicker:function(){return this.dpDiv},setDefaults:function(t){return a(this._defaults,t||{}),this},_attachDatepicker:function(e,i){var s,n,o;s=e.nodeName.toLowerCase(),n="div"===s||"span"===s,e.id||(this.uuid+=1,e.id="dp"+this.uuid),o=this._newInst(t(e),n),o.settings=t.extend({},i||{}),"input"===s?this._connectDatepicker(e,o):n&&this._inlineDatepicker(e,o)},_newInst:function(e,i){var s=e[0].id.replace(/([^A-Za-z0-9_\-])/g,"\\\\$1");return{id:s,input:e,selectedDay:0,selectedMonth:0,selectedYear:0,drawMonth:0,drawYear:0,inline:i,dpDiv:i?n(t("<div class='"+this._inlineClass+" ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all'></div>")):this.dpDiv}},_connectDatepicker:function(e,i){var s=t(e);i.append=t([]),i.trigger=t([]),s.hasClass(this.markerClassName)||(this._attachments(s,i),s.addClass(this.markerClassName).on("keydown",this._doKeyDown).on("keypress",this._doKeyPress).on("keyup",this._doKeyUp),this._autoSize(i),t.data(e,"datepicker",i),i.settings.disabled&&this._disableDatepicker(e))},_attachments:function(e,i){var s,n,o,a=this._get(i,"appendText"),r=this._get(i,"isRTL");i.append&&i.append.remove(),a&&(i.append=t("<span class='"+this._appendClass+"'>"+a+"</span>"),e[r?"before":"after"](i.append)),e.off("focus",this._showDatepicker),i.trigger&&i.trigger.remove(),s=this._get(i,"showOn"),("focus"===s||"both"===s)&&e.on("focus",this._showDatepicker),("button"===s||"both"===s)&&(n=this._get(i,"buttonText"),o=this._get(i,"buttonImage"),i.trigger=t(this._get(i,"buttonImageOnly")?t("<img/>").addClass(this._triggerClass).attr({src:o,alt:n,title:n}):t("<button type='button'></button>").addClass(this._triggerClass).html(o?t("<img/>").attr({src:o,alt:n,title:n}):n)),e[r?"before":"after"](i.trigger),i.trigger.on("click",function(){return t.datepicker._datepickerShowing&&t.datepicker._lastInput===e[0]?t.datepicker._hideDatepicker():t.datepicker._datepickerShowing&&t.datepicker._lastInput!==e[0]?(t.datepicker._hideDatepicker(),t.datepicker._showDatepicker(e[0])):t.datepicker._showDatepicker(e[0]),!1}))},_autoSize:function(t){if(this._get(t,"autoSize")&&!t.inline){var e,i,s,n,o=new Date(2009,11,20),a=this._get(t,"dateFormat");a.match(/[DM]/)&&(e=function(t){for(i=0,s=0,n=0;t.length>n;n++)t[n].length>i&&(i=t[n].length,s=n);return s},o.setMonth(e(this._get(t,a.match(/MM/)?"monthNames":"monthNamesShort"))),o.setDate(e(this._get(t,a.match(/DD/)?"dayNames":"dayNamesShort"))+20-o.getDay())),t.input.attr("size",this._formatDate(t,o).length)}},_inlineDatepicker:function(e,i){var s=t(e);s.hasClass(this.markerClassName)||(s.addClass(this.markerClassName).append(i.dpDiv),t.data(e,"datepicker",i),this._setDate(i,this._getDefaultDate(i),!0),this._updateDatepicker(i),this._updateAlternate(i),i.settings.disabled&&this._disableDatepicker(e),i.dpDiv.css("display","block"))},_dialogDatepicker:function(e,i,s,n,o){var r,h,l,c,u,d=this._dialogInst;return d||(this.uuid+=1,r="dp"+this.uuid,this._dialogInput=t("<input type='text' id='"+r+"' style='position: absolute; top: -100px; width: 0px;'/>"),this._dialogInput.on("keydown",this._doKeyDown),t("body").append(this._dialogInput),d=this._dialogInst=this._newInst(this._dialogInput,!1),d.settings={},t.data(this._dialogInput[0],"datepicker",d)),a(d.settings,n||{}),i=i&&i.constructor===Date?this._formatDate(d,i):i,this._dialogInput.val(i),this._pos=o?o.length?o:[o.pageX,o.pageY]:null,this._pos||(h=document.documentElement.clientWidth,l=document.documentElement.clientHeight,c=document.documentElement.scrollLeft||document.body.scrollLeft,u=document.documentElement.scrollTop||document.body.scrollTop,this._pos=[h/2-100+c,l/2-150+u]),this._dialogInput.css("left",this._pos[0]+20+"px").css("top",this._pos[1]+"px"),d.settings.onSelect=s,this._inDialog=!0,this.dpDiv.addClass(this._dialogClass),this._showDatepicker(this._dialogInput[0]),t.blockUI&&t.blockUI(this.dpDiv),t.data(this._dialogInput[0],"datepicker",d),this},_destroyDatepicker:function(e){var i,s=t(e),n=t.data(e,"datepicker");s.hasClass(this.markerClassName)&&(i=e.nodeName.toLowerCase(),t.removeData(e,"datepicker"),"input"===i?(n.append.remove(),n.trigger.remove(),s.removeClass(this.markerClassName).off("focus",this._showDatepicker).off("keydown",this._doKeyDown).off("keypress",this._doKeyPress).off("keyup",this._doKeyUp)):("div"===i||"span"===i)&&s.removeClass(this.markerClassName).empty(),p===n&&(p=null))},_enableDatepicker:function(e){var i,s,n=t(e),o=t.data(e,"datepicker");n.hasClass(this.markerClassName)&&(i=e.nodeName.toLowerCase(),"input"===i?(e.disabled=!1,o.trigger.filter("button").each(function(){this.disabled=!1}).end().filter("img").css({opacity:"1.0",cursor:""})):("div"===i||"span"===i)&&(s=n.children("."+this._inlineClass),s.children().removeClass("ui-state-disabled"),s.find("select.ui-datepicker-month, select.ui-datepicker-year").prop("disabled",!1)),this._disabledInputs=t.map(this._disabledInputs,function(t){return t===e?null:t}))},_disableDatepicker:function(e){var i,s,n=t(e),o=t.data(e,"datepicker");n.hasClass(this.markerClassName)&&(i=e.nodeName.toLowerCase(),"input"===i?(e.disabled=!0,o.trigger.filter("button").each(function(){this.disabled=!0}).end().filter("img").css({opacity:"0.5",cursor:"default"})):("div"===i||"span"===i)&&(s=n.children("."+this._inlineClass),s.children().addClass("ui-state-disabled"),s.find("select.ui-datepicker-month, select.ui-datepicker-year").prop("disabled",!0)),this._disabledInputs=t.map(this._disabledInputs,function(t){return t===e?null:t}),this._disabledInputs[this._disabledInputs.length]=e)},_isDisabledDatepicker:function(t){if(!t)return!1;for(var e=0;this._disabledInputs.length>e;e++)if(this._disabledInputs[e]===t)return!0;return!1},_getInst:function(e){try{return t.data(e,"datepicker")}catch(i){throw"Missing instance data for this datepicker"}},_optionDatepicker:function(e,i,s){var n,o,r,h,l=this._getInst(e);return 2===arguments.length&&"string"==typeof i?"defaults"===i?t.extend({},t.datepicker._defaults):l?"all"===i?t.extend({},l.settings):this._get(l,i):null:(n=i||{},"string"==typeof i&&(n={},n[i]=s),l&&(this._curInst===l&&this._hideDatepicker(),o=this._getDateDatepicker(e,!0),r=this._getMinMaxDate(l,"min"),h=this._getMinMaxDate(l,"max"),a(l.settings,n),null!==r&&void 0!==n.dateFormat&&void 0===n.minDate&&(l.settings.minDate=this._formatDate(l,r)),null!==h&&void 0!==n.dateFormat&&void 0===n.maxDate&&(l.settings.maxDate=this._formatDate(l,h)),"disabled"in n&&(n.disabled?this._disableDatepicker(e):this._enableDatepicker(e)),this._attachments(t(e),l),this._autoSize(l),this._setDate(l,o),this._updateAlternate(l),this._updateDatepicker(l)),void 0)},_changeDatepicker:function(t,e,i){this._optionDatepicker(t,e,i)},_refreshDatepicker:function(t){var e=this._getInst(t);e&&this._updateDatepicker(e)},_setDateDatepicker:function(t,e){var i=this._getInst(t);i&&(this._setDate(i,e),this._updateDatepicker(i),this._updateAlternate(i))},_getDateDatepicker:function(t,e){var i=this._getInst(t);return i&&!i.inline&&this._setDateFromField(i,e),i?this._getDate(i):null},_doKeyDown:function(e){var i,s,n,o=t.datepicker._getInst(e.target),a=!0,r=o.dpDiv.is(".ui-datepicker-rtl");if(o._keyEvent=!0,t.datepicker._datepickerShowing)switch(e.keyCode){case 9:t.datepicker._hideDatepicker(),a=!1;break;case 13:return n=t("td."+t.datepicker._dayOverClass+":not(."+t.datepicker._currentClass+")",o.dpDiv),n[0]&&t.datepicker._selectDay(e.target,o.selectedMonth,o.selectedYear,n[0]),i=t.datepicker._get(o,"onSelect"),i?(s=t.datepicker._formatDate(o),i.apply(o.input?o.input[0]:null,[s,o])):t.datepicker._hideDatepicker(),!1;case 27:t.datepicker._hideDatepicker();break;case 33:t.datepicker._adjustDate(e.target,e.ctrlKey?-t.datepicker._get(o,"stepBigMonths"):-t.datepicker._get(o,"stepMonths"),"M");break;case 34:t.datepicker._adjustDate(e.target,e.ctrlKey?+t.datepicker._get(o,"stepBigMonths"):+t.datepicker._get(o,"stepMonths"),"M");break;case 35:(e.ctrlKey||e.metaKey)&&t.datepicker._clearDate(e.target),a=e.ctrlKey||e.metaKey;break;case 36:(e.ctrlKey||e.metaKey)&&t.datepicker._gotoToday(e.target),a=e.ctrlKey||e.metaKey;break;case 37:(e.ctrlKey||e.metaKey)&&t.datepicker._adjustDate(e.target,r?1:-1,"D"),a=e.ctrlKey||e.metaKey,e.originalEvent.altKey&&t.datepicker._adjustDate(e.target,e.ctrlKey?-t.datepicker._get(o,"stepBigMonths"):-t.datepicker._get(o,"stepMonths"),"M");break;case 38:(e.ctrlKey||e.metaKey)&&t.datepicker._adjustDate(e.target,-7,"D"),a=e.ctrlKey||e.metaKey;break;case 39:(e.ctrlKey||e.metaKey)&&t.datepicker._adjustDate(e.target,r?-1:1,"D"),a=e.ctrlKey||e.metaKey,e.originalEvent.altKey&&t.datepicker._adjustDate(e.target,e.ctrlKey?+t.datepicker._get(o,"stepBigMonths"):+t.datepicker._get(o,"stepMonths"),"M");break;case 40:(e.ctrlKey||e.metaKey)&&t.datepicker._adjustDate(e.target,7,"D"),a=e.ctrlKey||e.metaKey;break;default:a=!1}else 36===e.keyCode&&e.ctrlKey?t.datepicker._showDatepicker(this):a=!1;a&&(e.preventDefault(),e.stopPropagation())},_doKeyPress:function(e){var i,s,n=t.datepicker._getInst(e.target);return t.datepicker._get(n,"constrainInput")?(i=t.datepicker._possibleChars(t.datepicker._get(n,"dateFormat")),s=String.fromCharCode(null==e.charCode?e.keyCode:e.charCode),e.ctrlKey||e.metaKey||" ">s||!i||i.indexOf(s)>-1):void 0},_doKeyUp:function(e){var i,s=t.datepicker._getInst(e.target);if(s.input.val()!==s.lastVal)try{i=t.datepicker.parseDate(t.datepicker._get(s,"dateFormat"),s.input?s.input.val():null,t.datepicker._getFormatConfig(s)),i&&(t.datepicker._setDateFromField(s),t.datepicker._updateAlternate(s),t.datepicker._updateDatepicker(s))}catch(n){}return!0},_showDatepicker:function(e){if(e=e.target||e,"input"!==e.nodeName.toLowerCase()&&(e=t("input",e.parentNode)[0]),!t.datepicker._isDisabledDatepicker(e)&&t.datepicker._lastInput!==e){var s,n,o,r,h,l,c;s=t.datepicker._getInst(e),t.datepicker._curInst&&t.datepicker._curInst!==s&&(t.datepicker._curInst.dpDiv.stop(!0,!0),s&&t.datepicker._datepickerShowing&&t.datepicker._hideDatepicker(t.datepicker._curInst.input[0])),n=t.datepicker._get(s,"beforeShow"),o=n?n.apply(e,[e,s]):{},o!==!1&&(a(s.settings,o),s.lastVal=null,t.datepicker._lastInput=e,t.datepicker._setDateFromField(s),t.datepicker._inDialog&&(e.value=""),t.datepicker._pos||(t.datepicker._pos=t.datepicker._findPos(e),t.datepicker._pos[1]+=e.offsetHeight),r=!1,t(e).parents().each(function(){return r|="fixed"===t(this).css("position"),!r}),h={left:t.datepicker._pos[0],top:t.datepicker._pos[1]},t.datepicker._pos=null,s.dpDiv.empty(),s.dpDiv.css({position:"absolute",display:"block",top:"-1000px"}),t.datepicker._updateDatepicker(s),h=t.datepicker._checkOffset(s,h,r),s.dpDiv.css({position:t.datepicker._inDialog&&t.blockUI?"static":r?"fixed":"absolute",display:"none",left:h.left+"px",top:h.top+"px"}),s.inline||(l=t.datepicker._get(s,"showAnim"),c=t.datepicker._get(s,"duration"),s.dpDiv.css("z-index",i(t(e))+1),t.datepicker._datepickerShowing=!0,t.effects&&t.effects.effect[l]?s.dpDiv.show(l,t.datepicker._get(s,"showOptions"),c):s.dpDiv[l||"show"](l?c:null),t.datepicker._shouldFocusInput(s)&&s.input.trigger("focus"),t.datepicker._curInst=s))}},_updateDatepicker:function(e){this.maxRows=4,p=e,e.dpDiv.empty().append(this._generateHTML(e)),this._attachHandlers(e);var i,s=this._getNumberOfMonths(e),n=s[1],a=17,r=e.dpDiv.find("."+this._dayOverClass+" a");r.length>0&&o.apply(r.get(0)),e.dpDiv.removeClass("ui-datepicker-multi-2 ui-datepicker-multi-3 ui-datepicker-multi-4").width(""),n>1&&e.dpDiv.addClass("ui-datepicker-multi-"+n).css("width",a*n+"em"),e.dpDiv[(1!==s[0]||1!==s[1]?"add":"remove")+"Class"]("ui-datepicker-multi"),e.dpDiv[(this._get(e,"isRTL")?"add":"remove")+"Class"]("ui-datepicker-rtl"),e===t.datepicker._curInst&&t.datepicker._datepickerShowing&&t.datepicker._shouldFocusInput(e)&&e.input.trigger("focus"),e.yearshtml&&(i=e.yearshtml,setTimeout(function(){i===e.yearshtml&&e.yearshtml&&e.dpDiv.find("select.ui-datepicker-year:first").replaceWith(e.yearshtml),i=e.yearshtml=null},0))},_shouldFocusInput:function(t){return t.input&&t.input.is(":visible")&&!t.input.is(":disabled")&&!t.input.is(":focus")},_checkOffset:function(e,i,s){var n=e.dpDiv.outerWidth(),o=e.dpDiv.outerHeight(),a=e.input?e.input.outerWidth():0,r=e.input?e.input.outerHeight():0,h=document.documentElement.clientWidth+(s?0:t(document).scrollLeft()),l=document.documentElement.clientHeight+(s?0:t(document).scrollTop());return i.left-=this._get(e,"isRTL")?n-a:0,i.left-=s&&i.left===e.input.offset().left?t(document).scrollLeft():0,i.top-=s&&i.top===e.input.offset().top+r?t(document).scrollTop():0,i.left-=Math.min(i.left,i.left+n>h&&h>n?Math.abs(i.left+n-h):0),i.top-=Math.min(i.top,i.top+o>l&&l>o?Math.abs(o+r):0),i},_findPos:function(e){for(var i,s=this._getInst(e),n=this._get(s,"isRTL");e&&("hidden"===e.type||1!==e.nodeType||t.expr.filters.hidden(e));)e=e[n?"previousSibling":"nextSibling"];return i=t(e).offset(),[i.left,i.top]},_hideDatepicker:function(e){var i,s,n,o,a=this._curInst;!a||e&&a!==t.data(e,"datepicker")||this._datepickerShowing&&(i=this._get(a,"showAnim"),s=this._get(a,"duration"),n=function(){t.datepicker._tidyDialog(a)},t.effects&&(t.effects.effect[i]||t.effects[i])?a.dpDiv.hide(i,t.datepicker._get(a,"showOptions"),s,n):a.dpDiv["slideDown"===i?"slideUp":"fadeIn"===i?"fadeOut":"hide"](i?s:null,n),i||n(),this._datepickerShowing=!1,o=this._get(a,"onClose"),o&&o.apply(a.input?a.input[0]:null,[a.input?a.input.val():"",a]),this._lastInput=null,this._inDialog&&(this._dialogInput.css({position:"absolute",left:"0",top:"-100px"}),t.blockUI&&(t.unblockUI(),t("body").append(this.dpDiv))),this._inDialog=!1)},_tidyDialog:function(t){t.dpDiv.removeClass(this._dialogClass).off(".ui-datepicker-calendar")},_checkExternalClick:function(e){if(t.datepicker._curInst){var i=t(e.target),s=t.datepicker._getInst(i[0]);(i[0].id!==t.datepicker._mainDivId&&0===i.parents("#"+t.datepicker._mainDivId).length&&!i.hasClass(t.datepicker.markerClassName)&&!i.closest("."+t.datepicker._triggerClass).length&&t.datepicker._datepickerShowing&&(!t.datepicker._inDialog||!t.blockUI)||i.hasClass(t.datepicker.markerClassName)&&t.datepicker._curInst!==s)&&t.datepicker._hideDatepicker()}},_adjustDate:function(e,i,s){var n=t(e),o=this._getInst(n[0]);this._isDisabledDatepicker(n[0])||(this._adjustInstDate(o,i+("M"===s?this._get(o,"showCurrentAtPos"):0),s),this._updateDatepicker(o))},_gotoToday:function(e){var i,s=t(e),n=this._getInst(s[0]);this._get(n,"gotoCurrent")&&n.currentDay?(n.selectedDay=n.currentDay,n.drawMonth=n.selectedMonth=n.currentMonth,n.drawYear=n.selectedYear=n.currentYear):(i=new Date,n.selectedDay=i.getDate(),n.drawMonth=n.selectedMonth=i.getMonth(),n.drawYear=n.selectedYear=i.getFullYear()),this._notifyChange(n),this._adjustDate(s)},_selectMonthYear:function(e,i,s){var n=t(e),o=this._getInst(n[0]);o["selected"+("M"===s?"Month":"Year")]=o["draw"+("M"===s?"Month":"Year")]=parseInt(i.options[i.selectedIndex].value,10),this._notifyChange(o),this._adjustDate(n)},_selectDay:function(e,i,s,n){var o,a=t(e);t(n).hasClass(this._unselectableClass)||this._isDisabledDatepicker(a[0])||(o=this._getInst(a[0]),o.selectedDay=o.currentDay=t("a",n).html(),o.selectedMonth=o.currentMonth=i,o.selectedYear=o.currentYear=s,this._selectDate(e,this._formatDate(o,o.currentDay,o.currentMonth,o.currentYear)))},_clearDate:function(e){var i=t(e);this._selectDate(i,"")},_selectDate:function(e,i){var s,n=t(e),o=this._getInst(n[0]);i=null!=i?i:this._formatDate(o),o.input&&o.input.val(i),this._updateAlternate(o),s=this._get(o,"onSelect"),s?s.apply(o.input?o.input[0]:null,[i,o]):o.input&&o.input.trigger("change"),o.inline?this._updateDatepicker(o):(this._hideDatepicker(),this._lastInput=o.input[0],"object"!=typeof o.input[0]&&o.input.trigger("focus"),this._lastInput=null)},_updateAlternate:function(e){var i,s,n,o=this._get(e,"altField");o&&(i=this._get(e,"altFormat")||this._get(e,"dateFormat"),s=this._getDate(e),n=this.formatDate(i,s,this._getFormatConfig(e)),t(o).val(n))},noWeekends:function(t){var e=t.getDay();return[e>0&&6>e,""]},iso8601Week:function(t){var e,i=new Date(t.getTime());return i.setDate(i.getDate()+4-(i.getDay()||7)),e=i.getTime(),i.setMonth(0),i.setDate(1),Math.floor(Math.round((e-i)/864e5)/7)+1},parseDate:function(e,i,s){if(null==e||null==i)throw"Invalid arguments";if(i="object"==typeof i?""+i:i+"",""===i)return null;var n,o,a,r,h=0,l=(s?s.shortYearCutoff:null)||this._defaults.shortYearCutoff,c="string"!=typeof l?l:(new Date).getFullYear()%100+parseInt(l,10),u=(s?s.dayNamesShort:null)||this._defaults.dayNamesShort,d=(s?s.dayNames:null)||this._defaults.dayNames,p=(s?s.monthNamesShort:null)||this._defaults.monthNamesShort,f=(s?s.monthNames:null)||this._defaults.monthNames,g=-1,m=-1,_=-1,v=-1,b=!1,y=function(t){var i=e.length>n+1&&e.charAt(n+1)===t;return i&&n++,i},w=function(t){var e=y(t),s="@"===t?14:"!"===t?20:"y"===t&&e?4:"o"===t?3:2,n="y"===t?s:1,o=RegExp("^\\d{"+n+","+s+"}"),a=i.substring(h).match(o);if(!a)throw"Missing number at position "+h;return h+=a[0].length,parseInt(a[0],10)},k=function(e,s,n){var o=-1,a=t.map(y(e)?n:s,function(t,e){return[[e,t]]}).sort(function(t,e){return-(t[1].length-e[1].length)});if(t.each(a,function(t,e){var s=e[1];return i.substr(h,s.length).toLowerCase()===s.toLowerCase()?(o=e[0],h+=s.length,!1):void 0}),-1!==o)return o+1;throw"Unknown name at position "+h},x=function(){if(i.charAt(h)!==e.charAt(n))throw"Unexpected literal at position "+h;h++};for(n=0;e.length>n;n++)if(b)"'"!==e.charAt(n)||y("'")?x():b=!1;else switch(e.charAt(n)){case"d":_=w("d");break;case"D":k("D",u,d);break;case"o":v=w("o");break;case"m":m=w("m");break;case"M":m=k("M",p,f);break;case"y":g=w("y");break;case"@":r=new Date(w("@")),g=r.getFullYear(),m=r.getMonth()+1,_=r.getDate();break;case"!":r=new Date((w("!")-this._ticksTo1970)/1e4),g=r.getFullYear(),m=r.getMonth()+1,_=r.getDate();break;case"'":y("'")?x():b=!0;break;default:x()}if(i.length>h&&(a=i.substr(h),!/^\s+/.test(a)))throw"Extra/unparsed characters found in date: "+a;if(-1===g?g=(new Date).getFullYear():100>g&&(g+=(new Date).getFullYear()-(new Date).getFullYear()%100+(c>=g?0:-100)),v>-1)for(m=1,_=v;;){if(o=this._getDaysInMonth(g,m-1),o>=_)break;m++,_-=o}if(r=this._daylightSavingAdjust(new Date(g,m-1,_)),r.getFullYear()!==g||r.getMonth()+1!==m||r.getDate()!==_)throw"Invalid date";return r},ATOM:"yy-mm-dd",COOKIE:"D, dd M yy",ISO_8601:"yy-mm-dd",RFC_822:"D, d M y",RFC_850:"DD, dd-M-y",RFC_1036:"D, d M y",RFC_1123:"D, d M yy",RFC_2822:"D, d M yy",RSS:"D, d M y",TICKS:"!",TIMESTAMP:"@",W3C:"yy-mm-dd",_ticksTo1970:1e7*60*60*24*(718685+Math.floor(492.5)-Math.floor(19.7)+Math.floor(4.925)),formatDate:function(t,e,i){if(!e)return"";var s,n=(i?i.dayNamesShort:null)||this._defaults.dayNamesShort,o=(i?i.dayNames:null)||this._defaults.dayNames,a=(i?i.monthNamesShort:null)||this._defaults.monthNamesShort,r=(i?i.monthNames:null)||this._defaults.monthNames,h=function(e){var i=t.length>s+1&&t.charAt(s+1)===e;return i&&s++,i},l=function(t,e,i){var s=""+e;if(h(t))for(;i>s.length;)s="0"+s;return s},c=function(t,e,i,s){return h(t)?s[e]:i[e]},u="",d=!1;if(e)for(s=0;t.length>s;s++)if(d)"'"!==t.charAt(s)||h("'")?u+=t.charAt(s):d=!1;else switch(t.charAt(s)){case"d":u+=l("d",e.getDate(),2);break;case"D":u+=c("D",e.getDay(),n,o);break;case"o":u+=l("o",Math.round((new Date(e.getFullYear(),e.getMonth(),e.getDate()).getTime()-new Date(e.getFullYear(),0,0).getTime())/864e5),3);break;case"m":u+=l("m",e.getMonth()+1,2);break;case"M":u+=c("M",e.getMonth(),a,r);break;case"y":u+=h("y")?e.getFullYear():(10>e.getFullYear()%100?"0":"")+e.getFullYear()%100;break;case"@":u+=e.getTime();break;case"!":u+=1e4*e.getTime()+this._ticksTo1970;break;case"'":h("'")?u+="'":d=!0;break;default:u+=t.charAt(s)}return u},_possibleChars:function(t){var e,i="",s=!1,n=function(i){var s=t.length>e+1&&t.charAt(e+1)===i;return s&&e++,s};for(e=0;t.length>e;e++)if(s)"'"!==t.charAt(e)||n("'")?i+=t.charAt(e):s=!1;else switch(t.charAt(e)){case"d":case"m":case"y":case"@":i+="0123456789";break;case"D":case"M":return null;case"'":n("'")?i+="'":s=!0;break;default:i+=t.charAt(e)}return i},_get:function(t,e){return void 0!==t.settings[e]?t.settings[e]:this._defaults[e]},_setDateFromField:function(t,e){if(t.input.val()!==t.lastVal){var i=this._get(t,"dateFormat"),s=t.lastVal=t.input?t.input.val():null,n=this._getDefaultDate(t),o=n,a=this._getFormatConfig(t);try{o=this.parseDate(i,s,a)||n}catch(r){s=e?"":s}t.selectedDay=o.getDate(),t.drawMonth=t.selectedMonth=o.getMonth(),t.drawYear=t.selectedYear=o.getFullYear(),t.currentDay=s?o.getDate():0,t.currentMonth=s?o.getMonth():0,t.currentYear=s?o.getFullYear():0,this._adjustInstDate(t)}},_getDefaultDate:function(t){return this._restrictMinMax(t,this._determineDate(t,this._get(t,"defaultDate"),new Date))},_determineDate:function(e,i,s){var n=function(t){var e=new Date;return e.setDate(e.getDate()+t),e},o=function(i){try{return t.datepicker.parseDate(t.datepicker._get(e,"dateFormat"),i,t.datepicker._getFormatConfig(e))}catch(s){}for(var n=(i.toLowerCase().match(/^c/)?t.datepicker._getDate(e):null)||new Date,o=n.getFullYear(),a=n.getMonth(),r=n.getDate(),h=/([+\-]?[0-9]+)\s*(d|D|w|W|m|M|y|Y)?/g,l=h.exec(i);l;){switch(l[2]||"d"){case"d":case"D":r+=parseInt(l[1],10);break;case"w":case"W":r+=7*parseInt(l[1],10);break;case"m":case"M":a+=parseInt(l[1],10),r=Math.min(r,t.datepicker._getDaysInMonth(o,a));break;case"y":case"Y":o+=parseInt(l[1],10),r=Math.min(r,t.datepicker._getDaysInMonth(o,a))}l=h.exec(i)}return new Date(o,a,r)},a=null==i||""===i?s:"string"==typeof i?o(i):"number"==typeof i?isNaN(i)?s:n(i):new Date(i.getTime());return a=a&&"Invalid Date"==""+a?s:a,a&&(a.setHours(0),a.setMinutes(0),a.setSeconds(0),a.setMilliseconds(0)),this._daylightSavingAdjust(a)},_daylightSavingAdjust:function(t){return t?(t.setHours(t.getHours()>12?t.getHours()+2:0),t):null},_setDate:function(t,e,i){var s=!e,n=t.selectedMonth,o=t.selectedYear,a=this._restrictMinMax(t,this._determineDate(t,e,new Date));t.selectedDay=t.currentDay=a.getDate(),t.drawMonth=t.selectedMonth=t.currentMonth=a.getMonth(),t.drawYear=t.selectedYear=t.currentYear=a.getFullYear(),n===t.selectedMonth&&o===t.selectedYear||i||this._notifyChange(t),this._adjustInstDate(t),t.input&&t.input.val(s?"":this._formatDate(t))},_getDate:function(t){var e=!t.currentYear||t.input&&""===t.input.val()?null:this._daylightSavingAdjust(new Date(t.currentYear,t.currentMonth,t.currentDay));return e},_attachHandlers:function(e){var i=this._get(e,"stepMonths"),s="#"+e.id.replace(/\\\\/g,"\\");e.dpDiv.find("[data-handler]").map(function(){var e={prev:function(){t.datepicker._adjustDate(s,-i,"M")},next:function(){t.datepicker._adjustDate(s,+i,"M")},hide:function(){t.datepicker._hideDatepicker()},today:function(){t.datepicker._gotoToday(s)},selectDay:function(){return t.datepicker._selectDay(s,+this.getAttribute("data-month"),+this.getAttribute("data-year"),this),!1},selectMonth:function(){return t.datepicker._selectMonthYear(s,this,"M"),!1},selectYear:function(){return t.datepicker._selectMonthYear(s,this,"Y"),!1}};t(this).on(this.getAttribute("data-event"),e[this.getAttribute("data-handler")])})},_generateHTML:function(t){var e,i,s,n,o,a,r,h,l,c,u,d,p,f,g,m,_,v,b,y,w,k,x,C,D,I,T,P,M,S,H,z,O,A,N,W,E,F,L,R=new Date,B=this._daylightSavingAdjust(new Date(R.getFullYear(),R.getMonth(),R.getDate())),Y=this._get(t,"isRTL"),j=this._get(t,"showButtonPanel"),q=this._get(t,"hideIfNoPrevNext"),K=this._get(t,"navigationAsDateFormat"),U=this._getNumberOfMonths(t),V=this._get(t,"showCurrentAtPos"),$=this._get(t,"stepMonths"),X=1!==U[0]||1!==U[1],G=this._daylightSavingAdjust(t.currentDay?new Date(t.currentYear,t.currentMonth,t.currentDay):new Date(9999,9,9)),Q=this._getMinMaxDate(t,"min"),J=this._getMinMaxDate(t,"max"),Z=t.drawMonth-V,te=t.drawYear;if(0>Z&&(Z+=12,te--),J)for(e=this._daylightSavingAdjust(new Date(J.getFullYear(),J.getMonth()-U[0]*U[1]+1,J.getDate())),e=Q&&Q>e?Q:e;this._daylightSavingAdjust(new Date(te,Z,1))>e;)Z--,0>Z&&(Z=11,te--);for(t.drawMonth=Z,t.drawYear=te,i=this._get(t,"prevText"),i=K?this.formatDate(i,this._daylightSavingAdjust(new Date(te,Z-$,1)),this._getFormatConfig(t)):i,s=this._canAdjustMonth(t,-1,te,Z)?"<a class='ui-datepicker-prev ui-corner-all' data-handler='prev' data-event='click' title='"+i+"'><span class='ui-icon ui-icon-circle-triangle-"+(Y?"e":"w")+"'>"+i+"</span></a>":q?"":"<a class='ui-datepicker-prev ui-corner-all ui-state-disabled' title='"+i+"'><span class='ui-icon ui-icon-circle-triangle-"+(Y?"e":"w")+"'>"+i+"</span></a>",n=this._get(t,"nextText"),n=K?this.formatDate(n,this._daylightSavingAdjust(new Date(te,Z+$,1)),this._getFormatConfig(t)):n,o=this._canAdjustMonth(t,1,te,Z)?"<a class='ui-datepicker-next ui-corner-all' data-handler='next' data-event='click' title='"+n+"'><span class='ui-icon ui-icon-circle-triangle-"+(Y?"w":"e")+"'>"+n+"</span></a>":q?"":"<a class='ui-datepicker-next ui-corner-all ui-state-disabled' title='"+n+"'><span class='ui-icon ui-icon-circle-triangle-"+(Y?"w":"e")+"'>"+n+"</span></a>",a=this._get(t,"currentText"),r=this._get(t,"gotoCurrent")&&t.currentDay?G:B,a=K?this.formatDate(a,r,this._getFormatConfig(t)):a,h=t.inline?"":"<button type='button' class='ui-datepicker-close ui-state-default ui-priority-primary ui-corner-all' data-handler='hide' data-event='click'>"+this._get(t,"closeText")+"</button>",l=j?"<div class='ui-datepicker-buttonpane ui-widget-content'>"+(Y?h:"")+(this._isInRange(t,r)?"<button type='button' class='ui-datepicker-current ui-state-default ui-priority-secondary ui-corner-all' data-handler='today' data-event='click'>"+a+"</button>":"")+(Y?"":h)+"</div>":"",c=parseInt(this._get(t,"firstDay"),10),c=isNaN(c)?0:c,u=this._get(t,"showWeek"),d=this._get(t,"dayNames"),p=this._get(t,"dayNamesMin"),f=this._get(t,"monthNames"),g=this._get(t,"monthNamesShort"),m=this._get(t,"beforeShowDay"),_=this._get(t,"showOtherMonths"),v=this._get(t,"selectOtherMonths"),b=this._getDefaultDate(t),y="",k=0;U[0]>k;k++){for(x="",this.maxRows=4,C=0;U[1]>C;C++){if(D=this._daylightSavingAdjust(new Date(te,Z,t.selectedDay)),I=" ui-corner-all",T="",X){if(T+="<div class='ui-datepicker-group",U[1]>1)switch(C){case 0:T+=" ui-datepicker-group-first",I=" ui-corner-"+(Y?"right":"left");
|
||
break;case U[1]-1:T+=" ui-datepicker-group-last",I=" ui-corner-"+(Y?"left":"right");break;default:T+=" ui-datepicker-group-middle",I=""}T+="'>"}for(T+="<div class='ui-datepicker-header ui-widget-header ui-helper-clearfix"+I+"'>"+(/all|left/.test(I)&&0===k?Y?o:s:"")+(/all|right/.test(I)&&0===k?Y?s:o:"")+this._generateMonthYearHeader(t,Z,te,Q,J,k>0||C>0,f,g)+"</div><table class='ui-datepicker-calendar'><thead>"+"<tr>",P=u?"<th class='ui-datepicker-week-col'>"+this._get(t,"weekHeader")+"</th>":"",w=0;7>w;w++)M=(w+c)%7,P+="<th scope='col'"+((w+c+6)%7>=5?" class='ui-datepicker-week-end'":"")+">"+"<span title='"+d[M]+"'>"+p[M]+"</span></th>";for(T+=P+"</tr></thead><tbody>",S=this._getDaysInMonth(te,Z),te===t.selectedYear&&Z===t.selectedMonth&&(t.selectedDay=Math.min(t.selectedDay,S)),H=(this._getFirstDayOfMonth(te,Z)-c+7)%7,z=Math.ceil((H+S)/7),O=X?this.maxRows>z?this.maxRows:z:z,this.maxRows=O,A=this._daylightSavingAdjust(new Date(te,Z,1-H)),N=0;O>N;N++){for(T+="<tr>",W=u?"<td class='ui-datepicker-week-col'>"+this._get(t,"calculateWeek")(A)+"</td>":"",w=0;7>w;w++)E=m?m.apply(t.input?t.input[0]:null,[A]):[!0,""],F=A.getMonth()!==Z,L=F&&!v||!E[0]||Q&&Q>A||J&&A>J,W+="<td class='"+((w+c+6)%7>=5?" ui-datepicker-week-end":"")+(F?" ui-datepicker-other-month":"")+(A.getTime()===D.getTime()&&Z===t.selectedMonth&&t._keyEvent||b.getTime()===A.getTime()&&b.getTime()===D.getTime()?" "+this._dayOverClass:"")+(L?" "+this._unselectableClass+" ui-state-disabled":"")+(F&&!_?"":" "+E[1]+(A.getTime()===G.getTime()?" "+this._currentClass:"")+(A.getTime()===B.getTime()?" ui-datepicker-today":""))+"'"+(F&&!_||!E[2]?"":" title='"+E[2].replace(/'/g,"'")+"'")+(L?"":" data-handler='selectDay' data-event='click' data-month='"+A.getMonth()+"' data-year='"+A.getFullYear()+"'")+">"+(F&&!_?" ":L?"<span class='ui-state-default'>"+A.getDate()+"</span>":"<a class='ui-state-default"+(A.getTime()===B.getTime()?" ui-state-highlight":"")+(A.getTime()===G.getTime()?" ui-state-active":"")+(F?" ui-priority-secondary":"")+"' href='#'>"+A.getDate()+"</a>")+"</td>",A.setDate(A.getDate()+1),A=this._daylightSavingAdjust(A);T+=W+"</tr>"}Z++,Z>11&&(Z=0,te++),T+="</tbody></table>"+(X?"</div>"+(U[0]>0&&C===U[1]-1?"<div class='ui-datepicker-row-break'></div>":""):""),x+=T}y+=x}return y+=l,t._keyEvent=!1,y},_generateMonthYearHeader:function(t,e,i,s,n,o,a,r){var h,l,c,u,d,p,f,g,m=this._get(t,"changeMonth"),_=this._get(t,"changeYear"),v=this._get(t,"showMonthAfterYear"),b="<div class='ui-datepicker-title'>",y="";if(o||!m)y+="<span class='ui-datepicker-month'>"+a[e]+"</span>";else{for(h=s&&s.getFullYear()===i,l=n&&n.getFullYear()===i,y+="<select class='ui-datepicker-month' data-handler='selectMonth' data-event='change'>",c=0;12>c;c++)(!h||c>=s.getMonth())&&(!l||n.getMonth()>=c)&&(y+="<option value='"+c+"'"+(c===e?" selected='selected'":"")+">"+r[c]+"</option>");y+="</select>"}if(v||(b+=y+(!o&&m&&_?"":" ")),!t.yearshtml)if(t.yearshtml="",o||!_)b+="<span class='ui-datepicker-year'>"+i+"</span>";else{for(u=this._get(t,"yearRange").split(":"),d=(new Date).getFullYear(),p=function(t){var e=t.match(/c[+\-].*/)?i+parseInt(t.substring(1),10):t.match(/[+\-].*/)?d+parseInt(t,10):parseInt(t,10);return isNaN(e)?d:e},f=p(u[0]),g=Math.max(f,p(u[1]||"")),f=s?Math.max(f,s.getFullYear()):f,g=n?Math.min(g,n.getFullYear()):g,t.yearshtml+="<select class='ui-datepicker-year' data-handler='selectYear' data-event='change'>";g>=f;f++)t.yearshtml+="<option value='"+f+"'"+(f===i?" selected='selected'":"")+">"+f+"</option>";t.yearshtml+="</select>",b+=t.yearshtml,t.yearshtml=null}return b+=this._get(t,"yearSuffix"),v&&(b+=(!o&&m&&_?"":" ")+y),b+="</div>"},_adjustInstDate:function(t,e,i){var s=t.selectedYear+("Y"===i?e:0),n=t.selectedMonth+("M"===i?e:0),o=Math.min(t.selectedDay,this._getDaysInMonth(s,n))+("D"===i?e:0),a=this._restrictMinMax(t,this._daylightSavingAdjust(new Date(s,n,o)));t.selectedDay=a.getDate(),t.drawMonth=t.selectedMonth=a.getMonth(),t.drawYear=t.selectedYear=a.getFullYear(),("M"===i||"Y"===i)&&this._notifyChange(t)},_restrictMinMax:function(t,e){var i=this._getMinMaxDate(t,"min"),s=this._getMinMaxDate(t,"max"),n=i&&i>e?i:e;return s&&n>s?s:n},_notifyChange:function(t){var e=this._get(t,"onChangeMonthYear");e&&e.apply(t.input?t.input[0]:null,[t.selectedYear,t.selectedMonth+1,t])},_getNumberOfMonths:function(t){var e=this._get(t,"numberOfMonths");return null==e?[1,1]:"number"==typeof e?[1,e]:e},_getMinMaxDate:function(t,e){return this._determineDate(t,this._get(t,e+"Date"),null)},_getDaysInMonth:function(t,e){return 32-this._daylightSavingAdjust(new Date(t,e,32)).getDate()},_getFirstDayOfMonth:function(t,e){return new Date(t,e,1).getDay()},_canAdjustMonth:function(t,e,i,s){var n=this._getNumberOfMonths(t),o=this._daylightSavingAdjust(new Date(i,s+(0>e?e:n[0]*n[1]),1));return 0>e&&o.setDate(this._getDaysInMonth(o.getFullYear(),o.getMonth())),this._isInRange(t,o)},_isInRange:function(t,e){var i,s,n=this._getMinMaxDate(t,"min"),o=this._getMinMaxDate(t,"max"),a=null,r=null,h=this._get(t,"yearRange");return h&&(i=h.split(":"),s=(new Date).getFullYear(),a=parseInt(i[0],10),r=parseInt(i[1],10),i[0].match(/[+\-].*/)&&(a+=s),i[1].match(/[+\-].*/)&&(r+=s)),(!n||e.getTime()>=n.getTime())&&(!o||e.getTime()<=o.getTime())&&(!a||e.getFullYear()>=a)&&(!r||r>=e.getFullYear())},_getFormatConfig:function(t){var e=this._get(t,"shortYearCutoff");return e="string"!=typeof e?e:(new Date).getFullYear()%100+parseInt(e,10),{shortYearCutoff:e,dayNamesShort:this._get(t,"dayNamesShort"),dayNames:this._get(t,"dayNames"),monthNamesShort:this._get(t,"monthNamesShort"),monthNames:this._get(t,"monthNames")}},_formatDate:function(t,e,i,s){e||(t.currentDay=t.selectedDay,t.currentMonth=t.selectedMonth,t.currentYear=t.selectedYear);var n=e?"object"==typeof e?e:this._daylightSavingAdjust(new Date(s,i,e)):this._daylightSavingAdjust(new Date(t.currentYear,t.currentMonth,t.currentDay));return this.formatDate(this._get(t,"dateFormat"),n,this._getFormatConfig(t))}}),t.fn.datepicker=function(e){if(!this.length)return this;t.datepicker.initialized||(t(document).on("mousedown",t.datepicker._checkExternalClick),t.datepicker.initialized=!0),0===t("#"+t.datepicker._mainDivId).length&&t("body").append(t.datepicker.dpDiv);var i=Array.prototype.slice.call(arguments,1);return"string"!=typeof e||"isDisabled"!==e&&"getDate"!==e&&"widget"!==e?"option"===e&&2===arguments.length&&"string"==typeof arguments[1]?t.datepicker["_"+e+"Datepicker"].apply(t.datepicker,[this[0]].concat(i)):this.each(function(){"string"==typeof e?t.datepicker["_"+e+"Datepicker"].apply(t.datepicker,[this].concat(i)):t.datepicker._attachDatepicker(this,e)}):t.datepicker["_"+e+"Datepicker"].apply(t.datepicker,[this[0]].concat(i))},t.datepicker=new s,t.datepicker.initialized=!1,t.datepicker.uuid=(new Date).getTime(),t.datepicker.version="1.12.1",t.datepicker,t.widget("ui.dialog",{version:"1.12.1",options:{appendTo:"body",autoOpen:!0,buttons:[],classes:{"ui-dialog":"ui-corner-all","ui-dialog-titlebar":"ui-corner-all"},closeOnEscape:!0,closeText:"Close",draggable:!0,hide:null,height:"auto",maxHeight:null,maxWidth:null,minHeight:150,minWidth:150,modal:!1,position:{my:"center",at:"center",of:window,collision:"fit",using:function(e){var i=t(this).css(e).offset().top;0>i&&t(this).css("top",e.top-i)}},resizable:!0,show:null,title:null,width:300,beforeClose:null,close:null,drag:null,dragStart:null,dragStop:null,focus:null,open:null,resize:null,resizeStart:null,resizeStop:null},sizeRelatedOptions:{buttons:!0,height:!0,maxHeight:!0,maxWidth:!0,minHeight:!0,minWidth:!0,width:!0},resizableRelatedOptions:{maxHeight:!0,maxWidth:!0,minHeight:!0,minWidth:!0},_create:function(){this.originalCss={display:this.element[0].style.display,width:this.element[0].style.width,minHeight:this.element[0].style.minHeight,maxHeight:this.element[0].style.maxHeight,height:this.element[0].style.height},this.originalPosition={parent:this.element.parent(),index:this.element.parent().children().index(this.element)},this.originalTitle=this.element.attr("title"),null==this.options.title&&null!=this.originalTitle&&(this.options.title=this.originalTitle),this.options.disabled&&(this.options.disabled=!1),this._createWrapper(),this.element.show().removeAttr("title").appendTo(this.uiDialog),this._addClass("ui-dialog-content","ui-widget-content"),this._createTitlebar(),this._createButtonPane(),this.options.draggable&&t.fn.draggable&&this._makeDraggable(),this.options.resizable&&t.fn.resizable&&this._makeResizable(),this._isOpen=!1,this._trackFocus()},_init:function(){this.options.autoOpen&&this.open()},_appendTo:function(){var e=this.options.appendTo;return e&&(e.jquery||e.nodeType)?t(e):this.document.find(e||"body").eq(0)},_destroy:function(){var t,e=this.originalPosition;this._untrackInstance(),this._destroyOverlay(),this.element.removeUniqueId().css(this.originalCss).detach(),this.uiDialog.remove(),this.originalTitle&&this.element.attr("title",this.originalTitle),t=e.parent.children().eq(e.index),t.length&&t[0]!==this.element[0]?t.before(this.element):e.parent.append(this.element)},widget:function(){return this.uiDialog},disable:t.noop,enable:t.noop,close:function(e){var i=this;this._isOpen&&this._trigger("beforeClose",e)!==!1&&(this._isOpen=!1,this._focusedElement=null,this._destroyOverlay(),this._untrackInstance(),this.opener.filter(":focusable").trigger("focus").length||t.ui.safeBlur(t.ui.safeActiveElement(this.document[0])),this._hide(this.uiDialog,this.options.hide,function(){i._trigger("close",e)}))},isOpen:function(){return this._isOpen},moveToTop:function(){this._moveToTop()},_moveToTop:function(e,i){var s=!1,n=this.uiDialog.siblings(".ui-front:visible").map(function(){return+t(this).css("z-index")}).get(),o=Math.max.apply(null,n);return o>=+this.uiDialog.css("z-index")&&(this.uiDialog.css("z-index",o+1),s=!0),s&&!i&&this._trigger("focus",e),s},open:function(){var e=this;return this._isOpen?(this._moveToTop()&&this._focusTabbable(),void 0):(this._isOpen=!0,this.opener=t(t.ui.safeActiveElement(this.document[0])),this._size(),this._position(),this._createOverlay(),this._moveToTop(null,!0),this.overlay&&this.overlay.css("z-index",this.uiDialog.css("z-index")-1),this._show(this.uiDialog,this.options.show,function(){e._focusTabbable(),e._trigger("focus")}),this._makeFocusTarget(),this._trigger("open"),void 0)},_focusTabbable:function(){var t=this._focusedElement;t||(t=this.element.find("[autofocus]")),t.length||(t=this.element.find(":tabbable")),t.length||(t=this.uiDialogButtonPane.find(":tabbable")),t.length||(t=this.uiDialogTitlebarClose.filter(":tabbable")),t.length||(t=this.uiDialog),t.eq(0).trigger("focus")},_keepFocus:function(e){function i(){var e=t.ui.safeActiveElement(this.document[0]),i=this.uiDialog[0]===e||t.contains(this.uiDialog[0],e);i||this._focusTabbable()}e.preventDefault(),i.call(this),this._delay(i)},_createWrapper:function(){this.uiDialog=t("<div>").hide().attr({tabIndex:-1,role:"dialog"}).appendTo(this._appendTo()),this._addClass(this.uiDialog,"ui-dialog","ui-widget ui-widget-content ui-front"),this._on(this.uiDialog,{keydown:function(e){if(this.options.closeOnEscape&&!e.isDefaultPrevented()&&e.keyCode&&e.keyCode===t.ui.keyCode.ESCAPE)return e.preventDefault(),this.close(e),void 0;if(e.keyCode===t.ui.keyCode.TAB&&!e.isDefaultPrevented()){var i=this.uiDialog.find(":tabbable"),s=i.filter(":first"),n=i.filter(":last");e.target!==n[0]&&e.target!==this.uiDialog[0]||e.shiftKey?e.target!==s[0]&&e.target!==this.uiDialog[0]||!e.shiftKey||(this._delay(function(){n.trigger("focus")}),e.preventDefault()):(this._delay(function(){s.trigger("focus")}),e.preventDefault())}},mousedown:function(t){this._moveToTop(t)&&this._focusTabbable()}}),this.element.find("[aria-describedby]").length||this.uiDialog.attr({"aria-describedby":this.element.uniqueId().attr("id")})},_createTitlebar:function(){var e;this.uiDialogTitlebar=t("<div>"),this._addClass(this.uiDialogTitlebar,"ui-dialog-titlebar","ui-widget-header ui-helper-clearfix"),this._on(this.uiDialogTitlebar,{mousedown:function(e){t(e.target).closest(".ui-dialog-titlebar-close")||this.uiDialog.trigger("focus")}}),this.uiDialogTitlebarClose=t("<button type='button'></button>").button({label:t("<a>").text(this.options.closeText).html(),icon:"ui-icon-closethick",showLabel:!1}).appendTo(this.uiDialogTitlebar),this._addClass(this.uiDialogTitlebarClose,"ui-dialog-titlebar-close"),this._on(this.uiDialogTitlebarClose,{click:function(t){t.preventDefault(),this.close(t)}}),e=t("<span>").uniqueId().prependTo(this.uiDialogTitlebar),this._addClass(e,"ui-dialog-title"),this._title(e),this.uiDialogTitlebar.prependTo(this.uiDialog),this.uiDialog.attr({"aria-labelledby":e.attr("id")})},_title:function(t){this.options.title?t.text(this.options.title):t.html(" ")},_createButtonPane:function(){this.uiDialogButtonPane=t("<div>"),this._addClass(this.uiDialogButtonPane,"ui-dialog-buttonpane","ui-widget-content ui-helper-clearfix"),this.uiButtonSet=t("<div>").appendTo(this.uiDialogButtonPane),this._addClass(this.uiButtonSet,"ui-dialog-buttonset"),this._createButtons()},_createButtons:function(){var e=this,i=this.options.buttons;return this.uiDialogButtonPane.remove(),this.uiButtonSet.empty(),t.isEmptyObject(i)||t.isArray(i)&&!i.length?(this._removeClass(this.uiDialog,"ui-dialog-buttons"),void 0):(t.each(i,function(i,s){var n,o;s=t.isFunction(s)?{click:s,text:i}:s,s=t.extend({type:"button"},s),n=s.click,o={icon:s.icon,iconPosition:s.iconPosition,showLabel:s.showLabel,icons:s.icons,text:s.text},delete s.click,delete s.icon,delete s.iconPosition,delete s.showLabel,delete s.icons,"boolean"==typeof s.text&&delete s.text,t("<button></button>",s).button(o).appendTo(e.uiButtonSet).on("click",function(){n.apply(e.element[0],arguments)})}),this._addClass(this.uiDialog,"ui-dialog-buttons"),this.uiDialogButtonPane.appendTo(this.uiDialog),void 0)},_makeDraggable:function(){function e(t){return{position:t.position,offset:t.offset}}var i=this,s=this.options;this.uiDialog.draggable({cancel:".ui-dialog-content, .ui-dialog-titlebar-close",handle:".ui-dialog-titlebar",containment:"document",start:function(s,n){i._addClass(t(this),"ui-dialog-dragging"),i._blockFrames(),i._trigger("dragStart",s,e(n))},drag:function(t,s){i._trigger("drag",t,e(s))},stop:function(n,o){var a=o.offset.left-i.document.scrollLeft(),r=o.offset.top-i.document.scrollTop();s.position={my:"left top",at:"left"+(a>=0?"+":"")+a+" "+"top"+(r>=0?"+":"")+r,of:i.window},i._removeClass(t(this),"ui-dialog-dragging"),i._unblockFrames(),i._trigger("dragStop",n,e(o))}})},_makeResizable:function(){function e(t){return{originalPosition:t.originalPosition,originalSize:t.originalSize,position:t.position,size:t.size}}var i=this,s=this.options,n=s.resizable,o=this.uiDialog.css("position"),a="string"==typeof n?n:"n,e,s,w,se,sw,ne,nw";this.uiDialog.resizable({cancel:".ui-dialog-content",containment:"document",alsoResize:this.element,maxWidth:s.maxWidth,maxHeight:s.maxHeight,minWidth:s.minWidth,minHeight:this._minHeight(),handles:a,start:function(s,n){i._addClass(t(this),"ui-dialog-resizing"),i._blockFrames(),i._trigger("resizeStart",s,e(n))},resize:function(t,s){i._trigger("resize",t,e(s))},stop:function(n,o){var a=i.uiDialog.offset(),r=a.left-i.document.scrollLeft(),h=a.top-i.document.scrollTop();s.height=i.uiDialog.height(),s.width=i.uiDialog.width(),s.position={my:"left top",at:"left"+(r>=0?"+":"")+r+" "+"top"+(h>=0?"+":"")+h,of:i.window},i._removeClass(t(this),"ui-dialog-resizing"),i._unblockFrames(),i._trigger("resizeStop",n,e(o))}}).css("position",o)},_trackFocus:function(){this._on(this.widget(),{focusin:function(e){this._makeFocusTarget(),this._focusedElement=t(e.target)}})},_makeFocusTarget:function(){this._untrackInstance(),this._trackingInstances().unshift(this)},_untrackInstance:function(){var e=this._trackingInstances(),i=t.inArray(this,e);-1!==i&&e.splice(i,1)},_trackingInstances:function(){var t=this.document.data("ui-dialog-instances");return t||(t=[],this.document.data("ui-dialog-instances",t)),t},_minHeight:function(){var t=this.options;return"auto"===t.height?t.minHeight:Math.min(t.minHeight,t.height)},_position:function(){var t=this.uiDialog.is(":visible");t||this.uiDialog.show(),this.uiDialog.position(this.options.position),t||this.uiDialog.hide()},_setOptions:function(e){var i=this,s=!1,n={};t.each(e,function(t,e){i._setOption(t,e),t in i.sizeRelatedOptions&&(s=!0),t in i.resizableRelatedOptions&&(n[t]=e)}),s&&(this._size(),this._position()),this.uiDialog.is(":data(ui-resizable)")&&this.uiDialog.resizable("option",n)},_setOption:function(e,i){var s,n,o=this.uiDialog;"disabled"!==e&&(this._super(e,i),"appendTo"===e&&this.uiDialog.appendTo(this._appendTo()),"buttons"===e&&this._createButtons(),"closeText"===e&&this.uiDialogTitlebarClose.button({label:t("<a>").text(""+this.options.closeText).html()}),"draggable"===e&&(s=o.is(":data(ui-draggable)"),s&&!i&&o.draggable("destroy"),!s&&i&&this._makeDraggable()),"position"===e&&this._position(),"resizable"===e&&(n=o.is(":data(ui-resizable)"),n&&!i&&o.resizable("destroy"),n&&"string"==typeof i&&o.resizable("option","handles",i),n||i===!1||this._makeResizable()),"title"===e&&this._title(this.uiDialogTitlebar.find(".ui-dialog-title")))},_size:function(){var t,e,i,s=this.options;this.element.show().css({width:"auto",minHeight:0,maxHeight:"none",height:0}),s.minWidth>s.width&&(s.width=s.minWidth),t=this.uiDialog.css({height:"auto",width:s.width}).outerHeight(),e=Math.max(0,s.minHeight-t),i="number"==typeof s.maxHeight?Math.max(0,s.maxHeight-t):"none","auto"===s.height?this.element.css({minHeight:e,maxHeight:i,height:"auto"}):this.element.height(Math.max(0,s.height-t)),this.uiDialog.is(":data(ui-resizable)")&&this.uiDialog.resizable("option","minHeight",this._minHeight())},_blockFrames:function(){this.iframeBlocks=this.document.find("iframe").map(function(){var e=t(this);return t("<div>").css({position:"absolute",width:e.outerWidth(),height:e.outerHeight()}).appendTo(e.parent()).offset(e.offset())[0]})},_unblockFrames:function(){this.iframeBlocks&&(this.iframeBlocks.remove(),delete this.iframeBlocks)},_allowInteraction:function(e){return t(e.target).closest(".ui-dialog").length?!0:!!t(e.target).closest(".ui-datepicker").length},_createOverlay:function(){if(this.options.modal){var e=!0;this._delay(function(){e=!1}),this.document.data("ui-dialog-overlays")||this._on(this.document,{focusin:function(t){e||this._allowInteraction(t)||(t.preventDefault(),this._trackingInstances()[0]._focusTabbable())}}),this.overlay=t("<div>").appendTo(this._appendTo()),this._addClass(this.overlay,null,"ui-widget-overlay ui-front"),this._on(this.overlay,{mousedown:"_keepFocus"}),this.document.data("ui-dialog-overlays",(this.document.data("ui-dialog-overlays")||0)+1)}},_destroyOverlay:function(){if(this.options.modal&&this.overlay){var t=this.document.data("ui-dialog-overlays")-1;t?this.document.data("ui-dialog-overlays",t):(this._off(this.document,"focusin"),this.document.removeData("ui-dialog-overlays")),this.overlay.remove(),this.overlay=null}}}),t.uiBackCompat!==!1&&t.widget("ui.dialog",t.ui.dialog,{options:{dialogClass:""},_createWrapper:function(){this._super(),this.uiDialog.addClass(this.options.dialogClass)},_setOption:function(t,e){"dialogClass"===t&&this.uiDialog.removeClass(this.options.dialogClass).addClass(e),this._superApply(arguments)}}),t.ui.dialog,t.widget("ui.progressbar",{version:"1.12.1",options:{classes:{"ui-progressbar":"ui-corner-all","ui-progressbar-value":"ui-corner-left","ui-progressbar-complete":"ui-corner-right"},max:100,value:0,change:null,complete:null},min:0,_create:function(){this.oldValue=this.options.value=this._constrainedValue(),this.element.attr({role:"progressbar","aria-valuemin":this.min}),this._addClass("ui-progressbar","ui-widget ui-widget-content"),this.valueDiv=t("<div>").appendTo(this.element),this._addClass(this.valueDiv,"ui-progressbar-value","ui-widget-header"),this._refreshValue()},_destroy:function(){this.element.removeAttr("role aria-valuemin aria-valuemax aria-valuenow"),this.valueDiv.remove()},value:function(t){return void 0===t?this.options.value:(this.options.value=this._constrainedValue(t),this._refreshValue(),void 0)},_constrainedValue:function(t){return void 0===t&&(t=this.options.value),this.indeterminate=t===!1,"number"!=typeof t&&(t=0),this.indeterminate?!1:Math.min(this.options.max,Math.max(this.min,t))},_setOptions:function(t){var e=t.value;delete t.value,this._super(t),this.options.value=this._constrainedValue(e),this._refreshValue()},_setOption:function(t,e){"max"===t&&(e=Math.max(this.min,e)),this._super(t,e)},_setOptionDisabled:function(t){this._super(t),this.element.attr("aria-disabled",t),this._toggleClass(null,"ui-state-disabled",!!t)},_percentage:function(){return this.indeterminate?100:100*(this.options.value-this.min)/(this.options.max-this.min)},_refreshValue:function(){var e=this.options.value,i=this._percentage();this.valueDiv.toggle(this.indeterminate||e>this.min).width(i.toFixed(0)+"%"),this._toggleClass(this.valueDiv,"ui-progressbar-complete",null,e===this.options.max)._toggleClass("ui-progressbar-indeterminate",null,this.indeterminate),this.indeterminate?(this.element.removeAttr("aria-valuenow"),this.overlayDiv||(this.overlayDiv=t("<div>").appendTo(this.valueDiv),this._addClass(this.overlayDiv,"ui-progressbar-overlay"))):(this.element.attr({"aria-valuemax":this.options.max,"aria-valuenow":e}),this.overlayDiv&&(this.overlayDiv.remove(),this.overlayDiv=null)),this.oldValue!==e&&(this.oldValue=e,this._trigger("change")),e===this.options.max&&this._trigger("complete")}}),t.widget("ui.selectmenu",[t.ui.formResetMixin,{version:"1.12.1",defaultElement:"<select>",options:{appendTo:null,classes:{"ui-selectmenu-button-open":"ui-corner-top","ui-selectmenu-button-closed":"ui-corner-all"},disabled:null,icons:{button:"ui-icon-triangle-1-s"},position:{my:"left top",at:"left bottom",collision:"none"},width:!1,change:null,close:null,focus:null,open:null,select:null},_create:function(){var e=this.element.uniqueId().attr("id");this.ids={element:e,button:e+"-button",menu:e+"-menu"},this._drawButton(),this._drawMenu(),this._bindFormResetHandler(),this._rendered=!1,this.menuItems=t()},_drawButton:function(){var e,i=this,s=this._parseOption(this.element.find("option:selected"),this.element[0].selectedIndex);this.labels=this.element.labels().attr("for",this.ids.button),this._on(this.labels,{click:function(t){this.button.focus(),t.preventDefault()}}),this.element.hide(),this.button=t("<span>",{tabindex:this.options.disabled?-1:0,id:this.ids.button,role:"combobox","aria-expanded":"false","aria-autocomplete":"list","aria-owns":this.ids.menu,"aria-haspopup":"true",title:this.element.attr("title")}).insertAfter(this.element),this._addClass(this.button,"ui-selectmenu-button ui-selectmenu-button-closed","ui-button ui-widget"),e=t("<span>").appendTo(this.button),this._addClass(e,"ui-selectmenu-icon","ui-icon "+this.options.icons.button),this.buttonItem=this._renderButtonItem(s).appendTo(this.button),this.options.width!==!1&&this._resizeButton(),this._on(this.button,this._buttonEvents),this.button.one("focusin",function(){i._rendered||i._refreshMenu()})},_drawMenu:function(){var e=this;this.menu=t("<ul>",{"aria-hidden":"true","aria-labelledby":this.ids.button,id:this.ids.menu}),this.menuWrap=t("<div>").append(this.menu),this._addClass(this.menuWrap,"ui-selectmenu-menu","ui-front"),this.menuWrap.appendTo(this._appendTo()),this.menuInstance=this.menu.menu({classes:{"ui-menu":"ui-corner-bottom"},role:"listbox",select:function(t,i){t.preventDefault(),e._setSelection(),e._select(i.item.data("ui-selectmenu-item"),t)},focus:function(t,i){var s=i.item.data("ui-selectmenu-item");null!=e.focusIndex&&s.index!==e.focusIndex&&(e._trigger("focus",t,{item:s}),e.isOpen||e._select(s,t)),e.focusIndex=s.index,e.button.attr("aria-activedescendant",e.menuItems.eq(s.index).attr("id"))}}).menu("instance"),this.menuInstance._off(this.menu,"mouseleave"),this.menuInstance._closeOnDocumentClick=function(){return!1},this.menuInstance._isDivider=function(){return!1}},refresh:function(){this._refreshMenu(),this.buttonItem.replaceWith(this.buttonItem=this._renderButtonItem(this._getSelectedItem().data("ui-selectmenu-item")||{})),null===this.options.width&&this._resizeButton()},_refreshMenu:function(){var t,e=this.element.find("option");this.menu.empty(),this._parseOptions(e),this._renderMenu(this.menu,this.items),this.menuInstance.refresh(),this.menuItems=this.menu.find("li").not(".ui-selectmenu-optgroup").find(".ui-menu-item-wrapper"),this._rendered=!0,e.length&&(t=this._getSelectedItem(),this.menuInstance.focus(null,t),this._setAria(t.data("ui-selectmenu-item")),this._setOption("disabled",this.element.prop("disabled")))},open:function(t){this.options.disabled||(this._rendered?(this._removeClass(this.menu.find(".ui-state-active"),null,"ui-state-active"),this.menuInstance.focus(null,this._getSelectedItem())):this._refreshMenu(),this.menuItems.length&&(this.isOpen=!0,this._toggleAttr(),this._resizeMenu(),this._position(),this._on(this.document,this._documentClick),this._trigger("open",t)))},_position:function(){this.menuWrap.position(t.extend({of:this.button},this.options.position))},close:function(t){this.isOpen&&(this.isOpen=!1,this._toggleAttr(),this.range=null,this._off(this.document),this._trigger("close",t))},widget:function(){return this.button},menuWidget:function(){return this.menu},_renderButtonItem:function(e){var i=t("<span>");return this._setText(i,e.label),this._addClass(i,"ui-selectmenu-text"),i},_renderMenu:function(e,i){var s=this,n="";t.each(i,function(i,o){var a;o.optgroup!==n&&(a=t("<li>",{text:o.optgroup}),s._addClass(a,"ui-selectmenu-optgroup","ui-menu-divider"+(o.element.parent("optgroup").prop("disabled")?" ui-state-disabled":"")),a.appendTo(e),n=o.optgroup),s._renderItemData(e,o)})},_renderItemData:function(t,e){return this._renderItem(t,e).data("ui-selectmenu-item",e)},_renderItem:function(e,i){var s=t("<li>"),n=t("<div>",{title:i.element.attr("title")});return i.disabled&&this._addClass(s,null,"ui-state-disabled"),this._setText(n,i.label),s.append(n).appendTo(e)},_setText:function(t,e){e?t.text(e):t.html(" ")},_move:function(t,e){var i,s,n=".ui-menu-item";this.isOpen?i=this.menuItems.eq(this.focusIndex).parent("li"):(i=this.menuItems.eq(this.element[0].selectedIndex).parent("li"),n+=":not(.ui-state-disabled)"),s="first"===t||"last"===t?i["first"===t?"prevAll":"nextAll"](n).eq(-1):i[t+"All"](n).eq(0),s.length&&this.menuInstance.focus(e,s)},_getSelectedItem:function(){return this.menuItems.eq(this.element[0].selectedIndex).parent("li")},_toggle:function(t){this[this.isOpen?"close":"open"](t)},_setSelection:function(){var t;this.range&&(window.getSelection?(t=window.getSelection(),t.removeAllRanges(),t.addRange(this.range)):this.range.select(),this.button.focus())},_documentClick:{mousedown:function(e){this.isOpen&&(t(e.target).closest(".ui-selectmenu-menu, #"+t.ui.escapeSelector(this.ids.button)).length||this.close(e))}},_buttonEvents:{mousedown:function(){var t;window.getSelection?(t=window.getSelection(),t.rangeCount&&(this.range=t.getRangeAt(0))):this.range=document.selection.createRange()},click:function(t){this._setSelection(),this._toggle(t)},keydown:function(e){var i=!0;switch(e.keyCode){case t.ui.keyCode.TAB:case t.ui.keyCode.ESCAPE:this.close(e),i=!1;break;case t.ui.keyCode.ENTER:this.isOpen&&this._selectFocusedItem(e);break;case t.ui.keyCode.UP:e.altKey?this._toggle(e):this._move("prev",e);break;case t.ui.keyCode.DOWN:e.altKey?this._toggle(e):this._move("next",e);break;case t.ui.keyCode.SPACE:this.isOpen?this._selectFocusedItem(e):this._toggle(e);break;case t.ui.keyCode.LEFT:this._move("prev",e);break;case t.ui.keyCode.RIGHT:this._move("next",e);break;case t.ui.keyCode.HOME:case t.ui.keyCode.PAGE_UP:this._move("first",e);break;case t.ui.keyCode.END:case t.ui.keyCode.PAGE_DOWN:this._move("last",e);break;default:this.menu.trigger(e),i=!1}i&&e.preventDefault()}},_selectFocusedItem:function(t){var e=this.menuItems.eq(this.focusIndex).parent("li");e.hasClass("ui-state-disabled")||this._select(e.data("ui-selectmenu-item"),t)},_select:function(t,e){var i=this.element[0].selectedIndex;this.element[0].selectedIndex=t.index,this.buttonItem.replaceWith(this.buttonItem=this._renderButtonItem(t)),this._setAria(t),this._trigger("select",e,{item:t}),t.index!==i&&this._trigger("change",e,{item:t}),this.close(e)},_setAria:function(t){var e=this.menuItems.eq(t.index).attr("id");this.button.attr({"aria-labelledby":e,"aria-activedescendant":e}),this.menu.attr("aria-activedescendant",e)},_setOption:function(t,e){if("icons"===t){var i=this.button.find("span.ui-icon");this._removeClass(i,null,this.options.icons.button)._addClass(i,null,e.button)}this._super(t,e),"appendTo"===t&&this.menuWrap.appendTo(this._appendTo()),"width"===t&&this._resizeButton()},_setOptionDisabled:function(t){this._super(t),this.menuInstance.option("disabled",t),this.button.attr("aria-disabled",t),this._toggleClass(this.button,null,"ui-state-disabled",t),this.element.prop("disabled",t),t?(this.button.attr("tabindex",-1),this.close()):this.button.attr("tabindex",0)},_appendTo:function(){var e=this.options.appendTo;return e&&(e=e.jquery||e.nodeType?t(e):this.document.find(e).eq(0)),e&&e[0]||(e=this.element.closest(".ui-front, dialog")),e.length||(e=this.document[0].body),e},_toggleAttr:function(){this.button.attr("aria-expanded",this.isOpen),this._removeClass(this.button,"ui-selectmenu-button-"+(this.isOpen?"closed":"open"))._addClass(this.button,"ui-selectmenu-button-"+(this.isOpen?"open":"closed"))._toggleClass(this.menuWrap,"ui-selectmenu-open",null,this.isOpen),this.menu.attr("aria-hidden",!this.isOpen)},_resizeButton:function(){var t=this.options.width;return t===!1?(this.button.css("width",""),void 0):(null===t&&(t=this.element.show().outerWidth(),this.element.hide()),this.button.outerWidth(t),void 0)},_resizeMenu:function(){this.menu.outerWidth(Math.max(this.button.outerWidth(),this.menu.width("").outerWidth()+1))},_getCreateOptions:function(){var t=this._super();return t.disabled=this.element.prop("disabled"),t},_parseOptions:function(e){var i=this,s=[];e.each(function(e,n){s.push(i._parseOption(t(n),e))}),this.items=s},_parseOption:function(t,e){var i=t.parent("optgroup");return{element:t,index:e,value:t.val(),label:t.text(),optgroup:i.attr("label")||"",disabled:i.prop("disabled")||t.prop("disabled")}},_destroy:function(){this._unbindFormResetHandler(),this.menuWrap.remove(),this.button.remove(),this.element.show(),this.element.removeUniqueId(),this.labels.attr("for",this.ids.element)}}]),t.widget("ui.slider",t.ui.mouse,{version:"1.12.1",widgetEventPrefix:"slide",options:{animate:!1,classes:{"ui-slider":"ui-corner-all","ui-slider-handle":"ui-corner-all","ui-slider-range":"ui-corner-all ui-widget-header"},distance:0,max:100,min:0,orientation:"horizontal",range:!1,step:1,value:0,values:null,change:null,slide:null,start:null,stop:null},numPages:5,_create:function(){this._keySliding=!1,this._mouseSliding=!1,this._animateOff=!0,this._handleIndex=null,this._detectOrientation(),this._mouseInit(),this._calculateNewMax(),this._addClass("ui-slider ui-slider-"+this.orientation,"ui-widget ui-widget-content"),this._refresh(),this._animateOff=!1},_refresh:function(){this._createRange(),this._createHandles(),this._setupEvents(),this._refreshValue()},_createHandles:function(){var e,i,s=this.options,n=this.element.find(".ui-slider-handle"),o="<span tabindex='0'></span>",a=[];for(i=s.values&&s.values.length||1,n.length>i&&(n.slice(i).remove(),n=n.slice(0,i)),e=n.length;i>e;e++)a.push(o);this.handles=n.add(t(a.join("")).appendTo(this.element)),this._addClass(this.handles,"ui-slider-handle","ui-state-default"),this.handle=this.handles.eq(0),this.handles.each(function(e){t(this).data("ui-slider-handle-index",e).attr("tabIndex",0)})},_createRange:function(){var e=this.options;e.range?(e.range===!0&&(e.values?e.values.length&&2!==e.values.length?e.values=[e.values[0],e.values[0]]:t.isArray(e.values)&&(e.values=e.values.slice(0)):e.values=[this._valueMin(),this._valueMin()]),this.range&&this.range.length?(this._removeClass(this.range,"ui-slider-range-min ui-slider-range-max"),this.range.css({left:"",bottom:""})):(this.range=t("<div>").appendTo(this.element),this._addClass(this.range,"ui-slider-range")),("min"===e.range||"max"===e.range)&&this._addClass(this.range,"ui-slider-range-"+e.range)):(this.range&&this.range.remove(),this.range=null)
|
||
},_setupEvents:function(){this._off(this.handles),this._on(this.handles,this._handleEvents),this._hoverable(this.handles),this._focusable(this.handles)},_destroy:function(){this.handles.remove(),this.range&&this.range.remove(),this._mouseDestroy()},_mouseCapture:function(e){var i,s,n,o,a,r,h,l,c=this,u=this.options;return u.disabled?!1:(this.elementSize={width:this.element.outerWidth(),height:this.element.outerHeight()},this.elementOffset=this.element.offset(),i={x:e.pageX,y:e.pageY},s=this._normValueFromMouse(i),n=this._valueMax()-this._valueMin()+1,this.handles.each(function(e){var i=Math.abs(s-c.values(e));(n>i||n===i&&(e===c._lastChangedValue||c.values(e)===u.min))&&(n=i,o=t(this),a=e)}),r=this._start(e,a),r===!1?!1:(this._mouseSliding=!0,this._handleIndex=a,this._addClass(o,null,"ui-state-active"),o.trigger("focus"),h=o.offset(),l=!t(e.target).parents().addBack().is(".ui-slider-handle"),this._clickOffset=l?{left:0,top:0}:{left:e.pageX-h.left-o.width()/2,top:e.pageY-h.top-o.height()/2-(parseInt(o.css("borderTopWidth"),10)||0)-(parseInt(o.css("borderBottomWidth"),10)||0)+(parseInt(o.css("marginTop"),10)||0)},this.handles.hasClass("ui-state-hover")||this._slide(e,a,s),this._animateOff=!0,!0))},_mouseStart:function(){return!0},_mouseDrag:function(t){var e={x:t.pageX,y:t.pageY},i=this._normValueFromMouse(e);return this._slide(t,this._handleIndex,i),!1},_mouseStop:function(t){return this._removeClass(this.handles,null,"ui-state-active"),this._mouseSliding=!1,this._stop(t,this._handleIndex),this._change(t,this._handleIndex),this._handleIndex=null,this._clickOffset=null,this._animateOff=!1,!1},_detectOrientation:function(){this.orientation="vertical"===this.options.orientation?"vertical":"horizontal"},_normValueFromMouse:function(t){var e,i,s,n,o;return"horizontal"===this.orientation?(e=this.elementSize.width,i=t.x-this.elementOffset.left-(this._clickOffset?this._clickOffset.left:0)):(e=this.elementSize.height,i=t.y-this.elementOffset.top-(this._clickOffset?this._clickOffset.top:0)),s=i/e,s>1&&(s=1),0>s&&(s=0),"vertical"===this.orientation&&(s=1-s),n=this._valueMax()-this._valueMin(),o=this._valueMin()+s*n,this._trimAlignValue(o)},_uiHash:function(t,e,i){var s={handle:this.handles[t],handleIndex:t,value:void 0!==e?e:this.value()};return this._hasMultipleValues()&&(s.value=void 0!==e?e:this.values(t),s.values=i||this.values()),s},_hasMultipleValues:function(){return this.options.values&&this.options.values.length},_start:function(t,e){return this._trigger("start",t,this._uiHash(e))},_slide:function(t,e,i){var s,n,o=this.value(),a=this.values();this._hasMultipleValues()&&(n=this.values(e?0:1),o=this.values(e),2===this.options.values.length&&this.options.range===!0&&(i=0===e?Math.min(n,i):Math.max(n,i)),a[e]=i),i!==o&&(s=this._trigger("slide",t,this._uiHash(e,i,a)),s!==!1&&(this._hasMultipleValues()?this.values(e,i):this.value(i)))},_stop:function(t,e){this._trigger("stop",t,this._uiHash(e))},_change:function(t,e){this._keySliding||this._mouseSliding||(this._lastChangedValue=e,this._trigger("change",t,this._uiHash(e)))},value:function(t){return arguments.length?(this.options.value=this._trimAlignValue(t),this._refreshValue(),this._change(null,0),void 0):this._value()},values:function(e,i){var s,n,o;if(arguments.length>1)return this.options.values[e]=this._trimAlignValue(i),this._refreshValue(),this._change(null,e),void 0;if(!arguments.length)return this._values();if(!t.isArray(arguments[0]))return this._hasMultipleValues()?this._values(e):this.value();for(s=this.options.values,n=arguments[0],o=0;s.length>o;o+=1)s[o]=this._trimAlignValue(n[o]),this._change(null,o);this._refreshValue()},_setOption:function(e,i){var s,n=0;switch("range"===e&&this.options.range===!0&&("min"===i?(this.options.value=this._values(0),this.options.values=null):"max"===i&&(this.options.value=this._values(this.options.values.length-1),this.options.values=null)),t.isArray(this.options.values)&&(n=this.options.values.length),this._super(e,i),e){case"orientation":this._detectOrientation(),this._removeClass("ui-slider-horizontal ui-slider-vertical")._addClass("ui-slider-"+this.orientation),this._refreshValue(),this.options.range&&this._refreshRange(i),this.handles.css("horizontal"===i?"bottom":"left","");break;case"value":this._animateOff=!0,this._refreshValue(),this._change(null,0),this._animateOff=!1;break;case"values":for(this._animateOff=!0,this._refreshValue(),s=n-1;s>=0;s--)this._change(null,s);this._animateOff=!1;break;case"step":case"min":case"max":this._animateOff=!0,this._calculateNewMax(),this._refreshValue(),this._animateOff=!1;break;case"range":this._animateOff=!0,this._refresh(),this._animateOff=!1}},_setOptionDisabled:function(t){this._super(t),this._toggleClass(null,"ui-state-disabled",!!t)},_value:function(){var t=this.options.value;return t=this._trimAlignValue(t)},_values:function(t){var e,i,s;if(arguments.length)return e=this.options.values[t],e=this._trimAlignValue(e);if(this._hasMultipleValues()){for(i=this.options.values.slice(),s=0;i.length>s;s+=1)i[s]=this._trimAlignValue(i[s]);return i}return[]},_trimAlignValue:function(t){if(this._valueMin()>=t)return this._valueMin();if(t>=this._valueMax())return this._valueMax();var e=this.options.step>0?this.options.step:1,i=(t-this._valueMin())%e,s=t-i;return 2*Math.abs(i)>=e&&(s+=i>0?e:-e),parseFloat(s.toFixed(5))},_calculateNewMax:function(){var t=this.options.max,e=this._valueMin(),i=this.options.step,s=Math.round((t-e)/i)*i;t=s+e,t>this.options.max&&(t-=i),this.max=parseFloat(t.toFixed(this._precision()))},_precision:function(){var t=this._precisionOf(this.options.step);return null!==this.options.min&&(t=Math.max(t,this._precisionOf(this.options.min))),t},_precisionOf:function(t){var e=""+t,i=e.indexOf(".");return-1===i?0:e.length-i-1},_valueMin:function(){return this.options.min},_valueMax:function(){return this.max},_refreshRange:function(t){"vertical"===t&&this.range.css({width:"",left:""}),"horizontal"===t&&this.range.css({height:"",bottom:""})},_refreshValue:function(){var e,i,s,n,o,a=this.options.range,r=this.options,h=this,l=this._animateOff?!1:r.animate,c={};this._hasMultipleValues()?this.handles.each(function(s){i=100*((h.values(s)-h._valueMin())/(h._valueMax()-h._valueMin())),c["horizontal"===h.orientation?"left":"bottom"]=i+"%",t(this).stop(1,1)[l?"animate":"css"](c,r.animate),h.options.range===!0&&("horizontal"===h.orientation?(0===s&&h.range.stop(1,1)[l?"animate":"css"]({left:i+"%"},r.animate),1===s&&h.range[l?"animate":"css"]({width:i-e+"%"},{queue:!1,duration:r.animate})):(0===s&&h.range.stop(1,1)[l?"animate":"css"]({bottom:i+"%"},r.animate),1===s&&h.range[l?"animate":"css"]({height:i-e+"%"},{queue:!1,duration:r.animate}))),e=i}):(s=this.value(),n=this._valueMin(),o=this._valueMax(),i=o!==n?100*((s-n)/(o-n)):0,c["horizontal"===this.orientation?"left":"bottom"]=i+"%",this.handle.stop(1,1)[l?"animate":"css"](c,r.animate),"min"===a&&"horizontal"===this.orientation&&this.range.stop(1,1)[l?"animate":"css"]({width:i+"%"},r.animate),"max"===a&&"horizontal"===this.orientation&&this.range.stop(1,1)[l?"animate":"css"]({width:100-i+"%"},r.animate),"min"===a&&"vertical"===this.orientation&&this.range.stop(1,1)[l?"animate":"css"]({height:i+"%"},r.animate),"max"===a&&"vertical"===this.orientation&&this.range.stop(1,1)[l?"animate":"css"]({height:100-i+"%"},r.animate))},_handleEvents:{keydown:function(e){var i,s,n,o,a=t(e.target).data("ui-slider-handle-index");switch(e.keyCode){case t.ui.keyCode.HOME:case t.ui.keyCode.END:case t.ui.keyCode.PAGE_UP:case t.ui.keyCode.PAGE_DOWN:case t.ui.keyCode.UP:case t.ui.keyCode.RIGHT:case t.ui.keyCode.DOWN:case t.ui.keyCode.LEFT:if(e.preventDefault(),!this._keySliding&&(this._keySliding=!0,this._addClass(t(e.target),null,"ui-state-active"),i=this._start(e,a),i===!1))return}switch(o=this.options.step,s=n=this._hasMultipleValues()?this.values(a):this.value(),e.keyCode){case t.ui.keyCode.HOME:n=this._valueMin();break;case t.ui.keyCode.END:n=this._valueMax();break;case t.ui.keyCode.PAGE_UP:n=this._trimAlignValue(s+(this._valueMax()-this._valueMin())/this.numPages);break;case t.ui.keyCode.PAGE_DOWN:n=this._trimAlignValue(s-(this._valueMax()-this._valueMin())/this.numPages);break;case t.ui.keyCode.UP:case t.ui.keyCode.RIGHT:if(s===this._valueMax())return;n=this._trimAlignValue(s+o);break;case t.ui.keyCode.DOWN:case t.ui.keyCode.LEFT:if(s===this._valueMin())return;n=this._trimAlignValue(s-o)}this._slide(e,a,n)},keyup:function(e){var i=t(e.target).data("ui-slider-handle-index");this._keySliding&&(this._keySliding=!1,this._stop(e,i),this._change(e,i),this._removeClass(t(e.target),null,"ui-state-active"))}}}),t.widget("ui.spinner",{version:"1.12.1",defaultElement:"<input>",widgetEventPrefix:"spin",options:{classes:{"ui-spinner":"ui-corner-all","ui-spinner-down":"ui-corner-br","ui-spinner-up":"ui-corner-tr"},culture:null,icons:{down:"ui-icon-triangle-1-s",up:"ui-icon-triangle-1-n"},incremental:!0,max:null,min:null,numberFormat:null,page:10,step:1,change:null,spin:null,start:null,stop:null},_create:function(){this._setOption("max",this.options.max),this._setOption("min",this.options.min),this._setOption("step",this.options.step),""!==this.value()&&this._value(this.element.val(),!0),this._draw(),this._on(this._events),this._refresh(),this._on(this.window,{beforeunload:function(){this.element.removeAttr("autocomplete")}})},_getCreateOptions:function(){var e=this._super(),i=this.element;return t.each(["min","max","step"],function(t,s){var n=i.attr(s);null!=n&&n.length&&(e[s]=n)}),e},_events:{keydown:function(t){this._start(t)&&this._keydown(t)&&t.preventDefault()},keyup:"_stop",focus:function(){this.previous=this.element.val()},blur:function(t){return this.cancelBlur?(delete this.cancelBlur,void 0):(this._stop(),this._refresh(),this.previous!==this.element.val()&&this._trigger("change",t),void 0)},mousewheel:function(t,e){if(e){if(!this.spinning&&!this._start(t))return!1;this._spin((e>0?1:-1)*this.options.step,t),clearTimeout(this.mousewheelTimer),this.mousewheelTimer=this._delay(function(){this.spinning&&this._stop(t)},100),t.preventDefault()}},"mousedown .ui-spinner-button":function(e){function i(){var e=this.element[0]===t.ui.safeActiveElement(this.document[0]);e||(this.element.trigger("focus"),this.previous=s,this._delay(function(){this.previous=s}))}var s;s=this.element[0]===t.ui.safeActiveElement(this.document[0])?this.previous:this.element.val(),e.preventDefault(),i.call(this),this.cancelBlur=!0,this._delay(function(){delete this.cancelBlur,i.call(this)}),this._start(e)!==!1&&this._repeat(null,t(e.currentTarget).hasClass("ui-spinner-up")?1:-1,e)},"mouseup .ui-spinner-button":"_stop","mouseenter .ui-spinner-button":function(e){return t(e.currentTarget).hasClass("ui-state-active")?this._start(e)===!1?!1:(this._repeat(null,t(e.currentTarget).hasClass("ui-spinner-up")?1:-1,e),void 0):void 0},"mouseleave .ui-spinner-button":"_stop"},_enhance:function(){this.uiSpinner=this.element.attr("autocomplete","off").wrap("<span>").parent().append("<a></a><a></a>")},_draw:function(){this._enhance(),this._addClass(this.uiSpinner,"ui-spinner","ui-widget ui-widget-content"),this._addClass("ui-spinner-input"),this.element.attr("role","spinbutton"),this.buttons=this.uiSpinner.children("a").attr("tabIndex",-1).attr("aria-hidden",!0).button({classes:{"ui-button":""}}),this._removeClass(this.buttons,"ui-corner-all"),this._addClass(this.buttons.first(),"ui-spinner-button ui-spinner-up"),this._addClass(this.buttons.last(),"ui-spinner-button ui-spinner-down"),this.buttons.first().button({icon:this.options.icons.up,showLabel:!1}),this.buttons.last().button({icon:this.options.icons.down,showLabel:!1}),this.buttons.height()>Math.ceil(.5*this.uiSpinner.height())&&this.uiSpinner.height()>0&&this.uiSpinner.height(this.uiSpinner.height())},_keydown:function(e){var i=this.options,s=t.ui.keyCode;switch(e.keyCode){case s.UP:return this._repeat(null,1,e),!0;case s.DOWN:return this._repeat(null,-1,e),!0;case s.PAGE_UP:return this._repeat(null,i.page,e),!0;case s.PAGE_DOWN:return this._repeat(null,-i.page,e),!0}return!1},_start:function(t){return this.spinning||this._trigger("start",t)!==!1?(this.counter||(this.counter=1),this.spinning=!0,!0):!1},_repeat:function(t,e,i){t=t||500,clearTimeout(this.timer),this.timer=this._delay(function(){this._repeat(40,e,i)},t),this._spin(e*this.options.step,i)},_spin:function(t,e){var i=this.value()||0;this.counter||(this.counter=1),i=this._adjustValue(i+t*this._increment(this.counter)),this.spinning&&this._trigger("spin",e,{value:i})===!1||(this._value(i),this.counter++)},_increment:function(e){var i=this.options.incremental;return i?t.isFunction(i)?i(e):Math.floor(e*e*e/5e4-e*e/500+17*e/200+1):1},_precision:function(){var t=this._precisionOf(this.options.step);return null!==this.options.min&&(t=Math.max(t,this._precisionOf(this.options.min))),t},_precisionOf:function(t){var e=""+t,i=e.indexOf(".");return-1===i?0:e.length-i-1},_adjustValue:function(t){var e,i,s=this.options;return e=null!==s.min?s.min:0,i=t-e,i=Math.round(i/s.step)*s.step,t=e+i,t=parseFloat(t.toFixed(this._precision())),null!==s.max&&t>s.max?s.max:null!==s.min&&s.min>t?s.min:t},_stop:function(t){this.spinning&&(clearTimeout(this.timer),clearTimeout(this.mousewheelTimer),this.counter=0,this.spinning=!1,this._trigger("stop",t))},_setOption:function(t,e){var i,s,n;return"culture"===t||"numberFormat"===t?(i=this._parse(this.element.val()),this.options[t]=e,this.element.val(this._format(i)),void 0):(("max"===t||"min"===t||"step"===t)&&"string"==typeof e&&(e=this._parse(e)),"icons"===t&&(s=this.buttons.first().find(".ui-icon"),this._removeClass(s,null,this.options.icons.up),this._addClass(s,null,e.up),n=this.buttons.last().find(".ui-icon"),this._removeClass(n,null,this.options.icons.down),this._addClass(n,null,e.down)),this._super(t,e),void 0)},_setOptionDisabled:function(t){this._super(t),this._toggleClass(this.uiSpinner,null,"ui-state-disabled",!!t),this.element.prop("disabled",!!t),this.buttons.button(t?"disable":"enable")},_setOptions:r(function(t){this._super(t)}),_parse:function(t){return"string"==typeof t&&""!==t&&(t=window.Globalize&&this.options.numberFormat?Globalize.parseFloat(t,10,this.options.culture):+t),""===t||isNaN(t)?null:t},_format:function(t){return""===t?"":window.Globalize&&this.options.numberFormat?Globalize.format(t,this.options.numberFormat,this.options.culture):t},_refresh:function(){this.element.attr({"aria-valuemin":this.options.min,"aria-valuemax":this.options.max,"aria-valuenow":this._parse(this.element.val())})},isValid:function(){var t=this.value();return null===t?!1:t===this._adjustValue(t)},_value:function(t,e){var i;""!==t&&(i=this._parse(t),null!==i&&(e||(i=this._adjustValue(i)),t=this._format(i))),this.element.val(t),this._refresh()},_destroy:function(){this.element.prop("disabled",!1).removeAttr("autocomplete role aria-valuemin aria-valuemax aria-valuenow"),this.uiSpinner.replaceWith(this.element)},stepUp:r(function(t){this._stepUp(t)}),_stepUp:function(t){this._start()&&(this._spin((t||1)*this.options.step),this._stop())},stepDown:r(function(t){this._stepDown(t)}),_stepDown:function(t){this._start()&&(this._spin((t||1)*-this.options.step),this._stop())},pageUp:r(function(t){this._stepUp((t||1)*this.options.page)}),pageDown:r(function(t){this._stepDown((t||1)*this.options.page)}),value:function(t){return arguments.length?(r(this._value).call(this,t),void 0):this._parse(this.element.val())},widget:function(){return this.uiSpinner}}),t.uiBackCompat!==!1&&t.widget("ui.spinner",t.ui.spinner,{_enhance:function(){this.uiSpinner=this.element.attr("autocomplete","off").wrap(this._uiSpinnerHtml()).parent().append(this._buttonHtml())},_uiSpinnerHtml:function(){return"<span>"},_buttonHtml:function(){return"<a></a><a></a>"}}),t.ui.spinner,t.widget("ui.tabs",{version:"1.12.1",delay:300,options:{active:null,classes:{"ui-tabs":"ui-corner-all","ui-tabs-nav":"ui-corner-all","ui-tabs-panel":"ui-corner-bottom","ui-tabs-tab":"ui-corner-top"},collapsible:!1,event:"click",heightStyle:"content",hide:null,show:null,activate:null,beforeActivate:null,beforeLoad:null,load:null},_isLocal:function(){var t=/#.*$/;return function(e){var i,s;i=e.href.replace(t,""),s=location.href.replace(t,"");try{i=decodeURIComponent(i)}catch(n){}try{s=decodeURIComponent(s)}catch(n){}return e.hash.length>1&&i===s}}(),_create:function(){var e=this,i=this.options;this.running=!1,this._addClass("ui-tabs","ui-widget ui-widget-content"),this._toggleClass("ui-tabs-collapsible",null,i.collapsible),this._processTabs(),i.active=this._initialActive(),t.isArray(i.disabled)&&(i.disabled=t.unique(i.disabled.concat(t.map(this.tabs.filter(".ui-state-disabled"),function(t){return e.tabs.index(t)}))).sort()),this.active=this.options.active!==!1&&this.anchors.length?this._findActive(i.active):t(),this._refresh(),this.active.length&&this.load(i.active)},_initialActive:function(){var e=this.options.active,i=this.options.collapsible,s=location.hash.substring(1);return null===e&&(s&&this.tabs.each(function(i,n){return t(n).attr("aria-controls")===s?(e=i,!1):void 0}),null===e&&(e=this.tabs.index(this.tabs.filter(".ui-tabs-active"))),(null===e||-1===e)&&(e=this.tabs.length?0:!1)),e!==!1&&(e=this.tabs.index(this.tabs.eq(e)),-1===e&&(e=i?!1:0)),!i&&e===!1&&this.anchors.length&&(e=0),e},_getCreateEventData:function(){return{tab:this.active,panel:this.active.length?this._getPanelForTab(this.active):t()}},_tabKeydown:function(e){var i=t(t.ui.safeActiveElement(this.document[0])).closest("li"),s=this.tabs.index(i),n=!0;if(!this._handlePageNav(e)){switch(e.keyCode){case t.ui.keyCode.RIGHT:case t.ui.keyCode.DOWN:s++;break;case t.ui.keyCode.UP:case t.ui.keyCode.LEFT:n=!1,s--;break;case t.ui.keyCode.END:s=this.anchors.length-1;break;case t.ui.keyCode.HOME:s=0;break;case t.ui.keyCode.SPACE:return e.preventDefault(),clearTimeout(this.activating),this._activate(s),void 0;case t.ui.keyCode.ENTER:return e.preventDefault(),clearTimeout(this.activating),this._activate(s===this.options.active?!1:s),void 0;default:return}e.preventDefault(),clearTimeout(this.activating),s=this._focusNextTab(s,n),e.ctrlKey||e.metaKey||(i.attr("aria-selected","false"),this.tabs.eq(s).attr("aria-selected","true"),this.activating=this._delay(function(){this.option("active",s)},this.delay))}},_panelKeydown:function(e){this._handlePageNav(e)||e.ctrlKey&&e.keyCode===t.ui.keyCode.UP&&(e.preventDefault(),this.active.trigger("focus"))},_handlePageNav:function(e){return e.altKey&&e.keyCode===t.ui.keyCode.PAGE_UP?(this._activate(this._focusNextTab(this.options.active-1,!1)),!0):e.altKey&&e.keyCode===t.ui.keyCode.PAGE_DOWN?(this._activate(this._focusNextTab(this.options.active+1,!0)),!0):void 0},_findNextTab:function(e,i){function s(){return e>n&&(e=0),0>e&&(e=n),e}for(var n=this.tabs.length-1;-1!==t.inArray(s(),this.options.disabled);)e=i?e+1:e-1;return e},_focusNextTab:function(t,e){return t=this._findNextTab(t,e),this.tabs.eq(t).trigger("focus"),t},_setOption:function(t,e){return"active"===t?(this._activate(e),void 0):(this._super(t,e),"collapsible"===t&&(this._toggleClass("ui-tabs-collapsible",null,e),e||this.options.active!==!1||this._activate(0)),"event"===t&&this._setupEvents(e),"heightStyle"===t&&this._setupHeightStyle(e),void 0)},_sanitizeSelector:function(t){return t?t.replace(/[!"$%&'()*+,.\/:;<=>?@\[\]\^`{|}~]/g,"\\$&"):""},refresh:function(){var e=this.options,i=this.tablist.children(":has(a[href])");e.disabled=t.map(i.filter(".ui-state-disabled"),function(t){return i.index(t)}),this._processTabs(),e.active!==!1&&this.anchors.length?this.active.length&&!t.contains(this.tablist[0],this.active[0])?this.tabs.length===e.disabled.length?(e.active=!1,this.active=t()):this._activate(this._findNextTab(Math.max(0,e.active-1),!1)):e.active=this.tabs.index(this.active):(e.active=!1,this.active=t()),this._refresh()},_refresh:function(){this._setOptionDisabled(this.options.disabled),this._setupEvents(this.options.event),this._setupHeightStyle(this.options.heightStyle),this.tabs.not(this.active).attr({"aria-selected":"false","aria-expanded":"false",tabIndex:-1}),this.panels.not(this._getPanelForTab(this.active)).hide().attr({"aria-hidden":"true"}),this.active.length?(this.active.attr({"aria-selected":"true","aria-expanded":"true",tabIndex:0}),this._addClass(this.active,"ui-tabs-active","ui-state-active"),this._getPanelForTab(this.active).show().attr({"aria-hidden":"false"})):this.tabs.eq(0).attr("tabIndex",0)},_processTabs:function(){var e=this,i=this.tabs,s=this.anchors,n=this.panels;this.tablist=this._getList().attr("role","tablist"),this._addClass(this.tablist,"ui-tabs-nav","ui-helper-reset ui-helper-clearfix ui-widget-header"),this.tablist.on("mousedown"+this.eventNamespace,"> li",function(e){t(this).is(".ui-state-disabled")&&e.preventDefault()}).on("focus"+this.eventNamespace,".ui-tabs-anchor",function(){t(this).closest("li").is(".ui-state-disabled")&&this.blur()}),this.tabs=this.tablist.find("> li:has(a[href])").attr({role:"tab",tabIndex:-1}),this._addClass(this.tabs,"ui-tabs-tab","ui-state-default"),this.anchors=this.tabs.map(function(){return t("a",this)[0]}).attr({role:"presentation",tabIndex:-1}),this._addClass(this.anchors,"ui-tabs-anchor"),this.panels=t(),this.anchors.each(function(i,s){var n,o,a,r=t(s).uniqueId().attr("id"),h=t(s).closest("li"),l=h.attr("aria-controls");e._isLocal(s)?(n=s.hash,a=n.substring(1),o=e.element.find(e._sanitizeSelector(n))):(a=h.attr("aria-controls")||t({}).uniqueId()[0].id,n="#"+a,o=e.element.find(n),o.length||(o=e._createPanel(a),o.insertAfter(e.panels[i-1]||e.tablist)),o.attr("aria-live","polite")),o.length&&(e.panels=e.panels.add(o)),l&&h.data("ui-tabs-aria-controls",l),h.attr({"aria-controls":a,"aria-labelledby":r}),o.attr("aria-labelledby",r)}),this.panels.attr("role","tabpanel"),this._addClass(this.panels,"ui-tabs-panel","ui-widget-content"),i&&(this._off(i.not(this.tabs)),this._off(s.not(this.anchors)),this._off(n.not(this.panels)))},_getList:function(){return this.tablist||this.element.find("ol, ul").eq(0)},_createPanel:function(e){return t("<div>").attr("id",e).data("ui-tabs-destroy",!0)},_setOptionDisabled:function(e){var i,s,n;for(t.isArray(e)&&(e.length?e.length===this.anchors.length&&(e=!0):e=!1),n=0;s=this.tabs[n];n++)i=t(s),e===!0||-1!==t.inArray(n,e)?(i.attr("aria-disabled","true"),this._addClass(i,null,"ui-state-disabled")):(i.removeAttr("aria-disabled"),this._removeClass(i,null,"ui-state-disabled"));this.options.disabled=e,this._toggleClass(this.widget(),this.widgetFullName+"-disabled",null,e===!0)},_setupEvents:function(e){var i={};e&&t.each(e.split(" "),function(t,e){i[e]="_eventHandler"}),this._off(this.anchors.add(this.tabs).add(this.panels)),this._on(!0,this.anchors,{click:function(t){t.preventDefault()}}),this._on(this.anchors,i),this._on(this.tabs,{keydown:"_tabKeydown"}),this._on(this.panels,{keydown:"_panelKeydown"}),this._focusable(this.tabs),this._hoverable(this.tabs)},_setupHeightStyle:function(e){var i,s=this.element.parent();"fill"===e?(i=s.height(),i-=this.element.outerHeight()-this.element.height(),this.element.siblings(":visible").each(function(){var e=t(this),s=e.css("position");"absolute"!==s&&"fixed"!==s&&(i-=e.outerHeight(!0))}),this.element.children().not(this.panels).each(function(){i-=t(this).outerHeight(!0)}),this.panels.each(function(){t(this).height(Math.max(0,i-t(this).innerHeight()+t(this).height()))}).css("overflow","auto")):"auto"===e&&(i=0,this.panels.each(function(){i=Math.max(i,t(this).height("").height())}).height(i))},_eventHandler:function(e){var i=this.options,s=this.active,n=t(e.currentTarget),o=n.closest("li"),a=o[0]===s[0],r=a&&i.collapsible,h=r?t():this._getPanelForTab(o),l=s.length?this._getPanelForTab(s):t(),c={oldTab:s,oldPanel:l,newTab:r?t():o,newPanel:h};e.preventDefault(),o.hasClass("ui-state-disabled")||o.hasClass("ui-tabs-loading")||this.running||a&&!i.collapsible||this._trigger("beforeActivate",e,c)===!1||(i.active=r?!1:this.tabs.index(o),this.active=a?t():o,this.xhr&&this.xhr.abort(),l.length||h.length||t.error("jQuery UI Tabs: Mismatching fragment identifier."),h.length&&this.load(this.tabs.index(o),e),this._toggle(e,c))},_toggle:function(e,i){function s(){o.running=!1,o._trigger("activate",e,i)}function n(){o._addClass(i.newTab.closest("li"),"ui-tabs-active","ui-state-active"),a.length&&o.options.show?o._show(a,o.options.show,s):(a.show(),s())}var o=this,a=i.newPanel,r=i.oldPanel;this.running=!0,r.length&&this.options.hide?this._hide(r,this.options.hide,function(){o._removeClass(i.oldTab.closest("li"),"ui-tabs-active","ui-state-active"),n()}):(this._removeClass(i.oldTab.closest("li"),"ui-tabs-active","ui-state-active"),r.hide(),n()),r.attr("aria-hidden","true"),i.oldTab.attr({"aria-selected":"false","aria-expanded":"false"}),a.length&&r.length?i.oldTab.attr("tabIndex",-1):a.length&&this.tabs.filter(function(){return 0===t(this).attr("tabIndex")}).attr("tabIndex",-1),a.attr("aria-hidden","false"),i.newTab.attr({"aria-selected":"true","aria-expanded":"true",tabIndex:0})},_activate:function(e){var i,s=this._findActive(e);s[0]!==this.active[0]&&(s.length||(s=this.active),i=s.find(".ui-tabs-anchor")[0],this._eventHandler({target:i,currentTarget:i,preventDefault:t.noop}))},_findActive:function(e){return e===!1?t():this.tabs.eq(e)},_getIndex:function(e){return"string"==typeof e&&(e=this.anchors.index(this.anchors.filter("[href$='"+t.ui.escapeSelector(e)+"']"))),e},_destroy:function(){this.xhr&&this.xhr.abort(),this.tablist.removeAttr("role").off(this.eventNamespace),this.anchors.removeAttr("role tabIndex").removeUniqueId(),this.tabs.add(this.panels).each(function(){t.data(this,"ui-tabs-destroy")?t(this).remove():t(this).removeAttr("role tabIndex aria-live aria-busy aria-selected aria-labelledby aria-hidden aria-expanded")}),this.tabs.each(function(){var e=t(this),i=e.data("ui-tabs-aria-controls");i?e.attr("aria-controls",i).removeData("ui-tabs-aria-controls"):e.removeAttr("aria-controls")}),this.panels.show(),"content"!==this.options.heightStyle&&this.panels.css("height","")},enable:function(e){var i=this.options.disabled;i!==!1&&(void 0===e?i=!1:(e=this._getIndex(e),i=t.isArray(i)?t.map(i,function(t){return t!==e?t:null}):t.map(this.tabs,function(t,i){return i!==e?i:null})),this._setOptionDisabled(i))},disable:function(e){var i=this.options.disabled;if(i!==!0){if(void 0===e)i=!0;else{if(e=this._getIndex(e),-1!==t.inArray(e,i))return;i=t.isArray(i)?t.merge([e],i).sort():[e]}this._setOptionDisabled(i)}},load:function(e,i){e=this._getIndex(e);var s=this,n=this.tabs.eq(e),o=n.find(".ui-tabs-anchor"),a=this._getPanelForTab(n),r={tab:n,panel:a},h=function(t,e){"abort"===e&&s.panels.stop(!1,!0),s._removeClass(n,"ui-tabs-loading"),a.removeAttr("aria-busy"),t===s.xhr&&delete s.xhr};this._isLocal(o[0])||(this.xhr=t.ajax(this._ajaxSettings(o,i,r)),this.xhr&&"canceled"!==this.xhr.statusText&&(this._addClass(n,"ui-tabs-loading"),a.attr("aria-busy","true"),this.xhr.done(function(t,e,n){setTimeout(function(){a.html(t),s._trigger("load",i,r),h(n,e)},1)}).fail(function(t,e){setTimeout(function(){h(t,e)},1)})))},_ajaxSettings:function(e,i,s){var n=this;return{url:e.attr("href").replace(/#.*$/,""),beforeSend:function(e,o){return n._trigger("beforeLoad",i,t.extend({jqXHR:e,ajaxSettings:o},s))}}},_getPanelForTab:function(e){var i=t(e).attr("aria-controls");return this.element.find(this._sanitizeSelector("#"+i))}}),t.uiBackCompat!==!1&&t.widget("ui.tabs",t.ui.tabs,{_processTabs:function(){this._superApply(arguments),this._addClass(this.tabs,"ui-tab")}}),t.ui.tabs,t.widget("ui.tooltip",{version:"1.12.1",options:{classes:{"ui-tooltip":"ui-corner-all ui-widget-shadow"},content:function(){var e=t(this).attr("title")||"";return t("<a>").text(e).html()},hide:!0,items:"[title]:not([disabled])",position:{my:"left top+15",at:"left bottom",collision:"flipfit flip"},show:!0,track:!1,close:null,open:null},_addDescribedBy:function(e,i){var s=(e.attr("aria-describedby")||"").split(/\s+/);s.push(i),e.data("ui-tooltip-id",i).attr("aria-describedby",t.trim(s.join(" ")))},_removeDescribedBy:function(e){var i=e.data("ui-tooltip-id"),s=(e.attr("aria-describedby")||"").split(/\s+/),n=t.inArray(i,s);-1!==n&&s.splice(n,1),e.removeData("ui-tooltip-id"),s=t.trim(s.join(" ")),s?e.attr("aria-describedby",s):e.removeAttr("aria-describedby")},_create:function(){this._on({mouseover:"open",focusin:"open"}),this.tooltips={},this.parents={},this.liveRegion=t("<div>").attr({role:"log","aria-live":"assertive","aria-relevant":"additions"}).appendTo(this.document[0].body),this._addClass(this.liveRegion,null,"ui-helper-hidden-accessible"),this.disabledTitles=t([])},_setOption:function(e,i){var s=this;this._super(e,i),"content"===e&&t.each(this.tooltips,function(t,e){s._updateContent(e.element)})},_setOptionDisabled:function(t){this[t?"_disable":"_enable"]()},_disable:function(){var e=this;t.each(this.tooltips,function(i,s){var n=t.Event("blur");n.target=n.currentTarget=s.element[0],e.close(n,!0)}),this.disabledTitles=this.disabledTitles.add(this.element.find(this.options.items).addBack().filter(function(){var e=t(this);return e.is("[title]")?e.data("ui-tooltip-title",e.attr("title")).removeAttr("title"):void 0}))},_enable:function(){this.disabledTitles.each(function(){var e=t(this);e.data("ui-tooltip-title")&&e.attr("title",e.data("ui-tooltip-title"))}),this.disabledTitles=t([])},open:function(e){var i=this,s=t(e?e.target:this.element).closest(this.options.items);s.length&&!s.data("ui-tooltip-id")&&(s.attr("title")&&s.data("ui-tooltip-title",s.attr("title")),s.data("ui-tooltip-open",!0),e&&"mouseover"===e.type&&s.parents().each(function(){var e,s=t(this);s.data("ui-tooltip-open")&&(e=t.Event("blur"),e.target=e.currentTarget=this,i.close(e,!0)),s.attr("title")&&(s.uniqueId(),i.parents[this.id]={element:this,title:s.attr("title")},s.attr("title",""))}),this._registerCloseHandlers(e,s),this._updateContent(s,e))},_updateContent:function(t,e){var i,s=this.options.content,n=this,o=e?e.type:null;return"string"==typeof s||s.nodeType||s.jquery?this._open(e,t,s):(i=s.call(t[0],function(i){n._delay(function(){t.data("ui-tooltip-open")&&(e&&(e.type=o),this._open(e,t,i))})}),i&&this._open(e,t,i),void 0)},_open:function(e,i,s){function n(t){l.of=t,a.is(":hidden")||a.position(l)}var o,a,r,h,l=t.extend({},this.options.position);if(s){if(o=this._find(i))return o.tooltip.find(".ui-tooltip-content").html(s),void 0;i.is("[title]")&&(e&&"mouseover"===e.type?i.attr("title",""):i.removeAttr("title")),o=this._tooltip(i),a=o.tooltip,this._addDescribedBy(i,a.attr("id")),a.find(".ui-tooltip-content").html(s),this.liveRegion.children().hide(),h=t("<div>").html(a.find(".ui-tooltip-content").html()),h.removeAttr("name").find("[name]").removeAttr("name"),h.removeAttr("id").find("[id]").removeAttr("id"),h.appendTo(this.liveRegion),this.options.track&&e&&/^mouse/.test(e.type)?(this._on(this.document,{mousemove:n}),n(e)):a.position(t.extend({of:i},this.options.position)),a.hide(),this._show(a,this.options.show),this.options.track&&this.options.show&&this.options.show.delay&&(r=this.delayedShow=setInterval(function(){a.is(":visible")&&(n(l.of),clearInterval(r))},t.fx.interval)),this._trigger("open",e,{tooltip:a})}},_registerCloseHandlers:function(e,i){var s={keyup:function(e){if(e.keyCode===t.ui.keyCode.ESCAPE){var s=t.Event(e);s.currentTarget=i[0],this.close(s,!0)}}};i[0]!==this.element[0]&&(s.remove=function(){this._removeTooltip(this._find(i).tooltip)}),e&&"mouseover"!==e.type||(s.mouseleave="close"),e&&"focusin"!==e.type||(s.focusout="close"),this._on(!0,i,s)},close:function(e){var i,s=this,n=t(e?e.currentTarget:this.element),o=this._find(n);return o?(i=o.tooltip,o.closing||(clearInterval(this.delayedShow),n.data("ui-tooltip-title")&&!n.attr("title")&&n.attr("title",n.data("ui-tooltip-title")),this._removeDescribedBy(n),o.hiding=!0,i.stop(!0),this._hide(i,this.options.hide,function(){s._removeTooltip(t(this))}),n.removeData("ui-tooltip-open"),this._off(n,"mouseleave focusout keyup"),n[0]!==this.element[0]&&this._off(n,"remove"),this._off(this.document,"mousemove"),e&&"mouseleave"===e.type&&t.each(this.parents,function(e,i){t(i.element).attr("title",i.title),delete s.parents[e]
|
||
}),o.closing=!0,this._trigger("close",e,{tooltip:i}),o.hiding||(o.closing=!1)),void 0):(n.removeData("ui-tooltip-open"),void 0)},_tooltip:function(e){var i=t("<div>").attr("role","tooltip"),s=t("<div>").appendTo(i),n=i.uniqueId().attr("id");return this._addClass(s,"ui-tooltip-content"),this._addClass(i,"ui-tooltip","ui-widget ui-widget-content"),i.appendTo(this._appendTo(e)),this.tooltips[n]={element:e,tooltip:i}},_find:function(t){var e=t.data("ui-tooltip-id");return e?this.tooltips[e]:null},_removeTooltip:function(t){t.remove(),delete this.tooltips[t.attr("id")]},_appendTo:function(t){var e=t.closest(".ui-front, dialog");return e.length||(e=this.document[0].body),e},_destroy:function(){var e=this;t.each(this.tooltips,function(i,s){var n=t.Event("blur"),o=s.element;n.target=n.currentTarget=o[0],e.close(n,!0),t("#"+i).remove(),o.data("ui-tooltip-title")&&(o.attr("title")||o.attr("title",o.data("ui-tooltip-title")),o.removeData("ui-tooltip-title"))}),this.liveRegion.remove()}}),t.uiBackCompat!==!1&&t.widget("ui.tooltip",t.ui.tooltip,{options:{tooltipClass:null},_tooltip:function(){var t=this._superApply(arguments);return this.options.tooltipClass&&t.tooltip.addClass(this.options.tooltipClass),t}}),t.ui.tooltip;var f="ui-effects-",g="ui-effects-style",m="ui-effects-animated",_=t;t.effects={effect:{}},function(t,e){function i(t,e,i){var s=u[e.type]||{};return null==t?i||!e.def?null:e.def:(t=s.floor?~~t:parseFloat(t),isNaN(t)?e.def:s.mod?(t+s.mod)%s.mod:0>t?0:t>s.max?s.max:t)}function s(i){var s=l(),n=s._rgba=[];return i=i.toLowerCase(),f(h,function(t,o){var a,r=o.re.exec(i),h=r&&o.parse(r),l=o.space||"rgba";return h?(a=s[l](h),s[c[l].cache]=a[c[l].cache],n=s._rgba=a._rgba,!1):e}),n.length?("0,0,0,0"===n.join()&&t.extend(n,o.transparent),s):o[i]}function n(t,e,i){return i=(i+1)%1,1>6*i?t+6*(e-t)*i:1>2*i?e:2>3*i?t+6*(e-t)*(2/3-i):t}var o,a="backgroundColor borderBottomColor borderLeftColor borderRightColor borderTopColor color columnRuleColor outlineColor textDecorationColor textEmphasisColor",r=/^([\-+])=\s*(\d+\.?\d*)/,h=[{re:/rgba?\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,parse:function(t){return[t[1],t[2],t[3],t[4]]}},{re:/rgba?\(\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,parse:function(t){return[2.55*t[1],2.55*t[2],2.55*t[3],t[4]]}},{re:/#([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})/,parse:function(t){return[parseInt(t[1],16),parseInt(t[2],16),parseInt(t[3],16)]}},{re:/#([a-f0-9])([a-f0-9])([a-f0-9])/,parse:function(t){return[parseInt(t[1]+t[1],16),parseInt(t[2]+t[2],16),parseInt(t[3]+t[3],16)]}},{re:/hsla?\(\s*(\d+(?:\.\d+)?)\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,space:"hsla",parse:function(t){return[t[1],t[2]/100,t[3]/100,t[4]]}}],l=t.Color=function(e,i,s,n){return new t.Color.fn.parse(e,i,s,n)},c={rgba:{props:{red:{idx:0,type:"byte"},green:{idx:1,type:"byte"},blue:{idx:2,type:"byte"}}},hsla:{props:{hue:{idx:0,type:"degrees"},saturation:{idx:1,type:"percent"},lightness:{idx:2,type:"percent"}}}},u={"byte":{floor:!0,max:255},percent:{max:1},degrees:{mod:360,floor:!0}},d=l.support={},p=t("<p>")[0],f=t.each;p.style.cssText="background-color:rgba(1,1,1,.5)",d.rgba=p.style.backgroundColor.indexOf("rgba")>-1,f(c,function(t,e){e.cache="_"+t,e.props.alpha={idx:3,type:"percent",def:1}}),l.fn=t.extend(l.prototype,{parse:function(n,a,r,h){if(n===e)return this._rgba=[null,null,null,null],this;(n.jquery||n.nodeType)&&(n=t(n).css(a),a=e);var u=this,d=t.type(n),p=this._rgba=[];return a!==e&&(n=[n,a,r,h],d="array"),"string"===d?this.parse(s(n)||o._default):"array"===d?(f(c.rgba.props,function(t,e){p[e.idx]=i(n[e.idx],e)}),this):"object"===d?(n instanceof l?f(c,function(t,e){n[e.cache]&&(u[e.cache]=n[e.cache].slice())}):f(c,function(e,s){var o=s.cache;f(s.props,function(t,e){if(!u[o]&&s.to){if("alpha"===t||null==n[t])return;u[o]=s.to(u._rgba)}u[o][e.idx]=i(n[t],e,!0)}),u[o]&&0>t.inArray(null,u[o].slice(0,3))&&(u[o][3]=1,s.from&&(u._rgba=s.from(u[o])))}),this):e},is:function(t){var i=l(t),s=!0,n=this;return f(c,function(t,o){var a,r=i[o.cache];return r&&(a=n[o.cache]||o.to&&o.to(n._rgba)||[],f(o.props,function(t,i){return null!=r[i.idx]?s=r[i.idx]===a[i.idx]:e})),s}),s},_space:function(){var t=[],e=this;return f(c,function(i,s){e[s.cache]&&t.push(i)}),t.pop()},transition:function(t,e){var s=l(t),n=s._space(),o=c[n],a=0===this.alpha()?l("transparent"):this,r=a[o.cache]||o.to(a._rgba),h=r.slice();return s=s[o.cache],f(o.props,function(t,n){var o=n.idx,a=r[o],l=s[o],c=u[n.type]||{};null!==l&&(null===a?h[o]=l:(c.mod&&(l-a>c.mod/2?a+=c.mod:a-l>c.mod/2&&(a-=c.mod)),h[o]=i((l-a)*e+a,n)))}),this[n](h)},blend:function(e){if(1===this._rgba[3])return this;var i=this._rgba.slice(),s=i.pop(),n=l(e)._rgba;return l(t.map(i,function(t,e){return(1-s)*n[e]+s*t}))},toRgbaString:function(){var e="rgba(",i=t.map(this._rgba,function(t,e){return null==t?e>2?1:0:t});return 1===i[3]&&(i.pop(),e="rgb("),e+i.join()+")"},toHslaString:function(){var e="hsla(",i=t.map(this.hsla(),function(t,e){return null==t&&(t=e>2?1:0),e&&3>e&&(t=Math.round(100*t)+"%"),t});return 1===i[3]&&(i.pop(),e="hsl("),e+i.join()+")"},toHexString:function(e){var i=this._rgba.slice(),s=i.pop();return e&&i.push(~~(255*s)),"#"+t.map(i,function(t){return t=(t||0).toString(16),1===t.length?"0"+t:t}).join("")},toString:function(){return 0===this._rgba[3]?"transparent":this.toRgbaString()}}),l.fn.parse.prototype=l.fn,c.hsla.to=function(t){if(null==t[0]||null==t[1]||null==t[2])return[null,null,null,t[3]];var e,i,s=t[0]/255,n=t[1]/255,o=t[2]/255,a=t[3],r=Math.max(s,n,o),h=Math.min(s,n,o),l=r-h,c=r+h,u=.5*c;return e=h===r?0:s===r?60*(n-o)/l+360:n===r?60*(o-s)/l+120:60*(s-n)/l+240,i=0===l?0:.5>=u?l/c:l/(2-c),[Math.round(e)%360,i,u,null==a?1:a]},c.hsla.from=function(t){if(null==t[0]||null==t[1]||null==t[2])return[null,null,null,t[3]];var e=t[0]/360,i=t[1],s=t[2],o=t[3],a=.5>=s?s*(1+i):s+i-s*i,r=2*s-a;return[Math.round(255*n(r,a,e+1/3)),Math.round(255*n(r,a,e)),Math.round(255*n(r,a,e-1/3)),o]},f(c,function(s,n){var o=n.props,a=n.cache,h=n.to,c=n.from;l.fn[s]=function(s){if(h&&!this[a]&&(this[a]=h(this._rgba)),s===e)return this[a].slice();var n,r=t.type(s),u="array"===r||"object"===r?s:arguments,d=this[a].slice();return f(o,function(t,e){var s=u["object"===r?t:e.idx];null==s&&(s=d[e.idx]),d[e.idx]=i(s,e)}),c?(n=l(c(d)),n[a]=d,n):l(d)},f(o,function(e,i){l.fn[e]||(l.fn[e]=function(n){var o,a=t.type(n),h="alpha"===e?this._hsla?"hsla":"rgba":s,l=this[h](),c=l[i.idx];return"undefined"===a?c:("function"===a&&(n=n.call(this,c),a=t.type(n)),null==n&&i.empty?this:("string"===a&&(o=r.exec(n),o&&(n=c+parseFloat(o[2])*("+"===o[1]?1:-1))),l[i.idx]=n,this[h](l)))})})}),l.hook=function(e){var i=e.split(" ");f(i,function(e,i){t.cssHooks[i]={set:function(e,n){var o,a,r="";if("transparent"!==n&&("string"!==t.type(n)||(o=s(n)))){if(n=l(o||n),!d.rgba&&1!==n._rgba[3]){for(a="backgroundColor"===i?e.parentNode:e;(""===r||"transparent"===r)&&a&&a.style;)try{r=t.css(a,"backgroundColor"),a=a.parentNode}catch(h){}n=n.blend(r&&"transparent"!==r?r:"_default")}n=n.toRgbaString()}try{e.style[i]=n}catch(h){}}},t.fx.step[i]=function(e){e.colorInit||(e.start=l(e.elem,i),e.end=l(e.end),e.colorInit=!0),t.cssHooks[i].set(e.elem,e.start.transition(e.end,e.pos))}})},l.hook(a),t.cssHooks.borderColor={expand:function(t){var e={};return f(["Top","Right","Bottom","Left"],function(i,s){e["border"+s+"Color"]=t}),e}},o=t.Color.names={aqua:"#00ffff",black:"#000000",blue:"#0000ff",fuchsia:"#ff00ff",gray:"#808080",green:"#008000",lime:"#00ff00",maroon:"#800000",navy:"#000080",olive:"#808000",purple:"#800080",red:"#ff0000",silver:"#c0c0c0",teal:"#008080",white:"#ffffff",yellow:"#ffff00",transparent:[null,null,null,0],_default:"#ffffff"}}(_),function(){function e(e){var i,s,n=e.ownerDocument.defaultView?e.ownerDocument.defaultView.getComputedStyle(e,null):e.currentStyle,o={};if(n&&n.length&&n[0]&&n[n[0]])for(s=n.length;s--;)i=n[s],"string"==typeof n[i]&&(o[t.camelCase(i)]=n[i]);else for(i in n)"string"==typeof n[i]&&(o[i]=n[i]);return o}function i(e,i){var s,o,a={};for(s in i)o=i[s],e[s]!==o&&(n[s]||(t.fx.step[s]||!isNaN(parseFloat(o)))&&(a[s]=o));return a}var s=["add","remove","toggle"],n={border:1,borderBottom:1,borderColor:1,borderLeft:1,borderRight:1,borderTop:1,borderWidth:1,margin:1,padding:1};t.each(["borderLeftStyle","borderRightStyle","borderBottomStyle","borderTopStyle"],function(e,i){t.fx.step[i]=function(t){("none"!==t.end&&!t.setAttr||1===t.pos&&!t.setAttr)&&(_.style(t.elem,i,t.end),t.setAttr=!0)}}),t.fn.addBack||(t.fn.addBack=function(t){return this.add(null==t?this.prevObject:this.prevObject.filter(t))}),t.effects.animateClass=function(n,o,a,r){var h=t.speed(o,a,r);return this.queue(function(){var o,a=t(this),r=a.attr("class")||"",l=h.children?a.find("*").addBack():a;l=l.map(function(){var i=t(this);return{el:i,start:e(this)}}),o=function(){t.each(s,function(t,e){n[e]&&a[e+"Class"](n[e])})},o(),l=l.map(function(){return this.end=e(this.el[0]),this.diff=i(this.start,this.end),this}),a.attr("class",r),l=l.map(function(){var e=this,i=t.Deferred(),s=t.extend({},h,{queue:!1,complete:function(){i.resolve(e)}});return this.el.animate(this.diff,s),i.promise()}),t.when.apply(t,l.get()).done(function(){o(),t.each(arguments,function(){var e=this.el;t.each(this.diff,function(t){e.css(t,"")})}),h.complete.call(a[0])})})},t.fn.extend({addClass:function(e){return function(i,s,n,o){return s?t.effects.animateClass.call(this,{add:i},s,n,o):e.apply(this,arguments)}}(t.fn.addClass),removeClass:function(e){return function(i,s,n,o){return arguments.length>1?t.effects.animateClass.call(this,{remove:i},s,n,o):e.apply(this,arguments)}}(t.fn.removeClass),toggleClass:function(e){return function(i,s,n,o,a){return"boolean"==typeof s||void 0===s?n?t.effects.animateClass.call(this,s?{add:i}:{remove:i},n,o,a):e.apply(this,arguments):t.effects.animateClass.call(this,{toggle:i},s,n,o)}}(t.fn.toggleClass),switchClass:function(e,i,s,n,o){return t.effects.animateClass.call(this,{add:i,remove:e},s,n,o)}})}(),function(){function e(e,i,s,n){return t.isPlainObject(e)&&(i=e,e=e.effect),e={effect:e},null==i&&(i={}),t.isFunction(i)&&(n=i,s=null,i={}),("number"==typeof i||t.fx.speeds[i])&&(n=s,s=i,i={}),t.isFunction(s)&&(n=s,s=null),i&&t.extend(e,i),s=s||i.duration,e.duration=t.fx.off?0:"number"==typeof s?s:s in t.fx.speeds?t.fx.speeds[s]:t.fx.speeds._default,e.complete=n||i.complete,e}function i(e){return!e||"number"==typeof e||t.fx.speeds[e]?!0:"string"!=typeof e||t.effects.effect[e]?t.isFunction(e)?!0:"object"!=typeof e||e.effect?!1:!0:!0}function s(t,e){var i=e.outerWidth(),s=e.outerHeight(),n=/^rect\((-?\d*\.?\d*px|-?\d+%|auto),?\s*(-?\d*\.?\d*px|-?\d+%|auto),?\s*(-?\d*\.?\d*px|-?\d+%|auto),?\s*(-?\d*\.?\d*px|-?\d+%|auto)\)$/,o=n.exec(t)||["",0,i,s,0];return{top:parseFloat(o[1])||0,right:"auto"===o[2]?i:parseFloat(o[2]),bottom:"auto"===o[3]?s:parseFloat(o[3]),left:parseFloat(o[4])||0}}t.expr&&t.expr.filters&&t.expr.filters.animated&&(t.expr.filters.animated=function(e){return function(i){return!!t(i).data(m)||e(i)}}(t.expr.filters.animated)),t.uiBackCompat!==!1&&t.extend(t.effects,{save:function(t,e){for(var i=0,s=e.length;s>i;i++)null!==e[i]&&t.data(f+e[i],t[0].style[e[i]])},restore:function(t,e){for(var i,s=0,n=e.length;n>s;s++)null!==e[s]&&(i=t.data(f+e[s]),t.css(e[s],i))},setMode:function(t,e){return"toggle"===e&&(e=t.is(":hidden")?"show":"hide"),e},createWrapper:function(e){if(e.parent().is(".ui-effects-wrapper"))return e.parent();var i={width:e.outerWidth(!0),height:e.outerHeight(!0),"float":e.css("float")},s=t("<div></div>").addClass("ui-effects-wrapper").css({fontSize:"100%",background:"transparent",border:"none",margin:0,padding:0}),n={width:e.width(),height:e.height()},o=document.activeElement;try{o.id}catch(a){o=document.body}return e.wrap(s),(e[0]===o||t.contains(e[0],o))&&t(o).trigger("focus"),s=e.parent(),"static"===e.css("position")?(s.css({position:"relative"}),e.css({position:"relative"})):(t.extend(i,{position:e.css("position"),zIndex:e.css("z-index")}),t.each(["top","left","bottom","right"],function(t,s){i[s]=e.css(s),isNaN(parseInt(i[s],10))&&(i[s]="auto")}),e.css({position:"relative",top:0,left:0,right:"auto",bottom:"auto"})),e.css(n),s.css(i).show()},removeWrapper:function(e){var i=document.activeElement;return e.parent().is(".ui-effects-wrapper")&&(e.parent().replaceWith(e),(e[0]===i||t.contains(e[0],i))&&t(i).trigger("focus")),e}}),t.extend(t.effects,{version:"1.12.1",define:function(e,i,s){return s||(s=i,i="effect"),t.effects.effect[e]=s,t.effects.effect[e].mode=i,s},scaledDimensions:function(t,e,i){if(0===e)return{height:0,width:0,outerHeight:0,outerWidth:0};var s="horizontal"!==i?(e||100)/100:1,n="vertical"!==i?(e||100)/100:1;return{height:t.height()*n,width:t.width()*s,outerHeight:t.outerHeight()*n,outerWidth:t.outerWidth()*s}},clipToBox:function(t){return{width:t.clip.right-t.clip.left,height:t.clip.bottom-t.clip.top,left:t.clip.left,top:t.clip.top}},unshift:function(t,e,i){var s=t.queue();e>1&&s.splice.apply(s,[1,0].concat(s.splice(e,i))),t.dequeue()},saveStyle:function(t){t.data(g,t[0].style.cssText)},restoreStyle:function(t){t[0].style.cssText=t.data(g)||"",t.removeData(g)},mode:function(t,e){var i=t.is(":hidden");return"toggle"===e&&(e=i?"show":"hide"),(i?"hide"===e:"show"===e)&&(e="none"),e},getBaseline:function(t,e){var i,s;switch(t[0]){case"top":i=0;break;case"middle":i=.5;break;case"bottom":i=1;break;default:i=t[0]/e.height}switch(t[1]){case"left":s=0;break;case"center":s=.5;break;case"right":s=1;break;default:s=t[1]/e.width}return{x:s,y:i}},createPlaceholder:function(e){var i,s=e.css("position"),n=e.position();return e.css({marginTop:e.css("marginTop"),marginBottom:e.css("marginBottom"),marginLeft:e.css("marginLeft"),marginRight:e.css("marginRight")}).outerWidth(e.outerWidth()).outerHeight(e.outerHeight()),/^(static|relative)/.test(s)&&(s="absolute",i=t("<"+e[0].nodeName+">").insertAfter(e).css({display:/^(inline|ruby)/.test(e.css("display"))?"inline-block":"block",visibility:"hidden",marginTop:e.css("marginTop"),marginBottom:e.css("marginBottom"),marginLeft:e.css("marginLeft"),marginRight:e.css("marginRight"),"float":e.css("float")}).outerWidth(e.outerWidth()).outerHeight(e.outerHeight()).addClass("ui-effects-placeholder"),e.data(f+"placeholder",i)),e.css({position:s,left:n.left,top:n.top}),i},removePlaceholder:function(t){var e=f+"placeholder",i=t.data(e);i&&(i.remove(),t.removeData(e))},cleanUp:function(e){t.effects.restoreStyle(e),t.effects.removePlaceholder(e)},setTransition:function(e,i,s,n){return n=n||{},t.each(i,function(t,i){var o=e.cssUnit(i);o[0]>0&&(n[i]=o[0]*s+o[1])}),n}}),t.fn.extend({effect:function(){function i(e){function i(){r.removeData(m),t.effects.cleanUp(r),"hide"===s.mode&&r.hide(),a()}function a(){t.isFunction(h)&&h.call(r[0]),t.isFunction(e)&&e()}var r=t(this);s.mode=c.shift(),t.uiBackCompat===!1||o?"none"===s.mode?(r[l](),a()):n.call(r[0],s,i):(r.is(":hidden")?"hide"===l:"show"===l)?(r[l](),a()):n.call(r[0],s,a)}var s=e.apply(this,arguments),n=t.effects.effect[s.effect],o=n.mode,a=s.queue,r=a||"fx",h=s.complete,l=s.mode,c=[],u=function(e){var i=t(this),s=t.effects.mode(i,l)||o;i.data(m,!0),c.push(s),o&&("show"===s||s===o&&"hide"===s)&&i.show(),o&&"none"===s||t.effects.saveStyle(i),t.isFunction(e)&&e()};return t.fx.off||!n?l?this[l](s.duration,h):this.each(function(){h&&h.call(this)}):a===!1?this.each(u).each(i):this.queue(r,u).queue(r,i)},show:function(t){return function(s){if(i(s))return t.apply(this,arguments);var n=e.apply(this,arguments);return n.mode="show",this.effect.call(this,n)}}(t.fn.show),hide:function(t){return function(s){if(i(s))return t.apply(this,arguments);var n=e.apply(this,arguments);return n.mode="hide",this.effect.call(this,n)}}(t.fn.hide),toggle:function(t){return function(s){if(i(s)||"boolean"==typeof s)return t.apply(this,arguments);var n=e.apply(this,arguments);return n.mode="toggle",this.effect.call(this,n)}}(t.fn.toggle),cssUnit:function(e){var i=this.css(e),s=[];return t.each(["em","px","%","pt"],function(t,e){i.indexOf(e)>0&&(s=[parseFloat(i),e])}),s},cssClip:function(t){return t?this.css("clip","rect("+t.top+"px "+t.right+"px "+t.bottom+"px "+t.left+"px)"):s(this.css("clip"),this)},transfer:function(e,i){var s=t(this),n=t(e.to),o="fixed"===n.css("position"),a=t("body"),r=o?a.scrollTop():0,h=o?a.scrollLeft():0,l=n.offset(),c={top:l.top-r,left:l.left-h,height:n.innerHeight(),width:n.innerWidth()},u=s.offset(),d=t("<div class='ui-effects-transfer'></div>").appendTo("body").addClass(e.className).css({top:u.top-r,left:u.left-h,height:s.innerHeight(),width:s.innerWidth(),position:o?"fixed":"absolute"}).animate(c,e.duration,e.easing,function(){d.remove(),t.isFunction(i)&&i()})}}),t.fx.step.clip=function(e){e.clipInit||(e.start=t(e.elem).cssClip(),"string"==typeof e.end&&(e.end=s(e.end,e.elem)),e.clipInit=!0),t(e.elem).cssClip({top:e.pos*(e.end.top-e.start.top)+e.start.top,right:e.pos*(e.end.right-e.start.right)+e.start.right,bottom:e.pos*(e.end.bottom-e.start.bottom)+e.start.bottom,left:e.pos*(e.end.left-e.start.left)+e.start.left})}}(),function(){var e={};t.each(["Quad","Cubic","Quart","Quint","Expo"],function(t,i){e[i]=function(e){return Math.pow(e,t+2)}}),t.extend(e,{Sine:function(t){return 1-Math.cos(t*Math.PI/2)},Circ:function(t){return 1-Math.sqrt(1-t*t)},Elastic:function(t){return 0===t||1===t?t:-Math.pow(2,8*(t-1))*Math.sin((80*(t-1)-7.5)*Math.PI/15)},Back:function(t){return t*t*(3*t-2)},Bounce:function(t){for(var e,i=4;((e=Math.pow(2,--i))-1)/11>t;);return 1/Math.pow(4,3-i)-7.5625*Math.pow((3*e-2)/22-t,2)}}),t.each(e,function(e,i){t.easing["easeIn"+e]=i,t.easing["easeOut"+e]=function(t){return 1-i(1-t)},t.easing["easeInOut"+e]=function(t){return.5>t?i(2*t)/2:1-i(-2*t+2)/2}})}();var v=t.effects;t.effects.define("blind","hide",function(e,i){var s={up:["bottom","top"],vertical:["bottom","top"],down:["top","bottom"],left:["right","left"],horizontal:["right","left"],right:["left","right"]},n=t(this),o=e.direction||"up",a=n.cssClip(),r={clip:t.extend({},a)},h=t.effects.createPlaceholder(n);r.clip[s[o][0]]=r.clip[s[o][1]],"show"===e.mode&&(n.cssClip(r.clip),h&&h.css(t.effects.clipToBox(r)),r.clip=a),h&&h.animate(t.effects.clipToBox(r),e.duration,e.easing),n.animate(r,{queue:!1,duration:e.duration,easing:e.easing,complete:i})}),t.effects.define("bounce",function(e,i){var s,n,o,a=t(this),r=e.mode,h="hide"===r,l="show"===r,c=e.direction||"up",u=e.distance,d=e.times||5,p=2*d+(l||h?1:0),f=e.duration/p,g=e.easing,m="up"===c||"down"===c?"top":"left",_="up"===c||"left"===c,v=0,b=a.queue().length;for(t.effects.createPlaceholder(a),o=a.css(m),u||(u=a["top"===m?"outerHeight":"outerWidth"]()/3),l&&(n={opacity:1},n[m]=o,a.css("opacity",0).css(m,_?2*-u:2*u).animate(n,f,g)),h&&(u/=Math.pow(2,d-1)),n={},n[m]=o;d>v;v++)s={},s[m]=(_?"-=":"+=")+u,a.animate(s,f,g).animate(n,f,g),u=h?2*u:u/2;h&&(s={opacity:0},s[m]=(_?"-=":"+=")+u,a.animate(s,f,g)),a.queue(i),t.effects.unshift(a,b,p+1)}),t.effects.define("clip","hide",function(e,i){var s,n={},o=t(this),a=e.direction||"vertical",r="both"===a,h=r||"horizontal"===a,l=r||"vertical"===a;s=o.cssClip(),n.clip={top:l?(s.bottom-s.top)/2:s.top,right:h?(s.right-s.left)/2:s.right,bottom:l?(s.bottom-s.top)/2:s.bottom,left:h?(s.right-s.left)/2:s.left},t.effects.createPlaceholder(o),"show"===e.mode&&(o.cssClip(n.clip),n.clip=s),o.animate(n,{queue:!1,duration:e.duration,easing:e.easing,complete:i})}),t.effects.define("drop","hide",function(e,i){var s,n=t(this),o=e.mode,a="show"===o,r=e.direction||"left",h="up"===r||"down"===r?"top":"left",l="up"===r||"left"===r?"-=":"+=",c="+="===l?"-=":"+=",u={opacity:0};t.effects.createPlaceholder(n),s=e.distance||n["top"===h?"outerHeight":"outerWidth"](!0)/2,u[h]=l+s,a&&(n.css(u),u[h]=c+s,u.opacity=1),n.animate(u,{queue:!1,duration:e.duration,easing:e.easing,complete:i})}),t.effects.define("explode","hide",function(e,i){function s(){b.push(this),b.length===u*d&&n()}function n(){p.css({visibility:"visible"}),t(b).remove(),i()}var o,a,r,h,l,c,u=e.pieces?Math.round(Math.sqrt(e.pieces)):3,d=u,p=t(this),f=e.mode,g="show"===f,m=p.show().css("visibility","hidden").offset(),_=Math.ceil(p.outerWidth()/d),v=Math.ceil(p.outerHeight()/u),b=[];for(o=0;u>o;o++)for(h=m.top+o*v,c=o-(u-1)/2,a=0;d>a;a++)r=m.left+a*_,l=a-(d-1)/2,p.clone().appendTo("body").wrap("<div></div>").css({position:"absolute",visibility:"visible",left:-a*_,top:-o*v}).parent().addClass("ui-effects-explode").css({position:"absolute",overflow:"hidden",width:_,height:v,left:r+(g?l*_:0),top:h+(g?c*v:0),opacity:g?0:1}).animate({left:r+(g?0:l*_),top:h+(g?0:c*v),opacity:g?1:0},e.duration||500,e.easing,s)}),t.effects.define("fade","toggle",function(e,i){var s="show"===e.mode;t(this).css("opacity",s?0:1).animate({opacity:s?1:0},{queue:!1,duration:e.duration,easing:e.easing,complete:i})}),t.effects.define("fold","hide",function(e,i){var s=t(this),n=e.mode,o="show"===n,a="hide"===n,r=e.size||15,h=/([0-9]+)%/.exec(r),l=!!e.horizFirst,c=l?["right","bottom"]:["bottom","right"],u=e.duration/2,d=t.effects.createPlaceholder(s),p=s.cssClip(),f={clip:t.extend({},p)},g={clip:t.extend({},p)},m=[p[c[0]],p[c[1]]],_=s.queue().length;h&&(r=parseInt(h[1],10)/100*m[a?0:1]),f.clip[c[0]]=r,g.clip[c[0]]=r,g.clip[c[1]]=0,o&&(s.cssClip(g.clip),d&&d.css(t.effects.clipToBox(g)),g.clip=p),s.queue(function(i){d&&d.animate(t.effects.clipToBox(f),u,e.easing).animate(t.effects.clipToBox(g),u,e.easing),i()}).animate(f,u,e.easing).animate(g,u,e.easing).queue(i),t.effects.unshift(s,_,4)}),t.effects.define("highlight","show",function(e,i){var s=t(this),n={backgroundColor:s.css("backgroundColor")};"hide"===e.mode&&(n.opacity=0),t.effects.saveStyle(s),s.css({backgroundImage:"none",backgroundColor:e.color||"#ffff99"}).animate(n,{queue:!1,duration:e.duration,easing:e.easing,complete:i})}),t.effects.define("size",function(e,i){var s,n,o,a=t(this),r=["fontSize"],h=["borderTopWidth","borderBottomWidth","paddingTop","paddingBottom"],l=["borderLeftWidth","borderRightWidth","paddingLeft","paddingRight"],c=e.mode,u="effect"!==c,d=e.scale||"both",p=e.origin||["middle","center"],f=a.css("position"),g=a.position(),m=t.effects.scaledDimensions(a),_=e.from||m,v=e.to||t.effects.scaledDimensions(a,0);t.effects.createPlaceholder(a),"show"===c&&(o=_,_=v,v=o),n={from:{y:_.height/m.height,x:_.width/m.width},to:{y:v.height/m.height,x:v.width/m.width}},("box"===d||"both"===d)&&(n.from.y!==n.to.y&&(_=t.effects.setTransition(a,h,n.from.y,_),v=t.effects.setTransition(a,h,n.to.y,v)),n.from.x!==n.to.x&&(_=t.effects.setTransition(a,l,n.from.x,_),v=t.effects.setTransition(a,l,n.to.x,v))),("content"===d||"both"===d)&&n.from.y!==n.to.y&&(_=t.effects.setTransition(a,r,n.from.y,_),v=t.effects.setTransition(a,r,n.to.y,v)),p&&(s=t.effects.getBaseline(p,m),_.top=(m.outerHeight-_.outerHeight)*s.y+g.top,_.left=(m.outerWidth-_.outerWidth)*s.x+g.left,v.top=(m.outerHeight-v.outerHeight)*s.y+g.top,v.left=(m.outerWidth-v.outerWidth)*s.x+g.left),a.css(_),("content"===d||"both"===d)&&(h=h.concat(["marginTop","marginBottom"]).concat(r),l=l.concat(["marginLeft","marginRight"]),a.find("*[width]").each(function(){var i=t(this),s=t.effects.scaledDimensions(i),o={height:s.height*n.from.y,width:s.width*n.from.x,outerHeight:s.outerHeight*n.from.y,outerWidth:s.outerWidth*n.from.x},a={height:s.height*n.to.y,width:s.width*n.to.x,outerHeight:s.height*n.to.y,outerWidth:s.width*n.to.x};n.from.y!==n.to.y&&(o=t.effects.setTransition(i,h,n.from.y,o),a=t.effects.setTransition(i,h,n.to.y,a)),n.from.x!==n.to.x&&(o=t.effects.setTransition(i,l,n.from.x,o),a=t.effects.setTransition(i,l,n.to.x,a)),u&&t.effects.saveStyle(i),i.css(o),i.animate(a,e.duration,e.easing,function(){u&&t.effects.restoreStyle(i)})})),a.animate(v,{queue:!1,duration:e.duration,easing:e.easing,complete:function(){var e=a.offset();0===v.opacity&&a.css("opacity",_.opacity),u||(a.css("position","static"===f?"relative":f).offset(e),t.effects.saveStyle(a)),i()}})}),t.effects.define("scale",function(e,i){var s=t(this),n=e.mode,o=parseInt(e.percent,10)||(0===parseInt(e.percent,10)?0:"effect"!==n?0:100),a=t.extend(!0,{from:t.effects.scaledDimensions(s),to:t.effects.scaledDimensions(s,o,e.direction||"both"),origin:e.origin||["middle","center"]},e);e.fade&&(a.from.opacity=1,a.to.opacity=0),t.effects.effect.size.call(this,a,i)}),t.effects.define("puff","hide",function(e,i){var s=t.extend(!0,{},e,{fade:!0,percent:parseInt(e.percent,10)||150});t.effects.effect.scale.call(this,s,i)}),t.effects.define("pulsate","show",function(e,i){var s=t(this),n=e.mode,o="show"===n,a="hide"===n,r=o||a,h=2*(e.times||5)+(r?1:0),l=e.duration/h,c=0,u=1,d=s.queue().length;for((o||!s.is(":visible"))&&(s.css("opacity",0).show(),c=1);h>u;u++)s.animate({opacity:c},l,e.easing),c=1-c;s.animate({opacity:c},l,e.easing),s.queue(i),t.effects.unshift(s,d,h+1)}),t.effects.define("shake",function(e,i){var s=1,n=t(this),o=e.direction||"left",a=e.distance||20,r=e.times||3,h=2*r+1,l=Math.round(e.duration/h),c="up"===o||"down"===o?"top":"left",u="up"===o||"left"===o,d={},p={},f={},g=n.queue().length;for(t.effects.createPlaceholder(n),d[c]=(u?"-=":"+=")+a,p[c]=(u?"+=":"-=")+2*a,f[c]=(u?"-=":"+=")+2*a,n.animate(d,l,e.easing);r>s;s++)n.animate(p,l,e.easing).animate(f,l,e.easing);n.animate(p,l,e.easing).animate(d,l/2,e.easing).queue(i),t.effects.unshift(n,g,h+1)}),t.effects.define("slide","show",function(e,i){var s,n,o=t(this),a={up:["bottom","top"],down:["top","bottom"],left:["right","left"],right:["left","right"]},r=e.mode,h=e.direction||"left",l="up"===h||"down"===h?"top":"left",c="up"===h||"left"===h,u=e.distance||o["top"===l?"outerHeight":"outerWidth"](!0),d={};t.effects.createPlaceholder(o),s=o.cssClip(),n=o.position()[l],d[l]=(c?-1:1)*u+n,d.clip=o.cssClip(),d.clip[a[h][1]]=d.clip[a[h][0]],"show"===r&&(o.cssClip(d.clip),o.css(l,d[l]),d.clip=s,d[l]=n),o.animate(d,{queue:!1,duration:e.duration,easing:e.easing,complete:i})});var v;t.uiBackCompat!==!1&&(v=t.effects.define("transfer",function(e,i){t(this).transfer(e,i)}))});
|
||
|
||
/***/ }),
|
||
/* 8 */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
|
||
window._ = __webpack_require__(9);
|
||
|
||
/**
|
||
* We'll load jQuery and the Bootstrap jQuery plugin which provides support
|
||
* for JavaScript based Bootstrap features such as modals and tabs. This
|
||
* code may be modified to fit the specific needs of your application.
|
||
*/
|
||
|
||
window.$ = window.jQuery = __webpack_require__(3);
|
||
__webpack_require__(11);
|
||
|
||
/**
|
||
* Vue is a modern JavaScript library for building interactive web interfaces
|
||
* using reactive data binding and reusable components. Vue's API is clean
|
||
* and simple, leaving you to focus on building your next great project.
|
||
*/
|
||
|
||
window.Vue = __webpack_require__(12);
|
||
window.eventHub = new Vue();
|
||
__webpack_require__(13);
|
||
|
||
/**
|
||
* We'll register a HTTP interceptor to attach the "CSRF" header to each of
|
||
* the outgoing requests issued by this application. The CSRF middleware
|
||
* included with Laravel will automatically verify the header's value.
|
||
*/
|
||
|
||
Vue.http.interceptors.push(function (request, next) {
|
||
request.headers.set('X-CSRF-TOKEN', Laravel.csrfToken);
|
||
|
||
next();
|
||
});
|
||
|
||
/**
|
||
* Echo exposes an expressive API for subscribing to channels and listening
|
||
* for events that are broadcast by Laravel. Echo and event broadcasting
|
||
* allows your team to easily build robust real-time web applications.
|
||
*/
|
||
|
||
// import Echo from "laravel-echo"
|
||
|
||
// window.Echo = new Echo({
|
||
// broadcaster: 'pusher',
|
||
// key: 'your-pusher-key'
|
||
// });
|
||
|
||
/***/ }),
|
||
/* 9 */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
/* WEBPACK VAR INJECTION */(function(global, module) {var __WEBPACK_AMD_DEFINE_RESULT__;/**
|
||
* @license
|
||
* Lodash <https://lodash.com/>
|
||
* Copyright JS Foundation and other contributors <https://js.foundation/>
|
||
* Released under MIT license <https://lodash.com/license>
|
||
* Based on Underscore.js 1.8.3 <http://underscorejs.org/LICENSE>
|
||
* Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
|
||
*/
|
||
;(function() {
|
||
|
||
/** Used as a safe reference for `undefined` in pre-ES5 environments. */
|
||
var undefined;
|
||
|
||
/** Used as the semantic version number. */
|
||
var VERSION = '4.17.4';
|
||
|
||
/** Used as the size to enable large array optimizations. */
|
||
var LARGE_ARRAY_SIZE = 200;
|
||
|
||
/** Error message constants. */
|
||
var CORE_ERROR_TEXT = 'Unsupported core-js use. Try https://npms.io/search?q=ponyfill.',
|
||
FUNC_ERROR_TEXT = 'Expected a function';
|
||
|
||
/** Used to stand-in for `undefined` hash values. */
|
||
var HASH_UNDEFINED = '__lodash_hash_undefined__';
|
||
|
||
/** Used as the maximum memoize cache size. */
|
||
var MAX_MEMOIZE_SIZE = 500;
|
||
|
||
/** Used as the internal argument placeholder. */
|
||
var PLACEHOLDER = '__lodash_placeholder__';
|
||
|
||
/** Used to compose bitmasks for cloning. */
|
||
var CLONE_DEEP_FLAG = 1,
|
||
CLONE_FLAT_FLAG = 2,
|
||
CLONE_SYMBOLS_FLAG = 4;
|
||
|
||
/** Used to compose bitmasks for value comparisons. */
|
||
var COMPARE_PARTIAL_FLAG = 1,
|
||
COMPARE_UNORDERED_FLAG = 2;
|
||
|
||
/** Used to compose bitmasks for function metadata. */
|
||
var WRAP_BIND_FLAG = 1,
|
||
WRAP_BIND_KEY_FLAG = 2,
|
||
WRAP_CURRY_BOUND_FLAG = 4,
|
||
WRAP_CURRY_FLAG = 8,
|
||
WRAP_CURRY_RIGHT_FLAG = 16,
|
||
WRAP_PARTIAL_FLAG = 32,
|
||
WRAP_PARTIAL_RIGHT_FLAG = 64,
|
||
WRAP_ARY_FLAG = 128,
|
||
WRAP_REARG_FLAG = 256,
|
||
WRAP_FLIP_FLAG = 512;
|
||
|
||
/** Used as default options for `_.truncate`. */
|
||
var DEFAULT_TRUNC_LENGTH = 30,
|
||
DEFAULT_TRUNC_OMISSION = '...';
|
||
|
||
/** Used to detect hot functions by number of calls within a span of milliseconds. */
|
||
var HOT_COUNT = 800,
|
||
HOT_SPAN = 16;
|
||
|
||
/** Used to indicate the type of lazy iteratees. */
|
||
var LAZY_FILTER_FLAG = 1,
|
||
LAZY_MAP_FLAG = 2,
|
||
LAZY_WHILE_FLAG = 3;
|
||
|
||
/** Used as references for various `Number` constants. */
|
||
var INFINITY = 1 / 0,
|
||
MAX_SAFE_INTEGER = 9007199254740991,
|
||
MAX_INTEGER = 1.7976931348623157e+308,
|
||
NAN = 0 / 0;
|
||
|
||
/** Used as references for the maximum length and index of an array. */
|
||
var MAX_ARRAY_LENGTH = 4294967295,
|
||
MAX_ARRAY_INDEX = MAX_ARRAY_LENGTH - 1,
|
||
HALF_MAX_ARRAY_LENGTH = MAX_ARRAY_LENGTH >>> 1;
|
||
|
||
/** Used to associate wrap methods with their bit flags. */
|
||
var wrapFlags = [
|
||
['ary', WRAP_ARY_FLAG],
|
||
['bind', WRAP_BIND_FLAG],
|
||
['bindKey', WRAP_BIND_KEY_FLAG],
|
||
['curry', WRAP_CURRY_FLAG],
|
||
['curryRight', WRAP_CURRY_RIGHT_FLAG],
|
||
['flip', WRAP_FLIP_FLAG],
|
||
['partial', WRAP_PARTIAL_FLAG],
|
||
['partialRight', WRAP_PARTIAL_RIGHT_FLAG],
|
||
['rearg', WRAP_REARG_FLAG]
|
||
];
|
||
|
||
/** `Object#toString` result references. */
|
||
var argsTag = '[object Arguments]',
|
||
arrayTag = '[object Array]',
|
||
asyncTag = '[object AsyncFunction]',
|
||
boolTag = '[object Boolean]',
|
||
dateTag = '[object Date]',
|
||
domExcTag = '[object DOMException]',
|
||
errorTag = '[object Error]',
|
||
funcTag = '[object Function]',
|
||
genTag = '[object GeneratorFunction]',
|
||
mapTag = '[object Map]',
|
||
numberTag = '[object Number]',
|
||
nullTag = '[object Null]',
|
||
objectTag = '[object Object]',
|
||
promiseTag = '[object Promise]',
|
||
proxyTag = '[object Proxy]',
|
||
regexpTag = '[object RegExp]',
|
||
setTag = '[object Set]',
|
||
stringTag = '[object String]',
|
||
symbolTag = '[object Symbol]',
|
||
undefinedTag = '[object Undefined]',
|
||
weakMapTag = '[object WeakMap]',
|
||
weakSetTag = '[object WeakSet]';
|
||
|
||
var arrayBufferTag = '[object ArrayBuffer]',
|
||
dataViewTag = '[object DataView]',
|
||
float32Tag = '[object Float32Array]',
|
||
float64Tag = '[object Float64Array]',
|
||
int8Tag = '[object Int8Array]',
|
||
int16Tag = '[object Int16Array]',
|
||
int32Tag = '[object Int32Array]',
|
||
uint8Tag = '[object Uint8Array]',
|
||
uint8ClampedTag = '[object Uint8ClampedArray]',
|
||
uint16Tag = '[object Uint16Array]',
|
||
uint32Tag = '[object Uint32Array]';
|
||
|
||
/** Used to match empty string literals in compiled template source. */
|
||
var reEmptyStringLeading = /\b__p \+= '';/g,
|
||
reEmptyStringMiddle = /\b(__p \+=) '' \+/g,
|
||
reEmptyStringTrailing = /(__e\(.*?\)|\b__t\)) \+\n'';/g;
|
||
|
||
/** Used to match HTML entities and HTML characters. */
|
||
var reEscapedHtml = /&(?:amp|lt|gt|quot|#39);/g,
|
||
reUnescapedHtml = /[&<>"']/g,
|
||
reHasEscapedHtml = RegExp(reEscapedHtml.source),
|
||
reHasUnescapedHtml = RegExp(reUnescapedHtml.source);
|
||
|
||
/** Used to match template delimiters. */
|
||
var reEscape = /<%-([\s\S]+?)%>/g,
|
||
reEvaluate = /<%([\s\S]+?)%>/g,
|
||
reInterpolate = /<%=([\s\S]+?)%>/g;
|
||
|
||
/** Used to match property names within property paths. */
|
||
var reIsDeepProp = /\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/,
|
||
reIsPlainProp = /^\w*$/,
|
||
reLeadingDot = /^\./,
|
||
rePropName = /[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|$))/g;
|
||
|
||
/**
|
||
* Used to match `RegExp`
|
||
* [syntax characters](http://ecma-international.org/ecma-262/7.0/#sec-patterns).
|
||
*/
|
||
var reRegExpChar = /[\\^$.*+?()[\]{}|]/g,
|
||
reHasRegExpChar = RegExp(reRegExpChar.source);
|
||
|
||
/** Used to match leading and trailing whitespace. */
|
||
var reTrim = /^\s+|\s+$/g,
|
||
reTrimStart = /^\s+/,
|
||
reTrimEnd = /\s+$/;
|
||
|
||
/** Used to match wrap detail comments. */
|
||
var reWrapComment = /\{(?:\n\/\* \[wrapped with .+\] \*\/)?\n?/,
|
||
reWrapDetails = /\{\n\/\* \[wrapped with (.+)\] \*/,
|
||
reSplitDetails = /,? & /;
|
||
|
||
/** Used to match words composed of alphanumeric characters. */
|
||
var reAsciiWord = /[^\x00-\x2f\x3a-\x40\x5b-\x60\x7b-\x7f]+/g;
|
||
|
||
/** Used to match backslashes in property paths. */
|
||
var reEscapeChar = /\\(\\)?/g;
|
||
|
||
/**
|
||
* Used to match
|
||
* [ES template delimiters](http://ecma-international.org/ecma-262/7.0/#sec-template-literal-lexical-components).
|
||
*/
|
||
var reEsTemplate = /\$\{([^\\}]*(?:\\.[^\\}]*)*)\}/g;
|
||
|
||
/** Used to match `RegExp` flags from their coerced string values. */
|
||
var reFlags = /\w*$/;
|
||
|
||
/** Used to detect bad signed hexadecimal string values. */
|
||
var reIsBadHex = /^[-+]0x[0-9a-f]+$/i;
|
||
|
||
/** Used to detect binary string values. */
|
||
var reIsBinary = /^0b[01]+$/i;
|
||
|
||
/** Used to detect host constructors (Safari). */
|
||
var reIsHostCtor = /^\[object .+?Constructor\]$/;
|
||
|
||
/** Used to detect octal string values. */
|
||
var reIsOctal = /^0o[0-7]+$/i;
|
||
|
||
/** Used to detect unsigned integer values. */
|
||
var reIsUint = /^(?:0|[1-9]\d*)$/;
|
||
|
||
/** Used to match Latin Unicode letters (excluding mathematical operators). */
|
||
var reLatin = /[\xc0-\xd6\xd8-\xf6\xf8-\xff\u0100-\u017f]/g;
|
||
|
||
/** Used to ensure capturing order of template delimiters. */
|
||
var reNoMatch = /($^)/;
|
||
|
||
/** Used to match unescaped characters in compiled string literals. */
|
||
var reUnescapedString = /['\n\r\u2028\u2029\\]/g;
|
||
|
||
/** Used to compose unicode character classes. */
|
||
var rsAstralRange = '\\ud800-\\udfff',
|
||
rsComboMarksRange = '\\u0300-\\u036f',
|
||
reComboHalfMarksRange = '\\ufe20-\\ufe2f',
|
||
rsComboSymbolsRange = '\\u20d0-\\u20ff',
|
||
rsComboRange = rsComboMarksRange + reComboHalfMarksRange + rsComboSymbolsRange,
|
||
rsDingbatRange = '\\u2700-\\u27bf',
|
||
rsLowerRange = 'a-z\\xdf-\\xf6\\xf8-\\xff',
|
||
rsMathOpRange = '\\xac\\xb1\\xd7\\xf7',
|
||
rsNonCharRange = '\\x00-\\x2f\\x3a-\\x40\\x5b-\\x60\\x7b-\\xbf',
|
||
rsPunctuationRange = '\\u2000-\\u206f',
|
||
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',
|
||
rsUpperRange = 'A-Z\\xc0-\\xd6\\xd8-\\xde',
|
||
rsVarRange = '\\ufe0e\\ufe0f',
|
||
rsBreakRange = rsMathOpRange + rsNonCharRange + rsPunctuationRange + rsSpaceRange;
|
||
|
||
/** Used to compose unicode capture groups. */
|
||
var rsApos = "['\u2019]",
|
||
rsAstral = '[' + rsAstralRange + ']',
|
||
rsBreak = '[' + rsBreakRange + ']',
|
||
rsCombo = '[' + rsComboRange + ']',
|
||
rsDigits = '\\d+',
|
||
rsDingbat = '[' + rsDingbatRange + ']',
|
||
rsLower = '[' + rsLowerRange + ']',
|
||
rsMisc = '[^' + rsAstralRange + rsBreakRange + rsDigits + rsDingbatRange + rsLowerRange + rsUpperRange + ']',
|
||
rsFitz = '\\ud83c[\\udffb-\\udfff]',
|
||
rsModifier = '(?:' + rsCombo + '|' + rsFitz + ')',
|
||
rsNonAstral = '[^' + rsAstralRange + ']',
|
||
rsRegional = '(?:\\ud83c[\\udde6-\\uddff]){2}',
|
||
rsSurrPair = '[\\ud800-\\udbff][\\udc00-\\udfff]',
|
||
rsUpper = '[' + rsUpperRange + ']',
|
||
rsZWJ = '\\u200d';
|
||
|
||
/** Used to compose unicode regexes. */
|
||
var rsMiscLower = '(?:' + rsLower + '|' + rsMisc + ')',
|
||
rsMiscUpper = '(?:' + rsUpper + '|' + rsMisc + ')',
|
||
rsOptContrLower = '(?:' + rsApos + '(?:d|ll|m|re|s|t|ve))?',
|
||
rsOptContrUpper = '(?:' + rsApos + '(?:D|LL|M|RE|S|T|VE))?',
|
||
reOptMod = rsModifier + '?',
|
||
rsOptVar = '[' + rsVarRange + ']?',
|
||
rsOptJoin = '(?:' + rsZWJ + '(?:' + [rsNonAstral, rsRegional, rsSurrPair].join('|') + ')' + rsOptVar + reOptMod + ')*',
|
||
rsOrdLower = '\\d*(?:(?:1st|2nd|3rd|(?![123])\\dth)\\b)',
|
||
rsOrdUpper = '\\d*(?:(?:1ST|2ND|3RD|(?![123])\\dTH)\\b)',
|
||
rsSeq = rsOptVar + reOptMod + rsOptJoin,
|
||
rsEmoji = '(?:' + [rsDingbat, rsRegional, rsSurrPair].join('|') + ')' + rsSeq,
|
||
rsSymbol = '(?:' + [rsNonAstral + rsCombo + '?', rsCombo, rsRegional, rsSurrPair, rsAstral].join('|') + ')';
|
||
|
||
/** Used to match apostrophes. */
|
||
var reApos = RegExp(rsApos, 'g');
|
||
|
||
/**
|
||
* Used to match [combining diacritical marks](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks) and
|
||
* [combining diacritical marks for symbols](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks_for_Symbols).
|
||
*/
|
||
var reComboMark = RegExp(rsCombo, 'g');
|
||
|
||
/** Used to match [string symbols](https://mathiasbynens.be/notes/javascript-unicode). */
|
||
var reUnicode = RegExp(rsFitz + '(?=' + rsFitz + ')|' + rsSymbol + rsSeq, 'g');
|
||
|
||
/** Used to match complex or compound words. */
|
||
var reUnicodeWord = RegExp([
|
||
rsUpper + '?' + rsLower + '+' + rsOptContrLower + '(?=' + [rsBreak, rsUpper, '$'].join('|') + ')',
|
||
rsMiscUpper + '+' + rsOptContrUpper + '(?=' + [rsBreak, rsUpper + rsMiscLower, '$'].join('|') + ')',
|
||
rsUpper + '?' + rsMiscLower + '+' + rsOptContrLower,
|
||
rsUpper + '+' + rsOptContrUpper,
|
||
rsOrdUpper,
|
||
rsOrdLower,
|
||
rsDigits,
|
||
rsEmoji
|
||
].join('|'), 'g');
|
||
|
||
/** 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/). */
|
||
var reHasUnicode = RegExp('[' + rsZWJ + rsAstralRange + rsComboRange + rsVarRange + ']');
|
||
|
||
/** Used to detect strings that need a more robust regexp to match words. */
|
||
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 ]/;
|
||
|
||
/** Used to assign default `context` object properties. */
|
||
var contextProps = [
|
||
'Array', 'Buffer', 'DataView', 'Date', 'Error', 'Float32Array', 'Float64Array',
|
||
'Function', 'Int8Array', 'Int16Array', 'Int32Array', 'Map', 'Math', 'Object',
|
||
'Promise', 'RegExp', 'Set', 'String', 'Symbol', 'TypeError', 'Uint8Array',
|
||
'Uint8ClampedArray', 'Uint16Array', 'Uint32Array', 'WeakMap',
|
||
'_', 'clearTimeout', 'isFinite', 'parseInt', 'setTimeout'
|
||
];
|
||
|
||
/** Used to make template sourceURLs easier to identify. */
|
||
var templateCounter = -1;
|
||
|
||
/** Used to identify `toStringTag` values of typed arrays. */
|
||
var typedArrayTags = {};
|
||
typedArrayTags[float32Tag] = typedArrayTags[float64Tag] =
|
||
typedArrayTags[int8Tag] = typedArrayTags[int16Tag] =
|
||
typedArrayTags[int32Tag] = typedArrayTags[uint8Tag] =
|
||
typedArrayTags[uint8ClampedTag] = typedArrayTags[uint16Tag] =
|
||
typedArrayTags[uint32Tag] = true;
|
||
typedArrayTags[argsTag] = typedArrayTags[arrayTag] =
|
||
typedArrayTags[arrayBufferTag] = typedArrayTags[boolTag] =
|
||
typedArrayTags[dataViewTag] = typedArrayTags[dateTag] =
|
||
typedArrayTags[errorTag] = typedArrayTags[funcTag] =
|
||
typedArrayTags[mapTag] = typedArrayTags[numberTag] =
|
||
typedArrayTags[objectTag] = typedArrayTags[regexpTag] =
|
||
typedArrayTags[setTag] = typedArrayTags[stringTag] =
|
||
typedArrayTags[weakMapTag] = false;
|
||
|
||
/** Used to identify `toStringTag` values supported by `_.clone`. */
|
||
var cloneableTags = {};
|
||
cloneableTags[argsTag] = cloneableTags[arrayTag] =
|
||
cloneableTags[arrayBufferTag] = cloneableTags[dataViewTag] =
|
||
cloneableTags[boolTag] = cloneableTags[dateTag] =
|
||
cloneableTags[float32Tag] = cloneableTags[float64Tag] =
|
||
cloneableTags[int8Tag] = cloneableTags[int16Tag] =
|
||
cloneableTags[int32Tag] = cloneableTags[mapTag] =
|
||
cloneableTags[numberTag] = cloneableTags[objectTag] =
|
||
cloneableTags[regexpTag] = cloneableTags[setTag] =
|
||
cloneableTags[stringTag] = cloneableTags[symbolTag] =
|
||
cloneableTags[uint8Tag] = cloneableTags[uint8ClampedTag] =
|
||
cloneableTags[uint16Tag] = cloneableTags[uint32Tag] = true;
|
||
cloneableTags[errorTag] = cloneableTags[funcTag] =
|
||
cloneableTags[weakMapTag] = false;
|
||
|
||
/** Used to map Latin Unicode letters to basic Latin letters. */
|
||
var deburredLetters = {
|
||
// Latin-1 Supplement block.
|
||
'\xc0': 'A', '\xc1': 'A', '\xc2': 'A', '\xc3': 'A', '\xc4': 'A', '\xc5': 'A',
|
||
'\xe0': 'a', '\xe1': 'a', '\xe2': 'a', '\xe3': 'a', '\xe4': 'a', '\xe5': 'a',
|
||
'\xc7': 'C', '\xe7': 'c',
|
||
'\xd0': 'D', '\xf0': 'd',
|
||
'\xc8': 'E', '\xc9': 'E', '\xca': 'E', '\xcb': 'E',
|
||
'\xe8': 'e', '\xe9': 'e', '\xea': 'e', '\xeb': 'e',
|
||
'\xcc': 'I', '\xcd': 'I', '\xce': 'I', '\xcf': 'I',
|
||
'\xec': 'i', '\xed': 'i', '\xee': 'i', '\xef': 'i',
|
||
'\xd1': 'N', '\xf1': 'n',
|
||
'\xd2': 'O', '\xd3': 'O', '\xd4': 'O', '\xd5': 'O', '\xd6': 'O', '\xd8': 'O',
|
||
'\xf2': 'o', '\xf3': 'o', '\xf4': 'o', '\xf5': 'o', '\xf6': 'o', '\xf8': 'o',
|
||
'\xd9': 'U', '\xda': 'U', '\xdb': 'U', '\xdc': 'U',
|
||
'\xf9': 'u', '\xfa': 'u', '\xfb': 'u', '\xfc': 'u',
|
||
'\xdd': 'Y', '\xfd': 'y', '\xff': 'y',
|
||
'\xc6': 'Ae', '\xe6': 'ae',
|
||
'\xde': 'Th', '\xfe': 'th',
|
||
'\xdf': 'ss',
|
||
// Latin Extended-A block.
|
||
'\u0100': 'A', '\u0102': 'A', '\u0104': 'A',
|
||
'\u0101': 'a', '\u0103': 'a', '\u0105': 'a',
|
||
'\u0106': 'C', '\u0108': 'C', '\u010a': 'C', '\u010c': 'C',
|
||
'\u0107': 'c', '\u0109': 'c', '\u010b': 'c', '\u010d': 'c',
|
||
'\u010e': 'D', '\u0110': 'D', '\u010f': 'd', '\u0111': 'd',
|
||
'\u0112': 'E', '\u0114': 'E', '\u0116': 'E', '\u0118': 'E', '\u011a': 'E',
|
||
'\u0113': 'e', '\u0115': 'e', '\u0117': 'e', '\u0119': 'e', '\u011b': 'e',
|
||
'\u011c': 'G', '\u011e': 'G', '\u0120': 'G', '\u0122': 'G',
|
||
'\u011d': 'g', '\u011f': 'g', '\u0121': 'g', '\u0123': 'g',
|
||
'\u0124': 'H', '\u0126': 'H', '\u0125': 'h', '\u0127': 'h',
|
||
'\u0128': 'I', '\u012a': 'I', '\u012c': 'I', '\u012e': 'I', '\u0130': 'I',
|
||
'\u0129': 'i', '\u012b': 'i', '\u012d': 'i', '\u012f': 'i', '\u0131': 'i',
|
||
'\u0134': 'J', '\u0135': 'j',
|
||
'\u0136': 'K', '\u0137': 'k', '\u0138': 'k',
|
||
'\u0139': 'L', '\u013b': 'L', '\u013d': 'L', '\u013f': 'L', '\u0141': 'L',
|
||
'\u013a': 'l', '\u013c': 'l', '\u013e': 'l', '\u0140': 'l', '\u0142': 'l',
|
||
'\u0143': 'N', '\u0145': 'N', '\u0147': 'N', '\u014a': 'N',
|
||
'\u0144': 'n', '\u0146': 'n', '\u0148': 'n', '\u014b': 'n',
|
||
'\u014c': 'O', '\u014e': 'O', '\u0150': 'O',
|
||
'\u014d': 'o', '\u014f': 'o', '\u0151': 'o',
|
||
'\u0154': 'R', '\u0156': 'R', '\u0158': 'R',
|
||
'\u0155': 'r', '\u0157': 'r', '\u0159': 'r',
|
||
'\u015a': 'S', '\u015c': 'S', '\u015e': 'S', '\u0160': 'S',
|
||
'\u015b': 's', '\u015d': 's', '\u015f': 's', '\u0161': 's',
|
||
'\u0162': 'T', '\u0164': 'T', '\u0166': 'T',
|
||
'\u0163': 't', '\u0165': 't', '\u0167': 't',
|
||
'\u0168': 'U', '\u016a': 'U', '\u016c': 'U', '\u016e': 'U', '\u0170': 'U', '\u0172': 'U',
|
||
'\u0169': 'u', '\u016b': 'u', '\u016d': 'u', '\u016f': 'u', '\u0171': 'u', '\u0173': 'u',
|
||
'\u0174': 'W', '\u0175': 'w',
|
||
'\u0176': 'Y', '\u0177': 'y', '\u0178': 'Y',
|
||
'\u0179': 'Z', '\u017b': 'Z', '\u017d': 'Z',
|
||
'\u017a': 'z', '\u017c': 'z', '\u017e': 'z',
|
||
'\u0132': 'IJ', '\u0133': 'ij',
|
||
'\u0152': 'Oe', '\u0153': 'oe',
|
||
'\u0149': "'n", '\u017f': 's'
|
||
};
|
||
|
||
/** Used to map characters to HTML entities. */
|
||
var htmlEscapes = {
|
||
'&': '&',
|
||
'<': '<',
|
||
'>': '>',
|
||
'"': '"',
|
||
"'": '''
|
||
};
|
||
|
||
/** Used to map HTML entities to characters. */
|
||
var htmlUnescapes = {
|
||
'&': '&',
|
||
'<': '<',
|
||
'>': '>',
|
||
'"': '"',
|
||
''': "'"
|
||
};
|
||
|
||
/** Used to escape characters for inclusion in compiled string literals. */
|
||
var stringEscapes = {
|
||
'\\': '\\',
|
||
"'": "'",
|
||
'\n': 'n',
|
||
'\r': 'r',
|
||
'\u2028': 'u2028',
|
||
'\u2029': 'u2029'
|
||
};
|
||
|
||
/** Built-in method references without a dependency on `root`. */
|
||
var freeParseFloat = parseFloat,
|
||
freeParseInt = parseInt;
|
||
|
||
/** Detect free variable `global` from Node.js. */
|
||
var freeGlobal = typeof global == 'object' && global && global.Object === Object && global;
|
||
|
||
/** Detect free variable `self`. */
|
||
var freeSelf = typeof self == 'object' && self && self.Object === Object && self;
|
||
|
||
/** Used as a reference to the global object. */
|
||
var root = freeGlobal || freeSelf || Function('return this')();
|
||
|
||
/** Detect free variable `exports`. */
|
||
var freeExports = typeof exports == 'object' && exports && !exports.nodeType && exports;
|
||
|
||
/** Detect free variable `module`. */
|
||
var freeModule = freeExports && typeof module == 'object' && module && !module.nodeType && module;
|
||
|
||
/** Detect the popular CommonJS extension `module.exports`. */
|
||
var moduleExports = freeModule && freeModule.exports === freeExports;
|
||
|
||
/** Detect free variable `process` from Node.js. */
|
||
var freeProcess = moduleExports && freeGlobal.process;
|
||
|
||
/** Used to access faster Node.js helpers. */
|
||
var nodeUtil = (function() {
|
||
try {
|
||
return freeProcess && freeProcess.binding && freeProcess.binding('util');
|
||
} catch (e) {}
|
||
}());
|
||
|
||
/* Node.js helper references. */
|
||
var nodeIsArrayBuffer = nodeUtil && nodeUtil.isArrayBuffer,
|
||
nodeIsDate = nodeUtil && nodeUtil.isDate,
|
||
nodeIsMap = nodeUtil && nodeUtil.isMap,
|
||
nodeIsRegExp = nodeUtil && nodeUtil.isRegExp,
|
||
nodeIsSet = nodeUtil && nodeUtil.isSet,
|
||
nodeIsTypedArray = nodeUtil && nodeUtil.isTypedArray;
|
||
|
||
/*--------------------------------------------------------------------------*/
|
||
|
||
/**
|
||
* Adds the key-value `pair` to `map`.
|
||
*
|
||
* @private
|
||
* @param {Object} map The map to modify.
|
||
* @param {Array} pair The key-value pair to add.
|
||
* @returns {Object} Returns `map`.
|
||
*/
|
||
function addMapEntry(map, pair) {
|
||
// Don't return `map.set` because it's not chainable in IE 11.
|
||
map.set(pair[0], pair[1]);
|
||
return map;
|
||
}
|
||
|
||
/**
|
||
* Adds `value` to `set`.
|
||
*
|
||
* @private
|
||
* @param {Object} set The set to modify.
|
||
* @param {*} value The value to add.
|
||
* @returns {Object} Returns `set`.
|
||
*/
|
||
function addSetEntry(set, value) {
|
||
// Don't return `set.add` because it's not chainable in IE 11.
|
||
set.add(value);
|
||
return set;
|
||
}
|
||
|
||
/**
|
||
* A faster alternative to `Function#apply`, this function invokes `func`
|
||
* with the `this` binding of `thisArg` and the arguments of `args`.
|
||
*
|
||
* @private
|
||
* @param {Function} func The function to invoke.
|
||
* @param {*} thisArg The `this` binding of `func`.
|
||
* @param {Array} args The arguments to invoke `func` with.
|
||
* @returns {*} Returns the result of `func`.
|
||
*/
|
||
function apply(func, thisArg, args) {
|
||
switch (args.length) {
|
||
case 0: return func.call(thisArg);
|
||
case 1: return func.call(thisArg, args[0]);
|
||
case 2: return func.call(thisArg, args[0], args[1]);
|
||
case 3: return func.call(thisArg, args[0], args[1], args[2]);
|
||
}
|
||
return func.apply(thisArg, args);
|
||
}
|
||
|
||
/**
|
||
* A specialized version of `baseAggregator` for arrays.
|
||
*
|
||
* @private
|
||
* @param {Array} [array] The array to iterate over.
|
||
* @param {Function} setter The function to set `accumulator` values.
|
||
* @param {Function} iteratee The iteratee to transform keys.
|
||
* @param {Object} accumulator The initial aggregated object.
|
||
* @returns {Function} Returns `accumulator`.
|
||
*/
|
||
function arrayAggregator(array, setter, iteratee, accumulator) {
|
||
var index = -1,
|
||
length = array == null ? 0 : array.length;
|
||
|
||
while (++index < length) {
|
||
var value = array[index];
|
||
setter(accumulator, value, iteratee(value), array);
|
||
}
|
||
return accumulator;
|
||
}
|
||
|
||
/**
|
||
* A specialized version of `_.forEach` for arrays without support for
|
||
* iteratee shorthands.
|
||
*
|
||
* @private
|
||
* @param {Array} [array] The array to iterate over.
|
||
* @param {Function} iteratee The function invoked per iteration.
|
||
* @returns {Array} Returns `array`.
|
||
*/
|
||
function arrayEach(array, iteratee) {
|
||
var index = -1,
|
||
length = array == null ? 0 : array.length;
|
||
|
||
while (++index < length) {
|
||
if (iteratee(array[index], index, array) === false) {
|
||
break;
|
||
}
|
||
}
|
||
return array;
|
||
}
|
||
|
||
/**
|
||
* A specialized version of `_.forEachRight` for arrays without support for
|
||
* iteratee shorthands.
|
||
*
|
||
* @private
|
||
* @param {Array} [array] The array to iterate over.
|
||
* @param {Function} iteratee The function invoked per iteration.
|
||
* @returns {Array} Returns `array`.
|
||
*/
|
||
function arrayEachRight(array, iteratee) {
|
||
var length = array == null ? 0 : array.length;
|
||
|
||
while (length--) {
|
||
if (iteratee(array[length], length, array) === false) {
|
||
break;
|
||
}
|
||
}
|
||
return array;
|
||
}
|
||
|
||
/**
|
||
* A specialized version of `_.every` for arrays without support for
|
||
* iteratee shorthands.
|
||
*
|
||
* @private
|
||
* @param {Array} [array] The array to iterate over.
|
||
* @param {Function} predicate The function invoked per iteration.
|
||
* @returns {boolean} Returns `true` if all elements pass the predicate check,
|
||
* else `false`.
|
||
*/
|
||
function arrayEvery(array, predicate) {
|
||
var index = -1,
|
||
length = array == null ? 0 : array.length;
|
||
|
||
while (++index < length) {
|
||
if (!predicate(array[index], index, array)) {
|
||
return false;
|
||
}
|
||
}
|
||
return true;
|
||
}
|
||
|
||
/**
|
||
* A specialized version of `_.filter` for arrays without support for
|
||
* iteratee shorthands.
|
||
*
|
||
* @private
|
||
* @param {Array} [array] The array to iterate over.
|
||
* @param {Function} predicate The function invoked per iteration.
|
||
* @returns {Array} Returns the new filtered array.
|
||
*/
|
||
function arrayFilter(array, predicate) {
|
||
var index = -1,
|
||
length = array == null ? 0 : array.length,
|
||
resIndex = 0,
|
||
result = [];
|
||
|
||
while (++index < length) {
|
||
var value = array[index];
|
||
if (predicate(value, index, array)) {
|
||
result[resIndex++] = value;
|
||
}
|
||
}
|
||
return result;
|
||
}
|
||
|
||
/**
|
||
* A specialized version of `_.includes` for arrays without support for
|
||
* specifying an index to search from.
|
||
*
|
||
* @private
|
||
* @param {Array} [array] The array to inspect.
|
||
* @param {*} target The value to search for.
|
||
* @returns {boolean} Returns `true` if `target` is found, else `false`.
|
||
*/
|
||
function arrayIncludes(array, value) {
|
||
var length = array == null ? 0 : array.length;
|
||
return !!length && baseIndexOf(array, value, 0) > -1;
|
||
}
|
||
|
||
/**
|
||
* This function is like `arrayIncludes` except that it accepts a comparator.
|
||
*
|
||
* @private
|
||
* @param {Array} [array] The array to inspect.
|
||
* @param {*} target The value to search for.
|
||
* @param {Function} comparator The comparator invoked per element.
|
||
* @returns {boolean} Returns `true` if `target` is found, else `false`.
|
||
*/
|
||
function arrayIncludesWith(array, value, comparator) {
|
||
var index = -1,
|
||
length = array == null ? 0 : array.length;
|
||
|
||
while (++index < length) {
|
||
if (comparator(value, array[index])) {
|
||
return true;
|
||
}
|
||
}
|
||
return false;
|
||
}
|
||
|
||
/**
|
||
* A specialized version of `_.map` for arrays without support for iteratee
|
||
* shorthands.
|
||
*
|
||
* @private
|
||
* @param {Array} [array] The array to iterate over.
|
||
* @param {Function} iteratee The function invoked per iteration.
|
||
* @returns {Array} Returns the new mapped array.
|
||
*/
|
||
function arrayMap(array, iteratee) {
|
||
var index = -1,
|
||
length = array == null ? 0 : array.length,
|
||
result = Array(length);
|
||
|
||
while (++index < length) {
|
||
result[index] = iteratee(array[index], index, array);
|
||
}
|
||
return result;
|
||
}
|
||
|
||
/**
|
||
* Appends the elements of `values` to `array`.
|
||
*
|
||
* @private
|
||
* @param {Array} array The array to modify.
|
||
* @param {Array} values The values to append.
|
||
* @returns {Array} Returns `array`.
|
||
*/
|
||
function arrayPush(array, values) {
|
||
var index = -1,
|
||
length = values.length,
|
||
offset = array.length;
|
||
|
||
while (++index < length) {
|
||
array[offset + index] = values[index];
|
||
}
|
||
return array;
|
||
}
|
||
|
||
/**
|
||
* A specialized version of `_.reduce` for arrays without support for
|
||
* iteratee shorthands.
|
||
*
|
||
* @private
|
||
* @param {Array} [array] The array to iterate over.
|
||
* @param {Function} iteratee The function invoked per iteration.
|
||
* @param {*} [accumulator] The initial value.
|
||
* @param {boolean} [initAccum] Specify using the first element of `array` as
|
||
* the initial value.
|
||
* @returns {*} Returns the accumulated value.
|
||
*/
|
||
function arrayReduce(array, iteratee, accumulator, initAccum) {
|
||
var index = -1,
|
||
length = array == null ? 0 : array.length;
|
||
|
||
if (initAccum && length) {
|
||
accumulator = array[++index];
|
||
}
|
||
while (++index < length) {
|
||
accumulator = iteratee(accumulator, array[index], index, array);
|
||
}
|
||
return accumulator;
|
||
}
|
||
|
||
/**
|
||
* A specialized version of `_.reduceRight` for arrays without support for
|
||
* iteratee shorthands.
|
||
*
|
||
* @private
|
||
* @param {Array} [array] The array to iterate over.
|
||
* @param {Function} iteratee The function invoked per iteration.
|
||
* @param {*} [accumulator] The initial value.
|
||
* @param {boolean} [initAccum] Specify using the last element of `array` as
|
||
* the initial value.
|
||
* @returns {*} Returns the accumulated value.
|
||
*/
|
||
function arrayReduceRight(array, iteratee, accumulator, initAccum) {
|
||
var length = array == null ? 0 : array.length;
|
||
if (initAccum && length) {
|
||
accumulator = array[--length];
|
||
}
|
||
while (length--) {
|
||
accumulator = iteratee(accumulator, array[length], length, array);
|
||
}
|
||
return accumulator;
|
||
}
|
||
|
||
/**
|
||
* A specialized version of `_.some` for arrays without support for iteratee
|
||
* shorthands.
|
||
*
|
||
* @private
|
||
* @param {Array} [array] The array to iterate over.
|
||
* @param {Function} predicate The function invoked per iteration.
|
||
* @returns {boolean} Returns `true` if any element passes the predicate check,
|
||
* else `false`.
|
||
*/
|
||
function arraySome(array, predicate) {
|
||
var index = -1,
|
||
length = array == null ? 0 : array.length;
|
||
|
||
while (++index < length) {
|
||
if (predicate(array[index], index, array)) {
|
||
return true;
|
||
}
|
||
}
|
||
return false;
|
||
}
|
||
|
||
/**
|
||
* Gets the size of an ASCII `string`.
|
||
*
|
||
* @private
|
||
* @param {string} string The string inspect.
|
||
* @returns {number} Returns the string size.
|
||
*/
|
||
var asciiSize = baseProperty('length');
|
||
|
||
/**
|
||
* Converts an ASCII `string` to an array.
|
||
*
|
||
* @private
|
||
* @param {string} string The string to convert.
|
||
* @returns {Array} Returns the converted array.
|
||
*/
|
||
function asciiToArray(string) {
|
||
return string.split('');
|
||
}
|
||
|
||
/**
|
||
* Splits an ASCII `string` into an array of its words.
|
||
*
|
||
* @private
|
||
* @param {string} The string to inspect.
|
||
* @returns {Array} Returns the words of `string`.
|
||
*/
|
||
function asciiWords(string) {
|
||
return string.match(reAsciiWord) || [];
|
||
}
|
||
|
||
/**
|
||
* The base implementation of methods like `_.findKey` and `_.findLastKey`,
|
||
* without support for iteratee shorthands, which iterates over `collection`
|
||
* using `eachFunc`.
|
||
*
|
||
* @private
|
||
* @param {Array|Object} collection The collection to inspect.
|
||
* @param {Function} predicate The function invoked per iteration.
|
||
* @param {Function} eachFunc The function to iterate over `collection`.
|
||
* @returns {*} Returns the found element or its key, else `undefined`.
|
||
*/
|
||
function baseFindKey(collection, predicate, eachFunc) {
|
||
var result;
|
||
eachFunc(collection, function(value, key, collection) {
|
||
if (predicate(value, key, collection)) {
|
||
result = key;
|
||
return false;
|
||
}
|
||
});
|
||
return result;
|
||
}
|
||
|
||
/**
|
||
* The base implementation of `_.findIndex` and `_.findLastIndex` without
|
||
* support for iteratee shorthands.
|
||
*
|
||
* @private
|
||
* @param {Array} array The array to inspect.
|
||
* @param {Function} predicate The function invoked per iteration.
|
||
* @param {number} fromIndex The index to search from.
|
||
* @param {boolean} [fromRight] Specify iterating from right to left.
|
||
* @returns {number} Returns the index of the matched value, else `-1`.
|
||
*/
|
||
function baseFindIndex(array, predicate, fromIndex, fromRight) {
|
||
var length = array.length,
|
||
index = fromIndex + (fromRight ? 1 : -1);
|
||
|
||
while ((fromRight ? index-- : ++index < length)) {
|
||
if (predicate(array[index], index, array)) {
|
||
return index;
|
||
}
|
||
}
|
||
return -1;
|
||
}
|
||
|
||
/**
|
||
* The base implementation of `_.indexOf` without `fromIndex` bounds checks.
|
||
*
|
||
* @private
|
||
* @param {Array} array The array to inspect.
|
||
* @param {*} value The value to search for.
|
||
* @param {number} fromIndex The index to search from.
|
||
* @returns {number} Returns the index of the matched value, else `-1`.
|
||
*/
|
||
function baseIndexOf(array, value, fromIndex) {
|
||
return value === value
|
||
? strictIndexOf(array, value, fromIndex)
|
||
: baseFindIndex(array, baseIsNaN, fromIndex);
|
||
}
|
||
|
||
/**
|
||
* This function is like `baseIndexOf` except that it accepts a comparator.
|
||
*
|
||
* @private
|
||
* @param {Array} array The array to inspect.
|
||
* @param {*} value The value to search for.
|
||
* @param {number} fromIndex The index to search from.
|
||
* @param {Function} comparator The comparator invoked per element.
|
||
* @returns {number} Returns the index of the matched value, else `-1`.
|
||
*/
|
||
function baseIndexOfWith(array, value, fromIndex, comparator) {
|
||
var index = fromIndex - 1,
|
||
length = array.length;
|
||
|
||
while (++index < length) {
|
||
if (comparator(array[index], value)) {
|
||
return index;
|
||
}
|
||
}
|
||
return -1;
|
||
}
|
||
|
||
/**
|
||
* The base implementation of `_.isNaN` without support for number objects.
|
||
*
|
||
* @private
|
||
* @param {*} value The value to check.
|
||
* @returns {boolean} Returns `true` if `value` is `NaN`, else `false`.
|
||
*/
|
||
function baseIsNaN(value) {
|
||
return value !== value;
|
||
}
|
||
|
||
/**
|
||
* The base implementation of `_.mean` and `_.meanBy` without support for
|
||
* iteratee shorthands.
|
||
*
|
||
* @private
|
||
* @param {Array} array The array to iterate over.
|
||
* @param {Function} iteratee The function invoked per iteration.
|
||
* @returns {number} Returns the mean.
|
||
*/
|
||
function baseMean(array, iteratee) {
|
||
var length = array == null ? 0 : array.length;
|
||
return length ? (baseSum(array, iteratee) / length) : NAN;
|
||
}
|
||
|
||
/**
|
||
* The base implementation of `_.property` without support for deep paths.
|
||
*
|
||
* @private
|
||
* @param {string} key The key of the property to get.
|
||
* @returns {Function} Returns the new accessor function.
|
||
*/
|
||
function baseProperty(key) {
|
||
return function(object) {
|
||
return object == null ? undefined : object[key];
|
||
};
|
||
}
|
||
|
||
/**
|
||
* The base implementation of `_.propertyOf` without support for deep paths.
|
||
*
|
||
* @private
|
||
* @param {Object} object The object to query.
|
||
* @returns {Function} Returns the new accessor function.
|
||
*/
|
||
function basePropertyOf(object) {
|
||
return function(key) {
|
||
return object == null ? undefined : object[key];
|
||
};
|
||
}
|
||
|
||
/**
|
||
* The base implementation of `_.reduce` and `_.reduceRight`, without support
|
||
* for iteratee shorthands, which iterates over `collection` using `eachFunc`.
|
||
*
|
||
* @private
|
||
* @param {Array|Object} collection The collection to iterate over.
|
||
* @param {Function} iteratee The function invoked per iteration.
|
||
* @param {*} accumulator The initial value.
|
||
* @param {boolean} initAccum Specify using the first or last element of
|
||
* `collection` as the initial value.
|
||
* @param {Function} eachFunc The function to iterate over `collection`.
|
||
* @returns {*} Returns the accumulated value.
|
||
*/
|
||
function baseReduce(collection, iteratee, accumulator, initAccum, eachFunc) {
|
||
eachFunc(collection, function(value, index, collection) {
|
||
accumulator = initAccum
|
||
? (initAccum = false, value)
|
||
: iteratee(accumulator, value, index, collection);
|
||
});
|
||
return accumulator;
|
||
}
|
||
|
||
/**
|
||
* The base implementation of `_.sortBy` which uses `comparer` to define the
|
||
* sort order of `array` and replaces criteria objects with their corresponding
|
||
* values.
|
||
*
|
||
* @private
|
||
* @param {Array} array The array to sort.
|
||
* @param {Function} comparer The function to define sort order.
|
||
* @returns {Array} Returns `array`.
|
||
*/
|
||
function baseSortBy(array, comparer) {
|
||
var length = array.length;
|
||
|
||
array.sort(comparer);
|
||
while (length--) {
|
||
array[length] = array[length].value;
|
||
}
|
||
return array;
|
||
}
|
||
|
||
/**
|
||
* The base implementation of `_.sum` and `_.sumBy` without support for
|
||
* iteratee shorthands.
|
||
*
|
||
* @private
|
||
* @param {Array} array The array to iterate over.
|
||
* @param {Function} iteratee The function invoked per iteration.
|
||
* @returns {number} Returns the sum.
|
||
*/
|
||
function baseSum(array, iteratee) {
|
||
var result,
|
||
index = -1,
|
||
length = array.length;
|
||
|
||
while (++index < length) {
|
||
var current = iteratee(array[index]);
|
||
if (current !== undefined) {
|
||
result = result === undefined ? current : (result + current);
|
||
}
|
||
}
|
||
return result;
|
||
}
|
||
|
||
/**
|
||
* The base implementation of `_.times` without support for iteratee shorthands
|
||
* or max array length checks.
|
||
*
|
||
* @private
|
||
* @param {number} n The number of times to invoke `iteratee`.
|
||
* @param {Function} iteratee The function invoked per iteration.
|
||
* @returns {Array} Returns the array of results.
|
||
*/
|
||
function baseTimes(n, iteratee) {
|
||
var index = -1,
|
||
result = Array(n);
|
||
|
||
while (++index < n) {
|
||
result[index] = iteratee(index);
|
||
}
|
||
return result;
|
||
}
|
||
|
||
/**
|
||
* The base implementation of `_.toPairs` and `_.toPairsIn` which creates an array
|
||
* of key-value pairs for `object` corresponding to the property names of `props`.
|
||
*
|
||
* @private
|
||
* @param {Object} object The object to query.
|
||
* @param {Array} props The property names to get values for.
|
||
* @returns {Object} Returns the key-value pairs.
|
||
*/
|
||
function baseToPairs(object, props) {
|
||
return arrayMap(props, function(key) {
|
||
return [key, object[key]];
|
||
});
|
||
}
|
||
|
||
/**
|
||
* The base implementation of `_.unary` without support for storing metadata.
|
||
*
|
||
* @private
|
||
* @param {Function} func The function to cap arguments for.
|
||
* @returns {Function} Returns the new capped function.
|
||
*/
|
||
function baseUnary(func) {
|
||
return function(value) {
|
||
return func(value);
|
||
};
|
||
}
|
||
|
||
/**
|
||
* The base implementation of `_.values` and `_.valuesIn` which creates an
|
||
* array of `object` property values corresponding to the property names
|
||
* of `props`.
|
||
*
|
||
* @private
|
||
* @param {Object} object The object to query.
|
||
* @param {Array} props The property names to get values for.
|
||
* @returns {Object} Returns the array of property values.
|
||
*/
|
||
function baseValues(object, props) {
|
||
return arrayMap(props, function(key) {
|
||
return object[key];
|
||
});
|
||
}
|
||
|
||
/**
|
||
* Checks if a `cache` value for `key` exists.
|
||
*
|
||
* @private
|
||
* @param {Object} cache The cache to query.
|
||
* @param {string} key The key of the entry to check.
|
||
* @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
|
||
*/
|
||
function cacheHas(cache, key) {
|
||
return cache.has(key);
|
||
}
|
||
|
||
/**
|
||
* Used by `_.trim` and `_.trimStart` to get the index of the first string symbol
|
||
* that is not found in the character symbols.
|
||
*
|
||
* @private
|
||
* @param {Array} strSymbols The string symbols to inspect.
|
||
* @param {Array} chrSymbols The character symbols to find.
|
||
* @returns {number} Returns the index of the first unmatched string symbol.
|
||
*/
|
||
function charsStartIndex(strSymbols, chrSymbols) {
|
||
var index = -1,
|
||
length = strSymbols.length;
|
||
|
||
while (++index < length && baseIndexOf(chrSymbols, strSymbols[index], 0) > -1) {}
|
||
return index;
|
||
}
|
||
|
||
/**
|
||
* Used by `_.trim` and `_.trimEnd` to get the index of the last string symbol
|
||
* that is not found in the character symbols.
|
||
*
|
||
* @private
|
||
* @param {Array} strSymbols The string symbols to inspect.
|
||
* @param {Array} chrSymbols The character symbols to find.
|
||
* @returns {number} Returns the index of the last unmatched string symbol.
|
||
*/
|
||
function charsEndIndex(strSymbols, chrSymbols) {
|
||
var index = strSymbols.length;
|
||
|
||
while (index-- && baseIndexOf(chrSymbols, strSymbols[index], 0) > -1) {}
|
||
return index;
|
||
}
|
||
|
||
/**
|
||
* Gets the number of `placeholder` occurrences in `array`.
|
||
*
|
||
* @private
|
||
* @param {Array} array The array to inspect.
|
||
* @param {*} placeholder The placeholder to search for.
|
||
* @returns {number} Returns the placeholder count.
|
||
*/
|
||
function countHolders(array, placeholder) {
|
||
var length = array.length,
|
||
result = 0;
|
||
|
||
while (length--) {
|
||
if (array[length] === placeholder) {
|
||
++result;
|
||
}
|
||
}
|
||
return result;
|
||
}
|
||
|
||
/**
|
||
* Used by `_.deburr` to convert Latin-1 Supplement and Latin Extended-A
|
||
* letters to basic Latin letters.
|
||
*
|
||
* @private
|
||
* @param {string} letter The matched letter to deburr.
|
||
* @returns {string} Returns the deburred letter.
|
||
*/
|
||
var deburrLetter = basePropertyOf(deburredLetters);
|
||
|
||
/**
|
||
* Used by `_.escape` to convert characters to HTML entities.
|
||
*
|
||
* @private
|
||
* @param {string} chr The matched character to escape.
|
||
* @returns {string} Returns the escaped character.
|
||
*/
|
||
var escapeHtmlChar = basePropertyOf(htmlEscapes);
|
||
|
||
/**
|
||
* Used by `_.template` to escape characters for inclusion in compiled string literals.
|
||
*
|
||
* @private
|
||
* @param {string} chr The matched character to escape.
|
||
* @returns {string} Returns the escaped character.
|
||
*/
|
||
function escapeStringChar(chr) {
|
||
return '\\' + stringEscapes[chr];
|
||
}
|
||
|
||
/**
|
||
* Gets the value at `key` of `object`.
|
||
*
|
||
* @private
|
||
* @param {Object} [object] The object to query.
|
||
* @param {string} key The key of the property to get.
|
||
* @returns {*} Returns the property value.
|
||
*/
|
||
function getValue(object, key) {
|
||
return object == null ? undefined : object[key];
|
||
}
|
||
|
||
/**
|
||
* Checks if `string` contains Unicode symbols.
|
||
*
|
||
* @private
|
||
* @param {string} string The string to inspect.
|
||
* @returns {boolean} Returns `true` if a symbol is found, else `false`.
|
||
*/
|
||
function hasUnicode(string) {
|
||
return reHasUnicode.test(string);
|
||
}
|
||
|
||
/**
|
||
* Checks if `string` contains a word composed of Unicode symbols.
|
||
*
|
||
* @private
|
||
* @param {string} string The string to inspect.
|
||
* @returns {boolean} Returns `true` if a word is found, else `false`.
|
||
*/
|
||
function hasUnicodeWord(string) {
|
||
return reHasUnicodeWord.test(string);
|
||
}
|
||
|
||
/**
|
||
* Converts `iterator` to an array.
|
||
*
|
||
* @private
|
||
* @param {Object} iterator The iterator to convert.
|
||
* @returns {Array} Returns the converted array.
|
||
*/
|
||
function iteratorToArray(iterator) {
|
||
var data,
|
||
result = [];
|
||
|
||
while (!(data = iterator.next()).done) {
|
||
result.push(data.value);
|
||
}
|
||
return result;
|
||
}
|
||
|
||
/**
|
||
* Converts `map` to its key-value pairs.
|
||
*
|
||
* @private
|
||
* @param {Object} map The map to convert.
|
||
* @returns {Array} Returns the key-value pairs.
|
||
*/
|
||
function mapToArray(map) {
|
||
var index = -1,
|
||
result = Array(map.size);
|
||
|
||
map.forEach(function(value, key) {
|
||
result[++index] = [key, value];
|
||
});
|
||
return result;
|
||
}
|
||
|
||
/**
|
||
* Creates a unary function that invokes `func` with its argument transformed.
|
||
*
|
||
* @private
|
||
* @param {Function} func The function to wrap.
|
||
* @param {Function} transform The argument transform.
|
||
* @returns {Function} Returns the new function.
|
||
*/
|
||
function overArg(func, transform) {
|
||
return function(arg) {
|
||
return func(transform(arg));
|
||
};
|
||
}
|
||
|
||
/**
|
||
* Replaces all `placeholder` elements in `array` with an internal placeholder
|
||
* and returns an array of their indexes.
|
||
*
|
||
* @private
|
||
* @param {Array} array The array to modify.
|
||
* @param {*} placeholder The placeholder to replace.
|
||
* @returns {Array} Returns the new array of placeholder indexes.
|
||
*/
|
||
function replaceHolders(array, placeholder) {
|
||
var index = -1,
|
||
length = array.length,
|
||
resIndex = 0,
|
||
result = [];
|
||
|
||
while (++index < length) {
|
||
var value = array[index];
|
||
if (value === placeholder || value === PLACEHOLDER) {
|
||
array[index] = PLACEHOLDER;
|
||
result[resIndex++] = index;
|
||
}
|
||
}
|
||
return result;
|
||
}
|
||
|
||
/**
|
||
* Converts `set` to an array of its values.
|
||
*
|
||
* @private
|
||
* @param {Object} set The set to convert.
|
||
* @returns {Array} Returns the values.
|
||
*/
|
||
function setToArray(set) {
|
||
var index = -1,
|
||
result = Array(set.size);
|
||
|
||
set.forEach(function(value) {
|
||
result[++index] = value;
|
||
});
|
||
return result;
|
||
}
|
||
|
||
/**
|
||
* Converts `set` to its value-value pairs.
|
||
*
|
||
* @private
|
||
* @param {Object} set The set to convert.
|
||
* @returns {Array} Returns the value-value pairs.
|
||
*/
|
||
function setToPairs(set) {
|
||
var index = -1,
|
||
result = Array(set.size);
|
||
|
||
set.forEach(function(value) {
|
||
result[++index] = [value, value];
|
||
});
|
||
return result;
|
||
}
|
||
|
||
/**
|
||
* A specialized version of `_.indexOf` which performs strict equality
|
||
* comparisons of values, i.e. `===`.
|
||
*
|
||
* @private
|
||
* @param {Array} array The array to inspect.
|
||
* @param {*} value The value to search for.
|
||
* @param {number} fromIndex The index to search from.
|
||
* @returns {number} Returns the index of the matched value, else `-1`.
|
||
*/
|
||
function strictIndexOf(array, value, fromIndex) {
|
||
var index = fromIndex - 1,
|
||
length = array.length;
|
||
|
||
while (++index < length) {
|
||
if (array[index] === value) {
|
||
return index;
|
||
}
|
||
}
|
||
return -1;
|
||
}
|
||
|
||
/**
|
||
* A specialized version of `_.lastIndexOf` which performs strict equality
|
||
* comparisons of values, i.e. `===`.
|
||
*
|
||
* @private
|
||
* @param {Array} array The array to inspect.
|
||
* @param {*} value The value to search for.
|
||
* @param {number} fromIndex The index to search from.
|
||
* @returns {number} Returns the index of the matched value, else `-1`.
|
||
*/
|
||
function strictLastIndexOf(array, value, fromIndex) {
|
||
var index = fromIndex + 1;
|
||
while (index--) {
|
||
if (array[index] === value) {
|
||
return index;
|
||
}
|
||
}
|
||
return index;
|
||
}
|
||
|
||
/**
|
||
* Gets the number of symbols in `string`.
|
||
*
|
||
* @private
|
||
* @param {string} string The string to inspect.
|
||
* @returns {number} Returns the string size.
|
||
*/
|
||
function stringSize(string) {
|
||
return hasUnicode(string)
|
||
? unicodeSize(string)
|
||
: asciiSize(string);
|
||
}
|
||
|
||
/**
|
||
* Converts `string` to an array.
|
||
*
|
||
* @private
|
||
* @param {string} string The string to convert.
|
||
* @returns {Array} Returns the converted array.
|
||
*/
|
||
function stringToArray(string) {
|
||
return hasUnicode(string)
|
||
? unicodeToArray(string)
|
||
: asciiToArray(string);
|
||
}
|
||
|
||
/**
|
||
* Used by `_.unescape` to convert HTML entities to characters.
|
||
*
|
||
* @private
|
||
* @param {string} chr The matched character to unescape.
|
||
* @returns {string} Returns the unescaped character.
|
||
*/
|
||
var unescapeHtmlChar = basePropertyOf(htmlUnescapes);
|
||
|
||
/**
|
||
* Gets the size of a Unicode `string`.
|
||
*
|
||
* @private
|
||
* @param {string} string The string inspect.
|
||
* @returns {number} Returns the string size.
|
||
*/
|
||
function unicodeSize(string) {
|
||
var result = reUnicode.lastIndex = 0;
|
||
while (reUnicode.test(string)) {
|
||
++result;
|
||
}
|
||
return result;
|
||
}
|
||
|
||
/**
|
||
* Converts a Unicode `string` to an array.
|
||
*
|
||
* @private
|
||
* @param {string} string The string to convert.
|
||
* @returns {Array} Returns the converted array.
|
||
*/
|
||
function unicodeToArray(string) {
|
||
return string.match(reUnicode) || [];
|
||
}
|
||
|
||
/**
|
||
* Splits a Unicode `string` into an array of its words.
|
||
*
|
||
* @private
|
||
* @param {string} The string to inspect.
|
||
* @returns {Array} Returns the words of `string`.
|
||
*/
|
||
function unicodeWords(string) {
|
||
return string.match(reUnicodeWord) || [];
|
||
}
|
||
|
||
/*--------------------------------------------------------------------------*/
|
||
|
||
/**
|
||
* Create a new pristine `lodash` function using the `context` object.
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 1.1.0
|
||
* @category Util
|
||
* @param {Object} [context=root] The context object.
|
||
* @returns {Function} Returns a new `lodash` function.
|
||
* @example
|
||
*
|
||
* _.mixin({ 'foo': _.constant('foo') });
|
||
*
|
||
* var lodash = _.runInContext();
|
||
* lodash.mixin({ 'bar': lodash.constant('bar') });
|
||
*
|
||
* _.isFunction(_.foo);
|
||
* // => true
|
||
* _.isFunction(_.bar);
|
||
* // => false
|
||
*
|
||
* lodash.isFunction(lodash.foo);
|
||
* // => false
|
||
* lodash.isFunction(lodash.bar);
|
||
* // => true
|
||
*
|
||
* // Create a suped-up `defer` in Node.js.
|
||
* var defer = _.runInContext({ 'setTimeout': setImmediate }).defer;
|
||
*/
|
||
var runInContext = (function runInContext(context) {
|
||
context = context == null ? root : _.defaults(root.Object(), context, _.pick(root, contextProps));
|
||
|
||
/** Built-in constructor references. */
|
||
var Array = context.Array,
|
||
Date = context.Date,
|
||
Error = context.Error,
|
||
Function = context.Function,
|
||
Math = context.Math,
|
||
Object = context.Object,
|
||
RegExp = context.RegExp,
|
||
String = context.String,
|
||
TypeError = context.TypeError;
|
||
|
||
/** Used for built-in method references. */
|
||
var arrayProto = Array.prototype,
|
||
funcProto = Function.prototype,
|
||
objectProto = Object.prototype;
|
||
|
||
/** Used to detect overreaching core-js shims. */
|
||
var coreJsData = context['__core-js_shared__'];
|
||
|
||
/** Used to resolve the decompiled source of functions. */
|
||
var funcToString = funcProto.toString;
|
||
|
||
/** Used to check objects for own properties. */
|
||
var hasOwnProperty = objectProto.hasOwnProperty;
|
||
|
||
/** Used to generate unique IDs. */
|
||
var idCounter = 0;
|
||
|
||
/** Used to detect methods masquerading as native. */
|
||
var maskSrcKey = (function() {
|
||
var uid = /[^.]+$/.exec(coreJsData && coreJsData.keys && coreJsData.keys.IE_PROTO || '');
|
||
return uid ? ('Symbol(src)_1.' + uid) : '';
|
||
}());
|
||
|
||
/**
|
||
* Used to resolve the
|
||
* [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)
|
||
* of values.
|
||
*/
|
||
var nativeObjectToString = objectProto.toString;
|
||
|
||
/** Used to infer the `Object` constructor. */
|
||
var objectCtorString = funcToString.call(Object);
|
||
|
||
/** Used to restore the original `_` reference in `_.noConflict`. */
|
||
var oldDash = root._;
|
||
|
||
/** Used to detect if a method is native. */
|
||
var reIsNative = RegExp('^' +
|
||
funcToString.call(hasOwnProperty).replace(reRegExpChar, '\\$&')
|
||
.replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$'
|
||
);
|
||
|
||
/** Built-in value references. */
|
||
var Buffer = moduleExports ? context.Buffer : undefined,
|
||
Symbol = context.Symbol,
|
||
Uint8Array = context.Uint8Array,
|
||
allocUnsafe = Buffer ? Buffer.allocUnsafe : undefined,
|
||
getPrototype = overArg(Object.getPrototypeOf, Object),
|
||
objectCreate = Object.create,
|
||
propertyIsEnumerable = objectProto.propertyIsEnumerable,
|
||
splice = arrayProto.splice,
|
||
spreadableSymbol = Symbol ? Symbol.isConcatSpreadable : undefined,
|
||
symIterator = Symbol ? Symbol.iterator : undefined,
|
||
symToStringTag = Symbol ? Symbol.toStringTag : undefined;
|
||
|
||
var defineProperty = (function() {
|
||
try {
|
||
var func = getNative(Object, 'defineProperty');
|
||
func({}, '', {});
|
||
return func;
|
||
} catch (e) {}
|
||
}());
|
||
|
||
/** Mocked built-ins. */
|
||
var ctxClearTimeout = context.clearTimeout !== root.clearTimeout && context.clearTimeout,
|
||
ctxNow = Date && Date.now !== root.Date.now && Date.now,
|
||
ctxSetTimeout = context.setTimeout !== root.setTimeout && context.setTimeout;
|
||
|
||
/* Built-in method references for those with the same name as other `lodash` methods. */
|
||
var nativeCeil = Math.ceil,
|
||
nativeFloor = Math.floor,
|
||
nativeGetSymbols = Object.getOwnPropertySymbols,
|
||
nativeIsBuffer = Buffer ? Buffer.isBuffer : undefined,
|
||
nativeIsFinite = context.isFinite,
|
||
nativeJoin = arrayProto.join,
|
||
nativeKeys = overArg(Object.keys, Object),
|
||
nativeMax = Math.max,
|
||
nativeMin = Math.min,
|
||
nativeNow = Date.now,
|
||
nativeParseInt = context.parseInt,
|
||
nativeRandom = Math.random,
|
||
nativeReverse = arrayProto.reverse;
|
||
|
||
/* Built-in method references that are verified to be native. */
|
||
var DataView = getNative(context, 'DataView'),
|
||
Map = getNative(context, 'Map'),
|
||
Promise = getNative(context, 'Promise'),
|
||
Set = getNative(context, 'Set'),
|
||
WeakMap = getNative(context, 'WeakMap'),
|
||
nativeCreate = getNative(Object, 'create');
|
||
|
||
/** Used to store function metadata. */
|
||
var metaMap = WeakMap && new WeakMap;
|
||
|
||
/** Used to lookup unminified function names. */
|
||
var realNames = {};
|
||
|
||
/** Used to detect maps, sets, and weakmaps. */
|
||
var dataViewCtorString = toSource(DataView),
|
||
mapCtorString = toSource(Map),
|
||
promiseCtorString = toSource(Promise),
|
||
setCtorString = toSource(Set),
|
||
weakMapCtorString = toSource(WeakMap);
|
||
|
||
/** Used to convert symbols to primitives and strings. */
|
||
var symbolProto = Symbol ? Symbol.prototype : undefined,
|
||
symbolValueOf = symbolProto ? symbolProto.valueOf : undefined,
|
||
symbolToString = symbolProto ? symbolProto.toString : undefined;
|
||
|
||
/*------------------------------------------------------------------------*/
|
||
|
||
/**
|
||
* Creates a `lodash` object which wraps `value` to enable implicit method
|
||
* chain sequences. Methods that operate on and return arrays, collections,
|
||
* and functions can be chained together. Methods that retrieve a single value
|
||
* or may return a primitive value will automatically end the chain sequence
|
||
* and return the unwrapped value. Otherwise, the value must be unwrapped
|
||
* with `_#value`.
|
||
*
|
||
* Explicit chain sequences, which must be unwrapped with `_#value`, may be
|
||
* enabled using `_.chain`.
|
||
*
|
||
* The execution of chained methods is lazy, that is, it's deferred until
|
||
* `_#value` is implicitly or explicitly called.
|
||
*
|
||
* Lazy evaluation allows several methods to support shortcut fusion.
|
||
* Shortcut fusion is an optimization to merge iteratee calls; this avoids
|
||
* the creation of intermediate arrays and can greatly reduce the number of
|
||
* iteratee executions. Sections of a chain sequence qualify for shortcut
|
||
* fusion if the section is applied to an array and iteratees accept only
|
||
* one argument. The heuristic for whether a section qualifies for shortcut
|
||
* fusion is subject to change.
|
||
*
|
||
* Chaining is supported in custom builds as long as the `_#value` method is
|
||
* directly or indirectly included in the build.
|
||
*
|
||
* In addition to lodash methods, wrappers have `Array` and `String` methods.
|
||
*
|
||
* The wrapper `Array` methods are:
|
||
* `concat`, `join`, `pop`, `push`, `shift`, `sort`, `splice`, and `unshift`
|
||
*
|
||
* The wrapper `String` methods are:
|
||
* `replace` and `split`
|
||
*
|
||
* The wrapper methods that support shortcut fusion are:
|
||
* `at`, `compact`, `drop`, `dropRight`, `dropWhile`, `filter`, `find`,
|
||
* `findLast`, `head`, `initial`, `last`, `map`, `reject`, `reverse`, `slice`,
|
||
* `tail`, `take`, `takeRight`, `takeRightWhile`, `takeWhile`, and `toArray`
|
||
*
|
||
* The chainable wrapper methods are:
|
||
* `after`, `ary`, `assign`, `assignIn`, `assignInWith`, `assignWith`, `at`,
|
||
* `before`, `bind`, `bindAll`, `bindKey`, `castArray`, `chain`, `chunk`,
|
||
* `commit`, `compact`, `concat`, `conforms`, `constant`, `countBy`, `create`,
|
||
* `curry`, `debounce`, `defaults`, `defaultsDeep`, `defer`, `delay`,
|
||
* `difference`, `differenceBy`, `differenceWith`, `drop`, `dropRight`,
|
||
* `dropRightWhile`, `dropWhile`, `extend`, `extendWith`, `fill`, `filter`,
|
||
* `flatMap`, `flatMapDeep`, `flatMapDepth`, `flatten`, `flattenDeep`,
|
||
* `flattenDepth`, `flip`, `flow`, `flowRight`, `fromPairs`, `functions`,
|
||
* `functionsIn`, `groupBy`, `initial`, `intersection`, `intersectionBy`,
|
||
* `intersectionWith`, `invert`, `invertBy`, `invokeMap`, `iteratee`, `keyBy`,
|
||
* `keys`, `keysIn`, `map`, `mapKeys`, `mapValues`, `matches`, `matchesProperty`,
|
||
* `memoize`, `merge`, `mergeWith`, `method`, `methodOf`, `mixin`, `negate`,
|
||
* `nthArg`, `omit`, `omitBy`, `once`, `orderBy`, `over`, `overArgs`,
|
||
* `overEvery`, `overSome`, `partial`, `partialRight`, `partition`, `pick`,
|
||
* `pickBy`, `plant`, `property`, `propertyOf`, `pull`, `pullAll`, `pullAllBy`,
|
||
* `pullAllWith`, `pullAt`, `push`, `range`, `rangeRight`, `rearg`, `reject`,
|
||
* `remove`, `rest`, `reverse`, `sampleSize`, `set`, `setWith`, `shuffle`,
|
||
* `slice`, `sort`, `sortBy`, `splice`, `spread`, `tail`, `take`, `takeRight`,
|
||
* `takeRightWhile`, `takeWhile`, `tap`, `throttle`, `thru`, `toArray`,
|
||
* `toPairs`, `toPairsIn`, `toPath`, `toPlainObject`, `transform`, `unary`,
|
||
* `union`, `unionBy`, `unionWith`, `uniq`, `uniqBy`, `uniqWith`, `unset`,
|
||
* `unshift`, `unzip`, `unzipWith`, `update`, `updateWith`, `values`,
|
||
* `valuesIn`, `without`, `wrap`, `xor`, `xorBy`, `xorWith`, `zip`,
|
||
* `zipObject`, `zipObjectDeep`, and `zipWith`
|
||
*
|
||
* The wrapper methods that are **not** chainable by default are:
|
||
* `add`, `attempt`, `camelCase`, `capitalize`, `ceil`, `clamp`, `clone`,
|
||
* `cloneDeep`, `cloneDeepWith`, `cloneWith`, `conformsTo`, `deburr`,
|
||
* `defaultTo`, `divide`, `each`, `eachRight`, `endsWith`, `eq`, `escape`,
|
||
* `escapeRegExp`, `every`, `find`, `findIndex`, `findKey`, `findLast`,
|
||
* `findLastIndex`, `findLastKey`, `first`, `floor`, `forEach`, `forEachRight`,
|
||
* `forIn`, `forInRight`, `forOwn`, `forOwnRight`, `get`, `gt`, `gte`, `has`,
|
||
* `hasIn`, `head`, `identity`, `includes`, `indexOf`, `inRange`, `invoke`,
|
||
* `isArguments`, `isArray`, `isArrayBuffer`, `isArrayLike`, `isArrayLikeObject`,
|
||
* `isBoolean`, `isBuffer`, `isDate`, `isElement`, `isEmpty`, `isEqual`,
|
||
* `isEqualWith`, `isError`, `isFinite`, `isFunction`, `isInteger`, `isLength`,
|
||
* `isMap`, `isMatch`, `isMatchWith`, `isNaN`, `isNative`, `isNil`, `isNull`,
|
||
* `isNumber`, `isObject`, `isObjectLike`, `isPlainObject`, `isRegExp`,
|
||
* `isSafeInteger`, `isSet`, `isString`, `isUndefined`, `isTypedArray`,
|
||
* `isWeakMap`, `isWeakSet`, `join`, `kebabCase`, `last`, `lastIndexOf`,
|
||
* `lowerCase`, `lowerFirst`, `lt`, `lte`, `max`, `maxBy`, `mean`, `meanBy`,
|
||
* `min`, `minBy`, `multiply`, `noConflict`, `noop`, `now`, `nth`, `pad`,
|
||
* `padEnd`, `padStart`, `parseInt`, `pop`, `random`, `reduce`, `reduceRight`,
|
||
* `repeat`, `result`, `round`, `runInContext`, `sample`, `shift`, `size`,
|
||
* `snakeCase`, `some`, `sortedIndex`, `sortedIndexBy`, `sortedLastIndex`,
|
||
* `sortedLastIndexBy`, `startCase`, `startsWith`, `stubArray`, `stubFalse`,
|
||
* `stubObject`, `stubString`, `stubTrue`, `subtract`, `sum`, `sumBy`,
|
||
* `template`, `times`, `toFinite`, `toInteger`, `toJSON`, `toLength`,
|
||
* `toLower`, `toNumber`, `toSafeInteger`, `toString`, `toUpper`, `trim`,
|
||
* `trimEnd`, `trimStart`, `truncate`, `unescape`, `uniqueId`, `upperCase`,
|
||
* `upperFirst`, `value`, and `words`
|
||
*
|
||
* @name _
|
||
* @constructor
|
||
* @category Seq
|
||
* @param {*} value The value to wrap in a `lodash` instance.
|
||
* @returns {Object} Returns the new `lodash` wrapper instance.
|
||
* @example
|
||
*
|
||
* function square(n) {
|
||
* return n * n;
|
||
* }
|
||
*
|
||
* var wrapped = _([1, 2, 3]);
|
||
*
|
||
* // Returns an unwrapped value.
|
||
* wrapped.reduce(_.add);
|
||
* // => 6
|
||
*
|
||
* // Returns a wrapped value.
|
||
* var squares = wrapped.map(square);
|
||
*
|
||
* _.isArray(squares);
|
||
* // => false
|
||
*
|
||
* _.isArray(squares.value());
|
||
* // => true
|
||
*/
|
||
function lodash(value) {
|
||
if (isObjectLike(value) && !isArray(value) && !(value instanceof LazyWrapper)) {
|
||
if (value instanceof LodashWrapper) {
|
||
return value;
|
||
}
|
||
if (hasOwnProperty.call(value, '__wrapped__')) {
|
||
return wrapperClone(value);
|
||
}
|
||
}
|
||
return new LodashWrapper(value);
|
||
}
|
||
|
||
/**
|
||
* The base implementation of `_.create` without support for assigning
|
||
* properties to the created object.
|
||
*
|
||
* @private
|
||
* @param {Object} proto The object to inherit from.
|
||
* @returns {Object} Returns the new object.
|
||
*/
|
||
var baseCreate = (function() {
|
||
function object() {}
|
||
return function(proto) {
|
||
if (!isObject(proto)) {
|
||
return {};
|
||
}
|
||
if (objectCreate) {
|
||
return objectCreate(proto);
|
||
}
|
||
object.prototype = proto;
|
||
var result = new object;
|
||
object.prototype = undefined;
|
||
return result;
|
||
};
|
||
}());
|
||
|
||
/**
|
||
* The function whose prototype chain sequence wrappers inherit from.
|
||
*
|
||
* @private
|
||
*/
|
||
function baseLodash() {
|
||
// No operation performed.
|
||
}
|
||
|
||
/**
|
||
* The base constructor for creating `lodash` wrapper objects.
|
||
*
|
||
* @private
|
||
* @param {*} value The value to wrap.
|
||
* @param {boolean} [chainAll] Enable explicit method chain sequences.
|
||
*/
|
||
function LodashWrapper(value, chainAll) {
|
||
this.__wrapped__ = value;
|
||
this.__actions__ = [];
|
||
this.__chain__ = !!chainAll;
|
||
this.__index__ = 0;
|
||
this.__values__ = undefined;
|
||
}
|
||
|
||
/**
|
||
* By default, the template delimiters used by lodash are like those in
|
||
* embedded Ruby (ERB) as well as ES2015 template strings. Change the
|
||
* following template settings to use alternative delimiters.
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @type {Object}
|
||
*/
|
||
lodash.templateSettings = {
|
||
|
||
/**
|
||
* Used to detect `data` property values to be HTML-escaped.
|
||
*
|
||
* @memberOf _.templateSettings
|
||
* @type {RegExp}
|
||
*/
|
||
'escape': reEscape,
|
||
|
||
/**
|
||
* Used to detect code to be evaluated.
|
||
*
|
||
* @memberOf _.templateSettings
|
||
* @type {RegExp}
|
||
*/
|
||
'evaluate': reEvaluate,
|
||
|
||
/**
|
||
* Used to detect `data` property values to inject.
|
||
*
|
||
* @memberOf _.templateSettings
|
||
* @type {RegExp}
|
||
*/
|
||
'interpolate': reInterpolate,
|
||
|
||
/**
|
||
* Used to reference the data object in the template text.
|
||
*
|
||
* @memberOf _.templateSettings
|
||
* @type {string}
|
||
*/
|
||
'variable': '',
|
||
|
||
/**
|
||
* Used to import variables into the compiled template.
|
||
*
|
||
* @memberOf _.templateSettings
|
||
* @type {Object}
|
||
*/
|
||
'imports': {
|
||
|
||
/**
|
||
* A reference to the `lodash` function.
|
||
*
|
||
* @memberOf _.templateSettings.imports
|
||
* @type {Function}
|
||
*/
|
||
'_': lodash
|
||
}
|
||
};
|
||
|
||
// Ensure wrappers are instances of `baseLodash`.
|
||
lodash.prototype = baseLodash.prototype;
|
||
lodash.prototype.constructor = lodash;
|
||
|
||
LodashWrapper.prototype = baseCreate(baseLodash.prototype);
|
||
LodashWrapper.prototype.constructor = LodashWrapper;
|
||
|
||
/*------------------------------------------------------------------------*/
|
||
|
||
/**
|
||
* Creates a lazy wrapper object which wraps `value` to enable lazy evaluation.
|
||
*
|
||
* @private
|
||
* @constructor
|
||
* @param {*} value The value to wrap.
|
||
*/
|
||
function LazyWrapper(value) {
|
||
this.__wrapped__ = value;
|
||
this.__actions__ = [];
|
||
this.__dir__ = 1;
|
||
this.__filtered__ = false;
|
||
this.__iteratees__ = [];
|
||
this.__takeCount__ = MAX_ARRAY_LENGTH;
|
||
this.__views__ = [];
|
||
}
|
||
|
||
/**
|
||
* Creates a clone of the lazy wrapper object.
|
||
*
|
||
* @private
|
||
* @name clone
|
||
* @memberOf LazyWrapper
|
||
* @returns {Object} Returns the cloned `LazyWrapper` object.
|
||
*/
|
||
function lazyClone() {
|
||
var result = new LazyWrapper(this.__wrapped__);
|
||
result.__actions__ = copyArray(this.__actions__);
|
||
result.__dir__ = this.__dir__;
|
||
result.__filtered__ = this.__filtered__;
|
||
result.__iteratees__ = copyArray(this.__iteratees__);
|
||
result.__takeCount__ = this.__takeCount__;
|
||
result.__views__ = copyArray(this.__views__);
|
||
return result;
|
||
}
|
||
|
||
/**
|
||
* Reverses the direction of lazy iteration.
|
||
*
|
||
* @private
|
||
* @name reverse
|
||
* @memberOf LazyWrapper
|
||
* @returns {Object} Returns the new reversed `LazyWrapper` object.
|
||
*/
|
||
function lazyReverse() {
|
||
if (this.__filtered__) {
|
||
var result = new LazyWrapper(this);
|
||
result.__dir__ = -1;
|
||
result.__filtered__ = true;
|
||
} else {
|
||
result = this.clone();
|
||
result.__dir__ *= -1;
|
||
}
|
||
return result;
|
||
}
|
||
|
||
/**
|
||
* Extracts the unwrapped value from its lazy wrapper.
|
||
*
|
||
* @private
|
||
* @name value
|
||
* @memberOf LazyWrapper
|
||
* @returns {*} Returns the unwrapped value.
|
||
*/
|
||
function lazyValue() {
|
||
var array = this.__wrapped__.value(),
|
||
dir = this.__dir__,
|
||
isArr = isArray(array),
|
||
isRight = dir < 0,
|
||
arrLength = isArr ? array.length : 0,
|
||
view = getView(0, arrLength, this.__views__),
|
||
start = view.start,
|
||
end = view.end,
|
||
length = end - start,
|
||
index = isRight ? end : (start - 1),
|
||
iteratees = this.__iteratees__,
|
||
iterLength = iteratees.length,
|
||
resIndex = 0,
|
||
takeCount = nativeMin(length, this.__takeCount__);
|
||
|
||
if (!isArr || (!isRight && arrLength == length && takeCount == length)) {
|
||
return baseWrapperValue(array, this.__actions__);
|
||
}
|
||
var result = [];
|
||
|
||
outer:
|
||
while (length-- && resIndex < takeCount) {
|
||
index += dir;
|
||
|
||
var iterIndex = -1,
|
||
value = array[index];
|
||
|
||
while (++iterIndex < iterLength) {
|
||
var data = iteratees[iterIndex],
|
||
iteratee = data.iteratee,
|
||
type = data.type,
|
||
computed = iteratee(value);
|
||
|
||
if (type == LAZY_MAP_FLAG) {
|
||
value = computed;
|
||
} else if (!computed) {
|
||
if (type == LAZY_FILTER_FLAG) {
|
||
continue outer;
|
||
} else {
|
||
break outer;
|
||
}
|
||
}
|
||
}
|
||
result[resIndex++] = value;
|
||
}
|
||
return result;
|
||
}
|
||
|
||
// Ensure `LazyWrapper` is an instance of `baseLodash`.
|
||
LazyWrapper.prototype = baseCreate(baseLodash.prototype);
|
||
LazyWrapper.prototype.constructor = LazyWrapper;
|
||
|
||
/*------------------------------------------------------------------------*/
|
||
|
||
/**
|
||
* Creates a hash object.
|
||
*
|
||
* @private
|
||
* @constructor
|
||
* @param {Array} [entries] The key-value pairs to cache.
|
||
*/
|
||
function Hash(entries) {
|
||
var index = -1,
|
||
length = entries == null ? 0 : entries.length;
|
||
|
||
this.clear();
|
||
while (++index < length) {
|
||
var entry = entries[index];
|
||
this.set(entry[0], entry[1]);
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Removes all key-value entries from the hash.
|
||
*
|
||
* @private
|
||
* @name clear
|
||
* @memberOf Hash
|
||
*/
|
||
function hashClear() {
|
||
this.__data__ = nativeCreate ? nativeCreate(null) : {};
|
||
this.size = 0;
|
||
}
|
||
|
||
/**
|
||
* Removes `key` and its value from the hash.
|
||
*
|
||
* @private
|
||
* @name delete
|
||
* @memberOf Hash
|
||
* @param {Object} hash The hash to modify.
|
||
* @param {string} key The key of the value to remove.
|
||
* @returns {boolean} Returns `true` if the entry was removed, else `false`.
|
||
*/
|
||
function hashDelete(key) {
|
||
var result = this.has(key) && delete this.__data__[key];
|
||
this.size -= result ? 1 : 0;
|
||
return result;
|
||
}
|
||
|
||
/**
|
||
* Gets the hash value for `key`.
|
||
*
|
||
* @private
|
||
* @name get
|
||
* @memberOf Hash
|
||
* @param {string} key The key of the value to get.
|
||
* @returns {*} Returns the entry value.
|
||
*/
|
||
function hashGet(key) {
|
||
var data = this.__data__;
|
||
if (nativeCreate) {
|
||
var result = data[key];
|
||
return result === HASH_UNDEFINED ? undefined : result;
|
||
}
|
||
return hasOwnProperty.call(data, key) ? data[key] : undefined;
|
||
}
|
||
|
||
/**
|
||
* Checks if a hash value for `key` exists.
|
||
*
|
||
* @private
|
||
* @name has
|
||
* @memberOf Hash
|
||
* @param {string} key The key of the entry to check.
|
||
* @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
|
||
*/
|
||
function hashHas(key) {
|
||
var data = this.__data__;
|
||
return nativeCreate ? (data[key] !== undefined) : hasOwnProperty.call(data, key);
|
||
}
|
||
|
||
/**
|
||
* Sets the hash `key` to `value`.
|
||
*
|
||
* @private
|
||
* @name set
|
||
* @memberOf Hash
|
||
* @param {string} key The key of the value to set.
|
||
* @param {*} value The value to set.
|
||
* @returns {Object} Returns the hash instance.
|
||
*/
|
||
function hashSet(key, value) {
|
||
var data = this.__data__;
|
||
this.size += this.has(key) ? 0 : 1;
|
||
data[key] = (nativeCreate && value === undefined) ? HASH_UNDEFINED : value;
|
||
return this;
|
||
}
|
||
|
||
// Add methods to `Hash`.
|
||
Hash.prototype.clear = hashClear;
|
||
Hash.prototype['delete'] = hashDelete;
|
||
Hash.prototype.get = hashGet;
|
||
Hash.prototype.has = hashHas;
|
||
Hash.prototype.set = hashSet;
|
||
|
||
/*------------------------------------------------------------------------*/
|
||
|
||
/**
|
||
* Creates an list cache object.
|
||
*
|
||
* @private
|
||
* @constructor
|
||
* @param {Array} [entries] The key-value pairs to cache.
|
||
*/
|
||
function ListCache(entries) {
|
||
var index = -1,
|
||
length = entries == null ? 0 : entries.length;
|
||
|
||
this.clear();
|
||
while (++index < length) {
|
||
var entry = entries[index];
|
||
this.set(entry[0], entry[1]);
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Removes all key-value entries from the list cache.
|
||
*
|
||
* @private
|
||
* @name clear
|
||
* @memberOf ListCache
|
||
*/
|
||
function listCacheClear() {
|
||
this.__data__ = [];
|
||
this.size = 0;
|
||
}
|
||
|
||
/**
|
||
* Removes `key` and its value from the list cache.
|
||
*
|
||
* @private
|
||
* @name delete
|
||
* @memberOf ListCache
|
||
* @param {string} key The key of the value to remove.
|
||
* @returns {boolean} Returns `true` if the entry was removed, else `false`.
|
||
*/
|
||
function listCacheDelete(key) {
|
||
var data = this.__data__,
|
||
index = assocIndexOf(data, key);
|
||
|
||
if (index < 0) {
|
||
return false;
|
||
}
|
||
var lastIndex = data.length - 1;
|
||
if (index == lastIndex) {
|
||
data.pop();
|
||
} else {
|
||
splice.call(data, index, 1);
|
||
}
|
||
--this.size;
|
||
return true;
|
||
}
|
||
|
||
/**
|
||
* Gets the list cache value for `key`.
|
||
*
|
||
* @private
|
||
* @name get
|
||
* @memberOf ListCache
|
||
* @param {string} key The key of the value to get.
|
||
* @returns {*} Returns the entry value.
|
||
*/
|
||
function listCacheGet(key) {
|
||
var data = this.__data__,
|
||
index = assocIndexOf(data, key);
|
||
|
||
return index < 0 ? undefined : data[index][1];
|
||
}
|
||
|
||
/**
|
||
* Checks if a list cache value for `key` exists.
|
||
*
|
||
* @private
|
||
* @name has
|
||
* @memberOf ListCache
|
||
* @param {string} key The key of the entry to check.
|
||
* @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
|
||
*/
|
||
function listCacheHas(key) {
|
||
return assocIndexOf(this.__data__, key) > -1;
|
||
}
|
||
|
||
/**
|
||
* Sets the list cache `key` to `value`.
|
||
*
|
||
* @private
|
||
* @name set
|
||
* @memberOf ListCache
|
||
* @param {string} key The key of the value to set.
|
||
* @param {*} value The value to set.
|
||
* @returns {Object} Returns the list cache instance.
|
||
*/
|
||
function listCacheSet(key, value) {
|
||
var data = this.__data__,
|
||
index = assocIndexOf(data, key);
|
||
|
||
if (index < 0) {
|
||
++this.size;
|
||
data.push([key, value]);
|
||
} else {
|
||
data[index][1] = value;
|
||
}
|
||
return this;
|
||
}
|
||
|
||
// Add methods to `ListCache`.
|
||
ListCache.prototype.clear = listCacheClear;
|
||
ListCache.prototype['delete'] = listCacheDelete;
|
||
ListCache.prototype.get = listCacheGet;
|
||
ListCache.prototype.has = listCacheHas;
|
||
ListCache.prototype.set = listCacheSet;
|
||
|
||
/*------------------------------------------------------------------------*/
|
||
|
||
/**
|
||
* Creates a map cache object to store key-value pairs.
|
||
*
|
||
* @private
|
||
* @constructor
|
||
* @param {Array} [entries] The key-value pairs to cache.
|
||
*/
|
||
function MapCache(entries) {
|
||
var index = -1,
|
||
length = entries == null ? 0 : entries.length;
|
||
|
||
this.clear();
|
||
while (++index < length) {
|
||
var entry = entries[index];
|
||
this.set(entry[0], entry[1]);
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Removes all key-value entries from the map.
|
||
*
|
||
* @private
|
||
* @name clear
|
||
* @memberOf MapCache
|
||
*/
|
||
function mapCacheClear() {
|
||
this.size = 0;
|
||
this.__data__ = {
|
||
'hash': new Hash,
|
||
'map': new (Map || ListCache),
|
||
'string': new Hash
|
||
};
|
||
}
|
||
|
||
/**
|
||
* Removes `key` and its value from the map.
|
||
*
|
||
* @private
|
||
* @name delete
|
||
* @memberOf MapCache
|
||
* @param {string} key The key of the value to remove.
|
||
* @returns {boolean} Returns `true` if the entry was removed, else `false`.
|
||
*/
|
||
function mapCacheDelete(key) {
|
||
var result = getMapData(this, key)['delete'](key);
|
||
this.size -= result ? 1 : 0;
|
||
return result;
|
||
}
|
||
|
||
/**
|
||
* Gets the map value for `key`.
|
||
*
|
||
* @private
|
||
* @name get
|
||
* @memberOf MapCache
|
||
* @param {string} key The key of the value to get.
|
||
* @returns {*} Returns the entry value.
|
||
*/
|
||
function mapCacheGet(key) {
|
||
return getMapData(this, key).get(key);
|
||
}
|
||
|
||
/**
|
||
* Checks if a map value for `key` exists.
|
||
*
|
||
* @private
|
||
* @name has
|
||
* @memberOf MapCache
|
||
* @param {string} key The key of the entry to check.
|
||
* @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
|
||
*/
|
||
function mapCacheHas(key) {
|
||
return getMapData(this, key).has(key);
|
||
}
|
||
|
||
/**
|
||
* Sets the map `key` to `value`.
|
||
*
|
||
* @private
|
||
* @name set
|
||
* @memberOf MapCache
|
||
* @param {string} key The key of the value to set.
|
||
* @param {*} value The value to set.
|
||
* @returns {Object} Returns the map cache instance.
|
||
*/
|
||
function mapCacheSet(key, value) {
|
||
var data = getMapData(this, key),
|
||
size = data.size;
|
||
|
||
data.set(key, value);
|
||
this.size += data.size == size ? 0 : 1;
|
||
return this;
|
||
}
|
||
|
||
// Add methods to `MapCache`.
|
||
MapCache.prototype.clear = mapCacheClear;
|
||
MapCache.prototype['delete'] = mapCacheDelete;
|
||
MapCache.prototype.get = mapCacheGet;
|
||
MapCache.prototype.has = mapCacheHas;
|
||
MapCache.prototype.set = mapCacheSet;
|
||
|
||
/*------------------------------------------------------------------------*/
|
||
|
||
/**
|
||
*
|
||
* Creates an array cache object to store unique values.
|
||
*
|
||
* @private
|
||
* @constructor
|
||
* @param {Array} [values] The values to cache.
|
||
*/
|
||
function SetCache(values) {
|
||
var index = -1,
|
||
length = values == null ? 0 : values.length;
|
||
|
||
this.__data__ = new MapCache;
|
||
while (++index < length) {
|
||
this.add(values[index]);
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Adds `value` to the array cache.
|
||
*
|
||
* @private
|
||
* @name add
|
||
* @memberOf SetCache
|
||
* @alias push
|
||
* @param {*} value The value to cache.
|
||
* @returns {Object} Returns the cache instance.
|
||
*/
|
||
function setCacheAdd(value) {
|
||
this.__data__.set(value, HASH_UNDEFINED);
|
||
return this;
|
||
}
|
||
|
||
/**
|
||
* Checks if `value` is in the array cache.
|
||
*
|
||
* @private
|
||
* @name has
|
||
* @memberOf SetCache
|
||
* @param {*} value The value to search for.
|
||
* @returns {number} Returns `true` if `value` is found, else `false`.
|
||
*/
|
||
function setCacheHas(value) {
|
||
return this.__data__.has(value);
|
||
}
|
||
|
||
// Add methods to `SetCache`.
|
||
SetCache.prototype.add = SetCache.prototype.push = setCacheAdd;
|
||
SetCache.prototype.has = setCacheHas;
|
||
|
||
/*------------------------------------------------------------------------*/
|
||
|
||
/**
|
||
* Creates a stack cache object to store key-value pairs.
|
||
*
|
||
* @private
|
||
* @constructor
|
||
* @param {Array} [entries] The key-value pairs to cache.
|
||
*/
|
||
function Stack(entries) {
|
||
var data = this.__data__ = new ListCache(entries);
|
||
this.size = data.size;
|
||
}
|
||
|
||
/**
|
||
* Removes all key-value entries from the stack.
|
||
*
|
||
* @private
|
||
* @name clear
|
||
* @memberOf Stack
|
||
*/
|
||
function stackClear() {
|
||
this.__data__ = new ListCache;
|
||
this.size = 0;
|
||
}
|
||
|
||
/**
|
||
* Removes `key` and its value from the stack.
|
||
*
|
||
* @private
|
||
* @name delete
|
||
* @memberOf Stack
|
||
* @param {string} key The key of the value to remove.
|
||
* @returns {boolean} Returns `true` if the entry was removed, else `false`.
|
||
*/
|
||
function stackDelete(key) {
|
||
var data = this.__data__,
|
||
result = data['delete'](key);
|
||
|
||
this.size = data.size;
|
||
return result;
|
||
}
|
||
|
||
/**
|
||
* Gets the stack value for `key`.
|
||
*
|
||
* @private
|
||
* @name get
|
||
* @memberOf Stack
|
||
* @param {string} key The key of the value to get.
|
||
* @returns {*} Returns the entry value.
|
||
*/
|
||
function stackGet(key) {
|
||
return this.__data__.get(key);
|
||
}
|
||
|
||
/**
|
||
* Checks if a stack value for `key` exists.
|
||
*
|
||
* @private
|
||
* @name has
|
||
* @memberOf Stack
|
||
* @param {string} key The key of the entry to check.
|
||
* @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
|
||
*/
|
||
function stackHas(key) {
|
||
return this.__data__.has(key);
|
||
}
|
||
|
||
/**
|
||
* Sets the stack `key` to `value`.
|
||
*
|
||
* @private
|
||
* @name set
|
||
* @memberOf Stack
|
||
* @param {string} key The key of the value to set.
|
||
* @param {*} value The value to set.
|
||
* @returns {Object} Returns the stack cache instance.
|
||
*/
|
||
function stackSet(key, value) {
|
||
var data = this.__data__;
|
||
if (data instanceof ListCache) {
|
||
var pairs = data.__data__;
|
||
if (!Map || (pairs.length < LARGE_ARRAY_SIZE - 1)) {
|
||
pairs.push([key, value]);
|
||
this.size = ++data.size;
|
||
return this;
|
||
}
|
||
data = this.__data__ = new MapCache(pairs);
|
||
}
|
||
data.set(key, value);
|
||
this.size = data.size;
|
||
return this;
|
||
}
|
||
|
||
// Add methods to `Stack`.
|
||
Stack.prototype.clear = stackClear;
|
||
Stack.prototype['delete'] = stackDelete;
|
||
Stack.prototype.get = stackGet;
|
||
Stack.prototype.has = stackHas;
|
||
Stack.prototype.set = stackSet;
|
||
|
||
/*------------------------------------------------------------------------*/
|
||
|
||
/**
|
||
* Creates an array of the enumerable property names of the array-like `value`.
|
||
*
|
||
* @private
|
||
* @param {*} value The value to query.
|
||
* @param {boolean} inherited Specify returning inherited property names.
|
||
* @returns {Array} Returns the array of property names.
|
||
*/
|
||
function arrayLikeKeys(value, inherited) {
|
||
var isArr = isArray(value),
|
||
isArg = !isArr && isArguments(value),
|
||
isBuff = !isArr && !isArg && isBuffer(value),
|
||
isType = !isArr && !isArg && !isBuff && isTypedArray(value),
|
||
skipIndexes = isArr || isArg || isBuff || isType,
|
||
result = skipIndexes ? baseTimes(value.length, String) : [],
|
||
length = result.length;
|
||
|
||
for (var key in value) {
|
||
if ((inherited || hasOwnProperty.call(value, key)) &&
|
||
!(skipIndexes && (
|
||
// Safari 9 has enumerable `arguments.length` in strict mode.
|
||
key == 'length' ||
|
||
// Node.js 0.10 has enumerable non-index properties on buffers.
|
||
(isBuff && (key == 'offset' || key == 'parent')) ||
|
||
// PhantomJS 2 has enumerable non-index properties on typed arrays.
|
||
(isType && (key == 'buffer' || key == 'byteLength' || key == 'byteOffset')) ||
|
||
// Skip index properties.
|
||
isIndex(key, length)
|
||
))) {
|
||
result.push(key);
|
||
}
|
||
}
|
||
return result;
|
||
}
|
||
|
||
/**
|
||
* A specialized version of `_.sample` for arrays.
|
||
*
|
||
* @private
|
||
* @param {Array} array The array to sample.
|
||
* @returns {*} Returns the random element.
|
||
*/
|
||
function arraySample(array) {
|
||
var length = array.length;
|
||
return length ? array[baseRandom(0, length - 1)] : undefined;
|
||
}
|
||
|
||
/**
|
||
* A specialized version of `_.sampleSize` for arrays.
|
||
*
|
||
* @private
|
||
* @param {Array} array The array to sample.
|
||
* @param {number} n The number of elements to sample.
|
||
* @returns {Array} Returns the random elements.
|
||
*/
|
||
function arraySampleSize(array, n) {
|
||
return shuffleSelf(copyArray(array), baseClamp(n, 0, array.length));
|
||
}
|
||
|
||
/**
|
||
* A specialized version of `_.shuffle` for arrays.
|
||
*
|
||
* @private
|
||
* @param {Array} array The array to shuffle.
|
||
* @returns {Array} Returns the new shuffled array.
|
||
*/
|
||
function arrayShuffle(array) {
|
||
return shuffleSelf(copyArray(array));
|
||
}
|
||
|
||
/**
|
||
* This function is like `assignValue` except that it doesn't assign
|
||
* `undefined` values.
|
||
*
|
||
* @private
|
||
* @param {Object} object The object to modify.
|
||
* @param {string} key The key of the property to assign.
|
||
* @param {*} value The value to assign.
|
||
*/
|
||
function assignMergeValue(object, key, value) {
|
||
if ((value !== undefined && !eq(object[key], value)) ||
|
||
(value === undefined && !(key in object))) {
|
||
baseAssignValue(object, key, value);
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Assigns `value` to `key` of `object` if the existing value is not equivalent
|
||
* using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
|
||
* for equality comparisons.
|
||
*
|
||
* @private
|
||
* @param {Object} object The object to modify.
|
||
* @param {string} key The key of the property to assign.
|
||
* @param {*} value The value to assign.
|
||
*/
|
||
function assignValue(object, key, value) {
|
||
var objValue = object[key];
|
||
if (!(hasOwnProperty.call(object, key) && eq(objValue, value)) ||
|
||
(value === undefined && !(key in object))) {
|
||
baseAssignValue(object, key, value);
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Gets the index at which the `key` is found in `array` of key-value pairs.
|
||
*
|
||
* @private
|
||
* @param {Array} array The array to inspect.
|
||
* @param {*} key The key to search for.
|
||
* @returns {number} Returns the index of the matched value, else `-1`.
|
||
*/
|
||
function assocIndexOf(array, key) {
|
||
var length = array.length;
|
||
while (length--) {
|
||
if (eq(array[length][0], key)) {
|
||
return length;
|
||
}
|
||
}
|
||
return -1;
|
||
}
|
||
|
||
/**
|
||
* Aggregates elements of `collection` on `accumulator` with keys transformed
|
||
* by `iteratee` and values set by `setter`.
|
||
*
|
||
* @private
|
||
* @param {Array|Object} collection The collection to iterate over.
|
||
* @param {Function} setter The function to set `accumulator` values.
|
||
* @param {Function} iteratee The iteratee to transform keys.
|
||
* @param {Object} accumulator The initial aggregated object.
|
||
* @returns {Function} Returns `accumulator`.
|
||
*/
|
||
function baseAggregator(collection, setter, iteratee, accumulator) {
|
||
baseEach(collection, function(value, key, collection) {
|
||
setter(accumulator, value, iteratee(value), collection);
|
||
});
|
||
return accumulator;
|
||
}
|
||
|
||
/**
|
||
* The base implementation of `_.assign` without support for multiple sources
|
||
* or `customizer` functions.
|
||
*
|
||
* @private
|
||
* @param {Object} object The destination object.
|
||
* @param {Object} source The source object.
|
||
* @returns {Object} Returns `object`.
|
||
*/
|
||
function baseAssign(object, source) {
|
||
return object && copyObject(source, keys(source), object);
|
||
}
|
||
|
||
/**
|
||
* The base implementation of `_.assignIn` without support for multiple sources
|
||
* or `customizer` functions.
|
||
*
|
||
* @private
|
||
* @param {Object} object The destination object.
|
||
* @param {Object} source The source object.
|
||
* @returns {Object} Returns `object`.
|
||
*/
|
||
function baseAssignIn(object, source) {
|
||
return object && copyObject(source, keysIn(source), object);
|
||
}
|
||
|
||
/**
|
||
* The base implementation of `assignValue` and `assignMergeValue` without
|
||
* value checks.
|
||
*
|
||
* @private
|
||
* @param {Object} object The object to modify.
|
||
* @param {string} key The key of the property to assign.
|
||
* @param {*} value The value to assign.
|
||
*/
|
||
function baseAssignValue(object, key, value) {
|
||
if (key == '__proto__' && defineProperty) {
|
||
defineProperty(object, key, {
|
||
'configurable': true,
|
||
'enumerable': true,
|
||
'value': value,
|
||
'writable': true
|
||
});
|
||
} else {
|
||
object[key] = value;
|
||
}
|
||
}
|
||
|
||
/**
|
||
* The base implementation of `_.at` without support for individual paths.
|
||
*
|
||
* @private
|
||
* @param {Object} object The object to iterate over.
|
||
* @param {string[]} paths The property paths to pick.
|
||
* @returns {Array} Returns the picked elements.
|
||
*/
|
||
function baseAt(object, paths) {
|
||
var index = -1,
|
||
length = paths.length,
|
||
result = Array(length),
|
||
skip = object == null;
|
||
|
||
while (++index < length) {
|
||
result[index] = skip ? undefined : get(object, paths[index]);
|
||
}
|
||
return result;
|
||
}
|
||
|
||
/**
|
||
* The base implementation of `_.clamp` which doesn't coerce arguments.
|
||
*
|
||
* @private
|
||
* @param {number} number The number to clamp.
|
||
* @param {number} [lower] The lower bound.
|
||
* @param {number} upper The upper bound.
|
||
* @returns {number} Returns the clamped number.
|
||
*/
|
||
function baseClamp(number, lower, upper) {
|
||
if (number === number) {
|
||
if (upper !== undefined) {
|
||
number = number <= upper ? number : upper;
|
||
}
|
||
if (lower !== undefined) {
|
||
number = number >= lower ? number : lower;
|
||
}
|
||
}
|
||
return number;
|
||
}
|
||
|
||
/**
|
||
* The base implementation of `_.clone` and `_.cloneDeep` which tracks
|
||
* traversed objects.
|
||
*
|
||
* @private
|
||
* @param {*} value The value to clone.
|
||
* @param {boolean} bitmask The bitmask flags.
|
||
* 1 - Deep clone
|
||
* 2 - Flatten inherited properties
|
||
* 4 - Clone symbols
|
||
* @param {Function} [customizer] The function to customize cloning.
|
||
* @param {string} [key] The key of `value`.
|
||
* @param {Object} [object] The parent object of `value`.
|
||
* @param {Object} [stack] Tracks traversed objects and their clone counterparts.
|
||
* @returns {*} Returns the cloned value.
|
||
*/
|
||
function baseClone(value, bitmask, customizer, key, object, stack) {
|
||
var result,
|
||
isDeep = bitmask & CLONE_DEEP_FLAG,
|
||
isFlat = bitmask & CLONE_FLAT_FLAG,
|
||
isFull = bitmask & CLONE_SYMBOLS_FLAG;
|
||
|
||
if (customizer) {
|
||
result = object ? customizer(value, key, object, stack) : customizer(value);
|
||
}
|
||
if (result !== undefined) {
|
||
return result;
|
||
}
|
||
if (!isObject(value)) {
|
||
return value;
|
||
}
|
||
var isArr = isArray(value);
|
||
if (isArr) {
|
||
result = initCloneArray(value);
|
||
if (!isDeep) {
|
||
return copyArray(value, result);
|
||
}
|
||
} else {
|
||
var tag = getTag(value),
|
||
isFunc = tag == funcTag || tag == genTag;
|
||
|
||
if (isBuffer(value)) {
|
||
return cloneBuffer(value, isDeep);
|
||
}
|
||
if (tag == objectTag || tag == argsTag || (isFunc && !object)) {
|
||
result = (isFlat || isFunc) ? {} : initCloneObject(value);
|
||
if (!isDeep) {
|
||
return isFlat
|
||
? copySymbolsIn(value, baseAssignIn(result, value))
|
||
: copySymbols(value, baseAssign(result, value));
|
||
}
|
||
} else {
|
||
if (!cloneableTags[tag]) {
|
||
return object ? value : {};
|
||
}
|
||
result = initCloneByTag(value, tag, baseClone, isDeep);
|
||
}
|
||
}
|
||
// Check for circular references and return its corresponding clone.
|
||
stack || (stack = new Stack);
|
||
var stacked = stack.get(value);
|
||
if (stacked) {
|
||
return stacked;
|
||
}
|
||
stack.set(value, result);
|
||
|
||
var keysFunc = isFull
|
||
? (isFlat ? getAllKeysIn : getAllKeys)
|
||
: (isFlat ? keysIn : keys);
|
||
|
||
var props = isArr ? undefined : keysFunc(value);
|
||
arrayEach(props || value, function(subValue, key) {
|
||
if (props) {
|
||
key = subValue;
|
||
subValue = value[key];
|
||
}
|
||
// Recursively populate clone (susceptible to call stack limits).
|
||
assignValue(result, key, baseClone(subValue, bitmask, customizer, key, value, stack));
|
||
});
|
||
return result;
|
||
}
|
||
|
||
/**
|
||
* The base implementation of `_.conforms` which doesn't clone `source`.
|
||
*
|
||
* @private
|
||
* @param {Object} source The object of property predicates to conform to.
|
||
* @returns {Function} Returns the new spec function.
|
||
*/
|
||
function baseConforms(source) {
|
||
var props = keys(source);
|
||
return function(object) {
|
||
return baseConformsTo(object, source, props);
|
||
};
|
||
}
|
||
|
||
/**
|
||
* The base implementation of `_.conformsTo` which accepts `props` to check.
|
||
*
|
||
* @private
|
||
* @param {Object} object The object to inspect.
|
||
* @param {Object} source The object of property predicates to conform to.
|
||
* @returns {boolean} Returns `true` if `object` conforms, else `false`.
|
||
*/
|
||
function baseConformsTo(object, source, props) {
|
||
var length = props.length;
|
||
if (object == null) {
|
||
return !length;
|
||
}
|
||
object = Object(object);
|
||
while (length--) {
|
||
var key = props[length],
|
||
predicate = source[key],
|
||
value = object[key];
|
||
|
||
if ((value === undefined && !(key in object)) || !predicate(value)) {
|
||
return false;
|
||
}
|
||
}
|
||
return true;
|
||
}
|
||
|
||
/**
|
||
* The base implementation of `_.delay` and `_.defer` which accepts `args`
|
||
* to provide to `func`.
|
||
*
|
||
* @private
|
||
* @param {Function} func The function to delay.
|
||
* @param {number} wait The number of milliseconds to delay invocation.
|
||
* @param {Array} args The arguments to provide to `func`.
|
||
* @returns {number|Object} Returns the timer id or timeout object.
|
||
*/
|
||
function baseDelay(func, wait, args) {
|
||
if (typeof func != 'function') {
|
||
throw new TypeError(FUNC_ERROR_TEXT);
|
||
}
|
||
return setTimeout(function() { func.apply(undefined, args); }, wait);
|
||
}
|
||
|
||
/**
|
||
* The base implementation of methods like `_.difference` without support
|
||
* for excluding multiple arrays or iteratee shorthands.
|
||
*
|
||
* @private
|
||
* @param {Array} array The array to inspect.
|
||
* @param {Array} values The values to exclude.
|
||
* @param {Function} [iteratee] The iteratee invoked per element.
|
||
* @param {Function} [comparator] The comparator invoked per element.
|
||
* @returns {Array} Returns the new array of filtered values.
|
||
*/
|
||
function baseDifference(array, values, iteratee, comparator) {
|
||
var index = -1,
|
||
includes = arrayIncludes,
|
||
isCommon = true,
|
||
length = array.length,
|
||
result = [],
|
||
valuesLength = values.length;
|
||
|
||
if (!length) {
|
||
return result;
|
||
}
|
||
if (iteratee) {
|
||
values = arrayMap(values, baseUnary(iteratee));
|
||
}
|
||
if (comparator) {
|
||
includes = arrayIncludesWith;
|
||
isCommon = false;
|
||
}
|
||
else if (values.length >= LARGE_ARRAY_SIZE) {
|
||
includes = cacheHas;
|
||
isCommon = false;
|
||
values = new SetCache(values);
|
||
}
|
||
outer:
|
||
while (++index < length) {
|
||
var value = array[index],
|
||
computed = iteratee == null ? value : iteratee(value);
|
||
|
||
value = (comparator || value !== 0) ? value : 0;
|
||
if (isCommon && computed === computed) {
|
||
var valuesIndex = valuesLength;
|
||
while (valuesIndex--) {
|
||
if (values[valuesIndex] === computed) {
|
||
continue outer;
|
||
}
|
||
}
|
||
result.push(value);
|
||
}
|
||
else if (!includes(values, computed, comparator)) {
|
||
result.push(value);
|
||
}
|
||
}
|
||
return result;
|
||
}
|
||
|
||
/**
|
||
* The base implementation of `_.forEach` without support for iteratee shorthands.
|
||
*
|
||
* @private
|
||
* @param {Array|Object} collection The collection to iterate over.
|
||
* @param {Function} iteratee The function invoked per iteration.
|
||
* @returns {Array|Object} Returns `collection`.
|
||
*/
|
||
var baseEach = createBaseEach(baseForOwn);
|
||
|
||
/**
|
||
* The base implementation of `_.forEachRight` without support for iteratee shorthands.
|
||
*
|
||
* @private
|
||
* @param {Array|Object} collection The collection to iterate over.
|
||
* @param {Function} iteratee The function invoked per iteration.
|
||
* @returns {Array|Object} Returns `collection`.
|
||
*/
|
||
var baseEachRight = createBaseEach(baseForOwnRight, true);
|
||
|
||
/**
|
||
* The base implementation of `_.every` without support for iteratee shorthands.
|
||
*
|
||
* @private
|
||
* @param {Array|Object} collection The collection to iterate over.
|
||
* @param {Function} predicate The function invoked per iteration.
|
||
* @returns {boolean} Returns `true` if all elements pass the predicate check,
|
||
* else `false`
|
||
*/
|
||
function baseEvery(collection, predicate) {
|
||
var result = true;
|
||
baseEach(collection, function(value, index, collection) {
|
||
result = !!predicate(value, index, collection);
|
||
return result;
|
||
});
|
||
return result;
|
||
}
|
||
|
||
/**
|
||
* The base implementation of methods like `_.max` and `_.min` which accepts a
|
||
* `comparator` to determine the extremum value.
|
||
*
|
||
* @private
|
||
* @param {Array} array The array to iterate over.
|
||
* @param {Function} iteratee The iteratee invoked per iteration.
|
||
* @param {Function} comparator The comparator used to compare values.
|
||
* @returns {*} Returns the extremum value.
|
||
*/
|
||
function baseExtremum(array, iteratee, comparator) {
|
||
var index = -1,
|
||
length = array.length;
|
||
|
||
while (++index < length) {
|
||
var value = array[index],
|
||
current = iteratee(value);
|
||
|
||
if (current != null && (computed === undefined
|
||
? (current === current && !isSymbol(current))
|
||
: comparator(current, computed)
|
||
)) {
|
||
var computed = current,
|
||
result = value;
|
||
}
|
||
}
|
||
return result;
|
||
}
|
||
|
||
/**
|
||
* The base implementation of `_.fill` without an iteratee call guard.
|
||
*
|
||
* @private
|
||
* @param {Array} array The array to fill.
|
||
* @param {*} value The value to fill `array` with.
|
||
* @param {number} [start=0] The start position.
|
||
* @param {number} [end=array.length] The end position.
|
||
* @returns {Array} Returns `array`.
|
||
*/
|
||
function baseFill(array, value, start, end) {
|
||
var length = array.length;
|
||
|
||
start = toInteger(start);
|
||
if (start < 0) {
|
||
start = -start > length ? 0 : (length + start);
|
||
}
|
||
end = (end === undefined || end > length) ? length : toInteger(end);
|
||
if (end < 0) {
|
||
end += length;
|
||
}
|
||
end = start > end ? 0 : toLength(end);
|
||
while (start < end) {
|
||
array[start++] = value;
|
||
}
|
||
return array;
|
||
}
|
||
|
||
/**
|
||
* The base implementation of `_.filter` without support for iteratee shorthands.
|
||
*
|
||
* @private
|
||
* @param {Array|Object} collection The collection to iterate over.
|
||
* @param {Function} predicate The function invoked per iteration.
|
||
* @returns {Array} Returns the new filtered array.
|
||
*/
|
||
function baseFilter(collection, predicate) {
|
||
var result = [];
|
||
baseEach(collection, function(value, index, collection) {
|
||
if (predicate(value, index, collection)) {
|
||
result.push(value);
|
||
}
|
||
});
|
||
return result;
|
||
}
|
||
|
||
/**
|
||
* The base implementation of `_.flatten` with support for restricting flattening.
|
||
*
|
||
* @private
|
||
* @param {Array} array The array to flatten.
|
||
* @param {number} depth The maximum recursion depth.
|
||
* @param {boolean} [predicate=isFlattenable] The function invoked per iteration.
|
||
* @param {boolean} [isStrict] Restrict to values that pass `predicate` checks.
|
||
* @param {Array} [result=[]] The initial result value.
|
||
* @returns {Array} Returns the new flattened array.
|
||
*/
|
||
function baseFlatten(array, depth, predicate, isStrict, result) {
|
||
var index = -1,
|
||
length = array.length;
|
||
|
||
predicate || (predicate = isFlattenable);
|
||
result || (result = []);
|
||
|
||
while (++index < length) {
|
||
var value = array[index];
|
||
if (depth > 0 && predicate(value)) {
|
||
if (depth > 1) {
|
||
// Recursively flatten arrays (susceptible to call stack limits).
|
||
baseFlatten(value, depth - 1, predicate, isStrict, result);
|
||
} else {
|
||
arrayPush(result, value);
|
||
}
|
||
} else if (!isStrict) {
|
||
result[result.length] = value;
|
||
}
|
||
}
|
||
return result;
|
||
}
|
||
|
||
/**
|
||
* The base implementation of `baseForOwn` which iterates over `object`
|
||
* properties returned by `keysFunc` and invokes `iteratee` for each property.
|
||
* Iteratee functions may exit iteration early by explicitly returning `false`.
|
||
*
|
||
* @private
|
||
* @param {Object} object The object to iterate over.
|
||
* @param {Function} iteratee The function invoked per iteration.
|
||
* @param {Function} keysFunc The function to get the keys of `object`.
|
||
* @returns {Object} Returns `object`.
|
||
*/
|
||
var baseFor = createBaseFor();
|
||
|
||
/**
|
||
* This function is like `baseFor` except that it iterates over properties
|
||
* in the opposite order.
|
||
*
|
||
* @private
|
||
* @param {Object} object The object to iterate over.
|
||
* @param {Function} iteratee The function invoked per iteration.
|
||
* @param {Function} keysFunc The function to get the keys of `object`.
|
||
* @returns {Object} Returns `object`.
|
||
*/
|
||
var baseForRight = createBaseFor(true);
|
||
|
||
/**
|
||
* The base implementation of `_.forOwn` without support for iteratee shorthands.
|
||
*
|
||
* @private
|
||
* @param {Object} object The object to iterate over.
|
||
* @param {Function} iteratee The function invoked per iteration.
|
||
* @returns {Object} Returns `object`.
|
||
*/
|
||
function baseForOwn(object, iteratee) {
|
||
return object && baseFor(object, iteratee, keys);
|
||
}
|
||
|
||
/**
|
||
* The base implementation of `_.forOwnRight` without support for iteratee shorthands.
|
||
*
|
||
* @private
|
||
* @param {Object} object The object to iterate over.
|
||
* @param {Function} iteratee The function invoked per iteration.
|
||
* @returns {Object} Returns `object`.
|
||
*/
|
||
function baseForOwnRight(object, iteratee) {
|
||
return object && baseForRight(object, iteratee, keys);
|
||
}
|
||
|
||
/**
|
||
* The base implementation of `_.functions` which creates an array of
|
||
* `object` function property names filtered from `props`.
|
||
*
|
||
* @private
|
||
* @param {Object} object The object to inspect.
|
||
* @param {Array} props The property names to filter.
|
||
* @returns {Array} Returns the function names.
|
||
*/
|
||
function baseFunctions(object, props) {
|
||
return arrayFilter(props, function(key) {
|
||
return isFunction(object[key]);
|
||
});
|
||
}
|
||
|
||
/**
|
||
* The base implementation of `_.get` without support for default values.
|
||
*
|
||
* @private
|
||
* @param {Object} object The object to query.
|
||
* @param {Array|string} path The path of the property to get.
|
||
* @returns {*} Returns the resolved value.
|
||
*/
|
||
function baseGet(object, path) {
|
||
path = castPath(path, object);
|
||
|
||
var index = 0,
|
||
length = path.length;
|
||
|
||
while (object != null && index < length) {
|
||
object = object[toKey(path[index++])];
|
||
}
|
||
return (index && index == length) ? object : undefined;
|
||
}
|
||
|
||
/**
|
||
* The base implementation of `getAllKeys` and `getAllKeysIn` which uses
|
||
* `keysFunc` and `symbolsFunc` to get the enumerable property names and
|
||
* symbols of `object`.
|
||
*
|
||
* @private
|
||
* @param {Object} object The object to query.
|
||
* @param {Function} keysFunc The function to get the keys of `object`.
|
||
* @param {Function} symbolsFunc The function to get the symbols of `object`.
|
||
* @returns {Array} Returns the array of property names and symbols.
|
||
*/
|
||
function baseGetAllKeys(object, keysFunc, symbolsFunc) {
|
||
var result = keysFunc(object);
|
||
return isArray(object) ? result : arrayPush(result, symbolsFunc(object));
|
||
}
|
||
|
||
/**
|
||
* The base implementation of `getTag` without fallbacks for buggy environments.
|
||
*
|
||
* @private
|
||
* @param {*} value The value to query.
|
||
* @returns {string} Returns the `toStringTag`.
|
||
*/
|
||
function baseGetTag(value) {
|
||
if (value == null) {
|
||
return value === undefined ? undefinedTag : nullTag;
|
||
}
|
||
return (symToStringTag && symToStringTag in Object(value))
|
||
? getRawTag(value)
|
||
: objectToString(value);
|
||
}
|
||
|
||
/**
|
||
* The base implementation of `_.gt` which doesn't coerce arguments.
|
||
*
|
||
* @private
|
||
* @param {*} value The value to compare.
|
||
* @param {*} other The other value to compare.
|
||
* @returns {boolean} Returns `true` if `value` is greater than `other`,
|
||
* else `false`.
|
||
*/
|
||
function baseGt(value, other) {
|
||
return value > other;
|
||
}
|
||
|
||
/**
|
||
* The base implementation of `_.has` without support for deep paths.
|
||
*
|
||
* @private
|
||
* @param {Object} [object] The object to query.
|
||
* @param {Array|string} key The key to check.
|
||
* @returns {boolean} Returns `true` if `key` exists, else `false`.
|
||
*/
|
||
function baseHas(object, key) {
|
||
return object != null && hasOwnProperty.call(object, key);
|
||
}
|
||
|
||
/**
|
||
* The base implementation of `_.hasIn` without support for deep paths.
|
||
*
|
||
* @private
|
||
* @param {Object} [object] The object to query.
|
||
* @param {Array|string} key The key to check.
|
||
* @returns {boolean} Returns `true` if `key` exists, else `false`.
|
||
*/
|
||
function baseHasIn(object, key) {
|
||
return object != null && key in Object(object);
|
||
}
|
||
|
||
/**
|
||
* The base implementation of `_.inRange` which doesn't coerce arguments.
|
||
*
|
||
* @private
|
||
* @param {number} number The number to check.
|
||
* @param {number} start The start of the range.
|
||
* @param {number} end The end of the range.
|
||
* @returns {boolean} Returns `true` if `number` is in the range, else `false`.
|
||
*/
|
||
function baseInRange(number, start, end) {
|
||
return number >= nativeMin(start, end) && number < nativeMax(start, end);
|
||
}
|
||
|
||
/**
|
||
* The base implementation of methods like `_.intersection`, without support
|
||
* for iteratee shorthands, that accepts an array of arrays to inspect.
|
||
*
|
||
* @private
|
||
* @param {Array} arrays The arrays to inspect.
|
||
* @param {Function} [iteratee] The iteratee invoked per element.
|
||
* @param {Function} [comparator] The comparator invoked per element.
|
||
* @returns {Array} Returns the new array of shared values.
|
||
*/
|
||
function baseIntersection(arrays, iteratee, comparator) {
|
||
var includes = comparator ? arrayIncludesWith : arrayIncludes,
|
||
length = arrays[0].length,
|
||
othLength = arrays.length,
|
||
othIndex = othLength,
|
||
caches = Array(othLength),
|
||
maxLength = Infinity,
|
||
result = [];
|
||
|
||
while (othIndex--) {
|
||
var array = arrays[othIndex];
|
||
if (othIndex && iteratee) {
|
||
array = arrayMap(array, baseUnary(iteratee));
|
||
}
|
||
maxLength = nativeMin(array.length, maxLength);
|
||
caches[othIndex] = !comparator && (iteratee || (length >= 120 && array.length >= 120))
|
||
? new SetCache(othIndex && array)
|
||
: undefined;
|
||
}
|
||
array = arrays[0];
|
||
|
||
var index = -1,
|
||
seen = caches[0];
|
||
|
||
outer:
|
||
while (++index < length && result.length < maxLength) {
|
||
var value = array[index],
|
||
computed = iteratee ? iteratee(value) : value;
|
||
|
||
value = (comparator || value !== 0) ? value : 0;
|
||
if (!(seen
|
||
? cacheHas(seen, computed)
|
||
: includes(result, computed, comparator)
|
||
)) {
|
||
othIndex = othLength;
|
||
while (--othIndex) {
|
||
var cache = caches[othIndex];
|
||
if (!(cache
|
||
? cacheHas(cache, computed)
|
||
: includes(arrays[othIndex], computed, comparator))
|
||
) {
|
||
continue outer;
|
||
}
|
||
}
|
||
if (seen) {
|
||
seen.push(computed);
|
||
}
|
||
result.push(value);
|
||
}
|
||
}
|
||
return result;
|
||
}
|
||
|
||
/**
|
||
* The base implementation of `_.invert` and `_.invertBy` which inverts
|
||
* `object` with values transformed by `iteratee` and set by `setter`.
|
||
*
|
||
* @private
|
||
* @param {Object} object The object to iterate over.
|
||
* @param {Function} setter The function to set `accumulator` values.
|
||
* @param {Function} iteratee The iteratee to transform values.
|
||
* @param {Object} accumulator The initial inverted object.
|
||
* @returns {Function} Returns `accumulator`.
|
||
*/
|
||
function baseInverter(object, setter, iteratee, accumulator) {
|
||
baseForOwn(object, function(value, key, object) {
|
||
setter(accumulator, iteratee(value), key, object);
|
||
});
|
||
return accumulator;
|
||
}
|
||
|
||
/**
|
||
* The base implementation of `_.invoke` without support for individual
|
||
* method arguments.
|
||
*
|
||
* @private
|
||
* @param {Object} object The object to query.
|
||
* @param {Array|string} path The path of the method to invoke.
|
||
* @param {Array} args The arguments to invoke the method with.
|
||
* @returns {*} Returns the result of the invoked method.
|
||
*/
|
||
function baseInvoke(object, path, args) {
|
||
path = castPath(path, object);
|
||
object = parent(object, path);
|
||
var func = object == null ? object : object[toKey(last(path))];
|
||
return func == null ? undefined : apply(func, object, args);
|
||
}
|
||
|
||
/**
|
||
* The base implementation of `_.isArguments`.
|
||
*
|
||
* @private
|
||
* @param {*} value The value to check.
|
||
* @returns {boolean} Returns `true` if `value` is an `arguments` object,
|
||
*/
|
||
function baseIsArguments(value) {
|
||
return isObjectLike(value) && baseGetTag(value) == argsTag;
|
||
}
|
||
|
||
/**
|
||
* The base implementation of `_.isArrayBuffer` without Node.js optimizations.
|
||
*
|
||
* @private
|
||
* @param {*} value The value to check.
|
||
* @returns {boolean} Returns `true` if `value` is an array buffer, else `false`.
|
||
*/
|
||
function baseIsArrayBuffer(value) {
|
||
return isObjectLike(value) && baseGetTag(value) == arrayBufferTag;
|
||
}
|
||
|
||
/**
|
||
* The base implementation of `_.isDate` without Node.js optimizations.
|
||
*
|
||
* @private
|
||
* @param {*} value The value to check.
|
||
* @returns {boolean} Returns `true` if `value` is a date object, else `false`.
|
||
*/
|
||
function baseIsDate(value) {
|
||
return isObjectLike(value) && baseGetTag(value) == dateTag;
|
||
}
|
||
|
||
/**
|
||
* The base implementation of `_.isEqual` which supports partial comparisons
|
||
* and tracks traversed objects.
|
||
*
|
||
* @private
|
||
* @param {*} value The value to compare.
|
||
* @param {*} other The other value to compare.
|
||
* @param {boolean} bitmask The bitmask flags.
|
||
* 1 - Unordered comparison
|
||
* 2 - Partial comparison
|
||
* @param {Function} [customizer] The function to customize comparisons.
|
||
* @param {Object} [stack] Tracks traversed `value` and `other` objects.
|
||
* @returns {boolean} Returns `true` if the values are equivalent, else `false`.
|
||
*/
|
||
function baseIsEqual(value, other, bitmask, customizer, stack) {
|
||
if (value === other) {
|
||
return true;
|
||
}
|
||
if (value == null || other == null || (!isObjectLike(value) && !isObjectLike(other))) {
|
||
return value !== value && other !== other;
|
||
}
|
||
return baseIsEqualDeep(value, other, bitmask, customizer, baseIsEqual, stack);
|
||
}
|
||
|
||
/**
|
||
* A specialized version of `baseIsEqual` for arrays and objects which performs
|
||
* deep comparisons and tracks traversed objects enabling objects with circular
|
||
* references to be compared.
|
||
*
|
||
* @private
|
||
* @param {Object} object The object to compare.
|
||
* @param {Object} other The other object to compare.
|
||
* @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.
|
||
* @param {Function} customizer The function to customize comparisons.
|
||
* @param {Function} equalFunc The function to determine equivalents of values.
|
||
* @param {Object} [stack] Tracks traversed `object` and `other` objects.
|
||
* @returns {boolean} Returns `true` if the objects are equivalent, else `false`.
|
||
*/
|
||
function baseIsEqualDeep(object, other, bitmask, customizer, equalFunc, stack) {
|
||
var objIsArr = isArray(object),
|
||
othIsArr = isArray(other),
|
||
objTag = objIsArr ? arrayTag : getTag(object),
|
||
othTag = othIsArr ? arrayTag : getTag(other);
|
||
|
||
objTag = objTag == argsTag ? objectTag : objTag;
|
||
othTag = othTag == argsTag ? objectTag : othTag;
|
||
|
||
var objIsObj = objTag == objectTag,
|
||
othIsObj = othTag == objectTag,
|
||
isSameTag = objTag == othTag;
|
||
|
||
if (isSameTag && isBuffer(object)) {
|
||
if (!isBuffer(other)) {
|
||
return false;
|
||
}
|
||
objIsArr = true;
|
||
objIsObj = false;
|
||
}
|
||
if (isSameTag && !objIsObj) {
|
||
stack || (stack = new Stack);
|
||
return (objIsArr || isTypedArray(object))
|
||
? equalArrays(object, other, bitmask, customizer, equalFunc, stack)
|
||
: equalByTag(object, other, objTag, bitmask, customizer, equalFunc, stack);
|
||
}
|
||
if (!(bitmask & COMPARE_PARTIAL_FLAG)) {
|
||
var objIsWrapped = objIsObj && hasOwnProperty.call(object, '__wrapped__'),
|
||
othIsWrapped = othIsObj && hasOwnProperty.call(other, '__wrapped__');
|
||
|
||
if (objIsWrapped || othIsWrapped) {
|
||
var objUnwrapped = objIsWrapped ? object.value() : object,
|
||
othUnwrapped = othIsWrapped ? other.value() : other;
|
||
|
||
stack || (stack = new Stack);
|
||
return equalFunc(objUnwrapped, othUnwrapped, bitmask, customizer, stack);
|
||
}
|
||
}
|
||
if (!isSameTag) {
|
||
return false;
|
||
}
|
||
stack || (stack = new Stack);
|
||
return equalObjects(object, other, bitmask, customizer, equalFunc, stack);
|
||
}
|
||
|
||
/**
|
||
* The base implementation of `_.isMap` without Node.js optimizations.
|
||
*
|
||
* @private
|
||
* @param {*} value The value to check.
|
||
* @returns {boolean} Returns `true` if `value` is a map, else `false`.
|
||
*/
|
||
function baseIsMap(value) {
|
||
return isObjectLike(value) && getTag(value) == mapTag;
|
||
}
|
||
|
||
/**
|
||
* The base implementation of `_.isMatch` without support for iteratee shorthands.
|
||
*
|
||
* @private
|
||
* @param {Object} object The object to inspect.
|
||
* @param {Object} source The object of property values to match.
|
||
* @param {Array} matchData The property names, values, and compare flags to match.
|
||
* @param {Function} [customizer] The function to customize comparisons.
|
||
* @returns {boolean} Returns `true` if `object` is a match, else `false`.
|
||
*/
|
||
function baseIsMatch(object, source, matchData, customizer) {
|
||
var index = matchData.length,
|
||
length = index,
|
||
noCustomizer = !customizer;
|
||
|
||
if (object == null) {
|
||
return !length;
|
||
}
|
||
object = Object(object);
|
||
while (index--) {
|
||
var data = matchData[index];
|
||
if ((noCustomizer && data[2])
|
||
? data[1] !== object[data[0]]
|
||
: !(data[0] in object)
|
||
) {
|
||
return false;
|
||
}
|
||
}
|
||
while (++index < length) {
|
||
data = matchData[index];
|
||
var key = data[0],
|
||
objValue = object[key],
|
||
srcValue = data[1];
|
||
|
||
if (noCustomizer && data[2]) {
|
||
if (objValue === undefined && !(key in object)) {
|
||
return false;
|
||
}
|
||
} else {
|
||
var stack = new Stack;
|
||
if (customizer) {
|
||
var result = customizer(objValue, srcValue, key, object, source, stack);
|
||
}
|
||
if (!(result === undefined
|
||
? baseIsEqual(srcValue, objValue, COMPARE_PARTIAL_FLAG | COMPARE_UNORDERED_FLAG, customizer, stack)
|
||
: result
|
||
)) {
|
||
return false;
|
||
}
|
||
}
|
||
}
|
||
return true;
|
||
}
|
||
|
||
/**
|
||
* The base implementation of `_.isNative` without bad shim checks.
|
||
*
|
||
* @private
|
||
* @param {*} value The value to check.
|
||
* @returns {boolean} Returns `true` if `value` is a native function,
|
||
* else `false`.
|
||
*/
|
||
function baseIsNative(value) {
|
||
if (!isObject(value) || isMasked(value)) {
|
||
return false;
|
||
}
|
||
var pattern = isFunction(value) ? reIsNative : reIsHostCtor;
|
||
return pattern.test(toSource(value));
|
||
}
|
||
|
||
/**
|
||
* The base implementation of `_.isRegExp` without Node.js optimizations.
|
||
*
|
||
* @private
|
||
* @param {*} value The value to check.
|
||
* @returns {boolean} Returns `true` if `value` is a regexp, else `false`.
|
||
*/
|
||
function baseIsRegExp(value) {
|
||
return isObjectLike(value) && baseGetTag(value) == regexpTag;
|
||
}
|
||
|
||
/**
|
||
* The base implementation of `_.isSet` without Node.js optimizations.
|
||
*
|
||
* @private
|
||
* @param {*} value The value to check.
|
||
* @returns {boolean} Returns `true` if `value` is a set, else `false`.
|
||
*/
|
||
function baseIsSet(value) {
|
||
return isObjectLike(value) && getTag(value) == setTag;
|
||
}
|
||
|
||
/**
|
||
* The base implementation of `_.isTypedArray` without Node.js optimizations.
|
||
*
|
||
* @private
|
||
* @param {*} value The value to check.
|
||
* @returns {boolean} Returns `true` if `value` is a typed array, else `false`.
|
||
*/
|
||
function baseIsTypedArray(value) {
|
||
return isObjectLike(value) &&
|
||
isLength(value.length) && !!typedArrayTags[baseGetTag(value)];
|
||
}
|
||
|
||
/**
|
||
* The base implementation of `_.iteratee`.
|
||
*
|
||
* @private
|
||
* @param {*} [value=_.identity] The value to convert to an iteratee.
|
||
* @returns {Function} Returns the iteratee.
|
||
*/
|
||
function baseIteratee(value) {
|
||
// Don't store the `typeof` result in a variable to avoid a JIT bug in Safari 9.
|
||
// See https://bugs.webkit.org/show_bug.cgi?id=156034 for more details.
|
||
if (typeof value == 'function') {
|
||
return value;
|
||
}
|
||
if (value == null) {
|
||
return identity;
|
||
}
|
||
if (typeof value == 'object') {
|
||
return isArray(value)
|
||
? baseMatchesProperty(value[0], value[1])
|
||
: baseMatches(value);
|
||
}
|
||
return property(value);
|
||
}
|
||
|
||
/**
|
||
* The base implementation of `_.keys` which doesn't treat sparse arrays as dense.
|
||
*
|
||
* @private
|
||
* @param {Object} object The object to query.
|
||
* @returns {Array} Returns the array of property names.
|
||
*/
|
||
function baseKeys(object) {
|
||
if (!isPrototype(object)) {
|
||
return nativeKeys(object);
|
||
}
|
||
var result = [];
|
||
for (var key in Object(object)) {
|
||
if (hasOwnProperty.call(object, key) && key != 'constructor') {
|
||
result.push(key);
|
||
}
|
||
}
|
||
return result;
|
||
}
|
||
|
||
/**
|
||
* The base implementation of `_.keysIn` which doesn't treat sparse arrays as dense.
|
||
*
|
||
* @private
|
||
* @param {Object} object The object to query.
|
||
* @returns {Array} Returns the array of property names.
|
||
*/
|
||
function baseKeysIn(object) {
|
||
if (!isObject(object)) {
|
||
return nativeKeysIn(object);
|
||
}
|
||
var isProto = isPrototype(object),
|
||
result = [];
|
||
|
||
for (var key in object) {
|
||
if (!(key == 'constructor' && (isProto || !hasOwnProperty.call(object, key)))) {
|
||
result.push(key);
|
||
}
|
||
}
|
||
return result;
|
||
}
|
||
|
||
/**
|
||
* The base implementation of `_.lt` which doesn't coerce arguments.
|
||
*
|
||
* @private
|
||
* @param {*} value The value to compare.
|
||
* @param {*} other The other value to compare.
|
||
* @returns {boolean} Returns `true` if `value` is less than `other`,
|
||
* else `false`.
|
||
*/
|
||
function baseLt(value, other) {
|
||
return value < other;
|
||
}
|
||
|
||
/**
|
||
* The base implementation of `_.map` without support for iteratee shorthands.
|
||
*
|
||
* @private
|
||
* @param {Array|Object} collection The collection to iterate over.
|
||
* @param {Function} iteratee The function invoked per iteration.
|
||
* @returns {Array} Returns the new mapped array.
|
||
*/
|
||
function baseMap(collection, iteratee) {
|
||
var index = -1,
|
||
result = isArrayLike(collection) ? Array(collection.length) : [];
|
||
|
||
baseEach(collection, function(value, key, collection) {
|
||
result[++index] = iteratee(value, key, collection);
|
||
});
|
||
return result;
|
||
}
|
||
|
||
/**
|
||
* The base implementation of `_.matches` which doesn't clone `source`.
|
||
*
|
||
* @private
|
||
* @param {Object} source The object of property values to match.
|
||
* @returns {Function} Returns the new spec function.
|
||
*/
|
||
function baseMatches(source) {
|
||
var matchData = getMatchData(source);
|
||
if (matchData.length == 1 && matchData[0][2]) {
|
||
return matchesStrictComparable(matchData[0][0], matchData[0][1]);
|
||
}
|
||
return function(object) {
|
||
return object === source || baseIsMatch(object, source, matchData);
|
||
};
|
||
}
|
||
|
||
/**
|
||
* The base implementation of `_.matchesProperty` which doesn't clone `srcValue`.
|
||
*
|
||
* @private
|
||
* @param {string} path The path of the property to get.
|
||
* @param {*} srcValue The value to match.
|
||
* @returns {Function} Returns the new spec function.
|
||
*/
|
||
function baseMatchesProperty(path, srcValue) {
|
||
if (isKey(path) && isStrictComparable(srcValue)) {
|
||
return matchesStrictComparable(toKey(path), srcValue);
|
||
}
|
||
return function(object) {
|
||
var objValue = get(object, path);
|
||
return (objValue === undefined && objValue === srcValue)
|
||
? hasIn(object, path)
|
||
: baseIsEqual(srcValue, objValue, COMPARE_PARTIAL_FLAG | COMPARE_UNORDERED_FLAG);
|
||
};
|
||
}
|
||
|
||
/**
|
||
* The base implementation of `_.merge` without support for multiple sources.
|
||
*
|
||
* @private
|
||
* @param {Object} object The destination object.
|
||
* @param {Object} source The source object.
|
||
* @param {number} srcIndex The index of `source`.
|
||
* @param {Function} [customizer] The function to customize merged values.
|
||
* @param {Object} [stack] Tracks traversed source values and their merged
|
||
* counterparts.
|
||
*/
|
||
function baseMerge(object, source, srcIndex, customizer, stack) {
|
||
if (object === source) {
|
||
return;
|
||
}
|
||
baseFor(source, function(srcValue, key) {
|
||
if (isObject(srcValue)) {
|
||
stack || (stack = new Stack);
|
||
baseMergeDeep(object, source, key, srcIndex, baseMerge, customizer, stack);
|
||
}
|
||
else {
|
||
var newValue = customizer
|
||
? customizer(object[key], srcValue, (key + ''), object, source, stack)
|
||
: undefined;
|
||
|
||
if (newValue === undefined) {
|
||
newValue = srcValue;
|
||
}
|
||
assignMergeValue(object, key, newValue);
|
||
}
|
||
}, keysIn);
|
||
}
|
||
|
||
/**
|
||
* A specialized version of `baseMerge` for arrays and objects which performs
|
||
* deep merges and tracks traversed objects enabling objects with circular
|
||
* references to be merged.
|
||
*
|
||
* @private
|
||
* @param {Object} object The destination object.
|
||
* @param {Object} source The source object.
|
||
* @param {string} key The key of the value to merge.
|
||
* @param {number} srcIndex The index of `source`.
|
||
* @param {Function} mergeFunc The function to merge values.
|
||
* @param {Function} [customizer] The function to customize assigned values.
|
||
* @param {Object} [stack] Tracks traversed source values and their merged
|
||
* counterparts.
|
||
*/
|
||
function baseMergeDeep(object, source, key, srcIndex, mergeFunc, customizer, stack) {
|
||
var objValue = object[key],
|
||
srcValue = source[key],
|
||
stacked = stack.get(srcValue);
|
||
|
||
if (stacked) {
|
||
assignMergeValue(object, key, stacked);
|
||
return;
|
||
}
|
||
var newValue = customizer
|
||
? customizer(objValue, srcValue, (key + ''), object, source, stack)
|
||
: undefined;
|
||
|
||
var isCommon = newValue === undefined;
|
||
|
||
if (isCommon) {
|
||
var isArr = isArray(srcValue),
|
||
isBuff = !isArr && isBuffer(srcValue),
|
||
isTyped = !isArr && !isBuff && isTypedArray(srcValue);
|
||
|
||
newValue = srcValue;
|
||
if (isArr || isBuff || isTyped) {
|
||
if (isArray(objValue)) {
|
||
newValue = objValue;
|
||
}
|
||
else if (isArrayLikeObject(objValue)) {
|
||
newValue = copyArray(objValue);
|
||
}
|
||
else if (isBuff) {
|
||
isCommon = false;
|
||
newValue = cloneBuffer(srcValue, true);
|
||
}
|
||
else if (isTyped) {
|
||
isCommon = false;
|
||
newValue = cloneTypedArray(srcValue, true);
|
||
}
|
||
else {
|
||
newValue = [];
|
||
}
|
||
}
|
||
else if (isPlainObject(srcValue) || isArguments(srcValue)) {
|
||
newValue = objValue;
|
||
if (isArguments(objValue)) {
|
||
newValue = toPlainObject(objValue);
|
||
}
|
||
else if (!isObject(objValue) || (srcIndex && isFunction(objValue))) {
|
||
newValue = initCloneObject(srcValue);
|
||
}
|
||
}
|
||
else {
|
||
isCommon = false;
|
||
}
|
||
}
|
||
if (isCommon) {
|
||
// Recursively merge objects and arrays (susceptible to call stack limits).
|
||
stack.set(srcValue, newValue);
|
||
mergeFunc(newValue, srcValue, srcIndex, customizer, stack);
|
||
stack['delete'](srcValue);
|
||
}
|
||
assignMergeValue(object, key, newValue);
|
||
}
|
||
|
||
/**
|
||
* The base implementation of `_.nth` which doesn't coerce arguments.
|
||
*
|
||
* @private
|
||
* @param {Array} array The array to query.
|
||
* @param {number} n The index of the element to return.
|
||
* @returns {*} Returns the nth element of `array`.
|
||
*/
|
||
function baseNth(array, n) {
|
||
var length = array.length;
|
||
if (!length) {
|
||
return;
|
||
}
|
||
n += n < 0 ? length : 0;
|
||
return isIndex(n, length) ? array[n] : undefined;
|
||
}
|
||
|
||
/**
|
||
* The base implementation of `_.orderBy` without param guards.
|
||
*
|
||
* @private
|
||
* @param {Array|Object} collection The collection to iterate over.
|
||
* @param {Function[]|Object[]|string[]} iteratees The iteratees to sort by.
|
||
* @param {string[]} orders The sort orders of `iteratees`.
|
||
* @returns {Array} Returns the new sorted array.
|
||
*/
|
||
function baseOrderBy(collection, iteratees, orders) {
|
||
var index = -1;
|
||
iteratees = arrayMap(iteratees.length ? iteratees : [identity], baseUnary(getIteratee()));
|
||
|
||
var result = baseMap(collection, function(value, key, collection) {
|
||
var criteria = arrayMap(iteratees, function(iteratee) {
|
||
return iteratee(value);
|
||
});
|
||
return { 'criteria': criteria, 'index': ++index, 'value': value };
|
||
});
|
||
|
||
return baseSortBy(result, function(object, other) {
|
||
return compareMultiple(object, other, orders);
|
||
});
|
||
}
|
||
|
||
/**
|
||
* The base implementation of `_.pick` without support for individual
|
||
* property identifiers.
|
||
*
|
||
* @private
|
||
* @param {Object} object The source object.
|
||
* @param {string[]} paths The property paths to pick.
|
||
* @returns {Object} Returns the new object.
|
||
*/
|
||
function basePick(object, paths) {
|
||
return basePickBy(object, paths, function(value, path) {
|
||
return hasIn(object, path);
|
||
});
|
||
}
|
||
|
||
/**
|
||
* The base implementation of `_.pickBy` without support for iteratee shorthands.
|
||
*
|
||
* @private
|
||
* @param {Object} object The source object.
|
||
* @param {string[]} paths The property paths to pick.
|
||
* @param {Function} predicate The function invoked per property.
|
||
* @returns {Object} Returns the new object.
|
||
*/
|
||
function basePickBy(object, paths, predicate) {
|
||
var index = -1,
|
||
length = paths.length,
|
||
result = {};
|
||
|
||
while (++index < length) {
|
||
var path = paths[index],
|
||
value = baseGet(object, path);
|
||
|
||
if (predicate(value, path)) {
|
||
baseSet(result, castPath(path, object), value);
|
||
}
|
||
}
|
||
return result;
|
||
}
|
||
|
||
/**
|
||
* A specialized version of `baseProperty` which supports deep paths.
|
||
*
|
||
* @private
|
||
* @param {Array|string} path The path of the property to get.
|
||
* @returns {Function} Returns the new accessor function.
|
||
*/
|
||
function basePropertyDeep(path) {
|
||
return function(object) {
|
||
return baseGet(object, path);
|
||
};
|
||
}
|
||
|
||
/**
|
||
* The base implementation of `_.pullAllBy` without support for iteratee
|
||
* shorthands.
|
||
*
|
||
* @private
|
||
* @param {Array} array The array to modify.
|
||
* @param {Array} values The values to remove.
|
||
* @param {Function} [iteratee] The iteratee invoked per element.
|
||
* @param {Function} [comparator] The comparator invoked per element.
|
||
* @returns {Array} Returns `array`.
|
||
*/
|
||
function basePullAll(array, values, iteratee, comparator) {
|
||
var indexOf = comparator ? baseIndexOfWith : baseIndexOf,
|
||
index = -1,
|
||
length = values.length,
|
||
seen = array;
|
||
|
||
if (array === values) {
|
||
values = copyArray(values);
|
||
}
|
||
if (iteratee) {
|
||
seen = arrayMap(array, baseUnary(iteratee));
|
||
}
|
||
while (++index < length) {
|
||
var fromIndex = 0,
|
||
value = values[index],
|
||
computed = iteratee ? iteratee(value) : value;
|
||
|
||
while ((fromIndex = indexOf(seen, computed, fromIndex, comparator)) > -1) {
|
||
if (seen !== array) {
|
||
splice.call(seen, fromIndex, 1);
|
||
}
|
||
splice.call(array, fromIndex, 1);
|
||
}
|
||
}
|
||
return array;
|
||
}
|
||
|
||
/**
|
||
* The base implementation of `_.pullAt` without support for individual
|
||
* indexes or capturing the removed elements.
|
||
*
|
||
* @private
|
||
* @param {Array} array The array to modify.
|
||
* @param {number[]} indexes The indexes of elements to remove.
|
||
* @returns {Array} Returns `array`.
|
||
*/
|
||
function basePullAt(array, indexes) {
|
||
var length = array ? indexes.length : 0,
|
||
lastIndex = length - 1;
|
||
|
||
while (length--) {
|
||
var index = indexes[length];
|
||
if (length == lastIndex || index !== previous) {
|
||
var previous = index;
|
||
if (isIndex(index)) {
|
||
splice.call(array, index, 1);
|
||
} else {
|
||
baseUnset(array, index);
|
||
}
|
||
}
|
||
}
|
||
return array;
|
||
}
|
||
|
||
/**
|
||
* The base implementation of `_.random` without support for returning
|
||
* floating-point numbers.
|
||
*
|
||
* @private
|
||
* @param {number} lower The lower bound.
|
||
* @param {number} upper The upper bound.
|
||
* @returns {number} Returns the random number.
|
||
*/
|
||
function baseRandom(lower, upper) {
|
||
return lower + nativeFloor(nativeRandom() * (upper - lower + 1));
|
||
}
|
||
|
||
/**
|
||
* The base implementation of `_.range` and `_.rangeRight` which doesn't
|
||
* coerce arguments.
|
||
*
|
||
* @private
|
||
* @param {number} start The start of the range.
|
||
* @param {number} end The end of the range.
|
||
* @param {number} step The value to increment or decrement by.
|
||
* @param {boolean} [fromRight] Specify iterating from right to left.
|
||
* @returns {Array} Returns the range of numbers.
|
||
*/
|
||
function baseRange(start, end, step, fromRight) {
|
||
var index = -1,
|
||
length = nativeMax(nativeCeil((end - start) / (step || 1)), 0),
|
||
result = Array(length);
|
||
|
||
while (length--) {
|
||
result[fromRight ? length : ++index] = start;
|
||
start += step;
|
||
}
|
||
return result;
|
||
}
|
||
|
||
/**
|
||
* The base implementation of `_.repeat` which doesn't coerce arguments.
|
||
*
|
||
* @private
|
||
* @param {string} string The string to repeat.
|
||
* @param {number} n The number of times to repeat the string.
|
||
* @returns {string} Returns the repeated string.
|
||
*/
|
||
function baseRepeat(string, n) {
|
||
var result = '';
|
||
if (!string || n < 1 || n > MAX_SAFE_INTEGER) {
|
||
return result;
|
||
}
|
||
// Leverage the exponentiation by squaring algorithm for a faster repeat.
|
||
// See https://en.wikipedia.org/wiki/Exponentiation_by_squaring for more details.
|
||
do {
|
||
if (n % 2) {
|
||
result += string;
|
||
}
|
||
n = nativeFloor(n / 2);
|
||
if (n) {
|
||
string += string;
|
||
}
|
||
} while (n);
|
||
|
||
return result;
|
||
}
|
||
|
||
/**
|
||
* The base implementation of `_.rest` which doesn't validate or coerce arguments.
|
||
*
|
||
* @private
|
||
* @param {Function} func The function to apply a rest parameter to.
|
||
* @param {number} [start=func.length-1] The start position of the rest parameter.
|
||
* @returns {Function} Returns the new function.
|
||
*/
|
||
function baseRest(func, start) {
|
||
return setToString(overRest(func, start, identity), func + '');
|
||
}
|
||
|
||
/**
|
||
* The base implementation of `_.sample`.
|
||
*
|
||
* @private
|
||
* @param {Array|Object} collection The collection to sample.
|
||
* @returns {*} Returns the random element.
|
||
*/
|
||
function baseSample(collection) {
|
||
return arraySample(values(collection));
|
||
}
|
||
|
||
/**
|
||
* The base implementation of `_.sampleSize` without param guards.
|
||
*
|
||
* @private
|
||
* @param {Array|Object} collection The collection to sample.
|
||
* @param {number} n The number of elements to sample.
|
||
* @returns {Array} Returns the random elements.
|
||
*/
|
||
function baseSampleSize(collection, n) {
|
||
var array = values(collection);
|
||
return shuffleSelf(array, baseClamp(n, 0, array.length));
|
||
}
|
||
|
||
/**
|
||
* The base implementation of `_.set`.
|
||
*
|
||
* @private
|
||
* @param {Object} object The object to modify.
|
||
* @param {Array|string} path The path of the property to set.
|
||
* @param {*} value The value to set.
|
||
* @param {Function} [customizer] The function to customize path creation.
|
||
* @returns {Object} Returns `object`.
|
||
*/
|
||
function baseSet(object, path, value, customizer) {
|
||
if (!isObject(object)) {
|
||
return object;
|
||
}
|
||
path = castPath(path, object);
|
||
|
||
var index = -1,
|
||
length = path.length,
|
||
lastIndex = length - 1,
|
||
nested = object;
|
||
|
||
while (nested != null && ++index < length) {
|
||
var key = toKey(path[index]),
|
||
newValue = value;
|
||
|
||
if (index != lastIndex) {
|
||
var objValue = nested[key];
|
||
newValue = customizer ? customizer(objValue, key, nested) : undefined;
|
||
if (newValue === undefined) {
|
||
newValue = isObject(objValue)
|
||
? objValue
|
||
: (isIndex(path[index + 1]) ? [] : {});
|
||
}
|
||
}
|
||
assignValue(nested, key, newValue);
|
||
nested = nested[key];
|
||
}
|
||
return object;
|
||
}
|
||
|
||
/**
|
||
* The base implementation of `setData` without support for hot loop shorting.
|
||
*
|
||
* @private
|
||
* @param {Function} func The function to associate metadata with.
|
||
* @param {*} data The metadata.
|
||
* @returns {Function} Returns `func`.
|
||
*/
|
||
var baseSetData = !metaMap ? identity : function(func, data) {
|
||
metaMap.set(func, data);
|
||
return func;
|
||
};
|
||
|
||
/**
|
||
* The base implementation of `setToString` without support for hot loop shorting.
|
||
*
|
||
* @private
|
||
* @param {Function} func The function to modify.
|
||
* @param {Function} string The `toString` result.
|
||
* @returns {Function} Returns `func`.
|
||
*/
|
||
var baseSetToString = !defineProperty ? identity : function(func, string) {
|
||
return defineProperty(func, 'toString', {
|
||
'configurable': true,
|
||
'enumerable': false,
|
||
'value': constant(string),
|
||
'writable': true
|
||
});
|
||
};
|
||
|
||
/**
|
||
* The base implementation of `_.shuffle`.
|
||
*
|
||
* @private
|
||
* @param {Array|Object} collection The collection to shuffle.
|
||
* @returns {Array} Returns the new shuffled array.
|
||
*/
|
||
function baseShuffle(collection) {
|
||
return shuffleSelf(values(collection));
|
||
}
|
||
|
||
/**
|
||
* The base implementation of `_.slice` without an iteratee call guard.
|
||
*
|
||
* @private
|
||
* @param {Array} array The array to slice.
|
||
* @param {number} [start=0] The start position.
|
||
* @param {number} [end=array.length] The end position.
|
||
* @returns {Array} Returns the slice of `array`.
|
||
*/
|
||
function baseSlice(array, start, end) {
|
||
var index = -1,
|
||
length = array.length;
|
||
|
||
if (start < 0) {
|
||
start = -start > length ? 0 : (length + start);
|
||
}
|
||
end = end > length ? length : end;
|
||
if (end < 0) {
|
||
end += length;
|
||
}
|
||
length = start > end ? 0 : ((end - start) >>> 0);
|
||
start >>>= 0;
|
||
|
||
var result = Array(length);
|
||
while (++index < length) {
|
||
result[index] = array[index + start];
|
||
}
|
||
return result;
|
||
}
|
||
|
||
/**
|
||
* The base implementation of `_.some` without support for iteratee shorthands.
|
||
*
|
||
* @private
|
||
* @param {Array|Object} collection The collection to iterate over.
|
||
* @param {Function} predicate The function invoked per iteration.
|
||
* @returns {boolean} Returns `true` if any element passes the predicate check,
|
||
* else `false`.
|
||
*/
|
||
function baseSome(collection, predicate) {
|
||
var result;
|
||
|
||
baseEach(collection, function(value, index, collection) {
|
||
result = predicate(value, index, collection);
|
||
return !result;
|
||
});
|
||
return !!result;
|
||
}
|
||
|
||
/**
|
||
* The base implementation of `_.sortedIndex` and `_.sortedLastIndex` which
|
||
* performs a binary search of `array` to determine the index at which `value`
|
||
* should be inserted into `array` in order to maintain its sort order.
|
||
*
|
||
* @private
|
||
* @param {Array} array The sorted array to inspect.
|
||
* @param {*} value The value to evaluate.
|
||
* @param {boolean} [retHighest] Specify returning the highest qualified index.
|
||
* @returns {number} Returns the index at which `value` should be inserted
|
||
* into `array`.
|
||
*/
|
||
function baseSortedIndex(array, value, retHighest) {
|
||
var low = 0,
|
||
high = array == null ? low : array.length;
|
||
|
||
if (typeof value == 'number' && value === value && high <= HALF_MAX_ARRAY_LENGTH) {
|
||
while (low < high) {
|
||
var mid = (low + high) >>> 1,
|
||
computed = array[mid];
|
||
|
||
if (computed !== null && !isSymbol(computed) &&
|
||
(retHighest ? (computed <= value) : (computed < value))) {
|
||
low = mid + 1;
|
||
} else {
|
||
high = mid;
|
||
}
|
||
}
|
||
return high;
|
||
}
|
||
return baseSortedIndexBy(array, value, identity, retHighest);
|
||
}
|
||
|
||
/**
|
||
* The base implementation of `_.sortedIndexBy` and `_.sortedLastIndexBy`
|
||
* which invokes `iteratee` for `value` and each element of `array` to compute
|
||
* their sort ranking. The iteratee is invoked with one argument; (value).
|
||
*
|
||
* @private
|
||
* @param {Array} array The sorted array to inspect.
|
||
* @param {*} value The value to evaluate.
|
||
* @param {Function} iteratee The iteratee invoked per element.
|
||
* @param {boolean} [retHighest] Specify returning the highest qualified index.
|
||
* @returns {number} Returns the index at which `value` should be inserted
|
||
* into `array`.
|
||
*/
|
||
function baseSortedIndexBy(array, value, iteratee, retHighest) {
|
||
value = iteratee(value);
|
||
|
||
var low = 0,
|
||
high = array == null ? 0 : array.length,
|
||
valIsNaN = value !== value,
|
||
valIsNull = value === null,
|
||
valIsSymbol = isSymbol(value),
|
||
valIsUndefined = value === undefined;
|
||
|
||
while (low < high) {
|
||
var mid = nativeFloor((low + high) / 2),
|
||
computed = iteratee(array[mid]),
|
||
othIsDefined = computed !== undefined,
|
||
othIsNull = computed === null,
|
||
othIsReflexive = computed === computed,
|
||
othIsSymbol = isSymbol(computed);
|
||
|
||
if (valIsNaN) {
|
||
var setLow = retHighest || othIsReflexive;
|
||
} else if (valIsUndefined) {
|
||
setLow = othIsReflexive && (retHighest || othIsDefined);
|
||
} else if (valIsNull) {
|
||
setLow = othIsReflexive && othIsDefined && (retHighest || !othIsNull);
|
||
} else if (valIsSymbol) {
|
||
setLow = othIsReflexive && othIsDefined && !othIsNull && (retHighest || !othIsSymbol);
|
||
} else if (othIsNull || othIsSymbol) {
|
||
setLow = false;
|
||
} else {
|
||
setLow = retHighest ? (computed <= value) : (computed < value);
|
||
}
|
||
if (setLow) {
|
||
low = mid + 1;
|
||
} else {
|
||
high = mid;
|
||
}
|
||
}
|
||
return nativeMin(high, MAX_ARRAY_INDEX);
|
||
}
|
||
|
||
/**
|
||
* The base implementation of `_.sortedUniq` and `_.sortedUniqBy` without
|
||
* support for iteratee shorthands.
|
||
*
|
||
* @private
|
||
* @param {Array} array The array to inspect.
|
||
* @param {Function} [iteratee] The iteratee invoked per element.
|
||
* @returns {Array} Returns the new duplicate free array.
|
||
*/
|
||
function baseSortedUniq(array, iteratee) {
|
||
var index = -1,
|
||
length = array.length,
|
||
resIndex = 0,
|
||
result = [];
|
||
|
||
while (++index < length) {
|
||
var value = array[index],
|
||
computed = iteratee ? iteratee(value) : value;
|
||
|
||
if (!index || !eq(computed, seen)) {
|
||
var seen = computed;
|
||
result[resIndex++] = value === 0 ? 0 : value;
|
||
}
|
||
}
|
||
return result;
|
||
}
|
||
|
||
/**
|
||
* The base implementation of `_.toNumber` which doesn't ensure correct
|
||
* conversions of binary, hexadecimal, or octal string values.
|
||
*
|
||
* @private
|
||
* @param {*} value The value to process.
|
||
* @returns {number} Returns the number.
|
||
*/
|
||
function baseToNumber(value) {
|
||
if (typeof value == 'number') {
|
||
return value;
|
||
}
|
||
if (isSymbol(value)) {
|
||
return NAN;
|
||
}
|
||
return +value;
|
||
}
|
||
|
||
/**
|
||
* The base implementation of `_.toString` which doesn't convert nullish
|
||
* values to empty strings.
|
||
*
|
||
* @private
|
||
* @param {*} value The value to process.
|
||
* @returns {string} Returns the string.
|
||
*/
|
||
function baseToString(value) {
|
||
// Exit early for strings to avoid a performance hit in some environments.
|
||
if (typeof value == 'string') {
|
||
return value;
|
||
}
|
||
if (isArray(value)) {
|
||
// Recursively convert values (susceptible to call stack limits).
|
||
return arrayMap(value, baseToString) + '';
|
||
}
|
||
if (isSymbol(value)) {
|
||
return symbolToString ? symbolToString.call(value) : '';
|
||
}
|
||
var result = (value + '');
|
||
return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result;
|
||
}
|
||
|
||
/**
|
||
* The base implementation of `_.uniqBy` without support for iteratee shorthands.
|
||
*
|
||
* @private
|
||
* @param {Array} array The array to inspect.
|
||
* @param {Function} [iteratee] The iteratee invoked per element.
|
||
* @param {Function} [comparator] The comparator invoked per element.
|
||
* @returns {Array} Returns the new duplicate free array.
|
||
*/
|
||
function baseUniq(array, iteratee, comparator) {
|
||
var index = -1,
|
||
includes = arrayIncludes,
|
||
length = array.length,
|
||
isCommon = true,
|
||
result = [],
|
||
seen = result;
|
||
|
||
if (comparator) {
|
||
isCommon = false;
|
||
includes = arrayIncludesWith;
|
||
}
|
||
else if (length >= LARGE_ARRAY_SIZE) {
|
||
var set = iteratee ? null : createSet(array);
|
||
if (set) {
|
||
return setToArray(set);
|
||
}
|
||
isCommon = false;
|
||
includes = cacheHas;
|
||
seen = new SetCache;
|
||
}
|
||
else {
|
||
seen = iteratee ? [] : result;
|
||
}
|
||
outer:
|
||
while (++index < length) {
|
||
var value = array[index],
|
||
computed = iteratee ? iteratee(value) : value;
|
||
|
||
value = (comparator || value !== 0) ? value : 0;
|
||
if (isCommon && computed === computed) {
|
||
var seenIndex = seen.length;
|
||
while (seenIndex--) {
|
||
if (seen[seenIndex] === computed) {
|
||
continue outer;
|
||
}
|
||
}
|
||
if (iteratee) {
|
||
seen.push(computed);
|
||
}
|
||
result.push(value);
|
||
}
|
||
else if (!includes(seen, computed, comparator)) {
|
||
if (seen !== result) {
|
||
seen.push(computed);
|
||
}
|
||
result.push(value);
|
||
}
|
||
}
|
||
return result;
|
||
}
|
||
|
||
/**
|
||
* The base implementation of `_.unset`.
|
||
*
|
||
* @private
|
||
* @param {Object} object The object to modify.
|
||
* @param {Array|string} path The property path to unset.
|
||
* @returns {boolean} Returns `true` if the property is deleted, else `false`.
|
||
*/
|
||
function baseUnset(object, path) {
|
||
path = castPath(path, object);
|
||
object = parent(object, path);
|
||
return object == null || delete object[toKey(last(path))];
|
||
}
|
||
|
||
/**
|
||
* The base implementation of `_.update`.
|
||
*
|
||
* @private
|
||
* @param {Object} object The object to modify.
|
||
* @param {Array|string} path The path of the property to update.
|
||
* @param {Function} updater The function to produce the updated value.
|
||
* @param {Function} [customizer] The function to customize path creation.
|
||
* @returns {Object} Returns `object`.
|
||
*/
|
||
function baseUpdate(object, path, updater, customizer) {
|
||
return baseSet(object, path, updater(baseGet(object, path)), customizer);
|
||
}
|
||
|
||
/**
|
||
* The base implementation of methods like `_.dropWhile` and `_.takeWhile`
|
||
* without support for iteratee shorthands.
|
||
*
|
||
* @private
|
||
* @param {Array} array The array to query.
|
||
* @param {Function} predicate The function invoked per iteration.
|
||
* @param {boolean} [isDrop] Specify dropping elements instead of taking them.
|
||
* @param {boolean} [fromRight] Specify iterating from right to left.
|
||
* @returns {Array} Returns the slice of `array`.
|
||
*/
|
||
function baseWhile(array, predicate, isDrop, fromRight) {
|
||
var length = array.length,
|
||
index = fromRight ? length : -1;
|
||
|
||
while ((fromRight ? index-- : ++index < length) &&
|
||
predicate(array[index], index, array)) {}
|
||
|
||
return isDrop
|
||
? baseSlice(array, (fromRight ? 0 : index), (fromRight ? index + 1 : length))
|
||
: baseSlice(array, (fromRight ? index + 1 : 0), (fromRight ? length : index));
|
||
}
|
||
|
||
/**
|
||
* The base implementation of `wrapperValue` which returns the result of
|
||
* performing a sequence of actions on the unwrapped `value`, where each
|
||
* successive action is supplied the return value of the previous.
|
||
*
|
||
* @private
|
||
* @param {*} value The unwrapped value.
|
||
* @param {Array} actions Actions to perform to resolve the unwrapped value.
|
||
* @returns {*} Returns the resolved value.
|
||
*/
|
||
function baseWrapperValue(value, actions) {
|
||
var result = value;
|
||
if (result instanceof LazyWrapper) {
|
||
result = result.value();
|
||
}
|
||
return arrayReduce(actions, function(result, action) {
|
||
return action.func.apply(action.thisArg, arrayPush([result], action.args));
|
||
}, result);
|
||
}
|
||
|
||
/**
|
||
* The base implementation of methods like `_.xor`, without support for
|
||
* iteratee shorthands, that accepts an array of arrays to inspect.
|
||
*
|
||
* @private
|
||
* @param {Array} arrays The arrays to inspect.
|
||
* @param {Function} [iteratee] The iteratee invoked per element.
|
||
* @param {Function} [comparator] The comparator invoked per element.
|
||
* @returns {Array} Returns the new array of values.
|
||
*/
|
||
function baseXor(arrays, iteratee, comparator) {
|
||
var length = arrays.length;
|
||
if (length < 2) {
|
||
return length ? baseUniq(arrays[0]) : [];
|
||
}
|
||
var index = -1,
|
||
result = Array(length);
|
||
|
||
while (++index < length) {
|
||
var array = arrays[index],
|
||
othIndex = -1;
|
||
|
||
while (++othIndex < length) {
|
||
if (othIndex != index) {
|
||
result[index] = baseDifference(result[index] || array, arrays[othIndex], iteratee, comparator);
|
||
}
|
||
}
|
||
}
|
||
return baseUniq(baseFlatten(result, 1), iteratee, comparator);
|
||
}
|
||
|
||
/**
|
||
* This base implementation of `_.zipObject` which assigns values using `assignFunc`.
|
||
*
|
||
* @private
|
||
* @param {Array} props The property identifiers.
|
||
* @param {Array} values The property values.
|
||
* @param {Function} assignFunc The function to assign values.
|
||
* @returns {Object} Returns the new object.
|
||
*/
|
||
function baseZipObject(props, values, assignFunc) {
|
||
var index = -1,
|
||
length = props.length,
|
||
valsLength = values.length,
|
||
result = {};
|
||
|
||
while (++index < length) {
|
||
var value = index < valsLength ? values[index] : undefined;
|
||
assignFunc(result, props[index], value);
|
||
}
|
||
return result;
|
||
}
|
||
|
||
/**
|
||
* Casts `value` to an empty array if it's not an array like object.
|
||
*
|
||
* @private
|
||
* @param {*} value The value to inspect.
|
||
* @returns {Array|Object} Returns the cast array-like object.
|
||
*/
|
||
function castArrayLikeObject(value) {
|
||
return isArrayLikeObject(value) ? value : [];
|
||
}
|
||
|
||
/**
|
||
* Casts `value` to `identity` if it's not a function.
|
||
*
|
||
* @private
|
||
* @param {*} value The value to inspect.
|
||
* @returns {Function} Returns cast function.
|
||
*/
|
||
function castFunction(value) {
|
||
return typeof value == 'function' ? value : identity;
|
||
}
|
||
|
||
/**
|
||
* Casts `value` to a path array if it's not one.
|
||
*
|
||
* @private
|
||
* @param {*} value The value to inspect.
|
||
* @param {Object} [object] The object to query keys on.
|
||
* @returns {Array} Returns the cast property path array.
|
||
*/
|
||
function castPath(value, object) {
|
||
if (isArray(value)) {
|
||
return value;
|
||
}
|
||
return isKey(value, object) ? [value] : stringToPath(toString(value));
|
||
}
|
||
|
||
/**
|
||
* A `baseRest` alias which can be replaced with `identity` by module
|
||
* replacement plugins.
|
||
*
|
||
* @private
|
||
* @type {Function}
|
||
* @param {Function} func The function to apply a rest parameter to.
|
||
* @returns {Function} Returns the new function.
|
||
*/
|
||
var castRest = baseRest;
|
||
|
||
/**
|
||
* Casts `array` to a slice if it's needed.
|
||
*
|
||
* @private
|
||
* @param {Array} array The array to inspect.
|
||
* @param {number} start The start position.
|
||
* @param {number} [end=array.length] The end position.
|
||
* @returns {Array} Returns the cast slice.
|
||
*/
|
||
function castSlice(array, start, end) {
|
||
var length = array.length;
|
||
end = end === undefined ? length : end;
|
||
return (!start && end >= length) ? array : baseSlice(array, start, end);
|
||
}
|
||
|
||
/**
|
||
* A simple wrapper around the global [`clearTimeout`](https://mdn.io/clearTimeout).
|
||
*
|
||
* @private
|
||
* @param {number|Object} id The timer id or timeout object of the timer to clear.
|
||
*/
|
||
var clearTimeout = ctxClearTimeout || function(id) {
|
||
return root.clearTimeout(id);
|
||
};
|
||
|
||
/**
|
||
* Creates a clone of `buffer`.
|
||
*
|
||
* @private
|
||
* @param {Buffer} buffer The buffer to clone.
|
||
* @param {boolean} [isDeep] Specify a deep clone.
|
||
* @returns {Buffer} Returns the cloned buffer.
|
||
*/
|
||
function cloneBuffer(buffer, isDeep) {
|
||
if (isDeep) {
|
||
return buffer.slice();
|
||
}
|
||
var length = buffer.length,
|
||
result = allocUnsafe ? allocUnsafe(length) : new buffer.constructor(length);
|
||
|
||
buffer.copy(result);
|
||
return result;
|
||
}
|
||
|
||
/**
|
||
* Creates a clone of `arrayBuffer`.
|
||
*
|
||
* @private
|
||
* @param {ArrayBuffer} arrayBuffer The array buffer to clone.
|
||
* @returns {ArrayBuffer} Returns the cloned array buffer.
|
||
*/
|
||
function cloneArrayBuffer(arrayBuffer) {
|
||
var result = new arrayBuffer.constructor(arrayBuffer.byteLength);
|
||
new Uint8Array(result).set(new Uint8Array(arrayBuffer));
|
||
return result;
|
||
}
|
||
|
||
/**
|
||
* Creates a clone of `dataView`.
|
||
*
|
||
* @private
|
||
* @param {Object} dataView The data view to clone.
|
||
* @param {boolean} [isDeep] Specify a deep clone.
|
||
* @returns {Object} Returns the cloned data view.
|
||
*/
|
||
function cloneDataView(dataView, isDeep) {
|
||
var buffer = isDeep ? cloneArrayBuffer(dataView.buffer) : dataView.buffer;
|
||
return new dataView.constructor(buffer, dataView.byteOffset, dataView.byteLength);
|
||
}
|
||
|
||
/**
|
||
* Creates a clone of `map`.
|
||
*
|
||
* @private
|
||
* @param {Object} map The map to clone.
|
||
* @param {Function} cloneFunc The function to clone values.
|
||
* @param {boolean} [isDeep] Specify a deep clone.
|
||
* @returns {Object} Returns the cloned map.
|
||
*/
|
||
function cloneMap(map, isDeep, cloneFunc) {
|
||
var array = isDeep ? cloneFunc(mapToArray(map), CLONE_DEEP_FLAG) : mapToArray(map);
|
||
return arrayReduce(array, addMapEntry, new map.constructor);
|
||
}
|
||
|
||
/**
|
||
* Creates a clone of `regexp`.
|
||
*
|
||
* @private
|
||
* @param {Object} regexp The regexp to clone.
|
||
* @returns {Object} Returns the cloned regexp.
|
||
*/
|
||
function cloneRegExp(regexp) {
|
||
var result = new regexp.constructor(regexp.source, reFlags.exec(regexp));
|
||
result.lastIndex = regexp.lastIndex;
|
||
return result;
|
||
}
|
||
|
||
/**
|
||
* Creates a clone of `set`.
|
||
*
|
||
* @private
|
||
* @param {Object} set The set to clone.
|
||
* @param {Function} cloneFunc The function to clone values.
|
||
* @param {boolean} [isDeep] Specify a deep clone.
|
||
* @returns {Object} Returns the cloned set.
|
||
*/
|
||
function cloneSet(set, isDeep, cloneFunc) {
|
||
var array = isDeep ? cloneFunc(setToArray(set), CLONE_DEEP_FLAG) : setToArray(set);
|
||
return arrayReduce(array, addSetEntry, new set.constructor);
|
||
}
|
||
|
||
/**
|
||
* Creates a clone of the `symbol` object.
|
||
*
|
||
* @private
|
||
* @param {Object} symbol The symbol object to clone.
|
||
* @returns {Object} Returns the cloned symbol object.
|
||
*/
|
||
function cloneSymbol(symbol) {
|
||
return symbolValueOf ? Object(symbolValueOf.call(symbol)) : {};
|
||
}
|
||
|
||
/**
|
||
* Creates a clone of `typedArray`.
|
||
*
|
||
* @private
|
||
* @param {Object} typedArray The typed array to clone.
|
||
* @param {boolean} [isDeep] Specify a deep clone.
|
||
* @returns {Object} Returns the cloned typed array.
|
||
*/
|
||
function cloneTypedArray(typedArray, isDeep) {
|
||
var buffer = isDeep ? cloneArrayBuffer(typedArray.buffer) : typedArray.buffer;
|
||
return new typedArray.constructor(buffer, typedArray.byteOffset, typedArray.length);
|
||
}
|
||
|
||
/**
|
||
* Compares values to sort them in ascending order.
|
||
*
|
||
* @private
|
||
* @param {*} value The value to compare.
|
||
* @param {*} other The other value to compare.
|
||
* @returns {number} Returns the sort order indicator for `value`.
|
||
*/
|
||
function compareAscending(value, other) {
|
||
if (value !== other) {
|
||
var valIsDefined = value !== undefined,
|
||
valIsNull = value === null,
|
||
valIsReflexive = value === value,
|
||
valIsSymbol = isSymbol(value);
|
||
|
||
var othIsDefined = other !== undefined,
|
||
othIsNull = other === null,
|
||
othIsReflexive = other === other,
|
||
othIsSymbol = isSymbol(other);
|
||
|
||
if ((!othIsNull && !othIsSymbol && !valIsSymbol && value > other) ||
|
||
(valIsSymbol && othIsDefined && othIsReflexive && !othIsNull && !othIsSymbol) ||
|
||
(valIsNull && othIsDefined && othIsReflexive) ||
|
||
(!valIsDefined && othIsReflexive) ||
|
||
!valIsReflexive) {
|
||
return 1;
|
||
}
|
||
if ((!valIsNull && !valIsSymbol && !othIsSymbol && value < other) ||
|
||
(othIsSymbol && valIsDefined && valIsReflexive && !valIsNull && !valIsSymbol) ||
|
||
(othIsNull && valIsDefined && valIsReflexive) ||
|
||
(!othIsDefined && valIsReflexive) ||
|
||
!othIsReflexive) {
|
||
return -1;
|
||
}
|
||
}
|
||
return 0;
|
||
}
|
||
|
||
/**
|
||
* Used by `_.orderBy` to compare multiple properties of a value to another
|
||
* and stable sort them.
|
||
*
|
||
* If `orders` is unspecified, all values are sorted in ascending order. Otherwise,
|
||
* specify an order of "desc" for descending or "asc" for ascending sort order
|
||
* of corresponding values.
|
||
*
|
||
* @private
|
||
* @param {Object} object The object to compare.
|
||
* @param {Object} other The other object to compare.
|
||
* @param {boolean[]|string[]} orders The order to sort by for each property.
|
||
* @returns {number} Returns the sort order indicator for `object`.
|
||
*/
|
||
function compareMultiple(object, other, orders) {
|
||
var index = -1,
|
||
objCriteria = object.criteria,
|
||
othCriteria = other.criteria,
|
||
length = objCriteria.length,
|
||
ordersLength = orders.length;
|
||
|
||
while (++index < length) {
|
||
var result = compareAscending(objCriteria[index], othCriteria[index]);
|
||
if (result) {
|
||
if (index >= ordersLength) {
|
||
return result;
|
||
}
|
||
var order = orders[index];
|
||
return result * (order == 'desc' ? -1 : 1);
|
||
}
|
||
}
|
||
// Fixes an `Array#sort` bug in the JS engine embedded in Adobe applications
|
||
// that causes it, under certain circumstances, to provide the same value for
|
||
// `object` and `other`. See https://github.com/jashkenas/underscore/pull/1247
|
||
// for more details.
|
||
//
|
||
// This also ensures a stable sort in V8 and other engines.
|
||
// See https://bugs.chromium.org/p/v8/issues/detail?id=90 for more details.
|
||
return object.index - other.index;
|
||
}
|
||
|
||
/**
|
||
* Creates an array that is the composition of partially applied arguments,
|
||
* placeholders, and provided arguments into a single array of arguments.
|
||
*
|
||
* @private
|
||
* @param {Array} args The provided arguments.
|
||
* @param {Array} partials The arguments to prepend to those provided.
|
||
* @param {Array} holders The `partials` placeholder indexes.
|
||
* @params {boolean} [isCurried] Specify composing for a curried function.
|
||
* @returns {Array} Returns the new array of composed arguments.
|
||
*/
|
||
function composeArgs(args, partials, holders, isCurried) {
|
||
var argsIndex = -1,
|
||
argsLength = args.length,
|
||
holdersLength = holders.length,
|
||
leftIndex = -1,
|
||
leftLength = partials.length,
|
||
rangeLength = nativeMax(argsLength - holdersLength, 0),
|
||
result = Array(leftLength + rangeLength),
|
||
isUncurried = !isCurried;
|
||
|
||
while (++leftIndex < leftLength) {
|
||
result[leftIndex] = partials[leftIndex];
|
||
}
|
||
while (++argsIndex < holdersLength) {
|
||
if (isUncurried || argsIndex < argsLength) {
|
||
result[holders[argsIndex]] = args[argsIndex];
|
||
}
|
||
}
|
||
while (rangeLength--) {
|
||
result[leftIndex++] = args[argsIndex++];
|
||
}
|
||
return result;
|
||
}
|
||
|
||
/**
|
||
* This function is like `composeArgs` except that the arguments composition
|
||
* is tailored for `_.partialRight`.
|
||
*
|
||
* @private
|
||
* @param {Array} args The provided arguments.
|
||
* @param {Array} partials The arguments to append to those provided.
|
||
* @param {Array} holders The `partials` placeholder indexes.
|
||
* @params {boolean} [isCurried] Specify composing for a curried function.
|
||
* @returns {Array} Returns the new array of composed arguments.
|
||
*/
|
||
function composeArgsRight(args, partials, holders, isCurried) {
|
||
var argsIndex = -1,
|
||
argsLength = args.length,
|
||
holdersIndex = -1,
|
||
holdersLength = holders.length,
|
||
rightIndex = -1,
|
||
rightLength = partials.length,
|
||
rangeLength = nativeMax(argsLength - holdersLength, 0),
|
||
result = Array(rangeLength + rightLength),
|
||
isUncurried = !isCurried;
|
||
|
||
while (++argsIndex < rangeLength) {
|
||
result[argsIndex] = args[argsIndex];
|
||
}
|
||
var offset = argsIndex;
|
||
while (++rightIndex < rightLength) {
|
||
result[offset + rightIndex] = partials[rightIndex];
|
||
}
|
||
while (++holdersIndex < holdersLength) {
|
||
if (isUncurried || argsIndex < argsLength) {
|
||
result[offset + holders[holdersIndex]] = args[argsIndex++];
|
||
}
|
||
}
|
||
return result;
|
||
}
|
||
|
||
/**
|
||
* Copies the values of `source` to `array`.
|
||
*
|
||
* @private
|
||
* @param {Array} source The array to copy values from.
|
||
* @param {Array} [array=[]] The array to copy values to.
|
||
* @returns {Array} Returns `array`.
|
||
*/
|
||
function copyArray(source, array) {
|
||
var index = -1,
|
||
length = source.length;
|
||
|
||
array || (array = Array(length));
|
||
while (++index < length) {
|
||
array[index] = source[index];
|
||
}
|
||
return array;
|
||
}
|
||
|
||
/**
|
||
* Copies properties of `source` to `object`.
|
||
*
|
||
* @private
|
||
* @param {Object} source The object to copy properties from.
|
||
* @param {Array} props The property identifiers to copy.
|
||
* @param {Object} [object={}] The object to copy properties to.
|
||
* @param {Function} [customizer] The function to customize copied values.
|
||
* @returns {Object} Returns `object`.
|
||
*/
|
||
function copyObject(source, props, object, customizer) {
|
||
var isNew = !object;
|
||
object || (object = {});
|
||
|
||
var index = -1,
|
||
length = props.length;
|
||
|
||
while (++index < length) {
|
||
var key = props[index];
|
||
|
||
var newValue = customizer
|
||
? customizer(object[key], source[key], key, object, source)
|
||
: undefined;
|
||
|
||
if (newValue === undefined) {
|
||
newValue = source[key];
|
||
}
|
||
if (isNew) {
|
||
baseAssignValue(object, key, newValue);
|
||
} else {
|
||
assignValue(object, key, newValue);
|
||
}
|
||
}
|
||
return object;
|
||
}
|
||
|
||
/**
|
||
* Copies own symbols of `source` to `object`.
|
||
*
|
||
* @private
|
||
* @param {Object} source The object to copy symbols from.
|
||
* @param {Object} [object={}] The object to copy symbols to.
|
||
* @returns {Object} Returns `object`.
|
||
*/
|
||
function copySymbols(source, object) {
|
||
return copyObject(source, getSymbols(source), object);
|
||
}
|
||
|
||
/**
|
||
* Copies own and inherited symbols of `source` to `object`.
|
||
*
|
||
* @private
|
||
* @param {Object} source The object to copy symbols from.
|
||
* @param {Object} [object={}] The object to copy symbols to.
|
||
* @returns {Object} Returns `object`.
|
||
*/
|
||
function copySymbolsIn(source, object) {
|
||
return copyObject(source, getSymbolsIn(source), object);
|
||
}
|
||
|
||
/**
|
||
* Creates a function like `_.groupBy`.
|
||
*
|
||
* @private
|
||
* @param {Function} setter The function to set accumulator values.
|
||
* @param {Function} [initializer] The accumulator object initializer.
|
||
* @returns {Function} Returns the new aggregator function.
|
||
*/
|
||
function createAggregator(setter, initializer) {
|
||
return function(collection, iteratee) {
|
||
var func = isArray(collection) ? arrayAggregator : baseAggregator,
|
||
accumulator = initializer ? initializer() : {};
|
||
|
||
return func(collection, setter, getIteratee(iteratee, 2), accumulator);
|
||
};
|
||
}
|
||
|
||
/**
|
||
* Creates a function like `_.assign`.
|
||
*
|
||
* @private
|
||
* @param {Function} assigner The function to assign values.
|
||
* @returns {Function} Returns the new assigner function.
|
||
*/
|
||
function createAssigner(assigner) {
|
||
return baseRest(function(object, sources) {
|
||
var index = -1,
|
||
length = sources.length,
|
||
customizer = length > 1 ? sources[length - 1] : undefined,
|
||
guard = length > 2 ? sources[2] : undefined;
|
||
|
||
customizer = (assigner.length > 3 && typeof customizer == 'function')
|
||
? (length--, customizer)
|
||
: undefined;
|
||
|
||
if (guard && isIterateeCall(sources[0], sources[1], guard)) {
|
||
customizer = length < 3 ? undefined : customizer;
|
||
length = 1;
|
||
}
|
||
object = Object(object);
|
||
while (++index < length) {
|
||
var source = sources[index];
|
||
if (source) {
|
||
assigner(object, source, index, customizer);
|
||
}
|
||
}
|
||
return object;
|
||
});
|
||
}
|
||
|
||
/**
|
||
* Creates a `baseEach` or `baseEachRight` function.
|
||
*
|
||
* @private
|
||
* @param {Function} eachFunc The function to iterate over a collection.
|
||
* @param {boolean} [fromRight] Specify iterating from right to left.
|
||
* @returns {Function} Returns the new base function.
|
||
*/
|
||
function createBaseEach(eachFunc, fromRight) {
|
||
return function(collection, iteratee) {
|
||
if (collection == null) {
|
||
return collection;
|
||
}
|
||
if (!isArrayLike(collection)) {
|
||
return eachFunc(collection, iteratee);
|
||
}
|
||
var length = collection.length,
|
||
index = fromRight ? length : -1,
|
||
iterable = Object(collection);
|
||
|
||
while ((fromRight ? index-- : ++index < length)) {
|
||
if (iteratee(iterable[index], index, iterable) === false) {
|
||
break;
|
||
}
|
||
}
|
||
return collection;
|
||
};
|
||
}
|
||
|
||
/**
|
||
* Creates a base function for methods like `_.forIn` and `_.forOwn`.
|
||
*
|
||
* @private
|
||
* @param {boolean} [fromRight] Specify iterating from right to left.
|
||
* @returns {Function} Returns the new base function.
|
||
*/
|
||
function createBaseFor(fromRight) {
|
||
return function(object, iteratee, keysFunc) {
|
||
var index = -1,
|
||
iterable = Object(object),
|
||
props = keysFunc(object),
|
||
length = props.length;
|
||
|
||
while (length--) {
|
||
var key = props[fromRight ? length : ++index];
|
||
if (iteratee(iterable[key], key, iterable) === false) {
|
||
break;
|
||
}
|
||
}
|
||
return object;
|
||
};
|
||
}
|
||
|
||
/**
|
||
* Creates a function that wraps `func` to invoke it with the optional `this`
|
||
* binding of `thisArg`.
|
||
*
|
||
* @private
|
||
* @param {Function} func The function to wrap.
|
||
* @param {number} bitmask The bitmask flags. See `createWrap` for more details.
|
||
* @param {*} [thisArg] The `this` binding of `func`.
|
||
* @returns {Function} Returns the new wrapped function.
|
||
*/
|
||
function createBind(func, bitmask, thisArg) {
|
||
var isBind = bitmask & WRAP_BIND_FLAG,
|
||
Ctor = createCtor(func);
|
||
|
||
function wrapper() {
|
||
var fn = (this && this !== root && this instanceof wrapper) ? Ctor : func;
|
||
return fn.apply(isBind ? thisArg : this, arguments);
|
||
}
|
||
return wrapper;
|
||
}
|
||
|
||
/**
|
||
* Creates a function like `_.lowerFirst`.
|
||
*
|
||
* @private
|
||
* @param {string} methodName The name of the `String` case method to use.
|
||
* @returns {Function} Returns the new case function.
|
||
*/
|
||
function createCaseFirst(methodName) {
|
||
return function(string) {
|
||
string = toString(string);
|
||
|
||
var strSymbols = hasUnicode(string)
|
||
? stringToArray(string)
|
||
: undefined;
|
||
|
||
var chr = strSymbols
|
||
? strSymbols[0]
|
||
: string.charAt(0);
|
||
|
||
var trailing = strSymbols
|
||
? castSlice(strSymbols, 1).join('')
|
||
: string.slice(1);
|
||
|
||
return chr[methodName]() + trailing;
|
||
};
|
||
}
|
||
|
||
/**
|
||
* Creates a function like `_.camelCase`.
|
||
*
|
||
* @private
|
||
* @param {Function} callback The function to combine each word.
|
||
* @returns {Function} Returns the new compounder function.
|
||
*/
|
||
function createCompounder(callback) {
|
||
return function(string) {
|
||
return arrayReduce(words(deburr(string).replace(reApos, '')), callback, '');
|
||
};
|
||
}
|
||
|
||
/**
|
||
* Creates a function that produces an instance of `Ctor` regardless of
|
||
* whether it was invoked as part of a `new` expression or by `call` or `apply`.
|
||
*
|
||
* @private
|
||
* @param {Function} Ctor The constructor to wrap.
|
||
* @returns {Function} Returns the new wrapped function.
|
||
*/
|
||
function createCtor(Ctor) {
|
||
return function() {
|
||
// Use a `switch` statement to work with class constructors. See
|
||
// http://ecma-international.org/ecma-262/7.0/#sec-ecmascript-function-objects-call-thisargument-argumentslist
|
||
// for more details.
|
||
var args = arguments;
|
||
switch (args.length) {
|
||
case 0: return new Ctor;
|
||
case 1: return new Ctor(args[0]);
|
||
case 2: return new Ctor(args[0], args[1]);
|
||
case 3: return new Ctor(args[0], args[1], args[2]);
|
||
case 4: return new Ctor(args[0], args[1], args[2], args[3]);
|
||
case 5: return new Ctor(args[0], args[1], args[2], args[3], args[4]);
|
||
case 6: return new Ctor(args[0], args[1], args[2], args[3], args[4], args[5]);
|
||
case 7: return new Ctor(args[0], args[1], args[2], args[3], args[4], args[5], args[6]);
|
||
}
|
||
var thisBinding = baseCreate(Ctor.prototype),
|
||
result = Ctor.apply(thisBinding, args);
|
||
|
||
// Mimic the constructor's `return` behavior.
|
||
// See https://es5.github.io/#x13.2.2 for more details.
|
||
return isObject(result) ? result : thisBinding;
|
||
};
|
||
}
|
||
|
||
/**
|
||
* Creates a function that wraps `func` to enable currying.
|
||
*
|
||
* @private
|
||
* @param {Function} func The function to wrap.
|
||
* @param {number} bitmask The bitmask flags. See `createWrap` for more details.
|
||
* @param {number} arity The arity of `func`.
|
||
* @returns {Function} Returns the new wrapped function.
|
||
*/
|
||
function createCurry(func, bitmask, arity) {
|
||
var Ctor = createCtor(func);
|
||
|
||
function wrapper() {
|
||
var length = arguments.length,
|
||
args = Array(length),
|
||
index = length,
|
||
placeholder = getHolder(wrapper);
|
||
|
||
while (index--) {
|
||
args[index] = arguments[index];
|
||
}
|
||
var holders = (length < 3 && args[0] !== placeholder && args[length - 1] !== placeholder)
|
||
? []
|
||
: replaceHolders(args, placeholder);
|
||
|
||
length -= holders.length;
|
||
if (length < arity) {
|
||
return createRecurry(
|
||
func, bitmask, createHybrid, wrapper.placeholder, undefined,
|
||
args, holders, undefined, undefined, arity - length);
|
||
}
|
||
var fn = (this && this !== root && this instanceof wrapper) ? Ctor : func;
|
||
return apply(fn, this, args);
|
||
}
|
||
return wrapper;
|
||
}
|
||
|
||
/**
|
||
* Creates a `_.find` or `_.findLast` function.
|
||
*
|
||
* @private
|
||
* @param {Function} findIndexFunc The function to find the collection index.
|
||
* @returns {Function} Returns the new find function.
|
||
*/
|
||
function createFind(findIndexFunc) {
|
||
return function(collection, predicate, fromIndex) {
|
||
var iterable = Object(collection);
|
||
if (!isArrayLike(collection)) {
|
||
var iteratee = getIteratee(predicate, 3);
|
||
collection = keys(collection);
|
||
predicate = function(key) { return iteratee(iterable[key], key, iterable); };
|
||
}
|
||
var index = findIndexFunc(collection, predicate, fromIndex);
|
||
return index > -1 ? iterable[iteratee ? collection[index] : index] : undefined;
|
||
};
|
||
}
|
||
|
||
/**
|
||
* Creates a `_.flow` or `_.flowRight` function.
|
||
*
|
||
* @private
|
||
* @param {boolean} [fromRight] Specify iterating from right to left.
|
||
* @returns {Function} Returns the new flow function.
|
||
*/
|
||
function createFlow(fromRight) {
|
||
return flatRest(function(funcs) {
|
||
var length = funcs.length,
|
||
index = length,
|
||
prereq = LodashWrapper.prototype.thru;
|
||
|
||
if (fromRight) {
|
||
funcs.reverse();
|
||
}
|
||
while (index--) {
|
||
var func = funcs[index];
|
||
if (typeof func != 'function') {
|
||
throw new TypeError(FUNC_ERROR_TEXT);
|
||
}
|
||
if (prereq && !wrapper && getFuncName(func) == 'wrapper') {
|
||
var wrapper = new LodashWrapper([], true);
|
||
}
|
||
}
|
||
index = wrapper ? index : length;
|
||
while (++index < length) {
|
||
func = funcs[index];
|
||
|
||
var funcName = getFuncName(func),
|
||
data = funcName == 'wrapper' ? getData(func) : undefined;
|
||
|
||
if (data && isLaziable(data[0]) &&
|
||
data[1] == (WRAP_ARY_FLAG | WRAP_CURRY_FLAG | WRAP_PARTIAL_FLAG | WRAP_REARG_FLAG) &&
|
||
!data[4].length && data[9] == 1
|
||
) {
|
||
wrapper = wrapper[getFuncName(data[0])].apply(wrapper, data[3]);
|
||
} else {
|
||
wrapper = (func.length == 1 && isLaziable(func))
|
||
? wrapper[funcName]()
|
||
: wrapper.thru(func);
|
||
}
|
||
}
|
||
return function() {
|
||
var args = arguments,
|
||
value = args[0];
|
||
|
||
if (wrapper && args.length == 1 && isArray(value)) {
|
||
return wrapper.plant(value).value();
|
||
}
|
||
var index = 0,
|
||
result = length ? funcs[index].apply(this, args) : value;
|
||
|
||
while (++index < length) {
|
||
result = funcs[index].call(this, result);
|
||
}
|
||
return result;
|
||
};
|
||
});
|
||
}
|
||
|
||
/**
|
||
* Creates a function that wraps `func` to invoke it with optional `this`
|
||
* binding of `thisArg`, partial application, and currying.
|
||
*
|
||
* @private
|
||
* @param {Function|string} func The function or method name to wrap.
|
||
* @param {number} bitmask The bitmask flags. See `createWrap` for more details.
|
||
* @param {*} [thisArg] The `this` binding of `func`.
|
||
* @param {Array} [partials] The arguments to prepend to those provided to
|
||
* the new function.
|
||
* @param {Array} [holders] The `partials` placeholder indexes.
|
||
* @param {Array} [partialsRight] The arguments to append to those provided
|
||
* to the new function.
|
||
* @param {Array} [holdersRight] The `partialsRight` placeholder indexes.
|
||
* @param {Array} [argPos] The argument positions of the new function.
|
||
* @param {number} [ary] The arity cap of `func`.
|
||
* @param {number} [arity] The arity of `func`.
|
||
* @returns {Function} Returns the new wrapped function.
|
||
*/
|
||
function createHybrid(func, bitmask, thisArg, partials, holders, partialsRight, holdersRight, argPos, ary, arity) {
|
||
var isAry = bitmask & WRAP_ARY_FLAG,
|
||
isBind = bitmask & WRAP_BIND_FLAG,
|
||
isBindKey = bitmask & WRAP_BIND_KEY_FLAG,
|
||
isCurried = bitmask & (WRAP_CURRY_FLAG | WRAP_CURRY_RIGHT_FLAG),
|
||
isFlip = bitmask & WRAP_FLIP_FLAG,
|
||
Ctor = isBindKey ? undefined : createCtor(func);
|
||
|
||
function wrapper() {
|
||
var length = arguments.length,
|
||
args = Array(length),
|
||
index = length;
|
||
|
||
while (index--) {
|
||
args[index] = arguments[index];
|
||
}
|
||
if (isCurried) {
|
||
var placeholder = getHolder(wrapper),
|
||
holdersCount = countHolders(args, placeholder);
|
||
}
|
||
if (partials) {
|
||
args = composeArgs(args, partials, holders, isCurried);
|
||
}
|
||
if (partialsRight) {
|
||
args = composeArgsRight(args, partialsRight, holdersRight, isCurried);
|
||
}
|
||
length -= holdersCount;
|
||
if (isCurried && length < arity) {
|
||
var newHolders = replaceHolders(args, placeholder);
|
||
return createRecurry(
|
||
func, bitmask, createHybrid, wrapper.placeholder, thisArg,
|
||
args, newHolders, argPos, ary, arity - length
|
||
);
|
||
}
|
||
var thisBinding = isBind ? thisArg : this,
|
||
fn = isBindKey ? thisBinding[func] : func;
|
||
|
||
length = args.length;
|
||
if (argPos) {
|
||
args = reorder(args, argPos);
|
||
} else if (isFlip && length > 1) {
|
||
args.reverse();
|
||
}
|
||
if (isAry && ary < length) {
|
||
args.length = ary;
|
||
}
|
||
if (this && this !== root && this instanceof wrapper) {
|
||
fn = Ctor || createCtor(fn);
|
||
}
|
||
return fn.apply(thisBinding, args);
|
||
}
|
||
return wrapper;
|
||
}
|
||
|
||
/**
|
||
* Creates a function like `_.invertBy`.
|
||
*
|
||
* @private
|
||
* @param {Function} setter The function to set accumulator values.
|
||
* @param {Function} toIteratee The function to resolve iteratees.
|
||
* @returns {Function} Returns the new inverter function.
|
||
*/
|
||
function createInverter(setter, toIteratee) {
|
||
return function(object, iteratee) {
|
||
return baseInverter(object, setter, toIteratee(iteratee), {});
|
||
};
|
||
}
|
||
|
||
/**
|
||
* Creates a function that performs a mathematical operation on two values.
|
||
*
|
||
* @private
|
||
* @param {Function} operator The function to perform the operation.
|
||
* @param {number} [defaultValue] The value used for `undefined` arguments.
|
||
* @returns {Function} Returns the new mathematical operation function.
|
||
*/
|
||
function createMathOperation(operator, defaultValue) {
|
||
return function(value, other) {
|
||
var result;
|
||
if (value === undefined && other === undefined) {
|
||
return defaultValue;
|
||
}
|
||
if (value !== undefined) {
|
||
result = value;
|
||
}
|
||
if (other !== undefined) {
|
||
if (result === undefined) {
|
||
return other;
|
||
}
|
||
if (typeof value == 'string' || typeof other == 'string') {
|
||
value = baseToString(value);
|
||
other = baseToString(other);
|
||
} else {
|
||
value = baseToNumber(value);
|
||
other = baseToNumber(other);
|
||
}
|
||
result = operator(value, other);
|
||
}
|
||
return result;
|
||
};
|
||
}
|
||
|
||
/**
|
||
* Creates a function like `_.over`.
|
||
*
|
||
* @private
|
||
* @param {Function} arrayFunc The function to iterate over iteratees.
|
||
* @returns {Function} Returns the new over function.
|
||
*/
|
||
function createOver(arrayFunc) {
|
||
return flatRest(function(iteratees) {
|
||
iteratees = arrayMap(iteratees, baseUnary(getIteratee()));
|
||
return baseRest(function(args) {
|
||
var thisArg = this;
|
||
return arrayFunc(iteratees, function(iteratee) {
|
||
return apply(iteratee, thisArg, args);
|
||
});
|
||
});
|
||
});
|
||
}
|
||
|
||
/**
|
||
* Creates the padding for `string` based on `length`. The `chars` string
|
||
* is truncated if the number of characters exceeds `length`.
|
||
*
|
||
* @private
|
||
* @param {number} length The padding length.
|
||
* @param {string} [chars=' '] The string used as padding.
|
||
* @returns {string} Returns the padding for `string`.
|
||
*/
|
||
function createPadding(length, chars) {
|
||
chars = chars === undefined ? ' ' : baseToString(chars);
|
||
|
||
var charsLength = chars.length;
|
||
if (charsLength < 2) {
|
||
return charsLength ? baseRepeat(chars, length) : chars;
|
||
}
|
||
var result = baseRepeat(chars, nativeCeil(length / stringSize(chars)));
|
||
return hasUnicode(chars)
|
||
? castSlice(stringToArray(result), 0, length).join('')
|
||
: result.slice(0, length);
|
||
}
|
||
|
||
/**
|
||
* Creates a function that wraps `func` to invoke it with the `this` binding
|
||
* of `thisArg` and `partials` prepended to the arguments it receives.
|
||
*
|
||
* @private
|
||
* @param {Function} func The function to wrap.
|
||
* @param {number} bitmask The bitmask flags. See `createWrap` for more details.
|
||
* @param {*} thisArg The `this` binding of `func`.
|
||
* @param {Array} partials The arguments to prepend to those provided to
|
||
* the new function.
|
||
* @returns {Function} Returns the new wrapped function.
|
||
*/
|
||
function createPartial(func, bitmask, thisArg, partials) {
|
||
var isBind = bitmask & WRAP_BIND_FLAG,
|
||
Ctor = createCtor(func);
|
||
|
||
function wrapper() {
|
||
var argsIndex = -1,
|
||
argsLength = arguments.length,
|
||
leftIndex = -1,
|
||
leftLength = partials.length,
|
||
args = Array(leftLength + argsLength),
|
||
fn = (this && this !== root && this instanceof wrapper) ? Ctor : func;
|
||
|
||
while (++leftIndex < leftLength) {
|
||
args[leftIndex] = partials[leftIndex];
|
||
}
|
||
while (argsLength--) {
|
||
args[leftIndex++] = arguments[++argsIndex];
|
||
}
|
||
return apply(fn, isBind ? thisArg : this, args);
|
||
}
|
||
return wrapper;
|
||
}
|
||
|
||
/**
|
||
* Creates a `_.range` or `_.rangeRight` function.
|
||
*
|
||
* @private
|
||
* @param {boolean} [fromRight] Specify iterating from right to left.
|
||
* @returns {Function} Returns the new range function.
|
||
*/
|
||
function createRange(fromRight) {
|
||
return function(start, end, step) {
|
||
if (step && typeof step != 'number' && isIterateeCall(start, end, step)) {
|
||
end = step = undefined;
|
||
}
|
||
// Ensure the sign of `-0` is preserved.
|
||
start = toFinite(start);
|
||
if (end === undefined) {
|
||
end = start;
|
||
start = 0;
|
||
} else {
|
||
end = toFinite(end);
|
||
}
|
||
step = step === undefined ? (start < end ? 1 : -1) : toFinite(step);
|
||
return baseRange(start, end, step, fromRight);
|
||
};
|
||
}
|
||
|
||
/**
|
||
* Creates a function that performs a relational operation on two values.
|
||
*
|
||
* @private
|
||
* @param {Function} operator The function to perform the operation.
|
||
* @returns {Function} Returns the new relational operation function.
|
||
*/
|
||
function createRelationalOperation(operator) {
|
||
return function(value, other) {
|
||
if (!(typeof value == 'string' && typeof other == 'string')) {
|
||
value = toNumber(value);
|
||
other = toNumber(other);
|
||
}
|
||
return operator(value, other);
|
||
};
|
||
}
|
||
|
||
/**
|
||
* Creates a function that wraps `func` to continue currying.
|
||
*
|
||
* @private
|
||
* @param {Function} func The function to wrap.
|
||
* @param {number} bitmask The bitmask flags. See `createWrap` for more details.
|
||
* @param {Function} wrapFunc The function to create the `func` wrapper.
|
||
* @param {*} placeholder The placeholder value.
|
||
* @param {*} [thisArg] The `this` binding of `func`.
|
||
* @param {Array} [partials] The arguments to prepend to those provided to
|
||
* the new function.
|
||
* @param {Array} [holders] The `partials` placeholder indexes.
|
||
* @param {Array} [argPos] The argument positions of the new function.
|
||
* @param {number} [ary] The arity cap of `func`.
|
||
* @param {number} [arity] The arity of `func`.
|
||
* @returns {Function} Returns the new wrapped function.
|
||
*/
|
||
function createRecurry(func, bitmask, wrapFunc, placeholder, thisArg, partials, holders, argPos, ary, arity) {
|
||
var isCurry = bitmask & WRAP_CURRY_FLAG,
|
||
newHolders = isCurry ? holders : undefined,
|
||
newHoldersRight = isCurry ? undefined : holders,
|
||
newPartials = isCurry ? partials : undefined,
|
||
newPartialsRight = isCurry ? undefined : partials;
|
||
|
||
bitmask |= (isCurry ? WRAP_PARTIAL_FLAG : WRAP_PARTIAL_RIGHT_FLAG);
|
||
bitmask &= ~(isCurry ? WRAP_PARTIAL_RIGHT_FLAG : WRAP_PARTIAL_FLAG);
|
||
|
||
if (!(bitmask & WRAP_CURRY_BOUND_FLAG)) {
|
||
bitmask &= ~(WRAP_BIND_FLAG | WRAP_BIND_KEY_FLAG);
|
||
}
|
||
var newData = [
|
||
func, bitmask, thisArg, newPartials, newHolders, newPartialsRight,
|
||
newHoldersRight, argPos, ary, arity
|
||
];
|
||
|
||
var result = wrapFunc.apply(undefined, newData);
|
||
if (isLaziable(func)) {
|
||
setData(result, newData);
|
||
}
|
||
result.placeholder = placeholder;
|
||
return setWrapToString(result, func, bitmask);
|
||
}
|
||
|
||
/**
|
||
* Creates a function like `_.round`.
|
||
*
|
||
* @private
|
||
* @param {string} methodName The name of the `Math` method to use when rounding.
|
||
* @returns {Function} Returns the new round function.
|
||
*/
|
||
function createRound(methodName) {
|
||
var func = Math[methodName];
|
||
return function(number, precision) {
|
||
number = toNumber(number);
|
||
precision = precision == null ? 0 : nativeMin(toInteger(precision), 292);
|
||
if (precision) {
|
||
// Shift with exponential notation to avoid floating-point issues.
|
||
// See [MDN](https://mdn.io/round#Examples) for more details.
|
||
var pair = (toString(number) + 'e').split('e'),
|
||
value = func(pair[0] + 'e' + (+pair[1] + precision));
|
||
|
||
pair = (toString(value) + 'e').split('e');
|
||
return +(pair[0] + 'e' + (+pair[1] - precision));
|
||
}
|
||
return func(number);
|
||
};
|
||
}
|
||
|
||
/**
|
||
* Creates a set object of `values`.
|
||
*
|
||
* @private
|
||
* @param {Array} values The values to add to the set.
|
||
* @returns {Object} Returns the new set.
|
||
*/
|
||
var createSet = !(Set && (1 / setToArray(new Set([,-0]))[1]) == INFINITY) ? noop : function(values) {
|
||
return new Set(values);
|
||
};
|
||
|
||
/**
|
||
* Creates a `_.toPairs` or `_.toPairsIn` function.
|
||
*
|
||
* @private
|
||
* @param {Function} keysFunc The function to get the keys of a given object.
|
||
* @returns {Function} Returns the new pairs function.
|
||
*/
|
||
function createToPairs(keysFunc) {
|
||
return function(object) {
|
||
var tag = getTag(object);
|
||
if (tag == mapTag) {
|
||
return mapToArray(object);
|
||
}
|
||
if (tag == setTag) {
|
||
return setToPairs(object);
|
||
}
|
||
return baseToPairs(object, keysFunc(object));
|
||
};
|
||
}
|
||
|
||
/**
|
||
* Creates a function that either curries or invokes `func` with optional
|
||
* `this` binding and partially applied arguments.
|
||
*
|
||
* @private
|
||
* @param {Function|string} func The function or method name to wrap.
|
||
* @param {number} bitmask The bitmask flags.
|
||
* 1 - `_.bind`
|
||
* 2 - `_.bindKey`
|
||
* 4 - `_.curry` or `_.curryRight` of a bound function
|
||
* 8 - `_.curry`
|
||
* 16 - `_.curryRight`
|
||
* 32 - `_.partial`
|
||
* 64 - `_.partialRight`
|
||
* 128 - `_.rearg`
|
||
* 256 - `_.ary`
|
||
* 512 - `_.flip`
|
||
* @param {*} [thisArg] The `this` binding of `func`.
|
||
* @param {Array} [partials] The arguments to be partially applied.
|
||
* @param {Array} [holders] The `partials` placeholder indexes.
|
||
* @param {Array} [argPos] The argument positions of the new function.
|
||
* @param {number} [ary] The arity cap of `func`.
|
||
* @param {number} [arity] The arity of `func`.
|
||
* @returns {Function} Returns the new wrapped function.
|
||
*/
|
||
function createWrap(func, bitmask, thisArg, partials, holders, argPos, ary, arity) {
|
||
var isBindKey = bitmask & WRAP_BIND_KEY_FLAG;
|
||
if (!isBindKey && typeof func != 'function') {
|
||
throw new TypeError(FUNC_ERROR_TEXT);
|
||
}
|
||
var length = partials ? partials.length : 0;
|
||
if (!length) {
|
||
bitmask &= ~(WRAP_PARTIAL_FLAG | WRAP_PARTIAL_RIGHT_FLAG);
|
||
partials = holders = undefined;
|
||
}
|
||
ary = ary === undefined ? ary : nativeMax(toInteger(ary), 0);
|
||
arity = arity === undefined ? arity : toInteger(arity);
|
||
length -= holders ? holders.length : 0;
|
||
|
||
if (bitmask & WRAP_PARTIAL_RIGHT_FLAG) {
|
||
var partialsRight = partials,
|
||
holdersRight = holders;
|
||
|
||
partials = holders = undefined;
|
||
}
|
||
var data = isBindKey ? undefined : getData(func);
|
||
|
||
var newData = [
|
||
func, bitmask, thisArg, partials, holders, partialsRight, holdersRight,
|
||
argPos, ary, arity
|
||
];
|
||
|
||
if (data) {
|
||
mergeData(newData, data);
|
||
}
|
||
func = newData[0];
|
||
bitmask = newData[1];
|
||
thisArg = newData[2];
|
||
partials = newData[3];
|
||
holders = newData[4];
|
||
arity = newData[9] = newData[9] === undefined
|
||
? (isBindKey ? 0 : func.length)
|
||
: nativeMax(newData[9] - length, 0);
|
||
|
||
if (!arity && bitmask & (WRAP_CURRY_FLAG | WRAP_CURRY_RIGHT_FLAG)) {
|
||
bitmask &= ~(WRAP_CURRY_FLAG | WRAP_CURRY_RIGHT_FLAG);
|
||
}
|
||
if (!bitmask || bitmask == WRAP_BIND_FLAG) {
|
||
var result = createBind(func, bitmask, thisArg);
|
||
} else if (bitmask == WRAP_CURRY_FLAG || bitmask == WRAP_CURRY_RIGHT_FLAG) {
|
||
result = createCurry(func, bitmask, arity);
|
||
} else if ((bitmask == WRAP_PARTIAL_FLAG || bitmask == (WRAP_BIND_FLAG | WRAP_PARTIAL_FLAG)) && !holders.length) {
|
||
result = createPartial(func, bitmask, thisArg, partials);
|
||
} else {
|
||
result = createHybrid.apply(undefined, newData);
|
||
}
|
||
var setter = data ? baseSetData : setData;
|
||
return setWrapToString(setter(result, newData), func, bitmask);
|
||
}
|
||
|
||
/**
|
||
* Used by `_.defaults` to customize its `_.assignIn` use to assign properties
|
||
* of source objects to the destination object for all destination properties
|
||
* that resolve to `undefined`.
|
||
*
|
||
* @private
|
||
* @param {*} objValue The destination value.
|
||
* @param {*} srcValue The source value.
|
||
* @param {string} key The key of the property to assign.
|
||
* @param {Object} object The parent object of `objValue`.
|
||
* @returns {*} Returns the value to assign.
|
||
*/
|
||
function customDefaultsAssignIn(objValue, srcValue, key, object) {
|
||
if (objValue === undefined ||
|
||
(eq(objValue, objectProto[key]) && !hasOwnProperty.call(object, key))) {
|
||
return srcValue;
|
||
}
|
||
return objValue;
|
||
}
|
||
|
||
/**
|
||
* Used by `_.defaultsDeep` to customize its `_.merge` use to merge source
|
||
* objects into destination objects that are passed thru.
|
||
*
|
||
* @private
|
||
* @param {*} objValue The destination value.
|
||
* @param {*} srcValue The source value.
|
||
* @param {string} key The key of the property to merge.
|
||
* @param {Object} object The parent object of `objValue`.
|
||
* @param {Object} source The parent object of `srcValue`.
|
||
* @param {Object} [stack] Tracks traversed source values and their merged
|
||
* counterparts.
|
||
* @returns {*} Returns the value to assign.
|
||
*/
|
||
function customDefaultsMerge(objValue, srcValue, key, object, source, stack) {
|
||
if (isObject(objValue) && isObject(srcValue)) {
|
||
// Recursively merge objects and arrays (susceptible to call stack limits).
|
||
stack.set(srcValue, objValue);
|
||
baseMerge(objValue, srcValue, undefined, customDefaultsMerge, stack);
|
||
stack['delete'](srcValue);
|
||
}
|
||
return objValue;
|
||
}
|
||
|
||
/**
|
||
* Used by `_.omit` to customize its `_.cloneDeep` use to only clone plain
|
||
* objects.
|
||
*
|
||
* @private
|
||
* @param {*} value The value to inspect.
|
||
* @param {string} key The key of the property to inspect.
|
||
* @returns {*} Returns the uncloned value or `undefined` to defer cloning to `_.cloneDeep`.
|
||
*/
|
||
function customOmitClone(value) {
|
||
return isPlainObject(value) ? undefined : value;
|
||
}
|
||
|
||
/**
|
||
* A specialized version of `baseIsEqualDeep` for arrays with support for
|
||
* partial deep comparisons.
|
||
*
|
||
* @private
|
||
* @param {Array} array The array to compare.
|
||
* @param {Array} other The other array to compare.
|
||
* @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.
|
||
* @param {Function} customizer The function to customize comparisons.
|
||
* @param {Function} equalFunc The function to determine equivalents of values.
|
||
* @param {Object} stack Tracks traversed `array` and `other` objects.
|
||
* @returns {boolean} Returns `true` if the arrays are equivalent, else `false`.
|
||
*/
|
||
function equalArrays(array, other, bitmask, customizer, equalFunc, stack) {
|
||
var isPartial = bitmask & COMPARE_PARTIAL_FLAG,
|
||
arrLength = array.length,
|
||
othLength = other.length;
|
||
|
||
if (arrLength != othLength && !(isPartial && othLength > arrLength)) {
|
||
return false;
|
||
}
|
||
// Assume cyclic values are equal.
|
||
var stacked = stack.get(array);
|
||
if (stacked && stack.get(other)) {
|
||
return stacked == other;
|
||
}
|
||
var index = -1,
|
||
result = true,
|
||
seen = (bitmask & COMPARE_UNORDERED_FLAG) ? new SetCache : undefined;
|
||
|
||
stack.set(array, other);
|
||
stack.set(other, array);
|
||
|
||
// Ignore non-index properties.
|
||
while (++index < arrLength) {
|
||
var arrValue = array[index],
|
||
othValue = other[index];
|
||
|
||
if (customizer) {
|
||
var compared = isPartial
|
||
? customizer(othValue, arrValue, index, other, array, stack)
|
||
: customizer(arrValue, othValue, index, array, other, stack);
|
||
}
|
||
if (compared !== undefined) {
|
||
if (compared) {
|
||
continue;
|
||
}
|
||
result = false;
|
||
break;
|
||
}
|
||
// Recursively compare arrays (susceptible to call stack limits).
|
||
if (seen) {
|
||
if (!arraySome(other, function(othValue, othIndex) {
|
||
if (!cacheHas(seen, othIndex) &&
|
||
(arrValue === othValue || equalFunc(arrValue, othValue, bitmask, customizer, stack))) {
|
||
return seen.push(othIndex);
|
||
}
|
||
})) {
|
||
result = false;
|
||
break;
|
||
}
|
||
} else if (!(
|
||
arrValue === othValue ||
|
||
equalFunc(arrValue, othValue, bitmask, customizer, stack)
|
||
)) {
|
||
result = false;
|
||
break;
|
||
}
|
||
}
|
||
stack['delete'](array);
|
||
stack['delete'](other);
|
||
return result;
|
||
}
|
||
|
||
/**
|
||
* A specialized version of `baseIsEqualDeep` for comparing objects of
|
||
* the same `toStringTag`.
|
||
*
|
||
* **Note:** This function only supports comparing values with tags of
|
||
* `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`.
|
||
*
|
||
* @private
|
||
* @param {Object} object The object to compare.
|
||
* @param {Object} other The other object to compare.
|
||
* @param {string} tag The `toStringTag` of the objects to compare.
|
||
* @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.
|
||
* @param {Function} customizer The function to customize comparisons.
|
||
* @param {Function} equalFunc The function to determine equivalents of values.
|
||
* @param {Object} stack Tracks traversed `object` and `other` objects.
|
||
* @returns {boolean} Returns `true` if the objects are equivalent, else `false`.
|
||
*/
|
||
function equalByTag(object, other, tag, bitmask, customizer, equalFunc, stack) {
|
||
switch (tag) {
|
||
case dataViewTag:
|
||
if ((object.byteLength != other.byteLength) ||
|
||
(object.byteOffset != other.byteOffset)) {
|
||
return false;
|
||
}
|
||
object = object.buffer;
|
||
other = other.buffer;
|
||
|
||
case arrayBufferTag:
|
||
if ((object.byteLength != other.byteLength) ||
|
||
!equalFunc(new Uint8Array(object), new Uint8Array(other))) {
|
||
return false;
|
||
}
|
||
return true;
|
||
|
||
case boolTag:
|
||
case dateTag:
|
||
case numberTag:
|
||
// Coerce booleans to `1` or `0` and dates to milliseconds.
|
||
// Invalid dates are coerced to `NaN`.
|
||
return eq(+object, +other);
|
||
|
||
case errorTag:
|
||
return object.name == other.name && object.message == other.message;
|
||
|
||
case regexpTag:
|
||
case stringTag:
|
||
// Coerce regexes to strings and treat strings, primitives and objects,
|
||
// as equal. See http://www.ecma-international.org/ecma-262/7.0/#sec-regexp.prototype.tostring
|
||
// for more details.
|
||
return object == (other + '');
|
||
|
||
case mapTag:
|
||
var convert = mapToArray;
|
||
|
||
case setTag:
|
||
var isPartial = bitmask & COMPARE_PARTIAL_FLAG;
|
||
convert || (convert = setToArray);
|
||
|
||
if (object.size != other.size && !isPartial) {
|
||
return false;
|
||
}
|
||
// Assume cyclic values are equal.
|
||
var stacked = stack.get(object);
|
||
if (stacked) {
|
||
return stacked == other;
|
||
}
|
||
bitmask |= COMPARE_UNORDERED_FLAG;
|
||
|
||
// Recursively compare objects (susceptible to call stack limits).
|
||
stack.set(object, other);
|
||
var result = equalArrays(convert(object), convert(other), bitmask, customizer, equalFunc, stack);
|
||
stack['delete'](object);
|
||
return result;
|
||
|
||
case symbolTag:
|
||
if (symbolValueOf) {
|
||
return symbolValueOf.call(object) == symbolValueOf.call(other);
|
||
}
|
||
}
|
||
return false;
|
||
}
|
||
|
||
/**
|
||
* A specialized version of `baseIsEqualDeep` for objects with support for
|
||
* partial deep comparisons.
|
||
*
|
||
* @private
|
||
* @param {Object} object The object to compare.
|
||
* @param {Object} other The other object to compare.
|
||
* @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.
|
||
* @param {Function} customizer The function to customize comparisons.
|
||
* @param {Function} equalFunc The function to determine equivalents of values.
|
||
* @param {Object} stack Tracks traversed `object` and `other` objects.
|
||
* @returns {boolean} Returns `true` if the objects are equivalent, else `false`.
|
||
*/
|
||
function equalObjects(object, other, bitmask, customizer, equalFunc, stack) {
|
||
var isPartial = bitmask & COMPARE_PARTIAL_FLAG,
|
||
objProps = getAllKeys(object),
|
||
objLength = objProps.length,
|
||
othProps = getAllKeys(other),
|
||
othLength = othProps.length;
|
||
|
||
if (objLength != othLength && !isPartial) {
|
||
return false;
|
||
}
|
||
var index = objLength;
|
||
while (index--) {
|
||
var key = objProps[index];
|
||
if (!(isPartial ? key in other : hasOwnProperty.call(other, key))) {
|
||
return false;
|
||
}
|
||
}
|
||
// Assume cyclic values are equal.
|
||
var stacked = stack.get(object);
|
||
if (stacked && stack.get(other)) {
|
||
return stacked == other;
|
||
}
|
||
var result = true;
|
||
stack.set(object, other);
|
||
stack.set(other, object);
|
||
|
||
var skipCtor = isPartial;
|
||
while (++index < objLength) {
|
||
key = objProps[index];
|
||
var objValue = object[key],
|
||
othValue = other[key];
|
||
|
||
if (customizer) {
|
||
var compared = isPartial
|
||
? customizer(othValue, objValue, key, other, object, stack)
|
||
: customizer(objValue, othValue, key, object, other, stack);
|
||
}
|
||
// Recursively compare objects (susceptible to call stack limits).
|
||
if (!(compared === undefined
|
||
? (objValue === othValue || equalFunc(objValue, othValue, bitmask, customizer, stack))
|
||
: compared
|
||
)) {
|
||
result = false;
|
||
break;
|
||
}
|
||
skipCtor || (skipCtor = key == 'constructor');
|
||
}
|
||
if (result && !skipCtor) {
|
||
var objCtor = object.constructor,
|
||
othCtor = other.constructor;
|
||
|
||
// Non `Object` object instances with different constructors are not equal.
|
||
if (objCtor != othCtor &&
|
||
('constructor' in object && 'constructor' in other) &&
|
||
!(typeof objCtor == 'function' && objCtor instanceof objCtor &&
|
||
typeof othCtor == 'function' && othCtor instanceof othCtor)) {
|
||
result = false;
|
||
}
|
||
}
|
||
stack['delete'](object);
|
||
stack['delete'](other);
|
||
return result;
|
||
}
|
||
|
||
/**
|
||
* A specialized version of `baseRest` which flattens the rest array.
|
||
*
|
||
* @private
|
||
* @param {Function} func The function to apply a rest parameter to.
|
||
* @returns {Function} Returns the new function.
|
||
*/
|
||
function flatRest(func) {
|
||
return setToString(overRest(func, undefined, flatten), func + '');
|
||
}
|
||
|
||
/**
|
||
* Creates an array of own enumerable property names and symbols of `object`.
|
||
*
|
||
* @private
|
||
* @param {Object} object The object to query.
|
||
* @returns {Array} Returns the array of property names and symbols.
|
||
*/
|
||
function getAllKeys(object) {
|
||
return baseGetAllKeys(object, keys, getSymbols);
|
||
}
|
||
|
||
/**
|
||
* Creates an array of own and inherited enumerable property names and
|
||
* symbols of `object`.
|
||
*
|
||
* @private
|
||
* @param {Object} object The object to query.
|
||
* @returns {Array} Returns the array of property names and symbols.
|
||
*/
|
||
function getAllKeysIn(object) {
|
||
return baseGetAllKeys(object, keysIn, getSymbolsIn);
|
||
}
|
||
|
||
/**
|
||
* Gets metadata for `func`.
|
||
*
|
||
* @private
|
||
* @param {Function} func The function to query.
|
||
* @returns {*} Returns the metadata for `func`.
|
||
*/
|
||
var getData = !metaMap ? noop : function(func) {
|
||
return metaMap.get(func);
|
||
};
|
||
|
||
/**
|
||
* Gets the name of `func`.
|
||
*
|
||
* @private
|
||
* @param {Function} func The function to query.
|
||
* @returns {string} Returns the function name.
|
||
*/
|
||
function getFuncName(func) {
|
||
var result = (func.name + ''),
|
||
array = realNames[result],
|
||
length = hasOwnProperty.call(realNames, result) ? array.length : 0;
|
||
|
||
while (length--) {
|
||
var data = array[length],
|
||
otherFunc = data.func;
|
||
if (otherFunc == null || otherFunc == func) {
|
||
return data.name;
|
||
}
|
||
}
|
||
return result;
|
||
}
|
||
|
||
/**
|
||
* Gets the argument placeholder value for `func`.
|
||
*
|
||
* @private
|
||
* @param {Function} func The function to inspect.
|
||
* @returns {*} Returns the placeholder value.
|
||
*/
|
||
function getHolder(func) {
|
||
var object = hasOwnProperty.call(lodash, 'placeholder') ? lodash : func;
|
||
return object.placeholder;
|
||
}
|
||
|
||
/**
|
||
* Gets the appropriate "iteratee" function. If `_.iteratee` is customized,
|
||
* this function returns the custom method, otherwise it returns `baseIteratee`.
|
||
* If arguments are provided, the chosen function is invoked with them and
|
||
* its result is returned.
|
||
*
|
||
* @private
|
||
* @param {*} [value] The value to convert to an iteratee.
|
||
* @param {number} [arity] The arity of the created iteratee.
|
||
* @returns {Function} Returns the chosen function or its result.
|
||
*/
|
||
function getIteratee() {
|
||
var result = lodash.iteratee || iteratee;
|
||
result = result === iteratee ? baseIteratee : result;
|
||
return arguments.length ? result(arguments[0], arguments[1]) : result;
|
||
}
|
||
|
||
/**
|
||
* Gets the data for `map`.
|
||
*
|
||
* @private
|
||
* @param {Object} map The map to query.
|
||
* @param {string} key The reference key.
|
||
* @returns {*} Returns the map data.
|
||
*/
|
||
function getMapData(map, key) {
|
||
var data = map.__data__;
|
||
return isKeyable(key)
|
||
? data[typeof key == 'string' ? 'string' : 'hash']
|
||
: data.map;
|
||
}
|
||
|
||
/**
|
||
* Gets the property names, values, and compare flags of `object`.
|
||
*
|
||
* @private
|
||
* @param {Object} object The object to query.
|
||
* @returns {Array} Returns the match data of `object`.
|
||
*/
|
||
function getMatchData(object) {
|
||
var result = keys(object),
|
||
length = result.length;
|
||
|
||
while (length--) {
|
||
var key = result[length],
|
||
value = object[key];
|
||
|
||
result[length] = [key, value, isStrictComparable(value)];
|
||
}
|
||
return result;
|
||
}
|
||
|
||
/**
|
||
* Gets the native function at `key` of `object`.
|
||
*
|
||
* @private
|
||
* @param {Object} object The object to query.
|
||
* @param {string} key The key of the method to get.
|
||
* @returns {*} Returns the function if it's native, else `undefined`.
|
||
*/
|
||
function getNative(object, key) {
|
||
var value = getValue(object, key);
|
||
return baseIsNative(value) ? value : undefined;
|
||
}
|
||
|
||
/**
|
||
* A specialized version of `baseGetTag` which ignores `Symbol.toStringTag` values.
|
||
*
|
||
* @private
|
||
* @param {*} value The value to query.
|
||
* @returns {string} Returns the raw `toStringTag`.
|
||
*/
|
||
function getRawTag(value) {
|
||
var isOwn = hasOwnProperty.call(value, symToStringTag),
|
||
tag = value[symToStringTag];
|
||
|
||
try {
|
||
value[symToStringTag] = undefined;
|
||
var unmasked = true;
|
||
} catch (e) {}
|
||
|
||
var result = nativeObjectToString.call(value);
|
||
if (unmasked) {
|
||
if (isOwn) {
|
||
value[symToStringTag] = tag;
|
||
} else {
|
||
delete value[symToStringTag];
|
||
}
|
||
}
|
||
return result;
|
||
}
|
||
|
||
/**
|
||
* Creates an array of the own enumerable symbols of `object`.
|
||
*
|
||
* @private
|
||
* @param {Object} object The object to query.
|
||
* @returns {Array} Returns the array of symbols.
|
||
*/
|
||
var getSymbols = !nativeGetSymbols ? stubArray : function(object) {
|
||
if (object == null) {
|
||
return [];
|
||
}
|
||
object = Object(object);
|
||
return arrayFilter(nativeGetSymbols(object), function(symbol) {
|
||
return propertyIsEnumerable.call(object, symbol);
|
||
});
|
||
};
|
||
|
||
/**
|
||
* Creates an array of the own and inherited enumerable symbols of `object`.
|
||
*
|
||
* @private
|
||
* @param {Object} object The object to query.
|
||
* @returns {Array} Returns the array of symbols.
|
||
*/
|
||
var getSymbolsIn = !nativeGetSymbols ? stubArray : function(object) {
|
||
var result = [];
|
||
while (object) {
|
||
arrayPush(result, getSymbols(object));
|
||
object = getPrototype(object);
|
||
}
|
||
return result;
|
||
};
|
||
|
||
/**
|
||
* Gets the `toStringTag` of `value`.
|
||
*
|
||
* @private
|
||
* @param {*} value The value to query.
|
||
* @returns {string} Returns the `toStringTag`.
|
||
*/
|
||
var getTag = baseGetTag;
|
||
|
||
// Fallback for data views, maps, sets, and weak maps in IE 11 and promises in Node.js < 6.
|
||
if ((DataView && getTag(new DataView(new ArrayBuffer(1))) != dataViewTag) ||
|
||
(Map && getTag(new Map) != mapTag) ||
|
||
(Promise && getTag(Promise.resolve()) != promiseTag) ||
|
||
(Set && getTag(new Set) != setTag) ||
|
||
(WeakMap && getTag(new WeakMap) != weakMapTag)) {
|
||
getTag = function(value) {
|
||
var result = baseGetTag(value),
|
||
Ctor = result == objectTag ? value.constructor : undefined,
|
||
ctorString = Ctor ? toSource(Ctor) : '';
|
||
|
||
if (ctorString) {
|
||
switch (ctorString) {
|
||
case dataViewCtorString: return dataViewTag;
|
||
case mapCtorString: return mapTag;
|
||
case promiseCtorString: return promiseTag;
|
||
case setCtorString: return setTag;
|
||
case weakMapCtorString: return weakMapTag;
|
||
}
|
||
}
|
||
return result;
|
||
};
|
||
}
|
||
|
||
/**
|
||
* Gets the view, applying any `transforms` to the `start` and `end` positions.
|
||
*
|
||
* @private
|
||
* @param {number} start The start of the view.
|
||
* @param {number} end The end of the view.
|
||
* @param {Array} transforms The transformations to apply to the view.
|
||
* @returns {Object} Returns an object containing the `start` and `end`
|
||
* positions of the view.
|
||
*/
|
||
function getView(start, end, transforms) {
|
||
var index = -1,
|
||
length = transforms.length;
|
||
|
||
while (++index < length) {
|
||
var data = transforms[index],
|
||
size = data.size;
|
||
|
||
switch (data.type) {
|
||
case 'drop': start += size; break;
|
||
case 'dropRight': end -= size; break;
|
||
case 'take': end = nativeMin(end, start + size); break;
|
||
case 'takeRight': start = nativeMax(start, end - size); break;
|
||
}
|
||
}
|
||
return { 'start': start, 'end': end };
|
||
}
|
||
|
||
/**
|
||
* Extracts wrapper details from the `source` body comment.
|
||
*
|
||
* @private
|
||
* @param {string} source The source to inspect.
|
||
* @returns {Array} Returns the wrapper details.
|
||
*/
|
||
function getWrapDetails(source) {
|
||
var match = source.match(reWrapDetails);
|
||
return match ? match[1].split(reSplitDetails) : [];
|
||
}
|
||
|
||
/**
|
||
* Checks if `path` exists on `object`.
|
||
*
|
||
* @private
|
||
* @param {Object} object The object to query.
|
||
* @param {Array|string} path The path to check.
|
||
* @param {Function} hasFunc The function to check properties.
|
||
* @returns {boolean} Returns `true` if `path` exists, else `false`.
|
||
*/
|
||
function hasPath(object, path, hasFunc) {
|
||
path = castPath(path, object);
|
||
|
||
var index = -1,
|
||
length = path.length,
|
||
result = false;
|
||
|
||
while (++index < length) {
|
||
var key = toKey(path[index]);
|
||
if (!(result = object != null && hasFunc(object, key))) {
|
||
break;
|
||
}
|
||
object = object[key];
|
||
}
|
||
if (result || ++index != length) {
|
||
return result;
|
||
}
|
||
length = object == null ? 0 : object.length;
|
||
return !!length && isLength(length) && isIndex(key, length) &&
|
||
(isArray(object) || isArguments(object));
|
||
}
|
||
|
||
/**
|
||
* Initializes an array clone.
|
||
*
|
||
* @private
|
||
* @param {Array} array The array to clone.
|
||
* @returns {Array} Returns the initialized clone.
|
||
*/
|
||
function initCloneArray(array) {
|
||
var length = array.length,
|
||
result = array.constructor(length);
|
||
|
||
// Add properties assigned by `RegExp#exec`.
|
||
if (length && typeof array[0] == 'string' && hasOwnProperty.call(array, 'index')) {
|
||
result.index = array.index;
|
||
result.input = array.input;
|
||
}
|
||
return result;
|
||
}
|
||
|
||
/**
|
||
* Initializes an object clone.
|
||
*
|
||
* @private
|
||
* @param {Object} object The object to clone.
|
||
* @returns {Object} Returns the initialized clone.
|
||
*/
|
||
function initCloneObject(object) {
|
||
return (typeof object.constructor == 'function' && !isPrototype(object))
|
||
? baseCreate(getPrototype(object))
|
||
: {};
|
||
}
|
||
|
||
/**
|
||
* Initializes an object clone based on its `toStringTag`.
|
||
*
|
||
* **Note:** This function only supports cloning values with tags of
|
||
* `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`.
|
||
*
|
||
* @private
|
||
* @param {Object} object The object to clone.
|
||
* @param {string} tag The `toStringTag` of the object to clone.
|
||
* @param {Function} cloneFunc The function to clone values.
|
||
* @param {boolean} [isDeep] Specify a deep clone.
|
||
* @returns {Object} Returns the initialized clone.
|
||
*/
|
||
function initCloneByTag(object, tag, cloneFunc, isDeep) {
|
||
var Ctor = object.constructor;
|
||
switch (tag) {
|
||
case arrayBufferTag:
|
||
return cloneArrayBuffer(object);
|
||
|
||
case boolTag:
|
||
case dateTag:
|
||
return new Ctor(+object);
|
||
|
||
case dataViewTag:
|
||
return cloneDataView(object, isDeep);
|
||
|
||
case float32Tag: case float64Tag:
|
||
case int8Tag: case int16Tag: case int32Tag:
|
||
case uint8Tag: case uint8ClampedTag: case uint16Tag: case uint32Tag:
|
||
return cloneTypedArray(object, isDeep);
|
||
|
||
case mapTag:
|
||
return cloneMap(object, isDeep, cloneFunc);
|
||
|
||
case numberTag:
|
||
case stringTag:
|
||
return new Ctor(object);
|
||
|
||
case regexpTag:
|
||
return cloneRegExp(object);
|
||
|
||
case setTag:
|
||
return cloneSet(object, isDeep, cloneFunc);
|
||
|
||
case symbolTag:
|
||
return cloneSymbol(object);
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Inserts wrapper `details` in a comment at the top of the `source` body.
|
||
*
|
||
* @private
|
||
* @param {string} source The source to modify.
|
||
* @returns {Array} details The details to insert.
|
||
* @returns {string} Returns the modified source.
|
||
*/
|
||
function insertWrapDetails(source, details) {
|
||
var length = details.length;
|
||
if (!length) {
|
||
return source;
|
||
}
|
||
var lastIndex = length - 1;
|
||
details[lastIndex] = (length > 1 ? '& ' : '') + details[lastIndex];
|
||
details = details.join(length > 2 ? ', ' : ' ');
|
||
return source.replace(reWrapComment, '{\n/* [wrapped with ' + details + '] */\n');
|
||
}
|
||
|
||
/**
|
||
* Checks if `value` is a flattenable `arguments` object or array.
|
||
*
|
||
* @private
|
||
* @param {*} value The value to check.
|
||
* @returns {boolean} Returns `true` if `value` is flattenable, else `false`.
|
||
*/
|
||
function isFlattenable(value) {
|
||
return isArray(value) || isArguments(value) ||
|
||
!!(spreadableSymbol && value && value[spreadableSymbol]);
|
||
}
|
||
|
||
/**
|
||
* Checks if `value` is a valid array-like index.
|
||
*
|
||
* @private
|
||
* @param {*} value The value to check.
|
||
* @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index.
|
||
* @returns {boolean} Returns `true` if `value` is a valid index, else `false`.
|
||
*/
|
||
function isIndex(value, length) {
|
||
length = length == null ? MAX_SAFE_INTEGER : length;
|
||
return !!length &&
|
||
(typeof value == 'number' || reIsUint.test(value)) &&
|
||
(value > -1 && value % 1 == 0 && value < length);
|
||
}
|
||
|
||
/**
|
||
* Checks if the given arguments are from an iteratee call.
|
||
*
|
||
* @private
|
||
* @param {*} value The potential iteratee value argument.
|
||
* @param {*} index The potential iteratee index or key argument.
|
||
* @param {*} object The potential iteratee object argument.
|
||
* @returns {boolean} Returns `true` if the arguments are from an iteratee call,
|
||
* else `false`.
|
||
*/
|
||
function isIterateeCall(value, index, object) {
|
||
if (!isObject(object)) {
|
||
return false;
|
||
}
|
||
var type = typeof index;
|
||
if (type == 'number'
|
||
? (isArrayLike(object) && isIndex(index, object.length))
|
||
: (type == 'string' && index in object)
|
||
) {
|
||
return eq(object[index], value);
|
||
}
|
||
return false;
|
||
}
|
||
|
||
/**
|
||
* Checks if `value` is a property name and not a property path.
|
||
*
|
||
* @private
|
||
* @param {*} value The value to check.
|
||
* @param {Object} [object] The object to query keys on.
|
||
* @returns {boolean} Returns `true` if `value` is a property name, else `false`.
|
||
*/
|
||
function isKey(value, object) {
|
||
if (isArray(value)) {
|
||
return false;
|
||
}
|
||
var type = typeof value;
|
||
if (type == 'number' || type == 'symbol' || type == 'boolean' ||
|
||
value == null || isSymbol(value)) {
|
||
return true;
|
||
}
|
||
return reIsPlainProp.test(value) || !reIsDeepProp.test(value) ||
|
||
(object != null && value in Object(object));
|
||
}
|
||
|
||
/**
|
||
* Checks if `value` is suitable for use as unique object key.
|
||
*
|
||
* @private
|
||
* @param {*} value The value to check.
|
||
* @returns {boolean} Returns `true` if `value` is suitable, else `false`.
|
||
*/
|
||
function isKeyable(value) {
|
||
var type = typeof value;
|
||
return (type == 'string' || type == 'number' || type == 'symbol' || type == 'boolean')
|
||
? (value !== '__proto__')
|
||
: (value === null);
|
||
}
|
||
|
||
/**
|
||
* Checks if `func` has a lazy counterpart.
|
||
*
|
||
* @private
|
||
* @param {Function} func The function to check.
|
||
* @returns {boolean} Returns `true` if `func` has a lazy counterpart,
|
||
* else `false`.
|
||
*/
|
||
function isLaziable(func) {
|
||
var funcName = getFuncName(func),
|
||
other = lodash[funcName];
|
||
|
||
if (typeof other != 'function' || !(funcName in LazyWrapper.prototype)) {
|
||
return false;
|
||
}
|
||
if (func === other) {
|
||
return true;
|
||
}
|
||
var data = getData(other);
|
||
return !!data && func === data[0];
|
||
}
|
||
|
||
/**
|
||
* Checks if `func` has its source masked.
|
||
*
|
||
* @private
|
||
* @param {Function} func The function to check.
|
||
* @returns {boolean} Returns `true` if `func` is masked, else `false`.
|
||
*/
|
||
function isMasked(func) {
|
||
return !!maskSrcKey && (maskSrcKey in func);
|
||
}
|
||
|
||
/**
|
||
* Checks if `func` is capable of being masked.
|
||
*
|
||
* @private
|
||
* @param {*} value The value to check.
|
||
* @returns {boolean} Returns `true` if `func` is maskable, else `false`.
|
||
*/
|
||
var isMaskable = coreJsData ? isFunction : stubFalse;
|
||
|
||
/**
|
||
* Checks if `value` is likely a prototype object.
|
||
*
|
||
* @private
|
||
* @param {*} value The value to check.
|
||
* @returns {boolean} Returns `true` if `value` is a prototype, else `false`.
|
||
*/
|
||
function isPrototype(value) {
|
||
var Ctor = value && value.constructor,
|
||
proto = (typeof Ctor == 'function' && Ctor.prototype) || objectProto;
|
||
|
||
return value === proto;
|
||
}
|
||
|
||
/**
|
||
* Checks if `value` is suitable for strict equality comparisons, i.e. `===`.
|
||
*
|
||
* @private
|
||
* @param {*} value The value to check.
|
||
* @returns {boolean} Returns `true` if `value` if suitable for strict
|
||
* equality comparisons, else `false`.
|
||
*/
|
||
function isStrictComparable(value) {
|
||
return value === value && !isObject(value);
|
||
}
|
||
|
||
/**
|
||
* A specialized version of `matchesProperty` for source values suitable
|
||
* for strict equality comparisons, i.e. `===`.
|
||
*
|
||
* @private
|
||
* @param {string} key The key of the property to get.
|
||
* @param {*} srcValue The value to match.
|
||
* @returns {Function} Returns the new spec function.
|
||
*/
|
||
function matchesStrictComparable(key, srcValue) {
|
||
return function(object) {
|
||
if (object == null) {
|
||
return false;
|
||
}
|
||
return object[key] === srcValue &&
|
||
(srcValue !== undefined || (key in Object(object)));
|
||
};
|
||
}
|
||
|
||
/**
|
||
* A specialized version of `_.memoize` which clears the memoized function's
|
||
* cache when it exceeds `MAX_MEMOIZE_SIZE`.
|
||
*
|
||
* @private
|
||
* @param {Function} func The function to have its output memoized.
|
||
* @returns {Function} Returns the new memoized function.
|
||
*/
|
||
function memoizeCapped(func) {
|
||
var result = memoize(func, function(key) {
|
||
if (cache.size === MAX_MEMOIZE_SIZE) {
|
||
cache.clear();
|
||
}
|
||
return key;
|
||
});
|
||
|
||
var cache = result.cache;
|
||
return result;
|
||
}
|
||
|
||
/**
|
||
* Merges the function metadata of `source` into `data`.
|
||
*
|
||
* Merging metadata reduces the number of wrappers used to invoke a function.
|
||
* This is possible because methods like `_.bind`, `_.curry`, and `_.partial`
|
||
* may be applied regardless of execution order. Methods like `_.ary` and
|
||
* `_.rearg` modify function arguments, making the order in which they are
|
||
* executed important, preventing the merging of metadata. However, we make
|
||
* an exception for a safe combined case where curried functions have `_.ary`
|
||
* and or `_.rearg` applied.
|
||
*
|
||
* @private
|
||
* @param {Array} data The destination metadata.
|
||
* @param {Array} source The source metadata.
|
||
* @returns {Array} Returns `data`.
|
||
*/
|
||
function mergeData(data, source) {
|
||
var bitmask = data[1],
|
||
srcBitmask = source[1],
|
||
newBitmask = bitmask | srcBitmask,
|
||
isCommon = newBitmask < (WRAP_BIND_FLAG | WRAP_BIND_KEY_FLAG | WRAP_ARY_FLAG);
|
||
|
||
var isCombo =
|
||
((srcBitmask == WRAP_ARY_FLAG) && (bitmask == WRAP_CURRY_FLAG)) ||
|
||
((srcBitmask == WRAP_ARY_FLAG) && (bitmask == WRAP_REARG_FLAG) && (data[7].length <= source[8])) ||
|
||
((srcBitmask == (WRAP_ARY_FLAG | WRAP_REARG_FLAG)) && (source[7].length <= source[8]) && (bitmask == WRAP_CURRY_FLAG));
|
||
|
||
// Exit early if metadata can't be merged.
|
||
if (!(isCommon || isCombo)) {
|
||
return data;
|
||
}
|
||
// Use source `thisArg` if available.
|
||
if (srcBitmask & WRAP_BIND_FLAG) {
|
||
data[2] = source[2];
|
||
// Set when currying a bound function.
|
||
newBitmask |= bitmask & WRAP_BIND_FLAG ? 0 : WRAP_CURRY_BOUND_FLAG;
|
||
}
|
||
// Compose partial arguments.
|
||
var value = source[3];
|
||
if (value) {
|
||
var partials = data[3];
|
||
data[3] = partials ? composeArgs(partials, value, source[4]) : value;
|
||
data[4] = partials ? replaceHolders(data[3], PLACEHOLDER) : source[4];
|
||
}
|
||
// Compose partial right arguments.
|
||
value = source[5];
|
||
if (value) {
|
||
partials = data[5];
|
||
data[5] = partials ? composeArgsRight(partials, value, source[6]) : value;
|
||
data[6] = partials ? replaceHolders(data[5], PLACEHOLDER) : source[6];
|
||
}
|
||
// Use source `argPos` if available.
|
||
value = source[7];
|
||
if (value) {
|
||
data[7] = value;
|
||
}
|
||
// Use source `ary` if it's smaller.
|
||
if (srcBitmask & WRAP_ARY_FLAG) {
|
||
data[8] = data[8] == null ? source[8] : nativeMin(data[8], source[8]);
|
||
}
|
||
// Use source `arity` if one is not provided.
|
||
if (data[9] == null) {
|
||
data[9] = source[9];
|
||
}
|
||
// Use source `func` and merge bitmasks.
|
||
data[0] = source[0];
|
||
data[1] = newBitmask;
|
||
|
||
return data;
|
||
}
|
||
|
||
/**
|
||
* This function is like
|
||
* [`Object.keys`](http://ecma-international.org/ecma-262/7.0/#sec-object.keys)
|
||
* except that it includes inherited enumerable properties.
|
||
*
|
||
* @private
|
||
* @param {Object} object The object to query.
|
||
* @returns {Array} Returns the array of property names.
|
||
*/
|
||
function nativeKeysIn(object) {
|
||
var result = [];
|
||
if (object != null) {
|
||
for (var key in Object(object)) {
|
||
result.push(key);
|
||
}
|
||
}
|
||
return result;
|
||
}
|
||
|
||
/**
|
||
* Converts `value` to a string using `Object.prototype.toString`.
|
||
*
|
||
* @private
|
||
* @param {*} value The value to convert.
|
||
* @returns {string} Returns the converted string.
|
||
*/
|
||
function objectToString(value) {
|
||
return nativeObjectToString.call(value);
|
||
}
|
||
|
||
/**
|
||
* A specialized version of `baseRest` which transforms the rest array.
|
||
*
|
||
* @private
|
||
* @param {Function} func The function to apply a rest parameter to.
|
||
* @param {number} [start=func.length-1] The start position of the rest parameter.
|
||
* @param {Function} transform The rest array transform.
|
||
* @returns {Function} Returns the new function.
|
||
*/
|
||
function overRest(func, start, transform) {
|
||
start = nativeMax(start === undefined ? (func.length - 1) : start, 0);
|
||
return function() {
|
||
var args = arguments,
|
||
index = -1,
|
||
length = nativeMax(args.length - start, 0),
|
||
array = Array(length);
|
||
|
||
while (++index < length) {
|
||
array[index] = args[start + index];
|
||
}
|
||
index = -1;
|
||
var otherArgs = Array(start + 1);
|
||
while (++index < start) {
|
||
otherArgs[index] = args[index];
|
||
}
|
||
otherArgs[start] = transform(array);
|
||
return apply(func, this, otherArgs);
|
||
};
|
||
}
|
||
|
||
/**
|
||
* Gets the parent value at `path` of `object`.
|
||
*
|
||
* @private
|
||
* @param {Object} object The object to query.
|
||
* @param {Array} path The path to get the parent value of.
|
||
* @returns {*} Returns the parent value.
|
||
*/
|
||
function parent(object, path) {
|
||
return path.length < 2 ? object : baseGet(object, baseSlice(path, 0, -1));
|
||
}
|
||
|
||
/**
|
||
* Reorder `array` according to the specified indexes where the element at
|
||
* the first index is assigned as the first element, the element at
|
||
* the second index is assigned as the second element, and so on.
|
||
*
|
||
* @private
|
||
* @param {Array} array The array to reorder.
|
||
* @param {Array} indexes The arranged array indexes.
|
||
* @returns {Array} Returns `array`.
|
||
*/
|
||
function reorder(array, indexes) {
|
||
var arrLength = array.length,
|
||
length = nativeMin(indexes.length, arrLength),
|
||
oldArray = copyArray(array);
|
||
|
||
while (length--) {
|
||
var index = indexes[length];
|
||
array[length] = isIndex(index, arrLength) ? oldArray[index] : undefined;
|
||
}
|
||
return array;
|
||
}
|
||
|
||
/**
|
||
* Sets metadata for `func`.
|
||
*
|
||
* **Note:** If this function becomes hot, i.e. is invoked a lot in a short
|
||
* period of time, it will trip its breaker and transition to an identity
|
||
* function to avoid garbage collection pauses in V8. See
|
||
* [V8 issue 2070](https://bugs.chromium.org/p/v8/issues/detail?id=2070)
|
||
* for more details.
|
||
*
|
||
* @private
|
||
* @param {Function} func The function to associate metadata with.
|
||
* @param {*} data The metadata.
|
||
* @returns {Function} Returns `func`.
|
||
*/
|
||
var setData = shortOut(baseSetData);
|
||
|
||
/**
|
||
* A simple wrapper around the global [`setTimeout`](https://mdn.io/setTimeout).
|
||
*
|
||
* @private
|
||
* @param {Function} func The function to delay.
|
||
* @param {number} wait The number of milliseconds to delay invocation.
|
||
* @returns {number|Object} Returns the timer id or timeout object.
|
||
*/
|
||
var setTimeout = ctxSetTimeout || function(func, wait) {
|
||
return root.setTimeout(func, wait);
|
||
};
|
||
|
||
/**
|
||
* Sets the `toString` method of `func` to return `string`.
|
||
*
|
||
* @private
|
||
* @param {Function} func The function to modify.
|
||
* @param {Function} string The `toString` result.
|
||
* @returns {Function} Returns `func`.
|
||
*/
|
||
var setToString = shortOut(baseSetToString);
|
||
|
||
/**
|
||
* Sets the `toString` method of `wrapper` to mimic the source of `reference`
|
||
* with wrapper details in a comment at the top of the source body.
|
||
*
|
||
* @private
|
||
* @param {Function} wrapper The function to modify.
|
||
* @param {Function} reference The reference function.
|
||
* @param {number} bitmask The bitmask flags. See `createWrap` for more details.
|
||
* @returns {Function} Returns `wrapper`.
|
||
*/
|
||
function setWrapToString(wrapper, reference, bitmask) {
|
||
var source = (reference + '');
|
||
return setToString(wrapper, insertWrapDetails(source, updateWrapDetails(getWrapDetails(source), bitmask)));
|
||
}
|
||
|
||
/**
|
||
* Creates a function that'll short out and invoke `identity` instead
|
||
* of `func` when it's called `HOT_COUNT` or more times in `HOT_SPAN`
|
||
* milliseconds.
|
||
*
|
||
* @private
|
||
* @param {Function} func The function to restrict.
|
||
* @returns {Function} Returns the new shortable function.
|
||
*/
|
||
function shortOut(func) {
|
||
var count = 0,
|
||
lastCalled = 0;
|
||
|
||
return function() {
|
||
var stamp = nativeNow(),
|
||
remaining = HOT_SPAN - (stamp - lastCalled);
|
||
|
||
lastCalled = stamp;
|
||
if (remaining > 0) {
|
||
if (++count >= HOT_COUNT) {
|
||
return arguments[0];
|
||
}
|
||
} else {
|
||
count = 0;
|
||
}
|
||
return func.apply(undefined, arguments);
|
||
};
|
||
}
|
||
|
||
/**
|
||
* A specialized version of `_.shuffle` which mutates and sets the size of `array`.
|
||
*
|
||
* @private
|
||
* @param {Array} array The array to shuffle.
|
||
* @param {number} [size=array.length] The size of `array`.
|
||
* @returns {Array} Returns `array`.
|
||
*/
|
||
function shuffleSelf(array, size) {
|
||
var index = -1,
|
||
length = array.length,
|
||
lastIndex = length - 1;
|
||
|
||
size = size === undefined ? length : size;
|
||
while (++index < size) {
|
||
var rand = baseRandom(index, lastIndex),
|
||
value = array[rand];
|
||
|
||
array[rand] = array[index];
|
||
array[index] = value;
|
||
}
|
||
array.length = size;
|
||
return array;
|
||
}
|
||
|
||
/**
|
||
* Converts `string` to a property path array.
|
||
*
|
||
* @private
|
||
* @param {string} string The string to convert.
|
||
* @returns {Array} Returns the property path array.
|
||
*/
|
||
var stringToPath = memoizeCapped(function(string) {
|
||
var result = [];
|
||
if (reLeadingDot.test(string)) {
|
||
result.push('');
|
||
}
|
||
string.replace(rePropName, function(match, number, quote, string) {
|
||
result.push(quote ? string.replace(reEscapeChar, '$1') : (number || match));
|
||
});
|
||
return result;
|
||
});
|
||
|
||
/**
|
||
* Converts `value` to a string key if it's not a string or symbol.
|
||
*
|
||
* @private
|
||
* @param {*} value The value to inspect.
|
||
* @returns {string|symbol} Returns the key.
|
||
*/
|
||
function toKey(value) {
|
||
if (typeof value == 'string' || isSymbol(value)) {
|
||
return value;
|
||
}
|
||
var result = (value + '');
|
||
return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result;
|
||
}
|
||
|
||
/**
|
||
* Converts `func` to its source code.
|
||
*
|
||
* @private
|
||
* @param {Function} func The function to convert.
|
||
* @returns {string} Returns the source code.
|
||
*/
|
||
function toSource(func) {
|
||
if (func != null) {
|
||
try {
|
||
return funcToString.call(func);
|
||
} catch (e) {}
|
||
try {
|
||
return (func + '');
|
||
} catch (e) {}
|
||
}
|
||
return '';
|
||
}
|
||
|
||
/**
|
||
* Updates wrapper `details` based on `bitmask` flags.
|
||
*
|
||
* @private
|
||
* @returns {Array} details The details to modify.
|
||
* @param {number} bitmask The bitmask flags. See `createWrap` for more details.
|
||
* @returns {Array} Returns `details`.
|
||
*/
|
||
function updateWrapDetails(details, bitmask) {
|
||
arrayEach(wrapFlags, function(pair) {
|
||
var value = '_.' + pair[0];
|
||
if ((bitmask & pair[1]) && !arrayIncludes(details, value)) {
|
||
details.push(value);
|
||
}
|
||
});
|
||
return details.sort();
|
||
}
|
||
|
||
/**
|
||
* Creates a clone of `wrapper`.
|
||
*
|
||
* @private
|
||
* @param {Object} wrapper The wrapper to clone.
|
||
* @returns {Object} Returns the cloned wrapper.
|
||
*/
|
||
function wrapperClone(wrapper) {
|
||
if (wrapper instanceof LazyWrapper) {
|
||
return wrapper.clone();
|
||
}
|
||
var result = new LodashWrapper(wrapper.__wrapped__, wrapper.__chain__);
|
||
result.__actions__ = copyArray(wrapper.__actions__);
|
||
result.__index__ = wrapper.__index__;
|
||
result.__values__ = wrapper.__values__;
|
||
return result;
|
||
}
|
||
|
||
/*------------------------------------------------------------------------*/
|
||
|
||
/**
|
||
* Creates an array of elements split into groups the length of `size`.
|
||
* If `array` can't be split evenly, the final chunk will be the remaining
|
||
* elements.
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 3.0.0
|
||
* @category Array
|
||
* @param {Array} array The array to process.
|
||
* @param {number} [size=1] The length of each chunk
|
||
* @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
|
||
* @returns {Array} Returns the new array of chunks.
|
||
* @example
|
||
*
|
||
* _.chunk(['a', 'b', 'c', 'd'], 2);
|
||
* // => [['a', 'b'], ['c', 'd']]
|
||
*
|
||
* _.chunk(['a', 'b', 'c', 'd'], 3);
|
||
* // => [['a', 'b', 'c'], ['d']]
|
||
*/
|
||
function chunk(array, size, guard) {
|
||
if ((guard ? isIterateeCall(array, size, guard) : size === undefined)) {
|
||
size = 1;
|
||
} else {
|
||
size = nativeMax(toInteger(size), 0);
|
||
}
|
||
var length = array == null ? 0 : array.length;
|
||
if (!length || size < 1) {
|
||
return [];
|
||
}
|
||
var index = 0,
|
||
resIndex = 0,
|
||
result = Array(nativeCeil(length / size));
|
||
|
||
while (index < length) {
|
||
result[resIndex++] = baseSlice(array, index, (index += size));
|
||
}
|
||
return result;
|
||
}
|
||
|
||
/**
|
||
* Creates an array with all falsey values removed. The values `false`, `null`,
|
||
* `0`, `""`, `undefined`, and `NaN` are falsey.
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 0.1.0
|
||
* @category Array
|
||
* @param {Array} array The array to compact.
|
||
* @returns {Array} Returns the new array of filtered values.
|
||
* @example
|
||
*
|
||
* _.compact([0, 1, false, 2, '', 3]);
|
||
* // => [1, 2, 3]
|
||
*/
|
||
function compact(array) {
|
||
var index = -1,
|
||
length = array == null ? 0 : array.length,
|
||
resIndex = 0,
|
||
result = [];
|
||
|
||
while (++index < length) {
|
||
var value = array[index];
|
||
if (value) {
|
||
result[resIndex++] = value;
|
||
}
|
||
}
|
||
return result;
|
||
}
|
||
|
||
/**
|
||
* Creates a new array concatenating `array` with any additional arrays
|
||
* and/or values.
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 4.0.0
|
||
* @category Array
|
||
* @param {Array} array The array to concatenate.
|
||
* @param {...*} [values] The values to concatenate.
|
||
* @returns {Array} Returns the new concatenated array.
|
||
* @example
|
||
*
|
||
* var array = [1];
|
||
* var other = _.concat(array, 2, [3], [[4]]);
|
||
*
|
||
* console.log(other);
|
||
* // => [1, 2, 3, [4]]
|
||
*
|
||
* console.log(array);
|
||
* // => [1]
|
||
*/
|
||
function concat() {
|
||
var length = arguments.length;
|
||
if (!length) {
|
||
return [];
|
||
}
|
||
var args = Array(length - 1),
|
||
array = arguments[0],
|
||
index = length;
|
||
|
||
while (index--) {
|
||
args[index - 1] = arguments[index];
|
||
}
|
||
return arrayPush(isArray(array) ? copyArray(array) : [array], baseFlatten(args, 1));
|
||
}
|
||
|
||
/**
|
||
* Creates an array of `array` values not included in the other given arrays
|
||
* using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
|
||
* for equality comparisons. The order and references of result values are
|
||
* determined by the first array.
|
||
*
|
||
* **Note:** Unlike `_.pullAll`, this method returns a new array.
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 0.1.0
|
||
* @category Array
|
||
* @param {Array} array The array to inspect.
|
||
* @param {...Array} [values] The values to exclude.
|
||
* @returns {Array} Returns the new array of filtered values.
|
||
* @see _.without, _.xor
|
||
* @example
|
||
*
|
||
* _.difference([2, 1], [2, 3]);
|
||
* // => [1]
|
||
*/
|
||
var difference = baseRest(function(array, values) {
|
||
return isArrayLikeObject(array)
|
||
? baseDifference(array, baseFlatten(values, 1, isArrayLikeObject, true))
|
||
: [];
|
||
});
|
||
|
||
/**
|
||
* This method is like `_.difference` except that it accepts `iteratee` which
|
||
* is invoked for each element of `array` and `values` to generate the criterion
|
||
* by which they're compared. The order and references of result values are
|
||
* determined by the first array. The iteratee is invoked with one argument:
|
||
* (value).
|
||
*
|
||
* **Note:** Unlike `_.pullAllBy`, this method returns a new array.
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 4.0.0
|
||
* @category Array
|
||
* @param {Array} array The array to inspect.
|
||
* @param {...Array} [values] The values to exclude.
|
||
* @param {Function} [iteratee=_.identity] The iteratee invoked per element.
|
||
* @returns {Array} Returns the new array of filtered values.
|
||
* @example
|
||
*
|
||
* _.differenceBy([2.1, 1.2], [2.3, 3.4], Math.floor);
|
||
* // => [1.2]
|
||
*
|
||
* // The `_.property` iteratee shorthand.
|
||
* _.differenceBy([{ 'x': 2 }, { 'x': 1 }], [{ 'x': 1 }], 'x');
|
||
* // => [{ 'x': 2 }]
|
||
*/
|
||
var differenceBy = baseRest(function(array, values) {
|
||
var iteratee = last(values);
|
||
if (isArrayLikeObject(iteratee)) {
|
||
iteratee = undefined;
|
||
}
|
||
return isArrayLikeObject(array)
|
||
? baseDifference(array, baseFlatten(values, 1, isArrayLikeObject, true), getIteratee(iteratee, 2))
|
||
: [];
|
||
});
|
||
|
||
/**
|
||
* This method is like `_.difference` except that it accepts `comparator`
|
||
* which is invoked to compare elements of `array` to `values`. The order and
|
||
* references of result values are determined by the first array. The comparator
|
||
* is invoked with two arguments: (arrVal, othVal).
|
||
*
|
||
* **Note:** Unlike `_.pullAllWith`, this method returns a new array.
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 4.0.0
|
||
* @category Array
|
||
* @param {Array} array The array to inspect.
|
||
* @param {...Array} [values] The values to exclude.
|
||
* @param {Function} [comparator] The comparator invoked per element.
|
||
* @returns {Array} Returns the new array of filtered values.
|
||
* @example
|
||
*
|
||
* var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }];
|
||
*
|
||
* _.differenceWith(objects, [{ 'x': 1, 'y': 2 }], _.isEqual);
|
||
* // => [{ 'x': 2, 'y': 1 }]
|
||
*/
|
||
var differenceWith = baseRest(function(array, values) {
|
||
var comparator = last(values);
|
||
if (isArrayLikeObject(comparator)) {
|
||
comparator = undefined;
|
||
}
|
||
return isArrayLikeObject(array)
|
||
? baseDifference(array, baseFlatten(values, 1, isArrayLikeObject, true), undefined, comparator)
|
||
: [];
|
||
});
|
||
|
||
/**
|
||
* Creates a slice of `array` with `n` elements dropped from the beginning.
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 0.5.0
|
||
* @category Array
|
||
* @param {Array} array The array to query.
|
||
* @param {number} [n=1] The number of elements to drop.
|
||
* @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
|
||
* @returns {Array} Returns the slice of `array`.
|
||
* @example
|
||
*
|
||
* _.drop([1, 2, 3]);
|
||
* // => [2, 3]
|
||
*
|
||
* _.drop([1, 2, 3], 2);
|
||
* // => [3]
|
||
*
|
||
* _.drop([1, 2, 3], 5);
|
||
* // => []
|
||
*
|
||
* _.drop([1, 2, 3], 0);
|
||
* // => [1, 2, 3]
|
||
*/
|
||
function drop(array, n, guard) {
|
||
var length = array == null ? 0 : array.length;
|
||
if (!length) {
|
||
return [];
|
||
}
|
||
n = (guard || n === undefined) ? 1 : toInteger(n);
|
||
return baseSlice(array, n < 0 ? 0 : n, length);
|
||
}
|
||
|
||
/**
|
||
* Creates a slice of `array` with `n` elements dropped from the end.
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 3.0.0
|
||
* @category Array
|
||
* @param {Array} array The array to query.
|
||
* @param {number} [n=1] The number of elements to drop.
|
||
* @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
|
||
* @returns {Array} Returns the slice of `array`.
|
||
* @example
|
||
*
|
||
* _.dropRight([1, 2, 3]);
|
||
* // => [1, 2]
|
||
*
|
||
* _.dropRight([1, 2, 3], 2);
|
||
* // => [1]
|
||
*
|
||
* _.dropRight([1, 2, 3], 5);
|
||
* // => []
|
||
*
|
||
* _.dropRight([1, 2, 3], 0);
|
||
* // => [1, 2, 3]
|
||
*/
|
||
function dropRight(array, n, guard) {
|
||
var length = array == null ? 0 : array.length;
|
||
if (!length) {
|
||
return [];
|
||
}
|
||
n = (guard || n === undefined) ? 1 : toInteger(n);
|
||
n = length - n;
|
||
return baseSlice(array, 0, n < 0 ? 0 : n);
|
||
}
|
||
|
||
/**
|
||
* Creates a slice of `array` excluding elements dropped from the end.
|
||
* Elements are dropped until `predicate` returns falsey. The predicate is
|
||
* invoked with three arguments: (value, index, array).
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 3.0.0
|
||
* @category Array
|
||
* @param {Array} array The array to query.
|
||
* @param {Function} [predicate=_.identity] The function invoked per iteration.
|
||
* @returns {Array} Returns the slice of `array`.
|
||
* @example
|
||
*
|
||
* var users = [
|
||
* { 'user': 'barney', 'active': true },
|
||
* { 'user': 'fred', 'active': false },
|
||
* { 'user': 'pebbles', 'active': false }
|
||
* ];
|
||
*
|
||
* _.dropRightWhile(users, function(o) { return !o.active; });
|
||
* // => objects for ['barney']
|
||
*
|
||
* // The `_.matches` iteratee shorthand.
|
||
* _.dropRightWhile(users, { 'user': 'pebbles', 'active': false });
|
||
* // => objects for ['barney', 'fred']
|
||
*
|
||
* // The `_.matchesProperty` iteratee shorthand.
|
||
* _.dropRightWhile(users, ['active', false]);
|
||
* // => objects for ['barney']
|
||
*
|
||
* // The `_.property` iteratee shorthand.
|
||
* _.dropRightWhile(users, 'active');
|
||
* // => objects for ['barney', 'fred', 'pebbles']
|
||
*/
|
||
function dropRightWhile(array, predicate) {
|
||
return (array && array.length)
|
||
? baseWhile(array, getIteratee(predicate, 3), true, true)
|
||
: [];
|
||
}
|
||
|
||
/**
|
||
* Creates a slice of `array` excluding elements dropped from the beginning.
|
||
* Elements are dropped until `predicate` returns falsey. The predicate is
|
||
* invoked with three arguments: (value, index, array).
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 3.0.0
|
||
* @category Array
|
||
* @param {Array} array The array to query.
|
||
* @param {Function} [predicate=_.identity] The function invoked per iteration.
|
||
* @returns {Array} Returns the slice of `array`.
|
||
* @example
|
||
*
|
||
* var users = [
|
||
* { 'user': 'barney', 'active': false },
|
||
* { 'user': 'fred', 'active': false },
|
||
* { 'user': 'pebbles', 'active': true }
|
||
* ];
|
||
*
|
||
* _.dropWhile(users, function(o) { return !o.active; });
|
||
* // => objects for ['pebbles']
|
||
*
|
||
* // The `_.matches` iteratee shorthand.
|
||
* _.dropWhile(users, { 'user': 'barney', 'active': false });
|
||
* // => objects for ['fred', 'pebbles']
|
||
*
|
||
* // The `_.matchesProperty` iteratee shorthand.
|
||
* _.dropWhile(users, ['active', false]);
|
||
* // => objects for ['pebbles']
|
||
*
|
||
* // The `_.property` iteratee shorthand.
|
||
* _.dropWhile(users, 'active');
|
||
* // => objects for ['barney', 'fred', 'pebbles']
|
||
*/
|
||
function dropWhile(array, predicate) {
|
||
return (array && array.length)
|
||
? baseWhile(array, getIteratee(predicate, 3), true)
|
||
: [];
|
||
}
|
||
|
||
/**
|
||
* Fills elements of `array` with `value` from `start` up to, but not
|
||
* including, `end`.
|
||
*
|
||
* **Note:** This method mutates `array`.
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 3.2.0
|
||
* @category Array
|
||
* @param {Array} array The array to fill.
|
||
* @param {*} value The value to fill `array` with.
|
||
* @param {number} [start=0] The start position.
|
||
* @param {number} [end=array.length] The end position.
|
||
* @returns {Array} Returns `array`.
|
||
* @example
|
||
*
|
||
* var array = [1, 2, 3];
|
||
*
|
||
* _.fill(array, 'a');
|
||
* console.log(array);
|
||
* // => ['a', 'a', 'a']
|
||
*
|
||
* _.fill(Array(3), 2);
|
||
* // => [2, 2, 2]
|
||
*
|
||
* _.fill([4, 6, 8, 10], '*', 1, 3);
|
||
* // => [4, '*', '*', 10]
|
||
*/
|
||
function fill(array, value, start, end) {
|
||
var length = array == null ? 0 : array.length;
|
||
if (!length) {
|
||
return [];
|
||
}
|
||
if (start && typeof start != 'number' && isIterateeCall(array, value, start)) {
|
||
start = 0;
|
||
end = length;
|
||
}
|
||
return baseFill(array, value, start, end);
|
||
}
|
||
|
||
/**
|
||
* This method is like `_.find` except that it returns the index of the first
|
||
* element `predicate` returns truthy for instead of the element itself.
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 1.1.0
|
||
* @category Array
|
||
* @param {Array} array The array to inspect.
|
||
* @param {Function} [predicate=_.identity] The function invoked per iteration.
|
||
* @param {number} [fromIndex=0] The index to search from.
|
||
* @returns {number} Returns the index of the found element, else `-1`.
|
||
* @example
|
||
*
|
||
* var users = [
|
||
* { 'user': 'barney', 'active': false },
|
||
* { 'user': 'fred', 'active': false },
|
||
* { 'user': 'pebbles', 'active': true }
|
||
* ];
|
||
*
|
||
* _.findIndex(users, function(o) { return o.user == 'barney'; });
|
||
* // => 0
|
||
*
|
||
* // The `_.matches` iteratee shorthand.
|
||
* _.findIndex(users, { 'user': 'fred', 'active': false });
|
||
* // => 1
|
||
*
|
||
* // The `_.matchesProperty` iteratee shorthand.
|
||
* _.findIndex(users, ['active', false]);
|
||
* // => 0
|
||
*
|
||
* // The `_.property` iteratee shorthand.
|
||
* _.findIndex(users, 'active');
|
||
* // => 2
|
||
*/
|
||
function findIndex(array, predicate, fromIndex) {
|
||
var length = array == null ? 0 : array.length;
|
||
if (!length) {
|
||
return -1;
|
||
}
|
||
var index = fromIndex == null ? 0 : toInteger(fromIndex);
|
||
if (index < 0) {
|
||
index = nativeMax(length + index, 0);
|
||
}
|
||
return baseFindIndex(array, getIteratee(predicate, 3), index);
|
||
}
|
||
|
||
/**
|
||
* This method is like `_.findIndex` except that it iterates over elements
|
||
* of `collection` from right to left.
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 2.0.0
|
||
* @category Array
|
||
* @param {Array} array The array to inspect.
|
||
* @param {Function} [predicate=_.identity] The function invoked per iteration.
|
||
* @param {number} [fromIndex=array.length-1] The index to search from.
|
||
* @returns {number} Returns the index of the found element, else `-1`.
|
||
* @example
|
||
*
|
||
* var users = [
|
||
* { 'user': 'barney', 'active': true },
|
||
* { 'user': 'fred', 'active': false },
|
||
* { 'user': 'pebbles', 'active': false }
|
||
* ];
|
||
*
|
||
* _.findLastIndex(users, function(o) { return o.user == 'pebbles'; });
|
||
* // => 2
|
||
*
|
||
* // The `_.matches` iteratee shorthand.
|
||
* _.findLastIndex(users, { 'user': 'barney', 'active': true });
|
||
* // => 0
|
||
*
|
||
* // The `_.matchesProperty` iteratee shorthand.
|
||
* _.findLastIndex(users, ['active', false]);
|
||
* // => 2
|
||
*
|
||
* // The `_.property` iteratee shorthand.
|
||
* _.findLastIndex(users, 'active');
|
||
* // => 0
|
||
*/
|
||
function findLastIndex(array, predicate, fromIndex) {
|
||
var length = array == null ? 0 : array.length;
|
||
if (!length) {
|
||
return -1;
|
||
}
|
||
var index = length - 1;
|
||
if (fromIndex !== undefined) {
|
||
index = toInteger(fromIndex);
|
||
index = fromIndex < 0
|
||
? nativeMax(length + index, 0)
|
||
: nativeMin(index, length - 1);
|
||
}
|
||
return baseFindIndex(array, getIteratee(predicate, 3), index, true);
|
||
}
|
||
|
||
/**
|
||
* Flattens `array` a single level deep.
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 0.1.0
|
||
* @category Array
|
||
* @param {Array} array The array to flatten.
|
||
* @returns {Array} Returns the new flattened array.
|
||
* @example
|
||
*
|
||
* _.flatten([1, [2, [3, [4]], 5]]);
|
||
* // => [1, 2, [3, [4]], 5]
|
||
*/
|
||
function flatten(array) {
|
||
var length = array == null ? 0 : array.length;
|
||
return length ? baseFlatten(array, 1) : [];
|
||
}
|
||
|
||
/**
|
||
* Recursively flattens `array`.
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 3.0.0
|
||
* @category Array
|
||
* @param {Array} array The array to flatten.
|
||
* @returns {Array} Returns the new flattened array.
|
||
* @example
|
||
*
|
||
* _.flattenDeep([1, [2, [3, [4]], 5]]);
|
||
* // => [1, 2, 3, 4, 5]
|
||
*/
|
||
function flattenDeep(array) {
|
||
var length = array == null ? 0 : array.length;
|
||
return length ? baseFlatten(array, INFINITY) : [];
|
||
}
|
||
|
||
/**
|
||
* Recursively flatten `array` up to `depth` times.
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 4.4.0
|
||
* @category Array
|
||
* @param {Array} array The array to flatten.
|
||
* @param {number} [depth=1] The maximum recursion depth.
|
||
* @returns {Array} Returns the new flattened array.
|
||
* @example
|
||
*
|
||
* var array = [1, [2, [3, [4]], 5]];
|
||
*
|
||
* _.flattenDepth(array, 1);
|
||
* // => [1, 2, [3, [4]], 5]
|
||
*
|
||
* _.flattenDepth(array, 2);
|
||
* // => [1, 2, 3, [4], 5]
|
||
*/
|
||
function flattenDepth(array, depth) {
|
||
var length = array == null ? 0 : array.length;
|
||
if (!length) {
|
||
return [];
|
||
}
|
||
depth = depth === undefined ? 1 : toInteger(depth);
|
||
return baseFlatten(array, depth);
|
||
}
|
||
|
||
/**
|
||
* The inverse of `_.toPairs`; this method returns an object composed
|
||
* from key-value `pairs`.
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 4.0.0
|
||
* @category Array
|
||
* @param {Array} pairs The key-value pairs.
|
||
* @returns {Object} Returns the new object.
|
||
* @example
|
||
*
|
||
* _.fromPairs([['a', 1], ['b', 2]]);
|
||
* // => { 'a': 1, 'b': 2 }
|
||
*/
|
||
function fromPairs(pairs) {
|
||
var index = -1,
|
||
length = pairs == null ? 0 : pairs.length,
|
||
result = {};
|
||
|
||
while (++index < length) {
|
||
var pair = pairs[index];
|
||
result[pair[0]] = pair[1];
|
||
}
|
||
return result;
|
||
}
|
||
|
||
/**
|
||
* Gets the first element of `array`.
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 0.1.0
|
||
* @alias first
|
||
* @category Array
|
||
* @param {Array} array The array to query.
|
||
* @returns {*} Returns the first element of `array`.
|
||
* @example
|
||
*
|
||
* _.head([1, 2, 3]);
|
||
* // => 1
|
||
*
|
||
* _.head([]);
|
||
* // => undefined
|
||
*/
|
||
function head(array) {
|
||
return (array && array.length) ? array[0] : undefined;
|
||
}
|
||
|
||
/**
|
||
* Gets the index at which the first occurrence of `value` is found in `array`
|
||
* using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
|
||
* for equality comparisons. If `fromIndex` is negative, it's used as the
|
||
* offset from the end of `array`.
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 0.1.0
|
||
* @category Array
|
||
* @param {Array} array The array to inspect.
|
||
* @param {*} value The value to search for.
|
||
* @param {number} [fromIndex=0] The index to search from.
|
||
* @returns {number} Returns the index of the matched value, else `-1`.
|
||
* @example
|
||
*
|
||
* _.indexOf([1, 2, 1, 2], 2);
|
||
* // => 1
|
||
*
|
||
* // Search from the `fromIndex`.
|
||
* _.indexOf([1, 2, 1, 2], 2, 2);
|
||
* // => 3
|
||
*/
|
||
function indexOf(array, value, fromIndex) {
|
||
var length = array == null ? 0 : array.length;
|
||
if (!length) {
|
||
return -1;
|
||
}
|
||
var index = fromIndex == null ? 0 : toInteger(fromIndex);
|
||
if (index < 0) {
|
||
index = nativeMax(length + index, 0);
|
||
}
|
||
return baseIndexOf(array, value, index);
|
||
}
|
||
|
||
/**
|
||
* Gets all but the last element of `array`.
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 0.1.0
|
||
* @category Array
|
||
* @param {Array} array The array to query.
|
||
* @returns {Array} Returns the slice of `array`.
|
||
* @example
|
||
*
|
||
* _.initial([1, 2, 3]);
|
||
* // => [1, 2]
|
||
*/
|
||
function initial(array) {
|
||
var length = array == null ? 0 : array.length;
|
||
return length ? baseSlice(array, 0, -1) : [];
|
||
}
|
||
|
||
/**
|
||
* Creates an array of unique values that are included in all given arrays
|
||
* using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
|
||
* for equality comparisons. The order and references of result values are
|
||
* determined by the first array.
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 0.1.0
|
||
* @category Array
|
||
* @param {...Array} [arrays] The arrays to inspect.
|
||
* @returns {Array} Returns the new array of intersecting values.
|
||
* @example
|
||
*
|
||
* _.intersection([2, 1], [2, 3]);
|
||
* // => [2]
|
||
*/
|
||
var intersection = baseRest(function(arrays) {
|
||
var mapped = arrayMap(arrays, castArrayLikeObject);
|
||
return (mapped.length && mapped[0] === arrays[0])
|
||
? baseIntersection(mapped)
|
||
: [];
|
||
});
|
||
|
||
/**
|
||
* This method is like `_.intersection` except that it accepts `iteratee`
|
||
* which is invoked for each element of each `arrays` to generate the criterion
|
||
* by which they're compared. The order and references of result values are
|
||
* determined by the first array. The iteratee is invoked with one argument:
|
||
* (value).
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 4.0.0
|
||
* @category Array
|
||
* @param {...Array} [arrays] The arrays to inspect.
|
||
* @param {Function} [iteratee=_.identity] The iteratee invoked per element.
|
||
* @returns {Array} Returns the new array of intersecting values.
|
||
* @example
|
||
*
|
||
* _.intersectionBy([2.1, 1.2], [2.3, 3.4], Math.floor);
|
||
* // => [2.1]
|
||
*
|
||
* // The `_.property` iteratee shorthand.
|
||
* _.intersectionBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x');
|
||
* // => [{ 'x': 1 }]
|
||
*/
|
||
var intersectionBy = baseRest(function(arrays) {
|
||
var iteratee = last(arrays),
|
||
mapped = arrayMap(arrays, castArrayLikeObject);
|
||
|
||
if (iteratee === last(mapped)) {
|
||
iteratee = undefined;
|
||
} else {
|
||
mapped.pop();
|
||
}
|
||
return (mapped.length && mapped[0] === arrays[0])
|
||
? baseIntersection(mapped, getIteratee(iteratee, 2))
|
||
: [];
|
||
});
|
||
|
||
/**
|
||
* This method is like `_.intersection` except that it accepts `comparator`
|
||
* which is invoked to compare elements of `arrays`. The order and references
|
||
* of result values are determined by the first array. The comparator is
|
||
* invoked with two arguments: (arrVal, othVal).
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 4.0.0
|
||
* @category Array
|
||
* @param {...Array} [arrays] The arrays to inspect.
|
||
* @param {Function} [comparator] The comparator invoked per element.
|
||
* @returns {Array} Returns the new array of intersecting values.
|
||
* @example
|
||
*
|
||
* var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }];
|
||
* var others = [{ 'x': 1, 'y': 1 }, { 'x': 1, 'y': 2 }];
|
||
*
|
||
* _.intersectionWith(objects, others, _.isEqual);
|
||
* // => [{ 'x': 1, 'y': 2 }]
|
||
*/
|
||
var intersectionWith = baseRest(function(arrays) {
|
||
var comparator = last(arrays),
|
||
mapped = arrayMap(arrays, castArrayLikeObject);
|
||
|
||
comparator = typeof comparator == 'function' ? comparator : undefined;
|
||
if (comparator) {
|
||
mapped.pop();
|
||
}
|
||
return (mapped.length && mapped[0] === arrays[0])
|
||
? baseIntersection(mapped, undefined, comparator)
|
||
: [];
|
||
});
|
||
|
||
/**
|
||
* Converts all elements in `array` into a string separated by `separator`.
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 4.0.0
|
||
* @category Array
|
||
* @param {Array} array The array to convert.
|
||
* @param {string} [separator=','] The element separator.
|
||
* @returns {string} Returns the joined string.
|
||
* @example
|
||
*
|
||
* _.join(['a', 'b', 'c'], '~');
|
||
* // => 'a~b~c'
|
||
*/
|
||
function join(array, separator) {
|
||
return array == null ? '' : nativeJoin.call(array, separator);
|
||
}
|
||
|
||
/**
|
||
* Gets the last element of `array`.
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 0.1.0
|
||
* @category Array
|
||
* @param {Array} array The array to query.
|
||
* @returns {*} Returns the last element of `array`.
|
||
* @example
|
||
*
|
||
* _.last([1, 2, 3]);
|
||
* // => 3
|
||
*/
|
||
function last(array) {
|
||
var length = array == null ? 0 : array.length;
|
||
return length ? array[length - 1] : undefined;
|
||
}
|
||
|
||
/**
|
||
* This method is like `_.indexOf` except that it iterates over elements of
|
||
* `array` from right to left.
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 0.1.0
|
||
* @category Array
|
||
* @param {Array} array The array to inspect.
|
||
* @param {*} value The value to search for.
|
||
* @param {number} [fromIndex=array.length-1] The index to search from.
|
||
* @returns {number} Returns the index of the matched value, else `-1`.
|
||
* @example
|
||
*
|
||
* _.lastIndexOf([1, 2, 1, 2], 2);
|
||
* // => 3
|
||
*
|
||
* // Search from the `fromIndex`.
|
||
* _.lastIndexOf([1, 2, 1, 2], 2, 2);
|
||
* // => 1
|
||
*/
|
||
function lastIndexOf(array, value, fromIndex) {
|
||
var length = array == null ? 0 : array.length;
|
||
if (!length) {
|
||
return -1;
|
||
}
|
||
var index = length;
|
||
if (fromIndex !== undefined) {
|
||
index = toInteger(fromIndex);
|
||
index = index < 0 ? nativeMax(length + index, 0) : nativeMin(index, length - 1);
|
||
}
|
||
return value === value
|
||
? strictLastIndexOf(array, value, index)
|
||
: baseFindIndex(array, baseIsNaN, index, true);
|
||
}
|
||
|
||
/**
|
||
* Gets the element at index `n` of `array`. If `n` is negative, the nth
|
||
* element from the end is returned.
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 4.11.0
|
||
* @category Array
|
||
* @param {Array} array The array to query.
|
||
* @param {number} [n=0] The index of the element to return.
|
||
* @returns {*} Returns the nth element of `array`.
|
||
* @example
|
||
*
|
||
* var array = ['a', 'b', 'c', 'd'];
|
||
*
|
||
* _.nth(array, 1);
|
||
* // => 'b'
|
||
*
|
||
* _.nth(array, -2);
|
||
* // => 'c';
|
||
*/
|
||
function nth(array, n) {
|
||
return (array && array.length) ? baseNth(array, toInteger(n)) : undefined;
|
||
}
|
||
|
||
/**
|
||
* Removes all given values from `array` using
|
||
* [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
|
||
* for equality comparisons.
|
||
*
|
||
* **Note:** Unlike `_.without`, this method mutates `array`. Use `_.remove`
|
||
* to remove elements from an array by predicate.
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 2.0.0
|
||
* @category Array
|
||
* @param {Array} array The array to modify.
|
||
* @param {...*} [values] The values to remove.
|
||
* @returns {Array} Returns `array`.
|
||
* @example
|
||
*
|
||
* var array = ['a', 'b', 'c', 'a', 'b', 'c'];
|
||
*
|
||
* _.pull(array, 'a', 'c');
|
||
* console.log(array);
|
||
* // => ['b', 'b']
|
||
*/
|
||
var pull = baseRest(pullAll);
|
||
|
||
/**
|
||
* This method is like `_.pull` except that it accepts an array of values to remove.
|
||
*
|
||
* **Note:** Unlike `_.difference`, this method mutates `array`.
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 4.0.0
|
||
* @category Array
|
||
* @param {Array} array The array to modify.
|
||
* @param {Array} values The values to remove.
|
||
* @returns {Array} Returns `array`.
|
||
* @example
|
||
*
|
||
* var array = ['a', 'b', 'c', 'a', 'b', 'c'];
|
||
*
|
||
* _.pullAll(array, ['a', 'c']);
|
||
* console.log(array);
|
||
* // => ['b', 'b']
|
||
*/
|
||
function pullAll(array, values) {
|
||
return (array && array.length && values && values.length)
|
||
? basePullAll(array, values)
|
||
: array;
|
||
}
|
||
|
||
/**
|
||
* This method is like `_.pullAll` except that it accepts `iteratee` which is
|
||
* invoked for each element of `array` and `values` to generate the criterion
|
||
* by which they're compared. The iteratee is invoked with one argument: (value).
|
||
*
|
||
* **Note:** Unlike `_.differenceBy`, this method mutates `array`.
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 4.0.0
|
||
* @category Array
|
||
* @param {Array} array The array to modify.
|
||
* @param {Array} values The values to remove.
|
||
* @param {Function} [iteratee=_.identity] The iteratee invoked per element.
|
||
* @returns {Array} Returns `array`.
|
||
* @example
|
||
*
|
||
* var array = [{ 'x': 1 }, { 'x': 2 }, { 'x': 3 }, { 'x': 1 }];
|
||
*
|
||
* _.pullAllBy(array, [{ 'x': 1 }, { 'x': 3 }], 'x');
|
||
* console.log(array);
|
||
* // => [{ 'x': 2 }]
|
||
*/
|
||
function pullAllBy(array, values, iteratee) {
|
||
return (array && array.length && values && values.length)
|
||
? basePullAll(array, values, getIteratee(iteratee, 2))
|
||
: array;
|
||
}
|
||
|
||
/**
|
||
* This method is like `_.pullAll` except that it accepts `comparator` which
|
||
* is invoked to compare elements of `array` to `values`. The comparator is
|
||
* invoked with two arguments: (arrVal, othVal).
|
||
*
|
||
* **Note:** Unlike `_.differenceWith`, this method mutates `array`.
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 4.6.0
|
||
* @category Array
|
||
* @param {Array} array The array to modify.
|
||
* @param {Array} values The values to remove.
|
||
* @param {Function} [comparator] The comparator invoked per element.
|
||
* @returns {Array} Returns `array`.
|
||
* @example
|
||
*
|
||
* var array = [{ 'x': 1, 'y': 2 }, { 'x': 3, 'y': 4 }, { 'x': 5, 'y': 6 }];
|
||
*
|
||
* _.pullAllWith(array, [{ 'x': 3, 'y': 4 }], _.isEqual);
|
||
* console.log(array);
|
||
* // => [{ 'x': 1, 'y': 2 }, { 'x': 5, 'y': 6 }]
|
||
*/
|
||
function pullAllWith(array, values, comparator) {
|
||
return (array && array.length && values && values.length)
|
||
? basePullAll(array, values, undefined, comparator)
|
||
: array;
|
||
}
|
||
|
||
/**
|
||
* Removes elements from `array` corresponding to `indexes` and returns an
|
||
* array of removed elements.
|
||
*
|
||
* **Note:** Unlike `_.at`, this method mutates `array`.
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 3.0.0
|
||
* @category Array
|
||
* @param {Array} array The array to modify.
|
||
* @param {...(number|number[])} [indexes] The indexes of elements to remove.
|
||
* @returns {Array} Returns the new array of removed elements.
|
||
* @example
|
||
*
|
||
* var array = ['a', 'b', 'c', 'd'];
|
||
* var pulled = _.pullAt(array, [1, 3]);
|
||
*
|
||
* console.log(array);
|
||
* // => ['a', 'c']
|
||
*
|
||
* console.log(pulled);
|
||
* // => ['b', 'd']
|
||
*/
|
||
var pullAt = flatRest(function(array, indexes) {
|
||
var length = array == null ? 0 : array.length,
|
||
result = baseAt(array, indexes);
|
||
|
||
basePullAt(array, arrayMap(indexes, function(index) {
|
||
return isIndex(index, length) ? +index : index;
|
||
}).sort(compareAscending));
|
||
|
||
return result;
|
||
});
|
||
|
||
/**
|
||
* Removes all elements from `array` that `predicate` returns truthy for
|
||
* and returns an array of the removed elements. The predicate is invoked
|
||
* with three arguments: (value, index, array).
|
||
*
|
||
* **Note:** Unlike `_.filter`, this method mutates `array`. Use `_.pull`
|
||
* to pull elements from an array by value.
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 2.0.0
|
||
* @category Array
|
||
* @param {Array} array The array to modify.
|
||
* @param {Function} [predicate=_.identity] The function invoked per iteration.
|
||
* @returns {Array} Returns the new array of removed elements.
|
||
* @example
|
||
*
|
||
* var array = [1, 2, 3, 4];
|
||
* var evens = _.remove(array, function(n) {
|
||
* return n % 2 == 0;
|
||
* });
|
||
*
|
||
* console.log(array);
|
||
* // => [1, 3]
|
||
*
|
||
* console.log(evens);
|
||
* // => [2, 4]
|
||
*/
|
||
function remove(array, predicate) {
|
||
var result = [];
|
||
if (!(array && array.length)) {
|
||
return result;
|
||
}
|
||
var index = -1,
|
||
indexes = [],
|
||
length = array.length;
|
||
|
||
predicate = getIteratee(predicate, 3);
|
||
while (++index < length) {
|
||
var value = array[index];
|
||
if (predicate(value, index, array)) {
|
||
result.push(value);
|
||
indexes.push(index);
|
||
}
|
||
}
|
||
basePullAt(array, indexes);
|
||
return result;
|
||
}
|
||
|
||
/**
|
||
* Reverses `array` so that the first element becomes the last, the second
|
||
* element becomes the second to last, and so on.
|
||
*
|
||
* **Note:** This method mutates `array` and is based on
|
||
* [`Array#reverse`](https://mdn.io/Array/reverse).
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 4.0.0
|
||
* @category Array
|
||
* @param {Array} array The array to modify.
|
||
* @returns {Array} Returns `array`.
|
||
* @example
|
||
*
|
||
* var array = [1, 2, 3];
|
||
*
|
||
* _.reverse(array);
|
||
* // => [3, 2, 1]
|
||
*
|
||
* console.log(array);
|
||
* // => [3, 2, 1]
|
||
*/
|
||
function reverse(array) {
|
||
return array == null ? array : nativeReverse.call(array);
|
||
}
|
||
|
||
/**
|
||
* Creates a slice of `array` from `start` up to, but not including, `end`.
|
||
*
|
||
* **Note:** This method is used instead of
|
||
* [`Array#slice`](https://mdn.io/Array/slice) to ensure dense arrays are
|
||
* returned.
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 3.0.0
|
||
* @category Array
|
||
* @param {Array} array The array to slice.
|
||
* @param {number} [start=0] The start position.
|
||
* @param {number} [end=array.length] The end position.
|
||
* @returns {Array} Returns the slice of `array`.
|
||
*/
|
||
function slice(array, start, end) {
|
||
var length = array == null ? 0 : array.length;
|
||
if (!length) {
|
||
return [];
|
||
}
|
||
if (end && typeof end != 'number' && isIterateeCall(array, start, end)) {
|
||
start = 0;
|
||
end = length;
|
||
}
|
||
else {
|
||
start = start == null ? 0 : toInteger(start);
|
||
end = end === undefined ? length : toInteger(end);
|
||
}
|
||
return baseSlice(array, start, end);
|
||
}
|
||
|
||
/**
|
||
* Uses a binary search to determine the lowest index at which `value`
|
||
* should be inserted into `array` in order to maintain its sort order.
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 0.1.0
|
||
* @category Array
|
||
* @param {Array} array The sorted array to inspect.
|
||
* @param {*} value The value to evaluate.
|
||
* @returns {number} Returns the index at which `value` should be inserted
|
||
* into `array`.
|
||
* @example
|
||
*
|
||
* _.sortedIndex([30, 50], 40);
|
||
* // => 1
|
||
*/
|
||
function sortedIndex(array, value) {
|
||
return baseSortedIndex(array, value);
|
||
}
|
||
|
||
/**
|
||
* This method is like `_.sortedIndex` except that it accepts `iteratee`
|
||
* which is invoked for `value` and each element of `array` to compute their
|
||
* sort ranking. The iteratee is invoked with one argument: (value).
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 4.0.0
|
||
* @category Array
|
||
* @param {Array} array The sorted array to inspect.
|
||
* @param {*} value The value to evaluate.
|
||
* @param {Function} [iteratee=_.identity] The iteratee invoked per element.
|
||
* @returns {number} Returns the index at which `value` should be inserted
|
||
* into `array`.
|
||
* @example
|
||
*
|
||
* var objects = [{ 'x': 4 }, { 'x': 5 }];
|
||
*
|
||
* _.sortedIndexBy(objects, { 'x': 4 }, function(o) { return o.x; });
|
||
* // => 0
|
||
*
|
||
* // The `_.property` iteratee shorthand.
|
||
* _.sortedIndexBy(objects, { 'x': 4 }, 'x');
|
||
* // => 0
|
||
*/
|
||
function sortedIndexBy(array, value, iteratee) {
|
||
return baseSortedIndexBy(array, value, getIteratee(iteratee, 2));
|
||
}
|
||
|
||
/**
|
||
* This method is like `_.indexOf` except that it performs a binary
|
||
* search on a sorted `array`.
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 4.0.0
|
||
* @category Array
|
||
* @param {Array} array The array to inspect.
|
||
* @param {*} value The value to search for.
|
||
* @returns {number} Returns the index of the matched value, else `-1`.
|
||
* @example
|
||
*
|
||
* _.sortedIndexOf([4, 5, 5, 5, 6], 5);
|
||
* // => 1
|
||
*/
|
||
function sortedIndexOf(array, value) {
|
||
var length = array == null ? 0 : array.length;
|
||
if (length) {
|
||
var index = baseSortedIndex(array, value);
|
||
if (index < length && eq(array[index], value)) {
|
||
return index;
|
||
}
|
||
}
|
||
return -1;
|
||
}
|
||
|
||
/**
|
||
* This method is like `_.sortedIndex` except that it returns the highest
|
||
* index at which `value` should be inserted into `array` in order to
|
||
* maintain its sort order.
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 3.0.0
|
||
* @category Array
|
||
* @param {Array} array The sorted array to inspect.
|
||
* @param {*} value The value to evaluate.
|
||
* @returns {number} Returns the index at which `value` should be inserted
|
||
* into `array`.
|
||
* @example
|
||
*
|
||
* _.sortedLastIndex([4, 5, 5, 5, 6], 5);
|
||
* // => 4
|
||
*/
|
||
function sortedLastIndex(array, value) {
|
||
return baseSortedIndex(array, value, true);
|
||
}
|
||
|
||
/**
|
||
* This method is like `_.sortedLastIndex` except that it accepts `iteratee`
|
||
* which is invoked for `value` and each element of `array` to compute their
|
||
* sort ranking. The iteratee is invoked with one argument: (value).
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 4.0.0
|
||
* @category Array
|
||
* @param {Array} array The sorted array to inspect.
|
||
* @param {*} value The value to evaluate.
|
||
* @param {Function} [iteratee=_.identity] The iteratee invoked per element.
|
||
* @returns {number} Returns the index at which `value` should be inserted
|
||
* into `array`.
|
||
* @example
|
||
*
|
||
* var objects = [{ 'x': 4 }, { 'x': 5 }];
|
||
*
|
||
* _.sortedLastIndexBy(objects, { 'x': 4 }, function(o) { return o.x; });
|
||
* // => 1
|
||
*
|
||
* // The `_.property` iteratee shorthand.
|
||
* _.sortedLastIndexBy(objects, { 'x': 4 }, 'x');
|
||
* // => 1
|
||
*/
|
||
function sortedLastIndexBy(array, value, iteratee) {
|
||
return baseSortedIndexBy(array, value, getIteratee(iteratee, 2), true);
|
||
}
|
||
|
||
/**
|
||
* This method is like `_.lastIndexOf` except that it performs a binary
|
||
* search on a sorted `array`.
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 4.0.0
|
||
* @category Array
|
||
* @param {Array} array The array to inspect.
|
||
* @param {*} value The value to search for.
|
||
* @returns {number} Returns the index of the matched value, else `-1`.
|
||
* @example
|
||
*
|
||
* _.sortedLastIndexOf([4, 5, 5, 5, 6], 5);
|
||
* // => 3
|
||
*/
|
||
function sortedLastIndexOf(array, value) {
|
||
var length = array == null ? 0 : array.length;
|
||
if (length) {
|
||
var index = baseSortedIndex(array, value, true) - 1;
|
||
if (eq(array[index], value)) {
|
||
return index;
|
||
}
|
||
}
|
||
return -1;
|
||
}
|
||
|
||
/**
|
||
* This method is like `_.uniq` except that it's designed and optimized
|
||
* for sorted arrays.
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 4.0.0
|
||
* @category Array
|
||
* @param {Array} array The array to inspect.
|
||
* @returns {Array} Returns the new duplicate free array.
|
||
* @example
|
||
*
|
||
* _.sortedUniq([1, 1, 2]);
|
||
* // => [1, 2]
|
||
*/
|
||
function sortedUniq(array) {
|
||
return (array && array.length)
|
||
? baseSortedUniq(array)
|
||
: [];
|
||
}
|
||
|
||
/**
|
||
* This method is like `_.uniqBy` except that it's designed and optimized
|
||
* for sorted arrays.
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 4.0.0
|
||
* @category Array
|
||
* @param {Array} array The array to inspect.
|
||
* @param {Function} [iteratee] The iteratee invoked per element.
|
||
* @returns {Array} Returns the new duplicate free array.
|
||
* @example
|
||
*
|
||
* _.sortedUniqBy([1.1, 1.2, 2.3, 2.4], Math.floor);
|
||
* // => [1.1, 2.3]
|
||
*/
|
||
function sortedUniqBy(array, iteratee) {
|
||
return (array && array.length)
|
||
? baseSortedUniq(array, getIteratee(iteratee, 2))
|
||
: [];
|
||
}
|
||
|
||
/**
|
||
* Gets all but the first element of `array`.
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 4.0.0
|
||
* @category Array
|
||
* @param {Array} array The array to query.
|
||
* @returns {Array} Returns the slice of `array`.
|
||
* @example
|
||
*
|
||
* _.tail([1, 2, 3]);
|
||
* // => [2, 3]
|
||
*/
|
||
function tail(array) {
|
||
var length = array == null ? 0 : array.length;
|
||
return length ? baseSlice(array, 1, length) : [];
|
||
}
|
||
|
||
/**
|
||
* Creates a slice of `array` with `n` elements taken from the beginning.
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 0.1.0
|
||
* @category Array
|
||
* @param {Array} array The array to query.
|
||
* @param {number} [n=1] The number of elements to take.
|
||
* @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
|
||
* @returns {Array} Returns the slice of `array`.
|
||
* @example
|
||
*
|
||
* _.take([1, 2, 3]);
|
||
* // => [1]
|
||
*
|
||
* _.take([1, 2, 3], 2);
|
||
* // => [1, 2]
|
||
*
|
||
* _.take([1, 2, 3], 5);
|
||
* // => [1, 2, 3]
|
||
*
|
||
* _.take([1, 2, 3], 0);
|
||
* // => []
|
||
*/
|
||
function take(array, n, guard) {
|
||
if (!(array && array.length)) {
|
||
return [];
|
||
}
|
||
n = (guard || n === undefined) ? 1 : toInteger(n);
|
||
return baseSlice(array, 0, n < 0 ? 0 : n);
|
||
}
|
||
|
||
/**
|
||
* Creates a slice of `array` with `n` elements taken from the end.
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 3.0.0
|
||
* @category Array
|
||
* @param {Array} array The array to query.
|
||
* @param {number} [n=1] The number of elements to take.
|
||
* @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
|
||
* @returns {Array} Returns the slice of `array`.
|
||
* @example
|
||
*
|
||
* _.takeRight([1, 2, 3]);
|
||
* // => [3]
|
||
*
|
||
* _.takeRight([1, 2, 3], 2);
|
||
* // => [2, 3]
|
||
*
|
||
* _.takeRight([1, 2, 3], 5);
|
||
* // => [1, 2, 3]
|
||
*
|
||
* _.takeRight([1, 2, 3], 0);
|
||
* // => []
|
||
*/
|
||
function takeRight(array, n, guard) {
|
||
var length = array == null ? 0 : array.length;
|
||
if (!length) {
|
||
return [];
|
||
}
|
||
n = (guard || n === undefined) ? 1 : toInteger(n);
|
||
n = length - n;
|
||
return baseSlice(array, n < 0 ? 0 : n, length);
|
||
}
|
||
|
||
/**
|
||
* Creates a slice of `array` with elements taken from the end. Elements are
|
||
* taken until `predicate` returns falsey. The predicate is invoked with
|
||
* three arguments: (value, index, array).
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 3.0.0
|
||
* @category Array
|
||
* @param {Array} array The array to query.
|
||
* @param {Function} [predicate=_.identity] The function invoked per iteration.
|
||
* @returns {Array} Returns the slice of `array`.
|
||
* @example
|
||
*
|
||
* var users = [
|
||
* { 'user': 'barney', 'active': true },
|
||
* { 'user': 'fred', 'active': false },
|
||
* { 'user': 'pebbles', 'active': false }
|
||
* ];
|
||
*
|
||
* _.takeRightWhile(users, function(o) { return !o.active; });
|
||
* // => objects for ['fred', 'pebbles']
|
||
*
|
||
* // The `_.matches` iteratee shorthand.
|
||
* _.takeRightWhile(users, { 'user': 'pebbles', 'active': false });
|
||
* // => objects for ['pebbles']
|
||
*
|
||
* // The `_.matchesProperty` iteratee shorthand.
|
||
* _.takeRightWhile(users, ['active', false]);
|
||
* // => objects for ['fred', 'pebbles']
|
||
*
|
||
* // The `_.property` iteratee shorthand.
|
||
* _.takeRightWhile(users, 'active');
|
||
* // => []
|
||
*/
|
||
function takeRightWhile(array, predicate) {
|
||
return (array && array.length)
|
||
? baseWhile(array, getIteratee(predicate, 3), false, true)
|
||
: [];
|
||
}
|
||
|
||
/**
|
||
* Creates a slice of `array` with elements taken from the beginning. Elements
|
||
* are taken until `predicate` returns falsey. The predicate is invoked with
|
||
* three arguments: (value, index, array).
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 3.0.0
|
||
* @category Array
|
||
* @param {Array} array The array to query.
|
||
* @param {Function} [predicate=_.identity] The function invoked per iteration.
|
||
* @returns {Array} Returns the slice of `array`.
|
||
* @example
|
||
*
|
||
* var users = [
|
||
* { 'user': 'barney', 'active': false },
|
||
* { 'user': 'fred', 'active': false },
|
||
* { 'user': 'pebbles', 'active': true }
|
||
* ];
|
||
*
|
||
* _.takeWhile(users, function(o) { return !o.active; });
|
||
* // => objects for ['barney', 'fred']
|
||
*
|
||
* // The `_.matches` iteratee shorthand.
|
||
* _.takeWhile(users, { 'user': 'barney', 'active': false });
|
||
* // => objects for ['barney']
|
||
*
|
||
* // The `_.matchesProperty` iteratee shorthand.
|
||
* _.takeWhile(users, ['active', false]);
|
||
* // => objects for ['barney', 'fred']
|
||
*
|
||
* // The `_.property` iteratee shorthand.
|
||
* _.takeWhile(users, 'active');
|
||
* // => []
|
||
*/
|
||
function takeWhile(array, predicate) {
|
||
return (array && array.length)
|
||
? baseWhile(array, getIteratee(predicate, 3))
|
||
: [];
|
||
}
|
||
|
||
/**
|
||
* Creates an array of unique values, in order, from all given arrays using
|
||
* [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
|
||
* for equality comparisons.
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 0.1.0
|
||
* @category Array
|
||
* @param {...Array} [arrays] The arrays to inspect.
|
||
* @returns {Array} Returns the new array of combined values.
|
||
* @example
|
||
*
|
||
* _.union([2], [1, 2]);
|
||
* // => [2, 1]
|
||
*/
|
||
var union = baseRest(function(arrays) {
|
||
return baseUniq(baseFlatten(arrays, 1, isArrayLikeObject, true));
|
||
});
|
||
|
||
/**
|
||
* This method is like `_.union` except that it accepts `iteratee` which is
|
||
* invoked for each element of each `arrays` to generate the criterion by
|
||
* which uniqueness is computed. Result values are chosen from the first
|
||
* array in which the value occurs. The iteratee is invoked with one argument:
|
||
* (value).
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 4.0.0
|
||
* @category Array
|
||
* @param {...Array} [arrays] The arrays to inspect.
|
||
* @param {Function} [iteratee=_.identity] The iteratee invoked per element.
|
||
* @returns {Array} Returns the new array of combined values.
|
||
* @example
|
||
*
|
||
* _.unionBy([2.1], [1.2, 2.3], Math.floor);
|
||
* // => [2.1, 1.2]
|
||
*
|
||
* // The `_.property` iteratee shorthand.
|
||
* _.unionBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x');
|
||
* // => [{ 'x': 1 }, { 'x': 2 }]
|
||
*/
|
||
var unionBy = baseRest(function(arrays) {
|
||
var iteratee = last(arrays);
|
||
if (isArrayLikeObject(iteratee)) {
|
||
iteratee = undefined;
|
||
}
|
||
return baseUniq(baseFlatten(arrays, 1, isArrayLikeObject, true), getIteratee(iteratee, 2));
|
||
});
|
||
|
||
/**
|
||
* This method is like `_.union` except that it accepts `comparator` which
|
||
* is invoked to compare elements of `arrays`. Result values are chosen from
|
||
* the first array in which the value occurs. The comparator is invoked
|
||
* with two arguments: (arrVal, othVal).
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 4.0.0
|
||
* @category Array
|
||
* @param {...Array} [arrays] The arrays to inspect.
|
||
* @param {Function} [comparator] The comparator invoked per element.
|
||
* @returns {Array} Returns the new array of combined values.
|
||
* @example
|
||
*
|
||
* var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }];
|
||
* var others = [{ 'x': 1, 'y': 1 }, { 'x': 1, 'y': 2 }];
|
||
*
|
||
* _.unionWith(objects, others, _.isEqual);
|
||
* // => [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }, { 'x': 1, 'y': 1 }]
|
||
*/
|
||
var unionWith = baseRest(function(arrays) {
|
||
var comparator = last(arrays);
|
||
comparator = typeof comparator == 'function' ? comparator : undefined;
|
||
return baseUniq(baseFlatten(arrays, 1, isArrayLikeObject, true), undefined, comparator);
|
||
});
|
||
|
||
/**
|
||
* Creates a duplicate-free version of an array, using
|
||
* [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
|
||
* for equality comparisons, in which only the first occurrence of each element
|
||
* is kept. The order of result values is determined by the order they occur
|
||
* in the array.
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 0.1.0
|
||
* @category Array
|
||
* @param {Array} array The array to inspect.
|
||
* @returns {Array} Returns the new duplicate free array.
|
||
* @example
|
||
*
|
||
* _.uniq([2, 1, 2]);
|
||
* // => [2, 1]
|
||
*/
|
||
function uniq(array) {
|
||
return (array && array.length) ? baseUniq(array) : [];
|
||
}
|
||
|
||
/**
|
||
* This method is like `_.uniq` except that it accepts `iteratee` which is
|
||
* invoked for each element in `array` to generate the criterion by which
|
||
* uniqueness is computed. The order of result values is determined by the
|
||
* order they occur in the array. The iteratee is invoked with one argument:
|
||
* (value).
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 4.0.0
|
||
* @category Array
|
||
* @param {Array} array The array to inspect.
|
||
* @param {Function} [iteratee=_.identity] The iteratee invoked per element.
|
||
* @returns {Array} Returns the new duplicate free array.
|
||
* @example
|
||
*
|
||
* _.uniqBy([2.1, 1.2, 2.3], Math.floor);
|
||
* // => [2.1, 1.2]
|
||
*
|
||
* // The `_.property` iteratee shorthand.
|
||
* _.uniqBy([{ 'x': 1 }, { 'x': 2 }, { 'x': 1 }], 'x');
|
||
* // => [{ 'x': 1 }, { 'x': 2 }]
|
||
*/
|
||
function uniqBy(array, iteratee) {
|
||
return (array && array.length) ? baseUniq(array, getIteratee(iteratee, 2)) : [];
|
||
}
|
||
|
||
/**
|
||
* This method is like `_.uniq` except that it accepts `comparator` which
|
||
* is invoked to compare elements of `array`. The order of result values is
|
||
* determined by the order they occur in the array.The comparator is invoked
|
||
* with two arguments: (arrVal, othVal).
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 4.0.0
|
||
* @category Array
|
||
* @param {Array} array The array to inspect.
|
||
* @param {Function} [comparator] The comparator invoked per element.
|
||
* @returns {Array} Returns the new duplicate free array.
|
||
* @example
|
||
*
|
||
* var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }, { 'x': 1, 'y': 2 }];
|
||
*
|
||
* _.uniqWith(objects, _.isEqual);
|
||
* // => [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }]
|
||
*/
|
||
function uniqWith(array, comparator) {
|
||
comparator = typeof comparator == 'function' ? comparator : undefined;
|
||
return (array && array.length) ? baseUniq(array, undefined, comparator) : [];
|
||
}
|
||
|
||
/**
|
||
* This method is like `_.zip` except that it accepts an array of grouped
|
||
* elements and creates an array regrouping the elements to their pre-zip
|
||
* configuration.
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 1.2.0
|
||
* @category Array
|
||
* @param {Array} array The array of grouped elements to process.
|
||
* @returns {Array} Returns the new array of regrouped elements.
|
||
* @example
|
||
*
|
||
* var zipped = _.zip(['a', 'b'], [1, 2], [true, false]);
|
||
* // => [['a', 1, true], ['b', 2, false]]
|
||
*
|
||
* _.unzip(zipped);
|
||
* // => [['a', 'b'], [1, 2], [true, false]]
|
||
*/
|
||
function unzip(array) {
|
||
if (!(array && array.length)) {
|
||
return [];
|
||
}
|
||
var length = 0;
|
||
array = arrayFilter(array, function(group) {
|
||
if (isArrayLikeObject(group)) {
|
||
length = nativeMax(group.length, length);
|
||
return true;
|
||
}
|
||
});
|
||
return baseTimes(length, function(index) {
|
||
return arrayMap(array, baseProperty(index));
|
||
});
|
||
}
|
||
|
||
/**
|
||
* This method is like `_.unzip` except that it accepts `iteratee` to specify
|
||
* how regrouped values should be combined. The iteratee is invoked with the
|
||
* elements of each group: (...group).
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 3.8.0
|
||
* @category Array
|
||
* @param {Array} array The array of grouped elements to process.
|
||
* @param {Function} [iteratee=_.identity] The function to combine
|
||
* regrouped values.
|
||
* @returns {Array} Returns the new array of regrouped elements.
|
||
* @example
|
||
*
|
||
* var zipped = _.zip([1, 2], [10, 20], [100, 200]);
|
||
* // => [[1, 10, 100], [2, 20, 200]]
|
||
*
|
||
* _.unzipWith(zipped, _.add);
|
||
* // => [3, 30, 300]
|
||
*/
|
||
function unzipWith(array, iteratee) {
|
||
if (!(array && array.length)) {
|
||
return [];
|
||
}
|
||
var result = unzip(array);
|
||
if (iteratee == null) {
|
||
return result;
|
||
}
|
||
return arrayMap(result, function(group) {
|
||
return apply(iteratee, undefined, group);
|
||
});
|
||
}
|
||
|
||
/**
|
||
* Creates an array excluding all given values using
|
||
* [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
|
||
* for equality comparisons.
|
||
*
|
||
* **Note:** Unlike `_.pull`, this method returns a new array.
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 0.1.0
|
||
* @category Array
|
||
* @param {Array} array The array to inspect.
|
||
* @param {...*} [values] The values to exclude.
|
||
* @returns {Array} Returns the new array of filtered values.
|
||
* @see _.difference, _.xor
|
||
* @example
|
||
*
|
||
* _.without([2, 1, 2, 3], 1, 2);
|
||
* // => [3]
|
||
*/
|
||
var without = baseRest(function(array, values) {
|
||
return isArrayLikeObject(array)
|
||
? baseDifference(array, values)
|
||
: [];
|
||
});
|
||
|
||
/**
|
||
* Creates an array of unique values that is the
|
||
* [symmetric difference](https://en.wikipedia.org/wiki/Symmetric_difference)
|
||
* of the given arrays. The order of result values is determined by the order
|
||
* they occur in the arrays.
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 2.4.0
|
||
* @category Array
|
||
* @param {...Array} [arrays] The arrays to inspect.
|
||
* @returns {Array} Returns the new array of filtered values.
|
||
* @see _.difference, _.without
|
||
* @example
|
||
*
|
||
* _.xor([2, 1], [2, 3]);
|
||
* // => [1, 3]
|
||
*/
|
||
var xor = baseRest(function(arrays) {
|
||
return baseXor(arrayFilter(arrays, isArrayLikeObject));
|
||
});
|
||
|
||
/**
|
||
* This method is like `_.xor` except that it accepts `iteratee` which is
|
||
* invoked for each element of each `arrays` to generate the criterion by
|
||
* which by which they're compared. The order of result values is determined
|
||
* by the order they occur in the arrays. The iteratee is invoked with one
|
||
* argument: (value).
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 4.0.0
|
||
* @category Array
|
||
* @param {...Array} [arrays] The arrays to inspect.
|
||
* @param {Function} [iteratee=_.identity] The iteratee invoked per element.
|
||
* @returns {Array} Returns the new array of filtered values.
|
||
* @example
|
||
*
|
||
* _.xorBy([2.1, 1.2], [2.3, 3.4], Math.floor);
|
||
* // => [1.2, 3.4]
|
||
*
|
||
* // The `_.property` iteratee shorthand.
|
||
* _.xorBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x');
|
||
* // => [{ 'x': 2 }]
|
||
*/
|
||
var xorBy = baseRest(function(arrays) {
|
||
var iteratee = last(arrays);
|
||
if (isArrayLikeObject(iteratee)) {
|
||
iteratee = undefined;
|
||
}
|
||
return baseXor(arrayFilter(arrays, isArrayLikeObject), getIteratee(iteratee, 2));
|
||
});
|
||
|
||
/**
|
||
* This method is like `_.xor` except that it accepts `comparator` which is
|
||
* invoked to compare elements of `arrays`. The order of result values is
|
||
* determined by the order they occur in the arrays. The comparator is invoked
|
||
* with two arguments: (arrVal, othVal).
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 4.0.0
|
||
* @category Array
|
||
* @param {...Array} [arrays] The arrays to inspect.
|
||
* @param {Function} [comparator] The comparator invoked per element.
|
||
* @returns {Array} Returns the new array of filtered values.
|
||
* @example
|
||
*
|
||
* var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }];
|
||
* var others = [{ 'x': 1, 'y': 1 }, { 'x': 1, 'y': 2 }];
|
||
*
|
||
* _.xorWith(objects, others, _.isEqual);
|
||
* // => [{ 'x': 2, 'y': 1 }, { 'x': 1, 'y': 1 }]
|
||
*/
|
||
var xorWith = baseRest(function(arrays) {
|
||
var comparator = last(arrays);
|
||
comparator = typeof comparator == 'function' ? comparator : undefined;
|
||
return baseXor(arrayFilter(arrays, isArrayLikeObject), undefined, comparator);
|
||
});
|
||
|
||
/**
|
||
* Creates an array of grouped elements, the first of which contains the
|
||
* first elements of the given arrays, the second of which contains the
|
||
* second elements of the given arrays, and so on.
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 0.1.0
|
||
* @category Array
|
||
* @param {...Array} [arrays] The arrays to process.
|
||
* @returns {Array} Returns the new array of grouped elements.
|
||
* @example
|
||
*
|
||
* _.zip(['a', 'b'], [1, 2], [true, false]);
|
||
* // => [['a', 1, true], ['b', 2, false]]
|
||
*/
|
||
var zip = baseRest(unzip);
|
||
|
||
/**
|
||
* This method is like `_.fromPairs` except that it accepts two arrays,
|
||
* one of property identifiers and one of corresponding values.
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 0.4.0
|
||
* @category Array
|
||
* @param {Array} [props=[]] The property identifiers.
|
||
* @param {Array} [values=[]] The property values.
|
||
* @returns {Object} Returns the new object.
|
||
* @example
|
||
*
|
||
* _.zipObject(['a', 'b'], [1, 2]);
|
||
* // => { 'a': 1, 'b': 2 }
|
||
*/
|
||
function zipObject(props, values) {
|
||
return baseZipObject(props || [], values || [], assignValue);
|
||
}
|
||
|
||
/**
|
||
* This method is like `_.zipObject` except that it supports property paths.
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 4.1.0
|
||
* @category Array
|
||
* @param {Array} [props=[]] The property identifiers.
|
||
* @param {Array} [values=[]] The property values.
|
||
* @returns {Object} Returns the new object.
|
||
* @example
|
||
*
|
||
* _.zipObjectDeep(['a.b[0].c', 'a.b[1].d'], [1, 2]);
|
||
* // => { 'a': { 'b': [{ 'c': 1 }, { 'd': 2 }] } }
|
||
*/
|
||
function zipObjectDeep(props, values) {
|
||
return baseZipObject(props || [], values || [], baseSet);
|
||
}
|
||
|
||
/**
|
||
* This method is like `_.zip` except that it accepts `iteratee` to specify
|
||
* how grouped values should be combined. The iteratee is invoked with the
|
||
* elements of each group: (...group).
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 3.8.0
|
||
* @category Array
|
||
* @param {...Array} [arrays] The arrays to process.
|
||
* @param {Function} [iteratee=_.identity] The function to combine
|
||
* grouped values.
|
||
* @returns {Array} Returns the new array of grouped elements.
|
||
* @example
|
||
*
|
||
* _.zipWith([1, 2], [10, 20], [100, 200], function(a, b, c) {
|
||
* return a + b + c;
|
||
* });
|
||
* // => [111, 222]
|
||
*/
|
||
var zipWith = baseRest(function(arrays) {
|
||
var length = arrays.length,
|
||
iteratee = length > 1 ? arrays[length - 1] : undefined;
|
||
|
||
iteratee = typeof iteratee == 'function' ? (arrays.pop(), iteratee) : undefined;
|
||
return unzipWith(arrays, iteratee);
|
||
});
|
||
|
||
/*------------------------------------------------------------------------*/
|
||
|
||
/**
|
||
* Creates a `lodash` wrapper instance that wraps `value` with explicit method
|
||
* chain sequences enabled. The result of such sequences must be unwrapped
|
||
* with `_#value`.
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 1.3.0
|
||
* @category Seq
|
||
* @param {*} value The value to wrap.
|
||
* @returns {Object} Returns the new `lodash` wrapper instance.
|
||
* @example
|
||
*
|
||
* var users = [
|
||
* { 'user': 'barney', 'age': 36 },
|
||
* { 'user': 'fred', 'age': 40 },
|
||
* { 'user': 'pebbles', 'age': 1 }
|
||
* ];
|
||
*
|
||
* var youngest = _
|
||
* .chain(users)
|
||
* .sortBy('age')
|
||
* .map(function(o) {
|
||
* return o.user + ' is ' + o.age;
|
||
* })
|
||
* .head()
|
||
* .value();
|
||
* // => 'pebbles is 1'
|
||
*/
|
||
function chain(value) {
|
||
var result = lodash(value);
|
||
result.__chain__ = true;
|
||
return result;
|
||
}
|
||
|
||
/**
|
||
* This method invokes `interceptor` and returns `value`. The interceptor
|
||
* is invoked with one argument; (value). The purpose of this method is to
|
||
* "tap into" a method chain sequence in order to modify intermediate results.
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 0.1.0
|
||
* @category Seq
|
||
* @param {*} value The value to provide to `interceptor`.
|
||
* @param {Function} interceptor The function to invoke.
|
||
* @returns {*} Returns `value`.
|
||
* @example
|
||
*
|
||
* _([1, 2, 3])
|
||
* .tap(function(array) {
|
||
* // Mutate input array.
|
||
* array.pop();
|
||
* })
|
||
* .reverse()
|
||
* .value();
|
||
* // => [2, 1]
|
||
*/
|
||
function tap(value, interceptor) {
|
||
interceptor(value);
|
||
return value;
|
||
}
|
||
|
||
/**
|
||
* This method is like `_.tap` except that it returns the result of `interceptor`.
|
||
* The purpose of this method is to "pass thru" values replacing intermediate
|
||
* results in a method chain sequence.
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 3.0.0
|
||
* @category Seq
|
||
* @param {*} value The value to provide to `interceptor`.
|
||
* @param {Function} interceptor The function to invoke.
|
||
* @returns {*} Returns the result of `interceptor`.
|
||
* @example
|
||
*
|
||
* _(' abc ')
|
||
* .chain()
|
||
* .trim()
|
||
* .thru(function(value) {
|
||
* return [value];
|
||
* })
|
||
* .value();
|
||
* // => ['abc']
|
||
*/
|
||
function thru(value, interceptor) {
|
||
return interceptor(value);
|
||
}
|
||
|
||
/**
|
||
* This method is the wrapper version of `_.at`.
|
||
*
|
||
* @name at
|
||
* @memberOf _
|
||
* @since 1.0.0
|
||
* @category Seq
|
||
* @param {...(string|string[])} [paths] The property paths to pick.
|
||
* @returns {Object} Returns the new `lodash` wrapper instance.
|
||
* @example
|
||
*
|
||
* var object = { 'a': [{ 'b': { 'c': 3 } }, 4] };
|
||
*
|
||
* _(object).at(['a[0].b.c', 'a[1]']).value();
|
||
* // => [3, 4]
|
||
*/
|
||
var wrapperAt = flatRest(function(paths) {
|
||
var length = paths.length,
|
||
start = length ? paths[0] : 0,
|
||
value = this.__wrapped__,
|
||
interceptor = function(object) { return baseAt(object, paths); };
|
||
|
||
if (length > 1 || this.__actions__.length ||
|
||
!(value instanceof LazyWrapper) || !isIndex(start)) {
|
||
return this.thru(interceptor);
|
||
}
|
||
value = value.slice(start, +start + (length ? 1 : 0));
|
||
value.__actions__.push({
|
||
'func': thru,
|
||
'args': [interceptor],
|
||
'thisArg': undefined
|
||
});
|
||
return new LodashWrapper(value, this.__chain__).thru(function(array) {
|
||
if (length && !array.length) {
|
||
array.push(undefined);
|
||
}
|
||
return array;
|
||
});
|
||
});
|
||
|
||
/**
|
||
* Creates a `lodash` wrapper instance with explicit method chain sequences enabled.
|
||
*
|
||
* @name chain
|
||
* @memberOf _
|
||
* @since 0.1.0
|
||
* @category Seq
|
||
* @returns {Object} Returns the new `lodash` wrapper instance.
|
||
* @example
|
||
*
|
||
* var users = [
|
||
* { 'user': 'barney', 'age': 36 },
|
||
* { 'user': 'fred', 'age': 40 }
|
||
* ];
|
||
*
|
||
* // A sequence without explicit chaining.
|
||
* _(users).head();
|
||
* // => { 'user': 'barney', 'age': 36 }
|
||
*
|
||
* // A sequence with explicit chaining.
|
||
* _(users)
|
||
* .chain()
|
||
* .head()
|
||
* .pick('user')
|
||
* .value();
|
||
* // => { 'user': 'barney' }
|
||
*/
|
||
function wrapperChain() {
|
||
return chain(this);
|
||
}
|
||
|
||
/**
|
||
* Executes the chain sequence and returns the wrapped result.
|
||
*
|
||
* @name commit
|
||
* @memberOf _
|
||
* @since 3.2.0
|
||
* @category Seq
|
||
* @returns {Object} Returns the new `lodash` wrapper instance.
|
||
* @example
|
||
*
|
||
* var array = [1, 2];
|
||
* var wrapped = _(array).push(3);
|
||
*
|
||
* console.log(array);
|
||
* // => [1, 2]
|
||
*
|
||
* wrapped = wrapped.commit();
|
||
* console.log(array);
|
||
* // => [1, 2, 3]
|
||
*
|
||
* wrapped.last();
|
||
* // => 3
|
||
*
|
||
* console.log(array);
|
||
* // => [1, 2, 3]
|
||
*/
|
||
function wrapperCommit() {
|
||
return new LodashWrapper(this.value(), this.__chain__);
|
||
}
|
||
|
||
/**
|
||
* Gets the next value on a wrapped object following the
|
||
* [iterator protocol](https://mdn.io/iteration_protocols#iterator).
|
||
*
|
||
* @name next
|
||
* @memberOf _
|
||
* @since 4.0.0
|
||
* @category Seq
|
||
* @returns {Object} Returns the next iterator value.
|
||
* @example
|
||
*
|
||
* var wrapped = _([1, 2]);
|
||
*
|
||
* wrapped.next();
|
||
* // => { 'done': false, 'value': 1 }
|
||
*
|
||
* wrapped.next();
|
||
* // => { 'done': false, 'value': 2 }
|
||
*
|
||
* wrapped.next();
|
||
* // => { 'done': true, 'value': undefined }
|
||
*/
|
||
function wrapperNext() {
|
||
if (this.__values__ === undefined) {
|
||
this.__values__ = toArray(this.value());
|
||
}
|
||
var done = this.__index__ >= this.__values__.length,
|
||
value = done ? undefined : this.__values__[this.__index__++];
|
||
|
||
return { 'done': done, 'value': value };
|
||
}
|
||
|
||
/**
|
||
* Enables the wrapper to be iterable.
|
||
*
|
||
* @name Symbol.iterator
|
||
* @memberOf _
|
||
* @since 4.0.0
|
||
* @category Seq
|
||
* @returns {Object} Returns the wrapper object.
|
||
* @example
|
||
*
|
||
* var wrapped = _([1, 2]);
|
||
*
|
||
* wrapped[Symbol.iterator]() === wrapped;
|
||
* // => true
|
||
*
|
||
* Array.from(wrapped);
|
||
* // => [1, 2]
|
||
*/
|
||
function wrapperToIterator() {
|
||
return this;
|
||
}
|
||
|
||
/**
|
||
* Creates a clone of the chain sequence planting `value` as the wrapped value.
|
||
*
|
||
* @name plant
|
||
* @memberOf _
|
||
* @since 3.2.0
|
||
* @category Seq
|
||
* @param {*} value The value to plant.
|
||
* @returns {Object} Returns the new `lodash` wrapper instance.
|
||
* @example
|
||
*
|
||
* function square(n) {
|
||
* return n * n;
|
||
* }
|
||
*
|
||
* var wrapped = _([1, 2]).map(square);
|
||
* var other = wrapped.plant([3, 4]);
|
||
*
|
||
* other.value();
|
||
* // => [9, 16]
|
||
*
|
||
* wrapped.value();
|
||
* // => [1, 4]
|
||
*/
|
||
function wrapperPlant(value) {
|
||
var result,
|
||
parent = this;
|
||
|
||
while (parent instanceof baseLodash) {
|
||
var clone = wrapperClone(parent);
|
||
clone.__index__ = 0;
|
||
clone.__values__ = undefined;
|
||
if (result) {
|
||
previous.__wrapped__ = clone;
|
||
} else {
|
||
result = clone;
|
||
}
|
||
var previous = clone;
|
||
parent = parent.__wrapped__;
|
||
}
|
||
previous.__wrapped__ = value;
|
||
return result;
|
||
}
|
||
|
||
/**
|
||
* This method is the wrapper version of `_.reverse`.
|
||
*
|
||
* **Note:** This method mutates the wrapped array.
|
||
*
|
||
* @name reverse
|
||
* @memberOf _
|
||
* @since 0.1.0
|
||
* @category Seq
|
||
* @returns {Object} Returns the new `lodash` wrapper instance.
|
||
* @example
|
||
*
|
||
* var array = [1, 2, 3];
|
||
*
|
||
* _(array).reverse().value()
|
||
* // => [3, 2, 1]
|
||
*
|
||
* console.log(array);
|
||
* // => [3, 2, 1]
|
||
*/
|
||
function wrapperReverse() {
|
||
var value = this.__wrapped__;
|
||
if (value instanceof LazyWrapper) {
|
||
var wrapped = value;
|
||
if (this.__actions__.length) {
|
||
wrapped = new LazyWrapper(this);
|
||
}
|
||
wrapped = wrapped.reverse();
|
||
wrapped.__actions__.push({
|
||
'func': thru,
|
||
'args': [reverse],
|
||
'thisArg': undefined
|
||
});
|
||
return new LodashWrapper(wrapped, this.__chain__);
|
||
}
|
||
return this.thru(reverse);
|
||
}
|
||
|
||
/**
|
||
* Executes the chain sequence to resolve the unwrapped value.
|
||
*
|
||
* @name value
|
||
* @memberOf _
|
||
* @since 0.1.0
|
||
* @alias toJSON, valueOf
|
||
* @category Seq
|
||
* @returns {*} Returns the resolved unwrapped value.
|
||
* @example
|
||
*
|
||
* _([1, 2, 3]).value();
|
||
* // => [1, 2, 3]
|
||
*/
|
||
function wrapperValue() {
|
||
return baseWrapperValue(this.__wrapped__, this.__actions__);
|
||
}
|
||
|
||
/*------------------------------------------------------------------------*/
|
||
|
||
/**
|
||
* Creates an object composed of keys generated from the results of running
|
||
* each element of `collection` thru `iteratee`. The corresponding value of
|
||
* each key is the number of times the key was returned by `iteratee`. The
|
||
* iteratee is invoked with one argument: (value).
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 0.5.0
|
||
* @category Collection
|
||
* @param {Array|Object} collection The collection to iterate over.
|
||
* @param {Function} [iteratee=_.identity] The iteratee to transform keys.
|
||
* @returns {Object} Returns the composed aggregate object.
|
||
* @example
|
||
*
|
||
* _.countBy([6.1, 4.2, 6.3], Math.floor);
|
||
* // => { '4': 1, '6': 2 }
|
||
*
|
||
* // The `_.property` iteratee shorthand.
|
||
* _.countBy(['one', 'two', 'three'], 'length');
|
||
* // => { '3': 2, '5': 1 }
|
||
*/
|
||
var countBy = createAggregator(function(result, value, key) {
|
||
if (hasOwnProperty.call(result, key)) {
|
||
++result[key];
|
||
} else {
|
||
baseAssignValue(result, key, 1);
|
||
}
|
||
});
|
||
|
||
/**
|
||
* Checks if `predicate` returns truthy for **all** elements of `collection`.
|
||
* Iteration is stopped once `predicate` returns falsey. The predicate is
|
||
* invoked with three arguments: (value, index|key, collection).
|
||
*
|
||
* **Note:** This method returns `true` for
|
||
* [empty collections](https://en.wikipedia.org/wiki/Empty_set) because
|
||
* [everything is true](https://en.wikipedia.org/wiki/Vacuous_truth) of
|
||
* elements of empty collections.
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 0.1.0
|
||
* @category Collection
|
||
* @param {Array|Object} collection The collection to iterate over.
|
||
* @param {Function} [predicate=_.identity] The function invoked per iteration.
|
||
* @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
|
||
* @returns {boolean} Returns `true` if all elements pass the predicate check,
|
||
* else `false`.
|
||
* @example
|
||
*
|
||
* _.every([true, 1, null, 'yes'], Boolean);
|
||
* // => false
|
||
*
|
||
* var users = [
|
||
* { 'user': 'barney', 'age': 36, 'active': false },
|
||
* { 'user': 'fred', 'age': 40, 'active': false }
|
||
* ];
|
||
*
|
||
* // The `_.matches` iteratee shorthand.
|
||
* _.every(users, { 'user': 'barney', 'active': false });
|
||
* // => false
|
||
*
|
||
* // The `_.matchesProperty` iteratee shorthand.
|
||
* _.every(users, ['active', false]);
|
||
* // => true
|
||
*
|
||
* // The `_.property` iteratee shorthand.
|
||
* _.every(users, 'active');
|
||
* // => false
|
||
*/
|
||
function every(collection, predicate, guard) {
|
||
var func = isArray(collection) ? arrayEvery : baseEvery;
|
||
if (guard && isIterateeCall(collection, predicate, guard)) {
|
||
predicate = undefined;
|
||
}
|
||
return func(collection, getIteratee(predicate, 3));
|
||
}
|
||
|
||
/**
|
||
* Iterates over elements of `collection`, returning an array of all elements
|
||
* `predicate` returns truthy for. The predicate is invoked with three
|
||
* arguments: (value, index|key, collection).
|
||
*
|
||
* **Note:** Unlike `_.remove`, this method returns a new array.
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 0.1.0
|
||
* @category Collection
|
||
* @param {Array|Object} collection The collection to iterate over.
|
||
* @param {Function} [predicate=_.identity] The function invoked per iteration.
|
||
* @returns {Array} Returns the new filtered array.
|
||
* @see _.reject
|
||
* @example
|
||
*
|
||
* var users = [
|
||
* { 'user': 'barney', 'age': 36, 'active': true },
|
||
* { 'user': 'fred', 'age': 40, 'active': false }
|
||
* ];
|
||
*
|
||
* _.filter(users, function(o) { return !o.active; });
|
||
* // => objects for ['fred']
|
||
*
|
||
* // The `_.matches` iteratee shorthand.
|
||
* _.filter(users, { 'age': 36, 'active': true });
|
||
* // => objects for ['barney']
|
||
*
|
||
* // The `_.matchesProperty` iteratee shorthand.
|
||
* _.filter(users, ['active', false]);
|
||
* // => objects for ['fred']
|
||
*
|
||
* // The `_.property` iteratee shorthand.
|
||
* _.filter(users, 'active');
|
||
* // => objects for ['barney']
|
||
*/
|
||
function filter(collection, predicate) {
|
||
var func = isArray(collection) ? arrayFilter : baseFilter;
|
||
return func(collection, getIteratee(predicate, 3));
|
||
}
|
||
|
||
/**
|
||
* Iterates over elements of `collection`, returning the first element
|
||
* `predicate` returns truthy for. The predicate is invoked with three
|
||
* arguments: (value, index|key, collection).
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 0.1.0
|
||
* @category Collection
|
||
* @param {Array|Object} collection The collection to inspect.
|
||
* @param {Function} [predicate=_.identity] The function invoked per iteration.
|
||
* @param {number} [fromIndex=0] The index to search from.
|
||
* @returns {*} Returns the matched element, else `undefined`.
|
||
* @example
|
||
*
|
||
* var users = [
|
||
* { 'user': 'barney', 'age': 36, 'active': true },
|
||
* { 'user': 'fred', 'age': 40, 'active': false },
|
||
* { 'user': 'pebbles', 'age': 1, 'active': true }
|
||
* ];
|
||
*
|
||
* _.find(users, function(o) { return o.age < 40; });
|
||
* // => object for 'barney'
|
||
*
|
||
* // The `_.matches` iteratee shorthand.
|
||
* _.find(users, { 'age': 1, 'active': true });
|
||
* // => object for 'pebbles'
|
||
*
|
||
* // The `_.matchesProperty` iteratee shorthand.
|
||
* _.find(users, ['active', false]);
|
||
* // => object for 'fred'
|
||
*
|
||
* // The `_.property` iteratee shorthand.
|
||
* _.find(users, 'active');
|
||
* // => object for 'barney'
|
||
*/
|
||
var find = createFind(findIndex);
|
||
|
||
/**
|
||
* This method is like `_.find` except that it iterates over elements of
|
||
* `collection` from right to left.
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 2.0.0
|
||
* @category Collection
|
||
* @param {Array|Object} collection The collection to inspect.
|
||
* @param {Function} [predicate=_.identity] The function invoked per iteration.
|
||
* @param {number} [fromIndex=collection.length-1] The index to search from.
|
||
* @returns {*} Returns the matched element, else `undefined`.
|
||
* @example
|
||
*
|
||
* _.findLast([1, 2, 3, 4], function(n) {
|
||
* return n % 2 == 1;
|
||
* });
|
||
* // => 3
|
||
*/
|
||
var findLast = createFind(findLastIndex);
|
||
|
||
/**
|
||
* Creates a flattened array of values by running each element in `collection`
|
||
* thru `iteratee` and flattening the mapped results. The iteratee is invoked
|
||
* with three arguments: (value, index|key, collection).
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 4.0.0
|
||
* @category Collection
|
||
* @param {Array|Object} collection The collection to iterate over.
|
||
* @param {Function} [iteratee=_.identity] The function invoked per iteration.
|
||
* @returns {Array} Returns the new flattened array.
|
||
* @example
|
||
*
|
||
* function duplicate(n) {
|
||
* return [n, n];
|
||
* }
|
||
*
|
||
* _.flatMap([1, 2], duplicate);
|
||
* // => [1, 1, 2, 2]
|
||
*/
|
||
function flatMap(collection, iteratee) {
|
||
return baseFlatten(map(collection, iteratee), 1);
|
||
}
|
||
|
||
/**
|
||
* This method is like `_.flatMap` except that it recursively flattens the
|
||
* mapped results.
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 4.7.0
|
||
* @category Collection
|
||
* @param {Array|Object} collection The collection to iterate over.
|
||
* @param {Function} [iteratee=_.identity] The function invoked per iteration.
|
||
* @returns {Array} Returns the new flattened array.
|
||
* @example
|
||
*
|
||
* function duplicate(n) {
|
||
* return [[[n, n]]];
|
||
* }
|
||
*
|
||
* _.flatMapDeep([1, 2], duplicate);
|
||
* // => [1, 1, 2, 2]
|
||
*/
|
||
function flatMapDeep(collection, iteratee) {
|
||
return baseFlatten(map(collection, iteratee), INFINITY);
|
||
}
|
||
|
||
/**
|
||
* This method is like `_.flatMap` except that it recursively flattens the
|
||
* mapped results up to `depth` times.
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 4.7.0
|
||
* @category Collection
|
||
* @param {Array|Object} collection The collection to iterate over.
|
||
* @param {Function} [iteratee=_.identity] The function invoked per iteration.
|
||
* @param {number} [depth=1] The maximum recursion depth.
|
||
* @returns {Array} Returns the new flattened array.
|
||
* @example
|
||
*
|
||
* function duplicate(n) {
|
||
* return [[[n, n]]];
|
||
* }
|
||
*
|
||
* _.flatMapDepth([1, 2], duplicate, 2);
|
||
* // => [[1, 1], [2, 2]]
|
||
*/
|
||
function flatMapDepth(collection, iteratee, depth) {
|
||
depth = depth === undefined ? 1 : toInteger(depth);
|
||
return baseFlatten(map(collection, iteratee), depth);
|
||
}
|
||
|
||
/**
|
||
* Iterates over elements of `collection` and invokes `iteratee` for each element.
|
||
* The iteratee is invoked with three arguments: (value, index|key, collection).
|
||
* Iteratee functions may exit iteration early by explicitly returning `false`.
|
||
*
|
||
* **Note:** As with other "Collections" methods, objects with a "length"
|
||
* property are iterated like arrays. To avoid this behavior use `_.forIn`
|
||
* or `_.forOwn` for object iteration.
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 0.1.0
|
||
* @alias each
|
||
* @category Collection
|
||
* @param {Array|Object} collection The collection to iterate over.
|
||
* @param {Function} [iteratee=_.identity] The function invoked per iteration.
|
||
* @returns {Array|Object} Returns `collection`.
|
||
* @see _.forEachRight
|
||
* @example
|
||
*
|
||
* _.forEach([1, 2], function(value) {
|
||
* console.log(value);
|
||
* });
|
||
* // => Logs `1` then `2`.
|
||
*
|
||
* _.forEach({ 'a': 1, 'b': 2 }, function(value, key) {
|
||
* console.log(key);
|
||
* });
|
||
* // => Logs 'a' then 'b' (iteration order is not guaranteed).
|
||
*/
|
||
function forEach(collection, iteratee) {
|
||
var func = isArray(collection) ? arrayEach : baseEach;
|
||
return func(collection, getIteratee(iteratee, 3));
|
||
}
|
||
|
||
/**
|
||
* This method is like `_.forEach` except that it iterates over elements of
|
||
* `collection` from right to left.
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 2.0.0
|
||
* @alias eachRight
|
||
* @category Collection
|
||
* @param {Array|Object} collection The collection to iterate over.
|
||
* @param {Function} [iteratee=_.identity] The function invoked per iteration.
|
||
* @returns {Array|Object} Returns `collection`.
|
||
* @see _.forEach
|
||
* @example
|
||
*
|
||
* _.forEachRight([1, 2], function(value) {
|
||
* console.log(value);
|
||
* });
|
||
* // => Logs `2` then `1`.
|
||
*/
|
||
function forEachRight(collection, iteratee) {
|
||
var func = isArray(collection) ? arrayEachRight : baseEachRight;
|
||
return func(collection, getIteratee(iteratee, 3));
|
||
}
|
||
|
||
/**
|
||
* Creates an object composed of keys generated from the results of running
|
||
* each element of `collection` thru `iteratee`. The order of grouped values
|
||
* is determined by the order they occur in `collection`. The corresponding
|
||
* value of each key is an array of elements responsible for generating the
|
||
* key. The iteratee is invoked with one argument: (value).
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 0.1.0
|
||
* @category Collection
|
||
* @param {Array|Object} collection The collection to iterate over.
|
||
* @param {Function} [iteratee=_.identity] The iteratee to transform keys.
|
||
* @returns {Object} Returns the composed aggregate object.
|
||
* @example
|
||
*
|
||
* _.groupBy([6.1, 4.2, 6.3], Math.floor);
|
||
* // => { '4': [4.2], '6': [6.1, 6.3] }
|
||
*
|
||
* // The `_.property` iteratee shorthand.
|
||
* _.groupBy(['one', 'two', 'three'], 'length');
|
||
* // => { '3': ['one', 'two'], '5': ['three'] }
|
||
*/
|
||
var groupBy = createAggregator(function(result, value, key) {
|
||
if (hasOwnProperty.call(result, key)) {
|
||
result[key].push(value);
|
||
} else {
|
||
baseAssignValue(result, key, [value]);
|
||
}
|
||
});
|
||
|
||
/**
|
||
* Checks if `value` is in `collection`. If `collection` is a string, it's
|
||
* checked for a substring of `value`, otherwise
|
||
* [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
|
||
* is used for equality comparisons. If `fromIndex` is negative, it's used as
|
||
* the offset from the end of `collection`.
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 0.1.0
|
||
* @category Collection
|
||
* @param {Array|Object|string} collection The collection to inspect.
|
||
* @param {*} value The value to search for.
|
||
* @param {number} [fromIndex=0] The index to search from.
|
||
* @param- {Object} [guard] Enables use as an iteratee for methods like `_.reduce`.
|
||
* @returns {boolean} Returns `true` if `value` is found, else `false`.
|
||
* @example
|
||
*
|
||
* _.includes([1, 2, 3], 1);
|
||
* // => true
|
||
*
|
||
* _.includes([1, 2, 3], 1, 2);
|
||
* // => false
|
||
*
|
||
* _.includes({ 'a': 1, 'b': 2 }, 1);
|
||
* // => true
|
||
*
|
||
* _.includes('abcd', 'bc');
|
||
* // => true
|
||
*/
|
||
function includes(collection, value, fromIndex, guard) {
|
||
collection = isArrayLike(collection) ? collection : values(collection);
|
||
fromIndex = (fromIndex && !guard) ? toInteger(fromIndex) : 0;
|
||
|
||
var length = collection.length;
|
||
if (fromIndex < 0) {
|
||
fromIndex = nativeMax(length + fromIndex, 0);
|
||
}
|
||
return isString(collection)
|
||
? (fromIndex <= length && collection.indexOf(value, fromIndex) > -1)
|
||
: (!!length && baseIndexOf(collection, value, fromIndex) > -1);
|
||
}
|
||
|
||
/**
|
||
* Invokes the method at `path` of each element in `collection`, returning
|
||
* an array of the results of each invoked method. Any additional arguments
|
||
* are provided to each invoked method. If `path` is a function, it's invoked
|
||
* for, and `this` bound to, each element in `collection`.
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 4.0.0
|
||
* @category Collection
|
||
* @param {Array|Object} collection The collection to iterate over.
|
||
* @param {Array|Function|string} path The path of the method to invoke or
|
||
* the function invoked per iteration.
|
||
* @param {...*} [args] The arguments to invoke each method with.
|
||
* @returns {Array} Returns the array of results.
|
||
* @example
|
||
*
|
||
* _.invokeMap([[5, 1, 7], [3, 2, 1]], 'sort');
|
||
* // => [[1, 5, 7], [1, 2, 3]]
|
||
*
|
||
* _.invokeMap([123, 456], String.prototype.split, '');
|
||
* // => [['1', '2', '3'], ['4', '5', '6']]
|
||
*/
|
||
var invokeMap = baseRest(function(collection, path, args) {
|
||
var index = -1,
|
||
isFunc = typeof path == 'function',
|
||
result = isArrayLike(collection) ? Array(collection.length) : [];
|
||
|
||
baseEach(collection, function(value) {
|
||
result[++index] = isFunc ? apply(path, value, args) : baseInvoke(value, path, args);
|
||
});
|
||
return result;
|
||
});
|
||
|
||
/**
|
||
* Creates an object composed of keys generated from the results of running
|
||
* each element of `collection` thru `iteratee`. The corresponding value of
|
||
* each key is the last element responsible for generating the key. The
|
||
* iteratee is invoked with one argument: (value).
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 4.0.0
|
||
* @category Collection
|
||
* @param {Array|Object} collection The collection to iterate over.
|
||
* @param {Function} [iteratee=_.identity] The iteratee to transform keys.
|
||
* @returns {Object} Returns the composed aggregate object.
|
||
* @example
|
||
*
|
||
* var array = [
|
||
* { 'dir': 'left', 'code': 97 },
|
||
* { 'dir': 'right', 'code': 100 }
|
||
* ];
|
||
*
|
||
* _.keyBy(array, function(o) {
|
||
* return String.fromCharCode(o.code);
|
||
* });
|
||
* // => { 'a': { 'dir': 'left', 'code': 97 }, 'd': { 'dir': 'right', 'code': 100 } }
|
||
*
|
||
* _.keyBy(array, 'dir');
|
||
* // => { 'left': { 'dir': 'left', 'code': 97 }, 'right': { 'dir': 'right', 'code': 100 } }
|
||
*/
|
||
var keyBy = createAggregator(function(result, value, key) {
|
||
baseAssignValue(result, key, value);
|
||
});
|
||
|
||
/**
|
||
* Creates an array of values by running each element in `collection` thru
|
||
* `iteratee`. The iteratee is invoked with three arguments:
|
||
* (value, index|key, collection).
|
||
*
|
||
* Many lodash methods are guarded to work as iteratees for methods like
|
||
* `_.every`, `_.filter`, `_.map`, `_.mapValues`, `_.reject`, and `_.some`.
|
||
*
|
||
* The guarded methods are:
|
||
* `ary`, `chunk`, `curry`, `curryRight`, `drop`, `dropRight`, `every`,
|
||
* `fill`, `invert`, `parseInt`, `random`, `range`, `rangeRight`, `repeat`,
|
||
* `sampleSize`, `slice`, `some`, `sortBy`, `split`, `take`, `takeRight`,
|
||
* `template`, `trim`, `trimEnd`, `trimStart`, and `words`
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 0.1.0
|
||
* @category Collection
|
||
* @param {Array|Object} collection The collection to iterate over.
|
||
* @param {Function} [iteratee=_.identity] The function invoked per iteration.
|
||
* @returns {Array} Returns the new mapped array.
|
||
* @example
|
||
*
|
||
* function square(n) {
|
||
* return n * n;
|
||
* }
|
||
*
|
||
* _.map([4, 8], square);
|
||
* // => [16, 64]
|
||
*
|
||
* _.map({ 'a': 4, 'b': 8 }, square);
|
||
* // => [16, 64] (iteration order is not guaranteed)
|
||
*
|
||
* var users = [
|
||
* { 'user': 'barney' },
|
||
* { 'user': 'fred' }
|
||
* ];
|
||
*
|
||
* // The `_.property` iteratee shorthand.
|
||
* _.map(users, 'user');
|
||
* // => ['barney', 'fred']
|
||
*/
|
||
function map(collection, iteratee) {
|
||
var func = isArray(collection) ? arrayMap : baseMap;
|
||
return func(collection, getIteratee(iteratee, 3));
|
||
}
|
||
|
||
/**
|
||
* This method is like `_.sortBy` except that it allows specifying the sort
|
||
* orders of the iteratees to sort by. If `orders` is unspecified, all values
|
||
* are sorted in ascending order. Otherwise, specify an order of "desc" for
|
||
* descending or "asc" for ascending sort order of corresponding values.
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 4.0.0
|
||
* @category Collection
|
||
* @param {Array|Object} collection The collection to iterate over.
|
||
* @param {Array[]|Function[]|Object[]|string[]} [iteratees=[_.identity]]
|
||
* The iteratees to sort by.
|
||
* @param {string[]} [orders] The sort orders of `iteratees`.
|
||
* @param- {Object} [guard] Enables use as an iteratee for methods like `_.reduce`.
|
||
* @returns {Array} Returns the new sorted array.
|
||
* @example
|
||
*
|
||
* var users = [
|
||
* { 'user': 'fred', 'age': 48 },
|
||
* { 'user': 'barney', 'age': 34 },
|
||
* { 'user': 'fred', 'age': 40 },
|
||
* { 'user': 'barney', 'age': 36 }
|
||
* ];
|
||
*
|
||
* // Sort by `user` in ascending order and by `age` in descending order.
|
||
* _.orderBy(users, ['user', 'age'], ['asc', 'desc']);
|
||
* // => objects for [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 40]]
|
||
*/
|
||
function orderBy(collection, iteratees, orders, guard) {
|
||
if (collection == null) {
|
||
return [];
|
||
}
|
||
if (!isArray(iteratees)) {
|
||
iteratees = iteratees == null ? [] : [iteratees];
|
||
}
|
||
orders = guard ? undefined : orders;
|
||
if (!isArray(orders)) {
|
||
orders = orders == null ? [] : [orders];
|
||
}
|
||
return baseOrderBy(collection, iteratees, orders);
|
||
}
|
||
|
||
/**
|
||
* Creates an array of elements split into two groups, the first of which
|
||
* contains elements `predicate` returns truthy for, the second of which
|
||
* contains elements `predicate` returns falsey for. The predicate is
|
||
* invoked with one argument: (value).
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 3.0.0
|
||
* @category Collection
|
||
* @param {Array|Object} collection The collection to iterate over.
|
||
* @param {Function} [predicate=_.identity] The function invoked per iteration.
|
||
* @returns {Array} Returns the array of grouped elements.
|
||
* @example
|
||
*
|
||
* var users = [
|
||
* { 'user': 'barney', 'age': 36, 'active': false },
|
||
* { 'user': 'fred', 'age': 40, 'active': true },
|
||
* { 'user': 'pebbles', 'age': 1, 'active': false }
|
||
* ];
|
||
*
|
||
* _.partition(users, function(o) { return o.active; });
|
||
* // => objects for [['fred'], ['barney', 'pebbles']]
|
||
*
|
||
* // The `_.matches` iteratee shorthand.
|
||
* _.partition(users, { 'age': 1, 'active': false });
|
||
* // => objects for [['pebbles'], ['barney', 'fred']]
|
||
*
|
||
* // The `_.matchesProperty` iteratee shorthand.
|
||
* _.partition(users, ['active', false]);
|
||
* // => objects for [['barney', 'pebbles'], ['fred']]
|
||
*
|
||
* // The `_.property` iteratee shorthand.
|
||
* _.partition(users, 'active');
|
||
* // => objects for [['fred'], ['barney', 'pebbles']]
|
||
*/
|
||
var partition = createAggregator(function(result, value, key) {
|
||
result[key ? 0 : 1].push(value);
|
||
}, function() { return [[], []]; });
|
||
|
||
/**
|
||
* Reduces `collection` to a value which is the accumulated result of running
|
||
* each element in `collection` thru `iteratee`, where each successive
|
||
* invocation is supplied the return value of the previous. If `accumulator`
|
||
* is not given, the first element of `collection` is used as the initial
|
||
* value. The iteratee is invoked with four arguments:
|
||
* (accumulator, value, index|key, collection).
|
||
*
|
||
* Many lodash methods are guarded to work as iteratees for methods like
|
||
* `_.reduce`, `_.reduceRight`, and `_.transform`.
|
||
*
|
||
* The guarded methods are:
|
||
* `assign`, `defaults`, `defaultsDeep`, `includes`, `merge`, `orderBy`,
|
||
* and `sortBy`
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 0.1.0
|
||
* @category Collection
|
||
* @param {Array|Object} collection The collection to iterate over.
|
||
* @param {Function} [iteratee=_.identity] The function invoked per iteration.
|
||
* @param {*} [accumulator] The initial value.
|
||
* @returns {*} Returns the accumulated value.
|
||
* @see _.reduceRight
|
||
* @example
|
||
*
|
||
* _.reduce([1, 2], function(sum, n) {
|
||
* return sum + n;
|
||
* }, 0);
|
||
* // => 3
|
||
*
|
||
* _.reduce({ 'a': 1, 'b': 2, 'c': 1 }, function(result, value, key) {
|
||
* (result[value] || (result[value] = [])).push(key);
|
||
* return result;
|
||
* }, {});
|
||
* // => { '1': ['a', 'c'], '2': ['b'] } (iteration order is not guaranteed)
|
||
*/
|
||
function reduce(collection, iteratee, accumulator) {
|
||
var func = isArray(collection) ? arrayReduce : baseReduce,
|
||
initAccum = arguments.length < 3;
|
||
|
||
return func(collection, getIteratee(iteratee, 4), accumulator, initAccum, baseEach);
|
||
}
|
||
|
||
/**
|
||
* This method is like `_.reduce` except that it iterates over elements of
|
||
* `collection` from right to left.
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 0.1.0
|
||
* @category Collection
|
||
* @param {Array|Object} collection The collection to iterate over.
|
||
* @param {Function} [iteratee=_.identity] The function invoked per iteration.
|
||
* @param {*} [accumulator] The initial value.
|
||
* @returns {*} Returns the accumulated value.
|
||
* @see _.reduce
|
||
* @example
|
||
*
|
||
* var array = [[0, 1], [2, 3], [4, 5]];
|
||
*
|
||
* _.reduceRight(array, function(flattened, other) {
|
||
* return flattened.concat(other);
|
||
* }, []);
|
||
* // => [4, 5, 2, 3, 0, 1]
|
||
*/
|
||
function reduceRight(collection, iteratee, accumulator) {
|
||
var func = isArray(collection) ? arrayReduceRight : baseReduce,
|
||
initAccum = arguments.length < 3;
|
||
|
||
return func(collection, getIteratee(iteratee, 4), accumulator, initAccum, baseEachRight);
|
||
}
|
||
|
||
/**
|
||
* The opposite of `_.filter`; this method returns the elements of `collection`
|
||
* that `predicate` does **not** return truthy for.
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 0.1.0
|
||
* @category Collection
|
||
* @param {Array|Object} collection The collection to iterate over.
|
||
* @param {Function} [predicate=_.identity] The function invoked per iteration.
|
||
* @returns {Array} Returns the new filtered array.
|
||
* @see _.filter
|
||
* @example
|
||
*
|
||
* var users = [
|
||
* { 'user': 'barney', 'age': 36, 'active': false },
|
||
* { 'user': 'fred', 'age': 40, 'active': true }
|
||
* ];
|
||
*
|
||
* _.reject(users, function(o) { return !o.active; });
|
||
* // => objects for ['fred']
|
||
*
|
||
* // The `_.matches` iteratee shorthand.
|
||
* _.reject(users, { 'age': 40, 'active': true });
|
||
* // => objects for ['barney']
|
||
*
|
||
* // The `_.matchesProperty` iteratee shorthand.
|
||
* _.reject(users, ['active', false]);
|
||
* // => objects for ['fred']
|
||
*
|
||
* // The `_.property` iteratee shorthand.
|
||
* _.reject(users, 'active');
|
||
* // => objects for ['barney']
|
||
*/
|
||
function reject(collection, predicate) {
|
||
var func = isArray(collection) ? arrayFilter : baseFilter;
|
||
return func(collection, negate(getIteratee(predicate, 3)));
|
||
}
|
||
|
||
/**
|
||
* Gets a random element from `collection`.
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 2.0.0
|
||
* @category Collection
|
||
* @param {Array|Object} collection The collection to sample.
|
||
* @returns {*} Returns the random element.
|
||
* @example
|
||
*
|
||
* _.sample([1, 2, 3, 4]);
|
||
* // => 2
|
||
*/
|
||
function sample(collection) {
|
||
var func = isArray(collection) ? arraySample : baseSample;
|
||
return func(collection);
|
||
}
|
||
|
||
/**
|
||
* Gets `n` random elements at unique keys from `collection` up to the
|
||
* size of `collection`.
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 4.0.0
|
||
* @category Collection
|
||
* @param {Array|Object} collection The collection to sample.
|
||
* @param {number} [n=1] The number of elements to sample.
|
||
* @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
|
||
* @returns {Array} Returns the random elements.
|
||
* @example
|
||
*
|
||
* _.sampleSize([1, 2, 3], 2);
|
||
* // => [3, 1]
|
||
*
|
||
* _.sampleSize([1, 2, 3], 4);
|
||
* // => [2, 3, 1]
|
||
*/
|
||
function sampleSize(collection, n, guard) {
|
||
if ((guard ? isIterateeCall(collection, n, guard) : n === undefined)) {
|
||
n = 1;
|
||
} else {
|
||
n = toInteger(n);
|
||
}
|
||
var func = isArray(collection) ? arraySampleSize : baseSampleSize;
|
||
return func(collection, n);
|
||
}
|
||
|
||
/**
|
||
* Creates an array of shuffled values, using a version of the
|
||
* [Fisher-Yates shuffle](https://en.wikipedia.org/wiki/Fisher-Yates_shuffle).
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 0.1.0
|
||
* @category Collection
|
||
* @param {Array|Object} collection The collection to shuffle.
|
||
* @returns {Array} Returns the new shuffled array.
|
||
* @example
|
||
*
|
||
* _.shuffle([1, 2, 3, 4]);
|
||
* // => [4, 1, 3, 2]
|
||
*/
|
||
function shuffle(collection) {
|
||
var func = isArray(collection) ? arrayShuffle : baseShuffle;
|
||
return func(collection);
|
||
}
|
||
|
||
/**
|
||
* Gets the size of `collection` by returning its length for array-like
|
||
* values or the number of own enumerable string keyed properties for objects.
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 0.1.0
|
||
* @category Collection
|
||
* @param {Array|Object|string} collection The collection to inspect.
|
||
* @returns {number} Returns the collection size.
|
||
* @example
|
||
*
|
||
* _.size([1, 2, 3]);
|
||
* // => 3
|
||
*
|
||
* _.size({ 'a': 1, 'b': 2 });
|
||
* // => 2
|
||
*
|
||
* _.size('pebbles');
|
||
* // => 7
|
||
*/
|
||
function size(collection) {
|
||
if (collection == null) {
|
||
return 0;
|
||
}
|
||
if (isArrayLike(collection)) {
|
||
return isString(collection) ? stringSize(collection) : collection.length;
|
||
}
|
||
var tag = getTag(collection);
|
||
if (tag == mapTag || tag == setTag) {
|
||
return collection.size;
|
||
}
|
||
return baseKeys(collection).length;
|
||
}
|
||
|
||
/**
|
||
* Checks if `predicate` returns truthy for **any** element of `collection`.
|
||
* Iteration is stopped once `predicate` returns truthy. The predicate is
|
||
* invoked with three arguments: (value, index|key, collection).
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 0.1.0
|
||
* @category Collection
|
||
* @param {Array|Object} collection The collection to iterate over.
|
||
* @param {Function} [predicate=_.identity] The function invoked per iteration.
|
||
* @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
|
||
* @returns {boolean} Returns `true` if any element passes the predicate check,
|
||
* else `false`.
|
||
* @example
|
||
*
|
||
* _.some([null, 0, 'yes', false], Boolean);
|
||
* // => true
|
||
*
|
||
* var users = [
|
||
* { 'user': 'barney', 'active': true },
|
||
* { 'user': 'fred', 'active': false }
|
||
* ];
|
||
*
|
||
* // The `_.matches` iteratee shorthand.
|
||
* _.some(users, { 'user': 'barney', 'active': false });
|
||
* // => false
|
||
*
|
||
* // The `_.matchesProperty` iteratee shorthand.
|
||
* _.some(users, ['active', false]);
|
||
* // => true
|
||
*
|
||
* // The `_.property` iteratee shorthand.
|
||
* _.some(users, 'active');
|
||
* // => true
|
||
*/
|
||
function some(collection, predicate, guard) {
|
||
var func = isArray(collection) ? arraySome : baseSome;
|
||
if (guard && isIterateeCall(collection, predicate, guard)) {
|
||
predicate = undefined;
|
||
}
|
||
return func(collection, getIteratee(predicate, 3));
|
||
}
|
||
|
||
/**
|
||
* Creates an array of elements, sorted in ascending order by the results of
|
||
* running each element in a collection thru each iteratee. This method
|
||
* performs a stable sort, that is, it preserves the original sort order of
|
||
* equal elements. The iteratees are invoked with one argument: (value).
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 0.1.0
|
||
* @category Collection
|
||
* @param {Array|Object} collection The collection to iterate over.
|
||
* @param {...(Function|Function[])} [iteratees=[_.identity]]
|
||
* The iteratees to sort by.
|
||
* @returns {Array} Returns the new sorted array.
|
||
* @example
|
||
*
|
||
* var users = [
|
||
* { 'user': 'fred', 'age': 48 },
|
||
* { 'user': 'barney', 'age': 36 },
|
||
* { 'user': 'fred', 'age': 40 },
|
||
* { 'user': 'barney', 'age': 34 }
|
||
* ];
|
||
*
|
||
* _.sortBy(users, [function(o) { return o.user; }]);
|
||
* // => objects for [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 40]]
|
||
*
|
||
* _.sortBy(users, ['user', 'age']);
|
||
* // => objects for [['barney', 34], ['barney', 36], ['fred', 40], ['fred', 48]]
|
||
*/
|
||
var sortBy = baseRest(function(collection, iteratees) {
|
||
if (collection == null) {
|
||
return [];
|
||
}
|
||
var length = iteratees.length;
|
||
if (length > 1 && isIterateeCall(collection, iteratees[0], iteratees[1])) {
|
||
iteratees = [];
|
||
} else if (length > 2 && isIterateeCall(iteratees[0], iteratees[1], iteratees[2])) {
|
||
iteratees = [iteratees[0]];
|
||
}
|
||
return baseOrderBy(collection, baseFlatten(iteratees, 1), []);
|
||
});
|
||
|
||
/*------------------------------------------------------------------------*/
|
||
|
||
/**
|
||
* Gets the timestamp of the number of milliseconds that have elapsed since
|
||
* the Unix epoch (1 January 1970 00:00:00 UTC).
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 2.4.0
|
||
* @category Date
|
||
* @returns {number} Returns the timestamp.
|
||
* @example
|
||
*
|
||
* _.defer(function(stamp) {
|
||
* console.log(_.now() - stamp);
|
||
* }, _.now());
|
||
* // => Logs the number of milliseconds it took for the deferred invocation.
|
||
*/
|
||
var now = ctxNow || function() {
|
||
return root.Date.now();
|
||
};
|
||
|
||
/*------------------------------------------------------------------------*/
|
||
|
||
/**
|
||
* The opposite of `_.before`; this method creates a function that invokes
|
||
* `func` once it's called `n` or more times.
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 0.1.0
|
||
* @category Function
|
||
* @param {number} n The number of calls before `func` is invoked.
|
||
* @param {Function} func The function to restrict.
|
||
* @returns {Function} Returns the new restricted function.
|
||
* @example
|
||
*
|
||
* var saves = ['profile', 'settings'];
|
||
*
|
||
* var done = _.after(saves.length, function() {
|
||
* console.log('done saving!');
|
||
* });
|
||
*
|
||
* _.forEach(saves, function(type) {
|
||
* asyncSave({ 'type': type, 'complete': done });
|
||
* });
|
||
* // => Logs 'done saving!' after the two async saves have completed.
|
||
*/
|
||
function after(n, func) {
|
||
if (typeof func != 'function') {
|
||
throw new TypeError(FUNC_ERROR_TEXT);
|
||
}
|
||
n = toInteger(n);
|
||
return function() {
|
||
if (--n < 1) {
|
||
return func.apply(this, arguments);
|
||
}
|
||
};
|
||
}
|
||
|
||
/**
|
||
* Creates a function that invokes `func`, with up to `n` arguments,
|
||
* ignoring any additional arguments.
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 3.0.0
|
||
* @category Function
|
||
* @param {Function} func The function to cap arguments for.
|
||
* @param {number} [n=func.length] The arity cap.
|
||
* @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
|
||
* @returns {Function} Returns the new capped function.
|
||
* @example
|
||
*
|
||
* _.map(['6', '8', '10'], _.ary(parseInt, 1));
|
||
* // => [6, 8, 10]
|
||
*/
|
||
function ary(func, n, guard) {
|
||
n = guard ? undefined : n;
|
||
n = (func && n == null) ? func.length : n;
|
||
return createWrap(func, WRAP_ARY_FLAG, undefined, undefined, undefined, undefined, n);
|
||
}
|
||
|
||
/**
|
||
* Creates a function that invokes `func`, with the `this` binding and arguments
|
||
* of the created function, while it's called less than `n` times. Subsequent
|
||
* calls to the created function return the result of the last `func` invocation.
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 3.0.0
|
||
* @category Function
|
||
* @param {number} n The number of calls at which `func` is no longer invoked.
|
||
* @param {Function} func The function to restrict.
|
||
* @returns {Function} Returns the new restricted function.
|
||
* @example
|
||
*
|
||
* jQuery(element).on('click', _.before(5, addContactToList));
|
||
* // => Allows adding up to 4 contacts to the list.
|
||
*/
|
||
function before(n, func) {
|
||
var result;
|
||
if (typeof func != 'function') {
|
||
throw new TypeError(FUNC_ERROR_TEXT);
|
||
}
|
||
n = toInteger(n);
|
||
return function() {
|
||
if (--n > 0) {
|
||
result = func.apply(this, arguments);
|
||
}
|
||
if (n <= 1) {
|
||
func = undefined;
|
||
}
|
||
return result;
|
||
};
|
||
}
|
||
|
||
/**
|
||
* Creates a function that invokes `func` with the `this` binding of `thisArg`
|
||
* and `partials` prepended to the arguments it receives.
|
||
*
|
||
* The `_.bind.placeholder` value, which defaults to `_` in monolithic builds,
|
||
* may be used as a placeholder for partially applied arguments.
|
||
*
|
||
* **Note:** Unlike native `Function#bind`, this method doesn't set the "length"
|
||
* property of bound functions.
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 0.1.0
|
||
* @category Function
|
||
* @param {Function} func The function to bind.
|
||
* @param {*} thisArg The `this` binding of `func`.
|
||
* @param {...*} [partials] The arguments to be partially applied.
|
||
* @returns {Function} Returns the new bound function.
|
||
* @example
|
||
*
|
||
* function greet(greeting, punctuation) {
|
||
* return greeting + ' ' + this.user + punctuation;
|
||
* }
|
||
*
|
||
* var object = { 'user': 'fred' };
|
||
*
|
||
* var bound = _.bind(greet, object, 'hi');
|
||
* bound('!');
|
||
* // => 'hi fred!'
|
||
*
|
||
* // Bound with placeholders.
|
||
* var bound = _.bind(greet, object, _, '!');
|
||
* bound('hi');
|
||
* // => 'hi fred!'
|
||
*/
|
||
var bind = baseRest(function(func, thisArg, partials) {
|
||
var bitmask = WRAP_BIND_FLAG;
|
||
if (partials.length) {
|
||
var holders = replaceHolders(partials, getHolder(bind));
|
||
bitmask |= WRAP_PARTIAL_FLAG;
|
||
}
|
||
return createWrap(func, bitmask, thisArg, partials, holders);
|
||
});
|
||
|
||
/**
|
||
* Creates a function that invokes the method at `object[key]` with `partials`
|
||
* prepended to the arguments it receives.
|
||
*
|
||
* This method differs from `_.bind` by allowing bound functions to reference
|
||
* methods that may be redefined or don't yet exist. See
|
||
* [Peter Michaux's article](http://peter.michaux.ca/articles/lazy-function-definition-pattern)
|
||
* for more details.
|
||
*
|
||
* The `_.bindKey.placeholder` value, which defaults to `_` in monolithic
|
||
* builds, may be used as a placeholder for partially applied arguments.
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 0.10.0
|
||
* @category Function
|
||
* @param {Object} object The object to invoke the method on.
|
||
* @param {string} key The key of the method.
|
||
* @param {...*} [partials] The arguments to be partially applied.
|
||
* @returns {Function} Returns the new bound function.
|
||
* @example
|
||
*
|
||
* var object = {
|
||
* 'user': 'fred',
|
||
* 'greet': function(greeting, punctuation) {
|
||
* return greeting + ' ' + this.user + punctuation;
|
||
* }
|
||
* };
|
||
*
|
||
* var bound = _.bindKey(object, 'greet', 'hi');
|
||
* bound('!');
|
||
* // => 'hi fred!'
|
||
*
|
||
* object.greet = function(greeting, punctuation) {
|
||
* return greeting + 'ya ' + this.user + punctuation;
|
||
* };
|
||
*
|
||
* bound('!');
|
||
* // => 'hiya fred!'
|
||
*
|
||
* // Bound with placeholders.
|
||
* var bound = _.bindKey(object, 'greet', _, '!');
|
||
* bound('hi');
|
||
* // => 'hiya fred!'
|
||
*/
|
||
var bindKey = baseRest(function(object, key, partials) {
|
||
var bitmask = WRAP_BIND_FLAG | WRAP_BIND_KEY_FLAG;
|
||
if (partials.length) {
|
||
var holders = replaceHolders(partials, getHolder(bindKey));
|
||
bitmask |= WRAP_PARTIAL_FLAG;
|
||
}
|
||
return createWrap(key, bitmask, object, partials, holders);
|
||
});
|
||
|
||
/**
|
||
* Creates a function that accepts arguments of `func` and either invokes
|
||
* `func` returning its result, if at least `arity` number of arguments have
|
||
* been provided, or returns a function that accepts the remaining `func`
|
||
* arguments, and so on. The arity of `func` may be specified if `func.length`
|
||
* is not sufficient.
|
||
*
|
||
* The `_.curry.placeholder` value, which defaults to `_` in monolithic builds,
|
||
* may be used as a placeholder for provided arguments.
|
||
*
|
||
* **Note:** This method doesn't set the "length" property of curried functions.
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 2.0.0
|
||
* @category Function
|
||
* @param {Function} func The function to curry.
|
||
* @param {number} [arity=func.length] The arity of `func`.
|
||
* @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
|
||
* @returns {Function} Returns the new curried function.
|
||
* @example
|
||
*
|
||
* var abc = function(a, b, c) {
|
||
* return [a, b, c];
|
||
* };
|
||
*
|
||
* var curried = _.curry(abc);
|
||
*
|
||
* curried(1)(2)(3);
|
||
* // => [1, 2, 3]
|
||
*
|
||
* curried(1, 2)(3);
|
||
* // => [1, 2, 3]
|
||
*
|
||
* curried(1, 2, 3);
|
||
* // => [1, 2, 3]
|
||
*
|
||
* // Curried with placeholders.
|
||
* curried(1)(_, 3)(2);
|
||
* // => [1, 2, 3]
|
||
*/
|
||
function curry(func, arity, guard) {
|
||
arity = guard ? undefined : arity;
|
||
var result = createWrap(func, WRAP_CURRY_FLAG, undefined, undefined, undefined, undefined, undefined, arity);
|
||
result.placeholder = curry.placeholder;
|
||
return result;
|
||
}
|
||
|
||
/**
|
||
* This method is like `_.curry` except that arguments are applied to `func`
|
||
* in the manner of `_.partialRight` instead of `_.partial`.
|
||
*
|
||
* The `_.curryRight.placeholder` value, which defaults to `_` in monolithic
|
||
* builds, may be used as a placeholder for provided arguments.
|
||
*
|
||
* **Note:** This method doesn't set the "length" property of curried functions.
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 3.0.0
|
||
* @category Function
|
||
* @param {Function} func The function to curry.
|
||
* @param {number} [arity=func.length] The arity of `func`.
|
||
* @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
|
||
* @returns {Function} Returns the new curried function.
|
||
* @example
|
||
*
|
||
* var abc = function(a, b, c) {
|
||
* return [a, b, c];
|
||
* };
|
||
*
|
||
* var curried = _.curryRight(abc);
|
||
*
|
||
* curried(3)(2)(1);
|
||
* // => [1, 2, 3]
|
||
*
|
||
* curried(2, 3)(1);
|
||
* // => [1, 2, 3]
|
||
*
|
||
* curried(1, 2, 3);
|
||
* // => [1, 2, 3]
|
||
*
|
||
* // Curried with placeholders.
|
||
* curried(3)(1, _)(2);
|
||
* // => [1, 2, 3]
|
||
*/
|
||
function curryRight(func, arity, guard) {
|
||
arity = guard ? undefined : arity;
|
||
var result = createWrap(func, WRAP_CURRY_RIGHT_FLAG, undefined, undefined, undefined, undefined, undefined, arity);
|
||
result.placeholder = curryRight.placeholder;
|
||
return result;
|
||
}
|
||
|
||
/**
|
||
* Creates a debounced function that delays invoking `func` until after `wait`
|
||
* milliseconds have elapsed since the last time the debounced function was
|
||
* invoked. The debounced function comes with a `cancel` method to cancel
|
||
* delayed `func` invocations and a `flush` method to immediately invoke them.
|
||
* Provide `options` to indicate whether `func` should be invoked on the
|
||
* leading and/or trailing edge of the `wait` timeout. The `func` is invoked
|
||
* with the last arguments provided to the debounced function. Subsequent
|
||
* calls to the debounced function return the result of the last `func`
|
||
* invocation.
|
||
*
|
||
* **Note:** If `leading` and `trailing` options are `true`, `func` is
|
||
* invoked on the trailing edge of the timeout only if the debounced function
|
||
* is invoked more than once during the `wait` timeout.
|
||
*
|
||
* If `wait` is `0` and `leading` is `false`, `func` invocation is deferred
|
||
* until to the next tick, similar to `setTimeout` with a timeout of `0`.
|
||
*
|
||
* See [David Corbacho's article](https://css-tricks.com/debouncing-throttling-explained-examples/)
|
||
* for details over the differences between `_.debounce` and `_.throttle`.
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 0.1.0
|
||
* @category Function
|
||
* @param {Function} func The function to debounce.
|
||
* @param {number} [wait=0] The number of milliseconds to delay.
|
||
* @param {Object} [options={}] The options object.
|
||
* @param {boolean} [options.leading=false]
|
||
* Specify invoking on the leading edge of the timeout.
|
||
* @param {number} [options.maxWait]
|
||
* The maximum time `func` is allowed to be delayed before it's invoked.
|
||
* @param {boolean} [options.trailing=true]
|
||
* Specify invoking on the trailing edge of the timeout.
|
||
* @returns {Function} Returns the new debounced function.
|
||
* @example
|
||
*
|
||
* // Avoid costly calculations while the window size is in flux.
|
||
* jQuery(window).on('resize', _.debounce(calculateLayout, 150));
|
||
*
|
||
* // Invoke `sendMail` when clicked, debouncing subsequent calls.
|
||
* jQuery(element).on('click', _.debounce(sendMail, 300, {
|
||
* 'leading': true,
|
||
* 'trailing': false
|
||
* }));
|
||
*
|
||
* // Ensure `batchLog` is invoked once after 1 second of debounced calls.
|
||
* var debounced = _.debounce(batchLog, 250, { 'maxWait': 1000 });
|
||
* var source = new EventSource('/stream');
|
||
* jQuery(source).on('message', debounced);
|
||
*
|
||
* // Cancel the trailing debounced invocation.
|
||
* jQuery(window).on('popstate', debounced.cancel);
|
||
*/
|
||
function debounce(func, wait, options) {
|
||
var lastArgs,
|
||
lastThis,
|
||
maxWait,
|
||
result,
|
||
timerId,
|
||
lastCallTime,
|
||
lastInvokeTime = 0,
|
||
leading = false,
|
||
maxing = false,
|
||
trailing = true;
|
||
|
||
if (typeof func != 'function') {
|
||
throw new TypeError(FUNC_ERROR_TEXT);
|
||
}
|
||
wait = toNumber(wait) || 0;
|
||
if (isObject(options)) {
|
||
leading = !!options.leading;
|
||
maxing = 'maxWait' in options;
|
||
maxWait = maxing ? nativeMax(toNumber(options.maxWait) || 0, wait) : maxWait;
|
||
trailing = 'trailing' in options ? !!options.trailing : trailing;
|
||
}
|
||
|
||
function invokeFunc(time) {
|
||
var args = lastArgs,
|
||
thisArg = lastThis;
|
||
|
||
lastArgs = lastThis = undefined;
|
||
lastInvokeTime = time;
|
||
result = func.apply(thisArg, args);
|
||
return result;
|
||
}
|
||
|
||
function leadingEdge(time) {
|
||
// Reset any `maxWait` timer.
|
||
lastInvokeTime = time;
|
||
// Start the timer for the trailing edge.
|
||
timerId = setTimeout(timerExpired, wait);
|
||
// Invoke the leading edge.
|
||
return leading ? invokeFunc(time) : result;
|
||
}
|
||
|
||
function remainingWait(time) {
|
||
var timeSinceLastCall = time - lastCallTime,
|
||
timeSinceLastInvoke = time - lastInvokeTime,
|
||
result = wait - timeSinceLastCall;
|
||
|
||
return maxing ? nativeMin(result, maxWait - timeSinceLastInvoke) : result;
|
||
}
|
||
|
||
function shouldInvoke(time) {
|
||
var timeSinceLastCall = time - lastCallTime,
|
||
timeSinceLastInvoke = time - lastInvokeTime;
|
||
|
||
// Either this is the first call, activity has stopped and we're at the
|
||
// trailing edge, the system time has gone backwards and we're treating
|
||
// it as the trailing edge, or we've hit the `maxWait` limit.
|
||
return (lastCallTime === undefined || (timeSinceLastCall >= wait) ||
|
||
(timeSinceLastCall < 0) || (maxing && timeSinceLastInvoke >= maxWait));
|
||
}
|
||
|
||
function timerExpired() {
|
||
var time = now();
|
||
if (shouldInvoke(time)) {
|
||
return trailingEdge(time);
|
||
}
|
||
// Restart the timer.
|
||
timerId = setTimeout(timerExpired, remainingWait(time));
|
||
}
|
||
|
||
function trailingEdge(time) {
|
||
timerId = undefined;
|
||
|
||
// Only invoke if we have `lastArgs` which means `func` has been
|
||
// debounced at least once.
|
||
if (trailing && lastArgs) {
|
||
return invokeFunc(time);
|
||
}
|
||
lastArgs = lastThis = undefined;
|
||
return result;
|
||
}
|
||
|
||
function cancel() {
|
||
if (timerId !== undefined) {
|
||
clearTimeout(timerId);
|
||
}
|
||
lastInvokeTime = 0;
|
||
lastArgs = lastCallTime = lastThis = timerId = undefined;
|
||
}
|
||
|
||
function flush() {
|
||
return timerId === undefined ? result : trailingEdge(now());
|
||
}
|
||
|
||
function debounced() {
|
||
var time = now(),
|
||
isInvoking = shouldInvoke(time);
|
||
|
||
lastArgs = arguments;
|
||
lastThis = this;
|
||
lastCallTime = time;
|
||
|
||
if (isInvoking) {
|
||
if (timerId === undefined) {
|
||
return leadingEdge(lastCallTime);
|
||
}
|
||
if (maxing) {
|
||
// Handle invocations in a tight loop.
|
||
timerId = setTimeout(timerExpired, wait);
|
||
return invokeFunc(lastCallTime);
|
||
}
|
||
}
|
||
if (timerId === undefined) {
|
||
timerId = setTimeout(timerExpired, wait);
|
||
}
|
||
return result;
|
||
}
|
||
debounced.cancel = cancel;
|
||
debounced.flush = flush;
|
||
return debounced;
|
||
}
|
||
|
||
/**
|
||
* Defers invoking the `func` until the current call stack has cleared. Any
|
||
* additional arguments are provided to `func` when it's invoked.
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 0.1.0
|
||
* @category Function
|
||
* @param {Function} func The function to defer.
|
||
* @param {...*} [args] The arguments to invoke `func` with.
|
||
* @returns {number} Returns the timer id.
|
||
* @example
|
||
*
|
||
* _.defer(function(text) {
|
||
* console.log(text);
|
||
* }, 'deferred');
|
||
* // => Logs 'deferred' after one millisecond.
|
||
*/
|
||
var defer = baseRest(function(func, args) {
|
||
return baseDelay(func, 1, args);
|
||
});
|
||
|
||
/**
|
||
* Invokes `func` after `wait` milliseconds. Any additional arguments are
|
||
* provided to `func` when it's invoked.
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 0.1.0
|
||
* @category Function
|
||
* @param {Function} func The function to delay.
|
||
* @param {number} wait The number of milliseconds to delay invocation.
|
||
* @param {...*} [args] The arguments to invoke `func` with.
|
||
* @returns {number} Returns the timer id.
|
||
* @example
|
||
*
|
||
* _.delay(function(text) {
|
||
* console.log(text);
|
||
* }, 1000, 'later');
|
||
* // => Logs 'later' after one second.
|
||
*/
|
||
var delay = baseRest(function(func, wait, args) {
|
||
return baseDelay(func, toNumber(wait) || 0, args);
|
||
});
|
||
|
||
/**
|
||
* Creates a function that invokes `func` with arguments reversed.
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 4.0.0
|
||
* @category Function
|
||
* @param {Function} func The function to flip arguments for.
|
||
* @returns {Function} Returns the new flipped function.
|
||
* @example
|
||
*
|
||
* var flipped = _.flip(function() {
|
||
* return _.toArray(arguments);
|
||
* });
|
||
*
|
||
* flipped('a', 'b', 'c', 'd');
|
||
* // => ['d', 'c', 'b', 'a']
|
||
*/
|
||
function flip(func) {
|
||
return createWrap(func, WRAP_FLIP_FLAG);
|
||
}
|
||
|
||
/**
|
||
* Creates a function that memoizes the result of `func`. If `resolver` is
|
||
* provided, it determines the cache key for storing the result based on the
|
||
* arguments provided to the memoized function. By default, the first argument
|
||
* provided to the memoized function is used as the map cache key. The `func`
|
||
* is invoked with the `this` binding of the memoized function.
|
||
*
|
||
* **Note:** The cache is exposed as the `cache` property on the memoized
|
||
* function. Its creation may be customized by replacing the `_.memoize.Cache`
|
||
* constructor with one whose instances implement the
|
||
* [`Map`](http://ecma-international.org/ecma-262/7.0/#sec-properties-of-the-map-prototype-object)
|
||
* method interface of `clear`, `delete`, `get`, `has`, and `set`.
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 0.1.0
|
||
* @category Function
|
||
* @param {Function} func The function to have its output memoized.
|
||
* @param {Function} [resolver] The function to resolve the cache key.
|
||
* @returns {Function} Returns the new memoized function.
|
||
* @example
|
||
*
|
||
* var object = { 'a': 1, 'b': 2 };
|
||
* var other = { 'c': 3, 'd': 4 };
|
||
*
|
||
* var values = _.memoize(_.values);
|
||
* values(object);
|
||
* // => [1, 2]
|
||
*
|
||
* values(other);
|
||
* // => [3, 4]
|
||
*
|
||
* object.a = 2;
|
||
* values(object);
|
||
* // => [1, 2]
|
||
*
|
||
* // Modify the result cache.
|
||
* values.cache.set(object, ['a', 'b']);
|
||
* values(object);
|
||
* // => ['a', 'b']
|
||
*
|
||
* // Replace `_.memoize.Cache`.
|
||
* _.memoize.Cache = WeakMap;
|
||
*/
|
||
function memoize(func, resolver) {
|
||
if (typeof func != 'function' || (resolver != null && typeof resolver != 'function')) {
|
||
throw new TypeError(FUNC_ERROR_TEXT);
|
||
}
|
||
var memoized = function() {
|
||
var args = arguments,
|
||
key = resolver ? resolver.apply(this, args) : args[0],
|
||
cache = memoized.cache;
|
||
|
||
if (cache.has(key)) {
|
||
return cache.get(key);
|
||
}
|
||
var result = func.apply(this, args);
|
||
memoized.cache = cache.set(key, result) || cache;
|
||
return result;
|
||
};
|
||
memoized.cache = new (memoize.Cache || MapCache);
|
||
return memoized;
|
||
}
|
||
|
||
// Expose `MapCache`.
|
||
memoize.Cache = MapCache;
|
||
|
||
/**
|
||
* Creates a function that negates the result of the predicate `func`. The
|
||
* `func` predicate is invoked with the `this` binding and arguments of the
|
||
* created function.
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 3.0.0
|
||
* @category Function
|
||
* @param {Function} predicate The predicate to negate.
|
||
* @returns {Function} Returns the new negated function.
|
||
* @example
|
||
*
|
||
* function isEven(n) {
|
||
* return n % 2 == 0;
|
||
* }
|
||
*
|
||
* _.filter([1, 2, 3, 4, 5, 6], _.negate(isEven));
|
||
* // => [1, 3, 5]
|
||
*/
|
||
function negate(predicate) {
|
||
if (typeof predicate != 'function') {
|
||
throw new TypeError(FUNC_ERROR_TEXT);
|
||
}
|
||
return function() {
|
||
var args = arguments;
|
||
switch (args.length) {
|
||
case 0: return !predicate.call(this);
|
||
case 1: return !predicate.call(this, args[0]);
|
||
case 2: return !predicate.call(this, args[0], args[1]);
|
||
case 3: return !predicate.call(this, args[0], args[1], args[2]);
|
||
}
|
||
return !predicate.apply(this, args);
|
||
};
|
||
}
|
||
|
||
/**
|
||
* Creates a function that is restricted to invoking `func` once. Repeat calls
|
||
* to the function return the value of the first invocation. The `func` is
|
||
* invoked with the `this` binding and arguments of the created function.
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 0.1.0
|
||
* @category Function
|
||
* @param {Function} func The function to restrict.
|
||
* @returns {Function} Returns the new restricted function.
|
||
* @example
|
||
*
|
||
* var initialize = _.once(createApplication);
|
||
* initialize();
|
||
* initialize();
|
||
* // => `createApplication` is invoked once
|
||
*/
|
||
function once(func) {
|
||
return before(2, func);
|
||
}
|
||
|
||
/**
|
||
* Creates a function that invokes `func` with its arguments transformed.
|
||
*
|
||
* @static
|
||
* @since 4.0.0
|
||
* @memberOf _
|
||
* @category Function
|
||
* @param {Function} func The function to wrap.
|
||
* @param {...(Function|Function[])} [transforms=[_.identity]]
|
||
* The argument transforms.
|
||
* @returns {Function} Returns the new function.
|
||
* @example
|
||
*
|
||
* function doubled(n) {
|
||
* return n * 2;
|
||
* }
|
||
*
|
||
* function square(n) {
|
||
* return n * n;
|
||
* }
|
||
*
|
||
* var func = _.overArgs(function(x, y) {
|
||
* return [x, y];
|
||
* }, [square, doubled]);
|
||
*
|
||
* func(9, 3);
|
||
* // => [81, 6]
|
||
*
|
||
* func(10, 5);
|
||
* // => [100, 10]
|
||
*/
|
||
var overArgs = castRest(function(func, transforms) {
|
||
transforms = (transforms.length == 1 && isArray(transforms[0]))
|
||
? arrayMap(transforms[0], baseUnary(getIteratee()))
|
||
: arrayMap(baseFlatten(transforms, 1), baseUnary(getIteratee()));
|
||
|
||
var funcsLength = transforms.length;
|
||
return baseRest(function(args) {
|
||
var index = -1,
|
||
length = nativeMin(args.length, funcsLength);
|
||
|
||
while (++index < length) {
|
||
args[index] = transforms[index].call(this, args[index]);
|
||
}
|
||
return apply(func, this, args);
|
||
});
|
||
});
|
||
|
||
/**
|
||
* Creates a function that invokes `func` with `partials` prepended to the
|
||
* arguments it receives. This method is like `_.bind` except it does **not**
|
||
* alter the `this` binding.
|
||
*
|
||
* The `_.partial.placeholder` value, which defaults to `_` in monolithic
|
||
* builds, may be used as a placeholder for partially applied arguments.
|
||
*
|
||
* **Note:** This method doesn't set the "length" property of partially
|
||
* applied functions.
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 0.2.0
|
||
* @category Function
|
||
* @param {Function} func The function to partially apply arguments to.
|
||
* @param {...*} [partials] The arguments to be partially applied.
|
||
* @returns {Function} Returns the new partially applied function.
|
||
* @example
|
||
*
|
||
* function greet(greeting, name) {
|
||
* return greeting + ' ' + name;
|
||
* }
|
||
*
|
||
* var sayHelloTo = _.partial(greet, 'hello');
|
||
* sayHelloTo('fred');
|
||
* // => 'hello fred'
|
||
*
|
||
* // Partially applied with placeholders.
|
||
* var greetFred = _.partial(greet, _, 'fred');
|
||
* greetFred('hi');
|
||
* // => 'hi fred'
|
||
*/
|
||
var partial = baseRest(function(func, partials) {
|
||
var holders = replaceHolders(partials, getHolder(partial));
|
||
return createWrap(func, WRAP_PARTIAL_FLAG, undefined, partials, holders);
|
||
});
|
||
|
||
/**
|
||
* This method is like `_.partial` except that partially applied arguments
|
||
* are appended to the arguments it receives.
|
||
*
|
||
* The `_.partialRight.placeholder` value, which defaults to `_` in monolithic
|
||
* builds, may be used as a placeholder for partially applied arguments.
|
||
*
|
||
* **Note:** This method doesn't set the "length" property of partially
|
||
* applied functions.
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 1.0.0
|
||
* @category Function
|
||
* @param {Function} func The function to partially apply arguments to.
|
||
* @param {...*} [partials] The arguments to be partially applied.
|
||
* @returns {Function} Returns the new partially applied function.
|
||
* @example
|
||
*
|
||
* function greet(greeting, name) {
|
||
* return greeting + ' ' + name;
|
||
* }
|
||
*
|
||
* var greetFred = _.partialRight(greet, 'fred');
|
||
* greetFred('hi');
|
||
* // => 'hi fred'
|
||
*
|
||
* // Partially applied with placeholders.
|
||
* var sayHelloTo = _.partialRight(greet, 'hello', _);
|
||
* sayHelloTo('fred');
|
||
* // => 'hello fred'
|
||
*/
|
||
var partialRight = baseRest(function(func, partials) {
|
||
var holders = replaceHolders(partials, getHolder(partialRight));
|
||
return createWrap(func, WRAP_PARTIAL_RIGHT_FLAG, undefined, partials, holders);
|
||
});
|
||
|
||
/**
|
||
* Creates a function that invokes `func` with arguments arranged according
|
||
* to the specified `indexes` where the argument value at the first index is
|
||
* provided as the first argument, the argument value at the second index is
|
||
* provided as the second argument, and so on.
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 3.0.0
|
||
* @category Function
|
||
* @param {Function} func The function to rearrange arguments for.
|
||
* @param {...(number|number[])} indexes The arranged argument indexes.
|
||
* @returns {Function} Returns the new function.
|
||
* @example
|
||
*
|
||
* var rearged = _.rearg(function(a, b, c) {
|
||
* return [a, b, c];
|
||
* }, [2, 0, 1]);
|
||
*
|
||
* rearged('b', 'c', 'a')
|
||
* // => ['a', 'b', 'c']
|
||
*/
|
||
var rearg = flatRest(function(func, indexes) {
|
||
return createWrap(func, WRAP_REARG_FLAG, undefined, undefined, undefined, indexes);
|
||
});
|
||
|
||
/**
|
||
* Creates a function that invokes `func` with the `this` binding of the
|
||
* created function and arguments from `start` and beyond provided as
|
||
* an array.
|
||
*
|
||
* **Note:** This method is based on the
|
||
* [rest parameter](https://mdn.io/rest_parameters).
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 4.0.0
|
||
* @category Function
|
||
* @param {Function} func The function to apply a rest parameter to.
|
||
* @param {number} [start=func.length-1] The start position of the rest parameter.
|
||
* @returns {Function} Returns the new function.
|
||
* @example
|
||
*
|
||
* var say = _.rest(function(what, names) {
|
||
* return what + ' ' + _.initial(names).join(', ') +
|
||
* (_.size(names) > 1 ? ', & ' : '') + _.last(names);
|
||
* });
|
||
*
|
||
* say('hello', 'fred', 'barney', 'pebbles');
|
||
* // => 'hello fred, barney, & pebbles'
|
||
*/
|
||
function rest(func, start) {
|
||
if (typeof func != 'function') {
|
||
throw new TypeError(FUNC_ERROR_TEXT);
|
||
}
|
||
start = start === undefined ? start : toInteger(start);
|
||
return baseRest(func, start);
|
||
}
|
||
|
||
/**
|
||
* Creates a function that invokes `func` with the `this` binding of the
|
||
* create function and an array of arguments much like
|
||
* [`Function#apply`](http://www.ecma-international.org/ecma-262/7.0/#sec-function.prototype.apply).
|
||
*
|
||
* **Note:** This method is based on the
|
||
* [spread operator](https://mdn.io/spread_operator).
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 3.2.0
|
||
* @category Function
|
||
* @param {Function} func The function to spread arguments over.
|
||
* @param {number} [start=0] The start position of the spread.
|
||
* @returns {Function} Returns the new function.
|
||
* @example
|
||
*
|
||
* var say = _.spread(function(who, what) {
|
||
* return who + ' says ' + what;
|
||
* });
|
||
*
|
||
* say(['fred', 'hello']);
|
||
* // => 'fred says hello'
|
||
*
|
||
* var numbers = Promise.all([
|
||
* Promise.resolve(40),
|
||
* Promise.resolve(36)
|
||
* ]);
|
||
*
|
||
* numbers.then(_.spread(function(x, y) {
|
||
* return x + y;
|
||
* }));
|
||
* // => a Promise of 76
|
||
*/
|
||
function spread(func, start) {
|
||
if (typeof func != 'function') {
|
||
throw new TypeError(FUNC_ERROR_TEXT);
|
||
}
|
||
start = start == null ? 0 : nativeMax(toInteger(start), 0);
|
||
return baseRest(function(args) {
|
||
var array = args[start],
|
||
otherArgs = castSlice(args, 0, start);
|
||
|
||
if (array) {
|
||
arrayPush(otherArgs, array);
|
||
}
|
||
return apply(func, this, otherArgs);
|
||
});
|
||
}
|
||
|
||
/**
|
||
* Creates a throttled function that only invokes `func` at most once per
|
||
* every `wait` milliseconds. The throttled function comes with a `cancel`
|
||
* method to cancel delayed `func` invocations and a `flush` method to
|
||
* immediately invoke them. Provide `options` to indicate whether `func`
|
||
* should be invoked on the leading and/or trailing edge of the `wait`
|
||
* timeout. The `func` is invoked with the last arguments provided to the
|
||
* throttled function. Subsequent calls to the throttled function return the
|
||
* result of the last `func` invocation.
|
||
*
|
||
* **Note:** If `leading` and `trailing` options are `true`, `func` is
|
||
* invoked on the trailing edge of the timeout only if the throttled function
|
||
* is invoked more than once during the `wait` timeout.
|
||
*
|
||
* If `wait` is `0` and `leading` is `false`, `func` invocation is deferred
|
||
* until to the next tick, similar to `setTimeout` with a timeout of `0`.
|
||
*
|
||
* See [David Corbacho's article](https://css-tricks.com/debouncing-throttling-explained-examples/)
|
||
* for details over the differences between `_.throttle` and `_.debounce`.
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 0.1.0
|
||
* @category Function
|
||
* @param {Function} func The function to throttle.
|
||
* @param {number} [wait=0] The number of milliseconds to throttle invocations to.
|
||
* @param {Object} [options={}] The options object.
|
||
* @param {boolean} [options.leading=true]
|
||
* Specify invoking on the leading edge of the timeout.
|
||
* @param {boolean} [options.trailing=true]
|
||
* Specify invoking on the trailing edge of the timeout.
|
||
* @returns {Function} Returns the new throttled function.
|
||
* @example
|
||
*
|
||
* // Avoid excessively updating the position while scrolling.
|
||
* jQuery(window).on('scroll', _.throttle(updatePosition, 100));
|
||
*
|
||
* // Invoke `renewToken` when the click event is fired, but not more than once every 5 minutes.
|
||
* var throttled = _.throttle(renewToken, 300000, { 'trailing': false });
|
||
* jQuery(element).on('click', throttled);
|
||
*
|
||
* // Cancel the trailing throttled invocation.
|
||
* jQuery(window).on('popstate', throttled.cancel);
|
||
*/
|
||
function throttle(func, wait, options) {
|
||
var leading = true,
|
||
trailing = true;
|
||
|
||
if (typeof func != 'function') {
|
||
throw new TypeError(FUNC_ERROR_TEXT);
|
||
}
|
||
if (isObject(options)) {
|
||
leading = 'leading' in options ? !!options.leading : leading;
|
||
trailing = 'trailing' in options ? !!options.trailing : trailing;
|
||
}
|
||
return debounce(func, wait, {
|
||
'leading': leading,
|
||
'maxWait': wait,
|
||
'trailing': trailing
|
||
});
|
||
}
|
||
|
||
/**
|
||
* Creates a function that accepts up to one argument, ignoring any
|
||
* additional arguments.
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 4.0.0
|
||
* @category Function
|
||
* @param {Function} func The function to cap arguments for.
|
||
* @returns {Function} Returns the new capped function.
|
||
* @example
|
||
*
|
||
* _.map(['6', '8', '10'], _.unary(parseInt));
|
||
* // => [6, 8, 10]
|
||
*/
|
||
function unary(func) {
|
||
return ary(func, 1);
|
||
}
|
||
|
||
/**
|
||
* Creates a function that provides `value` to `wrapper` as its first
|
||
* argument. Any additional arguments provided to the function are appended
|
||
* to those provided to the `wrapper`. The wrapper is invoked with the `this`
|
||
* binding of the created function.
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 0.1.0
|
||
* @category Function
|
||
* @param {*} value The value to wrap.
|
||
* @param {Function} [wrapper=identity] The wrapper function.
|
||
* @returns {Function} Returns the new function.
|
||
* @example
|
||
*
|
||
* var p = _.wrap(_.escape, function(func, text) {
|
||
* return '<p>' + func(text) + '</p>';
|
||
* });
|
||
*
|
||
* p('fred, barney, & pebbles');
|
||
* // => '<p>fred, barney, & pebbles</p>'
|
||
*/
|
||
function wrap(value, wrapper) {
|
||
return partial(castFunction(wrapper), value);
|
||
}
|
||
|
||
/*------------------------------------------------------------------------*/
|
||
|
||
/**
|
||
* Casts `value` as an array if it's not one.
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 4.4.0
|
||
* @category Lang
|
||
* @param {*} value The value to inspect.
|
||
* @returns {Array} Returns the cast array.
|
||
* @example
|
||
*
|
||
* _.castArray(1);
|
||
* // => [1]
|
||
*
|
||
* _.castArray({ 'a': 1 });
|
||
* // => [{ 'a': 1 }]
|
||
*
|
||
* _.castArray('abc');
|
||
* // => ['abc']
|
||
*
|
||
* _.castArray(null);
|
||
* // => [null]
|
||
*
|
||
* _.castArray(undefined);
|
||
* // => [undefined]
|
||
*
|
||
* _.castArray();
|
||
* // => []
|
||
*
|
||
* var array = [1, 2, 3];
|
||
* console.log(_.castArray(array) === array);
|
||
* // => true
|
||
*/
|
||
function castArray() {
|
||
if (!arguments.length) {
|
||
return [];
|
||
}
|
||
var value = arguments[0];
|
||
return isArray(value) ? value : [value];
|
||
}
|
||
|
||
/**
|
||
* Creates a shallow clone of `value`.
|
||
*
|
||
* **Note:** This method is loosely based on the
|
||
* [structured clone algorithm](https://mdn.io/Structured_clone_algorithm)
|
||
* and supports cloning arrays, array buffers, booleans, date objects, maps,
|
||
* numbers, `Object` objects, regexes, sets, strings, symbols, and typed
|
||
* arrays. The own enumerable properties of `arguments` objects are cloned
|
||
* as plain objects. An empty object is returned for uncloneable values such
|
||
* as error objects, functions, DOM nodes, and WeakMaps.
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 0.1.0
|
||
* @category Lang
|
||
* @param {*} value The value to clone.
|
||
* @returns {*} Returns the cloned value.
|
||
* @see _.cloneDeep
|
||
* @example
|
||
*
|
||
* var objects = [{ 'a': 1 }, { 'b': 2 }];
|
||
*
|
||
* var shallow = _.clone(objects);
|
||
* console.log(shallow[0] === objects[0]);
|
||
* // => true
|
||
*/
|
||
function clone(value) {
|
||
return baseClone(value, CLONE_SYMBOLS_FLAG);
|
||
}
|
||
|
||
/**
|
||
* This method is like `_.clone` except that it accepts `customizer` which
|
||
* is invoked to produce the cloned value. If `customizer` returns `undefined`,
|
||
* cloning is handled by the method instead. The `customizer` is invoked with
|
||
* up to four arguments; (value [, index|key, object, stack]).
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 4.0.0
|
||
* @category Lang
|
||
* @param {*} value The value to clone.
|
||
* @param {Function} [customizer] The function to customize cloning.
|
||
* @returns {*} Returns the cloned value.
|
||
* @see _.cloneDeepWith
|
||
* @example
|
||
*
|
||
* function customizer(value) {
|
||
* if (_.isElement(value)) {
|
||
* return value.cloneNode(false);
|
||
* }
|
||
* }
|
||
*
|
||
* var el = _.cloneWith(document.body, customizer);
|
||
*
|
||
* console.log(el === document.body);
|
||
* // => false
|
||
* console.log(el.nodeName);
|
||
* // => 'BODY'
|
||
* console.log(el.childNodes.length);
|
||
* // => 0
|
||
*/
|
||
function cloneWith(value, customizer) {
|
||
customizer = typeof customizer == 'function' ? customizer : undefined;
|
||
return baseClone(value, CLONE_SYMBOLS_FLAG, customizer);
|
||
}
|
||
|
||
/**
|
||
* This method is like `_.clone` except that it recursively clones `value`.
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 1.0.0
|
||
* @category Lang
|
||
* @param {*} value The value to recursively clone.
|
||
* @returns {*} Returns the deep cloned value.
|
||
* @see _.clone
|
||
* @example
|
||
*
|
||
* var objects = [{ 'a': 1 }, { 'b': 2 }];
|
||
*
|
||
* var deep = _.cloneDeep(objects);
|
||
* console.log(deep[0] === objects[0]);
|
||
* // => false
|
||
*/
|
||
function cloneDeep(value) {
|
||
return baseClone(value, CLONE_DEEP_FLAG | CLONE_SYMBOLS_FLAG);
|
||
}
|
||
|
||
/**
|
||
* This method is like `_.cloneWith` except that it recursively clones `value`.
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 4.0.0
|
||
* @category Lang
|
||
* @param {*} value The value to recursively clone.
|
||
* @param {Function} [customizer] The function to customize cloning.
|
||
* @returns {*} Returns the deep cloned value.
|
||
* @see _.cloneWith
|
||
* @example
|
||
*
|
||
* function customizer(value) {
|
||
* if (_.isElement(value)) {
|
||
* return value.cloneNode(true);
|
||
* }
|
||
* }
|
||
*
|
||
* var el = _.cloneDeepWith(document.body, customizer);
|
||
*
|
||
* console.log(el === document.body);
|
||
* // => false
|
||
* console.log(el.nodeName);
|
||
* // => 'BODY'
|
||
* console.log(el.childNodes.length);
|
||
* // => 20
|
||
*/
|
||
function cloneDeepWith(value, customizer) {
|
||
customizer = typeof customizer == 'function' ? customizer : undefined;
|
||
return baseClone(value, CLONE_DEEP_FLAG | CLONE_SYMBOLS_FLAG, customizer);
|
||
}
|
||
|
||
/**
|
||
* Checks if `object` conforms to `source` by invoking the predicate
|
||
* properties of `source` with the corresponding property values of `object`.
|
||
*
|
||
* **Note:** This method is equivalent to `_.conforms` when `source` is
|
||
* partially applied.
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 4.14.0
|
||
* @category Lang
|
||
* @param {Object} object The object to inspect.
|
||
* @param {Object} source The object of property predicates to conform to.
|
||
* @returns {boolean} Returns `true` if `object` conforms, else `false`.
|
||
* @example
|
||
*
|
||
* var object = { 'a': 1, 'b': 2 };
|
||
*
|
||
* _.conformsTo(object, { 'b': function(n) { return n > 1; } });
|
||
* // => true
|
||
*
|
||
* _.conformsTo(object, { 'b': function(n) { return n > 2; } });
|
||
* // => false
|
||
*/
|
||
function conformsTo(object, source) {
|
||
return source == null || baseConformsTo(object, source, keys(source));
|
||
}
|
||
|
||
/**
|
||
* Performs a
|
||
* [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
|
||
* comparison between two values to determine if they are equivalent.
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 4.0.0
|
||
* @category Lang
|
||
* @param {*} value The value to compare.
|
||
* @param {*} other The other value to compare.
|
||
* @returns {boolean} Returns `true` if the values are equivalent, else `false`.
|
||
* @example
|
||
*
|
||
* var object = { 'a': 1 };
|
||
* var other = { 'a': 1 };
|
||
*
|
||
* _.eq(object, object);
|
||
* // => true
|
||
*
|
||
* _.eq(object, other);
|
||
* // => false
|
||
*
|
||
* _.eq('a', 'a');
|
||
* // => true
|
||
*
|
||
* _.eq('a', Object('a'));
|
||
* // => false
|
||
*
|
||
* _.eq(NaN, NaN);
|
||
* // => true
|
||
*/
|
||
function eq(value, other) {
|
||
return value === other || (value !== value && other !== other);
|
||
}
|
||
|
||
/**
|
||
* Checks if `value` is greater than `other`.
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 3.9.0
|
||
* @category Lang
|
||
* @param {*} value The value to compare.
|
||
* @param {*} other The other value to compare.
|
||
* @returns {boolean} Returns `true` if `value` is greater than `other`,
|
||
* else `false`.
|
||
* @see _.lt
|
||
* @example
|
||
*
|
||
* _.gt(3, 1);
|
||
* // => true
|
||
*
|
||
* _.gt(3, 3);
|
||
* // => false
|
||
*
|
||
* _.gt(1, 3);
|
||
* // => false
|
||
*/
|
||
var gt = createRelationalOperation(baseGt);
|
||
|
||
/**
|
||
* Checks if `value` is greater than or equal to `other`.
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 3.9.0
|
||
* @category Lang
|
||
* @param {*} value The value to compare.
|
||
* @param {*} other The other value to compare.
|
||
* @returns {boolean} Returns `true` if `value` is greater than or equal to
|
||
* `other`, else `false`.
|
||
* @see _.lte
|
||
* @example
|
||
*
|
||
* _.gte(3, 1);
|
||
* // => true
|
||
*
|
||
* _.gte(3, 3);
|
||
* // => true
|
||
*
|
||
* _.gte(1, 3);
|
||
* // => false
|
||
*/
|
||
var gte = createRelationalOperation(function(value, other) {
|
||
return value >= other;
|
||
});
|
||
|
||
/**
|
||
* Checks if `value` is likely an `arguments` object.
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 0.1.0
|
||
* @category Lang
|
||
* @param {*} value The value to check.
|
||
* @returns {boolean} Returns `true` if `value` is an `arguments` object,
|
||
* else `false`.
|
||
* @example
|
||
*
|
||
* _.isArguments(function() { return arguments; }());
|
||
* // => true
|
||
*
|
||
* _.isArguments([1, 2, 3]);
|
||
* // => false
|
||
*/
|
||
var isArguments = baseIsArguments(function() { return arguments; }()) ? baseIsArguments : function(value) {
|
||
return isObjectLike(value) && hasOwnProperty.call(value, 'callee') &&
|
||
!propertyIsEnumerable.call(value, 'callee');
|
||
};
|
||
|
||
/**
|
||
* Checks if `value` is classified as an `Array` object.
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 0.1.0
|
||
* @category Lang
|
||
* @param {*} value The value to check.
|
||
* @returns {boolean} Returns `true` if `value` is an array, else `false`.
|
||
* @example
|
||
*
|
||
* _.isArray([1, 2, 3]);
|
||
* // => true
|
||
*
|
||
* _.isArray(document.body.children);
|
||
* // => false
|
||
*
|
||
* _.isArray('abc');
|
||
* // => false
|
||
*
|
||
* _.isArray(_.noop);
|
||
* // => false
|
||
*/
|
||
var isArray = Array.isArray;
|
||
|
||
/**
|
||
* Checks if `value` is classified as an `ArrayBuffer` object.
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 4.3.0
|
||
* @category Lang
|
||
* @param {*} value The value to check.
|
||
* @returns {boolean} Returns `true` if `value` is an array buffer, else `false`.
|
||
* @example
|
||
*
|
||
* _.isArrayBuffer(new ArrayBuffer(2));
|
||
* // => true
|
||
*
|
||
* _.isArrayBuffer(new Array(2));
|
||
* // => false
|
||
*/
|
||
var isArrayBuffer = nodeIsArrayBuffer ? baseUnary(nodeIsArrayBuffer) : baseIsArrayBuffer;
|
||
|
||
/**
|
||
* Checks if `value` is array-like. A value is considered array-like if it's
|
||
* not a function and has a `value.length` that's an integer greater than or
|
||
* equal to `0` and less than or equal to `Number.MAX_SAFE_INTEGER`.
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 4.0.0
|
||
* @category Lang
|
||
* @param {*} value The value to check.
|
||
* @returns {boolean} Returns `true` if `value` is array-like, else `false`.
|
||
* @example
|
||
*
|
||
* _.isArrayLike([1, 2, 3]);
|
||
* // => true
|
||
*
|
||
* _.isArrayLike(document.body.children);
|
||
* // => true
|
||
*
|
||
* _.isArrayLike('abc');
|
||
* // => true
|
||
*
|
||
* _.isArrayLike(_.noop);
|
||
* // => false
|
||
*/
|
||
function isArrayLike(value) {
|
||
return value != null && isLength(value.length) && !isFunction(value);
|
||
}
|
||
|
||
/**
|
||
* This method is like `_.isArrayLike` except that it also checks if `value`
|
||
* is an object.
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 4.0.0
|
||
* @category Lang
|
||
* @param {*} value The value to check.
|
||
* @returns {boolean} Returns `true` if `value` is an array-like object,
|
||
* else `false`.
|
||
* @example
|
||
*
|
||
* _.isArrayLikeObject([1, 2, 3]);
|
||
* // => true
|
||
*
|
||
* _.isArrayLikeObject(document.body.children);
|
||
* // => true
|
||
*
|
||
* _.isArrayLikeObject('abc');
|
||
* // => false
|
||
*
|
||
* _.isArrayLikeObject(_.noop);
|
||
* // => false
|
||
*/
|
||
function isArrayLikeObject(value) {
|
||
return isObjectLike(value) && isArrayLike(value);
|
||
}
|
||
|
||
/**
|
||
* Checks if `value` is classified as a boolean primitive or object.
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 0.1.0
|
||
* @category Lang
|
||
* @param {*} value The value to check.
|
||
* @returns {boolean} Returns `true` if `value` is a boolean, else `false`.
|
||
* @example
|
||
*
|
||
* _.isBoolean(false);
|
||
* // => true
|
||
*
|
||
* _.isBoolean(null);
|
||
* // => false
|
||
*/
|
||
function isBoolean(value) {
|
||
return value === true || value === false ||
|
||
(isObjectLike(value) && baseGetTag(value) == boolTag);
|
||
}
|
||
|
||
/**
|
||
* Checks if `value` is a buffer.
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 4.3.0
|
||
* @category Lang
|
||
* @param {*} value The value to check.
|
||
* @returns {boolean} Returns `true` if `value` is a buffer, else `false`.
|
||
* @example
|
||
*
|
||
* _.isBuffer(new Buffer(2));
|
||
* // => true
|
||
*
|
||
* _.isBuffer(new Uint8Array(2));
|
||
* // => false
|
||
*/
|
||
var isBuffer = nativeIsBuffer || stubFalse;
|
||
|
||
/**
|
||
* Checks if `value` is classified as a `Date` object.
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 0.1.0
|
||
* @category Lang
|
||
* @param {*} value The value to check.
|
||
* @returns {boolean} Returns `true` if `value` is a date object, else `false`.
|
||
* @example
|
||
*
|
||
* _.isDate(new Date);
|
||
* // => true
|
||
*
|
||
* _.isDate('Mon April 23 2012');
|
||
* // => false
|
||
*/
|
||
var isDate = nodeIsDate ? baseUnary(nodeIsDate) : baseIsDate;
|
||
|
||
/**
|
||
* Checks if `value` is likely a DOM element.
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 0.1.0
|
||
* @category Lang
|
||
* @param {*} value The value to check.
|
||
* @returns {boolean} Returns `true` if `value` is a DOM element, else `false`.
|
||
* @example
|
||
*
|
||
* _.isElement(document.body);
|
||
* // => true
|
||
*
|
||
* _.isElement('<body>');
|
||
* // => false
|
||
*/
|
||
function isElement(value) {
|
||
return isObjectLike(value) && value.nodeType === 1 && !isPlainObject(value);
|
||
}
|
||
|
||
/**
|
||
* Checks if `value` is an empty object, collection, map, or set.
|
||
*
|
||
* Objects are considered empty if they have no own enumerable string keyed
|
||
* properties.
|
||
*
|
||
* Array-like values such as `arguments` objects, arrays, buffers, strings, or
|
||
* jQuery-like collections are considered empty if they have a `length` of `0`.
|
||
* Similarly, maps and sets are considered empty if they have a `size` of `0`.
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 0.1.0
|
||
* @category Lang
|
||
* @param {*} value The value to check.
|
||
* @returns {boolean} Returns `true` if `value` is empty, else `false`.
|
||
* @example
|
||
*
|
||
* _.isEmpty(null);
|
||
* // => true
|
||
*
|
||
* _.isEmpty(true);
|
||
* // => true
|
||
*
|
||
* _.isEmpty(1);
|
||
* // => true
|
||
*
|
||
* _.isEmpty([1, 2, 3]);
|
||
* // => false
|
||
*
|
||
* _.isEmpty({ 'a': 1 });
|
||
* // => false
|
||
*/
|
||
function isEmpty(value) {
|
||
if (value == null) {
|
||
return true;
|
||
}
|
||
if (isArrayLike(value) &&
|
||
(isArray(value) || typeof value == 'string' || typeof value.splice == 'function' ||
|
||
isBuffer(value) || isTypedArray(value) || isArguments(value))) {
|
||
return !value.length;
|
||
}
|
||
var tag = getTag(value);
|
||
if (tag == mapTag || tag == setTag) {
|
||
return !value.size;
|
||
}
|
||
if (isPrototype(value)) {
|
||
return !baseKeys(value).length;
|
||
}
|
||
for (var key in value) {
|
||
if (hasOwnProperty.call(value, key)) {
|
||
return false;
|
||
}
|
||
}
|
||
return true;
|
||
}
|
||
|
||
/**
|
||
* Performs a deep comparison between two values to determine if they are
|
||
* equivalent.
|
||
*
|
||
* **Note:** This method supports comparing arrays, array buffers, booleans,
|
||
* date objects, error objects, maps, numbers, `Object` objects, regexes,
|
||
* sets, strings, symbols, and typed arrays. `Object` objects are compared
|
||
* by their own, not inherited, enumerable properties. Functions and DOM
|
||
* nodes are compared by strict equality, i.e. `===`.
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 0.1.0
|
||
* @category Lang
|
||
* @param {*} value The value to compare.
|
||
* @param {*} other The other value to compare.
|
||
* @returns {boolean} Returns `true` if the values are equivalent, else `false`.
|
||
* @example
|
||
*
|
||
* var object = { 'a': 1 };
|
||
* var other = { 'a': 1 };
|
||
*
|
||
* _.isEqual(object, other);
|
||
* // => true
|
||
*
|
||
* object === other;
|
||
* // => false
|
||
*/
|
||
function isEqual(value, other) {
|
||
return baseIsEqual(value, other);
|
||
}
|
||
|
||
/**
|
||
* This method is like `_.isEqual` except that it accepts `customizer` which
|
||
* is invoked to compare values. If `customizer` returns `undefined`, comparisons
|
||
* are handled by the method instead. The `customizer` is invoked with up to
|
||
* six arguments: (objValue, othValue [, index|key, object, other, stack]).
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 4.0.0
|
||
* @category Lang
|
||
* @param {*} value The value to compare.
|
||
* @param {*} other The other value to compare.
|
||
* @param {Function} [customizer] The function to customize comparisons.
|
||
* @returns {boolean} Returns `true` if the values are equivalent, else `false`.
|
||
* @example
|
||
*
|
||
* function isGreeting(value) {
|
||
* return /^h(?:i|ello)$/.test(value);
|
||
* }
|
||
*
|
||
* function customizer(objValue, othValue) {
|
||
* if (isGreeting(objValue) && isGreeting(othValue)) {
|
||
* return true;
|
||
* }
|
||
* }
|
||
*
|
||
* var array = ['hello', 'goodbye'];
|
||
* var other = ['hi', 'goodbye'];
|
||
*
|
||
* _.isEqualWith(array, other, customizer);
|
||
* // => true
|
||
*/
|
||
function isEqualWith(value, other, customizer) {
|
||
customizer = typeof customizer == 'function' ? customizer : undefined;
|
||
var result = customizer ? customizer(value, other) : undefined;
|
||
return result === undefined ? baseIsEqual(value, other, undefined, customizer) : !!result;
|
||
}
|
||
|
||
/**
|
||
* Checks if `value` is an `Error`, `EvalError`, `RangeError`, `ReferenceError`,
|
||
* `SyntaxError`, `TypeError`, or `URIError` object.
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 3.0.0
|
||
* @category Lang
|
||
* @param {*} value The value to check.
|
||
* @returns {boolean} Returns `true` if `value` is an error object, else `false`.
|
||
* @example
|
||
*
|
||
* _.isError(new Error);
|
||
* // => true
|
||
*
|
||
* _.isError(Error);
|
||
* // => false
|
||
*/
|
||
function isError(value) {
|
||
if (!isObjectLike(value)) {
|
||
return false;
|
||
}
|
||
var tag = baseGetTag(value);
|
||
return tag == errorTag || tag == domExcTag ||
|
||
(typeof value.message == 'string' && typeof value.name == 'string' && !isPlainObject(value));
|
||
}
|
||
|
||
/**
|
||
* Checks if `value` is a finite primitive number.
|
||
*
|
||
* **Note:** This method is based on
|
||
* [`Number.isFinite`](https://mdn.io/Number/isFinite).
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 0.1.0
|
||
* @category Lang
|
||
* @param {*} value The value to check.
|
||
* @returns {boolean} Returns `true` if `value` is a finite number, else `false`.
|
||
* @example
|
||
*
|
||
* _.isFinite(3);
|
||
* // => true
|
||
*
|
||
* _.isFinite(Number.MIN_VALUE);
|
||
* // => true
|
||
*
|
||
* _.isFinite(Infinity);
|
||
* // => false
|
||
*
|
||
* _.isFinite('3');
|
||
* // => false
|
||
*/
|
||
function isFinite(value) {
|
||
return typeof value == 'number' && nativeIsFinite(value);
|
||
}
|
||
|
||
/**
|
||
* Checks if `value` is classified as a `Function` object.
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 0.1.0
|
||
* @category Lang
|
||
* @param {*} value The value to check.
|
||
* @returns {boolean} Returns `true` if `value` is a function, else `false`.
|
||
* @example
|
||
*
|
||
* _.isFunction(_);
|
||
* // => true
|
||
*
|
||
* _.isFunction(/abc/);
|
||
* // => false
|
||
*/
|
||
function isFunction(value) {
|
||
if (!isObject(value)) {
|
||
return false;
|
||
}
|
||
// The use of `Object#toString` avoids issues with the `typeof` operator
|
||
// in Safari 9 which returns 'object' for typed arrays and other constructors.
|
||
var tag = baseGetTag(value);
|
||
return tag == funcTag || tag == genTag || tag == asyncTag || tag == proxyTag;
|
||
}
|
||
|
||
/**
|
||
* Checks if `value` is an integer.
|
||
*
|
||
* **Note:** This method is based on
|
||
* [`Number.isInteger`](https://mdn.io/Number/isInteger).
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 4.0.0
|
||
* @category Lang
|
||
* @param {*} value The value to check.
|
||
* @returns {boolean} Returns `true` if `value` is an integer, else `false`.
|
||
* @example
|
||
*
|
||
* _.isInteger(3);
|
||
* // => true
|
||
*
|
||
* _.isInteger(Number.MIN_VALUE);
|
||
* // => false
|
||
*
|
||
* _.isInteger(Infinity);
|
||
* // => false
|
||
*
|
||
* _.isInteger('3');
|
||
* // => false
|
||
*/
|
||
function isInteger(value) {
|
||
return typeof value == 'number' && value == toInteger(value);
|
||
}
|
||
|
||
/**
|
||
* Checks if `value` is a valid array-like length.
|
||
*
|
||
* **Note:** This method is loosely based on
|
||
* [`ToLength`](http://ecma-international.org/ecma-262/7.0/#sec-tolength).
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 4.0.0
|
||
* @category Lang
|
||
* @param {*} value The value to check.
|
||
* @returns {boolean} Returns `true` if `value` is a valid length, else `false`.
|
||
* @example
|
||
*
|
||
* _.isLength(3);
|
||
* // => true
|
||
*
|
||
* _.isLength(Number.MIN_VALUE);
|
||
* // => false
|
||
*
|
||
* _.isLength(Infinity);
|
||
* // => false
|
||
*
|
||
* _.isLength('3');
|
||
* // => false
|
||
*/
|
||
function isLength(value) {
|
||
return typeof value == 'number' &&
|
||
value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER;
|
||
}
|
||
|
||
/**
|
||
* Checks if `value` is the
|
||
* [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types)
|
||
* of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 0.1.0
|
||
* @category Lang
|
||
* @param {*} value The value to check.
|
||
* @returns {boolean} Returns `true` if `value` is an object, else `false`.
|
||
* @example
|
||
*
|
||
* _.isObject({});
|
||
* // => true
|
||
*
|
||
* _.isObject([1, 2, 3]);
|
||
* // => true
|
||
*
|
||
* _.isObject(_.noop);
|
||
* // => true
|
||
*
|
||
* _.isObject(null);
|
||
* // => false
|
||
*/
|
||
function isObject(value) {
|
||
var type = typeof value;
|
||
return value != null && (type == 'object' || type == 'function');
|
||
}
|
||
|
||
/**
|
||
* Checks if `value` is object-like. A value is object-like if it's not `null`
|
||
* and has a `typeof` result of "object".
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 4.0.0
|
||
* @category Lang
|
||
* @param {*} value The value to check.
|
||
* @returns {boolean} Returns `true` if `value` is object-like, else `false`.
|
||
* @example
|
||
*
|
||
* _.isObjectLike({});
|
||
* // => true
|
||
*
|
||
* _.isObjectLike([1, 2, 3]);
|
||
* // => true
|
||
*
|
||
* _.isObjectLike(_.noop);
|
||
* // => false
|
||
*
|
||
* _.isObjectLike(null);
|
||
* // => false
|
||
*/
|
||
function isObjectLike(value) {
|
||
return value != null && typeof value == 'object';
|
||
}
|
||
|
||
/**
|
||
* Checks if `value` is classified as a `Map` object.
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 4.3.0
|
||
* @category Lang
|
||
* @param {*} value The value to check.
|
||
* @returns {boolean} Returns `true` if `value` is a map, else `false`.
|
||
* @example
|
||
*
|
||
* _.isMap(new Map);
|
||
* // => true
|
||
*
|
||
* _.isMap(new WeakMap);
|
||
* // => false
|
||
*/
|
||
var isMap = nodeIsMap ? baseUnary(nodeIsMap) : baseIsMap;
|
||
|
||
/**
|
||
* Performs a partial deep comparison between `object` and `source` to
|
||
* determine if `object` contains equivalent property values.
|
||
*
|
||
* **Note:** This method is equivalent to `_.matches` when `source` is
|
||
* partially applied.
|
||
*
|
||
* Partial comparisons will match empty array and empty object `source`
|
||
* values against any array or object value, respectively. See `_.isEqual`
|
||
* for a list of supported value comparisons.
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 3.0.0
|
||
* @category Lang
|
||
* @param {Object} object The object to inspect.
|
||
* @param {Object} source The object of property values to match.
|
||
* @returns {boolean} Returns `true` if `object` is a match, else `false`.
|
||
* @example
|
||
*
|
||
* var object = { 'a': 1, 'b': 2 };
|
||
*
|
||
* _.isMatch(object, { 'b': 2 });
|
||
* // => true
|
||
*
|
||
* _.isMatch(object, { 'b': 1 });
|
||
* // => false
|
||
*/
|
||
function isMatch(object, source) {
|
||
return object === source || baseIsMatch(object, source, getMatchData(source));
|
||
}
|
||
|
||
/**
|
||
* This method is like `_.isMatch` except that it accepts `customizer` which
|
||
* is invoked to compare values. If `customizer` returns `undefined`, comparisons
|
||
* are handled by the method instead. The `customizer` is invoked with five
|
||
* arguments: (objValue, srcValue, index|key, object, source).
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 4.0.0
|
||
* @category Lang
|
||
* @param {Object} object The object to inspect.
|
||
* @param {Object} source The object of property values to match.
|
||
* @param {Function} [customizer] The function to customize comparisons.
|
||
* @returns {boolean} Returns `true` if `object` is a match, else `false`.
|
||
* @example
|
||
*
|
||
* function isGreeting(value) {
|
||
* return /^h(?:i|ello)$/.test(value);
|
||
* }
|
||
*
|
||
* function customizer(objValue, srcValue) {
|
||
* if (isGreeting(objValue) && isGreeting(srcValue)) {
|
||
* return true;
|
||
* }
|
||
* }
|
||
*
|
||
* var object = { 'greeting': 'hello' };
|
||
* var source = { 'greeting': 'hi' };
|
||
*
|
||
* _.isMatchWith(object, source, customizer);
|
||
* // => true
|
||
*/
|
||
function isMatchWith(object, source, customizer) {
|
||
customizer = typeof customizer == 'function' ? customizer : undefined;
|
||
return baseIsMatch(object, source, getMatchData(source), customizer);
|
||
}
|
||
|
||
/**
|
||
* Checks if `value` is `NaN`.
|
||
*
|
||
* **Note:** This method is based on
|
||
* [`Number.isNaN`](https://mdn.io/Number/isNaN) and is not the same as
|
||
* global [`isNaN`](https://mdn.io/isNaN) which returns `true` for
|
||
* `undefined` and other non-number values.
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 0.1.0
|
||
* @category Lang
|
||
* @param {*} value The value to check.
|
||
* @returns {boolean} Returns `true` if `value` is `NaN`, else `false`.
|
||
* @example
|
||
*
|
||
* _.isNaN(NaN);
|
||
* // => true
|
||
*
|
||
* _.isNaN(new Number(NaN));
|
||
* // => true
|
||
*
|
||
* isNaN(undefined);
|
||
* // => true
|
||
*
|
||
* _.isNaN(undefined);
|
||
* // => false
|
||
*/
|
||
function isNaN(value) {
|
||
// An `NaN` primitive is the only value that is not equal to itself.
|
||
// Perform the `toStringTag` check first to avoid errors with some
|
||
// ActiveX objects in IE.
|
||
return isNumber(value) && value != +value;
|
||
}
|
||
|
||
/**
|
||
* Checks if `value` is a pristine native function.
|
||
*
|
||
* **Note:** This method can't reliably detect native functions in the presence
|
||
* of the core-js package because core-js circumvents this kind of detection.
|
||
* Despite multiple requests, the core-js maintainer has made it clear: any
|
||
* attempt to fix the detection will be obstructed. As a result, we're left
|
||
* with little choice but to throw an error. Unfortunately, this also affects
|
||
* packages, like [babel-polyfill](https://www.npmjs.com/package/babel-polyfill),
|
||
* which rely on core-js.
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 3.0.0
|
||
* @category Lang
|
||
* @param {*} value The value to check.
|
||
* @returns {boolean} Returns `true` if `value` is a native function,
|
||
* else `false`.
|
||
* @example
|
||
*
|
||
* _.isNative(Array.prototype.push);
|
||
* // => true
|
||
*
|
||
* _.isNative(_);
|
||
* // => false
|
||
*/
|
||
function isNative(value) {
|
||
if (isMaskable(value)) {
|
||
throw new Error(CORE_ERROR_TEXT);
|
||
}
|
||
return baseIsNative(value);
|
||
}
|
||
|
||
/**
|
||
* Checks if `value` is `null`.
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 0.1.0
|
||
* @category Lang
|
||
* @param {*} value The value to check.
|
||
* @returns {boolean} Returns `true` if `value` is `null`, else `false`.
|
||
* @example
|
||
*
|
||
* _.isNull(null);
|
||
* // => true
|
||
*
|
||
* _.isNull(void 0);
|
||
* // => false
|
||
*/
|
||
function isNull(value) {
|
||
return value === null;
|
||
}
|
||
|
||
/**
|
||
* Checks if `value` is `null` or `undefined`.
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 4.0.0
|
||
* @category Lang
|
||
* @param {*} value The value to check.
|
||
* @returns {boolean} Returns `true` if `value` is nullish, else `false`.
|
||
* @example
|
||
*
|
||
* _.isNil(null);
|
||
* // => true
|
||
*
|
||
* _.isNil(void 0);
|
||
* // => true
|
||
*
|
||
* _.isNil(NaN);
|
||
* // => false
|
||
*/
|
||
function isNil(value) {
|
||
return value == null;
|
||
}
|
||
|
||
/**
|
||
* Checks if `value` is classified as a `Number` primitive or object.
|
||
*
|
||
* **Note:** To exclude `Infinity`, `-Infinity`, and `NaN`, which are
|
||
* classified as numbers, use the `_.isFinite` method.
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 0.1.0
|
||
* @category Lang
|
||
* @param {*} value The value to check.
|
||
* @returns {boolean} Returns `true` if `value` is a number, else `false`.
|
||
* @example
|
||
*
|
||
* _.isNumber(3);
|
||
* // => true
|
||
*
|
||
* _.isNumber(Number.MIN_VALUE);
|
||
* // => true
|
||
*
|
||
* _.isNumber(Infinity);
|
||
* // => true
|
||
*
|
||
* _.isNumber('3');
|
||
* // => false
|
||
*/
|
||
function isNumber(value) {
|
||
return typeof value == 'number' ||
|
||
(isObjectLike(value) && baseGetTag(value) == numberTag);
|
||
}
|
||
|
||
/**
|
||
* Checks if `value` is a plain object, that is, an object created by the
|
||
* `Object` constructor or one with a `[[Prototype]]` of `null`.
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 0.8.0
|
||
* @category Lang
|
||
* @param {*} value The value to check.
|
||
* @returns {boolean} Returns `true` if `value` is a plain object, else `false`.
|
||
* @example
|
||
*
|
||
* function Foo() {
|
||
* this.a = 1;
|
||
* }
|
||
*
|
||
* _.isPlainObject(new Foo);
|
||
* // => false
|
||
*
|
||
* _.isPlainObject([1, 2, 3]);
|
||
* // => false
|
||
*
|
||
* _.isPlainObject({ 'x': 0, 'y': 0 });
|
||
* // => true
|
||
*
|
||
* _.isPlainObject(Object.create(null));
|
||
* // => true
|
||
*/
|
||
function isPlainObject(value) {
|
||
if (!isObjectLike(value) || baseGetTag(value) != objectTag) {
|
||
return false;
|
||
}
|
||
var proto = getPrototype(value);
|
||
if (proto === null) {
|
||
return true;
|
||
}
|
||
var Ctor = hasOwnProperty.call(proto, 'constructor') && proto.constructor;
|
||
return typeof Ctor == 'function' && Ctor instanceof Ctor &&
|
||
funcToString.call(Ctor) == objectCtorString;
|
||
}
|
||
|
||
/**
|
||
* Checks if `value` is classified as a `RegExp` object.
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 0.1.0
|
||
* @category Lang
|
||
* @param {*} value The value to check.
|
||
* @returns {boolean} Returns `true` if `value` is a regexp, else `false`.
|
||
* @example
|
||
*
|
||
* _.isRegExp(/abc/);
|
||
* // => true
|
||
*
|
||
* _.isRegExp('/abc/');
|
||
* // => false
|
||
*/
|
||
var isRegExp = nodeIsRegExp ? baseUnary(nodeIsRegExp) : baseIsRegExp;
|
||
|
||
/**
|
||
* Checks if `value` is a safe integer. An integer is safe if it's an IEEE-754
|
||
* double precision number which isn't the result of a rounded unsafe integer.
|
||
*
|
||
* **Note:** This method is based on
|
||
* [`Number.isSafeInteger`](https://mdn.io/Number/isSafeInteger).
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 4.0.0
|
||
* @category Lang
|
||
* @param {*} value The value to check.
|
||
* @returns {boolean} Returns `true` if `value` is a safe integer, else `false`.
|
||
* @example
|
||
*
|
||
* _.isSafeInteger(3);
|
||
* // => true
|
||
*
|
||
* _.isSafeInteger(Number.MIN_VALUE);
|
||
* // => false
|
||
*
|
||
* _.isSafeInteger(Infinity);
|
||
* // => false
|
||
*
|
||
* _.isSafeInteger('3');
|
||
* // => false
|
||
*/
|
||
function isSafeInteger(value) {
|
||
return isInteger(value) && value >= -MAX_SAFE_INTEGER && value <= MAX_SAFE_INTEGER;
|
||
}
|
||
|
||
/**
|
||
* Checks if `value` is classified as a `Set` object.
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 4.3.0
|
||
* @category Lang
|
||
* @param {*} value The value to check.
|
||
* @returns {boolean} Returns `true` if `value` is a set, else `false`.
|
||
* @example
|
||
*
|
||
* _.isSet(new Set);
|
||
* // => true
|
||
*
|
||
* _.isSet(new WeakSet);
|
||
* // => false
|
||
*/
|
||
var isSet = nodeIsSet ? baseUnary(nodeIsSet) : baseIsSet;
|
||
|
||
/**
|
||
* Checks if `value` is classified as a `String` primitive or object.
|
||
*
|
||
* @static
|
||
* @since 0.1.0
|
||
* @memberOf _
|
||
* @category Lang
|
||
* @param {*} value The value to check.
|
||
* @returns {boolean} Returns `true` if `value` is a string, else `false`.
|
||
* @example
|
||
*
|
||
* _.isString('abc');
|
||
* // => true
|
||
*
|
||
* _.isString(1);
|
||
* // => false
|
||
*/
|
||
function isString(value) {
|
||
return typeof value == 'string' ||
|
||
(!isArray(value) && isObjectLike(value) && baseGetTag(value) == stringTag);
|
||
}
|
||
|
||
/**
|
||
* Checks if `value` is classified as a `Symbol` primitive or object.
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 4.0.0
|
||
* @category Lang
|
||
* @param {*} value The value to check.
|
||
* @returns {boolean} Returns `true` if `value` is a symbol, else `false`.
|
||
* @example
|
||
*
|
||
* _.isSymbol(Symbol.iterator);
|
||
* // => true
|
||
*
|
||
* _.isSymbol('abc');
|
||
* // => false
|
||
*/
|
||
function isSymbol(value) {
|
||
return typeof value == 'symbol' ||
|
||
(isObjectLike(value) && baseGetTag(value) == symbolTag);
|
||
}
|
||
|
||
/**
|
||
* Checks if `value` is classified as a typed array.
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 3.0.0
|
||
* @category Lang
|
||
* @param {*} value The value to check.
|
||
* @returns {boolean} Returns `true` if `value` is a typed array, else `false`.
|
||
* @example
|
||
*
|
||
* _.isTypedArray(new Uint8Array);
|
||
* // => true
|
||
*
|
||
* _.isTypedArray([]);
|
||
* // => false
|
||
*/
|
||
var isTypedArray = nodeIsTypedArray ? baseUnary(nodeIsTypedArray) : baseIsTypedArray;
|
||
|
||
/**
|
||
* Checks if `value` is `undefined`.
|
||
*
|
||
* @static
|
||
* @since 0.1.0
|
||
* @memberOf _
|
||
* @category Lang
|
||
* @param {*} value The value to check.
|
||
* @returns {boolean} Returns `true` if `value` is `undefined`, else `false`.
|
||
* @example
|
||
*
|
||
* _.isUndefined(void 0);
|
||
* // => true
|
||
*
|
||
* _.isUndefined(null);
|
||
* // => false
|
||
*/
|
||
function isUndefined(value) {
|
||
return value === undefined;
|
||
}
|
||
|
||
/**
|
||
* Checks if `value` is classified as a `WeakMap` object.
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 4.3.0
|
||
* @category Lang
|
||
* @param {*} value The value to check.
|
||
* @returns {boolean} Returns `true` if `value` is a weak map, else `false`.
|
||
* @example
|
||
*
|
||
* _.isWeakMap(new WeakMap);
|
||
* // => true
|
||
*
|
||
* _.isWeakMap(new Map);
|
||
* // => false
|
||
*/
|
||
function isWeakMap(value) {
|
||
return isObjectLike(value) && getTag(value) == weakMapTag;
|
||
}
|
||
|
||
/**
|
||
* Checks if `value` is classified as a `WeakSet` object.
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 4.3.0
|
||
* @category Lang
|
||
* @param {*} value The value to check.
|
||
* @returns {boolean} Returns `true` if `value` is a weak set, else `false`.
|
||
* @example
|
||
*
|
||
* _.isWeakSet(new WeakSet);
|
||
* // => true
|
||
*
|
||
* _.isWeakSet(new Set);
|
||
* // => false
|
||
*/
|
||
function isWeakSet(value) {
|
||
return isObjectLike(value) && baseGetTag(value) == weakSetTag;
|
||
}
|
||
|
||
/**
|
||
* Checks if `value` is less than `other`.
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 3.9.0
|
||
* @category Lang
|
||
* @param {*} value The value to compare.
|
||
* @param {*} other The other value to compare.
|
||
* @returns {boolean} Returns `true` if `value` is less than `other`,
|
||
* else `false`.
|
||
* @see _.gt
|
||
* @example
|
||
*
|
||
* _.lt(1, 3);
|
||
* // => true
|
||
*
|
||
* _.lt(3, 3);
|
||
* // => false
|
||
*
|
||
* _.lt(3, 1);
|
||
* // => false
|
||
*/
|
||
var lt = createRelationalOperation(baseLt);
|
||
|
||
/**
|
||
* Checks if `value` is less than or equal to `other`.
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 3.9.0
|
||
* @category Lang
|
||
* @param {*} value The value to compare.
|
||
* @param {*} other The other value to compare.
|
||
* @returns {boolean} Returns `true` if `value` is less than or equal to
|
||
* `other`, else `false`.
|
||
* @see _.gte
|
||
* @example
|
||
*
|
||
* _.lte(1, 3);
|
||
* // => true
|
||
*
|
||
* _.lte(3, 3);
|
||
* // => true
|
||
*
|
||
* _.lte(3, 1);
|
||
* // => false
|
||
*/
|
||
var lte = createRelationalOperation(function(value, other) {
|
||
return value <= other;
|
||
});
|
||
|
||
/**
|
||
* Converts `value` to an array.
|
||
*
|
||
* @static
|
||
* @since 0.1.0
|
||
* @memberOf _
|
||
* @category Lang
|
||
* @param {*} value The value to convert.
|
||
* @returns {Array} Returns the converted array.
|
||
* @example
|
||
*
|
||
* _.toArray({ 'a': 1, 'b': 2 });
|
||
* // => [1, 2]
|
||
*
|
||
* _.toArray('abc');
|
||
* // => ['a', 'b', 'c']
|
||
*
|
||
* _.toArray(1);
|
||
* // => []
|
||
*
|
||
* _.toArray(null);
|
||
* // => []
|
||
*/
|
||
function toArray(value) {
|
||
if (!value) {
|
||
return [];
|
||
}
|
||
if (isArrayLike(value)) {
|
||
return isString(value) ? stringToArray(value) : copyArray(value);
|
||
}
|
||
if (symIterator && value[symIterator]) {
|
||
return iteratorToArray(value[symIterator]());
|
||
}
|
||
var tag = getTag(value),
|
||
func = tag == mapTag ? mapToArray : (tag == setTag ? setToArray : values);
|
||
|
||
return func(value);
|
||
}
|
||
|
||
/**
|
||
* Converts `value` to a finite number.
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 4.12.0
|
||
* @category Lang
|
||
* @param {*} value The value to convert.
|
||
* @returns {number} Returns the converted number.
|
||
* @example
|
||
*
|
||
* _.toFinite(3.2);
|
||
* // => 3.2
|
||
*
|
||
* _.toFinite(Number.MIN_VALUE);
|
||
* // => 5e-324
|
||
*
|
||
* _.toFinite(Infinity);
|
||
* // => 1.7976931348623157e+308
|
||
*
|
||
* _.toFinite('3.2');
|
||
* // => 3.2
|
||
*/
|
||
function toFinite(value) {
|
||
if (!value) {
|
||
return value === 0 ? value : 0;
|
||
}
|
||
value = toNumber(value);
|
||
if (value === INFINITY || value === -INFINITY) {
|
||
var sign = (value < 0 ? -1 : 1);
|
||
return sign * MAX_INTEGER;
|
||
}
|
||
return value === value ? value : 0;
|
||
}
|
||
|
||
/**
|
||
* Converts `value` to an integer.
|
||
*
|
||
* **Note:** This method is loosely based on
|
||
* [`ToInteger`](http://www.ecma-international.org/ecma-262/7.0/#sec-tointeger).
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 4.0.0
|
||
* @category Lang
|
||
* @param {*} value The value to convert.
|
||
* @returns {number} Returns the converted integer.
|
||
* @example
|
||
*
|
||
* _.toInteger(3.2);
|
||
* // => 3
|
||
*
|
||
* _.toInteger(Number.MIN_VALUE);
|
||
* // => 0
|
||
*
|
||
* _.toInteger(Infinity);
|
||
* // => 1.7976931348623157e+308
|
||
*
|
||
* _.toInteger('3.2');
|
||
* // => 3
|
||
*/
|
||
function toInteger(value) {
|
||
var result = toFinite(value),
|
||
remainder = result % 1;
|
||
|
||
return result === result ? (remainder ? result - remainder : result) : 0;
|
||
}
|
||
|
||
/**
|
||
* Converts `value` to an integer suitable for use as the length of an
|
||
* array-like object.
|
||
*
|
||
* **Note:** This method is based on
|
||
* [`ToLength`](http://ecma-international.org/ecma-262/7.0/#sec-tolength).
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 4.0.0
|
||
* @category Lang
|
||
* @param {*} value The value to convert.
|
||
* @returns {number} Returns the converted integer.
|
||
* @example
|
||
*
|
||
* _.toLength(3.2);
|
||
* // => 3
|
||
*
|
||
* _.toLength(Number.MIN_VALUE);
|
||
* // => 0
|
||
*
|
||
* _.toLength(Infinity);
|
||
* // => 4294967295
|
||
*
|
||
* _.toLength('3.2');
|
||
* // => 3
|
||
*/
|
||
function toLength(value) {
|
||
return value ? baseClamp(toInteger(value), 0, MAX_ARRAY_LENGTH) : 0;
|
||
}
|
||
|
||
/**
|
||
* Converts `value` to a number.
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 4.0.0
|
||
* @category Lang
|
||
* @param {*} value The value to process.
|
||
* @returns {number} Returns the number.
|
||
* @example
|
||
*
|
||
* _.toNumber(3.2);
|
||
* // => 3.2
|
||
*
|
||
* _.toNumber(Number.MIN_VALUE);
|
||
* // => 5e-324
|
||
*
|
||
* _.toNumber(Infinity);
|
||
* // => Infinity
|
||
*
|
||
* _.toNumber('3.2');
|
||
* // => 3.2
|
||
*/
|
||
function toNumber(value) {
|
||
if (typeof value == 'number') {
|
||
return value;
|
||
}
|
||
if (isSymbol(value)) {
|
||
return NAN;
|
||
}
|
||
if (isObject(value)) {
|
||
var other = typeof value.valueOf == 'function' ? value.valueOf() : value;
|
||
value = isObject(other) ? (other + '') : other;
|
||
}
|
||
if (typeof value != 'string') {
|
||
return value === 0 ? value : +value;
|
||
}
|
||
value = value.replace(reTrim, '');
|
||
var isBinary = reIsBinary.test(value);
|
||
return (isBinary || reIsOctal.test(value))
|
||
? freeParseInt(value.slice(2), isBinary ? 2 : 8)
|
||
: (reIsBadHex.test(value) ? NAN : +value);
|
||
}
|
||
|
||
/**
|
||
* Converts `value` to a plain object flattening inherited enumerable string
|
||
* keyed properties of `value` to own properties of the plain object.
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 3.0.0
|
||
* @category Lang
|
||
* @param {*} value The value to convert.
|
||
* @returns {Object} Returns the converted plain object.
|
||
* @example
|
||
*
|
||
* function Foo() {
|
||
* this.b = 2;
|
||
* }
|
||
*
|
||
* Foo.prototype.c = 3;
|
||
*
|
||
* _.assign({ 'a': 1 }, new Foo);
|
||
* // => { 'a': 1, 'b': 2 }
|
||
*
|
||
* _.assign({ 'a': 1 }, _.toPlainObject(new Foo));
|
||
* // => { 'a': 1, 'b': 2, 'c': 3 }
|
||
*/
|
||
function toPlainObject(value) {
|
||
return copyObject(value, keysIn(value));
|
||
}
|
||
|
||
/**
|
||
* Converts `value` to a safe integer. A safe integer can be compared and
|
||
* represented correctly.
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 4.0.0
|
||
* @category Lang
|
||
* @param {*} value The value to convert.
|
||
* @returns {number} Returns the converted integer.
|
||
* @example
|
||
*
|
||
* _.toSafeInteger(3.2);
|
||
* // => 3
|
||
*
|
||
* _.toSafeInteger(Number.MIN_VALUE);
|
||
* // => 0
|
||
*
|
||
* _.toSafeInteger(Infinity);
|
||
* // => 9007199254740991
|
||
*
|
||
* _.toSafeInteger('3.2');
|
||
* // => 3
|
||
*/
|
||
function toSafeInteger(value) {
|
||
return value
|
||
? baseClamp(toInteger(value), -MAX_SAFE_INTEGER, MAX_SAFE_INTEGER)
|
||
: (value === 0 ? value : 0);
|
||
}
|
||
|
||
/**
|
||
* Converts `value` to a string. An empty string is returned for `null`
|
||
* and `undefined` values. The sign of `-0` is preserved.
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 4.0.0
|
||
* @category Lang
|
||
* @param {*} value The value to convert.
|
||
* @returns {string} Returns the converted string.
|
||
* @example
|
||
*
|
||
* _.toString(null);
|
||
* // => ''
|
||
*
|
||
* _.toString(-0);
|
||
* // => '-0'
|
||
*
|
||
* _.toString([1, 2, 3]);
|
||
* // => '1,2,3'
|
||
*/
|
||
function toString(value) {
|
||
return value == null ? '' : baseToString(value);
|
||
}
|
||
|
||
/*------------------------------------------------------------------------*/
|
||
|
||
/**
|
||
* Assigns own enumerable string keyed properties of source objects to the
|
||
* destination object. Source objects are applied from left to right.
|
||
* Subsequent sources overwrite property assignments of previous sources.
|
||
*
|
||
* **Note:** This method mutates `object` and is loosely based on
|
||
* [`Object.assign`](https://mdn.io/Object/assign).
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 0.10.0
|
||
* @category Object
|
||
* @param {Object} object The destination object.
|
||
* @param {...Object} [sources] The source objects.
|
||
* @returns {Object} Returns `object`.
|
||
* @see _.assignIn
|
||
* @example
|
||
*
|
||
* function Foo() {
|
||
* this.a = 1;
|
||
* }
|
||
*
|
||
* function Bar() {
|
||
* this.c = 3;
|
||
* }
|
||
*
|
||
* Foo.prototype.b = 2;
|
||
* Bar.prototype.d = 4;
|
||
*
|
||
* _.assign({ 'a': 0 }, new Foo, new Bar);
|
||
* // => { 'a': 1, 'c': 3 }
|
||
*/
|
||
var assign = createAssigner(function(object, source) {
|
||
if (isPrototype(source) || isArrayLike(source)) {
|
||
copyObject(source, keys(source), object);
|
||
return;
|
||
}
|
||
for (var key in source) {
|
||
if (hasOwnProperty.call(source, key)) {
|
||
assignValue(object, key, source[key]);
|
||
}
|
||
}
|
||
});
|
||
|
||
/**
|
||
* This method is like `_.assign` except that it iterates over own and
|
||
* inherited source properties.
|
||
*
|
||
* **Note:** This method mutates `object`.
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 4.0.0
|
||
* @alias extend
|
||
* @category Object
|
||
* @param {Object} object The destination object.
|
||
* @param {...Object} [sources] The source objects.
|
||
* @returns {Object} Returns `object`.
|
||
* @see _.assign
|
||
* @example
|
||
*
|
||
* function Foo() {
|
||
* this.a = 1;
|
||
* }
|
||
*
|
||
* function Bar() {
|
||
* this.c = 3;
|
||
* }
|
||
*
|
||
* Foo.prototype.b = 2;
|
||
* Bar.prototype.d = 4;
|
||
*
|
||
* _.assignIn({ 'a': 0 }, new Foo, new Bar);
|
||
* // => { 'a': 1, 'b': 2, 'c': 3, 'd': 4 }
|
||
*/
|
||
var assignIn = createAssigner(function(object, source) {
|
||
copyObject(source, keysIn(source), object);
|
||
});
|
||
|
||
/**
|
||
* This method is like `_.assignIn` except that it accepts `customizer`
|
||
* which is invoked to produce the assigned values. If `customizer` returns
|
||
* `undefined`, assignment is handled by the method instead. The `customizer`
|
||
* is invoked with five arguments: (objValue, srcValue, key, object, source).
|
||
*
|
||
* **Note:** This method mutates `object`.
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 4.0.0
|
||
* @alias extendWith
|
||
* @category Object
|
||
* @param {Object} object The destination object.
|
||
* @param {...Object} sources The source objects.
|
||
* @param {Function} [customizer] The function to customize assigned values.
|
||
* @returns {Object} Returns `object`.
|
||
* @see _.assignWith
|
||
* @example
|
||
*
|
||
* function customizer(objValue, srcValue) {
|
||
* return _.isUndefined(objValue) ? srcValue : objValue;
|
||
* }
|
||
*
|
||
* var defaults = _.partialRight(_.assignInWith, customizer);
|
||
*
|
||
* defaults({ 'a': 1 }, { 'b': 2 }, { 'a': 3 });
|
||
* // => { 'a': 1, 'b': 2 }
|
||
*/
|
||
var assignInWith = createAssigner(function(object, source, srcIndex, customizer) {
|
||
copyObject(source, keysIn(source), object, customizer);
|
||
});
|
||
|
||
/**
|
||
* This method is like `_.assign` except that it accepts `customizer`
|
||
* which is invoked to produce the assigned values. If `customizer` returns
|
||
* `undefined`, assignment is handled by the method instead. The `customizer`
|
||
* is invoked with five arguments: (objValue, srcValue, key, object, source).
|
||
*
|
||
* **Note:** This method mutates `object`.
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 4.0.0
|
||
* @category Object
|
||
* @param {Object} object The destination object.
|
||
* @param {...Object} sources The source objects.
|
||
* @param {Function} [customizer] The function to customize assigned values.
|
||
* @returns {Object} Returns `object`.
|
||
* @see _.assignInWith
|
||
* @example
|
||
*
|
||
* function customizer(objValue, srcValue) {
|
||
* return _.isUndefined(objValue) ? srcValue : objValue;
|
||
* }
|
||
*
|
||
* var defaults = _.partialRight(_.assignWith, customizer);
|
||
*
|
||
* defaults({ 'a': 1 }, { 'b': 2 }, { 'a': 3 });
|
||
* // => { 'a': 1, 'b': 2 }
|
||
*/
|
||
var assignWith = createAssigner(function(object, source, srcIndex, customizer) {
|
||
copyObject(source, keys(source), object, customizer);
|
||
});
|
||
|
||
/**
|
||
* Creates an array of values corresponding to `paths` of `object`.
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 1.0.0
|
||
* @category Object
|
||
* @param {Object} object The object to iterate over.
|
||
* @param {...(string|string[])} [paths] The property paths to pick.
|
||
* @returns {Array} Returns the picked values.
|
||
* @example
|
||
*
|
||
* var object = { 'a': [{ 'b': { 'c': 3 } }, 4] };
|
||
*
|
||
* _.at(object, ['a[0].b.c', 'a[1]']);
|
||
* // => [3, 4]
|
||
*/
|
||
var at = flatRest(baseAt);
|
||
|
||
/**
|
||
* Creates an object that inherits from the `prototype` object. If a
|
||
* `properties` object is given, its own enumerable string keyed properties
|
||
* are assigned to the created object.
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 2.3.0
|
||
* @category Object
|
||
* @param {Object} prototype The object to inherit from.
|
||
* @param {Object} [properties] The properties to assign to the object.
|
||
* @returns {Object} Returns the new object.
|
||
* @example
|
||
*
|
||
* function Shape() {
|
||
* this.x = 0;
|
||
* this.y = 0;
|
||
* }
|
||
*
|
||
* function Circle() {
|
||
* Shape.call(this);
|
||
* }
|
||
*
|
||
* Circle.prototype = _.create(Shape.prototype, {
|
||
* 'constructor': Circle
|
||
* });
|
||
*
|
||
* var circle = new Circle;
|
||
* circle instanceof Circle;
|
||
* // => true
|
||
*
|
||
* circle instanceof Shape;
|
||
* // => true
|
||
*/
|
||
function create(prototype, properties) {
|
||
var result = baseCreate(prototype);
|
||
return properties == null ? result : baseAssign(result, properties);
|
||
}
|
||
|
||
/**
|
||
* Assigns own and inherited enumerable string keyed properties of source
|
||
* objects to the destination object for all destination properties that
|
||
* resolve to `undefined`. Source objects are applied from left to right.
|
||
* Once a property is set, additional values of the same property are ignored.
|
||
*
|
||
* **Note:** This method mutates `object`.
|
||
*
|
||
* @static
|
||
* @since 0.1.0
|
||
* @memberOf _
|
||
* @category Object
|
||
* @param {Object} object The destination object.
|
||
* @param {...Object} [sources] The source objects.
|
||
* @returns {Object} Returns `object`.
|
||
* @see _.defaultsDeep
|
||
* @example
|
||
*
|
||
* _.defaults({ 'a': 1 }, { 'b': 2 }, { 'a': 3 });
|
||
* // => { 'a': 1, 'b': 2 }
|
||
*/
|
||
var defaults = baseRest(function(args) {
|
||
args.push(undefined, customDefaultsAssignIn);
|
||
return apply(assignInWith, undefined, args);
|
||
});
|
||
|
||
/**
|
||
* This method is like `_.defaults` except that it recursively assigns
|
||
* default properties.
|
||
*
|
||
* **Note:** This method mutates `object`.
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 3.10.0
|
||
* @category Object
|
||
* @param {Object} object The destination object.
|
||
* @param {...Object} [sources] The source objects.
|
||
* @returns {Object} Returns `object`.
|
||
* @see _.defaults
|
||
* @example
|
||
*
|
||
* _.defaultsDeep({ 'a': { 'b': 2 } }, { 'a': { 'b': 1, 'c': 3 } });
|
||
* // => { 'a': { 'b': 2, 'c': 3 } }
|
||
*/
|
||
var defaultsDeep = baseRest(function(args) {
|
||
args.push(undefined, customDefaultsMerge);
|
||
return apply(mergeWith, undefined, args);
|
||
});
|
||
|
||
/**
|
||
* This method is like `_.find` except that it returns the key of the first
|
||
* element `predicate` returns truthy for instead of the element itself.
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 1.1.0
|
||
* @category Object
|
||
* @param {Object} object The object to inspect.
|
||
* @param {Function} [predicate=_.identity] The function invoked per iteration.
|
||
* @returns {string|undefined} Returns the key of the matched element,
|
||
* else `undefined`.
|
||
* @example
|
||
*
|
||
* var users = {
|
||
* 'barney': { 'age': 36, 'active': true },
|
||
* 'fred': { 'age': 40, 'active': false },
|
||
* 'pebbles': { 'age': 1, 'active': true }
|
||
* };
|
||
*
|
||
* _.findKey(users, function(o) { return o.age < 40; });
|
||
* // => 'barney' (iteration order is not guaranteed)
|
||
*
|
||
* // The `_.matches` iteratee shorthand.
|
||
* _.findKey(users, { 'age': 1, 'active': true });
|
||
* // => 'pebbles'
|
||
*
|
||
* // The `_.matchesProperty` iteratee shorthand.
|
||
* _.findKey(users, ['active', false]);
|
||
* // => 'fred'
|
||
*
|
||
* // The `_.property` iteratee shorthand.
|
||
* _.findKey(users, 'active');
|
||
* // => 'barney'
|
||
*/
|
||
function findKey(object, predicate) {
|
||
return baseFindKey(object, getIteratee(predicate, 3), baseForOwn);
|
||
}
|
||
|
||
/**
|
||
* This method is like `_.findKey` except that it iterates over elements of
|
||
* a collection in the opposite order.
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 2.0.0
|
||
* @category Object
|
||
* @param {Object} object The object to inspect.
|
||
* @param {Function} [predicate=_.identity] The function invoked per iteration.
|
||
* @returns {string|undefined} Returns the key of the matched element,
|
||
* else `undefined`.
|
||
* @example
|
||
*
|
||
* var users = {
|
||
* 'barney': { 'age': 36, 'active': true },
|
||
* 'fred': { 'age': 40, 'active': false },
|
||
* 'pebbles': { 'age': 1, 'active': true }
|
||
* };
|
||
*
|
||
* _.findLastKey(users, function(o) { return o.age < 40; });
|
||
* // => returns 'pebbles' assuming `_.findKey` returns 'barney'
|
||
*
|
||
* // The `_.matches` iteratee shorthand.
|
||
* _.findLastKey(users, { 'age': 36, 'active': true });
|
||
* // => 'barney'
|
||
*
|
||
* // The `_.matchesProperty` iteratee shorthand.
|
||
* _.findLastKey(users, ['active', false]);
|
||
* // => 'fred'
|
||
*
|
||
* // The `_.property` iteratee shorthand.
|
||
* _.findLastKey(users, 'active');
|
||
* // => 'pebbles'
|
||
*/
|
||
function findLastKey(object, predicate) {
|
||
return baseFindKey(object, getIteratee(predicate, 3), baseForOwnRight);
|
||
}
|
||
|
||
/**
|
||
* Iterates over own and inherited enumerable string keyed properties of an
|
||
* object and invokes `iteratee` for each property. The iteratee is invoked
|
||
* with three arguments: (value, key, object). Iteratee functions may exit
|
||
* iteration early by explicitly returning `false`.
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 0.3.0
|
||
* @category Object
|
||
* @param {Object} object The object to iterate over.
|
||
* @param {Function} [iteratee=_.identity] The function invoked per iteration.
|
||
* @returns {Object} Returns `object`.
|
||
* @see _.forInRight
|
||
* @example
|
||
*
|
||
* function Foo() {
|
||
* this.a = 1;
|
||
* this.b = 2;
|
||
* }
|
||
*
|
||
* Foo.prototype.c = 3;
|
||
*
|
||
* _.forIn(new Foo, function(value, key) {
|
||
* console.log(key);
|
||
* });
|
||
* // => Logs 'a', 'b', then 'c' (iteration order is not guaranteed).
|
||
*/
|
||
function forIn(object, iteratee) {
|
||
return object == null
|
||
? object
|
||
: baseFor(object, getIteratee(iteratee, 3), keysIn);
|
||
}
|
||
|
||
/**
|
||
* This method is like `_.forIn` except that it iterates over properties of
|
||
* `object` in the opposite order.
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 2.0.0
|
||
* @category Object
|
||
* @param {Object} object The object to iterate over.
|
||
* @param {Function} [iteratee=_.identity] The function invoked per iteration.
|
||
* @returns {Object} Returns `object`.
|
||
* @see _.forIn
|
||
* @example
|
||
*
|
||
* function Foo() {
|
||
* this.a = 1;
|
||
* this.b = 2;
|
||
* }
|
||
*
|
||
* Foo.prototype.c = 3;
|
||
*
|
||
* _.forInRight(new Foo, function(value, key) {
|
||
* console.log(key);
|
||
* });
|
||
* // => Logs 'c', 'b', then 'a' assuming `_.forIn` logs 'a', 'b', then 'c'.
|
||
*/
|
||
function forInRight(object, iteratee) {
|
||
return object == null
|
||
? object
|
||
: baseForRight(object, getIteratee(iteratee, 3), keysIn);
|
||
}
|
||
|
||
/**
|
||
* Iterates over own enumerable string keyed properties of an object and
|
||
* invokes `iteratee` for each property. The iteratee is invoked with three
|
||
* arguments: (value, key, object). Iteratee functions may exit iteration
|
||
* early by explicitly returning `false`.
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 0.3.0
|
||
* @category Object
|
||
* @param {Object} object The object to iterate over.
|
||
* @param {Function} [iteratee=_.identity] The function invoked per iteration.
|
||
* @returns {Object} Returns `object`.
|
||
* @see _.forOwnRight
|
||
* @example
|
||
*
|
||
* function Foo() {
|
||
* this.a = 1;
|
||
* this.b = 2;
|
||
* }
|
||
*
|
||
* Foo.prototype.c = 3;
|
||
*
|
||
* _.forOwn(new Foo, function(value, key) {
|
||
* console.log(key);
|
||
* });
|
||
* // => Logs 'a' then 'b' (iteration order is not guaranteed).
|
||
*/
|
||
function forOwn(object, iteratee) {
|
||
return object && baseForOwn(object, getIteratee(iteratee, 3));
|
||
}
|
||
|
||
/**
|
||
* This method is like `_.forOwn` except that it iterates over properties of
|
||
* `object` in the opposite order.
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 2.0.0
|
||
* @category Object
|
||
* @param {Object} object The object to iterate over.
|
||
* @param {Function} [iteratee=_.identity] The function invoked per iteration.
|
||
* @returns {Object} Returns `object`.
|
||
* @see _.forOwn
|
||
* @example
|
||
*
|
||
* function Foo() {
|
||
* this.a = 1;
|
||
* this.b = 2;
|
||
* }
|
||
*
|
||
* Foo.prototype.c = 3;
|
||
*
|
||
* _.forOwnRight(new Foo, function(value, key) {
|
||
* console.log(key);
|
||
* });
|
||
* // => Logs 'b' then 'a' assuming `_.forOwn` logs 'a' then 'b'.
|
||
*/
|
||
function forOwnRight(object, iteratee) {
|
||
return object && baseForOwnRight(object, getIteratee(iteratee, 3));
|
||
}
|
||
|
||
/**
|
||
* Creates an array of function property names from own enumerable properties
|
||
* of `object`.
|
||
*
|
||
* @static
|
||
* @since 0.1.0
|
||
* @memberOf _
|
||
* @category Object
|
||
* @param {Object} object The object to inspect.
|
||
* @returns {Array} Returns the function names.
|
||
* @see _.functionsIn
|
||
* @example
|
||
*
|
||
* function Foo() {
|
||
* this.a = _.constant('a');
|
||
* this.b = _.constant('b');
|
||
* }
|
||
*
|
||
* Foo.prototype.c = _.constant('c');
|
||
*
|
||
* _.functions(new Foo);
|
||
* // => ['a', 'b']
|
||
*/
|
||
function functions(object) {
|
||
return object == null ? [] : baseFunctions(object, keys(object));
|
||
}
|
||
|
||
/**
|
||
* Creates an array of function property names from own and inherited
|
||
* enumerable properties of `object`.
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 4.0.0
|
||
* @category Object
|
||
* @param {Object} object The object to inspect.
|
||
* @returns {Array} Returns the function names.
|
||
* @see _.functions
|
||
* @example
|
||
*
|
||
* function Foo() {
|
||
* this.a = _.constant('a');
|
||
* this.b = _.constant('b');
|
||
* }
|
||
*
|
||
* Foo.prototype.c = _.constant('c');
|
||
*
|
||
* _.functionsIn(new Foo);
|
||
* // => ['a', 'b', 'c']
|
||
*/
|
||
function functionsIn(object) {
|
||
return object == null ? [] : baseFunctions(object, keysIn(object));
|
||
}
|
||
|
||
/**
|
||
* Gets the value at `path` of `object`. If the resolved value is
|
||
* `undefined`, the `defaultValue` is returned in its place.
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 3.7.0
|
||
* @category Object
|
||
* @param {Object} object The object to query.
|
||
* @param {Array|string} path The path of the property to get.
|
||
* @param {*} [defaultValue] The value returned for `undefined` resolved values.
|
||
* @returns {*} Returns the resolved value.
|
||
* @example
|
||
*
|
||
* var object = { 'a': [{ 'b': { 'c': 3 } }] };
|
||
*
|
||
* _.get(object, 'a[0].b.c');
|
||
* // => 3
|
||
*
|
||
* _.get(object, ['a', '0', 'b', 'c']);
|
||
* // => 3
|
||
*
|
||
* _.get(object, 'a.b.c', 'default');
|
||
* // => 'default'
|
||
*/
|
||
function get(object, path, defaultValue) {
|
||
var result = object == null ? undefined : baseGet(object, path);
|
||
return result === undefined ? defaultValue : result;
|
||
}
|
||
|
||
/**
|
||
* Checks if `path` is a direct property of `object`.
|
||
*
|
||
* @static
|
||
* @since 0.1.0
|
||
* @memberOf _
|
||
* @category Object
|
||
* @param {Object} object The object to query.
|
||
* @param {Array|string} path The path to check.
|
||
* @returns {boolean} Returns `true` if `path` exists, else `false`.
|
||
* @example
|
||
*
|
||
* var object = { 'a': { 'b': 2 } };
|
||
* var other = _.create({ 'a': _.create({ 'b': 2 }) });
|
||
*
|
||
* _.has(object, 'a');
|
||
* // => true
|
||
*
|
||
* _.has(object, 'a.b');
|
||
* // => true
|
||
*
|
||
* _.has(object, ['a', 'b']);
|
||
* // => true
|
||
*
|
||
* _.has(other, 'a');
|
||
* // => false
|
||
*/
|
||
function has(object, path) {
|
||
return object != null && hasPath(object, path, baseHas);
|
||
}
|
||
|
||
/**
|
||
* Checks if `path` is a direct or inherited property of `object`.
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 4.0.0
|
||
* @category Object
|
||
* @param {Object} object The object to query.
|
||
* @param {Array|string} path The path to check.
|
||
* @returns {boolean} Returns `true` if `path` exists, else `false`.
|
||
* @example
|
||
*
|
||
* var object = _.create({ 'a': _.create({ 'b': 2 }) });
|
||
*
|
||
* _.hasIn(object, 'a');
|
||
* // => true
|
||
*
|
||
* _.hasIn(object, 'a.b');
|
||
* // => true
|
||
*
|
||
* _.hasIn(object, ['a', 'b']);
|
||
* // => true
|
||
*
|
||
* _.hasIn(object, 'b');
|
||
* // => false
|
||
*/
|
||
function hasIn(object, path) {
|
||
return object != null && hasPath(object, path, baseHasIn);
|
||
}
|
||
|
||
/**
|
||
* Creates an object composed of the inverted keys and values of `object`.
|
||
* If `object` contains duplicate values, subsequent values overwrite
|
||
* property assignments of previous values.
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 0.7.0
|
||
* @category Object
|
||
* @param {Object} object The object to invert.
|
||
* @returns {Object} Returns the new inverted object.
|
||
* @example
|
||
*
|
||
* var object = { 'a': 1, 'b': 2, 'c': 1 };
|
||
*
|
||
* _.invert(object);
|
||
* // => { '1': 'c', '2': 'b' }
|
||
*/
|
||
var invert = createInverter(function(result, value, key) {
|
||
result[value] = key;
|
||
}, constant(identity));
|
||
|
||
/**
|
||
* This method is like `_.invert` except that the inverted object is generated
|
||
* from the results of running each element of `object` thru `iteratee`. The
|
||
* corresponding inverted value of each inverted key is an array of keys
|
||
* responsible for generating the inverted value. The iteratee is invoked
|
||
* with one argument: (value).
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 4.1.0
|
||
* @category Object
|
||
* @param {Object} object The object to invert.
|
||
* @param {Function} [iteratee=_.identity] The iteratee invoked per element.
|
||
* @returns {Object} Returns the new inverted object.
|
||
* @example
|
||
*
|
||
* var object = { 'a': 1, 'b': 2, 'c': 1 };
|
||
*
|
||
* _.invertBy(object);
|
||
* // => { '1': ['a', 'c'], '2': ['b'] }
|
||
*
|
||
* _.invertBy(object, function(value) {
|
||
* return 'group' + value;
|
||
* });
|
||
* // => { 'group1': ['a', 'c'], 'group2': ['b'] }
|
||
*/
|
||
var invertBy = createInverter(function(result, value, key) {
|
||
if (hasOwnProperty.call(result, value)) {
|
||
result[value].push(key);
|
||
} else {
|
||
result[value] = [key];
|
||
}
|
||
}, getIteratee);
|
||
|
||
/**
|
||
* Invokes the method at `path` of `object`.
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 4.0.0
|
||
* @category Object
|
||
* @param {Object} object The object to query.
|
||
* @param {Array|string} path The path of the method to invoke.
|
||
* @param {...*} [args] The arguments to invoke the method with.
|
||
* @returns {*} Returns the result of the invoked method.
|
||
* @example
|
||
*
|
||
* var object = { 'a': [{ 'b': { 'c': [1, 2, 3, 4] } }] };
|
||
*
|
||
* _.invoke(object, 'a[0].b.c.slice', 1, 3);
|
||
* // => [2, 3]
|
||
*/
|
||
var invoke = baseRest(baseInvoke);
|
||
|
||
/**
|
||
* Creates an array of the own enumerable property names of `object`.
|
||
*
|
||
* **Note:** Non-object values are coerced to objects. See the
|
||
* [ES spec](http://ecma-international.org/ecma-262/7.0/#sec-object.keys)
|
||
* for more details.
|
||
*
|
||
* @static
|
||
* @since 0.1.0
|
||
* @memberOf _
|
||
* @category Object
|
||
* @param {Object} object The object to query.
|
||
* @returns {Array} Returns the array of property names.
|
||
* @example
|
||
*
|
||
* function Foo() {
|
||
* this.a = 1;
|
||
* this.b = 2;
|
||
* }
|
||
*
|
||
* Foo.prototype.c = 3;
|
||
*
|
||
* _.keys(new Foo);
|
||
* // => ['a', 'b'] (iteration order is not guaranteed)
|
||
*
|
||
* _.keys('hi');
|
||
* // => ['0', '1']
|
||
*/
|
||
function keys(object) {
|
||
return isArrayLike(object) ? arrayLikeKeys(object) : baseKeys(object);
|
||
}
|
||
|
||
/**
|
||
* Creates an array of the own and inherited enumerable property names of `object`.
|
||
*
|
||
* **Note:** Non-object values are coerced to objects.
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 3.0.0
|
||
* @category Object
|
||
* @param {Object} object The object to query.
|
||
* @returns {Array} Returns the array of property names.
|
||
* @example
|
||
*
|
||
* function Foo() {
|
||
* this.a = 1;
|
||
* this.b = 2;
|
||
* }
|
||
*
|
||
* Foo.prototype.c = 3;
|
||
*
|
||
* _.keysIn(new Foo);
|
||
* // => ['a', 'b', 'c'] (iteration order is not guaranteed)
|
||
*/
|
||
function keysIn(object) {
|
||
return isArrayLike(object) ? arrayLikeKeys(object, true) : baseKeysIn(object);
|
||
}
|
||
|
||
/**
|
||
* The opposite of `_.mapValues`; this method creates an object with the
|
||
* same values as `object` and keys generated by running each own enumerable
|
||
* string keyed property of `object` thru `iteratee`. The iteratee is invoked
|
||
* with three arguments: (value, key, object).
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 3.8.0
|
||
* @category Object
|
||
* @param {Object} object The object to iterate over.
|
||
* @param {Function} [iteratee=_.identity] The function invoked per iteration.
|
||
* @returns {Object} Returns the new mapped object.
|
||
* @see _.mapValues
|
||
* @example
|
||
*
|
||
* _.mapKeys({ 'a': 1, 'b': 2 }, function(value, key) {
|
||
* return key + value;
|
||
* });
|
||
* // => { 'a1': 1, 'b2': 2 }
|
||
*/
|
||
function mapKeys(object, iteratee) {
|
||
var result = {};
|
||
iteratee = getIteratee(iteratee, 3);
|
||
|
||
baseForOwn(object, function(value, key, object) {
|
||
baseAssignValue(result, iteratee(value, key, object), value);
|
||
});
|
||
return result;
|
||
}
|
||
|
||
/**
|
||
* Creates an object with the same keys as `object` and values generated
|
||
* by running each own enumerable string keyed property of `object` thru
|
||
* `iteratee`. The iteratee is invoked with three arguments:
|
||
* (value, key, object).
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 2.4.0
|
||
* @category Object
|
||
* @param {Object} object The object to iterate over.
|
||
* @param {Function} [iteratee=_.identity] The function invoked per iteration.
|
||
* @returns {Object} Returns the new mapped object.
|
||
* @see _.mapKeys
|
||
* @example
|
||
*
|
||
* var users = {
|
||
* 'fred': { 'user': 'fred', 'age': 40 },
|
||
* 'pebbles': { 'user': 'pebbles', 'age': 1 }
|
||
* };
|
||
*
|
||
* _.mapValues(users, function(o) { return o.age; });
|
||
* // => { 'fred': 40, 'pebbles': 1 } (iteration order is not guaranteed)
|
||
*
|
||
* // The `_.property` iteratee shorthand.
|
||
* _.mapValues(users, 'age');
|
||
* // => { 'fred': 40, 'pebbles': 1 } (iteration order is not guaranteed)
|
||
*/
|
||
function mapValues(object, iteratee) {
|
||
var result = {};
|
||
iteratee = getIteratee(iteratee, 3);
|
||
|
||
baseForOwn(object, function(value, key, object) {
|
||
baseAssignValue(result, key, iteratee(value, key, object));
|
||
});
|
||
return result;
|
||
}
|
||
|
||
/**
|
||
* This method is like `_.assign` except that it recursively merges own and
|
||
* inherited enumerable string keyed properties of source objects into the
|
||
* destination object. Source properties that resolve to `undefined` are
|
||
* skipped if a destination value exists. Array and plain object properties
|
||
* are merged recursively. Other objects and value types are overridden by
|
||
* assignment. Source objects are applied from left to right. Subsequent
|
||
* sources overwrite property assignments of previous sources.
|
||
*
|
||
* **Note:** This method mutates `object`.
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 0.5.0
|
||
* @category Object
|
||
* @param {Object} object The destination object.
|
||
* @param {...Object} [sources] The source objects.
|
||
* @returns {Object} Returns `object`.
|
||
* @example
|
||
*
|
||
* var object = {
|
||
* 'a': [{ 'b': 2 }, { 'd': 4 }]
|
||
* };
|
||
*
|
||
* var other = {
|
||
* 'a': [{ 'c': 3 }, { 'e': 5 }]
|
||
* };
|
||
*
|
||
* _.merge(object, other);
|
||
* // => { 'a': [{ 'b': 2, 'c': 3 }, { 'd': 4, 'e': 5 }] }
|
||
*/
|
||
var merge = createAssigner(function(object, source, srcIndex) {
|
||
baseMerge(object, source, srcIndex);
|
||
});
|
||
|
||
/**
|
||
* This method is like `_.merge` except that it accepts `customizer` which
|
||
* is invoked to produce the merged values of the destination and source
|
||
* properties. If `customizer` returns `undefined`, merging is handled by the
|
||
* method instead. The `customizer` is invoked with six arguments:
|
||
* (objValue, srcValue, key, object, source, stack).
|
||
*
|
||
* **Note:** This method mutates `object`.
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 4.0.0
|
||
* @category Object
|
||
* @param {Object} object The destination object.
|
||
* @param {...Object} sources The source objects.
|
||
* @param {Function} customizer The function to customize assigned values.
|
||
* @returns {Object} Returns `object`.
|
||
* @example
|
||
*
|
||
* function customizer(objValue, srcValue) {
|
||
* if (_.isArray(objValue)) {
|
||
* return objValue.concat(srcValue);
|
||
* }
|
||
* }
|
||
*
|
||
* var object = { 'a': [1], 'b': [2] };
|
||
* var other = { 'a': [3], 'b': [4] };
|
||
*
|
||
* _.mergeWith(object, other, customizer);
|
||
* // => { 'a': [1, 3], 'b': [2, 4] }
|
||
*/
|
||
var mergeWith = createAssigner(function(object, source, srcIndex, customizer) {
|
||
baseMerge(object, source, srcIndex, customizer);
|
||
});
|
||
|
||
/**
|
||
* The opposite of `_.pick`; this method creates an object composed of the
|
||
* own and inherited enumerable property paths of `object` that are not omitted.
|
||
*
|
||
* **Note:** This method is considerably slower than `_.pick`.
|
||
*
|
||
* @static
|
||
* @since 0.1.0
|
||
* @memberOf _
|
||
* @category Object
|
||
* @param {Object} object The source object.
|
||
* @param {...(string|string[])} [paths] The property paths to omit.
|
||
* @returns {Object} Returns the new object.
|
||
* @example
|
||
*
|
||
* var object = { 'a': 1, 'b': '2', 'c': 3 };
|
||
*
|
||
* _.omit(object, ['a', 'c']);
|
||
* // => { 'b': '2' }
|
||
*/
|
||
var omit = flatRest(function(object, paths) {
|
||
var result = {};
|
||
if (object == null) {
|
||
return result;
|
||
}
|
||
var isDeep = false;
|
||
paths = arrayMap(paths, function(path) {
|
||
path = castPath(path, object);
|
||
isDeep || (isDeep = path.length > 1);
|
||
return path;
|
||
});
|
||
copyObject(object, getAllKeysIn(object), result);
|
||
if (isDeep) {
|
||
result = baseClone(result, CLONE_DEEP_FLAG | CLONE_FLAT_FLAG | CLONE_SYMBOLS_FLAG, customOmitClone);
|
||
}
|
||
var length = paths.length;
|
||
while (length--) {
|
||
baseUnset(result, paths[length]);
|
||
}
|
||
return result;
|
||
});
|
||
|
||
/**
|
||
* The opposite of `_.pickBy`; this method creates an object composed of
|
||
* the own and inherited enumerable string keyed properties of `object` that
|
||
* `predicate` doesn't return truthy for. The predicate is invoked with two
|
||
* arguments: (value, key).
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 4.0.0
|
||
* @category Object
|
||
* @param {Object} object The source object.
|
||
* @param {Function} [predicate=_.identity] The function invoked per property.
|
||
* @returns {Object} Returns the new object.
|
||
* @example
|
||
*
|
||
* var object = { 'a': 1, 'b': '2', 'c': 3 };
|
||
*
|
||
* _.omitBy(object, _.isNumber);
|
||
* // => { 'b': '2' }
|
||
*/
|
||
function omitBy(object, predicate) {
|
||
return pickBy(object, negate(getIteratee(predicate)));
|
||
}
|
||
|
||
/**
|
||
* Creates an object composed of the picked `object` properties.
|
||
*
|
||
* @static
|
||
* @since 0.1.0
|
||
* @memberOf _
|
||
* @category Object
|
||
* @param {Object} object The source object.
|
||
* @param {...(string|string[])} [paths] The property paths to pick.
|
||
* @returns {Object} Returns the new object.
|
||
* @example
|
||
*
|
||
* var object = { 'a': 1, 'b': '2', 'c': 3 };
|
||
*
|
||
* _.pick(object, ['a', 'c']);
|
||
* // => { 'a': 1, 'c': 3 }
|
||
*/
|
||
var pick = flatRest(function(object, paths) {
|
||
return object == null ? {} : basePick(object, paths);
|
||
});
|
||
|
||
/**
|
||
* Creates an object composed of the `object` properties `predicate` returns
|
||
* truthy for. The predicate is invoked with two arguments: (value, key).
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 4.0.0
|
||
* @category Object
|
||
* @param {Object} object The source object.
|
||
* @param {Function} [predicate=_.identity] The function invoked per property.
|
||
* @returns {Object} Returns the new object.
|
||
* @example
|
||
*
|
||
* var object = { 'a': 1, 'b': '2', 'c': 3 };
|
||
*
|
||
* _.pickBy(object, _.isNumber);
|
||
* // => { 'a': 1, 'c': 3 }
|
||
*/
|
||
function pickBy(object, predicate) {
|
||
if (object == null) {
|
||
return {};
|
||
}
|
||
var props = arrayMap(getAllKeysIn(object), function(prop) {
|
||
return [prop];
|
||
});
|
||
predicate = getIteratee(predicate);
|
||
return basePickBy(object, props, function(value, path) {
|
||
return predicate(value, path[0]);
|
||
});
|
||
}
|
||
|
||
/**
|
||
* This method is like `_.get` except that if the resolved value is a
|
||
* function it's invoked with the `this` binding of its parent object and
|
||
* its result is returned.
|
||
*
|
||
* @static
|
||
* @since 0.1.0
|
||
* @memberOf _
|
||
* @category Object
|
||
* @param {Object} object The object to query.
|
||
* @param {Array|string} path The path of the property to resolve.
|
||
* @param {*} [defaultValue] The value returned for `undefined` resolved values.
|
||
* @returns {*} Returns the resolved value.
|
||
* @example
|
||
*
|
||
* var object = { 'a': [{ 'b': { 'c1': 3, 'c2': _.constant(4) } }] };
|
||
*
|
||
* _.result(object, 'a[0].b.c1');
|
||
* // => 3
|
||
*
|
||
* _.result(object, 'a[0].b.c2');
|
||
* // => 4
|
||
*
|
||
* _.result(object, 'a[0].b.c3', 'default');
|
||
* // => 'default'
|
||
*
|
||
* _.result(object, 'a[0].b.c3', _.constant('default'));
|
||
* // => 'default'
|
||
*/
|
||
function result(object, path, defaultValue) {
|
||
path = castPath(path, object);
|
||
|
||
var index = -1,
|
||
length = path.length;
|
||
|
||
// Ensure the loop is entered when path is empty.
|
||
if (!length) {
|
||
length = 1;
|
||
object = undefined;
|
||
}
|
||
while (++index < length) {
|
||
var value = object == null ? undefined : object[toKey(path[index])];
|
||
if (value === undefined) {
|
||
index = length;
|
||
value = defaultValue;
|
||
}
|
||
object = isFunction(value) ? value.call(object) : value;
|
||
}
|
||
return object;
|
||
}
|
||
|
||
/**
|
||
* Sets the value at `path` of `object`. If a portion of `path` doesn't exist,
|
||
* it's created. Arrays are created for missing index properties while objects
|
||
* are created for all other missing properties. Use `_.setWith` to customize
|
||
* `path` creation.
|
||
*
|
||
* **Note:** This method mutates `object`.
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 3.7.0
|
||
* @category Object
|
||
* @param {Object} object The object to modify.
|
||
* @param {Array|string} path The path of the property to set.
|
||
* @param {*} value The value to set.
|
||
* @returns {Object} Returns `object`.
|
||
* @example
|
||
*
|
||
* var object = { 'a': [{ 'b': { 'c': 3 } }] };
|
||
*
|
||
* _.set(object, 'a[0].b.c', 4);
|
||
* console.log(object.a[0].b.c);
|
||
* // => 4
|
||
*
|
||
* _.set(object, ['x', '0', 'y', 'z'], 5);
|
||
* console.log(object.x[0].y.z);
|
||
* // => 5
|
||
*/
|
||
function set(object, path, value) {
|
||
return object == null ? object : baseSet(object, path, value);
|
||
}
|
||
|
||
/**
|
||
* This method is like `_.set` except that it accepts `customizer` which is
|
||
* invoked to produce the objects of `path`. If `customizer` returns `undefined`
|
||
* path creation is handled by the method instead. The `customizer` is invoked
|
||
* with three arguments: (nsValue, key, nsObject).
|
||
*
|
||
* **Note:** This method mutates `object`.
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 4.0.0
|
||
* @category Object
|
||
* @param {Object} object The object to modify.
|
||
* @param {Array|string} path The path of the property to set.
|
||
* @param {*} value The value to set.
|
||
* @param {Function} [customizer] The function to customize assigned values.
|
||
* @returns {Object} Returns `object`.
|
||
* @example
|
||
*
|
||
* var object = {};
|
||
*
|
||
* _.setWith(object, '[0][1]', 'a', Object);
|
||
* // => { '0': { '1': 'a' } }
|
||
*/
|
||
function setWith(object, path, value, customizer) {
|
||
customizer = typeof customizer == 'function' ? customizer : undefined;
|
||
return object == null ? object : baseSet(object, path, value, customizer);
|
||
}
|
||
|
||
/**
|
||
* Creates an array of own enumerable string keyed-value pairs for `object`
|
||
* which can be consumed by `_.fromPairs`. If `object` is a map or set, its
|
||
* entries are returned.
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 4.0.0
|
||
* @alias entries
|
||
* @category Object
|
||
* @param {Object} object The object to query.
|
||
* @returns {Array} Returns the key-value pairs.
|
||
* @example
|
||
*
|
||
* function Foo() {
|
||
* this.a = 1;
|
||
* this.b = 2;
|
||
* }
|
||
*
|
||
* Foo.prototype.c = 3;
|
||
*
|
||
* _.toPairs(new Foo);
|
||
* // => [['a', 1], ['b', 2]] (iteration order is not guaranteed)
|
||
*/
|
||
var toPairs = createToPairs(keys);
|
||
|
||
/**
|
||
* Creates an array of own and inherited enumerable string keyed-value pairs
|
||
* for `object` which can be consumed by `_.fromPairs`. If `object` is a map
|
||
* or set, its entries are returned.
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 4.0.0
|
||
* @alias entriesIn
|
||
* @category Object
|
||
* @param {Object} object The object to query.
|
||
* @returns {Array} Returns the key-value pairs.
|
||
* @example
|
||
*
|
||
* function Foo() {
|
||
* this.a = 1;
|
||
* this.b = 2;
|
||
* }
|
||
*
|
||
* Foo.prototype.c = 3;
|
||
*
|
||
* _.toPairsIn(new Foo);
|
||
* // => [['a', 1], ['b', 2], ['c', 3]] (iteration order is not guaranteed)
|
||
*/
|
||
var toPairsIn = createToPairs(keysIn);
|
||
|
||
/**
|
||
* An alternative to `_.reduce`; this method transforms `object` to a new
|
||
* `accumulator` object which is the result of running each of its own
|
||
* enumerable string keyed properties thru `iteratee`, with each invocation
|
||
* potentially mutating the `accumulator` object. If `accumulator` is not
|
||
* provided, a new object with the same `[[Prototype]]` will be used. The
|
||
* iteratee is invoked with four arguments: (accumulator, value, key, object).
|
||
* Iteratee functions may exit iteration early by explicitly returning `false`.
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 1.3.0
|
||
* @category Object
|
||
* @param {Object} object The object to iterate over.
|
||
* @param {Function} [iteratee=_.identity] The function invoked per iteration.
|
||
* @param {*} [accumulator] The custom accumulator value.
|
||
* @returns {*} Returns the accumulated value.
|
||
* @example
|
||
*
|
||
* _.transform([2, 3, 4], function(result, n) {
|
||
* result.push(n *= n);
|
||
* return n % 2 == 0;
|
||
* }, []);
|
||
* // => [4, 9]
|
||
*
|
||
* _.transform({ 'a': 1, 'b': 2, 'c': 1 }, function(result, value, key) {
|
||
* (result[value] || (result[value] = [])).push(key);
|
||
* }, {});
|
||
* // => { '1': ['a', 'c'], '2': ['b'] }
|
||
*/
|
||
function transform(object, iteratee, accumulator) {
|
||
var isArr = isArray(object),
|
||
isArrLike = isArr || isBuffer(object) || isTypedArray(object);
|
||
|
||
iteratee = getIteratee(iteratee, 4);
|
||
if (accumulator == null) {
|
||
var Ctor = object && object.constructor;
|
||
if (isArrLike) {
|
||
accumulator = isArr ? new Ctor : [];
|
||
}
|
||
else if (isObject(object)) {
|
||
accumulator = isFunction(Ctor) ? baseCreate(getPrototype(object)) : {};
|
||
}
|
||
else {
|
||
accumulator = {};
|
||
}
|
||
}
|
||
(isArrLike ? arrayEach : baseForOwn)(object, function(value, index, object) {
|
||
return iteratee(accumulator, value, index, object);
|
||
});
|
||
return accumulator;
|
||
}
|
||
|
||
/**
|
||
* Removes the property at `path` of `object`.
|
||
*
|
||
* **Note:** This method mutates `object`.
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 4.0.0
|
||
* @category Object
|
||
* @param {Object} object The object to modify.
|
||
* @param {Array|string} path The path of the property to unset.
|
||
* @returns {boolean} Returns `true` if the property is deleted, else `false`.
|
||
* @example
|
||
*
|
||
* var object = { 'a': [{ 'b': { 'c': 7 } }] };
|
||
* _.unset(object, 'a[0].b.c');
|
||
* // => true
|
||
*
|
||
* console.log(object);
|
||
* // => { 'a': [{ 'b': {} }] };
|
||
*
|
||
* _.unset(object, ['a', '0', 'b', 'c']);
|
||
* // => true
|
||
*
|
||
* console.log(object);
|
||
* // => { 'a': [{ 'b': {} }] };
|
||
*/
|
||
function unset(object, path) {
|
||
return object == null ? true : baseUnset(object, path);
|
||
}
|
||
|
||
/**
|
||
* This method is like `_.set` except that accepts `updater` to produce the
|
||
* value to set. Use `_.updateWith` to customize `path` creation. The `updater`
|
||
* is invoked with one argument: (value).
|
||
*
|
||
* **Note:** This method mutates `object`.
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 4.6.0
|
||
* @category Object
|
||
* @param {Object} object The object to modify.
|
||
* @param {Array|string} path The path of the property to set.
|
||
* @param {Function} updater The function to produce the updated value.
|
||
* @returns {Object} Returns `object`.
|
||
* @example
|
||
*
|
||
* var object = { 'a': [{ 'b': { 'c': 3 } }] };
|
||
*
|
||
* _.update(object, 'a[0].b.c', function(n) { return n * n; });
|
||
* console.log(object.a[0].b.c);
|
||
* // => 9
|
||
*
|
||
* _.update(object, 'x[0].y.z', function(n) { return n ? n + 1 : 0; });
|
||
* console.log(object.x[0].y.z);
|
||
* // => 0
|
||
*/
|
||
function update(object, path, updater) {
|
||
return object == null ? object : baseUpdate(object, path, castFunction(updater));
|
||
}
|
||
|
||
/**
|
||
* This method is like `_.update` except that it accepts `customizer` which is
|
||
* invoked to produce the objects of `path`. If `customizer` returns `undefined`
|
||
* path creation is handled by the method instead. The `customizer` is invoked
|
||
* with three arguments: (nsValue, key, nsObject).
|
||
*
|
||
* **Note:** This method mutates `object`.
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 4.6.0
|
||
* @category Object
|
||
* @param {Object} object The object to modify.
|
||
* @param {Array|string} path The path of the property to set.
|
||
* @param {Function} updater The function to produce the updated value.
|
||
* @param {Function} [customizer] The function to customize assigned values.
|
||
* @returns {Object} Returns `object`.
|
||
* @example
|
||
*
|
||
* var object = {};
|
||
*
|
||
* _.updateWith(object, '[0][1]', _.constant('a'), Object);
|
||
* // => { '0': { '1': 'a' } }
|
||
*/
|
||
function updateWith(object, path, updater, customizer) {
|
||
customizer = typeof customizer == 'function' ? customizer : undefined;
|
||
return object == null ? object : baseUpdate(object, path, castFunction(updater), customizer);
|
||
}
|
||
|
||
/**
|
||
* Creates an array of the own enumerable string keyed property values of `object`.
|
||
*
|
||
* **Note:** Non-object values are coerced to objects.
|
||
*
|
||
* @static
|
||
* @since 0.1.0
|
||
* @memberOf _
|
||
* @category Object
|
||
* @param {Object} object The object to query.
|
||
* @returns {Array} Returns the array of property values.
|
||
* @example
|
||
*
|
||
* function Foo() {
|
||
* this.a = 1;
|
||
* this.b = 2;
|
||
* }
|
||
*
|
||
* Foo.prototype.c = 3;
|
||
*
|
||
* _.values(new Foo);
|
||
* // => [1, 2] (iteration order is not guaranteed)
|
||
*
|
||
* _.values('hi');
|
||
* // => ['h', 'i']
|
||
*/
|
||
function values(object) {
|
||
return object == null ? [] : baseValues(object, keys(object));
|
||
}
|
||
|
||
/**
|
||
* Creates an array of the own and inherited enumerable string keyed property
|
||
* values of `object`.
|
||
*
|
||
* **Note:** Non-object values are coerced to objects.
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 3.0.0
|
||
* @category Object
|
||
* @param {Object} object The object to query.
|
||
* @returns {Array} Returns the array of property values.
|
||
* @example
|
||
*
|
||
* function Foo() {
|
||
* this.a = 1;
|
||
* this.b = 2;
|
||
* }
|
||
*
|
||
* Foo.prototype.c = 3;
|
||
*
|
||
* _.valuesIn(new Foo);
|
||
* // => [1, 2, 3] (iteration order is not guaranteed)
|
||
*/
|
||
function valuesIn(object) {
|
||
return object == null ? [] : baseValues(object, keysIn(object));
|
||
}
|
||
|
||
/*------------------------------------------------------------------------*/
|
||
|
||
/**
|
||
* Clamps `number` within the inclusive `lower` and `upper` bounds.
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 4.0.0
|
||
* @category Number
|
||
* @param {number} number The number to clamp.
|
||
* @param {number} [lower] The lower bound.
|
||
* @param {number} upper The upper bound.
|
||
* @returns {number} Returns the clamped number.
|
||
* @example
|
||
*
|
||
* _.clamp(-10, -5, 5);
|
||
* // => -5
|
||
*
|
||
* _.clamp(10, -5, 5);
|
||
* // => 5
|
||
*/
|
||
function clamp(number, lower, upper) {
|
||
if (upper === undefined) {
|
||
upper = lower;
|
||
lower = undefined;
|
||
}
|
||
if (upper !== undefined) {
|
||
upper = toNumber(upper);
|
||
upper = upper === upper ? upper : 0;
|
||
}
|
||
if (lower !== undefined) {
|
||
lower = toNumber(lower);
|
||
lower = lower === lower ? lower : 0;
|
||
}
|
||
return baseClamp(toNumber(number), lower, upper);
|
||
}
|
||
|
||
/**
|
||
* Checks if `n` is between `start` and up to, but not including, `end`. If
|
||
* `end` is not specified, it's set to `start` with `start` then set to `0`.
|
||
* If `start` is greater than `end` the params are swapped to support
|
||
* negative ranges.
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 3.3.0
|
||
* @category Number
|
||
* @param {number} number The number to check.
|
||
* @param {number} [start=0] The start of the range.
|
||
* @param {number} end The end of the range.
|
||
* @returns {boolean} Returns `true` if `number` is in the range, else `false`.
|
||
* @see _.range, _.rangeRight
|
||
* @example
|
||
*
|
||
* _.inRange(3, 2, 4);
|
||
* // => true
|
||
*
|
||
* _.inRange(4, 8);
|
||
* // => true
|
||
*
|
||
* _.inRange(4, 2);
|
||
* // => false
|
||
*
|
||
* _.inRange(2, 2);
|
||
* // => false
|
||
*
|
||
* _.inRange(1.2, 2);
|
||
* // => true
|
||
*
|
||
* _.inRange(5.2, 4);
|
||
* // => false
|
||
*
|
||
* _.inRange(-3, -2, -6);
|
||
* // => true
|
||
*/
|
||
function inRange(number, start, end) {
|
||
start = toFinite(start);
|
||
if (end === undefined) {
|
||
end = start;
|
||
start = 0;
|
||
} else {
|
||
end = toFinite(end);
|
||
}
|
||
number = toNumber(number);
|
||
return baseInRange(number, start, end);
|
||
}
|
||
|
||
/**
|
||
* Produces a random number between the inclusive `lower` and `upper` bounds.
|
||
* If only one argument is provided a number between `0` and the given number
|
||
* is returned. If `floating` is `true`, or either `lower` or `upper` are
|
||
* floats, a floating-point number is returned instead of an integer.
|
||
*
|
||
* **Note:** JavaScript follows the IEEE-754 standard for resolving
|
||
* floating-point values which can produce unexpected results.
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 0.7.0
|
||
* @category Number
|
||
* @param {number} [lower=0] The lower bound.
|
||
* @param {number} [upper=1] The upper bound.
|
||
* @param {boolean} [floating] Specify returning a floating-point number.
|
||
* @returns {number} Returns the random number.
|
||
* @example
|
||
*
|
||
* _.random(0, 5);
|
||
* // => an integer between 0 and 5
|
||
*
|
||
* _.random(5);
|
||
* // => also an integer between 0 and 5
|
||
*
|
||
* _.random(5, true);
|
||
* // => a floating-point number between 0 and 5
|
||
*
|
||
* _.random(1.2, 5.2);
|
||
* // => a floating-point number between 1.2 and 5.2
|
||
*/
|
||
function random(lower, upper, floating) {
|
||
if (floating && typeof floating != 'boolean' && isIterateeCall(lower, upper, floating)) {
|
||
upper = floating = undefined;
|
||
}
|
||
if (floating === undefined) {
|
||
if (typeof upper == 'boolean') {
|
||
floating = upper;
|
||
upper = undefined;
|
||
}
|
||
else if (typeof lower == 'boolean') {
|
||
floating = lower;
|
||
lower = undefined;
|
||
}
|
||
}
|
||
if (lower === undefined && upper === undefined) {
|
||
lower = 0;
|
||
upper = 1;
|
||
}
|
||
else {
|
||
lower = toFinite(lower);
|
||
if (upper === undefined) {
|
||
upper = lower;
|
||
lower = 0;
|
||
} else {
|
||
upper = toFinite(upper);
|
||
}
|
||
}
|
||
if (lower > upper) {
|
||
var temp = lower;
|
||
lower = upper;
|
||
upper = temp;
|
||
}
|
||
if (floating || lower % 1 || upper % 1) {
|
||
var rand = nativeRandom();
|
||
return nativeMin(lower + (rand * (upper - lower + freeParseFloat('1e-' + ((rand + '').length - 1)))), upper);
|
||
}
|
||
return baseRandom(lower, upper);
|
||
}
|
||
|
||
/*------------------------------------------------------------------------*/
|
||
|
||
/**
|
||
* Converts `string` to [camel case](https://en.wikipedia.org/wiki/CamelCase).
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 3.0.0
|
||
* @category String
|
||
* @param {string} [string=''] The string to convert.
|
||
* @returns {string} Returns the camel cased string.
|
||
* @example
|
||
*
|
||
* _.camelCase('Foo Bar');
|
||
* // => 'fooBar'
|
||
*
|
||
* _.camelCase('--foo-bar--');
|
||
* // => 'fooBar'
|
||
*
|
||
* _.camelCase('__FOO_BAR__');
|
||
* // => 'fooBar'
|
||
*/
|
||
var camelCase = createCompounder(function(result, word, index) {
|
||
word = word.toLowerCase();
|
||
return result + (index ? capitalize(word) : word);
|
||
});
|
||
|
||
/**
|
||
* Converts the first character of `string` to upper case and the remaining
|
||
* to lower case.
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 3.0.0
|
||
* @category String
|
||
* @param {string} [string=''] The string to capitalize.
|
||
* @returns {string} Returns the capitalized string.
|
||
* @example
|
||
*
|
||
* _.capitalize('FRED');
|
||
* // => 'Fred'
|
||
*/
|
||
function capitalize(string) {
|
||
return upperFirst(toString(string).toLowerCase());
|
||
}
|
||
|
||
/**
|
||
* Deburrs `string` by converting
|
||
* [Latin-1 Supplement](https://en.wikipedia.org/wiki/Latin-1_Supplement_(Unicode_block)#Character_table)
|
||
* and [Latin Extended-A](https://en.wikipedia.org/wiki/Latin_Extended-A)
|
||
* letters to basic Latin letters and removing
|
||
* [combining diacritical marks](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks).
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 3.0.0
|
||
* @category String
|
||
* @param {string} [string=''] The string to deburr.
|
||
* @returns {string} Returns the deburred string.
|
||
* @example
|
||
*
|
||
* _.deburr('déjà vu');
|
||
* // => 'deja vu'
|
||
*/
|
||
function deburr(string) {
|
||
string = toString(string);
|
||
return string && string.replace(reLatin, deburrLetter).replace(reComboMark, '');
|
||
}
|
||
|
||
/**
|
||
* Checks if `string` ends with the given target string.
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 3.0.0
|
||
* @category String
|
||
* @param {string} [string=''] The string to inspect.
|
||
* @param {string} [target] The string to search for.
|
||
* @param {number} [position=string.length] The position to search up to.
|
||
* @returns {boolean} Returns `true` if `string` ends with `target`,
|
||
* else `false`.
|
||
* @example
|
||
*
|
||
* _.endsWith('abc', 'c');
|
||
* // => true
|
||
*
|
||
* _.endsWith('abc', 'b');
|
||
* // => false
|
||
*
|
||
* _.endsWith('abc', 'b', 2);
|
||
* // => true
|
||
*/
|
||
function endsWith(string, target, position) {
|
||
string = toString(string);
|
||
target = baseToString(target);
|
||
|
||
var length = string.length;
|
||
position = position === undefined
|
||
? length
|
||
: baseClamp(toInteger(position), 0, length);
|
||
|
||
var end = position;
|
||
position -= target.length;
|
||
return position >= 0 && string.slice(position, end) == target;
|
||
}
|
||
|
||
/**
|
||
* Converts the characters "&", "<", ">", '"', and "'" in `string` to their
|
||
* corresponding HTML entities.
|
||
*
|
||
* **Note:** No other characters are escaped. To escape additional
|
||
* characters use a third-party library like [_he_](https://mths.be/he).
|
||
*
|
||
* Though the ">" character is escaped for symmetry, characters like
|
||
* ">" and "/" don't need escaping in HTML and have no special meaning
|
||
* unless they're part of a tag or unquoted attribute value. See
|
||
* [Mathias Bynens's article](https://mathiasbynens.be/notes/ambiguous-ampersands)
|
||
* (under "semi-related fun fact") for more details.
|
||
*
|
||
* When working with HTML you should always
|
||
* [quote attribute values](http://wonko.com/post/html-escaping) to reduce
|
||
* XSS vectors.
|
||
*
|
||
* @static
|
||
* @since 0.1.0
|
||
* @memberOf _
|
||
* @category String
|
||
* @param {string} [string=''] The string to escape.
|
||
* @returns {string} Returns the escaped string.
|
||
* @example
|
||
*
|
||
* _.escape('fred, barney, & pebbles');
|
||
* // => 'fred, barney, & pebbles'
|
||
*/
|
||
function escape(string) {
|
||
string = toString(string);
|
||
return (string && reHasUnescapedHtml.test(string))
|
||
? string.replace(reUnescapedHtml, escapeHtmlChar)
|
||
: string;
|
||
}
|
||
|
||
/**
|
||
* Escapes the `RegExp` special characters "^", "$", "\", ".", "*", "+",
|
||
* "?", "(", ")", "[", "]", "{", "}", and "|" in `string`.
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 3.0.0
|
||
* @category String
|
||
* @param {string} [string=''] The string to escape.
|
||
* @returns {string} Returns the escaped string.
|
||
* @example
|
||
*
|
||
* _.escapeRegExp('[lodash](https://lodash.com/)');
|
||
* // => '\[lodash\]\(https://lodash\.com/\)'
|
||
*/
|
||
function escapeRegExp(string) {
|
||
string = toString(string);
|
||
return (string && reHasRegExpChar.test(string))
|
||
? string.replace(reRegExpChar, '\\$&')
|
||
: string;
|
||
}
|
||
|
||
/**
|
||
* Converts `string` to
|
||
* [kebab case](https://en.wikipedia.org/wiki/Letter_case#Special_case_styles).
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 3.0.0
|
||
* @category String
|
||
* @param {string} [string=''] The string to convert.
|
||
* @returns {string} Returns the kebab cased string.
|
||
* @example
|
||
*
|
||
* _.kebabCase('Foo Bar');
|
||
* // => 'foo-bar'
|
||
*
|
||
* _.kebabCase('fooBar');
|
||
* // => 'foo-bar'
|
||
*
|
||
* _.kebabCase('__FOO_BAR__');
|
||
* // => 'foo-bar'
|
||
*/
|
||
var kebabCase = createCompounder(function(result, word, index) {
|
||
return result + (index ? '-' : '') + word.toLowerCase();
|
||
});
|
||
|
||
/**
|
||
* Converts `string`, as space separated words, to lower case.
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 4.0.0
|
||
* @category String
|
||
* @param {string} [string=''] The string to convert.
|
||
* @returns {string} Returns the lower cased string.
|
||
* @example
|
||
*
|
||
* _.lowerCase('--Foo-Bar--');
|
||
* // => 'foo bar'
|
||
*
|
||
* _.lowerCase('fooBar');
|
||
* // => 'foo bar'
|
||
*
|
||
* _.lowerCase('__FOO_BAR__');
|
||
* // => 'foo bar'
|
||
*/
|
||
var lowerCase = createCompounder(function(result, word, index) {
|
||
return result + (index ? ' ' : '') + word.toLowerCase();
|
||
});
|
||
|
||
/**
|
||
* Converts the first character of `string` to lower case.
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 4.0.0
|
||
* @category String
|
||
* @param {string} [string=''] The string to convert.
|
||
* @returns {string} Returns the converted string.
|
||
* @example
|
||
*
|
||
* _.lowerFirst('Fred');
|
||
* // => 'fred'
|
||
*
|
||
* _.lowerFirst('FRED');
|
||
* // => 'fRED'
|
||
*/
|
||
var lowerFirst = createCaseFirst('toLowerCase');
|
||
|
||
/**
|
||
* Pads `string` on the left and right sides if it's shorter than `length`.
|
||
* Padding characters are truncated if they can't be evenly divided by `length`.
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 3.0.0
|
||
* @category String
|
||
* @param {string} [string=''] The string to pad.
|
||
* @param {number} [length=0] The padding length.
|
||
* @param {string} [chars=' '] The string used as padding.
|
||
* @returns {string} Returns the padded string.
|
||
* @example
|
||
*
|
||
* _.pad('abc', 8);
|
||
* // => ' abc '
|
||
*
|
||
* _.pad('abc', 8, '_-');
|
||
* // => '_-abc_-_'
|
||
*
|
||
* _.pad('abc', 3);
|
||
* // => 'abc'
|
||
*/
|
||
function pad(string, length, chars) {
|
||
string = toString(string);
|
||
length = toInteger(length);
|
||
|
||
var strLength = length ? stringSize(string) : 0;
|
||
if (!length || strLength >= length) {
|
||
return string;
|
||
}
|
||
var mid = (length - strLength) / 2;
|
||
return (
|
||
createPadding(nativeFloor(mid), chars) +
|
||
string +
|
||
createPadding(nativeCeil(mid), chars)
|
||
);
|
||
}
|
||
|
||
/**
|
||
* Pads `string` on the right side if it's shorter than `length`. Padding
|
||
* characters are truncated if they exceed `length`.
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 4.0.0
|
||
* @category String
|
||
* @param {string} [string=''] The string to pad.
|
||
* @param {number} [length=0] The padding length.
|
||
* @param {string} [chars=' '] The string used as padding.
|
||
* @returns {string} Returns the padded string.
|
||
* @example
|
||
*
|
||
* _.padEnd('abc', 6);
|
||
* // => 'abc '
|
||
*
|
||
* _.padEnd('abc', 6, '_-');
|
||
* // => 'abc_-_'
|
||
*
|
||
* _.padEnd('abc', 3);
|
||
* // => 'abc'
|
||
*/
|
||
function padEnd(string, length, chars) {
|
||
string = toString(string);
|
||
length = toInteger(length);
|
||
|
||
var strLength = length ? stringSize(string) : 0;
|
||
return (length && strLength < length)
|
||
? (string + createPadding(length - strLength, chars))
|
||
: string;
|
||
}
|
||
|
||
/**
|
||
* Pads `string` on the left side if it's shorter than `length`. Padding
|
||
* characters are truncated if they exceed `length`.
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 4.0.0
|
||
* @category String
|
||
* @param {string} [string=''] The string to pad.
|
||
* @param {number} [length=0] The padding length.
|
||
* @param {string} [chars=' '] The string used as padding.
|
||
* @returns {string} Returns the padded string.
|
||
* @example
|
||
*
|
||
* _.padStart('abc', 6);
|
||
* // => ' abc'
|
||
*
|
||
* _.padStart('abc', 6, '_-');
|
||
* // => '_-_abc'
|
||
*
|
||
* _.padStart('abc', 3);
|
||
* // => 'abc'
|
||
*/
|
||
function padStart(string, length, chars) {
|
||
string = toString(string);
|
||
length = toInteger(length);
|
||
|
||
var strLength = length ? stringSize(string) : 0;
|
||
return (length && strLength < length)
|
||
? (createPadding(length - strLength, chars) + string)
|
||
: string;
|
||
}
|
||
|
||
/**
|
||
* Converts `string` to an integer of the specified radix. If `radix` is
|
||
* `undefined` or `0`, a `radix` of `10` is used unless `value` is a
|
||
* hexadecimal, in which case a `radix` of `16` is used.
|
||
*
|
||
* **Note:** This method aligns with the
|
||
* [ES5 implementation](https://es5.github.io/#x15.1.2.2) of `parseInt`.
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 1.1.0
|
||
* @category String
|
||
* @param {string} string The string to convert.
|
||
* @param {number} [radix=10] The radix to interpret `value` by.
|
||
* @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
|
||
* @returns {number} Returns the converted integer.
|
||
* @example
|
||
*
|
||
* _.parseInt('08');
|
||
* // => 8
|
||
*
|
||
* _.map(['6', '08', '10'], _.parseInt);
|
||
* // => [6, 8, 10]
|
||
*/
|
||
function parseInt(string, radix, guard) {
|
||
if (guard || radix == null) {
|
||
radix = 0;
|
||
} else if (radix) {
|
||
radix = +radix;
|
||
}
|
||
return nativeParseInt(toString(string).replace(reTrimStart, ''), radix || 0);
|
||
}
|
||
|
||
/**
|
||
* Repeats the given string `n` times.
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 3.0.0
|
||
* @category String
|
||
* @param {string} [string=''] The string to repeat.
|
||
* @param {number} [n=1] The number of times to repeat the string.
|
||
* @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
|
||
* @returns {string} Returns the repeated string.
|
||
* @example
|
||
*
|
||
* _.repeat('*', 3);
|
||
* // => '***'
|
||
*
|
||
* _.repeat('abc', 2);
|
||
* // => 'abcabc'
|
||
*
|
||
* _.repeat('abc', 0);
|
||
* // => ''
|
||
*/
|
||
function repeat(string, n, guard) {
|
||
if ((guard ? isIterateeCall(string, n, guard) : n === undefined)) {
|
||
n = 1;
|
||
} else {
|
||
n = toInteger(n);
|
||
}
|
||
return baseRepeat(toString(string), n);
|
||
}
|
||
|
||
/**
|
||
* Replaces matches for `pattern` in `string` with `replacement`.
|
||
*
|
||
* **Note:** This method is based on
|
||
* [`String#replace`](https://mdn.io/String/replace).
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 4.0.0
|
||
* @category String
|
||
* @param {string} [string=''] The string to modify.
|
||
* @param {RegExp|string} pattern The pattern to replace.
|
||
* @param {Function|string} replacement The match replacement.
|
||
* @returns {string} Returns the modified string.
|
||
* @example
|
||
*
|
||
* _.replace('Hi Fred', 'Fred', 'Barney');
|
||
* // => 'Hi Barney'
|
||
*/
|
||
function replace() {
|
||
var args = arguments,
|
||
string = toString(args[0]);
|
||
|
||
return args.length < 3 ? string : string.replace(args[1], args[2]);
|
||
}
|
||
|
||
/**
|
||
* Converts `string` to
|
||
* [snake case](https://en.wikipedia.org/wiki/Snake_case).
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 3.0.0
|
||
* @category String
|
||
* @param {string} [string=''] The string to convert.
|
||
* @returns {string} Returns the snake cased string.
|
||
* @example
|
||
*
|
||
* _.snakeCase('Foo Bar');
|
||
* // => 'foo_bar'
|
||
*
|
||
* _.snakeCase('fooBar');
|
||
* // => 'foo_bar'
|
||
*
|
||
* _.snakeCase('--FOO-BAR--');
|
||
* // => 'foo_bar'
|
||
*/
|
||
var snakeCase = createCompounder(function(result, word, index) {
|
||
return result + (index ? '_' : '') + word.toLowerCase();
|
||
});
|
||
|
||
/**
|
||
* Splits `string` by `separator`.
|
||
*
|
||
* **Note:** This method is based on
|
||
* [`String#split`](https://mdn.io/String/split).
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 4.0.0
|
||
* @category String
|
||
* @param {string} [string=''] The string to split.
|
||
* @param {RegExp|string} separator The separator pattern to split by.
|
||
* @param {number} [limit] The length to truncate results to.
|
||
* @returns {Array} Returns the string segments.
|
||
* @example
|
||
*
|
||
* _.split('a-b-c', '-', 2);
|
||
* // => ['a', 'b']
|
||
*/
|
||
function split(string, separator, limit) {
|
||
if (limit && typeof limit != 'number' && isIterateeCall(string, separator, limit)) {
|
||
separator = limit = undefined;
|
||
}
|
||
limit = limit === undefined ? MAX_ARRAY_LENGTH : limit >>> 0;
|
||
if (!limit) {
|
||
return [];
|
||
}
|
||
string = toString(string);
|
||
if (string && (
|
||
typeof separator == 'string' ||
|
||
(separator != null && !isRegExp(separator))
|
||
)) {
|
||
separator = baseToString(separator);
|
||
if (!separator && hasUnicode(string)) {
|
||
return castSlice(stringToArray(string), 0, limit);
|
||
}
|
||
}
|
||
return string.split(separator, limit);
|
||
}
|
||
|
||
/**
|
||
* Converts `string` to
|
||
* [start case](https://en.wikipedia.org/wiki/Letter_case#Stylistic_or_specialised_usage).
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 3.1.0
|
||
* @category String
|
||
* @param {string} [string=''] The string to convert.
|
||
* @returns {string} Returns the start cased string.
|
||
* @example
|
||
*
|
||
* _.startCase('--foo-bar--');
|
||
* // => 'Foo Bar'
|
||
*
|
||
* _.startCase('fooBar');
|
||
* // => 'Foo Bar'
|
||
*
|
||
* _.startCase('__FOO_BAR__');
|
||
* // => 'FOO BAR'
|
||
*/
|
||
var startCase = createCompounder(function(result, word, index) {
|
||
return result + (index ? ' ' : '') + upperFirst(word);
|
||
});
|
||
|
||
/**
|
||
* Checks if `string` starts with the given target string.
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 3.0.0
|
||
* @category String
|
||
* @param {string} [string=''] The string to inspect.
|
||
* @param {string} [target] The string to search for.
|
||
* @param {number} [position=0] The position to search from.
|
||
* @returns {boolean} Returns `true` if `string` starts with `target`,
|
||
* else `false`.
|
||
* @example
|
||
*
|
||
* _.startsWith('abc', 'a');
|
||
* // => true
|
||
*
|
||
* _.startsWith('abc', 'b');
|
||
* // => false
|
||
*
|
||
* _.startsWith('abc', 'b', 1);
|
||
* // => true
|
||
*/
|
||
function startsWith(string, target, position) {
|
||
string = toString(string);
|
||
position = position == null
|
||
? 0
|
||
: baseClamp(toInteger(position), 0, string.length);
|
||
|
||
target = baseToString(target);
|
||
return string.slice(position, position + target.length) == target;
|
||
}
|
||
|
||
/**
|
||
* Creates a compiled template function that can interpolate data properties
|
||
* in "interpolate" delimiters, HTML-escape interpolated data properties in
|
||
* "escape" delimiters, and execute JavaScript in "evaluate" delimiters. Data
|
||
* properties may be accessed as free variables in the template. If a setting
|
||
* object is given, it takes precedence over `_.templateSettings` values.
|
||
*
|
||
* **Note:** In the development build `_.template` utilizes
|
||
* [sourceURLs](http://www.html5rocks.com/en/tutorials/developertools/sourcemaps/#toc-sourceurl)
|
||
* for easier debugging.
|
||
*
|
||
* For more information on precompiling templates see
|
||
* [lodash's custom builds documentation](https://lodash.com/custom-builds).
|
||
*
|
||
* For more information on Chrome extension sandboxes see
|
||
* [Chrome's extensions documentation](https://developer.chrome.com/extensions/sandboxingEval).
|
||
*
|
||
* @static
|
||
* @since 0.1.0
|
||
* @memberOf _
|
||
* @category String
|
||
* @param {string} [string=''] The template string.
|
||
* @param {Object} [options={}] The options object.
|
||
* @param {RegExp} [options.escape=_.templateSettings.escape]
|
||
* The HTML "escape" delimiter.
|
||
* @param {RegExp} [options.evaluate=_.templateSettings.evaluate]
|
||
* The "evaluate" delimiter.
|
||
* @param {Object} [options.imports=_.templateSettings.imports]
|
||
* An object to import into the template as free variables.
|
||
* @param {RegExp} [options.interpolate=_.templateSettings.interpolate]
|
||
* The "interpolate" delimiter.
|
||
* @param {string} [options.sourceURL='lodash.templateSources[n]']
|
||
* The sourceURL of the compiled template.
|
||
* @param {string} [options.variable='obj']
|
||
* The data object variable name.
|
||
* @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
|
||
* @returns {Function} Returns the compiled template function.
|
||
* @example
|
||
*
|
||
* // Use the "interpolate" delimiter to create a compiled template.
|
||
* var compiled = _.template('hello <%= user %>!');
|
||
* compiled({ 'user': 'fred' });
|
||
* // => 'hello fred!'
|
||
*
|
||
* // Use the HTML "escape" delimiter to escape data property values.
|
||
* var compiled = _.template('<b><%- value %></b>');
|
||
* compiled({ 'value': '<script>' });
|
||
* // => '<b><script></b>'
|
||
*
|
||
* // Use the "evaluate" delimiter to execute JavaScript and generate HTML.
|
||
* var compiled = _.template('<% _.forEach(users, function(user) { %><li><%- user %></li><% }); %>');
|
||
* compiled({ 'users': ['fred', 'barney'] });
|
||
* // => '<li>fred</li><li>barney</li>'
|
||
*
|
||
* // Use the internal `print` function in "evaluate" delimiters.
|
||
* var compiled = _.template('<% print("hello " + user); %>!');
|
||
* compiled({ 'user': 'barney' });
|
||
* // => 'hello barney!'
|
||
*
|
||
* // Use the ES template literal delimiter as an "interpolate" delimiter.
|
||
* // Disable support by replacing the "interpolate" delimiter.
|
||
* var compiled = _.template('hello ${ user }!');
|
||
* compiled({ 'user': 'pebbles' });
|
||
* // => 'hello pebbles!'
|
||
*
|
||
* // Use backslashes to treat delimiters as plain text.
|
||
* var compiled = _.template('<%= "\\<%- value %\\>" %>');
|
||
* compiled({ 'value': 'ignored' });
|
||
* // => '<%- value %>'
|
||
*
|
||
* // Use the `imports` option to import `jQuery` as `jq`.
|
||
* var text = '<% jq.each(users, function(user) { %><li><%- user %></li><% }); %>';
|
||
* var compiled = _.template(text, { 'imports': { 'jq': jQuery } });
|
||
* compiled({ 'users': ['fred', 'barney'] });
|
||
* // => '<li>fred</li><li>barney</li>'
|
||
*
|
||
* // Use the `sourceURL` option to specify a custom sourceURL for the template.
|
||
* var compiled = _.template('hello <%= user %>!', { 'sourceURL': '/basic/greeting.jst' });
|
||
* compiled(data);
|
||
* // => Find the source of "greeting.jst" under the Sources tab or Resources panel of the web inspector.
|
||
*
|
||
* // Use the `variable` option to ensure a with-statement isn't used in the compiled template.
|
||
* var compiled = _.template('hi <%= data.user %>!', { 'variable': 'data' });
|
||
* compiled.source;
|
||
* // => function(data) {
|
||
* // var __t, __p = '';
|
||
* // __p += 'hi ' + ((__t = ( data.user )) == null ? '' : __t) + '!';
|
||
* // return __p;
|
||
* // }
|
||
*
|
||
* // Use custom template delimiters.
|
||
* _.templateSettings.interpolate = /{{([\s\S]+?)}}/g;
|
||
* var compiled = _.template('hello {{ user }}!');
|
||
* compiled({ 'user': 'mustache' });
|
||
* // => 'hello mustache!'
|
||
*
|
||
* // Use the `source` property to inline compiled templates for meaningful
|
||
* // line numbers in error messages and stack traces.
|
||
* fs.writeFileSync(path.join(process.cwd(), 'jst.js'), '\
|
||
* var JST = {\
|
||
* "main": ' + _.template(mainText).source + '\
|
||
* };\
|
||
* ');
|
||
*/
|
||
function template(string, options, guard) {
|
||
// Based on John Resig's `tmpl` implementation
|
||
// (http://ejohn.org/blog/javascript-micro-templating/)
|
||
// and Laura Doktorova's doT.js (https://github.com/olado/doT).
|
||
var settings = lodash.templateSettings;
|
||
|
||
if (guard && isIterateeCall(string, options, guard)) {
|
||
options = undefined;
|
||
}
|
||
string = toString(string);
|
||
options = assignInWith({}, options, settings, customDefaultsAssignIn);
|
||
|
||
var imports = assignInWith({}, options.imports, settings.imports, customDefaultsAssignIn),
|
||
importsKeys = keys(imports),
|
||
importsValues = baseValues(imports, importsKeys);
|
||
|
||
var isEscaping,
|
||
isEvaluating,
|
||
index = 0,
|
||
interpolate = options.interpolate || reNoMatch,
|
||
source = "__p += '";
|
||
|
||
// Compile the regexp to match each delimiter.
|
||
var reDelimiters = RegExp(
|
||
(options.escape || reNoMatch).source + '|' +
|
||
interpolate.source + '|' +
|
||
(interpolate === reInterpolate ? reEsTemplate : reNoMatch).source + '|' +
|
||
(options.evaluate || reNoMatch).source + '|$'
|
||
, 'g');
|
||
|
||
// Use a sourceURL for easier debugging.
|
||
var sourceURL = '//# sourceURL=' +
|
||
('sourceURL' in options
|
||
? options.sourceURL
|
||
: ('lodash.templateSources[' + (++templateCounter) + ']')
|
||
) + '\n';
|
||
|
||
string.replace(reDelimiters, function(match, escapeValue, interpolateValue, esTemplateValue, evaluateValue, offset) {
|
||
interpolateValue || (interpolateValue = esTemplateValue);
|
||
|
||
// Escape characters that can't be included in string literals.
|
||
source += string.slice(index, offset).replace(reUnescapedString, escapeStringChar);
|
||
|
||
// Replace delimiters with snippets.
|
||
if (escapeValue) {
|
||
isEscaping = true;
|
||
source += "' +\n__e(" + escapeValue + ") +\n'";
|
||
}
|
||
if (evaluateValue) {
|
||
isEvaluating = true;
|
||
source += "';\n" + evaluateValue + ";\n__p += '";
|
||
}
|
||
if (interpolateValue) {
|
||
source += "' +\n((__t = (" + interpolateValue + ")) == null ? '' : __t) +\n'";
|
||
}
|
||
index = offset + match.length;
|
||
|
||
// The JS engine embedded in Adobe products needs `match` returned in
|
||
// order to produce the correct `offset` value.
|
||
return match;
|
||
});
|
||
|
||
source += "';\n";
|
||
|
||
// If `variable` is not specified wrap a with-statement around the generated
|
||
// code to add the data object to the top of the scope chain.
|
||
var variable = options.variable;
|
||
if (!variable) {
|
||
source = 'with (obj) {\n' + source + '\n}\n';
|
||
}
|
||
// Cleanup code by stripping empty strings.
|
||
source = (isEvaluating ? source.replace(reEmptyStringLeading, '') : source)
|
||
.replace(reEmptyStringMiddle, '$1')
|
||
.replace(reEmptyStringTrailing, '$1;');
|
||
|
||
// Frame code as the function body.
|
||
source = 'function(' + (variable || 'obj') + ') {\n' +
|
||
(variable
|
||
? ''
|
||
: 'obj || (obj = {});\n'
|
||
) +
|
||
"var __t, __p = ''" +
|
||
(isEscaping
|
||
? ', __e = _.escape'
|
||
: ''
|
||
) +
|
||
(isEvaluating
|
||
? ', __j = Array.prototype.join;\n' +
|
||
"function print() { __p += __j.call(arguments, '') }\n"
|
||
: ';\n'
|
||
) +
|
||
source +
|
||
'return __p\n}';
|
||
|
||
var result = attempt(function() {
|
||
return Function(importsKeys, sourceURL + 'return ' + source)
|
||
.apply(undefined, importsValues);
|
||
});
|
||
|
||
// Provide the compiled function's source by its `toString` method or
|
||
// the `source` property as a convenience for inlining compiled templates.
|
||
result.source = source;
|
||
if (isError(result)) {
|
||
throw result;
|
||
}
|
||
return result;
|
||
}
|
||
|
||
/**
|
||
* Converts `string`, as a whole, to lower case just like
|
||
* [String#toLowerCase](https://mdn.io/toLowerCase).
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 4.0.0
|
||
* @category String
|
||
* @param {string} [string=''] The string to convert.
|
||
* @returns {string} Returns the lower cased string.
|
||
* @example
|
||
*
|
||
* _.toLower('--Foo-Bar--');
|
||
* // => '--foo-bar--'
|
||
*
|
||
* _.toLower('fooBar');
|
||
* // => 'foobar'
|
||
*
|
||
* _.toLower('__FOO_BAR__');
|
||
* // => '__foo_bar__'
|
||
*/
|
||
function toLower(value) {
|
||
return toString(value).toLowerCase();
|
||
}
|
||
|
||
/**
|
||
* Converts `string`, as a whole, to upper case just like
|
||
* [String#toUpperCase](https://mdn.io/toUpperCase).
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 4.0.0
|
||
* @category String
|
||
* @param {string} [string=''] The string to convert.
|
||
* @returns {string} Returns the upper cased string.
|
||
* @example
|
||
*
|
||
* _.toUpper('--foo-bar--');
|
||
* // => '--FOO-BAR--'
|
||
*
|
||
* _.toUpper('fooBar');
|
||
* // => 'FOOBAR'
|
||
*
|
||
* _.toUpper('__foo_bar__');
|
||
* // => '__FOO_BAR__'
|
||
*/
|
||
function toUpper(value) {
|
||
return toString(value).toUpperCase();
|
||
}
|
||
|
||
/**
|
||
* Removes leading and trailing whitespace or specified characters from `string`.
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 3.0.0
|
||
* @category String
|
||
* @param {string} [string=''] The string to trim.
|
||
* @param {string} [chars=whitespace] The characters to trim.
|
||
* @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
|
||
* @returns {string} Returns the trimmed string.
|
||
* @example
|
||
*
|
||
* _.trim(' abc ');
|
||
* // => 'abc'
|
||
*
|
||
* _.trim('-_-abc-_-', '_-');
|
||
* // => 'abc'
|
||
*
|
||
* _.map([' foo ', ' bar '], _.trim);
|
||
* // => ['foo', 'bar']
|
||
*/
|
||
function trim(string, chars, guard) {
|
||
string = toString(string);
|
||
if (string && (guard || chars === undefined)) {
|
||
return string.replace(reTrim, '');
|
||
}
|
||
if (!string || !(chars = baseToString(chars))) {
|
||
return string;
|
||
}
|
||
var strSymbols = stringToArray(string),
|
||
chrSymbols = stringToArray(chars),
|
||
start = charsStartIndex(strSymbols, chrSymbols),
|
||
end = charsEndIndex(strSymbols, chrSymbols) + 1;
|
||
|
||
return castSlice(strSymbols, start, end).join('');
|
||
}
|
||
|
||
/**
|
||
* Removes trailing whitespace or specified characters from `string`.
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 4.0.0
|
||
* @category String
|
||
* @param {string} [string=''] The string to trim.
|
||
* @param {string} [chars=whitespace] The characters to trim.
|
||
* @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
|
||
* @returns {string} Returns the trimmed string.
|
||
* @example
|
||
*
|
||
* _.trimEnd(' abc ');
|
||
* // => ' abc'
|
||
*
|
||
* _.trimEnd('-_-abc-_-', '_-');
|
||
* // => '-_-abc'
|
||
*/
|
||
function trimEnd(string, chars, guard) {
|
||
string = toString(string);
|
||
if (string && (guard || chars === undefined)) {
|
||
return string.replace(reTrimEnd, '');
|
||
}
|
||
if (!string || !(chars = baseToString(chars))) {
|
||
return string;
|
||
}
|
||
var strSymbols = stringToArray(string),
|
||
end = charsEndIndex(strSymbols, stringToArray(chars)) + 1;
|
||
|
||
return castSlice(strSymbols, 0, end).join('');
|
||
}
|
||
|
||
/**
|
||
* Removes leading whitespace or specified characters from `string`.
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 4.0.0
|
||
* @category String
|
||
* @param {string} [string=''] The string to trim.
|
||
* @param {string} [chars=whitespace] The characters to trim.
|
||
* @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
|
||
* @returns {string} Returns the trimmed string.
|
||
* @example
|
||
*
|
||
* _.trimStart(' abc ');
|
||
* // => 'abc '
|
||
*
|
||
* _.trimStart('-_-abc-_-', '_-');
|
||
* // => 'abc-_-'
|
||
*/
|
||
function trimStart(string, chars, guard) {
|
||
string = toString(string);
|
||
if (string && (guard || chars === undefined)) {
|
||
return string.replace(reTrimStart, '');
|
||
}
|
||
if (!string || !(chars = baseToString(chars))) {
|
||
return string;
|
||
}
|
||
var strSymbols = stringToArray(string),
|
||
start = charsStartIndex(strSymbols, stringToArray(chars));
|
||
|
||
return castSlice(strSymbols, start).join('');
|
||
}
|
||
|
||
/**
|
||
* Truncates `string` if it's longer than the given maximum string length.
|
||
* The last characters of the truncated string are replaced with the omission
|
||
* string which defaults to "...".
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 4.0.0
|
||
* @category String
|
||
* @param {string} [string=''] The string to truncate.
|
||
* @param {Object} [options={}] The options object.
|
||
* @param {number} [options.length=30] The maximum string length.
|
||
* @param {string} [options.omission='...'] The string to indicate text is omitted.
|
||
* @param {RegExp|string} [options.separator] The separator pattern to truncate to.
|
||
* @returns {string} Returns the truncated string.
|
||
* @example
|
||
*
|
||
* _.truncate('hi-diddly-ho there, neighborino');
|
||
* // => 'hi-diddly-ho there, neighbo...'
|
||
*
|
||
* _.truncate('hi-diddly-ho there, neighborino', {
|
||
* 'length': 24,
|
||
* 'separator': ' '
|
||
* });
|
||
* // => 'hi-diddly-ho there,...'
|
||
*
|
||
* _.truncate('hi-diddly-ho there, neighborino', {
|
||
* 'length': 24,
|
||
* 'separator': /,? +/
|
||
* });
|
||
* // => 'hi-diddly-ho there...'
|
||
*
|
||
* _.truncate('hi-diddly-ho there, neighborino', {
|
||
* 'omission': ' [...]'
|
||
* });
|
||
* // => 'hi-diddly-ho there, neig [...]'
|
||
*/
|
||
function truncate(string, options) {
|
||
var length = DEFAULT_TRUNC_LENGTH,
|
||
omission = DEFAULT_TRUNC_OMISSION;
|
||
|
||
if (isObject(options)) {
|
||
var separator = 'separator' in options ? options.separator : separator;
|
||
length = 'length' in options ? toInteger(options.length) : length;
|
||
omission = 'omission' in options ? baseToString(options.omission) : omission;
|
||
}
|
||
string = toString(string);
|
||
|
||
var strLength = string.length;
|
||
if (hasUnicode(string)) {
|
||
var strSymbols = stringToArray(string);
|
||
strLength = strSymbols.length;
|
||
}
|
||
if (length >= strLength) {
|
||
return string;
|
||
}
|
||
var end = length - stringSize(omission);
|
||
if (end < 1) {
|
||
return omission;
|
||
}
|
||
var result = strSymbols
|
||
? castSlice(strSymbols, 0, end).join('')
|
||
: string.slice(0, end);
|
||
|
||
if (separator === undefined) {
|
||
return result + omission;
|
||
}
|
||
if (strSymbols) {
|
||
end += (result.length - end);
|
||
}
|
||
if (isRegExp(separator)) {
|
||
if (string.slice(end).search(separator)) {
|
||
var match,
|
||
substring = result;
|
||
|
||
if (!separator.global) {
|
||
separator = RegExp(separator.source, toString(reFlags.exec(separator)) + 'g');
|
||
}
|
||
separator.lastIndex = 0;
|
||
while ((match = separator.exec(substring))) {
|
||
var newEnd = match.index;
|
||
}
|
||
result = result.slice(0, newEnd === undefined ? end : newEnd);
|
||
}
|
||
} else if (string.indexOf(baseToString(separator), end) != end) {
|
||
var index = result.lastIndexOf(separator);
|
||
if (index > -1) {
|
||
result = result.slice(0, index);
|
||
}
|
||
}
|
||
return result + omission;
|
||
}
|
||
|
||
/**
|
||
* The inverse of `_.escape`; this method converts the HTML entities
|
||
* `&`, `<`, `>`, `"`, and `'` in `string` to
|
||
* their corresponding characters.
|
||
*
|
||
* **Note:** No other HTML entities are unescaped. To unescape additional
|
||
* HTML entities use a third-party library like [_he_](https://mths.be/he).
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 0.6.0
|
||
* @category String
|
||
* @param {string} [string=''] The string to unescape.
|
||
* @returns {string} Returns the unescaped string.
|
||
* @example
|
||
*
|
||
* _.unescape('fred, barney, & pebbles');
|
||
* // => 'fred, barney, & pebbles'
|
||
*/
|
||
function unescape(string) {
|
||
string = toString(string);
|
||
return (string && reHasEscapedHtml.test(string))
|
||
? string.replace(reEscapedHtml, unescapeHtmlChar)
|
||
: string;
|
||
}
|
||
|
||
/**
|
||
* Converts `string`, as space separated words, to upper case.
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 4.0.0
|
||
* @category String
|
||
* @param {string} [string=''] The string to convert.
|
||
* @returns {string} Returns the upper cased string.
|
||
* @example
|
||
*
|
||
* _.upperCase('--foo-bar');
|
||
* // => 'FOO BAR'
|
||
*
|
||
* _.upperCase('fooBar');
|
||
* // => 'FOO BAR'
|
||
*
|
||
* _.upperCase('__foo_bar__');
|
||
* // => 'FOO BAR'
|
||
*/
|
||
var upperCase = createCompounder(function(result, word, index) {
|
||
return result + (index ? ' ' : '') + word.toUpperCase();
|
||
});
|
||
|
||
/**
|
||
* Converts the first character of `string` to upper case.
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 4.0.0
|
||
* @category String
|
||
* @param {string} [string=''] The string to convert.
|
||
* @returns {string} Returns the converted string.
|
||
* @example
|
||
*
|
||
* _.upperFirst('fred');
|
||
* // => 'Fred'
|
||
*
|
||
* _.upperFirst('FRED');
|
||
* // => 'FRED'
|
||
*/
|
||
var upperFirst = createCaseFirst('toUpperCase');
|
||
|
||
/**
|
||
* Splits `string` into an array of its words.
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 3.0.0
|
||
* @category String
|
||
* @param {string} [string=''] The string to inspect.
|
||
* @param {RegExp|string} [pattern] The pattern to match words.
|
||
* @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
|
||
* @returns {Array} Returns the words of `string`.
|
||
* @example
|
||
*
|
||
* _.words('fred, barney, & pebbles');
|
||
* // => ['fred', 'barney', 'pebbles']
|
||
*
|
||
* _.words('fred, barney, & pebbles', /[^, ]+/g);
|
||
* // => ['fred', 'barney', '&', 'pebbles']
|
||
*/
|
||
function words(string, pattern, guard) {
|
||
string = toString(string);
|
||
pattern = guard ? undefined : pattern;
|
||
|
||
if (pattern === undefined) {
|
||
return hasUnicodeWord(string) ? unicodeWords(string) : asciiWords(string);
|
||
}
|
||
return string.match(pattern) || [];
|
||
}
|
||
|
||
/*------------------------------------------------------------------------*/
|
||
|
||
/**
|
||
* Attempts to invoke `func`, returning either the result or the caught error
|
||
* object. Any additional arguments are provided to `func` when it's invoked.
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 3.0.0
|
||
* @category Util
|
||
* @param {Function} func The function to attempt.
|
||
* @param {...*} [args] The arguments to invoke `func` with.
|
||
* @returns {*} Returns the `func` result or error object.
|
||
* @example
|
||
*
|
||
* // Avoid throwing errors for invalid selectors.
|
||
* var elements = _.attempt(function(selector) {
|
||
* return document.querySelectorAll(selector);
|
||
* }, '>_>');
|
||
*
|
||
* if (_.isError(elements)) {
|
||
* elements = [];
|
||
* }
|
||
*/
|
||
var attempt = baseRest(function(func, args) {
|
||
try {
|
||
return apply(func, undefined, args);
|
||
} catch (e) {
|
||
return isError(e) ? e : new Error(e);
|
||
}
|
||
});
|
||
|
||
/**
|
||
* Binds methods of an object to the object itself, overwriting the existing
|
||
* method.
|
||
*
|
||
* **Note:** This method doesn't set the "length" property of bound functions.
|
||
*
|
||
* @static
|
||
* @since 0.1.0
|
||
* @memberOf _
|
||
* @category Util
|
||
* @param {Object} object The object to bind and assign the bound methods to.
|
||
* @param {...(string|string[])} methodNames The object method names to bind.
|
||
* @returns {Object} Returns `object`.
|
||
* @example
|
||
*
|
||
* var view = {
|
||
* 'label': 'docs',
|
||
* 'click': function() {
|
||
* console.log('clicked ' + this.label);
|
||
* }
|
||
* };
|
||
*
|
||
* _.bindAll(view, ['click']);
|
||
* jQuery(element).on('click', view.click);
|
||
* // => Logs 'clicked docs' when clicked.
|
||
*/
|
||
var bindAll = flatRest(function(object, methodNames) {
|
||
arrayEach(methodNames, function(key) {
|
||
key = toKey(key);
|
||
baseAssignValue(object, key, bind(object[key], object));
|
||
});
|
||
return object;
|
||
});
|
||
|
||
/**
|
||
* Creates a function that iterates over `pairs` and invokes the corresponding
|
||
* function of the first predicate to return truthy. The predicate-function
|
||
* pairs are invoked with the `this` binding and arguments of the created
|
||
* function.
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 4.0.0
|
||
* @category Util
|
||
* @param {Array} pairs The predicate-function pairs.
|
||
* @returns {Function} Returns the new composite function.
|
||
* @example
|
||
*
|
||
* var func = _.cond([
|
||
* [_.matches({ 'a': 1 }), _.constant('matches A')],
|
||
* [_.conforms({ 'b': _.isNumber }), _.constant('matches B')],
|
||
* [_.stubTrue, _.constant('no match')]
|
||
* ]);
|
||
*
|
||
* func({ 'a': 1, 'b': 2 });
|
||
* // => 'matches A'
|
||
*
|
||
* func({ 'a': 0, 'b': 1 });
|
||
* // => 'matches B'
|
||
*
|
||
* func({ 'a': '1', 'b': '2' });
|
||
* // => 'no match'
|
||
*/
|
||
function cond(pairs) {
|
||
var length = pairs == null ? 0 : pairs.length,
|
||
toIteratee = getIteratee();
|
||
|
||
pairs = !length ? [] : arrayMap(pairs, function(pair) {
|
||
if (typeof pair[1] != 'function') {
|
||
throw new TypeError(FUNC_ERROR_TEXT);
|
||
}
|
||
return [toIteratee(pair[0]), pair[1]];
|
||
});
|
||
|
||
return baseRest(function(args) {
|
||
var index = -1;
|
||
while (++index < length) {
|
||
var pair = pairs[index];
|
||
if (apply(pair[0], this, args)) {
|
||
return apply(pair[1], this, args);
|
||
}
|
||
}
|
||
});
|
||
}
|
||
|
||
/**
|
||
* Creates a function that invokes the predicate properties of `source` with
|
||
* the corresponding property values of a given object, returning `true` if
|
||
* all predicates return truthy, else `false`.
|
||
*
|
||
* **Note:** The created function is equivalent to `_.conformsTo` with
|
||
* `source` partially applied.
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 4.0.0
|
||
* @category Util
|
||
* @param {Object} source The object of property predicates to conform to.
|
||
* @returns {Function} Returns the new spec function.
|
||
* @example
|
||
*
|
||
* var objects = [
|
||
* { 'a': 2, 'b': 1 },
|
||
* { 'a': 1, 'b': 2 }
|
||
* ];
|
||
*
|
||
* _.filter(objects, _.conforms({ 'b': function(n) { return n > 1; } }));
|
||
* // => [{ 'a': 1, 'b': 2 }]
|
||
*/
|
||
function conforms(source) {
|
||
return baseConforms(baseClone(source, CLONE_DEEP_FLAG));
|
||
}
|
||
|
||
/**
|
||
* Creates a function that returns `value`.
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 2.4.0
|
||
* @category Util
|
||
* @param {*} value The value to return from the new function.
|
||
* @returns {Function} Returns the new constant function.
|
||
* @example
|
||
*
|
||
* var objects = _.times(2, _.constant({ 'a': 1 }));
|
||
*
|
||
* console.log(objects);
|
||
* // => [{ 'a': 1 }, { 'a': 1 }]
|
||
*
|
||
* console.log(objects[0] === objects[1]);
|
||
* // => true
|
||
*/
|
||
function constant(value) {
|
||
return function() {
|
||
return value;
|
||
};
|
||
}
|
||
|
||
/**
|
||
* Checks `value` to determine whether a default value should be returned in
|
||
* its place. The `defaultValue` is returned if `value` is `NaN`, `null`,
|
||
* or `undefined`.
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 4.14.0
|
||
* @category Util
|
||
* @param {*} value The value to check.
|
||
* @param {*} defaultValue The default value.
|
||
* @returns {*} Returns the resolved value.
|
||
* @example
|
||
*
|
||
* _.defaultTo(1, 10);
|
||
* // => 1
|
||
*
|
||
* _.defaultTo(undefined, 10);
|
||
* // => 10
|
||
*/
|
||
function defaultTo(value, defaultValue) {
|
||
return (value == null || value !== value) ? defaultValue : value;
|
||
}
|
||
|
||
/**
|
||
* Creates a function that returns the result of invoking the given functions
|
||
* with the `this` binding of the created function, where each successive
|
||
* invocation is supplied the return value of the previous.
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 3.0.0
|
||
* @category Util
|
||
* @param {...(Function|Function[])} [funcs] The functions to invoke.
|
||
* @returns {Function} Returns the new composite function.
|
||
* @see _.flowRight
|
||
* @example
|
||
*
|
||
* function square(n) {
|
||
* return n * n;
|
||
* }
|
||
*
|
||
* var addSquare = _.flow([_.add, square]);
|
||
* addSquare(1, 2);
|
||
* // => 9
|
||
*/
|
||
var flow = createFlow();
|
||
|
||
/**
|
||
* This method is like `_.flow` except that it creates a function that
|
||
* invokes the given functions from right to left.
|
||
*
|
||
* @static
|
||
* @since 3.0.0
|
||
* @memberOf _
|
||
* @category Util
|
||
* @param {...(Function|Function[])} [funcs] The functions to invoke.
|
||
* @returns {Function} Returns the new composite function.
|
||
* @see _.flow
|
||
* @example
|
||
*
|
||
* function square(n) {
|
||
* return n * n;
|
||
* }
|
||
*
|
||
* var addSquare = _.flowRight([square, _.add]);
|
||
* addSquare(1, 2);
|
||
* // => 9
|
||
*/
|
||
var flowRight = createFlow(true);
|
||
|
||
/**
|
||
* This method returns the first argument it receives.
|
||
*
|
||
* @static
|
||
* @since 0.1.0
|
||
* @memberOf _
|
||
* @category Util
|
||
* @param {*} value Any value.
|
||
* @returns {*} Returns `value`.
|
||
* @example
|
||
*
|
||
* var object = { 'a': 1 };
|
||
*
|
||
* console.log(_.identity(object) === object);
|
||
* // => true
|
||
*/
|
||
function identity(value) {
|
||
return value;
|
||
}
|
||
|
||
/**
|
||
* Creates a function that invokes `func` with the arguments of the created
|
||
* function. If `func` is a property name, the created function returns the
|
||
* property value for a given element. If `func` is an array or object, the
|
||
* created function returns `true` for elements that contain the equivalent
|
||
* source properties, otherwise it returns `false`.
|
||
*
|
||
* @static
|
||
* @since 4.0.0
|
||
* @memberOf _
|
||
* @category Util
|
||
* @param {*} [func=_.identity] The value to convert to a callback.
|
||
* @returns {Function} Returns the callback.
|
||
* @example
|
||
*
|
||
* var users = [
|
||
* { 'user': 'barney', 'age': 36, 'active': true },
|
||
* { 'user': 'fred', 'age': 40, 'active': false }
|
||
* ];
|
||
*
|
||
* // The `_.matches` iteratee shorthand.
|
||
* _.filter(users, _.iteratee({ 'user': 'barney', 'active': true }));
|
||
* // => [{ 'user': 'barney', 'age': 36, 'active': true }]
|
||
*
|
||
* // The `_.matchesProperty` iteratee shorthand.
|
||
* _.filter(users, _.iteratee(['user', 'fred']));
|
||
* // => [{ 'user': 'fred', 'age': 40 }]
|
||
*
|
||
* // The `_.property` iteratee shorthand.
|
||
* _.map(users, _.iteratee('user'));
|
||
* // => ['barney', 'fred']
|
||
*
|
||
* // Create custom iteratee shorthands.
|
||
* _.iteratee = _.wrap(_.iteratee, function(iteratee, func) {
|
||
* return !_.isRegExp(func) ? iteratee(func) : function(string) {
|
||
* return func.test(string);
|
||
* };
|
||
* });
|
||
*
|
||
* _.filter(['abc', 'def'], /ef/);
|
||
* // => ['def']
|
||
*/
|
||
function iteratee(func) {
|
||
return baseIteratee(typeof func == 'function' ? func : baseClone(func, CLONE_DEEP_FLAG));
|
||
}
|
||
|
||
/**
|
||
* Creates a function that performs a partial deep comparison between a given
|
||
* object and `source`, returning `true` if the given object has equivalent
|
||
* property values, else `false`.
|
||
*
|
||
* **Note:** The created function is equivalent to `_.isMatch` with `source`
|
||
* partially applied.
|
||
*
|
||
* Partial comparisons will match empty array and empty object `source`
|
||
* values against any array or object value, respectively. See `_.isEqual`
|
||
* for a list of supported value comparisons.
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 3.0.0
|
||
* @category Util
|
||
* @param {Object} source The object of property values to match.
|
||
* @returns {Function} Returns the new spec function.
|
||
* @example
|
||
*
|
||
* var objects = [
|
||
* { 'a': 1, 'b': 2, 'c': 3 },
|
||
* { 'a': 4, 'b': 5, 'c': 6 }
|
||
* ];
|
||
*
|
||
* _.filter(objects, _.matches({ 'a': 4, 'c': 6 }));
|
||
* // => [{ 'a': 4, 'b': 5, 'c': 6 }]
|
||
*/
|
||
function matches(source) {
|
||
return baseMatches(baseClone(source, CLONE_DEEP_FLAG));
|
||
}
|
||
|
||
/**
|
||
* Creates a function that performs a partial deep comparison between the
|
||
* value at `path` of a given object to `srcValue`, returning `true` if the
|
||
* object value is equivalent, else `false`.
|
||
*
|
||
* **Note:** Partial comparisons will match empty array and empty object
|
||
* `srcValue` values against any array or object value, respectively. See
|
||
* `_.isEqual` for a list of supported value comparisons.
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 3.2.0
|
||
* @category Util
|
||
* @param {Array|string} path The path of the property to get.
|
||
* @param {*} srcValue The value to match.
|
||
* @returns {Function} Returns the new spec function.
|
||
* @example
|
||
*
|
||
* var objects = [
|
||
* { 'a': 1, 'b': 2, 'c': 3 },
|
||
* { 'a': 4, 'b': 5, 'c': 6 }
|
||
* ];
|
||
*
|
||
* _.find(objects, _.matchesProperty('a', 4));
|
||
* // => { 'a': 4, 'b': 5, 'c': 6 }
|
||
*/
|
||
function matchesProperty(path, srcValue) {
|
||
return baseMatchesProperty(path, baseClone(srcValue, CLONE_DEEP_FLAG));
|
||
}
|
||
|
||
/**
|
||
* Creates a function that invokes the method at `path` of a given object.
|
||
* Any additional arguments are provided to the invoked method.
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 3.7.0
|
||
* @category Util
|
||
* @param {Array|string} path The path of the method to invoke.
|
||
* @param {...*} [args] The arguments to invoke the method with.
|
||
* @returns {Function} Returns the new invoker function.
|
||
* @example
|
||
*
|
||
* var objects = [
|
||
* { 'a': { 'b': _.constant(2) } },
|
||
* { 'a': { 'b': _.constant(1) } }
|
||
* ];
|
||
*
|
||
* _.map(objects, _.method('a.b'));
|
||
* // => [2, 1]
|
||
*
|
||
* _.map(objects, _.method(['a', 'b']));
|
||
* // => [2, 1]
|
||
*/
|
||
var method = baseRest(function(path, args) {
|
||
return function(object) {
|
||
return baseInvoke(object, path, args);
|
||
};
|
||
});
|
||
|
||
/**
|
||
* The opposite of `_.method`; this method creates a function that invokes
|
||
* the method at a given path of `object`. Any additional arguments are
|
||
* provided to the invoked method.
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 3.7.0
|
||
* @category Util
|
||
* @param {Object} object The object to query.
|
||
* @param {...*} [args] The arguments to invoke the method with.
|
||
* @returns {Function} Returns the new invoker function.
|
||
* @example
|
||
*
|
||
* var array = _.times(3, _.constant),
|
||
* object = { 'a': array, 'b': array, 'c': array };
|
||
*
|
||
* _.map(['a[2]', 'c[0]'], _.methodOf(object));
|
||
* // => [2, 0]
|
||
*
|
||
* _.map([['a', '2'], ['c', '0']], _.methodOf(object));
|
||
* // => [2, 0]
|
||
*/
|
||
var methodOf = baseRest(function(object, args) {
|
||
return function(path) {
|
||
return baseInvoke(object, path, args);
|
||
};
|
||
});
|
||
|
||
/**
|
||
* Adds all own enumerable string keyed function properties of a source
|
||
* object to the destination object. If `object` is a function, then methods
|
||
* are added to its prototype as well.
|
||
*
|
||
* **Note:** Use `_.runInContext` to create a pristine `lodash` function to
|
||
* avoid conflicts caused by modifying the original.
|
||
*
|
||
* @static
|
||
* @since 0.1.0
|
||
* @memberOf _
|
||
* @category Util
|
||
* @param {Function|Object} [object=lodash] The destination object.
|
||
* @param {Object} source The object of functions to add.
|
||
* @param {Object} [options={}] The options object.
|
||
* @param {boolean} [options.chain=true] Specify whether mixins are chainable.
|
||
* @returns {Function|Object} Returns `object`.
|
||
* @example
|
||
*
|
||
* function vowels(string) {
|
||
* return _.filter(string, function(v) {
|
||
* return /[aeiou]/i.test(v);
|
||
* });
|
||
* }
|
||
*
|
||
* _.mixin({ 'vowels': vowels });
|
||
* _.vowels('fred');
|
||
* // => ['e']
|
||
*
|
||
* _('fred').vowels().value();
|
||
* // => ['e']
|
||
*
|
||
* _.mixin({ 'vowels': vowels }, { 'chain': false });
|
||
* _('fred').vowels();
|
||
* // => ['e']
|
||
*/
|
||
function mixin(object, source, options) {
|
||
var props = keys(source),
|
||
methodNames = baseFunctions(source, props);
|
||
|
||
if (options == null &&
|
||
!(isObject(source) && (methodNames.length || !props.length))) {
|
||
options = source;
|
||
source = object;
|
||
object = this;
|
||
methodNames = baseFunctions(source, keys(source));
|
||
}
|
||
var chain = !(isObject(options) && 'chain' in options) || !!options.chain,
|
||
isFunc = isFunction(object);
|
||
|
||
arrayEach(methodNames, function(methodName) {
|
||
var func = source[methodName];
|
||
object[methodName] = func;
|
||
if (isFunc) {
|
||
object.prototype[methodName] = function() {
|
||
var chainAll = this.__chain__;
|
||
if (chain || chainAll) {
|
||
var result = object(this.__wrapped__),
|
||
actions = result.__actions__ = copyArray(this.__actions__);
|
||
|
||
actions.push({ 'func': func, 'args': arguments, 'thisArg': object });
|
||
result.__chain__ = chainAll;
|
||
return result;
|
||
}
|
||
return func.apply(object, arrayPush([this.value()], arguments));
|
||
};
|
||
}
|
||
});
|
||
|
||
return object;
|
||
}
|
||
|
||
/**
|
||
* Reverts the `_` variable to its previous value and returns a reference to
|
||
* the `lodash` function.
|
||
*
|
||
* @static
|
||
* @since 0.1.0
|
||
* @memberOf _
|
||
* @category Util
|
||
* @returns {Function} Returns the `lodash` function.
|
||
* @example
|
||
*
|
||
* var lodash = _.noConflict();
|
||
*/
|
||
function noConflict() {
|
||
if (root._ === this) {
|
||
root._ = oldDash;
|
||
}
|
||
return this;
|
||
}
|
||
|
||
/**
|
||
* This method returns `undefined`.
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 2.3.0
|
||
* @category Util
|
||
* @example
|
||
*
|
||
* _.times(2, _.noop);
|
||
* // => [undefined, undefined]
|
||
*/
|
||
function noop() {
|
||
// No operation performed.
|
||
}
|
||
|
||
/**
|
||
* Creates a function that gets the argument at index `n`. If `n` is negative,
|
||
* the nth argument from the end is returned.
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 4.0.0
|
||
* @category Util
|
||
* @param {number} [n=0] The index of the argument to return.
|
||
* @returns {Function} Returns the new pass-thru function.
|
||
* @example
|
||
*
|
||
* var func = _.nthArg(1);
|
||
* func('a', 'b', 'c', 'd');
|
||
* // => 'b'
|
||
*
|
||
* var func = _.nthArg(-2);
|
||
* func('a', 'b', 'c', 'd');
|
||
* // => 'c'
|
||
*/
|
||
function nthArg(n) {
|
||
n = toInteger(n);
|
||
return baseRest(function(args) {
|
||
return baseNth(args, n);
|
||
});
|
||
}
|
||
|
||
/**
|
||
* Creates a function that invokes `iteratees` with the arguments it receives
|
||
* and returns their results.
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 4.0.0
|
||
* @category Util
|
||
* @param {...(Function|Function[])} [iteratees=[_.identity]]
|
||
* The iteratees to invoke.
|
||
* @returns {Function} Returns the new function.
|
||
* @example
|
||
*
|
||
* var func = _.over([Math.max, Math.min]);
|
||
*
|
||
* func(1, 2, 3, 4);
|
||
* // => [4, 1]
|
||
*/
|
||
var over = createOver(arrayMap);
|
||
|
||
/**
|
||
* Creates a function that checks if **all** of the `predicates` return
|
||
* truthy when invoked with the arguments it receives.
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 4.0.0
|
||
* @category Util
|
||
* @param {...(Function|Function[])} [predicates=[_.identity]]
|
||
* The predicates to check.
|
||
* @returns {Function} Returns the new function.
|
||
* @example
|
||
*
|
||
* var func = _.overEvery([Boolean, isFinite]);
|
||
*
|
||
* func('1');
|
||
* // => true
|
||
*
|
||
* func(null);
|
||
* // => false
|
||
*
|
||
* func(NaN);
|
||
* // => false
|
||
*/
|
||
var overEvery = createOver(arrayEvery);
|
||
|
||
/**
|
||
* Creates a function that checks if **any** of the `predicates` return
|
||
* truthy when invoked with the arguments it receives.
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 4.0.0
|
||
* @category Util
|
||
* @param {...(Function|Function[])} [predicates=[_.identity]]
|
||
* The predicates to check.
|
||
* @returns {Function} Returns the new function.
|
||
* @example
|
||
*
|
||
* var func = _.overSome([Boolean, isFinite]);
|
||
*
|
||
* func('1');
|
||
* // => true
|
||
*
|
||
* func(null);
|
||
* // => true
|
||
*
|
||
* func(NaN);
|
||
* // => false
|
||
*/
|
||
var overSome = createOver(arraySome);
|
||
|
||
/**
|
||
* Creates a function that returns the value at `path` of a given object.
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 2.4.0
|
||
* @category Util
|
||
* @param {Array|string} path The path of the property to get.
|
||
* @returns {Function} Returns the new accessor function.
|
||
* @example
|
||
*
|
||
* var objects = [
|
||
* { 'a': { 'b': 2 } },
|
||
* { 'a': { 'b': 1 } }
|
||
* ];
|
||
*
|
||
* _.map(objects, _.property('a.b'));
|
||
* // => [2, 1]
|
||
*
|
||
* _.map(_.sortBy(objects, _.property(['a', 'b'])), 'a.b');
|
||
* // => [1, 2]
|
||
*/
|
||
function property(path) {
|
||
return isKey(path) ? baseProperty(toKey(path)) : basePropertyDeep(path);
|
||
}
|
||
|
||
/**
|
||
* The opposite of `_.property`; this method creates a function that returns
|
||
* the value at a given path of `object`.
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 3.0.0
|
||
* @category Util
|
||
* @param {Object} object The object to query.
|
||
* @returns {Function} Returns the new accessor function.
|
||
* @example
|
||
*
|
||
* var array = [0, 1, 2],
|
||
* object = { 'a': array, 'b': array, 'c': array };
|
||
*
|
||
* _.map(['a[2]', 'c[0]'], _.propertyOf(object));
|
||
* // => [2, 0]
|
||
*
|
||
* _.map([['a', '2'], ['c', '0']], _.propertyOf(object));
|
||
* // => [2, 0]
|
||
*/
|
||
function propertyOf(object) {
|
||
return function(path) {
|
||
return object == null ? undefined : baseGet(object, path);
|
||
};
|
||
}
|
||
|
||
/**
|
||
* Creates an array of numbers (positive and/or negative) progressing from
|
||
* `start` up to, but not including, `end`. A step of `-1` is used if a negative
|
||
* `start` is specified without an `end` or `step`. If `end` is not specified,
|
||
* it's set to `start` with `start` then set to `0`.
|
||
*
|
||
* **Note:** JavaScript follows the IEEE-754 standard for resolving
|
||
* floating-point values which can produce unexpected results.
|
||
*
|
||
* @static
|
||
* @since 0.1.0
|
||
* @memberOf _
|
||
* @category Util
|
||
* @param {number} [start=0] The start of the range.
|
||
* @param {number} end The end of the range.
|
||
* @param {number} [step=1] The value to increment or decrement by.
|
||
* @returns {Array} Returns the range of numbers.
|
||
* @see _.inRange, _.rangeRight
|
||
* @example
|
||
*
|
||
* _.range(4);
|
||
* // => [0, 1, 2, 3]
|
||
*
|
||
* _.range(-4);
|
||
* // => [0, -1, -2, -3]
|
||
*
|
||
* _.range(1, 5);
|
||
* // => [1, 2, 3, 4]
|
||
*
|
||
* _.range(0, 20, 5);
|
||
* // => [0, 5, 10, 15]
|
||
*
|
||
* _.range(0, -4, -1);
|
||
* // => [0, -1, -2, -3]
|
||
*
|
||
* _.range(1, 4, 0);
|
||
* // => [1, 1, 1]
|
||
*
|
||
* _.range(0);
|
||
* // => []
|
||
*/
|
||
var range = createRange();
|
||
|
||
/**
|
||
* This method is like `_.range` except that it populates values in
|
||
* descending order.
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 4.0.0
|
||
* @category Util
|
||
* @param {number} [start=0] The start of the range.
|
||
* @param {number} end The end of the range.
|
||
* @param {number} [step=1] The value to increment or decrement by.
|
||
* @returns {Array} Returns the range of numbers.
|
||
* @see _.inRange, _.range
|
||
* @example
|
||
*
|
||
* _.rangeRight(4);
|
||
* // => [3, 2, 1, 0]
|
||
*
|
||
* _.rangeRight(-4);
|
||
* // => [-3, -2, -1, 0]
|
||
*
|
||
* _.rangeRight(1, 5);
|
||
* // => [4, 3, 2, 1]
|
||
*
|
||
* _.rangeRight(0, 20, 5);
|
||
* // => [15, 10, 5, 0]
|
||
*
|
||
* _.rangeRight(0, -4, -1);
|
||
* // => [-3, -2, -1, 0]
|
||
*
|
||
* _.rangeRight(1, 4, 0);
|
||
* // => [1, 1, 1]
|
||
*
|
||
* _.rangeRight(0);
|
||
* // => []
|
||
*/
|
||
var rangeRight = createRange(true);
|
||
|
||
/**
|
||
* This method returns a new empty array.
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 4.13.0
|
||
* @category Util
|
||
* @returns {Array} Returns the new empty array.
|
||
* @example
|
||
*
|
||
* var arrays = _.times(2, _.stubArray);
|
||
*
|
||
* console.log(arrays);
|
||
* // => [[], []]
|
||
*
|
||
* console.log(arrays[0] === arrays[1]);
|
||
* // => false
|
||
*/
|
||
function stubArray() {
|
||
return [];
|
||
}
|
||
|
||
/**
|
||
* This method returns `false`.
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 4.13.0
|
||
* @category Util
|
||
* @returns {boolean} Returns `false`.
|
||
* @example
|
||
*
|
||
* _.times(2, _.stubFalse);
|
||
* // => [false, false]
|
||
*/
|
||
function stubFalse() {
|
||
return false;
|
||
}
|
||
|
||
/**
|
||
* This method returns a new empty object.
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 4.13.0
|
||
* @category Util
|
||
* @returns {Object} Returns the new empty object.
|
||
* @example
|
||
*
|
||
* var objects = _.times(2, _.stubObject);
|
||
*
|
||
* console.log(objects);
|
||
* // => [{}, {}]
|
||
*
|
||
* console.log(objects[0] === objects[1]);
|
||
* // => false
|
||
*/
|
||
function stubObject() {
|
||
return {};
|
||
}
|
||
|
||
/**
|
||
* This method returns an empty string.
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 4.13.0
|
||
* @category Util
|
||
* @returns {string} Returns the empty string.
|
||
* @example
|
||
*
|
||
* _.times(2, _.stubString);
|
||
* // => ['', '']
|
||
*/
|
||
function stubString() {
|
||
return '';
|
||
}
|
||
|
||
/**
|
||
* This method returns `true`.
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 4.13.0
|
||
* @category Util
|
||
* @returns {boolean} Returns `true`.
|
||
* @example
|
||
*
|
||
* _.times(2, _.stubTrue);
|
||
* // => [true, true]
|
||
*/
|
||
function stubTrue() {
|
||
return true;
|
||
}
|
||
|
||
/**
|
||
* Invokes the iteratee `n` times, returning an array of the results of
|
||
* each invocation. The iteratee is invoked with one argument; (index).
|
||
*
|
||
* @static
|
||
* @since 0.1.0
|
||
* @memberOf _
|
||
* @category Util
|
||
* @param {number} n The number of times to invoke `iteratee`.
|
||
* @param {Function} [iteratee=_.identity] The function invoked per iteration.
|
||
* @returns {Array} Returns the array of results.
|
||
* @example
|
||
*
|
||
* _.times(3, String);
|
||
* // => ['0', '1', '2']
|
||
*
|
||
* _.times(4, _.constant(0));
|
||
* // => [0, 0, 0, 0]
|
||
*/
|
||
function times(n, iteratee) {
|
||
n = toInteger(n);
|
||
if (n < 1 || n > MAX_SAFE_INTEGER) {
|
||
return [];
|
||
}
|
||
var index = MAX_ARRAY_LENGTH,
|
||
length = nativeMin(n, MAX_ARRAY_LENGTH);
|
||
|
||
iteratee = getIteratee(iteratee);
|
||
n -= MAX_ARRAY_LENGTH;
|
||
|
||
var result = baseTimes(length, iteratee);
|
||
while (++index < n) {
|
||
iteratee(index);
|
||
}
|
||
return result;
|
||
}
|
||
|
||
/**
|
||
* Converts `value` to a property path array.
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 4.0.0
|
||
* @category Util
|
||
* @param {*} value The value to convert.
|
||
* @returns {Array} Returns the new property path array.
|
||
* @example
|
||
*
|
||
* _.toPath('a.b.c');
|
||
* // => ['a', 'b', 'c']
|
||
*
|
||
* _.toPath('a[0].b.c');
|
||
* // => ['a', '0', 'b', 'c']
|
||
*/
|
||
function toPath(value) {
|
||
if (isArray(value)) {
|
||
return arrayMap(value, toKey);
|
||
}
|
||
return isSymbol(value) ? [value] : copyArray(stringToPath(toString(value)));
|
||
}
|
||
|
||
/**
|
||
* Generates a unique ID. If `prefix` is given, the ID is appended to it.
|
||
*
|
||
* @static
|
||
* @since 0.1.0
|
||
* @memberOf _
|
||
* @category Util
|
||
* @param {string} [prefix=''] The value to prefix the ID with.
|
||
* @returns {string} Returns the unique ID.
|
||
* @example
|
||
*
|
||
* _.uniqueId('contact_');
|
||
* // => 'contact_104'
|
||
*
|
||
* _.uniqueId();
|
||
* // => '105'
|
||
*/
|
||
function uniqueId(prefix) {
|
||
var id = ++idCounter;
|
||
return toString(prefix) + id;
|
||
}
|
||
|
||
/*------------------------------------------------------------------------*/
|
||
|
||
/**
|
||
* Adds two numbers.
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 3.4.0
|
||
* @category Math
|
||
* @param {number} augend The first number in an addition.
|
||
* @param {number} addend The second number in an addition.
|
||
* @returns {number} Returns the total.
|
||
* @example
|
||
*
|
||
* _.add(6, 4);
|
||
* // => 10
|
||
*/
|
||
var add = createMathOperation(function(augend, addend) {
|
||
return augend + addend;
|
||
}, 0);
|
||
|
||
/**
|
||
* Computes `number` rounded up to `precision`.
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 3.10.0
|
||
* @category Math
|
||
* @param {number} number The number to round up.
|
||
* @param {number} [precision=0] The precision to round up to.
|
||
* @returns {number} Returns the rounded up number.
|
||
* @example
|
||
*
|
||
* _.ceil(4.006);
|
||
* // => 5
|
||
*
|
||
* _.ceil(6.004, 2);
|
||
* // => 6.01
|
||
*
|
||
* _.ceil(6040, -2);
|
||
* // => 6100
|
||
*/
|
||
var ceil = createRound('ceil');
|
||
|
||
/**
|
||
* Divide two numbers.
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 4.7.0
|
||
* @category Math
|
||
* @param {number} dividend The first number in a division.
|
||
* @param {number} divisor The second number in a division.
|
||
* @returns {number} Returns the quotient.
|
||
* @example
|
||
*
|
||
* _.divide(6, 4);
|
||
* // => 1.5
|
||
*/
|
||
var divide = createMathOperation(function(dividend, divisor) {
|
||
return dividend / divisor;
|
||
}, 1);
|
||
|
||
/**
|
||
* Computes `number` rounded down to `precision`.
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 3.10.0
|
||
* @category Math
|
||
* @param {number} number The number to round down.
|
||
* @param {number} [precision=0] The precision to round down to.
|
||
* @returns {number} Returns the rounded down number.
|
||
* @example
|
||
*
|
||
* _.floor(4.006);
|
||
* // => 4
|
||
*
|
||
* _.floor(0.046, 2);
|
||
* // => 0.04
|
||
*
|
||
* _.floor(4060, -2);
|
||
* // => 4000
|
||
*/
|
||
var floor = createRound('floor');
|
||
|
||
/**
|
||
* Computes the maximum value of `array`. If `array` is empty or falsey,
|
||
* `undefined` is returned.
|
||
*
|
||
* @static
|
||
* @since 0.1.0
|
||
* @memberOf _
|
||
* @category Math
|
||
* @param {Array} array The array to iterate over.
|
||
* @returns {*} Returns the maximum value.
|
||
* @example
|
||
*
|
||
* _.max([4, 2, 8, 6]);
|
||
* // => 8
|
||
*
|
||
* _.max([]);
|
||
* // => undefined
|
||
*/
|
||
function max(array) {
|
||
return (array && array.length)
|
||
? baseExtremum(array, identity, baseGt)
|
||
: undefined;
|
||
}
|
||
|
||
/**
|
||
* This method is like `_.max` except that it accepts `iteratee` which is
|
||
* invoked for each element in `array` to generate the criterion by which
|
||
* the value is ranked. The iteratee is invoked with one argument: (value).
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 4.0.0
|
||
* @category Math
|
||
* @param {Array} array The array to iterate over.
|
||
* @param {Function} [iteratee=_.identity] The iteratee invoked per element.
|
||
* @returns {*} Returns the maximum value.
|
||
* @example
|
||
*
|
||
* var objects = [{ 'n': 1 }, { 'n': 2 }];
|
||
*
|
||
* _.maxBy(objects, function(o) { return o.n; });
|
||
* // => { 'n': 2 }
|
||
*
|
||
* // The `_.property` iteratee shorthand.
|
||
* _.maxBy(objects, 'n');
|
||
* // => { 'n': 2 }
|
||
*/
|
||
function maxBy(array, iteratee) {
|
||
return (array && array.length)
|
||
? baseExtremum(array, getIteratee(iteratee, 2), baseGt)
|
||
: undefined;
|
||
}
|
||
|
||
/**
|
||
* Computes the mean of the values in `array`.
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 4.0.0
|
||
* @category Math
|
||
* @param {Array} array The array to iterate over.
|
||
* @returns {number} Returns the mean.
|
||
* @example
|
||
*
|
||
* _.mean([4, 2, 8, 6]);
|
||
* // => 5
|
||
*/
|
||
function mean(array) {
|
||
return baseMean(array, identity);
|
||
}
|
||
|
||
/**
|
||
* This method is like `_.mean` except that it accepts `iteratee` which is
|
||
* invoked for each element in `array` to generate the value to be averaged.
|
||
* The iteratee is invoked with one argument: (value).
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 4.7.0
|
||
* @category Math
|
||
* @param {Array} array The array to iterate over.
|
||
* @param {Function} [iteratee=_.identity] The iteratee invoked per element.
|
||
* @returns {number} Returns the mean.
|
||
* @example
|
||
*
|
||
* var objects = [{ 'n': 4 }, { 'n': 2 }, { 'n': 8 }, { 'n': 6 }];
|
||
*
|
||
* _.meanBy(objects, function(o) { return o.n; });
|
||
* // => 5
|
||
*
|
||
* // The `_.property` iteratee shorthand.
|
||
* _.meanBy(objects, 'n');
|
||
* // => 5
|
||
*/
|
||
function meanBy(array, iteratee) {
|
||
return baseMean(array, getIteratee(iteratee, 2));
|
||
}
|
||
|
||
/**
|
||
* Computes the minimum value of `array`. If `array` is empty or falsey,
|
||
* `undefined` is returned.
|
||
*
|
||
* @static
|
||
* @since 0.1.0
|
||
* @memberOf _
|
||
* @category Math
|
||
* @param {Array} array The array to iterate over.
|
||
* @returns {*} Returns the minimum value.
|
||
* @example
|
||
*
|
||
* _.min([4, 2, 8, 6]);
|
||
* // => 2
|
||
*
|
||
* _.min([]);
|
||
* // => undefined
|
||
*/
|
||
function min(array) {
|
||
return (array && array.length)
|
||
? baseExtremum(array, identity, baseLt)
|
||
: undefined;
|
||
}
|
||
|
||
/**
|
||
* This method is like `_.min` except that it accepts `iteratee` which is
|
||
* invoked for each element in `array` to generate the criterion by which
|
||
* the value is ranked. The iteratee is invoked with one argument: (value).
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 4.0.0
|
||
* @category Math
|
||
* @param {Array} array The array to iterate over.
|
||
* @param {Function} [iteratee=_.identity] The iteratee invoked per element.
|
||
* @returns {*} Returns the minimum value.
|
||
* @example
|
||
*
|
||
* var objects = [{ 'n': 1 }, { 'n': 2 }];
|
||
*
|
||
* _.minBy(objects, function(o) { return o.n; });
|
||
* // => { 'n': 1 }
|
||
*
|
||
* // The `_.property` iteratee shorthand.
|
||
* _.minBy(objects, 'n');
|
||
* // => { 'n': 1 }
|
||
*/
|
||
function minBy(array, iteratee) {
|
||
return (array && array.length)
|
||
? baseExtremum(array, getIteratee(iteratee, 2), baseLt)
|
||
: undefined;
|
||
}
|
||
|
||
/**
|
||
* Multiply two numbers.
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 4.7.0
|
||
* @category Math
|
||
* @param {number} multiplier The first number in a multiplication.
|
||
* @param {number} multiplicand The second number in a multiplication.
|
||
* @returns {number} Returns the product.
|
||
* @example
|
||
*
|
||
* _.multiply(6, 4);
|
||
* // => 24
|
||
*/
|
||
var multiply = createMathOperation(function(multiplier, multiplicand) {
|
||
return multiplier * multiplicand;
|
||
}, 1);
|
||
|
||
/**
|
||
* Computes `number` rounded to `precision`.
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 3.10.0
|
||
* @category Math
|
||
* @param {number} number The number to round.
|
||
* @param {number} [precision=0] The precision to round to.
|
||
* @returns {number} Returns the rounded number.
|
||
* @example
|
||
*
|
||
* _.round(4.006);
|
||
* // => 4
|
||
*
|
||
* _.round(4.006, 2);
|
||
* // => 4.01
|
||
*
|
||
* _.round(4060, -2);
|
||
* // => 4100
|
||
*/
|
||
var round = createRound('round');
|
||
|
||
/**
|
||
* Subtract two numbers.
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 4.0.0
|
||
* @category Math
|
||
* @param {number} minuend The first number in a subtraction.
|
||
* @param {number} subtrahend The second number in a subtraction.
|
||
* @returns {number} Returns the difference.
|
||
* @example
|
||
*
|
||
* _.subtract(6, 4);
|
||
* // => 2
|
||
*/
|
||
var subtract = createMathOperation(function(minuend, subtrahend) {
|
||
return minuend - subtrahend;
|
||
}, 0);
|
||
|
||
/**
|
||
* Computes the sum of the values in `array`.
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 3.4.0
|
||
* @category Math
|
||
* @param {Array} array The array to iterate over.
|
||
* @returns {number} Returns the sum.
|
||
* @example
|
||
*
|
||
* _.sum([4, 2, 8, 6]);
|
||
* // => 20
|
||
*/
|
||
function sum(array) {
|
||
return (array && array.length)
|
||
? baseSum(array, identity)
|
||
: 0;
|
||
}
|
||
|
||
/**
|
||
* This method is like `_.sum` except that it accepts `iteratee` which is
|
||
* invoked for each element in `array` to generate the value to be summed.
|
||
* The iteratee is invoked with one argument: (value).
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @since 4.0.0
|
||
* @category Math
|
||
* @param {Array} array The array to iterate over.
|
||
* @param {Function} [iteratee=_.identity] The iteratee invoked per element.
|
||
* @returns {number} Returns the sum.
|
||
* @example
|
||
*
|
||
* var objects = [{ 'n': 4 }, { 'n': 2 }, { 'n': 8 }, { 'n': 6 }];
|
||
*
|
||
* _.sumBy(objects, function(o) { return o.n; });
|
||
* // => 20
|
||
*
|
||
* // The `_.property` iteratee shorthand.
|
||
* _.sumBy(objects, 'n');
|
||
* // => 20
|
||
*/
|
||
function sumBy(array, iteratee) {
|
||
return (array && array.length)
|
||
? baseSum(array, getIteratee(iteratee, 2))
|
||
: 0;
|
||
}
|
||
|
||
/*------------------------------------------------------------------------*/
|
||
|
||
// Add methods that return wrapped values in chain sequences.
|
||
lodash.after = after;
|
||
lodash.ary = ary;
|
||
lodash.assign = assign;
|
||
lodash.assignIn = assignIn;
|
||
lodash.assignInWith = assignInWith;
|
||
lodash.assignWith = assignWith;
|
||
lodash.at = at;
|
||
lodash.before = before;
|
||
lodash.bind = bind;
|
||
lodash.bindAll = bindAll;
|
||
lodash.bindKey = bindKey;
|
||
lodash.castArray = castArray;
|
||
lodash.chain = chain;
|
||
lodash.chunk = chunk;
|
||
lodash.compact = compact;
|
||
lodash.concat = concat;
|
||
lodash.cond = cond;
|
||
lodash.conforms = conforms;
|
||
lodash.constant = constant;
|
||
lodash.countBy = countBy;
|
||
lodash.create = create;
|
||
lodash.curry = curry;
|
||
lodash.curryRight = curryRight;
|
||
lodash.debounce = debounce;
|
||
lodash.defaults = defaults;
|
||
lodash.defaultsDeep = defaultsDeep;
|
||
lodash.defer = defer;
|
||
lodash.delay = delay;
|
||
lodash.difference = difference;
|
||
lodash.differenceBy = differenceBy;
|
||
lodash.differenceWith = differenceWith;
|
||
lodash.drop = drop;
|
||
lodash.dropRight = dropRight;
|
||
lodash.dropRightWhile = dropRightWhile;
|
||
lodash.dropWhile = dropWhile;
|
||
lodash.fill = fill;
|
||
lodash.filter = filter;
|
||
lodash.flatMap = flatMap;
|
||
lodash.flatMapDeep = flatMapDeep;
|
||
lodash.flatMapDepth = flatMapDepth;
|
||
lodash.flatten = flatten;
|
||
lodash.flattenDeep = flattenDeep;
|
||
lodash.flattenDepth = flattenDepth;
|
||
lodash.flip = flip;
|
||
lodash.flow = flow;
|
||
lodash.flowRight = flowRight;
|
||
lodash.fromPairs = fromPairs;
|
||
lodash.functions = functions;
|
||
lodash.functionsIn = functionsIn;
|
||
lodash.groupBy = groupBy;
|
||
lodash.initial = initial;
|
||
lodash.intersection = intersection;
|
||
lodash.intersectionBy = intersectionBy;
|
||
lodash.intersectionWith = intersectionWith;
|
||
lodash.invert = invert;
|
||
lodash.invertBy = invertBy;
|
||
lodash.invokeMap = invokeMap;
|
||
lodash.iteratee = iteratee;
|
||
lodash.keyBy = keyBy;
|
||
lodash.keys = keys;
|
||
lodash.keysIn = keysIn;
|
||
lodash.map = map;
|
||
lodash.mapKeys = mapKeys;
|
||
lodash.mapValues = mapValues;
|
||
lodash.matches = matches;
|
||
lodash.matchesProperty = matchesProperty;
|
||
lodash.memoize = memoize;
|
||
lodash.merge = merge;
|
||
lodash.mergeWith = mergeWith;
|
||
lodash.method = method;
|
||
lodash.methodOf = methodOf;
|
||
lodash.mixin = mixin;
|
||
lodash.negate = negate;
|
||
lodash.nthArg = nthArg;
|
||
lodash.omit = omit;
|
||
lodash.omitBy = omitBy;
|
||
lodash.once = once;
|
||
lodash.orderBy = orderBy;
|
||
lodash.over = over;
|
||
lodash.overArgs = overArgs;
|
||
lodash.overEvery = overEvery;
|
||
lodash.overSome = overSome;
|
||
lodash.partial = partial;
|
||
lodash.partialRight = partialRight;
|
||
lodash.partition = partition;
|
||
lodash.pick = pick;
|
||
lodash.pickBy = pickBy;
|
||
lodash.property = property;
|
||
lodash.propertyOf = propertyOf;
|
||
lodash.pull = pull;
|
||
lodash.pullAll = pullAll;
|
||
lodash.pullAllBy = pullAllBy;
|
||
lodash.pullAllWith = pullAllWith;
|
||
lodash.pullAt = pullAt;
|
||
lodash.range = range;
|
||
lodash.rangeRight = rangeRight;
|
||
lodash.rearg = rearg;
|
||
lodash.reject = reject;
|
||
lodash.remove = remove;
|
||
lodash.rest = rest;
|
||
lodash.reverse = reverse;
|
||
lodash.sampleSize = sampleSize;
|
||
lodash.set = set;
|
||
lodash.setWith = setWith;
|
||
lodash.shuffle = shuffle;
|
||
lodash.slice = slice;
|
||
lodash.sortBy = sortBy;
|
||
lodash.sortedUniq = sortedUniq;
|
||
lodash.sortedUniqBy = sortedUniqBy;
|
||
lodash.split = split;
|
||
lodash.spread = spread;
|
||
lodash.tail = tail;
|
||
lodash.take = take;
|
||
lodash.takeRight = takeRight;
|
||
lodash.takeRightWhile = takeRightWhile;
|
||
lodash.takeWhile = takeWhile;
|
||
lodash.tap = tap;
|
||
lodash.throttle = throttle;
|
||
lodash.thru = thru;
|
||
lodash.toArray = toArray;
|
||
lodash.toPairs = toPairs;
|
||
lodash.toPairsIn = toPairsIn;
|
||
lodash.toPath = toPath;
|
||
lodash.toPlainObject = toPlainObject;
|
||
lodash.transform = transform;
|
||
lodash.unary = unary;
|
||
lodash.union = union;
|
||
lodash.unionBy = unionBy;
|
||
lodash.unionWith = unionWith;
|
||
lodash.uniq = uniq;
|
||
lodash.uniqBy = uniqBy;
|
||
lodash.uniqWith = uniqWith;
|
||
lodash.unset = unset;
|
||
lodash.unzip = unzip;
|
||
lodash.unzipWith = unzipWith;
|
||
lodash.update = update;
|
||
lodash.updateWith = updateWith;
|
||
lodash.values = values;
|
||
lodash.valuesIn = valuesIn;
|
||
lodash.without = without;
|
||
lodash.words = words;
|
||
lodash.wrap = wrap;
|
||
lodash.xor = xor;
|
||
lodash.xorBy = xorBy;
|
||
lodash.xorWith = xorWith;
|
||
lodash.zip = zip;
|
||
lodash.zipObject = zipObject;
|
||
lodash.zipObjectDeep = zipObjectDeep;
|
||
lodash.zipWith = zipWith;
|
||
|
||
// Add aliases.
|
||
lodash.entries = toPairs;
|
||
lodash.entriesIn = toPairsIn;
|
||
lodash.extend = assignIn;
|
||
lodash.extendWith = assignInWith;
|
||
|
||
// Add methods to `lodash.prototype`.
|
||
mixin(lodash, lodash);
|
||
|
||
/*------------------------------------------------------------------------*/
|
||
|
||
// Add methods that return unwrapped values in chain sequences.
|
||
lodash.add = add;
|
||
lodash.attempt = attempt;
|
||
lodash.camelCase = camelCase;
|
||
lodash.capitalize = capitalize;
|
||
lodash.ceil = ceil;
|
||
lodash.clamp = clamp;
|
||
lodash.clone = clone;
|
||
lodash.cloneDeep = cloneDeep;
|
||
lodash.cloneDeepWith = cloneDeepWith;
|
||
lodash.cloneWith = cloneWith;
|
||
lodash.conformsTo = conformsTo;
|
||
lodash.deburr = deburr;
|
||
lodash.defaultTo = defaultTo;
|
||
lodash.divide = divide;
|
||
lodash.endsWith = endsWith;
|
||
lodash.eq = eq;
|
||
lodash.escape = escape;
|
||
lodash.escapeRegExp = escapeRegExp;
|
||
lodash.every = every;
|
||
lodash.find = find;
|
||
lodash.findIndex = findIndex;
|
||
lodash.findKey = findKey;
|
||
lodash.findLast = findLast;
|
||
lodash.findLastIndex = findLastIndex;
|
||
lodash.findLastKey = findLastKey;
|
||
lodash.floor = floor;
|
||
lodash.forEach = forEach;
|
||
lodash.forEachRight = forEachRight;
|
||
lodash.forIn = forIn;
|
||
lodash.forInRight = forInRight;
|
||
lodash.forOwn = forOwn;
|
||
lodash.forOwnRight = forOwnRight;
|
||
lodash.get = get;
|
||
lodash.gt = gt;
|
||
lodash.gte = gte;
|
||
lodash.has = has;
|
||
lodash.hasIn = hasIn;
|
||
lodash.head = head;
|
||
lodash.identity = identity;
|
||
lodash.includes = includes;
|
||
lodash.indexOf = indexOf;
|
||
lodash.inRange = inRange;
|
||
lodash.invoke = invoke;
|
||
lodash.isArguments = isArguments;
|
||
lodash.isArray = isArray;
|
||
lodash.isArrayBuffer = isArrayBuffer;
|
||
lodash.isArrayLike = isArrayLike;
|
||
lodash.isArrayLikeObject = isArrayLikeObject;
|
||
lodash.isBoolean = isBoolean;
|
||
lodash.isBuffer = isBuffer;
|
||
lodash.isDate = isDate;
|
||
lodash.isElement = isElement;
|
||
lodash.isEmpty = isEmpty;
|
||
lodash.isEqual = isEqual;
|
||
lodash.isEqualWith = isEqualWith;
|
||
lodash.isError = isError;
|
||
lodash.isFinite = isFinite;
|
||
lodash.isFunction = isFunction;
|
||
lodash.isInteger = isInteger;
|
||
lodash.isLength = isLength;
|
||
lodash.isMap = isMap;
|
||
lodash.isMatch = isMatch;
|
||
lodash.isMatchWith = isMatchWith;
|
||
lodash.isNaN = isNaN;
|
||
lodash.isNative = isNative;
|
||
lodash.isNil = isNil;
|
||
lodash.isNull = isNull;
|
||
lodash.isNumber = isNumber;
|
||
lodash.isObject = isObject;
|
||
lodash.isObjectLike = isObjectLike;
|
||
lodash.isPlainObject = isPlainObject;
|
||
lodash.isRegExp = isRegExp;
|
||
lodash.isSafeInteger = isSafeInteger;
|
||
lodash.isSet = isSet;
|
||
lodash.isString = isString;
|
||
lodash.isSymbol = isSymbol;
|
||
lodash.isTypedArray = isTypedArray;
|
||
lodash.isUndefined = isUndefined;
|
||
lodash.isWeakMap = isWeakMap;
|
||
lodash.isWeakSet = isWeakSet;
|
||
lodash.join = join;
|
||
lodash.kebabCase = kebabCase;
|
||
lodash.last = last;
|
||
lodash.lastIndexOf = lastIndexOf;
|
||
lodash.lowerCase = lowerCase;
|
||
lodash.lowerFirst = lowerFirst;
|
||
lodash.lt = lt;
|
||
lodash.lte = lte;
|
||
lodash.max = max;
|
||
lodash.maxBy = maxBy;
|
||
lodash.mean = mean;
|
||
lodash.meanBy = meanBy;
|
||
lodash.min = min;
|
||
lodash.minBy = minBy;
|
||
lodash.stubArray = stubArray;
|
||
lodash.stubFalse = stubFalse;
|
||
lodash.stubObject = stubObject;
|
||
lodash.stubString = stubString;
|
||
lodash.stubTrue = stubTrue;
|
||
lodash.multiply = multiply;
|
||
lodash.nth = nth;
|
||
lodash.noConflict = noConflict;
|
||
lodash.noop = noop;
|
||
lodash.now = now;
|
||
lodash.pad = pad;
|
||
lodash.padEnd = padEnd;
|
||
lodash.padStart = padStart;
|
||
lodash.parseInt = parseInt;
|
||
lodash.random = random;
|
||
lodash.reduce = reduce;
|
||
lodash.reduceRight = reduceRight;
|
||
lodash.repeat = repeat;
|
||
lodash.replace = replace;
|
||
lodash.result = result;
|
||
lodash.round = round;
|
||
lodash.runInContext = runInContext;
|
||
lodash.sample = sample;
|
||
lodash.size = size;
|
||
lodash.snakeCase = snakeCase;
|
||
lodash.some = some;
|
||
lodash.sortedIndex = sortedIndex;
|
||
lodash.sortedIndexBy = sortedIndexBy;
|
||
lodash.sortedIndexOf = sortedIndexOf;
|
||
lodash.sortedLastIndex = sortedLastIndex;
|
||
lodash.sortedLastIndexBy = sortedLastIndexBy;
|
||
lodash.sortedLastIndexOf = sortedLastIndexOf;
|
||
lodash.startCase = startCase;
|
||
lodash.startsWith = startsWith;
|
||
lodash.subtract = subtract;
|
||
lodash.sum = sum;
|
||
lodash.sumBy = sumBy;
|
||
lodash.template = template;
|
||
lodash.times = times;
|
||
lodash.toFinite = toFinite;
|
||
lodash.toInteger = toInteger;
|
||
lodash.toLength = toLength;
|
||
lodash.toLower = toLower;
|
||
lodash.toNumber = toNumber;
|
||
lodash.toSafeInteger = toSafeInteger;
|
||
lodash.toString = toString;
|
||
lodash.toUpper = toUpper;
|
||
lodash.trim = trim;
|
||
lodash.trimEnd = trimEnd;
|
||
lodash.trimStart = trimStart;
|
||
lodash.truncate = truncate;
|
||
lodash.unescape = unescape;
|
||
lodash.uniqueId = uniqueId;
|
||
lodash.upperCase = upperCase;
|
||
lodash.upperFirst = upperFirst;
|
||
|
||
// Add aliases.
|
||
lodash.each = forEach;
|
||
lodash.eachRight = forEachRight;
|
||
lodash.first = head;
|
||
|
||
mixin(lodash, (function() {
|
||
var source = {};
|
||
baseForOwn(lodash, function(func, methodName) {
|
||
if (!hasOwnProperty.call(lodash.prototype, methodName)) {
|
||
source[methodName] = func;
|
||
}
|
||
});
|
||
return source;
|
||
}()), { 'chain': false });
|
||
|
||
/*------------------------------------------------------------------------*/
|
||
|
||
/**
|
||
* The semantic version number.
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @type {string}
|
||
*/
|
||
lodash.VERSION = VERSION;
|
||
|
||
// Assign default placeholders.
|
||
arrayEach(['bind', 'bindKey', 'curry', 'curryRight', 'partial', 'partialRight'], function(methodName) {
|
||
lodash[methodName].placeholder = lodash;
|
||
});
|
||
|
||
// Add `LazyWrapper` methods for `_.drop` and `_.take` variants.
|
||
arrayEach(['drop', 'take'], function(methodName, index) {
|
||
LazyWrapper.prototype[methodName] = function(n) {
|
||
n = n === undefined ? 1 : nativeMax(toInteger(n), 0);
|
||
|
||
var result = (this.__filtered__ && !index)
|
||
? new LazyWrapper(this)
|
||
: this.clone();
|
||
|
||
if (result.__filtered__) {
|
||
result.__takeCount__ = nativeMin(n, result.__takeCount__);
|
||
} else {
|
||
result.__views__.push({
|
||
'size': nativeMin(n, MAX_ARRAY_LENGTH),
|
||
'type': methodName + (result.__dir__ < 0 ? 'Right' : '')
|
||
});
|
||
}
|
||
return result;
|
||
};
|
||
|
||
LazyWrapper.prototype[methodName + 'Right'] = function(n) {
|
||
return this.reverse()[methodName](n).reverse();
|
||
};
|
||
});
|
||
|
||
// Add `LazyWrapper` methods that accept an `iteratee` value.
|
||
arrayEach(['filter', 'map', 'takeWhile'], function(methodName, index) {
|
||
var type = index + 1,
|
||
isFilter = type == LAZY_FILTER_FLAG || type == LAZY_WHILE_FLAG;
|
||
|
||
LazyWrapper.prototype[methodName] = function(iteratee) {
|
||
var result = this.clone();
|
||
result.__iteratees__.push({
|
||
'iteratee': getIteratee(iteratee, 3),
|
||
'type': type
|
||
});
|
||
result.__filtered__ = result.__filtered__ || isFilter;
|
||
return result;
|
||
};
|
||
});
|
||
|
||
// Add `LazyWrapper` methods for `_.head` and `_.last`.
|
||
arrayEach(['head', 'last'], function(methodName, index) {
|
||
var takeName = 'take' + (index ? 'Right' : '');
|
||
|
||
LazyWrapper.prototype[methodName] = function() {
|
||
return this[takeName](1).value()[0];
|
||
};
|
||
});
|
||
|
||
// Add `LazyWrapper` methods for `_.initial` and `_.tail`.
|
||
arrayEach(['initial', 'tail'], function(methodName, index) {
|
||
var dropName = 'drop' + (index ? '' : 'Right');
|
||
|
||
LazyWrapper.prototype[methodName] = function() {
|
||
return this.__filtered__ ? new LazyWrapper(this) : this[dropName](1);
|
||
};
|
||
});
|
||
|
||
LazyWrapper.prototype.compact = function() {
|
||
return this.filter(identity);
|
||
};
|
||
|
||
LazyWrapper.prototype.find = function(predicate) {
|
||
return this.filter(predicate).head();
|
||
};
|
||
|
||
LazyWrapper.prototype.findLast = function(predicate) {
|
||
return this.reverse().find(predicate);
|
||
};
|
||
|
||
LazyWrapper.prototype.invokeMap = baseRest(function(path, args) {
|
||
if (typeof path == 'function') {
|
||
return new LazyWrapper(this);
|
||
}
|
||
return this.map(function(value) {
|
||
return baseInvoke(value, path, args);
|
||
});
|
||
});
|
||
|
||
LazyWrapper.prototype.reject = function(predicate) {
|
||
return this.filter(negate(getIteratee(predicate)));
|
||
};
|
||
|
||
LazyWrapper.prototype.slice = function(start, end) {
|
||
start = toInteger(start);
|
||
|
||
var result = this;
|
||
if (result.__filtered__ && (start > 0 || end < 0)) {
|
||
return new LazyWrapper(result);
|
||
}
|
||
if (start < 0) {
|
||
result = result.takeRight(-start);
|
||
} else if (start) {
|
||
result = result.drop(start);
|
||
}
|
||
if (end !== undefined) {
|
||
end = toInteger(end);
|
||
result = end < 0 ? result.dropRight(-end) : result.take(end - start);
|
||
}
|
||
return result;
|
||
};
|
||
|
||
LazyWrapper.prototype.takeRightWhile = function(predicate) {
|
||
return this.reverse().takeWhile(predicate).reverse();
|
||
};
|
||
|
||
LazyWrapper.prototype.toArray = function() {
|
||
return this.take(MAX_ARRAY_LENGTH);
|
||
};
|
||
|
||
// Add `LazyWrapper` methods to `lodash.prototype`.
|
||
baseForOwn(LazyWrapper.prototype, function(func, methodName) {
|
||
var checkIteratee = /^(?:filter|find|map|reject)|While$/.test(methodName),
|
||
isTaker = /^(?:head|last)$/.test(methodName),
|
||
lodashFunc = lodash[isTaker ? ('take' + (methodName == 'last' ? 'Right' : '')) : methodName],
|
||
retUnwrapped = isTaker || /^find/.test(methodName);
|
||
|
||
if (!lodashFunc) {
|
||
return;
|
||
}
|
||
lodash.prototype[methodName] = function() {
|
||
var value = this.__wrapped__,
|
||
args = isTaker ? [1] : arguments,
|
||
isLazy = value instanceof LazyWrapper,
|
||
iteratee = args[0],
|
||
useLazy = isLazy || isArray(value);
|
||
|
||
var interceptor = function(value) {
|
||
var result = lodashFunc.apply(lodash, arrayPush([value], args));
|
||
return (isTaker && chainAll) ? result[0] : result;
|
||
};
|
||
|
||
if (useLazy && checkIteratee && typeof iteratee == 'function' && iteratee.length != 1) {
|
||
// Avoid lazy use if the iteratee has a "length" value other than `1`.
|
||
isLazy = useLazy = false;
|
||
}
|
||
var chainAll = this.__chain__,
|
||
isHybrid = !!this.__actions__.length,
|
||
isUnwrapped = retUnwrapped && !chainAll,
|
||
onlyLazy = isLazy && !isHybrid;
|
||
|
||
if (!retUnwrapped && useLazy) {
|
||
value = onlyLazy ? value : new LazyWrapper(this);
|
||
var result = func.apply(value, args);
|
||
result.__actions__.push({ 'func': thru, 'args': [interceptor], 'thisArg': undefined });
|
||
return new LodashWrapper(result, chainAll);
|
||
}
|
||
if (isUnwrapped && onlyLazy) {
|
||
return func.apply(this, args);
|
||
}
|
||
result = this.thru(interceptor);
|
||
return isUnwrapped ? (isTaker ? result.value()[0] : result.value()) : result;
|
||
};
|
||
});
|
||
|
||
// Add `Array` methods to `lodash.prototype`.
|
||
arrayEach(['pop', 'push', 'shift', 'sort', 'splice', 'unshift'], function(methodName) {
|
||
var func = arrayProto[methodName],
|
||
chainName = /^(?:push|sort|unshift)$/.test(methodName) ? 'tap' : 'thru',
|
||
retUnwrapped = /^(?:pop|shift)$/.test(methodName);
|
||
|
||
lodash.prototype[methodName] = function() {
|
||
var args = arguments;
|
||
if (retUnwrapped && !this.__chain__) {
|
||
var value = this.value();
|
||
return func.apply(isArray(value) ? value : [], args);
|
||
}
|
||
return this[chainName](function(value) {
|
||
return func.apply(isArray(value) ? value : [], args);
|
||
});
|
||
};
|
||
});
|
||
|
||
// Map minified method names to their real names.
|
||
baseForOwn(LazyWrapper.prototype, function(func, methodName) {
|
||
var lodashFunc = lodash[methodName];
|
||
if (lodashFunc) {
|
||
var key = (lodashFunc.name + ''),
|
||
names = realNames[key] || (realNames[key] = []);
|
||
|
||
names.push({ 'name': methodName, 'func': lodashFunc });
|
||
}
|
||
});
|
||
|
||
realNames[createHybrid(undefined, WRAP_BIND_KEY_FLAG).name] = [{
|
||
'name': 'wrapper',
|
||
'func': undefined
|
||
}];
|
||
|
||
// Add methods to `LazyWrapper`.
|
||
LazyWrapper.prototype.clone = lazyClone;
|
||
LazyWrapper.prototype.reverse = lazyReverse;
|
||
LazyWrapper.prototype.value = lazyValue;
|
||
|
||
// Add chain sequence methods to the `lodash` wrapper.
|
||
lodash.prototype.at = wrapperAt;
|
||
lodash.prototype.chain = wrapperChain;
|
||
lodash.prototype.commit = wrapperCommit;
|
||
lodash.prototype.next = wrapperNext;
|
||
lodash.prototype.plant = wrapperPlant;
|
||
lodash.prototype.reverse = wrapperReverse;
|
||
lodash.prototype.toJSON = lodash.prototype.valueOf = lodash.prototype.value = wrapperValue;
|
||
|
||
// Add lazy aliases.
|
||
lodash.prototype.first = lodash.prototype.head;
|
||
|
||
if (symIterator) {
|
||
lodash.prototype[symIterator] = wrapperToIterator;
|
||
}
|
||
return lodash;
|
||
});
|
||
|
||
/*--------------------------------------------------------------------------*/
|
||
|
||
// Export lodash.
|
||
var _ = runInContext();
|
||
|
||
// Some AMD build optimizers, like r.js, check for condition patterns like:
|
||
if (true) {
|
||
// Expose Lodash on the global object to prevent errors when Lodash is
|
||
// loaded by a script tag in the presence of an AMD loader.
|
||
// See http://requirejs.org/docs/errors.html#mismatch for more details.
|
||
// Use `_.noConflict` to remove Lodash from the global object.
|
||
root._ = _;
|
||
|
||
// Define as an anonymous module so, through path mapping, it can be
|
||
// referenced as the "underscore" module.
|
||
!(__WEBPACK_AMD_DEFINE_RESULT__ = function() {
|
||
return _;
|
||
}.call(exports, __webpack_require__, exports, module),
|
||
__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
|
||
}
|
||
// Check for `exports` after `define` in case a build optimizer adds it.
|
||
else if (freeModule) {
|
||
// Export for Node.js.
|
||
(freeModule.exports = _)._ = _;
|
||
// Export for CommonJS support.
|
||
freeExports._ = _;
|
||
}
|
||
else {
|
||
// Export to the global object.
|
||
root._ = _;
|
||
}
|
||
}.call(this));
|
||
|
||
/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(4), __webpack_require__(10)(module)))
|
||
|
||
/***/ }),
|
||
/* 10 */
|
||
/***/ (function(module, exports) {
|
||
|
||
module.exports = function(module) {
|
||
if(!module.webpackPolyfill) {
|
||
module.deprecate = function() {};
|
||
module.paths = [];
|
||
// module.parent = undefined by default
|
||
if(!module.children) module.children = [];
|
||
Object.defineProperty(module, "loaded", {
|
||
enumerable: true,
|
||
get: function() {
|
||
return module.l;
|
||
}
|
||
});
|
||
Object.defineProperty(module, "id", {
|
||
enumerable: true,
|
||
get: function() {
|
||
return module.i;
|
||
}
|
||
});
|
||
module.webpackPolyfill = 1;
|
||
}
|
||
return module;
|
||
};
|
||
|
||
|
||
/***/ }),
|
||
/* 11 */
|
||
/***/ (function(module, exports) {
|
||
|
||
/* */
|
||
"format global";
|
||
"deps jquery";
|
||
"exports $";
|
||
/*!
|
||
* Bootstrap v3.3.4 (http://getbootstrap.com)
|
||
* Copyright 2011-2015 Twitter, Inc.
|
||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
|
||
*/
|
||
|
||
if (typeof jQuery === 'undefined') {
|
||
throw new Error('Bootstrap\'s JavaScript requires jQuery')
|
||
}
|
||
|
||
+function ($) {
|
||
'use strict';
|
||
var version = $.fn.jquery.split(' ')[0].split('.')
|
||
if ((version[0] < 2 && version[1] < 9) || (version[0] == 1 && version[1] == 9 && version[2] < 1)) {
|
||
throw new Error('Bootstrap\'s JavaScript requires jQuery version 1.9.1 or higher')
|
||
}
|
||
}(jQuery);
|
||
|
||
/* ========================================================================
|
||
* Bootstrap: transition.js v3.3.4
|
||
* http://getbootstrap.com/javascript/#transitions
|
||
* ========================================================================
|
||
* Copyright 2011-2015 Twitter, Inc.
|
||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
|
||
* ======================================================================== */
|
||
|
||
|
||
+function ($) {
|
||
'use strict';
|
||
|
||
// CSS TRANSITION SUPPORT (Shoutout: http://www.modernizr.com/)
|
||
// ============================================================
|
||
|
||
function transitionEnd() {
|
||
var el = document.createElement('bootstrap')
|
||
|
||
var transEndEventNames = {
|
||
WebkitTransition : 'webkitTransitionEnd',
|
||
MozTransition : 'transitionend',
|
||
OTransition : 'oTransitionEnd otransitionend',
|
||
transition : 'transitionend'
|
||
}
|
||
|
||
for (var name in transEndEventNames) {
|
||
if (el.style[name] !== undefined) {
|
||
return { end: transEndEventNames[name] }
|
||
}
|
||
}
|
||
|
||
return false // explicit for ie8 ( ._.)
|
||
}
|
||
|
||
// http://blog.alexmaccaw.com/css-transitions
|
||
$.fn.emulateTransitionEnd = function (duration) {
|
||
var called = false
|
||
var $el = this
|
||
$(this).one('bsTransitionEnd', function () { called = true })
|
||
var callback = function () { if (!called) $($el).trigger($.support.transition.end) }
|
||
setTimeout(callback, duration)
|
||
return this
|
||
}
|
||
|
||
$(function () {
|
||
$.support.transition = transitionEnd()
|
||
|
||
if (!$.support.transition) return
|
||
|
||
$.event.special.bsTransitionEnd = {
|
||
bindType: $.support.transition.end,
|
||
delegateType: $.support.transition.end,
|
||
handle: function (e) {
|
||
if ($(e.target).is(this)) return e.handleObj.handler.apply(this, arguments)
|
||
}
|
||
}
|
||
})
|
||
|
||
}(jQuery);
|
||
|
||
/* ========================================================================
|
||
* Bootstrap: alert.js v3.3.4
|
||
* http://getbootstrap.com/javascript/#alerts
|
||
* ========================================================================
|
||
* Copyright 2011-2015 Twitter, Inc.
|
||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
|
||
* ======================================================================== */
|
||
|
||
|
||
+function ($) {
|
||
'use strict';
|
||
|
||
// ALERT CLASS DEFINITION
|
||
// ======================
|
||
|
||
var dismiss = '[data-dismiss="alert"]'
|
||
var Alert = function (el) {
|
||
$(el).on('click', dismiss, this.close)
|
||
}
|
||
|
||
Alert.VERSION = '3.3.4'
|
||
|
||
Alert.TRANSITION_DURATION = 150
|
||
|
||
Alert.prototype.close = function (e) {
|
||
var $this = $(this)
|
||
var selector = $this.attr('data-target')
|
||
|
||
if (!selector) {
|
||
selector = $this.attr('href')
|
||
selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') // strip for ie7
|
||
}
|
||
|
||
var $parent = $(selector)
|
||
|
||
if (e) e.preventDefault()
|
||
|
||
if (!$parent.length) {
|
||
$parent = $this.closest('.alert')
|
||
}
|
||
|
||
$parent.trigger(e = $.Event('close.bs.alert'))
|
||
|
||
if (e.isDefaultPrevented()) return
|
||
|
||
$parent.removeClass('in')
|
||
|
||
function removeElement() {
|
||
// detach from parent, fire event then clean up data
|
||
$parent.detach().trigger('closed.bs.alert').remove()
|
||
}
|
||
|
||
$.support.transition && $parent.hasClass('fade') ?
|
||
$parent
|
||
.one('bsTransitionEnd', removeElement)
|
||
.emulateTransitionEnd(Alert.TRANSITION_DURATION) :
|
||
removeElement()
|
||
}
|
||
|
||
|
||
// ALERT PLUGIN DEFINITION
|
||
// =======================
|
||
|
||
function Plugin(option) {
|
||
return this.each(function () {
|
||
var $this = $(this)
|
||
var data = $this.data('bs.alert')
|
||
|
||
if (!data) $this.data('bs.alert', (data = new Alert(this)))
|
||
if (typeof option == 'string') data[option].call($this)
|
||
})
|
||
}
|
||
|
||
var old = $.fn.alert
|
||
|
||
$.fn.alert = Plugin
|
||
$.fn.alert.Constructor = Alert
|
||
|
||
|
||
// ALERT NO CONFLICT
|
||
// =================
|
||
|
||
$.fn.alert.noConflict = function () {
|
||
$.fn.alert = old
|
||
return this
|
||
}
|
||
|
||
|
||
// ALERT DATA-API
|
||
// ==============
|
||
|
||
$(document).on('click.bs.alert.data-api', dismiss, Alert.prototype.close)
|
||
|
||
}(jQuery);
|
||
|
||
/* ========================================================================
|
||
* Bootstrap: button.js v3.3.4
|
||
* http://getbootstrap.com/javascript/#buttons
|
||
* ========================================================================
|
||
* Copyright 2011-2015 Twitter, Inc.
|
||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
|
||
* ======================================================================== */
|
||
|
||
|
||
+function ($) {
|
||
'use strict';
|
||
|
||
// BUTTON PUBLIC CLASS DEFINITION
|
||
// ==============================
|
||
|
||
var Button = function (element, options) {
|
||
this.$element = $(element)
|
||
this.options = $.extend({}, Button.DEFAULTS, options)
|
||
this.isLoading = false
|
||
}
|
||
|
||
Button.VERSION = '3.3.4'
|
||
|
||
Button.DEFAULTS = {
|
||
loadingText: 'loading...'
|
||
}
|
||
|
||
Button.prototype.setState = function (state) {
|
||
var d = 'disabled'
|
||
var $el = this.$element
|
||
var val = $el.is('input') ? 'val' : 'html'
|
||
var data = $el.data()
|
||
|
||
state = state + 'Text'
|
||
|
||
if (data.resetText == null) $el.data('resetText', $el[val]())
|
||
|
||
// push to event loop to allow forms to submit
|
||
setTimeout($.proxy(function () {
|
||
$el[val](data[state] == null ? this.options[state] : data[state])
|
||
|
||
if (state == 'loadingText') {
|
||
this.isLoading = true
|
||
$el.addClass(d).attr(d, d)
|
||
} else if (this.isLoading) {
|
||
this.isLoading = false
|
||
$el.removeClass(d).removeAttr(d)
|
||
}
|
||
}, this), 0)
|
||
}
|
||
|
||
Button.prototype.toggle = function () {
|
||
var changed = true
|
||
var $parent = this.$element.closest('[data-toggle="buttons"]')
|
||
|
||
if ($parent.length) {
|
||
var $input = this.$element.find('input')
|
||
if ($input.prop('type') == 'radio') {
|
||
if ($input.prop('checked') && this.$element.hasClass('active')) changed = false
|
||
else $parent.find('.active').removeClass('active')
|
||
}
|
||
if (changed) $input.prop('checked', !this.$element.hasClass('active')).trigger('change')
|
||
} else {
|
||
this.$element.attr('aria-pressed', !this.$element.hasClass('active'))
|
||
}
|
||
|
||
if (changed) this.$element.toggleClass('active')
|
||
}
|
||
|
||
|
||
// BUTTON PLUGIN DEFINITION
|
||
// ========================
|
||
|
||
function Plugin(option) {
|
||
return this.each(function () {
|
||
var $this = $(this)
|
||
var data = $this.data('bs.button')
|
||
var options = typeof option == 'object' && option
|
||
|
||
if (!data) $this.data('bs.button', (data = new Button(this, options)))
|
||
|
||
if (option == 'toggle') data.toggle()
|
||
else if (option) data.setState(option)
|
||
})
|
||
}
|
||
|
||
var old = $.fn.button
|
||
|
||
$.fn.button = Plugin
|
||
$.fn.button.Constructor = Button
|
||
|
||
|
||
// BUTTON NO CONFLICT
|
||
// ==================
|
||
|
||
$.fn.button.noConflict = function () {
|
||
$.fn.button = old
|
||
return this
|
||
}
|
||
|
||
|
||
// BUTTON DATA-API
|
||
// ===============
|
||
|
||
$(document)
|
||
.on('click.bs.button.data-api', '[data-toggle^="button"]', function (e) {
|
||
var $btn = $(e.target)
|
||
if (!$btn.hasClass('btn')) $btn = $btn.closest('.btn')
|
||
Plugin.call($btn, 'toggle')
|
||
e.preventDefault()
|
||
})
|
||
.on('focus.bs.button.data-api blur.bs.button.data-api', '[data-toggle^="button"]', function (e) {
|
||
$(e.target).closest('.btn').toggleClass('focus', /^focus(in)?$/.test(e.type))
|
||
})
|
||
|
||
}(jQuery);
|
||
|
||
/* ========================================================================
|
||
* Bootstrap: carousel.js v3.3.4
|
||
* http://getbootstrap.com/javascript/#carousel
|
||
* ========================================================================
|
||
* Copyright 2011-2015 Twitter, Inc.
|
||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
|
||
* ======================================================================== */
|
||
|
||
|
||
+function ($) {
|
||
'use strict';
|
||
|
||
// CAROUSEL CLASS DEFINITION
|
||
// =========================
|
||
|
||
var Carousel = function (element, options) {
|
||
this.$element = $(element)
|
||
this.$indicators = this.$element.find('.carousel-indicators')
|
||
this.options = options
|
||
this.paused = null
|
||
this.sliding = null
|
||
this.interval = null
|
||
this.$active = null
|
||
this.$items = null
|
||
|
||
this.options.keyboard && this.$element.on('keydown.bs.carousel', $.proxy(this.keydown, this))
|
||
|
||
this.options.pause == 'hover' && !('ontouchstart' in document.documentElement) && this.$element
|
||
.on('mouseenter.bs.carousel', $.proxy(this.pause, this))
|
||
.on('mouseleave.bs.carousel', $.proxy(this.cycle, this))
|
||
}
|
||
|
||
Carousel.VERSION = '3.3.4'
|
||
|
||
Carousel.TRANSITION_DURATION = 600
|
||
|
||
Carousel.DEFAULTS = {
|
||
interval: 5000,
|
||
pause: 'hover',
|
||
wrap: true,
|
||
keyboard: true
|
||
}
|
||
|
||
Carousel.prototype.keydown = function (e) {
|
||
if (/input|textarea/i.test(e.target.tagName)) return
|
||
switch (e.which) {
|
||
case 37: this.prev(); break
|
||
case 39: this.next(); break
|
||
default: return
|
||
}
|
||
|
||
e.preventDefault()
|
||
}
|
||
|
||
Carousel.prototype.cycle = function (e) {
|
||
e || (this.paused = false)
|
||
|
||
this.interval && clearInterval(this.interval)
|
||
|
||
this.options.interval
|
||
&& !this.paused
|
||
&& (this.interval = setInterval($.proxy(this.next, this), this.options.interval))
|
||
|
||
return this
|
||
}
|
||
|
||
Carousel.prototype.getItemIndex = function (item) {
|
||
this.$items = item.parent().children('.item')
|
||
return this.$items.index(item || this.$active)
|
||
}
|
||
|
||
Carousel.prototype.getItemForDirection = function (direction, active) {
|
||
var activeIndex = this.getItemIndex(active)
|
||
var willWrap = (direction == 'prev' && activeIndex === 0)
|
||
|| (direction == 'next' && activeIndex == (this.$items.length - 1))
|
||
if (willWrap && !this.options.wrap) return active
|
||
var delta = direction == 'prev' ? -1 : 1
|
||
var itemIndex = (activeIndex + delta) % this.$items.length
|
||
return this.$items.eq(itemIndex)
|
||
}
|
||
|
||
Carousel.prototype.to = function (pos) {
|
||
var that = this
|
||
var activeIndex = this.getItemIndex(this.$active = this.$element.find('.item.active'))
|
||
|
||
if (pos > (this.$items.length - 1) || pos < 0) return
|
||
|
||
if (this.sliding) return this.$element.one('slid.bs.carousel', function () { that.to(pos) }) // yes, "slid"
|
||
if (activeIndex == pos) return this.pause().cycle()
|
||
|
||
return this.slide(pos > activeIndex ? 'next' : 'prev', this.$items.eq(pos))
|
||
}
|
||
|
||
Carousel.prototype.pause = function (e) {
|
||
e || (this.paused = true)
|
||
|
||
if (this.$element.find('.next, .prev').length && $.support.transition) {
|
||
this.$element.trigger($.support.transition.end)
|
||
this.cycle(true)
|
||
}
|
||
|
||
this.interval = clearInterval(this.interval)
|
||
|
||
return this
|
||
}
|
||
|
||
Carousel.prototype.next = function () {
|
||
if (this.sliding) return
|
||
return this.slide('next')
|
||
}
|
||
|
||
Carousel.prototype.prev = function () {
|
||
if (this.sliding) return
|
||
return this.slide('prev')
|
||
}
|
||
|
||
Carousel.prototype.slide = function (type, next) {
|
||
var $active = this.$element.find('.item.active')
|
||
var $next = next || this.getItemForDirection(type, $active)
|
||
var isCycling = this.interval
|
||
var direction = type == 'next' ? 'left' : 'right'
|
||
var that = this
|
||
|
||
if ($next.hasClass('active')) return (this.sliding = false)
|
||
|
||
var relatedTarget = $next[0]
|
||
var slideEvent = $.Event('slide.bs.carousel', {
|
||
relatedTarget: relatedTarget,
|
||
direction: direction
|
||
})
|
||
this.$element.trigger(slideEvent)
|
||
if (slideEvent.isDefaultPrevented()) return
|
||
|
||
this.sliding = true
|
||
|
||
isCycling && this.pause()
|
||
|
||
if (this.$indicators.length) {
|
||
this.$indicators.find('.active').removeClass('active')
|
||
var $nextIndicator = $(this.$indicators.children()[this.getItemIndex($next)])
|
||
$nextIndicator && $nextIndicator.addClass('active')
|
||
}
|
||
|
||
var slidEvent = $.Event('slid.bs.carousel', { relatedTarget: relatedTarget, direction: direction }) // yes, "slid"
|
||
if ($.support.transition && this.$element.hasClass('slide')) {
|
||
$next.addClass(type)
|
||
$next[0].offsetWidth // force reflow
|
||
$active.addClass(direction)
|
||
$next.addClass(direction)
|
||
$active
|
||
.one('bsTransitionEnd', function () {
|
||
$next.removeClass([type, direction].join(' ')).addClass('active')
|
||
$active.removeClass(['active', direction].join(' '))
|
||
that.sliding = false
|
||
setTimeout(function () {
|
||
that.$element.trigger(slidEvent)
|
||
}, 0)
|
||
})
|
||
.emulateTransitionEnd(Carousel.TRANSITION_DURATION)
|
||
} else {
|
||
$active.removeClass('active')
|
||
$next.addClass('active')
|
||
this.sliding = false
|
||
this.$element.trigger(slidEvent)
|
||
}
|
||
|
||
isCycling && this.cycle()
|
||
|
||
return this
|
||
}
|
||
|
||
|
||
// CAROUSEL PLUGIN DEFINITION
|
||
// ==========================
|
||
|
||
function Plugin(option) {
|
||
return this.each(function () {
|
||
var $this = $(this)
|
||
var data = $this.data('bs.carousel')
|
||
var options = $.extend({}, Carousel.DEFAULTS, $this.data(), typeof option == 'object' && option)
|
||
var action = typeof option == 'string' ? option : options.slide
|
||
|
||
if (!data) $this.data('bs.carousel', (data = new Carousel(this, options)))
|
||
if (typeof option == 'number') data.to(option)
|
||
else if (action) data[action]()
|
||
else if (options.interval) data.pause().cycle()
|
||
})
|
||
}
|
||
|
||
var old = $.fn.carousel
|
||
|
||
$.fn.carousel = Plugin
|
||
$.fn.carousel.Constructor = Carousel
|
||
|
||
|
||
// CAROUSEL NO CONFLICT
|
||
// ====================
|
||
|
||
$.fn.carousel.noConflict = function () {
|
||
$.fn.carousel = old
|
||
return this
|
||
}
|
||
|
||
|
||
// CAROUSEL DATA-API
|
||
// =================
|
||
|
||
var clickHandler = function (e) {
|
||
var href
|
||
var $this = $(this)
|
||
var $target = $($this.attr('data-target') || (href = $this.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '')) // strip for ie7
|
||
if (!$target.hasClass('carousel')) return
|
||
var options = $.extend({}, $target.data(), $this.data())
|
||
var slideIndex = $this.attr('data-slide-to')
|
||
if (slideIndex) options.interval = false
|
||
|
||
Plugin.call($target, options)
|
||
|
||
if (slideIndex) {
|
||
$target.data('bs.carousel').to(slideIndex)
|
||
}
|
||
|
||
e.preventDefault()
|
||
}
|
||
|
||
$(document)
|
||
.on('click.bs.carousel.data-api', '[data-slide]', clickHandler)
|
||
.on('click.bs.carousel.data-api', '[data-slide-to]', clickHandler)
|
||
|
||
$(window).on('load', function () {
|
||
$('[data-ride="carousel"]').each(function () {
|
||
var $carousel = $(this)
|
||
Plugin.call($carousel, $carousel.data())
|
||
})
|
||
})
|
||
|
||
}(jQuery);
|
||
|
||
/* ========================================================================
|
||
* Bootstrap: collapse.js v3.3.4
|
||
* http://getbootstrap.com/javascript/#collapse
|
||
* ========================================================================
|
||
* Copyright 2011-2015 Twitter, Inc.
|
||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
|
||
* ======================================================================== */
|
||
|
||
|
||
+function ($) {
|
||
'use strict';
|
||
|
||
// COLLAPSE PUBLIC CLASS DEFINITION
|
||
// ================================
|
||
|
||
var Collapse = function (element, options) {
|
||
this.$element = $(element)
|
||
this.options = $.extend({}, Collapse.DEFAULTS, options)
|
||
this.$trigger = $('[data-toggle="collapse"][href="#' + element.id + '"],' +
|
||
'[data-toggle="collapse"][data-target="#' + element.id + '"]')
|
||
this.transitioning = null
|
||
|
||
if (this.options.parent) {
|
||
this.$parent = this.getParent()
|
||
} else {
|
||
this.addAriaAndCollapsedClass(this.$element, this.$trigger)
|
||
}
|
||
|
||
if (this.options.toggle) this.toggle()
|
||
}
|
||
|
||
Collapse.VERSION = '3.3.4'
|
||
|
||
Collapse.TRANSITION_DURATION = 350
|
||
|
||
Collapse.DEFAULTS = {
|
||
toggle: true
|
||
}
|
||
|
||
Collapse.prototype.dimension = function () {
|
||
var hasWidth = this.$element.hasClass('width')
|
||
return hasWidth ? 'width' : 'height'
|
||
}
|
||
|
||
Collapse.prototype.show = function () {
|
||
if (this.transitioning || this.$element.hasClass('in')) return
|
||
|
||
var activesData
|
||
var actives = this.$parent && this.$parent.children('.panel').children('.in, .collapsing')
|
||
|
||
if (actives && actives.length) {
|
||
activesData = actives.data('bs.collapse')
|
||
if (activesData && activesData.transitioning) return
|
||
}
|
||
|
||
var startEvent = $.Event('show.bs.collapse')
|
||
this.$element.trigger(startEvent)
|
||
if (startEvent.isDefaultPrevented()) return
|
||
|
||
if (actives && actives.length) {
|
||
Plugin.call(actives, 'hide')
|
||
activesData || actives.data('bs.collapse', null)
|
||
}
|
||
|
||
var dimension = this.dimension()
|
||
|
||
this.$element
|
||
.removeClass('collapse')
|
||
.addClass('collapsing')[dimension](0)
|
||
.attr('aria-expanded', true)
|
||
|
||
this.$trigger
|
||
.removeClass('collapsed')
|
||
.attr('aria-expanded', true)
|
||
|
||
this.transitioning = 1
|
||
|
||
var complete = function () {
|
||
this.$element
|
||
.removeClass('collapsing')
|
||
.addClass('collapse in')[dimension]('')
|
||
this.transitioning = 0
|
||
this.$element
|
||
.trigger('shown.bs.collapse')
|
||
}
|
||
|
||
if (!$.support.transition) return complete.call(this)
|
||
|
||
var scrollSize = $.camelCase(['scroll', dimension].join('-'))
|
||
|
||
this.$element
|
||
.one('bsTransitionEnd', $.proxy(complete, this))
|
||
.emulateTransitionEnd(Collapse.TRANSITION_DURATION)[dimension](this.$element[0][scrollSize])
|
||
}
|
||
|
||
Collapse.prototype.hide = function () {
|
||
if (this.transitioning || !this.$element.hasClass('in')) return
|
||
|
||
var startEvent = $.Event('hide.bs.collapse')
|
||
this.$element.trigger(startEvent)
|
||
if (startEvent.isDefaultPrevented()) return
|
||
|
||
var dimension = this.dimension()
|
||
|
||
this.$element[dimension](this.$element[dimension]())[0].offsetHeight
|
||
|
||
this.$element
|
||
.addClass('collapsing')
|
||
.removeClass('collapse in')
|
||
.attr('aria-expanded', false)
|
||
|
||
this.$trigger
|
||
.addClass('collapsed')
|
||
.attr('aria-expanded', false)
|
||
|
||
this.transitioning = 1
|
||
|
||
var complete = function () {
|
||
this.transitioning = 0
|
||
this.$element
|
||
.removeClass('collapsing')
|
||
.addClass('collapse')
|
||
.trigger('hidden.bs.collapse')
|
||
}
|
||
|
||
if (!$.support.transition) return complete.call(this)
|
||
|
||
this.$element
|
||
[dimension](0)
|
||
.one('bsTransitionEnd', $.proxy(complete, this))
|
||
.emulateTransitionEnd(Collapse.TRANSITION_DURATION)
|
||
}
|
||
|
||
Collapse.prototype.toggle = function () {
|
||
this[this.$element.hasClass('in') ? 'hide' : 'show']()
|
||
}
|
||
|
||
Collapse.prototype.getParent = function () {
|
||
return $(this.options.parent)
|
||
.find('[data-toggle="collapse"][data-parent="' + this.options.parent + '"]')
|
||
.each($.proxy(function (i, element) {
|
||
var $element = $(element)
|
||
this.addAriaAndCollapsedClass(getTargetFromTrigger($element), $element)
|
||
}, this))
|
||
.end()
|
||
}
|
||
|
||
Collapse.prototype.addAriaAndCollapsedClass = function ($element, $trigger) {
|
||
var isOpen = $element.hasClass('in')
|
||
|
||
$element.attr('aria-expanded', isOpen)
|
||
$trigger
|
||
.toggleClass('collapsed', !isOpen)
|
||
.attr('aria-expanded', isOpen)
|
||
}
|
||
|
||
function getTargetFromTrigger($trigger) {
|
||
var href
|
||
var target = $trigger.attr('data-target')
|
||
|| (href = $trigger.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '') // strip for ie7
|
||
|
||
return $(target)
|
||
}
|
||
|
||
|
||
// COLLAPSE PLUGIN DEFINITION
|
||
// ==========================
|
||
|
||
function Plugin(option) {
|
||
return this.each(function () {
|
||
var $this = $(this)
|
||
var data = $this.data('bs.collapse')
|
||
var options = $.extend({}, Collapse.DEFAULTS, $this.data(), typeof option == 'object' && option)
|
||
|
||
if (!data && options.toggle && /show|hide/.test(option)) options.toggle = false
|
||
if (!data) $this.data('bs.collapse', (data = new Collapse(this, options)))
|
||
if (typeof option == 'string') data[option]()
|
||
})
|
||
}
|
||
|
||
var old = $.fn.collapse
|
||
|
||
$.fn.collapse = Plugin
|
||
$.fn.collapse.Constructor = Collapse
|
||
|
||
|
||
// COLLAPSE NO CONFLICT
|
||
// ====================
|
||
|
||
$.fn.collapse.noConflict = function () {
|
||
$.fn.collapse = old
|
||
return this
|
||
}
|
||
|
||
|
||
// COLLAPSE DATA-API
|
||
// =================
|
||
|
||
$(document).on('click.bs.collapse.data-api', '[data-toggle="collapse"]', function (e) {
|
||
var $this = $(this)
|
||
|
||
if (!$this.attr('data-target')) e.preventDefault()
|
||
|
||
var $target = getTargetFromTrigger($this)
|
||
var data = $target.data('bs.collapse')
|
||
var option = data ? 'toggle' : $this.data()
|
||
|
||
Plugin.call($target, option)
|
||
})
|
||
|
||
}(jQuery);
|
||
|
||
/* ========================================================================
|
||
* Bootstrap: dropdown.js v3.3.4
|
||
* http://getbootstrap.com/javascript/#dropdowns
|
||
* ========================================================================
|
||
* Copyright 2011-2015 Twitter, Inc.
|
||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
|
||
* ======================================================================== */
|
||
|
||
|
||
+function ($) {
|
||
'use strict';
|
||
|
||
// DROPDOWN CLASS DEFINITION
|
||
// =========================
|
||
|
||
var backdrop = '.dropdown-backdrop'
|
||
var toggle = '[data-toggle="dropdown"]'
|
||
var Dropdown = function (element) {
|
||
$(element).on('click.bs.dropdown', this.toggle)
|
||
}
|
||
|
||
Dropdown.VERSION = '3.3.4'
|
||
|
||
Dropdown.prototype.toggle = function (e) {
|
||
var $this = $(this)
|
||
|
||
if ($this.is('.disabled, :disabled')) return
|
||
|
||
var $parent = getParent($this)
|
||
var isActive = $parent.hasClass('open')
|
||
|
||
clearMenus()
|
||
|
||
if (!isActive) {
|
||
if ('ontouchstart' in document.documentElement && !$parent.closest('.navbar-nav').length) {
|
||
// if mobile we use a backdrop because click events don't delegate
|
||
$('<div class="dropdown-backdrop"/>').insertAfter($(this)).on('click', clearMenus)
|
||
}
|
||
|
||
var relatedTarget = { relatedTarget: this }
|
||
$parent.trigger(e = $.Event('show.bs.dropdown', relatedTarget))
|
||
|
||
if (e.isDefaultPrevented()) return
|
||
|
||
$this
|
||
.trigger('focus')
|
||
.attr('aria-expanded', 'true')
|
||
|
||
$parent
|
||
.toggleClass('open')
|
||
.trigger('shown.bs.dropdown', relatedTarget)
|
||
}
|
||
|
||
return false
|
||
}
|
||
|
||
Dropdown.prototype.keydown = function (e) {
|
||
if (!/(38|40|27|32)/.test(e.which) || /input|textarea/i.test(e.target.tagName)) return
|
||
|
||
var $this = $(this)
|
||
|
||
e.preventDefault()
|
||
e.stopPropagation()
|
||
|
||
if ($this.is('.disabled, :disabled')) return
|
||
|
||
var $parent = getParent($this)
|
||
var isActive = $parent.hasClass('open')
|
||
|
||
if ((!isActive && e.which != 27) || (isActive && e.which == 27)) {
|
||
if (e.which == 27) $parent.find(toggle).trigger('focus')
|
||
return $this.trigger('click')
|
||
}
|
||
|
||
var desc = ' li:not(.disabled):visible a'
|
||
var $items = $parent.find('[role="menu"]' + desc + ', [role="listbox"]' + desc)
|
||
|
||
if (!$items.length) return
|
||
|
||
var index = $items.index(e.target)
|
||
|
||
if (e.which == 38 && index > 0) index-- // up
|
||
if (e.which == 40 && index < $items.length - 1) index++ // down
|
||
if (!~index) index = 0
|
||
|
||
$items.eq(index).trigger('focus')
|
||
}
|
||
|
||
function clearMenus(e) {
|
||
if (e && e.which === 3) return
|
||
$(backdrop).remove()
|
||
$(toggle).each(function () {
|
||
var $this = $(this)
|
||
var $parent = getParent($this)
|
||
var relatedTarget = { relatedTarget: this }
|
||
|
||
if (!$parent.hasClass('open')) return
|
||
|
||
$parent.trigger(e = $.Event('hide.bs.dropdown', relatedTarget))
|
||
|
||
if (e.isDefaultPrevented()) return
|
||
|
||
$this.attr('aria-expanded', 'false')
|
||
$parent.removeClass('open').trigger('hidden.bs.dropdown', relatedTarget)
|
||
})
|
||
}
|
||
|
||
function getParent($this) {
|
||
var selector = $this.attr('data-target')
|
||
|
||
if (!selector) {
|
||
selector = $this.attr('href')
|
||
selector = selector && /#[A-Za-z]/.test(selector) && selector.replace(/.*(?=#[^\s]*$)/, '') // strip for ie7
|
||
}
|
||
|
||
var $parent = selector && $(selector)
|
||
|
||
return $parent && $parent.length ? $parent : $this.parent()
|
||
}
|
||
|
||
|
||
// DROPDOWN PLUGIN DEFINITION
|
||
// ==========================
|
||
|
||
function Plugin(option) {
|
||
return this.each(function () {
|
||
var $this = $(this)
|
||
var data = $this.data('bs.dropdown')
|
||
|
||
if (!data) $this.data('bs.dropdown', (data = new Dropdown(this)))
|
||
if (typeof option == 'string') data[option].call($this)
|
||
})
|
||
}
|
||
|
||
var old = $.fn.dropdown
|
||
|
||
$.fn.dropdown = Plugin
|
||
$.fn.dropdown.Constructor = Dropdown
|
||
|
||
|
||
// DROPDOWN NO CONFLICT
|
||
// ====================
|
||
|
||
$.fn.dropdown.noConflict = function () {
|
||
$.fn.dropdown = old
|
||
return this
|
||
}
|
||
|
||
|
||
// APPLY TO STANDARD DROPDOWN ELEMENTS
|
||
// ===================================
|
||
|
||
$(document)
|
||
.on('click.bs.dropdown.data-api', clearMenus)
|
||
.on('click.bs.dropdown.data-api', '.dropdown form', function (e) { e.stopPropagation() })
|
||
.on('click.bs.dropdown.data-api', toggle, Dropdown.prototype.toggle)
|
||
.on('keydown.bs.dropdown.data-api', toggle, Dropdown.prototype.keydown)
|
||
.on('keydown.bs.dropdown.data-api', '[role="menu"]', Dropdown.prototype.keydown)
|
||
.on('keydown.bs.dropdown.data-api', '[role="listbox"]', Dropdown.prototype.keydown)
|
||
|
||
}(jQuery);
|
||
|
||
/* ========================================================================
|
||
* Bootstrap: modal.js v3.3.4
|
||
* http://getbootstrap.com/javascript/#modals
|
||
* ========================================================================
|
||
* Copyright 2011-2015 Twitter, Inc.
|
||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
|
||
* ======================================================================== */
|
||
|
||
|
||
+function ($) {
|
||
'use strict';
|
||
|
||
// MODAL CLASS DEFINITION
|
||
// ======================
|
||
|
||
var Modal = function (element, options) {
|
||
this.options = options
|
||
this.$body = $(document.body)
|
||
this.$element = $(element)
|
||
this.$dialog = this.$element.find('.modal-dialog')
|
||
this.$backdrop = null
|
||
this.isShown = null
|
||
this.originalBodyPad = null
|
||
this.scrollbarWidth = 0
|
||
this.ignoreBackdropClick = false
|
||
|
||
if (this.options.remote) {
|
||
this.$element
|
||
.find('.modal-content')
|
||
.load(this.options.remote, $.proxy(function () {
|
||
this.$element.trigger('loaded.bs.modal')
|
||
}, this))
|
||
}
|
||
}
|
||
|
||
Modal.VERSION = '3.3.4'
|
||
|
||
Modal.TRANSITION_DURATION = 300
|
||
Modal.BACKDROP_TRANSITION_DURATION = 150
|
||
|
||
Modal.DEFAULTS = {
|
||
backdrop: true,
|
||
keyboard: true,
|
||
show: true
|
||
}
|
||
|
||
Modal.prototype.toggle = function (_relatedTarget) {
|
||
return this.isShown ? this.hide() : this.show(_relatedTarget)
|
||
}
|
||
|
||
Modal.prototype.show = function (_relatedTarget) {
|
||
var that = this
|
||
var e = $.Event('show.bs.modal', { relatedTarget: _relatedTarget })
|
||
|
||
this.$element.trigger(e)
|
||
|
||
if (this.isShown || e.isDefaultPrevented()) return
|
||
|
||
this.isShown = true
|
||
|
||
this.checkScrollbar()
|
||
this.setScrollbar()
|
||
this.$body.addClass('modal-open')
|
||
|
||
this.escape()
|
||
this.resize()
|
||
|
||
this.$element.on('click.dismiss.bs.modal', '[data-dismiss="modal"]', $.proxy(this.hide, this))
|
||
|
||
this.$dialog.on('mousedown.dismiss.bs.modal', function () {
|
||
that.$element.one('mouseup.dismiss.bs.modal', function (e) {
|
||
if ($(e.target).is(that.$element)) that.ignoreBackdropClick = true
|
||
})
|
||
})
|
||
|
||
this.backdrop(function () {
|
||
var transition = $.support.transition && that.$element.hasClass('fade')
|
||
|
||
if (!that.$element.parent().length) {
|
||
that.$element.appendTo(that.$body) // don't move modals dom position
|
||
}
|
||
|
||
that.$element
|
||
.show()
|
||
.scrollTop(0)
|
||
|
||
that.adjustDialog()
|
||
|
||
if (transition) {
|
||
that.$element[0].offsetWidth // force reflow
|
||
}
|
||
|
||
that.$element
|
||
.addClass('in')
|
||
.attr('aria-hidden', false)
|
||
|
||
that.enforceFocus()
|
||
|
||
var e = $.Event('shown.bs.modal', { relatedTarget: _relatedTarget })
|
||
|
||
transition ?
|
||
that.$dialog // wait for modal to slide in
|
||
.one('bsTransitionEnd', function () {
|
||
that.$element.trigger('focus').trigger(e)
|
||
})
|
||
.emulateTransitionEnd(Modal.TRANSITION_DURATION) :
|
||
that.$element.trigger('focus').trigger(e)
|
||
})
|
||
}
|
||
|
||
Modal.prototype.hide = function (e) {
|
||
if (e) e.preventDefault()
|
||
|
||
e = $.Event('hide.bs.modal')
|
||
|
||
this.$element.trigger(e)
|
||
|
||
if (!this.isShown || e.isDefaultPrevented()) return
|
||
|
||
this.isShown = false
|
||
|
||
this.escape()
|
||
this.resize()
|
||
|
||
$(document).off('focusin.bs.modal')
|
||
|
||
this.$element
|
||
.removeClass('in')
|
||
.attr('aria-hidden', true)
|
||
.off('click.dismiss.bs.modal')
|
||
.off('mouseup.dismiss.bs.modal')
|
||
|
||
this.$dialog.off('mousedown.dismiss.bs.modal')
|
||
|
||
$.support.transition && this.$element.hasClass('fade') ?
|
||
this.$element
|
||
.one('bsTransitionEnd', $.proxy(this.hideModal, this))
|
||
.emulateTransitionEnd(Modal.TRANSITION_DURATION) :
|
||
this.hideModal()
|
||
}
|
||
|
||
Modal.prototype.enforceFocus = function () {
|
||
$(document)
|
||
.off('focusin.bs.modal') // guard against infinite focus loop
|
||
.on('focusin.bs.modal', $.proxy(function (e) {
|
||
if (this.$element[0] !== e.target && !this.$element.has(e.target).length) {
|
||
this.$element.trigger('focus')
|
||
}
|
||
}, this))
|
||
}
|
||
|
||
Modal.prototype.escape = function () {
|
||
if (this.isShown && this.options.keyboard) {
|
||
this.$element.on('keydown.dismiss.bs.modal', $.proxy(function (e) {
|
||
e.which == 27 && this.hide()
|
||
}, this))
|
||
} else if (!this.isShown) {
|
||
this.$element.off('keydown.dismiss.bs.modal')
|
||
}
|
||
}
|
||
|
||
Modal.prototype.resize = function () {
|
||
if (this.isShown) {
|
||
$(window).on('resize.bs.modal', $.proxy(this.handleUpdate, this))
|
||
} else {
|
||
$(window).off('resize.bs.modal')
|
||
}
|
||
}
|
||
|
||
Modal.prototype.hideModal = function () {
|
||
var that = this
|
||
this.$element.hide()
|
||
this.backdrop(function () {
|
||
that.$body.removeClass('modal-open')
|
||
that.resetAdjustments()
|
||
that.resetScrollbar()
|
||
that.$element.trigger('hidden.bs.modal')
|
||
})
|
||
}
|
||
|
||
Modal.prototype.removeBackdrop = function () {
|
||
this.$backdrop && this.$backdrop.remove()
|
||
this.$backdrop = null
|
||
}
|
||
|
||
Modal.prototype.backdrop = function (callback) {
|
||
var that = this
|
||
var animate = this.$element.hasClass('fade') ? 'fade' : ''
|
||
|
||
if (this.isShown && this.options.backdrop) {
|
||
var doAnimate = $.support.transition && animate
|
||
|
||
this.$backdrop = $('<div class="modal-backdrop ' + animate + '" />')
|
||
.appendTo(this.$body)
|
||
|
||
this.$element.on('click.dismiss.bs.modal', $.proxy(function (e) {
|
||
if (this.ignoreBackdropClick) {
|
||
this.ignoreBackdropClick = false
|
||
return
|
||
}
|
||
if (e.target !== e.currentTarget) return
|
||
this.options.backdrop == 'static'
|
||
? this.$element[0].focus()
|
||
: this.hide()
|
||
}, this))
|
||
|
||
if (doAnimate) this.$backdrop[0].offsetWidth // force reflow
|
||
|
||
this.$backdrop.addClass('in')
|
||
|
||
if (!callback) return
|
||
|
||
doAnimate ?
|
||
this.$backdrop
|
||
.one('bsTransitionEnd', callback)
|
||
.emulateTransitionEnd(Modal.BACKDROP_TRANSITION_DURATION) :
|
||
callback()
|
||
|
||
} else if (!this.isShown && this.$backdrop) {
|
||
this.$backdrop.removeClass('in')
|
||
|
||
var callbackRemove = function () {
|
||
that.removeBackdrop()
|
||
callback && callback()
|
||
}
|
||
$.support.transition && this.$element.hasClass('fade') ?
|
||
this.$backdrop
|
||
.one('bsTransitionEnd', callbackRemove)
|
||
.emulateTransitionEnd(Modal.BACKDROP_TRANSITION_DURATION) :
|
||
callbackRemove()
|
||
|
||
} else if (callback) {
|
||
callback()
|
||
}
|
||
}
|
||
|
||
// these following methods are used to handle overflowing modals
|
||
|
||
Modal.prototype.handleUpdate = function () {
|
||
this.adjustDialog()
|
||
}
|
||
|
||
Modal.prototype.adjustDialog = function () {
|
||
var modalIsOverflowing = this.$element[0].scrollHeight > document.documentElement.clientHeight
|
||
|
||
this.$element.css({
|
||
paddingLeft: !this.bodyIsOverflowing && modalIsOverflowing ? this.scrollbarWidth : '',
|
||
paddingRight: this.bodyIsOverflowing && !modalIsOverflowing ? this.scrollbarWidth : ''
|
||
})
|
||
}
|
||
|
||
Modal.prototype.resetAdjustments = function () {
|
||
this.$element.css({
|
||
paddingLeft: '',
|
||
paddingRight: ''
|
||
})
|
||
}
|
||
|
||
Modal.prototype.checkScrollbar = function () {
|
||
var fullWindowWidth = window.innerWidth
|
||
if (!fullWindowWidth) { // workaround for missing window.innerWidth in IE8
|
||
var documentElementRect = document.documentElement.getBoundingClientRect()
|
||
fullWindowWidth = documentElementRect.right - Math.abs(documentElementRect.left)
|
||
}
|
||
this.bodyIsOverflowing = document.body.clientWidth < fullWindowWidth
|
||
this.scrollbarWidth = this.measureScrollbar()
|
||
}
|
||
|
||
Modal.prototype.setScrollbar = function () {
|
||
var bodyPad = parseInt((this.$body.css('padding-right') || 0), 10)
|
||
this.originalBodyPad = document.body.style.paddingRight || ''
|
||
if (this.bodyIsOverflowing) this.$body.css('padding-right', bodyPad + this.scrollbarWidth)
|
||
}
|
||
|
||
Modal.prototype.resetScrollbar = function () {
|
||
this.$body.css('padding-right', this.originalBodyPad)
|
||
}
|
||
|
||
Modal.prototype.measureScrollbar = function () { // thx walsh
|
||
var scrollDiv = document.createElement('div')
|
||
scrollDiv.className = 'modal-scrollbar-measure'
|
||
this.$body.append(scrollDiv)
|
||
var scrollbarWidth = scrollDiv.offsetWidth - scrollDiv.clientWidth
|
||
this.$body[0].removeChild(scrollDiv)
|
||
return scrollbarWidth
|
||
}
|
||
|
||
|
||
// MODAL PLUGIN DEFINITION
|
||
// =======================
|
||
|
||
function Plugin(option, _relatedTarget) {
|
||
return this.each(function () {
|
||
var $this = $(this)
|
||
var data = $this.data('bs.modal')
|
||
var options = $.extend({}, Modal.DEFAULTS, $this.data(), typeof option == 'object' && option)
|
||
|
||
if (!data) $this.data('bs.modal', (data = new Modal(this, options)))
|
||
if (typeof option == 'string') data[option](_relatedTarget)
|
||
else if (options.show) data.show(_relatedTarget)
|
||
})
|
||
}
|
||
|
||
var old = $.fn.modal
|
||
|
||
$.fn.modal = Plugin
|
||
$.fn.modal.Constructor = Modal
|
||
|
||
|
||
// MODAL NO CONFLICT
|
||
// =================
|
||
|
||
$.fn.modal.noConflict = function () {
|
||
$.fn.modal = old
|
||
return this
|
||
}
|
||
|
||
|
||
// MODAL DATA-API
|
||
// ==============
|
||
|
||
$(document).on('click.bs.modal.data-api', '[data-toggle="modal"]', function (e) {
|
||
var $this = $(this)
|
||
var href = $this.attr('href')
|
||
var $target = $($this.attr('data-target') || (href && href.replace(/.*(?=#[^\s]+$)/, ''))) // strip for ie7
|
||
var option = $target.data('bs.modal') ? 'toggle' : $.extend({ remote: !/#/.test(href) && href }, $target.data(), $this.data())
|
||
|
||
if ($this.is('a')) e.preventDefault()
|
||
|
||
$target.one('show.bs.modal', function (showEvent) {
|
||
if (showEvent.isDefaultPrevented()) return // only register focus restorer if modal will actually get shown
|
||
$target.one('hidden.bs.modal', function () {
|
||
$this.is(':visible') && $this.trigger('focus')
|
||
})
|
||
})
|
||
Plugin.call($target, option, this)
|
||
})
|
||
|
||
}(jQuery);
|
||
|
||
/* ========================================================================
|
||
* Bootstrap: tooltip.js v3.3.4
|
||
* http://getbootstrap.com/javascript/#tooltip
|
||
* Inspired by the original jQuery.tipsy by Jason Frame
|
||
* ========================================================================
|
||
* Copyright 2011-2015 Twitter, Inc.
|
||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
|
||
* ======================================================================== */
|
||
|
||
|
||
+function ($) {
|
||
'use strict';
|
||
|
||
// TOOLTIP PUBLIC CLASS DEFINITION
|
||
// ===============================
|
||
|
||
var Tooltip = function (element, options) {
|
||
this.type = null
|
||
this.options = null
|
||
this.enabled = null
|
||
this.timeout = null
|
||
this.hoverState = null
|
||
this.$element = null
|
||
|
||
this.init('tooltip', element, options)
|
||
}
|
||
|
||
Tooltip.VERSION = '3.3.4'
|
||
|
||
Tooltip.TRANSITION_DURATION = 150
|
||
|
||
Tooltip.DEFAULTS = {
|
||
animation: true,
|
||
placement: 'top',
|
||
selector: false,
|
||
template: '<div class="tooltip" role="tooltip"><div class="tooltip-arrow"></div><div class="tooltip-inner"></div></div>',
|
||
trigger: 'hover focus',
|
||
title: '',
|
||
delay: 0,
|
||
html: false,
|
||
container: false,
|
||
viewport: {
|
||
selector: 'body',
|
||
padding: 0
|
||
}
|
||
}
|
||
|
||
Tooltip.prototype.init = function (type, element, options) {
|
||
this.enabled = true
|
||
this.type = type
|
||
this.$element = $(element)
|
||
this.options = this.getOptions(options)
|
||
this.$viewport = this.options.viewport && $(this.options.viewport.selector || this.options.viewport)
|
||
|
||
if (this.$element[0] instanceof document.constructor && !this.options.selector) {
|
||
throw new Error('`selector` option must be specified when initializing ' + this.type + ' on the window.document object!')
|
||
}
|
||
|
||
var triggers = this.options.trigger.split(' ')
|
||
|
||
for (var i = triggers.length; i--;) {
|
||
var trigger = triggers[i]
|
||
|
||
if (trigger == 'click') {
|
||
this.$element.on('click.' + this.type, this.options.selector, $.proxy(this.toggle, this))
|
||
} else if (trigger != 'manual') {
|
||
var eventIn = trigger == 'hover' ? 'mouseenter' : 'focusin'
|
||
var eventOut = trigger == 'hover' ? 'mouseleave' : 'focusout'
|
||
|
||
this.$element.on(eventIn + '.' + this.type, this.options.selector, $.proxy(this.enter, this))
|
||
this.$element.on(eventOut + '.' + this.type, this.options.selector, $.proxy(this.leave, this))
|
||
}
|
||
}
|
||
|
||
this.options.selector ?
|
||
(this._options = $.extend({}, this.options, { trigger: 'manual', selector: '' })) :
|
||
this.fixTitle()
|
||
}
|
||
|
||
Tooltip.prototype.getDefaults = function () {
|
||
return Tooltip.DEFAULTS
|
||
}
|
||
|
||
Tooltip.prototype.getOptions = function (options) {
|
||
options = $.extend({}, this.getDefaults(), this.$element.data(), options)
|
||
|
||
if (options.delay && typeof options.delay == 'number') {
|
||
options.delay = {
|
||
show: options.delay,
|
||
hide: options.delay
|
||
}
|
||
}
|
||
|
||
return options
|
||
}
|
||
|
||
Tooltip.prototype.getDelegateOptions = function () {
|
||
var options = {}
|
||
var defaults = this.getDefaults()
|
||
|
||
this._options && $.each(this._options, function (key, value) {
|
||
if (defaults[key] != value) options[key] = value
|
||
})
|
||
|
||
return options
|
||
}
|
||
|
||
Tooltip.prototype.enter = function (obj) {
|
||
var self = obj instanceof this.constructor ?
|
||
obj : $(obj.currentTarget).data('bs.' + this.type)
|
||
|
||
if (self && self.$tip && self.$tip.is(':visible')) {
|
||
self.hoverState = 'in'
|
||
return
|
||
}
|
||
|
||
if (!self) {
|
||
self = new this.constructor(obj.currentTarget, this.getDelegateOptions())
|
||
$(obj.currentTarget).data('bs.' + this.type, self)
|
||
}
|
||
|
||
clearTimeout(self.timeout)
|
||
|
||
self.hoverState = 'in'
|
||
|
||
if (!self.options.delay || !self.options.delay.show) return self.show()
|
||
|
||
self.timeout = setTimeout(function () {
|
||
if (self.hoverState == 'in') self.show()
|
||
}, self.options.delay.show)
|
||
}
|
||
|
||
Tooltip.prototype.leave = function (obj) {
|
||
var self = obj instanceof this.constructor ?
|
||
obj : $(obj.currentTarget).data('bs.' + this.type)
|
||
|
||
if (!self) {
|
||
self = new this.constructor(obj.currentTarget, this.getDelegateOptions())
|
||
$(obj.currentTarget).data('bs.' + this.type, self)
|
||
}
|
||
|
||
clearTimeout(self.timeout)
|
||
|
||
self.hoverState = 'out'
|
||
|
||
if (!self.options.delay || !self.options.delay.hide) return self.hide()
|
||
|
||
self.timeout = setTimeout(function () {
|
||
if (self.hoverState == 'out') self.hide()
|
||
}, self.options.delay.hide)
|
||
}
|
||
|
||
Tooltip.prototype.show = function () {
|
||
var e = $.Event('show.bs.' + this.type)
|
||
|
||
if (this.hasContent() && this.enabled) {
|
||
this.$element.trigger(e)
|
||
|
||
var inDom = $.contains(this.$element[0].ownerDocument.documentElement, this.$element[0])
|
||
if (e.isDefaultPrevented() || !inDom) return
|
||
var that = this
|
||
|
||
var $tip = this.tip()
|
||
|
||
var tipId = this.getUID(this.type)
|
||
|
||
this.setContent()
|
||
$tip.attr('id', tipId)
|
||
this.$element.attr('aria-describedby', tipId)
|
||
|
||
if (this.options.animation) $tip.addClass('fade')
|
||
|
||
var placement = typeof this.options.placement == 'function' ?
|
||
this.options.placement.call(this, $tip[0], this.$element[0]) :
|
||
this.options.placement
|
||
|
||
var autoToken = /\s?auto?\s?/i
|
||
var autoPlace = autoToken.test(placement)
|
||
if (autoPlace) placement = placement.replace(autoToken, '') || 'top'
|
||
|
||
$tip
|
||
.detach()
|
||
.css({ top: 0, left: 0, display: 'block' })
|
||
.addClass(placement)
|
||
.data('bs.' + this.type, this)
|
||
|
||
this.options.container ? $tip.appendTo(this.options.container) : $tip.insertAfter(this.$element)
|
||
|
||
var pos = this.getPosition()
|
||
var actualWidth = $tip[0].offsetWidth
|
||
var actualHeight = $tip[0].offsetHeight
|
||
|
||
if (autoPlace) {
|
||
var orgPlacement = placement
|
||
var $container = this.options.container ? $(this.options.container) : this.$element.parent()
|
||
var containerDim = this.getPosition($container)
|
||
|
||
placement = placement == 'bottom' && pos.bottom + actualHeight > containerDim.bottom ? 'top' :
|
||
placement == 'top' && pos.top - actualHeight < containerDim.top ? 'bottom' :
|
||
placement == 'right' && pos.right + actualWidth > containerDim.width ? 'left' :
|
||
placement == 'left' && pos.left - actualWidth < containerDim.left ? 'right' :
|
||
placement
|
||
|
||
$tip
|
||
.removeClass(orgPlacement)
|
||
.addClass(placement)
|
||
}
|
||
|
||
var calculatedOffset = this.getCalculatedOffset(placement, pos, actualWidth, actualHeight)
|
||
|
||
this.applyPlacement(calculatedOffset, placement)
|
||
|
||
var complete = function () {
|
||
var prevHoverState = that.hoverState
|
||
that.$element.trigger('shown.bs.' + that.type)
|
||
that.hoverState = null
|
||
|
||
if (prevHoverState == 'out') that.leave(that)
|
||
}
|
||
|
||
$.support.transition && this.$tip.hasClass('fade') ?
|
||
$tip
|
||
.one('bsTransitionEnd', complete)
|
||
.emulateTransitionEnd(Tooltip.TRANSITION_DURATION) :
|
||
complete()
|
||
}
|
||
}
|
||
|
||
Tooltip.prototype.applyPlacement = function (offset, placement) {
|
||
var $tip = this.tip()
|
||
var width = $tip[0].offsetWidth
|
||
var height = $tip[0].offsetHeight
|
||
|
||
// manually read margins because getBoundingClientRect includes difference
|
||
var marginTop = parseInt($tip.css('margin-top'), 10)
|
||
var marginLeft = parseInt($tip.css('margin-left'), 10)
|
||
|
||
// we must check for NaN for ie 8/9
|
||
if (isNaN(marginTop)) marginTop = 0
|
||
if (isNaN(marginLeft)) marginLeft = 0
|
||
|
||
offset.top = offset.top + marginTop
|
||
offset.left = offset.left + marginLeft
|
||
|
||
// $.fn.offset doesn't round pixel values
|
||
// so we use setOffset directly with our own function B-0
|
||
$.offset.setOffset($tip[0], $.extend({
|
||
using: function (props) {
|
||
$tip.css({
|
||
top: Math.round(props.top),
|
||
left: Math.round(props.left)
|
||
})
|
||
}
|
||
}, offset), 0)
|
||
|
||
$tip.addClass('in')
|
||
|
||
// check to see if placing tip in new offset caused the tip to resize itself
|
||
var actualWidth = $tip[0].offsetWidth
|
||
var actualHeight = $tip[0].offsetHeight
|
||
|
||
if (placement == 'top' && actualHeight != height) {
|
||
offset.top = offset.top + height - actualHeight
|
||
}
|
||
|
||
var delta = this.getViewportAdjustedDelta(placement, offset, actualWidth, actualHeight)
|
||
|
||
if (delta.left) offset.left += delta.left
|
||
else offset.top += delta.top
|
||
|
||
var isVertical = /top|bottom/.test(placement)
|
||
var arrowDelta = isVertical ? delta.left * 2 - width + actualWidth : delta.top * 2 - height + actualHeight
|
||
var arrowOffsetPosition = isVertical ? 'offsetWidth' : 'offsetHeight'
|
||
|
||
$tip.offset(offset)
|
||
this.replaceArrow(arrowDelta, $tip[0][arrowOffsetPosition], isVertical)
|
||
}
|
||
|
||
Tooltip.prototype.replaceArrow = function (delta, dimension, isVertical) {
|
||
this.arrow()
|
||
.css(isVertical ? 'left' : 'top', 50 * (1 - delta / dimension) + '%')
|
||
.css(isVertical ? 'top' : 'left', '')
|
||
}
|
||
|
||
Tooltip.prototype.setContent = function () {
|
||
var $tip = this.tip()
|
||
var title = this.getTitle()
|
||
|
||
$tip.find('.tooltip-inner')[this.options.html ? 'html' : 'text'](title)
|
||
$tip.removeClass('fade in top bottom left right')
|
||
}
|
||
|
||
Tooltip.prototype.hide = function (callback) {
|
||
var that = this
|
||
var $tip = $(this.$tip)
|
||
var e = $.Event('hide.bs.' + this.type)
|
||
|
||
function complete() {
|
||
if (that.hoverState != 'in') $tip.detach()
|
||
that.$element
|
||
.removeAttr('aria-describedby')
|
||
.trigger('hidden.bs.' + that.type)
|
||
callback && callback()
|
||
}
|
||
|
||
this.$element.trigger(e)
|
||
|
||
if (e.isDefaultPrevented()) return
|
||
|
||
$tip.removeClass('in')
|
||
|
||
$.support.transition && $tip.hasClass('fade') ?
|
||
$tip
|
||
.one('bsTransitionEnd', complete)
|
||
.emulateTransitionEnd(Tooltip.TRANSITION_DURATION) :
|
||
complete()
|
||
|
||
this.hoverState = null
|
||
|
||
return this
|
||
}
|
||
|
||
Tooltip.prototype.fixTitle = function () {
|
||
var $e = this.$element
|
||
if ($e.attr('title') || typeof ($e.attr('data-original-title')) != 'string') {
|
||
$e.attr('data-original-title', $e.attr('title') || '').attr('title', '')
|
||
}
|
||
}
|
||
|
||
Tooltip.prototype.hasContent = function () {
|
||
return this.getTitle()
|
||
}
|
||
|
||
Tooltip.prototype.getPosition = function ($element) {
|
||
$element = $element || this.$element
|
||
|
||
var el = $element[0]
|
||
var isBody = el.tagName == 'BODY'
|
||
|
||
var elRect = el.getBoundingClientRect()
|
||
if (elRect.width == null) {
|
||
// width and height are missing in IE8, so compute them manually; see https://github.com/twbs/bootstrap/issues/14093
|
||
elRect = $.extend({}, elRect, { width: elRect.right - elRect.left, height: elRect.bottom - elRect.top })
|
||
}
|
||
var elOffset = isBody ? { top: 0, left: 0 } : $element.offset()
|
||
var scroll = { scroll: isBody ? document.documentElement.scrollTop || document.body.scrollTop : $element.scrollTop() }
|
||
var outerDims = isBody ? { width: $(window).width(), height: $(window).height() } : null
|
||
|
||
return $.extend({}, elRect, scroll, outerDims, elOffset)
|
||
}
|
||
|
||
Tooltip.prototype.getCalculatedOffset = function (placement, pos, actualWidth, actualHeight) {
|
||
return placement == 'bottom' ? { top: pos.top + pos.height, left: pos.left + pos.width / 2 - actualWidth / 2 } :
|
||
placement == 'top' ? { top: pos.top - actualHeight, left: pos.left + pos.width / 2 - actualWidth / 2 } :
|
||
placement == 'left' ? { top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left - actualWidth } :
|
||
/* placement == 'right' */ { top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left + pos.width }
|
||
|
||
}
|
||
|
||
Tooltip.prototype.getViewportAdjustedDelta = function (placement, pos, actualWidth, actualHeight) {
|
||
var delta = { top: 0, left: 0 }
|
||
if (!this.$viewport) return delta
|
||
|
||
var viewportPadding = this.options.viewport && this.options.viewport.padding || 0
|
||
var viewportDimensions = this.getPosition(this.$viewport)
|
||
|
||
if (/right|left/.test(placement)) {
|
||
var topEdgeOffset = pos.top - viewportPadding - viewportDimensions.scroll
|
||
var bottomEdgeOffset = pos.top + viewportPadding - viewportDimensions.scroll + actualHeight
|
||
if (topEdgeOffset < viewportDimensions.top) { // top overflow
|
||
delta.top = viewportDimensions.top - topEdgeOffset
|
||
} else if (bottomEdgeOffset > viewportDimensions.top + viewportDimensions.height) { // bottom overflow
|
||
delta.top = viewportDimensions.top + viewportDimensions.height - bottomEdgeOffset
|
||
}
|
||
} else {
|
||
var leftEdgeOffset = pos.left - viewportPadding
|
||
var rightEdgeOffset = pos.left + viewportPadding + actualWidth
|
||
if (leftEdgeOffset < viewportDimensions.left) { // left overflow
|
||
delta.left = viewportDimensions.left - leftEdgeOffset
|
||
} else if (rightEdgeOffset > viewportDimensions.width) { // right overflow
|
||
delta.left = viewportDimensions.left + viewportDimensions.width - rightEdgeOffset
|
||
}
|
||
}
|
||
|
||
return delta
|
||
}
|
||
|
||
Tooltip.prototype.getTitle = function () {
|
||
var title
|
||
var $e = this.$element
|
||
var o = this.options
|
||
|
||
title = $e.attr('data-original-title')
|
||
|| (typeof o.title == 'function' ? o.title.call($e[0]) : o.title)
|
||
|
||
return title
|
||
}
|
||
|
||
Tooltip.prototype.getUID = function (prefix) {
|
||
do prefix += ~~(Math.random() * 1000000)
|
||
while (document.getElementById(prefix))
|
||
return prefix
|
||
}
|
||
|
||
Tooltip.prototype.tip = function () {
|
||
return (this.$tip = this.$tip || $(this.options.template))
|
||
}
|
||
|
||
Tooltip.prototype.arrow = function () {
|
||
return (this.$arrow = this.$arrow || this.tip().find('.tooltip-arrow'))
|
||
}
|
||
|
||
Tooltip.prototype.enable = function () {
|
||
this.enabled = true
|
||
}
|
||
|
||
Tooltip.prototype.disable = function () {
|
||
this.enabled = false
|
||
}
|
||
|
||
Tooltip.prototype.toggleEnabled = function () {
|
||
this.enabled = !this.enabled
|
||
}
|
||
|
||
Tooltip.prototype.toggle = function (e) {
|
||
var self = this
|
||
if (e) {
|
||
self = $(e.currentTarget).data('bs.' + this.type)
|
||
if (!self) {
|
||
self = new this.constructor(e.currentTarget, this.getDelegateOptions())
|
||
$(e.currentTarget).data('bs.' + this.type, self)
|
||
}
|
||
}
|
||
|
||
self.tip().hasClass('in') ? self.leave(self) : self.enter(self)
|
||
}
|
||
|
||
Tooltip.prototype.destroy = function () {
|
||
var that = this
|
||
clearTimeout(this.timeout)
|
||
this.hide(function () {
|
||
that.$element.off('.' + that.type).removeData('bs.' + that.type)
|
||
})
|
||
}
|
||
|
||
|
||
// TOOLTIP PLUGIN DEFINITION
|
||
// =========================
|
||
|
||
function Plugin(option) {
|
||
return this.each(function () {
|
||
var $this = $(this)
|
||
var data = $this.data('bs.tooltip')
|
||
var options = typeof option == 'object' && option
|
||
|
||
if (!data && /destroy|hide/.test(option)) return
|
||
if (!data) $this.data('bs.tooltip', (data = new Tooltip(this, options)))
|
||
if (typeof option == 'string') data[option]()
|
||
})
|
||
}
|
||
|
||
var old = $.fn.tooltip
|
||
|
||
$.fn.tooltip = Plugin
|
||
$.fn.tooltip.Constructor = Tooltip
|
||
|
||
|
||
// TOOLTIP NO CONFLICT
|
||
// ===================
|
||
|
||
$.fn.tooltip.noConflict = function () {
|
||
$.fn.tooltip = old
|
||
return this
|
||
}
|
||
|
||
}(jQuery);
|
||
|
||
/* ========================================================================
|
||
* Bootstrap: popover.js v3.3.4
|
||
* http://getbootstrap.com/javascript/#popovers
|
||
* ========================================================================
|
||
* Copyright 2011-2015 Twitter, Inc.
|
||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
|
||
* ======================================================================== */
|
||
|
||
|
||
+function ($) {
|
||
'use strict';
|
||
|
||
// POPOVER PUBLIC CLASS DEFINITION
|
||
// ===============================
|
||
|
||
var Popover = function (element, options) {
|
||
this.init('popover', element, options)
|
||
}
|
||
|
||
if (!$.fn.tooltip) throw new Error('Popover requires tooltip.js')
|
||
|
||
Popover.VERSION = '3.3.4'
|
||
|
||
Popover.DEFAULTS = $.extend({}, $.fn.tooltip.Constructor.DEFAULTS, {
|
||
placement: 'right',
|
||
trigger: 'click',
|
||
content: '',
|
||
template: '<div class="popover" role="tooltip"><div class="arrow"></div><h3 class="popover-title"></h3><div class="popover-content"></div></div>'
|
||
})
|
||
|
||
|
||
// NOTE: POPOVER EXTENDS tooltip.js
|
||
// ================================
|
||
|
||
Popover.prototype = $.extend({}, $.fn.tooltip.Constructor.prototype)
|
||
|
||
Popover.prototype.constructor = Popover
|
||
|
||
Popover.prototype.getDefaults = function () {
|
||
return Popover.DEFAULTS
|
||
}
|
||
|
||
Popover.prototype.setContent = function () {
|
||
var $tip = this.tip()
|
||
var title = this.getTitle()
|
||
var content = this.getContent()
|
||
|
||
$tip.find('.popover-title')[this.options.html ? 'html' : 'text'](title)
|
||
$tip.find('.popover-content').children().detach().end()[ // we use append for html objects to maintain js events
|
||
this.options.html ? (typeof content == 'string' ? 'html' : 'append') : 'text'
|
||
](content)
|
||
|
||
$tip.removeClass('fade top bottom left right in')
|
||
|
||
// IE8 doesn't accept hiding via the `:empty` pseudo selector, we have to do
|
||
// this manually by checking the contents.
|
||
if (!$tip.find('.popover-title').html()) $tip.find('.popover-title').hide()
|
||
}
|
||
|
||
Popover.prototype.hasContent = function () {
|
||
return this.getTitle() || this.getContent()
|
||
}
|
||
|
||
Popover.prototype.getContent = function () {
|
||
var $e = this.$element
|
||
var o = this.options
|
||
|
||
return $e.attr('data-content')
|
||
|| (typeof o.content == 'function' ?
|
||
o.content.call($e[0]) :
|
||
o.content)
|
||
}
|
||
|
||
Popover.prototype.arrow = function () {
|
||
return (this.$arrow = this.$arrow || this.tip().find('.arrow'))
|
||
}
|
||
|
||
|
||
// POPOVER PLUGIN DEFINITION
|
||
// =========================
|
||
|
||
function Plugin(option) {
|
||
return this.each(function () {
|
||
var $this = $(this)
|
||
var data = $this.data('bs.popover')
|
||
var options = typeof option == 'object' && option
|
||
|
||
if (!data && /destroy|hide/.test(option)) return
|
||
if (!data) $this.data('bs.popover', (data = new Popover(this, options)))
|
||
if (typeof option == 'string') data[option]()
|
||
})
|
||
}
|
||
|
||
var old = $.fn.popover
|
||
|
||
$.fn.popover = Plugin
|
||
$.fn.popover.Constructor = Popover
|
||
|
||
|
||
// POPOVER NO CONFLICT
|
||
// ===================
|
||
|
||
$.fn.popover.noConflict = function () {
|
||
$.fn.popover = old
|
||
return this
|
||
}
|
||
|
||
}(jQuery);
|
||
|
||
/* ========================================================================
|
||
* Bootstrap: scrollspy.js v3.3.4
|
||
* http://getbootstrap.com/javascript/#scrollspy
|
||
* ========================================================================
|
||
* Copyright 2011-2015 Twitter, Inc.
|
||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
|
||
* ======================================================================== */
|
||
|
||
|
||
+function ($) {
|
||
'use strict';
|
||
|
||
// SCROLLSPY CLASS DEFINITION
|
||
// ==========================
|
||
|
||
function ScrollSpy(element, options) {
|
||
this.$body = $(document.body)
|
||
this.$scrollElement = $(element).is(document.body) ? $(window) : $(element)
|
||
this.options = $.extend({}, ScrollSpy.DEFAULTS, options)
|
||
this.selector = (this.options.target || '') + ' .nav li > a'
|
||
this.offsets = []
|
||
this.targets = []
|
||
this.activeTarget = null
|
||
this.scrollHeight = 0
|
||
|
||
this.$scrollElement.on('scroll.bs.scrollspy', $.proxy(this.process, this))
|
||
this.refresh()
|
||
this.process()
|
||
}
|
||
|
||
ScrollSpy.VERSION = '3.3.4'
|
||
|
||
ScrollSpy.DEFAULTS = {
|
||
offset: 10
|
||
}
|
||
|
||
ScrollSpy.prototype.getScrollHeight = function () {
|
||
return this.$scrollElement[0].scrollHeight || Math.max(this.$body[0].scrollHeight, document.documentElement.scrollHeight)
|
||
}
|
||
|
||
ScrollSpy.prototype.refresh = function () {
|
||
var that = this
|
||
var offsetMethod = 'offset'
|
||
var offsetBase = 0
|
||
|
||
this.offsets = []
|
||
this.targets = []
|
||
this.scrollHeight = this.getScrollHeight()
|
||
|
||
if (!$.isWindow(this.$scrollElement[0])) {
|
||
offsetMethod = 'position'
|
||
offsetBase = this.$scrollElement.scrollTop()
|
||
}
|
||
|
||
this.$body
|
||
.find(this.selector)
|
||
.map(function () {
|
||
var $el = $(this)
|
||
var href = $el.data('target') || $el.attr('href')
|
||
var $href = /^#./.test(href) && $(href)
|
||
|
||
return ($href
|
||
&& $href.length
|
||
&& $href.is(':visible')
|
||
&& [[$href[offsetMethod]().top + offsetBase, href]]) || null
|
||
})
|
||
.sort(function (a, b) { return a[0] - b[0] })
|
||
.each(function () {
|
||
that.offsets.push(this[0])
|
||
that.targets.push(this[1])
|
||
})
|
||
}
|
||
|
||
ScrollSpy.prototype.process = function () {
|
||
var scrollTop = this.$scrollElement.scrollTop() + this.options.offset
|
||
var scrollHeight = this.getScrollHeight()
|
||
var maxScroll = this.options.offset + scrollHeight - this.$scrollElement.height()
|
||
var offsets = this.offsets
|
||
var targets = this.targets
|
||
var activeTarget = this.activeTarget
|
||
var i
|
||
|
||
if (this.scrollHeight != scrollHeight) {
|
||
this.refresh()
|
||
}
|
||
|
||
if (scrollTop >= maxScroll) {
|
||
return activeTarget != (i = targets[targets.length - 1]) && this.activate(i)
|
||
}
|
||
|
||
if (activeTarget && scrollTop < offsets[0]) {
|
||
this.activeTarget = null
|
||
return this.clear()
|
||
}
|
||
|
||
for (i = offsets.length; i--;) {
|
||
activeTarget != targets[i]
|
||
&& scrollTop >= offsets[i]
|
||
&& (offsets[i + 1] === undefined || scrollTop < offsets[i + 1])
|
||
&& this.activate(targets[i])
|
||
}
|
||
}
|
||
|
||
ScrollSpy.prototype.activate = function (target) {
|
||
this.activeTarget = target
|
||
|
||
this.clear()
|
||
|
||
var selector = this.selector +
|
||
'[data-target="' + target + '"],' +
|
||
this.selector + '[href="' + target + '"]'
|
||
|
||
var active = $(selector)
|
||
.parents('li')
|
||
.addClass('active')
|
||
|
||
if (active.parent('.dropdown-menu').length) {
|
||
active = active
|
||
.closest('li.dropdown')
|
||
.addClass('active')
|
||
}
|
||
|
||
active.trigger('activate.bs.scrollspy')
|
||
}
|
||
|
||
ScrollSpy.prototype.clear = function () {
|
||
$(this.selector)
|
||
.parentsUntil(this.options.target, '.active')
|
||
.removeClass('active')
|
||
}
|
||
|
||
|
||
// SCROLLSPY PLUGIN DEFINITION
|
||
// ===========================
|
||
|
||
function Plugin(option) {
|
||
return this.each(function () {
|
||
var $this = $(this)
|
||
var data = $this.data('bs.scrollspy')
|
||
var options = typeof option == 'object' && option
|
||
|
||
if (!data) $this.data('bs.scrollspy', (data = new ScrollSpy(this, options)))
|
||
if (typeof option == 'string') data[option]()
|
||
})
|
||
}
|
||
|
||
var old = $.fn.scrollspy
|
||
|
||
$.fn.scrollspy = Plugin
|
||
$.fn.scrollspy.Constructor = ScrollSpy
|
||
|
||
|
||
// SCROLLSPY NO CONFLICT
|
||
// =====================
|
||
|
||
$.fn.scrollspy.noConflict = function () {
|
||
$.fn.scrollspy = old
|
||
return this
|
||
}
|
||
|
||
|
||
// SCROLLSPY DATA-API
|
||
// ==================
|
||
|
||
$(window).on('load.bs.scrollspy.data-api', function () {
|
||
$('[data-spy="scroll"]').each(function () {
|
||
var $spy = $(this)
|
||
Plugin.call($spy, $spy.data())
|
||
})
|
||
})
|
||
|
||
}(jQuery);
|
||
|
||
/* ========================================================================
|
||
* Bootstrap: tab.js v3.3.4
|
||
* http://getbootstrap.com/javascript/#tabs
|
||
* ========================================================================
|
||
* Copyright 2011-2015 Twitter, Inc.
|
||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
|
||
* ======================================================================== */
|
||
|
||
|
||
+function ($) {
|
||
'use strict';
|
||
|
||
// TAB CLASS DEFINITION
|
||
// ====================
|
||
|
||
var Tab = function (element) {
|
||
this.element = $(element)
|
||
}
|
||
|
||
Tab.VERSION = '3.3.4'
|
||
|
||
Tab.TRANSITION_DURATION = 150
|
||
|
||
Tab.prototype.show = function () {
|
||
var $this = this.element
|
||
var $ul = $this.closest('ul:not(.dropdown-menu)')
|
||
var selector = $this.data('target')
|
||
|
||
if (!selector) {
|
||
selector = $this.attr('href')
|
||
selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') // strip for ie7
|
||
}
|
||
|
||
if ($this.parent('li').hasClass('active')) return
|
||
|
||
var $previous = $ul.find('.active:last a')
|
||
var hideEvent = $.Event('hide.bs.tab', {
|
||
relatedTarget: $this[0]
|
||
})
|
||
var showEvent = $.Event('show.bs.tab', {
|
||
relatedTarget: $previous[0]
|
||
})
|
||
|
||
$previous.trigger(hideEvent)
|
||
$this.trigger(showEvent)
|
||
|
||
if (showEvent.isDefaultPrevented() || hideEvent.isDefaultPrevented()) return
|
||
|
||
var $target = $(selector)
|
||
|
||
this.activate($this.closest('li'), $ul)
|
||
this.activate($target, $target.parent(), function () {
|
||
$previous.trigger({
|
||
type: 'hidden.bs.tab',
|
||
relatedTarget: $this[0]
|
||
})
|
||
$this.trigger({
|
||
type: 'shown.bs.tab',
|
||
relatedTarget: $previous[0]
|
||
})
|
||
})
|
||
}
|
||
|
||
Tab.prototype.activate = function (element, container, callback) {
|
||
var $active = container.find('> .active')
|
||
var transition = callback
|
||
&& $.support.transition
|
||
&& (($active.length && $active.hasClass('fade')) || !!container.find('> .fade').length)
|
||
|
||
function next() {
|
||
$active
|
||
.removeClass('active')
|
||
.find('> .dropdown-menu > .active')
|
||
.removeClass('active')
|
||
.end()
|
||
.find('[data-toggle="tab"]')
|
||
.attr('aria-expanded', false)
|
||
|
||
element
|
||
.addClass('active')
|
||
.find('[data-toggle="tab"]')
|
||
.attr('aria-expanded', true)
|
||
|
||
if (transition) {
|
||
element[0].offsetWidth // reflow for transition
|
||
element.addClass('in')
|
||
} else {
|
||
element.removeClass('fade')
|
||
}
|
||
|
||
if (element.parent('.dropdown-menu').length) {
|
||
element
|
||
.closest('li.dropdown')
|
||
.addClass('active')
|
||
.end()
|
||
.find('[data-toggle="tab"]')
|
||
.attr('aria-expanded', true)
|
||
}
|
||
|
||
callback && callback()
|
||
}
|
||
|
||
$active.length && transition ?
|
||
$active
|
||
.one('bsTransitionEnd', next)
|
||
.emulateTransitionEnd(Tab.TRANSITION_DURATION) :
|
||
next()
|
||
|
||
$active.removeClass('in')
|
||
}
|
||
|
||
|
||
// TAB PLUGIN DEFINITION
|
||
// =====================
|
||
|
||
function Plugin(option) {
|
||
return this.each(function () {
|
||
var $this = $(this)
|
||
var data = $this.data('bs.tab')
|
||
|
||
if (!data) $this.data('bs.tab', (data = new Tab(this)))
|
||
if (typeof option == 'string') data[option]()
|
||
})
|
||
}
|
||
|
||
var old = $.fn.tab
|
||
|
||
$.fn.tab = Plugin
|
||
$.fn.tab.Constructor = Tab
|
||
|
||
|
||
// TAB NO CONFLICT
|
||
// ===============
|
||
|
||
$.fn.tab.noConflict = function () {
|
||
$.fn.tab = old
|
||
return this
|
||
}
|
||
|
||
|
||
// TAB DATA-API
|
||
// ============
|
||
|
||
var clickHandler = function (e) {
|
||
e.preventDefault()
|
||
Plugin.call($(this), 'show')
|
||
}
|
||
|
||
$(document)
|
||
.on('click.bs.tab.data-api', '[data-toggle="tab"]', clickHandler)
|
||
.on('click.bs.tab.data-api', '[data-toggle="pill"]', clickHandler)
|
||
|
||
}(jQuery);
|
||
|
||
/* ========================================================================
|
||
* Bootstrap: affix.js v3.3.4
|
||
* http://getbootstrap.com/javascript/#affix
|
||
* ========================================================================
|
||
* Copyright 2011-2015 Twitter, Inc.
|
||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
|
||
* ======================================================================== */
|
||
|
||
|
||
+function ($) {
|
||
'use strict';
|
||
|
||
// AFFIX CLASS DEFINITION
|
||
// ======================
|
||
|
||
var Affix = function (element, options) {
|
||
this.options = $.extend({}, Affix.DEFAULTS, options)
|
||
|
||
this.$target = $(this.options.target)
|
||
.on('scroll.bs.affix.data-api', $.proxy(this.checkPosition, this))
|
||
.on('click.bs.affix.data-api', $.proxy(this.checkPositionWithEventLoop, this))
|
||
|
||
this.$element = $(element)
|
||
this.affixed = null
|
||
this.unpin = null
|
||
this.pinnedOffset = null
|
||
|
||
this.checkPosition()
|
||
}
|
||
|
||
Affix.VERSION = '3.3.4'
|
||
|
||
Affix.RESET = 'affix affix-top affix-bottom'
|
||
|
||
Affix.DEFAULTS = {
|
||
offset: 0,
|
||
target: window
|
||
}
|
||
|
||
Affix.prototype.getState = function (scrollHeight, height, offsetTop, offsetBottom) {
|
||
var scrollTop = this.$target.scrollTop()
|
||
var position = this.$element.offset()
|
||
var targetHeight = this.$target.height()
|
||
|
||
if (offsetTop != null && this.affixed == 'top') return scrollTop < offsetTop ? 'top' : false
|
||
|
||
if (this.affixed == 'bottom') {
|
||
if (offsetTop != null) return (scrollTop + this.unpin <= position.top) ? false : 'bottom'
|
||
return (scrollTop + targetHeight <= scrollHeight - offsetBottom) ? false : 'bottom'
|
||
}
|
||
|
||
var initializing = this.affixed == null
|
||
var colliderTop = initializing ? scrollTop : position.top
|
||
var colliderHeight = initializing ? targetHeight : height
|
||
|
||
if (offsetTop != null && scrollTop <= offsetTop) return 'top'
|
||
if (offsetBottom != null && (colliderTop + colliderHeight >= scrollHeight - offsetBottom)) return 'bottom'
|
||
|
||
return false
|
||
}
|
||
|
||
Affix.prototype.getPinnedOffset = function () {
|
||
if (this.pinnedOffset) return this.pinnedOffset
|
||
this.$element.removeClass(Affix.RESET).addClass('affix')
|
||
var scrollTop = this.$target.scrollTop()
|
||
var position = this.$element.offset()
|
||
return (this.pinnedOffset = position.top - scrollTop)
|
||
}
|
||
|
||
Affix.prototype.checkPositionWithEventLoop = function () {
|
||
setTimeout($.proxy(this.checkPosition, this), 1)
|
||
}
|
||
|
||
Affix.prototype.checkPosition = function () {
|
||
if (!this.$element.is(':visible')) return
|
||
|
||
var height = this.$element.height()
|
||
var offset = this.options.offset
|
||
var offsetTop = offset.top
|
||
var offsetBottom = offset.bottom
|
||
var scrollHeight = $(document.body).height()
|
||
|
||
if (typeof offset != 'object') offsetBottom = offsetTop = offset
|
||
if (typeof offsetTop == 'function') offsetTop = offset.top(this.$element)
|
||
if (typeof offsetBottom == 'function') offsetBottom = offset.bottom(this.$element)
|
||
|
||
var affix = this.getState(scrollHeight, height, offsetTop, offsetBottom)
|
||
|
||
if (this.affixed != affix) {
|
||
if (this.unpin != null) this.$element.css('top', '')
|
||
|
||
var affixType = 'affix' + (affix ? '-' + affix : '')
|
||
var e = $.Event(affixType + '.bs.affix')
|
||
|
||
this.$element.trigger(e)
|
||
|
||
if (e.isDefaultPrevented()) return
|
||
|
||
this.affixed = affix
|
||
this.unpin = affix == 'bottom' ? this.getPinnedOffset() : null
|
||
|
||
this.$element
|
||
.removeClass(Affix.RESET)
|
||
.addClass(affixType)
|
||
.trigger(affixType.replace('affix', 'affixed') + '.bs.affix')
|
||
}
|
||
|
||
if (affix == 'bottom') {
|
||
this.$element.offset({
|
||
top: scrollHeight - height - offsetBottom
|
||
})
|
||
}
|
||
}
|
||
|
||
|
||
// AFFIX PLUGIN DEFINITION
|
||
// =======================
|
||
|
||
function Plugin(option) {
|
||
return this.each(function () {
|
||
var $this = $(this)
|
||
var data = $this.data('bs.affix')
|
||
var options = typeof option == 'object' && option
|
||
|
||
if (!data) $this.data('bs.affix', (data = new Affix(this, options)))
|
||
if (typeof option == 'string') data[option]()
|
||
})
|
||
}
|
||
|
||
var old = $.fn.affix
|
||
|
||
$.fn.affix = Plugin
|
||
$.fn.affix.Constructor = Affix
|
||
|
||
|
||
// AFFIX NO CONFLICT
|
||
// =================
|
||
|
||
$.fn.affix.noConflict = function () {
|
||
$.fn.affix = old
|
||
return this
|
||
}
|
||
|
||
|
||
// AFFIX DATA-API
|
||
// ==============
|
||
|
||
$(window).on('load', function () {
|
||
$('[data-spy="affix"]').each(function () {
|
||
var $spy = $(this)
|
||
var data = $spy.data()
|
||
|
||
data.offset = data.offset || {}
|
||
|
||
if (data.offsetBottom != null) data.offset.bottom = data.offsetBottom
|
||
if (data.offsetTop != null) data.offset.top = data.offsetTop
|
||
|
||
Plugin.call($spy, data)
|
||
})
|
||
})
|
||
|
||
}(jQuery);
|
||
|
||
|
||
/***/ }),
|
||
/* 12 */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
"use strict";
|
||
/* WEBPACK VAR INJECTION */(function(global) {/*!
|
||
* Vue.js v2.4.4
|
||
* (c) 2014-2017 Evan You
|
||
* Released under the MIT License.
|
||
*/
|
||
|
||
|
||
/* */
|
||
|
||
// these helpers produces better vm code in JS engines due to their
|
||
// explicitness and function inlining
|
||
function isUndef (v) {
|
||
return v === undefined || v === null
|
||
}
|
||
|
||
function isDef (v) {
|
||
return v !== undefined && v !== null
|
||
}
|
||
|
||
function isTrue (v) {
|
||
return v === true
|
||
}
|
||
|
||
function isFalse (v) {
|
||
return v === false
|
||
}
|
||
|
||
/**
|
||
* Check if value is primitive
|
||
*/
|
||
function isPrimitive (value) {
|
||
return (
|
||
typeof value === 'string' ||
|
||
typeof value === 'number' ||
|
||
typeof value === 'boolean'
|
||
)
|
||
}
|
||
|
||
/**
|
||
* Quick object check - this is primarily used to tell
|
||
* Objects from primitive values when we know the value
|
||
* is a JSON-compliant type.
|
||
*/
|
||
function isObject (obj) {
|
||
return obj !== null && typeof obj === 'object'
|
||
}
|
||
|
||
var _toString = Object.prototype.toString;
|
||
|
||
/**
|
||
* Strict object type check. Only returns true
|
||
* for plain JavaScript objects.
|
||
*/
|
||
function isPlainObject (obj) {
|
||
return _toString.call(obj) === '[object Object]'
|
||
}
|
||
|
||
function isRegExp (v) {
|
||
return _toString.call(v) === '[object RegExp]'
|
||
}
|
||
|
||
/**
|
||
* Check if val is a valid array index.
|
||
*/
|
||
function isValidArrayIndex (val) {
|
||
var n = parseFloat(val);
|
||
return n >= 0 && Math.floor(n) === n && isFinite(val)
|
||
}
|
||
|
||
/**
|
||
* Convert a value to a string that is actually rendered.
|
||
*/
|
||
function toString (val) {
|
||
return val == null
|
||
? ''
|
||
: typeof val === 'object'
|
||
? JSON.stringify(val, null, 2)
|
||
: String(val)
|
||
}
|
||
|
||
/**
|
||
* Convert a input value to a number for persistence.
|
||
* If the conversion fails, return original string.
|
||
*/
|
||
function toNumber (val) {
|
||
var n = parseFloat(val);
|
||
return isNaN(n) ? val : n
|
||
}
|
||
|
||
/**
|
||
* Make a map and return a function for checking if a key
|
||
* is in that map.
|
||
*/
|
||
function makeMap (
|
||
str,
|
||
expectsLowerCase
|
||
) {
|
||
var map = Object.create(null);
|
||
var list = str.split(',');
|
||
for (var i = 0; i < list.length; i++) {
|
||
map[list[i]] = true;
|
||
}
|
||
return expectsLowerCase
|
||
? function (val) { return map[val.toLowerCase()]; }
|
||
: function (val) { return map[val]; }
|
||
}
|
||
|
||
/**
|
||
* Check if a tag is a built-in tag.
|
||
*/
|
||
var isBuiltInTag = makeMap('slot,component', true);
|
||
|
||
/**
|
||
* Check if a attribute is a reserved attribute.
|
||
*/
|
||
var isReservedAttribute = makeMap('key,ref,slot,is');
|
||
|
||
/**
|
||
* Remove an item from an array
|
||
*/
|
||
function remove (arr, item) {
|
||
if (arr.length) {
|
||
var index = arr.indexOf(item);
|
||
if (index > -1) {
|
||
return arr.splice(index, 1)
|
||
}
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Check whether the object has the property.
|
||
*/
|
||
var hasOwnProperty = Object.prototype.hasOwnProperty;
|
||
function hasOwn (obj, key) {
|
||
return hasOwnProperty.call(obj, key)
|
||
}
|
||
|
||
/**
|
||
* Create a cached version of a pure function.
|
||
*/
|
||
function cached (fn) {
|
||
var cache = Object.create(null);
|
||
return (function cachedFn (str) {
|
||
var hit = cache[str];
|
||
return hit || (cache[str] = fn(str))
|
||
})
|
||
}
|
||
|
||
/**
|
||
* Camelize a hyphen-delimited string.
|
||
*/
|
||
var camelizeRE = /-(\w)/g;
|
||
var camelize = cached(function (str) {
|
||
return str.replace(camelizeRE, function (_, c) { return c ? c.toUpperCase() : ''; })
|
||
});
|
||
|
||
/**
|
||
* Capitalize a string.
|
||
*/
|
||
var capitalize = cached(function (str) {
|
||
return str.charAt(0).toUpperCase() + str.slice(1)
|
||
});
|
||
|
||
/**
|
||
* Hyphenate a camelCase string.
|
||
*/
|
||
var hyphenateRE = /\B([A-Z])/g;
|
||
var hyphenate = cached(function (str) {
|
||
return str.replace(hyphenateRE, '-$1').toLowerCase()
|
||
});
|
||
|
||
/**
|
||
* Simple bind, faster than native
|
||
*/
|
||
function bind (fn, ctx) {
|
||
function boundFn (a) {
|
||
var l = arguments.length;
|
||
return l
|
||
? l > 1
|
||
? fn.apply(ctx, arguments)
|
||
: fn.call(ctx, a)
|
||
: fn.call(ctx)
|
||
}
|
||
// record original fn length
|
||
boundFn._length = fn.length;
|
||
return boundFn
|
||
}
|
||
|
||
/**
|
||
* Convert an Array-like object to a real Array.
|
||
*/
|
||
function toArray (list, start) {
|
||
start = start || 0;
|
||
var i = list.length - start;
|
||
var ret = new Array(i);
|
||
while (i--) {
|
||
ret[i] = list[i + start];
|
||
}
|
||
return ret
|
||
}
|
||
|
||
/**
|
||
* Mix properties into target object.
|
||
*/
|
||
function extend (to, _from) {
|
||
for (var key in _from) {
|
||
to[key] = _from[key];
|
||
}
|
||
return to
|
||
}
|
||
|
||
/**
|
||
* Merge an Array of Objects into a single Object.
|
||
*/
|
||
function toObject (arr) {
|
||
var res = {};
|
||
for (var i = 0; i < arr.length; i++) {
|
||
if (arr[i]) {
|
||
extend(res, arr[i]);
|
||
}
|
||
}
|
||
return res
|
||
}
|
||
|
||
/**
|
||
* Perform no operation.
|
||
* Stubbing args to make Flow happy without leaving useless transpiled code
|
||
* with ...rest (https://flow.org/blog/2017/05/07/Strict-Function-Call-Arity/)
|
||
*/
|
||
function noop (a, b, c) {}
|
||
|
||
/**
|
||
* Always return false.
|
||
*/
|
||
var no = function (a, b, c) { return false; };
|
||
|
||
/**
|
||
* Return same value
|
||
*/
|
||
var identity = function (_) { return _; };
|
||
|
||
/**
|
||
* Generate a static keys string from compiler modules.
|
||
*/
|
||
function genStaticKeys (modules) {
|
||
return modules.reduce(function (keys, m) {
|
||
return keys.concat(m.staticKeys || [])
|
||
}, []).join(',')
|
||
}
|
||
|
||
/**
|
||
* Check if two values are loosely equal - that is,
|
||
* if they are plain objects, do they have the same shape?
|
||
*/
|
||
function looseEqual (a, b) {
|
||
if (a === b) { return true }
|
||
var isObjectA = isObject(a);
|
||
var isObjectB = isObject(b);
|
||
if (isObjectA && isObjectB) {
|
||
try {
|
||
var isArrayA = Array.isArray(a);
|
||
var isArrayB = Array.isArray(b);
|
||
if (isArrayA && isArrayB) {
|
||
return a.length === b.length && a.every(function (e, i) {
|
||
return looseEqual(e, b[i])
|
||
})
|
||
} else if (!isArrayA && !isArrayB) {
|
||
var keysA = Object.keys(a);
|
||
var keysB = Object.keys(b);
|
||
return keysA.length === keysB.length && keysA.every(function (key) {
|
||
return looseEqual(a[key], b[key])
|
||
})
|
||
} else {
|
||
/* istanbul ignore next */
|
||
return false
|
||
}
|
||
} catch (e) {
|
||
/* istanbul ignore next */
|
||
return false
|
||
}
|
||
} else if (!isObjectA && !isObjectB) {
|
||
return String(a) === String(b)
|
||
} else {
|
||
return false
|
||
}
|
||
}
|
||
|
||
function looseIndexOf (arr, val) {
|
||
for (var i = 0; i < arr.length; i++) {
|
||
if (looseEqual(arr[i], val)) { return i }
|
||
}
|
||
return -1
|
||
}
|
||
|
||
/**
|
||
* Ensure a function is called only once.
|
||
*/
|
||
function once (fn) {
|
||
var called = false;
|
||
return function () {
|
||
if (!called) {
|
||
called = true;
|
||
fn.apply(this, arguments);
|
||
}
|
||
}
|
||
}
|
||
|
||
var SSR_ATTR = 'data-server-rendered';
|
||
|
||
var ASSET_TYPES = [
|
||
'component',
|
||
'directive',
|
||
'filter'
|
||
];
|
||
|
||
var LIFECYCLE_HOOKS = [
|
||
'beforeCreate',
|
||
'created',
|
||
'beforeMount',
|
||
'mounted',
|
||
'beforeUpdate',
|
||
'updated',
|
||
'beforeDestroy',
|
||
'destroyed',
|
||
'activated',
|
||
'deactivated'
|
||
];
|
||
|
||
/* */
|
||
|
||
var config = ({
|
||
/**
|
||
* Option merge strategies (used in core/util/options)
|
||
*/
|
||
optionMergeStrategies: Object.create(null),
|
||
|
||
/**
|
||
* Whether to suppress warnings.
|
||
*/
|
||
silent: false,
|
||
|
||
/**
|
||
* Show production mode tip message on boot?
|
||
*/
|
||
productionTip: "development" !== 'production',
|
||
|
||
/**
|
||
* Whether to enable devtools
|
||
*/
|
||
devtools: "development" !== 'production',
|
||
|
||
/**
|
||
* Whether to record perf
|
||
*/
|
||
performance: false,
|
||
|
||
/**
|
||
* Error handler for watcher errors
|
||
*/
|
||
errorHandler: null,
|
||
|
||
/**
|
||
* Warn handler for watcher warns
|
||
*/
|
||
warnHandler: null,
|
||
|
||
/**
|
||
* Ignore certain custom elements
|
||
*/
|
||
ignoredElements: [],
|
||
|
||
/**
|
||
* Custom user key aliases for v-on
|
||
*/
|
||
keyCodes: Object.create(null),
|
||
|
||
/**
|
||
* Check if a tag is reserved so that it cannot be registered as a
|
||
* component. This is platform-dependent and may be overwritten.
|
||
*/
|
||
isReservedTag: no,
|
||
|
||
/**
|
||
* Check if an attribute is reserved so that it cannot be used as a component
|
||
* prop. This is platform-dependent and may be overwritten.
|
||
*/
|
||
isReservedAttr: no,
|
||
|
||
/**
|
||
* Check if a tag is an unknown element.
|
||
* Platform-dependent.
|
||
*/
|
||
isUnknownElement: no,
|
||
|
||
/**
|
||
* Get the namespace of an element
|
||
*/
|
||
getTagNamespace: noop,
|
||
|
||
/**
|
||
* Parse the real tag name for the specific platform.
|
||
*/
|
||
parsePlatformTagName: identity,
|
||
|
||
/**
|
||
* Check if an attribute must be bound using property, e.g. value
|
||
* Platform-dependent.
|
||
*/
|
||
mustUseProp: no,
|
||
|
||
/**
|
||
* Exposed for legacy reasons
|
||
*/
|
||
_lifecycleHooks: LIFECYCLE_HOOKS
|
||
});
|
||
|
||
/* */
|
||
|
||
var emptyObject = Object.freeze({});
|
||
|
||
/**
|
||
* Check if a string starts with $ or _
|
||
*/
|
||
function isReserved (str) {
|
||
var c = (str + '').charCodeAt(0);
|
||
return c === 0x24 || c === 0x5F
|
||
}
|
||
|
||
/**
|
||
* Define a property.
|
||
*/
|
||
function def (obj, key, val, enumerable) {
|
||
Object.defineProperty(obj, key, {
|
||
value: val,
|
||
enumerable: !!enumerable,
|
||
writable: true,
|
||
configurable: true
|
||
});
|
||
}
|
||
|
||
/**
|
||
* Parse simple path.
|
||
*/
|
||
var bailRE = /[^\w.$]/;
|
||
function parsePath (path) {
|
||
if (bailRE.test(path)) {
|
||
return
|
||
}
|
||
var segments = path.split('.');
|
||
return function (obj) {
|
||
for (var i = 0; i < segments.length; i++) {
|
||
if (!obj) { return }
|
||
obj = obj[segments[i]];
|
||
}
|
||
return obj
|
||
}
|
||
}
|
||
|
||
/* */
|
||
|
||
var warn = noop;
|
||
var tip = noop;
|
||
var formatComponentName = (null); // work around flow check
|
||
|
||
if (true) {
|
||
var hasConsole = typeof console !== 'undefined';
|
||
var classifyRE = /(?:^|[-_])(\w)/g;
|
||
var classify = function (str) { return str
|
||
.replace(classifyRE, function (c) { return c.toUpperCase(); })
|
||
.replace(/[-_]/g, ''); };
|
||
|
||
warn = function (msg, vm) {
|
||
var trace = vm ? generateComponentTrace(vm) : '';
|
||
|
||
if (config.warnHandler) {
|
||
config.warnHandler.call(null, msg, vm, trace);
|
||
} else if (hasConsole && (!config.silent)) {
|
||
console.error(("[Vue warn]: " + msg + trace));
|
||
}
|
||
};
|
||
|
||
tip = function (msg, vm) {
|
||
if (hasConsole && (!config.silent)) {
|
||
console.warn("[Vue tip]: " + msg + (
|
||
vm ? generateComponentTrace(vm) : ''
|
||
));
|
||
}
|
||
};
|
||
|
||
formatComponentName = function (vm, includeFile) {
|
||
if (vm.$root === vm) {
|
||
return '<Root>'
|
||
}
|
||
var name = typeof vm === 'string'
|
||
? vm
|
||
: typeof vm === 'function' && vm.options
|
||
? vm.options.name
|
||
: vm._isVue
|
||
? vm.$options.name || vm.$options._componentTag
|
||
: vm.name;
|
||
|
||
var file = vm._isVue && vm.$options.__file;
|
||
if (!name && file) {
|
||
var match = file.match(/([^/\\]+)\.vue$/);
|
||
name = match && match[1];
|
||
}
|
||
|
||
return (
|
||
(name ? ("<" + (classify(name)) + ">") : "<Anonymous>") +
|
||
(file && includeFile !== false ? (" at " + file) : '')
|
||
)
|
||
};
|
||
|
||
var repeat = function (str, n) {
|
||
var res = '';
|
||
while (n) {
|
||
if (n % 2 === 1) { res += str; }
|
||
if (n > 1) { str += str; }
|
||
n >>= 1;
|
||
}
|
||
return res
|
||
};
|
||
|
||
var generateComponentTrace = function (vm) {
|
||
if (vm._isVue && vm.$parent) {
|
||
var tree = [];
|
||
var currentRecursiveSequence = 0;
|
||
while (vm) {
|
||
if (tree.length > 0) {
|
||
var last = tree[tree.length - 1];
|
||
if (last.constructor === vm.constructor) {
|
||
currentRecursiveSequence++;
|
||
vm = vm.$parent;
|
||
continue
|
||
} else if (currentRecursiveSequence > 0) {
|
||
tree[tree.length - 1] = [last, currentRecursiveSequence];
|
||
currentRecursiveSequence = 0;
|
||
}
|
||
}
|
||
tree.push(vm);
|
||
vm = vm.$parent;
|
||
}
|
||
return '\n\nfound in\n\n' + tree
|
||
.map(function (vm, i) { return ("" + (i === 0 ? '---> ' : repeat(' ', 5 + i * 2)) + (Array.isArray(vm)
|
||
? ((formatComponentName(vm[0])) + "... (" + (vm[1]) + " recursive calls)")
|
||
: formatComponentName(vm))); })
|
||
.join('\n')
|
||
} else {
|
||
return ("\n\n(found in " + (formatComponentName(vm)) + ")")
|
||
}
|
||
};
|
||
}
|
||
|
||
/* */
|
||
|
||
function handleError (err, vm, info) {
|
||
if (config.errorHandler) {
|
||
config.errorHandler.call(null, err, vm, info);
|
||
} else {
|
||
if (true) {
|
||
warn(("Error in " + info + ": \"" + (err.toString()) + "\""), vm);
|
||
}
|
||
/* istanbul ignore else */
|
||
if (inBrowser && typeof console !== 'undefined') {
|
||
console.error(err);
|
||
} else {
|
||
throw err
|
||
}
|
||
}
|
||
}
|
||
|
||
/* */
|
||
/* globals MutationObserver */
|
||
|
||
// can we use __proto__?
|
||
var hasProto = '__proto__' in {};
|
||
|
||
// Browser environment sniffing
|
||
var inBrowser = typeof window !== 'undefined';
|
||
var UA = inBrowser && window.navigator.userAgent.toLowerCase();
|
||
var isIE = UA && /msie|trident/.test(UA);
|
||
var isIE9 = UA && UA.indexOf('msie 9.0') > 0;
|
||
var isEdge = UA && UA.indexOf('edge/') > 0;
|
||
var isAndroid = UA && UA.indexOf('android') > 0;
|
||
var isIOS = UA && /iphone|ipad|ipod|ios/.test(UA);
|
||
var isChrome = UA && /chrome\/\d+/.test(UA) && !isEdge;
|
||
|
||
// Firefox has a "watch" function on Object.prototype...
|
||
var nativeWatch = ({}).watch;
|
||
|
||
var supportsPassive = false;
|
||
if (inBrowser) {
|
||
try {
|
||
var opts = {};
|
||
Object.defineProperty(opts, 'passive', ({
|
||
get: function get () {
|
||
/* istanbul ignore next */
|
||
supportsPassive = true;
|
||
}
|
||
})); // https://github.com/facebook/flow/issues/285
|
||
window.addEventListener('test-passive', null, opts);
|
||
} catch (e) {}
|
||
}
|
||
|
||
// this needs to be lazy-evaled because vue may be required before
|
||
// vue-server-renderer can set VUE_ENV
|
||
var _isServer;
|
||
var isServerRendering = function () {
|
||
if (_isServer === undefined) {
|
||
/* istanbul ignore if */
|
||
if (!inBrowser && typeof global !== 'undefined') {
|
||
// detect presence of vue-server-renderer and avoid
|
||
// Webpack shimming the process
|
||
_isServer = global['process'].env.VUE_ENV === 'server';
|
||
} else {
|
||
_isServer = false;
|
||
}
|
||
}
|
||
return _isServer
|
||
};
|
||
|
||
// detect devtools
|
||
var devtools = inBrowser && window.__VUE_DEVTOOLS_GLOBAL_HOOK__;
|
||
|
||
/* istanbul ignore next */
|
||
function isNative (Ctor) {
|
||
return typeof Ctor === 'function' && /native code/.test(Ctor.toString())
|
||
}
|
||
|
||
var hasSymbol =
|
||
typeof Symbol !== 'undefined' && isNative(Symbol) &&
|
||
typeof Reflect !== 'undefined' && isNative(Reflect.ownKeys);
|
||
|
||
/**
|
||
* Defer a task to execute it asynchronously.
|
||
*/
|
||
var nextTick = (function () {
|
||
var callbacks = [];
|
||
var pending = false;
|
||
var timerFunc;
|
||
|
||
function nextTickHandler () {
|
||
pending = false;
|
||
var copies = callbacks.slice(0);
|
||
callbacks.length = 0;
|
||
for (var i = 0; i < copies.length; i++) {
|
||
copies[i]();
|
||
}
|
||
}
|
||
|
||
// the nextTick behavior leverages the microtask queue, which can be accessed
|
||
// via either native Promise.then or MutationObserver.
|
||
// MutationObserver has wider support, however it is seriously bugged in
|
||
// UIWebView in iOS >= 9.3.3 when triggered in touch event handlers. It
|
||
// completely stops working after triggering a few times... so, if native
|
||
// Promise is available, we will use it:
|
||
/* istanbul ignore if */
|
||
if (typeof Promise !== 'undefined' && isNative(Promise)) {
|
||
var p = Promise.resolve();
|
||
var logError = function (err) { console.error(err); };
|
||
timerFunc = function () {
|
||
p.then(nextTickHandler).catch(logError);
|
||
// in problematic UIWebViews, Promise.then doesn't completely break, but
|
||
// it can get stuck in a weird state where callbacks are pushed into the
|
||
// microtask queue but the queue isn't being flushed, until the browser
|
||
// needs to do some other work, e.g. handle a timer. Therefore we can
|
||
// "force" the microtask queue to be flushed by adding an empty timer.
|
||
if (isIOS) { setTimeout(noop); }
|
||
};
|
||
} else if (!isIE && typeof MutationObserver !== 'undefined' && (
|
||
isNative(MutationObserver) ||
|
||
// PhantomJS and iOS 7.x
|
||
MutationObserver.toString() === '[object MutationObserverConstructor]'
|
||
)) {
|
||
// use MutationObserver where native Promise is not available,
|
||
// e.g. PhantomJS, iOS7, Android 4.4
|
||
var counter = 1;
|
||
var observer = new MutationObserver(nextTickHandler);
|
||
var textNode = document.createTextNode(String(counter));
|
||
observer.observe(textNode, {
|
||
characterData: true
|
||
});
|
||
timerFunc = function () {
|
||
counter = (counter + 1) % 2;
|
||
textNode.data = String(counter);
|
||
};
|
||
} else {
|
||
// fallback to setTimeout
|
||
/* istanbul ignore next */
|
||
timerFunc = function () {
|
||
setTimeout(nextTickHandler, 0);
|
||
};
|
||
}
|
||
|
||
return function queueNextTick (cb, ctx) {
|
||
var _resolve;
|
||
callbacks.push(function () {
|
||
if (cb) {
|
||
try {
|
||
cb.call(ctx);
|
||
} catch (e) {
|
||
handleError(e, ctx, 'nextTick');
|
||
}
|
||
} else if (_resolve) {
|
||
_resolve(ctx);
|
||
}
|
||
});
|
||
if (!pending) {
|
||
pending = true;
|
||
timerFunc();
|
||
}
|
||
if (!cb && typeof Promise !== 'undefined') {
|
||
return new Promise(function (resolve, reject) {
|
||
_resolve = resolve;
|
||
})
|
||
}
|
||
}
|
||
})();
|
||
|
||
var _Set;
|
||
/* istanbul ignore if */
|
||
if (typeof Set !== 'undefined' && isNative(Set)) {
|
||
// use native Set when available.
|
||
_Set = Set;
|
||
} else {
|
||
// a non-standard Set polyfill that only works with primitive keys.
|
||
_Set = (function () {
|
||
function Set () {
|
||
this.set = Object.create(null);
|
||
}
|
||
Set.prototype.has = function has (key) {
|
||
return this.set[key] === true
|
||
};
|
||
Set.prototype.add = function add (key) {
|
||
this.set[key] = true;
|
||
};
|
||
Set.prototype.clear = function clear () {
|
||
this.set = Object.create(null);
|
||
};
|
||
|
||
return Set;
|
||
}());
|
||
}
|
||
|
||
/* */
|
||
|
||
|
||
var uid = 0;
|
||
|
||
/**
|
||
* A dep is an observable that can have multiple
|
||
* directives subscribing to it.
|
||
*/
|
||
var Dep = function Dep () {
|
||
this.id = uid++;
|
||
this.subs = [];
|
||
};
|
||
|
||
Dep.prototype.addSub = function addSub (sub) {
|
||
this.subs.push(sub);
|
||
};
|
||
|
||
Dep.prototype.removeSub = function removeSub (sub) {
|
||
remove(this.subs, sub);
|
||
};
|
||
|
||
Dep.prototype.depend = function depend () {
|
||
if (Dep.target) {
|
||
Dep.target.addDep(this);
|
||
}
|
||
};
|
||
|
||
Dep.prototype.notify = function notify () {
|
||
// stabilize the subscriber list first
|
||
var subs = this.subs.slice();
|
||
for (var i = 0, l = subs.length; i < l; i++) {
|
||
subs[i].update();
|
||
}
|
||
};
|
||
|
||
// the current target watcher being evaluated.
|
||
// this is globally unique because there could be only one
|
||
// watcher being evaluated at any time.
|
||
Dep.target = null;
|
||
var targetStack = [];
|
||
|
||
function pushTarget (_target) {
|
||
if (Dep.target) { targetStack.push(Dep.target); }
|
||
Dep.target = _target;
|
||
}
|
||
|
||
function popTarget () {
|
||
Dep.target = targetStack.pop();
|
||
}
|
||
|
||
/*
|
||
* not type checking this file because flow doesn't play well with
|
||
* dynamically accessing methods on Array prototype
|
||
*/
|
||
|
||
var arrayProto = Array.prototype;
|
||
var arrayMethods = Object.create(arrayProto);[
|
||
'push',
|
||
'pop',
|
||
'shift',
|
||
'unshift',
|
||
'splice',
|
||
'sort',
|
||
'reverse'
|
||
]
|
||
.forEach(function (method) {
|
||
// cache original method
|
||
var original = arrayProto[method];
|
||
def(arrayMethods, method, function mutator () {
|
||
var args = [], len = arguments.length;
|
||
while ( len-- ) args[ len ] = arguments[ len ];
|
||
|
||
var result = original.apply(this, args);
|
||
var ob = this.__ob__;
|
||
var inserted;
|
||
switch (method) {
|
||
case 'push':
|
||
case 'unshift':
|
||
inserted = args;
|
||
break
|
||
case 'splice':
|
||
inserted = args.slice(2);
|
||
break
|
||
}
|
||
if (inserted) { ob.observeArray(inserted); }
|
||
// notify change
|
||
ob.dep.notify();
|
||
return result
|
||
});
|
||
});
|
||
|
||
/* */
|
||
|
||
var arrayKeys = Object.getOwnPropertyNames(arrayMethods);
|
||
|
||
/**
|
||
* By default, when a reactive property is set, the new value is
|
||
* also converted to become reactive. However when passing down props,
|
||
* we don't want to force conversion because the value may be a nested value
|
||
* under a frozen data structure. Converting it would defeat the optimization.
|
||
*/
|
||
var observerState = {
|
||
shouldConvert: true
|
||
};
|
||
|
||
/**
|
||
* Observer class that are attached to each observed
|
||
* object. Once attached, the observer converts target
|
||
* object's property keys into getter/setters that
|
||
* collect dependencies and dispatches updates.
|
||
*/
|
||
var Observer = function Observer (value) {
|
||
this.value = value;
|
||
this.dep = new Dep();
|
||
this.vmCount = 0;
|
||
def(value, '__ob__', this);
|
||
if (Array.isArray(value)) {
|
||
var augment = hasProto
|
||
? protoAugment
|
||
: copyAugment;
|
||
augment(value, arrayMethods, arrayKeys);
|
||
this.observeArray(value);
|
||
} else {
|
||
this.walk(value);
|
||
}
|
||
};
|
||
|
||
/**
|
||
* Walk through each property and convert them into
|
||
* getter/setters. This method should only be called when
|
||
* value type is Object.
|
||
*/
|
||
Observer.prototype.walk = function walk (obj) {
|
||
var keys = Object.keys(obj);
|
||
for (var i = 0; i < keys.length; i++) {
|
||
defineReactive$$1(obj, keys[i], obj[keys[i]]);
|
||
}
|
||
};
|
||
|
||
/**
|
||
* Observe a list of Array items.
|
||
*/
|
||
Observer.prototype.observeArray = function observeArray (items) {
|
||
for (var i = 0, l = items.length; i < l; i++) {
|
||
observe(items[i]);
|
||
}
|
||
};
|
||
|
||
// helpers
|
||
|
||
/**
|
||
* Augment an target Object or Array by intercepting
|
||
* the prototype chain using __proto__
|
||
*/
|
||
function protoAugment (target, src, keys) {
|
||
/* eslint-disable no-proto */
|
||
target.__proto__ = src;
|
||
/* eslint-enable no-proto */
|
||
}
|
||
|
||
/**
|
||
* Augment an target Object or Array by defining
|
||
* hidden properties.
|
||
*/
|
||
/* istanbul ignore next */
|
||
function copyAugment (target, src, keys) {
|
||
for (var i = 0, l = keys.length; i < l; i++) {
|
||
var key = keys[i];
|
||
def(target, key, src[key]);
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Attempt to create an observer instance for a value,
|
||
* returns the new observer if successfully observed,
|
||
* or the existing observer if the value already has one.
|
||
*/
|
||
function observe (value, asRootData) {
|
||
if (!isObject(value)) {
|
||
return
|
||
}
|
||
var ob;
|
||
if (hasOwn(value, '__ob__') && value.__ob__ instanceof Observer) {
|
||
ob = value.__ob__;
|
||
} else if (
|
||
observerState.shouldConvert &&
|
||
!isServerRendering() &&
|
||
(Array.isArray(value) || isPlainObject(value)) &&
|
||
Object.isExtensible(value) &&
|
||
!value._isVue
|
||
) {
|
||
ob = new Observer(value);
|
||
}
|
||
if (asRootData && ob) {
|
||
ob.vmCount++;
|
||
}
|
||
return ob
|
||
}
|
||
|
||
/**
|
||
* Define a reactive property on an Object.
|
||
*/
|
||
function defineReactive$$1 (
|
||
obj,
|
||
key,
|
||
val,
|
||
customSetter,
|
||
shallow
|
||
) {
|
||
var dep = new Dep();
|
||
|
||
var property = Object.getOwnPropertyDescriptor(obj, key);
|
||
if (property && property.configurable === false) {
|
||
return
|
||
}
|
||
|
||
// cater for pre-defined getter/setters
|
||
var getter = property && property.get;
|
||
var setter = property && property.set;
|
||
|
||
var childOb = !shallow && observe(val);
|
||
Object.defineProperty(obj, key, {
|
||
enumerable: true,
|
||
configurable: true,
|
||
get: function reactiveGetter () {
|
||
var value = getter ? getter.call(obj) : val;
|
||
if (Dep.target) {
|
||
dep.depend();
|
||
if (childOb) {
|
||
childOb.dep.depend();
|
||
if (Array.isArray(value)) {
|
||
dependArray(value);
|
||
}
|
||
}
|
||
}
|
||
return value
|
||
},
|
||
set: function reactiveSetter (newVal) {
|
||
var value = getter ? getter.call(obj) : val;
|
||
/* eslint-disable no-self-compare */
|
||
if (newVal === value || (newVal !== newVal && value !== value)) {
|
||
return
|
||
}
|
||
/* eslint-enable no-self-compare */
|
||
if ("development" !== 'production' && customSetter) {
|
||
customSetter();
|
||
}
|
||
if (setter) {
|
||
setter.call(obj, newVal);
|
||
} else {
|
||
val = newVal;
|
||
}
|
||
childOb = !shallow && observe(newVal);
|
||
dep.notify();
|
||
}
|
||
});
|
||
}
|
||
|
||
/**
|
||
* Set a property on an object. Adds the new property and
|
||
* triggers change notification if the property doesn't
|
||
* already exist.
|
||
*/
|
||
function set (target, key, val) {
|
||
if (Array.isArray(target) && isValidArrayIndex(key)) {
|
||
target.length = Math.max(target.length, key);
|
||
target.splice(key, 1, val);
|
||
return val
|
||
}
|
||
if (hasOwn(target, key)) {
|
||
target[key] = val;
|
||
return val
|
||
}
|
||
var ob = (target).__ob__;
|
||
if (target._isVue || (ob && ob.vmCount)) {
|
||
"development" !== 'production' && warn(
|
||
'Avoid adding reactive properties to a Vue instance or its root $data ' +
|
||
'at runtime - declare it upfront in the data option.'
|
||
);
|
||
return val
|
||
}
|
||
if (!ob) {
|
||
target[key] = val;
|
||
return val
|
||
}
|
||
defineReactive$$1(ob.value, key, val);
|
||
ob.dep.notify();
|
||
return val
|
||
}
|
||
|
||
/**
|
||
* Delete a property and trigger change if necessary.
|
||
*/
|
||
function del (target, key) {
|
||
if (Array.isArray(target) && isValidArrayIndex(key)) {
|
||
target.splice(key, 1);
|
||
return
|
||
}
|
||
var ob = (target).__ob__;
|
||
if (target._isVue || (ob && ob.vmCount)) {
|
||
"development" !== 'production' && warn(
|
||
'Avoid deleting properties on a Vue instance or its root $data ' +
|
||
'- just set it to null.'
|
||
);
|
||
return
|
||
}
|
||
if (!hasOwn(target, key)) {
|
||
return
|
||
}
|
||
delete target[key];
|
||
if (!ob) {
|
||
return
|
||
}
|
||
ob.dep.notify();
|
||
}
|
||
|
||
/**
|
||
* Collect dependencies on array elements when the array is touched, since
|
||
* we cannot intercept array element access like property getters.
|
||
*/
|
||
function dependArray (value) {
|
||
for (var e = (void 0), i = 0, l = value.length; i < l; i++) {
|
||
e = value[i];
|
||
e && e.__ob__ && e.__ob__.dep.depend();
|
||
if (Array.isArray(e)) {
|
||
dependArray(e);
|
||
}
|
||
}
|
||
}
|
||
|
||
/* */
|
||
|
||
/**
|
||
* Option overwriting strategies are functions that handle
|
||
* how to merge a parent option value and a child option
|
||
* value into the final value.
|
||
*/
|
||
var strats = config.optionMergeStrategies;
|
||
|
||
/**
|
||
* Options with restrictions
|
||
*/
|
||
if (true) {
|
||
strats.el = strats.propsData = function (parent, child, vm, key) {
|
||
if (!vm) {
|
||
warn(
|
||
"option \"" + key + "\" can only be used during instance " +
|
||
'creation with the `new` keyword.'
|
||
);
|
||
}
|
||
return defaultStrat(parent, child)
|
||
};
|
||
}
|
||
|
||
/**
|
||
* Helper that recursively merges two data objects together.
|
||
*/
|
||
function mergeData (to, from) {
|
||
if (!from) { return to }
|
||
var key, toVal, fromVal;
|
||
var keys = Object.keys(from);
|
||
for (var i = 0; i < keys.length; i++) {
|
||
key = keys[i];
|
||
toVal = to[key];
|
||
fromVal = from[key];
|
||
if (!hasOwn(to, key)) {
|
||
set(to, key, fromVal);
|
||
} else if (isPlainObject(toVal) && isPlainObject(fromVal)) {
|
||
mergeData(toVal, fromVal);
|
||
}
|
||
}
|
||
return to
|
||
}
|
||
|
||
/**
|
||
* Data
|
||
*/
|
||
function mergeDataOrFn (
|
||
parentVal,
|
||
childVal,
|
||
vm
|
||
) {
|
||
if (!vm) {
|
||
// in a Vue.extend merge, both should be functions
|
||
if (!childVal) {
|
||
return parentVal
|
||
}
|
||
if (!parentVal) {
|
||
return childVal
|
||
}
|
||
// when parentVal & childVal are both present,
|
||
// we need to return a function that returns the
|
||
// merged result of both functions... no need to
|
||
// check if parentVal is a function here because
|
||
// it has to be a function to pass previous merges.
|
||
return function mergedDataFn () {
|
||
return mergeData(
|
||
typeof childVal === 'function' ? childVal.call(this) : childVal,
|
||
typeof parentVal === 'function' ? parentVal.call(this) : parentVal
|
||
)
|
||
}
|
||
} else if (parentVal || childVal) {
|
||
return function mergedInstanceDataFn () {
|
||
// instance merge
|
||
var instanceData = typeof childVal === 'function'
|
||
? childVal.call(vm)
|
||
: childVal;
|
||
var defaultData = typeof parentVal === 'function'
|
||
? parentVal.call(vm)
|
||
: parentVal;
|
||
if (instanceData) {
|
||
return mergeData(instanceData, defaultData)
|
||
} else {
|
||
return defaultData
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
strats.data = function (
|
||
parentVal,
|
||
childVal,
|
||
vm
|
||
) {
|
||
if (!vm) {
|
||
if (childVal && typeof childVal !== 'function') {
|
||
"development" !== 'production' && warn(
|
||
'The "data" option should be a function ' +
|
||
'that returns a per-instance value in component ' +
|
||
'definitions.',
|
||
vm
|
||
);
|
||
|
||
return parentVal
|
||
}
|
||
return mergeDataOrFn.call(this, parentVal, childVal)
|
||
}
|
||
|
||
return mergeDataOrFn(parentVal, childVal, vm)
|
||
};
|
||
|
||
/**
|
||
* Hooks and props are merged as arrays.
|
||
*/
|
||
function mergeHook (
|
||
parentVal,
|
||
childVal
|
||
) {
|
||
return childVal
|
||
? parentVal
|
||
? parentVal.concat(childVal)
|
||
: Array.isArray(childVal)
|
||
? childVal
|
||
: [childVal]
|
||
: parentVal
|
||
}
|
||
|
||
LIFECYCLE_HOOKS.forEach(function (hook) {
|
||
strats[hook] = mergeHook;
|
||
});
|
||
|
||
/**
|
||
* Assets
|
||
*
|
||
* When a vm is present (instance creation), we need to do
|
||
* a three-way merge between constructor options, instance
|
||
* options and parent options.
|
||
*/
|
||
function mergeAssets (parentVal, childVal) {
|
||
var res = Object.create(parentVal || null);
|
||
return childVal
|
||
? extend(res, childVal)
|
||
: res
|
||
}
|
||
|
||
ASSET_TYPES.forEach(function (type) {
|
||
strats[type + 's'] = mergeAssets;
|
||
});
|
||
|
||
/**
|
||
* Watchers.
|
||
*
|
||
* Watchers hashes should not overwrite one
|
||
* another, so we merge them as arrays.
|
||
*/
|
||
strats.watch = function (parentVal, childVal) {
|
||
// work around Firefox's Object.prototype.watch...
|
||
if (parentVal === nativeWatch) { parentVal = undefined; }
|
||
if (childVal === nativeWatch) { childVal = undefined; }
|
||
/* istanbul ignore if */
|
||
if (!childVal) { return Object.create(parentVal || null) }
|
||
if (!parentVal) { return childVal }
|
||
var ret = {};
|
||
extend(ret, parentVal);
|
||
for (var key in childVal) {
|
||
var parent = ret[key];
|
||
var child = childVal[key];
|
||
if (parent && !Array.isArray(parent)) {
|
||
parent = [parent];
|
||
}
|
||
ret[key] = parent
|
||
? parent.concat(child)
|
||
: Array.isArray(child) ? child : [child];
|
||
}
|
||
return ret
|
||
};
|
||
|
||
/**
|
||
* Other object hashes.
|
||
*/
|
||
strats.props =
|
||
strats.methods =
|
||
strats.inject =
|
||
strats.computed = function (parentVal, childVal) {
|
||
if (!parentVal) { return childVal }
|
||
var ret = Object.create(null);
|
||
extend(ret, parentVal);
|
||
if (childVal) { extend(ret, childVal); }
|
||
return ret
|
||
};
|
||
strats.provide = mergeDataOrFn;
|
||
|
||
/**
|
||
* Default strategy.
|
||
*/
|
||
var defaultStrat = function (parentVal, childVal) {
|
||
return childVal === undefined
|
||
? parentVal
|
||
: childVal
|
||
};
|
||
|
||
/**
|
||
* Validate component names
|
||
*/
|
||
function checkComponents (options) {
|
||
for (var key in options.components) {
|
||
var lower = key.toLowerCase();
|
||
if (isBuiltInTag(lower) || config.isReservedTag(lower)) {
|
||
warn(
|
||
'Do not use built-in or reserved HTML elements as component ' +
|
||
'id: ' + key
|
||
);
|
||
}
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Ensure all props option syntax are normalized into the
|
||
* Object-based format.
|
||
*/
|
||
function normalizeProps (options) {
|
||
var props = options.props;
|
||
if (!props) { return }
|
||
var res = {};
|
||
var i, val, name;
|
||
if (Array.isArray(props)) {
|
||
i = props.length;
|
||
while (i--) {
|
||
val = props[i];
|
||
if (typeof val === 'string') {
|
||
name = camelize(val);
|
||
res[name] = { type: null };
|
||
} else if (true) {
|
||
warn('props must be strings when using array syntax.');
|
||
}
|
||
}
|
||
} else if (isPlainObject(props)) {
|
||
for (var key in props) {
|
||
val = props[key];
|
||
name = camelize(key);
|
||
res[name] = isPlainObject(val)
|
||
? val
|
||
: { type: val };
|
||
}
|
||
}
|
||
options.props = res;
|
||
}
|
||
|
||
/**
|
||
* Normalize all injections into Object-based format
|
||
*/
|
||
function normalizeInject (options) {
|
||
var inject = options.inject;
|
||
if (Array.isArray(inject)) {
|
||
var normalized = options.inject = {};
|
||
for (var i = 0; i < inject.length; i++) {
|
||
normalized[inject[i]] = inject[i];
|
||
}
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Normalize raw function directives into object format.
|
||
*/
|
||
function normalizeDirectives (options) {
|
||
var dirs = options.directives;
|
||
if (dirs) {
|
||
for (var key in dirs) {
|
||
var def = dirs[key];
|
||
if (typeof def === 'function') {
|
||
dirs[key] = { bind: def, update: def };
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Merge two option objects into a new one.
|
||
* Core utility used in both instantiation and inheritance.
|
||
*/
|
||
function mergeOptions (
|
||
parent,
|
||
child,
|
||
vm
|
||
) {
|
||
if (true) {
|
||
checkComponents(child);
|
||
}
|
||
|
||
if (typeof child === 'function') {
|
||
child = child.options;
|
||
}
|
||
|
||
normalizeProps(child);
|
||
normalizeInject(child);
|
||
normalizeDirectives(child);
|
||
var extendsFrom = child.extends;
|
||
if (extendsFrom) {
|
||
parent = mergeOptions(parent, extendsFrom, vm);
|
||
}
|
||
if (child.mixins) {
|
||
for (var i = 0, l = child.mixins.length; i < l; i++) {
|
||
parent = mergeOptions(parent, child.mixins[i], vm);
|
||
}
|
||
}
|
||
var options = {};
|
||
var key;
|
||
for (key in parent) {
|
||
mergeField(key);
|
||
}
|
||
for (key in child) {
|
||
if (!hasOwn(parent, key)) {
|
||
mergeField(key);
|
||
}
|
||
}
|
||
function mergeField (key) {
|
||
var strat = strats[key] || defaultStrat;
|
||
options[key] = strat(parent[key], child[key], vm, key);
|
||
}
|
||
return options
|
||
}
|
||
|
||
/**
|
||
* Resolve an asset.
|
||
* This function is used because child instances need access
|
||
* to assets defined in its ancestor chain.
|
||
*/
|
||
function resolveAsset (
|
||
options,
|
||
type,
|
||
id,
|
||
warnMissing
|
||
) {
|
||
/* istanbul ignore if */
|
||
if (typeof id !== 'string') {
|
||
return
|
||
}
|
||
var assets = options[type];
|
||
// check local registration variations first
|
||
if (hasOwn(assets, id)) { return assets[id] }
|
||
var camelizedId = camelize(id);
|
||
if (hasOwn(assets, camelizedId)) { return assets[camelizedId] }
|
||
var PascalCaseId = capitalize(camelizedId);
|
||
if (hasOwn(assets, PascalCaseId)) { return assets[PascalCaseId] }
|
||
// fallback to prototype chain
|
||
var res = assets[id] || assets[camelizedId] || assets[PascalCaseId];
|
||
if ("development" !== 'production' && warnMissing && !res) {
|
||
warn(
|
||
'Failed to resolve ' + type.slice(0, -1) + ': ' + id,
|
||
options
|
||
);
|
||
}
|
||
return res
|
||
}
|
||
|
||
/* */
|
||
|
||
function validateProp (
|
||
key,
|
||
propOptions,
|
||
propsData,
|
||
vm
|
||
) {
|
||
var prop = propOptions[key];
|
||
var absent = !hasOwn(propsData, key);
|
||
var value = propsData[key];
|
||
// handle boolean props
|
||
if (isType(Boolean, prop.type)) {
|
||
if (absent && !hasOwn(prop, 'default')) {
|
||
value = false;
|
||
} else if (!isType(String, prop.type) && (value === '' || value === hyphenate(key))) {
|
||
value = true;
|
||
}
|
||
}
|
||
// check default value
|
||
if (value === undefined) {
|
||
value = getPropDefaultValue(vm, prop, key);
|
||
// since the default value is a fresh copy,
|
||
// make sure to observe it.
|
||
var prevShouldConvert = observerState.shouldConvert;
|
||
observerState.shouldConvert = true;
|
||
observe(value);
|
||
observerState.shouldConvert = prevShouldConvert;
|
||
}
|
||
if (true) {
|
||
assertProp(prop, key, value, vm, absent);
|
||
}
|
||
return value
|
||
}
|
||
|
||
/**
|
||
* Get the default value of a prop.
|
||
*/
|
||
function getPropDefaultValue (vm, prop, key) {
|
||
// no default, return undefined
|
||
if (!hasOwn(prop, 'default')) {
|
||
return undefined
|
||
}
|
||
var def = prop.default;
|
||
// warn against non-factory defaults for Object & Array
|
||
if ("development" !== 'production' && isObject(def)) {
|
||
warn(
|
||
'Invalid default value for prop "' + key + '": ' +
|
||
'Props with type Object/Array must use a factory function ' +
|
||
'to return the default value.',
|
||
vm
|
||
);
|
||
}
|
||
// the raw prop value was also undefined from previous render,
|
||
// return previous default value to avoid unnecessary watcher trigger
|
||
if (vm && vm.$options.propsData &&
|
||
vm.$options.propsData[key] === undefined &&
|
||
vm._props[key] !== undefined
|
||
) {
|
||
return vm._props[key]
|
||
}
|
||
// call factory function for non-Function types
|
||
// a value is Function if its prototype is function even across different execution context
|
||
return typeof def === 'function' && getType(prop.type) !== 'Function'
|
||
? def.call(vm)
|
||
: def
|
||
}
|
||
|
||
/**
|
||
* Assert whether a prop is valid.
|
||
*/
|
||
function assertProp (
|
||
prop,
|
||
name,
|
||
value,
|
||
vm,
|
||
absent
|
||
) {
|
||
if (prop.required && absent) {
|
||
warn(
|
||
'Missing required prop: "' + name + '"',
|
||
vm
|
||
);
|
||
return
|
||
}
|
||
if (value == null && !prop.required) {
|
||
return
|
||
}
|
||
var type = prop.type;
|
||
var valid = !type || type === true;
|
||
var expectedTypes = [];
|
||
if (type) {
|
||
if (!Array.isArray(type)) {
|
||
type = [type];
|
||
}
|
||
for (var i = 0; i < type.length && !valid; i++) {
|
||
var assertedType = assertType(value, type[i]);
|
||
expectedTypes.push(assertedType.expectedType || '');
|
||
valid = assertedType.valid;
|
||
}
|
||
}
|
||
if (!valid) {
|
||
warn(
|
||
'Invalid prop: type check failed for prop "' + name + '".' +
|
||
' Expected ' + expectedTypes.map(capitalize).join(', ') +
|
||
', got ' + Object.prototype.toString.call(value).slice(8, -1) + '.',
|
||
vm
|
||
);
|
||
return
|
||
}
|
||
var validator = prop.validator;
|
||
if (validator) {
|
||
if (!validator(value)) {
|
||
warn(
|
||
'Invalid prop: custom validator check failed for prop "' + name + '".',
|
||
vm
|
||
);
|
||
}
|
||
}
|
||
}
|
||
|
||
var simpleCheckRE = /^(String|Number|Boolean|Function|Symbol)$/;
|
||
|
||
function assertType (value, type) {
|
||
var valid;
|
||
var expectedType = getType(type);
|
||
if (simpleCheckRE.test(expectedType)) {
|
||
var t = typeof value;
|
||
valid = t === expectedType.toLowerCase();
|
||
// for primitive wrapper objects
|
||
if (!valid && t === 'object') {
|
||
valid = value instanceof type;
|
||
}
|
||
} else if (expectedType === 'Object') {
|
||
valid = isPlainObject(value);
|
||
} else if (expectedType === 'Array') {
|
||
valid = Array.isArray(value);
|
||
} else {
|
||
valid = value instanceof type;
|
||
}
|
||
return {
|
||
valid: valid,
|
||
expectedType: expectedType
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Use function string name to check built-in types,
|
||
* because a simple equality check will fail when running
|
||
* across different vms / iframes.
|
||
*/
|
||
function getType (fn) {
|
||
var match = fn && fn.toString().match(/^\s*function (\w+)/);
|
||
return match ? match[1] : ''
|
||
}
|
||
|
||
function isType (type, fn) {
|
||
if (!Array.isArray(fn)) {
|
||
return getType(fn) === getType(type)
|
||
}
|
||
for (var i = 0, len = fn.length; i < len; i++) {
|
||
if (getType(fn[i]) === getType(type)) {
|
||
return true
|
||
}
|
||
}
|
||
/* istanbul ignore next */
|
||
return false
|
||
}
|
||
|
||
/* */
|
||
|
||
var mark;
|
||
var measure;
|
||
|
||
if (true) {
|
||
var perf = inBrowser && window.performance;
|
||
/* istanbul ignore if */
|
||
if (
|
||
perf &&
|
||
perf.mark &&
|
||
perf.measure &&
|
||
perf.clearMarks &&
|
||
perf.clearMeasures
|
||
) {
|
||
mark = function (tag) { return perf.mark(tag); };
|
||
measure = function (name, startTag, endTag) {
|
||
perf.measure(name, startTag, endTag);
|
||
perf.clearMarks(startTag);
|
||
perf.clearMarks(endTag);
|
||
perf.clearMeasures(name);
|
||
};
|
||
}
|
||
}
|
||
|
||
/* not type checking this file because flow doesn't play well with Proxy */
|
||
|
||
var initProxy;
|
||
|
||
if (true) {
|
||
var allowedGlobals = makeMap(
|
||
'Infinity,undefined,NaN,isFinite,isNaN,' +
|
||
'parseFloat,parseInt,decodeURI,decodeURIComponent,encodeURI,encodeURIComponent,' +
|
||
'Math,Number,Date,Array,Object,Boolean,String,RegExp,Map,Set,JSON,Intl,' +
|
||
'require' // for Webpack/Browserify
|
||
);
|
||
|
||
var warnNonPresent = function (target, key) {
|
||
warn(
|
||
"Property or method \"" + key + "\" is not defined on the instance but " +
|
||
"referenced during render. Make sure to declare reactive data " +
|
||
"properties in the data option.",
|
||
target
|
||
);
|
||
};
|
||
|
||
var hasProxy =
|
||
typeof Proxy !== 'undefined' &&
|
||
Proxy.toString().match(/native code/);
|
||
|
||
if (hasProxy) {
|
||
var isBuiltInModifier = makeMap('stop,prevent,self,ctrl,shift,alt,meta');
|
||
config.keyCodes = new Proxy(config.keyCodes, {
|
||
set: function set (target, key, value) {
|
||
if (isBuiltInModifier(key)) {
|
||
warn(("Avoid overwriting built-in modifier in config.keyCodes: ." + key));
|
||
return false
|
||
} else {
|
||
target[key] = value;
|
||
return true
|
||
}
|
||
}
|
||
});
|
||
}
|
||
|
||
var hasHandler = {
|
||
has: function has (target, key) {
|
||
var has = key in target;
|
||
var isAllowed = allowedGlobals(key) || key.charAt(0) === '_';
|
||
if (!has && !isAllowed) {
|
||
warnNonPresent(target, key);
|
||
}
|
||
return has || !isAllowed
|
||
}
|
||
};
|
||
|
||
var getHandler = {
|
||
get: function get (target, key) {
|
||
if (typeof key === 'string' && !(key in target)) {
|
||
warnNonPresent(target, key);
|
||
}
|
||
return target[key]
|
||
}
|
||
};
|
||
|
||
initProxy = function initProxy (vm) {
|
||
if (hasProxy) {
|
||
// determine which proxy handler to use
|
||
var options = vm.$options;
|
||
var handlers = options.render && options.render._withStripped
|
||
? getHandler
|
||
: hasHandler;
|
||
vm._renderProxy = new Proxy(vm, handlers);
|
||
} else {
|
||
vm._renderProxy = vm;
|
||
}
|
||
};
|
||
}
|
||
|
||
/* */
|
||
|
||
var VNode = function VNode (
|
||
tag,
|
||
data,
|
||
children,
|
||
text,
|
||
elm,
|
||
context,
|
||
componentOptions,
|
||
asyncFactory
|
||
) {
|
||
this.tag = tag;
|
||
this.data = data;
|
||
this.children = children;
|
||
this.text = text;
|
||
this.elm = elm;
|
||
this.ns = undefined;
|
||
this.context = context;
|
||
this.functionalContext = undefined;
|
||
this.key = data && data.key;
|
||
this.componentOptions = componentOptions;
|
||
this.componentInstance = undefined;
|
||
this.parent = undefined;
|
||
this.raw = false;
|
||
this.isStatic = false;
|
||
this.isRootInsert = true;
|
||
this.isComment = false;
|
||
this.isCloned = false;
|
||
this.isOnce = false;
|
||
this.asyncFactory = asyncFactory;
|
||
this.asyncMeta = undefined;
|
||
this.isAsyncPlaceholder = false;
|
||
};
|
||
|
||
var prototypeAccessors = { child: {} };
|
||
|
||
// DEPRECATED: alias for componentInstance for backwards compat.
|
||
/* istanbul ignore next */
|
||
prototypeAccessors.child.get = function () {
|
||
return this.componentInstance
|
||
};
|
||
|
||
Object.defineProperties( VNode.prototype, prototypeAccessors );
|
||
|
||
var createEmptyVNode = function (text) {
|
||
if ( text === void 0 ) text = '';
|
||
|
||
var node = new VNode();
|
||
node.text = text;
|
||
node.isComment = true;
|
||
return node
|
||
};
|
||
|
||
function createTextVNode (val) {
|
||
return new VNode(undefined, undefined, undefined, String(val))
|
||
}
|
||
|
||
// optimized shallow clone
|
||
// used for static nodes and slot nodes because they may be reused across
|
||
// multiple renders, cloning them avoids errors when DOM manipulations rely
|
||
// on their elm reference.
|
||
function cloneVNode (vnode, deep) {
|
||
var cloned = new VNode(
|
||
vnode.tag,
|
||
vnode.data,
|
||
vnode.children,
|
||
vnode.text,
|
||
vnode.elm,
|
||
vnode.context,
|
||
vnode.componentOptions,
|
||
vnode.asyncFactory
|
||
);
|
||
cloned.ns = vnode.ns;
|
||
cloned.isStatic = vnode.isStatic;
|
||
cloned.key = vnode.key;
|
||
cloned.isComment = vnode.isComment;
|
||
cloned.isCloned = true;
|
||
if (deep && vnode.children) {
|
||
cloned.children = cloneVNodes(vnode.children);
|
||
}
|
||
return cloned
|
||
}
|
||
|
||
function cloneVNodes (vnodes, deep) {
|
||
var len = vnodes.length;
|
||
var res = new Array(len);
|
||
for (var i = 0; i < len; i++) {
|
||
res[i] = cloneVNode(vnodes[i], deep);
|
||
}
|
||
return res
|
||
}
|
||
|
||
/* */
|
||
|
||
var normalizeEvent = cached(function (name) {
|
||
var passive = name.charAt(0) === '&';
|
||
name = passive ? name.slice(1) : name;
|
||
var once$$1 = name.charAt(0) === '~'; // Prefixed last, checked first
|
||
name = once$$1 ? name.slice(1) : name;
|
||
var capture = name.charAt(0) === '!';
|
||
name = capture ? name.slice(1) : name;
|
||
var plain = !(passive || once$$1 || capture);
|
||
return {
|
||
name: name,
|
||
plain: plain,
|
||
once: once$$1,
|
||
capture: capture,
|
||
passive: passive
|
||
}
|
||
});
|
||
|
||
function createFnInvoker (fns) {
|
||
function invoker () {
|
||
var arguments$1 = arguments;
|
||
|
||
var fns = invoker.fns;
|
||
if (Array.isArray(fns)) {
|
||
var cloned = fns.slice();
|
||
for (var i = 0; i < cloned.length; i++) {
|
||
cloned[i].apply(null, arguments$1);
|
||
}
|
||
} else {
|
||
// return handler return value for single handlers
|
||
return fns.apply(null, arguments)
|
||
}
|
||
}
|
||
invoker.fns = fns;
|
||
return invoker
|
||
}
|
||
|
||
// #6552
|
||
function prioritizePlainEvents (a, b) {
|
||
return a.plain ? -1 : b.plain ? 1 : 0
|
||
}
|
||
|
||
function updateListeners (
|
||
on,
|
||
oldOn,
|
||
add,
|
||
remove$$1,
|
||
vm
|
||
) {
|
||
var name, cur, old, event;
|
||
var toAdd = [];
|
||
var hasModifier = false;
|
||
for (name in on) {
|
||
cur = on[name];
|
||
old = oldOn[name];
|
||
event = normalizeEvent(name);
|
||
if (!event.plain) { hasModifier = true; }
|
||
if (isUndef(cur)) {
|
||
"development" !== 'production' && warn(
|
||
"Invalid handler for event \"" + (event.name) + "\": got " + String(cur),
|
||
vm
|
||
);
|
||
} else if (isUndef(old)) {
|
||
if (isUndef(cur.fns)) {
|
||
cur = on[name] = createFnInvoker(cur);
|
||
}
|
||
event.handler = cur;
|
||
toAdd.push(event);
|
||
} else if (cur !== old) {
|
||
old.fns = cur;
|
||
on[name] = old;
|
||
}
|
||
}
|
||
if (toAdd.length) {
|
||
if (hasModifier) { toAdd.sort(prioritizePlainEvents); }
|
||
for (var i = 0; i < toAdd.length; i++) {
|
||
var event$1 = toAdd[i];
|
||
add(event$1.name, event$1.handler, event$1.once, event$1.capture, event$1.passive);
|
||
}
|
||
}
|
||
for (name in oldOn) {
|
||
if (isUndef(on[name])) {
|
||
event = normalizeEvent(name);
|
||
remove$$1(event.name, oldOn[name], event.capture);
|
||
}
|
||
}
|
||
}
|
||
|
||
/* */
|
||
|
||
function mergeVNodeHook (def, hookKey, hook) {
|
||
var invoker;
|
||
var oldHook = def[hookKey];
|
||
|
||
function wrappedHook () {
|
||
hook.apply(this, arguments);
|
||
// important: remove merged hook to ensure it's called only once
|
||
// and prevent memory leak
|
||
remove(invoker.fns, wrappedHook);
|
||
}
|
||
|
||
if (isUndef(oldHook)) {
|
||
// no existing hook
|
||
invoker = createFnInvoker([wrappedHook]);
|
||
} else {
|
||
/* istanbul ignore if */
|
||
if (isDef(oldHook.fns) && isTrue(oldHook.merged)) {
|
||
// already a merged invoker
|
||
invoker = oldHook;
|
||
invoker.fns.push(wrappedHook);
|
||
} else {
|
||
// existing plain hook
|
||
invoker = createFnInvoker([oldHook, wrappedHook]);
|
||
}
|
||
}
|
||
|
||
invoker.merged = true;
|
||
def[hookKey] = invoker;
|
||
}
|
||
|
||
/* */
|
||
|
||
function extractPropsFromVNodeData (
|
||
data,
|
||
Ctor,
|
||
tag
|
||
) {
|
||
// we are only extracting raw values here.
|
||
// validation and default values are handled in the child
|
||
// component itself.
|
||
var propOptions = Ctor.options.props;
|
||
if (isUndef(propOptions)) {
|
||
return
|
||
}
|
||
var res = {};
|
||
var attrs = data.attrs;
|
||
var props = data.props;
|
||
if (isDef(attrs) || isDef(props)) {
|
||
for (var key in propOptions) {
|
||
var altKey = hyphenate(key);
|
||
if (true) {
|
||
var keyInLowerCase = key.toLowerCase();
|
||
if (
|
||
key !== keyInLowerCase &&
|
||
attrs && hasOwn(attrs, keyInLowerCase)
|
||
) {
|
||
tip(
|
||
"Prop \"" + keyInLowerCase + "\" is passed to component " +
|
||
(formatComponentName(tag || Ctor)) + ", but the declared prop name is" +
|
||
" \"" + key + "\". " +
|
||
"Note that HTML attributes are case-insensitive and camelCased " +
|
||
"props need to use their kebab-case equivalents when using in-DOM " +
|
||
"templates. You should probably use \"" + altKey + "\" instead of \"" + key + "\"."
|
||
);
|
||
}
|
||
}
|
||
checkProp(res, props, key, altKey, true) ||
|
||
checkProp(res, attrs, key, altKey, false);
|
||
}
|
||
}
|
||
return res
|
||
}
|
||
|
||
function checkProp (
|
||
res,
|
||
hash,
|
||
key,
|
||
altKey,
|
||
preserve
|
||
) {
|
||
if (isDef(hash)) {
|
||
if (hasOwn(hash, key)) {
|
||
res[key] = hash[key];
|
||
if (!preserve) {
|
||
delete hash[key];
|
||
}
|
||
return true
|
||
} else if (hasOwn(hash, altKey)) {
|
||
res[key] = hash[altKey];
|
||
if (!preserve) {
|
||
delete hash[altKey];
|
||
}
|
||
return true
|
||
}
|
||
}
|
||
return false
|
||
}
|
||
|
||
/* */
|
||
|
||
// The template compiler attempts to minimize the need for normalization by
|
||
// statically analyzing the template at compile time.
|
||
//
|
||
// For plain HTML markup, normalization can be completely skipped because the
|
||
// generated render function is guaranteed to return Array<VNode>. There are
|
||
// two cases where extra normalization is needed:
|
||
|
||
// 1. When the children contains components - because a functional component
|
||
// may return an Array instead of a single root. In this case, just a simple
|
||
// normalization is needed - if any child is an Array, we flatten the whole
|
||
// thing with Array.prototype.concat. It is guaranteed to be only 1-level deep
|
||
// because functional components already normalize their own children.
|
||
function simpleNormalizeChildren (children) {
|
||
for (var i = 0; i < children.length; i++) {
|
||
if (Array.isArray(children[i])) {
|
||
return Array.prototype.concat.apply([], children)
|
||
}
|
||
}
|
||
return children
|
||
}
|
||
|
||
// 2. When the children contains constructs that always generated nested Arrays,
|
||
// e.g. <template>, <slot>, v-for, or when the children is provided by user
|
||
// with hand-written render functions / JSX. In such cases a full normalization
|
||
// is needed to cater to all possible types of children values.
|
||
function normalizeChildren (children) {
|
||
return isPrimitive(children)
|
||
? [createTextVNode(children)]
|
||
: Array.isArray(children)
|
||
? normalizeArrayChildren(children)
|
||
: undefined
|
||
}
|
||
|
||
function isTextNode (node) {
|
||
return isDef(node) && isDef(node.text) && isFalse(node.isComment)
|
||
}
|
||
|
||
function normalizeArrayChildren (children, nestedIndex) {
|
||
var res = [];
|
||
var i, c, last;
|
||
for (i = 0; i < children.length; i++) {
|
||
c = children[i];
|
||
if (isUndef(c) || typeof c === 'boolean') { continue }
|
||
last = res[res.length - 1];
|
||
// nested
|
||
if (Array.isArray(c)) {
|
||
res.push.apply(res, normalizeArrayChildren(c, ((nestedIndex || '') + "_" + i)));
|
||
} else if (isPrimitive(c)) {
|
||
if (isTextNode(last)) {
|
||
// merge adjacent text nodes
|
||
// this is necessary for SSR hydration because text nodes are
|
||
// essentially merged when rendered to HTML strings
|
||
(last).text += String(c);
|
||
} else if (c !== '') {
|
||
// convert primitive to vnode
|
||
res.push(createTextVNode(c));
|
||
}
|
||
} else {
|
||
if (isTextNode(c) && isTextNode(last)) {
|
||
// merge adjacent text nodes
|
||
res[res.length - 1] = createTextVNode(last.text + c.text);
|
||
} else {
|
||
// default key for nested array children (likely generated by v-for)
|
||
if (isTrue(children._isVList) &&
|
||
isDef(c.tag) &&
|
||
isUndef(c.key) &&
|
||
isDef(nestedIndex)) {
|
||
c.key = "__vlist" + nestedIndex + "_" + i + "__";
|
||
}
|
||
res.push(c);
|
||
}
|
||
}
|
||
}
|
||
return res
|
||
}
|
||
|
||
/* */
|
||
|
||
function ensureCtor (comp, base) {
|
||
if (comp.__esModule && comp.default) {
|
||
comp = comp.default;
|
||
}
|
||
return isObject(comp)
|
||
? base.extend(comp)
|
||
: comp
|
||
}
|
||
|
||
function createAsyncPlaceholder (
|
||
factory,
|
||
data,
|
||
context,
|
||
children,
|
||
tag
|
||
) {
|
||
var node = createEmptyVNode();
|
||
node.asyncFactory = factory;
|
||
node.asyncMeta = { data: data, context: context, children: children, tag: tag };
|
||
return node
|
||
}
|
||
|
||
function resolveAsyncComponent (
|
||
factory,
|
||
baseCtor,
|
||
context
|
||
) {
|
||
if (isTrue(factory.error) && isDef(factory.errorComp)) {
|
||
return factory.errorComp
|
||
}
|
||
|
||
if (isDef(factory.resolved)) {
|
||
return factory.resolved
|
||
}
|
||
|
||
if (isTrue(factory.loading) && isDef(factory.loadingComp)) {
|
||
return factory.loadingComp
|
||
}
|
||
|
||
if (isDef(factory.contexts)) {
|
||
// already pending
|
||
factory.contexts.push(context);
|
||
} else {
|
||
var contexts = factory.contexts = [context];
|
||
var sync = true;
|
||
|
||
var forceRender = function () {
|
||
for (var i = 0, l = contexts.length; i < l; i++) {
|
||
contexts[i].$forceUpdate();
|
||
}
|
||
};
|
||
|
||
var resolve = once(function (res) {
|
||
// cache resolved
|
||
factory.resolved = ensureCtor(res, baseCtor);
|
||
// invoke callbacks only if this is not a synchronous resolve
|
||
// (async resolves are shimmed as synchronous during SSR)
|
||
if (!sync) {
|
||
forceRender();
|
||
}
|
||
});
|
||
|
||
var reject = once(function (reason) {
|
||
"development" !== 'production' && warn(
|
||
"Failed to resolve async component: " + (String(factory)) +
|
||
(reason ? ("\nReason: " + reason) : '')
|
||
);
|
||
if (isDef(factory.errorComp)) {
|
||
factory.error = true;
|
||
forceRender();
|
||
}
|
||
});
|
||
|
||
var res = factory(resolve, reject);
|
||
|
||
if (isObject(res)) {
|
||
if (typeof res.then === 'function') {
|
||
// () => Promise
|
||
if (isUndef(factory.resolved)) {
|
||
res.then(resolve, reject);
|
||
}
|
||
} else if (isDef(res.component) && typeof res.component.then === 'function') {
|
||
res.component.then(resolve, reject);
|
||
|
||
if (isDef(res.error)) {
|
||
factory.errorComp = ensureCtor(res.error, baseCtor);
|
||
}
|
||
|
||
if (isDef(res.loading)) {
|
||
factory.loadingComp = ensureCtor(res.loading, baseCtor);
|
||
if (res.delay === 0) {
|
||
factory.loading = true;
|
||
} else {
|
||
setTimeout(function () {
|
||
if (isUndef(factory.resolved) && isUndef(factory.error)) {
|
||
factory.loading = true;
|
||
forceRender();
|
||
}
|
||
}, res.delay || 200);
|
||
}
|
||
}
|
||
|
||
if (isDef(res.timeout)) {
|
||
setTimeout(function () {
|
||
if (isUndef(factory.resolved)) {
|
||
reject(
|
||
true
|
||
? ("timeout (" + (res.timeout) + "ms)")
|
||
: null
|
||
);
|
||
}
|
||
}, res.timeout);
|
||
}
|
||
}
|
||
}
|
||
|
||
sync = false;
|
||
// return in case resolved synchronously
|
||
return factory.loading
|
||
? factory.loadingComp
|
||
: factory.resolved
|
||
}
|
||
}
|
||
|
||
/* */
|
||
|
||
function isAsyncPlaceholder (node) {
|
||
return node.isComment && node.asyncFactory
|
||
}
|
||
|
||
/* */
|
||
|
||
function getFirstComponentChild (children) {
|
||
if (Array.isArray(children)) {
|
||
for (var i = 0; i < children.length; i++) {
|
||
var c = children[i];
|
||
if (isDef(c) && (isDef(c.componentOptions) || isAsyncPlaceholder(c))) {
|
||
return c
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
/* */
|
||
|
||
/* */
|
||
|
||
function initEvents (vm) {
|
||
vm._events = Object.create(null);
|
||
vm._hasHookEvent = false;
|
||
// init parent attached events
|
||
var listeners = vm.$options._parentListeners;
|
||
if (listeners) {
|
||
updateComponentListeners(vm, listeners);
|
||
}
|
||
}
|
||
|
||
var target;
|
||
|
||
function add (event, fn, once$$1) {
|
||
if (once$$1) {
|
||
target.$once(event, fn);
|
||
} else {
|
||
target.$on(event, fn);
|
||
}
|
||
}
|
||
|
||
function remove$1 (event, fn) {
|
||
target.$off(event, fn);
|
||
}
|
||
|
||
function updateComponentListeners (
|
||
vm,
|
||
listeners,
|
||
oldListeners
|
||
) {
|
||
target = vm;
|
||
updateListeners(listeners, oldListeners || {}, add, remove$1, vm);
|
||
}
|
||
|
||
function eventsMixin (Vue) {
|
||
var hookRE = /^hook:/;
|
||
Vue.prototype.$on = function (event, fn) {
|
||
var this$1 = this;
|
||
|
||
var vm = this;
|
||
if (Array.isArray(event)) {
|
||
for (var i = 0, l = event.length; i < l; i++) {
|
||
this$1.$on(event[i], fn);
|
||
}
|
||
} else {
|
||
(vm._events[event] || (vm._events[event] = [])).push(fn);
|
||
// optimize hook:event cost by using a boolean flag marked at registration
|
||
// instead of a hash lookup
|
||
if (hookRE.test(event)) {
|
||
vm._hasHookEvent = true;
|
||
}
|
||
}
|
||
return vm
|
||
};
|
||
|
||
Vue.prototype.$once = function (event, fn) {
|
||
var vm = this;
|
||
function on () {
|
||
vm.$off(event, on);
|
||
fn.apply(vm, arguments);
|
||
}
|
||
on.fn = fn;
|
||
vm.$on(event, on);
|
||
return vm
|
||
};
|
||
|
||
Vue.prototype.$off = function (event, fn) {
|
||
var this$1 = this;
|
||
|
||
var vm = this;
|
||
// all
|
||
if (!arguments.length) {
|
||
vm._events = Object.create(null);
|
||
return vm
|
||
}
|
||
// array of events
|
||
if (Array.isArray(event)) {
|
||
for (var i = 0, l = event.length; i < l; i++) {
|
||
this$1.$off(event[i], fn);
|
||
}
|
||
return vm
|
||
}
|
||
// specific event
|
||
var cbs = vm._events[event];
|
||
if (!cbs) {
|
||
return vm
|
||
}
|
||
if (arguments.length === 1) {
|
||
vm._events[event] = null;
|
||
return vm
|
||
}
|
||
if (fn) {
|
||
// specific handler
|
||
var cb;
|
||
var i$1 = cbs.length;
|
||
while (i$1--) {
|
||
cb = cbs[i$1];
|
||
if (cb === fn || cb.fn === fn) {
|
||
cbs.splice(i$1, 1);
|
||
break
|
||
}
|
||
}
|
||
}
|
||
return vm
|
||
};
|
||
|
||
Vue.prototype.$emit = function (event) {
|
||
var vm = this;
|
||
if (true) {
|
||
var lowerCaseEvent = event.toLowerCase();
|
||
if (lowerCaseEvent !== event && vm._events[lowerCaseEvent]) {
|
||
tip(
|
||
"Event \"" + lowerCaseEvent + "\" is emitted in component " +
|
||
(formatComponentName(vm)) + " but the handler is registered for \"" + event + "\". " +
|
||
"Note that HTML attributes are case-insensitive and you cannot use " +
|
||
"v-on to listen to camelCase events when using in-DOM templates. " +
|
||
"You should probably use \"" + (hyphenate(event)) + "\" instead of \"" + event + "\"."
|
||
);
|
||
}
|
||
}
|
||
var cbs = vm._events[event];
|
||
if (cbs) {
|
||
cbs = cbs.length > 1 ? toArray(cbs) : cbs;
|
||
var args = toArray(arguments, 1);
|
||
for (var i = 0, l = cbs.length; i < l; i++) {
|
||
try {
|
||
cbs[i].apply(vm, args);
|
||
} catch (e) {
|
||
handleError(e, vm, ("event handler for \"" + event + "\""));
|
||
}
|
||
}
|
||
}
|
||
return vm
|
||
};
|
||
}
|
||
|
||
/* */
|
||
|
||
/**
|
||
* Runtime helper for resolving raw children VNodes into a slot object.
|
||
*/
|
||
function resolveSlots (
|
||
children,
|
||
context
|
||
) {
|
||
var slots = {};
|
||
if (!children) {
|
||
return slots
|
||
}
|
||
var defaultSlot = [];
|
||
for (var i = 0, l = children.length; i < l; i++) {
|
||
var child = children[i];
|
||
var data = child.data;
|
||
// remove slot attribute if the node is resolved as a Vue slot node
|
||
if (data && data.attrs && data.attrs.slot) {
|
||
delete data.attrs.slot;
|
||
}
|
||
// named slots should only be respected if the vnode was rendered in the
|
||
// same context.
|
||
if ((child.context === context || child.functionalContext === context) &&
|
||
data && data.slot != null
|
||
) {
|
||
var name = child.data.slot;
|
||
var slot = (slots[name] || (slots[name] = []));
|
||
if (child.tag === 'template') {
|
||
slot.push.apply(slot, child.children);
|
||
} else {
|
||
slot.push(child);
|
||
}
|
||
} else {
|
||
defaultSlot.push(child);
|
||
}
|
||
}
|
||
// ignore whitespace
|
||
if (!defaultSlot.every(isWhitespace)) {
|
||
slots.default = defaultSlot;
|
||
}
|
||
return slots
|
||
}
|
||
|
||
function isWhitespace (node) {
|
||
return node.isComment || node.text === ' '
|
||
}
|
||
|
||
function resolveScopedSlots (
|
||
fns, // see flow/vnode
|
||
res
|
||
) {
|
||
res = res || {};
|
||
for (var i = 0; i < fns.length; i++) {
|
||
if (Array.isArray(fns[i])) {
|
||
resolveScopedSlots(fns[i], res);
|
||
} else {
|
||
res[fns[i].key] = fns[i].fn;
|
||
}
|
||
}
|
||
return res
|
||
}
|
||
|
||
/* */
|
||
|
||
var activeInstance = null;
|
||
var isUpdatingChildComponent = false;
|
||
|
||
function initLifecycle (vm) {
|
||
var options = vm.$options;
|
||
|
||
// locate first non-abstract parent
|
||
var parent = options.parent;
|
||
if (parent && !options.abstract) {
|
||
while (parent.$options.abstract && parent.$parent) {
|
||
parent = parent.$parent;
|
||
}
|
||
parent.$children.push(vm);
|
||
}
|
||
|
||
vm.$parent = parent;
|
||
vm.$root = parent ? parent.$root : vm;
|
||
|
||
vm.$children = [];
|
||
vm.$refs = {};
|
||
|
||
vm._watcher = null;
|
||
vm._inactive = null;
|
||
vm._directInactive = false;
|
||
vm._isMounted = false;
|
||
vm._isDestroyed = false;
|
||
vm._isBeingDestroyed = false;
|
||
}
|
||
|
||
function lifecycleMixin (Vue) {
|
||
Vue.prototype._update = function (vnode, hydrating) {
|
||
var vm = this;
|
||
if (vm._isMounted) {
|
||
callHook(vm, 'beforeUpdate');
|
||
}
|
||
var prevEl = vm.$el;
|
||
var prevVnode = vm._vnode;
|
||
var prevActiveInstance = activeInstance;
|
||
activeInstance = vm;
|
||
vm._vnode = vnode;
|
||
// Vue.prototype.__patch__ is injected in entry points
|
||
// based on the rendering backend used.
|
||
if (!prevVnode) {
|
||
// initial render
|
||
vm.$el = vm.__patch__(
|
||
vm.$el, vnode, hydrating, false /* removeOnly */,
|
||
vm.$options._parentElm,
|
||
vm.$options._refElm
|
||
);
|
||
// no need for the ref nodes after initial patch
|
||
// this prevents keeping a detached DOM tree in memory (#5851)
|
||
vm.$options._parentElm = vm.$options._refElm = null;
|
||
} else {
|
||
// updates
|
||
vm.$el = vm.__patch__(prevVnode, vnode);
|
||
}
|
||
activeInstance = prevActiveInstance;
|
||
// update __vue__ reference
|
||
if (prevEl) {
|
||
prevEl.__vue__ = null;
|
||
}
|
||
if (vm.$el) {
|
||
vm.$el.__vue__ = vm;
|
||
}
|
||
// if parent is an HOC, update its $el as well
|
||
if (vm.$vnode && vm.$parent && vm.$vnode === vm.$parent._vnode) {
|
||
vm.$parent.$el = vm.$el;
|
||
}
|
||
// updated hook is called by the scheduler to ensure that children are
|
||
// updated in a parent's updated hook.
|
||
};
|
||
|
||
Vue.prototype.$forceUpdate = function () {
|
||
var vm = this;
|
||
if (vm._watcher) {
|
||
vm._watcher.update();
|
||
}
|
||
};
|
||
|
||
Vue.prototype.$destroy = function () {
|
||
var vm = this;
|
||
if (vm._isBeingDestroyed) {
|
||
return
|
||
}
|
||
callHook(vm, 'beforeDestroy');
|
||
vm._isBeingDestroyed = true;
|
||
// remove self from parent
|
||
var parent = vm.$parent;
|
||
if (parent && !parent._isBeingDestroyed && !vm.$options.abstract) {
|
||
remove(parent.$children, vm);
|
||
}
|
||
// teardown watchers
|
||
if (vm._watcher) {
|
||
vm._watcher.teardown();
|
||
}
|
||
var i = vm._watchers.length;
|
||
while (i--) {
|
||
vm._watchers[i].teardown();
|
||
}
|
||
// remove reference from data ob
|
||
// frozen object may not have observer.
|
||
if (vm._data.__ob__) {
|
||
vm._data.__ob__.vmCount--;
|
||
}
|
||
// call the last hook...
|
||
vm._isDestroyed = true;
|
||
// invoke destroy hooks on current rendered tree
|
||
vm.__patch__(vm._vnode, null);
|
||
// fire destroyed hook
|
||
callHook(vm, 'destroyed');
|
||
// turn off all instance listeners.
|
||
vm.$off();
|
||
// remove __vue__ reference
|
||
if (vm.$el) {
|
||
vm.$el.__vue__ = null;
|
||
}
|
||
};
|
||
}
|
||
|
||
function mountComponent (
|
||
vm,
|
||
el,
|
||
hydrating
|
||
) {
|
||
vm.$el = el;
|
||
if (!vm.$options.render) {
|
||
vm.$options.render = createEmptyVNode;
|
||
if (true) {
|
||
/* istanbul ignore if */
|
||
if ((vm.$options.template && vm.$options.template.charAt(0) !== '#') ||
|
||
vm.$options.el || el) {
|
||
warn(
|
||
'You are using the runtime-only build of Vue where the template ' +
|
||
'compiler is not available. Either pre-compile the templates into ' +
|
||
'render functions, or use the compiler-included build.',
|
||
vm
|
||
);
|
||
} else {
|
||
warn(
|
||
'Failed to mount component: template or render function not defined.',
|
||
vm
|
||
);
|
||
}
|
||
}
|
||
}
|
||
callHook(vm, 'beforeMount');
|
||
|
||
var updateComponent;
|
||
/* istanbul ignore if */
|
||
if ("development" !== 'production' && config.performance && mark) {
|
||
updateComponent = function () {
|
||
var name = vm._name;
|
||
var id = vm._uid;
|
||
var startTag = "vue-perf-start:" + id;
|
||
var endTag = "vue-perf-end:" + id;
|
||
|
||
mark(startTag);
|
||
var vnode = vm._render();
|
||
mark(endTag);
|
||
measure((name + " render"), startTag, endTag);
|
||
|
||
mark(startTag);
|
||
vm._update(vnode, hydrating);
|
||
mark(endTag);
|
||
measure((name + " patch"), startTag, endTag);
|
||
};
|
||
} else {
|
||
updateComponent = function () {
|
||
vm._update(vm._render(), hydrating);
|
||
};
|
||
}
|
||
|
||
vm._watcher = new Watcher(vm, updateComponent, noop);
|
||
hydrating = false;
|
||
|
||
// manually mounted instance, call mounted on self
|
||
// mounted is called for render-created child components in its inserted hook
|
||
if (vm.$vnode == null) {
|
||
vm._isMounted = true;
|
||
callHook(vm, 'mounted');
|
||
}
|
||
return vm
|
||
}
|
||
|
||
function updateChildComponent (
|
||
vm,
|
||
propsData,
|
||
listeners,
|
||
parentVnode,
|
||
renderChildren
|
||
) {
|
||
if (true) {
|
||
isUpdatingChildComponent = true;
|
||
}
|
||
|
||
// determine whether component has slot children
|
||
// we need to do this before overwriting $options._renderChildren
|
||
var hasChildren = !!(
|
||
renderChildren || // has new static slots
|
||
vm.$options._renderChildren || // has old static slots
|
||
parentVnode.data.scopedSlots || // has new scoped slots
|
||
vm.$scopedSlots !== emptyObject // has old scoped slots
|
||
);
|
||
|
||
vm.$options._parentVnode = parentVnode;
|
||
vm.$vnode = parentVnode; // update vm's placeholder node without re-render
|
||
|
||
if (vm._vnode) { // update child tree's parent
|
||
vm._vnode.parent = parentVnode;
|
||
}
|
||
vm.$options._renderChildren = renderChildren;
|
||
|
||
// update $attrs and $listeners hash
|
||
// these are also reactive so they may trigger child update if the child
|
||
// used them during render
|
||
vm.$attrs = (parentVnode.data && parentVnode.data.attrs) || emptyObject;
|
||
vm.$listeners = listeners || emptyObject;
|
||
|
||
// update props
|
||
if (propsData && vm.$options.props) {
|
||
observerState.shouldConvert = false;
|
||
var props = vm._props;
|
||
var propKeys = vm.$options._propKeys || [];
|
||
for (var i = 0; i < propKeys.length; i++) {
|
||
var key = propKeys[i];
|
||
props[key] = validateProp(key, vm.$options.props, propsData, vm);
|
||
}
|
||
observerState.shouldConvert = true;
|
||
// keep a copy of raw propsData
|
||
vm.$options.propsData = propsData;
|
||
}
|
||
|
||
// update listeners
|
||
if (listeners) {
|
||
var oldListeners = vm.$options._parentListeners;
|
||
vm.$options._parentListeners = listeners;
|
||
updateComponentListeners(vm, listeners, oldListeners);
|
||
}
|
||
// resolve slots + force update if has children
|
||
if (hasChildren) {
|
||
vm.$slots = resolveSlots(renderChildren, parentVnode.context);
|
||
vm.$forceUpdate();
|
||
}
|
||
|
||
if (true) {
|
||
isUpdatingChildComponent = false;
|
||
}
|
||
}
|
||
|
||
function isInInactiveTree (vm) {
|
||
while (vm && (vm = vm.$parent)) {
|
||
if (vm._inactive) { return true }
|
||
}
|
||
return false
|
||
}
|
||
|
||
function activateChildComponent (vm, direct) {
|
||
if (direct) {
|
||
vm._directInactive = false;
|
||
if (isInInactiveTree(vm)) {
|
||
return
|
||
}
|
||
} else if (vm._directInactive) {
|
||
return
|
||
}
|
||
if (vm._inactive || vm._inactive === null) {
|
||
vm._inactive = false;
|
||
for (var i = 0; i < vm.$children.length; i++) {
|
||
activateChildComponent(vm.$children[i]);
|
||
}
|
||
callHook(vm, 'activated');
|
||
}
|
||
}
|
||
|
||
function deactivateChildComponent (vm, direct) {
|
||
if (direct) {
|
||
vm._directInactive = true;
|
||
if (isInInactiveTree(vm)) {
|
||
return
|
||
}
|
||
}
|
||
if (!vm._inactive) {
|
||
vm._inactive = true;
|
||
for (var i = 0; i < vm.$children.length; i++) {
|
||
deactivateChildComponent(vm.$children[i]);
|
||
}
|
||
callHook(vm, 'deactivated');
|
||
}
|
||
}
|
||
|
||
function callHook (vm, hook) {
|
||
var handlers = vm.$options[hook];
|
||
if (handlers) {
|
||
for (var i = 0, j = handlers.length; i < j; i++) {
|
||
try {
|
||
handlers[i].call(vm);
|
||
} catch (e) {
|
||
handleError(e, vm, (hook + " hook"));
|
||
}
|
||
}
|
||
}
|
||
if (vm._hasHookEvent) {
|
||
vm.$emit('hook:' + hook);
|
||
}
|
||
}
|
||
|
||
/* */
|
||
|
||
|
||
var MAX_UPDATE_COUNT = 100;
|
||
|
||
var queue = [];
|
||
var activatedChildren = [];
|
||
var has = {};
|
||
var circular = {};
|
||
var waiting = false;
|
||
var flushing = false;
|
||
var index = 0;
|
||
|
||
/**
|
||
* Reset the scheduler's state.
|
||
*/
|
||
function resetSchedulerState () {
|
||
index = queue.length = activatedChildren.length = 0;
|
||
has = {};
|
||
if (true) {
|
||
circular = {};
|
||
}
|
||
waiting = flushing = false;
|
||
}
|
||
|
||
/**
|
||
* Flush both queues and run the watchers.
|
||
*/
|
||
function flushSchedulerQueue () {
|
||
flushing = true;
|
||
var watcher, id;
|
||
|
||
// Sort queue before flush.
|
||
// This ensures that:
|
||
// 1. Components are updated from parent to child. (because parent is always
|
||
// created before the child)
|
||
// 2. A component's user watchers are run before its render watcher (because
|
||
// user watchers are created before the render watcher)
|
||
// 3. If a component is destroyed during a parent component's watcher run,
|
||
// its watchers can be skipped.
|
||
queue.sort(function (a, b) { return a.id - b.id; });
|
||
|
||
// do not cache length because more watchers might be pushed
|
||
// as we run existing watchers
|
||
for (index = 0; index < queue.length; index++) {
|
||
watcher = queue[index];
|
||
id = watcher.id;
|
||
has[id] = null;
|
||
watcher.run();
|
||
// in dev build, check and stop circular updates.
|
||
if ("development" !== 'production' && has[id] != null) {
|
||
circular[id] = (circular[id] || 0) + 1;
|
||
if (circular[id] > MAX_UPDATE_COUNT) {
|
||
warn(
|
||
'You may have an infinite update loop ' + (
|
||
watcher.user
|
||
? ("in watcher with expression \"" + (watcher.expression) + "\"")
|
||
: "in a component render function."
|
||
),
|
||
watcher.vm
|
||
);
|
||
break
|
||
}
|
||
}
|
||
}
|
||
|
||
// keep copies of post queues before resetting state
|
||
var activatedQueue = activatedChildren.slice();
|
||
var updatedQueue = queue.slice();
|
||
|
||
resetSchedulerState();
|
||
|
||
// call component updated and activated hooks
|
||
callActivatedHooks(activatedQueue);
|
||
callUpdatedHooks(updatedQueue);
|
||
|
||
// devtool hook
|
||
/* istanbul ignore if */
|
||
if (devtools && config.devtools) {
|
||
devtools.emit('flush');
|
||
}
|
||
}
|
||
|
||
function callUpdatedHooks (queue) {
|
||
var i = queue.length;
|
||
while (i--) {
|
||
var watcher = queue[i];
|
||
var vm = watcher.vm;
|
||
if (vm._watcher === watcher && vm._isMounted) {
|
||
callHook(vm, 'updated');
|
||
}
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Queue a kept-alive component that was activated during patch.
|
||
* The queue will be processed after the entire tree has been patched.
|
||
*/
|
||
function queueActivatedComponent (vm) {
|
||
// setting _inactive to false here so that a render function can
|
||
// rely on checking whether it's in an inactive tree (e.g. router-view)
|
||
vm._inactive = false;
|
||
activatedChildren.push(vm);
|
||
}
|
||
|
||
function callActivatedHooks (queue) {
|
||
for (var i = 0; i < queue.length; i++) {
|
||
queue[i]._inactive = true;
|
||
activateChildComponent(queue[i], true /* true */);
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Push a watcher into the watcher queue.
|
||
* Jobs with duplicate IDs will be skipped unless it's
|
||
* pushed when the queue is being flushed.
|
||
*/
|
||
function queueWatcher (watcher) {
|
||
var id = watcher.id;
|
||
if (has[id] == null) {
|
||
has[id] = true;
|
||
if (!flushing) {
|
||
queue.push(watcher);
|
||
} else {
|
||
// if already flushing, splice the watcher based on its id
|
||
// if already past its id, it will be run next immediately.
|
||
var i = queue.length - 1;
|
||
while (i > index && queue[i].id > watcher.id) {
|
||
i--;
|
||
}
|
||
queue.splice(i + 1, 0, watcher);
|
||
}
|
||
// queue the flush
|
||
if (!waiting) {
|
||
waiting = true;
|
||
nextTick(flushSchedulerQueue);
|
||
}
|
||
}
|
||
}
|
||
|
||
/* */
|
||
|
||
var uid$2 = 0;
|
||
|
||
/**
|
||
* A watcher parses an expression, collects dependencies,
|
||
* and fires callback when the expression value changes.
|
||
* This is used for both the $watch() api and directives.
|
||
*/
|
||
var Watcher = function Watcher (
|
||
vm,
|
||
expOrFn,
|
||
cb,
|
||
options
|
||
) {
|
||
this.vm = vm;
|
||
vm._watchers.push(this);
|
||
// options
|
||
if (options) {
|
||
this.deep = !!options.deep;
|
||
this.user = !!options.user;
|
||
this.lazy = !!options.lazy;
|
||
this.sync = !!options.sync;
|
||
} else {
|
||
this.deep = this.user = this.lazy = this.sync = false;
|
||
}
|
||
this.cb = cb;
|
||
this.id = ++uid$2; // uid for batching
|
||
this.active = true;
|
||
this.dirty = this.lazy; // for lazy watchers
|
||
this.deps = [];
|
||
this.newDeps = [];
|
||
this.depIds = new _Set();
|
||
this.newDepIds = new _Set();
|
||
this.expression = true
|
||
? expOrFn.toString()
|
||
: '';
|
||
// parse expression for getter
|
||
if (typeof expOrFn === 'function') {
|
||
this.getter = expOrFn;
|
||
} else {
|
||
this.getter = parsePath(expOrFn);
|
||
if (!this.getter) {
|
||
this.getter = function () {};
|
||
"development" !== 'production' && warn(
|
||
"Failed watching path: \"" + expOrFn + "\" " +
|
||
'Watcher only accepts simple dot-delimited paths. ' +
|
||
'For full control, use a function instead.',
|
||
vm
|
||
);
|
||
}
|
||
}
|
||
this.value = this.lazy
|
||
? undefined
|
||
: this.get();
|
||
};
|
||
|
||
/**
|
||
* Evaluate the getter, and re-collect dependencies.
|
||
*/
|
||
Watcher.prototype.get = function get () {
|
||
pushTarget(this);
|
||
var value;
|
||
var vm = this.vm;
|
||
try {
|
||
value = this.getter.call(vm, vm);
|
||
} catch (e) {
|
||
if (this.user) {
|
||
handleError(e, vm, ("getter for watcher \"" + (this.expression) + "\""));
|
||
} else {
|
||
throw e
|
||
}
|
||
} finally {
|
||
// "touch" every property so they are all tracked as
|
||
// dependencies for deep watching
|
||
if (this.deep) {
|
||
traverse(value);
|
||
}
|
||
popTarget();
|
||
this.cleanupDeps();
|
||
}
|
||
return value
|
||
};
|
||
|
||
/**
|
||
* Add a dependency to this directive.
|
||
*/
|
||
Watcher.prototype.addDep = function addDep (dep) {
|
||
var id = dep.id;
|
||
if (!this.newDepIds.has(id)) {
|
||
this.newDepIds.add(id);
|
||
this.newDeps.push(dep);
|
||
if (!this.depIds.has(id)) {
|
||
dep.addSub(this);
|
||
}
|
||
}
|
||
};
|
||
|
||
/**
|
||
* Clean up for dependency collection.
|
||
*/
|
||
Watcher.prototype.cleanupDeps = function cleanupDeps () {
|
||
var this$1 = this;
|
||
|
||
var i = this.deps.length;
|
||
while (i--) {
|
||
var dep = this$1.deps[i];
|
||
if (!this$1.newDepIds.has(dep.id)) {
|
||
dep.removeSub(this$1);
|
||
}
|
||
}
|
||
var tmp = this.depIds;
|
||
this.depIds = this.newDepIds;
|
||
this.newDepIds = tmp;
|
||
this.newDepIds.clear();
|
||
tmp = this.deps;
|
||
this.deps = this.newDeps;
|
||
this.newDeps = tmp;
|
||
this.newDeps.length = 0;
|
||
};
|
||
|
||
/**
|
||
* Subscriber interface.
|
||
* Will be called when a dependency changes.
|
||
*/
|
||
Watcher.prototype.update = function update () {
|
||
/* istanbul ignore else */
|
||
if (this.lazy) {
|
||
this.dirty = true;
|
||
} else if (this.sync) {
|
||
this.run();
|
||
} else {
|
||
queueWatcher(this);
|
||
}
|
||
};
|
||
|
||
/**
|
||
* Scheduler job interface.
|
||
* Will be called by the scheduler.
|
||
*/
|
||
Watcher.prototype.run = function run () {
|
||
if (this.active) {
|
||
var value = this.get();
|
||
if (
|
||
value !== this.value ||
|
||
// Deep watchers and watchers on Object/Arrays should fire even
|
||
// when the value is the same, because the value may
|
||
// have mutated.
|
||
isObject(value) ||
|
||
this.deep
|
||
) {
|
||
// set new value
|
||
var oldValue = this.value;
|
||
this.value = value;
|
||
if (this.user) {
|
||
try {
|
||
this.cb.call(this.vm, value, oldValue);
|
||
} catch (e) {
|
||
handleError(e, this.vm, ("callback for watcher \"" + (this.expression) + "\""));
|
||
}
|
||
} else {
|
||
this.cb.call(this.vm, value, oldValue);
|
||
}
|
||
}
|
||
}
|
||
};
|
||
|
||
/**
|
||
* Evaluate the value of the watcher.
|
||
* This only gets called for lazy watchers.
|
||
*/
|
||
Watcher.prototype.evaluate = function evaluate () {
|
||
this.value = this.get();
|
||
this.dirty = false;
|
||
};
|
||
|
||
/**
|
||
* Depend on all deps collected by this watcher.
|
||
*/
|
||
Watcher.prototype.depend = function depend () {
|
||
var this$1 = this;
|
||
|
||
var i = this.deps.length;
|
||
while (i--) {
|
||
this$1.deps[i].depend();
|
||
}
|
||
};
|
||
|
||
/**
|
||
* Remove self from all dependencies' subscriber list.
|
||
*/
|
||
Watcher.prototype.teardown = function teardown () {
|
||
var this$1 = this;
|
||
|
||
if (this.active) {
|
||
// remove self from vm's watcher list
|
||
// this is a somewhat expensive operation so we skip it
|
||
// if the vm is being destroyed.
|
||
if (!this.vm._isBeingDestroyed) {
|
||
remove(this.vm._watchers, this);
|
||
}
|
||
var i = this.deps.length;
|
||
while (i--) {
|
||
this$1.deps[i].removeSub(this$1);
|
||
}
|
||
this.active = false;
|
||
}
|
||
};
|
||
|
||
/**
|
||
* Recursively traverse an object to evoke all converted
|
||
* getters, so that every nested property inside the object
|
||
* is collected as a "deep" dependency.
|
||
*/
|
||
var seenObjects = new _Set();
|
||
function traverse (val) {
|
||
seenObjects.clear();
|
||
_traverse(val, seenObjects);
|
||
}
|
||
|
||
function _traverse (val, seen) {
|
||
var i, keys;
|
||
var isA = Array.isArray(val);
|
||
if ((!isA && !isObject(val)) || !Object.isExtensible(val)) {
|
||
return
|
||
}
|
||
if (val.__ob__) {
|
||
var depId = val.__ob__.dep.id;
|
||
if (seen.has(depId)) {
|
||
return
|
||
}
|
||
seen.add(depId);
|
||
}
|
||
if (isA) {
|
||
i = val.length;
|
||
while (i--) { _traverse(val[i], seen); }
|
||
} else {
|
||
keys = Object.keys(val);
|
||
i = keys.length;
|
||
while (i--) { _traverse(val[keys[i]], seen); }
|
||
}
|
||
}
|
||
|
||
/* */
|
||
|
||
var sharedPropertyDefinition = {
|
||
enumerable: true,
|
||
configurable: true,
|
||
get: noop,
|
||
set: noop
|
||
};
|
||
|
||
function proxy (target, sourceKey, key) {
|
||
sharedPropertyDefinition.get = function proxyGetter () {
|
||
return this[sourceKey][key]
|
||
};
|
||
sharedPropertyDefinition.set = function proxySetter (val) {
|
||
this[sourceKey][key] = val;
|
||
};
|
||
Object.defineProperty(target, key, sharedPropertyDefinition);
|
||
}
|
||
|
||
function initState (vm) {
|
||
vm._watchers = [];
|
||
var opts = vm.$options;
|
||
if (opts.props) { initProps(vm, opts.props); }
|
||
if (opts.methods) { initMethods(vm, opts.methods); }
|
||
if (opts.data) {
|
||
initData(vm);
|
||
} else {
|
||
observe(vm._data = {}, true /* asRootData */);
|
||
}
|
||
if (opts.computed) { initComputed(vm, opts.computed); }
|
||
if (opts.watch && opts.watch !== nativeWatch) {
|
||
initWatch(vm, opts.watch);
|
||
}
|
||
}
|
||
|
||
function checkOptionType (vm, name) {
|
||
var option = vm.$options[name];
|
||
if (!isPlainObject(option)) {
|
||
warn(
|
||
("component option \"" + name + "\" should be an object."),
|
||
vm
|
||
);
|
||
}
|
||
}
|
||
|
||
function initProps (vm, propsOptions) {
|
||
var propsData = vm.$options.propsData || {};
|
||
var props = vm._props = {};
|
||
// cache prop keys so that future props updates can iterate using Array
|
||
// instead of dynamic object key enumeration.
|
||
var keys = vm.$options._propKeys = [];
|
||
var isRoot = !vm.$parent;
|
||
// root instance props should be converted
|
||
observerState.shouldConvert = isRoot;
|
||
var loop = function ( key ) {
|
||
keys.push(key);
|
||
var value = validateProp(key, propsOptions, propsData, vm);
|
||
/* istanbul ignore else */
|
||
if (true) {
|
||
if (isReservedAttribute(key) || config.isReservedAttr(key)) {
|
||
warn(
|
||
("\"" + key + "\" is a reserved attribute and cannot be used as component prop."),
|
||
vm
|
||
);
|
||
}
|
||
defineReactive$$1(props, key, value, function () {
|
||
if (vm.$parent && !isUpdatingChildComponent) {
|
||
warn(
|
||
"Avoid mutating a prop directly since the value will be " +
|
||
"overwritten whenever the parent component re-renders. " +
|
||
"Instead, use a data or computed property based on the prop's " +
|
||
"value. Prop being mutated: \"" + key + "\"",
|
||
vm
|
||
);
|
||
}
|
||
});
|
||
} else {
|
||
defineReactive$$1(props, key, value);
|
||
}
|
||
// static props are already proxied on the component's prototype
|
||
// during Vue.extend(). We only need to proxy props defined at
|
||
// instantiation here.
|
||
if (!(key in vm)) {
|
||
proxy(vm, "_props", key);
|
||
}
|
||
};
|
||
|
||
for (var key in propsOptions) loop( key );
|
||
observerState.shouldConvert = true;
|
||
}
|
||
|
||
function initData (vm) {
|
||
var data = vm.$options.data;
|
||
data = vm._data = typeof data === 'function'
|
||
? getData(data, vm)
|
||
: data || {};
|
||
if (!isPlainObject(data)) {
|
||
data = {};
|
||
"development" !== 'production' && warn(
|
||
'data functions should return an object:\n' +
|
||
'https://vuejs.org/v2/guide/components.html#data-Must-Be-a-Function',
|
||
vm
|
||
);
|
||
}
|
||
// proxy data on instance
|
||
var keys = Object.keys(data);
|
||
var props = vm.$options.props;
|
||
var methods = vm.$options.methods;
|
||
var i = keys.length;
|
||
while (i--) {
|
||
var key = keys[i];
|
||
if (true) {
|
||
if (methods && hasOwn(methods, key)) {
|
||
warn(
|
||
("Method \"" + key + "\" has already been defined as a data property."),
|
||
vm
|
||
);
|
||
}
|
||
}
|
||
if (props && hasOwn(props, key)) {
|
||
"development" !== 'production' && warn(
|
||
"The data property \"" + key + "\" is already declared as a prop. " +
|
||
"Use prop default value instead.",
|
||
vm
|
||
);
|
||
} else if (!isReserved(key)) {
|
||
proxy(vm, "_data", key);
|
||
}
|
||
}
|
||
// observe data
|
||
observe(data, true /* asRootData */);
|
||
}
|
||
|
||
function getData (data, vm) {
|
||
try {
|
||
return data.call(vm)
|
||
} catch (e) {
|
||
handleError(e, vm, "data()");
|
||
return {}
|
||
}
|
||
}
|
||
|
||
var computedWatcherOptions = { lazy: true };
|
||
|
||
function initComputed (vm, computed) {
|
||
"development" !== 'production' && checkOptionType(vm, 'computed');
|
||
var watchers = vm._computedWatchers = Object.create(null);
|
||
// computed properties are just getters during SSR
|
||
var isSSR = isServerRendering();
|
||
|
||
for (var key in computed) {
|
||
var userDef = computed[key];
|
||
var getter = typeof userDef === 'function' ? userDef : userDef.get;
|
||
if ("development" !== 'production' && getter == null) {
|
||
warn(
|
||
("Getter is missing for computed property \"" + key + "\"."),
|
||
vm
|
||
);
|
||
}
|
||
|
||
if (!isSSR) {
|
||
// create internal watcher for the computed property.
|
||
watchers[key] = new Watcher(
|
||
vm,
|
||
getter || noop,
|
||
noop,
|
||
computedWatcherOptions
|
||
);
|
||
}
|
||
|
||
// component-defined computed properties are already defined on the
|
||
// component prototype. We only need to define computed properties defined
|
||
// at instantiation here.
|
||
if (!(key in vm)) {
|
||
defineComputed(vm, key, userDef);
|
||
} else if (true) {
|
||
if (key in vm.$data) {
|
||
warn(("The computed property \"" + key + "\" is already defined in data."), vm);
|
||
} else if (vm.$options.props && key in vm.$options.props) {
|
||
warn(("The computed property \"" + key + "\" is already defined as a prop."), vm);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
function defineComputed (
|
||
target,
|
||
key,
|
||
userDef
|
||
) {
|
||
var shouldCache = !isServerRendering();
|
||
if (typeof userDef === 'function') {
|
||
sharedPropertyDefinition.get = shouldCache
|
||
? createComputedGetter(key)
|
||
: userDef;
|
||
sharedPropertyDefinition.set = noop;
|
||
} else {
|
||
sharedPropertyDefinition.get = userDef.get
|
||
? shouldCache && userDef.cache !== false
|
||
? createComputedGetter(key)
|
||
: userDef.get
|
||
: noop;
|
||
sharedPropertyDefinition.set = userDef.set
|
||
? userDef.set
|
||
: noop;
|
||
}
|
||
if ("development" !== 'production' &&
|
||
sharedPropertyDefinition.set === noop) {
|
||
sharedPropertyDefinition.set = function () {
|
||
warn(
|
||
("Computed property \"" + key + "\" was assigned to but it has no setter."),
|
||
this
|
||
);
|
||
};
|
||
}
|
||
Object.defineProperty(target, key, sharedPropertyDefinition);
|
||
}
|
||
|
||
function createComputedGetter (key) {
|
||
return function computedGetter () {
|
||
var watcher = this._computedWatchers && this._computedWatchers[key];
|
||
if (watcher) {
|
||
if (watcher.dirty) {
|
||
watcher.evaluate();
|
||
}
|
||
if (Dep.target) {
|
||
watcher.depend();
|
||
}
|
||
return watcher.value
|
||
}
|
||
}
|
||
}
|
||
|
||
function initMethods (vm, methods) {
|
||
"development" !== 'production' && checkOptionType(vm, 'methods');
|
||
var props = vm.$options.props;
|
||
for (var key in methods) {
|
||
if (true) {
|
||
if (methods[key] == null) {
|
||
warn(
|
||
"Method \"" + key + "\" has an undefined value in the component definition. " +
|
||
"Did you reference the function correctly?",
|
||
vm
|
||
);
|
||
}
|
||
if (props && hasOwn(props, key)) {
|
||
warn(
|
||
("Method \"" + key + "\" has already been defined as a prop."),
|
||
vm
|
||
);
|
||
}
|
||
if ((key in vm) && isReserved(key)) {
|
||
warn(
|
||
"Method \"" + key + "\" conflicts with an existing Vue instance method. " +
|
||
"Avoid defining component methods that start with _ or $."
|
||
);
|
||
}
|
||
}
|
||
vm[key] = methods[key] == null ? noop : bind(methods[key], vm);
|
||
}
|
||
}
|
||
|
||
function initWatch (vm, watch) {
|
||
"development" !== 'production' && checkOptionType(vm, 'watch');
|
||
for (var key in watch) {
|
||
var handler = watch[key];
|
||
if (Array.isArray(handler)) {
|
||
for (var i = 0; i < handler.length; i++) {
|
||
createWatcher(vm, key, handler[i]);
|
||
}
|
||
} else {
|
||
createWatcher(vm, key, handler);
|
||
}
|
||
}
|
||
}
|
||
|
||
function createWatcher (
|
||
vm,
|
||
keyOrFn,
|
||
handler,
|
||
options
|
||
) {
|
||
if (isPlainObject(handler)) {
|
||
options = handler;
|
||
handler = handler.handler;
|
||
}
|
||
if (typeof handler === 'string') {
|
||
handler = vm[handler];
|
||
}
|
||
return vm.$watch(keyOrFn, handler, options)
|
||
}
|
||
|
||
function stateMixin (Vue) {
|
||
// flow somehow has problems with directly declared definition object
|
||
// when using Object.defineProperty, so we have to procedurally build up
|
||
// the object here.
|
||
var dataDef = {};
|
||
dataDef.get = function () { return this._data };
|
||
var propsDef = {};
|
||
propsDef.get = function () { return this._props };
|
||
if (true) {
|
||
dataDef.set = function (newData) {
|
||
warn(
|
||
'Avoid replacing instance root $data. ' +
|
||
'Use nested data properties instead.',
|
||
this
|
||
);
|
||
};
|
||
propsDef.set = function () {
|
||
warn("$props is readonly.", this);
|
||
};
|
||
}
|
||
Object.defineProperty(Vue.prototype, '$data', dataDef);
|
||
Object.defineProperty(Vue.prototype, '$props', propsDef);
|
||
|
||
Vue.prototype.$set = set;
|
||
Vue.prototype.$delete = del;
|
||
|
||
Vue.prototype.$watch = function (
|
||
expOrFn,
|
||
cb,
|
||
options
|
||
) {
|
||
var vm = this;
|
||
if (isPlainObject(cb)) {
|
||
return createWatcher(vm, expOrFn, cb, options)
|
||
}
|
||
options = options || {};
|
||
options.user = true;
|
||
var watcher = new Watcher(vm, expOrFn, cb, options);
|
||
if (options.immediate) {
|
||
cb.call(vm, watcher.value);
|
||
}
|
||
return function unwatchFn () {
|
||
watcher.teardown();
|
||
}
|
||
};
|
||
}
|
||
|
||
/* */
|
||
|
||
function initProvide (vm) {
|
||
var provide = vm.$options.provide;
|
||
if (provide) {
|
||
vm._provided = typeof provide === 'function'
|
||
? provide.call(vm)
|
||
: provide;
|
||
}
|
||
}
|
||
|
||
function initInjections (vm) {
|
||
var result = resolveInject(vm.$options.inject, vm);
|
||
if (result) {
|
||
observerState.shouldConvert = false;
|
||
Object.keys(result).forEach(function (key) {
|
||
/* istanbul ignore else */
|
||
if (true) {
|
||
defineReactive$$1(vm, key, result[key], function () {
|
||
warn(
|
||
"Avoid mutating an injected value directly since the changes will be " +
|
||
"overwritten whenever the provided component re-renders. " +
|
||
"injection being mutated: \"" + key + "\"",
|
||
vm
|
||
);
|
||
});
|
||
} else {
|
||
defineReactive$$1(vm, key, result[key]);
|
||
}
|
||
});
|
||
observerState.shouldConvert = true;
|
||
}
|
||
}
|
||
|
||
function resolveInject (inject, vm) {
|
||
if (inject) {
|
||
// inject is :any because flow is not smart enough to figure out cached
|
||
var result = Object.create(null);
|
||
var keys = hasSymbol
|
||
? Reflect.ownKeys(inject).filter(function (key) {
|
||
/* istanbul ignore next */
|
||
return Object.getOwnPropertyDescriptor(inject, key).enumerable
|
||
})
|
||
: Object.keys(inject);
|
||
|
||
for (var i = 0; i < keys.length; i++) {
|
||
var key = keys[i];
|
||
var provideKey = inject[key];
|
||
var source = vm;
|
||
while (source) {
|
||
if (source._provided && provideKey in source._provided) {
|
||
result[key] = source._provided[provideKey];
|
||
break
|
||
}
|
||
source = source.$parent;
|
||
}
|
||
if ("development" !== 'production' && !source) {
|
||
warn(("Injection \"" + key + "\" not found"), vm);
|
||
}
|
||
}
|
||
return result
|
||
}
|
||
}
|
||
|
||
/* */
|
||
|
||
function createFunctionalComponent (
|
||
Ctor,
|
||
propsData,
|
||
data,
|
||
context,
|
||
children
|
||
) {
|
||
var props = {};
|
||
var propOptions = Ctor.options.props;
|
||
if (isDef(propOptions)) {
|
||
for (var key in propOptions) {
|
||
props[key] = validateProp(key, propOptions, propsData || emptyObject);
|
||
}
|
||
} else {
|
||
if (isDef(data.attrs)) { mergeProps(props, data.attrs); }
|
||
if (isDef(data.props)) { mergeProps(props, data.props); }
|
||
}
|
||
// ensure the createElement function in functional components
|
||
// gets a unique context - this is necessary for correct named slot check
|
||
var _context = Object.create(context);
|
||
var h = function (a, b, c, d) { return createElement(_context, a, b, c, d, true); };
|
||
var vnode = Ctor.options.render.call(null, h, {
|
||
data: data,
|
||
props: props,
|
||
children: children,
|
||
parent: context,
|
||
listeners: data.on || emptyObject,
|
||
injections: resolveInject(Ctor.options.inject, context),
|
||
slots: function () { return resolveSlots(children, context); }
|
||
});
|
||
if (vnode instanceof VNode) {
|
||
vnode.functionalContext = context;
|
||
vnode.functionalOptions = Ctor.options;
|
||
if (data.slot) {
|
||
(vnode.data || (vnode.data = {})).slot = data.slot;
|
||
}
|
||
}
|
||
return vnode
|
||
}
|
||
|
||
function mergeProps (to, from) {
|
||
for (var key in from) {
|
||
to[camelize(key)] = from[key];
|
||
}
|
||
}
|
||
|
||
/* */
|
||
|
||
// hooks to be invoked on component VNodes during patch
|
||
var componentVNodeHooks = {
|
||
init: function init (
|
||
vnode,
|
||
hydrating,
|
||
parentElm,
|
||
refElm
|
||
) {
|
||
if (!vnode.componentInstance || vnode.componentInstance._isDestroyed) {
|
||
var child = vnode.componentInstance = createComponentInstanceForVnode(
|
||
vnode,
|
||
activeInstance,
|
||
parentElm,
|
||
refElm
|
||
);
|
||
child.$mount(hydrating ? vnode.elm : undefined, hydrating);
|
||
} else if (vnode.data.keepAlive) {
|
||
// kept-alive components, treat as a patch
|
||
var mountedNode = vnode; // work around flow
|
||
componentVNodeHooks.prepatch(mountedNode, mountedNode);
|
||
}
|
||
},
|
||
|
||
prepatch: function prepatch (oldVnode, vnode) {
|
||
var options = vnode.componentOptions;
|
||
var child = vnode.componentInstance = oldVnode.componentInstance;
|
||
updateChildComponent(
|
||
child,
|
||
options.propsData, // updated props
|
||
options.listeners, // updated listeners
|
||
vnode, // new parent vnode
|
||
options.children // new children
|
||
);
|
||
},
|
||
|
||
insert: function insert (vnode) {
|
||
var context = vnode.context;
|
||
var componentInstance = vnode.componentInstance;
|
||
if (!componentInstance._isMounted) {
|
||
componentInstance._isMounted = true;
|
||
callHook(componentInstance, 'mounted');
|
||
}
|
||
if (vnode.data.keepAlive) {
|
||
if (context._isMounted) {
|
||
// vue-router#1212
|
||
// During updates, a kept-alive component's child components may
|
||
// change, so directly walking the tree here may call activated hooks
|
||
// on incorrect children. Instead we push them into a queue which will
|
||
// be processed after the whole patch process ended.
|
||
queueActivatedComponent(componentInstance);
|
||
} else {
|
||
activateChildComponent(componentInstance, true /* direct */);
|
||
}
|
||
}
|
||
},
|
||
|
||
destroy: function destroy (vnode) {
|
||
var componentInstance = vnode.componentInstance;
|
||
if (!componentInstance._isDestroyed) {
|
||
if (!vnode.data.keepAlive) {
|
||
componentInstance.$destroy();
|
||
} else {
|
||
deactivateChildComponent(componentInstance, true /* direct */);
|
||
}
|
||
}
|
||
}
|
||
};
|
||
|
||
var hooksToMerge = Object.keys(componentVNodeHooks);
|
||
|
||
function createComponent (
|
||
Ctor,
|
||
data,
|
||
context,
|
||
children,
|
||
tag
|
||
) {
|
||
if (isUndef(Ctor)) {
|
||
return
|
||
}
|
||
|
||
var baseCtor = context.$options._base;
|
||
|
||
// plain options object: turn it into a constructor
|
||
if (isObject(Ctor)) {
|
||
Ctor = baseCtor.extend(Ctor);
|
||
}
|
||
|
||
// if at this stage it's not a constructor or an async component factory,
|
||
// reject.
|
||
if (typeof Ctor !== 'function') {
|
||
if (true) {
|
||
warn(("Invalid Component definition: " + (String(Ctor))), context);
|
||
}
|
||
return
|
||
}
|
||
|
||
// async component
|
||
var asyncFactory;
|
||
if (isUndef(Ctor.cid)) {
|
||
asyncFactory = Ctor;
|
||
Ctor = resolveAsyncComponent(asyncFactory, baseCtor, context);
|
||
if (Ctor === undefined) {
|
||
// return a placeholder node for async component, which is rendered
|
||
// as a comment node but preserves all the raw information for the node.
|
||
// the information will be used for async server-rendering and hydration.
|
||
return createAsyncPlaceholder(
|
||
asyncFactory,
|
||
data,
|
||
context,
|
||
children,
|
||
tag
|
||
)
|
||
}
|
||
}
|
||
|
||
data = data || {};
|
||
|
||
// resolve constructor options in case global mixins are applied after
|
||
// component constructor creation
|
||
resolveConstructorOptions(Ctor);
|
||
|
||
// transform component v-model data into props & events
|
||
if (isDef(data.model)) {
|
||
transformModel(Ctor.options, data);
|
||
}
|
||
|
||
// extract props
|
||
var propsData = extractPropsFromVNodeData(data, Ctor, tag);
|
||
|
||
// functional component
|
||
if (isTrue(Ctor.options.functional)) {
|
||
return createFunctionalComponent(Ctor, propsData, data, context, children)
|
||
}
|
||
|
||
// extract listeners, since these needs to be treated as
|
||
// child component listeners instead of DOM listeners
|
||
var listeners = data.on;
|
||
// replace with listeners with .native modifier
|
||
// so it gets processed during parent component patch.
|
||
data.on = data.nativeOn;
|
||
|
||
if (isTrue(Ctor.options.abstract)) {
|
||
// abstract components do not keep anything
|
||
// other than props & listeners & slot
|
||
|
||
// work around flow
|
||
var slot = data.slot;
|
||
data = {};
|
||
if (slot) {
|
||
data.slot = slot;
|
||
}
|
||
}
|
||
|
||
// merge component management hooks onto the placeholder node
|
||
mergeHooks(data);
|
||
|
||
// return a placeholder vnode
|
||
var name = Ctor.options.name || tag;
|
||
var vnode = new VNode(
|
||
("vue-component-" + (Ctor.cid) + (name ? ("-" + name) : '')),
|
||
data, undefined, undefined, undefined, context,
|
||
{ Ctor: Ctor, propsData: propsData, listeners: listeners, tag: tag, children: children },
|
||
asyncFactory
|
||
);
|
||
return vnode
|
||
}
|
||
|
||
function createComponentInstanceForVnode (
|
||
vnode, // we know it's MountedComponentVNode but flow doesn't
|
||
parent, // activeInstance in lifecycle state
|
||
parentElm,
|
||
refElm
|
||
) {
|
||
var vnodeComponentOptions = vnode.componentOptions;
|
||
var options = {
|
||
_isComponent: true,
|
||
parent: parent,
|
||
propsData: vnodeComponentOptions.propsData,
|
||
_componentTag: vnodeComponentOptions.tag,
|
||
_parentVnode: vnode,
|
||
_parentListeners: vnodeComponentOptions.listeners,
|
||
_renderChildren: vnodeComponentOptions.children,
|
||
_parentElm: parentElm || null,
|
||
_refElm: refElm || null
|
||
};
|
||
// check inline-template render functions
|
||
var inlineTemplate = vnode.data.inlineTemplate;
|
||
if (isDef(inlineTemplate)) {
|
||
options.render = inlineTemplate.render;
|
||
options.staticRenderFns = inlineTemplate.staticRenderFns;
|
||
}
|
||
return new vnodeComponentOptions.Ctor(options)
|
||
}
|
||
|
||
function mergeHooks (data) {
|
||
if (!data.hook) {
|
||
data.hook = {};
|
||
}
|
||
for (var i = 0; i < hooksToMerge.length; i++) {
|
||
var key = hooksToMerge[i];
|
||
var fromParent = data.hook[key];
|
||
var ours = componentVNodeHooks[key];
|
||
data.hook[key] = fromParent ? mergeHook$1(ours, fromParent) : ours;
|
||
}
|
||
}
|
||
|
||
function mergeHook$1 (one, two) {
|
||
return function (a, b, c, d) {
|
||
one(a, b, c, d);
|
||
two(a, b, c, d);
|
||
}
|
||
}
|
||
|
||
// transform component v-model info (value and callback) into
|
||
// prop and event handler respectively.
|
||
function transformModel (options, data) {
|
||
var prop = (options.model && options.model.prop) || 'value';
|
||
var event = (options.model && options.model.event) || 'input';(data.props || (data.props = {}))[prop] = data.model.value;
|
||
var on = data.on || (data.on = {});
|
||
if (isDef(on[event])) {
|
||
on[event] = [data.model.callback].concat(on[event]);
|
||
} else {
|
||
on[event] = data.model.callback;
|
||
}
|
||
}
|
||
|
||
/* */
|
||
|
||
var SIMPLE_NORMALIZE = 1;
|
||
var ALWAYS_NORMALIZE = 2;
|
||
|
||
// wrapper function for providing a more flexible interface
|
||
// without getting yelled at by flow
|
||
function createElement (
|
||
context,
|
||
tag,
|
||
data,
|
||
children,
|
||
normalizationType,
|
||
alwaysNormalize
|
||
) {
|
||
if (Array.isArray(data) || isPrimitive(data)) {
|
||
normalizationType = children;
|
||
children = data;
|
||
data = undefined;
|
||
}
|
||
if (isTrue(alwaysNormalize)) {
|
||
normalizationType = ALWAYS_NORMALIZE;
|
||
}
|
||
return _createElement(context, tag, data, children, normalizationType)
|
||
}
|
||
|
||
function _createElement (
|
||
context,
|
||
tag,
|
||
data,
|
||
children,
|
||
normalizationType
|
||
) {
|
||
if (isDef(data) && isDef((data).__ob__)) {
|
||
"development" !== 'production' && warn(
|
||
"Avoid using observed data object as vnode data: " + (JSON.stringify(data)) + "\n" +
|
||
'Always create fresh vnode data objects in each render!',
|
||
context
|
||
);
|
||
return createEmptyVNode()
|
||
}
|
||
// object syntax in v-bind
|
||
if (isDef(data) && isDef(data.is)) {
|
||
tag = data.is;
|
||
}
|
||
if (!tag) {
|
||
// in case of component :is set to falsy value
|
||
return createEmptyVNode()
|
||
}
|
||
// warn against non-primitive key
|
||
if ("development" !== 'production' &&
|
||
isDef(data) && isDef(data.key) && !isPrimitive(data.key)
|
||
) {
|
||
warn(
|
||
'Avoid using non-primitive value as key, ' +
|
||
'use string/number value instead.',
|
||
context
|
||
);
|
||
}
|
||
// support single function children as default scoped slot
|
||
if (Array.isArray(children) &&
|
||
typeof children[0] === 'function'
|
||
) {
|
||
data = data || {};
|
||
data.scopedSlots = { default: children[0] };
|
||
children.length = 0;
|
||
}
|
||
if (normalizationType === ALWAYS_NORMALIZE) {
|
||
children = normalizeChildren(children);
|
||
} else if (normalizationType === SIMPLE_NORMALIZE) {
|
||
children = simpleNormalizeChildren(children);
|
||
}
|
||
var vnode, ns;
|
||
if (typeof tag === 'string') {
|
||
var Ctor;
|
||
ns = (context.$vnode && context.$vnode.ns) || config.getTagNamespace(tag);
|
||
if (config.isReservedTag(tag)) {
|
||
// platform built-in elements
|
||
vnode = new VNode(
|
||
config.parsePlatformTagName(tag), data, children,
|
||
undefined, undefined, context
|
||
);
|
||
} else if (isDef(Ctor = resolveAsset(context.$options, 'components', tag))) {
|
||
// component
|
||
vnode = createComponent(Ctor, data, context, children, tag);
|
||
} else {
|
||
// unknown or unlisted namespaced elements
|
||
// check at runtime because it may get assigned a namespace when its
|
||
// parent normalizes children
|
||
vnode = new VNode(
|
||
tag, data, children,
|
||
undefined, undefined, context
|
||
);
|
||
}
|
||
} else {
|
||
// direct component options / constructor
|
||
vnode = createComponent(tag, data, context, children);
|
||
}
|
||
if (isDef(vnode)) {
|
||
if (ns) { applyNS(vnode, ns); }
|
||
return vnode
|
||
} else {
|
||
return createEmptyVNode()
|
||
}
|
||
}
|
||
|
||
function applyNS (vnode, ns) {
|
||
vnode.ns = ns;
|
||
if (vnode.tag === 'foreignObject') {
|
||
// use default namespace inside foreignObject
|
||
return
|
||
}
|
||
if (isDef(vnode.children)) {
|
||
for (var i = 0, l = vnode.children.length; i < l; i++) {
|
||
var child = vnode.children[i];
|
||
if (isDef(child.tag) && isUndef(child.ns)) {
|
||
applyNS(child, ns);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
/* */
|
||
|
||
/**
|
||
* Runtime helper for rendering v-for lists.
|
||
*/
|
||
function renderList (
|
||
val,
|
||
render
|
||
) {
|
||
var ret, i, l, keys, key;
|
||
if (Array.isArray(val) || typeof val === 'string') {
|
||
ret = new Array(val.length);
|
||
for (i = 0, l = val.length; i < l; i++) {
|
||
ret[i] = render(val[i], i);
|
||
}
|
||
} else if (typeof val === 'number') {
|
||
ret = new Array(val);
|
||
for (i = 0; i < val; i++) {
|
||
ret[i] = render(i + 1, i);
|
||
}
|
||
} else if (isObject(val)) {
|
||
keys = Object.keys(val);
|
||
ret = new Array(keys.length);
|
||
for (i = 0, l = keys.length; i < l; i++) {
|
||
key = keys[i];
|
||
ret[i] = render(val[key], key, i);
|
||
}
|
||
}
|
||
if (isDef(ret)) {
|
||
(ret)._isVList = true;
|
||
}
|
||
return ret
|
||
}
|
||
|
||
/* */
|
||
|
||
/**
|
||
* Runtime helper for rendering <slot>
|
||
*/
|
||
function renderSlot (
|
||
name,
|
||
fallback,
|
||
props,
|
||
bindObject
|
||
) {
|
||
var scopedSlotFn = this.$scopedSlots[name];
|
||
if (scopedSlotFn) { // scoped slot
|
||
props = props || {};
|
||
if (bindObject) {
|
||
props = extend(extend({}, bindObject), props);
|
||
}
|
||
return scopedSlotFn(props) || fallback
|
||
} else {
|
||
var slotNodes = this.$slots[name];
|
||
// warn duplicate slot usage
|
||
if (slotNodes && "development" !== 'production') {
|
||
slotNodes._rendered && warn(
|
||
"Duplicate presence of slot \"" + name + "\" found in the same render tree " +
|
||
"- this will likely cause render errors.",
|
||
this
|
||
);
|
||
slotNodes._rendered = true;
|
||
}
|
||
return slotNodes || fallback
|
||
}
|
||
}
|
||
|
||
/* */
|
||
|
||
/**
|
||
* Runtime helper for resolving filters
|
||
*/
|
||
function resolveFilter (id) {
|
||
return resolveAsset(this.$options, 'filters', id, true) || identity
|
||
}
|
||
|
||
/* */
|
||
|
||
/**
|
||
* Runtime helper for checking keyCodes from config.
|
||
*/
|
||
function checkKeyCodes (
|
||
eventKeyCode,
|
||
key,
|
||
builtInAlias
|
||
) {
|
||
var keyCodes = config.keyCodes[key] || builtInAlias;
|
||
if (Array.isArray(keyCodes)) {
|
||
return keyCodes.indexOf(eventKeyCode) === -1
|
||
} else {
|
||
return keyCodes !== eventKeyCode
|
||
}
|
||
}
|
||
|
||
/* */
|
||
|
||
/**
|
||
* Runtime helper for merging v-bind="object" into a VNode's data.
|
||
*/
|
||
function bindObjectProps (
|
||
data,
|
||
tag,
|
||
value,
|
||
asProp,
|
||
isSync
|
||
) {
|
||
if (value) {
|
||
if (!isObject(value)) {
|
||
"development" !== 'production' && warn(
|
||
'v-bind without argument expects an Object or Array value',
|
||
this
|
||
);
|
||
} else {
|
||
if (Array.isArray(value)) {
|
||
value = toObject(value);
|
||
}
|
||
var hash;
|
||
var loop = function ( key ) {
|
||
if (
|
||
key === 'class' ||
|
||
key === 'style' ||
|
||
isReservedAttribute(key)
|
||
) {
|
||
hash = data;
|
||
} else {
|
||
var type = data.attrs && data.attrs.type;
|
||
hash = asProp || config.mustUseProp(tag, type, key)
|
||
? data.domProps || (data.domProps = {})
|
||
: data.attrs || (data.attrs = {});
|
||
}
|
||
if (!(key in hash)) {
|
||
hash[key] = value[key];
|
||
|
||
if (isSync) {
|
||
var on = data.on || (data.on = {});
|
||
on[("update:" + key)] = function ($event) {
|
||
value[key] = $event;
|
||
};
|
||
}
|
||
}
|
||
};
|
||
|
||
for (var key in value) loop( key );
|
||
}
|
||
}
|
||
return data
|
||
}
|
||
|
||
/* */
|
||
|
||
/**
|
||
* Runtime helper for rendering static trees.
|
||
*/
|
||
function renderStatic (
|
||
index,
|
||
isInFor
|
||
) {
|
||
var tree = this._staticTrees[index];
|
||
// if has already-rendered static tree and not inside v-for,
|
||
// we can reuse the same tree by doing a shallow clone.
|
||
if (tree && !isInFor) {
|
||
return Array.isArray(tree)
|
||
? cloneVNodes(tree)
|
||
: cloneVNode(tree)
|
||
}
|
||
// otherwise, render a fresh tree.
|
||
tree = this._staticTrees[index] =
|
||
this.$options.staticRenderFns[index].call(this._renderProxy);
|
||
markStatic(tree, ("__static__" + index), false);
|
||
return tree
|
||
}
|
||
|
||
/**
|
||
* Runtime helper for v-once.
|
||
* Effectively it means marking the node as static with a unique key.
|
||
*/
|
||
function markOnce (
|
||
tree,
|
||
index,
|
||
key
|
||
) {
|
||
markStatic(tree, ("__once__" + index + (key ? ("_" + key) : "")), true);
|
||
return tree
|
||
}
|
||
|
||
function markStatic (
|
||
tree,
|
||
key,
|
||
isOnce
|
||
) {
|
||
if (Array.isArray(tree)) {
|
||
for (var i = 0; i < tree.length; i++) {
|
||
if (tree[i] && typeof tree[i] !== 'string') {
|
||
markStaticNode(tree[i], (key + "_" + i), isOnce);
|
||
}
|
||
}
|
||
} else {
|
||
markStaticNode(tree, key, isOnce);
|
||
}
|
||
}
|
||
|
||
function markStaticNode (node, key, isOnce) {
|
||
node.isStatic = true;
|
||
node.key = key;
|
||
node.isOnce = isOnce;
|
||
}
|
||
|
||
/* */
|
||
|
||
function bindObjectListeners (data, value) {
|
||
if (value) {
|
||
if (!isPlainObject(value)) {
|
||
"development" !== 'production' && warn(
|
||
'v-on without argument expects an Object value',
|
||
this
|
||
);
|
||
} else {
|
||
var on = data.on = data.on ? extend({}, data.on) : {};
|
||
for (var key in value) {
|
||
var existing = on[key];
|
||
var ours = value[key];
|
||
on[key] = existing ? [].concat(ours, existing) : ours;
|
||
}
|
||
}
|
||
}
|
||
return data
|
||
}
|
||
|
||
/* */
|
||
|
||
function initRender (vm) {
|
||
vm._vnode = null; // the root of the child tree
|
||
vm._staticTrees = null;
|
||
var parentVnode = vm.$vnode = vm.$options._parentVnode; // the placeholder node in parent tree
|
||
var renderContext = parentVnode && parentVnode.context;
|
||
vm.$slots = resolveSlots(vm.$options._renderChildren, renderContext);
|
||
vm.$scopedSlots = emptyObject;
|
||
// bind the createElement fn to this instance
|
||
// so that we get proper render context inside it.
|
||
// args order: tag, data, children, normalizationType, alwaysNormalize
|
||
// internal version is used by render functions compiled from templates
|
||
vm._c = function (a, b, c, d) { return createElement(vm, a, b, c, d, false); };
|
||
// normalization is always applied for the public version, used in
|
||
// user-written render functions.
|
||
vm.$createElement = function (a, b, c, d) { return createElement(vm, a, b, c, d, true); };
|
||
|
||
// $attrs & $listeners are exposed for easier HOC creation.
|
||
// they need to be reactive so that HOCs using them are always updated
|
||
var parentData = parentVnode && parentVnode.data;
|
||
|
||
/* istanbul ignore else */
|
||
if (true) {
|
||
defineReactive$$1(vm, '$attrs', parentData && parentData.attrs || emptyObject, function () {
|
||
!isUpdatingChildComponent && warn("$attrs is readonly.", vm);
|
||
}, true);
|
||
defineReactive$$1(vm, '$listeners', vm.$options._parentListeners || emptyObject, function () {
|
||
!isUpdatingChildComponent && warn("$listeners is readonly.", vm);
|
||
}, true);
|
||
} else {
|
||
defineReactive$$1(vm, '$attrs', parentData && parentData.attrs || emptyObject, null, true);
|
||
defineReactive$$1(vm, '$listeners', vm.$options._parentListeners || emptyObject, null, true);
|
||
}
|
||
}
|
||
|
||
function renderMixin (Vue) {
|
||
Vue.prototype.$nextTick = function (fn) {
|
||
return nextTick(fn, this)
|
||
};
|
||
|
||
Vue.prototype._render = function () {
|
||
var vm = this;
|
||
var ref = vm.$options;
|
||
var render = ref.render;
|
||
var staticRenderFns = ref.staticRenderFns;
|
||
var _parentVnode = ref._parentVnode;
|
||
|
||
if (vm._isMounted) {
|
||
// if the parent didn't update, the slot nodes will be the ones from
|
||
// last render. They need to be cloned to ensure "freshness" for this render.
|
||
for (var key in vm.$slots) {
|
||
var slot = vm.$slots[key];
|
||
if (slot._rendered) {
|
||
vm.$slots[key] = cloneVNodes(slot, true /* deep */);
|
||
}
|
||
}
|
||
}
|
||
|
||
vm.$scopedSlots = (_parentVnode && _parentVnode.data.scopedSlots) || emptyObject;
|
||
|
||
if (staticRenderFns && !vm._staticTrees) {
|
||
vm._staticTrees = [];
|
||
}
|
||
// set parent vnode. this allows render functions to have access
|
||
// to the data on the placeholder node.
|
||
vm.$vnode = _parentVnode;
|
||
// render self
|
||
var vnode;
|
||
try {
|
||
vnode = render.call(vm._renderProxy, vm.$createElement);
|
||
} catch (e) {
|
||
handleError(e, vm, "render function");
|
||
// return error render result,
|
||
// or previous vnode to prevent render error causing blank component
|
||
/* istanbul ignore else */
|
||
if (true) {
|
||
vnode = vm.$options.renderError
|
||
? vm.$options.renderError.call(vm._renderProxy, vm.$createElement, e)
|
||
: vm._vnode;
|
||
} else {
|
||
vnode = vm._vnode;
|
||
}
|
||
}
|
||
// return empty vnode in case the render function errored out
|
||
if (!(vnode instanceof VNode)) {
|
||
if ("development" !== 'production' && Array.isArray(vnode)) {
|
||
warn(
|
||
'Multiple root nodes returned from render function. Render function ' +
|
||
'should return a single root node.',
|
||
vm
|
||
);
|
||
}
|
||
vnode = createEmptyVNode();
|
||
}
|
||
// set parent
|
||
vnode.parent = _parentVnode;
|
||
return vnode
|
||
};
|
||
|
||
// internal render helpers.
|
||
// these are exposed on the instance prototype to reduce generated render
|
||
// code size.
|
||
Vue.prototype._o = markOnce;
|
||
Vue.prototype._n = toNumber;
|
||
Vue.prototype._s = toString;
|
||
Vue.prototype._l = renderList;
|
||
Vue.prototype._t = renderSlot;
|
||
Vue.prototype._q = looseEqual;
|
||
Vue.prototype._i = looseIndexOf;
|
||
Vue.prototype._m = renderStatic;
|
||
Vue.prototype._f = resolveFilter;
|
||
Vue.prototype._k = checkKeyCodes;
|
||
Vue.prototype._b = bindObjectProps;
|
||
Vue.prototype._v = createTextVNode;
|
||
Vue.prototype._e = createEmptyVNode;
|
||
Vue.prototype._u = resolveScopedSlots;
|
||
Vue.prototype._g = bindObjectListeners;
|
||
}
|
||
|
||
/* */
|
||
|
||
var uid$1 = 0;
|
||
|
||
function initMixin (Vue) {
|
||
Vue.prototype._init = function (options) {
|
||
var vm = this;
|
||
// a uid
|
||
vm._uid = uid$1++;
|
||
|
||
var startTag, endTag;
|
||
/* istanbul ignore if */
|
||
if ("development" !== 'production' && config.performance && mark) {
|
||
startTag = "vue-perf-init:" + (vm._uid);
|
||
endTag = "vue-perf-end:" + (vm._uid);
|
||
mark(startTag);
|
||
}
|
||
|
||
// a flag to avoid this being observed
|
||
vm._isVue = true;
|
||
// merge options
|
||
if (options && options._isComponent) {
|
||
// optimize internal component instantiation
|
||
// since dynamic options merging is pretty slow, and none of the
|
||
// internal component options needs special treatment.
|
||
initInternalComponent(vm, options);
|
||
} else {
|
||
vm.$options = mergeOptions(
|
||
resolveConstructorOptions(vm.constructor),
|
||
options || {},
|
||
vm
|
||
);
|
||
}
|
||
/* istanbul ignore else */
|
||
if (true) {
|
||
initProxy(vm);
|
||
} else {
|
||
vm._renderProxy = vm;
|
||
}
|
||
// expose real self
|
||
vm._self = vm;
|
||
initLifecycle(vm);
|
||
initEvents(vm);
|
||
initRender(vm);
|
||
callHook(vm, 'beforeCreate');
|
||
initInjections(vm); // resolve injections before data/props
|
||
initState(vm);
|
||
initProvide(vm); // resolve provide after data/props
|
||
callHook(vm, 'created');
|
||
|
||
/* istanbul ignore if */
|
||
if ("development" !== 'production' && config.performance && mark) {
|
||
vm._name = formatComponentName(vm, false);
|
||
mark(endTag);
|
||
measure(((vm._name) + " init"), startTag, endTag);
|
||
}
|
||
|
||
if (vm.$options.el) {
|
||
vm.$mount(vm.$options.el);
|
||
}
|
||
};
|
||
}
|
||
|
||
function initInternalComponent (vm, options) {
|
||
var opts = vm.$options = Object.create(vm.constructor.options);
|
||
// doing this because it's faster than dynamic enumeration.
|
||
opts.parent = options.parent;
|
||
opts.propsData = options.propsData;
|
||
opts._parentVnode = options._parentVnode;
|
||
opts._parentListeners = options._parentListeners;
|
||
opts._renderChildren = options._renderChildren;
|
||
opts._componentTag = options._componentTag;
|
||
opts._parentElm = options._parentElm;
|
||
opts._refElm = options._refElm;
|
||
if (options.render) {
|
||
opts.render = options.render;
|
||
opts.staticRenderFns = options.staticRenderFns;
|
||
}
|
||
}
|
||
|
||
function resolveConstructorOptions (Ctor) {
|
||
var options = Ctor.options;
|
||
if (Ctor.super) {
|
||
var superOptions = resolveConstructorOptions(Ctor.super);
|
||
var cachedSuperOptions = Ctor.superOptions;
|
||
if (superOptions !== cachedSuperOptions) {
|
||
// super option changed,
|
||
// need to resolve new options.
|
||
Ctor.superOptions = superOptions;
|
||
// check if there are any late-modified/attached options (#4976)
|
||
var modifiedOptions = resolveModifiedOptions(Ctor);
|
||
// update base extend options
|
||
if (modifiedOptions) {
|
||
extend(Ctor.extendOptions, modifiedOptions);
|
||
}
|
||
options = Ctor.options = mergeOptions(superOptions, Ctor.extendOptions);
|
||
if (options.name) {
|
||
options.components[options.name] = Ctor;
|
||
}
|
||
}
|
||
}
|
||
return options
|
||
}
|
||
|
||
function resolveModifiedOptions (Ctor) {
|
||
var modified;
|
||
var latest = Ctor.options;
|
||
var extended = Ctor.extendOptions;
|
||
var sealed = Ctor.sealedOptions;
|
||
for (var key in latest) {
|
||
if (latest[key] !== sealed[key]) {
|
||
if (!modified) { modified = {}; }
|
||
modified[key] = dedupe(latest[key], extended[key], sealed[key]);
|
||
}
|
||
}
|
||
return modified
|
||
}
|
||
|
||
function dedupe (latest, extended, sealed) {
|
||
// compare latest and sealed to ensure lifecycle hooks won't be duplicated
|
||
// between merges
|
||
if (Array.isArray(latest)) {
|
||
var res = [];
|
||
sealed = Array.isArray(sealed) ? sealed : [sealed];
|
||
extended = Array.isArray(extended) ? extended : [extended];
|
||
for (var i = 0; i < latest.length; i++) {
|
||
// push original options and not sealed options to exclude duplicated options
|
||
if (extended.indexOf(latest[i]) >= 0 || sealed.indexOf(latest[i]) < 0) {
|
||
res.push(latest[i]);
|
||
}
|
||
}
|
||
return res
|
||
} else {
|
||
return latest
|
||
}
|
||
}
|
||
|
||
function Vue$3 (options) {
|
||
if ("development" !== 'production' &&
|
||
!(this instanceof Vue$3)
|
||
) {
|
||
warn('Vue is a constructor and should be called with the `new` keyword');
|
||
}
|
||
this._init(options);
|
||
}
|
||
|
||
initMixin(Vue$3);
|
||
stateMixin(Vue$3);
|
||
eventsMixin(Vue$3);
|
||
lifecycleMixin(Vue$3);
|
||
renderMixin(Vue$3);
|
||
|
||
/* */
|
||
|
||
function initUse (Vue) {
|
||
Vue.use = function (plugin) {
|
||
var installedPlugins = (this._installedPlugins || (this._installedPlugins = []));
|
||
if (installedPlugins.indexOf(plugin) > -1) {
|
||
return this
|
||
}
|
||
|
||
// additional parameters
|
||
var args = toArray(arguments, 1);
|
||
args.unshift(this);
|
||
if (typeof plugin.install === 'function') {
|
||
plugin.install.apply(plugin, args);
|
||
} else if (typeof plugin === 'function') {
|
||
plugin.apply(null, args);
|
||
}
|
||
installedPlugins.push(plugin);
|
||
return this
|
||
};
|
||
}
|
||
|
||
/* */
|
||
|
||
function initMixin$1 (Vue) {
|
||
Vue.mixin = function (mixin) {
|
||
this.options = mergeOptions(this.options, mixin);
|
||
return this
|
||
};
|
||
}
|
||
|
||
/* */
|
||
|
||
function initExtend (Vue) {
|
||
/**
|
||
* Each instance constructor, including Vue, has a unique
|
||
* cid. This enables us to create wrapped "child
|
||
* constructors" for prototypal inheritance and cache them.
|
||
*/
|
||
Vue.cid = 0;
|
||
var cid = 1;
|
||
|
||
/**
|
||
* Class inheritance
|
||
*/
|
||
Vue.extend = function (extendOptions) {
|
||
extendOptions = extendOptions || {};
|
||
var Super = this;
|
||
var SuperId = Super.cid;
|
||
var cachedCtors = extendOptions._Ctor || (extendOptions._Ctor = {});
|
||
if (cachedCtors[SuperId]) {
|
||
return cachedCtors[SuperId]
|
||
}
|
||
|
||
var name = extendOptions.name || Super.options.name;
|
||
if (true) {
|
||
if (!/^[a-zA-Z][\w-]*$/.test(name)) {
|
||
warn(
|
||
'Invalid component name: "' + name + '". Component names ' +
|
||
'can only contain alphanumeric characters and the hyphen, ' +
|
||
'and must start with a letter.'
|
||
);
|
||
}
|
||
}
|
||
|
||
var Sub = function VueComponent (options) {
|
||
this._init(options);
|
||
};
|
||
Sub.prototype = Object.create(Super.prototype);
|
||
Sub.prototype.constructor = Sub;
|
||
Sub.cid = cid++;
|
||
Sub.options = mergeOptions(
|
||
Super.options,
|
||
extendOptions
|
||
);
|
||
Sub['super'] = Super;
|
||
|
||
// For props and computed properties, we define the proxy getters on
|
||
// the Vue instances at extension time, on the extended prototype. This
|
||
// avoids Object.defineProperty calls for each instance created.
|
||
if (Sub.options.props) {
|
||
initProps$1(Sub);
|
||
}
|
||
if (Sub.options.computed) {
|
||
initComputed$1(Sub);
|
||
}
|
||
|
||
// allow further extension/mixin/plugin usage
|
||
Sub.extend = Super.extend;
|
||
Sub.mixin = Super.mixin;
|
||
Sub.use = Super.use;
|
||
|
||
// create asset registers, so extended classes
|
||
// can have their private assets too.
|
||
ASSET_TYPES.forEach(function (type) {
|
||
Sub[type] = Super[type];
|
||
});
|
||
// enable recursive self-lookup
|
||
if (name) {
|
||
Sub.options.components[name] = Sub;
|
||
}
|
||
|
||
// keep a reference to the super options at extension time.
|
||
// later at instantiation we can check if Super's options have
|
||
// been updated.
|
||
Sub.superOptions = Super.options;
|
||
Sub.extendOptions = extendOptions;
|
||
Sub.sealedOptions = extend({}, Sub.options);
|
||
|
||
// cache constructor
|
||
cachedCtors[SuperId] = Sub;
|
||
return Sub
|
||
};
|
||
}
|
||
|
||
function initProps$1 (Comp) {
|
||
var props = Comp.options.props;
|
||
for (var key in props) {
|
||
proxy(Comp.prototype, "_props", key);
|
||
}
|
||
}
|
||
|
||
function initComputed$1 (Comp) {
|
||
var computed = Comp.options.computed;
|
||
for (var key in computed) {
|
||
defineComputed(Comp.prototype, key, computed[key]);
|
||
}
|
||
}
|
||
|
||
/* */
|
||
|
||
function initAssetRegisters (Vue) {
|
||
/**
|
||
* Create asset registration methods.
|
||
*/
|
||
ASSET_TYPES.forEach(function (type) {
|
||
Vue[type] = function (
|
||
id,
|
||
definition
|
||
) {
|
||
if (!definition) {
|
||
return this.options[type + 's'][id]
|
||
} else {
|
||
/* istanbul ignore if */
|
||
if (true) {
|
||
if (type === 'component' && config.isReservedTag(id)) {
|
||
warn(
|
||
'Do not use built-in or reserved HTML elements as component ' +
|
||
'id: ' + id
|
||
);
|
||
}
|
||
}
|
||
if (type === 'component' && isPlainObject(definition)) {
|
||
definition.name = definition.name || id;
|
||
definition = this.options._base.extend(definition);
|
||
}
|
||
if (type === 'directive' && typeof definition === 'function') {
|
||
definition = { bind: definition, update: definition };
|
||
}
|
||
this.options[type + 's'][id] = definition;
|
||
return definition
|
||
}
|
||
};
|
||
});
|
||
}
|
||
|
||
/* */
|
||
|
||
var patternTypes = [String, RegExp, Array];
|
||
|
||
function getComponentName (opts) {
|
||
return opts && (opts.Ctor.options.name || opts.tag)
|
||
}
|
||
|
||
function matches (pattern, name) {
|
||
if (Array.isArray(pattern)) {
|
||
return pattern.indexOf(name) > -1
|
||
} else if (typeof pattern === 'string') {
|
||
return pattern.split(',').indexOf(name) > -1
|
||
} else if (isRegExp(pattern)) {
|
||
return pattern.test(name)
|
||
}
|
||
/* istanbul ignore next */
|
||
return false
|
||
}
|
||
|
||
function pruneCache (cache, current, filter) {
|
||
for (var key in cache) {
|
||
var cachedNode = cache[key];
|
||
if (cachedNode) {
|
||
var name = getComponentName(cachedNode.componentOptions);
|
||
if (name && !filter(name)) {
|
||
if (cachedNode !== current) {
|
||
pruneCacheEntry(cachedNode);
|
||
}
|
||
cache[key] = null;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
function pruneCacheEntry (vnode) {
|
||
if (vnode) {
|
||
vnode.componentInstance.$destroy();
|
||
}
|
||
}
|
||
|
||
var KeepAlive = {
|
||
name: 'keep-alive',
|
||
abstract: true,
|
||
|
||
props: {
|
||
include: patternTypes,
|
||
exclude: patternTypes
|
||
},
|
||
|
||
created: function created () {
|
||
this.cache = Object.create(null);
|
||
},
|
||
|
||
destroyed: function destroyed () {
|
||
var this$1 = this;
|
||
|
||
for (var key in this$1.cache) {
|
||
pruneCacheEntry(this$1.cache[key]);
|
||
}
|
||
},
|
||
|
||
watch: {
|
||
include: function include (val) {
|
||
pruneCache(this.cache, this._vnode, function (name) { return matches(val, name); });
|
||
},
|
||
exclude: function exclude (val) {
|
||
pruneCache(this.cache, this._vnode, function (name) { return !matches(val, name); });
|
||
}
|
||
},
|
||
|
||
render: function render () {
|
||
var vnode = getFirstComponentChild(this.$slots.default);
|
||
var componentOptions = vnode && vnode.componentOptions;
|
||
if (componentOptions) {
|
||
// check pattern
|
||
var name = getComponentName(componentOptions);
|
||
if (name && (
|
||
(this.include && !matches(this.include, name)) ||
|
||
(this.exclude && matches(this.exclude, name))
|
||
)) {
|
||
return vnode
|
||
}
|
||
var key = vnode.key == null
|
||
// same constructor may get registered as different local components
|
||
// so cid alone is not enough (#3269)
|
||
? componentOptions.Ctor.cid + (componentOptions.tag ? ("::" + (componentOptions.tag)) : '')
|
||
: vnode.key;
|
||
if (this.cache[key]) {
|
||
vnode.componentInstance = this.cache[key].componentInstance;
|
||
} else {
|
||
this.cache[key] = vnode;
|
||
}
|
||
vnode.data.keepAlive = true;
|
||
}
|
||
return vnode
|
||
}
|
||
};
|
||
|
||
var builtInComponents = {
|
||
KeepAlive: KeepAlive
|
||
};
|
||
|
||
/* */
|
||
|
||
function initGlobalAPI (Vue) {
|
||
// config
|
||
var configDef = {};
|
||
configDef.get = function () { return config; };
|
||
if (true) {
|
||
configDef.set = function () {
|
||
warn(
|
||
'Do not replace the Vue.config object, set individual fields instead.'
|
||
);
|
||
};
|
||
}
|
||
Object.defineProperty(Vue, 'config', configDef);
|
||
|
||
// exposed util methods.
|
||
// NOTE: these are not considered part of the public API - avoid relying on
|
||
// them unless you are aware of the risk.
|
||
Vue.util = {
|
||
warn: warn,
|
||
extend: extend,
|
||
mergeOptions: mergeOptions,
|
||
defineReactive: defineReactive$$1
|
||
};
|
||
|
||
Vue.set = set;
|
||
Vue.delete = del;
|
||
Vue.nextTick = nextTick;
|
||
|
||
Vue.options = Object.create(null);
|
||
ASSET_TYPES.forEach(function (type) {
|
||
Vue.options[type + 's'] = Object.create(null);
|
||
});
|
||
|
||
// this is used to identify the "base" constructor to extend all plain-object
|
||
// components with in Weex's multi-instance scenarios.
|
||
Vue.options._base = Vue;
|
||
|
||
extend(Vue.options.components, builtInComponents);
|
||
|
||
initUse(Vue);
|
||
initMixin$1(Vue);
|
||
initExtend(Vue);
|
||
initAssetRegisters(Vue);
|
||
}
|
||
|
||
initGlobalAPI(Vue$3);
|
||
|
||
Object.defineProperty(Vue$3.prototype, '$isServer', {
|
||
get: isServerRendering
|
||
});
|
||
|
||
Object.defineProperty(Vue$3.prototype, '$ssrContext', {
|
||
get: function get () {
|
||
/* istanbul ignore next */
|
||
return this.$vnode && this.$vnode.ssrContext
|
||
}
|
||
});
|
||
|
||
Vue$3.version = '2.4.4';
|
||
|
||
/* */
|
||
|
||
// these are reserved for web because they are directly compiled away
|
||
// during template compilation
|
||
var isReservedAttr = makeMap('style,class');
|
||
|
||
// attributes that should be using props for binding
|
||
var acceptValue = makeMap('input,textarea,option,select,progress');
|
||
var mustUseProp = function (tag, type, attr) {
|
||
return (
|
||
(attr === 'value' && acceptValue(tag)) && type !== 'button' ||
|
||
(attr === 'selected' && tag === 'option') ||
|
||
(attr === 'checked' && tag === 'input') ||
|
||
(attr === 'muted' && tag === 'video')
|
||
)
|
||
};
|
||
|
||
var isEnumeratedAttr = makeMap('contenteditable,draggable,spellcheck');
|
||
|
||
var isBooleanAttr = makeMap(
|
||
'allowfullscreen,async,autofocus,autoplay,checked,compact,controls,declare,' +
|
||
'default,defaultchecked,defaultmuted,defaultselected,defer,disabled,' +
|
||
'enabled,formnovalidate,hidden,indeterminate,inert,ismap,itemscope,loop,multiple,' +
|
||
'muted,nohref,noresize,noshade,novalidate,nowrap,open,pauseonexit,readonly,' +
|
||
'required,reversed,scoped,seamless,selected,sortable,translate,' +
|
||
'truespeed,typemustmatch,visible'
|
||
);
|
||
|
||
var xlinkNS = 'http://www.w3.org/1999/xlink';
|
||
|
||
var isXlink = function (name) {
|
||
return name.charAt(5) === ':' && name.slice(0, 5) === 'xlink'
|
||
};
|
||
|
||
var getXlinkProp = function (name) {
|
||
return isXlink(name) ? name.slice(6, name.length) : ''
|
||
};
|
||
|
||
var isFalsyAttrValue = function (val) {
|
||
return val == null || val === false
|
||
};
|
||
|
||
/* */
|
||
|
||
function genClassForVnode (vnode) {
|
||
var data = vnode.data;
|
||
var parentNode = vnode;
|
||
var childNode = vnode;
|
||
while (isDef(childNode.componentInstance)) {
|
||
childNode = childNode.componentInstance._vnode;
|
||
if (childNode.data) {
|
||
data = mergeClassData(childNode.data, data);
|
||
}
|
||
}
|
||
while (isDef(parentNode = parentNode.parent)) {
|
||
if (parentNode.data) {
|
||
data = mergeClassData(data, parentNode.data);
|
||
}
|
||
}
|
||
return renderClass(data.staticClass, data.class)
|
||
}
|
||
|
||
function mergeClassData (child, parent) {
|
||
return {
|
||
staticClass: concat(child.staticClass, parent.staticClass),
|
||
class: isDef(child.class)
|
||
? [child.class, parent.class]
|
||
: parent.class
|
||
}
|
||
}
|
||
|
||
function renderClass (
|
||
staticClass,
|
||
dynamicClass
|
||
) {
|
||
if (isDef(staticClass) || isDef(dynamicClass)) {
|
||
return concat(staticClass, stringifyClass(dynamicClass))
|
||
}
|
||
/* istanbul ignore next */
|
||
return ''
|
||
}
|
||
|
||
function concat (a, b) {
|
||
return a ? b ? (a + ' ' + b) : a : (b || '')
|
||
}
|
||
|
||
function stringifyClass (value) {
|
||
if (Array.isArray(value)) {
|
||
return stringifyArray(value)
|
||
}
|
||
if (isObject(value)) {
|
||
return stringifyObject(value)
|
||
}
|
||
if (typeof value === 'string') {
|
||
return value
|
||
}
|
||
/* istanbul ignore next */
|
||
return ''
|
||
}
|
||
|
||
function stringifyArray (value) {
|
||
var res = '';
|
||
var stringified;
|
||
for (var i = 0, l = value.length; i < l; i++) {
|
||
if (isDef(stringified = stringifyClass(value[i])) && stringified !== '') {
|
||
if (res) { res += ' '; }
|
||
res += stringified;
|
||
}
|
||
}
|
||
return res
|
||
}
|
||
|
||
function stringifyObject (value) {
|
||
var res = '';
|
||
for (var key in value) {
|
||
if (value[key]) {
|
||
if (res) { res += ' '; }
|
||
res += key;
|
||
}
|
||
}
|
||
return res
|
||
}
|
||
|
||
/* */
|
||
|
||
var namespaceMap = {
|
||
svg: 'http://www.w3.org/2000/svg',
|
||
math: 'http://www.w3.org/1998/Math/MathML'
|
||
};
|
||
|
||
var isHTMLTag = makeMap(
|
||
'html,body,base,head,link,meta,style,title,' +
|
||
'address,article,aside,footer,header,h1,h2,h3,h4,h5,h6,hgroup,nav,section,' +
|
||
'div,dd,dl,dt,figcaption,figure,picture,hr,img,li,main,ol,p,pre,ul,' +
|
||
'a,b,abbr,bdi,bdo,br,cite,code,data,dfn,em,i,kbd,mark,q,rp,rt,rtc,ruby,' +
|
||
's,samp,small,span,strong,sub,sup,time,u,var,wbr,area,audio,map,track,video,' +
|
||
'embed,object,param,source,canvas,script,noscript,del,ins,' +
|
||
'caption,col,colgroup,table,thead,tbody,td,th,tr,' +
|
||
'button,datalist,fieldset,form,input,label,legend,meter,optgroup,option,' +
|
||
'output,progress,select,textarea,' +
|
||
'details,dialog,menu,menuitem,summary,' +
|
||
'content,element,shadow,template,blockquote,iframe,tfoot'
|
||
);
|
||
|
||
// this map is intentionally selective, only covering SVG elements that may
|
||
// contain child elements.
|
||
var isSVG = makeMap(
|
||
'svg,animate,circle,clippath,cursor,defs,desc,ellipse,filter,font-face,' +
|
||
'foreignObject,g,glyph,image,line,marker,mask,missing-glyph,path,pattern,' +
|
||
'polygon,polyline,rect,switch,symbol,text,textpath,tspan,use,view',
|
||
true
|
||
);
|
||
|
||
var isPreTag = function (tag) { return tag === 'pre'; };
|
||
|
||
var isReservedTag = function (tag) {
|
||
return isHTMLTag(tag) || isSVG(tag)
|
||
};
|
||
|
||
function getTagNamespace (tag) {
|
||
if (isSVG(tag)) {
|
||
return 'svg'
|
||
}
|
||
// basic support for MathML
|
||
// note it doesn't support other MathML elements being component roots
|
||
if (tag === 'math') {
|
||
return 'math'
|
||
}
|
||
}
|
||
|
||
var unknownElementCache = Object.create(null);
|
||
function isUnknownElement (tag) {
|
||
/* istanbul ignore if */
|
||
if (!inBrowser) {
|
||
return true
|
||
}
|
||
if (isReservedTag(tag)) {
|
||
return false
|
||
}
|
||
tag = tag.toLowerCase();
|
||
/* istanbul ignore if */
|
||
if (unknownElementCache[tag] != null) {
|
||
return unknownElementCache[tag]
|
||
}
|
||
var el = document.createElement(tag);
|
||
if (tag.indexOf('-') > -1) {
|
||
// http://stackoverflow.com/a/28210364/1070244
|
||
return (unknownElementCache[tag] = (
|
||
el.constructor === window.HTMLUnknownElement ||
|
||
el.constructor === window.HTMLElement
|
||
))
|
||
} else {
|
||
return (unknownElementCache[tag] = /HTMLUnknownElement/.test(el.toString()))
|
||
}
|
||
}
|
||
|
||
var isTextInputType = makeMap('text,number,password,search,email,tel,url');
|
||
|
||
/* */
|
||
|
||
/**
|
||
* Query an element selector if it's not an element already.
|
||
*/
|
||
function query (el) {
|
||
if (typeof el === 'string') {
|
||
var selected = document.querySelector(el);
|
||
if (!selected) {
|
||
"development" !== 'production' && warn(
|
||
'Cannot find element: ' + el
|
||
);
|
||
return document.createElement('div')
|
||
}
|
||
return selected
|
||
} else {
|
||
return el
|
||
}
|
||
}
|
||
|
||
/* */
|
||
|
||
function createElement$1 (tagName, vnode) {
|
||
var elm = document.createElement(tagName);
|
||
if (tagName !== 'select') {
|
||
return elm
|
||
}
|
||
// false or null will remove the attribute but undefined will not
|
||
if (vnode.data && vnode.data.attrs && vnode.data.attrs.multiple !== undefined) {
|
||
elm.setAttribute('multiple', 'multiple');
|
||
}
|
||
return elm
|
||
}
|
||
|
||
function createElementNS (namespace, tagName) {
|
||
return document.createElementNS(namespaceMap[namespace], tagName)
|
||
}
|
||
|
||
function createTextNode (text) {
|
||
return document.createTextNode(text)
|
||
}
|
||
|
||
function createComment (text) {
|
||
return document.createComment(text)
|
||
}
|
||
|
||
function insertBefore (parentNode, newNode, referenceNode) {
|
||
parentNode.insertBefore(newNode, referenceNode);
|
||
}
|
||
|
||
function removeChild (node, child) {
|
||
node.removeChild(child);
|
||
}
|
||
|
||
function appendChild (node, child) {
|
||
node.appendChild(child);
|
||
}
|
||
|
||
function parentNode (node) {
|
||
return node.parentNode
|
||
}
|
||
|
||
function nextSibling (node) {
|
||
return node.nextSibling
|
||
}
|
||
|
||
function tagName (node) {
|
||
return node.tagName
|
||
}
|
||
|
||
function setTextContent (node, text) {
|
||
node.textContent = text;
|
||
}
|
||
|
||
function setAttribute (node, key, val) {
|
||
node.setAttribute(key, val);
|
||
}
|
||
|
||
|
||
var nodeOps = Object.freeze({
|
||
createElement: createElement$1,
|
||
createElementNS: createElementNS,
|
||
createTextNode: createTextNode,
|
||
createComment: createComment,
|
||
insertBefore: insertBefore,
|
||
removeChild: removeChild,
|
||
appendChild: appendChild,
|
||
parentNode: parentNode,
|
||
nextSibling: nextSibling,
|
||
tagName: tagName,
|
||
setTextContent: setTextContent,
|
||
setAttribute: setAttribute
|
||
});
|
||
|
||
/* */
|
||
|
||
var ref = {
|
||
create: function create (_, vnode) {
|
||
registerRef(vnode);
|
||
},
|
||
update: function update (oldVnode, vnode) {
|
||
if (oldVnode.data.ref !== vnode.data.ref) {
|
||
registerRef(oldVnode, true);
|
||
registerRef(vnode);
|
||
}
|
||
},
|
||
destroy: function destroy (vnode) {
|
||
registerRef(vnode, true);
|
||
}
|
||
};
|
||
|
||
function registerRef (vnode, isRemoval) {
|
||
var key = vnode.data.ref;
|
||
if (!key) { return }
|
||
|
||
var vm = vnode.context;
|
||
var ref = vnode.componentInstance || vnode.elm;
|
||
var refs = vm.$refs;
|
||
if (isRemoval) {
|
||
if (Array.isArray(refs[key])) {
|
||
remove(refs[key], ref);
|
||
} else if (refs[key] === ref) {
|
||
refs[key] = undefined;
|
||
}
|
||
} else {
|
||
if (vnode.data.refInFor) {
|
||
if (!Array.isArray(refs[key])) {
|
||
refs[key] = [ref];
|
||
} else if (refs[key].indexOf(ref) < 0) {
|
||
// $flow-disable-line
|
||
refs[key].push(ref);
|
||
}
|
||
} else {
|
||
refs[key] = ref;
|
||
}
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Virtual DOM patching algorithm based on Snabbdom by
|
||
* Simon Friis Vindum (@paldepind)
|
||
* Licensed under the MIT License
|
||
* https://github.com/paldepind/snabbdom/blob/master/LICENSE
|
||
*
|
||
* modified by Evan You (@yyx990803)
|
||
*
|
||
* Not type-checking this because this file is perf-critical and the cost
|
||
* of making flow understand it is not worth it.
|
||
*/
|
||
|
||
var emptyNode = new VNode('', {}, []);
|
||
|
||
var hooks = ['create', 'activate', 'update', 'remove', 'destroy'];
|
||
|
||
function sameVnode (a, b) {
|
||
return (
|
||
a.key === b.key && (
|
||
(
|
||
a.tag === b.tag &&
|
||
a.isComment === b.isComment &&
|
||
isDef(a.data) === isDef(b.data) &&
|
||
sameInputType(a, b)
|
||
) || (
|
||
isTrue(a.isAsyncPlaceholder) &&
|
||
a.asyncFactory === b.asyncFactory &&
|
||
isUndef(b.asyncFactory.error)
|
||
)
|
||
)
|
||
)
|
||
}
|
||
|
||
function sameInputType (a, b) {
|
||
if (a.tag !== 'input') { return true }
|
||
var i;
|
||
var typeA = isDef(i = a.data) && isDef(i = i.attrs) && i.type;
|
||
var typeB = isDef(i = b.data) && isDef(i = i.attrs) && i.type;
|
||
return typeA === typeB || isTextInputType(typeA) && isTextInputType(typeB)
|
||
}
|
||
|
||
function createKeyToOldIdx (children, beginIdx, endIdx) {
|
||
var i, key;
|
||
var map = {};
|
||
for (i = beginIdx; i <= endIdx; ++i) {
|
||
key = children[i].key;
|
||
if (isDef(key)) { map[key] = i; }
|
||
}
|
||
return map
|
||
}
|
||
|
||
function createPatchFunction (backend) {
|
||
var i, j;
|
||
var cbs = {};
|
||
|
||
var modules = backend.modules;
|
||
var nodeOps = backend.nodeOps;
|
||
|
||
for (i = 0; i < hooks.length; ++i) {
|
||
cbs[hooks[i]] = [];
|
||
for (j = 0; j < modules.length; ++j) {
|
||
if (isDef(modules[j][hooks[i]])) {
|
||
cbs[hooks[i]].push(modules[j][hooks[i]]);
|
||
}
|
||
}
|
||
}
|
||
|
||
function emptyNodeAt (elm) {
|
||
return new VNode(nodeOps.tagName(elm).toLowerCase(), {}, [], undefined, elm)
|
||
}
|
||
|
||
function createRmCb (childElm, listeners) {
|
||
function remove$$1 () {
|
||
if (--remove$$1.listeners === 0) {
|
||
removeNode(childElm);
|
||
}
|
||
}
|
||
remove$$1.listeners = listeners;
|
||
return remove$$1
|
||
}
|
||
|
||
function removeNode (el) {
|
||
var parent = nodeOps.parentNode(el);
|
||
// element may have already been removed due to v-html / v-text
|
||
if (isDef(parent)) {
|
||
nodeOps.removeChild(parent, el);
|
||
}
|
||
}
|
||
|
||
var inPre = 0;
|
||
function createElm (vnode, insertedVnodeQueue, parentElm, refElm, nested) {
|
||
vnode.isRootInsert = !nested; // for transition enter check
|
||
if (createComponent(vnode, insertedVnodeQueue, parentElm, refElm)) {
|
||
return
|
||
}
|
||
|
||
var data = vnode.data;
|
||
var children = vnode.children;
|
||
var tag = vnode.tag;
|
||
if (isDef(tag)) {
|
||
if (true) {
|
||
if (data && data.pre) {
|
||
inPre++;
|
||
}
|
||
if (
|
||
!inPre &&
|
||
!vnode.ns &&
|
||
!(config.ignoredElements.length && config.ignoredElements.indexOf(tag) > -1) &&
|
||
config.isUnknownElement(tag)
|
||
) {
|
||
warn(
|
||
'Unknown custom element: <' + tag + '> - did you ' +
|
||
'register the component correctly? For recursive components, ' +
|
||
'make sure to provide the "name" option.',
|
||
vnode.context
|
||
);
|
||
}
|
||
}
|
||
vnode.elm = vnode.ns
|
||
? nodeOps.createElementNS(vnode.ns, tag)
|
||
: nodeOps.createElement(tag, vnode);
|
||
setScope(vnode);
|
||
|
||
/* istanbul ignore if */
|
||
{
|
||
createChildren(vnode, children, insertedVnodeQueue);
|
||
if (isDef(data)) {
|
||
invokeCreateHooks(vnode, insertedVnodeQueue);
|
||
}
|
||
insert(parentElm, vnode.elm, refElm);
|
||
}
|
||
|
||
if ("development" !== 'production' && data && data.pre) {
|
||
inPre--;
|
||
}
|
||
} else if (isTrue(vnode.isComment)) {
|
||
vnode.elm = nodeOps.createComment(vnode.text);
|
||
insert(parentElm, vnode.elm, refElm);
|
||
} else {
|
||
vnode.elm = nodeOps.createTextNode(vnode.text);
|
||
insert(parentElm, vnode.elm, refElm);
|
||
}
|
||
}
|
||
|
||
function createComponent (vnode, insertedVnodeQueue, parentElm, refElm) {
|
||
var i = vnode.data;
|
||
if (isDef(i)) {
|
||
var isReactivated = isDef(vnode.componentInstance) && i.keepAlive;
|
||
if (isDef(i = i.hook) && isDef(i = i.init)) {
|
||
i(vnode, false /* hydrating */, parentElm, refElm);
|
||
}
|
||
// after calling the init hook, if the vnode is a child component
|
||
// it should've created a child instance and mounted it. the child
|
||
// component also has set the placeholder vnode's elm.
|
||
// in that case we can just return the element and be done.
|
||
if (isDef(vnode.componentInstance)) {
|
||
initComponent(vnode, insertedVnodeQueue);
|
||
if (isTrue(isReactivated)) {
|
||
reactivateComponent(vnode, insertedVnodeQueue, parentElm, refElm);
|
||
}
|
||
return true
|
||
}
|
||
}
|
||
}
|
||
|
||
function initComponent (vnode, insertedVnodeQueue) {
|
||
if (isDef(vnode.data.pendingInsert)) {
|
||
insertedVnodeQueue.push.apply(insertedVnodeQueue, vnode.data.pendingInsert);
|
||
vnode.data.pendingInsert = null;
|
||
}
|
||
vnode.elm = vnode.componentInstance.$el;
|
||
if (isPatchable(vnode)) {
|
||
invokeCreateHooks(vnode, insertedVnodeQueue);
|
||
setScope(vnode);
|
||
} else {
|
||
// empty component root.
|
||
// skip all element-related modules except for ref (#3455)
|
||
registerRef(vnode);
|
||
// make sure to invoke the insert hook
|
||
insertedVnodeQueue.push(vnode);
|
||
}
|
||
}
|
||
|
||
function reactivateComponent (vnode, insertedVnodeQueue, parentElm, refElm) {
|
||
var i;
|
||
// hack for #4339: a reactivated component with inner transition
|
||
// does not trigger because the inner node's created hooks are not called
|
||
// again. It's not ideal to involve module-specific logic in here but
|
||
// there doesn't seem to be a better way to do it.
|
||
var innerNode = vnode;
|
||
while (innerNode.componentInstance) {
|
||
innerNode = innerNode.componentInstance._vnode;
|
||
if (isDef(i = innerNode.data) && isDef(i = i.transition)) {
|
||
for (i = 0; i < cbs.activate.length; ++i) {
|
||
cbs.activate[i](emptyNode, innerNode);
|
||
}
|
||
insertedVnodeQueue.push(innerNode);
|
||
break
|
||
}
|
||
}
|
||
// unlike a newly created component,
|
||
// a reactivated keep-alive component doesn't insert itself
|
||
insert(parentElm, vnode.elm, refElm);
|
||
}
|
||
|
||
function insert (parent, elm, ref$$1) {
|
||
if (isDef(parent)) {
|
||
if (isDef(ref$$1)) {
|
||
if (ref$$1.parentNode === parent) {
|
||
nodeOps.insertBefore(parent, elm, ref$$1);
|
||
}
|
||
} else {
|
||
nodeOps.appendChild(parent, elm);
|
||
}
|
||
}
|
||
}
|
||
|
||
function createChildren (vnode, children, insertedVnodeQueue) {
|
||
if (Array.isArray(children)) {
|
||
for (var i = 0; i < children.length; ++i) {
|
||
createElm(children[i], insertedVnodeQueue, vnode.elm, null, true);
|
||
}
|
||
} else if (isPrimitive(vnode.text)) {
|
||
nodeOps.appendChild(vnode.elm, nodeOps.createTextNode(vnode.text));
|
||
}
|
||
}
|
||
|
||
function isPatchable (vnode) {
|
||
while (vnode.componentInstance) {
|
||
vnode = vnode.componentInstance._vnode;
|
||
}
|
||
return isDef(vnode.tag)
|
||
}
|
||
|
||
function invokeCreateHooks (vnode, insertedVnodeQueue) {
|
||
for (var i$1 = 0; i$1 < cbs.create.length; ++i$1) {
|
||
cbs.create[i$1](emptyNode, vnode);
|
||
}
|
||
i = vnode.data.hook; // Reuse variable
|
||
if (isDef(i)) {
|
||
if (isDef(i.create)) { i.create(emptyNode, vnode); }
|
||
if (isDef(i.insert)) { insertedVnodeQueue.push(vnode); }
|
||
}
|
||
}
|
||
|
||
// set scope id attribute for scoped CSS.
|
||
// this is implemented as a special case to avoid the overhead
|
||
// of going through the normal attribute patching process.
|
||
function setScope (vnode) {
|
||
var i;
|
||
var ancestor = vnode;
|
||
while (ancestor) {
|
||
if (isDef(i = ancestor.context) && isDef(i = i.$options._scopeId)) {
|
||
nodeOps.setAttribute(vnode.elm, i, '');
|
||
}
|
||
ancestor = ancestor.parent;
|
||
}
|
||
// for slot content they should also get the scopeId from the host instance.
|
||
if (isDef(i = activeInstance) &&
|
||
i !== vnode.context &&
|
||
isDef(i = i.$options._scopeId)
|
||
) {
|
||
nodeOps.setAttribute(vnode.elm, i, '');
|
||
}
|
||
}
|
||
|
||
function addVnodes (parentElm, refElm, vnodes, startIdx, endIdx, insertedVnodeQueue) {
|
||
for (; startIdx <= endIdx; ++startIdx) {
|
||
createElm(vnodes[startIdx], insertedVnodeQueue, parentElm, refElm);
|
||
}
|
||
}
|
||
|
||
function invokeDestroyHook (vnode) {
|
||
var i, j;
|
||
var data = vnode.data;
|
||
if (isDef(data)) {
|
||
if (isDef(i = data.hook) && isDef(i = i.destroy)) { i(vnode); }
|
||
for (i = 0; i < cbs.destroy.length; ++i) { cbs.destroy[i](vnode); }
|
||
}
|
||
if (isDef(i = vnode.children)) {
|
||
for (j = 0; j < vnode.children.length; ++j) {
|
||
invokeDestroyHook(vnode.children[j]);
|
||
}
|
||
}
|
||
}
|
||
|
||
function removeVnodes (parentElm, vnodes, startIdx, endIdx) {
|
||
for (; startIdx <= endIdx; ++startIdx) {
|
||
var ch = vnodes[startIdx];
|
||
if (isDef(ch)) {
|
||
if (isDef(ch.tag)) {
|
||
removeAndInvokeRemoveHook(ch);
|
||
invokeDestroyHook(ch);
|
||
} else { // Text node
|
||
removeNode(ch.elm);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
function removeAndInvokeRemoveHook (vnode, rm) {
|
||
if (isDef(rm) || isDef(vnode.data)) {
|
||
var i;
|
||
var listeners = cbs.remove.length + 1;
|
||
if (isDef(rm)) {
|
||
// we have a recursively passed down rm callback
|
||
// increase the listeners count
|
||
rm.listeners += listeners;
|
||
} else {
|
||
// directly removing
|
||
rm = createRmCb(vnode.elm, listeners);
|
||
}
|
||
// recursively invoke hooks on child component root node
|
||
if (isDef(i = vnode.componentInstance) && isDef(i = i._vnode) && isDef(i.data)) {
|
||
removeAndInvokeRemoveHook(i, rm);
|
||
}
|
||
for (i = 0; i < cbs.remove.length; ++i) {
|
||
cbs.remove[i](vnode, rm);
|
||
}
|
||
if (isDef(i = vnode.data.hook) && isDef(i = i.remove)) {
|
||
i(vnode, rm);
|
||
} else {
|
||
rm();
|
||
}
|
||
} else {
|
||
removeNode(vnode.elm);
|
||
}
|
||
}
|
||
|
||
function updateChildren (parentElm, oldCh, newCh, insertedVnodeQueue, removeOnly) {
|
||
var oldStartIdx = 0;
|
||
var newStartIdx = 0;
|
||
var oldEndIdx = oldCh.length - 1;
|
||
var oldStartVnode = oldCh[0];
|
||
var oldEndVnode = oldCh[oldEndIdx];
|
||
var newEndIdx = newCh.length - 1;
|
||
var newStartVnode = newCh[0];
|
||
var newEndVnode = newCh[newEndIdx];
|
||
var oldKeyToIdx, idxInOld, elmToMove, refElm;
|
||
|
||
// removeOnly is a special flag used only by <transition-group>
|
||
// to ensure removed elements stay in correct relative positions
|
||
// during leaving transitions
|
||
var canMove = !removeOnly;
|
||
|
||
while (oldStartIdx <= oldEndIdx && newStartIdx <= newEndIdx) {
|
||
if (isUndef(oldStartVnode)) {
|
||
oldStartVnode = oldCh[++oldStartIdx]; // Vnode has been moved left
|
||
} else if (isUndef(oldEndVnode)) {
|
||
oldEndVnode = oldCh[--oldEndIdx];
|
||
} else if (sameVnode(oldStartVnode, newStartVnode)) {
|
||
patchVnode(oldStartVnode, newStartVnode, insertedVnodeQueue);
|
||
oldStartVnode = oldCh[++oldStartIdx];
|
||
newStartVnode = newCh[++newStartIdx];
|
||
} else if (sameVnode(oldEndVnode, newEndVnode)) {
|
||
patchVnode(oldEndVnode, newEndVnode, insertedVnodeQueue);
|
||
oldEndVnode = oldCh[--oldEndIdx];
|
||
newEndVnode = newCh[--newEndIdx];
|
||
} else if (sameVnode(oldStartVnode, newEndVnode)) { // Vnode moved right
|
||
patchVnode(oldStartVnode, newEndVnode, insertedVnodeQueue);
|
||
canMove && nodeOps.insertBefore(parentElm, oldStartVnode.elm, nodeOps.nextSibling(oldEndVnode.elm));
|
||
oldStartVnode = oldCh[++oldStartIdx];
|
||
newEndVnode = newCh[--newEndIdx];
|
||
} else if (sameVnode(oldEndVnode, newStartVnode)) { // Vnode moved left
|
||
patchVnode(oldEndVnode, newStartVnode, insertedVnodeQueue);
|
||
canMove && nodeOps.insertBefore(parentElm, oldEndVnode.elm, oldStartVnode.elm);
|
||
oldEndVnode = oldCh[--oldEndIdx];
|
||
newStartVnode = newCh[++newStartIdx];
|
||
} else {
|
||
if (isUndef(oldKeyToIdx)) { oldKeyToIdx = createKeyToOldIdx(oldCh, oldStartIdx, oldEndIdx); }
|
||
idxInOld = isDef(newStartVnode.key)
|
||
? oldKeyToIdx[newStartVnode.key]
|
||
: findIdxInOld(newStartVnode, oldCh, oldStartIdx, oldEndIdx);
|
||
if (isUndef(idxInOld)) { // New element
|
||
createElm(newStartVnode, insertedVnodeQueue, parentElm, oldStartVnode.elm);
|
||
} else {
|
||
elmToMove = oldCh[idxInOld];
|
||
/* istanbul ignore if */
|
||
if ("development" !== 'production' && !elmToMove) {
|
||
warn(
|
||
'It seems there are duplicate keys that is causing an update error. ' +
|
||
'Make sure each v-for item has a unique key.'
|
||
);
|
||
}
|
||
if (sameVnode(elmToMove, newStartVnode)) {
|
||
patchVnode(elmToMove, newStartVnode, insertedVnodeQueue);
|
||
oldCh[idxInOld] = undefined;
|
||
canMove && nodeOps.insertBefore(parentElm, elmToMove.elm, oldStartVnode.elm);
|
||
} else {
|
||
// same key but different element. treat as new element
|
||
createElm(newStartVnode, insertedVnodeQueue, parentElm, oldStartVnode.elm);
|
||
}
|
||
}
|
||
newStartVnode = newCh[++newStartIdx];
|
||
}
|
||
}
|
||
if (oldStartIdx > oldEndIdx) {
|
||
refElm = isUndef(newCh[newEndIdx + 1]) ? null : newCh[newEndIdx + 1].elm;
|
||
addVnodes(parentElm, refElm, newCh, newStartIdx, newEndIdx, insertedVnodeQueue);
|
||
} else if (newStartIdx > newEndIdx) {
|
||
removeVnodes(parentElm, oldCh, oldStartIdx, oldEndIdx);
|
||
}
|
||
}
|
||
|
||
function findIdxInOld (node, oldCh, start, end) {
|
||
for (var i = start; i < end; i++) {
|
||
var c = oldCh[i];
|
||
if (isDef(c) && sameVnode(node, c)) { return i }
|
||
}
|
||
}
|
||
|
||
function patchVnode (oldVnode, vnode, insertedVnodeQueue, removeOnly) {
|
||
if (oldVnode === vnode) {
|
||
return
|
||
}
|
||
|
||
var elm = vnode.elm = oldVnode.elm;
|
||
|
||
if (isTrue(oldVnode.isAsyncPlaceholder)) {
|
||
if (isDef(vnode.asyncFactory.resolved)) {
|
||
hydrate(oldVnode.elm, vnode, insertedVnodeQueue);
|
||
} else {
|
||
vnode.isAsyncPlaceholder = true;
|
||
}
|
||
return
|
||
}
|
||
|
||
// reuse element for static trees.
|
||
// note we only do this if the vnode is cloned -
|
||
// if the new node is not cloned it means the render functions have been
|
||
// reset by the hot-reload-api and we need to do a proper re-render.
|
||
if (isTrue(vnode.isStatic) &&
|
||
isTrue(oldVnode.isStatic) &&
|
||
vnode.key === oldVnode.key &&
|
||
(isTrue(vnode.isCloned) || isTrue(vnode.isOnce))
|
||
) {
|
||
vnode.componentInstance = oldVnode.componentInstance;
|
||
return
|
||
}
|
||
|
||
var i;
|
||
var data = vnode.data;
|
||
if (isDef(data) && isDef(i = data.hook) && isDef(i = i.prepatch)) {
|
||
i(oldVnode, vnode);
|
||
}
|
||
|
||
var oldCh = oldVnode.children;
|
||
var ch = vnode.children;
|
||
if (isDef(data) && isPatchable(vnode)) {
|
||
for (i = 0; i < cbs.update.length; ++i) { cbs.update[i](oldVnode, vnode); }
|
||
if (isDef(i = data.hook) && isDef(i = i.update)) { i(oldVnode, vnode); }
|
||
}
|
||
if (isUndef(vnode.text)) {
|
||
if (isDef(oldCh) && isDef(ch)) {
|
||
if (oldCh !== ch) { updateChildren(elm, oldCh, ch, insertedVnodeQueue, removeOnly); }
|
||
} else if (isDef(ch)) {
|
||
if (isDef(oldVnode.text)) { nodeOps.setTextContent(elm, ''); }
|
||
addVnodes(elm, null, ch, 0, ch.length - 1, insertedVnodeQueue);
|
||
} else if (isDef(oldCh)) {
|
||
removeVnodes(elm, oldCh, 0, oldCh.length - 1);
|
||
} else if (isDef(oldVnode.text)) {
|
||
nodeOps.setTextContent(elm, '');
|
||
}
|
||
} else if (oldVnode.text !== vnode.text) {
|
||
nodeOps.setTextContent(elm, vnode.text);
|
||
}
|
||
if (isDef(data)) {
|
||
if (isDef(i = data.hook) && isDef(i = i.postpatch)) { i(oldVnode, vnode); }
|
||
}
|
||
}
|
||
|
||
function invokeInsertHook (vnode, queue, initial) {
|
||
// delay insert hooks for component root nodes, invoke them after the
|
||
// element is really inserted
|
||
if (isTrue(initial) && isDef(vnode.parent)) {
|
||
vnode.parent.data.pendingInsert = queue;
|
||
} else {
|
||
for (var i = 0; i < queue.length; ++i) {
|
||
queue[i].data.hook.insert(queue[i]);
|
||
}
|
||
}
|
||
}
|
||
|
||
var bailed = false;
|
||
// list of modules that can skip create hook during hydration because they
|
||
// are already rendered on the client or has no need for initialization
|
||
var isRenderedModule = makeMap('attrs,style,class,staticClass,staticStyle,key');
|
||
|
||
// Note: this is a browser-only function so we can assume elms are DOM nodes.
|
||
function hydrate (elm, vnode, insertedVnodeQueue) {
|
||
if (isTrue(vnode.isComment) && isDef(vnode.asyncFactory)) {
|
||
vnode.elm = elm;
|
||
vnode.isAsyncPlaceholder = true;
|
||
return true
|
||
}
|
||
if (true) {
|
||
if (!assertNodeMatch(elm, vnode)) {
|
||
return false
|
||
}
|
||
}
|
||
vnode.elm = elm;
|
||
var tag = vnode.tag;
|
||
var data = vnode.data;
|
||
var children = vnode.children;
|
||
if (isDef(data)) {
|
||
if (isDef(i = data.hook) && isDef(i = i.init)) { i(vnode, true /* hydrating */); }
|
||
if (isDef(i = vnode.componentInstance)) {
|
||
// child component. it should have hydrated its own tree.
|
||
initComponent(vnode, insertedVnodeQueue);
|
||
return true
|
||
}
|
||
}
|
||
if (isDef(tag)) {
|
||
if (isDef(children)) {
|
||
// empty element, allow client to pick up and populate children
|
||
if (!elm.hasChildNodes()) {
|
||
createChildren(vnode, children, insertedVnodeQueue);
|
||
} else {
|
||
// v-html and domProps: innerHTML
|
||
if (isDef(i = data) && isDef(i = i.domProps) && isDef(i = i.innerHTML)) {
|
||
if (i !== elm.innerHTML) {
|
||
/* istanbul ignore if */
|
||
if ("development" !== 'production' &&
|
||
typeof console !== 'undefined' &&
|
||
!bailed
|
||
) {
|
||
bailed = true;
|
||
console.warn('Parent: ', elm);
|
||
console.warn('server innerHTML: ', i);
|
||
console.warn('client innerHTML: ', elm.innerHTML);
|
||
}
|
||
return false
|
||
}
|
||
} else {
|
||
// iterate and compare children lists
|
||
var childrenMatch = true;
|
||
var childNode = elm.firstChild;
|
||
for (var i$1 = 0; i$1 < children.length; i$1++) {
|
||
if (!childNode || !hydrate(childNode, children[i$1], insertedVnodeQueue)) {
|
||
childrenMatch = false;
|
||
break
|
||
}
|
||
childNode = childNode.nextSibling;
|
||
}
|
||
// if childNode is not null, it means the actual childNodes list is
|
||
// longer than the virtual children list.
|
||
if (!childrenMatch || childNode) {
|
||
/* istanbul ignore if */
|
||
if ("development" !== 'production' &&
|
||
typeof console !== 'undefined' &&
|
||
!bailed
|
||
) {
|
||
bailed = true;
|
||
console.warn('Parent: ', elm);
|
||
console.warn('Mismatching childNodes vs. VNodes: ', elm.childNodes, children);
|
||
}
|
||
return false
|
||
}
|
||
}
|
||
}
|
||
}
|
||
if (isDef(data)) {
|
||
for (var key in data) {
|
||
if (!isRenderedModule(key)) {
|
||
invokeCreateHooks(vnode, insertedVnodeQueue);
|
||
break
|
||
}
|
||
}
|
||
}
|
||
} else if (elm.data !== vnode.text) {
|
||
elm.data = vnode.text;
|
||
}
|
||
return true
|
||
}
|
||
|
||
function assertNodeMatch (node, vnode) {
|
||
if (isDef(vnode.tag)) {
|
||
return (
|
||
vnode.tag.indexOf('vue-component') === 0 ||
|
||
vnode.tag.toLowerCase() === (node.tagName && node.tagName.toLowerCase())
|
||
)
|
||
} else {
|
||
return node.nodeType === (vnode.isComment ? 8 : 3)
|
||
}
|
||
}
|
||
|
||
return function patch (oldVnode, vnode, hydrating, removeOnly, parentElm, refElm) {
|
||
if (isUndef(vnode)) {
|
||
if (isDef(oldVnode)) { invokeDestroyHook(oldVnode); }
|
||
return
|
||
}
|
||
|
||
var isInitialPatch = false;
|
||
var insertedVnodeQueue = [];
|
||
|
||
if (isUndef(oldVnode)) {
|
||
// empty mount (likely as component), create new root element
|
||
isInitialPatch = true;
|
||
createElm(vnode, insertedVnodeQueue, parentElm, refElm);
|
||
} else {
|
||
var isRealElement = isDef(oldVnode.nodeType);
|
||
if (!isRealElement && sameVnode(oldVnode, vnode)) {
|
||
// patch existing root node
|
||
patchVnode(oldVnode, vnode, insertedVnodeQueue, removeOnly);
|
||
} else {
|
||
if (isRealElement) {
|
||
// mounting to a real element
|
||
// check if this is server-rendered content and if we can perform
|
||
// a successful hydration.
|
||
if (oldVnode.nodeType === 1 && oldVnode.hasAttribute(SSR_ATTR)) {
|
||
oldVnode.removeAttribute(SSR_ATTR);
|
||
hydrating = true;
|
||
}
|
||
if (isTrue(hydrating)) {
|
||
if (hydrate(oldVnode, vnode, insertedVnodeQueue)) {
|
||
invokeInsertHook(vnode, insertedVnodeQueue, true);
|
||
return oldVnode
|
||
} else if (true) {
|
||
warn(
|
||
'The client-side rendered virtual DOM tree is not matching ' +
|
||
'server-rendered content. This is likely caused by incorrect ' +
|
||
'HTML markup, for example nesting block-level elements inside ' +
|
||
'<p>, or missing <tbody>. Bailing hydration and performing ' +
|
||
'full client-side render.'
|
||
);
|
||
}
|
||
}
|
||
// either not server-rendered, or hydration failed.
|
||
// create an empty node and replace it
|
||
oldVnode = emptyNodeAt(oldVnode);
|
||
}
|
||
// replacing existing element
|
||
var oldElm = oldVnode.elm;
|
||
var parentElm$1 = nodeOps.parentNode(oldElm);
|
||
createElm(
|
||
vnode,
|
||
insertedVnodeQueue,
|
||
// extremely rare edge case: do not insert if old element is in a
|
||
// leaving transition. Only happens when combining transition +
|
||
// keep-alive + HOCs. (#4590)
|
||
oldElm._leaveCb ? null : parentElm$1,
|
||
nodeOps.nextSibling(oldElm)
|
||
);
|
||
|
||
if (isDef(vnode.parent)) {
|
||
// component root element replaced.
|
||
// update parent placeholder node element, recursively
|
||
var ancestor = vnode.parent;
|
||
var patchable = isPatchable(vnode);
|
||
while (ancestor) {
|
||
for (var i = 0; i < cbs.destroy.length; ++i) {
|
||
cbs.destroy[i](ancestor);
|
||
}
|
||
ancestor.elm = vnode.elm;
|
||
if (patchable) {
|
||
for (var i$1 = 0; i$1 < cbs.create.length; ++i$1) {
|
||
cbs.create[i$1](emptyNode, ancestor);
|
||
}
|
||
// #6513
|
||
// invoke insert hooks that may have been merged by create hooks.
|
||
// e.g. for directives that uses the "inserted" hook.
|
||
var insert = ancestor.data.hook.insert;
|
||
if (insert.merged) {
|
||
// start at index 1 to avoid re-invoking component mounted hook
|
||
for (var i$2 = 1; i$2 < insert.fns.length; i$2++) {
|
||
insert.fns[i$2]();
|
||
}
|
||
}
|
||
}
|
||
ancestor = ancestor.parent;
|
||
}
|
||
}
|
||
|
||
if (isDef(parentElm$1)) {
|
||
removeVnodes(parentElm$1, [oldVnode], 0, 0);
|
||
} else if (isDef(oldVnode.tag)) {
|
||
invokeDestroyHook(oldVnode);
|
||
}
|
||
}
|
||
}
|
||
|
||
invokeInsertHook(vnode, insertedVnodeQueue, isInitialPatch);
|
||
return vnode.elm
|
||
}
|
||
}
|
||
|
||
/* */
|
||
|
||
var directives = {
|
||
create: updateDirectives,
|
||
update: updateDirectives,
|
||
destroy: function unbindDirectives (vnode) {
|
||
updateDirectives(vnode, emptyNode);
|
||
}
|
||
};
|
||
|
||
function updateDirectives (oldVnode, vnode) {
|
||
if (oldVnode.data.directives || vnode.data.directives) {
|
||
_update(oldVnode, vnode);
|
||
}
|
||
}
|
||
|
||
function _update (oldVnode, vnode) {
|
||
var isCreate = oldVnode === emptyNode;
|
||
var isDestroy = vnode === emptyNode;
|
||
var oldDirs = normalizeDirectives$1(oldVnode.data.directives, oldVnode.context);
|
||
var newDirs = normalizeDirectives$1(vnode.data.directives, vnode.context);
|
||
|
||
var dirsWithInsert = [];
|
||
var dirsWithPostpatch = [];
|
||
|
||
var key, oldDir, dir;
|
||
for (key in newDirs) {
|
||
oldDir = oldDirs[key];
|
||
dir = newDirs[key];
|
||
if (!oldDir) {
|
||
// new directive, bind
|
||
callHook$1(dir, 'bind', vnode, oldVnode);
|
||
if (dir.def && dir.def.inserted) {
|
||
dirsWithInsert.push(dir);
|
||
}
|
||
} else {
|
||
// existing directive, update
|
||
dir.oldValue = oldDir.value;
|
||
callHook$1(dir, 'update', vnode, oldVnode);
|
||
if (dir.def && dir.def.componentUpdated) {
|
||
dirsWithPostpatch.push(dir);
|
||
}
|
||
}
|
||
}
|
||
|
||
if (dirsWithInsert.length) {
|
||
var callInsert = function () {
|
||
for (var i = 0; i < dirsWithInsert.length; i++) {
|
||
callHook$1(dirsWithInsert[i], 'inserted', vnode, oldVnode);
|
||
}
|
||
};
|
||
if (isCreate) {
|
||
mergeVNodeHook(vnode.data.hook || (vnode.data.hook = {}), 'insert', callInsert);
|
||
} else {
|
||
callInsert();
|
||
}
|
||
}
|
||
|
||
if (dirsWithPostpatch.length) {
|
||
mergeVNodeHook(vnode.data.hook || (vnode.data.hook = {}), 'postpatch', function () {
|
||
for (var i = 0; i < dirsWithPostpatch.length; i++) {
|
||
callHook$1(dirsWithPostpatch[i], 'componentUpdated', vnode, oldVnode);
|
||
}
|
||
});
|
||
}
|
||
|
||
if (!isCreate) {
|
||
for (key in oldDirs) {
|
||
if (!newDirs[key]) {
|
||
// no longer present, unbind
|
||
callHook$1(oldDirs[key], 'unbind', oldVnode, oldVnode, isDestroy);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
var emptyModifiers = Object.create(null);
|
||
|
||
function normalizeDirectives$1 (
|
||
dirs,
|
||
vm
|
||
) {
|
||
var res = Object.create(null);
|
||
if (!dirs) {
|
||
return res
|
||
}
|
||
var i, dir;
|
||
for (i = 0; i < dirs.length; i++) {
|
||
dir = dirs[i];
|
||
if (!dir.modifiers) {
|
||
dir.modifiers = emptyModifiers;
|
||
}
|
||
res[getRawDirName(dir)] = dir;
|
||
dir.def = resolveAsset(vm.$options, 'directives', dir.name, true);
|
||
}
|
||
return res
|
||
}
|
||
|
||
function getRawDirName (dir) {
|
||
return dir.rawName || ((dir.name) + "." + (Object.keys(dir.modifiers || {}).join('.')))
|
||
}
|
||
|
||
function callHook$1 (dir, hook, vnode, oldVnode, isDestroy) {
|
||
var fn = dir.def && dir.def[hook];
|
||
if (fn) {
|
||
try {
|
||
fn(vnode.elm, dir, vnode, oldVnode, isDestroy);
|
||
} catch (e) {
|
||
handleError(e, vnode.context, ("directive " + (dir.name) + " " + hook + " hook"));
|
||
}
|
||
}
|
||
}
|
||
|
||
var baseModules = [
|
||
ref,
|
||
directives
|
||
];
|
||
|
||
/* */
|
||
|
||
function updateAttrs (oldVnode, vnode) {
|
||
var opts = vnode.componentOptions;
|
||
if (isDef(opts) && opts.Ctor.options.inheritAttrs === false) {
|
||
return
|
||
}
|
||
if (isUndef(oldVnode.data.attrs) && isUndef(vnode.data.attrs)) {
|
||
return
|
||
}
|
||
var key, cur, old;
|
||
var elm = vnode.elm;
|
||
var oldAttrs = oldVnode.data.attrs || {};
|
||
var attrs = vnode.data.attrs || {};
|
||
// clone observed objects, as the user probably wants to mutate it
|
||
if (isDef(attrs.__ob__)) {
|
||
attrs = vnode.data.attrs = extend({}, attrs);
|
||
}
|
||
|
||
for (key in attrs) {
|
||
cur = attrs[key];
|
||
old = oldAttrs[key];
|
||
if (old !== cur) {
|
||
setAttr(elm, key, cur);
|
||
}
|
||
}
|
||
// #4391: in IE9, setting type can reset value for input[type=radio]
|
||
/* istanbul ignore if */
|
||
if (isIE9 && attrs.value !== oldAttrs.value) {
|
||
setAttr(elm, 'value', attrs.value);
|
||
}
|
||
for (key in oldAttrs) {
|
||
if (isUndef(attrs[key])) {
|
||
if (isXlink(key)) {
|
||
elm.removeAttributeNS(xlinkNS, getXlinkProp(key));
|
||
} else if (!isEnumeratedAttr(key)) {
|
||
elm.removeAttribute(key);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
function setAttr (el, key, value) {
|
||
if (isBooleanAttr(key)) {
|
||
// set attribute for blank value
|
||
// e.g. <option disabled>Select one</option>
|
||
if (isFalsyAttrValue(value)) {
|
||
el.removeAttribute(key);
|
||
} else {
|
||
// technically allowfullscreen is a boolean attribute for <iframe>,
|
||
// but Flash expects a value of "true" when used on <embed> tag
|
||
value = key === 'allowfullscreen' && el.tagName === 'EMBED'
|
||
? 'true'
|
||
: key;
|
||
el.setAttribute(key, value);
|
||
}
|
||
} else if (isEnumeratedAttr(key)) {
|
||
el.setAttribute(key, isFalsyAttrValue(value) || value === 'false' ? 'false' : 'true');
|
||
} else if (isXlink(key)) {
|
||
if (isFalsyAttrValue(value)) {
|
||
el.removeAttributeNS(xlinkNS, getXlinkProp(key));
|
||
} else {
|
||
el.setAttributeNS(xlinkNS, key, value);
|
||
}
|
||
} else {
|
||
if (isFalsyAttrValue(value)) {
|
||
el.removeAttribute(key);
|
||
} else {
|
||
el.setAttribute(key, value);
|
||
}
|
||
}
|
||
}
|
||
|
||
var attrs = {
|
||
create: updateAttrs,
|
||
update: updateAttrs
|
||
};
|
||
|
||
/* */
|
||
|
||
function updateClass (oldVnode, vnode) {
|
||
var el = vnode.elm;
|
||
var data = vnode.data;
|
||
var oldData = oldVnode.data;
|
||
if (
|
||
isUndef(data.staticClass) &&
|
||
isUndef(data.class) && (
|
||
isUndef(oldData) || (
|
||
isUndef(oldData.staticClass) &&
|
||
isUndef(oldData.class)
|
||
)
|
||
)
|
||
) {
|
||
return
|
||
}
|
||
|
||
var cls = genClassForVnode(vnode);
|
||
|
||
// handle transition classes
|
||
var transitionClass = el._transitionClasses;
|
||
if (isDef(transitionClass)) {
|
||
cls = concat(cls, stringifyClass(transitionClass));
|
||
}
|
||
|
||
// set the class
|
||
if (cls !== el._prevClass) {
|
||
el.setAttribute('class', cls);
|
||
el._prevClass = cls;
|
||
}
|
||
}
|
||
|
||
var klass = {
|
||
create: updateClass,
|
||
update: updateClass
|
||
};
|
||
|
||
/* */
|
||
|
||
var validDivisionCharRE = /[\w).+\-_$\]]/;
|
||
|
||
function parseFilters (exp) {
|
||
var inSingle = false;
|
||
var inDouble = false;
|
||
var inTemplateString = false;
|
||
var inRegex = false;
|
||
var curly = 0;
|
||
var square = 0;
|
||
var paren = 0;
|
||
var lastFilterIndex = 0;
|
||
var c, prev, i, expression, filters;
|
||
|
||
for (i = 0; i < exp.length; i++) {
|
||
prev = c;
|
||
c = exp.charCodeAt(i);
|
||
if (inSingle) {
|
||
if (c === 0x27 && prev !== 0x5C) { inSingle = false; }
|
||
} else if (inDouble) {
|
||
if (c === 0x22 && prev !== 0x5C) { inDouble = false; }
|
||
} else if (inTemplateString) {
|
||
if (c === 0x60 && prev !== 0x5C) { inTemplateString = false; }
|
||
} else if (inRegex) {
|
||
if (c === 0x2f && prev !== 0x5C) { inRegex = false; }
|
||
} else if (
|
||
c === 0x7C && // pipe
|
||
exp.charCodeAt(i + 1) !== 0x7C &&
|
||
exp.charCodeAt(i - 1) !== 0x7C &&
|
||
!curly && !square && !paren
|
||
) {
|
||
if (expression === undefined) {
|
||
// first filter, end of expression
|
||
lastFilterIndex = i + 1;
|
||
expression = exp.slice(0, i).trim();
|
||
} else {
|
||
pushFilter();
|
||
}
|
||
} else {
|
||
switch (c) {
|
||
case 0x22: inDouble = true; break // "
|
||
case 0x27: inSingle = true; break // '
|
||
case 0x60: inTemplateString = true; break // `
|
||
case 0x28: paren++; break // (
|
||
case 0x29: paren--; break // )
|
||
case 0x5B: square++; break // [
|
||
case 0x5D: square--; break // ]
|
||
case 0x7B: curly++; break // {
|
||
case 0x7D: curly--; break // }
|
||
}
|
||
if (c === 0x2f) { // /
|
||
var j = i - 1;
|
||
var p = (void 0);
|
||
// find first non-whitespace prev char
|
||
for (; j >= 0; j--) {
|
||
p = exp.charAt(j);
|
||
if (p !== ' ') { break }
|
||
}
|
||
if (!p || !validDivisionCharRE.test(p)) {
|
||
inRegex = true;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
if (expression === undefined) {
|
||
expression = exp.slice(0, i).trim();
|
||
} else if (lastFilterIndex !== 0) {
|
||
pushFilter();
|
||
}
|
||
|
||
function pushFilter () {
|
||
(filters || (filters = [])).push(exp.slice(lastFilterIndex, i).trim());
|
||
lastFilterIndex = i + 1;
|
||
}
|
||
|
||
if (filters) {
|
||
for (i = 0; i < filters.length; i++) {
|
||
expression = wrapFilter(expression, filters[i]);
|
||
}
|
||
}
|
||
|
||
return expression
|
||
}
|
||
|
||
function wrapFilter (exp, filter) {
|
||
var i = filter.indexOf('(');
|
||
if (i < 0) {
|
||
// _f: resolveFilter
|
||
return ("_f(\"" + filter + "\")(" + exp + ")")
|
||
} else {
|
||
var name = filter.slice(0, i);
|
||
var args = filter.slice(i + 1);
|
||
return ("_f(\"" + name + "\")(" + exp + "," + args)
|
||
}
|
||
}
|
||
|
||
/* */
|
||
|
||
function baseWarn (msg) {
|
||
console.error(("[Vue compiler]: " + msg));
|
||
}
|
||
|
||
function pluckModuleFunction (
|
||
modules,
|
||
key
|
||
) {
|
||
return modules
|
||
? modules.map(function (m) { return m[key]; }).filter(function (_) { return _; })
|
||
: []
|
||
}
|
||
|
||
function addProp (el, name, value) {
|
||
(el.props || (el.props = [])).push({ name: name, value: value });
|
||
}
|
||
|
||
function addAttr (el, name, value) {
|
||
(el.attrs || (el.attrs = [])).push({ name: name, value: value });
|
||
}
|
||
|
||
function addDirective (
|
||
el,
|
||
name,
|
||
rawName,
|
||
value,
|
||
arg,
|
||
modifiers
|
||
) {
|
||
(el.directives || (el.directives = [])).push({ name: name, rawName: rawName, value: value, arg: arg, modifiers: modifiers });
|
||
}
|
||
|
||
function addHandler (
|
||
el,
|
||
name,
|
||
value,
|
||
modifiers,
|
||
important,
|
||
warn
|
||
) {
|
||
// warn prevent and passive modifier
|
||
/* istanbul ignore if */
|
||
if (
|
||
"development" !== 'production' && warn &&
|
||
modifiers && modifiers.prevent && modifiers.passive
|
||
) {
|
||
warn(
|
||
'passive and prevent can\'t be used together. ' +
|
||
'Passive handler can\'t prevent default event.'
|
||
);
|
||
}
|
||
// check capture modifier
|
||
if (modifiers && modifiers.capture) {
|
||
delete modifiers.capture;
|
||
name = '!' + name; // mark the event as captured
|
||
}
|
||
if (modifiers && modifiers.once) {
|
||
delete modifiers.once;
|
||
name = '~' + name; // mark the event as once
|
||
}
|
||
/* istanbul ignore if */
|
||
if (modifiers && modifiers.passive) {
|
||
delete modifiers.passive;
|
||
name = '&' + name; // mark the event as passive
|
||
}
|
||
var events;
|
||
if (modifiers && modifiers.native) {
|
||
delete modifiers.native;
|
||
events = el.nativeEvents || (el.nativeEvents = {});
|
||
} else {
|
||
events = el.events || (el.events = {});
|
||
}
|
||
var newHandler = { value: value, modifiers: modifiers };
|
||
var handlers = events[name];
|
||
/* istanbul ignore if */
|
||
if (Array.isArray(handlers)) {
|
||
important ? handlers.unshift(newHandler) : handlers.push(newHandler);
|
||
} else if (handlers) {
|
||
events[name] = important ? [newHandler, handlers] : [handlers, newHandler];
|
||
} else {
|
||
events[name] = newHandler;
|
||
}
|
||
}
|
||
|
||
function getBindingAttr (
|
||
el,
|
||
name,
|
||
getStatic
|
||
) {
|
||
var dynamicValue =
|
||
getAndRemoveAttr(el, ':' + name) ||
|
||
getAndRemoveAttr(el, 'v-bind:' + name);
|
||
if (dynamicValue != null) {
|
||
return parseFilters(dynamicValue)
|
||
} else if (getStatic !== false) {
|
||
var staticValue = getAndRemoveAttr(el, name);
|
||
if (staticValue != null) {
|
||
return JSON.stringify(staticValue)
|
||
}
|
||
}
|
||
}
|
||
|
||
function getAndRemoveAttr (el, name) {
|
||
var val;
|
||
if ((val = el.attrsMap[name]) != null) {
|
||
var list = el.attrsList;
|
||
for (var i = 0, l = list.length; i < l; i++) {
|
||
if (list[i].name === name) {
|
||
list.splice(i, 1);
|
||
break
|
||
}
|
||
}
|
||
}
|
||
return val
|
||
}
|
||
|
||
/* */
|
||
|
||
/**
|
||
* Cross-platform code generation for component v-model
|
||
*/
|
||
function genComponentModel (
|
||
el,
|
||
value,
|
||
modifiers
|
||
) {
|
||
var ref = modifiers || {};
|
||
var number = ref.number;
|
||
var trim = ref.trim;
|
||
|
||
var baseValueExpression = '$$v';
|
||
var valueExpression = baseValueExpression;
|
||
if (trim) {
|
||
valueExpression =
|
||
"(typeof " + baseValueExpression + " === 'string'" +
|
||
"? " + baseValueExpression + ".trim()" +
|
||
": " + baseValueExpression + ")";
|
||
}
|
||
if (number) {
|
||
valueExpression = "_n(" + valueExpression + ")";
|
||
}
|
||
var assignment = genAssignmentCode(value, valueExpression);
|
||
|
||
el.model = {
|
||
value: ("(" + value + ")"),
|
||
expression: ("\"" + value + "\""),
|
||
callback: ("function (" + baseValueExpression + ") {" + assignment + "}")
|
||
};
|
||
}
|
||
|
||
/**
|
||
* Cross-platform codegen helper for generating v-model value assignment code.
|
||
*/
|
||
function genAssignmentCode (
|
||
value,
|
||
assignment
|
||
) {
|
||
var modelRs = parseModel(value);
|
||
if (modelRs.idx === null) {
|
||
return (value + "=" + assignment)
|
||
} else {
|
||
return ("$set(" + (modelRs.exp) + ", " + (modelRs.idx) + ", " + assignment + ")")
|
||
}
|
||
}
|
||
|
||
/**
|
||
* parse directive model to do the array update transform. a[idx] = val => $$a.splice($$idx, 1, val)
|
||
*
|
||
* for loop possible cases:
|
||
*
|
||
* - test
|
||
* - test[idx]
|
||
* - test[test1[idx]]
|
||
* - test["a"][idx]
|
||
* - xxx.test[a[a].test1[idx]]
|
||
* - test.xxx.a["asa"][test1[idx]]
|
||
*
|
||
*/
|
||
|
||
var len;
|
||
var str;
|
||
var chr;
|
||
var index$1;
|
||
var expressionPos;
|
||
var expressionEndPos;
|
||
|
||
function parseModel (val) {
|
||
str = val;
|
||
len = str.length;
|
||
index$1 = expressionPos = expressionEndPos = 0;
|
||
|
||
if (val.indexOf('[') < 0 || val.lastIndexOf(']') < len - 1) {
|
||
return {
|
||
exp: val,
|
||
idx: null
|
||
}
|
||
}
|
||
|
||
while (!eof()) {
|
||
chr = next();
|
||
/* istanbul ignore if */
|
||
if (isStringStart(chr)) {
|
||
parseString(chr);
|
||
} else if (chr === 0x5B) {
|
||
parseBracket(chr);
|
||
}
|
||
}
|
||
|
||
return {
|
||
exp: val.substring(0, expressionPos),
|
||
idx: val.substring(expressionPos + 1, expressionEndPos)
|
||
}
|
||
}
|
||
|
||
function next () {
|
||
return str.charCodeAt(++index$1)
|
||
}
|
||
|
||
function eof () {
|
||
return index$1 >= len
|
||
}
|
||
|
||
function isStringStart (chr) {
|
||
return chr === 0x22 || chr === 0x27
|
||
}
|
||
|
||
function parseBracket (chr) {
|
||
var inBracket = 1;
|
||
expressionPos = index$1;
|
||
while (!eof()) {
|
||
chr = next();
|
||
if (isStringStart(chr)) {
|
||
parseString(chr);
|
||
continue
|
||
}
|
||
if (chr === 0x5B) { inBracket++; }
|
||
if (chr === 0x5D) { inBracket--; }
|
||
if (inBracket === 0) {
|
||
expressionEndPos = index$1;
|
||
break
|
||
}
|
||
}
|
||
}
|
||
|
||
function parseString (chr) {
|
||
var stringQuote = chr;
|
||
while (!eof()) {
|
||
chr = next();
|
||
if (chr === stringQuote) {
|
||
break
|
||
}
|
||
}
|
||
}
|
||
|
||
/* */
|
||
|
||
var warn$1;
|
||
|
||
// in some cases, the event used has to be determined at runtime
|
||
// so we used some reserved tokens during compile.
|
||
var RANGE_TOKEN = '__r';
|
||
var CHECKBOX_RADIO_TOKEN = '__c';
|
||
|
||
function model (
|
||
el,
|
||
dir,
|
||
_warn
|
||
) {
|
||
warn$1 = _warn;
|
||
var value = dir.value;
|
||
var modifiers = dir.modifiers;
|
||
var tag = el.tag;
|
||
var type = el.attrsMap.type;
|
||
|
||
if (true) {
|
||
var dynamicType = el.attrsMap['v-bind:type'] || el.attrsMap[':type'];
|
||
if (tag === 'input' && dynamicType) {
|
||
warn$1(
|
||
"<input :type=\"" + dynamicType + "\" v-model=\"" + value + "\">:\n" +
|
||
"v-model does not support dynamic input types. Use v-if branches instead."
|
||
);
|
||
}
|
||
// inputs with type="file" are read only and setting the input's
|
||
// value will throw an error.
|
||
if (tag === 'input' && type === 'file') {
|
||
warn$1(
|
||
"<" + (el.tag) + " v-model=\"" + value + "\" type=\"file\">:\n" +
|
||
"File inputs are read only. Use a v-on:change listener instead."
|
||
);
|
||
}
|
||
}
|
||
|
||
if (el.component) {
|
||
genComponentModel(el, value, modifiers);
|
||
// component v-model doesn't need extra runtime
|
||
return false
|
||
} else if (tag === 'select') {
|
||
genSelect(el, value, modifiers);
|
||
} else if (tag === 'input' && type === 'checkbox') {
|
||
genCheckboxModel(el, value, modifiers);
|
||
} else if (tag === 'input' && type === 'radio') {
|
||
genRadioModel(el, value, modifiers);
|
||
} else if (tag === 'input' || tag === 'textarea') {
|
||
genDefaultModel(el, value, modifiers);
|
||
} else if (!config.isReservedTag(tag)) {
|
||
genComponentModel(el, value, modifiers);
|
||
// component v-model doesn't need extra runtime
|
||
return false
|
||
} else if (true) {
|
||
warn$1(
|
||
"<" + (el.tag) + " v-model=\"" + value + "\">: " +
|
||
"v-model is not supported on this element type. " +
|
||
'If you are working with contenteditable, it\'s recommended to ' +
|
||
'wrap a library dedicated for that purpose inside a custom component.'
|
||
);
|
||
}
|
||
|
||
// ensure runtime directive metadata
|
||
return true
|
||
}
|
||
|
||
function genCheckboxModel (
|
||
el,
|
||
value,
|
||
modifiers
|
||
) {
|
||
var number = modifiers && modifiers.number;
|
||
var valueBinding = getBindingAttr(el, 'value') || 'null';
|
||
var trueValueBinding = getBindingAttr(el, 'true-value') || 'true';
|
||
var falseValueBinding = getBindingAttr(el, 'false-value') || 'false';
|
||
addProp(el, 'checked',
|
||
"Array.isArray(" + value + ")" +
|
||
"?_i(" + value + "," + valueBinding + ")>-1" + (
|
||
trueValueBinding === 'true'
|
||
? (":(" + value + ")")
|
||
: (":_q(" + value + "," + trueValueBinding + ")")
|
||
)
|
||
);
|
||
addHandler(el, CHECKBOX_RADIO_TOKEN,
|
||
"var $$a=" + value + "," +
|
||
'$$el=$event.target,' +
|
||
"$$c=$$el.checked?(" + trueValueBinding + "):(" + falseValueBinding + ");" +
|
||
'if(Array.isArray($$a)){' +
|
||
"var $$v=" + (number ? '_n(' + valueBinding + ')' : valueBinding) + "," +
|
||
'$$i=_i($$a,$$v);' +
|
||
"if($$el.checked){$$i<0&&(" + value + "=$$a.concat([$$v]))}" +
|
||
"else{$$i>-1&&(" + value + "=$$a.slice(0,$$i).concat($$a.slice($$i+1)))}" +
|
||
"}else{" + (genAssignmentCode(value, '$$c')) + "}",
|
||
null, true
|
||
);
|
||
}
|
||
|
||
function genRadioModel (
|
||
el,
|
||
value,
|
||
modifiers
|
||
) {
|
||
var number = modifiers && modifiers.number;
|
||
var valueBinding = getBindingAttr(el, 'value') || 'null';
|
||
valueBinding = number ? ("_n(" + valueBinding + ")") : valueBinding;
|
||
addProp(el, 'checked', ("_q(" + value + "," + valueBinding + ")"));
|
||
addHandler(el, CHECKBOX_RADIO_TOKEN, genAssignmentCode(value, valueBinding), null, true);
|
||
}
|
||
|
||
function genSelect (
|
||
el,
|
||
value,
|
||
modifiers
|
||
) {
|
||
var number = modifiers && modifiers.number;
|
||
var selectedVal = "Array.prototype.filter" +
|
||
".call($event.target.options,function(o){return o.selected})" +
|
||
".map(function(o){var val = \"_value\" in o ? o._value : o.value;" +
|
||
"return " + (number ? '_n(val)' : 'val') + "})";
|
||
|
||
var assignment = '$event.target.multiple ? $$selectedVal : $$selectedVal[0]';
|
||
var code = "var $$selectedVal = " + selectedVal + ";";
|
||
code = code + " " + (genAssignmentCode(value, assignment));
|
||
addHandler(el, 'change', code, null, true);
|
||
}
|
||
|
||
function genDefaultModel (
|
||
el,
|
||
value,
|
||
modifiers
|
||
) {
|
||
var type = el.attrsMap.type;
|
||
var ref = modifiers || {};
|
||
var lazy = ref.lazy;
|
||
var number = ref.number;
|
||
var trim = ref.trim;
|
||
var needCompositionGuard = !lazy && type !== 'range';
|
||
var event = lazy
|
||
? 'change'
|
||
: type === 'range'
|
||
? RANGE_TOKEN
|
||
: 'input';
|
||
|
||
var valueExpression = '$event.target.value';
|
||
if (trim) {
|
||
valueExpression = "$event.target.value.trim()";
|
||
}
|
||
if (number) {
|
||
valueExpression = "_n(" + valueExpression + ")";
|
||
}
|
||
|
||
var code = genAssignmentCode(value, valueExpression);
|
||
if (needCompositionGuard) {
|
||
code = "if($event.target.composing)return;" + code;
|
||
}
|
||
|
||
addProp(el, 'value', ("(" + value + ")"));
|
||
addHandler(el, event, code, null, true);
|
||
if (trim || number) {
|
||
addHandler(el, 'blur', '$forceUpdate()');
|
||
}
|
||
}
|
||
|
||
/* */
|
||
|
||
// normalize v-model event tokens that can only be determined at runtime.
|
||
// it's important to place the event as the first in the array because
|
||
// the whole point is ensuring the v-model callback gets called before
|
||
// user-attached handlers.
|
||
function normalizeEvents (on) {
|
||
var event;
|
||
/* istanbul ignore if */
|
||
if (isDef(on[RANGE_TOKEN])) {
|
||
// IE input[type=range] only supports `change` event
|
||
event = isIE ? 'change' : 'input';
|
||
on[event] = [].concat(on[RANGE_TOKEN], on[event] || []);
|
||
delete on[RANGE_TOKEN];
|
||
}
|
||
if (isDef(on[CHECKBOX_RADIO_TOKEN])) {
|
||
// Chrome fires microtasks in between click/change, leads to #4521
|
||
event = isChrome ? 'click' : 'change';
|
||
on[event] = [].concat(on[CHECKBOX_RADIO_TOKEN], on[event] || []);
|
||
delete on[CHECKBOX_RADIO_TOKEN];
|
||
}
|
||
}
|
||
|
||
var target$1;
|
||
|
||
function add$1 (
|
||
event,
|
||
handler,
|
||
once$$1,
|
||
capture,
|
||
passive
|
||
) {
|
||
if (once$$1) {
|
||
var oldHandler = handler;
|
||
var _target = target$1; // save current target element in closure
|
||
handler = function (ev) {
|
||
var res = arguments.length === 1
|
||
? oldHandler(ev)
|
||
: oldHandler.apply(null, arguments);
|
||
if (res !== null) {
|
||
remove$2(event, handler, capture, _target);
|
||
}
|
||
};
|
||
}
|
||
target$1.addEventListener(
|
||
event,
|
||
handler,
|
||
supportsPassive
|
||
? { capture: capture, passive: passive }
|
||
: capture
|
||
);
|
||
}
|
||
|
||
function remove$2 (
|
||
event,
|
||
handler,
|
||
capture,
|
||
_target
|
||
) {
|
||
(_target || target$1).removeEventListener(event, handler, capture);
|
||
}
|
||
|
||
function updateDOMListeners (oldVnode, vnode) {
|
||
if (isUndef(oldVnode.data.on) && isUndef(vnode.data.on)) {
|
||
return
|
||
}
|
||
var on = vnode.data.on || {};
|
||
var oldOn = oldVnode.data.on || {};
|
||
target$1 = vnode.elm;
|
||
normalizeEvents(on);
|
||
updateListeners(on, oldOn, add$1, remove$2, vnode.context);
|
||
}
|
||
|
||
var events = {
|
||
create: updateDOMListeners,
|
||
update: updateDOMListeners
|
||
};
|
||
|
||
/* */
|
||
|
||
function updateDOMProps (oldVnode, vnode) {
|
||
if (isUndef(oldVnode.data.domProps) && isUndef(vnode.data.domProps)) {
|
||
return
|
||
}
|
||
var key, cur;
|
||
var elm = vnode.elm;
|
||
var oldProps = oldVnode.data.domProps || {};
|
||
var props = vnode.data.domProps || {};
|
||
// clone observed objects, as the user probably wants to mutate it
|
||
if (isDef(props.__ob__)) {
|
||
props = vnode.data.domProps = extend({}, props);
|
||
}
|
||
|
||
for (key in oldProps) {
|
||
if (isUndef(props[key])) {
|
||
elm[key] = '';
|
||
}
|
||
}
|
||
for (key in props) {
|
||
cur = props[key];
|
||
// ignore children if the node has textContent or innerHTML,
|
||
// as these will throw away existing DOM nodes and cause removal errors
|
||
// on subsequent patches (#3360)
|
||
if (key === 'textContent' || key === 'innerHTML') {
|
||
if (vnode.children) { vnode.children.length = 0; }
|
||
if (cur === oldProps[key]) { continue }
|
||
}
|
||
|
||
if (key === 'value') {
|
||
// store value as _value as well since
|
||
// non-string values will be stringified
|
||
elm._value = cur;
|
||
// avoid resetting cursor position when value is the same
|
||
var strCur = isUndef(cur) ? '' : String(cur);
|
||
if (shouldUpdateValue(elm, vnode, strCur)) {
|
||
elm.value = strCur;
|
||
}
|
||
} else {
|
||
elm[key] = cur;
|
||
}
|
||
}
|
||
}
|
||
|
||
// check platforms/web/util/attrs.js acceptValue
|
||
|
||
|
||
function shouldUpdateValue (
|
||
elm,
|
||
vnode,
|
||
checkVal
|
||
) {
|
||
return (!elm.composing && (
|
||
vnode.tag === 'option' ||
|
||
isDirty(elm, checkVal) ||
|
||
isInputChanged(elm, checkVal)
|
||
))
|
||
}
|
||
|
||
function isDirty (elm, checkVal) {
|
||
// return true when textbox (.number and .trim) loses focus and its value is
|
||
// not equal to the updated value
|
||
var notInFocus = true;
|
||
// #6157
|
||
// work around IE bug when accessing document.activeElement in an iframe
|
||
try { notInFocus = document.activeElement !== elm; } catch (e) {}
|
||
return notInFocus && elm.value !== checkVal
|
||
}
|
||
|
||
function isInputChanged (elm, newVal) {
|
||
var value = elm.value;
|
||
var modifiers = elm._vModifiers; // injected by v-model runtime
|
||
if (isDef(modifiers) && modifiers.number) {
|
||
return toNumber(value) !== toNumber(newVal)
|
||
}
|
||
if (isDef(modifiers) && modifiers.trim) {
|
||
return value.trim() !== newVal.trim()
|
||
}
|
||
return value !== newVal
|
||
}
|
||
|
||
var domProps = {
|
||
create: updateDOMProps,
|
||
update: updateDOMProps
|
||
};
|
||
|
||
/* */
|
||
|
||
var parseStyleText = cached(function (cssText) {
|
||
var res = {};
|
||
var listDelimiter = /;(?![^(]*\))/g;
|
||
var propertyDelimiter = /:(.+)/;
|
||
cssText.split(listDelimiter).forEach(function (item) {
|
||
if (item) {
|
||
var tmp = item.split(propertyDelimiter);
|
||
tmp.length > 1 && (res[tmp[0].trim()] = tmp[1].trim());
|
||
}
|
||
});
|
||
return res
|
||
});
|
||
|
||
// merge static and dynamic style data on the same vnode
|
||
function normalizeStyleData (data) {
|
||
var style = normalizeStyleBinding(data.style);
|
||
// static style is pre-processed into an object during compilation
|
||
// and is always a fresh object, so it's safe to merge into it
|
||
return data.staticStyle
|
||
? extend(data.staticStyle, style)
|
||
: style
|
||
}
|
||
|
||
// normalize possible array / string values into Object
|
||
function normalizeStyleBinding (bindingStyle) {
|
||
if (Array.isArray(bindingStyle)) {
|
||
return toObject(bindingStyle)
|
||
}
|
||
if (typeof bindingStyle === 'string') {
|
||
return parseStyleText(bindingStyle)
|
||
}
|
||
return bindingStyle
|
||
}
|
||
|
||
/**
|
||
* parent component style should be after child's
|
||
* so that parent component's style could override it
|
||
*/
|
||
function getStyle (vnode, checkChild) {
|
||
var res = {};
|
||
var styleData;
|
||
|
||
if (checkChild) {
|
||
var childNode = vnode;
|
||
while (childNode.componentInstance) {
|
||
childNode = childNode.componentInstance._vnode;
|
||
if (childNode.data && (styleData = normalizeStyleData(childNode.data))) {
|
||
extend(res, styleData);
|
||
}
|
||
}
|
||
}
|
||
|
||
if ((styleData = normalizeStyleData(vnode.data))) {
|
||
extend(res, styleData);
|
||
}
|
||
|
||
var parentNode = vnode;
|
||
while ((parentNode = parentNode.parent)) {
|
||
if (parentNode.data && (styleData = normalizeStyleData(parentNode.data))) {
|
||
extend(res, styleData);
|
||
}
|
||
}
|
||
return res
|
||
}
|
||
|
||
/* */
|
||
|
||
var cssVarRE = /^--/;
|
||
var importantRE = /\s*!important$/;
|
||
var setProp = function (el, name, val) {
|
||
/* istanbul ignore if */
|
||
if (cssVarRE.test(name)) {
|
||
el.style.setProperty(name, val);
|
||
} else if (importantRE.test(val)) {
|
||
el.style.setProperty(name, val.replace(importantRE, ''), 'important');
|
||
} else {
|
||
var normalizedName = normalize(name);
|
||
if (Array.isArray(val)) {
|
||
// Support values array created by autoprefixer, e.g.
|
||
// {display: ["-webkit-box", "-ms-flexbox", "flex"]}
|
||
// Set them one by one, and the browser will only set those it can recognize
|
||
for (var i = 0, len = val.length; i < len; i++) {
|
||
el.style[normalizedName] = val[i];
|
||
}
|
||
} else {
|
||
el.style[normalizedName] = val;
|
||
}
|
||
}
|
||
};
|
||
|
||
var vendorNames = ['Webkit', 'Moz', 'ms'];
|
||
|
||
var emptyStyle;
|
||
var normalize = cached(function (prop) {
|
||
emptyStyle = emptyStyle || document.createElement('div').style;
|
||
prop = camelize(prop);
|
||
if (prop !== 'filter' && (prop in emptyStyle)) {
|
||
return prop
|
||
}
|
||
var capName = prop.charAt(0).toUpperCase() + prop.slice(1);
|
||
for (var i = 0; i < vendorNames.length; i++) {
|
||
var name = vendorNames[i] + capName;
|
||
if (name in emptyStyle) {
|
||
return name
|
||
}
|
||
}
|
||
});
|
||
|
||
function updateStyle (oldVnode, vnode) {
|
||
var data = vnode.data;
|
||
var oldData = oldVnode.data;
|
||
|
||
if (isUndef(data.staticStyle) && isUndef(data.style) &&
|
||
isUndef(oldData.staticStyle) && isUndef(oldData.style)
|
||
) {
|
||
return
|
||
}
|
||
|
||
var cur, name;
|
||
var el = vnode.elm;
|
||
var oldStaticStyle = oldData.staticStyle;
|
||
var oldStyleBinding = oldData.normalizedStyle || oldData.style || {};
|
||
|
||
// if static style exists, stylebinding already merged into it when doing normalizeStyleData
|
||
var oldStyle = oldStaticStyle || oldStyleBinding;
|
||
|
||
var style = normalizeStyleBinding(vnode.data.style) || {};
|
||
|
||
// store normalized style under a different key for next diff
|
||
// make sure to clone it if it's reactive, since the user likely wants
|
||
// to mutate it.
|
||
vnode.data.normalizedStyle = isDef(style.__ob__)
|
||
? extend({}, style)
|
||
: style;
|
||
|
||
var newStyle = getStyle(vnode, true);
|
||
|
||
for (name in oldStyle) {
|
||
if (isUndef(newStyle[name])) {
|
||
setProp(el, name, '');
|
||
}
|
||
}
|
||
for (name in newStyle) {
|
||
cur = newStyle[name];
|
||
if (cur !== oldStyle[name]) {
|
||
// ie9 setting to null has no effect, must use empty string
|
||
setProp(el, name, cur == null ? '' : cur);
|
||
}
|
||
}
|
||
}
|
||
|
||
var style = {
|
||
create: updateStyle,
|
||
update: updateStyle
|
||
};
|
||
|
||
/* */
|
||
|
||
/**
|
||
* Add class with compatibility for SVG since classList is not supported on
|
||
* SVG elements in IE
|
||
*/
|
||
function addClass (el, cls) {
|
||
/* istanbul ignore if */
|
||
if (!cls || !(cls = cls.trim())) {
|
||
return
|
||
}
|
||
|
||
/* istanbul ignore else */
|
||
if (el.classList) {
|
||
if (cls.indexOf(' ') > -1) {
|
||
cls.split(/\s+/).forEach(function (c) { return el.classList.add(c); });
|
||
} else {
|
||
el.classList.add(cls);
|
||
}
|
||
} else {
|
||
var cur = " " + (el.getAttribute('class') || '') + " ";
|
||
if (cur.indexOf(' ' + cls + ' ') < 0) {
|
||
el.setAttribute('class', (cur + cls).trim());
|
||
}
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Remove class with compatibility for SVG since classList is not supported on
|
||
* SVG elements in IE
|
||
*/
|
||
function removeClass (el, cls) {
|
||
/* istanbul ignore if */
|
||
if (!cls || !(cls = cls.trim())) {
|
||
return
|
||
}
|
||
|
||
/* istanbul ignore else */
|
||
if (el.classList) {
|
||
if (cls.indexOf(' ') > -1) {
|
||
cls.split(/\s+/).forEach(function (c) { return el.classList.remove(c); });
|
||
} else {
|
||
el.classList.remove(cls);
|
||
}
|
||
if (!el.classList.length) {
|
||
el.removeAttribute('class');
|
||
}
|
||
} else {
|
||
var cur = " " + (el.getAttribute('class') || '') + " ";
|
||
var tar = ' ' + cls + ' ';
|
||
while (cur.indexOf(tar) >= 0) {
|
||
cur = cur.replace(tar, ' ');
|
||
}
|
||
cur = cur.trim();
|
||
if (cur) {
|
||
el.setAttribute('class', cur);
|
||
} else {
|
||
el.removeAttribute('class');
|
||
}
|
||
}
|
||
}
|
||
|
||
/* */
|
||
|
||
function resolveTransition (def$$1) {
|
||
if (!def$$1) {
|
||
return
|
||
}
|
||
/* istanbul ignore else */
|
||
if (typeof def$$1 === 'object') {
|
||
var res = {};
|
||
if (def$$1.css !== false) {
|
||
extend(res, autoCssTransition(def$$1.name || 'v'));
|
||
}
|
||
extend(res, def$$1);
|
||
return res
|
||
} else if (typeof def$$1 === 'string') {
|
||
return autoCssTransition(def$$1)
|
||
}
|
||
}
|
||
|
||
var autoCssTransition = cached(function (name) {
|
||
return {
|
||
enterClass: (name + "-enter"),
|
||
enterToClass: (name + "-enter-to"),
|
||
enterActiveClass: (name + "-enter-active"),
|
||
leaveClass: (name + "-leave"),
|
||
leaveToClass: (name + "-leave-to"),
|
||
leaveActiveClass: (name + "-leave-active")
|
||
}
|
||
});
|
||
|
||
var hasTransition = inBrowser && !isIE9;
|
||
var TRANSITION = 'transition';
|
||
var ANIMATION = 'animation';
|
||
|
||
// Transition property/event sniffing
|
||
var transitionProp = 'transition';
|
||
var transitionEndEvent = 'transitionend';
|
||
var animationProp = 'animation';
|
||
var animationEndEvent = 'animationend';
|
||
if (hasTransition) {
|
||
/* istanbul ignore if */
|
||
if (window.ontransitionend === undefined &&
|
||
window.onwebkittransitionend !== undefined
|
||
) {
|
||
transitionProp = 'WebkitTransition';
|
||
transitionEndEvent = 'webkitTransitionEnd';
|
||
}
|
||
if (window.onanimationend === undefined &&
|
||
window.onwebkitanimationend !== undefined
|
||
) {
|
||
animationProp = 'WebkitAnimation';
|
||
animationEndEvent = 'webkitAnimationEnd';
|
||
}
|
||
}
|
||
|
||
// binding to window is necessary to make hot reload work in IE in strict mode
|
||
var raf = inBrowser && window.requestAnimationFrame
|
||
? window.requestAnimationFrame.bind(window)
|
||
: setTimeout;
|
||
|
||
function nextFrame (fn) {
|
||
raf(function () {
|
||
raf(fn);
|
||
});
|
||
}
|
||
|
||
function addTransitionClass (el, cls) {
|
||
var transitionClasses = el._transitionClasses || (el._transitionClasses = []);
|
||
if (transitionClasses.indexOf(cls) < 0) {
|
||
transitionClasses.push(cls);
|
||
addClass(el, cls);
|
||
}
|
||
}
|
||
|
||
function removeTransitionClass (el, cls) {
|
||
if (el._transitionClasses) {
|
||
remove(el._transitionClasses, cls);
|
||
}
|
||
removeClass(el, cls);
|
||
}
|
||
|
||
function whenTransitionEnds (
|
||
el,
|
||
expectedType,
|
||
cb
|
||
) {
|
||
var ref = getTransitionInfo(el, expectedType);
|
||
var type = ref.type;
|
||
var timeout = ref.timeout;
|
||
var propCount = ref.propCount;
|
||
if (!type) { return cb() }
|
||
var event = type === TRANSITION ? transitionEndEvent : animationEndEvent;
|
||
var ended = 0;
|
||
var end = function () {
|
||
el.removeEventListener(event, onEnd);
|
||
cb();
|
||
};
|
||
var onEnd = function (e) {
|
||
if (e.target === el) {
|
||
if (++ended >= propCount) {
|
||
end();
|
||
}
|
||
}
|
||
};
|
||
setTimeout(function () {
|
||
if (ended < propCount) {
|
||
end();
|
||
}
|
||
}, timeout + 1);
|
||
el.addEventListener(event, onEnd);
|
||
}
|
||
|
||
var transformRE = /\b(transform|all)(,|$)/;
|
||
|
||
function getTransitionInfo (el, expectedType) {
|
||
var styles = window.getComputedStyle(el);
|
||
var transitionDelays = styles[transitionProp + 'Delay'].split(', ');
|
||
var transitionDurations = styles[transitionProp + 'Duration'].split(', ');
|
||
var transitionTimeout = getTimeout(transitionDelays, transitionDurations);
|
||
var animationDelays = styles[animationProp + 'Delay'].split(', ');
|
||
var animationDurations = styles[animationProp + 'Duration'].split(', ');
|
||
var animationTimeout = getTimeout(animationDelays, animationDurations);
|
||
|
||
var type;
|
||
var timeout = 0;
|
||
var propCount = 0;
|
||
/* istanbul ignore if */
|
||
if (expectedType === TRANSITION) {
|
||
if (transitionTimeout > 0) {
|
||
type = TRANSITION;
|
||
timeout = transitionTimeout;
|
||
propCount = transitionDurations.length;
|
||
}
|
||
} else if (expectedType === ANIMATION) {
|
||
if (animationTimeout > 0) {
|
||
type = ANIMATION;
|
||
timeout = animationTimeout;
|
||
propCount = animationDurations.length;
|
||
}
|
||
} else {
|
||
timeout = Math.max(transitionTimeout, animationTimeout);
|
||
type = timeout > 0
|
||
? transitionTimeout > animationTimeout
|
||
? TRANSITION
|
||
: ANIMATION
|
||
: null;
|
||
propCount = type
|
||
? type === TRANSITION
|
||
? transitionDurations.length
|
||
: animationDurations.length
|
||
: 0;
|
||
}
|
||
var hasTransform =
|
||
type === TRANSITION &&
|
||
transformRE.test(styles[transitionProp + 'Property']);
|
||
return {
|
||
type: type,
|
||
timeout: timeout,
|
||
propCount: propCount,
|
||
hasTransform: hasTransform
|
||
}
|
||
}
|
||
|
||
function getTimeout (delays, durations) {
|
||
/* istanbul ignore next */
|
||
while (delays.length < durations.length) {
|
||
delays = delays.concat(delays);
|
||
}
|
||
|
||
return Math.max.apply(null, durations.map(function (d, i) {
|
||
return toMs(d) + toMs(delays[i])
|
||
}))
|
||
}
|
||
|
||
function toMs (s) {
|
||
return Number(s.slice(0, -1)) * 1000
|
||
}
|
||
|
||
/* */
|
||
|
||
function enter (vnode, toggleDisplay) {
|
||
var el = vnode.elm;
|
||
|
||
// call leave callback now
|
||
if (isDef(el._leaveCb)) {
|
||
el._leaveCb.cancelled = true;
|
||
el._leaveCb();
|
||
}
|
||
|
||
var data = resolveTransition(vnode.data.transition);
|
||
if (isUndef(data)) {
|
||
return
|
||
}
|
||
|
||
/* istanbul ignore if */
|
||
if (isDef(el._enterCb) || el.nodeType !== 1) {
|
||
return
|
||
}
|
||
|
||
var css = data.css;
|
||
var type = data.type;
|
||
var enterClass = data.enterClass;
|
||
var enterToClass = data.enterToClass;
|
||
var enterActiveClass = data.enterActiveClass;
|
||
var appearClass = data.appearClass;
|
||
var appearToClass = data.appearToClass;
|
||
var appearActiveClass = data.appearActiveClass;
|
||
var beforeEnter = data.beforeEnter;
|
||
var enter = data.enter;
|
||
var afterEnter = data.afterEnter;
|
||
var enterCancelled = data.enterCancelled;
|
||
var beforeAppear = data.beforeAppear;
|
||
var appear = data.appear;
|
||
var afterAppear = data.afterAppear;
|
||
var appearCancelled = data.appearCancelled;
|
||
var duration = data.duration;
|
||
|
||
// activeInstance will always be the <transition> component managing this
|
||
// transition. One edge case to check is when the <transition> is placed
|
||
// as the root node of a child component. In that case we need to check
|
||
// <transition>'s parent for appear check.
|
||
var context = activeInstance;
|
||
var transitionNode = activeInstance.$vnode;
|
||
while (transitionNode && transitionNode.parent) {
|
||
transitionNode = transitionNode.parent;
|
||
context = transitionNode.context;
|
||
}
|
||
|
||
var isAppear = !context._isMounted || !vnode.isRootInsert;
|
||
|
||
if (isAppear && !appear && appear !== '') {
|
||
return
|
||
}
|
||
|
||
var startClass = isAppear && appearClass
|
||
? appearClass
|
||
: enterClass;
|
||
var activeClass = isAppear && appearActiveClass
|
||
? appearActiveClass
|
||
: enterActiveClass;
|
||
var toClass = isAppear && appearToClass
|
||
? appearToClass
|
||
: enterToClass;
|
||
|
||
var beforeEnterHook = isAppear
|
||
? (beforeAppear || beforeEnter)
|
||
: beforeEnter;
|
||
var enterHook = isAppear
|
||
? (typeof appear === 'function' ? appear : enter)
|
||
: enter;
|
||
var afterEnterHook = isAppear
|
||
? (afterAppear || afterEnter)
|
||
: afterEnter;
|
||
var enterCancelledHook = isAppear
|
||
? (appearCancelled || enterCancelled)
|
||
: enterCancelled;
|
||
|
||
var explicitEnterDuration = toNumber(
|
||
isObject(duration)
|
||
? duration.enter
|
||
: duration
|
||
);
|
||
|
||
if ("development" !== 'production' && explicitEnterDuration != null) {
|
||
checkDuration(explicitEnterDuration, 'enter', vnode);
|
||
}
|
||
|
||
var expectsCSS = css !== false && !isIE9;
|
||
var userWantsControl = getHookArgumentsLength(enterHook);
|
||
|
||
var cb = el._enterCb = once(function () {
|
||
if (expectsCSS) {
|
||
removeTransitionClass(el, toClass);
|
||
removeTransitionClass(el, activeClass);
|
||
}
|
||
if (cb.cancelled) {
|
||
if (expectsCSS) {
|
||
removeTransitionClass(el, startClass);
|
||
}
|
||
enterCancelledHook && enterCancelledHook(el);
|
||
} else {
|
||
afterEnterHook && afterEnterHook(el);
|
||
}
|
||
el._enterCb = null;
|
||
});
|
||
|
||
if (!vnode.data.show) {
|
||
// remove pending leave element on enter by injecting an insert hook
|
||
mergeVNodeHook(vnode.data.hook || (vnode.data.hook = {}), 'insert', function () {
|
||
var parent = el.parentNode;
|
||
var pendingNode = parent && parent._pending && parent._pending[vnode.key];
|
||
if (pendingNode &&
|
||
pendingNode.tag === vnode.tag &&
|
||
pendingNode.elm._leaveCb
|
||
) {
|
||
pendingNode.elm._leaveCb();
|
||
}
|
||
enterHook && enterHook(el, cb);
|
||
});
|
||
}
|
||
|
||
// start enter transition
|
||
beforeEnterHook && beforeEnterHook(el);
|
||
if (expectsCSS) {
|
||
addTransitionClass(el, startClass);
|
||
addTransitionClass(el, activeClass);
|
||
nextFrame(function () {
|
||
addTransitionClass(el, toClass);
|
||
removeTransitionClass(el, startClass);
|
||
if (!cb.cancelled && !userWantsControl) {
|
||
if (isValidDuration(explicitEnterDuration)) {
|
||
setTimeout(cb, explicitEnterDuration);
|
||
} else {
|
||
whenTransitionEnds(el, type, cb);
|
||
}
|
||
}
|
||
});
|
||
}
|
||
|
||
if (vnode.data.show) {
|
||
toggleDisplay && toggleDisplay();
|
||
enterHook && enterHook(el, cb);
|
||
}
|
||
|
||
if (!expectsCSS && !userWantsControl) {
|
||
cb();
|
||
}
|
||
}
|
||
|
||
function leave (vnode, rm) {
|
||
var el = vnode.elm;
|
||
|
||
// call enter callback now
|
||
if (isDef(el._enterCb)) {
|
||
el._enterCb.cancelled = true;
|
||
el._enterCb();
|
||
}
|
||
|
||
var data = resolveTransition(vnode.data.transition);
|
||
if (isUndef(data)) {
|
||
return rm()
|
||
}
|
||
|
||
/* istanbul ignore if */
|
||
if (isDef(el._leaveCb) || el.nodeType !== 1) {
|
||
return
|
||
}
|
||
|
||
var css = data.css;
|
||
var type = data.type;
|
||
var leaveClass = data.leaveClass;
|
||
var leaveToClass = data.leaveToClass;
|
||
var leaveActiveClass = data.leaveActiveClass;
|
||
var beforeLeave = data.beforeLeave;
|
||
var leave = data.leave;
|
||
var afterLeave = data.afterLeave;
|
||
var leaveCancelled = data.leaveCancelled;
|
||
var delayLeave = data.delayLeave;
|
||
var duration = data.duration;
|
||
|
||
var expectsCSS = css !== false && !isIE9;
|
||
var userWantsControl = getHookArgumentsLength(leave);
|
||
|
||
var explicitLeaveDuration = toNumber(
|
||
isObject(duration)
|
||
? duration.leave
|
||
: duration
|
||
);
|
||
|
||
if ("development" !== 'production' && isDef(explicitLeaveDuration)) {
|
||
checkDuration(explicitLeaveDuration, 'leave', vnode);
|
||
}
|
||
|
||
var cb = el._leaveCb = once(function () {
|
||
if (el.parentNode && el.parentNode._pending) {
|
||
el.parentNode._pending[vnode.key] = null;
|
||
}
|
||
if (expectsCSS) {
|
||
removeTransitionClass(el, leaveToClass);
|
||
removeTransitionClass(el, leaveActiveClass);
|
||
}
|
||
if (cb.cancelled) {
|
||
if (expectsCSS) {
|
||
removeTransitionClass(el, leaveClass);
|
||
}
|
||
leaveCancelled && leaveCancelled(el);
|
||
} else {
|
||
rm();
|
||
afterLeave && afterLeave(el);
|
||
}
|
||
el._leaveCb = null;
|
||
});
|
||
|
||
if (delayLeave) {
|
||
delayLeave(performLeave);
|
||
} else {
|
||
performLeave();
|
||
}
|
||
|
||
function performLeave () {
|
||
// the delayed leave may have already been cancelled
|
||
if (cb.cancelled) {
|
||
return
|
||
}
|
||
// record leaving element
|
||
if (!vnode.data.show) {
|
||
(el.parentNode._pending || (el.parentNode._pending = {}))[(vnode.key)] = vnode;
|
||
}
|
||
beforeLeave && beforeLeave(el);
|
||
if (expectsCSS) {
|
||
addTransitionClass(el, leaveClass);
|
||
addTransitionClass(el, leaveActiveClass);
|
||
nextFrame(function () {
|
||
addTransitionClass(el, leaveToClass);
|
||
removeTransitionClass(el, leaveClass);
|
||
if (!cb.cancelled && !userWantsControl) {
|
||
if (isValidDuration(explicitLeaveDuration)) {
|
||
setTimeout(cb, explicitLeaveDuration);
|
||
} else {
|
||
whenTransitionEnds(el, type, cb);
|
||
}
|
||
}
|
||
});
|
||
}
|
||
leave && leave(el, cb);
|
||
if (!expectsCSS && !userWantsControl) {
|
||
cb();
|
||
}
|
||
}
|
||
}
|
||
|
||
// only used in dev mode
|
||
function checkDuration (val, name, vnode) {
|
||
if (typeof val !== 'number') {
|
||
warn(
|
||
"<transition> explicit " + name + " duration is not a valid number - " +
|
||
"got " + (JSON.stringify(val)) + ".",
|
||
vnode.context
|
||
);
|
||
} else if (isNaN(val)) {
|
||
warn(
|
||
"<transition> explicit " + name + " duration is NaN - " +
|
||
'the duration expression might be incorrect.',
|
||
vnode.context
|
||
);
|
||
}
|
||
}
|
||
|
||
function isValidDuration (val) {
|
||
return typeof val === 'number' && !isNaN(val)
|
||
}
|
||
|
||
/**
|
||
* Normalize a transition hook's argument length. The hook may be:
|
||
* - a merged hook (invoker) with the original in .fns
|
||
* - a wrapped component method (check ._length)
|
||
* - a plain function (.length)
|
||
*/
|
||
function getHookArgumentsLength (fn) {
|
||
if (isUndef(fn)) {
|
||
return false
|
||
}
|
||
var invokerFns = fn.fns;
|
||
if (isDef(invokerFns)) {
|
||
// invoker
|
||
return getHookArgumentsLength(
|
||
Array.isArray(invokerFns)
|
||
? invokerFns[0]
|
||
: invokerFns
|
||
)
|
||
} else {
|
||
return (fn._length || fn.length) > 1
|
||
}
|
||
}
|
||
|
||
function _enter (_, vnode) {
|
||
if (vnode.data.show !== true) {
|
||
enter(vnode);
|
||
}
|
||
}
|
||
|
||
var transition = inBrowser ? {
|
||
create: _enter,
|
||
activate: _enter,
|
||
remove: function remove$$1 (vnode, rm) {
|
||
/* istanbul ignore else */
|
||
if (vnode.data.show !== true) {
|
||
leave(vnode, rm);
|
||
} else {
|
||
rm();
|
||
}
|
||
}
|
||
} : {};
|
||
|
||
var platformModules = [
|
||
attrs,
|
||
klass,
|
||
events,
|
||
domProps,
|
||
style,
|
||
transition
|
||
];
|
||
|
||
/* */
|
||
|
||
// the directive module should be applied last, after all
|
||
// built-in modules have been applied.
|
||
var modules = platformModules.concat(baseModules);
|
||
|
||
var patch = createPatchFunction({ nodeOps: nodeOps, modules: modules });
|
||
|
||
/**
|
||
* Not type checking this file because flow doesn't like attaching
|
||
* properties to Elements.
|
||
*/
|
||
|
||
/* istanbul ignore if */
|
||
if (isIE9) {
|
||
// http://www.matts411.com/post/internet-explorer-9-oninput/
|
||
document.addEventListener('selectionchange', function () {
|
||
var el = document.activeElement;
|
||
if (el && el.vmodel) {
|
||
trigger(el, 'input');
|
||
}
|
||
});
|
||
}
|
||
|
||
var model$1 = {
|
||
inserted: function inserted (el, binding, vnode) {
|
||
if (vnode.tag === 'select') {
|
||
setSelected(el, binding, vnode.context);
|
||
el._vOptions = [].map.call(el.options, getValue);
|
||
} else if (vnode.tag === 'textarea' || isTextInputType(el.type)) {
|
||
el._vModifiers = binding.modifiers;
|
||
if (!binding.modifiers.lazy) {
|
||
// Safari < 10.2 & UIWebView doesn't fire compositionend when
|
||
// switching focus before confirming composition choice
|
||
// this also fixes the issue where some browsers e.g. iOS Chrome
|
||
// fires "change" instead of "input" on autocomplete.
|
||
el.addEventListener('change', onCompositionEnd);
|
||
if (!isAndroid) {
|
||
el.addEventListener('compositionstart', onCompositionStart);
|
||
el.addEventListener('compositionend', onCompositionEnd);
|
||
}
|
||
/* istanbul ignore if */
|
||
if (isIE9) {
|
||
el.vmodel = true;
|
||
}
|
||
}
|
||
}
|
||
},
|
||
componentUpdated: function componentUpdated (el, binding, vnode) {
|
||
if (vnode.tag === 'select') {
|
||
setSelected(el, binding, vnode.context);
|
||
// in case the options rendered by v-for have changed,
|
||
// it's possible that the value is out-of-sync with the rendered options.
|
||
// detect such cases and filter out values that no longer has a matching
|
||
// option in the DOM.
|
||
var prevOptions = el._vOptions;
|
||
var curOptions = el._vOptions = [].map.call(el.options, getValue);
|
||
if (curOptions.some(function (o, i) { return !looseEqual(o, prevOptions[i]); })) {
|
||
// trigger change event if
|
||
// no matching option found for at least one value
|
||
var needReset = el.multiple
|
||
? binding.value.some(function (v) { return hasNoMatchingOption(v, curOptions); })
|
||
: binding.value !== binding.oldValue && hasNoMatchingOption(binding.value, curOptions);
|
||
if (needReset) {
|
||
trigger(el, 'change');
|
||
}
|
||
}
|
||
}
|
||
}
|
||
};
|
||
|
||
function setSelected (el, binding, vm) {
|
||
actuallySetSelected(el, binding, vm);
|
||
/* istanbul ignore if */
|
||
if (isIE || isEdge) {
|
||
setTimeout(function () {
|
||
actuallySetSelected(el, binding, vm);
|
||
}, 0);
|
||
}
|
||
}
|
||
|
||
function actuallySetSelected (el, binding, vm) {
|
||
var value = binding.value;
|
||
var isMultiple = el.multiple;
|
||
if (isMultiple && !Array.isArray(value)) {
|
||
"development" !== 'production' && warn(
|
||
"<select multiple v-model=\"" + (binding.expression) + "\"> " +
|
||
"expects an Array value for its binding, but got " + (Object.prototype.toString.call(value).slice(8, -1)),
|
||
vm
|
||
);
|
||
return
|
||
}
|
||
var selected, option;
|
||
for (var i = 0, l = el.options.length; i < l; i++) {
|
||
option = el.options[i];
|
||
if (isMultiple) {
|
||
selected = looseIndexOf(value, getValue(option)) > -1;
|
||
if (option.selected !== selected) {
|
||
option.selected = selected;
|
||
}
|
||
} else {
|
||
if (looseEqual(getValue(option), value)) {
|
||
if (el.selectedIndex !== i) {
|
||
el.selectedIndex = i;
|
||
}
|
||
return
|
||
}
|
||
}
|
||
}
|
||
if (!isMultiple) {
|
||
el.selectedIndex = -1;
|
||
}
|
||
}
|
||
|
||
function hasNoMatchingOption (value, options) {
|
||
return options.every(function (o) { return !looseEqual(o, value); })
|
||
}
|
||
|
||
function getValue (option) {
|
||
return '_value' in option
|
||
? option._value
|
||
: option.value
|
||
}
|
||
|
||
function onCompositionStart (e) {
|
||
e.target.composing = true;
|
||
}
|
||
|
||
function onCompositionEnd (e) {
|
||
// prevent triggering an input event for no reason
|
||
if (!e.target.composing) { return }
|
||
e.target.composing = false;
|
||
trigger(e.target, 'input');
|
||
}
|
||
|
||
function trigger (el, type) {
|
||
var e = document.createEvent('HTMLEvents');
|
||
e.initEvent(type, true, true);
|
||
el.dispatchEvent(e);
|
||
}
|
||
|
||
/* */
|
||
|
||
// recursively search for possible transition defined inside the component root
|
||
function locateNode (vnode) {
|
||
return vnode.componentInstance && (!vnode.data || !vnode.data.transition)
|
||
? locateNode(vnode.componentInstance._vnode)
|
||
: vnode
|
||
}
|
||
|
||
var show = {
|
||
bind: function bind (el, ref, vnode) {
|
||
var value = ref.value;
|
||
|
||
vnode = locateNode(vnode);
|
||
var transition$$1 = vnode.data && vnode.data.transition;
|
||
var originalDisplay = el.__vOriginalDisplay =
|
||
el.style.display === 'none' ? '' : el.style.display;
|
||
if (value && transition$$1) {
|
||
vnode.data.show = true;
|
||
enter(vnode, function () {
|
||
el.style.display = originalDisplay;
|
||
});
|
||
} else {
|
||
el.style.display = value ? originalDisplay : 'none';
|
||
}
|
||
},
|
||
|
||
update: function update (el, ref, vnode) {
|
||
var value = ref.value;
|
||
var oldValue = ref.oldValue;
|
||
|
||
/* istanbul ignore if */
|
||
if (value === oldValue) { return }
|
||
vnode = locateNode(vnode);
|
||
var transition$$1 = vnode.data && vnode.data.transition;
|
||
if (transition$$1) {
|
||
vnode.data.show = true;
|
||
if (value) {
|
||
enter(vnode, function () {
|
||
el.style.display = el.__vOriginalDisplay;
|
||
});
|
||
} else {
|
||
leave(vnode, function () {
|
||
el.style.display = 'none';
|
||
});
|
||
}
|
||
} else {
|
||
el.style.display = value ? el.__vOriginalDisplay : 'none';
|
||
}
|
||
},
|
||
|
||
unbind: function unbind (
|
||
el,
|
||
binding,
|
||
vnode,
|
||
oldVnode,
|
||
isDestroy
|
||
) {
|
||
if (!isDestroy) {
|
||
el.style.display = el.__vOriginalDisplay;
|
||
}
|
||
}
|
||
};
|
||
|
||
var platformDirectives = {
|
||
model: model$1,
|
||
show: show
|
||
};
|
||
|
||
/* */
|
||
|
||
// Provides transition support for a single element/component.
|
||
// supports transition mode (out-in / in-out)
|
||
|
||
var transitionProps = {
|
||
name: String,
|
||
appear: Boolean,
|
||
css: Boolean,
|
||
mode: String,
|
||
type: String,
|
||
enterClass: String,
|
||
leaveClass: String,
|
||
enterToClass: String,
|
||
leaveToClass: String,
|
||
enterActiveClass: String,
|
||
leaveActiveClass: String,
|
||
appearClass: String,
|
||
appearActiveClass: String,
|
||
appearToClass: String,
|
||
duration: [Number, String, Object]
|
||
};
|
||
|
||
// in case the child is also an abstract component, e.g. <keep-alive>
|
||
// we want to recursively retrieve the real component to be rendered
|
||
function getRealChild (vnode) {
|
||
var compOptions = vnode && vnode.componentOptions;
|
||
if (compOptions && compOptions.Ctor.options.abstract) {
|
||
return getRealChild(getFirstComponentChild(compOptions.children))
|
||
} else {
|
||
return vnode
|
||
}
|
||
}
|
||
|
||
function extractTransitionData (comp) {
|
||
var data = {};
|
||
var options = comp.$options;
|
||
// props
|
||
for (var key in options.propsData) {
|
||
data[key] = comp[key];
|
||
}
|
||
// events.
|
||
// extract listeners and pass them directly to the transition methods
|
||
var listeners = options._parentListeners;
|
||
for (var key$1 in listeners) {
|
||
data[camelize(key$1)] = listeners[key$1];
|
||
}
|
||
return data
|
||
}
|
||
|
||
function placeholder (h, rawChild) {
|
||
if (/\d-keep-alive$/.test(rawChild.tag)) {
|
||
return h('keep-alive', {
|
||
props: rawChild.componentOptions.propsData
|
||
})
|
||
}
|
||
}
|
||
|
||
function hasParentTransition (vnode) {
|
||
while ((vnode = vnode.parent)) {
|
||
if (vnode.data.transition) {
|
||
return true
|
||
}
|
||
}
|
||
}
|
||
|
||
function isSameChild (child, oldChild) {
|
||
return oldChild.key === child.key && oldChild.tag === child.tag
|
||
}
|
||
|
||
var Transition = {
|
||
name: 'transition',
|
||
props: transitionProps,
|
||
abstract: true,
|
||
|
||
render: function render (h) {
|
||
var this$1 = this;
|
||
|
||
var children = this.$options._renderChildren;
|
||
if (!children) {
|
||
return
|
||
}
|
||
|
||
// filter out text nodes (possible whitespaces)
|
||
children = children.filter(function (c) { return c.tag || isAsyncPlaceholder(c); });
|
||
/* istanbul ignore if */
|
||
if (!children.length) {
|
||
return
|
||
}
|
||
|
||
// warn multiple elements
|
||
if ("development" !== 'production' && children.length > 1) {
|
||
warn(
|
||
'<transition> can only be used on a single element. Use ' +
|
||
'<transition-group> for lists.',
|
||
this.$parent
|
||
);
|
||
}
|
||
|
||
var mode = this.mode;
|
||
|
||
// warn invalid mode
|
||
if ("development" !== 'production' &&
|
||
mode && mode !== 'in-out' && mode !== 'out-in'
|
||
) {
|
||
warn(
|
||
'invalid <transition> mode: ' + mode,
|
||
this.$parent
|
||
);
|
||
}
|
||
|
||
var rawChild = children[0];
|
||
|
||
// if this is a component root node and the component's
|
||
// parent container node also has transition, skip.
|
||
if (hasParentTransition(this.$vnode)) {
|
||
return rawChild
|
||
}
|
||
|
||
// apply transition data to child
|
||
// use getRealChild() to ignore abstract components e.g. keep-alive
|
||
var child = getRealChild(rawChild);
|
||
/* istanbul ignore if */
|
||
if (!child) {
|
||
return rawChild
|
||
}
|
||
|
||
if (this._leaving) {
|
||
return placeholder(h, rawChild)
|
||
}
|
||
|
||
// ensure a key that is unique to the vnode type and to this transition
|
||
// component instance. This key will be used to remove pending leaving nodes
|
||
// during entering.
|
||
var id = "__transition-" + (this._uid) + "-";
|
||
child.key = child.key == null
|
||
? child.isComment
|
||
? id + 'comment'
|
||
: id + child.tag
|
||
: isPrimitive(child.key)
|
||
? (String(child.key).indexOf(id) === 0 ? child.key : id + child.key)
|
||
: child.key;
|
||
|
||
var data = (child.data || (child.data = {})).transition = extractTransitionData(this);
|
||
var oldRawChild = this._vnode;
|
||
var oldChild = getRealChild(oldRawChild);
|
||
|
||
// mark v-show
|
||
// so that the transition module can hand over the control to the directive
|
||
if (child.data.directives && child.data.directives.some(function (d) { return d.name === 'show'; })) {
|
||
child.data.show = true;
|
||
}
|
||
|
||
if (
|
||
oldChild &&
|
||
oldChild.data &&
|
||
!isSameChild(child, oldChild) &&
|
||
!isAsyncPlaceholder(oldChild)
|
||
) {
|
||
// replace old child transition data with fresh one
|
||
// important for dynamic transitions!
|
||
var oldData = oldChild && (oldChild.data.transition = extend({}, data));
|
||
// handle transition mode
|
||
if (mode === 'out-in') {
|
||
// return placeholder node and queue update when leave finishes
|
||
this._leaving = true;
|
||
mergeVNodeHook(oldData, 'afterLeave', function () {
|
||
this$1._leaving = false;
|
||
this$1.$forceUpdate();
|
||
});
|
||
return placeholder(h, rawChild)
|
||
} else if (mode === 'in-out') {
|
||
if (isAsyncPlaceholder(child)) {
|
||
return oldRawChild
|
||
}
|
||
var delayedLeave;
|
||
var performLeave = function () { delayedLeave(); };
|
||
mergeVNodeHook(data, 'afterEnter', performLeave);
|
||
mergeVNodeHook(data, 'enterCancelled', performLeave);
|
||
mergeVNodeHook(oldData, 'delayLeave', function (leave) { delayedLeave = leave; });
|
||
}
|
||
}
|
||
|
||
return rawChild
|
||
}
|
||
};
|
||
|
||
/* */
|
||
|
||
// Provides transition support for list items.
|
||
// supports move transitions using the FLIP technique.
|
||
|
||
// Because the vdom's children update algorithm is "unstable" - i.e.
|
||
// it doesn't guarantee the relative positioning of removed elements,
|
||
// we force transition-group to update its children into two passes:
|
||
// in the first pass, we remove all nodes that need to be removed,
|
||
// triggering their leaving transition; in the second pass, we insert/move
|
||
// into the final desired state. This way in the second pass removed
|
||
// nodes will remain where they should be.
|
||
|
||
var props = extend({
|
||
tag: String,
|
||
moveClass: String
|
||
}, transitionProps);
|
||
|
||
delete props.mode;
|
||
|
||
var TransitionGroup = {
|
||
props: props,
|
||
|
||
render: function render (h) {
|
||
var tag = this.tag || this.$vnode.data.tag || 'span';
|
||
var map = Object.create(null);
|
||
var prevChildren = this.prevChildren = this.children;
|
||
var rawChildren = this.$slots.default || [];
|
||
var children = this.children = [];
|
||
var transitionData = extractTransitionData(this);
|
||
|
||
for (var i = 0; i < rawChildren.length; i++) {
|
||
var c = rawChildren[i];
|
||
if (c.tag) {
|
||
if (c.key != null && String(c.key).indexOf('__vlist') !== 0) {
|
||
children.push(c);
|
||
map[c.key] = c
|
||
;(c.data || (c.data = {})).transition = transitionData;
|
||
} else if (true) {
|
||
var opts = c.componentOptions;
|
||
var name = opts ? (opts.Ctor.options.name || opts.tag || '') : c.tag;
|
||
warn(("<transition-group> children must be keyed: <" + name + ">"));
|
||
}
|
||
}
|
||
}
|
||
|
||
if (prevChildren) {
|
||
var kept = [];
|
||
var removed = [];
|
||
for (var i$1 = 0; i$1 < prevChildren.length; i$1++) {
|
||
var c$1 = prevChildren[i$1];
|
||
c$1.data.transition = transitionData;
|
||
c$1.data.pos = c$1.elm.getBoundingClientRect();
|
||
if (map[c$1.key]) {
|
||
kept.push(c$1);
|
||
} else {
|
||
removed.push(c$1);
|
||
}
|
||
}
|
||
this.kept = h(tag, null, kept);
|
||
this.removed = removed;
|
||
}
|
||
|
||
return h(tag, null, children)
|
||
},
|
||
|
||
beforeUpdate: function beforeUpdate () {
|
||
// force removing pass
|
||
this.__patch__(
|
||
this._vnode,
|
||
this.kept,
|
||
false, // hydrating
|
||
true // removeOnly (!important, avoids unnecessary moves)
|
||
);
|
||
this._vnode = this.kept;
|
||
},
|
||
|
||
updated: function updated () {
|
||
var children = this.prevChildren;
|
||
var moveClass = this.moveClass || ((this.name || 'v') + '-move');
|
||
if (!children.length || !this.hasMove(children[0].elm, moveClass)) {
|
||
return
|
||
}
|
||
|
||
// we divide the work into three loops to avoid mixing DOM reads and writes
|
||
// in each iteration - which helps prevent layout thrashing.
|
||
children.forEach(callPendingCbs);
|
||
children.forEach(recordPosition);
|
||
children.forEach(applyTranslation);
|
||
|
||
// force reflow to put everything in position
|
||
var body = document.body;
|
||
var f = body.offsetHeight; // eslint-disable-line
|
||
|
||
children.forEach(function (c) {
|
||
if (c.data.moved) {
|
||
var el = c.elm;
|
||
var s = el.style;
|
||
addTransitionClass(el, moveClass);
|
||
s.transform = s.WebkitTransform = s.transitionDuration = '';
|
||
el.addEventListener(transitionEndEvent, el._moveCb = function cb (e) {
|
||
if (!e || /transform$/.test(e.propertyName)) {
|
||
el.removeEventListener(transitionEndEvent, cb);
|
||
el._moveCb = null;
|
||
removeTransitionClass(el, moveClass);
|
||
}
|
||
});
|
||
}
|
||
});
|
||
},
|
||
|
||
methods: {
|
||
hasMove: function hasMove (el, moveClass) {
|
||
/* istanbul ignore if */
|
||
if (!hasTransition) {
|
||
return false
|
||
}
|
||
/* istanbul ignore if */
|
||
if (this._hasMove) {
|
||
return this._hasMove
|
||
}
|
||
// Detect whether an element with the move class applied has
|
||
// CSS transitions. Since the element may be inside an entering
|
||
// transition at this very moment, we make a clone of it and remove
|
||
// all other transition classes applied to ensure only the move class
|
||
// is applied.
|
||
var clone = el.cloneNode();
|
||
if (el._transitionClasses) {
|
||
el._transitionClasses.forEach(function (cls) { removeClass(clone, cls); });
|
||
}
|
||
addClass(clone, moveClass);
|
||
clone.style.display = 'none';
|
||
this.$el.appendChild(clone);
|
||
var info = getTransitionInfo(clone);
|
||
this.$el.removeChild(clone);
|
||
return (this._hasMove = info.hasTransform)
|
||
}
|
||
}
|
||
};
|
||
|
||
function callPendingCbs (c) {
|
||
/* istanbul ignore if */
|
||
if (c.elm._moveCb) {
|
||
c.elm._moveCb();
|
||
}
|
||
/* istanbul ignore if */
|
||
if (c.elm._enterCb) {
|
||
c.elm._enterCb();
|
||
}
|
||
}
|
||
|
||
function recordPosition (c) {
|
||
c.data.newPos = c.elm.getBoundingClientRect();
|
||
}
|
||
|
||
function applyTranslation (c) {
|
||
var oldPos = c.data.pos;
|
||
var newPos = c.data.newPos;
|
||
var dx = oldPos.left - newPos.left;
|
||
var dy = oldPos.top - newPos.top;
|
||
if (dx || dy) {
|
||
c.data.moved = true;
|
||
var s = c.elm.style;
|
||
s.transform = s.WebkitTransform = "translate(" + dx + "px," + dy + "px)";
|
||
s.transitionDuration = '0s';
|
||
}
|
||
}
|
||
|
||
var platformComponents = {
|
||
Transition: Transition,
|
||
TransitionGroup: TransitionGroup
|
||
};
|
||
|
||
/* */
|
||
|
||
// install platform specific utils
|
||
Vue$3.config.mustUseProp = mustUseProp;
|
||
Vue$3.config.isReservedTag = isReservedTag;
|
||
Vue$3.config.isReservedAttr = isReservedAttr;
|
||
Vue$3.config.getTagNamespace = getTagNamespace;
|
||
Vue$3.config.isUnknownElement = isUnknownElement;
|
||
|
||
// install platform runtime directives & components
|
||
extend(Vue$3.options.directives, platformDirectives);
|
||
extend(Vue$3.options.components, platformComponents);
|
||
|
||
// install platform patch function
|
||
Vue$3.prototype.__patch__ = inBrowser ? patch : noop;
|
||
|
||
// public mount method
|
||
Vue$3.prototype.$mount = function (
|
||
el,
|
||
hydrating
|
||
) {
|
||
el = el && inBrowser ? query(el) : undefined;
|
||
return mountComponent(this, el, hydrating)
|
||
};
|
||
|
||
// devtools global hook
|
||
/* istanbul ignore next */
|
||
setTimeout(function () {
|
||
if (config.devtools) {
|
||
if (devtools) {
|
||
devtools.emit('init', Vue$3);
|
||
} else if ("development" !== 'production' && isChrome) {
|
||
console[console.info ? 'info' : 'log'](
|
||
'Download the Vue Devtools extension for a better development experience:\n' +
|
||
'https://github.com/vuejs/vue-devtools'
|
||
);
|
||
}
|
||
}
|
||
if ("development" !== 'production' &&
|
||
config.productionTip !== false &&
|
||
inBrowser && typeof console !== 'undefined'
|
||
) {
|
||
console[console.info ? 'info' : 'log'](
|
||
"You are running Vue in development mode.\n" +
|
||
"Make sure to turn on production mode when deploying for production.\n" +
|
||
"See more tips at https://vuejs.org/guide/deployment.html"
|
||
);
|
||
}
|
||
}, 0);
|
||
|
||
/* */
|
||
|
||
// check whether current browser encodes a char inside attribute values
|
||
function shouldDecode (content, encoded) {
|
||
var div = document.createElement('div');
|
||
div.innerHTML = "<div a=\"" + content + "\"/>";
|
||
return div.innerHTML.indexOf(encoded) > 0
|
||
}
|
||
|
||
// #3663
|
||
// IE encodes newlines inside attribute values while other browsers don't
|
||
var shouldDecodeNewlines = inBrowser ? shouldDecode('\n', ' ') : false;
|
||
|
||
/* */
|
||
|
||
var defaultTagRE = /\{\{((?:.|\n)+?)\}\}/g;
|
||
var regexEscapeRE = /[-.*+?^${}()|[\]\/\\]/g;
|
||
|
||
var buildRegex = cached(function (delimiters) {
|
||
var open = delimiters[0].replace(regexEscapeRE, '\\$&');
|
||
var close = delimiters[1].replace(regexEscapeRE, '\\$&');
|
||
return new RegExp(open + '((?:.|\\n)+?)' + close, 'g')
|
||
});
|
||
|
||
function parseText (
|
||
text,
|
||
delimiters
|
||
) {
|
||
var tagRE = delimiters ? buildRegex(delimiters) : defaultTagRE;
|
||
if (!tagRE.test(text)) {
|
||
return
|
||
}
|
||
var tokens = [];
|
||
var lastIndex = tagRE.lastIndex = 0;
|
||
var match, index;
|
||
while ((match = tagRE.exec(text))) {
|
||
index = match.index;
|
||
// push text token
|
||
if (index > lastIndex) {
|
||
tokens.push(JSON.stringify(text.slice(lastIndex, index)));
|
||
}
|
||
// tag token
|
||
var exp = parseFilters(match[1].trim());
|
||
tokens.push(("_s(" + exp + ")"));
|
||
lastIndex = index + match[0].length;
|
||
}
|
||
if (lastIndex < text.length) {
|
||
tokens.push(JSON.stringify(text.slice(lastIndex)));
|
||
}
|
||
return tokens.join('+')
|
||
}
|
||
|
||
/* */
|
||
|
||
function transformNode (el, options) {
|
||
var warn = options.warn || baseWarn;
|
||
var staticClass = getAndRemoveAttr(el, 'class');
|
||
if ("development" !== 'production' && staticClass) {
|
||
var expression = parseText(staticClass, options.delimiters);
|
||
if (expression) {
|
||
warn(
|
||
"class=\"" + staticClass + "\": " +
|
||
'Interpolation inside attributes has been removed. ' +
|
||
'Use v-bind or the colon shorthand instead. For example, ' +
|
||
'instead of <div class="{{ val }}">, use <div :class="val">.'
|
||
);
|
||
}
|
||
}
|
||
if (staticClass) {
|
||
el.staticClass = JSON.stringify(staticClass);
|
||
}
|
||
var classBinding = getBindingAttr(el, 'class', false /* getStatic */);
|
||
if (classBinding) {
|
||
el.classBinding = classBinding;
|
||
}
|
||
}
|
||
|
||
function genData (el) {
|
||
var data = '';
|
||
if (el.staticClass) {
|
||
data += "staticClass:" + (el.staticClass) + ",";
|
||
}
|
||
if (el.classBinding) {
|
||
data += "class:" + (el.classBinding) + ",";
|
||
}
|
||
return data
|
||
}
|
||
|
||
var klass$1 = {
|
||
staticKeys: ['staticClass'],
|
||
transformNode: transformNode,
|
||
genData: genData
|
||
};
|
||
|
||
/* */
|
||
|
||
function transformNode$1 (el, options) {
|
||
var warn = options.warn || baseWarn;
|
||
var staticStyle = getAndRemoveAttr(el, 'style');
|
||
if (staticStyle) {
|
||
/* istanbul ignore if */
|
||
if (true) {
|
||
var expression = parseText(staticStyle, options.delimiters);
|
||
if (expression) {
|
||
warn(
|
||
"style=\"" + staticStyle + "\": " +
|
||
'Interpolation inside attributes has been removed. ' +
|
||
'Use v-bind or the colon shorthand instead. For example, ' +
|
||
'instead of <div style="{{ val }}">, use <div :style="val">.'
|
||
);
|
||
}
|
||
}
|
||
el.staticStyle = JSON.stringify(parseStyleText(staticStyle));
|
||
}
|
||
|
||
var styleBinding = getBindingAttr(el, 'style', false /* getStatic */);
|
||
if (styleBinding) {
|
||
el.styleBinding = styleBinding;
|
||
}
|
||
}
|
||
|
||
function genData$1 (el) {
|
||
var data = '';
|
||
if (el.staticStyle) {
|
||
data += "staticStyle:" + (el.staticStyle) + ",";
|
||
}
|
||
if (el.styleBinding) {
|
||
data += "style:(" + (el.styleBinding) + "),";
|
||
}
|
||
return data
|
||
}
|
||
|
||
var style$1 = {
|
||
staticKeys: ['staticStyle'],
|
||
transformNode: transformNode$1,
|
||
genData: genData$1
|
||
};
|
||
|
||
var modules$1 = [
|
||
klass$1,
|
||
style$1
|
||
];
|
||
|
||
/* */
|
||
|
||
function text (el, dir) {
|
||
if (dir.value) {
|
||
addProp(el, 'textContent', ("_s(" + (dir.value) + ")"));
|
||
}
|
||
}
|
||
|
||
/* */
|
||
|
||
function html (el, dir) {
|
||
if (dir.value) {
|
||
addProp(el, 'innerHTML', ("_s(" + (dir.value) + ")"));
|
||
}
|
||
}
|
||
|
||
var directives$1 = {
|
||
model: model,
|
||
text: text,
|
||
html: html
|
||
};
|
||
|
||
/* */
|
||
|
||
var isUnaryTag = makeMap(
|
||
'area,base,br,col,embed,frame,hr,img,input,isindex,keygen,' +
|
||
'link,meta,param,source,track,wbr'
|
||
);
|
||
|
||
// Elements that you can, intentionally, leave open
|
||
// (and which close themselves)
|
||
var canBeLeftOpenTag = makeMap(
|
||
'colgroup,dd,dt,li,options,p,td,tfoot,th,thead,tr,source'
|
||
);
|
||
|
||
// HTML5 tags https://html.spec.whatwg.org/multipage/indices.html#elements-3
|
||
// Phrasing Content https://html.spec.whatwg.org/multipage/dom.html#phrasing-content
|
||
var isNonPhrasingTag = makeMap(
|
||
'address,article,aside,base,blockquote,body,caption,col,colgroup,dd,' +
|
||
'details,dialog,div,dl,dt,fieldset,figcaption,figure,footer,form,' +
|
||
'h1,h2,h3,h4,h5,h6,head,header,hgroup,hr,html,legend,li,menuitem,meta,' +
|
||
'optgroup,option,param,rp,rt,source,style,summary,tbody,td,tfoot,th,thead,' +
|
||
'title,tr,track'
|
||
);
|
||
|
||
/* */
|
||
|
||
var baseOptions = {
|
||
expectHTML: true,
|
||
modules: modules$1,
|
||
directives: directives$1,
|
||
isPreTag: isPreTag,
|
||
isUnaryTag: isUnaryTag,
|
||
mustUseProp: mustUseProp,
|
||
canBeLeftOpenTag: canBeLeftOpenTag,
|
||
isReservedTag: isReservedTag,
|
||
getTagNamespace: getTagNamespace,
|
||
staticKeys: genStaticKeys(modules$1)
|
||
};
|
||
|
||
/* */
|
||
|
||
var decoder;
|
||
|
||
var he = {
|
||
decode: function decode (html) {
|
||
decoder = decoder || document.createElement('div');
|
||
decoder.innerHTML = html;
|
||
return decoder.textContent
|
||
}
|
||
};
|
||
|
||
/**
|
||
* Not type-checking this file because it's mostly vendor code.
|
||
*/
|
||
|
||
/*!
|
||
* HTML Parser By John Resig (ejohn.org)
|
||
* Modified by Juriy "kangax" Zaytsev
|
||
* Original code by Erik Arvidsson, Mozilla Public License
|
||
* http://erik.eae.net/simplehtmlparser/simplehtmlparser.js
|
||
*/
|
||
|
||
// Regular Expressions for parsing tags and attributes
|
||
var attribute = /^\s*([^\s"'<>\/=]+)(?:\s*(=)\s*(?:"([^"]*)"+|'([^']*)'+|([^\s"'=<>`]+)))?/;
|
||
// could use https://www.w3.org/TR/1999/REC-xml-names-19990114/#NT-QName
|
||
// but for Vue templates we can enforce a simple charset
|
||
var ncname = '[a-zA-Z_][\\w\\-\\.]*';
|
||
var qnameCapture = "((?:" + ncname + "\\:)?" + ncname + ")";
|
||
var startTagOpen = new RegExp(("^<" + qnameCapture));
|
||
var startTagClose = /^\s*(\/?)>/;
|
||
var endTag = new RegExp(("^<\\/" + qnameCapture + "[^>]*>"));
|
||
var doctype = /^<!DOCTYPE [^>]+>/i;
|
||
var comment = /^<!--/;
|
||
var conditionalComment = /^<!\[/;
|
||
|
||
var IS_REGEX_CAPTURING_BROKEN = false;
|
||
'x'.replace(/x(.)?/g, function (m, g) {
|
||
IS_REGEX_CAPTURING_BROKEN = g === '';
|
||
});
|
||
|
||
// Special Elements (can contain anything)
|
||
var isPlainTextElement = makeMap('script,style,textarea', true);
|
||
var reCache = {};
|
||
|
||
var decodingMap = {
|
||
'<': '<',
|
||
'>': '>',
|
||
'"': '"',
|
||
'&': '&',
|
||
' ': '\n'
|
||
};
|
||
var encodedAttr = /&(?:lt|gt|quot|amp);/g;
|
||
var encodedAttrWithNewLines = /&(?:lt|gt|quot|amp|#10);/g;
|
||
|
||
// #5992
|
||
var isIgnoreNewlineTag = makeMap('pre,textarea', true);
|
||
var shouldIgnoreFirstNewline = function (tag, html) { return tag && isIgnoreNewlineTag(tag) && html[0] === '\n'; };
|
||
|
||
function decodeAttr (value, shouldDecodeNewlines) {
|
||
var re = shouldDecodeNewlines ? encodedAttrWithNewLines : encodedAttr;
|
||
return value.replace(re, function (match) { return decodingMap[match]; })
|
||
}
|
||
|
||
function parseHTML (html, options) {
|
||
var stack = [];
|
||
var expectHTML = options.expectHTML;
|
||
var isUnaryTag$$1 = options.isUnaryTag || no;
|
||
var canBeLeftOpenTag$$1 = options.canBeLeftOpenTag || no;
|
||
var index = 0;
|
||
var last, lastTag;
|
||
while (html) {
|
||
last = html;
|
||
// Make sure we're not in a plaintext content element like script/style
|
||
if (!lastTag || !isPlainTextElement(lastTag)) {
|
||
var textEnd = html.indexOf('<');
|
||
if (textEnd === 0) {
|
||
// Comment:
|
||
if (comment.test(html)) {
|
||
var commentEnd = html.indexOf('-->');
|
||
|
||
if (commentEnd >= 0) {
|
||
if (options.shouldKeepComment) {
|
||
options.comment(html.substring(4, commentEnd));
|
||
}
|
||
advance(commentEnd + 3);
|
||
continue
|
||
}
|
||
}
|
||
|
||
// http://en.wikipedia.org/wiki/Conditional_comment#Downlevel-revealed_conditional_comment
|
||
if (conditionalComment.test(html)) {
|
||
var conditionalEnd = html.indexOf(']>');
|
||
|
||
if (conditionalEnd >= 0) {
|
||
advance(conditionalEnd + 2);
|
||
continue
|
||
}
|
||
}
|
||
|
||
// Doctype:
|
||
var doctypeMatch = html.match(doctype);
|
||
if (doctypeMatch) {
|
||
advance(doctypeMatch[0].length);
|
||
continue
|
||
}
|
||
|
||
// End tag:
|
||
var endTagMatch = html.match(endTag);
|
||
if (endTagMatch) {
|
||
var curIndex = index;
|
||
advance(endTagMatch[0].length);
|
||
parseEndTag(endTagMatch[1], curIndex, index);
|
||
continue
|
||
}
|
||
|
||
// Start tag:
|
||
var startTagMatch = parseStartTag();
|
||
if (startTagMatch) {
|
||
handleStartTag(startTagMatch);
|
||
if (shouldIgnoreFirstNewline(lastTag, html)) {
|
||
advance(1);
|
||
}
|
||
continue
|
||
}
|
||
}
|
||
|
||
var text = (void 0), rest = (void 0), next = (void 0);
|
||
if (textEnd >= 0) {
|
||
rest = html.slice(textEnd);
|
||
while (
|
||
!endTag.test(rest) &&
|
||
!startTagOpen.test(rest) &&
|
||
!comment.test(rest) &&
|
||
!conditionalComment.test(rest)
|
||
) {
|
||
// < in plain text, be forgiving and treat it as text
|
||
next = rest.indexOf('<', 1);
|
||
if (next < 0) { break }
|
||
textEnd += next;
|
||
rest = html.slice(textEnd);
|
||
}
|
||
text = html.substring(0, textEnd);
|
||
advance(textEnd);
|
||
}
|
||
|
||
if (textEnd < 0) {
|
||
text = html;
|
||
html = '';
|
||
}
|
||
|
||
if (options.chars && text) {
|
||
options.chars(text);
|
||
}
|
||
} else {
|
||
var endTagLength = 0;
|
||
var stackedTag = lastTag.toLowerCase();
|
||
var reStackedTag = reCache[stackedTag] || (reCache[stackedTag] = new RegExp('([\\s\\S]*?)(</' + stackedTag + '[^>]*>)', 'i'));
|
||
var rest$1 = html.replace(reStackedTag, function (all, text, endTag) {
|
||
endTagLength = endTag.length;
|
||
if (!isPlainTextElement(stackedTag) && stackedTag !== 'noscript') {
|
||
text = text
|
||
.replace(/<!--([\s\S]*?)-->/g, '$1')
|
||
.replace(/<!\[CDATA\[([\s\S]*?)]]>/g, '$1');
|
||
}
|
||
if (shouldIgnoreFirstNewline(stackedTag, text)) {
|
||
text = text.slice(1);
|
||
}
|
||
if (options.chars) {
|
||
options.chars(text);
|
||
}
|
||
return ''
|
||
});
|
||
index += html.length - rest$1.length;
|
||
html = rest$1;
|
||
parseEndTag(stackedTag, index - endTagLength, index);
|
||
}
|
||
|
||
if (html === last) {
|
||
options.chars && options.chars(html);
|
||
if ("development" !== 'production' && !stack.length && options.warn) {
|
||
options.warn(("Mal-formatted tag at end of template: \"" + html + "\""));
|
||
}
|
||
break
|
||
}
|
||
}
|
||
|
||
// Clean up any remaining tags
|
||
parseEndTag();
|
||
|
||
function advance (n) {
|
||
index += n;
|
||
html = html.substring(n);
|
||
}
|
||
|
||
function parseStartTag () {
|
||
var start = html.match(startTagOpen);
|
||
if (start) {
|
||
var match = {
|
||
tagName: start[1],
|
||
attrs: [],
|
||
start: index
|
||
};
|
||
advance(start[0].length);
|
||
var end, attr;
|
||
while (!(end = html.match(startTagClose)) && (attr = html.match(attribute))) {
|
||
advance(attr[0].length);
|
||
match.attrs.push(attr);
|
||
}
|
||
if (end) {
|
||
match.unarySlash = end[1];
|
||
advance(end[0].length);
|
||
match.end = index;
|
||
return match
|
||
}
|
||
}
|
||
}
|
||
|
||
function handleStartTag (match) {
|
||
var tagName = match.tagName;
|
||
var unarySlash = match.unarySlash;
|
||
|
||
if (expectHTML) {
|
||
if (lastTag === 'p' && isNonPhrasingTag(tagName)) {
|
||
parseEndTag(lastTag);
|
||
}
|
||
if (canBeLeftOpenTag$$1(tagName) && lastTag === tagName) {
|
||
parseEndTag(tagName);
|
||
}
|
||
}
|
||
|
||
var unary = isUnaryTag$$1(tagName) || !!unarySlash;
|
||
|
||
var l = match.attrs.length;
|
||
var attrs = new Array(l);
|
||
for (var i = 0; i < l; i++) {
|
||
var args = match.attrs[i];
|
||
// hackish work around FF bug https://bugzilla.mozilla.org/show_bug.cgi?id=369778
|
||
if (IS_REGEX_CAPTURING_BROKEN && args[0].indexOf('""') === -1) {
|
||
if (args[3] === '') { delete args[3]; }
|
||
if (args[4] === '') { delete args[4]; }
|
||
if (args[5] === '') { delete args[5]; }
|
||
}
|
||
var value = args[3] || args[4] || args[5] || '';
|
||
attrs[i] = {
|
||
name: args[1],
|
||
value: decodeAttr(
|
||
value,
|
||
options.shouldDecodeNewlines
|
||
)
|
||
};
|
||
}
|
||
|
||
if (!unary) {
|
||
stack.push({ tag: tagName, lowerCasedTag: tagName.toLowerCase(), attrs: attrs });
|
||
lastTag = tagName;
|
||
}
|
||
|
||
if (options.start) {
|
||
options.start(tagName, attrs, unary, match.start, match.end);
|
||
}
|
||
}
|
||
|
||
function parseEndTag (tagName, start, end) {
|
||
var pos, lowerCasedTagName;
|
||
if (start == null) { start = index; }
|
||
if (end == null) { end = index; }
|
||
|
||
if (tagName) {
|
||
lowerCasedTagName = tagName.toLowerCase();
|
||
}
|
||
|
||
// Find the closest opened tag of the same type
|
||
if (tagName) {
|
||
for (pos = stack.length - 1; pos >= 0; pos--) {
|
||
if (stack[pos].lowerCasedTag === lowerCasedTagName) {
|
||
break
|
||
}
|
||
}
|
||
} else {
|
||
// If no tag name is provided, clean shop
|
||
pos = 0;
|
||
}
|
||
|
||
if (pos >= 0) {
|
||
// Close all the open elements, up the stack
|
||
for (var i = stack.length - 1; i >= pos; i--) {
|
||
if ("development" !== 'production' &&
|
||
(i > pos || !tagName) &&
|
||
options.warn
|
||
) {
|
||
options.warn(
|
||
("tag <" + (stack[i].tag) + "> has no matching end tag.")
|
||
);
|
||
}
|
||
if (options.end) {
|
||
options.end(stack[i].tag, start, end);
|
||
}
|
||
}
|
||
|
||
// Remove the open elements from the stack
|
||
stack.length = pos;
|
||
lastTag = pos && stack[pos - 1].tag;
|
||
} else if (lowerCasedTagName === 'br') {
|
||
if (options.start) {
|
||
options.start(tagName, [], true, start, end);
|
||
}
|
||
} else if (lowerCasedTagName === 'p') {
|
||
if (options.start) {
|
||
options.start(tagName, [], false, start, end);
|
||
}
|
||
if (options.end) {
|
||
options.end(tagName, start, end);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
/* */
|
||
|
||
var onRE = /^@|^v-on:/;
|
||
var dirRE = /^v-|^@|^:/;
|
||
var forAliasRE = /(.*?)\s+(?:in|of)\s+(.*)/;
|
||
var forIteratorRE = /\((\{[^}]*\}|[^,]*),([^,]*)(?:,([^,]*))?\)/;
|
||
|
||
var argRE = /:(.*)$/;
|
||
var bindRE = /^:|^v-bind:/;
|
||
var modifierRE = /\.[^.]+/g;
|
||
|
||
var decodeHTMLCached = cached(he.decode);
|
||
|
||
// configurable state
|
||
var warn$2;
|
||
var delimiters;
|
||
var transforms;
|
||
var preTransforms;
|
||
var postTransforms;
|
||
var platformIsPreTag;
|
||
var platformMustUseProp;
|
||
var platformGetTagNamespace;
|
||
|
||
/**
|
||
* Convert HTML string to AST.
|
||
*/
|
||
function parse (
|
||
template,
|
||
options
|
||
) {
|
||
warn$2 = options.warn || baseWarn;
|
||
|
||
platformIsPreTag = options.isPreTag || no;
|
||
platformMustUseProp = options.mustUseProp || no;
|
||
platformGetTagNamespace = options.getTagNamespace || no;
|
||
|
||
transforms = pluckModuleFunction(options.modules, 'transformNode');
|
||
preTransforms = pluckModuleFunction(options.modules, 'preTransformNode');
|
||
postTransforms = pluckModuleFunction(options.modules, 'postTransformNode');
|
||
|
||
delimiters = options.delimiters;
|
||
|
||
var stack = [];
|
||
var preserveWhitespace = options.preserveWhitespace !== false;
|
||
var root;
|
||
var currentParent;
|
||
var inVPre = false;
|
||
var inPre = false;
|
||
var warned = false;
|
||
|
||
function warnOnce (msg) {
|
||
if (!warned) {
|
||
warned = true;
|
||
warn$2(msg);
|
||
}
|
||
}
|
||
|
||
function endPre (element) {
|
||
// check pre state
|
||
if (element.pre) {
|
||
inVPre = false;
|
||
}
|
||
if (platformIsPreTag(element.tag)) {
|
||
inPre = false;
|
||
}
|
||
}
|
||
|
||
parseHTML(template, {
|
||
warn: warn$2,
|
||
expectHTML: options.expectHTML,
|
||
isUnaryTag: options.isUnaryTag,
|
||
canBeLeftOpenTag: options.canBeLeftOpenTag,
|
||
shouldDecodeNewlines: options.shouldDecodeNewlines,
|
||
shouldKeepComment: options.comments,
|
||
start: function start (tag, attrs, unary) {
|
||
// check namespace.
|
||
// inherit parent ns if there is one
|
||
var ns = (currentParent && currentParent.ns) || platformGetTagNamespace(tag);
|
||
|
||
// handle IE svg bug
|
||
/* istanbul ignore if */
|
||
if (isIE && ns === 'svg') {
|
||
attrs = guardIESVGBug(attrs);
|
||
}
|
||
|
||
var element = {
|
||
type: 1,
|
||
tag: tag,
|
||
attrsList: attrs,
|
||
attrsMap: makeAttrsMap(attrs),
|
||
parent: currentParent,
|
||
children: []
|
||
};
|
||
if (ns) {
|
||
element.ns = ns;
|
||
}
|
||
|
||
if (isForbiddenTag(element) && !isServerRendering()) {
|
||
element.forbidden = true;
|
||
"development" !== 'production' && warn$2(
|
||
'Templates should only be responsible for mapping the state to the ' +
|
||
'UI. Avoid placing tags with side-effects in your templates, such as ' +
|
||
"<" + tag + ">" + ', as they will not be parsed.'
|
||
);
|
||
}
|
||
|
||
// apply pre-transforms
|
||
for (var i = 0; i < preTransforms.length; i++) {
|
||
preTransforms[i](element, options);
|
||
}
|
||
|
||
if (!inVPre) {
|
||
processPre(element);
|
||
if (element.pre) {
|
||
inVPre = true;
|
||
}
|
||
}
|
||
if (platformIsPreTag(element.tag)) {
|
||
inPre = true;
|
||
}
|
||
if (inVPre) {
|
||
processRawAttrs(element);
|
||
} else {
|
||
processFor(element);
|
||
processIf(element);
|
||
processOnce(element);
|
||
processKey(element);
|
||
|
||
// determine whether this is a plain element after
|
||
// removing structural attributes
|
||
element.plain = !element.key && !attrs.length;
|
||
|
||
processRef(element);
|
||
processSlot(element);
|
||
processComponent(element);
|
||
for (var i$1 = 0; i$1 < transforms.length; i$1++) {
|
||
transforms[i$1](element, options);
|
||
}
|
||
processAttrs(element);
|
||
}
|
||
|
||
function checkRootConstraints (el) {
|
||
if (true) {
|
||
if (el.tag === 'slot' || el.tag === 'template') {
|
||
warnOnce(
|
||
"Cannot use <" + (el.tag) + "> as component root element because it may " +
|
||
'contain multiple nodes.'
|
||
);
|
||
}
|
||
if (el.attrsMap.hasOwnProperty('v-for')) {
|
||
warnOnce(
|
||
'Cannot use v-for on stateful component root element because ' +
|
||
'it renders multiple elements.'
|
||
);
|
||
}
|
||
}
|
||
}
|
||
|
||
// tree management
|
||
if (!root) {
|
||
root = element;
|
||
checkRootConstraints(root);
|
||
} else if (!stack.length) {
|
||
// allow root elements with v-if, v-else-if and v-else
|
||
if (root.if && (element.elseif || element.else)) {
|
||
checkRootConstraints(element);
|
||
addIfCondition(root, {
|
||
exp: element.elseif,
|
||
block: element
|
||
});
|
||
} else if (true) {
|
||
warnOnce(
|
||
"Component template should contain exactly one root element. " +
|
||
"If you are using v-if on multiple elements, " +
|
||
"use v-else-if to chain them instead."
|
||
);
|
||
}
|
||
}
|
||
if (currentParent && !element.forbidden) {
|
||
if (element.elseif || element.else) {
|
||
processIfConditions(element, currentParent);
|
||
} else if (element.slotScope) { // scoped slot
|
||
currentParent.plain = false;
|
||
var name = element.slotTarget || '"default"';(currentParent.scopedSlots || (currentParent.scopedSlots = {}))[name] = element;
|
||
} else {
|
||
currentParent.children.push(element);
|
||
element.parent = currentParent;
|
||
}
|
||
}
|
||
if (!unary) {
|
||
currentParent = element;
|
||
stack.push(element);
|
||
} else {
|
||
endPre(element);
|
||
}
|
||
// apply post-transforms
|
||
for (var i$2 = 0; i$2 < postTransforms.length; i$2++) {
|
||
postTransforms[i$2](element, options);
|
||
}
|
||
},
|
||
|
||
end: function end () {
|
||
// remove trailing whitespace
|
||
var element = stack[stack.length - 1];
|
||
var lastNode = element.children[element.children.length - 1];
|
||
if (lastNode && lastNode.type === 3 && lastNode.text === ' ' && !inPre) {
|
||
element.children.pop();
|
||
}
|
||
// pop stack
|
||
stack.length -= 1;
|
||
currentParent = stack[stack.length - 1];
|
||
endPre(element);
|
||
},
|
||
|
||
chars: function chars (text) {
|
||
if (!currentParent) {
|
||
if (true) {
|
||
if (text === template) {
|
||
warnOnce(
|
||
'Component template requires a root element, rather than just text.'
|
||
);
|
||
} else if ((text = text.trim())) {
|
||
warnOnce(
|
||
("text \"" + text + "\" outside root element will be ignored.")
|
||
);
|
||
}
|
||
}
|
||
return
|
||
}
|
||
// IE textarea placeholder bug
|
||
/* istanbul ignore if */
|
||
if (isIE &&
|
||
currentParent.tag === 'textarea' &&
|
||
currentParent.attrsMap.placeholder === text
|
||
) {
|
||
return
|
||
}
|
||
var children = currentParent.children;
|
||
text = inPre || text.trim()
|
||
? isTextTag(currentParent) ? text : decodeHTMLCached(text)
|
||
// only preserve whitespace if its not right after a starting tag
|
||
: preserveWhitespace && children.length ? ' ' : '';
|
||
if (text) {
|
||
var expression;
|
||
if (!inVPre && text !== ' ' && (expression = parseText(text, delimiters))) {
|
||
children.push({
|
||
type: 2,
|
||
expression: expression,
|
||
text: text
|
||
});
|
||
} else if (text !== ' ' || !children.length || children[children.length - 1].text !== ' ') {
|
||
children.push({
|
||
type: 3,
|
||
text: text
|
||
});
|
||
}
|
||
}
|
||
},
|
||
comment: function comment (text) {
|
||
currentParent.children.push({
|
||
type: 3,
|
||
text: text,
|
||
isComment: true
|
||
});
|
||
}
|
||
});
|
||
return root
|
||
}
|
||
|
||
function processPre (el) {
|
||
if (getAndRemoveAttr(el, 'v-pre') != null) {
|
||
el.pre = true;
|
||
}
|
||
}
|
||
|
||
function processRawAttrs (el) {
|
||
var l = el.attrsList.length;
|
||
if (l) {
|
||
var attrs = el.attrs = new Array(l);
|
||
for (var i = 0; i < l; i++) {
|
||
attrs[i] = {
|
||
name: el.attrsList[i].name,
|
||
value: JSON.stringify(el.attrsList[i].value)
|
||
};
|
||
}
|
||
} else if (!el.pre) {
|
||
// non root node in pre blocks with no attributes
|
||
el.plain = true;
|
||
}
|
||
}
|
||
|
||
function processKey (el) {
|
||
var exp = getBindingAttr(el, 'key');
|
||
if (exp) {
|
||
if ("development" !== 'production' && el.tag === 'template') {
|
||
warn$2("<template> cannot be keyed. Place the key on real elements instead.");
|
||
}
|
||
el.key = exp;
|
||
}
|
||
}
|
||
|
||
function processRef (el) {
|
||
var ref = getBindingAttr(el, 'ref');
|
||
if (ref) {
|
||
el.ref = ref;
|
||
el.refInFor = checkInFor(el);
|
||
}
|
||
}
|
||
|
||
function processFor (el) {
|
||
var exp;
|
||
if ((exp = getAndRemoveAttr(el, 'v-for'))) {
|
||
var inMatch = exp.match(forAliasRE);
|
||
if (!inMatch) {
|
||
"development" !== 'production' && warn$2(
|
||
("Invalid v-for expression: " + exp)
|
||
);
|
||
return
|
||
}
|
||
el.for = inMatch[2].trim();
|
||
var alias = inMatch[1].trim();
|
||
var iteratorMatch = alias.match(forIteratorRE);
|
||
if (iteratorMatch) {
|
||
el.alias = iteratorMatch[1].trim();
|
||
el.iterator1 = iteratorMatch[2].trim();
|
||
if (iteratorMatch[3]) {
|
||
el.iterator2 = iteratorMatch[3].trim();
|
||
}
|
||
} else {
|
||
el.alias = alias;
|
||
}
|
||
}
|
||
}
|
||
|
||
function processIf (el) {
|
||
var exp = getAndRemoveAttr(el, 'v-if');
|
||
if (exp) {
|
||
el.if = exp;
|
||
addIfCondition(el, {
|
||
exp: exp,
|
||
block: el
|
||
});
|
||
} else {
|
||
if (getAndRemoveAttr(el, 'v-else') != null) {
|
||
el.else = true;
|
||
}
|
||
var elseif = getAndRemoveAttr(el, 'v-else-if');
|
||
if (elseif) {
|
||
el.elseif = elseif;
|
||
}
|
||
}
|
||
}
|
||
|
||
function processIfConditions (el, parent) {
|
||
var prev = findPrevElement(parent.children);
|
||
if (prev && prev.if) {
|
||
addIfCondition(prev, {
|
||
exp: el.elseif,
|
||
block: el
|
||
});
|
||
} else if (true) {
|
||
warn$2(
|
||
"v-" + (el.elseif ? ('else-if="' + el.elseif + '"') : 'else') + " " +
|
||
"used on element <" + (el.tag) + "> without corresponding v-if."
|
||
);
|
||
}
|
||
}
|
||
|
||
function findPrevElement (children) {
|
||
var i = children.length;
|
||
while (i--) {
|
||
if (children[i].type === 1) {
|
||
return children[i]
|
||
} else {
|
||
if ("development" !== 'production' && children[i].text !== ' ') {
|
||
warn$2(
|
||
"text \"" + (children[i].text.trim()) + "\" between v-if and v-else(-if) " +
|
||
"will be ignored."
|
||
);
|
||
}
|
||
children.pop();
|
||
}
|
||
}
|
||
}
|
||
|
||
function addIfCondition (el, condition) {
|
||
if (!el.ifConditions) {
|
||
el.ifConditions = [];
|
||
}
|
||
el.ifConditions.push(condition);
|
||
}
|
||
|
||
function processOnce (el) {
|
||
var once$$1 = getAndRemoveAttr(el, 'v-once');
|
||
if (once$$1 != null) {
|
||
el.once = true;
|
||
}
|
||
}
|
||
|
||
function processSlot (el) {
|
||
if (el.tag === 'slot') {
|
||
el.slotName = getBindingAttr(el, 'name');
|
||
if ("development" !== 'production' && el.key) {
|
||
warn$2(
|
||
"`key` does not work on <slot> because slots are abstract outlets " +
|
||
"and can possibly expand into multiple elements. " +
|
||
"Use the key on a wrapping element instead."
|
||
);
|
||
}
|
||
} else {
|
||
var slotTarget = getBindingAttr(el, 'slot');
|
||
if (slotTarget) {
|
||
el.slotTarget = slotTarget === '""' ? '"default"' : slotTarget;
|
||
// preserve slot as an attribute for native shadow DOM compat
|
||
addAttr(el, 'slot', slotTarget);
|
||
}
|
||
if (el.tag === 'template') {
|
||
el.slotScope = getAndRemoveAttr(el, 'scope');
|
||
}
|
||
}
|
||
}
|
||
|
||
function processComponent (el) {
|
||
var binding;
|
||
if ((binding = getBindingAttr(el, 'is'))) {
|
||
el.component = binding;
|
||
}
|
||
if (getAndRemoveAttr(el, 'inline-template') != null) {
|
||
el.inlineTemplate = true;
|
||
}
|
||
}
|
||
|
||
function processAttrs (el) {
|
||
var list = el.attrsList;
|
||
var i, l, name, rawName, value, modifiers, isProp;
|
||
for (i = 0, l = list.length; i < l; i++) {
|
||
name = rawName = list[i].name;
|
||
value = list[i].value;
|
||
if (dirRE.test(name)) {
|
||
// mark element as dynamic
|
||
el.hasBindings = true;
|
||
// modifiers
|
||
modifiers = parseModifiers(name);
|
||
if (modifiers) {
|
||
name = name.replace(modifierRE, '');
|
||
}
|
||
if (bindRE.test(name)) { // v-bind
|
||
name = name.replace(bindRE, '');
|
||
value = parseFilters(value);
|
||
isProp = false;
|
||
if (modifiers) {
|
||
if (modifiers.prop) {
|
||
isProp = true;
|
||
name = camelize(name);
|
||
if (name === 'innerHtml') { name = 'innerHTML'; }
|
||
}
|
||
if (modifiers.camel) {
|
||
name = camelize(name);
|
||
}
|
||
if (modifiers.sync) {
|
||
addHandler(
|
||
el,
|
||
("update:" + (camelize(name))),
|
||
genAssignmentCode(value, "$event")
|
||
);
|
||
}
|
||
}
|
||
if (isProp || (
|
||
!el.component && platformMustUseProp(el.tag, el.attrsMap.type, name)
|
||
)) {
|
||
addProp(el, name, value);
|
||
} else {
|
||
addAttr(el, name, value);
|
||
}
|
||
} else if (onRE.test(name)) { // v-on
|
||
name = name.replace(onRE, '');
|
||
addHandler(el, name, value, modifiers, false, warn$2);
|
||
} else { // normal directives
|
||
name = name.replace(dirRE, '');
|
||
// parse arg
|
||
var argMatch = name.match(argRE);
|
||
var arg = argMatch && argMatch[1];
|
||
if (arg) {
|
||
name = name.slice(0, -(arg.length + 1));
|
||
}
|
||
addDirective(el, name, rawName, value, arg, modifiers);
|
||
if ("development" !== 'production' && name === 'model') {
|
||
checkForAliasModel(el, value);
|
||
}
|
||
}
|
||
} else {
|
||
// literal attribute
|
||
if (true) {
|
||
var expression = parseText(value, delimiters);
|
||
if (expression) {
|
||
warn$2(
|
||
name + "=\"" + value + "\": " +
|
||
'Interpolation inside attributes has been removed. ' +
|
||
'Use v-bind or the colon shorthand instead. For example, ' +
|
||
'instead of <div id="{{ val }}">, use <div :id="val">.'
|
||
);
|
||
}
|
||
}
|
||
addAttr(el, name, JSON.stringify(value));
|
||
}
|
||
}
|
||
}
|
||
|
||
function checkInFor (el) {
|
||
var parent = el;
|
||
while (parent) {
|
||
if (parent.for !== undefined) {
|
||
return true
|
||
}
|
||
parent = parent.parent;
|
||
}
|
||
return false
|
||
}
|
||
|
||
function parseModifiers (name) {
|
||
var match = name.match(modifierRE);
|
||
if (match) {
|
||
var ret = {};
|
||
match.forEach(function (m) { ret[m.slice(1)] = true; });
|
||
return ret
|
||
}
|
||
}
|
||
|
||
function makeAttrsMap (attrs) {
|
||
var map = {};
|
||
for (var i = 0, l = attrs.length; i < l; i++) {
|
||
if (
|
||
"development" !== 'production' &&
|
||
map[attrs[i].name] && !isIE && !isEdge
|
||
) {
|
||
warn$2('duplicate attribute: ' + attrs[i].name);
|
||
}
|
||
map[attrs[i].name] = attrs[i].value;
|
||
}
|
||
return map
|
||
}
|
||
|
||
// for script (e.g. type="x/template") or style, do not decode content
|
||
function isTextTag (el) {
|
||
return el.tag === 'script' || el.tag === 'style'
|
||
}
|
||
|
||
function isForbiddenTag (el) {
|
||
return (
|
||
el.tag === 'style' ||
|
||
(el.tag === 'script' && (
|
||
!el.attrsMap.type ||
|
||
el.attrsMap.type === 'text/javascript'
|
||
))
|
||
)
|
||
}
|
||
|
||
var ieNSBug = /^xmlns:NS\d+/;
|
||
var ieNSPrefix = /^NS\d+:/;
|
||
|
||
/* istanbul ignore next */
|
||
function guardIESVGBug (attrs) {
|
||
var res = [];
|
||
for (var i = 0; i < attrs.length; i++) {
|
||
var attr = attrs[i];
|
||
if (!ieNSBug.test(attr.name)) {
|
||
attr.name = attr.name.replace(ieNSPrefix, '');
|
||
res.push(attr);
|
||
}
|
||
}
|
||
return res
|
||
}
|
||
|
||
function checkForAliasModel (el, value) {
|
||
var _el = el;
|
||
while (_el) {
|
||
if (_el.for && _el.alias === value) {
|
||
warn$2(
|
||
"<" + (el.tag) + " v-model=\"" + value + "\">: " +
|
||
"You are binding v-model directly to a v-for iteration alias. " +
|
||
"This will not be able to modify the v-for source array because " +
|
||
"writing to the alias is like modifying a function local variable. " +
|
||
"Consider using an array of objects and use v-model on an object property instead."
|
||
);
|
||
}
|
||
_el = _el.parent;
|
||
}
|
||
}
|
||
|
||
/* */
|
||
|
||
var isStaticKey;
|
||
var isPlatformReservedTag;
|
||
|
||
var genStaticKeysCached = cached(genStaticKeys$1);
|
||
|
||
/**
|
||
* Goal of the optimizer: walk the generated template AST tree
|
||
* and detect sub-trees that are purely static, i.e. parts of
|
||
* the DOM that never needs to change.
|
||
*
|
||
* Once we detect these sub-trees, we can:
|
||
*
|
||
* 1. Hoist them into constants, so that we no longer need to
|
||
* create fresh nodes for them on each re-render;
|
||
* 2. Completely skip them in the patching process.
|
||
*/
|
||
function optimize (root, options) {
|
||
if (!root) { return }
|
||
isStaticKey = genStaticKeysCached(options.staticKeys || '');
|
||
isPlatformReservedTag = options.isReservedTag || no;
|
||
// first pass: mark all non-static nodes.
|
||
markStatic$1(root);
|
||
// second pass: mark static roots.
|
||
markStaticRoots(root, false);
|
||
}
|
||
|
||
function genStaticKeys$1 (keys) {
|
||
return makeMap(
|
||
'type,tag,attrsList,attrsMap,plain,parent,children,attrs' +
|
||
(keys ? ',' + keys : '')
|
||
)
|
||
}
|
||
|
||
function markStatic$1 (node) {
|
||
node.static = isStatic(node);
|
||
if (node.type === 1) {
|
||
// do not make component slot content static. this avoids
|
||
// 1. components not able to mutate slot nodes
|
||
// 2. static slot content fails for hot-reloading
|
||
if (
|
||
!isPlatformReservedTag(node.tag) &&
|
||
node.tag !== 'slot' &&
|
||
node.attrsMap['inline-template'] == null
|
||
) {
|
||
return
|
||
}
|
||
for (var i = 0, l = node.children.length; i < l; i++) {
|
||
var child = node.children[i];
|
||
markStatic$1(child);
|
||
if (!child.static) {
|
||
node.static = false;
|
||
}
|
||
}
|
||
if (node.ifConditions) {
|
||
for (var i$1 = 1, l$1 = node.ifConditions.length; i$1 < l$1; i$1++) {
|
||
var block = node.ifConditions[i$1].block;
|
||
markStatic$1(block);
|
||
if (!block.static) {
|
||
node.static = false;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
function markStaticRoots (node, isInFor) {
|
||
if (node.type === 1) {
|
||
if (node.static || node.once) {
|
||
node.staticInFor = isInFor;
|
||
}
|
||
// For a node to qualify as a static root, it should have children that
|
||
// are not just static text. Otherwise the cost of hoisting out will
|
||
// outweigh the benefits and it's better off to just always render it fresh.
|
||
if (node.static && node.children.length && !(
|
||
node.children.length === 1 &&
|
||
node.children[0].type === 3
|
||
)) {
|
||
node.staticRoot = true;
|
||
return
|
||
} else {
|
||
node.staticRoot = false;
|
||
}
|
||
if (node.children) {
|
||
for (var i = 0, l = node.children.length; i < l; i++) {
|
||
markStaticRoots(node.children[i], isInFor || !!node.for);
|
||
}
|
||
}
|
||
if (node.ifConditions) {
|
||
for (var i$1 = 1, l$1 = node.ifConditions.length; i$1 < l$1; i$1++) {
|
||
markStaticRoots(node.ifConditions[i$1].block, isInFor);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
function isStatic (node) {
|
||
if (node.type === 2) { // expression
|
||
return false
|
||
}
|
||
if (node.type === 3) { // text
|
||
return true
|
||
}
|
||
return !!(node.pre || (
|
||
!node.hasBindings && // no dynamic bindings
|
||
!node.if && !node.for && // not v-if or v-for or v-else
|
||
!isBuiltInTag(node.tag) && // not a built-in
|
||
isPlatformReservedTag(node.tag) && // not a component
|
||
!isDirectChildOfTemplateFor(node) &&
|
||
Object.keys(node).every(isStaticKey)
|
||
))
|
||
}
|
||
|
||
function isDirectChildOfTemplateFor (node) {
|
||
while (node.parent) {
|
||
node = node.parent;
|
||
if (node.tag !== 'template') {
|
||
return false
|
||
}
|
||
if (node.for) {
|
||
return true
|
||
}
|
||
}
|
||
return false
|
||
}
|
||
|
||
/* */
|
||
|
||
var fnExpRE = /^\s*([\w$_]+|\([^)]*?\))\s*=>|^function\s*\(/;
|
||
var simplePathRE = /^\s*[A-Za-z_$][\w$]*(?:\.[A-Za-z_$][\w$]*|\['.*?']|\[".*?"]|\[\d+]|\[[A-Za-z_$][\w$]*])*\s*$/;
|
||
|
||
// keyCode aliases
|
||
var keyCodes = {
|
||
esc: 27,
|
||
tab: 9,
|
||
enter: 13,
|
||
space: 32,
|
||
up: 38,
|
||
left: 37,
|
||
right: 39,
|
||
down: 40,
|
||
'delete': [8, 46]
|
||
};
|
||
|
||
// #4868: modifiers that prevent the execution of the listener
|
||
// need to explicitly return null so that we can determine whether to remove
|
||
// the listener for .once
|
||
var genGuard = function (condition) { return ("if(" + condition + ")return null;"); };
|
||
|
||
var modifierCode = {
|
||
stop: '$event.stopPropagation();',
|
||
prevent: '$event.preventDefault();',
|
||
self: genGuard("$event.target !== $event.currentTarget"),
|
||
ctrl: genGuard("!$event.ctrlKey"),
|
||
shift: genGuard("!$event.shiftKey"),
|
||
alt: genGuard("!$event.altKey"),
|
||
meta: genGuard("!$event.metaKey"),
|
||
left: genGuard("'button' in $event && $event.button !== 0"),
|
||
middle: genGuard("'button' in $event && $event.button !== 1"),
|
||
right: genGuard("'button' in $event && $event.button !== 2")
|
||
};
|
||
|
||
function genHandlers (
|
||
events,
|
||
isNative,
|
||
warn
|
||
) {
|
||
var res = isNative ? 'nativeOn:{' : 'on:{';
|
||
for (var name in events) {
|
||
var handler = events[name];
|
||
// #5330: warn click.right, since right clicks do not actually fire click events.
|
||
if ("development" !== 'production' &&
|
||
name === 'click' &&
|
||
handler && handler.modifiers && handler.modifiers.right
|
||
) {
|
||
warn(
|
||
"Use \"contextmenu\" instead of \"click.right\" since right clicks " +
|
||
"do not actually fire \"click\" events."
|
||
);
|
||
}
|
||
res += "\"" + name + "\":" + (genHandler(name, handler)) + ",";
|
||
}
|
||
return res.slice(0, -1) + '}'
|
||
}
|
||
|
||
function genHandler (
|
||
name,
|
||
handler
|
||
) {
|
||
if (!handler) {
|
||
return 'function(){}'
|
||
}
|
||
|
||
if (Array.isArray(handler)) {
|
||
return ("[" + (handler.map(function (handler) { return genHandler(name, handler); }).join(',')) + "]")
|
||
}
|
||
|
||
var isMethodPath = simplePathRE.test(handler.value);
|
||
var isFunctionExpression = fnExpRE.test(handler.value);
|
||
|
||
if (!handler.modifiers) {
|
||
return isMethodPath || isFunctionExpression
|
||
? handler.value
|
||
: ("function($event){" + (handler.value) + "}") // inline statement
|
||
} else {
|
||
var code = '';
|
||
var genModifierCode = '';
|
||
var keys = [];
|
||
for (var key in handler.modifiers) {
|
||
if (modifierCode[key]) {
|
||
genModifierCode += modifierCode[key];
|
||
// left/right
|
||
if (keyCodes[key]) {
|
||
keys.push(key);
|
||
}
|
||
} else {
|
||
keys.push(key);
|
||
}
|
||
}
|
||
if (keys.length) {
|
||
code += genKeyFilter(keys);
|
||
}
|
||
// Make sure modifiers like prevent and stop get executed after key filtering
|
||
if (genModifierCode) {
|
||
code += genModifierCode;
|
||
}
|
||
var handlerCode = isMethodPath
|
||
? handler.value + '($event)'
|
||
: isFunctionExpression
|
||
? ("(" + (handler.value) + ")($event)")
|
||
: handler.value;
|
||
return ("function($event){" + code + handlerCode + "}")
|
||
}
|
||
}
|
||
|
||
function genKeyFilter (keys) {
|
||
return ("if(!('button' in $event)&&" + (keys.map(genFilterCode).join('&&')) + ")return null;")
|
||
}
|
||
|
||
function genFilterCode (key) {
|
||
var keyVal = parseInt(key, 10);
|
||
if (keyVal) {
|
||
return ("$event.keyCode!==" + keyVal)
|
||
}
|
||
var alias = keyCodes[key];
|
||
return ("_k($event.keyCode," + (JSON.stringify(key)) + (alias ? ',' + JSON.stringify(alias) : '') + ")")
|
||
}
|
||
|
||
/* */
|
||
|
||
function on (el, dir) {
|
||
if ("development" !== 'production' && dir.modifiers) {
|
||
warn("v-on without argument does not support modifiers.");
|
||
}
|
||
el.wrapListeners = function (code) { return ("_g(" + code + "," + (dir.value) + ")"); };
|
||
}
|
||
|
||
/* */
|
||
|
||
function bind$1 (el, dir) {
|
||
el.wrapData = function (code) {
|
||
return ("_b(" + code + ",'" + (el.tag) + "'," + (dir.value) + "," + (dir.modifiers && dir.modifiers.prop ? 'true' : 'false') + (dir.modifiers && dir.modifiers.sync ? ',true' : '') + ")")
|
||
};
|
||
}
|
||
|
||
/* */
|
||
|
||
var baseDirectives = {
|
||
on: on,
|
||
bind: bind$1,
|
||
cloak: noop
|
||
};
|
||
|
||
/* */
|
||
|
||
var CodegenState = function CodegenState (options) {
|
||
this.options = options;
|
||
this.warn = options.warn || baseWarn;
|
||
this.transforms = pluckModuleFunction(options.modules, 'transformCode');
|
||
this.dataGenFns = pluckModuleFunction(options.modules, 'genData');
|
||
this.directives = extend(extend({}, baseDirectives), options.directives);
|
||
var isReservedTag = options.isReservedTag || no;
|
||
this.maybeComponent = function (el) { return !isReservedTag(el.tag); };
|
||
this.onceId = 0;
|
||
this.staticRenderFns = [];
|
||
};
|
||
|
||
|
||
|
||
function generate (
|
||
ast,
|
||
options
|
||
) {
|
||
var state = new CodegenState(options);
|
||
var code = ast ? genElement(ast, state) : '_c("div")';
|
||
return {
|
||
render: ("with(this){return " + code + "}"),
|
||
staticRenderFns: state.staticRenderFns
|
||
}
|
||
}
|
||
|
||
function genElement (el, state) {
|
||
if (el.staticRoot && !el.staticProcessed) {
|
||
return genStatic(el, state)
|
||
} else if (el.once && !el.onceProcessed) {
|
||
return genOnce(el, state)
|
||
} else if (el.for && !el.forProcessed) {
|
||
return genFor(el, state)
|
||
} else if (el.if && !el.ifProcessed) {
|
||
return genIf(el, state)
|
||
} else if (el.tag === 'template' && !el.slotTarget) {
|
||
return genChildren(el, state) || 'void 0'
|
||
} else if (el.tag === 'slot') {
|
||
return genSlot(el, state)
|
||
} else {
|
||
// component or element
|
||
var code;
|
||
if (el.component) {
|
||
code = genComponent(el.component, el, state);
|
||
} else {
|
||
var data = el.plain ? undefined : genData$2(el, state);
|
||
|
||
var children = el.inlineTemplate ? null : genChildren(el, state, true);
|
||
code = "_c('" + (el.tag) + "'" + (data ? ("," + data) : '') + (children ? ("," + children) : '') + ")";
|
||
}
|
||
// module transforms
|
||
for (var i = 0; i < state.transforms.length; i++) {
|
||
code = state.transforms[i](el, code);
|
||
}
|
||
return code
|
||
}
|
||
}
|
||
|
||
// hoist static sub-trees out
|
||
function genStatic (el, state) {
|
||
el.staticProcessed = true;
|
||
state.staticRenderFns.push(("with(this){return " + (genElement(el, state)) + "}"));
|
||
return ("_m(" + (state.staticRenderFns.length - 1) + (el.staticInFor ? ',true' : '') + ")")
|
||
}
|
||
|
||
// v-once
|
||
function genOnce (el, state) {
|
||
el.onceProcessed = true;
|
||
if (el.if && !el.ifProcessed) {
|
||
return genIf(el, state)
|
||
} else if (el.staticInFor) {
|
||
var key = '';
|
||
var parent = el.parent;
|
||
while (parent) {
|
||
if (parent.for) {
|
||
key = parent.key;
|
||
break
|
||
}
|
||
parent = parent.parent;
|
||
}
|
||
if (!key) {
|
||
"development" !== 'production' && state.warn(
|
||
"v-once can only be used inside v-for that is keyed. "
|
||
);
|
||
return genElement(el, state)
|
||
}
|
||
return ("_o(" + (genElement(el, state)) + "," + (state.onceId++) + "," + key + ")")
|
||
} else {
|
||
return genStatic(el, state)
|
||
}
|
||
}
|
||
|
||
function genIf (
|
||
el,
|
||
state,
|
||
altGen,
|
||
altEmpty
|
||
) {
|
||
el.ifProcessed = true; // avoid recursion
|
||
return genIfConditions(el.ifConditions.slice(), state, altGen, altEmpty)
|
||
}
|
||
|
||
function genIfConditions (
|
||
conditions,
|
||
state,
|
||
altGen,
|
||
altEmpty
|
||
) {
|
||
if (!conditions.length) {
|
||
return altEmpty || '_e()'
|
||
}
|
||
|
||
var condition = conditions.shift();
|
||
if (condition.exp) {
|
||
return ("(" + (condition.exp) + ")?" + (genTernaryExp(condition.block)) + ":" + (genIfConditions(conditions, state, altGen, altEmpty)))
|
||
} else {
|
||
return ("" + (genTernaryExp(condition.block)))
|
||
}
|
||
|
||
// v-if with v-once should generate code like (a)?_m(0):_m(1)
|
||
function genTernaryExp (el) {
|
||
return altGen
|
||
? altGen(el, state)
|
||
: el.once
|
||
? genOnce(el, state)
|
||
: genElement(el, state)
|
||
}
|
||
}
|
||
|
||
function genFor (
|
||
el,
|
||
state,
|
||
altGen,
|
||
altHelper
|
||
) {
|
||
var exp = el.for;
|
||
var alias = el.alias;
|
||
var iterator1 = el.iterator1 ? ("," + (el.iterator1)) : '';
|
||
var iterator2 = el.iterator2 ? ("," + (el.iterator2)) : '';
|
||
|
||
if ("development" !== 'production' &&
|
||
state.maybeComponent(el) &&
|
||
el.tag !== 'slot' &&
|
||
el.tag !== 'template' &&
|
||
!el.key
|
||
) {
|
||
state.warn(
|
||
"<" + (el.tag) + " v-for=\"" + alias + " in " + exp + "\">: component lists rendered with " +
|
||
"v-for should have explicit keys. " +
|
||
"See https://vuejs.org/guide/list.html#key for more info.",
|
||
true /* tip */
|
||
);
|
||
}
|
||
|
||
el.forProcessed = true; // avoid recursion
|
||
return (altHelper || '_l') + "((" + exp + ")," +
|
||
"function(" + alias + iterator1 + iterator2 + "){" +
|
||
"return " + ((altGen || genElement)(el, state)) +
|
||
'})'
|
||
}
|
||
|
||
function genData$2 (el, state) {
|
||
var data = '{';
|
||
|
||
// directives first.
|
||
// directives may mutate the el's other properties before they are generated.
|
||
var dirs = genDirectives(el, state);
|
||
if (dirs) { data += dirs + ','; }
|
||
|
||
// key
|
||
if (el.key) {
|
||
data += "key:" + (el.key) + ",";
|
||
}
|
||
// ref
|
||
if (el.ref) {
|
||
data += "ref:" + (el.ref) + ",";
|
||
}
|
||
if (el.refInFor) {
|
||
data += "refInFor:true,";
|
||
}
|
||
// pre
|
||
if (el.pre) {
|
||
data += "pre:true,";
|
||
}
|
||
// record original tag name for components using "is" attribute
|
||
if (el.component) {
|
||
data += "tag:\"" + (el.tag) + "\",";
|
||
}
|
||
// module data generation functions
|
||
for (var i = 0; i < state.dataGenFns.length; i++) {
|
||
data += state.dataGenFns[i](el);
|
||
}
|
||
// attributes
|
||
if (el.attrs) {
|
||
data += "attrs:{" + (genProps(el.attrs)) + "},";
|
||
}
|
||
// DOM props
|
||
if (el.props) {
|
||
data += "domProps:{" + (genProps(el.props)) + "},";
|
||
}
|
||
// event handlers
|
||
if (el.events) {
|
||
data += (genHandlers(el.events, false, state.warn)) + ",";
|
||
}
|
||
if (el.nativeEvents) {
|
||
data += (genHandlers(el.nativeEvents, true, state.warn)) + ",";
|
||
}
|
||
// slot target
|
||
if (el.slotTarget) {
|
||
data += "slot:" + (el.slotTarget) + ",";
|
||
}
|
||
// scoped slots
|
||
if (el.scopedSlots) {
|
||
data += (genScopedSlots(el.scopedSlots, state)) + ",";
|
||
}
|
||
// component v-model
|
||
if (el.model) {
|
||
data += "model:{value:" + (el.model.value) + ",callback:" + (el.model.callback) + ",expression:" + (el.model.expression) + "},";
|
||
}
|
||
// inline-template
|
||
if (el.inlineTemplate) {
|
||
var inlineTemplate = genInlineTemplate(el, state);
|
||
if (inlineTemplate) {
|
||
data += inlineTemplate + ",";
|
||
}
|
||
}
|
||
data = data.replace(/,$/, '') + '}';
|
||
// v-bind data wrap
|
||
if (el.wrapData) {
|
||
data = el.wrapData(data);
|
||
}
|
||
// v-on data wrap
|
||
if (el.wrapListeners) {
|
||
data = el.wrapListeners(data);
|
||
}
|
||
return data
|
||
}
|
||
|
||
function genDirectives (el, state) {
|
||
var dirs = el.directives;
|
||
if (!dirs) { return }
|
||
var res = 'directives:[';
|
||
var hasRuntime = false;
|
||
var i, l, dir, needRuntime;
|
||
for (i = 0, l = dirs.length; i < l; i++) {
|
||
dir = dirs[i];
|
||
needRuntime = true;
|
||
var gen = state.directives[dir.name];
|
||
if (gen) {
|
||
// compile-time directive that manipulates AST.
|
||
// returns true if it also needs a runtime counterpart.
|
||
needRuntime = !!gen(el, dir, state.warn);
|
||
}
|
||
if (needRuntime) {
|
||
hasRuntime = true;
|
||
res += "{name:\"" + (dir.name) + "\",rawName:\"" + (dir.rawName) + "\"" + (dir.value ? (",value:(" + (dir.value) + "),expression:" + (JSON.stringify(dir.value))) : '') + (dir.arg ? (",arg:\"" + (dir.arg) + "\"") : '') + (dir.modifiers ? (",modifiers:" + (JSON.stringify(dir.modifiers))) : '') + "},";
|
||
}
|
||
}
|
||
if (hasRuntime) {
|
||
return res.slice(0, -1) + ']'
|
||
}
|
||
}
|
||
|
||
function genInlineTemplate (el, state) {
|
||
var ast = el.children[0];
|
||
if ("development" !== 'production' && (
|
||
el.children.length > 1 || ast.type !== 1
|
||
)) {
|
||
state.warn('Inline-template components must have exactly one child element.');
|
||
}
|
||
if (ast.type === 1) {
|
||
var inlineRenderFns = generate(ast, state.options);
|
||
return ("inlineTemplate:{render:function(){" + (inlineRenderFns.render) + "},staticRenderFns:[" + (inlineRenderFns.staticRenderFns.map(function (code) { return ("function(){" + code + "}"); }).join(',')) + "]}")
|
||
}
|
||
}
|
||
|
||
function genScopedSlots (
|
||
slots,
|
||
state
|
||
) {
|
||
return ("scopedSlots:_u([" + (Object.keys(slots).map(function (key) {
|
||
return genScopedSlot(key, slots[key], state)
|
||
}).join(',')) + "])")
|
||
}
|
||
|
||
function genScopedSlot (
|
||
key,
|
||
el,
|
||
state
|
||
) {
|
||
if (el.for && !el.forProcessed) {
|
||
return genForScopedSlot(key, el, state)
|
||
}
|
||
return "{key:" + key + ",fn:function(" + (String(el.attrsMap.scope)) + "){" +
|
||
"return " + (el.tag === 'template'
|
||
? genChildren(el, state) || 'void 0'
|
||
: genElement(el, state)) + "}}"
|
||
}
|
||
|
||
function genForScopedSlot (
|
||
key,
|
||
el,
|
||
state
|
||
) {
|
||
var exp = el.for;
|
||
var alias = el.alias;
|
||
var iterator1 = el.iterator1 ? ("," + (el.iterator1)) : '';
|
||
var iterator2 = el.iterator2 ? ("," + (el.iterator2)) : '';
|
||
el.forProcessed = true; // avoid recursion
|
||
return "_l((" + exp + ")," +
|
||
"function(" + alias + iterator1 + iterator2 + "){" +
|
||
"return " + (genScopedSlot(key, el, state)) +
|
||
'})'
|
||
}
|
||
|
||
function genChildren (
|
||
el,
|
||
state,
|
||
checkSkip,
|
||
altGenElement,
|
||
altGenNode
|
||
) {
|
||
var children = el.children;
|
||
if (children.length) {
|
||
var el$1 = children[0];
|
||
// optimize single v-for
|
||
if (children.length === 1 &&
|
||
el$1.for &&
|
||
el$1.tag !== 'template' &&
|
||
el$1.tag !== 'slot'
|
||
) {
|
||
return (altGenElement || genElement)(el$1, state)
|
||
}
|
||
var normalizationType = checkSkip
|
||
? getNormalizationType(children, state.maybeComponent)
|
||
: 0;
|
||
var gen = altGenNode || genNode;
|
||
return ("[" + (children.map(function (c) { return gen(c, state); }).join(',')) + "]" + (normalizationType ? ("," + normalizationType) : ''))
|
||
}
|
||
}
|
||
|
||
// determine the normalization needed for the children array.
|
||
// 0: no normalization needed
|
||
// 1: simple normalization needed (possible 1-level deep nested array)
|
||
// 2: full normalization needed
|
||
function getNormalizationType (
|
||
children,
|
||
maybeComponent
|
||
) {
|
||
var res = 0;
|
||
for (var i = 0; i < children.length; i++) {
|
||
var el = children[i];
|
||
if (el.type !== 1) {
|
||
continue
|
||
}
|
||
if (needsNormalization(el) ||
|
||
(el.ifConditions && el.ifConditions.some(function (c) { return needsNormalization(c.block); }))) {
|
||
res = 2;
|
||
break
|
||
}
|
||
if (maybeComponent(el) ||
|
||
(el.ifConditions && el.ifConditions.some(function (c) { return maybeComponent(c.block); }))) {
|
||
res = 1;
|
||
}
|
||
}
|
||
return res
|
||
}
|
||
|
||
function needsNormalization (el) {
|
||
return el.for !== undefined || el.tag === 'template' || el.tag === 'slot'
|
||
}
|
||
|
||
function genNode (node, state) {
|
||
if (node.type === 1) {
|
||
return genElement(node, state)
|
||
} if (node.type === 3 && node.isComment) {
|
||
return genComment(node)
|
||
} else {
|
||
return genText(node)
|
||
}
|
||
}
|
||
|
||
function genText (text) {
|
||
return ("_v(" + (text.type === 2
|
||
? text.expression // no need for () because already wrapped in _s()
|
||
: transformSpecialNewlines(JSON.stringify(text.text))) + ")")
|
||
}
|
||
|
||
function genComment (comment) {
|
||
return ("_e(" + (JSON.stringify(comment.text)) + ")")
|
||
}
|
||
|
||
function genSlot (el, state) {
|
||
var slotName = el.slotName || '"default"';
|
||
var children = genChildren(el, state);
|
||
var res = "_t(" + slotName + (children ? ("," + children) : '');
|
||
var attrs = el.attrs && ("{" + (el.attrs.map(function (a) { return ((camelize(a.name)) + ":" + (a.value)); }).join(',')) + "}");
|
||
var bind$$1 = el.attrsMap['v-bind'];
|
||
if ((attrs || bind$$1) && !children) {
|
||
res += ",null";
|
||
}
|
||
if (attrs) {
|
||
res += "," + attrs;
|
||
}
|
||
if (bind$$1) {
|
||
res += (attrs ? '' : ',null') + "," + bind$$1;
|
||
}
|
||
return res + ')'
|
||
}
|
||
|
||
// componentName is el.component, take it as argument to shun flow's pessimistic refinement
|
||
function genComponent (
|
||
componentName,
|
||
el,
|
||
state
|
||
) {
|
||
var children = el.inlineTemplate ? null : genChildren(el, state, true);
|
||
return ("_c(" + componentName + "," + (genData$2(el, state)) + (children ? ("," + children) : '') + ")")
|
||
}
|
||
|
||
function genProps (props) {
|
||
var res = '';
|
||
for (var i = 0; i < props.length; i++) {
|
||
var prop = props[i];
|
||
res += "\"" + (prop.name) + "\":" + (transformSpecialNewlines(prop.value)) + ",";
|
||
}
|
||
return res.slice(0, -1)
|
||
}
|
||
|
||
// #3895, #4268
|
||
function transformSpecialNewlines (text) {
|
||
return text
|
||
.replace(/\u2028/g, '\\u2028')
|
||
.replace(/\u2029/g, '\\u2029')
|
||
}
|
||
|
||
/* */
|
||
|
||
// these keywords should not appear inside expressions, but operators like
|
||
// typeof, instanceof and in are allowed
|
||
var prohibitedKeywordRE = new RegExp('\\b' + (
|
||
'do,if,for,let,new,try,var,case,else,with,await,break,catch,class,const,' +
|
||
'super,throw,while,yield,delete,export,import,return,switch,default,' +
|
||
'extends,finally,continue,debugger,function,arguments'
|
||
).split(',').join('\\b|\\b') + '\\b');
|
||
|
||
// these unary operators should not be used as property/method names
|
||
var unaryOperatorsRE = new RegExp('\\b' + (
|
||
'delete,typeof,void'
|
||
).split(',').join('\\s*\\([^\\)]*\\)|\\b') + '\\s*\\([^\\)]*\\)');
|
||
|
||
// check valid identifier for v-for
|
||
var identRE = /[A-Za-z_$][\w$]*/;
|
||
|
||
// strip strings in expressions
|
||
var stripStringRE = /'(?:[^'\\]|\\.)*'|"(?:[^"\\]|\\.)*"|`(?:[^`\\]|\\.)*\$\{|\}(?:[^`\\]|\\.)*`|`(?:[^`\\]|\\.)*`/g;
|
||
|
||
// detect problematic expressions in a template
|
||
function detectErrors (ast) {
|
||
var errors = [];
|
||
if (ast) {
|
||
checkNode(ast, errors);
|
||
}
|
||
return errors
|
||
}
|
||
|
||
function checkNode (node, errors) {
|
||
if (node.type === 1) {
|
||
for (var name in node.attrsMap) {
|
||
if (dirRE.test(name)) {
|
||
var value = node.attrsMap[name];
|
||
if (value) {
|
||
if (name === 'v-for') {
|
||
checkFor(node, ("v-for=\"" + value + "\""), errors);
|
||
} else if (onRE.test(name)) {
|
||
checkEvent(value, (name + "=\"" + value + "\""), errors);
|
||
} else {
|
||
checkExpression(value, (name + "=\"" + value + "\""), errors);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
if (node.children) {
|
||
for (var i = 0; i < node.children.length; i++) {
|
||
checkNode(node.children[i], errors);
|
||
}
|
||
}
|
||
} else if (node.type === 2) {
|
||
checkExpression(node.expression, node.text, errors);
|
||
}
|
||
}
|
||
|
||
function checkEvent (exp, text, errors) {
|
||
var stipped = exp.replace(stripStringRE, '');
|
||
var keywordMatch = stipped.match(unaryOperatorsRE);
|
||
if (keywordMatch && stipped.charAt(keywordMatch.index - 1) !== '$') {
|
||
errors.push(
|
||
"avoid using JavaScript unary operator as property name: " +
|
||
"\"" + (keywordMatch[0]) + "\" in expression " + (text.trim())
|
||
);
|
||
}
|
||
checkExpression(exp, text, errors);
|
||
}
|
||
|
||
function checkFor (node, text, errors) {
|
||
checkExpression(node.for || '', text, errors);
|
||
checkIdentifier(node.alias, 'v-for alias', text, errors);
|
||
checkIdentifier(node.iterator1, 'v-for iterator', text, errors);
|
||
checkIdentifier(node.iterator2, 'v-for iterator', text, errors);
|
||
}
|
||
|
||
function checkIdentifier (ident, type, text, errors) {
|
||
if (typeof ident === 'string' && !identRE.test(ident)) {
|
||
errors.push(("invalid " + type + " \"" + ident + "\" in expression: " + (text.trim())));
|
||
}
|
||
}
|
||
|
||
function checkExpression (exp, text, errors) {
|
||
try {
|
||
new Function(("return " + exp));
|
||
} catch (e) {
|
||
var keywordMatch = exp.replace(stripStringRE, '').match(prohibitedKeywordRE);
|
||
if (keywordMatch) {
|
||
errors.push(
|
||
"avoid using JavaScript keyword as property name: " +
|
||
"\"" + (keywordMatch[0]) + "\" in expression " + (text.trim())
|
||
);
|
||
} else {
|
||
errors.push(("invalid expression: " + (text.trim())));
|
||
}
|
||
}
|
||
}
|
||
|
||
/* */
|
||
|
||
function createFunction (code, errors) {
|
||
try {
|
||
return new Function(code)
|
||
} catch (err) {
|
||
errors.push({ err: err, code: code });
|
||
return noop
|
||
}
|
||
}
|
||
|
||
function createCompileToFunctionFn (compile) {
|
||
var cache = Object.create(null);
|
||
|
||
return function compileToFunctions (
|
||
template,
|
||
options,
|
||
vm
|
||
) {
|
||
options = options || {};
|
||
|
||
/* istanbul ignore if */
|
||
if (true) {
|
||
// detect possible CSP restriction
|
||
try {
|
||
new Function('return 1');
|
||
} catch (e) {
|
||
if (e.toString().match(/unsafe-eval|CSP/)) {
|
||
warn(
|
||
'It seems you are using the standalone build of Vue.js in an ' +
|
||
'environment with Content Security Policy that prohibits unsafe-eval. ' +
|
||
'The template compiler cannot work in this environment. Consider ' +
|
||
'relaxing the policy to allow unsafe-eval or pre-compiling your ' +
|
||
'templates into render functions.'
|
||
);
|
||
}
|
||
}
|
||
}
|
||
|
||
// check cache
|
||
var key = options.delimiters
|
||
? String(options.delimiters) + template
|
||
: template;
|
||
if (cache[key]) {
|
||
return cache[key]
|
||
}
|
||
|
||
// compile
|
||
var compiled = compile(template, options);
|
||
|
||
// check compilation errors/tips
|
||
if (true) {
|
||
if (compiled.errors && compiled.errors.length) {
|
||
warn(
|
||
"Error compiling template:\n\n" + template + "\n\n" +
|
||
compiled.errors.map(function (e) { return ("- " + e); }).join('\n') + '\n',
|
||
vm
|
||
);
|
||
}
|
||
if (compiled.tips && compiled.tips.length) {
|
||
compiled.tips.forEach(function (msg) { return tip(msg, vm); });
|
||
}
|
||
}
|
||
|
||
// turn code into functions
|
||
var res = {};
|
||
var fnGenErrors = [];
|
||
res.render = createFunction(compiled.render, fnGenErrors);
|
||
res.staticRenderFns = compiled.staticRenderFns.map(function (code) {
|
||
return createFunction(code, fnGenErrors)
|
||
});
|
||
|
||
// check function generation errors.
|
||
// this should only happen if there is a bug in the compiler itself.
|
||
// mostly for codegen development use
|
||
/* istanbul ignore if */
|
||
if (true) {
|
||
if ((!compiled.errors || !compiled.errors.length) && fnGenErrors.length) {
|
||
warn(
|
||
"Failed to generate render function:\n\n" +
|
||
fnGenErrors.map(function (ref) {
|
||
var err = ref.err;
|
||
var code = ref.code;
|
||
|
||
return ((err.toString()) + " in\n\n" + code + "\n");
|
||
}).join('\n'),
|
||
vm
|
||
);
|
||
}
|
||
}
|
||
|
||
return (cache[key] = res)
|
||
}
|
||
}
|
||
|
||
/* */
|
||
|
||
function createCompilerCreator (baseCompile) {
|
||
return function createCompiler (baseOptions) {
|
||
function compile (
|
||
template,
|
||
options
|
||
) {
|
||
var finalOptions = Object.create(baseOptions);
|
||
var errors = [];
|
||
var tips = [];
|
||
finalOptions.warn = function (msg, tip) {
|
||
(tip ? tips : errors).push(msg);
|
||
};
|
||
|
||
if (options) {
|
||
// merge custom modules
|
||
if (options.modules) {
|
||
finalOptions.modules =
|
||
(baseOptions.modules || []).concat(options.modules);
|
||
}
|
||
// merge custom directives
|
||
if (options.directives) {
|
||
finalOptions.directives = extend(
|
||
Object.create(baseOptions.directives),
|
||
options.directives
|
||
);
|
||
}
|
||
// copy other options
|
||
for (var key in options) {
|
||
if (key !== 'modules' && key !== 'directives') {
|
||
finalOptions[key] = options[key];
|
||
}
|
||
}
|
||
}
|
||
|
||
var compiled = baseCompile(template, finalOptions);
|
||
if (true) {
|
||
errors.push.apply(errors, detectErrors(compiled.ast));
|
||
}
|
||
compiled.errors = errors;
|
||
compiled.tips = tips;
|
||
return compiled
|
||
}
|
||
|
||
return {
|
||
compile: compile,
|
||
compileToFunctions: createCompileToFunctionFn(compile)
|
||
}
|
||
}
|
||
}
|
||
|
||
/* */
|
||
|
||
// `createCompilerCreator` allows creating compilers that use alternative
|
||
// parser/optimizer/codegen, e.g the SSR optimizing compiler.
|
||
// Here we just export a default compiler using the default parts.
|
||
var createCompiler = createCompilerCreator(function baseCompile (
|
||
template,
|
||
options
|
||
) {
|
||
var ast = parse(template.trim(), options);
|
||
optimize(ast, options);
|
||
var code = generate(ast, options);
|
||
return {
|
||
ast: ast,
|
||
render: code.render,
|
||
staticRenderFns: code.staticRenderFns
|
||
}
|
||
});
|
||
|
||
/* */
|
||
|
||
var ref$1 = createCompiler(baseOptions);
|
||
var compileToFunctions = ref$1.compileToFunctions;
|
||
|
||
/* */
|
||
|
||
var idToTemplate = cached(function (id) {
|
||
var el = query(id);
|
||
return el && el.innerHTML
|
||
});
|
||
|
||
var mount = Vue$3.prototype.$mount;
|
||
Vue$3.prototype.$mount = function (
|
||
el,
|
||
hydrating
|
||
) {
|
||
el = el && query(el);
|
||
|
||
/* istanbul ignore if */
|
||
if (el === document.body || el === document.documentElement) {
|
||
"development" !== 'production' && warn(
|
||
"Do not mount Vue to <html> or <body> - mount to normal elements instead."
|
||
);
|
||
return this
|
||
}
|
||
|
||
var options = this.$options;
|
||
// resolve template/el and convert to render function
|
||
if (!options.render) {
|
||
var template = options.template;
|
||
if (template) {
|
||
if (typeof template === 'string') {
|
||
if (template.charAt(0) === '#') {
|
||
template = idToTemplate(template);
|
||
/* istanbul ignore if */
|
||
if ("development" !== 'production' && !template) {
|
||
warn(
|
||
("Template element not found or is empty: " + (options.template)),
|
||
this
|
||
);
|
||
}
|
||
}
|
||
} else if (template.nodeType) {
|
||
template = template.innerHTML;
|
||
} else {
|
||
if (true) {
|
||
warn('invalid template option:' + template, this);
|
||
}
|
||
return this
|
||
}
|
||
} else if (el) {
|
||
template = getOuterHTML(el);
|
||
}
|
||
if (template) {
|
||
/* istanbul ignore if */
|
||
if ("development" !== 'production' && config.performance && mark) {
|
||
mark('compile');
|
||
}
|
||
|
||
var ref = compileToFunctions(template, {
|
||
shouldDecodeNewlines: shouldDecodeNewlines,
|
||
delimiters: options.delimiters,
|
||
comments: options.comments
|
||
}, this);
|
||
var render = ref.render;
|
||
var staticRenderFns = ref.staticRenderFns;
|
||
options.render = render;
|
||
options.staticRenderFns = staticRenderFns;
|
||
|
||
/* istanbul ignore if */
|
||
if ("development" !== 'production' && config.performance && mark) {
|
||
mark('compile end');
|
||
measure(((this._name) + " compile"), 'compile', 'compile end');
|
||
}
|
||
}
|
||
}
|
||
return mount.call(this, el, hydrating)
|
||
};
|
||
|
||
/**
|
||
* Get outerHTML of elements, taking care
|
||
* of SVG elements in IE as well.
|
||
*/
|
||
function getOuterHTML (el) {
|
||
if (el.outerHTML) {
|
||
return el.outerHTML
|
||
} else {
|
||
var container = document.createElement('div');
|
||
container.appendChild(el.cloneNode(true));
|
||
return container.innerHTML
|
||
}
|
||
}
|
||
|
||
Vue$3.compile = compileToFunctions;
|
||
|
||
module.exports = Vue$3;
|
||
|
||
/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(4)))
|
||
|
||
/***/ }),
|
||
/* 13 */
|
||
/***/ (function(module, __webpack_exports__, __webpack_require__) {
|
||
|
||
"use strict";
|
||
Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
|
||
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Url", function() { return Url; });
|
||
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Http", function() { return Http; });
|
||
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Resource", function() { return Resource; });
|
||
/*!
|
||
* vue-resource v1.3.4
|
||
* https://github.com/pagekit/vue-resource
|
||
* Released under the MIT License.
|
||
*/
|
||
|
||
/**
|
||
* Promises/A+ polyfill v1.1.4 (https://github.com/bramstein/promis)
|
||
*/
|
||
|
||
var RESOLVED = 0;
|
||
var REJECTED = 1;
|
||
var PENDING = 2;
|
||
|
||
function Promise$1(executor) {
|
||
|
||
this.state = PENDING;
|
||
this.value = undefined;
|
||
this.deferred = [];
|
||
|
||
var promise = this;
|
||
|
||
try {
|
||
executor(function (x) {
|
||
promise.resolve(x);
|
||
}, function (r) {
|
||
promise.reject(r);
|
||
});
|
||
} catch (e) {
|
||
promise.reject(e);
|
||
}
|
||
}
|
||
|
||
Promise$1.reject = function (r) {
|
||
return new Promise$1(function (resolve, reject) {
|
||
reject(r);
|
||
});
|
||
};
|
||
|
||
Promise$1.resolve = function (x) {
|
||
return new Promise$1(function (resolve, reject) {
|
||
resolve(x);
|
||
});
|
||
};
|
||
|
||
Promise$1.all = function all(iterable) {
|
||
return new Promise$1(function (resolve, reject) {
|
||
var count = 0, result = [];
|
||
|
||
if (iterable.length === 0) {
|
||
resolve(result);
|
||
}
|
||
|
||
function resolver(i) {
|
||
return function (x) {
|
||
result[i] = x;
|
||
count += 1;
|
||
|
||
if (count === iterable.length) {
|
||
resolve(result);
|
||
}
|
||
};
|
||
}
|
||
|
||
for (var i = 0; i < iterable.length; i += 1) {
|
||
Promise$1.resolve(iterable[i]).then(resolver(i), reject);
|
||
}
|
||
});
|
||
};
|
||
|
||
Promise$1.race = function race(iterable) {
|
||
return new Promise$1(function (resolve, reject) {
|
||
for (var i = 0; i < iterable.length; i += 1) {
|
||
Promise$1.resolve(iterable[i]).then(resolve, reject);
|
||
}
|
||
});
|
||
};
|
||
|
||
var p$1 = Promise$1.prototype;
|
||
|
||
p$1.resolve = function resolve(x) {
|
||
var promise = this;
|
||
|
||
if (promise.state === PENDING) {
|
||
if (x === promise) {
|
||
throw new TypeError('Promise settled with itself.');
|
||
}
|
||
|
||
var called = false;
|
||
|
||
try {
|
||
var then = x && x['then'];
|
||
|
||
if (x !== null && typeof x === 'object' && typeof then === 'function') {
|
||
then.call(x, function (x) {
|
||
if (!called) {
|
||
promise.resolve(x);
|
||
}
|
||
called = true;
|
||
|
||
}, function (r) {
|
||
if (!called) {
|
||
promise.reject(r);
|
||
}
|
||
called = true;
|
||
});
|
||
return;
|
||
}
|
||
} catch (e) {
|
||
if (!called) {
|
||
promise.reject(e);
|
||
}
|
||
return;
|
||
}
|
||
|
||
promise.state = RESOLVED;
|
||
promise.value = x;
|
||
promise.notify();
|
||
}
|
||
};
|
||
|
||
p$1.reject = function reject(reason) {
|
||
var promise = this;
|
||
|
||
if (promise.state === PENDING) {
|
||
if (reason === promise) {
|
||
throw new TypeError('Promise settled with itself.');
|
||
}
|
||
|
||
promise.state = REJECTED;
|
||
promise.value = reason;
|
||
promise.notify();
|
||
}
|
||
};
|
||
|
||
p$1.notify = function notify() {
|
||
var promise = this;
|
||
|
||
nextTick(function () {
|
||
if (promise.state !== PENDING) {
|
||
while (promise.deferred.length) {
|
||
var deferred = promise.deferred.shift(),
|
||
onResolved = deferred[0],
|
||
onRejected = deferred[1],
|
||
resolve = deferred[2],
|
||
reject = deferred[3];
|
||
|
||
try {
|
||
if (promise.state === RESOLVED) {
|
||
if (typeof onResolved === 'function') {
|
||
resolve(onResolved.call(undefined, promise.value));
|
||
} else {
|
||
resolve(promise.value);
|
||
}
|
||
} else if (promise.state === REJECTED) {
|
||
if (typeof onRejected === 'function') {
|
||
resolve(onRejected.call(undefined, promise.value));
|
||
} else {
|
||
reject(promise.value);
|
||
}
|
||
}
|
||
} catch (e) {
|
||
reject(e);
|
||
}
|
||
}
|
||
}
|
||
});
|
||
};
|
||
|
||
p$1.then = function then(onResolved, onRejected) {
|
||
var promise = this;
|
||
|
||
return new Promise$1(function (resolve, reject) {
|
||
promise.deferred.push([onResolved, onRejected, resolve, reject]);
|
||
promise.notify();
|
||
});
|
||
};
|
||
|
||
p$1.catch = function (onRejected) {
|
||
return this.then(undefined, onRejected);
|
||
};
|
||
|
||
/**
|
||
* Promise adapter.
|
||
*/
|
||
|
||
if (typeof Promise === 'undefined') {
|
||
window.Promise = Promise$1;
|
||
}
|
||
|
||
function PromiseObj(executor, context) {
|
||
|
||
if (executor instanceof Promise) {
|
||
this.promise = executor;
|
||
} else {
|
||
this.promise = new Promise(executor.bind(context));
|
||
}
|
||
|
||
this.context = context;
|
||
}
|
||
|
||
PromiseObj.all = function (iterable, context) {
|
||
return new PromiseObj(Promise.all(iterable), context);
|
||
};
|
||
|
||
PromiseObj.resolve = function (value, context) {
|
||
return new PromiseObj(Promise.resolve(value), context);
|
||
};
|
||
|
||
PromiseObj.reject = function (reason, context) {
|
||
return new PromiseObj(Promise.reject(reason), context);
|
||
};
|
||
|
||
PromiseObj.race = function (iterable, context) {
|
||
return new PromiseObj(Promise.race(iterable), context);
|
||
};
|
||
|
||
var p = PromiseObj.prototype;
|
||
|
||
p.bind = function (context) {
|
||
this.context = context;
|
||
return this;
|
||
};
|
||
|
||
p.then = function (fulfilled, rejected) {
|
||
|
||
if (fulfilled && fulfilled.bind && this.context) {
|
||
fulfilled = fulfilled.bind(this.context);
|
||
}
|
||
|
||
if (rejected && rejected.bind && this.context) {
|
||
rejected = rejected.bind(this.context);
|
||
}
|
||
|
||
return new PromiseObj(this.promise.then(fulfilled, rejected), this.context);
|
||
};
|
||
|
||
p.catch = function (rejected) {
|
||
|
||
if (rejected && rejected.bind && this.context) {
|
||
rejected = rejected.bind(this.context);
|
||
}
|
||
|
||
return new PromiseObj(this.promise.catch(rejected), this.context);
|
||
};
|
||
|
||
p.finally = function (callback) {
|
||
|
||
return this.then(function (value) {
|
||
callback.call(this);
|
||
return value;
|
||
}, function (reason) {
|
||
callback.call(this);
|
||
return Promise.reject(reason);
|
||
}
|
||
);
|
||
};
|
||
|
||
/**
|
||
* Utility functions.
|
||
*/
|
||
|
||
var ref = {};
|
||
var hasOwnProperty = ref.hasOwnProperty;
|
||
|
||
var ref$1 = [];
|
||
var slice = ref$1.slice;
|
||
var debug = false;
|
||
var ntick;
|
||
|
||
var inBrowser = typeof window !== 'undefined';
|
||
|
||
var Util = function (ref) {
|
||
var config = ref.config;
|
||
var nextTick = ref.nextTick;
|
||
|
||
ntick = nextTick;
|
||
debug = config.debug || !config.silent;
|
||
};
|
||
|
||
function warn(msg) {
|
||
if (typeof console !== 'undefined' && debug) {
|
||
console.warn('[VueResource warn]: ' + msg);
|
||
}
|
||
}
|
||
|
||
function error(msg) {
|
||
if (typeof console !== 'undefined') {
|
||
console.error(msg);
|
||
}
|
||
}
|
||
|
||
function nextTick(cb, ctx) {
|
||
return ntick(cb, ctx);
|
||
}
|
||
|
||
function trim(str) {
|
||
return str ? str.replace(/^\s*|\s*$/g, '') : '';
|
||
}
|
||
|
||
function trimEnd(str, chars) {
|
||
|
||
if (str && chars === undefined) {
|
||
return str.replace(/\s+$/, '');
|
||
}
|
||
|
||
if (!str || !chars) {
|
||
return str;
|
||
}
|
||
|
||
return str.replace(new RegExp(("[" + chars + "]+$")), '');
|
||
}
|
||
|
||
function toLower(str) {
|
||
return str ? str.toLowerCase() : '';
|
||
}
|
||
|
||
function toUpper(str) {
|
||
return str ? str.toUpperCase() : '';
|
||
}
|
||
|
||
var isArray = Array.isArray;
|
||
|
||
function isString(val) {
|
||
return typeof val === 'string';
|
||
}
|
||
|
||
|
||
|
||
function isFunction(val) {
|
||
return typeof val === 'function';
|
||
}
|
||
|
||
function isObject(obj) {
|
||
return obj !== null && typeof obj === 'object';
|
||
}
|
||
|
||
function isPlainObject(obj) {
|
||
return isObject(obj) && Object.getPrototypeOf(obj) == Object.prototype;
|
||
}
|
||
|
||
function isBlob(obj) {
|
||
return typeof Blob !== 'undefined' && obj instanceof Blob;
|
||
}
|
||
|
||
function isFormData(obj) {
|
||
return typeof FormData !== 'undefined' && obj instanceof FormData;
|
||
}
|
||
|
||
function when(value, fulfilled, rejected) {
|
||
|
||
var promise = PromiseObj.resolve(value);
|
||
|
||
if (arguments.length < 2) {
|
||
return promise;
|
||
}
|
||
|
||
return promise.then(fulfilled, rejected);
|
||
}
|
||
|
||
function options(fn, obj, opts) {
|
||
|
||
opts = opts || {};
|
||
|
||
if (isFunction(opts)) {
|
||
opts = opts.call(obj);
|
||
}
|
||
|
||
return merge(fn.bind({$vm: obj, $options: opts}), fn, {$options: opts});
|
||
}
|
||
|
||
function each(obj, iterator) {
|
||
|
||
var i, key;
|
||
|
||
if (isArray(obj)) {
|
||
for (i = 0; i < obj.length; i++) {
|
||
iterator.call(obj[i], obj[i], i);
|
||
}
|
||
} else if (isObject(obj)) {
|
||
for (key in obj) {
|
||
if (hasOwnProperty.call(obj, key)) {
|
||
iterator.call(obj[key], obj[key], key);
|
||
}
|
||
}
|
||
}
|
||
|
||
return obj;
|
||
}
|
||
|
||
var assign = Object.assign || _assign;
|
||
|
||
function merge(target) {
|
||
|
||
var args = slice.call(arguments, 1);
|
||
|
||
args.forEach(function (source) {
|
||
_merge(target, source, true);
|
||
});
|
||
|
||
return target;
|
||
}
|
||
|
||
function defaults(target) {
|
||
|
||
var args = slice.call(arguments, 1);
|
||
|
||
args.forEach(function (source) {
|
||
|
||
for (var key in source) {
|
||
if (target[key] === undefined) {
|
||
target[key] = source[key];
|
||
}
|
||
}
|
||
|
||
});
|
||
|
||
return target;
|
||
}
|
||
|
||
function _assign(target) {
|
||
|
||
var args = slice.call(arguments, 1);
|
||
|
||
args.forEach(function (source) {
|
||
_merge(target, source);
|
||
});
|
||
|
||
return target;
|
||
}
|
||
|
||
function _merge(target, source, deep) {
|
||
for (var key in source) {
|
||
if (deep && (isPlainObject(source[key]) || isArray(source[key]))) {
|
||
if (isPlainObject(source[key]) && !isPlainObject(target[key])) {
|
||
target[key] = {};
|
||
}
|
||
if (isArray(source[key]) && !isArray(target[key])) {
|
||
target[key] = [];
|
||
}
|
||
_merge(target[key], source[key], deep);
|
||
} else if (source[key] !== undefined) {
|
||
target[key] = source[key];
|
||
}
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Root Prefix Transform.
|
||
*/
|
||
|
||
var root = function (options$$1, next) {
|
||
|
||
var url = next(options$$1);
|
||
|
||
if (isString(options$$1.root) && !/^(https?:)?\//.test(url)) {
|
||
url = trimEnd(options$$1.root, '/') + '/' + url;
|
||
}
|
||
|
||
return url;
|
||
};
|
||
|
||
/**
|
||
* Query Parameter Transform.
|
||
*/
|
||
|
||
var query = function (options$$1, next) {
|
||
|
||
var urlParams = Object.keys(Url.options.params), query = {}, url = next(options$$1);
|
||
|
||
each(options$$1.params, function (value, key) {
|
||
if (urlParams.indexOf(key) === -1) {
|
||
query[key] = value;
|
||
}
|
||
});
|
||
|
||
query = Url.params(query);
|
||
|
||
if (query) {
|
||
url += (url.indexOf('?') == -1 ? '?' : '&') + query;
|
||
}
|
||
|
||
return url;
|
||
};
|
||
|
||
/**
|
||
* URL Template v2.0.6 (https://github.com/bramstein/url-template)
|
||
*/
|
||
|
||
function expand(url, params, variables) {
|
||
|
||
var tmpl = parse(url), expanded = tmpl.expand(params);
|
||
|
||
if (variables) {
|
||
variables.push.apply(variables, tmpl.vars);
|
||
}
|
||
|
||
return expanded;
|
||
}
|
||
|
||
function parse(template) {
|
||
|
||
var operators = ['+', '#', '.', '/', ';', '?', '&'], variables = [];
|
||
|
||
return {
|
||
vars: variables,
|
||
expand: function expand(context) {
|
||
return template.replace(/\{([^\{\}]+)\}|([^\{\}]+)/g, function (_, expression, literal) {
|
||
if (expression) {
|
||
|
||
var operator = null, values = [];
|
||
|
||
if (operators.indexOf(expression.charAt(0)) !== -1) {
|
||
operator = expression.charAt(0);
|
||
expression = expression.substr(1);
|
||
}
|
||
|
||
expression.split(/,/g).forEach(function (variable) {
|
||
var tmp = /([^:\*]*)(?::(\d+)|(\*))?/.exec(variable);
|
||
values.push.apply(values, getValues(context, operator, tmp[1], tmp[2] || tmp[3]));
|
||
variables.push(tmp[1]);
|
||
});
|
||
|
||
if (operator && operator !== '+') {
|
||
|
||
var separator = ',';
|
||
|
||
if (operator === '?') {
|
||
separator = '&';
|
||
} else if (operator !== '#') {
|
||
separator = operator;
|
||
}
|
||
|
||
return (values.length !== 0 ? operator : '') + values.join(separator);
|
||
} else {
|
||
return values.join(',');
|
||
}
|
||
|
||
} else {
|
||
return encodeReserved(literal);
|
||
}
|
||
});
|
||
}
|
||
};
|
||
}
|
||
|
||
function getValues(context, operator, key, modifier) {
|
||
|
||
var value = context[key], result = [];
|
||
|
||
if (isDefined(value) && value !== '') {
|
||
if (typeof value === 'string' || typeof value === 'number' || typeof value === 'boolean') {
|
||
value = value.toString();
|
||
|
||
if (modifier && modifier !== '*') {
|
||
value = value.substring(0, parseInt(modifier, 10));
|
||
}
|
||
|
||
result.push(encodeValue(operator, value, isKeyOperator(operator) ? key : null));
|
||
} else {
|
||
if (modifier === '*') {
|
||
if (Array.isArray(value)) {
|
||
value.filter(isDefined).forEach(function (value) {
|
||
result.push(encodeValue(operator, value, isKeyOperator(operator) ? key : null));
|
||
});
|
||
} else {
|
||
Object.keys(value).forEach(function (k) {
|
||
if (isDefined(value[k])) {
|
||
result.push(encodeValue(operator, value[k], k));
|
||
}
|
||
});
|
||
}
|
||
} else {
|
||
var tmp = [];
|
||
|
||
if (Array.isArray(value)) {
|
||
value.filter(isDefined).forEach(function (value) {
|
||
tmp.push(encodeValue(operator, value));
|
||
});
|
||
} else {
|
||
Object.keys(value).forEach(function (k) {
|
||
if (isDefined(value[k])) {
|
||
tmp.push(encodeURIComponent(k));
|
||
tmp.push(encodeValue(operator, value[k].toString()));
|
||
}
|
||
});
|
||
}
|
||
|
||
if (isKeyOperator(operator)) {
|
||
result.push(encodeURIComponent(key) + '=' + tmp.join(','));
|
||
} else if (tmp.length !== 0) {
|
||
result.push(tmp.join(','));
|
||
}
|
||
}
|
||
}
|
||
} else {
|
||
if (operator === ';') {
|
||
result.push(encodeURIComponent(key));
|
||
} else if (value === '' && (operator === '&' || operator === '?')) {
|
||
result.push(encodeURIComponent(key) + '=');
|
||
} else if (value === '') {
|
||
result.push('');
|
||
}
|
||
}
|
||
|
||
return result;
|
||
}
|
||
|
||
function isDefined(value) {
|
||
return value !== undefined && value !== null;
|
||
}
|
||
|
||
function isKeyOperator(operator) {
|
||
return operator === ';' || operator === '&' || operator === '?';
|
||
}
|
||
|
||
function encodeValue(operator, value, key) {
|
||
|
||
value = (operator === '+' || operator === '#') ? encodeReserved(value) : encodeURIComponent(value);
|
||
|
||
if (key) {
|
||
return encodeURIComponent(key) + '=' + value;
|
||
} else {
|
||
return value;
|
||
}
|
||
}
|
||
|
||
function encodeReserved(str) {
|
||
return str.split(/(%[0-9A-Fa-f]{2})/g).map(function (part) {
|
||
if (!/%[0-9A-Fa-f]/.test(part)) {
|
||
part = encodeURI(part);
|
||
}
|
||
return part;
|
||
}).join('');
|
||
}
|
||
|
||
/**
|
||
* URL Template (RFC 6570) Transform.
|
||
*/
|
||
|
||
var template = function (options) {
|
||
|
||
var variables = [], url = expand(options.url, options.params, variables);
|
||
|
||
variables.forEach(function (key) {
|
||
delete options.params[key];
|
||
});
|
||
|
||
return url;
|
||
};
|
||
|
||
/**
|
||
* Service for URL templating.
|
||
*/
|
||
|
||
function Url(url, params) {
|
||
|
||
var self = this || {}, options$$1 = url, transform;
|
||
|
||
if (isString(url)) {
|
||
options$$1 = {url: url, params: params};
|
||
}
|
||
|
||
options$$1 = merge({}, Url.options, self.$options, options$$1);
|
||
|
||
Url.transforms.forEach(function (handler) {
|
||
|
||
if (isString(handler)) {
|
||
handler = Url.transform[handler];
|
||
}
|
||
|
||
if (isFunction(handler)) {
|
||
transform = factory(handler, transform, self.$vm);
|
||
}
|
||
|
||
});
|
||
|
||
return transform(options$$1);
|
||
}
|
||
|
||
/**
|
||
* Url options.
|
||
*/
|
||
|
||
Url.options = {
|
||
url: '',
|
||
root: null,
|
||
params: {}
|
||
};
|
||
|
||
/**
|
||
* Url transforms.
|
||
*/
|
||
|
||
Url.transform = {template: template, query: query, root: root};
|
||
Url.transforms = ['template', 'query', 'root'];
|
||
|
||
/**
|
||
* Encodes a Url parameter string.
|
||
*
|
||
* @param {Object} obj
|
||
*/
|
||
|
||
Url.params = function (obj) {
|
||
|
||
var params = [], escape = encodeURIComponent;
|
||
|
||
params.add = function (key, value) {
|
||
|
||
if (isFunction(value)) {
|
||
value = value();
|
||
}
|
||
|
||
if (value === null) {
|
||
value = '';
|
||
}
|
||
|
||
this.push(escape(key) + '=' + escape(value));
|
||
};
|
||
|
||
serialize(params, obj);
|
||
|
||
return params.join('&').replace(/%20/g, '+');
|
||
};
|
||
|
||
/**
|
||
* Parse a URL and return its components.
|
||
*
|
||
* @param {String} url
|
||
*/
|
||
|
||
Url.parse = function (url) {
|
||
|
||
var el = document.createElement('a');
|
||
|
||
if (document.documentMode) {
|
||
el.href = url;
|
||
url = el.href;
|
||
}
|
||
|
||
el.href = url;
|
||
|
||
return {
|
||
href: el.href,
|
||
protocol: el.protocol ? el.protocol.replace(/:$/, '') : '',
|
||
port: el.port,
|
||
host: el.host,
|
||
hostname: el.hostname,
|
||
pathname: el.pathname.charAt(0) === '/' ? el.pathname : '/' + el.pathname,
|
||
search: el.search ? el.search.replace(/^\?/, '') : '',
|
||
hash: el.hash ? el.hash.replace(/^#/, '') : ''
|
||
};
|
||
};
|
||
|
||
function factory(handler, next, vm) {
|
||
return function (options$$1) {
|
||
return handler.call(vm, options$$1, next);
|
||
};
|
||
}
|
||
|
||
function serialize(params, obj, scope) {
|
||
|
||
var array = isArray(obj), plain = isPlainObject(obj), hash;
|
||
|
||
each(obj, function (value, key) {
|
||
|
||
hash = isObject(value) || isArray(value);
|
||
|
||
if (scope) {
|
||
key = scope + '[' + (plain || hash ? key : '') + ']';
|
||
}
|
||
|
||
if (!scope && array) {
|
||
params.add(value.name, value.value);
|
||
} else if (hash) {
|
||
serialize(params, value, key);
|
||
} else {
|
||
params.add(key, value);
|
||
}
|
||
});
|
||
}
|
||
|
||
/**
|
||
* XDomain client (Internet Explorer).
|
||
*/
|
||
|
||
var xdrClient = function (request) {
|
||
return new PromiseObj(function (resolve) {
|
||
|
||
var xdr = new XDomainRequest(), handler = function (ref) {
|
||
var type = ref.type;
|
||
|
||
|
||
var status = 0;
|
||
|
||
if (type === 'load') {
|
||
status = 200;
|
||
} else if (type === 'error') {
|
||
status = 500;
|
||
}
|
||
|
||
resolve(request.respondWith(xdr.responseText, {status: status}));
|
||
};
|
||
|
||
request.abort = function () { return xdr.abort(); };
|
||
|
||
xdr.open(request.method, request.getUrl());
|
||
|
||
if (request.timeout) {
|
||
xdr.timeout = request.timeout;
|
||
}
|
||
|
||
xdr.onload = handler;
|
||
xdr.onabort = handler;
|
||
xdr.onerror = handler;
|
||
xdr.ontimeout = handler;
|
||
xdr.onprogress = function () {};
|
||
xdr.send(request.getBody());
|
||
});
|
||
};
|
||
|
||
/**
|
||
* CORS Interceptor.
|
||
*/
|
||
|
||
var SUPPORTS_CORS = inBrowser && 'withCredentials' in new XMLHttpRequest();
|
||
|
||
var cors = function (request, next) {
|
||
|
||
if (inBrowser) {
|
||
|
||
var orgUrl = Url.parse(location.href);
|
||
var reqUrl = Url.parse(request.getUrl());
|
||
|
||
if (reqUrl.protocol !== orgUrl.protocol || reqUrl.host !== orgUrl.host) {
|
||
|
||
request.crossOrigin = true;
|
||
request.emulateHTTP = false;
|
||
|
||
if (!SUPPORTS_CORS) {
|
||
request.client = xdrClient;
|
||
}
|
||
}
|
||
}
|
||
|
||
next();
|
||
};
|
||
|
||
/**
|
||
* Form data Interceptor.
|
||
*/
|
||
|
||
var form = function (request, next) {
|
||
|
||
if (isFormData(request.body)) {
|
||
|
||
request.headers.delete('Content-Type');
|
||
|
||
} else if (isObject(request.body) && request.emulateJSON) {
|
||
|
||
request.body = Url.params(request.body);
|
||
request.headers.set('Content-Type', 'application/x-www-form-urlencoded');
|
||
}
|
||
|
||
next();
|
||
};
|
||
|
||
/**
|
||
* JSON Interceptor.
|
||
*/
|
||
|
||
var json = function (request, next) {
|
||
|
||
var type = request.headers.get('Content-Type') || '';
|
||
|
||
if (isObject(request.body) && type.indexOf('application/json') === 0) {
|
||
request.body = JSON.stringify(request.body);
|
||
}
|
||
|
||
next(function (response) {
|
||
|
||
return response.bodyText ? when(response.text(), function (text) {
|
||
|
||
type = response.headers.get('Content-Type') || '';
|
||
|
||
if (type.indexOf('application/json') === 0 || isJson(text)) {
|
||
|
||
try {
|
||
response.body = JSON.parse(text);
|
||
} catch (e) {
|
||
response.body = null;
|
||
}
|
||
|
||
} else {
|
||
response.body = text;
|
||
}
|
||
|
||
return response;
|
||
|
||
}) : response;
|
||
|
||
});
|
||
};
|
||
|
||
function isJson(str) {
|
||
|
||
var start = str.match(/^\[|^\{(?!\{)/), end = {'[': /]$/, '{': /}$/};
|
||
|
||
return start && end[start[0]].test(str);
|
||
}
|
||
|
||
/**
|
||
* JSONP client (Browser).
|
||
*/
|
||
|
||
var jsonpClient = function (request) {
|
||
return new PromiseObj(function (resolve) {
|
||
|
||
var name = request.jsonp || 'callback', callback = request.jsonpCallback || '_jsonp' + Math.random().toString(36).substr(2), body = null, handler, script;
|
||
|
||
handler = function (ref) {
|
||
var type = ref.type;
|
||
|
||
|
||
var status = 0;
|
||
|
||
if (type === 'load' && body !== null) {
|
||
status = 200;
|
||
} else if (type === 'error') {
|
||
status = 500;
|
||
}
|
||
|
||
if (status && window[callback]) {
|
||
delete window[callback];
|
||
document.body.removeChild(script);
|
||
}
|
||
|
||
resolve(request.respondWith(body, {status: status}));
|
||
};
|
||
|
||
window[callback] = function (result) {
|
||
body = JSON.stringify(result);
|
||
};
|
||
|
||
request.abort = function () {
|
||
handler({type: 'abort'});
|
||
};
|
||
|
||
request.params[name] = callback;
|
||
|
||
if (request.timeout) {
|
||
setTimeout(request.abort, request.timeout);
|
||
}
|
||
|
||
script = document.createElement('script');
|
||
script.src = request.getUrl();
|
||
script.type = 'text/javascript';
|
||
script.async = true;
|
||
script.onload = handler;
|
||
script.onerror = handler;
|
||
|
||
document.body.appendChild(script);
|
||
});
|
||
};
|
||
|
||
/**
|
||
* JSONP Interceptor.
|
||
*/
|
||
|
||
var jsonp = function (request, next) {
|
||
|
||
if (request.method == 'JSONP') {
|
||
request.client = jsonpClient;
|
||
}
|
||
|
||
next();
|
||
};
|
||
|
||
/**
|
||
* Before Interceptor.
|
||
*/
|
||
|
||
var before = function (request, next) {
|
||
|
||
if (isFunction(request.before)) {
|
||
request.before.call(this, request);
|
||
}
|
||
|
||
next();
|
||
};
|
||
|
||
/**
|
||
* HTTP method override Interceptor.
|
||
*/
|
||
|
||
var method = function (request, next) {
|
||
|
||
if (request.emulateHTTP && /^(PUT|PATCH|DELETE)$/i.test(request.method)) {
|
||
request.headers.set('X-HTTP-Method-Override', request.method);
|
||
request.method = 'POST';
|
||
}
|
||
|
||
next();
|
||
};
|
||
|
||
/**
|
||
* Header Interceptor.
|
||
*/
|
||
|
||
var header = function (request, next) {
|
||
|
||
var headers = assign({}, Http.headers.common,
|
||
!request.crossOrigin ? Http.headers.custom : {},
|
||
Http.headers[toLower(request.method)]
|
||
);
|
||
|
||
each(headers, function (value, name) {
|
||
if (!request.headers.has(name)) {
|
||
request.headers.set(name, value);
|
||
}
|
||
});
|
||
|
||
next();
|
||
};
|
||
|
||
/**
|
||
* XMLHttp client (Browser).
|
||
*/
|
||
|
||
var xhrClient = function (request) {
|
||
return new PromiseObj(function (resolve) {
|
||
|
||
var xhr = new XMLHttpRequest(), handler = function (event) {
|
||
|
||
var response = request.respondWith(
|
||
'response' in xhr ? xhr.response : xhr.responseText, {
|
||
status: xhr.status === 1223 ? 204 : xhr.status, // IE9 status bug
|
||
statusText: xhr.status === 1223 ? 'No Content' : trim(xhr.statusText)
|
||
}
|
||
);
|
||
|
||
each(trim(xhr.getAllResponseHeaders()).split('\n'), function (row) {
|
||
response.headers.append(row.slice(0, row.indexOf(':')), row.slice(row.indexOf(':') + 1));
|
||
});
|
||
|
||
resolve(response);
|
||
};
|
||
|
||
request.abort = function () { return xhr.abort(); };
|
||
|
||
if (request.progress) {
|
||
if (request.method === 'GET') {
|
||
xhr.addEventListener('progress', request.progress);
|
||
} else if (/^(POST|PUT)$/i.test(request.method)) {
|
||
xhr.upload.addEventListener('progress', request.progress);
|
||
}
|
||
}
|
||
|
||
xhr.open(request.method, request.getUrl(), true);
|
||
|
||
if (request.timeout) {
|
||
xhr.timeout = request.timeout;
|
||
}
|
||
|
||
if (request.responseType && 'responseType' in xhr) {
|
||
xhr.responseType = request.responseType;
|
||
}
|
||
|
||
if (request.withCredentials || request.credentials) {
|
||
xhr.withCredentials = true;
|
||
}
|
||
|
||
if (!request.crossOrigin) {
|
||
request.headers.set('X-Requested-With', 'XMLHttpRequest');
|
||
}
|
||
|
||
request.headers.forEach(function (value, name) {
|
||
xhr.setRequestHeader(name, value);
|
||
});
|
||
|
||
xhr.onload = handler;
|
||
xhr.onabort = handler;
|
||
xhr.onerror = handler;
|
||
xhr.ontimeout = handler;
|
||
xhr.send(request.getBody());
|
||
});
|
||
};
|
||
|
||
/**
|
||
* Http client (Node).
|
||
*/
|
||
|
||
var nodeClient = function (request) {
|
||
|
||
var client = __webpack_require__(14);
|
||
|
||
return new PromiseObj(function (resolve) {
|
||
|
||
var url = request.getUrl();
|
||
var body = request.getBody();
|
||
var method = request.method;
|
||
var headers = {}, handler;
|
||
|
||
request.headers.forEach(function (value, name) {
|
||
headers[name] = value;
|
||
});
|
||
|
||
client(url, {body: body, method: method, headers: headers}).then(handler = function (resp) {
|
||
|
||
var response = request.respondWith(resp.body, {
|
||
status: resp.statusCode,
|
||
statusText: trim(resp.statusMessage)
|
||
}
|
||
);
|
||
|
||
each(resp.headers, function (value, name) {
|
||
response.headers.set(name, value);
|
||
});
|
||
|
||
resolve(response);
|
||
|
||
}, function (error$$1) { return handler(error$$1.response); });
|
||
});
|
||
};
|
||
|
||
/**
|
||
* Base client.
|
||
*/
|
||
|
||
var Client = function (context) {
|
||
|
||
var reqHandlers = [sendRequest], resHandlers = [], handler;
|
||
|
||
if (!isObject(context)) {
|
||
context = null;
|
||
}
|
||
|
||
function Client(request) {
|
||
return new PromiseObj(function (resolve, reject) {
|
||
|
||
function exec() {
|
||
|
||
handler = reqHandlers.pop();
|
||
|
||
if (isFunction(handler)) {
|
||
handler.call(context, request, next);
|
||
} else {
|
||
warn(("Invalid interceptor of type " + (typeof handler) + ", must be a function"));
|
||
next();
|
||
}
|
||
}
|
||
|
||
function next(response) {
|
||
|
||
if (isFunction(response)) {
|
||
|
||
resHandlers.unshift(response);
|
||
|
||
} else if (isObject(response)) {
|
||
|
||
resHandlers.forEach(function (handler) {
|
||
response = when(response, function (response) {
|
||
return handler.call(context, response) || response;
|
||
}, reject);
|
||
});
|
||
|
||
when(response, resolve, reject);
|
||
|
||
return;
|
||
}
|
||
|
||
exec();
|
||
}
|
||
|
||
exec();
|
||
|
||
}, context);
|
||
}
|
||
|
||
Client.use = function (handler) {
|
||
reqHandlers.push(handler);
|
||
};
|
||
|
||
return Client;
|
||
};
|
||
|
||
function sendRequest(request, resolve) {
|
||
|
||
var client = request.client || (inBrowser ? xhrClient : nodeClient);
|
||
|
||
resolve(client(request));
|
||
}
|
||
|
||
/**
|
||
* HTTP Headers.
|
||
*/
|
||
|
||
var Headers = function Headers(headers) {
|
||
var this$1 = this;
|
||
|
||
|
||
this.map = {};
|
||
|
||
each(headers, function (value, name) { return this$1.append(name, value); });
|
||
};
|
||
|
||
Headers.prototype.has = function has (name) {
|
||
return getName(this.map, name) !== null;
|
||
};
|
||
|
||
Headers.prototype.get = function get (name) {
|
||
|
||
var list = this.map[getName(this.map, name)];
|
||
|
||
return list ? list.join() : null;
|
||
};
|
||
|
||
Headers.prototype.getAll = function getAll (name) {
|
||
return this.map[getName(this.map, name)] || [];
|
||
};
|
||
|
||
Headers.prototype.set = function set (name, value) {
|
||
this.map[normalizeName(getName(this.map, name) || name)] = [trim(value)];
|
||
};
|
||
|
||
Headers.prototype.append = function append (name, value){
|
||
|
||
var list = this.map[getName(this.map, name)];
|
||
|
||
if (list) {
|
||
list.push(trim(value));
|
||
} else {
|
||
this.set(name, value);
|
||
}
|
||
};
|
||
|
||
Headers.prototype.delete = function delete$1 (name){
|
||
delete this.map[getName(this.map, name)];
|
||
};
|
||
|
||
Headers.prototype.deleteAll = function deleteAll (){
|
||
this.map = {};
|
||
};
|
||
|
||
Headers.prototype.forEach = function forEach (callback, thisArg) {
|
||
var this$1 = this;
|
||
|
||
each(this.map, function (list, name) {
|
||
each(list, function (value) { return callback.call(thisArg, value, name, this$1); });
|
||
});
|
||
};
|
||
|
||
function getName(map, name) {
|
||
return Object.keys(map).reduce(function (prev, curr) {
|
||
return toLower(name) === toLower(curr) ? curr : prev;
|
||
}, null);
|
||
}
|
||
|
||
function normalizeName(name) {
|
||
|
||
if (/[^a-z0-9\-#$%&'*+.\^_`|~]/i.test(name)) {
|
||
throw new TypeError('Invalid character in header field name');
|
||
}
|
||
|
||
return trim(name);
|
||
}
|
||
|
||
/**
|
||
* HTTP Response.
|
||
*/
|
||
|
||
var Response = function Response(body, ref) {
|
||
var url = ref.url;
|
||
var headers = ref.headers;
|
||
var status = ref.status;
|
||
var statusText = ref.statusText;
|
||
|
||
|
||
this.url = url;
|
||
this.ok = status >= 200 && status < 300;
|
||
this.status = status || 0;
|
||
this.statusText = statusText || '';
|
||
this.headers = new Headers(headers);
|
||
this.body = body;
|
||
|
||
if (isString(body)) {
|
||
|
||
this.bodyText = body;
|
||
|
||
} else if (isBlob(body)) {
|
||
|
||
this.bodyBlob = body;
|
||
|
||
if (isBlobText(body)) {
|
||
this.bodyText = blobText(body);
|
||
}
|
||
}
|
||
};
|
||
|
||
Response.prototype.blob = function blob () {
|
||
return when(this.bodyBlob);
|
||
};
|
||
|
||
Response.prototype.text = function text () {
|
||
return when(this.bodyText);
|
||
};
|
||
|
||
Response.prototype.json = function json () {
|
||
return when(this.text(), function (text) { return JSON.parse(text); });
|
||
};
|
||
|
||
Object.defineProperty(Response.prototype, 'data', {
|
||
|
||
get: function get() {
|
||
return this.body;
|
||
},
|
||
|
||
set: function set(body) {
|
||
this.body = body;
|
||
}
|
||
|
||
});
|
||
|
||
function blobText(body) {
|
||
return new PromiseObj(function (resolve) {
|
||
|
||
var reader = new FileReader();
|
||
|
||
reader.readAsText(body);
|
||
reader.onload = function () {
|
||
resolve(reader.result);
|
||
};
|
||
|
||
});
|
||
}
|
||
|
||
function isBlobText(body) {
|
||
return body.type.indexOf('text') === 0 || body.type.indexOf('json') !== -1;
|
||
}
|
||
|
||
/**
|
||
* HTTP Request.
|
||
*/
|
||
|
||
var Request = function Request(options$$1) {
|
||
|
||
this.body = null;
|
||
this.params = {};
|
||
|
||
assign(this, options$$1, {
|
||
method: toUpper(options$$1.method || 'GET')
|
||
});
|
||
|
||
if (!(this.headers instanceof Headers)) {
|
||
this.headers = new Headers(this.headers);
|
||
}
|
||
};
|
||
|
||
Request.prototype.getUrl = function getUrl (){
|
||
return Url(this);
|
||
};
|
||
|
||
Request.prototype.getBody = function getBody (){
|
||
return this.body;
|
||
};
|
||
|
||
Request.prototype.respondWith = function respondWith (body, options$$1) {
|
||
return new Response(body, assign(options$$1 || {}, {url: this.getUrl()}));
|
||
};
|
||
|
||
/**
|
||
* Service for sending network requests.
|
||
*/
|
||
|
||
var COMMON_HEADERS = {'Accept': 'application/json, text/plain, */*'};
|
||
var JSON_CONTENT_TYPE = {'Content-Type': 'application/json;charset=utf-8'};
|
||
|
||
function Http(options$$1) {
|
||
|
||
var self = this || {}, client = Client(self.$vm);
|
||
|
||
defaults(options$$1 || {}, self.$options, Http.options);
|
||
|
||
Http.interceptors.forEach(function (handler) {
|
||
|
||
if (isString(handler)) {
|
||
handler = Http.interceptor[handler];
|
||
}
|
||
|
||
if (isFunction(handler)) {
|
||
client.use(handler);
|
||
}
|
||
|
||
});
|
||
|
||
return client(new Request(options$$1)).then(function (response) {
|
||
|
||
return response.ok ? response : PromiseObj.reject(response);
|
||
|
||
}, function (response) {
|
||
|
||
if (response instanceof Error) {
|
||
error(response);
|
||
}
|
||
|
||
return PromiseObj.reject(response);
|
||
});
|
||
}
|
||
|
||
Http.options = {};
|
||
|
||
Http.headers = {
|
||
put: JSON_CONTENT_TYPE,
|
||
post: JSON_CONTENT_TYPE,
|
||
patch: JSON_CONTENT_TYPE,
|
||
delete: JSON_CONTENT_TYPE,
|
||
common: COMMON_HEADERS,
|
||
custom: {}
|
||
};
|
||
|
||
Http.interceptor = {before: before, method: method, jsonp: jsonp, json: json, form: form, header: header, cors: cors};
|
||
Http.interceptors = ['before', 'method', 'jsonp', 'json', 'form', 'header', 'cors'];
|
||
|
||
['get', 'delete', 'head', 'jsonp'].forEach(function (method$$1) {
|
||
|
||
Http[method$$1] = function (url, options$$1) {
|
||
return this(assign(options$$1 || {}, {url: url, method: method$$1}));
|
||
};
|
||
|
||
});
|
||
|
||
['post', 'put', 'patch'].forEach(function (method$$1) {
|
||
|
||
Http[method$$1] = function (url, body, options$$1) {
|
||
return this(assign(options$$1 || {}, {url: url, method: method$$1, body: body}));
|
||
};
|
||
|
||
});
|
||
|
||
/**
|
||
* Service for interacting with RESTful services.
|
||
*/
|
||
|
||
function Resource(url, params, actions, options$$1) {
|
||
|
||
var self = this || {}, resource = {};
|
||
|
||
actions = assign({},
|
||
Resource.actions,
|
||
actions
|
||
);
|
||
|
||
each(actions, function (action, name) {
|
||
|
||
action = merge({url: url, params: assign({}, params)}, options$$1, action);
|
||
|
||
resource[name] = function () {
|
||
return (self.$http || Http)(opts(action, arguments));
|
||
};
|
||
});
|
||
|
||
return resource;
|
||
}
|
||
|
||
function opts(action, args) {
|
||
|
||
var options$$1 = assign({}, action), params = {}, body;
|
||
|
||
switch (args.length) {
|
||
|
||
case 2:
|
||
|
||
params = args[0];
|
||
body = args[1];
|
||
|
||
break;
|
||
|
||
case 1:
|
||
|
||
if (/^(POST|PUT|PATCH)$/i.test(options$$1.method)) {
|
||
body = args[0];
|
||
} else {
|
||
params = args[0];
|
||
}
|
||
|
||
break;
|
||
|
||
case 0:
|
||
|
||
break;
|
||
|
||
default:
|
||
|
||
throw 'Expected up to 2 arguments [params, body], got ' + args.length + ' arguments';
|
||
}
|
||
|
||
options$$1.body = body;
|
||
options$$1.params = assign({}, options$$1.params, params);
|
||
|
||
return options$$1;
|
||
}
|
||
|
||
Resource.actions = {
|
||
|
||
get: {method: 'GET'},
|
||
save: {method: 'POST'},
|
||
query: {method: 'GET'},
|
||
update: {method: 'PUT'},
|
||
remove: {method: 'DELETE'},
|
||
delete: {method: 'DELETE'}
|
||
|
||
};
|
||
|
||
/**
|
||
* Install plugin.
|
||
*/
|
||
|
||
function plugin(Vue) {
|
||
|
||
if (plugin.installed) {
|
||
return;
|
||
}
|
||
|
||
Util(Vue);
|
||
|
||
Vue.url = Url;
|
||
Vue.http = Http;
|
||
Vue.resource = Resource;
|
||
Vue.Promise = PromiseObj;
|
||
|
||
Object.defineProperties(Vue.prototype, {
|
||
|
||
$url: {
|
||
get: function get() {
|
||
return options(Vue.url, this, this.$options.url);
|
||
}
|
||
},
|
||
|
||
$http: {
|
||
get: function get() {
|
||
return options(Vue.http, this, this.$options.http);
|
||
}
|
||
},
|
||
|
||
$resource: {
|
||
get: function get() {
|
||
return Vue.resource.bind(this);
|
||
}
|
||
},
|
||
|
||
$promise: {
|
||
get: function get() {
|
||
var this$1 = this;
|
||
|
||
return function (executor) { return new Vue.Promise(executor, this$1); };
|
||
}
|
||
}
|
||
|
||
});
|
||
}
|
||
|
||
if (typeof window !== 'undefined' && window.Vue) {
|
||
window.Vue.use(plugin);
|
||
}
|
||
|
||
/* harmony default export */ __webpack_exports__["default"] = (plugin);
|
||
|
||
|
||
|
||
/***/ }),
|
||
/* 14 */
|
||
/***/ (function(module, exports) {
|
||
|
||
/* (ignored) */
|
||
|
||
/***/ }),
|
||
/* 15 */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
var disposed = false
|
||
function injectStyle (ssrContext) {
|
||
if (disposed) return
|
||
__webpack_require__(16)
|
||
}
|
||
var Component = __webpack_require__(2)(
|
||
/* script */
|
||
__webpack_require__(19),
|
||
/* template */
|
||
__webpack_require__(20),
|
||
/* styles */
|
||
injectStyle,
|
||
/* scopeId */
|
||
"data-v-e9c80318",
|
||
/* moduleIdentifier (server only) */
|
||
null
|
||
)
|
||
Component.options.__file = "/home/hydrogen/work/snipe-it/resources/assets/js/components/passport/Clients.vue"
|
||
if (Component.esModule && Object.keys(Component.esModule).some(function (key) {return key !== "default" && key.substr(0, 2) !== "__"})) {console.error("named exports are not supported in *.vue files.")}
|
||
if (Component.options.functional) {console.error("[vue-loader] Clients.vue: functional components are not supported with templates, they should use render functions.")}
|
||
|
||
/* hot reload */
|
||
if (false) {(function () {
|
||
var hotAPI = require("vue-hot-reload-api")
|
||
hotAPI.install(require("vue"), false)
|
||
if (!hotAPI.compatible) return
|
||
module.hot.accept()
|
||
if (!module.hot.data) {
|
||
hotAPI.createRecord("data-v-e9c80318", Component.options)
|
||
} else {
|
||
hotAPI.reload("data-v-e9c80318", Component.options)
|
||
}
|
||
module.hot.dispose(function (data) {
|
||
disposed = true
|
||
})
|
||
})()}
|
||
|
||
module.exports = Component.exports
|
||
|
||
|
||
/***/ }),
|
||
/* 16 */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
// style-loader: Adds some css to the DOM by adding a <style> tag
|
||
|
||
// load the styles
|
||
var content = __webpack_require__(17);
|
||
if(typeof content === 'string') content = [[module.i, content, '']];
|
||
if(content.locals) module.exports = content.locals;
|
||
// add the styles to the DOM
|
||
var update = __webpack_require__(1)("d331c48a", content, false);
|
||
// Hot Module Replacement
|
||
if(false) {
|
||
// When the styles change, update the <style> tags
|
||
if(!content.locals) {
|
||
module.hot.accept("!!../../../../../node_modules/css-loader/index.js?sourceMap!../../../../../node_modules/vue-loader/lib/style-compiler/index.js?{\"vue\":true,\"id\":\"data-v-e9c80318\",\"scoped\":true,\"hasInlineConfig\":true}!../../../../../node_modules/vue-loader/lib/selector.js?type=styles&index=0!./Clients.vue", function() {
|
||
var newContent = require("!!../../../../../node_modules/css-loader/index.js?sourceMap!../../../../../node_modules/vue-loader/lib/style-compiler/index.js?{\"vue\":true,\"id\":\"data-v-e9c80318\",\"scoped\":true,\"hasInlineConfig\":true}!../../../../../node_modules/vue-loader/lib/selector.js?type=styles&index=0!./Clients.vue");
|
||
if(typeof newContent === 'string') newContent = [[module.id, newContent, '']];
|
||
update(newContent);
|
||
});
|
||
}
|
||
// When the module is disposed, remove the <style> tags
|
||
module.hot.dispose(function() { update(); });
|
||
}
|
||
|
||
/***/ }),
|
||
/* 17 */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
exports = module.exports = __webpack_require__(0)(true);
|
||
// imports
|
||
|
||
|
||
// module
|
||
exports.push([module.i, "\n.action-link[data-v-e9c80318] {\n cursor: pointer;\n}\n.m-b-none[data-v-e9c80318] {\n margin-bottom: 0;\n}\n", "", {"version":3,"sources":["/home/hydrogen/work/snipe-it/resources/assets/js/components/passport/Clients.vue?35867ce4"],"names":[],"mappings":";AACA;IACA,gBAAA;CACA;AAEA;IACA,iBAAA;CACA","file":"Clients.vue","sourcesContent":["<style scoped>\n .action-link {\n cursor: pointer;\n }\n\n .m-b-none {\n margin-bottom: 0;\n }\n</style>\n\n<template>\n <div>\n <div class=\"panel panel-default\">\n <div class=\"panel-heading\">\n <div style=\"display: flex; justify-content: space-between; align-items: center;\">\n <span>\n OAuth Clients\n </span>\n\n <a class=\"action-link\" @click=\"showCreateClientForm\">\n Create New Client\n </a>\n </div>\n </div>\n\n <div class=\"panel-body\">\n <!-- Current Clients -->\n <p class=\"m-b-none\" v-if=\"clients.length === 0\">\n You have not created any OAuth clients.\n </p>\n\n <table class=\"table table-borderless m-b-none\" v-if=\"clients.length > 0\">\n <thead>\n <tr>\n <th>Client ID</th>\n <th>Name</th>\n <th>Secret</th>\n <th></th>\n <th></th>\n </tr>\n </thead>\n\n <tbody>\n <tr v-for=\"client in clients\">\n <!-- ID -->\n <td style=\"vertical-align: middle;\">\n {{ client.id }}\n </td>\n\n <!-- Name -->\n <td style=\"vertical-align: middle;\">\n {{ client.name }}\n </td>\n\n <!-- Secret -->\n <td style=\"vertical-align: middle;\">\n <code>{{ client.secret }}</code>\n </td>\n\n <!-- Edit Button -->\n <td style=\"vertical-align: middle;\">\n <a class=\"action-link\" @click=\"edit(client)\">\n Edit\n </a>\n </td>\n\n <!-- Delete Button -->\n <td style=\"vertical-align: middle;\">\n <a class=\"action-link text-danger\" @click=\"destroy(client)\">\n Delete\n </a>\n </td>\n </tr>\n </tbody>\n </table>\n </div>\n </div>\n\n <!-- Create Client Modal -->\n <div class=\"modal fade\" id=\"modal-create-client\" tabindex=\"-1\" role=\"dialog\">\n <div class=\"modal-dialog\">\n <div class=\"modal-content\">\n <div class=\"modal-header\">\n <button type=\"button \" class=\"close\" data-dismiss=\"modal\" aria-hidden=\"true\">×</button>\n\n <h4 class=\"modal-title\">\n Create Client\n </h4>\n </div>\n\n <div class=\"modal-body\">\n <!-- Form Errors -->\n <div class=\"alert alert-danger\" v-if=\"createForm.errors.length > 0\">\n <p><strong>Whoops!</strong> Something went wrong!</p>\n <br>\n <ul>\n <li v-for=\"error in createForm.errors\">\n {{ error }}\n </li>\n </ul>\n </div>\n\n <!-- Create Client Form -->\n <form class=\"form-horizontal\" role=\"form\">\n <!-- Name -->\n <div class=\"form-group\">\n <label class=\"col-md-3 control-label\">Name</label>\n\n <div class=\"col-md-7\">\n <input id=\"create-client-name\" type=\"text\" class=\"form-control\"\n @keyup.enter=\"store\" v-model=\"createForm.name\">\n\n <span class=\"help-block\">\n Something your users will recognize and trust.\n </span>\n </div>\n </div>\n\n <!-- Redirect URL -->\n <div class=\"form-group\">\n <label class=\"col-md-3 control-label\">Redirect URL</label>\n\n <div class=\"col-md-7\">\n <input type=\"text\" class=\"form-control\" name=\"redirect\"\n @keyup.enter=\"store\" v-model=\"createForm.redirect\">\n\n <span class=\"help-block\">\n Your application's authorization callback URL.\n </span>\n </div>\n </div>\n </form>\n </div>\n\n <!-- Modal Actions -->\n <div class=\"modal-footer\">\n <button type=\"button\" class=\"btn btn-default\" data-dismiss=\"modal\">Close</button>\n\n <button type=\"button\" class=\"btn btn-primary\" @click=\"store\">\n Create\n </button>\n </div>\n </div>\n </div>\n </div>\n\n <!-- Edit Client Modal -->\n <div class=\"modal fade\" id=\"modal-edit-client\" tabindex=\"-1\" role=\"dialog\">\n <div class=\"modal-dialog\">\n <div class=\"modal-content\">\n <div class=\"modal-header\">\n <button type=\"button \" class=\"close\" data-dismiss=\"modal\" aria-hidden=\"true\">×</button>\n\n <h4 class=\"modal-title\">\n Edit Client\n </h4>\n </div>\n\n <div class=\"modal-body\">\n <!-- Form Errors -->\n <div class=\"alert alert-danger\" v-if=\"editForm.errors.length > 0\">\n <p><strong>Whoops!</strong> Something went wrong!</p>\n <br>\n <ul>\n <li v-for=\"error in editForm.errors\">\n {{ error }}\n </li>\n </ul>\n </div>\n\n <!-- Edit Client Form -->\n <form class=\"form-horizontal\" role=\"form\">\n <!-- Name -->\n <div class=\"form-group\">\n <label class=\"col-md-3 control-label\">Name</label>\n\n <div class=\"col-md-7\">\n <input id=\"edit-client-name\" type=\"text\" class=\"form-control\"\n @keyup.enter=\"update\" v-model=\"editForm.name\">\n\n <span class=\"help-block\">\n Something your users will recognize and trust.\n </span>\n </div>\n </div>\n\n <!-- Redirect URL -->\n <div class=\"form-group\">\n <label class=\"col-md-3 control-label\">Redirect URL</label>\n\n <div class=\"col-md-7\">\n <input type=\"text\" class=\"form-control\" name=\"redirect\"\n @keyup.enter=\"update\" v-model=\"editForm.redirect\">\n\n <span class=\"help-block\">\n Your application's authorization callback URL.\n </span>\n </div>\n </div>\n </form>\n </div>\n\n <!-- Modal Actions -->\n <div class=\"modal-footer\">\n <button type=\"button\" class=\"btn btn-default\" data-dismiss=\"modal\">Close</button>\n\n <button type=\"button\" class=\"btn btn-primary\" @click=\"update\">\n Save Changes\n </button>\n </div>\n </div>\n </div>\n </div>\n </div>\n</template>\n\n<script>\n export default {\n /*\n * The component's data.\n */\n data() {\n return {\n clients: [],\n\n createForm: {\n errors: [],\n name: '',\n redirect: ''\n },\n\n editForm: {\n errors: [],\n name: '',\n redirect: ''\n }\n };\n },\n\n /**\n * Prepare the component (Vue 1.x).\n */\n ready() {\n this.prepareComponent();\n },\n\n /**\n * Prepare the component (Vue 2.x).\n */\n mounted() {\n this.prepareComponent();\n },\n\n methods: {\n /**\n * Prepare the component.\n */\n prepareComponent() {\n this.getClients();\n\n $('#modal-create-client').on('shown.bs.modal', () => {\n $('#create-client-name').focus();\n });\n\n $('#modal-edit-client').on('shown.bs.modal', () => {\n $('#edit-client-name').focus();\n });\n },\n\n /**\n * Get all of the OAuth clients for the user.\n */\n getClients() {\n this.$http.get('/oauth/clients')\n .then(response => {\n this.clients = response.data;\n });\n },\n\n /**\n * Show the form for creating new clients.\n */\n showCreateClientForm() {\n $('#modal-create-client').modal('show');\n },\n\n /**\n * Create a new OAuth client for the user.\n */\n store() {\n this.persistClient(\n 'post', '/oauth/clients',\n this.createForm, '#modal-create-client'\n );\n },\n\n /**\n * Edit the given client.\n */\n edit(client) {\n this.editForm.id = client.id;\n this.editForm.name = client.name;\n this.editForm.redirect = client.redirect;\n\n $('#modal-edit-client').modal('show');\n },\n\n /**\n * Update the client being edited.\n */\n update() {\n this.persistClient(\n 'put', '/oauth/clients/' + this.editForm.id,\n this.editForm, '#modal-edit-client'\n );\n },\n\n /**\n * Persist the client to storage using the given form.\n */\n persistClient(method, uri, form, modal) {\n form.errors = [];\n\n this.$http[method](uri, form)\n .then(response => {\n this.getClients();\n\n form.name = '';\n form.redirect = '';\n form.errors = [];\n\n $(modal).modal('hide');\n })\n .catch(response => {\n if (typeof response.data === 'object') {\n form.errors = _.flatten(_.toArray(response.data));\n } else {\n form.errors = ['Something went wrong. Please try again.'];\n }\n });\n },\n\n /**\n * Destroy the given client.\n */\n destroy(client) {\n this.$http.delete('/oauth/clients/' + client.id)\n .then(response => {\n this.getClients();\n });\n }\n }\n }\n</script>\n"],"sourceRoot":""}]);
|
||
|
||
// exports
|
||
|
||
|
||
/***/ }),
|
||
/* 18 */
|
||
/***/ (function(module, exports) {
|
||
|
||
/**
|
||
* Translates the list format produced by css-loader into something
|
||
* easier to manipulate.
|
||
*/
|
||
module.exports = function listToStyles (parentId, list) {
|
||
var styles = []
|
||
var newStyles = {}
|
||
for (var i = 0; i < list.length; i++) {
|
||
var item = list[i]
|
||
var id = item[0]
|
||
var css = item[1]
|
||
var media = item[2]
|
||
var sourceMap = item[3]
|
||
var part = {
|
||
id: parentId + ':' + i,
|
||
css: css,
|
||
media: media,
|
||
sourceMap: sourceMap
|
||
}
|
||
if (!newStyles[id]) {
|
||
styles.push(newStyles[id] = { id: id, parts: [part] })
|
||
} else {
|
||
newStyles[id].parts.push(part)
|
||
}
|
||
}
|
||
return styles
|
||
}
|
||
|
||
|
||
/***/ }),
|
||
/* 19 */
|
||
/***/ (function(module, __webpack_exports__, __webpack_require__) {
|
||
|
||
"use strict";
|
||
Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
|
||
var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
|
||
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
|
||
/* harmony default export */ __webpack_exports__["default"] = ({
|
||
/*
|
||
* The component's data.
|
||
*/
|
||
data: function data() {
|
||
return {
|
||
clients: [],
|
||
|
||
createForm: {
|
||
errors: [],
|
||
name: '',
|
||
redirect: ''
|
||
},
|
||
|
||
editForm: {
|
||
errors: [],
|
||
name: '',
|
||
redirect: ''
|
||
}
|
||
};
|
||
},
|
||
|
||
|
||
/**
|
||
* Prepare the component (Vue 1.x).
|
||
*/
|
||
ready: function ready() {
|
||
this.prepareComponent();
|
||
},
|
||
|
||
|
||
/**
|
||
* Prepare the component (Vue 2.x).
|
||
*/
|
||
mounted: function mounted() {
|
||
this.prepareComponent();
|
||
},
|
||
|
||
|
||
methods: {
|
||
/**
|
||
* Prepare the component.
|
||
*/
|
||
prepareComponent: function prepareComponent() {
|
||
this.getClients();
|
||
|
||
$('#modal-create-client').on('shown.bs.modal', function () {
|
||
$('#create-client-name').focus();
|
||
});
|
||
|
||
$('#modal-edit-client').on('shown.bs.modal', function () {
|
||
$('#edit-client-name').focus();
|
||
});
|
||
},
|
||
|
||
|
||
/**
|
||
* Get all of the OAuth clients for the user.
|
||
*/
|
||
getClients: function getClients() {
|
||
var _this = this;
|
||
|
||
this.$http.get('/oauth/clients').then(function (response) {
|
||
_this.clients = response.data;
|
||
});
|
||
},
|
||
|
||
|
||
/**
|
||
* Show the form for creating new clients.
|
||
*/
|
||
showCreateClientForm: function showCreateClientForm() {
|
||
$('#modal-create-client').modal('show');
|
||
},
|
||
|
||
|
||
/**
|
||
* Create a new OAuth client for the user.
|
||
*/
|
||
store: function store() {
|
||
this.persistClient('post', '/oauth/clients', this.createForm, '#modal-create-client');
|
||
},
|
||
|
||
|
||
/**
|
||
* Edit the given client.
|
||
*/
|
||
edit: function edit(client) {
|
||
this.editForm.id = client.id;
|
||
this.editForm.name = client.name;
|
||
this.editForm.redirect = client.redirect;
|
||
|
||
$('#modal-edit-client').modal('show');
|
||
},
|
||
|
||
|
||
/**
|
||
* Update the client being edited.
|
||
*/
|
||
update: function update() {
|
||
this.persistClient('put', '/oauth/clients/' + this.editForm.id, this.editForm, '#modal-edit-client');
|
||
},
|
||
|
||
|
||
/**
|
||
* Persist the client to storage using the given form.
|
||
*/
|
||
persistClient: function persistClient(method, uri, form, modal) {
|
||
var _this2 = this;
|
||
|
||
form.errors = [];
|
||
|
||
this.$http[method](uri, form).then(function (response) {
|
||
_this2.getClients();
|
||
|
||
form.name = '';
|
||
form.redirect = '';
|
||
form.errors = [];
|
||
|
||
$(modal).modal('hide');
|
||
}).catch(function (response) {
|
||
if (_typeof(response.data) === 'object') {
|
||
form.errors = _.flatten(_.toArray(response.data));
|
||
} else {
|
||
form.errors = ['Something went wrong. Please try again.'];
|
||
}
|
||
});
|
||
},
|
||
|
||
|
||
/**
|
||
* Destroy the given client.
|
||
*/
|
||
destroy: function destroy(client) {
|
||
var _this3 = this;
|
||
|
||
this.$http.delete('/oauth/clients/' + client.id).then(function (response) {
|
||
_this3.getClients();
|
||
});
|
||
}
|
||
}
|
||
});
|
||
|
||
/***/ }),
|
||
/* 20 */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
module.exports={render:function (){var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;
|
||
return _c('div', [_c('div', {
|
||
staticClass: "panel panel-default"
|
||
}, [_c('div', {
|
||
staticClass: "panel-heading"
|
||
}, [_c('div', {
|
||
staticStyle: {
|
||
"display": "flex",
|
||
"justify-content": "space-between",
|
||
"align-items": "center"
|
||
}
|
||
}, [_c('span', [_vm._v("\n OAuth Clients\n ")]), _vm._v(" "), _c('a', {
|
||
staticClass: "action-link",
|
||
on: {
|
||
"click": _vm.showCreateClientForm
|
||
}
|
||
}, [_vm._v("\n Create New Client\n ")])])]), _vm._v(" "), _c('div', {
|
||
staticClass: "panel-body"
|
||
}, [(_vm.clients.length === 0) ? _c('p', {
|
||
staticClass: "m-b-none"
|
||
}, [_vm._v("\n You have not created any OAuth clients.\n ")]) : _vm._e(), _vm._v(" "), (_vm.clients.length > 0) ? _c('table', {
|
||
staticClass: "table table-borderless m-b-none"
|
||
}, [_vm._m(0), _vm._v(" "), _c('tbody', _vm._l((_vm.clients), function(client) {
|
||
return _c('tr', [_c('td', {
|
||
staticStyle: {
|
||
"vertical-align": "middle"
|
||
}
|
||
}, [_vm._v("\n " + _vm._s(client.id) + "\n ")]), _vm._v(" "), _c('td', {
|
||
staticStyle: {
|
||
"vertical-align": "middle"
|
||
}
|
||
}, [_vm._v("\n " + _vm._s(client.name) + "\n ")]), _vm._v(" "), _c('td', {
|
||
staticStyle: {
|
||
"vertical-align": "middle"
|
||
}
|
||
}, [_c('code', [_vm._v(_vm._s(client.secret))])]), _vm._v(" "), _c('td', {
|
||
staticStyle: {
|
||
"vertical-align": "middle"
|
||
}
|
||
}, [_c('a', {
|
||
staticClass: "action-link",
|
||
on: {
|
||
"click": function($event) {
|
||
_vm.edit(client)
|
||
}
|
||
}
|
||
}, [_vm._v("\n Edit\n ")])]), _vm._v(" "), _c('td', {
|
||
staticStyle: {
|
||
"vertical-align": "middle"
|
||
}
|
||
}, [_c('a', {
|
||
staticClass: "action-link text-danger",
|
||
on: {
|
||
"click": function($event) {
|
||
_vm.destroy(client)
|
||
}
|
||
}
|
||
}, [_vm._v("\n Delete\n ")])])])
|
||
}))]) : _vm._e()])]), _vm._v(" "), _c('div', {
|
||
staticClass: "modal fade",
|
||
attrs: {
|
||
"id": "modal-create-client",
|
||
"tabindex": "-1",
|
||
"role": "dialog"
|
||
}
|
||
}, [_c('div', {
|
||
staticClass: "modal-dialog"
|
||
}, [_c('div', {
|
||
staticClass: "modal-content"
|
||
}, [_vm._m(1), _vm._v(" "), _c('div', {
|
||
staticClass: "modal-body"
|
||
}, [(_vm.createForm.errors.length > 0) ? _c('div', {
|
||
staticClass: "alert alert-danger"
|
||
}, [_vm._m(2), _vm._v(" "), _c('br'), _vm._v(" "), _c('ul', _vm._l((_vm.createForm.errors), function(error) {
|
||
return _c('li', [_vm._v("\n " + _vm._s(error) + "\n ")])
|
||
}))]) : _vm._e(), _vm._v(" "), _c('form', {
|
||
staticClass: "form-horizontal",
|
||
attrs: {
|
||
"role": "form"
|
||
}
|
||
}, [_c('div', {
|
||
staticClass: "form-group"
|
||
}, [_c('label', {
|
||
staticClass: "col-md-3 control-label"
|
||
}, [_vm._v("Name")]), _vm._v(" "), _c('div', {
|
||
staticClass: "col-md-7"
|
||
}, [_c('input', {
|
||
directives: [{
|
||
name: "model",
|
||
rawName: "v-model",
|
||
value: (_vm.createForm.name),
|
||
expression: "createForm.name"
|
||
}],
|
||
staticClass: "form-control",
|
||
attrs: {
|
||
"id": "create-client-name",
|
||
"type": "text"
|
||
},
|
||
domProps: {
|
||
"value": (_vm.createForm.name)
|
||
},
|
||
on: {
|
||
"keyup": function($event) {
|
||
if (!('button' in $event) && _vm._k($event.keyCode, "enter", 13)) { return null; }
|
||
_vm.store($event)
|
||
},
|
||
"input": function($event) {
|
||
if ($event.target.composing) { return; }
|
||
_vm.createForm.name = $event.target.value
|
||
}
|
||
}
|
||
}), _vm._v(" "), _c('span', {
|
||
staticClass: "help-block"
|
||
}, [_vm._v("\n Something your users will recognize and trust.\n ")])])]), _vm._v(" "), _c('div', {
|
||
staticClass: "form-group"
|
||
}, [_c('label', {
|
||
staticClass: "col-md-3 control-label"
|
||
}, [_vm._v("Redirect URL")]), _vm._v(" "), _c('div', {
|
||
staticClass: "col-md-7"
|
||
}, [_c('input', {
|
||
directives: [{
|
||
name: "model",
|
||
rawName: "v-model",
|
||
value: (_vm.createForm.redirect),
|
||
expression: "createForm.redirect"
|
||
}],
|
||
staticClass: "form-control",
|
||
attrs: {
|
||
"type": "text",
|
||
"name": "redirect"
|
||
},
|
||
domProps: {
|
||
"value": (_vm.createForm.redirect)
|
||
},
|
||
on: {
|
||
"keyup": function($event) {
|
||
if (!('button' in $event) && _vm._k($event.keyCode, "enter", 13)) { return null; }
|
||
_vm.store($event)
|
||
},
|
||
"input": function($event) {
|
||
if ($event.target.composing) { return; }
|
||
_vm.createForm.redirect = $event.target.value
|
||
}
|
||
}
|
||
}), _vm._v(" "), _c('span', {
|
||
staticClass: "help-block"
|
||
}, [_vm._v("\n Your application's authorization callback URL.\n ")])])])])]), _vm._v(" "), _c('div', {
|
||
staticClass: "modal-footer"
|
||
}, [_c('button', {
|
||
staticClass: "btn btn-default",
|
||
attrs: {
|
||
"type": "button",
|
||
"data-dismiss": "modal"
|
||
}
|
||
}, [_vm._v("Close")]), _vm._v(" "), _c('button', {
|
||
staticClass: "btn btn-primary",
|
||
attrs: {
|
||
"type": "button"
|
||
},
|
||
on: {
|
||
"click": _vm.store
|
||
}
|
||
}, [_vm._v("\n Create\n ")])])])])]), _vm._v(" "), _c('div', {
|
||
staticClass: "modal fade",
|
||
attrs: {
|
||
"id": "modal-edit-client",
|
||
"tabindex": "-1",
|
||
"role": "dialog"
|
||
}
|
||
}, [_c('div', {
|
||
staticClass: "modal-dialog"
|
||
}, [_c('div', {
|
||
staticClass: "modal-content"
|
||
}, [_vm._m(3), _vm._v(" "), _c('div', {
|
||
staticClass: "modal-body"
|
||
}, [(_vm.editForm.errors.length > 0) ? _c('div', {
|
||
staticClass: "alert alert-danger"
|
||
}, [_vm._m(4), _vm._v(" "), _c('br'), _vm._v(" "), _c('ul', _vm._l((_vm.editForm.errors), function(error) {
|
||
return _c('li', [_vm._v("\n " + _vm._s(error) + "\n ")])
|
||
}))]) : _vm._e(), _vm._v(" "), _c('form', {
|
||
staticClass: "form-horizontal",
|
||
attrs: {
|
||
"role": "form"
|
||
}
|
||
}, [_c('div', {
|
||
staticClass: "form-group"
|
||
}, [_c('label', {
|
||
staticClass: "col-md-3 control-label"
|
||
}, [_vm._v("Name")]), _vm._v(" "), _c('div', {
|
||
staticClass: "col-md-7"
|
||
}, [_c('input', {
|
||
directives: [{
|
||
name: "model",
|
||
rawName: "v-model",
|
||
value: (_vm.editForm.name),
|
||
expression: "editForm.name"
|
||
}],
|
||
staticClass: "form-control",
|
||
attrs: {
|
||
"id": "edit-client-name",
|
||
"type": "text"
|
||
},
|
||
domProps: {
|
||
"value": (_vm.editForm.name)
|
||
},
|
||
on: {
|
||
"keyup": function($event) {
|
||
if (!('button' in $event) && _vm._k($event.keyCode, "enter", 13)) { return null; }
|
||
_vm.update($event)
|
||
},
|
||
"input": function($event) {
|
||
if ($event.target.composing) { return; }
|
||
_vm.editForm.name = $event.target.value
|
||
}
|
||
}
|
||
}), _vm._v(" "), _c('span', {
|
||
staticClass: "help-block"
|
||
}, [_vm._v("\n Something your users will recognize and trust.\n ")])])]), _vm._v(" "), _c('div', {
|
||
staticClass: "form-group"
|
||
}, [_c('label', {
|
||
staticClass: "col-md-3 control-label"
|
||
}, [_vm._v("Redirect URL")]), _vm._v(" "), _c('div', {
|
||
staticClass: "col-md-7"
|
||
}, [_c('input', {
|
||
directives: [{
|
||
name: "model",
|
||
rawName: "v-model",
|
||
value: (_vm.editForm.redirect),
|
||
expression: "editForm.redirect"
|
||
}],
|
||
staticClass: "form-control",
|
||
attrs: {
|
||
"type": "text",
|
||
"name": "redirect"
|
||
},
|
||
domProps: {
|
||
"value": (_vm.editForm.redirect)
|
||
},
|
||
on: {
|
||
"keyup": function($event) {
|
||
if (!('button' in $event) && _vm._k($event.keyCode, "enter", 13)) { return null; }
|
||
_vm.update($event)
|
||
},
|
||
"input": function($event) {
|
||
if ($event.target.composing) { return; }
|
||
_vm.editForm.redirect = $event.target.value
|
||
}
|
||
}
|
||
}), _vm._v(" "), _c('span', {
|
||
staticClass: "help-block"
|
||
}, [_vm._v("\n Your application's authorization callback URL.\n ")])])])])]), _vm._v(" "), _c('div', {
|
||
staticClass: "modal-footer"
|
||
}, [_c('button', {
|
||
staticClass: "btn btn-default",
|
||
attrs: {
|
||
"type": "button",
|
||
"data-dismiss": "modal"
|
||
}
|
||
}, [_vm._v("Close")]), _vm._v(" "), _c('button', {
|
||
staticClass: "btn btn-primary",
|
||
attrs: {
|
||
"type": "button"
|
||
},
|
||
on: {
|
||
"click": _vm.update
|
||
}
|
||
}, [_vm._v("\n Save Changes\n ")])])])])])])
|
||
},staticRenderFns: [function (){var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;
|
||
return _c('thead', [_c('tr', [_c('th', [_vm._v("Client ID")]), _vm._v(" "), _c('th', [_vm._v("Name")]), _vm._v(" "), _c('th', [_vm._v("Secret")]), _vm._v(" "), _c('th'), _vm._v(" "), _c('th')])])
|
||
},function (){var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;
|
||
return _c('div', {
|
||
staticClass: "modal-header"
|
||
}, [_c('button', {
|
||
staticClass: "close",
|
||
attrs: {
|
||
"type": "button ",
|
||
"data-dismiss": "modal",
|
||
"aria-hidden": "true"
|
||
}
|
||
}, [_vm._v("×")]), _vm._v(" "), _c('h4', {
|
||
staticClass: "modal-title"
|
||
}, [_vm._v("\n Create Client\n ")])])
|
||
},function (){var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;
|
||
return _c('p', [_c('strong', [_vm._v("Whoops!")]), _vm._v(" Something went wrong!")])
|
||
},function (){var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;
|
||
return _c('div', {
|
||
staticClass: "modal-header"
|
||
}, [_c('button', {
|
||
staticClass: "close",
|
||
attrs: {
|
||
"type": "button ",
|
||
"data-dismiss": "modal",
|
||
"aria-hidden": "true"
|
||
}
|
||
}, [_vm._v("×")]), _vm._v(" "), _c('h4', {
|
||
staticClass: "modal-title"
|
||
}, [_vm._v("\n Edit Client\n ")])])
|
||
},function (){var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;
|
||
return _c('p', [_c('strong', [_vm._v("Whoops!")]), _vm._v(" Something went wrong!")])
|
||
}]}
|
||
module.exports.render._withStripped = true
|
||
if (false) {
|
||
module.hot.accept()
|
||
if (module.hot.data) {
|
||
require("vue-hot-reload-api").rerender("data-v-e9c80318", module.exports)
|
||
}
|
||
}
|
||
|
||
/***/ }),
|
||
/* 21 */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
var disposed = false
|
||
function injectStyle (ssrContext) {
|
||
if (disposed) return
|
||
__webpack_require__(22)
|
||
}
|
||
var Component = __webpack_require__(2)(
|
||
/* script */
|
||
__webpack_require__(24),
|
||
/* template */
|
||
__webpack_require__(25),
|
||
/* styles */
|
||
injectStyle,
|
||
/* scopeId */
|
||
"data-v-de0d0e4e",
|
||
/* moduleIdentifier (server only) */
|
||
null
|
||
)
|
||
Component.options.__file = "/home/hydrogen/work/snipe-it/resources/assets/js/components/passport/AuthorizedClients.vue"
|
||
if (Component.esModule && Object.keys(Component.esModule).some(function (key) {return key !== "default" && key.substr(0, 2) !== "__"})) {console.error("named exports are not supported in *.vue files.")}
|
||
if (Component.options.functional) {console.error("[vue-loader] AuthorizedClients.vue: functional components are not supported with templates, they should use render functions.")}
|
||
|
||
/* hot reload */
|
||
if (false) {(function () {
|
||
var hotAPI = require("vue-hot-reload-api")
|
||
hotAPI.install(require("vue"), false)
|
||
if (!hotAPI.compatible) return
|
||
module.hot.accept()
|
||
if (!module.hot.data) {
|
||
hotAPI.createRecord("data-v-de0d0e4e", Component.options)
|
||
} else {
|
||
hotAPI.reload("data-v-de0d0e4e", Component.options)
|
||
}
|
||
module.hot.dispose(function (data) {
|
||
disposed = true
|
||
})
|
||
})()}
|
||
|
||
module.exports = Component.exports
|
||
|
||
|
||
/***/ }),
|
||
/* 22 */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
// style-loader: Adds some css to the DOM by adding a <style> tag
|
||
|
||
// load the styles
|
||
var content = __webpack_require__(23);
|
||
if(typeof content === 'string') content = [[module.i, content, '']];
|
||
if(content.locals) module.exports = content.locals;
|
||
// add the styles to the DOM
|
||
var update = __webpack_require__(1)("e5c39684", content, false);
|
||
// Hot Module Replacement
|
||
if(false) {
|
||
// When the styles change, update the <style> tags
|
||
if(!content.locals) {
|
||
module.hot.accept("!!../../../../../node_modules/css-loader/index.js?sourceMap!../../../../../node_modules/vue-loader/lib/style-compiler/index.js?{\"vue\":true,\"id\":\"data-v-de0d0e4e\",\"scoped\":true,\"hasInlineConfig\":true}!../../../../../node_modules/vue-loader/lib/selector.js?type=styles&index=0!./AuthorizedClients.vue", function() {
|
||
var newContent = require("!!../../../../../node_modules/css-loader/index.js?sourceMap!../../../../../node_modules/vue-loader/lib/style-compiler/index.js?{\"vue\":true,\"id\":\"data-v-de0d0e4e\",\"scoped\":true,\"hasInlineConfig\":true}!../../../../../node_modules/vue-loader/lib/selector.js?type=styles&index=0!./AuthorizedClients.vue");
|
||
if(typeof newContent === 'string') newContent = [[module.id, newContent, '']];
|
||
update(newContent);
|
||
});
|
||
}
|
||
// When the module is disposed, remove the <style> tags
|
||
module.hot.dispose(function() { update(); });
|
||
}
|
||
|
||
/***/ }),
|
||
/* 23 */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
exports = module.exports = __webpack_require__(0)(true);
|
||
// imports
|
||
|
||
|
||
// module
|
||
exports.push([module.i, "\n.action-link[data-v-de0d0e4e] {\n cursor: pointer;\n}\n.m-b-none[data-v-de0d0e4e] {\n margin-bottom: 0;\n}\n", "", {"version":3,"sources":["/home/hydrogen/work/snipe-it/resources/assets/js/components/passport/AuthorizedClients.vue?a99076c0"],"names":[],"mappings":";AACA;IACA,gBAAA;CACA;AAEA;IACA,iBAAA;CACA","file":"AuthorizedClients.vue","sourcesContent":["<style scoped>\n .action-link {\n cursor: pointer;\n }\n\n .m-b-none {\n margin-bottom: 0;\n }\n</style>\n\n<template>\n <div>\n <div v-if=\"tokens.length > 0\">\n <div class=\"panel panel-default\">\n <div class=\"panel-heading\">Authorized Applications</div>\n\n <div class=\"panel-body\">\n <!-- Authorized Tokens -->\n <table class=\"table table-borderless m-b-none\">\n <thead>\n <tr>\n <th>Name</th>\n <th>Scopes</th>\n <th></th>\n </tr>\n </thead>\n\n <tbody>\n <tr v-for=\"token in tokens\">\n <!-- Client Name -->\n <td style=\"vertical-align: middle;\">\n {{ token.client.name }}\n </td>\n\n <!-- Scopes -->\n <td style=\"vertical-align: middle;\">\n <span v-if=\"token.scopes.length > 0\">\n {{ token.scopes.join(', ') }}\n </span>\n </td>\n\n <!-- Revoke Button -->\n <td style=\"vertical-align: middle;\">\n <a class=\"action-link text-danger\" @click=\"revoke(token)\">\n Revoke\n </a>\n </td>\n </tr>\n </tbody>\n </table>\n </div>\n </div>\n </div>\n </div>\n</template>\n\n<script>\n export default {\n /*\n * The component's data.\n */\n data() {\n return {\n tokens: []\n };\n },\n\n /**\n * Prepare the component (Vue 1.x).\n */\n ready() {\n this.prepareComponent();\n },\n\n /**\n * Prepare the component (Vue 2.x).\n */\n mounted() {\n this.prepareComponent();\n },\n\n methods: {\n /**\n * Prepare the component (Vue 2.x).\n */\n prepareComponent() {\n this.getTokens();\n },\n\n /**\n * Get all of the authorized tokens for the user.\n */\n getTokens() {\n this.$http.get('/oauth/tokens')\n .then(response => {\n this.tokens = response.data;\n });\n },\n\n /**\n * Revoke the given token.\n */\n revoke(token) {\n this.$http.delete('/oauth/tokens/' + token.id)\n .then(response => {\n this.getTokens();\n });\n }\n }\n }\n</script>\n"],"sourceRoot":""}]);
|
||
|
||
// exports
|
||
|
||
|
||
/***/ }),
|
||
/* 24 */
|
||
/***/ (function(module, __webpack_exports__, __webpack_require__) {
|
||
|
||
"use strict";
|
||
Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
|
||
/* harmony default export */ __webpack_exports__["default"] = ({
|
||
/*
|
||
* The component's data.
|
||
*/
|
||
data: function data() {
|
||
return {
|
||
tokens: []
|
||
};
|
||
},
|
||
|
||
|
||
/**
|
||
* Prepare the component (Vue 1.x).
|
||
*/
|
||
ready: function ready() {
|
||
this.prepareComponent();
|
||
},
|
||
|
||
|
||
/**
|
||
* Prepare the component (Vue 2.x).
|
||
*/
|
||
mounted: function mounted() {
|
||
this.prepareComponent();
|
||
},
|
||
|
||
|
||
methods: {
|
||
/**
|
||
* Prepare the component (Vue 2.x).
|
||
*/
|
||
prepareComponent: function prepareComponent() {
|
||
this.getTokens();
|
||
},
|
||
|
||
|
||
/**
|
||
* Get all of the authorized tokens for the user.
|
||
*/
|
||
getTokens: function getTokens() {
|
||
var _this = this;
|
||
|
||
this.$http.get('/oauth/tokens').then(function (response) {
|
||
_this.tokens = response.data;
|
||
});
|
||
},
|
||
|
||
|
||
/**
|
||
* Revoke the given token.
|
||
*/
|
||
revoke: function revoke(token) {
|
||
var _this2 = this;
|
||
|
||
this.$http.delete('/oauth/tokens/' + token.id).then(function (response) {
|
||
_this2.getTokens();
|
||
});
|
||
}
|
||
}
|
||
});
|
||
|
||
/***/ }),
|
||
/* 25 */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
module.exports={render:function (){var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;
|
||
return _c('div', [(_vm.tokens.length > 0) ? _c('div', [_c('div', {
|
||
staticClass: "panel panel-default"
|
||
}, [_c('div', {
|
||
staticClass: "panel-heading"
|
||
}, [_vm._v("Authorized Applications")]), _vm._v(" "), _c('div', {
|
||
staticClass: "panel-body"
|
||
}, [_c('table', {
|
||
staticClass: "table table-borderless m-b-none"
|
||
}, [_vm._m(0), _vm._v(" "), _c('tbody', _vm._l((_vm.tokens), function(token) {
|
||
return _c('tr', [_c('td', {
|
||
staticStyle: {
|
||
"vertical-align": "middle"
|
||
}
|
||
}, [_vm._v("\n " + _vm._s(token.client.name) + "\n ")]), _vm._v(" "), _c('td', {
|
||
staticStyle: {
|
||
"vertical-align": "middle"
|
||
}
|
||
}, [(token.scopes.length > 0) ? _c('span', [_vm._v("\n " + _vm._s(token.scopes.join(', ')) + "\n ")]) : _vm._e()]), _vm._v(" "), _c('td', {
|
||
staticStyle: {
|
||
"vertical-align": "middle"
|
||
}
|
||
}, [_c('a', {
|
||
staticClass: "action-link text-danger",
|
||
on: {
|
||
"click": function($event) {
|
||
_vm.revoke(token)
|
||
}
|
||
}
|
||
}, [_vm._v("\n Revoke\n ")])])])
|
||
}))])])])]) : _vm._e()])
|
||
},staticRenderFns: [function (){var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;
|
||
return _c('thead', [_c('tr', [_c('th', [_vm._v("Name")]), _vm._v(" "), _c('th', [_vm._v("Scopes")]), _vm._v(" "), _c('th')])])
|
||
}]}
|
||
module.exports.render._withStripped = true
|
||
if (false) {
|
||
module.hot.accept()
|
||
if (module.hot.data) {
|
||
require("vue-hot-reload-api").rerender("data-v-de0d0e4e", module.exports)
|
||
}
|
||
}
|
||
|
||
/***/ }),
|
||
/* 26 */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
var disposed = false
|
||
function injectStyle (ssrContext) {
|
||
if (disposed) return
|
||
__webpack_require__(27)
|
||
}
|
||
var Component = __webpack_require__(2)(
|
||
/* script */
|
||
__webpack_require__(29),
|
||
/* template */
|
||
__webpack_require__(30),
|
||
/* styles */
|
||
injectStyle,
|
||
/* scopeId */
|
||
"data-v-225778c2",
|
||
/* moduleIdentifier (server only) */
|
||
null
|
||
)
|
||
Component.options.__file = "/home/hydrogen/work/snipe-it/resources/assets/js/components/passport/PersonalAccessTokens.vue"
|
||
if (Component.esModule && Object.keys(Component.esModule).some(function (key) {return key !== "default" && key.substr(0, 2) !== "__"})) {console.error("named exports are not supported in *.vue files.")}
|
||
if (Component.options.functional) {console.error("[vue-loader] PersonalAccessTokens.vue: functional components are not supported with templates, they should use render functions.")}
|
||
|
||
/* hot reload */
|
||
if (false) {(function () {
|
||
var hotAPI = require("vue-hot-reload-api")
|
||
hotAPI.install(require("vue"), false)
|
||
if (!hotAPI.compatible) return
|
||
module.hot.accept()
|
||
if (!module.hot.data) {
|
||
hotAPI.createRecord("data-v-225778c2", Component.options)
|
||
} else {
|
||
hotAPI.reload("data-v-225778c2", Component.options)
|
||
}
|
||
module.hot.dispose(function (data) {
|
||
disposed = true
|
||
})
|
||
})()}
|
||
|
||
module.exports = Component.exports
|
||
|
||
|
||
/***/ }),
|
||
/* 27 */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
// style-loader: Adds some css to the DOM by adding a <style> tag
|
||
|
||
// load the styles
|
||
var content = __webpack_require__(28);
|
||
if(typeof content === 'string') content = [[module.i, content, '']];
|
||
if(content.locals) module.exports = content.locals;
|
||
// add the styles to the DOM
|
||
var update = __webpack_require__(1)("f4a39e98", content, false);
|
||
// Hot Module Replacement
|
||
if(false) {
|
||
// When the styles change, update the <style> tags
|
||
if(!content.locals) {
|
||
module.hot.accept("!!../../../../../node_modules/css-loader/index.js?sourceMap!../../../../../node_modules/vue-loader/lib/style-compiler/index.js?{\"vue\":true,\"id\":\"data-v-225778c2\",\"scoped\":true,\"hasInlineConfig\":true}!../../../../../node_modules/vue-loader/lib/selector.js?type=styles&index=0!./PersonalAccessTokens.vue", function() {
|
||
var newContent = require("!!../../../../../node_modules/css-loader/index.js?sourceMap!../../../../../node_modules/vue-loader/lib/style-compiler/index.js?{\"vue\":true,\"id\":\"data-v-225778c2\",\"scoped\":true,\"hasInlineConfig\":true}!../../../../../node_modules/vue-loader/lib/selector.js?type=styles&index=0!./PersonalAccessTokens.vue");
|
||
if(typeof newContent === 'string') newContent = [[module.id, newContent, '']];
|
||
update(newContent);
|
||
});
|
||
}
|
||
// When the module is disposed, remove the <style> tags
|
||
module.hot.dispose(function() { update(); });
|
||
}
|
||
|
||
/***/ }),
|
||
/* 28 */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
exports = module.exports = __webpack_require__(0)(true);
|
||
// imports
|
||
|
||
|
||
// module
|
||
exports.push([module.i, "\n.action-link[data-v-225778c2] {\n cursor: pointer;\n}\n.m-b-none[data-v-225778c2] {\n margin-bottom: 0;\n}\n", "", {"version":3,"sources":["/home/hydrogen/work/snipe-it/resources/assets/js/components/passport/PersonalAccessTokens.vue?5734f4e4"],"names":[],"mappings":";AACA;IACA,gBAAA;CACA;AAEA;IACA,iBAAA;CACA","file":"PersonalAccessTokens.vue","sourcesContent":["<style scoped>\n .action-link {\n cursor: pointer;\n }\n\n .m-b-none {\n margin-bottom: 0;\n }\n</style>\n\n<template>\n <div>\n <div>\n <div class=\"panel panel-default\">\n <div class=\"panel-heading\">\n <div style=\"display: flex; justify-content: space-between; align-items: center;\">\n <span>\n Personal Access Tokens\n </span>\n\n <a class=\"action-link\" @click=\"showCreateTokenForm\">\n Create New Token\n </a>\n </div>\n </div>\n\n <div class=\"panel-body\">\n <!-- No Tokens Notice -->\n <p class=\"m-b-none\" v-if=\"tokens.length === 0\">\n You have not created any personal access tokens.\n </p>\n\n <!-- Personal Access Tokens -->\n <table class=\"table table-borderless m-b-none\" v-if=\"tokens.length > 0\">\n <thead>\n <tr>\n <th>Name</th>\n <th></th>\n </tr>\n </thead>\n\n <tbody>\n <tr v-for=\"token in tokens\">\n <!-- Client Name -->\n <td style=\"vertical-align: middle;\">\n {{ token.name }}\n </td>\n\n <!-- Delete Button -->\n <td style=\"vertical-align: middle;\">\n <a class=\"action-link text-danger\" @click=\"revoke(token)\">\n Delete\n </a>\n </td>\n </tr>\n </tbody>\n </table>\n </div>\n </div>\n </div>\n\n <!-- Create Token Modal -->\n <div class=\"modal fade\" id=\"modal-create-token\" tabindex=\"-1\" role=\"dialog\">\n <div class=\"modal-dialog\">\n <div class=\"modal-content\">\n <div class=\"modal-header\">\n <button type=\"button \" class=\"close\" data-dismiss=\"modal\" aria-hidden=\"true\">×</button>\n\n <h4 class=\"modal-title\">\n Create Token\n </h4>\n </div>\n\n <div class=\"modal-body\">\n <!-- Form Errors -->\n <div class=\"alert alert-danger\" v-if=\"form.errors.length > 0\">\n <p><strong>Whoops!</strong> Something went wrong!</p>\n <br>\n <ul>\n <li v-for=\"error in form.errors\">\n {{ error }}\n </li>\n </ul>\n </div>\n\n <!-- Create Token Form -->\n <form class=\"form-horizontal\" role=\"form\" @submit.prevent=\"store\">\n <!-- Name -->\n <div class=\"form-group\">\n <label class=\"col-md-4 control-label\">Name</label>\n\n <div class=\"col-md-6\">\n <input id=\"create-token-name\" type=\"text\" class=\"form-control\" name=\"name\" v-model=\"form.name\">\n </div>\n </div>\n\n <!-- Scopes -->\n <div class=\"form-group\" v-if=\"scopes.length > 0\">\n <label class=\"col-md-4 control-label\">Scopes</label>\n\n <div class=\"col-md-6\">\n <div v-for=\"scope in scopes\">\n <div class=\"checkbox\">\n <label>\n <input type=\"checkbox\"\n @click=\"toggleScope(scope.id)\"\n :checked=\"scopeIsAssigned(scope.id)\">\n\n {{ scope.id }}\n </label>\n </div>\n </div>\n </div>\n </div>\n </form>\n </div>\n\n <!-- Modal Actions -->\n <div class=\"modal-footer\">\n <button type=\"button\" class=\"btn btn-default\" data-dismiss=\"modal\">Close</button>\n\n <button type=\"button\" class=\"btn btn-primary\" @click=\"store\">\n Create\n </button>\n </div>\n </div>\n </div>\n </div>\n\n <!-- Access Token Modal -->\n <div class=\"modal fade\" id=\"modal-access-token\" tabindex=\"-1\" role=\"dialog\">\n <div class=\"modal-dialog\">\n <div class=\"modal-content\">\n <div class=\"modal-header\">\n <button type=\"button \" class=\"close\" data-dismiss=\"modal\" aria-hidden=\"true\">×</button>\n\n <h4 class=\"modal-title\">\n Personal Access Token\n </h4>\n </div>\n\n <div class=\"modal-body\">\n <p>\n Here is your new personal access token. This is the only time it will be shown so don't lose it!\n You may now use this token to make API requests.\n </p>\n\n <pre><code>{{ accessToken }}</code></pre>\n </div>\n\n <!-- Modal Actions -->\n <div class=\"modal-footer\">\n <button type=\"button\" class=\"btn btn-default\" data-dismiss=\"modal\">Close</button>\n </div>\n </div>\n </div>\n </div>\n </div>\n</template>\n\n<script>\n export default {\n /*\n * The component's data.\n */\n data() {\n return {\n accessToken: null,\n\n tokens: [],\n scopes: [],\n\n form: {\n name: '',\n scopes: [],\n errors: []\n }\n };\n },\n\n /**\n * Prepare the component (Vue 1.x).\n */\n ready() {\n this.prepareComponent();\n },\n\n /**\n * Prepare the component (Vue 2.x).\n */\n mounted() {\n this.prepareComponent();\n },\n\n methods: {\n /**\n * Prepare the component.\n */\n prepareComponent() {\n this.getTokens();\n this.getScopes();\n\n $('#modal-create-token').on('shown.bs.modal', () => {\n $('#create-token-name').focus();\n });\n },\n\n /**\n * Get all of the personal access tokens for the user.\n */\n getTokens() {\n this.$http.get('/oauth/personal-access-tokens')\n .then(response => {\n this.tokens = response.data;\n });\n },\n\n /**\n * Get all of the available scopes.\n */\n getScopes() {\n this.$http.get('/oauth/scopes')\n .then(response => {\n this.scopes = response.data;\n });\n },\n\n /**\n * Show the form for creating new tokens.\n */\n showCreateTokenForm() {\n $('#modal-create-token').modal('show');\n },\n\n /**\n * Create a new personal access token.\n */\n store() {\n this.accessToken = null;\n\n this.form.errors = [];\n\n this.$http.post('/oauth/personal-access-tokens', this.form)\n .then(response => {\n this.form.name = '';\n this.form.scopes = [];\n this.form.errors = [];\n\n this.tokens.push(response.data.token);\n\n this.showAccessToken(response.data.accessToken);\n })\n .catch(response => {\n if (typeof response.data === 'object') {\n this.form.errors = _.flatten(_.toArray(response.data));\n } else {\n console.dir(this.form);\n this.form.errors = ['Something went wrong. Please try again.'];\n }\n });\n },\n\n /**\n * Toggle the given scope in the list of assigned scopes.\n */\n toggleScope(scope) {\n if (this.scopeIsAssigned(scope)) {\n this.form.scopes = _.reject(this.form.scopes, s => s == scope);\n } else {\n this.form.scopes.push(scope);\n }\n },\n\n /**\n * Determine if the given scope has been assigned to the token.\n */\n scopeIsAssigned(scope) {\n return _.indexOf(this.form.scopes, scope) >= 0;\n },\n\n /**\n * Show the given access token to the user.\n */\n showAccessToken(accessToken) {\n $('#modal-create-token').modal('hide');\n\n this.accessToken = accessToken;\n\n $('#modal-access-token').modal('show');\n },\n\n /**\n * Revoke the given token.\n */\n revoke(token) {\n this.$http.delete('/oauth/personal-access-tokens/' + token.id)\n .then(response => {\n this.getTokens();\n });\n }\n }\n }\n</script>\n"],"sourceRoot":""}]);
|
||
|
||
// exports
|
||
|
||
|
||
/***/ }),
|
||
/* 29 */
|
||
/***/ (function(module, __webpack_exports__, __webpack_require__) {
|
||
|
||
"use strict";
|
||
Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
|
||
var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
|
||
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
|
||
/* harmony default export */ __webpack_exports__["default"] = ({
|
||
/*
|
||
* The component's data.
|
||
*/
|
||
data: function data() {
|
||
return {
|
||
accessToken: null,
|
||
|
||
tokens: [],
|
||
scopes: [],
|
||
|
||
form: {
|
||
name: '',
|
||
scopes: [],
|
||
errors: []
|
||
}
|
||
};
|
||
},
|
||
|
||
|
||
/**
|
||
* Prepare the component (Vue 1.x).
|
||
*/
|
||
ready: function ready() {
|
||
this.prepareComponent();
|
||
},
|
||
|
||
|
||
/**
|
||
* Prepare the component (Vue 2.x).
|
||
*/
|
||
mounted: function mounted() {
|
||
this.prepareComponent();
|
||
},
|
||
|
||
|
||
methods: {
|
||
/**
|
||
* Prepare the component.
|
||
*/
|
||
prepareComponent: function prepareComponent() {
|
||
this.getTokens();
|
||
this.getScopes();
|
||
|
||
$('#modal-create-token').on('shown.bs.modal', function () {
|
||
$('#create-token-name').focus();
|
||
});
|
||
},
|
||
|
||
|
||
/**
|
||
* Get all of the personal access tokens for the user.
|
||
*/
|
||
getTokens: function getTokens() {
|
||
var _this = this;
|
||
|
||
this.$http.get('/oauth/personal-access-tokens').then(function (response) {
|
||
_this.tokens = response.data;
|
||
});
|
||
},
|
||
|
||
|
||
/**
|
||
* Get all of the available scopes.
|
||
*/
|
||
getScopes: function getScopes() {
|
||
var _this2 = this;
|
||
|
||
this.$http.get('/oauth/scopes').then(function (response) {
|
||
_this2.scopes = response.data;
|
||
});
|
||
},
|
||
|
||
|
||
/**
|
||
* Show the form for creating new tokens.
|
||
*/
|
||
showCreateTokenForm: function showCreateTokenForm() {
|
||
$('#modal-create-token').modal('show');
|
||
},
|
||
|
||
|
||
/**
|
||
* Create a new personal access token.
|
||
*/
|
||
store: function store() {
|
||
var _this3 = this;
|
||
|
||
this.accessToken = null;
|
||
|
||
this.form.errors = [];
|
||
|
||
this.$http.post('/oauth/personal-access-tokens', this.form).then(function (response) {
|
||
_this3.form.name = '';
|
||
_this3.form.scopes = [];
|
||
_this3.form.errors = [];
|
||
|
||
_this3.tokens.push(response.data.token);
|
||
|
||
_this3.showAccessToken(response.data.accessToken);
|
||
}).catch(function (response) {
|
||
if (_typeof(response.data) === 'object') {
|
||
_this3.form.errors = _.flatten(_.toArray(response.data));
|
||
} else {
|
||
console.dir(_this3.form);
|
||
_this3.form.errors = ['Something went wrong. Please try again.'];
|
||
}
|
||
});
|
||
},
|
||
|
||
|
||
/**
|
||
* Toggle the given scope in the list of assigned scopes.
|
||
*/
|
||
toggleScope: function toggleScope(scope) {
|
||
if (this.scopeIsAssigned(scope)) {
|
||
this.form.scopes = _.reject(this.form.scopes, function (s) {
|
||
return s == scope;
|
||
});
|
||
} else {
|
||
this.form.scopes.push(scope);
|
||
}
|
||
},
|
||
|
||
|
||
/**
|
||
* Determine if the given scope has been assigned to the token.
|
||
*/
|
||
scopeIsAssigned: function scopeIsAssigned(scope) {
|
||
return _.indexOf(this.form.scopes, scope) >= 0;
|
||
},
|
||
|
||
|
||
/**
|
||
* Show the given access token to the user.
|
||
*/
|
||
showAccessToken: function showAccessToken(accessToken) {
|
||
$('#modal-create-token').modal('hide');
|
||
|
||
this.accessToken = accessToken;
|
||
|
||
$('#modal-access-token').modal('show');
|
||
},
|
||
|
||
|
||
/**
|
||
* Revoke the given token.
|
||
*/
|
||
revoke: function revoke(token) {
|
||
var _this4 = this;
|
||
|
||
this.$http.delete('/oauth/personal-access-tokens/' + token.id).then(function (response) {
|
||
_this4.getTokens();
|
||
});
|
||
}
|
||
}
|
||
});
|
||
|
||
/***/ }),
|
||
/* 30 */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
module.exports={render:function (){var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;
|
||
return _c('div', [_c('div', [_c('div', {
|
||
staticClass: "panel panel-default"
|
||
}, [_c('div', {
|
||
staticClass: "panel-heading"
|
||
}, [_c('div', {
|
||
staticStyle: {
|
||
"display": "flex",
|
||
"justify-content": "space-between",
|
||
"align-items": "center"
|
||
}
|
||
}, [_c('span', [_vm._v("\n Personal Access Tokens\n ")]), _vm._v(" "), _c('a', {
|
||
staticClass: "action-link",
|
||
on: {
|
||
"click": _vm.showCreateTokenForm
|
||
}
|
||
}, [_vm._v("\n Create New Token\n ")])])]), _vm._v(" "), _c('div', {
|
||
staticClass: "panel-body"
|
||
}, [(_vm.tokens.length === 0) ? _c('p', {
|
||
staticClass: "m-b-none"
|
||
}, [_vm._v("\n You have not created any personal access tokens.\n ")]) : _vm._e(), _vm._v(" "), (_vm.tokens.length > 0) ? _c('table', {
|
||
staticClass: "table table-borderless m-b-none"
|
||
}, [_vm._m(0), _vm._v(" "), _c('tbody', _vm._l((_vm.tokens), function(token) {
|
||
return _c('tr', [_c('td', {
|
||
staticStyle: {
|
||
"vertical-align": "middle"
|
||
}
|
||
}, [_vm._v("\n " + _vm._s(token.name) + "\n ")]), _vm._v(" "), _c('td', {
|
||
staticStyle: {
|
||
"vertical-align": "middle"
|
||
}
|
||
}, [_c('a', {
|
||
staticClass: "action-link text-danger",
|
||
on: {
|
||
"click": function($event) {
|
||
_vm.revoke(token)
|
||
}
|
||
}
|
||
}, [_vm._v("\n Delete\n ")])])])
|
||
}))]) : _vm._e()])])]), _vm._v(" "), _c('div', {
|
||
staticClass: "modal fade",
|
||
attrs: {
|
||
"id": "modal-create-token",
|
||
"tabindex": "-1",
|
||
"role": "dialog"
|
||
}
|
||
}, [_c('div', {
|
||
staticClass: "modal-dialog"
|
||
}, [_c('div', {
|
||
staticClass: "modal-content"
|
||
}, [_vm._m(1), _vm._v(" "), _c('div', {
|
||
staticClass: "modal-body"
|
||
}, [(_vm.form.errors.length > 0) ? _c('div', {
|
||
staticClass: "alert alert-danger"
|
||
}, [_vm._m(2), _vm._v(" "), _c('br'), _vm._v(" "), _c('ul', _vm._l((_vm.form.errors), function(error) {
|
||
return _c('li', [_vm._v("\n " + _vm._s(error) + "\n ")])
|
||
}))]) : _vm._e(), _vm._v(" "), _c('form', {
|
||
staticClass: "form-horizontal",
|
||
attrs: {
|
||
"role": "form"
|
||
},
|
||
on: {
|
||
"submit": function($event) {
|
||
$event.preventDefault();
|
||
_vm.store($event)
|
||
}
|
||
}
|
||
}, [_c('div', {
|
||
staticClass: "form-group"
|
||
}, [_c('label', {
|
||
staticClass: "col-md-4 control-label"
|
||
}, [_vm._v("Name")]), _vm._v(" "), _c('div', {
|
||
staticClass: "col-md-6"
|
||
}, [_c('input', {
|
||
directives: [{
|
||
name: "model",
|
||
rawName: "v-model",
|
||
value: (_vm.form.name),
|
||
expression: "form.name"
|
||
}],
|
||
staticClass: "form-control",
|
||
attrs: {
|
||
"id": "create-token-name",
|
||
"type": "text",
|
||
"name": "name"
|
||
},
|
||
domProps: {
|
||
"value": (_vm.form.name)
|
||
},
|
||
on: {
|
||
"input": function($event) {
|
||
if ($event.target.composing) { return; }
|
||
_vm.form.name = $event.target.value
|
||
}
|
||
}
|
||
})])]), _vm._v(" "), (_vm.scopes.length > 0) ? _c('div', {
|
||
staticClass: "form-group"
|
||
}, [_c('label', {
|
||
staticClass: "col-md-4 control-label"
|
||
}, [_vm._v("Scopes")]), _vm._v(" "), _c('div', {
|
||
staticClass: "col-md-6"
|
||
}, _vm._l((_vm.scopes), function(scope) {
|
||
return _c('div', [_c('div', {
|
||
staticClass: "checkbox"
|
||
}, [_c('label', [_c('input', {
|
||
attrs: {
|
||
"type": "checkbox"
|
||
},
|
||
domProps: {
|
||
"checked": _vm.scopeIsAssigned(scope.id)
|
||
},
|
||
on: {
|
||
"click": function($event) {
|
||
_vm.toggleScope(scope.id)
|
||
}
|
||
}
|
||
}), _vm._v("\n\n " + _vm._s(scope.id) + "\n ")])])])
|
||
}))]) : _vm._e()])]), _vm._v(" "), _c('div', {
|
||
staticClass: "modal-footer"
|
||
}, [_c('button', {
|
||
staticClass: "btn btn-default",
|
||
attrs: {
|
||
"type": "button",
|
||
"data-dismiss": "modal"
|
||
}
|
||
}, [_vm._v("Close")]), _vm._v(" "), _c('button', {
|
||
staticClass: "btn btn-primary",
|
||
attrs: {
|
||
"type": "button"
|
||
},
|
||
on: {
|
||
"click": _vm.store
|
||
}
|
||
}, [_vm._v("\n Create\n ")])])])])]), _vm._v(" "), _c('div', {
|
||
staticClass: "modal fade",
|
||
attrs: {
|
||
"id": "modal-access-token",
|
||
"tabindex": "-1",
|
||
"role": "dialog"
|
||
}
|
||
}, [_c('div', {
|
||
staticClass: "modal-dialog"
|
||
}, [_c('div', {
|
||
staticClass: "modal-content"
|
||
}, [_vm._m(3), _vm._v(" "), _c('div', {
|
||
staticClass: "modal-body"
|
||
}, [_c('p', [_vm._v("\n Here is your new personal access token. This is the only time it will be shown so don't lose it!\n You may now use this token to make API requests.\n ")]), _vm._v(" "), _c('pre', [_c('code', [_vm._v(_vm._s(_vm.accessToken))])])]), _vm._v(" "), _vm._m(4)])])])])
|
||
},staticRenderFns: [function (){var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;
|
||
return _c('thead', [_c('tr', [_c('th', [_vm._v("Name")]), _vm._v(" "), _c('th')])])
|
||
},function (){var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;
|
||
return _c('div', {
|
||
staticClass: "modal-header"
|
||
}, [_c('button', {
|
||
staticClass: "close",
|
||
attrs: {
|
||
"type": "button ",
|
||
"data-dismiss": "modal",
|
||
"aria-hidden": "true"
|
||
}
|
||
}, [_vm._v("×")]), _vm._v(" "), _c('h4', {
|
||
staticClass: "modal-title"
|
||
}, [_vm._v("\n Create Token\n ")])])
|
||
},function (){var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;
|
||
return _c('p', [_c('strong', [_vm._v("Whoops!")]), _vm._v(" Something went wrong!")])
|
||
},function (){var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;
|
||
return _c('div', {
|
||
staticClass: "modal-header"
|
||
}, [_c('button', {
|
||
staticClass: "close",
|
||
attrs: {
|
||
"type": "button ",
|
||
"data-dismiss": "modal",
|
||
"aria-hidden": "true"
|
||
}
|
||
}, [_vm._v("×")]), _vm._v(" "), _c('h4', {
|
||
staticClass: "modal-title"
|
||
}, [_vm._v("\n Personal Access Token\n ")])])
|
||
},function (){var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;
|
||
return _c('div', {
|
||
staticClass: "modal-footer"
|
||
}, [_c('button', {
|
||
staticClass: "btn btn-default",
|
||
attrs: {
|
||
"type": "button",
|
||
"data-dismiss": "modal"
|
||
}
|
||
}, [_vm._v("Close")])])
|
||
}]}
|
||
module.exports.render._withStripped = true
|
||
if (false) {
|
||
module.hot.accept()
|
||
if (module.hot.data) {
|
||
require("vue-hot-reload-api").rerender("data-v-225778c2", module.exports)
|
||
}
|
||
}
|
||
|
||
/***/ }),
|
||
/* 31 */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
var disposed = false
|
||
function injectStyle (ssrContext) {
|
||
if (disposed) return
|
||
__webpack_require__(32)
|
||
}
|
||
var Component = __webpack_require__(2)(
|
||
/* script */
|
||
__webpack_require__(34),
|
||
/* template */
|
||
null,
|
||
/* styles */
|
||
injectStyle,
|
||
/* scopeId */
|
||
"data-v-5301a236",
|
||
/* moduleIdentifier (server only) */
|
||
null
|
||
)
|
||
Component.options.__file = "/home/hydrogen/work/snipe-it/resources/assets/js/components/importer/importer.vue"
|
||
if (Component.esModule && Object.keys(Component.esModule).some(function (key) {return key !== "default" && key.substr(0, 2) !== "__"})) {console.error("named exports are not supported in *.vue files.")}
|
||
|
||
/* hot reload */
|
||
if (false) {(function () {
|
||
var hotAPI = require("vue-hot-reload-api")
|
||
hotAPI.install(require("vue"), false)
|
||
if (!hotAPI.compatible) return
|
||
module.hot.accept()
|
||
if (!module.hot.data) {
|
||
hotAPI.createRecord("data-v-5301a236", Component.options)
|
||
} else {
|
||
hotAPI.reload("data-v-5301a236", Component.options)
|
||
}
|
||
module.hot.dispose(function (data) {
|
||
disposed = true
|
||
})
|
||
})()}
|
||
|
||
module.exports = Component.exports
|
||
|
||
|
||
/***/ }),
|
||
/* 32 */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
// style-loader: Adds some css to the DOM by adding a <style> tag
|
||
|
||
// load the styles
|
||
var content = __webpack_require__(33);
|
||
if(typeof content === 'string') content = [[module.i, content, '']];
|
||
if(content.locals) module.exports = content.locals;
|
||
// add the styles to the DOM
|
||
var update = __webpack_require__(1)("a59106c2", content, false);
|
||
// Hot Module Replacement
|
||
if(false) {
|
||
// When the styles change, update the <style> tags
|
||
if(!content.locals) {
|
||
module.hot.accept("!!../../../../../node_modules/css-loader/index.js?sourceMap!../../../../../node_modules/vue-loader/lib/style-compiler/index.js?{\"vue\":true,\"id\":\"data-v-5301a236\",\"scoped\":true,\"hasInlineConfig\":true}!../../../../../node_modules/vue-loader/lib/selector.js?type=styles&index=0!./importer.vue", function() {
|
||
var newContent = require("!!../../../../../node_modules/css-loader/index.js?sourceMap!../../../../../node_modules/vue-loader/lib/style-compiler/index.js?{\"vue\":true,\"id\":\"data-v-5301a236\",\"scoped\":true,\"hasInlineConfig\":true}!../../../../../node_modules/vue-loader/lib/selector.js?type=styles&index=0!./importer.vue");
|
||
if(typeof newContent === 'string') newContent = [[module.id, newContent, '']];
|
||
update(newContent);
|
||
});
|
||
}
|
||
// When the module is disposed, remove the <style> tags
|
||
module.hot.dispose(function() { update(); });
|
||
}
|
||
|
||
/***/ }),
|
||
/* 33 */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
exports = module.exports = __webpack_require__(0)(true);
|
||
// imports
|
||
|
||
|
||
// module
|
||
exports.push([module.i, "\ntd[data-v-5301a236] {\n font-size: 13px;\n}\nth[data-v-5301a236] {\n font-size: 13px;\n}\n", "", {"version":3,"sources":["/home/hydrogen/work/snipe-it/resources/assets/js/components/importer/importer.vue?11d3fd0e"],"names":[],"mappings":";AACA;IACA,gBAAA;CACA;AAEA;IACA,gBAAA;CACA","file":"importer.vue","sourcesContent":["<style scoped>\ntd {\n font-size: 13px;\n}\n\nth {\n font-size: 13px;\n}\n</style>\n\n<script>\n require('blueimp-file-upload');\n export default {\n\n props: ['importUrl'],\n /*\n * The component's data.\n */\n data() {\n return {\n files: [],\n displayImportModal: false,\n activeFile: null,\n alert: {\n type: null,\n message: null,\n visible: false,\n },\n importErrors: null,\n progress: {\n currentClass: \"progress-bar-warning\",\n currentPercent: \"0\",\n statusText: '',\n visible: false\n }\n };\n },\n\n mounted() {\n window.eventHub.$on('importErrors', this.updateImportErrors);\n this.fetchFiles();\n let vm = this;\n $('#fileupload').fileupload({\n dataType: 'json',\n done(e, data) {\n vm.progress.currentClass=\"progress-bar-success\";\n vm.progress.statusText = \"Success!\";\n vm.files = data.result.files.concat(vm.files);\n console.log(data.result.header_row);\n },\n add(e, data) {\n data.headers = {\n \"X-Requested-With\": 'XMLHttpRequest',\n \"X-CSRF-TOKEN\": Laravel.csrfToken\n };\n data.process().done( () => {data.submit();});\n vm.progress.visible=true;\n },\n progress(e, data) {\n var progress = parseInt((data.loaded / data.total * 100, 10));\n vm.progress.currentPercent = progress;\n vm.progress.statusText = progress+'% Complete';\n },\n fail(e, data) {\n vm.progress.currentClass = \"progress-bar-danger\";\n // Display any errors returned from the $.ajax()\n vm.progress.statusText = data.jqXHR.responseJSON.messages;\n }\n })\n },\n\n methods: {\n fetchFiles() {\n this.$http.get(this.importUrl)\n .then( ({data}) => this.files = data, // Success\n //Fail\n (response) => {\n this.alert.type=\"danger\";\n this.alert.visible=true;\n this.alert.message=\"Something went wrong fetching files...\";\n });\n },\n deleteFile(file, key) {\n this.$http.delete(this.importUrl+\"/\"+file.id)\n .then((response) => this.files.splice(key, 1), // Success, remove file from array.\n (response) => {// Fail\n this.alert.type=\"danger\";\n this.alert.visible=true;\n this.alert.message=response.body.messages;\n }\n );\n },\n toggleEvent(fileId) {\n window.eventHub.$emit('showDetails', fileId)\n },\n updateAlert(alert) {\n this.alert = alert;\n },\n updateImportErrors(errors) {\n this.importErrors = errors;\n }\n },\n\n computed: {\n progressWidth() {\n return \"width: \"+this.progress.currentPercent*10+'%';\n }\n },\n\n components: {\n alert: require('../alert.vue'),\n errors: require('./importer-errors.vue'),\n importFile: require('./importer-file.vue'),\n }\n }\n\n</script>\n"],"sourceRoot":""}]);
|
||
|
||
// exports
|
||
|
||
|
||
/***/ }),
|
||
/* 34 */
|
||
/***/ (function(module, __webpack_exports__, __webpack_require__) {
|
||
|
||
"use strict";
|
||
Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
|
||
__webpack_require__(35);
|
||
/* harmony default export */ __webpack_exports__["default"] = ({
|
||
|
||
props: ['importUrl'],
|
||
/*
|
||
* The component's data.
|
||
*/
|
||
data: function data() {
|
||
return {
|
||
files: [],
|
||
displayImportModal: false,
|
||
activeFile: null,
|
||
alert: {
|
||
type: null,
|
||
message: null,
|
||
visible: false
|
||
},
|
||
importErrors: null,
|
||
progress: {
|
||
currentClass: "progress-bar-warning",
|
||
currentPercent: "0",
|
||
statusText: '',
|
||
visible: false
|
||
}
|
||
};
|
||
},
|
||
mounted: function mounted() {
|
||
window.eventHub.$on('importErrors', this.updateImportErrors);
|
||
this.fetchFiles();
|
||
var vm = this;
|
||
$('#fileupload').fileupload({
|
||
dataType: 'json',
|
||
done: function done(e, data) {
|
||
vm.progress.currentClass = "progress-bar-success";
|
||
vm.progress.statusText = "Success!";
|
||
vm.files = data.result.files.concat(vm.files);
|
||
console.log(data.result.header_row);
|
||
},
|
||
add: function add(e, data) {
|
||
data.headers = {
|
||
"X-Requested-With": 'XMLHttpRequest',
|
||
"X-CSRF-TOKEN": Laravel.csrfToken
|
||
};
|
||
data.process().done(function () {
|
||
data.submit();
|
||
});
|
||
vm.progress.visible = true;
|
||
},
|
||
progress: function progress(e, data) {
|
||
var progress = parseInt((data.loaded / data.total * 100, 10));
|
||
vm.progress.currentPercent = progress;
|
||
vm.progress.statusText = progress + '% Complete';
|
||
},
|
||
fail: function fail(e, data) {
|
||
vm.progress.currentClass = "progress-bar-danger";
|
||
// Display any errors returned from the $.ajax()
|
||
vm.progress.statusText = data.jqXHR.responseJSON.messages;
|
||
}
|
||
});
|
||
},
|
||
|
||
|
||
methods: {
|
||
fetchFiles: function fetchFiles() {
|
||
var _this = this;
|
||
|
||
this.$http.get(this.importUrl).then(function (_ref) {
|
||
var data = _ref.data;
|
||
return _this.files = data;
|
||
}, // Success
|
||
//Fail
|
||
function (response) {
|
||
_this.alert.type = "danger";
|
||
_this.alert.visible = true;
|
||
_this.alert.message = "Something went wrong fetching files...";
|
||
});
|
||
},
|
||
deleteFile: function deleteFile(file, key) {
|
||
var _this2 = this;
|
||
|
||
this.$http.delete(this.importUrl + "/" + file.id).then(function (response) {
|
||
return _this2.files.splice(key, 1);
|
||
}, // Success, remove file from array.
|
||
function (response) {
|
||
// Fail
|
||
_this2.alert.type = "danger";
|
||
_this2.alert.visible = true;
|
||
_this2.alert.message = response.body.messages;
|
||
});
|
||
},
|
||
toggleEvent: function toggleEvent(fileId) {
|
||
window.eventHub.$emit('showDetails', fileId);
|
||
},
|
||
updateAlert: function updateAlert(alert) {
|
||
this.alert = alert;
|
||
},
|
||
updateImportErrors: function updateImportErrors(errors) {
|
||
this.importErrors = errors;
|
||
}
|
||
},
|
||
|
||
computed: {
|
||
progressWidth: function progressWidth() {
|
||
return "width: " + this.progress.currentPercent * 10 + '%';
|
||
}
|
||
},
|
||
|
||
components: {
|
||
alert: __webpack_require__(38),
|
||
errors: __webpack_require__(43),
|
||
importFile: __webpack_require__(48)
|
||
}
|
||
});
|
||
|
||
/***/ }),
|
||
/* 35 */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/*
|
||
* jQuery File Upload Plugin
|
||
* https://github.com/blueimp/jQuery-File-Upload
|
||
*
|
||
* Copyright 2010, Sebastian Tschan
|
||
* https://blueimp.net
|
||
*
|
||
* Licensed under the MIT license:
|
||
* https://opensource.org/licenses/MIT
|
||
*/
|
||
|
||
/* jshint nomen:false */
|
||
/* global define, require, window, document, location, Blob, FormData */
|
||
|
||
;(function (factory) {
|
||
'use strict';
|
||
if (true) {
|
||
// Register as an anonymous AMD module:
|
||
!(__WEBPACK_AMD_DEFINE_ARRAY__ = [
|
||
__webpack_require__(3),
|
||
__webpack_require__(36)
|
||
], __WEBPACK_AMD_DEFINE_FACTORY__ = (factory),
|
||
__WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ?
|
||
(__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__),
|
||
__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
|
||
} else if (typeof exports === 'object') {
|
||
// Node/CommonJS:
|
||
factory(
|
||
require('jquery'),
|
||
require('./vendor/jquery.ui.widget')
|
||
);
|
||
} else {
|
||
// Browser globals:
|
||
factory(window.jQuery);
|
||
}
|
||
}(function ($) {
|
||
'use strict';
|
||
|
||
// Detect file input support, based on
|
||
// http://viljamis.com/blog/2012/file-upload-support-on-mobile/
|
||
$.support.fileInput = !(new RegExp(
|
||
// Handle devices which give false positives for the feature detection:
|
||
'(Android (1\\.[0156]|2\\.[01]))' +
|
||
'|(Windows Phone (OS 7|8\\.0))|(XBLWP)|(ZuneWP)|(WPDesktop)' +
|
||
'|(w(eb)?OSBrowser)|(webOS)' +
|
||
'|(Kindle/(1\\.0|2\\.[05]|3\\.0))'
|
||
).test(window.navigator.userAgent) ||
|
||
// Feature detection for all other devices:
|
||
$('<input type="file">').prop('disabled'));
|
||
|
||
// The FileReader API is not actually used, but works as feature detection,
|
||
// as some Safari versions (5?) support XHR file uploads via the FormData API,
|
||
// but not non-multipart XHR file uploads.
|
||
// window.XMLHttpRequestUpload is not available on IE10, so we check for
|
||
// window.ProgressEvent instead to detect XHR2 file upload capability:
|
||
$.support.xhrFileUpload = !!(window.ProgressEvent && window.FileReader);
|
||
$.support.xhrFormDataFileUpload = !!window.FormData;
|
||
|
||
// Detect support for Blob slicing (required for chunked uploads):
|
||
$.support.blobSlice = window.Blob && (Blob.prototype.slice ||
|
||
Blob.prototype.webkitSlice || Blob.prototype.mozSlice);
|
||
|
||
// Helper function to create drag handlers for dragover/dragenter/dragleave:
|
||
function getDragHandler(type) {
|
||
var isDragOver = type === 'dragover';
|
||
return function (e) {
|
||
e.dataTransfer = e.originalEvent && e.originalEvent.dataTransfer;
|
||
var dataTransfer = e.dataTransfer;
|
||
if (dataTransfer && $.inArray('Files', dataTransfer.types) !== -1 &&
|
||
this._trigger(
|
||
type,
|
||
$.Event(type, {delegatedEvent: e})
|
||
) !== false) {
|
||
e.preventDefault();
|
||
if (isDragOver) {
|
||
dataTransfer.dropEffect = 'copy';
|
||
}
|
||
}
|
||
};
|
||
}
|
||
|
||
// The fileupload widget listens for change events on file input fields defined
|
||
// via fileInput setting and paste or drop events of the given dropZone.
|
||
// In addition to the default jQuery Widget methods, the fileupload widget
|
||
// exposes the "add" and "send" methods, to add or directly send files using
|
||
// the fileupload API.
|
||
// By default, files added via file input selection, paste, drag & drop or
|
||
// "add" method are uploaded immediately, but it is possible to override
|
||
// the "add" callback option to queue file uploads.
|
||
$.widget('blueimp.fileupload', {
|
||
|
||
options: {
|
||
// The drop target element(s), by the default the complete document.
|
||
// Set to null to disable drag & drop support:
|
||
dropZone: $(document),
|
||
// The paste target element(s), by the default undefined.
|
||
// Set to a DOM node or jQuery object to enable file pasting:
|
||
pasteZone: undefined,
|
||
// The file input field(s), that are listened to for change events.
|
||
// If undefined, it is set to the file input fields inside
|
||
// of the widget element on plugin initialization.
|
||
// Set to null to disable the change listener.
|
||
fileInput: undefined,
|
||
// By default, the file input field is replaced with a clone after
|
||
// each input field change event. This is required for iframe transport
|
||
// queues and allows change events to be fired for the same file
|
||
// selection, but can be disabled by setting the following option to false:
|
||
replaceFileInput: true,
|
||
// The parameter name for the file form data (the request argument name).
|
||
// If undefined or empty, the name property of the file input field is
|
||
// used, or "files[]" if the file input name property is also empty,
|
||
// can be a string or an array of strings:
|
||
paramName: undefined,
|
||
// By default, each file of a selection is uploaded using an individual
|
||
// request for XHR type uploads. Set to false to upload file
|
||
// selections in one request each:
|
||
singleFileUploads: true,
|
||
// To limit the number of files uploaded with one XHR request,
|
||
// set the following option to an integer greater than 0:
|
||
limitMultiFileUploads: undefined,
|
||
// The following option limits the number of files uploaded with one
|
||
// XHR request to keep the request size under or equal to the defined
|
||
// limit in bytes:
|
||
limitMultiFileUploadSize: undefined,
|
||
// Multipart file uploads add a number of bytes to each uploaded file,
|
||
// therefore the following option adds an overhead for each file used
|
||
// in the limitMultiFileUploadSize configuration:
|
||
limitMultiFileUploadSizeOverhead: 512,
|
||
// Set the following option to true to issue all file upload requests
|
||
// in a sequential order:
|
||
sequentialUploads: false,
|
||
// To limit the number of concurrent uploads,
|
||
// set the following option to an integer greater than 0:
|
||
limitConcurrentUploads: undefined,
|
||
// Set the following option to true to force iframe transport uploads:
|
||
forceIframeTransport: false,
|
||
// Set the following option to the location of a redirect url on the
|
||
// origin server, for cross-domain iframe transport uploads:
|
||
redirect: undefined,
|
||
// The parameter name for the redirect url, sent as part of the form
|
||
// data and set to 'redirect' if this option is empty:
|
||
redirectParamName: undefined,
|
||
// Set the following option to the location of a postMessage window,
|
||
// to enable postMessage transport uploads:
|
||
postMessage: undefined,
|
||
// By default, XHR file uploads are sent as multipart/form-data.
|
||
// The iframe transport is always using multipart/form-data.
|
||
// Set to false to enable non-multipart XHR uploads:
|
||
multipart: true,
|
||
// To upload large files in smaller chunks, set the following option
|
||
// to a preferred maximum chunk size. If set to 0, null or undefined,
|
||
// or the browser does not support the required Blob API, files will
|
||
// be uploaded as a whole.
|
||
maxChunkSize: undefined,
|
||
// When a non-multipart upload or a chunked multipart upload has been
|
||
// aborted, this option can be used to resume the upload by setting
|
||
// it to the size of the already uploaded bytes. This option is most
|
||
// useful when modifying the options object inside of the "add" or
|
||
// "send" callbacks, as the options are cloned for each file upload.
|
||
uploadedBytes: undefined,
|
||
// By default, failed (abort or error) file uploads are removed from the
|
||
// global progress calculation. Set the following option to false to
|
||
// prevent recalculating the global progress data:
|
||
recalculateProgress: true,
|
||
// Interval in milliseconds to calculate and trigger progress events:
|
||
progressInterval: 100,
|
||
// Interval in milliseconds to calculate progress bitrate:
|
||
bitrateInterval: 500,
|
||
// By default, uploads are started automatically when adding files:
|
||
autoUpload: true,
|
||
|
||
// Error and info messages:
|
||
messages: {
|
||
uploadedBytes: 'Uploaded bytes exceed file size'
|
||
},
|
||
|
||
// Translation function, gets the message key to be translated
|
||
// and an object with context specific data as arguments:
|
||
i18n: function (message, context) {
|
||
message = this.messages[message] || message.toString();
|
||
if (context) {
|
||
$.each(context, function (key, value) {
|
||
message = message.replace('{' + key + '}', value);
|
||
});
|
||
}
|
||
return message;
|
||
},
|
||
|
||
// Additional form data to be sent along with the file uploads can be set
|
||
// using this option, which accepts an array of objects with name and
|
||
// value properties, a function returning such an array, a FormData
|
||
// object (for XHR file uploads), or a simple object.
|
||
// The form of the first fileInput is given as parameter to the function:
|
||
formData: function (form) {
|
||
return form.serializeArray();
|
||
},
|
||
|
||
// The add callback is invoked as soon as files are added to the fileupload
|
||
// widget (via file input selection, drag & drop, paste or add API call).
|
||
// If the singleFileUploads option is enabled, this callback will be
|
||
// called once for each file in the selection for XHR file uploads, else
|
||
// once for each file selection.
|
||
//
|
||
// The upload starts when the submit method is invoked on the data parameter.
|
||
// The data object contains a files property holding the added files
|
||
// and allows you to override plugin options as well as define ajax settings.
|
||
//
|
||
// Listeners for this callback can also be bound the following way:
|
||
// .bind('fileuploadadd', func);
|
||
//
|
||
// data.submit() returns a Promise object and allows to attach additional
|
||
// handlers using jQuery's Deferred callbacks:
|
||
// data.submit().done(func).fail(func).always(func);
|
||
add: function (e, data) {
|
||
if (e.isDefaultPrevented()) {
|
||
return false;
|
||
}
|
||
if (data.autoUpload || (data.autoUpload !== false &&
|
||
$(this).fileupload('option', 'autoUpload'))) {
|
||
data.process().done(function () {
|
||
data.submit();
|
||
});
|
||
}
|
||
},
|
||
|
||
// Other callbacks:
|
||
|
||
// Callback for the submit event of each file upload:
|
||
// submit: function (e, data) {}, // .bind('fileuploadsubmit', func);
|
||
|
||
// Callback for the start of each file upload request:
|
||
// send: function (e, data) {}, // .bind('fileuploadsend', func);
|
||
|
||
// Callback for successful uploads:
|
||
// done: function (e, data) {}, // .bind('fileuploaddone', func);
|
||
|
||
// Callback for failed (abort or error) uploads:
|
||
// fail: function (e, data) {}, // .bind('fileuploadfail', func);
|
||
|
||
// Callback for completed (success, abort or error) requests:
|
||
// always: function (e, data) {}, // .bind('fileuploadalways', func);
|
||
|
||
// Callback for upload progress events:
|
||
// progress: function (e, data) {}, // .bind('fileuploadprogress', func);
|
||
|
||
// Callback for global upload progress events:
|
||
// progressall: function (e, data) {}, // .bind('fileuploadprogressall', func);
|
||
|
||
// Callback for uploads start, equivalent to the global ajaxStart event:
|
||
// start: function (e) {}, // .bind('fileuploadstart', func);
|
||
|
||
// Callback for uploads stop, equivalent to the global ajaxStop event:
|
||
// stop: function (e) {}, // .bind('fileuploadstop', func);
|
||
|
||
// Callback for change events of the fileInput(s):
|
||
// change: function (e, data) {}, // .bind('fileuploadchange', func);
|
||
|
||
// Callback for paste events to the pasteZone(s):
|
||
// paste: function (e, data) {}, // .bind('fileuploadpaste', func);
|
||
|
||
// Callback for drop events of the dropZone(s):
|
||
// drop: function (e, data) {}, // .bind('fileuploaddrop', func);
|
||
|
||
// Callback for dragover events of the dropZone(s):
|
||
// dragover: function (e) {}, // .bind('fileuploaddragover', func);
|
||
|
||
// Callback for the start of each chunk upload request:
|
||
// chunksend: function (e, data) {}, // .bind('fileuploadchunksend', func);
|
||
|
||
// Callback for successful chunk uploads:
|
||
// chunkdone: function (e, data) {}, // .bind('fileuploadchunkdone', func);
|
||
|
||
// Callback for failed (abort or error) chunk uploads:
|
||
// chunkfail: function (e, data) {}, // .bind('fileuploadchunkfail', func);
|
||
|
||
// Callback for completed (success, abort or error) chunk upload requests:
|
||
// chunkalways: function (e, data) {}, // .bind('fileuploadchunkalways', func);
|
||
|
||
// The plugin options are used as settings object for the ajax calls.
|
||
// The following are jQuery ajax settings required for the file uploads:
|
||
processData: false,
|
||
contentType: false,
|
||
cache: false,
|
||
timeout: 0
|
||
},
|
||
|
||
// A list of options that require reinitializing event listeners and/or
|
||
// special initialization code:
|
||
_specialOptions: [
|
||
'fileInput',
|
||
'dropZone',
|
||
'pasteZone',
|
||
'multipart',
|
||
'forceIframeTransport'
|
||
],
|
||
|
||
_blobSlice: $.support.blobSlice && function () {
|
||
var slice = this.slice || this.webkitSlice || this.mozSlice;
|
||
return slice.apply(this, arguments);
|
||
},
|
||
|
||
_BitrateTimer: function () {
|
||
this.timestamp = ((Date.now) ? Date.now() : (new Date()).getTime());
|
||
this.loaded = 0;
|
||
this.bitrate = 0;
|
||
this.getBitrate = function (now, loaded, interval) {
|
||
var timeDiff = now - this.timestamp;
|
||
if (!this.bitrate || !interval || timeDiff > interval) {
|
||
this.bitrate = (loaded - this.loaded) * (1000 / timeDiff) * 8;
|
||
this.loaded = loaded;
|
||
this.timestamp = now;
|
||
}
|
||
return this.bitrate;
|
||
};
|
||
},
|
||
|
||
_isXHRUpload: function (options) {
|
||
return !options.forceIframeTransport &&
|
||
((!options.multipart && $.support.xhrFileUpload) ||
|
||
$.support.xhrFormDataFileUpload);
|
||
},
|
||
|
||
_getFormData: function (options) {
|
||
var formData;
|
||
if ($.type(options.formData) === 'function') {
|
||
return options.formData(options.form);
|
||
}
|
||
if ($.isArray(options.formData)) {
|
||
return options.formData;
|
||
}
|
||
if ($.type(options.formData) === 'object') {
|
||
formData = [];
|
||
$.each(options.formData, function (name, value) {
|
||
formData.push({name: name, value: value});
|
||
});
|
||
return formData;
|
||
}
|
||
return [];
|
||
},
|
||
|
||
_getTotal: function (files) {
|
||
var total = 0;
|
||
$.each(files, function (index, file) {
|
||
total += file.size || 1;
|
||
});
|
||
return total;
|
||
},
|
||
|
||
_initProgressObject: function (obj) {
|
||
var progress = {
|
||
loaded: 0,
|
||
total: 0,
|
||
bitrate: 0
|
||
};
|
||
if (obj._progress) {
|
||
$.extend(obj._progress, progress);
|
||
} else {
|
||
obj._progress = progress;
|
||
}
|
||
},
|
||
|
||
_initResponseObject: function (obj) {
|
||
var prop;
|
||
if (obj._response) {
|
||
for (prop in obj._response) {
|
||
if (obj._response.hasOwnProperty(prop)) {
|
||
delete obj._response[prop];
|
||
}
|
||
}
|
||
} else {
|
||
obj._response = {};
|
||
}
|
||
},
|
||
|
||
_onProgress: function (e, data) {
|
||
if (e.lengthComputable) {
|
||
var now = ((Date.now) ? Date.now() : (new Date()).getTime()),
|
||
loaded;
|
||
if (data._time && data.progressInterval &&
|
||
(now - data._time < data.progressInterval) &&
|
||
e.loaded !== e.total) {
|
||
return;
|
||
}
|
||
data._time = now;
|
||
loaded = Math.floor(
|
||
e.loaded / e.total * (data.chunkSize || data._progress.total)
|
||
) + (data.uploadedBytes || 0);
|
||
// Add the difference from the previously loaded state
|
||
// to the global loaded counter:
|
||
this._progress.loaded += (loaded - data._progress.loaded);
|
||
this._progress.bitrate = this._bitrateTimer.getBitrate(
|
||
now,
|
||
this._progress.loaded,
|
||
data.bitrateInterval
|
||
);
|
||
data._progress.loaded = data.loaded = loaded;
|
||
data._progress.bitrate = data.bitrate = data._bitrateTimer.getBitrate(
|
||
now,
|
||
loaded,
|
||
data.bitrateInterval
|
||
);
|
||
// Trigger a custom progress event with a total data property set
|
||
// to the file size(s) of the current upload and a loaded data
|
||
// property calculated accordingly:
|
||
this._trigger(
|
||
'progress',
|
||
$.Event('progress', {delegatedEvent: e}),
|
||
data
|
||
);
|
||
// Trigger a global progress event for all current file uploads,
|
||
// including ajax calls queued for sequential file uploads:
|
||
this._trigger(
|
||
'progressall',
|
||
$.Event('progressall', {delegatedEvent: e}),
|
||
this._progress
|
||
);
|
||
}
|
||
},
|
||
|
||
_initProgressListener: function (options) {
|
||
var that = this,
|
||
xhr = options.xhr ? options.xhr() : $.ajaxSettings.xhr();
|
||
// Accesss to the native XHR object is required to add event listeners
|
||
// for the upload progress event:
|
||
if (xhr.upload) {
|
||
$(xhr.upload).bind('progress', function (e) {
|
||
var oe = e.originalEvent;
|
||
// Make sure the progress event properties get copied over:
|
||
e.lengthComputable = oe.lengthComputable;
|
||
e.loaded = oe.loaded;
|
||
e.total = oe.total;
|
||
that._onProgress(e, options);
|
||
});
|
||
options.xhr = function () {
|
||
return xhr;
|
||
};
|
||
}
|
||
},
|
||
|
||
_isInstanceOf: function (type, obj) {
|
||
// Cross-frame instanceof check
|
||
return Object.prototype.toString.call(obj) === '[object ' + type + ']';
|
||
},
|
||
|
||
_initXHRData: function (options) {
|
||
var that = this,
|
||
formData,
|
||
file = options.files[0],
|
||
// Ignore non-multipart setting if not supported:
|
||
multipart = options.multipart || !$.support.xhrFileUpload,
|
||
paramName = $.type(options.paramName) === 'array' ?
|
||
options.paramName[0] : options.paramName;
|
||
options.headers = $.extend({}, options.headers);
|
||
if (options.contentRange) {
|
||
options.headers['Content-Range'] = options.contentRange;
|
||
}
|
||
if (!multipart || options.blob || !this._isInstanceOf('File', file)) {
|
||
options.headers['Content-Disposition'] = 'attachment; filename="' +
|
||
encodeURI(file.name) + '"';
|
||
}
|
||
if (!multipart) {
|
||
options.contentType = file.type || 'application/octet-stream';
|
||
options.data = options.blob || file;
|
||
} else if ($.support.xhrFormDataFileUpload) {
|
||
if (options.postMessage) {
|
||
// window.postMessage does not allow sending FormData
|
||
// objects, so we just add the File/Blob objects to
|
||
// the formData array and let the postMessage window
|
||
// create the FormData object out of this array:
|
||
formData = this._getFormData(options);
|
||
if (options.blob) {
|
||
formData.push({
|
||
name: paramName,
|
||
value: options.blob
|
||
});
|
||
} else {
|
||
$.each(options.files, function (index, file) {
|
||
formData.push({
|
||
name: ($.type(options.paramName) === 'array' &&
|
||
options.paramName[index]) || paramName,
|
||
value: file
|
||
});
|
||
});
|
||
}
|
||
} else {
|
||
if (that._isInstanceOf('FormData', options.formData)) {
|
||
formData = options.formData;
|
||
} else {
|
||
formData = new FormData();
|
||
$.each(this._getFormData(options), function (index, field) {
|
||
formData.append(field.name, field.value);
|
||
});
|
||
}
|
||
if (options.blob) {
|
||
formData.append(paramName, options.blob, file.name);
|
||
} else {
|
||
$.each(options.files, function (index, file) {
|
||
// This check allows the tests to run with
|
||
// dummy objects:
|
||
if (that._isInstanceOf('File', file) ||
|
||
that._isInstanceOf('Blob', file)) {
|
||
formData.append(
|
||
($.type(options.paramName) === 'array' &&
|
||
options.paramName[index]) || paramName,
|
||
file,
|
||
file.uploadName || file.name
|
||
);
|
||
}
|
||
});
|
||
}
|
||
}
|
||
options.data = formData;
|
||
}
|
||
// Blob reference is not needed anymore, free memory:
|
||
options.blob = null;
|
||
},
|
||
|
||
_initIframeSettings: function (options) {
|
||
var targetHost = $('<a></a>').prop('href', options.url).prop('host');
|
||
// Setting the dataType to iframe enables the iframe transport:
|
||
options.dataType = 'iframe ' + (options.dataType || '');
|
||
// The iframe transport accepts a serialized array as form data:
|
||
options.formData = this._getFormData(options);
|
||
// Add redirect url to form data on cross-domain uploads:
|
||
if (options.redirect && targetHost && targetHost !== location.host) {
|
||
options.formData.push({
|
||
name: options.redirectParamName || 'redirect',
|
||
value: options.redirect
|
||
});
|
||
}
|
||
},
|
||
|
||
_initDataSettings: function (options) {
|
||
if (this._isXHRUpload(options)) {
|
||
if (!this._chunkedUpload(options, true)) {
|
||
if (!options.data) {
|
||
this._initXHRData(options);
|
||
}
|
||
this._initProgressListener(options);
|
||
}
|
||
if (options.postMessage) {
|
||
// Setting the dataType to postmessage enables the
|
||
// postMessage transport:
|
||
options.dataType = 'postmessage ' + (options.dataType || '');
|
||
}
|
||
} else {
|
||
this._initIframeSettings(options);
|
||
}
|
||
},
|
||
|
||
_getParamName: function (options) {
|
||
var fileInput = $(options.fileInput),
|
||
paramName = options.paramName;
|
||
if (!paramName) {
|
||
paramName = [];
|
||
fileInput.each(function () {
|
||
var input = $(this),
|
||
name = input.prop('name') || 'files[]',
|
||
i = (input.prop('files') || [1]).length;
|
||
while (i) {
|
||
paramName.push(name);
|
||
i -= 1;
|
||
}
|
||
});
|
||
if (!paramName.length) {
|
||
paramName = [fileInput.prop('name') || 'files[]'];
|
||
}
|
||
} else if (!$.isArray(paramName)) {
|
||
paramName = [paramName];
|
||
}
|
||
return paramName;
|
||
},
|
||
|
||
_initFormSettings: function (options) {
|
||
// Retrieve missing options from the input field and the
|
||
// associated form, if available:
|
||
if (!options.form || !options.form.length) {
|
||
options.form = $(options.fileInput.prop('form'));
|
||
// If the given file input doesn't have an associated form,
|
||
// use the default widget file input's form:
|
||
if (!options.form.length) {
|
||
options.form = $(this.options.fileInput.prop('form'));
|
||
}
|
||
}
|
||
options.paramName = this._getParamName(options);
|
||
if (!options.url) {
|
||
options.url = options.form.prop('action') || location.href;
|
||
}
|
||
// The HTTP request method must be "POST" or "PUT":
|
||
options.type = (options.type ||
|
||
($.type(options.form.prop('method')) === 'string' &&
|
||
options.form.prop('method')) || ''
|
||
).toUpperCase();
|
||
if (options.type !== 'POST' && options.type !== 'PUT' &&
|
||
options.type !== 'PATCH') {
|
||
options.type = 'POST';
|
||
}
|
||
if (!options.formAcceptCharset) {
|
||
options.formAcceptCharset = options.form.attr('accept-charset');
|
||
}
|
||
},
|
||
|
||
_getAJAXSettings: function (data) {
|
||
var options = $.extend({}, this.options, data);
|
||
this._initFormSettings(options);
|
||
this._initDataSettings(options);
|
||
return options;
|
||
},
|
||
|
||
// jQuery 1.6 doesn't provide .state(),
|
||
// while jQuery 1.8+ removed .isRejected() and .isResolved():
|
||
_getDeferredState: function (deferred) {
|
||
if (deferred.state) {
|
||
return deferred.state();
|
||
}
|
||
if (deferred.isResolved()) {
|
||
return 'resolved';
|
||
}
|
||
if (deferred.isRejected()) {
|
||
return 'rejected';
|
||
}
|
||
return 'pending';
|
||
},
|
||
|
||
// Maps jqXHR callbacks to the equivalent
|
||
// methods of the given Promise object:
|
||
_enhancePromise: function (promise) {
|
||
promise.success = promise.done;
|
||
promise.error = promise.fail;
|
||
promise.complete = promise.always;
|
||
return promise;
|
||
},
|
||
|
||
// Creates and returns a Promise object enhanced with
|
||
// the jqXHR methods abort, success, error and complete:
|
||
_getXHRPromise: function (resolveOrReject, context, args) {
|
||
var dfd = $.Deferred(),
|
||
promise = dfd.promise();
|
||
context = context || this.options.context || promise;
|
||
if (resolveOrReject === true) {
|
||
dfd.resolveWith(context, args);
|
||
} else if (resolveOrReject === false) {
|
||
dfd.rejectWith(context, args);
|
||
}
|
||
promise.abort = dfd.promise;
|
||
return this._enhancePromise(promise);
|
||
},
|
||
|
||
// Adds convenience methods to the data callback argument:
|
||
_addConvenienceMethods: function (e, data) {
|
||
var that = this,
|
||
getPromise = function (args) {
|
||
return $.Deferred().resolveWith(that, args).promise();
|
||
};
|
||
data.process = function (resolveFunc, rejectFunc) {
|
||
if (resolveFunc || rejectFunc) {
|
||
data._processQueue = this._processQueue =
|
||
(this._processQueue || getPromise([this])).then(
|
||
function () {
|
||
if (data.errorThrown) {
|
||
return $.Deferred()
|
||
.rejectWith(that, [data]).promise();
|
||
}
|
||
return getPromise(arguments);
|
||
}
|
||
).then(resolveFunc, rejectFunc);
|
||
}
|
||
return this._processQueue || getPromise([this]);
|
||
};
|
||
data.submit = function () {
|
||
if (this.state() !== 'pending') {
|
||
data.jqXHR = this.jqXHR =
|
||
(that._trigger(
|
||
'submit',
|
||
$.Event('submit', {delegatedEvent: e}),
|
||
this
|
||
) !== false) && that._onSend(e, this);
|
||
}
|
||
return this.jqXHR || that._getXHRPromise();
|
||
};
|
||
data.abort = function () {
|
||
if (this.jqXHR) {
|
||
return this.jqXHR.abort();
|
||
}
|
||
this.errorThrown = 'abort';
|
||
that._trigger('fail', null, this);
|
||
return that._getXHRPromise(false);
|
||
};
|
||
data.state = function () {
|
||
if (this.jqXHR) {
|
||
return that._getDeferredState(this.jqXHR);
|
||
}
|
||
if (this._processQueue) {
|
||
return that._getDeferredState(this._processQueue);
|
||
}
|
||
};
|
||
data.processing = function () {
|
||
return !this.jqXHR && this._processQueue && that
|
||
._getDeferredState(this._processQueue) === 'pending';
|
||
};
|
||
data.progress = function () {
|
||
return this._progress;
|
||
};
|
||
data.response = function () {
|
||
return this._response;
|
||
};
|
||
},
|
||
|
||
// Parses the Range header from the server response
|
||
// and returns the uploaded bytes:
|
||
_getUploadedBytes: function (jqXHR) {
|
||
var range = jqXHR.getResponseHeader('Range'),
|
||
parts = range && range.split('-'),
|
||
upperBytesPos = parts && parts.length > 1 &&
|
||
parseInt(parts[1], 10);
|
||
return upperBytesPos && upperBytesPos + 1;
|
||
},
|
||
|
||
// Uploads a file in multiple, sequential requests
|
||
// by splitting the file up in multiple blob chunks.
|
||
// If the second parameter is true, only tests if the file
|
||
// should be uploaded in chunks, but does not invoke any
|
||
// upload requests:
|
||
_chunkedUpload: function (options, testOnly) {
|
||
options.uploadedBytes = options.uploadedBytes || 0;
|
||
var that = this,
|
||
file = options.files[0],
|
||
fs = file.size,
|
||
ub = options.uploadedBytes,
|
||
mcs = options.maxChunkSize || fs,
|
||
slice = this._blobSlice,
|
||
dfd = $.Deferred(),
|
||
promise = dfd.promise(),
|
||
jqXHR,
|
||
upload;
|
||
if (!(this._isXHRUpload(options) && slice && (ub || ($.type(mcs) === 'function' ? mcs(options) : mcs) < fs)) ||
|
||
options.data) {
|
||
return false;
|
||
}
|
||
if (testOnly) {
|
||
return true;
|
||
}
|
||
if (ub >= fs) {
|
||
file.error = options.i18n('uploadedBytes');
|
||
return this._getXHRPromise(
|
||
false,
|
||
options.context,
|
||
[null, 'error', file.error]
|
||
);
|
||
}
|
||
// The chunk upload method:
|
||
upload = function () {
|
||
// Clone the options object for each chunk upload:
|
||
var o = $.extend({}, options),
|
||
currentLoaded = o._progress.loaded;
|
||
o.blob = slice.call(
|
||
file,
|
||
ub,
|
||
ub + ($.type(mcs) === 'function' ? mcs(o) : mcs),
|
||
file.type
|
||
);
|
||
// Store the current chunk size, as the blob itself
|
||
// will be dereferenced after data processing:
|
||
o.chunkSize = o.blob.size;
|
||
// Expose the chunk bytes position range:
|
||
o.contentRange = 'bytes ' + ub + '-' +
|
||
(ub + o.chunkSize - 1) + '/' + fs;
|
||
// Process the upload data (the blob and potential form data):
|
||
that._initXHRData(o);
|
||
// Add progress listeners for this chunk upload:
|
||
that._initProgressListener(o);
|
||
jqXHR = ((that._trigger('chunksend', null, o) !== false && $.ajax(o)) ||
|
||
that._getXHRPromise(false, o.context))
|
||
.done(function (result, textStatus, jqXHR) {
|
||
ub = that._getUploadedBytes(jqXHR) ||
|
||
(ub + o.chunkSize);
|
||
// Create a progress event if no final progress event
|
||
// with loaded equaling total has been triggered
|
||
// for this chunk:
|
||
if (currentLoaded + o.chunkSize - o._progress.loaded) {
|
||
that._onProgress($.Event('progress', {
|
||
lengthComputable: true,
|
||
loaded: ub - o.uploadedBytes,
|
||
total: ub - o.uploadedBytes
|
||
}), o);
|
||
}
|
||
options.uploadedBytes = o.uploadedBytes = ub;
|
||
o.result = result;
|
||
o.textStatus = textStatus;
|
||
o.jqXHR = jqXHR;
|
||
that._trigger('chunkdone', null, o);
|
||
that._trigger('chunkalways', null, o);
|
||
if (ub < fs) {
|
||
// File upload not yet complete,
|
||
// continue with the next chunk:
|
||
upload();
|
||
} else {
|
||
dfd.resolveWith(
|
||
o.context,
|
||
[result, textStatus, jqXHR]
|
||
);
|
||
}
|
||
})
|
||
.fail(function (jqXHR, textStatus, errorThrown) {
|
||
o.jqXHR = jqXHR;
|
||
o.textStatus = textStatus;
|
||
o.errorThrown = errorThrown;
|
||
that._trigger('chunkfail', null, o);
|
||
that._trigger('chunkalways', null, o);
|
||
dfd.rejectWith(
|
||
o.context,
|
||
[jqXHR, textStatus, errorThrown]
|
||
);
|
||
});
|
||
};
|
||
this._enhancePromise(promise);
|
||
promise.abort = function () {
|
||
return jqXHR.abort();
|
||
};
|
||
upload();
|
||
return promise;
|
||
},
|
||
|
||
_beforeSend: function (e, data) {
|
||
if (this._active === 0) {
|
||
// the start callback is triggered when an upload starts
|
||
// and no other uploads are currently running,
|
||
// equivalent to the global ajaxStart event:
|
||
this._trigger('start');
|
||
// Set timer for global bitrate progress calculation:
|
||
this._bitrateTimer = new this._BitrateTimer();
|
||
// Reset the global progress values:
|
||
this._progress.loaded = this._progress.total = 0;
|
||
this._progress.bitrate = 0;
|
||
}
|
||
// Make sure the container objects for the .response() and
|
||
// .progress() methods on the data object are available
|
||
// and reset to their initial state:
|
||
this._initResponseObject(data);
|
||
this._initProgressObject(data);
|
||
data._progress.loaded = data.loaded = data.uploadedBytes || 0;
|
||
data._progress.total = data.total = this._getTotal(data.files) || 1;
|
||
data._progress.bitrate = data.bitrate = 0;
|
||
this._active += 1;
|
||
// Initialize the global progress values:
|
||
this._progress.loaded += data.loaded;
|
||
this._progress.total += data.total;
|
||
},
|
||
|
||
_onDone: function (result, textStatus, jqXHR, options) {
|
||
var total = options._progress.total,
|
||
response = options._response;
|
||
if (options._progress.loaded < total) {
|
||
// Create a progress event if no final progress event
|
||
// with loaded equaling total has been triggered:
|
||
this._onProgress($.Event('progress', {
|
||
lengthComputable: true,
|
||
loaded: total,
|
||
total: total
|
||
}), options);
|
||
}
|
||
response.result = options.result = result;
|
||
response.textStatus = options.textStatus = textStatus;
|
||
response.jqXHR = options.jqXHR = jqXHR;
|
||
this._trigger('done', null, options);
|
||
},
|
||
|
||
_onFail: function (jqXHR, textStatus, errorThrown, options) {
|
||
var response = options._response;
|
||
if (options.recalculateProgress) {
|
||
// Remove the failed (error or abort) file upload from
|
||
// the global progress calculation:
|
||
this._progress.loaded -= options._progress.loaded;
|
||
this._progress.total -= options._progress.total;
|
||
}
|
||
response.jqXHR = options.jqXHR = jqXHR;
|
||
response.textStatus = options.textStatus = textStatus;
|
||
response.errorThrown = options.errorThrown = errorThrown;
|
||
this._trigger('fail', null, options);
|
||
},
|
||
|
||
_onAlways: function (jqXHRorResult, textStatus, jqXHRorError, options) {
|
||
// jqXHRorResult, textStatus and jqXHRorError are added to the
|
||
// options object via done and fail callbacks
|
||
this._trigger('always', null, options);
|
||
},
|
||
|
||
_onSend: function (e, data) {
|
||
if (!data.submit) {
|
||
this._addConvenienceMethods(e, data);
|
||
}
|
||
var that = this,
|
||
jqXHR,
|
||
aborted,
|
||
slot,
|
||
pipe,
|
||
options = that._getAJAXSettings(data),
|
||
send = function () {
|
||
that._sending += 1;
|
||
// Set timer for bitrate progress calculation:
|
||
options._bitrateTimer = new that._BitrateTimer();
|
||
jqXHR = jqXHR || (
|
||
((aborted || that._trigger(
|
||
'send',
|
||
$.Event('send', {delegatedEvent: e}),
|
||
options
|
||
) === false) &&
|
||
that._getXHRPromise(false, options.context, aborted)) ||
|
||
that._chunkedUpload(options) || $.ajax(options)
|
||
).done(function (result, textStatus, jqXHR) {
|
||
that._onDone(result, textStatus, jqXHR, options);
|
||
}).fail(function (jqXHR, textStatus, errorThrown) {
|
||
that._onFail(jqXHR, textStatus, errorThrown, options);
|
||
}).always(function (jqXHRorResult, textStatus, jqXHRorError) {
|
||
that._onAlways(
|
||
jqXHRorResult,
|
||
textStatus,
|
||
jqXHRorError,
|
||
options
|
||
);
|
||
that._sending -= 1;
|
||
that._active -= 1;
|
||
if (options.limitConcurrentUploads &&
|
||
options.limitConcurrentUploads > that._sending) {
|
||
// Start the next queued upload,
|
||
// that has not been aborted:
|
||
var nextSlot = that._slots.shift();
|
||
while (nextSlot) {
|
||
if (that._getDeferredState(nextSlot) === 'pending') {
|
||
nextSlot.resolve();
|
||
break;
|
||
}
|
||
nextSlot = that._slots.shift();
|
||
}
|
||
}
|
||
if (that._active === 0) {
|
||
// The stop callback is triggered when all uploads have
|
||
// been completed, equivalent to the global ajaxStop event:
|
||
that._trigger('stop');
|
||
}
|
||
});
|
||
return jqXHR;
|
||
};
|
||
this._beforeSend(e, options);
|
||
if (this.options.sequentialUploads ||
|
||
(this.options.limitConcurrentUploads &&
|
||
this.options.limitConcurrentUploads <= this._sending)) {
|
||
if (this.options.limitConcurrentUploads > 1) {
|
||
slot = $.Deferred();
|
||
this._slots.push(slot);
|
||
pipe = slot.then(send);
|
||
} else {
|
||
this._sequence = this._sequence.then(send, send);
|
||
pipe = this._sequence;
|
||
}
|
||
// Return the piped Promise object, enhanced with an abort method,
|
||
// which is delegated to the jqXHR object of the current upload,
|
||
// and jqXHR callbacks mapped to the equivalent Promise methods:
|
||
pipe.abort = function () {
|
||
aborted = [undefined, 'abort', 'abort'];
|
||
if (!jqXHR) {
|
||
if (slot) {
|
||
slot.rejectWith(options.context, aborted);
|
||
}
|
||
return send();
|
||
}
|
||
return jqXHR.abort();
|
||
};
|
||
return this._enhancePromise(pipe);
|
||
}
|
||
return send();
|
||
},
|
||
|
||
_onAdd: function (e, data) {
|
||
var that = this,
|
||
result = true,
|
||
options = $.extend({}, this.options, data),
|
||
files = data.files,
|
||
filesLength = files.length,
|
||
limit = options.limitMultiFileUploads,
|
||
limitSize = options.limitMultiFileUploadSize,
|
||
overhead = options.limitMultiFileUploadSizeOverhead,
|
||
batchSize = 0,
|
||
paramName = this._getParamName(options),
|
||
paramNameSet,
|
||
paramNameSlice,
|
||
fileSet,
|
||
i,
|
||
j = 0;
|
||
if (!filesLength) {
|
||
return false;
|
||
}
|
||
if (limitSize && files[0].size === undefined) {
|
||
limitSize = undefined;
|
||
}
|
||
if (!(options.singleFileUploads || limit || limitSize) ||
|
||
!this._isXHRUpload(options)) {
|
||
fileSet = [files];
|
||
paramNameSet = [paramName];
|
||
} else if (!(options.singleFileUploads || limitSize) && limit) {
|
||
fileSet = [];
|
||
paramNameSet = [];
|
||
for (i = 0; i < filesLength; i += limit) {
|
||
fileSet.push(files.slice(i, i + limit));
|
||
paramNameSlice = paramName.slice(i, i + limit);
|
||
if (!paramNameSlice.length) {
|
||
paramNameSlice = paramName;
|
||
}
|
||
paramNameSet.push(paramNameSlice);
|
||
}
|
||
} else if (!options.singleFileUploads && limitSize) {
|
||
fileSet = [];
|
||
paramNameSet = [];
|
||
for (i = 0; i < filesLength; i = i + 1) {
|
||
batchSize += files[i].size + overhead;
|
||
if (i + 1 === filesLength ||
|
||
((batchSize + files[i + 1].size + overhead) > limitSize) ||
|
||
(limit && i + 1 - j >= limit)) {
|
||
fileSet.push(files.slice(j, i + 1));
|
||
paramNameSlice = paramName.slice(j, i + 1);
|
||
if (!paramNameSlice.length) {
|
||
paramNameSlice = paramName;
|
||
}
|
||
paramNameSet.push(paramNameSlice);
|
||
j = i + 1;
|
||
batchSize = 0;
|
||
}
|
||
}
|
||
} else {
|
||
paramNameSet = paramName;
|
||
}
|
||
data.originalFiles = files;
|
||
$.each(fileSet || files, function (index, element) {
|
||
var newData = $.extend({}, data);
|
||
newData.files = fileSet ? element : [element];
|
||
newData.paramName = paramNameSet[index];
|
||
that._initResponseObject(newData);
|
||
that._initProgressObject(newData);
|
||
that._addConvenienceMethods(e, newData);
|
||
result = that._trigger(
|
||
'add',
|
||
$.Event('add', {delegatedEvent: e}),
|
||
newData
|
||
);
|
||
return result;
|
||
});
|
||
return result;
|
||
},
|
||
|
||
_replaceFileInput: function (data) {
|
||
var input = data.fileInput,
|
||
inputClone = input.clone(true),
|
||
restoreFocus = input.is(document.activeElement);
|
||
// Add a reference for the new cloned file input to the data argument:
|
||
data.fileInputClone = inputClone;
|
||
$('<form></form>').append(inputClone)[0].reset();
|
||
// Detaching allows to insert the fileInput on another form
|
||
// without loosing the file input value:
|
||
input.after(inputClone).detach();
|
||
// If the fileInput had focus before it was detached,
|
||
// restore focus to the inputClone.
|
||
if (restoreFocus) {
|
||
inputClone.focus();
|
||
}
|
||
// Avoid memory leaks with the detached file input:
|
||
$.cleanData(input.unbind('remove'));
|
||
// Replace the original file input element in the fileInput
|
||
// elements set with the clone, which has been copied including
|
||
// event handlers:
|
||
this.options.fileInput = this.options.fileInput.map(function (i, el) {
|
||
if (el === input[0]) {
|
||
return inputClone[0];
|
||
}
|
||
return el;
|
||
});
|
||
// If the widget has been initialized on the file input itself,
|
||
// override this.element with the file input clone:
|
||
if (input[0] === this.element[0]) {
|
||
this.element = inputClone;
|
||
}
|
||
},
|
||
|
||
_handleFileTreeEntry: function (entry, path) {
|
||
var that = this,
|
||
dfd = $.Deferred(),
|
||
entries = [],
|
||
dirReader,
|
||
errorHandler = function (e) {
|
||
if (e && !e.entry) {
|
||
e.entry = entry;
|
||
}
|
||
// Since $.when returns immediately if one
|
||
// Deferred is rejected, we use resolve instead.
|
||
// This allows valid files and invalid items
|
||
// to be returned together in one set:
|
||
dfd.resolve([e]);
|
||
},
|
||
successHandler = function (entries) {
|
||
that._handleFileTreeEntries(
|
||
entries,
|
||
path + entry.name + '/'
|
||
).done(function (files) {
|
||
dfd.resolve(files);
|
||
}).fail(errorHandler);
|
||
},
|
||
readEntries = function () {
|
||
dirReader.readEntries(function (results) {
|
||
if (!results.length) {
|
||
successHandler(entries);
|
||
} else {
|
||
entries = entries.concat(results);
|
||
readEntries();
|
||
}
|
||
}, errorHandler);
|
||
};
|
||
path = path || '';
|
||
if (entry.isFile) {
|
||
if (entry._file) {
|
||
// Workaround for Chrome bug #149735
|
||
entry._file.relativePath = path;
|
||
dfd.resolve(entry._file);
|
||
} else {
|
||
entry.file(function (file) {
|
||
file.relativePath = path;
|
||
dfd.resolve(file);
|
||
}, errorHandler);
|
||
}
|
||
} else if (entry.isDirectory) {
|
||
dirReader = entry.createReader();
|
||
readEntries();
|
||
} else {
|
||
// Return an empy list for file system items
|
||
// other than files or directories:
|
||
dfd.resolve([]);
|
||
}
|
||
return dfd.promise();
|
||
},
|
||
|
||
_handleFileTreeEntries: function (entries, path) {
|
||
var that = this;
|
||
return $.when.apply(
|
||
$,
|
||
$.map(entries, function (entry) {
|
||
return that._handleFileTreeEntry(entry, path);
|
||
})
|
||
).then(function () {
|
||
return Array.prototype.concat.apply(
|
||
[],
|
||
arguments
|
||
);
|
||
});
|
||
},
|
||
|
||
_getDroppedFiles: function (dataTransfer) {
|
||
dataTransfer = dataTransfer || {};
|
||
var items = dataTransfer.items;
|
||
if (items && items.length && (items[0].webkitGetAsEntry ||
|
||
items[0].getAsEntry)) {
|
||
return this._handleFileTreeEntries(
|
||
$.map(items, function (item) {
|
||
var entry;
|
||
if (item.webkitGetAsEntry) {
|
||
entry = item.webkitGetAsEntry();
|
||
if (entry) {
|
||
// Workaround for Chrome bug #149735:
|
||
entry._file = item.getAsFile();
|
||
}
|
||
return entry;
|
||
}
|
||
return item.getAsEntry();
|
||
})
|
||
);
|
||
}
|
||
return $.Deferred().resolve(
|
||
$.makeArray(dataTransfer.files)
|
||
).promise();
|
||
},
|
||
|
||
_getSingleFileInputFiles: function (fileInput) {
|
||
fileInput = $(fileInput);
|
||
var entries = fileInput.prop('webkitEntries') ||
|
||
fileInput.prop('entries'),
|
||
files,
|
||
value;
|
||
if (entries && entries.length) {
|
||
return this._handleFileTreeEntries(entries);
|
||
}
|
||
files = $.makeArray(fileInput.prop('files'));
|
||
if (!files.length) {
|
||
value = fileInput.prop('value');
|
||
if (!value) {
|
||
return $.Deferred().resolve([]).promise();
|
||
}
|
||
// If the files property is not available, the browser does not
|
||
// support the File API and we add a pseudo File object with
|
||
// the input value as name with path information removed:
|
||
files = [{name: value.replace(/^.*\\/, '')}];
|
||
} else if (files[0].name === undefined && files[0].fileName) {
|
||
// File normalization for Safari 4 and Firefox 3:
|
||
$.each(files, function (index, file) {
|
||
file.name = file.fileName;
|
||
file.size = file.fileSize;
|
||
});
|
||
}
|
||
return $.Deferred().resolve(files).promise();
|
||
},
|
||
|
||
_getFileInputFiles: function (fileInput) {
|
||
if (!(fileInput instanceof $) || fileInput.length === 1) {
|
||
return this._getSingleFileInputFiles(fileInput);
|
||
}
|
||
return $.when.apply(
|
||
$,
|
||
$.map(fileInput, this._getSingleFileInputFiles)
|
||
).then(function () {
|
||
return Array.prototype.concat.apply(
|
||
[],
|
||
arguments
|
||
);
|
||
});
|
||
},
|
||
|
||
_onChange: function (e) {
|
||
var that = this,
|
||
data = {
|
||
fileInput: $(e.target),
|
||
form: $(e.target.form)
|
||
};
|
||
this._getFileInputFiles(data.fileInput).always(function (files) {
|
||
data.files = files;
|
||
if (that.options.replaceFileInput) {
|
||
that._replaceFileInput(data);
|
||
}
|
||
if (that._trigger(
|
||
'change',
|
||
$.Event('change', {delegatedEvent: e}),
|
||
data
|
||
) !== false) {
|
||
that._onAdd(e, data);
|
||
}
|
||
});
|
||
},
|
||
|
||
_onPaste: function (e) {
|
||
var items = e.originalEvent && e.originalEvent.clipboardData &&
|
||
e.originalEvent.clipboardData.items,
|
||
data = {files: []};
|
||
if (items && items.length) {
|
||
$.each(items, function (index, item) {
|
||
var file = item.getAsFile && item.getAsFile();
|
||
if (file) {
|
||
data.files.push(file);
|
||
}
|
||
});
|
||
if (this._trigger(
|
||
'paste',
|
||
$.Event('paste', {delegatedEvent: e}),
|
||
data
|
||
) !== false) {
|
||
this._onAdd(e, data);
|
||
}
|
||
}
|
||
},
|
||
|
||
_onDrop: function (e) {
|
||
e.dataTransfer = e.originalEvent && e.originalEvent.dataTransfer;
|
||
var that = this,
|
||
dataTransfer = e.dataTransfer,
|
||
data = {};
|
||
if (dataTransfer && dataTransfer.files && dataTransfer.files.length) {
|
||
e.preventDefault();
|
||
this._getDroppedFiles(dataTransfer).always(function (files) {
|
||
data.files = files;
|
||
if (that._trigger(
|
||
'drop',
|
||
$.Event('drop', {delegatedEvent: e}),
|
||
data
|
||
) !== false) {
|
||
that._onAdd(e, data);
|
||
}
|
||
});
|
||
}
|
||
},
|
||
|
||
_onDragOver: getDragHandler('dragover'),
|
||
|
||
_onDragEnter: getDragHandler('dragenter'),
|
||
|
||
_onDragLeave: getDragHandler('dragleave'),
|
||
|
||
_initEventHandlers: function () {
|
||
if (this._isXHRUpload(this.options)) {
|
||
this._on(this.options.dropZone, {
|
||
dragover: this._onDragOver,
|
||
drop: this._onDrop,
|
||
// event.preventDefault() on dragenter is required for IE10+:
|
||
dragenter: this._onDragEnter,
|
||
// dragleave is not required, but added for completeness:
|
||
dragleave: this._onDragLeave
|
||
});
|
||
this._on(this.options.pasteZone, {
|
||
paste: this._onPaste
|
||
});
|
||
}
|
||
if ($.support.fileInput) {
|
||
this._on(this.options.fileInput, {
|
||
change: this._onChange
|
||
});
|
||
}
|
||
},
|
||
|
||
_destroyEventHandlers: function () {
|
||
this._off(this.options.dropZone, 'dragenter dragleave dragover drop');
|
||
this._off(this.options.pasteZone, 'paste');
|
||
this._off(this.options.fileInput, 'change');
|
||
},
|
||
|
||
_destroy: function () {
|
||
this._destroyEventHandlers();
|
||
},
|
||
|
||
_setOption: function (key, value) {
|
||
var reinit = $.inArray(key, this._specialOptions) !== -1;
|
||
if (reinit) {
|
||
this._destroyEventHandlers();
|
||
}
|
||
this._super(key, value);
|
||
if (reinit) {
|
||
this._initSpecialOptions();
|
||
this._initEventHandlers();
|
||
}
|
||
},
|
||
|
||
_initSpecialOptions: function () {
|
||
var options = this.options;
|
||
if (options.fileInput === undefined) {
|
||
options.fileInput = this.element.is('input[type="file"]') ?
|
||
this.element : this.element.find('input[type="file"]');
|
||
} else if (!(options.fileInput instanceof $)) {
|
||
options.fileInput = $(options.fileInput);
|
||
}
|
||
if (!(options.dropZone instanceof $)) {
|
||
options.dropZone = $(options.dropZone);
|
||
}
|
||
if (!(options.pasteZone instanceof $)) {
|
||
options.pasteZone = $(options.pasteZone);
|
||
}
|
||
},
|
||
|
||
_getRegExp: function (str) {
|
||
var parts = str.split('/'),
|
||
modifiers = parts.pop();
|
||
parts.shift();
|
||
return new RegExp(parts.join('/'), modifiers);
|
||
},
|
||
|
||
_isRegExpOption: function (key, value) {
|
||
return key !== 'url' && $.type(value) === 'string' &&
|
||
/^\/.*\/[igm]{0,3}$/.test(value);
|
||
},
|
||
|
||
_initDataAttributes: function () {
|
||
var that = this,
|
||
options = this.options,
|
||
data = this.element.data();
|
||
// Initialize options set via HTML5 data-attributes:
|
||
$.each(
|
||
this.element[0].attributes,
|
||
function (index, attr) {
|
||
var key = attr.name.toLowerCase(),
|
||
value;
|
||
if (/^data-/.test(key)) {
|
||
// Convert hyphen-ated key to camelCase:
|
||
key = key.slice(5).replace(/-[a-z]/g, function (str) {
|
||
return str.charAt(1).toUpperCase();
|
||
});
|
||
value = data[key];
|
||
if (that._isRegExpOption(key, value)) {
|
||
value = that._getRegExp(value);
|
||
}
|
||
options[key] = value;
|
||
}
|
||
}
|
||
);
|
||
},
|
||
|
||
_create: function () {
|
||
this._initDataAttributes();
|
||
this._initSpecialOptions();
|
||
this._slots = [];
|
||
this._sequence = this._getXHRPromise(true);
|
||
this._sending = this._active = 0;
|
||
this._initProgressObject(this);
|
||
this._initEventHandlers();
|
||
},
|
||
|
||
// This method is exposed to the widget API and allows to query
|
||
// the number of active uploads:
|
||
active: function () {
|
||
return this._active;
|
||
},
|
||
|
||
// This method is exposed to the widget API and allows to query
|
||
// the widget upload progress.
|
||
// It returns an object with loaded, total and bitrate properties
|
||
// for the running uploads:
|
||
progress: function () {
|
||
return this._progress;
|
||
},
|
||
|
||
// This method is exposed to the widget API and allows adding files
|
||
// using the fileupload API. The data parameter accepts an object which
|
||
// must have a files property and can contain additional options:
|
||
// .fileupload('add', {files: filesList});
|
||
add: function (data) {
|
||
var that = this;
|
||
if (!data || this.options.disabled) {
|
||
return;
|
||
}
|
||
if (data.fileInput && !data.files) {
|
||
this._getFileInputFiles(data.fileInput).always(function (files) {
|
||
data.files = files;
|
||
that._onAdd(null, data);
|
||
});
|
||
} else {
|
||
data.files = $.makeArray(data.files);
|
||
this._onAdd(null, data);
|
||
}
|
||
},
|
||
|
||
// This method is exposed to the widget API and allows sending files
|
||
// using the fileupload API. The data parameter accepts an object which
|
||
// must have a files or fileInput property and can contain additional options:
|
||
// .fileupload('send', {files: filesList});
|
||
// The method returns a Promise object for the file upload call.
|
||
send: function (data) {
|
||
if (data && !this.options.disabled) {
|
||
if (data.fileInput && !data.files) {
|
||
var that = this,
|
||
dfd = $.Deferred(),
|
||
promise = dfd.promise(),
|
||
jqXHR,
|
||
aborted;
|
||
promise.abort = function () {
|
||
aborted = true;
|
||
if (jqXHR) {
|
||
return jqXHR.abort();
|
||
}
|
||
dfd.reject(null, 'abort', 'abort');
|
||
return promise;
|
||
};
|
||
this._getFileInputFiles(data.fileInput).always(
|
||
function (files) {
|
||
if (aborted) {
|
||
return;
|
||
}
|
||
if (!files.length) {
|
||
dfd.reject();
|
||
return;
|
||
}
|
||
data.files = files;
|
||
jqXHR = that._onSend(null, data);
|
||
jqXHR.then(
|
||
function (result, textStatus, jqXHR) {
|
||
dfd.resolve(result, textStatus, jqXHR);
|
||
},
|
||
function (jqXHR, textStatus, errorThrown) {
|
||
dfd.reject(jqXHR, textStatus, errorThrown);
|
||
}
|
||
);
|
||
}
|
||
);
|
||
return this._enhancePromise(promise);
|
||
}
|
||
data.files = $.makeArray(data.files);
|
||
if (data.files.length) {
|
||
return this._onSend(null, data);
|
||
}
|
||
}
|
||
return this._getXHRPromise(false, data && data.context);
|
||
}
|
||
|
||
});
|
||
|
||
}));
|
||
|
||
|
||
/***/ }),
|
||
/* 36 */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/*!
|
||
* jQuery UI Widget 1.12.1
|
||
* http://jqueryui.com
|
||
*
|
||
* Copyright jQuery Foundation and other contributors
|
||
* Released under the MIT license.
|
||
* http://jquery.org/license
|
||
*/
|
||
|
||
//>>label: Widget
|
||
//>>group: Core
|
||
//>>description: Provides a factory for creating stateful widgets with a common API.
|
||
//>>docs: http://api.jqueryui.com/jQuery.widget/
|
||
//>>demos: http://jqueryui.com/widget/
|
||
|
||
( function( factory ) {
|
||
if ( true ) {
|
||
|
||
// AMD. Register as an anonymous module.
|
||
!(__WEBPACK_AMD_DEFINE_ARRAY__ = [ __webpack_require__(3), __webpack_require__(37) ], __WEBPACK_AMD_DEFINE_FACTORY__ = (factory),
|
||
__WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ?
|
||
(__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__),
|
||
__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
|
||
} else {
|
||
|
||
// Browser globals
|
||
factory( jQuery );
|
||
}
|
||
}( function( $ ) {
|
||
|
||
var widgetUuid = 0;
|
||
var widgetSlice = Array.prototype.slice;
|
||
|
||
$.cleanData = ( function( orig ) {
|
||
return function( elems ) {
|
||
var events, elem, i;
|
||
for ( i = 0; ( elem = elems[ i ] ) != null; i++ ) {
|
||
try {
|
||
|
||
// Only trigger remove when necessary to save time
|
||
events = $._data( elem, "events" );
|
||
if ( events && events.remove ) {
|
||
$( elem ).triggerHandler( "remove" );
|
||
}
|
||
|
||
// Http://bugs.jquery.com/ticket/8235
|
||
} catch ( e ) {}
|
||
}
|
||
orig( elems );
|
||
};
|
||
} )( $.cleanData );
|
||
|
||
$.widget = function( name, base, prototype ) {
|
||
var existingConstructor, constructor, basePrototype;
|
||
|
||
// ProxiedPrototype allows the provided prototype to remain unmodified
|
||
// so that it can be used as a mixin for multiple widgets (#8876)
|
||
var proxiedPrototype = {};
|
||
|
||
var namespace = name.split( "." )[ 0 ];
|
||
name = name.split( "." )[ 1 ];
|
||
var fullName = namespace + "-" + name;
|
||
|
||
if ( !prototype ) {
|
||
prototype = base;
|
||
base = $.Widget;
|
||
}
|
||
|
||
if ( $.isArray( prototype ) ) {
|
||
prototype = $.extend.apply( null, [ {} ].concat( prototype ) );
|
||
}
|
||
|
||
// Create selector for plugin
|
||
$.expr[ ":" ][ fullName.toLowerCase() ] = function( elem ) {
|
||
return !!$.data( elem, fullName );
|
||
};
|
||
|
||
$[ namespace ] = $[ namespace ] || {};
|
||
existingConstructor = $[ namespace ][ name ];
|
||
constructor = $[ namespace ][ name ] = function( options, element ) {
|
||
|
||
// Allow instantiation without "new" keyword
|
||
if ( !this._createWidget ) {
|
||
return new constructor( options, element );
|
||
}
|
||
|
||
// Allow instantiation without initializing for simple inheritance
|
||
// must use "new" keyword (the code above always passes args)
|
||
if ( arguments.length ) {
|
||
this._createWidget( options, element );
|
||
}
|
||
};
|
||
|
||
// Extend with the existing constructor to carry over any static properties
|
||
$.extend( constructor, existingConstructor, {
|
||
version: prototype.version,
|
||
|
||
// Copy the object used to create the prototype in case we need to
|
||
// redefine the widget later
|
||
_proto: $.extend( {}, prototype ),
|
||
|
||
// Track widgets that inherit from this widget in case this widget is
|
||
// redefined after a widget inherits from it
|
||
_childConstructors: []
|
||
} );
|
||
|
||
basePrototype = new base();
|
||
|
||
// We need to make the options hash a property directly on the new instance
|
||
// otherwise we'll modify the options hash on the prototype that we're
|
||
// inheriting from
|
||
basePrototype.options = $.widget.extend( {}, basePrototype.options );
|
||
$.each( prototype, function( prop, value ) {
|
||
if ( !$.isFunction( value ) ) {
|
||
proxiedPrototype[ prop ] = value;
|
||
return;
|
||
}
|
||
proxiedPrototype[ prop ] = ( function() {
|
||
function _super() {
|
||
return base.prototype[ prop ].apply( this, arguments );
|
||
}
|
||
|
||
function _superApply( args ) {
|
||
return base.prototype[ prop ].apply( this, args );
|
||
}
|
||
|
||
return function() {
|
||
var __super = this._super;
|
||
var __superApply = this._superApply;
|
||
var returnValue;
|
||
|
||
this._super = _super;
|
||
this._superApply = _superApply;
|
||
|
||
returnValue = value.apply( this, arguments );
|
||
|
||
this._super = __super;
|
||
this._superApply = __superApply;
|
||
|
||
return returnValue;
|
||
};
|
||
} )();
|
||
} );
|
||
constructor.prototype = $.widget.extend( basePrototype, {
|
||
|
||
// TODO: remove support for widgetEventPrefix
|
||
// always use the name + a colon as the prefix, e.g., draggable:start
|
||
// don't prefix for widgets that aren't DOM-based
|
||
widgetEventPrefix: existingConstructor ? ( basePrototype.widgetEventPrefix || name ) : name
|
||
}, proxiedPrototype, {
|
||
constructor: constructor,
|
||
namespace: namespace,
|
||
widgetName: name,
|
||
widgetFullName: fullName
|
||
} );
|
||
|
||
// If this widget is being redefined then we need to find all widgets that
|
||
// are inheriting from it and redefine all of them so that they inherit from
|
||
// the new version of this widget. We're essentially trying to replace one
|
||
// level in the prototype chain.
|
||
if ( existingConstructor ) {
|
||
$.each( existingConstructor._childConstructors, function( i, child ) {
|
||
var childPrototype = child.prototype;
|
||
|
||
// Redefine the child widget using the same prototype that was
|
||
// originally used, but inherit from the new version of the base
|
||
$.widget( childPrototype.namespace + "." + childPrototype.widgetName, constructor,
|
||
child._proto );
|
||
} );
|
||
|
||
// Remove the list of existing child constructors from the old constructor
|
||
// so the old child constructors can be garbage collected
|
||
delete existingConstructor._childConstructors;
|
||
} else {
|
||
base._childConstructors.push( constructor );
|
||
}
|
||
|
||
$.widget.bridge( name, constructor );
|
||
|
||
return constructor;
|
||
};
|
||
|
||
$.widget.extend = function( target ) {
|
||
var input = widgetSlice.call( arguments, 1 );
|
||
var inputIndex = 0;
|
||
var inputLength = input.length;
|
||
var key;
|
||
var value;
|
||
|
||
for ( ; inputIndex < inputLength; inputIndex++ ) {
|
||
for ( key in input[ inputIndex ] ) {
|
||
value = input[ inputIndex ][ key ];
|
||
if ( input[ inputIndex ].hasOwnProperty( key ) && value !== undefined ) {
|
||
|
||
// Clone objects
|
||
if ( $.isPlainObject( value ) ) {
|
||
target[ key ] = $.isPlainObject( target[ key ] ) ?
|
||
$.widget.extend( {}, target[ key ], value ) :
|
||
|
||
// Don't extend strings, arrays, etc. with objects
|
||
$.widget.extend( {}, value );
|
||
|
||
// Copy everything else by reference
|
||
} else {
|
||
target[ key ] = value;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
return target;
|
||
};
|
||
|
||
$.widget.bridge = function( name, object ) {
|
||
var fullName = object.prototype.widgetFullName || name;
|
||
$.fn[ name ] = function( options ) {
|
||
var isMethodCall = typeof options === "string";
|
||
var args = widgetSlice.call( arguments, 1 );
|
||
var returnValue = this;
|
||
|
||
if ( isMethodCall ) {
|
||
|
||
// If this is an empty collection, we need to have the instance method
|
||
// return undefined instead of the jQuery instance
|
||
if ( !this.length && options === "instance" ) {
|
||
returnValue = undefined;
|
||
} else {
|
||
this.each( function() {
|
||
var methodValue;
|
||
var instance = $.data( this, fullName );
|
||
|
||
if ( options === "instance" ) {
|
||
returnValue = instance;
|
||
return false;
|
||
}
|
||
|
||
if ( !instance ) {
|
||
return $.error( "cannot call methods on " + name +
|
||
" prior to initialization; " +
|
||
"attempted to call method '" + options + "'" );
|
||
}
|
||
|
||
if ( !$.isFunction( instance[ options ] ) || options.charAt( 0 ) === "_" ) {
|
||
return $.error( "no such method '" + options + "' for " + name +
|
||
" widget instance" );
|
||
}
|
||
|
||
methodValue = instance[ options ].apply( instance, args );
|
||
|
||
if ( methodValue !== instance && methodValue !== undefined ) {
|
||
returnValue = methodValue && methodValue.jquery ?
|
||
returnValue.pushStack( methodValue.get() ) :
|
||
methodValue;
|
||
return false;
|
||
}
|
||
} );
|
||
}
|
||
} else {
|
||
|
||
// Allow multiple hashes to be passed on init
|
||
if ( args.length ) {
|
||
options = $.widget.extend.apply( null, [ options ].concat( args ) );
|
||
}
|
||
|
||
this.each( function() {
|
||
var instance = $.data( this, fullName );
|
||
if ( instance ) {
|
||
instance.option( options || {} );
|
||
if ( instance._init ) {
|
||
instance._init();
|
||
}
|
||
} else {
|
||
$.data( this, fullName, new object( options, this ) );
|
||
}
|
||
} );
|
||
}
|
||
|
||
return returnValue;
|
||
};
|
||
};
|
||
|
||
$.Widget = function( /* options, element */ ) {};
|
||
$.Widget._childConstructors = [];
|
||
|
||
$.Widget.prototype = {
|
||
widgetName: "widget",
|
||
widgetEventPrefix: "",
|
||
defaultElement: "<div>",
|
||
|
||
options: {
|
||
classes: {},
|
||
disabled: false,
|
||
|
||
// Callbacks
|
||
create: null
|
||
},
|
||
|
||
_createWidget: function( options, element ) {
|
||
element = $( element || this.defaultElement || this )[ 0 ];
|
||
this.element = $( element );
|
||
this.uuid = widgetUuid++;
|
||
this.eventNamespace = "." + this.widgetName + this.uuid;
|
||
|
||
this.bindings = $();
|
||
this.hoverable = $();
|
||
this.focusable = $();
|
||
this.classesElementLookup = {};
|
||
|
||
if ( element !== this ) {
|
||
$.data( element, this.widgetFullName, this );
|
||
this._on( true, this.element, {
|
||
remove: function( event ) {
|
||
if ( event.target === element ) {
|
||
this.destroy();
|
||
}
|
||
}
|
||
} );
|
||
this.document = $( element.style ?
|
||
|
||
// Element within the document
|
||
element.ownerDocument :
|
||
|
||
// Element is window or document
|
||
element.document || element );
|
||
this.window = $( this.document[ 0 ].defaultView || this.document[ 0 ].parentWindow );
|
||
}
|
||
|
||
this.options = $.widget.extend( {},
|
||
this.options,
|
||
this._getCreateOptions(),
|
||
options );
|
||
|
||
this._create();
|
||
|
||
if ( this.options.disabled ) {
|
||
this._setOptionDisabled( this.options.disabled );
|
||
}
|
||
|
||
this._trigger( "create", null, this._getCreateEventData() );
|
||
this._init();
|
||
},
|
||
|
||
_getCreateOptions: function() {
|
||
return {};
|
||
},
|
||
|
||
_getCreateEventData: $.noop,
|
||
|
||
_create: $.noop,
|
||
|
||
_init: $.noop,
|
||
|
||
destroy: function() {
|
||
var that = this;
|
||
|
||
this._destroy();
|
||
$.each( this.classesElementLookup, function( key, value ) {
|
||
that._removeClass( value, key );
|
||
} );
|
||
|
||
// We can probably remove the unbind calls in 2.0
|
||
// all event bindings should go through this._on()
|
||
this.element
|
||
.off( this.eventNamespace )
|
||
.removeData( this.widgetFullName );
|
||
this.widget()
|
||
.off( this.eventNamespace )
|
||
.removeAttr( "aria-disabled" );
|
||
|
||
// Clean up events and states
|
||
this.bindings.off( this.eventNamespace );
|
||
},
|
||
|
||
_destroy: $.noop,
|
||
|
||
widget: function() {
|
||
return this.element;
|
||
},
|
||
|
||
option: function( key, value ) {
|
||
var options = key;
|
||
var parts;
|
||
var curOption;
|
||
var i;
|
||
|
||
if ( arguments.length === 0 ) {
|
||
|
||
// Don't return a reference to the internal hash
|
||
return $.widget.extend( {}, this.options );
|
||
}
|
||
|
||
if ( typeof key === "string" ) {
|
||
|
||
// Handle nested keys, e.g., "foo.bar" => { foo: { bar: ___ } }
|
||
options = {};
|
||
parts = key.split( "." );
|
||
key = parts.shift();
|
||
if ( parts.length ) {
|
||
curOption = options[ key ] = $.widget.extend( {}, this.options[ key ] );
|
||
for ( i = 0; i < parts.length - 1; i++ ) {
|
||
curOption[ parts[ i ] ] = curOption[ parts[ i ] ] || {};
|
||
curOption = curOption[ parts[ i ] ];
|
||
}
|
||
key = parts.pop();
|
||
if ( arguments.length === 1 ) {
|
||
return curOption[ key ] === undefined ? null : curOption[ key ];
|
||
}
|
||
curOption[ key ] = value;
|
||
} else {
|
||
if ( arguments.length === 1 ) {
|
||
return this.options[ key ] === undefined ? null : this.options[ key ];
|
||
}
|
||
options[ key ] = value;
|
||
}
|
||
}
|
||
|
||
this._setOptions( options );
|
||
|
||
return this;
|
||
},
|
||
|
||
_setOptions: function( options ) {
|
||
var key;
|
||
|
||
for ( key in options ) {
|
||
this._setOption( key, options[ key ] );
|
||
}
|
||
|
||
return this;
|
||
},
|
||
|
||
_setOption: function( key, value ) {
|
||
if ( key === "classes" ) {
|
||
this._setOptionClasses( value );
|
||
}
|
||
|
||
this.options[ key ] = value;
|
||
|
||
if ( key === "disabled" ) {
|
||
this._setOptionDisabled( value );
|
||
}
|
||
|
||
return this;
|
||
},
|
||
|
||
_setOptionClasses: function( value ) {
|
||
var classKey, elements, currentElements;
|
||
|
||
for ( classKey in value ) {
|
||
currentElements = this.classesElementLookup[ classKey ];
|
||
if ( value[ classKey ] === this.options.classes[ classKey ] ||
|
||
!currentElements ||
|
||
!currentElements.length ) {
|
||
continue;
|
||
}
|
||
|
||
// We are doing this to create a new jQuery object because the _removeClass() call
|
||
// on the next line is going to destroy the reference to the current elements being
|
||
// tracked. We need to save a copy of this collection so that we can add the new classes
|
||
// below.
|
||
elements = $( currentElements.get() );
|
||
this._removeClass( currentElements, classKey );
|
||
|
||
// We don't use _addClass() here, because that uses this.options.classes
|
||
// for generating the string of classes. We want to use the value passed in from
|
||
// _setOption(), this is the new value of the classes option which was passed to
|
||
// _setOption(). We pass this value directly to _classes().
|
||
elements.addClass( this._classes( {
|
||
element: elements,
|
||
keys: classKey,
|
||
classes: value,
|
||
add: true
|
||
} ) );
|
||
}
|
||
},
|
||
|
||
_setOptionDisabled: function( value ) {
|
||
this._toggleClass( this.widget(), this.widgetFullName + "-disabled", null, !!value );
|
||
|
||
// If the widget is becoming disabled, then nothing is interactive
|
||
if ( value ) {
|
||
this._removeClass( this.hoverable, null, "ui-state-hover" );
|
||
this._removeClass( this.focusable, null, "ui-state-focus" );
|
||
}
|
||
},
|
||
|
||
enable: function() {
|
||
return this._setOptions( { disabled: false } );
|
||
},
|
||
|
||
disable: function() {
|
||
return this._setOptions( { disabled: true } );
|
||
},
|
||
|
||
_classes: function( options ) {
|
||
var full = [];
|
||
var that = this;
|
||
|
||
options = $.extend( {
|
||
element: this.element,
|
||
classes: this.options.classes || {}
|
||
}, options );
|
||
|
||
function processClassString( classes, checkOption ) {
|
||
var current, i;
|
||
for ( i = 0; i < classes.length; i++ ) {
|
||
current = that.classesElementLookup[ classes[ i ] ] || $();
|
||
if ( options.add ) {
|
||
current = $( $.unique( current.get().concat( options.element.get() ) ) );
|
||
} else {
|
||
current = $( current.not( options.element ).get() );
|
||
}
|
||
that.classesElementLookup[ classes[ i ] ] = current;
|
||
full.push( classes[ i ] );
|
||
if ( checkOption && options.classes[ classes[ i ] ] ) {
|
||
full.push( options.classes[ classes[ i ] ] );
|
||
}
|
||
}
|
||
}
|
||
|
||
this._on( options.element, {
|
||
"remove": "_untrackClassesElement"
|
||
} );
|
||
|
||
if ( options.keys ) {
|
||
processClassString( options.keys.match( /\S+/g ) || [], true );
|
||
}
|
||
if ( options.extra ) {
|
||
processClassString( options.extra.match( /\S+/g ) || [] );
|
||
}
|
||
|
||
return full.join( " " );
|
||
},
|
||
|
||
_untrackClassesElement: function( event ) {
|
||
var that = this;
|
||
$.each( that.classesElementLookup, function( key, value ) {
|
||
if ( $.inArray( event.target, value ) !== -1 ) {
|
||
that.classesElementLookup[ key ] = $( value.not( event.target ).get() );
|
||
}
|
||
} );
|
||
},
|
||
|
||
_removeClass: function( element, keys, extra ) {
|
||
return this._toggleClass( element, keys, extra, false );
|
||
},
|
||
|
||
_addClass: function( element, keys, extra ) {
|
||
return this._toggleClass( element, keys, extra, true );
|
||
},
|
||
|
||
_toggleClass: function( element, keys, extra, add ) {
|
||
add = ( typeof add === "boolean" ) ? add : extra;
|
||
var shift = ( typeof element === "string" || element === null ),
|
||
options = {
|
||
extra: shift ? keys : extra,
|
||
keys: shift ? element : keys,
|
||
element: shift ? this.element : element,
|
||
add: add
|
||
};
|
||
options.element.toggleClass( this._classes( options ), add );
|
||
return this;
|
||
},
|
||
|
||
_on: function( suppressDisabledCheck, element, handlers ) {
|
||
var delegateElement;
|
||
var instance = this;
|
||
|
||
// No suppressDisabledCheck flag, shuffle arguments
|
||
if ( typeof suppressDisabledCheck !== "boolean" ) {
|
||
handlers = element;
|
||
element = suppressDisabledCheck;
|
||
suppressDisabledCheck = false;
|
||
}
|
||
|
||
// No element argument, shuffle and use this.element
|
||
if ( !handlers ) {
|
||
handlers = element;
|
||
element = this.element;
|
||
delegateElement = this.widget();
|
||
} else {
|
||
element = delegateElement = $( element );
|
||
this.bindings = this.bindings.add( element );
|
||
}
|
||
|
||
$.each( handlers, function( event, handler ) {
|
||
function handlerProxy() {
|
||
|
||
// Allow widgets to customize the disabled handling
|
||
// - disabled as an array instead of boolean
|
||
// - disabled class as method for disabling individual parts
|
||
if ( !suppressDisabledCheck &&
|
||
( instance.options.disabled === true ||
|
||
$( this ).hasClass( "ui-state-disabled" ) ) ) {
|
||
return;
|
||
}
|
||
return ( typeof handler === "string" ? instance[ handler ] : handler )
|
||
.apply( instance, arguments );
|
||
}
|
||
|
||
// Copy the guid so direct unbinding works
|
||
if ( typeof handler !== "string" ) {
|
||
handlerProxy.guid = handler.guid =
|
||
handler.guid || handlerProxy.guid || $.guid++;
|
||
}
|
||
|
||
var match = event.match( /^([\w:-]*)\s*(.*)$/ );
|
||
var eventName = match[ 1 ] + instance.eventNamespace;
|
||
var selector = match[ 2 ];
|
||
|
||
if ( selector ) {
|
||
delegateElement.on( eventName, selector, handlerProxy );
|
||
} else {
|
||
element.on( eventName, handlerProxy );
|
||
}
|
||
} );
|
||
},
|
||
|
||
_off: function( element, eventName ) {
|
||
eventName = ( eventName || "" ).split( " " ).join( this.eventNamespace + " " ) +
|
||
this.eventNamespace;
|
||
element.off( eventName ).off( eventName );
|
||
|
||
// Clear the stack to avoid memory leaks (#10056)
|
||
this.bindings = $( this.bindings.not( element ).get() );
|
||
this.focusable = $( this.focusable.not( element ).get() );
|
||
this.hoverable = $( this.hoverable.not( element ).get() );
|
||
},
|
||
|
||
_delay: function( handler, delay ) {
|
||
function handlerProxy() {
|
||
return ( typeof handler === "string" ? instance[ handler ] : handler )
|
||
.apply( instance, arguments );
|
||
}
|
||
var instance = this;
|
||
return setTimeout( handlerProxy, delay || 0 );
|
||
},
|
||
|
||
_hoverable: function( element ) {
|
||
this.hoverable = this.hoverable.add( element );
|
||
this._on( element, {
|
||
mouseenter: function( event ) {
|
||
this._addClass( $( event.currentTarget ), null, "ui-state-hover" );
|
||
},
|
||
mouseleave: function( event ) {
|
||
this._removeClass( $( event.currentTarget ), null, "ui-state-hover" );
|
||
}
|
||
} );
|
||
},
|
||
|
||
_focusable: function( element ) {
|
||
this.focusable = this.focusable.add( element );
|
||
this._on( element, {
|
||
focusin: function( event ) {
|
||
this._addClass( $( event.currentTarget ), null, "ui-state-focus" );
|
||
},
|
||
focusout: function( event ) {
|
||
this._removeClass( $( event.currentTarget ), null, "ui-state-focus" );
|
||
}
|
||
} );
|
||
},
|
||
|
||
_trigger: function( type, event, data ) {
|
||
var prop, orig;
|
||
var callback = this.options[ type ];
|
||
|
||
data = data || {};
|
||
event = $.Event( event );
|
||
event.type = ( type === this.widgetEventPrefix ?
|
||
type :
|
||
this.widgetEventPrefix + type ).toLowerCase();
|
||
|
||
// The original event may come from any element
|
||
// so we need to reset the target on the new event
|
||
event.target = this.element[ 0 ];
|
||
|
||
// Copy original event properties over to the new event
|
||
orig = event.originalEvent;
|
||
if ( orig ) {
|
||
for ( prop in orig ) {
|
||
if ( !( prop in event ) ) {
|
||
event[ prop ] = orig[ prop ];
|
||
}
|
||
}
|
||
}
|
||
|
||
this.element.trigger( event, data );
|
||
return !( $.isFunction( callback ) &&
|
||
callback.apply( this.element[ 0 ], [ event ].concat( data ) ) === false ||
|
||
event.isDefaultPrevented() );
|
||
}
|
||
};
|
||
|
||
$.each( { show: "fadeIn", hide: "fadeOut" }, function( method, defaultEffect ) {
|
||
$.Widget.prototype[ "_" + method ] = function( element, options, callback ) {
|
||
if ( typeof options === "string" ) {
|
||
options = { effect: options };
|
||
}
|
||
|
||
var hasOptions;
|
||
var effectName = !options ?
|
||
method :
|
||
options === true || typeof options === "number" ?
|
||
defaultEffect :
|
||
options.effect || defaultEffect;
|
||
|
||
options = options || {};
|
||
if ( typeof options === "number" ) {
|
||
options = { duration: options };
|
||
}
|
||
|
||
hasOptions = !$.isEmptyObject( options );
|
||
options.complete = callback;
|
||
|
||
if ( options.delay ) {
|
||
element.delay( options.delay );
|
||
}
|
||
|
||
if ( hasOptions && $.effects && $.effects.effect[ effectName ] ) {
|
||
element[ method ]( options );
|
||
} else if ( effectName !== method && element[ effectName ] ) {
|
||
element[ effectName ]( options.duration, options.easing, callback );
|
||
} else {
|
||
element.queue( function( next ) {
|
||
$( this )[ method ]();
|
||
if ( callback ) {
|
||
callback.call( element[ 0 ] );
|
||
}
|
||
next();
|
||
} );
|
||
}
|
||
};
|
||
} );
|
||
|
||
return $.widget;
|
||
|
||
} ) );
|
||
|
||
|
||
/***/ }),
|
||
/* 37 */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;( function( factory ) {
|
||
if ( true ) {
|
||
|
||
// AMD. Register as an anonymous module.
|
||
!(__WEBPACK_AMD_DEFINE_ARRAY__ = [ __webpack_require__(3) ], __WEBPACK_AMD_DEFINE_FACTORY__ = (factory),
|
||
__WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ?
|
||
(__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__),
|
||
__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
|
||
} else {
|
||
|
||
// Browser globals
|
||
factory( jQuery );
|
||
}
|
||
} ( function( $ ) {
|
||
|
||
$.ui = $.ui || {};
|
||
|
||
return $.ui.version = "1.12.1";
|
||
|
||
} ) );
|
||
|
||
|
||
/***/ }),
|
||
/* 38 */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
var disposed = false
|
||
function injectStyle (ssrContext) {
|
||
if (disposed) return
|
||
__webpack_require__(39)
|
||
}
|
||
var Component = __webpack_require__(2)(
|
||
/* script */
|
||
__webpack_require__(41),
|
||
/* template */
|
||
__webpack_require__(42),
|
||
/* styles */
|
||
injectStyle,
|
||
/* scopeId */
|
||
"data-v-3edef3ba",
|
||
/* moduleIdentifier (server only) */
|
||
null
|
||
)
|
||
Component.options.__file = "/home/hydrogen/work/snipe-it/resources/assets/js/components/alert.vue"
|
||
if (Component.esModule && Object.keys(Component.esModule).some(function (key) {return key !== "default" && key.substr(0, 2) !== "__"})) {console.error("named exports are not supported in *.vue files.")}
|
||
if (Component.options.functional) {console.error("[vue-loader] alert.vue: functional components are not supported with templates, they should use render functions.")}
|
||
|
||
/* hot reload */
|
||
if (false) {(function () {
|
||
var hotAPI = require("vue-hot-reload-api")
|
||
hotAPI.install(require("vue"), false)
|
||
if (!hotAPI.compatible) return
|
||
module.hot.accept()
|
||
if (!module.hot.data) {
|
||
hotAPI.createRecord("data-v-3edef3ba", Component.options)
|
||
} else {
|
||
hotAPI.reload("data-v-3edef3ba", Component.options)
|
||
}
|
||
module.hot.dispose(function (data) {
|
||
disposed = true
|
||
})
|
||
})()}
|
||
|
||
module.exports = Component.exports
|
||
|
||
|
||
/***/ }),
|
||
/* 39 */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
// style-loader: Adds some css to the DOM by adding a <style> tag
|
||
|
||
// load the styles
|
||
var content = __webpack_require__(40);
|
||
if(typeof content === 'string') content = [[module.i, content, '']];
|
||
if(content.locals) module.exports = content.locals;
|
||
// add the styles to the DOM
|
||
var update = __webpack_require__(1)("dd91a98c", content, false);
|
||
// Hot Module Replacement
|
||
if(false) {
|
||
// When the styles change, update the <style> tags
|
||
if(!content.locals) {
|
||
module.hot.accept("!!../../../../node_modules/css-loader/index.js?sourceMap!../../../../node_modules/vue-loader/lib/style-compiler/index.js?{\"vue\":true,\"id\":\"data-v-3edef3ba\",\"scoped\":true,\"hasInlineConfig\":true}!../../../../node_modules/vue-loader/lib/selector.js?type=styles&index=0!./alert.vue", function() {
|
||
var newContent = require("!!../../../../node_modules/css-loader/index.js?sourceMap!../../../../node_modules/vue-loader/lib/style-compiler/index.js?{\"vue\":true,\"id\":\"data-v-3edef3ba\",\"scoped\":true,\"hasInlineConfig\":true}!../../../../node_modules/vue-loader/lib/selector.js?type=styles&index=0!./alert.vue");
|
||
if(typeof newContent === 'string') newContent = [[module.id, newContent, '']];
|
||
update(newContent);
|
||
});
|
||
}
|
||
// When the module is disposed, remove the <style> tags
|
||
module.hot.dispose(function() { update(); });
|
||
}
|
||
|
||
/***/ }),
|
||
/* 40 */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
exports = module.exports = __webpack_require__(0)(true);
|
||
// imports
|
||
|
||
|
||
// module
|
||
exports.push([module.i, "\n\n", "", {"version":3,"sources":[],"names":[],"mappings":"","file":"alert.vue","sourceRoot":""}]);
|
||
|
||
// exports
|
||
|
||
|
||
/***/ }),
|
||
/* 41 */
|
||
/***/ (function(module, __webpack_exports__, __webpack_require__) {
|
||
|
||
"use strict";
|
||
Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
|
||
/* harmony default export */ __webpack_exports__["default"] = ({
|
||
/*
|
||
* The component's data.
|
||
*/
|
||
props: ['alertType', 'title'],
|
||
|
||
computed: {
|
||
alertClassName: function alertClassName() {
|
||
return 'alert-' + this.alertType;
|
||
}
|
||
},
|
||
|
||
methods: {
|
||
hideEvent: function hideEvent() {
|
||
this.$emit('hide');
|
||
}
|
||
}
|
||
});
|
||
|
||
/***/ }),
|
||
/* 42 */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
module.exports={render:function (){var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;
|
||
return _c('div', {
|
||
staticClass: "col-md-12",
|
||
class: _vm.alertType
|
||
}, [_c('div', {
|
||
staticClass: "alert",
|
||
class: _vm.alertClassName
|
||
}, [_c('button', {
|
||
staticClass: "close",
|
||
attrs: {
|
||
"type": "button"
|
||
},
|
||
on: {
|
||
"click": _vm.hideEvent
|
||
}
|
||
}, [_vm._v("×")]), _vm._v(" "), _c('i', {
|
||
directives: [{
|
||
name: "show",
|
||
rawName: "v-show",
|
||
value: (_vm.alertType == 'success'),
|
||
expression: "alertType == 'success'"
|
||
}],
|
||
staticClass: "fa fa-check faa-pulse animated"
|
||
}), _vm._v(" "), _c('strong', [_vm._v(_vm._s(_vm.title) + " ")]), _vm._v(" "), _vm._t("default")], 2)])
|
||
},staticRenderFns: []}
|
||
module.exports.render._withStripped = true
|
||
if (false) {
|
||
module.hot.accept()
|
||
if (module.hot.data) {
|
||
require("vue-hot-reload-api").rerender("data-v-3edef3ba", module.exports)
|
||
}
|
||
}
|
||
|
||
/***/ }),
|
||
/* 43 */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
var disposed = false
|
||
function injectStyle (ssrContext) {
|
||
if (disposed) return
|
||
__webpack_require__(44)
|
||
}
|
||
var Component = __webpack_require__(2)(
|
||
/* script */
|
||
__webpack_require__(46),
|
||
/* template */
|
||
__webpack_require__(47),
|
||
/* styles */
|
||
injectStyle,
|
||
/* scopeId */
|
||
"data-v-5667c312",
|
||
/* moduleIdentifier (server only) */
|
||
null
|
||
)
|
||
Component.options.__file = "/home/hydrogen/work/snipe-it/resources/assets/js/components/importer/importer-errors.vue"
|
||
if (Component.esModule && Object.keys(Component.esModule).some(function (key) {return key !== "default" && key.substr(0, 2) !== "__"})) {console.error("named exports are not supported in *.vue files.")}
|
||
if (Component.options.functional) {console.error("[vue-loader] importer-errors.vue: functional components are not supported with templates, they should use render functions.")}
|
||
|
||
/* hot reload */
|
||
if (false) {(function () {
|
||
var hotAPI = require("vue-hot-reload-api")
|
||
hotAPI.install(require("vue"), false)
|
||
if (!hotAPI.compatible) return
|
||
module.hot.accept()
|
||
if (!module.hot.data) {
|
||
hotAPI.createRecord("data-v-5667c312", Component.options)
|
||
} else {
|
||
hotAPI.reload("data-v-5667c312", Component.options)
|
||
}
|
||
module.hot.dispose(function (data) {
|
||
disposed = true
|
||
})
|
||
})()}
|
||
|
||
module.exports = Component.exports
|
||
|
||
|
||
/***/ }),
|
||
/* 44 */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
// style-loader: Adds some css to the DOM by adding a <style> tag
|
||
|
||
// load the styles
|
||
var content = __webpack_require__(45);
|
||
if(typeof content === 'string') content = [[module.i, content, '']];
|
||
if(content.locals) module.exports = content.locals;
|
||
// add the styles to the DOM
|
||
var update = __webpack_require__(1)("309deebd", content, false);
|
||
// Hot Module Replacement
|
||
if(false) {
|
||
// When the styles change, update the <style> tags
|
||
if(!content.locals) {
|
||
module.hot.accept("!!../../../../../node_modules/css-loader/index.js?sourceMap!../../../../../node_modules/vue-loader/lib/style-compiler/index.js?{\"vue\":true,\"id\":\"data-v-5667c312\",\"scoped\":true,\"hasInlineConfig\":true}!../../../../../node_modules/vue-loader/lib/selector.js?type=styles&index=0!./importer-errors.vue", function() {
|
||
var newContent = require("!!../../../../../node_modules/css-loader/index.js?sourceMap!../../../../../node_modules/vue-loader/lib/style-compiler/index.js?{\"vue\":true,\"id\":\"data-v-5667c312\",\"scoped\":true,\"hasInlineConfig\":true}!../../../../../node_modules/vue-loader/lib/selector.js?type=styles&index=0!./importer-errors.vue");
|
||
if(typeof newContent === 'string') newContent = [[module.id, newContent, '']];
|
||
update(newContent);
|
||
});
|
||
}
|
||
// When the module is disposed, remove the <style> tags
|
||
module.hot.dispose(function() { update(); });
|
||
}
|
||
|
||
/***/ }),
|
||
/* 45 */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
exports = module.exports = __webpack_require__(0)(true);
|
||
// imports
|
||
|
||
|
||
// module
|
||
exports.push([module.i, "\n\n", "", {"version":3,"sources":[],"names":[],"mappings":"","file":"importer-errors.vue","sourceRoot":""}]);
|
||
|
||
// exports
|
||
|
||
|
||
/***/ }),
|
||
/* 46 */
|
||
/***/ (function(module, __webpack_exports__, __webpack_require__) {
|
||
|
||
"use strict";
|
||
Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
|
||
/* harmony default export */ __webpack_exports__["default"] = ({
|
||
/*
|
||
* The component's data.
|
||
*/
|
||
props: ['errors']
|
||
});
|
||
|
||
/***/ }),
|
||
/* 47 */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
module.exports={render:function (){var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;
|
||
return (_vm.errors) ? _c('div', {
|
||
staticClass: "box"
|
||
}, [_c('div', {
|
||
staticClass: "box-body"
|
||
}, [_vm._m(0), _vm._v(" "), _c('div', {
|
||
staticClass: "errors-table"
|
||
}, [_c('table', {
|
||
staticClass: "table table-striped table-bordered",
|
||
attrs: {
|
||
"id": "errors-table"
|
||
}
|
||
}, [_vm._m(1), _vm._v(" "), _c('tbody', _vm._l((_vm.errors), function(error, item) {
|
||
return _c('tr', [_c('td', [_vm._v(_vm._s(item))]), _vm._v(" "), _vm._l((error), function(value, field) {
|
||
return _c('td', [_c('b', [_vm._v(_vm._s(field) + ":")]), _vm._v(" "), _vm._l((value), function(errorString) {
|
||
return _c('span', [_vm._v(_vm._s(errorString[0]))])
|
||
}), _vm._v(" "), _c('br')], 2)
|
||
})], 2)
|
||
}))])])])]) : _vm._e()
|
||
},staticRenderFns: [function (){var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;
|
||
return _c('div', {
|
||
staticClass: "alert alert-warning"
|
||
}, [_c('strong', [_vm._v("Warning")]), _vm._v(" Some Errors occured while importing\n ")])
|
||
},function (){var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;
|
||
return _c('thead', [_c('th', [_vm._v("Item")]), _vm._v(" "), _c('th', [_vm._v("Errors")])])
|
||
}]}
|
||
module.exports.render._withStripped = true
|
||
if (false) {
|
||
module.hot.accept()
|
||
if (module.hot.data) {
|
||
require("vue-hot-reload-api").rerender("data-v-5667c312", module.exports)
|
||
}
|
||
}
|
||
|
||
/***/ }),
|
||
/* 48 */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
var disposed = false
|
||
function injectStyle (ssrContext) {
|
||
if (disposed) return
|
||
__webpack_require__(49)
|
||
}
|
||
var Component = __webpack_require__(2)(
|
||
/* script */
|
||
__webpack_require__(51),
|
||
/* template */
|
||
__webpack_require__(58),
|
||
/* styles */
|
||
injectStyle,
|
||
/* scopeId */
|
||
null,
|
||
/* moduleIdentifier (server only) */
|
||
null
|
||
)
|
||
Component.options.__file = "/home/hydrogen/work/snipe-it/resources/assets/js/components/importer/importer-file.vue"
|
||
if (Component.esModule && Object.keys(Component.esModule).some(function (key) {return key !== "default" && key.substr(0, 2) !== "__"})) {console.error("named exports are not supported in *.vue files.")}
|
||
if (Component.options.functional) {console.error("[vue-loader] importer-file.vue: functional components are not supported with templates, they should use render functions.")}
|
||
|
||
/* hot reload */
|
||
if (false) {(function () {
|
||
var hotAPI = require("vue-hot-reload-api")
|
||
hotAPI.install(require("vue"), false)
|
||
if (!hotAPI.compatible) return
|
||
module.hot.accept()
|
||
if (!module.hot.data) {
|
||
hotAPI.createRecord("data-v-91619f3a", Component.options)
|
||
} else {
|
||
hotAPI.reload("data-v-91619f3a", Component.options)
|
||
}
|
||
module.hot.dispose(function (data) {
|
||
disposed = true
|
||
})
|
||
})()}
|
||
|
||
module.exports = Component.exports
|
||
|
||
|
||
/***/ }),
|
||
/* 49 */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
// style-loader: Adds some css to the DOM by adding a <style> tag
|
||
|
||
// load the styles
|
||
var content = __webpack_require__(50);
|
||
if(typeof content === 'string') content = [[module.i, content, '']];
|
||
if(content.locals) module.exports = content.locals;
|
||
// add the styles to the DOM
|
||
var update = __webpack_require__(1)("678f48f4", content, false);
|
||
// Hot Module Replacement
|
||
if(false) {
|
||
// When the styles change, update the <style> tags
|
||
if(!content.locals) {
|
||
module.hot.accept("!!../../../../../node_modules/css-loader/index.js?sourceMap!../../../../../node_modules/vue-loader/lib/style-compiler/index.js?{\"vue\":true,\"id\":\"data-v-91619f3a\",\"scoped\":false,\"hasInlineConfig\":true}!../../../../../node_modules/vue-loader/lib/selector.js?type=styles&index=0!./importer-file.vue", function() {
|
||
var newContent = require("!!../../../../../node_modules/css-loader/index.js?sourceMap!../../../../../node_modules/vue-loader/lib/style-compiler/index.js?{\"vue\":true,\"id\":\"data-v-91619f3a\",\"scoped\":false,\"hasInlineConfig\":true}!../../../../../node_modules/vue-loader/lib/selector.js?type=styles&index=0!./importer-file.vue");
|
||
if(typeof newContent === 'string') newContent = [[module.id, newContent, '']];
|
||
update(newContent);
|
||
});
|
||
}
|
||
// When the module is disposed, remove the <style> tags
|
||
module.hot.dispose(function() { update(); });
|
||
}
|
||
|
||
/***/ }),
|
||
/* 50 */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
exports = module.exports = __webpack_require__(0)(true);
|
||
// imports
|
||
|
||
|
||
// module
|
||
exports.push([module.i, "\ntr {\n padding-left:30px;\n}\n", "", {"version":3,"sources":["/home/hydrogen/work/snipe-it/resources/assets/js/components/importer/importer-file.vue?47063959"],"names":[],"mappings":";AACA;IACA,kBAAA;CACA","file":"importer-file.vue","sourcesContent":["<style>\ntr {\n padding-left:30px;\n}\n</style>\n\n<template>\n <tr v-show=\"processDetail\">\n <td colspan=\"3\">\n <h4 class=\"modal-title\">Import File:</h4>\n <div class=\"dynamic-form-row\">\n <div class=\"col-md-4 col-xs-12\">\n <label for=\"import-type\">Import Type:</label>\n </div>\n <div class=\"col-md-4 col-xs-12\">\n <select2 :options=\"options.importTypes\" v-model=\"options.importType\">\n <option disabled value=\"0\"></option>\n </select2>\n </div>\n </div>\n <div class=\"dynamic-form-row\">\n <div class=\"col-md-4 col-xs-12\">\n <label for=\"import-update\">Update Existing Values?:</label>\n </div>\n <div class=\"col-md-4 col-xs-12\">\n <input type=\"checkbox\" name=\"import-update\" v-model=\"options.update\">\n </div>\n </div>\n\n <div class=\"col-md-12\" style=\"padding-top: 30px;\">\n <table class=\"table\">\n <thead>\n <th>Header Field</th>\n <th>Import Field</th>\n <th>Sample Value</th>\n </thead>\n <tbody>\n <template v-for=\"(header, index) in file.header_row\">\n <tr>\n <td>\n <label :for=\"header\" class=\"controllabel\">{{ header }}</label>\n </td>\n <td>\n <div required>\n <select2 :options=\"columns\" v-model=\"columnMappings[header]\">\n <option value=\"0\">Do Not Import</option>\n </select2>\n </div>\n </td>\n <td>\n <div>{{ activeFile.first_row[index] }}</div>\n </td>\n </tr>\n </template>\n </tbody>\n </table>\n </div>\n </td>\n\n <td>\n <button type=\"button\" class=\"btn btn-default\" @click=\"processDetail = false\">Cancel</button>\n <button type=\"submit\" class=\"btn btn-primary\" @click=\"postSave\">Import</button>\n <div class=\"alert alert-success col-md-5 col-md-offset-1\" style=\"text-align:left\" v-if=\"statusText\">{{ this.statusText }}</div>\n </td>\n </tr>\n</template>\n\n<script>\n export default {\n props: ['file', 'customFieldUrl'],\n data() {\n return {\n activeFile: this.file,\n processDetail: false,\n statusText: null,\n options: {\n importType: this.file.import_type,\n update: false,\n importTypes: [\n { id: 'asset', text: 'Assets' },\n { id: 'accessory', text: 'Accessories' },\n { id: 'consumable', text: 'Consumables' },\n { id: 'component', text: 'Components' },\n { id: 'license', text: 'Licenses' },\n { id: 'user', text: 'Users' }\n ],\n statusText: null,\n },\n columnOptions: {\n general: [\n {id: 'category', text: 'Category' },\n {id: 'company', text: 'Company' },\n {id: 'checkout_to', text: 'Checked out to' },\n {id: 'email', text: 'Email' },\n {id: 'first_name', text: 'First Name' },\n {id: 'item_name', text: 'Item Name' },\n {id: 'last_name', text: 'Last Name' },\n {id: 'location', text: 'Location' },\n {id: 'maintained', text: 'Maintained' },\n {id: 'manufacturer', text: 'Manufacturer' },\n {id: 'notes', text: 'Notes' },\n {id: 'order_number', text: 'Order Number' },\n {id: 'purchase_cost', text: 'Purchase Cost' },\n {id: 'purchase_date', text: 'Purchase Date' },\n {id: 'quantity', text: 'Quantity' },\n {id: 'requestable', text: 'Requestable' },\n {id: 'serial', text: 'Serial Number' },\n {id: 'supplier', text: 'Supplier' },\n {id: 'username', text: 'Username' },\n ],\n assets: [\n {id: 'asset_tag', text: 'Asset Tag' },\n {id: 'asset_model', text: 'Model Name' },\n {id: 'image', text: 'Image Filename' },\n {id: 'model_number', text: 'Model Number' },\n {id: 'name', text: 'Full Name' },\n {id: 'status', text: 'Status' },\n {id: 'warranty_months', text: 'Warranty Months' },\n ],\n licenses: [\n {id: 'expiration_date', text: 'Expiration Date' },\n {id: 'license_email', text: 'Licensed To Email' },\n {id: 'license_name', text: 'Licensed To Name' },\n {id: 'purchase_order', text: 'Purchase Order' },\n {id: 'reassignable', text: 'Reassignable' },\n {id: 'seats', text: 'Seats' },\n ],\n users: [\n {id: 'employee_num', text: 'Employee Number' },\n {id: 'jobtitle', text: 'Job Title' },\n {id: 'phone_number', text: 'Phone Number' },\n ],\n customFields: [],\n },\n columnMappings: this.file.field_map || {},\n activeColumn: null,\n }\n },\n created() {\n this.fetchCustomFields();\n window.eventHub.$on('showDetails', this.toggleExtendedDisplay)\n this.populateSelect2ActiveItems();\n },\n computed: {\n columns() {\n switch(this.options.importType) {\n case 'asset':\n return this.columnOptions.general.concat(this.columnOptions.assets).concat(this.columnOptions.customFields);\n case 'license':\n return this.columnOptions.general.concat(this.columnOptions.licenses);\n case 'user':\n return this.columnOptions.general.concat(this.columnOptions.users);\n }\n return this.columnOptions.general;\n }\n },\n methods: {\n fetchCustomFields() {\n this.$http.get(this.customFieldUrl)\n .then( ({data}) => {\n data = data.rows;\n data.forEach((item) => {\n this.columnOptions.customFields.push({\n 'id': item.db_column_name,\n 'text': item.name,\n })\n })\n });\n },\n postSave() {\n this.statusText = \"Processing...\";\n this.$http.post(this.file.process_url, {\n 'import-update': this.options.update,\n 'import-type': this.options.importType,\n 'column-mappings': this.columnMappings\n }).then( ({body}) => {\n // Success\n this.statusText = \"Success... Redirecting.\";\n window.location.href = body.messages.redirect_url;\n }, ({body}) => {\n // Failure\n if(body.status == 'import-errors') {\n window.eventHub.$emit('importErrors', body.messages);\n this.statusText = \"Error\";\n } else {\n this.$emit('alert', {\n message: body.messages,\n type: \"danger\",\n visible: true,\n })\n }\n this.displayImportModal=false;\n });\n },\n populateSelect2ActiveItems() {\n if(this.file.field_map == null) {\n // Begin by populating the active selection in dropdowns with blank values.\n for (var i=0; i < this.file.header_row.length; i++) {\n this.$set(this.columnMappings, this.file.header_row[i], null);\n }\n // Then, for any values that have a likely match, we make that active.\n for(var j=0; j < this.columns.length; j++) {\n let column = this.columns[j];\n let index = this.file.header_row.indexOf(column.text)\n if(index != -1) {\n this.$set(this.columnMappings, this.file.header_row[index], column.id)\n }\n }\n }\n },\n toggleExtendedDisplay(fileId) {\n if(fileId == this.file.id) {\n this.processDetail = !this.processDetail\n }\n },\n updateModel(header, value) {\n console.log(header, value);\n this.columnMappings[header] = value;\n }\n },\n components: {\n select2: require('../select2.vue')\n }\n }\n</script>\n"],"sourceRoot":""}]);
|
||
|
||
// exports
|
||
|
||
|
||
/***/ }),
|
||
/* 51 */
|
||
/***/ (function(module, __webpack_exports__, __webpack_require__) {
|
||
|
||
"use strict";
|
||
Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
|
||
/* harmony default export */ __webpack_exports__["default"] = ({
|
||
props: ['file', 'customFieldUrl'],
|
||
data: function data() {
|
||
return {
|
||
activeFile: this.file,
|
||
processDetail: false,
|
||
statusText: null,
|
||
options: {
|
||
importType: this.file.import_type,
|
||
update: false,
|
||
importTypes: [{ id: 'asset', text: 'Assets' }, { id: 'accessory', text: 'Accessories' }, { id: 'consumable', text: 'Consumables' }, { id: 'component', text: 'Components' }, { id: 'license', text: 'Licenses' }, { id: 'user', text: 'Users' }],
|
||
statusText: null
|
||
},
|
||
columnOptions: {
|
||
general: [{ id: 'category', text: 'Category' }, { id: 'company', text: 'Company' }, { id: 'checkout_to', text: 'Checked out to' }, { id: 'email', text: 'Email' }, { id: 'first_name', text: 'First Name' }, { id: 'item_name', text: 'Item Name' }, { id: 'last_name', text: 'Last Name' }, { id: 'location', text: 'Location' }, { id: 'maintained', text: 'Maintained' }, { id: 'manufacturer', text: 'Manufacturer' }, { id: 'notes', text: 'Notes' }, { id: 'order_number', text: 'Order Number' }, { id: 'purchase_cost', text: 'Purchase Cost' }, { id: 'purchase_date', text: 'Purchase Date' }, { id: 'quantity', text: 'Quantity' }, { id: 'requestable', text: 'Requestable' }, { id: 'serial', text: 'Serial Number' }, { id: 'supplier', text: 'Supplier' }, { id: 'username', text: 'Username' }],
|
||
assets: [{ id: 'asset_tag', text: 'Asset Tag' }, { id: 'asset_model', text: 'Model Name' }, { id: 'image', text: 'Image Filename' }, { id: 'model_number', text: 'Model Number' }, { id: 'name', text: 'Full Name' }, { id: 'status', text: 'Status' }, { id: 'warranty_months', text: 'Warranty Months' }],
|
||
licenses: [{ id: 'expiration_date', text: 'Expiration Date' }, { id: 'license_email', text: 'Licensed To Email' }, { id: 'license_name', text: 'Licensed To Name' }, { id: 'purchase_order', text: 'Purchase Order' }, { id: 'reassignable', text: 'Reassignable' }, { id: 'seats', text: 'Seats' }],
|
||
users: [{ id: 'employee_num', text: 'Employee Number' }, { id: 'jobtitle', text: 'Job Title' }, { id: 'phone_number', text: 'Phone Number' }],
|
||
customFields: []
|
||
},
|
||
columnMappings: this.file.field_map || {},
|
||
activeColumn: null
|
||
};
|
||
},
|
||
created: function created() {
|
||
this.fetchCustomFields();
|
||
window.eventHub.$on('showDetails', this.toggleExtendedDisplay);
|
||
this.populateSelect2ActiveItems();
|
||
},
|
||
|
||
computed: {
|
||
columns: function columns() {
|
||
switch (this.options.importType) {
|
||
case 'asset':
|
||
return this.columnOptions.general.concat(this.columnOptions.assets).concat(this.columnOptions.customFields);
|
||
case 'license':
|
||
return this.columnOptions.general.concat(this.columnOptions.licenses);
|
||
case 'user':
|
||
return this.columnOptions.general.concat(this.columnOptions.users);
|
||
}
|
||
return this.columnOptions.general;
|
||
}
|
||
},
|
||
methods: {
|
||
fetchCustomFields: function fetchCustomFields() {
|
||
var _this = this;
|
||
|
||
this.$http.get(this.customFieldUrl).then(function (_ref) {
|
||
var data = _ref.data;
|
||
|
||
data = data.rows;
|
||
data.forEach(function (item) {
|
||
_this.columnOptions.customFields.push({
|
||
'id': item.db_column_name,
|
||
'text': item.name
|
||
});
|
||
});
|
||
});
|
||
},
|
||
postSave: function postSave() {
|
||
var _this2 = this;
|
||
|
||
this.statusText = "Processing...";
|
||
this.$http.post(this.file.process_url, {
|
||
'import-update': this.options.update,
|
||
'import-type': this.options.importType,
|
||
'column-mappings': this.columnMappings
|
||
}).then(function (_ref2) {
|
||
var body = _ref2.body;
|
||
|
||
// Success
|
||
_this2.statusText = "Success... Redirecting.";
|
||
window.location.href = body.messages.redirect_url;
|
||
}, function (_ref3) {
|
||
var body = _ref3.body;
|
||
|
||
// Failure
|
||
if (body.status == 'import-errors') {
|
||
window.eventHub.$emit('importErrors', body.messages);
|
||
_this2.statusText = "Error";
|
||
} else {
|
||
_this2.$emit('alert', {
|
||
message: body.messages,
|
||
type: "danger",
|
||
visible: true
|
||
});
|
||
}
|
||
_this2.displayImportModal = false;
|
||
});
|
||
},
|
||
populateSelect2ActiveItems: function populateSelect2ActiveItems() {
|
||
if (this.file.field_map == null) {
|
||
// Begin by populating the active selection in dropdowns with blank values.
|
||
for (var i = 0; i < this.file.header_row.length; i++) {
|
||
this.$set(this.columnMappings, this.file.header_row[i], null);
|
||
}
|
||
// Then, for any values that have a likely match, we make that active.
|
||
for (var j = 0; j < this.columns.length; j++) {
|
||
var column = this.columns[j];
|
||
var index = this.file.header_row.indexOf(column.text);
|
||
if (index != -1) {
|
||
this.$set(this.columnMappings, this.file.header_row[index], column.id);
|
||
}
|
||
}
|
||
}
|
||
},
|
||
toggleExtendedDisplay: function toggleExtendedDisplay(fileId) {
|
||
if (fileId == this.file.id) {
|
||
this.processDetail = !this.processDetail;
|
||
}
|
||
},
|
||
updateModel: function updateModel(header, value) {
|
||
console.log(header, value);
|
||
this.columnMappings[header] = value;
|
||
}
|
||
},
|
||
components: {
|
||
select2: __webpack_require__(52)
|
||
}
|
||
});
|
||
|
||
/***/ }),
|
||
/* 52 */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
var disposed = false
|
||
function injectStyle (ssrContext) {
|
||
if (disposed) return
|
||
__webpack_require__(53)
|
||
}
|
||
var Component = __webpack_require__(2)(
|
||
/* script */
|
||
__webpack_require__(55),
|
||
/* template */
|
||
__webpack_require__(57),
|
||
/* styles */
|
||
injectStyle,
|
||
/* scopeId */
|
||
"data-v-ff564a86",
|
||
/* moduleIdentifier (server only) */
|
||
null
|
||
)
|
||
Component.options.__file = "/home/hydrogen/work/snipe-it/resources/assets/js/components/select2.vue"
|
||
if (Component.esModule && Object.keys(Component.esModule).some(function (key) {return key !== "default" && key.substr(0, 2) !== "__"})) {console.error("named exports are not supported in *.vue files.")}
|
||
if (Component.options.functional) {console.error("[vue-loader] select2.vue: functional components are not supported with templates, they should use render functions.")}
|
||
|
||
/* hot reload */
|
||
if (false) {(function () {
|
||
var hotAPI = require("vue-hot-reload-api")
|
||
hotAPI.install(require("vue"), false)
|
||
if (!hotAPI.compatible) return
|
||
module.hot.accept()
|
||
if (!module.hot.data) {
|
||
hotAPI.createRecord("data-v-ff564a86", Component.options)
|
||
} else {
|
||
hotAPI.reload("data-v-ff564a86", Component.options)
|
||
}
|
||
module.hot.dispose(function (data) {
|
||
disposed = true
|
||
})
|
||
})()}
|
||
|
||
module.exports = Component.exports
|
||
|
||
|
||
/***/ }),
|
||
/* 53 */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
// style-loader: Adds some css to the DOM by adding a <style> tag
|
||
|
||
// load the styles
|
||
var content = __webpack_require__(54);
|
||
if(typeof content === 'string') content = [[module.i, content, '']];
|
||
if(content.locals) module.exports = content.locals;
|
||
// add the styles to the DOM
|
||
var update = __webpack_require__(1)("48f4d153", content, false);
|
||
// Hot Module Replacement
|
||
if(false) {
|
||
// When the styles change, update the <style> tags
|
||
if(!content.locals) {
|
||
module.hot.accept("!!../../../../node_modules/css-loader/index.js?sourceMap!../../../../node_modules/vue-loader/lib/style-compiler/index.js?{\"vue\":true,\"id\":\"data-v-ff564a86\",\"scoped\":true,\"hasInlineConfig\":true}!../../../../node_modules/vue-loader/lib/selector.js?type=styles&index=0!./select2.vue", function() {
|
||
var newContent = require("!!../../../../node_modules/css-loader/index.js?sourceMap!../../../../node_modules/vue-loader/lib/style-compiler/index.js?{\"vue\":true,\"id\":\"data-v-ff564a86\",\"scoped\":true,\"hasInlineConfig\":true}!../../../../node_modules/vue-loader/lib/selector.js?type=styles&index=0!./select2.vue");
|
||
if(typeof newContent === 'string') newContent = [[module.id, newContent, '']];
|
||
update(newContent);
|
||
});
|
||
}
|
||
// When the module is disposed, remove the <style> tags
|
||
module.hot.dispose(function() { update(); });
|
||
}
|
||
|
||
/***/ }),
|
||
/* 54 */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
exports = module.exports = __webpack_require__(0)(true);
|
||
// imports
|
||
|
||
|
||
// module
|
||
exports.push([module.i, "\n.select2-dropdown[data-v-ff564a86] {\n z-index:9999;\n}\n", "", {"version":3,"sources":["/home/hydrogen/work/snipe-it/resources/assets/js/components/select2.vue?5e14c42b"],"names":[],"mappings":";AAEA;IACA,aAAA;CACA","file":"select2.vue","sourcesContent":["\n<style scoped>\n .select2-dropdown {\n z-index:9999;\n }\n</style>\n\n<template>\n <select style=\"width:100%\">\n <slot></slot>\n </select>\n</template>\n\n<script>\n require('select2');\n export default {\n /*\n * The component's data.\n */\n props: ['options', 'value'],\n\n mounted() {\n var vm = this;\n $(this.$el)\n .select2({\n data: this.options\n })\n .on('change', function() { vm.$emit('input', this.value) } )\n .val(this.value).trigger('change');\n },\n watch: {\n value: function (value) {\n $(this.$el).val(value)\n },\n options: function (options) {\n var vm = this;\n $(this.$el).select2('destroy').empty().select2({data: options})\n .on('change', function() { vm.$emit('input', this.value) } )\n .val(this.value).trigger('change');\n },\n destroyed: function() {\n $(this.$el).off().select2('destroy')\n }\n }\n }\n\n</script>\n"],"sourceRoot":""}]);
|
||
|
||
// exports
|
||
|
||
|
||
/***/ }),
|
||
/* 55 */
|
||
/***/ (function(module, __webpack_exports__, __webpack_require__) {
|
||
|
||
"use strict";
|
||
Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
//
|
||
|
||
__webpack_require__(56);
|
||
/* harmony default export */ __webpack_exports__["default"] = ({
|
||
/*
|
||
* The component's data.
|
||
*/
|
||
props: ['options', 'value'],
|
||
|
||
mounted: function mounted() {
|
||
var vm = this;
|
||
$(this.$el).select2({
|
||
data: this.options
|
||
}).on('change', function () {
|
||
vm.$emit('input', this.value);
|
||
}).val(this.value).trigger('change');
|
||
},
|
||
|
||
watch: {
|
||
value: function value(_value) {
|
||
$(this.$el).val(_value);
|
||
},
|
||
options: function options(_options) {
|
||
var vm = this;
|
||
$(this.$el).select2('destroy').empty().select2({ data: _options }).on('change', function () {
|
||
vm.$emit('input', this.value);
|
||
}).val(this.value).trigger('change');
|
||
},
|
||
destroyed: function destroyed() {
|
||
$(this.$el).off().select2('destroy');
|
||
}
|
||
}
|
||
});
|
||
|
||
/***/ }),
|
||
/* 56 */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;var require;var require;/*!
|
||
* Select2 4.0.3
|
||
* https://select2.github.io
|
||
*
|
||
* Released under the MIT license
|
||
* https://github.com/select2/select2/blob/master/LICENSE.md
|
||
*/
|
||
(function (factory) {
|
||
if (true) {
|
||
// AMD. Register as an anonymous module.
|
||
!(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(3)], __WEBPACK_AMD_DEFINE_FACTORY__ = (factory),
|
||
__WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ?
|
||
(__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__),
|
||
__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
|
||
} else if (typeof exports === 'object') {
|
||
// Node/CommonJS
|
||
factory(require('jquery'));
|
||
} else {
|
||
// Browser globals
|
||
factory(jQuery);
|
||
}
|
||
}(function (jQuery) {
|
||
// This is needed so we can catch the AMD loader configuration and use it
|
||
// The inner file should be wrapped (by `banner.start.js`) in a function that
|
||
// returns the AMD loader references.
|
||
var S2 =
|
||
(function () {
|
||
// Restore the Select2 AMD loader so it can be used
|
||
// Needed mostly in the language files, where the loader is not inserted
|
||
if (jQuery && jQuery.fn && jQuery.fn.select2 && jQuery.fn.select2.amd) {
|
||
var S2 = jQuery.fn.select2.amd;
|
||
}
|
||
var S2;(function () { if (!S2 || !S2.requirejs) {
|
||
if (!S2) { S2 = {}; } else { require = S2; }
|
||
/**
|
||
* @license almond 0.3.1 Copyright (c) 2011-2014, The Dojo Foundation All Rights Reserved.
|
||
* Available via the MIT or new BSD license.
|
||
* see: http://github.com/jrburke/almond for details
|
||
*/
|
||
//Going sloppy to avoid 'use strict' string cost, but strict practices should
|
||
//be followed.
|
||
/*jslint sloppy: true */
|
||
/*global setTimeout: false */
|
||
|
||
var requirejs, require, define;
|
||
(function (undef) {
|
||
var main, req, makeMap, handlers,
|
||
defined = {},
|
||
waiting = {},
|
||
config = {},
|
||
defining = {},
|
||
hasOwn = Object.prototype.hasOwnProperty,
|
||
aps = [].slice,
|
||
jsSuffixRegExp = /\.js$/;
|
||
|
||
function hasProp(obj, prop) {
|
||
return hasOwn.call(obj, prop);
|
||
}
|
||
|
||
/**
|
||
* Given a relative module name, like ./something, normalize it to
|
||
* a real name that can be mapped to a path.
|
||
* @param {String} name the relative name
|
||
* @param {String} baseName a real name that the name arg is relative
|
||
* to.
|
||
* @returns {String} normalized name
|
||
*/
|
||
function normalize(name, baseName) {
|
||
var nameParts, nameSegment, mapValue, foundMap, lastIndex,
|
||
foundI, foundStarMap, starI, i, j, part,
|
||
baseParts = baseName && baseName.split("/"),
|
||
map = config.map,
|
||
starMap = (map && map['*']) || {};
|
||
|
||
//Adjust any relative paths.
|
||
if (name && name.charAt(0) === ".") {
|
||
//If have a base name, try to normalize against it,
|
||
//otherwise, assume it is a top-level require that will
|
||
//be relative to baseUrl in the end.
|
||
if (baseName) {
|
||
name = name.split('/');
|
||
lastIndex = name.length - 1;
|
||
|
||
// Node .js allowance:
|
||
if (config.nodeIdCompat && jsSuffixRegExp.test(name[lastIndex])) {
|
||
name[lastIndex] = name[lastIndex].replace(jsSuffixRegExp, '');
|
||
}
|
||
|
||
//Lop off the last part of baseParts, so that . matches the
|
||
//"directory" and not name of the baseName's module. For instance,
|
||
//baseName of "one/two/three", maps to "one/two/three.js", but we
|
||
//want the directory, "one/two" for this normalization.
|
||
name = baseParts.slice(0, baseParts.length - 1).concat(name);
|
||
|
||
//start trimDots
|
||
for (i = 0; i < name.length; i += 1) {
|
||
part = name[i];
|
||
if (part === ".") {
|
||
name.splice(i, 1);
|
||
i -= 1;
|
||
} else if (part === "..") {
|
||
if (i === 1 && (name[2] === '..' || name[0] === '..')) {
|
||
//End of the line. Keep at least one non-dot
|
||
//path segment at the front so it can be mapped
|
||
//correctly to disk. Otherwise, there is likely
|
||
//no path mapping for a path starting with '..'.
|
||
//This can still fail, but catches the most reasonable
|
||
//uses of ..
|
||
break;
|
||
} else if (i > 0) {
|
||
name.splice(i - 1, 2);
|
||
i -= 2;
|
||
}
|
||
}
|
||
}
|
||
//end trimDots
|
||
|
||
name = name.join("/");
|
||
} else if (name.indexOf('./') === 0) {
|
||
// No baseName, so this is ID is resolved relative
|
||
// to baseUrl, pull off the leading dot.
|
||
name = name.substring(2);
|
||
}
|
||
}
|
||
|
||
//Apply map config if available.
|
||
if ((baseParts || starMap) && map) {
|
||
nameParts = name.split('/');
|
||
|
||
for (i = nameParts.length; i > 0; i -= 1) {
|
||
nameSegment = nameParts.slice(0, i).join("/");
|
||
|
||
if (baseParts) {
|
||
//Find the longest baseName segment match in the config.
|
||
//So, do joins on the biggest to smallest lengths of baseParts.
|
||
for (j = baseParts.length; j > 0; j -= 1) {
|
||
mapValue = map[baseParts.slice(0, j).join('/')];
|
||
|
||
//baseName segment has config, find if it has one for
|
||
//this name.
|
||
if (mapValue) {
|
||
mapValue = mapValue[nameSegment];
|
||
if (mapValue) {
|
||
//Match, update name to the new value.
|
||
foundMap = mapValue;
|
||
foundI = i;
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
if (foundMap) {
|
||
break;
|
||
}
|
||
|
||
//Check for a star map match, but just hold on to it,
|
||
//if there is a shorter segment match later in a matching
|
||
//config, then favor over this star map.
|
||
if (!foundStarMap && starMap && starMap[nameSegment]) {
|
||
foundStarMap = starMap[nameSegment];
|
||
starI = i;
|
||
}
|
||
}
|
||
|
||
if (!foundMap && foundStarMap) {
|
||
foundMap = foundStarMap;
|
||
foundI = starI;
|
||
}
|
||
|
||
if (foundMap) {
|
||
nameParts.splice(0, foundI, foundMap);
|
||
name = nameParts.join('/');
|
||
}
|
||
}
|
||
|
||
return name;
|
||
}
|
||
|
||
function makeRequire(relName, forceSync) {
|
||
return function () {
|
||
//A version of a require function that passes a moduleName
|
||
//value for items that may need to
|
||
//look up paths relative to the moduleName
|
||
var args = aps.call(arguments, 0);
|
||
|
||
//If first arg is not require('string'), and there is only
|
||
//one arg, it is the array form without a callback. Insert
|
||
//a null so that the following concat is correct.
|
||
if (typeof args[0] !== 'string' && args.length === 1) {
|
||
args.push(null);
|
||
}
|
||
return req.apply(undef, args.concat([relName, forceSync]));
|
||
};
|
||
}
|
||
|
||
function makeNormalize(relName) {
|
||
return function (name) {
|
||
return normalize(name, relName);
|
||
};
|
||
}
|
||
|
||
function makeLoad(depName) {
|
||
return function (value) {
|
||
defined[depName] = value;
|
||
};
|
||
}
|
||
|
||
function callDep(name) {
|
||
if (hasProp(waiting, name)) {
|
||
var args = waiting[name];
|
||
delete waiting[name];
|
||
defining[name] = true;
|
||
main.apply(undef, args);
|
||
}
|
||
|
||
if (!hasProp(defined, name) && !hasProp(defining, name)) {
|
||
throw new Error('No ' + name);
|
||
}
|
||
return defined[name];
|
||
}
|
||
|
||
//Turns a plugin!resource to [plugin, resource]
|
||
//with the plugin being undefined if the name
|
||
//did not have a plugin prefix.
|
||
function splitPrefix(name) {
|
||
var prefix,
|
||
index = name ? name.indexOf('!') : -1;
|
||
if (index > -1) {
|
||
prefix = name.substring(0, index);
|
||
name = name.substring(index + 1, name.length);
|
||
}
|
||
return [prefix, name];
|
||
}
|
||
|
||
/**
|
||
* Makes a name map, normalizing the name, and using a plugin
|
||
* for normalization if necessary. Grabs a ref to plugin
|
||
* too, as an optimization.
|
||
*/
|
||
makeMap = function (name, relName) {
|
||
var plugin,
|
||
parts = splitPrefix(name),
|
||
prefix = parts[0];
|
||
|
||
name = parts[1];
|
||
|
||
if (prefix) {
|
||
prefix = normalize(prefix, relName);
|
||
plugin = callDep(prefix);
|
||
}
|
||
|
||
//Normalize according
|
||
if (prefix) {
|
||
if (plugin && plugin.normalize) {
|
||
name = plugin.normalize(name, makeNormalize(relName));
|
||
} else {
|
||
name = normalize(name, relName);
|
||
}
|
||
} else {
|
||
name = normalize(name, relName);
|
||
parts = splitPrefix(name);
|
||
prefix = parts[0];
|
||
name = parts[1];
|
||
if (prefix) {
|
||
plugin = callDep(prefix);
|
||
}
|
||
}
|
||
|
||
//Using ridiculous property names for space reasons
|
||
return {
|
||
f: prefix ? prefix + '!' + name : name, //fullName
|
||
n: name,
|
||
pr: prefix,
|
||
p: plugin
|
||
};
|
||
};
|
||
|
||
function makeConfig(name) {
|
||
return function () {
|
||
return (config && config.config && config.config[name]) || {};
|
||
};
|
||
}
|
||
|
||
handlers = {
|
||
require: function (name) {
|
||
return makeRequire(name);
|
||
},
|
||
exports: function (name) {
|
||
var e = defined[name];
|
||
if (typeof e !== 'undefined') {
|
||
return e;
|
||
} else {
|
||
return (defined[name] = {});
|
||
}
|
||
},
|
||
module: function (name) {
|
||
return {
|
||
id: name,
|
||
uri: '',
|
||
exports: defined[name],
|
||
config: makeConfig(name)
|
||
};
|
||
}
|
||
};
|
||
|
||
main = function (name, deps, callback, relName) {
|
||
var cjsModule, depName, ret, map, i,
|
||
args = [],
|
||
callbackType = typeof callback,
|
||
usingExports;
|
||
|
||
//Use name if no relName
|
||
relName = relName || name;
|
||
|
||
//Call the callback to define the module, if necessary.
|
||
if (callbackType === 'undefined' || callbackType === 'function') {
|
||
//Pull out the defined dependencies and pass the ordered
|
||
//values to the callback.
|
||
//Default to [require, exports, module] if no deps
|
||
deps = !deps.length && callback.length ? ['require', 'exports', 'module'] : deps;
|
||
for (i = 0; i < deps.length; i += 1) {
|
||
map = makeMap(deps[i], relName);
|
||
depName = map.f;
|
||
|
||
//Fast path CommonJS standard dependencies.
|
||
if (depName === "require") {
|
||
args[i] = handlers.require(name);
|
||
} else if (depName === "exports") {
|
||
//CommonJS module spec 1.1
|
||
args[i] = handlers.exports(name);
|
||
usingExports = true;
|
||
} else if (depName === "module") {
|
||
//CommonJS module spec 1.1
|
||
cjsModule = args[i] = handlers.module(name);
|
||
} else if (hasProp(defined, depName) ||
|
||
hasProp(waiting, depName) ||
|
||
hasProp(defining, depName)) {
|
||
args[i] = callDep(depName);
|
||
} else if (map.p) {
|
||
map.p.load(map.n, makeRequire(relName, true), makeLoad(depName), {});
|
||
args[i] = defined[depName];
|
||
} else {
|
||
throw new Error(name + ' missing ' + depName);
|
||
}
|
||
}
|
||
|
||
ret = callback ? callback.apply(defined[name], args) : undefined;
|
||
|
||
if (name) {
|
||
//If setting exports via "module" is in play,
|
||
//favor that over return value and exports. After that,
|
||
//favor a non-undefined return value over exports use.
|
||
if (cjsModule && cjsModule.exports !== undef &&
|
||
cjsModule.exports !== defined[name]) {
|
||
defined[name] = cjsModule.exports;
|
||
} else if (ret !== undef || !usingExports) {
|
||
//Use the return value from the function.
|
||
defined[name] = ret;
|
||
}
|
||
}
|
||
} else if (name) {
|
||
//May just be an object definition for the module. Only
|
||
//worry about defining if have a module name.
|
||
defined[name] = callback;
|
||
}
|
||
};
|
||
|
||
requirejs = require = req = function (deps, callback, relName, forceSync, alt) {
|
||
if (typeof deps === "string") {
|
||
if (handlers[deps]) {
|
||
//callback in this case is really relName
|
||
return handlers[deps](callback);
|
||
}
|
||
//Just return the module wanted. In this scenario, the
|
||
//deps arg is the module name, and second arg (if passed)
|
||
//is just the relName.
|
||
//Normalize module name, if it contains . or ..
|
||
return callDep(makeMap(deps, callback).f);
|
||
} else if (!deps.splice) {
|
||
//deps is a config object, not an array.
|
||
config = deps;
|
||
if (config.deps) {
|
||
req(config.deps, config.callback);
|
||
}
|
||
if (!callback) {
|
||
return;
|
||
}
|
||
|
||
if (callback.splice) {
|
||
//callback is an array, which means it is a dependency list.
|
||
//Adjust args if there are dependencies
|
||
deps = callback;
|
||
callback = relName;
|
||
relName = null;
|
||
} else {
|
||
deps = undef;
|
||
}
|
||
}
|
||
|
||
//Support require(['a'])
|
||
callback = callback || function () {};
|
||
|
||
//If relName is a function, it is an errback handler,
|
||
//so remove it.
|
||
if (typeof relName === 'function') {
|
||
relName = forceSync;
|
||
forceSync = alt;
|
||
}
|
||
|
||
//Simulate async callback;
|
||
if (forceSync) {
|
||
main(undef, deps, callback, relName);
|
||
} else {
|
||
//Using a non-zero value because of concern for what old browsers
|
||
//do, and latest browsers "upgrade" to 4 if lower value is used:
|
||
//http://www.whatwg.org/specs/web-apps/current-work/multipage/timers.html#dom-windowtimers-settimeout:
|
||
//If want a value immediately, use require('id') instead -- something
|
||
//that works in almond on the global level, but not guaranteed and
|
||
//unlikely to work in other AMD implementations.
|
||
setTimeout(function () {
|
||
main(undef, deps, callback, relName);
|
||
}, 4);
|
||
}
|
||
|
||
return req;
|
||
};
|
||
|
||
/**
|
||
* Just drops the config on the floor, but returns req in case
|
||
* the config return value is used.
|
||
*/
|
||
req.config = function (cfg) {
|
||
return req(cfg);
|
||
};
|
||
|
||
/**
|
||
* Expose module registry for debugging and tooling
|
||
*/
|
||
requirejs._defined = defined;
|
||
|
||
define = function (name, deps, callback) {
|
||
if (typeof name !== 'string') {
|
||
throw new Error('See almond README: incorrect module build, no module name');
|
||
}
|
||
|
||
//This module may not have dependencies
|
||
if (!deps.splice) {
|
||
//deps is not an array, so probably means
|
||
//an object literal or factory function for
|
||
//the value. Adjust args.
|
||
callback = deps;
|
||
deps = [];
|
||
}
|
||
|
||
if (!hasProp(defined, name) && !hasProp(waiting, name)) {
|
||
waiting[name] = [name, deps, callback];
|
||
}
|
||
};
|
||
|
||
define.amd = {
|
||
jQuery: true
|
||
};
|
||
}());
|
||
|
||
S2.requirejs = requirejs;S2.require = require;S2.define = define;
|
||
}
|
||
}());
|
||
S2.define("almond", function(){});
|
||
|
||
/* global jQuery:false, $:false */
|
||
S2.define('jquery',[],function () {
|
||
var _$ = jQuery || $;
|
||
|
||
if (_$ == null && console && console.error) {
|
||
console.error(
|
||
'Select2: An instance of jQuery or a jQuery-compatible library was not ' +
|
||
'found. Make sure that you are including jQuery before Select2 on your ' +
|
||
'web page.'
|
||
);
|
||
}
|
||
|
||
return _$;
|
||
});
|
||
|
||
S2.define('select2/utils',[
|
||
'jquery'
|
||
], function ($) {
|
||
var Utils = {};
|
||
|
||
Utils.Extend = function (ChildClass, SuperClass) {
|
||
var __hasProp = {}.hasOwnProperty;
|
||
|
||
function BaseConstructor () {
|
||
this.constructor = ChildClass;
|
||
}
|
||
|
||
for (var key in SuperClass) {
|
||
if (__hasProp.call(SuperClass, key)) {
|
||
ChildClass[key] = SuperClass[key];
|
||
}
|
||
}
|
||
|
||
BaseConstructor.prototype = SuperClass.prototype;
|
||
ChildClass.prototype = new BaseConstructor();
|
||
ChildClass.__super__ = SuperClass.prototype;
|
||
|
||
return ChildClass;
|
||
};
|
||
|
||
function getMethods (theClass) {
|
||
var proto = theClass.prototype;
|
||
|
||
var methods = [];
|
||
|
||
for (var methodName in proto) {
|
||
var m = proto[methodName];
|
||
|
||
if (typeof m !== 'function') {
|
||
continue;
|
||
}
|
||
|
||
if (methodName === 'constructor') {
|
||
continue;
|
||
}
|
||
|
||
methods.push(methodName);
|
||
}
|
||
|
||
return methods;
|
||
}
|
||
|
||
Utils.Decorate = function (SuperClass, DecoratorClass) {
|
||
var decoratedMethods = getMethods(DecoratorClass);
|
||
var superMethods = getMethods(SuperClass);
|
||
|
||
function DecoratedClass () {
|
||
var unshift = Array.prototype.unshift;
|
||
|
||
var argCount = DecoratorClass.prototype.constructor.length;
|
||
|
||
var calledConstructor = SuperClass.prototype.constructor;
|
||
|
||
if (argCount > 0) {
|
||
unshift.call(arguments, SuperClass.prototype.constructor);
|
||
|
||
calledConstructor = DecoratorClass.prototype.constructor;
|
||
}
|
||
|
||
calledConstructor.apply(this, arguments);
|
||
}
|
||
|
||
DecoratorClass.displayName = SuperClass.displayName;
|
||
|
||
function ctr () {
|
||
this.constructor = DecoratedClass;
|
||
}
|
||
|
||
DecoratedClass.prototype = new ctr();
|
||
|
||
for (var m = 0; m < superMethods.length; m++) {
|
||
var superMethod = superMethods[m];
|
||
|
||
DecoratedClass.prototype[superMethod] =
|
||
SuperClass.prototype[superMethod];
|
||
}
|
||
|
||
var calledMethod = function (methodName) {
|
||
// Stub out the original method if it's not decorating an actual method
|
||
var originalMethod = function () {};
|
||
|
||
if (methodName in DecoratedClass.prototype) {
|
||
originalMethod = DecoratedClass.prototype[methodName];
|
||
}
|
||
|
||
var decoratedMethod = DecoratorClass.prototype[methodName];
|
||
|
||
return function () {
|
||
var unshift = Array.prototype.unshift;
|
||
|
||
unshift.call(arguments, originalMethod);
|
||
|
||
return decoratedMethod.apply(this, arguments);
|
||
};
|
||
};
|
||
|
||
for (var d = 0; d < decoratedMethods.length; d++) {
|
||
var decoratedMethod = decoratedMethods[d];
|
||
|
||
DecoratedClass.prototype[decoratedMethod] = calledMethod(decoratedMethod);
|
||
}
|
||
|
||
return DecoratedClass;
|
||
};
|
||
|
||
var Observable = function () {
|
||
this.listeners = {};
|
||
};
|
||
|
||
Observable.prototype.on = function (event, callback) {
|
||
this.listeners = this.listeners || {};
|
||
|
||
if (event in this.listeners) {
|
||
this.listeners[event].push(callback);
|
||
} else {
|
||
this.listeners[event] = [callback];
|
||
}
|
||
};
|
||
|
||
Observable.prototype.trigger = function (event) {
|
||
var slice = Array.prototype.slice;
|
||
var params = slice.call(arguments, 1);
|
||
|
||
this.listeners = this.listeners || {};
|
||
|
||
// Params should always come in as an array
|
||
if (params == null) {
|
||
params = [];
|
||
}
|
||
|
||
// If there are no arguments to the event, use a temporary object
|
||
if (params.length === 0) {
|
||
params.push({});
|
||
}
|
||
|
||
// Set the `_type` of the first object to the event
|
||
params[0]._type = event;
|
||
|
||
if (event in this.listeners) {
|
||
this.invoke(this.listeners[event], slice.call(arguments, 1));
|
||
}
|
||
|
||
if ('*' in this.listeners) {
|
||
this.invoke(this.listeners['*'], arguments);
|
||
}
|
||
};
|
||
|
||
Observable.prototype.invoke = function (listeners, params) {
|
||
for (var i = 0, len = listeners.length; i < len; i++) {
|
||
listeners[i].apply(this, params);
|
||
}
|
||
};
|
||
|
||
Utils.Observable = Observable;
|
||
|
||
Utils.generateChars = function (length) {
|
||
var chars = '';
|
||
|
||
for (var i = 0; i < length; i++) {
|
||
var randomChar = Math.floor(Math.random() * 36);
|
||
chars += randomChar.toString(36);
|
||
}
|
||
|
||
return chars;
|
||
};
|
||
|
||
Utils.bind = function (func, context) {
|
||
return function () {
|
||
func.apply(context, arguments);
|
||
};
|
||
};
|
||
|
||
Utils._convertData = function (data) {
|
||
for (var originalKey in data) {
|
||
var keys = originalKey.split('-');
|
||
|
||
var dataLevel = data;
|
||
|
||
if (keys.length === 1) {
|
||
continue;
|
||
}
|
||
|
||
for (var k = 0; k < keys.length; k++) {
|
||
var key = keys[k];
|
||
|
||
// Lowercase the first letter
|
||
// By default, dash-separated becomes camelCase
|
||
key = key.substring(0, 1).toLowerCase() + key.substring(1);
|
||
|
||
if (!(key in dataLevel)) {
|
||
dataLevel[key] = {};
|
||
}
|
||
|
||
if (k == keys.length - 1) {
|
||
dataLevel[key] = data[originalKey];
|
||
}
|
||
|
||
dataLevel = dataLevel[key];
|
||
}
|
||
|
||
delete data[originalKey];
|
||
}
|
||
|
||
return data;
|
||
};
|
||
|
||
Utils.hasScroll = function (index, el) {
|
||
// Adapted from the function created by @ShadowScripter
|
||
// and adapted by @BillBarry on the Stack Exchange Code Review website.
|
||
// The original code can be found at
|
||
// http://codereview.stackexchange.com/q/13338
|
||
// and was designed to be used with the Sizzle selector engine.
|
||
|
||
var $el = $(el);
|
||
var overflowX = el.style.overflowX;
|
||
var overflowY = el.style.overflowY;
|
||
|
||
//Check both x and y declarations
|
||
if (overflowX === overflowY &&
|
||
(overflowY === 'hidden' || overflowY === 'visible')) {
|
||
return false;
|
||
}
|
||
|
||
if (overflowX === 'scroll' || overflowY === 'scroll') {
|
||
return true;
|
||
}
|
||
|
||
return ($el.innerHeight() < el.scrollHeight ||
|
||
$el.innerWidth() < el.scrollWidth);
|
||
};
|
||
|
||
Utils.escapeMarkup = function (markup) {
|
||
var replaceMap = {
|
||
'\\': '\',
|
||
'&': '&',
|
||
'<': '<',
|
||
'>': '>',
|
||
'"': '"',
|
||
'\'': ''',
|
||
'/': '/'
|
||
};
|
||
|
||
// Do not try to escape the markup if it's not a string
|
||
if (typeof markup !== 'string') {
|
||
return markup;
|
||
}
|
||
|
||
return String(markup).replace(/[&<>"'\/\\]/g, function (match) {
|
||
return replaceMap[match];
|
||
});
|
||
};
|
||
|
||
// Append an array of jQuery nodes to a given element.
|
||
Utils.appendMany = function ($element, $nodes) {
|
||
// jQuery 1.7.x does not support $.fn.append() with an array
|
||
// Fall back to a jQuery object collection using $.fn.add()
|
||
if ($.fn.jquery.substr(0, 3) === '1.7') {
|
||
var $jqNodes = $();
|
||
|
||
$.map($nodes, function (node) {
|
||
$jqNodes = $jqNodes.add(node);
|
||
});
|
||
|
||
$nodes = $jqNodes;
|
||
}
|
||
|
||
$element.append($nodes);
|
||
};
|
||
|
||
return Utils;
|
||
});
|
||
|
||
S2.define('select2/results',[
|
||
'jquery',
|
||
'./utils'
|
||
], function ($, Utils) {
|
||
function Results ($element, options, dataAdapter) {
|
||
this.$element = $element;
|
||
this.data = dataAdapter;
|
||
this.options = options;
|
||
|
||
Results.__super__.constructor.call(this);
|
||
}
|
||
|
||
Utils.Extend(Results, Utils.Observable);
|
||
|
||
Results.prototype.render = function () {
|
||
var $results = $(
|
||
'<ul class="select2-results__options" role="tree"></ul>'
|
||
);
|
||
|
||
if (this.options.get('multiple')) {
|
||
$results.attr('aria-multiselectable', 'true');
|
||
}
|
||
|
||
this.$results = $results;
|
||
|
||
return $results;
|
||
};
|
||
|
||
Results.prototype.clear = function () {
|
||
this.$results.empty();
|
||
};
|
||
|
||
Results.prototype.displayMessage = function (params) {
|
||
var escapeMarkup = this.options.get('escapeMarkup');
|
||
|
||
this.clear();
|
||
this.hideLoading();
|
||
|
||
var $message = $(
|
||
'<li role="treeitem" aria-live="assertive"' +
|
||
' class="select2-results__option"></li>'
|
||
);
|
||
|
||
var message = this.options.get('translations').get(params.message);
|
||
|
||
$message.append(
|
||
escapeMarkup(
|
||
message(params.args)
|
||
)
|
||
);
|
||
|
||
$message[0].className += ' select2-results__message';
|
||
|
||
this.$results.append($message);
|
||
};
|
||
|
||
Results.prototype.hideMessages = function () {
|
||
this.$results.find('.select2-results__message').remove();
|
||
};
|
||
|
||
Results.prototype.append = function (data) {
|
||
this.hideLoading();
|
||
|
||
var $options = [];
|
||
|
||
if (data.results == null || data.results.length === 0) {
|
||
if (this.$results.children().length === 0) {
|
||
this.trigger('results:message', {
|
||
message: 'noResults'
|
||
});
|
||
}
|
||
|
||
return;
|
||
}
|
||
|
||
data.results = this.sort(data.results);
|
||
|
||
for (var d = 0; d < data.results.length; d++) {
|
||
var item = data.results[d];
|
||
|
||
var $option = this.option(item);
|
||
|
||
$options.push($option);
|
||
}
|
||
|
||
this.$results.append($options);
|
||
};
|
||
|
||
Results.prototype.position = function ($results, $dropdown) {
|
||
var $resultsContainer = $dropdown.find('.select2-results');
|
||
$resultsContainer.append($results);
|
||
};
|
||
|
||
Results.prototype.sort = function (data) {
|
||
var sorter = this.options.get('sorter');
|
||
|
||
return sorter(data);
|
||
};
|
||
|
||
Results.prototype.highlightFirstItem = function () {
|
||
var $options = this.$results
|
||
.find('.select2-results__option[aria-selected]');
|
||
|
||
var $selected = $options.filter('[aria-selected=true]');
|
||
|
||
// Check if there are any selected options
|
||
if ($selected.length > 0) {
|
||
// If there are selected options, highlight the first
|
||
$selected.first().trigger('mouseenter');
|
||
} else {
|
||
// If there are no selected options, highlight the first option
|
||
// in the dropdown
|
||
$options.first().trigger('mouseenter');
|
||
}
|
||
|
||
this.ensureHighlightVisible();
|
||
};
|
||
|
||
Results.prototype.setClasses = function () {
|
||
var self = this;
|
||
|
||
this.data.current(function (selected) {
|
||
var selectedIds = $.map(selected, function (s) {
|
||
return s.id.toString();
|
||
});
|
||
|
||
var $options = self.$results
|
||
.find('.select2-results__option[aria-selected]');
|
||
|
||
$options.each(function () {
|
||
var $option = $(this);
|
||
|
||
var item = $.data(this, 'data');
|
||
|
||
// id needs to be converted to a string when comparing
|
||
var id = '' + item.id;
|
||
|
||
if ((item.element != null && item.element.selected) ||
|
||
(item.element == null && $.inArray(id, selectedIds) > -1)) {
|
||
$option.attr('aria-selected', 'true');
|
||
} else {
|
||
$option.attr('aria-selected', 'false');
|
||
}
|
||
});
|
||
|
||
});
|
||
};
|
||
|
||
Results.prototype.showLoading = function (params) {
|
||
this.hideLoading();
|
||
|
||
var loadingMore = this.options.get('translations').get('searching');
|
||
|
||
var loading = {
|
||
disabled: true,
|
||
loading: true,
|
||
text: loadingMore(params)
|
||
};
|
||
var $loading = this.option(loading);
|
||
$loading.className += ' loading-results';
|
||
|
||
this.$results.prepend($loading);
|
||
};
|
||
|
||
Results.prototype.hideLoading = function () {
|
||
this.$results.find('.loading-results').remove();
|
||
};
|
||
|
||
Results.prototype.option = function (data) {
|
||
var option = document.createElement('li');
|
||
option.className = 'select2-results__option';
|
||
|
||
var attrs = {
|
||
'role': 'treeitem',
|
||
'aria-selected': 'false'
|
||
};
|
||
|
||
if (data.disabled) {
|
||
delete attrs['aria-selected'];
|
||
attrs['aria-disabled'] = 'true';
|
||
}
|
||
|
||
if (data.id == null) {
|
||
delete attrs['aria-selected'];
|
||
}
|
||
|
||
if (data._resultId != null) {
|
||
option.id = data._resultId;
|
||
}
|
||
|
||
if (data.title) {
|
||
option.title = data.title;
|
||
}
|
||
|
||
if (data.children) {
|
||
attrs.role = 'group';
|
||
attrs['aria-label'] = data.text;
|
||
delete attrs['aria-selected'];
|
||
}
|
||
|
||
for (var attr in attrs) {
|
||
var val = attrs[attr];
|
||
|
||
option.setAttribute(attr, val);
|
||
}
|
||
|
||
if (data.children) {
|
||
var $option = $(option);
|
||
|
||
var label = document.createElement('strong');
|
||
label.className = 'select2-results__group';
|
||
|
||
var $label = $(label);
|
||
this.template(data, label);
|
||
|
||
var $children = [];
|
||
|
||
for (var c = 0; c < data.children.length; c++) {
|
||
var child = data.children[c];
|
||
|
||
var $child = this.option(child);
|
||
|
||
$children.push($child);
|
||
}
|
||
|
||
var $childrenContainer = $('<ul></ul>', {
|
||
'class': 'select2-results__options select2-results__options--nested'
|
||
});
|
||
|
||
$childrenContainer.append($children);
|
||
|
||
$option.append(label);
|
||
$option.append($childrenContainer);
|
||
} else {
|
||
this.template(data, option);
|
||
}
|
||
|
||
$.data(option, 'data', data);
|
||
|
||
return option;
|
||
};
|
||
|
||
Results.prototype.bind = function (container, $container) {
|
||
var self = this;
|
||
|
||
var id = container.id + '-results';
|
||
|
||
this.$results.attr('id', id);
|
||
|
||
container.on('results:all', function (params) {
|
||
self.clear();
|
||
self.append(params.data);
|
||
|
||
if (container.isOpen()) {
|
||
self.setClasses();
|
||
self.highlightFirstItem();
|
||
}
|
||
});
|
||
|
||
container.on('results:append', function (params) {
|
||
self.append(params.data);
|
||
|
||
if (container.isOpen()) {
|
||
self.setClasses();
|
||
}
|
||
});
|
||
|
||
container.on('query', function (params) {
|
||
self.hideMessages();
|
||
self.showLoading(params);
|
||
});
|
||
|
||
container.on('select', function () {
|
||
if (!container.isOpen()) {
|
||
return;
|
||
}
|
||
|
||
self.setClasses();
|
||
self.highlightFirstItem();
|
||
});
|
||
|
||
container.on('unselect', function () {
|
||
if (!container.isOpen()) {
|
||
return;
|
||
}
|
||
|
||
self.setClasses();
|
||
self.highlightFirstItem();
|
||
});
|
||
|
||
container.on('open', function () {
|
||
// When the dropdown is open, aria-expended="true"
|
||
self.$results.attr('aria-expanded', 'true');
|
||
self.$results.attr('aria-hidden', 'false');
|
||
|
||
self.setClasses();
|
||
self.ensureHighlightVisible();
|
||
});
|
||
|
||
container.on('close', function () {
|
||
// When the dropdown is closed, aria-expended="false"
|
||
self.$results.attr('aria-expanded', 'false');
|
||
self.$results.attr('aria-hidden', 'true');
|
||
self.$results.removeAttr('aria-activedescendant');
|
||
});
|
||
|
||
container.on('results:toggle', function () {
|
||
var $highlighted = self.getHighlightedResults();
|
||
|
||
if ($highlighted.length === 0) {
|
||
return;
|
||
}
|
||
|
||
$highlighted.trigger('mouseup');
|
||
});
|
||
|
||
container.on('results:select', function () {
|
||
var $highlighted = self.getHighlightedResults();
|
||
|
||
if ($highlighted.length === 0) {
|
||
return;
|
||
}
|
||
|
||
var data = $highlighted.data('data');
|
||
|
||
if ($highlighted.attr('aria-selected') == 'true') {
|
||
self.trigger('close', {});
|
||
} else {
|
||
self.trigger('select', {
|
||
data: data
|
||
});
|
||
}
|
||
});
|
||
|
||
container.on('results:previous', function () {
|
||
var $highlighted = self.getHighlightedResults();
|
||
|
||
var $options = self.$results.find('[aria-selected]');
|
||
|
||
var currentIndex = $options.index($highlighted);
|
||
|
||
// If we are already at te top, don't move further
|
||
if (currentIndex === 0) {
|
||
return;
|
||
}
|
||
|
||
var nextIndex = currentIndex - 1;
|
||
|
||
// If none are highlighted, highlight the first
|
||
if ($highlighted.length === 0) {
|
||
nextIndex = 0;
|
||
}
|
||
|
||
var $next = $options.eq(nextIndex);
|
||
|
||
$next.trigger('mouseenter');
|
||
|
||
var currentOffset = self.$results.offset().top;
|
||
var nextTop = $next.offset().top;
|
||
var nextOffset = self.$results.scrollTop() + (nextTop - currentOffset);
|
||
|
||
if (nextIndex === 0) {
|
||
self.$results.scrollTop(0);
|
||
} else if (nextTop - currentOffset < 0) {
|
||
self.$results.scrollTop(nextOffset);
|
||
}
|
||
});
|
||
|
||
container.on('results:next', function () {
|
||
var $highlighted = self.getHighlightedResults();
|
||
|
||
var $options = self.$results.find('[aria-selected]');
|
||
|
||
var currentIndex = $options.index($highlighted);
|
||
|
||
var nextIndex = currentIndex + 1;
|
||
|
||
// If we are at the last option, stay there
|
||
if (nextIndex >= $options.length) {
|
||
return;
|
||
}
|
||
|
||
var $next = $options.eq(nextIndex);
|
||
|
||
$next.trigger('mouseenter');
|
||
|
||
var currentOffset = self.$results.offset().top +
|
||
self.$results.outerHeight(false);
|
||
var nextBottom = $next.offset().top + $next.outerHeight(false);
|
||
var nextOffset = self.$results.scrollTop() + nextBottom - currentOffset;
|
||
|
||
if (nextIndex === 0) {
|
||
self.$results.scrollTop(0);
|
||
} else if (nextBottom > currentOffset) {
|
||
self.$results.scrollTop(nextOffset);
|
||
}
|
||
});
|
||
|
||
container.on('results:focus', function (params) {
|
||
params.element.addClass('select2-results__option--highlighted');
|
||
});
|
||
|
||
container.on('results:message', function (params) {
|
||
self.displayMessage(params);
|
||
});
|
||
|
||
if ($.fn.mousewheel) {
|
||
this.$results.on('mousewheel', function (e) {
|
||
var top = self.$results.scrollTop();
|
||
|
||
var bottom = self.$results.get(0).scrollHeight - top + e.deltaY;
|
||
|
||
var isAtTop = e.deltaY > 0 && top - e.deltaY <= 0;
|
||
var isAtBottom = e.deltaY < 0 && bottom <= self.$results.height();
|
||
|
||
if (isAtTop) {
|
||
self.$results.scrollTop(0);
|
||
|
||
e.preventDefault();
|
||
e.stopPropagation();
|
||
} else if (isAtBottom) {
|
||
self.$results.scrollTop(
|
||
self.$results.get(0).scrollHeight - self.$results.height()
|
||
);
|
||
|
||
e.preventDefault();
|
||
e.stopPropagation();
|
||
}
|
||
});
|
||
}
|
||
|
||
this.$results.on('mouseup', '.select2-results__option[aria-selected]',
|
||
function (evt) {
|
||
var $this = $(this);
|
||
|
||
var data = $this.data('data');
|
||
|
||
if ($this.attr('aria-selected') === 'true') {
|
||
if (self.options.get('multiple')) {
|
||
self.trigger('unselect', {
|
||
originalEvent: evt,
|
||
data: data
|
||
});
|
||
} else {
|
||
self.trigger('close', {});
|
||
}
|
||
|
||
return;
|
||
}
|
||
|
||
self.trigger('select', {
|
||
originalEvent: evt,
|
||
data: data
|
||
});
|
||
});
|
||
|
||
this.$results.on('mouseenter', '.select2-results__option[aria-selected]',
|
||
function (evt) {
|
||
var data = $(this).data('data');
|
||
|
||
self.getHighlightedResults()
|
||
.removeClass('select2-results__option--highlighted');
|
||
|
||
self.trigger('results:focus', {
|
||
data: data,
|
||
element: $(this)
|
||
});
|
||
});
|
||
};
|
||
|
||
Results.prototype.getHighlightedResults = function () {
|
||
var $highlighted = this.$results
|
||
.find('.select2-results__option--highlighted');
|
||
|
||
return $highlighted;
|
||
};
|
||
|
||
Results.prototype.destroy = function () {
|
||
this.$results.remove();
|
||
};
|
||
|
||
Results.prototype.ensureHighlightVisible = function () {
|
||
var $highlighted = this.getHighlightedResults();
|
||
|
||
if ($highlighted.length === 0) {
|
||
return;
|
||
}
|
||
|
||
var $options = this.$results.find('[aria-selected]');
|
||
|
||
var currentIndex = $options.index($highlighted);
|
||
|
||
var currentOffset = this.$results.offset().top;
|
||
var nextTop = $highlighted.offset().top;
|
||
var nextOffset = this.$results.scrollTop() + (nextTop - currentOffset);
|
||
|
||
var offsetDelta = nextTop - currentOffset;
|
||
nextOffset -= $highlighted.outerHeight(false) * 2;
|
||
|
||
if (currentIndex <= 2) {
|
||
this.$results.scrollTop(0);
|
||
} else if (offsetDelta > this.$results.outerHeight() || offsetDelta < 0) {
|
||
this.$results.scrollTop(nextOffset);
|
||
}
|
||
};
|
||
|
||
Results.prototype.template = function (result, container) {
|
||
var template = this.options.get('templateResult');
|
||
var escapeMarkup = this.options.get('escapeMarkup');
|
||
|
||
var content = template(result, container);
|
||
|
||
if (content == null) {
|
||
container.style.display = 'none';
|
||
} else if (typeof content === 'string') {
|
||
container.innerHTML = escapeMarkup(content);
|
||
} else {
|
||
$(container).append(content);
|
||
}
|
||
};
|
||
|
||
return Results;
|
||
});
|
||
|
||
S2.define('select2/keys',[
|
||
|
||
], function () {
|
||
var KEYS = {
|
||
BACKSPACE: 8,
|
||
TAB: 9,
|
||
ENTER: 13,
|
||
SHIFT: 16,
|
||
CTRL: 17,
|
||
ALT: 18,
|
||
ESC: 27,
|
||
SPACE: 32,
|
||
PAGE_UP: 33,
|
||
PAGE_DOWN: 34,
|
||
END: 35,
|
||
HOME: 36,
|
||
LEFT: 37,
|
||
UP: 38,
|
||
RIGHT: 39,
|
||
DOWN: 40,
|
||
DELETE: 46
|
||
};
|
||
|
||
return KEYS;
|
||
});
|
||
|
||
S2.define('select2/selection/base',[
|
||
'jquery',
|
||
'../utils',
|
||
'../keys'
|
||
], function ($, Utils, KEYS) {
|
||
function BaseSelection ($element, options) {
|
||
this.$element = $element;
|
||
this.options = options;
|
||
|
||
BaseSelection.__super__.constructor.call(this);
|
||
}
|
||
|
||
Utils.Extend(BaseSelection, Utils.Observable);
|
||
|
||
BaseSelection.prototype.render = function () {
|
||
var $selection = $(
|
||
'<span class="select2-selection" role="combobox" ' +
|
||
' aria-haspopup="true" aria-expanded="false">' +
|
||
'</span>'
|
||
);
|
||
|
||
this._tabindex = 0;
|
||
|
||
if (this.$element.data('old-tabindex') != null) {
|
||
this._tabindex = this.$element.data('old-tabindex');
|
||
} else if (this.$element.attr('tabindex') != null) {
|
||
this._tabindex = this.$element.attr('tabindex');
|
||
}
|
||
|
||
$selection.attr('title', this.$element.attr('title'));
|
||
$selection.attr('tabindex', this._tabindex);
|
||
|
||
this.$selection = $selection;
|
||
|
||
return $selection;
|
||
};
|
||
|
||
BaseSelection.prototype.bind = function (container, $container) {
|
||
var self = this;
|
||
|
||
var id = container.id + '-container';
|
||
var resultsId = container.id + '-results';
|
||
|
||
this.container = container;
|
||
|
||
this.$selection.on('focus', function (evt) {
|
||
self.trigger('focus', evt);
|
||
});
|
||
|
||
this.$selection.on('blur', function (evt) {
|
||
self._handleBlur(evt);
|
||
});
|
||
|
||
this.$selection.on('keydown', function (evt) {
|
||
self.trigger('keypress', evt);
|
||
|
||
if (evt.which === KEYS.SPACE) {
|
||
evt.preventDefault();
|
||
}
|
||
});
|
||
|
||
container.on('results:focus', function (params) {
|
||
self.$selection.attr('aria-activedescendant', params.data._resultId);
|
||
});
|
||
|
||
container.on('selection:update', function (params) {
|
||
self.update(params.data);
|
||
});
|
||
|
||
container.on('open', function () {
|
||
// When the dropdown is open, aria-expanded="true"
|
||
self.$selection.attr('aria-expanded', 'true');
|
||
self.$selection.attr('aria-owns', resultsId);
|
||
|
||
self._attachCloseHandler(container);
|
||
});
|
||
|
||
container.on('close', function () {
|
||
// When the dropdown is closed, aria-expanded="false"
|
||
self.$selection.attr('aria-expanded', 'false');
|
||
self.$selection.removeAttr('aria-activedescendant');
|
||
self.$selection.removeAttr('aria-owns');
|
||
|
||
self.$selection.focus();
|
||
|
||
self._detachCloseHandler(container);
|
||
});
|
||
|
||
container.on('enable', function () {
|
||
self.$selection.attr('tabindex', self._tabindex);
|
||
});
|
||
|
||
container.on('disable', function () {
|
||
self.$selection.attr('tabindex', '-1');
|
||
});
|
||
};
|
||
|
||
BaseSelection.prototype._handleBlur = function (evt) {
|
||
var self = this;
|
||
|
||
// This needs to be delayed as the active element is the body when the tab
|
||
// key is pressed, possibly along with others.
|
||
window.setTimeout(function () {
|
||
// Don't trigger `blur` if the focus is still in the selection
|
||
if (
|
||
(document.activeElement == self.$selection[0]) ||
|
||
($.contains(self.$selection[0], document.activeElement))
|
||
) {
|
||
return;
|
||
}
|
||
|
||
self.trigger('blur', evt);
|
||
}, 1);
|
||
};
|
||
|
||
BaseSelection.prototype._attachCloseHandler = function (container) {
|
||
var self = this;
|
||
|
||
$(document.body).on('mousedown.select2.' + container.id, function (e) {
|
||
var $target = $(e.target);
|
||
|
||
var $select = $target.closest('.select2');
|
||
|
||
var $all = $('.select2.select2-container--open');
|
||
|
||
$all.each(function () {
|
||
var $this = $(this);
|
||
|
||
if (this == $select[0]) {
|
||
return;
|
||
}
|
||
|
||
var $element = $this.data('element');
|
||
|
||
$element.select2('close');
|
||
});
|
||
});
|
||
};
|
||
|
||
BaseSelection.prototype._detachCloseHandler = function (container) {
|
||
$(document.body).off('mousedown.select2.' + container.id);
|
||
};
|
||
|
||
BaseSelection.prototype.position = function ($selection, $container) {
|
||
var $selectionContainer = $container.find('.selection');
|
||
$selectionContainer.append($selection);
|
||
};
|
||
|
||
BaseSelection.prototype.destroy = function () {
|
||
this._detachCloseHandler(this.container);
|
||
};
|
||
|
||
BaseSelection.prototype.update = function (data) {
|
||
throw new Error('The `update` method must be defined in child classes.');
|
||
};
|
||
|
||
return BaseSelection;
|
||
});
|
||
|
||
S2.define('select2/selection/single',[
|
||
'jquery',
|
||
'./base',
|
||
'../utils',
|
||
'../keys'
|
||
], function ($, BaseSelection, Utils, KEYS) {
|
||
function SingleSelection () {
|
||
SingleSelection.__super__.constructor.apply(this, arguments);
|
||
}
|
||
|
||
Utils.Extend(SingleSelection, BaseSelection);
|
||
|
||
SingleSelection.prototype.render = function () {
|
||
var $selection = SingleSelection.__super__.render.call(this);
|
||
|
||
$selection.addClass('select2-selection--single');
|
||
|
||
$selection.html(
|
||
'<span class="select2-selection__rendered"></span>' +
|
||
'<span class="select2-selection__arrow" role="presentation">' +
|
||
'<b role="presentation"></b>' +
|
||
'</span>'
|
||
);
|
||
|
||
return $selection;
|
||
};
|
||
|
||
SingleSelection.prototype.bind = function (container, $container) {
|
||
var self = this;
|
||
|
||
SingleSelection.__super__.bind.apply(this, arguments);
|
||
|
||
var id = container.id + '-container';
|
||
|
||
this.$selection.find('.select2-selection__rendered').attr('id', id);
|
||
this.$selection.attr('aria-labelledby', id);
|
||
|
||
this.$selection.on('mousedown', function (evt) {
|
||
// Only respond to left clicks
|
||
if (evt.which !== 1) {
|
||
return;
|
||
}
|
||
|
||
self.trigger('toggle', {
|
||
originalEvent: evt
|
||
});
|
||
});
|
||
|
||
this.$selection.on('focus', function (evt) {
|
||
// User focuses on the container
|
||
});
|
||
|
||
this.$selection.on('blur', function (evt) {
|
||
// User exits the container
|
||
});
|
||
|
||
container.on('focus', function (evt) {
|
||
if (!container.isOpen()) {
|
||
self.$selection.focus();
|
||
}
|
||
});
|
||
|
||
container.on('selection:update', function (params) {
|
||
self.update(params.data);
|
||
});
|
||
};
|
||
|
||
SingleSelection.prototype.clear = function () {
|
||
this.$selection.find('.select2-selection__rendered').empty();
|
||
};
|
||
|
||
SingleSelection.prototype.display = function (data, container) {
|
||
var template = this.options.get('templateSelection');
|
||
var escapeMarkup = this.options.get('escapeMarkup');
|
||
|
||
return escapeMarkup(template(data, container));
|
||
};
|
||
|
||
SingleSelection.prototype.selectionContainer = function () {
|
||
return $('<span></span>');
|
||
};
|
||
|
||
SingleSelection.prototype.update = function (data) {
|
||
if (data.length === 0) {
|
||
this.clear();
|
||
return;
|
||
}
|
||
|
||
var selection = data[0];
|
||
|
||
var $rendered = this.$selection.find('.select2-selection__rendered');
|
||
var formatted = this.display(selection, $rendered);
|
||
|
||
$rendered.empty().append(formatted);
|
||
$rendered.prop('title', selection.title || selection.text);
|
||
};
|
||
|
||
return SingleSelection;
|
||
});
|
||
|
||
S2.define('select2/selection/multiple',[
|
||
'jquery',
|
||
'./base',
|
||
'../utils'
|
||
], function ($, BaseSelection, Utils) {
|
||
function MultipleSelection ($element, options) {
|
||
MultipleSelection.__super__.constructor.apply(this, arguments);
|
||
}
|
||
|
||
Utils.Extend(MultipleSelection, BaseSelection);
|
||
|
||
MultipleSelection.prototype.render = function () {
|
||
var $selection = MultipleSelection.__super__.render.call(this);
|
||
|
||
$selection.addClass('select2-selection--multiple');
|
||
|
||
$selection.html(
|
||
'<ul class="select2-selection__rendered"></ul>'
|
||
);
|
||
|
||
return $selection;
|
||
};
|
||
|
||
MultipleSelection.prototype.bind = function (container, $container) {
|
||
var self = this;
|
||
|
||
MultipleSelection.__super__.bind.apply(this, arguments);
|
||
|
||
this.$selection.on('click', function (evt) {
|
||
self.trigger('toggle', {
|
||
originalEvent: evt
|
||
});
|
||
});
|
||
|
||
this.$selection.on(
|
||
'click',
|
||
'.select2-selection__choice__remove',
|
||
function (evt) {
|
||
// Ignore the event if it is disabled
|
||
if (self.options.get('disabled')) {
|
||
return;
|
||
}
|
||
|
||
var $remove = $(this);
|
||
var $selection = $remove.parent();
|
||
|
||
var data = $selection.data('data');
|
||
|
||
self.trigger('unselect', {
|
||
originalEvent: evt,
|
||
data: data
|
||
});
|
||
}
|
||
);
|
||
};
|
||
|
||
MultipleSelection.prototype.clear = function () {
|
||
this.$selection.find('.select2-selection__rendered').empty();
|
||
};
|
||
|
||
MultipleSelection.prototype.display = function (data, container) {
|
||
var template = this.options.get('templateSelection');
|
||
var escapeMarkup = this.options.get('escapeMarkup');
|
||
|
||
return escapeMarkup(template(data, container));
|
||
};
|
||
|
||
MultipleSelection.prototype.selectionContainer = function () {
|
||
var $container = $(
|
||
'<li class="select2-selection__choice">' +
|
||
'<span class="select2-selection__choice__remove" role="presentation">' +
|
||
'×' +
|
||
'</span>' +
|
||
'</li>'
|
||
);
|
||
|
||
return $container;
|
||
};
|
||
|
||
MultipleSelection.prototype.update = function (data) {
|
||
this.clear();
|
||
|
||
if (data.length === 0) {
|
||
return;
|
||
}
|
||
|
||
var $selections = [];
|
||
|
||
for (var d = 0; d < data.length; d++) {
|
||
var selection = data[d];
|
||
|
||
var $selection = this.selectionContainer();
|
||
var formatted = this.display(selection, $selection);
|
||
|
||
$selection.append(formatted);
|
||
$selection.prop('title', selection.title || selection.text);
|
||
|
||
$selection.data('data', selection);
|
||
|
||
$selections.push($selection);
|
||
}
|
||
|
||
var $rendered = this.$selection.find('.select2-selection__rendered');
|
||
|
||
Utils.appendMany($rendered, $selections);
|
||
};
|
||
|
||
return MultipleSelection;
|
||
});
|
||
|
||
S2.define('select2/selection/placeholder',[
|
||
'../utils'
|
||
], function (Utils) {
|
||
function Placeholder (decorated, $element, options) {
|
||
this.placeholder = this.normalizePlaceholder(options.get('placeholder'));
|
||
|
||
decorated.call(this, $element, options);
|
||
}
|
||
|
||
Placeholder.prototype.normalizePlaceholder = function (_, placeholder) {
|
||
if (typeof placeholder === 'string') {
|
||
placeholder = {
|
||
id: '',
|
||
text: placeholder
|
||
};
|
||
}
|
||
|
||
return placeholder;
|
||
};
|
||
|
||
Placeholder.prototype.createPlaceholder = function (decorated, placeholder) {
|
||
var $placeholder = this.selectionContainer();
|
||
|
||
$placeholder.html(this.display(placeholder));
|
||
$placeholder.addClass('select2-selection__placeholder')
|
||
.removeClass('select2-selection__choice');
|
||
|
||
return $placeholder;
|
||
};
|
||
|
||
Placeholder.prototype.update = function (decorated, data) {
|
||
var singlePlaceholder = (
|
||
data.length == 1 && data[0].id != this.placeholder.id
|
||
);
|
||
var multipleSelections = data.length > 1;
|
||
|
||
if (multipleSelections || singlePlaceholder) {
|
||
return decorated.call(this, data);
|
||
}
|
||
|
||
this.clear();
|
||
|
||
var $placeholder = this.createPlaceholder(this.placeholder);
|
||
|
||
this.$selection.find('.select2-selection__rendered').append($placeholder);
|
||
};
|
||
|
||
return Placeholder;
|
||
});
|
||
|
||
S2.define('select2/selection/allowClear',[
|
||
'jquery',
|
||
'../keys'
|
||
], function ($, KEYS) {
|
||
function AllowClear () { }
|
||
|
||
AllowClear.prototype.bind = function (decorated, container, $container) {
|
||
var self = this;
|
||
|
||
decorated.call(this, container, $container);
|
||
|
||
if (this.placeholder == null) {
|
||
if (this.options.get('debug') && window.console && console.error) {
|
||
console.error(
|
||
'Select2: The `allowClear` option should be used in combination ' +
|
||
'with the `placeholder` option.'
|
||
);
|
||
}
|
||
}
|
||
|
||
this.$selection.on('mousedown', '.select2-selection__clear',
|
||
function (evt) {
|
||
self._handleClear(evt);
|
||
});
|
||
|
||
container.on('keypress', function (evt) {
|
||
self._handleKeyboardClear(evt, container);
|
||
});
|
||
};
|
||
|
||
AllowClear.prototype._handleClear = function (_, evt) {
|
||
// Ignore the event if it is disabled
|
||
if (this.options.get('disabled')) {
|
||
return;
|
||
}
|
||
|
||
var $clear = this.$selection.find('.select2-selection__clear');
|
||
|
||
// Ignore the event if nothing has been selected
|
||
if ($clear.length === 0) {
|
||
return;
|
||
}
|
||
|
||
evt.stopPropagation();
|
||
|
||
var data = $clear.data('data');
|
||
|
||
for (var d = 0; d < data.length; d++) {
|
||
var unselectData = {
|
||
data: data[d]
|
||
};
|
||
|
||
// Trigger the `unselect` event, so people can prevent it from being
|
||
// cleared.
|
||
this.trigger('unselect', unselectData);
|
||
|
||
// If the event was prevented, don't clear it out.
|
||
if (unselectData.prevented) {
|
||
return;
|
||
}
|
||
}
|
||
|
||
this.$element.val(this.placeholder.id).trigger('change');
|
||
|
||
this.trigger('toggle', {});
|
||
};
|
||
|
||
AllowClear.prototype._handleKeyboardClear = function (_, evt, container) {
|
||
if (container.isOpen()) {
|
||
return;
|
||
}
|
||
|
||
if (evt.which == KEYS.DELETE || evt.which == KEYS.BACKSPACE) {
|
||
this._handleClear(evt);
|
||
}
|
||
};
|
||
|
||
AllowClear.prototype.update = function (decorated, data) {
|
||
decorated.call(this, data);
|
||
|
||
if (this.$selection.find('.select2-selection__placeholder').length > 0 ||
|
||
data.length === 0) {
|
||
return;
|
||
}
|
||
|
||
var $remove = $(
|
||
'<span class="select2-selection__clear">' +
|
||
'×' +
|
||
'</span>'
|
||
);
|
||
$remove.data('data', data);
|
||
|
||
this.$selection.find('.select2-selection__rendered').prepend($remove);
|
||
};
|
||
|
||
return AllowClear;
|
||
});
|
||
|
||
S2.define('select2/selection/search',[
|
||
'jquery',
|
||
'../utils',
|
||
'../keys'
|
||
], function ($, Utils, KEYS) {
|
||
function Search (decorated, $element, options) {
|
||
decorated.call(this, $element, options);
|
||
}
|
||
|
||
Search.prototype.render = function (decorated) {
|
||
var $search = $(
|
||
'<li class="select2-search select2-search--inline">' +
|
||
'<input class="select2-search__field" type="search" tabindex="-1"' +
|
||
' autocomplete="off" autocorrect="off" autocapitalize="off"' +
|
||
' spellcheck="false" role="textbox" aria-autocomplete="list" />' +
|
||
'</li>'
|
||
);
|
||
|
||
this.$searchContainer = $search;
|
||
this.$search = $search.find('input');
|
||
|
||
var $rendered = decorated.call(this);
|
||
|
||
this._transferTabIndex();
|
||
|
||
return $rendered;
|
||
};
|
||
|
||
Search.prototype.bind = function (decorated, container, $container) {
|
||
var self = this;
|
||
|
||
decorated.call(this, container, $container);
|
||
|
||
container.on('open', function () {
|
||
self.$search.trigger('focus');
|
||
});
|
||
|
||
container.on('close', function () {
|
||
self.$search.val('');
|
||
self.$search.removeAttr('aria-activedescendant');
|
||
self.$search.trigger('focus');
|
||
});
|
||
|
||
container.on('enable', function () {
|
||
self.$search.prop('disabled', false);
|
||
|
||
self._transferTabIndex();
|
||
});
|
||
|
||
container.on('disable', function () {
|
||
self.$search.prop('disabled', true);
|
||
});
|
||
|
||
container.on('focus', function (evt) {
|
||
self.$search.trigger('focus');
|
||
});
|
||
|
||
container.on('results:focus', function (params) {
|
||
self.$search.attr('aria-activedescendant', params.id);
|
||
});
|
||
|
||
this.$selection.on('focusin', '.select2-search--inline', function (evt) {
|
||
self.trigger('focus', evt);
|
||
});
|
||
|
||
this.$selection.on('focusout', '.select2-search--inline', function (evt) {
|
||
self._handleBlur(evt);
|
||
});
|
||
|
||
this.$selection.on('keydown', '.select2-search--inline', function (evt) {
|
||
evt.stopPropagation();
|
||
|
||
self.trigger('keypress', evt);
|
||
|
||
self._keyUpPrevented = evt.isDefaultPrevented();
|
||
|
||
var key = evt.which;
|
||
|
||
if (key === KEYS.BACKSPACE && self.$search.val() === '') {
|
||
var $previousChoice = self.$searchContainer
|
||
.prev('.select2-selection__choice');
|
||
|
||
if ($previousChoice.length > 0) {
|
||
var item = $previousChoice.data('data');
|
||
|
||
self.searchRemoveChoice(item);
|
||
|
||
evt.preventDefault();
|
||
}
|
||
}
|
||
});
|
||
|
||
// Try to detect the IE version should the `documentMode` property that
|
||
// is stored on the document. This is only implemented in IE and is
|
||
// slightly cleaner than doing a user agent check.
|
||
// This property is not available in Edge, but Edge also doesn't have
|
||
// this bug.
|
||
var msie = document.documentMode;
|
||
var disableInputEvents = msie && msie <= 11;
|
||
|
||
// Workaround for browsers which do not support the `input` event
|
||
// This will prevent double-triggering of events for browsers which support
|
||
// both the `keyup` and `input` events.
|
||
this.$selection.on(
|
||
'input.searchcheck',
|
||
'.select2-search--inline',
|
||
function (evt) {
|
||
// IE will trigger the `input` event when a placeholder is used on a
|
||
// search box. To get around this issue, we are forced to ignore all
|
||
// `input` events in IE and keep using `keyup`.
|
||
if (disableInputEvents) {
|
||
self.$selection.off('input.search input.searchcheck');
|
||
return;
|
||
}
|
||
|
||
// Unbind the duplicated `keyup` event
|
||
self.$selection.off('keyup.search');
|
||
}
|
||
);
|
||
|
||
this.$selection.on(
|
||
'keyup.search input.search',
|
||
'.select2-search--inline',
|
||
function (evt) {
|
||
// IE will trigger the `input` event when a placeholder is used on a
|
||
// search box. To get around this issue, we are forced to ignore all
|
||
// `input` events in IE and keep using `keyup`.
|
||
if (disableInputEvents && evt.type === 'input') {
|
||
self.$selection.off('input.search input.searchcheck');
|
||
return;
|
||
}
|
||
|
||
var key = evt.which;
|
||
|
||
// We can freely ignore events from modifier keys
|
||
if (key == KEYS.SHIFT || key == KEYS.CTRL || key == KEYS.ALT) {
|
||
return;
|
||
}
|
||
|
||
// Tabbing will be handled during the `keydown` phase
|
||
if (key == KEYS.TAB) {
|
||
return;
|
||
}
|
||
|
||
self.handleSearch(evt);
|
||
}
|
||
);
|
||
};
|
||
|
||
/**
|
||
* This method will transfer the tabindex attribute from the rendered
|
||
* selection to the search box. This allows for the search box to be used as
|
||
* the primary focus instead of the selection container.
|
||
*
|
||
* @private
|
||
*/
|
||
Search.prototype._transferTabIndex = function (decorated) {
|
||
this.$search.attr('tabindex', this.$selection.attr('tabindex'));
|
||
this.$selection.attr('tabindex', '-1');
|
||
};
|
||
|
||
Search.prototype.createPlaceholder = function (decorated, placeholder) {
|
||
this.$search.attr('placeholder', placeholder.text);
|
||
};
|
||
|
||
Search.prototype.update = function (decorated, data) {
|
||
var searchHadFocus = this.$search[0] == document.activeElement;
|
||
|
||
this.$search.attr('placeholder', '');
|
||
|
||
decorated.call(this, data);
|
||
|
||
this.$selection.find('.select2-selection__rendered')
|
||
.append(this.$searchContainer);
|
||
|
||
this.resizeSearch();
|
||
if (searchHadFocus) {
|
||
this.$search.focus();
|
||
}
|
||
};
|
||
|
||
Search.prototype.handleSearch = function () {
|
||
this.resizeSearch();
|
||
|
||
if (!this._keyUpPrevented) {
|
||
var input = this.$search.val();
|
||
|
||
this.trigger('query', {
|
||
term: input
|
||
});
|
||
}
|
||
|
||
this._keyUpPrevented = false;
|
||
};
|
||
|
||
Search.prototype.searchRemoveChoice = function (decorated, item) {
|
||
this.trigger('unselect', {
|
||
data: item
|
||
});
|
||
|
||
this.$search.val(item.text);
|
||
this.handleSearch();
|
||
};
|
||
|
||
Search.prototype.resizeSearch = function () {
|
||
this.$search.css('width', '25px');
|
||
|
||
var width = '';
|
||
|
||
if (this.$search.attr('placeholder') !== '') {
|
||
width = this.$selection.find('.select2-selection__rendered').innerWidth();
|
||
} else {
|
||
var minimumWidth = this.$search.val().length + 1;
|
||
|
||
width = (minimumWidth * 0.75) + 'em';
|
||
}
|
||
|
||
this.$search.css('width', width);
|
||
};
|
||
|
||
return Search;
|
||
});
|
||
|
||
S2.define('select2/selection/eventRelay',[
|
||
'jquery'
|
||
], function ($) {
|
||
function EventRelay () { }
|
||
|
||
EventRelay.prototype.bind = function (decorated, container, $container) {
|
||
var self = this;
|
||
var relayEvents = [
|
||
'open', 'opening',
|
||
'close', 'closing',
|
||
'select', 'selecting',
|
||
'unselect', 'unselecting'
|
||
];
|
||
|
||
var preventableEvents = ['opening', 'closing', 'selecting', 'unselecting'];
|
||
|
||
decorated.call(this, container, $container);
|
||
|
||
container.on('*', function (name, params) {
|
||
// Ignore events that should not be relayed
|
||
if ($.inArray(name, relayEvents) === -1) {
|
||
return;
|
||
}
|
||
|
||
// The parameters should always be an object
|
||
params = params || {};
|
||
|
||
// Generate the jQuery event for the Select2 event
|
||
var evt = $.Event('select2:' + name, {
|
||
params: params
|
||
});
|
||
|
||
self.$element.trigger(evt);
|
||
|
||
// Only handle preventable events if it was one
|
||
if ($.inArray(name, preventableEvents) === -1) {
|
||
return;
|
||
}
|
||
|
||
params.prevented = evt.isDefaultPrevented();
|
||
});
|
||
};
|
||
|
||
return EventRelay;
|
||
});
|
||
|
||
S2.define('select2/translation',[
|
||
'jquery',
|
||
'require'
|
||
], function ($, require) {
|
||
function Translation (dict) {
|
||
this.dict = dict || {};
|
||
}
|
||
|
||
Translation.prototype.all = function () {
|
||
return this.dict;
|
||
};
|
||
|
||
Translation.prototype.get = function (key) {
|
||
return this.dict[key];
|
||
};
|
||
|
||
Translation.prototype.extend = function (translation) {
|
||
this.dict = $.extend({}, translation.all(), this.dict);
|
||
};
|
||
|
||
// Static functions
|
||
|
||
Translation._cache = {};
|
||
|
||
Translation.loadPath = function (path) {
|
||
if (!(path in Translation._cache)) {
|
||
var translations = require(path);
|
||
|
||
Translation._cache[path] = translations;
|
||
}
|
||
|
||
return new Translation(Translation._cache[path]);
|
||
};
|
||
|
||
return Translation;
|
||
});
|
||
|
||
S2.define('select2/diacritics',[
|
||
|
||
], function () {
|
||
var diacritics = {
|
||
'\u24B6': 'A',
|
||
'\uFF21': 'A',
|
||
'\u00C0': 'A',
|
||
'\u00C1': 'A',
|
||
'\u00C2': 'A',
|
||
'\u1EA6': 'A',
|
||
'\u1EA4': 'A',
|
||
'\u1EAA': 'A',
|
||
'\u1EA8': 'A',
|
||
'\u00C3': 'A',
|
||
'\u0100': 'A',
|
||
'\u0102': 'A',
|
||
'\u1EB0': 'A',
|
||
'\u1EAE': 'A',
|
||
'\u1EB4': 'A',
|
||
'\u1EB2': 'A',
|
||
'\u0226': 'A',
|
||
'\u01E0': 'A',
|
||
'\u00C4': 'A',
|
||
'\u01DE': 'A',
|
||
'\u1EA2': 'A',
|
||
'\u00C5': 'A',
|
||
'\u01FA': 'A',
|
||
'\u01CD': 'A',
|
||
'\u0200': 'A',
|
||
'\u0202': 'A',
|
||
'\u1EA0': 'A',
|
||
'\u1EAC': 'A',
|
||
'\u1EB6': 'A',
|
||
'\u1E00': 'A',
|
||
'\u0104': 'A',
|
||
'\u023A': 'A',
|
||
'\u2C6F': 'A',
|
||
'\uA732': 'AA',
|
||
'\u00C6': 'AE',
|
||
'\u01FC': 'AE',
|
||
'\u01E2': 'AE',
|
||
'\uA734': 'AO',
|
||
'\uA736': 'AU',
|
||
'\uA738': 'AV',
|
||
'\uA73A': 'AV',
|
||
'\uA73C': 'AY',
|
||
'\u24B7': 'B',
|
||
'\uFF22': 'B',
|
||
'\u1E02': 'B',
|
||
'\u1E04': 'B',
|
||
'\u1E06': 'B',
|
||
'\u0243': 'B',
|
||
'\u0182': 'B',
|
||
'\u0181': 'B',
|
||
'\u24B8': 'C',
|
||
'\uFF23': 'C',
|
||
'\u0106': 'C',
|
||
'\u0108': 'C',
|
||
'\u010A': 'C',
|
||
'\u010C': 'C',
|
||
'\u00C7': 'C',
|
||
'\u1E08': 'C',
|
||
'\u0187': 'C',
|
||
'\u023B': 'C',
|
||
'\uA73E': 'C',
|
||
'\u24B9': 'D',
|
||
'\uFF24': 'D',
|
||
'\u1E0A': 'D',
|
||
'\u010E': 'D',
|
||
'\u1E0C': 'D',
|
||
'\u1E10': 'D',
|
||
'\u1E12': 'D',
|
||
'\u1E0E': 'D',
|
||
'\u0110': 'D',
|
||
'\u018B': 'D',
|
||
'\u018A': 'D',
|
||
'\u0189': 'D',
|
||
'\uA779': 'D',
|
||
'\u01F1': 'DZ',
|
||
'\u01C4': 'DZ',
|
||
'\u01F2': 'Dz',
|
||
'\u01C5': 'Dz',
|
||
'\u24BA': 'E',
|
||
'\uFF25': 'E',
|
||
'\u00C8': 'E',
|
||
'\u00C9': 'E',
|
||
'\u00CA': 'E',
|
||
'\u1EC0': 'E',
|
||
'\u1EBE': 'E',
|
||
'\u1EC4': 'E',
|
||
'\u1EC2': 'E',
|
||
'\u1EBC': 'E',
|
||
'\u0112': 'E',
|
||
'\u1E14': 'E',
|
||
'\u1E16': 'E',
|
||
'\u0114': 'E',
|
||
'\u0116': 'E',
|
||
'\u00CB': 'E',
|
||
'\u1EBA': 'E',
|
||
'\u011A': 'E',
|
||
'\u0204': 'E',
|
||
'\u0206': 'E',
|
||
'\u1EB8': 'E',
|
||
'\u1EC6': 'E',
|
||
'\u0228': 'E',
|
||
'\u1E1C': 'E',
|
||
'\u0118': 'E',
|
||
'\u1E18': 'E',
|
||
'\u1E1A': 'E',
|
||
'\u0190': 'E',
|
||
'\u018E': 'E',
|
||
'\u24BB': 'F',
|
||
'\uFF26': 'F',
|
||
'\u1E1E': 'F',
|
||
'\u0191': 'F',
|
||
'\uA77B': 'F',
|
||
'\u24BC': 'G',
|
||
'\uFF27': 'G',
|
||
'\u01F4': 'G',
|
||
'\u011C': 'G',
|
||
'\u1E20': 'G',
|
||
'\u011E': 'G',
|
||
'\u0120': 'G',
|
||
'\u01E6': 'G',
|
||
'\u0122': 'G',
|
||
'\u01E4': 'G',
|
||
'\u0193': 'G',
|
||
'\uA7A0': 'G',
|
||
'\uA77D': 'G',
|
||
'\uA77E': 'G',
|
||
'\u24BD': 'H',
|
||
'\uFF28': 'H',
|
||
'\u0124': 'H',
|
||
'\u1E22': 'H',
|
||
'\u1E26': 'H',
|
||
'\u021E': 'H',
|
||
'\u1E24': 'H',
|
||
'\u1E28': 'H',
|
||
'\u1E2A': 'H',
|
||
'\u0126': 'H',
|
||
'\u2C67': 'H',
|
||
'\u2C75': 'H',
|
||
'\uA78D': 'H',
|
||
'\u24BE': 'I',
|
||
'\uFF29': 'I',
|
||
'\u00CC': 'I',
|
||
'\u00CD': 'I',
|
||
'\u00CE': 'I',
|
||
'\u0128': 'I',
|
||
'\u012A': 'I',
|
||
'\u012C': 'I',
|
||
'\u0130': 'I',
|
||
'\u00CF': 'I',
|
||
'\u1E2E': 'I',
|
||
'\u1EC8': 'I',
|
||
'\u01CF': 'I',
|
||
'\u0208': 'I',
|
||
'\u020A': 'I',
|
||
'\u1ECA': 'I',
|
||
'\u012E': 'I',
|
||
'\u1E2C': 'I',
|
||
'\u0197': 'I',
|
||
'\u24BF': 'J',
|
||
'\uFF2A': 'J',
|
||
'\u0134': 'J',
|
||
'\u0248': 'J',
|
||
'\u24C0': 'K',
|
||
'\uFF2B': 'K',
|
||
'\u1E30': 'K',
|
||
'\u01E8': 'K',
|
||
'\u1E32': 'K',
|
||
'\u0136': 'K',
|
||
'\u1E34': 'K',
|
||
'\u0198': 'K',
|
||
'\u2C69': 'K',
|
||
'\uA740': 'K',
|
||
'\uA742': 'K',
|
||
'\uA744': 'K',
|
||
'\uA7A2': 'K',
|
||
'\u24C1': 'L',
|
||
'\uFF2C': 'L',
|
||
'\u013F': 'L',
|
||
'\u0139': 'L',
|
||
'\u013D': 'L',
|
||
'\u1E36': 'L',
|
||
'\u1E38': 'L',
|
||
'\u013B': 'L',
|
||
'\u1E3C': 'L',
|
||
'\u1E3A': 'L',
|
||
'\u0141': 'L',
|
||
'\u023D': 'L',
|
||
'\u2C62': 'L',
|
||
'\u2C60': 'L',
|
||
'\uA748': 'L',
|
||
'\uA746': 'L',
|
||
'\uA780': 'L',
|
||
'\u01C7': 'LJ',
|
||
'\u01C8': 'Lj',
|
||
'\u24C2': 'M',
|
||
'\uFF2D': 'M',
|
||
'\u1E3E': 'M',
|
||
'\u1E40': 'M',
|
||
'\u1E42': 'M',
|
||
'\u2C6E': 'M',
|
||
'\u019C': 'M',
|
||
'\u24C3': 'N',
|
||
'\uFF2E': 'N',
|
||
'\u01F8': 'N',
|
||
'\u0143': 'N',
|
||
'\u00D1': 'N',
|
||
'\u1E44': 'N',
|
||
'\u0147': 'N',
|
||
'\u1E46': 'N',
|
||
'\u0145': 'N',
|
||
'\u1E4A': 'N',
|
||
'\u1E48': 'N',
|
||
'\u0220': 'N',
|
||
'\u019D': 'N',
|
||
'\uA790': 'N',
|
||
'\uA7A4': 'N',
|
||
'\u01CA': 'NJ',
|
||
'\u01CB': 'Nj',
|
||
'\u24C4': 'O',
|
||
'\uFF2F': 'O',
|
||
'\u00D2': 'O',
|
||
'\u00D3': 'O',
|
||
'\u00D4': 'O',
|
||
'\u1ED2': 'O',
|
||
'\u1ED0': 'O',
|
||
'\u1ED6': 'O',
|
||
'\u1ED4': 'O',
|
||
'\u00D5': 'O',
|
||
'\u1E4C': 'O',
|
||
'\u022C': 'O',
|
||
'\u1E4E': 'O',
|
||
'\u014C': 'O',
|
||
'\u1E50': 'O',
|
||
'\u1E52': 'O',
|
||
'\u014E': 'O',
|
||
'\u022E': 'O',
|
||
'\u0230': 'O',
|
||
'\u00D6': 'O',
|
||
'\u022A': 'O',
|
||
'\u1ECE': 'O',
|
||
'\u0150': 'O',
|
||
'\u01D1': 'O',
|
||
'\u020C': 'O',
|
||
'\u020E': 'O',
|
||
'\u01A0': 'O',
|
||
'\u1EDC': 'O',
|
||
'\u1EDA': 'O',
|
||
'\u1EE0': 'O',
|
||
'\u1EDE': 'O',
|
||
'\u1EE2': 'O',
|
||
'\u1ECC': 'O',
|
||
'\u1ED8': 'O',
|
||
'\u01EA': 'O',
|
||
'\u01EC': 'O',
|
||
'\u00D8': 'O',
|
||
'\u01FE': 'O',
|
||
'\u0186': 'O',
|
||
'\u019F': 'O',
|
||
'\uA74A': 'O',
|
||
'\uA74C': 'O',
|
||
'\u01A2': 'OI',
|
||
'\uA74E': 'OO',
|
||
'\u0222': 'OU',
|
||
'\u24C5': 'P',
|
||
'\uFF30': 'P',
|
||
'\u1E54': 'P',
|
||
'\u1E56': 'P',
|
||
'\u01A4': 'P',
|
||
'\u2C63': 'P',
|
||
'\uA750': 'P',
|
||
'\uA752': 'P',
|
||
'\uA754': 'P',
|
||
'\u24C6': 'Q',
|
||
'\uFF31': 'Q',
|
||
'\uA756': 'Q',
|
||
'\uA758': 'Q',
|
||
'\u024A': 'Q',
|
||
'\u24C7': 'R',
|
||
'\uFF32': 'R',
|
||
'\u0154': 'R',
|
||
'\u1E58': 'R',
|
||
'\u0158': 'R',
|
||
'\u0210': 'R',
|
||
'\u0212': 'R',
|
||
'\u1E5A': 'R',
|
||
'\u1E5C': 'R',
|
||
'\u0156': 'R',
|
||
'\u1E5E': 'R',
|
||
'\u024C': 'R',
|
||
'\u2C64': 'R',
|
||
'\uA75A': 'R',
|
||
'\uA7A6': 'R',
|
||
'\uA782': 'R',
|
||
'\u24C8': 'S',
|
||
'\uFF33': 'S',
|
||
'\u1E9E': 'S',
|
||
'\u015A': 'S',
|
||
'\u1E64': 'S',
|
||
'\u015C': 'S',
|
||
'\u1E60': 'S',
|
||
'\u0160': 'S',
|
||
'\u1E66': 'S',
|
||
'\u1E62': 'S',
|
||
'\u1E68': 'S',
|
||
'\u0218': 'S',
|
||
'\u015E': 'S',
|
||
'\u2C7E': 'S',
|
||
'\uA7A8': 'S',
|
||
'\uA784': 'S',
|
||
'\u24C9': 'T',
|
||
'\uFF34': 'T',
|
||
'\u1E6A': 'T',
|
||
'\u0164': 'T',
|
||
'\u1E6C': 'T',
|
||
'\u021A': 'T',
|
||
'\u0162': 'T',
|
||
'\u1E70': 'T',
|
||
'\u1E6E': 'T',
|
||
'\u0166': 'T',
|
||
'\u01AC': 'T',
|
||
'\u01AE': 'T',
|
||
'\u023E': 'T',
|
||
'\uA786': 'T',
|
||
'\uA728': 'TZ',
|
||
'\u24CA': 'U',
|
||
'\uFF35': 'U',
|
||
'\u00D9': 'U',
|
||
'\u00DA': 'U',
|
||
'\u00DB': 'U',
|
||
'\u0168': 'U',
|
||
'\u1E78': 'U',
|
||
'\u016A': 'U',
|
||
'\u1E7A': 'U',
|
||
'\u016C': 'U',
|
||
'\u00DC': 'U',
|
||
'\u01DB': 'U',
|
||
'\u01D7': 'U',
|
||
'\u01D5': 'U',
|
||
'\u01D9': 'U',
|
||
'\u1EE6': 'U',
|
||
'\u016E': 'U',
|
||
'\u0170': 'U',
|
||
'\u01D3': 'U',
|
||
'\u0214': 'U',
|
||
'\u0216': 'U',
|
||
'\u01AF': 'U',
|
||
'\u1EEA': 'U',
|
||
'\u1EE8': 'U',
|
||
'\u1EEE': 'U',
|
||
'\u1EEC': 'U',
|
||
'\u1EF0': 'U',
|
||
'\u1EE4': 'U',
|
||
'\u1E72': 'U',
|
||
'\u0172': 'U',
|
||
'\u1E76': 'U',
|
||
'\u1E74': 'U',
|
||
'\u0244': 'U',
|
||
'\u24CB': 'V',
|
||
'\uFF36': 'V',
|
||
'\u1E7C': 'V',
|
||
'\u1E7E': 'V',
|
||
'\u01B2': 'V',
|
||
'\uA75E': 'V',
|
||
'\u0245': 'V',
|
||
'\uA760': 'VY',
|
||
'\u24CC': 'W',
|
||
'\uFF37': 'W',
|
||
'\u1E80': 'W',
|
||
'\u1E82': 'W',
|
||
'\u0174': 'W',
|
||
'\u1E86': 'W',
|
||
'\u1E84': 'W',
|
||
'\u1E88': 'W',
|
||
'\u2C72': 'W',
|
||
'\u24CD': 'X',
|
||
'\uFF38': 'X',
|
||
'\u1E8A': 'X',
|
||
'\u1E8C': 'X',
|
||
'\u24CE': 'Y',
|
||
'\uFF39': 'Y',
|
||
'\u1EF2': 'Y',
|
||
'\u00DD': 'Y',
|
||
'\u0176': 'Y',
|
||
'\u1EF8': 'Y',
|
||
'\u0232': 'Y',
|
||
'\u1E8E': 'Y',
|
||
'\u0178': 'Y',
|
||
'\u1EF6': 'Y',
|
||
'\u1EF4': 'Y',
|
||
'\u01B3': 'Y',
|
||
'\u024E': 'Y',
|
||
'\u1EFE': 'Y',
|
||
'\u24CF': 'Z',
|
||
'\uFF3A': 'Z',
|
||
'\u0179': 'Z',
|
||
'\u1E90': 'Z',
|
||
'\u017B': 'Z',
|
||
'\u017D': 'Z',
|
||
'\u1E92': 'Z',
|
||
'\u1E94': 'Z',
|
||
'\u01B5': 'Z',
|
||
'\u0224': 'Z',
|
||
'\u2C7F': 'Z',
|
||
'\u2C6B': 'Z',
|
||
'\uA762': 'Z',
|
||
'\u24D0': 'a',
|
||
'\uFF41': 'a',
|
||
'\u1E9A': 'a',
|
||
'\u00E0': 'a',
|
||
'\u00E1': 'a',
|
||
'\u00E2': 'a',
|
||
'\u1EA7': 'a',
|
||
'\u1EA5': 'a',
|
||
'\u1EAB': 'a',
|
||
'\u1EA9': 'a',
|
||
'\u00E3': 'a',
|
||
'\u0101': 'a',
|
||
'\u0103': 'a',
|
||
'\u1EB1': 'a',
|
||
'\u1EAF': 'a',
|
||
'\u1EB5': 'a',
|
||
'\u1EB3': 'a',
|
||
'\u0227': 'a',
|
||
'\u01E1': 'a',
|
||
'\u00E4': 'a',
|
||
'\u01DF': 'a',
|
||
'\u1EA3': 'a',
|
||
'\u00E5': 'a',
|
||
'\u01FB': 'a',
|
||
'\u01CE': 'a',
|
||
'\u0201': 'a',
|
||
'\u0203': 'a',
|
||
'\u1EA1': 'a',
|
||
'\u1EAD': 'a',
|
||
'\u1EB7': 'a',
|
||
'\u1E01': 'a',
|
||
'\u0105': 'a',
|
||
'\u2C65': 'a',
|
||
'\u0250': 'a',
|
||
'\uA733': 'aa',
|
||
'\u00E6': 'ae',
|
||
'\u01FD': 'ae',
|
||
'\u01E3': 'ae',
|
||
'\uA735': 'ao',
|
||
'\uA737': 'au',
|
||
'\uA739': 'av',
|
||
'\uA73B': 'av',
|
||
'\uA73D': 'ay',
|
||
'\u24D1': 'b',
|
||
'\uFF42': 'b',
|
||
'\u1E03': 'b',
|
||
'\u1E05': 'b',
|
||
'\u1E07': 'b',
|
||
'\u0180': 'b',
|
||
'\u0183': 'b',
|
||
'\u0253': 'b',
|
||
'\u24D2': 'c',
|
||
'\uFF43': 'c',
|
||
'\u0107': 'c',
|
||
'\u0109': 'c',
|
||
'\u010B': 'c',
|
||
'\u010D': 'c',
|
||
'\u00E7': 'c',
|
||
'\u1E09': 'c',
|
||
'\u0188': 'c',
|
||
'\u023C': 'c',
|
||
'\uA73F': 'c',
|
||
'\u2184': 'c',
|
||
'\u24D3': 'd',
|
||
'\uFF44': 'd',
|
||
'\u1E0B': 'd',
|
||
'\u010F': 'd',
|
||
'\u1E0D': 'd',
|
||
'\u1E11': 'd',
|
||
'\u1E13': 'd',
|
||
'\u1E0F': 'd',
|
||
'\u0111': 'd',
|
||
'\u018C': 'd',
|
||
'\u0256': 'd',
|
||
'\u0257': 'd',
|
||
'\uA77A': 'd',
|
||
'\u01F3': 'dz',
|
||
'\u01C6': 'dz',
|
||
'\u24D4': 'e',
|
||
'\uFF45': 'e',
|
||
'\u00E8': 'e',
|
||
'\u00E9': 'e',
|
||
'\u00EA': 'e',
|
||
'\u1EC1': 'e',
|
||
'\u1EBF': 'e',
|
||
'\u1EC5': 'e',
|
||
'\u1EC3': 'e',
|
||
'\u1EBD': 'e',
|
||
'\u0113': 'e',
|
||
'\u1E15': 'e',
|
||
'\u1E17': 'e',
|
||
'\u0115': 'e',
|
||
'\u0117': 'e',
|
||
'\u00EB': 'e',
|
||
'\u1EBB': 'e',
|
||
'\u011B': 'e',
|
||
'\u0205': 'e',
|
||
'\u0207': 'e',
|
||
'\u1EB9': 'e',
|
||
'\u1EC7': 'e',
|
||
'\u0229': 'e',
|
||
'\u1E1D': 'e',
|
||
'\u0119': 'e',
|
||
'\u1E19': 'e',
|
||
'\u1E1B': 'e',
|
||
'\u0247': 'e',
|
||
'\u025B': 'e',
|
||
'\u01DD': 'e',
|
||
'\u24D5': 'f',
|
||
'\uFF46': 'f',
|
||
'\u1E1F': 'f',
|
||
'\u0192': 'f',
|
||
'\uA77C': 'f',
|
||
'\u24D6': 'g',
|
||
'\uFF47': 'g',
|
||
'\u01F5': 'g',
|
||
'\u011D': 'g',
|
||
'\u1E21': 'g',
|
||
'\u011F': 'g',
|
||
'\u0121': 'g',
|
||
'\u01E7': 'g',
|
||
'\u0123': 'g',
|
||
'\u01E5': 'g',
|
||
'\u0260': 'g',
|
||
'\uA7A1': 'g',
|
||
'\u1D79': 'g',
|
||
'\uA77F': 'g',
|
||
'\u24D7': 'h',
|
||
'\uFF48': 'h',
|
||
'\u0125': 'h',
|
||
'\u1E23': 'h',
|
||
'\u1E27': 'h',
|
||
'\u021F': 'h',
|
||
'\u1E25': 'h',
|
||
'\u1E29': 'h',
|
||
'\u1E2B': 'h',
|
||
'\u1E96': 'h',
|
||
'\u0127': 'h',
|
||
'\u2C68': 'h',
|
||
'\u2C76': 'h',
|
||
'\u0265': 'h',
|
||
'\u0195': 'hv',
|
||
'\u24D8': 'i',
|
||
'\uFF49': 'i',
|
||
'\u00EC': 'i',
|
||
'\u00ED': 'i',
|
||
'\u00EE': 'i',
|
||
'\u0129': 'i',
|
||
'\u012B': 'i',
|
||
'\u012D': 'i',
|
||
'\u00EF': 'i',
|
||
'\u1E2F': 'i',
|
||
'\u1EC9': 'i',
|
||
'\u01D0': 'i',
|
||
'\u0209': 'i',
|
||
'\u020B': 'i',
|
||
'\u1ECB': 'i',
|
||
'\u012F': 'i',
|
||
'\u1E2D': 'i',
|
||
'\u0268': 'i',
|
||
'\u0131': 'i',
|
||
'\u24D9': 'j',
|
||
'\uFF4A': 'j',
|
||
'\u0135': 'j',
|
||
'\u01F0': 'j',
|
||
'\u0249': 'j',
|
||
'\u24DA': 'k',
|
||
'\uFF4B': 'k',
|
||
'\u1E31': 'k',
|
||
'\u01E9': 'k',
|
||
'\u1E33': 'k',
|
||
'\u0137': 'k',
|
||
'\u1E35': 'k',
|
||
'\u0199': 'k',
|
||
'\u2C6A': 'k',
|
||
'\uA741': 'k',
|
||
'\uA743': 'k',
|
||
'\uA745': 'k',
|
||
'\uA7A3': 'k',
|
||
'\u24DB': 'l',
|
||
'\uFF4C': 'l',
|
||
'\u0140': 'l',
|
||
'\u013A': 'l',
|
||
'\u013E': 'l',
|
||
'\u1E37': 'l',
|
||
'\u1E39': 'l',
|
||
'\u013C': 'l',
|
||
'\u1E3D': 'l',
|
||
'\u1E3B': 'l',
|
||
'\u017F': 'l',
|
||
'\u0142': 'l',
|
||
'\u019A': 'l',
|
||
'\u026B': 'l',
|
||
'\u2C61': 'l',
|
||
'\uA749': 'l',
|
||
'\uA781': 'l',
|
||
'\uA747': 'l',
|
||
'\u01C9': 'lj',
|
||
'\u24DC': 'm',
|
||
'\uFF4D': 'm',
|
||
'\u1E3F': 'm',
|
||
'\u1E41': 'm',
|
||
'\u1E43': 'm',
|
||
'\u0271': 'm',
|
||
'\u026F': 'm',
|
||
'\u24DD': 'n',
|
||
'\uFF4E': 'n',
|
||
'\u01F9': 'n',
|
||
'\u0144': 'n',
|
||
'\u00F1': 'n',
|
||
'\u1E45': 'n',
|
||
'\u0148': 'n',
|
||
'\u1E47': 'n',
|
||
'\u0146': 'n',
|
||
'\u1E4B': 'n',
|
||
'\u1E49': 'n',
|
||
'\u019E': 'n',
|
||
'\u0272': 'n',
|
||
'\u0149': 'n',
|
||
'\uA791': 'n',
|
||
'\uA7A5': 'n',
|
||
'\u01CC': 'nj',
|
||
'\u24DE': 'o',
|
||
'\uFF4F': 'o',
|
||
'\u00F2': 'o',
|
||
'\u00F3': 'o',
|
||
'\u00F4': 'o',
|
||
'\u1ED3': 'o',
|
||
'\u1ED1': 'o',
|
||
'\u1ED7': 'o',
|
||
'\u1ED5': 'o',
|
||
'\u00F5': 'o',
|
||
'\u1E4D': 'o',
|
||
'\u022D': 'o',
|
||
'\u1E4F': 'o',
|
||
'\u014D': 'o',
|
||
'\u1E51': 'o',
|
||
'\u1E53': 'o',
|
||
'\u014F': 'o',
|
||
'\u022F': 'o',
|
||
'\u0231': 'o',
|
||
'\u00F6': 'o',
|
||
'\u022B': 'o',
|
||
'\u1ECF': 'o',
|
||
'\u0151': 'o',
|
||
'\u01D2': 'o',
|
||
'\u020D': 'o',
|
||
'\u020F': 'o',
|
||
'\u01A1': 'o',
|
||
'\u1EDD': 'o',
|
||
'\u1EDB': 'o',
|
||
'\u1EE1': 'o',
|
||
'\u1EDF': 'o',
|
||
'\u1EE3': 'o',
|
||
'\u1ECD': 'o',
|
||
'\u1ED9': 'o',
|
||
'\u01EB': 'o',
|
||
'\u01ED': 'o',
|
||
'\u00F8': 'o',
|
||
'\u01FF': 'o',
|
||
'\u0254': 'o',
|
||
'\uA74B': 'o',
|
||
'\uA74D': 'o',
|
||
'\u0275': 'o',
|
||
'\u01A3': 'oi',
|
||
'\u0223': 'ou',
|
||
'\uA74F': 'oo',
|
||
'\u24DF': 'p',
|
||
'\uFF50': 'p',
|
||
'\u1E55': 'p',
|
||
'\u1E57': 'p',
|
||
'\u01A5': 'p',
|
||
'\u1D7D': 'p',
|
||
'\uA751': 'p',
|
||
'\uA753': 'p',
|
||
'\uA755': 'p',
|
||
'\u24E0': 'q',
|
||
'\uFF51': 'q',
|
||
'\u024B': 'q',
|
||
'\uA757': 'q',
|
||
'\uA759': 'q',
|
||
'\u24E1': 'r',
|
||
'\uFF52': 'r',
|
||
'\u0155': 'r',
|
||
'\u1E59': 'r',
|
||
'\u0159': 'r',
|
||
'\u0211': 'r',
|
||
'\u0213': 'r',
|
||
'\u1E5B': 'r',
|
||
'\u1E5D': 'r',
|
||
'\u0157': 'r',
|
||
'\u1E5F': 'r',
|
||
'\u024D': 'r',
|
||
'\u027D': 'r',
|
||
'\uA75B': 'r',
|
||
'\uA7A7': 'r',
|
||
'\uA783': 'r',
|
||
'\u24E2': 's',
|
||
'\uFF53': 's',
|
||
'\u00DF': 's',
|
||
'\u015B': 's',
|
||
'\u1E65': 's',
|
||
'\u015D': 's',
|
||
'\u1E61': 's',
|
||
'\u0161': 's',
|
||
'\u1E67': 's',
|
||
'\u1E63': 's',
|
||
'\u1E69': 's',
|
||
'\u0219': 's',
|
||
'\u015F': 's',
|
||
'\u023F': 's',
|
||
'\uA7A9': 's',
|
||
'\uA785': 's',
|
||
'\u1E9B': 's',
|
||
'\u24E3': 't',
|
||
'\uFF54': 't',
|
||
'\u1E6B': 't',
|
||
'\u1E97': 't',
|
||
'\u0165': 't',
|
||
'\u1E6D': 't',
|
||
'\u021B': 't',
|
||
'\u0163': 't',
|
||
'\u1E71': 't',
|
||
'\u1E6F': 't',
|
||
'\u0167': 't',
|
||
'\u01AD': 't',
|
||
'\u0288': 't',
|
||
'\u2C66': 't',
|
||
'\uA787': 't',
|
||
'\uA729': 'tz',
|
||
'\u24E4': 'u',
|
||
'\uFF55': 'u',
|
||
'\u00F9': 'u',
|
||
'\u00FA': 'u',
|
||
'\u00FB': 'u',
|
||
'\u0169': 'u',
|
||
'\u1E79': 'u',
|
||
'\u016B': 'u',
|
||
'\u1E7B': 'u',
|
||
'\u016D': 'u',
|
||
'\u00FC': 'u',
|
||
'\u01DC': 'u',
|
||
'\u01D8': 'u',
|
||
'\u01D6': 'u',
|
||
'\u01DA': 'u',
|
||
'\u1EE7': 'u',
|
||
'\u016F': 'u',
|
||
'\u0171': 'u',
|
||
'\u01D4': 'u',
|
||
'\u0215': 'u',
|
||
'\u0217': 'u',
|
||
'\u01B0': 'u',
|
||
'\u1EEB': 'u',
|
||
'\u1EE9': 'u',
|
||
'\u1EEF': 'u',
|
||
'\u1EED': 'u',
|
||
'\u1EF1': 'u',
|
||
'\u1EE5': 'u',
|
||
'\u1E73': 'u',
|
||
'\u0173': 'u',
|
||
'\u1E77': 'u',
|
||
'\u1E75': 'u',
|
||
'\u0289': 'u',
|
||
'\u24E5': 'v',
|
||
'\uFF56': 'v',
|
||
'\u1E7D': 'v',
|
||
'\u1E7F': 'v',
|
||
'\u028B': 'v',
|
||
'\uA75F': 'v',
|
||
'\u028C': 'v',
|
||
'\uA761': 'vy',
|
||
'\u24E6': 'w',
|
||
'\uFF57': 'w',
|
||
'\u1E81': 'w',
|
||
'\u1E83': 'w',
|
||
'\u0175': 'w',
|
||
'\u1E87': 'w',
|
||
'\u1E85': 'w',
|
||
'\u1E98': 'w',
|
||
'\u1E89': 'w',
|
||
'\u2C73': 'w',
|
||
'\u24E7': 'x',
|
||
'\uFF58': 'x',
|
||
'\u1E8B': 'x',
|
||
'\u1E8D': 'x',
|
||
'\u24E8': 'y',
|
||
'\uFF59': 'y',
|
||
'\u1EF3': 'y',
|
||
'\u00FD': 'y',
|
||
'\u0177': 'y',
|
||
'\u1EF9': 'y',
|
||
'\u0233': 'y',
|
||
'\u1E8F': 'y',
|
||
'\u00FF': 'y',
|
||
'\u1EF7': 'y',
|
||
'\u1E99': 'y',
|
||
'\u1EF5': 'y',
|
||
'\u01B4': 'y',
|
||
'\u024F': 'y',
|
||
'\u1EFF': 'y',
|
||
'\u24E9': 'z',
|
||
'\uFF5A': 'z',
|
||
'\u017A': 'z',
|
||
'\u1E91': 'z',
|
||
'\u017C': 'z',
|
||
'\u017E': 'z',
|
||
'\u1E93': 'z',
|
||
'\u1E95': 'z',
|
||
'\u01B6': 'z',
|
||
'\u0225': 'z',
|
||
'\u0240': 'z',
|
||
'\u2C6C': 'z',
|
||
'\uA763': 'z',
|
||
'\u0386': '\u0391',
|
||
'\u0388': '\u0395',
|
||
'\u0389': '\u0397',
|
||
'\u038A': '\u0399',
|
||
'\u03AA': '\u0399',
|
||
'\u038C': '\u039F',
|
||
'\u038E': '\u03A5',
|
||
'\u03AB': '\u03A5',
|
||
'\u038F': '\u03A9',
|
||
'\u03AC': '\u03B1',
|
||
'\u03AD': '\u03B5',
|
||
'\u03AE': '\u03B7',
|
||
'\u03AF': '\u03B9',
|
||
'\u03CA': '\u03B9',
|
||
'\u0390': '\u03B9',
|
||
'\u03CC': '\u03BF',
|
||
'\u03CD': '\u03C5',
|
||
'\u03CB': '\u03C5',
|
||
'\u03B0': '\u03C5',
|
||
'\u03C9': '\u03C9',
|
||
'\u03C2': '\u03C3'
|
||
};
|
||
|
||
return diacritics;
|
||
});
|
||
|
||
S2.define('select2/data/base',[
|
||
'../utils'
|
||
], function (Utils) {
|
||
function BaseAdapter ($element, options) {
|
||
BaseAdapter.__super__.constructor.call(this);
|
||
}
|
||
|
||
Utils.Extend(BaseAdapter, Utils.Observable);
|
||
|
||
BaseAdapter.prototype.current = function (callback) {
|
||
throw new Error('The `current` method must be defined in child classes.');
|
||
};
|
||
|
||
BaseAdapter.prototype.query = function (params, callback) {
|
||
throw new Error('The `query` method must be defined in child classes.');
|
||
};
|
||
|
||
BaseAdapter.prototype.bind = function (container, $container) {
|
||
// Can be implemented in subclasses
|
||
};
|
||
|
||
BaseAdapter.prototype.destroy = function () {
|
||
// Can be implemented in subclasses
|
||
};
|
||
|
||
BaseAdapter.prototype.generateResultId = function (container, data) {
|
||
var id = container.id + '-result-';
|
||
|
||
id += Utils.generateChars(4);
|
||
|
||
if (data.id != null) {
|
||
id += '-' + data.id.toString();
|
||
} else {
|
||
id += '-' + Utils.generateChars(4);
|
||
}
|
||
return id;
|
||
};
|
||
|
||
return BaseAdapter;
|
||
});
|
||
|
||
S2.define('select2/data/select',[
|
||
'./base',
|
||
'../utils',
|
||
'jquery'
|
||
], function (BaseAdapter, Utils, $) {
|
||
function SelectAdapter ($element, options) {
|
||
this.$element = $element;
|
||
this.options = options;
|
||
|
||
SelectAdapter.__super__.constructor.call(this);
|
||
}
|
||
|
||
Utils.Extend(SelectAdapter, BaseAdapter);
|
||
|
||
SelectAdapter.prototype.current = function (callback) {
|
||
var data = [];
|
||
var self = this;
|
||
|
||
this.$element.find(':selected').each(function () {
|
||
var $option = $(this);
|
||
|
||
var option = self.item($option);
|
||
|
||
data.push(option);
|
||
});
|
||
|
||
callback(data);
|
||
};
|
||
|
||
SelectAdapter.prototype.select = function (data) {
|
||
var self = this;
|
||
|
||
data.selected = true;
|
||
|
||
// If data.element is a DOM node, use it instead
|
||
if ($(data.element).is('option')) {
|
||
data.element.selected = true;
|
||
|
||
this.$element.trigger('change');
|
||
|
||
return;
|
||
}
|
||
|
||
if (this.$element.prop('multiple')) {
|
||
this.current(function (currentData) {
|
||
var val = [];
|
||
|
||
data = [data];
|
||
data.push.apply(data, currentData);
|
||
|
||
for (var d = 0; d < data.length; d++) {
|
||
var id = data[d].id;
|
||
|
||
if ($.inArray(id, val) === -1) {
|
||
val.push(id);
|
||
}
|
||
}
|
||
|
||
self.$element.val(val);
|
||
self.$element.trigger('change');
|
||
});
|
||
} else {
|
||
var val = data.id;
|
||
|
||
this.$element.val(val);
|
||
this.$element.trigger('change');
|
||
}
|
||
};
|
||
|
||
SelectAdapter.prototype.unselect = function (data) {
|
||
var self = this;
|
||
|
||
if (!this.$element.prop('multiple')) {
|
||
return;
|
||
}
|
||
|
||
data.selected = false;
|
||
|
||
if ($(data.element).is('option')) {
|
||
data.element.selected = false;
|
||
|
||
this.$element.trigger('change');
|
||
|
||
return;
|
||
}
|
||
|
||
this.current(function (currentData) {
|
||
var val = [];
|
||
|
||
for (var d = 0; d < currentData.length; d++) {
|
||
var id = currentData[d].id;
|
||
|
||
if (id !== data.id && $.inArray(id, val) === -1) {
|
||
val.push(id);
|
||
}
|
||
}
|
||
|
||
self.$element.val(val);
|
||
|
||
self.$element.trigger('change');
|
||
});
|
||
};
|
||
|
||
SelectAdapter.prototype.bind = function (container, $container) {
|
||
var self = this;
|
||
|
||
this.container = container;
|
||
|
||
container.on('select', function (params) {
|
||
self.select(params.data);
|
||
});
|
||
|
||
container.on('unselect', function (params) {
|
||
self.unselect(params.data);
|
||
});
|
||
};
|
||
|
||
SelectAdapter.prototype.destroy = function () {
|
||
// Remove anything added to child elements
|
||
this.$element.find('*').each(function () {
|
||
// Remove any custom data set by Select2
|
||
$.removeData(this, 'data');
|
||
});
|
||
};
|
||
|
||
SelectAdapter.prototype.query = function (params, callback) {
|
||
var data = [];
|
||
var self = this;
|
||
|
||
var $options = this.$element.children();
|
||
|
||
$options.each(function () {
|
||
var $option = $(this);
|
||
|
||
if (!$option.is('option') && !$option.is('optgroup')) {
|
||
return;
|
||
}
|
||
|
||
var option = self.item($option);
|
||
|
||
var matches = self.matches(params, option);
|
||
|
||
if (matches !== null) {
|
||
data.push(matches);
|
||
}
|
||
});
|
||
|
||
callback({
|
||
results: data
|
||
});
|
||
};
|
||
|
||
SelectAdapter.prototype.addOptions = function ($options) {
|
||
Utils.appendMany(this.$element, $options);
|
||
};
|
||
|
||
SelectAdapter.prototype.option = function (data) {
|
||
var option;
|
||
|
||
if (data.children) {
|
||
option = document.createElement('optgroup');
|
||
option.label = data.text;
|
||
} else {
|
||
option = document.createElement('option');
|
||
|
||
if (option.textContent !== undefined) {
|
||
option.textContent = data.text;
|
||
} else {
|
||
option.innerText = data.text;
|
||
}
|
||
}
|
||
|
||
if (data.id) {
|
||
option.value = data.id;
|
||
}
|
||
|
||
if (data.disabled) {
|
||
option.disabled = true;
|
||
}
|
||
|
||
if (data.selected) {
|
||
option.selected = true;
|
||
}
|
||
|
||
if (data.title) {
|
||
option.title = data.title;
|
||
}
|
||
|
||
var $option = $(option);
|
||
|
||
var normalizedData = this._normalizeItem(data);
|
||
normalizedData.element = option;
|
||
|
||
// Override the option's data with the combined data
|
||
$.data(option, 'data', normalizedData);
|
||
|
||
return $option;
|
||
};
|
||
|
||
SelectAdapter.prototype.item = function ($option) {
|
||
var data = {};
|
||
|
||
data = $.data($option[0], 'data');
|
||
|
||
if (data != null) {
|
||
return data;
|
||
}
|
||
|
||
if ($option.is('option')) {
|
||
data = {
|
||
id: $option.val(),
|
||
text: $option.text(),
|
||
disabled: $option.prop('disabled'),
|
||
selected: $option.prop('selected'),
|
||
title: $option.prop('title')
|
||
};
|
||
} else if ($option.is('optgroup')) {
|
||
data = {
|
||
text: $option.prop('label'),
|
||
children: [],
|
||
title: $option.prop('title')
|
||
};
|
||
|
||
var $children = $option.children('option');
|
||
var children = [];
|
||
|
||
for (var c = 0; c < $children.length; c++) {
|
||
var $child = $($children[c]);
|
||
|
||
var child = this.item($child);
|
||
|
||
children.push(child);
|
||
}
|
||
|
||
data.children = children;
|
||
}
|
||
|
||
data = this._normalizeItem(data);
|
||
data.element = $option[0];
|
||
|
||
$.data($option[0], 'data', data);
|
||
|
||
return data;
|
||
};
|
||
|
||
SelectAdapter.prototype._normalizeItem = function (item) {
|
||
if (!$.isPlainObject(item)) {
|
||
item = {
|
||
id: item,
|
||
text: item
|
||
};
|
||
}
|
||
|
||
item = $.extend({}, {
|
||
text: ''
|
||
}, item);
|
||
|
||
var defaults = {
|
||
selected: false,
|
||
disabled: false
|
||
};
|
||
|
||
if (item.id != null) {
|
||
item.id = item.id.toString();
|
||
}
|
||
|
||
if (item.text != null) {
|
||
item.text = item.text.toString();
|
||
}
|
||
|
||
if (item._resultId == null && item.id && this.container != null) {
|
||
item._resultId = this.generateResultId(this.container, item);
|
||
}
|
||
|
||
return $.extend({}, defaults, item);
|
||
};
|
||
|
||
SelectAdapter.prototype.matches = function (params, data) {
|
||
var matcher = this.options.get('matcher');
|
||
|
||
return matcher(params, data);
|
||
};
|
||
|
||
return SelectAdapter;
|
||
});
|
||
|
||
S2.define('select2/data/array',[
|
||
'./select',
|
||
'../utils',
|
||
'jquery'
|
||
], function (SelectAdapter, Utils, $) {
|
||
function ArrayAdapter ($element, options) {
|
||
var data = options.get('data') || [];
|
||
|
||
ArrayAdapter.__super__.constructor.call(this, $element, options);
|
||
|
||
this.addOptions(this.convertToOptions(data));
|
||
}
|
||
|
||
Utils.Extend(ArrayAdapter, SelectAdapter);
|
||
|
||
ArrayAdapter.prototype.select = function (data) {
|
||
var $option = this.$element.find('option').filter(function (i, elm) {
|
||
return elm.value == data.id.toString();
|
||
});
|
||
|
||
if ($option.length === 0) {
|
||
$option = this.option(data);
|
||
|
||
this.addOptions($option);
|
||
}
|
||
|
||
ArrayAdapter.__super__.select.call(this, data);
|
||
};
|
||
|
||
ArrayAdapter.prototype.convertToOptions = function (data) {
|
||
var self = this;
|
||
|
||
var $existing = this.$element.find('option');
|
||
var existingIds = $existing.map(function () {
|
||
return self.item($(this)).id;
|
||
}).get();
|
||
|
||
var $options = [];
|
||
|
||
// Filter out all items except for the one passed in the argument
|
||
function onlyItem (item) {
|
||
return function () {
|
||
return $(this).val() == item.id;
|
||
};
|
||
}
|
||
|
||
for (var d = 0; d < data.length; d++) {
|
||
var item = this._normalizeItem(data[d]);
|
||
|
||
// Skip items which were pre-loaded, only merge the data
|
||
if ($.inArray(item.id, existingIds) >= 0) {
|
||
var $existingOption = $existing.filter(onlyItem(item));
|
||
|
||
var existingData = this.item($existingOption);
|
||
var newData = $.extend(true, {}, item, existingData);
|
||
|
||
var $newOption = this.option(newData);
|
||
|
||
$existingOption.replaceWith($newOption);
|
||
|
||
continue;
|
||
}
|
||
|
||
var $option = this.option(item);
|
||
|
||
if (item.children) {
|
||
var $children = this.convertToOptions(item.children);
|
||
|
||
Utils.appendMany($option, $children);
|
||
}
|
||
|
||
$options.push($option);
|
||
}
|
||
|
||
return $options;
|
||
};
|
||
|
||
return ArrayAdapter;
|
||
});
|
||
|
||
S2.define('select2/data/ajax',[
|
||
'./array',
|
||
'../utils',
|
||
'jquery'
|
||
], function (ArrayAdapter, Utils, $) {
|
||
function AjaxAdapter ($element, options) {
|
||
this.ajaxOptions = this._applyDefaults(options.get('ajax'));
|
||
|
||
if (this.ajaxOptions.processResults != null) {
|
||
this.processResults = this.ajaxOptions.processResults;
|
||
}
|
||
|
||
AjaxAdapter.__super__.constructor.call(this, $element, options);
|
||
}
|
||
|
||
Utils.Extend(AjaxAdapter, ArrayAdapter);
|
||
|
||
AjaxAdapter.prototype._applyDefaults = function (options) {
|
||
var defaults = {
|
||
data: function (params) {
|
||
return $.extend({}, params, {
|
||
q: params.term
|
||
});
|
||
},
|
||
transport: function (params, success, failure) {
|
||
var $request = $.ajax(params);
|
||
|
||
$request.then(success);
|
||
$request.fail(failure);
|
||
|
||
return $request;
|
||
}
|
||
};
|
||
|
||
return $.extend({}, defaults, options, true);
|
||
};
|
||
|
||
AjaxAdapter.prototype.processResults = function (results) {
|
||
return results;
|
||
};
|
||
|
||
AjaxAdapter.prototype.query = function (params, callback) {
|
||
var matches = [];
|
||
var self = this;
|
||
|
||
if (this._request != null) {
|
||
// JSONP requests cannot always be aborted
|
||
if ($.isFunction(this._request.abort)) {
|
||
this._request.abort();
|
||
}
|
||
|
||
this._request = null;
|
||
}
|
||
|
||
var options = $.extend({
|
||
type: 'GET'
|
||
}, this.ajaxOptions);
|
||
|
||
if (typeof options.url === 'function') {
|
||
options.url = options.url.call(this.$element, params);
|
||
}
|
||
|
||
if (typeof options.data === 'function') {
|
||
options.data = options.data.call(this.$element, params);
|
||
}
|
||
|
||
function request () {
|
||
var $request = options.transport(options, function (data) {
|
||
var results = self.processResults(data, params);
|
||
|
||
if (self.options.get('debug') && window.console && console.error) {
|
||
// Check to make sure that the response included a `results` key.
|
||
if (!results || !results.results || !$.isArray(results.results)) {
|
||
console.error(
|
||
'Select2: The AJAX results did not return an array in the ' +
|
||
'`results` key of the response.'
|
||
);
|
||
}
|
||
}
|
||
|
||
callback(results);
|
||
}, function () {
|
||
// Attempt to detect if a request was aborted
|
||
// Only works if the transport exposes a status property
|
||
if ($request.status && $request.status === '0') {
|
||
return;
|
||
}
|
||
|
||
self.trigger('results:message', {
|
||
message: 'errorLoading'
|
||
});
|
||
});
|
||
|
||
self._request = $request;
|
||
}
|
||
|
||
if (this.ajaxOptions.delay && params.term != null) {
|
||
if (this._queryTimeout) {
|
||
window.clearTimeout(this._queryTimeout);
|
||
}
|
||
|
||
this._queryTimeout = window.setTimeout(request, this.ajaxOptions.delay);
|
||
} else {
|
||
request();
|
||
}
|
||
};
|
||
|
||
return AjaxAdapter;
|
||
});
|
||
|
||
S2.define('select2/data/tags',[
|
||
'jquery'
|
||
], function ($) {
|
||
function Tags (decorated, $element, options) {
|
||
var tags = options.get('tags');
|
||
|
||
var createTag = options.get('createTag');
|
||
|
||
if (createTag !== undefined) {
|
||
this.createTag = createTag;
|
||
}
|
||
|
||
var insertTag = options.get('insertTag');
|
||
|
||
if (insertTag !== undefined) {
|
||
this.insertTag = insertTag;
|
||
}
|
||
|
||
decorated.call(this, $element, options);
|
||
|
||
if ($.isArray(tags)) {
|
||
for (var t = 0; t < tags.length; t++) {
|
||
var tag = tags[t];
|
||
var item = this._normalizeItem(tag);
|
||
|
||
var $option = this.option(item);
|
||
|
||
this.$element.append($option);
|
||
}
|
||
}
|
||
}
|
||
|
||
Tags.prototype.query = function (decorated, params, callback) {
|
||
var self = this;
|
||
|
||
this._removeOldTags();
|
||
|
||
if (params.term == null || params.page != null) {
|
||
decorated.call(this, params, callback);
|
||
return;
|
||
}
|
||
|
||
function wrapper (obj, child) {
|
||
var data = obj.results;
|
||
|
||
for (var i = 0; i < data.length; i++) {
|
||
var option = data[i];
|
||
|
||
var checkChildren = (
|
||
option.children != null &&
|
||
!wrapper({
|
||
results: option.children
|
||
}, true)
|
||
);
|
||
|
||
var checkText = option.text === params.term;
|
||
|
||
if (checkText || checkChildren) {
|
||
if (child) {
|
||
return false;
|
||
}
|
||
|
||
obj.data = data;
|
||
callback(obj);
|
||
|
||
return;
|
||
}
|
||
}
|
||
|
||
if (child) {
|
||
return true;
|
||
}
|
||
|
||
var tag = self.createTag(params);
|
||
|
||
if (tag != null) {
|
||
var $option = self.option(tag);
|
||
$option.attr('data-select2-tag', true);
|
||
|
||
self.addOptions([$option]);
|
||
|
||
self.insertTag(data, tag);
|
||
}
|
||
|
||
obj.results = data;
|
||
|
||
callback(obj);
|
||
}
|
||
|
||
decorated.call(this, params, wrapper);
|
||
};
|
||
|
||
Tags.prototype.createTag = function (decorated, params) {
|
||
var term = $.trim(params.term);
|
||
|
||
if (term === '') {
|
||
return null;
|
||
}
|
||
|
||
return {
|
||
id: term,
|
||
text: term
|
||
};
|
||
};
|
||
|
||
Tags.prototype.insertTag = function (_, data, tag) {
|
||
data.unshift(tag);
|
||
};
|
||
|
||
Tags.prototype._removeOldTags = function (_) {
|
||
var tag = this._lastTag;
|
||
|
||
var $options = this.$element.find('option[data-select2-tag]');
|
||
|
||
$options.each(function () {
|
||
if (this.selected) {
|
||
return;
|
||
}
|
||
|
||
$(this).remove();
|
||
});
|
||
};
|
||
|
||
return Tags;
|
||
});
|
||
|
||
S2.define('select2/data/tokenizer',[
|
||
'jquery'
|
||
], function ($) {
|
||
function Tokenizer (decorated, $element, options) {
|
||
var tokenizer = options.get('tokenizer');
|
||
|
||
if (tokenizer !== undefined) {
|
||
this.tokenizer = tokenizer;
|
||
}
|
||
|
||
decorated.call(this, $element, options);
|
||
}
|
||
|
||
Tokenizer.prototype.bind = function (decorated, container, $container) {
|
||
decorated.call(this, container, $container);
|
||
|
||
this.$search = container.dropdown.$search || container.selection.$search ||
|
||
$container.find('.select2-search__field');
|
||
};
|
||
|
||
Tokenizer.prototype.query = function (decorated, params, callback) {
|
||
var self = this;
|
||
|
||
function createAndSelect (data) {
|
||
// Normalize the data object so we can use it for checks
|
||
var item = self._normalizeItem(data);
|
||
|
||
// Check if the data object already exists as a tag
|
||
// Select it if it doesn't
|
||
var $existingOptions = self.$element.find('option').filter(function () {
|
||
return $(this).val() === item.id;
|
||
});
|
||
|
||
// If an existing option wasn't found for it, create the option
|
||
if (!$existingOptions.length) {
|
||
var $option = self.option(item);
|
||
$option.attr('data-select2-tag', true);
|
||
|
||
self._removeOldTags();
|
||
self.addOptions([$option]);
|
||
}
|
||
|
||
// Select the item, now that we know there is an option for it
|
||
select(item);
|
||
}
|
||
|
||
function select (data) {
|
||
self.trigger('select', {
|
||
data: data
|
||
});
|
||
}
|
||
|
||
params.term = params.term || '';
|
||
|
||
var tokenData = this.tokenizer(params, this.options, createAndSelect);
|
||
|
||
if (tokenData.term !== params.term) {
|
||
// Replace the search term if we have the search box
|
||
if (this.$search.length) {
|
||
this.$search.val(tokenData.term);
|
||
this.$search.focus();
|
||
}
|
||
|
||
params.term = tokenData.term;
|
||
}
|
||
|
||
decorated.call(this, params, callback);
|
||
};
|
||
|
||
Tokenizer.prototype.tokenizer = function (_, params, options, callback) {
|
||
var separators = options.get('tokenSeparators') || [];
|
||
var term = params.term;
|
||
var i = 0;
|
||
|
||
var createTag = this.createTag || function (params) {
|
||
return {
|
||
id: params.term,
|
||
text: params.term
|
||
};
|
||
};
|
||
|
||
while (i < term.length) {
|
||
var termChar = term[i];
|
||
|
||
if ($.inArray(termChar, separators) === -1) {
|
||
i++;
|
||
|
||
continue;
|
||
}
|
||
|
||
var part = term.substr(0, i);
|
||
var partParams = $.extend({}, params, {
|
||
term: part
|
||
});
|
||
|
||
var data = createTag(partParams);
|
||
|
||
if (data == null) {
|
||
i++;
|
||
continue;
|
||
}
|
||
|
||
callback(data);
|
||
|
||
// Reset the term to not include the tokenized portion
|
||
term = term.substr(i + 1) || '';
|
||
i = 0;
|
||
}
|
||
|
||
return {
|
||
term: term
|
||
};
|
||
};
|
||
|
||
return Tokenizer;
|
||
});
|
||
|
||
S2.define('select2/data/minimumInputLength',[
|
||
|
||
], function () {
|
||
function MinimumInputLength (decorated, $e, options) {
|
||
this.minimumInputLength = options.get('minimumInputLength');
|
||
|
||
decorated.call(this, $e, options);
|
||
}
|
||
|
||
MinimumInputLength.prototype.query = function (decorated, params, callback) {
|
||
params.term = params.term || '';
|
||
|
||
if (params.term.length < this.minimumInputLength) {
|
||
this.trigger('results:message', {
|
||
message: 'inputTooShort',
|
||
args: {
|
||
minimum: this.minimumInputLength,
|
||
input: params.term,
|
||
params: params
|
||
}
|
||
});
|
||
|
||
return;
|
||
}
|
||
|
||
decorated.call(this, params, callback);
|
||
};
|
||
|
||
return MinimumInputLength;
|
||
});
|
||
|
||
S2.define('select2/data/maximumInputLength',[
|
||
|
||
], function () {
|
||
function MaximumInputLength (decorated, $e, options) {
|
||
this.maximumInputLength = options.get('maximumInputLength');
|
||
|
||
decorated.call(this, $e, options);
|
||
}
|
||
|
||
MaximumInputLength.prototype.query = function (decorated, params, callback) {
|
||
params.term = params.term || '';
|
||
|
||
if (this.maximumInputLength > 0 &&
|
||
params.term.length > this.maximumInputLength) {
|
||
this.trigger('results:message', {
|
||
message: 'inputTooLong',
|
||
args: {
|
||
maximum: this.maximumInputLength,
|
||
input: params.term,
|
||
params: params
|
||
}
|
||
});
|
||
|
||
return;
|
||
}
|
||
|
||
decorated.call(this, params, callback);
|
||
};
|
||
|
||
return MaximumInputLength;
|
||
});
|
||
|
||
S2.define('select2/data/maximumSelectionLength',[
|
||
|
||
], function (){
|
||
function MaximumSelectionLength (decorated, $e, options) {
|
||
this.maximumSelectionLength = options.get('maximumSelectionLength');
|
||
|
||
decorated.call(this, $e, options);
|
||
}
|
||
|
||
MaximumSelectionLength.prototype.query =
|
||
function (decorated, params, callback) {
|
||
var self = this;
|
||
|
||
this.current(function (currentData) {
|
||
var count = currentData != null ? currentData.length : 0;
|
||
if (self.maximumSelectionLength > 0 &&
|
||
count >= self.maximumSelectionLength) {
|
||
self.trigger('results:message', {
|
||
message: 'maximumSelected',
|
||
args: {
|
||
maximum: self.maximumSelectionLength
|
||
}
|
||
});
|
||
return;
|
||
}
|
||
decorated.call(self, params, callback);
|
||
});
|
||
};
|
||
|
||
return MaximumSelectionLength;
|
||
});
|
||
|
||
S2.define('select2/dropdown',[
|
||
'jquery',
|
||
'./utils'
|
||
], function ($, Utils) {
|
||
function Dropdown ($element, options) {
|
||
this.$element = $element;
|
||
this.options = options;
|
||
|
||
Dropdown.__super__.constructor.call(this);
|
||
}
|
||
|
||
Utils.Extend(Dropdown, Utils.Observable);
|
||
|
||
Dropdown.prototype.render = function () {
|
||
var $dropdown = $(
|
||
'<span class="select2-dropdown">' +
|
||
'<span class="select2-results"></span>' +
|
||
'</span>'
|
||
);
|
||
|
||
$dropdown.attr('dir', this.options.get('dir'));
|
||
|
||
this.$dropdown = $dropdown;
|
||
|
||
return $dropdown;
|
||
};
|
||
|
||
Dropdown.prototype.bind = function () {
|
||
// Should be implemented in subclasses
|
||
};
|
||
|
||
Dropdown.prototype.position = function ($dropdown, $container) {
|
||
// Should be implmented in subclasses
|
||
};
|
||
|
||
Dropdown.prototype.destroy = function () {
|
||
// Remove the dropdown from the DOM
|
||
this.$dropdown.remove();
|
||
};
|
||
|
||
return Dropdown;
|
||
});
|
||
|
||
S2.define('select2/dropdown/search',[
|
||
'jquery',
|
||
'../utils'
|
||
], function ($, Utils) {
|
||
function Search () { }
|
||
|
||
Search.prototype.render = function (decorated) {
|
||
var $rendered = decorated.call(this);
|
||
|
||
var $search = $(
|
||
'<span class="select2-search select2-search--dropdown">' +
|
||
'<input class="select2-search__field" type="search" tabindex="-1"' +
|
||
' autocomplete="off" autocorrect="off" autocapitalize="off"' +
|
||
' spellcheck="false" role="textbox" />' +
|
||
'</span>'
|
||
);
|
||
|
||
this.$searchContainer = $search;
|
||
this.$search = $search.find('input');
|
||
|
||
$rendered.prepend($search);
|
||
|
||
return $rendered;
|
||
};
|
||
|
||
Search.prototype.bind = function (decorated, container, $container) {
|
||
var self = this;
|
||
|
||
decorated.call(this, container, $container);
|
||
|
||
this.$search.on('keydown', function (evt) {
|
||
self.trigger('keypress', evt);
|
||
|
||
self._keyUpPrevented = evt.isDefaultPrevented();
|
||
});
|
||
|
||
// Workaround for browsers which do not support the `input` event
|
||
// This will prevent double-triggering of events for browsers which support
|
||
// both the `keyup` and `input` events.
|
||
this.$search.on('input', function (evt) {
|
||
// Unbind the duplicated `keyup` event
|
||
$(this).off('keyup');
|
||
});
|
||
|
||
this.$search.on('keyup input', function (evt) {
|
||
self.handleSearch(evt);
|
||
});
|
||
|
||
container.on('open', function () {
|
||
self.$search.attr('tabindex', 0);
|
||
|
||
self.$search.focus();
|
||
|
||
window.setTimeout(function () {
|
||
self.$search.focus();
|
||
}, 0);
|
||
});
|
||
|
||
container.on('close', function () {
|
||
self.$search.attr('tabindex', -1);
|
||
|
||
self.$search.val('');
|
||
});
|
||
|
||
container.on('focus', function () {
|
||
if (container.isOpen()) {
|
||
self.$search.focus();
|
||
}
|
||
});
|
||
|
||
container.on('results:all', function (params) {
|
||
if (params.query.term == null || params.query.term === '') {
|
||
var showSearch = self.showSearch(params);
|
||
|
||
if (showSearch) {
|
||
self.$searchContainer.removeClass('select2-search--hide');
|
||
} else {
|
||
self.$searchContainer.addClass('select2-search--hide');
|
||
}
|
||
}
|
||
});
|
||
};
|
||
|
||
Search.prototype.handleSearch = function (evt) {
|
||
if (!this._keyUpPrevented) {
|
||
var input = this.$search.val();
|
||
|
||
this.trigger('query', {
|
||
term: input
|
||
});
|
||
}
|
||
|
||
this._keyUpPrevented = false;
|
||
};
|
||
|
||
Search.prototype.showSearch = function (_, params) {
|
||
return true;
|
||
};
|
||
|
||
return Search;
|
||
});
|
||
|
||
S2.define('select2/dropdown/hidePlaceholder',[
|
||
|
||
], function () {
|
||
function HidePlaceholder (decorated, $element, options, dataAdapter) {
|
||
this.placeholder = this.normalizePlaceholder(options.get('placeholder'));
|
||
|
||
decorated.call(this, $element, options, dataAdapter);
|
||
}
|
||
|
||
HidePlaceholder.prototype.append = function (decorated, data) {
|
||
data.results = this.removePlaceholder(data.results);
|
||
|
||
decorated.call(this, data);
|
||
};
|
||
|
||
HidePlaceholder.prototype.normalizePlaceholder = function (_, placeholder) {
|
||
if (typeof placeholder === 'string') {
|
||
placeholder = {
|
||
id: '',
|
||
text: placeholder
|
||
};
|
||
}
|
||
|
||
return placeholder;
|
||
};
|
||
|
||
HidePlaceholder.prototype.removePlaceholder = function (_, data) {
|
||
var modifiedData = data.slice(0);
|
||
|
||
for (var d = data.length - 1; d >= 0; d--) {
|
||
var item = data[d];
|
||
|
||
if (this.placeholder.id === item.id) {
|
||
modifiedData.splice(d, 1);
|
||
}
|
||
}
|
||
|
||
return modifiedData;
|
||
};
|
||
|
||
return HidePlaceholder;
|
||
});
|
||
|
||
S2.define('select2/dropdown/infiniteScroll',[
|
||
'jquery'
|
||
], function ($) {
|
||
function InfiniteScroll (decorated, $element, options, dataAdapter) {
|
||
this.lastParams = {};
|
||
|
||
decorated.call(this, $element, options, dataAdapter);
|
||
|
||
this.$loadingMore = this.createLoadingMore();
|
||
this.loading = false;
|
||
}
|
||
|
||
InfiniteScroll.prototype.append = function (decorated, data) {
|
||
this.$loadingMore.remove();
|
||
this.loading = false;
|
||
|
||
decorated.call(this, data);
|
||
|
||
if (this.showLoadingMore(data)) {
|
||
this.$results.append(this.$loadingMore);
|
||
}
|
||
};
|
||
|
||
InfiniteScroll.prototype.bind = function (decorated, container, $container) {
|
||
var self = this;
|
||
|
||
decorated.call(this, container, $container);
|
||
|
||
container.on('query', function (params) {
|
||
self.lastParams = params;
|
||
self.loading = true;
|
||
});
|
||
|
||
container.on('query:append', function (params) {
|
||
self.lastParams = params;
|
||
self.loading = true;
|
||
});
|
||
|
||
this.$results.on('scroll', function () {
|
||
var isLoadMoreVisible = $.contains(
|
||
document.documentElement,
|
||
self.$loadingMore[0]
|
||
);
|
||
|
||
if (self.loading || !isLoadMoreVisible) {
|
||
return;
|
||
}
|
||
|
||
var currentOffset = self.$results.offset().top +
|
||
self.$results.outerHeight(false);
|
||
var loadingMoreOffset = self.$loadingMore.offset().top +
|
||
self.$loadingMore.outerHeight(false);
|
||
|
||
if (currentOffset + 50 >= loadingMoreOffset) {
|
||
self.loadMore();
|
||
}
|
||
});
|
||
};
|
||
|
||
InfiniteScroll.prototype.loadMore = function () {
|
||
this.loading = true;
|
||
|
||
var params = $.extend({}, {page: 1}, this.lastParams);
|
||
|
||
params.page++;
|
||
|
||
this.trigger('query:append', params);
|
||
};
|
||
|
||
InfiniteScroll.prototype.showLoadingMore = function (_, data) {
|
||
return data.pagination && data.pagination.more;
|
||
};
|
||
|
||
InfiniteScroll.prototype.createLoadingMore = function () {
|
||
var $option = $(
|
||
'<li ' +
|
||
'class="select2-results__option select2-results__option--load-more"' +
|
||
'role="treeitem" aria-disabled="true"></li>'
|
||
);
|
||
|
||
var message = this.options.get('translations').get('loadingMore');
|
||
|
||
$option.html(message(this.lastParams));
|
||
|
||
return $option;
|
||
};
|
||
|
||
return InfiniteScroll;
|
||
});
|
||
|
||
S2.define('select2/dropdown/attachBody',[
|
||
'jquery',
|
||
'../utils'
|
||
], function ($, Utils) {
|
||
function AttachBody (decorated, $element, options) {
|
||
this.$dropdownParent = options.get('dropdownParent') || $(document.body);
|
||
|
||
decorated.call(this, $element, options);
|
||
}
|
||
|
||
AttachBody.prototype.bind = function (decorated, container, $container) {
|
||
var self = this;
|
||
|
||
var setupResultsEvents = false;
|
||
|
||
decorated.call(this, container, $container);
|
||
|
||
container.on('open', function () {
|
||
self._showDropdown();
|
||
self._attachPositioningHandler(container);
|
||
|
||
if (!setupResultsEvents) {
|
||
setupResultsEvents = true;
|
||
|
||
container.on('results:all', function () {
|
||
self._positionDropdown();
|
||
self._resizeDropdown();
|
||
});
|
||
|
||
container.on('results:append', function () {
|
||
self._positionDropdown();
|
||
self._resizeDropdown();
|
||
});
|
||
}
|
||
});
|
||
|
||
container.on('close', function () {
|
||
self._hideDropdown();
|
||
self._detachPositioningHandler(container);
|
||
});
|
||
|
||
this.$dropdownContainer.on('mousedown', function (evt) {
|
||
evt.stopPropagation();
|
||
});
|
||
};
|
||
|
||
AttachBody.prototype.destroy = function (decorated) {
|
||
decorated.call(this);
|
||
|
||
this.$dropdownContainer.remove();
|
||
};
|
||
|
||
AttachBody.prototype.position = function (decorated, $dropdown, $container) {
|
||
// Clone all of the container classes
|
||
$dropdown.attr('class', $container.attr('class'));
|
||
|
||
$dropdown.removeClass('select2');
|
||
$dropdown.addClass('select2-container--open');
|
||
|
||
$dropdown.css({
|
||
position: 'absolute',
|
||
top: -999999
|
||
});
|
||
|
||
this.$container = $container;
|
||
};
|
||
|
||
AttachBody.prototype.render = function (decorated) {
|
||
var $container = $('<span></span>');
|
||
|
||
var $dropdown = decorated.call(this);
|
||
$container.append($dropdown);
|
||
|
||
this.$dropdownContainer = $container;
|
||
|
||
return $container;
|
||
};
|
||
|
||
AttachBody.prototype._hideDropdown = function (decorated) {
|
||
this.$dropdownContainer.detach();
|
||
};
|
||
|
||
AttachBody.prototype._attachPositioningHandler =
|
||
function (decorated, container) {
|
||
var self = this;
|
||
|
||
var scrollEvent = 'scroll.select2.' + container.id;
|
||
var resizeEvent = 'resize.select2.' + container.id;
|
||
var orientationEvent = 'orientationchange.select2.' + container.id;
|
||
|
||
var $watchers = this.$container.parents().filter(Utils.hasScroll);
|
||
$watchers.each(function () {
|
||
$(this).data('select2-scroll-position', {
|
||
x: $(this).scrollLeft(),
|
||
y: $(this).scrollTop()
|
||
});
|
||
});
|
||
|
||
$watchers.on(scrollEvent, function (ev) {
|
||
var position = $(this).data('select2-scroll-position');
|
||
$(this).scrollTop(position.y);
|
||
});
|
||
|
||
$(window).on(scrollEvent + ' ' + resizeEvent + ' ' + orientationEvent,
|
||
function (e) {
|
||
self._positionDropdown();
|
||
self._resizeDropdown();
|
||
});
|
||
};
|
||
|
||
AttachBody.prototype._detachPositioningHandler =
|
||
function (decorated, container) {
|
||
var scrollEvent = 'scroll.select2.' + container.id;
|
||
var resizeEvent = 'resize.select2.' + container.id;
|
||
var orientationEvent = 'orientationchange.select2.' + container.id;
|
||
|
||
var $watchers = this.$container.parents().filter(Utils.hasScroll);
|
||
$watchers.off(scrollEvent);
|
||
|
||
$(window).off(scrollEvent + ' ' + resizeEvent + ' ' + orientationEvent);
|
||
};
|
||
|
||
AttachBody.prototype._positionDropdown = function () {
|
||
var $window = $(window);
|
||
|
||
var isCurrentlyAbove = this.$dropdown.hasClass('select2-dropdown--above');
|
||
var isCurrentlyBelow = this.$dropdown.hasClass('select2-dropdown--below');
|
||
|
||
var newDirection = null;
|
||
|
||
var offset = this.$container.offset();
|
||
|
||
offset.bottom = offset.top + this.$container.outerHeight(false);
|
||
|
||
var container = {
|
||
height: this.$container.outerHeight(false)
|
||
};
|
||
|
||
container.top = offset.top;
|
||
container.bottom = offset.top + container.height;
|
||
|
||
var dropdown = {
|
||
height: this.$dropdown.outerHeight(false)
|
||
};
|
||
|
||
var viewport = {
|
||
top: $window.scrollTop(),
|
||
bottom: $window.scrollTop() + $window.height()
|
||
};
|
||
|
||
var enoughRoomAbove = viewport.top < (offset.top - dropdown.height);
|
||
var enoughRoomBelow = viewport.bottom > (offset.bottom + dropdown.height);
|
||
|
||
var css = {
|
||
left: offset.left,
|
||
top: container.bottom
|
||
};
|
||
|
||
// Determine what the parent element is to use for calciulating the offset
|
||
var $offsetParent = this.$dropdownParent;
|
||
|
||
// For statically positoned elements, we need to get the element
|
||
// that is determining the offset
|
||
if ($offsetParent.css('position') === 'static') {
|
||
$offsetParent = $offsetParent.offsetParent();
|
||
}
|
||
|
||
var parentOffset = $offsetParent.offset();
|
||
|
||
css.top -= parentOffset.top;
|
||
css.left -= parentOffset.left;
|
||
|
||
if (!isCurrentlyAbove && !isCurrentlyBelow) {
|
||
newDirection = 'below';
|
||
}
|
||
|
||
if (!enoughRoomBelow && enoughRoomAbove && !isCurrentlyAbove) {
|
||
newDirection = 'above';
|
||
} else if (!enoughRoomAbove && enoughRoomBelow && isCurrentlyAbove) {
|
||
newDirection = 'below';
|
||
}
|
||
|
||
if (newDirection == 'above' ||
|
||
(isCurrentlyAbove && newDirection !== 'below')) {
|
||
css.top = container.top - parentOffset.top - dropdown.height;
|
||
}
|
||
|
||
if (newDirection != null) {
|
||
this.$dropdown
|
||
.removeClass('select2-dropdown--below select2-dropdown--above')
|
||
.addClass('select2-dropdown--' + newDirection);
|
||
this.$container
|
||
.removeClass('select2-container--below select2-container--above')
|
||
.addClass('select2-container--' + newDirection);
|
||
}
|
||
|
||
this.$dropdownContainer.css(css);
|
||
};
|
||
|
||
AttachBody.prototype._resizeDropdown = function () {
|
||
var css = {
|
||
width: this.$container.outerWidth(false) + 'px'
|
||
};
|
||
|
||
if (this.options.get('dropdownAutoWidth')) {
|
||
css.minWidth = css.width;
|
||
css.position = 'relative';
|
||
css.width = 'auto';
|
||
}
|
||
|
||
this.$dropdown.css(css);
|
||
};
|
||
|
||
AttachBody.prototype._showDropdown = function (decorated) {
|
||
this.$dropdownContainer.appendTo(this.$dropdownParent);
|
||
|
||
this._positionDropdown();
|
||
this._resizeDropdown();
|
||
};
|
||
|
||
return AttachBody;
|
||
});
|
||
|
||
S2.define('select2/dropdown/minimumResultsForSearch',[
|
||
|
||
], function () {
|
||
function countResults (data) {
|
||
var count = 0;
|
||
|
||
for (var d = 0; d < data.length; d++) {
|
||
var item = data[d];
|
||
|
||
if (item.children) {
|
||
count += countResults(item.children);
|
||
} else {
|
||
count++;
|
||
}
|
||
}
|
||
|
||
return count;
|
||
}
|
||
|
||
function MinimumResultsForSearch (decorated, $element, options, dataAdapter) {
|
||
this.minimumResultsForSearch = options.get('minimumResultsForSearch');
|
||
|
||
if (this.minimumResultsForSearch < 0) {
|
||
this.minimumResultsForSearch = Infinity;
|
||
}
|
||
|
||
decorated.call(this, $element, options, dataAdapter);
|
||
}
|
||
|
||
MinimumResultsForSearch.prototype.showSearch = function (decorated, params) {
|
||
if (countResults(params.data.results) < this.minimumResultsForSearch) {
|
||
return false;
|
||
}
|
||
|
||
return decorated.call(this, params);
|
||
};
|
||
|
||
return MinimumResultsForSearch;
|
||
});
|
||
|
||
S2.define('select2/dropdown/selectOnClose',[
|
||
|
||
], function () {
|
||
function SelectOnClose () { }
|
||
|
||
SelectOnClose.prototype.bind = function (decorated, container, $container) {
|
||
var self = this;
|
||
|
||
decorated.call(this, container, $container);
|
||
|
||
container.on('close', function (params) {
|
||
self._handleSelectOnClose(params);
|
||
});
|
||
};
|
||
|
||
SelectOnClose.prototype._handleSelectOnClose = function (_, params) {
|
||
if (params && params.originalSelect2Event != null) {
|
||
var event = params.originalSelect2Event;
|
||
|
||
// Don't select an item if the close event was triggered from a select or
|
||
// unselect event
|
||
if (event._type === 'select' || event._type === 'unselect') {
|
||
return;
|
||
}
|
||
}
|
||
|
||
var $highlightedResults = this.getHighlightedResults();
|
||
|
||
// Only select highlighted results
|
||
if ($highlightedResults.length < 1) {
|
||
return;
|
||
}
|
||
|
||
var data = $highlightedResults.data('data');
|
||
|
||
// Don't re-select already selected resulte
|
||
if (
|
||
(data.element != null && data.element.selected) ||
|
||
(data.element == null && data.selected)
|
||
) {
|
||
return;
|
||
}
|
||
|
||
this.trigger('select', {
|
||
data: data
|
||
});
|
||
};
|
||
|
||
return SelectOnClose;
|
||
});
|
||
|
||
S2.define('select2/dropdown/closeOnSelect',[
|
||
|
||
], function () {
|
||
function CloseOnSelect () { }
|
||
|
||
CloseOnSelect.prototype.bind = function (decorated, container, $container) {
|
||
var self = this;
|
||
|
||
decorated.call(this, container, $container);
|
||
|
||
container.on('select', function (evt) {
|
||
self._selectTriggered(evt);
|
||
});
|
||
|
||
container.on('unselect', function (evt) {
|
||
self._selectTriggered(evt);
|
||
});
|
||
};
|
||
|
||
CloseOnSelect.prototype._selectTriggered = function (_, evt) {
|
||
var originalEvent = evt.originalEvent;
|
||
|
||
// Don't close if the control key is being held
|
||
if (originalEvent && originalEvent.ctrlKey) {
|
||
return;
|
||
}
|
||
|
||
this.trigger('close', {
|
||
originalEvent: originalEvent,
|
||
originalSelect2Event: evt
|
||
});
|
||
};
|
||
|
||
return CloseOnSelect;
|
||
});
|
||
|
||
S2.define('select2/i18n/en',[],function () {
|
||
// English
|
||
return {
|
||
errorLoading: function () {
|
||
return 'The results could not be loaded.';
|
||
},
|
||
inputTooLong: function (args) {
|
||
var overChars = args.input.length - args.maximum;
|
||
|
||
var message = 'Please delete ' + overChars + ' character';
|
||
|
||
if (overChars != 1) {
|
||
message += 's';
|
||
}
|
||
|
||
return message;
|
||
},
|
||
inputTooShort: function (args) {
|
||
var remainingChars = args.minimum - args.input.length;
|
||
|
||
var message = 'Please enter ' + remainingChars + ' or more characters';
|
||
|
||
return message;
|
||
},
|
||
loadingMore: function () {
|
||
return 'Loading more results…';
|
||
},
|
||
maximumSelected: function (args) {
|
||
var message = 'You can only select ' + args.maximum + ' item';
|
||
|
||
if (args.maximum != 1) {
|
||
message += 's';
|
||
}
|
||
|
||
return message;
|
||
},
|
||
noResults: function () {
|
||
return 'No results found';
|
||
},
|
||
searching: function () {
|
||
return 'Searching…';
|
||
}
|
||
};
|
||
});
|
||
|
||
S2.define('select2/defaults',[
|
||
'jquery',
|
||
'require',
|
||
|
||
'./results',
|
||
|
||
'./selection/single',
|
||
'./selection/multiple',
|
||
'./selection/placeholder',
|
||
'./selection/allowClear',
|
||
'./selection/search',
|
||
'./selection/eventRelay',
|
||
|
||
'./utils',
|
||
'./translation',
|
||
'./diacritics',
|
||
|
||
'./data/select',
|
||
'./data/array',
|
||
'./data/ajax',
|
||
'./data/tags',
|
||
'./data/tokenizer',
|
||
'./data/minimumInputLength',
|
||
'./data/maximumInputLength',
|
||
'./data/maximumSelectionLength',
|
||
|
||
'./dropdown',
|
||
'./dropdown/search',
|
||
'./dropdown/hidePlaceholder',
|
||
'./dropdown/infiniteScroll',
|
||
'./dropdown/attachBody',
|
||
'./dropdown/minimumResultsForSearch',
|
||
'./dropdown/selectOnClose',
|
||
'./dropdown/closeOnSelect',
|
||
|
||
'./i18n/en'
|
||
], function ($, require,
|
||
|
||
ResultsList,
|
||
|
||
SingleSelection, MultipleSelection, Placeholder, AllowClear,
|
||
SelectionSearch, EventRelay,
|
||
|
||
Utils, Translation, DIACRITICS,
|
||
|
||
SelectData, ArrayData, AjaxData, Tags, Tokenizer,
|
||
MinimumInputLength, MaximumInputLength, MaximumSelectionLength,
|
||
|
||
Dropdown, DropdownSearch, HidePlaceholder, InfiniteScroll,
|
||
AttachBody, MinimumResultsForSearch, SelectOnClose, CloseOnSelect,
|
||
|
||
EnglishTranslation) {
|
||
function Defaults () {
|
||
this.reset();
|
||
}
|
||
|
||
Defaults.prototype.apply = function (options) {
|
||
options = $.extend(true, {}, this.defaults, options);
|
||
|
||
if (options.dataAdapter == null) {
|
||
if (options.ajax != null) {
|
||
options.dataAdapter = AjaxData;
|
||
} else if (options.data != null) {
|
||
options.dataAdapter = ArrayData;
|
||
} else {
|
||
options.dataAdapter = SelectData;
|
||
}
|
||
|
||
if (options.minimumInputLength > 0) {
|
||
options.dataAdapter = Utils.Decorate(
|
||
options.dataAdapter,
|
||
MinimumInputLength
|
||
);
|
||
}
|
||
|
||
if (options.maximumInputLength > 0) {
|
||
options.dataAdapter = Utils.Decorate(
|
||
options.dataAdapter,
|
||
MaximumInputLength
|
||
);
|
||
}
|
||
|
||
if (options.maximumSelectionLength > 0) {
|
||
options.dataAdapter = Utils.Decorate(
|
||
options.dataAdapter,
|
||
MaximumSelectionLength
|
||
);
|
||
}
|
||
|
||
if (options.tags) {
|
||
options.dataAdapter = Utils.Decorate(options.dataAdapter, Tags);
|
||
}
|
||
|
||
if (options.tokenSeparators != null || options.tokenizer != null) {
|
||
options.dataAdapter = Utils.Decorate(
|
||
options.dataAdapter,
|
||
Tokenizer
|
||
);
|
||
}
|
||
|
||
if (options.query != null) {
|
||
var Query = require(options.amdBase + 'compat/query');
|
||
|
||
options.dataAdapter = Utils.Decorate(
|
||
options.dataAdapter,
|
||
Query
|
||
);
|
||
}
|
||
|
||
if (options.initSelection != null) {
|
||
var InitSelection = require(options.amdBase + 'compat/initSelection');
|
||
|
||
options.dataAdapter = Utils.Decorate(
|
||
options.dataAdapter,
|
||
InitSelection
|
||
);
|
||
}
|
||
}
|
||
|
||
if (options.resultsAdapter == null) {
|
||
options.resultsAdapter = ResultsList;
|
||
|
||
if (options.ajax != null) {
|
||
options.resultsAdapter = Utils.Decorate(
|
||
options.resultsAdapter,
|
||
InfiniteScroll
|
||
);
|
||
}
|
||
|
||
if (options.placeholder != null) {
|
||
options.resultsAdapter = Utils.Decorate(
|
||
options.resultsAdapter,
|
||
HidePlaceholder
|
||
);
|
||
}
|
||
|
||
if (options.selectOnClose) {
|
||
options.resultsAdapter = Utils.Decorate(
|
||
options.resultsAdapter,
|
||
SelectOnClose
|
||
);
|
||
}
|
||
}
|
||
|
||
if (options.dropdownAdapter == null) {
|
||
if (options.multiple) {
|
||
options.dropdownAdapter = Dropdown;
|
||
} else {
|
||
var SearchableDropdown = Utils.Decorate(Dropdown, DropdownSearch);
|
||
|
||
options.dropdownAdapter = SearchableDropdown;
|
||
}
|
||
|
||
if (options.minimumResultsForSearch !== 0) {
|
||
options.dropdownAdapter = Utils.Decorate(
|
||
options.dropdownAdapter,
|
||
MinimumResultsForSearch
|
||
);
|
||
}
|
||
|
||
if (options.closeOnSelect) {
|
||
options.dropdownAdapter = Utils.Decorate(
|
||
options.dropdownAdapter,
|
||
CloseOnSelect
|
||
);
|
||
}
|
||
|
||
if (
|
||
options.dropdownCssClass != null ||
|
||
options.dropdownCss != null ||
|
||
options.adaptDropdownCssClass != null
|
||
) {
|
||
var DropdownCSS = require(options.amdBase + 'compat/dropdownCss');
|
||
|
||
options.dropdownAdapter = Utils.Decorate(
|
||
options.dropdownAdapter,
|
||
DropdownCSS
|
||
);
|
||
}
|
||
|
||
options.dropdownAdapter = Utils.Decorate(
|
||
options.dropdownAdapter,
|
||
AttachBody
|
||
);
|
||
}
|
||
|
||
if (options.selectionAdapter == null) {
|
||
if (options.multiple) {
|
||
options.selectionAdapter = MultipleSelection;
|
||
} else {
|
||
options.selectionAdapter = SingleSelection;
|
||
}
|
||
|
||
// Add the placeholder mixin if a placeholder was specified
|
||
if (options.placeholder != null) {
|
||
options.selectionAdapter = Utils.Decorate(
|
||
options.selectionAdapter,
|
||
Placeholder
|
||
);
|
||
}
|
||
|
||
if (options.allowClear) {
|
||
options.selectionAdapter = Utils.Decorate(
|
||
options.selectionAdapter,
|
||
AllowClear
|
||
);
|
||
}
|
||
|
||
if (options.multiple) {
|
||
options.selectionAdapter = Utils.Decorate(
|
||
options.selectionAdapter,
|
||
SelectionSearch
|
||
);
|
||
}
|
||
|
||
if (
|
||
options.containerCssClass != null ||
|
||
options.containerCss != null ||
|
||
options.adaptContainerCssClass != null
|
||
) {
|
||
var ContainerCSS = require(options.amdBase + 'compat/containerCss');
|
||
|
||
options.selectionAdapter = Utils.Decorate(
|
||
options.selectionAdapter,
|
||
ContainerCSS
|
||
);
|
||
}
|
||
|
||
options.selectionAdapter = Utils.Decorate(
|
||
options.selectionAdapter,
|
||
EventRelay
|
||
);
|
||
}
|
||
|
||
if (typeof options.language === 'string') {
|
||
// Check if the language is specified with a region
|
||
if (options.language.indexOf('-') > 0) {
|
||
// Extract the region information if it is included
|
||
var languageParts = options.language.split('-');
|
||
var baseLanguage = languageParts[0];
|
||
|
||
options.language = [options.language, baseLanguage];
|
||
} else {
|
||
options.language = [options.language];
|
||
}
|
||
}
|
||
|
||
if ($.isArray(options.language)) {
|
||
var languages = new Translation();
|
||
options.language.push('en');
|
||
|
||
var languageNames = options.language;
|
||
|
||
for (var l = 0; l < languageNames.length; l++) {
|
||
var name = languageNames[l];
|
||
var language = {};
|
||
|
||
try {
|
||
// Try to load it with the original name
|
||
language = Translation.loadPath(name);
|
||
} catch (e) {
|
||
try {
|
||
// If we couldn't load it, check if it wasn't the full path
|
||
name = this.defaults.amdLanguageBase + name;
|
||
language = Translation.loadPath(name);
|
||
} catch (ex) {
|
||
// The translation could not be loaded at all. Sometimes this is
|
||
// because of a configuration problem, other times this can be
|
||
// because of how Select2 helps load all possible translation files.
|
||
if (options.debug && window.console && console.warn) {
|
||
console.warn(
|
||
'Select2: The language file for "' + name + '" could not be ' +
|
||
'automatically loaded. A fallback will be used instead.'
|
||
);
|
||
}
|
||
|
||
continue;
|
||
}
|
||
}
|
||
|
||
languages.extend(language);
|
||
}
|
||
|
||
options.translations = languages;
|
||
} else {
|
||
var baseTranslation = Translation.loadPath(
|
||
this.defaults.amdLanguageBase + 'en'
|
||
);
|
||
var customTranslation = new Translation(options.language);
|
||
|
||
customTranslation.extend(baseTranslation);
|
||
|
||
options.translations = customTranslation;
|
||
}
|
||
|
||
return options;
|
||
};
|
||
|
||
Defaults.prototype.reset = function () {
|
||
function stripDiacritics (text) {
|
||
// Used 'uni range + named function' from http://jsperf.com/diacritics/18
|
||
function match(a) {
|
||
return DIACRITICS[a] || a;
|
||
}
|
||
|
||
return text.replace(/[^\u0000-\u007E]/g, match);
|
||
}
|
||
|
||
function matcher (params, data) {
|
||
// Always return the object if there is nothing to compare
|
||
if ($.trim(params.term) === '') {
|
||
return data;
|
||
}
|
||
|
||
// Do a recursive check for options with children
|
||
if (data.children && data.children.length > 0) {
|
||
// Clone the data object if there are children
|
||
// This is required as we modify the object to remove any non-matches
|
||
var match = $.extend(true, {}, data);
|
||
|
||
// Check each child of the option
|
||
for (var c = data.children.length - 1; c >= 0; c--) {
|
||
var child = data.children[c];
|
||
|
||
var matches = matcher(params, child);
|
||
|
||
// If there wasn't a match, remove the object in the array
|
||
if (matches == null) {
|
||
match.children.splice(c, 1);
|
||
}
|
||
}
|
||
|
||
// If any children matched, return the new object
|
||
if (match.children.length > 0) {
|
||
return match;
|
||
}
|
||
|
||
// If there were no matching children, check just the plain object
|
||
return matcher(params, match);
|
||
}
|
||
|
||
var original = stripDiacritics(data.text).toUpperCase();
|
||
var term = stripDiacritics(params.term).toUpperCase();
|
||
|
||
// Check if the text contains the term
|
||
if (original.indexOf(term) > -1) {
|
||
return data;
|
||
}
|
||
|
||
// If it doesn't contain the term, don't return anything
|
||
return null;
|
||
}
|
||
|
||
this.defaults = {
|
||
amdBase: './',
|
||
amdLanguageBase: './i18n/',
|
||
closeOnSelect: true,
|
||
debug: false,
|
||
dropdownAutoWidth: false,
|
||
escapeMarkup: Utils.escapeMarkup,
|
||
language: EnglishTranslation,
|
||
matcher: matcher,
|
||
minimumInputLength: 0,
|
||
maximumInputLength: 0,
|
||
maximumSelectionLength: 0,
|
||
minimumResultsForSearch: 0,
|
||
selectOnClose: false,
|
||
sorter: function (data) {
|
||
return data;
|
||
},
|
||
templateResult: function (result) {
|
||
return result.text;
|
||
},
|
||
templateSelection: function (selection) {
|
||
return selection.text;
|
||
},
|
||
theme: 'default',
|
||
width: 'resolve'
|
||
};
|
||
};
|
||
|
||
Defaults.prototype.set = function (key, value) {
|
||
var camelKey = $.camelCase(key);
|
||
|
||
var data = {};
|
||
data[camelKey] = value;
|
||
|
||
var convertedData = Utils._convertData(data);
|
||
|
||
$.extend(this.defaults, convertedData);
|
||
};
|
||
|
||
var defaults = new Defaults();
|
||
|
||
return defaults;
|
||
});
|
||
|
||
S2.define('select2/options',[
|
||
'require',
|
||
'jquery',
|
||
'./defaults',
|
||
'./utils'
|
||
], function (require, $, Defaults, Utils) {
|
||
function Options (options, $element) {
|
||
this.options = options;
|
||
|
||
if ($element != null) {
|
||
this.fromElement($element);
|
||
}
|
||
|
||
this.options = Defaults.apply(this.options);
|
||
|
||
if ($element && $element.is('input')) {
|
||
var InputCompat = require(this.get('amdBase') + 'compat/inputData');
|
||
|
||
this.options.dataAdapter = Utils.Decorate(
|
||
this.options.dataAdapter,
|
||
InputCompat
|
||
);
|
||
}
|
||
}
|
||
|
||
Options.prototype.fromElement = function ($e) {
|
||
var excludedData = ['select2'];
|
||
|
||
if (this.options.multiple == null) {
|
||
this.options.multiple = $e.prop('multiple');
|
||
}
|
||
|
||
if (this.options.disabled == null) {
|
||
this.options.disabled = $e.prop('disabled');
|
||
}
|
||
|
||
if (this.options.language == null) {
|
||
if ($e.prop('lang')) {
|
||
this.options.language = $e.prop('lang').toLowerCase();
|
||
} else if ($e.closest('[lang]').prop('lang')) {
|
||
this.options.language = $e.closest('[lang]').prop('lang');
|
||
}
|
||
}
|
||
|
||
if (this.options.dir == null) {
|
||
if ($e.prop('dir')) {
|
||
this.options.dir = $e.prop('dir');
|
||
} else if ($e.closest('[dir]').prop('dir')) {
|
||
this.options.dir = $e.closest('[dir]').prop('dir');
|
||
} else {
|
||
this.options.dir = 'ltr';
|
||
}
|
||
}
|
||
|
||
$e.prop('disabled', this.options.disabled);
|
||
$e.prop('multiple', this.options.multiple);
|
||
|
||
if ($e.data('select2Tags')) {
|
||
if (this.options.debug && window.console && console.warn) {
|
||
console.warn(
|
||
'Select2: The `data-select2-tags` attribute has been changed to ' +
|
||
'use the `data-data` and `data-tags="true"` attributes and will be ' +
|
||
'removed in future versions of Select2.'
|
||
);
|
||
}
|
||
|
||
$e.data('data', $e.data('select2Tags'));
|
||
$e.data('tags', true);
|
||
}
|
||
|
||
if ($e.data('ajaxUrl')) {
|
||
if (this.options.debug && window.console && console.warn) {
|
||
console.warn(
|
||
'Select2: The `data-ajax-url` attribute has been changed to ' +
|
||
'`data-ajax--url` and support for the old attribute will be removed' +
|
||
' in future versions of Select2.'
|
||
);
|
||
}
|
||
|
||
$e.attr('ajax--url', $e.data('ajaxUrl'));
|
||
$e.data('ajax--url', $e.data('ajaxUrl'));
|
||
}
|
||
|
||
var dataset = {};
|
||
|
||
// Prefer the element's `dataset` attribute if it exists
|
||
// jQuery 1.x does not correctly handle data attributes with multiple dashes
|
||
if ($.fn.jquery && $.fn.jquery.substr(0, 2) == '1.' && $e[0].dataset) {
|
||
dataset = $.extend(true, {}, $e[0].dataset, $e.data());
|
||
} else {
|
||
dataset = $e.data();
|
||
}
|
||
|
||
var data = $.extend(true, {}, dataset);
|
||
|
||
data = Utils._convertData(data);
|
||
|
||
for (var key in data) {
|
||
if ($.inArray(key, excludedData) > -1) {
|
||
continue;
|
||
}
|
||
|
||
if ($.isPlainObject(this.options[key])) {
|
||
$.extend(this.options[key], data[key]);
|
||
} else {
|
||
this.options[key] = data[key];
|
||
}
|
||
}
|
||
|
||
return this;
|
||
};
|
||
|
||
Options.prototype.get = function (key) {
|
||
return this.options[key];
|
||
};
|
||
|
||
Options.prototype.set = function (key, val) {
|
||
this.options[key] = val;
|
||
};
|
||
|
||
return Options;
|
||
});
|
||
|
||
S2.define('select2/core',[
|
||
'jquery',
|
||
'./options',
|
||
'./utils',
|
||
'./keys'
|
||
], function ($, Options, Utils, KEYS) {
|
||
var Select2 = function ($element, options) {
|
||
if ($element.data('select2') != null) {
|
||
$element.data('select2').destroy();
|
||
}
|
||
|
||
this.$element = $element;
|
||
|
||
this.id = this._generateId($element);
|
||
|
||
options = options || {};
|
||
|
||
this.options = new Options(options, $element);
|
||
|
||
Select2.__super__.constructor.call(this);
|
||
|
||
// Set up the tabindex
|
||
|
||
var tabindex = $element.attr('tabindex') || 0;
|
||
$element.data('old-tabindex', tabindex);
|
||
$element.attr('tabindex', '-1');
|
||
|
||
// Set up containers and adapters
|
||
|
||
var DataAdapter = this.options.get('dataAdapter');
|
||
this.dataAdapter = new DataAdapter($element, this.options);
|
||
|
||
var $container = this.render();
|
||
|
||
this._placeContainer($container);
|
||
|
||
var SelectionAdapter = this.options.get('selectionAdapter');
|
||
this.selection = new SelectionAdapter($element, this.options);
|
||
this.$selection = this.selection.render();
|
||
|
||
this.selection.position(this.$selection, $container);
|
||
|
||
var DropdownAdapter = this.options.get('dropdownAdapter');
|
||
this.dropdown = new DropdownAdapter($element, this.options);
|
||
this.$dropdown = this.dropdown.render();
|
||
|
||
this.dropdown.position(this.$dropdown, $container);
|
||
|
||
var ResultsAdapter = this.options.get('resultsAdapter');
|
||
this.results = new ResultsAdapter($element, this.options, this.dataAdapter);
|
||
this.$results = this.results.render();
|
||
|
||
this.results.position(this.$results, this.$dropdown);
|
||
|
||
// Bind events
|
||
|
||
var self = this;
|
||
|
||
// Bind the container to all of the adapters
|
||
this._bindAdapters();
|
||
|
||
// Register any DOM event handlers
|
||
this._registerDomEvents();
|
||
|
||
// Register any internal event handlers
|
||
this._registerDataEvents();
|
||
this._registerSelectionEvents();
|
||
this._registerDropdownEvents();
|
||
this._registerResultsEvents();
|
||
this._registerEvents();
|
||
|
||
// Set the initial state
|
||
this.dataAdapter.current(function (initialData) {
|
||
self.trigger('selection:update', {
|
||
data: initialData
|
||
});
|
||
});
|
||
|
||
// Hide the original select
|
||
$element.addClass('select2-hidden-accessible');
|
||
$element.attr('aria-hidden', 'true');
|
||
|
||
// Synchronize any monitored attributes
|
||
this._syncAttributes();
|
||
|
||
$element.data('select2', this);
|
||
};
|
||
|
||
Utils.Extend(Select2, Utils.Observable);
|
||
|
||
Select2.prototype._generateId = function ($element) {
|
||
var id = '';
|
||
|
||
if ($element.attr('id') != null) {
|
||
id = $element.attr('id');
|
||
} else if ($element.attr('name') != null) {
|
||
id = $element.attr('name') + '-' + Utils.generateChars(2);
|
||
} else {
|
||
id = Utils.generateChars(4);
|
||
}
|
||
|
||
id = id.replace(/(:|\.|\[|\]|,)/g, '');
|
||
id = 'select2-' + id;
|
||
|
||
return id;
|
||
};
|
||
|
||
Select2.prototype._placeContainer = function ($container) {
|
||
$container.insertAfter(this.$element);
|
||
|
||
var width = this._resolveWidth(this.$element, this.options.get('width'));
|
||
|
||
if (width != null) {
|
||
$container.css('width', width);
|
||
}
|
||
};
|
||
|
||
Select2.prototype._resolveWidth = function ($element, method) {
|
||
var WIDTH = /^width:(([-+]?([0-9]*\.)?[0-9]+)(px|em|ex|%|in|cm|mm|pt|pc))/i;
|
||
|
||
if (method == 'resolve') {
|
||
var styleWidth = this._resolveWidth($element, 'style');
|
||
|
||
if (styleWidth != null) {
|
||
return styleWidth;
|
||
}
|
||
|
||
return this._resolveWidth($element, 'element');
|
||
}
|
||
|
||
if (method == 'element') {
|
||
var elementWidth = $element.outerWidth(false);
|
||
|
||
if (elementWidth <= 0) {
|
||
return 'auto';
|
||
}
|
||
|
||
return elementWidth + 'px';
|
||
}
|
||
|
||
if (method == 'style') {
|
||
var style = $element.attr('style');
|
||
|
||
if (typeof(style) !== 'string') {
|
||
return null;
|
||
}
|
||
|
||
var attrs = style.split(';');
|
||
|
||
for (var i = 0, l = attrs.length; i < l; i = i + 1) {
|
||
var attr = attrs[i].replace(/\s/g, '');
|
||
var matches = attr.match(WIDTH);
|
||
|
||
if (matches !== null && matches.length >= 1) {
|
||
return matches[1];
|
||
}
|
||
}
|
||
|
||
return null;
|
||
}
|
||
|
||
return method;
|
||
};
|
||
|
||
Select2.prototype._bindAdapters = function () {
|
||
this.dataAdapter.bind(this, this.$container);
|
||
this.selection.bind(this, this.$container);
|
||
|
||
this.dropdown.bind(this, this.$container);
|
||
this.results.bind(this, this.$container);
|
||
};
|
||
|
||
Select2.prototype._registerDomEvents = function () {
|
||
var self = this;
|
||
|
||
this.$element.on('change.select2', function () {
|
||
self.dataAdapter.current(function (data) {
|
||
self.trigger('selection:update', {
|
||
data: data
|
||
});
|
||
});
|
||
});
|
||
|
||
this.$element.on('focus.select2', function (evt) {
|
||
self.trigger('focus', evt);
|
||
});
|
||
|
||
this._syncA = Utils.bind(this._syncAttributes, this);
|
||
this._syncS = Utils.bind(this._syncSubtree, this);
|
||
|
||
if (this.$element[0].attachEvent) {
|
||
this.$element[0].attachEvent('onpropertychange', this._syncA);
|
||
}
|
||
|
||
var observer = window.MutationObserver ||
|
||
window.WebKitMutationObserver ||
|
||
window.MozMutationObserver
|
||
;
|
||
|
||
if (observer != null) {
|
||
this._observer = new observer(function (mutations) {
|
||
$.each(mutations, self._syncA);
|
||
$.each(mutations, self._syncS);
|
||
});
|
||
this._observer.observe(this.$element[0], {
|
||
attributes: true,
|
||
childList: true,
|
||
subtree: false
|
||
});
|
||
} else if (this.$element[0].addEventListener) {
|
||
this.$element[0].addEventListener(
|
||
'DOMAttrModified',
|
||
self._syncA,
|
||
false
|
||
);
|
||
this.$element[0].addEventListener(
|
||
'DOMNodeInserted',
|
||
self._syncS,
|
||
false
|
||
);
|
||
this.$element[0].addEventListener(
|
||
'DOMNodeRemoved',
|
||
self._syncS,
|
||
false
|
||
);
|
||
}
|
||
};
|
||
|
||
Select2.prototype._registerDataEvents = function () {
|
||
var self = this;
|
||
|
||
this.dataAdapter.on('*', function (name, params) {
|
||
self.trigger(name, params);
|
||
});
|
||
};
|
||
|
||
Select2.prototype._registerSelectionEvents = function () {
|
||
var self = this;
|
||
var nonRelayEvents = ['toggle', 'focus'];
|
||
|
||
this.selection.on('toggle', function () {
|
||
self.toggleDropdown();
|
||
});
|
||
|
||
this.selection.on('focus', function (params) {
|
||
self.focus(params);
|
||
});
|
||
|
||
this.selection.on('*', function (name, params) {
|
||
if ($.inArray(name, nonRelayEvents) !== -1) {
|
||
return;
|
||
}
|
||
|
||
self.trigger(name, params);
|
||
});
|
||
};
|
||
|
||
Select2.prototype._registerDropdownEvents = function () {
|
||
var self = this;
|
||
|
||
this.dropdown.on('*', function (name, params) {
|
||
self.trigger(name, params);
|
||
});
|
||
};
|
||
|
||
Select2.prototype._registerResultsEvents = function () {
|
||
var self = this;
|
||
|
||
this.results.on('*', function (name, params) {
|
||
self.trigger(name, params);
|
||
});
|
||
};
|
||
|
||
Select2.prototype._registerEvents = function () {
|
||
var self = this;
|
||
|
||
this.on('open', function () {
|
||
self.$container.addClass('select2-container--open');
|
||
});
|
||
|
||
this.on('close', function () {
|
||
self.$container.removeClass('select2-container--open');
|
||
});
|
||
|
||
this.on('enable', function () {
|
||
self.$container.removeClass('select2-container--disabled');
|
||
});
|
||
|
||
this.on('disable', function () {
|
||
self.$container.addClass('select2-container--disabled');
|
||
});
|
||
|
||
this.on('blur', function () {
|
||
self.$container.removeClass('select2-container--focus');
|
||
});
|
||
|
||
this.on('query', function (params) {
|
||
if (!self.isOpen()) {
|
||
self.trigger('open', {});
|
||
}
|
||
|
||
this.dataAdapter.query(params, function (data) {
|
||
self.trigger('results:all', {
|
||
data: data,
|
||
query: params
|
||
});
|
||
});
|
||
});
|
||
|
||
this.on('query:append', function (params) {
|
||
this.dataAdapter.query(params, function (data) {
|
||
self.trigger('results:append', {
|
||
data: data,
|
||
query: params
|
||
});
|
||
});
|
||
});
|
||
|
||
this.on('keypress', function (evt) {
|
||
var key = evt.which;
|
||
|
||
if (self.isOpen()) {
|
||
if (key === KEYS.ESC || key === KEYS.TAB ||
|
||
(key === KEYS.UP && evt.altKey)) {
|
||
self.close();
|
||
|
||
evt.preventDefault();
|
||
} else if (key === KEYS.ENTER) {
|
||
self.trigger('results:select', {});
|
||
|
||
evt.preventDefault();
|
||
} else if ((key === KEYS.SPACE && evt.ctrlKey)) {
|
||
self.trigger('results:toggle', {});
|
||
|
||
evt.preventDefault();
|
||
} else if (key === KEYS.UP) {
|
||
self.trigger('results:previous', {});
|
||
|
||
evt.preventDefault();
|
||
} else if (key === KEYS.DOWN) {
|
||
self.trigger('results:next', {});
|
||
|
||
evt.preventDefault();
|
||
}
|
||
} else {
|
||
if (key === KEYS.ENTER || key === KEYS.SPACE ||
|
||
(key === KEYS.DOWN && evt.altKey)) {
|
||
self.open();
|
||
|
||
evt.preventDefault();
|
||
}
|
||
}
|
||
});
|
||
};
|
||
|
||
Select2.prototype._syncAttributes = function () {
|
||
this.options.set('disabled', this.$element.prop('disabled'));
|
||
|
||
if (this.options.get('disabled')) {
|
||
if (this.isOpen()) {
|
||
this.close();
|
||
}
|
||
|
||
this.trigger('disable', {});
|
||
} else {
|
||
this.trigger('enable', {});
|
||
}
|
||
};
|
||
|
||
Select2.prototype._syncSubtree = function (evt, mutations) {
|
||
var changed = false;
|
||
var self = this;
|
||
|
||
// Ignore any mutation events raised for elements that aren't options or
|
||
// optgroups. This handles the case when the select element is destroyed
|
||
if (
|
||
evt && evt.target && (
|
||
evt.target.nodeName !== 'OPTION' && evt.target.nodeName !== 'OPTGROUP'
|
||
)
|
||
) {
|
||
return;
|
||
}
|
||
|
||
if (!mutations) {
|
||
// If mutation events aren't supported, then we can only assume that the
|
||
// change affected the selections
|
||
changed = true;
|
||
} else if (mutations.addedNodes && mutations.addedNodes.length > 0) {
|
||
for (var n = 0; n < mutations.addedNodes.length; n++) {
|
||
var node = mutations.addedNodes[n];
|
||
|
||
if (node.selected) {
|
||
changed = true;
|
||
}
|
||
}
|
||
} else if (mutations.removedNodes && mutations.removedNodes.length > 0) {
|
||
changed = true;
|
||
}
|
||
|
||
// Only re-pull the data if we think there is a change
|
||
if (changed) {
|
||
this.dataAdapter.current(function (currentData) {
|
||
self.trigger('selection:update', {
|
||
data: currentData
|
||
});
|
||
});
|
||
}
|
||
};
|
||
|
||
/**
|
||
* Override the trigger method to automatically trigger pre-events when
|
||
* there are events that can be prevented.
|
||
*/
|
||
Select2.prototype.trigger = function (name, args) {
|
||
var actualTrigger = Select2.__super__.trigger;
|
||
var preTriggerMap = {
|
||
'open': 'opening',
|
||
'close': 'closing',
|
||
'select': 'selecting',
|
||
'unselect': 'unselecting'
|
||
};
|
||
|
||
if (args === undefined) {
|
||
args = {};
|
||
}
|
||
|
||
if (name in preTriggerMap) {
|
||
var preTriggerName = preTriggerMap[name];
|
||
var preTriggerArgs = {
|
||
prevented: false,
|
||
name: name,
|
||
args: args
|
||
};
|
||
|
||
actualTrigger.call(this, preTriggerName, preTriggerArgs);
|
||
|
||
if (preTriggerArgs.prevented) {
|
||
args.prevented = true;
|
||
|
||
return;
|
||
}
|
||
}
|
||
|
||
actualTrigger.call(this, name, args);
|
||
};
|
||
|
||
Select2.prototype.toggleDropdown = function () {
|
||
if (this.options.get('disabled')) {
|
||
return;
|
||
}
|
||
|
||
if (this.isOpen()) {
|
||
this.close();
|
||
} else {
|
||
this.open();
|
||
}
|
||
};
|
||
|
||
Select2.prototype.open = function () {
|
||
if (this.isOpen()) {
|
||
return;
|
||
}
|
||
|
||
this.trigger('query', {});
|
||
};
|
||
|
||
Select2.prototype.close = function () {
|
||
if (!this.isOpen()) {
|
||
return;
|
||
}
|
||
|
||
this.trigger('close', {});
|
||
};
|
||
|
||
Select2.prototype.isOpen = function () {
|
||
return this.$container.hasClass('select2-container--open');
|
||
};
|
||
|
||
Select2.prototype.hasFocus = function () {
|
||
return this.$container.hasClass('select2-container--focus');
|
||
};
|
||
|
||
Select2.prototype.focus = function (data) {
|
||
// No need to re-trigger focus events if we are already focused
|
||
if (this.hasFocus()) {
|
||
return;
|
||
}
|
||
|
||
this.$container.addClass('select2-container--focus');
|
||
this.trigger('focus', {});
|
||
};
|
||
|
||
Select2.prototype.enable = function (args) {
|
||
if (this.options.get('debug') && window.console && console.warn) {
|
||
console.warn(
|
||
'Select2: The `select2("enable")` method has been deprecated and will' +
|
||
' be removed in later Select2 versions. Use $element.prop("disabled")' +
|
||
' instead.'
|
||
);
|
||
}
|
||
|
||
if (args == null || args.length === 0) {
|
||
args = [true];
|
||
}
|
||
|
||
var disabled = !args[0];
|
||
|
||
this.$element.prop('disabled', disabled);
|
||
};
|
||
|
||
Select2.prototype.data = function () {
|
||
if (this.options.get('debug') &&
|
||
arguments.length > 0 && window.console && console.warn) {
|
||
console.warn(
|
||
'Select2: Data can no longer be set using `select2("data")`. You ' +
|
||
'should consider setting the value instead using `$element.val()`.'
|
||
);
|
||
}
|
||
|
||
var data = [];
|
||
|
||
this.dataAdapter.current(function (currentData) {
|
||
data = currentData;
|
||
});
|
||
|
||
return data;
|
||
};
|
||
|
||
Select2.prototype.val = function (args) {
|
||
if (this.options.get('debug') && window.console && console.warn) {
|
||
console.warn(
|
||
'Select2: The `select2("val")` method has been deprecated and will be' +
|
||
' removed in later Select2 versions. Use $element.val() instead.'
|
||
);
|
||
}
|
||
|
||
if (args == null || args.length === 0) {
|
||
return this.$element.val();
|
||
}
|
||
|
||
var newVal = args[0];
|
||
|
||
if ($.isArray(newVal)) {
|
||
newVal = $.map(newVal, function (obj) {
|
||
return obj.toString();
|
||
});
|
||
}
|
||
|
||
this.$element.val(newVal).trigger('change');
|
||
};
|
||
|
||
Select2.prototype.destroy = function () {
|
||
this.$container.remove();
|
||
|
||
if (this.$element[0].detachEvent) {
|
||
this.$element[0].detachEvent('onpropertychange', this._syncA);
|
||
}
|
||
|
||
if (this._observer != null) {
|
||
this._observer.disconnect();
|
||
this._observer = null;
|
||
} else if (this.$element[0].removeEventListener) {
|
||
this.$element[0]
|
||
.removeEventListener('DOMAttrModified', this._syncA, false);
|
||
this.$element[0]
|
||
.removeEventListener('DOMNodeInserted', this._syncS, false);
|
||
this.$element[0]
|
||
.removeEventListener('DOMNodeRemoved', this._syncS, false);
|
||
}
|
||
|
||
this._syncA = null;
|
||
this._syncS = null;
|
||
|
||
this.$element.off('.select2');
|
||
this.$element.attr('tabindex', this.$element.data('old-tabindex'));
|
||
|
||
this.$element.removeClass('select2-hidden-accessible');
|
||
this.$element.attr('aria-hidden', 'false');
|
||
this.$element.removeData('select2');
|
||
|
||
this.dataAdapter.destroy();
|
||
this.selection.destroy();
|
||
this.dropdown.destroy();
|
||
this.results.destroy();
|
||
|
||
this.dataAdapter = null;
|
||
this.selection = null;
|
||
this.dropdown = null;
|
||
this.results = null;
|
||
};
|
||
|
||
Select2.prototype.render = function () {
|
||
var $container = $(
|
||
'<span class="select2 select2-container">' +
|
||
'<span class="selection"></span>' +
|
||
'<span class="dropdown-wrapper" aria-hidden="true"></span>' +
|
||
'</span>'
|
||
);
|
||
|
||
$container.attr('dir', this.options.get('dir'));
|
||
|
||
this.$container = $container;
|
||
|
||
this.$container.addClass('select2-container--' + this.options.get('theme'));
|
||
|
||
$container.data('element', this.$element);
|
||
|
||
return $container;
|
||
};
|
||
|
||
return Select2;
|
||
});
|
||
|
||
S2.define('jquery-mousewheel',[
|
||
'jquery'
|
||
], function ($) {
|
||
// Used to shim jQuery.mousewheel for non-full builds.
|
||
return $;
|
||
});
|
||
|
||
S2.define('jquery.select2',[
|
||
'jquery',
|
||
'jquery-mousewheel',
|
||
|
||
'./select2/core',
|
||
'./select2/defaults'
|
||
], function ($, _, Select2, Defaults) {
|
||
if ($.fn.select2 == null) {
|
||
// All methods that should return the element
|
||
var thisMethods = ['open', 'close', 'destroy'];
|
||
|
||
$.fn.select2 = function (options) {
|
||
options = options || {};
|
||
|
||
if (typeof options === 'object') {
|
||
this.each(function () {
|
||
var instanceOptions = $.extend(true, {}, options);
|
||
|
||
var instance = new Select2($(this), instanceOptions);
|
||
});
|
||
|
||
return this;
|
||
} else if (typeof options === 'string') {
|
||
var ret;
|
||
var args = Array.prototype.slice.call(arguments, 1);
|
||
|
||
this.each(function () {
|
||
var instance = $(this).data('select2');
|
||
|
||
if (instance == null && window.console && console.error) {
|
||
console.error(
|
||
'The select2(\'' + options + '\') method was called on an ' +
|
||
'element that is not using Select2.'
|
||
);
|
||
}
|
||
|
||
ret = instance[options].apply(instance, args);
|
||
});
|
||
|
||
// Check if we should be returning `this`
|
||
if ($.inArray(options, thisMethods) > -1) {
|
||
return this;
|
||
}
|
||
|
||
return ret;
|
||
} else {
|
||
throw new Error('Invalid arguments for Select2: ' + options);
|
||
}
|
||
};
|
||
}
|
||
|
||
if ($.fn.select2.defaults == null) {
|
||
$.fn.select2.defaults = Defaults;
|
||
}
|
||
|
||
return Select2;
|
||
});
|
||
|
||
// Return the AMD loader configuration so it can be used outside of this file
|
||
return {
|
||
define: S2.define,
|
||
require: S2.require
|
||
};
|
||
}());
|
||
|
||
// Autoload the jQuery bindings
|
||
// We know that all of the modules exist above this, so we're safe
|
||
var select2 = S2.require('jquery.select2');
|
||
|
||
// Hold the AMD module references on the jQuery function that was just loaded
|
||
// This allows Select2 to use the internal loader outside of this file, such
|
||
// as in the language files.
|
||
jQuery.fn.select2.amd = S2;
|
||
|
||
// Return the Select2 instance for anyone who is importing it.
|
||
return select2;
|
||
}));
|
||
|
||
|
||
/***/ }),
|
||
/* 57 */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
module.exports={render:function (){var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;
|
||
return _c('select', {
|
||
staticStyle: {
|
||
"width": "100%"
|
||
}
|
||
}, [_vm._t("default")], 2)
|
||
},staticRenderFns: []}
|
||
module.exports.render._withStripped = true
|
||
if (false) {
|
||
module.hot.accept()
|
||
if (module.hot.data) {
|
||
require("vue-hot-reload-api").rerender("data-v-ff564a86", module.exports)
|
||
}
|
||
}
|
||
|
||
/***/ }),
|
||
/* 58 */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
module.exports={render:function (){var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;
|
||
return _c('tr', {
|
||
directives: [{
|
||
name: "show",
|
||
rawName: "v-show",
|
||
value: (_vm.processDetail),
|
||
expression: "processDetail"
|
||
}]
|
||
}, [_c('td', {
|
||
attrs: {
|
||
"colspan": "3"
|
||
}
|
||
}, [_c('h4', {
|
||
staticClass: "modal-title"
|
||
}, [_vm._v("Import File:")]), _vm._v(" "), _c('div', {
|
||
staticClass: "dynamic-form-row"
|
||
}, [_vm._m(0), _vm._v(" "), _c('div', {
|
||
staticClass: "col-md-4 col-xs-12"
|
||
}, [_c('select2', {
|
||
attrs: {
|
||
"options": _vm.options.importTypes
|
||
},
|
||
model: {
|
||
value: (_vm.options.importType),
|
||
callback: function($$v) {
|
||
_vm.options.importType = $$v
|
||
},
|
||
expression: "options.importType"
|
||
}
|
||
}, [_c('option', {
|
||
attrs: {
|
||
"disabled": "",
|
||
"value": "0"
|
||
}
|
||
})])], 1)]), _vm._v(" "), _c('div', {
|
||
staticClass: "dynamic-form-row"
|
||
}, [_vm._m(1), _vm._v(" "), _c('div', {
|
||
staticClass: "col-md-4 col-xs-12"
|
||
}, [_c('input', {
|
||
directives: [{
|
||
name: "model",
|
||
rawName: "v-model",
|
||
value: (_vm.options.update),
|
||
expression: "options.update"
|
||
}],
|
||
attrs: {
|
||
"type": "checkbox",
|
||
"name": "import-update"
|
||
},
|
||
domProps: {
|
||
"checked": Array.isArray(_vm.options.update) ? _vm._i(_vm.options.update, null) > -1 : (_vm.options.update)
|
||
},
|
||
on: {
|
||
"__c": function($event) {
|
||
var $$a = _vm.options.update,
|
||
$$el = $event.target,
|
||
$$c = $$el.checked ? (true) : (false);
|
||
if (Array.isArray($$a)) {
|
||
var $$v = null,
|
||
$$i = _vm._i($$a, $$v);
|
||
if ($$el.checked) {
|
||
$$i < 0 && (_vm.options.update = $$a.concat([$$v]))
|
||
} else {
|
||
$$i > -1 && (_vm.options.update = $$a.slice(0, $$i).concat($$a.slice($$i + 1)))
|
||
}
|
||
} else {
|
||
_vm.options.update = $$c
|
||
}
|
||
}
|
||
}
|
||
})])]), _vm._v(" "), _c('div', {
|
||
staticClass: "col-md-12",
|
||
staticStyle: {
|
||
"padding-top": "30px"
|
||
}
|
||
}, [_c('table', {
|
||
staticClass: "table"
|
||
}, [_vm._m(2), _vm._v(" "), _c('tbody', [_vm._l((_vm.file.header_row), function(header, index) {
|
||
return [_c('tr', [_c('td', [_c('label', {
|
||
staticClass: "controllabel",
|
||
attrs: {
|
||
"for": header
|
||
}
|
||
}, [_vm._v(_vm._s(header))])]), _vm._v(" "), _c('td', [_c('div', {
|
||
attrs: {
|
||
"required": ""
|
||
}
|
||
}, [_c('select2', {
|
||
attrs: {
|
||
"options": _vm.columns
|
||
},
|
||
model: {
|
||
value: (_vm.columnMappings[header]),
|
||
callback: function($$v) {
|
||
_vm.$set(_vm.columnMappings, header, $$v)
|
||
},
|
||
expression: "columnMappings[header]"
|
||
}
|
||
}, [_c('option', {
|
||
attrs: {
|
||
"value": "0"
|
||
}
|
||
}, [_vm._v("Do Not Import")])])], 1)]), _vm._v(" "), _c('td', [_c('div', [_vm._v(_vm._s(_vm.activeFile.first_row[index]))])])])]
|
||
})], 2)])])]), _vm._v(" "), _c('td', [_c('button', {
|
||
staticClass: "btn btn-default",
|
||
attrs: {
|
||
"type": "button"
|
||
},
|
||
on: {
|
||
"click": function($event) {
|
||
_vm.processDetail = false
|
||
}
|
||
}
|
||
}, [_vm._v("Cancel")]), _vm._v(" "), _c('button', {
|
||
staticClass: "btn btn-primary",
|
||
attrs: {
|
||
"type": "submit"
|
||
},
|
||
on: {
|
||
"click": _vm.postSave
|
||
}
|
||
}, [_vm._v("Import")]), _vm._v(" "), (_vm.statusText) ? _c('div', {
|
||
staticClass: "alert alert-success col-md-5 col-md-offset-1",
|
||
staticStyle: {
|
||
"text-align": "left"
|
||
}
|
||
}, [_vm._v(_vm._s(this.statusText))]) : _vm._e()])])
|
||
},staticRenderFns: [function (){var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;
|
||
return _c('div', {
|
||
staticClass: "col-md-4 col-xs-12"
|
||
}, [_c('label', {
|
||
attrs: {
|
||
"for": "import-type"
|
||
}
|
||
}, [_vm._v("Import Type:")])])
|
||
},function (){var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;
|
||
return _c('div', {
|
||
staticClass: "col-md-4 col-xs-12"
|
||
}, [_c('label', {
|
||
attrs: {
|
||
"for": "import-update"
|
||
}
|
||
}, [_vm._v("Update Existing Values?:")])])
|
||
},function (){var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;
|
||
return _c('thead', [_c('th', [_vm._v("Header Field")]), _vm._v(" "), _c('th', [_vm._v("Import Field")]), _vm._v(" "), _c('th', [_vm._v("Sample Value")])])
|
||
}]}
|
||
module.exports.render._withStripped = true
|
||
if (false) {
|
||
module.hot.accept()
|
||
if (module.hot.data) {
|
||
require("vue-hot-reload-api").rerender("data-v-91619f3a", module.exports)
|
||
}
|
||
}
|
||
|
||
/***/ }),
|
||
/* 59 */
|
||
/***/ (function(module, exports) {
|
||
|
||
// removed by extract-text-webpack-plugin
|
||
|
||
/***/ }),
|
||
/* 60 */
|
||
/***/ (function(module, exports) {
|
||
|
||
// removed by extract-text-webpack-plugin
|
||
|
||
/***/ }),
|
||
/* 61 */
|
||
/***/ (function(module, exports) {
|
||
|
||
// removed by extract-text-webpack-plugin
|
||
|
||
/***/ })
|
||
/******/ ]);
|
||
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vd2VicGFjay9ib290c3RyYXAgMzFlMmU2ZTI3MDgxYTI4Y2FlZTgiLCJ3ZWJwYWNrOi8vLy4vbm9kZV9tb2R1bGVzL2Nzcy1sb2FkZXIvbGliL2Nzcy1iYXNlLmpzIiwid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy92dWUtc3R5bGUtbG9hZGVyL2xpYi9hZGRTdHlsZXNDbGllbnQuanMiLCJ3ZWJwYWNrOi8vLy4vbm9kZV9tb2R1bGVzL3Z1ZS1sb2FkZXIvbGliL2NvbXBvbmVudC1ub3JtYWxpemVyLmpzIiwid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9qcXVlcnkvZGlzdC9qcXVlcnkuanMiLCJ3ZWJwYWNrOi8vLyh3ZWJwYWNrKS9idWlsZGluL2dsb2JhbC5qcyIsIndlYnBhY2s6Ly8vLi9yZXNvdXJjZXMvYXNzZXRzL2pzL3Z1ZS5qcyIsIndlYnBhY2s6Ly8vLi9ub2RlX21vZHVsZXMvanF1ZXJ5LXVpLWJ1bmRsZS9qcXVlcnktdWkubWluLmpzIiwid2VicGFjazovLy8uL3Jlc291cmNlcy9hc3NldHMvanMvYm9vdHN0cmFwLmpzIiwid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9sb2Rhc2gvbG9kYXNoLmpzIiwid2VicGFjazovLy8od2VicGFjaykvYnVpbGRpbi9tb2R1bGUuanMiLCJ3ZWJwYWNrOi8vLy4vbm9kZV9tb2R1bGVzL2Jvb3RzdHJhcC1sZXNzL2pzL2Jvb3RzdHJhcC5qcyIsIndlYnBhY2s6Ly8vLi9ub2RlX21vZHVsZXMvdnVlL2Rpc3QvdnVlLmNvbW1vbi5qcyIsIndlYnBhY2s6Ly8vLi9ub2RlX21vZHVsZXMvdnVlLXJlc291cmNlL2Rpc3QvdnVlLXJlc291cmNlLmVzMjAxNS5qcyIsIndlYnBhY2s6Ly8vZ290IChpZ25vcmVkKSIsIndlYnBhY2s6Ly8vLi9yZXNvdXJjZXMvYXNzZXRzL2pzL2NvbXBvbmVudHMvcGFzc3BvcnQvQ2xpZW50cy52dWUiLCJ3ZWJwYWNrOi8vLy4vcmVzb3VyY2VzL2Fzc2V0cy9qcy9jb21wb25lbnRzL3Bhc3Nwb3J0L0NsaWVudHMudnVlPzBlMWIiLCJ3ZWJwYWNrOi8vLy4vcmVzb3VyY2VzL2Fzc2V0cy9qcy9jb21wb25lbnRzL3Bhc3Nwb3J0L0NsaWVudHMudnVlP2FiMWUiLCJ3ZWJwYWNrOi8vLy4vbm9kZV9tb2R1bGVzL3Z1ZS1zdHlsZS1sb2FkZXIvbGliL2xpc3RUb1N0eWxlcy5qcyIsIndlYnBhY2s6Ly8vQ2xpZW50cy52dWUiLCJ3ZWJwYWNrOi8vLy4vcmVzb3VyY2VzL2Fzc2V0cy9qcy9jb21wb25lbnRzL3Bhc3Nwb3J0L0NsaWVudHMudnVlPzU3MWIiLCJ3ZWJwYWNrOi8vLy4vcmVzb3VyY2VzL2Fzc2V0cy9qcy9jb21wb25lbnRzL3Bhc3Nwb3J0L0F1dGhvcml6ZWRDbGllbnRzLnZ1ZSIsIndlYnBhY2s6Ly8vLi9yZXNvdXJjZXMvYXNzZXRzL2pzL2NvbXBvbmVudHMvcGFzc3BvcnQvQXV0aG9yaXplZENsaWVudHMudnVlPzRkY2UiLCJ3ZWJwYWNrOi8vLy4vcmVzb3VyY2VzL2Fzc2V0cy9qcy9jb21wb25lbnRzL3Bhc3Nwb3J0L0F1dGhvcml6ZWRDbGllbnRzLnZ1ZT9jNWFiIiwid2VicGFjazovLy9BdXRob3JpemVkQ2xpZW50cy52dWUiLCJ3ZWJwYWNrOi8vLy4vcmVzb3VyY2VzL2Fzc2V0cy9qcy9jb21wb25lbnRzL3Bhc3Nwb3J0L0F1dGhvcml6ZWRDbGllbnRzLnZ1ZT9mYmI3Iiwid2VicGFjazovLy8uL3Jlc291cmNlcy9hc3NldHMvanMvY29tcG9uZW50cy9wYXNzcG9ydC9QZXJzb25hbEFjY2Vzc1Rva2Vucy52dWUiLCJ3ZWJwYWNrOi8vLy4vcmVzb3VyY2VzL2Fzc2V0cy9qcy9jb21wb25lbnRzL3Bhc3Nwb3J0L1BlcnNvbmFsQWNjZXNzVG9rZW5zLnZ1ZT8xMWZjIiwid2VicGFjazovLy8uL3Jlc291cmNlcy9hc3NldHMvanMvY29tcG9uZW50cy9wYXNzcG9ydC9QZXJzb25hbEFjY2Vzc1Rva2Vucy52dWU/Mjg0OCIsIndlYnBhY2s6Ly8vUGVyc29uYWxBY2Nlc3NUb2tlbnMudnVlIiwid2VicGFjazovLy8uL3Jlc291cmNlcy9hc3NldHMvanMvY29tcG9uZW50cy9wYXNzcG9ydC9QZXJzb25hbEFjY2Vzc1Rva2Vucy52dWU/NzA0OCIsIndlYnBhY2s6Ly8vLi9yZXNvdXJjZXMvYXNzZXRzL2pzL2NvbXBvbmVudHMvaW1wb3J0ZXIvaW1wb3J0ZXIudnVlIiwid2VicGFjazovLy8uL3Jlc291cmNlcy9hc3NldHMvanMvY29tcG9uZW50cy9pbXBvcnRlci9pbXBvcnRlci52dWU/NDdhYiIsIndlYnBhY2s6Ly8vLi9yZXNvdXJjZXMvYXNzZXRzL2pzL2NvbXBvbmVudHMvaW1wb3J0ZXIvaW1wb3J0ZXIudnVlP2QwN2IiLCJ3ZWJwYWNrOi8vL2ltcG9ydGVyLnZ1ZSIsIndlYnBhY2s6Ly8vLi9ub2RlX21vZHVsZXMvYmx1ZWltcC1maWxlLXVwbG9hZC9qcy9qcXVlcnkuZmlsZXVwbG9hZC5qcyIsIndlYnBhY2s6Ly8vLi9ub2RlX21vZHVsZXMvanF1ZXJ5LXVpL3VpL3dpZGdldC5qcyIsIndlYnBhY2s6Ly8vLi9ub2RlX21vZHVsZXMvanF1ZXJ5LXVpL3VpL3ZlcnNpb24uanMiLCJ3ZWJwYWNrOi8vLy4vcmVzb3VyY2VzL2Fzc2V0cy9qcy9jb21wb25lbnRzL2FsZXJ0LnZ1ZSIsIndlYnBhY2s6Ly8vLi9yZXNvdXJjZXMvYXNzZXRzL2pzL2NvbXBvbmVudHMvYWxlcnQudnVlP2ViMzAiLCJ3ZWJwYWNrOi8vLy4vcmVzb3VyY2VzL2Fzc2V0cy9qcy9jb21wb25lbnRzL2FsZXJ0LnZ1ZT9kMDBkIiwid2VicGFjazovLy9hbGVydC52dWUiLCJ3ZWJwYWNrOi8vLy4vcmVzb3VyY2VzL2Fzc2V0cy9qcy9jb21wb25lbnRzL2FsZXJ0LnZ1ZT9lMWFjIiwid2VicGFjazovLy8uL3Jlc291cmNlcy9hc3NldHMvanMvY29tcG9uZW50cy9pbXBvcnRlci9pbXBvcnRlci1lcnJvcnMudnVlIiwid2VicGFjazovLy8uL3Jlc291cmNlcy9hc3NldHMvanMvY29tcG9uZW50cy9pbXBvcnRlci9pbXBvcnRlci1lcnJvcnMudnVlPzNjNDAiLCJ3ZWJwYWNrOi8vLy4vcmVzb3VyY2VzL2Fzc2V0cy9qcy9jb21wb25lbnRzL2ltcG9ydGVyL2ltcG9ydGVyLWVycm9ycy52dWU/NTY3MCIsIndlYnBhY2s6Ly8vaW1wb3J0ZXItZXJyb3JzLnZ1ZSIsIndlYnBhY2s6Ly8vLi9yZXNvdXJjZXMvYXNzZXRzL2pzL2NvbXBvbmVudHMvaW1wb3J0ZXIvaW1wb3J0ZXItZXJyb3JzLnZ1ZT85N2IxIiwid2VicGFjazovLy8uL3Jlc291cmNlcy9hc3NldHMvanMvY29tcG9uZW50cy9pbXBvcnRlci9pbXBvcnRlci1maWxlLnZ1ZSIsIndlYnBhY2s6Ly8vLi9yZXNvdXJjZXMvYXNzZXRzL2pzL2NvbXBvbmVudHMvaW1wb3J0ZXIvaW1wb3J0ZXItZmlsZS52dWU/ZDVmNSIsIndlYnBhY2s6Ly8vLi9yZXNvdXJjZXMvYXNzZXRzL2pzL2NvbXBvbmVudHMvaW1wb3J0ZXIvaW1wb3J0ZXItZmlsZS52dWU/MTkzYSIsIndlYnBhY2s6Ly8vaW1wb3J0ZXItZmlsZS52dWUiLCJ3ZWJwYWNrOi8vLy4vcmVzb3VyY2VzL2Fzc2V0cy9qcy9jb21wb25lbnRzL3NlbGVjdDIudnVlIiwid2VicGFjazovLy8uL3Jlc291cmNlcy9hc3NldHMvanMvY29tcG9uZW50cy9zZWxlY3QyLnZ1ZT8wM2NlIiwid2VicGFjazovLy8uL3Jlc291cmNlcy9hc3NldHMvanMvY29tcG9uZW50cy9zZWxlY3QyLnZ1ZT9lZWQwIiwid2VicGFjazovLy9zZWxlY3QyLnZ1ZSIsIndlYnBhY2s6Ly8vLi9ub2RlX21vZHVsZXMvc2VsZWN0Mi9kaXN0L2pzL3NlbGVjdDIuanMiLCJ3ZWJwYWNrOi8vLy4vcmVzb3VyY2VzL2Fzc2V0cy9qcy9jb21wb25lbnRzL3NlbGVjdDIudnVlP2Y0OWIiLCJ3ZWJwYWNrOi8vLy4vcmVzb3VyY2VzL2Fzc2V0cy9qcy9jb21wb25lbnRzL2ltcG9ydGVyL2ltcG9ydGVyLWZpbGUudnVlP2E3OWMiLCJ3ZWJwYWNrOi8vLy4vcmVzb3VyY2VzL2Fzc2V0cy9sZXNzL0FkbWluTFRFLmxlc3MiLCJ3ZWJwYWNrOi8vLy4vcmVzb3VyY2VzL2Fzc2V0cy9sZXNzL2FwcC5sZXNzIiwid2VicGFjazovLy8uL3Jlc291cmNlcy9hc3NldHMvbGVzcy9vdmVycmlkZXMubGVzcz81OTUwIl0sIm5hbWVzIjpbInJlcXVpcmUiLCJWdWUiLCJjb21wb25lbnQiLCJ3aW5kb3ciLCJfIiwiJCIsImpRdWVyeSIsImV2ZW50SHViIiwiaHR0cCIsImludGVyY2VwdG9ycyIsInB1c2giLCJyZXF1ZXN0IiwibmV4dCIsImhlYWRlcnMiLCJzZXQiLCJMYXJhdmVsIiwiY3NyZlRva2VuIl0sIm1hcHBpbmdzIjoiO0FBQUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7OztBQUdBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGFBQUs7QUFDTDtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLG1DQUEyQiwwQkFBMEIsRUFBRTtBQUN2RCx5Q0FBaUMsZUFBZTtBQUNoRDtBQUNBO0FBQ0E7O0FBRUE7QUFDQSw4REFBc0QsK0RBQStEOztBQUVySDtBQUNBOztBQUVBO0FBQ0E7Ozs7Ozs7QUM3REE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLG1DQUFtQyxnQkFBZ0I7QUFDbkQsSUFBSTtBQUNKO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGdCQUFnQixpQkFBaUI7QUFDakM7QUFDQTtBQUNBO0FBQ0E7QUFDQSxZQUFZLG9CQUFvQjtBQUNoQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRzs7QUFFSDtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxvREFBb0QsY0FBYzs7QUFFbEU7QUFDQTs7Ozs7OztBQzNFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsVUFBVSxpQkFBaUI7QUFDM0I7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSxtQkFBbUI7QUFDbkI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsbUJBQW1CLG1CQUFtQjtBQUN0QztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQSxtQkFBbUIsc0JBQXNCO0FBQ3pDO0FBQ0E7QUFDQSx1QkFBdUIsMkJBQTJCO0FBQ2xEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EsaUJBQWlCLG1CQUFtQjtBQUNwQztBQUNBO0FBQ0E7QUFDQTtBQUNBLHFCQUFxQiwyQkFBMkI7QUFDaEQ7QUFDQTtBQUNBLFlBQVksdUJBQXVCO0FBQ25DO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQSxxQkFBcUIsdUJBQXVCO0FBQzVDO0FBQ0E7QUFDQSw4QkFBOEI7QUFDOUI7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxDQUFDOztBQUVEO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EseURBQXlEO0FBQ3pEOztBQUVBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7Ozs7O0FDdE5BOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EseUJBQXlCO0FBQ3pCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7Ozs7O0FDMUZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7O0FBRUE7QUFDQSxDQUFDOztBQUVEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7O0FBRUE7O0FBRUE7O0FBRUE7O0FBRUE7O0FBRUE7O0FBRUE7O0FBRUE7O0FBRUE7O0FBRUE7O0FBRUE7O0FBRUE7Ozs7QUFJQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7OztBQUlBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxFQUFFOztBQUVGO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxFQUFFOztBQUVGO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsRUFBRTs7QUFFRjtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxFQUFFOztBQUVGO0FBQ0E7QUFDQTtBQUNBLEVBQUU7O0FBRUY7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNILEVBQUU7O0FBRUY7QUFDQTtBQUNBLEVBQUU7O0FBRUY7QUFDQTtBQUNBLEVBQUU7O0FBRUY7QUFDQTtBQUNBLEVBQUU7O0FBRUY7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFFOztBQUVGO0FBQ0E7QUFDQSxFQUFFOztBQUVGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsK0JBQStCO0FBQy9CO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSxRQUFRLFlBQVk7O0FBRXBCO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQSxNQUFNO0FBQ047QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsRUFBRTs7QUFFRixvQkFBb0I7O0FBRXBCO0FBQ0E7QUFDQSxFQUFFOztBQUVGO0FBQ0E7QUFDQSxFQUFFOztBQUVGOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFFOztBQUVGO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxFQUFFOztBQUVGOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7O0FBRUY7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFFOztBQUVGO0FBQ0E7QUFDQTtBQUNBLEVBQUU7O0FBRUYsZ0NBQWdDO0FBQ2hDO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTs7QUFFRjtBQUNBOztBQUVBO0FBQ0E7QUFDQSxVQUFVLFlBQVk7QUFDdEI7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EsRUFBRTs7QUFFRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTs7QUFFRjtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLEVBQUU7O0FBRUY7QUFDQTtBQUNBLEVBQUU7O0FBRUY7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBLFNBQVMsU0FBUztBQUNsQjtBQUNBOztBQUVBOztBQUVBO0FBQ0EsRUFBRTs7QUFFRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLFNBQVMsWUFBWTtBQUNyQjtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EsRUFBRTs7QUFFRjtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLFVBQVUsWUFBWTtBQUN0Qjs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLEdBQUc7QUFDSDtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLEVBQUU7O0FBRUY7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0EsRUFBRTs7QUFFRjs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxDQUFDOztBQUVEO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLENBQUM7O0FBRUQ7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFFOztBQUVGO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUyxTQUFTO0FBQ2xCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFFOztBQUVGOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsMEJBQTBCO0FBQzFCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFFOztBQUVGO0FBQ0E7O0FBRUEsZ0JBQWdCLElBQUk7O0FBRXBCO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBLHdDQUF3QyxJQUFJO0FBQzVDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7O0FBRUY7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLEVBQUU7O0FBRUY7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTs7QUFFRjtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0gsR0FBRztBQUNIOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLENBQUM7QUFDRCxTQUFTOztBQUVUO0FBQ0E7QUFDQTtBQUNBLEdBQUc7O0FBRUg7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztB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QUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTs7QUFFRjtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTs7QUFFRjtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTs7QUFFRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLElBQUk7QUFDSjtBQUNBO0FBQ0EsR0FBRzs7QUFFSDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7O0FBRUg7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsV0FBVyxVQUFVO0FBQ3JCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsV0FBVyxjQUFjO0FBQ3pCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQSxnQ0FBZ0MsTUFBTTtBQUN0QztBQUNBO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQTs7QUFFQSxlQUFlOztBQUVmLFNBQVM7O0FBRVQ7QUFDQSxRQUFRLGlDQUFpQztBQUN6QyxRQUFRLG9CQUFvQjtBQUM1QixRQUFRLHNDQUFzQztBQUM5QyxRQUFRO0FBQ1IsRUFBRTs7QUFFRjtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxHQUFHOztBQUVIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7O0FBRUE7QUFDQSxHQUFHOztBQUVIO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7O0FBRUY7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsZ0JBQWdCLGFBQWEsRUFBRTtBQUMvQjtBQUNBO0FBQ0E7QUFDQSxHQUFHOztBQUVIO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0wsR0FBRzs7QUFFSDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7O0FBRUg7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsS0FBSzs7QUFFTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0EsNERBQTREOztBQUU1RDtBQUNBO0FBQ0E7QUFDQSx5Q0FBeUM7O0FBRXpDO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBLE9BQU87QUFDUDtBQUNBO0FBQ0E7QUFDQTtBQUNBLDZEQUE2RDs7QUFFN0Q7QUFDQTtBQUNBO0FBQ0EsMENBQTBDOztBQUUxQztBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLGdFQUFnRTs7QUFFaEU7QUFDQTtBQUNBO0FBQ0EsNkNBQTZDOztBQUU3QztBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHOztBQUVIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQU07QUFDTjtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsRUFBRTs7QUFFRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHOztBQUVIO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRzs7QUFFSDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRzs7QUFFSDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBLEdBQUc7O0FBRUg7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHOztBQUVIO0FBQ0E7QUFDQSxHQUFHOztBQUVIO0FBQ0E7QUFDQSxHQUFHOztBQUVIO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRzs7QUFFSDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxHQUFHOztBQUVIO0FBQ0E7QUFDQTtBQUNBLGlFQUFpRSxVQUFVO0FBQzNFLHND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QUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRzs7QUFFSCxRQUFRLFNBQVM7QUFDakI7QUFDQTtBQUNBLEdBQUc7QUFDSDs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFdBQVcsU0FBUztBQUNwQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsdUNBQXVDLGlEQUFpRDtBQUN4RjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLGlEQUFpRDtBQUNqRCxVQUFVLHdDQUF3QztBQUNsRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxXQUFXLGdCQUFnQjtBQUMzQjtBQUNBLFdBQVcsUUFBUTtBQUNuQixXQUFXLE1BQU07QUFDakIsV0FBVyxNQUFNO0FBQ2pCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLElBQUk7QUFDSjtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLENBQUM7O0FBRUQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsQ0FBQztBQUNEO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLENBQUM7QUFDRDtBQUNBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7QUFDRjs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLENBQUM7QUFDRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGOztBQUVBOztBQUVBLENBQUM7Ozs7QUFJRDtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7OztBQUtBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FBR0E7QUFDQTs7QUFFQSxRQUFRLEdBQUc7QUFDWDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOzs7QUFHQTs7OztBQUlBOztBQUVBOztBQUVBO0FBQ0E7Ozs7QUFJQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsRUFBRTtBQUNGOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLGdCQUFnQixTQUFTO0FBQ3pCO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKOztBQUVBOztBQUVBLGNBQWMsU0FBUztBQUN2QjtBQUNBOztBQUVBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLENBQUM7OztBQUdEOzs7QUFHQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBLElBQUk7QUFDSjtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxRQUFRO0FBQ1I7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQSxLQUFLO0FBQ0w7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EsSUFBSTtBQUNKOztBQUVBO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7QUFDQTs7QUFFQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7O0FBR0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLFVBQVUsT0FBTztBQUNqQjtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSCxFQUFFOztBQUVGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsVUFBVSxPQUFPO0FBQ2pCLDBCQUEwQix3QkFBd0I7O0FBRWxEO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EsRUFBRTs7QUFFRjtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsRUFBRTs7QUFFRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFFOztBQUVGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxDQUFDOztBQUVEO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBLDBDQUEwQztBQUMxQyxFQUFFO0FBQ0Y7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLENBQUM7QUFDRDtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsQ0FBQztBQUNEOzs7O0FBSUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxtQkFBbUI7O0FBRW5CO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLFVBQVUsY0FBYztBQUN4QjtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0EsR0FBRzs7QUFFSDtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFFBQVE7O0FBRVI7QUFDQTtBQUNBO0FBQ0EsT0FBTztBQUNQLE1BQU07O0FBRU47QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUk7O0FBRUo7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQSxJQUFJOztBQUVKO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUk7O0FBRUo7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSTs7QUFFSjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBO0FBQ0EsSUFBSTs7QUFFSjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7QUFDQTtBQUNBLElBQUk7O0FBRUo7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUk7O0FBRUo7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFJOztBQUVKO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7O0FBR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0EsR0FBRztBQUNIOztBQUVBO0FBQ0EsR0FBRzs7QUFFSDtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7O0FBRUY7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0EsS0FBSzs7QUFFTDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBLHdDQUF3QyxzQ0FBc0M7QUFDOUUsb0NBQW9DLHVDQUF1QztBQUMzRSxvQ0FBb0Msc0NBQXNDO0FBQzFFO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxRQUFRO0FBQ1IsT0FBTztBQUNQO0FBQ0EsTUFBTTtBQUNOLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxXQUFXOztBQUVYO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLFVBQVU7O0FBRVY7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUzs7QUFFVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxXQUFXOztBQUVYO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxRQUFROztBQUVSO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsTUFBTTtBQUNOLEtBQUs7O0FBRUw7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUk7QUFDSjs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxNQUFNOztBQUVOO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSxvQ0FBb0M7QUFDcEMscUNBQXFDO0FBQ3JDLG9DQUFvQztBQUNwQztBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7O0FBRUg7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsRUFBRTs7QUFFRjtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLENBQUM7OztBQUdEO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7O0FBS0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGOzs7OztBQUtBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRzs7QUFFSDtBQUNBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxDQUFDOztBQUVEOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQSxDQUFDOztBQUVEO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOzs7OztBQUtBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxFQUFFO0FBQ0Y7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLFVBQVUsU0FBUztBQUNuQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7QUFLQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBLE1BQU07QUFDTjtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxFQUFFO0FBQ0Y7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBLHVCQUF1QixhQUFhO0FBQ3BDLEdBQUc7O0FBRUg7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsRUFBRTtBQUNGOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7Ozs7QUFJQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsb0JBQW9CLFNBQVM7QUFDN0I7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsSUFBSTs7QUFFSjtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsRUFBRTs7QUFFRjtBQUNBO0FBQ0EsRUFBRTs7QUFFRjtBQUNBO0FBQ0EsRUFBRTs7QUFFRjtBQUNBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7O0FBRUY7QUFDQTtBQUNBO0FBQ0EsQ0FBQzs7QUFFRDtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLElBQUk7QUFDSixHQUFHO0FBQ0gsRUFBRTs7QUFFRjtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQSxDQUFDOzs7QUFHRDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFFOztBQUVGO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7O0FBRUY7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKLEdBQUc7QUFDSDtBQUNBLENBQUM7O0FBRUQ7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKLEVBQUU7QUFDRjtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0gsRUFBRTtBQUNGO0FBQ0E7QUFDQSxFQUFFOztBQUVGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxDQUFDO0FBQ0Q7O0FBRUE7OztBQUdBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7Ozs7O0FBS0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUFHQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLFFBQVEsZ0JBQWdCO0FBQ3hCO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLGlCQUFpQixnQkFBZ0I7QUFDakM7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBLENBQUM7QUFDRDs7QUFFQTs7QUFFQTs7OztBQUlBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7O0FBR0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUEsRUFBRTtBQUNGOztBQUVBLEVBQUU7QUFDRjtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOzs7QUFHQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSxRQUFRLE9BQU87QUFDZjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FBR0Esc0JBQXNCOztBQUV0QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsUUFBUSxPQUFPO0FBQ2Y7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxJQUFJO0FBQ0o7O0FBRUE7QUFDQSxJQUFJO0FBQ0o7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7OztBQUdBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLENBQUM7QUFDRDs7OztBQUlBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEVBQUUsZ0JBQWdCO0FBQ2xCOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsR0FBRzs7QUFFSDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSxXQUFXOztBQUVYOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFJOztBQUVKO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBLEVBQUU7O0FBRUY7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUEsMkNBQTJDO0FBQzNDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFFOztBQUVGOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLG9EQUFvRDtBQUNwRDs7QUFFQTtBQUNBOztBQUVBLGNBQWMsc0JBQXNCO0FBQ3BDO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQSx5QkFBeUI7QUFDekI7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQSwrREFBK0Q7QUFDL0Q7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EsRUFBRTs7QUFFRjtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSxVQUFVLGNBQWM7O0FBRXhCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxpQkFBaUIsbUJBQW1CO0FBQ3BDOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSwwQkFBMEIsdUNBQXVDO0FBQ2pFO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLHVCQUF1Qix1REFBdUQ7QUFDOUU7O0FBRUE7QUFDQSxFQUFFOztBQUVGO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLOztBQUVMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBLEdBQUc7QUFDSCxFQUFFOztBQUVGO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTs7QUFFRjtBQUNBOztBQUVBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBLEdBQUc7QUFDSDs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFJOztBQUVKO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRzs7QUFFSDtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0Esc0NBQXNDO0FBQ3RDO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQSxFQUFFO0FBQ0Y7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBLHFDQUFxQyxjQUFjO0FBQ25EO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsQ0FBQzs7QUFFRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EscUNBQXFDO0FBQ3JDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsQ0FBQztBQUNEO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsQ0FBQzs7QUFFRDs7QUFFQTtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQSxDQUFDOzs7QUFHRDs7QUFFQTs7QUFFQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLDJDQUEyQyxPQUFPO0FBQ2xEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsOEJBQThCOztBQUU5QjtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxVQUFVLE9BQU87QUFDakI7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQSxnQkFBZ0IsZ0JBQWdCO0FBQ2hDO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsT0FBTztBQUNQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsUUFBUSwrQkFBK0I7QUFDdkM7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsRUFBRTs7QUFFRjtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBLHVDQUF1QyxPQUFPO0FBQzlDO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBLHdDQUF3QyxPQUFPO0FBQy9DO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLEVBQUU7O0FBRUY7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsU0FBUyxxQ0FBcUM7QUFDOUM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EsUUFBUTtBQUNSO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxDQUFDOztBQUVEO0FBQ0E7QUFDQTtBQUNBLEVBQUU7O0FBRUY7QUFDQTtBQUNBLEVBQUU7O0FBRUY7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTCxHQUFHO0FBQ0gsRUFBRTs7QUFFRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0gsRUFBRTs7QUFFRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0gsRUFBRTs7QUFFRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNILEVBQUU7O0FBRUY7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSCxFQUFFOztBQUVGO0FBQ0E7QUFDQTs7QUFFQSxTQUFTLDhCQUE4QjtBQUN2Qzs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EsRUFBRTs7QUFFRjtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLEdBQUc7QUFDSCxFQUFFOztBQUVGO0FBQ0E7QUFDQSw2QkFBNkI7QUFDN0I7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0EsWUFBWSxPQUFPO0FBQ25COztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBLEtBQUs7QUFDTDs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0gsRUFBRTs7QUFFRjtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxHQUFHO0FBQ0g7QUFDQSxDQUFDOztBQUVEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLENBQUM7QUFDRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsU0FBUyxXQUFXO0FBQ3BCO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLENBQUM7QUFDRDs7QUFFQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7OztBQUlBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLDBCQUEwQjtBQUMxQixzQkFBc0IsY0FBYztBQUNwQyxnQkFBZ0IsV0FBVyxZQUFZO0FBQ3ZDLFdBQVc7QUFDWDtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBLHFDQUFxQyxVQUFVLFNBQVMsTUFBTSxhQUFhO0FBQzNFLGFBQWEsZUFBZTtBQUM1Qjs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGLENBQUM7OztBQUdEO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUFHQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBLGtCQUFrQjtBQUNsQjtBQUNBO0FBQ0E7QUFDQTs7O0FBR0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFlBQVksK0RBQStEO0FBQzNFO0FBQ0E7QUFDQTtBQUNBLEVBQUU7O0FBRUY7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLEVBQUU7QUFDRjtBQUNBOztBQUVBLFFBQVEsT0FBTzs7QUFFZjtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7O0FBRUg7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFFOztBQUVGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7O0FBRUY7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFFOztBQUVGO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7O0FBRUEsR0FBRzs7QUFFSDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxFQUFFOztBQUVGO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLENBQUM7O0FBRUQ7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE9BQU87QUFDUDtBQUNBO0FBQ0EsR0FBRzs7QUFFSDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLENBQUM7O0FBRUQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGtCQUFrQixnQkFBZ0I7QUFDbEM7QUFDQSxNQUFNO0FBQ047QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLENBQUM7QUFDRDtBQUNBO0FBQ0E7QUFDQSxpQkFBaUI7O0FBRWpCO0FBQ0E7O0FBRUEsVUFBVSxPQUFPO0FBQ2pCO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsQ0FBQzs7QUFFRDtBQUNBO0FBQ0E7QUFDQTtBQUNBLFlBQVk7QUFDWjs7QUFFQTtBQUNBO0FBQ0E7O0FBRUEsV0FBVyxTQUFTO0FBQ3BCO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQSxDQUFDOzs7QUFHRDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLEdBQUc7QUFDSDs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBOztBQUVBOztBQUVBO0FBQ0E7Ozs7O0FBS0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFdBQVc7O0FBRVg7QUFDQTtBQUNBO0FBQ0EsUUFBUSxPQUFPO0FBQ2Y7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxRQUFRLGdCQUFnQjtBQUN4Qjs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsV0FBVztBQUNYO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFJO0FBQ0osR0FBRztBQUNIOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSTs7QUFFSjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxNQUFNO0FBQ047QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKLGlEQUFpRCwwQkFBMEI7QUFDM0U7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUk7QUFDSjs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSxVQUFVLGdCQUFnQjtBQUMxQjtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0EsMkJBQTJCO0FBQzNCO0FBQ0EscUJBQXFCO0FBQ3JCO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxXQUFXLGdCQUFnQjtBQUMzQjtBQUNBOztBQUVBLDZDQUE2QztBQUM3QztBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7O0FBRUE7O0FBRUEsUUFBUSxnQkFBZ0I7QUFDeEI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDs7QUFFQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0gsRUFBRTs7QUFFRjtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQSxTQUFTLGdCQUFnQjtBQUN6QjtBQUNBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7O0FBRUY7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBLENBQUM7O0FBRUQ7QUFDQSxpRUFBaUU7QUFDakU7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUEsRUFBRTtBQUNGO0FBQ0E7QUFDQTs7QUFFQSxJQUFJO0FBQ0o7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBLG9CQUFvQixjQUFjO0FBQ2xDLEVBQUU7QUFDRjtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLGlEQUFpRDs7QUFFakQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSwrQkFBK0IsU0FBUztBQUN4QztBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNILEVBQUU7QUFDRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSwrQkFBK0IsU0FBUztBQUN4QztBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EsbUJBQW1CLGdCQUFnQjtBQUNuQztBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0EsQ0FBQzs7QUFFRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLENBQUM7O0FBRUQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFVBQVUsa0JBQWtCO0FBQzVCLFdBQVcsa0JBQWtCO0FBQzdCLGNBQWM7QUFDZCxDQUFDO0FBQ0Q7QUFDQTtBQUNBO0FBQ0EsQ0FBQzs7QUFFRDtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBLFFBQVEsbUJBQW1CO0FBQzNCOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7O0FBR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGOzs7QUFHQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLENBQUM7OztBQUdEO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsRUFBRTs7QUFFRjtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQSxDQUFDOztBQUVEO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBLEVBQUU7O0FBRUY7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7O0FBRUY7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxDQUFDOztBQUVEO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLENBQUM7Ozs7O0FBS0Q7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxFQUFFOztBQUVGO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBLENBQUM7O0FBRUQ7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLEVBQUU7O0FBRUY7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsRUFBRTs7QUFFRjtBQUNBO0FBQ0E7QUFDQTtBQUNBLENBQUM7O0FBRUQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIOztBQUVBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLENBQUM7Ozs7O0FBS0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUFHQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxFQUFFOztBQUVGO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxFQUFFOztBQUVGO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUk7QUFDSjs7QUFFQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLE1BQU07QUFDTjtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxJQUFJO0FBQ0o7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNILEVBQUU7O0FBRUY7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxDQUFDOzs7OztBQUtEOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7O0FBRUEsaUNBQWlDO0FBQ2pDO0FBQ0E7O0FBRUEsSUFBSTtBQUNKOztBQUVBLElBQUk7QUFDSjtBQUNBO0FBQ0EsS0FBSztBQUNMOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0EsQ0FBQzs7QUFFRDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQSxLQUFLO0FBQ0w7QUFDQTs7QUFFQTtBQUNBLFdBQVcsU0FBUztBQUNwQjs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLElBQUk7O0FBRUo7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsQ0FBQzs7QUFFRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsQ0FBQzs7Ozs7QUFLRDs7O0FBR0E7O0FBRUE7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsc0NBQXNDO0FBQ3RDO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQSx5QkFBeUI7QUFDekI7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSw4Q0FBOEM7QUFDOUM7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSwyQ0FBMkM7QUFDM0M7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxVQUFVLEtBQUs7QUFDZjtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0EsaURBQWlEO0FBQ2pEO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxFQUFFOztBQUVGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQSxDQUFDOztBQUVEOztBQUVBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSCxFQUFFO0FBQ0Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsQ0FBQzs7O0FBR0Q7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsQ0FBQzs7QUFFRDtBQUNBO0FBQ0E7QUFDQTtBQUNBLENBQUM7Ozs7O0FBS0Q7OztBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUscUNBQXFDOztBQUVwRDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBOztBQUVBOztBQUVBOzs7O0FBSUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FBR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBLElBQUk7O0FBRUo7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7O0FBRUgsRUFBRTs7QUFFRjtBQUNBO0FBQ0E7QUFDQTs7QUFFQSxFQUFFOztBQUVGO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxHQUFHOztBQUVILEVBQUU7O0FBRUY7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsYUFBYTtBQUNiLEtBQUs7QUFDTDs7QUFFQSxXQUFXO0FBQ1gsR0FBRztBQUNIO0FBQ0EsQ0FBQzs7O0FBR0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxnQkFBZ0I7O0FBRWhCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxnQkFBZ0I7O0FBRWhCLGdEQUFnRDtBQUNoRDs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBLG1CQUFtQjtBQUNuQjs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSx3REFBd0Q7QUFDeEQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxFQUFFOztBQUVGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsaUJBQWlCOztBQUVqQjtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQSxJQUFJOztBQUVKO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLE1BQU07QUFDTjtBQUNBO0FBQ0EsT0FBTztBQUNQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBLFNBQVM7QUFDVDs7QUFFQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0EsaUJBQWlCO0FBQ2pCLFNBQVM7O0FBRVQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxrREFBa0Q7O0FBRWxEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGFBQWE7QUFDYjs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHOztBQUVIO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRzs7QUFFSDtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7O0FBRUg7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxHQUFHOztBQUVIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFFOztBQUVGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsRUFBRTs7QUFFRjtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0EsMkJBQTJCOztBQUUzQjtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0Esa0NBQWtDOztBQUVsQztBQUNBLHNCQUFzQjtBQUN0QiwyQkFBMkI7O0FBRTNCO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSzs7QUFFTDtBQUNBO0FBQ0E7QUFDQSxLQUFLOztBQUVMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLOztBQUVMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7O0FBRUw7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsT0FBTzs7QUFFUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7O0FBRUw7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSTs7QUFFSjtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esc0RBQXNEO0FBQ3REO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMOztBQUVBO0FBQ0E7QUFDQTtBQUNBLElBQUk7O0FBRUo7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLEtBQUs7QUFDTDs7QUFFQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSTs7QUFFSjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EsRUFBRTs7QUFFRjtBQUNBO0FBQ0EsRUFBRTs7QUFFRjtBQUNBO0FBQ0E7QUFDQSxDQUFDOztBQUVEO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0EsQ0FBQzs7O0FBR0Q7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGOzs7QUFHQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxJQUFJO0FBQ0o7O0FBRUE7QUFDQSxFQUFFOztBQUVGO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBLElBQUk7QUFDSjtBQUNBO0FBQ0EsR0FBRztBQUNILEVBQUU7O0FBRUY7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsR0FBRztBQUNILEVBQUU7O0FBRUY7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQSxDQUFDOzs7QUFHRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7O0FBS0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxRQUFROztBQUVSO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7O0FBRUEsbURBQW1EO0FBQ25EO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsUUFBUTtBQUNSO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsV0FBVyx1QkFBdUI7QUFDbEMsV0FBVyx5QkFBeUI7QUFDcEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFFBQVE7QUFDUjtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0EsS0FBSzs7QUFFTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSTs7QUFFSjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLENBQUM7Ozs7O0FBS0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLENBQUM7O0FBRUQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLENBQUM7O0FBRUQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLENBQUM7O0FBRUQ7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsQ0FBQzs7Ozs7QUFLRDtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxDQUFDOztBQUVEO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLElBQUk7QUFDSjtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxHQUFHOztBQUVIO0FBQ0E7QUFDQTtBQUNBLENBQUM7Ozs7O0FBS0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsQ0FBQzs7O0FBR0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7O0FBR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxFQUFFO0FBQ0Y7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHOztBQUVIO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQSxJQUFJO0FBQ0osR0FBRztBQUNIOztBQUVBO0FBQ0E7Ozs7O0FBS0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsQ0FBQzs7Ozs7QUFLRDtBQUNBO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7Ozs7O0FBS0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQSxxREFBcUQ7QUFDckQ7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUEsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxXQUFXO0FBQ1g7O0FBRUE7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTs7QUFFRjtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsbUJBQW1COztBQUVuQiw0REFBNEQsZUFBZTtBQUMzRTtBQUNBOztBQUVBO0FBQ0E7O0FBRUEsR0FBRzs7QUFFSDtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFFOztBQUVGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLEdBQUc7QUFDSDtBQUNBLENBQUM7O0FBRUQ7QUFDQSxjQUFjLHNEQUFzRDtBQUNwRTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsSUFBSTtBQUNKO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQSxDQUFDOztBQUVEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxDQUFDOzs7QUFHRDtBQUNBLGNBQWMsbUNBQW1DO0FBQ2pELGVBQWUsNkRBQTZEO0FBQzVFOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7QUFDQSxFQUFFO0FBQ0YsQ0FBQzs7O0FBR0Q7O0FBRUE7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0EsRUFBRTs7QUFFRjtBQUNBO0FBQ0EsRUFBRTtBQUNGOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxDQUFDOztBQUVEO0FBQ0E7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7O0FBS0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUFBO0FBQ0Y7Ozs7O0FBS0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7QUFLQTtBQUNBLENBQUM7Ozs7Ozs7QUM1Z1VEOztBQUVBO0FBQ0E7QUFDQTtBQUNBLENBQUM7O0FBRUQ7QUFDQTtBQUNBO0FBQ0EsQ0FBQztBQUNEO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSw0Q0FBNEM7O0FBRTVDOzs7Ozs7Ozs7Ozs7Ozs7Ozs7QUNuQkE7Ozs7O0FBS0EsbUJBQUFBLENBQVEsQ0FBUjtBQUNBLG1CQUFBQSxDQUFRLENBQVI7O0FBRUE7Ozs7O0FB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QTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsZUFBZTtBQUNmLGNBQWM7QUFDZCxjQUFjO0FBQ2QsZ0JBQWdCO0FBQ2hCLGVBQWU7QUFDZjs7QUFFQTtBQUNBO0FBQ0EsVUFBVTtBQUNWLFNBQVM7QUFDVCxTQUFTO0FBQ1QsV0FBVztBQUNYLFVBQVU7QUFDVjs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0wsR0FBRzs7QUFFSDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGFBQWEsT0FBTztBQUNwQixhQUFhLE1BQU07QUFDbkIsZUFBZSxPQUFP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QUFDQSxtQkFBbUIsZ0NBQWdDO0FBQ25EO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGlDQUFpQyw2QkFBNkI7QUFDOUQ7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLOztBQUVMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsZUFBZSxRQUFRO0FBQ3ZCO0FBQ0EsT0FBTztBQUNQLEtBQUs7O0FBRUw7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGtFQUFrRTtBQUNsRTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNB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OztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSxFQUFFO0FBQ2pCLGlCQUFpQixRQUFRO0FBQ3pCO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSxPQUFPO0FBQ3RCLGVBQWUsT0FBTztBQUN0QixlQUFlLE1BQU07QUFDckIsZUFBZSxTQUFTO0FBQ3hCLGlCQUFpQixRQUFRO0FBQ3pCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLEVBQUU7QUFDakIsaUJBQWlCLFFBQVE7QUFDekI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSxFQUFFO0FBQ2pCLGlCQUFpQixRQUFRO0FBQ3pCO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSxFQUFFO0FBQ2pCLGlCQUFpQixRQUFRO0FBQ3pCO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSxFQUFFO0FBQ2pCLGlCQUFpQixRQUFRO0FBQ3pCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLEVBQUU7QUFDakIsaUJBQWlCLFNBQVM7QUFDMUI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFD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QUN4QixlQUFlLFNBQVM7QUFDeEIsZUFBZSxPQUFPO0FBQ3RCLGlCQUFpQixRQUFRO0FBQ3pCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsT0FBTztBQUN0QixlQUFlLE9BQU87QUFDdEIsZUFBZSxPQUFPO0FBQ3RCLGVBQWUsU0FBUztBQUN4QixlQUFlLFNBQVM7QUFDeEIsZUFBZSxPQUFPO0FBQ3RCLGlCQUFpQixRQUFRO0FBQ3pCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLFNBQVM7QUFDeEIsaUJBQWlCLFNBQVM7QUFDMUI7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLE9BQU87QUFDdEIs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QUFDakIsaUJBQWlCLFFBQVE7QUFDekI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSxFQUFFO0FBQ2pCLGVBQWUsT0FBTztBQUN0QixpQkFBaUIsUUFBUTtBQUN6QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsRUFBRTtBQUNqQixpQkFBaUIsUUFBUTtBQUN6QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsU0FBUztBQUN4QixpQkFBaUIsUUFBUTtBQUN6QjtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsU0FBUztBQUN4QixpQkFBaUIsUUFBUTtBQUN6QjtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsRUFBRTtBQUNqQixpQkFBaUIsUUFBUTtBQUN6QjtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSxFQUFFO0FBQ2pCLGlCQUFpQixRQUFRO0FBQ3pCO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLEVBQUU7QUFDakIsaUJBQWlCLFFBQVE7QUFDekI7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSxPQUFPO0FBQ3RCLGVBQWUsRUFBRTtBQUNqQixpQkFBaUIsU0FBUztBQUMxQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtB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O0FBQ1Y7QUFDQTtBQUNBO0FBQ0E7QUFDQSxjQUFjO0FBQ2Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxjQUFjO0FBQ2Q7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxpQkFBaUIsT0FBTztBQUN4QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGlCQUFpQixPQUFPO0FBQ3hCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxjQUFjO0FBQ2Q7QUFDQTtBQUNBLGNBQWM7QUFDZDtBQUNBO0FBQ0EsY0FBYztBQUNkO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBLGNBQWM7QUFDZDs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGlCQUFpQixPQUFPO0FBQ3hCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSxFQUFFO0FBQ2pCLGlCQUFpQixPQUFPO0FBQ3hCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxpQkFBaUIsT0FBTztBQUN4QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtB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QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLFNBQVM7QUFDeEIsZUFBZSxPQUFPO0FBQ3RCLGVBQWUsT0FBTyxZQUFZO0FBQ2xDLGVBQWUsUUFBUTtBQUN2QjtBQUNBLGVBQWUsT0FBTztBQUN0QjtBQUNBLGVBQWUsUUFBUTtBQUN2QjtBQUNBLGlCQUFpQixTQUFTO0FBQzFCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFFBQVE7QUFDUjtBQUNBO0FBQ0Esa0RBQWtELGtCQUFrQjtBQUNwRTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVB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QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSxTQUFTO0FBQ3hCLGVBQWUsS0FBSztBQUNwQixpQkFBaUIsU0FBUztBQUMxQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLOztBQUVMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSxTQUFTO0FBQ3hCLGVBQWUscUJBQXFCO0FBQ3BDLGlCQUFpQixTQUFTO0FBQzFCO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsUUFBUTtBQUNSO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7O0FBRUw7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSxTQUFTO0FBQ3hCLGVBQWUsT0FBTztBQUN0QixpQkFBaUIsU0FBUztBQUMxQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsUUFBUTtBQUNSO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSxTQUFTO0FBQ3hCLGVBQWUsT0FBTztBQUN0QixpQkFBaUIsU0FBUztBQUMxQjtBQUNBO0FBQ0E7QUFDQTtBQUNBLFFBQVE7QUFDUjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsUUFBUTtBQUNSO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsT0FBTztBQUNQOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFD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QUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLEVBQUU7QUFDakIsaUJBQWlCLFFBQVE7QUFDekI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsRUFBRTtBQUNqQixpQkFBaUIsUUFBUTtBQUN6QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLEVBQUU7QUFDakIsaUJBQWlCLFFBQVE7QUFDekI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSxFQUFFO0FBQ2pCLGlCQUFpQixRQUFRO0FBQ3pCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsRUFBRTtBQUNqQixpQkFBaUIsUUFBUTtBQUN6QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLEVBQUU7QUFDakIsaUJBQWlCLFFBQVE7QUFDekI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSxFQUFFO0FBQ2pCLGlCQUFpQixRQUFRO0FBQ3pCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsRUFBRTtBQUNqQixpQkFBaUIsUUFBUTtBQUN6QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esa0JBQWtCLFNBQVM7QUFDM0I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsRUFBRTtBQUNqQixlQUFlLEVBQUU7QUFDakIsaUJBQWlCLFFBQVE7QUFDekI7QUFDQTtBQUNBLHFCQUFxQjtBQUNyQixvQkFBb0I7QUFDcEI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLEVBQUU7QUFDakIsZUFBZSxFQUFFO0FBQ2pCLGVBQWUsU0FBUztBQUN4QixpQkFBaUIsUUFBUTtBQUN6QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLEVBQUU7QUFDakIsaUJBQWlCLFFBQVE7QUFDekI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLEVBQUU7QUFDakIsaUJBQWlCLFFBQVE7QUFDekI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsRUFBRTtBQUNqQixpQkFBaUIsUUFBUTtBQUN6QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSxFQUFFO0FBQ2pCLGlCQUFpQixRQUFRO0FBQ3pCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLEVBQUU7QUFDakIsaUJBQWlCLFFBQVE7QUFDekI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsRUFBRTtBQUNqQixpQkFBaUIsUUFBUTtBQUN6QjtBQUNBO0FBQ0Esb0JBQW9CO0FBQ3BCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSxFQUFFO0FBQ2pCLGlCQUFpQixRQUFRO0FBQ3pCO0FBQ0E7QUFDQSx3QkFBd0I7QUFDeEI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsRUFBRTtBQUNqQixpQkFBaUIsUUFBUTtBQUN6QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSxPQUFPO0FBQ3RCLGVBQWUsT0FBTztBQUN0QixpQkFBaUIsUUFBUTtBQUN6QjtBQUNBO0FBQ0EscUJBQXFCO0FBQ3JCO0FBQ0EsMEJBQTBCLFNBQVM7QUFDbkM7QUFDQTtBQUNBLDBCQUEwQixTQUFTO0FBQ25DO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLE9BQU87QUFDdEIsZUFBZSxPQUFPO0FBQ3RCLGVBQWUsU0FBUztBQUN4QixpQkFBaUIsUUFBUTtBQUN6QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxxQkFBcUI7QUFDckIscUJBQXFCO0FBQ3JCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSxFQUFFO0FBQ2pCLGlCQUFpQixRQUFRO0FBQ3pCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSxFQUFFO0FBQ2pCLGlCQUFpQixRQUFRO0FBQ3pCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsRUFBRTtBQUNqQixpQkFBaUIsUUFBUTtBQUN6QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSxFQUFFO0FBQ2pCLGlCQUFpQixRQUFRO0FBQ3pCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLEVBQUU7QUFDakIsaUJBQWlCLFFBQVE7QUFDekI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLEVBQUU7QUFDakIsaUJBQWlCLFFBQVE7QUFDekI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esd0JBQXdCLGlCQUFpQjtBQUN6QztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSxFQUFFO0FBQ2pCLGlCQUFpQixRQUFRO0FBQ3pCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSxFQUFFO0FBQ2pCLGlCQUFpQixRQUFRO0FBQ3pCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLEVBQUU7QUFDakIsaUJBQWlCLFFBQVE7QUFDekI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSxFQUFFO0FBQ2pCLGlCQUFpQixRQUFRO0FBQ3pCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsRUFBRTtBQUNqQixpQkFBaUIsUUFBUTtBQUN6QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLEVBQUU7QUFDakIsaUJBQWlCLFFBQVE7QUFDekI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSxFQUFFO0FBQ2pCLGlCQUFpQixRQUFRO0FBQ3pCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLEVBQUU7QUFDakIsaUJBQWlCLFFBQVE7QUFDekI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsRUFBRTtBQUNqQixpQkFBaUIsUUFBUTtBQUN6QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSxFQUFFO0FBQ2pCLGVBQWUsRUFBRTtBQUNqQixpQkFBaUIsUUFBUTtBQUN6QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSxFQUFFO0FBQ2pCLGVBQWUsRUFBRTtBQUNqQixpQkFBaUIsUUFBUTtBQUN6QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLOztBQUVMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSxFQUFFO0FBQ2pCLGlCQUFpQixNQUFNO0FBQ3ZCO0FBQ0E7QUFDQSxrQkFBa0IsaUJBQWlCO0FBQ25DO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtB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QTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsT0FBTztBQUN0QixlQUFlLE9BQU87QUFDdEIsZUFBZSxPQUFPO0FBQ3RCLGlCQUFpQixRQUFRO0FBQ3pCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxPQUFPO0FBQ1A7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsT0FBTztBQUN0QixlQUFlLE9BQU87QUFDdEIsZUFBZSxRQUFRO0FBQ3ZCLGlCQUFpQixPQUFPO0FBQ3hCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLE9BQU87QUFDdEIsaUJBQWlCLE9BQU87QUFDeEI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7O0FBRUw7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsT0FBTztBQUN0QixpQkFBaUIsT0FBTztBQUN4QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLE9BQU87QUFDdEIsaUJBQWlCLE9BQU87QUFDeEI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSxPQUFPO0FBQ3RCLGVBQWUsT0FBTztBQUN0QixlQUFlLE9BQU87QUFDdEIsaUJBQWlCLFFBQVE7QUFDekI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsT0FBTztBQUN0QixpQkFBaUIsT0FBTztBQUN4QjtBQUNBO0FBQ0E7QUFDQSxpQ0FBaUM7QUFDakM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLGtDQUFrQyxLQUFLO0FBQ3ZDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLE9BQU87QUFDdEIsaUJBQWlCLE9BQU87QUFDeEI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSxPQUFPO0FBQ3RCLGlCQUFpQixPQUFPO0FBQ3hCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSzs7QUFFTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsT0FBTztBQUN0QixpQkFBaUIsT0FBTztBQUN4QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7O0FBRUw7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLE9BQU87QUFDdEIsaUJBQWlCLE9BQU87QUFDeEI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLE9BQU87QUFDdEIsZUFBZSxPQUFPO0FBQ3RCLGVBQWUsT0FBTztBQUN0QixpQkFBaUIsT0FBTztBQUN4QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsT0FBTztBQUN0QixlQUFlLE9BQU87QUFDdEIsZUFBZSxPQUFPO0FBQ3RCLGlCQUFpQixPQUFPO0FBQ3hCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSxPQUFPO0FBQ3RCLGVBQWUsT0FBTztBQUN0QixlQUFlLE9BQU87QUFDdEIsaUJBQWlCLE9BQU87QUFDeEI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsT0FBTztBQUN0QixlQUFlLE9BQU87QUFDdEIsZ0JBQWdCLE9BQU87QUFDdkIsaUJBQWlCLE9BQU87QUFDeEI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE9BQU87QUFDUDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsT0FBTztBQUN0QixlQUFlLE9BQU87QUFDdEIsZ0JBQWdCLE9BQU87QUFDdkIsaUJBQWlCLE9BQU87QUFDeEI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE9BQU87QUFDUDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsT0FBTztBQUN0QixlQUFlLGNBQWM7QUFDN0IsZUFBZSxnQkFBZ0I7QUFDL0IsaUJBQWlCLE9BQU87QUFDeEI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLE9BQU87QUFDdEIsaUJBQWlCLE9BQU87QUFDeEI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLOztBQUVMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSxPQUFPO0FBQ3RC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O0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxPQUFPO0FBQ1A7QUFDQSxLQUFLLE1BQU0saUJBQWlCOztBQUU1Qjs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsY0FBYztBQUNkO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsS0FBSzs7QUFFTDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQSxXQUFXO0FBQ1g7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7O0FBRUw7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQSxLQUFLOztBQUVMO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxLQUFLOztBQUVMO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxLQUFLOztBQUVMO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE9BQU87QUFDUCxLQUFLOztBQUVMO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE9BQU87QUFDUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLG1DQUFtQyw0REFBNEQ7QUFDL0Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7O0FBRUw7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0EsS0FBSzs7QUFFTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsb0JBQW9CLHlDQUF5QztBQUM3RDtBQUNBLEtBQUs7O0FBRUw7QUFDQTtBQUNBO0FBQ0EsS0FBSzs7QUFFTDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHOztBQUVIOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQUE7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxDQUFDOzs7Ozs7OztBQzNyaEJEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTs7Ozs7OztBQ3JCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLENBQUM7O0FBRUQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQUdBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsZ0JBQWdCO0FBQ2hCO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGdEQUFnRCxnQkFBZ0I7QUFDaEUsZ0NBQWdDO0FBQ2hDO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRzs7QUFFSCxDQUFDOztBQUVEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUFHQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQUdBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLEtBQUs7QUFDTDs7QUFFQTs7QUFFQTtBQUNBOzs7QUFHQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOzs7QUFHQTtBQUNBOztBQUVBOztBQUVBLENBQUM7O0FBRUQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQUdBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsZ0NBQWdDO0FBQ2hDO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLE9BQU87QUFDUDtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7O0FBRUE7QUFDQTs7O0FBR0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7O0FBRUE7O0FBRUE7QUFDQTs7O0FBR0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7O0FBR0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBLEtBQUs7O0FBRUwsQ0FBQzs7QUFFRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FBR0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsMkJBQTJCO0FBQzNCLDJCQUEyQjtBQUMzQjtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBLHNGQUFzRixlQUFlO0FBQ3JHOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBOztBQUVBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsaURBQWlELHFEQUFxRDtBQUN0RztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxXQUFXO0FBQ1gsU0FBUztBQUNUO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTs7O0FBR0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLCtCQUErQjtBQUMvQjs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDs7QUFFQTs7QUFFQTtBQUNBOzs7QUFHQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOzs7QUFHQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSw2QkFBNkI7QUFDN0I7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0wsR0FBRzs7QUFFSCxDQUFDOztBQUVEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUFHQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLG9DQUFvQztBQUNwQztBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUE7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE9BQU87QUFDUDtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOzs7QUFHQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsK0JBQStCOztBQUUvQjtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7O0FBRUE7O0FBRUE7QUFDQTs7O0FBR0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7O0FBR0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLEdBQUc7O0FBRUgsQ0FBQzs7QUFFRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FBR0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsMkJBQTJCO0FBQzNCOztBQUVBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUE7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsMkJBQTJCOztBQUUzQjs7QUFFQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0EsS0FBSztBQUNMOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTs7O0FBR0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsS0FBSztBQUNMOztBQUVBOztBQUVBO0FBQ0E7OztBQUdBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7OztBQUdBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLHNFQUFzRSxzQkFBc0I7QUFDNUY7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsQ0FBQzs7QUFFRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FBR0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTs7QUFFQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSx5Q0FBeUMsZ0NBQWdDOztBQUV6RTs7QUFFQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxPQUFPO0FBQ1AsS0FBSzs7QUFFTDtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQSx5Q0FBeUMsZ0NBQWdDOztBQUV6RTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFdBQVc7QUFDWDtBQUNBO0FBQ0EsS0FBSztBQUNMOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUE7O0FBRUE7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE9BQU87QUFDUDs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE9BQU87QUFDUCxLQUFLO0FBQ0w7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE9BQU87O0FBRVA7O0FBRUE7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSxLQUFLO0FBQ0w7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMOztBQUVBO0FBQ0E7QUFDQSwyQkFBMkI7QUFDM0I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBLGtEQUFrRDtBQUNsRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FBR0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLCtCQUErQjs7QUFFL0I7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMOztBQUVBOztBQUVBO0FBQ0E7OztBQUdBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7OztBQUdBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxrRUFBa0Usa0NBQWtDOztBQUVwRzs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE9BQU87QUFDUCxLQUFLO0FBQ0w7QUFDQSxHQUFHOztBQUVILENBQUM7O0FBRUQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FBR0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUEsaUNBQWlDLEtBQUs7QUFDdEM7O0FBRUE7QUFDQTtBQUNBLE9BQU87QUFDUDtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0Esa0NBQWtDLGlCQUFpQixrQ0FBa0M7QUFDckY7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSx5QkFBeUI7O0FBRXpCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsS0FBSzs7QUFFTDtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0EsS0FBSztBQUNMOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0EsS0FBSztBQUNMOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLGNBQWMsb0NBQW9DO0FBQ2xEO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQSxLQUFLOztBQUVMOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLHVFQUF1RTtBQUN2RSwwQkFBMEIsV0FBVyx3RUFBd0U7QUFDN0c7QUFDQSw4QkFBOEIsa0JBQWtCO0FBQ2hELHFCQUFxQjtBQUNyQiw4QkFBOEIsdURBQXVEOztBQUVyRixzQkFBc0I7QUFDdEI7O0FBRUE7QUFDQSxvQ0FBb0MsZ0ZBQWdGO0FBQ3BILG9DQUFvQyxnRkFBZ0Y7QUFDcEgsb0NBQW9DLGlGQUFpRjtBQUNySCxvQ0FBb0M7O0FBRXBDOztBQUVBO0FBQ0EsaUJBQWlCO0FBQ2pCOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsbURBQW1EO0FBQ25EO0FBQ0EsT0FBTyxrRkFBa0Y7QUFDekY7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0EscURBQXFEO0FBQ3JEO0FBQ0EsT0FBTyx1REFBdUQ7QUFDOUQ7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMOzs7QUFHQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMOztBQUVBOztBQUVBO0FBQ0E7OztBQUdBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsQ0FBQzs7QUFFRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FBR0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTs7QUFFQSxnQ0FBZ0M7QUFDaEM7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHOzs7QUFHSDtBQUNBOztBQUVBLGlDQUFpQzs7QUFFakM7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7OztBQUdBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7O0FBRUE7O0FBRUE7QUFDQTs7O0FBR0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSxDQUFDOztBQUVEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUFHQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EscUNBQXFDO0FBQ3JDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsT0FBTztBQUNQLDZCQUE2QixxQkFBcUI7QUFDbEQ7QUFDQTtBQUNBO0FBQ0EsT0FBTztBQUNQOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSw0QkFBNEIsS0FBSztBQUNqQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUFHQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLEtBQUs7QUFDTDs7QUFFQTs7QUFFQTtBQUNBOzs7QUFHQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOzs7QUFHQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMLEdBQUc7O0FBRUgsQ0FBQzs7QUFFRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FBR0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBLEtBQUs7O0FBRUw7QUFDQTs7QUFFQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsT0FBTztBQUNQO0FBQ0E7QUFDQTtBQUNBLE9BQU87QUFDUCxLQUFLO0FBQ0w7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLE9BQU87QUFDUDtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7OztBQUdBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLEtBQUs7QUFDTDs7QUFFQTs7QUFFQTtBQUNBOzs7QUFHQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOzs7QUFHQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQSxDQUFDOztBQUVEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUFHQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQSw4QkFBOEI7O0FBRTlCO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxPQUFPO0FBQ1A7QUFDQTs7O0FBR0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7O0FBRUE7O0FBRUE7QUFDQTs7O0FBR0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7O0FBR0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0EsS0FBSztBQUNMLEdBQUc7O0FBRUgsQ0FBQzs7Ozs7Ozs7QUNoeEVEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFD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QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsT0FBTztBQUNQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGlEQUFpRCxPQUFPO0FBQ3hEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsY0FBYztBQUNkO0FBQ0E7QUFDQSxp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QTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxtQkFBbUIsMkJBQTJCO0FBQzlDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBLEdBQUc7QUFDSDtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxrQ0FBa0MsU0FBUztBQUMzQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsMkJBQTJCLHVCQUF1QjtBQUNsRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBLDBCQUEwQixVQUFVOztBQUVwQztBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsaUJBQWlCLFNBQVM7QUFDMUI7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsdUNBQXVDO0FBQ3ZDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxDQUFDOztBQUVEO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxxQkFBcUIsbUJBQW1CO0FBQ3hDO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHVCQUF1QixvQkFBb0I7QUFDM0M7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxzQkFBc0IsbUNBQW1DO0FBQ3pELG1CQUFtQixrQkFBa0I7QUFDckM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsaUJBQWlCLHFCQUFxQjtBQUN0QztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsYUFBYSxxQkFBcUI7QUFDbEM7QUFDQSwrQ0FBK0M7QUFDL0M7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE9BQU87QUFDUDtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0EsT0FBTztBQUNQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esb0JBQW9CO0FBQ3BCO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBOztBQUVBO0FBQ0EsMENBQTBDLE9BQU87QUFDakQ7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLOztBQUVMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7O0FBRUw7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsT0FBTztBQUNQOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFdBQVc7QUFDWDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsV0FBVztBQUNYO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBLG1CQUFtQixxQkFBcUI7QUFDeEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLCtDQUErQztBQUMvQzs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsdUNBQXVDLE9BQU87QUFDOUM7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsdUNBQXVDLE9BQU87QUFDOUM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHFDQUFxQyxPQUFPO0FBQzVDO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esc0NBQXNDLE9BQU87QUFDN0M7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsT0FBTztBQUNQO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsaUJBQWlCLGdCQUFnQjtBQUNqQztBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsT0FBTztBQUNQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EsMEJBQTBCOztBQUUxQixrQkFBa0I7QUFDbEI7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLG1CQUFtQixxQkFBcUI7QUFDeEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsdUJBQXVCO0FBQ3ZCO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQSxtQkFBbUIseUJBQXlCO0FBQzVDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsbUJBQW1CLHlCQUF5QjtBQUM1QztBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLHdDQUF3QyxPQUFPO0FBQy9DO0FBQ0E7QUFDQSxPQUFPO0FBQ1A7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7O0FBR0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDhCQUE4QixvQkFBb0IsRUFBRTs7QUFFcEQ7QUFDQTtBQUNBLGlCQUFpQixzQkFBc0I7QUFDdkM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLGlCQUFpQixrQkFBa0I7QUFDbkM7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0Esb0JBQW9CO0FBQ3BCO0FBQ0EseUJBQXlCO0FBQ3pCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQSxPQUFPO0FBQ1A7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsaUJBQWlCLHlCQUF5QjtBQUMxQyxHQUFHO0FBQ0g7QUFDQTtBQUNBLGlCQUFpQiwrQkFBK0I7QUFDaEQ7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLG1CQUFtQiwyQkFBMkI7QUFDOUMscUJBQXFCLCtCQUErQjtBQUNwRDtBQUNBO0FBQ0EsR0FBRztBQUNILHlCQUF5QjtBQUN6QjtBQUNBLHNCQUFzQixpQ0FBaUM7QUFDdkQ7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE9BQU87QUFDUCxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBOztBQUVBLDhCQUE4Qjs7QUFFOUI7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBLE9BQU87QUFDUDtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxxQkFBcUIsb0JBQW9CO0FBQ3pDO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSw2QkFBNkI7QUFDN0I7QUFDQSw4QkFBOEI7QUFDOUI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNULE9BQU87QUFDUDtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUOztBQUVBLG1CQUFtQixpQkFBaUI7QUFDcEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSCw0QkFBNEIsK0JBQStCO0FBQzNELDRCQUE0QiwrQkFBK0I7QUFDM0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQSxpQ0FBaUMsa0RBQWtEO0FBQ25GO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esd0JBQXdCLHdDQUF3QztBQUNoRSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQSxxQ0FBcUM7QUFDckM7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBLDhCQUE4QjtBQUM5QjtBQUNBO0FBQ0EsR0FBRzs7QUFFSDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7O0FBRUg7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsT0FBTztBQUNQO0FBQ0E7QUFDQTtBQUNBLEdBQUc7O0FBRUg7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE9BQU87QUFDUDtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSyx1RkFBdUY7QUFDNUY7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFD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QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0EscUJBQXFCO0FBQ3JCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsdUJBQXVCO0FBQ3ZCO0FBQ0Esb0JBQW9CO0FBQ3BCOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxzQkFBc0IsZUFBZTtBQUNyQztBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsbUJBQW1CLG1CQUFtQjtBQUN0QztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxzRUFBc0U7QUFDdEU7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxpQ0FBaUM7O0FBRWpDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsT0FBTztBQUNQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSx3QkFBd0I7QUFDeEI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDs7QUFFQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxHQUFHOztBQUVIO0FBQ0E7QUFDQSxH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QUssMENBQTBDO0FBQ3JEO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsNkNBQTZDLGtCQUFrQjtBQUMvRCxzQkFBc0IsK0NBQStDO0FBQ3JFLGlEQUFpRDs7QUFFakQ7QUFDQSxzREFBc0Q7QUFDdEQ7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSw4Q0FBOEM7QUFDOUM7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsMkJBQTJCO0FBQzNCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsMkNBQTJDO0FBQzNDOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSwyQkFBMkIsMkJBQTJCO0FBQ3RELGtDQUFrQztBQUNsQzs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7OztBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsT0FBTyw2Q0FBNkMsRUFBRTtBQUN0RDtBQUNBOztBQUVBO0FBQ0E7QUFDQSxrQ0FBa0M7QUFDbEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0Esd0JBQXdCO0FBQ3hCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBLENBQUM7O0FBRUQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0EsVUFBVTtBQUNWO0FBQ0EsdUNBQXVDLFNBQVM7QUFDaEQ7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsaUJBQWlCLHdCQUF3QjtBQUN6QztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsQ0FBQzs7QUFFRDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZTtBQUNmOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSw2Q0FBNkMsNEJBQTRCLEVBQUU7QUFDM0UsS0FBSztBQUNMO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSw2Q0FBNkMsK0JBQStCLEVBQUU7QUFDOUUsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLENBQUM7O0FBRUQ7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxjQUFjO0FBQ2Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0EsR0FBRzs7QUFFSDtBQUNBO0FBQ0EsMkRBQTJEO0FBQzNEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRzs7QUFFSDtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSw2REFBNkQ7QUFDN0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFdBQVc7QUFDWDtBQUNBO0FBQ0E7QUFDQSxPQUFPO0FBQ1A7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBLENBQUM7O0FBRUQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUEsaUNBQWlDLHFDQUFxQzs7QUFFdEU7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsMkNBQTJDLHVDQUF1QyxFQUFFO0FBQ3BGO0FBQ0E7QUFDQTtBQUNBLDZDQUE2QywyQ0FBMkMsRUFBRTtBQUMxRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHdDQUF3QyxPQUFPO0FBQy9DO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxxQ0FBcUMsOEJBQThCLEVBQUU7QUFDckU7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLDRCQUE0QjtBQUM1QjtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxPQUFPO0FBQ1AsS0FBSztBQUNMO0FBQ0E7QUFDQSxHQUFHOztBQUVIO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLDZCQUE2QjtBQUM3QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVCxPQUFPO0FBQ1A7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0EsR0FBRzs7QUFFSDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSw2Q0FBNkMsdUNBQXVDLEVBQUU7QUFDdEY7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSw4Q0FBOEM7QUFDOUM7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsMEVBQTBFLDBCQUEwQixFQUFFO0FBQ3RHO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHFFQUFxRTtBQUNyRTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBLE9BQU87QUFDUDtBQUNBO0FBQ0E7QUFDQTtBQUNBLHdDQUF3QyxnQkFBZ0I7QUFDeEQ7QUFDQTtBQUNBLGdFQUFnRSxzQkFBc0IsRUFBRTtBQUN4RjtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsdUNBQXVDO0FBQ3ZDO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsQ0FBQzs7QUFFRDs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBLG1CQUFtQix3QkFBd0I7QUFDM0M7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFdBQVcsdUJBQXVCO0FBQ2xDLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsdUJBQXVCLDJCQUEyQjtBQUNsRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLEdBQUc7O0FBRUg7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRzs7QUFFSDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsOEJBQThCOztBQUU5QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQSxLQUFLO0FBQ0wsR0FBRzs7QUFFSDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esc0RBQXNELHlCQUF5QixFQUFFO0FBQ2pGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsQ0FBQzs7QUFFRDs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLGdFQUFnRTs7QUFFaEU7O0FBRUEsc0JBQXNCLEVBQUUsY0FBYyxFQUFFO0FBQ3hDLCtCQUErQjs7QUFFL0I7QUFDQTtBQUNBO0FBQ0E7QUFDQSxDQUFDOztBQUVEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGtDQUFrQyxPQUFPO0FBQ3pDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxvQ0FBb0MsT0FBTztBQUMzQztBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7O0FBRUE7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QUFDQSxLQUFLOztBQUVMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLOztBQUVMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsV0FBVztBQUNYO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFdBQVc7QUFDWCxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0EsV0FBVztBQUNYO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE9BQU87QUFDUDtBQUNBLEdBQUc7QUFDSDtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxtQkFBbUIsT0FBTztBQUMxQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTCxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTCxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FB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QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsQ0FBQzs7QUFFRDs7QUFFQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLENBQUM7O0FBRUQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsT0FBTztBQUNQO0FBQ0EsT0FBTztBQUNQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxPQUFPO0FBQ1A7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7Ozs7Ozs7Ozs7OztBQy84VEE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBLFNBQVM7QUFDVCxLQUFLO0FBQ0w7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBLHVCQUF1QixxQkFBcUI7QUFDNUM7QUFDQTtBQUNBLEtBQUs7QUFDTDs7QUFFQTtBQUNBO0FBQ0EsdUJBQXVCLHFCQUFxQjtBQUM1QztBQUNBO0FBQ0EsS0FBSztBQUNMOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsaUJBQWlCO0FBQ2pCO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsaUJBQWlCO0FBQ2pCO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSx5QkFBeUI7QUFDekI7QUFDQTtBQUNBLHFCQUFxQjtBQUNyQjtBQUNBO0FBQ0EseUJBQXlCO0FBQ3pCO0FBQ0E7QUFDQTtBQUNBLGlCQUFpQjtBQUNqQjtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBOzs7O0FBSUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUEsMEJBQTBCLHlCQUF5QixRQUFRLGVBQWU7QUFDMUU7O0FBRUE7O0FBRUE7O0FBRUE7QUFDQSxtQkFBbUIsZ0JBQWdCO0FBQ25DO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUE7O0FBRUE7O0FBRUE7QUFDQTtBQUNBLEtBQUs7O0FBRUw7QUFDQTs7QUFFQTs7QUFFQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBLEtBQUs7O0FBRUw7QUFDQTs7QUFFQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0EsS0FBSzs7QUFFTDtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNB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QSxHQUFHO0FBQ0g7QUFDQSxHQUFHO0FBQ0g7QUFDQSxHQUFHO0FBQ0g7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQSwyRUFBMkUsYUFBYTtBQUN4RjtBQUNBLE9BQU87QUFDUDtBQUNBLHNDQUFzQyxRQUFRO0FBQzlDO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBLEdBQUc7QUFDSDtBQUNBLEdBQUc7QUFDSDtBQUNBLEdBQUc7QUFDSDtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBLDJFQUEyRSxhQUFhO0FBQ3hGO0FBQ0EsT0FBTztBQUNQO0FBQ0Esc0NBQXNDLFFBQVE7QUFDOUM7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0EsR0FBRztBQUNIO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQSxHQUFHO0FBQ0g7QUFDQSxHQUFHO0FBQ0g7QUFDQSxHQUFHO0FBQ0g7QUFDQSxHQUFHO0FBQ0g7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQSxHQUFHO0FBQ0g7QUFDQSxHQUFHO0FBQ0g7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQSwyRUFBMkUsYUFBYTtBQUN4RjtBQUNBLE9BQU87QUFD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QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUEsQ0FBQztBQUNEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0EsQ0FBQztBQUNEOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHVDQUF1QyxrQkFBa0I7QUFDekQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsYUFBYTs7QUFFYjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxvREFBb0QsWUFB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QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLCtDQUErQyxrQkFBa0I7QUFDakU7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTOztBQUVUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTOztBQUVUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxtQ0FBbUM7QUFDbkM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsNkJBQTZCO0FBQzdCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSx5QkFBeUI7QUFDekI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHFCQUFxQjtBQUNyQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHFCQUFxQjtBQUNyQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7O0FBRVQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUzs7QUFFVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGlCQUFpQjtBQUNqQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUzs7QUFFVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTOztBQUVUO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUzs7QUFFVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsNkNBQTZDLGtCQUFrQjtBQUMvRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxxQkFBcUI7QUFDckI7QUFDQSxxQkFBcUI7QUFDckI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHFCQUFxQjtBQUNyQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGlCQUFpQjtBQUNqQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7O0FBRVQ7QUFDQTtBQUNBO0FBQ0EscUNBQXFDO0FBQ3JDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNB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O0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxpQ0FBaUM7QUFDakM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBLEtBQUs7O0FBRUwsQ0FBQzs7Ozs7OztBQ3o4Q0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUNBLEVBQUU7O0FBRUY7QUFDQTtBQUNBO0FBQ0EsQ0FBQzs7QUFFRDtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLGNBQWMsK0JBQStCO0FBQzdDOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxJQUFJO0FBQ0o7QUFDQTtBQUNBO0FBQ0EsQ0FBQzs7QUFFRDtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSx3Q0FBd0M7QUFDeEM7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLHNCQUFzQjs7QUFFdEI7QUFDQTtBQUNBO0FBQ0EsRUFBRTs7QUFFRjs7QUFFQTtBQUNBO0FBQ0E7QUFDQSw0Q0FBNEM7QUFDNUM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLEdBQUc7QUFDSCxFQUFFO0FBQ0Y7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFFOztBQUVGO0FBQ0E7QUFDQTtBQUNB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QUFFQTtBQUNBO0FBQ0EsR0FBRzs7QUFFSDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxFQUFFOztBQUVGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSCxFQUFFOztBQUVGO0FBQ0E7QUFDQSxFQUFFOztBQUVGO0FBQ0E7QUFDQSxFQUFFOztBQUVGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFFOztBQUVGO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7QUFDQTtBQUNBLEdBQUc7QUFDSCxFQUFFOztBQUVGO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTs7QUFFRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7O0FBRUY7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0gsRUFBRTs7QUFFRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSCxFQUFFOztBQUVGO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBLFNBQVMsa0NBQWtDO0FBQzNDO0FBQ0E7QUFDQSxjQUFjO0FB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QSw4Q0FBOEMsT0FBTztBQUNyRDs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYTtBQUNiLDBDQUEwQztBQUMxQztBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHVCQUF1QixpQkFBaUI7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QUNUO0FBQ0E7QUFDQSxPQUFPOztBQUVQLEtBQUs7QUFDTDs7QUFFQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQSxxQkFBcUIsMEJBQTBCO0FBQy9DOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLE9BQU87O0FBRVA7O0FBRUE7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLOztBQUVMO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsS0FBSzs7QUFFTDtBQUNBO0FBQ0E7QUFDQSxLQUFLOztBQUVMO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxLQUFLOztBQUVMO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxLQUFLOztBQUVMO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxLQUFLOztBQUVMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLOztBQUVMO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0EsS0FBSzs7QUFFTDtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBLGdDQUFnQztBQUNoQyxPQUFPO0FBQ1A7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBLEtBQUs7O0FBRUw7QUFDQTs7QUFFQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLE9BQU87QUFDUDtBQUNBO0FBQ0EsS0FBSzs7QUFFTDtBQUNBOztBQUVBOztBQUVBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxPQUFPO0FBQ1A7QUFDQTtBQUNBLEtBQUs7O0FBRUw7QUFDQTtBQUNBLEtBQUs7O0FBRUw7QUFDQTtBQUNBLEtBQUs7O0FBRUw7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxPQUFPO0FBQ1A7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxXQUFXO0FBQ1gsU0FBUztBQUNULGtDQUFrQztBQUNsQzs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLE9BQU87QUFDUCxLQUFLOztBQUVMO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLE9BQU87QUFDUCxLQUFLO0FBQ0w7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLENBQUM7O0FBRUQ7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLENBQUM7O0FBRUQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0EsS0FBSzs7QUFFTDtBQUNBO0FBQ0EsS0FBSzs7QUFFTDtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7O0FBRUw7QUFDQTtBQUNBLEtBQUs7O0FBRUw7QUFDQTtBQUNBLEtBQUs7O0FBRUw7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxLQUFLOztBQUVMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQSxLQUFLOztBQUVMO0FBQ0E7QUFDQSxLQUFLOztBQUVMO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLEtBQUs7QUFDTDs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQSxPQUFPO0FBQ1AsS0FBSztBQUNMOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0EsQ0FBQzs7QUFFRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsT0FBTztBQUNQLEtBQUs7O0FBRUw7QUFDQTtBQUNBLEtBQUs7O0FBRUw7QUFDQTtBQUNBLEtBQUs7O0FBRUw7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLOztBQUVMO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0EsQ0FBQzs7QUFFRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxPQUFPO0FBQ1AsS0FBSzs7QUFFTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxrQkFBa0I7QUFDbEI7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUEsbUJBQW1CLGlCQUFpQjtBQUNwQzs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0EsQ0FBQzs7QUFFRDtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQSxDQUFDOztBQUVEO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsMEJBQTBCOztBQUUxQjtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsS0FBSzs7QUFFTDtBQUNBO0FBQ0EsS0FBSztBQUNMOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7O0FBRUEsbUJBQW1CLGlCQUFpQjtBQUNwQztBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUEsNkJBQTZCO0FBQzdCOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLGdCQUFnQjtBQUNoQjtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBLENBQUM7O0FBRUQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQSxLQUFLOztBQUVMO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSzs7QUFFTDtBQUNBOztBQUVBO0FBQ0EsS0FBSzs7QUFFTDtBQUNBO0FBQ0EsS0FBSzs7QUFFTDtBQUNBO0FBQ0EsS0FBSzs7QUFFTDtBQUNBO0FBQ0EsS0FBSzs7QUFFTDtBQUNBO0FBQ0EsS0FBSzs7QUFFTDtBQUNBO0FBQ0EsS0FBSzs7QUFFTDtBQUNBOztBQUVBOztBQUVBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7O0FBRUw7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsT0FBTztBQUNQOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsS0FBSzs7QUFFTDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0EsS0FBSztBQUNMOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBLENBQUM7O0FBRUQ7QUFDQTtBQUNBO0FBQ0EsMEJBQTBCOztBQUUxQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxPQUFPOztBQUVQOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EsS0FBSztBQUNMOztBQUVBO0FBQ0EsQ0FBQzs7QUFFRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0EsMkJBQTJCO0FBQzNCOztBQUVBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQSxDQUFDOztBQUVEOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxDQUFDOztBQUVEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EsQ0FBQzs7QUFFRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQSxLQUFLOztBQUVMO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQSx1QkFBdUIsaUJBQWlCO0FBQ3hDOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxPQUFPO0FBQ1AsS0FBSztBQUNMOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBLHFCQUFxQix3QkFBd0I7QUFDN0M7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQSxLQUFLO0FBQ0w7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0EsS0FBSzs7QUFFTDtBQUNBO0FBQ0EsS0FBSztBQUNMOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7O0FBRUw7QUFDQTtBQUNBLEtBQUs7QUFDTDs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7O0FBRUE7QUFDQTtBQUNBLE9BQU87QUFDUDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBLHFCQUFxQixzQkFBc0I7QUFDM0M7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSxzQkFBc0I7QUFDdEI7QUFDQSxLQUFLOztBQUVMO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBLHNCQUFzQjtBQUN0Qjs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQSxDQUFDOztBQUVEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsS0FBSzs7QUFFTDtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7O0FBRUw7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBLG1CQUFtQixpQkFBaUI7QUFDcEM7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0EsdUNBQXVDOztBQUV2Qzs7QUFFQTs7QUFFQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQSxDQUFDOztBQUVEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLDBCQUEwQjtBQUMxQjtBQUNBLFNBQVM7QUFDVCxPQUFPO0FBQ1A7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQSxzQkFBc0I7QUFDdEI7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLEtBQUs7O0FBRUw7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EsT0FBTztBQUNQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLFNBQVM7QUFDVCxPQUFPOztBQUVQO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBOztBQUVBO0FBQ0EsQ0FBQzs7QUFFRDtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQSxxQkFBcUIsaUJBQWlCO0FBQ3RDO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBLHFCQUFxQixpQkFBaUI7QUFDdEM7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxXQUFXO0FBQ1g7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EsS0FBSztBQUNMOztBQUVBO0FBQ0EsQ0FBQzs7QUFFRDtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsT0FBTzs7QUFFUDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLE9BQU87QUFDUDs7QUFFQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBLGtDQUFrQztBQUNsQztBQUNBLE9BQU87O0FBRVA7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxDQUFDOztBQUVEOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE9BQU87O0FBRVA7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0EsQ0FBQzs7QUFFRDs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE9BQU87O0FBRVA7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0EsQ0FBQzs7QUFFRDs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsV0FBVztBQUNYO0FBQ0E7QUFDQTtBQUNBLE9BQU87QUFDUDs7QUFFQTtBQUNBLENBQUM7O0FBRUQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EsQ0FBQzs7QUFFRDtBQUNBO0FBQ0E7QUFDQTtBQUNBLHNCQUFzQjs7QUFFdEI7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0EsS0FBSzs7QUFFTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLOztBQUVMO0FBQ0E7QUFDQSxLQUFLOztBQUVMO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBLE9BQU87QUFDUCxLQUFLOztBQUVMO0FBQ0E7O0FBRUE7QUFDQSxLQUFLOztBQUVMO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSzs7QUFFTDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxPQUFPO0FBQ1A7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxDQUFDOztBQUVEOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUEsaUNBQWlDLFFBQVE7QUFDekM7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBLENBQUM7O0FBRUQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsS0FBSzs7QUFFTDtBQUNBO0FBQ0E7QUFDQSxLQUFLOztBQUVMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDs7QUFFQTtBQUNBOztBQUVBLDRCQUE0QixHQUFHLFFBQVE7O0FBRXZDOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0EsQ0FBQzs7QUFFRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7O0FBRVQ7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0EsS0FBSzs7QUFFTDtBQUNBO0FBQ0E7QUFDQSxLQUFLOztBQUVMO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7O0FBRUw7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsT0FBTztBQUNQLEtBQUs7O0FBRUw7QUFDQTtBQUNBO0FBQ0EsS0FBSzs7QUFFTDtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUE7O0FBRUE7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0EsQ0FBQzs7QUFFRDs7QUFFQTtBQUNBO0FBQ0E7O0FBRUEsbUJBQW1CLGlCQUFpQjtBQUNwQzs7QUFFQTtBQUNBO0FBQ0EsT0FBTztBQUNQO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBLENBQUM7O0FBRUQ7O0FBRUE7QUFDQSw2QkFBNkI7O0FBRTdCO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBLEtBQUs7QUFDTDs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7O0FBRUE7QUFDQSxDQUFDOztBQUVEOztBQUVBO0FBQ0EsNkJBQTZCOztBQUU3QjtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQSxLQUFLOztBQUVMO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7O0FBRUE7QUFDQSxDQUFDOztBQUVEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxLQUFLO0FBQ0w7QUFDQTs7QUFFQTs7QUFFQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQSxDQUFDOztBQUVEO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EsK0JBQStCOztBQUUvQjtBQUNBO0FBQ0E7QUFDQSxPQUFPO0FBQ1A7QUFDQSxPQUFPO0FBQ1A7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsT0FBTztBQUNQOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLE9BQU87QUFDUDtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxPQUFPO0FBQ1A7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQSxxQkFBcUIsMEJBQTBCO0FBQy9DO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsV0FBVztBQUNYO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHFDQUFxQzs7QUFFckM7QUFDQSw4Q0FBOEMsUUFBUTtBQUN0RDs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE9BQU87QUFDUDtBQUNBO0FBQ0EsT0FBTztBQUNQO0FBQ0E7QUFDQSxPQUFPO0FBQ1A7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQSxDQUFDOztBQUVEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxPQUFPO0FBQ1A7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLE9BQU87QUFDUDtBQUNBLE9BQU87QUFDUDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxpQ0FBaUM7QUFDakMsS0FBSztBQUNMO0FBQ0E7O0FBRUEsZ0NBQWdDOztBQUVoQzs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsT0FBTztBQUNQO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxDQUFDOztBQUVEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBOztBQUVBOztBQUVBOztBQUVBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBOztBQUVBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxPQUFPO0FBQ1AsS0FBSzs7QUFFTDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBLEtBQUs7QUFDTDtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBLGdDQUFnQzs7QUFFaEMsdUNBQXVDLE9BQU87QUFDOUM7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNULE9BQU87QUFDUCxLQUFLOztBQUVMO0FBQ0E7QUFDQSxLQUFLOztBQUVMO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsT0FBTztBQUNQO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsT0FBTztBQUNQLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLEtBQUs7QUFDTDs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLEtBQUs7O0FBRUw7QUFDQTtBQUNBLEtBQUs7O0FBRUw7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxLQUFLO0FBQ0w7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsS0FBSztBQUNMOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLEtBQUs7QUFDTDs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxLQUFLOztBQUVMO0FBQ0E7QUFDQSxLQUFLOztBQUVMO0FBQ0E7QUFDQSxLQUFLOztBQUVMO0FBQ0E7QUFDQSxLQUFLOztBQUVMO0FBQ0E7QUFDQSxLQUFLOztBQUVMO0FBQ0E7QUFDQSwrQkFBK0I7QUFDL0I7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1QsT0FBTztBQUNQLEtBQUs7O0FBRUw7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVCxPQUFPO0FBQ1AsS0FBSzs7QUFFTDtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EsU0FBUztBQUNULDJDQUEyQzs7QUFFM0M7QUFDQSxTQUFTO0FBQ1QsMkNBQTJDOztBQUUzQztBQUNBLFNBQVM7QUFDVCw2Q0FBNkM7O0FBRTdDO0FBQ0EsU0FBUztBQUNULHlDQUF5Qzs7QUFFekM7QUFDQTtBQUNBLE9BQU87QUFDUDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsZ0NBQWdDO0FBQ2hDLEtBQUs7QUFDTCwrQkFBK0I7QUFDL0I7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMLHFCQUFxQixpQ0FBaUM7QUFDdEQ7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNULE9BQU87QUFDUDtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSw0QkFBNEI7QUFDNUI7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsNEJBQTRCO0FBQzVCOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLDRCQUE0QjtBQUM1Qjs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBLEtBQUs7O0FBRUw7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsT0FBTztBQUNQOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTs7QUFFQTs7QUFFQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0EsQ0FBQzs7QUFFRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsQ0FBQzs7QUFFRDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLGlEQUFpRDs7QUFFakQ7QUFDQSxTQUFTOztBQUVUO0FBQ0EsT0FBTztBQUNQO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxTQUFTOztBQUVUO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EsT0FBTztBQUNQO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLENBQUM7O0FBRUQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLENBQUM7O0FBRUQ7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxDQUFDOzs7Ozs7O0FDNWxMRCxnQkFBZ0IsbUJBQW1CLGFBQWEsMEJBQTBCO0FBQzFFO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNILENBQUM7QUFDRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxDOzs7Ozs7QUNiQSxnQkFBZ0IsbUJBQW1CLGFBQWEsMEJBQTBCO0FBQzFFO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTCxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0EsR0FBRztBQUNIO0FBQ0EsR0FBRztBQUNIO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQSxPQUFPO0FBQ1A7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBLEdBQUc7QUFDSDtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsV0FBVztBQUNYO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBLE9BQU87QUFDUDtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTCxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSCxDQUFDLCtCQUErQixhQUFhLDBCQUEwQjtBQUN2RTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSCxDQUFDLGFBQWEsYUFBYSwwQkFBMEI7QUFDckQ7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0gsQ0FBQyxhQUFhLGFBQWEsMEJBQTBCO0FBQ3JEO0FBQ0EsQ0FBQztBQUNEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEM7Ozs7OztBQ3hKQSx5Qzs7Ozs7O0FDQUEseUM7Ozs7OztBQ0FBLHlDIiwiZmlsZSI6Ii92dWUuanMiLCJzb3VyY2VzQ29udGVudCI6WyIgXHQvLyBUaGUgbW9kdWxlIGNhY2hlXG4gXHR2YXIgaW5zdGFsbGVkTW9kdWxlcyA9IHt9O1xuXG4gXHQvLyBUaGUgcmVxdWlyZSBmdW5jdGlvblxuIFx0ZnVuY3Rpb24gX193ZWJwYWNrX3JlcXVpcmVfXyhtb2R1bGVJZCkge1xuXG4gXHRcdC8vIENoZWNrIGlmIG1vZHVsZSBpcyBpbiBjYWNoZVxuIFx0XHRpZihpbnN0YWxsZWRNb2R1bGVzW21vZHVsZUlkXSkge1xuIFx0XHRcdHJldHVybiBpbnN0YWxsZWRNb2R1bGVzW21vZHVsZUlkXS5leHBvcnRzO1xuIFx0XHR9XG4gXHRcdC8vIENyZWF0ZSBhIG5ldyBtb2R1bGUgKGFuZCBwdXQgaXQgaW50byB0aGUgY2FjaGUpXG4gXHRcdHZhciBtb2R1bGUgPSBpbnN0YWxsZWRNb2R1bGVzW21vZHVsZUlkXSA9IHtcbiBcdFx0XHRpOiBtb2R1bGVJZCxcbiBcdFx0XHRsOiBmYWxzZSxcbiBcdFx0XHRleHBvcnRzOiB7fVxuIFx0XHR9O1xuXG4gXHRcdC8vIEV4ZWN1dGUgdGhlIG1vZHVsZSBmdW5jdGlvblxuIFx0XHRtb2R1bGVzW21vZHVsZUlkXS5jYWxsKG1vZHVsZS5leHBvcnRzLCBtb2R1bGUsIG1vZHVsZS5leHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKTtcblxuIFx0XHQvLyBGbGFnIHRoZSBtb2R1bGUgYXMgbG9hZGVkXG4gXHRcdG1vZHVsZS5sID0gdHJ1ZTtcblxuIFx0XHQvLyBSZXR1cm4gdGhlIGV4cG9ydHMgb2YgdGhlIG1vZHVsZVxuIFx0XHRyZXR1cm4gbW9kdWxlLmV4cG9ydHM7XG4gXHR9XG5cblxuIFx0Ly8gZXhwb3NlIHRoZSBtb2R1bGVzIG9iamVjdCAoX193ZWJwYWNrX21vZHVsZXNfXylcbiBcdF9fd2VicGFja19yZXF1aXJlX18ubSA9IG1vZHVsZXM7XG5cbiBcdC8vIGV4cG9zZSB0aGUgbW9kdWxlIGNhY2hlXG4gXHRfX3dlYnBhY2tfcmVxdWlyZV9fLmMgPSBpbnN0YWxsZWRNb2R1bGVzO1xuXG4gXHQvLyBkZWZpbmUgZ2V0dGVyIGZ1bmN0aW9uIGZvciBoYXJtb255IGV4cG9ydHNcbiBcdF9fd2VicGFja19yZXF1aXJlX18uZCA9IGZ1bmN0aW9uKGV4cG9ydHMsIG5hbWUsIGdldHRlcikge1xuIFx0XHRpZighX193ZWJwYWNrX3JlcXVpcmVfXy5vKGV4cG9ydHMsIG5hbWUpKSB7XG4gXHRcdFx0T2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIG5hbWUsIHtcbiBcdFx0XHRcdGNvbmZpZ3VyYWJsZTogZmFsc2UsXG4gXHRcdFx0XHRlbnVtZXJhYmxlOiB0cnVlLFxuIFx0XHRcdFx0Z2V0OiBnZXR0ZXJcbiBcdFx0XHR9KTtcbiBcdFx0fVxuIFx0fTtcblxuIFx0Ly8gZ2V0RGVmYXVsdEV4cG9ydCBmdW5jdGlvbiBmb3IgY29tcGF0aWJpbGl0eSB3aXRoIG5vbi1oYXJtb255IG1vZHVsZXNcbiBcdF9fd2VicGFja19yZXF1aXJlX18ubiA9IGZ1bmN0aW9uKG1vZHVsZSkge1xuIFx0XHR2YXIgZ2V0dGVyID0gbW9kdWxlICYmIG1vZHVsZS5fX2VzTW9kdWxlID9cbiBcdFx0XHRmdW5jdGlvbiBnZXREZWZhdWx0KCkgeyByZXR1cm4gbW9kdWxlWydkZWZhdWx0J107IH0gOlxuIFx0XHRcdGZ1bmN0aW9uIGdldE1vZHVsZUV4cG9ydHMoKSB7IHJldHVybiBtb2R1bGU7IH07XG4gXHRcdF9fd2VicGFja19yZXF1aXJlX18uZChnZXR0ZXIsICdhJywgZ2V0dGVyKTtcbiBcdFx0cmV0dXJuIGdldHRlcjtcbiBcdH07XG5cbiBcdC8vIE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbFxuIFx0X193ZWJwYWNrX3JlcXVpcmVfXy5vID0gZnVuY3Rpb24ob2JqZWN0LCBwcm9wZXJ0eSkgeyByZXR1cm4gT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKG9iamVjdCwgcHJvcGVydHkpOyB9O1xuXG4gXHQvLyBfX3dlYnBhY2tfcHVibGljX3BhdGhfX1xuIFx0X193ZWJwYWNrX3JlcXVpcmVfXy5wID0gXCJcIjtcblxuIFx0Ly8gTG9hZCBlbnRyeSBtb2R1bGUgYW5kIHJldHVybiBleHBvcnRzXG4gXHRyZXR1cm4gX193ZWJwYWNrX3JlcXVpcmVfXyhfX3dlYnBhY2tfcmVxdWlyZV9fLnMgPSA1KTtcblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyB3ZWJwYWNrL2Jvb3RzdHJhcCAzMWUyZTZlMjcwODFhMjhjYWVlOCIsIi8qXG5cdE1JVCBMaWNlbnNlIGh0dHA6Ly93d3cub3BlbnNvdXJjZS5vcmcvbGljZW5zZXMvbWl0LWxpY2Vuc2UucGhwXG5cdEF1dGhvciBUb2JpYXMgS29wcGVycyBAc29rcmFcbiovXG4vLyBjc3MgYmFzZSBjb2RlLCBpbmplY3RlZCBieSB0aGUgY3NzLWxvYWRlclxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbih1c2VTb3VyY2VNYXApIHtcblx0dmFyIGxpc3QgPSBbXTtcblxuXHQvLyByZXR1cm4gdGhlIGxpc3Qgb2YgbW9kdWxlcyBhcyBjc3Mgc3RyaW5nXG5cdGxpc3QudG9TdHJpbmcgPSBmdW5jdGlvbiB0b1N0cmluZygpIHtcblx0XHRyZXR1cm4gdGhpcy5tYXAoZnVuY3Rpb24gKGl0ZW0pIHtcblx0XHRcdHZhciBjb250ZW50ID0gY3NzV2l0aE1hcHBpbmdUb1N0cmluZyhpdGVtLCB1c2VTb3VyY2VNYXApO1xuXHRcdFx0aWYoaXRlbVsyXSkge1xuXHRcdFx0XHRyZXR1cm4gXCJAbWVkaWEgXCIgKyBpdGVtWzJdICsgXCJ7XCIgKyBjb250ZW50ICsgXCJ9XCI7XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRyZXR1cm4gY29udGVudDtcblx0XHRcdH1cblx0XHR9KS5qb2luKFwiXCIpO1xuXHR9O1xuXG5cdC8vIGltcG9ydCBhIGxpc3Qgb2YgbW9kdWxlcyBpbnRvIHRoZSBsaXN0XG5cdGxpc3QuaSA9IGZ1bmN0aW9uKG1vZHVsZXMsIG1lZGlhUXVlcnkpIHtcblx0XHRpZih0eXBlb2YgbW9kdWxlcyA9PT0gXCJzdHJpbmdcIilcblx0XHRcdG1vZHVsZXMgPSBbW251bGwsIG1vZHVsZXMsIFwiXCJdXTtcblx0XHR2YXIgYWxyZWFkeUltcG9ydGVkTW9kdWxlcyA9IHt9O1xuXHRcdGZvcih2YXIgaSA9IDA7IGkgPCB0aGlzLmxlbmd0aDsgaSsrKSB7XG5cdFx0XHR2YXIgaWQgPSB0aGlzW2ldWzBdO1xuXHRcdFx0aWYodHlwZW9mIGlkID09PSBcIm51bWJlclwiKVxuXHRcdFx0XHRhbHJlYWR5SW1wb3J0ZWRNb2R1bGVzW2lkXSA9IHRydWU7XG5cdFx0fVxuXHRcdGZvcihpID0gMDsgaSA8IG1vZHVsZXMubGVuZ3RoOyBpKyspIHtcblx0XHRcdHZhciBpdGVtID0gbW9kdWxlc1tpXTtcblx0XHRcdC8vIHNraXAgYWxyZWFkeSBpbXBvcnRlZCBtb2R1bGVcblx0XHRcdC8vIHRoaXMgaW1wbGVtZW50YXRpb24gaXMgbm90IDEwMCUgcGVyZmVjdCBmb3Igd2VpcmQgbWVkaWEgcXVlcnkgY29tYmluYXRpb25zXG5cdFx0XHQvLyAgd2hlbiBhIG1vZHVsZSBpcyBpbXBvcnRlZCBtdWx0aXBsZSB0aW1lcyB3aXRoIGRpZmZlcmVudCBtZWRpYSBxdWVyaWVzLlxuXHRcdFx0Ly8gIEkgaG9wZSB0aGlzIHdpbGwgbmV2ZXIgb2NjdXIgKEhleSB0aGlzIHdheSB3ZSBoYXZlIHNtYWxsZXIgYnVuZGxlcylcblx0XHRcdGlmKHR5cGVvZiBpdGVtWzBdICE9PSBcIm51bWJlclwiIHx8ICFhbHJlYWR5SW1wb3J0ZWRNb2R1bGVzW2l0ZW1bMF1dKSB7XG5cdFx0XHRcdGlmKG1lZGlhUXVlcnkgJiYgIWl0ZW1bMl0pIHtcblx0XHRcdFx0XHRpdGVtWzJdID0gbWVkaWFRdWVyeTtcblx0XHRcdFx0fSBlbHNlIGlmKG1lZGlhUXVlcnkpIHtcblx0XHRcdFx0XHRpdGVtWzJdID0gXCIoXCIgKyBpdGVtWzJdICsgXCIpIGFuZCAoXCIgKyBtZWRpYVF1ZXJ5ICsgXCIpXCI7XG5cdFx0XHRcdH1cblx0XHRcdFx0bGlzdC5wdXNoKGl0ZW0pO1xuXHRcdFx0fVxuXHRcdH1cblx0fTtcblx0cmV0dXJuIGxpc3Q7XG59O1xuXG5mdW5jdGlvbiBjc3NXaXRoTWFwcGluZ1RvU3RyaW5nKGl0ZW0sIHVzZVNvdXJjZU1hcCkge1xuXHR2YXIgY29udGVudCA9IGl0ZW1bMV0gfHwgJyc7XG5cdHZhciBjc3NNYXBwaW5nID0gaXRlbVszXTtcblx0aWYgKCFjc3NNYXBwaW5nKSB7XG5cdFx0cmV0dXJuIGNvbnRlbnQ7XG5cdH1cblxuXHRpZiAodXNlU291cmNlTWFwICYmIHR5cGVvZiBidG9hID09PSAnZnVuY3Rpb24nKSB7XG5cdFx0dmFyIHNvdXJjZU1hcHBpbmcgPSB0b0NvbW1lbnQoY3NzTWFwcGluZyk7XG5cdFx0dmFyIHNvdXJjZVVSTHMgPSBjc3NNYXBwaW5nLnNvdXJjZXMubWFwKGZ1bmN0aW9uIChzb3VyY2UpIHtcblx0XHRcdHJldHVybiAnLyojIHNvdXJjZVVSTD0nICsgY3NzTWFwcGluZy5zb3VyY2VSb290ICsgc291cmNlICsgJyAqLydcblx0XHR9KTtcblxuXHRcdHJldHVybiBbY29udGVudF0uY29uY2F0KHNvdXJjZVVSTHMpLmNvbmNhdChbc291cmNlTWFwcGluZ10pLmpvaW4oJ1xcbicpO1xuXHR9XG5cblx0cmV0dXJuIFtjb250ZW50XS5qb2luKCdcXG4nKTtcbn1cblxuLy8gQWRhcHRlZCBmcm9tIGNvbnZlcnQtc291cmNlLW1hcCAoTUlUKVxuZnVuY3Rpb24gdG9Db21tZW50KHNvdXJjZU1hcCkge1xuXHQvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tdW5kZWZcblx0dmFyIGJhc2U2NCA9IGJ0b2EodW5lc2NhcGUoZW5jb2RlVVJJQ29tcG9uZW50KEpTT04uc3RyaW5naWZ5KHNvdXJjZU1hcCkpKSk7XG5cdHZhciBkYXRhID0gJ3NvdXJjZU1hcHBpbmdVUkw9ZGF0YTphcHBsaWNhdGlvbi9qc29uO2NoYXJzZXQ9dXRmLTg7YmFzZTY0LCcgKyBiYXNlNjQ7XG5cblx0cmV0dXJuICcvKiMgJyArIGRhdGEgKyAnICovJztcbn1cblxuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIC4vbm9kZV9tb2R1bGVzL2Nzcy1sb2FkZXIvbGliL2Nzcy1iYXNlLmpzXG4vLyBtb2R1bGUgaWQgPSAwXG4vLyBtb2R1bGUgY2h1bmtzID0gMCIsIi8qXG4gIE1JVCBMaWNlbnNlIGh0dHA6Ly93d3cub3BlbnNvdXJjZS5vcmcvbGljZW5zZXMvbWl0LWxpY2Vuc2UucGhwXG4gIEF1dGhvciBUb2JpYXMgS29wcGVycyBAc29rcmFcbiAgTW9kaWZpZWQgYnkgRXZhbiBZb3UgQHl5eDk5MDgwM1xuKi9cblxudmFyIGhhc0RvY3VtZW50ID0gdHlwZW9mIGRvY3VtZW50ICE9PSAndW5kZWZpbmVkJ1xuXG5pZiAodHlwZW9mIERFQlVHICE9PSAndW5kZWZpbmVkJyAmJiBERUJVRykge1xuICBpZiAoIWhhc0RvY3VtZW50KSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICd2dWUtc3R5bGUtbG9hZGVyIGNhbm5vdCBiZSB1c2VkIGluIGEgbm9uLWJyb3dzZXIgZW52aXJvbm1lbnQuICcgK1xuICAgIFwiVXNlIHsgdGFyZ2V0OiAnbm9kZScgfSBpbiB5b3VyIFdlYnBhY2sgY29uZmlnIHRvIGluZGljYXRlIGEgc2VydmVyLXJlbmRlcmluZyBlbnZpcm9ubWVudC5cIlxuICApIH1cbn1cblxudmFyIGxpc3RUb1N0eWxlcyA9IHJlcXVpcmUoJy4vbGlzdFRvU3R5bGVzJylcblxuLypcbnR5cGUgU3R5bGVPYmplY3QgPSB7XG4gIGlkOiBudW1iZXI7XG4gIHBhcnRzOiBBcnJheTxTdHlsZU9iamVjdFBhcnQ+XG59XG5cbnR5cGUgU3R5bGVPYmplY3RQYXJ0ID0ge1xuICBjc3M6IHN0cmluZztcbiAgbWVkaWE6IHN0cmluZztcbiAgc291cmNlTWFwOiA/c3RyaW5nXG59XG4qL1xuXG52YXIgc3R5bGVzSW5Eb20gPSB7LypcbiAgW2lkOiBudW1iZXJdOiB7XG4gICAgaWQ6IG51bWJlcixcbiAgICByZWZzOiBudW1iZXIsXG4gICAgcGFydHM6IEFycmF5PChvYmo/OiBTdHlsZU9iamVjdFBhcnQpID0+IHZvaWQ+XG4gIH1cbiovfVxuXG52YXIgaGVhZCA9IGhhc0RvY3VtZW50ICYmIChkb2N1bWVudC5oZWFkIHx8IGRvY3VtZW50LmdldEVsZW1lbnRzQnlUYWdOYW1lKCdoZWFkJylbMF0pXG52YXIgc2luZ2xldG9uRWxlbWVudCA9IG51bGxcbnZhciBzaW5nbGV0b25Db3VudGVyID0gMFxudmFyIGlzUHJvZHVjdGlvbiA9IGZhbHNlXG52YXIgbm9vcCA9IGZ1bmN0aW9uICgpIHt9XG5cbi8vIEZvcmNlIHNpbmdsZS10YWcgc29sdXRpb24gb24gSUU2LTksIHdoaWNoIGhhcyBhIGhhcmQgbGltaXQgb24gdGhlICMgb2YgPHN0eWxlPlxuLy8gdGFncyBpdCB3aWxsIGFsbG93IG9uIGEgcGFnZVxudmFyIGlzT2xkSUUgPSB0eXBlb2YgbmF2aWdhdG9yICE9PSAndW5kZWZpbmVkJyAmJiAvbXNpZSBbNi05XVxcYi8udGVzdChuYXZpZ2F0b3IudXNlckFnZW50LnRvTG93ZXJDYXNlKCkpXG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKHBhcmVudElkLCBsaXN0LCBfaXNQcm9kdWN0aW9uKSB7XG4gIGlzUHJvZHVjdGlvbiA9IF9pc1Byb2R1Y3Rpb25cblxuICB2YXIgc3R5bGVzID0gbGlzdFRvU3R5bGVzKHBhcmVudElkLCBsaXN0KVxuICBhZGRTdHlsZXNUb0RvbShzdHlsZXMpXG5cbiAgcmV0dXJuIGZ1bmN0aW9uIHVwZGF0ZSAobmV3TGlzdCkge1xuICAgIHZhciBtYXlSZW1vdmUgPSBbXVxuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgc3R5bGVzLmxlbmd0aDsgaSsrKSB7XG4gICAgICB2YXIgaXRlbSA9IHN0eWxlc1tpXVxuICAgICAgdmFyIGRvbVN0eWxlID0gc3R5bGVzSW5Eb21baXRlbS5pZF1cbiAgICAgIGRvbVN0eWxlLnJlZnMtLVxuICAgICAgbWF5UmVtb3ZlLnB1c2goZG9tU3R5bGUpXG4gICAgfVxuICAgIGlmIChuZXdMaXN0KSB7XG4gICAgICBzdHlsZXMgPSBsaXN0VG9TdHlsZXMocGFyZW50SWQsIG5ld0xpc3QpXG4gICAgICBhZGRTdHlsZXNUb0RvbShzdHlsZXMpXG4gICAgfSBlbHNlIHtcbiAgICAgIHN0eWxlcyA9IFtdXG4gICAgfVxuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbWF5UmVtb3ZlLmxlbmd0aDsgaSsrKSB7XG4gICAgICB2YXIgZG9tU3R5bGUgPSBtYXlSZW1vdmVbaV1cbiAgICAgIGlmIChkb21TdHlsZS5yZWZzID09PSAwKSB7XG4gICAgICAgIGZvciAodmFyIGogPSAwOyBqIDwgZG9tU3R5bGUucGFydHMubGVuZ3RoOyBqKyspIHtcbiAgICAgICAgICBkb21TdHlsZS5wYXJ0c1tqXSgpXG4gICAgICAgIH1cbiAgICAgICAgZGVsZXRlIHN0eWxlc0luRG9tW2RvbVN0eWxlLmlkXVxuICAgICAgfVxuICAgIH1cbiAgfVxufVxuXG5mdW5jdGlvbiBhZGRTdHlsZXNUb0RvbSAoc3R5bGVzIC8qIEFycmF5PFN0eWxlT2JqZWN0PiAqLykge1xuICBmb3IgKHZhciBpID0gMDsgaSA8IHN0eWxlcy5sZW5ndGg7IGkrKykge1xuICAgIHZhciBpdGVtID0gc3R5bGVzW2ldXG4gICAgdmFyIGRvbVN0eWxlID0gc3R5bGVzSW5Eb21baXRlbS5pZF1cbiAgICBpZiAoZG9tU3R5bGUpIHtcbiAgICAgIGRvbVN0eWxlLnJlZnMrK1xuICAgICAgZm9yICh2YXIgaiA9IDA7IGogPCBkb21TdHlsZS5wYXJ0cy5sZW5ndGg7IGorKykge1xuICAgICAgICBkb21TdHlsZS5wYXJ0c1tqXShpdGVtLnBhcnRzW2pdKVxuICAgICAgfVxuICAgICAgZm9yICg7IGogPCBpdGVtLnBhcnRzLmxlbmd0aDsgaisrKSB7XG4gICAgICAgIGRvbVN0eWxlLnBhcnRzLnB1c2goYWRkU3R5bGUoaXRlbS5wYXJ0c1tqXSkpXG4gICAgICB9XG4gICAgICBpZiAoZG9tU3R5bGUucGFydHMubGVuZ3RoID4gaXRlbS5wYXJ0cy5sZW5ndGgpIHtcbiAgICAgICAgZG9tU3R5bGUucGFydHMubGVuZ3RoID0gaXRlbS5wYXJ0cy5sZW5ndGhcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgdmFyIHBhcnRzID0gW11cbiAgICAgIGZvciAodmFyIGogPSAwOyBqIDwgaXRlbS5wYXJ0cy5sZW5ndGg7IGorKykge1xuICAgICAgICBwYXJ0cy5wdXNoKGFkZFN0eWxlKGl0ZW0ucGFydHNbal0pKVxuICAgICAgfVxuICAgICAgc3R5bGVzSW5Eb21baXRlbS5pZF0gPSB7IGlkOiBpdGVtLmlkLCByZWZzOiAxLCBwYXJ0czogcGFydHMgfVxuICAgIH1cbiAgfVxufVxuXG5mdW5jdGlvbiBjcmVhdGVTdHlsZUVsZW1lbnQgKCkge1xuICB2YXIgc3R5bGVFbGVtZW50ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnc3R5bGUnKVxuICBzdHlsZUVsZW1lbnQudHlwZSA9ICd0ZXh0L2NzcydcbiAgaGVhZC5hcHBlbmRDaGlsZChzdHlsZUVsZW1lbnQpXG4gIHJldHVybiBzdHlsZUVsZW1lbnRcbn1cblxuZnVuY3Rpb24gYWRkU3R5bGUgKG9iaiAvKiBTdHlsZU9iamVjdFBhcnQgKi8pIHtcbiAgdmFyIHVwZGF0ZSwgcmVtb3ZlXG4gIHZhciBzdHlsZUVsZW1lbnQgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCdzdHlsZVtkYXRhLXZ1ZS1zc3ItaWR+PVwiJyArIG9iai5pZCArICdcIl0nKVxuXG4gIGlmIChzdHlsZUVsZW1lbnQpIHtcbiAgICBpZiAoaXNQcm9kdWN0aW9uKSB7XG4gICAgICAvLyBoYXMgU1NSIHN0eWxlcyBhbmQgaW4gcHJvZHVjdGlvbiBtb2RlLlxuICAgICAgLy8gc2ltcGx5IGRvIG5vdGhpbmcuXG4gICAgICByZXR1cm4gbm9vcFxuICAgIH0gZWxzZSB7XG4gICAgICAvLyBoYXMgU1NSIHN0eWxlcyBidXQgaW4gZGV2IG1vZGUuXG4gICAgICAvLyBmb3Igc29tZSByZWFzb24gQ2hyb21lIGNhbid0IGhhbmRsZSBzb3VyY2UgbWFwIGluIHNlcnZlci1yZW5kZXJlZFxuICAgICAgLy8gc3R5bGUgdGFncyAtIHNvdXJjZSBtYXBzIGluIDxzdHlsZT4gb25seSB3b3JrcyBpZiB0aGUgc3R5bGUgdGFnIGlzXG4gICAgICAvLyBjcmVhdGVkIGFuZCBpbnNlcnRlZCBkeW5hbWljYWxseS4gU28gd2UgcmVtb3ZlIHRoZSBzZXJ2ZXIgcmVuZGVyZWRcbiAgICAgIC8vIHN0eWxlcyBhbmQgaW5qZWN0IG5ldyBvbmVzLlxuICAgICAgc3R5bGVFbGVtZW50LnBhcmVudE5vZGUucmVtb3ZlQ2hpbGQoc3R5bGVFbGVtZW50KVxuICAgIH1cbiAgfVxuXG4gIGlmIChpc09sZElFKSB7XG4gICAgLy8gdXNlIHNpbmdsZXRvbiBtb2RlIGZvciBJRTkuXG4gICAgdmFyIHN0eWxlSW5kZXggPSBzaW5nbGV0b25Db3VudGVyKytcbiAgICBzdHlsZUVsZW1lbnQgPSBzaW5nbGV0b25FbGVtZW50IHx8IChzaW5nbGV0b25FbGVtZW50ID0gY3JlYXRlU3R5bGVFbGVtZW50KCkpXG4gICAgdXBkYXRlID0gYXBwbHlUb1NpbmdsZXRvblRhZy5iaW5kKG51bGwsIHN0eWxlRWxlbWVudCwgc3R5bGVJbmRleCwgZmFsc2UpXG4gICAgcmVtb3ZlID0gYXBwbHlUb1NpbmdsZXRvblRhZy5iaW5kKG51bGwsIHN0eWxlRWxlbWVudCwgc3R5bGVJbmRleCwgdHJ1ZSlcbiAgfSBlbHNlIHtcbiAgICAvLyB1c2UgbXVsdGktc3R5bGUtdGFnIG1vZGUgaW4gYWxsIG90aGVyIGNhc2VzXG4gICAgc3R5bGVFbGVtZW50ID0gY3JlYXRlU3R5bGVFbGVtZW50KClcbiAgICB1cGRhdGUgPSBhcHBseVRvVGFnLmJpbmQobnVsbCwgc3R5bGVFbGVtZW50KVxuICAgIHJlbW92ZSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgIHN0eWxlRWxlbWVudC5wYXJlbnROb2RlLnJlbW92ZUNoaWxkKHN0eWxlRWxlbWVudClcbiAgICB9XG4gIH1cblxuICB1cGRhdGUob2JqKVxuXG4gIHJldHVybiBmdW5jdGlvbiB1cGRhdGVTdHlsZSAobmV3T2JqIC8qIFN0eWxlT2JqZWN0UGFydCAqLykge1xuICAgIGlmIChuZXdPYmopIHtcbiAgICAgIGlmIChuZXdPYmouY3NzID09PSBvYmouY3NzICYmXG4gICAgICAgICAgbmV3T2JqLm1lZGlhID09PSBvYmoubWVkaWEgJiZcbiAgICAgICAgICBuZXdPYmouc291cmNlTWFwID09PSBvYmouc291cmNlTWFwKSB7XG4gICAgICAgIHJldHVyblxuICAgICAgfVxuICAgICAgdXBkYXRlKG9iaiA9IG5ld09iailcbiAgICB9IGVsc2Uge1xuICAgICAgcmVtb3ZlKClcbiAgICB9XG4gIH1cbn1cblxudmFyIHJlcGxhY2VUZXh0ID0gKGZ1bmN0aW9uICgpIHtcbiAgdmFyIHRleHRTdG9yZSA9IFtdXG5cbiAgcmV0dXJuIGZ1bmN0aW9uIChpbmRleCwgcmVwbGFjZW1lbnQpIHtcbiAgICB0ZXh0U3RvcmVbaW5kZXhdID0gcmVwbGFjZW1lbnRcbiAgICByZXR1cm4gdGV4dFN0b3JlLmZpbHRlcihCb29sZWFuKS5qb2luKCdcXG4nKVxuICB9XG59KSgpXG5cbmZ1bmN0aW9uIGFwcGx5VG9TaW5nbGV0b25UYWcgKHN0eWxlRWxlbWVudCwgaW5kZXgsIHJlbW92ZSwgb2JqKSB7XG4gIHZhciBjc3MgPSByZW1vdmUgPyAnJyA6IG9iai5jc3NcblxuICBpZiAoc3R5bGVFbGVtZW50LnN0eWxlU2hlZXQpIHtcbiAgICBzdHlsZUVsZW1lbnQuc3R5bGVTaGVldC5jc3NUZXh0ID0gcmVwbGFjZVRleHQoaW5kZXgsIGNzcylcbiAgfSBlbHNlIHtcbiAgICB2YXIgY3NzTm9kZSA9IGRvY3VtZW50LmNyZWF0ZVRleHROb2RlKGNzcylcbiAgICB2YXIgY2hpbGROb2RlcyA9IHN0eWxlRWxlbWVudC5jaGlsZE5vZGVzXG4gICAgaWYgKGNoaWxkTm9kZXNbaW5kZXhdKSBzdHlsZUVsZW1lbnQucmVtb3ZlQ2hpbGQoY2hpbGROb2Rlc1tpbmRleF0pXG4gICAgaWYgKGNoaWxkTm9kZXMubGVuZ3RoKSB7XG4gICAgICBzdHlsZUVsZW1lbnQuaW5zZXJ0QmVmb3JlKGNzc05vZGUsIGNoaWxkTm9kZXNbaW5kZXhdKVxuICAgIH0gZWxzZSB7XG4gICAgICBzdHlsZUVsZW1lbnQuYXBwZW5kQ2hpbGQoY3NzTm9kZSlcbiAgICB9XG4gIH1cbn1cblxuZnVuY3Rpb24gYXBwbHlUb1RhZyAoc3R5bGVFbGVtZW50LCBvYmopIHtcbiAgdmFyIGNzcyA9IG9iai5jc3NcbiAgdmFyIG1lZGlhID0gb2JqLm1lZGlhXG4gIHZhciBzb3VyY2VNYXAgPSBvYmouc291cmNlTWFwXG5cbiAgaWYgKG1lZGlhKSB7XG4gICAgc3R5bGVFbGVtZW50LnNldEF0dHJpYnV0ZSgnbWVkaWEnLCBtZWRpYSlcbiAgfVxuXG4gIGlmIChzb3VyY2VNYXApIHtcbiAgICAvLyBodHRwczovL2RldmVsb3Blci5jaHJvbWUuY29tL2RldnRvb2xzL2RvY3MvamF2YXNjcmlwdC1kZWJ1Z2dpbmdcbiAgICAvLyB0aGlzIG1ha2VzIHNvdXJjZSBtYXBzIGluc2lkZSBzdHlsZSB0YWdzIHdvcmsgcHJvcGVybHkgaW4gQ2hyb21lXG4gICAgY3NzICs9ICdcXG4vKiMgc291cmNlVVJMPScgKyBzb3VyY2VNYXAuc291cmNlc1swXSArICcgKi8nXG4gICAgLy8gaHR0cDovL3N0YWNrb3ZlcmZsb3cuY29tL2EvMjY2MDM4NzVcbiAgICBjc3MgKz0gJ1xcbi8qIyBzb3VyY2VNYXBwaW5nVVJMPWRhdGE6YXBwbGljYXRpb24vanNvbjtiYXNlNjQsJyArIGJ0b2EodW5lc2NhcGUoZW5jb2RlVVJJQ29tcG9uZW50KEpTT04uc3RyaW5naWZ5KHNvdXJjZU1hcCkpKSkgKyAnICovJ1xuICB9XG5cbiAgaWYgKHN0eWxlRWxlbWVudC5zdHlsZVNoZWV0KSB7XG4gICAgc3R5bGVFbGVtZW50LnN0eWxlU2hlZXQuY3NzVGV4dCA9IGNzc1xuICB9IGVsc2Uge1xuICAgIHdoaWxlIChzdHlsZUVsZW1lbnQuZmlyc3RDaGlsZCkge1xuICAgICAgc3R5bGVFbGVtZW50LnJlbW92ZUNoaWxkKHN0eWxlRWxlbWVudC5maXJzdENoaWxkKVxuICAgIH1cbiAgICBzdHlsZUVsZW1lbnQuYXBwZW5kQ2hpbGQoZG9jdW1lbnQuY3JlYXRlVGV4dE5vZGUoY3NzKSlcbiAgfVxufVxuXG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gLi9ub2RlX21vZHVsZXMvdnVlLXN0eWxlLWxvYWRlci9saWIvYWRkU3R5bGVzQ2xpZW50LmpzXG4vLyBtb2R1bGUgaWQgPSAxXG4vLyBtb2R1bGUgY2h1bmtzID0gMCIsIi8qIGdsb2JhbHMgX19WVUVfU1NSX0NPTlRFWFRfXyAqL1xuXG4vLyB0aGlzIG1vZHVsZSBpcyBhIHJ1bnRpbWUgdXRpbGl0eSBmb3IgY2xlYW5lciBjb21wb25lbnQgbW9kdWxlIG91dHB1dCBhbmQgd2lsbFxuLy8gYmUgaW5jbHVkZWQgaW4gdGhlIGZpbmFsIHdlYnBhY2sgdXNlciBidW5kbGVcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBub3JtYWxpemVDb21wb25lbnQgKFxuICByYXdTY3JpcHRFeHBvcnRzLFxuICBjb21waWxlZFRlbXBsYXRlLFxuICBpbmplY3RTdHlsZXMsXG4gIHNjb3BlSWQsXG4gIG1vZHVsZUlkZW50aWZpZXIgLyogc2VydmVyIG9ubHkgKi9cbikge1xuICB2YXIgZXNNb2R1bGVcbiAgdmFyIHNjcmlwdEV4cG9ydHMgPSByYXdTY3JpcHRFeHBvcnRzID0gcmF3U2NyaXB0RXhwb3J0cyB8fCB7fVxuXG4gIC8vIEVTNiBtb2R1bGVzIGludGVyb3BcbiAgdmFyIHR5cGUgPSB0eXBlb2YgcmF3U2NyaXB0RXhwb3J0cy5kZWZhdWx0XG4gIGlmICh0eXBlID09PSAnb2JqZWN0JyB8fCB0eXBlID09PSAnZnVuY3Rpb24nKSB7XG4gICAgZXNNb2R1bGUgPSByYXdTY3JpcHRFeHBvcnRzXG4gICAgc2NyaXB0RXhwb3J0cyA9IHJhd1NjcmlwdEV4cG9ydHMuZGVmYXVsdFxuICB9XG5cbiAgLy8gVnVlLmV4dGVuZCBjb25zdHJ1Y3RvciBleHBvcnQgaW50ZXJvcFxuICB2YXIgb3B0aW9ucyA9IHR5cGVvZiBzY3JpcHRFeHBvcnRzID09PSAnZnVuY3Rpb24nXG4gICAgPyBzY3JpcHRFeHBvcnRzLm9wdGlvbnNcbiAgICA6IHNjcmlwdEV4cG9ydHNcblxuICAvLyByZW5kZXIgZnVuY3Rpb25zXG4gIGlmIChjb21waWxlZFRlbXBsYXRlKSB7XG4gICAgb3B0aW9ucy5yZW5kZXIgPSBjb21waWxlZFRlbXBsYXRlLnJlbmRlclxuICAgIG9wdGlvbnMuc3RhdGljUmVuZGVyRm5zID0gY29tcGlsZWRUZW1wbGF0ZS5zdGF0aWNSZW5kZXJGbnNcbiAgfVxuXG4gIC8vIHNjb3BlZElkXG4gIGlmIChzY29wZUlkKSB7XG4gICAgb3B0aW9ucy5fc2NvcGVJZCA9IHNjb3BlSWRcbiAgfVxuXG4gIHZhciBob29rXG4gIGlmIChtb2R1bGVJZGVudGlmaWVyKSB7IC8vIHNlcnZlciBidWlsZFxuICAgIGhvb2sgPSBmdW5jdGlvbiAoY29udGV4dCkge1xuICAgICAgLy8gMi4zIGluamVjdGlvblxuICAgICAgY29udGV4dCA9XG4gICAgICAgIGNvbnRleHQgfHwgLy8gY2FjaGVkIGNhbGxcbiAgICAgICAgKHRoaXMuJHZub2RlICYmIHRoaXMuJHZub2RlLnNzckNvbnRleHQpIHx8IC8vIHN0YXRlZnVsXG4gICAgICAgICh0aGlzLnBhcmVudCAmJiB0aGlzLnBhcmVudC4kdm5vZGUgJiYgdGhpcy5wYXJlbnQuJHZub2RlLnNzckNvbnRleHQpIC8vIGZ1bmN0aW9uYWxcbiAgICAgIC8vIDIuMiB3aXRoIHJ1bkluTmV3Q29udGV4dDogdHJ1ZVxuICAgICAgaWYgKCFjb250ZXh0ICYmIHR5cGVvZiBfX1ZVRV9TU1JfQ09OVEVYVF9fICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgICBjb250ZXh0ID0gX19WVUVfU1NSX0NPTlRFWFRfX1xuICAgICAgfVxuICAgICAgLy8gaW5qZWN0IGNvbXBvbmVudCBzdHlsZXNcbiAgICAgIGlmIChpbmplY3RTdHlsZXMpIHtcbiAgICAgICAgaW5qZWN0U3R5bGVzLmNhbGwodGhpcywgY29udGV4dClcbiAgICAgIH1cbiAgICAgIC8vIHJlZ2lzdGVyIGNvbXBvbmVudCBtb2R1bGUgaWRlbnRpZmllciBmb3IgYXN5bmMgY2h1bmsgaW5mZXJyZW5jZVxuICAgICAgaWYgKGNvbnRleHQgJiYgY29udGV4dC5fcmVnaXN0ZXJlZENvbXBvbmVudHMpIHtcbiAgICAgICAgY29udGV4dC5fcmVnaXN0ZXJlZENvbXBvbmVudHMuYWRkKG1vZHVsZUlkZW50aWZpZXIpXG4gICAgICB9XG4gICAgfVxuICAgIC8vIHVzZWQgYnkgc3NyIGluIGNhc2UgY29tcG9uZW50IGlzIGNhY2hlZCBhbmQgYmVmb3JlQ3JlYXRlXG4gICAgLy8gbmV2ZXIgZ2V0cyBjYWxsZWRcbiAgICBvcHRpb25zLl9zc3JSZWdpc3RlciA9IGhvb2tcbiAgfSBlbHNlIGlmIChpbmplY3RTdHlsZXMpIHtcbiAgICBob29rID0gaW5qZWN0U3R5bGVzXG4gIH1cblxuICBpZiAoaG9vaykge1xuICAgIHZhciBmdW5jdGlvbmFsID0gb3B0aW9ucy5mdW5jdGlvbmFsXG4gICAgdmFyIGV4aXN0aW5nID0gZnVuY3Rpb25hbFxuICAgICAgPyBvcHRpb25zLnJlbmRlclxuICAgICAgOiBvcHRpb25zLmJlZm9yZUNyZWF0ZVxuICAgIGlmICghZnVuY3Rpb25hbCkge1xuICAgICAgLy8gaW5qZWN0IGNvbXBvbmVudCByZWdpc3RyYXRpb24gYXMgYmVmb3JlQ3JlYXRlIGhvb2tcbiAgICAgIG9wdGlvbnMuYmVmb3JlQ3JlYXRlID0gZXhpc3RpbmdcbiAgICAgICAgPyBbXS5jb25jYXQoZXhpc3RpbmcsIGhvb2spXG4gICAgICAgIDogW2hvb2tdXG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIHJlZ2lzdGVyIGZvciBmdW5jdGlvYWwgY29tcG9uZW50IGluIHZ1ZSBmaWxlXG4gICAgICBvcHRpb25zLnJlbmRlciA9IGZ1bmN0aW9uIHJlbmRlcldpdGhTdHlsZUluamVjdGlvbiAoaCwgY29udGV4dCkge1xuICAgICAgICBob29rLmNhbGwoY29udGV4dClcbiAgICAgICAgcmV0dXJuIGV4aXN0aW5nKGgsIGNvbnRleHQpXG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHtcbiAgICBlc01vZHVsZTogZXNNb2R1bGUsXG4gICAgZXhwb3J0czogc2NyaXB0RXhwb3J0cyxcbiAgICBvcHRpb25zOiBvcHRpb25zXG4gIH1cbn1cblxuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIC4vbm9kZV9tb2R1bGVzL3Z1ZS1sb2FkZXIvbGliL2NvbXBvbmVudC1ub3JtYWxpemVyLmpzXG4vLyBtb2R1bGUgaWQgPSAyXG4vLyBtb2R1bGUgY2h1bmtzID0gMCIsIi8qIVxuICogalF1ZXJ5IEphdmFTY3JpcHQgTGlicmFyeSB2My4yLjFcbiAqIGh0dHBzOi8vanF1ZXJ5LmNvbS9cbiAqXG4gKiBJbmNsdWRlcyBTaXp6bGUuanNcbiAqIGh0dHBzOi8vc2l6emxlanMuY29tL1xuICpcbiAqIENvcHlyaWdodCBKUyBGb3VuZGF0aW9uIGFuZCBvdGhlciBjb250cmlidXRvcnNcbiAqIFJlbGVhc2VkIHVuZGVyIHRoZSBNSVQgbGljZW5zZVxuICogaHR0cHM6Ly9qcXVlcnkub3JnL2xpY2Vuc2VcbiAqXG4gKiBEYXRlOiAyMDE3LTAzLTIwVDE4OjU5WlxuICovXG4oIGZ1bmN0aW9uKCBnbG9iYWwsIGZhY3RvcnkgKSB7XG5cblx0XCJ1c2Ugc3RyaWN0XCI7XG5cblx0aWYgKCB0eXBlb2YgbW9kdWxlID09PSBcIm9iamVjdFwiICYmIHR5cGVvZiBtb2R1bGUuZXhwb3J0cyA9PT0gXCJvYmplY3RcIiApIHtcblxuXHRcdC8vIEZvciBDb21tb25KUyBhbmQgQ29tbW9uSlMtbGlrZSBlbnZpcm9ubWVudHMgd2hlcmUgYSBwcm9wZXIgYHdpbmRvd2Bcblx0XHQvLyBpcyBwcmVzZW50LCBleGVjdXRlIHRoZSBmYWN0b3J5IGFuZCBnZXQgalF1ZXJ5LlxuXHRcdC8vIEZvciBlbnZpcm9ubWVudHMgdGhhdCBkbyBub3QgaGF2ZSBhIGB3aW5kb3dgIHdpdGggYSBgZG9jdW1lbnRgXG5cdFx0Ly8gKHN1Y2ggYXMgTm9kZS5qcyksIGV4cG9zZSBhIGZhY3RvcnkgYXMgbW9kdWxlLmV4cG9ydHMuXG5cdFx0Ly8gVGhpcyBhY2NlbnR1YXRlcyB0aGUgbmVlZCBmb3IgdGhlIGNyZWF0aW9uIG9mIGEgcmVhbCBgd2luZG93YC5cblx0XHQvLyBlLmcuIHZhciBqUXVlcnkgPSByZXF1aXJlKFwianF1ZXJ5XCIpKHdpbmRvdyk7XG5cdFx0Ly8gU2VlIHRpY2tldCAjMTQ1NDkgZm9yIG1vcmUgaW5mby5cblx0XHRtb2R1bGUuZXhwb3J0cyA9IGdsb2JhbC5kb2N1bWVudCA/XG5cdFx0XHRmYWN0b3J5KCBnbG9iYWwsIHRydWUgKSA6XG5cdFx0XHRmdW5jdGlvbiggdyApIHtcblx0XHRcdFx0aWYgKCAhdy5kb2N1bWVudCApIHtcblx0XHRcdFx0XHR0aHJvdyBuZXcgRXJyb3IoIFwialF1ZXJ5IHJlcXVpcmVzIGEgd2luZG93IHdpdGggYSBkb2N1bWVudFwiICk7XG5cdFx0XHRcdH1cblx0XHRcdFx0cmV0dXJuIGZhY3RvcnkoIHcgKTtcblx0XHRcdH07XG5cdH0gZWxzZSB7XG5cdFx0ZmFjdG9yeSggZ2xvYmFsICk7XG5cdH1cblxuLy8gUGFzcyB0aGlzIGlmIHdpbmRvdyBpcyBub3QgZGVmaW5lZCB5ZXRcbn0gKSggdHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIiA/IHdpbmRvdyA6IHRoaXMsIGZ1bmN0aW9uKCB3aW5kb3csIG5vR2xvYmFsICkge1xuXG4vLyBFZGdlIDw9IDEyIC0gMTMrLCBGaXJlZm94IDw9MTggLSA0NSssIElFIDEwIC0gMTEsIFNhZmFyaSA1LjEgLSA5KywgaU9TIDYgLSA5LjFcbi8vIHRocm93IGV4Y2VwdGlvbnMgd2hlbiBub24tc3RyaWN0IGNvZGUgKGUuZy4sIEFTUC5ORVQgNC41KSBhY2Nlc3NlcyBzdHJpY3QgbW9kZVxuLy8gYXJndW1lbnRzLmNhbGxlZS5jYWxsZXIgKHRyYWMtMTMzMzUpLiBCdXQgYXMgb2YgalF1ZXJ5IDMuMCAoMjAxNiksIHN0cmljdCBtb2RlIHNob3VsZCBiZSBjb21tb25cbi8vIGVub3VnaCB0aGF0IGFsbCBzdWNoIGF0dGVtcHRzIGFyZSBndWFyZGVkIGluIGEgdHJ5IGJsb2NrLlxuXCJ1c2Ugc3RyaWN0XCI7XG5cbnZhciBhcnIgPSBbXTtcblxudmFyIGRvY3VtZW50ID0gd2luZG93LmRvY3VtZW50O1xuXG52YXIgZ2V0UHJvdG8gPSBPYmplY3QuZ2V0UHJvdG90eXBlT2Y7XG5cbnZhciBzbGljZSA9IGFyci5zbGljZTtcblxudmFyIGNvbmNhdCA9IGFyci5jb25jYXQ7XG5cbnZhciBwdXNoID0gYXJyLnB1c2g7XG5cbnZhciBpbmRleE9mID0gYXJyLmluZGV4T2Y7XG5cbnZhciBjbGFzczJ0eXBlID0ge307XG5cbnZhciB0b1N0cmluZyA9IGNsYXNzMnR5cGUudG9TdHJpbmc7XG5cbnZhciBoYXNPd24gPSBjbGFzczJ0eXBlLmhhc093blByb3BlcnR5O1xuXG52YXIgZm5Ub1N0cmluZyA9IGhhc093bi50b1N0cmluZztcblxudmFyIE9iamVjdEZ1bmN0aW9uU3RyaW5nID0gZm5Ub1N0cmluZy5jYWxsKCBPYmplY3QgKTtcblxudmFyIHN1cHBvcnQgPSB7fTtcblxuXG5cblx0ZnVuY3Rpb24gRE9NRXZhbCggY29kZSwgZG9jICkge1xuXHRcdGRvYyA9IGRvYyB8fCBkb2N1bWVudDtcblxuXHRcdHZhciBzY3JpcHQgPSBkb2MuY3JlYXRlRWxlbWVudCggXCJzY3JpcHRcIiApO1xuXG5cdFx0c2NyaXB0LnRleHQgPSBjb2RlO1xuXHRcdGRvYy5oZWFkLmFwcGVuZENoaWxkKCBzY3JpcHQgKS5wYXJlbnROb2RlLnJlbW92ZUNoaWxkKCBzY3JpcHQgKTtcblx0fVxuLyogZ2xvYmFsIFN5bWJvbCAqL1xuLy8gRGVmaW5pbmcgdGhpcyBnbG9iYWwgaW4gLmVzbGludHJjLmpzb24gd291bGQgY3JlYXRlIGEgZGFuZ2VyIG9mIHVzaW5nIHRoZSBnbG9iYWxcbi8vIHVuZ3VhcmRlZCBpbiBhbm90aGVyIHBsYWNlLCBpdCBzZWVtcyBzYWZlciB0byBkZWZpbmUgZ2xvYmFsIG9ubHkgZm9yIHRoaXMgbW9kdWxlXG5cblxuXG52YXJcblx0dmVyc2lvbiA9IFwiMy4yLjFcIixcblxuXHQvLyBEZWZpbmUgYSBsb2NhbCBjb3B5IG9mIGpRdWVyeVxuXHRqUXVlcnkgPSBmdW5jdGlvbiggc2VsZWN0b3IsIGNvbnRleHQgKSB7XG5cblx0XHQvLyBUaGUgalF1ZXJ5IG9iamVjdCBpcyBhY3R1YWxseSBqdXN0IHRoZSBpbml0IGNvbnN0cnVjdG9yICdlbmhhbmNlZCdcblx0XHQvLyBOZWVkIGluaXQgaWYgalF1ZXJ5IGlzIGNhbGxlZCAoanVzdCBhbGxvdyBlcnJvciB0byBiZSB0aHJvd24gaWYgbm90IGluY2x1ZGVkKVxuXHRcdHJldHVybiBuZXcgalF1ZXJ5LmZuLmluaXQoIHNlbGVjdG9yLCBjb250ZXh0ICk7XG5cdH0sXG5cblx0Ly8gU3VwcG9ydDogQW5kcm9pZCA8PTQuMCBvbmx5XG5cdC8vIE1ha2Ugc3VyZSB3ZSB0cmltIEJPTSBhbmQgTkJTUFxuXHRydHJpbSA9IC9eW1xcc1xcdUZFRkZcXHhBMF0rfFtcXHNcXHVGRUZGXFx4QTBdKyQvZyxcblxuXHQvLyBNYXRjaGVzIGRhc2hlZCBzdHJpbmcgZm9yIGNhbWVsaXppbmdcblx0cm1zUHJlZml4ID0gL14tbXMtLyxcblx0cmRhc2hBbHBoYSA9IC8tKFthLXpdKS9nLFxuXG5cdC8vIFVzZWQgYnkgalF1ZXJ5LmNhbWVsQ2FzZSBhcyBjYWxsYmFjayB0byByZXBsYWNlKClcblx0ZmNhbWVsQ2FzZSA9IGZ1bmN0aW9uKCBhbGwsIGxldHRlciApIHtcblx0XHRyZXR1cm4gbGV0dGVyLnRvVXBwZXJDYXNlKCk7XG5cdH07XG5cbmpRdWVyeS5mbiA9IGpRdWVyeS5wcm90b3R5cGUgPSB7XG5cblx0Ly8gVGhlIGN1cnJlbnQgdmVyc2lvbiBvZiBqUXVlcnkgYmVpbmcgdXNlZFxuXHRqcXVlcnk6IHZlcnNpb24sXG5cblx0Y29uc3RydWN0b3I6IGpRdWVyeSxcblxuXHQvLyBUaGUgZGVmYXVsdCBsZW5ndGggb2YgYSBqUXVlcnkgb2JqZWN0IGlzIDBcblx0bGVuZ3RoOiAwLFxuXG5cdHRvQXJyYXk6IGZ1bmN0aW9uKCkge1xuXHRcdHJldHVybiBzbGljZS5jYWxsKCB0aGlzICk7XG5cdH0sXG5cblx0Ly8gR2V0IHRoZSBOdGggZWxlbWVudCBpbiB0aGUgbWF0Y2hlZCBlbGVtZW50IHNldCBPUlxuXHQvLyBHZXQgdGhlIHdob2xlIG1hdGNoZWQgZWxlbWVudCBzZXQgYXMgYSBjbGVhbiBhcnJheVxuXHRnZXQ6IGZ1bmN0aW9uKCBudW0gKSB7XG5cblx0XHQvLyBSZXR1cm4gYWxsIHRoZSBlbGVtZW50cyBpbiBhIGNsZWFuIGFycmF5XG5cdFx0aWYgKCBudW0gPT0gbnVsbCApIHtcblx0XHRcdHJldHVybiBzbGljZS5jYWxsKCB0aGlzICk7XG5cdFx0fVxuXG5cdFx0Ly8gUmV0dXJuIGp1c3QgdGhlIG9uZSBlbGVtZW50IGZyb20gdGhlIHNldFxuXHRcdHJldHVybiBudW0gPCAwID8gdGhpc1sgbnVtICsgdGhpcy5sZW5ndGggXSA6IHRoaXNbIG51bSBdO1xuXHR9LFxuXG5cdC8vIFRha2UgYW4gYXJyYXkgb2YgZWxlbWVudHMgYW5kIHB1c2ggaXQgb250byB0aGUgc3RhY2tcblx0Ly8gKHJldHVybmluZyB0aGUgbmV3IG1hdGNoZWQgZWxlbWVudCBzZXQpXG5cdHB1c2hTdGFjazogZnVuY3Rpb24oIGVsZW1zICkge1xuXG5cdFx0Ly8gQnVpbGQgYSBuZXcgalF1ZXJ5IG1hdGNoZWQgZWxlbWVudCBzZXRcblx0XHR2YXIgcmV0ID0galF1ZXJ5Lm1lcmdlKCB0aGlzLmNvbnN0cnVjdG9yKCksIGVsZW1zICk7XG5cblx0XHQvLyBBZGQgdGhlIG9sZCBvYmplY3Qgb250byB0aGUgc3RhY2sgKGFzIGEgcmVmZXJlbmNlKVxuXHRcdHJldC5wcmV2T2JqZWN0ID0gdGhpcztcblxuXHRcdC8vIFJldHVybiB0aGUgbmV3bHktZm9ybWVkIGVsZW1lbnQgc2V0XG5cdFx0cmV0dXJuIHJldDtcblx0fSxcblxuXHQvLyBFeGVjdXRlIGEgY2FsbGJhY2sgZm9yIGV2ZXJ5IGVsZW1lbnQgaW4gdGhlIG1hdGNoZWQgc2V0LlxuXHRlYWNoOiBmdW5jdGlvbiggY2FsbGJhY2sgKSB7XG5cdFx0cmV0dXJuIGpRdWVyeS5lYWNoKCB0aGlzLCBjYWxsYmFjayApO1xuXHR9LFxuXG5cdG1hcDogZnVuY3Rpb24oIGNhbGxiYWNrICkge1xuXHRcdHJldHVybiB0aGlzLnB1c2hTdGFjayggalF1ZXJ5Lm1hcCggdGhpcywgZnVuY3Rpb24oIGVsZW0sIGkgKSB7XG5cdFx0XHRyZXR1cm4gY2FsbGJhY2suY2FsbCggZWxlbSwgaSwgZWxlbSApO1xuXHRcdH0gKSApO1xuXHR9LFxuXG5cdHNsaWNlOiBmdW5jdGlvbigpIHtcblx0XHRyZXR1cm4gdGhpcy5wdXNoU3RhY2soIHNsaWNlLmFwcGx5KCB0aGlzLCBhcmd1bWVudHMgKSApO1xuXHR9LFxuXG5cdGZpcnN0OiBmdW5jdGlvbigpIHtcblx0XHRyZXR1cm4gdGhpcy5lcSggMCApO1xuXHR9LFxuXG5cdGxhc3Q6IGZ1bmN0aW9uKCkge1xuXHRcdHJldHVybiB0aGlzLmVxKCAtMSApO1xuXHR9LFxuXG5cdGVxOiBmdW5jdGlvbiggaSApIHtcblx0XHR2YXIgbGVuID0gdGhpcy5sZW5ndGgsXG5cdFx0XHRqID0gK2kgKyAoIGkgPCAwID8gbGVuIDogMCApO1xuXHRcdHJldHVybiB0aGlzLnB1c2hTdGFjayggaiA+PSAwICYmIGogPCBsZW4gPyBbIHRoaXNbIGogXSBdIDogW10gKTtcblx0fSxcblxuXHRlbmQ6IGZ1bmN0aW9uKCkge1xuXHRcdHJldHVybiB0aGlzLnByZXZPYmplY3QgfHwgdGhpcy5jb25zdHJ1Y3RvcigpO1xuXHR9LFxuXG5cdC8vIEZvciBpbnRlcm5hbCB1c2Ugb25seS5cblx0Ly8gQmVoYXZlcyBsaWtlIGFuIEFycmF5J3MgbWV0aG9kLCBub3QgbGlrZSBhIGpRdWVyeSBtZXRob2QuXG5cdHB1c2g6IHB1c2gsXG5cdHNvcnQ6IGFyci5zb3J0LFxuXHRzcGxpY2U6IGFyci5zcGxpY2Vcbn07XG5cbmpRdWVyeS5leHRlbmQgPSBqUXVlcnkuZm4uZXh0ZW5kID0gZnVuY3Rpb24oKSB7XG5cdHZhciBvcHRpb25zLCBuYW1lLCBzcmMsIGNvcHksIGNvcHlJc0FycmF5LCBjbG9uZSxcblx0XHR0YXJnZXQgPSBhcmd1bWVudHNbIDAgXSB8fCB7fSxcblx0XHRpID0gMSxcblx0XHRsZW5ndGggPSBhcmd1bWVudHMubGVuZ3RoLFxuXHRcdGRlZXAgPSBmYWxzZTtcblxuXHQvLyBIYW5kbGUgYSBkZWVwIGNvcHkgc2l0dWF0aW9uXG5cdGlmICggdHlwZW9mIHRhcmdldCA9PT0gXCJib29sZWFuXCIgKSB7XG5cdFx0ZGVlcCA9IHRhcmdldDtcblxuXHRcdC8vIFNraXAgdGhlIGJvb2xlYW4gYW5kIHRoZSB0YXJnZXRcblx0XHR0YXJnZXQgPSBhcmd1bWVudHNbIGkgXSB8fCB7fTtcblx0XHRpKys7XG5cdH1cblxuXHQvLyBIYW5kbGUgY2FzZSB3aGVuIHRhcmdldCBpcyBhIHN0cmluZyBvciBzb21ldGhpbmcgKHBvc3NpYmxlIGluIGRlZXAgY29weSlcblx0aWYgKCB0eXBlb2YgdGFyZ2V0ICE9PSBcIm9iamVjdFwiICYmICFqUXVlcnkuaXNGdW5jdGlvbiggdGFyZ2V0ICkgKSB7XG5cdFx0dGFyZ2V0ID0ge307XG5cdH1cblxuXHQvLyBFeHRlbmQgalF1ZXJ5IGl0c2VsZiBpZiBvbmx5IG9uZSBhcmd1bWVudCBpcyBwYXNzZWRcblx0aWYgKCBpID09PSBsZW5ndGggKSB7XG5cdFx0dGFyZ2V0ID0gdGhpcztcblx0XHRpLS07XG5cdH1cblxuXHRmb3IgKCA7IGkgPCBsZW5ndGg7IGkrKyApIHtcblxuXHRcdC8vIE9ubHkgZGVhbCB3aXRoIG5vbi1udWxsL3VuZGVmaW5lZCB2YWx1ZXNcblx0XHRpZiAoICggb3B0aW9ucyA9IGFyZ3VtZW50c1sgaSBdICkgIT0gbnVsbCApIHtcblxuXHRcdFx0Ly8gRXh0ZW5kIHRoZSBiYXNlIG9iamVjdFxuXHRcdFx0Zm9yICggbmFtZSBpbiBvcHRpb25zICkge1xuXHRcdFx0XHRzcmMgPSB0YXJnZXRbIG5hbWUgXTtcblx0XHRcdFx0Y29weSA9IG9wdGlvbnNbIG5hbWUgXTtcblxuXHRcdFx0XHQvLyBQcmV2ZW50IG5ldmVyLWVuZGluZyBsb29wXG5cdFx0XHRcdGlmICggdGFyZ2V0ID09PSBjb3B5ICkge1xuXHRcdFx0XHRcdGNvbnRpbnVlO1xuXHRcdFx0XHR9XG5cblx0XHRcdFx0Ly8gUmVjdXJzZSBpZiB3ZSdyZSBtZXJnaW5nIHBsYWluIG9iamVjdHMgb3IgYXJyYXlzXG5cdFx0XHRcdGlmICggZGVlcCAmJiBjb3B5ICYmICggalF1ZXJ5LmlzUGxhaW5PYmplY3QoIGNvcHkgKSB8fFxuXHRcdFx0XHRcdCggY29weUlzQXJyYXkgPSBBcnJheS5pc0FycmF5KCBjb3B5ICkgKSApICkge1xuXG5cdFx0XHRcdFx0aWYgKCBjb3B5SXNBcnJheSApIHtcblx0XHRcdFx0XHRcdGNvcHlJc0FycmF5ID0gZmFsc2U7XG5cdFx0XHRcdFx0XHRjbG9uZSA9IHNyYyAmJiBBcnJheS5pc0FycmF5KCBzcmMgKSA/IHNyYyA6IFtdO1xuXG5cdFx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRcdGNsb25lID0gc3JjICYmIGpRdWVyeS5pc1BsYWluT2JqZWN0KCBzcmMgKSA/IHNyYyA6IHt9O1xuXHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdC8vIE5ldmVyIG1vdmUgb3JpZ2luYWwgb2JqZWN0cywgY2xvbmUgdGhlbVxuXHRcdFx0XHRcdHRhcmdldFsgbmFtZSBdID0galF1ZXJ5LmV4dGVuZCggZGVlcCwgY2xvbmUsIGNvcHkgKTtcblxuXHRcdFx0XHQvLyBEb24ndCBicmluZyBpbiB1bmRlZmluZWQgdmFsdWVzXG5cdFx0XHRcdH0gZWxzZSBpZiAoIGNvcHkgIT09IHVuZGVmaW5lZCApIHtcblx0XHRcdFx0XHR0YXJnZXRbIG5hbWUgXSA9IGNvcHk7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9XG5cdH1cblxuXHQvLyBSZXR1cm4gdGhlIG1vZGlmaWVkIG9iamVjdFxuXHRyZXR1cm4gdGFyZ2V0O1xufTtcblxualF1ZXJ5LmV4dGVuZCgge1xuXG5cdC8vIFVuaXF1ZSBmb3IgZWFjaCBjb3B5IG9mIGpRdWVyeSBvbiB0aGUgcGFnZVxuXHRleHBhbmRvOiBcImpRdWVyeVwiICsgKCB2ZXJzaW9uICsgTWF0aC5yYW5kb20oKSApLnJlcGxhY2UoIC9cXEQvZywgXCJcIiApLFxuXG5cdC8vIEFzc3VtZSBqUXVlcnkgaXMgcmVhZHkgd2l0aG91dCB0aGUgcmVhZHkgbW9kdWxlXG5cdGlzUmVhZHk6IHRydWUsXG5cblx0ZXJyb3I6IGZ1bmN0aW9uKCBtc2cgKSB7XG5cdFx0dGhyb3cgbmV3IEVycm9yKCBtc2cgKTtcblx0fSxcblxuXHRub29wOiBmdW5jdGlvbigpIHt9LFxuXG5cdGlzRnVuY3Rpb246IGZ1bmN0aW9uKCBvYmogKSB7XG5cdFx0cmV0dXJuIGpRdWVyeS50eXBlKCBvYmogKSA9PT0gXCJmdW5jdGlvblwiO1xuXHR9LFxuXG5cdGlzV2luZG93OiBmdW5jdGlvbiggb2JqICkge1xuXHRcdHJldHVybiBvYmogIT0gbnVsbCAmJiBvYmogPT09IG9iai53aW5kb3c7XG5cdH0sXG5cblx0aXNOdW1lcmljOiBmdW5jdGlvbiggb2JqICkge1xuXG5cdFx0Ly8gQXMgb2YgalF1ZXJ5IDMuMCwgaXNOdW1lcmljIGlzIGxpbWl0ZWQgdG9cblx0XHQvLyBzdHJpbmdzIGFuZCBudW1iZXJzIChwcmltaXRpdmVzIG9yIG9iamVjdHMpXG5cdFx0Ly8gdGhhdCBjYW4gYmUgY29lcmNlZCB0byBmaW5pdGUgbnVtYmVycyAoZ2gtMjY2Milcblx0XHR2YXIgdHlwZSA9IGpRdWVyeS50eXBlKCBvYmogKTtcblx0XHRyZXR1cm4gKCB0eXBlID09PSBcIm51bWJlclwiIHx8IHR5cGUgPT09IFwic3RyaW5nXCIgKSAmJlxuXG5cdFx0XHQvLyBwYXJzZUZsb2F0IE5hTnMgbnVtZXJpYy1jYXN0IGZhbHNlIHBvc2l0aXZlcyAoXCJcIilcblx0XHRcdC8vIC4uLmJ1dCBtaXNpbnRlcnByZXRzIGxlYWRpbmctbnVtYmVyIHN0cmluZ3MsIHBhcnRpY3VsYXJseSBoZXggbGl0ZXJhbHMgKFwiMHguLi5cIilcblx0XHRcdC8vIHN1YnRyYWN0aW9uIGZvcmNlcyBpbmZpbml0aWVzIHRvIE5hTlxuXHRcdFx0IWlzTmFOKCBvYmogLSBwYXJzZUZsb2F0KCBvYmogKSApO1xuXHR9LFxuXG5cdGlzUGxhaW5PYmplY3Q6IGZ1bmN0aW9uKCBvYmogKSB7XG5cdFx0dmFyIHByb3RvLCBDdG9yO1xuXG5cdFx0Ly8gRGV0ZWN0IG9idmlvdXMgbmVnYXRpdmVzXG5cdFx0Ly8gVXNlIHRvU3RyaW5nIGluc3RlYWQgb2YgalF1ZXJ5LnR5cGUgdG8gY2F0Y2ggaG9zdCBvYmplY3RzXG5cdFx0aWYgKCAhb2JqIHx8IHRvU3RyaW5nLmNhbGwoIG9iaiApICE9PSBcIltvYmplY3QgT2JqZWN0XVwiICkge1xuXHRcdFx0cmV0dXJuIGZhbHNlO1xuXHRcdH1cblxuXHRcdHByb3RvID0gZ2V0UHJvdG8oIG9iaiApO1xuXG5cdFx0Ly8gT2JqZWN0cyB3aXRoIG5vIHByb3RvdHlwZSAoZS5nLiwgYE9iamVjdC5jcmVhdGUoIG51bGwgKWApIGFyZSBwbGFpblxuXHRcdGlmICggIXByb3RvICkge1xuXHRcdFx0cmV0dXJuIHRydWU7XG5cdFx0fVxuXG5cdFx0Ly8gT2JqZWN0cyB3aXRoIHByb3RvdHlwZSBhcmUgcGxhaW4gaWZmIHRoZXkgd2VyZSBjb25zdHJ1Y3RlZCBieSBhIGdsb2JhbCBPYmplY3QgZnVuY3Rpb25cblx0XHRDdG9yID0gaGFzT3duLmNhbGwoIHByb3RvLCBcImNvbnN0cnVjdG9yXCIgKSAmJiBwcm90by5jb25zdHJ1Y3Rvcjtcblx0XHRyZXR1cm4gdHlwZW9mIEN0b3IgPT09IFwiZnVuY3Rpb25cIiAmJiBmblRvU3RyaW5nLmNhbGwoIEN0b3IgKSA9PT0gT2JqZWN0RnVuY3Rpb25TdHJpbmc7XG5cdH0sXG5cblx0aXNFbXB0eU9iamVjdDogZnVuY3Rpb24oIG9iaiApIHtcblxuXHRcdC8qIGVzbGludC1kaXNhYmxlIG5vLXVudXNlZC12YXJzICovXG5cdFx0Ly8gU2VlIGh0dHBzOi8vZ2l0aHViLmNvbS9lc2xpbnQvZXNsaW50L2lzc3Vlcy82MTI1XG5cdFx0dmFyIG5hbWU7XG5cblx0XHRmb3IgKCBuYW1lIGluIG9iaiApIHtcblx0XHRcdHJldHVybiBmYWxzZTtcblx0XHR9XG5cdFx0cmV0dXJuIHRydWU7XG5cdH0sXG5cblx0dHlwZTogZnVuY3Rpb24oIG9iaiApIHtcblx0XHRpZiAoIG9iaiA9PSBudWxsICkge1xuXHRcdFx0cmV0dXJuIG9iaiArIFwiXCI7XG5cdFx0fVxuXG5cdFx0Ly8gU3VwcG9ydDogQW5kcm9pZCA8PTIuMyBvbmx5IChmdW5jdGlvbmlzaCBSZWdFeHApXG5cdFx0cmV0dXJuIHR5cGVvZiBvYmogPT09IFwib2JqZWN0XCIgfHwgdHlwZW9mIG9iaiA9PT0gXCJmdW5jdGlvblwiID9cblx0XHRcdGNsYXNzMnR5cGVbIHRvU3RyaW5nLmNhbGwoIG9iaiApIF0gfHwgXCJvYmplY3RcIiA6XG5cdFx0XHR0eXBlb2Ygb2JqO1xuXHR9LFxuXG5cdC8vIEV2YWx1YXRlcyBhIHNjcmlwdCBpbiBhIGdsb2JhbCBjb250ZXh0XG5cdGdsb2JhbEV2YWw6IGZ1bmN0aW9uKCBjb2RlICkge1xuXHRcdERPTUV2YWwoIGNvZGUgKTtcblx0fSxcblxuXHQvLyBDb252ZXJ0IGRhc2hlZCB0byBjYW1lbENhc2U7IHVzZWQgYnkgdGhlIGNzcyBhbmQgZGF0YSBtb2R1bGVzXG5cdC8vIFN1cHBvcnQ6IElFIDw9OSAtIDExLCBFZGdlIDEyIC0gMTNcblx0Ly8gTWljcm9zb2Z0IGZvcmdvdCB0byBodW1wIHRoZWlyIHZlbmRvciBwcmVmaXggKCM5NTcyKVxuXHRjYW1lbENhc2U6IGZ1bmN0aW9uKCBzdHJpbmcgKSB7XG5cdFx0cmV0dXJuIHN0cmluZy5yZXBsYWNlKCBybXNQcmVmaXgsIFwibXMtXCIgKS5yZXBsYWNlKCByZGFzaEFscGhhLCBmY2FtZWxDYXNlICk7XG5cdH0sXG5cblx0ZWFjaDogZnVuY3Rpb24oIG9iaiwgY2FsbGJhY2sgKSB7XG5cdFx0dmFyIGxlbmd0aCwgaSA9IDA7XG5cblx0XHRpZiAoIGlzQXJyYXlMaWtlKCBvYmogKSApIHtcblx0XHRcdGxlbmd0aCA9IG9iai5sZW5ndGg7XG5cdFx0XHRmb3IgKCA7IGkgPCBsZW5ndGg7IGkrKyApIHtcblx0XHRcdFx0aWYgKCBjYWxsYmFjay5jYWxsKCBvYmpbIGkgXSwgaSwgb2JqWyBpIF0gKSA9PT0gZmFsc2UgKSB7XG5cdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9IGVsc2Uge1xuXHRcdFx0Zm9yICggaSBpbiBvYmogKSB7XG5cdFx0XHRcdGlmICggY2FsbGJhY2suY2FsbCggb2JqWyBpIF0sIGksIG9ialsgaSBdICkgPT09IGZhbHNlICkge1xuXHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0cmV0dXJuIG9iajtcblx0fSxcblxuXHQvLyBTdXBwb3J0OiBBbmRyb2lkIDw9NC4wIG9ubHlcblx0dHJpbTogZnVuY3Rpb24oIHRleHQgKSB7XG5cdFx0cmV0dXJuIHRleHQgPT0gbnVsbCA/XG5cdFx0XHRcIlwiIDpcblx0XHRcdCggdGV4dCArIFwiXCIgKS5yZXBsYWNlKCBydHJpbSwgXCJcIiApO1xuXHR9LFxuXG5cdC8vIHJlc3VsdHMgaXMgZm9yIGludGVybmFsIHVzYWdlIG9ubHlcblx0bWFrZUFycmF5OiBmdW5jdGlvbiggYXJyLCByZXN1bHRzICkge1xuXHRcdHZhciByZXQgPSByZXN1bHRzIHx8IFtdO1xuXG5cdFx0aWYgKCBhcnIgIT0gbnVsbCApIHtcblx0XHRcdGlmICggaXNBcnJheUxpa2UoIE9iamVjdCggYXJyICkgKSApIHtcblx0XHRcdFx0alF1ZXJ5Lm1lcmdlKCByZXQsXG5cdFx0XHRcdFx0dHlwZW9mIGFyciA9PT0gXCJzdHJpbmdcIiA/XG5cdFx0XHRcdFx0WyBhcnIgXSA6IGFyclxuXHRcdFx0XHQpO1xuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0cHVzaC5jYWxsKCByZXQsIGFyciApO1xuXHRcdFx0fVxuXHRcdH1cblxuXHRcdHJldHVybiByZXQ7XG5cdH0sXG5cblx0aW5BcnJheTogZnVuY3Rpb24oIGVsZW0sIGFyciwgaSApIHtcblx0XHRyZXR1cm4gYXJyID09IG51bGwgPyAtMSA6IGluZGV4T2YuY2FsbCggYXJyLCBlbGVtLCBpICk7XG5cdH0sXG5cblx0Ly8gU3VwcG9ydDogQW5kcm9pZCA8PTQuMCBvbmx5LCBQaGFudG9tSlMgMSBvbmx5XG5cdC8vIHB1c2guYXBwbHkoXywgYXJyYXlsaWtlKSB0aHJvd3Mgb24gYW5jaWVudCBXZWJLaXRcblx0bWVyZ2U6IGZ1bmN0aW9uKCBmaXJzdCwgc2Vjb25kICkge1xuXHRcdHZhciBsZW4gPSArc2Vjb25kLmxlbmd0aCxcblx0XHRcdGogPSAwLFxuXHRcdFx0aSA9IGZpcnN0Lmxlbmd0aDtcblxuXHRcdGZvciAoIDsgaiA8IGxlbjsgaisrICkge1xuXHRcdFx0Zmlyc3RbIGkrKyBdID0gc2Vjb25kWyBqIF07XG5cdFx0fVxuXG5cdFx0Zmlyc3QubGVuZ3RoID0gaTtcblxuXHRcdHJldHVybiBmaXJzdDtcblx0fSxcblxuXHRncmVwOiBmdW5jdGlvbiggZWxlbXMsIGNhbGxiYWNrLCBpbnZlcnQgKSB7XG5cdFx0dmFyIGNhbGxiYWNrSW52ZXJzZSxcblx0XHRcdG1hdGNoZXMgPSBbXSxcblx0XHRcdGkgPSAwLFxuXHRcdFx0bGVuZ3RoID0gZWxlbXMubGVuZ3RoLFxuXHRcdFx0Y2FsbGJhY2tFeHBlY3QgPSAhaW52ZXJ0O1xuXG5cdFx0Ly8gR28gdGhyb3VnaCB0aGUgYXJyYXksIG9ubHkgc2F2aW5nIHRoZSBpdGVtc1xuXHRcdC8vIHRoYXQgcGFzcyB0aGUgdmFsaWRhdG9yIGZ1bmN0aW9uXG5cdFx0Zm9yICggOyBpIDwgbGVuZ3RoOyBpKysgKSB7XG5cdFx0XHRjYWxsYmFja0ludmVyc2UgPSAhY2FsbGJhY2soIGVsZW1zWyBpIF0sIGkgKTtcblx0XHRcdGlmICggY2FsbGJhY2tJbnZlcnNlICE9PSBjYWxsYmFja0V4cGVjdCApIHtcblx0XHRcdFx0bWF0Y2hlcy5wdXNoKCBlbGVtc1sgaSBdICk7XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0cmV0dXJuIG1hdGNoZXM7XG5cdH0sXG5cblx0Ly8gYXJnIGlzIGZvciBpbnRlcm5hbCB1c2FnZSBvbmx5XG5cdG1hcDogZnVuY3Rpb24oIGVsZW1zLCBjYWxsYmFjaywgYXJnICkge1xuXHRcdHZhciBsZW5ndGgsIHZhbHVlLFxuXHRcdFx0aSA9IDAsXG5cdFx0XHRyZXQgPSBbXTtcblxuXHRcdC8vIEdvIHRocm91Z2ggdGhlIGFycmF5LCB0cmFuc2xhdGluZyBlYWNoIG9mIHRoZSBpdGVtcyB0byB0aGVpciBuZXcgdmFsdWVzXG5cdFx0aWYgKCBpc0FycmF5TGlrZSggZWxlbXMgKSApIHtcblx0XHRcdGxlbmd0aCA9IGVsZW1zLmxlbmd0aDtcblx0XHRcdGZvciAoIDsgaSA8IGxlbmd0aDsgaSsrICkge1xuXHRcdFx0XHR2YWx1ZSA9IGNhbGxiYWNrKCBlbGVtc1sgaSBdLCBpLCBhcmcgKTtcblxuXHRcdFx0XHRpZiAoIHZhbHVlICE9IG51bGwgKSB7XG5cdFx0XHRcdFx0cmV0LnB1c2goIHZhbHVlICk7XG5cdFx0XHRcdH1cblx0XHRcdH1cblxuXHRcdC8vIEdvIHRocm91Z2ggZXZlcnkga2V5IG9uIHRoZSBvYmplY3QsXG5cdFx0fSBlbHNlIHtcblx0XHRcdGZvciAoIGkgaW4gZWxlbXMgKSB7XG5cdFx0XHRcdHZhbHVlID0gY2FsbGJhY2soIGVsZW1zWyBpIF0sIGksIGFyZyApO1xuXG5cdFx0XHRcdGlmICggdmFsdWUgIT0gbnVsbCApIHtcblx0XHRcdFx0XHRyZXQucHVzaCggdmFsdWUgKTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH1cblxuXHRcdC8vIEZsYXR0ZW4gYW55IG5lc3RlZCBhcnJheXNcblx0XHRyZXR1cm4gY29uY2F0LmFwcGx5KCBbXSwgcmV0ICk7XG5cdH0sXG5cblx0Ly8gQSBnbG9iYWwgR1VJRCBjb3VudGVyIGZvciBvYmplY3RzXG5cdGd1aWQ6IDEsXG5cblx0Ly8gQmluZCBhIGZ1bmN0aW9uIHRvIGEgY29udGV4dCwgb3B0aW9uYWxseSBwYXJ0aWFsbHkgYXBwbHlpbmcgYW55XG5cdC8vIGFyZ3VtZW50cy5cblx0cHJveHk6IGZ1bmN0aW9uKCBmbiwgY29udGV4dCApIHtcblx0XHR2YXIgdG1wLCBhcmdzLCBwcm94eTtcblxuXHRcdGlmICggdHlwZW9mIGNvbnRleHQgPT09IFwic3RyaW5nXCIgKSB7XG5cdFx0XHR0bXAgPSBmblsgY29udGV4dCBdO1xuXHRcdFx0Y29udGV4dCA9IGZuO1xuXHRcdFx0Zm4gPSB0bXA7XG5cdFx0fVxuXG5cdFx0Ly8gUXVpY2sgY2hlY2sgdG8gZGV0ZXJtaW5lIGlmIHRhcmdldCBpcyBjYWxsYWJsZSwgaW4gdGhlIHNwZWNcblx0XHQvLyB0aGlzIHRocm93cyBhIFR5cGVFcnJvciwgYnV0IHdlIHdpbGwganVzdCByZXR1cm4gdW5kZWZpbmVkLlxuXHRcdGlmICggIWpRdWVyeS5pc0Z1bmN0aW9uKCBmbiApICkge1xuXHRcdFx0cmV0dXJuIHVuZGVmaW5lZDtcblx0XHR9XG5cblx0XHQvLyBTaW11bGF0ZWQgYmluZFxuXHRcdGFyZ3MgPSBzbGljZS5jYWxsKCBhcmd1bWVudHMsIDIgKTtcblx0XHRwcm94eSA9IGZ1bmN0aW9uKCkge1xuXHRcdFx0cmV0dXJuIGZuLmFwcGx5KCBjb250ZXh0IHx8IHRoaXMsIGFyZ3MuY29uY2F0KCBzbGljZS5jYWxsKCBhcmd1bWVudHMgKSApICk7XG5cdFx0fTtcblxuXHRcdC8vIFNldCB0aGUgZ3VpZCBvZiB1bmlxdWUgaGFuZGxlciB0byB0aGUgc2FtZSBvZiBvcmlnaW5hbCBoYW5kbGVyLCBzbyBpdCBjYW4gYmUgcmVtb3ZlZFxuXHRcdHByb3h5Lmd1aWQgPSBmbi5ndWlkID0gZm4uZ3VpZCB8fCBqUXVlcnkuZ3VpZCsrO1xuXG5cdFx0cmV0dXJuIHByb3h5O1xuXHR9LFxuXG5cdG5vdzogRGF0ZS5ub3csXG5cblx0Ly8galF1ZXJ5LnN1cHBvcnQgaXMgbm90IHVzZWQgaW4gQ29yZSBidXQgb3RoZXIgcHJvamVjdHMgYXR0YWNoIHRoZWlyXG5cdC8vIHByb3BlcnRpZXMgdG8gaXQgc28gaXQgbmVlZHMgdG8gZXhpc3QuXG5cdHN1cHBvcnQ6IHN1cHBvcnRcbn0gKTtcblxuaWYgKCB0eXBlb2YgU3ltYm9sID09PSBcImZ1bmN0aW9uXCIgKSB7XG5cdGpRdWVyeS5mblsgU3ltYm9sLml0ZXJhdG9yIF0gPSBhcnJbIFN5bWJvbC5pdGVyYXRvciBdO1xufVxuXG4vLyBQb3B1bGF0ZSB0aGUgY2xhc3MydHlwZSBtYXBcbmpRdWVyeS5lYWNoKCBcIkJvb2xlYW4gTnVtYmVyIFN0cmluZyBGdW5jdGlvbiBBcnJheSBEYXRlIFJlZ0V4cCBPYmplY3QgRXJyb3IgU3ltYm9sXCIuc3BsaXQoIFwiIFwiICksXG5mdW5jdGlvbiggaSwgbmFtZSApIHtcblx0Y2xhc3MydHlwZVsgXCJbb2JqZWN0IFwiICsgbmFtZSArIFwiXVwiIF0gPSBuYW1lLnRvTG93ZXJDYXNlKCk7XG59ICk7XG5cbmZ1bmN0aW9uIGlzQXJyYXlMaWtlKCBvYmogKSB7XG5cblx0Ly8gU3VwcG9ydDogcmVhbCBpT1MgOC4yIG9ubHkgKG5vdCByZXByb2R1Y2libGUgaW4gc2ltdWxhdG9yKVxuXHQvLyBgaW5gIGNoZWNrIHVzZWQgdG8gcHJldmVudCBKSVQgZXJyb3IgKGdoLTIxNDUpXG5cdC8vIGhhc093biBpc24ndCB1c2VkIGhlcmUgZHVlIHRvIGZhbHNlIG5lZ2F0aXZlc1xuXHQvLyByZWdhcmRpbmcgTm9kZWxpc3QgbGVuZ3RoIGluIElFXG5cdHZhciBsZW5ndGggPSAhIW9iaiAmJiBcImxlbmd0aFwiIGluIG9iaiAmJiBvYmoubGVuZ3RoLFxuXHRcdHR5cGUgPSBqUXVlcnkudHlwZSggb2JqICk7XG5cblx0aWYgKCB0eXBlID09PSBcImZ1bmN0aW9uXCIgfHwgalF1ZXJ5LmlzV2luZG93KCBvYmogKSApIHtcblx0XHRyZXR1cm4gZmFsc2U7XG5cdH1cblxuXHRyZXR1cm4gdHlwZSA9PT0gXCJhcnJheVwiIHx8IGxlbmd0aCA9PT0gMCB8fFxuXHRcdHR5cGVvZiBsZW5ndGggPT09IFwibnVtYmVyXCIgJiYgbGVuZ3RoID4gMCAmJiAoIGxlbmd0aCAtIDEgKSBpbiBvYmo7XG59XG52YXIgU2l6emxlID1cbi8qIVxuICogU2l6emxlIENTUyBTZWxlY3RvciBFbmdpbmUgdjIuMy4zXG4gKiBodHRwczovL3NpenpsZWpzLmNvbS9cbiAqXG4gKiBDb3B5cmlnaHQgalF1ZXJ5IEZvdW5kYXRpb24gYW5kIG90aGVyIGNvbnRyaWJ1dG9yc1xuICogUmVsZWFzZWQgdW5kZXIgdGhlIE1JVCBsaWNlbnNlXG4gKiBodHRwOi8vanF1ZXJ5Lm9yZy9saWNlbnNlXG4gKlxuICogRGF0ZTogMjAxNi0wOC0wOFxuICovXG4oZnVuY3Rpb24oIHdpbmRvdyApIHtcblxudmFyIGksXG5cdHN1cHBvcnQsXG5cdEV4cHIsXG5cdGdldFRleHQsXG5cdGlzWE1MLFxuXHR0b2tlbml6ZSxcblx0Y29tcGlsZSxcblx0c2VsZWN0LFxuXHRvdXRlcm1vc3RDb250ZXh0LFxuXHRzb3J0SW5wdXQsXG5cdGhhc0R1cGxpY2F0ZSxcblxuXHQvLyBMb2NhbCBkb2N1bWVudCB2YXJzXG5cdHNldERvY3VtZW50LFxuXHRkb2N1bWVudCxcblx0ZG9jRWxlbSxcblx0ZG9jdW1lbnRJc0hUTUwsXG5cdHJidWdneVFTQSxcblx0cmJ1Z2d5TWF0Y2hlcyxcblx0bWF0Y2hlcyxcblx0Y29udGFpbnMsXG5cblx0Ly8gSW5zdGFuY2Utc3BlY2lmaWMgZGF0YVxuXHRleHBhbmRvID0gXCJzaXp6bGVcIiArIDEgKiBuZXcgRGF0ZSgpLFxuXHRwcmVmZXJyZWREb2MgPSB3aW5kb3cuZG9jdW1lbnQsXG5cdGRpcnJ1bnMgPSAwLFxuXHRkb25lID0gMCxcblx0Y2xhc3NDYWNoZSA9IGNyZWF0ZUNhY2hlKCksXG5cdHRva2VuQ2FjaGUgPSBjcmVhdGVDYWNoZSgpLFxuXHRjb21waWxlckNhY2hlID0gY3JlYXRlQ2FjaGUoKSxcblx0c29ydE9yZGVyID0gZnVuY3Rpb24oIGEsIGIgKSB7XG5cdFx0aWYgKCBhID09PSBiICkge1xuXHRcdFx0aGFzRHVwbGljYXRlID0gdHJ1ZTtcblx0XHR9XG5cdFx0cmV0dXJuIDA7XG5cdH0sXG5cblx0Ly8gSW5zdGFuY2UgbWV0aG9kc1xuXHRoYXNPd24gPSAoe30pLmhhc093blByb3BlcnR5LFxuXHRhcnIgPSBbXSxcblx0cG9wID0gYXJyLnBvcCxcblx0cHVzaF9uYXRpdmUgPSBhcnIucHVzaCxcblx0cHVzaCA9IGFyci5wdXNoLFxuXHRzbGljZSA9IGFyci5zbGljZSxcblx0Ly8gVXNlIGEgc3RyaXBwZWQtZG93biBpbmRleE9mIGFzIGl0J3MgZmFzdGVyIHRoYW4gbmF0aXZlXG5cdC8vIGh0dHBzOi8vanNwZXJmLmNvbS90aG9yLWluZGV4b2YtdnMtZm9yLzVcblx0aW5kZXhPZiA9IGZ1bmN0aW9uKCBsaXN0LCBlbGVtICkge1xuXHRcdHZhciBpID0gMCxcblx0XHRcdGxlbiA9IGxpc3QubGVuZ3RoO1xuXHRcdGZvciAoIDsgaSA8IGxlbjsgaSsrICkge1xuXHRcdFx0aWYgKCBsaXN0W2ldID09PSBlbGVtICkge1xuXHRcdFx0XHRyZXR1cm4gaTtcblx0XHRcdH1cblx0XHR9XG5cdFx0cmV0dXJuIC0xO1xuXHR9LFxuXG5cdGJvb2xlYW5zID0gXCJjaGVja2VkfHNlbGVjdGVkfGFzeW5jfGF1dG9mb2N1c3xhdXRvcGxheXxjb250cm9sc3xkZWZlcnxkaXNhYmxlZHxoaWRkZW58aXNtYXB8bG9vcHxtdWx0aXBsZXxvcGVufHJlYWRvbmx5fHJlcXVpcmVkfHNjb3BlZFwiLFxuXG5cdC8vIFJlZ3VsYXIgZXhwcmVzc2lvbnNcblxuXHQvLyBodHRwOi8vd3d3LnczLm9yZy9UUi9jc3MzLXNlbGVjdG9ycy8jd2hpdGVzcGFjZVxuXHR3aGl0ZXNwYWNlID0gXCJbXFxcXHgyMFxcXFx0XFxcXHJcXFxcblxcXFxmXVwiLFxuXG5cdC8vIGh0dHA6Ly93d3cudzMub3JnL1RSL0NTUzIxL3N5bmRhdGEuaHRtbCN2YWx1ZS1kZWYtaWRlbnRpZmllclxuXHRpZGVudGlmaWVyID0gXCIoPzpcXFxcXFxcXC58W1xcXFx3LV18W15cXDAtXFxcXHhhMF0pK1wiLFxuXG5cdC8vIEF0dHJpYnV0ZSBzZWxlY3RvcnM6IGh0dHA6Ly93d3cudzMub3JnL1RSL3NlbGVjdG9ycy8jYXR0cmlidXRlLXNlbGVjdG9yc1xuXHRhdHRyaWJ1dGVzID0gXCJcXFxcW1wiICsgd2hpdGVzcGFjZSArIFwiKihcIiArIGlkZW50aWZpZXIgKyBcIikoPzpcIiArIHdoaXRlc3BhY2UgK1xuXHRcdC8vIE9wZXJhdG9yIChjYXB0dXJlIDIpXG5cdFx0XCIqKFsqXiR8IX5dPz0pXCIgKyB3aGl0ZXNwYWNlICtcblx0XHQvLyBcIkF0dHJpYnV0ZSB2YWx1ZXMgbXVzdCBiZSBDU1MgaWRlbnRpZmllcnMgW2NhcHR1cmUgNV0gb3Igc3RyaW5ncyBbY2FwdHVyZSAzIG9yIGNhcHR1cmUgNF1cIlxuXHRcdFwiKig/OicoKD86XFxcXFxcXFwufFteXFxcXFxcXFwnXSkqKSd8XFxcIigoPzpcXFxcXFxcXC58W15cXFxcXFxcXFxcXCJdKSopXFxcInwoXCIgKyBpZGVudGlmaWVyICsgXCIpKXwpXCIgKyB3aGl0ZXNwYWNlICtcblx0XHRcIipcXFxcXVwiLFxuXG5cdHBzZXVkb3MgPSBcIjooXCIgKyBpZGVudGlmaWVyICsgXCIpKD86XFxcXCgoXCIgK1xuXHRcdC8vIFRvIHJlZHVjZSB0aGUgbnVtYmVyIG9mIHNlbGVjdG9ycyBuZWVkaW5nIHRva2VuaXplIGluIHRoZSBwcmVGaWx0ZXIsIHByZWZlciBhcmd1bWVudHM6XG5cdFx0Ly8gMS4gcXVvdGVkIChjYXB0dXJlIDM7IGNhcHR1cmUgNCBvciBjYXB0dXJlIDUpXG5cdFx0XCIoJygoPzpcXFxcXFxcXC58W15cXFxcXFxcXCddKSopJ3xcXFwiKCg/OlxcXFxcXFxcLnxbXlxcXFxcXFxcXFxcIl0pKilcXFwiKXxcIiArXG5cdFx0Ly8gMi4gc2ltcGxlIChjYXB0dXJlIDYpXG5cdFx0XCIoKD86XFxcXFxcXFwufFteXFxcXFxcXFwoKVtcXFxcXV18XCIgKyBhdHRyaWJ1dGVzICsgXCIpKil8XCIgK1xuXHRcdC8vIDMuIGFueXRoaW5nIGVsc2UgKGNhcHR1cmUgMilcblx0XHRcIi4qXCIgK1xuXHRcdFwiKVxcXFwpfClcIixcblxuXHQvLyBMZWFkaW5nIGFuZCBub24tZXNjYXBlZCB0cmFpbGluZyB3aGl0ZXNwYWNlLCBjYXB0dXJpbmcgc29tZSBub24td2hpdGVzcGFjZSBjaGFyYWN0ZXJzIHByZWNlZGluZyB0aGUgbGF0dGVyXG5cdHJ3aGl0ZXNwYWNlID0gbmV3IFJlZ0V4cCggd2hpdGVzcGFjZSArIFwiK1wiLCBcImdcIiApLFxuXHRydHJpbSA9IG5ldyBSZWdFeHAoIFwiXlwiICsgd2hpdGVzcGFjZSArIFwiK3woKD86XnxbXlxcXFxcXFxcXSkoPzpcXFxcXFxcXC4pKilcIiArIHdoaXRlc3BhY2UgKyBcIiskXCIsIFwiZ1wiICksXG5cblx0cmNvbW1hID0gbmV3IFJlZ0V4cCggXCJeXCIgKyB3aGl0ZXNwYWNlICsgXCIqLFwiICsgd2hpdGVzcGFjZSArIFwiKlwiICksXG5cdHJjb21iaW5hdG9ycyA9IG5ldyBSZWdFeHAoIFwiXlwiICsgd2hpdGVzcGFjZSArIFwiKihbPit+XXxcIiArIHdoaXRlc3BhY2UgKyBcIilcIiArIHdoaXRlc3BhY2UgKyBcIipcIiApLFxuXG5cdHJhdHRyaWJ1dGVRdW90ZXMgPSBuZXcgUmVnRXhwKCBcIj1cIiArIHdoaXRlc3BhY2UgKyBcIiooW15cXFxcXSdcXFwiXSo/KVwiICsgd2hpdGVzcGFjZSArIFwiKlxcXFxdXCIsIFwiZ1wiICksXG5cblx0cnBzZXVkbyA9IG5ldyBSZWdFeHAoIHBzZXVkb3MgKSxcblx0cmlkZW50aWZpZXIgPSBuZXcgUmVnRXhwKCBcIl5cIiArIGlkZW50aWZpZXIgKyBcIiRcIiApLFxuXG5cdG1hdGNoRXhwciA9IHtcblx0XHRcIklEXCI6IG5ldyBSZWdFeHAoIFwiXiMoXCIgKyBpZGVudGlmaWVyICsgXCIpXCIgKSxcblx0XHRcIkNMQVNTXCI6IG5ldyBSZWdFeHAoIFwiXlxcXFwuKFwiICsgaWRlbnRpZmllciArIFwiKVwiICksXG5cdFx0XCJUQUdcIjogbmV3IFJlZ0V4cCggXCJeKFwiICsgaWRlbnRpZmllciArIFwifFsqXSlcIiApLFxuXHRcdFwiQVRUUlwiOiBuZXcgUmVnRXhwKCBcIl5cIiArIGF0dHJpYnV0ZXMgKSxcblx0XHRcIlBTRVVET1wiOiBuZXcgUmVnRXhwKCBcIl5cIiArIHBzZXVkb3MgKSxcblx0XHRcIkNISUxEXCI6IG5ldyBSZWdFeHAoIFwiXjoob25seXxmaXJzdHxsYXN0fG50aHxudGgtbGFzdCktKGNoaWxkfG9mLXR5cGUpKD86XFxcXChcIiArIHdoaXRlc3BhY2UgK1xuXHRcdFx0XCIqKGV2ZW58b2RkfCgoWystXXwpKFxcXFxkKilufClcIiArIHdoaXRlc3BhY2UgKyBcIiooPzooWystXXwpXCIgKyB3aGl0ZXNwYWNlICtcblx0XHRcdFwiKihcXFxcZCspfCkpXCIgKyB3aGl0ZXNwYWNlICsgXCIqXFxcXCl8KVwiLCBcImlcIiApLFxuXHRcdFwiYm9vbFwiOiBuZXcgUmVnRXhwKCBcIl4oPzpcIiArIGJvb2xlYW5zICsgXCIpJFwiLCBcImlcIiApLFxuXHRcdC8vIEZvciB1c2UgaW4gbGlicmFyaWVzIGltcGxlbWVudGluZyAuaXMoKVxuXHRcdC8vIFdlIHVzZSB0aGlzIGZvciBQT1MgbWF0Y2hpbmcgaW4gYHNlbGVjdGBcblx0XHRcIm5lZWRzQ29udGV4dFwiOiBuZXcgUmVnRXhwKCBcIl5cIiArIHdoaXRlc3BhY2UgKyBcIipbPit+XXw6KGV2ZW58b2RkfGVxfGd0fGx0fG50aHxmaXJzdHxsYXN0KSg/OlxcXFwoXCIgK1xuXHRcdFx0d2hpdGVzcGFjZSArIFwiKigoPzotXFxcXGQpP1xcXFxkKilcIiArIHdoaXRlc3BhY2UgKyBcIipcXFxcKXwpKD89W14tXXwkKVwiLCBcImlcIiApXG5cdH0sXG5cblx0cmlucHV0cyA9IC9eKD86aW5wdXR8c2VsZWN0fHRleHRhcmVhfGJ1dHRvbikkL2ksXG5cdHJoZWFkZXIgPSAvXmhcXGQkL2ksXG5cblx0cm5hdGl2ZSA9IC9eW157XStcXHtcXHMqXFxbbmF0aXZlIFxcdy8sXG5cblx0Ly8gRWFzaWx5LXBhcnNlYWJsZS9yZXRyaWV2YWJsZSBJRCBvciBUQUcgb3IgQ0xBU1Mgc2VsZWN0b3JzXG5cdHJxdWlja0V4cHIgPSAvXig/OiMoW1xcdy1dKyl8KFxcdyspfFxcLihbXFx3LV0rKSkkLyxcblxuXHRyc2libGluZyA9IC9bK35dLyxcblxuXHQvLyBDU1MgZXNjYXBlc1xuXHQvLyBodHRwOi8vd3d3LnczLm9yZy9UUi9DU1MyMS9zeW5kYXRhLmh0bWwjZXNjYXBlZC1jaGFyYWN0ZXJzXG5cdHJ1bmVzY2FwZSA9IG5ldyBSZWdFeHAoIFwiXFxcXFxcXFwoW1xcXFxkYS1mXXsxLDZ9XCIgKyB3aGl0ZXNwYWNlICsgXCI/fChcIiArIHdoaXRlc3BhY2UgKyBcIil8LilcIiwgXCJpZ1wiICksXG5cdGZ1bmVzY2FwZSA9IGZ1bmN0aW9uKCBfLCBlc2NhcGVkLCBlc2NhcGVkV2hpdGVzcGFjZSApIHtcblx0XHR2YXIgaGlnaCA9IFwiMHhcIiArIGVzY2FwZWQgLSAweDEwMDAwO1xuXHRcdC8vIE5hTiBtZWFucyBub24tY29kZXBvaW50XG5cdFx0Ly8gU3VwcG9ydDogRmlyZWZveDwyNFxuXHRcdC8vIFdvcmthcm91bmQgZXJyb25lb3VzIG51bWVyaWMgaW50ZXJwcmV0YXRpb24gb2YgK1wiMHhcIlxuXHRcdHJldHVybiBoaWdoICE9PSBoaWdoIHx8IGVzY2FwZWRXaGl0ZXNwYWNlID9cblx0XHRcdGVzY2FwZWQgOlxuXHRcdFx0aGlnaCA8IDAgP1xuXHRcdFx0XHQvLyBCTVAgY29kZXBvaW50XG5cdFx0XHRcdFN0cmluZy5mcm9tQ2hhckNvZGUoIGhpZ2ggKyAweDEwMDAwICkgOlxuXHRcdFx0XHQvLyBTdXBwbGVtZW50YWwgUGxhbmUgY29kZXBvaW50IChzdXJyb2dhdGUgcGFpcilcblx0XHRcdFx0U3RyaW5nLmZyb21DaGFyQ29kZSggaGlnaCA+PiAxMCB8IDB4RDgwMCwgaGlnaCAmIDB4M0ZGIHwgMHhEQzAwICk7XG5cdH0sXG5cblx0Ly8gQ1NTIHN0cmluZy9pZGVudGlmaWVyIHNlcmlhbGl6YXRpb25cblx0Ly8gaHR0cHM6Ly9kcmFmdHMuY3Nzd2cub3JnL2Nzc29tLyNjb21tb24tc2VyaWFsaXppbmctaWRpb21zXG5cdHJjc3Nlc2NhcGUgPSAvKFtcXDAtXFx4MWZcXHg3Zl18Xi0/XFxkKXxeLSR8W15cXDAtXFx4MWZcXHg3Zi1cXHVGRkZGXFx3LV0vZyxcblx0ZmNzc2VzY2FwZSA9IGZ1bmN0aW9uKCBjaCwgYXNDb2RlUG9pbnQgKSB7XG5cdFx0aWYgKCBhc0NvZGVQb2ludCApIHtcblxuXHRcdFx0Ly8gVSswMDAwIE5VTEwgYmVjb21lcyBVK0ZGRkQgUkVQTEFDRU1FTlQgQ0hBUkFDVEVSXG5cdFx0XHRpZiAoIGNoID09PSBcIlxcMFwiICkge1xuXHRcdFx0XHRyZXR1cm4gXCJcXHVGRkZEXCI7XG5cdFx0XHR9XG5cblx0XHRcdC8vIENvbnRyb2wgY2hhcmFjdGVycyBhbmQgKGRlcGVuZGVudCB1cG9uIHBvc2l0aW9uKSBudW1iZXJzIGdldCBlc2NhcGVkIGFzIGNvZGUgcG9pbnRzXG5cdFx0XHRyZXR1cm4gY2guc2xpY2UoIDAsIC0xICkgKyBcIlxcXFxcIiArIGNoLmNoYXJDb2RlQXQoIGNoLmxlbmd0aCAtIDEgKS50b1N0cmluZyggMTYgKSArIFwiIFwiO1xuXHRcdH1cblxuXHRcdC8vIE90aGVyIHBvdGVudGlhbGx5LXNwZWNpYWwgQVNDSUkgY2hhcmFjdGVycyBnZXQgYmFja3NsYXNoLWVzY2FwZWRcblx0XHRyZXR1cm4gXCJcXFxcXCIgKyBjaDtcblx0fSxcblxuXHQvLyBVc2VkIGZvciBpZnJhbWVzXG5cdC8vIFNlZSBzZXREb2N1bWVudCgpXG5cdC8vIFJlbW92aW5nIHRoZSBmdW5jdGlvbiB3cmFwcGVyIGNhdXNlcyBhIFwiUGVybWlzc2lvbiBEZW5pZWRcIlxuXHQvLyBlcnJvciBpbiBJRVxuXHR1bmxvYWRIYW5kbGVyID0gZnVuY3Rpb24oKSB7XG5cdFx0c2V0RG9jdW1lbnQoKTtcblx0fSxcblxuXHRkaXNhYmxlZEFuY2VzdG9yID0gYWRkQ29tYmluYXRvcihcblx0XHRmdW5jdGlvbiggZWxlbSApIHtcblx0XHRcdHJldHVybiBlbGVtLmRpc2FibGVkID09PSB0cnVlICYmIChcImZvcm1cIiBpbiBlbGVtIHx8IFwibGFiZWxcIiBpbiBlbGVtKTtcblx0XHR9LFxuXHRcdHsgZGlyOiBcInBhcmVudE5vZGVcIiwgbmV4dDogXCJsZWdlbmRcIiB9XG5cdCk7XG5cbi8vIE9wdGltaXplIGZvciBwdXNoLmFwcGx5KCBfLCBOb2RlTGlzdCApXG50cnkge1xuXHRwdXNoLmFwcGx5KFxuXHRcdChhcnIgPSBzbGljZS5jYWxsKCBwcmVmZXJyZWREb2MuY2hpbGROb2RlcyApKSxcblx0XHRwcmVmZXJyZWREb2MuY2hpbGROb2Rlc1xuXHQpO1xuXHQvLyBTdXBwb3J0OiBBbmRyb2lkPDQuMFxuXHQvLyBEZXRlY3Qgc2lsZW50bHkgZmFpbGluZyBwdXNoLmFwcGx5XG5cdGFyclsgcHJlZmVycmVkRG9jLmNoaWxkTm9kZXMubGVuZ3RoIF0ubm9kZVR5cGU7XG59IGNhdGNoICggZSApIHtcblx0cHVzaCA9IHsgYXBwbHk6IGFyci5sZW5ndGggP1xuXG5cdFx0Ly8gTGV2ZXJhZ2Ugc2xpY2UgaWYgcG9zc2libGVcblx0XHRmdW5jdGlvbiggdGFyZ2V0LCBlbHMgKSB7XG5cdFx0XHRwdXNoX25hdGl2ZS5hcHBseSggdGFyZ2V0LCBzbGljZS5jYWxsKGVscykgKTtcblx0XHR9IDpcblxuXHRcdC8vIFN1cHBvcnQ6IElFPDlcblx0XHQvLyBPdGhlcndpc2UgYXBwZW5kIGRpcmVjdGx5XG5cdFx0ZnVuY3Rpb24oIHRhcmdldCwgZWxzICkge1xuXHRcdFx0dmFyIGogPSB0YXJnZXQubGVuZ3RoLFxuXHRcdFx0XHRpID0gMDtcblx0XHRcdC8vIENhbid0IHRydXN0IE5vZGVMaXN0Lmxlbmd0aFxuXHRcdFx0d2hpbGUgKCAodGFyZ2V0W2orK10gPSBlbHNbaSsrXSkgKSB7fVxuXHRcdFx0dGFyZ2V0Lmxlbmd0aCA9IGogLSAxO1xuXHRcdH1cblx0fTtcbn1cblxuZnVuY3Rpb24gU2l6emxlKCBzZWxlY3RvciwgY29udGV4dCwgcmVzdWx0cywgc2VlZCApIHtcblx0dmFyIG0sIGksIGVsZW0sIG5pZCwgbWF0Y2gsIGdyb3VwcywgbmV3U2VsZWN0b3IsXG5cdFx0bmV3Q29udGV4dCA9IGNvbnRleHQgJiYgY29udGV4dC5vd25lckRvY3VtZW50LFxuXG5cdFx0Ly8gbm9kZVR5cGUgZGVmYXVsdHMgdG8gOSwgc2luY2UgY29udGV4dCBkZWZhdWx0cyB0byBkb2N1bWVudFxuXHRcdG5vZGVUeXBlID0gY29udGV4dCA/IGNvbnRleHQubm9kZVR5cGUgOiA5O1xuXG5cdHJlc3VsdHMgPSByZXN1bHRzIHx8IFtdO1xuXG5cdC8vIFJldHVybiBlYXJseSBmcm9tIGNhbGxzIHdpdGggaW52YWxpZCBzZWxlY3RvciBvciBjb250ZXh0XG5cdGlmICggdHlwZW9mIHNlbGVjdG9yICE9PSBcInN0cmluZ1wiIHx8ICFzZWxlY3RvciB8fFxuXHRcdG5vZGVUeXBlICE9PSAxICYmIG5vZGVUeXBlICE9PSA5ICYmIG5vZGVUeXBlICE9PSAxMSApIHtcblxuXHRcdHJldHVybiByZXN1bHRzO1xuXHR9XG5cblx0Ly8gVHJ5IHRvIHNob3J0Y3V0IGZpbmQgb3BlcmF0aW9ucyAoYXMgb3Bwb3NlZCB0byBmaWx0ZXJzKSBpbiBIVE1MIGRvY3VtZW50c1xuXHRpZiAoICFzZWVkICkge1xuXG5cdFx0aWYgKCAoIGNvbnRleHQgPyBjb250ZXh0Lm93bmVyRG9jdW1lbnQgfHwgY29udGV4dCA6IHByZWZlcnJlZERvYyApICE9PSBkb2N1bWVudCApIHtcblx0XHRcdHNldERvY3VtZW50KCBjb250ZXh0ICk7XG5cdFx0fVxuXHRcdGNvbnRleHQgPSBjb250ZXh0IHx8IGRvY3VtZW50O1xuXG5cdFx0aWYgKCBkb2N1bWVudElzSFRNTCApIHtcblxuXHRcdFx0Ly8gSWYgdGhlIHNlbGVjdG9yIGlzIHN1ZmZpY2llbnRseSBzaW1wbGUsIHRyeSB1c2luZyBhIFwiZ2V0KkJ5KlwiIERPTSBtZXRob2Rcblx0XHRcdC8vIChleGNlcHRpbmcgRG9jdW1lbnRGcmFnbWVudCBjb250ZXh0LCB3aGVyZSB0aGUgbWV0aG9kcyBkb24ndCBleGlzdClcblx0XHRcdGlmICggbm9kZVR5cGUgIT09IDExICYmIChtYXRjaCA9IHJxdWlja0V4cHIuZXhlYyggc2VsZWN0b3IgKSkgKSB7XG5cblx0XHRcdFx0Ly8gSUQgc2VsZWN0b3Jcblx0XHRcdFx0aWYgKCAobSA9IG1hdGNoWzFdKSApIHtcblxuXHRcdFx0XHRcdC8vIERvY3VtZW50IGNvbnRleHRcblx0XHRcdFx0XHRpZiAoIG5vZGVUeXBlID09PSA5ICkge1xuXHRcdFx0XHRcdFx0aWYgKCAoZWxlbSA9IGNvbnRleHQuZ2V0RWxlbWVudEJ5SWQoIG0gKSkgKSB7XG5cblx0XHRcdFx0XHRcdFx0Ly8gU3VwcG9ydDogSUUsIE9wZXJhLCBXZWJraXRcblx0XHRcdFx0XHRcdFx0Ly8gVE9ETzogaWRlbnRpZnkgdmVyc2lvbnNcblx0XHRcdFx0XHRcdFx0Ly8gZ2V0RWxlbWVudEJ5SWQgY2FuIG1hdGNoIGVsZW1lbnRzIGJ5IG5hbWUgaW5zdGVhZCBvZiBJRFxuXHRcdFx0XHRcdFx0XHRpZiAoIGVsZW0uaWQgPT09IG0gKSB7XG5cdFx0XHRcdFx0XHRcdFx0cmVzdWx0cy5wdXNoKCBlbGVtICk7XG5cdFx0XHRcdFx0XHRcdFx0cmV0dXJuIHJlc3VsdHM7XG5cdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0XHRcdHJldHVybiByZXN1bHRzO1xuXHRcdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0Ly8gRWxlbWVudCBjb250ZXh0XG5cdFx0XHRcdFx0fSBlbHNlIHtcblxuXHRcdFx0XHRcdFx0Ly8gU3VwcG9ydDogSUUsIE9wZXJhLCBXZWJraXRcblx0XHRcdFx0XHRcdC8vIFRPRE86IGlkZW50aWZ5IHZlcnNpb25zXG5cdFx0XHRcdFx0XHQvLyBnZXRFbGVtZW50QnlJZCBjYW4gbWF0Y2ggZWxlbWVudHMgYnkgbmFtZSBpbnN0ZWFkIG9mIElEXG5cdFx0XHRcdFx0XHRpZiAoIG5ld0NvbnRleHQgJiYgKGVsZW0gPSBuZXdDb250ZXh0LmdldEVsZW1lbnRCeUlkKCBtICkpICYmXG5cdFx0XHRcdFx0XHRcdGNvbnRhaW5zKCBjb250ZXh0LCBlbGVtICkgJiZcblx0XHRcdFx0XHRcdFx0ZWxlbS5pZCA9PT0gbSApIHtcblxuXHRcdFx0XHRcdFx0XHRyZXN1bHRzLnB1c2goIGVsZW0gKTtcblx0XHRcdFx0XHRcdFx0cmV0dXJuIHJlc3VsdHM7XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0fVxuXG5cdFx0XHRcdC8vIFR5cGUgc2VsZWN0b3Jcblx0XHRcdFx0fSBlbHNlIGlmICggbWF0Y2hbMl0gKSB7XG5cdFx0XHRcdFx0cHVzaC5hcHBseSggcmVzdWx0cywgY29udGV4dC5nZXRFbGVtZW50c0J5VGFnTmFtZSggc2VsZWN0b3IgKSApO1xuXHRcdFx0XHRcdHJldHVybiByZXN1bHRzO1xuXG5cdFx0XHRcdC8vIENsYXNzIHNlbGVjdG9yXG5cdFx0XHRcdH0gZWxzZSBpZiAoIChtID0gbWF0Y2hbM10pICYmIHN1cHBvcnQuZ2V0RWxlbWVudHNCeUNsYXNzTmFtZSAmJlxuXHRcdFx0XHRcdGNvbnRleHQuZ2V0RWxlbWVudHNCeUNsYXNzTmFtZSApIHtcblxuXHRcdFx0XHRcdHB1c2guYXBwbHkoIHJlc3VsdHMsIGNvbnRleHQuZ2V0RWxlbWVudHNCeUNsYXNzTmFtZSggbSApICk7XG5cdFx0XHRcdFx0cmV0dXJuIHJlc3VsdHM7XG5cdFx0XHRcdH1cblx0XHRcdH1cblxuXHRcdFx0Ly8gVGFrZSBhZHZhbnRhZ2Ugb2YgcXVlcnlTZWxlY3RvckFsbFxuXHRcdFx0aWYgKCBzdXBwb3J0LnFzYSAmJlxuXHRcdFx0XHQhY29tcGlsZXJDYWNoZVsgc2VsZWN0b3IgKyBcIiBcIiBdICYmXG5cdFx0XHRcdCghcmJ1Z2d5UVNBIHx8ICFyYnVnZ3lRU0EudGVzdCggc2VsZWN0b3IgKSkgKSB7XG5cblx0XHRcdFx0aWYgKCBub2RlVHlwZSAhPT0gMSApIHtcblx0XHRcdFx0XHRuZXdDb250ZXh0ID0gY29udGV4dDtcblx0XHRcdFx0XHRuZXdTZWxlY3RvciA9IHNlbGVjdG9yO1xuXG5cdFx0XHRcdC8vIHFTQSBsb29rcyBvdXRzaWRlIEVsZW1lbnQgY29udGV4dCwgd2hpY2ggaXMgbm90IHdoYXQgd2Ugd2FudFxuXHRcdFx0XHQvLyBUaGFua3MgdG8gQW5kcmV3IER1cG9udCBmb3IgdGhpcyB3b3JrYXJvdW5kIHRlY2huaXF1ZVxuXHRcdFx0XHQvLyBTdXBwb3J0OiBJRSA8PThcblx0XHRcdFx0Ly8gRXhjbHVkZSBvYmplY3QgZWxlbWVudHNcblx0XHRcdFx0fSBlbHNlIGlmICggY29udGV4dC5ub2RlTmFtZS50b0xvd2VyQ2FzZSgpICE9PSBcIm9iamVjdFwiICkge1xuXG5cdFx0XHRcdFx0Ly8gQ2FwdHVyZSB0aGUgY29udGV4dCBJRCwgc2V0dGluZyBpdCBmaXJzdCBpZiBuZWNlc3Nhcnlcblx0XHRcdFx0XHRpZiAoIChuaWQgPSBjb250ZXh0LmdldEF0dHJpYnV0ZSggXCJpZFwiICkpICkge1xuXHRcdFx0XHRcdFx0bmlkID0gbmlkLnJlcGxhY2UoIHJjc3Nlc2NhcGUsIGZjc3Nlc2NhcGUgKTtcblx0XHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdFx0Y29udGV4dC5zZXRBdHRyaWJ1dGUoIFwiaWRcIiwgKG5pZCA9IGV4cGFuZG8pICk7XG5cdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0Ly8gUHJlZml4IGV2ZXJ5IHNlbGVjdG9yIGluIHRoZSBsaXN0XG5cdFx0XHRcdFx0Z3JvdXBzID0gdG9rZW5pemUoIHNlbGVjdG9yICk7XG5cdFx0XHRcdFx0aSA9IGdyb3Vwcy5sZW5ndGg7XG5cdFx0XHRcdFx0d2hpbGUgKCBpLS0gKSB7XG5cdFx0XHRcdFx0XHRncm91cHNbaV0gPSBcIiNcIiArIG5pZCArIFwiIFwiICsgdG9TZWxlY3RvciggZ3JvdXBzW2ldICk7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHRcdG5ld1NlbGVjdG9yID0gZ3JvdXBzLmpvaW4oIFwiLFwiICk7XG5cblx0XHRcdFx0XHQvLyBFeHBhbmQgY29udGV4dCBmb3Igc2libGluZyBzZWxlY3RvcnNcblx0XHRcdFx0XHRuZXdDb250ZXh0ID0gcnNpYmxpbmcudGVzdCggc2VsZWN0b3IgKSAmJiB0ZXN0Q29udGV4dCggY29udGV4dC5wYXJlbnROb2RlICkgfHxcblx0XHRcdFx0XHRcdGNvbnRleHQ7XG5cdFx0XHRcdH1cblxuXHRcdFx0XHRpZiAoIG5ld1NlbGVjdG9yICkge1xuXHRcdFx0XHRcdHRyeSB7XG5cdFx0XHRcdFx0XHRwdXNoLmFwcGx5KCByZXN1bHRzLFxuXHRcdFx0XHRcdFx0XHRuZXdDb250ZXh0LnF1ZXJ5U2VsZWN0b3JBbGwoIG5ld1NlbGVjdG9yIClcblx0XHRcdFx0XHRcdCk7XG5cdFx0XHRcdFx0XHRyZXR1cm4gcmVzdWx0cztcblx0XHRcdFx0XHR9IGNhdGNoICggcXNhRXJyb3IgKSB7XG5cdFx0XHRcdFx0fSBmaW5hbGx5IHtcblx0XHRcdFx0XHRcdGlmICggbmlkID09PSBleHBhbmRvICkge1xuXHRcdFx0XHRcdFx0XHRjb250ZXh0LnJlbW92ZUF0dHJpYnV0ZSggXCJpZFwiICk7XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fVxuXHR9XG5cblx0Ly8gQWxsIG90aGVyc1xuXHRyZXR1cm4gc2VsZWN0KCBzZWxlY3Rvci5yZXBsYWNlKCBydHJpbSwgXCIkMVwiICksIGNvbnRleHQsIHJlc3VsdHMsIHNlZWQgKTtcbn1cblxuLyoqXG4gKiBDcmVhdGUga2V5LXZhbHVlIGNhY2hlcyBvZiBsaW1pdGVkIHNpemVcbiAqIEByZXR1cm5zIHtmdW5jdGlvbihzdHJpbmcsIG9iamVjdCl9IFJldHVybnMgdGhlIE9iamVjdCBkYXRhIGFmdGVyIHN0b3JpbmcgaXQgb24gaXRzZWxmIHdpdGhcbiAqXHRwcm9wZXJ0eSBuYW1lIHRoZSAoc3BhY2Utc3VmZml4ZWQpIHN0cmluZyBhbmQgKGlmIHRoZSBjYWNoZSBpcyBsYXJnZXIgdGhhbiBFeHByLmNhY2hlTGVuZ3RoKVxuICpcdGRlbGV0aW5nIHRoZSBvbGRlc3QgZW50cnlcbiAqL1xuZnVuY3Rpb24gY3JlYXRlQ2FjaGUoKSB7XG5cdHZhciBrZXlzID0gW107XG5cblx0ZnVuY3Rpb24gY2FjaGUoIGtleSwgdmFsdWUgKSB7XG5cdFx0Ly8gVXNlIChrZXkgKyBcIiBcIikgdG8gYXZvaWQgY29sbGlzaW9uIHdpdGggbmF0aXZlIHByb3RvdHlwZSBwcm9wZXJ0aWVzIChzZWUgSXNzdWUgIzE1Nylcblx0XHRpZiAoIGtleXMucHVzaCgga2V5ICsgXCIgXCIgKSA+IEV4cHIuY2FjaGVMZW5ndGggKSB7XG5cdFx0XHQvLyBPbmx5IGtlZXAgdGhlIG1vc3QgcmVjZW50IGVudHJpZXNcblx0XHRcdGRlbGV0ZSBjYWNoZVsga2V5cy5zaGlmdCgpIF07XG5cdFx0fVxuXHRcdHJldHVybiAoY2FjaGVbIGtleSArIFwiIFwiIF0gPSB2YWx1ZSk7XG5cdH1cblx0cmV0dXJuIGNhY2hlO1xufVxuXG4vKipcbiAqIE1hcmsgYSBmdW5jdGlvbiBmb3Igc3BlY2lhbCB1c2UgYnkgU2l6emxlXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBmbiBUaGUgZnVuY3Rpb24gdG8gbWFya1xuICovXG5mdW5jdGlvbiBtYXJrRnVuY3Rpb24oIGZuICkge1xuXHRmblsgZXhwYW5kbyBdID0gdHJ1ZTtcblx0cmV0dXJuIGZuO1xufVxuXG4vKipcbiAqIFN1cHBvcnQgdGVzdGluZyB1c2luZyBhbiBlbGVtZW50XG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBmbiBQYXNzZWQgdGhlIGNyZWF0ZWQgZWxlbWVudCBhbmQgcmV0dXJucyBhIGJvb2xlYW4gcmVzdWx0XG4gKi9cbmZ1bmN0aW9uIGFzc2VydCggZm4gKSB7XG5cdHZhciBlbCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJmaWVsZHNldFwiKTtcblxuXHR0cnkge1xuXHRcdHJldHVybiAhIWZuKCBlbCApO1xuXHR9IGNhdGNoIChlKSB7XG5cdFx0cmV0dXJuIGZhbHNlO1xuXHR9IGZpbmFsbHkge1xuXHRcdC8vIFJlbW92ZSBmcm9tIGl0cyBwYXJlbnQgYnkgZGVmYXVsdFxuXHRcdGlmICggZWwucGFyZW50Tm9kZSApIHtcblx0XHRcdGVsLnBhcmVudE5vZGUucmVtb3ZlQ2hpbGQoIGVsICk7XG5cdFx0fVxuXHRcdC8vIHJlbGVhc2UgbWVtb3J5IGluIElFXG5cdFx0ZWwgPSBudWxsO1xuXHR9XG59XG5cbi8qKlxuICogQWRkcyB0aGUgc2FtZSBoYW5kbGVyIGZvciBhbGwgb2YgdGhlIHNwZWNpZmllZCBhdHRyc1xuICogQHBhcmFtIHtTdHJpbmd9IGF0dHJzIFBpcGUtc2VwYXJhdGVkIGxpc3Qgb2YgYXR0cmlidXRlc1xuICogQHBhcmFtIHtGdW5jdGlvbn0gaGFuZGxlciBUaGUgbWV0aG9kIHRoYXQgd2lsbCBiZSBhcHBsaWVkXG4gKi9cbmZ1bmN0aW9uIGFkZEhhbmRsZSggYXR0cnMsIGhhbmRsZXIgKSB7XG5cdHZhciBhcnIgPSBhdHRycy5zcGxpdChcInxcIiksXG5cdFx0aSA9IGFyci5sZW5ndGg7XG5cblx0d2hpbGUgKCBpLS0gKSB7XG5cdFx0RXhwci5hdHRySGFuZGxlWyBhcnJbaV0gXSA9IGhhbmRsZXI7XG5cdH1cbn1cblxuLyoqXG4gKiBDaGVja3MgZG9jdW1lbnQgb3JkZXIgb2YgdHdvIHNpYmxpbmdzXG4gKiBAcGFyYW0ge0VsZW1lbnR9IGFcbiAqIEBwYXJhbSB7RWxlbWVudH0gYlxuICogQHJldHVybnMge051bWJlcn0gUmV0dXJucyBsZXNzIHRoYW4gMCBpZiBhIHByZWNlZGVzIGIsIGdyZWF0ZXIgdGhhbiAwIGlmIGEgZm9sbG93cyBiXG4gKi9cbmZ1bmN0aW9uIHNpYmxpbmdDaGVjayggYSwgYiApIHtcblx0dmFyIGN1ciA9IGIgJiYgYSxcblx0XHRkaWZmID0gY3VyICYmIGEubm9kZVR5cGUgPT09IDEgJiYgYi5ub2RlVHlwZSA9PT0gMSAmJlxuXHRcdFx0YS5zb3VyY2VJbmRleCAtIGIuc291cmNlSW5kZXg7XG5cblx0Ly8gVXNlIElFIHNvdXJjZUluZGV4IGlmIGF2YWlsYWJsZSBvbiBib3RoIG5vZGVzXG5cdGlmICggZGlmZiApIHtcblx0XHRyZXR1cm4gZGlmZjtcblx0fVxuXG5cdC8vIENoZWNrIGlmIGIgZm9sbG93cyBhXG5cdGlmICggY3VyICkge1xuXHRcdHdoaWxlICggKGN1ciA9IGN1ci5uZXh0U2libGluZykgKSB7XG5cdFx0XHRpZiAoIGN1ciA9PT0gYiApIHtcblx0XHRcdFx0cmV0dXJuIC0xO1xuXHRcdFx0fVxuXHRcdH1cblx0fVxuXG5cdHJldHVybiBhID8gMSA6IC0xO1xufVxuXG4vKipcbiAqIFJldHVybnMgYSBmdW5jdGlvbiB0byB1c2UgaW4gcHNldWRvcyBmb3IgaW5wdXQgdHlwZXNcbiAqIEBwYXJhbSB7U3RyaW5nfSB0eXBlXG4gKi9cbmZ1bmN0aW9uIGNyZWF0ZUlucHV0UHNldWRvKCB0eXBlICkge1xuXHRyZXR1cm4gZnVuY3Rpb24oIGVsZW0gKSB7XG5cdFx0dmFyIG5hbWUgPSBlbGVtLm5vZGVOYW1lLnRvTG93ZXJDYXNlKCk7XG5cdFx0cmV0dXJuIG5hbWUgPT09IFwiaW5wdXRcIiAmJiBlbGVtLnR5cGUgPT09IHR5cGU7XG5cdH07XG59XG5cbi8qKlxuICogUmV0dXJucyBhIGZ1bmN0aW9uIHRvIHVzZSBpbiBwc2V1ZG9zIGZvciBidXR0b25zXG4gKiBAcGFyYW0ge1N0cmluZ30gdHlwZVxuICovXG5mdW5jdGlvbiBjcmVhdGVCdXR0b25Qc2V1ZG8oIHR5cGUgKSB7XG5cdHJldHVybiBmdW5jdGlvbiggZWxlbSApIHtcblx0XHR2YXIgbmFtZSA9IGVsZW0ubm9kZU5hbWUudG9Mb3dlckNhc2UoKTtcblx0XHRyZXR1cm4gKG5hbWUgPT09IFwiaW5wdXRcIiB8fCBuYW1lID09PSBcImJ1dHRvblwiKSAmJiBlbGVtLnR5cGUgPT09IHR5cGU7XG5cdH07XG59XG5cbi8qKlxuICogUmV0dXJucyBhIGZ1bmN0aW9uIHRvIHVzZSBpbiBwc2V1ZG9zIGZvciA6ZW5hYmxlZC86ZGlzYWJsZWRcbiAqIEBwYXJhbSB7Qm9vbGVhbn0gZGlzYWJsZWQgdHJ1ZSBmb3IgOmRpc2FibGVkOyBmYWxzZSBmb3IgOmVuYWJsZWRcbiAqL1xuZnVuY3Rpb24gY3JlYXRlRGlzYWJsZWRQc2V1ZG8oIGRpc2FibGVkICkge1xuXG5cdC8vIEtub3duIDpkaXNhYmxlZCBmYWxzZSBwb3NpdGl2ZXM6IGZpZWxkc2V0W2Rpc2FibGVkXSA+IGxlZ2VuZDpudGgtb2YtdHlwZShuKzIpIDpjYW4tZGlzYWJsZVxuXHRyZXR1cm4gZnVuY3Rpb24oIGVsZW0gKSB7XG5cblx0XHQvLyBPbmx5IGNlcnRhaW4gZWxlbWVudHMgY2FuIG1hdGNoIDplbmFibGVkIG9yIDpkaXNhYmxlZFxuXHRcdC8vIGh0dHBzOi8vaHRtbC5zcGVjLndoYXR3Zy5vcmcvbXVsdGlwYWdlL3NjcmlwdGluZy5odG1sI3NlbGVjdG9yLWVuYWJsZWRcblx0XHQvLyBodHRwczovL2h0bWwuc3BlYy53aGF0d2cub3JnL211bHRpcGFnZS9zY3JpcHRpbmcuaHRtbCNzZWxlY3Rvci1kaXNhYmxlZFxuXHRcdGlmICggXCJmb3JtXCIgaW4gZWxlbSApIHtcblxuXHRcdFx0Ly8gQ2hlY2sgZm9yIGluaGVyaXRlZCBkaXNhYmxlZG5lc3Mgb24gcmVsZXZhbnQgbm9uLWRpc2FibGVkIGVsZW1lbnRzOlxuXHRcdFx0Ly8gKiBsaXN0ZWQgZm9ybS1hc3NvY2lhdGVkIGVsZW1lbnRzIGluIGEgZGlzYWJsZWQgZmllbGRzZXRcblx0XHRcdC8vICAgaHR0cHM6Ly9odG1sLnNwZWMud2hhdHdnLm9yZy9tdWx0aXBhZ2UvZm9ybXMuaHRtbCNjYXRlZ29yeS1saXN0ZWRcblx0XHRcdC8vICAgaHR0cHM6Ly9odG1sLnNwZWMud2hhdHdnLm9yZy9tdWx0aXBhZ2UvZm9ybXMuaHRtbCNjb25jZXB0LWZlLWRpc2FibGVkXG5cdFx0XHQvLyAqIG9wdGlvbiBlbGVtZW50cyBpbiBhIGRpc2FibGVkIG9wdGdyb3VwXG5cdFx0XHQvLyAgIGh0dHBzOi8vaHRtbC5zcGVjLndoYXR3Zy5vcmcvbXVsdGlwYWdlL2Zvcm1zLmh0bWwjY29uY2VwdC1vcHRpb24tZGlzYWJsZWRcblx0XHRcdC8vIEFsbCBzdWNoIGVsZW1lbnRzIGhhdmUgYSBcImZvcm1cIiBwcm9wZXJ0eS5cblx0XHRcdGlmICggZWxlbS5wYXJlbnROb2RlICYmIGVsZW0uZGlzYWJsZWQgPT09IGZhbHNlICkge1xuXG5cdFx0XHRcdC8vIE9wdGlvbiBlbGVtZW50cyBkZWZlciB0byBhIHBhcmVudCBvcHRncm91cCBpZiBwcmVzZW50XG5cdFx0XHRcdGlmICggXCJsYWJlbFwiIGluIGVsZW0gKSB7XG5cdFx0XHRcdFx0aWYgKCBcImxhYmVsXCIgaW4gZWxlbS5wYXJlbnROb2RlICkge1xuXHRcdFx0XHRcdFx0cmV0dXJuIGVsZW0ucGFyZW50Tm9kZS5kaXNhYmxlZCA9PT0gZGlzYWJsZWQ7XG5cdFx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRcdHJldHVybiBlbGVtLmRpc2FibGVkID09PSBkaXNhYmxlZDtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblxuXHRcdFx0XHQvLyBTdXBwb3J0OiBJRSA2IC0gMTFcblx0XHRcdFx0Ly8gVXNlIHRoZSBpc0Rpc2FibGVkIHNob3J0Y3V0IHByb3BlcnR5IHRvIGNoZWNrIGZvciBkaXNhYmxlZCBmaWVsZHNldCBhbmNlc3RvcnNcblx0XHRcdFx0cmV0dXJuIGVsZW0uaXNEaXNhYmxlZCA9PT0gZGlzYWJsZWQgfHxcblxuXHRcdFx0XHRcdC8vIFdoZXJlIHRoZXJlIGlzIG5vIGlzRGlzYWJsZWQsIGNoZWNrIG1hbnVhbGx5XG5cdFx0XHRcdFx0LyoganNoaW50IC1XMDE4ICovXG5cdFx0XHRcdFx0ZWxlbS5pc0Rpc2FibGVkICE9PSAhZGlzYWJsZWQgJiZcblx0XHRcdFx0XHRcdGRpc2FibGVkQW5jZXN0b3IoIGVsZW0gKSA9PT0gZGlzYWJsZWQ7XG5cdFx0XHR9XG5cblx0XHRcdHJldHVybiBlbGVtLmRpc2FibGVkID09PSBkaXNhYmxlZDtcblxuXHRcdC8vIFRyeSB0byB3aW5ub3cgb3V0IGVsZW1lbnRzIHRoYXQgY2FuJ3QgYmUgZGlzYWJsZWQgYmVmb3JlIHRydXN0aW5nIHRoZSBkaXNhYmxlZCBwcm9wZXJ0eS5cblx0XHQvLyBTb21lIHZpY3RpbXMgZ2V0IGNhdWdodCBpbiBvdXIgbmV0IChsYWJlbCwgbGVnZW5kLCBtZW51LCB0cmFjayksIGJ1dCBpdCBzaG91bGRuJ3Rcblx0XHQvLyBldmVuIGV4aXN0IG9uIHRoZW0sIGxldCBhbG9uZSBoYXZlIGEgYm9vbGVhbiB2YWx1ZS5cblx0XHR9IGVsc2UgaWYgKCBcImxhYmVsXCIgaW4gZWxlbSApIHtcblx0XHRcdHJldHVybiBlbGVtLmRpc2FibGVkID09PSBkaXNhYmxlZDtcblx0XHR9XG5cblx0XHQvLyBSZW1haW5pbmcgZWxlbWVudHMgYXJlIG5laXRoZXIgOmVuYWJsZWQgbm9yIDpkaXNhYmxlZFxuXHRcdHJldHVybiBmYWxzZTtcblx0fTtcbn1cblxuLyoqXG4gKiBSZXR1cm5zIGEgZnVuY3Rpb24gdG8gdXNlIGluIHBzZXVkb3MgZm9yIHBvc2l0aW9uYWxzXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBmblxuICovXG5mdW5jdGlvbiBjcmVhdGVQb3NpdGlvbmFsUHNldWRvKCBmbiApIHtcblx0cmV0dXJuIG1hcmtGdW5jdGlvbihmdW5jdGlvbiggYXJndW1lbnQgKSB7XG5cdFx0YXJndW1lbnQgPSArYXJndW1lbnQ7XG5cdFx0cmV0dXJuIG1hcmtGdW5jdGlvbihmdW5jdGlvbiggc2VlZCwgbWF0Y2hlcyApIHtcblx0XHRcdHZhciBqLFxuXHRcdFx0XHRtYXRjaEluZGV4ZXMgPSBmbiggW10sIHNlZWQubGVuZ3RoLCBhcmd1bWVudCApLFxuXHRcdFx0XHRpID0gbWF0Y2hJbmRleGVzLmxlbmd0aDtcblxuXHRcdFx0Ly8gTWF0Y2ggZWxlbWVudHMgZm91bmQgYXQgdGhlIHNwZWNpZmllZCBpbmRleGVzXG5cdFx0XHR3aGlsZSAoIGktLSApIHtcblx0XHRcdFx0aWYgKCBzZWVkWyAoaiA9IG1hdGNoSW5kZXhlc1tpXSkgXSApIHtcblx0XHRcdFx0XHRzZWVkW2pdID0gIShtYXRjaGVzW2pdID0gc2VlZFtqXSk7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9KTtcblx0fSk7XG59XG5cbi8qKlxuICogQ2hlY2tzIGEgbm9kZSBmb3IgdmFsaWRpdHkgYXMgYSBTaXp6bGUgY29udGV4dFxuICogQHBhcmFtIHtFbGVtZW50fE9iamVjdD19IGNvbnRleHRcbiAqIEByZXR1cm5zIHtFbGVtZW50fE9iamVjdHxCb29sZWFufSBUaGUgaW5wdXQgbm9kZSBpZiBhY2NlcHRhYmxlLCBvdGhlcndpc2UgYSBmYWxzeSB2YWx1ZVxuICovXG5mdW5jdGlvbiB0ZXN0Q29udGV4dCggY29udGV4dCApIHtcblx0cmV0dXJuIGNvbnRleHQgJiYgdHlwZW9mIGNvbnRleHQuZ2V0RWxlbWVudHNCeVRhZ05hbWUgIT09IFwidW5kZWZpbmVkXCIgJiYgY29udGV4dDtcbn1cblxuLy8gRXhwb3NlIHN1cHBvcnQgdmFycyBmb3IgY29udmVuaWVuY2VcbnN1cHBvcnQgPSBTaXp6bGUuc3VwcG9ydCA9IHt9O1xuXG4vKipcbiAqIERldGVjdHMgWE1MIG5vZGVzXG4gKiBAcGFyYW0ge0VsZW1lbnR8T2JqZWN0fSBlbGVtIEFuIGVsZW1lbnQgb3IgYSBkb2N1bWVudFxuICogQHJldHVybnMge0Jvb2xlYW59IFRydWUgaWZmIGVsZW0gaXMgYSBub24tSFRNTCBYTUwgbm9kZVxuICovXG5pc1hNTCA9IFNpenpsZS5pc1hNTCA9IGZ1bmN0aW9uKCBlbGVtICkge1xuXHQvLyBkb2N1bWVudEVsZW1lbnQgaXMgdmVyaWZpZWQgZm9yIGNhc2VzIHdoZXJlIGl0IGRvZXNuJ3QgeWV0IGV4aXN0XG5cdC8vIChzdWNoIGFzIGxvYWRpbmcgaWZyYW1lcyBpbiBJRSAtICM0ODMzKVxuXHR2YXIgZG9jdW1lbnRFbGVtZW50ID0gZWxlbSAmJiAoZWxlbS5vd25lckRvY3VtZW50IHx8IGVsZW0pLmRvY3VtZW50RWxlbWVudDtcblx0cmV0dXJuIGRvY3VtZW50RWxlbWVudCA/IGRvY3VtZW50RWxlbWVudC5ub2RlTmFtZSAhPT0gXCJIVE1MXCIgOiBmYWxzZTtcbn07XG5cbi8qKlxuICogU2V0cyBkb2N1bWVudC1yZWxhdGVkIHZhcmlhYmxlcyBvbmNlIGJhc2VkIG9uIHRoZSBjdXJyZW50IGRvY3VtZW50XG4gKiBAcGFyYW0ge0VsZW1lbnR8T2JqZWN0fSBbZG9jXSBBbiBlbGVtZW50IG9yIGRvY3VtZW50IG9iamVjdCB0byB1c2UgdG8gc2V0IHRoZSBkb2N1bWVudFxuICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyB0aGUgY3VycmVudCBkb2N1bWVudFxuICovXG5zZXREb2N1bWVudCA9IFNpenpsZS5zZXREb2N1bWVudCA9IGZ1bmN0aW9uKCBub2RlICkge1xuXHR2YXIgaGFzQ29tcGFyZSwgc3ViV2luZG93LFxuXHRcdGRvYyA9IG5vZGUgPyBub2RlLm93bmVyRG9jdW1lbnQgfHwgbm9kZSA6IHByZWZlcnJlZERvYztcblxuXHQvLyBSZXR1cm4gZWFybHkgaWYgZG9jIGlzIGludmFsaWQgb3IgYWxyZWFkeSBzZWxlY3RlZFxuXHRpZiAoIGRvYyA9PT0gZG9jdW1lbnQgfHwgZG9jLm5vZGVUeXBlICE9PSA5IHx8ICFkb2MuZG9jdW1lbnRFbGVtZW50ICkge1xuXHRcdHJldHVybiBkb2N1bWVudDtcblx0fVxuXG5cdC8vIFVwZGF0ZSBnbG9iYWwgdmFyaWFibGVzXG5cdGRvY3VtZW50ID0gZG9jO1xuXHRkb2NFbGVtID0gZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50O1xuXHRkb2N1bWVudElzSFRNTCA9ICFpc1hNTCggZG9jdW1lbnQgKTtcblxuXHQvLyBTdXBwb3J0OiBJRSA5LTExLCBFZGdlXG5cdC8vIEFjY2Vzc2luZyBpZnJhbWUgZG9jdW1lbnRzIGFmdGVyIHVubG9hZCB0aHJvd3MgXCJwZXJtaXNzaW9uIGRlbmllZFwiIGVycm9ycyAoalF1ZXJ5ICMxMzkzNilcblx0aWYgKCBwcmVmZXJyZWREb2MgIT09IGRvY3VtZW50ICYmXG5cdFx0KHN1YldpbmRvdyA9IGRvY3VtZW50LmRlZmF1bHRWaWV3KSAmJiBzdWJXaW5kb3cudG9wICE9PSBzdWJXaW5kb3cgKSB7XG5cblx0XHQvLyBTdXBwb3J0OiBJRSAxMSwgRWRnZVxuXHRcdGlmICggc3ViV2luZG93LmFkZEV2ZW50TGlzdGVuZXIgKSB7XG5cdFx0XHRzdWJXaW5kb3cuYWRkRXZlbnRMaXN0ZW5lciggXCJ1bmxvYWRcIiwgdW5sb2FkSGFuZGxlciwgZmFsc2UgKTtcblxuXHRcdC8vIFN1cHBvcnQ6IElFIDkgLSAxMCBvbmx5XG5cdFx0fSBlbHNlIGlmICggc3ViV2luZG93LmF0dGFjaEV2ZW50ICkge1xuXHRcdFx0c3ViV2luZG93LmF0dGFjaEV2ZW50KCBcIm9udW5sb2FkXCIsIHVubG9hZEhhbmRsZXIgKTtcblx0XHR9XG5cdH1cblxuXHQvKiBBdHRyaWJ1dGVzXG5cdC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi9cblxuXHQvLyBTdXBwb3J0OiBJRTw4XG5cdC8vIFZlcmlmeSB0aGF0IGdldEF0dHJpYnV0ZSByZWFsbHkgcmV0dXJucyBhdHRyaWJ1dGVzIGFuZCBub3QgcHJvcGVydGllc1xuXHQvLyAoZXhjZXB0aW5nIElFOCBib29sZWFucylcblx0c3VwcG9ydC5hdHRyaWJ1dGVzID0gYXNzZXJ0KGZ1bmN0aW9uKCBlbCApIHtcblx0XHRlbC5jbGFzc05hbWUgPSBcImlcIjtcblx0XHRyZXR1cm4gIWVsLmdldEF0dHJpYnV0ZShcImNsYXNzTmFtZVwiKTtcblx0fSk7XG5cblx0LyogZ2V0RWxlbWVudChzKUJ5KlxuXHQtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovXG5cblx0Ly8gQ2hlY2sgaWYgZ2V0RWxlbWVudHNCeVRhZ05hbWUoXCIqXCIpIHJldHVybnMgb25seSBlbGVtZW50c1xuXHRzdXBwb3J0LmdldEVsZW1lbnRzQnlUYWdOYW1lID0gYXNzZXJ0KGZ1bmN0aW9uKCBlbCApIHtcblx0XHRlbC5hcHBlbmRDaGlsZCggZG9jdW1lbnQuY3JlYXRlQ29tbWVudChcIlwiKSApO1xuXHRcdHJldHVybiAhZWwuZ2V0RWxlbWVudHNCeVRhZ05hbWUoXCIqXCIpLmxlbmd0aDtcblx0fSk7XG5cblx0Ly8gU3VwcG9ydDogSUU8OVxuXHRzdXBwb3J0LmdldEVsZW1lbnRzQnlDbGFzc05hbWUgPSBybmF0aXZlLnRlc3QoIGRvY3VtZW50LmdldEVsZW1lbnRzQnlDbGFzc05hbWUgKTtcblxuXHQvLyBTdXBwb3J0OiBJRTwxMFxuXHQvLyBDaGVjayBpZiBnZXRFbGVtZW50QnlJZCByZXR1cm5zIGVsZW1lbnRzIGJ5IG5hbWVcblx0Ly8gVGhlIGJyb2tlbiBnZXRFbGVtZW50QnlJZCBtZXRob2RzIGRvbid0IHBpY2sgdXAgcHJvZ3JhbW1hdGljYWxseS1zZXQgbmFtZXMsXG5cdC8vIHNvIHVzZSBhIHJvdW5kYWJvdXQgZ2V0RWxlbWVudHNCeU5hbWUgdGVzdFxuXHRzdXBwb3J0LmdldEJ5SWQgPSBhc3NlcnQoZnVuY3Rpb24oIGVsICkge1xuXHRcdGRvY0VsZW0uYXBwZW5kQ2hpbGQoIGVsICkuaWQgPSBleHBhbmRvO1xuXHRcdHJldHVybiAhZG9jdW1lbnQuZ2V0RWxlbWVudHNCeU5hbWUgfHwgIWRvY3VtZW50LmdldEVsZW1lbnRzQnlOYW1lKCBleHBhbmRvICkubGVuZ3RoO1xuXHR9KTtcblxuXHQvLyBJRCBmaWx0ZXIgYW5kIGZpbmRcblx0aWYgKCBzdXBwb3J0LmdldEJ5SWQgKSB7XG5cdFx0RXhwci5maWx0ZXJbXCJJRFwiXSA9IGZ1bmN0aW9uKCBpZCApIHtcblx0XHRcdHZhciBhdHRySWQgPSBpZC5yZXBsYWNlKCBydW5lc2NhcGUsIGZ1bmVzY2FwZSApO1xuXHRcdFx0cmV0dXJuIGZ1bmN0aW9uKCBlbGVtICkge1xuXHRcdFx0XHRyZXR1cm4gZWxlbS5nZXRBdHRyaWJ1dGUoXCJpZFwiKSA9PT0gYXR0cklkO1xuXHRcdFx0fTtcblx0XHR9O1xuXHRcdEV4cHIuZmluZFtcIklEXCJdID0gZnVuY3Rpb24oIGlkLCBjb250ZXh0ICkge1xuXHRcdFx0aWYgKCB0eXBlb2YgY29udGV4dC5nZXRFbGVtZW50QnlJZCAhPT0gXCJ1bmRlZmluZWRcIiAmJiBkb2N1bWVudElzSFRNTCApIHtcblx0XHRcdFx0dmFyIGVsZW0gPSBjb250ZXh0LmdldEVsZW1lbnRCeUlkKCBpZCApO1xuXHRcdFx0XHRyZXR1cm4gZWxlbSA/IFsgZWxlbSBdIDogW107XG5cdFx0XHR9XG5cdFx0fTtcblx0fSBlbHNlIHtcblx0XHRFeHByLmZpbHRlcltcIklEXCJdID0gIGZ1bmN0aW9uKCBpZCApIHtcblx0XHRcdHZhciBhdHRySWQgPSBpZC5yZXBsYWNlKCBydW5lc2NhcGUsIGZ1bmVzY2FwZSApO1xuXHRcdFx0cmV0dXJuIGZ1bmN0aW9uKCBlbGVtICkge1xuXHRcdFx0XHR2YXIgbm9kZSA9IHR5cGVvZiBlbGVtLmdldEF0dHJpYnV0ZU5vZGUgIT09IFwidW5kZWZpbmVkXCIgJiZcblx0XHRcdFx0XHRlbGVtLmdldEF0dHJpYnV0ZU5vZGUoXCJpZFwiKTtcblx0XHRcdFx0cmV0dXJuIG5vZGUgJiYgbm9kZS52YWx1ZSA9PT0gYXR0cklkO1xuXHRcdFx0fTtcblx0XHR9O1xuXG5cdFx0Ly8gU3VwcG9ydDogSUUgNiAtIDcgb25seVxuXHRcdC8vIGdldEVsZW1lbnRCeUlkIGlzIG5vdCByZWxpYWJsZSBhcyBhIGZpbmQgc2hvcnRjdXRcblx0XHRFeHByLmZpbmRbXCJJRFwiXSA9IGZ1bmN0aW9uKCBpZCwgY29udGV4dCApIHtcblx0XHRcdGlmICggdHlwZW9mIGNvbnRleHQuZ2V0RWxlbWVudEJ5SWQgIT09IFwidW5kZWZpbmVkXCIgJiYgZG9jdW1lbnRJc0hUTUwgKSB7XG5cdFx0XHRcdHZhciBub2RlLCBpLCBlbGVtcyxcblx0XHRcdFx0XHRlbGVtID0gY29udGV4dC5nZXRFbGVtZW50QnlJZCggaWQgKTtcblxuXHRcdFx0XHRpZiAoIGVsZW0gKSB7XG5cblx0XHRcdFx0XHQvLyBWZXJpZnkgdGhlIGlkIGF0dHJpYnV0ZVxuXHRcdFx0XHRcdG5vZGUgPSBlbGVtLmdldEF0dHJpYnV0ZU5vZGUoXCJpZFwiKTtcblx0XHRcdFx0XHRpZiAoIG5vZGUgJiYgbm9kZS52YWx1ZSA9PT0gaWQgKSB7XG5cdFx0XHRcdFx0XHRyZXR1cm4gWyBlbGVtIF07XG5cdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0Ly8gRmFsbCBiYWNrIG9uIGdldEVsZW1lbnRzQnlOYW1lXG5cdFx0XHRcdFx0ZWxlbXMgPSBjb250ZXh0LmdldEVsZW1lbnRzQnlOYW1lKCBpZCApO1xuXHRcdFx0XHRcdGkgPSAwO1xuXHRcdFx0XHRcdHdoaWxlICggKGVsZW0gPSBlbGVtc1tpKytdKSApIHtcblx0XHRcdFx0XHRcdG5vZGUgPSBlbGVtLmdldEF0dHJpYnV0ZU5vZGUoXCJpZFwiKTtcblx0XHRcdFx0XHRcdGlmICggbm9kZSAmJiBub2RlLnZhbHVlID09PSBpZCApIHtcblx0XHRcdFx0XHRcdFx0cmV0dXJuIFsgZWxlbSBdO1xuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXG5cdFx0XHRcdHJldHVybiBbXTtcblx0XHRcdH1cblx0XHR9O1xuXHR9XG5cblx0Ly8gVGFnXG5cdEV4cHIuZmluZFtcIlRBR1wiXSA9IHN1cHBvcnQuZ2V0RWxlbWVudHNCeVRhZ05hbWUgP1xuXHRcdGZ1bmN0aW9uKCB0YWcsIGNvbnRleHQgKSB7XG5cdFx0XHRpZiAoIHR5cGVvZiBjb250ZXh0LmdldEVsZW1lbnRzQnlUYWdOYW1lICE9PSBcInVuZGVmaW5lZFwiICkge1xuXHRcdFx0XHRyZXR1cm4gY29udGV4dC5nZXRFbGVtZW50c0J5VGFnTmFtZSggdGFnICk7XG5cblx0XHRcdC8vIERvY3VtZW50RnJhZ21lbnQgbm9kZXMgZG9uJ3QgaGF2ZSBnRUJUTlxuXHRcdFx0fSBlbHNlIGlmICggc3VwcG9ydC5xc2EgKSB7XG5cdFx0XHRcdHJldHVybiBjb250ZXh0LnF1ZXJ5U2VsZWN0b3JBbGwoIHRhZyApO1xuXHRcdFx0fVxuXHRcdH0gOlxuXG5cdFx0ZnVuY3Rpb24oIHRhZywgY29udGV4dCApIHtcblx0XHRcdHZhciBlbGVtLFxuXHRcdFx0XHR0bXAgPSBbXSxcblx0XHRcdFx0aSA9IDAsXG5cdFx0XHRcdC8vIEJ5IGhhcHB5IGNvaW5jaWRlbmNlLCBhIChicm9rZW4pIGdFQlROIGFwcGVhcnMgb24gRG9jdW1lbnRGcmFnbWVudCBub2RlcyB0b29cblx0XHRcdFx0cmVzdWx0cyA9IGNvbnRleHQuZ2V0RWxlbWVudHNCeVRhZ05hbWUoIHRhZyApO1xuXG5cdFx0XHQvLyBGaWx0ZXIgb3V0IHBvc3NpYmxlIGNvbW1lbnRzXG5cdFx0XHRpZiAoIHRhZyA9PT0gXCIqXCIgKSB7XG5cdFx0XHRcdHdoaWxlICggKGVsZW0gPSByZXN1bHRzW2krK10pICkge1xuXHRcdFx0XHRcdGlmICggZWxlbS5ub2RlVHlwZSA9PT0gMSApIHtcblx0XHRcdFx0XHRcdHRtcC5wdXNoKCBlbGVtICk7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cblx0XHRcdFx0cmV0dXJuIHRtcDtcblx0XHRcdH1cblx0XHRcdHJldHVybiByZXN1bHRzO1xuXHRcdH07XG5cblx0Ly8gQ2xhc3Ncblx0RXhwci5maW5kW1wiQ0xBU1NcIl0gPSBzdXBwb3J0LmdldEVsZW1lbnRzQnlDbGFzc05hbWUgJiYgZnVuY3Rpb24oIGNsYXNzTmFtZSwgY29udGV4dCApIHtcblx0XHRpZiAoIHR5cGVvZiBjb250ZXh0LmdldEVsZW1lbnRzQnlDbGFzc05hbWUgIT09IFwidW5kZWZpbmVkXCIgJiYgZG9jdW1lbnRJc0hUTUwgKSB7XG5cdFx0XHRyZXR1cm4gY29udGV4dC5nZXRFbGVtZW50c0J5Q2xhc3NOYW1lKCBjbGFzc05hbWUgKTtcblx0XHR9XG5cdH07XG5cblx0LyogUVNBL21hdGNoZXNTZWxlY3RvclxuXHQtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovXG5cblx0Ly8gUVNBIGFuZCBtYXRjaGVzU2VsZWN0b3Igc3VwcG9ydFxuXG5cdC8vIG1hdGNoZXNTZWxlY3Rvcig6YWN0aXZlKSByZXBvcnRzIGZhbHNlIHdoZW4gdHJ1ZSAoSUU5L09wZXJhIDExLjUpXG5cdHJidWdneU1hdGNoZXMgPSBbXTtcblxuXHQvLyBxU2EoOmZvY3VzKSByZXBvcnRzIGZhbHNlIHdoZW4gdHJ1ZSAoQ2hyb21lIDIxKVxuXHQvLyBXZSBhbGxvdyB0aGlzIGJlY2F1c2Ugb2YgYSBidWcgaW4gSUU4LzkgdGhhdCB0aHJvd3MgYW4gZXJyb3Jcblx0Ly8gd2hlbmV2ZXIgYGRvY3VtZW50LmFjdGl2ZUVsZW1lbnRgIGlzIGFjY2Vzc2VkIG9uIGFuIGlmcmFtZVxuXHQvLyBTbywgd2UgYWxsb3cgOmZvY3VzIHRvIHBhc3MgdGhyb3VnaCBRU0EgYWxsIHRoZSB0aW1lIHRvIGF2b2lkIHRoZSBJRSBlcnJvclxuXHQvLyBTZWUgaHR0cHM6Ly9idWdzLmpxdWVyeS5jb20vdGlja2V0LzEzMzc4XG5cdHJidWdneVFTQSA9IFtdO1xuXG5cdGlmICggKHN1cHBvcnQucXNhID0gcm5hdGl2ZS50ZXN0KCBkb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsICkpICkge1xuXHRcdC8vIEJ1aWxkIFFTQSByZWdleFxuXHRcdC8vIFJlZ2V4IHN0cmF0ZWd5IGFkb3B0ZWQgZnJvbSBEaWVnbyBQZXJpbmlcblx0XHRhc3NlcnQoZnVuY3Rpb24oIGVsICkge1xuXHRcdFx0Ly8gU2VsZWN0IGlzIHNldCB0byBlbXB0eSBzdHJpbmcgb24gcHVycG9zZVxuXHRcdFx0Ly8gVGhpcyBpcyB0byB0ZXN0IElFJ3MgdHJlYXRtZW50IG9mIG5vdCBleHBsaWNpdGx5XG5cdFx0XHQvLyBzZXR0aW5nIGEgYm9vbGVhbiBjb250ZW50IGF0dHJpYnV0ZSxcblx0XHRcdC8vIHNpbmNlIGl0cyBwcmVzZW5jZSBzaG91bGQgYmUgZW5vdWdoXG5cdFx0XHQvLyBodHRwczovL2J1Z3MuanF1ZXJ5LmNvbS90aWNrZXQvMTIzNTlcblx0XHRcdGRvY0VsZW0uYXBwZW5kQ2hpbGQoIGVsICkuaW5uZXJIVE1MID0gXCI8YSBpZD0nXCIgKyBleHBhbmRvICsgXCInPjwvYT5cIiArXG5cdFx0XHRcdFwiPHNlbGVjdCBpZD0nXCIgKyBleHBhbmRvICsgXCItXFxyXFxcXCcgbXNhbGxvd2NhcHR1cmU9Jyc+XCIgK1xuXHRcdFx0XHRcIjxvcHRpb24gc2VsZWN0ZWQ9Jyc+PC9vcHRpb24+PC9zZWxlY3Q+XCI7XG5cblx0XHRcdC8vIFN1cHBvcnQ6IElFOCwgT3BlcmEgMTEtMTIuMTZcblx0XHRcdC8vIE5vdGhpbmcgc2hvdWxkIGJlIHNlbGVjdGVkIHdoZW4gZW1wdHkgc3RyaW5ncyBmb2xsb3cgXj0gb3IgJD0gb3IgKj1cblx0XHRcdC8vIFRoZSB0ZXN0IGF0dHJpYnV0ZSBtdXN0IGJlIHVua25vd24gaW4gT3BlcmEgYnV0IFwic2FmZVwiIGZvciBXaW5SVFxuXHRcdFx0Ly8gaHR0cHM6Ly9tc2RuLm1pY3Jvc29mdC5jb20vZW4tdXMvbGlicmFyeS9pZS9oaDQ2NTM4OC5hc3B4I2F0dHJpYnV0ZV9zZWN0aW9uXG5cdFx0XHRpZiAoIGVsLnF1ZXJ5U2VsZWN0b3JBbGwoXCJbbXNhbGxvd2NhcHR1cmVePScnXVwiKS5sZW5ndGggKSB7XG5cdFx0XHRcdHJidWdneVFTQS5wdXNoKCBcIlsqXiRdPVwiICsgd2hpdGVzcGFjZSArIFwiKig/OicnfFxcXCJcXFwiKVwiICk7XG5cdFx0XHR9XG5cblx0XHRcdC8vIFN1cHBvcnQ6IElFOFxuXHRcdFx0Ly8gQm9vbGVhbiBhdHRyaWJ1dGVzIGFuZCBcInZhbHVlXCIgYXJlIG5vdCB0cmVhdGVkIGNvcnJlY3RseVxuXHRcdFx0aWYgKCAhZWwucXVlcnlTZWxlY3RvckFsbChcIltzZWxlY3RlZF1cIikubGVuZ3RoICkge1xuXHRcdFx0XHRyYnVnZ3lRU0EucHVzaCggXCJcXFxcW1wiICsgd2hpdGVzcGFjZSArIFwiKig/OnZhbHVlfFwiICsgYm9vbGVhbnMgKyBcIilcIiApO1xuXHRcdFx0fVxuXG5cdFx0XHQvLyBTdXBwb3J0OiBDaHJvbWU8MjksIEFuZHJvaWQ8NC40LCBTYWZhcmk8Ny4wKywgaU9TPDcuMCssIFBoYW50b21KUzwxLjkuOCtcblx0XHRcdGlmICggIWVsLnF1ZXJ5U2VsZWN0b3JBbGwoIFwiW2lkfj1cIiArIGV4cGFuZG8gKyBcIi1dXCIgKS5sZW5ndGggKSB7XG5cdFx0XHRcdHJidWdneVFTQS5wdXNoKFwifj1cIik7XG5cdFx0XHR9XG5cblx0XHRcdC8vIFdlYmtpdC9PcGVyYSAtIDpjaGVja2VkIHNob3VsZCByZXR1cm4gc2VsZWN0ZWQgb3B0aW9uIGVsZW1lbnRzXG5cdFx0XHQvLyBodHRwOi8vd3d3LnczLm9yZy9UUi8yMDExL1JFQy1jc3MzLXNlbGVjdG9ycy0yMDExMDkyOS8jY2hlY2tlZFxuXHRcdFx0Ly8gSUU4IHRocm93cyBlcnJvciBoZXJlIGFuZCB3aWxsIG5vdCBzZWUgbGF0ZXIgdGVzdHNcblx0XHRcdGlmICggIWVsLnF1ZXJ5U2VsZWN0b3JBbGwoXCI6Y2hlY2tlZFwiKS5sZW5ndGggKSB7XG5cdFx0XHRcdHJidWdneVFTQS5wdXNoKFwiOmNoZWNrZWRcIik7XG5cdFx0XHR9XG5cblx0XHRcdC8vIFN1cHBvcnQ6IFNhZmFyaSA4KywgaU9TIDgrXG5cdFx0XHQvLyBodHRwczovL2J1Z3Mud2Via2l0Lm9yZy9zaG93X2J1Zy5jZ2k/aWQ9MTM2ODUxXG5cdFx0XHQvLyBJbi1wYWdlIGBzZWxlY3RvciNpZCBzaWJsaW5nLWNvbWJpbmF0b3Igc2VsZWN0b3JgIGZhaWxzXG5cdFx0XHRpZiAoICFlbC5xdWVyeVNlbGVjdG9yQWxsKCBcImEjXCIgKyBleHBhbmRvICsgXCIrKlwiICkubGVuZ3RoICkge1xuXHRcdFx0XHRyYnVnZ3lRU0EucHVzaChcIi4jLitbK35dXCIpO1xuXHRcdFx0fVxuXHRcdH0pO1xuXG5cdFx0YXNzZXJ0KGZ1bmN0aW9uKCBlbCApIHtcblx0XHRcdGVsLmlubmVySFRNTCA9IFwiPGEgaHJlZj0nJyBkaXNhYmxlZD0nZGlzYWJsZWQnPjwvYT5cIiArXG5cdFx0XHRcdFwiPHNlbGVjdCBkaXNhYmxlZD0nZGlzYWJsZWQnPjxvcHRpb24vPjwvc2VsZWN0PlwiO1xuXG5cdFx0XHQvLyBTdXBwb3J0OiBXaW5kb3dzIDggTmF0aXZlIEFwcHNcblx0XHRcdC8vIFRoZSB0eXBlIGFuZCBuYW1lIGF0dHJpYnV0ZXMgYXJlIHJlc3RyaWN0ZWQgZHVyaW5nIC5pbm5lckhUTUwgYXNzaWdubWVudFxuXHRcdFx0dmFyIGlucHV0ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcImlucHV0XCIpO1xuXHRcdFx0aW5wdXQuc2V0QXR0cmlidXRlKCBcInR5cGVcIiwgXCJoaWRkZW5cIiApO1xuXHRcdFx0ZWwuYXBwZW5kQ2hpbGQoIGlucHV0ICkuc2V0QXR0cmlidXRlKCBcIm5hbWVcIiwgXCJEXCIgKTtcblxuXHRcdFx0Ly8gU3VwcG9ydDogSUU4XG5cdFx0XHQvLyBFbmZvcmNlIGNhc2Utc2Vuc2l0aXZpdHkgb2YgbmFtZSBhdHRyaWJ1dGVcblx0XHRcdGlmICggZWwucXVlcnlTZWxlY3RvckFsbChcIltuYW1lPWRdXCIpLmxlbmd0aCApIHtcblx0XHRcdFx0cmJ1Z2d5UVNBLnB1c2goIFwibmFtZVwiICsgd2hpdGVzcGFjZSArIFwiKlsqXiR8IX5dPz1cIiApO1xuXHRcdFx0fVxuXG5cdFx0XHQvLyBGRiAzLjUgLSA6ZW5hYmxlZC86ZGlzYWJsZWQgYW5kIGhpZGRlbiBlbGVtZW50cyAoaGlkZGVuIGVsZW1lbnRzIGFyZSBzdGlsbCBlbmFibGVkKVxuXHRcdFx0Ly8gSUU4IHRocm93cyBlcnJvciBoZXJlIGFuZCB3aWxsIG5vdCBzZWUgbGF0ZXIgdGVzdHNcblx0XHRcdGlmICggZWwucXVlcnlTZWxlY3RvckFsbChcIjplbmFibGVkXCIpLmxlbmd0aCAhPT0gMiApIHtcblx0XHRcdFx0cmJ1Z2d5UVNBLnB1c2goIFwiOmVuYWJsZWRcIiwgXCI6ZGlzYWJsZWRcIiApO1xuXHRcdFx0fVxuXG5cdFx0XHQvLyBTdXBwb3J0OiBJRTktMTErXG5cdFx0XHQvLyBJRSdzIDpkaXNhYmxlZCBzZWxlY3RvciBkb2VzIG5vdCBwaWNrIHVwIHRoZSBjaGlsZHJlbiBvZiBkaXNhYmxlZCBmaWVsZHNldHNcblx0XHRcdGRvY0VsZW0uYXBwZW5kQ2hpbGQoIGVsICkuZGlzYWJsZWQgPSB0cnVlO1xuXHRcdFx0aWYgKCBlbC5xdWVyeVNlbGVjdG9yQWxsKFwiOmRpc2FibGVkXCIpLmxlbmd0aCAhPT0gMiApIHtcblx0XHRcdFx0cmJ1Z2d5UVNBLnB1c2goIFwiOmVuYWJsZWRcIiwgXCI6ZGlzYWJsZWRcIiApO1xuXHRcdFx0fVxuXG5cdFx0XHQvLyBPcGVyYSAxMC0xMSBkb2VzIG5vdCB0aHJvdyBvbiBwb3N0LWNvbW1hIGludmFsaWQgcHNldWRvc1xuXHRcdFx0ZWwucXVlcnlTZWxlY3RvckFsbChcIiosOnhcIik7XG5cdFx0XHRyYnVnZ3lRU0EucHVzaChcIiwuKjpcIik7XG5cdFx0fSk7XG5cdH1cblxuXHRpZiAoIChzdXBwb3J0Lm1hdGNoZXNTZWxlY3RvciA9IHJuYXRpdmUudGVzdCggKG1hdGNoZXMgPSBkb2NFbGVtLm1hdGNoZXMgfHxcblx0XHRkb2NFbGVtLndlYmtpdE1hdGNoZXNTZWxlY3RvciB8fFxuXHRcdGRvY0VsZW0ubW96TWF0Y2hlc1NlbGVjdG9yIHx8XG5cdFx0ZG9jRWxlbS5vTWF0Y2hlc1NlbGVjdG9yIHx8XG5cdFx0ZG9jRWxlbS5tc01hdGNoZXNTZWxlY3RvcikgKSkgKSB7XG5cblx0XHRhc3NlcnQoZnVuY3Rpb24oIGVsICkge1xuXHRcdFx0Ly8gQ2hlY2sgdG8gc2VlIGlmIGl0J3MgcG9zc2libGUgdG8gZG8gbWF0Y2hlc1NlbGVjdG9yXG5cdFx0XHQvLyBvbiBhIGRpc2Nvbm5lY3RlZCBub2RlIChJRSA5KVxuXHRcdFx0c3VwcG9ydC5kaXNjb25uZWN0ZWRNYXRjaCA9IG1hdGNoZXMuY2FsbCggZWwsIFwiKlwiICk7XG5cblx0XHRcdC8vIFRoaXMgc2hvdWxkIGZhaWwgd2l0aCBhbiBleGNlcHRpb25cblx0XHRcdC8vIEdlY2tvIGRvZXMgbm90IGVycm9yLCByZXR1cm5zIGZhbHNlIGluc3RlYWRcblx0XHRcdG1hdGNoZXMuY2FsbCggZWwsIFwiW3MhPScnXTp4XCIgKTtcblx0XHRcdHJidWdneU1hdGNoZXMucHVzaCggXCIhPVwiLCBwc2V1ZG9zICk7XG5cdFx0fSk7XG5cdH1cblxuXHRyYnVnZ3lRU0EgPSByYnVnZ3lRU0EubGVuZ3RoICYmIG5ldyBSZWdFeHAoIHJidWdneVFTQS5qb2luKFwifFwiKSApO1xuXHRyYnVnZ3lNYXRjaGVzID0gcmJ1Z2d5TWF0Y2hlcy5sZW5ndGggJiYgbmV3IFJlZ0V4cCggcmJ1Z2d5TWF0Y2hlcy5qb2luKFwifFwiKSApO1xuXG5cdC8qIENvbnRhaW5zXG5cdC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi9cblx0aGFzQ29tcGFyZSA9IHJuYXRpdmUudGVzdCggZG9jRWxlbS5jb21wYXJlRG9jdW1lbnRQb3NpdGlvbiApO1xuXG5cdC8vIEVsZW1lbnQgY29udGFpbnMgYW5vdGhlclxuXHQvLyBQdXJwb3NlZnVsbHkgc2VsZi1leGNsdXNpdmVcblx0Ly8gQXMgaW4sIGFuIGVsZW1lbnQgZG9lcyBub3QgY29udGFpbiBpdHNlbGZcblx0Y29udGFpbnMgPSBoYXNDb21wYXJlIHx8IHJuYXRpdmUudGVzdCggZG9jRWxlbS5jb250YWlucyApID9cblx0XHRmdW5jdGlvbiggYSwgYiApIHtcblx0XHRcdHZhciBhZG93biA9IGEubm9kZVR5cGUgPT09IDkgPyBhLmRvY3VtZW50RWxlbWVudCA6IGEsXG5cdFx0XHRcdGJ1cCA9IGIgJiYgYi5wYXJlbnROb2RlO1xuXHRcdFx0cmV0dXJuIGEgPT09IGJ1cCB8fCAhISggYnVwICYmIGJ1cC5ub2RlVHlwZSA9PT0gMSAmJiAoXG5cdFx0XHRcdGFkb3duLmNvbnRhaW5zID9cblx0XHRcdFx0XHRhZG93bi5jb250YWlucyggYnVwICkgOlxuXHRcdFx0XHRcdGEuY29tcGFyZURvY3VtZW50UG9zaXRpb24gJiYgYS5jb21wYXJlRG9jdW1lbnRQb3NpdGlvbiggYnVwICkgJiAxNlxuXHRcdFx0KSk7XG5cdFx0fSA6XG5cdFx0ZnVuY3Rpb24oIGEsIGIgKSB7XG5cdFx0XHRpZiAoIGIgKSB7XG5cdFx0XHRcdHdoaWxlICggKGIgPSBiLnBhcmVudE5vZGUpICkge1xuXHRcdFx0XHRcdGlmICggYiA9PT0gYSApIHtcblx0XHRcdFx0XHRcdHJldHVybiB0cnVlO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdFx0cmV0dXJuIGZhbHNlO1xuXHRcdH07XG5cblx0LyogU29ydGluZ1xuXHQtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovXG5cblx0Ly8gRG9jdW1lbnQgb3JkZXIgc29ydGluZ1xuXHRzb3J0T3JkZXIgPSBoYXNDb21wYXJlID9cblx0ZnVuY3Rpb24oIGEsIGIgKSB7XG5cblx0XHQvLyBGbGFnIGZvciBkdXBsaWNhdGUgcmVtb3ZhbFxuXHRcdGlmICggYSA9PT0gYiApIHtcblx0XHRcdGhhc0R1cGxpY2F0ZSA9IHRydWU7XG5cdFx0XHRyZXR1cm4gMDtcblx0XHR9XG5cblx0XHQvLyBTb3J0IG9uIG1ldGhvZCBleGlzdGVuY2UgaWYgb25seSBvbmUgaW5wdXQgaGFzIGNvbXBhcmVEb2N1bWVudFBvc2l0aW9uXG5cdFx0dmFyIGNvbXBhcmUgPSAhYS5jb21wYXJlRG9jdW1lbnRQb3NpdGlvbiAtICFiLmNvbXBhcmVEb2N1bWVudFBvc2l0aW9uO1xuXHRcdGlmICggY29tcGFyZSApIHtcblx0XHRcdHJldHVybiBjb21wYXJlO1xuXHRcdH1cblxuXHRcdC8vIENhbGN1bGF0ZSBwb3NpdGlvbiBpZiBib3RoIGlucHV0cyBiZWxvbmcgdG8gdGhlIHNhbWUgZG9jdW1lbnRcblx0XHRjb21wYXJlID0gKCBhLm93bmVyRG9jdW1lbnQgfHwgYSApID09PSAoIGIub3duZXJEb2N1bWVudCB8fCBiICkgP1xuXHRcdFx0YS5jb21wYXJlRG9jdW1lbnRQb3NpdGlvbiggYiApIDpcblxuXHRcdFx0Ly8gT3RoZXJ3aXNlIHdlIGtub3cgdGhleSBhcmUgZGlzY29ubmVjdGVkXG5cdFx0XHQxO1xuXG5cdFx0Ly8gRGlzY29ubmVjdGVkIG5vZGVzXG5cdFx0aWYgKCBjb21wYXJlICYgMSB8fFxuXHRcdFx0KCFzdXBwb3J0LnNvcnREZXRhY2hlZCAmJiBiLmNvbXBhcmVEb2N1bWVudFBvc2l0aW9uKCBhICkgPT09IGNvbXBhcmUpICkge1xuXG5cdFx0XHQvLyBDaG9vc2UgdGhlIGZpcnN0IGVsZW1lbnQgdGhhdCBpcyByZWxhdGVkIHRvIG91ciBwcmVmZXJyZWQgZG9jdW1lbnRcblx0XHRcdGlmICggYSA9PT0gZG9jdW1lbnQgfHwgYS5vd25lckRvY3VtZW50ID09PSBwcmVmZXJyZWREb2MgJiYgY29udGFpbnMocHJlZmVycmVkRG9jLCBhKSApIHtcblx0XHRcdFx0cmV0dXJuIC0xO1xuXHRcdFx0fVxuXHRcdFx0aWYgKCBiID09PSBkb2N1bWVudCB8fCBiLm93bmVyRG9jdW1lbnQgPT09IHByZWZlcnJlZERvYyAmJiBjb250YWlucyhwcmVmZXJyZWREb2MsIGIpICkge1xuXHRcdFx0XHRyZXR1cm4gMTtcblx0XHRcdH1cblxuXHRcdFx0Ly8gTWFpbnRhaW4gb3JpZ2luYWwgb3JkZXJcblx0XHRcdHJldHVybiBzb3J0SW5wdXQgP1xuXHRcdFx0XHQoIGluZGV4T2YoIHNvcnRJbnB1dCwgYSApIC0gaW5kZXhPZiggc29ydElucHV0LCBiICkgKSA6XG5cdFx0XHRcdDA7XG5cdFx0fVxuXG5cdFx0cmV0dXJuIGNvbXBhcmUgJiA0ID8gLTEgOiAxO1xuXHR9IDpcblx0ZnVuY3Rpb24oIGEsIGIgKSB7XG5cdFx0Ly8gRXhpdCBlYXJseSBpZiB0aGUgbm9kZXMgYXJlIGlkZW50aWNhbFxuXHRcdGlmICggYSA9PT0gYiApIHtcblx0XHRcdGhhc0R1cGxpY2F0ZSA9IHRydWU7XG5cdFx0XHRyZXR1cm4gMDtcblx0XHR9XG5cblx0XHR2YXIgY3VyLFxuXHRcdFx0aSA9IDAsXG5cdFx0XHRhdXAgPSBhLnBhcmVudE5vZGUsXG5cdFx0XHRidXAgPSBiLnBhcmVudE5vZGUsXG5cdFx0XHRhcCA9IFsgYSBdLFxuXHRcdFx0YnAgPSBbIGIgXTtcblxuXHRcdC8vIFBhcmVudGxlc3Mgbm9kZXMgYXJlIGVpdGhlciBkb2N1bWVudHMgb3IgZGlzY29ubmVjdGVkXG5cdFx0aWYgKCAhYXVwIHx8ICFidXAgKSB7XG5cdFx0XHRyZXR1cm4gYSA9PT0gZG9jdW1lbnQgPyAtMSA6XG5cdFx0XHRcdGIgPT09IGRvY3VtZW50ID8gMSA6XG5cdFx0XHRcdGF1cCA/IC0xIDpcblx0XHRcdFx0YnVwID8gMSA6XG5cdFx0XHRcdHNvcnRJbnB1dCA/XG5cdFx0XHRcdCggaW5kZXhPZiggc29ydElucHV0LCBhICkgLSBpbmRleE9mKCBzb3J0SW5wdXQsIGIgKSApIDpcblx0XHRcdFx0MDtcblxuXHRcdC8vIElmIHRoZSBub2RlcyBhcmUgc2libGluZ3MsIHdlIGNhbiBkbyBhIHF1aWNrIGNoZWNrXG5cdFx0fSBlbHNlIGlmICggYXVwID09PSBidXAgKSB7XG5cdFx0XHRyZXR1cm4gc2libGluZ0NoZWNrKCBhLCBiICk7XG5cdFx0fVxuXG5cdFx0Ly8gT3RoZXJ3aXNlIHdlIG5lZWQgZnVsbCBsaXN0cyBvZiB0aGVpciBhbmNlc3RvcnMgZm9yIGNvbXBhcmlzb25cblx0XHRjdXIgPSBhO1xuXHRcdHdoaWxlICggKGN1ciA9IGN1ci5wYXJlbnROb2RlKSApIHtcblx0XHRcdGFwLnVuc2hpZnQoIGN1ciApO1xuXHRcdH1cblx0XHRjdXIgPSBiO1xuXHRcdHdoaWxlICggKGN1ciA9IGN1ci5wYXJlbnROb2RlKSApIHtcblx0XHRcdGJwLnVuc2hpZnQoIGN1ciApO1xuXHRcdH1cblxuXHRcdC8vIFdhbGsgZG93biB0aGUgdHJlZSBsb29raW5nIGZvciBhIGRpc2NyZXBhbmN5XG5cdFx0d2hpbGUgKCBhcFtpXSA9PT0gYnBbaV0gKSB7XG5cdFx0XHRpKys7XG5cdFx0fVxuXG5cdFx0cmV0dXJuIGkgP1xuXHRcdFx0Ly8gRG8gYSBzaWJsaW5nIGNoZWNrIGlmIHRoZSBub2RlcyBoYXZlIGEgY29tbW9uIGFuY2VzdG9yXG5cdFx0XHRzaWJsaW5nQ2hlY2soIGFwW2ldLCBicFtpXSApIDpcblxuXHRcdFx0Ly8gT3RoZXJ3aXNlIG5vZGVzIGluIG91ciBkb2N1bWVudCBzb3J0IGZpcnN0XG5cdFx0XHRhcFtpXSA9PT0gcHJlZmVycmVkRG9jID8gLTEgOlxuXHRcdFx0YnBbaV0gPT09IHByZWZlcnJlZERvYyA/IDEgOlxuXHRcdFx0MDtcblx0fTtcblxuXHRyZXR1cm4gZG9jdW1lbnQ7XG59O1xuXG5TaXp6bGUubWF0Y2hlcyA9IGZ1bmN0aW9uKCBleHByLCBlbGVtZW50cyApIHtcblx0cmV0dXJuIFNpenpsZSggZXhwciwgbnVsbCwgbnVsbCwgZWxlbWVudHMgKTtcbn07XG5cblNpenpsZS5tYXRjaGVzU2VsZWN0b3IgPSBmdW5jdGlvbiggZWxlbSwgZXhwciApIHtcblx0Ly8gU2V0IGRvY3VtZW50IHZhcnMgaWYgbmVlZGVkXG5cdGlmICggKCBlbGVtLm93bmVyRG9jdW1lbnQgfHwgZWxlbSApICE9PSBkb2N1bWVudCApIHtcblx0XHRzZXREb2N1bWVudCggZWxlbSApO1xuXHR9XG5cblx0Ly8gTWFrZSBzdXJlIHRoYXQgYXR0cmlidXRlIHNlbGVjdG9ycyBhcmUgcXVvdGVkXG5cdGV4cHIgPSBleHByLnJlcGxhY2UoIHJhdHRyaWJ1dGVRdW90ZXMsIFwiPSckMSddXCIgKTtcblxuXHRpZiAoIHN1cHBvcnQubWF0Y2hlc1NlbGVjdG9yICYmIGRvY3VtZW50SXNIVE1MICYmXG5cdFx0IWNvbXBpbGVyQ2FjaGVbIGV4cHIgKyBcIiBcIiBdICYmXG5cdFx0KCAhcmJ1Z2d5TWF0Y2hlcyB8fCAhcmJ1Z2d5TWF0Y2hlcy50ZXN0KCBleHByICkgKSAmJlxuXHRcdCggIXJidWdneVFTQSAgICAgfHwgIXJidWdneVFTQS50ZXN0KCBleHByICkgKSApIHtcblxuXHRcdHRyeSB7XG5cdFx0XHR2YXIgcmV0ID0gbWF0Y2hlcy5jYWxsKCBlbGVtLCBleHByICk7XG5cblx0XHRcdC8vIElFIDkncyBtYXRjaGVzU2VsZWN0b3IgcmV0dXJucyBmYWxzZSBvbiBkaXNjb25uZWN0ZWQgbm9kZXNcblx0XHRcdGlmICggcmV0IHx8IHN1cHBvcnQuZGlzY29ubmVjdGVkTWF0Y2ggfHxcblx0XHRcdFx0XHQvLyBBcyB3ZWxsLCBkaXNjb25uZWN0ZWQgbm9kZXMgYXJlIHNhaWQgdG8gYmUgaW4gYSBkb2N1bWVudFxuXHRcdFx0XHRcdC8vIGZyYWdtZW50IGluIElFIDlcblx0XHRcdFx0XHRlbGVtLmRvY3VtZW50ICYmIGVsZW0uZG9jdW1lbnQubm9kZVR5cGUgIT09IDExICkge1xuXHRcdFx0XHRyZXR1cm4gcmV0O1xuXHRcdFx0fVxuXHRcdH0gY2F0Y2ggKGUpIHt9XG5cdH1cblxuXHRyZXR1cm4gU2l6emxlKCBleHByLCBkb2N1bWVudCwgbnVsbCwgWyBlbGVtIF0gKS5sZW5ndGggPiAwO1xufTtcblxuU2l6emxlLmNvbnRhaW5zID0gZnVuY3Rpb24oIGNvbnRleHQsIGVsZW0gKSB7XG5cdC8vIFNldCBkb2N1bWVudCB2YXJzIGlmIG5lZWRlZFxuXHRpZiAoICggY29udGV4dC5vd25lckRvY3VtZW50IHx8IGNvbnRleHQgKSAhPT0gZG9jdW1lbnQgKSB7XG5cdFx0c2V0RG9jdW1lbnQoIGNvbnRleHQgKTtcblx0fVxuXHRyZXR1cm4gY29udGFpbnMoIGNvbnRleHQsIGVsZW0gKTtcbn07XG5cblNpenpsZS5hdHRyID0gZnVuY3Rpb24oIGVsZW0sIG5hbWUgKSB7XG5cdC8vIFNldCBkb2N1bWVudCB2YXJzIGlmIG5lZWRlZFxuXHRpZiAoICggZWxlbS5vd25lckRvY3VtZW50IHx8IGVsZW0gKSAhPT0gZG9jdW1lbnQgKSB7XG5cdFx0c2V0RG9jdW1lbnQoIGVsZW0gKTtcblx0fVxuXG5cdHZhciBmbiA9IEV4cHIuYXR0ckhhbmRsZVsgbmFtZS50b0xvd2VyQ2FzZSgpIF0sXG5cdFx0Ly8gRG9uJ3QgZ2V0IGZvb2xlZCBieSBPYmplY3QucHJvdG90eXBlIHByb3BlcnRpZXMgKGpRdWVyeSAjMTM4MDcpXG5cdFx0dmFsID0gZm4gJiYgaGFzT3duLmNhbGwoIEV4cHIuYXR0ckhhbmRsZSwgbmFtZS50b0xvd2VyQ2FzZSgpICkgP1xuXHRcdFx0Zm4oIGVsZW0sIG5hbWUsICFkb2N1bWVudElzSFRNTCApIDpcblx0XHRcdHVuZGVmaW5lZDtcblxuXHRyZXR1cm4gdmFsICE9PSB1bmRlZmluZWQgP1xuXHRcdHZhbCA6XG5cdFx0c3VwcG9ydC5hdHRyaWJ1dGVzIHx8ICFkb2N1bWVudElzSFRNTCA/XG5cdFx0XHRlbGVtLmdldEF0dHJpYnV0ZSggbmFtZSApIDpcblx0XHRcdCh2YWwgPSBlbGVtLmdldEF0dHJpYnV0ZU5vZGUobmFtZSkpICYmIHZhbC5zcGVjaWZpZWQgP1xuXHRcdFx0XHR2YWwudmFsdWUgOlxuXHRcdFx0XHRudWxsO1xufTtcblxuU2l6emxlLmVzY2FwZSA9IGZ1bmN0aW9uKCBzZWwgKSB7XG5cdHJldHVybiAoc2VsICsgXCJcIikucmVwbGFjZSggcmNzc2VzY2FwZSwgZmNzc2VzY2FwZSApO1xufTtcblxuU2l6emxlLmVycm9yID0gZnVuY3Rpb24oIG1zZyApIHtcblx0dGhyb3cgbmV3IEVycm9yKCBcIlN5bnRheCBlcnJvciwgdW5yZWNvZ25pemVkIGV4cHJlc3Npb246IFwiICsgbXNnICk7XG59O1xuXG4vKipcbiAqIERvY3VtZW50IHNvcnRpbmcgYW5kIHJlbW92aW5nIGR1cGxpY2F0ZXNcbiAqIEBwYXJhbSB7QXJyYXlMaWtlfSByZXN1bHRzXG4gKi9cblNpenpsZS51bmlxdWVTb3J0ID0gZnVuY3Rpb24oIHJlc3VsdHMgKSB7XG5cdHZhciBlbGVtLFxuXHRcdGR1cGxpY2F0ZXMgPSBbXSxcblx0XHRqID0gMCxcblx0XHRpID0gMDtcblxuXHQvLyBVbmxlc3Mgd2UgKmtub3cqIHdlIGNhbiBkZXRlY3QgZHVwbGljYXRlcywgYXNzdW1lIHRoZWlyIHByZXNlbmNlXG5cdGhhc0R1cGxpY2F0ZSA9ICFzdXBwb3J0LmRldGVjdER1cGxpY2F0ZXM7XG5cdHNvcnRJbnB1dCA9ICFzdXBwb3J0LnNvcnRTdGFibGUgJiYgcmVzdWx0cy5zbGljZSggMCApO1xuXHRyZXN1bHRzLnNvcnQoIHNvcnRPcmRlciApO1xuXG5cdGlmICggaGFzRHVwbGljYXRlICkge1xuXHRcdHdoaWxlICggKGVsZW0gPSByZXN1bHRzW2krK10pICkge1xuXHRcdFx0aWYgKCBlbGVtID09PSByZXN1bHRzWyBpIF0gKSB7XG5cdFx0XHRcdGogPSBkdXBsaWNhdGVzLnB1c2goIGkgKTtcblx0XHRcdH1cblx0XHR9XG5cdFx0d2hpbGUgKCBqLS0gKSB7XG5cdFx0XHRyZXN1bHRzLnNwbGljZSggZHVwbGljYXRlc1sgaiBdLCAxICk7XG5cdFx0fVxuXHR9XG5cblx0Ly8gQ2xlYXIgaW5wdXQgYWZ0ZXIgc29ydGluZyB0byByZWxlYXNlIG9iamVjdHNcblx0Ly8gU2VlIGh0dHBzOi8vZ2l0aHViLmNvbS9qcXVlcnkvc2l6emxlL3B1bGwvMjI1XG5cdHNvcnRJbnB1dCA9IG51bGw7XG5cblx0cmV0dXJuIHJlc3VsdHM7XG59O1xuXG4vKipcbiAqIFV0aWxpdHkgZnVuY3Rpb24gZm9yIHJldHJpZXZpbmcgdGhlIHRleHQgdmFsdWUgb2YgYW4gYXJyYXkgb2YgRE9NIG5vZGVzXG4gKiBAcGFyYW0ge0FycmF5fEVsZW1lbnR9IGVsZW1cbiAqL1xuZ2V0VGV4dCA9IFNpenpsZS5nZXRUZXh0ID0gZnVuY3Rpb24oIGVsZW0gKSB7XG5cdHZhciBub2RlLFxuXHRcdHJldCA9IFwiXCIsXG5cdFx0aSA9IDAsXG5cdFx0bm9kZVR5cGUgPSBlbGVtLm5vZGVUeXBlO1xuXG5cdGlmICggIW5vZGVUeXBlICkge1xuXHRcdC8vIElmIG5vIG5vZGVUeXBlLCB0aGlzIGlzIGV4cGVjdGVkIHRvIGJlIGFuIGFycmF5XG5cdFx0d2hpbGUgKCAobm9kZSA9IGVsZW1baSsrXSkgKSB7XG5cdFx0XHQvLyBEbyBub3QgdHJhdmVyc2UgY29tbWVudCBub2Rlc1xuXHRcdFx0cmV0ICs9IGdldFRleHQoIG5vZGUgKTtcblx0XHR9XG5cdH0gZWxzZSBpZiAoIG5vZGVUeXBlID09PSAxIHx8IG5vZGVUeXBlID09PSA5IHx8IG5vZGVUeXBlID09PSAxMSApIHtcblx0XHQvLyBVc2UgdGV4dENvbnRlbnQgZm9yIGVsZW1lbnRzXG5cdFx0Ly8gaW5uZXJUZXh0IHVzYWdlIHJlbW92ZWQgZm9yIGNvbnNpc3RlbmN5IG9mIG5ldyBsaW5lcyAoalF1ZXJ5ICMxMTE1Mylcblx0XHRpZiAoIHR5cGVvZiBlbGVtLnRleHRDb250ZW50ID09PSBcInN0cmluZ1wiICkge1xuXHRcdFx0cmV0dXJuIGVsZW0udGV4dENvbnRlbnQ7XG5cdFx0fSBlbHNlIHtcblx0XHRcdC8vIFRyYXZlcnNlIGl0cyBjaGlsZHJlblxuXHRcdFx0Zm9yICggZWxlbSA9IGVsZW0uZmlyc3RDaGlsZDsgZWxlbTsgZWxlbSA9IGVsZW0ubmV4dFNpYmxpbmcgKSB7XG5cdFx0XHRcdHJldCArPSBnZXRUZXh0KCBlbGVtICk7XG5cdFx0XHR9XG5cdFx0fVxuXHR9IGVsc2UgaWYgKCBub2RlVHlwZSA9PT0gMyB8fCBub2RlVHlwZSA9PT0gNCApIHtcblx0XHRyZXR1cm4gZWxlbS5ub2RlVmFsdWU7XG5cdH1cblx0Ly8gRG8gbm90IGluY2x1ZGUgY29tbWVudCBvciBwcm9jZXNzaW5nIGluc3RydWN0aW9uIG5vZGVzXG5cblx0cmV0dXJuIHJldDtcbn07XG5cbkV4cHIgPSBTaXp6bGUuc2VsZWN0b3JzID0ge1xuXG5cdC8vIENhbiBiZSBhZGp1c3RlZCBieSB0aGUgdXNlclxuXHRjYWNoZUxlbmd0aDogNTAsXG5cblx0Y3JlYXRlUHNldWRvOiBtYXJrRnVuY3Rpb24sXG5cblx0bWF0Y2g6IG1hdGNoRXhwcixcblxuXHRhdHRySGFuZGxlOiB7fSxcblxuXHRmaW5kOiB7fSxcblxuXHRyZWxhdGl2ZToge1xuXHRcdFwiPlwiOiB7IGRpcjogXCJwYXJlbnROb2RlXCIsIGZpcnN0OiB0cnVlIH0sXG5cdFx0XCIgXCI6IHsgZGlyOiBcInBhcmVudE5vZGVcIiB9LFxuXHRcdFwiK1wiOiB7IGRpcjogXCJwcmV2aW91c1NpYmxpbmdcIiwgZmlyc3Q6IHRydWUgfSxcblx0XHRcIn5cIjogeyBkaXI6IFwicHJldmlvdXNTaWJsaW5nXCIgfVxuXHR9LFxuXG5cdHByZUZpbHRlcjoge1xuXHRcdFwiQVRUUlwiOiBmdW5jdGlvbiggbWF0Y2ggKSB7XG5cdFx0XHRtYXRjaFsxXSA9IG1hdGNoWzFdLnJlcGxhY2UoIHJ1bmVzY2FwZSwgZnVuZXNjYXBlICk7XG5cblx0XHRcdC8vIE1vdmUgdGhlIGdpdmVuIHZhbHVlIHRvIG1hdGNoWzNdIHdoZXRoZXIgcXVvdGVkIG9yIHVucXVvdGVkXG5cdFx0XHRtYXRjaFszXSA9ICggbWF0Y2hbM10gfHwgbWF0Y2hbNF0gfHwgbWF0Y2hbNV0gfHwgXCJcIiApLnJlcGxhY2UoIHJ1bmVzY2FwZSwgZnVuZXNjYXBlICk7XG5cblx0XHRcdGlmICggbWF0Y2hbMl0gPT09IFwifj1cIiApIHtcblx0XHRcdFx0bWF0Y2hbM10gPSBcIiBcIiArIG1hdGNoWzNdICsgXCIgXCI7XG5cdFx0XHR9XG5cblx0XHRcdHJldHVybiBtYXRjaC5zbGljZSggMCwgNCApO1xuXHRcdH0sXG5cblx0XHRcIkNISUxEXCI6IGZ1bmN0aW9uKCBtYXRjaCApIHtcblx0XHRcdC8qIG1hdGNoZXMgZnJvbSBtYXRjaEV4cHJbXCJDSElMRFwiXVxuXHRcdFx0XHQxIHR5cGUgKG9ubHl8bnRofC4uLilcblx0XHRcdFx0MiB3aGF0IChjaGlsZHxvZi10eXBlKVxuXHRcdFx0XHQzIGFyZ3VtZW50IChldmVufG9kZHxcXGQqfFxcZCpuKFsrLV1cXGQrKT98Li4uKVxuXHRcdFx0XHQ0IHhuLWNvbXBvbmVudCBvZiB4bit5IGFyZ3VtZW50IChbKy1dP1xcZCpufClcblx0XHRcdFx0NSBzaWduIG9mIHhuLWNvbXBvbmVudFxuXHRcdFx0XHQ2IHggb2YgeG4tY29tcG9uZW50XG5cdFx0XHRcdDcgc2lnbiBvZiB5LWNvbXBvbmVudFxuXHRcdFx0XHQ4IHkgb2YgeS1jb21wb25lbnRcblx0XHRcdCovXG5cdFx0XHRtYXRjaFsxXSA9IG1hdGNoWzFdLnRvTG93ZXJDYXNlKCk7XG5cblx0XHRcdGlmICggbWF0Y2hbMV0uc2xpY2UoIDAsIDMgKSA9PT0gXCJudGhcIiApIHtcblx0XHRcdFx0Ly8gbnRoLSogcmVxdWlyZXMgYXJndW1lbnRcblx0XHRcdFx0aWYgKCAhbWF0Y2hbM10gKSB7XG5cdFx0XHRcdFx0U2l6emxlLmVycm9yKCBtYXRjaFswXSApO1xuXHRcdFx0XHR9XG5cblx0XHRcdFx0Ly8gbnVtZXJpYyB4IGFuZCB5IHBhcmFtZXRlcnMgZm9yIEV4cHIuZmlsdGVyLkNISUxEXG5cdFx0XHRcdC8vIHJlbWVtYmVyIHRoYXQgZmFsc2UvdHJ1ZSBjYXN0IHJlc3BlY3RpdmVseSB0byAwLzFcblx0XHRcdFx0bWF0Y2hbNF0gPSArKCBtYXRjaFs0XSA/IG1hdGNoWzVdICsgKG1hdGNoWzZdIHx8IDEpIDogMiAqICggbWF0Y2hbM10gPT09IFwiZXZlblwiIHx8IG1hdGNoWzNdID09PSBcIm9kZFwiICkgKTtcblx0XHRcdFx0bWF0Y2hbNV0gPSArKCAoIG1hdGNoWzddICsgbWF0Y2hbOF0gKSB8fCBtYXRjaFszXSA9PT0gXCJvZGRcIiApO1xuXG5cdFx0XHQvLyBvdGhlciB0eXBlcyBwcm9oaWJpdCBhcmd1bWVudHNcblx0XHRcdH0gZWxzZSBpZiAoIG1hdGNoWzNdICkge1xuXHRcdFx0XHRTaXp6bGUuZXJyb3IoIG1hdGNoWzBdICk7XG5cdFx0XHR9XG5cblx0XHRcdHJldHVybiBtYXRjaDtcblx0XHR9LFxuXG5cdFx0XCJQU0VVRE9cIjogZnVuY3Rpb24oIG1hdGNoICkge1xuXHRcdFx0dmFyIGV4Y2Vzcyxcblx0XHRcdFx0dW5xdW90ZWQgPSAhbWF0Y2hbNl0gJiYgbWF0Y2hbMl07XG5cblx0XHRcdGlmICggbWF0Y2hFeHByW1wiQ0hJTERcIl0udGVzdCggbWF0Y2hbMF0gKSApIHtcblx0XHRcdFx0cmV0dXJuIG51bGw7XG5cdFx0XHR9XG5cblx0XHRcdC8vIEFjY2VwdCBxdW90ZWQgYXJndW1lbnRzIGFzLWlzXG5cdFx0XHRpZiAoIG1hdGNoWzNdICkge1xuXHRcdFx0XHRtYXRjaFsyXSA9IG1hdGNoWzRdIHx8IG1hdGNoWzVdIHx8IFwiXCI7XG5cblx0XHRcdC8vIFN0cmlwIGV4Y2VzcyBjaGFyYWN0ZXJzIGZyb20gdW5xdW90ZWQgYXJndW1lbnRzXG5cdFx0XHR9IGVsc2UgaWYgKCB1bnF1b3RlZCAmJiBycHNldWRvLnRlc3QoIHVucXVvdGVkICkgJiZcblx0XHRcdFx0Ly8gR2V0IGV4Y2VzcyBmcm9tIHRva2VuaXplIChyZWN1cnNpdmVseSlcblx0XHRcdFx0KGV4Y2VzcyA9IHRva2VuaXplKCB1bnF1b3RlZCwgdHJ1ZSApKSAmJlxuXHRcdFx0XHQvLyBhZHZhbmNlIHRvIHRoZSBuZXh0IGNsb3NpbmcgcGFyZW50aGVzaXNcblx0XHRcdFx0KGV4Y2VzcyA9IHVucXVvdGVkLmluZGV4T2YoIFwiKVwiLCB1bnF1b3RlZC5sZW5ndGggLSBleGNlc3MgKSAtIHVucXVvdGVkLmxlbmd0aCkgKSB7XG5cblx0XHRcdFx0Ly8gZXhjZXNzIGlzIGEgbmVnYXRpdmUgaW5kZXhcblx0XHRcdFx0bWF0Y2hbMF0gPSBtYXRjaFswXS5zbGljZSggMCwgZXhjZXNzICk7XG5cdFx0XHRcdG1hdGNoWzJdID0gdW5xdW90ZWQuc2xpY2UoIDAsIGV4Y2VzcyApO1xuXHRcdFx0fVxuXG5cdFx0XHQvLyBSZXR1cm4gb25seSBjYXB0dXJlcyBuZWVkZWQgYnkgdGhlIHBzZXVkbyBmaWx0ZXIgbWV0aG9kICh0eXBlIGFuZCBhcmd1bWVudClcblx0XHRcdHJldHVybiBtYXRjaC5zbGljZSggMCwgMyApO1xuXHRcdH1cblx0fSxcblxuXHRmaWx0ZXI6IHtcblxuXHRcdFwiVEFHXCI6IGZ1bmN0aW9uKCBub2RlTmFtZVNlbGVjdG9yICkge1xuXHRcdFx0dmFyIG5vZGVOYW1lID0gbm9kZU5hbWVTZWxlY3Rvci5yZXBsYWNlKCBydW5lc2NhcGUsIGZ1bmVzY2FwZSApLnRvTG93ZXJDYXNlKCk7XG5cdFx0XHRyZXR1cm4gbm9kZU5hbWVTZWxlY3RvciA9PT0gXCIqXCIgP1xuXHRcdFx0XHRmdW5jdGlvbigpIHsgcmV0dXJuIHRydWU7IH0gOlxuXHRcdFx0XHRmdW5jdGlvbiggZWxlbSApIHtcblx0XHRcdFx0XHRyZXR1cm4gZWxlbS5ub2RlTmFtZSAmJiBlbGVtLm5vZGVOYW1lLnRvTG93ZXJDYXNlKCkgPT09IG5vZGVOYW1lO1xuXHRcdFx0XHR9O1xuXHRcdH0sXG5cblx0XHRcIkNMQVNTXCI6IGZ1bmN0aW9uKCBjbGFzc05hbWUgKSB7XG5cdFx0XHR2YXIgcGF0dGVybiA9IGNsYXNzQ2FjaGVbIGNsYXNzTmFtZSArIFwiIFwiIF07XG5cblx0XHRcdHJldHVybiBwYXR0ZXJuIHx8XG5cdFx0XHRcdChwYXR0ZXJuID0gbmV3IFJlZ0V4cCggXCIoXnxcIiArIHdoaXRlc3BhY2UgKyBcIilcIiArIGNsYXNzTmFtZSArIFwiKFwiICsgd2hpdGVzcGFjZSArIFwifCQpXCIgKSkgJiZcblx0XHRcdFx0Y2xhc3NDYWNoZSggY2xhc3NOYW1lLCBmdW5jdGlvbiggZWxlbSApIHtcblx0XHRcdFx0XHRyZXR1cm4gcGF0dGVybi50ZXN0KCB0eXBlb2YgZWxlbS5jbGFzc05hbWUgPT09IFwic3RyaW5nXCIgJiYgZWxlbS5jbGFzc05hbWUgfHwgdHlwZW9mIGVsZW0uZ2V0QXR0cmlidXRlICE9PSBcInVuZGVmaW5lZFwiICYmIGVsZW0uZ2V0QXR0cmlidXRlKFwiY2xhc3NcIikgfHwgXCJcIiApO1xuXHRcdFx0XHR9KTtcblx0XHR9LFxuXG5cdFx0XCJBVFRSXCI6IGZ1bmN0aW9uKCBuYW1lLCBvcGVyYXRvciwgY2hlY2sgKSB7XG5cdFx0XHRyZXR1cm4gZnVuY3Rpb24oIGVsZW0gKSB7XG5cdFx0XHRcdHZhciByZXN1bHQgPSBTaXp6bGUuYXR0ciggZWxlbSwgbmFtZSApO1xuXG5cdFx0XHRcdGlmICggcmVzdWx0ID09IG51bGwgKSB7XG5cdFx0XHRcdFx0cmV0dXJuIG9wZXJhdG9yID09PSBcIiE9XCI7XG5cdFx0XHRcdH1cblx0XHRcdFx0aWYgKCAhb3BlcmF0b3IgKSB7XG5cdFx0XHRcdFx0cmV0dXJuIHRydWU7XG5cdFx0XHRcdH1cblxuXHRcdFx0XHRyZXN1bHQgKz0gXCJcIjtcblxuXHRcdFx0XHRyZXR1cm4gb3BlcmF0b3IgPT09IFwiPVwiID8gcmVzdWx0ID09PSBjaGVjayA6XG5cdFx0XHRcdFx0b3BlcmF0b3IgPT09IFwiIT1cIiA/IHJlc3VsdCAhPT0gY2hlY2sgOlxuXHRcdFx0XHRcdG9wZXJhdG9yID09PSBcIl49XCIgPyBjaGVjayAmJiByZXN1bHQuaW5kZXhPZiggY2hlY2sgKSA9PT0gMCA6XG5cdFx0XHRcdFx0b3BlcmF0b3IgPT09IFwiKj1cIiA/IGNoZWNrICYmIHJlc3VsdC5pbmRleE9mKCBjaGVjayApID4gLTEgOlxuXHRcdFx0XHRcdG9wZXJhdG9yID09PSBcIiQ9XCIgPyBjaGVjayAmJiByZXN1bHQuc2xpY2UoIC1jaGVjay5sZW5ndGggKSA9PT0gY2hlY2sgOlxuXHRcdFx0XHRcdG9wZXJhdG9yID09PSBcIn49XCIgPyAoIFwiIFwiICsgcmVzdWx0LnJlcGxhY2UoIHJ3aGl0ZXNwYWNlLCBcIiBcIiApICsgXCIgXCIgKS5pbmRleE9mKCBjaGVjayApID4gLTEgOlxuXHRcdFx0XHRcdG9wZXJhdG9yID09PSBcInw9XCIgPyByZXN1bHQgPT09IGNoZWNrIHx8IHJlc3VsdC5zbGljZSggMCwgY2hlY2subGVuZ3RoICsgMSApID09PSBjaGVjayArIFwiLVwiIDpcblx0XHRcdFx0XHRmYWxzZTtcblx0XHRcdH07XG5cdFx0fSxcblxuXHRcdFwiQ0hJTERcIjogZnVuY3Rpb24oIHR5cGUsIHdoYXQsIGFyZ3VtZW50LCBmaXJzdCwgbGFzdCApIHtcblx0XHRcdHZhciBzaW1wbGUgPSB0eXBlLnNsaWNlKCAwLCAzICkgIT09IFwibnRoXCIsXG5cdFx0XHRcdGZvcndhcmQgPSB0eXBlLnNsaWNlKCAtNCApICE9PSBcImxhc3RcIixcblx0XHRcdFx0b2ZUeXBlID0gd2hhdCA9PT0gXCJvZi10eXBlXCI7XG5cblx0XHRcdHJldHVybiBmaXJzdCA9PT0gMSAmJiBsYXN0ID09PSAwID9cblxuXHRcdFx0XHQvLyBTaG9ydGN1dCBmb3IgOm50aC0qKG4pXG5cdFx0XHRcdGZ1bmN0aW9uKCBlbGVtICkge1xuXHRcdFx0XHRcdHJldHVybiAhIWVsZW0ucGFyZW50Tm9kZTtcblx0XHRcdFx0fSA6XG5cblx0XHRcdFx0ZnVuY3Rpb24oIGVsZW0sIGNvbnRleHQsIHhtbCApIHtcblx0XHRcdFx0XHR2YXIgY2FjaGUsIHVuaXF1ZUNhY2hlLCBvdXRlckNhY2hlLCBub2RlLCBub2RlSW5kZXgsIHN0YXJ0LFxuXHRcdFx0XHRcdFx0ZGlyID0gc2ltcGxlICE9PSBmb3J3YXJkID8gXCJuZXh0U2libGluZ1wiIDogXCJwcmV2aW91c1NpYmxpbmdcIixcblx0XHRcdFx0XHRcdHBhcmVudCA9IGVsZW0ucGFyZW50Tm9kZSxcblx0XHRcdFx0XHRcdG5hbWUgPSBvZlR5cGUgJiYgZWxlbS5ub2RlTmFtZS50b0xvd2VyQ2FzZSgpLFxuXHRcdFx0XHRcdFx0dXNlQ2FjaGUgPSAheG1sICYmICFvZlR5cGUsXG5cdFx0XHRcdFx0XHRkaWZmID0gZmFsc2U7XG5cblx0XHRcdFx0XHRpZiAoIHBhcmVudCApIHtcblxuXHRcdFx0XHRcdFx0Ly8gOihmaXJzdHxsYXN0fG9ubHkpLShjaGlsZHxvZi10eXBlKVxuXHRcdFx0XHRcdFx0aWYgKCBzaW1wbGUgKSB7XG5cdFx0XHRcdFx0XHRcdHdoaWxlICggZGlyICkge1xuXHRcdFx0XHRcdFx0XHRcdG5vZGUgPSBlbGVtO1xuXHRcdFx0XHRcdFx0XHRcdHdoaWxlICggKG5vZGUgPSBub2RlWyBkaXIgXSkgKSB7XG5cdFx0XHRcdFx0XHRcdFx0XHRpZiAoIG9mVHlwZSA/XG5cdFx0XHRcdFx0XHRcdFx0XHRcdG5vZGUubm9kZU5hbWUudG9Mb3dlckNhc2UoKSA9PT0gbmFtZSA6XG5cdFx0XHRcdFx0XHRcdFx0XHRcdG5vZGUubm9kZVR5cGUgPT09IDEgKSB7XG5cblx0XHRcdFx0XHRcdFx0XHRcdFx0cmV0dXJuIGZhbHNlO1xuXHRcdFx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdFx0XHQvLyBSZXZlcnNlIGRpcmVjdGlvbiBmb3IgOm9ubHktKiAoaWYgd2UgaGF2ZW4ndCB5ZXQgZG9uZSBzbylcblx0XHRcdFx0XHRcdFx0XHRzdGFydCA9IGRpciA9IHR5cGUgPT09IFwib25seVwiICYmICFzdGFydCAmJiBcIm5leHRTaWJsaW5nXCI7XG5cdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdFx0cmV0dXJuIHRydWU7XG5cdFx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHRcdHN0YXJ0ID0gWyBmb3J3YXJkID8gcGFyZW50LmZpcnN0Q2hpbGQgOiBwYXJlbnQubGFzdENoaWxkIF07XG5cblx0XHRcdFx0XHRcdC8vIG5vbi14bWwgOm50aC1jaGlsZCguLi4pIHN0b3JlcyBjYWNoZSBkYXRhIG9uIGBwYXJlbnRgXG5cdFx0XHRcdFx0XHRpZiAoIGZvcndhcmQgJiYgdXNlQ2FjaGUgKSB7XG5cblx0XHRcdFx0XHRcdFx0Ly8gU2VlayBgZWxlbWAgZnJvbSBhIHByZXZpb3VzbHktY2FjaGVkIGluZGV4XG5cblx0XHRcdFx0XHRcdFx0Ly8gLi4uaW4gYSBnemlwLWZyaWVuZGx5IHdheVxuXHRcdFx0XHRcdFx0XHRub2RlID0gcGFyZW50O1xuXHRcdFx0XHRcdFx0XHRvdXRlckNhY2hlID0gbm9kZVsgZXhwYW5kbyBdIHx8IChub2RlWyBleHBhbmRvIF0gPSB7fSk7XG5cblx0XHRcdFx0XHRcdFx0Ly8gU3VwcG9ydDogSUUgPDkgb25seVxuXHRcdFx0XHRcdFx0XHQvLyBEZWZlbmQgYWdhaW5zdCBjbG9uZWQgYXR0cm9wZXJ0aWVzIChqUXVlcnkgZ2gtMTcwOSlcblx0XHRcdFx0XHRcdFx0dW5pcXVlQ2FjaGUgPSBvdXRlckNhY2hlWyBub2RlLnVuaXF1ZUlEIF0gfHxcblx0XHRcdFx0XHRcdFx0XHQob3V0ZXJDYWNoZVsgbm9kZS51bmlxdWVJRCBdID0ge30pO1xuXG5cdFx0XHRcdFx0XHRcdGNhY2hlID0gdW5pcXVlQ2FjaGVbIHR5cGUgXSB8fCBbXTtcblx0XHRcdFx0XHRcdFx0bm9kZUluZGV4ID0gY2FjaGVbIDAgXSA9PT0gZGlycnVucyAmJiBjYWNoZVsgMSBdO1xuXHRcdFx0XHRcdFx0XHRkaWZmID0gbm9kZUluZGV4ICYmIGNhY2hlWyAyIF07XG5cdFx0XHRcdFx0XHRcdG5vZGUgPSBub2RlSW5kZXggJiYgcGFyZW50LmNoaWxkTm9kZXNbIG5vZGVJbmRleCBdO1xuXG5cdFx0XHRcdFx0XHRcdHdoaWxlICggKG5vZGUgPSArK25vZGVJbmRleCAmJiBub2RlICYmIG5vZGVbIGRpciBdIHx8XG5cblx0XHRcdFx0XHRcdFx0XHQvLyBGYWxsYmFjayB0byBzZWVraW5nIGBlbGVtYCBmcm9tIHRoZSBzdGFydFxuXHRcdFx0XHRcdFx0XHRcdChkaWZmID0gbm9kZUluZGV4ID0gMCkgfHwgc3RhcnQucG9wKCkpICkge1xuXG5cdFx0XHRcdFx0XHRcdFx0Ly8gV2hlbiBmb3VuZCwgY2FjaGUgaW5kZXhlcyBvbiBgcGFyZW50YCBhbmQgYnJlYWtcblx0XHRcdFx0XHRcdFx0XHRpZiAoIG5vZGUubm9kZVR5cGUgPT09IDEgJiYgKytkaWZmICYmIG5vZGUgPT09IGVsZW0gKSB7XG5cdFx0XHRcdFx0XHRcdFx0XHR1bmlxdWVDYWNoZVsgdHlwZSBdID0gWyBkaXJydW5zLCBub2RlSW5kZXgsIGRpZmYgXTtcblx0XHRcdFx0XHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdFx0XHQvLyBVc2UgcHJldmlvdXNseS1jYWNoZWQgZWxlbWVudCBpbmRleCBpZiBhdmFpbGFibGVcblx0XHRcdFx0XHRcdFx0aWYgKCB1c2VDYWNoZSApIHtcblx0XHRcdFx0XHRcdFx0XHQvLyAuLi5pbiBhIGd6aXAtZnJpZW5kbHkgd2F5XG5cdFx0XHRcdFx0XHRcdFx0bm9kZSA9IGVsZW07XG5cdFx0XHRcdFx0XHRcdFx0b3V0ZXJDYWNoZSA9IG5vZGVbIGV4cGFuZG8gXSB8fCAobm9kZVsgZXhwYW5kbyBdID0ge30pO1xuXG5cdFx0XHRcdFx0XHRcdFx0Ly8gU3VwcG9ydDogSUUgPDkgb25seVxuXHRcdFx0XHRcdFx0XHRcdC8vIERlZmVuZCBhZ2FpbnN0IGNsb25lZCBhdHRyb3BlcnRpZXMgKGpRdWVyeSBnaC0xNzA5KVxuXHRcdFx0XHRcdFx0XHRcdHVuaXF1ZUNhY2hlID0gb3V0ZXJDYWNoZVsgbm9kZS51bmlxdWVJRCBdIHx8XG5cdFx0XHRcdFx0XHRcdFx0XHQob3V0ZXJDYWNoZVsgbm9kZS51bmlxdWVJRCBdID0ge30pO1xuXG5cdFx0XHRcdFx0XHRcdFx0Y2FjaGUgPSB1bmlxdWVDYWNoZVsgdHlwZSBdIHx8IFtdO1xuXHRcdFx0XHRcdFx0XHRcdG5vZGVJbmRleCA9IGNhY2hlWyAwIF0gPT09IGRpcnJ1bnMgJiYgY2FjaGVbIDEgXTtcblx0XHRcdFx0XHRcdFx0XHRkaWZmID0gbm9kZUluZGV4O1xuXHRcdFx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHRcdFx0Ly8geG1sIDpudGgtY2hpbGQoLi4uKVxuXHRcdFx0XHRcdFx0XHQvLyBvciA6bnRoLWxhc3QtY2hpbGQoLi4uKSBvciA6bnRoKC1sYXN0KT8tb2YtdHlwZSguLi4pXG5cdFx0XHRcdFx0XHRcdGlmICggZGlmZiA9PT0gZmFsc2UgKSB7XG5cdFx0XHRcdFx0XHRcdFx0Ly8gVXNlIHRoZSBzYW1lIGxvb3AgYXMgYWJvdmUgdG8gc2VlayBgZWxlbWAgZnJvbSB0aGUgc3RhcnRcblx0XHRcdFx0XHRcdFx0XHR3aGlsZSAoIChub2RlID0gKytub2RlSW5kZXggJiYgbm9kZSAmJiBub2RlWyBkaXIgXSB8fFxuXHRcdFx0XHRcdFx0XHRcdFx0KGRpZmYgPSBub2RlSW5kZXggPSAwKSB8fCBzdGFydC5wb3AoKSkgKSB7XG5cblx0XHRcdFx0XHRcdFx0XHRcdGlmICggKCBvZlR5cGUgP1xuXHRcdFx0XHRcdFx0XHRcdFx0XHRub2RlLm5vZGVOYW1lLnRvTG93ZXJDYXNlKCkgPT09IG5hbWUgOlxuXHRcdFx0XHRcdFx0XHRcdFx0XHRub2RlLm5vZGVUeXBlID09PSAxICkgJiZcblx0XHRcdFx0XHRcdFx0XHRcdFx0KytkaWZmICkge1xuXG5cdFx0XHRcdFx0XHRcdFx0XHRcdC8vIENhY2hlIHRoZSBpbmRleCBvZiBlYWNoIGVuY291bnRlcmVkIGVsZW1lbnRcblx0XHRcdFx0XHRcdFx0XHRcdFx0aWYgKCB1c2VDYWNoZSApIHtcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRvdXRlckNhY2hlID0gbm9kZVsgZXhwYW5kbyBdIHx8IChub2RlWyBleHBhbmRvIF0gPSB7fSk7XG5cblx0XHRcdFx0XHRcdFx0XHRcdFx0XHQvLyBTdXBwb3J0OiBJRSA8OSBvbmx5XG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0Ly8gRGVmZW5kIGFnYWluc3QgY2xvbmVkIGF0dHJvcGVydGllcyAoalF1ZXJ5IGdoLTE3MDkpXG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0dW5pcXVlQ2FjaGUgPSBvdXRlckNhY2hlWyBub2RlLnVuaXF1ZUlEIF0gfHxcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdChvdXRlckNhY2hlWyBub2RlLnVuaXF1ZUlEIF0gPSB7fSk7XG5cblx0XHRcdFx0XHRcdFx0XHRcdFx0XHR1bmlxdWVDYWNoZVsgdHlwZSBdID0gWyBkaXJydW5zLCBkaWZmIF07XG5cdFx0XHRcdFx0XHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdFx0XHRcdFx0XHRpZiAoIG5vZGUgPT09IGVsZW0gKSB7XG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHRcdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdFx0Ly8gSW5jb3Jwb3JhdGUgdGhlIG9mZnNldCwgdGhlbiBjaGVjayBhZ2FpbnN0IGN5Y2xlIHNpemVcblx0XHRcdFx0XHRcdGRpZmYgLT0gbGFzdDtcblx0XHRcdFx0XHRcdHJldHVybiBkaWZmID09PSBmaXJzdCB8fCAoIGRpZmYgJSBmaXJzdCA9PT0gMCAmJiBkaWZmIC8gZmlyc3QgPj0gMCApO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fTtcblx0XHR9LFxuXG5cdFx0XCJQU0VVRE9cIjogZnVuY3Rpb24oIHBzZXVkbywgYXJndW1lbnQgKSB7XG5cdFx0XHQvLyBwc2V1ZG8tY2xhc3MgbmFtZXMgYXJlIGNhc2UtaW5zZW5zaXRpdmVcblx0XHRcdC8vIGh0dHA6Ly93d3cudzMub3JnL1RSL3NlbGVjdG9ycy8jcHNldWRvLWNsYXNzZXNcblx0XHRcdC8vIFByaW9yaXRpemUgYnkgY2FzZSBzZW5zaXRpdml0eSBpbiBjYXNlIGN1c3RvbSBwc2V1ZG9zIGFyZSBhZGRlZCB3aXRoIHVwcGVyY2FzZSBsZXR0ZXJzXG5cdFx0XHQvLyBSZW1lbWJlciB0aGF0IHNldEZpbHRlcnMgaW5oZXJpdHMgZnJvbSBwc2V1ZG9zXG5cdFx0XHR2YXIgYXJncyxcblx0XHRcdFx0Zm4gPSBFeHByLnBzZXVkb3NbIHBzZXVkbyBdIHx8IEV4cHIuc2V0RmlsdGVyc1sgcHNldWRvLnRvTG93ZXJDYXNlKCkgXSB8fFxuXHRcdFx0XHRcdFNpenpsZS5lcnJvciggXCJ1bnN1cHBvcnRlZCBwc2V1ZG86IFwiICsgcHNldWRvICk7XG5cblx0XHRcdC8vIFRoZSB1c2VyIG1heSB1c2UgY3JlYXRlUHNldWRvIHRvIGluZGljYXRlIHRoYXRcblx0XHRcdC8vIGFyZ3VtZW50cyBhcmUgbmVlZGVkIHRvIGNyZWF0ZSB0aGUgZmlsdGVyIGZ1bmN0aW9uXG5cdFx0XHQvLyBqdXN0IGFzIFNpenpsZSBkb2VzXG5cdFx0XHRpZiAoIGZuWyBleHBhbmRvIF0gKSB7XG5cdFx0XHRcdHJldHVybiBmbiggYXJndW1lbnQgKTtcblx0XHRcdH1cblxuXHRcdFx0Ly8gQnV0IG1haW50YWluIHN1cHBvcnQgZm9yIG9sZCBzaWduYXR1cmVzXG5cdFx0XHRpZiAoIGZuLmxlbmd0aCA+IDEgKSB7XG5cdFx0XHRcdGFyZ3MgPSBbIHBzZXVkbywgcHNldWRvLCBcIlwiLCBhcmd1bWVudCBdO1xuXHRcdFx0XHRyZXR1cm4gRXhwci5zZXRGaWx0ZXJzLmhhc093blByb3BlcnR5KCBwc2V1ZG8udG9Mb3dlckNhc2UoKSApID9cblx0XHRcdFx0XHRtYXJrRnVuY3Rpb24oZnVuY3Rpb24oIHNlZWQsIG1hdGNoZXMgKSB7XG5cdFx0XHRcdFx0XHR2YXIgaWR4LFxuXHRcdFx0XHRcdFx0XHRtYXRjaGVkID0gZm4oIHNlZWQsIGFyZ3VtZW50ICksXG5cdFx0XHRcdFx0XHRcdGkgPSBtYXRjaGVkLmxlbmd0aDtcblx0XHRcdFx0XHRcdHdoaWxlICggaS0tICkge1xuXHRcdFx0XHRcdFx0XHRpZHggPSBpbmRleE9mKCBzZWVkLCBtYXRjaGVkW2ldICk7XG5cdFx0XHRcdFx0XHRcdHNlZWRbIGlkeCBdID0gISggbWF0Y2hlc1sgaWR4IF0gPSBtYXRjaGVkW2ldICk7XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0fSkgOlxuXHRcdFx0XHRcdGZ1bmN0aW9uKCBlbGVtICkge1xuXHRcdFx0XHRcdFx0cmV0dXJuIGZuKCBlbGVtLCAwLCBhcmdzICk7XG5cdFx0XHRcdFx0fTtcblx0XHRcdH1cblxuXHRcdFx0cmV0dXJuIGZuO1xuXHRcdH1cblx0fSxcblxuXHRwc2V1ZG9zOiB7XG5cdFx0Ly8gUG90ZW50aWFsbHkgY29tcGxleCBwc2V1ZG9zXG5cdFx0XCJub3RcIjogbWFya0Z1bmN0aW9uKGZ1bmN0aW9uKCBzZWxlY3RvciApIHtcblx0XHRcdC8vIFRyaW0gdGhlIHNlbGVjdG9yIHBhc3NlZCB0byBjb21waWxlXG5cdFx0XHQvLyB0byBhdm9pZCB0cmVhdGluZyBsZWFkaW5nIGFuZCB0cmFpbGluZ1xuXHRcdFx0Ly8gc3BhY2VzIGFzIGNvbWJpbmF0b3JzXG5cdFx0XHR2YXIgaW5wdXQgPSBbXSxcblx0XHRcdFx0cmVzdWx0cyA9IFtdLFxuXHRcdFx0XHRtYXRjaGVyID0gY29tcGlsZSggc2VsZWN0b3IucmVwbGFjZSggcnRyaW0sIFwiJDFcIiApICk7XG5cblx0XHRcdHJldHVybiBtYXRjaGVyWyBleHBhbmRvIF0gP1xuXHRcdFx0XHRtYXJrRnVuY3Rpb24oZnVuY3Rpb24oIHNlZWQsIG1hdGNoZXMsIGNvbnRleHQsIHhtbCApIHtcblx0XHRcdFx0XHR2YXIgZWxlbSxcblx0XHRcdFx0XHRcdHVubWF0Y2hlZCA9IG1hdGNoZXIoIHNlZWQsIG51bGwsIHhtbCwgW10gKSxcblx0XHRcdFx0XHRcdGkgPSBzZWVkLmxlbmd0aDtcblxuXHRcdFx0XHRcdC8vIE1hdGNoIGVsZW1lbnRzIHVubWF0Y2hlZCBieSBgbWF0Y2hlcmBcblx0XHRcdFx0XHR3aGlsZSAoIGktLSApIHtcblx0XHRcdFx0XHRcdGlmICggKGVsZW0gPSB1bm1hdGNoZWRbaV0pICkge1xuXHRcdFx0XHRcdFx0XHRzZWVkW2ldID0gIShtYXRjaGVzW2ldID0gZWxlbSk7XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9KSA6XG5cdFx0XHRcdGZ1bmN0aW9uKCBlbGVtLCBjb250ZXh0LCB4bWwgKSB7XG5cdFx0XHRcdFx0aW5wdXRbMF0gPSBlbGVtO1xuXHRcdFx0XHRcdG1hdGNoZXIoIGlucHV0LCBudWxsLCB4bWwsIHJlc3VsdHMgKTtcblx0XHRcdFx0XHQvLyBEb24ndCBrZWVwIHRoZSBlbGVtZW50IChpc3N1ZSAjMjk5KVxuXHRcdFx0XHRcdGlucHV0WzBdID0gbnVsbDtcblx0XHRcdFx0XHRyZXR1cm4gIXJlc3VsdHMucG9wKCk7XG5cdFx0XHRcdH07XG5cdFx0fSksXG5cblx0XHRcImhhc1wiOiBtYXJrRnVuY3Rpb24oZnVuY3Rpb24oIHNlbGVjdG9yICkge1xuXHRcdFx0cmV0dXJuIGZ1bmN0aW9uKCBlbGVtICkge1xuXHRcdFx0XHRyZXR1cm4gU2l6emxlKCBzZWxlY3RvciwgZWxlbSApLmxlbmd0aCA+IDA7XG5cdFx0XHR9O1xuXHRcdH0pLFxuXG5cdFx0XCJjb250YWluc1wiOiBtYXJrRnVuY3Rpb24oZnVuY3Rpb24oIHRleHQgKSB7XG5cdFx0XHR0ZXh0ID0gdGV4dC5yZXBsYWNlKCBydW5lc2NhcGUsIGZ1bmVzY2FwZSApO1xuXHRcdFx0cmV0dXJuIGZ1bmN0aW9uKCBlbGVtICkge1xuXHRcdFx0XHRyZXR1cm4gKCBlbGVtLnRleHRDb250ZW50IHx8IGVsZW0uaW5uZXJUZXh0IHx8IGdldFRleHQoIGVsZW0gKSApLmluZGV4T2YoIHRleHQgKSA+IC0xO1xuXHRcdFx0fTtcblx0XHR9KSxcblxuXHRcdC8vIFwiV2hldGhlciBhbiBlbGVtZW50IGlzIHJlcHJlc2VudGVkIGJ5IGEgOmxhbmcoKSBzZWxlY3RvclxuXHRcdC8vIGlzIGJhc2VkIHNvbGVseSBvbiB0aGUgZWxlbWVudCdzIGxhbmd1YWdlIHZhbHVlXG5cdFx0Ly8gYmVpbmcgZXF1YWwgdG8gdGhlIGlkZW50aWZpZXIgQyxcblx0XHQvLyBvciBiZWdpbm5pbmcgd2l0aCB0aGUgaWRlbnRpZmllciBDIGltbWVkaWF0ZWx5IGZvbGxvd2VkIGJ5IFwiLVwiLlxuXHRcdC8vIFRoZSBtYXRjaGluZyBvZiBDIGFnYWluc3QgdGhlIGVsZW1lbnQncyBsYW5ndWFnZSB2YWx1ZSBpcyBwZXJmb3JtZWQgY2FzZS1pbnNlbnNpdGl2ZWx5LlxuXHRcdC8vIFRoZSBpZGVudGlmaWVyIEMgZG9lcyBub3QgaGF2ZSB0byBiZSBhIHZhbGlkIGxhbmd1YWdlIG5hbWUuXCJcblx0XHQvLyBodHRwOi8vd3d3LnczLm9yZy9UUi9zZWxlY3RvcnMvI2xhbmctcHNldWRvXG5cdFx0XCJsYW5nXCI6IG1hcmtGdW5jdGlvbiggZnVuY3Rpb24oIGxhbmcgKSB7XG5cdFx0XHQvLyBsYW5nIHZhbHVlIG11c3QgYmUgYSB2YWxpZCBpZGVudGlmaWVyXG5cdFx0XHRpZiAoICFyaWRlbnRpZmllci50ZXN0KGxhbmcgfHwgXCJcIikgKSB7XG5cdFx0XHRcdFNpenpsZS5lcnJvciggXCJ1bnN1cHBvcnRlZCBsYW5nOiBcIiArIGxhbmcgKTtcblx0XHRcdH1cblx0XHRcdGxhbmcgPSBsYW5nLnJlcGxhY2UoIHJ1bmVzY2FwZSwgZnVuZXNjYXBlICkudG9Mb3dlckNhc2UoKTtcblx0XHRcdHJldHVybiBmdW5jdGlvbiggZWxlbSApIHtcblx0XHRcdFx0dmFyIGVsZW1MYW5nO1xuXHRcdFx0XHRkbyB7XG5cdFx0XHRcdFx0aWYgKCAoZWxlbUxhbmcgPSBkb2N1bWVudElzSFRNTCA/XG5cdFx0XHRcdFx0XHRlbGVtLmxhbmcgOlxuXHRcdFx0XHRcdFx0ZWxlbS5nZXRBdHRyaWJ1dGUoXCJ4bWw6bGFuZ1wiKSB8fCBlbGVtLmdldEF0dHJpYnV0ZShcImxhbmdcIikpICkge1xuXG5cdFx0XHRcdFx0XHRlbGVtTGFuZyA9IGVsZW1MYW5nLnRvTG93ZXJDYXNlKCk7XG5cdFx0XHRcdFx0XHRyZXR1cm4gZWxlbUxhbmcgPT09IGxhbmcgfHwgZWxlbUxhbmcuaW5kZXhPZiggbGFuZyArIFwiLVwiICkgPT09IDA7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9IHdoaWxlICggKGVsZW0gPSBlbGVtLnBhcmVudE5vZGUpICYmIGVsZW0ubm9kZVR5cGUgPT09IDEgKTtcblx0XHRcdFx0cmV0dXJuIGZhbHNlO1xuXHRcdFx0fTtcblx0XHR9KSxcblxuXHRcdC8vIE1pc2NlbGxhbmVvdXNcblx0XHRcInRhcmdldFwiOiBmdW5jdGlvbiggZWxlbSApIHtcblx0XHRcdHZhciBoYXNoID0gd2luZG93LmxvY2F0aW9uICYmIHdpbmRvdy5sb2NhdGlvbi5oYXNoO1xuXHRcdFx0cmV0dXJuIGhhc2ggJiYgaGFzaC5zbGljZSggMSApID09PSBlbGVtLmlkO1xuXHRcdH0sXG5cblx0XHRcInJvb3RcIjogZnVuY3Rpb24oIGVsZW0gKSB7XG5cdFx0XHRyZXR1cm4gZWxlbSA9PT0gZG9jRWxlbTtcblx0XHR9LFxuXG5cdFx0XCJmb2N1c1wiOiBmdW5jdGlvbiggZWxlbSApIHtcblx0XHRcdHJldHVybiBlbGVtID09PSBkb2N1bWVudC5hY3RpdmVFbGVtZW50ICYmICghZG9jdW1lbnQuaGFzRm9jdXMgfHwgZG9jdW1lbnQuaGFzRm9jdXMoKSkgJiYgISEoZWxlbS50eXBlIHx8IGVsZW0uaHJlZiB8fCB+ZWxlbS50YWJJbmRleCk7XG5cdFx0fSxcblxuXHRcdC8vIEJvb2xlYW4gcHJvcGVydGllc1xuXHRcdFwiZW5hYmxlZFwiOiBjcmVhdGVEaXNhYmxlZFBzZXVkbyggZmFsc2UgKSxcblx0XHRcImRpc2FibGVkXCI6IGNyZWF0ZURpc2FibGVkUHNldWRvKCB0cnVlICksXG5cblx0XHRcImNoZWNrZWRcIjogZnVuY3Rpb24oIGVsZW0gKSB7XG5cdFx0XHQvLyBJbiBDU1MzLCA6Y2hlY2tlZCBzaG91bGQgcmV0dXJuIGJvdGggY2hlY2tlZCBhbmQgc2VsZWN0ZWQgZWxlbWVudHNcblx0XHRcdC8vIGh0dHA6Ly93d3cudzMub3JnL1RSLzIwMTEvUkVDLWNzczMtc2VsZWN0b3JzLTIwMTEwOTI5LyNjaGVja2VkXG5cdFx0XHR2YXIgbm9kZU5hbWUgPSBlbGVtLm5vZGVOYW1lLnRvTG93ZXJDYXNlKCk7XG5cdFx0XHRyZXR1cm4gKG5vZGVOYW1lID09PSBcImlucHV0XCIgJiYgISFlbGVtLmNoZWNrZWQpIHx8IChub2RlTmFtZSA9PT0gXCJvcHRpb25cIiAmJiAhIWVsZW0uc2VsZWN0ZWQpO1xuXHRcdH0sXG5cblx0XHRcInNlbGVjdGVkXCI6IGZ1bmN0aW9uKCBlbGVtICkge1xuXHRcdFx0Ly8gQWNjZXNzaW5nIHRoaXMgcHJvcGVydHkgbWFrZXMgc2VsZWN0ZWQtYnktZGVmYXVsdFxuXHRcdFx0Ly8gb3B0aW9ucyBpbiBTYWZhcmkgd29yayBwcm9wZXJseVxuXHRcdFx0aWYgKCBlbGVtLnBhcmVudE5vZGUgKSB7XG5cdFx0XHRcdGVsZW0ucGFyZW50Tm9kZS5zZWxlY3RlZEluZGV4O1xuXHRcdFx0fVxuXG5cdFx0XHRyZXR1cm4gZWxlbS5zZWxlY3RlZCA9PT0gdHJ1ZTtcblx0XHR9LFxuXG5cdFx0Ly8gQ29udGVudHNcblx0XHRcImVtcHR5XCI6IGZ1bmN0aW9uKCBlbGVtICkge1xuXHRcdFx0Ly8gaHR0cDovL3d3dy53My5vcmcvVFIvc2VsZWN0b3JzLyNlbXB0eS1wc2V1ZG9cblx0XHRcdC8vIDplbXB0eSBpcyBuZWdhdGVkIGJ5IGVsZW1lbnQgKDEpIG9yIGNvbnRlbnQgbm9kZXMgKHRleHQ6IDM7IGNkYXRhOiA0OyBlbnRpdHkgcmVmOiA1KSxcblx0XHRcdC8vICAgYnV0IG5vdCBieSBvdGhlcnMgKGNvbW1lbnQ6IDg7IHByb2Nlc3NpbmcgaW5zdHJ1Y3Rpb246IDc7IGV0Yy4pXG5cdFx0XHQvLyBub2RlVHlwZSA8IDYgd29ya3MgYmVjYXVzZSBhdHRyaWJ1dGVzICgyKSBkbyBub3QgYXBwZWFyIGFzIGNoaWxkcmVuXG5cdFx0XHRmb3IgKCBlbGVtID0gZWxlbS5maXJzdENoaWxkOyBlbGVtOyBlbGVtID0gZWxlbS5uZXh0U2libGluZyApIHtcblx0XHRcdFx0aWYgKCBlbGVtLm5vZGVUeXBlIDwgNiApIHtcblx0XHRcdFx0XHRyZXR1cm4gZmFsc2U7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHRcdHJldHVybiB0cnVlO1xuXHRcdH0sXG5cblx0XHRcInBhcmVudFwiOiBmdW5jdGlvbiggZWxlbSApIHtcblx0XHRcdHJldHVybiAhRXhwci5wc2V1ZG9zW1wiZW1wdHlcIl0oIGVsZW0gKTtcblx0XHR9LFxuXG5cdFx0Ly8gRWxlbWVudC9pbnB1dCB0eXBlc1xuXHRcdFwiaGVhZGVyXCI6IGZ1bmN0aW9uKCBlbGVtICkge1xuXHRcdFx0cmV0dXJuIHJoZWFkZXIudGVzdCggZWxlbS5ub2RlTmFtZSApO1xuXHRcdH0sXG5cblx0XHRcImlucHV0XCI6IGZ1bmN0aW9uKCBlbGVtICkge1xuXHRcdFx0cmV0dXJuIHJpbnB1dHMudGVzdCggZWxlbS5ub2RlTmFtZSApO1xuXHRcdH0sXG5cblx0XHRcImJ1dHRvblwiOiBmdW5jdGlvbiggZWxlbSApIHtcblx0XHRcdHZhciBuYW1lID0gZWxlbS5ub2RlTmFtZS50b0xvd2VyQ2FzZSgpO1xuXHRcdFx0cmV0dXJuIG5hbWUgPT09IFwiaW5wdXRcIiAmJiBlbGVtLnR5cGUgPT09IFwiYnV0dG9uXCIgfHwgbmFtZSA9PT0gXCJidXR0b25cIjtcblx0XHR9LFxuXG5cdFx0XCJ0ZXh0XCI6IGZ1bmN0aW9uKCBlbGVtICkge1xuXHRcdFx0dmFyIGF0dHI7XG5cdFx0XHRyZXR1cm4gZWxlbS5ub2RlTmFtZS50b0xvd2VyQ2FzZSgpID09PSBcImlucHV0XCIgJiZcblx0XHRcdFx0ZWxlbS50eXBlID09PSBcInRleHRcIiAmJlxuXG5cdFx0XHRcdC8vIFN1cHBvcnQ6IElFPDhcblx0XHRcdFx0Ly8gTmV3IEhUTUw1IGF0dHJpYnV0ZSB2YWx1ZXMgKGUuZy4sIFwic2VhcmNoXCIpIGFwcGVhciB3aXRoIGVsZW0udHlwZSA9PT0gXCJ0ZXh0XCJcblx0XHRcdFx0KCAoYXR0ciA9IGVsZW0uZ2V0QXR0cmlidXRlKFwidHlwZVwiKSkgPT0gbnVsbCB8fCBhdHRyLnRvTG93ZXJDYXNlKCkgPT09IFwidGV4dFwiICk7XG5cdFx0fSxcblxuXHRcdC8vIFBvc2l0aW9uLWluLWNvbGxlY3Rpb25cblx0XHRcImZpcnN0XCI6IGNyZWF0ZVBvc2l0aW9uYWxQc2V1ZG8oZnVuY3Rpb24oKSB7XG5cdFx0XHRyZXR1cm4gWyAwIF07XG5cdFx0fSksXG5cblx0XHRcImxhc3RcIjogY3JlYXRlUG9zaXRpb25hbFBzZXVkbyhmdW5jdGlvbiggbWF0Y2hJbmRleGVzLCBsZW5ndGggKSB7XG5cdFx0XHRyZXR1cm4gWyBsZW5ndGggLSAxIF07XG5cdFx0fSksXG5cblx0XHRcImVxXCI6IGNyZWF0ZVBvc2l0aW9uYWxQc2V1ZG8oZnVuY3Rpb24oIG1hdGNoSW5kZXhlcywgbGVuZ3RoLCBhcmd1bWVudCApIHtcblx0XHRcdHJldHVybiBbIGFyZ3VtZW50IDwgMCA/IGFyZ3VtZW50ICsgbGVuZ3RoIDogYXJndW1lbnQgXTtcblx0XHR9KSxcblxuXHRcdFwiZXZlblwiOiBjcmVhdGVQb3NpdGlvbmFsUHNldWRvKGZ1bmN0aW9uKCBtYXRjaEluZGV4ZXMsIGxlbmd0aCApIHtcblx0XHRcdHZhciBpID0gMDtcblx0XHRcdGZvciAoIDsgaSA8IGxlbmd0aDsgaSArPSAyICkge1xuXHRcdFx0XHRtYXRjaEluZGV4ZXMucHVzaCggaSApO1xuXHRcdFx0fVxuXHRcdFx0cmV0dXJuIG1hdGNoSW5kZXhlcztcblx0XHR9KSxcblxuXHRcdFwib2RkXCI6IGNyZWF0ZVBvc2l0aW9uYWxQc2V1ZG8oZnVuY3Rpb24oIG1hdGNoSW5kZXhlcywgbGVuZ3RoICkge1xuXHRcdFx0dmFyIGkgPSAxO1xuXHRcdFx0Zm9yICggOyBpIDwgbGVuZ3RoOyBpICs9IDIgKSB7XG5cdFx0XHRcdG1hdGNoSW5kZXhlcy5wdXNoKCBpICk7XG5cdFx0XHR9XG5cdFx0XHRyZXR1cm4gbWF0Y2hJbmRleGVzO1xuXHRcdH0pLFxuXG5cdFx0XCJsdFwiOiBjcmVhdGVQb3NpdGlvbmFsUHNldWRvKGZ1bmN0aW9uKCBtYXRjaEluZGV4ZXMsIGxlbmd0aCwgYXJndW1lbnQgKSB7XG5cdFx0XHR2YXIgaSA9IGFyZ3VtZW50IDwgMCA/IGFyZ3VtZW50ICsgbGVuZ3RoIDogYXJndW1lbnQ7XG5cdFx0XHRmb3IgKCA7IC0taSA+PSAwOyApIHtcblx0XHRcdFx0bWF0Y2hJbmRleGVzLnB1c2goIGkgKTtcblx0XHRcdH1cblx0XHRcdHJldHVybiBtYXRjaEluZGV4ZXM7XG5cdFx0fSksXG5cblx0XHRcImd0XCI6IGNyZWF0ZVBvc2l0aW9uYWxQc2V1ZG8oZnVuY3Rpb24oIG1hdGNoSW5kZXhlcywgbGVuZ3RoLCBhcmd1bWVudCApIHtcblx0XHRcdHZhciBpID0gYXJndW1lbnQgPCAwID8gYXJndW1lbnQgKyBsZW5ndGggOiBhcmd1bWVudDtcblx0XHRcdGZvciAoIDsgKytpIDwgbGVuZ3RoOyApIHtcblx0XHRcdFx0bWF0Y2hJbmRleGVzLnB1c2goIGkgKTtcblx0XHRcdH1cblx0XHRcdHJldHVybiBtYXRjaEluZGV4ZXM7XG5cdFx0fSlcblx0fVxufTtcblxuRXhwci5wc2V1ZG9zW1wibnRoXCJdID0gRXhwci5wc2V1ZG9zW1wiZXFcIl07XG5cbi8vIEFkZCBidXR0b24vaW5wdXQgdHlwZSBwc2V1ZG9zXG5mb3IgKCBpIGluIHsgcmFkaW86IHRydWUsIGNoZWNrYm94OiB0cnVlLCBmaWxlOiB0cnVlLCBwYXNzd29yZDogdHJ1ZSwgaW1hZ2U6IHRydWUgfSApIHtcblx0RXhwci5wc2V1ZG9zWyBpIF0gPSBjcmVhdGVJbnB1dFBzZXVkbyggaSApO1xufVxuZm9yICggaSBpbiB7IHN1Ym1pdDogdHJ1ZSwgcmVzZXQ6IHRydWUgfSApIHtcblx0RXhwci5wc2V1ZG9zWyBpIF0gPSBjcmVhdGVCdXR0b25Qc2V1ZG8oIGkgKTtcbn1cblxuLy8gRWFzeSBBUEkgZm9yIGNyZWF0aW5nIG5ldyBzZXRGaWx0ZXJzXG5mdW5jdGlvbiBzZXRGaWx0ZXJzKCkge31cbnNldEZpbHRlcnMucHJvdG90eXBlID0gRXhwci5maWx0ZXJzID0gRXhwci5wc2V1ZG9zO1xuRXhwci5zZXRGaWx0ZXJzID0gbmV3IHNldEZpbHRlcnMoKTtcblxudG9rZW5pemUgPSBTaXp6bGUudG9rZW5pemUgPSBmdW5jdGlvbiggc2VsZWN0b3IsIHBhcnNlT25seSApIHtcblx0dmFyIG1hdGNoZWQsIG1hdGNoLCB0b2tlbnMsIHR5cGUsXG5cdFx0c29GYXIsIGdyb3VwcywgcHJlRmlsdGVycyxcblx0XHRjYWNoZWQgPSB0b2tlbkNhY2hlWyBzZWxlY3RvciArIFwiIFwiIF07XG5cblx0aWYgKCBjYWNoZWQgKSB7XG5cdFx0cmV0dXJuIHBhcnNlT25seSA/IDAgOiBjYWNoZWQuc2xpY2UoIDAgKTtcblx0fVxuXG5cdHNvRmFyID0gc2VsZWN0b3I7XG5cdGdyb3VwcyA9IFtdO1xuXHRwcmVGaWx0ZXJzID0gRXhwci5wcmVGaWx0ZXI7XG5cblx0d2hpbGUgKCBzb0ZhciApIHtcblxuXHRcdC8vIENvbW1hIGFuZCBmaXJzdCBydW5cblx0XHRpZiAoICFtYXRjaGVkIHx8IChtYXRjaCA9IHJjb21tYS5leGVjKCBzb0ZhciApKSApIHtcblx0XHRcdGlmICggbWF0Y2ggKSB7XG5cdFx0XHRcdC8vIERvbid0IGNvbnN1bWUgdHJhaWxpbmcgY29tbWFzIGFzIHZhbGlkXG5cdFx0XHRcdHNvRmFyID0gc29GYXIuc2xpY2UoIG1hdGNoWzBdLmxlbmd0aCApIHx8IHNvRmFyO1xuXHRcdFx0fVxuXHRcdFx0Z3JvdXBzLnB1c2goICh0b2tlbnMgPSBbXSkgKTtcblx0XHR9XG5cblx0XHRtYXRjaGVkID0gZmFsc2U7XG5cblx0XHQvLyBDb21iaW5hdG9yc1xuXHRcdGlmICggKG1hdGNoID0gcmNvbWJpbmF0b3JzLmV4ZWMoIHNvRmFyICkpICkge1xuXHRcdFx0bWF0Y2hlZCA9IG1hdGNoLnNoaWZ0KCk7XG5cdFx0XHR0b2tlbnMucHVzaCh7XG5cdFx0XHRcdHZhbHVlOiBtYXRjaGVkLFxuXHRcdFx0XHQvLyBDYXN0IGRlc2NlbmRhbnQgY29tYmluYXRvcnMgdG8gc3BhY2Vcblx0XHRcdFx0dHlwZTogbWF0Y2hbMF0ucmVwbGFjZSggcnRyaW0sIFwiIFwiIClcblx0XHRcdH0pO1xuXHRcdFx0c29GYXIgPSBzb0Zhci5zbGljZSggbWF0Y2hlZC5sZW5ndGggKTtcblx0XHR9XG5cblx0XHQvLyBGaWx0ZXJzXG5cdFx0Zm9yICggdHlwZSBpbiBFeHByLmZpbHRlciApIHtcblx0XHRcdGlmICggKG1hdGNoID0gbWF0Y2hFeHByWyB0eXBlIF0uZXhlYyggc29GYXIgKSkgJiYgKCFwcmVGaWx0ZXJzWyB0eXBlIF0gfHxcblx0XHRcdFx0KG1hdGNoID0gcHJlRmlsdGVyc1sgdHlwZSBdKCBtYXRjaCApKSkgKSB7XG5cdFx0XHRcdG1hdGNoZWQgPSBtYXRjaC5zaGlmdCgpO1xuXHRcdFx0XHR0b2tlbnMucHVzaCh7XG5cdFx0XHRcdFx0dmFsdWU6IG1hdGNoZWQsXG5cdFx0XHRcdFx0dHlwZTogdHlwZSxcblx0XHRcdFx0XHRtYXRjaGVzOiBtYXRjaFxuXHRcdFx0XHR9KTtcblx0XHRcdFx0c29GYXIgPSBzb0Zhci5zbGljZSggbWF0Y2hlZC5sZW5ndGggKTtcblx0XHRcdH1cblx0XHR9XG5cblx0XHRpZiAoICFtYXRjaGVkICkge1xuXHRcdFx0YnJlYWs7XG5cdFx0fVxuXHR9XG5cblx0Ly8gUmV0dXJuIHRoZSBsZW5ndGggb2YgdGhlIGludmFsaWQgZXhjZXNzXG5cdC8vIGlmIHdlJ3JlIGp1c3QgcGFyc2luZ1xuXHQvLyBPdGhlcndpc2UsIHRocm93IGFuIGVycm9yIG9yIHJldHVybiB0b2tlbnNcblx0cmV0dXJuIHBhcnNlT25seSA/XG5cdFx0c29GYXIubGVuZ3RoIDpcblx0XHRzb0ZhciA/XG5cdFx0XHRTaXp6bGUuZXJyb3IoIHNlbGVjdG9yICkgOlxuXHRcdFx0Ly8gQ2FjaGUgdGhlIHRva2Vuc1xuXHRcdFx0dG9rZW5DYWNoZSggc2VsZWN0b3IsIGdyb3VwcyApLnNsaWNlKCAwICk7XG59O1xuXG5mdW5jdGlvbiB0b1NlbGVjdG9yKCB0b2tlbnMgKSB7XG5cdHZhciBpID0gMCxcblx0XHRsZW4gPSB0b2tlbnMubGVuZ3RoLFxuXHRcdHNlbGVjdG9yID0gXCJcIjtcblx0Zm9yICggOyBpIDwgbGVuOyBpKysgKSB7XG5cdFx0c2VsZWN0b3IgKz0gdG9rZW5zW2ldLnZhbHVlO1xuXHR9XG5cdHJldHVybiBzZWxlY3Rvcjtcbn1cblxuZnVuY3Rpb24gYWRkQ29tYmluYXRvciggbWF0Y2hlciwgY29tYmluYXRvciwgYmFzZSApIHtcblx0dmFyIGRpciA9IGNvbWJpbmF0b3IuZGlyLFxuXHRcdHNraXAgPSBjb21iaW5hdG9yLm5leHQsXG5cdFx0a2V5ID0gc2tpcCB8fCBkaXIsXG5cdFx0Y2hlY2tOb25FbGVtZW50cyA9IGJhc2UgJiYga2V5ID09PSBcInBhcmVudE5vZGVcIixcblx0XHRkb25lTmFtZSA9IGRvbmUrKztcblxuXHRyZXR1cm4gY29tYmluYXRvci5maXJzdCA/XG5cdFx0Ly8gQ2hlY2sgYWdhaW5zdCBjbG9zZXN0IGFuY2VzdG9yL3ByZWNlZGluZyBlbGVtZW50XG5cdFx0ZnVuY3Rpb24oIGVsZW0sIGNvbnRleHQsIHhtbCApIHtcblx0XHRcdHdoaWxlICggKGVsZW0gPSBlbGVtWyBkaXIgXSkgKSB7XG5cdFx0XHRcdGlmICggZWxlbS5ub2RlVHlwZSA9PT0gMSB8fCBjaGVja05vbkVsZW1lbnRzICkge1xuXHRcdFx0XHRcdHJldHVybiBtYXRjaGVyKCBlbGVtLCBjb250ZXh0LCB4bWwgKTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdFx0cmV0dXJuIGZhbHNlO1xuXHRcdH0gOlxuXG5cdFx0Ly8gQ2hlY2sgYWdhaW5zdCBhbGwgYW5jZXN0b3IvcHJlY2VkaW5nIGVsZW1lbnRzXG5cdFx0ZnVuY3Rpb24oIGVsZW0sIGNvbnRleHQsIHhtbCApIHtcblx0XHRcdHZhciBvbGRDYWNoZSwgdW5pcXVlQ2FjaGUsIG91dGVyQ2FjaGUsXG5cdFx0XHRcdG5ld0NhY2hlID0gWyBkaXJydW5zLCBkb25lTmFtZSBdO1xuXG5cdFx0XHQvLyBXZSBjYW4ndCBzZXQgYXJiaXRyYXJ5IGRhdGEgb24gWE1MIG5vZGVzLCBzbyB0aGV5IGRvbid0IGJlbmVmaXQgZnJvbSBjb21iaW5hdG9yIGNhY2hpbmdcblx0XHRcdGlmICggeG1sICkge1xuXHRcdFx0XHR3aGlsZSAoIChlbGVtID0gZWxlbVsgZGlyIF0pICkge1xuXHRcdFx0XHRcdGlmICggZWxlbS5ub2RlVHlwZSA9PT0gMSB8fCBjaGVja05vbkVsZW1lbnRzICkge1xuXHRcdFx0XHRcdFx0aWYgKCBtYXRjaGVyKCBlbGVtLCBjb250ZXh0LCB4bWwgKSApIHtcblx0XHRcdFx0XHRcdFx0cmV0dXJuIHRydWU7XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHR3aGlsZSAoIChlbGVtID0gZWxlbVsgZGlyIF0pICkge1xuXHRcdFx0XHRcdGlmICggZWxlbS5ub2RlVHlwZSA9PT0gMSB8fCBjaGVja05vbkVsZW1lbnRzICkge1xuXHRcdFx0XHRcdFx0b3V0ZXJDYWNoZSA9IGVsZW1bIGV4cGFuZG8gXSB8fCAoZWxlbVsgZXhwYW5kbyBdID0ge30pO1xuXG5cdFx0XHRcdFx0XHQvLyBTdXBwb3J0OiBJRSA8OSBvbmx5XG5cdFx0XHRcdFx0XHQvLyBEZWZlbmQgYWdhaW5zdCBjbG9uZWQgYXR0cm9wZXJ0aWVzIChqUXVlcnkgZ2gtMTcwOSlcblx0XHRcdFx0XHRcdHVuaXF1ZUNhY2hlID0gb3V0ZXJDYWNoZVsgZWxlbS51bmlxdWVJRCBdIHx8IChvdXRlckNhY2hlWyBlbGVtLnVuaXF1ZUlEIF0gPSB7fSk7XG5cblx0XHRcdFx0XHRcdGlmICggc2tpcCAmJiBza2lwID09PSBlbGVtLm5vZGVOYW1lLnRvTG93ZXJDYXNlKCkgKSB7XG5cdFx0XHRcdFx0XHRcdGVsZW0gPSBlbGVtWyBkaXIgXSB8fCBlbGVtO1xuXHRcdFx0XHRcdFx0fSBlbHNlIGlmICggKG9sZENhY2hlID0gdW5pcXVlQ2FjaGVbIGtleSBdKSAmJlxuXHRcdFx0XHRcdFx0XHRvbGRDYWNoZVsgMCBdID09PSBkaXJydW5zICYmIG9sZENhY2hlWyAxIF0gPT09IGRvbmVOYW1lICkge1xuXG5cdFx0XHRcdFx0XHRcdC8vIEFzc2lnbiB0byBuZXdDYWNoZSBzbyByZXN1bHRzIGJhY2stcHJvcGFnYXRlIHRvIHByZXZpb3VzIGVsZW1lbnRzXG5cdFx0XHRcdFx0XHRcdHJldHVybiAobmV3Q2FjaGVbIDIgXSA9IG9sZENhY2hlWyAyIF0pO1xuXHRcdFx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRcdFx0Ly8gUmV1c2UgbmV3Y2FjaGUgc28gcmVzdWx0cyBiYWNrLXByb3BhZ2F0ZSB0byBwcmV2aW91cyBlbGVtZW50c1xuXHRcdFx0XHRcdFx0XHR1bmlxdWVDYWNoZVsga2V5IF0gPSBuZXdDYWNoZTtcblxuXHRcdFx0XHRcdFx0XHQvLyBBIG1hdGNoIG1lYW5zIHdlJ3JlIGRvbmU7IGEgZmFpbCBtZWFucyB3ZSBoYXZlIHRvIGtlZXAgY2hlY2tpbmdcblx0XHRcdFx0XHRcdFx0aWYgKCAobmV3Q2FjaGVbIDIgXSA9IG1hdGNoZXIoIGVsZW0sIGNvbnRleHQsIHhtbCApKSApIHtcblx0XHRcdFx0XHRcdFx0XHRyZXR1cm4gdHJ1ZTtcblx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdFx0cmV0dXJuIGZhbHNlO1xuXHRcdH07XG59XG5cbmZ1bmN0aW9uIGVsZW1lbnRNYXRjaGVyKCBtYXRjaGVycyApIHtcblx0cmV0dXJuIG1hdGNoZXJzLmxlbmd0aCA+IDEgP1xuXHRcdGZ1bmN0aW9uKCBlbGVtLCBjb250ZXh0LCB4bWwgKSB7XG5cdFx0XHR2YXIgaSA9IG1hdGNoZXJzLmxlbmd0aDtcblx0XHRcdHdoaWxlICggaS0tICkge1xuXHRcdFx0XHRpZiAoICFtYXRjaGVyc1tpXSggZWxlbSwgY29udGV4dCwgeG1sICkgKSB7XG5cdFx0XHRcdFx0cmV0dXJuIGZhbHNlO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0XHRyZXR1cm4gdHJ1ZTtcblx0XHR9IDpcblx0XHRtYXRjaGVyc1swXTtcbn1cblxuZnVuY3Rpb24gbXVsdGlwbGVDb250ZXh0cyggc2VsZWN0b3IsIGNvbnRleHRzLCByZXN1bHRzICkge1xuXHR2YXIgaSA9IDAsXG5cdFx0bGVuID0gY29udGV4dHMubGVuZ3RoO1xuXHRmb3IgKCA7IGkgPCBsZW47IGkrKyApIHtcblx0XHRTaXp6bGUoIHNlbGVjdG9yLCBjb250ZXh0c1tpXSwgcmVzdWx0cyApO1xuXHR9XG5cdHJldHVybiByZXN1bHRzO1xufVxuXG5mdW5jdGlvbiBjb25kZW5zZSggdW5tYXRjaGVkLCBtYXAsIGZpbHRlciwgY29udGV4dCwgeG1sICkge1xuXHR2YXIgZWxlbSxcblx0XHRuZXdVbm1hdGNoZWQgPSBbXSxcblx0XHRpID0gMCxcblx0XHRsZW4gPSB1bm1hdGNoZWQubGVuZ3RoLFxuXHRcdG1hcHBlZCA9IG1hcCAhPSBudWxsO1xuXG5cdGZvciAoIDsgaSA8IGxlbjsgaSsrICkge1xuXHRcdGlmICggKGVsZW0gPSB1bm1hdGNoZWRbaV0pICkge1xuXHRcdFx0aWYgKCAhZmlsdGVyIHx8IGZpbHRlciggZWxlbSwgY29udGV4dCwgeG1sICkgKSB7XG5cdFx0XHRcdG5ld1VubWF0Y2hlZC5wdXNoKCBlbGVtICk7XG5cdFx0XHRcdGlmICggbWFwcGVkICkge1xuXHRcdFx0XHRcdG1hcC5wdXNoKCBpICk7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9XG5cdH1cblxuXHRyZXR1cm4gbmV3VW5tYXRjaGVkO1xufVxuXG5mdW5jdGlvbiBzZXRNYXRjaGVyKCBwcmVGaWx0ZXIsIHNlbGVjdG9yLCBtYXRjaGVyLCBwb3N0RmlsdGVyLCBwb3N0RmluZGVyLCBwb3N0U2VsZWN0b3IgKSB7XG5cdGlmICggcG9zdEZpbHRlciAmJiAhcG9zdEZpbHRlclsgZXhwYW5kbyBdICkge1xuXHRcdHBvc3RGaWx0ZXIgPSBzZXRNYXRjaGVyKCBwb3N0RmlsdGVyICk7XG5cdH1cblx0aWYgKCBwb3N0RmluZGVyICYmICFwb3N0RmluZGVyWyBleHBhbmRvIF0gKSB7XG5cdFx0cG9zdEZpbmRlciA9IHNldE1hdGNoZXIoIHBvc3RGaW5kZXIsIHBvc3RTZWxlY3RvciApO1xuXHR9XG5cdHJldHVybiBtYXJrRnVuY3Rpb24oZnVuY3Rpb24oIHNlZWQsIHJlc3VsdHMsIGNvbnRleHQsIHhtbCApIHtcblx0XHR2YXIgdGVtcCwgaSwgZWxlbSxcblx0XHRcdHByZU1hcCA9IFtdLFxuXHRcdFx0cG9zdE1hcCA9IFtdLFxuXHRcdFx0cHJlZXhpc3RpbmcgPSByZXN1bHRzLmxlbmd0aCxcblxuXHRcdFx0Ly8gR2V0IGluaXRpYWwgZWxlbWVudHMgZnJvbSBzZWVkIG9yIGNvbnRleHRcblx0XHRcdGVsZW1zID0gc2VlZCB8fCBtdWx0aXBsZUNvbnRleHRzKCBzZWxlY3RvciB8fCBcIipcIiwgY29udGV4dC5ub2RlVHlwZSA/IFsgY29udGV4dCBdIDogY29udGV4dCwgW10gKSxcblxuXHRcdFx0Ly8gUHJlZmlsdGVyIHRvIGdldCBtYXRjaGVyIGlucHV0LCBwcmVzZXJ2aW5nIGEgbWFwIGZvciBzZWVkLXJlc3VsdHMgc3luY2hyb25pemF0aW9uXG5cdFx0XHRtYXRjaGVySW4gPSBwcmVGaWx0ZXIgJiYgKCBzZWVkIHx8ICFzZWxlY3RvciApID9cblx0XHRcdFx0Y29uZGVuc2UoIGVsZW1zLCBwcmVNYXAsIHByZUZpbHRlciwgY29udGV4dCwgeG1sICkgOlxuXHRcdFx0XHRlbGVtcyxcblxuXHRcdFx0bWF0Y2hlck91dCA9IG1hdGNoZXIgP1xuXHRcdFx0XHQvLyBJZiB3ZSBoYXZlIGEgcG9zdEZpbmRlciwgb3IgZmlsdGVyZWQgc2VlZCwgb3Igbm9uLXNlZWQgcG9zdEZpbHRlciBvciBwcmVleGlzdGluZyByZXN1bHRzLFxuXHRcdFx0XHRwb3N0RmluZGVyIHx8ICggc2VlZCA/IHByZUZpbHRlciA6IHByZWV4aXN0aW5nIHx8IHBvc3RGaWx0ZXIgKSA/XG5cblx0XHRcdFx0XHQvLyAuLi5pbnRlcm1lZGlhdGUgcHJvY2Vzc2luZyBpcyBuZWNlc3Nhcnlcblx0XHRcdFx0XHRbXSA6XG5cblx0XHRcdFx0XHQvLyAuLi5vdGhlcndpc2UgdXNlIHJlc3VsdHMgZGlyZWN0bHlcblx0XHRcdFx0XHRyZXN1bHRzIDpcblx0XHRcdFx0bWF0Y2hlckluO1xuXG5cdFx0Ly8gRmluZCBwcmltYXJ5IG1hdGNoZXNcblx0XHRpZiAoIG1hdGNoZXIgKSB7XG5cdFx0XHRtYXRjaGVyKCBtYXRjaGVySW4sIG1hdGNoZXJPdXQsIGNvbnRleHQsIHhtbCApO1xuXHRcdH1cblxuXHRcdC8vIEFwcGx5IHBvc3RGaWx0ZXJcblx0XHRpZiAoIHBvc3RGaWx0ZXIgKSB7XG5cdFx0XHR0ZW1wID0gY29uZGVuc2UoIG1hdGNoZXJPdXQsIHBvc3RNYXAgKTtcblx0XHRcdHBvc3RGaWx0ZXIoIHRlbXAsIFtdLCBjb250ZXh0LCB4bWwgKTtcblxuXHRcdFx0Ly8gVW4tbWF0Y2ggZmFpbGluZyBlbGVtZW50cyBieSBtb3ZpbmcgdGhlbSBiYWNrIHRvIG1hdGNoZXJJblxuXHRcdFx0aSA9IHRlbXAubGVuZ3RoO1xuXHRcdFx0d2hpbGUgKCBpLS0gKSB7XG5cdFx0XHRcdGlmICggKGVsZW0gPSB0ZW1wW2ldKSApIHtcblx0XHRcdFx0XHRtYXRjaGVyT3V0WyBwb3N0TWFwW2ldIF0gPSAhKG1hdGNoZXJJblsgcG9zdE1hcFtpXSBdID0gZWxlbSk7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9XG5cblx0XHRpZiAoIHNlZWQgKSB7XG5cdFx0XHRpZiAoIHBvc3RGaW5kZXIgfHwgcHJlRmlsdGVyICkge1xuXHRcdFx0XHRpZiAoIHBvc3RGaW5kZXIgKSB7XG5cdFx0XHRcdFx0Ly8gR2V0IHRoZSBmaW5hbCBtYXRjaGVyT3V0IGJ5IGNvbmRlbnNpbmcgdGhpcyBpbnRlcm1lZGlhdGUgaW50byBwb3N0RmluZGVyIGNvbnRleHRzXG5cdFx0XHRcdFx0dGVtcCA9IFtdO1xuXHRcdFx0XHRcdGkgPSBtYXRjaGVyT3V0Lmxlbmd0aDtcblx0XHRcdFx0XHR3aGlsZSAoIGktLSApIHtcblx0XHRcdFx0XHRcdGlmICggKGVsZW0gPSBtYXRjaGVyT3V0W2ldKSApIHtcblx0XHRcdFx0XHRcdFx0Ly8gUmVzdG9yZSBtYXRjaGVySW4gc2luY2UgZWxlbSBpcyBub3QgeWV0IGEgZmluYWwgbWF0Y2hcblx0XHRcdFx0XHRcdFx0dGVtcC5wdXNoKCAobWF0Y2hlckluW2ldID0gZWxlbSkgKTtcblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0cG9zdEZpbmRlciggbnVsbCwgKG1hdGNoZXJPdXQgPSBbXSksIHRlbXAsIHhtbCApO1xuXHRcdFx0XHR9XG5cblx0XHRcdFx0Ly8gTW92ZSBtYXRjaGVkIGVsZW1lbnRzIGZyb20gc2VlZCB0byByZXN1bHRzIHRvIGtlZXAgdGhlbSBzeW5jaHJvbml6ZWRcblx0XHRcdFx0aSA9IG1hdGNoZXJPdXQubGVuZ3RoO1xuXHRcdFx0XHR3aGlsZSAoIGktLSApIHtcblx0XHRcdFx0XHRpZiAoIChlbGVtID0gbWF0Y2hlck91dFtpXSkgJiZcblx0XHRcdFx0XHRcdCh0ZW1wID0gcG9zdEZpbmRlciA/IGluZGV4T2YoIHNlZWQsIGVsZW0gKSA6IHByZU1hcFtpXSkgPiAtMSApIHtcblxuXHRcdFx0XHRcdFx0c2VlZFt0ZW1wXSA9ICEocmVzdWx0c1t0ZW1wXSA9IGVsZW0pO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXHRcdFx0fVxuXG5cdFx0Ly8gQWRkIGVsZW1lbnRzIHRvIHJlc3VsdHMsIHRocm91Z2ggcG9zdEZpbmRlciBpZiBkZWZpbmVkXG5cdFx0fSBlbHNlIHtcblx0XHRcdG1hdGNoZXJPdXQgPSBjb25kZW5zZShcblx0XHRcdFx0bWF0Y2hlck91dCA9PT0gcmVzdWx0cyA/XG5cdFx0XHRcdFx0bWF0Y2hlck91dC5zcGxpY2UoIHByZWV4aXN0aW5nLCBtYXRjaGVyT3V0Lmxlbmd0aCApIDpcblx0XHRcdFx0XHRtYXRjaGVyT3V0XG5cdFx0XHQpO1xuXHRcdFx0aWYgKCBwb3N0RmluZGVyICkge1xuXHRcdFx0XHRwb3N0RmluZGVyKCBudWxsLCByZXN1bHRzLCBtYXRjaGVyT3V0LCB4bWwgKTtcblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdHB1c2guYXBwbHkoIHJlc3VsdHMsIG1hdGNoZXJPdXQgKTtcblx0XHRcdH1cblx0XHR9XG5cdH0pO1xufVxuXG5mdW5jdGlvbiBtYXRjaGVyRnJvbVRva2VucyggdG9rZW5zICkge1xuXHR2YXIgY2hlY2tDb250ZXh0LCBtYXRjaGVyLCBqLFxuXHRcdGxlbiA9IHRva2Vucy5sZW5ndGgsXG5cdFx0bGVhZGluZ1JlbGF0aXZlID0gRXhwci5yZWxhdGl2ZVsgdG9rZW5zWzBdLnR5cGUgXSxcblx0XHRpbXBsaWNpdFJlbGF0aXZlID0gbGVhZGluZ1JlbGF0aXZlIHx8IEV4cHIucmVsYXRpdmVbXCIgXCJdLFxuXHRcdGkgPSBsZWFkaW5nUmVsYXRpdmUgPyAxIDogMCxcblxuXHRcdC8vIFRoZSBmb3VuZGF0aW9uYWwgbWF0Y2hlciBlbnN1cmVzIHRoYXQgZWxlbWVudHMgYXJlIHJlYWNoYWJsZSBmcm9tIHRvcC1sZXZlbCBjb250ZXh0KHMpXG5cdFx0bWF0Y2hDb250ZXh0ID0gYWRkQ29tYmluYXRvciggZnVuY3Rpb24oIGVsZW0gKSB7XG5cdFx0XHRyZXR1cm4gZWxlbSA9PT0gY2hlY2tDb250ZXh0O1xuXHRcdH0sIGltcGxpY2l0UmVsYXRpdmUsIHRydWUgKSxcblx0XHRtYXRjaEFueUNvbnRleHQgPSBhZGRDb21iaW5hdG9yKCBmdW5jdGlvbiggZWxlbSApIHtcblx0XHRcdHJldHVybiBpbmRleE9mKCBjaGVja0NvbnRleHQsIGVsZW0gKSA+IC0xO1xuXHRcdH0sIGltcGxpY2l0UmVsYXRpdmUsIHRydWUgKSxcblx0XHRtYXRjaGVycyA9IFsgZnVuY3Rpb24oIGVsZW0sIGNvbnRleHQsIHhtbCApIHtcblx0XHRcdHZhciByZXQgPSAoICFsZWFkaW5nUmVsYXRpdmUgJiYgKCB4bWwgfHwgY29udGV4dCAhPT0gb3V0ZXJtb3N0Q29udGV4dCApICkgfHwgKFxuXHRcdFx0XHQoY2hlY2tDb250ZXh0ID0gY29udGV4dCkubm9kZVR5cGUgP1xuXHRcdFx0XHRcdG1hdGNoQ29udGV4dCggZWxlbSwgY29udGV4dCwgeG1sICkgOlxuXHRcdFx0XHRcdG1hdGNoQW55Q29udGV4dCggZWxlbSwgY29udGV4dCwgeG1sICkgKTtcblx0XHRcdC8vIEF2b2lkIGhhbmdpbmcgb250byBlbGVtZW50IChpc3N1ZSAjMjk5KVxuXHRcdFx0Y2hlY2tDb250ZXh0ID0gbnVsbDtcblx0XHRcdHJldHVybiByZXQ7XG5cdFx0fSBdO1xuXG5cdGZvciAoIDsgaSA8IGxlbjsgaSsrICkge1xuXHRcdGlmICggKG1hdGNoZXIgPSBFeHByLnJlbGF0aXZlWyB0b2tlbnNbaV0udHlwZSBdKSApIHtcblx0XHRcdG1hdGNoZXJzID0gWyBhZGRDb21iaW5hdG9yKGVsZW1lbnRNYXRjaGVyKCBtYXRjaGVycyApLCBtYXRjaGVyKSBdO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHRtYXRjaGVyID0gRXhwci5maWx0ZXJbIHRva2Vuc1tpXS50eXBlIF0uYXBwbHkoIG51bGwsIHRva2Vuc1tpXS5tYXRjaGVzICk7XG5cblx0XHRcdC8vIFJldHVybiBzcGVjaWFsIHVwb24gc2VlaW5nIGEgcG9zaXRpb25hbCBtYXRjaGVyXG5cdFx0XHRpZiAoIG1hdGNoZXJbIGV4cGFuZG8gXSApIHtcblx0XHRcdFx0Ly8gRmluZCB0aGUgbmV4dCByZWxhdGl2ZSBvcGVyYXRvciAoaWYgYW55KSBmb3IgcHJvcGVyIGhhbmRsaW5nXG5cdFx0XHRcdGogPSArK2k7XG5cdFx0XHRcdGZvciAoIDsgaiA8IGxlbjsgaisrICkge1xuXHRcdFx0XHRcdGlmICggRXhwci5yZWxhdGl2ZVsgdG9rZW5zW2pdLnR5cGUgXSApIHtcblx0XHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXHRcdFx0XHRyZXR1cm4gc2V0TWF0Y2hlcihcblx0XHRcdFx0XHRpID4gMSAmJiBlbGVtZW50TWF0Y2hlciggbWF0Y2hlcnMgKSxcblx0XHRcdFx0XHRpID4gMSAmJiB0b1NlbGVjdG9yKFxuXHRcdFx0XHRcdFx0Ly8gSWYgdGhlIHByZWNlZGluZyB0b2tlbiB3YXMgYSBkZXNjZW5kYW50IGNvbWJpbmF0b3IsIGluc2VydCBhbiBpbXBsaWNpdCBhbnktZWxlbWVudCBgKmBcblx0XHRcdFx0XHRcdHRva2Vucy5zbGljZSggMCwgaSAtIDEgKS5jb25jYXQoeyB2YWx1ZTogdG9rZW5zWyBpIC0gMiBdLnR5cGUgPT09IFwiIFwiID8gXCIqXCIgOiBcIlwiIH0pXG5cdFx0XHRcdFx0KS5yZXBsYWNlKCBydHJpbSwgXCIkMVwiICksXG5cdFx0XHRcdFx0bWF0Y2hlcixcblx0XHRcdFx0XHRpIDwgaiAmJiBtYXRjaGVyRnJvbVRva2VucyggdG9rZW5zLnNsaWNlKCBpLCBqICkgKSxcblx0XHRcdFx0XHRqIDwgbGVuICYmIG1hdGNoZXJGcm9tVG9rZW5zKCAodG9rZW5zID0gdG9rZW5zLnNsaWNlKCBqICkpICksXG5cdFx0XHRcdFx0aiA8IGxlbiAmJiB0b1NlbGVjdG9yKCB0b2tlbnMgKVxuXHRcdFx0XHQpO1xuXHRcdFx0fVxuXHRcdFx0bWF0Y2hlcnMucHVzaCggbWF0Y2hlciApO1xuXHRcdH1cblx0fVxuXG5cdHJldHVybiBlbGVtZW50TWF0Y2hlciggbWF0Y2hlcnMgKTtcbn1cblxuZnVuY3Rpb24gbWF0Y2hlckZyb21Hcm91cE1hdGNoZXJzKCBlbGVtZW50TWF0Y2hlcnMsIHNldE1hdGNoZXJzICkge1xuXHR2YXIgYnlTZXQgPSBzZXRNYXRjaGVycy5sZW5ndGggPiAwLFxuXHRcdGJ5RWxlbWVudCA9IGVsZW1lbnRNYXRjaGVycy5sZW5ndGggPiAwLFxuXHRcdHN1cGVyTWF0Y2hlciA9IGZ1bmN0aW9uKCBzZWVkLCBjb250ZXh0LCB4bWwsIHJlc3VsdHMsIG91dGVybW9zdCApIHtcblx0XHRcdHZhciBlbGVtLCBqLCBtYXRjaGVyLFxuXHRcdFx0XHRtYXRjaGVkQ291bnQgPSAwLFxuXHRcdFx0XHRpID0gXCIwXCIsXG5cdFx0XHRcdHVubWF0Y2hlZCA9IHNlZWQgJiYgW10sXG5cdFx0XHRcdHNldE1hdGNoZWQgPSBbXSxcblx0XHRcdFx0Y29udGV4dEJhY2t1cCA9IG91dGVybW9zdENvbnRleHQsXG5cdFx0XHRcdC8vIFdlIG11c3QgYWx3YXlzIGhhdmUgZWl0aGVyIHNlZWQgZWxlbWVudHMgb3Igb3V0ZXJtb3N0IGNvbnRleHRcblx0XHRcdFx0ZWxlbXMgPSBzZWVkIHx8IGJ5RWxlbWVudCAmJiBFeHByLmZpbmRbXCJUQUdcIl0oIFwiKlwiLCBvdXRlcm1vc3QgKSxcblx0XHRcdFx0Ly8gVXNlIGludGVnZXIgZGlycnVucyBpZmYgdGhpcyBpcyB0aGUgb3V0ZXJtb3N0IG1hdGNoZXJcblx0XHRcdFx0ZGlycnVuc1VuaXF1ZSA9IChkaXJydW5zICs9IGNvbnRleHRCYWNrdXAgPT0gbnVsbCA/IDEgOiBNYXRoLnJhbmRvbSgpIHx8IDAuMSksXG5cdFx0XHRcdGxlbiA9IGVsZW1zLmxlbmd0aDtcblxuXHRcdFx0aWYgKCBvdXRlcm1vc3QgKSB7XG5cdFx0XHRcdG91dGVybW9zdENvbnRleHQgPSBjb250ZXh0ID09PSBkb2N1bWVudCB8fCBjb250ZXh0IHx8IG91dGVybW9zdDtcblx0XHRcdH1cblxuXHRcdFx0Ly8gQWRkIGVsZW1lbnRzIHBhc3NpbmcgZWxlbWVudE1hdGNoZXJzIGRpcmVjdGx5IHRvIHJlc3VsdHNcblx0XHRcdC8vIFN1cHBvcnQ6IElFPDksIFNhZmFyaVxuXHRcdFx0Ly8gVG9sZXJhdGUgTm9kZUxpc3QgcHJvcGVydGllcyAoSUU6IFwibGVuZ3RoXCI7IFNhZmFyaTogPG51bWJlcj4pIG1hdGNoaW5nIGVsZW1lbnRzIGJ5IGlkXG5cdFx0XHRmb3IgKCA7IGkgIT09IGxlbiAmJiAoZWxlbSA9IGVsZW1zW2ldKSAhPSBudWxsOyBpKysgKSB7XG5cdFx0XHRcdGlmICggYnlFbGVtZW50ICYmIGVsZW0gKSB7XG5cdFx0XHRcdFx0aiA9IDA7XG5cdFx0XHRcdFx0aWYgKCAhY29udGV4dCAmJiBlbGVtLm93bmVyRG9jdW1lbnQgIT09IGRvY3VtZW50ICkge1xuXHRcdFx0XHRcdFx0c2V0RG9jdW1lbnQoIGVsZW0gKTtcblx0XHRcdFx0XHRcdHhtbCA9ICFkb2N1bWVudElzSFRNTDtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0d2hpbGUgKCAobWF0Y2hlciA9IGVsZW1lbnRNYXRjaGVyc1tqKytdKSApIHtcblx0XHRcdFx0XHRcdGlmICggbWF0Y2hlciggZWxlbSwgY29udGV4dCB8fCBkb2N1bWVudCwgeG1sKSApIHtcblx0XHRcdFx0XHRcdFx0cmVzdWx0cy5wdXNoKCBlbGVtICk7XG5cdFx0XHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdH1cblx0XHRcdFx0XHRpZiAoIG91dGVybW9zdCApIHtcblx0XHRcdFx0XHRcdGRpcnJ1bnMgPSBkaXJydW5zVW5pcXVlO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXG5cdFx0XHRcdC8vIFRyYWNrIHVubWF0Y2hlZCBlbGVtZW50cyBmb3Igc2V0IGZpbHRlcnNcblx0XHRcdFx0aWYgKCBieVNldCApIHtcblx0XHRcdFx0XHQvLyBUaGV5IHdpbGwgaGF2ZSBnb25lIHRocm91Z2ggYWxsIHBvc3NpYmxlIG1hdGNoZXJzXG5cdFx0XHRcdFx0aWYgKCAoZWxlbSA9ICFtYXRjaGVyICYmIGVsZW0pICkge1xuXHRcdFx0XHRcdFx0bWF0Y2hlZENvdW50LS07XG5cdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0Ly8gTGVuZ3RoZW4gdGhlIGFycmF5IGZvciBldmVyeSBlbGVtZW50LCBtYXRjaGVkIG9yIG5vdFxuXHRcdFx0XHRcdGlmICggc2VlZCApIHtcblx0XHRcdFx0XHRcdHVubWF0Y2hlZC5wdXNoKCBlbGVtICk7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cdFx0XHR9XG5cblx0XHRcdC8vIGBpYCBpcyBub3cgdGhlIGNvdW50IG9mIGVsZW1lbnRzIHZpc2l0ZWQgYWJvdmUsIGFuZCBhZGRpbmcgaXQgdG8gYG1hdGNoZWRDb3VudGBcblx0XHRcdC8vIG1ha2VzIHRoZSBsYXR0ZXIgbm9ubmVnYXRpdmUuXG5cdFx0XHRtYXRjaGVkQ291bnQgKz0gaTtcblxuXHRcdFx0Ly8gQXBwbHkgc2V0IGZpbHRlcnMgdG8gdW5tYXRjaGVkIGVsZW1lbnRzXG5cdFx0XHQvLyBOT1RFOiBUaGlzIGNhbiBiZSBza2lwcGVkIGlmIHRoZXJlIGFyZSBubyB1bm1hdGNoZWQgZWxlbWVudHMgKGkuZS4sIGBtYXRjaGVkQ291bnRgXG5cdFx0XHQvLyBlcXVhbHMgYGlgKSwgdW5sZXNzIHdlIGRpZG4ndCB2aXNpdCBfYW55XyBlbGVtZW50cyBpbiB0aGUgYWJvdmUgbG9vcCBiZWNhdXNlIHdlIGhhdmVcblx0XHRcdC8vIG5vIGVsZW1lbnQgbWF0Y2hlcnMgYW5kIG5vIHNlZWQuXG5cdFx0XHQvLyBJbmNyZW1lbnRpbmcgYW4gaW5pdGlhbGx5LXN0cmluZyBcIjBcIiBgaWAgYWxsb3dzIGBpYCB0byByZW1haW4gYSBzdHJpbmcgb25seSBpbiB0aGF0XG5cdFx0XHQvLyBjYXNlLCB3aGljaCB3aWxsIHJlc3VsdCBpbiBhIFwiMDBcIiBgbWF0Y2hlZENvdW50YCB0aGF0IGRpZmZlcnMgZnJvbSBgaWAgYnV0IGlzIGFsc29cblx0XHRcdC8vIG51bWVyaWNhbGx5IHplcm8uXG5cdFx0XHRpZiAoIGJ5U2V0ICYmIGkgIT09IG1hdGNoZWRDb3VudCApIHtcblx0XHRcdFx0aiA9IDA7XG5cdFx0XHRcdHdoaWxlICggKG1hdGNoZXIgPSBzZXRNYXRjaGVyc1tqKytdKSApIHtcblx0XHRcdFx0XHRtYXRjaGVyKCB1bm1hdGNoZWQsIHNldE1hdGNoZWQsIGNvbnRleHQsIHhtbCApO1xuXHRcdFx0XHR9XG5cblx0XHRcdFx0aWYgKCBzZWVkICkge1xuXHRcdFx0XHRcdC8vIFJlaW50ZWdyYXRlIGVsZW1lbnQgbWF0Y2hlcyB0byBlbGltaW5hdGUgdGhlIG5lZWQgZm9yIHNvcnRpbmdcblx0XHRcdFx0XHRpZiAoIG1hdGNoZWRDb3VudCA+IDAgKSB7XG5cdFx0XHRcdFx0XHR3aGlsZSAoIGktLSApIHtcblx0XHRcdFx0XHRcdFx0aWYgKCAhKHVubWF0Y2hlZFtpXSB8fCBzZXRNYXRjaGVkW2ldKSApIHtcblx0XHRcdFx0XHRcdFx0XHRzZXRNYXRjaGVkW2ldID0gcG9wLmNhbGwoIHJlc3VsdHMgKTtcblx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdC8vIERpc2NhcmQgaW5kZXggcGxhY2Vob2xkZXIgdmFsdWVzIHRvIGdldCBvbmx5IGFjdHVhbCBtYXRjaGVzXG5cdFx0XHRcdFx0c2V0TWF0Y2hlZCA9IGNvbmRlbnNlKCBzZXRNYXRjaGVkICk7XG5cdFx0XHRcdH1cblxuXHRcdFx0XHQvLyBBZGQgbWF0Y2hlcyB0byByZXN1bHRzXG5cdFx0XHRcdHB1c2guYXBwbHkoIHJlc3VsdHMsIHNldE1hdGNoZWQgKTtcblxuXHRcdFx0XHQvLyBTZWVkbGVzcyBzZXQgbWF0Y2hlcyBzdWNjZWVkaW5nIG11bHRpcGxlIHN1Y2Nlc3NmdWwgbWF0Y2hlcnMgc3RpcHVsYXRlIHNvcnRpbmdcblx0XHRcdFx0aWYgKCBvdXRlcm1vc3QgJiYgIXNlZWQgJiYgc2V0TWF0Y2hlZC5sZW5ndGggPiAwICYmXG5cdFx0XHRcdFx0KCBtYXRjaGVkQ291bnQgKyBzZXRNYXRjaGVycy5sZW5ndGggKSA+IDEgKSB7XG5cblx0XHRcdFx0XHRTaXp6bGUudW5pcXVlU29ydCggcmVzdWx0cyApO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cblx0XHRcdC8vIE92ZXJyaWRlIG1hbmlwdWxhdGlvbiBvZiBnbG9iYWxzIGJ5IG5lc3RlZCBtYXRjaGVyc1xuXHRcdFx0aWYgKCBvdXRlcm1vc3QgKSB7XG5cdFx0XHRcdGRpcnJ1bnMgPSBkaXJydW5zVW5pcXVlO1xuXHRcdFx0XHRvdXRlcm1vc3RDb250ZXh0ID0gY29udGV4dEJhY2t1cDtcblx0XHRcdH1cblxuXHRcdFx0cmV0dXJuIHVubWF0Y2hlZDtcblx0XHR9O1xuXG5cdHJldHVybiBieVNldCA/XG5cdFx0bWFya0Z1bmN0aW9uKCBzdXBlck1hdGNoZXIgKSA6XG5cdFx0c3VwZXJNYXRjaGVyO1xufVxuXG5jb21waWxlID0gU2l6emxlLmNvbXBpbGUgPSBmdW5jdGlvbiggc2VsZWN0b3IsIG1hdGNoIC8qIEludGVybmFsIFVzZSBPbmx5ICovICkge1xuXHR2YXIgaSxcblx0XHRzZXRNYXRjaGVycyA9IFtdLFxuXHRcdGVsZW1lbnRNYXRjaGVycyA9IFtdLFxuXHRcdGNhY2hlZCA9IGNvbXBpbGVyQ2FjaGVbIHNlbGVjdG9yICsgXCIgXCIgXTtcblxuXHRpZiAoICFjYWNoZWQgKSB7XG5cdFx0Ly8gR2VuZXJhdGUgYSBmdW5jdGlvbiBvZiByZWN1cnNpdmUgZnVuY3Rpb25zIHRoYXQgY2FuIGJlIHVzZWQgdG8gY2hlY2sgZWFjaCBlbGVtZW50XG5cdFx0aWYgKCAhbWF0Y2ggKSB7XG5cdFx0XHRtYXRjaCA9IHRva2VuaXplKCBzZWxlY3RvciApO1xuXHRcdH1cblx0XHRpID0gbWF0Y2gubGVuZ3RoO1xuXHRcdHdoaWxlICggaS0tICkge1xuXHRcdFx0Y2FjaGVkID0gbWF0Y2hlckZyb21Ub2tlbnMoIG1hdGNoW2ldICk7XG5cdFx0XHRpZiAoIGNhY2hlZFsgZXhwYW5kbyBdICkge1xuXHRcdFx0XHRzZXRNYXRjaGVycy5wdXNoKCBjYWNoZWQgKTtcblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdGVsZW1lbnRNYXRjaGVycy5wdXNoKCBjYWNoZWQgKTtcblx0XHRcdH1cblx0XHR9XG5cblx0XHQvLyBDYWNoZSB0aGUgY29tcGlsZWQgZnVuY3Rpb25cblx0XHRjYWNoZWQgPSBjb21waWxlckNhY2hlKCBzZWxlY3RvciwgbWF0Y2hlckZyb21Hcm91cE1hdGNoZXJzKCBlbGVtZW50TWF0Y2hlcnMsIHNldE1hdGNoZXJzICkgKTtcblxuXHRcdC8vIFNhdmUgc2VsZWN0b3IgYW5kIHRva2VuaXphdGlvblxuXHRcdGNhY2hlZC5zZWxlY3RvciA9IHNlbGVjdG9yO1xuXHR9XG5cdHJldHVybiBjYWNoZWQ7XG59O1xuXG4vKipcbiAqIEEgbG93LWxldmVsIHNlbGVjdGlvbiBmdW5jdGlvbiB0aGF0IHdvcmtzIHdpdGggU2l6emxlJ3MgY29tcGlsZWRcbiAqICBzZWxlY3RvciBmdW5jdGlvbnNcbiAqIEBwYXJhbSB7U3RyaW5nfEZ1bmN0aW9ufSBzZWxlY3RvciBBIHNlbGVjdG9yIG9yIGEgcHJlLWNvbXBpbGVkXG4gKiAgc2VsZWN0b3IgZnVuY3Rpb24gYnVpbHQgd2l0aCBTaXp6bGUuY29tcGlsZVxuICogQHBhcmFtIHtFbGVtZW50fSBjb250ZXh0XG4gKiBAcGFyYW0ge0FycmF5fSBbcmVzdWx0c11cbiAqIEBwYXJhbSB7QXJyYXl9IFtzZWVkXSBBIHNldCBvZiBlbGVtZW50cyB0byBtYXRjaCBhZ2FpbnN0XG4gKi9cbnNlbGVjdCA9IFNpenpsZS5zZWxlY3QgPSBmdW5jdGlvbiggc2VsZWN0b3IsIGNvbnRleHQsIHJlc3VsdHMsIHNlZWQgKSB7XG5cdHZhciBpLCB0b2tlbnMsIHRva2VuLCB0eXBlLCBmaW5kLFxuXHRcdGNvbXBpbGVkID0gdHlwZW9mIHNlbGVjdG9yID09PSBcImZ1bmN0aW9uXCIgJiYgc2VsZWN0b3IsXG5cdFx0bWF0Y2ggPSAhc2VlZCAmJiB0b2tlbml6ZSggKHNlbGVjdG9yID0gY29tcGlsZWQuc2VsZWN0b3IgfHwgc2VsZWN0b3IpICk7XG5cblx0cmVzdWx0cyA9IHJlc3VsdHMgfHwgW107XG5cblx0Ly8gVHJ5IHRvIG1pbmltaXplIG9wZXJhdGlvbnMgaWYgdGhlcmUgaXMgb25seSBvbmUgc2VsZWN0b3IgaW4gdGhlIGxpc3QgYW5kIG5vIHNlZWRcblx0Ly8gKHRoZSBsYXR0ZXIgb2Ygd2hpY2ggZ3VhcmFudGVlcyB1cyBjb250ZXh0KVxuXHRpZiAoIG1hdGNoLmxlbmd0aCA9PT0gMSApIHtcblxuXHRcdC8vIFJlZHVjZSBjb250ZXh0IGlmIHRoZSBsZWFkaW5nIGNvbXBvdW5kIHNlbGVjdG9yIGlzIGFuIElEXG5cdFx0dG9rZW5zID0gbWF0Y2hbMF0gPSBtYXRjaFswXS5zbGljZSggMCApO1xuXHRcdGlmICggdG9rZW5zLmxlbmd0aCA+IDIgJiYgKHRva2VuID0gdG9rZW5zWzBdKS50eXBlID09PSBcIklEXCIgJiZcblx0XHRcdFx0Y29udGV4dC5ub2RlVHlwZSA9PT0gOSAmJiBkb2N1bWVudElzSFRNTCAmJiBFeHByLnJlbGF0aXZlWyB0b2tlbnNbMV0udHlwZSBdICkge1xuXG5cdFx0XHRjb250ZXh0ID0gKCBFeHByLmZpbmRbXCJJRFwiXSggdG9rZW4ubWF0Y2hlc1swXS5yZXBsYWNlKHJ1bmVzY2FwZSwgZnVuZXNjYXBlKSwgY29udGV4dCApIHx8IFtdIClbMF07XG5cdFx0XHRpZiAoICFjb250ZXh0ICkge1xuXHRcdFx0XHRyZXR1cm4gcmVzdWx0cztcblxuXHRcdFx0Ly8gUHJlY29tcGlsZWQgbWF0Y2hlcnMgd2lsbCBzdGlsbCB2ZXJpZnkgYW5jZXN0cnksIHNvIHN0ZXAgdXAgYSBsZXZlbFxuXHRcdFx0fSBlbHNlIGlmICggY29tcGlsZWQgKSB7XG5cdFx0XHRcdGNvbnRleHQgPSBjb250ZXh0LnBhcmVudE5vZGU7XG5cdFx0XHR9XG5cblx0XHRcdHNlbGVjdG9yID0gc2VsZWN0b3Iuc2xpY2UoIHRva2Vucy5zaGlmdCgpLnZhbHVlLmxlbmd0aCApO1xuXHRcdH1cblxuXHRcdC8vIEZldGNoIGEgc2VlZCBzZXQgZm9yIHJpZ2h0LXRvLWxlZnQgbWF0Y2hpbmdcblx0XHRpID0gbWF0Y2hFeHByW1wibmVlZHNDb250ZXh0XCJdLnRlc3QoIHNlbGVjdG9yICkgPyAwIDogdG9rZW5zLmxlbmd0aDtcblx0XHR3aGlsZSAoIGktLSApIHtcblx0XHRcdHRva2VuID0gdG9rZW5zW2ldO1xuXG5cdFx0XHQvLyBBYm9ydCBpZiB3ZSBoaXQgYSBjb21iaW5hdG9yXG5cdFx0XHRpZiAoIEV4cHIucmVsYXRpdmVbICh0eXBlID0gdG9rZW4udHlwZSkgXSApIHtcblx0XHRcdFx0YnJlYWs7XG5cdFx0XHR9XG5cdFx0XHRpZiAoIChmaW5kID0gRXhwci5maW5kWyB0eXBlIF0pICkge1xuXHRcdFx0XHQvLyBTZWFyY2gsIGV4cGFuZGluZyBjb250ZXh0IGZvciBsZWFkaW5nIHNpYmxpbmcgY29tYmluYXRvcnNcblx0XHRcdFx0aWYgKCAoc2VlZCA9IGZpbmQoXG5cdFx0XHRcdFx0dG9rZW4ubWF0Y2hlc1swXS5yZXBsYWNlKCBydW5lc2NhcGUsIGZ1bmVzY2FwZSApLFxuXHRcdFx0XHRcdHJzaWJsaW5nLnRlc3QoIHRva2Vuc1swXS50eXBlICkgJiYgdGVzdENvbnRleHQoIGNvbnRleHQucGFyZW50Tm9kZSApIHx8IGNvbnRleHRcblx0XHRcdFx0KSkgKSB7XG5cblx0XHRcdFx0XHQvLyBJZiBzZWVkIGlzIGVtcHR5IG9yIG5vIHRva2VucyByZW1haW4sIHdlIGNhbiByZXR1cm4gZWFybHlcblx0XHRcdFx0XHR0b2tlbnMuc3BsaWNlKCBpLCAxICk7XG5cdFx0XHRcdFx0c2VsZWN0b3IgPSBzZWVkLmxlbmd0aCAmJiB0b1NlbGVjdG9yKCB0b2tlbnMgKTtcblx0XHRcdFx0XHRpZiAoICFzZWxlY3RvciApIHtcblx0XHRcdFx0XHRcdHB1c2guYXBwbHkoIHJlc3VsdHMsIHNlZWQgKTtcblx0XHRcdFx0XHRcdHJldHVybiByZXN1bHRzO1xuXHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fVxuXHR9XG5cblx0Ly8gQ29tcGlsZSBhbmQgZXhlY3V0ZSBhIGZpbHRlcmluZyBmdW5jdGlvbiBpZiBvbmUgaXMgbm90IHByb3ZpZGVkXG5cdC8vIFByb3ZpZGUgYG1hdGNoYCB0byBhdm9pZCByZXRva2VuaXphdGlvbiBpZiB3ZSBtb2RpZmllZCB0aGUgc2VsZWN0b3IgYWJvdmVcblx0KCBjb21waWxlZCB8fCBjb21waWxlKCBzZWxlY3RvciwgbWF0Y2ggKSApKFxuXHRcdHNlZWQsXG5cdFx0Y29udGV4dCxcblx0XHQhZG9jdW1lbnRJc0hUTUwsXG5cdFx0cmVzdWx0cyxcblx0XHQhY29udGV4dCB8fCByc2libGluZy50ZXN0KCBzZWxlY3RvciApICYmIHRlc3RDb250ZXh0KCBjb250ZXh0LnBhcmVudE5vZGUgKSB8fCBjb250ZXh0XG5cdCk7XG5cdHJldHVybiByZXN1bHRzO1xufTtcblxuLy8gT25lLXRpbWUgYXNzaWdubWVudHNcblxuLy8gU29ydCBzdGFiaWxpdHlcbnN1cHBvcnQuc29ydFN0YWJsZSA9IGV4cGFuZG8uc3BsaXQoXCJcIikuc29ydCggc29ydE9yZGVyICkuam9pbihcIlwiKSA9PT0gZXhwYW5kbztcblxuLy8gU3VwcG9ydDogQ2hyb21lIDE0LTM1K1xuLy8gQWx3YXlzIGFzc3VtZSBkdXBsaWNhdGVzIGlmIHRoZXkgYXJlbid0IHBhc3NlZCB0byB0aGUgY29tcGFyaXNvbiBmdW5jdGlvblxuc3VwcG9ydC5kZXRlY3REdXBsaWNhdGVzID0gISFoYXNEdXBsaWNhdGU7XG5cbi8vIEluaXRpYWxpemUgYWdhaW5zdCB0aGUgZGVmYXVsdCBkb2N1bWVudFxuc2V0RG9jdW1lbnQoKTtcblxuLy8gU3VwcG9ydDogV2Via2l0PDUzNy4zMiAtIFNhZmFyaSA2LjAuMy9DaHJvbWUgMjUgKGZpeGVkIGluIENocm9tZSAyNylcbi8vIERldGFjaGVkIG5vZGVzIGNvbmZvdW5kaW5nbHkgZm9sbG93ICplYWNoIG90aGVyKlxuc3VwcG9ydC5zb3J0RGV0YWNoZWQgPSBhc3NlcnQoZnVuY3Rpb24oIGVsICkge1xuXHQvLyBTaG91bGQgcmV0dXJuIDEsIGJ1dCByZXR1cm5zIDQgKGZvbGxvd2luZylcblx0cmV0dXJuIGVsLmNvbXBhcmVEb2N1bWVudFBvc2l0aW9uKCBkb2N1bWVudC5jcmVhdGVFbGVtZW50KFwiZmllbGRzZXRcIikgKSAmIDE7XG59KTtcblxuLy8gU3VwcG9ydDogSUU8OFxuLy8gUHJldmVudCBhdHRyaWJ1dGUvcHJvcGVydHkgXCJpbnRlcnBvbGF0aW9uXCJcbi8vIGh0dHBzOi8vbXNkbi5taWNyb3NvZnQuY29tL2VuLXVzL2xpYnJhcnkvbXM1MzY0MjklMjhWUy44NSUyOS5hc3B4XG5pZiAoICFhc3NlcnQoZnVuY3Rpb24oIGVsICkge1xuXHRlbC5pbm5lckhUTUwgPSBcIjxhIGhyZWY9JyMnPjwvYT5cIjtcblx0cmV0dXJuIGVsLmZpcnN0Q2hpbGQuZ2V0QXR0cmlidXRlKFwiaHJlZlwiKSA9PT0gXCIjXCIgO1xufSkgKSB7XG5cdGFkZEhhbmRsZSggXCJ0eXBlfGhyZWZ8aGVpZ2h0fHdpZHRoXCIsIGZ1bmN0aW9uKCBlbGVtLCBuYW1lLCBpc1hNTCApIHtcblx0XHRpZiAoICFpc1hNTCApIHtcblx0XHRcdHJldHVybiBlbGVtLmdldEF0dHJpYnV0ZSggbmFtZSwgbmFtZS50b0xvd2VyQ2FzZSgpID09PSBcInR5cGVcIiA/IDEgOiAyICk7XG5cdFx0fVxuXHR9KTtcbn1cblxuLy8gU3VwcG9ydDogSUU8OVxuLy8gVXNlIGRlZmF1bHRWYWx1ZSBpbiBwbGFjZSBvZiBnZXRBdHRyaWJ1dGUoXCJ2YWx1ZVwiKVxuaWYgKCAhc3VwcG9ydC5hdHRyaWJ1dGVzIHx8ICFhc3NlcnQoZnVuY3Rpb24oIGVsICkge1xuXHRlbC5pbm5lckhUTUwgPSBcIjxpbnB1dC8+XCI7XG5cdGVsLmZpcnN0Q2hpbGQuc2V0QXR0cmlidXRlKCBcInZhbHVlXCIsIFwiXCIgKTtcblx0cmV0dXJuIGVsLmZpcnN0Q2hpbGQuZ2V0QXR0cmlidXRlKCBcInZhbHVlXCIgKSA9PT0gXCJcIjtcbn0pICkge1xuXHRhZGRIYW5kbGUoIFwidmFsdWVcIiwgZnVuY3Rpb24oIGVsZW0sIG5hbWUsIGlzWE1MICkge1xuXHRcdGlmICggIWlzWE1MICYmIGVsZW0ubm9kZU5hbWUudG9Mb3dlckNhc2UoKSA9PT0gXCJpbnB1dFwiICkge1xuXHRcdFx0cmV0dXJuIGVsZW0uZGVmYXVsdFZhbHVlO1xuXHRcdH1cblx0fSk7XG59XG5cbi8vIFN1cHBvcnQ6IElFPDlcbi8vIFVzZSBnZXRBdHRyaWJ1dGVOb2RlIHRvIGZldGNoIGJvb2xlYW5zIHdoZW4gZ2V0QXR0cmlidXRlIGxpZXNcbmlmICggIWFzc2VydChmdW5jdGlvbiggZWwgKSB7XG5cdHJldHVybiBlbC5nZXRBdHRyaWJ1dGUoXCJkaXNhYmxlZFwiKSA9PSBudWxsO1xufSkgKSB7XG5cdGFkZEhhbmRsZSggYm9vbGVhbnMsIGZ1bmN0aW9uKCBlbGVtLCBuYW1lLCBpc1hNTCApIHtcblx0XHR2YXIgdmFsO1xuXHRcdGlmICggIWlzWE1MICkge1xuXHRcdFx0cmV0dXJuIGVsZW1bIG5hbWUgXSA9PT0gdHJ1ZSA/IG5hbWUudG9Mb3dlckNhc2UoKSA6XG5cdFx0XHRcdFx0KHZhbCA9IGVsZW0uZ2V0QXR0cmlidXRlTm9kZSggbmFtZSApKSAmJiB2YWwuc3BlY2lmaWVkID9cblx0XHRcdFx0XHR2YWwudmFsdWUgOlxuXHRcdFx0XHRudWxsO1xuXHRcdH1cblx0fSk7XG59XG5cbnJldHVybiBTaXp6bGU7XG5cbn0pKCB3aW5kb3cgKTtcblxuXG5cbmpRdWVyeS5maW5kID0gU2l6emxlO1xualF1ZXJ5LmV4cHIgPSBTaXp6bGUuc2VsZWN0b3JzO1xuXG4vLyBEZXByZWNhdGVkXG5qUXVlcnkuZXhwclsgXCI6XCIgXSA9IGpRdWVyeS5leHByLnBzZXVkb3M7XG5qUXVlcnkudW5pcXVlU29ydCA9IGpRdWVyeS51bmlxdWUgPSBTaXp6bGUudW5pcXVlU29ydDtcbmpRdWVyeS50ZXh0ID0gU2l6emxlLmdldFRleHQ7XG5qUXVlcnkuaXNYTUxEb2MgPSBTaXp6bGUuaXNYTUw7XG5qUXVlcnkuY29udGFpbnMgPSBTaXp6bGUuY29udGFpbnM7XG5qUXVlcnkuZXNjYXBlU2VsZWN0b3IgPSBTaXp6bGUuZXNjYXBlO1xuXG5cblxuXG52YXIgZGlyID0gZnVuY3Rpb24oIGVsZW0sIGRpciwgdW50aWwgKSB7XG5cdHZhciBtYXRjaGVkID0gW10sXG5cdFx0dHJ1bmNhdGUgPSB1bnRpbCAhPT0gdW5kZWZpbmVkO1xuXG5cdHdoaWxlICggKCBlbGVtID0gZWxlbVsgZGlyIF0gKSAmJiBlbGVtLm5vZGVUeXBlICE9PSA5ICkge1xuXHRcdGlmICggZWxlbS5ub2RlVHlwZSA9PT0gMSApIHtcblx0XHRcdGlmICggdHJ1bmNhdGUgJiYgalF1ZXJ5KCBlbGVtICkuaXMoIHVudGlsICkgKSB7XG5cdFx0XHRcdGJyZWFrO1xuXHRcdFx0fVxuXHRcdFx0bWF0Y2hlZC5wdXNoKCBlbGVtICk7XG5cdFx0fVxuXHR9XG5cdHJldHVybiBtYXRjaGVkO1xufTtcblxuXG52YXIgc2libGluZ3MgPSBmdW5jdGlvbiggbiwgZWxlbSApIHtcblx0dmFyIG1hdGNoZWQgPSBbXTtcblxuXHRmb3IgKCA7IG47IG4gPSBuLm5leHRTaWJsaW5nICkge1xuXHRcdGlmICggbi5ub2RlVHlwZSA9PT0gMSAmJiBuICE9PSBlbGVtICkge1xuXHRcdFx0bWF0Y2hlZC5wdXNoKCBuICk7XG5cdFx0fVxuXHR9XG5cblx0cmV0dXJuIG1hdGNoZWQ7XG59O1xuXG5cbnZhciBybmVlZHNDb250ZXh0ID0galF1ZXJ5LmV4cHIubWF0Y2gubmVlZHNDb250ZXh0O1xuXG5cblxuZnVuY3Rpb24gbm9kZU5hbWUoIGVsZW0sIG5hbWUgKSB7XG5cbiAgcmV0dXJuIGVsZW0ubm9kZU5hbWUgJiYgZWxlbS5ub2RlTmFtZS50b0xvd2VyQ2FzZSgpID09PSBuYW1lLnRvTG93ZXJDYXNlKCk7XG5cbn07XG52YXIgcnNpbmdsZVRhZyA9ICggL148KFthLXpdW15cXC9cXDA+OlxceDIwXFx0XFxyXFxuXFxmXSopW1xceDIwXFx0XFxyXFxuXFxmXSpcXC8/Pig/OjxcXC9cXDE+fCkkL2kgKTtcblxuXG5cbnZhciByaXNTaW1wbGUgPSAvXi5bXjojXFxbXFwuLF0qJC87XG5cbi8vIEltcGxlbWVudCB0aGUgaWRlbnRpY2FsIGZ1bmN0aW9uYWxpdHkgZm9yIGZpbHRlciBhbmQgbm90XG5mdW5jdGlvbiB3aW5ub3coIGVsZW1lbnRzLCBxdWFsaWZpZXIsIG5vdCApIHtcblx0aWYgKCBqUXVlcnkuaXNGdW5jdGlvbiggcXVhbGlmaWVyICkgKSB7XG5cdFx0cmV0dXJuIGpRdWVyeS5ncmVwKCBlbGVtZW50cywgZnVuY3Rpb24oIGVsZW0sIGkgKSB7XG5cdFx0XHRyZXR1cm4gISFxdWFsaWZpZXIuY2FsbCggZWxlbSwgaSwgZWxlbSApICE9PSBub3Q7XG5cdFx0fSApO1xuXHR9XG5cblx0Ly8gU2luZ2xlIGVsZW1lbnRcblx0aWYgKCBxdWFsaWZpZXIubm9kZVR5cGUgKSB7XG5cdFx0cmV0dXJuIGpRdWVyeS5ncmVwKCBlbGVtZW50cywgZnVuY3Rpb24oIGVsZW0gKSB7XG5cdFx0XHRyZXR1cm4gKCBlbGVtID09PSBxdWFsaWZpZXIgKSAhPT0gbm90O1xuXHRcdH0gKTtcblx0fVxuXG5cdC8vIEFycmF5bGlrZSBvZiBlbGVtZW50cyAoalF1ZXJ5LCBhcmd1bWVudHMsIEFycmF5KVxuXHRpZiAoIHR5cGVvZiBxdWFsaWZpZXIgIT09IFwic3RyaW5nXCIgKSB7XG5cdFx0cmV0dXJuIGpRdWVyeS5ncmVwKCBlbGVtZW50cywgZnVuY3Rpb24oIGVsZW0gKSB7XG5cdFx0XHRyZXR1cm4gKCBpbmRleE9mLmNhbGwoIHF1YWxpZmllciwgZWxlbSApID4gLTEgKSAhPT0gbm90O1xuXHRcdH0gKTtcblx0fVxuXG5cdC8vIFNpbXBsZSBzZWxlY3RvciB0aGF0IGNhbiBiZSBmaWx0ZXJlZCBkaXJlY3RseSwgcmVtb3Zpbmcgbm9uLUVsZW1lbnRzXG5cdGlmICggcmlzU2ltcGxlLnRlc3QoIHF1YWxpZmllciApICkge1xuXHRcdHJldHVybiBqUXVlcnkuZmlsdGVyKCBxdWFsaWZpZXIsIGVsZW1lbnRzLCBub3QgKTtcblx0fVxuXG5cdC8vIENvbXBsZXggc2VsZWN0b3IsIGNvbXBhcmUgdGhlIHR3byBzZXRzLCByZW1vdmluZyBub24tRWxlbWVudHNcblx0cXVhbGlmaWVyID0galF1ZXJ5LmZpbHRlciggcXVhbGlmaWVyLCBlbGVtZW50cyApO1xuXHRyZXR1cm4galF1ZXJ5LmdyZXAoIGVsZW1lbnRzLCBmdW5jdGlvbiggZWxlbSApIHtcblx0XHRyZXR1cm4gKCBpbmRleE9mLmNhbGwoIHF1YWxpZmllciwgZWxlbSApID4gLTEgKSAhPT0gbm90ICYmIGVsZW0ubm9kZVR5cGUgPT09IDE7XG5cdH0gKTtcbn1cblxualF1ZXJ5LmZpbHRlciA9IGZ1bmN0aW9uKCBleHByLCBlbGVtcywgbm90ICkge1xuXHR2YXIgZWxlbSA9IGVsZW1zWyAwIF07XG5cblx0aWYgKCBub3QgKSB7XG5cdFx0ZXhwciA9IFwiOm5vdChcIiArIGV4cHIgKyBcIilcIjtcblx0fVxuXG5cdGlmICggZWxlbXMubGVuZ3RoID09PSAxICYmIGVsZW0ubm9kZVR5cGUgPT09IDEgKSB7XG5cdFx0cmV0dXJuIGpRdWVyeS5maW5kLm1hdGNoZXNTZWxlY3RvciggZWxlbSwgZXhwciApID8gWyBlbGVtIF0gOiBbXTtcblx0fVxuXG5cdHJldHVybiBqUXVlcnkuZmluZC5tYXRjaGVzKCBleHByLCBqUXVlcnkuZ3JlcCggZWxlbXMsIGZ1bmN0aW9uKCBlbGVtICkge1xuXHRcdHJldHVybiBlbGVtLm5vZGVUeXBlID09PSAxO1xuXHR9ICkgKTtcbn07XG5cbmpRdWVyeS5mbi5leHRlbmQoIHtcblx0ZmluZDogZnVuY3Rpb24oIHNlbGVjdG9yICkge1xuXHRcdHZhciBpLCByZXQsXG5cdFx0XHRsZW4gPSB0aGlzLmxlbmd0aCxcblx0XHRcdHNlbGYgPSB0aGlzO1xuXG5cdFx0aWYgKCB0eXBlb2Ygc2VsZWN0b3IgIT09IFwic3RyaW5nXCIgKSB7XG5cdFx0XHRyZXR1cm4gdGhpcy5wdXNoU3RhY2soIGpRdWVyeSggc2VsZWN0b3IgKS5maWx0ZXIoIGZ1bmN0aW9uKCkge1xuXHRcdFx0XHRmb3IgKCBpID0gMDsgaSA8IGxlbjsgaSsrICkge1xuXHRcdFx0XHRcdGlmICggalF1ZXJ5LmNvbnRhaW5zKCBzZWxmWyBpIF0sIHRoaXMgKSApIHtcblx0XHRcdFx0XHRcdHJldHVybiB0cnVlO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXHRcdFx0fSApICk7XG5cdFx0fVxuXG5cdFx0cmV0ID0gdGhpcy5wdXNoU3RhY2soIFtdICk7XG5cblx0XHRmb3IgKCBpID0gMDsgaSA8IGxlbjsgaSsrICkge1xuXHRcdFx0alF1ZXJ5LmZpbmQoIHNlbGVjdG9yLCBzZWxmWyBpIF0sIHJldCApO1xuXHRcdH1cblxuXHRcdHJldHVybiBsZW4gPiAxID8galF1ZXJ5LnVuaXF1ZVNvcnQoIHJldCApIDogcmV0O1xuXHR9LFxuXHRmaWx0ZXI6IGZ1bmN0aW9uKCBzZWxlY3RvciApIHtcblx0XHRyZXR1cm4gdGhpcy5wdXNoU3RhY2soIHdpbm5vdyggdGhpcywgc2VsZWN0b3IgfHwgW10sIGZhbHNlICkgKTtcblx0fSxcblx0bm90OiBmdW5jdGlvbiggc2VsZWN0b3IgKSB7XG5cdFx0cmV0dXJuIHRoaXMucHVzaFN0YWNrKCB3aW5ub3coIHRoaXMsIHNlbGVjdG9yIHx8IFtdLCB0cnVlICkgKTtcblx0fSxcblx0aXM6IGZ1bmN0aW9uKCBzZWxlY3RvciApIHtcblx0XHRyZXR1cm4gISF3aW5ub3coXG5cdFx0XHR0aGlzLFxuXG5cdFx0XHQvLyBJZiB0aGlzIGlzIGEgcG9zaXRpb25hbC9yZWxhdGl2ZSBzZWxlY3RvciwgY2hlY2sgbWVtYmVyc2hpcCBpbiB0aGUgcmV0dXJuZWQgc2V0XG5cdFx0XHQvLyBzbyAkKFwicDpmaXJzdFwiKS5pcyhcInA6bGFzdFwiKSB3b24ndCByZXR1cm4gdHJ1ZSBmb3IgYSBkb2Mgd2l0aCB0d28gXCJwXCIuXG5cdFx0XHR0eXBlb2Ygc2VsZWN0b3IgPT09IFwic3RyaW5nXCIgJiYgcm5lZWRzQ29udGV4dC50ZXN0KCBzZWxlY3RvciApID9cblx0XHRcdFx0alF1ZXJ5KCBzZWxlY3RvciApIDpcblx0XHRcdFx0c2VsZWN0b3IgfHwgW10sXG5cdFx0XHRmYWxzZVxuXHRcdCkubGVuZ3RoO1xuXHR9XG59ICk7XG5cblxuLy8gSW5pdGlhbGl6ZSBhIGpRdWVyeSBvYmplY3RcblxuXG4vLyBBIGNlbnRyYWwgcmVmZXJlbmNlIHRvIHRoZSByb290IGpRdWVyeShkb2N1bWVudClcbnZhciByb290alF1ZXJ5LFxuXG5cdC8vIEEgc2ltcGxlIHdheSB0byBjaGVjayBmb3IgSFRNTCBzdHJpbmdzXG5cdC8vIFByaW9yaXRpemUgI2lkIG92ZXIgPHRhZz4gdG8gYXZvaWQgWFNTIHZpYSBsb2NhdGlvbi5oYXNoICgjOTUyMSlcblx0Ly8gU3RyaWN0IEhUTUwgcmVjb2duaXRpb24gKCMxMTI5MDogbXVzdCBzdGFydCB3aXRoIDwpXG5cdC8vIFNob3J0Y3V0IHNpbXBsZSAjaWQgY2FzZSBmb3Igc3BlZWRcblx0cnF1aWNrRXhwciA9IC9eKD86XFxzKig8W1xcd1xcV10rPilbXj5dKnwjKFtcXHctXSspKSQvLFxuXG5cdGluaXQgPSBqUXVlcnkuZm4uaW5pdCA9IGZ1bmN0aW9uKCBzZWxlY3RvciwgY29udGV4dCwgcm9vdCApIHtcblx0XHR2YXIgbWF0Y2gsIGVsZW07XG5cblx0XHQvLyBIQU5ETEU6ICQoXCJcIiksICQobnVsbCksICQodW5kZWZpbmVkKSwgJChmYWxzZSlcblx0XHRpZiAoICFzZWxlY3RvciApIHtcblx0XHRcdHJldHVybiB0aGlzO1xuXHRcdH1cblxuXHRcdC8vIE1ldGhvZCBpbml0KCkgYWNjZXB0cyBhbiBhbHRlcm5hdGUgcm9vdGpRdWVyeVxuXHRcdC8vIHNvIG1pZ3JhdGUgY2FuIHN1cHBvcnQgalF1ZXJ5LnN1YiAoZ2gtMjEwMSlcblx0XHRyb290ID0gcm9vdCB8fCByb290alF1ZXJ5O1xuXG5cdFx0Ly8gSGFuZGxlIEhUTUwgc3RyaW5nc1xuXHRcdGlmICggdHlwZW9mIHNlbGVjdG9yID09PSBcInN0cmluZ1wiICkge1xuXHRcdFx0aWYgKCBzZWxlY3RvclsgMCBdID09PSBcIjxcIiAmJlxuXHRcdFx0XHRzZWxlY3Rvclsgc2VsZWN0b3IubGVuZ3RoIC0gMSBdID09PSBcIj5cIiAmJlxuXHRcdFx0XHRzZWxlY3Rvci5sZW5ndGggPj0gMyApIHtcblxuXHRcdFx0XHQvLyBBc3N1bWUgdGhhdCBzdHJpbmdzIHRoYXQgc3RhcnQgYW5kIGVuZCB3aXRoIDw+IGFyZSBIVE1MIGFuZCBza2lwIHRoZSByZWdleCBjaGVja1xuXHRcdFx0XHRtYXRjaCA9IFsgbnVsbCwgc2VsZWN0b3IsIG51bGwgXTtcblxuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0bWF0Y2ggPSBycXVpY2tFeHByLmV4ZWMoIHNlbGVjdG9yICk7XG5cdFx0XHR9XG5cblx0XHRcdC8vIE1hdGNoIGh0bWwgb3IgbWFrZSBzdXJlIG5vIGNvbnRleHQgaXMgc3BlY2lmaWVkIGZvciAjaWRcblx0XHRcdGlmICggbWF0Y2ggJiYgKCBtYXRjaFsgMSBdIHx8ICFjb250ZXh0ICkgKSB7XG5cblx0XHRcdFx0Ly8gSEFORExFOiAkKGh0bWwpIC0+ICQoYXJyYXkpXG5cdFx0XHRcdGlmICggbWF0Y2hbIDEgXSApIHtcblx0XHRcdFx0XHRjb250ZXh0ID0gY29udGV4dCBpbnN0YW5jZW9mIGpRdWVyeSA/IGNvbnRleHRbIDAgXSA6IGNvbnRleHQ7XG5cblx0XHRcdFx0XHQvLyBPcHRpb24gdG8gcnVuIHNjcmlwdHMgaXMgdHJ1ZSBmb3IgYmFjay1jb21wYXRcblx0XHRcdFx0XHQvLyBJbnRlbnRpb25hbGx5IGxldCB0aGUgZXJyb3IgYmUgdGhyb3duIGlmIHBhcnNlSFRNTCBpcyBub3QgcHJlc2VudFxuXHRcdFx0XHRcdGpRdWVyeS5tZXJnZSggdGhpcywgalF1ZXJ5LnBhcnNlSFRNTChcblx0XHRcdFx0XHRcdG1hdGNoWyAxIF0sXG5cdFx0XHRcdFx0XHRjb250ZXh0ICYmIGNvbnRleHQubm9kZVR5cGUgPyBjb250ZXh0Lm93bmVyRG9jdW1lbnQgfHwgY29udGV4dCA6IGRvY3VtZW50LFxuXHRcdFx0XHRcdFx0dHJ1ZVxuXHRcdFx0XHRcdCkgKTtcblxuXHRcdFx0XHRcdC8vIEhBTkRMRTogJChodG1sLCBwcm9wcylcblx0XHRcdFx0XHRpZiAoIHJzaW5nbGVUYWcudGVzdCggbWF0Y2hbIDEgXSApICYmIGpRdWVyeS5pc1BsYWluT2JqZWN0KCBjb250ZXh0ICkgKSB7XG5cdFx0XHRcdFx0XHRmb3IgKCBtYXRjaCBpbiBjb250ZXh0ICkge1xuXG5cdFx0XHRcdFx0XHRcdC8vIFByb3BlcnRpZXMgb2YgY29udGV4dCBhcmUgY2FsbGVkIGFzIG1ldGhvZHMgaWYgcG9zc2libGVcblx0XHRcdFx0XHRcdFx0aWYgKCBqUXVlcnkuaXNGdW5jdGlvbiggdGhpc1sgbWF0Y2ggXSApICkge1xuXHRcdFx0XHRcdFx0XHRcdHRoaXNbIG1hdGNoIF0oIGNvbnRleHRbIG1hdGNoIF0gKTtcblxuXHRcdFx0XHRcdFx0XHQvLyAuLi5hbmQgb3RoZXJ3aXNlIHNldCBhcyBhdHRyaWJ1dGVzXG5cdFx0XHRcdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0XHRcdFx0dGhpcy5hdHRyKCBtYXRjaCwgY29udGV4dFsgbWF0Y2ggXSApO1xuXHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0cmV0dXJuIHRoaXM7XG5cblx0XHRcdFx0Ly8gSEFORExFOiAkKCNpZClcblx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRlbGVtID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoIG1hdGNoWyAyIF0gKTtcblxuXHRcdFx0XHRcdGlmICggZWxlbSApIHtcblxuXHRcdFx0XHRcdFx0Ly8gSW5qZWN0IHRoZSBlbGVtZW50IGRpcmVjdGx5IGludG8gdGhlIGpRdWVyeSBvYmplY3Rcblx0XHRcdFx0XHRcdHRoaXNbIDAgXSA9IGVsZW07XG5cdFx0XHRcdFx0XHR0aGlzLmxlbmd0aCA9IDE7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHRcdHJldHVybiB0aGlzO1xuXHRcdFx0XHR9XG5cblx0XHRcdC8vIEhBTkRMRTogJChleHByLCAkKC4uLikpXG5cdFx0XHR9IGVsc2UgaWYgKCAhY29udGV4dCB8fCBjb250ZXh0LmpxdWVyeSApIHtcblx0XHRcdFx0cmV0dXJuICggY29udGV4dCB8fCByb290ICkuZmluZCggc2VsZWN0b3IgKTtcblxuXHRcdFx0Ly8gSEFORExFOiAkKGV4cHIsIGNvbnRleHQpXG5cdFx0XHQvLyAod2hpY2ggaXMganVzdCBlcXVpdmFsZW50IHRvOiAkKGNvbnRleHQpLmZpbmQoZXhwcilcblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdHJldHVybiB0aGlzLmNvbnN0cnVjdG9yKCBjb250ZXh0ICkuZmluZCggc2VsZWN0b3IgKTtcblx0XHRcdH1cblxuXHRcdC8vIEhBTkRMRTogJChET01FbGVtZW50KVxuXHRcdH0gZWxzZSBpZiAoIHNlbGVjdG9yLm5vZGVUeXBlICkge1xuXHRcdFx0dGhpc1sgMCBdID0gc2VsZWN0b3I7XG5cdFx0XHR0aGlzLmxlbmd0aCA9IDE7XG5cdFx0XHRyZXR1cm4gdGhpcztcblxuXHRcdC8vIEhBTkRMRTogJChmdW5jdGlvbilcblx0XHQvLyBTaG9ydGN1dCBmb3IgZG9jdW1lbnQgcmVhZHlcblx0XHR9IGVsc2UgaWYgKCBqUXVlcnkuaXNGdW5jdGlvbiggc2VsZWN0b3IgKSApIHtcblx0XHRcdHJldHVybiByb290LnJlYWR5ICE9PSB1bmRlZmluZWQgP1xuXHRcdFx0XHRyb290LnJlYWR5KCBzZWxlY3RvciApIDpcblxuXHRcdFx0XHQvLyBFeGVjdXRlIGltbWVkaWF0ZWx5IGlmIHJlYWR5IGlzIG5vdCBwcmVzZW50XG5cdFx0XHRcdHNlbGVjdG9yKCBqUXVlcnkgKTtcblx0XHR9XG5cblx0XHRyZXR1cm4galF1ZXJ5Lm1ha2VBcnJheSggc2VsZWN0b3IsIHRoaXMgKTtcblx0fTtcblxuLy8gR2l2ZSB0aGUgaW5pdCBmdW5jdGlvbiB0aGUgalF1ZXJ5IHByb3RvdHlwZSBmb3IgbGF0ZXIgaW5zdGFudGlhdGlvblxuaW5pdC5wcm90b3R5cGUgPSBqUXVlcnkuZm47XG5cbi8vIEluaXRpYWxpemUgY2VudHJhbCByZWZlcmVuY2VcbnJvb3RqUXVlcnkgPSBqUXVlcnkoIGRvY3VtZW50ICk7XG5cblxudmFyIHJwYXJlbnRzcHJldiA9IC9eKD86cGFyZW50c3xwcmV2KD86VW50aWx8QWxsKSkvLFxuXG5cdC8vIE1ldGhvZHMgZ3VhcmFudGVlZCB0byBwcm9kdWNlIGEgdW5pcXVlIHNldCB3aGVuIHN0YXJ0aW5nIGZyb20gYSB1bmlxdWUgc2V0XG5cdGd1YXJhbnRlZWRVbmlxdWUgPSB7XG5cdFx0Y2hpbGRyZW46IHRydWUsXG5cdFx0Y29udGVudHM6IHRydWUsXG5cdFx0bmV4dDogdHJ1ZSxcblx0XHRwcmV2OiB0cnVlXG5cdH07XG5cbmpRdWVyeS5mbi5leHRlbmQoIHtcblx0aGFzOiBmdW5jdGlvbiggdGFyZ2V0ICkge1xuXHRcdHZhciB0YXJnZXRzID0galF1ZXJ5KCB0YXJnZXQsIHRoaXMgKSxcblx0XHRcdGwgPSB0YXJnZXRzLmxlbmd0aDtcblxuXHRcdHJldHVybiB0aGlzLmZpbHRlciggZnVuY3Rpb24oKSB7XG5cdFx0XHR2YXIgaSA9IDA7XG5cdFx0XHRmb3IgKCA7IGkgPCBsOyBpKysgKSB7XG5cdFx0XHRcdGlmICggalF1ZXJ5LmNvbnRhaW5zKCB0aGlzLCB0YXJnZXRzWyBpIF0gKSApIHtcblx0XHRcdFx0XHRyZXR1cm4gdHJ1ZTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH0gKTtcblx0fSxcblxuXHRjbG9zZXN0OiBmdW5jdGlvbiggc2VsZWN0b3JzLCBjb250ZXh0ICkge1xuXHRcdHZhciBjdXIsXG5cdFx0XHRpID0gMCxcblx0XHRcdGwgPSB0aGlzLmxlbmd0aCxcblx0XHRcdG1hdGNoZWQgPSBbXSxcblx0XHRcdHRhcmdldHMgPSB0eXBlb2Ygc2VsZWN0b3JzICE9PSBcInN0cmluZ1wiICYmIGpRdWVyeSggc2VsZWN0b3JzICk7XG5cblx0XHQvLyBQb3NpdGlvbmFsIHNlbGVjdG9ycyBuZXZlciBtYXRjaCwgc2luY2UgdGhlcmUncyBubyBfc2VsZWN0aW9uXyBjb250ZXh0XG5cdFx0aWYgKCAhcm5lZWRzQ29udGV4dC50ZXN0KCBzZWxlY3RvcnMgKSApIHtcblx0XHRcdGZvciAoIDsgaSA8IGw7IGkrKyApIHtcblx0XHRcdFx0Zm9yICggY3VyID0gdGhpc1sgaSBdOyBjdXIgJiYgY3VyICE9PSBjb250ZXh0OyBjdXIgPSBjdXIucGFyZW50Tm9kZSApIHtcblxuXHRcdFx0XHRcdC8vIEFsd2F5cyBza2lwIGRvY3VtZW50IGZyYWdtZW50c1xuXHRcdFx0XHRcdGlmICggY3VyLm5vZGVUeXBlIDwgMTEgJiYgKCB0YXJnZXRzID9cblx0XHRcdFx0XHRcdHRhcmdldHMuaW5kZXgoIGN1ciApID4gLTEgOlxuXG5cdFx0XHRcdFx0XHQvLyBEb24ndCBwYXNzIG5vbi1lbGVtZW50cyB0byBTaXp6bGVcblx0XHRcdFx0XHRcdGN1ci5ub2RlVHlwZSA9PT0gMSAmJlxuXHRcdFx0XHRcdFx0XHRqUXVlcnkuZmluZC5tYXRjaGVzU2VsZWN0b3IoIGN1ciwgc2VsZWN0b3JzICkgKSApIHtcblxuXHRcdFx0XHRcdFx0bWF0Y2hlZC5wdXNoKCBjdXIgKTtcblx0XHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH1cblxuXHRcdHJldHVybiB0aGlzLnB1c2hTdGFjayggbWF0Y2hlZC5sZW5ndGggPiAxID8galF1ZXJ5LnVuaXF1ZVNvcnQoIG1hdGNoZWQgKSA6IG1hdGNoZWQgKTtcblx0fSxcblxuXHQvLyBEZXRlcm1pbmUgdGhlIHBvc2l0aW9uIG9mIGFuIGVsZW1lbnQgd2l0aGluIHRoZSBzZXRcblx0aW5kZXg6IGZ1bmN0aW9uKCBlbGVtICkge1xuXG5cdFx0Ly8gTm8gYXJndW1lbnQsIHJldHVybiBpbmRleCBpbiBwYXJlbnRcblx0XHRpZiAoICFlbGVtICkge1xuXHRcdFx0cmV0dXJuICggdGhpc1sgMCBdICYmIHRoaXNbIDAgXS5wYXJlbnROb2RlICkgPyB0aGlzLmZpcnN0KCkucHJldkFsbCgpLmxlbmd0aCA6IC0xO1xuXHRcdH1cblxuXHRcdC8vIEluZGV4IGluIHNlbGVjdG9yXG5cdFx0aWYgKCB0eXBlb2YgZWxlbSA9PT0gXCJzdHJpbmdcIiApIHtcblx0XHRcdHJldHVybiBpbmRleE9mLmNhbGwoIGpRdWVyeSggZWxlbSApLCB0aGlzWyAwIF0gKTtcblx0XHR9XG5cblx0XHQvLyBMb2NhdGUgdGhlIHBvc2l0aW9uIG9mIHRoZSBkZXNpcmVkIGVsZW1lbnRcblx0XHRyZXR1cm4gaW5kZXhPZi5jYWxsKCB0aGlzLFxuXG5cdFx0XHQvLyBJZiBpdCByZWNlaXZlcyBhIGpRdWVyeSBvYmplY3QsIHRoZSBmaXJzdCBlbGVtZW50IGlzIHVzZWRcblx0XHRcdGVsZW0uanF1ZXJ5ID8gZWxlbVsgMCBdIDogZWxlbVxuXHRcdCk7XG5cdH0sXG5cblx0YWRkOiBmdW5jdGlvbiggc2VsZWN0b3IsIGNvbnRleHQgKSB7XG5cdFx0cmV0dXJuIHRoaXMucHVzaFN0YWNrKFxuXHRcdFx0alF1ZXJ5LnVuaXF1ZVNvcnQoXG5cdFx0XHRcdGpRdWVyeS5tZXJnZSggdGhpcy5nZXQoKSwgalF1ZXJ5KCBzZWxlY3RvciwgY29udGV4dCApIClcblx0XHRcdClcblx0XHQpO1xuXHR9LFxuXG5cdGFkZEJhY2s6IGZ1bmN0aW9uKCBzZWxlY3RvciApIHtcblx0XHRyZXR1cm4gdGhpcy5hZGQoIHNlbGVjdG9yID09IG51bGwgP1xuXHRcdFx0dGhpcy5wcmV2T2JqZWN0IDogdGhpcy5wcmV2T2JqZWN0LmZpbHRlciggc2VsZWN0b3IgKVxuXHRcdCk7XG5cdH1cbn0gKTtcblxuZnVuY3Rpb24gc2libGluZyggY3VyLCBkaXIgKSB7XG5cdHdoaWxlICggKCBjdXIgPSBjdXJbIGRpciBdICkgJiYgY3VyLm5vZGVUeXBlICE9PSAxICkge31cblx0cmV0dXJuIGN1cjtcbn1cblxualF1ZXJ5LmVhY2goIHtcblx0cGFyZW50OiBmdW5jdGlvbiggZWxlbSApIHtcblx0XHR2YXIgcGFyZW50ID0gZWxlbS5wYXJlbnROb2RlO1xuXHRcdHJldHVybiBwYXJlbnQgJiYgcGFyZW50Lm5vZGVUeXBlICE9PSAxMSA/IHBhcmVudCA6IG51bGw7XG5cdH0sXG5cdHBhcmVudHM6IGZ1bmN0aW9uKCBlbGVtICkge1xuXHRcdHJldHVybiBkaXIoIGVsZW0sIFwicGFyZW50Tm9kZVwiICk7XG5cdH0sXG5cdHBhcmVudHNVbnRpbDogZnVuY3Rpb24oIGVsZW0sIGksIHVudGlsICkge1xuXHRcdHJldHVybiBkaXIoIGVsZW0sIFwicGFyZW50Tm9kZVwiLCB1bnRpbCApO1xuXHR9LFxuXHRuZXh0OiBmdW5jdGlvbiggZWxlbSApIHtcblx0XHRyZXR1cm4gc2libGluZyggZWxlbSwgXCJuZXh0U2libGluZ1wiICk7XG5cdH0sXG5cdHByZXY6IGZ1bmN0aW9uKCBlbGVtICkge1xuXHRcdHJldHVybiBzaWJsaW5nKCBlbGVtLCBcInByZXZpb3VzU2libGluZ1wiICk7XG5cdH0sXG5cdG5leHRBbGw6IGZ1bmN0aW9uKCBlbGVtICkge1xuXHRcdHJldHVybiBkaXIoIGVsZW0sIFwibmV4dFNpYmxpbmdcIiApO1xuXHR9LFxuXHRwcmV2QWxsOiBmdW5jdGlvbiggZWxlbSApIHtcblx0XHRyZXR1cm4gZGlyKCBlbGVtLCBcInByZXZpb3VzU2libGluZ1wiICk7XG5cdH0sXG5cdG5leHRVbnRpbDogZnVuY3Rpb24oIGVsZW0sIGksIHVudGlsICkge1xuXHRcdHJldHVybiBkaXIoIGVsZW0sIFwibmV4dFNpYmxpbmdcIiwgdW50aWwgKTtcblx0fSxcblx0cHJldlVudGlsOiBmdW5jdGlvbiggZWxlbSwgaSwgdW50aWwgKSB7XG5cdFx0cmV0dXJuIGRpciggZWxlbSwgXCJwcmV2aW91c1NpYmxpbmdcIiwgdW50aWwgKTtcblx0fSxcblx0c2libGluZ3M6IGZ1bmN0aW9uKCBlbGVtICkge1xuXHRcdHJldHVybiBzaWJsaW5ncyggKCBlbGVtLnBhcmVudE5vZGUgfHwge30gKS5maXJzdENoaWxkLCBlbGVtICk7XG5cdH0sXG5cdGNoaWxkcmVuOiBmdW5jdGlvbiggZWxlbSApIHtcblx0XHRyZXR1cm4gc2libGluZ3MoIGVsZW0uZmlyc3RDaGlsZCApO1xuXHR9LFxuXHRjb250ZW50czogZnVuY3Rpb24oIGVsZW0gKSB7XG4gICAgICAgIGlmICggbm9kZU5hbWUoIGVsZW0sIFwiaWZyYW1lXCIgKSApIHtcbiAgICAgICAgICAgIHJldHVybiBlbGVtLmNvbnRlbnREb2N1bWVudDtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIFN1cHBvcnQ6IElFIDkgLSAxMSBvbmx5LCBpT1MgNyBvbmx5LCBBbmRyb2lkIEJyb3dzZXIgPD00LjMgb25seVxuICAgICAgICAvLyBUcmVhdCB0aGUgdGVtcGxhdGUgZWxlbWVudCBhcyBhIHJlZ3VsYXIgb25lIGluIGJyb3dzZXJzIHRoYXRcbiAgICAgICAgLy8gZG9uJ3Qgc3VwcG9ydCBpdC5cbiAgICAgICAgaWYgKCBub2RlTmFtZSggZWxlbSwgXCJ0ZW1wbGF0ZVwiICkgKSB7XG4gICAgICAgICAgICBlbGVtID0gZWxlbS5jb250ZW50IHx8IGVsZW07XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4galF1ZXJ5Lm1lcmdlKCBbXSwgZWxlbS5jaGlsZE5vZGVzICk7XG5cdH1cbn0sIGZ1bmN0aW9uKCBuYW1lLCBmbiApIHtcblx0alF1ZXJ5LmZuWyBuYW1lIF0gPSBmdW5jdGlvbiggdW50aWwsIHNlbGVjdG9yICkge1xuXHRcdHZhciBtYXRjaGVkID0galF1ZXJ5Lm1hcCggdGhpcywgZm4sIHVudGlsICk7XG5cblx0XHRpZiAoIG5hbWUuc2xpY2UoIC01ICkgIT09IFwiVW50aWxcIiApIHtcblx0XHRcdHNlbGVjdG9yID0gdW50aWw7XG5cdFx0fVxuXG5cdFx0aWYgKCBzZWxlY3RvciAmJiB0eXBlb2Ygc2VsZWN0b3IgPT09IFwic3RyaW5nXCIgKSB7XG5cdFx0XHRtYXRjaGVkID0galF1ZXJ5LmZpbHRlciggc2VsZWN0b3IsIG1hdGNoZWQgKTtcblx0XHR9XG5cblx0XHRpZiAoIHRoaXMubGVuZ3RoID4gMSApIHtcblxuXHRcdFx0Ly8gUmVtb3ZlIGR1cGxpY2F0ZXNcblx0XHRcdGlmICggIWd1YXJhbnRlZWRVbmlxdWVbIG5hbWUgXSApIHtcblx0XHRcdFx0alF1ZXJ5LnVuaXF1ZVNvcnQoIG1hdGNoZWQgKTtcblx0XHRcdH1cblxuXHRcdFx0Ly8gUmV2ZXJzZSBvcmRlciBmb3IgcGFyZW50cyogYW5kIHByZXYtZGVyaXZhdGl2ZXNcblx0XHRcdGlmICggcnBhcmVudHNwcmV2LnRlc3QoIG5hbWUgKSApIHtcblx0XHRcdFx0bWF0Y2hlZC5yZXZlcnNlKCk7XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0cmV0dXJuIHRoaXMucHVzaFN0YWNrKCBtYXRjaGVkICk7XG5cdH07XG59ICk7XG52YXIgcm5vdGh0bWx3aGl0ZSA9ICggL1teXFx4MjBcXHRcXHJcXG5cXGZdKy9nICk7XG5cblxuXG4vLyBDb252ZXJ0IFN0cmluZy1mb3JtYXR0ZWQgb3B0aW9ucyBpbnRvIE9iamVjdC1mb3JtYXR0ZWQgb25lc1xuZnVuY3Rpb24gY3JlYXRlT3B0aW9ucyggb3B0aW9ucyApIHtcblx0dmFyIG9iamVjdCA9IHt9O1xuXHRqUXVlcnkuZWFjaCggb3B0aW9ucy5tYXRjaCggcm5vdGh0bWx3aGl0ZSApIHx8IFtdLCBmdW5jdGlvbiggXywgZmxhZyApIHtcblx0XHRvYmplY3RbIGZsYWcgXSA9IHRydWU7XG5cdH0gKTtcblx0cmV0dXJuIG9iamVjdDtcbn1cblxuLypcbiAqIENyZWF0ZSBhIGNhbGxiYWNrIGxpc3QgdXNpbmcgdGhlIGZvbGxvd2luZyBwYXJhbWV0ZXJzOlxuICpcbiAqXHRvcHRpb25zOiBhbiBvcHRpb25hbCBsaXN0IG9mIHNwYWNlLXNlcGFyYXRlZCBvcHRpb25zIHRoYXQgd2lsbCBjaGFuZ2UgaG93XG4gKlx0XHRcdHRoZSBjYWxsYmFjayBsaXN0IGJlaGF2ZXMgb3IgYSBtb3JlIHRyYWRpdGlvbmFsIG9wdGlvbiBvYmplY3RcbiAqXG4gKiBCeSBkZWZhdWx0IGEgY2FsbGJhY2sgbGlzdCB3aWxsIGFjdCBsaWtlIGFuIGV2ZW50IGNhbGxiYWNrIGxpc3QgYW5kIGNhbiBiZVxuICogXCJmaXJlZFwiIG11bHRpcGxlIHRpbWVzLlxuICpcbiAqIFBvc3NpYmxlIG9wdGlvbnM6XG4gKlxuICpcdG9uY2U6XHRcdFx0d2lsbCBlbnN1cmUgdGhlIGNhbGxiYWNrIGxpc3QgY2FuIG9ubHkgYmUgZmlyZWQgb25jZSAobGlrZSBhIERlZmVycmVkKVxuICpcbiAqXHRtZW1vcnk6XHRcdFx0d2lsbCBrZWVwIHRyYWNrIG9mIHByZXZpb3VzIHZhbHVlcyBhbmQgd2lsbCBjYWxsIGFueSBjYWxsYmFjayBhZGRlZFxuICpcdFx0XHRcdFx0YWZ0ZXIgdGhlIGxpc3QgaGFzIGJlZW4gZmlyZWQgcmlnaHQgYXdheSB3aXRoIHRoZSBsYXRlc3QgXCJtZW1vcml6ZWRcIlxuICpcdFx0XHRcdFx0dmFsdWVzIChsaWtlIGEgRGVmZXJyZWQpXG4gKlxuICpcdHVuaXF1ZTpcdFx0XHR3aWxsIGVuc3VyZSBhIGNhbGxiYWNrIGNhbiBvbmx5IGJlIGFkZGVkIG9uY2UgKG5vIGR1cGxpY2F0ZSBpbiB0aGUgbGlzdClcbiAqXG4gKlx0c3RvcE9uRmFsc2U6XHRpbnRlcnJ1cHQgY2FsbGluZ3Mgd2hlbiBhIGNhbGxiYWNrIHJldHVybnMgZmFsc2VcbiAqXG4gKi9cbmpRdWVyeS5DYWxsYmFja3MgPSBmdW5jdGlvbiggb3B0aW9ucyApIHtcblxuXHQvLyBDb252ZXJ0IG9wdGlvbnMgZnJvbSBTdHJpbmctZm9ybWF0dGVkIHRvIE9iamVjdC1mb3JtYXR0ZWQgaWYgbmVlZGVkXG5cdC8vICh3ZSBjaGVjayBpbiBjYWNoZSBmaXJzdClcblx0b3B0aW9ucyA9IHR5cGVvZiBvcHRpb25zID09PSBcInN0cmluZ1wiID9cblx0XHRjcmVhdGVPcHRpb25zKCBvcHRpb25zICkgOlxuXHRcdGpRdWVyeS5leHRlbmQoIHt9LCBvcHRpb25zICk7XG5cblx0dmFyIC8vIEZsYWcgdG8ga25vdyBpZiBsaXN0IGlzIGN1cnJlbnRseSBmaXJpbmdcblx0XHRmaXJpbmcsXG5cblx0XHQvLyBMYXN0IGZpcmUgdmFsdWUgZm9yIG5vbi1mb3JnZXR0YWJsZSBsaXN0c1xuXHRcdG1lbW9yeSxcblxuXHRcdC8vIEZsYWcgdG8ga25vdyBpZiBsaXN0IHdhcyBhbHJlYWR5IGZpcmVkXG5cdFx0ZmlyZWQsXG5cblx0XHQvLyBGbGFnIHRvIHByZXZlbnQgZmlyaW5nXG5cdFx0bG9ja2VkLFxuXG5cdFx0Ly8gQWN0dWFsIGNhbGxiYWNrIGxpc3Rcblx0XHRsaXN0ID0gW10sXG5cblx0XHQvLyBRdWV1ZSBvZiBleGVjdXRpb24gZGF0YSBmb3IgcmVwZWF0YWJsZSBsaXN0c1xuXHRcdHF1ZXVlID0gW10sXG5cblx0XHQvLyBJbmRleCBvZiBjdXJyZW50bHkgZmlyaW5nIGNhbGxiYWNrIChtb2RpZmllZCBieSBhZGQvcmVtb3ZlIGFzIG5lZWRlZClcblx0XHRmaXJpbmdJbmRleCA9IC0xLFxuXG5cdFx0Ly8gRmlyZSBjYWxsYmFja3Ncblx0XHRmaXJlID0gZnVuY3Rpb24oKSB7XG5cblx0XHRcdC8vIEVuZm9yY2Ugc2luZ2xlLWZpcmluZ1xuXHRcdFx0bG9ja2VkID0gbG9ja2VkIHx8IG9wdGlvbnMub25jZTtcblxuXHRcdFx0Ly8gRXhlY3V0ZSBjYWxsYmFja3MgZm9yIGFsbCBwZW5kaW5nIGV4ZWN1dGlvbnMsXG5cdFx0XHQvLyByZXNwZWN0aW5nIGZpcmluZ0luZGV4IG92ZXJyaWRlcyBhbmQgcnVudGltZSBjaGFuZ2VzXG5cdFx0XHRmaXJlZCA9IGZpcmluZyA9IHRydWU7XG5cdFx0XHRmb3IgKCA7IHF1ZXVlLmxlbmd0aDsgZmlyaW5nSW5kZXggPSAtMSApIHtcblx0XHRcdFx0bWVtb3J5ID0gcXVldWUuc2hpZnQoKTtcblx0XHRcdFx0d2hpbGUgKCArK2ZpcmluZ0luZGV4IDwgbGlzdC5sZW5ndGggKSB7XG5cblx0XHRcdFx0XHQvLyBSdW4gY2FsbGJhY2sgYW5kIGNoZWNrIGZvciBlYXJseSB0ZXJtaW5hdGlvblxuXHRcdFx0XHRcdGlmICggbGlzdFsgZmlyaW5nSW5kZXggXS5hcHBseSggbWVtb3J5WyAwIF0sIG1lbW9yeVsgMSBdICkgPT09IGZhbHNlICYmXG5cdFx0XHRcdFx0XHRvcHRpb25zLnN0b3BPbkZhbHNlICkge1xuXG5cdFx0XHRcdFx0XHQvLyBKdW1wIHRvIGVuZCBhbmQgZm9yZ2V0IHRoZSBkYXRhIHNvIC5hZGQgZG9lc24ndCByZS1maXJlXG5cdFx0XHRcdFx0XHRmaXJpbmdJbmRleCA9IGxpc3QubGVuZ3RoO1xuXHRcdFx0XHRcdFx0bWVtb3J5ID0gZmFsc2U7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cdFx0XHR9XG5cblx0XHRcdC8vIEZvcmdldCB0aGUgZGF0YSBpZiB3ZSdyZSBkb25lIHdpdGggaXRcblx0XHRcdGlmICggIW9wdGlvbnMubWVtb3J5ICkge1xuXHRcdFx0XHRtZW1vcnkgPSBmYWxzZTtcblx0XHRcdH1cblxuXHRcdFx0ZmlyaW5nID0gZmFsc2U7XG5cblx0XHRcdC8vIENsZWFuIHVwIGlmIHdlJ3JlIGRvbmUgZmlyaW5nIGZvciBnb29kXG5cdFx0XHRpZiAoIGxvY2tlZCApIHtcblxuXHRcdFx0XHQvLyBLZWVwIGFuIGVtcHR5IGxpc3QgaWYgd2UgaGF2ZSBkYXRhIGZvciBmdXR1cmUgYWRkIGNhbGxzXG5cdFx0XHRcdGlmICggbWVtb3J5ICkge1xuXHRcdFx0XHRcdGxpc3QgPSBbXTtcblxuXHRcdFx0XHQvLyBPdGhlcndpc2UsIHRoaXMgb2JqZWN0IGlzIHNwZW50XG5cdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0bGlzdCA9IFwiXCI7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9LFxuXG5cdFx0Ly8gQWN0dWFsIENhbGxiYWNrcyBvYmplY3Rcblx0XHRzZWxmID0ge1xuXG5cdFx0XHQvLyBBZGQgYSBjYWxsYmFjayBvciBhIGNvbGxlY3Rpb24gb2YgY2FsbGJhY2tzIHRvIHRoZSBsaXN0XG5cdFx0XHRhZGQ6IGZ1bmN0aW9uKCkge1xuXHRcdFx0XHRpZiAoIGxpc3QgKSB7XG5cblx0XHRcdFx0XHQvLyBJZiB3ZSBoYXZlIG1lbW9yeSBmcm9tIGEgcGFzdCBydW4sIHdlIHNob3VsZCBmaXJlIGFmdGVyIGFkZGluZ1xuXHRcdFx0XHRcdGlmICggbWVtb3J5ICYmICFmaXJpbmcgKSB7XG5cdFx0XHRcdFx0XHRmaXJpbmdJbmRleCA9IGxpc3QubGVuZ3RoIC0gMTtcblx0XHRcdFx0XHRcdHF1ZXVlLnB1c2goIG1lbW9yeSApO1xuXHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdCggZnVuY3Rpb24gYWRkKCBhcmdzICkge1xuXHRcdFx0XHRcdFx0alF1ZXJ5LmVhY2goIGFyZ3MsIGZ1bmN0aW9uKCBfLCBhcmcgKSB7XG5cdFx0XHRcdFx0XHRcdGlmICggalF1ZXJ5LmlzRnVuY3Rpb24oIGFyZyApICkge1xuXHRcdFx0XHRcdFx0XHRcdGlmICggIW9wdGlvbnMudW5pcXVlIHx8ICFzZWxmLmhhcyggYXJnICkgKSB7XG5cdFx0XHRcdFx0XHRcdFx0XHRsaXN0LnB1c2goIGFyZyApO1xuXHRcdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdFx0fSBlbHNlIGlmICggYXJnICYmIGFyZy5sZW5ndGggJiYgalF1ZXJ5LnR5cGUoIGFyZyApICE9PSBcInN0cmluZ1wiICkge1xuXG5cdFx0XHRcdFx0XHRcdFx0Ly8gSW5zcGVjdCByZWN1cnNpdmVseVxuXHRcdFx0XHRcdFx0XHRcdGFkZCggYXJnICk7XG5cdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdH0gKTtcblx0XHRcdFx0XHR9ICkoIGFyZ3VtZW50cyApO1xuXG5cdFx0XHRcdFx0aWYgKCBtZW1vcnkgJiYgIWZpcmluZyApIHtcblx0XHRcdFx0XHRcdGZpcmUoKTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblx0XHRcdFx0cmV0dXJuIHRoaXM7XG5cdFx0XHR9LFxuXG5cdFx0XHQvLyBSZW1vdmUgYSBjYWxsYmFjayBmcm9tIHRoZSBsaXN0XG5cdFx0XHRyZW1vdmU6IGZ1bmN0aW9uKCkge1xuXHRcdFx0XHRqUXVlcnkuZWFjaCggYXJndW1lbnRzLCBmdW5jdGlvbiggXywgYXJnICkge1xuXHRcdFx0XHRcdHZhciBpbmRleDtcblx0XHRcdFx0XHR3aGlsZSAoICggaW5kZXggPSBqUXVlcnkuaW5BcnJheSggYXJnLCBsaXN0LCBpbmRleCApICkgPiAtMSApIHtcblx0XHRcdFx0XHRcdGxpc3Quc3BsaWNlKCBpbmRleCwgMSApO1xuXG5cdFx0XHRcdFx0XHQvLyBIYW5kbGUgZmlyaW5nIGluZGV4ZXNcblx0XHRcdFx0XHRcdGlmICggaW5kZXggPD0gZmlyaW5nSW5kZXggKSB7XG5cdFx0XHRcdFx0XHRcdGZpcmluZ0luZGV4LS07XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9ICk7XG5cdFx0XHRcdHJldHVybiB0aGlzO1xuXHRcdFx0fSxcblxuXHRcdFx0Ly8gQ2hlY2sgaWYgYSBnaXZlbiBjYWxsYmFjayBpcyBpbiB0aGUgbGlzdC5cblx0XHRcdC8vIElmIG5vIGFyZ3VtZW50IGlzIGdpdmVuLCByZXR1cm4gd2hldGhlciBvciBub3QgbGlzdCBoYXMgY2FsbGJhY2tzIGF0dGFjaGVkLlxuXHRcdFx0aGFzOiBmdW5jdGlvbiggZm4gKSB7XG5cdFx0XHRcdHJldHVybiBmbiA/XG5cdFx0XHRcdFx0alF1ZXJ5LmluQXJyYXkoIGZuLCBsaXN0ICkgPiAtMSA6XG5cdFx0XHRcdFx0bGlzdC5sZW5ndGggPiAwO1xuXHRcdFx0fSxcblxuXHRcdFx0Ly8gUmVtb3ZlIGFsbCBjYWxsYmFja3MgZnJvbSB0aGUgbGlzdFxuXHRcdFx0ZW1wdHk6IGZ1bmN0aW9uKCkge1xuXHRcdFx0XHRpZiAoIGxpc3QgKSB7XG5cdFx0XHRcdFx0bGlzdCA9IFtdO1xuXHRcdFx0XHR9XG5cdFx0XHRcdHJldHVybiB0aGlzO1xuXHRcdFx0fSxcblxuXHRcdFx0Ly8gRGlzYWJsZSAuZmlyZSBhbmQgLmFkZFxuXHRcdFx0Ly8gQWJvcnQgYW55IGN1cnJlbnQvcGVuZGluZyBleGVjdXRpb25zXG5cdFx0XHQvLyBDbGVhciBhbGwgY2FsbGJhY2tzIGFuZCB2YWx1ZXNcblx0XHRcdGRpc2FibGU6IGZ1bmN0aW9uKCkge1xuXHRcdFx0XHRsb2NrZWQgPSBxdWV1ZSA9IFtdO1xuXHRcdFx0XHRsaXN0ID0gbWVtb3J5ID0gXCJcIjtcblx0XHRcdFx0cmV0dXJuIHRoaXM7XG5cdFx0XHR9LFxuXHRcdFx0ZGlzYWJsZWQ6IGZ1bmN0aW9uKCkge1xuXHRcdFx0XHRyZXR1cm4gIWxpc3Q7XG5cdFx0XHR9LFxuXG5cdFx0XHQvLyBEaXNhYmxlIC5maXJlXG5cdFx0XHQvLyBBbHNvIGRpc2FibGUgLmFkZCB1bmxlc3Mgd2UgaGF2ZSBtZW1vcnkgKHNpbmNlIGl0IHdvdWxkIGhhdmUgbm8gZWZmZWN0KVxuXHRcdFx0Ly8gQWJvcnQgYW55IHBlbmRpbmcgZXhlY3V0aW9uc1xuXHRcdFx0bG9jazogZnVuY3Rpb24oKSB7XG5cdFx0XHRcdGxvY2tlZCA9IHF1ZXVlID0gW107XG5cdFx0XHRcdGlmICggIW1lbW9yeSAmJiAhZmlyaW5nICkge1xuXHRcdFx0XHRcdGxpc3QgPSBtZW1vcnkgPSBcIlwiO1xuXHRcdFx0XHR9XG5cdFx0XHRcdHJldHVybiB0aGlzO1xuXHRcdFx0fSxcblx0XHRcdGxvY2tlZDogZnVuY3Rpb24oKSB7XG5cdFx0XHRcdHJldHVybiAhIWxvY2tlZDtcblx0XHRcdH0sXG5cblx0XHRcdC8vIENhbGwgYWxsIGNhbGxiYWNrcyB3aXRoIHRoZSBnaXZlbiBjb250ZXh0IGFuZCBhcmd1bWVudHNcblx0XHRcdGZpcmVXaXRoOiBmdW5jdGlvbiggY29udGV4dCwgYXJncyApIHtcblx0XHRcdFx0aWYgKCAhbG9ja2VkICkge1xuXHRcdFx0XHRcdGFyZ3MgPSBhcmdzIHx8IFtdO1xuXHRcdFx0XHRcdGFyZ3MgPSBbIGNvbnRleHQsIGFyZ3Muc2xpY2UgPyBhcmdzLnNsaWNlKCkgOiBhcmdzIF07XG5cdFx0XHRcdFx0cXVldWUucHVzaCggYXJncyApO1xuXHRcdFx0XHRcdGlmICggIWZpcmluZyApIHtcblx0XHRcdFx0XHRcdGZpcmUoKTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblx0XHRcdFx0cmV0dXJuIHRoaXM7XG5cdFx0XHR9LFxuXG5cdFx0XHQvLyBDYWxsIGFsbCB0aGUgY2FsbGJhY2tzIHdpdGggdGhlIGdpdmVuIGFyZ3VtZW50c1xuXHRcdFx0ZmlyZTogZnVuY3Rpb24oKSB7XG5cdFx0XHRcdHNlbGYuZmlyZVdpdGgoIHRoaXMsIGFyZ3VtZW50cyApO1xuXHRcdFx0XHRyZXR1cm4gdGhpcztcblx0XHRcdH0sXG5cblx0XHRcdC8vIFRvIGtub3cgaWYgdGhlIGNhbGxiYWNrcyBoYXZlIGFscmVhZHkgYmVlbiBjYWxsZWQgYXQgbGVhc3Qgb25jZVxuXHRcdFx0ZmlyZWQ6IGZ1bmN0aW9uKCkge1xuXHRcdFx0XHRyZXR1cm4gISFmaXJlZDtcblx0XHRcdH1cblx0XHR9O1xuXG5cdHJldHVybiBzZWxmO1xufTtcblxuXG5mdW5jdGlvbiBJZGVudGl0eSggdiApIHtcblx0cmV0dXJuIHY7XG59XG5mdW5jdGlvbiBUaHJvd2VyKCBleCApIHtcblx0dGhyb3cgZXg7XG59XG5cbmZ1bmN0aW9uIGFkb3B0VmFsdWUoIHZhbHVlLCByZXNvbHZlLCByZWplY3QsIG5vVmFsdWUgKSB7XG5cdHZhciBtZXRob2Q7XG5cblx0dHJ5IHtcblxuXHRcdC8vIENoZWNrIGZvciBwcm9taXNlIGFzcGVjdCBmaXJzdCB0byBwcml2aWxlZ2Ugc3luY2hyb25vdXMgYmVoYXZpb3Jcblx0XHRpZiAoIHZhbHVlICYmIGpRdWVyeS5pc0Z1bmN0aW9uKCAoIG1ldGhvZCA9IHZhbHVlLnByb21pc2UgKSApICkge1xuXHRcdFx0bWV0aG9kLmNhbGwoIHZhbHVlICkuZG9uZSggcmVzb2x2ZSApLmZhaWwoIHJlamVjdCApO1xuXG5cdFx0Ly8gT3RoZXIgdGhlbmFibGVzXG5cdFx0fSBlbHNlIGlmICggdmFsdWUgJiYgalF1ZXJ5LmlzRnVuY3Rpb24oICggbWV0aG9kID0gdmFsdWUudGhlbiApICkgKSB7XG5cdFx0XHRtZXRob2QuY2FsbCggdmFsdWUsIHJlc29sdmUsIHJlamVjdCApO1xuXG5cdFx0Ly8gT3RoZXIgbm9uLXRoZW5hYmxlc1xuXHRcdH0gZWxzZSB7XG5cblx0XHRcdC8vIENvbnRyb2wgYHJlc29sdmVgIGFyZ3VtZW50cyBieSBsZXR0aW5nIEFycmF5I3NsaWNlIGNhc3QgYm9vbGVhbiBgbm9WYWx1ZWAgdG8gaW50ZWdlcjpcblx0XHRcdC8vICogZmFsc2U6IFsgdmFsdWUgXS5zbGljZSggMCApID0+IHJlc29sdmUoIHZhbHVlIClcblx0XHRcdC8vICogdHJ1ZTogWyB2YWx1ZSBdLnNsaWNlKCAxICkgPT4gcmVzb2x2ZSgpXG5cdFx0XHRyZXNvbHZlLmFwcGx5KCB1bmRlZmluZWQsIFsgdmFsdWUgXS5zbGljZSggbm9WYWx1ZSApICk7XG5cdFx0fVxuXG5cdC8vIEZvciBQcm9taXNlcy9BKywgY29udmVydCBleGNlcHRpb25zIGludG8gcmVqZWN0aW9uc1xuXHQvLyBTaW5jZSBqUXVlcnkud2hlbiBkb2Vzbid0IHVud3JhcCB0aGVuYWJsZXMsIHdlIGNhbiBza2lwIHRoZSBleHRyYSBjaGVja3MgYXBwZWFyaW5nIGluXG5cdC8vIERlZmVycmVkI3RoZW4gdG8gY29uZGl0aW9uYWxseSBzdXBwcmVzcyByZWplY3Rpb24uXG5cdH0gY2F0Y2ggKCB2YWx1ZSApIHtcblxuXHRcdC8vIFN1cHBvcnQ6IEFuZHJvaWQgNC4wIG9ubHlcblx0XHQvLyBTdHJpY3QgbW9kZSBmdW5jdGlvbnMgaW52b2tlZCB3aXRob3V0IC5jYWxsLy5hcHBseSBnZXQgZ2xvYmFsLW9iamVjdCBjb250ZXh0XG5cdFx0cmVqZWN0LmFwcGx5KCB1bmRlZmluZWQsIFsgdmFsdWUgXSApO1xuXHR9XG59XG5cbmpRdWVyeS5leHRlbmQoIHtcblxuXHREZWZlcnJlZDogZnVuY3Rpb24oIGZ1bmMgKSB7XG5cdFx0dmFyIHR1cGxlcyA9IFtcblxuXHRcdFx0XHQvLyBhY3Rpb24sIGFkZCBsaXN0ZW5lciwgY2FsbGJhY2tzLFxuXHRcdFx0XHQvLyAuLi4gLnRoZW4gaGFuZGxlcnMsIGFyZ3VtZW50IGluZGV4LCBbZmluYWwgc3RhdGVdXG5cdFx0XHRcdFsgXCJub3RpZnlcIiwgXCJwcm9ncmVzc1wiLCBqUXVlcnkuQ2FsbGJhY2tzKCBcIm1lbW9yeVwiICksXG5cdFx0XHRcdFx0alF1ZXJ5LkNhbGxiYWNrcyggXCJtZW1vcnlcIiApLCAyIF0sXG5cdFx0XHRcdFsgXCJyZXNvbHZlXCIsIFwiZG9uZVwiLCBqUXVlcnkuQ2FsbGJhY2tzKCBcIm9uY2UgbWVtb3J5XCIgKSxcblx0XHRcdFx0XHRqUXVlcnkuQ2FsbGJhY2tzKCBcIm9uY2UgbWVtb3J5XCIgKSwgMCwgXCJyZXNvbHZlZFwiIF0sXG5cdFx0XHRcdFsgXCJyZWplY3RcIiwgXCJmYWlsXCIsIGpRdWVyeS5DYWxsYmFja3MoIFwib25jZSBtZW1vcnlcIiApLFxuXHRcdFx0XHRcdGpRdWVyeS5DYWxsYmFja3MoIFwib25jZSBtZW1vcnlcIiApLCAxLCBcInJlamVjdGVkXCIgXVxuXHRcdFx0XSxcblx0XHRcdHN0YXRlID0gXCJwZW5kaW5nXCIsXG5cdFx0XHRwcm9taXNlID0ge1xuXHRcdFx0XHRzdGF0ZTogZnVuY3Rpb24oKSB7XG5cdFx0XHRcdFx0cmV0dXJuIHN0YXRlO1xuXHRcdFx0XHR9LFxuXHRcdFx0XHRhbHdheXM6IGZ1bmN0aW9uKCkge1xuXHRcdFx0XHRcdGRlZmVycmVkLmRvbmUoIGFyZ3VtZW50cyApLmZhaWwoIGFyZ3VtZW50cyApO1xuXHRcdFx0XHRcdHJldHVybiB0aGlzO1xuXHRcdFx0XHR9LFxuXHRcdFx0XHRcImNhdGNoXCI6IGZ1bmN0aW9uKCBmbiApIHtcblx0XHRcdFx0XHRyZXR1cm4gcHJvbWlzZS50aGVuKCBudWxsLCBmbiApO1xuXHRcdFx0XHR9LFxuXG5cdFx0XHRcdC8vIEtlZXAgcGlwZSBmb3IgYmFjay1jb21wYXRcblx0XHRcdFx0cGlwZTogZnVuY3Rpb24oIC8qIGZuRG9uZSwgZm5GYWlsLCBmblByb2dyZXNzICovICkge1xuXHRcdFx0XHRcdHZhciBmbnMgPSBhcmd1bWVudHM7XG5cblx0XHRcdFx0XHRyZXR1cm4galF1ZXJ5LkRlZmVycmVkKCBmdW5jdGlvbiggbmV3RGVmZXIgKSB7XG5cdFx0XHRcdFx0XHRqUXVlcnkuZWFjaCggdHVwbGVzLCBmdW5jdGlvbiggaSwgdHVwbGUgKSB7XG5cblx0XHRcdFx0XHRcdFx0Ly8gTWFwIHR1cGxlcyAocHJvZ3Jlc3MsIGRvbmUsIGZhaWwpIHRvIGFyZ3VtZW50cyAoZG9uZSwgZmFpbCwgcHJvZ3Jlc3MpXG5cdFx0XHRcdFx0XHRcdHZhciBmbiA9IGpRdWVyeS5pc0Z1bmN0aW9uKCBmbnNbIHR1cGxlWyA0IF0gXSApICYmIGZuc1sgdHVwbGVbIDQgXSBdO1xuXG5cdFx0XHRcdFx0XHRcdC8vIGRlZmVycmVkLnByb2dyZXNzKGZ1bmN0aW9uKCkgeyBiaW5kIHRvIG5ld0RlZmVyIG9yIG5ld0RlZmVyLm5vdGlmeSB9KVxuXHRcdFx0XHRcdFx0XHQvLyBkZWZlcnJlZC5kb25lKGZ1bmN0aW9uKCkgeyBiaW5kIHRvIG5ld0RlZmVyIG9yIG5ld0RlZmVyLnJlc29sdmUgfSlcblx0XHRcdFx0XHRcdFx0Ly8gZGVmZXJyZWQuZmFpbChmdW5jdGlvbigpIHsgYmluZCB0byBuZXdEZWZlciBvciBuZXdEZWZlci5yZWplY3QgfSlcblx0XHRcdFx0XHRcdFx0ZGVmZXJyZWRbIHR1cGxlWyAxIF0gXSggZnVuY3Rpb24oKSB7XG5cdFx0XHRcdFx0XHRcdFx0dmFyIHJldHVybmVkID0gZm4gJiYgZm4uYXBwbHkoIHRoaXMsIGFyZ3VtZW50cyApO1xuXHRcdFx0XHRcdFx0XHRcdGlmICggcmV0dXJuZWQgJiYgalF1ZXJ5LmlzRnVuY3Rpb24oIHJldHVybmVkLnByb21pc2UgKSApIHtcblx0XHRcdFx0XHRcdFx0XHRcdHJldHVybmVkLnByb21pc2UoKVxuXHRcdFx0XHRcdFx0XHRcdFx0XHQucHJvZ3Jlc3MoIG5ld0RlZmVyLm5vdGlmeSApXG5cdFx0XHRcdFx0XHRcdFx0XHRcdC5kb25lKCBuZXdEZWZlci5yZXNvbHZlIClcblx0XHRcdFx0XHRcdFx0XHRcdFx0LmZhaWwoIG5ld0RlZmVyLnJlamVjdCApO1xuXHRcdFx0XHRcdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0XHRcdFx0XHRuZXdEZWZlclsgdHVwbGVbIDAgXSArIFwiV2l0aFwiIF0oXG5cdFx0XHRcdFx0XHRcdFx0XHRcdHRoaXMsXG5cdFx0XHRcdFx0XHRcdFx0XHRcdGZuID8gWyByZXR1cm5lZCBdIDogYXJndW1lbnRzXG5cdFx0XHRcdFx0XHRcdFx0XHQpO1xuXHRcdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdFx0fSApO1xuXHRcdFx0XHRcdFx0fSApO1xuXHRcdFx0XHRcdFx0Zm5zID0gbnVsbDtcblx0XHRcdFx0XHR9ICkucHJvbWlzZSgpO1xuXHRcdFx0XHR9LFxuXHRcdFx0XHR0aGVuOiBmdW5jdGlvbiggb25GdWxmaWxsZWQsIG9uUmVqZWN0ZWQsIG9uUHJvZ3Jlc3MgKSB7XG5cdFx0XHRcdFx0dmFyIG1heERlcHRoID0gMDtcblx0XHRcdFx0XHRmdW5jdGlvbiByZXNvbHZlKCBkZXB0aCwgZGVmZXJyZWQsIGhhbmRsZXIsIHNwZWNpYWwgKSB7XG5cdFx0XHRcdFx0XHRyZXR1cm4gZnVuY3Rpb24oKSB7XG5cdFx0XHRcdFx0XHRcdHZhciB0aGF0ID0gdGhpcyxcblx0XHRcdFx0XHRcdFx0XHRhcmdzID0gYXJndW1lbnRzLFxuXHRcdFx0XHRcdFx0XHRcdG1pZ2h0VGhyb3cgPSBmdW5jdGlvbigpIHtcblx0XHRcdFx0XHRcdFx0XHRcdHZhciByZXR1cm5lZCwgdGhlbjtcblxuXHRcdFx0XHRcdFx0XHRcdFx0Ly8gU3VwcG9ydDogUHJvbWlzZXMvQSsgc2VjdGlvbiAyLjMuMy4zLjNcblx0XHRcdFx0XHRcdFx0XHRcdC8vIGh0dHBzOi8vcHJvbWlzZXNhcGx1cy5jb20vI3BvaW50LTU5XG5cdFx0XHRcdFx0XHRcdFx0XHQvLyBJZ25vcmUgZG91YmxlLXJlc29sdXRpb24gYXR0ZW1wdHNcblx0XHRcdFx0XHRcdFx0XHRcdGlmICggZGVwdGggPCBtYXhEZXB0aCApIHtcblx0XHRcdFx0XHRcdFx0XHRcdFx0cmV0dXJuO1xuXHRcdFx0XHRcdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0XHRcdFx0XHRyZXR1cm5lZCA9IGhhbmRsZXIuYXBwbHkoIHRoYXQsIGFyZ3MgKTtcblxuXHRcdFx0XHRcdFx0XHRcdFx0Ly8gU3VwcG9ydDogUHJvbWlzZXMvQSsgc2VjdGlvbiAyLjMuMVxuXHRcdFx0XHRcdFx0XHRcdFx0Ly8gaHR0cHM6Ly9wcm9taXNlc2FwbHVzLmNvbS8jcG9pbnQtNDhcblx0XHRcdFx0XHRcdFx0XHRcdGlmICggcmV0dXJuZWQgPT09IGRlZmVycmVkLnByb21pc2UoKSApIHtcblx0XHRcdFx0XHRcdFx0XHRcdFx0dGhyb3cgbmV3IFR5cGVFcnJvciggXCJUaGVuYWJsZSBzZWxmLXJlc29sdXRpb25cIiApO1xuXHRcdFx0XHRcdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0XHRcdFx0XHQvLyBTdXBwb3J0OiBQcm9taXNlcy9BKyBzZWN0aW9ucyAyLjMuMy4xLCAzLjVcblx0XHRcdFx0XHRcdFx0XHRcdC8vIGh0dHBzOi8vcHJvbWlzZXNhcGx1cy5jb20vI3BvaW50LTU0XG5cdFx0XHRcdFx0XHRcdFx0XHQvLyBodHRwczovL3Byb21pc2VzYXBsdXMuY29tLyNwb2ludC03NVxuXHRcdFx0XHRcdFx0XHRcdFx0Ly8gUmV0cmlldmUgYHRoZW5gIG9ubHkgb25jZVxuXHRcdFx0XHRcdFx0XHRcdFx0dGhlbiA9IHJldHVybmVkICYmXG5cblx0XHRcdFx0XHRcdFx0XHRcdFx0Ly8gU3VwcG9ydDogUHJvbWlzZXMvQSsgc2VjdGlvbiAyLjMuNFxuXHRcdFx0XHRcdFx0XHRcdFx0XHQvLyBodHRwczovL3Byb21pc2VzYXBsdXMuY29tLyNwb2ludC02NFxuXHRcdFx0XHRcdFx0XHRcdFx0XHQvLyBPbmx5IGNoZWNrIG9iamVjdHMgYW5kIGZ1bmN0aW9ucyBmb3IgdGhlbmFiaWxpdHlcblx0XHRcdFx0XHRcdFx0XHRcdFx0KCB0eXBlb2YgcmV0dXJuZWQgPT09IFwib2JqZWN0XCIgfHxcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHR0eXBlb2YgcmV0dXJuZWQgPT09IFwiZnVuY3Rpb25cIiApICYmXG5cdFx0XHRcdFx0XHRcdFx0XHRcdHJldHVybmVkLnRoZW47XG5cblx0XHRcdFx0XHRcdFx0XHRcdC8vIEhhbmRsZSBhIHJldHVybmVkIHRoZW5hYmxlXG5cdFx0XHRcdFx0XHRcdFx0XHRpZiAoIGpRdWVyeS5pc0Z1bmN0aW9uKCB0aGVuICkgKSB7XG5cblx0XHRcdFx0XHRcdFx0XHRcdFx0Ly8gU3BlY2lhbCBwcm9jZXNzb3JzIChub3RpZnkpIGp1c3Qgd2FpdCBmb3IgcmVzb2x1dGlvblxuXHRcdFx0XHRcdFx0XHRcdFx0XHRpZiAoIHNwZWNpYWwgKSB7XG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0dGhlbi5jYWxsKFxuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0cmV0dXJuZWQsXG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRyZXNvbHZlKCBtYXhEZXB0aCwgZGVmZXJyZWQsIElkZW50aXR5LCBzcGVjaWFsICksXG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRyZXNvbHZlKCBtYXhEZXB0aCwgZGVmZXJyZWQsIFRocm93ZXIsIHNwZWNpYWwgKVxuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdCk7XG5cblx0XHRcdFx0XHRcdFx0XHRcdFx0Ly8gTm9ybWFsIHByb2Nlc3NvcnMgKHJlc29sdmUpIGFsc28gaG9vayBpbnRvIHByb2dyZXNzXG5cdFx0XHRcdFx0XHRcdFx0XHRcdH0gZWxzZSB7XG5cblx0XHRcdFx0XHRcdFx0XHRcdFx0XHQvLyAuLi5hbmQgZGlzcmVnYXJkIG9sZGVyIHJlc29sdXRpb24gdmFsdWVzXG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0bWF4RGVwdGgrKztcblxuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdHRoZW4uY2FsbChcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdHJldHVybmVkLFxuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0cmVzb2x2ZSggbWF4RGVwdGgsIGRlZmVycmVkLCBJZGVudGl0eSwgc3BlY2lhbCApLFxuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0cmVzb2x2ZSggbWF4RGVwdGgsIGRlZmVycmVkLCBUaHJvd2VyLCBzcGVjaWFsICksXG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRyZXNvbHZlKCBtYXhEZXB0aCwgZGVmZXJyZWQsIElkZW50aXR5LFxuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRkZWZlcnJlZC5ub3RpZnlXaXRoIClcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHQpO1xuXHRcdFx0XHRcdFx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHRcdFx0XHRcdC8vIEhhbmRsZSBhbGwgb3RoZXIgcmV0dXJuZWQgdmFsdWVzXG5cdFx0XHRcdFx0XHRcdFx0XHR9IGVsc2Uge1xuXG5cdFx0XHRcdFx0XHRcdFx0XHRcdC8vIE9ubHkgc3Vic3RpdHV0ZSBoYW5kbGVycyBwYXNzIG9uIGNvbnRleHRcblx0XHRcdFx0XHRcdFx0XHRcdFx0Ly8gYW5kIG11bHRpcGxlIHZhbHVlcyAobm9uLXNwZWMgYmVoYXZpb3IpXG5cdFx0XHRcdFx0XHRcdFx0XHRcdGlmICggaGFuZGxlciAhPT0gSWRlbnRpdHkgKSB7XG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0dGhhdCA9IHVuZGVmaW5lZDtcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRhcmdzID0gWyByZXR1cm5lZCBdO1xuXHRcdFx0XHRcdFx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHRcdFx0XHRcdFx0Ly8gUHJvY2VzcyB0aGUgdmFsdWUocylcblx0XHRcdFx0XHRcdFx0XHRcdFx0Ly8gRGVmYXVsdCBwcm9jZXNzIGlzIHJlc29sdmVcblx0XHRcdFx0XHRcdFx0XHRcdFx0KCBzcGVjaWFsIHx8IGRlZmVycmVkLnJlc29sdmVXaXRoICkoIHRoYXQsIGFyZ3MgKTtcblx0XHRcdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdFx0XHR9LFxuXG5cdFx0XHRcdFx0XHRcdFx0Ly8gT25seSBub3JtYWwgcHJvY2Vzc29ycyAocmVzb2x2ZSkgY2F0Y2ggYW5kIHJlamVjdCBleGNlcHRpb25zXG5cdFx0XHRcdFx0XHRcdFx0cHJvY2VzcyA9IHNwZWNpYWwgP1xuXHRcdFx0XHRcdFx0XHRcdFx0bWlnaHRUaHJvdyA6XG5cdFx0XHRcdFx0XHRcdFx0XHRmdW5jdGlvbigpIHtcblx0XHRcdFx0XHRcdFx0XHRcdFx0dHJ5IHtcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRtaWdodFRocm93KCk7XG5cdFx0XHRcdFx0XHRcdFx0XHRcdH0gY2F0Y2ggKCBlICkge1xuXG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0aWYgKCBqUXVlcnkuRGVmZXJyZWQuZXhjZXB0aW9uSG9vayApIHtcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdGpRdWVyeS5EZWZlcnJlZC5leGNlcHRpb25Ib29rKCBlLFxuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRwcm9jZXNzLnN0YWNrVHJhY2UgKTtcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHRcdFx0XHRcdFx0XHQvLyBTdXBwb3J0OiBQcm9taXNlcy9BKyBzZWN0aW9uIDIuMy4zLjMuNC4xXG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0Ly8gaHR0cHM6Ly9wcm9taXNlc2FwbHVzLmNvbS8jcG9pbnQtNjFcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHQvLyBJZ25vcmUgcG9zdC1yZXNvbHV0aW9uIGV4Y2VwdGlvbnNcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRpZiAoIGRlcHRoICsgMSA+PSBtYXhEZXB0aCApIHtcblxuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0Ly8gT25seSBzdWJzdGl0dXRlIGhhbmRsZXJzIHBhc3Mgb24gY29udGV4dFxuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0Ly8gYW5kIG11bHRpcGxlIHZhbHVlcyAobm9uLXNwZWMgYmVoYXZpb3IpXG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRpZiAoIGhhbmRsZXIgIT09IFRocm93ZXIgKSB7XG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdHRoYXQgPSB1bmRlZmluZWQ7XG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdGFyZ3MgPSBbIGUgXTtcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0ZGVmZXJyZWQucmVqZWN0V2l0aCggdGhhdCwgYXJncyApO1xuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0XHRcdFx0fTtcblxuXHRcdFx0XHRcdFx0XHQvLyBTdXBwb3J0OiBQcm9taXNlcy9BKyBzZWN0aW9uIDIuMy4zLjMuMVxuXHRcdFx0XHRcdFx0XHQvLyBodHRwczovL3Byb21pc2VzYXBsdXMuY29tLyNwb2ludC01N1xuXHRcdFx0XHRcdFx0XHQvLyBSZS1yZXNvbHZlIHByb21pc2VzIGltbWVkaWF0ZWx5IHRvIGRvZGdlIGZhbHNlIHJlamVjdGlvbiBmcm9tXG5cdFx0XHRcdFx0XHRcdC8vIHN1YnNlcXVlbnQgZXJyb3JzXG5cdFx0XHRcdFx0XHRcdGlmICggZGVwdGggKSB7XG5cdFx0XHRcdFx0XHRcdFx0cHJvY2VzcygpO1xuXHRcdFx0XHRcdFx0XHR9IGVsc2Uge1xuXG5cdFx0XHRcdFx0XHRcdFx0Ly8gQ2FsbCBhbiBvcHRpb25hbCBob29rIHRvIHJlY29yZCB0aGUgc3RhY2ssIGluIGNhc2Ugb2YgZXhjZXB0aW9uXG5cdFx0XHRcdFx0XHRcdFx0Ly8gc2luY2UgaXQncyBvdGhlcndpc2UgbG9zdCB3aGVuIGV4ZWN1dGlvbiBnb2VzIGFzeW5jXG5cdFx0XHRcdFx0XHRcdFx0aWYgKCBqUXVlcnkuRGVmZXJyZWQuZ2V0U3RhY2tIb29rICkge1xuXHRcdFx0XHRcdFx0XHRcdFx0cHJvY2Vzcy5zdGFja1RyYWNlID0galF1ZXJ5LkRlZmVycmVkLmdldFN0YWNrSG9vaygpO1xuXHRcdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdFx0XHR3aW5kb3cuc2V0VGltZW91dCggcHJvY2VzcyApO1xuXHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHR9O1xuXHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdHJldHVybiBqUXVlcnkuRGVmZXJyZWQoIGZ1bmN0aW9uKCBuZXdEZWZlciApIHtcblxuXHRcdFx0XHRcdFx0Ly8gcHJvZ3Jlc3NfaGFuZGxlcnMuYWRkKCAuLi4gKVxuXHRcdFx0XHRcdFx0dHVwbGVzWyAwIF1bIDMgXS5hZGQoXG5cdFx0XHRcdFx0XHRcdHJlc29sdmUoXG5cdFx0XHRcdFx0XHRcdFx0MCxcblx0XHRcdFx0XHRcdFx0XHRuZXdEZWZlcixcblx0XHRcdFx0XHRcdFx0XHRqUXVlcnkuaXNGdW5jdGlvbiggb25Qcm9ncmVzcyApID9cblx0XHRcdFx0XHRcdFx0XHRcdG9uUHJvZ3Jlc3MgOlxuXHRcdFx0XHRcdFx0XHRcdFx0SWRlbnRpdHksXG5cdFx0XHRcdFx0XHRcdFx0bmV3RGVmZXIubm90aWZ5V2l0aFxuXHRcdFx0XHRcdFx0XHQpXG5cdFx0XHRcdFx0XHQpO1xuXG5cdFx0XHRcdFx0XHQvLyBmdWxmaWxsZWRfaGFuZGxlcnMuYWRkKCAuLi4gKVxuXHRcdFx0XHRcdFx0dHVwbGVzWyAxIF1bIDMgXS5hZGQoXG5cdFx0XHRcdFx0XHRcdHJlc29sdmUoXG5cdFx0XHRcdFx0XHRcdFx0MCxcblx0XHRcdFx0XHRcdFx0XHRuZXdEZWZlcixcblx0XHRcdFx0XHRcdFx0XHRqUXVlcnkuaXNGdW5jdGlvbiggb25GdWxmaWxsZWQgKSA/XG5cdFx0XHRcdFx0XHRcdFx0XHRvbkZ1bGZpbGxlZCA6XG5cdFx0XHRcdFx0XHRcdFx0XHRJZGVudGl0eVxuXHRcdFx0XHRcdFx0XHQpXG5cdFx0XHRcdFx0XHQpO1xuXG5cdFx0XHRcdFx0XHQvLyByZWplY3RlZF9oYW5kbGVycy5hZGQoIC4uLiApXG5cdFx0XHRcdFx0XHR0dXBsZXNbIDIgXVsgMyBdLmFkZChcblx0XHRcdFx0XHRcdFx0cmVzb2x2ZShcblx0XHRcdFx0XHRcdFx0XHQwLFxuXHRcdFx0XHRcdFx0XHRcdG5ld0RlZmVyLFxuXHRcdFx0XHRcdFx0XHRcdGpRdWVyeS5pc0Z1bmN0aW9uKCBvblJlamVjdGVkICkgP1xuXHRcdFx0XHRcdFx0XHRcdFx0b25SZWplY3RlZCA6XG5cdFx0XHRcdFx0XHRcdFx0XHRUaHJvd2VyXG5cdFx0XHRcdFx0XHRcdClcblx0XHRcdFx0XHRcdCk7XG5cdFx0XHRcdFx0fSApLnByb21pc2UoKTtcblx0XHRcdFx0fSxcblxuXHRcdFx0XHQvLyBHZXQgYSBwcm9taXNlIGZvciB0aGlzIGRlZmVycmVkXG5cdFx0XHRcdC8vIElmIG9iaiBpcyBwcm92aWRlZCwgdGhlIHByb21pc2UgYXNwZWN0IGlzIGFkZGVkIHRvIHRoZSBvYmplY3Rcblx0XHRcdFx0cHJvbWlzZTogZnVuY3Rpb24oIG9iaiApIHtcblx0XHRcdFx0XHRyZXR1cm4gb2JqICE9IG51bGwgPyBqUXVlcnkuZXh0ZW5kKCBvYmosIHByb21pc2UgKSA6IHByb21pc2U7XG5cdFx0XHRcdH1cblx0XHRcdH0sXG5cdFx0XHRkZWZlcnJlZCA9IHt9O1xuXG5cdFx0Ly8gQWRkIGxpc3Qtc3BlY2lmaWMgbWV0aG9kc1xuXHRcdGpRdWVyeS5lYWNoKCB0dXBsZXMsIGZ1bmN0aW9uKCBpLCB0dXBsZSApIHtcblx0XHRcdHZhciBsaXN0ID0gdHVwbGVbIDIgXSxcblx0XHRcdFx0c3RhdGVTdHJpbmcgPSB0dXBsZVsgNSBdO1xuXG5cdFx0XHQvLyBwcm9taXNlLnByb2dyZXNzID0gbGlzdC5hZGRcblx0XHRcdC8vIHByb21pc2UuZG9uZSA9IGxpc3QuYWRkXG5cdFx0XHQvLyBwcm9taXNlLmZhaWwgPSBsaXN0LmFkZFxuXHRcdFx0cHJvbWlzZVsgdHVwbGVbIDEgXSBdID0gbGlzdC5hZGQ7XG5cblx0XHRcdC8vIEhhbmRsZSBzdGF0ZVxuXHRcdFx0aWYgKCBzdGF0ZVN0cmluZyApIHtcblx0XHRcdFx0bGlzdC5hZGQoXG5cdFx0XHRcdFx0ZnVuY3Rpb24oKSB7XG5cblx0XHRcdFx0XHRcdC8vIHN0YXRlID0gXCJyZXNvbHZlZFwiIChpLmUuLCBmdWxmaWxsZWQpXG5cdFx0XHRcdFx0XHQvLyBzdGF0ZSA9IFwicmVqZWN0ZWRcIlxuXHRcdFx0XHRcdFx0c3RhdGUgPSBzdGF0ZVN0cmluZztcblx0XHRcdFx0XHR9LFxuXG5cdFx0XHRcdFx0Ly8gcmVqZWN0ZWRfY2FsbGJhY2tzLmRpc2FibGVcblx0XHRcdFx0XHQvLyBmdWxmaWxsZWRfY2FsbGJhY2tzLmRpc2FibGVcblx0XHRcdFx0XHR0dXBsZXNbIDMgLSBpIF1bIDIgXS5kaXNhYmxlLFxuXG5cdFx0XHRcdFx0Ly8gcHJvZ3Jlc3NfY2FsbGJhY2tzLmxvY2tcblx0XHRcdFx0XHR0dXBsZXNbIDAgXVsgMiBdLmxvY2tcblx0XHRcdFx0KTtcblx0XHRcdH1cblxuXHRcdFx0Ly8gcHJvZ3Jlc3NfaGFuZGxlcnMuZmlyZVxuXHRcdFx0Ly8gZnVsZmlsbGVkX2hhbmRsZXJzLmZpcmVcblx0XHRcdC8vIHJlamVjdGVkX2hhbmRsZXJzLmZpcmVcblx0XHRcdGxpc3QuYWRkKCB0dXBsZVsgMyBdLmZpcmUgKTtcblxuXHRcdFx0Ly8gZGVmZXJyZWQubm90aWZ5ID0gZnVuY3Rpb24oKSB7IGRlZmVycmVkLm5vdGlmeVdpdGgoLi4uKSB9XG5cdFx0XHQvLyBkZWZlcnJlZC5yZXNvbHZlID0gZnVuY3Rpb24oKSB7IGRlZmVycmVkLnJlc29sdmVXaXRoKC4uLikgfVxuXHRcdFx0Ly8gZGVmZXJyZWQucmVqZWN0ID0gZnVuY3Rpb24oKSB7IGRlZmVycmVkLnJlamVjdFdpdGgoLi4uKSB9XG5cdFx0XHRkZWZlcnJlZFsgdHVwbGVbIDAgXSBdID0gZnVuY3Rpb24oKSB7XG5cdFx0XHRcdGRlZmVycmVkWyB0dXBsZVsgMCBdICsgXCJXaXRoXCIgXSggdGhpcyA9PT0gZGVmZXJyZWQgPyB1bmRlZmluZWQgOiB0aGlzLCBhcmd1bWVudHMgKTtcblx0XHRcdFx0cmV0dXJuIHRoaXM7XG5cdFx0XHR9O1xuXG5cdFx0XHQvLyBkZWZlcnJlZC5ub3RpZnlXaXRoID0gbGlzdC5maXJlV2l0aFxuXHRcdFx0Ly8gZGVmZXJyZWQucmVzb2x2ZVdpdGggPSBsaXN0LmZpcmVXaXRoXG5cdFx0XHQvLyBkZWZlcnJlZC5yZWplY3RXaXRoID0gbGlzdC5maXJlV2l0aFxuXHRcdFx0ZGVmZXJyZWRbIHR1cGxlWyAwIF0gKyBcIldpdGhcIiBdID0gbGlzdC5maXJlV2l0aDtcblx0XHR9ICk7XG5cblx0XHQvLyBNYWtlIHRoZSBkZWZlcnJlZCBhIHByb21pc2Vcblx0XHRwcm9taXNlLnByb21pc2UoIGRlZmVycmVkICk7XG5cblx0XHQvLyBDYWxsIGdpdmVuIGZ1bmMgaWYgYW55XG5cdFx0aWYgKCBmdW5jICkge1xuXHRcdFx0ZnVuYy5jYWxsKCBkZWZlcnJlZCwgZGVmZXJyZWQgKTtcblx0XHR9XG5cblx0XHQvLyBBbGwgZG9uZSFcblx0XHRyZXR1cm4gZGVmZXJyZWQ7XG5cdH0sXG5cblx0Ly8gRGVmZXJyZWQgaGVscGVyXG5cdHdoZW46IGZ1bmN0aW9uKCBzaW5nbGVWYWx1ZSApIHtcblx0XHR2YXJcblxuXHRcdFx0Ly8gY291bnQgb2YgdW5jb21wbGV0ZWQgc3Vib3JkaW5hdGVzXG5cdFx0XHRyZW1haW5pbmcgPSBhcmd1bWVudHMubGVuZ3RoLFxuXG5cdFx0XHQvLyBjb3VudCBvZiB1bnByb2Nlc3NlZCBhcmd1bWVudHNcblx0XHRcdGkgPSByZW1haW5pbmcsXG5cblx0XHRcdC8vIHN1Ym9yZGluYXRlIGZ1bGZpbGxtZW50IGRhdGFcblx0XHRcdHJlc29sdmVDb250ZXh0cyA9IEFycmF5KCBpICksXG5cdFx0XHRyZXNvbHZlVmFsdWVzID0gc2xpY2UuY2FsbCggYXJndW1lbnRzICksXG5cblx0XHRcdC8vIHRoZSBtYXN0ZXIgRGVmZXJyZWRcblx0XHRcdG1hc3RlciA9IGpRdWVyeS5EZWZlcnJlZCgpLFxuXG5cdFx0XHQvLyBzdWJvcmRpbmF0ZSBjYWxsYmFjayBmYWN0b3J5XG5cdFx0XHR1cGRhdGVGdW5jID0gZnVuY3Rpb24oIGkgKSB7XG5cdFx0XHRcdHJldHVybiBmdW5jdGlvbiggdmFsdWUgKSB7XG5cdFx0XHRcdFx0cmVzb2x2ZUNvbnRleHRzWyBpIF0gPSB0aGlzO1xuXHRcdFx0XHRcdHJlc29sdmVWYWx1ZXNbIGkgXSA9IGFyZ3VtZW50cy5sZW5ndGggPiAxID8gc2xpY2UuY2FsbCggYXJndW1lbnRzICkgOiB2YWx1ZTtcblx0XHRcdFx0XHRpZiAoICEoIC0tcmVtYWluaW5nICkgKSB7XG5cdFx0XHRcdFx0XHRtYXN0ZXIucmVzb2x2ZVdpdGgoIHJlc29sdmVDb250ZXh0cywgcmVzb2x2ZVZhbHVlcyApO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fTtcblx0XHRcdH07XG5cblx0XHQvLyBTaW5nbGUtIGFuZCBlbXB0eSBhcmd1bWVudHMgYXJlIGFkb3B0ZWQgbGlrZSBQcm9taXNlLnJlc29sdmVcblx0XHRpZiAoIHJlbWFpbmluZyA8PSAxICkge1xuXHRcdFx0YWRvcHRWYWx1ZSggc2luZ2xlVmFsdWUsIG1hc3Rlci5kb25lKCB1cGRhdGVGdW5jKCBpICkgKS5yZXNvbHZlLCBtYXN0ZXIucmVqZWN0LFxuXHRcdFx0XHQhcmVtYWluaW5nICk7XG5cblx0XHRcdC8vIFVzZSAudGhlbigpIHRvIHVud3JhcCBzZWNvbmRhcnkgdGhlbmFibGVzIChjZi4gZ2gtMzAwMClcblx0XHRcdGlmICggbWFzdGVyLnN0YXRlKCkgPT09IFwicGVuZGluZ1wiIHx8XG5cdFx0XHRcdGpRdWVyeS5pc0Z1bmN0aW9uKCByZXNvbHZlVmFsdWVzWyBpIF0gJiYgcmVzb2x2ZVZhbHVlc1sgaSBdLnRoZW4gKSApIHtcblxuXHRcdFx0XHRyZXR1cm4gbWFzdGVyLnRoZW4oKTtcblx0XHRcdH1cblx0XHR9XG5cblx0XHQvLyBNdWx0aXBsZSBhcmd1bWVudHMgYXJlIGFnZ3JlZ2F0ZWQgbGlrZSBQcm9taXNlLmFsbCBhcnJheSBlbGVtZW50c1xuXHRcdHdoaWxlICggaS0tICkge1xuXHRcdFx0YWRvcHRWYWx1ZSggcmVzb2x2ZVZhbHVlc1sgaSBdLCB1cGRhdGVGdW5jKCBpICksIG1hc3Rlci5yZWplY3QgKTtcblx0XHR9XG5cblx0XHRyZXR1cm4gbWFzdGVyLnByb21pc2UoKTtcblx0fVxufSApO1xuXG5cbi8vIFRoZXNlIHVzdWFsbHkgaW5kaWNhdGUgYSBwcm9ncmFtbWVyIG1pc3Rha2UgZHVyaW5nIGRldmVsb3BtZW50LFxuLy8gd2FybiBhYm91dCB0aGVtIEFTQVAgcmF0aGVyIHRoYW4gc3dhbGxvd2luZyB0aGVtIGJ5IGRlZmF1bHQuXG52YXIgcmVycm9yTmFtZXMgPSAvXihFdmFsfEludGVybmFsfFJhbmdlfFJlZmVyZW5jZXxTeW50YXh8VHlwZXxVUkkpRXJyb3IkLztcblxualF1ZXJ5LkRlZmVycmVkLmV4Y2VwdGlvbkhvb2sgPSBmdW5jdGlvbiggZXJyb3IsIHN0YWNrICkge1xuXG5cdC8vIFN1cHBvcnQ6IElFIDggLSA5IG9ubHlcblx0Ly8gQ29uc29sZSBleGlzdHMgd2hlbiBkZXYgdG9vbHMgYXJlIG9wZW4sIHdoaWNoIGNhbiBoYXBwZW4gYXQgYW55IHRpbWVcblx0aWYgKCB3aW5kb3cuY29uc29sZSAmJiB3aW5kb3cuY29uc29sZS53YXJuICYmIGVycm9yICYmIHJlcnJvck5hbWVzLnRlc3QoIGVycm9yLm5hbWUgKSApIHtcblx0XHR3aW5kb3cuY29uc29sZS53YXJuKCBcImpRdWVyeS5EZWZlcnJlZCBleGNlcHRpb246IFwiICsgZXJyb3IubWVzc2FnZSwgZXJyb3Iuc3RhY2ssIHN0YWNrICk7XG5cdH1cbn07XG5cblxuXG5cbmpRdWVyeS5yZWFkeUV4Y2VwdGlvbiA9IGZ1bmN0aW9uKCBlcnJvciApIHtcblx0d2luZG93LnNldFRpbWVvdXQoIGZ1bmN0aW9uKCkge1xuXHRcdHRocm93IGVycm9yO1xuXHR9ICk7XG59O1xuXG5cblxuXG4vLyBUaGUgZGVmZXJyZWQgdXNlZCBvbiBET00gcmVhZHlcbnZhciByZWFkeUxpc3QgPSBqUXVlcnkuRGVmZXJyZWQoKTtcblxualF1ZXJ5LmZuLnJlYWR5ID0gZnVuY3Rpb24oIGZuICkge1xuXG5cdHJlYWR5TGlzdFxuXHRcdC50aGVuKCBmbiApXG5cblx0XHQvLyBXcmFwIGpRdWVyeS5yZWFkeUV4Y2VwdGlvbiBpbiBhIGZ1bmN0aW9uIHNvIHRoYXQgdGhlIGxvb2t1cFxuXHRcdC8vIGhhcHBlbnMgYXQgdGhlIHRpbWUgb2YgZXJyb3IgaGFuZGxpbmcgaW5zdGVhZCBvZiBjYWxsYmFja1xuXHRcdC8vIHJlZ2lzdHJhdGlvbi5cblx0XHQuY2F0Y2goIGZ1bmN0aW9uKCBlcnJvciApIHtcblx0XHRcdGpRdWVyeS5yZWFkeUV4Y2VwdGlvbiggZXJyb3IgKTtcblx0XHR9ICk7XG5cblx0cmV0dXJuIHRoaXM7XG59O1xuXG5qUXVlcnkuZXh0ZW5kKCB7XG5cblx0Ly8gSXMgdGhlIERPTSByZWFkeSB0byBiZSB1c2VkPyBTZXQgdG8gdHJ1ZSBvbmNlIGl0IG9jY3Vycy5cblx0aXNSZWFkeTogZmFsc2UsXG5cblx0Ly8gQSBjb3VudGVyIHRvIHRyYWNrIGhvdyBtYW55IGl0ZW1zIHRvIHdhaXQgZm9yIGJlZm9yZVxuXHQvLyB0aGUgcmVhZHkgZXZlbnQgZmlyZXMuIFNlZSAjNjc4MVxuXHRyZWFkeVdhaXQ6IDEsXG5cblx0Ly8gSGFuZGxlIHdoZW4gdGhlIERPTSBpcyByZWFkeVxuXHRyZWFkeTogZnVuY3Rpb24oIHdhaXQgKSB7XG5cblx0XHQvLyBBYm9ydCBpZiB0aGVyZSBhcmUgcGVuZGluZyBob2xkcyBvciB3ZSdyZSBhbHJlYWR5IHJlYWR5XG5cdFx0aWYgKCB3YWl0ID09PSB0cnVlID8gLS1qUXVlcnkucmVhZHlXYWl0IDogalF1ZXJ5LmlzUmVhZHkgKSB7XG5cdFx0XHRyZXR1cm47XG5cdFx0fVxuXG5cdFx0Ly8gUmVtZW1iZXIgdGhhdCB0aGUgRE9NIGlzIHJlYWR5XG5cdFx0alF1ZXJ5LmlzUmVhZHkgPSB0cnVlO1xuXG5cdFx0Ly8gSWYgYSBub3JtYWwgRE9NIFJlYWR5IGV2ZW50IGZpcmVkLCBkZWNyZW1lbnQsIGFuZCB3YWl0IGlmIG5lZWQgYmVcblx0XHRpZiAoIHdhaXQgIT09IHRydWUgJiYgLS1qUXVlcnkucmVhZHlXYWl0ID4gMCApIHtcblx0XHRcdHJldHVybjtcblx0XHR9XG5cblx0XHQvLyBJZiB0aGVyZSBhcmUgZnVuY3Rpb25zIGJvdW5kLCB0byBleGVjdXRlXG5cdFx0cmVhZHlMaXN0LnJlc29sdmVXaXRoKCBkb2N1bWVudCwgWyBqUXVlcnkgXSApO1xuXHR9XG59ICk7XG5cbmpRdWVyeS5yZWFkeS50aGVuID0gcmVhZHlMaXN0LnRoZW47XG5cbi8vIFRoZSByZWFkeSBldmVudCBoYW5kbGVyIGFuZCBzZWxmIGNsZWFudXAgbWV0aG9kXG5mdW5jdGlvbiBjb21wbGV0ZWQoKSB7XG5cdGRvY3VtZW50LnJlbW92ZUV2ZW50TGlzdGVuZXIoIFwiRE9NQ29udGVudExvYWRlZFwiLCBjb21wbGV0ZWQgKTtcblx0d2luZG93LnJlbW92ZUV2ZW50TGlzdGVuZXIoIFwibG9hZFwiLCBjb21wbGV0ZWQgKTtcblx0alF1ZXJ5LnJlYWR5KCk7XG59XG5cbi8vIENhdGNoIGNhc2VzIHdoZXJlICQoZG9jdW1lbnQpLnJlYWR5KCkgaXMgY2FsbGVkXG4vLyBhZnRlciB0aGUgYnJvd3NlciBldmVudCBoYXMgYWxyZWFkeSBvY2N1cnJlZC5cbi8vIFN1cHBvcnQ6IElFIDw9OSAtIDEwIG9ubHlcbi8vIE9sZGVyIElFIHNvbWV0aW1lcyBzaWduYWxzIFwiaW50ZXJhY3RpdmVcIiB0b28gc29vblxuaWYgKCBkb2N1bWVudC5yZWFkeVN0YXRlID09PSBcImNvbXBsZXRlXCIgfHxcblx0KCBkb2N1bWVudC5yZWFkeVN0YXRlICE9PSBcImxvYWRpbmdcIiAmJiAhZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LmRvU2Nyb2xsICkgKSB7XG5cblx0Ly8gSGFuZGxlIGl0IGFzeW5jaHJvbm91c2x5IHRvIGFsbG93IHNjcmlwdHMgdGhlIG9wcG9ydHVuaXR5IHRvIGRlbGF5IHJlYWR5XG5cdHdpbmRvdy5zZXRUaW1lb3V0KCBqUXVlcnkucmVhZHkgKTtcblxufSBlbHNlIHtcblxuXHQvLyBVc2UgdGhlIGhhbmR5IGV2ZW50IGNhbGxiYWNrXG5cdGRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoIFwiRE9NQ29udGVudExvYWRlZFwiLCBjb21wbGV0ZWQgKTtcblxuXHQvLyBBIGZhbGxiYWNrIHRvIHdpbmRvdy5vbmxvYWQsIHRoYXQgd2lsbCBhbHdheXMgd29ya1xuXHR3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lciggXCJsb2FkXCIsIGNvbXBsZXRlZCApO1xufVxuXG5cblxuXG4vLyBNdWx0aWZ1bmN0aW9uYWwgbWV0aG9kIHRvIGdldCBhbmQgc2V0IHZhbHVlcyBvZiBhIGNvbGxlY3Rpb25cbi8vIFRoZSB2YWx1ZS9zIGNhbiBvcHRpb25hbGx5IGJlIGV4ZWN1dGVkIGlmIGl0J3MgYSBmdW5jdGlvblxudmFyIGFjY2VzcyA9IGZ1bmN0aW9uKCBlbGVtcywgZm4sIGtleSwgdmFsdWUsIGNoYWluYWJsZSwgZW1wdHlHZXQsIHJhdyApIHtcblx0dmFyIGkgPSAwLFxuXHRcdGxlbiA9IGVsZW1zLmxlbmd0aCxcblx0XHRidWxrID0ga2V5ID09IG51bGw7XG5cblx0Ly8gU2V0cyBtYW55IHZhbHVlc1xuXHRpZiAoIGpRdWVyeS50eXBlKCBrZXkgKSA9PT0gXCJvYmplY3RcIiApIHtcblx0XHRjaGFpbmFibGUgPSB0cnVlO1xuXHRcdGZvciAoIGkgaW4ga2V5ICkge1xuXHRcdFx0YWNjZXNzKCBlbGVtcywgZm4sIGksIGtleVsgaSBdLCB0cnVlLCBlbXB0eUdldCwgcmF3ICk7XG5cdFx0fVxuXG5cdC8vIFNldHMgb25lIHZhbHVlXG5cdH0gZWxzZSBpZiAoIHZhbHVlICE9PSB1bmRlZmluZWQgKSB7XG5cdFx0Y2hhaW5hYmxlID0gdHJ1ZTtcblxuXHRcdGlmICggIWpRdWVyeS5pc0Z1bmN0aW9uKCB2YWx1ZSApICkge1xuXHRcdFx0cmF3ID0gdHJ1ZTtcblx0XHR9XG5cblx0XHRpZiAoIGJ1bGsgKSB7XG5cblx0XHRcdC8vIEJ1bGsgb3BlcmF0aW9ucyBydW4gYWdhaW5zdCB0aGUgZW50aXJlIHNldFxuXHRcdFx0aWYgKCByYXcgKSB7XG5cdFx0XHRcdGZuLmNhbGwoIGVsZW1zLCB2YWx1ZSApO1xuXHRcdFx0XHRmbiA9IG51bGw7XG5cblx0XHRcdC8vIC4uLmV4Y2VwdCB3aGVuIGV4ZWN1dGluZyBmdW5jdGlvbiB2YWx1ZXNcblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdGJ1bGsgPSBmbjtcblx0XHRcdFx0Zm4gPSBmdW5jdGlvbiggZWxlbSwga2V5LCB2YWx1ZSApIHtcblx0XHRcdFx0XHRyZXR1cm4gYnVsay5jYWxsKCBqUXVlcnkoIGVsZW0gKSwgdmFsdWUgKTtcblx0XHRcdFx0fTtcblx0XHRcdH1cblx0XHR9XG5cblx0XHRpZiAoIGZuICkge1xuXHRcdFx0Zm9yICggOyBpIDwgbGVuOyBpKysgKSB7XG5cdFx0XHRcdGZuKFxuXHRcdFx0XHRcdGVsZW1zWyBpIF0sIGtleSwgcmF3ID9cblx0XHRcdFx0XHR2YWx1ZSA6XG5cdFx0XHRcdFx0dmFsdWUuY2FsbCggZWxlbXNbIGkgXSwgaSwgZm4oIGVsZW1zWyBpIF0sIGtleSApIClcblx0XHRcdFx0KTtcblx0XHRcdH1cblx0XHR9XG5cdH1cblxuXHRpZiAoIGNoYWluYWJsZSApIHtcblx0XHRyZXR1cm4gZWxlbXM7XG5cdH1cblxuXHQvLyBHZXRzXG5cdGlmICggYnVsayApIHtcblx0XHRyZXR1cm4gZm4uY2FsbCggZWxlbXMgKTtcblx0fVxuXG5cdHJldHVybiBsZW4gPyBmbiggZWxlbXNbIDAgXSwga2V5ICkgOiBlbXB0eUdldDtcbn07XG52YXIgYWNjZXB0RGF0YSA9IGZ1bmN0aW9uKCBvd25lciApIHtcblxuXHQvLyBBY2NlcHRzIG9ubHk6XG5cdC8vICAtIE5vZGVcblx0Ly8gICAgLSBOb2RlLkVMRU1FTlRfTk9ERVxuXHQvLyAgICAtIE5vZGUuRE9DVU1FTlRfTk9ERVxuXHQvLyAgLSBPYmplY3Rcblx0Ly8gICAgLSBBbnlcblx0cmV0dXJuIG93bmVyLm5vZGVUeXBlID09PSAxIHx8IG93bmVyLm5vZGVUeXBlID09PSA5IHx8ICEoICtvd25lci5ub2RlVHlwZSApO1xufTtcblxuXG5cblxuZnVuY3Rpb24gRGF0YSgpIHtcblx0dGhpcy5leHBhbmRvID0galF1ZXJ5LmV4cGFuZG8gKyBEYXRhLnVpZCsrO1xufVxuXG5EYXRhLnVpZCA9IDE7XG5cbkRhdGEucHJvdG90eXBlID0ge1xuXG5cdGNhY2hlOiBmdW5jdGlvbiggb3duZXIgKSB7XG5cblx0XHQvLyBDaGVjayBpZiB0aGUgb3duZXIgb2JqZWN0IGFscmVhZHkgaGFzIGEgY2FjaGVcblx0XHR2YXIgdmFsdWUgPSBvd25lclsgdGhpcy5leHBhbmRvIF07XG5cblx0XHQvLyBJZiBub3QsIGNyZWF0ZSBvbmVcblx0XHRpZiAoICF2YWx1ZSApIHtcblx0XHRcdHZhbHVlID0ge307XG5cblx0XHRcdC8vIFdlIGNhbiBhY2NlcHQgZGF0YSBmb3Igbm9uLWVsZW1lbnQgbm9kZXMgaW4gbW9kZXJuIGJyb3dzZXJzLFxuXHRcdFx0Ly8gYnV0IHdlIHNob3VsZCBub3QsIHNlZSAjODMzNS5cblx0XHRcdC8vIEFsd2F5cyByZXR1cm4gYW4gZW1wdHkgb2JqZWN0LlxuXHRcdFx0aWYgKCBhY2NlcHREYXRhKCBvd25lciApICkge1xuXG5cdFx0XHRcdC8vIElmIGl0IGlzIGEgbm9kZSB1bmxpa2VseSB0byBiZSBzdHJpbmdpZnktZWQgb3IgbG9vcGVkIG92ZXJcblx0XHRcdFx0Ly8gdXNlIHBsYWluIGFzc2lnbm1lbnRcblx0XHRcdFx0aWYgKCBvd25lci5ub2RlVHlwZSApIHtcblx0XHRcdFx0XHRvd25lclsgdGhpcy5leHBhbmRvIF0gPSB2YWx1ZTtcblxuXHRcdFx0XHQvLyBPdGhlcndpc2Ugc2VjdXJlIGl0IGluIGEgbm9uLWVudW1lcmFibGUgcHJvcGVydHlcblx0XHRcdFx0Ly8gY29uZmlndXJhYmxlIG11c3QgYmUgdHJ1ZSB0byBhbGxvdyB0aGUgcHJvcGVydHkgdG8gYmVcblx0XHRcdFx0Ly8gZGVsZXRlZCB3aGVuIGRhdGEgaXMgcmVtb3ZlZFxuXHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdE9iamVjdC5kZWZpbmVQcm9wZXJ0eSggb3duZXIsIHRoaXMuZXhwYW5kbywge1xuXHRcdFx0XHRcdFx0dmFsdWU6IHZhbHVlLFxuXHRcdFx0XHRcdFx0Y29uZmlndXJhYmxlOiB0cnVlXG5cdFx0XHRcdFx0fSApO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0cmV0dXJuIHZhbHVlO1xuXHR9LFxuXHRzZXQ6IGZ1bmN0aW9uKCBvd25lciwgZGF0YSwgdmFsdWUgKSB7XG5cdFx0dmFyIHByb3AsXG5cdFx0XHRjYWNoZSA9IHRoaXMuY2FjaGUoIG93bmVyICk7XG5cblx0XHQvLyBIYW5kbGU6IFsgb3duZXIsIGtleSwgdmFsdWUgXSBhcmdzXG5cdFx0Ly8gQWx3YXlzIHVzZSBjYW1lbENhc2Uga2V5IChnaC0yMjU3KVxuXHRcdGlmICggdHlwZW9mIGRhdGEgPT09IFwic3RyaW5nXCIgKSB7XG5cdFx0XHRjYWNoZVsgalF1ZXJ5LmNhbWVsQ2FzZSggZGF0YSApIF0gPSB2YWx1ZTtcblxuXHRcdC8vIEhhbmRsZTogWyBvd25lciwgeyBwcm9wZXJ0aWVzIH0gXSBhcmdzXG5cdFx0fSBlbHNlIHtcblxuXHRcdFx0Ly8gQ29weSB0aGUgcHJvcGVydGllcyBvbmUtYnktb25lIHRvIHRoZSBjYWNoZSBvYmplY3Rcblx0XHRcdGZvciAoIHByb3AgaW4gZGF0YSApIHtcblx0XHRcdFx0Y2FjaGVbIGpRdWVyeS5jYW1lbENhc2UoIHByb3AgKSBdID0gZGF0YVsgcHJvcCBdO1xuXHRcdFx0fVxuXHRcdH1cblx0XHRyZXR1cm4gY2FjaGU7XG5cdH0sXG5cdGdldDogZnVuY3Rpb24oIG93bmVyLCBrZXkgKSB7XG5cdFx0cmV0dXJuIGtleSA9PT0gdW5kZWZpbmVkID9cblx0XHRcdHRoaXMuY2FjaGUoIG93bmVyICkgOlxuXG5cdFx0XHQvLyBBbHdheXMgdXNlIGNhbWVsQ2FzZSBrZXkgKGdoLTIyNTcpXG5cdFx0XHRvd25lclsgdGhpcy5leHBhbmRvIF0gJiYgb3duZXJbIHRoaXMuZXhwYW5kbyBdWyBqUXVlcnkuY2FtZWxDYXNlKCBrZXkgKSBdO1xuXHR9LFxuXHRhY2Nlc3M6IGZ1bmN0aW9uKCBvd25lciwga2V5LCB2YWx1ZSApIHtcblxuXHRcdC8vIEluIGNhc2VzIHdoZXJlIGVpdGhlcjpcblx0XHQvL1xuXHRcdC8vICAgMS4gTm8ga2V5IHdhcyBzcGVjaWZpZWRcblx0XHQvLyAgIDIuIEEgc3RyaW5nIGtleSB3YXMgc3BlY2lmaWVkLCBidXQgbm8gdmFsdWUgcHJvdmlkZWRcblx0XHQvL1xuXHRcdC8vIFRha2UgdGhlIFwicmVhZFwiIHBhdGggYW5kIGFsbG93IHRoZSBnZXQgbWV0aG9kIHRvIGRldGVybWluZVxuXHRcdC8vIHdoaWNoIHZhbHVlIHRvIHJldHVybiwgcmVzcGVjdGl2ZWx5IGVpdGhlcjpcblx0XHQvL1xuXHRcdC8vICAgMS4gVGhlIGVudGlyZSBjYWNoZSBvYmplY3Rcblx0XHQvLyAgIDIuIFRoZSBkYXRhIHN0b3JlZCBhdCB0aGUga2V5XG5cdFx0Ly9cblx0XHRpZiAoIGtleSA9PT0gdW5kZWZpbmVkIHx8XG5cdFx0XHRcdCggKCBrZXkgJiYgdHlwZW9mIGtleSA9PT0gXCJzdHJpbmdcIiApICYmIHZhbHVlID09PSB1bmRlZmluZWQgKSApIHtcblxuXHRcdFx0cmV0dXJuIHRoaXMuZ2V0KCBvd25lciwga2V5ICk7XG5cdFx0fVxuXG5cdFx0Ly8gV2hlbiB0aGUga2V5IGlzIG5vdCBhIHN0cmluZywgb3IgYm90aCBhIGtleSBhbmQgdmFsdWVcblx0XHQvLyBhcmUgc3BlY2lmaWVkLCBzZXQgb3IgZXh0ZW5kIChleGlzdGluZyBvYmplY3RzKSB3aXRoIGVpdGhlcjpcblx0XHQvL1xuXHRcdC8vICAgMS4gQW4gb2JqZWN0IG9mIHByb3BlcnRpZXNcblx0XHQvLyAgIDIuIEEga2V5IGFuZCB2YWx1ZVxuXHRcdC8vXG5cdFx0dGhpcy5zZXQoIG93bmVyLCBrZXksIHZhbHVlICk7XG5cblx0XHQvLyBTaW5jZSB0aGUgXCJzZXRcIiBwYXRoIGNhbiBoYXZlIHR3byBwb3NzaWJsZSBlbnRyeSBwb2ludHNcblx0XHQvLyByZXR1cm4gdGhlIGV4cGVjdGVkIGRhdGEgYmFzZWQgb24gd2hpY2ggcGF0aCB3YXMgdGFrZW5bKl1cblx0XHRyZXR1cm4gdmFsdWUgIT09IHVuZGVmaW5lZCA/IHZhbHVlIDoga2V5O1xuXHR9LFxuXHRyZW1vdmU6IGZ1bmN0aW9uKCBvd25lciwga2V5ICkge1xuXHRcdHZhciBpLFxuXHRcdFx0Y2FjaGUgPSBvd25lclsgdGhpcy5leHBhbmRvIF07XG5cblx0XHRpZiAoIGNhY2hlID09PSB1bmRlZmluZWQgKSB7XG5cdFx0XHRyZXR1cm47XG5cdFx0fVxuXG5cdFx0aWYgKCBrZXkgIT09IHVuZGVmaW5lZCApIHtcblxuXHRcdFx0Ly8gU3VwcG9ydCBhcnJheSBvciBzcGFjZSBzZXBhcmF0ZWQgc3RyaW5nIG9mIGtleXNcblx0XHRcdGlmICggQXJyYXkuaXNBcnJheSgga2V5ICkgKSB7XG5cblx0XHRcdFx0Ly8gSWYga2V5IGlzIGFuIGFycmF5IG9mIGtleXMuLi5cblx0XHRcdFx0Ly8gV2UgYWx3YXlzIHNldCBjYW1lbENhc2Uga2V5cywgc28gcmVtb3ZlIHRoYXQuXG5cdFx0XHRcdGtleSA9IGtleS5tYXAoIGpRdWVyeS5jYW1lbENhc2UgKTtcblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdGtleSA9IGpRdWVyeS5jYW1lbENhc2UoIGtleSApO1xuXG5cdFx0XHRcdC8vIElmIGEga2V5IHdpdGggdGhlIHNwYWNlcyBleGlzdHMsIHVzZSBpdC5cblx0XHRcdFx0Ly8gT3RoZXJ3aXNlLCBjcmVhdGUgYW4gYXJyYXkgYnkgbWF0Y2hpbmcgbm9uLXdoaXRlc3BhY2Vcblx0XHRcdFx0a2V5ID0ga2V5IGluIGNhY2hlID9cblx0XHRcdFx0XHRbIGtleSBdIDpcblx0XHRcdFx0XHQoIGtleS5tYXRjaCggcm5vdGh0bWx3aGl0ZSApIHx8IFtdICk7XG5cdFx0XHR9XG5cblx0XHRcdGkgPSBrZXkubGVuZ3RoO1xuXG5cdFx0XHR3aGlsZSAoIGktLSApIHtcblx0XHRcdFx0ZGVsZXRlIGNhY2hlWyBrZXlbIGkgXSBdO1xuXHRcdFx0fVxuXHRcdH1cblxuXHRcdC8vIFJlbW92ZSB0aGUgZXhwYW5kbyBpZiB0aGVyZSdzIG5vIG1vcmUgZGF0YVxuXHRcdGlmICgga2V5ID09PSB1bmRlZmluZWQgfHwgalF1ZXJ5LmlzRW1wdHlPYmplY3QoIGNhY2hlICkgKSB7XG5cblx0XHRcdC8vIFN1cHBvcnQ6IENocm9tZSA8PTM1IC0gNDVcblx0XHRcdC8vIFdlYmtpdCAmIEJsaW5rIHBlcmZvcm1hbmNlIHN1ZmZlcnMgd2hlbiBkZWxldGluZyBwcm9wZXJ0aWVzXG5cdFx0XHQvLyBmcm9tIERPTSBub2Rlcywgc28gc2V0IHRvIHVuZGVmaW5lZCBpbnN0ZWFkXG5cdFx0XHQvLyBodHRwczovL2J1Z3MuY2hyb21pdW0ub3JnL3AvY2hyb21pdW0vaXNzdWVzL2RldGFpbD9pZD0zNzg2MDcgKGJ1ZyByZXN0cmljdGVkKVxuXHRcdFx0aWYgKCBvd25lci5ub2RlVHlwZSApIHtcblx0XHRcdFx0b3duZXJbIHRoaXMuZXhwYW5kbyBdID0gdW5kZWZpbmVkO1xuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0ZGVsZXRlIG93bmVyWyB0aGlzLmV4cGFuZG8gXTtcblx0XHRcdH1cblx0XHR9XG5cdH0sXG5cdGhhc0RhdGE6IGZ1bmN0aW9uKCBvd25lciApIHtcblx0XHR2YXIgY2FjaGUgPSBvd25lclsgdGhpcy5leHBhbmRvIF07XG5cdFx0cmV0dXJuIGNhY2hlICE9PSB1bmRlZmluZWQgJiYgIWpRdWVyeS5pc0VtcHR5T2JqZWN0KCBjYWNoZSApO1xuXHR9XG59O1xudmFyIGRhdGFQcml2ID0gbmV3IERhdGEoKTtcblxudmFyIGRhdGFVc2VyID0gbmV3IERhdGEoKTtcblxuXG5cbi8vXHRJbXBsZW1lbnRhdGlvbiBTdW1tYXJ5XG4vL1xuLy9cdDEuIEVuZm9yY2UgQVBJIHN1cmZhY2UgYW5kIHNlbWFudGljIGNvbXBhdGliaWxpdHkgd2l0aCAxLjkueCBicmFuY2hcbi8vXHQyLiBJbXByb3ZlIHRoZSBtb2R1bGUncyBtYWludGFpbmFiaWxpdHkgYnkgcmVkdWNpbmcgdGhlIHN0b3JhZ2Vcbi8vXHRcdHBhdGhzIHRvIGEgc2luZ2xlIG1lY2hhbmlzbS5cbi8vXHQzLiBVc2UgdGhlIHNhbWUgc2luZ2xlIG1lY2hhbmlzbSB0byBzdXBwb3J0IFwicHJpdmF0ZVwiIGFuZCBcInVzZXJcIiBkYXRhLlxuLy9cdDQuIF9OZXZlcl8gZXhwb3NlIFwicHJpdmF0ZVwiIGRhdGEgdG8gdXNlciBjb2RlIChUT0RPOiBEcm9wIF9kYXRhLCBfcmVtb3ZlRGF0YSlcbi8vXHQ1LiBBdm9pZCBleHBvc2luZyBpbXBsZW1lbnRhdGlvbiBkZXRhaWxzIG9uIHVzZXIgb2JqZWN0cyAoZWcuIGV4cGFuZG8gcHJvcGVydGllcylcbi8vXHQ2LiBQcm92aWRlIGEgY2xlYXIgcGF0aCBmb3IgaW1wbGVtZW50YXRpb24gdXBncmFkZSB0byBXZWFrTWFwIGluIDIwMTRcblxudmFyIHJicmFjZSA9IC9eKD86XFx7W1xcd1xcV10qXFx9fFxcW1tcXHdcXFddKlxcXSkkLyxcblx0cm11bHRpRGFzaCA9IC9bQS1aXS9nO1xuXG5mdW5jdGlvbiBnZXREYXRhKCBkYXRhICkge1xuXHRpZiAoIGRhdGEgPT09IFwidHJ1ZVwiICkge1xuXHRcdHJldHVybiB0cnVlO1xuXHR9XG5cblx0aWYgKCBkYXRhID09PSBcImZhbHNlXCIgKSB7XG5cdFx0cmV0dXJuIGZhbHNlO1xuXHR9XG5cblx0aWYgKCBkYXRhID09PSBcIm51bGxcIiApIHtcblx0XHRyZXR1cm4gbnVsbDtcblx0fVxuXG5cdC8vIE9ubHkgY29udmVydCB0byBhIG51bWJlciBpZiBpdCBkb2Vzbid0IGNoYW5nZSB0aGUgc3RyaW5nXG5cdGlmICggZGF0YSA9PT0gK2RhdGEgKyBcIlwiICkge1xuXHRcdHJldHVybiArZGF0YTtcblx0fVxuXG5cdGlmICggcmJyYWNlLnRlc3QoIGRhdGEgKSApIHtcblx0XHRyZXR1cm4gSlNPTi5wYXJzZSggZGF0YSApO1xuXHR9XG5cblx0cmV0dXJuIGRhdGE7XG59XG5cbmZ1bmN0aW9uIGRhdGFBdHRyKCBlbGVtLCBrZXksIGRhdGEgKSB7XG5cdHZhciBuYW1lO1xuXG5cdC8vIElmIG5vdGhpbmcgd2FzIGZvdW5kIGludGVybmFsbHksIHRyeSB0byBmZXRjaCBhbnlcblx0Ly8gZGF0YSBmcm9tIHRoZSBIVE1MNSBkYXRhLSogYXR0cmlidXRlXG5cdGlmICggZGF0YSA9PT0gdW5kZWZpbmVkICYmIGVsZW0ubm9kZVR5cGUgPT09IDEgKSB7XG5cdFx0bmFtZSA9IFwiZGF0YS1cIiArIGtleS5yZXBsYWNlKCBybXVsdGlEYXNoLCBcIi0kJlwiICkudG9Mb3dlckNhc2UoKTtcblx0XHRkYXRhID0gZWxlbS5nZXRBdHRyaWJ1dGUoIG5hbWUgKTtcblxuXHRcdGlmICggdHlwZW9mIGRhdGEgPT09IFwic3RyaW5nXCIgKSB7XG5cdFx0XHR0cnkge1xuXHRcdFx0XHRkYXRhID0gZ2V0RGF0YSggZGF0YSApO1xuXHRcdFx0fSBjYXRjaCAoIGUgKSB7fVxuXG5cdFx0XHQvLyBNYWtlIHN1cmUgd2Ugc2V0IHRoZSBkYXRhIHNvIGl0IGlzbid0IGNoYW5nZWQgbGF0ZXJcblx0XHRcdGRhdGFVc2VyLnNldCggZWxlbSwga2V5LCBkYXRhICk7XG5cdFx0fSBlbHNlIHtcblx0XHRcdGRhdGEgPSB1bmRlZmluZWQ7XG5cdFx0fVxuXHR9XG5cdHJldHVybiBkYXRhO1xufVxuXG5qUXVlcnkuZXh0ZW5kKCB7XG5cdGhhc0RhdGE6IGZ1bmN0aW9uKCBlbGVtICkge1xuXHRcdHJldHVybiBkYXRhVXNlci5oYXNEYXRhKCBlbGVtICkgfHwgZGF0YVByaXYuaGFzRGF0YSggZWxlbSApO1xuXHR9LFxuXG5cdGRhdGE6IGZ1bmN0aW9uKCBlbGVtLCBuYW1lLCBkYXRhICkge1xuXHRcdHJldHVybiBkYXRhVXNlci5hY2Nlc3MoIGVsZW0sIG5hbWUsIGRhdGEgKTtcblx0fSxcblxuXHRyZW1vdmVEYXRhOiBmdW5jdGlvbiggZWxlbSwgbmFtZSApIHtcblx0XHRkYXRhVXNlci5yZW1vdmUoIGVsZW0sIG5hbWUgKTtcblx0fSxcblxuXHQvLyBUT0RPOiBOb3cgdGhhdCBhbGwgY2FsbHMgdG8gX2RhdGEgYW5kIF9yZW1vdmVEYXRhIGhhdmUgYmVlbiByZXBsYWNlZFxuXHQvLyB3aXRoIGRpcmVjdCBjYWxscyB0byBkYXRhUHJpdiBtZXRob2RzLCB0aGVzZSBjYW4gYmUgZGVwcmVjYXRlZC5cblx0X2RhdGE6IGZ1bmN0aW9uKCBlbGVtLCBuYW1lLCBkYXRhICkge1xuXHRcdHJldHVybiBkYXRhUHJpdi5hY2Nlc3MoIGVsZW0sIG5hbWUsIGRhdGEgKTtcblx0fSxcblxuXHRfcmVtb3ZlRGF0YTogZnVuY3Rpb24oIGVsZW0sIG5hbWUgKSB7XG5cdFx0ZGF0YVByaXYucmVtb3ZlKCBlbGVtLCBuYW1lICk7XG5cdH1cbn0gKTtcblxualF1ZXJ5LmZuLmV4dGVuZCgge1xuXHRkYXRhOiBmdW5jdGlvbigga2V5LCB2YWx1ZSApIHtcblx0XHR2YXIgaSwgbmFtZSwgZGF0YSxcblx0XHRcdGVsZW0gPSB0aGlzWyAwIF0sXG5cdFx0XHRhdHRycyA9IGVsZW0gJiYgZWxlbS5hdHRyaWJ1dGVzO1xuXG5cdFx0Ly8gR2V0cyBhbGwgdmFsdWVzXG5cdFx0aWYgKCBrZXkgPT09IHVuZGVmaW5lZCApIHtcblx0XHRcdGlmICggdGhpcy5sZW5ndGggKSB7XG5cdFx0XHRcdGRhdGEgPSBkYXRhVXNlci5nZXQoIGVsZW0gKTtcblxuXHRcdFx0XHRpZiAoIGVsZW0ubm9kZVR5cGUgPT09IDEgJiYgIWRhdGFQcml2LmdldCggZWxlbSwgXCJoYXNEYXRhQXR0cnNcIiApICkge1xuXHRcdFx0XHRcdGkgPSBhdHRycy5sZW5ndGg7XG5cdFx0XHRcdFx0d2hpbGUgKCBpLS0gKSB7XG5cblx0XHRcdFx0XHRcdC8vIFN1cHBvcnQ6IElFIDExIG9ubHlcblx0XHRcdFx0XHRcdC8vIFRoZSBhdHRycyBlbGVtZW50cyBjYW4gYmUgbnVsbCAoIzE0ODk0KVxuXHRcdFx0XHRcdFx0aWYgKCBhdHRyc1sgaSBdICkge1xuXHRcdFx0XHRcdFx0XHRuYW1lID0gYXR0cnNbIGkgXS5uYW1lO1xuXHRcdFx0XHRcdFx0XHRpZiAoIG5hbWUuaW5kZXhPZiggXCJkYXRhLVwiICkgPT09IDAgKSB7XG5cdFx0XHRcdFx0XHRcdFx0bmFtZSA9IGpRdWVyeS5jYW1lbENhc2UoIG5hbWUuc2xpY2UoIDUgKSApO1xuXHRcdFx0XHRcdFx0XHRcdGRhdGFBdHRyKCBlbGVtLCBuYW1lLCBkYXRhWyBuYW1lIF0gKTtcblx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdH1cblx0XHRcdFx0XHRkYXRhUHJpdi5zZXQoIGVsZW0sIFwiaGFzRGF0YUF0dHJzXCIsIHRydWUgKTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXG5cdFx0XHRyZXR1cm4gZGF0YTtcblx0XHR9XG5cblx0XHQvLyBTZXRzIG11bHRpcGxlIHZhbHVlc1xuXHRcdGlmICggdHlwZW9mIGtleSA9PT0gXCJvYmplY3RcIiApIHtcblx0XHRcdHJldHVybiB0aGlzLmVhY2goIGZ1bmN0aW9uKCkge1xuXHRcdFx0XHRkYXRhVXNlci5zZXQoIHRoaXMsIGtleSApO1xuXHRcdFx0fSApO1xuXHRcdH1cblxuXHRcdHJldHVybiBhY2Nlc3MoIHRoaXMsIGZ1bmN0aW9uKCB2YWx1ZSApIHtcblx0XHRcdHZhciBkYXRhO1xuXG5cdFx0XHQvLyBUaGUgY2FsbGluZyBqUXVlcnkgb2JqZWN0IChlbGVtZW50IG1hdGNoZXMpIGlzIG5vdCBlbXB0eVxuXHRcdFx0Ly8gKGFuZCB0aGVyZWZvcmUgaGFzIGFuIGVsZW1lbnQgYXBwZWFycyBhdCB0aGlzWyAwIF0pIGFuZCB0aGVcblx0XHRcdC8vIGB2YWx1ZWAgcGFyYW1ldGVyIHdhcyBub3QgdW5kZWZpbmVkLiBBbiBlbXB0eSBqUXVlcnkgb2JqZWN0XG5cdFx0XHQvLyB3aWxsIHJlc3VsdCBpbiBgdW5kZWZpbmVkYCBmb3IgZWxlbSA9IHRoaXNbIDAgXSB3aGljaCB3aWxsXG5cdFx0XHQvLyB0aHJvdyBhbiBleGNlcHRpb24gaWYgYW4gYXR0ZW1wdCB0byByZWFkIGEgZGF0YSBjYWNoZSBpcyBtYWRlLlxuXHRcdFx0aWYgKCBlbGVtICYmIHZhbHVlID09PSB1bmRlZmluZWQgKSB7XG5cblx0XHRcdFx0Ly8gQXR0ZW1wdCB0byBnZXQgZGF0YSBmcm9tIHRoZSBjYWNoZVxuXHRcdFx0XHQvLyBUaGUga2V5IHdpbGwgYWx3YXlzIGJlIGNhbWVsQ2FzZWQgaW4gRGF0YVxuXHRcdFx0XHRkYXRhID0gZGF0YVVzZXIuZ2V0KCBlbGVtLCBrZXkgKTtcblx0XHRcdFx0aWYgKCBkYXRhICE9PSB1bmRlZmluZWQgKSB7XG5cdFx0XHRcdFx0cmV0dXJuIGRhdGE7XG5cdFx0XHRcdH1cblxuXHRcdFx0XHQvLyBBdHRlbXB0IHRvIFwiZGlzY292ZXJcIiB0aGUgZGF0YSBpblxuXHRcdFx0XHQvLyBIVE1MNSBjdXN0b20gZGF0YS0qIGF0dHJzXG5cdFx0XHRcdGRhdGEgPSBkYXRhQXR0ciggZWxlbSwga2V5ICk7XG5cdFx0XHRcdGlmICggZGF0YSAhPT0gdW5kZWZpbmVkICkge1xuXHRcdFx0XHRcdHJldHVybiBkYXRhO1xuXHRcdFx0XHR9XG5cblx0XHRcdFx0Ly8gV2UgdHJpZWQgcmVhbGx5IGhhcmQsIGJ1dCB0aGUgZGF0YSBkb2Vzbid0IGV4aXN0LlxuXHRcdFx0XHRyZXR1cm47XG5cdFx0XHR9XG5cblx0XHRcdC8vIFNldCB0aGUgZGF0YS4uLlxuXHRcdFx0dGhpcy5lYWNoKCBmdW5jdGlvbigpIHtcblxuXHRcdFx0XHQvLyBXZSBhbHdheXMgc3RvcmUgdGhlIGNhbWVsQ2FzZWQga2V5XG5cdFx0XHRcdGRhdGFVc2VyLnNldCggdGhpcywga2V5LCB2YWx1ZSApO1xuXHRcdFx0fSApO1xuXHRcdH0sIG51bGwsIHZhbHVlLCBhcmd1bWVudHMubGVuZ3RoID4gMSwgbnVsbCwgdHJ1ZSApO1xuXHR9LFxuXG5cdHJlbW92ZURhdGE6IGZ1bmN0aW9uKCBrZXkgKSB7XG5cdFx0cmV0dXJuIHRoaXMuZWFjaCggZnVuY3Rpb24oKSB7XG5cdFx0XHRkYXRhVXNlci5yZW1vdmUoIHRoaXMsIGtleSApO1xuXHRcdH0gKTtcblx0fVxufSApO1xuXG5cbmpRdWVyeS5leHRlbmQoIHtcblx0cXVldWU6IGZ1bmN0aW9uKCBlbGVtLCB0eXBlLCBkYXRhICkge1xuXHRcdHZhciBxdWV1ZTtcblxuXHRcdGlmICggZWxlbSApIHtcblx0XHRcdHR5cGUgPSAoIHR5cGUgfHwgXCJmeFwiICkgKyBcInF1ZXVlXCI7XG5cdFx0XHRxdWV1ZSA9IGRhdGFQcml2LmdldCggZWxlbSwgdHlwZSApO1xuXG5cdFx0XHQvLyBTcGVlZCB1cCBkZXF1ZXVlIGJ5IGdldHRpbmcgb3V0IHF1aWNrbHkgaWYgdGhpcyBpcyBqdXN0IGEgbG9va3VwXG5cdFx0XHRpZiAoIGRhdGEgKSB7XG5cdFx0XHRcdGlmICggIXF1ZXVlIHx8IEFycmF5LmlzQXJyYXkoIGRhdGEgKSApIHtcblx0XHRcdFx0XHRxdWV1ZSA9IGRhdGFQcml2LmFjY2VzcyggZWxlbSwgdHlwZSwgalF1ZXJ5Lm1ha2VBcnJheSggZGF0YSApICk7XG5cdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0cXVldWUucHVzaCggZGF0YSApO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0XHRyZXR1cm4gcXVldWUgfHwgW107XG5cdFx0fVxuXHR9LFxuXG5cdGRlcXVldWU6IGZ1bmN0aW9uKCBlbGVtLCB0eXBlICkge1xuXHRcdHR5cGUgPSB0eXBlIHx8IFwiZnhcIjtcblxuXHRcdHZhciBxdWV1ZSA9IGpRdWVyeS5xdWV1ZSggZWxlbSwgdHlwZSApLFxuXHRcdFx0c3RhcnRMZW5ndGggPSBxdWV1ZS5sZW5ndGgsXG5cdFx0XHRmbiA9IHF1ZXVlLnNoaWZ0KCksXG5cdFx0XHRob29rcyA9IGpRdWVyeS5fcXVldWVIb29rcyggZWxlbSwgdHlwZSApLFxuXHRcdFx0bmV4dCA9IGZ1bmN0aW9uKCkge1xuXHRcdFx0XHRqUXVlcnkuZGVxdWV1ZSggZWxlbSwgdHlwZSApO1xuXHRcdFx0fTtcblxuXHRcdC8vIElmIHRoZSBmeCBxdWV1ZSBpcyBkZXF1ZXVlZCwgYWx3YXlzIHJlbW92ZSB0aGUgcHJvZ3Jlc3Mgc2VudGluZWxcblx0XHRpZiAoIGZuID09PSBcImlucHJvZ3Jlc3NcIiApIHtcblx0XHRcdGZuID0gcXVldWUuc2hpZnQoKTtcblx0XHRcdHN0YXJ0TGVuZ3RoLS07XG5cdFx0fVxuXG5cdFx0aWYgKCBmbiApIHtcblxuXHRcdFx0Ly8gQWRkIGEgcHJvZ3Jlc3Mgc2VudGluZWwgdG8gcHJldmVudCB0aGUgZnggcXVldWUgZnJvbSBiZWluZ1xuXHRcdFx0Ly8gYXV0b21hdGljYWxseSBkZXF1ZXVlZFxuXHRcdFx0aWYgKCB0eXBlID09PSBcImZ4XCIgKSB7XG5cdFx0XHRcdHF1ZXVlLnVuc2hpZnQoIFwiaW5wcm9ncmVzc1wiICk7XG5cdFx0XHR9XG5cblx0XHRcdC8vIENsZWFyIHVwIHRoZSBsYXN0IHF1ZXVlIHN0b3AgZnVuY3Rpb25cblx0XHRcdGRlbGV0ZSBob29rcy5zdG9wO1xuXHRcdFx0Zm4uY2FsbCggZWxlbSwgbmV4dCwgaG9va3MgKTtcblx0XHR9XG5cblx0XHRpZiAoICFzdGFydExlbmd0aCAmJiBob29rcyApIHtcblx0XHRcdGhvb2tzLmVtcHR5LmZpcmUoKTtcblx0XHR9XG5cdH0sXG5cblx0Ly8gTm90IHB1YmxpYyAtIGdlbmVyYXRlIGEgcXVldWVIb29rcyBvYmplY3QsIG9yIHJldHVybiB0aGUgY3VycmVudCBvbmVcblx0X3F1ZXVlSG9va3M6IGZ1bmN0aW9uKCBlbGVtLCB0eXBlICkge1xuXHRcdHZhciBrZXkgPSB0eXBlICsgXCJxdWV1ZUhvb2tzXCI7XG5cdFx0cmV0dXJuIGRhdGFQcml2LmdldCggZWxlbSwga2V5ICkgfHwgZGF0YVByaXYuYWNjZXNzKCBlbGVtLCBrZXksIHtcblx0XHRcdGVtcHR5OiBqUXVlcnkuQ2FsbGJhY2tzKCBcIm9uY2UgbWVtb3J5XCIgKS5hZGQoIGZ1bmN0aW9uKCkge1xuXHRcdFx0XHRkYXRhUHJpdi5yZW1vdmUoIGVsZW0sIFsgdHlwZSArIFwicXVldWVcIiwga2V5IF0gKTtcblx0XHRcdH0gKVxuXHRcdH0gKTtcblx0fVxufSApO1xuXG5qUXVlcnkuZm4uZXh0ZW5kKCB7XG5cdHF1ZXVlOiBmdW5jdGlvbiggdHlwZSwgZGF0YSApIHtcblx0XHR2YXIgc2V0dGVyID0gMjtcblxuXHRcdGlmICggdHlwZW9mIHR5cGUgIT09IFwic3RyaW5nXCIgKSB7XG5cdFx0XHRkYXRhID0gdHlwZTtcblx0XHRcdHR5cGUgPSBcImZ4XCI7XG5cdFx0XHRzZXR0ZXItLTtcblx0XHR9XG5cblx0XHRpZiAoIGFyZ3VtZW50cy5sZW5ndGggPCBzZXR0ZXIgKSB7XG5cdFx0XHRyZXR1cm4galF1ZXJ5LnF1ZXVlKCB0aGlzWyAwIF0sIHR5cGUgKTtcblx0XHR9XG5cblx0XHRyZXR1cm4gZGF0YSA9PT0gdW5kZWZpbmVkID9cblx0XHRcdHRoaXMgOlxuXHRcdFx0dGhpcy5lYWNoKCBmdW5jdGlvbigpIHtcblx0XHRcdFx0dmFyIHF1ZXVlID0galF1ZXJ5LnF1ZXVlKCB0aGlzLCB0eXBlLCBkYXRhICk7XG5cblx0XHRcdFx0Ly8gRW5zdXJlIGEgaG9va3MgZm9yIHRoaXMgcXVldWVcblx0XHRcdFx0alF1ZXJ5Ll9xdWV1ZUhvb2tzKCB0aGlzLCB0eXBlICk7XG5cblx0XHRcdFx0aWYgKCB0eXBlID09PSBcImZ4XCIgJiYgcXVldWVbIDAgXSAhPT0gXCJpbnByb2dyZXNzXCIgKSB7XG5cdFx0XHRcdFx0alF1ZXJ5LmRlcXVldWUoIHRoaXMsIHR5cGUgKTtcblx0XHRcdFx0fVxuXHRcdFx0fSApO1xuXHR9LFxuXHRkZXF1ZXVlOiBmdW5jdGlvbiggdHlwZSApIHtcblx0XHRyZXR1cm4gdGhpcy5lYWNoKCBmdW5jdGlvbigpIHtcblx0XHRcdGpRdWVyeS5kZXF1ZXVlKCB0aGlzLCB0eXBlICk7XG5cdFx0fSApO1xuXHR9LFxuXHRjbGVhclF1ZXVlOiBmdW5jdGlvbiggdHlwZSApIHtcblx0XHRyZXR1cm4gdGhpcy5xdWV1ZSggdHlwZSB8fCBcImZ4XCIsIFtdICk7XG5cdH0sXG5cblx0Ly8gR2V0IGEgcHJvbWlzZSByZXNvbHZlZCB3aGVuIHF1ZXVlcyBvZiBhIGNlcnRhaW4gdHlwZVxuXHQvLyBhcmUgZW1wdGllZCAoZnggaXMgdGhlIHR5cGUgYnkgZGVmYXVsdClcblx0cHJvbWlzZTogZnVuY3Rpb24oIHR5cGUsIG9iaiApIHtcblx0XHR2YXIgdG1wLFxuXHRcdFx0Y291bnQgPSAxLFxuXHRcdFx0ZGVmZXIgPSBqUXVlcnkuRGVmZXJyZWQoKSxcblx0XHRcdGVsZW1lbnRzID0gdGhpcyxcblx0XHRcdGkgPSB0aGlzLmxlbmd0aCxcblx0XHRcdHJlc29sdmUgPSBmdW5jdGlvbigpIHtcblx0XHRcdFx0aWYgKCAhKCAtLWNvdW50ICkgKSB7XG5cdFx0XHRcdFx0ZGVmZXIucmVzb2x2ZVdpdGgoIGVsZW1lbnRzLCBbIGVsZW1lbnRzIF0gKTtcblx0XHRcdFx0fVxuXHRcdFx0fTtcblxuXHRcdGlmICggdHlwZW9mIHR5cGUgIT09IFwic3RyaW5nXCIgKSB7XG5cdFx0XHRvYmogPSB0eXBlO1xuXHRcdFx0dHlwZSA9IHVuZGVmaW5lZDtcblx0XHR9XG5cdFx0dHlwZSA9IHR5cGUgfHwgXCJmeFwiO1xuXG5cdFx0d2hpbGUgKCBpLS0gKSB7XG5cdFx0XHR0bXAgPSBkYXRhUHJpdi5nZXQoIGVsZW1lbnRzWyBpIF0sIHR5cGUgKyBcInF1ZXVlSG9va3NcIiApO1xuXHRcdFx0aWYgKCB0bXAgJiYgdG1wLmVtcHR5ICkge1xuXHRcdFx0XHRjb3VudCsrO1xuXHRcdFx0XHR0bXAuZW1wdHkuYWRkKCByZXNvbHZlICk7XG5cdFx0XHR9XG5cdFx0fVxuXHRcdHJlc29sdmUoKTtcblx0XHRyZXR1cm4gZGVmZXIucHJvbWlzZSggb2JqICk7XG5cdH1cbn0gKTtcbnZhciBwbnVtID0gKCAvWystXT8oPzpcXGQqXFwufClcXGQrKD86W2VFXVsrLV0/XFxkK3wpLyApLnNvdXJjZTtcblxudmFyIHJjc3NOdW0gPSBuZXcgUmVnRXhwKCBcIl4oPzooWystXSk9fCkoXCIgKyBwbnVtICsgXCIpKFthLXolXSopJFwiLCBcImlcIiApO1xuXG5cbnZhciBjc3NFeHBhbmQgPSBbIFwiVG9wXCIsIFwiUmlnaHRcIiwgXCJCb3R0b21cIiwgXCJMZWZ0XCIgXTtcblxudmFyIGlzSGlkZGVuV2l0aGluVHJlZSA9IGZ1bmN0aW9uKCBlbGVtLCBlbCApIHtcblxuXHRcdC8vIGlzSGlkZGVuV2l0aGluVHJlZSBtaWdodCBiZSBjYWxsZWQgZnJvbSBqUXVlcnkjZmlsdGVyIGZ1bmN0aW9uO1xuXHRcdC8vIGluIHRoYXQgY2FzZSwgZWxlbWVudCB3aWxsIGJlIHNlY29uZCBhcmd1bWVudFxuXHRcdGVsZW0gPSBlbCB8fCBlbGVtO1xuXG5cdFx0Ly8gSW5saW5lIHN0eWxlIHRydW1wcyBhbGxcblx0XHRyZXR1cm4gZWxlbS5zdHlsZS5kaXNwbGF5ID09PSBcIm5vbmVcIiB8fFxuXHRcdFx0ZWxlbS5zdHlsZS5kaXNwbGF5ID09PSBcIlwiICYmXG5cblx0XHRcdC8vIE90aGVyd2lzZSwgY2hlY2sgY29tcHV0ZWQgc3R5bGVcblx0XHRcdC8vIFN1cHBvcnQ6IEZpcmVmb3ggPD00MyAtIDQ1XG5cdFx0XHQvLyBEaXNjb25uZWN0ZWQgZWxlbWVudHMgY2FuIGhhdmUgY29tcHV0ZWQgZGlzcGxheTogbm9uZSwgc28gZmlyc3QgY29uZmlybSB0aGF0IGVsZW0gaXNcblx0XHRcdC8vIGluIHRoZSBkb2N1bWVudC5cblx0XHRcdGpRdWVyeS5jb250YWlucyggZWxlbS5vd25lckRvY3VtZW50LCBlbGVtICkgJiZcblxuXHRcdFx0alF1ZXJ5LmNzcyggZWxlbSwgXCJkaXNwbGF5XCIgKSA9PT0gXCJub25lXCI7XG5cdH07XG5cbnZhciBzd2FwID0gZnVuY3Rpb24oIGVsZW0sIG9wdGlvbnMsIGNhbGxiYWNrLCBhcmdzICkge1xuXHR2YXIgcmV0LCBuYW1lLFxuXHRcdG9sZCA9IHt9O1xuXG5cdC8vIFJlbWVtYmVyIHRoZSBvbGQgdmFsdWVzLCBhbmQgaW5zZXJ0IHRoZSBuZXcgb25lc1xuXHRmb3IgKCBuYW1lIGluIG9wdGlvbnMgKSB7XG5cdFx0b2xkWyBuYW1lIF0gPSBlbGVtLnN0eWxlWyBuYW1lIF07XG5cdFx0ZWxlbS5zdHlsZVsgbmFtZSBdID0gb3B0aW9uc1sgbmFtZSBdO1xuXHR9XG5cblx0cmV0ID0gY2FsbGJhY2suYXBwbHkoIGVsZW0sIGFyZ3MgfHwgW10gKTtcblxuXHQvLyBSZXZlcnQgdGhlIG9sZCB2YWx1ZXNcblx0Zm9yICggbmFtZSBpbiBvcHRpb25zICkge1xuXHRcdGVsZW0uc3R5bGVbIG5hbWUgXSA9IG9sZFsgbmFtZSBdO1xuXHR9XG5cblx0cmV0dXJuIHJldDtcbn07XG5cblxuXG5cbmZ1bmN0aW9uIGFkanVzdENTUyggZWxlbSwgcHJvcCwgdmFsdWVQYXJ0cywgdHdlZW4gKSB7XG5cdHZhciBhZGp1c3RlZCxcblx0XHRzY2FsZSA9IDEsXG5cdFx0bWF4SXRlcmF0aW9ucyA9IDIwLFxuXHRcdGN1cnJlbnRWYWx1ZSA9IHR3ZWVuID9cblx0XHRcdGZ1bmN0aW9uKCkge1xuXHRcdFx0XHRyZXR1cm4gdHdlZW4uY3VyKCk7XG5cdFx0XHR9IDpcblx0XHRcdGZ1bmN0aW9uKCkge1xuXHRcdFx0XHRyZXR1cm4galF1ZXJ5LmNzcyggZWxlbSwgcHJvcCwgXCJcIiApO1xuXHRcdFx0fSxcblx0XHRpbml0aWFsID0gY3VycmVudFZhbHVlKCksXG5cdFx0dW5pdCA9IHZhbHVlUGFydHMgJiYgdmFsdWVQYXJ0c1sgMyBdIHx8ICggalF1ZXJ5LmNzc051bWJlclsgcHJvcCBdID8gXCJcIiA6IFwicHhcIiApLFxuXG5cdFx0Ly8gU3RhcnRpbmcgdmFsdWUgY29tcHV0YXRpb24gaXMgcmVxdWlyZWQgZm9yIHBvdGVudGlhbCB1bml0IG1pc21hdGNoZXNcblx0XHRpbml0aWFsSW5Vbml0ID0gKCBqUXVlcnkuY3NzTnVtYmVyWyBwcm9wIF0gfHwgdW5pdCAhPT0gXCJweFwiICYmICtpbml0aWFsICkgJiZcblx0XHRcdHJjc3NOdW0uZXhlYyggalF1ZXJ5LmNzcyggZWxlbSwgcHJvcCApICk7XG5cblx0aWYgKCBpbml0aWFsSW5Vbml0ICYmIGluaXRpYWxJblVuaXRbIDMgXSAhPT0gdW5pdCApIHtcblxuXHRcdC8vIFRydXN0IHVuaXRzIHJlcG9ydGVkIGJ5IGpRdWVyeS5jc3Ncblx0XHR1bml0ID0gdW5pdCB8fCBpbml0aWFsSW5Vbml0WyAzIF07XG5cblx0XHQvLyBNYWtlIHN1cmUgd2UgdXBkYXRlIHRoZSB0d2VlbiBwcm9wZXJ0aWVzIGxhdGVyIG9uXG5cdFx0dmFsdWVQYXJ0cyA9IHZhbHVlUGFydHMgfHwgW107XG5cblx0XHQvLyBJdGVyYXRpdmVseSBhcHByb3hpbWF0ZSBmcm9tIGEgbm9uemVybyBzdGFydGluZyBwb2ludFxuXHRcdGluaXRpYWxJblVuaXQgPSAraW5pdGlhbCB8fCAxO1xuXG5cdFx0ZG8ge1xuXG5cdFx0XHQvLyBJZiBwcmV2aW91cyBpdGVyYXRpb24gemVyb2VkIG91dCwgZG91YmxlIHVudGlsIHdlIGdldCAqc29tZXRoaW5nKi5cblx0XHRcdC8vIFVzZSBzdHJpbmcgZm9yIGRvdWJsaW5nIHNvIHdlIGRvbid0IGFjY2lkZW50YWxseSBzZWUgc2NhbGUgYXMgdW5jaGFuZ2VkIGJlbG93XG5cdFx0XHRzY2FsZSA9IHNjYWxlIHx8IFwiLjVcIjtcblxuXHRcdFx0Ly8gQWRqdXN0IGFuZCBhcHBseVxuXHRcdFx0aW5pdGlhbEluVW5pdCA9IGluaXRpYWxJblVuaXQgLyBzY2FsZTtcblx0XHRcdGpRdWVyeS5zdHlsZSggZWxlbSwgcHJvcCwgaW5pdGlhbEluVW5pdCArIHVuaXQgKTtcblxuXHRcdC8vIFVwZGF0ZSBzY2FsZSwgdG9sZXJhdGluZyB6ZXJvIG9yIE5hTiBmcm9tIHR3ZWVuLmN1cigpXG5cdFx0Ly8gQnJlYWsgdGhlIGxvb3AgaWYgc2NhbGUgaXMgdW5jaGFuZ2VkIG9yIHBlcmZlY3QsIG9yIGlmIHdlJ3ZlIGp1c3QgaGFkIGVub3VnaC5cblx0XHR9IHdoaWxlIChcblx0XHRcdHNjYWxlICE9PSAoIHNjYWxlID0gY3VycmVudFZhbHVlKCkgLyBpbml0aWFsICkgJiYgc2NhbGUgIT09IDEgJiYgLS1tYXhJdGVyYXRpb25zXG5cdFx0KTtcblx0fVxuXG5cdGlmICggdmFsdWVQYXJ0cyApIHtcblx0XHRpbml0aWFsSW5Vbml0ID0gK2luaXRpYWxJblVuaXQgfHwgK2luaXRpYWwgfHwgMDtcblxuXHRcdC8vIEFwcGx5IHJlbGF0aXZlIG9mZnNldCAoKz0vLT0pIGlmIHNwZWNpZmllZFxuXHRcdGFkanVzdGVkID0gdmFsdWVQYXJ0c1sgMSBdID9cblx0XHRcdGluaXRpYWxJblVuaXQgKyAoIHZhbHVlUGFydHNbIDEgXSArIDEgKSAqIHZhbHVlUGFydHNbIDIgXSA6XG5cdFx0XHQrdmFsdWVQYXJ0c1sgMiBdO1xuXHRcdGlmICggdHdlZW4gKSB7XG5cdFx0XHR0d2Vlbi51bml0ID0gdW5pdDtcblx0XHRcdHR3ZWVuLnN0YXJ0ID0gaW5pdGlhbEluVW5pdDtcblx0XHRcdHR3ZWVuLmVuZCA9IGFkanVzdGVkO1xuXHRcdH1cblx0fVxuXHRyZXR1cm4gYWRqdXN0ZWQ7XG59XG5cblxudmFyIGRlZmF1bHREaXNwbGF5TWFwID0ge307XG5cbmZ1bmN0aW9uIGdldERlZmF1bHREaXNwbGF5KCBlbGVtICkge1xuXHR2YXIgdGVtcCxcblx0XHRkb2MgPSBlbGVtLm93bmVyRG9jdW1lbnQsXG5cdFx0bm9kZU5hbWUgPSBlbGVtLm5vZGVOYW1lLFxuXHRcdGRpc3BsYXkgPSBkZWZhdWx0RGlzcGxheU1hcFsgbm9kZU5hbWUgXTtcblxuXHRpZiAoIGRpc3BsYXkgKSB7XG5cdFx0cmV0dXJuIGRpc3BsYXk7XG5cdH1cblxuXHR0ZW1wID0gZG9jLmJvZHkuYXBwZW5kQ2hpbGQoIGRvYy5jcmVhdGVFbGVtZW50KCBub2RlTmFtZSApICk7XG5cdGRpc3BsYXkgPSBqUXVlcnkuY3NzKCB0ZW1wLCBcImRpc3BsYXlcIiApO1xuXG5cdHRlbXAucGFyZW50Tm9kZS5yZW1vdmVDaGlsZCggdGVtcCApO1xuXG5cdGlmICggZGlzcGxheSA9PT0gXCJub25lXCIgKSB7XG5cdFx0ZGlzcGxheSA9IFwiYmxvY2tcIjtcblx0fVxuXHRkZWZhdWx0RGlzcGxheU1hcFsgbm9kZU5hbWUgXSA9IGRpc3BsYXk7XG5cblx0cmV0dXJuIGRpc3BsYXk7XG59XG5cbmZ1bmN0aW9uIHNob3dIaWRlKCBlbGVtZW50cywgc2hvdyApIHtcblx0dmFyIGRpc3BsYXksIGVsZW0sXG5cdFx0dmFsdWVzID0gW10sXG5cdFx0aW5kZXggPSAwLFxuXHRcdGxlbmd0aCA9IGVsZW1lbnRzLmxlbmd0aDtcblxuXHQvLyBEZXRlcm1pbmUgbmV3IGRpc3BsYXkgdmFsdWUgZm9yIGVsZW1lbnRzIHRoYXQgbmVlZCB0byBjaGFuZ2Vcblx0Zm9yICggOyBpbmRleCA8IGxlbmd0aDsgaW5kZXgrKyApIHtcblx0XHRlbGVtID0gZWxlbWVudHNbIGluZGV4IF07XG5cdFx0aWYgKCAhZWxlbS5zdHlsZSApIHtcblx0XHRcdGNvbnRpbnVlO1xuXHRcdH1cblxuXHRcdGRpc3BsYXkgPSBlbGVtLnN0eWxlLmRpc3BsYXk7XG5cdFx0aWYgKCBzaG93ICkge1xuXG5cdFx0XHQvLyBTaW5jZSB3ZSBmb3JjZSB2aXNpYmlsaXR5IHVwb24gY2FzY2FkZS1oaWRkZW4gZWxlbWVudHMsIGFuIGltbWVkaWF0ZSAoYW5kIHNsb3cpXG5cdFx0XHQvLyBjaGVjayBpcyByZXF1aXJlZCBpbiB0aGlzIGZpcnN0IGxvb3AgdW5sZXNzIHdlIGhhdmUgYSBub25lbXB0eSBkaXNwbGF5IHZhbHVlIChlaXRoZXJcblx0XHRcdC8vIGlubGluZSBvciBhYm91dC10by1iZS1yZXN0b3JlZClcblx0XHRcdGlmICggZGlzcGxheSA9PT0gXCJub25lXCIgKSB7XG5cdFx0XHRcdHZhbHVlc1sgaW5kZXggXSA9IGRhdGFQcml2LmdldCggZWxlbSwgXCJkaXNwbGF5XCIgKSB8fCBudWxsO1xuXHRcdFx0XHRpZiAoICF2YWx1ZXNbIGluZGV4IF0gKSB7XG5cdFx0XHRcdFx0ZWxlbS5zdHlsZS5kaXNwbGF5ID0gXCJcIjtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdFx0aWYgKCBlbGVtLnN0eWxlLmRpc3BsYXkgPT09IFwiXCIgJiYgaXNIaWRkZW5XaXRoaW5UcmVlKCBlbGVtICkgKSB7XG5cdFx0XHRcdHZhbHVlc1sgaW5kZXggXSA9IGdldERlZmF1bHREaXNwbGF5KCBlbGVtICk7XG5cdFx0XHR9XG5cdFx0fSBlbHNlIHtcblx0XHRcdGlmICggZGlzcGxheSAhPT0gXCJub25lXCIgKSB7XG5cdFx0XHRcdHZhbHVlc1sgaW5kZXggXSA9IFwibm9uZVwiO1xuXG5cdFx0XHRcdC8vIFJlbWVtYmVyIHdoYXQgd2UncmUgb3ZlcndyaXRpbmdcblx0XHRcdFx0ZGF0YVByaXYuc2V0KCBlbGVtLCBcImRpc3BsYXlcIiwgZGlzcGxheSApO1xuXHRcdFx0fVxuXHRcdH1cblx0fVxuXG5cdC8vIFNldCB0aGUgZGlzcGxheSBvZiB0aGUgZWxlbWVudHMgaW4gYSBzZWNvbmQgbG9vcCB0byBhdm9pZCBjb25zdGFudCByZWZsb3dcblx0Zm9yICggaW5kZXggPSAwOyBpbmRleCA8IGxlbmd0aDsgaW5kZXgrKyApIHtcblx0XHRpZiAoIHZhbHVlc1sgaW5kZXggXSAhPSBudWxsICkge1xuXHRcdFx0ZWxlbWVudHNbIGluZGV4IF0uc3R5bGUuZGlzcGxheSA9IHZhbHVlc1sgaW5kZXggXTtcblx0XHR9XG5cdH1cblxuXHRyZXR1cm4gZWxlbWVudHM7XG59XG5cbmpRdWVyeS5mbi5leHRlbmQoIHtcblx0c2hvdzogZnVuY3Rpb24oKSB7XG5cdFx0cmV0dXJuIHNob3dIaWRlKCB0aGlzLCB0cnVlICk7XG5cdH0sXG5cdGhpZGU6IGZ1bmN0aW9uKCkge1xuXHRcdHJldHVybiBzaG93SGlkZSggdGhpcyApO1xuXHR9LFxuXHR0b2dnbGU6IGZ1bmN0aW9uKCBzdGF0ZSApIHtcblx0XHRpZiAoIHR5cGVvZiBzdGF0ZSA9PT0gXCJib29sZWFuXCIgKSB7XG5cdFx0XHRyZXR1cm4gc3RhdGUgPyB0aGlzLnNob3coKSA6IHRoaXMuaGlkZSgpO1xuXHRcdH1cblxuXHRcdHJldHVybiB0aGlzLmVhY2goIGZ1bmN0aW9uKCkge1xuXHRcdFx0aWYgKCBpc0hpZGRlbldpdGhpblRyZWUoIHRoaXMgKSApIHtcblx0XHRcdFx0alF1ZXJ5KCB0aGlzICkuc2hvdygpO1xuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0alF1ZXJ5KCB0aGlzICkuaGlkZSgpO1xuXHRcdFx0fVxuXHRcdH0gKTtcblx0fVxufSApO1xudmFyIHJjaGVja2FibGVUeXBlID0gKCAvXig/OmNoZWNrYm94fHJhZGlvKSQvaSApO1xuXG52YXIgcnRhZ05hbWUgPSAoIC88KFthLXpdW15cXC9cXDA+XFx4MjBcXHRcXHJcXG5cXGZdKykvaSApO1xuXG52YXIgcnNjcmlwdFR5cGUgPSAoIC9eJHxcXC8oPzpqYXZhfGVjbWEpc2NyaXB0L2kgKTtcblxuXG5cbi8vIFdlIGhhdmUgdG8gY2xvc2UgdGhlc2UgdGFncyB0byBzdXBwb3J0IFhIVE1MICgjMTMyMDApXG52YXIgd3JhcE1hcCA9IHtcblxuXHQvLyBTdXBwb3J0OiBJRSA8PTkgb25seVxuXHRvcHRpb246IFsgMSwgXCI8c2VsZWN0IG11bHRpcGxlPSdtdWx0aXBsZSc+XCIsIFwiPC9zZWxlY3Q+XCIgXSxcblxuXHQvLyBYSFRNTCBwYXJzZXJzIGRvIG5vdCBtYWdpY2FsbHkgaW5zZXJ0IGVsZW1lbnRzIGluIHRoZVxuXHQvLyBzYW1lIHdheSB0aGF0IHRhZyBzb3VwIHBhcnNlcnMgZG8uIFNvIHdlIGNhbm5vdCBzaG9ydGVuXG5cdC8vIHRoaXMgYnkgb21pdHRpbmcgPHRib2R5PiBvciBvdGhlciByZXF1aXJlZCBlbGVtZW50cy5cblx0dGhlYWQ6IFsgMSwgXCI8dGFibGU+XCIsIFwiPC90YWJsZT5cIiBdLFxuXHRjb2w6IFsgMiwgXCI8dGFibGU+PGNvbGdyb3VwPlwiLCBcIjwvY29sZ3JvdXA+PC90YWJsZT5cIiBdLFxuXHR0cjogWyAyLCBcIjx0YWJsZT48dGJvZHk+XCIsIFwiPC90Ym9keT48L3RhYmxlPlwiIF0sXG5cdHRkOiBbIDMsIFwiPHRhYmxlPjx0Ym9keT48dHI+XCIsIFwiPC90cj48L3Rib2R5PjwvdGFibGU+XCIgXSxcblxuXHRfZGVmYXVsdDogWyAwLCBcIlwiLCBcIlwiIF1cbn07XG5cbi8vIFN1cHBvcnQ6IElFIDw9OSBvbmx5XG53cmFwTWFwLm9wdGdyb3VwID0gd3JhcE1hcC5vcHRpb247XG5cbndyYXBNYXAudGJvZHkgPSB3cmFwTWFwLnRmb290ID0gd3JhcE1hcC5jb2xncm91cCA9IHdyYXBNYXAuY2FwdGlvbiA9IHdyYXBNYXAudGhlYWQ7XG53cmFwTWFwLnRoID0gd3JhcE1hcC50ZDtcblxuXG5mdW5jdGlvbiBnZXRBbGwoIGNvbnRleHQsIHRhZyApIHtcblxuXHQvLyBTdXBwb3J0OiBJRSA8PTkgLSAxMSBvbmx5XG5cdC8vIFVzZSB0eXBlb2YgdG8gYXZvaWQgemVyby1hcmd1bWVudCBtZXRob2QgaW52b2NhdGlvbiBvbiBob3N0IG9iamVjdHMgKCMxNTE1MSlcblx0dmFyIHJldDtcblxuXHRpZiAoIHR5cGVvZiBjb250ZXh0LmdldEVsZW1lbnRzQnlUYWdOYW1lICE9PSBcInVuZGVmaW5lZFwiICkge1xuXHRcdHJldCA9IGNvbnRleHQuZ2V0RWxlbWVudHNCeVRhZ05hbWUoIHRhZyB8fCBcIipcIiApO1xuXG5cdH0gZWxzZSBpZiAoIHR5cGVvZiBjb250ZXh0LnF1ZXJ5U2VsZWN0b3JBbGwgIT09IFwidW5kZWZpbmVkXCIgKSB7XG5cdFx0cmV0ID0gY29udGV4dC5xdWVyeVNlbGVjdG9yQWxsKCB0YWcgfHwgXCIqXCIgKTtcblxuXHR9IGVsc2Uge1xuXHRcdHJldCA9IFtdO1xuXHR9XG5cblx0aWYgKCB0YWcgPT09IHVuZGVmaW5lZCB8fCB0YWcgJiYgbm9kZU5hbWUoIGNvbnRleHQsIHRhZyApICkge1xuXHRcdHJldHVybiBqUXVlcnkubWVyZ2UoIFsgY29udGV4dCBdLCByZXQgKTtcblx0fVxuXG5cdHJldHVybiByZXQ7XG59XG5cblxuLy8gTWFyayBzY3JpcHRzIGFzIGhhdmluZyBhbHJlYWR5IGJlZW4gZXZhbHVhdGVkXG5mdW5jdGlvbiBzZXRHbG9iYWxFdmFsKCBlbGVtcywgcmVmRWxlbWVudHMgKSB7XG5cdHZhciBpID0gMCxcblx0XHRsID0gZWxlbXMubGVuZ3RoO1xuXG5cdGZvciAoIDsgaSA8IGw7IGkrKyApIHtcblx0XHRkYXRhUHJpdi5zZXQoXG5cdFx0XHRlbGVtc1sgaSBdLFxuXHRcdFx0XCJnbG9iYWxFdmFsXCIsXG5cdFx0XHQhcmVmRWxlbWVudHMgfHwgZGF0YVByaXYuZ2V0KCByZWZFbGVtZW50c1sgaSBdLCBcImdsb2JhbEV2YWxcIiApXG5cdFx0KTtcblx0fVxufVxuXG5cbnZhciByaHRtbCA9IC88fCYjP1xcdys7LztcblxuZnVuY3Rpb24gYnVpbGRGcmFnbWVudCggZWxlbXMsIGNvbnRleHQsIHNjcmlwdHMsIHNlbGVjdGlvbiwgaWdub3JlZCApIHtcblx0dmFyIGVsZW0sIHRtcCwgdGFnLCB3cmFwLCBjb250YWlucywgaixcblx0XHRmcmFnbWVudCA9IGNvbnRleHQuY3JlYXRlRG9jdW1lbnRGcmFnbWVudCgpLFxuXHRcdG5vZGVzID0gW10sXG5cdFx0aSA9IDAsXG5cdFx0bCA9IGVsZW1zLmxlbmd0aDtcblxuXHRmb3IgKCA7IGkgPCBsOyBpKysgKSB7XG5cdFx0ZWxlbSA9IGVsZW1zWyBpIF07XG5cblx0XHRpZiAoIGVsZW0gfHwgZWxlbSA9PT0gMCApIHtcblxuXHRcdFx0Ly8gQWRkIG5vZGVzIGRpcmVjdGx5XG5cdFx0XHRpZiAoIGpRdWVyeS50eXBlKCBlbGVtICkgPT09IFwib2JqZWN0XCIgKSB7XG5cblx0XHRcdFx0Ly8gU3VwcG9ydDogQW5kcm9pZCA8PTQuMCBvbmx5LCBQaGFudG9tSlMgMSBvbmx5XG5cdFx0XHRcdC8vIHB1c2guYXBwbHkoXywgYXJyYXlsaWtlKSB0aHJvd3Mgb24gYW5jaWVudCBXZWJLaXRcblx0XHRcdFx0alF1ZXJ5Lm1lcmdlKCBub2RlcywgZWxlbS5ub2RlVHlwZSA/IFsgZWxlbSBdIDogZWxlbSApO1xuXG5cdFx0XHQvLyBDb252ZXJ0IG5vbi1odG1sIGludG8gYSB0ZXh0IG5vZGVcblx0XHRcdH0gZWxzZSBpZiAoICFyaHRtbC50ZXN0KCBlbGVtICkgKSB7XG5cdFx0XHRcdG5vZGVzLnB1c2goIGNvbnRleHQuY3JlYXRlVGV4dE5vZGUoIGVsZW0gKSApO1xuXG5cdFx0XHQvLyBDb252ZXJ0IGh0bWwgaW50byBET00gbm9kZXNcblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdHRtcCA9IHRtcCB8fCBmcmFnbWVudC5hcHBlbmRDaGlsZCggY29udGV4dC5jcmVhdGVFbGVtZW50KCBcImRpdlwiICkgKTtcblxuXHRcdFx0XHQvLyBEZXNlcmlhbGl6ZSBhIHN0YW5kYXJkIHJlcHJlc2VudGF0aW9uXG5cdFx0XHRcdHRhZyA9ICggcnRhZ05hbWUuZXhlYyggZWxlbSApIHx8IFsgXCJcIiwgXCJcIiBdIClbIDEgXS50b0xvd2VyQ2FzZSgpO1xuXHRcdFx0XHR3cmFwID0gd3JhcE1hcFsgdGFnIF0gfHwgd3JhcE1hcC5fZGVmYXVsdDtcblx0XHRcdFx0dG1wLmlubmVySFRNTCA9IHdyYXBbIDEgXSArIGpRdWVyeS5odG1sUHJlZmlsdGVyKCBlbGVtICkgKyB3cmFwWyAyIF07XG5cblx0XHRcdFx0Ly8gRGVzY2VuZCB0aHJvdWdoIHdyYXBwZXJzIHRvIHRoZSByaWdodCBjb250ZW50XG5cdFx0XHRcdGogPSB3cmFwWyAwIF07XG5cdFx0XHRcdHdoaWxlICggai0tICkge1xuXHRcdFx0XHRcdHRtcCA9IHRtcC5sYXN0Q2hpbGQ7XG5cdFx0XHRcdH1cblxuXHRcdFx0XHQvLyBTdXBwb3J0OiBBbmRyb2lkIDw9NC4wIG9ubHksIFBoYW50b21KUyAxIG9ubHlcblx0XHRcdFx0Ly8gcHVzaC5hcHBseShfLCBhcnJheWxpa2UpIHRocm93cyBvbiBhbmNpZW50IFdlYktpdFxuXHRcdFx0XHRqUXVlcnkubWVyZ2UoIG5vZGVzLCB0bXAuY2hpbGROb2RlcyApO1xuXG5cdFx0XHRcdC8vIFJlbWVtYmVyIHRoZSB0b3AtbGV2ZWwgY29udGFpbmVyXG5cdFx0XHRcdHRtcCA9IGZyYWdtZW50LmZpcnN0Q2hpbGQ7XG5cblx0XHRcdFx0Ly8gRW5zdXJlIHRoZSBjcmVhdGVkIG5vZGVzIGFyZSBvcnBoYW5lZCAoIzEyMzkyKVxuXHRcdFx0XHR0bXAudGV4dENvbnRlbnQgPSBcIlwiO1xuXHRcdFx0fVxuXHRcdH1cblx0fVxuXG5cdC8vIFJlbW92ZSB3cmFwcGVyIGZyb20gZnJhZ21lbnRcblx0ZnJhZ21lbnQudGV4dENvbnRlbnQgPSBcIlwiO1xuXG5cdGkgPSAwO1xuXHR3aGlsZSAoICggZWxlbSA9IG5vZGVzWyBpKysgXSApICkge1xuXG5cdFx0Ly8gU2tpcCBlbGVtZW50cyBhbHJlYWR5IGluIHRoZSBjb250ZXh0IGNvbGxlY3Rpb24gKHRyYWMtNDA4Nylcblx0XHRpZiAoIHNlbGVjdGlvbiAmJiBqUXVlcnkuaW5BcnJheSggZWxlbSwgc2VsZWN0aW9uICkgPiAtMSApIHtcblx0XHRcdGlmICggaWdub3JlZCApIHtcblx0XHRcdFx0aWdub3JlZC5wdXNoKCBlbGVtICk7XG5cdFx0XHR9XG5cdFx0XHRjb250aW51ZTtcblx0XHR9XG5cblx0XHRjb250YWlucyA9IGpRdWVyeS5jb250YWlucyggZWxlbS5vd25lckRvY3VtZW50LCBlbGVtICk7XG5cblx0XHQvLyBBcHBlbmQgdG8gZnJhZ21lbnRcblx0XHR0bXAgPSBnZXRBbGwoIGZyYWdtZW50LmFwcGVuZENoaWxkKCBlbGVtICksIFwic2NyaXB0XCIgKTtcblxuXHRcdC8vIFByZXNlcnZlIHNjcmlwdCBldmFsdWF0aW9uIGhpc3Rvcnlcblx0XHRpZiAoIGNvbnRhaW5zICkge1xuXHRcdFx0c2V0R2xvYmFsRXZhbCggdG1wICk7XG5cdFx0fVxuXG5cdFx0Ly8gQ2FwdHVyZSBleGVjdXRhYmxlc1xuXHRcdGlmICggc2NyaXB0cyApIHtcblx0XHRcdGogPSAwO1xuXHRcdFx0d2hpbGUgKCAoIGVsZW0gPSB0bXBbIGorKyBdICkgKSB7XG5cdFx0XHRcdGlmICggcnNjcmlwdFR5cGUudGVzdCggZWxlbS50eXBlIHx8IFwiXCIgKSApIHtcblx0XHRcdFx0XHRzY3JpcHRzLnB1c2goIGVsZW0gKTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH1cblx0fVxuXG5cdHJldHVybiBmcmFnbWVudDtcbn1cblxuXG4oIGZ1bmN0aW9uKCkge1xuXHR2YXIgZnJhZ21lbnQgPSBkb2N1bWVudC5jcmVhdGVEb2N1bWVudEZyYWdtZW50KCksXG5cdFx0ZGl2ID0gZnJhZ21lbnQuYXBwZW5kQ2hpbGQoIGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoIFwiZGl2XCIgKSApLFxuXHRcdGlucHV0ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCggXCJpbnB1dFwiICk7XG5cblx0Ly8gU3VwcG9ydDogQW5kcm9pZCA0LjAgLSA0LjMgb25seVxuXHQvLyBDaGVjayBzdGF0ZSBsb3N0IGlmIHRoZSBuYW1lIGlzIHNldCAoIzExMjE3KVxuXHQvLyBTdXBwb3J0OiBXaW5kb3dzIFdlYiBBcHBzIChXV0EpXG5cdC8vIGBuYW1lYCBhbmQgYHR5cGVgIG11c3QgdXNlIC5zZXRBdHRyaWJ1dGUgZm9yIFdXQSAoIzE0OTAxKVxuXHRpbnB1dC5zZXRBdHRyaWJ1dGUoIFwidHlwZVwiLCBcInJhZGlvXCIgKTtcblx0aW5wdXQuc2V0QXR0cmlidXRlKCBcImNoZWNrZWRcIiwgXCJjaGVja2VkXCIgKTtcblx0aW5wdXQuc2V0QXR0cmlidXRlKCBcIm5hbWVcIiwgXCJ0XCIgKTtcblxuXHRkaXYuYXBwZW5kQ2hpbGQoIGlucHV0ICk7XG5cblx0Ly8gU3VwcG9ydDogQW5kcm9pZCA8PTQuMSBvbmx5XG5cdC8vIE9sZGVyIFdlYktpdCBkb2Vzbid0IGNsb25lIGNoZWNrZWQgc3RhdGUgY29ycmVjdGx5IGluIGZyYWdtZW50c1xuXHRzdXBwb3J0LmNoZWNrQ2xvbmUgPSBkaXYuY2xvbmVOb2RlKCB0cnVlICkuY2xvbmVOb2RlKCB0cnVlICkubGFzdENoaWxkLmNoZWNrZWQ7XG5cblx0Ly8gU3VwcG9ydDogSUUgPD0xMSBvbmx5XG5cdC8vIE1ha2Ugc3VyZSB0ZXh0YXJlYSAoYW5kIGNoZWNrYm94KSBkZWZhdWx0VmFsdWUgaXMgcHJvcGVybHkgY2xvbmVkXG5cdGRpdi5pbm5lckhUTUwgPSBcIjx0ZXh0YXJlYT54PC90ZXh0YXJlYT5cIjtcblx0c3VwcG9ydC5ub0Nsb25lQ2hlY2tlZCA9ICEhZGl2LmNsb25lTm9kZSggdHJ1ZSApLmxhc3RDaGlsZC5kZWZhdWx0VmFsdWU7XG59ICkoKTtcbnZhciBkb2N1bWVudEVsZW1lbnQgPSBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQ7XG5cblxuXG52YXJcblx0cmtleUV2ZW50ID0gL15rZXkvLFxuXHRybW91c2VFdmVudCA9IC9eKD86bW91c2V8cG9pbnRlcnxjb250ZXh0bWVudXxkcmFnfGRyb3ApfGNsaWNrLyxcblx0cnR5cGVuYW1lc3BhY2UgPSAvXihbXi5dKikoPzpcXC4oLispfCkvO1xuXG5mdW5jdGlvbiByZXR1cm5UcnVlKCkge1xuXHRyZXR1cm4gdHJ1ZTtcbn1cblxuZnVuY3Rpb24gcmV0dXJuRmFsc2UoKSB7XG5cdHJldHVybiBmYWxzZTtcbn1cblxuLy8gU3VwcG9ydDogSUUgPD05IG9ubHlcbi8vIFNlZSAjMTMzOTMgZm9yIG1vcmUgaW5mb1xuZnVuY3Rpb24gc2FmZUFjdGl2ZUVsZW1lbnQoKSB7XG5cdHRyeSB7XG5cdFx0cmV0dXJuIGRvY3VtZW50LmFjdGl2ZUVsZW1lbnQ7XG5cdH0gY2F0Y2ggKCBlcnIgKSB7IH1cbn1cblxuZnVuY3Rpb24gb24oIGVsZW0sIHR5cGVzLCBzZWxlY3RvciwgZGF0YSwgZm4sIG9uZSApIHtcblx0dmFyIG9yaWdGbiwgdHlwZTtcblxuXHQvLyBUeXBlcyBjYW4gYmUgYSBtYXAgb2YgdHlwZXMvaGFuZGxlcnNcblx0aWYgKCB0eXBlb2YgdHlwZXMgPT09IFwib2JqZWN0XCIgKSB7XG5cblx0XHQvLyAoIHR5cGVzLU9iamVjdCwgc2VsZWN0b3IsIGRhdGEgKVxuXHRcdGlmICggdHlwZW9mIHNlbGVjdG9yICE9PSBcInN0cmluZ1wiICkge1xuXG5cdFx0XHQvLyAoIHR5cGVzLU9iamVjdCwgZGF0YSApXG5cdFx0XHRkYXRhID0gZGF0YSB8fCBzZWxlY3Rvcjtcblx0XHRcdHNlbGVjdG9yID0gdW5kZWZpbmVkO1xuXHRcdH1cblx0XHRmb3IgKCB0eXBlIGluIHR5cGVzICkge1xuXHRcdFx0b24oIGVsZW0sIHR5cGUsIHNlbGVjdG9yLCBkYXRhLCB0eXBlc1sgdHlwZSBdLCBvbmUgKTtcblx0XHR9XG5cdFx0cmV0dXJuIGVsZW07XG5cdH1cblxuXHRpZiAoIGRhdGEgPT0gbnVsbCAmJiBmbiA9PSBudWxsICkge1xuXG5cdFx0Ly8gKCB0eXBlcywgZm4gKVxuXHRcdGZuID0gc2VsZWN0b3I7XG5cdFx0ZGF0YSA9IHNlbGVjdG9yID0gdW5kZWZpbmVkO1xuXHR9IGVsc2UgaWYgKCBmbiA9PSBudWxsICkge1xuXHRcdGlmICggdHlwZW9mIHNlbGVjdG9yID09PSBcInN0cmluZ1wiICkge1xuXG5cdFx0XHQvLyAoIHR5cGVzLCBzZWxlY3RvciwgZm4gKVxuXHRcdFx0Zm4gPSBkYXRhO1xuXHRcdFx0ZGF0YSA9IHVuZGVmaW5lZDtcblx0XHR9IGVsc2Uge1xuXG5cdFx0XHQvLyAoIHR5cGVzLCBkYXRhLCBmbiApXG5cdFx0XHRmbiA9IGRhdGE7XG5cdFx0XHRkYXRhID0gc2VsZWN0b3I7XG5cdFx0XHRzZWxlY3RvciA9IHVuZGVmaW5lZDtcblx0XHR9XG5cdH1cblx0aWYgKCBmbiA9PT0gZmFsc2UgKSB7XG5cdFx0Zm4gPSByZXR1cm5GYWxzZTtcblx0fSBlbHNlIGlmICggIWZuICkge1xuXHRcdHJldHVybiBlbGVtO1xuXHR9XG5cblx0aWYgKCBvbmUgPT09IDEgKSB7XG5cdFx0b3JpZ0ZuID0gZm47XG5cdFx0Zm4gPSBmdW5jdGlvbiggZXZlbnQgKSB7XG5cblx0XHRcdC8vIENhbiB1c2UgYW4gZW1wdHkgc2V0LCBzaW5jZSBldmVudCBjb250YWlucyB0aGUgaW5mb1xuXHRcdFx0alF1ZXJ5KCkub2ZmKCBldmVudCApO1xuXHRcdFx0cmV0dXJuIG9yaWdGbi5hcHBseSggdGhpcywgYXJndW1lbnRzICk7XG5cdFx0fTtcblxuXHRcdC8vIFVzZSBzYW1lIGd1aWQgc28gY2FsbGVyIGNhbiByZW1vdmUgdXNpbmcgb3JpZ0ZuXG5cdFx0Zm4uZ3VpZCA9IG9yaWdGbi5ndWlkIHx8ICggb3JpZ0ZuLmd1aWQgPSBqUXVlcnkuZ3VpZCsrICk7XG5cdH1cblx0cmV0dXJuIGVsZW0uZWFjaCggZnVuY3Rpb24oKSB7XG5cdFx0alF1ZXJ5LmV2ZW50LmFkZCggdGhpcywgdHlwZXMsIGZuLCBkYXRhLCBzZWxlY3RvciApO1xuXHR9ICk7XG59XG5cbi8qXG4gKiBIZWxwZXIgZnVuY3Rpb25zIGZvciBtYW5hZ2luZyBldmVudHMgLS0gbm90IHBhcnQgb2YgdGhlIHB1YmxpYyBpbnRlcmZhY2UuXG4gKiBQcm9wcyB0byBEZWFuIEVkd2FyZHMnIGFkZEV2ZW50IGxpYnJhcnkgZm9yIG1hbnkgb2YgdGhlIGlkZWFzLlxuICovXG5qUXVlcnkuZXZlbnQgPSB7XG5cblx0Z2xvYmFsOiB7fSxcblxuXHRhZGQ6IGZ1bmN0aW9uKCBlbGVtLCB0eXBlcywgaGFuZGxlciwgZGF0YSwgc2VsZWN0b3IgKSB7XG5cblx0XHR2YXIgaGFuZGxlT2JqSW4sIGV2ZW50SGFuZGxlLCB0bXAsXG5cdFx0XHRldmVudHMsIHQsIGhhbmRsZU9iaixcblx0XHRcdHNwZWNpYWwsIGhhbmRsZXJzLCB0eXBlLCBuYW1lc3BhY2VzLCBvcmlnVHlwZSxcblx0XHRcdGVsZW1EYXRhID0gZGF0YVByaXYuZ2V0KCBlbGVtICk7XG5cblx0XHQvLyBEb24ndCBhdHRhY2ggZXZlbnRzIHRvIG5vRGF0YSBvciB0ZXh0L2NvbW1lbnQgbm9kZXMgKGJ1dCBhbGxvdyBwbGFpbiBvYmplY3RzKVxuXHRcdGlmICggIWVsZW1EYXRhICkge1xuXHRcdFx0cmV0dXJuO1xuXHRcdH1cblxuXHRcdC8vIENhbGxlciBjYW4gcGFzcyBpbiBhbiBvYmplY3Qgb2YgY3VzdG9tIGRhdGEgaW4gbGlldSBvZiB0aGUgaGFuZGxlclxuXHRcdGlmICggaGFuZGxlci5oYW5kbGVyICkge1xuXHRcdFx0aGFuZGxlT2JqSW4gPSBoYW5kbGVyO1xuXHRcdFx0aGFuZGxlciA9IGhhbmRsZU9iakluLmhhbmRsZXI7XG5cdFx0XHRzZWxlY3RvciA9IGhhbmRsZU9iakluLnNlbGVjdG9yO1xuXHRcdH1cblxuXHRcdC8vIEVuc3VyZSB0aGF0IGludmFsaWQgc2VsZWN0b3JzIHRocm93IGV4Y2VwdGlvbnMgYXQgYXR0YWNoIHRpbWVcblx0XHQvLyBFdmFsdWF0ZSBhZ2FpbnN0IGRvY3VtZW50RWxlbWVudCBpbiBjYXNlIGVsZW0gaXMgYSBub24tZWxlbWVudCBub2RlIChlLmcuLCBkb2N1bWVudClcblx0XHRpZiAoIHNlbGVjdG9yICkge1xuXHRcdFx0alF1ZXJ5LmZpbmQubWF0Y2hlc1NlbGVjdG9yKCBkb2N1bWVudEVsZW1lbnQsIHNlbGVjdG9yICk7XG5cdFx0fVxuXG5cdFx0Ly8gTWFrZSBzdXJlIHRoYXQgdGhlIGhhbmRsZXIgaGFzIGEgdW5pcXVlIElELCB1c2VkIHRvIGZpbmQvcmVtb3ZlIGl0IGxhdGVyXG5cdFx0aWYgKCAhaGFuZGxlci5ndWlkICkge1xuXHRcdFx0aGFuZGxlci5ndWlkID0galF1ZXJ5Lmd1aWQrKztcblx0XHR9XG5cblx0XHQvLyBJbml0IHRoZSBlbGVtZW50J3MgZXZlbnQgc3RydWN0dXJlIGFuZCBtYWluIGhhbmRsZXIsIGlmIHRoaXMgaXMgdGhlIGZpcnN0XG5cdFx0aWYgKCAhKCBldmVudHMgPSBlbGVtRGF0YS5ldmVudHMgKSApIHtcblx0XHRcdGV2ZW50cyA9IGVsZW1EYXRhLmV2ZW50cyA9IHt9O1xuXHRcdH1cblx0XHRpZiAoICEoIGV2ZW50SGFuZGxlID0gZWxlbURhdGEuaGFuZGxlICkgKSB7XG5cdFx0XHRldmVudEhhbmRsZSA9IGVsZW1EYXRhLmhhbmRsZSA9IGZ1bmN0aW9uKCBlICkge1xuXG5cdFx0XHRcdC8vIERpc2NhcmQgdGhlIHNlY29uZCBldmVudCBvZiBhIGpRdWVyeS5ldmVudC50cmlnZ2VyKCkgYW5kXG5cdFx0XHRcdC8vIHdoZW4gYW4gZXZlbnQgaXMgY2FsbGVkIGFmdGVyIGEgcGFnZSBoYXMgdW5sb2FkZWRcblx0XHRcdFx0cmV0dXJuIHR5cGVvZiBqUXVlcnkgIT09IFwidW5kZWZpbmVkXCIgJiYgalF1ZXJ5LmV2ZW50LnRyaWdnZXJlZCAhPT0gZS50eXBlID9cblx0XHRcdFx0XHRqUXVlcnkuZXZlbnQuZGlzcGF0Y2guYXBwbHkoIGVsZW0sIGFyZ3VtZW50cyApIDogdW5kZWZpbmVkO1xuXHRcdFx0fTtcblx0XHR9XG5cblx0XHQvLyBIYW5kbGUgbXVsdGlwbGUgZXZlbnRzIHNlcGFyYXRlZCBieSBhIHNwYWNlXG5cdFx0dHlwZXMgPSAoIHR5cGVzIHx8IFwiXCIgKS5tYXRjaCggcm5vdGh0bWx3aGl0ZSApIHx8IFsgXCJcIiBdO1xuXHRcdHQgPSB0eXBlcy5sZW5ndGg7XG5cdFx0d2hpbGUgKCB0LS0gKSB7XG5cdFx0XHR0bXAgPSBydHlwZW5hbWVzcGFjZS5leGVjKCB0eXBlc1sgdCBdICkgfHwgW107XG5cdFx0XHR0eXBlID0gb3JpZ1R5cGUgPSB0bXBbIDEgXTtcblx0XHRcdG5hbWVzcGFjZXMgPSAoIHRtcFsgMiBdIHx8IFwiXCIgKS5zcGxpdCggXCIuXCIgKS5zb3J0KCk7XG5cblx0XHRcdC8vIFRoZXJlICptdXN0KiBiZSBhIHR5cGUsIG5vIGF0dGFjaGluZyBuYW1lc3BhY2Utb25seSBoYW5kbGVyc1xuXHRcdFx0aWYgKCAhdHlwZSApIHtcblx0XHRcdFx0Y29udGludWU7XG5cdFx0XHR9XG5cblx0XHRcdC8vIElmIGV2ZW50IGNoYW5nZXMgaXRzIHR5cGUsIHVzZSB0aGUgc3BlY2lhbCBldmVudCBoYW5kbGVycyBmb3IgdGhlIGNoYW5nZWQgdHlwZVxuXHRcdFx0c3BlY2lhbCA9IGpRdWVyeS5ldmVudC5zcGVjaWFsWyB0eXBlIF0gfHwge307XG5cblx0XHRcdC8vIElmIHNlbGVjdG9yIGRlZmluZWQsIGRldGVybWluZSBzcGVjaWFsIGV2ZW50IGFwaSB0eXBlLCBvdGhlcndpc2UgZ2l2ZW4gdHlwZVxuXHRcdFx0dHlwZSA9ICggc2VsZWN0b3IgPyBzcGVjaWFsLmRlbGVnYXRlVHlwZSA6IHNwZWNpYWwuYmluZFR5cGUgKSB8fCB0eXBlO1xuXG5cdFx0XHQvLyBVcGRhdGUgc3BlY2lhbCBiYXNlZCBvbiBuZXdseSByZXNldCB0eXBlXG5cdFx0XHRzcGVjaWFsID0galF1ZXJ5LmV2ZW50LnNwZWNpYWxbIHR5cGUgXSB8fCB7fTtcblxuXHRcdFx0Ly8gaGFuZGxlT2JqIGlzIHBhc3NlZCB0byBhbGwgZXZlbnQgaGFuZGxlcnNcblx0XHRcdGhhbmRsZU9iaiA9IGpRdWVyeS5leHRlbmQoIHtcblx0XHRcdFx0dHlwZTogdHlwZSxcblx0XHRcdFx0b3JpZ1R5cGU6IG9yaWdUeXBlLFxuXHRcdFx0XHRkYXRhOiBkYXRhLFxuXHRcdFx0XHRoYW5kbGVyOiBoYW5kbGVyLFxuXHRcdFx0XHRndWlkOiBoYW5kbGVyLmd1aWQsXG5cdFx0XHRcdHNlbGVjdG9yOiBzZWxlY3Rvcixcblx0XHRcdFx0bmVlZHNDb250ZXh0OiBzZWxlY3RvciAmJiBqUXVlcnkuZXhwci5tYXRjaC5uZWVkc0NvbnRleHQudGVzdCggc2VsZWN0b3IgKSxcblx0XHRcdFx0bmFtZXNwYWNlOiBuYW1lc3BhY2VzLmpvaW4oIFwiLlwiIClcblx0XHRcdH0sIGhhbmRsZU9iakluICk7XG5cblx0XHRcdC8vIEluaXQgdGhlIGV2ZW50IGhhbmRsZXIgcXVldWUgaWYgd2UncmUgdGhlIGZpcnN0XG5cdFx0XHRpZiAoICEoIGhhbmRsZXJzID0gZXZlbnRzWyB0eXBlIF0gKSApIHtcblx0XHRcdFx0aGFuZGxlcnMgPSBldmVudHNbIHR5cGUgXSA9IFtdO1xuXHRcdFx0XHRoYW5kbGVycy5kZWxlZ2F0ZUNvdW50ID0gMDtcblxuXHRcdFx0XHQvLyBPbmx5IHVzZSBhZGRFdmVudExpc3RlbmVyIGlmIHRoZSBzcGVjaWFsIGV2ZW50cyBoYW5kbGVyIHJldHVybnMgZmFsc2Vcblx0XHRcdFx0aWYgKCAhc3BlY2lhbC5zZXR1cCB8fFxuXHRcdFx0XHRcdHNwZWNpYWwuc2V0dXAuY2FsbCggZWxlbSwgZGF0YSwgbmFtZXNwYWNlcywgZXZlbnRIYW5kbGUgKSA9PT0gZmFsc2UgKSB7XG5cblx0XHRcdFx0XHRpZiAoIGVsZW0uYWRkRXZlbnRMaXN0ZW5lciApIHtcblx0XHRcdFx0XHRcdGVsZW0uYWRkRXZlbnRMaXN0ZW5lciggdHlwZSwgZXZlbnRIYW5kbGUgKTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblx0XHRcdH1cblxuXHRcdFx0aWYgKCBzcGVjaWFsLmFkZCApIHtcblx0XHRcdFx0c3BlY2lhbC5hZGQuY2FsbCggZWxlbSwgaGFuZGxlT2JqICk7XG5cblx0XHRcdFx0aWYgKCAhaGFuZGxlT2JqLmhhbmRsZXIuZ3VpZCApIHtcblx0XHRcdFx0XHRoYW5kbGVPYmouaGFuZGxlci5ndWlkID0gaGFuZGxlci5ndWlkO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cblx0XHRcdC8vIEFkZCB0byB0aGUgZWxlbWVudCdzIGhhbmRsZXIgbGlzdCwgZGVsZWdhdGVzIGluIGZyb250XG5cdFx0XHRpZiAoIHNlbGVjdG9yICkge1xuXHRcdFx0XHRoYW5kbGVycy5zcGxpY2UoIGhhbmRsZXJzLmRlbGVnYXRlQ291bnQrKywgMCwgaGFuZGxlT2JqICk7XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRoYW5kbGVycy5wdXNoKCBoYW5kbGVPYmogKTtcblx0XHRcdH1cblxuXHRcdFx0Ly8gS2VlcCB0cmFjayBvZiB3aGljaCBldmVudHMgaGF2ZSBldmVyIGJlZW4gdXNlZCwgZm9yIGV2ZW50IG9wdGltaXphdGlvblxuXHRcdFx0alF1ZXJ5LmV2ZW50Lmdsb2JhbFsgdHlwZSBdID0gdHJ1ZTtcblx0XHR9XG5cblx0fSxcblxuXHQvLyBEZXRhY2ggYW4gZXZlbnQgb3Igc2V0IG9mIGV2ZW50cyBmcm9tIGFuIGVsZW1lbnRcblx0cmVtb3ZlOiBmdW5jdGlvbiggZWxlbSwgdHlwZXMsIGhhbmRsZXIsIHNlbGVjdG9yLCBtYXBwZWRUeXBlcyApIHtcblxuXHRcdHZhciBqLCBvcmlnQ291bnQsIHRtcCxcblx0XHRcdGV2ZW50cywgdCwgaGFuZGxlT2JqLFxuXHRcdFx0c3BlY2lhbCwgaGFuZGxlcnMsIHR5cGUsIG5hbWVzcGFjZXMsIG9yaWdUeXBlLFxuXHRcdFx0ZWxlbURhdGEgPSBkYXRhUHJpdi5oYXNEYXRhKCBlbGVtICkgJiYgZGF0YVByaXYuZ2V0KCBlbGVtICk7XG5cblx0XHRpZiAoICFlbGVtRGF0YSB8fCAhKCBldmVudHMgPSBlbGVtRGF0YS5ldmVudHMgKSApIHtcblx0XHRcdHJldHVybjtcblx0XHR9XG5cblx0XHQvLyBPbmNlIGZvciBlYWNoIHR5cGUubmFtZXNwYWNlIGluIHR5cGVzOyB0eXBlIG1heSBiZSBvbWl0dGVkXG5cdFx0dHlwZXMgPSAoIHR5cGVzIHx8IFwiXCIgKS5tYXRjaCggcm5vdGh0bWx3aGl0ZSApIHx8IFsgXCJcIiBdO1xuXHRcdHQgPSB0eXBlcy5sZW5ndGg7XG5cdFx0d2hpbGUgKCB0LS0gKSB7XG5cdFx0XHR0bXAgPSBydHlwZW5hbWVzcGFjZS5leGVjKCB0eXBlc1sgdCBdICkgfHwgW107XG5cdFx0XHR0eXBlID0gb3JpZ1R5cGUgPSB0bXBbIDEgXTtcblx0XHRcdG5hbWVzcGFjZXMgPSAoIHRtcFsgMiBdIHx8IFwiXCIgKS5zcGxpdCggXCIuXCIgKS5zb3J0KCk7XG5cblx0XHRcdC8vIFVuYmluZCBhbGwgZXZlbnRzIChvbiB0aGlzIG5hbWVzcGFjZSwgaWYgcHJvdmlkZWQpIGZvciB0aGUgZWxlbWVudFxuXHRcdFx0aWYgKCAhdHlwZSApIHtcblx0XHRcdFx0Zm9yICggdHlwZSBpbiBldmVudHMgKSB7XG5cdFx0XHRcdFx0alF1ZXJ5LmV2ZW50LnJlbW92ZSggZWxlbSwgdHlwZSArIHR5cGVzWyB0IF0sIGhhbmRsZXIsIHNlbGVjdG9yLCB0cnVlICk7XG5cdFx0XHRcdH1cblx0XHRcdFx0Y29udGludWU7XG5cdFx0XHR9XG5cblx0XHRcdHNwZWNpYWwgPSBqUXVlcnkuZXZlbnQuc3BlY2lhbFsgdHlwZSBdIHx8IHt9O1xuXHRcdFx0dHlwZSA9ICggc2VsZWN0b3IgPyBzcGVjaWFsLmRlbGVnYXRlVHlwZSA6IHNwZWNpYWwuYmluZFR5cGUgKSB8fCB0eXBlO1xuXHRcdFx0aGFuZGxlcnMgPSBldmVudHNbIHR5cGUgXSB8fCBbXTtcblx0XHRcdHRtcCA9IHRtcFsgMiBdICYmXG5cdFx0XHRcdG5ldyBSZWdFeHAoIFwiKF58XFxcXC4pXCIgKyBuYW1lc3BhY2VzLmpvaW4oIFwiXFxcXC4oPzouKlxcXFwufClcIiApICsgXCIoXFxcXC58JClcIiApO1xuXG5cdFx0XHQvLyBSZW1vdmUgbWF0Y2hpbmcgZXZlbnRzXG5cdFx0XHRvcmlnQ291bnQgPSBqID0gaGFuZGxlcnMubGVuZ3RoO1xuXHRcdFx0d2hpbGUgKCBqLS0gKSB7XG5cdFx0XHRcdGhhbmRsZU9iaiA9IGhhbmRsZXJzWyBqIF07XG5cblx0XHRcdFx0aWYgKCAoIG1hcHBlZFR5cGVzIHx8IG9yaWdUeXBlID09PSBoYW5kbGVPYmoub3JpZ1R5cGUgKSAmJlxuXHRcdFx0XHRcdCggIWhhbmRsZXIgfHwgaGFuZGxlci5ndWlkID09PSBoYW5kbGVPYmouZ3VpZCApICYmXG5cdFx0XHRcdFx0KCAhdG1wIHx8IHRtcC50ZXN0KCBoYW5kbGVPYmoubmFtZXNwYWNlICkgKSAmJlxuXHRcdFx0XHRcdCggIXNlbGVjdG9yIHx8IHNlbGVjdG9yID09PSBoYW5kbGVPYmouc2VsZWN0b3IgfHxcblx0XHRcdFx0XHRcdHNlbGVjdG9yID09PSBcIioqXCIgJiYgaGFuZGxlT2JqLnNlbGVjdG9yICkgKSB7XG5cdFx0XHRcdFx0aGFuZGxlcnMuc3BsaWNlKCBqLCAxICk7XG5cblx0XHRcdFx0XHRpZiAoIGhhbmRsZU9iai5zZWxlY3RvciApIHtcblx0XHRcdFx0XHRcdGhhbmRsZXJzLmRlbGVnYXRlQ291bnQtLTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0aWYgKCBzcGVjaWFsLnJlbW92ZSApIHtcblx0XHRcdFx0XHRcdHNwZWNpYWwucmVtb3ZlLmNhbGwoIGVsZW0sIGhhbmRsZU9iaiApO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXHRcdFx0fVxuXG5cdFx0XHQvLyBSZW1vdmUgZ2VuZXJpYyBldmVudCBoYW5kbGVyIGlmIHdlIHJlbW92ZWQgc29tZXRoaW5nIGFuZCBubyBtb3JlIGhhbmRsZXJzIGV4aXN0XG5cdFx0XHQvLyAoYXZvaWRzIHBvdGVudGlhbCBmb3IgZW5kbGVzcyByZWN1cnNpb24gZHVyaW5nIHJlbW92YWwgb2Ygc3BlY2lhbCBldmVudCBoYW5kbGVycylcblx0XHRcdGlmICggb3JpZ0NvdW50ICYmICFoYW5kbGVycy5sZW5ndGggKSB7XG5cdFx0XHRcdGlmICggIXNwZWNpYWwudGVhcmRvd24gfHxcblx0XHRcdFx0XHRzcGVjaWFsLnRlYXJkb3duLmNhbGwoIGVsZW0sIG5hbWVzcGFjZXMsIGVsZW1EYXRhLmhhbmRsZSApID09PSBmYWxzZSApIHtcblxuXHRcdFx0XHRcdGpRdWVyeS5yZW1vdmVFdmVudCggZWxlbSwgdHlwZSwgZWxlbURhdGEuaGFuZGxlICk7XG5cdFx0XHRcdH1cblxuXHRcdFx0XHRkZWxldGUgZXZlbnRzWyB0eXBlIF07XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0Ly8gUmVtb3ZlIGRhdGEgYW5kIHRoZSBleHBhbmRvIGlmIGl0J3Mgbm8gbG9uZ2VyIHVzZWRcblx0XHRpZiAoIGpRdWVyeS5pc0VtcHR5T2JqZWN0KCBldmVudHMgKSApIHtcblx0XHRcdGRhdGFQcml2LnJlbW92ZSggZWxlbSwgXCJoYW5kbGUgZXZlbnRzXCIgKTtcblx0XHR9XG5cdH0sXG5cblx0ZGlzcGF0Y2g6IGZ1bmN0aW9uKCBuYXRpdmVFdmVudCApIHtcblxuXHRcdC8vIE1ha2UgYSB3cml0YWJsZSBqUXVlcnkuRXZlbnQgZnJvbSB0aGUgbmF0aXZlIGV2ZW50IG9iamVjdFxuXHRcdHZhciBldmVudCA9IGpRdWVyeS5ldmVudC5maXgoIG5hdGl2ZUV2ZW50ICk7XG5cblx0XHR2YXIgaSwgaiwgcmV0LCBtYXRjaGVkLCBoYW5kbGVPYmosIGhhbmRsZXJRdWV1ZSxcblx0XHRcdGFyZ3MgPSBuZXcgQXJyYXkoIGFyZ3VtZW50cy5sZW5ndGggKSxcblx0XHRcdGhhbmRsZXJzID0gKCBkYXRhUHJpdi5nZXQoIHRoaXMsIFwiZXZlbnRzXCIgKSB8fCB7fSApWyBldmVudC50eXBlIF0gfHwgW10sXG5cdFx0XHRzcGVjaWFsID0galF1ZXJ5LmV2ZW50LnNwZWNpYWxbIGV2ZW50LnR5cGUgXSB8fCB7fTtcblxuXHRcdC8vIFVzZSB0aGUgZml4LWVkIGpRdWVyeS5FdmVudCByYXRoZXIgdGhhbiB0aGUgKHJlYWQtb25seSkgbmF0aXZlIGV2ZW50XG5cdFx0YXJnc1sgMCBdID0gZXZlbnQ7XG5cblx0XHRmb3IgKCBpID0gMTsgaSA8IGFyZ3VtZW50cy5sZW5ndGg7IGkrKyApIHtcblx0XHRcdGFyZ3NbIGkgXSA9IGFyZ3VtZW50c1sgaSBdO1xuXHRcdH1cblxuXHRcdGV2ZW50LmRlbGVnYXRlVGFyZ2V0ID0gdGhpcztcblxuXHRcdC8vIENhbGwgdGhlIHByZURpc3BhdGNoIGhvb2sgZm9yIHRoZSBtYXBwZWQgdHlwZSwgYW5kIGxldCBpdCBiYWlsIGlmIGRlc2lyZWRcblx0XHRpZiAoIHNwZWNpYWwucHJlRGlzcGF0Y2ggJiYgc3BlY2lhbC5wcmVEaXNwYXRjaC5jYWxsKCB0aGlzLCBldmVudCApID09PSBmYWxzZSApIHtcblx0XHRcdHJldHVybjtcblx0XHR9XG5cblx0XHQvLyBEZXRlcm1pbmUgaGFuZGxlcnNcblx0XHRoYW5kbGVyUXVldWUgPSBqUXVlcnkuZXZlbnQuaGFuZGxlcnMuY2FsbCggdGhpcywgZXZlbnQsIGhhbmRsZXJzICk7XG5cblx0XHQvLyBSdW4gZGVsZWdhdGVzIGZpcnN0OyB0aGV5IG1heSB3YW50IHRvIHN0b3AgcHJvcGFnYXRpb24gYmVuZWF0aCB1c1xuXHRcdGkgPSAwO1xuXHRcdHdoaWxlICggKCBtYXRjaGVkID0gaGFuZGxlclF1ZXVlWyBpKysgXSApICYmICFldmVudC5pc1Byb3BhZ2F0aW9uU3RvcHBlZCgpICkge1xuXHRcdFx0ZXZlbnQuY3VycmVudFRhcmdldCA9IG1hdGNoZWQuZWxlbTtcblxuXHRcdFx0aiA9IDA7XG5cdFx0XHR3aGlsZSAoICggaGFuZGxlT2JqID0gbWF0Y2hlZC5oYW5kbGVyc1sgaisrIF0gKSAmJlxuXHRcdFx0XHQhZXZlbnQuaXNJbW1lZGlhdGVQcm9wYWdhdGlvblN0b3BwZWQoKSApIHtcblxuXHRcdFx0XHQvLyBUcmlnZ2VyZWQgZXZlbnQgbXVzdCBlaXRoZXIgMSkgaGF2ZSBubyBuYW1lc3BhY2UsIG9yIDIpIGhhdmUgbmFtZXNwYWNlKHMpXG5cdFx0XHRcdC8vIGEgc3Vic2V0IG9yIGVxdWFsIHRvIHRob3NlIGluIHRoZSBib3VuZCBldmVudCAoYm90aCBjYW4gaGF2ZSBubyBuYW1lc3BhY2UpLlxuXHRcdFx0XHRpZiAoICFldmVudC5ybmFtZXNwYWNlIHx8IGV2ZW50LnJuYW1lc3BhY2UudGVzdCggaGFuZGxlT2JqLm5hbWVzcGFjZSApICkge1xuXG5cdFx0XHRcdFx0ZXZlbnQuaGFuZGxlT2JqID0gaGFuZGxlT2JqO1xuXHRcdFx0XHRcdGV2ZW50LmRhdGEgPSBoYW5kbGVPYmouZGF0YTtcblxuXHRcdFx0XHRcdHJldCA9ICggKCBqUXVlcnkuZXZlbnQuc3BlY2lhbFsgaGFuZGxlT2JqLm9yaWdUeXBlIF0gfHwge30gKS5oYW5kbGUgfHxcblx0XHRcdFx0XHRcdGhhbmRsZU9iai5oYW5kbGVyICkuYXBwbHkoIG1hdGNoZWQuZWxlbSwgYXJncyApO1xuXG5cdFx0XHRcdFx0aWYgKCByZXQgIT09IHVuZGVmaW5lZCApIHtcblx0XHRcdFx0XHRcdGlmICggKCBldmVudC5yZXN1bHQgPSByZXQgKSA9PT0gZmFsc2UgKSB7XG5cdFx0XHRcdFx0XHRcdGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG5cdFx0XHRcdFx0XHRcdGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpO1xuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH1cblxuXHRcdC8vIENhbGwgdGhlIHBvc3REaXNwYXRjaCBob29rIGZvciB0aGUgbWFwcGVkIHR5cGVcblx0XHRpZiAoIHNwZWNpYWwucG9zdERpc3BhdGNoICkge1xuXHRcdFx0c3BlY2lhbC5wb3N0RGlzcGF0Y2guY2FsbCggdGhpcywgZXZlbnQgKTtcblx0XHR9XG5cblx0XHRyZXR1cm4gZXZlbnQucmVzdWx0O1xuXHR9LFxuXG5cdGhhbmRsZXJzOiBmdW5jdGlvbiggZXZlbnQsIGhhbmRsZXJzICkge1xuXHRcdHZhciBpLCBoYW5kbGVPYmosIHNlbCwgbWF0Y2hlZEhhbmRsZXJzLCBtYXRjaGVkU2VsZWN0b3JzLFxuXHRcdFx0aGFuZGxlclF1ZXVlID0gW10sXG5cdFx0XHRkZWxlZ2F0ZUNvdW50ID0gaGFuZGxlcnMuZGVsZWdhdGVDb3VudCxcblx0XHRcdGN1ciA9IGV2ZW50LnRhcmdldDtcblxuXHRcdC8vIEZpbmQgZGVsZWdhdGUgaGFuZGxlcnNcblx0XHRpZiAoIGRlbGVnYXRlQ291bnQgJiZcblxuXHRcdFx0Ly8gU3VwcG9ydDogSUUgPD05XG5cdFx0XHQvLyBCbGFjay1ob2xlIFNWRyA8dXNlPiBpbnN0YW5jZSB0cmVlcyAodHJhYy0xMzE4MClcblx0XHRcdGN1ci5ub2RlVHlwZSAmJlxuXG5cdFx0XHQvLyBTdXBwb3J0OiBGaXJlZm94IDw9NDJcblx0XHRcdC8vIFN1cHByZXNzIHNwZWMtdmlvbGF0aW5nIGNsaWNrcyBpbmRpY2F0aW5nIGEgbm9uLXByaW1hcnkgcG9pbnRlciBidXR0b24gKHRyYWMtMzg2MSlcblx0XHRcdC8vIGh0dHBzOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMy1FdmVudHMvI2V2ZW50LXR5cGUtY2xpY2tcblx0XHRcdC8vIFN1cHBvcnQ6IElFIDExIG9ubHlcblx0XHRcdC8vIC4uLmJ1dCBub3QgYXJyb3cga2V5IFwiY2xpY2tzXCIgb2YgcmFkaW8gaW5wdXRzLCB3aGljaCBjYW4gaGF2ZSBgYnV0dG9uYCAtMSAoZ2gtMjM0Mylcblx0XHRcdCEoIGV2ZW50LnR5cGUgPT09IFwiY2xpY2tcIiAmJiBldmVudC5idXR0b24gPj0gMSApICkge1xuXG5cdFx0XHRmb3IgKCA7IGN1ciAhPT0gdGhpczsgY3VyID0gY3VyLnBhcmVudE5vZGUgfHwgdGhpcyApIHtcblxuXHRcdFx0XHQvLyBEb24ndCBjaGVjayBub24tZWxlbWVudHMgKCMxMzIwOClcblx0XHRcdFx0Ly8gRG9uJ3QgcHJvY2VzcyBjbGlja3Mgb24gZGlzYWJsZWQgZWxlbWVudHMgKCM2OTExLCAjODE2NSwgIzExMzgyLCAjMTE3NjQpXG5cdFx0XHRcdGlmICggY3VyLm5vZGVUeXBlID09PSAxICYmICEoIGV2ZW50LnR5cGUgPT09IFwiY2xpY2tcIiAmJiBjdXIuZGlzYWJsZWQgPT09IHRydWUgKSApIHtcblx0XHRcdFx0XHRtYXRjaGVkSGFuZGxlcnMgPSBbXTtcblx0XHRcdFx0XHRtYXRjaGVkU2VsZWN0b3JzID0ge307XG5cdFx0XHRcdFx0Zm9yICggaSA9IDA7IGkgPCBkZWxlZ2F0ZUNvdW50OyBpKysgKSB7XG5cdFx0XHRcdFx0XHRoYW5kbGVPYmogPSBoYW5kbGVyc1sgaSBdO1xuXG5cdFx0XHRcdFx0XHQvLyBEb24ndCBjb25mbGljdCB3aXRoIE9iamVjdC5wcm90b3R5cGUgcHJvcGVydGllcyAoIzEzMjAzKVxuXHRcdFx0XHRcdFx0c2VsID0gaGFuZGxlT2JqLnNlbGVjdG9yICsgXCIgXCI7XG5cblx0XHRcdFx0XHRcdGlmICggbWF0Y2hlZFNlbGVjdG9yc1sgc2VsIF0gPT09IHVuZGVmaW5lZCApIHtcblx0XHRcdFx0XHRcdFx0bWF0Y2hlZFNlbGVjdG9yc1sgc2VsIF0gPSBoYW5kbGVPYmoubmVlZHNDb250ZXh0ID9cblx0XHRcdFx0XHRcdFx0XHRqUXVlcnkoIHNlbCwgdGhpcyApLmluZGV4KCBjdXIgKSA+IC0xIDpcblx0XHRcdFx0XHRcdFx0XHRqUXVlcnkuZmluZCggc2VsLCB0aGlzLCBudWxsLCBbIGN1ciBdICkubGVuZ3RoO1xuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0aWYgKCBtYXRjaGVkU2VsZWN0b3JzWyBzZWwgXSApIHtcblx0XHRcdFx0XHRcdFx0bWF0Y2hlZEhhbmRsZXJzLnB1c2goIGhhbmRsZU9iaiApO1xuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdH1cblx0XHRcdFx0XHRpZiAoIG1hdGNoZWRIYW5kbGVycy5sZW5ndGggKSB7XG5cdFx0XHRcdFx0XHRoYW5kbGVyUXVldWUucHVzaCggeyBlbGVtOiBjdXIsIGhhbmRsZXJzOiBtYXRjaGVkSGFuZGxlcnMgfSApO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH1cblxuXHRcdC8vIEFkZCB0aGUgcmVtYWluaW5nIChkaXJlY3RseS1ib3VuZCkgaGFuZGxlcnNcblx0XHRjdXIgPSB0aGlzO1xuXHRcdGlmICggZGVsZWdhdGVDb3VudCA8IGhhbmRsZXJzLmxlbmd0aCApIHtcblx0XHRcdGhhbmRsZXJRdWV1ZS5wdXNoKCB7IGVsZW06IGN1ciwgaGFuZGxlcnM6IGhhbmRsZXJzLnNsaWNlKCBkZWxlZ2F0ZUNvdW50ICkgfSApO1xuXHRcdH1cblxuXHRcdHJldHVybiBoYW5kbGVyUXVldWU7XG5cdH0sXG5cblx0YWRkUHJvcDogZnVuY3Rpb24oIG5hbWUsIGhvb2sgKSB7XG5cdFx0T2JqZWN0LmRlZmluZVByb3BlcnR5KCBqUXVlcnkuRXZlbnQucHJvdG90eXBlLCBuYW1lLCB7XG5cdFx0XHRlbnVtZXJhYmxlOiB0cnVlLFxuXHRcdFx0Y29uZmlndXJhYmxlOiB0cnVlLFxuXG5cdFx0XHRnZXQ6IGpRdWVyeS5pc0Z1bmN0aW9uKCBob29rICkgP1xuXHRcdFx0XHRmdW5jdGlvbigpIHtcblx0XHRcdFx0XHRpZiAoIHRoaXMub3JpZ2luYWxFdmVudCApIHtcblx0XHRcdFx0XHRcdFx0cmV0dXJuIGhvb2soIHRoaXMub3JpZ2luYWxFdmVudCApO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fSA6XG5cdFx0XHRcdGZ1bmN0aW9uKCkge1xuXHRcdFx0XHRcdGlmICggdGhpcy5vcmlnaW5hbEV2ZW50ICkge1xuXHRcdFx0XHRcdFx0XHRyZXR1cm4gdGhpcy5vcmlnaW5hbEV2ZW50WyBuYW1lIF07XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9LFxuXG5cdFx0XHRzZXQ6IGZ1bmN0aW9uKCB2YWx1ZSApIHtcblx0XHRcdFx0T2JqZWN0LmRlZmluZVByb3BlcnR5KCB0aGlzLCBuYW1lLCB7XG5cdFx0XHRcdFx0ZW51bWVyYWJsZTogdHJ1ZSxcblx0XHRcdFx0XHRjb25maWd1cmFibGU6IHRydWUsXG5cdFx0XHRcdFx0d3JpdGFibGU6IHRydWUsXG5cdFx0XHRcdFx0dmFsdWU6IHZhbHVlXG5cdFx0XHRcdH0gKTtcblx0XHRcdH1cblx0XHR9ICk7XG5cdH0sXG5cblx0Zml4OiBmdW5jdGlvbiggb3JpZ2luYWxFdmVudCApIHtcblx0XHRyZXR1cm4gb3JpZ2luYWxFdmVudFsgalF1ZXJ5LmV4cGFuZG8gXSA/XG5cdFx0XHRvcmlnaW5hbEV2ZW50IDpcblx0XHRcdG5ldyBqUXVlcnkuRXZlbnQoIG9yaWdpbmFsRXZlbnQgKTtcblx0fSxcblxuXHRzcGVjaWFsOiB7XG5cdFx0bG9hZDoge1xuXG5cdFx0XHQvLyBQcmV2ZW50IHRyaWdnZXJlZCBpbWFnZS5sb2FkIGV2ZW50cyBmcm9tIGJ1YmJsaW5nIHRvIHdpbmRvdy5sb2FkXG5cdFx0XHRub0J1YmJsZTogdHJ1ZVxuXHRcdH0sXG5cdFx0Zm9jdXM6IHtcblxuXHRcdFx0Ly8gRmlyZSBuYXRpdmUgZXZlbnQgaWYgcG9zc2libGUgc28gYmx1ci9mb2N1cyBzZXF1ZW5jZSBpcyBjb3JyZWN0XG5cdFx0XHR0cmlnZ2VyOiBmdW5jdGlvbigpIHtcblx0XHRcdFx0aWYgKCB0aGlzICE9PSBzYWZlQWN0aXZlRWxlbWVudCgpICYmIHRoaXMuZm9jdXMgKSB7XG5cdFx0XHRcdFx0dGhpcy5mb2N1cygpO1xuXHRcdFx0XHRcdHJldHVybiBmYWxzZTtcblx0XHRcdFx0fVxuXHRcdFx0fSxcblx0XHRcdGRlbGVnYXRlVHlwZTogXCJmb2N1c2luXCJcblx0XHR9LFxuXHRcdGJsdXI6IHtcblx0XHRcdHRyaWdnZXI6IGZ1bmN0aW9uKCkge1xuXHRcdFx0XHRpZiAoIHRoaXMgPT09IHNhZmVBY3RpdmVFbGVtZW50KCkgJiYgdGhpcy5ibHVyICkge1xuXHRcdFx0XHRcdHRoaXMuYmx1cigpO1xuXHRcdFx0XHRcdHJldHVybiBmYWxzZTtcblx0XHRcdFx0fVxuXHRcdFx0fSxcblx0XHRcdGRlbGVnYXRlVHlwZTogXCJmb2N1c291dFwiXG5cdFx0fSxcblx0XHRjbGljazoge1xuXG5cdFx0XHQvLyBGb3IgY2hlY2tib3gsIGZpcmUgbmF0aXZlIGV2ZW50IHNvIGNoZWNrZWQgc3RhdGUgd2lsbCBiZSByaWdodFxuXHRcdFx0dHJpZ2dlcjogZnVuY3Rpb24oKSB7XG5cdFx0XHRcdGlmICggdGhpcy50eXBlID09PSBcImNoZWNrYm94XCIgJiYgdGhpcy5jbGljayAmJiBub2RlTmFtZSggdGhpcywgXCJpbnB1dFwiICkgKSB7XG5cdFx0XHRcdFx0dGhpcy5jbGljaygpO1xuXHRcdFx0XHRcdHJldHVybiBmYWxzZTtcblx0XHRcdFx0fVxuXHRcdFx0fSxcblxuXHRcdFx0Ly8gRm9yIGNyb3NzLWJyb3dzZXIgY29uc2lzdGVuY3ksIGRvbid0IGZpcmUgbmF0aXZlIC5jbGljaygpIG9uIGxpbmtzXG5cdFx0XHRfZGVmYXVsdDogZnVuY3Rpb24oIGV2ZW50ICkge1xuXHRcdFx0XHRyZXR1cm4gbm9kZU5hbWUoIGV2ZW50LnRhcmdldCwgXCJhXCIgKTtcblx0XHRcdH1cblx0XHR9LFxuXG5cdFx0YmVmb3JldW5sb2FkOiB7XG5cdFx0XHRwb3N0RGlzcGF0Y2g6IGZ1bmN0aW9uKCBldmVudCApIHtcblxuXHRcdFx0XHQvLyBTdXBwb3J0OiBGaXJlZm94IDIwK1xuXHRcdFx0XHQvLyBGaXJlZm94IGRvZXNuJ3QgYWxlcnQgaWYgdGhlIHJldHVyblZhbHVlIGZpZWxkIGlzIG5vdCBzZXQuXG5cdFx0XHRcdGlmICggZXZlbnQucmVzdWx0ICE9PSB1bmRlZmluZWQgJiYgZXZlbnQub3JpZ2luYWxFdmVudCApIHtcblx0XHRcdFx0XHRldmVudC5vcmlnaW5hbEV2ZW50LnJldHVyblZhbHVlID0gZXZlbnQucmVzdWx0O1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fVxuXHR9XG59O1xuXG5qUXVlcnkucmVtb3ZlRXZlbnQgPSBmdW5jdGlvbiggZWxlbSwgdHlwZSwgaGFuZGxlICkge1xuXG5cdC8vIFRoaXMgXCJpZlwiIGlzIG5lZWRlZCBmb3IgcGxhaW4gb2JqZWN0c1xuXHRpZiAoIGVsZW0ucmVtb3ZlRXZlbnRMaXN0ZW5lciApIHtcblx0XHRlbGVtLnJlbW92ZUV2ZW50TGlzdGVuZXIoIHR5cGUsIGhhbmRsZSApO1xuXHR9XG59O1xuXG5qUXVlcnkuRXZlbnQgPSBmdW5jdGlvbiggc3JjLCBwcm9wcyApIHtcblxuXHQvLyBBbGxvdyBpbnN0YW50aWF0aW9uIHdpdGhvdXQgdGhlICduZXcnIGtleXdvcmRcblx0aWYgKCAhKCB0aGlzIGluc3RhbmNlb2YgalF1ZXJ5LkV2ZW50ICkgKSB7XG5cdFx0cmV0dXJuIG5ldyBqUXVlcnkuRXZlbnQoIHNyYywgcHJvcHMgKTtcblx0fVxuXG5cdC8vIEV2ZW50IG9iamVjdFxuXHRpZiAoIHNyYyAmJiBzcmMudHlwZSApIHtcblx0XHR0aGlzLm9yaWdpbmFsRXZlbnQgPSBzcmM7XG5cdFx0dGhpcy50eXBlID0gc3JjLnR5cGU7XG5cblx0XHQvLyBFdmVudHMgYnViYmxpbmcgdXAgdGhlIGRvY3VtZW50IG1heSBoYXZlIGJlZW4gbWFya2VkIGFzIHByZXZlbnRlZFxuXHRcdC8vIGJ5IGEgaGFuZGxlciBsb3dlciBkb3duIHRoZSB0cmVlOyByZWZsZWN0IHRoZSBjb3JyZWN0IHZhbHVlLlxuXHRcdHRoaXMuaXNEZWZhdWx0UHJldmVudGVkID0gc3JjLmRlZmF1bHRQcmV2ZW50ZWQgfHxcblx0XHRcdFx0c3JjLmRlZmF1bHRQcmV2ZW50ZWQgPT09IHVuZGVmaW5lZCAmJlxuXG5cdFx0XHRcdC8vIFN1cHBvcnQ6IEFuZHJvaWQgPD0yLjMgb25seVxuXHRcdFx0XHRzcmMucmV0dXJuVmFsdWUgPT09IGZhbHNlID9cblx0XHRcdHJldHVyblRydWUgOlxuXHRcdFx0cmV0dXJuRmFsc2U7XG5cblx0XHQvLyBDcmVhdGUgdGFyZ2V0IHByb3BlcnRpZXNcblx0XHQvLyBTdXBwb3J0OiBTYWZhcmkgPD02IC0gNyBvbmx5XG5cdFx0Ly8gVGFyZ2V0IHNob3VsZCBub3QgYmUgYSB0ZXh0IG5vZGUgKCM1MDQsICMxMzE0Mylcblx0XHR0aGlzLnRhcmdldCA9ICggc3JjLnRhcmdldCAmJiBzcmMudGFyZ2V0Lm5vZGVUeXBlID09PSAzICkgP1xuXHRcdFx0c3JjLnRhcmdldC5wYXJlbnROb2RlIDpcblx0XHRcdHNyYy50YXJnZXQ7XG5cblx0XHR0aGlzLmN1cnJlbnRUYXJnZXQgPSBzcmMuY3VycmVudFRhcmdldDtcblx0XHR0aGlzLnJlbGF0ZWRUYXJnZXQgPSBzcmMucmVsYXRlZFRhcmdldDtcblxuXHQvLyBFdmVudCB0eXBlXG5cdH0gZWxzZSB7XG5cdFx0dGhpcy50eXBlID0gc3JjO1xuXHR9XG5cblx0Ly8gUHV0IGV4cGxpY2l0bHkgcHJvdmlkZWQgcHJvcGVydGllcyBvbnRvIHRoZSBldmVudCBvYmplY3Rcblx0aWYgKCBwcm9wcyApIHtcblx0XHRqUXVlcnkuZXh0ZW5kKCB0aGlzLCBwcm9wcyApO1xuXHR9XG5cblx0Ly8gQ3JlYXRlIGEgdGltZXN0YW1wIGlmIGluY29taW5nIGV2ZW50IGRvZXNuJ3QgaGF2ZSBvbmVcblx0dGhpcy50aW1lU3RhbXAgPSBzcmMgJiYgc3JjLnRpbWVTdGFtcCB8fCBqUXVlcnkubm93KCk7XG5cblx0Ly8gTWFyayBpdCBhcyBmaXhlZFxuXHR0aGlzWyBqUXVlcnkuZXhwYW5kbyBdID0gdHJ1ZTtcbn07XG5cbi8vIGpRdWVyeS5FdmVudCBpcyBiYXNlZCBvbiBET00zIEV2ZW50cyBhcyBzcGVjaWZpZWQgYnkgdGhlIEVDTUFTY3JpcHQgTGFuZ3VhZ2UgQmluZGluZ1xuLy8gaHR0cHM6Ly93d3cudzMub3JnL1RSLzIwMDMvV0QtRE9NLUxldmVsLTMtRXZlbnRzLTIwMDMwMzMxL2VjbWEtc2NyaXB0LWJpbmRpbmcuaHRtbFxualF1ZXJ5LkV2ZW50LnByb3RvdHlwZSA9IHtcblx0Y29uc3RydWN0b3I6IGpRdWVyeS5FdmVudCxcblx0aXNEZWZhdWx0UHJldmVudGVkOiByZXR1cm5GYWxzZSxcblx0aXNQcm9wYWdhdGlvblN0b3BwZWQ6IHJldHVybkZhbHNlLFxuXHRpc0ltbWVkaWF0ZVByb3BhZ2F0aW9uU3RvcHBlZDogcmV0dXJuRmFsc2UsXG5cdGlzU2ltdWxhdGVkOiBmYWxzZSxcblxuXHRwcmV2ZW50RGVmYXVsdDogZnVuY3Rpb24oKSB7XG5cdFx0dmFyIGUgPSB0aGlzLm9yaWdpbmFsRXZlbnQ7XG5cblx0XHR0aGlzLmlzRGVmYXVsdFByZXZlbnRlZCA9IHJldHVyblRydWU7XG5cblx0XHRpZiAoIGUgJiYgIXRoaXMuaXNTaW11bGF0ZWQgKSB7XG5cdFx0XHRlLnByZXZlbnREZWZhdWx0KCk7XG5cdFx0fVxuXHR9LFxuXHRzdG9wUHJvcGFnYXRpb246IGZ1bmN0aW9uKCkge1xuXHRcdHZhciBlID0gdGhpcy5vcmlnaW5hbEV2ZW50O1xuXG5cdFx0dGhpcy5pc1Byb3BhZ2F0aW9uU3RvcHBlZCA9IHJldHVyblRydWU7XG5cblx0XHRpZiAoIGUgJiYgIXRoaXMuaXNTaW11bGF0ZWQgKSB7XG5cdFx0XHRlLnN0b3BQcm9wYWdhdGlvbigpO1xuXHRcdH1cblx0fSxcblx0c3RvcEltbWVkaWF0ZVByb3BhZ2F0aW9uOiBmdW5jdGlvbigpIHtcblx0XHR2YXIgZSA9IHRoaXMub3JpZ2luYWxFdmVudDtcblxuXHRcdHRoaXMuaXNJbW1lZGlhdGVQcm9wYWdhdGlvblN0b3BwZWQgPSByZXR1cm5UcnVlO1xuXG5cdFx0aWYgKCBlICYmICF0aGlzLmlzU2ltdWxhdGVkICkge1xuXHRcdFx0ZS5zdG9wSW1tZWRpYXRlUHJvcGFnYXRpb24oKTtcblx0XHR9XG5cblx0XHR0aGlzLnN0b3BQcm9wYWdhdGlvbigpO1xuXHR9XG59O1xuXG4vLyBJbmNsdWRlcyBhbGwgY29tbW9uIGV2ZW50IHByb3BzIGluY2x1ZGluZyBLZXlFdmVudCBhbmQgTW91c2VFdmVudCBzcGVjaWZpYyBwcm9wc1xualF1ZXJ5LmVhY2goIHtcblx0YWx0S2V5OiB0cnVlLFxuXHRidWJibGVzOiB0cnVlLFxuXHRjYW5jZWxhYmxlOiB0cnVlLFxuXHRjaGFuZ2VkVG91Y2hlczogdHJ1ZSxcblx0Y3RybEtleTogdHJ1ZSxcblx0ZGV0YWlsOiB0cnVlLFxuXHRldmVudFBoYXNlOiB0cnVlLFxuXHRtZXRhS2V5OiB0cnVlLFxuXHRwYWdlWDogdHJ1ZSxcblx0cGFnZVk6IHRydWUsXG5cdHNoaWZ0S2V5OiB0cnVlLFxuXHR2aWV3OiB0cnVlLFxuXHRcImNoYXJcIjogdHJ1ZSxcblx0Y2hhckNvZGU6IHRydWUsXG5cdGtleTogdHJ1ZSxcblx0a2V5Q29kZTogdHJ1ZSxcblx0YnV0dG9uOiB0cnVlLFxuXHRidXR0b25zOiB0cnVlLFxuXHRjbGllbnRYOiB0cnVlLFxuXHRjbGllbnRZOiB0cnVlLFxuXHRvZmZzZXRYOiB0cnVlLFxuXHRvZmZzZXRZOiB0cnVlLFxuXHRwb2ludGVySWQ6IHRydWUsXG5cdHBvaW50ZXJUeXBlOiB0cnVlLFxuXHRzY3JlZW5YOiB0cnVlLFxuXHRzY3JlZW5ZOiB0cnVlLFxuXHR0YXJnZXRUb3VjaGVzOiB0cnVlLFxuXHR0b0VsZW1lbnQ6IHRydWUsXG5cdHRvdWNoZXM6IHRydWUsXG5cblx0d2hpY2g6IGZ1bmN0aW9uKCBldmVudCApIHtcblx0XHR2YXIgYnV0dG9uID0gZXZlbnQuYnV0dG9uO1xuXG5cdFx0Ly8gQWRkIHdoaWNoIGZvciBrZXkgZXZlbnRzXG5cdFx0aWYgKCBldmVudC53aGljaCA9PSBudWxsICYmIHJrZXlFdmVudC50ZXN0KCBldmVudC50eXBlICkgKSB7XG5cdFx0XHRyZXR1cm4gZXZlbnQuY2hhckNvZGUgIT0gbnVsbCA/IGV2ZW50LmNoYXJDb2RlIDogZXZlbnQua2V5Q29kZTtcblx0XHR9XG5cblx0XHQvLyBBZGQgd2hpY2ggZm9yIGNsaWNrOiAxID09PSBsZWZ0OyAyID09PSBtaWRkbGU7IDMgPT09IHJpZ2h0XG5cdFx0aWYgKCAhZXZlbnQud2hpY2ggJiYgYnV0dG9uICE9PSB1bmRlZmluZWQgJiYgcm1vdXNlRXZlbnQudGVzdCggZXZlbnQudHlwZSApICkge1xuXHRcdFx0aWYgKCBidXR0b24gJiAxICkge1xuXHRcdFx0XHRyZXR1cm4gMTtcblx0XHRcdH1cblxuXHRcdFx0aWYgKCBidXR0b24gJiAyICkge1xuXHRcdFx0XHRyZXR1cm4gMztcblx0XHRcdH1cblxuXHRcdFx0aWYgKCBidXR0b24gJiA0ICkge1xuXHRcdFx0XHRyZXR1cm4gMjtcblx0XHRcdH1cblxuXHRcdFx0cmV0dXJuIDA7XG5cdFx0fVxuXG5cdFx0cmV0dXJuIGV2ZW50LndoaWNoO1xuXHR9XG59LCBqUXVlcnkuZXZlbnQuYWRkUHJvcCApO1xuXG4vLyBDcmVhdGUgbW91c2VlbnRlci9sZWF2ZSBldmVudHMgdXNpbmcgbW91c2VvdmVyL291dCBhbmQgZXZlbnQtdGltZSBjaGVja3Ncbi8vIHNvIHRoYXQgZXZlbnQgZGVsZWdhdGlvbiB3b3JrcyBpbiBqUXVlcnkuXG4vLyBEbyB0aGUgc2FtZSBmb3IgcG9pbnRlcmVudGVyL3BvaW50ZXJsZWF2ZSBhbmQgcG9pbnRlcm92ZXIvcG9pbnRlcm91dFxuLy9cbi8vIFN1cHBvcnQ6IFNhZmFyaSA3IG9ubHlcbi8vIFNhZmFyaSBzZW5kcyBtb3VzZWVudGVyIHRvbyBvZnRlbjsgc2VlOlxuLy8gaHR0cHM6Ly9idWdzLmNocm9taXVtLm9yZy9wL2Nocm9taXVtL2lzc3Vlcy9kZXRhaWw/aWQ9NDcwMjU4XG4vLyBmb3IgdGhlIGRlc2NyaXB0aW9uIG9mIHRoZSBidWcgKGl0IGV4aXN0ZWQgaW4gb2xkZXIgQ2hyb21lIHZlcnNpb25zIGFzIHdlbGwpLlxualF1ZXJ5LmVhY2goIHtcblx0bW91c2VlbnRlcjogXCJtb3VzZW92ZXJcIixcblx0bW91c2VsZWF2ZTogXCJtb3VzZW91dFwiLFxuXHRwb2ludGVyZW50ZXI6IFwicG9pbnRlcm92ZXJcIixcblx0cG9pbnRlcmxlYXZlOiBcInBvaW50ZXJvdXRcIlxufSwgZnVuY3Rpb24oIG9yaWcsIGZpeCApIHtcblx0alF1ZXJ5LmV2ZW50LnNwZWNpYWxbIG9yaWcgXSA9IHtcblx0XHRkZWxlZ2F0ZVR5cGU6IGZpeCxcblx0XHRiaW5kVHlwZTogZml4LFxuXG5cdFx0aGFuZGxlOiBmdW5jdGlvbiggZXZlbnQgKSB7XG5cdFx0XHR2YXIgcmV0LFxuXHRcdFx0XHR0YXJnZXQgPSB0aGlzLFxuXHRcdFx0XHRyZWxhdGVkID0gZXZlbnQucmVsYXRlZFRhcmdldCxcblx0XHRcdFx0aGFuZGxlT2JqID0gZXZlbnQuaGFuZGxlT2JqO1xuXG5cdFx0XHQvLyBGb3IgbW91c2VlbnRlci9sZWF2ZSBjYWxsIHRoZSBoYW5kbGVyIGlmIHJlbGF0ZWQgaXMgb3V0c2lkZSB0aGUgdGFyZ2V0LlxuXHRcdFx0Ly8gTkI6IE5vIHJlbGF0ZWRUYXJnZXQgaWYgdGhlIG1vdXNlIGxlZnQvZW50ZXJlZCB0aGUgYnJvd3NlciB3aW5kb3dcblx0XHRcdGlmICggIXJlbGF0ZWQgfHwgKCByZWxhdGVkICE9PSB0YXJnZXQgJiYgIWpRdWVyeS5jb250YWlucyggdGFyZ2V0LCByZWxhdGVkICkgKSApIHtcblx0XHRcdFx0ZXZlbnQudHlwZSA9IGhhbmRsZU9iai5vcmlnVHlwZTtcblx0XHRcdFx0cmV0ID0gaGFuZGxlT2JqLmhhbmRsZXIuYXBwbHkoIHRoaXMsIGFyZ3VtZW50cyApO1xuXHRcdFx0XHRldmVudC50eXBlID0gZml4O1xuXHRcdFx0fVxuXHRcdFx0cmV0dXJuIHJldDtcblx0XHR9XG5cdH07XG59ICk7XG5cbmpRdWVyeS5mbi5leHRlbmQoIHtcblxuXHRvbjogZnVuY3Rpb24oIHR5cGVzLCBzZWxlY3RvciwgZGF0YSwgZm4gKSB7XG5cdFx0cmV0dXJuIG9uKCB0aGlzLCB0eXBlcywgc2VsZWN0b3IsIGRhdGEsIGZuICk7XG5cdH0sXG5cdG9uZTogZnVuY3Rpb24oIHR5cGVzLCBzZWxlY3RvciwgZGF0YSwgZm4gKSB7XG5cdFx0cmV0dXJuIG9uKCB0aGlzLCB0eXBlcywgc2VsZWN0b3IsIGRhdGEsIGZuLCAxICk7XG5cdH0sXG5cdG9mZjogZnVuY3Rpb24oIHR5cGVzLCBzZWxlY3RvciwgZm4gKSB7XG5cdFx0dmFyIGhhbmRsZU9iaiwgdHlwZTtcblx0XHRpZiAoIHR5cGVzICYmIHR5cGVzLnByZXZlbnREZWZhdWx0ICYmIHR5cGVzLmhhbmRsZU9iaiApIHtcblxuXHRcdFx0Ly8gKCBldmVudCApICBkaXNwYXRjaGVkIGpRdWVyeS5FdmVudFxuXHRcdFx0aGFuZGxlT2JqID0gdHlwZXMuaGFuZGxlT2JqO1xuXHRcdFx0alF1ZXJ5KCB0eXBlcy5kZWxlZ2F0ZVRhcmdldCApLm9mZihcblx0XHRcdFx0aGFuZGxlT2JqLm5hbWVzcGFjZSA/XG5cdFx0XHRcdFx0aGFuZGxlT2JqLm9yaWdUeXBlICsgXCIuXCIgKyBoYW5kbGVPYmoubmFtZXNwYWNlIDpcblx0XHRcdFx0XHRoYW5kbGVPYmoub3JpZ1R5cGUsXG5cdFx0XHRcdGhhbmRsZU9iai5zZWxlY3Rvcixcblx0XHRcdFx0aGFuZGxlT2JqLmhhbmRsZXJcblx0XHRcdCk7XG5cdFx0XHRyZXR1cm4gdGhpcztcblx0XHR9XG5cdFx0aWYgKCB0eXBlb2YgdHlwZXMgPT09IFwib2JqZWN0XCIgKSB7XG5cblx0XHRcdC8vICggdHlwZXMtb2JqZWN0IFssIHNlbGVjdG9yXSApXG5cdFx0XHRmb3IgKCB0eXBlIGluIHR5cGVzICkge1xuXHRcdFx0XHR0aGlzLm9mZiggdHlwZSwgc2VsZWN0b3IsIHR5cGVzWyB0eXBlIF0gKTtcblx0XHRcdH1cblx0XHRcdHJldHVybiB0aGlzO1xuXHRcdH1cblx0XHRpZiAoIHNlbGVjdG9yID09PSBmYWxzZSB8fCB0eXBlb2Ygc2VsZWN0b3IgPT09IFwiZnVuY3Rpb25cIiApIHtcblxuXHRcdFx0Ly8gKCB0eXBlcyBbLCBmbl0gKVxuXHRcdFx0Zm4gPSBzZWxlY3Rvcjtcblx0XHRcdHNlbGVjdG9yID0gdW5kZWZpbmVkO1xuXHRcdH1cblx0XHRpZiAoIGZuID09PSBmYWxzZSApIHtcblx0XHRcdGZuID0gcmV0dXJuRmFsc2U7XG5cdFx0fVxuXHRcdHJldHVybiB0aGlzLmVhY2goIGZ1bmN0aW9uKCkge1xuXHRcdFx0alF1ZXJ5LmV2ZW50LnJlbW92ZSggdGhpcywgdHlwZXMsIGZuLCBzZWxlY3RvciApO1xuXHRcdH0gKTtcblx0fVxufSApO1xuXG5cbnZhclxuXG5cdC8qIGVzbGludC1kaXNhYmxlIG1heC1sZW4gKi9cblxuXHQvLyBTZWUgaHR0cHM6Ly9naXRodWIuY29tL2VzbGludC9lc2xpbnQvaXNzdWVzLzMyMjlcblx0cnhodG1sVGFnID0gLzwoPyFhcmVhfGJyfGNvbHxlbWJlZHxocnxpbWd8aW5wdXR8bGlua3xtZXRhfHBhcmFtKSgoW2Etel1bXlxcL1xcMD5cXHgyMFxcdFxcclxcblxcZl0qKVtePl0qKVxcLz4vZ2ksXG5cblx0LyogZXNsaW50LWVuYWJsZSAqL1xuXG5cdC8vIFN1cHBvcnQ6IElFIDw9MTAgLSAxMSwgRWRnZSAxMiAtIDEzXG5cdC8vIEluIElFL0VkZ2UgdXNpbmcgcmVnZXggZ3JvdXBzIGhlcmUgY2F1c2VzIHNldmVyZSBzbG93ZG93bnMuXG5cdC8vIFNlZSBodHRwczovL2Nvbm5lY3QubWljcm9zb2Z0LmNvbS9JRS9mZWVkYmFjay9kZXRhaWxzLzE3MzY1MTIvXG5cdHJub0lubmVyaHRtbCA9IC88c2NyaXB0fDxzdHlsZXw8bGluay9pLFxuXG5cdC8vIGNoZWNrZWQ9XCJjaGVja2VkXCIgb3IgY2hlY2tlZFxuXHRyY2hlY2tlZCA9IC9jaGVja2VkXFxzKig/OltePV18PVxccyouY2hlY2tlZC4pL2ksXG5cdHJzY3JpcHRUeXBlTWFza2VkID0gL150cnVlXFwvKC4qKS8sXG5cdHJjbGVhblNjcmlwdCA9IC9eXFxzKjwhKD86XFxbQ0RBVEFcXFt8LS0pfCg/OlxcXVxcXXwtLSk+XFxzKiQvZztcblxuLy8gUHJlZmVyIGEgdGJvZHkgb3ZlciBpdHMgcGFyZW50IHRhYmxlIGZvciBjb250YWluaW5nIG5ldyByb3dzXG5mdW5jdGlvbiBtYW5pcHVsYXRpb25UYXJnZXQoIGVsZW0sIGNvbnRlbnQgKSB7XG5cdGlmICggbm9kZU5hbWUoIGVsZW0sIFwidGFibGVcIiApICYmXG5cdFx0bm9kZU5hbWUoIGNvbnRlbnQubm9kZVR5cGUgIT09IDExID8gY29udGVudCA6IGNvbnRlbnQuZmlyc3RDaGlsZCwgXCJ0clwiICkgKSB7XG5cblx0XHRyZXR1cm4galF1ZXJ5KCBcIj50Ym9keVwiLCBlbGVtIClbIDAgXSB8fCBlbGVtO1xuXHR9XG5cblx0cmV0dXJuIGVsZW07XG59XG5cbi8vIFJlcGxhY2UvcmVzdG9yZSB0aGUgdHlwZSBhdHRyaWJ1dGUgb2Ygc2NyaXB0IGVsZW1lbnRzIGZvciBzYWZlIERPTSBtYW5pcHVsYXRpb25cbmZ1bmN0aW9uIGRpc2FibGVTY3JpcHQoIGVsZW0gKSB7XG5cdGVsZW0udHlwZSA9ICggZWxlbS5nZXRBdHRyaWJ1dGUoIFwidHlwZVwiICkgIT09IG51bGwgKSArIFwiL1wiICsgZWxlbS50eXBlO1xuXHRyZXR1cm4gZWxlbTtcbn1cbmZ1bmN0aW9uIHJlc3RvcmVTY3JpcHQoIGVsZW0gKSB7XG5cdHZhciBtYXRjaCA9IHJzY3JpcHRUeXBlTWFza2VkLmV4ZWMoIGVsZW0udHlwZSApO1xuXG5cdGlmICggbWF0Y2ggKSB7XG5cdFx0ZWxlbS50eXBlID0gbWF0Y2hbIDEgXTtcblx0fSBlbHNlIHtcblx0XHRlbGVtLnJlbW92ZUF0dHJpYnV0ZSggXCJ0eXBlXCIgKTtcblx0fVxuXG5cdHJldHVybiBlbGVtO1xufVxuXG5mdW5jdGlvbiBjbG9uZUNvcHlFdmVudCggc3JjLCBkZXN0ICkge1xuXHR2YXIgaSwgbCwgdHlwZSwgcGRhdGFPbGQsIHBkYXRhQ3VyLCB1ZGF0YU9sZCwgdWRhdGFDdXIsIGV2ZW50cztcblxuXHRpZiAoIGRlc3Qubm9kZVR5cGUgIT09IDEgKSB7XG5cdFx0cmV0dXJuO1xuXHR9XG5cblx0Ly8gMS4gQ29weSBwcml2YXRlIGRhdGE6IGV2ZW50cywgaGFuZGxlcnMsIGV0Yy5cblx0aWYgKCBkYXRhUHJpdi5oYXNEYXRhKCBzcmMgKSApIHtcblx0XHRwZGF0YU9sZCA9IGRhdGFQcml2LmFjY2Vzcyggc3JjICk7XG5cdFx0cGRhdGFDdXIgPSBkYXRhUHJpdi5zZXQoIGRlc3QsIHBkYXRhT2xkICk7XG5cdFx0ZXZlbnRzID0gcGRhdGFPbGQuZXZlbnRzO1xuXG5cdFx0aWYgKCBldmVudHMgKSB7XG5cdFx0XHRkZWxldGUgcGRhdGFDdXIuaGFuZGxlO1xuXHRcdFx0cGRhdGFDdXIuZXZlbnRzID0ge307XG5cblx0XHRcdGZvciAoIHR5cGUgaW4gZXZlbnRzICkge1xuXHRcdFx0XHRmb3IgKCBpID0gMCwgbCA9IGV2ZW50c1sgdHlwZSBdLmxlbmd0aDsgaSA8IGw7IGkrKyApIHtcblx0XHRcdFx0XHRqUXVlcnkuZXZlbnQuYWRkKCBkZXN0LCB0eXBlLCBldmVudHNbIHR5cGUgXVsgaSBdICk7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9XG5cdH1cblxuXHQvLyAyLiBDb3B5IHVzZXIgZGF0YVxuXHRpZiAoIGRhdGFVc2VyLmhhc0RhdGEoIHNyYyApICkge1xuXHRcdHVkYXRhT2xkID0gZGF0YVVzZXIuYWNjZXNzKCBzcmMgKTtcblx0XHR1ZGF0YUN1ciA9IGpRdWVyeS5leHRlbmQoIHt9LCB1ZGF0YU9sZCApO1xuXG5cdFx0ZGF0YVVzZXIuc2V0KCBkZXN0LCB1ZGF0YUN1ciApO1xuXHR9XG59XG5cbi8vIEZpeCBJRSBidWdzLCBzZWUgc3VwcG9ydCB0ZXN0c1xuZnVuY3Rpb24gZml4SW5wdXQoIHNyYywgZGVzdCApIHtcblx0dmFyIG5vZGVOYW1lID0gZGVzdC5ub2RlTmFtZS50b0xvd2VyQ2FzZSgpO1xuXG5cdC8vIEZhaWxzIHRvIHBlcnNpc3QgdGhlIGNoZWNrZWQgc3RhdGUgb2YgYSBjbG9uZWQgY2hlY2tib3ggb3IgcmFkaW8gYnV0dG9uLlxuXHRpZiAoIG5vZGVOYW1lID09PSBcImlucHV0XCIgJiYgcmNoZWNrYWJsZVR5cGUudGVzdCggc3JjLnR5cGUgKSApIHtcblx0XHRkZXN0LmNoZWNrZWQgPSBzcmMuY2hlY2tlZDtcblxuXHQvLyBGYWlscyB0byByZXR1cm4gdGhlIHNlbGVjdGVkIG9wdGlvbiB0byB0aGUgZGVmYXVsdCBzZWxlY3RlZCBzdGF0ZSB3aGVuIGNsb25pbmcgb3B0aW9uc1xuXHR9IGVsc2UgaWYgKCBub2RlTmFtZSA9PT0gXCJpbnB1dFwiIHx8IG5vZGVOYW1lID09PSBcInRleHRhcmVhXCIgKSB7XG5cdFx0ZGVzdC5kZWZhdWx0VmFsdWUgPSBzcmMuZGVmYXVsdFZhbHVlO1xuXHR9XG59XG5cbmZ1bmN0aW9uIGRvbU1hbmlwKCBjb2xsZWN0aW9uLCBhcmdzLCBjYWxsYmFjaywgaWdub3JlZCApIHtcblxuXHQvLyBGbGF0dGVuIGFueSBuZXN0ZWQgYXJyYXlzXG5cdGFyZ3MgPSBjb25jYXQuYXBwbHkoIFtdLCBhcmdzICk7XG5cblx0dmFyIGZyYWdtZW50LCBmaXJzdCwgc2NyaXB0cywgaGFzU2NyaXB0cywgbm9kZSwgZG9jLFxuXHRcdGkgPSAwLFxuXHRcdGwgPSBjb2xsZWN0aW9uLmxlbmd0aCxcblx0XHRpTm9DbG9uZSA9IGwgLSAxLFxuXHRcdHZhbHVlID0gYXJnc1sgMCBdLFxuXHRcdGlzRnVuY3Rpb24gPSBqUXVlcnkuaXNGdW5jdGlvbiggdmFsdWUgKTtcblxuXHQvLyBXZSBjYW4ndCBjbG9uZU5vZGUgZnJhZ21lbnRzIHRoYXQgY29udGFpbiBjaGVja2VkLCBpbiBXZWJLaXRcblx0aWYgKCBpc0Z1bmN0aW9uIHx8XG5cdFx0XHQoIGwgPiAxICYmIHR5cGVvZiB2YWx1ZSA9PT0gXCJzdHJpbmdcIiAmJlxuXHRcdFx0XHQhc3VwcG9ydC5jaGVja0Nsb25lICYmIHJjaGVja2VkLnRlc3QoIHZhbHVlICkgKSApIHtcblx0XHRyZXR1cm4gY29sbGVjdGlvbi5lYWNoKCBmdW5jdGlvbiggaW5kZXggKSB7XG5cdFx0XHR2YXIgc2VsZiA9IGNvbGxlY3Rpb24uZXEoIGluZGV4ICk7XG5cdFx0XHRpZiAoIGlzRnVuY3Rpb24gKSB7XG5cdFx0XHRcdGFyZ3NbIDAgXSA9IHZhbHVlLmNhbGwoIHRoaXMsIGluZGV4LCBzZWxmLmh0bWwoKSApO1xuXHRcdFx0fVxuXHRcdFx0ZG9tTWFuaXAoIHNlbGYsIGFyZ3MsIGNhbGxiYWNrLCBpZ25vcmVkICk7XG5cdFx0fSApO1xuXHR9XG5cblx0aWYgKCBsICkge1xuXHRcdGZyYWdtZW50ID0gYnVpbGRGcmFnbWVudCggYXJncywgY29sbGVjdGlvblsgMCBdLm93bmVyRG9jdW1lbnQsIGZhbHNlLCBjb2xsZWN0aW9uLCBpZ25vcmVkICk7XG5cdFx0Zmlyc3QgPSBmcmFnbWVudC5maXJzdENoaWxkO1xuXG5cdFx0aWYgKCBmcmFnbWVudC5jaGlsZE5vZGVzLmxlbmd0aCA9PT0gMSApIHtcblx0XHRcdGZyYWdtZW50ID0gZmlyc3Q7XG5cdFx0fVxuXG5cdFx0Ly8gUmVxdWlyZSBlaXRoZXIgbmV3IGNvbnRlbnQgb3IgYW4gaW50ZXJlc3QgaW4gaWdub3JlZCBlbGVtZW50cyB0byBpbnZva2UgdGhlIGNhbGxiYWNrXG5cdFx0aWYgKCBmaXJzdCB8fCBpZ25vcmVkICkge1xuXHRcdFx0c2NyaXB0cyA9IGpRdWVyeS5tYXAoIGdldEFsbCggZnJhZ21lbnQsIFwic2NyaXB0XCIgKSwgZGlzYWJsZVNjcmlwdCApO1xuXHRcdFx0aGFzU2NyaXB0cyA9IHNjcmlwdHMubGVuZ3RoO1xuXG5cdFx0XHQvLyBVc2UgdGhlIG9yaWdpbmFsIGZyYWdtZW50IGZvciB0aGUgbGFzdCBpdGVtXG5cdFx0XHQvLyBpbnN0ZWFkIG9mIHRoZSBmaXJzdCBiZWNhdXNlIGl0IGNhbiBlbmQgdXBcblx0XHRcdC8vIGJlaW5nIGVtcHRpZWQgaW5jb3JyZWN0bHkgaW4gY2VydGFpbiBzaXR1YXRpb25zICgjODA3MCkuXG5cdFx0XHRmb3IgKCA7IGkgPCBsOyBpKysgKSB7XG5cdFx0XHRcdG5vZGUgPSBmcmFnbWVudDtcblxuXHRcdFx0XHRpZiAoIGkgIT09IGlOb0Nsb25lICkge1xuXHRcdFx0XHRcdG5vZGUgPSBqUXVlcnkuY2xvbmUoIG5vZGUsIHRydWUsIHRydWUgKTtcblxuXHRcdFx0XHRcdC8vIEtlZXAgcmVmZXJlbmNlcyB0byBjbG9uZWQgc2NyaXB0cyBmb3IgbGF0ZXIgcmVzdG9yYXRpb25cblx0XHRcdFx0XHRpZiAoIGhhc1NjcmlwdHMgKSB7XG5cblx0XHRcdFx0XHRcdC8vIFN1cHBvcnQ6IEFuZHJvaWQgPD00LjAgb25seSwgUGhhbnRvbUpTIDEgb25seVxuXHRcdFx0XHRcdFx0Ly8gcHVzaC5hcHBseShfLCBhcnJheWxpa2UpIHRocm93cyBvbiBhbmNpZW50IFdlYktpdFxuXHRcdFx0XHRcdFx0alF1ZXJ5Lm1lcmdlKCBzY3JpcHRzLCBnZXRBbGwoIG5vZGUsIFwic2NyaXB0XCIgKSApO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXG5cdFx0XHRcdGNhbGxiYWNrLmNhbGwoIGNvbGxlY3Rpb25bIGkgXSwgbm9kZSwgaSApO1xuXHRcdFx0fVxuXG5cdFx0XHRpZiAoIGhhc1NjcmlwdHMgKSB7XG5cdFx0XHRcdGRvYyA9IHNjcmlwdHNbIHNjcmlwdHMubGVuZ3RoIC0gMSBdLm93bmVyRG9jdW1lbnQ7XG5cblx0XHRcdFx0Ly8gUmVlbmFibGUgc2NyaXB0c1xuXHRcdFx0XHRqUXVlcnkubWFwKCBzY3JpcHRzLCByZXN0b3JlU2NyaXB0ICk7XG5cblx0XHRcdFx0Ly8gRXZhbHVhdGUgZXhlY3V0YWJsZSBzY3JpcHRzIG9uIGZpcnN0IGRvY3VtZW50IGluc2VydGlvblxuXHRcdFx0XHRmb3IgKCBpID0gMDsgaSA8IGhhc1NjcmlwdHM7IGkrKyApIHtcblx0XHRcdFx0XHRub2RlID0gc2NyaXB0c1sgaSBdO1xuXHRcdFx0XHRcdGlmICggcnNjcmlwdFR5cGUudGVzdCggbm9kZS50eXBlIHx8IFwiXCIgKSAmJlxuXHRcdFx0XHRcdFx0IWRhdGFQcml2LmFjY2Vzcyggbm9kZSwgXCJnbG9iYWxFdmFsXCIgKSAmJlxuXHRcdFx0XHRcdFx0alF1ZXJ5LmNvbnRhaW5zKCBkb2MsIG5vZGUgKSApIHtcblxuXHRcdFx0XHRcdFx0aWYgKCBub2RlLnNyYyApIHtcblxuXHRcdFx0XHRcdFx0XHQvLyBPcHRpb25hbCBBSkFYIGRlcGVuZGVuY3ksIGJ1dCB3b24ndCBydW4gc2NyaXB0cyBpZiBub3QgcHJlc2VudFxuXHRcdFx0XHRcdFx0XHRpZiAoIGpRdWVyeS5fZXZhbFVybCApIHtcblx0XHRcdFx0XHRcdFx0XHRqUXVlcnkuX2V2YWxVcmwoIG5vZGUuc3JjICk7XG5cdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0XHRcdERPTUV2YWwoIG5vZGUudGV4dENvbnRlbnQucmVwbGFjZSggcmNsZWFuU2NyaXB0LCBcIlwiICksIGRvYyApO1xuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH1cblx0fVxuXG5cdHJldHVybiBjb2xsZWN0aW9uO1xufVxuXG5mdW5jdGlvbiByZW1vdmUoIGVsZW0sIHNlbGVjdG9yLCBrZWVwRGF0YSApIHtcblx0dmFyIG5vZGUsXG5cdFx0bm9kZXMgPSBzZWxlY3RvciA/IGpRdWVyeS5maWx0ZXIoIHNlbGVjdG9yLCBlbGVtICkgOiBlbGVtLFxuXHRcdGkgPSAwO1xuXG5cdGZvciAoIDsgKCBub2RlID0gbm9kZXNbIGkgXSApICE9IG51bGw7IGkrKyApIHtcblx0XHRpZiAoICFrZWVwRGF0YSAmJiBub2RlLm5vZGVUeXBlID09PSAxICkge1xuXHRcdFx0alF1ZXJ5LmNsZWFuRGF0YSggZ2V0QWxsKCBub2RlICkgKTtcblx0XHR9XG5cblx0XHRpZiAoIG5vZGUucGFyZW50Tm9kZSApIHtcblx0XHRcdGlmICgga2VlcERhdGEgJiYgalF1ZXJ5LmNvbnRhaW5zKCBub2RlLm93bmVyRG9jdW1lbnQsIG5vZGUgKSApIHtcblx0XHRcdFx0c2V0R2xvYmFsRXZhbCggZ2V0QWxsKCBub2RlLCBcInNjcmlwdFwiICkgKTtcblx0XHRcdH1cblx0XHRcdG5vZGUucGFyZW50Tm9kZS5yZW1vdmVDaGlsZCggbm9kZSApO1xuXHRcdH1cblx0fVxuXG5cdHJldHVybiBlbGVtO1xufVxuXG5qUXVlcnkuZXh0ZW5kKCB7XG5cdGh0bWxQcmVmaWx0ZXI6IGZ1bmN0aW9uKCBodG1sICkge1xuXHRcdHJldHVybiBodG1sLnJlcGxhY2UoIHJ4aHRtbFRhZywgXCI8JDE+PC8kMj5cIiApO1xuXHR9LFxuXG5cdGNsb25lOiBmdW5jdGlvbiggZWxlbSwgZGF0YUFuZEV2ZW50cywgZGVlcERhdGFBbmRFdmVudHMgKSB7XG5cdFx0dmFyIGksIGwsIHNyY0VsZW1lbnRzLCBkZXN0RWxlbWVudHMsXG5cdFx0XHRjbG9uZSA9IGVsZW0uY2xvbmVOb2RlKCB0cnVlICksXG5cdFx0XHRpblBhZ2UgPSBqUXVlcnkuY29udGFpbnMoIGVsZW0ub3duZXJEb2N1bWVudCwgZWxlbSApO1xuXG5cdFx0Ly8gRml4IElFIGNsb25pbmcgaXNzdWVzXG5cdFx0aWYgKCAhc3VwcG9ydC5ub0Nsb25lQ2hlY2tlZCAmJiAoIGVsZW0ubm9kZVR5cGUgPT09IDEgfHwgZWxlbS5ub2RlVHlwZSA9PT0gMTEgKSAmJlxuXHRcdFx0XHQhalF1ZXJ5LmlzWE1MRG9jKCBlbGVtICkgKSB7XG5cblx0XHRcdC8vIFdlIGVzY2hldyBTaXp6bGUgaGVyZSBmb3IgcGVyZm9ybWFuY2UgcmVhc29uczogaHR0cHM6Ly9qc3BlcmYuY29tL2dldGFsbC12cy1zaXp6bGUvMlxuXHRcdFx0ZGVzdEVsZW1lbnRzID0gZ2V0QWxsKCBjbG9uZSApO1xuXHRcdFx0c3JjRWxlbWVudHMgPSBnZXRBbGwoIGVsZW0gKTtcblxuXHRcdFx0Zm9yICggaSA9IDAsIGwgPSBzcmNFbGVtZW50cy5sZW5ndGg7IGkgPCBsOyBpKysgKSB7XG5cdFx0XHRcdGZpeElucHV0KCBzcmNFbGVtZW50c1sgaSBdLCBkZXN0RWxlbWVudHNbIGkgXSApO1xuXHRcdFx0fVxuXHRcdH1cblxuXHRcdC8vIENvcHkgdGhlIGV2ZW50cyBmcm9tIHRoZSBvcmlnaW5hbCB0byB0aGUgY2xvbmVcblx0XHRpZiAoIGRhdGFBbmRFdmVudHMgKSB7XG5cdFx0XHRpZiAoIGRlZXBEYXRhQW5kRXZlbnRzICkge1xuXHRcdFx0XHRzcmNFbGVtZW50cyA9IHNyY0VsZW1lbnRzIHx8IGdldEFsbCggZWxlbSApO1xuXHRcdFx0XHRkZXN0RWxlbWVudHMgPSBkZXN0RWxlbWVudHMgfHwgZ2V0QWxsKCBjbG9uZSApO1xuXG5cdFx0XHRcdGZvciAoIGkgPSAwLCBsID0gc3JjRWxlbWVudHMubGVuZ3RoOyBpIDwgbDsgaSsrICkge1xuXHRcdFx0XHRcdGNsb25lQ29weUV2ZW50KCBzcmNFbGVtZW50c1sgaSBdLCBkZXN0RWxlbWVudHNbIGkgXSApO1xuXHRcdFx0XHR9XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRjbG9uZUNvcHlFdmVudCggZWxlbSwgY2xvbmUgKTtcblx0XHRcdH1cblx0XHR9XG5cblx0XHQvLyBQcmVzZXJ2ZSBzY3JpcHQgZXZhbHVhdGlvbiBoaXN0b3J5XG5cdFx0ZGVzdEVsZW1lbnRzID0gZ2V0QWxsKCBjbG9uZSwgXCJzY3JpcHRcIiApO1xuXHRcdGlmICggZGVzdEVsZW1lbnRzLmxlbmd0aCA+IDAgKSB7XG5cdFx0XHRzZXRHbG9iYWxFdmFsKCBkZXN0RWxlbWVudHMsICFpblBhZ2UgJiYgZ2V0QWxsKCBlbGVtLCBcInNjcmlwdFwiICkgKTtcblx0XHR9XG5cblx0XHQvLyBSZXR1cm4gdGhlIGNsb25lZCBzZXRcblx0XHRyZXR1cm4gY2xvbmU7XG5cdH0sXG5cblx0Y2xlYW5EYXRhOiBmdW5jdGlvbiggZWxlbXMgKSB7XG5cdFx0dmFyIGRhdGEsIGVsZW0sIHR5cGUsXG5cdFx0XHRzcGVjaWFsID0galF1ZXJ5LmV2ZW50LnNwZWNpYWwsXG5cdFx0XHRpID0gMDtcblxuXHRcdGZvciAoIDsgKCBlbGVtID0gZWxlbXNbIGkgXSApICE9PSB1bmRlZmluZWQ7IGkrKyApIHtcblx0XHRcdGlmICggYWNjZXB0RGF0YSggZWxlbSApICkge1xuXHRcdFx0XHRpZiAoICggZGF0YSA9IGVsZW1bIGRhdGFQcml2LmV4cGFuZG8gXSApICkge1xuXHRcdFx0XHRcdGlmICggZGF0YS5ldmVudHMgKSB7XG5cdFx0XHRcdFx0XHRmb3IgKCB0eXBlIGluIGRhdGEuZXZlbnRzICkge1xuXHRcdFx0XHRcdFx0XHRpZiAoIHNwZWNpYWxbIHR5cGUgXSApIHtcblx0XHRcdFx0XHRcdFx0XHRqUXVlcnkuZXZlbnQucmVtb3ZlKCBlbGVtLCB0eXBlICk7XG5cblx0XHRcdFx0XHRcdFx0Ly8gVGhpcyBpcyBhIHNob3J0Y3V0IHRvIGF2b2lkIGpRdWVyeS5ldmVudC5yZW1vdmUncyBvdmVyaGVhZFxuXHRcdFx0XHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdFx0XHRcdGpRdWVyeS5yZW1vdmVFdmVudCggZWxlbSwgdHlwZSwgZGF0YS5oYW5kbGUgKTtcblx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdC8vIFN1cHBvcnQ6IENocm9tZSA8PTM1IC0gNDUrXG5cdFx0XHRcdFx0Ly8gQXNzaWduIHVuZGVmaW5lZCBpbnN0ZWFkIG9mIHVzaW5nIGRlbGV0ZSwgc2VlIERhdGEjcmVtb3ZlXG5cdFx0XHRcdFx0ZWxlbVsgZGF0YVByaXYuZXhwYW5kbyBdID0gdW5kZWZpbmVkO1xuXHRcdFx0XHR9XG5cdFx0XHRcdGlmICggZWxlbVsgZGF0YVVzZXIuZXhwYW5kbyBdICkge1xuXG5cdFx0XHRcdFx0Ly8gU3VwcG9ydDogQ2hyb21lIDw9MzUgLSA0NStcblx0XHRcdFx0XHQvLyBBc3NpZ24gdW5kZWZpbmVkIGluc3RlYWQgb2YgdXNpbmcgZGVsZXRlLCBzZWUgRGF0YSNyZW1vdmVcblx0XHRcdFx0XHRlbGVtWyBkYXRhVXNlci5leHBhbmRvIF0gPSB1bmRlZmluZWQ7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9XG5cdH1cbn0gKTtcblxualF1ZXJ5LmZuLmV4dGVuZCgge1xuXHRkZXRhY2g6IGZ1bmN0aW9uKCBzZWxlY3RvciApIHtcblx0XHRyZXR1cm4gcmVtb3ZlKCB0aGlzLCBzZWxlY3RvciwgdHJ1ZSApO1xuXHR9LFxuXG5cdHJlbW92ZTogZnVuY3Rpb24oIHNlbGVjdG9yICkge1xuXHRcdHJldHVybiByZW1vdmUoIHRoaXMsIHNlbGVjdG9yICk7XG5cdH0sXG5cblx0dGV4dDogZnVuY3Rpb24oIHZhbHVlICkge1xuXHRcdHJldHVybiBhY2Nlc3MoIHRoaXMsIGZ1bmN0aW9uKCB2YWx1ZSApIHtcblx0XHRcdHJldHVybiB2YWx1ZSA9PT0gdW5kZWZpbmVkID9cblx0XHRcdFx0alF1ZXJ5LnRleHQoIHRoaXMgKSA6XG5cdFx0XHRcdHRoaXMuZW1wdHkoKS5lYWNoKCBmdW5jdGlvbigpIHtcblx0XHRcdFx0XHRpZiAoIHRoaXMubm9kZVR5cGUgPT09IDEgfHwgdGhpcy5ub2RlVHlwZSA9PT0gMTEgfHwgdGhpcy5ub2RlVHlwZSA9PT0gOSApIHtcblx0XHRcdFx0XHRcdHRoaXMudGV4dENvbnRlbnQgPSB2YWx1ZTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH0gKTtcblx0XHR9LCBudWxsLCB2YWx1ZSwgYXJndW1lbnRzLmxlbmd0aCApO1xuXHR9LFxuXG5cdGFwcGVuZDogZnVuY3Rpb24oKSB7XG5cdFx0cmV0dXJuIGRvbU1hbmlwKCB0aGlzLCBhcmd1bWVudHMsIGZ1bmN0aW9uKCBlbGVtICkge1xuXHRcdFx0aWYgKCB0aGlzLm5vZGVUeXBlID09PSAxIHx8IHRoaXMubm9kZVR5cGUgPT09IDExIHx8IHRoaXMubm9kZVR5cGUgPT09IDkgKSB7XG5cdFx0XHRcdHZhciB0YXJnZXQgPSBtYW5pcHVsYXRpb25UYXJnZXQoIHRoaXMsIGVsZW0gKTtcblx0XHRcdFx0dGFyZ2V0LmFwcGVuZENoaWxkKCBlbGVtICk7XG5cdFx0XHR9XG5cdFx0fSApO1xuXHR9LFxuXG5cdHByZXBlbmQ6IGZ1bmN0aW9uKCkge1xuXHRcdHJldHVybiBkb21NYW5pcCggdGhpcywgYXJndW1lbnRzLCBmdW5jdGlvbiggZWxlbSApIHtcblx0XHRcdGlmICggdGhpcy5ub2RlVHlwZSA9PT0gMSB8fCB0aGlzLm5vZGVUeXBlID09PSAxMSB8fCB0aGlzLm5vZGVUeXBlID09PSA5ICkge1xuXHRcdFx0XHR2YXIgdGFyZ2V0ID0gbWFuaXB1bGF0aW9uVGFyZ2V0KCB0aGlzLCBlbGVtICk7XG5cdFx0XHRcdHRhcmdldC5pbnNlcnRCZWZvcmUoIGVsZW0sIHRhcmdldC5maXJzdENoaWxkICk7XG5cdFx0XHR9XG5cdFx0fSApO1xuXHR9LFxuXG5cdGJlZm9yZTogZnVuY3Rpb24oKSB7XG5cdFx0cmV0dXJuIGRvbU1hbmlwKCB0aGlzLCBhcmd1bWVudHMsIGZ1bmN0aW9uKCBlbGVtICkge1xuXHRcdFx0aWYgKCB0aGlzLnBhcmVudE5vZGUgKSB7XG5cdFx0XHRcdHRoaXMucGFyZW50Tm9kZS5pbnNlcnRCZWZvcmUoIGVsZW0sIHRoaXMgKTtcblx0XHRcdH1cblx0XHR9ICk7XG5cdH0sXG5cblx0YWZ0ZXI6IGZ1bmN0aW9uKCkge1xuXHRcdHJldHVybiBkb21NYW5pcCggdGhpcywgYXJndW1lbnRzLCBmdW5jdGlvbiggZWxlbSApIHtcblx0XHRcdGlmICggdGhpcy5wYXJlbnROb2RlICkge1xuXHRcdFx0XHR0aGlzLnBhcmVudE5vZGUuaW5zZXJ0QmVmb3JlKCBlbGVtLCB0aGlzLm5leHRTaWJsaW5nICk7XG5cdFx0XHR9XG5cdFx0fSApO1xuXHR9LFxuXG5cdGVtcHR5OiBmdW5jdGlvbigpIHtcblx0XHR2YXIgZWxlbSxcblx0XHRcdGkgPSAwO1xuXG5cdFx0Zm9yICggOyAoIGVsZW0gPSB0aGlzWyBpIF0gKSAhPSBudWxsOyBpKysgKSB7XG5cdFx0XHRpZiAoIGVsZW0ubm9kZVR5cGUgPT09IDEgKSB7XG5cblx0XHRcdFx0Ly8gUHJldmVudCBtZW1vcnkgbGVha3Ncblx0XHRcdFx0alF1ZXJ5LmNsZWFuRGF0YSggZ2V0QWxsKCBlbGVtLCBmYWxzZSApICk7XG5cblx0XHRcdFx0Ly8gUmVtb3ZlIGFueSByZW1haW5pbmcgbm9kZXNcblx0XHRcdFx0ZWxlbS50ZXh0Q29udGVudCA9IFwiXCI7XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0cmV0dXJuIHRoaXM7XG5cdH0sXG5cblx0Y2xvbmU6IGZ1bmN0aW9uKCBkYXRhQW5kRXZlbnRzLCBkZWVwRGF0YUFuZEV2ZW50cyApIHtcblx0XHRkYXRhQW5kRXZlbnRzID0gZGF0YUFuZEV2ZW50cyA9PSBudWxsID8gZmFsc2UgOiBkYXRhQW5kRXZlbnRzO1xuXHRcdGRlZXBEYXRhQW5kRXZlbnRzID0gZGVlcERhdGFBbmRFdmVudHMgPT0gbnVsbCA/IGRhdGFBbmRFdmVudHMgOiBkZWVwRGF0YUFuZEV2ZW50cztcblxuXHRcdHJldHVybiB0aGlzLm1hcCggZnVuY3Rpb24oKSB7XG5cdFx0XHRyZXR1cm4galF1ZXJ5LmNsb25lKCB0aGlzLCBkYXRhQW5kRXZlbnRzLCBkZWVwRGF0YUFuZEV2ZW50cyApO1xuXHRcdH0gKTtcblx0fSxcblxuXHRodG1sOiBmdW5jdGlvbiggdmFsdWUgKSB7XG5cdFx0cmV0dXJuIGFjY2VzcyggdGhpcywgZnVuY3Rpb24oIHZhbHVlICkge1xuXHRcdFx0dmFyIGVsZW0gPSB0aGlzWyAwIF0gfHwge30sXG5cdFx0XHRcdGkgPSAwLFxuXHRcdFx0XHRsID0gdGhpcy5sZW5ndGg7XG5cblx0XHRcdGlmICggdmFsdWUgPT09IHVuZGVmaW5lZCAmJiBlbGVtLm5vZGVUeXBlID09PSAxICkge1xuXHRcdFx0XHRyZXR1cm4gZWxlbS5pbm5lckhUTUw7XG5cdFx0XHR9XG5cblx0XHRcdC8vIFNlZSBpZiB3ZSBjYW4gdGFrZSBhIHNob3J0Y3V0IGFuZCBqdXN0IHVzZSBpbm5lckhUTUxcblx0XHRcdGlmICggdHlwZW9mIHZhbHVlID09PSBcInN0cmluZ1wiICYmICFybm9Jbm5lcmh0bWwudGVzdCggdmFsdWUgKSAmJlxuXHRcdFx0XHQhd3JhcE1hcFsgKCBydGFnTmFtZS5leGVjKCB2YWx1ZSApIHx8IFsgXCJcIiwgXCJcIiBdIClbIDEgXS50b0xvd2VyQ2FzZSgpIF0gKSB7XG5cblx0XHRcdFx0dmFsdWUgPSBqUXVlcnkuaHRtbFByZWZpbHRlciggdmFsdWUgKTtcblxuXHRcdFx0XHR0cnkge1xuXHRcdFx0XHRcdGZvciAoIDsgaSA8IGw7IGkrKyApIHtcblx0XHRcdFx0XHRcdGVsZW0gPSB0aGlzWyBpIF0gfHwge307XG5cblx0XHRcdFx0XHRcdC8vIFJlbW92ZSBlbGVtZW50IG5vZGVzIGFuZCBwcmV2ZW50IG1lbW9yeSBsZWFrc1xuXHRcdFx0XHRcdFx0aWYgKCBlbGVtLm5vZGVUeXBlID09PSAxICkge1xuXHRcdFx0XHRcdFx0XHRqUXVlcnkuY2xlYW5EYXRhKCBnZXRBbGwoIGVsZW0sIGZhbHNlICkgKTtcblx0XHRcdFx0XHRcdFx0ZWxlbS5pbm5lckhUTUwgPSB2YWx1ZTtcblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHRlbGVtID0gMDtcblxuXHRcdFx0XHQvLyBJZiB1c2luZyBpbm5lckhUTUwgdGhyb3dzIGFuIGV4Y2VwdGlvbiwgdXNlIHRoZSBmYWxsYmFjayBtZXRob2Rcblx0XHRcdFx0fSBjYXRjaCAoIGUgKSB7fVxuXHRcdFx0fVxuXG5cdFx0XHRpZiAoIGVsZW0gKSB7XG5cdFx0XHRcdHRoaXMuZW1wdHkoKS5hcHBlbmQoIHZhbHVlICk7XG5cdFx0XHR9XG5cdFx0fSwgbnVsbCwgdmFsdWUsIGFyZ3VtZW50cy5sZW5ndGggKTtcblx0fSxcblxuXHRyZXBsYWNlV2l0aDogZnVuY3Rpb24oKSB7XG5cdFx0dmFyIGlnbm9yZWQgPSBbXTtcblxuXHRcdC8vIE1ha2UgdGhlIGNoYW5nZXMsIHJlcGxhY2luZyBlYWNoIG5vbi1pZ25vcmVkIGNvbnRleHQgZWxlbWVudCB3aXRoIHRoZSBuZXcgY29udGVudFxuXHRcdHJldHVybiBkb21NYW5pcCggdGhpcywgYXJndW1lbnRzLCBmdW5jdGlvbiggZWxlbSApIHtcblx0XHRcdHZhciBwYXJlbnQgPSB0aGlzLnBhcmVudE5vZGU7XG5cblx0XHRcdGlmICggalF1ZXJ5LmluQXJyYXkoIHRoaXMsIGlnbm9yZWQgKSA8IDAgKSB7XG5cdFx0XHRcdGpRdWVyeS5jbGVhbkRhdGEoIGdldEFsbCggdGhpcyApICk7XG5cdFx0XHRcdGlmICggcGFyZW50ICkge1xuXHRcdFx0XHRcdHBhcmVudC5yZXBsYWNlQ2hpbGQoIGVsZW0sIHRoaXMgKTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXG5cdFx0Ly8gRm9yY2UgY2FsbGJhY2sgaW52b2NhdGlvblxuXHRcdH0sIGlnbm9yZWQgKTtcblx0fVxufSApO1xuXG5qUXVlcnkuZWFjaCgge1xuXHRhcHBlbmRUbzogXCJhcHBlbmRcIixcblx0cHJlcGVuZFRvOiBcInByZXBlbmRcIixcblx0aW5zZXJ0QmVmb3JlOiBcImJlZm9yZVwiLFxuXHRpbnNlcnRBZnRlcjogXCJhZnRlclwiLFxuXHRyZXBsYWNlQWxsOiBcInJlcGxhY2VXaXRoXCJcbn0sIGZ1bmN0aW9uKCBuYW1lLCBvcmlnaW5hbCApIHtcblx0alF1ZXJ5LmZuWyBuYW1lIF0gPSBmdW5jdGlvbiggc2VsZWN0b3IgKSB7XG5cdFx0dmFyIGVsZW1zLFxuXHRcdFx0cmV0ID0gW10sXG5cdFx0XHRpbnNlcnQgPSBqUXVlcnkoIHNlbGVjdG9yICksXG5cdFx0XHRsYXN0ID0gaW5zZXJ0Lmxlbmd0aCAtIDEsXG5cdFx0XHRpID0gMDtcblxuXHRcdGZvciAoIDsgaSA8PSBsYXN0OyBpKysgKSB7XG5cdFx0XHRlbGVtcyA9IGkgPT09IGxhc3QgPyB0aGlzIDogdGhpcy5jbG9uZSggdHJ1ZSApO1xuXHRcdFx0alF1ZXJ5KCBpbnNlcnRbIGkgXSApWyBvcmlnaW5hbCBdKCBlbGVtcyApO1xuXG5cdFx0XHQvLyBTdXBwb3J0OiBBbmRyb2lkIDw9NC4wIG9ubHksIFBoYW50b21KUyAxIG9ubHlcblx0XHRcdC8vIC5nZXQoKSBiZWNhdXNlIHB1c2guYXBwbHkoXywgYXJyYXlsaWtlKSB0aHJvd3Mgb24gYW5jaWVudCBXZWJLaXRcblx0XHRcdHB1c2guYXBwbHkoIHJldCwgZWxlbXMuZ2V0KCkgKTtcblx0XHR9XG5cblx0XHRyZXR1cm4gdGhpcy5wdXNoU3RhY2soIHJldCApO1xuXHR9O1xufSApO1xudmFyIHJtYXJnaW4gPSAoIC9ebWFyZ2luLyApO1xuXG52YXIgcm51bW5vbnB4ID0gbmV3IFJlZ0V4cCggXCJeKFwiICsgcG51bSArIFwiKSg/IXB4KVthLXolXSskXCIsIFwiaVwiICk7XG5cbnZhciBnZXRTdHlsZXMgPSBmdW5jdGlvbiggZWxlbSApIHtcblxuXHRcdC8vIFN1cHBvcnQ6IElFIDw9MTEgb25seSwgRmlyZWZveCA8PTMwICgjMTUwOTgsICMxNDE1MClcblx0XHQvLyBJRSB0aHJvd3Mgb24gZWxlbWVudHMgY3JlYXRlZCBpbiBwb3B1cHNcblx0XHQvLyBGRiBtZWFud2hpbGUgdGhyb3dzIG9uIGZyYW1lIGVsZW1lbnRzIHRocm91Z2ggXCJkZWZhdWx0Vmlldy5nZXRDb21wdXRlZFN0eWxlXCJcblx0XHR2YXIgdmlldyA9IGVsZW0ub3duZXJEb2N1bWVudC5kZWZhdWx0VmlldztcblxuXHRcdGlmICggIXZpZXcgfHwgIXZpZXcub3BlbmVyICkge1xuXHRcdFx0dmlldyA9IHdpbmRvdztcblx0XHR9XG5cblx0XHRyZXR1cm4gdmlldy5nZXRDb21wdXRlZFN0eWxlKCBlbGVtICk7XG5cdH07XG5cblxuXG4oIGZ1bmN0aW9uKCkge1xuXG5cdC8vIEV4ZWN1dGluZyBib3RoIHBpeGVsUG9zaXRpb24gJiBib3hTaXppbmdSZWxpYWJsZSB0ZXN0cyByZXF1aXJlIG9ubHkgb25lIGxheW91dFxuXHQvLyBzbyB0aGV5J3JlIGV4ZWN1dGVkIGF0IHRoZSBzYW1lIHRpbWUgdG8gc2F2ZSB0aGUgc2Vjb25kIGNvbXB1dGF0aW9uLlxuXHRmdW5jdGlvbiBjb21wdXRlU3R5bGVUZXN0cygpIHtcblxuXHRcdC8vIFRoaXMgaXMgYSBzaW5nbGV0b24sIHdlIG5lZWQgdG8gZXhlY3V0ZSBpdCBvbmx5IG9uY2Vcblx0XHRpZiAoICFkaXYgKSB7XG5cdFx0XHRyZXR1cm47XG5cdFx0fVxuXG5cdFx0ZGl2LnN0eWxlLmNzc1RleHQgPVxuXHRcdFx0XCJib3gtc2l6aW5nOmJvcmRlci1ib3g7XCIgK1xuXHRcdFx0XCJwb3NpdGlvbjpyZWxhdGl2ZTtkaXNwbGF5OmJsb2NrO1wiICtcblx0XHRcdFwibWFyZ2luOmF1dG87Ym9yZGVyOjFweDtwYWRkaW5nOjFweDtcIiArXG5cdFx0XHRcInRvcDoxJTt3aWR0aDo1MCVcIjtcblx0XHRkaXYuaW5uZXJIVE1MID0gXCJcIjtcblx0XHRkb2N1bWVudEVsZW1lbnQuYXBwZW5kQ2hpbGQoIGNvbnRhaW5lciApO1xuXG5cdFx0dmFyIGRpdlN0eWxlID0gd2luZG93LmdldENvbXB1dGVkU3R5bGUoIGRpdiApO1xuXHRcdHBpeGVsUG9zaXRpb25WYWwgPSBkaXZTdHlsZS50b3AgIT09IFwiMSVcIjtcblxuXHRcdC8vIFN1cHBvcnQ6IEFuZHJvaWQgNC4wIC0gNC4zIG9ubHksIEZpcmVmb3ggPD0zIC0gNDRcblx0XHRyZWxpYWJsZU1hcmdpbkxlZnRWYWwgPSBkaXZTdHlsZS5tYXJnaW5MZWZ0ID09PSBcIjJweFwiO1xuXHRcdGJveFNpemluZ1JlbGlhYmxlVmFsID0gZGl2U3R5bGUud2lkdGggPT09IFwiNHB4XCI7XG5cblx0XHQvLyBTdXBwb3J0OiBBbmRyb2lkIDQuMCAtIDQuMyBvbmx5XG5cdFx0Ly8gU29tZSBzdHlsZXMgY29tZSBiYWNrIHdpdGggcGVyY2VudGFnZSB2YWx1ZXMsIGV2ZW4gdGhvdWdoIHRoZXkgc2hvdWxkbid0XG5cdFx0ZGl2LnN0eWxlLm1hcmdpblJpZ2h0ID0gXCI1MCVcIjtcblx0XHRwaXhlbE1hcmdpblJpZ2h0VmFsID0gZGl2U3R5bGUubWFyZ2luUmlnaHQgPT09IFwiNHB4XCI7XG5cblx0XHRkb2N1bWVudEVsZW1lbnQucmVtb3ZlQ2hpbGQoIGNvbnRhaW5lciApO1xuXG5cdFx0Ly8gTnVsbGlmeSB0aGUgZGl2IHNvIGl0IHdvdWxkbid0IGJlIHN0b3JlZCBpbiB0aGUgbWVtb3J5IGFuZFxuXHRcdC8vIGl0IHdpbGwgYWxzbyBiZSBhIHNpZ24gdGhhdCBjaGVja3MgYWxyZWFkeSBwZXJmb3JtZWRcblx0XHRkaXYgPSBudWxsO1xuXHR9XG5cblx0dmFyIHBpeGVsUG9zaXRpb25WYWwsIGJveFNpemluZ1JlbGlhYmxlVmFsLCBwaXhlbE1hcmdpblJpZ2h0VmFsLCByZWxpYWJsZU1hcmdpbkxlZnRWYWwsXG5cdFx0Y29udGFpbmVyID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCggXCJkaXZcIiApLFxuXHRcdGRpdiA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoIFwiZGl2XCIgKTtcblxuXHQvLyBGaW5pc2ggZWFybHkgaW4gbGltaXRlZCAobm9uLWJyb3dzZXIpIGVudmlyb25tZW50c1xuXHRpZiAoICFkaXYuc3R5bGUgKSB7XG5cdFx0cmV0dXJuO1xuXHR9XG5cblx0Ly8gU3VwcG9ydDogSUUgPD05IC0gMTEgb25seVxuXHQvLyBTdHlsZSBvZiBjbG9uZWQgZWxlbWVudCBhZmZlY3RzIHNvdXJjZSBlbGVtZW50IGNsb25lZCAoIzg5MDgpXG5cdGRpdi5zdHlsZS5iYWNrZ3JvdW5kQ2xpcCA9IFwiY29udGVudC1ib3hcIjtcblx0ZGl2LmNsb25lTm9kZSggdHJ1ZSApLnN0eWxlLmJhY2tncm91bmRDbGlwID0gXCJcIjtcblx0c3VwcG9ydC5jbGVhckNsb25lU3R5bGUgPSBkaXYuc3R5bGUuYmFja2dyb3VuZENsaXAgPT09IFwiY29udGVudC1ib3hcIjtcblxuXHRjb250YWluZXIuc3R5bGUuY3NzVGV4dCA9IFwiYm9yZGVyOjA7d2lkdGg6OHB4O2hlaWdodDowO3RvcDowO2xlZnQ6LTk5OTlweDtcIiArXG5cdFx0XCJwYWRkaW5nOjA7bWFyZ2luLXRvcDoxcHg7cG9zaXRpb246YWJzb2x1dGVcIjtcblx0Y29udGFpbmVyLmFwcGVuZENoaWxkKCBkaXYgKTtcblxuXHRqUXVlcnkuZXh0ZW5kKCBzdXBwb3J0LCB7XG5cdFx0cGl4ZWxQb3NpdGlvbjogZnVuY3Rpb24oKSB7XG5cdFx0XHRjb21wdXRlU3R5bGVUZXN0cygpO1xuXHRcdFx0cmV0dXJuIHBpeGVsUG9zaXRpb25WYWw7XG5cdFx0fSxcblx0XHRib3hTaXppbmdSZWxpYWJsZTogZnVuY3Rpb24oKSB7XG5cdFx0XHRjb21wdXRlU3R5bGVUZXN0cygpO1xuXHRcdFx0cmV0dXJuIGJveFNpemluZ1JlbGlhYmxlVmFsO1xuXHRcdH0sXG5cdFx0cGl4ZWxNYXJnaW5SaWdodDogZnVuY3Rpb24oKSB7XG5cdFx0XHRjb21wdXRlU3R5bGVUZXN0cygpO1xuXHRcdFx0cmV0dXJuIHBpeGVsTWFyZ2luUmlnaHRWYWw7XG5cdFx0fSxcblx0XHRyZWxpYWJsZU1hcmdpbkxlZnQ6IGZ1bmN0aW9uKCkge1xuXHRcdFx0Y29tcHV0ZVN0eWxlVGVzdHMoKTtcblx0XHRcdHJldHVybiByZWxpYWJsZU1hcmdpbkxlZnRWYWw7XG5cdFx0fVxuXHR9ICk7XG59ICkoKTtcblxuXG5mdW5jdGlvbiBjdXJDU1MoIGVsZW0sIG5hbWUsIGNvbXB1dGVkICkge1xuXHR2YXIgd2lkdGgsIG1pbldpZHRoLCBtYXhXaWR0aCwgcmV0LFxuXG5cdFx0Ly8gU3VwcG9ydDogRmlyZWZveCA1MStcblx0XHQvLyBSZXRyaWV2aW5nIHN0eWxlIGJlZm9yZSBjb21wdXRlZCBzb21laG93XG5cdFx0Ly8gZml4ZXMgYW4gaXNzdWUgd2l0aCBnZXR0aW5nIHdyb25nIHZhbHVlc1xuXHRcdC8vIG9uIGRldGFjaGVkIGVsZW1lbnRzXG5cdFx0c3R5bGUgPSBlbGVtLnN0eWxlO1xuXG5cdGNvbXB1dGVkID0gY29tcHV0ZWQgfHwgZ2V0U3R5bGVzKCBlbGVtICk7XG5cblx0Ly8gZ2V0UHJvcGVydHlWYWx1ZSBpcyBuZWVkZWQgZm9yOlxuXHQvLyAgIC5jc3MoJ2ZpbHRlcicpIChJRSA5IG9ubHksICMxMjUzNylcblx0Ly8gICAuY3NzKCctLWN1c3RvbVByb3BlcnR5KSAoIzMxNDQpXG5cdGlmICggY29tcHV0ZWQgKSB7XG5cdFx0cmV0ID0gY29tcHV0ZWQuZ2V0UHJvcGVydHlWYWx1ZSggbmFtZSApIHx8IGNvbXB1dGVkWyBuYW1lIF07XG5cblx0XHRpZiAoIHJldCA9PT0gXCJcIiAmJiAhalF1ZXJ5LmNvbnRhaW5zKCBlbGVtLm93bmVyRG9jdW1lbnQsIGVsZW0gKSApIHtcblx0XHRcdHJldCA9IGpRdWVyeS5zdHlsZSggZWxlbSwgbmFtZSApO1xuXHRcdH1cblxuXHRcdC8vIEEgdHJpYnV0ZSB0byB0aGUgXCJhd2Vzb21lIGhhY2sgYnkgRGVhbiBFZHdhcmRzXCJcblx0XHQvLyBBbmRyb2lkIEJyb3dzZXIgcmV0dXJucyBwZXJjZW50YWdlIGZvciBzb21lIHZhbHVlcyxcblx0XHQvLyBidXQgd2lkdGggc2VlbXMgdG8gYmUgcmVsaWFibHkgcGl4ZWxzLlxuXHRcdC8vIFRoaXMgaXMgYWdhaW5zdCB0aGUgQ1NTT00gZHJhZnQgc3BlYzpcblx0XHQvLyBodHRwczovL2RyYWZ0cy5jc3N3Zy5vcmcvY3Nzb20vI3Jlc29sdmVkLXZhbHVlc1xuXHRcdGlmICggIXN1cHBvcnQucGl4ZWxNYXJnaW5SaWdodCgpICYmIHJudW1ub25weC50ZXN0KCByZXQgKSAmJiBybWFyZ2luLnRlc3QoIG5hbWUgKSApIHtcblxuXHRcdFx0Ly8gUmVtZW1iZXIgdGhlIG9yaWdpbmFsIHZhbHVlc1xuXHRcdFx0d2lkdGggPSBzdHlsZS53aWR0aDtcblx0XHRcdG1pbldpZHRoID0gc3R5bGUubWluV2lkdGg7XG5cdFx0XHRtYXhXaWR0aCA9IHN0eWxlLm1heFdpZHRoO1xuXG5cdFx0XHQvLyBQdXQgaW4gdGhlIG5ldyB2YWx1ZXMgdG8gZ2V0IGEgY29tcHV0ZWQgdmFsdWUgb3V0XG5cdFx0XHRzdHlsZS5taW5XaWR0aCA9IHN0eWxlLm1heFdpZHRoID0gc3R5bGUud2lkdGggPSByZXQ7XG5cdFx0XHRyZXQgPSBjb21wdXRlZC53aWR0aDtcblxuXHRcdFx0Ly8gUmV2ZXJ0IHRoZSBjaGFuZ2VkIHZhbHVlc1xuXHRcdFx0c3R5bGUud2lkdGggPSB3aWR0aDtcblx0XHRcdHN0eWxlLm1pbldpZHRoID0gbWluV2lkdGg7XG5cdFx0XHRzdHlsZS5tYXhXaWR0aCA9IG1heFdpZHRoO1xuXHRcdH1cblx0fVxuXG5cdHJldHVybiByZXQgIT09IHVuZGVmaW5lZCA/XG5cblx0XHQvLyBTdXBwb3J0OiBJRSA8PTkgLSAxMSBvbmx5XG5cdFx0Ly8gSUUgcmV0dXJucyB6SW5kZXggdmFsdWUgYXMgYW4gaW50ZWdlci5cblx0XHRyZXQgKyBcIlwiIDpcblx0XHRyZXQ7XG59XG5cblxuZnVuY3Rpb24gYWRkR2V0SG9va0lmKCBjb25kaXRpb25GbiwgaG9va0ZuICkge1xuXG5cdC8vIERlZmluZSB0aGUgaG9vaywgd2UnbGwgY2hlY2sgb24gdGhlIGZpcnN0IHJ1biBpZiBpdCdzIHJlYWxseSBuZWVkZWQuXG5cdHJldHVybiB7XG5cdFx0Z2V0OiBmdW5jdGlvbigpIHtcblx0XHRcdGlmICggY29uZGl0aW9uRm4oKSApIHtcblxuXHRcdFx0XHQvLyBIb29rIG5vdCBuZWVkZWQgKG9yIGl0J3Mgbm90IHBvc3NpYmxlIHRvIHVzZSBpdCBkdWVcblx0XHRcdFx0Ly8gdG8gbWlzc2luZyBkZXBlbmRlbmN5KSwgcmVtb3ZlIGl0LlxuXHRcdFx0XHRkZWxldGUgdGhpcy5nZXQ7XG5cdFx0XHRcdHJldHVybjtcblx0XHRcdH1cblxuXHRcdFx0Ly8gSG9vayBuZWVkZWQ7IHJlZGVmaW5lIGl0IHNvIHRoYXQgdGhlIHN1cHBvcnQgdGVzdCBpcyBub3QgZXhlY3V0ZWQgYWdhaW4uXG5cdFx0XHRyZXR1cm4gKCB0aGlzLmdldCA9IGhvb2tGbiApLmFwcGx5KCB0aGlzLCBhcmd1bWVudHMgKTtcblx0XHR9XG5cdH07XG59XG5cblxudmFyXG5cblx0Ly8gU3dhcHBhYmxlIGlmIGRpc3BsYXkgaXMgbm9uZSBvciBzdGFydHMgd2l0aCB0YWJsZVxuXHQvLyBleGNlcHQgXCJ0YWJsZVwiLCBcInRhYmxlLWNlbGxcIiwgb3IgXCJ0YWJsZS1jYXB0aW9uXCJcblx0Ly8gU2VlIGhlcmUgZm9yIGRpc3BsYXkgdmFsdWVzOiBodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL0NTUy9kaXNwbGF5XG5cdHJkaXNwbGF5c3dhcCA9IC9eKG5vbmV8dGFibGUoPyEtY1tlYV0pLispLyxcblx0cmN1c3RvbVByb3AgPSAvXi0tLyxcblx0Y3NzU2hvdyA9IHsgcG9zaXRpb246IFwiYWJzb2x1dGVcIiwgdmlzaWJpbGl0eTogXCJoaWRkZW5cIiwgZGlzcGxheTogXCJibG9ja1wiIH0sXG5cdGNzc05vcm1hbFRyYW5zZm9ybSA9IHtcblx0XHRsZXR0ZXJTcGFjaW5nOiBcIjBcIixcblx0XHRmb250V2VpZ2h0OiBcIjQwMFwiXG5cdH0sXG5cblx0Y3NzUHJlZml4ZXMgPSBbIFwiV2Via2l0XCIsIFwiTW96XCIsIFwibXNcIiBdLFxuXHRlbXB0eVN0eWxlID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCggXCJkaXZcIiApLnN0eWxlO1xuXG4vLyBSZXR1cm4gYSBjc3MgcHJvcGVydHkgbWFwcGVkIHRvIGEgcG90ZW50aWFsbHkgdmVuZG9yIHByZWZpeGVkIHByb3BlcnR5XG5mdW5jdGlvbiB2ZW5kb3JQcm9wTmFtZSggbmFtZSApIHtcblxuXHQvLyBTaG9ydGN1dCBmb3IgbmFtZXMgdGhhdCBhcmUgbm90IHZlbmRvciBwcmVmaXhlZFxuXHRpZiAoIG5hbWUgaW4gZW1wdHlTdHlsZSApIHtcblx0XHRyZXR1cm4gbmFtZTtcblx0fVxuXG5cdC8vIENoZWNrIGZvciB2ZW5kb3IgcHJlZml4ZWQgbmFtZXNcblx0dmFyIGNhcE5hbWUgPSBuYW1lWyAwIF0udG9VcHBlckNhc2UoKSArIG5hbWUuc2xpY2UoIDEgKSxcblx0XHRpID0gY3NzUHJlZml4ZXMubGVuZ3RoO1xuXG5cdHdoaWxlICggaS0tICkge1xuXHRcdG5hbWUgPSBjc3NQcmVmaXhlc1sgaSBdICsgY2FwTmFtZTtcblx0XHRpZiAoIG5hbWUgaW4gZW1wdHlTdHlsZSApIHtcblx0XHRcdHJldHVybiBuYW1lO1xuXHRcdH1cblx0fVxufVxuXG4vLyBSZXR1cm4gYSBwcm9wZXJ0eSBtYXBwZWQgYWxvbmcgd2hhdCBqUXVlcnkuY3NzUHJvcHMgc3VnZ2VzdHMgb3IgdG9cbi8vIGEgdmVuZG9yIHByZWZpeGVkIHByb3BlcnR5LlxuZnVuY3Rpb24gZmluYWxQcm9wTmFtZSggbmFtZSApIHtcblx0dmFyIHJldCA9IGpRdWVyeS5jc3NQcm9wc1sgbmFtZSBdO1xuXHRpZiAoICFyZXQgKSB7XG5cdFx0cmV0ID0galF1ZXJ5LmNzc1Byb3BzWyBuYW1lIF0gPSB2ZW5kb3JQcm9wTmFtZSggbmFtZSApIHx8IG5hbWU7XG5cdH1cblx0cmV0dXJuIHJldDtcbn1cblxuZnVuY3Rpb24gc2V0UG9zaXRpdmVOdW1iZXIoIGVsZW0sIHZhbHVlLCBzdWJ0cmFjdCApIHtcblxuXHQvLyBBbnkgcmVsYXRpdmUgKCsvLSkgdmFsdWVzIGhhdmUgYWxyZWFkeSBiZWVuXG5cdC8vIG5vcm1hbGl6ZWQgYXQgdGhpcyBwb2ludFxuXHR2YXIgbWF0Y2hlcyA9IHJjc3NOdW0uZXhlYyggdmFsdWUgKTtcblx0cmV0dXJuIG1hdGNoZXMgP1xuXG5cdFx0Ly8gR3VhcmQgYWdhaW5zdCB1bmRlZmluZWQgXCJzdWJ0cmFjdFwiLCBlLmcuLCB3aGVuIHVzZWQgYXMgaW4gY3NzSG9va3Ncblx0XHRNYXRoLm1heCggMCwgbWF0Y2hlc1sgMiBdIC0gKCBzdWJ0cmFjdCB8fCAwICkgKSArICggbWF0Y2hlc1sgMyBdIHx8IFwicHhcIiApIDpcblx0XHR2YWx1ZTtcbn1cblxuZnVuY3Rpb24gYXVnbWVudFdpZHRoT3JIZWlnaHQoIGVsZW0sIG5hbWUsIGV4dHJhLCBpc0JvcmRlckJveCwgc3R5bGVzICkge1xuXHR2YXIgaSxcblx0XHR2YWwgPSAwO1xuXG5cdC8vIElmIHdlIGFscmVhZHkgaGF2ZSB0aGUgcmlnaHQgbWVhc3VyZW1lbnQsIGF2b2lkIGF1Z21lbnRhdGlvblxuXHRpZiAoIGV4dHJhID09PSAoIGlzQm9yZGVyQm94ID8gXCJib3JkZXJcIiA6IFwiY29udGVudFwiICkgKSB7XG5cdFx0aSA9IDQ7XG5cblx0Ly8gT3RoZXJ3aXNlIGluaXRpYWxpemUgZm9yIGhvcml6b250YWwgb3IgdmVydGljYWwgcHJvcGVydGllc1xuXHR9IGVsc2Uge1xuXHRcdGkgPSBuYW1lID09PSBcIndpZHRoXCIgPyAxIDogMDtcblx0fVxuXG5cdGZvciAoIDsgaSA8IDQ7IGkgKz0gMiApIHtcblxuXHRcdC8vIEJvdGggYm94IG1vZGVscyBleGNsdWRlIG1hcmdpbiwgc28gYWRkIGl0IGlmIHdlIHdhbnQgaXRcblx0XHRpZiAoIGV4dHJhID09PSBcIm1hcmdpblwiICkge1xuXHRcdFx0dmFsICs9IGpRdWVyeS5jc3MoIGVsZW0sIGV4dHJhICsgY3NzRXhwYW5kWyBpIF0sIHRydWUsIHN0eWxlcyApO1xuXHRcdH1cblxuXHRcdGlmICggaXNCb3JkZXJCb3ggKSB7XG5cblx0XHRcdC8vIGJvcmRlci1ib3ggaW5jbHVkZXMgcGFkZGluZywgc28gcmVtb3ZlIGl0IGlmIHdlIHdhbnQgY29udGVudFxuXHRcdFx0aWYgKCBleHRyYSA9PT0gXCJjb250ZW50XCIgKSB7XG5cdFx0XHRcdHZhbCAtPSBqUXVlcnkuY3NzKCBlbGVtLCBcInBhZGRpbmdcIiArIGNzc0V4cGFuZFsgaSBdLCB0cnVlLCBzdHlsZXMgKTtcblx0XHRcdH1cblxuXHRcdFx0Ly8gQXQgdGhpcyBwb2ludCwgZXh0cmEgaXNuJ3QgYm9yZGVyIG5vciBtYXJnaW4sIHNvIHJlbW92ZSBib3JkZXJcblx0XHRcdGlmICggZXh0cmEgIT09IFwibWFyZ2luXCIgKSB7XG5cdFx0XHRcdHZhbCAtPSBqUXVlcnkuY3NzKCBlbGVtLCBcImJvcmRlclwiICsgY3NzRXhwYW5kWyBpIF0gKyBcIldpZHRoXCIsIHRydWUsIHN0eWxlcyApO1xuXHRcdFx0fVxuXHRcdH0gZWxzZSB7XG5cblx0XHRcdC8vIEF0IHRoaXMgcG9pbnQsIGV4dHJhIGlzbid0IGNvbnRlbnQsIHNvIGFkZCBwYWRkaW5nXG5cdFx0XHR2YWwgKz0galF1ZXJ5LmNzcyggZWxlbSwgXCJwYWRkaW5nXCIgKyBjc3NFeHBhbmRbIGkgXSwgdHJ1ZSwgc3R5bGVzICk7XG5cblx0XHRcdC8vIEF0IHRoaXMgcG9pbnQsIGV4dHJhIGlzbid0IGNvbnRlbnQgbm9yIHBhZGRpbmcsIHNvIGFkZCBib3JkZXJcblx0XHRcdGlmICggZXh0cmEgIT09IFwicGFkZGluZ1wiICkge1xuXHRcdFx0XHR2YWwgKz0galF1ZXJ5LmNzcyggZWxlbSwgXCJib3JkZXJcIiArIGNzc0V4cGFuZFsgaSBdICsgXCJXaWR0aFwiLCB0cnVlLCBzdHlsZXMgKTtcblx0XHRcdH1cblx0XHR9XG5cdH1cblxuXHRyZXR1cm4gdmFsO1xufVxuXG5mdW5jdGlvbiBnZXRXaWR0aE9ySGVpZ2h0KCBlbGVtLCBuYW1lLCBleHRyYSApIHtcblxuXHQvLyBTdGFydCB3aXRoIGNvbXB1dGVkIHN0eWxlXG5cdHZhciB2YWx1ZUlzQm9yZGVyQm94LFxuXHRcdHN0eWxlcyA9IGdldFN0eWxlcyggZWxlbSApLFxuXHRcdHZhbCA9IGN1ckNTUyggZWxlbSwgbmFtZSwgc3R5bGVzICksXG5cdFx0aXNCb3JkZXJCb3ggPSBqUXVlcnkuY3NzKCBlbGVtLCBcImJveFNpemluZ1wiLCBmYWxzZSwgc3R5bGVzICkgPT09IFwiYm9yZGVyLWJveFwiO1xuXG5cdC8vIENvbXB1dGVkIHVuaXQgaXMgbm90IHBpeGVscy4gU3RvcCBoZXJlIGFuZCByZXR1cm4uXG5cdGlmICggcm51bW5vbnB4LnRlc3QoIHZhbCApICkge1xuXHRcdHJldHVybiB2YWw7XG5cdH1cblxuXHQvLyBDaGVjayBmb3Igc3R5bGUgaW4gY2FzZSBhIGJyb3dzZXIgd2hpY2ggcmV0dXJucyB1bnJlbGlhYmxlIHZhbHVlc1xuXHQvLyBmb3IgZ2V0Q29tcHV0ZWRTdHlsZSBzaWxlbnRseSBmYWxscyBiYWNrIHRvIHRoZSByZWxpYWJsZSBlbGVtLnN0eWxlXG5cdHZhbHVlSXNCb3JkZXJCb3ggPSBpc0JvcmRlckJveCAmJlxuXHRcdCggc3VwcG9ydC5ib3hTaXppbmdSZWxpYWJsZSgpIHx8IHZhbCA9PT0gZWxlbS5zdHlsZVsgbmFtZSBdICk7XG5cblx0Ly8gRmFsbCBiYWNrIHRvIG9mZnNldFdpZHRoL0hlaWdodCB3aGVuIHZhbHVlIGlzIFwiYXV0b1wiXG5cdC8vIFRoaXMgaGFwcGVucyBmb3IgaW5saW5lIGVsZW1lbnRzIHdpdGggbm8gZXhwbGljaXQgc2V0dGluZyAoZ2gtMzU3MSlcblx0aWYgKCB2YWwgPT09IFwiYXV0b1wiICkge1xuXHRcdHZhbCA9IGVsZW1bIFwib2Zmc2V0XCIgKyBuYW1lWyAwIF0udG9VcHBlckNhc2UoKSArIG5hbWUuc2xpY2UoIDEgKSBdO1xuXHR9XG5cblx0Ly8gTm9ybWFsaXplIFwiXCIsIGF1dG8sIGFuZCBwcmVwYXJlIGZvciBleHRyYVxuXHR2YWwgPSBwYXJzZUZsb2F0KCB2YWwgKSB8fCAwO1xuXG5cdC8vIFVzZSB0aGUgYWN0aXZlIGJveC1zaXppbmcgbW9kZWwgdG8gYWRkL3N1YnRyYWN0IGlycmVsZXZhbnQgc3R5bGVzXG5cdHJldHVybiAoIHZhbCArXG5cdFx0YXVnbWVudFdpZHRoT3JIZWlnaHQoXG5cdFx0XHRlbGVtLFxuXHRcdFx0bmFtZSxcblx0XHRcdGV4dHJhIHx8ICggaXNCb3JkZXJCb3ggPyBcImJvcmRlclwiIDogXCJjb250ZW50XCIgKSxcblx0XHRcdHZhbHVlSXNCb3JkZXJCb3gsXG5cdFx0XHRzdHlsZXNcblx0XHQpXG5cdCkgKyBcInB4XCI7XG59XG5cbmpRdWVyeS5leHRlbmQoIHtcblxuXHQvLyBBZGQgaW4gc3R5bGUgcHJvcGVydHkgaG9va3MgZm9yIG92ZXJyaWRpbmcgdGhlIGRlZmF1bHRcblx0Ly8gYmVoYXZpb3Igb2YgZ2V0dGluZyBhbmQgc2V0dGluZyBhIHN0eWxlIHByb3BlcnR5XG5cdGNzc0hvb2tzOiB7XG5cdFx0b3BhY2l0eToge1xuXHRcdFx0Z2V0OiBmdW5jdGlvbiggZWxlbSwgY29tcHV0ZWQgKSB7XG5cdFx0XHRcdGlmICggY29tcHV0ZWQgKSB7XG5cblx0XHRcdFx0XHQvLyBXZSBzaG91bGQgYWx3YXlzIGdldCBhIG51bWJlciBiYWNrIGZyb20gb3BhY2l0eVxuXHRcdFx0XHRcdHZhciByZXQgPSBjdXJDU1MoIGVsZW0sIFwib3BhY2l0eVwiICk7XG5cdFx0XHRcdFx0cmV0dXJuIHJldCA9PT0gXCJcIiA/IFwiMVwiIDogcmV0O1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fVxuXHR9LFxuXG5cdC8vIERvbid0IGF1dG9tYXRpY2FsbHkgYWRkIFwicHhcIiB0byB0aGVzZSBwb3NzaWJseS11bml0bGVzcyBwcm9wZXJ0aWVzXG5cdGNzc051bWJlcjoge1xuXHRcdFwiYW5pbWF0aW9uSXRlcmF0aW9uQ291bnRcIjogdHJ1ZSxcblx0XHRcImNvbHVtbkNvdW50XCI6IHRydWUsXG5cdFx0XCJmaWxsT3BhY2l0eVwiOiB0cnVlLFxuXHRcdFwiZmxleEdyb3dcIjogdHJ1ZSxcblx0XHRcImZsZXhTaHJpbmtcIjogdHJ1ZSxcblx0XHRcImZvbnRXZWlnaHRcIjogdHJ1ZSxcblx0XHRcImxpbmVIZWlnaHRcIjogdHJ1ZSxcblx0XHRcIm9wYWNpdHlcIjogdHJ1ZSxcblx0XHRcIm9yZGVyXCI6IHRydWUsXG5cdFx0XCJvcnBoYW5zXCI6IHRydWUsXG5cdFx0XCJ3aWRvd3NcIjogdHJ1ZSxcblx0XHRcInpJbmRleFwiOiB0cnVlLFxuXHRcdFwiem9vbVwiOiB0cnVlXG5cdH0sXG5cblx0Ly8gQWRkIGluIHByb3BlcnRpZXMgd2hvc2UgbmFtZXMgeW91IHdpc2ggdG8gZml4IGJlZm9yZVxuXHQvLyBzZXR0aW5nIG9yIGdldHRpbmcgdGhlIHZhbHVlXG5cdGNzc1Byb3BzOiB7XG5cdFx0XCJmbG9hdFwiOiBcImNzc0Zsb2F0XCJcblx0fSxcblxuXHQvLyBHZXQgYW5kIHNldCB0aGUgc3R5bGUgcHJvcGVydHkgb24gYSBET00gTm9kZVxuXHRzdHlsZTogZnVuY3Rpb24oIGVsZW0sIG5hbWUsIHZhbHVlLCBleHRyYSApIHtcblxuXHRcdC8vIERvbid0IHNldCBzdHlsZXMgb24gdGV4dCBhbmQgY29tbWVudCBub2Rlc1xuXHRcdGlmICggIWVsZW0gfHwgZWxlbS5ub2RlVHlwZSA9PT0gMyB8fCBlbGVtLm5vZGVUeXBlID09PSA4IHx8ICFlbGVtLnN0eWxlICkge1xuXHRcdFx0cmV0dXJuO1xuXHRcdH1cblxuXHRcdC8vIE1ha2Ugc3VyZSB0aGF0IHdlJ3JlIHdvcmtpbmcgd2l0aCB0aGUgcmlnaHQgbmFtZVxuXHRcdHZhciByZXQsIHR5cGUsIGhvb2tzLFxuXHRcdFx0b3JpZ05hbWUgPSBqUXVlcnkuY2FtZWxDYXNlKCBuYW1lICksXG5cdFx0XHRpc0N1c3RvbVByb3AgPSByY3VzdG9tUHJvcC50ZXN0KCBuYW1lICksXG5cdFx0XHRzdHlsZSA9IGVsZW0uc3R5bGU7XG5cblx0XHQvLyBNYWtlIHN1cmUgdGhhdCB3ZSdyZSB3b3JraW5nIHdpdGggdGhlIHJpZ2h0IG5hbWUuIFdlIGRvbid0XG5cdFx0Ly8gd2FudCB0byBxdWVyeSB0aGUgdmFsdWUgaWYgaXQgaXMgYSBDU1MgY3VzdG9tIHByb3BlcnR5XG5cdFx0Ly8gc2luY2UgdGhleSBhcmUgdXNlci1kZWZpbmVkLlxuXHRcdGlmICggIWlzQ3VzdG9tUHJvcCApIHtcblx0XHRcdG5hbWUgPSBmaW5hbFByb3BOYW1lKCBvcmlnTmFtZSApO1xuXHRcdH1cblxuXHRcdC8vIEdldHMgaG9vayBmb3IgdGhlIHByZWZpeGVkIHZlcnNpb24sIHRoZW4gdW5wcmVmaXhlZCB2ZXJzaW9uXG5cdFx0aG9va3MgPSBqUXVlcnkuY3NzSG9va3NbIG5hbWUgXSB8fCBqUXVlcnkuY3NzSG9va3NbIG9yaWdOYW1lIF07XG5cblx0XHQvLyBDaGVjayBpZiB3ZSdyZSBzZXR0aW5nIGEgdmFsdWVcblx0XHRpZiAoIHZhbHVlICE9PSB1bmRlZmluZWQgKSB7XG5cdFx0XHR0eXBlID0gdHlwZW9mIHZhbHVlO1xuXG5cdFx0XHQvLyBDb252ZXJ0IFwiKz1cIiBvciBcIi09XCIgdG8gcmVsYXRpdmUgbnVtYmVycyAoIzczNDUpXG5cdFx0XHRpZiAoIHR5cGUgPT09IFwic3RyaW5nXCIgJiYgKCByZXQgPSByY3NzTnVtLmV4ZWMoIHZhbHVlICkgKSAmJiByZXRbIDEgXSApIHtcblx0XHRcdFx0dmFsdWUgPSBhZGp1c3RDU1MoIGVsZW0sIG5hbWUsIHJldCApO1xuXG5cdFx0XHRcdC8vIEZpeGVzIGJ1ZyAjOTIzN1xuXHRcdFx0XHR0eXBlID0gXCJudW1iZXJcIjtcblx0XHRcdH1cblxuXHRcdFx0Ly8gTWFrZSBzdXJlIHRoYXQgbnVsbCBhbmQgTmFOIHZhbHVlcyBhcmVuJ3Qgc2V0ICgjNzExNilcblx0XHRcdGlmICggdmFsdWUgPT0gbnVsbCB8fCB2YWx1ZSAhPT0gdmFsdWUgKSB7XG5cdFx0XHRcdHJldHVybjtcblx0XHRcdH1cblxuXHRcdFx0Ly8gSWYgYSBudW1iZXIgd2FzIHBhc3NlZCBpbiwgYWRkIHRoZSB1bml0IChleGNlcHQgZm9yIGNlcnRhaW4gQ1NTIHByb3BlcnRpZXMpXG5cdFx0XHRpZiAoIHR5cGUgPT09IFwibnVtYmVyXCIgKSB7XG5cdFx0XHRcdHZhbHVlICs9IHJldCAmJiByZXRbIDMgXSB8fCAoIGpRdWVyeS5jc3NOdW1iZXJbIG9yaWdOYW1lIF0gPyBcIlwiIDogXCJweFwiICk7XG5cdFx0XHR9XG5cblx0XHRcdC8vIGJhY2tncm91bmQtKiBwcm9wcyBhZmZlY3Qgb3JpZ2luYWwgY2xvbmUncyB2YWx1ZXNcblx0XHRcdGlmICggIXN1cHBvcnQuY2xlYXJDbG9uZVN0eWxlICYmIHZhbHVlID09PSBcIlwiICYmIG5hbWUuaW5kZXhPZiggXCJiYWNrZ3JvdW5kXCIgKSA9PT0gMCApIHtcblx0XHRcdFx0c3R5bGVbIG5hbWUgXSA9IFwiaW5oZXJpdFwiO1xuXHRcdFx0fVxuXG5cdFx0XHQvLyBJZiBhIGhvb2sgd2FzIHByb3ZpZGVkLCB1c2UgdGhhdCB2YWx1ZSwgb3RoZXJ3aXNlIGp1c3Qgc2V0IHRoZSBzcGVjaWZpZWQgdmFsdWVcblx0XHRcdGlmICggIWhvb2tzIHx8ICEoIFwic2V0XCIgaW4gaG9va3MgKSB8fFxuXHRcdFx0XHQoIHZhbHVlID0gaG9va3Muc2V0KCBlbGVtLCB2YWx1ZSwgZXh0cmEgKSApICE9PSB1bmRlZmluZWQgKSB7XG5cblx0XHRcdFx0aWYgKCBpc0N1c3RvbVByb3AgKSB7XG5cdFx0XHRcdFx0c3R5bGUuc2V0UHJvcGVydHkoIG5hbWUsIHZhbHVlICk7XG5cdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0c3R5bGVbIG5hbWUgXSA9IHZhbHVlO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cblx0XHR9IGVsc2Uge1xuXG5cdFx0XHQvLyBJZiBhIGhvb2sgd2FzIHByb3ZpZGVkIGdldCB0aGUgbm9uLWNvbXB1dGVkIHZhbHVlIGZyb20gdGhlcmVcblx0XHRcdGlmICggaG9va3MgJiYgXCJnZXRcIiBpbiBob29rcyAmJlxuXHRcdFx0XHQoIHJldCA9IGhvb2tzLmdldCggZWxlbSwgZmFsc2UsIGV4dHJhICkgKSAhPT0gdW5kZWZpbmVkICkge1xuXG5cdFx0XHRcdHJldHVybiByZXQ7XG5cdFx0XHR9XG5cblx0XHRcdC8vIE90aGVyd2lzZSBqdXN0IGdldCB0aGUgdmFsdWUgZnJvbSB0aGUgc3R5bGUgb2JqZWN0XG5cdFx0XHRyZXR1cm4gc3R5bGVbIG5hbWUgXTtcblx0XHR9XG5cdH0sXG5cblx0Y3NzOiBmdW5jdGlvbiggZWxlbSwgbmFtZSwgZXh0cmEsIHN0eWxlcyApIHtcblx0XHR2YXIgdmFsLCBudW0sIGhvb2tzLFxuXHRcdFx0b3JpZ05hbWUgPSBqUXVlcnkuY2FtZWxDYXNlKCBuYW1lICksXG5cdFx0XHRpc0N1c3RvbVByb3AgPSByY3VzdG9tUHJvcC50ZXN0KCBuYW1lICk7XG5cblx0XHQvLyBNYWtlIHN1cmUgdGhhdCB3ZSdyZSB3b3JraW5nIHdpdGggdGhlIHJpZ2h0IG5hbWUuIFdlIGRvbid0XG5cdFx0Ly8gd2FudCB0byBtb2RpZnkgdGhlIHZhbHVlIGlmIGl0IGlzIGEgQ1NTIGN1c3RvbSBwcm9wZXJ0eVxuXHRcdC8vIHNpbmNlIHRoZXkgYXJlIHVzZXItZGVmaW5lZC5cblx0XHRpZiAoICFpc0N1c3RvbVByb3AgKSB7XG5cdFx0XHRuYW1lID0gZmluYWxQcm9wTmFtZSggb3JpZ05hbWUgKTtcblx0XHR9XG5cblx0XHQvLyBUcnkgcHJlZml4ZWQgbmFtZSBmb2xsb3dlZCBieSB0aGUgdW5wcmVmaXhlZCBuYW1lXG5cdFx0aG9va3MgPSBqUXVlcnkuY3NzSG9va3NbIG5hbWUgXSB8fCBqUXVlcnkuY3NzSG9va3NbIG9yaWdOYW1lIF07XG5cblx0XHQvLyBJZiBhIGhvb2sgd2FzIHByb3ZpZGVkIGdldCB0aGUgY29tcHV0ZWQgdmFsdWUgZnJvbSB0aGVyZVxuXHRcdGlmICggaG9va3MgJiYgXCJnZXRcIiBpbiBob29rcyApIHtcblx0XHRcdHZhbCA9IGhvb2tzLmdldCggZWxlbSwgdHJ1ZSwgZXh0cmEgKTtcblx0XHR9XG5cblx0XHQvLyBPdGhlcndpc2UsIGlmIGEgd2F5IHRvIGdldCB0aGUgY29tcHV0ZWQgdmFsdWUgZXhpc3RzLCB1c2UgdGhhdFxuXHRcdGlmICggdmFsID09PSB1bmRlZmluZWQgKSB7XG5cdFx0XHR2YWwgPSBjdXJDU1MoIGVsZW0sIG5hbWUsIHN0eWxlcyApO1xuXHRcdH1cblxuXHRcdC8vIENvbnZlcnQgXCJub3JtYWxcIiB0byBjb21wdXRlZCB2YWx1ZVxuXHRcdGlmICggdmFsID09PSBcIm5vcm1hbFwiICYmIG5hbWUgaW4gY3NzTm9ybWFsVHJhbnNmb3JtICkge1xuXHRcdFx0dmFsID0gY3NzTm9ybWFsVHJhbnNmb3JtWyBuYW1lIF07XG5cdFx0fVxuXG5cdFx0Ly8gTWFrZSBudW1lcmljIGlmIGZvcmNlZCBvciBhIHF1YWxpZmllciB3YXMgcHJvdmlkZWQgYW5kIHZhbCBsb29rcyBudW1lcmljXG5cdFx0aWYgKCBleHRyYSA9PT0gXCJcIiB8fCBleHRyYSApIHtcblx0XHRcdG51bSA9IHBhcnNlRmxvYXQoIHZhbCApO1xuXHRcdFx0cmV0dXJuIGV4dHJhID09PSB0cnVlIHx8IGlzRmluaXRlKCBudW0gKSA/IG51bSB8fCAwIDogdmFsO1xuXHRcdH1cblxuXHRcdHJldHVybiB2YWw7XG5cdH1cbn0gKTtcblxualF1ZXJ5LmVhY2goIFsgXCJoZWlnaHRcIiwgXCJ3aWR0aFwiIF0sIGZ1bmN0aW9uKCBpLCBuYW1lICkge1xuXHRqUXVlcnkuY3NzSG9va3NbIG5hbWUgXSA9IHtcblx0XHRnZXQ6IGZ1bmN0aW9uKCBlbGVtLCBjb21wdXRlZCwgZXh0cmEgKSB7XG5cdFx0XHRpZiAoIGNvbXB1dGVkICkge1xuXG5cdFx0XHRcdC8vIENlcnRhaW4gZWxlbWVudHMgY2FuIGhhdmUgZGltZW5zaW9uIGluZm8gaWYgd2UgaW52aXNpYmx5IHNob3cgdGhlbVxuXHRcdFx0XHQvLyBidXQgaXQgbXVzdCBoYXZlIGEgY3VycmVudCBkaXNwbGF5IHN0eWxlIHRoYXQgd291bGQgYmVuZWZpdFxuXHRcdFx0XHRyZXR1cm4gcmRpc3BsYXlzd2FwLnRlc3QoIGpRdWVyeS5jc3MoIGVsZW0sIFwiZGlzcGxheVwiICkgKSAmJlxuXG5cdFx0XHRcdFx0Ly8gU3VwcG9ydDogU2FmYXJpIDgrXG5cdFx0XHRcdFx0Ly8gVGFibGUgY29sdW1ucyBpbiBTYWZhcmkgaGF2ZSBub24temVybyBvZmZzZXRXaWR0aCAmIHplcm9cblx0XHRcdFx0XHQvLyBnZXRCb3VuZGluZ0NsaWVudFJlY3QoKS53aWR0aCB1bmxlc3MgZGlzcGxheSBpcyBjaGFuZ2VkLlxuXHRcdFx0XHRcdC8vIFN1cHBvcnQ6IElFIDw9MTEgb25seVxuXHRcdFx0XHRcdC8vIFJ1bm5pbmcgZ2V0Qm91bmRpbmdDbGllbnRSZWN0IG9uIGEgZGlzY29ubmVjdGVkIG5vZGVcblx0XHRcdFx0XHQvLyBpbiBJRSB0aHJvd3MgYW4gZXJyb3IuXG5cdFx0XHRcdFx0KCAhZWxlbS5nZXRDbGllbnRSZWN0cygpLmxlbmd0aCB8fCAhZWxlbS5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKS53aWR0aCApID9cblx0XHRcdFx0XHRcdHN3YXAoIGVsZW0sIGNzc1Nob3csIGZ1bmN0aW9uKCkge1xuXHRcdFx0XHRcdFx0XHRyZXR1cm4gZ2V0V2lkdGhPckhlaWdodCggZWxlbSwgbmFtZSwgZXh0cmEgKTtcblx0XHRcdFx0XHRcdH0gKSA6XG5cdFx0XHRcdFx0XHRnZXRXaWR0aE9ySGVpZ2h0KCBlbGVtLCBuYW1lLCBleHRyYSApO1xuXHRcdFx0fVxuXHRcdH0sXG5cblx0XHRzZXQ6IGZ1bmN0aW9uKCBlbGVtLCB2YWx1ZSwgZXh0cmEgKSB7XG5cdFx0XHR2YXIgbWF0Y2hlcyxcblx0XHRcdFx0c3R5bGVzID0gZXh0cmEgJiYgZ2V0U3R5bGVzKCBlbGVtICksXG5cdFx0XHRcdHN1YnRyYWN0ID0gZXh0cmEgJiYgYXVnbWVudFdpZHRoT3JIZWlnaHQoXG5cdFx0XHRcdFx0ZWxlbSxcblx0XHRcdFx0XHRuYW1lLFxuXHRcdFx0XHRcdGV4dHJhLFxuXHRcdFx0XHRcdGpRdWVyeS5jc3MoIGVsZW0sIFwiYm94U2l6aW5nXCIsIGZhbHNlLCBzdHlsZXMgKSA9PT0gXCJib3JkZXItYm94XCIsXG5cdFx0XHRcdFx0c3R5bGVzXG5cdFx0XHRcdCk7XG5cblx0XHRcdC8vIENvbnZlcnQgdG8gcGl4ZWxzIGlmIHZhbHVlIGFkanVzdG1lbnQgaXMgbmVlZGVkXG5cdFx0XHRpZiAoIHN1YnRyYWN0ICYmICggbWF0Y2hlcyA9IHJjc3NOdW0uZXhlYyggdmFsdWUgKSApICYmXG5cdFx0XHRcdCggbWF0Y2hlc1sgMyBdIHx8IFwicHhcIiApICE9PSBcInB4XCIgKSB7XG5cblx0XHRcdFx0ZWxlbS5zdHlsZVsgbmFtZSBdID0gdmFsdWU7XG5cdFx0XHRcdHZhbHVlID0galF1ZXJ5LmNzcyggZWxlbSwgbmFtZSApO1xuXHRcdFx0fVxuXG5cdFx0XHRyZXR1cm4gc2V0UG9zaXRpdmVOdW1iZXIoIGVsZW0sIHZhbHVlLCBzdWJ0cmFjdCApO1xuXHRcdH1cblx0fTtcbn0gKTtcblxualF1ZXJ5LmNzc0hvb2tzLm1hcmdpbkxlZnQgPSBhZGRHZXRIb29rSWYoIHN1cHBvcnQucmVsaWFibGVNYXJnaW5MZWZ0LFxuXHRmdW5jdGlvbiggZWxlbSwgY29tcHV0ZWQgKSB7XG5cdFx0aWYgKCBjb21wdXRlZCApIHtcblx0XHRcdHJldHVybiAoIHBhcnNlRmxvYXQoIGN1ckNTUyggZWxlbSwgXCJtYXJnaW5MZWZ0XCIgKSApIHx8XG5cdFx0XHRcdGVsZW0uZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCkubGVmdCAtXG5cdFx0XHRcdFx0c3dhcCggZWxlbSwgeyBtYXJnaW5MZWZ0OiAwIH0sIGZ1bmN0aW9uKCkge1xuXHRcdFx0XHRcdFx0cmV0dXJuIGVsZW0uZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCkubGVmdDtcblx0XHRcdFx0XHR9IClcblx0XHRcdFx0KSArIFwicHhcIjtcblx0XHR9XG5cdH1cbik7XG5cbi8vIFRoZXNlIGhvb2tzIGFyZSB1c2VkIGJ5IGFuaW1hdGUgdG8gZXhwYW5kIHByb3BlcnRpZXNcbmpRdWVyeS5lYWNoKCB7XG5cdG1hcmdpbjogXCJcIixcblx0cGFkZGluZzogXCJcIixcblx0Ym9yZGVyOiBcIldpZHRoXCJcbn0sIGZ1bmN0aW9uKCBwcmVmaXgsIHN1ZmZpeCApIHtcblx0alF1ZXJ5LmNzc0hvb2tzWyBwcmVmaXggKyBzdWZmaXggXSA9IHtcblx0XHRleHBhbmQ6IGZ1bmN0aW9uKCB2YWx1ZSApIHtcblx0XHRcdHZhciBpID0gMCxcblx0XHRcdFx0ZXhwYW5kZWQgPSB7fSxcblxuXHRcdFx0XHQvLyBBc3N1bWVzIGEgc2luZ2xlIG51bWJlciBpZiBub3QgYSBzdHJpbmdcblx0XHRcdFx0cGFydHMgPSB0eXBlb2YgdmFsdWUgPT09IFwic3RyaW5nXCIgPyB2YWx1ZS5zcGxpdCggXCIgXCIgKSA6IFsgdmFsdWUgXTtcblxuXHRcdFx0Zm9yICggOyBpIDwgNDsgaSsrICkge1xuXHRcdFx0XHRleHBhbmRlZFsgcHJlZml4ICsgY3NzRXhwYW5kWyBpIF0gKyBzdWZmaXggXSA9XG5cdFx0XHRcdFx0cGFydHNbIGkgXSB8fCBwYXJ0c1sgaSAtIDIgXSB8fCBwYXJ0c1sgMCBdO1xuXHRcdFx0fVxuXG5cdFx0XHRyZXR1cm4gZXhwYW5kZWQ7XG5cdFx0fVxuXHR9O1xuXG5cdGlmICggIXJtYXJnaW4udGVzdCggcHJlZml4ICkgKSB7XG5cdFx0alF1ZXJ5LmNzc0hvb2tzWyBwcmVmaXggKyBzdWZmaXggXS5zZXQgPSBzZXRQb3NpdGl2ZU51bWJlcjtcblx0fVxufSApO1xuXG5qUXVlcnkuZm4uZXh0ZW5kKCB7XG5cdGNzczogZnVuY3Rpb24oIG5hbWUsIHZhbHVlICkge1xuXHRcdHJldHVybiBhY2Nlc3MoIHRoaXMsIGZ1bmN0aW9uKCBlbGVtLCBuYW1lLCB2YWx1ZSApIHtcblx0XHRcdHZhciBzdHlsZXMsIGxlbixcblx0XHRcdFx0bWFwID0ge30sXG5cdFx0XHRcdGkgPSAwO1xuXG5cdFx0XHRpZiAoIEFycmF5LmlzQXJyYXkoIG5hbWUgKSApIHtcblx0XHRcdFx0c3R5bGVzID0gZ2V0U3R5bGVzKCBlbGVtICk7XG5cdFx0XHRcdGxlbiA9IG5hbWUubGVuZ3RoO1xuXG5cdFx0XHRcdGZvciAoIDsgaSA8IGxlbjsgaSsrICkge1xuXHRcdFx0XHRcdG1hcFsgbmFtZVsgaSBdIF0gPSBqUXVlcnkuY3NzKCBlbGVtLCBuYW1lWyBpIF0sIGZhbHNlLCBzdHlsZXMgKTtcblx0XHRcdFx0fVxuXG5cdFx0XHRcdHJldHVybiBtYXA7XG5cdFx0XHR9XG5cblx0XHRcdHJldHVybiB2YWx1ZSAhPT0gdW5kZWZpbmVkID9cblx0XHRcdFx0alF1ZXJ5LnN0eWxlKCBlbGVtLCBuYW1lLCB2YWx1ZSApIDpcblx0XHRcdFx0alF1ZXJ5LmNzcyggZWxlbSwgbmFtZSApO1xuXHRcdH0sIG5hbWUsIHZhbHVlLCBhcmd1bWVudHMubGVuZ3RoID4gMSApO1xuXHR9XG59ICk7XG5cblxuZnVuY3Rpb24gVHdlZW4oIGVsZW0sIG9wdGlvbnMsIHByb3AsIGVuZCwgZWFzaW5nICkge1xuXHRyZXR1cm4gbmV3IFR3ZWVuLnByb3RvdHlwZS5pbml0KCBlbGVtLCBvcHRpb25zLCBwcm9wLCBlbmQsIGVhc2luZyApO1xufVxualF1ZXJ5LlR3ZWVuID0gVHdlZW47XG5cblR3ZWVuLnByb3RvdHlwZSA9IHtcblx0Y29uc3RydWN0b3I6IFR3ZWVuLFxuXHRpbml0OiBmdW5jdGlvbiggZWxlbSwgb3B0aW9ucywgcHJvcCwgZW5kLCBlYXNpbmcsIHVuaXQgKSB7XG5cdFx0dGhpcy5lbGVtID0gZWxlbTtcblx0XHR0aGlzLnByb3AgPSBwcm9wO1xuXHRcdHRoaXMuZWFzaW5nID0gZWFzaW5nIHx8IGpRdWVyeS5lYXNpbmcuX2RlZmF1bHQ7XG5cdFx0dGhpcy5vcHRpb25zID0gb3B0aW9ucztcblx0XHR0aGlzLnN0YXJ0ID0gdGhpcy5ub3cgPSB0aGlzLmN1cigpO1xuXHRcdHRoaXMuZW5kID0gZW5kO1xuXHRcdHRoaXMudW5pdCA9IHVuaXQgfHwgKCBqUXVlcnkuY3NzTnVtYmVyWyBwcm9wIF0gPyBcIlwiIDogXCJweFwiICk7XG5cdH0sXG5cdGN1cjogZnVuY3Rpb24oKSB7XG5cdFx0dmFyIGhvb2tzID0gVHdlZW4ucHJvcEhvb2tzWyB0aGlzLnByb3AgXTtcblxuXHRcdHJldHVybiBob29rcyAmJiBob29rcy5nZXQgP1xuXHRcdFx0aG9va3MuZ2V0KCB0aGlzICkgOlxuXHRcdFx0VHdlZW4ucHJvcEhvb2tzLl9kZWZhdWx0LmdldCggdGhpcyApO1xuXHR9LFxuXHRydW46IGZ1bmN0aW9uKCBwZXJjZW50ICkge1xuXHRcdHZhciBlYXNlZCxcblx0XHRcdGhvb2tzID0gVHdlZW4ucHJvcEhvb2tzWyB0aGlzLnByb3AgXTtcblxuXHRcdGlmICggdGhpcy5vcHRpb25zLmR1cmF0aW9uICkge1xuXHRcdFx0dGhpcy5wb3MgPSBlYXNlZCA9IGpRdWVyeS5lYXNpbmdbIHRoaXMuZWFzaW5nIF0oXG5cdFx0XHRcdHBlcmNlbnQsIHRoaXMub3B0aW9ucy5kdXJhdGlvbiAqIHBlcmNlbnQsIDAsIDEsIHRoaXMub3B0aW9ucy5kdXJhdGlvblxuXHRcdFx0KTtcblx0XHR9IGVsc2Uge1xuXHRcdFx0dGhpcy5wb3MgPSBlYXNlZCA9IHBlcmNlbnQ7XG5cdFx0fVxuXHRcdHRoaXMubm93ID0gKCB0aGlzLmVuZCAtIHRoaXMuc3RhcnQgKSAqIGVhc2VkICsgdGhpcy5zdGFydDtcblxuXHRcdGlmICggdGhpcy5vcHRpb25zLnN0ZXAgKSB7XG5cdFx0XHR0aGlzLm9wdGlvbnMuc3RlcC5jYWxsKCB0aGlzLmVsZW0sIHRoaXMubm93LCB0aGlzICk7XG5cdFx0fVxuXG5cdFx0aWYgKCBob29rcyAmJiBob29rcy5zZXQgKSB7XG5cdFx0XHRob29rcy5zZXQoIHRoaXMgKTtcblx0XHR9IGVsc2Uge1xuXHRcdFx0VHdlZW4ucHJvcEhvb2tzLl9kZWZhdWx0LnNldCggdGhpcyApO1xuXHRcdH1cblx0XHRyZXR1cm4gdGhpcztcblx0fVxufTtcblxuVHdlZW4ucHJvdG90eXBlLmluaXQucHJvdG90eXBlID0gVHdlZW4ucHJvdG90eXBlO1xuXG5Ud2Vlbi5wcm9wSG9va3MgPSB7XG5cdF9kZWZhdWx0OiB7XG5cdFx0Z2V0OiBmdW5jdGlvbiggdHdlZW4gKSB7XG5cdFx0XHR2YXIgcmVzdWx0O1xuXG5cdFx0XHQvLyBVc2UgYSBwcm9wZXJ0eSBvbiB0aGUgZWxlbWVudCBkaXJlY3RseSB3aGVuIGl0IGlzIG5vdCBhIERPTSBlbGVtZW50LFxuXHRcdFx0Ly8gb3Igd2hlbiB0aGVyZSBpcyBubyBtYXRjaGluZyBzdHlsZSBwcm9wZXJ0eSB0aGF0IGV4aXN0cy5cblx0XHRcdGlmICggdHdlZW4uZWxlbS5ub2RlVHlwZSAhPT0gMSB8fFxuXHRcdFx0XHR0d2Vlbi5lbGVtWyB0d2Vlbi5wcm9wIF0gIT0gbnVsbCAmJiB0d2Vlbi5lbGVtLnN0eWxlWyB0d2Vlbi5wcm9wIF0gPT0gbnVsbCApIHtcblx0XHRcdFx0cmV0dXJuIHR3ZWVuLmVsZW1bIHR3ZWVuLnByb3AgXTtcblx0XHRcdH1cblxuXHRcdFx0Ly8gUGFzc2luZyBhbiBlbXB0eSBzdHJpbmcgYXMgYSAzcmQgcGFyYW1ldGVyIHRvIC5jc3Mgd2lsbCBhdXRvbWF0aWNhbGx5XG5cdFx0XHQvLyBhdHRlbXB0IGEgcGFyc2VGbG9hdCBhbmQgZmFsbGJhY2sgdG8gYSBzdHJpbmcgaWYgdGhlIHBhcnNlIGZhaWxzLlxuXHRcdFx0Ly8gU2ltcGxlIHZhbHVlcyBzdWNoIGFzIFwiMTBweFwiIGFyZSBwYXJzZWQgdG8gRmxvYXQ7XG5cdFx0XHQvLyBjb21wbGV4IHZhbHVlcyBzdWNoIGFzIFwicm90YXRlKDFyYWQpXCIgYXJlIHJldHVybmVkIGFzLWlzLlxuXHRcdFx0cmVzdWx0ID0galF1ZXJ5LmNzcyggdHdlZW4uZWxlbSwgdHdlZW4ucHJvcCwgXCJcIiApO1xuXG5cdFx0XHQvLyBFbXB0eSBzdHJpbmdzLCBudWxsLCB1bmRlZmluZWQgYW5kIFwiYXV0b1wiIGFyZSBjb252ZXJ0ZWQgdG8gMC5cblx0XHRcdHJldHVybiAhcmVzdWx0IHx8IHJlc3VsdCA9PT0gXCJhdXRvXCIgPyAwIDogcmVzdWx0O1xuXHRcdH0sXG5cdFx0c2V0OiBmdW5jdGlvbiggdHdlZW4gKSB7XG5cblx0XHRcdC8vIFVzZSBzdGVwIGhvb2sgZm9yIGJhY2sgY29tcGF0LlxuXHRcdFx0Ly8gVXNlIGNzc0hvb2sgaWYgaXRzIHRoZXJlLlxuXHRcdFx0Ly8gVXNlIC5zdHlsZSBpZiBhdmFpbGFibGUgYW5kIHVzZSBwbGFpbiBwcm9wZXJ0aWVzIHdoZXJlIGF2YWlsYWJsZS5cblx0XHRcdGlmICggalF1ZXJ5LmZ4LnN0ZXBbIHR3ZWVuLnByb3AgXSApIHtcblx0XHRcdFx0alF1ZXJ5LmZ4LnN0ZXBbIHR3ZWVuLnByb3AgXSggdHdlZW4gKTtcblx0XHRcdH0gZWxzZSBpZiAoIHR3ZWVuLmVsZW0ubm9kZVR5cGUgPT09IDEgJiZcblx0XHRcdFx0KCB0d2Vlbi5lbGVtLnN0eWxlWyBqUXVlcnkuY3NzUHJvcHNbIHR3ZWVuLnByb3AgXSBdICE9IG51bGwgfHxcblx0XHRcdFx0XHRqUXVlcnkuY3NzSG9va3NbIHR3ZWVuLnByb3AgXSApICkge1xuXHRcdFx0XHRqUXVlcnkuc3R5bGUoIHR3ZWVuLmVsZW0sIHR3ZWVuLnByb3AsIHR3ZWVuLm5vdyArIHR3ZWVuLnVuaXQgKTtcblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdHR3ZWVuLmVsZW1bIHR3ZWVuLnByb3AgXSA9IHR3ZWVuLm5vdztcblx0XHRcdH1cblx0XHR9XG5cdH1cbn07XG5cbi8vIFN1cHBvcnQ6IElFIDw9OSBvbmx5XG4vLyBQYW5pYyBiYXNlZCBhcHByb2FjaCB0byBzZXR0aW5nIHRoaW5ncyBvbiBkaXNjb25uZWN0ZWQgbm9kZXNcblR3ZWVuLnByb3BIb29rcy5zY3JvbGxUb3AgPSBUd2Vlbi5wcm9wSG9va3Muc2Nyb2xsTGVmdCA9IHtcblx0c2V0OiBmdW5jdGlvbiggdHdlZW4gKSB7XG5cdFx0aWYgKCB0d2Vlbi5lbGVtLm5vZGVUeXBlICYmIHR3ZWVuLmVsZW0ucGFyZW50Tm9kZSApIHtcblx0XHRcdHR3ZWVuLmVsZW1bIHR3ZWVuLnByb3AgXSA9IHR3ZWVuLm5vdztcblx0XHR9XG5cdH1cbn07XG5cbmpRdWVyeS5lYXNpbmcgPSB7XG5cdGxpbmVhcjogZnVuY3Rpb24oIHAgKSB7XG5cdFx0cmV0dXJuIHA7XG5cdH0sXG5cdHN3aW5nOiBmdW5jdGlvbiggcCApIHtcblx0XHRyZXR1cm4gMC41IC0gTWF0aC5jb3MoIHAgKiBNYXRoLlBJICkgLyAyO1xuXHR9LFxuXHRfZGVmYXVsdDogXCJzd2luZ1wiXG59O1xuXG5qUXVlcnkuZnggPSBUd2Vlbi5wcm90b3R5cGUuaW5pdDtcblxuLy8gQmFjayBjb21wYXQgPDEuOCBleHRlbnNpb24gcG9pbnRcbmpRdWVyeS5meC5zdGVwID0ge307XG5cblxuXG5cbnZhclxuXHRmeE5vdywgaW5Qcm9ncmVzcyxcblx0cmZ4dHlwZXMgPSAvXig/OnRvZ2dsZXxzaG93fGhpZGUpJC8sXG5cdHJydW4gPSAvcXVldWVIb29rcyQvO1xuXG5mdW5jdGlvbiBzY2hlZHVsZSgpIHtcblx0aWYgKCBpblByb2dyZXNzICkge1xuXHRcdGlmICggZG9jdW1lbnQuaGlkZGVuID09PSBmYWxzZSAmJiB3aW5kb3cucmVxdWVzdEFuaW1hdGlvbkZyYW1lICkge1xuXHRcdFx0d2luZG93LnJlcXVlc3RBbmltYXRpb25GcmFtZSggc2NoZWR1bGUgKTtcblx0XHR9IGVsc2Uge1xuXHRcdFx0d2luZG93LnNldFRpbWVvdXQoIHNjaGVkdWxlLCBqUXVlcnkuZnguaW50ZXJ2YWwgKTtcblx0XHR9XG5cblx0XHRqUXVlcnkuZngudGljaygpO1xuXHR9XG59XG5cbi8vIEFuaW1hdGlvbnMgY3JlYXRlZCBzeW5jaHJvbm91c2x5IHdpbGwgcnVuIHN5bmNocm9ub3VzbHlcbmZ1bmN0aW9uIGNyZWF0ZUZ4Tm93KCkge1xuXHR3aW5kb3cuc2V0VGltZW91dCggZnVuY3Rpb24oKSB7XG5cdFx0ZnhOb3cgPSB1bmRlZmluZWQ7XG5cdH0gKTtcblx0cmV0dXJuICggZnhOb3cgPSBqUXVlcnkubm93KCkgKTtcbn1cblxuLy8gR2VuZXJhdGUgcGFyYW1ldGVycyB0byBjcmVhdGUgYSBzdGFuZGFyZCBhbmltYXRpb25cbmZ1bmN0aW9uIGdlbkZ4KCB0eXBlLCBpbmNsdWRlV2lkdGggKSB7XG5cdHZhciB3aGljaCxcblx0XHRpID0gMCxcblx0XHRhdHRycyA9IHsgaGVpZ2h0OiB0eXBlIH07XG5cblx0Ly8gSWYgd2UgaW5jbHVkZSB3aWR0aCwgc3RlcCB2YWx1ZSBpcyAxIHRvIGRvIGFsbCBjc3NFeHBhbmQgdmFsdWVzLFxuXHQvLyBvdGhlcndpc2Ugc3RlcCB2YWx1ZSBpcyAyIHRvIHNraXAgb3ZlciBMZWZ0IGFuZCBSaWdodFxuXHRpbmNsdWRlV2lkdGggPSBpbmNsdWRlV2lkdGggPyAxIDogMDtcblx0Zm9yICggOyBpIDwgNDsgaSArPSAyIC0gaW5jbHVkZVdpZHRoICkge1xuXHRcdHdoaWNoID0gY3NzRXhwYW5kWyBpIF07XG5cdFx0YXR0cnNbIFwibWFyZ2luXCIgKyB3aGljaCBdID0gYXR0cnNbIFwicGFkZGluZ1wiICsgd2hpY2ggXSA9IHR5cGU7XG5cdH1cblxuXHRpZiAoIGluY2x1ZGVXaWR0aCApIHtcblx0XHRhdHRycy5vcGFjaXR5ID0gYXR0cnMud2lkdGggPSB0eXBlO1xuXHR9XG5cblx0cmV0dXJuIGF0dHJzO1xufVxuXG5mdW5jdGlvbiBjcmVhdGVUd2VlbiggdmFsdWUsIHByb3AsIGFuaW1hdGlvbiApIHtcblx0dmFyIHR3ZWVuLFxuXHRcdGNvbGxlY3Rpb24gPSAoIEFuaW1hdGlvbi50d2VlbmVyc1sgcHJvcCBdIHx8IFtdICkuY29uY2F0KCBBbmltYXRpb24udHdlZW5lcnNbIFwiKlwiIF0gKSxcblx0XHRpbmRleCA9IDAsXG5cdFx0bGVuZ3RoID0gY29sbGVjdGlvbi5sZW5ndGg7XG5cdGZvciAoIDsgaW5kZXggPCBsZW5ndGg7IGluZGV4KysgKSB7XG5cdFx0aWYgKCAoIHR3ZWVuID0gY29sbGVjdGlvblsgaW5kZXggXS5jYWxsKCBhbmltYXRpb24sIHByb3AsIHZhbHVlICkgKSApIHtcblxuXHRcdFx0Ly8gV2UncmUgZG9uZSB3aXRoIHRoaXMgcHJvcGVydHlcblx0XHRcdHJldHVybiB0d2Vlbjtcblx0XHR9XG5cdH1cbn1cblxuZnVuY3Rpb24gZGVmYXVsdFByZWZpbHRlciggZWxlbSwgcHJvcHMsIG9wdHMgKSB7XG5cdHZhciBwcm9wLCB2YWx1ZSwgdG9nZ2xlLCBob29rcywgb2xkZmlyZSwgcHJvcFR3ZWVuLCByZXN0b3JlRGlzcGxheSwgZGlzcGxheSxcblx0XHRpc0JveCA9IFwid2lkdGhcIiBpbiBwcm9wcyB8fCBcImhlaWdodFwiIGluIHByb3BzLFxuXHRcdGFuaW0gPSB0aGlzLFxuXHRcdG9yaWcgPSB7fSxcblx0XHRzdHlsZSA9IGVsZW0uc3R5bGUsXG5cdFx0aGlkZGVuID0gZWxlbS5ub2RlVHlwZSAmJiBpc0hpZGRlbldpdGhpblRyZWUoIGVsZW0gKSxcblx0XHRkYXRhU2hvdyA9IGRhdGFQcml2LmdldCggZWxlbSwgXCJmeHNob3dcIiApO1xuXG5cdC8vIFF1ZXVlLXNraXBwaW5nIGFuaW1hdGlvbnMgaGlqYWNrIHRoZSBmeCBob29rc1xuXHRpZiAoICFvcHRzLnF1ZXVlICkge1xuXHRcdGhvb2tzID0galF1ZXJ5Ll9xdWV1ZUhvb2tzKCBlbGVtLCBcImZ4XCIgKTtcblx0XHRpZiAoIGhvb2tzLnVucXVldWVkID09IG51bGwgKSB7XG5cdFx0XHRob29rcy51bnF1ZXVlZCA9IDA7XG5cdFx0XHRvbGRmaXJlID0gaG9va3MuZW1wdHkuZmlyZTtcblx0XHRcdGhvb2tzLmVtcHR5LmZpcmUgPSBmdW5jdGlvbigpIHtcblx0XHRcdFx0aWYgKCAhaG9va3MudW5xdWV1ZWQgKSB7XG5cdFx0XHRcdFx0b2xkZmlyZSgpO1xuXHRcdFx0XHR9XG5cdFx0XHR9O1xuXHRcdH1cblx0XHRob29rcy51bnF1ZXVlZCsrO1xuXG5cdFx0YW5pbS5hbHdheXMoIGZ1bmN0aW9uKCkge1xuXG5cdFx0XHQvLyBFbnN1cmUgdGhlIGNvbXBsZXRlIGhhbmRsZXIgaXMgY2FsbGVkIGJlZm9yZSB0aGlzIGNvbXBsZXRlc1xuXHRcdFx0YW5pbS5hbHdheXMoIGZ1bmN0aW9uKCkge1xuXHRcdFx0XHRob29rcy51bnF1ZXVlZC0tO1xuXHRcdFx0XHRpZiAoICFqUXVlcnkucXVldWUoIGVsZW0sIFwiZnhcIiApLmxlbmd0aCApIHtcblx0XHRcdFx0XHRob29rcy5lbXB0eS5maXJlKCk7XG5cdFx0XHRcdH1cblx0XHRcdH0gKTtcblx0XHR9ICk7XG5cdH1cblxuXHQvLyBEZXRlY3Qgc2hvdy9oaWRlIGFuaW1hdGlvbnNcblx0Zm9yICggcHJvcCBpbiBwcm9wcyApIHtcblx0XHR2YWx1ZSA9IHByb3BzWyBwcm9wIF07XG5cdFx0aWYgKCByZnh0eXBlcy50ZXN0KCB2YWx1ZSApICkge1xuXHRcdFx0ZGVsZXRlIHByb3BzWyBwcm9wIF07XG5cdFx0XHR0b2dnbGUgPSB0b2dnbGUgfHwgdmFsdWUgPT09IFwidG9nZ2xlXCI7XG5cdFx0XHRpZiAoIHZhbHVlID09PSAoIGhpZGRlbiA/IFwiaGlkZVwiIDogXCJzaG93XCIgKSApIHtcblxuXHRcdFx0XHQvLyBQcmV0ZW5kIHRvIGJlIGhpZGRlbiBpZiB0aGlzIGlzIGEgXCJzaG93XCIgYW5kXG5cdFx0XHRcdC8vIHRoZXJlIGlzIHN0aWxsIGRhdGEgZnJvbSBhIHN0b3BwZWQgc2hvdy9oaWRlXG5cdFx0XHRcdGlmICggdmFsdWUgPT09IFwic2hvd1wiICYmIGRhdGFTaG93ICYmIGRhdGFTaG93WyBwcm9wIF0gIT09IHVuZGVmaW5lZCApIHtcblx0XHRcdFx0XHRoaWRkZW4gPSB0cnVlO1xuXG5cdFx0XHRcdC8vIElnbm9yZSBhbGwgb3RoZXIgbm8tb3Agc2hvdy9oaWRlIGRhdGFcblx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRjb250aW51ZTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdFx0b3JpZ1sgcHJvcCBdID0gZGF0YVNob3cgJiYgZGF0YVNob3dbIHByb3AgXSB8fCBqUXVlcnkuc3R5bGUoIGVsZW0sIHByb3AgKTtcblx0XHR9XG5cdH1cblxuXHQvLyBCYWlsIG91dCBpZiB0aGlzIGlzIGEgbm8tb3AgbGlrZSAuaGlkZSgpLmhpZGUoKVxuXHRwcm9wVHdlZW4gPSAhalF1ZXJ5LmlzRW1wdHlPYmplY3QoIHByb3BzICk7XG5cdGlmICggIXByb3BUd2VlbiAmJiBqUXVlcnkuaXNFbXB0eU9iamVjdCggb3JpZyApICkge1xuXHRcdHJldHVybjtcblx0fVxuXG5cdC8vIFJlc3RyaWN0IFwib3ZlcmZsb3dcIiBhbmQgXCJkaXNwbGF5XCIgc3R5bGVzIGR1cmluZyBib3ggYW5pbWF0aW9uc1xuXHRpZiAoIGlzQm94ICYmIGVsZW0ubm9kZVR5cGUgPT09IDEgKSB7XG5cblx0XHQvLyBTdXBwb3J0OiBJRSA8PTkgLSAxMSwgRWRnZSAxMiAtIDEzXG5cdFx0Ly8gUmVjb3JkIGFsbCAzIG92ZXJmbG93IGF0dHJpYnV0ZXMgYmVjYXVzZSBJRSBkb2VzIG5vdCBpbmZlciB0aGUgc2hvcnRoYW5kXG5cdFx0Ly8gZnJvbSBpZGVudGljYWxseS12YWx1ZWQgb3ZlcmZsb3dYIGFuZCBvdmVyZmxvd1lcblx0XHRvcHRzLm92ZXJmbG93ID0gWyBzdHlsZS5vdmVyZmxvdywgc3R5bGUub3ZlcmZsb3dYLCBzdHlsZS5vdmVyZmxvd1kgXTtcblxuXHRcdC8vIElkZW50aWZ5IGEgZGlzcGxheSB0eXBlLCBwcmVmZXJyaW5nIG9sZCBzaG93L2hpZGUgZGF0YSBvdmVyIHRoZSBDU1MgY2FzY2FkZVxuXHRcdHJlc3RvcmVEaXNwbGF5ID0gZGF0YVNob3cgJiYgZGF0YVNob3cuZGlzcGxheTtcblx0XHRpZiAoIHJlc3RvcmVEaXNwbGF5ID09IG51bGwgKSB7XG5cdFx0XHRyZXN0b3JlRGlzcGxheSA9IGRhdGFQcml2LmdldCggZWxlbSwgXCJkaXNwbGF5XCIgKTtcblx0XHR9XG5cdFx0ZGlzcGxheSA9IGpRdWVyeS5jc3MoIGVsZW0sIFwiZGlzcGxheVwiICk7XG5cdFx0aWYgKCBkaXNwbGF5ID09PSBcIm5vbmVcIiApIHtcblx0XHRcdGlmICggcmVzdG9yZURpc3BsYXkgKSB7XG5cdFx0XHRcdGRpc3BsYXkgPSByZXN0b3JlRGlzcGxheTtcblx0XHRcdH0gZWxzZSB7XG5cblx0XHRcdFx0Ly8gR2V0IG5vbmVtcHR5IHZhbHVlKHMpIGJ5IHRlbXBvcmFyaWx5IGZvcmNpbmcgdmlzaWJpbGl0eVxuXHRcdFx0XHRzaG93SGlkZSggWyBlbGVtIF0sIHRydWUgKTtcblx0XHRcdFx0cmVzdG9yZURpc3BsYXkgPSBlbGVtLnN0eWxlLmRpc3BsYXkgfHwgcmVzdG9yZURpc3BsYXk7XG5cdFx0XHRcdGRpc3BsYXkgPSBqUXVlcnkuY3NzKCBlbGVtLCBcImRpc3BsYXlcIiApO1xuXHRcdFx0XHRzaG93SGlkZSggWyBlbGVtIF0gKTtcblx0XHRcdH1cblx0XHR9XG5cblx0XHQvLyBBbmltYXRlIGlubGluZSBlbGVtZW50cyBhcyBpbmxpbmUtYmxvY2tcblx0XHRpZiAoIGRpc3BsYXkgPT09IFwiaW5saW5lXCIgfHwgZGlzcGxheSA9PT0gXCJpbmxpbmUtYmxvY2tcIiAmJiByZXN0b3JlRGlzcGxheSAhPSBudWxsICkge1xuXHRcdFx0aWYgKCBqUXVlcnkuY3NzKCBlbGVtLCBcImZsb2F0XCIgKSA9PT0gXCJub25lXCIgKSB7XG5cblx0XHRcdFx0Ly8gUmVzdG9yZSB0aGUgb3JpZ2luYWwgZGlzcGxheSB2YWx1ZSBhdCB0aGUgZW5kIG9mIHB1cmUgc2hvdy9oaWRlIGFuaW1hdGlvbnNcblx0XHRcdFx0aWYgKCAhcHJvcFR3ZWVuICkge1xuXHRcdFx0XHRcdGFuaW0uZG9uZSggZnVuY3Rpb24oKSB7XG5cdFx0XHRcdFx0XHRzdHlsZS5kaXNwbGF5ID0gcmVzdG9yZURpc3BsYXk7XG5cdFx0XHRcdFx0fSApO1xuXHRcdFx0XHRcdGlmICggcmVzdG9yZURpc3BsYXkgPT0gbnVsbCApIHtcblx0XHRcdFx0XHRcdGRpc3BsYXkgPSBzdHlsZS5kaXNwbGF5O1xuXHRcdFx0XHRcdFx0cmVzdG9yZURpc3BsYXkgPSBkaXNwbGF5ID09PSBcIm5vbmVcIiA/IFwiXCIgOiBkaXNwbGF5O1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXHRcdFx0XHRzdHlsZS5kaXNwbGF5ID0gXCJpbmxpbmUtYmxvY2tcIjtcblx0XHRcdH1cblx0XHR9XG5cdH1cblxuXHRpZiAoIG9wdHMub3ZlcmZsb3cgKSB7XG5cdFx0c3R5bGUub3ZlcmZsb3cgPSBcImhpZGRlblwiO1xuXHRcdGFuaW0uYWx3YXlzKCBmdW5jdGlvbigpIHtcblx0XHRcdHN0eWxlLm92ZXJmbG93ID0gb3B0cy5vdmVyZmxvd1sgMCBdO1xuXHRcdFx0c3R5bGUub3ZlcmZsb3dYID0gb3B0cy5vdmVyZmxvd1sgMSBdO1xuXHRcdFx0c3R5bGUub3ZlcmZsb3dZID0gb3B0cy5vdmVyZmxvd1sgMiBdO1xuXHRcdH0gKTtcblx0fVxuXG5cdC8vIEltcGxlbWVudCBzaG93L2hpZGUgYW5pbWF0aW9uc1xuXHRwcm9wVHdlZW4gPSBmYWxzZTtcblx0Zm9yICggcHJvcCBpbiBvcmlnICkge1xuXG5cdFx0Ly8gR2VuZXJhbCBzaG93L2hpZGUgc2V0dXAgZm9yIHRoaXMgZWxlbWVudCBhbmltYXRpb25cblx0XHRpZiAoICFwcm9wVHdlZW4gKSB7XG5cdFx0XHRpZiAoIGRhdGFTaG93ICkge1xuXHRcdFx0XHRpZiAoIFwiaGlkZGVuXCIgaW4gZGF0YVNob3cgKSB7XG5cdFx0XHRcdFx0aGlkZGVuID0gZGF0YVNob3cuaGlkZGVuO1xuXHRcdFx0XHR9XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRkYXRhU2hvdyA9IGRhdGFQcml2LmFjY2VzcyggZWxlbSwgXCJmeHNob3dcIiwgeyBkaXNwbGF5OiByZXN0b3JlRGlzcGxheSB9ICk7XG5cdFx0XHR9XG5cblx0XHRcdC8vIFN0b3JlIGhpZGRlbi92aXNpYmxlIGZvciB0b2dnbGUgc28gYC5zdG9wKCkudG9nZ2xlKClgIFwicmV2ZXJzZXNcIlxuXHRcdFx0aWYgKCB0b2dnbGUgKSB7XG5cdFx0XHRcdGRhdGFTaG93LmhpZGRlbiA9ICFoaWRkZW47XG5cdFx0XHR9XG5cblx0XHRcdC8vIFNob3cgZWxlbWVudHMgYmVmb3JlIGFuaW1hdGluZyB0aGVtXG5cdFx0XHRpZiAoIGhpZGRlbiApIHtcblx0XHRcdFx0c2hvd0hpZGUoIFsgZWxlbSBdLCB0cnVlICk7XG5cdFx0XHR9XG5cblx0XHRcdC8qIGVzbGludC1kaXNhYmxlIG5vLWxvb3AtZnVuYyAqL1xuXG5cdFx0XHRhbmltLmRvbmUoIGZ1bmN0aW9uKCkge1xuXG5cdFx0XHQvKiBlc2xpbnQtZW5hYmxlIG5vLWxvb3AtZnVuYyAqL1xuXG5cdFx0XHRcdC8vIFRoZSBmaW5hbCBzdGVwIG9mIGEgXCJoaWRlXCIgYW5pbWF0aW9uIGlzIGFjdHVhbGx5IGhpZGluZyB0aGUgZWxlbWVudFxuXHRcdFx0XHRpZiAoICFoaWRkZW4gKSB7XG5cdFx0XHRcdFx0c2hvd0hpZGUoIFsgZWxlbSBdICk7XG5cdFx0XHRcdH1cblx0XHRcdFx0ZGF0YVByaXYucmVtb3ZlKCBlbGVtLCBcImZ4c2hvd1wiICk7XG5cdFx0XHRcdGZvciAoIHByb3AgaW4gb3JpZyApIHtcblx0XHRcdFx0XHRqUXVlcnkuc3R5bGUoIGVsZW0sIHByb3AsIG9yaWdbIHByb3AgXSApO1xuXHRcdFx0XHR9XG5cdFx0XHR9ICk7XG5cdFx0fVxuXG5cdFx0Ly8gUGVyLXByb3BlcnR5IHNldHVwXG5cdFx0cHJvcFR3ZWVuID0gY3JlYXRlVHdlZW4oIGhpZGRlbiA/IGRhdGFTaG93WyBwcm9wIF0gOiAwLCBwcm9wLCBhbmltICk7XG5cdFx0aWYgKCAhKCBwcm9wIGluIGRhdGFTaG93ICkgKSB7XG5cdFx0XHRkYXRhU2hvd1sgcHJvcCBdID0gcHJvcFR3ZWVuLnN0YXJ0O1xuXHRcdFx0aWYgKCBoaWRkZW4gKSB7XG5cdFx0XHRcdHByb3BUd2Vlbi5lbmQgPSBwcm9wVHdlZW4uc3RhcnQ7XG5cdFx0XHRcdHByb3BUd2Vlbi5zdGFydCA9IDA7XG5cdFx0XHR9XG5cdFx0fVxuXHR9XG59XG5cbmZ1bmN0aW9uIHByb3BGaWx0ZXIoIHByb3BzLCBzcGVjaWFsRWFzaW5nICkge1xuXHR2YXIgaW5kZXgsIG5hbWUsIGVhc2luZywgdmFsdWUsIGhvb2tzO1xuXG5cdC8vIGNhbWVsQ2FzZSwgc3BlY2lhbEVhc2luZyBhbmQgZXhwYW5kIGNzc0hvb2sgcGFzc1xuXHRmb3IgKCBpbmRleCBpbiBwcm9wcyApIHtcblx0XHRuYW1lID0galF1ZXJ5LmNhbWVsQ2FzZSggaW5kZXggKTtcblx0XHRlYXNpbmcgPSBzcGVjaWFsRWFzaW5nWyBuYW1lIF07XG5cdFx0dmFsdWUgPSBwcm9wc1sgaW5kZXggXTtcblx0XHRpZiAoIEFycmF5LmlzQXJyYXkoIHZhbHVlICkgKSB7XG5cdFx0XHRlYXNpbmcgPSB2YWx1ZVsgMSBdO1xuXHRcdFx0dmFsdWUgPSBwcm9wc1sgaW5kZXggXSA9IHZhbHVlWyAwIF07XG5cdFx0fVxuXG5cdFx0aWYgKCBpbmRleCAhPT0gbmFtZSApIHtcblx0XHRcdHByb3BzWyBuYW1lIF0gPSB2YWx1ZTtcblx0XHRcdGRlbGV0ZSBwcm9wc1sgaW5kZXggXTtcblx0XHR9XG5cblx0XHRob29rcyA9IGpRdWVyeS5jc3NIb29rc1sgbmFtZSBdO1xuXHRcdGlmICggaG9va3MgJiYgXCJleHBhbmRcIiBpbiBob29rcyApIHtcblx0XHRcdHZhbHVlID0gaG9va3MuZXhwYW5kKCB2YWx1ZSApO1xuXHRcdFx0ZGVsZXRlIHByb3BzWyBuYW1lIF07XG5cblx0XHRcdC8vIE5vdCBxdWl0ZSAkLmV4dGVuZCwgdGhpcyB3b24ndCBvdmVyd3JpdGUgZXhpc3Rpbmcga2V5cy5cblx0XHRcdC8vIFJldXNpbmcgJ2luZGV4JyBiZWNhdXNlIHdlIGhhdmUgdGhlIGNvcnJlY3QgXCJuYW1lXCJcblx0XHRcdGZvciAoIGluZGV4IGluIHZhbHVlICkge1xuXHRcdFx0XHRpZiAoICEoIGluZGV4IGluIHByb3BzICkgKSB7XG5cdFx0XHRcdFx0cHJvcHNbIGluZGV4IF0gPSB2YWx1ZVsgaW5kZXggXTtcblx0XHRcdFx0XHRzcGVjaWFsRWFzaW5nWyBpbmRleCBdID0gZWFzaW5nO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fSBlbHNlIHtcblx0XHRcdHNwZWNpYWxFYXNpbmdbIG5hbWUgXSA9IGVhc2luZztcblx0XHR9XG5cdH1cbn1cblxuZnVuY3Rpb24gQW5pbWF0aW9uKCBlbGVtLCBwcm9wZXJ0aWVzLCBvcHRpb25zICkge1xuXHR2YXIgcmVzdWx0LFxuXHRcdHN0b3BwZWQsXG5cdFx0aW5kZXggPSAwLFxuXHRcdGxlbmd0aCA9IEFuaW1hdGlvbi5wcmVmaWx0ZXJzLmxlbmd0aCxcblx0XHRkZWZlcnJlZCA9IGpRdWVyeS5EZWZlcnJlZCgpLmFsd2F5cyggZnVuY3Rpb24oKSB7XG5cblx0XHRcdC8vIERvbid0IG1hdGNoIGVsZW0gaW4gdGhlIDphbmltYXRlZCBzZWxlY3RvclxuXHRcdFx0ZGVsZXRlIHRpY2suZWxlbTtcblx0XHR9ICksXG5cdFx0dGljayA9IGZ1bmN0aW9uKCkge1xuXHRcdFx0aWYgKCBzdG9wcGVkICkge1xuXHRcdFx0XHRyZXR1cm4gZmFsc2U7XG5cdFx0XHR9XG5cdFx0XHR2YXIgY3VycmVudFRpbWUgPSBmeE5vdyB8fCBjcmVhdGVGeE5vdygpLFxuXHRcdFx0XHRyZW1haW5pbmcgPSBNYXRoLm1heCggMCwgYW5pbWF0aW9uLnN0YXJ0VGltZSArIGFuaW1hdGlvbi5kdXJhdGlvbiAtIGN1cnJlbnRUaW1lICksXG5cblx0XHRcdFx0Ly8gU3VwcG9ydDogQW5kcm9pZCAyLjMgb25seVxuXHRcdFx0XHQvLyBBcmNoYWljIGNyYXNoIGJ1ZyB3b24ndCBhbGxvdyB1cyB0byB1c2UgYDEgLSAoIDAuNSB8fCAwIClgICgjMTI0OTcpXG5cdFx0XHRcdHRlbXAgPSByZW1haW5pbmcgLyBhbmltYXRpb24uZHVyYXRpb24gfHwgMCxcblx0XHRcdFx0cGVyY2VudCA9IDEgLSB0ZW1wLFxuXHRcdFx0XHRpbmRleCA9IDAsXG5cdFx0XHRcdGxlbmd0aCA9IGFuaW1hdGlvbi50d2VlbnMubGVuZ3RoO1xuXG5cdFx0XHRmb3IgKCA7IGluZGV4IDwgbGVuZ3RoOyBpbmRleCsrICkge1xuXHRcdFx0XHRhbmltYXRpb24udHdlZW5zWyBpbmRleCBdLnJ1biggcGVyY2VudCApO1xuXHRcdFx0fVxuXG5cdFx0XHRkZWZlcnJlZC5ub3RpZnlXaXRoKCBlbGVtLCBbIGFuaW1hdGlvbiwgcGVyY2VudCwgcmVtYWluaW5nIF0gKTtcblxuXHRcdFx0Ly8gSWYgdGhlcmUncyBtb3JlIHRvIGRvLCB5aWVsZFxuXHRcdFx0aWYgKCBwZXJjZW50IDwgMSAmJiBsZW5ndGggKSB7XG5cdFx0XHRcdHJldHVybiByZW1haW5pbmc7XG5cdFx0XHR9XG5cblx0XHRcdC8vIElmIHRoaXMgd2FzIGFuIGVtcHR5IGFuaW1hdGlvbiwgc3ludGhlc2l6ZSBhIGZpbmFsIHByb2dyZXNzIG5vdGlmaWNhdGlvblxuXHRcdFx0aWYgKCAhbGVuZ3RoICkge1xuXHRcdFx0XHRkZWZlcnJlZC5ub3RpZnlXaXRoKCBlbGVtLCBbIGFuaW1hdGlvbiwgMSwgMCBdICk7XG5cdFx0XHR9XG5cblx0XHRcdC8vIFJlc29sdmUgdGhlIGFuaW1hdGlvbiBhbmQgcmVwb3J0IGl0cyBjb25jbHVzaW9uXG5cdFx0XHRkZWZlcnJlZC5yZXNvbHZlV2l0aCggZWxlbSwgWyBhbmltYXRpb24gXSApO1xuXHRcdFx0cmV0dXJuIGZhbHNlO1xuXHRcdH0sXG5cdFx0YW5pbWF0aW9uID0gZGVmZXJyZWQucHJvbWlzZSgge1xuXHRcdFx0ZWxlbTogZWxlbSxcblx0XHRcdHByb3BzOiBqUXVlcnkuZXh0ZW5kKCB7fSwgcHJvcGVydGllcyApLFxuXHRcdFx0b3B0czogalF1ZXJ5LmV4dGVuZCggdHJ1ZSwge1xuXHRcdFx0XHRzcGVjaWFsRWFzaW5nOiB7fSxcblx0XHRcdFx0ZWFzaW5nOiBqUXVlcnkuZWFzaW5nLl9kZWZhdWx0XG5cdFx0XHR9LCBvcHRpb25zICksXG5cdFx0XHRvcmlnaW5hbFByb3BlcnRpZXM6IHByb3BlcnRpZXMsXG5cdFx0XHRvcmlnaW5hbE9wdGlvbnM6IG9wdGlvbnMsXG5cdFx0XHRzdGFydFRpbWU6IGZ4Tm93IHx8IGNyZWF0ZUZ4Tm93KCksXG5cdFx0XHRkdXJhdGlvbjogb3B0aW9ucy5kdXJhdGlvbixcblx0XHRcdHR3ZWVuczogW10sXG5cdFx0XHRjcmVhdGVUd2VlbjogZnVuY3Rpb24oIHByb3AsIGVuZCApIHtcblx0XHRcdFx0dmFyIHR3ZWVuID0galF1ZXJ5LlR3ZWVuKCBlbGVtLCBhbmltYXRpb24ub3B0cywgcHJvcCwgZW5kLFxuXHRcdFx0XHRcdFx0YW5pbWF0aW9uLm9wdHMuc3BlY2lhbEVhc2luZ1sgcHJvcCBdIHx8IGFuaW1hdGlvbi5vcHRzLmVhc2luZyApO1xuXHRcdFx0XHRhbmltYXRpb24udHdlZW5zLnB1c2goIHR3ZWVuICk7XG5cdFx0XHRcdHJldHVybiB0d2Vlbjtcblx0XHRcdH0sXG5cdFx0XHRzdG9wOiBmdW5jdGlvbiggZ290b0VuZCApIHtcblx0XHRcdFx0dmFyIGluZGV4ID0gMCxcblxuXHRcdFx0XHRcdC8vIElmIHdlIGFyZSBnb2luZyB0byB0aGUgZW5kLCB3ZSB3YW50IHRvIHJ1biBhbGwgdGhlIHR3ZWVuc1xuXHRcdFx0XHRcdC8vIG90aGVyd2lzZSB3ZSBza2lwIHRoaXMgcGFydFxuXHRcdFx0XHRcdGxlbmd0aCA9IGdvdG9FbmQgPyBhbmltYXRpb24udHdlZW5zLmxlbmd0aCA6IDA7XG5cdFx0XHRcdGlmICggc3RvcHBlZCApIHtcblx0XHRcdFx0XHRyZXR1cm4gdGhpcztcblx0XHRcdFx0fVxuXHRcdFx0XHRzdG9wcGVkID0gdHJ1ZTtcblx0XHRcdFx0Zm9yICggOyBpbmRleCA8IGxlbmd0aDsgaW5kZXgrKyApIHtcblx0XHRcdFx0XHRhbmltYXRpb24udHdlZW5zWyBpbmRleCBdLnJ1biggMSApO1xuXHRcdFx0XHR9XG5cblx0XHRcdFx0Ly8gUmVzb2x2ZSB3aGVuIHdlIHBsYXllZCB0aGUgbGFzdCBmcmFtZTsgb3RoZXJ3aXNlLCByZWplY3Rcblx0XHRcdFx0aWYgKCBnb3RvRW5kICkge1xuXHRcdFx0XHRcdGRlZmVycmVkLm5vdGlmeVdpdGgoIGVsZW0sIFsgYW5pbWF0aW9uLCAxLCAwIF0gKTtcblx0XHRcdFx0XHRkZWZlcnJlZC5yZXNvbHZlV2l0aCggZWxlbSwgWyBhbmltYXRpb24sIGdvdG9FbmQgXSApO1xuXHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdGRlZmVycmVkLnJlamVjdFdpdGgoIGVsZW0sIFsgYW5pbWF0aW9uLCBnb3RvRW5kIF0gKTtcblx0XHRcdFx0fVxuXHRcdFx0XHRyZXR1cm4gdGhpcztcblx0XHRcdH1cblx0XHR9ICksXG5cdFx0cHJvcHMgPSBhbmltYXRpb24ucHJvcHM7XG5cblx0cHJvcEZpbHRlciggcHJvcHMsIGFuaW1hdGlvbi5vcHRzLnNwZWNpYWxFYXNpbmcgKTtcblxuXHRmb3IgKCA7IGluZGV4IDwgbGVuZ3RoOyBpbmRleCsrICkge1xuXHRcdHJlc3VsdCA9IEFuaW1hdGlvbi5wcmVmaWx0ZXJzWyBpbmRleCBdLmNhbGwoIGFuaW1hdGlvbiwgZWxlbSwgcHJvcHMsIGFuaW1hdGlvbi5vcHRzICk7XG5cdFx0aWYgKCByZXN1bHQgKSB7XG5cdFx0XHRpZiAoIGpRdWVyeS5pc0Z1bmN0aW9uKCByZXN1bHQuc3RvcCApICkge1xuXHRcdFx0XHRqUXVlcnkuX3F1ZXVlSG9va3MoIGFuaW1hdGlvbi5lbGVtLCBhbmltYXRpb24ub3B0cy5xdWV1ZSApLnN0b3AgPVxuXHRcdFx0XHRcdGpRdWVyeS5wcm94eSggcmVzdWx0LnN0b3AsIHJlc3VsdCApO1xuXHRcdFx0fVxuXHRcdFx0cmV0dXJuIHJlc3VsdDtcblx0XHR9XG5cdH1cblxuXHRqUXVlcnkubWFwKCBwcm9wcywgY3JlYXRlVHdlZW4sIGFuaW1hdGlvbiApO1xuXG5cdGlmICggalF1ZXJ5LmlzRnVuY3Rpb24oIGFuaW1hdGlvbi5vcHRzLnN0YXJ0ICkgKSB7XG5cdFx0YW5pbWF0aW9uLm9wdHMuc3RhcnQuY2FsbCggZWxlbSwgYW5pbWF0aW9uICk7XG5cdH1cblxuXHQvLyBBdHRhY2ggY2FsbGJhY2tzIGZyb20gb3B0aW9uc1xuXHRhbmltYXRpb25cblx0XHQucHJvZ3Jlc3MoIGFuaW1hdGlvbi5vcHRzLnByb2dyZXNzIClcblx0XHQuZG9uZSggYW5pbWF0aW9uLm9wdHMuZG9uZSwgYW5pbWF0aW9uLm9wdHMuY29tcGxldGUgKVxuXHRcdC5mYWlsKCBhbmltYXRpb24ub3B0cy5mYWlsIClcblx0XHQuYWx3YXlzKCBhbmltYXRpb24ub3B0cy5hbHdheXMgKTtcblxuXHRqUXVlcnkuZngudGltZXIoXG5cdFx0alF1ZXJ5LmV4dGVuZCggdGljaywge1xuXHRcdFx0ZWxlbTogZWxlbSxcblx0XHRcdGFuaW06IGFuaW1hdGlvbixcblx0XHRcdHF1ZXVlOiBhbmltYXRpb24ub3B0cy5xdWV1ZVxuXHRcdH0gKVxuXHQpO1xuXG5cdHJldHVybiBhbmltYXRpb247XG59XG5cbmpRdWVyeS5BbmltYXRpb24gPSBqUXVlcnkuZXh0ZW5kKCBBbmltYXRpb24sIHtcblxuXHR0d2VlbmVyczoge1xuXHRcdFwiKlwiOiBbIGZ1bmN0aW9uKCBwcm9wLCB2YWx1ZSApIHtcblx0XHRcdHZhciB0d2VlbiA9IHRoaXMuY3JlYXRlVHdlZW4oIHByb3AsIHZhbHVlICk7XG5cdFx0XHRhZGp1c3RDU1MoIHR3ZWVuLmVsZW0sIHByb3AsIHJjc3NOdW0uZXhlYyggdmFsdWUgKSwgdHdlZW4gKTtcblx0XHRcdHJldHVybiB0d2Vlbjtcblx0XHR9IF1cblx0fSxcblxuXHR0d2VlbmVyOiBmdW5jdGlvbiggcHJvcHMsIGNhbGxiYWNrICkge1xuXHRcdGlmICggalF1ZXJ5LmlzRnVuY3Rpb24oIHByb3BzICkgKSB7XG5cdFx0XHRjYWxsYmFjayA9IHByb3BzO1xuXHRcdFx0cHJvcHMgPSBbIFwiKlwiIF07XG5cdFx0fSBlbHNlIHtcblx0XHRcdHByb3BzID0gcHJvcHMubWF0Y2goIHJub3RodG1sd2hpdGUgKTtcblx0XHR9XG5cblx0XHR2YXIgcHJvcCxcblx0XHRcdGluZGV4ID0gMCxcblx0XHRcdGxlbmd0aCA9IHByb3BzLmxlbmd0aDtcblxuXHRcdGZvciAoIDsgaW5kZXggPCBsZW5ndGg7IGluZGV4KysgKSB7XG5cdFx0XHRwcm9wID0gcHJvcHNbIGluZGV4IF07XG5cdFx0XHRBbmltYXRpb24udHdlZW5lcnNbIHByb3AgXSA9IEFuaW1hdGlvbi50d2VlbmVyc1sgcHJvcCBdIHx8IFtdO1xuXHRcdFx0QW5pbWF0aW9uLnR3ZWVuZXJzWyBwcm9wIF0udW5zaGlmdCggY2FsbGJhY2sgKTtcblx0XHR9XG5cdH0sXG5cblx0cHJlZmlsdGVyczogWyBkZWZhdWx0UHJlZmlsdGVyIF0sXG5cblx0cHJlZmlsdGVyOiBmdW5jdGlvbiggY2FsbGJhY2ssIHByZXBlbmQgKSB7XG5cdFx0aWYgKCBwcmVwZW5kICkge1xuXHRcdFx0QW5pbWF0aW9uLnByZWZpbHRlcnMudW5zaGlmdCggY2FsbGJhY2sgKTtcblx0XHR9IGVsc2Uge1xuXHRcdFx0QW5pbWF0aW9uLnByZWZpbHRlcnMucHVzaCggY2FsbGJhY2sgKTtcblx0XHR9XG5cdH1cbn0gKTtcblxualF1ZXJ5LnNwZWVkID0gZnVuY3Rpb24oIHNwZWVkLCBlYXNpbmcsIGZuICkge1xuXHR2YXIgb3B0ID0gc3BlZWQgJiYgdHlwZW9mIHNwZWVkID09PSBcIm9iamVjdFwiID8galF1ZXJ5LmV4dGVuZCgge30sIHNwZWVkICkgOiB7XG5cdFx0Y29tcGxldGU6IGZuIHx8ICFmbiAmJiBlYXNpbmcgfHxcblx0XHRcdGpRdWVyeS5pc0Z1bmN0aW9uKCBzcGVlZCApICYmIHNwZWVkLFxuXHRcdGR1cmF0aW9uOiBzcGVlZCxcblx0XHRlYXNpbmc6IGZuICYmIGVhc2luZyB8fCBlYXNpbmcgJiYgIWpRdWVyeS5pc0Z1bmN0aW9uKCBlYXNpbmcgKSAmJiBlYXNpbmdcblx0fTtcblxuXHQvLyBHbyB0byB0aGUgZW5kIHN0YXRlIGlmIGZ4IGFyZSBvZmZcblx0aWYgKCBqUXVlcnkuZngub2ZmICkge1xuXHRcdG9wdC5kdXJhdGlvbiA9IDA7XG5cblx0fSBlbHNlIHtcblx0XHRpZiAoIHR5cGVvZiBvcHQuZHVyYXRpb24gIT09IFwibnVtYmVyXCIgKSB7XG5cdFx0XHRpZiAoIG9wdC5kdXJhdGlvbiBpbiBqUXVlcnkuZnguc3BlZWRzICkge1xuXHRcdFx0XHRvcHQuZHVyYXRpb24gPSBqUXVlcnkuZnguc3BlZWRzWyBvcHQuZHVyYXRpb24gXTtcblxuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0b3B0LmR1cmF0aW9uID0galF1ZXJ5LmZ4LnNwZWVkcy5fZGVmYXVsdDtcblx0XHRcdH1cblx0XHR9XG5cdH1cblxuXHQvLyBOb3JtYWxpemUgb3B0LnF1ZXVlIC0gdHJ1ZS91bmRlZmluZWQvbnVsbCAtPiBcImZ4XCJcblx0aWYgKCBvcHQucXVldWUgPT0gbnVsbCB8fCBvcHQucXVldWUgPT09IHRydWUgKSB7XG5cdFx0b3B0LnF1ZXVlID0gXCJmeFwiO1xuXHR9XG5cblx0Ly8gUXVldWVpbmdcblx0b3B0Lm9sZCA9IG9wdC5jb21wbGV0ZTtcblxuXHRvcHQuY29tcGxldGUgPSBmdW5jdGlvbigpIHtcblx0XHRpZiAoIGpRdWVyeS5pc0Z1bmN0aW9uKCBvcHQub2xkICkgKSB7XG5cdFx0XHRvcHQub2xkLmNhbGwoIHRoaXMgKTtcblx0XHR9XG5cblx0XHRpZiAoIG9wdC5xdWV1ZSApIHtcblx0XHRcdGpRdWVyeS5kZXF1ZXVlKCB0aGlzLCBvcHQucXVldWUgKTtcblx0XHR9XG5cdH07XG5cblx0cmV0dXJuIG9wdDtcbn07XG5cbmpRdWVyeS5mbi5leHRlbmQoIHtcblx0ZmFkZVRvOiBmdW5jdGlvbiggc3BlZWQsIHRvLCBlYXNpbmcsIGNhbGxiYWNrICkge1xuXG5cdFx0Ly8gU2hvdyBhbnkgaGlkZGVuIGVsZW1lbnRzIGFmdGVyIHNldHRpbmcgb3BhY2l0eSB0byAwXG5cdFx0cmV0dXJuIHRoaXMuZmlsdGVyKCBpc0hpZGRlbldpdGhpblRyZWUgKS5jc3MoIFwib3BhY2l0eVwiLCAwICkuc2hvdygpXG5cblx0XHRcdC8vIEFuaW1hdGUgdG8gdGhlIHZhbHVlIHNwZWNpZmllZFxuXHRcdFx0LmVuZCgpLmFuaW1hdGUoIHsgb3BhY2l0eTogdG8gfSwgc3BlZWQsIGVhc2luZywgY2FsbGJhY2sgKTtcblx0fSxcblx0YW5pbWF0ZTogZnVuY3Rpb24oIHByb3AsIHNwZWVkLCBlYXNpbmcsIGNhbGxiYWNrICkge1xuXHRcdHZhciBlbXB0eSA9IGpRdWVyeS5pc0VtcHR5T2JqZWN0KCBwcm9wICksXG5cdFx0XHRvcHRhbGwgPSBqUXVlcnkuc3BlZWQoIHNwZWVkLCBlYXNpbmcsIGNhbGxiYWNrICksXG5cdFx0XHRkb0FuaW1hdGlvbiA9IGZ1bmN0aW9uKCkge1xuXG5cdFx0XHRcdC8vIE9wZXJhdGUgb24gYSBjb3B5IG9mIHByb3Agc28gcGVyLXByb3BlcnR5IGVhc2luZyB3b24ndCBiZSBsb3N0XG5cdFx0XHRcdHZhciBhbmltID0gQW5pbWF0aW9uKCB0aGlzLCBqUXVlcnkuZXh0ZW5kKCB7fSwgcHJvcCApLCBvcHRhbGwgKTtcblxuXHRcdFx0XHQvLyBFbXB0eSBhbmltYXRpb25zLCBvciBmaW5pc2hpbmcgcmVzb2x2ZXMgaW1tZWRpYXRlbHlcblx0XHRcdFx0aWYgKCBlbXB0eSB8fCBkYXRhUHJpdi5nZXQoIHRoaXMsIFwiZmluaXNoXCIgKSApIHtcblx0XHRcdFx0XHRhbmltLnN0b3AoIHRydWUgKTtcblx0XHRcdFx0fVxuXHRcdFx0fTtcblx0XHRcdGRvQW5pbWF0aW9uLmZpbmlzaCA9IGRvQW5pbWF0aW9uO1xuXG5cdFx0cmV0dXJuIGVtcHR5IHx8IG9wdGFsbC5xdWV1ZSA9PT0gZmFsc2UgP1xuXHRcdFx0dGhpcy5lYWNoKCBkb0FuaW1hdGlvbiApIDpcblx0XHRcdHRoaXMucXVldWUoIG9wdGFsbC5xdWV1ZSwgZG9BbmltYXRpb24gKTtcblx0fSxcblx0c3RvcDogZnVuY3Rpb24oIHR5cGUsIGNsZWFyUXVldWUsIGdvdG9FbmQgKSB7XG5cdFx0dmFyIHN0b3BRdWV1ZSA9IGZ1bmN0aW9uKCBob29rcyApIHtcblx0XHRcdHZhciBzdG9wID0gaG9va3Muc3RvcDtcblx0XHRcdGRlbGV0ZSBob29rcy5zdG9wO1xuXHRcdFx0c3RvcCggZ290b0VuZCApO1xuXHRcdH07XG5cblx0XHRpZiAoIHR5cGVvZiB0eXBlICE9PSBcInN0cmluZ1wiICkge1xuXHRcdFx0Z290b0VuZCA9IGNsZWFyUXVldWU7XG5cdFx0XHRjbGVhclF1ZXVlID0gdHlwZTtcblx0XHRcdHR5cGUgPSB1bmRlZmluZWQ7XG5cdFx0fVxuXHRcdGlmICggY2xlYXJRdWV1ZSAmJiB0eXBlICE9PSBmYWxzZSApIHtcblx0XHRcdHRoaXMucXVldWUoIHR5cGUgfHwgXCJmeFwiLCBbXSApO1xuXHRcdH1cblxuXHRcdHJldHVybiB0aGlzLmVhY2goIGZ1bmN0aW9uKCkge1xuXHRcdFx0dmFyIGRlcXVldWUgPSB0cnVlLFxuXHRcdFx0XHRpbmRleCA9IHR5cGUgIT0gbnVsbCAmJiB0eXBlICsgXCJxdWV1ZUhvb2tzXCIsXG5cdFx0XHRcdHRpbWVycyA9IGpRdWVyeS50aW1lcnMsXG5cdFx0XHRcdGRhdGEgPSBkYXRhUHJpdi5nZXQoIHRoaXMgKTtcblxuXHRcdFx0aWYgKCBpbmRleCApIHtcblx0XHRcdFx0aWYgKCBkYXRhWyBpbmRleCBdICYmIGRhdGFbIGluZGV4IF0uc3RvcCApIHtcblx0XHRcdFx0XHRzdG9wUXVldWUoIGRhdGFbIGluZGV4IF0gKTtcblx0XHRcdFx0fVxuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0Zm9yICggaW5kZXggaW4gZGF0YSApIHtcblx0XHRcdFx0XHRpZiAoIGRhdGFbIGluZGV4IF0gJiYgZGF0YVsgaW5kZXggXS5zdG9wICYmIHJydW4udGVzdCggaW5kZXggKSApIHtcblx0XHRcdFx0XHRcdHN0b3BRdWV1ZSggZGF0YVsgaW5kZXggXSApO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXHRcdFx0fVxuXG5cdFx0XHRmb3IgKCBpbmRleCA9IHRpbWVycy5sZW5ndGg7IGluZGV4LS07ICkge1xuXHRcdFx0XHRpZiAoIHRpbWVyc1sgaW5kZXggXS5lbGVtID09PSB0aGlzICYmXG5cdFx0XHRcdFx0KCB0eXBlID09IG51bGwgfHwgdGltZXJzWyBpbmRleCBdLnF1ZXVlID09PSB0eXBlICkgKSB7XG5cblx0XHRcdFx0XHR0aW1lcnNbIGluZGV4IF0uYW5pbS5zdG9wKCBnb3RvRW5kICk7XG5cdFx0XHRcdFx0ZGVxdWV1ZSA9IGZhbHNlO1xuXHRcdFx0XHRcdHRpbWVycy5zcGxpY2UoIGluZGV4LCAxICk7XG5cdFx0XHRcdH1cblx0XHRcdH1cblxuXHRcdFx0Ly8gU3RhcnQgdGhlIG5leHQgaW4gdGhlIHF1ZXVlIGlmIHRoZSBsYXN0IHN0ZXAgd2Fzbid0IGZvcmNlZC5cblx0XHRcdC8vIFRpbWVycyBjdXJyZW50bHkgd2lsbCBjYWxsIHRoZWlyIGNvbXBsZXRlIGNhbGxiYWNrcywgd2hpY2hcblx0XHRcdC8vIHdpbGwgZGVxdWV1ZSBidXQgb25seSBpZiB0aGV5IHdlcmUgZ290b0VuZC5cblx0XHRcdGlmICggZGVxdWV1ZSB8fCAhZ290b0VuZCApIHtcblx0XHRcdFx0alF1ZXJ5LmRlcXVldWUoIHRoaXMsIHR5cGUgKTtcblx0XHRcdH1cblx0XHR9ICk7XG5cdH0sXG5cdGZpbmlzaDogZnVuY3Rpb24oIHR5cGUgKSB7XG5cdFx0aWYgKCB0eXBlICE9PSBmYWxzZSApIHtcblx0XHRcdHR5cGUgPSB0eXBlIHx8IFwiZnhcIjtcblx0XHR9XG5cdFx0cmV0dXJuIHRoaXMuZWFjaCggZnVuY3Rpb24oKSB7XG5cdFx0XHR2YXIgaW5kZXgsXG5cdFx0XHRcdGRhdGEgPSBkYXRhUHJpdi5nZXQoIHRoaXMgKSxcblx0XHRcdFx0cXVldWUgPSBkYXRhWyB0eXBlICsgXCJxdWV1ZVwiIF0sXG5cdFx0XHRcdGhvb2tzID0gZGF0YVsgdHlwZSArIFwicXVldWVIb29rc1wiIF0sXG5cdFx0XHRcdHRpbWVycyA9IGpRdWVyeS50aW1lcnMsXG5cdFx0XHRcdGxlbmd0aCA9IHF1ZXVlID8gcXVldWUubGVuZ3RoIDogMDtcblxuXHRcdFx0Ly8gRW5hYmxlIGZpbmlzaGluZyBmbGFnIG9uIHByaXZhdGUgZGF0YVxuXHRcdFx0ZGF0YS5maW5pc2ggPSB0cnVlO1xuXG5cdFx0XHQvLyBFbXB0eSB0aGUgcXVldWUgZmlyc3Rcblx0XHRcdGpRdWVyeS5xdWV1ZSggdGhpcywgdHlwZSwgW10gKTtcblxuXHRcdFx0aWYgKCBob29rcyAmJiBob29rcy5zdG9wICkge1xuXHRcdFx0XHRob29rcy5zdG9wLmNhbGwoIHRoaXMsIHRydWUgKTtcblx0XHRcdH1cblxuXHRcdFx0Ly8gTG9vayBmb3IgYW55IGFjdGl2ZSBhbmltYXRpb25zLCBhbmQgZmluaXNoIHRoZW1cblx0XHRcdGZvciAoIGluZGV4ID0gdGltZXJzLmxlbmd0aDsgaW5kZXgtLTsgKSB7XG5cdFx0XHRcdGlmICggdGltZXJzWyBpbmRleCBdLmVsZW0gPT09IHRoaXMgJiYgdGltZXJzWyBpbmRleCBdLnF1ZXVlID09PSB0eXBlICkge1xuXHRcdFx0XHRcdHRpbWVyc1sgaW5kZXggXS5hbmltLnN0b3AoIHRydWUgKTtcblx0XHRcdFx0XHR0aW1lcnMuc3BsaWNlKCBpbmRleCwgMSApO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cblx0XHRcdC8vIExvb2sgZm9yIGFueSBhbmltYXRpb25zIGluIHRoZSBvbGQgcXVldWUgYW5kIGZpbmlzaCB0aGVtXG5cdFx0XHRmb3IgKCBpbmRleCA9IDA7IGluZGV4IDwgbGVuZ3RoOyBpbmRleCsrICkge1xuXHRcdFx0XHRpZiAoIHF1ZXVlWyBpbmRleCBdICYmIHF1ZXVlWyBpbmRleCBdLmZpbmlzaCApIHtcblx0XHRcdFx0XHRxdWV1ZVsgaW5kZXggXS5maW5pc2guY2FsbCggdGhpcyApO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cblx0XHRcdC8vIFR1cm4gb2ZmIGZpbmlzaGluZyBmbGFnXG5cdFx0XHRkZWxldGUgZGF0YS5maW5pc2g7XG5cdFx0fSApO1xuXHR9XG59ICk7XG5cbmpRdWVyeS5lYWNoKCBbIFwidG9nZ2xlXCIsIFwic2hvd1wiLCBcImhpZGVcIiBdLCBmdW5jdGlvbiggaSwgbmFtZSApIHtcblx0dmFyIGNzc0ZuID0galF1ZXJ5LmZuWyBuYW1lIF07XG5cdGpRdWVyeS5mblsgbmFtZSBdID0gZnVuY3Rpb24oIHNwZWVkLCBlYXNpbmcsIGNhbGxiYWNrICkge1xuXHRcdHJldHVybiBzcGVlZCA9PSBudWxsIHx8IHR5cGVvZiBzcGVlZCA9PT0gXCJib29sZWFuXCIgP1xuXHRcdFx0Y3NzRm4uYXBwbHkoIHRoaXMsIGFyZ3VtZW50cyApIDpcblx0XHRcdHRoaXMuYW5pbWF0ZSggZ2VuRngoIG5hbWUsIHRydWUgKSwgc3BlZWQsIGVhc2luZywgY2FsbGJhY2sgKTtcblx0fTtcbn0gKTtcblxuLy8gR2VuZXJhdGUgc2hvcnRjdXRzIGZvciBjdXN0b20gYW5pbWF0aW9uc1xualF1ZXJ5LmVhY2goIHtcblx0c2xpZGVEb3duOiBnZW5GeCggXCJzaG93XCIgKSxcblx0c2xpZGVVcDogZ2VuRngoIFwiaGlkZVwiICksXG5cdHNsaWRlVG9nZ2xlOiBnZW5GeCggXCJ0b2dnbGVcIiApLFxuXHRmYWRlSW46IHsgb3BhY2l0eTogXCJzaG93XCIgfSxcblx0ZmFkZU91dDogeyBvcGFjaXR5OiBcImhpZGVcIiB9LFxuXHRmYWRlVG9nZ2xlOiB7IG9wYWNpdHk6IFwidG9nZ2xlXCIgfVxufSwgZnVuY3Rpb24oIG5hbWUsIHByb3BzICkge1xuXHRqUXVlcnkuZm5bIG5hbWUgXSA9IGZ1bmN0aW9uKCBzcGVlZCwgZWFzaW5nLCBjYWxsYmFjayApIHtcblx0XHRyZXR1cm4gdGhpcy5hbmltYXRlKCBwcm9wcywgc3BlZWQsIGVhc2luZywgY2FsbGJhY2sgKTtcblx0fTtcbn0gKTtcblxualF1ZXJ5LnRpbWVycyA9IFtdO1xualF1ZXJ5LmZ4LnRpY2sgPSBmdW5jdGlvbigpIHtcblx0dmFyIHRpbWVyLFxuXHRcdGkgPSAwLFxuXHRcdHRpbWVycyA9IGpRdWVyeS50aW1lcnM7XG5cblx0ZnhOb3cgPSBqUXVlcnkubm93KCk7XG5cblx0Zm9yICggOyBpIDwgdGltZXJzLmxlbmd0aDsgaSsrICkge1xuXHRcdHRpbWVyID0gdGltZXJzWyBpIF07XG5cblx0XHQvLyBSdW4gdGhlIHRpbWVyIGFuZCBzYWZlbHkgcmVtb3ZlIGl0IHdoZW4gZG9uZSAoYWxsb3dpbmcgZm9yIGV4dGVybmFsIHJlbW92YWwpXG5cdFx0aWYgKCAhdGltZXIoKSAmJiB0aW1lcnNbIGkgXSA9PT0gdGltZXIgKSB7XG5cdFx0XHR0aW1lcnMuc3BsaWNlKCBpLS0sIDEgKTtcblx0XHR9XG5cdH1cblxuXHRpZiAoICF0aW1lcnMubGVuZ3RoICkge1xuXHRcdGpRdWVyeS5meC5zdG9wKCk7XG5cdH1cblx0ZnhOb3cgPSB1bmRlZmluZWQ7XG59O1xuXG5qUXVlcnkuZngudGltZXIgPSBmdW5jdGlvbiggdGltZXIgKSB7XG5cdGpRdWVyeS50aW1lcnMucHVzaCggdGltZXIgKTtcblx0alF1ZXJ5LmZ4LnN0YXJ0KCk7XG59O1xuXG5qUXVlcnkuZnguaW50ZXJ2YWwgPSAxMztcbmpRdWVyeS5meC5zdGFydCA9IGZ1bmN0aW9uKCkge1xuXHRpZiAoIGluUHJvZ3Jlc3MgKSB7XG5cdFx0cmV0dXJuO1xuXHR9XG5cblx0aW5Qcm9ncmVzcyA9IHRydWU7XG5cdHNjaGVkdWxlKCk7XG59O1xuXG5qUXVlcnkuZnguc3RvcCA9IGZ1bmN0aW9uKCkge1xuXHRpblByb2dyZXNzID0gbnVsbDtcbn07XG5cbmpRdWVyeS5meC5zcGVlZHMgPSB7XG5cdHNsb3c6IDYwMCxcblx0ZmFzdDogMjAwLFxuXG5cdC8vIERlZmF1bHQgc3BlZWRcblx0X2RlZmF1bHQ6IDQwMFxufTtcblxuXG4vLyBCYXNlZCBvZmYgb2YgdGhlIHBsdWdpbiBieSBDbGludCBIZWxmZXJzLCB3aXRoIHBlcm1pc3Npb24uXG4vLyBodHRwczovL3dlYi5hcmNoaXZlLm9yZy93ZWIvMjAxMDAzMjQwMTQ3NDcvaHR0cDovL2JsaW5kc2lnbmFscy5jb20vaW5kZXgucGhwLzIwMDkvMDcvanF1ZXJ5LWRlbGF5L1xualF1ZXJ5LmZuLmRlbGF5ID0gZnVuY3Rpb24oIHRpbWUsIHR5cGUgKSB7XG5cdHRpbWUgPSBqUXVlcnkuZnggPyBqUXVlcnkuZnguc3BlZWRzWyB0aW1lIF0gfHwgdGltZSA6IHRpbWU7XG5cdHR5cGUgPSB0eXBlIHx8IFwiZnhcIjtcblxuXHRyZXR1cm4gdGhpcy5xdWV1ZSggdHlwZSwgZnVuY3Rpb24oIG5leHQsIGhvb2tzICkge1xuXHRcdHZhciB0aW1lb3V0ID0gd2luZG93LnNldFRpbWVvdXQoIG5leHQsIHRpbWUgKTtcblx0XHRob29rcy5zdG9wID0gZnVuY3Rpb24oKSB7XG5cdFx0XHR3aW5kb3cuY2xlYXJUaW1lb3V0KCB0aW1lb3V0ICk7XG5cdFx0fTtcblx0fSApO1xufTtcblxuXG4oIGZ1bmN0aW9uKCkge1xuXHR2YXIgaW5wdXQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCBcImlucHV0XCIgKSxcblx0XHRzZWxlY3QgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCBcInNlbGVjdFwiICksXG5cdFx0b3B0ID0gc2VsZWN0LmFwcGVuZENoaWxkKCBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCBcIm9wdGlvblwiICkgKTtcblxuXHRpbnB1dC50eXBlID0gXCJjaGVja2JveFwiO1xuXG5cdC8vIFN1cHBvcnQ6IEFuZHJvaWQgPD00LjMgb25seVxuXHQvLyBEZWZhdWx0IHZhbHVlIGZvciBhIGNoZWNrYm94IHNob3VsZCBiZSBcIm9uXCJcblx0c3VwcG9ydC5jaGVja09uID0gaW5wdXQudmFsdWUgIT09IFwiXCI7XG5cblx0Ly8gU3VwcG9ydDogSUUgPD0xMSBvbmx5XG5cdC8vIE11c3QgYWNjZXNzIHNlbGVjdGVkSW5kZXggdG8gbWFrZSBkZWZhdWx0IG9wdGlvbnMgc2VsZWN0XG5cdHN1cHBvcnQub3B0U2VsZWN0ZWQgPSBvcHQuc2VsZWN0ZWQ7XG5cblx0Ly8gU3VwcG9ydDogSUUgPD0xMSBvbmx5XG5cdC8vIEFuIGlucHV0IGxvc2VzIGl0cyB2YWx1ZSBhZnRlciBiZWNvbWluZyBhIHJhZGlvXG5cdGlucHV0ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCggXCJpbnB1dFwiICk7XG5cdGlucHV0LnZhbHVlID0gXCJ0XCI7XG5cdGlucHV0LnR5cGUgPSBcInJhZGlvXCI7XG5cdHN1cHBvcnQucmFkaW9WYWx1ZSA9IGlucHV0LnZhbHVlID09PSBcInRcIjtcbn0gKSgpO1xuXG5cbnZhciBib29sSG9vayxcblx0YXR0ckhhbmRsZSA9IGpRdWVyeS5leHByLmF0dHJIYW5kbGU7XG5cbmpRdWVyeS5mbi5leHRlbmQoIHtcblx0YXR0cjogZnVuY3Rpb24oIG5hbWUsIHZhbHVlICkge1xuXHRcdHJldHVybiBhY2Nlc3MoIHRoaXMsIGpRdWVyeS5hdHRyLCBuYW1lLCB2YWx1ZSwgYXJndW1lbnRzLmxlbmd0aCA+IDEgKTtcblx0fSxcblxuXHRyZW1vdmVBdHRyOiBmdW5jdGlvbiggbmFtZSApIHtcblx0XHRyZXR1cm4gdGhpcy5lYWNoKCBmdW5jdGlvbigpIHtcblx0XHRcdGpRdWVyeS5yZW1vdmVBdHRyKCB0aGlzLCBuYW1lICk7XG5cdFx0fSApO1xuXHR9XG59ICk7XG5cbmpRdWVyeS5leHRlbmQoIHtcblx0YXR0cjogZnVuY3Rpb24oIGVsZW0sIG5hbWUsIHZhbHVlICkge1xuXHRcdHZhciByZXQsIGhvb2tzLFxuXHRcdFx0blR5cGUgPSBlbGVtLm5vZGVUeXBlO1xuXG5cdFx0Ly8gRG9uJ3QgZ2V0L3NldCBhdHRyaWJ1dGVzIG9uIHRleHQsIGNvbW1lbnQgYW5kIGF0dHJpYnV0ZSBub2Rlc1xuXHRcdGlmICggblR5cGUgPT09IDMgfHwgblR5cGUgPT09IDggfHwgblR5cGUgPT09IDIgKSB7XG5cdFx0XHRyZXR1cm47XG5cdFx0fVxuXG5cdFx0Ly8gRmFsbGJhY2sgdG8gcHJvcCB3aGVuIGF0dHJpYnV0ZXMgYXJlIG5vdCBzdXBwb3J0ZWRcblx0XHRpZiAoIHR5cGVvZiBlbGVtLmdldEF0dHJpYnV0ZSA9PT0gXCJ1bmRlZmluZWRcIiApIHtcblx0XHRcdHJldHVybiBqUXVlcnkucHJvcCggZWxlbSwgbmFtZSwgdmFsdWUgKTtcblx0XHR9XG5cblx0XHQvLyBBdHRyaWJ1dGUgaG9va3MgYXJlIGRldGVybWluZWQgYnkgdGhlIGxvd2VyY2FzZSB2ZXJzaW9uXG5cdFx0Ly8gR3JhYiBuZWNlc3NhcnkgaG9vayBpZiBvbmUgaXMgZGVmaW5lZFxuXHRcdGlmICggblR5cGUgIT09IDEgfHwgIWpRdWVyeS5pc1hNTERvYyggZWxlbSApICkge1xuXHRcdFx0aG9va3MgPSBqUXVlcnkuYXR0ckhvb2tzWyBuYW1lLnRvTG93ZXJDYXNlKCkgXSB8fFxuXHRcdFx0XHQoIGpRdWVyeS5leHByLm1hdGNoLmJvb2wudGVzdCggbmFtZSApID8gYm9vbEhvb2sgOiB1bmRlZmluZWQgKTtcblx0XHR9XG5cblx0XHRpZiAoIHZhbHVlICE9PSB1bmRlZmluZWQgKSB7XG5cdFx0XHRpZiAoIHZhbHVlID09PSBudWxsICkge1xuXHRcdFx0XHRqUXVlcnkucmVtb3ZlQXR0ciggZWxlbSwgbmFtZSApO1xuXHRcdFx0XHRyZXR1cm47XG5cdFx0XHR9XG5cblx0XHRcdGlmICggaG9va3MgJiYgXCJzZXRcIiBpbiBob29rcyAmJlxuXHRcdFx0XHQoIHJldCA9IGhvb2tzLnNldCggZWxlbSwgdmFsdWUsIG5hbWUgKSApICE9PSB1bmRlZmluZWQgKSB7XG5cdFx0XHRcdHJldHVybiByZXQ7XG5cdFx0XHR9XG5cblx0XHRcdGVsZW0uc2V0QXR0cmlidXRlKCBuYW1lLCB2YWx1ZSArIFwiXCIgKTtcblx0XHRcdHJldHVybiB2YWx1ZTtcblx0XHR9XG5cblx0XHRpZiAoIGhvb2tzICYmIFwiZ2V0XCIgaW4gaG9va3MgJiYgKCByZXQgPSBob29rcy5nZXQoIGVsZW0sIG5hbWUgKSApICE9PSBudWxsICkge1xuXHRcdFx0cmV0dXJuIHJldDtcblx0XHR9XG5cblx0XHRyZXQgPSBqUXVlcnkuZmluZC5hdHRyKCBlbGVtLCBuYW1lICk7XG5cblx0XHQvLyBOb24tZXhpc3RlbnQgYXR0cmlidXRlcyByZXR1cm4gbnVsbCwgd2Ugbm9ybWFsaXplIHRvIHVuZGVmaW5lZFxuXHRcdHJldHVybiByZXQgPT0gbnVsbCA/IHVuZGVmaW5lZCA6IHJldDtcblx0fSxcblxuXHRhdHRySG9va3M6IHtcblx0XHR0eXBlOiB7XG5cdFx0XHRzZXQ6IGZ1bmN0aW9uKCBlbGVtLCB2YWx1ZSApIHtcblx0XHRcdFx0aWYgKCAhc3VwcG9ydC5yYWRpb1ZhbHVlICYmIHZhbHVlID09PSBcInJhZGlvXCIgJiZcblx0XHRcdFx0XHRub2RlTmFtZSggZWxlbSwgXCJpbnB1dFwiICkgKSB7XG5cdFx0XHRcdFx0dmFyIHZhbCA9IGVsZW0udmFsdWU7XG5cdFx0XHRcdFx0ZWxlbS5zZXRBdHRyaWJ1dGUoIFwidHlwZVwiLCB2YWx1ZSApO1xuXHRcdFx0XHRcdGlmICggdmFsICkge1xuXHRcdFx0XHRcdFx0ZWxlbS52YWx1ZSA9IHZhbDtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0cmV0dXJuIHZhbHVlO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fVxuXHR9LFxuXG5cdHJlbW92ZUF0dHI6IGZ1bmN0aW9uKCBlbGVtLCB2YWx1ZSApIHtcblx0XHR2YXIgbmFtZSxcblx0XHRcdGkgPSAwLFxuXG5cdFx0XHQvLyBBdHRyaWJ1dGUgbmFtZXMgY2FuIGNvbnRhaW4gbm9uLUhUTUwgd2hpdGVzcGFjZSBjaGFyYWN0ZXJzXG5cdFx0XHQvLyBodHRwczovL2h0bWwuc3BlYy53aGF0d2cub3JnL211bHRpcGFnZS9zeW50YXguaHRtbCNhdHRyaWJ1dGVzLTJcblx0XHRcdGF0dHJOYW1lcyA9IHZhbHVlICYmIHZhbHVlLm1hdGNoKCBybm90aHRtbHdoaXRlICk7XG5cblx0XHRpZiAoIGF0dHJOYW1lcyAmJiBlbGVtLm5vZGVUeXBlID09PSAxICkge1xuXHRcdFx0d2hpbGUgKCAoIG5hbWUgPSBhdHRyTmFtZXNbIGkrKyBdICkgKSB7XG5cdFx0XHRcdGVsZW0ucmVtb3ZlQXR0cmlidXRlKCBuYW1lICk7XG5cdFx0XHR9XG5cdFx0fVxuXHR9XG59ICk7XG5cbi8vIEhvb2tzIGZvciBib29sZWFuIGF0dHJpYnV0ZXNcbmJvb2xIb29rID0ge1xuXHRzZXQ6IGZ1bmN0aW9uKCBlbGVtLCB2YWx1ZSwgbmFtZSApIHtcblx0XHRpZiAoIHZhbHVlID09PSBmYWxzZSApIHtcblxuXHRcdFx0Ly8gUmVtb3ZlIGJvb2xlYW4gYXR0cmlidXRlcyB3aGVuIHNldCB0byBmYWxzZVxuXHRcdFx0alF1ZXJ5LnJlbW92ZUF0dHIoIGVsZW0sIG5hbWUgKTtcblx0XHR9IGVsc2Uge1xuXHRcdFx0ZWxlbS5zZXRBdHRyaWJ1dGUoIG5hbWUsIG5hbWUgKTtcblx0XHR9XG5cdFx0cmV0dXJuIG5hbWU7XG5cdH1cbn07XG5cbmpRdWVyeS5lYWNoKCBqUXVlcnkuZXhwci5tYXRjaC5ib29sLnNvdXJjZS5tYXRjaCggL1xcdysvZyApLCBmdW5jdGlvbiggaSwgbmFtZSApIHtcblx0dmFyIGdldHRlciA9IGF0dHJIYW5kbGVbIG5hbWUgXSB8fCBqUXVlcnkuZmluZC5hdHRyO1xuXG5cdGF0dHJIYW5kbGVbIG5hbWUgXSA9IGZ1bmN0aW9uKCBlbGVtLCBuYW1lLCBpc1hNTCApIHtcblx0XHR2YXIgcmV0LCBoYW5kbGUsXG5cdFx0XHRsb3dlcmNhc2VOYW1lID0gbmFtZS50b0xvd2VyQ2FzZSgpO1xuXG5cdFx0aWYgKCAhaXNYTUwgKSB7XG5cblx0XHRcdC8vIEF2b2lkIGFuIGluZmluaXRlIGxvb3AgYnkgdGVtcG9yYXJpbHkgcmVtb3ZpbmcgdGhpcyBmdW5jdGlvbiBmcm9tIHRoZSBnZXR0ZXJcblx0XHRcdGhhbmRsZSA9IGF0dHJIYW5kbGVbIGxvd2VyY2FzZU5hbWUgXTtcblx0XHRcdGF0dHJIYW5kbGVbIGxvd2VyY2FzZU5hbWUgXSA9IHJldDtcblx0XHRcdHJldCA9IGdldHRlciggZWxlbSwgbmFtZSwgaXNYTUwgKSAhPSBudWxsID9cblx0XHRcdFx0bG93ZXJjYXNlTmFtZSA6XG5cdFx0XHRcdG51bGw7XG5cdFx0XHRhdHRySGFuZGxlWyBsb3dlcmNhc2VOYW1lIF0gPSBoYW5kbGU7XG5cdFx0fVxuXHRcdHJldHVybiByZXQ7XG5cdH07XG59ICk7XG5cblxuXG5cbnZhciByZm9jdXNhYmxlID0gL14oPzppbnB1dHxzZWxlY3R8dGV4dGFyZWF8YnV0dG9uKSQvaSxcblx0cmNsaWNrYWJsZSA9IC9eKD86YXxhcmVhKSQvaTtcblxualF1ZXJ5LmZuLmV4dGVuZCgge1xuXHRwcm9wOiBmdW5jdGlvbiggbmFtZSwgdmFsdWUgKSB7XG5cdFx0cmV0dXJuIGFjY2VzcyggdGhpcywgalF1ZXJ5LnByb3AsIG5hbWUsIHZhbHVlLCBhcmd1bWVudHMubGVuZ3RoID4gMSApO1xuXHR9LFxuXG5cdHJlbW92ZVByb3A6IGZ1bmN0aW9uKCBuYW1lICkge1xuXHRcdHJldHVybiB0aGlzLmVhY2goIGZ1bmN0aW9uKCkge1xuXHRcdFx0ZGVsZXRlIHRoaXNbIGpRdWVyeS5wcm9wRml4WyBuYW1lIF0gfHwgbmFtZSBdO1xuXHRcdH0gKTtcblx0fVxufSApO1xuXG5qUXVlcnkuZXh0ZW5kKCB7XG5cdHByb3A6IGZ1bmN0aW9uKCBlbGVtLCBuYW1lLCB2YWx1ZSApIHtcblx0XHR2YXIgcmV0LCBob29rcyxcblx0XHRcdG5UeXBlID0gZWxlbS5ub2RlVHlwZTtcblxuXHRcdC8vIERvbid0IGdldC9zZXQgcHJvcGVydGllcyBvbiB0ZXh0LCBjb21tZW50IGFuZCBhdHRyaWJ1dGUgbm9kZXNcblx0XHRpZiAoIG5UeXBlID09PSAzIHx8IG5UeXBlID09PSA4IHx8IG5UeXBlID09PSAyICkge1xuXHRcdFx0cmV0dXJuO1xuXHRcdH1cblxuXHRcdGlmICggblR5cGUgIT09IDEgfHwgIWpRdWVyeS5pc1hNTERvYyggZWxlbSApICkge1xuXG5cdFx0XHQvLyBGaXggbmFtZSBhbmQgYXR0YWNoIGhvb2tzXG5cdFx0XHRuYW1lID0galF1ZXJ5LnByb3BGaXhbIG5hbWUgXSB8fCBuYW1lO1xuXHRcdFx0aG9va3MgPSBqUXVlcnkucHJvcEhvb2tzWyBuYW1lIF07XG5cdFx0fVxuXG5cdFx0aWYgKCB2YWx1ZSAhPT0gdW5kZWZpbmVkICkge1xuXHRcdFx0aWYgKCBob29rcyAmJiBcInNldFwiIGluIGhvb2tzICYmXG5cdFx0XHRcdCggcmV0ID0gaG9va3Muc2V0KCBlbGVtLCB2YWx1ZSwgbmFtZSApICkgIT09IHVuZGVmaW5lZCApIHtcblx0XHRcdFx0cmV0dXJuIHJldDtcblx0XHRcdH1cblxuXHRcdFx0cmV0dXJuICggZWxlbVsgbmFtZSBdID0gdmFsdWUgKTtcblx0XHR9XG5cblx0XHRpZiAoIGhvb2tzICYmIFwiZ2V0XCIgaW4gaG9va3MgJiYgKCByZXQgPSBob29rcy5nZXQoIGVsZW0sIG5hbWUgKSApICE9PSBudWxsICkge1xuXHRcdFx0cmV0dXJuIHJldDtcblx0XHR9XG5cblx0XHRyZXR1cm4gZWxlbVsgbmFtZSBdO1xuXHR9LFxuXG5cdHByb3BIb29rczoge1xuXHRcdHRhYkluZGV4OiB7XG5cdFx0XHRnZXQ6IGZ1bmN0aW9uKCBlbGVtICkge1xuXG5cdFx0XHRcdC8vIFN1cHBvcnQ6IElFIDw9OSAtIDExIG9ubHlcblx0XHRcdFx0Ly8gZWxlbS50YWJJbmRleCBkb2Vzbid0IGFsd2F5cyByZXR1cm4gdGhlXG5cdFx0XHRcdC8vIGNvcnJlY3QgdmFsdWUgd2hlbiBpdCBoYXNuJ3QgYmVlbiBleHBsaWNpdGx5IHNldFxuXHRcdFx0XHQvLyBodHRwczovL3dlYi5hcmNoaXZlLm9yZy93ZWIvMjAxNDExMTYyMzMzNDcvaHR0cDovL2ZsdWlkcHJvamVjdC5vcmcvYmxvZy8yMDA4LzAxLzA5L2dldHRpbmctc2V0dGluZy1hbmQtcmVtb3ZpbmctdGFiaW5kZXgtdmFsdWVzLXdpdGgtamF2YXNjcmlwdC9cblx0XHRcdFx0Ly8gVXNlIHByb3BlciBhdHRyaWJ1dGUgcmV0cmlldmFsKCMxMjA3Milcblx0XHRcdFx0dmFyIHRhYmluZGV4ID0galF1ZXJ5LmZpbmQuYXR0ciggZWxlbSwgXCJ0YWJpbmRleFwiICk7XG5cblx0XHRcdFx0aWYgKCB0YWJpbmRleCApIHtcblx0XHRcdFx0XHRyZXR1cm4gcGFyc2VJbnQoIHRhYmluZGV4LCAxMCApO1xuXHRcdFx0XHR9XG5cblx0XHRcdFx0aWYgKFxuXHRcdFx0XHRcdHJmb2N1c2FibGUudGVzdCggZWxlbS5ub2RlTmFtZSApIHx8XG5cdFx0XHRcdFx0cmNsaWNrYWJsZS50ZXN0KCBlbGVtLm5vZGVOYW1lICkgJiZcblx0XHRcdFx0XHRlbGVtLmhyZWZcblx0XHRcdFx0KSB7XG5cdFx0XHRcdFx0cmV0dXJuIDA7XG5cdFx0XHRcdH1cblxuXHRcdFx0XHRyZXR1cm4gLTE7XG5cdFx0XHR9XG5cdFx0fVxuXHR9LFxuXG5cdHByb3BGaXg6IHtcblx0XHRcImZvclwiOiBcImh0bWxGb3JcIixcblx0XHRcImNsYXNzXCI6IFwiY2xhc3NOYW1lXCJcblx0fVxufSApO1xuXG4vLyBTdXBwb3J0OiBJRSA8PTExIG9ubHlcbi8vIEFjY2Vzc2luZyB0aGUgc2VsZWN0ZWRJbmRleCBwcm9wZXJ0eVxuLy8gZm9yY2VzIHRoZSBicm93c2VyIHRvIHJlc3BlY3Qgc2V0dGluZyBzZWxlY3RlZFxuLy8gb24gdGhlIG9wdGlvblxuLy8gVGhlIGdldHRlciBlbnN1cmVzIGEgZGVmYXVsdCBvcHRpb24gaXMgc2VsZWN0ZWRcbi8vIHdoZW4gaW4gYW4gb3B0Z3JvdXBcbi8vIGVzbGludCBydWxlIFwibm8tdW51c2VkLWV4cHJlc3Npb25zXCIgaXMgZGlzYWJsZWQgZm9yIHRoaXMgY29kZVxuLy8gc2luY2UgaXQgY29uc2lkZXJzIHN1Y2ggYWNjZXNzaW9ucyBub29wXG5pZiAoICFzdXBwb3J0Lm9wdFNlbGVjdGVkICkge1xuXHRqUXVlcnkucHJvcEhvb2tzLnNlbGVjdGVkID0ge1xuXHRcdGdldDogZnVuY3Rpb24oIGVsZW0gKSB7XG5cblx0XHRcdC8qIGVzbGludCBuby11bnVzZWQtZXhwcmVzc2lvbnM6IFwib2ZmXCIgKi9cblxuXHRcdFx0dmFyIHBhcmVudCA9IGVsZW0ucGFyZW50Tm9kZTtcblx0XHRcdGlmICggcGFyZW50ICYmIHBhcmVudC5wYXJlbnROb2RlICkge1xuXHRcdFx0XHRwYXJlbnQucGFyZW50Tm9kZS5zZWxlY3RlZEluZGV4O1xuXHRcdFx0fVxuXHRcdFx0cmV0dXJuIG51bGw7XG5cdFx0fSxcblx0XHRzZXQ6IGZ1bmN0aW9uKCBlbGVtICkge1xuXG5cdFx0XHQvKiBlc2xpbnQgbm8tdW51c2VkLWV4cHJlc3Npb25zOiBcIm9mZlwiICovXG5cblx0XHRcdHZhciBwYXJlbnQgPSBlbGVtLnBhcmVudE5vZGU7XG5cdFx0XHRpZiAoIHBhcmVudCApIHtcblx0XHRcdFx0cGFyZW50LnNlbGVjdGVkSW5kZXg7XG5cblx0XHRcdFx0aWYgKCBwYXJlbnQucGFyZW50Tm9kZSApIHtcblx0XHRcdFx0XHRwYXJlbnQucGFyZW50Tm9kZS5zZWxlY3RlZEluZGV4O1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fVxuXHR9O1xufVxuXG5qUXVlcnkuZWFjaCggW1xuXHRcInRhYkluZGV4XCIsXG5cdFwicmVhZE9ubHlcIixcblx0XCJtYXhMZW5ndGhcIixcblx0XCJjZWxsU3BhY2luZ1wiLFxuXHRcImNlbGxQYWRkaW5nXCIsXG5cdFwicm93U3BhblwiLFxuXHRcImNvbFNwYW5cIixcblx0XCJ1c2VNYXBcIixcblx0XCJmcmFtZUJvcmRlclwiLFxuXHRcImNvbnRlbnRFZGl0YWJsZVwiXG5dLCBmdW5jdGlvbigpIHtcblx0alF1ZXJ5LnByb3BGaXhbIHRoaXMudG9Mb3dlckNhc2UoKSBdID0gdGhpcztcbn0gKTtcblxuXG5cblxuXHQvLyBTdHJpcCBhbmQgY29sbGFwc2Ugd2hpdGVzcGFjZSBhY2NvcmRpbmcgdG8gSFRNTCBzcGVjXG5cdC8vIGh0dHBzOi8vaHRtbC5zcGVjLndoYXR3Zy5vcmcvbXVsdGlwYWdlL2luZnJhc3RydWN0dXJlLmh0bWwjc3RyaXAtYW5kLWNvbGxhcHNlLXdoaXRlc3BhY2Vcblx0ZnVuY3Rpb24gc3RyaXBBbmRDb2xsYXBzZSggdmFsdWUgKSB7XG5cdFx0dmFyIHRva2VucyA9IHZhbHVlLm1hdGNoKCBybm90aHRtbHdoaXRlICkgfHwgW107XG5cdFx0cmV0dXJuIHRva2Vucy5qb2luKCBcIiBcIiApO1xuXHR9XG5cblxuZnVuY3Rpb24gZ2V0Q2xhc3MoIGVsZW0gKSB7XG5cdHJldHVybiBlbGVtLmdldEF0dHJpYnV0ZSAmJiBlbGVtLmdldEF0dHJpYnV0ZSggXCJjbGFzc1wiICkgfHwgXCJcIjtcbn1cblxualF1ZXJ5LmZuLmV4dGVuZCgge1xuXHRhZGRDbGFzczogZnVuY3Rpb24oIHZhbHVlICkge1xuXHRcdHZhciBjbGFzc2VzLCBlbGVtLCBjdXIsIGN1clZhbHVlLCBjbGF6eiwgaiwgZmluYWxWYWx1ZSxcblx0XHRcdGkgPSAwO1xuXG5cdFx0aWYgKCBqUXVlcnkuaXNGdW5jdGlvbiggdmFsdWUgKSApIHtcblx0XHRcdHJldHVybiB0aGlzLmVhY2goIGZ1bmN0aW9uKCBqICkge1xuXHRcdFx0XHRqUXVlcnkoIHRoaXMgKS5hZGRDbGFzcyggdmFsdWUuY2FsbCggdGhpcywgaiwgZ2V0Q2xhc3MoIHRoaXMgKSApICk7XG5cdFx0XHR9ICk7XG5cdFx0fVxuXG5cdFx0aWYgKCB0eXBlb2YgdmFsdWUgPT09IFwic3RyaW5nXCIgJiYgdmFsdWUgKSB7XG5cdFx0XHRjbGFzc2VzID0gdmFsdWUubWF0Y2goIHJub3RodG1sd2hpdGUgKSB8fCBbXTtcblxuXHRcdFx0d2hpbGUgKCAoIGVsZW0gPSB0aGlzWyBpKysgXSApICkge1xuXHRcdFx0XHRjdXJWYWx1ZSA9IGdldENsYXNzKCBlbGVtICk7XG5cdFx0XHRcdGN1ciA9IGVsZW0ubm9kZVR5cGUgPT09IDEgJiYgKCBcIiBcIiArIHN0cmlwQW5kQ29sbGFwc2UoIGN1clZhbHVlICkgKyBcIiBcIiApO1xuXG5cdFx0XHRcdGlmICggY3VyICkge1xuXHRcdFx0XHRcdGogPSAwO1xuXHRcdFx0XHRcdHdoaWxlICggKCBjbGF6eiA9IGNsYXNzZXNbIGorKyBdICkgKSB7XG5cdFx0XHRcdFx0XHRpZiAoIGN1ci5pbmRleE9mKCBcIiBcIiArIGNsYXp6ICsgXCIgXCIgKSA8IDAgKSB7XG5cdFx0XHRcdFx0XHRcdGN1ciArPSBjbGF6eiArIFwiIFwiO1xuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdC8vIE9ubHkgYXNzaWduIGlmIGRpZmZlcmVudCB0byBhdm9pZCB1bm5lZWRlZCByZW5kZXJpbmcuXG5cdFx0XHRcdFx0ZmluYWxWYWx1ZSA9IHN0cmlwQW5kQ29sbGFwc2UoIGN1ciApO1xuXHRcdFx0XHRcdGlmICggY3VyVmFsdWUgIT09IGZpbmFsVmFsdWUgKSB7XG5cdFx0XHRcdFx0XHRlbGVtLnNldEF0dHJpYnV0ZSggXCJjbGFzc1wiLCBmaW5hbFZhbHVlICk7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0cmV0dXJuIHRoaXM7XG5cdH0sXG5cblx0cmVtb3ZlQ2xhc3M6IGZ1bmN0aW9uKCB2YWx1ZSApIHtcblx0XHR2YXIgY2xhc3NlcywgZWxlbSwgY3VyLCBjdXJWYWx1ZSwgY2xhenosIGosIGZpbmFsVmFsdWUsXG5cdFx0XHRpID0gMDtcblxuXHRcdGlmICggalF1ZXJ5LmlzRnVuY3Rpb24oIHZhbHVlICkgKSB7XG5cdFx0XHRyZXR1cm4gdGhpcy5lYWNoKCBmdW5jdGlvbiggaiApIHtcblx0XHRcdFx0alF1ZXJ5KCB0aGlzICkucmVtb3ZlQ2xhc3MoIHZhbHVlLmNhbGwoIHRoaXMsIGosIGdldENsYXNzKCB0aGlzICkgKSApO1xuXHRcdFx0fSApO1xuXHRcdH1cblxuXHRcdGlmICggIWFyZ3VtZW50cy5sZW5ndGggKSB7XG5cdFx0XHRyZXR1cm4gdGhpcy5hdHRyKCBcImNsYXNzXCIsIFwiXCIgKTtcblx0XHR9XG5cblx0XHRpZiAoIHR5cGVvZiB2YWx1ZSA9PT0gXCJzdHJpbmdcIiAmJiB2YWx1ZSApIHtcblx0XHRcdGNsYXNzZXMgPSB2YWx1ZS5tYXRjaCggcm5vdGh0bWx3aGl0ZSApIHx8IFtdO1xuXG5cdFx0XHR3aGlsZSAoICggZWxlbSA9IHRoaXNbIGkrKyBdICkgKSB7XG5cdFx0XHRcdGN1clZhbHVlID0gZ2V0Q2xhc3MoIGVsZW0gKTtcblxuXHRcdFx0XHQvLyBUaGlzIGV4cHJlc3Npb24gaXMgaGVyZSBmb3IgYmV0dGVyIGNvbXByZXNzaWJpbGl0eSAoc2VlIGFkZENsYXNzKVxuXHRcdFx0XHRjdXIgPSBlbGVtLm5vZGVUeXBlID09PSAxICYmICggXCIgXCIgKyBzdHJpcEFuZENvbGxhcHNlKCBjdXJWYWx1ZSApICsgXCIgXCIgKTtcblxuXHRcdFx0XHRpZiAoIGN1ciApIHtcblx0XHRcdFx0XHRqID0gMDtcblx0XHRcdFx0XHR3aGlsZSAoICggY2xhenogPSBjbGFzc2VzWyBqKysgXSApICkge1xuXG5cdFx0XHRcdFx0XHQvLyBSZW1vdmUgKmFsbCogaW5zdGFuY2VzXG5cdFx0XHRcdFx0XHR3aGlsZSAoIGN1ci5pbmRleE9mKCBcIiBcIiArIGNsYXp6ICsgXCIgXCIgKSA+IC0xICkge1xuXHRcdFx0XHRcdFx0XHRjdXIgPSBjdXIucmVwbGFjZSggXCIgXCIgKyBjbGF6eiArIFwiIFwiLCBcIiBcIiApO1xuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdC8vIE9ubHkgYXNzaWduIGlmIGRpZmZlcmVudCB0byBhdm9pZCB1bm5lZWRlZCByZW5kZXJpbmcuXG5cdFx0XHRcdFx0ZmluYWxWYWx1ZSA9IHN0cmlwQW5kQ29sbGFwc2UoIGN1ciApO1xuXHRcdFx0XHRcdGlmICggY3VyVmFsdWUgIT09IGZpbmFsVmFsdWUgKSB7XG5cdFx0XHRcdFx0XHRlbGVtLnNldEF0dHJpYnV0ZSggXCJjbGFzc1wiLCBmaW5hbFZhbHVlICk7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0cmV0dXJuIHRoaXM7XG5cdH0sXG5cblx0dG9nZ2xlQ2xhc3M6IGZ1bmN0aW9uKCB2YWx1ZSwgc3RhdGVWYWwgKSB7XG5cdFx0dmFyIHR5cGUgPSB0eXBlb2YgdmFsdWU7XG5cblx0XHRpZiAoIHR5cGVvZiBzdGF0ZVZhbCA9PT0gXCJib29sZWFuXCIgJiYgdHlwZSA9PT0gXCJzdHJpbmdcIiApIHtcblx0XHRcdHJldHVybiBzdGF0ZVZhbCA/IHRoaXMuYWRkQ2xhc3MoIHZhbHVlICkgOiB0aGlzLnJlbW92ZUNsYXNzKCB2YWx1ZSApO1xuXHRcdH1cblxuXHRcdGlmICggalF1ZXJ5LmlzRnVuY3Rpb24oIHZhbHVlICkgKSB7XG5cdFx0XHRyZXR1cm4gdGhpcy5lYWNoKCBmdW5jdGlvbiggaSApIHtcblx0XHRcdFx0alF1ZXJ5KCB0aGlzICkudG9nZ2xlQ2xhc3MoXG5cdFx0XHRcdFx0dmFsdWUuY2FsbCggdGhpcywgaSwgZ2V0Q2xhc3MoIHRoaXMgKSwgc3RhdGVWYWwgKSxcblx0XHRcdFx0XHRzdGF0ZVZhbFxuXHRcdFx0XHQpO1xuXHRcdFx0fSApO1xuXHRcdH1cblxuXHRcdHJldHVybiB0aGlzLmVhY2goIGZ1bmN0aW9uKCkge1xuXHRcdFx0dmFyIGNsYXNzTmFtZSwgaSwgc2VsZiwgY2xhc3NOYW1lcztcblxuXHRcdFx0aWYgKCB0eXBlID09PSBcInN0cmluZ1wiICkge1xuXG5cdFx0XHRcdC8vIFRvZ2dsZSBpbmRpdmlkdWFsIGNsYXNzIG5hbWVzXG5cdFx0XHRcdGkgPSAwO1xuXHRcdFx0XHRzZWxmID0galF1ZXJ5KCB0aGlzICk7XG5cdFx0XHRcdGNsYXNzTmFtZXMgPSB2YWx1ZS5tYXRjaCggcm5vdGh0bWx3aGl0ZSApIHx8IFtdO1xuXG5cdFx0XHRcdHdoaWxlICggKCBjbGFzc05hbWUgPSBjbGFzc05hbWVzWyBpKysgXSApICkge1xuXG5cdFx0XHRcdFx0Ly8gQ2hlY2sgZWFjaCBjbGFzc05hbWUgZ2l2ZW4sIHNwYWNlIHNlcGFyYXRlZCBsaXN0XG5cdFx0XHRcdFx0aWYgKCBzZWxmLmhhc0NsYXNzKCBjbGFzc05hbWUgKSApIHtcblx0XHRcdFx0XHRcdHNlbGYucmVtb3ZlQ2xhc3MoIGNsYXNzTmFtZSApO1xuXHRcdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0XHRzZWxmLmFkZENsYXNzKCBjbGFzc05hbWUgKTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblxuXHRcdFx0Ly8gVG9nZ2xlIHdob2xlIGNsYXNzIG5hbWVcblx0XHRcdH0gZWxzZSBpZiAoIHZhbHVlID09PSB1bmRlZmluZWQgfHwgdHlwZSA9PT0gXCJib29sZWFuXCIgKSB7XG5cdFx0XHRcdGNsYXNzTmFtZSA9IGdldENsYXNzKCB0aGlzICk7XG5cdFx0XHRcdGlmICggY2xhc3NOYW1lICkge1xuXG5cdFx0XHRcdFx0Ly8gU3RvcmUgY2xhc3NOYW1lIGlmIHNldFxuXHRcdFx0XHRcdGRhdGFQcml2LnNldCggdGhpcywgXCJfX2NsYXNzTmFtZV9fXCIsIGNsYXNzTmFtZSApO1xuXHRcdFx0XHR9XG5cblx0XHRcdFx0Ly8gSWYgdGhlIGVsZW1lbnQgaGFzIGEgY2xhc3MgbmFtZSBvciBpZiB3ZSdyZSBwYXNzZWQgYGZhbHNlYCxcblx0XHRcdFx0Ly8gdGhlbiByZW1vdmUgdGhlIHdob2xlIGNsYXNzbmFtZSAoaWYgdGhlcmUgd2FzIG9uZSwgdGhlIGFib3ZlIHNhdmVkIGl0KS5cblx0XHRcdFx0Ly8gT3RoZXJ3aXNlIGJyaW5nIGJhY2sgd2hhdGV2ZXIgd2FzIHByZXZpb3VzbHkgc2F2ZWQgKGlmIGFueXRoaW5nKSxcblx0XHRcdFx0Ly8gZmFsbGluZyBiYWNrIHRvIHRoZSBlbXB0eSBzdHJpbmcgaWYgbm90aGluZyB3YXMgc3RvcmVkLlxuXHRcdFx0XHRpZiAoIHRoaXMuc2V0QXR0cmlidXRlICkge1xuXHRcdFx0XHRcdHRoaXMuc2V0QXR0cmlidXRlKCBcImNsYXNzXCIsXG5cdFx0XHRcdFx0XHRjbGFzc05hbWUgfHwgdmFsdWUgPT09IGZhbHNlID9cblx0XHRcdFx0XHRcdFwiXCIgOlxuXHRcdFx0XHRcdFx0ZGF0YVByaXYuZ2V0KCB0aGlzLCBcIl9fY2xhc3NOYW1lX19cIiApIHx8IFwiXCJcblx0XHRcdFx0XHQpO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fSApO1xuXHR9LFxuXG5cdGhhc0NsYXNzOiBmdW5jdGlvbiggc2VsZWN0b3IgKSB7XG5cdFx0dmFyIGNsYXNzTmFtZSwgZWxlbSxcblx0XHRcdGkgPSAwO1xuXG5cdFx0Y2xhc3NOYW1lID0gXCIgXCIgKyBzZWxlY3RvciArIFwiIFwiO1xuXHRcdHdoaWxlICggKCBlbGVtID0gdGhpc1sgaSsrIF0gKSApIHtcblx0XHRcdGlmICggZWxlbS5ub2RlVHlwZSA9PT0gMSAmJlxuXHRcdFx0XHQoIFwiIFwiICsgc3RyaXBBbmRDb2xsYXBzZSggZ2V0Q2xhc3MoIGVsZW0gKSApICsgXCIgXCIgKS5pbmRleE9mKCBjbGFzc05hbWUgKSA+IC0xICkge1xuXHRcdFx0XHRcdHJldHVybiB0cnVlO1xuXHRcdFx0fVxuXHRcdH1cblxuXHRcdHJldHVybiBmYWxzZTtcblx0fVxufSApO1xuXG5cblxuXG52YXIgcnJldHVybiA9IC9cXHIvZztcblxualF1ZXJ5LmZuLmV4dGVuZCgge1xuXHR2YWw6IGZ1bmN0aW9uKCB2YWx1ZSApIHtcblx0XHR2YXIgaG9va3MsIHJldCwgaXNGdW5jdGlvbixcblx0XHRcdGVsZW0gPSB0aGlzWyAwIF07XG5cblx0XHRpZiAoICFhcmd1bWVudHMubGVuZ3RoICkge1xuXHRcdFx0aWYgKCBlbGVtICkge1xuXHRcdFx0XHRob29rcyA9IGpRdWVyeS52YWxIb29rc1sgZWxlbS50eXBlIF0gfHxcblx0XHRcdFx0XHRqUXVlcnkudmFsSG9va3NbIGVsZW0ubm9kZU5hbWUudG9Mb3dlckNhc2UoKSBdO1xuXG5cdFx0XHRcdGlmICggaG9va3MgJiZcblx0XHRcdFx0XHRcImdldFwiIGluIGhvb2tzICYmXG5cdFx0XHRcdFx0KCByZXQgPSBob29rcy5nZXQoIGVsZW0sIFwidmFsdWVcIiApICkgIT09IHVuZGVmaW5lZFxuXHRcdFx0XHQpIHtcblx0XHRcdFx0XHRyZXR1cm4gcmV0O1xuXHRcdFx0XHR9XG5cblx0XHRcdFx0cmV0ID0gZWxlbS52YWx1ZTtcblxuXHRcdFx0XHQvLyBIYW5kbGUgbW9zdCBjb21tb24gc3RyaW5nIGNhc2VzXG5cdFx0XHRcdGlmICggdHlwZW9mIHJldCA9PT0gXCJzdHJpbmdcIiApIHtcblx0XHRcdFx0XHRyZXR1cm4gcmV0LnJlcGxhY2UoIHJyZXR1cm4sIFwiXCIgKTtcblx0XHRcdFx0fVxuXG5cdFx0XHRcdC8vIEhhbmRsZSBjYXNlcyB3aGVyZSB2YWx1ZSBpcyBudWxsL3VuZGVmIG9yIG51bWJlclxuXHRcdFx0XHRyZXR1cm4gcmV0ID09IG51bGwgPyBcIlwiIDogcmV0O1xuXHRcdFx0fVxuXG5cdFx0XHRyZXR1cm47XG5cdFx0fVxuXG5cdFx0aXNGdW5jdGlvbiA9IGpRdWVyeS5pc0Z1bmN0aW9uKCB2YWx1ZSApO1xuXG5cdFx0cmV0dXJuIHRoaXMuZWFjaCggZnVuY3Rpb24oIGkgKSB7XG5cdFx0XHR2YXIgdmFsO1xuXG5cdFx0XHRpZiAoIHRoaXMubm9kZVR5cGUgIT09IDEgKSB7XG5cdFx0XHRcdHJldHVybjtcblx0XHRcdH1cblxuXHRcdFx0aWYgKCBpc0Z1bmN0aW9uICkge1xuXHRcdFx0XHR2YWwgPSB2YWx1ZS5jYWxsKCB0aGlzLCBpLCBqUXVlcnkoIHRoaXMgKS52YWwoKSApO1xuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0dmFsID0gdmFsdWU7XG5cdFx0XHR9XG5cblx0XHRcdC8vIFRyZWF0IG51bGwvdW5kZWZpbmVkIGFzIFwiXCI7IGNvbnZlcnQgbnVtYmVycyB0byBzdHJpbmdcblx0XHRcdGlmICggdmFsID09IG51bGwgKSB7XG5cdFx0XHRcdHZhbCA9IFwiXCI7XG5cblx0XHRcdH0gZWxzZSBpZiAoIHR5cGVvZiB2YWwgPT09IFwibnVtYmVyXCIgKSB7XG5cdFx0XHRcdHZhbCArPSBcIlwiO1xuXG5cdFx0XHR9IGVsc2UgaWYgKCBBcnJheS5pc0FycmF5KCB2YWwgKSApIHtcblx0XHRcdFx0dmFsID0galF1ZXJ5Lm1hcCggdmFsLCBmdW5jdGlvbiggdmFsdWUgKSB7XG5cdFx0XHRcdFx0cmV0dXJuIHZhbHVlID09IG51bGwgPyBcIlwiIDogdmFsdWUgKyBcIlwiO1xuXHRcdFx0XHR9ICk7XG5cdFx0XHR9XG5cblx0XHRcdGhvb2tzID0galF1ZXJ5LnZhbEhvb2tzWyB0aGlzLnR5cGUgXSB8fCBqUXVlcnkudmFsSG9va3NbIHRoaXMubm9kZU5hbWUudG9Mb3dlckNhc2UoKSBdO1xuXG5cdFx0XHQvLyBJZiBzZXQgcmV0dXJucyB1bmRlZmluZWQsIGZhbGwgYmFjayB0byBub3JtYWwgc2V0dGluZ1xuXHRcdFx0aWYgKCAhaG9va3MgfHwgISggXCJzZXRcIiBpbiBob29rcyApIHx8IGhvb2tzLnNldCggdGhpcywgdmFsLCBcInZhbHVlXCIgKSA9PT0gdW5kZWZpbmVkICkge1xuXHRcdFx0XHR0aGlzLnZhbHVlID0gdmFsO1xuXHRcdFx0fVxuXHRcdH0gKTtcblx0fVxufSApO1xuXG5qUXVlcnkuZXh0ZW5kKCB7XG5cdHZhbEhvb2tzOiB7XG5cdFx0b3B0aW9uOiB7XG5cdFx0XHRnZXQ6IGZ1bmN0aW9uKCBlbGVtICkge1xuXG5cdFx0XHRcdHZhciB2YWwgPSBqUXVlcnkuZmluZC5hdHRyKCBlbGVtLCBcInZhbHVlXCIgKTtcblx0XHRcdFx0cmV0dXJuIHZhbCAhPSBudWxsID9cblx0XHRcdFx0XHR2YWwgOlxuXG5cdFx0XHRcdFx0Ly8gU3VwcG9ydDogSUUgPD0xMCAtIDExIG9ubHlcblx0XHRcdFx0XHQvLyBvcHRpb24udGV4dCB0aHJvd3MgZXhjZXB0aW9ucyAoIzE0Njg2LCAjMTQ4NTgpXG5cdFx0XHRcdFx0Ly8gU3RyaXAgYW5kIGNvbGxhcHNlIHdoaXRlc3BhY2Vcblx0XHRcdFx0XHQvLyBodHRwczovL2h0bWwuc3BlYy53aGF0d2cub3JnLyNzdHJpcC1hbmQtY29sbGFwc2Utd2hpdGVzcGFjZVxuXHRcdFx0XHRcdHN0cmlwQW5kQ29sbGFwc2UoIGpRdWVyeS50ZXh0KCBlbGVtICkgKTtcblx0XHRcdH1cblx0XHR9LFxuXHRcdHNlbGVjdDoge1xuXHRcdFx0Z2V0OiBmdW5jdGlvbiggZWxlbSApIHtcblx0XHRcdFx0dmFyIHZhbHVlLCBvcHRpb24sIGksXG5cdFx0XHRcdFx0b3B0aW9ucyA9IGVsZW0ub3B0aW9ucyxcblx0XHRcdFx0XHRpbmRleCA9IGVsZW0uc2VsZWN0ZWRJbmRleCxcblx0XHRcdFx0XHRvbmUgPSBlbGVtLnR5cGUgPT09IFwic2VsZWN0LW9uZVwiLFxuXHRcdFx0XHRcdHZhbHVlcyA9IG9uZSA/IG51bGwgOiBbXSxcblx0XHRcdFx0XHRtYXggPSBvbmUgPyBpbmRleCArIDEgOiBvcHRpb25zLmxlbmd0aDtcblxuXHRcdFx0XHRpZiAoIGluZGV4IDwgMCApIHtcblx0XHRcdFx0XHRpID0gbWF4O1xuXG5cdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0aSA9IG9uZSA/IGluZGV4IDogMDtcblx0XHRcdFx0fVxuXG5cdFx0XHRcdC8vIExvb3AgdGhyb3VnaCBhbGwgdGhlIHNlbGVjdGVkIG9wdGlvbnNcblx0XHRcdFx0Zm9yICggOyBpIDwgbWF4OyBpKysgKSB7XG5cdFx0XHRcdFx0b3B0aW9uID0gb3B0aW9uc1sgaSBdO1xuXG5cdFx0XHRcdFx0Ly8gU3VwcG9ydDogSUUgPD05IG9ubHlcblx0XHRcdFx0XHQvLyBJRTgtOSBkb2Vzbid0IHVwZGF0ZSBzZWxlY3RlZCBhZnRlciBmb3JtIHJlc2V0ICgjMjU1MSlcblx0XHRcdFx0XHRpZiAoICggb3B0aW9uLnNlbGVjdGVkIHx8IGkgPT09IGluZGV4ICkgJiZcblxuXHRcdFx0XHRcdFx0XHQvLyBEb24ndCByZXR1cm4gb3B0aW9ucyB0aGF0IGFyZSBkaXNhYmxlZCBvciBpbiBhIGRpc2FibGVkIG9wdGdyb3VwXG5cdFx0XHRcdFx0XHRcdCFvcHRpb24uZGlzYWJsZWQgJiZcblx0XHRcdFx0XHRcdFx0KCAhb3B0aW9uLnBhcmVudE5vZGUuZGlzYWJsZWQgfHxcblx0XHRcdFx0XHRcdFx0XHQhbm9kZU5hbWUoIG9wdGlvbi5wYXJlbnROb2RlLCBcIm9wdGdyb3VwXCIgKSApICkge1xuXG5cdFx0XHRcdFx0XHQvLyBHZXQgdGhlIHNwZWNpZmljIHZhbHVlIGZvciB0aGUgb3B0aW9uXG5cdFx0XHRcdFx0XHR2YWx1ZSA9IGpRdWVyeSggb3B0aW9uICkudmFsKCk7XG5cblx0XHRcdFx0XHRcdC8vIFdlIGRvbid0IG5lZWQgYW4gYXJyYXkgZm9yIG9uZSBzZWxlY3RzXG5cdFx0XHRcdFx0XHRpZiAoIG9uZSApIHtcblx0XHRcdFx0XHRcdFx0cmV0dXJuIHZhbHVlO1xuXHRcdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0XHQvLyBNdWx0aS1TZWxlY3RzIHJldHVybiBhbiBhcnJheVxuXHRcdFx0XHRcdFx0dmFsdWVzLnB1c2goIHZhbHVlICk7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cblx0XHRcdFx0cmV0dXJuIHZhbHVlcztcblx0XHRcdH0sXG5cblx0XHRcdHNldDogZnVuY3Rpb24oIGVsZW0sIHZhbHVlICkge1xuXHRcdFx0XHR2YXIgb3B0aW9uU2V0LCBvcHRpb24sXG5cdFx0XHRcdFx0b3B0aW9ucyA9IGVsZW0ub3B0aW9ucyxcblx0XHRcdFx0XHR2YWx1ZXMgPSBqUXVlcnkubWFrZUFycmF5KCB2YWx1ZSApLFxuXHRcdFx0XHRcdGkgPSBvcHRpb25zLmxlbmd0aDtcblxuXHRcdFx0XHR3aGlsZSAoIGktLSApIHtcblx0XHRcdFx0XHRvcHRpb24gPSBvcHRpb25zWyBpIF07XG5cblx0XHRcdFx0XHQvKiBlc2xpbnQtZGlzYWJsZSBuby1jb25kLWFzc2lnbiAqL1xuXG5cdFx0XHRcdFx0aWYgKCBvcHRpb24uc2VsZWN0ZWQgPVxuXHRcdFx0XHRcdFx0alF1ZXJ5LmluQXJyYXkoIGpRdWVyeS52YWxIb29rcy5vcHRpb24uZ2V0KCBvcHRpb24gKSwgdmFsdWVzICkgPiAtMVxuXHRcdFx0XHRcdCkge1xuXHRcdFx0XHRcdFx0b3B0aW9uU2V0ID0gdHJ1ZTtcblx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHQvKiBlc2xpbnQtZW5hYmxlIG5vLWNvbmQtYXNzaWduICovXG5cdFx0XHRcdH1cblxuXHRcdFx0XHQvLyBGb3JjZSBicm93c2VycyB0byBiZWhhdmUgY29uc2lzdGVudGx5IHdoZW4gbm9uLW1hdGNoaW5nIHZhbHVlIGlzIHNldFxuXHRcdFx0XHRpZiAoICFvcHRpb25TZXQgKSB7XG5cdFx0XHRcdFx0ZWxlbS5zZWxlY3RlZEluZGV4ID0gLTE7XG5cdFx0XHRcdH1cblx0XHRcdFx0cmV0dXJuIHZhbHVlcztcblx0XHRcdH1cblx0XHR9XG5cdH1cbn0gKTtcblxuLy8gUmFkaW9zIGFuZCBjaGVja2JveGVzIGdldHRlci9zZXR0ZXJcbmpRdWVyeS5lYWNoKCBbIFwicmFkaW9cIiwgXCJjaGVja2JveFwiIF0sIGZ1bmN0aW9uKCkge1xuXHRqUXVlcnkudmFsSG9va3NbIHRoaXMgXSA9IHtcblx0XHRzZXQ6IGZ1bmN0aW9uKCBlbGVtLCB2YWx1ZSApIHtcblx0XHRcdGlmICggQXJyYXkuaXNBcnJheSggdmFsdWUgKSApIHtcblx0XHRcdFx0cmV0dXJuICggZWxlbS5jaGVja2VkID0galF1ZXJ5LmluQXJyYXkoIGpRdWVyeSggZWxlbSApLnZhbCgpLCB2YWx1ZSApID4gLTEgKTtcblx0XHRcdH1cblx0XHR9XG5cdH07XG5cdGlmICggIXN1cHBvcnQuY2hlY2tPbiApIHtcblx0XHRqUXVlcnkudmFsSG9va3NbIHRoaXMgXS5nZXQgPSBmdW5jdGlvbiggZWxlbSApIHtcblx0XHRcdHJldHVybiBlbGVtLmdldEF0dHJpYnV0ZSggXCJ2YWx1ZVwiICkgPT09IG51bGwgPyBcIm9uXCIgOiBlbGVtLnZhbHVlO1xuXHRcdH07XG5cdH1cbn0gKTtcblxuXG5cblxuLy8gUmV0dXJuIGpRdWVyeSBmb3IgYXR0cmlidXRlcy1vbmx5IGluY2x1c2lvblxuXG5cbnZhciByZm9jdXNNb3JwaCA9IC9eKD86Zm9jdXNpbmZvY3VzfGZvY3Vzb3V0Ymx1cikkLztcblxualF1ZXJ5LmV4dGVuZCggalF1ZXJ5LmV2ZW50LCB7XG5cblx0dHJpZ2dlcjogZnVuY3Rpb24oIGV2ZW50LCBkYXRhLCBlbGVtLCBvbmx5SGFuZGxlcnMgKSB7XG5cblx0XHR2YXIgaSwgY3VyLCB0bXAsIGJ1YmJsZVR5cGUsIG9udHlwZSwgaGFuZGxlLCBzcGVjaWFsLFxuXHRcdFx0ZXZlbnRQYXRoID0gWyBlbGVtIHx8IGRvY3VtZW50IF0sXG5cdFx0XHR0eXBlID0gaGFzT3duLmNhbGwoIGV2ZW50LCBcInR5cGVcIiApID8gZXZlbnQudHlwZSA6IGV2ZW50LFxuXHRcdFx0bmFtZXNwYWNlcyA9IGhhc093bi5jYWxsKCBldmVudCwgXCJuYW1lc3BhY2VcIiApID8gZXZlbnQubmFtZXNwYWNlLnNwbGl0KCBcIi5cIiApIDogW107XG5cblx0XHRjdXIgPSB0bXAgPSBlbGVtID0gZWxlbSB8fCBkb2N1bWVudDtcblxuXHRcdC8vIERvbid0IGRvIGV2ZW50cyBvbiB0ZXh0IGFuZCBjb21tZW50IG5vZGVzXG5cdFx0aWYgKCBlbGVtLm5vZGVUeXBlID09PSAzIHx8IGVsZW0ubm9kZVR5cGUgPT09IDggKSB7XG5cdFx0XHRyZXR1cm47XG5cdFx0fVxuXG5cdFx0Ly8gZm9jdXMvYmx1ciBtb3JwaHMgdG8gZm9jdXNpbi9vdXQ7IGVuc3VyZSB3ZSdyZSBub3QgZmlyaW5nIHRoZW0gcmlnaHQgbm93XG5cdFx0aWYgKCByZm9jdXNNb3JwaC50ZXN0KCB0eXBlICsgalF1ZXJ5LmV2ZW50LnRyaWdnZXJlZCApICkge1xuXHRcdFx0cmV0dXJuO1xuXHRcdH1cblxuXHRcdGlmICggdHlwZS5pbmRleE9mKCBcIi5cIiApID4gLTEgKSB7XG5cblx0XHRcdC8vIE5hbWVzcGFjZWQgdHJpZ2dlcjsgY3JlYXRlIGEgcmVnZXhwIHRvIG1hdGNoIGV2ZW50IHR5cGUgaW4gaGFuZGxlKClcblx0XHRcdG5hbWVzcGFjZXMgPSB0eXBlLnNwbGl0KCBcIi5cIiApO1xuXHRcdFx0dHlwZSA9IG5hbWVzcGFjZXMuc2hpZnQoKTtcblx0XHRcdG5hbWVzcGFjZXMuc29ydCgpO1xuXHRcdH1cblx0XHRvbnR5cGUgPSB0eXBlLmluZGV4T2YoIFwiOlwiICkgPCAwICYmIFwib25cIiArIHR5cGU7XG5cblx0XHQvLyBDYWxsZXIgY2FuIHBhc3MgaW4gYSBqUXVlcnkuRXZlbnQgb2JqZWN0LCBPYmplY3QsIG9yIGp1c3QgYW4gZXZlbnQgdHlwZSBzdHJpbmdcblx0XHRldmVudCA9IGV2ZW50WyBqUXVlcnkuZXhwYW5kbyBdID9cblx0XHRcdGV2ZW50IDpcblx0XHRcdG5ldyBqUXVlcnkuRXZlbnQoIHR5cGUsIHR5cGVvZiBldmVudCA9PT0gXCJvYmplY3RcIiAmJiBldmVudCApO1xuXG5cdFx0Ly8gVHJpZ2dlciBiaXRtYXNrOiAmIDEgZm9yIG5hdGl2ZSBoYW5kbGVyczsgJiAyIGZvciBqUXVlcnkgKGFsd2F5cyB0cnVlKVxuXHRcdGV2ZW50LmlzVHJpZ2dlciA9IG9ubHlIYW5kbGVycyA/IDIgOiAzO1xuXHRcdGV2ZW50Lm5hbWVzcGFjZSA9IG5hbWVzcGFjZXMuam9pbiggXCIuXCIgKTtcblx0XHRldmVudC5ybmFtZXNwYWNlID0gZXZlbnQubmFtZXNwYWNlID9cblx0XHRcdG5ldyBSZWdFeHAoIFwiKF58XFxcXC4pXCIgKyBuYW1lc3BhY2VzLmpvaW4oIFwiXFxcXC4oPzouKlxcXFwufClcIiApICsgXCIoXFxcXC58JClcIiApIDpcblx0XHRcdG51bGw7XG5cblx0XHQvLyBDbGVhbiB1cCB0aGUgZXZlbnQgaW4gY2FzZSBpdCBpcyBiZWluZyByZXVzZWRcblx0XHRldmVudC5yZXN1bHQgPSB1bmRlZmluZWQ7XG5cdFx0aWYgKCAhZXZlbnQudGFyZ2V0ICkge1xuXHRcdFx0ZXZlbnQudGFyZ2V0ID0gZWxlbTtcblx0XHR9XG5cblx0XHQvLyBDbG9uZSBhbnkgaW5jb21pbmcgZGF0YSBhbmQgcHJlcGVuZCB0aGUgZXZlbnQsIGNyZWF0aW5nIHRoZSBoYW5kbGVyIGFyZyBsaXN0XG5cdFx0ZGF0YSA9IGRhdGEgPT0gbnVsbCA/XG5cdFx0XHRbIGV2ZW50IF0gOlxuXHRcdFx0alF1ZXJ5Lm1ha2VBcnJheSggZGF0YSwgWyBldmVudCBdICk7XG5cblx0XHQvLyBBbGxvdyBzcGVjaWFsIGV2ZW50cyB0byBkcmF3IG91dHNpZGUgdGhlIGxpbmVzXG5cdFx0c3BlY2lhbCA9IGpRdWVyeS5ldmVudC5zcGVjaWFsWyB0eXBlIF0gfHwge307XG5cdFx0aWYgKCAhb25seUhhbmRsZXJzICYmIHNwZWNpYWwudHJpZ2dlciAmJiBzcGVjaWFsLnRyaWdnZXIuYXBwbHkoIGVsZW0sIGRhdGEgKSA9PT0gZmFsc2UgKSB7XG5cdFx0XHRyZXR1cm47XG5cdFx0fVxuXG5cdFx0Ly8gRGV0ZXJtaW5lIGV2ZW50IHByb3BhZ2F0aW9uIHBhdGggaW4gYWR2YW5jZSwgcGVyIFczQyBldmVudHMgc3BlYyAoIzk5NTEpXG5cdFx0Ly8gQnViYmxlIHVwIHRvIGRvY3VtZW50LCB0aGVuIHRvIHdpbmRvdzsgd2F0Y2ggZm9yIGEgZ2xvYmFsIG93bmVyRG9jdW1lbnQgdmFyICgjOTcyNClcblx0XHRpZiAoICFvbmx5SGFuZGxlcnMgJiYgIXNwZWNpYWwubm9CdWJibGUgJiYgIWpRdWVyeS5pc1dpbmRvdyggZWxlbSApICkge1xuXG5cdFx0XHRidWJibGVUeXBlID0gc3BlY2lhbC5kZWxlZ2F0ZVR5cGUgfHwgdHlwZTtcblx0XHRcdGlmICggIXJmb2N1c01vcnBoLnRlc3QoIGJ1YmJsZVR5cGUgKyB0eXBlICkgKSB7XG5cdFx0XHRcdGN1ciA9IGN1ci5wYXJlbnROb2RlO1xuXHRcdFx0fVxuXHRcdFx0Zm9yICggOyBjdXI7IGN1ciA9IGN1ci5wYXJlbnROb2RlICkge1xuXHRcdFx0XHRldmVudFBhdGgucHVzaCggY3VyICk7XG5cdFx0XHRcdHRtcCA9IGN1cjtcblx0XHRcdH1cblxuXHRcdFx0Ly8gT25seSBhZGQgd2luZG93IGlmIHdlIGdvdCB0byBkb2N1bWVudCAoZS5nLiwgbm90IHBsYWluIG9iaiBvciBkZXRhY2hlZCBET00pXG5cdFx0XHRpZiAoIHRtcCA9PT0gKCBlbGVtLm93bmVyRG9jdW1lbnQgfHwgZG9jdW1lbnQgKSApIHtcblx0XHRcdFx0ZXZlbnRQYXRoLnB1c2goIHRtcC5kZWZhdWx0VmlldyB8fCB0bXAucGFyZW50V2luZG93IHx8IHdpbmRvdyApO1xuXHRcdFx0fVxuXHRcdH1cblxuXHRcdC8vIEZpcmUgaGFuZGxlcnMgb24gdGhlIGV2ZW50IHBhdGhcblx0XHRpID0gMDtcblx0XHR3aGlsZSAoICggY3VyID0gZXZlbnRQYXRoWyBpKysgXSApICYmICFldmVudC5pc1Byb3BhZ2F0aW9uU3RvcHBlZCgpICkge1xuXG5cdFx0XHRldmVudC50eXBlID0gaSA+IDEgP1xuXHRcdFx0XHRidWJibGVUeXBlIDpcblx0XHRcdFx0c3BlY2lhbC5iaW5kVHlwZSB8fCB0eXBlO1xuXG5cdFx0XHQvLyBqUXVlcnkgaGFuZGxlclxuXHRcdFx0aGFuZGxlID0gKCBkYXRhUHJpdi5nZXQoIGN1ciwgXCJldmVudHNcIiApIHx8IHt9IClbIGV2ZW50LnR5cGUgXSAmJlxuXHRcdFx0XHRkYXRhUHJpdi5nZXQoIGN1ciwgXCJoYW5kbGVcIiApO1xuXHRcdFx0aWYgKCBoYW5kbGUgKSB7XG5cdFx0XHRcdGhhbmRsZS5hcHBseSggY3VyLCBkYXRhICk7XG5cdFx0XHR9XG5cblx0XHRcdC8vIE5hdGl2ZSBoYW5kbGVyXG5cdFx0XHRoYW5kbGUgPSBvbnR5cGUgJiYgY3VyWyBvbnR5cGUgXTtcblx0XHRcdGlmICggaGFuZGxlICYmIGhhbmRsZS5hcHBseSAmJiBhY2NlcHREYXRhKCBjdXIgKSApIHtcblx0XHRcdFx0ZXZlbnQucmVzdWx0ID0gaGFuZGxlLmFwcGx5KCBjdXIsIGRhdGEgKTtcblx0XHRcdFx0aWYgKCBldmVudC5yZXN1bHQgPT09IGZhbHNlICkge1xuXHRcdFx0XHRcdGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9XG5cdFx0ZXZlbnQudHlwZSA9IHR5cGU7XG5cblx0XHQvLyBJZiBub2JvZHkgcHJldmVudGVkIHRoZSBkZWZhdWx0IGFjdGlvbiwgZG8gaXQgbm93XG5cdFx0aWYgKCAhb25seUhhbmRsZXJzICYmICFldmVudC5pc0RlZmF1bHRQcmV2ZW50ZWQoKSApIHtcblxuXHRcdFx0aWYgKCAoICFzcGVjaWFsLl9kZWZhdWx0IHx8XG5cdFx0XHRcdHNwZWNpYWwuX2RlZmF1bHQuYXBwbHkoIGV2ZW50UGF0aC5wb3AoKSwgZGF0YSApID09PSBmYWxzZSApICYmXG5cdFx0XHRcdGFjY2VwdERhdGEoIGVsZW0gKSApIHtcblxuXHRcdFx0XHQvLyBDYWxsIGEgbmF0aXZlIERPTSBtZXRob2Qgb24gdGhlIHRhcmdldCB3aXRoIHRoZSBzYW1lIG5hbWUgYXMgdGhlIGV2ZW50LlxuXHRcdFx0XHQvLyBEb24ndCBkbyBkZWZhdWx0IGFjdGlvbnMgb24gd2luZG93LCB0aGF0J3Mgd2hlcmUgZ2xvYmFsIHZhcmlhYmxlcyBiZSAoIzYxNzApXG5cdFx0XHRcdGlmICggb250eXBlICYmIGpRdWVyeS5pc0Z1bmN0aW9uKCBlbGVtWyB0eXBlIF0gKSAmJiAhalF1ZXJ5LmlzV2luZG93KCBlbGVtICkgKSB7XG5cblx0XHRcdFx0XHQvLyBEb24ndCByZS10cmlnZ2VyIGFuIG9uRk9PIGV2ZW50IHdoZW4gd2UgY2FsbCBpdHMgRk9PKCkgbWV0aG9kXG5cdFx0XHRcdFx0dG1wID0gZWxlbVsgb250eXBlIF07XG5cblx0XHRcdFx0XHRpZiAoIHRtcCApIHtcblx0XHRcdFx0XHRcdGVsZW1bIG9udHlwZSBdID0gbnVsbDtcblx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHQvLyBQcmV2ZW50IHJlLXRyaWdnZXJpbmcgb2YgdGhlIHNhbWUgZXZlbnQsIHNpbmNlIHdlIGFscmVhZHkgYnViYmxlZCBpdCBhYm92ZVxuXHRcdFx0XHRcdGpRdWVyeS5ldmVudC50cmlnZ2VyZWQgPSB0eXBlO1xuXHRcdFx0XHRcdGVsZW1bIHR5cGUgXSgpO1xuXHRcdFx0XHRcdGpRdWVyeS5ldmVudC50cmlnZ2VyZWQgPSB1bmRlZmluZWQ7XG5cblx0XHRcdFx0XHRpZiAoIHRtcCApIHtcblx0XHRcdFx0XHRcdGVsZW1bIG9udHlwZSBdID0gdG1wO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH1cblxuXHRcdHJldHVybiBldmVudC5yZXN1bHQ7XG5cdH0sXG5cblx0Ly8gUGlnZ3liYWNrIG9uIGEgZG9ub3IgZXZlbnQgdG8gc2ltdWxhdGUgYSBkaWZmZXJlbnQgb25lXG5cdC8vIFVzZWQgb25seSBmb3IgYGZvY3VzKGluIHwgb3V0KWAgZXZlbnRzXG5cdHNpbXVsYXRlOiBmdW5jdGlvbiggdHlwZSwgZWxlbSwgZXZlbnQgKSB7XG5cdFx0dmFyIGUgPSBqUXVlcnkuZXh0ZW5kKFxuXHRcdFx0bmV3IGpRdWVyeS5FdmVudCgpLFxuXHRcdFx0ZXZlbnQsXG5cdFx0XHR7XG5cdFx0XHRcdHR5cGU6IHR5cGUsXG5cdFx0XHRcdGlzU2ltdWxhdGVkOiB0cnVlXG5cdFx0XHR9XG5cdFx0KTtcblxuXHRcdGpRdWVyeS5ldmVudC50cmlnZ2VyKCBlLCBudWxsLCBlbGVtICk7XG5cdH1cblxufSApO1xuXG5qUXVlcnkuZm4uZXh0ZW5kKCB7XG5cblx0dHJpZ2dlcjogZnVuY3Rpb24oIHR5cGUsIGRhdGEgKSB7XG5cdFx0cmV0dXJuIHRoaXMuZWFjaCggZnVuY3Rpb24oKSB7XG5cdFx0XHRqUXVlcnkuZXZlbnQudHJpZ2dlciggdHlwZSwgZGF0YSwgdGhpcyApO1xuXHRcdH0gKTtcblx0fSxcblx0dHJpZ2dlckhhbmRsZXI6IGZ1bmN0aW9uKCB0eXBlLCBkYXRhICkge1xuXHRcdHZhciBlbGVtID0gdGhpc1sgMCBdO1xuXHRcdGlmICggZWxlbSApIHtcblx0XHRcdHJldHVybiBqUXVlcnkuZXZlbnQudHJpZ2dlciggdHlwZSwgZGF0YSwgZWxlbSwgdHJ1ZSApO1xuXHRcdH1cblx0fVxufSApO1xuXG5cbmpRdWVyeS5lYWNoKCAoIFwiYmx1ciBmb2N1cyBmb2N1c2luIGZvY3Vzb3V0IHJlc2l6ZSBzY3JvbGwgY2xpY2sgZGJsY2xpY2sgXCIgK1xuXHRcIm1vdXNlZG93biBtb3VzZXVwIG1vdXNlbW92ZSBtb3VzZW92ZXIgbW91c2VvdXQgbW91c2VlbnRlciBtb3VzZWxlYXZlIFwiICtcblx0XCJjaGFuZ2Ugc2VsZWN0IHN1Ym1pdCBrZXlkb3duIGtleXByZXNzIGtleXVwIGNvbnRleHRtZW51XCIgKS5zcGxpdCggXCIgXCIgKSxcblx0ZnVuY3Rpb24oIGksIG5hbWUgKSB7XG5cblx0Ly8gSGFuZGxlIGV2ZW50IGJpbmRpbmdcblx0alF1ZXJ5LmZuWyBuYW1lIF0gPSBmdW5jdGlvbiggZGF0YSwgZm4gKSB7XG5cdFx0cmV0dXJuIGFyZ3VtZW50cy5sZW5ndGggPiAwID9cblx0XHRcdHRoaXMub24oIG5hbWUsIG51bGwsIGRhdGEsIGZuICkgOlxuXHRcdFx0dGhpcy50cmlnZ2VyKCBuYW1lICk7XG5cdH07XG59ICk7XG5cbmpRdWVyeS5mbi5leHRlbmQoIHtcblx0aG92ZXI6IGZ1bmN0aW9uKCBmbk92ZXIsIGZuT3V0ICkge1xuXHRcdHJldHVybiB0aGlzLm1vdXNlZW50ZXIoIGZuT3ZlciApLm1vdXNlbGVhdmUoIGZuT3V0IHx8IGZuT3ZlciApO1xuXHR9XG59ICk7XG5cblxuXG5cbnN1cHBvcnQuZm9jdXNpbiA9IFwib25mb2N1c2luXCIgaW4gd2luZG93O1xuXG5cbi8vIFN1cHBvcnQ6IEZpcmVmb3ggPD00NFxuLy8gRmlyZWZveCBkb2Vzbid0IGhhdmUgZm9jdXMoaW4gfCBvdXQpIGV2ZW50c1xuLy8gUmVsYXRlZCB0aWNrZXQgLSBodHRwczovL2J1Z3ppbGxhLm1vemlsbGEub3JnL3Nob3dfYnVnLmNnaT9pZD02ODc3ODdcbi8vXG4vLyBTdXBwb3J0OiBDaHJvbWUgPD00OCAtIDQ5LCBTYWZhcmkgPD05LjAgLSA5LjFcbi8vIGZvY3VzKGluIHwgb3V0KSBldmVudHMgZmlyZSBhZnRlciBmb2N1cyAmIGJsdXIgZXZlbnRzLFxuLy8gd2hpY2ggaXMgc3BlYyB2aW9sYXRpb24gLSBodHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMy1FdmVudHMvI2V2ZW50cy1mb2N1c2V2ZW50LWV2ZW50LW9yZGVyXG4vLyBSZWxhdGVkIHRpY2tldCAtIGh0dHBzOi8vYnVncy5jaHJvbWl1bS5vcmcvcC9jaHJvbWl1bS9pc3N1ZXMvZGV0YWlsP2lkPTQ0OTg1N1xuaWYgKCAhc3VwcG9ydC5mb2N1c2luICkge1xuXHRqUXVlcnkuZWFjaCggeyBmb2N1czogXCJmb2N1c2luXCIsIGJsdXI6IFwiZm9jdXNvdXRcIiB9LCBmdW5jdGlvbiggb3JpZywgZml4ICkge1xuXG5cdFx0Ly8gQXR0YWNoIGEgc2luZ2xlIGNhcHR1cmluZyBoYW5kbGVyIG9uIHRoZSBkb2N1bWVudCB3aGlsZSBzb21lb25lIHdhbnRzIGZvY3VzaW4vZm9jdXNvdXRcblx0XHR2YXIgaGFuZGxlciA9IGZ1bmN0aW9uKCBldmVudCApIHtcblx0XHRcdGpRdWVyeS5ldmVudC5zaW11bGF0ZSggZml4LCBldmVudC50YXJnZXQsIGpRdWVyeS5ldmVudC5maXgoIGV2ZW50ICkgKTtcblx0XHR9O1xuXG5cdFx0alF1ZXJ5LmV2ZW50LnNwZWNpYWxbIGZpeCBdID0ge1xuXHRcdFx0c2V0dXA6IGZ1bmN0aW9uKCkge1xuXHRcdFx0XHR2YXIgZG9jID0gdGhpcy5vd25lckRvY3VtZW50IHx8IHRoaXMsXG5cdFx0XHRcdFx0YXR0YWNoZXMgPSBkYXRhUHJpdi5hY2Nlc3MoIGRvYywgZml4ICk7XG5cblx0XHRcdFx0aWYgKCAhYXR0YWNoZXMgKSB7XG5cdFx0XHRcdFx0ZG9jLmFkZEV2ZW50TGlzdGVuZXIoIG9yaWcsIGhhbmRsZXIsIHRydWUgKTtcblx0XHRcdFx0fVxuXHRcdFx0XHRkYXRhUHJpdi5hY2Nlc3MoIGRvYywgZml4LCAoIGF0dGFjaGVzIHx8IDAgKSArIDEgKTtcblx0XHRcdH0sXG5cdFx0XHR0ZWFyZG93bjogZnVuY3Rpb24oKSB7XG5cdFx0XHRcdHZhciBkb2MgPSB0aGlzLm93bmVyRG9jdW1lbnQgfHwgdGhpcyxcblx0XHRcdFx0XHRhdHRhY2hlcyA9IGRhdGFQcml2LmFjY2VzcyggZG9jLCBmaXggKSAtIDE7XG5cblx0XHRcdFx0aWYgKCAhYXR0YWNoZXMgKSB7XG5cdFx0XHRcdFx0ZG9jLnJlbW92ZUV2ZW50TGlzdGVuZXIoIG9yaWcsIGhhbmRsZXIsIHRydWUgKTtcblx0XHRcdFx0XHRkYXRhUHJpdi5yZW1vdmUoIGRvYywgZml4ICk7XG5cblx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRkYXRhUHJpdi5hY2Nlc3MoIGRvYywgZml4LCBhdHRhY2hlcyApO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fTtcblx0fSApO1xufVxudmFyIGxvY2F0aW9uID0gd2luZG93LmxvY2F0aW9uO1xuXG52YXIgbm9uY2UgPSBqUXVlcnkubm93KCk7XG5cbnZhciBycXVlcnkgPSAoIC9cXD8vICk7XG5cblxuXG4vLyBDcm9zcy1icm93c2VyIHhtbCBwYXJzaW5nXG5qUXVlcnkucGFyc2VYTUwgPSBmdW5jdGlvbiggZGF0YSApIHtcblx0dmFyIHhtbDtcblx0aWYgKCAhZGF0YSB8fCB0eXBlb2YgZGF0YSAhPT0gXCJzdHJpbmdcIiApIHtcblx0XHRyZXR1cm4gbnVsbDtcblx0fVxuXG5cdC8vIFN1cHBvcnQ6IElFIDkgLSAxMSBvbmx5XG5cdC8vIElFIHRocm93cyBvbiBwYXJzZUZyb21TdHJpbmcgd2l0aCBpbnZhbGlkIGlucHV0LlxuXHR0cnkge1xuXHRcdHhtbCA9ICggbmV3IHdpbmRvdy5ET01QYXJzZXIoKSApLnBhcnNlRnJvbVN0cmluZyggZGF0YSwgXCJ0ZXh0L3htbFwiICk7XG5cdH0gY2F0Y2ggKCBlICkge1xuXHRcdHhtbCA9IHVuZGVmaW5lZDtcblx0fVxuXG5cdGlmICggIXhtbCB8fCB4bWwuZ2V0RWxlbWVudHNCeVRhZ05hbWUoIFwicGFyc2VyZXJyb3JcIiApLmxlbmd0aCApIHtcblx0XHRqUXVlcnkuZXJyb3IoIFwiSW52YWxpZCBYTUw6IFwiICsgZGF0YSApO1xuXHR9XG5cdHJldHVybiB4bWw7XG59O1xuXG5cbnZhclxuXHRyYnJhY2tldCA9IC9cXFtcXF0kLyxcblx0ckNSTEYgPSAvXFxyP1xcbi9nLFxuXHRyc3VibWl0dGVyVHlwZXMgPSAvXig/OnN1Ym1pdHxidXR0b258aW1hZ2V8cmVzZXR8ZmlsZSkkL2ksXG5cdHJzdWJtaXR0YWJsZSA9IC9eKD86aW5wdXR8c2VsZWN0fHRleHRhcmVhfGtleWdlbikvaTtcblxuZnVuY3Rpb24gYnVpbGRQYXJhbXMoIHByZWZpeCwgb2JqLCB0cmFkaXRpb25hbCwgYWRkICkge1xuXHR2YXIgbmFtZTtcblxuXHRpZiAoIEFycmF5LmlzQXJyYXkoIG9iaiApICkge1xuXG5cdFx0Ly8gU2VyaWFsaXplIGFycmF5IGl0ZW0uXG5cdFx0alF1ZXJ5LmVhY2goIG9iaiwgZnVuY3Rpb24oIGksIHYgKSB7XG5cdFx0XHRpZiAoIHRyYWRpdGlvbmFsIHx8IHJicmFja2V0LnRlc3QoIHByZWZpeCApICkge1xuXG5cdFx0XHRcdC8vIFRyZWF0IGVhY2ggYXJyYXkgaXRlbSBhcyBhIHNjYWxhci5cblx0XHRcdFx0YWRkKCBwcmVmaXgsIHYgKTtcblxuXHRcdFx0fSBlbHNlIHtcblxuXHRcdFx0XHQvLyBJdGVtIGlzIG5vbi1zY2FsYXIgKGFycmF5IG9yIG9iamVjdCksIGVuY29kZSBpdHMgbnVtZXJpYyBpbmRleC5cblx0XHRcdFx0YnVpbGRQYXJhbXMoXG5cdFx0XHRcdFx0cHJlZml4ICsgXCJbXCIgKyAoIHR5cGVvZiB2ID09PSBcIm9iamVjdFwiICYmIHYgIT0gbnVsbCA/IGkgOiBcIlwiICkgKyBcIl1cIixcblx0XHRcdFx0XHR2LFxuXHRcdFx0XHRcdHRyYWRpdGlvbmFsLFxuXHRcdFx0XHRcdGFkZFxuXHRcdFx0XHQpO1xuXHRcdFx0fVxuXHRcdH0gKTtcblxuXHR9IGVsc2UgaWYgKCAhdHJhZGl0aW9uYWwgJiYgalF1ZXJ5LnR5cGUoIG9iaiApID09PSBcIm9iamVjdFwiICkge1xuXG5cdFx0Ly8gU2VyaWFsaXplIG9iamVjdCBpdGVtLlxuXHRcdGZvciAoIG5hbWUgaW4gb2JqICkge1xuXHRcdFx0YnVpbGRQYXJhbXMoIHByZWZpeCArIFwiW1wiICsgbmFtZSArIFwiXVwiLCBvYmpbIG5hbWUgXSwgdHJhZGl0aW9uYWwsIGFkZCApO1xuXHRcdH1cblxuXHR9IGVsc2Uge1xuXG5cdFx0Ly8gU2VyaWFsaXplIHNjYWxhciBpdGVtLlxuXHRcdGFkZCggcHJlZml4LCBvYmogKTtcblx0fVxufVxuXG4vLyBTZXJpYWxpemUgYW4gYXJyYXkgb2YgZm9ybSBlbGVtZW50cyBvciBhIHNldCBvZlxuLy8ga2V5L3ZhbHVlcyBpbnRvIGEgcXVlcnkgc3RyaW5nXG5qUXVlcnkucGFyYW0gPSBmdW5jdGlvbiggYSwgdHJhZGl0aW9uYWwgKSB7XG5cdHZhciBwcmVmaXgsXG5cdFx0cyA9IFtdLFxuXHRcdGFkZCA9IGZ1bmN0aW9uKCBrZXksIHZhbHVlT3JGdW5jdGlvbiApIHtcblxuXHRcdFx0Ly8gSWYgdmFsdWUgaXMgYSBmdW5jdGlvbiwgaW52b2tlIGl0IGFuZCB1c2UgaXRzIHJldHVybiB2YWx1ZVxuXHRcdFx0dmFyIHZhbHVlID0galF1ZXJ5LmlzRnVuY3Rpb24oIHZhbHVlT3JGdW5jdGlvbiApID9cblx0XHRcdFx0dmFsdWVPckZ1bmN0aW9uKCkgOlxuXHRcdFx0XHR2YWx1ZU9yRnVuY3Rpb247XG5cblx0XHRcdHNbIHMubGVuZ3RoIF0gPSBlbmNvZGVVUklDb21wb25lbnQoIGtleSApICsgXCI9XCIgK1xuXHRcdFx0XHRlbmNvZGVVUklDb21wb25lbnQoIHZhbHVlID09IG51bGwgPyBcIlwiIDogdmFsdWUgKTtcblx0XHR9O1xuXG5cdC8vIElmIGFuIGFycmF5IHdhcyBwYXNzZWQgaW4sIGFzc3VtZSB0aGF0IGl0IGlzIGFuIGFycmF5IG9mIGZvcm0gZWxlbWVudHMuXG5cdGlmICggQXJyYXkuaXNBcnJheSggYSApIHx8ICggYS5qcXVlcnkgJiYgIWpRdWVyeS5pc1BsYWluT2JqZWN0KCBhICkgKSApIHtcblxuXHRcdC8vIFNlcmlhbGl6ZSB0aGUgZm9ybSBlbGVtZW50c1xuXHRcdGpRdWVyeS5lYWNoKCBhLCBmdW5jdGlvbigpIHtcblx0XHRcdGFkZCggdGhpcy5uYW1lLCB0aGlzLnZhbHVlICk7XG5cdFx0fSApO1xuXG5cdH0gZWxzZSB7XG5cblx0XHQvLyBJZiB0cmFkaXRpb25hbCwgZW5jb2RlIHRoZSBcIm9sZFwiIHdheSAodGhlIHdheSAxLjMuMiBvciBvbGRlclxuXHRcdC8vIGRpZCBpdCksIG90aGVyd2lzZSBlbmNvZGUgcGFyYW1zIHJlY3Vyc2l2ZWx5LlxuXHRcdGZvciAoIHByZWZpeCBpbiBhICkge1xuXHRcdFx0YnVpbGRQYXJhbXMoIHByZWZpeCwgYVsgcHJlZml4IF0sIHRyYWRpdGlvbmFsLCBhZGQgKTtcblx0XHR9XG5cdH1cblxuXHQvLyBSZXR1cm4gdGhlIHJlc3VsdGluZyBzZXJpYWxpemF0aW9uXG5cdHJldHVybiBzLmpvaW4oIFwiJlwiICk7XG59O1xuXG5qUXVlcnkuZm4uZXh0ZW5kKCB7XG5cdHNlcmlhbGl6ZTogZnVuY3Rpb24oKSB7XG5cdFx0cmV0dXJuIGpRdWVyeS5wYXJhbSggdGhpcy5zZXJpYWxpemVBcnJheSgpICk7XG5cdH0sXG5cdHNlcmlhbGl6ZUFycmF5OiBmdW5jdGlvbigpIHtcblx0XHRyZXR1cm4gdGhpcy5tYXAoIGZ1bmN0aW9uKCkge1xuXG5cdFx0XHQvLyBDYW4gYWRkIHByb3BIb29rIGZvciBcImVsZW1lbnRzXCIgdG8gZmlsdGVyIG9yIGFkZCBmb3JtIGVsZW1lbnRzXG5cdFx0XHR2YXIgZWxlbWVudHMgPSBqUXVlcnkucHJvcCggdGhpcywgXCJlbGVtZW50c1wiICk7XG5cdFx0XHRyZXR1cm4gZWxlbWVudHMgPyBqUXVlcnkubWFrZUFycmF5KCBlbGVtZW50cyApIDogdGhpcztcblx0XHR9IClcblx0XHQuZmlsdGVyKCBmdW5jdGlvbigpIHtcblx0XHRcdHZhciB0eXBlID0gdGhpcy50eXBlO1xuXG5cdFx0XHQvLyBVc2UgLmlzKCBcIjpkaXNhYmxlZFwiICkgc28gdGhhdCBmaWVsZHNldFtkaXNhYmxlZF0gd29ya3Ncblx0XHRcdHJldHVybiB0aGlzLm5hbWUgJiYgIWpRdWVyeSggdGhpcyApLmlzKCBcIjpkaXNhYmxlZFwiICkgJiZcblx0XHRcdFx0cnN1Ym1pdHRhYmxlLnRlc3QoIHRoaXMubm9kZU5hbWUgKSAmJiAhcnN1Ym1pdHRlclR5cGVzLnRlc3QoIHR5cGUgKSAmJlxuXHRcdFx0XHQoIHRoaXMuY2hlY2tlZCB8fCAhcmNoZWNrYWJsZVR5cGUudGVzdCggdHlwZSApICk7XG5cdFx0fSApXG5cdFx0Lm1hcCggZnVuY3Rpb24oIGksIGVsZW0gKSB7XG5cdFx0XHR2YXIgdmFsID0galF1ZXJ5KCB0aGlzICkudmFsKCk7XG5cblx0XHRcdGlmICggdmFsID09IG51bGwgKSB7XG5cdFx0XHRcdHJldHVybiBudWxsO1xuXHRcdFx0fVxuXG5cdFx0XHRpZiAoIEFycmF5LmlzQXJyYXkoIHZhbCApICkge1xuXHRcdFx0XHRyZXR1cm4galF1ZXJ5Lm1hcCggdmFsLCBmdW5jdGlvbiggdmFsICkge1xuXHRcdFx0XHRcdHJldHVybiB7IG5hbWU6IGVsZW0ubmFtZSwgdmFsdWU6IHZhbC5yZXBsYWNlKCByQ1JMRiwgXCJcXHJcXG5cIiApIH07XG5cdFx0XHRcdH0gKTtcblx0XHRcdH1cblxuXHRcdFx0cmV0dXJuIHsgbmFtZTogZWxlbS5uYW1lLCB2YWx1ZTogdmFsLnJlcGxhY2UoIHJDUkxGLCBcIlxcclxcblwiICkgfTtcblx0XHR9ICkuZ2V0KCk7XG5cdH1cbn0gKTtcblxuXG52YXJcblx0cjIwID0gLyUyMC9nLFxuXHRyaGFzaCA9IC8jLiokLyxcblx0cmFudGlDYWNoZSA9IC8oWz8mXSlfPVteJl0qLyxcblx0cmhlYWRlcnMgPSAvXiguKj8pOlsgXFx0XSooW15cXHJcXG5dKikkL21nLFxuXG5cdC8vICM3NjUzLCAjODEyNSwgIzgxNTI6IGxvY2FsIHByb3RvY29sIGRldGVjdGlvblxuXHRybG9jYWxQcm90b2NvbCA9IC9eKD86YWJvdXR8YXBwfGFwcC1zdG9yYWdlfC4rLWV4dGVuc2lvbnxmaWxlfHJlc3x3aWRnZXQpOiQvLFxuXHRybm9Db250ZW50ID0gL14oPzpHRVR8SEVBRCkkLyxcblx0cnByb3RvY29sID0gL15cXC9cXC8vLFxuXG5cdC8qIFByZWZpbHRlcnNcblx0ICogMSkgVGhleSBhcmUgdXNlZnVsIHRvIGludHJvZHVjZSBjdXN0b20gZGF0YVR5cGVzIChzZWUgYWpheC9qc29ucC5qcyBmb3IgYW4gZXhhbXBsZSlcblx0ICogMikgVGhlc2UgYXJlIGNhbGxlZDpcblx0ICogICAgLSBCRUZPUkUgYXNraW5nIGZvciBhIHRyYW5zcG9ydFxuXHQgKiAgICAtIEFGVEVSIHBhcmFtIHNlcmlhbGl6YXRpb24gKHMuZGF0YSBpcyBhIHN0cmluZyBpZiBzLnByb2Nlc3NEYXRhIGlzIHRydWUpXG5cdCAqIDMpIGtleSBpcyB0aGUgZGF0YVR5cGVcblx0ICogNCkgdGhlIGNhdGNoYWxsIHN5bWJvbCBcIipcIiBjYW4gYmUgdXNlZFxuXHQgKiA1KSBleGVjdXRpb24gd2lsbCBzdGFydCB3aXRoIHRyYW5zcG9ydCBkYXRhVHlwZSBhbmQgVEhFTiBjb250aW51ZSBkb3duIHRvIFwiKlwiIGlmIG5lZWRlZFxuXHQgKi9cblx0cHJlZmlsdGVycyA9IHt9LFxuXG5cdC8qIFRyYW5zcG9ydHMgYmluZGluZ3Ncblx0ICogMSkga2V5IGlzIHRoZSBkYXRhVHlwZVxuXHQgKiAyKSB0aGUgY2F0Y2hhbGwgc3ltYm9sIFwiKlwiIGNhbiBiZSB1c2VkXG5cdCAqIDMpIHNlbGVjdGlvbiB3aWxsIHN0YXJ0IHdpdGggdHJhbnNwb3J0IGRhdGFUeXBlIGFuZCBUSEVOIGdvIHRvIFwiKlwiIGlmIG5lZWRlZFxuXHQgKi9cblx0dHJhbnNwb3J0cyA9IHt9LFxuXG5cdC8vIEF2b2lkIGNvbW1lbnQtcHJvbG9nIGNoYXIgc2VxdWVuY2UgKCMxMDA5OCk7IG11c3QgYXBwZWFzZSBsaW50IGFuZCBldmFkZSBjb21wcmVzc2lvblxuXHRhbGxUeXBlcyA9IFwiKi9cIi5jb25jYXQoIFwiKlwiICksXG5cblx0Ly8gQW5jaG9yIHRhZyBmb3IgcGFyc2luZyB0aGUgZG9jdW1lbnQgb3JpZ2luXG5cdG9yaWdpbkFuY2hvciA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoIFwiYVwiICk7XG5cdG9yaWdpbkFuY2hvci5ocmVmID0gbG9jYXRpb24uaHJlZjtcblxuLy8gQmFzZSBcImNvbnN0cnVjdG9yXCIgZm9yIGpRdWVyeS5hamF4UHJlZmlsdGVyIGFuZCBqUXVlcnkuYWpheFRyYW5zcG9ydFxuZnVuY3Rpb24gYWRkVG9QcmVmaWx0ZXJzT3JUcmFuc3BvcnRzKCBzdHJ1Y3R1cmUgKSB7XG5cblx0Ly8gZGF0YVR5cGVFeHByZXNzaW9uIGlzIG9wdGlvbmFsIGFuZCBkZWZhdWx0cyB0byBcIipcIlxuXHRyZXR1cm4gZnVuY3Rpb24oIGRhdGFUeXBlRXhwcmVzc2lvbiwgZnVuYyApIHtcblxuXHRcdGlmICggdHlwZW9mIGRhdGFUeXBlRXhwcmVzc2lvbiAhPT0gXCJzdHJpbmdcIiApIHtcblx0XHRcdGZ1bmMgPSBkYXRhVHlwZUV4cHJlc3Npb247XG5cdFx0XHRkYXRhVHlwZUV4cHJlc3Npb24gPSBcIipcIjtcblx0XHR9XG5cblx0XHR2YXIgZGF0YVR5cGUsXG5cdFx0XHRpID0gMCxcblx0XHRcdGRhdGFUeXBlcyA9IGRhdGFUeXBlRXhwcmVzc2lvbi50b0xvd2VyQ2FzZSgpLm1hdGNoKCBybm90aHRtbHdoaXRlICkgfHwgW107XG5cblx0XHRpZiAoIGpRdWVyeS5pc0Z1bmN0aW9uKCBmdW5jICkgKSB7XG5cblx0XHRcdC8vIEZvciBlYWNoIGRhdGFUeXBlIGluIHRoZSBkYXRhVHlwZUV4cHJlc3Npb25cblx0XHRcdHdoaWxlICggKCBkYXRhVHlwZSA9IGRhdGFUeXBlc1sgaSsrIF0gKSApIHtcblxuXHRcdFx0XHQvLyBQcmVwZW5kIGlmIHJlcXVlc3RlZFxuXHRcdFx0XHRpZiAoIGRhdGFUeXBlWyAwIF0gPT09IFwiK1wiICkge1xuXHRcdFx0XHRcdGRhdGFUeXBlID0gZGF0YVR5cGUuc2xpY2UoIDEgKSB8fCBcIipcIjtcblx0XHRcdFx0XHQoIHN0cnVjdHVyZVsgZGF0YVR5cGUgXSA9IHN0cnVjdHVyZVsgZGF0YVR5cGUgXSB8fCBbXSApLnVuc2hpZnQoIGZ1bmMgKTtcblxuXHRcdFx0XHQvLyBPdGhlcndpc2UgYXBwZW5kXG5cdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0KCBzdHJ1Y3R1cmVbIGRhdGFUeXBlIF0gPSBzdHJ1Y3R1cmVbIGRhdGFUeXBlIF0gfHwgW10gKS5wdXNoKCBmdW5jICk7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9XG5cdH07XG59XG5cbi8vIEJhc2UgaW5zcGVjdGlvbiBmdW5jdGlvbiBmb3IgcHJlZmlsdGVycyBhbmQgdHJhbnNwb3J0c1xuZnVuY3Rpb24gaW5zcGVjdFByZWZpbHRlcnNPclRyYW5zcG9ydHMoIHN0cnVjdHVyZSwgb3B0aW9ucywgb3JpZ2luYWxPcHRpb25zLCBqcVhIUiApIHtcblxuXHR2YXIgaW5zcGVjdGVkID0ge30sXG5cdFx0c2Vla2luZ1RyYW5zcG9ydCA9ICggc3RydWN0dXJlID09PSB0cmFuc3BvcnRzICk7XG5cblx0ZnVuY3Rpb24gaW5zcGVjdCggZGF0YVR5cGUgKSB7XG5cdFx0dmFyIHNlbGVjdGVkO1xuXHRcdGluc3BlY3RlZFsgZGF0YVR5cGUgXSA9IHRydWU7XG5cdFx0alF1ZXJ5LmVhY2goIHN0cnVjdHVyZVsgZGF0YVR5cGUgXSB8fCBbXSwgZnVuY3Rpb24oIF8sIHByZWZpbHRlck9yRmFjdG9yeSApIHtcblx0XHRcdHZhciBkYXRhVHlwZU9yVHJhbnNwb3J0ID0gcHJlZmlsdGVyT3JGYWN0b3J5KCBvcHRpb25zLCBvcmlnaW5hbE9wdGlvbnMsIGpxWEhSICk7XG5cdFx0XHRpZiAoIHR5cGVvZiBkYXRhVHlwZU9yVHJhbnNwb3J0ID09PSBcInN0cmluZ1wiICYmXG5cdFx0XHRcdCFzZWVraW5nVHJhbnNwb3J0ICYmICFpbnNwZWN0ZWRbIGRhdGFUeXBlT3JUcmFuc3BvcnQgXSApIHtcblxuXHRcdFx0XHRvcHRpb25zLmRhdGFUeXBlcy51bnNoaWZ0KCBkYXRhVHlwZU9yVHJhbnNwb3J0ICk7XG5cdFx0XHRcdGluc3BlY3QoIGRhdGFUeXBlT3JUcmFuc3BvcnQgKTtcblx0XHRcdFx0cmV0dXJuIGZhbHNlO1xuXHRcdFx0fSBlbHNlIGlmICggc2Vla2luZ1RyYW5zcG9ydCApIHtcblx0XHRcdFx0cmV0dXJuICEoIHNlbGVjdGVkID0gZGF0YVR5cGVPclRyYW5zcG9ydCApO1xuXHRcdFx0fVxuXHRcdH0gKTtcblx0XHRyZXR1cm4gc2VsZWN0ZWQ7XG5cdH1cblxuXHRyZXR1cm4gaW5zcGVjdCggb3B0aW9ucy5kYXRhVHlwZXNbIDAgXSApIHx8ICFpbnNwZWN0ZWRbIFwiKlwiIF0gJiYgaW5zcGVjdCggXCIqXCIgKTtcbn1cblxuLy8gQSBzcGVjaWFsIGV4dGVuZCBmb3IgYWpheCBvcHRpb25zXG4vLyB0aGF0IHRha2VzIFwiZmxhdFwiIG9wdGlvbnMgKG5vdCB0byBiZSBkZWVwIGV4dGVuZGVkKVxuLy8gRml4ZXMgIzk4ODdcbmZ1bmN0aW9uIGFqYXhFeHRlbmQoIHRhcmdldCwgc3JjICkge1xuXHR2YXIga2V5LCBkZWVwLFxuXHRcdGZsYXRPcHRpb25zID0galF1ZXJ5LmFqYXhTZXR0aW5ncy5mbGF0T3B0aW9ucyB8fCB7fTtcblxuXHRmb3IgKCBrZXkgaW4gc3JjICkge1xuXHRcdGlmICggc3JjWyBrZXkgXSAhPT0gdW5kZWZpbmVkICkge1xuXHRcdFx0KCBmbGF0T3B0aW9uc1sga2V5IF0gPyB0YXJnZXQgOiAoIGRlZXAgfHwgKCBkZWVwID0ge30gKSApIClbIGtleSBdID0gc3JjWyBrZXkgXTtcblx0XHR9XG5cdH1cblx0aWYgKCBkZWVwICkge1xuXHRcdGpRdWVyeS5leHRlbmQoIHRydWUsIHRhcmdldCwgZGVlcCApO1xuXHR9XG5cblx0cmV0dXJuIHRhcmdldDtcbn1cblxuLyogSGFuZGxlcyByZXNwb25zZXMgdG8gYW4gYWpheCByZXF1ZXN0OlxuICogLSBmaW5kcyB0aGUgcmlnaHQgZGF0YVR5cGUgKG1lZGlhdGVzIGJldHdlZW4gY29udGVudC10eXBlIGFuZCBleHBlY3RlZCBkYXRhVHlwZSlcbiAqIC0gcmV0dXJucyB0aGUgY29ycmVzcG9uZGluZyByZXNwb25zZVxuICovXG5mdW5jdGlvbiBhamF4SGFuZGxlUmVzcG9uc2VzKCBzLCBqcVhIUiwgcmVzcG9uc2VzICkge1xuXG5cdHZhciBjdCwgdHlwZSwgZmluYWxEYXRhVHlwZSwgZmlyc3REYXRhVHlwZSxcblx0XHRjb250ZW50cyA9IHMuY29udGVudHMsXG5cdFx0ZGF0YVR5cGVzID0gcy5kYXRhVHlwZXM7XG5cblx0Ly8gUmVtb3ZlIGF1dG8gZGF0YVR5cGUgYW5kIGdldCBjb250ZW50LXR5cGUgaW4gdGhlIHByb2Nlc3Ncblx0d2hpbGUgKCBkYXRhVHlwZXNbIDAgXSA9PT0gXCIqXCIgKSB7XG5cdFx0ZGF0YVR5cGVzLnNoaWZ0KCk7XG5cdFx0aWYgKCBjdCA9PT0gdW5kZWZpbmVkICkge1xuXHRcdFx0Y3QgPSBzLm1pbWVUeXBlIHx8IGpxWEhSLmdldFJlc3BvbnNlSGVhZGVyKCBcIkNvbnRlbnQtVHlwZVwiICk7XG5cdFx0fVxuXHR9XG5cblx0Ly8gQ2hlY2sgaWYgd2UncmUgZGVhbGluZyB3aXRoIGEga25vd24gY29udGVudC10eXBlXG5cdGlmICggY3QgKSB7XG5cdFx0Zm9yICggdHlwZSBpbiBjb250ZW50cyApIHtcblx0XHRcdGlmICggY29udGVudHNbIHR5cGUgXSAmJiBjb250ZW50c1sgdHlwZSBdLnRlc3QoIGN0ICkgKSB7XG5cdFx0XHRcdGRhdGFUeXBlcy51bnNoaWZ0KCB0eXBlICk7XG5cdFx0XHRcdGJyZWFrO1xuXHRcdFx0fVxuXHRcdH1cblx0fVxuXG5cdC8vIENoZWNrIHRvIHNlZSBpZiB3ZSBoYXZlIGEgcmVzcG9uc2UgZm9yIHRoZSBleHBlY3RlZCBkYXRhVHlwZVxuXHRpZiAoIGRhdGFUeXBlc1sgMCBdIGluIHJlc3BvbnNlcyApIHtcblx0XHRmaW5hbERhdGFUeXBlID0gZGF0YVR5cGVzWyAwIF07XG5cdH0gZWxzZSB7XG5cblx0XHQvLyBUcnkgY29udmVydGlibGUgZGF0YVR5cGVzXG5cdFx0Zm9yICggdHlwZSBpbiByZXNwb25zZXMgKSB7XG5cdFx0XHRpZiAoICFkYXRhVHlwZXNbIDAgXSB8fCBzLmNvbnZlcnRlcnNbIHR5cGUgKyBcIiBcIiArIGRhdGFUeXBlc1sgMCBdIF0gKSB7XG5cdFx0XHRcdGZpbmFsRGF0YVR5cGUgPSB0eXBlO1xuXHRcdFx0XHRicmVhaztcblx0XHRcdH1cblx0XHRcdGlmICggIWZpcnN0RGF0YVR5cGUgKSB7XG5cdFx0XHRcdGZpcnN0RGF0YVR5cGUgPSB0eXBlO1xuXHRcdFx0fVxuXHRcdH1cblxuXHRcdC8vIE9yIGp1c3QgdXNlIGZpcnN0IG9uZVxuXHRcdGZpbmFsRGF0YVR5cGUgPSBmaW5hbERhdGFUeXBlIHx8IGZpcnN0RGF0YVR5cGU7XG5cdH1cblxuXHQvLyBJZiB3ZSBmb3VuZCBhIGRhdGFUeXBlXG5cdC8vIFdlIGFkZCB0aGUgZGF0YVR5cGUgdG8gdGhlIGxpc3QgaWYgbmVlZGVkXG5cdC8vIGFuZCByZXR1cm4gdGhlIGNvcnJlc3BvbmRpbmcgcmVzcG9uc2Vcblx0aWYgKCBmaW5hbERhdGFUeXBlICkge1xuXHRcdGlmICggZmluYWxEYXRhVHlwZSAhPT0gZGF0YVR5cGVzWyAwIF0gKSB7XG5cdFx0XHRkYXRhVHlwZXMudW5zaGlmdCggZmluYWxEYXRhVHlwZSApO1xuXHRcdH1cblx0XHRyZXR1cm4gcmVzcG9uc2VzWyBmaW5hbERhdGFUeXBlIF07XG5cdH1cbn1cblxuLyogQ2hhaW4gY29udmVyc2lvbnMgZ2l2ZW4gdGhlIHJlcXVlc3QgYW5kIHRoZSBvcmlnaW5hbCByZXNwb25zZVxuICogQWxzbyBzZXRzIHRoZSByZXNwb25zZVhYWCBmaWVsZHMgb24gdGhlIGpxWEhSIGluc3RhbmNlXG4gKi9cbmZ1bmN0aW9uIGFqYXhDb252ZXJ0KCBzLCByZXNwb25zZSwganFYSFIsIGlzU3VjY2VzcyApIHtcblx0dmFyIGNvbnYyLCBjdXJyZW50LCBjb252LCB0bXAsIHByZXYsXG5cdFx0Y29udmVydGVycyA9IHt9LFxuXG5cdFx0Ly8gV29yayB3aXRoIGEgY29weSBvZiBkYXRhVHlwZXMgaW4gY2FzZSB3ZSBuZWVkIHRvIG1vZGlmeSBpdCBmb3IgY29udmVyc2lvblxuXHRcdGRhdGFUeXBlcyA9IHMuZGF0YVR5cGVzLnNsaWNlKCk7XG5cblx0Ly8gQ3JlYXRlIGNvbnZlcnRlcnMgbWFwIHdpdGggbG93ZXJjYXNlZCBrZXlzXG5cdGlmICggZGF0YVR5cGVzWyAxIF0gKSB7XG5cdFx0Zm9yICggY29udiBpbiBzLmNvbnZlcnRlcnMgKSB7XG5cdFx0XHRjb252ZXJ0ZXJzWyBjb252LnRvTG93ZXJDYXNlKCkgXSA9IHMuY29udmVydGVyc1sgY29udiBdO1xuXHRcdH1cblx0fVxuXG5cdGN1cnJlbnQgPSBkYXRhVHlwZXMuc2hpZnQoKTtcblxuXHQvLyBDb252ZXJ0IHRvIGVhY2ggc2VxdWVudGlhbCBkYXRhVHlwZVxuXHR3aGlsZSAoIGN1cnJlbnQgKSB7XG5cblx0XHRpZiAoIHMucmVzcG9uc2VGaWVsZHNbIGN1cnJlbnQgXSApIHtcblx0XHRcdGpxWEhSWyBzLnJlc3BvbnNlRmllbGRzWyBjdXJyZW50IF0gXSA9IHJlc3BvbnNlO1xuXHRcdH1cblxuXHRcdC8vIEFwcGx5IHRoZSBkYXRhRmlsdGVyIGlmIHByb3ZpZGVkXG5cdFx0aWYgKCAhcHJldiAmJiBpc1N1Y2Nlc3MgJiYgcy5kYXRhRmlsdGVyICkge1xuXHRcdFx0cmVzcG9uc2UgPSBzLmRhdGFGaWx0ZXIoIHJlc3BvbnNlLCBzLmRhdGFUeXBlICk7XG5cdFx0fVxuXG5cdFx0cHJldiA9IGN1cnJlbnQ7XG5cdFx0Y3VycmVudCA9IGRhdGFUeXBlcy5zaGlmdCgpO1xuXG5cdFx0aWYgKCBjdXJyZW50ICkge1xuXG5cdFx0XHQvLyBUaGVyZSdzIG9ubHkgd29yayB0byBkbyBpZiBjdXJyZW50IGRhdGFUeXBlIGlzIG5vbi1hdXRvXG5cdFx0XHRpZiAoIGN1cnJlbnQgPT09IFwiKlwiICkge1xuXG5cdFx0XHRcdGN1cnJlbnQgPSBwcmV2O1xuXG5cdFx0XHQvLyBDb252ZXJ0IHJlc3BvbnNlIGlmIHByZXYgZGF0YVR5cGUgaXMgbm9uLWF1dG8gYW5kIGRpZmZlcnMgZnJvbSBjdXJyZW50XG5cdFx0XHR9IGVsc2UgaWYgKCBwcmV2ICE9PSBcIipcIiAmJiBwcmV2ICE9PSBjdXJyZW50ICkge1xuXG5cdFx0XHRcdC8vIFNlZWsgYSBkaXJlY3QgY29udmVydGVyXG5cdFx0XHRcdGNvbnYgPSBjb252ZXJ0ZXJzWyBwcmV2ICsgXCIgXCIgKyBjdXJyZW50IF0gfHwgY29udmVydGVyc1sgXCIqIFwiICsgY3VycmVudCBdO1xuXG5cdFx0XHRcdC8vIElmIG5vbmUgZm91bmQsIHNlZWsgYSBwYWlyXG5cdFx0XHRcdGlmICggIWNvbnYgKSB7XG5cdFx0XHRcdFx0Zm9yICggY29udjIgaW4gY29udmVydGVycyApIHtcblxuXHRcdFx0XHRcdFx0Ly8gSWYgY29udjIgb3V0cHV0cyBjdXJyZW50XG5cdFx0XHRcdFx0XHR0bXAgPSBjb252Mi5zcGxpdCggXCIgXCIgKTtcblx0XHRcdFx0XHRcdGlmICggdG1wWyAxIF0gPT09IGN1cnJlbnQgKSB7XG5cblx0XHRcdFx0XHRcdFx0Ly8gSWYgcHJldiBjYW4gYmUgY29udmVydGVkIHRvIGFjY2VwdGVkIGlucHV0XG5cdFx0XHRcdFx0XHRcdGNvbnYgPSBjb252ZXJ0ZXJzWyBwcmV2ICsgXCIgXCIgKyB0bXBbIDAgXSBdIHx8XG5cdFx0XHRcdFx0XHRcdFx0Y29udmVydGVyc1sgXCIqIFwiICsgdG1wWyAwIF0gXTtcblx0XHRcdFx0XHRcdFx0aWYgKCBjb252ICkge1xuXG5cdFx0XHRcdFx0XHRcdFx0Ly8gQ29uZGVuc2UgZXF1aXZhbGVuY2UgY29udmVydGVyc1xuXHRcdFx0XHRcdFx0XHRcdGlmICggY29udiA9PT0gdHJ1ZSApIHtcblx0XHRcdFx0XHRcdFx0XHRcdGNvbnYgPSBjb252ZXJ0ZXJzWyBjb252MiBdO1xuXG5cdFx0XHRcdFx0XHRcdFx0Ly8gT3RoZXJ3aXNlLCBpbnNlcnQgdGhlIGludGVybWVkaWF0ZSBkYXRhVHlwZVxuXHRcdFx0XHRcdFx0XHRcdH0gZWxzZSBpZiAoIGNvbnZlcnRlcnNbIGNvbnYyIF0gIT09IHRydWUgKSB7XG5cdFx0XHRcdFx0XHRcdFx0XHRjdXJyZW50ID0gdG1wWyAwIF07XG5cdFx0XHRcdFx0XHRcdFx0XHRkYXRhVHlwZXMudW5zaGlmdCggdG1wWyAxIF0gKTtcblx0XHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblxuXHRcdFx0XHQvLyBBcHBseSBjb252ZXJ0ZXIgKGlmIG5vdCBhbiBlcXVpdmFsZW5jZSlcblx0XHRcdFx0aWYgKCBjb252ICE9PSB0cnVlICkge1xuXG5cdFx0XHRcdFx0Ly8gVW5sZXNzIGVycm9ycyBhcmUgYWxsb3dlZCB0byBidWJibGUsIGNhdGNoIGFuZCByZXR1cm4gdGhlbVxuXHRcdFx0XHRcdGlmICggY29udiAmJiBzLnRocm93cyApIHtcblx0XHRcdFx0XHRcdHJlc3BvbnNlID0gY29udiggcmVzcG9uc2UgKTtcblx0XHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdFx0dHJ5IHtcblx0XHRcdFx0XHRcdFx0cmVzcG9uc2UgPSBjb252KCByZXNwb25zZSApO1xuXHRcdFx0XHRcdFx0fSBjYXRjaCAoIGUgKSB7XG5cdFx0XHRcdFx0XHRcdHJldHVybiB7XG5cdFx0XHRcdFx0XHRcdFx0c3RhdGU6IFwicGFyc2VyZXJyb3JcIixcblx0XHRcdFx0XHRcdFx0XHRlcnJvcjogY29udiA/IGUgOiBcIk5vIGNvbnZlcnNpb24gZnJvbSBcIiArIHByZXYgKyBcIiB0byBcIiArIGN1cnJlbnRcblx0XHRcdFx0XHRcdFx0fTtcblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9XG5cdH1cblxuXHRyZXR1cm4geyBzdGF0ZTogXCJzdWNjZXNzXCIsIGRhdGE6IHJlc3BvbnNlIH07XG59XG5cbmpRdWVyeS5leHRlbmQoIHtcblxuXHQvLyBDb3VudGVyIGZvciBob2xkaW5nIHRoZSBudW1iZXIgb2YgYWN0aXZlIHF1ZXJpZXNcblx0YWN0aXZlOiAwLFxuXG5cdC8vIExhc3QtTW9kaWZpZWQgaGVhZGVyIGNhY2hlIGZvciBuZXh0IHJlcXVlc3Rcblx0bGFzdE1vZGlmaWVkOiB7fSxcblx0ZXRhZzoge30sXG5cblx0YWpheFNldHRpbmdzOiB7XG5cdFx0dXJsOiBsb2NhdGlvbi5ocmVmLFxuXHRcdHR5cGU6IFwiR0VUXCIsXG5cdFx0aXNMb2NhbDogcmxvY2FsUHJvdG9jb2wudGVzdCggbG9jYXRpb24ucHJvdG9jb2wgKSxcblx0XHRnbG9iYWw6IHRydWUsXG5cdFx0cHJvY2Vzc0RhdGE6IHRydWUsXG5cdFx0YXN5bmM6IHRydWUsXG5cdFx0Y29udGVudFR5cGU6IFwiYXBwbGljYXRpb24veC13d3ctZm9ybS11cmxlbmNvZGVkOyBjaGFyc2V0PVVURi04XCIsXG5cblx0XHQvKlxuXHRcdHRpbWVvdXQ6IDAsXG5cdFx0ZGF0YTogbnVsbCxcblx0XHRkYXRhVHlwZTogbnVsbCxcblx0XHR1c2VybmFtZTogbnVsbCxcblx0XHRwYXNzd29yZDogbnVsbCxcblx0XHRjYWNoZTogbnVsbCxcblx0XHR0aHJvd3M6IGZhbHNlLFxuXHRcdHRyYWRpdGlvbmFsOiBmYWxzZSxcblx0XHRoZWFkZXJzOiB7fSxcblx0XHQqL1xuXG5cdFx0YWNjZXB0czoge1xuXHRcdFx0XCIqXCI6IGFsbFR5cGVzLFxuXHRcdFx0dGV4dDogXCJ0ZXh0L3BsYWluXCIsXG5cdFx0XHRodG1sOiBcInRleHQvaHRtbFwiLFxuXHRcdFx0eG1sOiBcImFwcGxpY2F0aW9uL3htbCwgdGV4dC94bWxcIixcblx0XHRcdGpzb246IFwiYXBwbGljYXRpb24vanNvbiwgdGV4dC9qYXZhc2NyaXB0XCJcblx0XHR9LFxuXG5cdFx0Y29udGVudHM6IHtcblx0XHRcdHhtbDogL1xcYnhtbFxcYi8sXG5cdFx0XHRodG1sOiAvXFxiaHRtbC8sXG5cdFx0XHRqc29uOiAvXFxianNvblxcYi9cblx0XHR9LFxuXG5cdFx0cmVzcG9uc2VGaWVsZHM6IHtcblx0XHRcdHhtbDogXCJyZXNwb25zZVhNTFwiLFxuXHRcdFx0dGV4dDogXCJyZXNwb25zZVRleHRcIixcblx0XHRcdGpzb246IFwicmVzcG9uc2VKU09OXCJcblx0XHR9LFxuXG5cdFx0Ly8gRGF0YSBjb252ZXJ0ZXJzXG5cdFx0Ly8gS2V5cyBzZXBhcmF0ZSBzb3VyY2UgKG9yIGNhdGNoYWxsIFwiKlwiKSBhbmQgZGVzdGluYXRpb24gdHlwZXMgd2l0aCBhIHNpbmdsZSBzcGFjZVxuXHRcdGNvbnZlcnRlcnM6IHtcblxuXHRcdFx0Ly8gQ29udmVydCBhbnl0aGluZyB0byB0ZXh0XG5cdFx0XHRcIiogdGV4dFwiOiBTdHJpbmcsXG5cblx0XHRcdC8vIFRleHQgdG8gaHRtbCAodHJ1ZSA9IG5vIHRyYW5zZm9ybWF0aW9uKVxuXHRcdFx0XCJ0ZXh0IGh0bWxcIjogdHJ1ZSxcblxuXHRcdFx0Ly8gRXZhbHVhdGUgdGV4dCBhcyBhIGpzb24gZXhwcmVzc2lvblxuXHRcdFx0XCJ0ZXh0IGpzb25cIjogSlNPTi5wYXJzZSxcblxuXHRcdFx0Ly8gUGFyc2UgdGV4dCBhcyB4bWxcblx0XHRcdFwidGV4dCB4bWxcIjogalF1ZXJ5LnBhcnNlWE1MXG5cdFx0fSxcblxuXHRcdC8vIEZvciBvcHRpb25zIHRoYXQgc2hvdWxkbid0IGJlIGRlZXAgZXh0ZW5kZWQ6XG5cdFx0Ly8geW91IGNhbiBhZGQgeW91ciBvd24gY3VzdG9tIG9wdGlvbnMgaGVyZSBpZlxuXHRcdC8vIGFuZCB3aGVuIHlvdSBjcmVhdGUgb25lIHRoYXQgc2hvdWxkbid0IGJlXG5cdFx0Ly8gZGVlcCBleHRlbmRlZCAoc2VlIGFqYXhFeHRlbmQpXG5cdFx0ZmxhdE9wdGlvbnM6IHtcblx0XHRcdHVybDogdHJ1ZSxcblx0XHRcdGNvbnRleHQ6IHRydWVcblx0XHR9XG5cdH0sXG5cblx0Ly8gQ3JlYXRlcyBhIGZ1bGwgZmxlZGdlZCBzZXR0aW5ncyBvYmplY3QgaW50byB0YXJnZXRcblx0Ly8gd2l0aCBib3RoIGFqYXhTZXR0aW5ncyBhbmQgc2V0dGluZ3MgZmllbGRzLlxuXHQvLyBJZiB0YXJnZXQgaXMgb21pdHRlZCwgd3JpdGVzIGludG8gYWpheFNldHRpbmdzLlxuXHRhamF4U2V0dXA6IGZ1bmN0aW9uKCB0YXJnZXQsIHNldHRpbmdzICkge1xuXHRcdHJldHVybiBzZXR0aW5ncyA/XG5cblx0XHRcdC8vIEJ1aWxkaW5nIGEgc2V0dGluZ3Mgb2JqZWN0XG5cdFx0XHRhamF4RXh0ZW5kKCBhamF4RXh0ZW5kKCB0YXJnZXQsIGpRdWVyeS5hamF4U2V0dGluZ3MgKSwgc2V0dGluZ3MgKSA6XG5cblx0XHRcdC8vIEV4dGVuZGluZyBhamF4U2V0dGluZ3Ncblx0XHRcdGFqYXhFeHRlbmQoIGpRdWVyeS5hamF4U2V0dGluZ3MsIHRhcmdldCApO1xuXHR9LFxuXG5cdGFqYXhQcmVmaWx0ZXI6IGFkZFRvUHJlZmlsdGVyc09yVHJhbnNwb3J0cyggcHJlZmlsdGVycyApLFxuXHRhamF4VHJhbnNwb3J0OiBhZGRUb1ByZWZpbHRlcnNPclRyYW5zcG9ydHMoIHRyYW5zcG9ydHMgKSxcblxuXHQvLyBNYWluIG1ldGhvZFxuXHRhamF4OiBmdW5jdGlvbiggdXJsLCBvcHRpb25zICkge1xuXG5cdFx0Ly8gSWYgdXJsIGlzIGFuIG9iamVjdCwgc2ltdWxhdGUgcHJlLTEuNSBzaWduYXR1cmVcblx0XHRpZiAoIHR5cGVvZiB1cmwgPT09IFwib2JqZWN0XCIgKSB7XG5cdFx0XHRvcHRpb25zID0gdXJsO1xuXHRcdFx0dXJsID0gdW5kZWZpbmVkO1xuXHRcdH1cblxuXHRcdC8vIEZvcmNlIG9wdGlvbnMgdG8gYmUgYW4gb2JqZWN0XG5cdFx0b3B0aW9ucyA9IG9wdGlvbnMgfHwge307XG5cblx0XHR2YXIgdHJhbnNwb3J0LFxuXG5cdFx0XHQvLyBVUkwgd2l0aG91dCBhbnRpLWNhY2hlIHBhcmFtXG5cdFx0XHRjYWNoZVVSTCxcblxuXHRcdFx0Ly8gUmVzcG9uc2UgaGVhZGVyc1xuXHRcdFx0cmVzcG9uc2VIZWFkZXJzU3RyaW5nLFxuXHRcdFx0cmVzcG9uc2VIZWFkZXJzLFxuXG5cdFx0XHQvLyB0aW1lb3V0IGhhbmRsZVxuXHRcdFx0dGltZW91dFRpbWVyLFxuXG5cdFx0XHQvLyBVcmwgY2xlYW51cCB2YXJcblx0XHRcdHVybEFuY2hvcixcblxuXHRcdFx0Ly8gUmVxdWVzdCBzdGF0ZSAoYmVjb21lcyBmYWxzZSB1cG9uIHNlbmQgYW5kIHRydWUgdXBvbiBjb21wbGV0aW9uKVxuXHRcdFx0Y29tcGxldGVkLFxuXG5cdFx0XHQvLyBUbyBrbm93IGlmIGdsb2JhbCBldmVudHMgYXJlIHRvIGJlIGRpc3BhdGNoZWRcblx0XHRcdGZpcmVHbG9iYWxzLFxuXG5cdFx0XHQvLyBMb29wIHZhcmlhYmxlXG5cdFx0XHRpLFxuXG5cdFx0XHQvLyB1bmNhY2hlZCBwYXJ0IG9mIHRoZSB1cmxcblx0XHRcdHVuY2FjaGVkLFxuXG5cdFx0XHQvLyBDcmVhdGUgdGhlIGZpbmFsIG9wdGlvbnMgb2JqZWN0XG5cdFx0XHRzID0galF1ZXJ5LmFqYXhTZXR1cCgge30sIG9wdGlvbnMgKSxcblxuXHRcdFx0Ly8gQ2FsbGJhY2tzIGNvbnRleHRcblx0XHRcdGNhbGxiYWNrQ29udGV4dCA9IHMuY29udGV4dCB8fCBzLFxuXG5cdFx0XHQvLyBDb250ZXh0IGZvciBnbG9iYWwgZXZlbnRzIGlzIGNhbGxiYWNrQ29udGV4dCBpZiBpdCBpcyBhIERPTSBub2RlIG9yIGpRdWVyeSBjb2xsZWN0aW9uXG5cdFx0XHRnbG9iYWxFdmVudENvbnRleHQgPSBzLmNvbnRleHQgJiZcblx0XHRcdFx0KCBjYWxsYmFja0NvbnRleHQubm9kZVR5cGUgfHwgY2FsbGJhY2tDb250ZXh0LmpxdWVyeSApID9cblx0XHRcdFx0XHRqUXVlcnkoIGNhbGxiYWNrQ29udGV4dCApIDpcblx0XHRcdFx0XHRqUXVlcnkuZXZlbnQsXG5cblx0XHRcdC8vIERlZmVycmVkc1xuXHRcdFx0ZGVmZXJyZWQgPSBqUXVlcnkuRGVmZXJyZWQoKSxcblx0XHRcdGNvbXBsZXRlRGVmZXJyZWQgPSBqUXVlcnkuQ2FsbGJhY2tzKCBcIm9uY2UgbWVtb3J5XCIgKSxcblxuXHRcdFx0Ly8gU3RhdHVzLWRlcGVuZGVudCBjYWxsYmFja3Ncblx0XHRcdHN0YXR1c0NvZGUgPSBzLnN0YXR1c0NvZGUgfHwge30sXG5cblx0XHRcdC8vIEhlYWRlcnMgKHRoZXkgYXJlIHNlbnQgYWxsIGF0IG9uY2UpXG5cdFx0XHRyZXF1ZXN0SGVhZGVycyA9IHt9LFxuXHRcdFx0cmVxdWVzdEhlYWRlcnNOYW1lcyA9IHt9LFxuXG5cdFx0XHQvLyBEZWZhdWx0IGFib3J0IG1lc3NhZ2Vcblx0XHRcdHN0ckFib3J0ID0gXCJjYW5jZWxlZFwiLFxuXG5cdFx0XHQvLyBGYWtlIHhoclxuXHRcdFx0anFYSFIgPSB7XG5cdFx0XHRcdHJlYWR5U3RhdGU6IDAsXG5cblx0XHRcdFx0Ly8gQnVpbGRzIGhlYWRlcnMgaGFzaHRhYmxlIGlmIG5lZWRlZFxuXHRcdFx0XHRnZXRSZXNwb25zZUhlYWRlcjogZnVuY3Rpb24oIGtleSApIHtcblx0XHRcdFx0XHR2YXIgbWF0Y2g7XG5cdFx0XHRcdFx0aWYgKCBjb21wbGV0ZWQgKSB7XG5cdFx0XHRcdFx0XHRpZiAoICFyZXNwb25zZUhlYWRlcnMgKSB7XG5cdFx0XHRcdFx0XHRcdHJlc3BvbnNlSGVhZGVycyA9IHt9O1xuXHRcdFx0XHRcdFx0XHR3aGlsZSAoICggbWF0Y2ggPSByaGVhZGVycy5leGVjKCByZXNwb25zZUhlYWRlcnNTdHJpbmcgKSApICkge1xuXHRcdFx0XHRcdFx0XHRcdHJlc3BvbnNlSGVhZGVyc1sgbWF0Y2hbIDEgXS50b0xvd2VyQ2FzZSgpIF0gPSBtYXRjaFsgMiBdO1xuXHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHRtYXRjaCA9IHJlc3BvbnNlSGVhZGVyc1sga2V5LnRvTG93ZXJDYXNlKCkgXTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0cmV0dXJuIG1hdGNoID09IG51bGwgPyBudWxsIDogbWF0Y2g7XG5cdFx0XHRcdH0sXG5cblx0XHRcdFx0Ly8gUmF3IHN0cmluZ1xuXHRcdFx0XHRnZXRBbGxSZXNwb25zZUhlYWRlcnM6IGZ1bmN0aW9uKCkge1xuXHRcdFx0XHRcdHJldHVybiBjb21wbGV0ZWQgPyByZXNwb25zZUhlYWRlcnNTdHJpbmcgOiBudWxsO1xuXHRcdFx0XHR9LFxuXG5cdFx0XHRcdC8vIENhY2hlcyB0aGUgaGVhZGVyXG5cdFx0XHRcdHNldFJlcXVlc3RIZWFkZXI6IGZ1bmN0aW9uKCBuYW1lLCB2YWx1ZSApIHtcblx0XHRcdFx0XHRpZiAoIGNvbXBsZXRlZCA9PSBudWxsICkge1xuXHRcdFx0XHRcdFx0bmFtZSA9IHJlcXVlc3RIZWFkZXJzTmFtZXNbIG5hbWUudG9Mb3dlckNhc2UoKSBdID1cblx0XHRcdFx0XHRcdFx0cmVxdWVzdEhlYWRlcnNOYW1lc1sgbmFtZS50b0xvd2VyQ2FzZSgpIF0gfHwgbmFtZTtcblx0XHRcdFx0XHRcdHJlcXVlc3RIZWFkZXJzWyBuYW1lIF0gPSB2YWx1ZTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0cmV0dXJuIHRoaXM7XG5cdFx0XHRcdH0sXG5cblx0XHRcdFx0Ly8gT3ZlcnJpZGVzIHJlc3BvbnNlIGNvbnRlbnQtdHlwZSBoZWFkZXJcblx0XHRcdFx0b3ZlcnJpZGVNaW1lVHlwZTogZnVuY3Rpb24oIHR5cGUgKSB7XG5cdFx0XHRcdFx0aWYgKCBjb21wbGV0ZWQgPT0gbnVsbCApIHtcblx0XHRcdFx0XHRcdHMubWltZVR5cGUgPSB0eXBlO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0XHRyZXR1cm4gdGhpcztcblx0XHRcdFx0fSxcblxuXHRcdFx0XHQvLyBTdGF0dXMtZGVwZW5kZW50IGNhbGxiYWNrc1xuXHRcdFx0XHRzdGF0dXNDb2RlOiBmdW5jdGlvbiggbWFwICkge1xuXHRcdFx0XHRcdHZhciBjb2RlO1xuXHRcdFx0XHRcdGlmICggbWFwICkge1xuXHRcdFx0XHRcdFx0aWYgKCBjb21wbGV0ZWQgKSB7XG5cblx0XHRcdFx0XHRcdFx0Ly8gRXhlY3V0ZSB0aGUgYXBwcm9wcmlhdGUgY2FsbGJhY2tzXG5cdFx0XHRcdFx0XHRcdGpxWEhSLmFsd2F5cyggbWFwWyBqcVhIUi5zdGF0dXMgXSApO1xuXHRcdFx0XHRcdFx0fSBlbHNlIHtcblxuXHRcdFx0XHRcdFx0XHQvLyBMYXp5LWFkZCB0aGUgbmV3IGNhbGxiYWNrcyBpbiBhIHdheSB0aGF0IHByZXNlcnZlcyBvbGQgb25lc1xuXHRcdFx0XHRcdFx0XHRmb3IgKCBjb2RlIGluIG1hcCApIHtcblx0XHRcdFx0XHRcdFx0XHRzdGF0dXNDb2RlWyBjb2RlIF0gPSBbIHN0YXR1c0NvZGVbIGNvZGUgXSwgbWFwWyBjb2RlIF0gXTtcblx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdH1cblx0XHRcdFx0XHRyZXR1cm4gdGhpcztcblx0XHRcdFx0fSxcblxuXHRcdFx0XHQvLyBDYW5jZWwgdGhlIHJlcXVlc3Rcblx0XHRcdFx0YWJvcnQ6IGZ1bmN0aW9uKCBzdGF0dXNUZXh0ICkge1xuXHRcdFx0XHRcdHZhciBmaW5hbFRleHQgPSBzdGF0dXNUZXh0IHx8IHN0ckFib3J0O1xuXHRcdFx0XHRcdGlmICggdHJhbnNwb3J0ICkge1xuXHRcdFx0XHRcdFx0dHJhbnNwb3J0LmFib3J0KCBmaW5hbFRleHQgKTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0ZG9uZSggMCwgZmluYWxUZXh0ICk7XG5cdFx0XHRcdFx0cmV0dXJuIHRoaXM7XG5cdFx0XHRcdH1cblx0XHRcdH07XG5cblx0XHQvLyBBdHRhY2ggZGVmZXJyZWRzXG5cdFx0ZGVmZXJyZWQucHJvbWlzZSgganFYSFIgKTtcblxuXHRcdC8vIEFkZCBwcm90b2NvbCBpZiBub3QgcHJvdmlkZWQgKHByZWZpbHRlcnMgbWlnaHQgZXhwZWN0IGl0KVxuXHRcdC8vIEhhbmRsZSBmYWxzeSB1cmwgaW4gdGhlIHNldHRpbmdzIG9iamVjdCAoIzEwMDkzOiBjb25zaXN0ZW5jeSB3aXRoIG9sZCBzaWduYXR1cmUpXG5cdFx0Ly8gV2UgYWxzbyB1c2UgdGhlIHVybCBwYXJhbWV0ZXIgaWYgYXZhaWxhYmxlXG5cdFx0cy51cmwgPSAoICggdXJsIHx8IHMudXJsIHx8IGxvY2F0aW9uLmhyZWYgKSArIFwiXCIgKVxuXHRcdFx0LnJlcGxhY2UoIHJwcm90b2NvbCwgbG9jYXRpb24ucHJvdG9jb2wgKyBcIi8vXCIgKTtcblxuXHRcdC8vIEFsaWFzIG1ldGhvZCBvcHRpb24gdG8gdHlwZSBhcyBwZXIgdGlja2V0ICMxMjAwNFxuXHRcdHMudHlwZSA9IG9wdGlvbnMubWV0aG9kIHx8IG9wdGlvbnMudHlwZSB8fCBzLm1ldGhvZCB8fCBzLnR5cGU7XG5cblx0XHQvLyBFeHRyYWN0IGRhdGFUeXBlcyBsaXN0XG5cdFx0cy5kYXRhVHlwZXMgPSAoIHMuZGF0YVR5cGUgfHwgXCIqXCIgKS50b0xvd2VyQ2FzZSgpLm1hdGNoKCBybm90aHRtbHdoaXRlICkgfHwgWyBcIlwiIF07XG5cblx0XHQvLyBBIGNyb3NzLWRvbWFpbiByZXF1ZXN0IGlzIGluIG9yZGVyIHdoZW4gdGhlIG9yaWdpbiBkb2Vzbid0IG1hdGNoIHRoZSBjdXJyZW50IG9yaWdpbi5cblx0XHRpZiAoIHMuY3Jvc3NEb21haW4gPT0gbnVsbCApIHtcblx0XHRcdHVybEFuY2hvciA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoIFwiYVwiICk7XG5cblx0XHRcdC8vIFN1cHBvcnQ6IElFIDw9OCAtIDExLCBFZGdlIDEyIC0gMTNcblx0XHRcdC8vIElFIHRocm93cyBleGNlcHRpb24gb24gYWNjZXNzaW5nIHRoZSBocmVmIHByb3BlcnR5IGlmIHVybCBpcyBtYWxmb3JtZWQsXG5cdFx0XHQvLyBlLmcuIGh0dHA6Ly9leGFtcGxlLmNvbTo4MHgvXG5cdFx0XHR0cnkge1xuXHRcdFx0XHR1cmxBbmNob3IuaHJlZiA9IHMudXJsO1xuXG5cdFx0XHRcdC8vIFN1cHBvcnQ6IElFIDw9OCAtIDExIG9ubHlcblx0XHRcdFx0Ly8gQW5jaG9yJ3MgaG9zdCBwcm9wZXJ0eSBpc24ndCBjb3JyZWN0bHkgc2V0IHdoZW4gcy51cmwgaXMgcmVsYXRpdmVcblx0XHRcdFx0dXJsQW5jaG9yLmhyZWYgPSB1cmxBbmNob3IuaHJlZjtcblx0XHRcdFx0cy5jcm9zc0RvbWFpbiA9IG9yaWdpbkFuY2hvci5wcm90b2NvbCArIFwiLy9cIiArIG9yaWdpbkFuY2hvci5ob3N0ICE9PVxuXHRcdFx0XHRcdHVybEFuY2hvci5wcm90b2NvbCArIFwiLy9cIiArIHVybEFuY2hvci5ob3N0O1xuXHRcdFx0fSBjYXRjaCAoIGUgKSB7XG5cblx0XHRcdFx0Ly8gSWYgdGhlcmUgaXMgYW4gZXJyb3IgcGFyc2luZyB0aGUgVVJMLCBhc3N1bWUgaXQgaXMgY3Jvc3NEb21haW4sXG5cdFx0XHRcdC8vIGl0IGNhbiBiZSByZWplY3RlZCBieSB0aGUgdHJhbnNwb3J0IGlmIGl0IGlzIGludmFsaWRcblx0XHRcdFx0cy5jcm9zc0RvbWFpbiA9IHRydWU7XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0Ly8gQ29udmVydCBkYXRhIGlmIG5vdCBhbHJlYWR5IGEgc3RyaW5nXG5cdFx0aWYgKCBzLmRhdGEgJiYgcy5wcm9jZXNzRGF0YSAmJiB0eXBlb2Ygcy5kYXRhICE9PSBcInN0cmluZ1wiICkge1xuXHRcdFx0cy5kYXRhID0galF1ZXJ5LnBhcmFtKCBzLmRhdGEsIHMudHJhZGl0aW9uYWwgKTtcblx0XHR9XG5cblx0XHQvLyBBcHBseSBwcmVmaWx0ZXJzXG5cdFx0aW5zcGVjdFByZWZpbHRlcnNPclRyYW5zcG9ydHMoIHByZWZpbHRlcnMsIHMsIG9wdGlvbnMsIGpxWEhSICk7XG5cblx0XHQvLyBJZiByZXF1ZXN0IHdhcyBhYm9ydGVkIGluc2lkZSBhIHByZWZpbHRlciwgc3RvcCB0aGVyZVxuXHRcdGlmICggY29tcGxldGVkICkge1xuXHRcdFx0cmV0dXJuIGpxWEhSO1xuXHRcdH1cblxuXHRcdC8vIFdlIGNhbiBmaXJlIGdsb2JhbCBldmVudHMgYXMgb2Ygbm93IGlmIGFza2VkIHRvXG5cdFx0Ly8gRG9uJ3QgZmlyZSBldmVudHMgaWYgalF1ZXJ5LmV2ZW50IGlzIHVuZGVmaW5lZCBpbiBhbiBBTUQtdXNhZ2Ugc2NlbmFyaW8gKCMxNTExOClcblx0XHRmaXJlR2xvYmFscyA9IGpRdWVyeS5ldmVudCAmJiBzLmdsb2JhbDtcblxuXHRcdC8vIFdhdGNoIGZvciBhIG5ldyBzZXQgb2YgcmVxdWVzdHNcblx0XHRpZiAoIGZpcmVHbG9iYWxzICYmIGpRdWVyeS5hY3RpdmUrKyA9PT0gMCApIHtcblx0XHRcdGpRdWVyeS5ldmVudC50cmlnZ2VyKCBcImFqYXhTdGFydFwiICk7XG5cdFx0fVxuXG5cdFx0Ly8gVXBwZXJjYXNlIHRoZSB0eXBlXG5cdFx0cy50eXBlID0gcy50eXBlLnRvVXBwZXJDYXNlKCk7XG5cblx0XHQvLyBEZXRlcm1pbmUgaWYgcmVxdWVzdCBoYXMgY29udGVudFxuXHRcdHMuaGFzQ29udGVudCA9ICFybm9Db250ZW50LnRlc3QoIHMudHlwZSApO1xuXG5cdFx0Ly8gU2F2ZSB0aGUgVVJMIGluIGNhc2Ugd2UncmUgdG95aW5nIHdpdGggdGhlIElmLU1vZGlmaWVkLVNpbmNlXG5cdFx0Ly8gYW5kL29yIElmLU5vbmUtTWF0Y2ggaGVhZGVyIGxhdGVyIG9uXG5cdFx0Ly8gUmVtb3ZlIGhhc2ggdG8gc2ltcGxpZnkgdXJsIG1hbmlwdWxhdGlvblxuXHRcdGNhY2hlVVJMID0gcy51cmwucmVwbGFjZSggcmhhc2gsIFwiXCIgKTtcblxuXHRcdC8vIE1vcmUgb3B0aW9ucyBoYW5kbGluZyBmb3IgcmVxdWVzdHMgd2l0aCBubyBjb250ZW50XG5cdFx0aWYgKCAhcy5oYXNDb250ZW50ICkge1xuXG5cdFx0XHQvLyBSZW1lbWJlciB0aGUgaGFzaCBzbyB3ZSBjYW4gcHV0IGl0IGJhY2tcblx0XHRcdHVuY2FjaGVkID0gcy51cmwuc2xpY2UoIGNhY2hlVVJMLmxlbmd0aCApO1xuXG5cdFx0XHQvLyBJZiBkYXRhIGlzIGF2YWlsYWJsZSwgYXBwZW5kIGRhdGEgdG8gdXJsXG5cdFx0XHRpZiAoIHMuZGF0YSApIHtcblx0XHRcdFx0Y2FjaGVVUkwgKz0gKCBycXVlcnkudGVzdCggY2FjaGVVUkwgKSA/IFwiJlwiIDogXCI/XCIgKSArIHMuZGF0YTtcblxuXHRcdFx0XHQvLyAjOTY4MjogcmVtb3ZlIGRhdGEgc28gdGhhdCBpdCdzIG5vdCB1c2VkIGluIGFuIGV2ZW50dWFsIHJldHJ5XG5cdFx0XHRcdGRlbGV0ZSBzLmRhdGE7XG5cdFx0XHR9XG5cblx0XHRcdC8vIEFkZCBvciB1cGRhdGUgYW50aS1jYWNoZSBwYXJhbSBpZiBuZWVkZWRcblx0XHRcdGlmICggcy5jYWNoZSA9PT0gZmFsc2UgKSB7XG5cdFx0XHRcdGNhY2hlVVJMID0gY2FjaGVVUkwucmVwbGFjZSggcmFudGlDYWNoZSwgXCIkMVwiICk7XG5cdFx0XHRcdHVuY2FjaGVkID0gKCBycXVlcnkudGVzdCggY2FjaGVVUkwgKSA/IFwiJlwiIDogXCI/XCIgKSArIFwiXz1cIiArICggbm9uY2UrKyApICsgdW5jYWNoZWQ7XG5cdFx0XHR9XG5cblx0XHRcdC8vIFB1dCBoYXNoIGFuZCBhbnRpLWNhY2hlIG9uIHRoZSBVUkwgdGhhdCB3aWxsIGJlIHJlcXVlc3RlZCAoZ2gtMTczMilcblx0XHRcdHMudXJsID0gY2FjaGVVUkwgKyB1bmNhY2hlZDtcblxuXHRcdC8vIENoYW5nZSAnJTIwJyB0byAnKycgaWYgdGhpcyBpcyBlbmNvZGVkIGZvcm0gYm9keSBjb250ZW50IChnaC0yNjU4KVxuXHRcdH0gZWxzZSBpZiAoIHMuZGF0YSAmJiBzLnByb2Nlc3NEYXRhICYmXG5cdFx0XHQoIHMuY29udGVudFR5cGUgfHwgXCJcIiApLmluZGV4T2YoIFwiYXBwbGljYXRpb24veC13d3ctZm9ybS11cmxlbmNvZGVkXCIgKSA9PT0gMCApIHtcblx0XHRcdHMuZGF0YSA9IHMuZGF0YS5yZXBsYWNlKCByMjAsIFwiK1wiICk7XG5cdFx0fVxuXG5cdFx0Ly8gU2V0IHRoZSBJZi1Nb2RpZmllZC1TaW5jZSBhbmQvb3IgSWYtTm9uZS1NYXRjaCBoZWFkZXIsIGlmIGluIGlmTW9kaWZpZWQgbW9kZS5cblx0XHRpZiAoIHMuaWZNb2RpZmllZCApIHtcblx0XHRcdGlmICggalF1ZXJ5Lmxhc3RNb2RpZmllZFsgY2FjaGVVUkwgXSApIHtcblx0XHRcdFx0anFYSFIuc2V0UmVxdWVzdEhlYWRlciggXCJJZi1Nb2RpZmllZC1TaW5jZVwiLCBqUXVlcnkubGFzdE1vZGlmaWVkWyBjYWNoZVVSTCBdICk7XG5cdFx0XHR9XG5cdFx0XHRpZiAoIGpRdWVyeS5ldGFnWyBjYWNoZVVSTCBdICkge1xuXHRcdFx0XHRqcVhIUi5zZXRSZXF1ZXN0SGVhZGVyKCBcIklmLU5vbmUtTWF0Y2hcIiwgalF1ZXJ5LmV0YWdbIGNhY2hlVVJMIF0gKTtcblx0XHRcdH1cblx0XHR9XG5cblx0XHQvLyBTZXQgdGhlIGNvcnJlY3QgaGVhZGVyLCBpZiBkYXRhIGlzIGJlaW5nIHNlbnRcblx0XHRpZiAoIHMuZGF0YSAmJiBzLmhhc0NvbnRlbnQgJiYgcy5jb250ZW50VHlwZSAhPT0gZmFsc2UgfHwgb3B0aW9ucy5jb250ZW50VHlwZSApIHtcblx0XHRcdGpxWEhSLnNldFJlcXVlc3RIZWFkZXIoIFwiQ29udGVudC1UeXBlXCIsIHMuY29udGVudFR5cGUgKTtcblx0XHR9XG5cblx0XHQvLyBTZXQgdGhlIEFjY2VwdHMgaGVhZGVyIGZvciB0aGUgc2VydmVyLCBkZXBlbmRpbmcgb24gdGhlIGRhdGFUeXBlXG5cdFx0anFYSFIuc2V0UmVxdWVzdEhlYWRlcihcblx0XHRcdFwiQWNjZXB0XCIsXG5cdFx0XHRzLmRhdGFUeXBlc1sgMCBdICYmIHMuYWNjZXB0c1sgcy5kYXRhVHlwZXNbIDAgXSBdID9cblx0XHRcdFx0cy5hY2NlcHRzWyBzLmRhdGFUeXBlc1sgMCBdIF0gK1xuXHRcdFx0XHRcdCggcy5kYXRhVHlwZXNbIDAgXSAhPT0gXCIqXCIgPyBcIiwgXCIgKyBhbGxUeXBlcyArIFwiOyBxPTAuMDFcIiA6IFwiXCIgKSA6XG5cdFx0XHRcdHMuYWNjZXB0c1sgXCIqXCIgXVxuXHRcdCk7XG5cblx0XHQvLyBDaGVjayBmb3IgaGVhZGVycyBvcHRpb25cblx0XHRmb3IgKCBpIGluIHMuaGVhZGVycyApIHtcblx0XHRcdGpxWEhSLnNldFJlcXVlc3RIZWFkZXIoIGksIHMuaGVhZGVyc1sgaSBdICk7XG5cdFx0fVxuXG5cdFx0Ly8gQWxsb3cgY3VzdG9tIGhlYWRlcnMvbWltZXR5cGVzIGFuZCBlYXJseSBhYm9ydFxuXHRcdGlmICggcy5iZWZvcmVTZW5kICYmXG5cdFx0XHQoIHMuYmVmb3JlU2VuZC5jYWxsKCBjYWxsYmFja0NvbnRleHQsIGpxWEhSLCBzICkgPT09IGZhbHNlIHx8IGNvbXBsZXRlZCApICkge1xuXG5cdFx0XHQvLyBBYm9ydCBpZiBub3QgZG9uZSBhbHJlYWR5IGFuZCByZXR1cm5cblx0XHRcdHJldHVybiBqcVhIUi5hYm9ydCgpO1xuXHRcdH1cblxuXHRcdC8vIEFib3J0aW5nIGlzIG5vIGxvbmdlciBhIGNhbmNlbGxhdGlvblxuXHRcdHN0ckFib3J0ID0gXCJhYm9ydFwiO1xuXG5cdFx0Ly8gSW5zdGFsbCBjYWxsYmFja3Mgb24gZGVmZXJyZWRzXG5cdFx0Y29tcGxldGVEZWZlcnJlZC5hZGQoIHMuY29tcGxldGUgKTtcblx0XHRqcVhIUi5kb25lKCBzLnN1Y2Nlc3MgKTtcblx0XHRqcVhIUi5mYWlsKCBzLmVycm9yICk7XG5cblx0XHQvLyBHZXQgdHJhbnNwb3J0XG5cdFx0dHJhbnNwb3J0ID0gaW5zcGVjdFByZWZpbHRlcnNPclRyYW5zcG9ydHMoIHRyYW5zcG9ydHMsIHMsIG9wdGlvbnMsIGpxWEhSICk7XG5cblx0XHQvLyBJZiBubyB0cmFuc3BvcnQsIHdlIGF1dG8tYWJvcnRcblx0XHRpZiAoICF0cmFuc3BvcnQgKSB7XG5cdFx0XHRkb25lKCAtMSwgXCJObyBUcmFuc3BvcnRcIiApO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHRqcVhIUi5yZWFkeVN0YXRlID0gMTtcblxuXHRcdFx0Ly8gU2VuZCBnbG9iYWwgZXZlbnRcblx0XHRcdGlmICggZmlyZUdsb2JhbHMgKSB7XG5cdFx0XHRcdGdsb2JhbEV2ZW50Q29udGV4dC50cmlnZ2VyKCBcImFqYXhTZW5kXCIsIFsganFYSFIsIHMgXSApO1xuXHRcdFx0fVxuXG5cdFx0XHQvLyBJZiByZXF1ZXN0IHdhcyBhYm9ydGVkIGluc2lkZSBhamF4U2VuZCwgc3RvcCB0aGVyZVxuXHRcdFx0aWYgKCBjb21wbGV0ZWQgKSB7XG5cdFx0XHRcdHJldHVybiBqcVhIUjtcblx0XHRcdH1cblxuXHRcdFx0Ly8gVGltZW91dFxuXHRcdFx0aWYgKCBzLmFzeW5jICYmIHMudGltZW91dCA+IDAgKSB7XG5cdFx0XHRcdHRpbWVvdXRUaW1lciA9IHdpbmRvdy5zZXRUaW1lb3V0KCBmdW5jdGlvbigpIHtcblx0XHRcdFx0XHRqcVhIUi5hYm9ydCggXCJ0aW1lb3V0XCIgKTtcblx0XHRcdFx0fSwgcy50aW1lb3V0ICk7XG5cdFx0XHR9XG5cblx0XHRcdHRyeSB7XG5cdFx0XHRcdGNvbXBsZXRlZCA9IGZhbHNlO1xuXHRcdFx0XHR0cmFuc3BvcnQuc2VuZCggcmVxdWVzdEhlYWRlcnMsIGRvbmUgKTtcblx0XHRcdH0gY2F0Y2ggKCBlICkge1xuXG5cdFx0XHRcdC8vIFJldGhyb3cgcG9zdC1jb21wbGV0aW9uIGV4Y2VwdGlvbnNcblx0XHRcdFx0aWYgKCBjb21wbGV0ZWQgKSB7XG5cdFx0XHRcdFx0dGhyb3cgZTtcblx0XHRcdFx0fVxuXG5cdFx0XHRcdC8vIFByb3BhZ2F0ZSBvdGhlcnMgYXMgcmVzdWx0c1xuXHRcdFx0XHRkb25lKCAtMSwgZSApO1xuXHRcdFx0fVxuXHRcdH1cblxuXHRcdC8vIENhbGxiYWNrIGZvciB3aGVuIGV2ZXJ5dGhpbmcgaXMgZG9uZVxuXHRcdGZ1bmN0aW9uIGRvbmUoIHN0YXR1cywgbmF0aXZlU3RhdHVzVGV4dCwgcmVzcG9uc2VzLCBoZWFkZXJzICkge1xuXHRcdFx0dmFyIGlzU3VjY2Vzcywgc3VjY2VzcywgZXJyb3IsIHJlc3BvbnNlLCBtb2RpZmllZCxcblx0XHRcdFx0c3RhdHVzVGV4dCA9IG5hdGl2ZVN0YXR1c1RleHQ7XG5cblx0XHRcdC8vIElnbm9yZSByZXBlYXQgaW52b2NhdGlvbnNcblx0XHRcdGlmICggY29tcGxldGVkICkge1xuXHRcdFx0XHRyZXR1cm47XG5cdFx0XHR9XG5cblx0XHRcdGNvbXBsZXRlZCA9IHRydWU7XG5cblx0XHRcdC8vIENsZWFyIHRpbWVvdXQgaWYgaXQgZXhpc3RzXG5cdFx0XHRpZiAoIHRpbWVvdXRUaW1lciApIHtcblx0XHRcdFx0d2luZG93LmNsZWFyVGltZW91dCggdGltZW91dFRpbWVyICk7XG5cdFx0XHR9XG5cblx0XHRcdC8vIERlcmVmZXJlbmNlIHRyYW5zcG9ydCBmb3IgZWFybHkgZ2FyYmFnZSBjb2xsZWN0aW9uXG5cdFx0XHQvLyAobm8gbWF0dGVyIGhvdyBsb25nIHRoZSBqcVhIUiBvYmplY3Qgd2lsbCBiZSB1c2VkKVxuXHRcdFx0dHJhbnNwb3J0ID0gdW5kZWZpbmVkO1xuXG5cdFx0XHQvLyBDYWNoZSByZXNwb25zZSBoZWFkZXJzXG5cdFx0XHRyZXNwb25zZUhlYWRlcnNTdHJpbmcgPSBoZWFkZXJzIHx8IFwiXCI7XG5cblx0XHRcdC8vIFNldCByZWFkeVN0YXRlXG5cdFx0XHRqcVhIUi5yZWFkeVN0YXRlID0gc3RhdHVzID4gMCA/IDQgOiAwO1xuXG5cdFx0XHQvLyBEZXRlcm1pbmUgaWYgc3VjY2Vzc2Z1bFxuXHRcdFx0aXNTdWNjZXNzID0gc3RhdHVzID49IDIwMCAmJiBzdGF0dXMgPCAzMDAgfHwgc3RhdHVzID09PSAzMDQ7XG5cblx0XHRcdC8vIEdldCByZXNwb25zZSBkYXRhXG5cdFx0XHRpZiAoIHJlc3BvbnNlcyApIHtcblx0XHRcdFx0cmVzcG9uc2UgPSBhamF4SGFuZGxlUmVzcG9uc2VzKCBzLCBqcVhIUiwgcmVzcG9uc2VzICk7XG5cdFx0XHR9XG5cblx0XHRcdC8vIENvbnZlcnQgbm8gbWF0dGVyIHdoYXQgKHRoYXQgd2F5IHJlc3BvbnNlWFhYIGZpZWxkcyBhcmUgYWx3YXlzIHNldClcblx0XHRcdHJlc3BvbnNlID0gYWpheENvbnZlcnQoIHMsIHJlc3BvbnNlLCBqcVhIUiwgaXNTdWNjZXNzICk7XG5cblx0XHRcdC8vIElmIHN1Y2Nlc3NmdWwsIGhhbmRsZSB0eXBlIGNoYWluaW5nXG5cdFx0XHRpZiAoIGlzU3VjY2VzcyApIHtcblxuXHRcdFx0XHQvLyBTZXQgdGhlIElmLU1vZGlmaWVkLVNpbmNlIGFuZC9vciBJZi1Ob25lLU1hdGNoIGhlYWRlciwgaWYgaW4gaWZNb2RpZmllZCBtb2RlLlxuXHRcdFx0XHRpZiAoIHMuaWZNb2RpZmllZCApIHtcblx0XHRcdFx0XHRtb2RpZmllZCA9IGpxWEhSLmdldFJlc3BvbnNlSGVhZGVyKCBcIkxhc3QtTW9kaWZpZWRcIiApO1xuXHRcdFx0XHRcdGlmICggbW9kaWZpZWQgKSB7XG5cdFx0XHRcdFx0XHRqUXVlcnkubGFzdE1vZGlmaWVkWyBjYWNoZVVSTCBdID0gbW9kaWZpZWQ7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHRcdG1vZGlmaWVkID0ganFYSFIuZ2V0UmVzcG9uc2VIZWFkZXIoIFwiZXRhZ1wiICk7XG5cdFx0XHRcdFx0aWYgKCBtb2RpZmllZCApIHtcblx0XHRcdFx0XHRcdGpRdWVyeS5ldGFnWyBjYWNoZVVSTCBdID0gbW9kaWZpZWQ7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cblx0XHRcdFx0Ly8gaWYgbm8gY29udGVudFxuXHRcdFx0XHRpZiAoIHN0YXR1cyA9PT0gMjA0IHx8IHMudHlwZSA9PT0gXCJIRUFEXCIgKSB7XG5cdFx0XHRcdFx0c3RhdHVzVGV4dCA9IFwibm9jb250ZW50XCI7XG5cblx0XHRcdFx0Ly8gaWYgbm90IG1vZGlmaWVkXG5cdFx0XHRcdH0gZWxzZSBpZiAoIHN0YXR1cyA9PT0gMzA0ICkge1xuXHRcdFx0XHRcdHN0YXR1c1RleHQgPSBcIm5vdG1vZGlmaWVkXCI7XG5cblx0XHRcdFx0Ly8gSWYgd2UgaGF2ZSBkYXRhLCBsZXQncyBjb252ZXJ0IGl0XG5cdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0c3RhdHVzVGV4dCA9IHJlc3BvbnNlLnN0YXRlO1xuXHRcdFx0XHRcdHN1Y2Nlc3MgPSByZXNwb25zZS5kYXRhO1xuXHRcdFx0XHRcdGVycm9yID0gcmVzcG9uc2UuZXJyb3I7XG5cdFx0XHRcdFx0aXNTdWNjZXNzID0gIWVycm9yO1xuXHRcdFx0XHR9XG5cdFx0XHR9IGVsc2Uge1xuXG5cdFx0XHRcdC8vIEV4dHJhY3QgZXJyb3IgZnJvbSBzdGF0dXNUZXh0IGFuZCBub3JtYWxpemUgZm9yIG5vbi1hYm9ydHNcblx0XHRcdFx0ZXJyb3IgPSBzdGF0dXNUZXh0O1xuXHRcdFx0XHRpZiAoIHN0YXR1cyB8fCAhc3RhdHVzVGV4dCApIHtcblx0XHRcdFx0XHRzdGF0dXNUZXh0ID0gXCJlcnJvclwiO1xuXHRcdFx0XHRcdGlmICggc3RhdHVzIDwgMCApIHtcblx0XHRcdFx0XHRcdHN0YXR1cyA9IDA7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cdFx0XHR9XG5cblx0XHRcdC8vIFNldCBkYXRhIGZvciB0aGUgZmFrZSB4aHIgb2JqZWN0XG5cdFx0XHRqcVhIUi5zdGF0dXMgPSBzdGF0dXM7XG5cdFx0XHRqcVhIUi5zdGF0dXNUZXh0ID0gKCBuYXRpdmVTdGF0dXNUZXh0IHx8IHN0YXR1c1RleHQgKSArIFwiXCI7XG5cblx0XHRcdC8vIFN1Y2Nlc3MvRXJyb3Jcblx0XHRcdGlmICggaXNTdWNjZXNzICkge1xuXHRcdFx0XHRkZWZlcnJlZC5yZXNvbHZlV2l0aCggY2FsbGJhY2tDb250ZXh0LCBbIHN1Y2Nlc3MsIHN0YXR1c1RleHQsIGpxWEhSIF0gKTtcblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdGRlZmVycmVkLnJlamVjdFdpdGgoIGNhbGxiYWNrQ29udGV4dCwgWyBqcVhIUiwgc3RhdHVzVGV4dCwgZXJyb3IgXSApO1xuXHRcdFx0fVxuXG5cdFx0XHQvLyBTdGF0dXMtZGVwZW5kZW50IGNhbGxiYWNrc1xuXHRcdFx0anFYSFIuc3RhdHVzQ29kZSggc3RhdHVzQ29kZSApO1xuXHRcdFx0c3RhdHVzQ29kZSA9IHVuZGVmaW5lZDtcblxuXHRcdFx0aWYgKCBmaXJlR2xvYmFscyApIHtcblx0XHRcdFx0Z2xvYmFsRXZlbnRDb250ZXh0LnRyaWdnZXIoIGlzU3VjY2VzcyA/IFwiYWpheFN1Y2Nlc3NcIiA6IFwiYWpheEVycm9yXCIsXG5cdFx0XHRcdFx0WyBqcVhIUiwgcywgaXNTdWNjZXNzID8gc3VjY2VzcyA6IGVycm9yIF0gKTtcblx0XHRcdH1cblxuXHRcdFx0Ly8gQ29tcGxldGVcblx0XHRcdGNvbXBsZXRlRGVmZXJyZWQuZmlyZVdpdGgoIGNhbGxiYWNrQ29udGV4dCwgWyBqcVhIUiwgc3RhdHVzVGV4dCBdICk7XG5cblx0XHRcdGlmICggZmlyZUdsb2JhbHMgKSB7XG5cdFx0XHRcdGdsb2JhbEV2ZW50Q29udGV4dC50cmlnZ2VyKCBcImFqYXhDb21wbGV0ZVwiLCBbIGpxWEhSLCBzIF0gKTtcblxuXHRcdFx0XHQvLyBIYW5kbGUgdGhlIGdsb2JhbCBBSkFYIGNvdW50ZXJcblx0XHRcdFx0aWYgKCAhKCAtLWpRdWVyeS5hY3RpdmUgKSApIHtcblx0XHRcdFx0XHRqUXVlcnkuZXZlbnQudHJpZ2dlciggXCJhamF4U3RvcFwiICk7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9XG5cblx0XHRyZXR1cm4ganFYSFI7XG5cdH0sXG5cblx0Z2V0SlNPTjogZnVuY3Rpb24oIHVybCwgZGF0YSwgY2FsbGJhY2sgKSB7XG5cdFx0cmV0dXJuIGpRdWVyeS5nZXQoIHVybCwgZGF0YSwgY2FsbGJhY2ssIFwianNvblwiICk7XG5cdH0sXG5cblx0Z2V0U2NyaXB0OiBmdW5jdGlvbiggdXJsLCBjYWxsYmFjayApIHtcblx0XHRyZXR1cm4galF1ZXJ5LmdldCggdXJsLCB1bmRlZmluZWQsIGNhbGxiYWNrLCBcInNjcmlwdFwiICk7XG5cdH1cbn0gKTtcblxualF1ZXJ5LmVhY2goIFsgXCJnZXRcIiwgXCJwb3N0XCIgXSwgZnVuY3Rpb24oIGksIG1ldGhvZCApIHtcblx0alF1ZXJ5WyBtZXRob2QgXSA9IGZ1bmN0aW9uKCB1cmwsIGRhdGEsIGNhbGxiYWNrLCB0eXBlICkge1xuXG5cdFx0Ly8gU2hpZnQgYXJndW1lbnRzIGlmIGRhdGEgYXJndW1lbnQgd2FzIG9taXR0ZWRcblx0XHRpZiAoIGpRdWVyeS5pc0Z1bmN0aW9uKCBkYXRhICkgKSB7XG5cdFx0XHR0eXBlID0gdHlwZSB8fCBjYWxsYmFjaztcblx0XHRcdGNhbGxiYWNrID0gZGF0YTtcblx0XHRcdGRhdGEgPSB1bmRlZmluZWQ7XG5cdFx0fVxuXG5cdFx0Ly8gVGhlIHVybCBjYW4gYmUgYW4gb3B0aW9ucyBvYmplY3QgKHdoaWNoIHRoZW4gbXVzdCBoYXZlIC51cmwpXG5cdFx0cmV0dXJuIGpRdWVyeS5hamF4KCBqUXVlcnkuZXh0ZW5kKCB7XG5cdFx0XHR1cmw6IHVybCxcblx0XHRcdHR5cGU6IG1ldGhvZCxcblx0XHRcdGRhdGFUeXBlOiB0eXBlLFxuXHRcdFx0ZGF0YTogZGF0YSxcblx0XHRcdHN1Y2Nlc3M6IGNhbGxiYWNrXG5cdFx0fSwgalF1ZXJ5LmlzUGxhaW5PYmplY3QoIHVybCApICYmIHVybCApICk7XG5cdH07XG59ICk7XG5cblxualF1ZXJ5Ll9ldmFsVXJsID0gZnVuY3Rpb24oIHVybCApIHtcblx0cmV0dXJuIGpRdWVyeS5hamF4KCB7XG5cdFx0dXJsOiB1cmwsXG5cblx0XHQvLyBNYWtlIHRoaXMgZXhwbGljaXQsIHNpbmNlIHVzZXIgY2FuIG92ZXJyaWRlIHRoaXMgdGhyb3VnaCBhamF4U2V0dXAgKCMxMTI2NClcblx0XHR0eXBlOiBcIkdFVFwiLFxuXHRcdGRhdGFUeXBlOiBcInNjcmlwdFwiLFxuXHRcdGNhY2hlOiB0cnVlLFxuXHRcdGFzeW5jOiBmYWxzZSxcblx0XHRnbG9iYWw6IGZhbHNlLFxuXHRcdFwidGhyb3dzXCI6IHRydWVcblx0fSApO1xufTtcblxuXG5qUXVlcnkuZm4uZXh0ZW5kKCB7XG5cdHdyYXBBbGw6IGZ1bmN0aW9uKCBodG1sICkge1xuXHRcdHZhciB3cmFwO1xuXG5cdFx0aWYgKCB0aGlzWyAwIF0gKSB7XG5cdFx0XHRpZiAoIGpRdWVyeS5pc0Z1bmN0aW9uKCBodG1sICkgKSB7XG5cdFx0XHRcdGh0bWwgPSBodG1sLmNhbGwoIHRoaXNbIDAgXSApO1xuXHRcdFx0fVxuXG5cdFx0XHQvLyBUaGUgZWxlbWVudHMgdG8gd3JhcCB0aGUgdGFyZ2V0IGFyb3VuZFxuXHRcdFx0d3JhcCA9IGpRdWVyeSggaHRtbCwgdGhpc1sgMCBdLm93bmVyRG9jdW1lbnQgKS5lcSggMCApLmNsb25lKCB0cnVlICk7XG5cblx0XHRcdGlmICggdGhpc1sgMCBdLnBhcmVudE5vZGUgKSB7XG5cdFx0XHRcdHdyYXAuaW5zZXJ0QmVmb3JlKCB0aGlzWyAwIF0gKTtcblx0XHRcdH1cblxuXHRcdFx0d3JhcC5tYXAoIGZ1bmN0aW9uKCkge1xuXHRcdFx0XHR2YXIgZWxlbSA9IHRoaXM7XG5cblx0XHRcdFx0d2hpbGUgKCBlbGVtLmZpcnN0RWxlbWVudENoaWxkICkge1xuXHRcdFx0XHRcdGVsZW0gPSBlbGVtLmZpcnN0RWxlbWVudENoaWxkO1xuXHRcdFx0XHR9XG5cblx0XHRcdFx0cmV0dXJuIGVsZW07XG5cdFx0XHR9ICkuYXBwZW5kKCB0aGlzICk7XG5cdFx0fVxuXG5cdFx0cmV0dXJuIHRoaXM7XG5cdH0sXG5cblx0d3JhcElubmVyOiBmdW5jdGlvbiggaHRtbCApIHtcblx0XHRpZiAoIGpRdWVyeS5pc0Z1bmN0aW9uKCBodG1sICkgKSB7XG5cdFx0XHRyZXR1cm4gdGhpcy5lYWNoKCBmdW5jdGlvbiggaSApIHtcblx0XHRcdFx0alF1ZXJ5KCB0aGlzICkud3JhcElubmVyKCBodG1sLmNhbGwoIHRoaXMsIGkgKSApO1xuXHRcdFx0fSApO1xuXHRcdH1cblxuXHRcdHJldHVybiB0aGlzLmVhY2goIGZ1bmN0aW9uKCkge1xuXHRcdFx0dmFyIHNlbGYgPSBqUXVlcnkoIHRoaXMgKSxcblx0XHRcdFx0Y29udGVudHMgPSBzZWxmLmNvbnRlbnRzKCk7XG5cblx0XHRcdGlmICggY29udGVudHMubGVuZ3RoICkge1xuXHRcdFx0XHRjb250ZW50cy53cmFwQWxsKCBodG1sICk7XG5cblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdHNlbGYuYXBwZW5kKCBodG1sICk7XG5cdFx0XHR9XG5cdFx0fSApO1xuXHR9LFxuXG5cdHdyYXA6IGZ1bmN0aW9uKCBodG1sICkge1xuXHRcdHZhciBpc0Z1bmN0aW9uID0galF1ZXJ5LmlzRnVuY3Rpb24oIGh0bWwgKTtcblxuXHRcdHJldHVybiB0aGlzLmVhY2goIGZ1bmN0aW9uKCBpICkge1xuXHRcdFx0alF1ZXJ5KCB0aGlzICkud3JhcEFsbCggaXNGdW5jdGlvbiA/IGh0bWwuY2FsbCggdGhpcywgaSApIDogaHRtbCApO1xuXHRcdH0gKTtcblx0fSxcblxuXHR1bndyYXA6IGZ1bmN0aW9uKCBzZWxlY3RvciApIHtcblx0XHR0aGlzLnBhcmVudCggc2VsZWN0b3IgKS5ub3QoIFwiYm9keVwiICkuZWFjaCggZnVuY3Rpb24oKSB7XG5cdFx0XHRqUXVlcnkoIHRoaXMgKS5yZXBsYWNlV2l0aCggdGhpcy5jaGlsZE5vZGVzICk7XG5cdFx0fSApO1xuXHRcdHJldHVybiB0aGlzO1xuXHR9XG59ICk7XG5cblxualF1ZXJ5LmV4cHIucHNldWRvcy5oaWRkZW4gPSBmdW5jdGlvbiggZWxlbSApIHtcblx0cmV0dXJuICFqUXVlcnkuZXhwci5wc2V1ZG9zLnZpc2libGUoIGVsZW0gKTtcbn07XG5qUXVlcnkuZXhwci5wc2V1ZG9zLnZpc2libGUgPSBmdW5jdGlvbiggZWxlbSApIHtcblx0cmV0dXJuICEhKCBlbGVtLm9mZnNldFdpZHRoIHx8IGVsZW0ub2Zmc2V0SGVpZ2h0IHx8IGVsZW0uZ2V0Q2xpZW50UmVjdHMoKS5sZW5ndGggKTtcbn07XG5cblxuXG5cbmpRdWVyeS5hamF4U2V0dGluZ3MueGhyID0gZnVuY3Rpb24oKSB7XG5cdHRyeSB7XG5cdFx0cmV0dXJuIG5ldyB3aW5kb3cuWE1MSHR0cFJlcXVlc3QoKTtcblx0fSBjYXRjaCAoIGUgKSB7fVxufTtcblxudmFyIHhoclN1Y2Nlc3NTdGF0dXMgPSB7XG5cblx0XHQvLyBGaWxlIHByb3RvY29sIGFsd2F5cyB5aWVsZHMgc3RhdHVzIGNvZGUgMCwgYXNzdW1lIDIwMFxuXHRcdDA6IDIwMCxcblxuXHRcdC8vIFN1cHBvcnQ6IElFIDw9OSBvbmx5XG5cdFx0Ly8gIzE0NTA6IHNvbWV0aW1lcyBJRSByZXR1cm5zIDEyMjMgd2hlbiBpdCBzaG91bGQgYmUgMjA0XG5cdFx0MTIyMzogMjA0XG5cdH0sXG5cdHhoclN1cHBvcnRlZCA9IGpRdWVyeS5hamF4U2V0dGluZ3MueGhyKCk7XG5cbnN1cHBvcnQuY29ycyA9ICEheGhyU3VwcG9ydGVkICYmICggXCJ3aXRoQ3JlZGVudGlhbHNcIiBpbiB4aHJTdXBwb3J0ZWQgKTtcbnN1cHBvcnQuYWpheCA9IHhoclN1cHBvcnRlZCA9ICEheGhyU3VwcG9ydGVkO1xuXG5qUXVlcnkuYWpheFRyYW5zcG9ydCggZnVuY3Rpb24oIG9wdGlvbnMgKSB7XG5cdHZhciBjYWxsYmFjaywgZXJyb3JDYWxsYmFjaztcblxuXHQvLyBDcm9zcyBkb21haW4gb25seSBhbGxvd2VkIGlmIHN1cHBvcnRlZCB0aHJvdWdoIFhNTEh0dHBSZXF1ZXN0XG5cdGlmICggc3VwcG9ydC5jb3JzIHx8IHhoclN1cHBvcnRlZCAmJiAhb3B0aW9ucy5jcm9zc0RvbWFpbiApIHtcblx0XHRyZXR1cm4ge1xuXHRcdFx0c2VuZDogZnVuY3Rpb24oIGhlYWRlcnMsIGNvbXBsZXRlICkge1xuXHRcdFx0XHR2YXIgaSxcblx0XHRcdFx0XHR4aHIgPSBvcHRpb25zLnhocigpO1xuXG5cdFx0XHRcdHhoci5vcGVuKFxuXHRcdFx0XHRcdG9wdGlvbnMudHlwZSxcblx0XHRcdFx0XHRvcHRpb25zLnVybCxcblx0XHRcdFx0XHRvcHRpb25zLmFzeW5jLFxuXHRcdFx0XHRcdG9wdGlvbnMudXNlcm5hbWUsXG5cdFx0XHRcdFx0b3B0aW9ucy5wYXNzd29yZFxuXHRcdFx0XHQpO1xuXG5cdFx0XHRcdC8vIEFwcGx5IGN1c3RvbSBmaWVsZHMgaWYgcHJvdmlkZWRcblx0XHRcdFx0aWYgKCBvcHRpb25zLnhockZpZWxkcyApIHtcblx0XHRcdFx0XHRmb3IgKCBpIGluIG9wdGlvbnMueGhyRmllbGRzICkge1xuXHRcdFx0XHRcdFx0eGhyWyBpIF0gPSBvcHRpb25zLnhockZpZWxkc1sgaSBdO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXG5cdFx0XHRcdC8vIE92ZXJyaWRlIG1pbWUgdHlwZSBpZiBuZWVkZWRcblx0XHRcdFx0aWYgKCBvcHRpb25zLm1pbWVUeXBlICYmIHhoci5vdmVycmlkZU1pbWVUeXBlICkge1xuXHRcdFx0XHRcdHhoci5vdmVycmlkZU1pbWVUeXBlKCBvcHRpb25zLm1pbWVUeXBlICk7XG5cdFx0XHRcdH1cblxuXHRcdFx0XHQvLyBYLVJlcXVlc3RlZC1XaXRoIGhlYWRlclxuXHRcdFx0XHQvLyBGb3IgY3Jvc3MtZG9tYWluIHJlcXVlc3RzLCBzZWVpbmcgYXMgY29uZGl0aW9ucyBmb3IgYSBwcmVmbGlnaHQgYXJlXG5cdFx0XHRcdC8vIGFraW4gdG8gYSBqaWdzYXcgcHV6emxlLCB3ZSBzaW1wbHkgbmV2ZXIgc2V0IGl0IHRvIGJlIHN1cmUuXG5cdFx0XHRcdC8vIChpdCBjYW4gYWx3YXlzIGJlIHNldCBvbiBhIHBlci1yZXF1ZXN0IGJhc2lzIG9yIGV2ZW4gdXNpbmcgYWpheFNldHVwKVxuXHRcdFx0XHQvLyBGb3Igc2FtZS1kb21haW4gcmVxdWVzdHMsIHdvbid0IGNoYW5nZSBoZWFkZXIgaWYgYWxyZWFkeSBwcm92aWRlZC5cblx0XHRcdFx0aWYgKCAhb3B0aW9ucy5jcm9zc0RvbWFpbiAmJiAhaGVhZGVyc1sgXCJYLVJlcXVlc3RlZC1XaXRoXCIgXSApIHtcblx0XHRcdFx0XHRoZWFkZXJzWyBcIlgtUmVxdWVzdGVkLVdpdGhcIiBdID0gXCJYTUxIdHRwUmVxdWVzdFwiO1xuXHRcdFx0XHR9XG5cblx0XHRcdFx0Ly8gU2V0IGhlYWRlcnNcblx0XHRcdFx0Zm9yICggaSBpbiBoZWFkZXJzICkge1xuXHRcdFx0XHRcdHhoci5zZXRSZXF1ZXN0SGVhZGVyKCBpLCBoZWFkZXJzWyBpIF0gKTtcblx0XHRcdFx0fVxuXG5cdFx0XHRcdC8vIENhbGxiYWNrXG5cdFx0XHRcdGNhbGxiYWNrID0gZnVuY3Rpb24oIHR5cGUgKSB7XG5cdFx0XHRcdFx0cmV0dXJuIGZ1bmN0aW9uKCkge1xuXHRcdFx0XHRcdFx0aWYgKCBjYWxsYmFjayApIHtcblx0XHRcdFx0XHRcdFx0Y2FsbGJhY2sgPSBlcnJvckNhbGxiYWNrID0geGhyLm9ubG9hZCA9XG5cdFx0XHRcdFx0XHRcdFx0eGhyLm9uZXJyb3IgPSB4aHIub25hYm9ydCA9IHhoci5vbnJlYWR5c3RhdGVjaGFuZ2UgPSBudWxsO1xuXG5cdFx0XHRcdFx0XHRcdGlmICggdHlwZSA9PT0gXCJhYm9ydFwiICkge1xuXHRcdFx0XHRcdFx0XHRcdHhoci5hYm9ydCgpO1xuXHRcdFx0XHRcdFx0XHR9IGVsc2UgaWYgKCB0eXBlID09PSBcImVycm9yXCIgKSB7XG5cblx0XHRcdFx0XHRcdFx0XHQvLyBTdXBwb3J0OiBJRSA8PTkgb25seVxuXHRcdFx0XHRcdFx0XHRcdC8vIE9uIGEgbWFudWFsIG5hdGl2ZSBhYm9ydCwgSUU5IHRocm93c1xuXHRcdFx0XHRcdFx0XHRcdC8vIGVycm9ycyBvbiBhbnkgcHJvcGVydHkgYWNjZXNzIHRoYXQgaXMgbm90IHJlYWR5U3RhdGVcblx0XHRcdFx0XHRcdFx0XHRpZiAoIHR5cGVvZiB4aHIuc3RhdHVzICE9PSBcIm51bWJlclwiICkge1xuXHRcdFx0XHRcdFx0XHRcdFx0Y29tcGxldGUoIDAsIFwiZXJyb3JcIiApO1xuXHRcdFx0XHRcdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0XHRcdFx0XHRjb21wbGV0ZShcblxuXHRcdFx0XHRcdFx0XHRcdFx0XHQvLyBGaWxlOiBwcm90b2NvbCBhbHdheXMgeWllbGRzIHN0YXR1cyAwOyBzZWUgIzg2MDUsICMxNDIwN1xuXHRcdFx0XHRcdFx0XHRcdFx0XHR4aHIuc3RhdHVzLFxuXHRcdFx0XHRcdFx0XHRcdFx0XHR4aHIuc3RhdHVzVGV4dFxuXHRcdFx0XHRcdFx0XHRcdFx0KTtcblx0XHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0XHRcdFx0Y29tcGxldGUoXG5cdFx0XHRcdFx0XHRcdFx0XHR4aHJTdWNjZXNzU3RhdHVzWyB4aHIuc3RhdHVzIF0gfHwgeGhyLnN0YXR1cyxcblx0XHRcdFx0XHRcdFx0XHRcdHhoci5zdGF0dXNUZXh0LFxuXG5cdFx0XHRcdFx0XHRcdFx0XHQvLyBTdXBwb3J0OiBJRSA8PTkgb25seVxuXHRcdFx0XHRcdFx0XHRcdFx0Ly8gSUU5IGhhcyBubyBYSFIyIGJ1dCB0aHJvd3Mgb24gYmluYXJ5ICh0cmFjLTExNDI2KVxuXHRcdFx0XHRcdFx0XHRcdFx0Ly8gRm9yIFhIUjIgbm9uLXRleHQsIGxldCB0aGUgY2FsbGVyIGhhbmRsZSBpdCAoZ2gtMjQ5OClcblx0XHRcdFx0XHRcdFx0XHRcdCggeGhyLnJlc3BvbnNlVHlwZSB8fCBcInRleHRcIiApICE9PSBcInRleHRcIiAgfHxcblx0XHRcdFx0XHRcdFx0XHRcdHR5cGVvZiB4aHIucmVzcG9uc2VUZXh0ICE9PSBcInN0cmluZ1wiID9cblx0XHRcdFx0XHRcdFx0XHRcdFx0eyBiaW5hcnk6IHhoci5yZXNwb25zZSB9IDpcblx0XHRcdFx0XHRcdFx0XHRcdFx0eyB0ZXh0OiB4aHIucmVzcG9uc2VUZXh0IH0sXG5cdFx0XHRcdFx0XHRcdFx0XHR4aHIuZ2V0QWxsUmVzcG9uc2VIZWFkZXJzKClcblx0XHRcdFx0XHRcdFx0XHQpO1xuXHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0fTtcblx0XHRcdFx0fTtcblxuXHRcdFx0XHQvLyBMaXN0ZW4gdG8gZXZlbnRzXG5cdFx0XHRcdHhoci5vbmxvYWQgPSBjYWxsYmFjaygpO1xuXHRcdFx0XHRlcnJvckNhbGxiYWNrID0geGhyLm9uZXJyb3IgPSBjYWxsYmFjayggXCJlcnJvclwiICk7XG5cblx0XHRcdFx0Ly8gU3VwcG9ydDogSUUgOSBvbmx5XG5cdFx0XHRcdC8vIFVzZSBvbnJlYWR5c3RhdGVjaGFuZ2UgdG8gcmVwbGFjZSBvbmFib3J0XG5cdFx0XHRcdC8vIHRvIGhhbmRsZSB1bmNhdWdodCBhYm9ydHNcblx0XHRcdFx0aWYgKCB4aHIub25hYm9ydCAhPT0gdW5kZWZpbmVkICkge1xuXHRcdFx0XHRcdHhoci5vbmFib3J0ID0gZXJyb3JDYWxsYmFjaztcblx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHR4aHIub25yZWFkeXN0YXRlY2hhbmdlID0gZnVuY3Rpb24oKSB7XG5cblx0XHRcdFx0XHRcdC8vIENoZWNrIHJlYWR5U3RhdGUgYmVmb3JlIHRpbWVvdXQgYXMgaXQgY2hhbmdlc1xuXHRcdFx0XHRcdFx0aWYgKCB4aHIucmVhZHlTdGF0ZSA9PT0gNCApIHtcblxuXHRcdFx0XHRcdFx0XHQvLyBBbGxvdyBvbmVycm9yIHRvIGJlIGNhbGxlZCBmaXJzdCxcblx0XHRcdFx0XHRcdFx0Ly8gYnV0IHRoYXQgd2lsbCBub3QgaGFuZGxlIGEgbmF0aXZlIGFib3J0XG5cdFx0XHRcdFx0XHRcdC8vIEFsc28sIHNhdmUgZXJyb3JDYWxsYmFjayB0byBhIHZhcmlhYmxlXG5cdFx0XHRcdFx0XHRcdC8vIGFzIHhoci5vbmVycm9yIGNhbm5vdCBiZSBhY2Nlc3NlZFxuXHRcdFx0XHRcdFx0XHR3aW5kb3cuc2V0VGltZW91dCggZnVuY3Rpb24oKSB7XG5cdFx0XHRcdFx0XHRcdFx0aWYgKCBjYWxsYmFjayApIHtcblx0XHRcdFx0XHRcdFx0XHRcdGVycm9yQ2FsbGJhY2soKTtcblx0XHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHRcdH0gKTtcblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHR9O1xuXHRcdFx0XHR9XG5cblx0XHRcdFx0Ly8gQ3JlYXRlIHRoZSBhYm9ydCBjYWxsYmFja1xuXHRcdFx0XHRjYWxsYmFjayA9IGNhbGxiYWNrKCBcImFib3J0XCIgKTtcblxuXHRcdFx0XHR0cnkge1xuXG5cdFx0XHRcdFx0Ly8gRG8gc2VuZCB0aGUgcmVxdWVzdCAodGhpcyBtYXkgcmFpc2UgYW4gZXhjZXB0aW9uKVxuXHRcdFx0XHRcdHhoci5zZW5kKCBvcHRpb25zLmhhc0NvbnRlbnQgJiYgb3B0aW9ucy5kYXRhIHx8IG51bGwgKTtcblx0XHRcdFx0fSBjYXRjaCAoIGUgKSB7XG5cblx0XHRcdFx0XHQvLyAjMTQ2ODM6IE9ubHkgcmV0aHJvdyBpZiB0aGlzIGhhc24ndCBiZWVuIG5vdGlmaWVkIGFzIGFuIGVycm9yIHlldFxuXHRcdFx0XHRcdGlmICggY2FsbGJhY2sgKSB7XG5cdFx0XHRcdFx0XHR0aHJvdyBlO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXHRcdFx0fSxcblxuXHRcdFx0YWJvcnQ6IGZ1bmN0aW9uKCkge1xuXHRcdFx0XHRpZiAoIGNhbGxiYWNrICkge1xuXHRcdFx0XHRcdGNhbGxiYWNrKCk7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9O1xuXHR9XG59ICk7XG5cblxuXG5cbi8vIFByZXZlbnQgYXV0by1leGVjdXRpb24gb2Ygc2NyaXB0cyB3aGVuIG5vIGV4cGxpY2l0IGRhdGFUeXBlIHdhcyBwcm92aWRlZCAoU2VlIGdoLTI0MzIpXG5qUXVlcnkuYWpheFByZWZpbHRlciggZnVuY3Rpb24oIHMgKSB7XG5cdGlmICggcy5jcm9zc0RvbWFpbiApIHtcblx0XHRzLmNvbnRlbnRzLnNjcmlwdCA9IGZhbHNlO1xuXHR9XG59ICk7XG5cbi8vIEluc3RhbGwgc2NyaXB0IGRhdGFUeXBlXG5qUXVlcnkuYWpheFNldHVwKCB7XG5cdGFjY2VwdHM6IHtcblx0XHRzY3JpcHQ6IFwidGV4dC9qYXZhc2NyaXB0LCBhcHBsaWNhdGlvbi9qYXZhc2NyaXB0LCBcIiArXG5cdFx0XHRcImFwcGxpY2F0aW9uL2VjbWFzY3JpcHQsIGFwcGxpY2F0aW9uL3gtZWNtYXNjcmlwdFwiXG5cdH0sXG5cdGNvbnRlbnRzOiB7XG5cdFx0c2NyaXB0OiAvXFxiKD86amF2YXxlY21hKXNjcmlwdFxcYi9cblx0fSxcblx0Y29udmVydGVyczoge1xuXHRcdFwidGV4dCBzY3JpcHRcIjogZnVuY3Rpb24oIHRleHQgKSB7XG5cdFx0XHRqUXVlcnkuZ2xvYmFsRXZhbCggdGV4dCApO1xuXHRcdFx0cmV0dXJuIHRleHQ7XG5cdFx0fVxuXHR9XG59ICk7XG5cbi8vIEhhbmRsZSBjYWNoZSdzIHNwZWNpYWwgY2FzZSBhbmQgY3Jvc3NEb21haW5cbmpRdWVyeS5hamF4UHJlZmlsdGVyKCBcInNjcmlwdFwiLCBmdW5jdGlvbiggcyApIHtcblx0aWYgKCBzLmNhY2hlID09PSB1bmRlZmluZWQgKSB7XG5cdFx0cy5jYWNoZSA9IGZhbHNlO1xuXHR9XG5cdGlmICggcy5jcm9zc0RvbWFpbiApIHtcblx0XHRzLnR5cGUgPSBcIkdFVFwiO1xuXHR9XG59ICk7XG5cbi8vIEJpbmQgc2NyaXB0IHRhZyBoYWNrIHRyYW5zcG9ydFxualF1ZXJ5LmFqYXhUcmFuc3BvcnQoIFwic2NyaXB0XCIsIGZ1bmN0aW9uKCBzICkge1xuXG5cdC8vIFRoaXMgdHJhbnNwb3J0IG9ubHkgZGVhbHMgd2l0aCBjcm9zcyBkb21haW4gcmVxdWVzdHNcblx0aWYgKCBzLmNyb3NzRG9tYWluICkge1xuXHRcdHZhciBzY3JpcHQsIGNhbGxiYWNrO1xuXHRcdHJldHVybiB7XG5cdFx0XHRzZW5kOiBmdW5jdGlvbiggXywgY29tcGxldGUgKSB7XG5cdFx0XHRcdHNjcmlwdCA9IGpRdWVyeSggXCI8c2NyaXB0PlwiICkucHJvcCgge1xuXHRcdFx0XHRcdGNoYXJzZXQ6IHMuc2NyaXB0Q2hhcnNldCxcblx0XHRcdFx0XHRzcmM6IHMudXJsXG5cdFx0XHRcdH0gKS5vbihcblx0XHRcdFx0XHRcImxvYWQgZXJyb3JcIixcblx0XHRcdFx0XHRjYWxsYmFjayA9IGZ1bmN0aW9uKCBldnQgKSB7XG5cdFx0XHRcdFx0XHRzY3JpcHQucmVtb3ZlKCk7XG5cdFx0XHRcdFx0XHRjYWxsYmFjayA9IG51bGw7XG5cdFx0XHRcdFx0XHRpZiAoIGV2dCApIHtcblx0XHRcdFx0XHRcdFx0Y29tcGxldGUoIGV2dC50eXBlID09PSBcImVycm9yXCIgPyA0MDQgOiAyMDAsIGV2dC50eXBlICk7XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHQpO1xuXG5cdFx0XHRcdC8vIFVzZSBuYXRpdmUgRE9NIG1hbmlwdWxhdGlvbiB0byBhdm9pZCBvdXIgZG9tTWFuaXAgQUpBWCB0cmlja2VyeVxuXHRcdFx0XHRkb2N1bWVudC5oZWFkLmFwcGVuZENoaWxkKCBzY3JpcHRbIDAgXSApO1xuXHRcdFx0fSxcblx0XHRcdGFib3J0OiBmdW5jdGlvbigpIHtcblx0XHRcdFx0aWYgKCBjYWxsYmFjayApIHtcblx0XHRcdFx0XHRjYWxsYmFjaygpO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fTtcblx0fVxufSApO1xuXG5cblxuXG52YXIgb2xkQ2FsbGJhY2tzID0gW10sXG5cdHJqc29ucCA9IC8oPSlcXD8oPz0mfCQpfFxcP1xcPy87XG5cbi8vIERlZmF1bHQganNvbnAgc2V0dGluZ3NcbmpRdWVyeS5hamF4U2V0dXAoIHtcblx0anNvbnA6IFwiY2FsbGJhY2tcIixcblx0anNvbnBDYWxsYmFjazogZnVuY3Rpb24oKSB7XG5cdFx0dmFyIGNhbGxiYWNrID0gb2xkQ2FsbGJhY2tzLnBvcCgpIHx8ICggalF1ZXJ5LmV4cGFuZG8gKyBcIl9cIiArICggbm9uY2UrKyApICk7XG5cdFx0dGhpc1sgY2FsbGJhY2sgXSA9IHRydWU7XG5cdFx0cmV0dXJuIGNhbGxiYWNrO1xuXHR9XG59ICk7XG5cbi8vIERldGVjdCwgbm9ybWFsaXplIG9wdGlvbnMgYW5kIGluc3RhbGwgY2FsbGJhY2tzIGZvciBqc29ucCByZXF1ZXN0c1xualF1ZXJ5LmFqYXhQcmVmaWx0ZXIoIFwianNvbiBqc29ucFwiLCBmdW5jdGlvbiggcywgb3JpZ2luYWxTZXR0aW5ncywganFYSFIgKSB7XG5cblx0dmFyIGNhbGxiYWNrTmFtZSwgb3ZlcndyaXR0ZW4sIHJlc3BvbnNlQ29udGFpbmVyLFxuXHRcdGpzb25Qcm9wID0gcy5qc29ucCAhPT0gZmFsc2UgJiYgKCByanNvbnAudGVzdCggcy51cmwgKSA/XG5cdFx0XHRcInVybFwiIDpcblx0XHRcdHR5cGVvZiBzLmRhdGEgPT09IFwic3RyaW5nXCIgJiZcblx0XHRcdFx0KCBzLmNvbnRlbnRUeXBlIHx8IFwiXCIgKVxuXHRcdFx0XHRcdC5pbmRleE9mKCBcImFwcGxpY2F0aW9uL3gtd3d3LWZvcm0tdXJsZW5jb2RlZFwiICkgPT09IDAgJiZcblx0XHRcdFx0cmpzb25wLnRlc3QoIHMuZGF0YSApICYmIFwiZGF0YVwiXG5cdFx0KTtcblxuXHQvLyBIYW5kbGUgaWZmIHRoZSBleHBlY3RlZCBkYXRhIHR5cGUgaXMgXCJqc29ucFwiIG9yIHdlIGhhdmUgYSBwYXJhbWV0ZXIgdG8gc2V0XG5cdGlmICgganNvblByb3AgfHwgcy5kYXRhVHlwZXNbIDAgXSA9PT0gXCJqc29ucFwiICkge1xuXG5cdFx0Ly8gR2V0IGNhbGxiYWNrIG5hbWUsIHJlbWVtYmVyaW5nIHByZWV4aXN0aW5nIHZhbHVlIGFzc29jaWF0ZWQgd2l0aCBpdFxuXHRcdGNhbGxiYWNrTmFtZSA9IHMuanNvbnBDYWxsYmFjayA9IGpRdWVyeS5pc0Z1bmN0aW9uKCBzLmpzb25wQ2FsbGJhY2sgKSA/XG5cdFx0XHRzLmpzb25wQ2FsbGJhY2soKSA6XG5cdFx0XHRzLmpzb25wQ2FsbGJhY2s7XG5cblx0XHQvLyBJbnNlcnQgY2FsbGJhY2sgaW50byB1cmwgb3IgZm9ybSBkYXRhXG5cdFx0aWYgKCBqc29uUHJvcCApIHtcblx0XHRcdHNbIGpzb25Qcm9wIF0gPSBzWyBqc29uUHJvcCBdLnJlcGxhY2UoIHJqc29ucCwgXCIkMVwiICsgY2FsbGJhY2tOYW1lICk7XG5cdFx0fSBlbHNlIGlmICggcy5qc29ucCAhPT0gZmFsc2UgKSB7XG5cdFx0XHRzLnVybCArPSAoIHJxdWVyeS50ZXN0KCBzLnVybCApID8gXCImXCIgOiBcIj9cIiApICsgcy5qc29ucCArIFwiPVwiICsgY2FsbGJhY2tOYW1lO1xuXHRcdH1cblxuXHRcdC8vIFVzZSBkYXRhIGNvbnZlcnRlciB0byByZXRyaWV2ZSBqc29uIGFmdGVyIHNjcmlwdCBleGVjdXRpb25cblx0XHRzLmNvbnZlcnRlcnNbIFwic2NyaXB0IGpzb25cIiBdID0gZnVuY3Rpb24oKSB7XG5cdFx0XHRpZiAoICFyZXNwb25zZUNvbnRhaW5lciApIHtcblx0XHRcdFx0alF1ZXJ5LmVycm9yKCBjYWxsYmFja05hbWUgKyBcIiB3YXMgbm90IGNhbGxlZFwiICk7XG5cdFx0XHR9XG5cdFx0XHRyZXR1cm4gcmVzcG9uc2VDb250YWluZXJbIDAgXTtcblx0XHR9O1xuXG5cdFx0Ly8gRm9yY2UganNvbiBkYXRhVHlwZVxuXHRcdHMuZGF0YVR5cGVzWyAwIF0gPSBcImpzb25cIjtcblxuXHRcdC8vIEluc3RhbGwgY2FsbGJhY2tcblx0XHRvdmVyd3JpdHRlbiA9IHdpbmRvd1sgY2FsbGJhY2tOYW1lIF07XG5cdFx0d2luZG93WyBjYWxsYmFja05hbWUgXSA9IGZ1bmN0aW9uKCkge1xuXHRcdFx0cmVzcG9uc2VDb250YWluZXIgPSBhcmd1bWVudHM7XG5cdFx0fTtcblxuXHRcdC8vIENsZWFuLXVwIGZ1bmN0aW9uIChmaXJlcyBhZnRlciBjb252ZXJ0ZXJzKVxuXHRcdGpxWEhSLmFsd2F5cyggZnVuY3Rpb24oKSB7XG5cblx0XHRcdC8vIElmIHByZXZpb3VzIHZhbHVlIGRpZG4ndCBleGlzdCAtIHJlbW92ZSBpdFxuXHRcdFx0aWYgKCBvdmVyd3JpdHRlbiA9PT0gdW5kZWZpbmVkICkge1xuXHRcdFx0XHRqUXVlcnkoIHdpbmRvdyApLnJlbW92ZVByb3AoIGNhbGxiYWNrTmFtZSApO1xuXG5cdFx0XHQvLyBPdGhlcndpc2UgcmVzdG9yZSBwcmVleGlzdGluZyB2YWx1ZVxuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0d2luZG93WyBjYWxsYmFja05hbWUgXSA9IG92ZXJ3cml0dGVuO1xuXHRcdFx0fVxuXG5cdFx0XHQvLyBTYXZlIGJhY2sgYXMgZnJlZVxuXHRcdFx0aWYgKCBzWyBjYWxsYmFja05hbWUgXSApIHtcblxuXHRcdFx0XHQvLyBNYWtlIHN1cmUgdGhhdCByZS11c2luZyB0aGUgb3B0aW9ucyBkb2Vzbid0IHNjcmV3IHRoaW5ncyBhcm91bmRcblx0XHRcdFx0cy5qc29ucENhbGxiYWNrID0gb3JpZ2luYWxTZXR0aW5ncy5qc29ucENhbGxiYWNrO1xuXG5cdFx0XHRcdC8vIFNhdmUgdGhlIGNhbGxiYWNrIG5hbWUgZm9yIGZ1dHVyZSB1c2Vcblx0XHRcdFx0b2xkQ2FsbGJhY2tzLnB1c2goIGNhbGxiYWNrTmFtZSApO1xuXHRcdFx0fVxuXG5cdFx0XHQvLyBDYWxsIGlmIGl0IHdhcyBhIGZ1bmN0aW9uIGFuZCB3ZSBoYXZlIGEgcmVzcG9uc2Vcblx0XHRcdGlmICggcmVzcG9uc2VDb250YWluZXIgJiYgalF1ZXJ5LmlzRnVuY3Rpb24oIG92ZXJ3cml0dGVuICkgKSB7XG5cdFx0XHRcdG92ZXJ3cml0dGVuKCByZXNwb25zZUNvbnRhaW5lclsgMCBdICk7XG5cdFx0XHR9XG5cblx0XHRcdHJlc3BvbnNlQ29udGFpbmVyID0gb3ZlcndyaXR0ZW4gPSB1bmRlZmluZWQ7XG5cdFx0fSApO1xuXG5cdFx0Ly8gRGVsZWdhdGUgdG8gc2NyaXB0XG5cdFx0cmV0dXJuIFwic2NyaXB0XCI7XG5cdH1cbn0gKTtcblxuXG5cblxuLy8gU3VwcG9ydDogU2FmYXJpIDggb25seVxuLy8gSW4gU2FmYXJpIDggZG9jdW1lbnRzIGNyZWF0ZWQgdmlhIGRvY3VtZW50LmltcGxlbWVudGF0aW9uLmNyZWF0ZUhUTUxEb2N1bWVudFxuLy8gY29sbGFwc2Ugc2libGluZyBmb3JtczogdGhlIHNlY29uZCBvbmUgYmVjb21lcyBhIGNoaWxkIG9mIHRoZSBmaXJzdCBvbmUuXG4vLyBCZWNhdXNlIG9mIHRoYXQsIHRoaXMgc2VjdXJpdHkgbWVhc3VyZSBoYXMgdG8gYmUgZGlzYWJsZWQgaW4gU2FmYXJpIDguXG4vLyBodHRwczovL2J1Z3Mud2Via2l0Lm9yZy9zaG93X2J1Zy5jZ2k/aWQ9MTM3MzM3XG5zdXBwb3J0LmNyZWF0ZUhUTUxEb2N1bWVudCA9ICggZnVuY3Rpb24oKSB7XG5cdHZhciBib2R5ID0gZG9jdW1lbnQuaW1wbGVtZW50YXRpb24uY3JlYXRlSFRNTERvY3VtZW50KCBcIlwiICkuYm9keTtcblx0Ym9keS5pbm5lckhUTUwgPSBcIjxmb3JtPjwvZm9ybT48Zm9ybT48L2Zvcm0+XCI7XG5cdHJldHVybiBib2R5LmNoaWxkTm9kZXMubGVuZ3RoID09PSAyO1xufSApKCk7XG5cblxuLy8gQXJndW1lbnQgXCJkYXRhXCIgc2hvdWxkIGJlIHN0cmluZyBvZiBodG1sXG4vLyBjb250ZXh0IChvcHRpb25hbCk6IElmIHNwZWNpZmllZCwgdGhlIGZyYWdtZW50IHdpbGwgYmUgY3JlYXRlZCBpbiB0aGlzIGNvbnRleHQsXG4vLyBkZWZhdWx0cyB0byBkb2N1bWVudFxuLy8ga2VlcFNjcmlwdHMgKG9wdGlvbmFsKTogSWYgdHJ1ZSwgd2lsbCBpbmNsdWRlIHNjcmlwdHMgcGFzc2VkIGluIHRoZSBodG1sIHN0cmluZ1xualF1ZXJ5LnBhcnNlSFRNTCA9IGZ1bmN0aW9uKCBkYXRhLCBjb250ZXh0LCBrZWVwU2NyaXB0cyApIHtcblx0aWYgKCB0eXBlb2YgZGF0YSAhPT0gXCJzdHJpbmdcIiApIHtcblx0XHRyZXR1cm4gW107XG5cdH1cblx0aWYgKCB0eXBlb2YgY29udGV4dCA9PT0gXCJib29sZWFuXCIgKSB7XG5cdFx0a2VlcFNjcmlwdHMgPSBjb250ZXh0O1xuXHRcdGNvbnRleHQgPSBmYWxzZTtcblx0fVxuXG5cdHZhciBiYXNlLCBwYXJzZWQsIHNjcmlwdHM7XG5cblx0aWYgKCAhY29udGV4dCApIHtcblxuXHRcdC8vIFN0b3Agc2NyaXB0cyBvciBpbmxpbmUgZXZlbnQgaGFuZGxlcnMgZnJvbSBiZWluZyBleGVjdXRlZCBpbW1lZGlhdGVseVxuXHRcdC8vIGJ5IHVzaW5nIGRvY3VtZW50LmltcGxlbWVudGF0aW9uXG5cdFx0aWYgKCBzdXBwb3J0LmNyZWF0ZUhUTUxEb2N1bWVudCApIHtcblx0XHRcdGNvbnRleHQgPSBkb2N1bWVudC5pbXBsZW1lbnRhdGlvbi5jcmVhdGVIVE1MRG9jdW1lbnQoIFwiXCIgKTtcblxuXHRcdFx0Ly8gU2V0IHRoZSBiYXNlIGhyZWYgZm9yIHRoZSBjcmVhdGVkIGRvY3VtZW50XG5cdFx0XHQvLyBzbyBhbnkgcGFyc2VkIGVsZW1lbnRzIHdpdGggVVJMc1xuXHRcdFx0Ly8gYXJlIGJhc2VkIG9uIHRoZSBkb2N1bWVudCdzIFVSTCAoZ2gtMjk2NSlcblx0XHRcdGJhc2UgPSBjb250ZXh0LmNyZWF0ZUVsZW1lbnQoIFwiYmFzZVwiICk7XG5cdFx0XHRiYXNlLmhyZWYgPSBkb2N1bWVudC5sb2NhdGlvbi5ocmVmO1xuXHRcdFx0Y29udGV4dC5oZWFkLmFwcGVuZENoaWxkKCBiYXNlICk7XG5cdFx0fSBlbHNlIHtcblx0XHRcdGNvbnRleHQgPSBkb2N1bWVudDtcblx0XHR9XG5cdH1cblxuXHRwYXJzZWQgPSByc2luZ2xlVGFnLmV4ZWMoIGRhdGEgKTtcblx0c2NyaXB0cyA9ICFrZWVwU2NyaXB0cyAmJiBbXTtcblxuXHQvLyBTaW5nbGUgdGFnXG5cdGlmICggcGFyc2VkICkge1xuXHRcdHJldHVybiBbIGNvbnRleHQuY3JlYXRlRWxlbWVudCggcGFyc2VkWyAxIF0gKSBdO1xuXHR9XG5cblx0cGFyc2VkID0gYnVpbGRGcmFnbWVudCggWyBkYXRhIF0sIGNvbnRleHQsIHNjcmlwdHMgKTtcblxuXHRpZiAoIHNjcmlwdHMgJiYgc2NyaXB0cy5sZW5ndGggKSB7XG5cdFx0alF1ZXJ5KCBzY3JpcHRzICkucmVtb3ZlKCk7XG5cdH1cblxuXHRyZXR1cm4galF1ZXJ5Lm1lcmdlKCBbXSwgcGFyc2VkLmNoaWxkTm9kZXMgKTtcbn07XG5cblxuLyoqXG4gKiBMb2FkIGEgdXJsIGludG8gYSBwYWdlXG4gKi9cbmpRdWVyeS5mbi5sb2FkID0gZnVuY3Rpb24oIHVybCwgcGFyYW1zLCBjYWxsYmFjayApIHtcblx0dmFyIHNlbGVjdG9yLCB0eXBlLCByZXNwb25zZSxcblx0XHRzZWxmID0gdGhpcyxcblx0XHRvZmYgPSB1cmwuaW5kZXhPZiggXCIgXCIgKTtcblxuXHRpZiAoIG9mZiA+IC0xICkge1xuXHRcdHNlbGVjdG9yID0gc3RyaXBBbmRDb2xsYXBzZSggdXJsLnNsaWNlKCBvZmYgKSApO1xuXHRcdHVybCA9IHVybC5zbGljZSggMCwgb2ZmICk7XG5cdH1cblxuXHQvLyBJZiBpdCdzIGEgZnVuY3Rpb25cblx0aWYgKCBqUXVlcnkuaXNGdW5jdGlvbiggcGFyYW1zICkgKSB7XG5cblx0XHQvLyBXZSBhc3N1bWUgdGhhdCBpdCdzIHRoZSBjYWxsYmFja1xuXHRcdGNhbGxiYWNrID0gcGFyYW1zO1xuXHRcdHBhcmFtcyA9IHVuZGVmaW5lZDtcblxuXHQvLyBPdGhlcndpc2UsIGJ1aWxkIGEgcGFyYW0gc3RyaW5nXG5cdH0gZWxzZSBpZiAoIHBhcmFtcyAmJiB0eXBlb2YgcGFyYW1zID09PSBcIm9iamVjdFwiICkge1xuXHRcdHR5cGUgPSBcIlBPU1RcIjtcblx0fVxuXG5cdC8vIElmIHdlIGhhdmUgZWxlbWVudHMgdG8gbW9kaWZ5LCBtYWtlIHRoZSByZXF1ZXN0XG5cdGlmICggc2VsZi5sZW5ndGggPiAwICkge1xuXHRcdGpRdWVyeS5hamF4KCB7XG5cdFx0XHR1cmw6IHVybCxcblxuXHRcdFx0Ly8gSWYgXCJ0eXBlXCIgdmFyaWFibGUgaXMgdW5kZWZpbmVkLCB0aGVuIFwiR0VUXCIgbWV0aG9kIHdpbGwgYmUgdXNlZC5cblx0XHRcdC8vIE1ha2UgdmFsdWUgb2YgdGhpcyBmaWVsZCBleHBsaWNpdCBzaW5jZVxuXHRcdFx0Ly8gdXNlciBjYW4gb3ZlcnJpZGUgaXQgdGhyb3VnaCBhamF4U2V0dXAgbWV0aG9kXG5cdFx0XHR0eXBlOiB0eXBlIHx8IFwiR0VUXCIsXG5cdFx0XHRkYXRhVHlwZTogXCJodG1sXCIsXG5cdFx0XHRkYXRhOiBwYXJhbXNcblx0XHR9ICkuZG9uZSggZnVuY3Rpb24oIHJlc3BvbnNlVGV4dCApIHtcblxuXHRcdFx0Ly8gU2F2ZSByZXNwb25zZSBmb3IgdXNlIGluIGNvbXBsZXRlIGNhbGxiYWNrXG5cdFx0XHRyZXNwb25zZSA9IGFyZ3VtZW50cztcblxuXHRcdFx0c2VsZi5odG1sKCBzZWxlY3RvciA/XG5cblx0XHRcdFx0Ly8gSWYgYSBzZWxlY3RvciB3YXMgc3BlY2lmaWVkLCBsb2NhdGUgdGhlIHJpZ2h0IGVsZW1lbnRzIGluIGEgZHVtbXkgZGl2XG5cdFx0XHRcdC8vIEV4Y2x1ZGUgc2NyaXB0cyB0byBhdm9pZCBJRSAnUGVybWlzc2lvbiBEZW5pZWQnIGVycm9yc1xuXHRcdFx0XHRqUXVlcnkoIFwiPGRpdj5cIiApLmFwcGVuZCggalF1ZXJ5LnBhcnNlSFRNTCggcmVzcG9uc2VUZXh0ICkgKS5maW5kKCBzZWxlY3RvciApIDpcblxuXHRcdFx0XHQvLyBPdGhlcndpc2UgdXNlIHRoZSBmdWxsIHJlc3VsdFxuXHRcdFx0XHRyZXNwb25zZVRleHQgKTtcblxuXHRcdC8vIElmIHRoZSByZXF1ZXN0IHN1Y2NlZWRzLCB0aGlzIGZ1bmN0aW9uIGdldHMgXCJkYXRhXCIsIFwic3RhdHVzXCIsIFwianFYSFJcIlxuXHRcdC8vIGJ1dCB0aGV5IGFyZSBpZ25vcmVkIGJlY2F1c2UgcmVzcG9uc2Ugd2FzIHNldCBhYm92ZS5cblx0XHQvLyBJZiBpdCBmYWlscywgdGhpcyBmdW5jdGlvbiBnZXRzIFwianFYSFJcIiwgXCJzdGF0dXNcIiwgXCJlcnJvclwiXG5cdFx0fSApLmFsd2F5cyggY2FsbGJhY2sgJiYgZnVuY3Rpb24oIGpxWEhSLCBzdGF0dXMgKSB7XG5cdFx0XHRzZWxmLmVhY2goIGZ1bmN0aW9uKCkge1xuXHRcdFx0XHRjYWxsYmFjay5hcHBseSggdGhpcywgcmVzcG9uc2UgfHwgWyBqcVhIUi5yZXNwb25zZVRleHQsIHN0YXR1cywganFYSFIgXSApO1xuXHRcdFx0fSApO1xuXHRcdH0gKTtcblx0fVxuXG5cdHJldHVybiB0aGlzO1xufTtcblxuXG5cblxuLy8gQXR0YWNoIGEgYnVuY2ggb2YgZnVuY3Rpb25zIGZvciBoYW5kbGluZyBjb21tb24gQUpBWCBldmVudHNcbmpRdWVyeS5lYWNoKCBbXG5cdFwiYWpheFN0YXJ0XCIsXG5cdFwiYWpheFN0b3BcIixcblx0XCJhamF4Q29tcGxldGVcIixcblx0XCJhamF4RXJyb3JcIixcblx0XCJhamF4U3VjY2Vzc1wiLFxuXHRcImFqYXhTZW5kXCJcbl0sIGZ1bmN0aW9uKCBpLCB0eXBlICkge1xuXHRqUXVlcnkuZm5bIHR5cGUgXSA9IGZ1bmN0aW9uKCBmbiApIHtcblx0XHRyZXR1cm4gdGhpcy5vbiggdHlwZSwgZm4gKTtcblx0fTtcbn0gKTtcblxuXG5cblxualF1ZXJ5LmV4cHIucHNldWRvcy5hbmltYXRlZCA9IGZ1bmN0aW9uKCBlbGVtICkge1xuXHRyZXR1cm4galF1ZXJ5LmdyZXAoIGpRdWVyeS50aW1lcnMsIGZ1bmN0aW9uKCBmbiApIHtcblx0XHRyZXR1cm4gZWxlbSA9PT0gZm4uZWxlbTtcblx0fSApLmxlbmd0aDtcbn07XG5cblxuXG5cbmpRdWVyeS5vZmZzZXQgPSB7XG5cdHNldE9mZnNldDogZnVuY3Rpb24oIGVsZW0sIG9wdGlvbnMsIGkgKSB7XG5cdFx0dmFyIGN1clBvc2l0aW9uLCBjdXJMZWZ0LCBjdXJDU1NUb3AsIGN1clRvcCwgY3VyT2Zmc2V0LCBjdXJDU1NMZWZ0LCBjYWxjdWxhdGVQb3NpdGlvbixcblx0XHRcdHBvc2l0aW9uID0galF1ZXJ5LmNzcyggZWxlbSwgXCJwb3NpdGlvblwiICksXG5cdFx0XHRjdXJFbGVtID0galF1ZXJ5KCBlbGVtICksXG5cdFx0XHRwcm9wcyA9IHt9O1xuXG5cdFx0Ly8gU2V0IHBvc2l0aW9uIGZpcnN0LCBpbi1jYXNlIHRvcC9sZWZ0IGFyZSBzZXQgZXZlbiBvbiBzdGF0aWMgZWxlbVxuXHRcdGlmICggcG9zaXRpb24gPT09IFwic3RhdGljXCIgKSB7XG5cdFx0XHRlbGVtLnN0eWxlLnBvc2l0aW9uID0gXCJyZWxhdGl2ZVwiO1xuXHRcdH1cblxuXHRcdGN1ck9mZnNldCA9IGN1ckVsZW0ub2Zmc2V0KCk7XG5cdFx0Y3VyQ1NTVG9wID0galF1ZXJ5LmNzcyggZWxlbSwgXCJ0b3BcIiApO1xuXHRcdGN1ckNTU0xlZnQgPSBqUXVlcnkuY3NzKCBlbGVtLCBcImxlZnRcIiApO1xuXHRcdGNhbGN1bGF0ZVBvc2l0aW9uID0gKCBwb3NpdGlvbiA9PT0gXCJhYnNvbHV0ZVwiIHx8IHBvc2l0aW9uID09PSBcImZpeGVkXCIgKSAmJlxuXHRcdFx0KCBjdXJDU1NUb3AgKyBjdXJDU1NMZWZ0ICkuaW5kZXhPZiggXCJhdXRvXCIgKSA+IC0xO1xuXG5cdFx0Ly8gTmVlZCB0byBiZSBhYmxlIHRvIGNhbGN1bGF0ZSBwb3NpdGlvbiBpZiBlaXRoZXJcblx0XHQvLyB0b3Agb3IgbGVmdCBpcyBhdXRvIGFuZCBwb3NpdGlvbiBpcyBlaXRoZXIgYWJzb2x1dGUgb3IgZml4ZWRcblx0XHRpZiAoIGNhbGN1bGF0ZVBvc2l0aW9uICkge1xuXHRcdFx0Y3VyUG9zaXRpb24gPSBjdXJFbGVtLnBvc2l0aW9uKCk7XG5cdFx0XHRjdXJUb3AgPSBjdXJQb3NpdGlvbi50b3A7XG5cdFx0XHRjdXJMZWZ0ID0gY3VyUG9zaXRpb24ubGVmdDtcblxuXHRcdH0gZWxzZSB7XG5cdFx0XHRjdXJUb3AgPSBwYXJzZUZsb2F0KCBjdXJDU1NUb3AgKSB8fCAwO1xuXHRcdFx0Y3VyTGVmdCA9IHBhcnNlRmxvYXQoIGN1ckNTU0xlZnQgKSB8fCAwO1xuXHRcdH1cblxuXHRcdGlmICggalF1ZXJ5LmlzRnVuY3Rpb24oIG9wdGlvbnMgKSApIHtcblxuXHRcdFx0Ly8gVXNlIGpRdWVyeS5leHRlbmQgaGVyZSB0byBhbGxvdyBtb2RpZmljYXRpb24gb2YgY29vcmRpbmF0ZXMgYXJndW1lbnQgKGdoLTE4NDgpXG5cdFx0XHRvcHRpb25zID0gb3B0aW9ucy5jYWxsKCBlbGVtLCBpLCBqUXVlcnkuZXh0ZW5kKCB7fSwgY3VyT2Zmc2V0ICkgKTtcblx0XHR9XG5cblx0XHRpZiAoIG9wdGlvbnMudG9wICE9IG51bGwgKSB7XG5cdFx0XHRwcm9wcy50b3AgPSAoIG9wdGlvbnMudG9wIC0gY3VyT2Zmc2V0LnRvcCApICsgY3VyVG9wO1xuXHRcdH1cblx0XHRpZiAoIG9wdGlvbnMubGVmdCAhPSBudWxsICkge1xuXHRcdFx0cHJvcHMubGVmdCA9ICggb3B0aW9ucy5sZWZ0IC0gY3VyT2Zmc2V0LmxlZnQgKSArIGN1ckxlZnQ7XG5cdFx0fVxuXG5cdFx0aWYgKCBcInVzaW5nXCIgaW4gb3B0aW9ucyApIHtcblx0XHRcdG9wdGlvbnMudXNpbmcuY2FsbCggZWxlbSwgcHJvcHMgKTtcblxuXHRcdH0gZWxzZSB7XG5cdFx0XHRjdXJFbGVtLmNzcyggcHJvcHMgKTtcblx0XHR9XG5cdH1cbn07XG5cbmpRdWVyeS5mbi5leHRlbmQoIHtcblx0b2Zmc2V0OiBmdW5jdGlvbiggb3B0aW9ucyApIHtcblxuXHRcdC8vIFByZXNlcnZlIGNoYWluaW5nIGZvciBzZXR0ZXJcblx0XHRpZiAoIGFyZ3VtZW50cy5sZW5ndGggKSB7XG5cdFx0XHRyZXR1cm4gb3B0aW9ucyA9PT0gdW5kZWZpbmVkID9cblx0XHRcdFx0dGhpcyA6XG5cdFx0XHRcdHRoaXMuZWFjaCggZnVuY3Rpb24oIGkgKSB7XG5cdFx0XHRcdFx0alF1ZXJ5Lm9mZnNldC5zZXRPZmZzZXQoIHRoaXMsIG9wdGlvbnMsIGkgKTtcblx0XHRcdFx0fSApO1xuXHRcdH1cblxuXHRcdHZhciBkb2MsIGRvY0VsZW0sIHJlY3QsIHdpbixcblx0XHRcdGVsZW0gPSB0aGlzWyAwIF07XG5cblx0XHRpZiAoICFlbGVtICkge1xuXHRcdFx0cmV0dXJuO1xuXHRcdH1cblxuXHRcdC8vIFJldHVybiB6ZXJvcyBmb3IgZGlzY29ubmVjdGVkIGFuZCBoaWRkZW4gKGRpc3BsYXk6IG5vbmUpIGVsZW1lbnRzIChnaC0yMzEwKVxuXHRcdC8vIFN1cHBvcnQ6IElFIDw9MTEgb25seVxuXHRcdC8vIFJ1bm5pbmcgZ2V0Qm91bmRpbmdDbGllbnRSZWN0IG9uIGFcblx0XHQvLyBkaXNjb25uZWN0ZWQgbm9kZSBpbiBJRSB0aHJvd3MgYW4gZXJyb3Jcblx0XHRpZiAoICFlbGVtLmdldENsaWVudFJlY3RzKCkubGVuZ3RoICkge1xuXHRcdFx0cmV0dXJuIHsgdG9wOiAwLCBsZWZ0OiAwIH07XG5cdFx0fVxuXG5cdFx0cmVjdCA9IGVsZW0uZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XG5cblx0XHRkb2MgPSBlbGVtLm93bmVyRG9jdW1lbnQ7XG5cdFx0ZG9jRWxlbSA9IGRvYy5kb2N1bWVudEVsZW1lbnQ7XG5cdFx0d2luID0gZG9jLmRlZmF1bHRWaWV3O1xuXG5cdFx0cmV0dXJuIHtcblx0XHRcdHRvcDogcmVjdC50b3AgKyB3aW4ucGFnZVlPZmZzZXQgLSBkb2NFbGVtLmNsaWVudFRvcCxcblx0XHRcdGxlZnQ6IHJlY3QubGVmdCArIHdpbi5wYWdlWE9mZnNldCAtIGRvY0VsZW0uY2xpZW50TGVmdFxuXHRcdH07XG5cdH0sXG5cblx0cG9zaXRpb246IGZ1bmN0aW9uKCkge1xuXHRcdGlmICggIXRoaXNbIDAgXSApIHtcblx0XHRcdHJldHVybjtcblx0XHR9XG5cblx0XHR2YXIgb2Zmc2V0UGFyZW50LCBvZmZzZXQsXG5cdFx0XHRlbGVtID0gdGhpc1sgMCBdLFxuXHRcdFx0cGFyZW50T2Zmc2V0ID0geyB0b3A6IDAsIGxlZnQ6IDAgfTtcblxuXHRcdC8vIEZpeGVkIGVsZW1lbnRzIGFyZSBvZmZzZXQgZnJvbSB3aW5kb3cgKHBhcmVudE9mZnNldCA9IHt0b3A6MCwgbGVmdDogMH0sXG5cdFx0Ly8gYmVjYXVzZSBpdCBpcyBpdHMgb25seSBvZmZzZXQgcGFyZW50XG5cdFx0aWYgKCBqUXVlcnkuY3NzKCBlbGVtLCBcInBvc2l0aW9uXCIgKSA9PT0gXCJmaXhlZFwiICkge1xuXG5cdFx0XHQvLyBBc3N1bWUgZ2V0Qm91bmRpbmdDbGllbnRSZWN0IGlzIHRoZXJlIHdoZW4gY29tcHV0ZWQgcG9zaXRpb24gaXMgZml4ZWRcblx0XHRcdG9mZnNldCA9IGVsZW0uZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XG5cblx0XHR9IGVsc2Uge1xuXG5cdFx0XHQvLyBHZXQgKnJlYWwqIG9mZnNldFBhcmVudFxuXHRcdFx0b2Zmc2V0UGFyZW50ID0gdGhpcy5vZmZzZXRQYXJlbnQoKTtcblxuXHRcdFx0Ly8gR2V0IGNvcnJlY3Qgb2Zmc2V0c1xuXHRcdFx0b2Zmc2V0ID0gdGhpcy5vZmZzZXQoKTtcblx0XHRcdGlmICggIW5vZGVOYW1lKCBvZmZzZXRQYXJlbnRbIDAgXSwgXCJodG1sXCIgKSApIHtcblx0XHRcdFx0cGFyZW50T2Zmc2V0ID0gb2Zmc2V0UGFyZW50Lm9mZnNldCgpO1xuXHRcdFx0fVxuXG5cdFx0XHQvLyBBZGQgb2Zmc2V0UGFyZW50IGJvcmRlcnNcblx0XHRcdHBhcmVudE9mZnNldCA9IHtcblx0XHRcdFx0dG9wOiBwYXJlbnRPZmZzZXQudG9wICsgalF1ZXJ5LmNzcyggb2Zmc2V0UGFyZW50WyAwIF0sIFwiYm9yZGVyVG9wV2lkdGhcIiwgdHJ1ZSApLFxuXHRcdFx0XHRsZWZ0OiBwYXJlbnRPZmZzZXQubGVmdCArIGpRdWVyeS5jc3MoIG9mZnNldFBhcmVudFsgMCBdLCBcImJvcmRlckxlZnRXaWR0aFwiLCB0cnVlIClcblx0XHRcdH07XG5cdFx0fVxuXG5cdFx0Ly8gU3VidHJhY3QgcGFyZW50IG9mZnNldHMgYW5kIGVsZW1lbnQgbWFyZ2luc1xuXHRcdHJldHVybiB7XG5cdFx0XHR0b3A6IG9mZnNldC50b3AgLSBwYXJlbnRPZmZzZXQudG9wIC0galF1ZXJ5LmNzcyggZWxlbSwgXCJtYXJnaW5Ub3BcIiwgdHJ1ZSApLFxuXHRcdFx0bGVmdDogb2Zmc2V0LmxlZnQgLSBwYXJlbnRPZmZzZXQubGVmdCAtIGpRdWVyeS5jc3MoIGVsZW0sIFwibWFyZ2luTGVmdFwiLCB0cnVlIClcblx0XHR9O1xuXHR9LFxuXG5cdC8vIFRoaXMgbWV0aG9kIHdpbGwgcmV0dXJuIGRvY3VtZW50RWxlbWVudCBpbiB0aGUgZm9sbG93aW5nIGNhc2VzOlxuXHQvLyAxKSBGb3IgdGhlIGVsZW1lbnQgaW5zaWRlIHRoZSBpZnJhbWUgd2l0aG91dCBvZmZzZXRQYXJlbnQsIHRoaXMgbWV0aG9kIHdpbGwgcmV0dXJuXG5cdC8vICAgIGRvY3VtZW50RWxlbWVudCBvZiB0aGUgcGFyZW50IHdpbmRvd1xuXHQvLyAyKSBGb3IgdGhlIGhpZGRlbiBvciBkZXRhY2hlZCBlbGVtZW50XG5cdC8vIDMpIEZvciBib2R5IG9yIGh0bWwgZWxlbWVudCwgaS5lLiBpbiBjYXNlIG9mIHRoZSBodG1sIG5vZGUgLSBpdCB3aWxsIHJldHVybiBpdHNlbGZcblx0Ly9cblx0Ly8gYnV0IHRob3NlIGV4Y2VwdGlvbnMgd2VyZSBuZXZlciBwcmVzZW50ZWQgYXMgYSByZWFsIGxpZmUgdXNlLWNhc2VzXG5cdC8vIGFuZCBtaWdodCBiZSBjb25zaWRlcmVkIGFzIG1vcmUgcHJlZmVyYWJsZSByZXN1bHRzLlxuXHQvL1xuXHQvLyBUaGlzIGxvZ2ljLCBob3dldmVyLCBpcyBub3QgZ3VhcmFudGVlZCBhbmQgY2FuIGNoYW5nZSBhdCBhbnkgcG9pbnQgaW4gdGhlIGZ1dHVyZVxuXHRvZmZzZXRQYXJlbnQ6IGZ1bmN0aW9uKCkge1xuXHRcdHJldHVybiB0aGlzLm1hcCggZnVuY3Rpb24oKSB7XG5cdFx0XHR2YXIgb2Zmc2V0UGFyZW50ID0gdGhpcy5vZmZzZXRQYXJlbnQ7XG5cblx0XHRcdHdoaWxlICggb2Zmc2V0UGFyZW50ICYmIGpRdWVyeS5jc3MoIG9mZnNldFBhcmVudCwgXCJwb3NpdGlvblwiICkgPT09IFwic3RhdGljXCIgKSB7XG5cdFx0XHRcdG9mZnNldFBhcmVudCA9IG9mZnNldFBhcmVudC5vZmZzZXRQYXJlbnQ7XG5cdFx0XHR9XG5cblx0XHRcdHJldHVybiBvZmZzZXRQYXJlbnQgfHwgZG9jdW1lbnRFbGVtZW50O1xuXHRcdH0gKTtcblx0fVxufSApO1xuXG4vLyBDcmVhdGUgc2Nyb2xsTGVmdCBhbmQgc2Nyb2xsVG9wIG1ldGhvZHNcbmpRdWVyeS5lYWNoKCB7IHNjcm9sbExlZnQ6IFwicGFnZVhPZmZzZXRcIiwgc2Nyb2xsVG9wOiBcInBhZ2VZT2Zmc2V0XCIgfSwgZnVuY3Rpb24oIG1ldGhvZCwgcHJvcCApIHtcblx0dmFyIHRvcCA9IFwicGFnZVlPZmZzZXRcIiA9PT0gcHJvcDtcblxuXHRqUXVlcnkuZm5bIG1ldGhvZCBdID0gZnVuY3Rpb24oIHZhbCApIHtcblx0XHRyZXR1cm4gYWNjZXNzKCB0aGlzLCBmdW5jdGlvbiggZWxlbSwgbWV0aG9kLCB2YWwgKSB7XG5cblx0XHRcdC8vIENvYWxlc2NlIGRvY3VtZW50cyBhbmQgd2luZG93c1xuXHRcdFx0dmFyIHdpbjtcblx0XHRcdGlmICggalF1ZXJ5LmlzV2luZG93KCBlbGVtICkgKSB7XG5cdFx0XHRcdHdpbiA9IGVsZW07XG5cdFx0XHR9IGVsc2UgaWYgKCBlbGVtLm5vZGVUeXBlID09PSA5ICkge1xuXHRcdFx0XHR3aW4gPSBlbGVtLmRlZmF1bHRWaWV3O1xuXHRcdFx0fVxuXG5cdFx0XHRpZiAoIHZhbCA9PT0gdW5kZWZpbmVkICkge1xuXHRcdFx0XHRyZXR1cm4gd2luID8gd2luWyBwcm9wIF0gOiBlbGVtWyBtZXRob2QgXTtcblx0XHRcdH1cblxuXHRcdFx0aWYgKCB3aW4gKSB7XG5cdFx0XHRcdHdpbi5zY3JvbGxUbyhcblx0XHRcdFx0XHQhdG9wID8gdmFsIDogd2luLnBhZ2VYT2Zmc2V0LFxuXHRcdFx0XHRcdHRvcCA/IHZhbCA6IHdpbi5wYWdlWU9mZnNldFxuXHRcdFx0XHQpO1xuXG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRlbGVtWyBtZXRob2QgXSA9IHZhbDtcblx0XHRcdH1cblx0XHR9LCBtZXRob2QsIHZhbCwgYXJndW1lbnRzLmxlbmd0aCApO1xuXHR9O1xufSApO1xuXG4vLyBTdXBwb3J0OiBTYWZhcmkgPD03IC0gOS4xLCBDaHJvbWUgPD0zNyAtIDQ5XG4vLyBBZGQgdGhlIHRvcC9sZWZ0IGNzc0hvb2tzIHVzaW5nIGpRdWVyeS5mbi5wb3NpdGlvblxuLy8gV2Via2l0IGJ1ZzogaHR0cHM6Ly9idWdzLndlYmtpdC5vcmcvc2hvd19idWcuY2dpP2lkPTI5MDg0XG4vLyBCbGluayBidWc6IGh0dHBzOi8vYnVncy5jaHJvbWl1bS5vcmcvcC9jaHJvbWl1bS9pc3N1ZXMvZGV0YWlsP2lkPTU4OTM0N1xuLy8gZ2V0Q29tcHV0ZWRTdHlsZSByZXR1cm5zIHBlcmNlbnQgd2hlbiBzcGVjaWZpZWQgZm9yIHRvcC9sZWZ0L2JvdHRvbS9yaWdodDtcbi8vIHJhdGhlciB0aGFuIG1ha2UgdGhlIGNzcyBtb2R1bGUgZGVwZW5kIG9uIHRoZSBvZmZzZXQgbW9kdWxlLCBqdXN0IGNoZWNrIGZvciBpdCBoZXJlXG5qUXVlcnkuZWFjaCggWyBcInRvcFwiLCBcImxlZnRcIiBdLCBmdW5jdGlvbiggaSwgcHJvcCApIHtcblx0alF1ZXJ5LmNzc0hvb2tzWyBwcm9wIF0gPSBhZGRHZXRIb29rSWYoIHN1cHBvcnQucGl4ZWxQb3NpdGlvbixcblx0XHRmdW5jdGlvbiggZWxlbSwgY29tcHV0ZWQgKSB7XG5cdFx0XHRpZiAoIGNvbXB1dGVkICkge1xuXHRcdFx0XHRjb21wdXRlZCA9IGN1ckNTUyggZWxlbSwgcHJvcCApO1xuXG5cdFx0XHRcdC8vIElmIGN1ckNTUyByZXR1cm5zIHBlcmNlbnRhZ2UsIGZhbGxiYWNrIHRvIG9mZnNldFxuXHRcdFx0XHRyZXR1cm4gcm51bW5vbnB4LnRlc3QoIGNvbXB1dGVkICkgP1xuXHRcdFx0XHRcdGpRdWVyeSggZWxlbSApLnBvc2l0aW9uKClbIHByb3AgXSArIFwicHhcIiA6XG5cdFx0XHRcdFx0Y29tcHV0ZWQ7XG5cdFx0XHR9XG5cdFx0fVxuXHQpO1xufSApO1xuXG5cbi8vIENyZWF0ZSBpbm5lckhlaWdodCwgaW5uZXJXaWR0aCwgaGVpZ2h0LCB3aWR0aCwgb3V0ZXJIZWlnaHQgYW5kIG91dGVyV2lkdGggbWV0aG9kc1xualF1ZXJ5LmVhY2goIHsgSGVpZ2h0OiBcImhlaWdodFwiLCBXaWR0aDogXCJ3aWR0aFwiIH0sIGZ1bmN0aW9uKCBuYW1lLCB0eXBlICkge1xuXHRqUXVlcnkuZWFjaCggeyBwYWRkaW5nOiBcImlubmVyXCIgKyBuYW1lLCBjb250ZW50OiB0eXBlLCBcIlwiOiBcIm91dGVyXCIgKyBuYW1lIH0sXG5cdFx0ZnVuY3Rpb24oIGRlZmF1bHRFeHRyYSwgZnVuY05hbWUgKSB7XG5cblx0XHQvLyBNYXJnaW4gaXMgb25seSBmb3Igb3V0ZXJIZWlnaHQsIG91dGVyV2lkdGhcblx0XHRqUXVlcnkuZm5bIGZ1bmNOYW1lIF0gPSBmdW5jdGlvbiggbWFyZ2luLCB2YWx1ZSApIHtcblx0XHRcdHZhciBjaGFpbmFibGUgPSBhcmd1bWVudHMubGVuZ3RoICYmICggZGVmYXVsdEV4dHJhIHx8IHR5cGVvZiBtYXJnaW4gIT09IFwiYm9vbGVhblwiICksXG5cdFx0XHRcdGV4dHJhID0gZGVmYXVsdEV4dHJhIHx8ICggbWFyZ2luID09PSB0cnVlIHx8IHZhbHVlID09PSB0cnVlID8gXCJtYXJnaW5cIiA6IFwiYm9yZGVyXCIgKTtcblxuXHRcdFx0cmV0dXJuIGFjY2VzcyggdGhpcywgZnVuY3Rpb24oIGVsZW0sIHR5cGUsIHZhbHVlICkge1xuXHRcdFx0XHR2YXIgZG9jO1xuXG5cdFx0XHRcdGlmICggalF1ZXJ5LmlzV2luZG93KCBlbGVtICkgKSB7XG5cblx0XHRcdFx0XHQvLyAkKCB3aW5kb3cgKS5vdXRlcldpZHRoL0hlaWdodCByZXR1cm4gdy9oIGluY2x1ZGluZyBzY3JvbGxiYXJzIChnaC0xNzI5KVxuXHRcdFx0XHRcdHJldHVybiBmdW5jTmFtZS5pbmRleE9mKCBcIm91dGVyXCIgKSA9PT0gMCA/XG5cdFx0XHRcdFx0XHRlbGVtWyBcImlubmVyXCIgKyBuYW1lIF0gOlxuXHRcdFx0XHRcdFx0ZWxlbS5kb2N1bWVudC5kb2N1bWVudEVsZW1lbnRbIFwiY2xpZW50XCIgKyBuYW1lIF07XG5cdFx0XHRcdH1cblxuXHRcdFx0XHQvLyBHZXQgZG9jdW1lbnQgd2lkdGggb3IgaGVpZ2h0XG5cdFx0XHRcdGlmICggZWxlbS5ub2RlVHlwZSA9PT0gOSApIHtcblx0XHRcdFx0XHRkb2MgPSBlbGVtLmRvY3VtZW50RWxlbWVudDtcblxuXHRcdFx0XHRcdC8vIEVpdGhlciBzY3JvbGxbV2lkdGgvSGVpZ2h0XSBvciBvZmZzZXRbV2lkdGgvSGVpZ2h0XSBvciBjbGllbnRbV2lkdGgvSGVpZ2h0XSxcblx0XHRcdFx0XHQvLyB3aGljaGV2ZXIgaXMgZ3JlYXRlc3Rcblx0XHRcdFx0XHRyZXR1cm4gTWF0aC5tYXgoXG5cdFx0XHRcdFx0XHRlbGVtLmJvZHlbIFwic2Nyb2xsXCIgKyBuYW1lIF0sIGRvY1sgXCJzY3JvbGxcIiArIG5hbWUgXSxcblx0XHRcdFx0XHRcdGVsZW0uYm9keVsgXCJvZmZzZXRcIiArIG5hbWUgXSwgZG9jWyBcIm9mZnNldFwiICsgbmFtZSBdLFxuXHRcdFx0XHRcdFx0ZG9jWyBcImNsaWVudFwiICsgbmFtZSBdXG5cdFx0XHRcdFx0KTtcblx0XHRcdFx0fVxuXG5cdFx0XHRcdHJldHVybiB2YWx1ZSA9PT0gdW5kZWZpbmVkID9cblxuXHRcdFx0XHRcdC8vIEdldCB3aWR0aCBvciBoZWlnaHQgb24gdGhlIGVsZW1lbnQsIHJlcXVlc3RpbmcgYnV0IG5vdCBmb3JjaW5nIHBhcnNlRmxvYXRcblx0XHRcdFx0XHRqUXVlcnkuY3NzKCBlbGVtLCB0eXBlLCBleHRyYSApIDpcblxuXHRcdFx0XHRcdC8vIFNldCB3aWR0aCBvciBoZWlnaHQgb24gdGhlIGVsZW1lbnRcblx0XHRcdFx0XHRqUXVlcnkuc3R5bGUoIGVsZW0sIHR5cGUsIHZhbHVlLCBleHRyYSApO1xuXHRcdFx0fSwgdHlwZSwgY2hhaW5hYmxlID8gbWFyZ2luIDogdW5kZWZpbmVkLCBjaGFpbmFibGUgKTtcblx0XHR9O1xuXHR9ICk7XG59ICk7XG5cblxualF1ZXJ5LmZuLmV4dGVuZCgge1xuXG5cdGJpbmQ6IGZ1bmN0aW9uKCB0eXBlcywgZGF0YSwgZm4gKSB7XG5cdFx0cmV0dXJuIHRoaXMub24oIHR5cGVzLCBudWxsLCBkYXRhLCBmbiApO1xuXHR9LFxuXHR1bmJpbmQ6IGZ1bmN0aW9uKCB0eXBlcywgZm4gKSB7XG5cdFx0cmV0dXJuIHRoaXMub2ZmKCB0eXBlcywgbnVsbCwgZm4gKTtcblx0fSxcblxuXHRkZWxlZ2F0ZTogZnVuY3Rpb24oIHNlbGVjdG9yLCB0eXBlcywgZGF0YSwgZm4gKSB7XG5cdFx0cmV0dXJuIHRoaXMub24oIHR5cGVzLCBzZWxlY3RvciwgZGF0YSwgZm4gKTtcblx0fSxcblx0dW5kZWxlZ2F0ZTogZnVuY3Rpb24oIHNlbGVjdG9yLCB0eXBlcywgZm4gKSB7XG5cblx0XHQvLyAoIG5hbWVzcGFjZSApIG9yICggc2VsZWN0b3IsIHR5cGVzIFssIGZuXSApXG5cdFx0cmV0dXJuIGFyZ3VtZW50cy5sZW5ndGggPT09IDEgP1xuXHRcdFx0dGhpcy5vZmYoIHNlbGVjdG9yLCBcIioqXCIgKSA6XG5cdFx0XHR0aGlzLm9mZiggdHlwZXMsIHNlbGVjdG9yIHx8IFwiKipcIiwgZm4gKTtcblx0fVxufSApO1xuXG5qUXVlcnkuaG9sZFJlYWR5ID0gZnVuY3Rpb24oIGhvbGQgKSB7XG5cdGlmICggaG9sZCApIHtcblx0XHRqUXVlcnkucmVhZHlXYWl0Kys7XG5cdH0gZWxzZSB7XG5cdFx0alF1ZXJ5LnJlYWR5KCB0cnVlICk7XG5cdH1cbn07XG5qUXVlcnkuaXNBcnJheSA9IEFycmF5LmlzQXJyYXk7XG5qUXVlcnkucGFyc2VKU09OID0gSlNPTi5wYXJzZTtcbmpRdWVyeS5ub2RlTmFtZSA9IG5vZGVOYW1lO1xuXG5cblxuXG4vLyBSZWdpc3RlciBhcyBhIG5hbWVkIEFNRCBtb2R1bGUsIHNpbmNlIGpRdWVyeSBjYW4gYmUgY29uY2F0ZW5hdGVkIHdpdGggb3RoZXJcbi8vIGZpbGVzIHRoYXQgbWF5IHVzZSBkZWZpbmUsIGJ1dCBub3QgdmlhIGEgcHJvcGVyIGNvbmNhdGVuYXRpb24gc2NyaXB0IHRoYXRcbi8vIHVuZGVyc3RhbmRzIGFub255bW91cyBBTUQgbW9kdWxlcy4gQSBuYW1lZCBBTUQgaXMgc2FmZXN0IGFuZCBtb3N0IHJvYnVzdFxuLy8gd2F5IHRvIHJlZ2lzdGVyLiBMb3dlcmNhc2UganF1ZXJ5IGlzIHVzZWQgYmVjYXVzZSBBTUQgbW9kdWxlIG5hbWVzIGFyZVxuLy8gZGVyaXZlZCBmcm9tIGZpbGUgbmFtZXMsIGFuZCBqUXVlcnkgaXMgbm9ybWFsbHkgZGVsaXZlcmVkIGluIGEgbG93ZXJjYXNlXG4vLyBmaWxlIG5hbWUuIERvIHRoaXMgYWZ0ZXIgY3JlYXRpbmcgdGhlIGdsb2JhbCBzbyB0aGF0IGlmIGFuIEFNRCBtb2R1bGUgd2FudHNcbi8vIHRvIGNhbGwgbm9Db25mbGljdCB0byBoaWRlIHRoaXMgdmVyc2lvbiBvZiBqUXVlcnksIGl0IHdpbGwgd29yay5cblxuLy8gTm90ZSB0aGF0IGZvciBtYXhpbXVtIHBvcnRhYmlsaXR5LCBsaWJyYXJpZXMgdGhhdCBhcmUgbm90IGpRdWVyeSBzaG91bGRcbi8vIGRlY2xhcmUgdGhlbXNlbHZlcyBhcyBhbm9ueW1vdXMgbW9kdWxlcywgYW5kIGF2b2lkIHNldHRpbmcgYSBnbG9iYWwgaWYgYW5cbi8vIEFNRCBsb2FkZXIgaXMgcHJlc2VudC4galF1ZXJ5IGlzIGEgc3BlY2lhbCBjYXNlLiBGb3IgbW9yZSBpbmZvcm1hdGlvbiwgc2VlXG4vLyBodHRwczovL2dpdGh1Yi5jb20vanJidXJrZS9yZXF1aXJlanMvd2lraS9VcGRhdGluZy1leGlzdGluZy1saWJyYXJpZXMjd2lraS1hbm9uXG5cbmlmICggdHlwZW9mIGRlZmluZSA9PT0gXCJmdW5jdGlvblwiICYmIGRlZmluZS5hbWQgKSB7XG5cdGRlZmluZSggXCJqcXVlcnlcIiwgW10sIGZ1bmN0aW9uKCkge1xuXHRcdHJldHVybiBqUXVlcnk7XG5cdH0gKTtcbn1cblxuXG5cblxudmFyXG5cblx0Ly8gTWFwIG92ZXIgalF1ZXJ5IGluIGNhc2Ugb2Ygb3ZlcndyaXRlXG5cdF9qUXVlcnkgPSB3aW5kb3cualF1ZXJ5LFxuXG5cdC8vIE1hcCBvdmVyIHRoZSAkIGluIGNhc2Ugb2Ygb3ZlcndyaXRlXG5cdF8kID0gd2luZG93LiQ7XG5cbmpRdWVyeS5ub0NvbmZsaWN0ID0gZnVuY3Rpb24oIGRlZXAgKSB7XG5cdGlmICggd2luZG93LiQgPT09IGpRdWVyeSApIHtcblx0XHR3aW5kb3cuJCA9IF8kO1xuXHR9XG5cblx0aWYgKCBkZWVwICYmIHdpbmRvdy5qUXVlcnkgPT09IGpRdWVyeSApIHtcblx0XHR3aW5kb3cualF1ZXJ5ID0gX2pRdWVyeTtcblx0fVxuXG5cdHJldHVybiBqUXVlcnk7XG59O1xuXG4vLyBFeHBvc2UgalF1ZXJ5IGFuZCAkIGlkZW50aWZpZXJzLCBldmVuIGluIEFNRFxuLy8gKCM3MTAyI2NvbW1lbnQ6MTAsIGh0dHBzOi8vZ2l0aHViLmNvbS9qcXVlcnkvanF1ZXJ5L3B1bGwvNTU3KVxuLy8gYW5kIENvbW1vbkpTIGZvciBicm93c2VyIGVtdWxhdG9ycyAoIzEzNTY2KVxuaWYgKCAhbm9HbG9iYWwgKSB7XG5cdHdpbmRvdy5qUXVlcnkgPSB3aW5kb3cuJCA9IGpRdWVyeTtcbn1cblxuXG5cblxucmV0dXJuIGpRdWVyeTtcbn0gKTtcblxuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIC4vbm9kZV9tb2R1bGVzL2pxdWVyeS9kaXN0L2pxdWVyeS5qc1xuLy8gbW9kdWxlIGlkID0gM1xuLy8gbW9kdWxlIGNodW5rcyA9IDAiLCJ2YXIgZztcclxuXHJcbi8vIFRoaXMgd29ya3MgaW4gbm9uLXN0cmljdCBtb2RlXHJcbmcgPSAoZnVuY3Rpb24oKSB7XHJcblx0cmV0dXJuIHRoaXM7XHJcbn0pKCk7XHJcblxyXG50cnkge1xyXG5cdC8vIFRoaXMgd29ya3MgaWYgZXZhbCBpcyBhbGxvd2VkIChzZWUgQ1NQKVxyXG5cdGcgPSBnIHx8IEZ1bmN0aW9uKFwicmV0dXJuIHRoaXNcIikoKSB8fCAoMSxldmFsKShcInRoaXNcIik7XHJcbn0gY2F0Y2goZSkge1xyXG5cdC8vIFRoaXMgd29ya3MgaWYgdGhlIHdpbmRvdyByZWZlcmVuY2UgaXMgYXZhaWxhYmxlXHJcblx0aWYodHlwZW9mIHdpbmRvdyA9PT0gXCJvYmplY3RcIilcclxuXHRcdGcgPSB3aW5kb3c7XHJcbn1cclxuXHJcbi8vIGcgY2FuIHN0aWxsIGJlIHVuZGVmaW5lZCwgYnV0IG5vdGhpbmcgdG8gZG8gYWJvdXQgaXQuLi5cclxuLy8gV2UgcmV0dXJuIHVuZGVmaW5lZCwgaW5zdGVhZCBvZiBub3RoaW5nIGhlcmUsIHNvIGl0J3NcclxuLy8gZWFzaWVyIHRvIGhhbmRsZSB0aGlzIGNhc2UuIGlmKCFnbG9iYWwpIHsgLi4ufVxyXG5cclxubW9kdWxlLmV4cG9ydHMgPSBnO1xyXG5cblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyAod2VicGFjaykvYnVpbGRpbi9nbG9iYWwuanNcbi8vIG1vZHVsZSBpZCA9IDRcbi8vIG1vZHVsZSBjaHVua3MgPSAwIiwiXG4vKipcbiAqIEZpcnN0IHdlIHdpbGwgbG9hZCBhbGwgb2YgdGhpcyBwcm9qZWN0J3MgSmF2YVNjcmlwdCBkZXBlbmRlbmNpZXMgd2hpY2hcbiAqIGluY2x1ZGUgVnVlIGFuZCBWdWUgUmVzb3VyY2UuIFRoaXMgZ2l2ZXMgYSBncmVhdCBzdGFydGluZyBwb2ludCBmb3JcbiAqIGJ1aWxkaW5nIHJvYnVzdCwgcG93ZXJmdWwgd2ViIGFwcGxpY2F0aW9ucyB1c2luZyBWdWUgYW5kIExhcmF2ZWwuXG4gKi9cbnJlcXVpcmUoJy4uLy4uLy4uL25vZGVfbW9kdWxlcy9qcXVlcnktdWktYnVuZGxlL2pxdWVyeS11aS5taW4uanMnKTtcbnJlcXVpcmUoJy4vYm9vdHN0cmFwJyk7XG5cbi8qKlxuICogTmV4dCwgd2Ugd2lsbCBjcmVhdGUgYSBmcmVzaCBWdWUgYXBwbGljYXRpb24gaW5zdGFuY2UgYW5kIGF0dGFjaCBpdCB0b1xuICogdGhlIHBhZ2UuIFRoZW4sIHlvdSBtYXkgYmVnaW4gYWRkaW5nIGNvbXBvbmVudHMgdG8gdGhpcyBhcHBsaWNhdGlvblxuICogb3IgY3VzdG9taXplIHRoZSBKYXZhU2NyaXB0IHNjYWZmb2xkaW5nIHRvIGZpdCB5b3VyIHVuaXF1ZSBuZWVkcy5cbiAqL1xuVnVlLmNvbXBvbmVudChcbiAgICAncGFzc3BvcnQtY2xpZW50cycsXG4gICAgcmVxdWlyZSgnLi9jb21wb25lbnRzL3Bhc3Nwb3J0L0NsaWVudHMudnVlJylcbik7XG5cblZ1ZS5jb21wb25lbnQoXG4gICAgJ3Bhc3Nwb3J0LWF1dGhvcml6ZWQtY2xpZW50cycsXG4gICAgcmVxdWlyZSgnLi9jb21wb25lbnRzL3Bhc3Nwb3J0L0F1dGhvcml6ZWRDbGllbnRzLnZ1ZScpXG4pO1xuXG5WdWUuY29tcG9uZW50KFxuICAgICdwYXNzcG9ydC1wZXJzb25hbC1hY2Nlc3MtdG9rZW5zJyxcbiAgICByZXF1aXJlKCcuL2NvbXBvbmVudHMvcGFzc3BvcnQvUGVyc29uYWxBY2Nlc3NUb2tlbnMudnVlJylcbik7XG5cblZ1ZS5jb21wb25lbnQoXG4gICAgJ2ltcG9ydGVyJyxcbiAgICByZXF1aXJlKCcuL2NvbXBvbmVudHMvaW1wb3J0ZXIvaW1wb3J0ZXIudnVlJylcbik7XG5cbi8vIENvbW1lbnRlZCBvdXQgY3VycmVudGx5IHRvIGF2b2lkIHRyeWluZyB0byBsb2FkIHZ1ZSBldmVyeXdoZXJlLlxuLy8gY29uc3QgYXBwID0gbmV3IFZ1ZSh7XG4vLyAgICAgZWw6ICcjYXBwJ1xuLy8gfSk7XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9yZXNvdXJjZXMvYXNzZXRzL2pzL3Z1ZS5qcyIsIi8qISBqUXVlcnkgVUkgLSB2MS4xMi4xIC0gMjAxNy0wMy0xOVxuKiBodHRwOi8vanF1ZXJ5dWkuY29tXG4qIEluY2x1ZGVzOiB3aWRnZXQuanMsIHBvc2l0aW9uLmpzLCBkYXRhLmpzLCBkaXNhYmxlLXNlbGVjdGlvbi5qcywgZm9jdXNhYmxlLmpzLCBmb3JtLXJlc2V0LW1peGluLmpzLCBqcXVlcnktMS03LmpzLCBrZXljb2RlLmpzLCBsYWJlbHMuanMsIHNjcm9sbC1wYXJlbnQuanMsIHRhYmJhYmxlLmpzLCB1bmlxdWUtaWQuanMsIHdpZGdldHMvZHJhZ2dhYmxlLmpzLCB3aWRnZXRzL2Ryb3BwYWJsZS5qcywgd2lkZ2V0cy9yZXNpemFibGUuanMsIHdpZGdldHMvc2VsZWN0YWJsZS5qcywgd2lkZ2V0cy9zb3J0YWJsZS5qcywgd2lkZ2V0cy9hY2NvcmRpb24uanMsIHdpZGdldHMvYXV0b2NvbXBsZXRlLmpzLCB3aWRnZXRzL2J1dHRvbi5qcywgd2lkZ2V0cy9jaGVja2JveHJhZGlvLmpzLCB3aWRnZXRzL2NvbnRyb2xncm91cC5qcywgd2lkZ2V0cy9kYXRlcGlja2VyLmpzLCB3aWRnZXRzL2RpYWxvZy5qcywgd2lkZ2V0cy9tZW51LmpzLCB3aWRnZXRzL21vdXNlLmpzLCB3aWRnZXRzL3Byb2dyZXNzYmFyLmpzLCB3aWRnZXRzL3NlbGVjdG1lbnUuanMsIHdpZGdldHMvc2xpZGVyLmpzLCB3aWRnZXRzL3NwaW5uZXIuanMsIHdpZGdldHMvdGFicy5qcywgd2lkZ2V0cy90b29sdGlwLmpzLCBlZmZlY3QuanMsIGVmZmVjdHMvZWZmZWN0LWJsaW5kLmpzLCBlZmZlY3RzL2VmZmVjdC1ib3VuY2UuanMsIGVmZmVjdHMvZWZmZWN0LWNsaXAuanMsIGVmZmVjdHMvZWZmZWN0LWRyb3AuanMsIGVmZmVjdHMvZWZmZWN0LWV4cGxvZGUuanMsIGVmZmVjdHMvZWZmZWN0LWZhZGUuanMsIGVmZmVjdHMvZWZmZWN0LWZvbGQuanMsIGVmZmVjdHMvZWZmZWN0LWhpZ2hsaWdodC5qcywgZWZmZWN0cy9lZmZlY3QtcHVmZi5qcywgZWZmZWN0cy9lZmZlY3QtcHVsc2F0ZS5qcywgZWZmZWN0cy9lZmZlY3Qtc2NhbGUuanMsIGVmZmVjdHMvZWZmZWN0LXNoYWtlLmpzLCBlZmZlY3RzL2VmZmVjdC1zaXplLmpzLCBlZmZlY3RzL2VmZmVjdC1zbGlkZS5qcywgZWZmZWN0cy9lZmZlY3QtdHJhbnNmZXIuanNcbiogQ29weXJpZ2h0IGpRdWVyeSBGb3VuZGF0aW9uIGFuZCBvdGhlciBjb250cmlidXRvcnM7IExpY2Vuc2VkIE1JVCAqL1xuXG4oZnVuY3Rpb24odCl7XCJmdW5jdGlvblwiPT10eXBlb2YgZGVmaW5lJiZkZWZpbmUuYW1kP2RlZmluZShbXCJqcXVlcnlcIl0sdCk6dChqUXVlcnkpfSkoZnVuY3Rpb24odCl7ZnVuY3Rpb24gZSh0KXtmb3IodmFyIGU9dC5jc3MoXCJ2aXNpYmlsaXR5XCIpO1wiaW5oZXJpdFwiPT09ZTspdD10LnBhcmVudCgpLGU9dC5jc3MoXCJ2aXNpYmlsaXR5XCIpO3JldHVyblwiaGlkZGVuXCIhPT1lfWZ1bmN0aW9uIGkodCl7Zm9yKHZhciBlLGk7dC5sZW5ndGgmJnRbMF0hPT1kb2N1bWVudDspe2lmKGU9dC5jc3MoXCJwb3NpdGlvblwiKSwoXCJhYnNvbHV0ZVwiPT09ZXx8XCJyZWxhdGl2ZVwiPT09ZXx8XCJmaXhlZFwiPT09ZSkmJihpPXBhcnNlSW50KHQuY3NzKFwiekluZGV4XCIpLDEwKSwhaXNOYU4oaSkmJjAhPT1pKSlyZXR1cm4gaTt0PXQucGFyZW50KCl9cmV0dXJuIDB9ZnVuY3Rpb24gcygpe3RoaXMuX2N1ckluc3Q9bnVsbCx0aGlzLl9rZXlFdmVudD0hMSx0aGlzLl9kaXNhYmxlZElucHV0cz1bXSx0aGlzLl9kYXRlcGlja2VyU2hvd2luZz0hMSx0aGlzLl9pbkRpYWxvZz0hMSx0aGlzLl9tYWluRGl2SWQ9XCJ1aS1kYXRlcGlja2VyLWRpdlwiLHRoaXMuX2lubGluZUNsYXNzPVwidWktZGF0ZXBpY2tlci1pbmxpbmVcIix0aGlzLl9hcHBlbmRDbGFzcz1cInVpLWRhdGVwaWNrZXItYXBwZW5kXCIsdGhpcy5fdHJpZ2dlckNsYXNzPVwidWktZGF0ZXBpY2tlci10cmlnZ2VyXCIsdGhpcy5fZGlhbG9nQ2xhc3M9XCJ1aS1kYXRlcGlja2VyLWRpYWxvZ1wiLHRoaXMuX2Rpc2FibGVDbGFzcz1cInVpLWRhdGVwaWNrZXItZGlzYWJsZWRcIix0aGlzLl91bnNlbGVjdGFibGVDbGFzcz1cInVpLWRhdGVwaWNrZXItdW5zZWxlY3RhYmxlXCIsdGhpcy5fY3VycmVudENsYXNzPVwidWktZGF0ZXBpY2tlci1jdXJyZW50LWRheVwiLHRoaXMuX2RheU92ZXJDbGFzcz1cInVpLWRhdGVwaWNrZXItZGF5cy1jZWxsLW92ZXJcIix0aGlzLnJlZ2lvbmFsPVtdLHRoaXMucmVnaW9uYWxbXCJcIl09e2Nsb3NlVGV4dDpcIkRvbmVcIixwcmV2VGV4dDpcIlByZXZcIixuZXh0VGV4dDpcIk5leHRcIixjdXJyZW50VGV4dDpcIlRvZGF5XCIsbW9udGhOYW1lczpbXCJKYW51YXJ5XCIsXCJGZWJydWFyeVwiLFwiTWFyY2hcIixcIkFwcmlsXCIsXCJNYXlcIixcIkp1bmVcIixcIkp1bHlcIixcIkF1Z3VzdFwiLFwiU2VwdGVtYmVyXCIsXCJPY3RvYmVyXCIsXCJOb3ZlbWJlclwiLFwiRGVjZW1iZXJcIl0sbW9udGhOYW1lc1Nob3J0OltcIkphblwiLFwiRmViXCIsXCJNYXJcIixcIkFwclwiLFwiTWF5XCIsXCJKdW5cIixcIkp1bFwiLFwiQXVnXCIsXCJTZXBcIixcIk9jdFwiLFwiTm92XCIsXCJEZWNcIl0sZGF5TmFtZXM6W1wiU3VuZGF5XCIsXCJNb25kYXlcIixcIlR1ZXNkYXlcIixcIldlZG5lc2RheVwiLFwiVGh1cnNkYXlcIixcIkZyaWRheVwiLFwiU2F0dXJkYXlcIl0sZGF5TmFtZXNTaG9ydDpbXCJTdW5cIixcIk1vblwiLFwiVHVlXCIsXCJXZWRcIixcIlRodVwiLFwiRnJpXCIsXCJTYXRcIl0sZGF5TmFtZXNNaW46W1wiU3VcIixcIk1vXCIsXCJUdVwiLFwiV2VcIixcIlRoXCIsXCJGclwiLFwiU2FcIl0sd2Vla0hlYWRlcjpcIldrXCIsZGF0ZUZvcm1hdDpcIm1tL2RkL3l5XCIsZmlyc3REYXk6MCxpc1JUTDohMSxzaG93TW9udGhBZnRlclllYXI6ITEseWVhclN1ZmZpeDpcIlwifSx0aGlzLl9kZWZhdWx0cz17c2hvd09uOlwiZm9jdXNcIixzaG93QW5pbTpcImZhZGVJblwiLHNob3dPcHRpb25zOnt9LGRlZmF1bHREYXRlOm51bGwsYXBwZW5kVGV4dDpcIlwiLGJ1dHRvblRleHQ6XCIuLi5cIixidXR0b25JbWFnZTpcIlwiLGJ1dHRvbkltYWdlT25seTohMSxoaWRlSWZOb1ByZXZOZXh0OiExLG5hdmlnYXRpb25Bc0RhdGVGb3JtYXQ6ITEsZ290b0N1cnJlbnQ6ITEsY2hhbmdlTW9udGg6ITEsY2hhbmdlWWVhcjohMSx5ZWFyUmFuZ2U6XCJjLTEwOmMrMTBcIixzaG93T3RoZXJNb250aHM6ITEsc2VsZWN0T3RoZXJNb250aHM6ITEsc2hvd1dlZWs6ITEsY2FsY3VsYXRlV2Vlazp0aGlzLmlzbzg2MDFXZWVrLHNob3J0WWVhckN1dG9mZjpcIisxMFwiLG1pbkRhdGU6bnVsbCxtYXhEYXRlOm51bGwsZHVyYXRpb246XCJmYXN0XCIsYmVmb3JlU2hvd0RheTpudWxsLGJlZm9yZVNob3c6bnVsbCxvblNlbGVjdDpudWxsLG9uQ2hhbmdlTW9udGhZZWFyOm51bGwsb25DbG9zZTpudWxsLG51bWJlck9mTW9udGhzOjEsc2hvd0N1cnJlbnRBdFBvczowLHN0ZXBNb250aHM6MSxzdGVwQmlnTW9udGhzOjEyLGFsdEZpZWxkOlwiXCIsYWx0Rm9ybWF0OlwiXCIsY29uc3RyYWluSW5wdXQ6ITAsc2hvd0J1dHRvblBhbmVsOiExLGF1dG9TaXplOiExLGRpc2FibGVkOiExfSx0LmV4dGVuZCh0aGlzLl9kZWZhdWx0cyx0aGlzLnJlZ2lvbmFsW1wiXCJdKSx0aGlzLnJlZ2lvbmFsLmVuPXQuZXh0ZW5kKCEwLHt9LHRoaXMucmVnaW9uYWxbXCJcIl0pLHRoaXMucmVnaW9uYWxbXCJlbi1VU1wiXT10LmV4dGVuZCghMCx7fSx0aGlzLnJlZ2lvbmFsLmVuKSx0aGlzLmRwRGl2PW4odChcIjxkaXYgaWQ9J1wiK3RoaXMuX21haW5EaXZJZCtcIicgY2xhc3M9J3VpLWRhdGVwaWNrZXIgdWktd2lkZ2V0IHVpLXdpZGdldC1jb250ZW50IHVpLWhlbHBlci1jbGVhcmZpeCB1aS1jb3JuZXItYWxsJz48L2Rpdj5cIikpfWZ1bmN0aW9uIG4oZSl7dmFyIGk9XCJidXR0b24sIC51aS1kYXRlcGlja2VyLXByZXYsIC51aS1kYXRlcGlja2VyLW5leHQsIC51aS1kYXRlcGlja2VyLWNhbGVuZGFyIHRkIGFcIjtyZXR1cm4gZS5vbihcIm1vdXNlb3V0XCIsaSxmdW5jdGlvbigpe3QodGhpcykucmVtb3ZlQ2xhc3MoXCJ1aS1zdGF0ZS1ob3ZlclwiKSwtMSE9PXRoaXMuY2xhc3NOYW1lLmluZGV4T2YoXCJ1aS1kYXRlcGlja2VyLXByZXZcIikmJnQodGhpcykucmVtb3ZlQ2xhc3MoXCJ1aS1kYXRlcGlja2VyLXByZXYtaG92ZXJcIiksLTEhPT10aGlzLmNsYXNzTmFtZS5pbmRleE9mKFwidWktZGF0ZXBpY2tlci1uZXh0XCIpJiZ0KHRoaXMpLnJlbW92ZUNsYXNzKFwidWktZGF0ZXBpY2tlci1uZXh0LWhvdmVyXCIpfSkub24oXCJtb3VzZW92ZXJcIixpLG8pfWZ1bmN0aW9uIG8oKXt0LmRhdGVwaWNrZXIuX2lzRGlzYWJsZWREYXRlcGlja2VyKHAuaW5saW5lP3AuZHBEaXYucGFyZW50KClbMF06cC5pbnB1dFswXSl8fCh0KHRoaXMpLnBhcmVudHMoXCIudWktZGF0ZXBpY2tlci1jYWxlbmRhclwiKS5maW5kKFwiYVwiKS5yZW1vdmVDbGFzcyhcInVpLXN0YXRlLWhvdmVyXCIpLHQodGhpcykuYWRkQ2xhc3MoXCJ1aS1zdGF0ZS1ob3ZlclwiKSwtMSE9PXRoaXMuY2xhc3NOYW1lLmluZGV4T2YoXCJ1aS1kYXRlcGlja2VyLXByZXZcIikmJnQodGhpcykuYWRkQ2xhc3MoXCJ1aS1kYXRlcGlja2VyLXByZXYtaG92ZXJcIiksLTEhPT10aGlzLmNsYXNzTmFtZS5pbmRleE9mKFwidWktZGF0ZXBpY2tlci1uZXh0XCIpJiZ0KHRoaXMpLmFkZENsYXNzKFwidWktZGF0ZXBpY2tlci1uZXh0LWhvdmVyXCIpKX1mdW5jdGlvbiBhKGUsaSl7dC5leHRlbmQoZSxpKTtmb3IodmFyIHMgaW4gaSludWxsPT1pW3NdJiYoZVtzXT1pW3NdKTtyZXR1cm4gZX1mdW5jdGlvbiByKHQpe3JldHVybiBmdW5jdGlvbigpe3ZhciBlPXRoaXMuZWxlbWVudC52YWwoKTt0LmFwcGx5KHRoaXMsYXJndW1lbnRzKSx0aGlzLl9yZWZyZXNoKCksZSE9PXRoaXMuZWxlbWVudC52YWwoKSYmdGhpcy5fdHJpZ2dlcihcImNoYW5nZVwiKX19dC51aT10LnVpfHx7fSx0LnVpLnZlcnNpb249XCIxLjEyLjFcIjt2YXIgaD0wLGw9QXJyYXkucHJvdG90eXBlLnNsaWNlO3QuY2xlYW5EYXRhPWZ1bmN0aW9uKGUpe3JldHVybiBmdW5jdGlvbihpKXt2YXIgcyxuLG87Zm9yKG89MDtudWxsIT0obj1pW29dKTtvKyspdHJ5e3M9dC5fZGF0YShuLFwiZXZlbnRzXCIpLHMmJnMucmVtb3ZlJiZ0KG4pLnRyaWdnZXJIYW5kbGVyKFwicmVtb3ZlXCIpfWNhdGNoKGEpe31lKGkpfX0odC5jbGVhbkRhdGEpLHQud2lkZ2V0PWZ1bmN0aW9uKGUsaSxzKXt2YXIgbixvLGEscj17fSxoPWUuc3BsaXQoXCIuXCIpWzBdO2U9ZS5zcGxpdChcIi5cIilbMV07dmFyIGw9aCtcIi1cIitlO3JldHVybiBzfHwocz1pLGk9dC5XaWRnZXQpLHQuaXNBcnJheShzKSYmKHM9dC5leHRlbmQuYXBwbHkobnVsbCxbe31dLmNvbmNhdChzKSkpLHQuZXhwcltcIjpcIl1bbC50b0xvd2VyQ2FzZSgpXT1mdW5jdGlvbihlKXtyZXR1cm4hIXQuZGF0YShlLGwpfSx0W2hdPXRbaF18fHt9LG49dFtoXVtlXSxvPXRbaF1bZV09ZnVuY3Rpb24odCxlKXtyZXR1cm4gdGhpcy5fY3JlYXRlV2lkZ2V0Pyhhcmd1bWVudHMubGVuZ3RoJiZ0aGlzLl9jcmVhdGVXaWRnZXQodCxlKSx2b2lkIDApOm5ldyBvKHQsZSl9LHQuZXh0ZW5kKG8sbix7dmVyc2lvbjpzLnZlcnNpb24sX3Byb3RvOnQuZXh0ZW5kKHt9LHMpLF9jaGlsZENvbnN0cnVjdG9yczpbXX0pLGE9bmV3IGksYS5vcHRpb25zPXQud2lkZ2V0LmV4dGVuZCh7fSxhLm9wdGlvbnMpLHQuZWFjaChzLGZ1bmN0aW9uKGUscyl7cmV0dXJuIHQuaXNGdW5jdGlvbihzKT8ocltlXT1mdW5jdGlvbigpe2Z1bmN0aW9uIHQoKXtyZXR1cm4gaS5wcm90b3R5cGVbZV0uYXBwbHkodGhpcyxhcmd1bWVudHMpfWZ1bmN0aW9uIG4odCl7cmV0dXJuIGkucHJvdG90eXBlW2VdLmFwcGx5KHRoaXMsdCl9cmV0dXJuIGZ1bmN0aW9uKCl7dmFyIGUsaT10aGlzLl9zdXBlcixvPXRoaXMuX3N1cGVyQXBwbHk7cmV0dXJuIHRoaXMuX3N1cGVyPXQsdGhpcy5fc3VwZXJBcHBseT1uLGU9cy5hcHBseSh0aGlzLGFyZ3VtZW50cyksdGhpcy5fc3VwZXI9aSx0aGlzLl9zdXBlckFwcGx5PW8sZX19KCksdm9pZCAwKToocltlXT1zLHZvaWQgMCl9KSxvLnByb3RvdHlwZT10LndpZGdldC5leHRlbmQoYSx7d2lkZ2V0RXZlbnRQcmVmaXg6bj9hLndpZGdldEV2ZW50UHJlZml4fHxlOmV9LHIse2NvbnN0cnVjdG9yOm8sbmFtZXNwYWNlOmgsd2lkZ2V0TmFtZTplLHdpZGdldEZ1bGxOYW1lOmx9KSxuPyh0LmVhY2gobi5fY2hpbGRDb25zdHJ1Y3RvcnMsZnVuY3Rpb24oZSxpKXt2YXIgcz1pLnByb3RvdHlwZTt0LndpZGdldChzLm5hbWVzcGFjZStcIi5cIitzLndpZGdldE5hbWUsbyxpLl9wcm90byl9KSxkZWxldGUgbi5fY2hpbGRDb25zdHJ1Y3RvcnMpOmkuX2NoaWxkQ29uc3RydWN0b3JzLnB1c2gobyksdC53aWRnZXQuYnJpZGdlKGUsbyksb30sdC53aWRnZXQuZXh0ZW5kPWZ1bmN0aW9uKGUpe2Zvcih2YXIgaSxzLG49bC5jYWxsKGFyZ3VtZW50cywxKSxvPTAsYT1uLmxlbmd0aDthPm87bysrKWZvcihpIGluIG5bb10pcz1uW29dW2ldLG5bb10uaGFzT3duUHJvcGVydHkoaSkmJnZvaWQgMCE9PXMmJihlW2ldPXQuaXNQbGFpbk9iamVjdChzKT90LmlzUGxhaW5PYmplY3QoZVtpXSk/dC53aWRnZXQuZXh0ZW5kKHt9LGVbaV0scyk6dC53aWRnZXQuZXh0ZW5kKHt9LHMpOnMpO3JldHVybiBlfSx0LndpZGdldC5icmlkZ2U9ZnVuY3Rpb24oZSxpKXt2YXIgcz1pLnByb3RvdHlwZS53aWRnZXRGdWxsTmFtZXx8ZTt0LmZuW2VdPWZ1bmN0aW9uKG4pe3ZhciBvPVwic3RyaW5nXCI9PXR5cGVvZiBuLGE9bC5jYWxsKGFyZ3VtZW50cywxKSxyPXRoaXM7cmV0dXJuIG8/dGhpcy5sZW5ndGh8fFwiaW5zdGFuY2VcIiE9PW4/dGhpcy5lYWNoKGZ1bmN0aW9uKCl7dmFyIGksbz10LmRhdGEodGhpcyxzKTtyZXR1cm5cImluc3RhbmNlXCI9PT1uPyhyPW8sITEpOm8/dC5pc0Z1bmN0aW9uKG9bbl0pJiZcIl9cIiE9PW4uY2hhckF0KDApPyhpPW9bbl0uYXBwbHkobyxhKSxpIT09byYmdm9pZCAwIT09aT8ocj1pJiZpLmpxdWVyeT9yLnB1c2hTdGFjayhpLmdldCgpKTppLCExKTp2b2lkIDApOnQuZXJyb3IoXCJubyBzdWNoIG1ldGhvZCAnXCIrbitcIicgZm9yIFwiK2UrXCIgd2lkZ2V0IGluc3RhbmNlXCIpOnQuZXJyb3IoXCJjYW5ub3QgY2FsbCBtZXRob2RzIG9uIFwiK2UrXCIgcHJpb3IgdG8gaW5pdGlhbGl6YXRpb247IFwiK1wiYXR0ZW1wdGVkIHRvIGNhbGwgbWV0aG9kICdcIituK1wiJ1wiKX0pOnI9dm9pZCAwOihhLmxlbmd0aCYmKG49dC53aWRnZXQuZXh0ZW5kLmFwcGx5KG51bGwsW25dLmNvbmNhdChhKSkpLHRoaXMuZWFjaChmdW5jdGlvbigpe3ZhciBlPXQuZGF0YSh0aGlzLHMpO2U/KGUub3B0aW9uKG58fHt9KSxlLl9pbml0JiZlLl9pbml0KCkpOnQuZGF0YSh0aGlzLHMsbmV3IGkobix0aGlzKSl9KSkscn19LHQuV2lkZ2V0PWZ1bmN0aW9uKCl7fSx0LldpZGdldC5fY2hpbGRDb25zdHJ1Y3RvcnM9W10sdC5XaWRnZXQucHJvdG90eXBlPXt3aWRnZXROYW1lOlwid2lkZ2V0XCIsd2lkZ2V0RXZlbnRQcmVmaXg6XCJcIixkZWZhdWx0RWxlbWVudDpcIjxkaXY+XCIsb3B0aW9uczp7Y2xhc3Nlczp7fSxkaXNhYmxlZDohMSxjcmVhdGU6bnVsbH0sX2NyZWF0ZVdpZGdldDpmdW5jdGlvbihlLGkpe2k9dChpfHx0aGlzLmRlZmF1bHRFbGVtZW50fHx0aGlzKVswXSx0aGlzLmVsZW1lbnQ9dChpKSx0aGlzLnV1aWQ9aCsrLHRoaXMuZXZlbnROYW1lc3BhY2U9XCIuXCIrdGhpcy53aWRnZXROYW1lK3RoaXMudXVpZCx0aGlzLmJpbmRpbmdzPXQoKSx0aGlzLmhvdmVyYWJsZT10KCksdGhpcy5mb2N1c2FibGU9dCgpLHRoaXMuY2xhc3Nlc0VsZW1lbnRMb29rdXA9e30saSE9PXRoaXMmJih0LmRhdGEoaSx0aGlzLndpZGdldEZ1bGxOYW1lLHRoaXMpLHRoaXMuX29uKCEwLHRoaXMuZWxlbWVudCx7cmVtb3ZlOmZ1bmN0aW9uKHQpe3QudGFyZ2V0PT09aSYmdGhpcy5kZXN0cm95KCl9fSksdGhpcy5kb2N1bWVudD10KGkuc3R5bGU/aS5vd25lckRvY3VtZW50OmkuZG9jdW1lbnR8fGkpLHRoaXMud2luZG93PXQodGhpcy5kb2N1bWVudFswXS5kZWZhdWx0Vmlld3x8dGhpcy5kb2N1bWVudFswXS5wYXJlbnRXaW5kb3cpKSx0aGlzLm9wdGlvbnM9dC53aWRnZXQuZXh0ZW5kKHt9LHRoaXMub3B0aW9ucyx0aGlzLl9nZXRDcmVhdGVPcHRpb25zKCksZSksdGhpcy5fY3JlYXRlKCksdGhpcy5vcHRpb25zLmRpc2FibGVkJiZ0aGlzLl9zZXRPcHRpb25EaXNhYmxlZCh0aGlzLm9wdGlvbnMuZGlzYWJsZWQpLHRoaXMuX3RyaWdnZXIoXCJjcmVhdGVcIixudWxsLHRoaXMuX2dldENyZWF0ZUV2ZW50RGF0YSgpKSx0aGlzLl9pbml0KCl9LF9nZXRDcmVhdGVPcHRpb25zOmZ1bmN0aW9uKCl7cmV0dXJue319LF9nZXRDcmVhdGVFdmVudERhdGE6dC5ub29wLF9jcmVhdGU6dC5ub29wLF9pbml0OnQubm9vcCxkZXN0cm95OmZ1bmN0aW9uKCl7dmFyIGU9dGhpczt0aGlzLl9kZXN0cm95KCksdC5lYWNoKHRoaXMuY2xhc3Nlc0VsZW1lbnRMb29rdXAsZnVuY3Rpb24odCxpKXtlLl9yZW1vdmVDbGFzcyhpLHQpfSksdGhpcy5lbGVtZW50Lm9mZih0aGlzLmV2ZW50TmFtZXNwYWNlKS5yZW1vdmVEYXRhKHRoaXMud2lkZ2V0RnVsbE5hbWUpLHRoaXMud2lkZ2V0KCkub2ZmKHRoaXMuZXZlbnROYW1lc3BhY2UpLnJlbW92ZUF0dHIoXCJhcmlhLWRpc2FibGVkXCIpLHRoaXMuYmluZGluZ3Mub2ZmKHRoaXMuZXZlbnROYW1lc3BhY2UpfSxfZGVzdHJveTp0Lm5vb3Asd2lkZ2V0OmZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMuZWxlbWVudH0sb3B0aW9uOmZ1bmN0aW9uKGUsaSl7dmFyIHMsbixvLGE9ZTtpZigwPT09YXJndW1lbnRzLmxlbmd0aClyZXR1cm4gdC53aWRnZXQuZXh0ZW5kKHt9LHRoaXMub3B0aW9ucyk7aWYoXCJzdHJpbmdcIj09dHlwZW9mIGUpaWYoYT17fSxzPWUuc3BsaXQoXCIuXCIpLGU9cy5zaGlmdCgpLHMubGVuZ3RoKXtmb3Iobj1hW2VdPXQud2lkZ2V0LmV4dGVuZCh7fSx0aGlzLm9wdGlvbnNbZV0pLG89MDtzLmxlbmd0aC0xPm87bysrKW5bc1tvXV09bltzW29dXXx8e30sbj1uW3Nbb11dO2lmKGU9cy5wb3AoKSwxPT09YXJndW1lbnRzLmxlbmd0aClyZXR1cm4gdm9pZCAwPT09bltlXT9udWxsOm5bZV07bltlXT1pfWVsc2V7aWYoMT09PWFyZ3VtZW50cy5sZW5ndGgpcmV0dXJuIHZvaWQgMD09PXRoaXMub3B0aW9uc1tlXT9udWxsOnRoaXMub3B0aW9uc1tlXTthW2VdPWl9cmV0dXJuIHRoaXMuX3NldE9wdGlvbnMoYSksdGhpc30sX3NldE9wdGlvbnM6ZnVuY3Rpb24odCl7dmFyIGU7Zm9yKGUgaW4gdCl0aGlzLl9zZXRPcHRpb24oZSx0W2VdKTtyZXR1cm4gdGhpc30sX3NldE9wdGlvbjpmdW5jdGlvbih0LGUpe3JldHVyblwiY2xhc3Nlc1wiPT09dCYmdGhpcy5fc2V0T3B0aW9uQ2xhc3NlcyhlKSx0aGlzLm9wdGlvbnNbdF09ZSxcImRpc2FibGVkXCI9PT10JiZ0aGlzLl9zZXRPcHRpb25EaXNhYmxlZChlKSx0aGlzfSxfc2V0T3B0aW9uQ2xhc3NlczpmdW5jdGlvbihlKXt2YXIgaSxzLG47Zm9yKGkgaW4gZSluPXRoaXMuY2xhc3Nlc0VsZW1lbnRMb29rdXBbaV0sZVtpXSE9PXRoaXMub3B0aW9ucy5jbGFzc2VzW2ldJiZuJiZuLmxlbmd0aCYmKHM9dChuLmdldCgpKSx0aGlzLl9yZW1vdmVDbGFzcyhuLGkpLHMuYWRkQ2xhc3ModGhpcy5fY2xhc3Nlcyh7ZWxlbWVudDpzLGtleXM6aSxjbGFzc2VzOmUsYWRkOiEwfSkpKX0sX3NldE9wdGlvbkRpc2FibGVkOmZ1bmN0aW9uKHQpe3RoaXMuX3RvZ2dsZUNsYXNzKHRoaXMud2lkZ2V0KCksdGhpcy53aWRnZXRGdWxsTmFtZStcIi1kaXNhYmxlZFwiLG51bGwsISF0KSx0JiYodGhpcy5fcmVtb3ZlQ2xhc3ModGhpcy5ob3ZlcmFibGUsbnVsbCxcInVpLXN0YXRlLWhvdmVyXCIpLHRoaXMuX3JlbW92ZUNsYXNzKHRoaXMuZm9jdXNhYmxlLG51bGwsXCJ1aS1zdGF0ZS1mb2N1c1wiKSl9LGVuYWJsZTpmdW5jdGlvbigpe3JldHVybiB0aGlzLl9zZXRPcHRpb25zKHtkaXNhYmxlZDohMX0pfSxkaXNhYmxlOmZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMuX3NldE9wdGlvbnMoe2Rpc2FibGVkOiEwfSl9LF9jbGFzc2VzOmZ1bmN0aW9uKGUpe2Z1bmN0aW9uIGkoaSxvKXt2YXIgYSxyO2ZvcihyPTA7aS5sZW5ndGg+cjtyKyspYT1uLmNsYXNzZXNFbGVtZW50TG9va3VwW2lbcl1dfHx0KCksYT1lLmFkZD90KHQudW5pcXVlKGEuZ2V0KCkuY29uY2F0KGUuZWxlbWVudC5nZXQoKSkpKTp0KGEubm90KGUuZWxlbWVudCkuZ2V0KCkpLG4uY2xhc3Nlc0VsZW1lbnRMb29rdXBbaVtyXV09YSxzLnB1c2goaVtyXSksbyYmZS5jbGFzc2VzW2lbcl1dJiZzLnB1c2goZS5jbGFzc2VzW2lbcl1dKX12YXIgcz1bXSxuPXRoaXM7cmV0dXJuIGU9dC5leHRlbmQoe2VsZW1lbnQ6dGhpcy5lbGVtZW50LGNsYXNzZXM6dGhpcy5vcHRpb25zLmNsYXNzZXN8fHt9fSxlKSx0aGlzLl9vbihlLmVsZW1lbnQse3JlbW92ZTpcIl91bnRyYWNrQ2xhc3Nlc0VsZW1lbnRcIn0pLGUua2V5cyYmaShlLmtleXMubWF0Y2goL1xcUysvZyl8fFtdLCEwKSxlLmV4dHJhJiZpKGUuZXh0cmEubWF0Y2goL1xcUysvZyl8fFtdKSxzLmpvaW4oXCIgXCIpfSxfdW50cmFja0NsYXNzZXNFbGVtZW50OmZ1bmN0aW9uKGUpe3ZhciBpPXRoaXM7dC5lYWNoKGkuY2xhc3Nlc0VsZW1lbnRMb29rdXAsZnVuY3Rpb24ocyxuKXstMSE9PXQuaW5BcnJheShlLnRhcmdldCxuKSYmKGkuY2xhc3Nlc0VsZW1lbnRMb29rdXBbc109dChuLm5vdChlLnRhcmdldCkuZ2V0KCkpKX0pfSxfcmVtb3ZlQ2xhc3M6ZnVuY3Rpb24odCxlLGkpe3JldHVybiB0aGlzLl90b2dnbGVDbGFzcyh0LGUsaSwhMSl9LF9hZGRDbGFzczpmdW5jdGlvbih0LGUsaSl7cmV0dXJuIHRoaXMuX3RvZ2dsZUNsYXNzKHQsZSxpLCEwKX0sX3RvZ2dsZUNsYXNzOmZ1bmN0aW9uKHQsZSxpLHMpe3M9XCJib29sZWFuXCI9PXR5cGVvZiBzP3M6aTt2YXIgbj1cInN0cmluZ1wiPT10eXBlb2YgdHx8bnVsbD09PXQsbz17ZXh0cmE6bj9lOmksa2V5czpuP3Q6ZSxlbGVtZW50Om4/dGhpcy5lbGVtZW50OnQsYWRkOnN9O3JldHVybiBvLmVsZW1lbnQudG9nZ2xlQ2xhc3ModGhpcy5fY2xhc3NlcyhvKSxzKSx0aGlzfSxfb246ZnVuY3Rpb24oZSxpLHMpe3ZhciBuLG89dGhpcztcImJvb2xlYW5cIiE9dHlwZW9mIGUmJihzPWksaT1lLGU9ITEpLHM/KGk9bj10KGkpLHRoaXMuYmluZGluZ3M9dGhpcy5iaW5kaW5ncy5hZGQoaSkpOihzPWksaT10aGlzLmVsZW1lbnQsbj10aGlzLndpZGdldCgpKSx0LmVhY2gocyxmdW5jdGlvbihzLGEpe2Z1bmN0aW9uIHIoKXtyZXR1cm4gZXx8by5vcHRpb25zLmRpc2FibGVkIT09ITAmJiF0KHRoaXMpLmhhc0NsYXNzKFwidWktc3RhdGUtZGlzYWJsZWRcIik/KFwic3RyaW5nXCI9PXR5cGVvZiBhP29bYV06YSkuYXBwbHkobyxhcmd1bWVudHMpOnZvaWQgMH1cInN0cmluZ1wiIT10eXBlb2YgYSYmKHIuZ3VpZD1hLmd1aWQ9YS5ndWlkfHxyLmd1aWR8fHQuZ3VpZCsrKTt2YXIgaD1zLm1hdGNoKC9eKFtcXHc6LV0qKVxccyooLiopJC8pLGw9aFsxXStvLmV2ZW50TmFtZXNwYWNlLGM9aFsyXTtjP24ub24obCxjLHIpOmkub24obCxyKX0pfSxfb2ZmOmZ1bmN0aW9uKGUsaSl7aT0oaXx8XCJcIikuc3BsaXQoXCIgXCIpLmpvaW4odGhpcy5ldmVudE5hbWVzcGFjZStcIiBcIikrdGhpcy5ldmVudE5hbWVzcGFjZSxlLm9mZihpKS5vZmYoaSksdGhpcy5iaW5kaW5ncz10KHRoaXMuYmluZGluZ3Mubm90KGUpLmdldCgpKSx0aGlzLmZvY3VzYWJsZT10KHRoaXMuZm9jdXNhYmxlLm5vdChlKS5nZXQoKSksdGhpcy5ob3ZlcmFibGU9dCh0aGlzLmhvdmVyYWJsZS5ub3QoZSkuZ2V0KCkpfSxfZGVsYXk6ZnVuY3Rpb24odCxlKXtmdW5jdGlvbiBpKCl7cmV0dXJuKFwic3RyaW5nXCI9PXR5cGVvZiB0P3NbdF06dCkuYXBwbHkocyxhcmd1bWVudHMpfXZhciBzPXRoaXM7cmV0dXJuIHNldFRpbWVvdXQoaSxlfHwwKX0sX2hvdmVyYWJsZTpmdW5jdGlvbihlKXt0aGlzLmhvdmVyYWJsZT10aGlzLmhvdmVyYWJsZS5hZGQoZSksdGhpcy5fb24oZSx7bW91c2VlbnRlcjpmdW5jdGlvbihlKXt0aGlzLl9hZGRDbGFzcyh0KGUuY3VycmVudFRhcmdldCksbnVsbCxcInVpLXN0YXRlLWhvdmVyXCIpfSxtb3VzZWxlYXZlOmZ1bmN0aW9uKGUpe3RoaXMuX3JlbW92ZUNsYXNzKHQoZS5jdXJyZW50VGFyZ2V0KSxudWxsLFwidWktc3RhdGUtaG92ZXJcIil9fSl9LF9mb2N1c2FibGU6ZnVuY3Rpb24oZSl7dGhpcy5mb2N1c2FibGU9dGhpcy5mb2N1c2FibGUuYWRkKGUpLHRoaXMuX29uKGUse2ZvY3VzaW46ZnVuY3Rpb24oZSl7dGhpcy5fYWRkQ2xhc3ModChlLmN1cnJlbnRUYXJnZXQpLG51bGwsXCJ1aS1zdGF0ZS1mb2N1c1wiKX0sZm9jdXNvdXQ6ZnVuY3Rpb24oZSl7dGhpcy5fcmVtb3ZlQ2xhc3ModChlLmN1cnJlbnRUYXJnZXQpLG51bGwsXCJ1aS1zdGF0ZS1mb2N1c1wiKX19KX0sX3RyaWdnZXI6ZnVuY3Rpb24oZSxpLHMpe3ZhciBuLG8sYT10aGlzLm9wdGlvbnNbZV07aWYocz1zfHx7fSxpPXQuRXZlbnQoaSksaS50eXBlPShlPT09dGhpcy53aWRnZXRFdmVudFByZWZpeD9lOnRoaXMud2lkZ2V0RXZlbnRQcmVmaXgrZSkudG9Mb3dlckNhc2UoKSxpLnRhcmdldD10aGlzLmVsZW1lbnRbMF0sbz1pLm9yaWdpbmFsRXZlbnQpZm9yKG4gaW4gbyluIGluIGl8fChpW25dPW9bbl0pO3JldHVybiB0aGlzLmVsZW1lbnQudHJpZ2dlcihpLHMpLCEodC5pc0Z1bmN0aW9uKGEpJiZhLmFwcGx5KHRoaXMuZWxlbWVudFswXSxbaV0uY29uY2F0KHMpKT09PSExfHxpLmlzRGVmYXVsdFByZXZlbnRlZCgpKX19LHQuZWFjaCh7c2hvdzpcImZhZGVJblwiLGhpZGU6XCJmYWRlT3V0XCJ9LGZ1bmN0aW9uKGUsaSl7dC5XaWRnZXQucHJvdG90eXBlW1wiX1wiK2VdPWZ1bmN0aW9uKHMsbixvKXtcInN0cmluZ1wiPT10eXBlb2YgbiYmKG49e2VmZmVjdDpufSk7dmFyIGEscj1uP249PT0hMHx8XCJudW1iZXJcIj09dHlwZW9mIG4/aTpuLmVmZmVjdHx8aTplO249bnx8e30sXCJudW1iZXJcIj09dHlwZW9mIG4mJihuPXtkdXJhdGlvbjpufSksYT0hdC5pc0VtcHR5T2JqZWN0KG4pLG4uY29tcGxldGU9byxuLmRlbGF5JiZzLmRlbGF5KG4uZGVsYXkpLGEmJnQuZWZmZWN0cyYmdC5lZmZlY3RzLmVmZmVjdFtyXT9zW2VdKG4pOnIhPT1lJiZzW3JdP3Nbcl0obi5kdXJhdGlvbixuLmVhc2luZyxvKTpzLnF1ZXVlKGZ1bmN0aW9uKGkpe3QodGhpcylbZV0oKSxvJiZvLmNhbGwoc1swXSksaSgpfSl9fSksdC53aWRnZXQsZnVuY3Rpb24oKXtmdW5jdGlvbiBlKHQsZSxpKXtyZXR1cm5bcGFyc2VGbG9hdCh0WzBdKSoodS50ZXN0KHRbMF0pP2UvMTAwOjEpLHBhcnNlRmxvYXQodFsxXSkqKHUudGVzdCh0WzFdKT9pLzEwMDoxKV19ZnVuY3Rpb24gaShlLGkpe3JldHVybiBwYXJzZUludCh0LmNzcyhlLGkpLDEwKXx8MH1mdW5jdGlvbiBzKGUpe3ZhciBpPWVbMF07cmV0dXJuIDk9PT1pLm5vZGVUeXBlP3t3aWR0aDplLndpZHRoKCksaGVpZ2h0OmUuaGVpZ2h0KCksb2Zmc2V0Ont0b3A6MCxsZWZ0OjB9fTp0LmlzV2luZG93KGkpP3t3aWR0aDplLndpZHRoKCksaGVpZ2h0OmUuaGVpZ2h0KCksb2Zmc2V0Ont0b3A6ZS5zY3JvbGxUb3AoKSxsZWZ0OmUuc2Nyb2xsTGVmdCgpfX06aS5wcmV2ZW50RGVmYXVsdD97d2lkdGg6MCxoZWlnaHQ6MCxvZmZzZXQ6e3RvcDppLnBhZ2VZLGxlZnQ6aS5wYWdlWH19Ont3aWR0aDplLm91dGVyV2lkdGgoKSxoZWlnaHQ6ZS5vdXRlckhlaWdodCgpLG9mZnNldDplLm9mZnNldCgpfX12YXIgbixvPU1hdGgubWF4LGE9TWF0aC5hYnMscj0vbGVmdHxjZW50ZXJ8cmlnaHQvLGg9L3RvcHxjZW50ZXJ8Ym90dG9tLyxsPS9bXFwrXFwtXVxcZCsoXFwuW1xcZF0rKT8lPy8sYz0vXlxcdysvLHU9LyUkLyxkPXQuZm4ucG9zaXRpb247dC5wb3NpdGlvbj17c2Nyb2xsYmFyV2lkdGg6ZnVuY3Rpb24oKXtpZih2b2lkIDAhPT1uKXJldHVybiBuO3ZhciBlLGkscz10KFwiPGRpdiBzdHlsZT0nZGlzcGxheTpibG9jaztwb3NpdGlvbjphYnNvbHV0ZTt3aWR0aDo1MHB4O2hlaWdodDo1MHB4O292ZXJmbG93OmhpZGRlbjsnPjxkaXYgc3R5bGU9J2hlaWdodDoxMDBweDt3aWR0aDphdXRvOyc+PC9kaXY+PC9kaXY+XCIpLG89cy5jaGlsZHJlbigpWzBdO3JldHVybiB0KFwiYm9keVwiKS5hcHBlbmQocyksZT1vLm9mZnNldFdpZHRoLHMuY3NzKFwib3ZlcmZsb3dcIixcInNjcm9sbFwiKSxpPW8ub2Zmc2V0V2lkdGgsZT09PWkmJihpPXNbMF0uY2xpZW50V2lkdGgpLHMucmVtb3ZlKCksbj1lLWl9LGdldFNjcm9sbEluZm86ZnVuY3Rpb24oZSl7dmFyIGk9ZS5pc1dpbmRvd3x8ZS5pc0RvY3VtZW50P1wiXCI6ZS5lbGVtZW50LmNzcyhcIm92ZXJmbG93LXhcIikscz1lLmlzV2luZG93fHxlLmlzRG9jdW1lbnQ/XCJcIjplLmVsZW1lbnQuY3NzKFwib3ZlcmZsb3cteVwiKSxuPVwic2Nyb2xsXCI9PT1pfHxcImF1dG9cIj09PWkmJmUud2lkdGg8ZS5lbGVtZW50WzBdLnNjcm9sbFdpZHRoLG89XCJzY3JvbGxcIj09PXN8fFwiYXV0b1wiPT09cyYmZS5oZWlnaHQ8ZS5lbGVtZW50WzBdLnNjcm9sbEhlaWdodDtyZXR1cm57d2lkdGg6bz90LnBvc2l0aW9uLnNjcm9sbGJhcldpZHRoKCk6MCxoZWlnaHQ6bj90LnBvc2l0aW9uLnNjcm9sbGJhcldpZHRoKCk6MH19LGdldFdpdGhpbkluZm86ZnVuY3Rpb24oZSl7dmFyIGk9dChlfHx3aW5kb3cpLHM9dC5pc1dpbmRvdyhpWzBdKSxuPSEhaVswXSYmOT09PWlbMF0ubm9kZVR5cGUsbz0hcyYmIW47cmV0dXJue2VsZW1lbnQ6aSxpc1dpbmRvdzpzLGlzRG9jdW1lbnQ6bixvZmZzZXQ6bz90KGUpLm9mZnNldCgpOntsZWZ0OjAsdG9wOjB9LHNjcm9sbExlZnQ6aS5zY3JvbGxMZWZ0KCksc2Nyb2xsVG9wOmkuc2Nyb2xsVG9wKCksd2lkdGg6aS5vdXRlcldpZHRoKCksaGVpZ2h0Omkub3V0ZXJIZWlnaHQoKX19fSx0LmZuLnBvc2l0aW9uPWZ1bmN0aW9uKG4pe2lmKCFufHwhbi5vZilyZXR1cm4gZC5hcHBseSh0aGlzLGFyZ3VtZW50cyk7bj10LmV4dGVuZCh7fSxuKTt2YXIgdSxwLGYsZyxtLF8sdj10KG4ub2YpLGI9dC5wb3NpdGlvbi5nZXRXaXRoaW5JbmZvKG4ud2l0aGluKSx5PXQucG9zaXRpb24uZ2V0U2Nyb2xsSW5mbyhiKSx3PShuLmNvbGxpc2lvbnx8XCJmbGlwXCIpLnNwbGl0KFwiIFwiKSxrPXt9O3JldHVybiBfPXModiksdlswXS5wcmV2ZW50RGVmYXVsdCYmKG4uYXQ9XCJsZWZ0IHRvcFwiKSxwPV8ud2lkdGgsZj1fLmhlaWdodCxnPV8ub2Zmc2V0LG09dC5leHRlbmQoe30sZyksdC5lYWNoKFtcIm15XCIsXCJhdFwiXSxmdW5jdGlvbigpe3ZhciB0LGUsaT0oblt0aGlzXXx8XCJcIikuc3BsaXQoXCIgXCIpOzE9PT1pLmxlbmd0aCYmKGk9ci50ZXN0KGlbMF0pP2kuY29uY2F0KFtcImNlbnRlclwiXSk6aC50ZXN0KGlbMF0pP1tcImNlbnRlclwiXS5jb25jYXQoaSk6W1wiY2VudGVyXCIsXCJjZW50ZXJcIl0pLGlbMF09ci50ZXN0KGlbMF0pP2lbMF06XCJjZW50ZXJcIixpWzFdPWgudGVzdChpWzFdKT9pWzFdOlwiY2VudGVyXCIsdD1sLmV4ZWMoaVswXSksZT1sLmV4ZWMoaVsxXSksa1t0aGlzXT1bdD90WzBdOjAsZT9lWzBdOjBdLG5bdGhpc109W2MuZXhlYyhpWzBdKVswXSxjLmV4ZWMoaVsxXSlbMF1dfSksMT09PXcubGVuZ3RoJiYod1sxXT13WzBdKSxcInJpZ2h0XCI9PT1uLmF0WzBdP20ubGVmdCs9cDpcImNlbnRlclwiPT09bi5hdFswXSYmKG0ubGVmdCs9cC8yKSxcImJvdHRvbVwiPT09bi5hdFsxXT9tLnRvcCs9ZjpcImNlbnRlclwiPT09bi5hdFsxXSYmKG0udG9wKz1mLzIpLHU9ZShrLmF0LHAsZiksbS5sZWZ0Kz11WzBdLG0udG9wKz11WzFdLHRoaXMuZWFjaChmdW5jdGlvbigpe3ZhciBzLHIsaD10KHRoaXMpLGw9aC5vdXRlcldpZHRoKCksYz1oLm91dGVySGVpZ2h0KCksZD1pKHRoaXMsXCJtYXJnaW5MZWZ0XCIpLF89aSh0aGlzLFwibWFyZ2luVG9wXCIpLHg9bCtkK2kodGhpcyxcIm1hcmdpblJpZ2h0XCIpK3kud2lkdGgsQz1jK18raSh0aGlzLFwibWFyZ2luQm90dG9tXCIpK3kuaGVpZ2h0LEQ9dC5leHRlbmQoe30sbSksST1lKGsubXksaC5vdXRlcldpZHRoKCksaC5vdXRlckhlaWdodCgpKTtcInJpZ2h0XCI9PT1uLm15WzBdP0QubGVmdC09bDpcImNlbnRlclwiPT09bi5teVswXSYmKEQubGVmdC09bC8yKSxcImJvdHRvbVwiPT09bi5teVsxXT9ELnRvcC09YzpcImNlbnRlclwiPT09bi5teVsxXSYmKEQudG9wLT1jLzIpLEQubGVmdCs9SVswXSxELnRvcCs9SVsxXSxzPXttYXJnaW5MZWZ0OmQsbWFyZ2luVG9wOl99LHQuZWFjaChbXCJsZWZ0XCIsXCJ0b3BcIl0sZnVuY3Rpb24oZSxpKXt0LnVpLnBvc2l0aW9uW3dbZV1dJiZ0LnVpLnBvc2l0aW9uW3dbZV1dW2ldKEQse3RhcmdldFdpZHRoOnAsdGFyZ2V0SGVpZ2h0OmYsZWxlbVdpZHRoOmwsZWxlbUhlaWdodDpjLGNvbGxpc2lvblBvc2l0aW9uOnMsY29sbGlzaW9uV2lkdGg6eCxjb2xsaXNpb25IZWlnaHQ6QyxvZmZzZXQ6W3VbMF0rSVswXSx1WzFdK0lbMV1dLG15Om4ubXksYXQ6bi5hdCx3aXRoaW46YixlbGVtOmh9KX0pLG4udXNpbmcmJihyPWZ1bmN0aW9uKHQpe3ZhciBlPWcubGVmdC1ELmxlZnQsaT1lK3AtbCxzPWcudG9wLUQudG9wLHI9cytmLWMsdT17dGFyZ2V0OntlbGVtZW50OnYsbGVmdDpnLmxlZnQsdG9wOmcudG9wLHdpZHRoOnAsaGVpZ2h0OmZ9LGVsZW1lbnQ6e2VsZW1lbnQ6aCxsZWZ0OkQubGVmdCx0b3A6RC50b3Asd2lkdGg6bCxoZWlnaHQ6Y30saG9yaXpvbnRhbDowPmk/XCJsZWZ0XCI6ZT4wP1wicmlnaHRcIjpcImNlbnRlclwiLHZlcnRpY2FsOjA+cj9cInRvcFwiOnM+MD9cImJvdHRvbVwiOlwibWlkZGxlXCJ9O2w+cCYmcD5hKGUraSkmJih1Lmhvcml6b250YWw9XCJjZW50ZXJcIiksYz5mJiZmPmEocytyKSYmKHUudmVydGljYWw9XCJtaWRkbGVcIiksdS5pbXBvcnRhbnQ9byhhKGUpLGEoaSkpPm8oYShzKSxhKHIpKT9cImhvcml6b250YWxcIjpcInZlcnRpY2FsXCIsbi51c2luZy5jYWxsKHRoaXMsdCx1KX0pLGgub2Zmc2V0KHQuZXh0ZW5kKEQse3VzaW5nOnJ9KSl9KX0sdC51aS5wb3NpdGlvbj17Zml0OntsZWZ0OmZ1bmN0aW9uKHQsZSl7dmFyIGkscz1lLndpdGhpbixuPXMuaXNXaW5kb3c/cy5zY3JvbGxMZWZ0OnMub2Zmc2V0LmxlZnQsYT1zLndpZHRoLHI9dC5sZWZ0LWUuY29sbGlzaW9uUG9zaXRpb24ubWFyZ2luTGVmdCxoPW4tcixsPXIrZS5jb2xsaXNpb25XaWR0aC1hLW47ZS5jb2xsaXNpb25XaWR0aD5hP2g+MCYmMD49bD8oaT10LmxlZnQraCtlLmNvbGxpc2lvbldpZHRoLWEtbix0LmxlZnQrPWgtaSk6dC5sZWZ0PWw+MCYmMD49aD9uOmg+bD9uK2EtZS5jb2xsaXNpb25XaWR0aDpuOmg+MD90LmxlZnQrPWg6bD4wP3QubGVmdC09bDp0LmxlZnQ9byh0LmxlZnQtcix0LmxlZnQpfSx0b3A6ZnVuY3Rpb24odCxlKXt2YXIgaSxzPWUud2l0aGluLG49cy5pc1dpbmRvdz9zLnNjcm9sbFRvcDpzLm9mZnNldC50b3AsYT1lLndpdGhpbi5oZWlnaHQscj10LnRvcC1lLmNvbGxpc2lvblBvc2l0aW9uLm1hcmdpblRvcCxoPW4tcixsPXIrZS5jb2xsaXNpb25IZWlnaHQtYS1uO2UuY29sbGlzaW9uSGVpZ2h0PmE/aD4wJiYwPj1sPyhpPXQudG9wK2grZS5jb2xsaXNpb25IZWlnaHQtYS1uLHQudG9wKz1oLWkpOnQudG9wPWw+MCYmMD49aD9uOmg+bD9uK2EtZS5jb2xsaXNpb25IZWlnaHQ6bjpoPjA/dC50b3ArPWg6bD4wP3QudG9wLT1sOnQudG9wPW8odC50b3Atcix0LnRvcCl9fSxmbGlwOntsZWZ0OmZ1bmN0aW9uKHQsZSl7dmFyIGkscyxuPWUud2l0aGluLG89bi5vZmZzZXQubGVmdCtuLnNjcm9sbExlZnQscj1uLndpZHRoLGg9bi5pc1dpbmRvdz9uLnNjcm9sbExlZnQ6bi5vZmZzZXQubGVmdCxsPXQubGVmdC1lLmNvbGxpc2lvblBvc2l0aW9uLm1hcmdpbkxlZnQsYz1sLWgsdT1sK2UuY29sbGlzaW9uV2lkdGgtci1oLGQ9XCJsZWZ0XCI9PT1lLm15WzBdPy1lLmVsZW1XaWR0aDpcInJpZ2h0XCI9PT1lLm15WzBdP2UuZWxlbVdpZHRoOjAscD1cImxlZnRcIj09PWUuYXRbMF0/ZS50YXJnZXRXaWR0aDpcInJpZ2h0XCI9PT1lLmF0WzBdPy1lLnRhcmdldFdpZHRoOjAsZj0tMiplLm9mZnNldFswXTswPmM/KGk9dC5sZWZ0K2QrcCtmK2UuY29sbGlzaW9uV2lkdGgtci1vLCgwPml8fGEoYyk+aSkmJih0LmxlZnQrPWQrcCtmKSk6dT4wJiYocz10LmxlZnQtZS5jb2xsaXNpb25Qb3NpdGlvbi5tYXJnaW5MZWZ0K2QrcCtmLWgsKHM+MHx8dT5hKHMpKSYmKHQubGVmdCs9ZCtwK2YpKX0sdG9wOmZ1bmN0aW9uKHQsZSl7dmFyIGkscyxuPWUud2l0aGluLG89bi5vZmZzZXQudG9wK24uc2Nyb2xsVG9wLHI9bi5oZWlnaHQsaD1uLmlzV2luZG93P24uc2Nyb2xsVG9wOm4ub2Zmc2V0LnRvcCxsPXQudG9wLWUuY29sbGlzaW9uUG9zaXRpb24ubWFyZ2luVG9wLGM9bC1oLHU9bCtlLmNvbGxpc2lvbkhlaWdodC1yLWgsZD1cInRvcFwiPT09ZS5teVsxXSxwPWQ/LWUuZWxlbUhlaWdodDpcImJvdHRvbVwiPT09ZS5teVsxXT9lLmVsZW1IZWlnaHQ6MCxmPVwidG9wXCI9PT1lLmF0WzFdP2UudGFyZ2V0SGVpZ2h0OlwiYm90dG9tXCI9PT1lLmF0WzFdPy1lLnRhcmdldEhlaWdodDowLGc9LTIqZS5vZmZzZXRbMV07MD5jPyhzPXQudG9wK3ArZitnK2UuY29sbGlzaW9uSGVpZ2h0LXItbywoMD5zfHxhKGMpPnMpJiYodC50b3ArPXArZitnKSk6dT4wJiYoaT10LnRvcC1lLmNvbGxpc2lvblBvc2l0aW9uLm1hcmdpblRvcCtwK2YrZy1oLChpPjB8fHU+YShpKSkmJih0LnRvcCs9cCtmK2cpKX19LGZsaXBmaXQ6e2xlZnQ6ZnVuY3Rpb24oKXt0LnVpLnBvc2l0aW9uLmZsaXAubGVmdC5hcHBseSh0aGlzLGFyZ3VtZW50cyksdC51aS5wb3NpdGlvbi5maXQubGVmdC5hcHBseSh0aGlzLGFyZ3VtZW50cyl9LHRvcDpmdW5jdGlvbigpe3QudWkucG9zaXRpb24uZmxpcC50b3AuYXBwbHkodGhpcyxhcmd1bWVudHMpLHQudWkucG9zaXRpb24uZml0LnRvcC5hcHBseSh0aGlzLGFyZ3VtZW50cyl9fX19KCksdC51aS5wb3NpdGlvbix0LmV4dGVuZCh0LmV4cHJbXCI6XCJdLHtkYXRhOnQuZXhwci5jcmVhdGVQc2V1ZG8/dC5leHByLmNyZWF0ZVBzZXVkbyhmdW5jdGlvbihlKXtyZXR1cm4gZnVuY3Rpb24oaSl7cmV0dXJuISF0LmRhdGEoaSxlKX19KTpmdW5jdGlvbihlLGkscyl7cmV0dXJuISF0LmRhdGEoZSxzWzNdKX19KSx0LmZuLmV4dGVuZCh7ZGlzYWJsZVNlbGVjdGlvbjpmdW5jdGlvbigpe3ZhciB0PVwib25zZWxlY3RzdGFydFwiaW4gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcImRpdlwiKT9cInNlbGVjdHN0YXJ0XCI6XCJtb3VzZWRvd25cIjtyZXR1cm4gZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5vbih0K1wiLnVpLWRpc2FibGVTZWxlY3Rpb25cIixmdW5jdGlvbih0KXt0LnByZXZlbnREZWZhdWx0KCl9KX19KCksZW5hYmxlU2VsZWN0aW9uOmZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMub2ZmKFwiLnVpLWRpc2FibGVTZWxlY3Rpb25cIil9fSksdC51aS5mb2N1c2FibGU9ZnVuY3Rpb24oaSxzKXt2YXIgbixvLGEscixoLGw9aS5ub2RlTmFtZS50b0xvd2VyQ2FzZSgpO3JldHVyblwiYXJlYVwiPT09bD8obj1pLnBhcmVudE5vZGUsbz1uLm5hbWUsaS5ocmVmJiZvJiZcIm1hcFwiPT09bi5ub2RlTmFtZS50b0xvd2VyQ2FzZSgpPyhhPXQoXCJpbWdbdXNlbWFwPScjXCIrbytcIiddXCIpLGEubGVuZ3RoPjAmJmEuaXMoXCI6dmlzaWJsZVwiKSk6ITEpOigvXihpbnB1dHxzZWxlY3R8dGV4dGFyZWF8YnV0dG9ufG9iamVjdCkkLy50ZXN0KGwpPyhyPSFpLmRpc2FibGVkLHImJihoPXQoaSkuY2xvc2VzdChcImZpZWxkc2V0XCIpWzBdLGgmJihyPSFoLmRpc2FibGVkKSkpOnI9XCJhXCI9PT1sP2kuaHJlZnx8czpzLHImJnQoaSkuaXMoXCI6dmlzaWJsZVwiKSYmZSh0KGkpKSl9LHQuZXh0ZW5kKHQuZXhwcltcIjpcIl0se2ZvY3VzYWJsZTpmdW5jdGlvbihlKXtyZXR1cm4gdC51aS5mb2N1c2FibGUoZSxudWxsIT10LmF0dHIoZSxcInRhYmluZGV4XCIpKX19KSx0LnVpLmZvY3VzYWJsZSx0LmZuLmZvcm09ZnVuY3Rpb24oKXtyZXR1cm5cInN0cmluZ1wiPT10eXBlb2YgdGhpc1swXS5mb3JtP3RoaXMuY2xvc2VzdChcImZvcm1cIik6dCh0aGlzWzBdLmZvcm0pfSx0LnVpLmZvcm1SZXNldE1peGluPXtfZm9ybVJlc2V0SGFuZGxlcjpmdW5jdGlvbigpe3ZhciBlPXQodGhpcyk7c2V0VGltZW91dChmdW5jdGlvbigpe3ZhciBpPWUuZGF0YShcInVpLWZvcm0tcmVzZXQtaW5zdGFuY2VzXCIpO3QuZWFjaChpLGZ1bmN0aW9uKCl7dGhpcy5yZWZyZXNoKCl9KX0pfSxfYmluZEZvcm1SZXNldEhhbmRsZXI6ZnVuY3Rpb24oKXtpZih0aGlzLmZvcm09dGhpcy5lbGVtZW50LmZvcm0oKSx0aGlzLmZvcm0ubGVuZ3RoKXt2YXIgdD10aGlzLmZvcm0uZGF0YShcInVpLWZvcm0tcmVzZXQtaW5zdGFuY2VzXCIpfHxbXTt0Lmxlbmd0aHx8dGhpcy5mb3JtLm9uKFwicmVzZXQudWktZm9ybS1yZXNldFwiLHRoaXMuX2Zvcm1SZXNldEhhbmRsZXIpLHQucHVzaCh0aGlzKSx0aGlzLmZvcm0uZGF0YShcInVpLWZvcm0tcmVzZXQtaW5zdGFuY2VzXCIsdCl9fSxfdW5iaW5kRm9ybVJlc2V0SGFuZGxlcjpmdW5jdGlvbigpe2lmKHRoaXMuZm9ybS5sZW5ndGgpe3ZhciBlPXRoaXMuZm9ybS5kYXRhKFwidWktZm9ybS1yZXNldC1pbnN0YW5jZXNcIik7ZS5zcGxpY2UodC5pbkFycmF5KHRoaXMsZSksMSksZS5sZW5ndGg/dGhpcy5mb3JtLmRhdGEoXCJ1aS1mb3JtLXJlc2V0LWluc3RhbmNlc1wiLGUpOnRoaXMuZm9ybS5yZW1vdmVEYXRhKFwidWktZm9ybS1yZXNldC1pbnN0YW5jZXNcIikub2ZmKFwicmVzZXQudWktZm9ybS1yZXNldFwiKX19fSxcIjEuN1wiPT09dC5mbi5qcXVlcnkuc3Vic3RyaW5nKDAsMykmJih0LmVhY2goW1wiV2lkdGhcIixcIkhlaWdodFwiXSxmdW5jdGlvbihlLGkpe2Z1bmN0aW9uIHMoZSxpLHMsbyl7cmV0dXJuIHQuZWFjaChuLGZ1bmN0aW9uKCl7aS09cGFyc2VGbG9hdCh0LmNzcyhlLFwicGFkZGluZ1wiK3RoaXMpKXx8MCxzJiYoaS09cGFyc2VGbG9hdCh0LmNzcyhlLFwiYm9yZGVyXCIrdGhpcytcIldpZHRoXCIpKXx8MCksbyYmKGktPXBhcnNlRmxvYXQodC5jc3MoZSxcIm1hcmdpblwiK3RoaXMpKXx8MCl9KSxpfXZhciBuPVwiV2lkdGhcIj09PWk/W1wiTGVmdFwiLFwiUmlnaHRcIl06W1wiVG9wXCIsXCJCb3R0b21cIl0sbz1pLnRvTG93ZXJDYXNlKCksYT17aW5uZXJXaWR0aDp0LmZuLmlubmVyV2lkdGgsaW5uZXJIZWlnaHQ6dC5mbi5pbm5lckhlaWdodCxvdXRlcldpZHRoOnQuZm4ub3V0ZXJXaWR0aCxvdXRlckhlaWdodDp0LmZuLm91dGVySGVpZ2h0fTt0LmZuW1wiaW5uZXJcIitpXT1mdW5jdGlvbihlKXtyZXR1cm4gdm9pZCAwPT09ZT9hW1wiaW5uZXJcIitpXS5jYWxsKHRoaXMpOnRoaXMuZWFjaChmdW5jdGlvbigpe3QodGhpcykuY3NzKG8scyh0aGlzLGUpK1wicHhcIil9KX0sdC5mbltcIm91dGVyXCIraV09ZnVuY3Rpb24oZSxuKXtyZXR1cm5cIm51bWJlclwiIT10eXBlb2YgZT9hW1wib3V0ZXJcIitpXS5jYWxsKHRoaXMsZSk6dGhpcy5lYWNoKGZ1bmN0aW9uKCl7dCh0aGlzKS5jc3MobyxzKHRoaXMsZSwhMCxuKStcInB4XCIpfSl9fSksdC5mbi5hZGRCYWNrPWZ1bmN0aW9uKHQpe3JldHVybiB0aGlzLmFkZChudWxsPT10P3RoaXMucHJldk9iamVjdDp0aGlzLnByZXZPYmplY3QuZmlsdGVyKHQpKX0pLHQudWkua2V5Q29kZT17QkFDS1NQQUNFOjgsQ09NTUE6MTg4LERFTEVURTo0NixET1dOOjQwLEVORDozNSxFTlRFUjoxMyxFU0NBUEU6MjcsSE9NRTozNixMRUZUOjM3LFBBR0VfRE9XTjozNCxQQUdFX1VQOjMzLFBFUklPRDoxOTAsUklHSFQ6MzksU1BBQ0U6MzIsVEFCOjksVVA6Mzh9LHQudWkuZXNjYXBlU2VsZWN0b3I9ZnVuY3Rpb24oKXt2YXIgdD0vKFshXCIjJCUmJygpKissLi86Ozw9Pj9AW1xcXV5ge3x9fl0pL2c7cmV0dXJuIGZ1bmN0aW9uKGUpe3JldHVybiBlLnJlcGxhY2UodCxcIlxcXFwkMVwiKX19KCksdC5mbi5sYWJlbHM9ZnVuY3Rpb24oKXt2YXIgZSxpLHMsbixvO3JldHVybiB0aGlzWzBdLmxhYmVscyYmdGhpc1swXS5sYWJlbHMubGVuZ3RoP3RoaXMucHVzaFN0YWNrKHRoaXNbMF0ubGFiZWxzKToobj10aGlzLmVxKDApLnBhcmVudHMoXCJsYWJlbFwiKSxzPXRoaXMuYXR0cihcImlkXCIpLHMmJihlPXRoaXMuZXEoMCkucGFyZW50cygpLmxhc3QoKSxvPWUuYWRkKGUubGVuZ3RoP2Uuc2libGluZ3MoKTp0aGlzLnNpYmxpbmdzKCkpLGk9XCJsYWJlbFtmb3I9J1wiK3QudWkuZXNjYXBlU2VsZWN0b3IocykrXCInXVwiLG49bi5hZGQoby5maW5kKGkpLmFkZEJhY2soaSkpKSx0aGlzLnB1c2hTdGFjayhuKSl9LHQuZm4uc2Nyb2xsUGFyZW50PWZ1bmN0aW9uKGUpe3ZhciBpPXRoaXMuY3NzKFwicG9zaXRpb25cIikscz1cImFic29sdXRlXCI9PT1pLG49ZT8vKGF1dG98c2Nyb2xsfGhpZGRlbikvOi8oYXV0b3xzY3JvbGwpLyxvPXRoaXMucGFyZW50cygpLmZpbHRlcihmdW5jdGlvbigpe3ZhciBlPXQodGhpcyk7cmV0dXJuIHMmJlwic3RhdGljXCI9PT1lLmNzcyhcInBvc2l0aW9uXCIpPyExOm4udGVzdChlLmNzcyhcIm92ZXJmbG93XCIpK2UuY3NzKFwib3ZlcmZsb3cteVwiKStlLmNzcyhcIm92ZXJmbG93LXhcIikpfSkuZXEoMCk7cmV0dXJuXCJmaXhlZFwiIT09aSYmby5sZW5ndGg/bzp0KHRoaXNbMF0ub3duZXJEb2N1bWVudHx8ZG9jdW1lbnQpfSx0LmV4dGVuZCh0LmV4cHJbXCI6XCJdLHt0YWJiYWJsZTpmdW5jdGlvbihlKXt2YXIgaT10LmF0dHIoZSxcInRhYmluZGV4XCIpLHM9bnVsbCE9aTtyZXR1cm4oIXN8fGk+PTApJiZ0LnVpLmZvY3VzYWJsZShlLHMpfX0pLHQuZm4uZXh0ZW5kKHt1bmlxdWVJZDpmdW5jdGlvbigpe3ZhciB0PTA7cmV0dXJuIGZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMuZWFjaChmdW5jdGlvbigpe3RoaXMuaWR8fCh0aGlzLmlkPVwidWktaWQtXCIrICsrdCl9KX19KCkscmVtb3ZlVW5pcXVlSWQ6ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5lYWNoKGZ1bmN0aW9uKCl7L151aS1pZC1cXGQrJC8udGVzdCh0aGlzLmlkKSYmdCh0aGlzKS5yZW1vdmVBdHRyKFwiaWRcIil9KX19KSx0LnVpLmllPSEhL21zaWUgW1xcdy5dKy8uZXhlYyhuYXZpZ2F0b3IudXNlckFnZW50LnRvTG93ZXJDYXNlKCkpO3ZhciBjPSExO3QoZG9jdW1lbnQpLm9uKFwibW91c2V1cFwiLGZ1bmN0aW9uKCl7Yz0hMX0pLHQud2lkZ2V0KFwidWkubW91c2VcIix7dmVyc2lvbjpcIjEuMTIuMVwiLG9wdGlvbnM6e2NhbmNlbDpcImlucHV0LCB0ZXh0YXJlYSwgYnV0dG9uLCBzZWxlY3QsIG9wdGlvblwiLGRpc3RhbmNlOjEsZGVsYXk6MH0sX21vdXNlSW5pdDpmdW5jdGlvbigpe3ZhciBlPXRoaXM7dGhpcy5lbGVtZW50Lm9uKFwibW91c2Vkb3duLlwiK3RoaXMud2lkZ2V0TmFtZSxmdW5jdGlvbih0KXtyZXR1cm4gZS5fbW91c2VEb3duKHQpfSkub24oXCJjbGljay5cIit0aGlzLndpZGdldE5hbWUsZnVuY3Rpb24oaSl7cmV0dXJuITA9PT10LmRhdGEoaS50YXJnZXQsZS53aWRnZXROYW1lK1wiLnByZXZlbnRDbGlja0V2ZW50XCIpPyh0LnJlbW92ZURhdGEoaS50YXJnZXQsZS53aWRnZXROYW1lK1wiLnByZXZlbnRDbGlja0V2ZW50XCIpLGkuc3RvcEltbWVkaWF0ZVByb3BhZ2F0aW9uKCksITEpOnZvaWQgMH0pLHRoaXMuc3RhcnRlZD0hMX0sX21vdXNlRGVzdHJveTpmdW5jdGlvbigpe3RoaXMuZWxlbWVudC5vZmYoXCIuXCIrdGhpcy53aWRnZXROYW1lKSx0aGlzLl9tb3VzZU1vdmVEZWxlZ2F0ZSYmdGhpcy5kb2N1bWVudC5vZmYoXCJtb3VzZW1vdmUuXCIrdGhpcy53aWRnZXROYW1lLHRoaXMuX21vdXNlTW92ZURlbGVnYXRlKS5vZmYoXCJtb3VzZXVwLlwiK3RoaXMud2lkZ2V0TmFtZSx0aGlzLl9tb3VzZVVwRGVsZWdhdGUpfSxfbW91c2VEb3duOmZ1bmN0aW9uKGUpe2lmKCFjKXt0aGlzLl9tb3VzZU1vdmVkPSExLHRoaXMuX21vdXNlU3RhcnRlZCYmdGhpcy5fbW91c2VVcChlKSx0aGlzLl9tb3VzZURvd25FdmVudD1lO3ZhciBpPXRoaXMscz0xPT09ZS53aGljaCxuPVwic3RyaW5nXCI9PXR5cGVvZiB0aGlzLm9wdGlvbnMuY2FuY2VsJiZlLnRhcmdldC5ub2RlTmFtZT90KGUudGFyZ2V0KS5jbG9zZXN0KHRoaXMub3B0aW9ucy5jYW5jZWwpLmxlbmd0aDohMTtyZXR1cm4gcyYmIW4mJnRoaXMuX21vdXNlQ2FwdHVyZShlKT8odGhpcy5tb3VzZURlbGF5TWV0PSF0aGlzLm9wdGlvbnMuZGVsYXksdGhpcy5tb3VzZURlbGF5TWV0fHwodGhpcy5fbW91c2VEZWxheVRpbWVyPXNldFRpbWVvdXQoZnVuY3Rpb24oKXtpLm1vdXNlRGVsYXlNZXQ9ITB9LHRoaXMub3B0aW9ucy5kZWxheSkpLHRoaXMuX21vdXNlRGlzdGFuY2VNZXQoZSkmJnRoaXMuX21vdXNlRGVsYXlNZXQoZSkmJih0aGlzLl9tb3VzZVN0YXJ0ZWQ9dGhpcy5fbW91c2VTdGFydChlKSE9PSExLCF0aGlzLl9tb3VzZVN0YXJ0ZWQpPyhlLnByZXZlbnREZWZhdWx0KCksITApOighMD09PXQuZGF0YShlLnRhcmdldCx0aGlzLndpZGdldE5hbWUrXCIucHJldmVudENsaWNrRXZlbnRcIikmJnQucmVtb3ZlRGF0YShlLnRhcmdldCx0aGlzLndpZGdldE5hbWUrXCIucHJldmVudENsaWNrRXZlbnRcIiksdGhpcy5fbW91c2VNb3ZlRGVsZWdhdGU9ZnVuY3Rpb24odCl7cmV0dXJuIGkuX21vdXNlTW92ZSh0KX0sdGhpcy5fbW91c2VVcERlbGVnYXRlPWZ1bmN0aW9uKHQpe3JldHVybiBpLl9tb3VzZVVwKHQpfSx0aGlzLmRvY3VtZW50Lm9uKFwibW91c2Vtb3ZlLlwiK3RoaXMud2lkZ2V0TmFtZSx0aGlzLl9tb3VzZU1vdmVEZWxlZ2F0ZSkub24oXCJtb3VzZXVwLlwiK3RoaXMud2lkZ2V0TmFtZSx0aGlzLl9tb3VzZVVwRGVsZWdhdGUpLGUucHJldmVudERlZmF1bHQoKSxjPSEwLCEwKSk6ITB9fSxfbW91c2VNb3ZlOmZ1bmN0aW9uKGUpe2lmKHRoaXMuX21vdXNlTW92ZWQpe2lmKHQudWkuaWUmJighZG9jdW1lbnQuZG9jdW1lbnRNb2RlfHw5PmRvY3VtZW50LmRvY3VtZW50TW9kZSkmJiFlLmJ1dHRvbilyZXR1cm4gdGhpcy5fbW91c2VVcChlKTtpZighZS53aGljaClpZihlLm9yaWdpbmFsRXZlbnQuYWx0S2V5fHxlLm9yaWdpbmFsRXZlbnQuY3RybEtleXx8ZS5vcmlnaW5hbEV2ZW50Lm1ldGFLZXl8fGUub3JpZ2luYWxFdmVudC5zaGlmdEtleSl0aGlzLmlnbm9yZU1pc3NpbmdXaGljaD0hMDtlbHNlIGlmKCF0aGlzLmlnbm9yZU1pc3NpbmdXaGljaClyZXR1cm4gdGhpcy5fbW91c2VVcChlKX1yZXR1cm4oZS53aGljaHx8ZS5idXR0b24pJiYodGhpcy5fbW91c2VNb3ZlZD0hMCksdGhpcy5fbW91c2VTdGFydGVkPyh0aGlzLl9tb3VzZURyYWcoZSksZS5wcmV2ZW50RGVmYXVsdCgpKToodGhpcy5fbW91c2VEaXN0YW5jZU1ldChlKSYmdGhpcy5fbW91c2VEZWxheU1ldChlKSYmKHRoaXMuX21vdXNlU3RhcnRlZD10aGlzLl9tb3VzZVN0YXJ0KHRoaXMuX21vdXNlRG93bkV2ZW50LGUpIT09ITEsdGhpcy5fbW91c2VTdGFydGVkP3RoaXMuX21vdXNlRHJhZyhlKTp0aGlzLl9tb3VzZVVwKGUpKSwhdGhpcy5fbW91c2VTdGFydGVkKX0sX21vdXNlVXA6ZnVuY3Rpb24oZSl7dGhpcy5kb2N1bWVudC5vZmYoXCJtb3VzZW1vdmUuXCIrdGhpcy53aWRnZXROYW1lLHRoaXMuX21vdXNlTW92ZURlbGVnYXRlKS5vZmYoXCJtb3VzZXVwLlwiK3RoaXMud2lkZ2V0TmFtZSx0aGlzLl9tb3VzZVVwRGVsZWdhdGUpLHRoaXMuX21vdXNlU3RhcnRlZCYmKHRoaXMuX21vdXNlU3RhcnRlZD0hMSxlLnRhcmdldD09PXRoaXMuX21vdXNlRG93bkV2ZW50LnRhcmdldCYmdC5kYXRhKGUudGFyZ2V0LHRoaXMud2lkZ2V0TmFtZStcIi5wcmV2ZW50Q2xpY2tFdmVudFwiLCEwKSx0aGlzLl9tb3VzZVN0b3AoZSkpLHRoaXMuX21vdXNlRGVsYXlUaW1lciYmKGNsZWFyVGltZW91dCh0aGlzLl9tb3VzZURlbGF5VGltZXIpLGRlbGV0ZSB0aGlzLl9tb3VzZURlbGF5VGltZXIpLHRoaXMuaWdub3JlTWlzc2luZ1doaWNoPSExLGM9ITEsZS5wcmV2ZW50RGVmYXVsdCgpfSxfbW91c2VEaXN0YW5jZU1ldDpmdW5jdGlvbih0KXtyZXR1cm4gTWF0aC5tYXgoTWF0aC5hYnModGhpcy5fbW91c2VEb3duRXZlbnQucGFnZVgtdC5wYWdlWCksTWF0aC5hYnModGhpcy5fbW91c2VEb3duRXZlbnQucGFnZVktdC5wYWdlWSkpPj10aGlzLm9wdGlvbnMuZGlzdGFuY2V9LF9tb3VzZURlbGF5TWV0OmZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMubW91c2VEZWxheU1ldH0sX21vdXNlU3RhcnQ6ZnVuY3Rpb24oKXt9LF9tb3VzZURyYWc6ZnVuY3Rpb24oKXt9LF9tb3VzZVN0b3A6ZnVuY3Rpb24oKXt9LF9tb3VzZUNhcHR1cmU6ZnVuY3Rpb24oKXtyZXR1cm4hMH19KSx0LnVpLnBsdWdpbj17YWRkOmZ1bmN0aW9uKGUsaSxzKXt2YXIgbixvPXQudWlbZV0ucHJvdG90eXBlO2ZvcihuIGluIHMpby5wbHVnaW5zW25dPW8ucGx1Z2luc1tuXXx8W10sby5wbHVnaW5zW25dLnB1c2goW2ksc1tuXV0pfSxjYWxsOmZ1bmN0aW9uKHQsZSxpLHMpe3ZhciBuLG89dC5wbHVnaW5zW2VdO2lmKG8mJihzfHx0LmVsZW1lbnRbMF0ucGFyZW50Tm9kZSYmMTEhPT10LmVsZW1lbnRbMF0ucGFyZW50Tm9kZS5ub2RlVHlwZSkpZm9yKG49MDtvLmxlbmd0aD5uO24rKyl0Lm9wdGlvbnNbb1tuXVswXV0mJm9bbl1bMV0uYXBwbHkodC5lbGVtZW50LGkpfX0sdC51aS5zYWZlQWN0aXZlRWxlbWVudD1mdW5jdGlvbih0KXt2YXIgZTt0cnl7ZT10LmFjdGl2ZUVsZW1lbnR9Y2F0Y2goaSl7ZT10LmJvZHl9cmV0dXJuIGV8fChlPXQuYm9keSksZS5ub2RlTmFtZXx8KGU9dC5ib2R5KSxlfSx0LnVpLnNhZmVCbHVyPWZ1bmN0aW9uKGUpe2UmJlwiYm9keVwiIT09ZS5ub2RlTmFtZS50b0xvd2VyQ2FzZSgpJiZ0KGUpLnRyaWdnZXIoXCJibHVyXCIpfSx0LndpZGdldChcInVpLmRyYWdnYWJsZVwiLHQudWkubW91c2Use3ZlcnNpb246XCIxLjEyLjFcIix3aWRnZXRFdmVudFByZWZpeDpcImRyYWdcIixvcHRpb25zOnthZGRDbGFzc2VzOiEwLGFwcGVuZFRvOlwicGFyZW50XCIsYXhpczohMSxjb25uZWN0VG9Tb3J0YWJsZTohMSxjb250YWlubWVudDohMSxjdXJzb3I6XCJhdXRvXCIsY3Vyc29yQXQ6ITEsZ3JpZDohMSxoYW5kbGU6ITEsaGVscGVyOlwib3JpZ2luYWxcIixpZnJhbWVGaXg6ITEsb3BhY2l0eTohMSxyZWZyZXNoUG9zaXRpb25zOiExLHJldmVydDohMSxyZXZlcnREdXJhdGlvbjo1MDAsc2NvcGU6XCJkZWZhdWx0XCIsc2Nyb2xsOiEwLHNjcm9sbFNlbnNpdGl2aXR5OjIwLHNjcm9sbFNwZWVkOjIwLHNuYXA6ITEsc25hcE1vZGU6XCJib3RoXCIsc25hcFRvbGVyYW5jZToyMCxzdGFjazohMSx6SW5kZXg6ITEsZHJhZzpudWxsLHN0YXJ0Om51bGwsc3RvcDpudWxsfSxfY3JlYXRlOmZ1bmN0aW9uKCl7XCJvcmlnaW5hbFwiPT09dGhpcy5vcHRpb25zLmhlbHBlciYmdGhpcy5fc2V0UG9zaXRpb25SZWxhdGl2ZSgpLHRoaXMub3B0aW9ucy5hZGRDbGFzc2VzJiZ0aGlzLl9hZGRDbGFzcyhcInVpLWRyYWdnYWJsZVwiKSx0aGlzLl9zZXRIYW5kbGVDbGFzc05hbWUoKSx0aGlzLl9tb3VzZUluaXQoKX0sX3NldE9wdGlvbjpmdW5jdGlvbih0LGUpe3RoaXMuX3N1cGVyKHQsZSksXCJoYW5kbGVcIj09PXQmJih0aGlzLl9yZW1vdmVIYW5kbGVDbGFzc05hbWUoKSx0aGlzLl9zZXRIYW5kbGVDbGFzc05hbWUoKSl9LF9kZXN0cm95OmZ1bmN0aW9uKCl7cmV0dXJuKHRoaXMuaGVscGVyfHx0aGlzLmVsZW1lbnQpLmlzKFwiLnVpLWRyYWdnYWJsZS1kcmFnZ2luZ1wiKT8odGhpcy5kZXN0cm95T25DbGVhcj0hMCx2b2lkIDApOih0aGlzLl9yZW1vdmVIYW5kbGVDbGFzc05hbWUoKSx0aGlzLl9tb3VzZURlc3Ryb3koKSx2b2lkIDApfSxfbW91c2VDYXB0dXJlOmZ1bmN0aW9uKGUpe3ZhciBpPXRoaXMub3B0aW9ucztyZXR1cm4gdGhpcy5oZWxwZXJ8fGkuZGlzYWJsZWR8fHQoZS50YXJnZXQpLmNsb3Nlc3QoXCIudWktcmVzaXphYmxlLWhhbmRsZVwiKS5sZW5ndGg+MD8hMToodGhpcy5oYW5kbGU9dGhpcy5fZ2V0SGFuZGxlKGUpLHRoaXMuaGFuZGxlPyh0aGlzLl9ibHVyQWN0aXZlRWxlbWVudChlKSx0aGlzLl9ibG9ja0ZyYW1lcyhpLmlmcmFtZUZpeD09PSEwP1wiaWZyYW1lXCI6aS5pZnJhbWVGaXgpLCEwKTohMSl9LF9ibG9ja0ZyYW1lczpmdW5jdGlvbihlKXt0aGlzLmlmcmFtZUJsb2Nrcz10aGlzLmRvY3VtZW50LmZpbmQoZSkubWFwKGZ1bmN0aW9uKCl7dmFyIGU9dCh0aGlzKTtyZXR1cm4gdChcIjxkaXY+XCIpLmNzcyhcInBvc2l0aW9uXCIsXCJhYnNvbHV0ZVwiKS5hcHBlbmRUbyhlLnBhcmVudCgpKS5vdXRlcldpZHRoKGUub3V0ZXJXaWR0aCgpKS5vdXRlckhlaWdodChlLm91dGVySGVpZ2h0KCkpLm9mZnNldChlLm9mZnNldCgpKVswXX0pfSxfdW5ibG9ja0ZyYW1lczpmdW5jdGlvbigpe3RoaXMuaWZyYW1lQmxvY2tzJiYodGhpcy5pZnJhbWVCbG9ja3MucmVtb3ZlKCksZGVsZXRlIHRoaXMuaWZyYW1lQmxvY2tzKX0sX2JsdXJBY3RpdmVFbGVtZW50OmZ1bmN0aW9uKGUpe3ZhciBpPXQudWkuc2FmZUFjdGl2ZUVsZW1lbnQodGhpcy5kb2N1bWVudFswXSkscz10KGUudGFyZ2V0KTtzLmNsb3Nlc3QoaSkubGVuZ3RofHx0LnVpLnNhZmVCbHVyKGkpfSxfbW91c2VTdGFydDpmdW5jdGlvbihlKXt2YXIgaT10aGlzLm9wdGlvbnM7cmV0dXJuIHRoaXMuaGVscGVyPXRoaXMuX2NyZWF0ZUhlbHBlcihlKSx0aGlzLl9hZGRDbGFzcyh0aGlzLmhlbHBlcixcInVpLWRyYWdnYWJsZS1kcmFnZ2luZ1wiKSx0aGlzLl9jYWNoZUhlbHBlclByb3BvcnRpb25zKCksdC51aS5kZG1hbmFnZXImJih0LnVpLmRkbWFuYWdlci5jdXJyZW50PXRoaXMpLHRoaXMuX2NhY2hlTWFyZ2lucygpLHRoaXMuY3NzUG9zaXRpb249dGhpcy5oZWxwZXIuY3NzKFwicG9zaXRpb25cIiksdGhpcy5zY3JvbGxQYXJlbnQ9dGhpcy5oZWxwZXIuc2Nyb2xsUGFyZW50KCEwKSx0aGlzLm9mZnNldFBhcmVudD10aGlzLmhlbHBlci5vZmZzZXRQYXJlbnQoKSx0aGlzLmhhc0ZpeGVkQW5jZXN0b3I9dGhpcy5oZWxwZXIucGFyZW50cygpLmZpbHRlcihmdW5jdGlvbigpe3JldHVyblwiZml4ZWRcIj09PXQodGhpcykuY3NzKFwicG9zaXRpb25cIil9KS5sZW5ndGg+MCx0aGlzLnBvc2l0aW9uQWJzPXRoaXMuZWxlbWVudC5vZmZzZXQoKSx0aGlzLl9yZWZyZXNoT2Zmc2V0cyhlKSx0aGlzLm9yaWdpbmFsUG9zaXRpb249dGhpcy5wb3NpdGlvbj10aGlzLl9nZW5lcmF0ZVBvc2l0aW9uKGUsITEpLHRoaXMub3JpZ2luYWxQYWdlWD1lLnBhZ2VYLHRoaXMub3JpZ2luYWxQYWdlWT1lLnBhZ2VZLGkuY3Vyc29yQXQmJnRoaXMuX2FkanVzdE9mZnNldEZyb21IZWxwZXIoaS5jdXJzb3JBdCksdGhpcy5fc2V0Q29udGFpbm1lbnQoKSx0aGlzLl90cmlnZ2VyKFwic3RhcnRcIixlKT09PSExPyh0aGlzLl9jbGVhcigpLCExKToodGhpcy5fY2FjaGVIZWxwZXJQcm9wb3J0aW9ucygpLHQudWkuZGRtYW5hZ2VyJiYhaS5kcm9wQmVoYXZpb3VyJiZ0LnVpLmRkbWFuYWdlci5wcmVwYXJlT2Zmc2V0cyh0aGlzLGUpLHRoaXMuX21vdXNlRHJhZyhlLCEwKSx0LnVpLmRkbWFuYWdlciYmdC51aS5kZG1hbmFnZXIuZHJhZ1N0YXJ0KHRoaXMsZSksITApfSxfcmVmcmVzaE9mZnNldHM6ZnVuY3Rpb24odCl7dGhpcy5vZmZzZXQ9e3RvcDp0aGlzLnBvc2l0aW9uQWJzLnRvcC10aGlzLm1hcmdpbnMudG9wLGxlZnQ6dGhpcy5wb3NpdGlvbkFicy5sZWZ0LXRoaXMubWFyZ2lucy5sZWZ0LHNjcm9sbDohMSxwYXJlbnQ6dGhpcy5fZ2V0UGFyZW50T2Zmc2V0KCkscmVsYXRpdmU6dGhpcy5fZ2V0UmVsYXRpdmVPZmZzZXQoKX0sdGhpcy5vZmZzZXQuY2xpY2s9e2xlZnQ6dC5wYWdlWC10aGlzLm9mZnNldC5sZWZ0LHRvcDp0LnBhZ2VZLXRoaXMub2Zmc2V0LnRvcH19LF9tb3VzZURyYWc6ZnVuY3Rpb24oZSxpKXtpZih0aGlzLmhhc0ZpeGVkQW5jZXN0b3ImJih0aGlzLm9mZnNldC5wYXJlbnQ9dGhpcy5fZ2V0UGFyZW50T2Zmc2V0KCkpLHRoaXMucG9zaXRpb249dGhpcy5fZ2VuZXJhdGVQb3NpdGlvbihlLCEwKSx0aGlzLnBvc2l0aW9uQWJzPXRoaXMuX2NvbnZlcnRQb3NpdGlvblRvKFwiYWJzb2x1dGVcIiksIWkpe3ZhciBzPXRoaXMuX3VpSGFzaCgpO2lmKHRoaXMuX3RyaWdnZXIoXCJkcmFnXCIsZSxzKT09PSExKXJldHVybiB0aGlzLl9tb3VzZVVwKG5ldyB0LkV2ZW50KFwibW91c2V1cFwiLGUpKSwhMTt0aGlzLnBvc2l0aW9uPXMucG9zaXRpb259cmV0dXJuIHRoaXMuaGVscGVyWzBdLnN0eWxlLmxlZnQ9dGhpcy5wb3NpdGlvbi5sZWZ0K1wicHhcIix0aGlzLmhlbHBlclswXS5zdHlsZS50b3A9dGhpcy5wb3NpdGlvbi50b3ArXCJweFwiLHQudWkuZGRtYW5hZ2VyJiZ0LnVpLmRkbWFuYWdlci5kcmFnKHRoaXMsZSksITF9LF9tb3VzZVN0b3A6ZnVuY3Rpb24oZSl7dmFyIGk9dGhpcyxzPSExO3JldHVybiB0LnVpLmRkbWFuYWdlciYmIXRoaXMub3B0aW9ucy5kcm9wQmVoYXZpb3VyJiYocz10LnVpLmRkbWFuYWdlci5kcm9wKHRoaXMsZSkpLHRoaXMuZHJvcHBlZCYmKHM9dGhpcy5kcm9wcGVkLHRoaXMuZHJvcHBlZD0hMSksXCJpbnZhbGlkXCI9PT10aGlzLm9wdGlvbnMucmV2ZXJ0JiYhc3x8XCJ2YWxpZFwiPT09dGhpcy5vcHRpb25zLnJldmVydCYmc3x8dGhpcy5vcHRpb25zLnJldmVydD09PSEwfHx0LmlzRnVuY3Rpb24odGhpcy5vcHRpb25zLnJldmVydCkmJnRoaXMub3B0aW9ucy5yZXZlcnQuY2FsbCh0aGlzLmVsZW1lbnQscyk/dCh0aGlzLmhlbHBlcikuYW5pbWF0ZSh0aGlzLm9yaWdpbmFsUG9zaXRpb24scGFyc2VJbnQodGhpcy5vcHRpb25zLnJldmVydER1cmF0aW9uLDEwKSxmdW5jdGlvbigpe2kuX3RyaWdnZXIoXCJzdG9wXCIsZSkhPT0hMSYmaS5fY2xlYXIoKX0pOnRoaXMuX3RyaWdnZXIoXCJzdG9wXCIsZSkhPT0hMSYmdGhpcy5fY2xlYXIoKSwhMX0sX21vdXNlVXA6ZnVuY3Rpb24oZSl7cmV0dXJuIHRoaXMuX3VuYmxvY2tGcmFtZXMoKSx0LnVpLmRkbWFuYWdlciYmdC51aS5kZG1hbmFnZXIuZHJhZ1N0b3AodGhpcyxlKSx0aGlzLmhhbmRsZUVsZW1lbnQuaXMoZS50YXJnZXQpJiZ0aGlzLmVsZW1lbnQudHJpZ2dlcihcImZvY3VzXCIpLHQudWkubW91c2UucHJvdG90eXBlLl9tb3VzZVVwLmNhbGwodGhpcyxlKX0sY2FuY2VsOmZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMuaGVscGVyLmlzKFwiLnVpLWRyYWdnYWJsZS1kcmFnZ2luZ1wiKT90aGlzLl9tb3VzZVVwKG5ldyB0LkV2ZW50KFwibW91c2V1cFwiLHt0YXJnZXQ6dGhpcy5lbGVtZW50WzBdfSkpOnRoaXMuX2NsZWFyKCksdGhpc30sX2dldEhhbmRsZTpmdW5jdGlvbihlKXtyZXR1cm4gdGhpcy5vcHRpb25zLmhhbmRsZT8hIXQoZS50YXJnZXQpLmNsb3Nlc3QodGhpcy5lbGVtZW50LmZpbmQodGhpcy5vcHRpb25zLmhhbmRsZSkpLmxlbmd0aDohMH0sX3NldEhhbmRsZUNsYXNzTmFtZTpmdW5jdGlvbigpe3RoaXMuaGFuZGxlRWxlbWVudD10aGlzLm9wdGlvbnMuaGFuZGxlP3RoaXMuZWxlbWVudC5maW5kKHRoaXMub3B0aW9ucy5oYW5kbGUpOnRoaXMuZWxlbWVudCx0aGlzLl9hZGRDbGFzcyh0aGlzLmhhbmRsZUVsZW1lbnQsXCJ1aS1kcmFnZ2FibGUtaGFuZGxlXCIpfSxfcmVtb3ZlSGFuZGxlQ2xhc3NOYW1lOmZ1bmN0aW9uKCl7dGhpcy5fcmVtb3ZlQ2xhc3ModGhpcy5oYW5kbGVFbGVtZW50LFwidWktZHJhZ2dhYmxlLWhhbmRsZVwiKX0sX2NyZWF0ZUhlbHBlcjpmdW5jdGlvbihlKXt2YXIgaT10aGlzLm9wdGlvbnMscz10LmlzRnVuY3Rpb24oaS5oZWxwZXIpLG49cz90KGkuaGVscGVyLmFwcGx5KHRoaXMuZWxlbWVudFswXSxbZV0pKTpcImNsb25lXCI9PT1pLmhlbHBlcj90aGlzLmVsZW1lbnQuY2xvbmUoKS5yZW1vdmVBdHRyKFwiaWRcIik6dGhpcy5lbGVtZW50O3JldHVybiBuLnBhcmVudHMoXCJib2R5XCIpLmxlbmd0aHx8bi5hcHBlbmRUbyhcInBhcmVudFwiPT09aS5hcHBlbmRUbz90aGlzLmVsZW1lbnRbMF0ucGFyZW50Tm9kZTppLmFwcGVuZFRvKSxzJiZuWzBdPT09dGhpcy5lbGVtZW50WzBdJiZ0aGlzLl9zZXRQb3NpdGlvblJlbGF0aXZlKCksblswXT09PXRoaXMuZWxlbWVudFswXXx8LyhmaXhlZHxhYnNvbHV0ZSkvLnRlc3Qobi5jc3MoXCJwb3NpdGlvblwiKSl8fG4uY3NzKFwicG9zaXRpb25cIixcImFic29sdXRlXCIpLG59LF9zZXRQb3NpdGlvblJlbGF0aXZlOmZ1bmN0aW9uKCl7L14oPzpyfGF8ZikvLnRlc3QodGhpcy5lbGVtZW50LmNzcyhcInBvc2l0aW9uXCIpKXx8KHRoaXMuZWxlbWVudFswXS5zdHlsZS5wb3NpdGlvbj1cInJlbGF0aXZlXCIpfSxfYWRqdXN0T2Zmc2V0RnJvbUhlbHBlcjpmdW5jdGlvbihlKXtcInN0cmluZ1wiPT10eXBlb2YgZSYmKGU9ZS5zcGxpdChcIiBcIikpLHQuaXNBcnJheShlKSYmKGU9e2xlZnQ6K2VbMF0sdG9wOitlWzFdfHwwfSksXCJsZWZ0XCJpbiBlJiYodGhpcy5vZmZzZXQuY2xpY2subGVmdD1lLmxlZnQrdGhpcy5tYXJnaW5zLmxlZnQpLFwicmlnaHRcImluIGUmJih0aGlzLm9mZnNldC5jbGljay5sZWZ0PXRoaXMuaGVscGVyUHJvcG9ydGlvbnMud2lkdGgtZS5yaWdodCt0aGlzLm1hcmdpbnMubGVmdCksXCJ0b3BcImluIGUmJih0aGlzLm9mZnNldC5jbGljay50b3A9ZS50b3ArdGhpcy5tYXJnaW5zLnRvcCksXCJib3R0b21cImluIGUmJih0aGlzLm9mZnNldC5jbGljay50b3A9dGhpcy5oZWxwZXJQcm9wb3J0aW9ucy5oZWlnaHQtZS5ib3R0b20rdGhpcy5tYXJnaW5zLnRvcCl9LF9pc1Jvb3ROb2RlOmZ1bmN0aW9uKHQpe3JldHVybi8oaHRtbHxib2R5KS9pLnRlc3QodC50YWdOYW1lKXx8dD09PXRoaXMuZG9jdW1lbnRbMF19LF9nZXRQYXJlbnRPZmZzZXQ6ZnVuY3Rpb24oKXt2YXIgZT10aGlzLm9mZnNldFBhcmVudC5vZmZzZXQoKSxpPXRoaXMuZG9jdW1lbnRbMF07cmV0dXJuXCJhYnNvbHV0ZVwiPT09dGhpcy5jc3NQb3NpdGlvbiYmdGhpcy5zY3JvbGxQYXJlbnRbMF0hPT1pJiZ0LmNvbnRhaW5zKHRoaXMuc2Nyb2xsUGFyZW50WzBdLHRoaXMub2Zmc2V0UGFyZW50WzBdKSYmKGUubGVmdCs9dGhpcy5zY3JvbGxQYXJlbnQuc2Nyb2xsTGVmdCgpLGUudG9wKz10aGlzLnNjcm9sbFBhcmVudC5zY3JvbGxUb3AoKSksdGhpcy5faXNSb290Tm9kZSh0aGlzLm9mZnNldFBhcmVudFswXSkmJihlPXt0b3A6MCxsZWZ0OjB9KSx7dG9wOmUudG9wKyhwYXJzZUludCh0aGlzLm9mZnNldFBhcmVudC5jc3MoXCJib3JkZXJUb3BXaWR0aFwiKSwxMCl8fDApLGxlZnQ6ZS5sZWZ0KyhwYXJzZUludCh0aGlzLm9mZnNldFBhcmVudC5jc3MoXCJib3JkZXJMZWZ0V2lkdGhcIiksMTApfHwwKX19LF9nZXRSZWxhdGl2ZU9mZnNldDpmdW5jdGlvbigpe2lmKFwicmVsYXRpdmVcIiE9PXRoaXMuY3NzUG9zaXRpb24pcmV0dXJue3RvcDowLGxlZnQ6MH07dmFyIHQ9dGhpcy5lbGVtZW50LnBvc2l0aW9uKCksZT10aGlzLl9pc1Jvb3ROb2RlKHRoaXMuc2Nyb2xsUGFyZW50WzBdKTtyZXR1cm57dG9wOnQudG9wLShwYXJzZUludCh0aGlzLmhlbHBlci5jc3MoXCJ0b3BcIiksMTApfHwwKSsoZT8wOnRoaXMuc2Nyb2xsUGFyZW50LnNjcm9sbFRvcCgpKSxsZWZ0OnQubGVmdC0ocGFyc2VJbnQodGhpcy5oZWxwZXIuY3NzKFwibGVmdFwiKSwxMCl8fDApKyhlPzA6dGhpcy5zY3JvbGxQYXJlbnQuc2Nyb2xsTGVmdCgpKX19LF9jYWNoZU1hcmdpbnM6ZnVuY3Rpb24oKXt0aGlzLm1hcmdpbnM9e2xlZnQ6cGFyc2VJbnQodGhpcy5lbGVtZW50LmNzcyhcIm1hcmdpbkxlZnRcIiksMTApfHwwLHRvcDpwYXJzZUludCh0aGlzLmVsZW1lbnQuY3NzKFwibWFyZ2luVG9wXCIpLDEwKXx8MCxyaWdodDpwYXJzZUludCh0aGlzLmVsZW1lbnQuY3NzKFwibWFyZ2luUmlnaHRcIiksMTApfHwwLGJvdHRvbTpwYXJzZUludCh0aGlzLmVsZW1lbnQuY3NzKFwibWFyZ2luQm90dG9tXCIpLDEwKXx8MH19LF9jYWNoZUhlbHBlclByb3BvcnRpb25zOmZ1bmN0aW9uKCl7dGhpcy5oZWxwZXJQcm9wb3J0aW9ucz17d2lkdGg6dGhpcy5oZWxwZXIub3V0ZXJXaWR0aCgpLGhlaWdodDp0aGlzLmhlbHBlci5vdXRlckhlaWdodCgpfX0sX3NldENvbnRhaW5tZW50OmZ1bmN0aW9uKCl7dmFyIGUsaSxzLG49dGhpcy5vcHRpb25zLG89dGhpcy5kb2N1bWVudFswXTtyZXR1cm4gdGhpcy5yZWxhdGl2ZUNvbnRhaW5lcj1udWxsLG4uY29udGFpbm1lbnQ/XCJ3aW5kb3dcIj09PW4uY29udGFpbm1lbnQ/KHRoaXMuY29udGFpbm1lbnQ9W3Qod2luZG93KS5zY3JvbGxMZWZ0KCktdGhpcy5vZmZzZXQucmVsYXRpdmUubGVmdC10aGlzLm9mZnNldC5wYXJlbnQubGVmdCx0KHdpbmRvdykuc2Nyb2xsVG9wKCktdGhpcy5vZmZzZXQucmVsYXRpdmUudG9wLXRoaXMub2Zmc2V0LnBhcmVudC50b3AsdCh3aW5kb3cpLnNjcm9sbExlZnQoKSt0KHdpbmRvdykud2lkdGgoKS10aGlzLmhlbHBlclByb3BvcnRpb25zLndpZHRoLXRoaXMubWFyZ2lucy5sZWZ0LHQod2luZG93KS5zY3JvbGxUb3AoKSsodCh3aW5kb3cpLmhlaWdodCgpfHxvLmJvZHkucGFyZW50Tm9kZS5zY3JvbGxIZWlnaHQpLXRoaXMuaGVscGVyUHJvcG9ydGlvbnMuaGVpZ2h0LXRoaXMubWFyZ2lucy50b3BdLHZvaWQgMCk6XCJkb2N1bWVudFwiPT09bi5jb250YWlubWVudD8odGhpcy5jb250YWlubWVudD1bMCwwLHQobykud2lkdGgoKS10aGlzLmhlbHBlclByb3BvcnRpb25zLndpZHRoLXRoaXMubWFyZ2lucy5sZWZ0LCh0KG8pLmhlaWdodCgpfHxvLmJvZHkucGFyZW50Tm9kZS5zY3JvbGxIZWlnaHQpLXRoaXMuaGVscGVyUHJvcG9ydGlvbnMuaGVpZ2h0LXRoaXMubWFyZ2lucy50b3BdLHZvaWQgMCk6bi5jb250YWlubWVudC5jb25zdHJ1Y3Rvcj09PUFycmF5Pyh0aGlzLmNvbnRhaW5tZW50PW4uY29udGFpbm1lbnQsdm9pZCAwKTooXCJwYXJlbnRcIj09PW4uY29udGFpbm1lbnQmJihuLmNvbnRhaW5tZW50PXRoaXMuaGVscGVyWzBdLnBhcmVudE5vZGUpLGk9dChuLmNvbnRhaW5tZW50KSxzPWlbMF0scyYmKGU9LyhzY3JvbGx8YXV0bykvLnRlc3QoaS5jc3MoXCJvdmVyZmxvd1wiKSksdGhpcy5jb250YWlubWVudD1bKHBhcnNlSW50KGkuY3NzKFwiYm9yZGVyTGVmdFdpZHRoXCIpLDEwKXx8MCkrKHBhcnNlSW50KGkuY3NzKFwicGFkZGluZ0xlZnRcIiksMTApfHwwKSwocGFyc2VJbnQoaS5jc3MoXCJib3JkZXJUb3BXaWR0aFwiKSwxMCl8fDApKyhwYXJzZUludChpLmNzcyhcInBhZGRpbmdUb3BcIiksMTApfHwwKSwoZT9NYXRoLm1heChzLnNjcm9sbFdpZHRoLHMub2Zmc2V0V2lkdGgpOnMub2Zmc2V0V2lkdGgpLShwYXJzZUludChpLmNzcyhcImJvcmRlclJpZ2h0V2lkdGhcIiksMTApfHwwKS0ocGFyc2VJbnQoaS5jc3MoXCJwYWRkaW5nUmlnaHRcIiksMTApfHwwKS10aGlzLmhlbHBlclByb3BvcnRpb25zLndpZHRoLXRoaXMubWFyZ2lucy5sZWZ0LXRoaXMubWFyZ2lucy5yaWdodCwoZT9NYXRoLm1heChzLnNjcm9sbEhlaWdodCxzLm9mZnNldEhlaWdodCk6cy5vZmZzZXRIZWlnaHQpLShwYXJzZUludChpLmNzcyhcImJvcmRlckJvdHRvbVdpZHRoXCIpLDEwKXx8MCktKHBhcnNlSW50KGkuY3NzKFwicGFkZGluZ0JvdHRvbVwiKSwxMCl8fDApLXRoaXMuaGVscGVyUHJvcG9ydGlvbnMuaGVpZ2h0LXRoaXMubWFyZ2lucy50b3AtdGhpcy5tYXJnaW5zLmJvdHRvbV0sdGhpcy5yZWxhdGl2ZUNvbnRhaW5lcj1pKSx2b2lkIDApOih0aGlzLmNvbnRhaW5tZW50PW51bGwsdm9pZCAwKVxufSxfY29udmVydFBvc2l0aW9uVG86ZnVuY3Rpb24odCxlKXtlfHwoZT10aGlzLnBvc2l0aW9uKTt2YXIgaT1cImFic29sdXRlXCI9PT10PzE6LTEscz10aGlzLl9pc1Jvb3ROb2RlKHRoaXMuc2Nyb2xsUGFyZW50WzBdKTtyZXR1cm57dG9wOmUudG9wK3RoaXMub2Zmc2V0LnJlbGF0aXZlLnRvcCppK3RoaXMub2Zmc2V0LnBhcmVudC50b3AqaS0oXCJmaXhlZFwiPT09dGhpcy5jc3NQb3NpdGlvbj8tdGhpcy5vZmZzZXQuc2Nyb2xsLnRvcDpzPzA6dGhpcy5vZmZzZXQuc2Nyb2xsLnRvcCkqaSxsZWZ0OmUubGVmdCt0aGlzLm9mZnNldC5yZWxhdGl2ZS5sZWZ0KmkrdGhpcy5vZmZzZXQucGFyZW50LmxlZnQqaS0oXCJmaXhlZFwiPT09dGhpcy5jc3NQb3NpdGlvbj8tdGhpcy5vZmZzZXQuc2Nyb2xsLmxlZnQ6cz8wOnRoaXMub2Zmc2V0LnNjcm9sbC5sZWZ0KSppfX0sX2dlbmVyYXRlUG9zaXRpb246ZnVuY3Rpb24odCxlKXt2YXIgaSxzLG4sbyxhPXRoaXMub3B0aW9ucyxyPXRoaXMuX2lzUm9vdE5vZGUodGhpcy5zY3JvbGxQYXJlbnRbMF0pLGg9dC5wYWdlWCxsPXQucGFnZVk7cmV0dXJuIHImJnRoaXMub2Zmc2V0LnNjcm9sbHx8KHRoaXMub2Zmc2V0LnNjcm9sbD17dG9wOnRoaXMuc2Nyb2xsUGFyZW50LnNjcm9sbFRvcCgpLGxlZnQ6dGhpcy5zY3JvbGxQYXJlbnQuc2Nyb2xsTGVmdCgpfSksZSYmKHRoaXMuY29udGFpbm1lbnQmJih0aGlzLnJlbGF0aXZlQ29udGFpbmVyPyhzPXRoaXMucmVsYXRpdmVDb250YWluZXIub2Zmc2V0KCksaT1bdGhpcy5jb250YWlubWVudFswXStzLmxlZnQsdGhpcy5jb250YWlubWVudFsxXStzLnRvcCx0aGlzLmNvbnRhaW5tZW50WzJdK3MubGVmdCx0aGlzLmNvbnRhaW5tZW50WzNdK3MudG9wXSk6aT10aGlzLmNvbnRhaW5tZW50LHQucGFnZVgtdGhpcy5vZmZzZXQuY2xpY2subGVmdDxpWzBdJiYoaD1pWzBdK3RoaXMub2Zmc2V0LmNsaWNrLmxlZnQpLHQucGFnZVktdGhpcy5vZmZzZXQuY2xpY2sudG9wPGlbMV0mJihsPWlbMV0rdGhpcy5vZmZzZXQuY2xpY2sudG9wKSx0LnBhZ2VYLXRoaXMub2Zmc2V0LmNsaWNrLmxlZnQ+aVsyXSYmKGg9aVsyXSt0aGlzLm9mZnNldC5jbGljay5sZWZ0KSx0LnBhZ2VZLXRoaXMub2Zmc2V0LmNsaWNrLnRvcD5pWzNdJiYobD1pWzNdK3RoaXMub2Zmc2V0LmNsaWNrLnRvcCkpLGEuZ3JpZCYmKG49YS5ncmlkWzFdP3RoaXMub3JpZ2luYWxQYWdlWStNYXRoLnJvdW5kKChsLXRoaXMub3JpZ2luYWxQYWdlWSkvYS5ncmlkWzFdKSphLmdyaWRbMV06dGhpcy5vcmlnaW5hbFBhZ2VZLGw9aT9uLXRoaXMub2Zmc2V0LmNsaWNrLnRvcD49aVsxXXx8bi10aGlzLm9mZnNldC5jbGljay50b3A+aVszXT9uOm4tdGhpcy5vZmZzZXQuY2xpY2sudG9wPj1pWzFdP24tYS5ncmlkWzFdOm4rYS5ncmlkWzFdOm4sbz1hLmdyaWRbMF0/dGhpcy5vcmlnaW5hbFBhZ2VYK01hdGgucm91bmQoKGgtdGhpcy5vcmlnaW5hbFBhZ2VYKS9hLmdyaWRbMF0pKmEuZ3JpZFswXTp0aGlzLm9yaWdpbmFsUGFnZVgsaD1pP28tdGhpcy5vZmZzZXQuY2xpY2subGVmdD49aVswXXx8by10aGlzLm9mZnNldC5jbGljay5sZWZ0PmlbMl0/bzpvLXRoaXMub2Zmc2V0LmNsaWNrLmxlZnQ+PWlbMF0/by1hLmdyaWRbMF06bythLmdyaWRbMF06byksXCJ5XCI9PT1hLmF4aXMmJihoPXRoaXMub3JpZ2luYWxQYWdlWCksXCJ4XCI9PT1hLmF4aXMmJihsPXRoaXMub3JpZ2luYWxQYWdlWSkpLHt0b3A6bC10aGlzLm9mZnNldC5jbGljay50b3AtdGhpcy5vZmZzZXQucmVsYXRpdmUudG9wLXRoaXMub2Zmc2V0LnBhcmVudC50b3ArKFwiZml4ZWRcIj09PXRoaXMuY3NzUG9zaXRpb24/LXRoaXMub2Zmc2V0LnNjcm9sbC50b3A6cj8wOnRoaXMub2Zmc2V0LnNjcm9sbC50b3ApLGxlZnQ6aC10aGlzLm9mZnNldC5jbGljay5sZWZ0LXRoaXMub2Zmc2V0LnJlbGF0aXZlLmxlZnQtdGhpcy5vZmZzZXQucGFyZW50LmxlZnQrKFwiZml4ZWRcIj09PXRoaXMuY3NzUG9zaXRpb24/LXRoaXMub2Zmc2V0LnNjcm9sbC5sZWZ0OnI/MDp0aGlzLm9mZnNldC5zY3JvbGwubGVmdCl9fSxfY2xlYXI6ZnVuY3Rpb24oKXt0aGlzLl9yZW1vdmVDbGFzcyh0aGlzLmhlbHBlcixcInVpLWRyYWdnYWJsZS1kcmFnZ2luZ1wiKSx0aGlzLmhlbHBlclswXT09PXRoaXMuZWxlbWVudFswXXx8dGhpcy5jYW5jZWxIZWxwZXJSZW1vdmFsfHx0aGlzLmhlbHBlci5yZW1vdmUoKSx0aGlzLmhlbHBlcj1udWxsLHRoaXMuY2FuY2VsSGVscGVyUmVtb3ZhbD0hMSx0aGlzLmRlc3Ryb3lPbkNsZWFyJiZ0aGlzLmRlc3Ryb3koKX0sX3RyaWdnZXI6ZnVuY3Rpb24oZSxpLHMpe3JldHVybiBzPXN8fHRoaXMuX3VpSGFzaCgpLHQudWkucGx1Z2luLmNhbGwodGhpcyxlLFtpLHMsdGhpc10sITApLC9eKGRyYWd8c3RhcnR8c3RvcCkvLnRlc3QoZSkmJih0aGlzLnBvc2l0aW9uQWJzPXRoaXMuX2NvbnZlcnRQb3NpdGlvblRvKFwiYWJzb2x1dGVcIikscy5vZmZzZXQ9dGhpcy5wb3NpdGlvbkFicyksdC5XaWRnZXQucHJvdG90eXBlLl90cmlnZ2VyLmNhbGwodGhpcyxlLGkscyl9LHBsdWdpbnM6e30sX3VpSGFzaDpmdW5jdGlvbigpe3JldHVybntoZWxwZXI6dGhpcy5oZWxwZXIscG9zaXRpb246dGhpcy5wb3NpdGlvbixvcmlnaW5hbFBvc2l0aW9uOnRoaXMub3JpZ2luYWxQb3NpdGlvbixvZmZzZXQ6dGhpcy5wb3NpdGlvbkFic319fSksdC51aS5wbHVnaW4uYWRkKFwiZHJhZ2dhYmxlXCIsXCJjb25uZWN0VG9Tb3J0YWJsZVwiLHtzdGFydDpmdW5jdGlvbihlLGkscyl7dmFyIG49dC5leHRlbmQoe30saSx7aXRlbTpzLmVsZW1lbnR9KTtzLnNvcnRhYmxlcz1bXSx0KHMub3B0aW9ucy5jb25uZWN0VG9Tb3J0YWJsZSkuZWFjaChmdW5jdGlvbigpe3ZhciBpPXQodGhpcykuc29ydGFibGUoXCJpbnN0YW5jZVwiKTtpJiYhaS5vcHRpb25zLmRpc2FibGVkJiYocy5zb3J0YWJsZXMucHVzaChpKSxpLnJlZnJlc2hQb3NpdGlvbnMoKSxpLl90cmlnZ2VyKFwiYWN0aXZhdGVcIixlLG4pKX0pfSxzdG9wOmZ1bmN0aW9uKGUsaSxzKXt2YXIgbj10LmV4dGVuZCh7fSxpLHtpdGVtOnMuZWxlbWVudH0pO3MuY2FuY2VsSGVscGVyUmVtb3ZhbD0hMSx0LmVhY2gocy5zb3J0YWJsZXMsZnVuY3Rpb24oKXt2YXIgdD10aGlzO3QuaXNPdmVyPyh0LmlzT3Zlcj0wLHMuY2FuY2VsSGVscGVyUmVtb3ZhbD0hMCx0LmNhbmNlbEhlbHBlclJlbW92YWw9ITEsdC5fc3RvcmVkQ1NTPXtwb3NpdGlvbjp0LnBsYWNlaG9sZGVyLmNzcyhcInBvc2l0aW9uXCIpLHRvcDp0LnBsYWNlaG9sZGVyLmNzcyhcInRvcFwiKSxsZWZ0OnQucGxhY2Vob2xkZXIuY3NzKFwibGVmdFwiKX0sdC5fbW91c2VTdG9wKGUpLHQub3B0aW9ucy5oZWxwZXI9dC5vcHRpb25zLl9oZWxwZXIpOih0LmNhbmNlbEhlbHBlclJlbW92YWw9ITAsdC5fdHJpZ2dlcihcImRlYWN0aXZhdGVcIixlLG4pKX0pfSxkcmFnOmZ1bmN0aW9uKGUsaSxzKXt0LmVhY2gocy5zb3J0YWJsZXMsZnVuY3Rpb24oKXt2YXIgbj0hMSxvPXRoaXM7by5wb3NpdGlvbkFicz1zLnBvc2l0aW9uQWJzLG8uaGVscGVyUHJvcG9ydGlvbnM9cy5oZWxwZXJQcm9wb3J0aW9ucyxvLm9mZnNldC5jbGljaz1zLm9mZnNldC5jbGljayxvLl9pbnRlcnNlY3RzV2l0aChvLmNvbnRhaW5lckNhY2hlKSYmKG49ITAsdC5lYWNoKHMuc29ydGFibGVzLGZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMucG9zaXRpb25BYnM9cy5wb3NpdGlvbkFicyx0aGlzLmhlbHBlclByb3BvcnRpb25zPXMuaGVscGVyUHJvcG9ydGlvbnMsdGhpcy5vZmZzZXQuY2xpY2s9cy5vZmZzZXQuY2xpY2ssdGhpcyE9PW8mJnRoaXMuX2ludGVyc2VjdHNXaXRoKHRoaXMuY29udGFpbmVyQ2FjaGUpJiZ0LmNvbnRhaW5zKG8uZWxlbWVudFswXSx0aGlzLmVsZW1lbnRbMF0pJiYobj0hMSksbn0pKSxuPyhvLmlzT3Zlcnx8KG8uaXNPdmVyPTEscy5fcGFyZW50PWkuaGVscGVyLnBhcmVudCgpLG8uY3VycmVudEl0ZW09aS5oZWxwZXIuYXBwZW5kVG8oby5lbGVtZW50KS5kYXRhKFwidWktc29ydGFibGUtaXRlbVwiLCEwKSxvLm9wdGlvbnMuX2hlbHBlcj1vLm9wdGlvbnMuaGVscGVyLG8ub3B0aW9ucy5oZWxwZXI9ZnVuY3Rpb24oKXtyZXR1cm4gaS5oZWxwZXJbMF19LGUudGFyZ2V0PW8uY3VycmVudEl0ZW1bMF0sby5fbW91c2VDYXB0dXJlKGUsITApLG8uX21vdXNlU3RhcnQoZSwhMCwhMCksby5vZmZzZXQuY2xpY2sudG9wPXMub2Zmc2V0LmNsaWNrLnRvcCxvLm9mZnNldC5jbGljay5sZWZ0PXMub2Zmc2V0LmNsaWNrLmxlZnQsby5vZmZzZXQucGFyZW50LmxlZnQtPXMub2Zmc2V0LnBhcmVudC5sZWZ0LW8ub2Zmc2V0LnBhcmVudC5sZWZ0LG8ub2Zmc2V0LnBhcmVudC50b3AtPXMub2Zmc2V0LnBhcmVudC50b3Atby5vZmZzZXQucGFyZW50LnRvcCxzLl90cmlnZ2VyKFwidG9Tb3J0YWJsZVwiLGUpLHMuZHJvcHBlZD1vLmVsZW1lbnQsdC5lYWNoKHMuc29ydGFibGVzLGZ1bmN0aW9uKCl7dGhpcy5yZWZyZXNoUG9zaXRpb25zKCl9KSxzLmN1cnJlbnRJdGVtPXMuZWxlbWVudCxvLmZyb21PdXRzaWRlPXMpLG8uY3VycmVudEl0ZW0mJihvLl9tb3VzZURyYWcoZSksaS5wb3NpdGlvbj1vLnBvc2l0aW9uKSk6by5pc092ZXImJihvLmlzT3Zlcj0wLG8uY2FuY2VsSGVscGVyUmVtb3ZhbD0hMCxvLm9wdGlvbnMuX3JldmVydD1vLm9wdGlvbnMucmV2ZXJ0LG8ub3B0aW9ucy5yZXZlcnQ9ITEsby5fdHJpZ2dlcihcIm91dFwiLGUsby5fdWlIYXNoKG8pKSxvLl9tb3VzZVN0b3AoZSwhMCksby5vcHRpb25zLnJldmVydD1vLm9wdGlvbnMuX3JldmVydCxvLm9wdGlvbnMuaGVscGVyPW8ub3B0aW9ucy5faGVscGVyLG8ucGxhY2Vob2xkZXImJm8ucGxhY2Vob2xkZXIucmVtb3ZlKCksaS5oZWxwZXIuYXBwZW5kVG8ocy5fcGFyZW50KSxzLl9yZWZyZXNoT2Zmc2V0cyhlKSxpLnBvc2l0aW9uPXMuX2dlbmVyYXRlUG9zaXRpb24oZSwhMCkscy5fdHJpZ2dlcihcImZyb21Tb3J0YWJsZVwiLGUpLHMuZHJvcHBlZD0hMSx0LmVhY2gocy5zb3J0YWJsZXMsZnVuY3Rpb24oKXt0aGlzLnJlZnJlc2hQb3NpdGlvbnMoKX0pKX0pfX0pLHQudWkucGx1Z2luLmFkZChcImRyYWdnYWJsZVwiLFwiY3Vyc29yXCIse3N0YXJ0OmZ1bmN0aW9uKGUsaSxzKXt2YXIgbj10KFwiYm9keVwiKSxvPXMub3B0aW9ucztuLmNzcyhcImN1cnNvclwiKSYmKG8uX2N1cnNvcj1uLmNzcyhcImN1cnNvclwiKSksbi5jc3MoXCJjdXJzb3JcIixvLmN1cnNvcil9LHN0b3A6ZnVuY3Rpb24oZSxpLHMpe3ZhciBuPXMub3B0aW9ucztuLl9jdXJzb3ImJnQoXCJib2R5XCIpLmNzcyhcImN1cnNvclwiLG4uX2N1cnNvcil9fSksdC51aS5wbHVnaW4uYWRkKFwiZHJhZ2dhYmxlXCIsXCJvcGFjaXR5XCIse3N0YXJ0OmZ1bmN0aW9uKGUsaSxzKXt2YXIgbj10KGkuaGVscGVyKSxvPXMub3B0aW9ucztuLmNzcyhcIm9wYWNpdHlcIikmJihvLl9vcGFjaXR5PW4uY3NzKFwib3BhY2l0eVwiKSksbi5jc3MoXCJvcGFjaXR5XCIsby5vcGFjaXR5KX0sc3RvcDpmdW5jdGlvbihlLGkscyl7dmFyIG49cy5vcHRpb25zO24uX29wYWNpdHkmJnQoaS5oZWxwZXIpLmNzcyhcIm9wYWNpdHlcIixuLl9vcGFjaXR5KX19KSx0LnVpLnBsdWdpbi5hZGQoXCJkcmFnZ2FibGVcIixcInNjcm9sbFwiLHtzdGFydDpmdW5jdGlvbih0LGUsaSl7aS5zY3JvbGxQYXJlbnROb3RIaWRkZW58fChpLnNjcm9sbFBhcmVudE5vdEhpZGRlbj1pLmhlbHBlci5zY3JvbGxQYXJlbnQoITEpKSxpLnNjcm9sbFBhcmVudE5vdEhpZGRlblswXSE9PWkuZG9jdW1lbnRbMF0mJlwiSFRNTFwiIT09aS5zY3JvbGxQYXJlbnROb3RIaWRkZW5bMF0udGFnTmFtZSYmKGkub3ZlcmZsb3dPZmZzZXQ9aS5zY3JvbGxQYXJlbnROb3RIaWRkZW4ub2Zmc2V0KCkpfSxkcmFnOmZ1bmN0aW9uKGUsaSxzKXt2YXIgbj1zLm9wdGlvbnMsbz0hMSxhPXMuc2Nyb2xsUGFyZW50Tm90SGlkZGVuWzBdLHI9cy5kb2N1bWVudFswXTthIT09ciYmXCJIVE1MXCIhPT1hLnRhZ05hbWU/KG4uYXhpcyYmXCJ4XCI9PT1uLmF4aXN8fChzLm92ZXJmbG93T2Zmc2V0LnRvcCthLm9mZnNldEhlaWdodC1lLnBhZ2VZPG4uc2Nyb2xsU2Vuc2l0aXZpdHk/YS5zY3JvbGxUb3A9bz1hLnNjcm9sbFRvcCtuLnNjcm9sbFNwZWVkOmUucGFnZVktcy5vdmVyZmxvd09mZnNldC50b3A8bi5zY3JvbGxTZW5zaXRpdml0eSYmKGEuc2Nyb2xsVG9wPW89YS5zY3JvbGxUb3Atbi5zY3JvbGxTcGVlZCkpLG4uYXhpcyYmXCJ5XCI9PT1uLmF4aXN8fChzLm92ZXJmbG93T2Zmc2V0LmxlZnQrYS5vZmZzZXRXaWR0aC1lLnBhZ2VYPG4uc2Nyb2xsU2Vuc2l0aXZpdHk/YS5zY3JvbGxMZWZ0PW89YS5zY3JvbGxMZWZ0K24uc2Nyb2xsU3BlZWQ6ZS5wYWdlWC1zLm92ZXJmbG93T2Zmc2V0LmxlZnQ8bi5zY3JvbGxTZW5zaXRpdml0eSYmKGEuc2Nyb2xsTGVmdD1vPWEuc2Nyb2xsTGVmdC1uLnNjcm9sbFNwZWVkKSkpOihuLmF4aXMmJlwieFwiPT09bi5heGlzfHwoZS5wYWdlWS10KHIpLnNjcm9sbFRvcCgpPG4uc2Nyb2xsU2Vuc2l0aXZpdHk/bz10KHIpLnNjcm9sbFRvcCh0KHIpLnNjcm9sbFRvcCgpLW4uc2Nyb2xsU3BlZWQpOnQod2luZG93KS5oZWlnaHQoKS0oZS5wYWdlWS10KHIpLnNjcm9sbFRvcCgpKTxuLnNjcm9sbFNlbnNpdGl2aXR5JiYobz10KHIpLnNjcm9sbFRvcCh0KHIpLnNjcm9sbFRvcCgpK24uc2Nyb2xsU3BlZWQpKSksbi5heGlzJiZcInlcIj09PW4uYXhpc3x8KGUucGFnZVgtdChyKS5zY3JvbGxMZWZ0KCk8bi5zY3JvbGxTZW5zaXRpdml0eT9vPXQocikuc2Nyb2xsTGVmdCh0KHIpLnNjcm9sbExlZnQoKS1uLnNjcm9sbFNwZWVkKTp0KHdpbmRvdykud2lkdGgoKS0oZS5wYWdlWC10KHIpLnNjcm9sbExlZnQoKSk8bi5zY3JvbGxTZW5zaXRpdml0eSYmKG89dChyKS5zY3JvbGxMZWZ0KHQocikuc2Nyb2xsTGVmdCgpK24uc2Nyb2xsU3BlZWQpKSkpLG8hPT0hMSYmdC51aS5kZG1hbmFnZXImJiFuLmRyb3BCZWhhdmlvdXImJnQudWkuZGRtYW5hZ2VyLnByZXBhcmVPZmZzZXRzKHMsZSl9fSksdC51aS5wbHVnaW4uYWRkKFwiZHJhZ2dhYmxlXCIsXCJzbmFwXCIse3N0YXJ0OmZ1bmN0aW9uKGUsaSxzKXt2YXIgbj1zLm9wdGlvbnM7cy5zbmFwRWxlbWVudHM9W10sdChuLnNuYXAuY29uc3RydWN0b3IhPT1TdHJpbmc/bi5zbmFwLml0ZW1zfHxcIjpkYXRhKHVpLWRyYWdnYWJsZSlcIjpuLnNuYXApLmVhY2goZnVuY3Rpb24oKXt2YXIgZT10KHRoaXMpLGk9ZS5vZmZzZXQoKTt0aGlzIT09cy5lbGVtZW50WzBdJiZzLnNuYXBFbGVtZW50cy5wdXNoKHtpdGVtOnRoaXMsd2lkdGg6ZS5vdXRlcldpZHRoKCksaGVpZ2h0OmUub3V0ZXJIZWlnaHQoKSx0b3A6aS50b3AsbGVmdDppLmxlZnR9KX0pfSxkcmFnOmZ1bmN0aW9uKGUsaSxzKXt2YXIgbixvLGEscixoLGwsYyx1LGQscCxmPXMub3B0aW9ucyxnPWYuc25hcFRvbGVyYW5jZSxtPWkub2Zmc2V0LmxlZnQsXz1tK3MuaGVscGVyUHJvcG9ydGlvbnMud2lkdGgsdj1pLm9mZnNldC50b3AsYj12K3MuaGVscGVyUHJvcG9ydGlvbnMuaGVpZ2h0O2ZvcihkPXMuc25hcEVsZW1lbnRzLmxlbmd0aC0xO2Q+PTA7ZC0tKWg9cy5zbmFwRWxlbWVudHNbZF0ubGVmdC1zLm1hcmdpbnMubGVmdCxsPWgrcy5zbmFwRWxlbWVudHNbZF0ud2lkdGgsYz1zLnNuYXBFbGVtZW50c1tkXS50b3Atcy5tYXJnaW5zLnRvcCx1PWMrcy5zbmFwRWxlbWVudHNbZF0uaGVpZ2h0LGgtZz5ffHxtPmwrZ3x8Yy1nPmJ8fHY+dStnfHwhdC5jb250YWlucyhzLnNuYXBFbGVtZW50c1tkXS5pdGVtLm93bmVyRG9jdW1lbnQscy5zbmFwRWxlbWVudHNbZF0uaXRlbSk/KHMuc25hcEVsZW1lbnRzW2RdLnNuYXBwaW5nJiZzLm9wdGlvbnMuc25hcC5yZWxlYXNlJiZzLm9wdGlvbnMuc25hcC5yZWxlYXNlLmNhbGwocy5lbGVtZW50LGUsdC5leHRlbmQocy5fdWlIYXNoKCkse3NuYXBJdGVtOnMuc25hcEVsZW1lbnRzW2RdLml0ZW19KSkscy5zbmFwRWxlbWVudHNbZF0uc25hcHBpbmc9ITEpOihcImlubmVyXCIhPT1mLnNuYXBNb2RlJiYobj1nPj1NYXRoLmFicyhjLWIpLG89Zz49TWF0aC5hYnModS12KSxhPWc+PU1hdGguYWJzKGgtXykscj1nPj1NYXRoLmFicyhsLW0pLG4mJihpLnBvc2l0aW9uLnRvcD1zLl9jb252ZXJ0UG9zaXRpb25UbyhcInJlbGF0aXZlXCIse3RvcDpjLXMuaGVscGVyUHJvcG9ydGlvbnMuaGVpZ2h0LGxlZnQ6MH0pLnRvcCksbyYmKGkucG9zaXRpb24udG9wPXMuX2NvbnZlcnRQb3NpdGlvblRvKFwicmVsYXRpdmVcIix7dG9wOnUsbGVmdDowfSkudG9wKSxhJiYoaS5wb3NpdGlvbi5sZWZ0PXMuX2NvbnZlcnRQb3NpdGlvblRvKFwicmVsYXRpdmVcIix7dG9wOjAsbGVmdDpoLXMuaGVscGVyUHJvcG9ydGlvbnMud2lkdGh9KS5sZWZ0KSxyJiYoaS5wb3NpdGlvbi5sZWZ0PXMuX2NvbnZlcnRQb3NpdGlvblRvKFwicmVsYXRpdmVcIix7dG9wOjAsbGVmdDpsfSkubGVmdCkpLHA9bnx8b3x8YXx8cixcIm91dGVyXCIhPT1mLnNuYXBNb2RlJiYobj1nPj1NYXRoLmFicyhjLXYpLG89Zz49TWF0aC5hYnModS1iKSxhPWc+PU1hdGguYWJzKGgtbSkscj1nPj1NYXRoLmFicyhsLV8pLG4mJihpLnBvc2l0aW9uLnRvcD1zLl9jb252ZXJ0UG9zaXRpb25UbyhcInJlbGF0aXZlXCIse3RvcDpjLGxlZnQ6MH0pLnRvcCksbyYmKGkucG9zaXRpb24udG9wPXMuX2NvbnZlcnRQb3NpdGlvblRvKFwicmVsYXRpdmVcIix7dG9wOnUtcy5oZWxwZXJQcm9wb3J0aW9ucy5oZWlnaHQsbGVmdDowfSkudG9wKSxhJiYoaS5wb3NpdGlvbi5sZWZ0PXMuX2NvbnZlcnRQb3NpdGlvblRvKFwicmVsYXRpdmVcIix7dG9wOjAsbGVmdDpofSkubGVmdCksciYmKGkucG9zaXRpb24ubGVmdD1zLl9jb252ZXJ0UG9zaXRpb25UbyhcInJlbGF0aXZlXCIse3RvcDowLGxlZnQ6bC1zLmhlbHBlclByb3BvcnRpb25zLndpZHRofSkubGVmdCkpLCFzLnNuYXBFbGVtZW50c1tkXS5zbmFwcGluZyYmKG58fG98fGF8fHJ8fHApJiZzLm9wdGlvbnMuc25hcC5zbmFwJiZzLm9wdGlvbnMuc25hcC5zbmFwLmNhbGwocy5lbGVtZW50LGUsdC5leHRlbmQocy5fdWlIYXNoKCkse3NuYXBJdGVtOnMuc25hcEVsZW1lbnRzW2RdLml0ZW19KSkscy5zbmFwRWxlbWVudHNbZF0uc25hcHBpbmc9bnx8b3x8YXx8cnx8cCl9fSksdC51aS5wbHVnaW4uYWRkKFwiZHJhZ2dhYmxlXCIsXCJzdGFja1wiLHtzdGFydDpmdW5jdGlvbihlLGkscyl7dmFyIG4sbz1zLm9wdGlvbnMsYT10Lm1ha2VBcnJheSh0KG8uc3RhY2spKS5zb3J0KGZ1bmN0aW9uKGUsaSl7cmV0dXJuKHBhcnNlSW50KHQoZSkuY3NzKFwiekluZGV4XCIpLDEwKXx8MCktKHBhcnNlSW50KHQoaSkuY3NzKFwiekluZGV4XCIpLDEwKXx8MCl9KTthLmxlbmd0aCYmKG49cGFyc2VJbnQodChhWzBdKS5jc3MoXCJ6SW5kZXhcIiksMTApfHwwLHQoYSkuZWFjaChmdW5jdGlvbihlKXt0KHRoaXMpLmNzcyhcInpJbmRleFwiLG4rZSl9KSx0aGlzLmNzcyhcInpJbmRleFwiLG4rYS5sZW5ndGgpKX19KSx0LnVpLnBsdWdpbi5hZGQoXCJkcmFnZ2FibGVcIixcInpJbmRleFwiLHtzdGFydDpmdW5jdGlvbihlLGkscyl7dmFyIG49dChpLmhlbHBlciksbz1zLm9wdGlvbnM7bi5jc3MoXCJ6SW5kZXhcIikmJihvLl96SW5kZXg9bi5jc3MoXCJ6SW5kZXhcIikpLG4uY3NzKFwiekluZGV4XCIsby56SW5kZXgpfSxzdG9wOmZ1bmN0aW9uKGUsaSxzKXt2YXIgbj1zLm9wdGlvbnM7bi5fekluZGV4JiZ0KGkuaGVscGVyKS5jc3MoXCJ6SW5kZXhcIixuLl96SW5kZXgpfX0pLHQudWkuZHJhZ2dhYmxlLHQud2lkZ2V0KFwidWkuZHJvcHBhYmxlXCIse3ZlcnNpb246XCIxLjEyLjFcIix3aWRnZXRFdmVudFByZWZpeDpcImRyb3BcIixvcHRpb25zOnthY2NlcHQ6XCIqXCIsYWRkQ2xhc3NlczohMCxncmVlZHk6ITEsc2NvcGU6XCJkZWZhdWx0XCIsdG9sZXJhbmNlOlwiaW50ZXJzZWN0XCIsYWN0aXZhdGU6bnVsbCxkZWFjdGl2YXRlOm51bGwsZHJvcDpudWxsLG91dDpudWxsLG92ZXI6bnVsbH0sX2NyZWF0ZTpmdW5jdGlvbigpe3ZhciBlLGk9dGhpcy5vcHRpb25zLHM9aS5hY2NlcHQ7dGhpcy5pc292ZXI9ITEsdGhpcy5pc291dD0hMCx0aGlzLmFjY2VwdD10LmlzRnVuY3Rpb24ocyk/czpmdW5jdGlvbih0KXtyZXR1cm4gdC5pcyhzKX0sdGhpcy5wcm9wb3J0aW9ucz1mdW5jdGlvbigpe3JldHVybiBhcmd1bWVudHMubGVuZ3RoPyhlPWFyZ3VtZW50c1swXSx2b2lkIDApOmU/ZTplPXt3aWR0aDp0aGlzLmVsZW1lbnRbMF0ub2Zmc2V0V2lkdGgsaGVpZ2h0OnRoaXMuZWxlbWVudFswXS5vZmZzZXRIZWlnaHR9fSx0aGlzLl9hZGRUb01hbmFnZXIoaS5zY29wZSksaS5hZGRDbGFzc2VzJiZ0aGlzLl9hZGRDbGFzcyhcInVpLWRyb3BwYWJsZVwiKX0sX2FkZFRvTWFuYWdlcjpmdW5jdGlvbihlKXt0LnVpLmRkbWFuYWdlci5kcm9wcGFibGVzW2VdPXQudWkuZGRtYW5hZ2VyLmRyb3BwYWJsZXNbZV18fFtdLHQudWkuZGRtYW5hZ2VyLmRyb3BwYWJsZXNbZV0ucHVzaCh0aGlzKX0sX3NwbGljZTpmdW5jdGlvbih0KXtmb3IodmFyIGU9MDt0Lmxlbmd0aD5lO2UrKyl0W2VdPT09dGhpcyYmdC5zcGxpY2UoZSwxKX0sX2Rlc3Ryb3k6ZnVuY3Rpb24oKXt2YXIgZT10LnVpLmRkbWFuYWdlci5kcm9wcGFibGVzW3RoaXMub3B0aW9ucy5zY29wZV07dGhpcy5fc3BsaWNlKGUpfSxfc2V0T3B0aW9uOmZ1bmN0aW9uKGUsaSl7aWYoXCJhY2NlcHRcIj09PWUpdGhpcy5hY2NlcHQ9dC5pc0Z1bmN0aW9uKGkpP2k6ZnVuY3Rpb24odCl7cmV0dXJuIHQuaXMoaSl9O2Vsc2UgaWYoXCJzY29wZVwiPT09ZSl7dmFyIHM9dC51aS5kZG1hbmFnZXIuZHJvcHBhYmxlc1t0aGlzLm9wdGlvbnMuc2NvcGVdO3RoaXMuX3NwbGljZShzKSx0aGlzLl9hZGRUb01hbmFnZXIoaSl9dGhpcy5fc3VwZXIoZSxpKX0sX2FjdGl2YXRlOmZ1bmN0aW9uKGUpe3ZhciBpPXQudWkuZGRtYW5hZ2VyLmN1cnJlbnQ7dGhpcy5fYWRkQWN0aXZlQ2xhc3MoKSxpJiZ0aGlzLl90cmlnZ2VyKFwiYWN0aXZhdGVcIixlLHRoaXMudWkoaSkpfSxfZGVhY3RpdmF0ZTpmdW5jdGlvbihlKXt2YXIgaT10LnVpLmRkbWFuYWdlci5jdXJyZW50O3RoaXMuX3JlbW92ZUFjdGl2ZUNsYXNzKCksaSYmdGhpcy5fdHJpZ2dlcihcImRlYWN0aXZhdGVcIixlLHRoaXMudWkoaSkpfSxfb3ZlcjpmdW5jdGlvbihlKXt2YXIgaT10LnVpLmRkbWFuYWdlci5jdXJyZW50O2kmJihpLmN1cnJlbnRJdGVtfHxpLmVsZW1lbnQpWzBdIT09dGhpcy5lbGVtZW50WzBdJiZ0aGlzLmFjY2VwdC5jYWxsKHRoaXMuZWxlbWVudFswXSxpLmN1cnJlbnRJdGVtfHxpLmVsZW1lbnQpJiYodGhpcy5fYWRkSG92ZXJDbGFzcygpLHRoaXMuX3RyaWdnZXIoXCJvdmVyXCIsZSx0aGlzLnVpKGkpKSl9LF9vdXQ6ZnVuY3Rpb24oZSl7dmFyIGk9dC51aS5kZG1hbmFnZXIuY3VycmVudDtpJiYoaS5jdXJyZW50SXRlbXx8aS5lbGVtZW50KVswXSE9PXRoaXMuZWxlbWVudFswXSYmdGhpcy5hY2NlcHQuY2FsbCh0aGlzLmVsZW1lbnRbMF0saS5jdXJyZW50SXRlbXx8aS5lbGVtZW50KSYmKHRoaXMuX3JlbW92ZUhvdmVyQ2xhc3MoKSx0aGlzLl90cmlnZ2VyKFwib3V0XCIsZSx0aGlzLnVpKGkpKSl9LF9kcm9wOmZ1bmN0aW9uKGUsaSl7dmFyIHM9aXx8dC51aS5kZG1hbmFnZXIuY3VycmVudCxuPSExO3JldHVybiBzJiYocy5jdXJyZW50SXRlbXx8cy5lbGVtZW50KVswXSE9PXRoaXMuZWxlbWVudFswXT8odGhpcy5lbGVtZW50LmZpbmQoXCI6ZGF0YSh1aS1kcm9wcGFibGUpXCIpLm5vdChcIi51aS1kcmFnZ2FibGUtZHJhZ2dpbmdcIikuZWFjaChmdW5jdGlvbigpe3ZhciBpPXQodGhpcykuZHJvcHBhYmxlKFwiaW5zdGFuY2VcIik7cmV0dXJuIGkub3B0aW9ucy5ncmVlZHkmJiFpLm9wdGlvbnMuZGlzYWJsZWQmJmkub3B0aW9ucy5zY29wZT09PXMub3B0aW9ucy5zY29wZSYmaS5hY2NlcHQuY2FsbChpLmVsZW1lbnRbMF0scy5jdXJyZW50SXRlbXx8cy5lbGVtZW50KSYmdShzLHQuZXh0ZW5kKGkse29mZnNldDppLmVsZW1lbnQub2Zmc2V0KCl9KSxpLm9wdGlvbnMudG9sZXJhbmNlLGUpPyhuPSEwLCExKTp2b2lkIDB9KSxuPyExOnRoaXMuYWNjZXB0LmNhbGwodGhpcy5lbGVtZW50WzBdLHMuY3VycmVudEl0ZW18fHMuZWxlbWVudCk/KHRoaXMuX3JlbW92ZUFjdGl2ZUNsYXNzKCksdGhpcy5fcmVtb3ZlSG92ZXJDbGFzcygpLHRoaXMuX3RyaWdnZXIoXCJkcm9wXCIsZSx0aGlzLnVpKHMpKSx0aGlzLmVsZW1lbnQpOiExKTohMX0sdWk6ZnVuY3Rpb24odCl7cmV0dXJue2RyYWdnYWJsZTp0LmN1cnJlbnRJdGVtfHx0LmVsZW1lbnQsaGVscGVyOnQuaGVscGVyLHBvc2l0aW9uOnQucG9zaXRpb24sb2Zmc2V0OnQucG9zaXRpb25BYnN9fSxfYWRkSG92ZXJDbGFzczpmdW5jdGlvbigpe3RoaXMuX2FkZENsYXNzKFwidWktZHJvcHBhYmxlLWhvdmVyXCIpfSxfcmVtb3ZlSG92ZXJDbGFzczpmdW5jdGlvbigpe3RoaXMuX3JlbW92ZUNsYXNzKFwidWktZHJvcHBhYmxlLWhvdmVyXCIpfSxfYWRkQWN0aXZlQ2xhc3M6ZnVuY3Rpb24oKXt0aGlzLl9hZGRDbGFzcyhcInVpLWRyb3BwYWJsZS1hY3RpdmVcIil9LF9yZW1vdmVBY3RpdmVDbGFzczpmdW5jdGlvbigpe3RoaXMuX3JlbW92ZUNsYXNzKFwidWktZHJvcHBhYmxlLWFjdGl2ZVwiKX19KTt2YXIgdT10LnVpLmludGVyc2VjdD1mdW5jdGlvbigpe2Z1bmN0aW9uIHQodCxlLGkpe3JldHVybiB0Pj1lJiZlK2k+dH1yZXR1cm4gZnVuY3Rpb24oZSxpLHMsbil7aWYoIWkub2Zmc2V0KXJldHVybiExO3ZhciBvPShlLnBvc2l0aW9uQWJzfHxlLnBvc2l0aW9uLmFic29sdXRlKS5sZWZ0K2UubWFyZ2lucy5sZWZ0LGE9KGUucG9zaXRpb25BYnN8fGUucG9zaXRpb24uYWJzb2x1dGUpLnRvcCtlLm1hcmdpbnMudG9wLHI9bytlLmhlbHBlclByb3BvcnRpb25zLndpZHRoLGg9YStlLmhlbHBlclByb3BvcnRpb25zLmhlaWdodCxsPWkub2Zmc2V0LmxlZnQsYz1pLm9mZnNldC50b3AsdT1sK2kucHJvcG9ydGlvbnMoKS53aWR0aCxkPWMraS5wcm9wb3J0aW9ucygpLmhlaWdodDtzd2l0Y2gocyl7Y2FzZVwiZml0XCI6cmV0dXJuIG8+PWwmJnU+PXImJmE+PWMmJmQ+PWg7Y2FzZVwiaW50ZXJzZWN0XCI6cmV0dXJuIG8rZS5oZWxwZXJQcm9wb3J0aW9ucy53aWR0aC8yPmwmJnU+ci1lLmhlbHBlclByb3BvcnRpb25zLndpZHRoLzImJmErZS5oZWxwZXJQcm9wb3J0aW9ucy5oZWlnaHQvMj5jJiZkPmgtZS5oZWxwZXJQcm9wb3J0aW9ucy5oZWlnaHQvMjtjYXNlXCJwb2ludGVyXCI6cmV0dXJuIHQobi5wYWdlWSxjLGkucHJvcG9ydGlvbnMoKS5oZWlnaHQpJiZ0KG4ucGFnZVgsbCxpLnByb3BvcnRpb25zKCkud2lkdGgpO2Nhc2VcInRvdWNoXCI6cmV0dXJuKGE+PWMmJmQ+PWF8fGg+PWMmJmQ+PWh8fGM+YSYmaD5kKSYmKG8+PWwmJnU+PW98fHI+PWwmJnU+PXJ8fGw+byYmcj51KTtkZWZhdWx0OnJldHVybiExfX19KCk7dC51aS5kZG1hbmFnZXI9e2N1cnJlbnQ6bnVsbCxkcm9wcGFibGVzOntcImRlZmF1bHRcIjpbXX0scHJlcGFyZU9mZnNldHM6ZnVuY3Rpb24oZSxpKXt2YXIgcyxuLG89dC51aS5kZG1hbmFnZXIuZHJvcHBhYmxlc1tlLm9wdGlvbnMuc2NvcGVdfHxbXSxhPWk/aS50eXBlOm51bGwscj0oZS5jdXJyZW50SXRlbXx8ZS5lbGVtZW50KS5maW5kKFwiOmRhdGEodWktZHJvcHBhYmxlKVwiKS5hZGRCYWNrKCk7dDpmb3Iocz0wO28ubGVuZ3RoPnM7cysrKWlmKCEob1tzXS5vcHRpb25zLmRpc2FibGVkfHxlJiYhb1tzXS5hY2NlcHQuY2FsbChvW3NdLmVsZW1lbnRbMF0sZS5jdXJyZW50SXRlbXx8ZS5lbGVtZW50KSkpe2ZvcihuPTA7ci5sZW5ndGg+bjtuKyspaWYocltuXT09PW9bc10uZWxlbWVudFswXSl7b1tzXS5wcm9wb3J0aW9ucygpLmhlaWdodD0wO2NvbnRpbnVlIHR9b1tzXS52aXNpYmxlPVwibm9uZVwiIT09b1tzXS5lbGVtZW50LmNzcyhcImRpc3BsYXlcIiksb1tzXS52aXNpYmxlJiYoXCJtb3VzZWRvd25cIj09PWEmJm9bc10uX2FjdGl2YXRlLmNhbGwob1tzXSxpKSxvW3NdLm9mZnNldD1vW3NdLmVsZW1lbnQub2Zmc2V0KCksb1tzXS5wcm9wb3J0aW9ucyh7d2lkdGg6b1tzXS5lbGVtZW50WzBdLm9mZnNldFdpZHRoLGhlaWdodDpvW3NdLmVsZW1lbnRbMF0ub2Zmc2V0SGVpZ2h0fSkpfX0sZHJvcDpmdW5jdGlvbihlLGkpe3ZhciBzPSExO3JldHVybiB0LmVhY2goKHQudWkuZGRtYW5hZ2VyLmRyb3BwYWJsZXNbZS5vcHRpb25zLnNjb3BlXXx8W10pLnNsaWNlKCksZnVuY3Rpb24oKXt0aGlzLm9wdGlvbnMmJighdGhpcy5vcHRpb25zLmRpc2FibGVkJiZ0aGlzLnZpc2libGUmJnUoZSx0aGlzLHRoaXMub3B0aW9ucy50b2xlcmFuY2UsaSkmJihzPXRoaXMuX2Ryb3AuY2FsbCh0aGlzLGkpfHxzKSwhdGhpcy5vcHRpb25zLmRpc2FibGVkJiZ0aGlzLnZpc2libGUmJnRoaXMuYWNjZXB0LmNhbGwodGhpcy5lbGVtZW50WzBdLGUuY3VycmVudEl0ZW18fGUuZWxlbWVudCkmJih0aGlzLmlzb3V0PSEwLHRoaXMuaXNvdmVyPSExLHRoaXMuX2RlYWN0aXZhdGUuY2FsbCh0aGlzLGkpKSl9KSxzfSxkcmFnU3RhcnQ6ZnVuY3Rpb24oZSxpKXtlLmVsZW1lbnQucGFyZW50c1VudGlsKFwiYm9keVwiKS5vbihcInNjcm9sbC5kcm9wcGFibGVcIixmdW5jdGlvbigpe2Uub3B0aW9ucy5yZWZyZXNoUG9zaXRpb25zfHx0LnVpLmRkbWFuYWdlci5wcmVwYXJlT2Zmc2V0cyhlLGkpfSl9LGRyYWc6ZnVuY3Rpb24oZSxpKXtlLm9wdGlvbnMucmVmcmVzaFBvc2l0aW9ucyYmdC51aS5kZG1hbmFnZXIucHJlcGFyZU9mZnNldHMoZSxpKSx0LmVhY2godC51aS5kZG1hbmFnZXIuZHJvcHBhYmxlc1tlLm9wdGlvbnMuc2NvcGVdfHxbXSxmdW5jdGlvbigpe2lmKCF0aGlzLm9wdGlvbnMuZGlzYWJsZWQmJiF0aGlzLmdyZWVkeUNoaWxkJiZ0aGlzLnZpc2libGUpe3ZhciBzLG4sbyxhPXUoZSx0aGlzLHRoaXMub3B0aW9ucy50b2xlcmFuY2UsaSkscj0hYSYmdGhpcy5pc292ZXI/XCJpc291dFwiOmEmJiF0aGlzLmlzb3Zlcj9cImlzb3ZlclwiOm51bGw7ciYmKHRoaXMub3B0aW9ucy5ncmVlZHkmJihuPXRoaXMub3B0aW9ucy5zY29wZSxvPXRoaXMuZWxlbWVudC5wYXJlbnRzKFwiOmRhdGEodWktZHJvcHBhYmxlKVwiKS5maWx0ZXIoZnVuY3Rpb24oKXtyZXR1cm4gdCh0aGlzKS5kcm9wcGFibGUoXCJpbnN0YW5jZVwiKS5vcHRpb25zLnNjb3BlPT09bn0pLG8ubGVuZ3RoJiYocz10KG9bMF0pLmRyb3BwYWJsZShcImluc3RhbmNlXCIpLHMuZ3JlZWR5Q2hpbGQ9XCJpc292ZXJcIj09PXIpKSxzJiZcImlzb3ZlclwiPT09ciYmKHMuaXNvdmVyPSExLHMuaXNvdXQ9ITAscy5fb3V0LmNhbGwocyxpKSksdGhpc1tyXT0hMCx0aGlzW1wiaXNvdXRcIj09PXI/XCJpc292ZXJcIjpcImlzb3V0XCJdPSExLHRoaXNbXCJpc292ZXJcIj09PXI/XCJfb3ZlclwiOlwiX291dFwiXS5jYWxsKHRoaXMsaSkscyYmXCJpc291dFwiPT09ciYmKHMuaXNvdXQ9ITEscy5pc292ZXI9ITAscy5fb3Zlci5jYWxsKHMsaSkpKX19KX0sZHJhZ1N0b3A6ZnVuY3Rpb24oZSxpKXtlLmVsZW1lbnQucGFyZW50c1VudGlsKFwiYm9keVwiKS5vZmYoXCJzY3JvbGwuZHJvcHBhYmxlXCIpLGUub3B0aW9ucy5yZWZyZXNoUG9zaXRpb25zfHx0LnVpLmRkbWFuYWdlci5wcmVwYXJlT2Zmc2V0cyhlLGkpfX0sdC51aUJhY2tDb21wYXQhPT0hMSYmdC53aWRnZXQoXCJ1aS5kcm9wcGFibGVcIix0LnVpLmRyb3BwYWJsZSx7b3B0aW9uczp7aG92ZXJDbGFzczohMSxhY3RpdmVDbGFzczohMX0sX2FkZEFjdGl2ZUNsYXNzOmZ1bmN0aW9uKCl7dGhpcy5fc3VwZXIoKSx0aGlzLm9wdGlvbnMuYWN0aXZlQ2xhc3MmJnRoaXMuZWxlbWVudC5hZGRDbGFzcyh0aGlzLm9wdGlvbnMuYWN0aXZlQ2xhc3MpfSxfcmVtb3ZlQWN0aXZlQ2xhc3M6ZnVuY3Rpb24oKXt0aGlzLl9zdXBlcigpLHRoaXMub3B0aW9ucy5hY3RpdmVDbGFzcyYmdGhpcy5lbGVtZW50LnJlbW92ZUNsYXNzKHRoaXMub3B0aW9ucy5hY3RpdmVDbGFzcyl9LF9hZGRIb3ZlckNsYXNzOmZ1bmN0aW9uKCl7dGhpcy5fc3VwZXIoKSx0aGlzLm9wdGlvbnMuaG92ZXJDbGFzcyYmdGhpcy5lbGVtZW50LmFkZENsYXNzKHRoaXMub3B0aW9ucy5ob3ZlckNsYXNzKX0sX3JlbW92ZUhvdmVyQ2xhc3M6ZnVuY3Rpb24oKXt0aGlzLl9zdXBlcigpLHRoaXMub3B0aW9ucy5ob3ZlckNsYXNzJiZ0aGlzLmVsZW1lbnQucmVtb3ZlQ2xhc3ModGhpcy5vcHRpb25zLmhvdmVyQ2xhc3MpfX0pLHQudWkuZHJvcHBhYmxlLHQud2lkZ2V0KFwidWkucmVzaXphYmxlXCIsdC51aS5tb3VzZSx7dmVyc2lvbjpcIjEuMTIuMVwiLHdpZGdldEV2ZW50UHJlZml4OlwicmVzaXplXCIsb3B0aW9uczp7YWxzb1Jlc2l6ZTohMSxhbmltYXRlOiExLGFuaW1hdGVEdXJhdGlvbjpcInNsb3dcIixhbmltYXRlRWFzaW5nOlwic3dpbmdcIixhc3BlY3RSYXRpbzohMSxhdXRvSGlkZTohMSxjbGFzc2VzOntcInVpLXJlc2l6YWJsZS1zZVwiOlwidWktaWNvbiB1aS1pY29uLWdyaXBzbWFsbC1kaWFnb25hbC1zZVwifSxjb250YWlubWVudDohMSxnaG9zdDohMSxncmlkOiExLGhhbmRsZXM6XCJlLHMsc2VcIixoZWxwZXI6ITEsbWF4SGVpZ2h0Om51bGwsbWF4V2lkdGg6bnVsbCxtaW5IZWlnaHQ6MTAsbWluV2lkdGg6MTAsekluZGV4OjkwLHJlc2l6ZTpudWxsLHN0YXJ0Om51bGwsc3RvcDpudWxsfSxfbnVtOmZ1bmN0aW9uKHQpe3JldHVybiBwYXJzZUZsb2F0KHQpfHwwfSxfaXNOdW1iZXI6ZnVuY3Rpb24odCl7cmV0dXJuIWlzTmFOKHBhcnNlRmxvYXQodCkpfSxfaGFzU2Nyb2xsOmZ1bmN0aW9uKGUsaSl7aWYoXCJoaWRkZW5cIj09PXQoZSkuY3NzKFwib3ZlcmZsb3dcIikpcmV0dXJuITE7dmFyIHM9aSYmXCJsZWZ0XCI9PT1pP1wic2Nyb2xsTGVmdFwiOlwic2Nyb2xsVG9wXCIsbj0hMTtyZXR1cm4gZVtzXT4wPyEwOihlW3NdPTEsbj1lW3NdPjAsZVtzXT0wLG4pfSxfY3JlYXRlOmZ1bmN0aW9uKCl7dmFyIGUsaT10aGlzLm9wdGlvbnMscz10aGlzO3RoaXMuX2FkZENsYXNzKFwidWktcmVzaXphYmxlXCIpLHQuZXh0ZW5kKHRoaXMse19hc3BlY3RSYXRpbzohIWkuYXNwZWN0UmF0aW8sYXNwZWN0UmF0aW86aS5hc3BlY3RSYXRpbyxvcmlnaW5hbEVsZW1lbnQ6dGhpcy5lbGVtZW50LF9wcm9wb3J0aW9uYWxseVJlc2l6ZUVsZW1lbnRzOltdLF9oZWxwZXI6aS5oZWxwZXJ8fGkuZ2hvc3R8fGkuYW5pbWF0ZT9pLmhlbHBlcnx8XCJ1aS1yZXNpemFibGUtaGVscGVyXCI6bnVsbH0pLHRoaXMuZWxlbWVudFswXS5ub2RlTmFtZS5tYXRjaCgvXihjYW52YXN8dGV4dGFyZWF8aW5wdXR8c2VsZWN0fGJ1dHRvbnxpbWcpJC9pKSYmKHRoaXMuZWxlbWVudC53cmFwKHQoXCI8ZGl2IGNsYXNzPSd1aS13cmFwcGVyJyBzdHlsZT0nb3ZlcmZsb3c6IGhpZGRlbjsnPjwvZGl2PlwiKS5jc3Moe3Bvc2l0aW9uOnRoaXMuZWxlbWVudC5jc3MoXCJwb3NpdGlvblwiKSx3aWR0aDp0aGlzLmVsZW1lbnQub3V0ZXJXaWR0aCgpLGhlaWdodDp0aGlzLmVsZW1lbnQub3V0ZXJIZWlnaHQoKSx0b3A6dGhpcy5lbGVtZW50LmNzcyhcInRvcFwiKSxsZWZ0OnRoaXMuZWxlbWVudC5jc3MoXCJsZWZ0XCIpfSkpLHRoaXMuZWxlbWVudD10aGlzLmVsZW1lbnQucGFyZW50KCkuZGF0YShcInVpLXJlc2l6YWJsZVwiLHRoaXMuZWxlbWVudC5yZXNpemFibGUoXCJpbnN0YW5jZVwiKSksdGhpcy5lbGVtZW50SXNXcmFwcGVyPSEwLGU9e21hcmdpblRvcDp0aGlzLm9yaWdpbmFsRWxlbWVudC5jc3MoXCJtYXJnaW5Ub3BcIiksbWFyZ2luUmlnaHQ6dGhpcy5vcmlnaW5hbEVsZW1lbnQuY3NzKFwibWFyZ2luUmlnaHRcIiksbWFyZ2luQm90dG9tOnRoaXMub3JpZ2luYWxFbGVtZW50LmNzcyhcIm1hcmdpbkJvdHRvbVwiKSxtYXJnaW5MZWZ0OnRoaXMub3JpZ2luYWxFbGVtZW50LmNzcyhcIm1hcmdpbkxlZnRcIil9LHRoaXMuZWxlbWVudC5jc3MoZSksdGhpcy5vcmlnaW5hbEVsZW1lbnQuY3NzKFwibWFyZ2luXCIsMCksdGhpcy5vcmlnaW5hbFJlc2l6ZVN0eWxlPXRoaXMub3JpZ2luYWxFbGVtZW50LmNzcyhcInJlc2l6ZVwiKSx0aGlzLm9yaWdpbmFsRWxlbWVudC5jc3MoXCJyZXNpemVcIixcIm5vbmVcIiksdGhpcy5fcHJvcG9ydGlvbmFsbHlSZXNpemVFbGVtZW50cy5wdXNoKHRoaXMub3JpZ2luYWxFbGVtZW50LmNzcyh7cG9zaXRpb246XCJzdGF0aWNcIix6b29tOjEsZGlzcGxheTpcImJsb2NrXCJ9KSksdGhpcy5vcmlnaW5hbEVsZW1lbnQuY3NzKGUpLHRoaXMuX3Byb3BvcnRpb25hbGx5UmVzaXplKCkpLHRoaXMuX3NldHVwSGFuZGxlcygpLGkuYXV0b0hpZGUmJnQodGhpcy5lbGVtZW50KS5vbihcIm1vdXNlZW50ZXJcIixmdW5jdGlvbigpe2kuZGlzYWJsZWR8fChzLl9yZW1vdmVDbGFzcyhcInVpLXJlc2l6YWJsZS1hdXRvaGlkZVwiKSxzLl9oYW5kbGVzLnNob3coKSl9KS5vbihcIm1vdXNlbGVhdmVcIixmdW5jdGlvbigpe2kuZGlzYWJsZWR8fHMucmVzaXppbmd8fChzLl9hZGRDbGFzcyhcInVpLXJlc2l6YWJsZS1hdXRvaGlkZVwiKSxzLl9oYW5kbGVzLmhpZGUoKSl9KSx0aGlzLl9tb3VzZUluaXQoKX0sX2Rlc3Ryb3k6ZnVuY3Rpb24oKXt0aGlzLl9tb3VzZURlc3Ryb3koKTt2YXIgZSxpPWZ1bmN0aW9uKGUpe3QoZSkucmVtb3ZlRGF0YShcInJlc2l6YWJsZVwiKS5yZW1vdmVEYXRhKFwidWktcmVzaXphYmxlXCIpLm9mZihcIi5yZXNpemFibGVcIikuZmluZChcIi51aS1yZXNpemFibGUtaGFuZGxlXCIpLnJlbW92ZSgpfTtyZXR1cm4gdGhpcy5lbGVtZW50SXNXcmFwcGVyJiYoaSh0aGlzLmVsZW1lbnQpLGU9dGhpcy5lbGVtZW50LHRoaXMub3JpZ2luYWxFbGVtZW50LmNzcyh7cG9zaXRpb246ZS5jc3MoXCJwb3NpdGlvblwiKSx3aWR0aDplLm91dGVyV2lkdGgoKSxoZWlnaHQ6ZS5vdXRlckhlaWdodCgpLHRvcDplLmNzcyhcInRvcFwiKSxsZWZ0OmUuY3NzKFwibGVmdFwiKX0pLmluc2VydEFmdGVyKGUpLGUucmVtb3ZlKCkpLHRoaXMub3JpZ2luYWxFbGVtZW50LmNzcyhcInJlc2l6ZVwiLHRoaXMub3JpZ2luYWxSZXNpemVTdHlsZSksaSh0aGlzLm9yaWdpbmFsRWxlbWVudCksdGhpc30sX3NldE9wdGlvbjpmdW5jdGlvbih0LGUpe3N3aXRjaCh0aGlzLl9zdXBlcih0LGUpLHQpe2Nhc2VcImhhbmRsZXNcIjp0aGlzLl9yZW1vdmVIYW5kbGVzKCksdGhpcy5fc2V0dXBIYW5kbGVzKCk7YnJlYWs7ZGVmYXVsdDp9fSxfc2V0dXBIYW5kbGVzOmZ1bmN0aW9uKCl7dmFyIGUsaSxzLG4sbyxhPXRoaXMub3B0aW9ucyxyPXRoaXM7aWYodGhpcy5oYW5kbGVzPWEuaGFuZGxlc3x8KHQoXCIudWktcmVzaXphYmxlLWhhbmRsZVwiLHRoaXMuZWxlbWVudCkubGVuZ3RoP3tuOlwiLnVpLXJlc2l6YWJsZS1uXCIsZTpcIi51aS1yZXNpemFibGUtZVwiLHM6XCIudWktcmVzaXphYmxlLXNcIix3OlwiLnVpLXJlc2l6YWJsZS13XCIsc2U6XCIudWktcmVzaXphYmxlLXNlXCIsc3c6XCIudWktcmVzaXphYmxlLXN3XCIsbmU6XCIudWktcmVzaXphYmxlLW5lXCIsbnc6XCIudWktcmVzaXphYmxlLW53XCJ9OlwiZSxzLHNlXCIpLHRoaXMuX2hhbmRsZXM9dCgpLHRoaXMuaGFuZGxlcy5jb25zdHJ1Y3Rvcj09PVN0cmluZylmb3IoXCJhbGxcIj09PXRoaXMuaGFuZGxlcyYmKHRoaXMuaGFuZGxlcz1cIm4sZSxzLHcsc2Usc3csbmUsbndcIikscz10aGlzLmhhbmRsZXMuc3BsaXQoXCIsXCIpLHRoaXMuaGFuZGxlcz17fSxpPTA7cy5sZW5ndGg+aTtpKyspZT10LnRyaW0oc1tpXSksbj1cInVpLXJlc2l6YWJsZS1cIitlLG89dChcIjxkaXY+XCIpLHRoaXMuX2FkZENsYXNzKG8sXCJ1aS1yZXNpemFibGUtaGFuZGxlIFwiK24pLG8uY3NzKHt6SW5kZXg6YS56SW5kZXh9KSx0aGlzLmhhbmRsZXNbZV09XCIudWktcmVzaXphYmxlLVwiK2UsdGhpcy5lbGVtZW50LmFwcGVuZChvKTt0aGlzLl9yZW5kZXJBeGlzPWZ1bmN0aW9uKGUpe3ZhciBpLHMsbixvO2U9ZXx8dGhpcy5lbGVtZW50O2ZvcihpIGluIHRoaXMuaGFuZGxlcyl0aGlzLmhhbmRsZXNbaV0uY29uc3RydWN0b3I9PT1TdHJpbmc/dGhpcy5oYW5kbGVzW2ldPXRoaXMuZWxlbWVudC5jaGlsZHJlbih0aGlzLmhhbmRsZXNbaV0pLmZpcnN0KCkuc2hvdygpOih0aGlzLmhhbmRsZXNbaV0uanF1ZXJ5fHx0aGlzLmhhbmRsZXNbaV0ubm9kZVR5cGUpJiYodGhpcy5oYW5kbGVzW2ldPXQodGhpcy5oYW5kbGVzW2ldKSx0aGlzLl9vbih0aGlzLmhhbmRsZXNbaV0se21vdXNlZG93bjpyLl9tb3VzZURvd259KSksdGhpcy5lbGVtZW50SXNXcmFwcGVyJiZ0aGlzLm9yaWdpbmFsRWxlbWVudFswXS5ub2RlTmFtZS5tYXRjaCgvXih0ZXh0YXJlYXxpbnB1dHxzZWxlY3R8YnV0dG9uKSQvaSkmJihzPXQodGhpcy5oYW5kbGVzW2ldLHRoaXMuZWxlbWVudCksbz0vc3d8bmV8bnd8c2V8bnxzLy50ZXN0KGkpP3Mub3V0ZXJIZWlnaHQoKTpzLm91dGVyV2lkdGgoKSxuPVtcInBhZGRpbmdcIiwvbmV8bnd8bi8udGVzdChpKT9cIlRvcFwiOi9zZXxzd3xzLy50ZXN0KGkpP1wiQm90dG9tXCI6L15lJC8udGVzdChpKT9cIlJpZ2h0XCI6XCJMZWZ0XCJdLmpvaW4oXCJcIiksZS5jc3MobixvKSx0aGlzLl9wcm9wb3J0aW9uYWxseVJlc2l6ZSgpKSx0aGlzLl9oYW5kbGVzPXRoaXMuX2hhbmRsZXMuYWRkKHRoaXMuaGFuZGxlc1tpXSl9LHRoaXMuX3JlbmRlckF4aXModGhpcy5lbGVtZW50KSx0aGlzLl9oYW5kbGVzPXRoaXMuX2hhbmRsZXMuYWRkKHRoaXMuZWxlbWVudC5maW5kKFwiLnVpLXJlc2l6YWJsZS1oYW5kbGVcIikpLHRoaXMuX2hhbmRsZXMuZGlzYWJsZVNlbGVjdGlvbigpLHRoaXMuX2hhbmRsZXMub24oXCJtb3VzZW92ZXJcIixmdW5jdGlvbigpe3IucmVzaXppbmd8fCh0aGlzLmNsYXNzTmFtZSYmKG89dGhpcy5jbGFzc05hbWUubWF0Y2goL3VpLXJlc2l6YWJsZS0oc2V8c3d8bmV8bnd8bnxlfHN8dykvaSkpLHIuYXhpcz1vJiZvWzFdP29bMV06XCJzZVwiKX0pLGEuYXV0b0hpZGUmJih0aGlzLl9oYW5kbGVzLmhpZGUoKSx0aGlzLl9hZGRDbGFzcyhcInVpLXJlc2l6YWJsZS1hdXRvaGlkZVwiKSl9LF9yZW1vdmVIYW5kbGVzOmZ1bmN0aW9uKCl7dGhpcy5faGFuZGxlcy5yZW1vdmUoKX0sX21vdXNlQ2FwdHVyZTpmdW5jdGlvbihlKXt2YXIgaSxzLG49ITE7Zm9yKGkgaW4gdGhpcy5oYW5kbGVzKXM9dCh0aGlzLmhhbmRsZXNbaV0pWzBdLChzPT09ZS50YXJnZXR8fHQuY29udGFpbnMocyxlLnRhcmdldCkpJiYobj0hMCk7cmV0dXJuIXRoaXMub3B0aW9ucy5kaXNhYmxlZCYmbn0sX21vdXNlU3RhcnQ6ZnVuY3Rpb24oZSl7dmFyIGkscyxuLG89dGhpcy5vcHRpb25zLGE9dGhpcy5lbGVtZW50O3JldHVybiB0aGlzLnJlc2l6aW5nPSEwLHRoaXMuX3JlbmRlclByb3h5KCksaT10aGlzLl9udW0odGhpcy5oZWxwZXIuY3NzKFwibGVmdFwiKSkscz10aGlzLl9udW0odGhpcy5oZWxwZXIuY3NzKFwidG9wXCIpKSxvLmNvbnRhaW5tZW50JiYoaSs9dChvLmNvbnRhaW5tZW50KS5zY3JvbGxMZWZ0KCl8fDAscys9dChvLmNvbnRhaW5tZW50KS5zY3JvbGxUb3AoKXx8MCksdGhpcy5vZmZzZXQ9dGhpcy5oZWxwZXIub2Zmc2V0KCksdGhpcy5wb3NpdGlvbj17bGVmdDppLHRvcDpzfSx0aGlzLnNpemU9dGhpcy5faGVscGVyP3t3aWR0aDp0aGlzLmhlbHBlci53aWR0aCgpLGhlaWdodDp0aGlzLmhlbHBlci5oZWlnaHQoKX06e3dpZHRoOmEud2lkdGgoKSxoZWlnaHQ6YS5oZWlnaHQoKX0sdGhpcy5vcmlnaW5hbFNpemU9dGhpcy5faGVscGVyP3t3aWR0aDphLm91dGVyV2lkdGgoKSxoZWlnaHQ6YS5vdXRlckhlaWdodCgpfTp7d2lkdGg6YS53aWR0aCgpLGhlaWdodDphLmhlaWdodCgpfSx0aGlzLnNpemVEaWZmPXt3aWR0aDphLm91dGVyV2lkdGgoKS1hLndpZHRoKCksaGVpZ2h0OmEub3V0ZXJIZWlnaHQoKS1hLmhlaWdodCgpfSx0aGlzLm9yaWdpbmFsUG9zaXRpb249e2xlZnQ6aSx0b3A6c30sdGhpcy5vcmlnaW5hbE1vdXNlUG9zaXRpb249e2xlZnQ6ZS5wYWdlWCx0b3A6ZS5wYWdlWX0sdGhpcy5hc3BlY3RSYXRpbz1cIm51bWJlclwiPT10eXBlb2Ygby5hc3BlY3RSYXRpbz9vLmFzcGVjdFJhdGlvOnRoaXMub3JpZ2luYWxTaXplLndpZHRoL3RoaXMub3JpZ2luYWxTaXplLmhlaWdodHx8MSxuPXQoXCIudWktcmVzaXphYmxlLVwiK3RoaXMuYXhpcykuY3NzKFwiY3Vyc29yXCIpLHQoXCJib2R5XCIpLmNzcyhcImN1cnNvclwiLFwiYXV0b1wiPT09bj90aGlzLmF4aXMrXCItcmVzaXplXCI6biksdGhpcy5fYWRkQ2xhc3MoXCJ1aS1yZXNpemFibGUtcmVzaXppbmdcIiksdGhpcy5fcHJvcGFnYXRlKFwic3RhcnRcIixlKSwhMH0sX21vdXNlRHJhZzpmdW5jdGlvbihlKXt2YXIgaSxzLG49dGhpcy5vcmlnaW5hbE1vdXNlUG9zaXRpb24sbz10aGlzLmF4aXMsYT1lLnBhZ2VYLW4ubGVmdHx8MCxyPWUucGFnZVktbi50b3B8fDAsaD10aGlzLl9jaGFuZ2Vbb107cmV0dXJuIHRoaXMuX3VwZGF0ZVByZXZQcm9wZXJ0aWVzKCksaD8oaT1oLmFwcGx5KHRoaXMsW2UsYSxyXSksdGhpcy5fdXBkYXRlVmlydHVhbEJvdW5kYXJpZXMoZS5zaGlmdEtleSksKHRoaXMuX2FzcGVjdFJhdGlvfHxlLnNoaWZ0S2V5KSYmKGk9dGhpcy5fdXBkYXRlUmF0aW8oaSxlKSksaT10aGlzLl9yZXNwZWN0U2l6ZShpLGUpLHRoaXMuX3VwZGF0ZUNhY2hlKGkpLHRoaXMuX3Byb3BhZ2F0ZShcInJlc2l6ZVwiLGUpLHM9dGhpcy5fYXBwbHlDaGFuZ2VzKCksIXRoaXMuX2hlbHBlciYmdGhpcy5fcHJvcG9ydGlvbmFsbHlSZXNpemVFbGVtZW50cy5sZW5ndGgmJnRoaXMuX3Byb3BvcnRpb25hbGx5UmVzaXplKCksdC5pc0VtcHR5T2JqZWN0KHMpfHwodGhpcy5fdXBkYXRlUHJldlByb3BlcnRpZXMoKSx0aGlzLl90cmlnZ2VyKFwicmVzaXplXCIsZSx0aGlzLnVpKCkpLHRoaXMuX2FwcGx5Q2hhbmdlcygpKSwhMSk6ITF9LF9tb3VzZVN0b3A6ZnVuY3Rpb24oZSl7dGhpcy5yZXNpemluZz0hMTt2YXIgaSxzLG4sbyxhLHIsaCxsPXRoaXMub3B0aW9ucyxjPXRoaXM7cmV0dXJuIHRoaXMuX2hlbHBlciYmKGk9dGhpcy5fcHJvcG9ydGlvbmFsbHlSZXNpemVFbGVtZW50cyxzPWkubGVuZ3RoJiYvdGV4dGFyZWEvaS50ZXN0KGlbMF0ubm9kZU5hbWUpLG49cyYmdGhpcy5faGFzU2Nyb2xsKGlbMF0sXCJsZWZ0XCIpPzA6Yy5zaXplRGlmZi5oZWlnaHQsbz1zPzA6Yy5zaXplRGlmZi53aWR0aCxhPXt3aWR0aDpjLmhlbHBlci53aWR0aCgpLW8saGVpZ2h0OmMuaGVscGVyLmhlaWdodCgpLW59LHI9cGFyc2VGbG9hdChjLmVsZW1lbnQuY3NzKFwibGVmdFwiKSkrKGMucG9zaXRpb24ubGVmdC1jLm9yaWdpbmFsUG9zaXRpb24ubGVmdCl8fG51bGwsaD1wYXJzZUZsb2F0KGMuZWxlbWVudC5jc3MoXCJ0b3BcIikpKyhjLnBvc2l0aW9uLnRvcC1jLm9yaWdpbmFsUG9zaXRpb24udG9wKXx8bnVsbCxsLmFuaW1hdGV8fHRoaXMuZWxlbWVudC5jc3ModC5leHRlbmQoYSx7dG9wOmgsbGVmdDpyfSkpLGMuaGVscGVyLmhlaWdodChjLnNpemUuaGVpZ2h0KSxjLmhlbHBlci53aWR0aChjLnNpemUud2lkdGgpLHRoaXMuX2hlbHBlciYmIWwuYW5pbWF0ZSYmdGhpcy5fcHJvcG9ydGlvbmFsbHlSZXNpemUoKSksdChcImJvZHlcIikuY3NzKFwiY3Vyc29yXCIsXCJhdXRvXCIpLHRoaXMuX3JlbW92ZUNsYXNzKFwidWktcmVzaXphYmxlLXJlc2l6aW5nXCIpLHRoaXMuX3Byb3BhZ2F0ZShcInN0b3BcIixlKSx0aGlzLl9oZWxwZXImJnRoaXMuaGVscGVyLnJlbW92ZSgpLCExfSxfdXBkYXRlUHJldlByb3BlcnRpZXM6ZnVuY3Rpb24oKXt0aGlzLnByZXZQb3NpdGlvbj17dG9wOnRoaXMucG9zaXRpb24udG9wLGxlZnQ6dGhpcy5wb3NpdGlvbi5sZWZ0fSx0aGlzLnByZXZTaXplPXt3aWR0aDp0aGlzLnNpemUud2lkdGgsaGVpZ2h0OnRoaXMuc2l6ZS5oZWlnaHR9fSxfYXBwbHlDaGFuZ2VzOmZ1bmN0aW9uKCl7dmFyIHQ9e307cmV0dXJuIHRoaXMucG9zaXRpb24udG9wIT09dGhpcy5wcmV2UG9zaXRpb24udG9wJiYodC50b3A9dGhpcy5wb3NpdGlvbi50b3ArXCJweFwiKSx0aGlzLnBvc2l0aW9uLmxlZnQhPT10aGlzLnByZXZQb3NpdGlvbi5sZWZ0JiYodC5sZWZ0PXRoaXMucG9zaXRpb24ubGVmdCtcInB4XCIpLHRoaXMuc2l6ZS53aWR0aCE9PXRoaXMucHJldlNpemUud2lkdGgmJih0LndpZHRoPXRoaXMuc2l6ZS53aWR0aCtcInB4XCIpLHRoaXMuc2l6ZS5oZWlnaHQhPT10aGlzLnByZXZTaXplLmhlaWdodCYmKHQuaGVpZ2h0PXRoaXMuc2l6ZS5oZWlnaHQrXCJweFwiKSx0aGlzLmhlbHBlci5jc3ModCksdH0sX3VwZGF0ZVZpcnR1YWxCb3VuZGFyaWVzOmZ1bmN0aW9uKHQpe3ZhciBlLGkscyxuLG8sYT10aGlzLm9wdGlvbnM7bz17bWluV2lkdGg6dGhpcy5faXNOdW1iZXIoYS5taW5XaWR0aCk/YS5taW5XaWR0aDowLG1heFdpZHRoOnRoaXMuX2lzTnVtYmVyKGEubWF4V2lkdGgpP2EubWF4V2lkdGg6MS8wLG1pbkhlaWdodDp0aGlzLl9pc051bWJlcihhLm1pbkhlaWdodCk/YS5taW5IZWlnaHQ6MCxtYXhIZWlnaHQ6dGhpcy5faXNOdW1iZXIoYS5tYXhIZWlnaHQpP2EubWF4SGVpZ2h0OjEvMH0sKHRoaXMuX2FzcGVjdFJhdGlvfHx0KSYmKGU9by5taW5IZWlnaHQqdGhpcy5hc3BlY3RSYXRpbyxzPW8ubWluV2lkdGgvdGhpcy5hc3BlY3RSYXRpbyxpPW8ubWF4SGVpZ2h0KnRoaXMuYXNwZWN0UmF0aW8sbj1vLm1heFdpZHRoL3RoaXMuYXNwZWN0UmF0aW8sZT5vLm1pbldpZHRoJiYoby5taW5XaWR0aD1lKSxzPm8ubWluSGVpZ2h0JiYoby5taW5IZWlnaHQ9cyksby5tYXhXaWR0aD5pJiYoby5tYXhXaWR0aD1pKSxvLm1heEhlaWdodD5uJiYoby5tYXhIZWlnaHQ9bikpLHRoaXMuX3ZCb3VuZGFyaWVzPW99LF91cGRhdGVDYWNoZTpmdW5jdGlvbih0KXt0aGlzLm9mZnNldD10aGlzLmhlbHBlci5vZmZzZXQoKSx0aGlzLl9pc051bWJlcih0LmxlZnQpJiYodGhpcy5wb3NpdGlvbi5sZWZ0PXQubGVmdCksdGhpcy5faXNOdW1iZXIodC50b3ApJiYodGhpcy5wb3NpdGlvbi50b3A9dC50b3ApLHRoaXMuX2lzTnVtYmVyKHQuaGVpZ2h0KSYmKHRoaXMuc2l6ZS5oZWlnaHQ9dC5oZWlnaHQpLHRoaXMuX2lzTnVtYmVyKHQud2lkdGgpJiYodGhpcy5zaXplLndpZHRoPXQud2lkdGgpfSxfdXBkYXRlUmF0aW86ZnVuY3Rpb24odCl7dmFyIGU9dGhpcy5wb3NpdGlvbixpPXRoaXMuc2l6ZSxzPXRoaXMuYXhpcztyZXR1cm4gdGhpcy5faXNOdW1iZXIodC5oZWlnaHQpP3Qud2lkdGg9dC5oZWlnaHQqdGhpcy5hc3BlY3RSYXRpbzp0aGlzLl9pc051bWJlcih0LndpZHRoKSYmKHQuaGVpZ2h0PXQud2lkdGgvdGhpcy5hc3BlY3RSYXRpbyksXCJzd1wiPT09cyYmKHQubGVmdD1lLmxlZnQrKGkud2lkdGgtdC53aWR0aCksdC50b3A9bnVsbCksXCJud1wiPT09cyYmKHQudG9wPWUudG9wKyhpLmhlaWdodC10LmhlaWdodCksdC5sZWZ0PWUubGVmdCsoaS53aWR0aC10LndpZHRoKSksdH0sX3Jlc3BlY3RTaXplOmZ1bmN0aW9uKHQpe3ZhciBlPXRoaXMuX3ZCb3VuZGFyaWVzLGk9dGhpcy5heGlzLHM9dGhpcy5faXNOdW1iZXIodC53aWR0aCkmJmUubWF4V2lkdGgmJmUubWF4V2lkdGg8dC53aWR0aCxuPXRoaXMuX2lzTnVtYmVyKHQuaGVpZ2h0KSYmZS5tYXhIZWlnaHQmJmUubWF4SGVpZ2h0PHQuaGVpZ2h0LG89dGhpcy5faXNOdW1iZXIodC53aWR0aCkmJmUubWluV2lkdGgmJmUubWluV2lkdGg+dC53aWR0aCxhPXRoaXMuX2lzTnVtYmVyKHQuaGVpZ2h0KSYmZS5taW5IZWlnaHQmJmUubWluSGVpZ2h0PnQuaGVpZ2h0LHI9dGhpcy5vcmlnaW5hbFBvc2l0aW9uLmxlZnQrdGhpcy5vcmlnaW5hbFNpemUud2lkdGgsaD10aGlzLm9yaWdpbmFsUG9zaXRpb24udG9wK3RoaXMub3JpZ2luYWxTaXplLmhlaWdodCxsPS9zd3xud3x3Ly50ZXN0KGkpLGM9L253fG5lfG4vLnRlc3QoaSk7cmV0dXJuIG8mJih0LndpZHRoPWUubWluV2lkdGgpLGEmJih0LmhlaWdodD1lLm1pbkhlaWdodCkscyYmKHQud2lkdGg9ZS5tYXhXaWR0aCksbiYmKHQuaGVpZ2h0PWUubWF4SGVpZ2h0KSxvJiZsJiYodC5sZWZ0PXItZS5taW5XaWR0aCkscyYmbCYmKHQubGVmdD1yLWUubWF4V2lkdGgpLGEmJmMmJih0LnRvcD1oLWUubWluSGVpZ2h0KSxuJiZjJiYodC50b3A9aC1lLm1heEhlaWdodCksdC53aWR0aHx8dC5oZWlnaHR8fHQubGVmdHx8IXQudG9wP3Qud2lkdGh8fHQuaGVpZ2h0fHx0LnRvcHx8IXQubGVmdHx8KHQubGVmdD1udWxsKTp0LnRvcD1udWxsLHR9LF9nZXRQYWRkaW5nUGx1c0JvcmRlckRpbWVuc2lvbnM6ZnVuY3Rpb24odCl7Zm9yKHZhciBlPTAsaT1bXSxzPVt0LmNzcyhcImJvcmRlclRvcFdpZHRoXCIpLHQuY3NzKFwiYm9yZGVyUmlnaHRXaWR0aFwiKSx0LmNzcyhcImJvcmRlckJvdHRvbVdpZHRoXCIpLHQuY3NzKFwiYm9yZGVyTGVmdFdpZHRoXCIpXSxuPVt0LmNzcyhcInBhZGRpbmdUb3BcIiksdC5jc3MoXCJwYWRkaW5nUmlnaHRcIiksdC5jc3MoXCJwYWRkaW5nQm90dG9tXCIpLHQuY3NzKFwicGFkZGluZ0xlZnRcIildOzQ+ZTtlKyspaVtlXT1wYXJzZUZsb2F0KHNbZV0pfHwwLGlbZV0rPXBhcnNlRmxvYXQobltlXSl8fDA7cmV0dXJue2hlaWdodDppWzBdK2lbMl0sd2lkdGg6aVsxXStpWzNdfX0sX3Byb3BvcnRpb25hbGx5UmVzaXplOmZ1bmN0aW9uKCl7aWYodGhpcy5fcHJvcG9ydGlvbmFsbHlSZXNpemVFbGVtZW50cy5sZW5ndGgpZm9yKHZhciB0LGU9MCxpPXRoaXMuaGVscGVyfHx0aGlzLmVsZW1lbnQ7dGhpcy5fcHJvcG9ydGlvbmFsbHlSZXNpemVFbGVtZW50cy5sZW5ndGg+ZTtlKyspdD10aGlzLl9wcm9wb3J0aW9uYWxseVJlc2l6ZUVsZW1lbnRzW2VdLHRoaXMub3V0ZXJEaW1lbnNpb25zfHwodGhpcy5vdXRlckRpbWVuc2lvbnM9dGhpcy5fZ2V0UGFkZGluZ1BsdXNCb3JkZXJEaW1lbnNpb25zKHQpKSx0LmNzcyh7aGVpZ2h0OmkuaGVpZ2h0KCktdGhpcy5vdXRlckRpbWVuc2lvbnMuaGVpZ2h0fHwwLHdpZHRoOmkud2lkdGgoKS10aGlzLm91dGVyRGltZW5zaW9ucy53aWR0aHx8MH0pfSxfcmVuZGVyUHJveHk6ZnVuY3Rpb24oKXt2YXIgZT10aGlzLmVsZW1lbnQsaT10aGlzLm9wdGlvbnM7dGhpcy5lbGVtZW50T2Zmc2V0PWUub2Zmc2V0KCksdGhpcy5faGVscGVyPyh0aGlzLmhlbHBlcj10aGlzLmhlbHBlcnx8dChcIjxkaXYgc3R5bGU9J292ZXJmbG93OmhpZGRlbjsnPjwvZGl2PlwiKSx0aGlzLl9hZGRDbGFzcyh0aGlzLmhlbHBlcix0aGlzLl9oZWxwZXIpLHRoaXMuaGVscGVyLmNzcyh7d2lkdGg6dGhpcy5lbGVtZW50Lm91dGVyV2lkdGgoKSxoZWlnaHQ6dGhpcy5lbGVtZW50Lm91dGVySGVpZ2h0KCkscG9zaXRpb246XCJhYnNvbHV0ZVwiLGxlZnQ6dGhpcy5lbGVtZW50T2Zmc2V0LmxlZnQrXCJweFwiLHRvcDp0aGlzLmVsZW1lbnRPZmZzZXQudG9wK1wicHhcIix6SW5kZXg6KytpLnpJbmRleH0pLHRoaXMuaGVscGVyLmFwcGVuZFRvKFwiYm9keVwiKS5kaXNhYmxlU2VsZWN0aW9uKCkpOnRoaXMuaGVscGVyPXRoaXMuZWxlbWVudH0sX2NoYW5nZTp7ZTpmdW5jdGlvbih0LGUpe3JldHVybnt3aWR0aDp0aGlzLm9yaWdpbmFsU2l6ZS53aWR0aCtlfX0sdzpmdW5jdGlvbih0LGUpe3ZhciBpPXRoaXMub3JpZ2luYWxTaXplLHM9dGhpcy5vcmlnaW5hbFBvc2l0aW9uO3JldHVybntsZWZ0OnMubGVmdCtlLHdpZHRoOmkud2lkdGgtZX19LG46ZnVuY3Rpb24odCxlLGkpe3ZhciBzPXRoaXMub3JpZ2luYWxTaXplLG49dGhpcy5vcmlnaW5hbFBvc2l0aW9uO3JldHVybnt0b3A6bi50b3AraSxoZWlnaHQ6cy5oZWlnaHQtaX19LHM6ZnVuY3Rpb24odCxlLGkpe3JldHVybntoZWlnaHQ6dGhpcy5vcmlnaW5hbFNpemUuaGVpZ2h0K2l9fSxzZTpmdW5jdGlvbihlLGkscyl7cmV0dXJuIHQuZXh0ZW5kKHRoaXMuX2NoYW5nZS5zLmFwcGx5KHRoaXMsYXJndW1lbnRzKSx0aGlzLl9jaGFuZ2UuZS5hcHBseSh0aGlzLFtlLGksc10pKX0sc3c6ZnVuY3Rpb24oZSxpLHMpe3JldHVybiB0LmV4dGVuZCh0aGlzLl9jaGFuZ2Uucy5hcHBseSh0aGlzLGFyZ3VtZW50cyksdGhpcy5fY2hhbmdlLncuYXBwbHkodGhpcyxbZSxpLHNdKSl9LG5lOmZ1bmN0aW9uKGUsaSxzKXtyZXR1cm4gdC5leHRlbmQodGhpcy5fY2hhbmdlLm4uYXBwbHkodGhpcyxhcmd1bWVudHMpLHRoaXMuX2NoYW5nZS5lLmFwcGx5KHRoaXMsW2UsaSxzXSkpfSxudzpmdW5jdGlvbihlLGkscyl7cmV0dXJuIHQuZXh0ZW5kKHRoaXMuX2NoYW5nZS5uLmFwcGx5KHRoaXMsYXJndW1lbnRzKSx0aGlzLl9jaGFuZ2Uudy5hcHBseSh0aGlzLFtlLGksc10pKX19LF9wcm9wYWdhdGU6ZnVuY3Rpb24oZSxpKXt0LnVpLnBsdWdpbi5jYWxsKHRoaXMsZSxbaSx0aGlzLnVpKCldKSxcInJlc2l6ZVwiIT09ZSYmdGhpcy5fdHJpZ2dlcihlLGksdGhpcy51aSgpKX0scGx1Z2luczp7fSx1aTpmdW5jdGlvbigpe3JldHVybntvcmlnaW5hbEVsZW1lbnQ6dGhpcy5vcmlnaW5hbEVsZW1lbnQsZWxlbWVudDp0aGlzLmVsZW1lbnQsaGVscGVyOnRoaXMuaGVscGVyLHBvc2l0aW9uOnRoaXMucG9zaXRpb24sc2l6ZTp0aGlzLnNpemUsb3JpZ2luYWxTaXplOnRoaXMub3JpZ2luYWxTaXplLG9yaWdpbmFsUG9zaXRpb246dGhpcy5vcmlnaW5hbFBvc2l0aW9ufX19KSx0LnVpLnBsdWdpbi5hZGQoXCJyZXNpemFibGVcIixcImFuaW1hdGVcIix7c3RvcDpmdW5jdGlvbihlKXt2YXIgaT10KHRoaXMpLnJlc2l6YWJsZShcImluc3RhbmNlXCIpLHM9aS5vcHRpb25zLG49aS5fcHJvcG9ydGlvbmFsbHlSZXNpemVFbGVtZW50cyxvPW4ubGVuZ3RoJiYvdGV4dGFyZWEvaS50ZXN0KG5bMF0ubm9kZU5hbWUpLGE9byYmaS5faGFzU2Nyb2xsKG5bMF0sXCJsZWZ0XCIpPzA6aS5zaXplRGlmZi5oZWlnaHQscj1vPzA6aS5zaXplRGlmZi53aWR0aCxoPXt3aWR0aDppLnNpemUud2lkdGgtcixoZWlnaHQ6aS5zaXplLmhlaWdodC1hfSxsPXBhcnNlRmxvYXQoaS5lbGVtZW50LmNzcyhcImxlZnRcIikpKyhpLnBvc2l0aW9uLmxlZnQtaS5vcmlnaW5hbFBvc2l0aW9uLmxlZnQpfHxudWxsLGM9cGFyc2VGbG9hdChpLmVsZW1lbnQuY3NzKFwidG9wXCIpKSsoaS5wb3NpdGlvbi50b3AtaS5vcmlnaW5hbFBvc2l0aW9uLnRvcCl8fG51bGw7aS5lbGVtZW50LmFuaW1hdGUodC5leHRlbmQoaCxjJiZsP3t0b3A6YyxsZWZ0Omx9Ont9KSx7ZHVyYXRpb246cy5hbmltYXRlRHVyYXRpb24sZWFzaW5nOnMuYW5pbWF0ZUVhc2luZyxzdGVwOmZ1bmN0aW9uKCl7dmFyIHM9e3dpZHRoOnBhcnNlRmxvYXQoaS5lbGVtZW50LmNzcyhcIndpZHRoXCIpKSxoZWlnaHQ6cGFyc2VGbG9hdChpLmVsZW1lbnQuY3NzKFwiaGVpZ2h0XCIpKSx0b3A6cGFyc2VGbG9hdChpLmVsZW1lbnQuY3NzKFwidG9wXCIpKSxsZWZ0OnBhcnNlRmxvYXQoaS5lbGVtZW50LmNzcyhcImxlZnRcIikpfTtuJiZuLmxlbmd0aCYmdChuWzBdKS5jc3Moe3dpZHRoOnMud2lkdGgsaGVpZ2h0OnMuaGVpZ2h0fSksaS5fdXBkYXRlQ2FjaGUocyksaS5fcHJvcGFnYXRlKFwicmVzaXplXCIsZSl9fSl9fSksdC51aS5wbHVnaW4uYWRkKFwicmVzaXphYmxlXCIsXCJjb250YWlubWVudFwiLHtzdGFydDpmdW5jdGlvbigpe3ZhciBlLGkscyxuLG8sYSxyLGg9dCh0aGlzKS5yZXNpemFibGUoXCJpbnN0YW5jZVwiKSxsPWgub3B0aW9ucyxjPWguZWxlbWVudCx1PWwuY29udGFpbm1lbnQsZD11IGluc3RhbmNlb2YgdD91LmdldCgwKTovcGFyZW50Ly50ZXN0KHUpP2MucGFyZW50KCkuZ2V0KDApOnU7ZCYmKGguY29udGFpbmVyRWxlbWVudD10KGQpLC9kb2N1bWVudC8udGVzdCh1KXx8dT09PWRvY3VtZW50PyhoLmNvbnRhaW5lck9mZnNldD17bGVmdDowLHRvcDowfSxoLmNvbnRhaW5lclBvc2l0aW9uPXtsZWZ0OjAsdG9wOjB9LGgucGFyZW50RGF0YT17ZWxlbWVudDp0KGRvY3VtZW50KSxsZWZ0OjAsdG9wOjAsd2lkdGg6dChkb2N1bWVudCkud2lkdGgoKSxoZWlnaHQ6dChkb2N1bWVudCkuaGVpZ2h0KCl8fGRvY3VtZW50LmJvZHkucGFyZW50Tm9kZS5zY3JvbGxIZWlnaHR9KTooZT10KGQpLGk9W10sdChbXCJUb3BcIixcIlJpZ2h0XCIsXCJMZWZ0XCIsXCJCb3R0b21cIl0pLmVhY2goZnVuY3Rpb24odCxzKXtpW3RdPWguX251bShlLmNzcyhcInBhZGRpbmdcIitzKSl9KSxoLmNvbnRhaW5lck9mZnNldD1lLm9mZnNldCgpLGguY29udGFpbmVyUG9zaXRpb249ZS5wb3NpdGlvbigpLGguY29udGFpbmVyU2l6ZT17aGVpZ2h0OmUuaW5uZXJIZWlnaHQoKS1pWzNdLHdpZHRoOmUuaW5uZXJXaWR0aCgpLWlbMV19LHM9aC5jb250YWluZXJPZmZzZXQsbj1oLmNvbnRhaW5lclNpemUuaGVpZ2h0LG89aC5jb250YWluZXJTaXplLndpZHRoLGE9aC5faGFzU2Nyb2xsKGQsXCJsZWZ0XCIpP2Quc2Nyb2xsV2lkdGg6byxyPWguX2hhc1Njcm9sbChkKT9kLnNjcm9sbEhlaWdodDpuLGgucGFyZW50RGF0YT17ZWxlbWVudDpkLGxlZnQ6cy5sZWZ0LHRvcDpzLnRvcCx3aWR0aDphLGhlaWdodDpyfSkpfSxyZXNpemU6ZnVuY3Rpb24oZSl7dmFyIGkscyxuLG8sYT10KHRoaXMpLnJlc2l6YWJsZShcImluc3RhbmNlXCIpLHI9YS5vcHRpb25zLGg9YS5jb250YWluZXJPZmZzZXQsbD1hLnBvc2l0aW9uLGM9YS5fYXNwZWN0UmF0aW98fGUuc2hpZnRLZXksdT17dG9wOjAsbGVmdDowfSxkPWEuY29udGFpbmVyRWxlbWVudCxwPSEwO2RbMF0hPT1kb2N1bWVudCYmL3N0YXRpYy8udGVzdChkLmNzcyhcInBvc2l0aW9uXCIpKSYmKHU9aCksbC5sZWZ0PChhLl9oZWxwZXI/aC5sZWZ0OjApJiYoYS5zaXplLndpZHRoPWEuc2l6ZS53aWR0aCsoYS5faGVscGVyP2EucG9zaXRpb24ubGVmdC1oLmxlZnQ6YS5wb3NpdGlvbi5sZWZ0LXUubGVmdCksYyYmKGEuc2l6ZS5oZWlnaHQ9YS5zaXplLndpZHRoL2EuYXNwZWN0UmF0aW8scD0hMSksYS5wb3NpdGlvbi5sZWZ0PXIuaGVscGVyP2gubGVmdDowKSxsLnRvcDwoYS5faGVscGVyP2gudG9wOjApJiYoYS5zaXplLmhlaWdodD1hLnNpemUuaGVpZ2h0KyhhLl9oZWxwZXI/YS5wb3NpdGlvbi50b3AtaC50b3A6YS5wb3NpdGlvbi50b3ApLGMmJihhLnNpemUud2lkdGg9YS5zaXplLmhlaWdodCphLmFzcGVjdFJhdGlvLHA9ITEpLGEucG9zaXRpb24udG9wPWEuX2hlbHBlcj9oLnRvcDowKSxuPWEuY29udGFpbmVyRWxlbWVudC5nZXQoMCk9PT1hLmVsZW1lbnQucGFyZW50KCkuZ2V0KDApLG89L3JlbGF0aXZlfGFic29sdXRlLy50ZXN0KGEuY29udGFpbmVyRWxlbWVudC5jc3MoXCJwb3NpdGlvblwiKSksbiYmbz8oYS5vZmZzZXQubGVmdD1hLnBhcmVudERhdGEubGVmdCthLnBvc2l0aW9uLmxlZnQsYS5vZmZzZXQudG9wPWEucGFyZW50RGF0YS50b3ArYS5wb3NpdGlvbi50b3ApOihhLm9mZnNldC5sZWZ0PWEuZWxlbWVudC5vZmZzZXQoKS5sZWZ0LGEub2Zmc2V0LnRvcD1hLmVsZW1lbnQub2Zmc2V0KCkudG9wKSxpPU1hdGguYWJzKGEuc2l6ZURpZmYud2lkdGgrKGEuX2hlbHBlcj9hLm9mZnNldC5sZWZ0LXUubGVmdDphLm9mZnNldC5sZWZ0LWgubGVmdCkpLHM9TWF0aC5hYnMoYS5zaXplRGlmZi5oZWlnaHQrKGEuX2hlbHBlcj9hLm9mZnNldC50b3AtdS50b3A6YS5vZmZzZXQudG9wLWgudG9wKSksaSthLnNpemUud2lkdGg+PWEucGFyZW50RGF0YS53aWR0aCYmKGEuc2l6ZS53aWR0aD1hLnBhcmVudERhdGEud2lkdGgtaSxjJiYoYS5zaXplLmhlaWdodD1hLnNpemUud2lkdGgvYS5hc3BlY3RSYXRpbyxwPSExKSkscythLnNpemUuaGVpZ2h0Pj1hLnBhcmVudERhdGEuaGVpZ2h0JiYoYS5zaXplLmhlaWdodD1hLnBhcmVudERhdGEuaGVpZ2h0LXMsYyYmKGEuc2l6ZS53aWR0aD1hLnNpemUuaGVpZ2h0KmEuYXNwZWN0UmF0aW8scD0hMSkpLHB8fChhLnBvc2l0aW9uLmxlZnQ9YS5wcmV2UG9zaXRpb24ubGVmdCxhLnBvc2l0aW9uLnRvcD1hLnByZXZQb3NpdGlvbi50b3AsYS5zaXplLndpZHRoPWEucHJldlNpemUud2lkdGgsYS5zaXplLmhlaWdodD1hLnByZXZTaXplLmhlaWdodCl9LHN0b3A6ZnVuY3Rpb24oKXt2YXIgZT10KHRoaXMpLnJlc2l6YWJsZShcImluc3RhbmNlXCIpLGk9ZS5vcHRpb25zLHM9ZS5jb250YWluZXJPZmZzZXQsbj1lLmNvbnRhaW5lclBvc2l0aW9uLG89ZS5jb250YWluZXJFbGVtZW50LGE9dChlLmhlbHBlcikscj1hLm9mZnNldCgpLGg9YS5vdXRlcldpZHRoKCktZS5zaXplRGlmZi53aWR0aCxsPWEub3V0ZXJIZWlnaHQoKS1lLnNpemVEaWZmLmhlaWdodDtlLl9oZWxwZXImJiFpLmFuaW1hdGUmJi9yZWxhdGl2ZS8udGVzdChvLmNzcyhcInBvc2l0aW9uXCIpKSYmdCh0aGlzKS5jc3Moe2xlZnQ6ci5sZWZ0LW4ubGVmdC1zLmxlZnQsd2lkdGg6aCxoZWlnaHQ6bH0pLGUuX2hlbHBlciYmIWkuYW5pbWF0ZSYmL3N0YXRpYy8udGVzdChvLmNzcyhcInBvc2l0aW9uXCIpKSYmdCh0aGlzKS5jc3Moe2xlZnQ6ci5sZWZ0LW4ubGVmdC1zLmxlZnQsd2lkdGg6aCxoZWlnaHQ6bH0pfX0pLHQudWkucGx1Z2luLmFkZChcInJlc2l6YWJsZVwiLFwiYWxzb1Jlc2l6ZVwiLHtzdGFydDpmdW5jdGlvbigpe3ZhciBlPXQodGhpcykucmVzaXphYmxlKFwiaW5zdGFuY2VcIiksaT1lLm9wdGlvbnM7dChpLmFsc29SZXNpemUpLmVhY2goZnVuY3Rpb24oKXt2YXIgZT10KHRoaXMpO2UuZGF0YShcInVpLXJlc2l6YWJsZS1hbHNvcmVzaXplXCIse3dpZHRoOnBhcnNlRmxvYXQoZS53aWR0aCgpKSxoZWlnaHQ6cGFyc2VGbG9hdChlLmhlaWdodCgpKSxsZWZ0OnBhcnNlRmxvYXQoZS5jc3MoXCJsZWZ0XCIpKSx0b3A6cGFyc2VGbG9hdChlLmNzcyhcInRvcFwiKSl9KX0pfSxyZXNpemU6ZnVuY3Rpb24oZSxpKXt2YXIgcz10KHRoaXMpLnJlc2l6YWJsZShcImluc3RhbmNlXCIpLG49cy5vcHRpb25zLG89cy5vcmlnaW5hbFNpemUsYT1zLm9yaWdpbmFsUG9zaXRpb24scj17aGVpZ2h0OnMuc2l6ZS5oZWlnaHQtby5oZWlnaHR8fDAsd2lkdGg6cy5zaXplLndpZHRoLW8ud2lkdGh8fDAsdG9wOnMucG9zaXRpb24udG9wLWEudG9wfHwwLGxlZnQ6cy5wb3NpdGlvbi5sZWZ0LWEubGVmdHx8MH07XG50KG4uYWxzb1Jlc2l6ZSkuZWFjaChmdW5jdGlvbigpe3ZhciBlPXQodGhpcykscz10KHRoaXMpLmRhdGEoXCJ1aS1yZXNpemFibGUtYWxzb3Jlc2l6ZVwiKSxuPXt9LG89ZS5wYXJlbnRzKGkub3JpZ2luYWxFbGVtZW50WzBdKS5sZW5ndGg/W1wid2lkdGhcIixcImhlaWdodFwiXTpbXCJ3aWR0aFwiLFwiaGVpZ2h0XCIsXCJ0b3BcIixcImxlZnRcIl07dC5lYWNoKG8sZnVuY3Rpb24odCxlKXt2YXIgaT0oc1tlXXx8MCkrKHJbZV18fDApO2kmJmk+PTAmJihuW2VdPWl8fG51bGwpfSksZS5jc3Mobil9KX0sc3RvcDpmdW5jdGlvbigpe3QodGhpcykucmVtb3ZlRGF0YShcInVpLXJlc2l6YWJsZS1hbHNvcmVzaXplXCIpfX0pLHQudWkucGx1Z2luLmFkZChcInJlc2l6YWJsZVwiLFwiZ2hvc3RcIix7c3RhcnQ6ZnVuY3Rpb24oKXt2YXIgZT10KHRoaXMpLnJlc2l6YWJsZShcImluc3RhbmNlXCIpLGk9ZS5zaXplO2UuZ2hvc3Q9ZS5vcmlnaW5hbEVsZW1lbnQuY2xvbmUoKSxlLmdob3N0LmNzcyh7b3BhY2l0eTouMjUsZGlzcGxheTpcImJsb2NrXCIscG9zaXRpb246XCJyZWxhdGl2ZVwiLGhlaWdodDppLmhlaWdodCx3aWR0aDppLndpZHRoLG1hcmdpbjowLGxlZnQ6MCx0b3A6MH0pLGUuX2FkZENsYXNzKGUuZ2hvc3QsXCJ1aS1yZXNpemFibGUtZ2hvc3RcIiksdC51aUJhY2tDb21wYXQhPT0hMSYmXCJzdHJpbmdcIj09dHlwZW9mIGUub3B0aW9ucy5naG9zdCYmZS5naG9zdC5hZGRDbGFzcyh0aGlzLm9wdGlvbnMuZ2hvc3QpLGUuZ2hvc3QuYXBwZW5kVG8oZS5oZWxwZXIpfSxyZXNpemU6ZnVuY3Rpb24oKXt2YXIgZT10KHRoaXMpLnJlc2l6YWJsZShcImluc3RhbmNlXCIpO2UuZ2hvc3QmJmUuZ2hvc3QuY3NzKHtwb3NpdGlvbjpcInJlbGF0aXZlXCIsaGVpZ2h0OmUuc2l6ZS5oZWlnaHQsd2lkdGg6ZS5zaXplLndpZHRofSl9LHN0b3A6ZnVuY3Rpb24oKXt2YXIgZT10KHRoaXMpLnJlc2l6YWJsZShcImluc3RhbmNlXCIpO2UuZ2hvc3QmJmUuaGVscGVyJiZlLmhlbHBlci5nZXQoMCkucmVtb3ZlQ2hpbGQoZS5naG9zdC5nZXQoMCkpfX0pLHQudWkucGx1Z2luLmFkZChcInJlc2l6YWJsZVwiLFwiZ3JpZFwiLHtyZXNpemU6ZnVuY3Rpb24oKXt2YXIgZSxpPXQodGhpcykucmVzaXphYmxlKFwiaW5zdGFuY2VcIikscz1pLm9wdGlvbnMsbj1pLnNpemUsbz1pLm9yaWdpbmFsU2l6ZSxhPWkub3JpZ2luYWxQb3NpdGlvbixyPWkuYXhpcyxoPVwibnVtYmVyXCI9PXR5cGVvZiBzLmdyaWQ/W3MuZ3JpZCxzLmdyaWRdOnMuZ3JpZCxsPWhbMF18fDEsYz1oWzFdfHwxLHU9TWF0aC5yb3VuZCgobi53aWR0aC1vLndpZHRoKS9sKSpsLGQ9TWF0aC5yb3VuZCgobi5oZWlnaHQtby5oZWlnaHQpL2MpKmMscD1vLndpZHRoK3UsZj1vLmhlaWdodCtkLGc9cy5tYXhXaWR0aCYmcD5zLm1heFdpZHRoLG09cy5tYXhIZWlnaHQmJmY+cy5tYXhIZWlnaHQsXz1zLm1pbldpZHRoJiZzLm1pbldpZHRoPnAsdj1zLm1pbkhlaWdodCYmcy5taW5IZWlnaHQ+ZjtzLmdyaWQ9aCxfJiYocCs9bCksdiYmKGYrPWMpLGcmJihwLT1sKSxtJiYoZi09YyksL14oc2V8c3xlKSQvLnRlc3Qocik/KGkuc2l6ZS53aWR0aD1wLGkuc2l6ZS5oZWlnaHQ9Zik6L14obmUpJC8udGVzdChyKT8oaS5zaXplLndpZHRoPXAsaS5zaXplLmhlaWdodD1mLGkucG9zaXRpb24udG9wPWEudG9wLWQpOi9eKHN3KSQvLnRlc3Qocik/KGkuc2l6ZS53aWR0aD1wLGkuc2l6ZS5oZWlnaHQ9ZixpLnBvc2l0aW9uLmxlZnQ9YS5sZWZ0LXUpOigoMD49Zi1jfHwwPj1wLWwpJiYoZT1pLl9nZXRQYWRkaW5nUGx1c0JvcmRlckRpbWVuc2lvbnModGhpcykpLGYtYz4wPyhpLnNpemUuaGVpZ2h0PWYsaS5wb3NpdGlvbi50b3A9YS50b3AtZCk6KGY9Yy1lLmhlaWdodCxpLnNpemUuaGVpZ2h0PWYsaS5wb3NpdGlvbi50b3A9YS50b3Arby5oZWlnaHQtZikscC1sPjA/KGkuc2l6ZS53aWR0aD1wLGkucG9zaXRpb24ubGVmdD1hLmxlZnQtdSk6KHA9bC1lLndpZHRoLGkuc2l6ZS53aWR0aD1wLGkucG9zaXRpb24ubGVmdD1hLmxlZnQrby53aWR0aC1wKSl9fSksdC51aS5yZXNpemFibGUsdC53aWRnZXQoXCJ1aS5zZWxlY3RhYmxlXCIsdC51aS5tb3VzZSx7dmVyc2lvbjpcIjEuMTIuMVwiLG9wdGlvbnM6e2FwcGVuZFRvOlwiYm9keVwiLGF1dG9SZWZyZXNoOiEwLGRpc3RhbmNlOjAsZmlsdGVyOlwiKlwiLHRvbGVyYW5jZTpcInRvdWNoXCIsc2VsZWN0ZWQ6bnVsbCxzZWxlY3Rpbmc6bnVsbCxzdGFydDpudWxsLHN0b3A6bnVsbCx1bnNlbGVjdGVkOm51bGwsdW5zZWxlY3Rpbmc6bnVsbH0sX2NyZWF0ZTpmdW5jdGlvbigpe3ZhciBlPXRoaXM7dGhpcy5fYWRkQ2xhc3MoXCJ1aS1zZWxlY3RhYmxlXCIpLHRoaXMuZHJhZ2dlZD0hMSx0aGlzLnJlZnJlc2g9ZnVuY3Rpb24oKXtlLmVsZW1lbnRQb3M9dChlLmVsZW1lbnRbMF0pLm9mZnNldCgpLGUuc2VsZWN0ZWVzPXQoZS5vcHRpb25zLmZpbHRlcixlLmVsZW1lbnRbMF0pLGUuX2FkZENsYXNzKGUuc2VsZWN0ZWVzLFwidWktc2VsZWN0ZWVcIiksZS5zZWxlY3RlZXMuZWFjaChmdW5jdGlvbigpe3ZhciBpPXQodGhpcykscz1pLm9mZnNldCgpLG49e2xlZnQ6cy5sZWZ0LWUuZWxlbWVudFBvcy5sZWZ0LHRvcDpzLnRvcC1lLmVsZW1lbnRQb3MudG9wfTt0LmRhdGEodGhpcyxcInNlbGVjdGFibGUtaXRlbVwiLHtlbGVtZW50OnRoaXMsJGVsZW1lbnQ6aSxsZWZ0Om4ubGVmdCx0b3A6bi50b3AscmlnaHQ6bi5sZWZ0K2kub3V0ZXJXaWR0aCgpLGJvdHRvbTpuLnRvcCtpLm91dGVySGVpZ2h0KCksc3RhcnRzZWxlY3RlZDohMSxzZWxlY3RlZDppLmhhc0NsYXNzKFwidWktc2VsZWN0ZWRcIiksc2VsZWN0aW5nOmkuaGFzQ2xhc3MoXCJ1aS1zZWxlY3RpbmdcIiksdW5zZWxlY3Rpbmc6aS5oYXNDbGFzcyhcInVpLXVuc2VsZWN0aW5nXCIpfSl9KX0sdGhpcy5yZWZyZXNoKCksdGhpcy5fbW91c2VJbml0KCksdGhpcy5oZWxwZXI9dChcIjxkaXY+XCIpLHRoaXMuX2FkZENsYXNzKHRoaXMuaGVscGVyLFwidWktc2VsZWN0YWJsZS1oZWxwZXJcIil9LF9kZXN0cm95OmZ1bmN0aW9uKCl7dGhpcy5zZWxlY3RlZXMucmVtb3ZlRGF0YShcInNlbGVjdGFibGUtaXRlbVwiKSx0aGlzLl9tb3VzZURlc3Ryb3koKX0sX21vdXNlU3RhcnQ6ZnVuY3Rpb24oZSl7dmFyIGk9dGhpcyxzPXRoaXMub3B0aW9uczt0aGlzLm9wb3M9W2UucGFnZVgsZS5wYWdlWV0sdGhpcy5lbGVtZW50UG9zPXQodGhpcy5lbGVtZW50WzBdKS5vZmZzZXQoKSx0aGlzLm9wdGlvbnMuZGlzYWJsZWR8fCh0aGlzLnNlbGVjdGVlcz10KHMuZmlsdGVyLHRoaXMuZWxlbWVudFswXSksdGhpcy5fdHJpZ2dlcihcInN0YXJ0XCIsZSksdChzLmFwcGVuZFRvKS5hcHBlbmQodGhpcy5oZWxwZXIpLHRoaXMuaGVscGVyLmNzcyh7bGVmdDplLnBhZ2VYLHRvcDplLnBhZ2VZLHdpZHRoOjAsaGVpZ2h0OjB9KSxzLmF1dG9SZWZyZXNoJiZ0aGlzLnJlZnJlc2goKSx0aGlzLnNlbGVjdGVlcy5maWx0ZXIoXCIudWktc2VsZWN0ZWRcIikuZWFjaChmdW5jdGlvbigpe3ZhciBzPXQuZGF0YSh0aGlzLFwic2VsZWN0YWJsZS1pdGVtXCIpO3Muc3RhcnRzZWxlY3RlZD0hMCxlLm1ldGFLZXl8fGUuY3RybEtleXx8KGkuX3JlbW92ZUNsYXNzKHMuJGVsZW1lbnQsXCJ1aS1zZWxlY3RlZFwiKSxzLnNlbGVjdGVkPSExLGkuX2FkZENsYXNzKHMuJGVsZW1lbnQsXCJ1aS11bnNlbGVjdGluZ1wiKSxzLnVuc2VsZWN0aW5nPSEwLGkuX3RyaWdnZXIoXCJ1bnNlbGVjdGluZ1wiLGUse3Vuc2VsZWN0aW5nOnMuZWxlbWVudH0pKX0pLHQoZS50YXJnZXQpLnBhcmVudHMoKS5hZGRCYWNrKCkuZWFjaChmdW5jdGlvbigpe3ZhciBzLG49dC5kYXRhKHRoaXMsXCJzZWxlY3RhYmxlLWl0ZW1cIik7cmV0dXJuIG4/KHM9IWUubWV0YUtleSYmIWUuY3RybEtleXx8IW4uJGVsZW1lbnQuaGFzQ2xhc3MoXCJ1aS1zZWxlY3RlZFwiKSxpLl9yZW1vdmVDbGFzcyhuLiRlbGVtZW50LHM/XCJ1aS11bnNlbGVjdGluZ1wiOlwidWktc2VsZWN0ZWRcIikuX2FkZENsYXNzKG4uJGVsZW1lbnQscz9cInVpLXNlbGVjdGluZ1wiOlwidWktdW5zZWxlY3RpbmdcIiksbi51bnNlbGVjdGluZz0hcyxuLnNlbGVjdGluZz1zLG4uc2VsZWN0ZWQ9cyxzP2kuX3RyaWdnZXIoXCJzZWxlY3RpbmdcIixlLHtzZWxlY3Rpbmc6bi5lbGVtZW50fSk6aS5fdHJpZ2dlcihcInVuc2VsZWN0aW5nXCIsZSx7dW5zZWxlY3Rpbmc6bi5lbGVtZW50fSksITEpOnZvaWQgMH0pKX0sX21vdXNlRHJhZzpmdW5jdGlvbihlKXtpZih0aGlzLmRyYWdnZWQ9ITAsIXRoaXMub3B0aW9ucy5kaXNhYmxlZCl7dmFyIGkscz10aGlzLG49dGhpcy5vcHRpb25zLG89dGhpcy5vcG9zWzBdLGE9dGhpcy5vcG9zWzFdLHI9ZS5wYWdlWCxoPWUucGFnZVk7cmV0dXJuIG8+ciYmKGk9cixyPW8sbz1pKSxhPmgmJihpPWgsaD1hLGE9aSksdGhpcy5oZWxwZXIuY3NzKHtsZWZ0Om8sdG9wOmEsd2lkdGg6ci1vLGhlaWdodDpoLWF9KSx0aGlzLnNlbGVjdGVlcy5lYWNoKGZ1bmN0aW9uKCl7dmFyIGk9dC5kYXRhKHRoaXMsXCJzZWxlY3RhYmxlLWl0ZW1cIiksbD0hMSxjPXt9O2kmJmkuZWxlbWVudCE9PXMuZWxlbWVudFswXSYmKGMubGVmdD1pLmxlZnQrcy5lbGVtZW50UG9zLmxlZnQsYy5yaWdodD1pLnJpZ2h0K3MuZWxlbWVudFBvcy5sZWZ0LGMudG9wPWkudG9wK3MuZWxlbWVudFBvcy50b3AsYy5ib3R0b209aS5ib3R0b20rcy5lbGVtZW50UG9zLnRvcCxcInRvdWNoXCI9PT1uLnRvbGVyYW5jZT9sPSEoYy5sZWZ0PnJ8fG8+Yy5yaWdodHx8Yy50b3A+aHx8YT5jLmJvdHRvbSk6XCJmaXRcIj09PW4udG9sZXJhbmNlJiYobD1jLmxlZnQ+byYmcj5jLnJpZ2h0JiZjLnRvcD5hJiZoPmMuYm90dG9tKSxsPyhpLnNlbGVjdGVkJiYocy5fcmVtb3ZlQ2xhc3MoaS4kZWxlbWVudCxcInVpLXNlbGVjdGVkXCIpLGkuc2VsZWN0ZWQ9ITEpLGkudW5zZWxlY3RpbmcmJihzLl9yZW1vdmVDbGFzcyhpLiRlbGVtZW50LFwidWktdW5zZWxlY3RpbmdcIiksaS51bnNlbGVjdGluZz0hMSksaS5zZWxlY3Rpbmd8fChzLl9hZGRDbGFzcyhpLiRlbGVtZW50LFwidWktc2VsZWN0aW5nXCIpLGkuc2VsZWN0aW5nPSEwLHMuX3RyaWdnZXIoXCJzZWxlY3RpbmdcIixlLHtzZWxlY3Rpbmc6aS5lbGVtZW50fSkpKTooaS5zZWxlY3RpbmcmJigoZS5tZXRhS2V5fHxlLmN0cmxLZXkpJiZpLnN0YXJ0c2VsZWN0ZWQ/KHMuX3JlbW92ZUNsYXNzKGkuJGVsZW1lbnQsXCJ1aS1zZWxlY3RpbmdcIiksaS5zZWxlY3Rpbmc9ITEscy5fYWRkQ2xhc3MoaS4kZWxlbWVudCxcInVpLXNlbGVjdGVkXCIpLGkuc2VsZWN0ZWQ9ITApOihzLl9yZW1vdmVDbGFzcyhpLiRlbGVtZW50LFwidWktc2VsZWN0aW5nXCIpLGkuc2VsZWN0aW5nPSExLGkuc3RhcnRzZWxlY3RlZCYmKHMuX2FkZENsYXNzKGkuJGVsZW1lbnQsXCJ1aS11bnNlbGVjdGluZ1wiKSxpLnVuc2VsZWN0aW5nPSEwKSxzLl90cmlnZ2VyKFwidW5zZWxlY3RpbmdcIixlLHt1bnNlbGVjdGluZzppLmVsZW1lbnR9KSkpLGkuc2VsZWN0ZWQmJihlLm1ldGFLZXl8fGUuY3RybEtleXx8aS5zdGFydHNlbGVjdGVkfHwocy5fcmVtb3ZlQ2xhc3MoaS4kZWxlbWVudCxcInVpLXNlbGVjdGVkXCIpLGkuc2VsZWN0ZWQ9ITEscy5fYWRkQ2xhc3MoaS4kZWxlbWVudCxcInVpLXVuc2VsZWN0aW5nXCIpLGkudW5zZWxlY3Rpbmc9ITAscy5fdHJpZ2dlcihcInVuc2VsZWN0aW5nXCIsZSx7dW5zZWxlY3Rpbmc6aS5lbGVtZW50fSkpKSkpfSksITF9fSxfbW91c2VTdG9wOmZ1bmN0aW9uKGUpe3ZhciBpPXRoaXM7cmV0dXJuIHRoaXMuZHJhZ2dlZD0hMSx0KFwiLnVpLXVuc2VsZWN0aW5nXCIsdGhpcy5lbGVtZW50WzBdKS5lYWNoKGZ1bmN0aW9uKCl7dmFyIHM9dC5kYXRhKHRoaXMsXCJzZWxlY3RhYmxlLWl0ZW1cIik7aS5fcmVtb3ZlQ2xhc3Mocy4kZWxlbWVudCxcInVpLXVuc2VsZWN0aW5nXCIpLHMudW5zZWxlY3Rpbmc9ITEscy5zdGFydHNlbGVjdGVkPSExLGkuX3RyaWdnZXIoXCJ1bnNlbGVjdGVkXCIsZSx7dW5zZWxlY3RlZDpzLmVsZW1lbnR9KX0pLHQoXCIudWktc2VsZWN0aW5nXCIsdGhpcy5lbGVtZW50WzBdKS5lYWNoKGZ1bmN0aW9uKCl7dmFyIHM9dC5kYXRhKHRoaXMsXCJzZWxlY3RhYmxlLWl0ZW1cIik7aS5fcmVtb3ZlQ2xhc3Mocy4kZWxlbWVudCxcInVpLXNlbGVjdGluZ1wiKS5fYWRkQ2xhc3Mocy4kZWxlbWVudCxcInVpLXNlbGVjdGVkXCIpLHMuc2VsZWN0aW5nPSExLHMuc2VsZWN0ZWQ9ITAscy5zdGFydHNlbGVjdGVkPSEwLGkuX3RyaWdnZXIoXCJzZWxlY3RlZFwiLGUse3NlbGVjdGVkOnMuZWxlbWVudH0pfSksdGhpcy5fdHJpZ2dlcihcInN0b3BcIixlKSx0aGlzLmhlbHBlci5yZW1vdmUoKSwhMX19KSx0LndpZGdldChcInVpLnNvcnRhYmxlXCIsdC51aS5tb3VzZSx7dmVyc2lvbjpcIjEuMTIuMVwiLHdpZGdldEV2ZW50UHJlZml4Olwic29ydFwiLHJlYWR5OiExLG9wdGlvbnM6e2FwcGVuZFRvOlwicGFyZW50XCIsYXhpczohMSxjb25uZWN0V2l0aDohMSxjb250YWlubWVudDohMSxjdXJzb3I6XCJhdXRvXCIsY3Vyc29yQXQ6ITEsZHJvcE9uRW1wdHk6ITAsZm9yY2VQbGFjZWhvbGRlclNpemU6ITEsZm9yY2VIZWxwZXJTaXplOiExLGdyaWQ6ITEsaGFuZGxlOiExLGhlbHBlcjpcIm9yaWdpbmFsXCIsaXRlbXM6XCI+ICpcIixvcGFjaXR5OiExLHBsYWNlaG9sZGVyOiExLHJldmVydDohMSxzY3JvbGw6ITAsc2Nyb2xsU2Vuc2l0aXZpdHk6MjAsc2Nyb2xsU3BlZWQ6MjAsc2NvcGU6XCJkZWZhdWx0XCIsdG9sZXJhbmNlOlwiaW50ZXJzZWN0XCIsekluZGV4OjFlMyxhY3RpdmF0ZTpudWxsLGJlZm9yZVN0b3A6bnVsbCxjaGFuZ2U6bnVsbCxkZWFjdGl2YXRlOm51bGwsb3V0Om51bGwsb3ZlcjpudWxsLHJlY2VpdmU6bnVsbCxyZW1vdmU6bnVsbCxzb3J0Om51bGwsc3RhcnQ6bnVsbCxzdG9wOm51bGwsdXBkYXRlOm51bGx9LF9pc092ZXJBeGlzOmZ1bmN0aW9uKHQsZSxpKXtyZXR1cm4gdD49ZSYmZStpPnR9LF9pc0Zsb2F0aW5nOmZ1bmN0aW9uKHQpe3JldHVybi9sZWZ0fHJpZ2h0Ly50ZXN0KHQuY3NzKFwiZmxvYXRcIikpfHwvaW5saW5lfHRhYmxlLWNlbGwvLnRlc3QodC5jc3MoXCJkaXNwbGF5XCIpKX0sX2NyZWF0ZTpmdW5jdGlvbigpe3RoaXMuY29udGFpbmVyQ2FjaGU9e30sdGhpcy5fYWRkQ2xhc3MoXCJ1aS1zb3J0YWJsZVwiKSx0aGlzLnJlZnJlc2goKSx0aGlzLm9mZnNldD10aGlzLmVsZW1lbnQub2Zmc2V0KCksdGhpcy5fbW91c2VJbml0KCksdGhpcy5fc2V0SGFuZGxlQ2xhc3NOYW1lKCksdGhpcy5yZWFkeT0hMH0sX3NldE9wdGlvbjpmdW5jdGlvbih0LGUpe3RoaXMuX3N1cGVyKHQsZSksXCJoYW5kbGVcIj09PXQmJnRoaXMuX3NldEhhbmRsZUNsYXNzTmFtZSgpfSxfc2V0SGFuZGxlQ2xhc3NOYW1lOmZ1bmN0aW9uKCl7dmFyIGU9dGhpczt0aGlzLl9yZW1vdmVDbGFzcyh0aGlzLmVsZW1lbnQuZmluZChcIi51aS1zb3J0YWJsZS1oYW5kbGVcIiksXCJ1aS1zb3J0YWJsZS1oYW5kbGVcIiksdC5lYWNoKHRoaXMuaXRlbXMsZnVuY3Rpb24oKXtlLl9hZGRDbGFzcyh0aGlzLmluc3RhbmNlLm9wdGlvbnMuaGFuZGxlP3RoaXMuaXRlbS5maW5kKHRoaXMuaW5zdGFuY2Uub3B0aW9ucy5oYW5kbGUpOnRoaXMuaXRlbSxcInVpLXNvcnRhYmxlLWhhbmRsZVwiKX0pfSxfZGVzdHJveTpmdW5jdGlvbigpe3RoaXMuX21vdXNlRGVzdHJveSgpO2Zvcih2YXIgdD10aGlzLml0ZW1zLmxlbmd0aC0xO3Q+PTA7dC0tKXRoaXMuaXRlbXNbdF0uaXRlbS5yZW1vdmVEYXRhKHRoaXMud2lkZ2V0TmFtZStcIi1pdGVtXCIpO3JldHVybiB0aGlzfSxfbW91c2VDYXB0dXJlOmZ1bmN0aW9uKGUsaSl7dmFyIHM9bnVsbCxuPSExLG89dGhpcztyZXR1cm4gdGhpcy5yZXZlcnRpbmc/ITE6dGhpcy5vcHRpb25zLmRpc2FibGVkfHxcInN0YXRpY1wiPT09dGhpcy5vcHRpb25zLnR5cGU/ITE6KHRoaXMuX3JlZnJlc2hJdGVtcyhlKSx0KGUudGFyZ2V0KS5wYXJlbnRzKCkuZWFjaChmdW5jdGlvbigpe3JldHVybiB0LmRhdGEodGhpcyxvLndpZGdldE5hbWUrXCItaXRlbVwiKT09PW8/KHM9dCh0aGlzKSwhMSk6dm9pZCAwfSksdC5kYXRhKGUudGFyZ2V0LG8ud2lkZ2V0TmFtZStcIi1pdGVtXCIpPT09byYmKHM9dChlLnRhcmdldCkpLHM/IXRoaXMub3B0aW9ucy5oYW5kbGV8fGl8fCh0KHRoaXMub3B0aW9ucy5oYW5kbGUscykuZmluZChcIipcIikuYWRkQmFjaygpLmVhY2goZnVuY3Rpb24oKXt0aGlzPT09ZS50YXJnZXQmJihuPSEwKX0pLG4pPyh0aGlzLmN1cnJlbnRJdGVtPXMsdGhpcy5fcmVtb3ZlQ3VycmVudHNGcm9tSXRlbXMoKSwhMCk6ITE6ITEpfSxfbW91c2VTdGFydDpmdW5jdGlvbihlLGkscyl7dmFyIG4sbyxhPXRoaXMub3B0aW9ucztpZih0aGlzLmN1cnJlbnRDb250YWluZXI9dGhpcyx0aGlzLnJlZnJlc2hQb3NpdGlvbnMoKSx0aGlzLmhlbHBlcj10aGlzLl9jcmVhdGVIZWxwZXIoZSksdGhpcy5fY2FjaGVIZWxwZXJQcm9wb3J0aW9ucygpLHRoaXMuX2NhY2hlTWFyZ2lucygpLHRoaXMuc2Nyb2xsUGFyZW50PXRoaXMuaGVscGVyLnNjcm9sbFBhcmVudCgpLHRoaXMub2Zmc2V0PXRoaXMuY3VycmVudEl0ZW0ub2Zmc2V0KCksdGhpcy5vZmZzZXQ9e3RvcDp0aGlzLm9mZnNldC50b3AtdGhpcy5tYXJnaW5zLnRvcCxsZWZ0OnRoaXMub2Zmc2V0LmxlZnQtdGhpcy5tYXJnaW5zLmxlZnR9LHQuZXh0ZW5kKHRoaXMub2Zmc2V0LHtjbGljazp7bGVmdDplLnBhZ2VYLXRoaXMub2Zmc2V0LmxlZnQsdG9wOmUucGFnZVktdGhpcy5vZmZzZXQudG9wfSxwYXJlbnQ6dGhpcy5fZ2V0UGFyZW50T2Zmc2V0KCkscmVsYXRpdmU6dGhpcy5fZ2V0UmVsYXRpdmVPZmZzZXQoKX0pLHRoaXMuaGVscGVyLmNzcyhcInBvc2l0aW9uXCIsXCJhYnNvbHV0ZVwiKSx0aGlzLmNzc1Bvc2l0aW9uPXRoaXMuaGVscGVyLmNzcyhcInBvc2l0aW9uXCIpLHRoaXMub3JpZ2luYWxQb3NpdGlvbj10aGlzLl9nZW5lcmF0ZVBvc2l0aW9uKGUpLHRoaXMub3JpZ2luYWxQYWdlWD1lLnBhZ2VYLHRoaXMub3JpZ2luYWxQYWdlWT1lLnBhZ2VZLGEuY3Vyc29yQXQmJnRoaXMuX2FkanVzdE9mZnNldEZyb21IZWxwZXIoYS5jdXJzb3JBdCksdGhpcy5kb21Qb3NpdGlvbj17cHJldjp0aGlzLmN1cnJlbnRJdGVtLnByZXYoKVswXSxwYXJlbnQ6dGhpcy5jdXJyZW50SXRlbS5wYXJlbnQoKVswXX0sdGhpcy5oZWxwZXJbMF0hPT10aGlzLmN1cnJlbnRJdGVtWzBdJiZ0aGlzLmN1cnJlbnRJdGVtLmhpZGUoKSx0aGlzLl9jcmVhdGVQbGFjZWhvbGRlcigpLGEuY29udGFpbm1lbnQmJnRoaXMuX3NldENvbnRhaW5tZW50KCksYS5jdXJzb3ImJlwiYXV0b1wiIT09YS5jdXJzb3ImJihvPXRoaXMuZG9jdW1lbnQuZmluZChcImJvZHlcIiksdGhpcy5zdG9yZWRDdXJzb3I9by5jc3MoXCJjdXJzb3JcIiksby5jc3MoXCJjdXJzb3JcIixhLmN1cnNvciksdGhpcy5zdG9yZWRTdHlsZXNoZWV0PXQoXCI8c3R5bGU+KnsgY3Vyc29yOiBcIithLmN1cnNvcitcIiAhaW1wb3J0YW50OyB9PC9zdHlsZT5cIikuYXBwZW5kVG8obykpLGEub3BhY2l0eSYmKHRoaXMuaGVscGVyLmNzcyhcIm9wYWNpdHlcIikmJih0aGlzLl9zdG9yZWRPcGFjaXR5PXRoaXMuaGVscGVyLmNzcyhcIm9wYWNpdHlcIikpLHRoaXMuaGVscGVyLmNzcyhcIm9wYWNpdHlcIixhLm9wYWNpdHkpKSxhLnpJbmRleCYmKHRoaXMuaGVscGVyLmNzcyhcInpJbmRleFwiKSYmKHRoaXMuX3N0b3JlZFpJbmRleD10aGlzLmhlbHBlci5jc3MoXCJ6SW5kZXhcIikpLHRoaXMuaGVscGVyLmNzcyhcInpJbmRleFwiLGEuekluZGV4KSksdGhpcy5zY3JvbGxQYXJlbnRbMF0hPT10aGlzLmRvY3VtZW50WzBdJiZcIkhUTUxcIiE9PXRoaXMuc2Nyb2xsUGFyZW50WzBdLnRhZ05hbWUmJih0aGlzLm92ZXJmbG93T2Zmc2V0PXRoaXMuc2Nyb2xsUGFyZW50Lm9mZnNldCgpKSx0aGlzLl90cmlnZ2VyKFwic3RhcnRcIixlLHRoaXMuX3VpSGFzaCgpKSx0aGlzLl9wcmVzZXJ2ZUhlbHBlclByb3BvcnRpb25zfHx0aGlzLl9jYWNoZUhlbHBlclByb3BvcnRpb25zKCksIXMpZm9yKG49dGhpcy5jb250YWluZXJzLmxlbmd0aC0xO24+PTA7bi0tKXRoaXMuY29udGFpbmVyc1tuXS5fdHJpZ2dlcihcImFjdGl2YXRlXCIsZSx0aGlzLl91aUhhc2godGhpcykpO3JldHVybiB0LnVpLmRkbWFuYWdlciYmKHQudWkuZGRtYW5hZ2VyLmN1cnJlbnQ9dGhpcyksdC51aS5kZG1hbmFnZXImJiFhLmRyb3BCZWhhdmlvdXImJnQudWkuZGRtYW5hZ2VyLnByZXBhcmVPZmZzZXRzKHRoaXMsZSksdGhpcy5kcmFnZ2luZz0hMCx0aGlzLl9hZGRDbGFzcyh0aGlzLmhlbHBlcixcInVpLXNvcnRhYmxlLWhlbHBlclwiKSx0aGlzLl9tb3VzZURyYWcoZSksITB9LF9tb3VzZURyYWc6ZnVuY3Rpb24oZSl7dmFyIGkscyxuLG8sYT10aGlzLm9wdGlvbnMscj0hMTtmb3IodGhpcy5wb3NpdGlvbj10aGlzLl9nZW5lcmF0ZVBvc2l0aW9uKGUpLHRoaXMucG9zaXRpb25BYnM9dGhpcy5fY29udmVydFBvc2l0aW9uVG8oXCJhYnNvbHV0ZVwiKSx0aGlzLmxhc3RQb3NpdGlvbkFic3x8KHRoaXMubGFzdFBvc2l0aW9uQWJzPXRoaXMucG9zaXRpb25BYnMpLHRoaXMub3B0aW9ucy5zY3JvbGwmJih0aGlzLnNjcm9sbFBhcmVudFswXSE9PXRoaXMuZG9jdW1lbnRbMF0mJlwiSFRNTFwiIT09dGhpcy5zY3JvbGxQYXJlbnRbMF0udGFnTmFtZT8odGhpcy5vdmVyZmxvd09mZnNldC50b3ArdGhpcy5zY3JvbGxQYXJlbnRbMF0ub2Zmc2V0SGVpZ2h0LWUucGFnZVk8YS5zY3JvbGxTZW5zaXRpdml0eT90aGlzLnNjcm9sbFBhcmVudFswXS5zY3JvbGxUb3A9cj10aGlzLnNjcm9sbFBhcmVudFswXS5zY3JvbGxUb3ArYS5zY3JvbGxTcGVlZDplLnBhZ2VZLXRoaXMub3ZlcmZsb3dPZmZzZXQudG9wPGEuc2Nyb2xsU2Vuc2l0aXZpdHkmJih0aGlzLnNjcm9sbFBhcmVudFswXS5zY3JvbGxUb3A9cj10aGlzLnNjcm9sbFBhcmVudFswXS5zY3JvbGxUb3AtYS5zY3JvbGxTcGVlZCksdGhpcy5vdmVyZmxvd09mZnNldC5sZWZ0K3RoaXMuc2Nyb2xsUGFyZW50WzBdLm9mZnNldFdpZHRoLWUucGFnZVg8YS5zY3JvbGxTZW5zaXRpdml0eT90aGlzLnNjcm9sbFBhcmVudFswXS5zY3JvbGxMZWZ0PXI9dGhpcy5zY3JvbGxQYXJlbnRbMF0uc2Nyb2xsTGVmdCthLnNjcm9sbFNwZWVkOmUucGFnZVgtdGhpcy5vdmVyZmxvd09mZnNldC5sZWZ0PGEuc2Nyb2xsU2Vuc2l0aXZpdHkmJih0aGlzLnNjcm9sbFBhcmVudFswXS5zY3JvbGxMZWZ0PXI9dGhpcy5zY3JvbGxQYXJlbnRbMF0uc2Nyb2xsTGVmdC1hLnNjcm9sbFNwZWVkKSk6KGUucGFnZVktdGhpcy5kb2N1bWVudC5zY3JvbGxUb3AoKTxhLnNjcm9sbFNlbnNpdGl2aXR5P3I9dGhpcy5kb2N1bWVudC5zY3JvbGxUb3AodGhpcy5kb2N1bWVudC5zY3JvbGxUb3AoKS1hLnNjcm9sbFNwZWVkKTp0aGlzLndpbmRvdy5oZWlnaHQoKS0oZS5wYWdlWS10aGlzLmRvY3VtZW50LnNjcm9sbFRvcCgpKTxhLnNjcm9sbFNlbnNpdGl2aXR5JiYocj10aGlzLmRvY3VtZW50LnNjcm9sbFRvcCh0aGlzLmRvY3VtZW50LnNjcm9sbFRvcCgpK2Euc2Nyb2xsU3BlZWQpKSxlLnBhZ2VYLXRoaXMuZG9jdW1lbnQuc2Nyb2xsTGVmdCgpPGEuc2Nyb2xsU2Vuc2l0aXZpdHk/cj10aGlzLmRvY3VtZW50LnNjcm9sbExlZnQodGhpcy5kb2N1bWVudC5zY3JvbGxMZWZ0KCktYS5zY3JvbGxTcGVlZCk6dGhpcy53aW5kb3cud2lkdGgoKS0oZS5wYWdlWC10aGlzLmRvY3VtZW50LnNjcm9sbExlZnQoKSk8YS5zY3JvbGxTZW5zaXRpdml0eSYmKHI9dGhpcy5kb2N1bWVudC5zY3JvbGxMZWZ0KHRoaXMuZG9jdW1lbnQuc2Nyb2xsTGVmdCgpK2Euc2Nyb2xsU3BlZWQpKSksciE9PSExJiZ0LnVpLmRkbWFuYWdlciYmIWEuZHJvcEJlaGF2aW91ciYmdC51aS5kZG1hbmFnZXIucHJlcGFyZU9mZnNldHModGhpcyxlKSksdGhpcy5wb3NpdGlvbkFicz10aGlzLl9jb252ZXJ0UG9zaXRpb25UbyhcImFic29sdXRlXCIpLHRoaXMub3B0aW9ucy5heGlzJiZcInlcIj09PXRoaXMub3B0aW9ucy5heGlzfHwodGhpcy5oZWxwZXJbMF0uc3R5bGUubGVmdD10aGlzLnBvc2l0aW9uLmxlZnQrXCJweFwiKSx0aGlzLm9wdGlvbnMuYXhpcyYmXCJ4XCI9PT10aGlzLm9wdGlvbnMuYXhpc3x8KHRoaXMuaGVscGVyWzBdLnN0eWxlLnRvcD10aGlzLnBvc2l0aW9uLnRvcCtcInB4XCIpLGk9dGhpcy5pdGVtcy5sZW5ndGgtMTtpPj0wO2ktLSlpZihzPXRoaXMuaXRlbXNbaV0sbj1zLml0ZW1bMF0sbz10aGlzLl9pbnRlcnNlY3RzV2l0aFBvaW50ZXIocyksbyYmcy5pbnN0YW5jZT09PXRoaXMuY3VycmVudENvbnRhaW5lciYmbiE9PXRoaXMuY3VycmVudEl0ZW1bMF0mJnRoaXMucGxhY2Vob2xkZXJbMT09PW8/XCJuZXh0XCI6XCJwcmV2XCJdKClbMF0hPT1uJiYhdC5jb250YWlucyh0aGlzLnBsYWNlaG9sZGVyWzBdLG4pJiYoXCJzZW1pLWR5bmFtaWNcIj09PXRoaXMub3B0aW9ucy50eXBlPyF0LmNvbnRhaW5zKHRoaXMuZWxlbWVudFswXSxuKTohMCkpe2lmKHRoaXMuZGlyZWN0aW9uPTE9PT1vP1wiZG93blwiOlwidXBcIixcInBvaW50ZXJcIiE9PXRoaXMub3B0aW9ucy50b2xlcmFuY2UmJiF0aGlzLl9pbnRlcnNlY3RzV2l0aFNpZGVzKHMpKWJyZWFrO3RoaXMuX3JlYXJyYW5nZShlLHMpLHRoaXMuX3RyaWdnZXIoXCJjaGFuZ2VcIixlLHRoaXMuX3VpSGFzaCgpKTticmVha31yZXR1cm4gdGhpcy5fY29udGFjdENvbnRhaW5lcnMoZSksdC51aS5kZG1hbmFnZXImJnQudWkuZGRtYW5hZ2VyLmRyYWcodGhpcyxlKSx0aGlzLl90cmlnZ2VyKFwic29ydFwiLGUsdGhpcy5fdWlIYXNoKCkpLHRoaXMubGFzdFBvc2l0aW9uQWJzPXRoaXMucG9zaXRpb25BYnMsITF9LF9tb3VzZVN0b3A6ZnVuY3Rpb24oZSxpKXtpZihlKXtpZih0LnVpLmRkbWFuYWdlciYmIXRoaXMub3B0aW9ucy5kcm9wQmVoYXZpb3VyJiZ0LnVpLmRkbWFuYWdlci5kcm9wKHRoaXMsZSksdGhpcy5vcHRpb25zLnJldmVydCl7dmFyIHM9dGhpcyxuPXRoaXMucGxhY2Vob2xkZXIub2Zmc2V0KCksbz10aGlzLm9wdGlvbnMuYXhpcyxhPXt9O28mJlwieFwiIT09b3x8KGEubGVmdD1uLmxlZnQtdGhpcy5vZmZzZXQucGFyZW50LmxlZnQtdGhpcy5tYXJnaW5zLmxlZnQrKHRoaXMub2Zmc2V0UGFyZW50WzBdPT09dGhpcy5kb2N1bWVudFswXS5ib2R5PzA6dGhpcy5vZmZzZXRQYXJlbnRbMF0uc2Nyb2xsTGVmdCkpLG8mJlwieVwiIT09b3x8KGEudG9wPW4udG9wLXRoaXMub2Zmc2V0LnBhcmVudC50b3AtdGhpcy5tYXJnaW5zLnRvcCsodGhpcy5vZmZzZXRQYXJlbnRbMF09PT10aGlzLmRvY3VtZW50WzBdLmJvZHk/MDp0aGlzLm9mZnNldFBhcmVudFswXS5zY3JvbGxUb3ApKSx0aGlzLnJldmVydGluZz0hMCx0KHRoaXMuaGVscGVyKS5hbmltYXRlKGEscGFyc2VJbnQodGhpcy5vcHRpb25zLnJldmVydCwxMCl8fDUwMCxmdW5jdGlvbigpe3MuX2NsZWFyKGUpfSl9ZWxzZSB0aGlzLl9jbGVhcihlLGkpO3JldHVybiExfX0sY2FuY2VsOmZ1bmN0aW9uKCl7aWYodGhpcy5kcmFnZ2luZyl7dGhpcy5fbW91c2VVcChuZXcgdC5FdmVudChcIm1vdXNldXBcIix7dGFyZ2V0Om51bGx9KSksXCJvcmlnaW5hbFwiPT09dGhpcy5vcHRpb25zLmhlbHBlcj8odGhpcy5jdXJyZW50SXRlbS5jc3ModGhpcy5fc3RvcmVkQ1NTKSx0aGlzLl9yZW1vdmVDbGFzcyh0aGlzLmN1cnJlbnRJdGVtLFwidWktc29ydGFibGUtaGVscGVyXCIpKTp0aGlzLmN1cnJlbnRJdGVtLnNob3coKTtmb3IodmFyIGU9dGhpcy5jb250YWluZXJzLmxlbmd0aC0xO2U+PTA7ZS0tKXRoaXMuY29udGFpbmVyc1tlXS5fdHJpZ2dlcihcImRlYWN0aXZhdGVcIixudWxsLHRoaXMuX3VpSGFzaCh0aGlzKSksdGhpcy5jb250YWluZXJzW2VdLmNvbnRhaW5lckNhY2hlLm92ZXImJih0aGlzLmNvbnRhaW5lcnNbZV0uX3RyaWdnZXIoXCJvdXRcIixudWxsLHRoaXMuX3VpSGFzaCh0aGlzKSksdGhpcy5jb250YWluZXJzW2VdLmNvbnRhaW5lckNhY2hlLm92ZXI9MCl9cmV0dXJuIHRoaXMucGxhY2Vob2xkZXImJih0aGlzLnBsYWNlaG9sZGVyWzBdLnBhcmVudE5vZGUmJnRoaXMucGxhY2Vob2xkZXJbMF0ucGFyZW50Tm9kZS5yZW1vdmVDaGlsZCh0aGlzLnBsYWNlaG9sZGVyWzBdKSxcIm9yaWdpbmFsXCIhPT10aGlzLm9wdGlvbnMuaGVscGVyJiZ0aGlzLmhlbHBlciYmdGhpcy5oZWxwZXJbMF0ucGFyZW50Tm9kZSYmdGhpcy5oZWxwZXIucmVtb3ZlKCksdC5leHRlbmQodGhpcyx7aGVscGVyOm51bGwsZHJhZ2dpbmc6ITEscmV2ZXJ0aW5nOiExLF9ub0ZpbmFsU29ydDpudWxsfSksdGhpcy5kb21Qb3NpdGlvbi5wcmV2P3QodGhpcy5kb21Qb3NpdGlvbi5wcmV2KS5hZnRlcih0aGlzLmN1cnJlbnRJdGVtKTp0KHRoaXMuZG9tUG9zaXRpb24ucGFyZW50KS5wcmVwZW5kKHRoaXMuY3VycmVudEl0ZW0pKSx0aGlzfSxzZXJpYWxpemU6ZnVuY3Rpb24oZSl7dmFyIGk9dGhpcy5fZ2V0SXRlbXNBc2pRdWVyeShlJiZlLmNvbm5lY3RlZCkscz1bXTtyZXR1cm4gZT1lfHx7fSx0KGkpLmVhY2goZnVuY3Rpb24oKXt2YXIgaT0odChlLml0ZW18fHRoaXMpLmF0dHIoZS5hdHRyaWJ1dGV8fFwiaWRcIil8fFwiXCIpLm1hdGNoKGUuZXhwcmVzc2lvbnx8LyguKylbXFwtPV9dKC4rKS8pO2kmJnMucHVzaCgoZS5rZXl8fGlbMV0rXCJbXVwiKStcIj1cIisoZS5rZXkmJmUuZXhwcmVzc2lvbj9pWzFdOmlbMl0pKX0pLCFzLmxlbmd0aCYmZS5rZXkmJnMucHVzaChlLmtleStcIj1cIikscy5qb2luKFwiJlwiKX0sdG9BcnJheTpmdW5jdGlvbihlKXt2YXIgaT10aGlzLl9nZXRJdGVtc0FzalF1ZXJ5KGUmJmUuY29ubmVjdGVkKSxzPVtdO3JldHVybiBlPWV8fHt9LGkuZWFjaChmdW5jdGlvbigpe3MucHVzaCh0KGUuaXRlbXx8dGhpcykuYXR0cihlLmF0dHJpYnV0ZXx8XCJpZFwiKXx8XCJcIil9KSxzfSxfaW50ZXJzZWN0c1dpdGg6ZnVuY3Rpb24odCl7dmFyIGU9dGhpcy5wb3NpdGlvbkFicy5sZWZ0LGk9ZSt0aGlzLmhlbHBlclByb3BvcnRpb25zLndpZHRoLHM9dGhpcy5wb3NpdGlvbkFicy50b3Asbj1zK3RoaXMuaGVscGVyUHJvcG9ydGlvbnMuaGVpZ2h0LG89dC5sZWZ0LGE9byt0LndpZHRoLHI9dC50b3AsaD1yK3QuaGVpZ2h0LGw9dGhpcy5vZmZzZXQuY2xpY2sudG9wLGM9dGhpcy5vZmZzZXQuY2xpY2subGVmdCx1PVwieFwiPT09dGhpcy5vcHRpb25zLmF4aXN8fHMrbD5yJiZoPnMrbCxkPVwieVwiPT09dGhpcy5vcHRpb25zLmF4aXN8fGUrYz5vJiZhPmUrYyxwPXUmJmQ7cmV0dXJuXCJwb2ludGVyXCI9PT10aGlzLm9wdGlvbnMudG9sZXJhbmNlfHx0aGlzLm9wdGlvbnMuZm9yY2VQb2ludGVyRm9yQ29udGFpbmVyc3x8XCJwb2ludGVyXCIhPT10aGlzLm9wdGlvbnMudG9sZXJhbmNlJiZ0aGlzLmhlbHBlclByb3BvcnRpb25zW3RoaXMuZmxvYXRpbmc/XCJ3aWR0aFwiOlwiaGVpZ2h0XCJdPnRbdGhpcy5mbG9hdGluZz9cIndpZHRoXCI6XCJoZWlnaHRcIl0/cDplK3RoaXMuaGVscGVyUHJvcG9ydGlvbnMud2lkdGgvMj5vJiZhPmktdGhpcy5oZWxwZXJQcm9wb3J0aW9ucy53aWR0aC8yJiZzK3RoaXMuaGVscGVyUHJvcG9ydGlvbnMuaGVpZ2h0LzI+ciYmaD5uLXRoaXMuaGVscGVyUHJvcG9ydGlvbnMuaGVpZ2h0LzJ9LF9pbnRlcnNlY3RzV2l0aFBvaW50ZXI6ZnVuY3Rpb24odCl7dmFyIGUsaSxzPVwieFwiPT09dGhpcy5vcHRpb25zLmF4aXN8fHRoaXMuX2lzT3ZlckF4aXModGhpcy5wb3NpdGlvbkFicy50b3ArdGhpcy5vZmZzZXQuY2xpY2sudG9wLHQudG9wLHQuaGVpZ2h0KSxuPVwieVwiPT09dGhpcy5vcHRpb25zLmF4aXN8fHRoaXMuX2lzT3ZlckF4aXModGhpcy5wb3NpdGlvbkFicy5sZWZ0K3RoaXMub2Zmc2V0LmNsaWNrLmxlZnQsdC5sZWZ0LHQud2lkdGgpLG89cyYmbjtyZXR1cm4gbz8oZT10aGlzLl9nZXREcmFnVmVydGljYWxEaXJlY3Rpb24oKSxpPXRoaXMuX2dldERyYWdIb3Jpem9udGFsRGlyZWN0aW9uKCksdGhpcy5mbG9hdGluZz9cInJpZ2h0XCI9PT1pfHxcImRvd25cIj09PWU/MjoxOmUmJihcImRvd25cIj09PWU/MjoxKSk6ITF9LF9pbnRlcnNlY3RzV2l0aFNpZGVzOmZ1bmN0aW9uKHQpe3ZhciBlPXRoaXMuX2lzT3ZlckF4aXModGhpcy5wb3NpdGlvbkFicy50b3ArdGhpcy5vZmZzZXQuY2xpY2sudG9wLHQudG9wK3QuaGVpZ2h0LzIsdC5oZWlnaHQpLGk9dGhpcy5faXNPdmVyQXhpcyh0aGlzLnBvc2l0aW9uQWJzLmxlZnQrdGhpcy5vZmZzZXQuY2xpY2subGVmdCx0LmxlZnQrdC53aWR0aC8yLHQud2lkdGgpLHM9dGhpcy5fZ2V0RHJhZ1ZlcnRpY2FsRGlyZWN0aW9uKCksbj10aGlzLl9nZXREcmFnSG9yaXpvbnRhbERpcmVjdGlvbigpO3JldHVybiB0aGlzLmZsb2F0aW5nJiZuP1wicmlnaHRcIj09PW4mJml8fFwibGVmdFwiPT09biYmIWk6cyYmKFwiZG93blwiPT09cyYmZXx8XCJ1cFwiPT09cyYmIWUpfSxfZ2V0RHJhZ1ZlcnRpY2FsRGlyZWN0aW9uOmZ1bmN0aW9uKCl7dmFyIHQ9dGhpcy5wb3NpdGlvbkFicy50b3AtdGhpcy5sYXN0UG9zaXRpb25BYnMudG9wO3JldHVybiAwIT09dCYmKHQ+MD9cImRvd25cIjpcInVwXCIpfSxfZ2V0RHJhZ0hvcml6b250YWxEaXJlY3Rpb246ZnVuY3Rpb24oKXt2YXIgdD10aGlzLnBvc2l0aW9uQWJzLmxlZnQtdGhpcy5sYXN0UG9zaXRpb25BYnMubGVmdDtyZXR1cm4gMCE9PXQmJih0PjA/XCJyaWdodFwiOlwibGVmdFwiKX0scmVmcmVzaDpmdW5jdGlvbih0KXtyZXR1cm4gdGhpcy5fcmVmcmVzaEl0ZW1zKHQpLHRoaXMuX3NldEhhbmRsZUNsYXNzTmFtZSgpLHRoaXMucmVmcmVzaFBvc2l0aW9ucygpLHRoaXN9LF9jb25uZWN0V2l0aDpmdW5jdGlvbigpe3ZhciB0PXRoaXMub3B0aW9ucztyZXR1cm4gdC5jb25uZWN0V2l0aC5jb25zdHJ1Y3Rvcj09PVN0cmluZz9bdC5jb25uZWN0V2l0aF06dC5jb25uZWN0V2l0aH0sX2dldEl0ZW1zQXNqUXVlcnk6ZnVuY3Rpb24oZSl7ZnVuY3Rpb24gaSgpe3IucHVzaCh0aGlzKX12YXIgcyxuLG8sYSxyPVtdLGg9W10sbD10aGlzLl9jb25uZWN0V2l0aCgpO2lmKGwmJmUpZm9yKHM9bC5sZW5ndGgtMTtzPj0wO3MtLSlmb3Iobz10KGxbc10sdGhpcy5kb2N1bWVudFswXSksbj1vLmxlbmd0aC0xO24+PTA7bi0tKWE9dC5kYXRhKG9bbl0sdGhpcy53aWRnZXRGdWxsTmFtZSksYSYmYSE9PXRoaXMmJiFhLm9wdGlvbnMuZGlzYWJsZWQmJmgucHVzaChbdC5pc0Z1bmN0aW9uKGEub3B0aW9ucy5pdGVtcyk/YS5vcHRpb25zLml0ZW1zLmNhbGwoYS5lbGVtZW50KTp0KGEub3B0aW9ucy5pdGVtcyxhLmVsZW1lbnQpLm5vdChcIi51aS1zb3J0YWJsZS1oZWxwZXJcIikubm90KFwiLnVpLXNvcnRhYmxlLXBsYWNlaG9sZGVyXCIpLGFdKTtmb3IoaC5wdXNoKFt0LmlzRnVuY3Rpb24odGhpcy5vcHRpb25zLml0ZW1zKT90aGlzLm9wdGlvbnMuaXRlbXMuY2FsbCh0aGlzLmVsZW1lbnQsbnVsbCx7b3B0aW9uczp0aGlzLm9wdGlvbnMsaXRlbTp0aGlzLmN1cnJlbnRJdGVtfSk6dCh0aGlzLm9wdGlvbnMuaXRlbXMsdGhpcy5lbGVtZW50KS5ub3QoXCIudWktc29ydGFibGUtaGVscGVyXCIpLm5vdChcIi51aS1zb3J0YWJsZS1wbGFjZWhvbGRlclwiKSx0aGlzXSkscz1oLmxlbmd0aC0xO3M+PTA7cy0tKWhbc11bMF0uZWFjaChpKTtyZXR1cm4gdChyKX0sX3JlbW92ZUN1cnJlbnRzRnJvbUl0ZW1zOmZ1bmN0aW9uKCl7dmFyIGU9dGhpcy5jdXJyZW50SXRlbS5maW5kKFwiOmRhdGEoXCIrdGhpcy53aWRnZXROYW1lK1wiLWl0ZW0pXCIpO3RoaXMuaXRlbXM9dC5ncmVwKHRoaXMuaXRlbXMsZnVuY3Rpb24odCl7Zm9yKHZhciBpPTA7ZS5sZW5ndGg+aTtpKyspaWYoZVtpXT09PXQuaXRlbVswXSlyZXR1cm4hMTtyZXR1cm4hMH0pfSxfcmVmcmVzaEl0ZW1zOmZ1bmN0aW9uKGUpe3RoaXMuaXRlbXM9W10sdGhpcy5jb250YWluZXJzPVt0aGlzXTt2YXIgaSxzLG4sbyxhLHIsaCxsLGM9dGhpcy5pdGVtcyx1PVtbdC5pc0Z1bmN0aW9uKHRoaXMub3B0aW9ucy5pdGVtcyk/dGhpcy5vcHRpb25zLml0ZW1zLmNhbGwodGhpcy5lbGVtZW50WzBdLGUse2l0ZW06dGhpcy5jdXJyZW50SXRlbX0pOnQodGhpcy5vcHRpb25zLml0ZW1zLHRoaXMuZWxlbWVudCksdGhpc11dLGQ9dGhpcy5fY29ubmVjdFdpdGgoKTtpZihkJiZ0aGlzLnJlYWR5KWZvcihpPWQubGVuZ3RoLTE7aT49MDtpLS0pZm9yKG49dChkW2ldLHRoaXMuZG9jdW1lbnRbMF0pLHM9bi5sZW5ndGgtMTtzPj0wO3MtLSlvPXQuZGF0YShuW3NdLHRoaXMud2lkZ2V0RnVsbE5hbWUpLG8mJm8hPT10aGlzJiYhby5vcHRpb25zLmRpc2FibGVkJiYodS5wdXNoKFt0LmlzRnVuY3Rpb24oby5vcHRpb25zLml0ZW1zKT9vLm9wdGlvbnMuaXRlbXMuY2FsbChvLmVsZW1lbnRbMF0sZSx7aXRlbTp0aGlzLmN1cnJlbnRJdGVtfSk6dChvLm9wdGlvbnMuaXRlbXMsby5lbGVtZW50KSxvXSksdGhpcy5jb250YWluZXJzLnB1c2gobykpO2ZvcihpPXUubGVuZ3RoLTE7aT49MDtpLS0pZm9yKGE9dVtpXVsxXSxyPXVbaV1bMF0scz0wLGw9ci5sZW5ndGg7bD5zO3MrKyloPXQocltzXSksaC5kYXRhKHRoaXMud2lkZ2V0TmFtZStcIi1pdGVtXCIsYSksYy5wdXNoKHtpdGVtOmgsaW5zdGFuY2U6YSx3aWR0aDowLGhlaWdodDowLGxlZnQ6MCx0b3A6MH0pfSxyZWZyZXNoUG9zaXRpb25zOmZ1bmN0aW9uKGUpe3RoaXMuZmxvYXRpbmc9dGhpcy5pdGVtcy5sZW5ndGg/XCJ4XCI9PT10aGlzLm9wdGlvbnMuYXhpc3x8dGhpcy5faXNGbG9hdGluZyh0aGlzLml0ZW1zWzBdLml0ZW0pOiExLHRoaXMub2Zmc2V0UGFyZW50JiZ0aGlzLmhlbHBlciYmKHRoaXMub2Zmc2V0LnBhcmVudD10aGlzLl9nZXRQYXJlbnRPZmZzZXQoKSk7dmFyIGkscyxuLG87Zm9yKGk9dGhpcy5pdGVtcy5sZW5ndGgtMTtpPj0wO2ktLSlzPXRoaXMuaXRlbXNbaV0scy5pbnN0YW5jZSE9PXRoaXMuY3VycmVudENvbnRhaW5lciYmdGhpcy5jdXJyZW50Q29udGFpbmVyJiZzLml0ZW1bMF0hPT10aGlzLmN1cnJlbnRJdGVtWzBdfHwobj10aGlzLm9wdGlvbnMudG9sZXJhbmNlRWxlbWVudD90KHRoaXMub3B0aW9ucy50b2xlcmFuY2VFbGVtZW50LHMuaXRlbSk6cy5pdGVtLGV8fChzLndpZHRoPW4ub3V0ZXJXaWR0aCgpLHMuaGVpZ2h0PW4ub3V0ZXJIZWlnaHQoKSksbz1uLm9mZnNldCgpLHMubGVmdD1vLmxlZnQscy50b3A9by50b3ApO2lmKHRoaXMub3B0aW9ucy5jdXN0b20mJnRoaXMub3B0aW9ucy5jdXN0b20ucmVmcmVzaENvbnRhaW5lcnMpdGhpcy5vcHRpb25zLmN1c3RvbS5yZWZyZXNoQ29udGFpbmVycy5jYWxsKHRoaXMpO2Vsc2UgZm9yKGk9dGhpcy5jb250YWluZXJzLmxlbmd0aC0xO2k+PTA7aS0tKW89dGhpcy5jb250YWluZXJzW2ldLmVsZW1lbnQub2Zmc2V0KCksdGhpcy5jb250YWluZXJzW2ldLmNvbnRhaW5lckNhY2hlLmxlZnQ9by5sZWZ0LHRoaXMuY29udGFpbmVyc1tpXS5jb250YWluZXJDYWNoZS50b3A9by50b3AsdGhpcy5jb250YWluZXJzW2ldLmNvbnRhaW5lckNhY2hlLndpZHRoPXRoaXMuY29udGFpbmVyc1tpXS5lbGVtZW50Lm91dGVyV2lkdGgoKSx0aGlzLmNvbnRhaW5lcnNbaV0uY29udGFpbmVyQ2FjaGUuaGVpZ2h0PXRoaXMuY29udGFpbmVyc1tpXS5lbGVtZW50Lm91dGVySGVpZ2h0KCk7cmV0dXJuIHRoaXN9LF9jcmVhdGVQbGFjZWhvbGRlcjpmdW5jdGlvbihlKXtlPWV8fHRoaXM7dmFyIGkscz1lLm9wdGlvbnM7cy5wbGFjZWhvbGRlciYmcy5wbGFjZWhvbGRlci5jb25zdHJ1Y3RvciE9PVN0cmluZ3x8KGk9cy5wbGFjZWhvbGRlcixzLnBsYWNlaG9sZGVyPXtlbGVtZW50OmZ1bmN0aW9uKCl7dmFyIHM9ZS5jdXJyZW50SXRlbVswXS5ub2RlTmFtZS50b0xvd2VyQ2FzZSgpLG49dChcIjxcIitzK1wiPlwiLGUuZG9jdW1lbnRbMF0pO3JldHVybiBlLl9hZGRDbGFzcyhuLFwidWktc29ydGFibGUtcGxhY2Vob2xkZXJcIixpfHxlLmN1cnJlbnRJdGVtWzBdLmNsYXNzTmFtZSkuX3JlbW92ZUNsYXNzKG4sXCJ1aS1zb3J0YWJsZS1oZWxwZXJcIiksXCJ0Ym9keVwiPT09cz9lLl9jcmVhdGVUclBsYWNlaG9sZGVyKGUuY3VycmVudEl0ZW0uZmluZChcInRyXCIpLmVxKDApLHQoXCI8dHI+XCIsZS5kb2N1bWVudFswXSkuYXBwZW5kVG8obikpOlwidHJcIj09PXM/ZS5fY3JlYXRlVHJQbGFjZWhvbGRlcihlLmN1cnJlbnRJdGVtLG4pOlwiaW1nXCI9PT1zJiZuLmF0dHIoXCJzcmNcIixlLmN1cnJlbnRJdGVtLmF0dHIoXCJzcmNcIikpLGl8fG4uY3NzKFwidmlzaWJpbGl0eVwiLFwiaGlkZGVuXCIpLG59LHVwZGF0ZTpmdW5jdGlvbih0LG4peyghaXx8cy5mb3JjZVBsYWNlaG9sZGVyU2l6ZSkmJihuLmhlaWdodCgpfHxuLmhlaWdodChlLmN1cnJlbnRJdGVtLmlubmVySGVpZ2h0KCktcGFyc2VJbnQoZS5jdXJyZW50SXRlbS5jc3MoXCJwYWRkaW5nVG9wXCIpfHwwLDEwKS1wYXJzZUludChlLmN1cnJlbnRJdGVtLmNzcyhcInBhZGRpbmdCb3R0b21cIil8fDAsMTApKSxuLndpZHRoKCl8fG4ud2lkdGgoZS5jdXJyZW50SXRlbS5pbm5lcldpZHRoKCktcGFyc2VJbnQoZS5jdXJyZW50SXRlbS5jc3MoXCJwYWRkaW5nTGVmdFwiKXx8MCwxMCktcGFyc2VJbnQoZS5jdXJyZW50SXRlbS5jc3MoXCJwYWRkaW5nUmlnaHRcIil8fDAsMTApKSl9fSksZS5wbGFjZWhvbGRlcj10KHMucGxhY2Vob2xkZXIuZWxlbWVudC5jYWxsKGUuZWxlbWVudCxlLmN1cnJlbnRJdGVtKSksZS5jdXJyZW50SXRlbS5hZnRlcihlLnBsYWNlaG9sZGVyKSxzLnBsYWNlaG9sZGVyLnVwZGF0ZShlLGUucGxhY2Vob2xkZXIpfSxfY3JlYXRlVHJQbGFjZWhvbGRlcjpmdW5jdGlvbihlLGkpe3ZhciBzPXRoaXM7ZS5jaGlsZHJlbigpLmVhY2goZnVuY3Rpb24oKXt0KFwiPHRkPiYjMTYwOzwvdGQ+XCIscy5kb2N1bWVudFswXSkuYXR0cihcImNvbHNwYW5cIix0KHRoaXMpLmF0dHIoXCJjb2xzcGFuXCIpfHwxKS5hcHBlbmRUbyhpKX0pfSxfY29udGFjdENvbnRhaW5lcnM6ZnVuY3Rpb24oZSl7dmFyIGkscyxuLG8sYSxyLGgsbCxjLHUsZD1udWxsLHA9bnVsbDtmb3IoaT10aGlzLmNvbnRhaW5lcnMubGVuZ3RoLTE7aT49MDtpLS0paWYoIXQuY29udGFpbnModGhpcy5jdXJyZW50SXRlbVswXSx0aGlzLmNvbnRhaW5lcnNbaV0uZWxlbWVudFswXSkpaWYodGhpcy5faW50ZXJzZWN0c1dpdGgodGhpcy5jb250YWluZXJzW2ldLmNvbnRhaW5lckNhY2hlKSl7aWYoZCYmdC5jb250YWlucyh0aGlzLmNvbnRhaW5lcnNbaV0uZWxlbWVudFswXSxkLmVsZW1lbnRbMF0pKWNvbnRpbnVlO2Q9dGhpcy5jb250YWluZXJzW2ldLHA9aX1lbHNlIHRoaXMuY29udGFpbmVyc1tpXS5jb250YWluZXJDYWNoZS5vdmVyJiYodGhpcy5jb250YWluZXJzW2ldLl90cmlnZ2VyKFwib3V0XCIsZSx0aGlzLl91aUhhc2godGhpcykpLHRoaXMuY29udGFpbmVyc1tpXS5jb250YWluZXJDYWNoZS5vdmVyPTApO2lmKGQpaWYoMT09PXRoaXMuY29udGFpbmVycy5sZW5ndGgpdGhpcy5jb250YWluZXJzW3BdLmNvbnRhaW5lckNhY2hlLm92ZXJ8fCh0aGlzLmNvbnRhaW5lcnNbcF0uX3RyaWdnZXIoXCJvdmVyXCIsZSx0aGlzLl91aUhhc2godGhpcykpLHRoaXMuY29udGFpbmVyc1twXS5jb250YWluZXJDYWNoZS5vdmVyPTEpO2Vsc2V7Zm9yKG49MWU0LG89bnVsbCxjPWQuZmxvYXRpbmd8fHRoaXMuX2lzRmxvYXRpbmcodGhpcy5jdXJyZW50SXRlbSksYT1jP1wibGVmdFwiOlwidG9wXCIscj1jP1wid2lkdGhcIjpcImhlaWdodFwiLHU9Yz9cInBhZ2VYXCI6XCJwYWdlWVwiLHM9dGhpcy5pdGVtcy5sZW5ndGgtMTtzPj0wO3MtLSl0LmNvbnRhaW5zKHRoaXMuY29udGFpbmVyc1twXS5lbGVtZW50WzBdLHRoaXMuaXRlbXNbc10uaXRlbVswXSkmJnRoaXMuaXRlbXNbc10uaXRlbVswXSE9PXRoaXMuY3VycmVudEl0ZW1bMF0mJihoPXRoaXMuaXRlbXNbc10uaXRlbS5vZmZzZXQoKVthXSxsPSExLGVbdV0taD50aGlzLml0ZW1zW3NdW3JdLzImJihsPSEwKSxuPk1hdGguYWJzKGVbdV0taCkmJihuPU1hdGguYWJzKGVbdV0taCksbz10aGlzLml0ZW1zW3NdLHRoaXMuZGlyZWN0aW9uPWw/XCJ1cFwiOlwiZG93blwiKSk7aWYoIW8mJiF0aGlzLm9wdGlvbnMuZHJvcE9uRW1wdHkpcmV0dXJuO2lmKHRoaXMuY3VycmVudENvbnRhaW5lcj09PXRoaXMuY29udGFpbmVyc1twXSlyZXR1cm4gdGhpcy5jdXJyZW50Q29udGFpbmVyLmNvbnRhaW5lckNhY2hlLm92ZXJ8fCh0aGlzLmNvbnRhaW5lcnNbcF0uX3RyaWdnZXIoXCJvdmVyXCIsZSx0aGlzLl91aUhhc2goKSksdGhpcy5jdXJyZW50Q29udGFpbmVyLmNvbnRhaW5lckNhY2hlLm92ZXI9MSksdm9pZCAwO28/dGhpcy5fcmVhcnJhbmdlKGUsbyxudWxsLCEwKTp0aGlzLl9yZWFycmFuZ2UoZSxudWxsLHRoaXMuY29udGFpbmVyc1twXS5lbGVtZW50LCEwKSx0aGlzLl90cmlnZ2VyKFwiY2hhbmdlXCIsZSx0aGlzLl91aUhhc2goKSksdGhpcy5jb250YWluZXJzW3BdLl90cmlnZ2VyKFwiY2hhbmdlXCIsZSx0aGlzLl91aUhhc2godGhpcykpLHRoaXMuY3VycmVudENvbnRhaW5lcj10aGlzLmNvbnRhaW5lcnNbcF0sdGhpcy5vcHRpb25zLnBsYWNlaG9sZGVyLnVwZGF0ZSh0aGlzLmN1cnJlbnRDb250YWluZXIsdGhpcy5wbGFjZWhvbGRlciksdGhpcy5jb250YWluZXJzW3BdLl90cmlnZ2VyKFwib3ZlclwiLGUsdGhpcy5fdWlIYXNoKHRoaXMpKSx0aGlzLmNvbnRhaW5lcnNbcF0uY29udGFpbmVyQ2FjaGUub3Zlcj0xfX0sX2NyZWF0ZUhlbHBlcjpmdW5jdGlvbihlKXt2YXIgaT10aGlzLm9wdGlvbnMscz10LmlzRnVuY3Rpb24oaS5oZWxwZXIpP3QoaS5oZWxwZXIuYXBwbHkodGhpcy5lbGVtZW50WzBdLFtlLHRoaXMuY3VycmVudEl0ZW1dKSk6XCJjbG9uZVwiPT09aS5oZWxwZXI/dGhpcy5jdXJyZW50SXRlbS5jbG9uZSgpOnRoaXMuY3VycmVudEl0ZW07cmV0dXJuIHMucGFyZW50cyhcImJvZHlcIikubGVuZ3RofHx0KFwicGFyZW50XCIhPT1pLmFwcGVuZFRvP2kuYXBwZW5kVG86dGhpcy5jdXJyZW50SXRlbVswXS5wYXJlbnROb2RlKVswXS5hcHBlbmRDaGlsZChzWzBdKSxzWzBdPT09dGhpcy5jdXJyZW50SXRlbVswXSYmKHRoaXMuX3N0b3JlZENTUz17d2lkdGg6dGhpcy5jdXJyZW50SXRlbVswXS5zdHlsZS53aWR0aCxoZWlnaHQ6dGhpcy5jdXJyZW50SXRlbVswXS5zdHlsZS5oZWlnaHQscG9zaXRpb246dGhpcy5jdXJyZW50SXRlbS5jc3MoXCJwb3NpdGlvblwiKSx0b3A6dGhpcy5jdXJyZW50SXRlbS5jc3MoXCJ0b3BcIiksbGVmdDp0aGlzLmN1cnJlbnRJdGVtLmNzcyhcImxlZnRcIil9KSwoIXNbMF0uc3R5bGUud2lkdGh8fGkuZm9yY2VIZWxwZXJTaXplKSYmcy53aWR0aCh0aGlzLmN1cnJlbnRJdGVtLndpZHRoKCkpLCghc1swXS5zdHlsZS5oZWlnaHR8fGkuZm9yY2VIZWxwZXJTaXplKSYmcy5oZWlnaHQodGhpcy5jdXJyZW50SXRlbS5oZWlnaHQoKSksc30sX2FkanVzdE9mZnNldEZyb21IZWxwZXI6ZnVuY3Rpb24oZSl7XCJzdHJpbmdcIj09dHlwZW9mIGUmJihlPWUuc3BsaXQoXCIgXCIpKSx0LmlzQXJyYXkoZSkmJihlPXtsZWZ0OitlWzBdLHRvcDorZVsxXXx8MH0pLFwibGVmdFwiaW4gZSYmKHRoaXMub2Zmc2V0LmNsaWNrLmxlZnQ9ZS5sZWZ0K3RoaXMubWFyZ2lucy5sZWZ0KSxcInJpZ2h0XCJpbiBlJiYodGhpcy5vZmZzZXQuY2xpY2subGVmdD10aGlzLmhlbHBlclByb3BvcnRpb25zLndpZHRoLWUucmlnaHQrdGhpcy5tYXJnaW5zLmxlZnQpLFwidG9wXCJpbiBlJiYodGhpcy5vZmZzZXQuY2xpY2sudG9wPWUudG9wK3RoaXMubWFyZ2lucy50b3ApLFwiYm90dG9tXCJpbiBlJiYodGhpcy5vZmZzZXQuY2xpY2sudG9wPXRoaXMuaGVscGVyUHJvcG9ydGlvbnMuaGVpZ2h0LWUuYm90dG9tK3RoaXMubWFyZ2lucy50b3ApfSxfZ2V0UGFyZW50T2Zmc2V0OmZ1bmN0aW9uKCl7dGhpcy5vZmZzZXRQYXJlbnQ9dGhpcy5oZWxwZXIub2Zmc2V0UGFyZW50KCk7dmFyIGU9dGhpcy5vZmZzZXRQYXJlbnQub2Zmc2V0KCk7cmV0dXJuXCJhYnNvbHV0ZVwiPT09dGhpcy5jc3NQb3NpdGlvbiYmdGhpcy5zY3JvbGxQYXJlbnRbMF0hPT10aGlzLmRvY3VtZW50WzBdJiZ0LmNvbnRhaW5zKHRoaXMuc2Nyb2xsUGFyZW50WzBdLHRoaXMub2Zmc2V0UGFyZW50WzBdKSYmKGUubGVmdCs9dGhpcy5zY3JvbGxQYXJlbnQuc2Nyb2xsTGVmdCgpLGUudG9wKz10aGlzLnNjcm9sbFBhcmVudC5zY3JvbGxUb3AoKSksKHRoaXMub2Zmc2V0UGFyZW50WzBdPT09dGhpcy5kb2N1bWVudFswXS5ib2R5fHx0aGlzLm9mZnNldFBhcmVudFswXS50YWdOYW1lJiZcImh0bWxcIj09PXRoaXMub2Zmc2V0UGFyZW50WzBdLnRhZ05hbWUudG9Mb3dlckNhc2UoKSYmdC51aS5pZSkmJihlPXt0b3A6MCxsZWZ0OjB9KSx7dG9wOmUudG9wKyhwYXJzZUludCh0aGlzLm9mZnNldFBhcmVudC5jc3MoXCJib3JkZXJUb3BXaWR0aFwiKSwxMCl8fDApLGxlZnQ6ZS5sZWZ0KyhwYXJzZUludCh0aGlzLm9mZnNldFBhcmVudC5jc3MoXCJib3JkZXJMZWZ0V2lkdGhcIiksMTApfHwwKX19LF9nZXRSZWxhdGl2ZU9mZnNldDpmdW5jdGlvbigpe2lmKFwicmVsYXRpdmVcIj09PXRoaXMuY3NzUG9zaXRpb24pe3ZhciB0PXRoaXMuY3VycmVudEl0ZW0ucG9zaXRpb24oKTtyZXR1cm57dG9wOnQudG9wLShwYXJzZUludCh0aGlzLmhlbHBlci5jc3MoXCJ0b3BcIiksMTApfHwwKSt0aGlzLnNjcm9sbFBhcmVudC5zY3JvbGxUb3AoKSxsZWZ0OnQubGVmdC0ocGFyc2VJbnQodGhpcy5oZWxwZXIuY3NzKFwibGVmdFwiKSwxMCl8fDApK3RoaXMuc2Nyb2xsUGFyZW50LnNjcm9sbExlZnQoKX19cmV0dXJue3RvcDowLGxlZnQ6MH19LF9jYWNoZU1hcmdpbnM6ZnVuY3Rpb24oKXt0aGlzLm1hcmdpbnM9e2xlZnQ6cGFyc2VJbnQodGhpcy5jdXJyZW50SXRlbS5jc3MoXCJtYXJnaW5MZWZ0XCIpLDEwKXx8MCx0b3A6cGFyc2VJbnQodGhpcy5jdXJyZW50SXRlbS5jc3MoXCJtYXJnaW5Ub3BcIiksMTApfHwwfX0sX2NhY2hlSGVscGVyUHJvcG9ydGlvbnM6ZnVuY3Rpb24oKXt0aGlzLmhlbHBlclByb3BvcnRpb25zPXt3aWR0aDp0aGlzLmhlbHBlci5vdXRlcldpZHRoKCksaGVpZ2h0OnRoaXMuaGVscGVyLm91dGVySGVpZ2h0KCl9fSxfc2V0Q29udGFpbm1lbnQ6ZnVuY3Rpb24oKXt2YXIgZSxpLHMsbj10aGlzLm9wdGlvbnM7XCJwYXJlbnRcIj09PW4uY29udGFpbm1lbnQmJihuLmNvbnRhaW5tZW50PXRoaXMuaGVscGVyWzBdLnBhcmVudE5vZGUpLChcImRvY3VtZW50XCI9PT1uLmNvbnRhaW5tZW50fHxcIndpbmRvd1wiPT09bi5jb250YWlubWVudCkmJih0aGlzLmNvbnRhaW5tZW50PVswLXRoaXMub2Zmc2V0LnJlbGF0aXZlLmxlZnQtdGhpcy5vZmZzZXQucGFyZW50LmxlZnQsMC10aGlzLm9mZnNldC5yZWxhdGl2ZS50b3AtdGhpcy5vZmZzZXQucGFyZW50LnRvcCxcImRvY3VtZW50XCI9PT1uLmNvbnRhaW5tZW50P3RoaXMuZG9jdW1lbnQud2lkdGgoKTp0aGlzLndpbmRvdy53aWR0aCgpLXRoaXMuaGVscGVyUHJvcG9ydGlvbnMud2lkdGgtdGhpcy5tYXJnaW5zLmxlZnQsKFwiZG9jdW1lbnRcIj09PW4uY29udGFpbm1lbnQ/dGhpcy5kb2N1bWVudC5oZWlnaHQoKXx8ZG9jdW1lbnQuYm9keS5wYXJlbnROb2RlLnNjcm9sbEhlaWdodDp0aGlzLndpbmRvdy5oZWlnaHQoKXx8dGhpcy5kb2N1bWVudFswXS5ib2R5LnBhcmVudE5vZGUuc2Nyb2xsSGVpZ2h0KS10aGlzLmhlbHBlclByb3BvcnRpb25zLmhlaWdodC10aGlzLm1hcmdpbnMudG9wXSksL14oZG9jdW1lbnR8d2luZG93fHBhcmVudCkkLy50ZXN0KG4uY29udGFpbm1lbnQpfHwoZT10KG4uY29udGFpbm1lbnQpWzBdLGk9dChuLmNvbnRhaW5tZW50KS5vZmZzZXQoKSxzPVwiaGlkZGVuXCIhPT10KGUpLmNzcyhcIm92ZXJmbG93XCIpLHRoaXMuY29udGFpbm1lbnQ9W2kubGVmdCsocGFyc2VJbnQodChlKS5jc3MoXCJib3JkZXJMZWZ0V2lkdGhcIiksMTApfHwwKSsocGFyc2VJbnQodChlKS5jc3MoXCJwYWRkaW5nTGVmdFwiKSwxMCl8fDApLXRoaXMubWFyZ2lucy5sZWZ0LGkudG9wKyhwYXJzZUludCh0KGUpLmNzcyhcImJvcmRlclRvcFdpZHRoXCIpLDEwKXx8MCkrKHBhcnNlSW50KHQoZSkuY3NzKFwicGFkZGluZ1RvcFwiKSwxMCl8fDApLXRoaXMubWFyZ2lucy50b3AsaS5sZWZ0KyhzP01hdGgubWF4KGUuc2Nyb2xsV2lkdGgsZS5vZmZzZXRXaWR0aCk6ZS5vZmZzZXRXaWR0aCktKHBhcnNlSW50KHQoZSkuY3NzKFwiYm9yZGVyTGVmdFdpZHRoXCIpLDEwKXx8MCktKHBhcnNlSW50KHQoZSkuY3NzKFwicGFkZGluZ1JpZ2h0XCIpLDEwKXx8MCktdGhpcy5oZWxwZXJQcm9wb3J0aW9ucy53aWR0aC10aGlzLm1hcmdpbnMubGVmdCxpLnRvcCsocz9NYXRoLm1heChlLnNjcm9sbEhlaWdodCxlLm9mZnNldEhlaWdodCk6ZS5vZmZzZXRIZWlnaHQpLShwYXJzZUludCh0KGUpLmNzcyhcImJvcmRlclRvcFdpZHRoXCIpLDEwKXx8MCktKHBhcnNlSW50KHQoZSkuY3NzKFwicGFkZGluZ0JvdHRvbVwiKSwxMCl8fDApLXRoaXMuaGVscGVyUHJvcG9ydGlvbnMuaGVpZ2h0LXRoaXMubWFyZ2lucy50b3BdKX0sX2NvbnZlcnRQb3NpdGlvblRvOmZ1bmN0aW9uKGUsaSl7aXx8KGk9dGhpcy5wb3NpdGlvbik7dmFyIHM9XCJhYnNvbHV0ZVwiPT09ZT8xOi0xLG49XCJhYnNvbHV0ZVwiIT09dGhpcy5jc3NQb3NpdGlvbnx8dGhpcy5zY3JvbGxQYXJlbnRbMF0hPT10aGlzLmRvY3VtZW50WzBdJiZ0LmNvbnRhaW5zKHRoaXMuc2Nyb2xsUGFyZW50WzBdLHRoaXMub2Zmc2V0UGFyZW50WzBdKT90aGlzLnNjcm9sbFBhcmVudDp0aGlzLm9mZnNldFBhcmVudCxvPS8oaHRtbHxib2R5KS9pLnRlc3QoblswXS50YWdOYW1lKTtyZXR1cm57dG9wOmkudG9wK3RoaXMub2Zmc2V0LnJlbGF0aXZlLnRvcCpzK3RoaXMub2Zmc2V0LnBhcmVudC50b3Aqcy0oXCJmaXhlZFwiPT09dGhpcy5jc3NQb3NpdGlvbj8tdGhpcy5zY3JvbGxQYXJlbnQuc2Nyb2xsVG9wKCk6bz8wOm4uc2Nyb2xsVG9wKCkpKnMsbGVmdDppLmxlZnQrdGhpcy5vZmZzZXQucmVsYXRpdmUubGVmdCpzK3RoaXMub2Zmc2V0LnBhcmVudC5sZWZ0KnMtKFwiZml4ZWRcIj09PXRoaXMuY3NzUG9zaXRpb24/LXRoaXMuc2Nyb2xsUGFyZW50LnNjcm9sbExlZnQoKTpvPzA6bi5zY3JvbGxMZWZ0KCkpKnN9fSxfZ2VuZXJhdGVQb3NpdGlvbjpmdW5jdGlvbihlKXt2YXIgaSxzLG49dGhpcy5vcHRpb25zLG89ZS5wYWdlWCxhPWUucGFnZVkscj1cImFic29sdXRlXCIhPT10aGlzLmNzc1Bvc2l0aW9ufHx0aGlzLnNjcm9sbFBhcmVudFswXSE9PXRoaXMuZG9jdW1lbnRbMF0mJnQuY29udGFpbnModGhpcy5zY3JvbGxQYXJlbnRbMF0sdGhpcy5vZmZzZXRQYXJlbnRbMF0pP3RoaXMuc2Nyb2xsUGFyZW50OnRoaXMub2Zmc2V0UGFyZW50LGg9LyhodG1sfGJvZHkpL2kudGVzdChyWzBdLnRhZ05hbWUpO3JldHVyblwicmVsYXRpdmVcIiE9PXRoaXMuY3NzUG9zaXRpb258fHRoaXMuc2Nyb2xsUGFyZW50WzBdIT09dGhpcy5kb2N1bWVudFswXSYmdGhpcy5zY3JvbGxQYXJlbnRbMF0hPT10aGlzLm9mZnNldFBhcmVudFswXXx8KHRoaXMub2Zmc2V0LnJlbGF0aXZlPXRoaXMuX2dldFJlbGF0aXZlT2Zmc2V0KCkpLHRoaXMub3JpZ2luYWxQb3NpdGlvbiYmKHRoaXMuY29udGFpbm1lbnQmJihlLnBhZ2VYLXRoaXMub2Zmc2V0LmNsaWNrLmxlZnQ8dGhpcy5jb250YWlubWVudFswXSYmKG89dGhpcy5jb250YWlubWVudFswXSt0aGlzLm9mZnNldC5jbGljay5sZWZ0KSxlLnBhZ2VZLXRoaXMub2Zmc2V0LmNsaWNrLnRvcDx0aGlzLmNvbnRhaW5tZW50WzFdJiYoYT10aGlzLmNvbnRhaW5tZW50WzFdK3RoaXMub2Zmc2V0LmNsaWNrLnRvcCksZS5wYWdlWC10aGlzLm9mZnNldC5jbGljay5sZWZ0PnRoaXMuY29udGFpbm1lbnRbMl0mJihvPXRoaXMuY29udGFpbm1lbnRbMl0rdGhpcy5vZmZzZXQuY2xpY2subGVmdCksZS5wYWdlWS10aGlzLm9mZnNldC5jbGljay50b3A+dGhpcy5jb250YWlubWVudFszXSYmKGE9dGhpcy5jb250YWlubWVudFszXSt0aGlzLm9mZnNldC5jbGljay50b3ApKSxuLmdyaWQmJihpPXRoaXMub3JpZ2luYWxQYWdlWStNYXRoLnJvdW5kKChhLXRoaXMub3JpZ2luYWxQYWdlWSkvbi5ncmlkWzFdKSpuLmdyaWRbMV0sYT10aGlzLmNvbnRhaW5tZW50P2ktdGhpcy5vZmZzZXQuY2xpY2sudG9wPj10aGlzLmNvbnRhaW5tZW50WzFdJiZpLXRoaXMub2Zmc2V0LmNsaWNrLnRvcDw9dGhpcy5jb250YWlubWVudFszXT9pOmktdGhpcy5vZmZzZXQuY2xpY2sudG9wPj10aGlzLmNvbnRhaW5tZW50WzFdP2ktbi5ncmlkWzFdOmkrbi5ncmlkWzFdOmkscz10aGlzLm9yaWdpbmFsUGFnZVgrTWF0aC5yb3VuZCgoby10aGlzLm9yaWdpbmFsUGFnZVgpL24uZ3JpZFswXSkqbi5ncmlkWzBdLG89dGhpcy5jb250YWlubWVudD9zLXRoaXMub2Zmc2V0LmNsaWNrLmxlZnQ+PXRoaXMuY29udGFpbm1lbnRbMF0mJnMtdGhpcy5vZmZzZXQuY2xpY2subGVmdDw9dGhpcy5jb250YWlubWVudFsyXT9zOnMtdGhpcy5vZmZzZXQuY2xpY2subGVmdD49dGhpcy5jb250YWlubWVudFswXT9zLW4uZ3JpZFswXTpzK24uZ3JpZFswXTpzKSkse3RvcDphLXRoaXMub2Zmc2V0LmNsaWNrLnRvcC10aGlzLm9mZnNldC5yZWxhdGl2ZS50b3AtdGhpcy5vZmZzZXQucGFyZW50LnRvcCsoXCJmaXhlZFwiPT09dGhpcy5jc3NQb3NpdGlvbj8tdGhpcy5zY3JvbGxQYXJlbnQuc2Nyb2xsVG9wKCk6aD8wOnIuc2Nyb2xsVG9wKCkpLGxlZnQ6by10aGlzLm9mZnNldC5jbGljay5sZWZ0LXRoaXMub2Zmc2V0LnJlbGF0aXZlLmxlZnQtdGhpcy5vZmZzZXQucGFyZW50LmxlZnQrKFwiZml4ZWRcIj09PXRoaXMuY3NzUG9zaXRpb24/LXRoaXMuc2Nyb2xsUGFyZW50LnNjcm9sbExlZnQoKTpoPzA6ci5zY3JvbGxMZWZ0KCkpfX0sX3JlYXJyYW5nZTpmdW5jdGlvbih0LGUsaSxzKXtpP2lbMF0uYXBwZW5kQ2hpbGQodGhpcy5wbGFjZWhvbGRlclswXSk6ZS5pdGVtWzBdLnBhcmVudE5vZGUuaW5zZXJ0QmVmb3JlKHRoaXMucGxhY2Vob2xkZXJbMF0sXCJkb3duXCI9PT10aGlzLmRpcmVjdGlvbj9lLml0ZW1bMF06ZS5pdGVtWzBdLm5leHRTaWJsaW5nKSx0aGlzLmNvdW50ZXI9dGhpcy5jb3VudGVyPysrdGhpcy5jb3VudGVyOjE7dmFyIG49dGhpcy5jb3VudGVyO3RoaXMuX2RlbGF5KGZ1bmN0aW9uKCl7bj09PXRoaXMuY291bnRlciYmdGhpcy5yZWZyZXNoUG9zaXRpb25zKCFzKX0pfSxfY2xlYXI6ZnVuY3Rpb24odCxlKXtmdW5jdGlvbiBpKHQsZSxpKXtyZXR1cm4gZnVuY3Rpb24ocyl7aS5fdHJpZ2dlcih0LHMsZS5fdWlIYXNoKGUpKX19dGhpcy5yZXZlcnRpbmc9ITE7dmFyIHMsbj1bXTtpZighdGhpcy5fbm9GaW5hbFNvcnQmJnRoaXMuY3VycmVudEl0ZW0ucGFyZW50KCkubGVuZ3RoJiZ0aGlzLnBsYWNlaG9sZGVyLmJlZm9yZSh0aGlzLmN1cnJlbnRJdGVtKSx0aGlzLl9ub0ZpbmFsU29ydD1udWxsLHRoaXMuaGVscGVyWzBdPT09dGhpcy5jdXJyZW50SXRlbVswXSl7Zm9yKHMgaW4gdGhpcy5fc3RvcmVkQ1NTKShcImF1dG9cIj09PXRoaXMuX3N0b3JlZENTU1tzXXx8XCJzdGF0aWNcIj09PXRoaXMuX3N0b3JlZENTU1tzXSkmJih0aGlzLl9zdG9yZWRDU1Nbc109XCJcIik7dGhpcy5jdXJyZW50SXRlbS5jc3ModGhpcy5fc3RvcmVkQ1NTKSx0aGlzLl9yZW1vdmVDbGFzcyh0aGlzLmN1cnJlbnRJdGVtLFwidWktc29ydGFibGUtaGVscGVyXCIpfWVsc2UgdGhpcy5jdXJyZW50SXRlbS5zaG93KCk7Zm9yKHRoaXMuZnJvbU91dHNpZGUmJiFlJiZuLnB1c2goZnVuY3Rpb24odCl7dGhpcy5fdHJpZ2dlcihcInJlY2VpdmVcIix0LHRoaXMuX3VpSGFzaCh0aGlzLmZyb21PdXRzaWRlKSl9KSwhdGhpcy5mcm9tT3V0c2lkZSYmdGhpcy5kb21Qb3NpdGlvbi5wcmV2PT09dGhpcy5jdXJyZW50SXRlbS5wcmV2KCkubm90KFwiLnVpLXNvcnRhYmxlLWhlbHBlclwiKVswXSYmdGhpcy5kb21Qb3NpdGlvbi5wYXJlbnQ9PT10aGlzLmN1cnJlbnRJdGVtLnBhcmVudCgpWzBdfHxlfHxuLnB1c2goZnVuY3Rpb24odCl7dGhpcy5fdHJpZ2dlcihcInVwZGF0ZVwiLHQsdGhpcy5fdWlIYXNoKCkpfSksdGhpcyE9PXRoaXMuY3VycmVudENvbnRhaW5lciYmKGV8fChuLnB1c2goZnVuY3Rpb24odCl7dGhpcy5fdHJpZ2dlcihcInJlbW92ZVwiLHQsdGhpcy5fdWlIYXNoKCkpfSksbi5wdXNoKGZ1bmN0aW9uKHQpe3JldHVybiBmdW5jdGlvbihlKXt0Ll90cmlnZ2VyKFwicmVjZWl2ZVwiLGUsdGhpcy5fdWlIYXNoKHRoaXMpKX19LmNhbGwodGhpcyx0aGlzLmN1cnJlbnRDb250YWluZXIpKSxuLnB1c2goZnVuY3Rpb24odCl7cmV0dXJuIGZ1bmN0aW9uKGUpe3QuX3RyaWdnZXIoXCJ1cGRhdGVcIixlLHRoaXMuX3VpSGFzaCh0aGlzKSl9fS5jYWxsKHRoaXMsdGhpcy5jdXJyZW50Q29udGFpbmVyKSkpKSxzPXRoaXMuY29udGFpbmVycy5sZW5ndGgtMTtzPj0wO3MtLSllfHxuLnB1c2goaShcImRlYWN0aXZhdGVcIix0aGlzLHRoaXMuY29udGFpbmVyc1tzXSkpLHRoaXMuY29udGFpbmVyc1tzXS5jb250YWluZXJDYWNoZS5vdmVyJiYobi5wdXNoKGkoXCJvdXRcIix0aGlzLHRoaXMuY29udGFpbmVyc1tzXSkpLHRoaXMuY29udGFpbmVyc1tzXS5jb250YWluZXJDYWNoZS5vdmVyPTApO2lmKHRoaXMuc3RvcmVkQ3Vyc29yJiYodGhpcy5kb2N1bWVudC5maW5kKFwiYm9keVwiKS5jc3MoXCJjdXJzb3JcIix0aGlzLnN0b3JlZEN1cnNvciksdGhpcy5zdG9yZWRTdHlsZXNoZWV0LnJlbW92ZSgpKSx0aGlzLl9zdG9yZWRPcGFjaXR5JiZ0aGlzLmhlbHBlci5jc3MoXCJvcGFjaXR5XCIsdGhpcy5fc3RvcmVkT3BhY2l0eSksdGhpcy5fc3RvcmVkWkluZGV4JiZ0aGlzLmhlbHBlci5jc3MoXCJ6SW5kZXhcIixcImF1dG9cIj09PXRoaXMuX3N0b3JlZFpJbmRleD9cIlwiOnRoaXMuX3N0b3JlZFpJbmRleCksdGhpcy5kcmFnZ2luZz0hMSxlfHx0aGlzLl90cmlnZ2VyKFwiYmVmb3JlU3RvcFwiLHQsdGhpcy5fdWlIYXNoKCkpLHRoaXMucGxhY2Vob2xkZXJbMF0ucGFyZW50Tm9kZS5yZW1vdmVDaGlsZCh0aGlzLnBsYWNlaG9sZGVyWzBdKSx0aGlzLmNhbmNlbEhlbHBlclJlbW92YWx8fCh0aGlzLmhlbHBlclswXSE9PXRoaXMuY3VycmVudEl0ZW1bMF0mJnRoaXMuaGVscGVyLnJlbW92ZSgpLHRoaXMuaGVscGVyPW51bGwpLCFlKXtmb3Iocz0wO24ubGVuZ3RoPnM7cysrKW5bc10uY2FsbCh0aGlzLHQpO3RoaXMuX3RyaWdnZXIoXCJzdG9wXCIsdCx0aGlzLl91aUhhc2goKSl9cmV0dXJuIHRoaXMuZnJvbU91dHNpZGU9ITEsIXRoaXMuY2FuY2VsSGVscGVyUmVtb3ZhbH0sX3RyaWdnZXI6ZnVuY3Rpb24oKXt0LldpZGdldC5wcm90b3R5cGUuX3RyaWdnZXIuYXBwbHkodGhpcyxhcmd1bWVudHMpPT09ITEmJnRoaXMuY2FuY2VsKCl9LF91aUhhc2g6ZnVuY3Rpb24oZSl7dmFyIGk9ZXx8dGhpcztyZXR1cm57aGVscGVyOmkuaGVscGVyLHBsYWNlaG9sZGVyOmkucGxhY2Vob2xkZXJ8fHQoW10pLHBvc2l0aW9uOmkucG9zaXRpb24sb3JpZ2luYWxQb3NpdGlvbjppLm9yaWdpbmFsUG9zaXRpb24sb2Zmc2V0OmkucG9zaXRpb25BYnMsaXRlbTppLmN1cnJlbnRJdGVtLHNlbmRlcjplP2UuZWxlbWVudDpudWxsfX19KSx0LndpZGdldChcInVpLmFjY29yZGlvblwiLHt2ZXJzaW9uOlwiMS4xMi4xXCIsb3B0aW9uczp7YWN0aXZlOjAsYW5pbWF0ZTp7fSxjbGFzc2VzOntcInVpLWFjY29yZGlvbi1oZWFkZXJcIjpcInVpLWNvcm5lci10b3BcIixcInVpLWFjY29yZGlvbi1oZWFkZXItY29sbGFwc2VkXCI6XCJ1aS1jb3JuZXItYWxsXCIsXCJ1aS1hY2NvcmRpb24tY29udGVudFwiOlwidWktY29ybmVyLWJvdHRvbVwifSxjb2xsYXBzaWJsZTohMSxldmVudDpcImNsaWNrXCIsaGVhZGVyOlwiPiBsaSA+IDpmaXJzdC1jaGlsZCwgPiA6bm90KGxpKTpldmVuXCIsaGVpZ2h0U3R5bGU6XCJhdXRvXCIsaWNvbnM6e2FjdGl2ZUhlYWRlcjpcInVpLWljb24tdHJpYW5nbGUtMS1zXCIsaGVhZGVyOlwidWktaWNvbi10cmlhbmdsZS0xLWVcIn0sYWN0aXZhdGU6bnVsbCxiZWZvcmVBY3RpdmF0ZTpudWxsfSxoaWRlUHJvcHM6e2JvcmRlclRvcFdpZHRoOlwiaGlkZVwiLGJvcmRlckJvdHRvbVdpZHRoOlwiaGlkZVwiLHBhZGRpbmdUb3A6XCJoaWRlXCIscGFkZGluZ0JvdHRvbTpcImhpZGVcIixoZWlnaHQ6XCJoaWRlXCJ9LHNob3dQcm9wczp7Ym9yZGVyVG9wV2lkdGg6XCJzaG93XCIsYm9yZGVyQm90dG9tV2lkdGg6XCJzaG93XCIscGFkZGluZ1RvcDpcInNob3dcIixwYWRkaW5nQm90dG9tOlwic2hvd1wiLGhlaWdodDpcInNob3dcIn0sX2NyZWF0ZTpmdW5jdGlvbigpe3ZhciBlPXRoaXMub3B0aW9uczt0aGlzLnByZXZTaG93PXRoaXMucHJldkhpZGU9dCgpLHRoaXMuX2FkZENsYXNzKFwidWktYWNjb3JkaW9uXCIsXCJ1aS13aWRnZXQgdWktaGVscGVyLXJlc2V0XCIpLHRoaXMuZWxlbWVudC5hdHRyKFwicm9sZVwiLFwidGFibGlzdFwiKSxlLmNvbGxhcHNpYmxlfHxlLmFjdGl2ZSE9PSExJiZudWxsIT1lLmFjdGl2ZXx8KGUuYWN0aXZlPTApLHRoaXMuX3Byb2Nlc3NQYW5lbHMoKSwwPmUuYWN0aXZlJiYoZS5hY3RpdmUrPXRoaXMuaGVhZGVycy5sZW5ndGgpLHRoaXMuX3JlZnJlc2goKX0sX2dldENyZWF0ZUV2ZW50RGF0YTpmdW5jdGlvbigpe3JldHVybntoZWFkZXI6dGhpcy5hY3RpdmUscGFuZWw6dGhpcy5hY3RpdmUubGVuZ3RoP3RoaXMuYWN0aXZlLm5leHQoKTp0KCl9fSxfY3JlYXRlSWNvbnM6ZnVuY3Rpb24oKXt2YXIgZSxpLHM9dGhpcy5vcHRpb25zLmljb25zO3MmJihlPXQoXCI8c3Bhbj5cIiksdGhpcy5fYWRkQ2xhc3MoZSxcInVpLWFjY29yZGlvbi1oZWFkZXItaWNvblwiLFwidWktaWNvbiBcIitzLmhlYWRlciksZS5wcmVwZW5kVG8odGhpcy5oZWFkZXJzKSxpPXRoaXMuYWN0aXZlLmNoaWxkcmVuKFwiLnVpLWFjY29yZGlvbi1oZWFkZXItaWNvblwiKSx0aGlzLl9yZW1vdmVDbGFzcyhpLHMuaGVhZGVyKS5fYWRkQ2xhc3MoaSxudWxsLHMuYWN0aXZlSGVhZGVyKS5fYWRkQ2xhc3ModGhpcy5oZWFkZXJzLFwidWktYWNjb3JkaW9uLWljb25zXCIpKVxufSxfZGVzdHJveUljb25zOmZ1bmN0aW9uKCl7dGhpcy5fcmVtb3ZlQ2xhc3ModGhpcy5oZWFkZXJzLFwidWktYWNjb3JkaW9uLWljb25zXCIpLHRoaXMuaGVhZGVycy5jaGlsZHJlbihcIi51aS1hY2NvcmRpb24taGVhZGVyLWljb25cIikucmVtb3ZlKCl9LF9kZXN0cm95OmZ1bmN0aW9uKCl7dmFyIHQ7dGhpcy5lbGVtZW50LnJlbW92ZUF0dHIoXCJyb2xlXCIpLHRoaXMuaGVhZGVycy5yZW1vdmVBdHRyKFwicm9sZSBhcmlhLWV4cGFuZGVkIGFyaWEtc2VsZWN0ZWQgYXJpYS1jb250cm9scyB0YWJJbmRleFwiKS5yZW1vdmVVbmlxdWVJZCgpLHRoaXMuX2Rlc3Ryb3lJY29ucygpLHQ9dGhpcy5oZWFkZXJzLm5leHQoKS5jc3MoXCJkaXNwbGF5XCIsXCJcIikucmVtb3ZlQXR0cihcInJvbGUgYXJpYS1oaWRkZW4gYXJpYS1sYWJlbGxlZGJ5XCIpLnJlbW92ZVVuaXF1ZUlkKCksXCJjb250ZW50XCIhPT10aGlzLm9wdGlvbnMuaGVpZ2h0U3R5bGUmJnQuY3NzKFwiaGVpZ2h0XCIsXCJcIil9LF9zZXRPcHRpb246ZnVuY3Rpb24odCxlKXtyZXR1cm5cImFjdGl2ZVwiPT09dD8odGhpcy5fYWN0aXZhdGUoZSksdm9pZCAwKTooXCJldmVudFwiPT09dCYmKHRoaXMub3B0aW9ucy5ldmVudCYmdGhpcy5fb2ZmKHRoaXMuaGVhZGVycyx0aGlzLm9wdGlvbnMuZXZlbnQpLHRoaXMuX3NldHVwRXZlbnRzKGUpKSx0aGlzLl9zdXBlcih0LGUpLFwiY29sbGFwc2libGVcIiE9PXR8fGV8fHRoaXMub3B0aW9ucy5hY3RpdmUhPT0hMXx8dGhpcy5fYWN0aXZhdGUoMCksXCJpY29uc1wiPT09dCYmKHRoaXMuX2Rlc3Ryb3lJY29ucygpLGUmJnRoaXMuX2NyZWF0ZUljb25zKCkpLHZvaWQgMCl9LF9zZXRPcHRpb25EaXNhYmxlZDpmdW5jdGlvbih0KXt0aGlzLl9zdXBlcih0KSx0aGlzLmVsZW1lbnQuYXR0cihcImFyaWEtZGlzYWJsZWRcIix0KSx0aGlzLl90b2dnbGVDbGFzcyhudWxsLFwidWktc3RhdGUtZGlzYWJsZWRcIiwhIXQpLHRoaXMuX3RvZ2dsZUNsYXNzKHRoaXMuaGVhZGVycy5hZGQodGhpcy5oZWFkZXJzLm5leHQoKSksbnVsbCxcInVpLXN0YXRlLWRpc2FibGVkXCIsISF0KX0sX2tleWRvd246ZnVuY3Rpb24oZSl7aWYoIWUuYWx0S2V5JiYhZS5jdHJsS2V5KXt2YXIgaT10LnVpLmtleUNvZGUscz10aGlzLmhlYWRlcnMubGVuZ3RoLG49dGhpcy5oZWFkZXJzLmluZGV4KGUudGFyZ2V0KSxvPSExO3N3aXRjaChlLmtleUNvZGUpe2Nhc2UgaS5SSUdIVDpjYXNlIGkuRE9XTjpvPXRoaXMuaGVhZGVyc1sobisxKSVzXTticmVhaztjYXNlIGkuTEVGVDpjYXNlIGkuVVA6bz10aGlzLmhlYWRlcnNbKG4tMStzKSVzXTticmVhaztjYXNlIGkuU1BBQ0U6Y2FzZSBpLkVOVEVSOnRoaXMuX2V2ZW50SGFuZGxlcihlKTticmVhaztjYXNlIGkuSE9NRTpvPXRoaXMuaGVhZGVyc1swXTticmVhaztjYXNlIGkuRU5EOm89dGhpcy5oZWFkZXJzW3MtMV19byYmKHQoZS50YXJnZXQpLmF0dHIoXCJ0YWJJbmRleFwiLC0xKSx0KG8pLmF0dHIoXCJ0YWJJbmRleFwiLDApLHQobykudHJpZ2dlcihcImZvY3VzXCIpLGUucHJldmVudERlZmF1bHQoKSl9fSxfcGFuZWxLZXlEb3duOmZ1bmN0aW9uKGUpe2Uua2V5Q29kZT09PXQudWkua2V5Q29kZS5VUCYmZS5jdHJsS2V5JiZ0KGUuY3VycmVudFRhcmdldCkucHJldigpLnRyaWdnZXIoXCJmb2N1c1wiKX0scmVmcmVzaDpmdW5jdGlvbigpe3ZhciBlPXRoaXMub3B0aW9uczt0aGlzLl9wcm9jZXNzUGFuZWxzKCksZS5hY3RpdmU9PT0hMSYmZS5jb2xsYXBzaWJsZT09PSEwfHwhdGhpcy5oZWFkZXJzLmxlbmd0aD8oZS5hY3RpdmU9ITEsdGhpcy5hY3RpdmU9dCgpKTplLmFjdGl2ZT09PSExP3RoaXMuX2FjdGl2YXRlKDApOnRoaXMuYWN0aXZlLmxlbmd0aCYmIXQuY29udGFpbnModGhpcy5lbGVtZW50WzBdLHRoaXMuYWN0aXZlWzBdKT90aGlzLmhlYWRlcnMubGVuZ3RoPT09dGhpcy5oZWFkZXJzLmZpbmQoXCIudWktc3RhdGUtZGlzYWJsZWRcIikubGVuZ3RoPyhlLmFjdGl2ZT0hMSx0aGlzLmFjdGl2ZT10KCkpOnRoaXMuX2FjdGl2YXRlKE1hdGgubWF4KDAsZS5hY3RpdmUtMSkpOmUuYWN0aXZlPXRoaXMuaGVhZGVycy5pbmRleCh0aGlzLmFjdGl2ZSksdGhpcy5fZGVzdHJveUljb25zKCksdGhpcy5fcmVmcmVzaCgpfSxfcHJvY2Vzc1BhbmVsczpmdW5jdGlvbigpe3ZhciB0PXRoaXMuaGVhZGVycyxlPXRoaXMucGFuZWxzO3RoaXMuaGVhZGVycz10aGlzLmVsZW1lbnQuZmluZCh0aGlzLm9wdGlvbnMuaGVhZGVyKSx0aGlzLl9hZGRDbGFzcyh0aGlzLmhlYWRlcnMsXCJ1aS1hY2NvcmRpb24taGVhZGVyIHVpLWFjY29yZGlvbi1oZWFkZXItY29sbGFwc2VkXCIsXCJ1aS1zdGF0ZS1kZWZhdWx0XCIpLHRoaXMucGFuZWxzPXRoaXMuaGVhZGVycy5uZXh0KCkuZmlsdGVyKFwiOm5vdCgudWktYWNjb3JkaW9uLWNvbnRlbnQtYWN0aXZlKVwiKS5oaWRlKCksdGhpcy5fYWRkQ2xhc3ModGhpcy5wYW5lbHMsXCJ1aS1hY2NvcmRpb24tY29udGVudFwiLFwidWktaGVscGVyLXJlc2V0IHVpLXdpZGdldC1jb250ZW50XCIpLGUmJih0aGlzLl9vZmYodC5ub3QodGhpcy5oZWFkZXJzKSksdGhpcy5fb2ZmKGUubm90KHRoaXMucGFuZWxzKSkpfSxfcmVmcmVzaDpmdW5jdGlvbigpe3ZhciBlLGk9dGhpcy5vcHRpb25zLHM9aS5oZWlnaHRTdHlsZSxuPXRoaXMuZWxlbWVudC5wYXJlbnQoKTt0aGlzLmFjdGl2ZT10aGlzLl9maW5kQWN0aXZlKGkuYWN0aXZlKSx0aGlzLl9hZGRDbGFzcyh0aGlzLmFjdGl2ZSxcInVpLWFjY29yZGlvbi1oZWFkZXItYWN0aXZlXCIsXCJ1aS1zdGF0ZS1hY3RpdmVcIikuX3JlbW92ZUNsYXNzKHRoaXMuYWN0aXZlLFwidWktYWNjb3JkaW9uLWhlYWRlci1jb2xsYXBzZWRcIiksdGhpcy5fYWRkQ2xhc3ModGhpcy5hY3RpdmUubmV4dCgpLFwidWktYWNjb3JkaW9uLWNvbnRlbnQtYWN0aXZlXCIpLHRoaXMuYWN0aXZlLm5leHQoKS5zaG93KCksdGhpcy5oZWFkZXJzLmF0dHIoXCJyb2xlXCIsXCJ0YWJcIikuZWFjaChmdW5jdGlvbigpe3ZhciBlPXQodGhpcyksaT1lLnVuaXF1ZUlkKCkuYXR0cihcImlkXCIpLHM9ZS5uZXh0KCksbj1zLnVuaXF1ZUlkKCkuYXR0cihcImlkXCIpO2UuYXR0cihcImFyaWEtY29udHJvbHNcIixuKSxzLmF0dHIoXCJhcmlhLWxhYmVsbGVkYnlcIixpKX0pLm5leHQoKS5hdHRyKFwicm9sZVwiLFwidGFicGFuZWxcIiksdGhpcy5oZWFkZXJzLm5vdCh0aGlzLmFjdGl2ZSkuYXR0cih7XCJhcmlhLXNlbGVjdGVkXCI6XCJmYWxzZVwiLFwiYXJpYS1leHBhbmRlZFwiOlwiZmFsc2VcIix0YWJJbmRleDotMX0pLm5leHQoKS5hdHRyKHtcImFyaWEtaGlkZGVuXCI6XCJ0cnVlXCJ9KS5oaWRlKCksdGhpcy5hY3RpdmUubGVuZ3RoP3RoaXMuYWN0aXZlLmF0dHIoe1wiYXJpYS1zZWxlY3RlZFwiOlwidHJ1ZVwiLFwiYXJpYS1leHBhbmRlZFwiOlwidHJ1ZVwiLHRhYkluZGV4OjB9KS5uZXh0KCkuYXR0cih7XCJhcmlhLWhpZGRlblwiOlwiZmFsc2VcIn0pOnRoaXMuaGVhZGVycy5lcSgwKS5hdHRyKFwidGFiSW5kZXhcIiwwKSx0aGlzLl9jcmVhdGVJY29ucygpLHRoaXMuX3NldHVwRXZlbnRzKGkuZXZlbnQpLFwiZmlsbFwiPT09cz8oZT1uLmhlaWdodCgpLHRoaXMuZWxlbWVudC5zaWJsaW5ncyhcIjp2aXNpYmxlXCIpLmVhY2goZnVuY3Rpb24oKXt2YXIgaT10KHRoaXMpLHM9aS5jc3MoXCJwb3NpdGlvblwiKTtcImFic29sdXRlXCIhPT1zJiZcImZpeGVkXCIhPT1zJiYoZS09aS5vdXRlckhlaWdodCghMCkpfSksdGhpcy5oZWFkZXJzLmVhY2goZnVuY3Rpb24oKXtlLT10KHRoaXMpLm91dGVySGVpZ2h0KCEwKX0pLHRoaXMuaGVhZGVycy5uZXh0KCkuZWFjaChmdW5jdGlvbigpe3QodGhpcykuaGVpZ2h0KE1hdGgubWF4KDAsZS10KHRoaXMpLmlubmVySGVpZ2h0KCkrdCh0aGlzKS5oZWlnaHQoKSkpfSkuY3NzKFwib3ZlcmZsb3dcIixcImF1dG9cIikpOlwiYXV0b1wiPT09cyYmKGU9MCx0aGlzLmhlYWRlcnMubmV4dCgpLmVhY2goZnVuY3Rpb24oKXt2YXIgaT10KHRoaXMpLmlzKFwiOnZpc2libGVcIik7aXx8dCh0aGlzKS5zaG93KCksZT1NYXRoLm1heChlLHQodGhpcykuY3NzKFwiaGVpZ2h0XCIsXCJcIikuaGVpZ2h0KCkpLGl8fHQodGhpcykuaGlkZSgpfSkuaGVpZ2h0KGUpKX0sX2FjdGl2YXRlOmZ1bmN0aW9uKGUpe3ZhciBpPXRoaXMuX2ZpbmRBY3RpdmUoZSlbMF07aSE9PXRoaXMuYWN0aXZlWzBdJiYoaT1pfHx0aGlzLmFjdGl2ZVswXSx0aGlzLl9ldmVudEhhbmRsZXIoe3RhcmdldDppLGN1cnJlbnRUYXJnZXQ6aSxwcmV2ZW50RGVmYXVsdDp0Lm5vb3B9KSl9LF9maW5kQWN0aXZlOmZ1bmN0aW9uKGUpe3JldHVyblwibnVtYmVyXCI9PXR5cGVvZiBlP3RoaXMuaGVhZGVycy5lcShlKTp0KCl9LF9zZXR1cEV2ZW50czpmdW5jdGlvbihlKXt2YXIgaT17a2V5ZG93bjpcIl9rZXlkb3duXCJ9O2UmJnQuZWFjaChlLnNwbGl0KFwiIFwiKSxmdW5jdGlvbih0LGUpe2lbZV09XCJfZXZlbnRIYW5kbGVyXCJ9KSx0aGlzLl9vZmYodGhpcy5oZWFkZXJzLmFkZCh0aGlzLmhlYWRlcnMubmV4dCgpKSksdGhpcy5fb24odGhpcy5oZWFkZXJzLGkpLHRoaXMuX29uKHRoaXMuaGVhZGVycy5uZXh0KCkse2tleWRvd246XCJfcGFuZWxLZXlEb3duXCJ9KSx0aGlzLl9ob3ZlcmFibGUodGhpcy5oZWFkZXJzKSx0aGlzLl9mb2N1c2FibGUodGhpcy5oZWFkZXJzKX0sX2V2ZW50SGFuZGxlcjpmdW5jdGlvbihlKXt2YXIgaSxzLG49dGhpcy5vcHRpb25zLG89dGhpcy5hY3RpdmUsYT10KGUuY3VycmVudFRhcmdldCkscj1hWzBdPT09b1swXSxoPXImJm4uY29sbGFwc2libGUsbD1oP3QoKTphLm5leHQoKSxjPW8ubmV4dCgpLHU9e29sZEhlYWRlcjpvLG9sZFBhbmVsOmMsbmV3SGVhZGVyOmg/dCgpOmEsbmV3UGFuZWw6bH07ZS5wcmV2ZW50RGVmYXVsdCgpLHImJiFuLmNvbGxhcHNpYmxlfHx0aGlzLl90cmlnZ2VyKFwiYmVmb3JlQWN0aXZhdGVcIixlLHUpPT09ITF8fChuLmFjdGl2ZT1oPyExOnRoaXMuaGVhZGVycy5pbmRleChhKSx0aGlzLmFjdGl2ZT1yP3QoKTphLHRoaXMuX3RvZ2dsZSh1KSx0aGlzLl9yZW1vdmVDbGFzcyhvLFwidWktYWNjb3JkaW9uLWhlYWRlci1hY3RpdmVcIixcInVpLXN0YXRlLWFjdGl2ZVwiKSxuLmljb25zJiYoaT1vLmNoaWxkcmVuKFwiLnVpLWFjY29yZGlvbi1oZWFkZXItaWNvblwiKSx0aGlzLl9yZW1vdmVDbGFzcyhpLG51bGwsbi5pY29ucy5hY3RpdmVIZWFkZXIpLl9hZGRDbGFzcyhpLG51bGwsbi5pY29ucy5oZWFkZXIpKSxyfHwodGhpcy5fcmVtb3ZlQ2xhc3MoYSxcInVpLWFjY29yZGlvbi1oZWFkZXItY29sbGFwc2VkXCIpLl9hZGRDbGFzcyhhLFwidWktYWNjb3JkaW9uLWhlYWRlci1hY3RpdmVcIixcInVpLXN0YXRlLWFjdGl2ZVwiKSxuLmljb25zJiYocz1hLmNoaWxkcmVuKFwiLnVpLWFjY29yZGlvbi1oZWFkZXItaWNvblwiKSx0aGlzLl9yZW1vdmVDbGFzcyhzLG51bGwsbi5pY29ucy5oZWFkZXIpLl9hZGRDbGFzcyhzLG51bGwsbi5pY29ucy5hY3RpdmVIZWFkZXIpKSx0aGlzLl9hZGRDbGFzcyhhLm5leHQoKSxcInVpLWFjY29yZGlvbi1jb250ZW50LWFjdGl2ZVwiKSkpfSxfdG9nZ2xlOmZ1bmN0aW9uKGUpe3ZhciBpPWUubmV3UGFuZWwscz10aGlzLnByZXZTaG93Lmxlbmd0aD90aGlzLnByZXZTaG93OmUub2xkUGFuZWw7dGhpcy5wcmV2U2hvdy5hZGQodGhpcy5wcmV2SGlkZSkuc3RvcCghMCwhMCksdGhpcy5wcmV2U2hvdz1pLHRoaXMucHJldkhpZGU9cyx0aGlzLm9wdGlvbnMuYW5pbWF0ZT90aGlzLl9hbmltYXRlKGkscyxlKToocy5oaWRlKCksaS5zaG93KCksdGhpcy5fdG9nZ2xlQ29tcGxldGUoZSkpLHMuYXR0cih7XCJhcmlhLWhpZGRlblwiOlwidHJ1ZVwifSkscy5wcmV2KCkuYXR0cih7XCJhcmlhLXNlbGVjdGVkXCI6XCJmYWxzZVwiLFwiYXJpYS1leHBhbmRlZFwiOlwiZmFsc2VcIn0pLGkubGVuZ3RoJiZzLmxlbmd0aD9zLnByZXYoKS5hdHRyKHt0YWJJbmRleDotMSxcImFyaWEtZXhwYW5kZWRcIjpcImZhbHNlXCJ9KTppLmxlbmd0aCYmdGhpcy5oZWFkZXJzLmZpbHRlcihmdW5jdGlvbigpe3JldHVybiAwPT09cGFyc2VJbnQodCh0aGlzKS5hdHRyKFwidGFiSW5kZXhcIiksMTApfSkuYXR0cihcInRhYkluZGV4XCIsLTEpLGkuYXR0cihcImFyaWEtaGlkZGVuXCIsXCJmYWxzZVwiKS5wcmV2KCkuYXR0cih7XCJhcmlhLXNlbGVjdGVkXCI6XCJ0cnVlXCIsXCJhcmlhLWV4cGFuZGVkXCI6XCJ0cnVlXCIsdGFiSW5kZXg6MH0pfSxfYW5pbWF0ZTpmdW5jdGlvbih0LGUsaSl7dmFyIHMsbixvLGE9dGhpcyxyPTAsaD10LmNzcyhcImJveC1zaXppbmdcIiksbD10Lmxlbmd0aCYmKCFlLmxlbmd0aHx8dC5pbmRleCgpPGUuaW5kZXgoKSksYz10aGlzLm9wdGlvbnMuYW5pbWF0ZXx8e30sdT1sJiZjLmRvd258fGMsZD1mdW5jdGlvbigpe2EuX3RvZ2dsZUNvbXBsZXRlKGkpfTtyZXR1cm5cIm51bWJlclwiPT10eXBlb2YgdSYmKG89dSksXCJzdHJpbmdcIj09dHlwZW9mIHUmJihuPXUpLG49bnx8dS5lYXNpbmd8fGMuZWFzaW5nLG89b3x8dS5kdXJhdGlvbnx8Yy5kdXJhdGlvbixlLmxlbmd0aD90Lmxlbmd0aD8ocz10LnNob3coKS5vdXRlckhlaWdodCgpLGUuYW5pbWF0ZSh0aGlzLmhpZGVQcm9wcyx7ZHVyYXRpb246byxlYXNpbmc6bixzdGVwOmZ1bmN0aW9uKHQsZSl7ZS5ub3c9TWF0aC5yb3VuZCh0KX19KSx0LmhpZGUoKS5hbmltYXRlKHRoaXMuc2hvd1Byb3BzLHtkdXJhdGlvbjpvLGVhc2luZzpuLGNvbXBsZXRlOmQsc3RlcDpmdW5jdGlvbih0LGkpe2kubm93PU1hdGgucm91bmQodCksXCJoZWlnaHRcIiE9PWkucHJvcD9cImNvbnRlbnQtYm94XCI9PT1oJiYocis9aS5ub3cpOlwiY29udGVudFwiIT09YS5vcHRpb25zLmhlaWdodFN0eWxlJiYoaS5ub3c9TWF0aC5yb3VuZChzLWUub3V0ZXJIZWlnaHQoKS1yKSxyPTApfX0pLHZvaWQgMCk6ZS5hbmltYXRlKHRoaXMuaGlkZVByb3BzLG8sbixkKTp0LmFuaW1hdGUodGhpcy5zaG93UHJvcHMsbyxuLGQpfSxfdG9nZ2xlQ29tcGxldGU6ZnVuY3Rpb24odCl7dmFyIGU9dC5vbGRQYW5lbCxpPWUucHJldigpO3RoaXMuX3JlbW92ZUNsYXNzKGUsXCJ1aS1hY2NvcmRpb24tY29udGVudC1hY3RpdmVcIiksdGhpcy5fcmVtb3ZlQ2xhc3MoaSxcInVpLWFjY29yZGlvbi1oZWFkZXItYWN0aXZlXCIpLl9hZGRDbGFzcyhpLFwidWktYWNjb3JkaW9uLWhlYWRlci1jb2xsYXBzZWRcIiksZS5sZW5ndGgmJihlLnBhcmVudCgpWzBdLmNsYXNzTmFtZT1lLnBhcmVudCgpWzBdLmNsYXNzTmFtZSksdGhpcy5fdHJpZ2dlcihcImFjdGl2YXRlXCIsbnVsbCx0KX19KSx0LndpZGdldChcInVpLm1lbnVcIix7dmVyc2lvbjpcIjEuMTIuMVwiLGRlZmF1bHRFbGVtZW50OlwiPHVsPlwiLGRlbGF5OjMwMCxvcHRpb25zOntpY29uczp7c3VibWVudTpcInVpLWljb24tY2FyZXQtMS1lXCJ9LGl0ZW1zOlwiPiAqXCIsbWVudXM6XCJ1bFwiLHBvc2l0aW9uOntteTpcImxlZnQgdG9wXCIsYXQ6XCJyaWdodCB0b3BcIn0scm9sZTpcIm1lbnVcIixibHVyOm51bGwsZm9jdXM6bnVsbCxzZWxlY3Q6bnVsbH0sX2NyZWF0ZTpmdW5jdGlvbigpe3RoaXMuYWN0aXZlTWVudT10aGlzLmVsZW1lbnQsdGhpcy5tb3VzZUhhbmRsZWQ9ITEsdGhpcy5lbGVtZW50LnVuaXF1ZUlkKCkuYXR0cih7cm9sZTp0aGlzLm9wdGlvbnMucm9sZSx0YWJJbmRleDowfSksdGhpcy5fYWRkQ2xhc3MoXCJ1aS1tZW51XCIsXCJ1aS13aWRnZXQgdWktd2lkZ2V0LWNvbnRlbnRcIiksdGhpcy5fb24oe1wibW91c2Vkb3duIC51aS1tZW51LWl0ZW1cIjpmdW5jdGlvbih0KXt0LnByZXZlbnREZWZhdWx0KCl9LFwiY2xpY2sgLnVpLW1lbnUtaXRlbVwiOmZ1bmN0aW9uKGUpe3ZhciBpPXQoZS50YXJnZXQpLHM9dCh0LnVpLnNhZmVBY3RpdmVFbGVtZW50KHRoaXMuZG9jdW1lbnRbMF0pKTshdGhpcy5tb3VzZUhhbmRsZWQmJmkubm90KFwiLnVpLXN0YXRlLWRpc2FibGVkXCIpLmxlbmd0aCYmKHRoaXMuc2VsZWN0KGUpLGUuaXNQcm9wYWdhdGlvblN0b3BwZWQoKXx8KHRoaXMubW91c2VIYW5kbGVkPSEwKSxpLmhhcyhcIi51aS1tZW51XCIpLmxlbmd0aD90aGlzLmV4cGFuZChlKTohdGhpcy5lbGVtZW50LmlzKFwiOmZvY3VzXCIpJiZzLmNsb3Nlc3QoXCIudWktbWVudVwiKS5sZW5ndGgmJih0aGlzLmVsZW1lbnQudHJpZ2dlcihcImZvY3VzXCIsWyEwXSksdGhpcy5hY3RpdmUmJjE9PT10aGlzLmFjdGl2ZS5wYXJlbnRzKFwiLnVpLW1lbnVcIikubGVuZ3RoJiZjbGVhclRpbWVvdXQodGhpcy50aW1lcikpKX0sXCJtb3VzZWVudGVyIC51aS1tZW51LWl0ZW1cIjpmdW5jdGlvbihlKXtpZighdGhpcy5wcmV2aW91c0ZpbHRlcil7dmFyIGk9dChlLnRhcmdldCkuY2xvc2VzdChcIi51aS1tZW51LWl0ZW1cIikscz10KGUuY3VycmVudFRhcmdldCk7aVswXT09PXNbMF0mJih0aGlzLl9yZW1vdmVDbGFzcyhzLnNpYmxpbmdzKCkuY2hpbGRyZW4oXCIudWktc3RhdGUtYWN0aXZlXCIpLG51bGwsXCJ1aS1zdGF0ZS1hY3RpdmVcIiksdGhpcy5mb2N1cyhlLHMpKX19LG1vdXNlbGVhdmU6XCJjb2xsYXBzZUFsbFwiLFwibW91c2VsZWF2ZSAudWktbWVudVwiOlwiY29sbGFwc2VBbGxcIixmb2N1czpmdW5jdGlvbih0LGUpe3ZhciBpPXRoaXMuYWN0aXZlfHx0aGlzLmVsZW1lbnQuZmluZCh0aGlzLm9wdGlvbnMuaXRlbXMpLmVxKDApO2V8fHRoaXMuZm9jdXModCxpKX0sYmx1cjpmdW5jdGlvbihlKXt0aGlzLl9kZWxheShmdW5jdGlvbigpe3ZhciBpPSF0LmNvbnRhaW5zKHRoaXMuZWxlbWVudFswXSx0LnVpLnNhZmVBY3RpdmVFbGVtZW50KHRoaXMuZG9jdW1lbnRbMF0pKTtpJiZ0aGlzLmNvbGxhcHNlQWxsKGUpfSl9LGtleWRvd246XCJfa2V5ZG93blwifSksdGhpcy5yZWZyZXNoKCksdGhpcy5fb24odGhpcy5kb2N1bWVudCx7Y2xpY2s6ZnVuY3Rpb24odCl7dGhpcy5fY2xvc2VPbkRvY3VtZW50Q2xpY2sodCkmJnRoaXMuY29sbGFwc2VBbGwodCksdGhpcy5tb3VzZUhhbmRsZWQ9ITF9fSl9LF9kZXN0cm95OmZ1bmN0aW9uKCl7dmFyIGU9dGhpcy5lbGVtZW50LmZpbmQoXCIudWktbWVudS1pdGVtXCIpLnJlbW92ZUF0dHIoXCJyb2xlIGFyaWEtZGlzYWJsZWRcIiksaT1lLmNoaWxkcmVuKFwiLnVpLW1lbnUtaXRlbS13cmFwcGVyXCIpLnJlbW92ZVVuaXF1ZUlkKCkucmVtb3ZlQXR0cihcInRhYkluZGV4IHJvbGUgYXJpYS1oYXNwb3B1cFwiKTt0aGlzLmVsZW1lbnQucmVtb3ZlQXR0cihcImFyaWEtYWN0aXZlZGVzY2VuZGFudFwiKS5maW5kKFwiLnVpLW1lbnVcIikuYWRkQmFjaygpLnJlbW92ZUF0dHIoXCJyb2xlIGFyaWEtbGFiZWxsZWRieSBhcmlhLWV4cGFuZGVkIGFyaWEtaGlkZGVuIGFyaWEtZGlzYWJsZWQgdGFiSW5kZXhcIikucmVtb3ZlVW5pcXVlSWQoKS5zaG93KCksaS5jaGlsZHJlbigpLmVhY2goZnVuY3Rpb24oKXt2YXIgZT10KHRoaXMpO2UuZGF0YShcInVpLW1lbnUtc3VibWVudS1jYXJldFwiKSYmZS5yZW1vdmUoKX0pfSxfa2V5ZG93bjpmdW5jdGlvbihlKXt2YXIgaSxzLG4sbyxhPSEwO3N3aXRjaChlLmtleUNvZGUpe2Nhc2UgdC51aS5rZXlDb2RlLlBBR0VfVVA6dGhpcy5wcmV2aW91c1BhZ2UoZSk7YnJlYWs7Y2FzZSB0LnVpLmtleUNvZGUuUEFHRV9ET1dOOnRoaXMubmV4dFBhZ2UoZSk7YnJlYWs7Y2FzZSB0LnVpLmtleUNvZGUuSE9NRTp0aGlzLl9tb3ZlKFwiZmlyc3RcIixcImZpcnN0XCIsZSk7YnJlYWs7Y2FzZSB0LnVpLmtleUNvZGUuRU5EOnRoaXMuX21vdmUoXCJsYXN0XCIsXCJsYXN0XCIsZSk7YnJlYWs7Y2FzZSB0LnVpLmtleUNvZGUuVVA6dGhpcy5wcmV2aW91cyhlKTticmVhaztjYXNlIHQudWkua2V5Q29kZS5ET1dOOnRoaXMubmV4dChlKTticmVhaztjYXNlIHQudWkua2V5Q29kZS5MRUZUOnRoaXMuY29sbGFwc2UoZSk7YnJlYWs7Y2FzZSB0LnVpLmtleUNvZGUuUklHSFQ6dGhpcy5hY3RpdmUmJiF0aGlzLmFjdGl2ZS5pcyhcIi51aS1zdGF0ZS1kaXNhYmxlZFwiKSYmdGhpcy5leHBhbmQoZSk7YnJlYWs7Y2FzZSB0LnVpLmtleUNvZGUuRU5URVI6Y2FzZSB0LnVpLmtleUNvZGUuU1BBQ0U6dGhpcy5fYWN0aXZhdGUoZSk7YnJlYWs7Y2FzZSB0LnVpLmtleUNvZGUuRVNDQVBFOnRoaXMuY29sbGFwc2UoZSk7YnJlYWs7ZGVmYXVsdDphPSExLHM9dGhpcy5wcmV2aW91c0ZpbHRlcnx8XCJcIixvPSExLG49ZS5rZXlDb2RlPj05NiYmMTA1Pj1lLmtleUNvZGU/XCJcIisoZS5rZXlDb2RlLTk2KTpTdHJpbmcuZnJvbUNoYXJDb2RlKGUua2V5Q29kZSksY2xlYXJUaW1lb3V0KHRoaXMuZmlsdGVyVGltZXIpLG49PT1zP289ITA6bj1zK24saT10aGlzLl9maWx0ZXJNZW51SXRlbXMobiksaT1vJiYtMSE9PWkuaW5kZXgodGhpcy5hY3RpdmUubmV4dCgpKT90aGlzLmFjdGl2ZS5uZXh0QWxsKFwiLnVpLW1lbnUtaXRlbVwiKTppLGkubGVuZ3RofHwobj1TdHJpbmcuZnJvbUNoYXJDb2RlKGUua2V5Q29kZSksaT10aGlzLl9maWx0ZXJNZW51SXRlbXMobikpLGkubGVuZ3RoPyh0aGlzLmZvY3VzKGUsaSksdGhpcy5wcmV2aW91c0ZpbHRlcj1uLHRoaXMuZmlsdGVyVGltZXI9dGhpcy5fZGVsYXkoZnVuY3Rpb24oKXtkZWxldGUgdGhpcy5wcmV2aW91c0ZpbHRlcn0sMWUzKSk6ZGVsZXRlIHRoaXMucHJldmlvdXNGaWx0ZXJ9YSYmZS5wcmV2ZW50RGVmYXVsdCgpfSxfYWN0aXZhdGU6ZnVuY3Rpb24odCl7dGhpcy5hY3RpdmUmJiF0aGlzLmFjdGl2ZS5pcyhcIi51aS1zdGF0ZS1kaXNhYmxlZFwiKSYmKHRoaXMuYWN0aXZlLmNoaWxkcmVuKFwiW2FyaWEtaGFzcG9wdXA9J3RydWUnXVwiKS5sZW5ndGg/dGhpcy5leHBhbmQodCk6dGhpcy5zZWxlY3QodCkpfSxyZWZyZXNoOmZ1bmN0aW9uKCl7dmFyIGUsaSxzLG4sbyxhPXRoaXMscj10aGlzLm9wdGlvbnMuaWNvbnMuc3VibWVudSxoPXRoaXMuZWxlbWVudC5maW5kKHRoaXMub3B0aW9ucy5tZW51cyk7dGhpcy5fdG9nZ2xlQ2xhc3MoXCJ1aS1tZW51LWljb25zXCIsbnVsbCwhIXRoaXMuZWxlbWVudC5maW5kKFwiLnVpLWljb25cIikubGVuZ3RoKSxzPWguZmlsdGVyKFwiOm5vdCgudWktbWVudSlcIikuaGlkZSgpLmF0dHIoe3JvbGU6dGhpcy5vcHRpb25zLnJvbGUsXCJhcmlhLWhpZGRlblwiOlwidHJ1ZVwiLFwiYXJpYS1leHBhbmRlZFwiOlwiZmFsc2VcIn0pLmVhY2goZnVuY3Rpb24oKXt2YXIgZT10KHRoaXMpLGk9ZS5wcmV2KCkscz10KFwiPHNwYW4+XCIpLmRhdGEoXCJ1aS1tZW51LXN1Ym1lbnUtY2FyZXRcIiwhMCk7YS5fYWRkQ2xhc3MocyxcInVpLW1lbnUtaWNvblwiLFwidWktaWNvbiBcIityKSxpLmF0dHIoXCJhcmlhLWhhc3BvcHVwXCIsXCJ0cnVlXCIpLnByZXBlbmQocyksZS5hdHRyKFwiYXJpYS1sYWJlbGxlZGJ5XCIsaS5hdHRyKFwiaWRcIikpfSksdGhpcy5fYWRkQ2xhc3MocyxcInVpLW1lbnVcIixcInVpLXdpZGdldCB1aS13aWRnZXQtY29udGVudCB1aS1mcm9udFwiKSxlPWguYWRkKHRoaXMuZWxlbWVudCksaT1lLmZpbmQodGhpcy5vcHRpb25zLml0ZW1zKSxpLm5vdChcIi51aS1tZW51LWl0ZW1cIikuZWFjaChmdW5jdGlvbigpe3ZhciBlPXQodGhpcyk7YS5faXNEaXZpZGVyKGUpJiZhLl9hZGRDbGFzcyhlLFwidWktbWVudS1kaXZpZGVyXCIsXCJ1aS13aWRnZXQtY29udGVudFwiKX0pLG49aS5ub3QoXCIudWktbWVudS1pdGVtLCAudWktbWVudS1kaXZpZGVyXCIpLG89bi5jaGlsZHJlbigpLm5vdChcIi51aS1tZW51XCIpLnVuaXF1ZUlkKCkuYXR0cih7dGFiSW5kZXg6LTEscm9sZTp0aGlzLl9pdGVtUm9sZSgpfSksdGhpcy5fYWRkQ2xhc3MobixcInVpLW1lbnUtaXRlbVwiKS5fYWRkQ2xhc3MobyxcInVpLW1lbnUtaXRlbS13cmFwcGVyXCIpLGkuZmlsdGVyKFwiLnVpLXN0YXRlLWRpc2FibGVkXCIpLmF0dHIoXCJhcmlhLWRpc2FibGVkXCIsXCJ0cnVlXCIpLHRoaXMuYWN0aXZlJiYhdC5jb250YWlucyh0aGlzLmVsZW1lbnRbMF0sdGhpcy5hY3RpdmVbMF0pJiZ0aGlzLmJsdXIoKX0sX2l0ZW1Sb2xlOmZ1bmN0aW9uKCl7cmV0dXJue21lbnU6XCJtZW51aXRlbVwiLGxpc3Rib3g6XCJvcHRpb25cIn1bdGhpcy5vcHRpb25zLnJvbGVdfSxfc2V0T3B0aW9uOmZ1bmN0aW9uKHQsZSl7aWYoXCJpY29uc1wiPT09dCl7dmFyIGk9dGhpcy5lbGVtZW50LmZpbmQoXCIudWktbWVudS1pY29uXCIpO3RoaXMuX3JlbW92ZUNsYXNzKGksbnVsbCx0aGlzLm9wdGlvbnMuaWNvbnMuc3VibWVudSkuX2FkZENsYXNzKGksbnVsbCxlLnN1Ym1lbnUpfXRoaXMuX3N1cGVyKHQsZSl9LF9zZXRPcHRpb25EaXNhYmxlZDpmdW5jdGlvbih0KXt0aGlzLl9zdXBlcih0KSx0aGlzLmVsZW1lbnQuYXR0cihcImFyaWEtZGlzYWJsZWRcIix0K1wiXCIpLHRoaXMuX3RvZ2dsZUNsYXNzKG51bGwsXCJ1aS1zdGF0ZS1kaXNhYmxlZFwiLCEhdCl9LGZvY3VzOmZ1bmN0aW9uKHQsZSl7dmFyIGkscyxuO3RoaXMuYmx1cih0LHQmJlwiZm9jdXNcIj09PXQudHlwZSksdGhpcy5fc2Nyb2xsSW50b1ZpZXcoZSksdGhpcy5hY3RpdmU9ZS5maXJzdCgpLHM9dGhpcy5hY3RpdmUuY2hpbGRyZW4oXCIudWktbWVudS1pdGVtLXdyYXBwZXJcIiksdGhpcy5fYWRkQ2xhc3MocyxudWxsLFwidWktc3RhdGUtYWN0aXZlXCIpLHRoaXMub3B0aW9ucy5yb2xlJiZ0aGlzLmVsZW1lbnQuYXR0cihcImFyaWEtYWN0aXZlZGVzY2VuZGFudFwiLHMuYXR0cihcImlkXCIpKSxuPXRoaXMuYWN0aXZlLnBhcmVudCgpLmNsb3Nlc3QoXCIudWktbWVudS1pdGVtXCIpLmNoaWxkcmVuKFwiLnVpLW1lbnUtaXRlbS13cmFwcGVyXCIpLHRoaXMuX2FkZENsYXNzKG4sbnVsbCxcInVpLXN0YXRlLWFjdGl2ZVwiKSx0JiZcImtleWRvd25cIj09PXQudHlwZT90aGlzLl9jbG9zZSgpOnRoaXMudGltZXI9dGhpcy5fZGVsYXkoZnVuY3Rpb24oKXt0aGlzLl9jbG9zZSgpfSx0aGlzLmRlbGF5KSxpPWUuY2hpbGRyZW4oXCIudWktbWVudVwiKSxpLmxlbmd0aCYmdCYmL15tb3VzZS8udGVzdCh0LnR5cGUpJiZ0aGlzLl9zdGFydE9wZW5pbmcoaSksdGhpcy5hY3RpdmVNZW51PWUucGFyZW50KCksdGhpcy5fdHJpZ2dlcihcImZvY3VzXCIsdCx7aXRlbTplfSl9LF9zY3JvbGxJbnRvVmlldzpmdW5jdGlvbihlKXt2YXIgaSxzLG4sbyxhLHI7dGhpcy5faGFzU2Nyb2xsKCkmJihpPXBhcnNlRmxvYXQodC5jc3ModGhpcy5hY3RpdmVNZW51WzBdLFwiYm9yZGVyVG9wV2lkdGhcIikpfHwwLHM9cGFyc2VGbG9hdCh0LmNzcyh0aGlzLmFjdGl2ZU1lbnVbMF0sXCJwYWRkaW5nVG9wXCIpKXx8MCxuPWUub2Zmc2V0KCkudG9wLXRoaXMuYWN0aXZlTWVudS5vZmZzZXQoKS50b3AtaS1zLG89dGhpcy5hY3RpdmVNZW51LnNjcm9sbFRvcCgpLGE9dGhpcy5hY3RpdmVNZW51LmhlaWdodCgpLHI9ZS5vdXRlckhlaWdodCgpLDA+bj90aGlzLmFjdGl2ZU1lbnUuc2Nyb2xsVG9wKG8rbik6bityPmEmJnRoaXMuYWN0aXZlTWVudS5zY3JvbGxUb3AobytuLWErcikpfSxibHVyOmZ1bmN0aW9uKHQsZSl7ZXx8Y2xlYXJUaW1lb3V0KHRoaXMudGltZXIpLHRoaXMuYWN0aXZlJiYodGhpcy5fcmVtb3ZlQ2xhc3ModGhpcy5hY3RpdmUuY2hpbGRyZW4oXCIudWktbWVudS1pdGVtLXdyYXBwZXJcIiksbnVsbCxcInVpLXN0YXRlLWFjdGl2ZVwiKSx0aGlzLl90cmlnZ2VyKFwiYmx1clwiLHQse2l0ZW06dGhpcy5hY3RpdmV9KSx0aGlzLmFjdGl2ZT1udWxsKX0sX3N0YXJ0T3BlbmluZzpmdW5jdGlvbih0KXtjbGVhclRpbWVvdXQodGhpcy50aW1lciksXCJ0cnVlXCI9PT10LmF0dHIoXCJhcmlhLWhpZGRlblwiKSYmKHRoaXMudGltZXI9dGhpcy5fZGVsYXkoZnVuY3Rpb24oKXt0aGlzLl9jbG9zZSgpLHRoaXMuX29wZW4odCl9LHRoaXMuZGVsYXkpKX0sX29wZW46ZnVuY3Rpb24oZSl7dmFyIGk9dC5leHRlbmQoe29mOnRoaXMuYWN0aXZlfSx0aGlzLm9wdGlvbnMucG9zaXRpb24pO2NsZWFyVGltZW91dCh0aGlzLnRpbWVyKSx0aGlzLmVsZW1lbnQuZmluZChcIi51aS1tZW51XCIpLm5vdChlLnBhcmVudHMoXCIudWktbWVudVwiKSkuaGlkZSgpLmF0dHIoXCJhcmlhLWhpZGRlblwiLFwidHJ1ZVwiKSxlLnNob3coKS5yZW1vdmVBdHRyKFwiYXJpYS1oaWRkZW5cIikuYXR0cihcImFyaWEtZXhwYW5kZWRcIixcInRydWVcIikucG9zaXRpb24oaSl9LGNvbGxhcHNlQWxsOmZ1bmN0aW9uKGUsaSl7Y2xlYXJUaW1lb3V0KHRoaXMudGltZXIpLHRoaXMudGltZXI9dGhpcy5fZGVsYXkoZnVuY3Rpb24oKXt2YXIgcz1pP3RoaXMuZWxlbWVudDp0KGUmJmUudGFyZ2V0KS5jbG9zZXN0KHRoaXMuZWxlbWVudC5maW5kKFwiLnVpLW1lbnVcIikpO3MubGVuZ3RofHwocz10aGlzLmVsZW1lbnQpLHRoaXMuX2Nsb3NlKHMpLHRoaXMuYmx1cihlKSx0aGlzLl9yZW1vdmVDbGFzcyhzLmZpbmQoXCIudWktc3RhdGUtYWN0aXZlXCIpLG51bGwsXCJ1aS1zdGF0ZS1hY3RpdmVcIiksdGhpcy5hY3RpdmVNZW51PXN9LHRoaXMuZGVsYXkpfSxfY2xvc2U6ZnVuY3Rpb24odCl7dHx8KHQ9dGhpcy5hY3RpdmU/dGhpcy5hY3RpdmUucGFyZW50KCk6dGhpcy5lbGVtZW50KSx0LmZpbmQoXCIudWktbWVudVwiKS5oaWRlKCkuYXR0cihcImFyaWEtaGlkZGVuXCIsXCJ0cnVlXCIpLmF0dHIoXCJhcmlhLWV4cGFuZGVkXCIsXCJmYWxzZVwiKX0sX2Nsb3NlT25Eb2N1bWVudENsaWNrOmZ1bmN0aW9uKGUpe3JldHVybiF0KGUudGFyZ2V0KS5jbG9zZXN0KFwiLnVpLW1lbnVcIikubGVuZ3RofSxfaXNEaXZpZGVyOmZ1bmN0aW9uKHQpe3JldHVybiEvW15cXC1cXHUyMDE0XFx1MjAxM1xcc10vLnRlc3QodC50ZXh0KCkpfSxjb2xsYXBzZTpmdW5jdGlvbih0KXt2YXIgZT10aGlzLmFjdGl2ZSYmdGhpcy5hY3RpdmUucGFyZW50KCkuY2xvc2VzdChcIi51aS1tZW51LWl0ZW1cIix0aGlzLmVsZW1lbnQpO2UmJmUubGVuZ3RoJiYodGhpcy5fY2xvc2UoKSx0aGlzLmZvY3VzKHQsZSkpfSxleHBhbmQ6ZnVuY3Rpb24odCl7dmFyIGU9dGhpcy5hY3RpdmUmJnRoaXMuYWN0aXZlLmNoaWxkcmVuKFwiLnVpLW1lbnUgXCIpLmZpbmQodGhpcy5vcHRpb25zLml0ZW1zKS5maXJzdCgpO2UmJmUubGVuZ3RoJiYodGhpcy5fb3BlbihlLnBhcmVudCgpKSx0aGlzLl9kZWxheShmdW5jdGlvbigpe3RoaXMuZm9jdXModCxlKX0pKX0sbmV4dDpmdW5jdGlvbih0KXt0aGlzLl9tb3ZlKFwibmV4dFwiLFwiZmlyc3RcIix0KX0scHJldmlvdXM6ZnVuY3Rpb24odCl7dGhpcy5fbW92ZShcInByZXZcIixcImxhc3RcIix0KX0saXNGaXJzdEl0ZW06ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5hY3RpdmUmJiF0aGlzLmFjdGl2ZS5wcmV2QWxsKFwiLnVpLW1lbnUtaXRlbVwiKS5sZW5ndGh9LGlzTGFzdEl0ZW06ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5hY3RpdmUmJiF0aGlzLmFjdGl2ZS5uZXh0QWxsKFwiLnVpLW1lbnUtaXRlbVwiKS5sZW5ndGh9LF9tb3ZlOmZ1bmN0aW9uKHQsZSxpKXt2YXIgczt0aGlzLmFjdGl2ZSYmKHM9XCJmaXJzdFwiPT09dHx8XCJsYXN0XCI9PT10P3RoaXMuYWN0aXZlW1wiZmlyc3RcIj09PXQ/XCJwcmV2QWxsXCI6XCJuZXh0QWxsXCJdKFwiLnVpLW1lbnUtaXRlbVwiKS5lcSgtMSk6dGhpcy5hY3RpdmVbdCtcIkFsbFwiXShcIi51aS1tZW51LWl0ZW1cIikuZXEoMCkpLHMmJnMubGVuZ3RoJiZ0aGlzLmFjdGl2ZXx8KHM9dGhpcy5hY3RpdmVNZW51LmZpbmQodGhpcy5vcHRpb25zLml0ZW1zKVtlXSgpKSx0aGlzLmZvY3VzKGkscyl9LG5leHRQYWdlOmZ1bmN0aW9uKGUpe3ZhciBpLHMsbjtyZXR1cm4gdGhpcy5hY3RpdmU/KHRoaXMuaXNMYXN0SXRlbSgpfHwodGhpcy5faGFzU2Nyb2xsKCk/KHM9dGhpcy5hY3RpdmUub2Zmc2V0KCkudG9wLG49dGhpcy5lbGVtZW50LmhlaWdodCgpLHRoaXMuYWN0aXZlLm5leHRBbGwoXCIudWktbWVudS1pdGVtXCIpLmVhY2goZnVuY3Rpb24oKXtyZXR1cm4gaT10KHRoaXMpLDA+aS5vZmZzZXQoKS50b3Atcy1ufSksdGhpcy5mb2N1cyhlLGkpKTp0aGlzLmZvY3VzKGUsdGhpcy5hY3RpdmVNZW51LmZpbmQodGhpcy5vcHRpb25zLml0ZW1zKVt0aGlzLmFjdGl2ZT9cImxhc3RcIjpcImZpcnN0XCJdKCkpKSx2b2lkIDApOih0aGlzLm5leHQoZSksdm9pZCAwKX0scHJldmlvdXNQYWdlOmZ1bmN0aW9uKGUpe3ZhciBpLHMsbjtyZXR1cm4gdGhpcy5hY3RpdmU/KHRoaXMuaXNGaXJzdEl0ZW0oKXx8KHRoaXMuX2hhc1Njcm9sbCgpPyhzPXRoaXMuYWN0aXZlLm9mZnNldCgpLnRvcCxuPXRoaXMuZWxlbWVudC5oZWlnaHQoKSx0aGlzLmFjdGl2ZS5wcmV2QWxsKFwiLnVpLW1lbnUtaXRlbVwiKS5lYWNoKGZ1bmN0aW9uKCl7cmV0dXJuIGk9dCh0aGlzKSxpLm9mZnNldCgpLnRvcC1zK24+MH0pLHRoaXMuZm9jdXMoZSxpKSk6dGhpcy5mb2N1cyhlLHRoaXMuYWN0aXZlTWVudS5maW5kKHRoaXMub3B0aW9ucy5pdGVtcykuZmlyc3QoKSkpLHZvaWQgMCk6KHRoaXMubmV4dChlKSx2b2lkIDApfSxfaGFzU2Nyb2xsOmZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMuZWxlbWVudC5vdXRlckhlaWdodCgpPHRoaXMuZWxlbWVudC5wcm9wKFwic2Nyb2xsSGVpZ2h0XCIpfSxzZWxlY3Q6ZnVuY3Rpb24oZSl7dGhpcy5hY3RpdmU9dGhpcy5hY3RpdmV8fHQoZS50YXJnZXQpLmNsb3Nlc3QoXCIudWktbWVudS1pdGVtXCIpO3ZhciBpPXtpdGVtOnRoaXMuYWN0aXZlfTt0aGlzLmFjdGl2ZS5oYXMoXCIudWktbWVudVwiKS5sZW5ndGh8fHRoaXMuY29sbGFwc2VBbGwoZSwhMCksdGhpcy5fdHJpZ2dlcihcInNlbGVjdFwiLGUsaSl9LF9maWx0ZXJNZW51SXRlbXM6ZnVuY3Rpb24oZSl7dmFyIGk9ZS5yZXBsYWNlKC9bXFwtXFxbXFxde30oKSorPy4sXFxcXFxcXiR8I1xcc10vZyxcIlxcXFwkJlwiKSxzPVJlZ0V4cChcIl5cIitpLFwiaVwiKTtyZXR1cm4gdGhpcy5hY3RpdmVNZW51LmZpbmQodGhpcy5vcHRpb25zLml0ZW1zKS5maWx0ZXIoXCIudWktbWVudS1pdGVtXCIpLmZpbHRlcihmdW5jdGlvbigpe3JldHVybiBzLnRlc3QodC50cmltKHQodGhpcykuY2hpbGRyZW4oXCIudWktbWVudS1pdGVtLXdyYXBwZXJcIikudGV4dCgpKSl9KX19KSx0LndpZGdldChcInVpLmF1dG9jb21wbGV0ZVwiLHt2ZXJzaW9uOlwiMS4xMi4xXCIsZGVmYXVsdEVsZW1lbnQ6XCI8aW5wdXQ+XCIsb3B0aW9uczp7YXBwZW5kVG86bnVsbCxhdXRvRm9jdXM6ITEsZGVsYXk6MzAwLG1pbkxlbmd0aDoxLHBvc2l0aW9uOntteTpcImxlZnQgdG9wXCIsYXQ6XCJsZWZ0IGJvdHRvbVwiLGNvbGxpc2lvbjpcIm5vbmVcIn0sc291cmNlOm51bGwsY2hhbmdlOm51bGwsY2xvc2U6bnVsbCxmb2N1czpudWxsLG9wZW46bnVsbCxyZXNwb25zZTpudWxsLHNlYXJjaDpudWxsLHNlbGVjdDpudWxsfSxyZXF1ZXN0SW5kZXg6MCxwZW5kaW5nOjAsX2NyZWF0ZTpmdW5jdGlvbigpe3ZhciBlLGkscyxuPXRoaXMuZWxlbWVudFswXS5ub2RlTmFtZS50b0xvd2VyQ2FzZSgpLG89XCJ0ZXh0YXJlYVwiPT09bixhPVwiaW5wdXRcIj09PW47dGhpcy5pc011bHRpTGluZT1vfHwhYSYmdGhpcy5faXNDb250ZW50RWRpdGFibGUodGhpcy5lbGVtZW50KSx0aGlzLnZhbHVlTWV0aG9kPXRoaXMuZWxlbWVudFtvfHxhP1widmFsXCI6XCJ0ZXh0XCJdLHRoaXMuaXNOZXdNZW51PSEwLHRoaXMuX2FkZENsYXNzKFwidWktYXV0b2NvbXBsZXRlLWlucHV0XCIpLHRoaXMuZWxlbWVudC5hdHRyKFwiYXV0b2NvbXBsZXRlXCIsXCJvZmZcIiksdGhpcy5fb24odGhpcy5lbGVtZW50LHtrZXlkb3duOmZ1bmN0aW9uKG4pe2lmKHRoaXMuZWxlbWVudC5wcm9wKFwicmVhZE9ubHlcIikpcmV0dXJuIGU9ITAscz0hMCxpPSEwLHZvaWQgMDtlPSExLHM9ITEsaT0hMTt2YXIgbz10LnVpLmtleUNvZGU7c3dpdGNoKG4ua2V5Q29kZSl7Y2FzZSBvLlBBR0VfVVA6ZT0hMCx0aGlzLl9tb3ZlKFwicHJldmlvdXNQYWdlXCIsbik7YnJlYWs7Y2FzZSBvLlBBR0VfRE9XTjplPSEwLHRoaXMuX21vdmUoXCJuZXh0UGFnZVwiLG4pO2JyZWFrO2Nhc2Ugby5VUDplPSEwLHRoaXMuX2tleUV2ZW50KFwicHJldmlvdXNcIixuKTticmVhaztjYXNlIG8uRE9XTjplPSEwLHRoaXMuX2tleUV2ZW50KFwibmV4dFwiLG4pO2JyZWFrO2Nhc2Ugby5FTlRFUjp0aGlzLm1lbnUuYWN0aXZlJiYoZT0hMCxuLnByZXZlbnREZWZhdWx0KCksdGhpcy5tZW51LnNlbGVjdChuKSk7YnJlYWs7Y2FzZSBvLlRBQjp0aGlzLm1lbnUuYWN0aXZlJiZ0aGlzLm1lbnUuc2VsZWN0KG4pO2JyZWFrO2Nhc2Ugby5FU0NBUEU6dGhpcy5tZW51LmVsZW1lbnQuaXMoXCI6dmlzaWJsZVwiKSYmKHRoaXMuaXNNdWx0aUxpbmV8fHRoaXMuX3ZhbHVlKHRoaXMudGVybSksdGhpcy5jbG9zZShuKSxuLnByZXZlbnREZWZhdWx0KCkpO2JyZWFrO2RlZmF1bHQ6aT0hMCx0aGlzLl9zZWFyY2hUaW1lb3V0KG4pfX0sa2V5cHJlc3M6ZnVuY3Rpb24ocyl7aWYoZSlyZXR1cm4gZT0hMSwoIXRoaXMuaXNNdWx0aUxpbmV8fHRoaXMubWVudS5lbGVtZW50LmlzKFwiOnZpc2libGVcIikpJiZzLnByZXZlbnREZWZhdWx0KCksdm9pZCAwO2lmKCFpKXt2YXIgbj10LnVpLmtleUNvZGU7c3dpdGNoKHMua2V5Q29kZSl7Y2FzZSBuLlBBR0VfVVA6dGhpcy5fbW92ZShcInByZXZpb3VzUGFnZVwiLHMpO2JyZWFrO2Nhc2Ugbi5QQUdFX0RPV046dGhpcy5fbW92ZShcIm5leHRQYWdlXCIscyk7YnJlYWs7Y2FzZSBuLlVQOnRoaXMuX2tleUV2ZW50KFwicHJldmlvdXNcIixzKTticmVhaztjYXNlIG4uRE9XTjp0aGlzLl9rZXlFdmVudChcIm5leHRcIixzKX19fSxpbnB1dDpmdW5jdGlvbih0KXtyZXR1cm4gcz8ocz0hMSx0LnByZXZlbnREZWZhdWx0KCksdm9pZCAwKToodGhpcy5fc2VhcmNoVGltZW91dCh0KSx2b2lkIDApfSxmb2N1czpmdW5jdGlvbigpe3RoaXMuc2VsZWN0ZWRJdGVtPW51bGwsdGhpcy5wcmV2aW91cz10aGlzLl92YWx1ZSgpfSxibHVyOmZ1bmN0aW9uKHQpe3JldHVybiB0aGlzLmNhbmNlbEJsdXI/KGRlbGV0ZSB0aGlzLmNhbmNlbEJsdXIsdm9pZCAwKTooY2xlYXJUaW1lb3V0KHRoaXMuc2VhcmNoaW5nKSx0aGlzLmNsb3NlKHQpLHRoaXMuX2NoYW5nZSh0KSx2b2lkIDApfX0pLHRoaXMuX2luaXRTb3VyY2UoKSx0aGlzLm1lbnU9dChcIjx1bD5cIikuYXBwZW5kVG8odGhpcy5fYXBwZW5kVG8oKSkubWVudSh7cm9sZTpudWxsfSkuaGlkZSgpLm1lbnUoXCJpbnN0YW5jZVwiKSx0aGlzLl9hZGRDbGFzcyh0aGlzLm1lbnUuZWxlbWVudCxcInVpLWF1dG9jb21wbGV0ZVwiLFwidWktZnJvbnRcIiksdGhpcy5fb24odGhpcy5tZW51LmVsZW1lbnQse21vdXNlZG93bjpmdW5jdGlvbihlKXtlLnByZXZlbnREZWZhdWx0KCksdGhpcy5jYW5jZWxCbHVyPSEwLHRoaXMuX2RlbGF5KGZ1bmN0aW9uKCl7ZGVsZXRlIHRoaXMuY2FuY2VsQmx1cix0aGlzLmVsZW1lbnRbMF0hPT10LnVpLnNhZmVBY3RpdmVFbGVtZW50KHRoaXMuZG9jdW1lbnRbMF0pJiZ0aGlzLmVsZW1lbnQudHJpZ2dlcihcImZvY3VzXCIpfSl9LG1lbnVmb2N1czpmdW5jdGlvbihlLGkpe3ZhciBzLG47cmV0dXJuIHRoaXMuaXNOZXdNZW51JiYodGhpcy5pc05ld01lbnU9ITEsZS5vcmlnaW5hbEV2ZW50JiYvXm1vdXNlLy50ZXN0KGUub3JpZ2luYWxFdmVudC50eXBlKSk/KHRoaXMubWVudS5ibHVyKCksdGhpcy5kb2N1bWVudC5vbmUoXCJtb3VzZW1vdmVcIixmdW5jdGlvbigpe3QoZS50YXJnZXQpLnRyaWdnZXIoZS5vcmlnaW5hbEV2ZW50KX0pLHZvaWQgMCk6KG49aS5pdGVtLmRhdGEoXCJ1aS1hdXRvY29tcGxldGUtaXRlbVwiKSwhMSE9PXRoaXMuX3RyaWdnZXIoXCJmb2N1c1wiLGUse2l0ZW06bn0pJiZlLm9yaWdpbmFsRXZlbnQmJi9ea2V5Ly50ZXN0KGUub3JpZ2luYWxFdmVudC50eXBlKSYmdGhpcy5fdmFsdWUobi52YWx1ZSkscz1pLml0ZW0uYXR0cihcImFyaWEtbGFiZWxcIil8fG4udmFsdWUscyYmdC50cmltKHMpLmxlbmd0aCYmKHRoaXMubGl2ZVJlZ2lvbi5jaGlsZHJlbigpLmhpZGUoKSx0KFwiPGRpdj5cIikudGV4dChzKS5hcHBlbmRUbyh0aGlzLmxpdmVSZWdpb24pKSx2b2lkIDApfSxtZW51c2VsZWN0OmZ1bmN0aW9uKGUsaSl7dmFyIHM9aS5pdGVtLmRhdGEoXCJ1aS1hdXRvY29tcGxldGUtaXRlbVwiKSxuPXRoaXMucHJldmlvdXM7dGhpcy5lbGVtZW50WzBdIT09dC51aS5zYWZlQWN0aXZlRWxlbWVudCh0aGlzLmRvY3VtZW50WzBdKSYmKHRoaXMuZWxlbWVudC50cmlnZ2VyKFwiZm9jdXNcIiksdGhpcy5wcmV2aW91cz1uLHRoaXMuX2RlbGF5KGZ1bmN0aW9uKCl7dGhpcy5wcmV2aW91cz1uLHRoaXMuc2VsZWN0ZWRJdGVtPXN9KSksITEhPT10aGlzLl90cmlnZ2VyKFwic2VsZWN0XCIsZSx7aXRlbTpzfSkmJnRoaXMuX3ZhbHVlKHMudmFsdWUpLHRoaXMudGVybT10aGlzLl92YWx1ZSgpLHRoaXMuY2xvc2UoZSksdGhpcy5zZWxlY3RlZEl0ZW09c319KSx0aGlzLmxpdmVSZWdpb249dChcIjxkaXY+XCIse3JvbGU6XCJzdGF0dXNcIixcImFyaWEtbGl2ZVwiOlwiYXNzZXJ0aXZlXCIsXCJhcmlhLXJlbGV2YW50XCI6XCJhZGRpdGlvbnNcIn0pLmFwcGVuZFRvKHRoaXMuZG9jdW1lbnRbMF0uYm9keSksdGhpcy5fYWRkQ2xhc3ModGhpcy5saXZlUmVnaW9uLG51bGwsXCJ1aS1oZWxwZXItaGlkZGVuLWFjY2Vzc2libGVcIiksdGhpcy5fb24odGhpcy53aW5kb3cse2JlZm9yZXVubG9hZDpmdW5jdGlvbigpe3RoaXMuZWxlbWVudC5yZW1vdmVBdHRyKFwiYXV0b2NvbXBsZXRlXCIpfX0pfSxfZGVzdHJveTpmdW5jdGlvbigpe2NsZWFyVGltZW91dCh0aGlzLnNlYXJjaGluZyksdGhpcy5lbGVtZW50LnJlbW92ZUF0dHIoXCJhdXRvY29tcGxldGVcIiksdGhpcy5tZW51LmVsZW1lbnQucmVtb3ZlKCksdGhpcy5saXZlUmVnaW9uLnJlbW92ZSgpfSxfc2V0T3B0aW9uOmZ1bmN0aW9uKHQsZSl7dGhpcy5fc3VwZXIodCxlKSxcInNvdXJjZVwiPT09dCYmdGhpcy5faW5pdFNvdXJjZSgpLFwiYXBwZW5kVG9cIj09PXQmJnRoaXMubWVudS5lbGVtZW50LmFwcGVuZFRvKHRoaXMuX2FwcGVuZFRvKCkpLFwiZGlzYWJsZWRcIj09PXQmJmUmJnRoaXMueGhyJiZ0aGlzLnhoci5hYm9ydCgpfSxfaXNFdmVudFRhcmdldEluV2lkZ2V0OmZ1bmN0aW9uKGUpe3ZhciBpPXRoaXMubWVudS5lbGVtZW50WzBdO3JldHVybiBlLnRhcmdldD09PXRoaXMuZWxlbWVudFswXXx8ZS50YXJnZXQ9PT1pfHx0LmNvbnRhaW5zKGksZS50YXJnZXQpfSxfY2xvc2VPbkNsaWNrT3V0c2lkZTpmdW5jdGlvbih0KXt0aGlzLl9pc0V2ZW50VGFyZ2V0SW5XaWRnZXQodCl8fHRoaXMuY2xvc2UoKX0sX2FwcGVuZFRvOmZ1bmN0aW9uKCl7dmFyIGU9dGhpcy5vcHRpb25zLmFwcGVuZFRvO3JldHVybiBlJiYoZT1lLmpxdWVyeXx8ZS5ub2RlVHlwZT90KGUpOnRoaXMuZG9jdW1lbnQuZmluZChlKS5lcSgwKSksZSYmZVswXXx8KGU9dGhpcy5lbGVtZW50LmNsb3Nlc3QoXCIudWktZnJvbnQsIGRpYWxvZ1wiKSksZS5sZW5ndGh8fChlPXRoaXMuZG9jdW1lbnRbMF0uYm9keSksZX0sX2luaXRTb3VyY2U6ZnVuY3Rpb24oKXt2YXIgZSxpLHM9dGhpczt0LmlzQXJyYXkodGhpcy5vcHRpb25zLnNvdXJjZSk/KGU9dGhpcy5vcHRpb25zLnNvdXJjZSx0aGlzLnNvdXJjZT1mdW5jdGlvbihpLHMpe3ModC51aS5hdXRvY29tcGxldGUuZmlsdGVyKGUsaS50ZXJtKSl9KTpcInN0cmluZ1wiPT10eXBlb2YgdGhpcy5vcHRpb25zLnNvdXJjZT8oaT10aGlzLm9wdGlvbnMuc291cmNlLHRoaXMuc291cmNlPWZ1bmN0aW9uKGUsbil7cy54aHImJnMueGhyLmFib3J0KCkscy54aHI9dC5hamF4KHt1cmw6aSxkYXRhOmUsZGF0YVR5cGU6XCJqc29uXCIsc3VjY2VzczpmdW5jdGlvbih0KXtuKHQpfSxlcnJvcjpmdW5jdGlvbigpe24oW10pfX0pfSk6dGhpcy5zb3VyY2U9dGhpcy5vcHRpb25zLnNvdXJjZX0sX3NlYXJjaFRpbWVvdXQ6ZnVuY3Rpb24odCl7Y2xlYXJUaW1lb3V0KHRoaXMuc2VhcmNoaW5nKSx0aGlzLnNlYXJjaGluZz10aGlzLl9kZWxheShmdW5jdGlvbigpe3ZhciBlPXRoaXMudGVybT09PXRoaXMuX3ZhbHVlKCksaT10aGlzLm1lbnUuZWxlbWVudC5pcyhcIjp2aXNpYmxlXCIpLHM9dC5hbHRLZXl8fHQuY3RybEtleXx8dC5tZXRhS2V5fHx0LnNoaWZ0S2V5OyghZXx8ZSYmIWkmJiFzKSYmKHRoaXMuc2VsZWN0ZWRJdGVtPW51bGwsdGhpcy5zZWFyY2gobnVsbCx0KSl9LHRoaXMub3B0aW9ucy5kZWxheSl9LHNlYXJjaDpmdW5jdGlvbih0LGUpe3JldHVybiB0PW51bGwhPXQ/dDp0aGlzLl92YWx1ZSgpLHRoaXMudGVybT10aGlzLl92YWx1ZSgpLHQubGVuZ3RoPHRoaXMub3B0aW9ucy5taW5MZW5ndGg/dGhpcy5jbG9zZShlKTp0aGlzLl90cmlnZ2VyKFwic2VhcmNoXCIsZSkhPT0hMT90aGlzLl9zZWFyY2godCk6dm9pZCAwfSxfc2VhcmNoOmZ1bmN0aW9uKHQpe3RoaXMucGVuZGluZysrLHRoaXMuX2FkZENsYXNzKFwidWktYXV0b2NvbXBsZXRlLWxvYWRpbmdcIiksdGhpcy5jYW5jZWxTZWFyY2g9ITEsdGhpcy5zb3VyY2Uoe3Rlcm06dH0sdGhpcy5fcmVzcG9uc2UoKSl9LF9yZXNwb25zZTpmdW5jdGlvbigpe3ZhciBlPSsrdGhpcy5yZXF1ZXN0SW5kZXg7cmV0dXJuIHQucHJveHkoZnVuY3Rpb24odCl7ZT09PXRoaXMucmVxdWVzdEluZGV4JiZ0aGlzLl9fcmVzcG9uc2UodCksdGhpcy5wZW5kaW5nLS0sdGhpcy5wZW5kaW5nfHx0aGlzLl9yZW1vdmVDbGFzcyhcInVpLWF1dG9jb21wbGV0ZS1sb2FkaW5nXCIpfSx0aGlzKX0sX19yZXNwb25zZTpmdW5jdGlvbih0KXt0JiYodD10aGlzLl9ub3JtYWxpemUodCkpLHRoaXMuX3RyaWdnZXIoXCJyZXNwb25zZVwiLG51bGwse2NvbnRlbnQ6dH0pLCF0aGlzLm9wdGlvbnMuZGlzYWJsZWQmJnQmJnQubGVuZ3RoJiYhdGhpcy5jYW5jZWxTZWFyY2g/KHRoaXMuX3N1Z2dlc3QodCksdGhpcy5fdHJpZ2dlcihcIm9wZW5cIikpOnRoaXMuX2Nsb3NlKCl9LGNsb3NlOmZ1bmN0aW9uKHQpe3RoaXMuY2FuY2VsU2VhcmNoPSEwLHRoaXMuX2Nsb3NlKHQpfSxfY2xvc2U6ZnVuY3Rpb24odCl7dGhpcy5fb2ZmKHRoaXMuZG9jdW1lbnQsXCJtb3VzZWRvd25cIiksdGhpcy5tZW51LmVsZW1lbnQuaXMoXCI6dmlzaWJsZVwiKSYmKHRoaXMubWVudS5lbGVtZW50LmhpZGUoKSx0aGlzLm1lbnUuYmx1cigpLHRoaXMuaXNOZXdNZW51PSEwLHRoaXMuX3RyaWdnZXIoXCJjbG9zZVwiLHQpKX0sX2NoYW5nZTpmdW5jdGlvbih0KXt0aGlzLnByZXZpb3VzIT09dGhpcy5fdmFsdWUoKSYmdGhpcy5fdHJpZ2dlcihcImNoYW5nZVwiLHQse2l0ZW06dGhpcy5zZWxlY3RlZEl0ZW19KX0sX25vcm1hbGl6ZTpmdW5jdGlvbihlKXtyZXR1cm4gZS5sZW5ndGgmJmVbMF0ubGFiZWwmJmVbMF0udmFsdWU/ZTp0Lm1hcChlLGZ1bmN0aW9uKGUpe3JldHVyblwic3RyaW5nXCI9PXR5cGVvZiBlP3tsYWJlbDplLHZhbHVlOmV9OnQuZXh0ZW5kKHt9LGUse2xhYmVsOmUubGFiZWx8fGUudmFsdWUsdmFsdWU6ZS52YWx1ZXx8ZS5sYWJlbH0pfSl9LF9zdWdnZXN0OmZ1bmN0aW9uKGUpe3ZhciBpPXRoaXMubWVudS5lbGVtZW50LmVtcHR5KCk7dGhpcy5fcmVuZGVyTWVudShpLGUpLHRoaXMuaXNOZXdNZW51PSEwLHRoaXMubWVudS5yZWZyZXNoKCksaS5zaG93KCksdGhpcy5fcmVzaXplTWVudSgpLGkucG9zaXRpb24odC5leHRlbmQoe29mOnRoaXMuZWxlbWVudH0sdGhpcy5vcHRpb25zLnBvc2l0aW9uKSksdGhpcy5vcHRpb25zLmF1dG9Gb2N1cyYmdGhpcy5tZW51Lm5leHQoKSx0aGlzLl9vbih0aGlzLmRvY3VtZW50LHttb3VzZWRvd246XCJfY2xvc2VPbkNsaWNrT3V0c2lkZVwifSl9LF9yZXNpemVNZW51OmZ1bmN0aW9uKCl7dmFyIHQ9dGhpcy5tZW51LmVsZW1lbnQ7dC5vdXRlcldpZHRoKE1hdGgubWF4KHQud2lkdGgoXCJcIikub3V0ZXJXaWR0aCgpKzEsdGhpcy5lbGVtZW50Lm91dGVyV2lkdGgoKSkpfSxfcmVuZGVyTWVudTpmdW5jdGlvbihlLGkpe3ZhciBzPXRoaXM7dC5lYWNoKGksZnVuY3Rpb24odCxpKXtzLl9yZW5kZXJJdGVtRGF0YShlLGkpfSl9LF9yZW5kZXJJdGVtRGF0YTpmdW5jdGlvbih0LGUpe3JldHVybiB0aGlzLl9yZW5kZXJJdGVtKHQsZSkuZGF0YShcInVpLWF1dG9jb21wbGV0ZS1pdGVtXCIsZSl9LF9yZW5kZXJJdGVtOmZ1bmN0aW9uKGUsaSl7cmV0dXJuIHQoXCI8bGk+XCIpLmFwcGVuZCh0KFwiPGRpdj5cIikudGV4dChpLmxhYmVsKSkuYXBwZW5kVG8oZSl9LF9tb3ZlOmZ1bmN0aW9uKHQsZSl7cmV0dXJuIHRoaXMubWVudS5lbGVtZW50LmlzKFwiOnZpc2libGVcIik/dGhpcy5tZW51LmlzRmlyc3RJdGVtKCkmJi9ecHJldmlvdXMvLnRlc3QodCl8fHRoaXMubWVudS5pc0xhc3RJdGVtKCkmJi9ebmV4dC8udGVzdCh0KT8odGhpcy5pc011bHRpTGluZXx8dGhpcy5fdmFsdWUodGhpcy50ZXJtKSx0aGlzLm1lbnUuYmx1cigpLHZvaWQgMCk6KHRoaXMubWVudVt0XShlKSx2b2lkIDApOih0aGlzLnNlYXJjaChudWxsLGUpLHZvaWQgMCl9LHdpZGdldDpmdW5jdGlvbigpe3JldHVybiB0aGlzLm1lbnUuZWxlbWVudH0sX3ZhbHVlOmZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMudmFsdWVNZXRob2QuYXBwbHkodGhpcy5lbGVtZW50LGFyZ3VtZW50cyl9LF9rZXlFdmVudDpmdW5jdGlvbih0LGUpeyghdGhpcy5pc011bHRpTGluZXx8dGhpcy5tZW51LmVsZW1lbnQuaXMoXCI6dmlzaWJsZVwiKSkmJih0aGlzLl9tb3ZlKHQsZSksZS5wcmV2ZW50RGVmYXVsdCgpKX0sX2lzQ29udGVudEVkaXRhYmxlOmZ1bmN0aW9uKHQpe2lmKCF0Lmxlbmd0aClyZXR1cm4hMTt2YXIgZT10LnByb3AoXCJjb250ZW50RWRpdGFibGVcIik7cmV0dXJuXCJpbmhlcml0XCI9PT1lP3RoaXMuX2lzQ29udGVudEVkaXRhYmxlKHQucGFyZW50KCkpOlwidHJ1ZVwiPT09ZX19KSx0LmV4dGVuZCh0LnVpLmF1dG9jb21wbGV0ZSx7ZXNjYXBlUmVnZXg6ZnVuY3Rpb24odCl7cmV0dXJuIHQucmVwbGFjZSgvW1xcLVxcW1xcXXt9KCkqKz8uLFxcXFxcXF4kfCNcXHNdL2csXCJcXFxcJCZcIil9LGZpbHRlcjpmdW5jdGlvbihlLGkpe3ZhciBzPVJlZ0V4cCh0LnVpLmF1dG9jb21wbGV0ZS5lc2NhcGVSZWdleChpKSxcImlcIik7cmV0dXJuIHQuZ3JlcChlLGZ1bmN0aW9uKHQpe3JldHVybiBzLnRlc3QodC5sYWJlbHx8dC52YWx1ZXx8dCl9KX19KSx0LndpZGdldChcInVpLmF1dG9jb21wbGV0ZVwiLHQudWkuYXV0b2NvbXBsZXRlLHtvcHRpb25zOnttZXNzYWdlczp7bm9SZXN1bHRzOlwiTm8gc2VhcmNoIHJlc3VsdHMuXCIscmVzdWx0czpmdW5jdGlvbih0KXtyZXR1cm4gdCsodD4xP1wiIHJlc3VsdHMgYXJlXCI6XCIgcmVzdWx0IGlzXCIpK1wiIGF2YWlsYWJsZSwgdXNlIHVwIGFuZCBkb3duIGFycm93IGtleXMgdG8gbmF2aWdhdGUuXCJ9fX0sX19yZXNwb25zZTpmdW5jdGlvbihlKXt2YXIgaTt0aGlzLl9zdXBlckFwcGx5KGFyZ3VtZW50cyksdGhpcy5vcHRpb25zLmRpc2FibGVkfHx0aGlzLmNhbmNlbFNlYXJjaHx8KGk9ZSYmZS5sZW5ndGg/dGhpcy5vcHRpb25zLm1lc3NhZ2VzLnJlc3VsdHMoZS5sZW5ndGgpOnRoaXMub3B0aW9ucy5tZXNzYWdlcy5ub1Jlc3VsdHMsdGhpcy5saXZlUmVnaW9uLmNoaWxkcmVuKCkuaGlkZSgpLHQoXCI8ZGl2PlwiKS50ZXh0KGkpLmFwcGVuZFRvKHRoaXMubGl2ZVJlZ2lvbikpfX0pLHQudWkuYXV0b2NvbXBsZXRlO3ZhciBkPS91aS1jb3JuZXItKFthLXpdKXsyLDZ9L2c7dC53aWRnZXQoXCJ1aS5jb250cm9sZ3JvdXBcIix7dmVyc2lvbjpcIjEuMTIuMVwiLGRlZmF1bHRFbGVtZW50OlwiPGRpdj5cIixvcHRpb25zOntkaXJlY3Rpb246XCJob3Jpem9udGFsXCIsZGlzYWJsZWQ6bnVsbCxvbmx5VmlzaWJsZTohMCxpdGVtczp7YnV0dG9uOlwiaW5wdXRbdHlwZT1idXR0b25dLCBpbnB1dFt0eXBlPXN1Ym1pdF0sIGlucHV0W3R5cGU9cmVzZXRdLCBidXR0b24sIGFcIixjb250cm9sZ3JvdXBMYWJlbDpcIi51aS1jb250cm9sZ3JvdXAtbGFiZWxcIixjaGVja2JveHJhZGlvOlwiaW5wdXRbdHlwZT0nY2hlY2tib3gnXSwgaW5wdXRbdHlwZT0ncmFkaW8nXVwiLHNlbGVjdG1lbnU6XCJzZWxlY3RcIixzcGlubmVyOlwiLnVpLXNwaW5uZXItaW5wdXRcIn19LF9jcmVhdGU6ZnVuY3Rpb24oKXt0aGlzLl9lbmhhbmNlKCl9LF9lbmhhbmNlOmZ1bmN0aW9uKCl7dGhpcy5lbGVtZW50LmF0dHIoXCJyb2xlXCIsXCJ0b29sYmFyXCIpLHRoaXMucmVmcmVzaCgpfSxfZGVzdHJveTpmdW5jdGlvbigpe3RoaXMuX2NhbGxDaGlsZE1ldGhvZChcImRlc3Ryb3lcIiksdGhpcy5jaGlsZFdpZGdldHMucmVtb3ZlRGF0YShcInVpLWNvbnRyb2xncm91cC1kYXRhXCIpLHRoaXMuZWxlbWVudC5yZW1vdmVBdHRyKFwicm9sZVwiKSx0aGlzLm9wdGlvbnMuaXRlbXMuY29udHJvbGdyb3VwTGFiZWwmJnRoaXMuZWxlbWVudC5maW5kKHRoaXMub3B0aW9ucy5pdGVtcy5jb250cm9sZ3JvdXBMYWJlbCkuZmluZChcIi51aS1jb250cm9sZ3JvdXAtbGFiZWwtY29udGVudHNcIikuY29udGVudHMoKS51bndyYXAoKX0sX2luaXRXaWRnZXRzOmZ1bmN0aW9uKCl7dmFyIGU9dGhpcyxpPVtdO3QuZWFjaCh0aGlzLm9wdGlvbnMuaXRlbXMsZnVuY3Rpb24ocyxuKXt2YXIgbyxhPXt9O3JldHVybiBuP1wiY29udHJvbGdyb3VwTGFiZWxcIj09PXM/KG89ZS5lbGVtZW50LmZpbmQobiksby5lYWNoKGZ1bmN0aW9uKCl7dmFyIGU9dCh0aGlzKTtlLmNoaWxkcmVuKFwiLnVpLWNvbnRyb2xncm91cC1sYWJlbC1jb250ZW50c1wiKS5sZW5ndGh8fGUuY29udGVudHMoKS53cmFwQWxsKFwiPHNwYW4gY2xhc3M9J3VpLWNvbnRyb2xncm91cC1sYWJlbC1jb250ZW50cyc+PC9zcGFuPlwiKX0pLGUuX2FkZENsYXNzKG8sbnVsbCxcInVpLXdpZGdldCB1aS13aWRnZXQtY29udGVudCB1aS1zdGF0ZS1kZWZhdWx0XCIpLGk9aS5jb25jYXQoby5nZXQoKSksdm9pZCAwKToodC5mbltzXSYmKGE9ZVtcIl9cIitzK1wiT3B0aW9uc1wiXT9lW1wiX1wiK3MrXCJPcHRpb25zXCJdKFwibWlkZGxlXCIpOntjbGFzc2VzOnt9fSxlLmVsZW1lbnQuZmluZChuKS5lYWNoKGZ1bmN0aW9uKCl7dmFyIG49dCh0aGlzKSxvPW5bc10oXCJpbnN0YW5jZVwiKSxyPXQud2lkZ2V0LmV4dGVuZCh7fSxhKTtpZihcImJ1dHRvblwiIT09c3x8IW4ucGFyZW50KFwiLnVpLXNwaW5uZXJcIikubGVuZ3RoKXtvfHwobz1uW3NdKClbc10oXCJpbnN0YW5jZVwiKSksbyYmKHIuY2xhc3Nlcz1lLl9yZXNvbHZlQ2xhc3Nlc1ZhbHVlcyhyLmNsYXNzZXMsbykpLG5bc10ocik7dmFyIGg9bltzXShcIndpZGdldFwiKTt0LmRhdGEoaFswXSxcInVpLWNvbnRyb2xncm91cC1kYXRhXCIsbz9vOm5bc10oXCJpbnN0YW5jZVwiKSksaS5wdXNoKGhbMF0pfX0pKSx2b2lkIDApOnZvaWQgMH0pLHRoaXMuY2hpbGRXaWRnZXRzPXQodC51bmlxdWUoaSkpLHRoaXMuX2FkZENsYXNzKHRoaXMuY2hpbGRXaWRnZXRzLFwidWktY29udHJvbGdyb3VwLWl0ZW1cIil9LF9jYWxsQ2hpbGRNZXRob2Q6ZnVuY3Rpb24oZSl7dGhpcy5jaGlsZFdpZGdldHMuZWFjaChmdW5jdGlvbigpe3ZhciBpPXQodGhpcykscz1pLmRhdGEoXCJ1aS1jb250cm9sZ3JvdXAtZGF0YVwiKTtzJiZzW2VdJiZzW2VdKCl9KX0sX3VwZGF0ZUNvcm5lckNsYXNzOmZ1bmN0aW9uKHQsZSl7dmFyIGk9XCJ1aS1jb3JuZXItdG9wIHVpLWNvcm5lci1ib3R0b20gdWktY29ybmVyLWxlZnQgdWktY29ybmVyLXJpZ2h0IHVpLWNvcm5lci1hbGxcIixzPXRoaXMuX2J1aWxkU2ltcGxlT3B0aW9ucyhlLFwibGFiZWxcIikuY2xhc3Nlcy5sYWJlbDt0aGlzLl9yZW1vdmVDbGFzcyh0LG51bGwsaSksdGhpcy5fYWRkQ2xhc3ModCxudWxsLHMpfSxfYnVpbGRTaW1wbGVPcHRpb25zOmZ1bmN0aW9uKHQsZSl7dmFyIGk9XCJ2ZXJ0aWNhbFwiPT09dGhpcy5vcHRpb25zLmRpcmVjdGlvbixzPXtjbGFzc2VzOnt9fTtyZXR1cm4gcy5jbGFzc2VzW2VdPXttaWRkbGU6XCJcIixmaXJzdDpcInVpLWNvcm5lci1cIisoaT9cInRvcFwiOlwibGVmdFwiKSxsYXN0OlwidWktY29ybmVyLVwiKyhpP1wiYm90dG9tXCI6XCJyaWdodFwiKSxvbmx5OlwidWktY29ybmVyLWFsbFwifVt0XSxzfSxfc3Bpbm5lck9wdGlvbnM6ZnVuY3Rpb24odCl7dmFyIGU9dGhpcy5fYnVpbGRTaW1wbGVPcHRpb25zKHQsXCJ1aS1zcGlubmVyXCIpO3JldHVybiBlLmNsYXNzZXNbXCJ1aS1zcGlubmVyLXVwXCJdPVwiXCIsZS5jbGFzc2VzW1widWktc3Bpbm5lci1kb3duXCJdPVwiXCIsZX0sX2J1dHRvbk9wdGlvbnM6ZnVuY3Rpb24odCl7cmV0dXJuIHRoaXMuX2J1aWxkU2ltcGxlT3B0aW9ucyh0LFwidWktYnV0dG9uXCIpfSxfY2hlY2tib3hyYWRpb09wdGlvbnM6ZnVuY3Rpb24odCl7cmV0dXJuIHRoaXMuX2J1aWxkU2ltcGxlT3B0aW9ucyh0LFwidWktY2hlY2tib3hyYWRpby1sYWJlbFwiKX0sX3NlbGVjdG1lbnVPcHRpb25zOmZ1bmN0aW9uKHQpe3ZhciBlPVwidmVydGljYWxcIj09PXRoaXMub3B0aW9ucy5kaXJlY3Rpb247cmV0dXJue3dpZHRoOmU/XCJhdXRvXCI6ITEsY2xhc3Nlczp7bWlkZGxlOntcInVpLXNlbGVjdG1lbnUtYnV0dG9uLW9wZW5cIjpcIlwiLFwidWktc2VsZWN0bWVudS1idXR0b24tY2xvc2VkXCI6XCJcIn0sZmlyc3Q6e1widWktc2VsZWN0bWVudS1idXR0b24tb3BlblwiOlwidWktY29ybmVyLVwiKyhlP1widG9wXCI6XCJ0bFwiKSxcInVpLXNlbGVjdG1lbnUtYnV0dG9uLWNsb3NlZFwiOlwidWktY29ybmVyLVwiKyhlP1widG9wXCI6XCJsZWZ0XCIpfSxsYXN0OntcInVpLXNlbGVjdG1lbnUtYnV0dG9uLW9wZW5cIjplP1wiXCI6XCJ1aS1jb3JuZXItdHJcIixcInVpLXNlbGVjdG1lbnUtYnV0dG9uLWNsb3NlZFwiOlwidWktY29ybmVyLVwiKyhlP1wiYm90dG9tXCI6XCJyaWdodFwiKX0sb25seTp7XCJ1aS1zZWxlY3RtZW51LWJ1dHRvbi1vcGVuXCI6XCJ1aS1jb3JuZXItdG9wXCIsXCJ1aS1zZWxlY3RtZW51LWJ1dHRvbi1jbG9zZWRcIjpcInVpLWNvcm5lci1hbGxcIn19W3RdfX0sX3Jlc29sdmVDbGFzc2VzVmFsdWVzOmZ1bmN0aW9uKGUsaSl7dmFyIHM9e307cmV0dXJuIHQuZWFjaChlLGZ1bmN0aW9uKG4pe3ZhciBvPWkub3B0aW9ucy5jbGFzc2VzW25dfHxcIlwiO289dC50cmltKG8ucmVwbGFjZShkLFwiXCIpKSxzW25dPShvK1wiIFwiK2Vbbl0pLnJlcGxhY2UoL1xccysvZyxcIiBcIil9KSxzfSxfc2V0T3B0aW9uOmZ1bmN0aW9uKHQsZSl7cmV0dXJuXCJkaXJlY3Rpb25cIj09PXQmJnRoaXMuX3JlbW92ZUNsYXNzKFwidWktY29udHJvbGdyb3VwLVwiK3RoaXMub3B0aW9ucy5kaXJlY3Rpb24pLHRoaXMuX3N1cGVyKHQsZSksXCJkaXNhYmxlZFwiPT09dD8odGhpcy5fY2FsbENoaWxkTWV0aG9kKGU/XCJkaXNhYmxlXCI6XCJlbmFibGVcIiksdm9pZCAwKToodGhpcy5yZWZyZXNoKCksdm9pZCAwKX0scmVmcmVzaDpmdW5jdGlvbigpe3ZhciBlLGk9dGhpczt0aGlzLl9hZGRDbGFzcyhcInVpLWNvbnRyb2xncm91cCB1aS1jb250cm9sZ3JvdXAtXCIrdGhpcy5vcHRpb25zLmRpcmVjdGlvbiksXCJob3Jpem9udGFsXCI9PT10aGlzLm9wdGlvbnMuZGlyZWN0aW9uJiZ0aGlzLl9hZGRDbGFzcyhudWxsLFwidWktaGVscGVyLWNsZWFyZml4XCIpLHRoaXMuX2luaXRXaWRnZXRzKCksZT10aGlzLmNoaWxkV2lkZ2V0cyx0aGlzLm9wdGlvbnMub25seVZpc2libGUmJihlPWUuZmlsdGVyKFwiOnZpc2libGVcIikpLGUubGVuZ3RoJiYodC5lYWNoKFtcImZpcnN0XCIsXCJsYXN0XCJdLGZ1bmN0aW9uKHQscyl7dmFyIG49ZVtzXSgpLmRhdGEoXCJ1aS1jb250cm9sZ3JvdXAtZGF0YVwiKTtpZihuJiZpW1wiX1wiK24ud2lkZ2V0TmFtZStcIk9wdGlvbnNcIl0pe3ZhciBvPWlbXCJfXCIrbi53aWRnZXROYW1lK1wiT3B0aW9uc1wiXSgxPT09ZS5sZW5ndGg/XCJvbmx5XCI6cyk7by5jbGFzc2VzPWkuX3Jlc29sdmVDbGFzc2VzVmFsdWVzKG8uY2xhc3NlcyxuKSxuLmVsZW1lbnRbbi53aWRnZXROYW1lXShvKX1lbHNlIGkuX3VwZGF0ZUNvcm5lckNsYXNzKGVbc10oKSxzKX0pLHRoaXMuX2NhbGxDaGlsZE1ldGhvZChcInJlZnJlc2hcIikpfX0pLHQud2lkZ2V0KFwidWkuY2hlY2tib3hyYWRpb1wiLFt0LnVpLmZvcm1SZXNldE1peGluLHt2ZXJzaW9uOlwiMS4xMi4xXCIsb3B0aW9uczp7ZGlzYWJsZWQ6bnVsbCxsYWJlbDpudWxsLGljb246ITAsY2xhc3Nlczp7XCJ1aS1jaGVja2JveHJhZGlvLWxhYmVsXCI6XCJ1aS1jb3JuZXItYWxsXCIsXCJ1aS1jaGVja2JveHJhZGlvLWljb25cIjpcInVpLWNvcm5lci1hbGxcIn19LF9nZXRDcmVhdGVPcHRpb25zOmZ1bmN0aW9uKCl7dmFyIGUsaSxzPXRoaXMsbj10aGlzLl9zdXBlcigpfHx7fTtyZXR1cm4gdGhpcy5fcmVhZFR5cGUoKSxpPXRoaXMuZWxlbWVudC5sYWJlbHMoKSx0aGlzLmxhYmVsPXQoaVtpLmxlbmd0aC0xXSksdGhpcy5sYWJlbC5sZW5ndGh8fHQuZXJyb3IoXCJObyBsYWJlbCBmb3VuZCBmb3IgY2hlY2tib3hyYWRpbyB3aWRnZXRcIiksdGhpcy5vcmlnaW5hbExhYmVsPVwiXCIsdGhpcy5sYWJlbC5jb250ZW50cygpLm5vdCh0aGlzLmVsZW1lbnRbMF0pLmVhY2goZnVuY3Rpb24oKXtzLm9yaWdpbmFsTGFiZWwrPTM9PT10aGlzLm5vZGVUeXBlP3QodGhpcykudGV4dCgpOnRoaXMub3V0ZXJIVE1MfSksdGhpcy5vcmlnaW5hbExhYmVsJiYobi5sYWJlbD10aGlzLm9yaWdpbmFsTGFiZWwpLGU9dGhpcy5lbGVtZW50WzBdLmRpc2FibGVkLG51bGwhPWUmJihuLmRpc2FibGVkPWUpLG59LF9jcmVhdGU6ZnVuY3Rpb24oKXt2YXIgdD10aGlzLmVsZW1lbnRbMF0uY2hlY2tlZDt0aGlzLl9iaW5kRm9ybVJlc2V0SGFuZGxlcigpLG51bGw9PXRoaXMub3B0aW9ucy5kaXNhYmxlZCYmKHRoaXMub3B0aW9ucy5kaXNhYmxlZD10aGlzLmVsZW1lbnRbMF0uZGlzYWJsZWQpLHRoaXMuX3NldE9wdGlvbihcImRpc2FibGVkXCIsdGhpcy5vcHRpb25zLmRpc2FibGVkKSx0aGlzLl9hZGRDbGFzcyhcInVpLWNoZWNrYm94cmFkaW9cIixcInVpLWhlbHBlci1oaWRkZW4tYWNjZXNzaWJsZVwiKSx0aGlzLl9hZGRDbGFzcyh0aGlzLmxhYmVsLFwidWktY2hlY2tib3hyYWRpby1sYWJlbFwiLFwidWktYnV0dG9uIHVpLXdpZGdldFwiKSxcInJhZGlvXCI9PT10aGlzLnR5cGUmJnRoaXMuX2FkZENsYXNzKHRoaXMubGFiZWwsXCJ1aS1jaGVja2JveHJhZGlvLXJhZGlvLWxhYmVsXCIpLHRoaXMub3B0aW9ucy5sYWJlbCYmdGhpcy5vcHRpb25zLmxhYmVsIT09dGhpcy5vcmlnaW5hbExhYmVsP3RoaXMuX3VwZGF0ZUxhYmVsKCk6dGhpcy5vcmlnaW5hbExhYmVsJiYodGhpcy5vcHRpb25zLmxhYmVsPXRoaXMub3JpZ2luYWxMYWJlbCksdGhpcy5fZW5oYW5jZSgpLHQmJih0aGlzLl9hZGRDbGFzcyh0aGlzLmxhYmVsLFwidWktY2hlY2tib3hyYWRpby1jaGVja2VkXCIsXCJ1aS1zdGF0ZS1hY3RpdmVcIiksdGhpcy5pY29uJiZ0aGlzLl9hZGRDbGFzcyh0aGlzLmljb24sbnVsbCxcInVpLXN0YXRlLWhvdmVyXCIpKSx0aGlzLl9vbih7Y2hhbmdlOlwiX3RvZ2dsZUNsYXNzZXNcIixmb2N1czpmdW5jdGlvbigpe3RoaXMuX2FkZENsYXNzKHRoaXMubGFiZWwsbnVsbCxcInVpLXN0YXRlLWZvY3VzIHVpLXZpc3VhbC1mb2N1c1wiKX0sYmx1cjpmdW5jdGlvbigpe3RoaXMuX3JlbW92ZUNsYXNzKHRoaXMubGFiZWwsbnVsbCxcInVpLXN0YXRlLWZvY3VzIHVpLXZpc3VhbC1mb2N1c1wiKX19KX0sX3JlYWRUeXBlOmZ1bmN0aW9uKCl7dmFyIGU9dGhpcy5lbGVtZW50WzBdLm5vZGVOYW1lLnRvTG93ZXJDYXNlKCk7dGhpcy50eXBlPXRoaXMuZWxlbWVudFswXS50eXBlLFwiaW5wdXRcIj09PWUmJi9yYWRpb3xjaGVja2JveC8udGVzdCh0aGlzLnR5cGUpfHx0LmVycm9yKFwiQ2FuJ3QgY3JlYXRlIGNoZWNrYm94cmFkaW8gb24gZWxlbWVudC5ub2RlTmFtZT1cIitlK1wiIGFuZCBlbGVtZW50LnR5cGU9XCIrdGhpcy50eXBlKX0sX2VuaGFuY2U6ZnVuY3Rpb24oKXt0aGlzLl91cGRhdGVJY29uKHRoaXMuZWxlbWVudFswXS5jaGVja2VkKX0sd2lkZ2V0OmZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMubGFiZWx9LF9nZXRSYWRpb0dyb3VwOmZ1bmN0aW9uKCl7dmFyIGUsaT10aGlzLmVsZW1lbnRbMF0ubmFtZSxzPVwiaW5wdXRbbmFtZT0nXCIrdC51aS5lc2NhcGVTZWxlY3RvcihpKStcIiddXCI7cmV0dXJuIGk/KGU9dGhpcy5mb3JtLmxlbmd0aD90KHRoaXMuZm9ybVswXS5lbGVtZW50cykuZmlsdGVyKHMpOnQocykuZmlsdGVyKGZ1bmN0aW9uKCl7cmV0dXJuIDA9PT10KHRoaXMpLmZvcm0oKS5sZW5ndGh9KSxlLm5vdCh0aGlzLmVsZW1lbnQpKTp0KFtdKX0sX3RvZ2dsZUNsYXNzZXM6ZnVuY3Rpb24oKXt2YXIgZT10aGlzLmVsZW1lbnRbMF0uY2hlY2tlZDt0aGlzLl90b2dnbGVDbGFzcyh0aGlzLmxhYmVsLFwidWktY2hlY2tib3hyYWRpby1jaGVja2VkXCIsXCJ1aS1zdGF0ZS1hY3RpdmVcIixlKSx0aGlzLm9wdGlvbnMuaWNvbiYmXCJjaGVja2JveFwiPT09dGhpcy50eXBlJiZ0aGlzLl90b2dnbGVDbGFzcyh0aGlzLmljb24sbnVsbCxcInVpLWljb24tY2hlY2sgdWktc3RhdGUtY2hlY2tlZFwiLGUpLl90b2dnbGVDbGFzcyh0aGlzLmljb24sbnVsbCxcInVpLWljb24tYmxhbmtcIiwhZSksXCJyYWRpb1wiPT09dGhpcy50eXBlJiZ0aGlzLl9nZXRSYWRpb0dyb3VwKCkuZWFjaChmdW5jdGlvbigpe3ZhciBlPXQodGhpcykuY2hlY2tib3hyYWRpbyhcImluc3RhbmNlXCIpO2UmJmUuX3JlbW92ZUNsYXNzKGUubGFiZWwsXCJ1aS1jaGVja2JveHJhZGlvLWNoZWNrZWRcIixcInVpLXN0YXRlLWFjdGl2ZVwiKX0pfSxfZGVzdHJveTpmdW5jdGlvbigpe3RoaXMuX3VuYmluZEZvcm1SZXNldEhhbmRsZXIoKSx0aGlzLmljb24mJih0aGlzLmljb24ucmVtb3ZlKCksdGhpcy5pY29uU3BhY2UucmVtb3ZlKCkpfSxfc2V0T3B0aW9uOmZ1bmN0aW9uKHQsZSl7cmV0dXJuXCJsYWJlbFwiIT09dHx8ZT8odGhpcy5fc3VwZXIodCxlKSxcImRpc2FibGVkXCI9PT10Pyh0aGlzLl90b2dnbGVDbGFzcyh0aGlzLmxhYmVsLG51bGwsXCJ1aS1zdGF0ZS1kaXNhYmxlZFwiLGUpLHRoaXMuZWxlbWVudFswXS5kaXNhYmxlZD1lLHZvaWQgMCk6KHRoaXMucmVmcmVzaCgpLHZvaWQgMCkpOnZvaWQgMH0sX3VwZGF0ZUljb246ZnVuY3Rpb24oZSl7dmFyIGk9XCJ1aS1pY29uIHVpLWljb24tYmFja2dyb3VuZCBcIjt0aGlzLm9wdGlvbnMuaWNvbj8odGhpcy5pY29ufHwodGhpcy5pY29uPXQoXCI8c3Bhbj5cIiksdGhpcy5pY29uU3BhY2U9dChcIjxzcGFuPiA8L3NwYW4+XCIpLHRoaXMuX2FkZENsYXNzKHRoaXMuaWNvblNwYWNlLFwidWktY2hlY2tib3hyYWRpby1pY29uLXNwYWNlXCIpKSxcImNoZWNrYm94XCI9PT10aGlzLnR5cGU/KGkrPWU/XCJ1aS1pY29uLWNoZWNrIHVpLXN0YXRlLWNoZWNrZWRcIjpcInVpLWljb24tYmxhbmtcIix0aGlzLl9yZW1vdmVDbGFzcyh0aGlzLmljb24sbnVsbCxlP1widWktaWNvbi1ibGFua1wiOlwidWktaWNvbi1jaGVja1wiKSk6aSs9XCJ1aS1pY29uLWJsYW5rXCIsdGhpcy5fYWRkQ2xhc3ModGhpcy5pY29uLFwidWktY2hlY2tib3hyYWRpby1pY29uXCIsaSksZXx8dGhpcy5fcmVtb3ZlQ2xhc3ModGhpcy5pY29uLG51bGwsXCJ1aS1pY29uLWNoZWNrIHVpLXN0YXRlLWNoZWNrZWRcIiksdGhpcy5pY29uLnByZXBlbmRUbyh0aGlzLmxhYmVsKS5hZnRlcih0aGlzLmljb25TcGFjZSkpOnZvaWQgMCE9PXRoaXMuaWNvbiYmKHRoaXMuaWNvbi5yZW1vdmUoKSx0aGlzLmljb25TcGFjZS5yZW1vdmUoKSxkZWxldGUgdGhpcy5pY29uKVxufSxfdXBkYXRlTGFiZWw6ZnVuY3Rpb24oKXt2YXIgdD10aGlzLmxhYmVsLmNvbnRlbnRzKCkubm90KHRoaXMuZWxlbWVudFswXSk7dGhpcy5pY29uJiYodD10Lm5vdCh0aGlzLmljb25bMF0pKSx0aGlzLmljb25TcGFjZSYmKHQ9dC5ub3QodGhpcy5pY29uU3BhY2VbMF0pKSx0LnJlbW92ZSgpLHRoaXMubGFiZWwuYXBwZW5kKHRoaXMub3B0aW9ucy5sYWJlbCl9LHJlZnJlc2g6ZnVuY3Rpb24oKXt2YXIgdD10aGlzLmVsZW1lbnRbMF0uY2hlY2tlZCxlPXRoaXMuZWxlbWVudFswXS5kaXNhYmxlZDt0aGlzLl91cGRhdGVJY29uKHQpLHRoaXMuX3RvZ2dsZUNsYXNzKHRoaXMubGFiZWwsXCJ1aS1jaGVja2JveHJhZGlvLWNoZWNrZWRcIixcInVpLXN0YXRlLWFjdGl2ZVwiLHQpLG51bGwhPT10aGlzLm9wdGlvbnMubGFiZWwmJnRoaXMuX3VwZGF0ZUxhYmVsKCksZSE9PXRoaXMub3B0aW9ucy5kaXNhYmxlZCYmdGhpcy5fc2V0T3B0aW9ucyh7ZGlzYWJsZWQ6ZX0pfX1dKSx0LnVpLmNoZWNrYm94cmFkaW8sdC53aWRnZXQoXCJ1aS5idXR0b25cIix7dmVyc2lvbjpcIjEuMTIuMVwiLGRlZmF1bHRFbGVtZW50OlwiPGJ1dHRvbj5cIixvcHRpb25zOntjbGFzc2VzOntcInVpLWJ1dHRvblwiOlwidWktY29ybmVyLWFsbFwifSxkaXNhYmxlZDpudWxsLGljb246bnVsbCxpY29uUG9zaXRpb246XCJiZWdpbm5pbmdcIixsYWJlbDpudWxsLHNob3dMYWJlbDohMH0sX2dldENyZWF0ZU9wdGlvbnM6ZnVuY3Rpb24oKXt2YXIgdCxlPXRoaXMuX3N1cGVyKCl8fHt9O3JldHVybiB0aGlzLmlzSW5wdXQ9dGhpcy5lbGVtZW50LmlzKFwiaW5wdXRcIiksdD10aGlzLmVsZW1lbnRbMF0uZGlzYWJsZWQsbnVsbCE9dCYmKGUuZGlzYWJsZWQ9dCksdGhpcy5vcmlnaW5hbExhYmVsPXRoaXMuaXNJbnB1dD90aGlzLmVsZW1lbnQudmFsKCk6dGhpcy5lbGVtZW50Lmh0bWwoKSx0aGlzLm9yaWdpbmFsTGFiZWwmJihlLmxhYmVsPXRoaXMub3JpZ2luYWxMYWJlbCksZX0sX2NyZWF0ZTpmdW5jdGlvbigpeyF0aGlzLm9wdGlvbi5zaG93TGFiZWwmIXRoaXMub3B0aW9ucy5pY29uJiYodGhpcy5vcHRpb25zLnNob3dMYWJlbD0hMCksbnVsbD09dGhpcy5vcHRpb25zLmRpc2FibGVkJiYodGhpcy5vcHRpb25zLmRpc2FibGVkPXRoaXMuZWxlbWVudFswXS5kaXNhYmxlZHx8ITEpLHRoaXMuaGFzVGl0bGU9ISF0aGlzLmVsZW1lbnQuYXR0cihcInRpdGxlXCIpLHRoaXMub3B0aW9ucy5sYWJlbCYmdGhpcy5vcHRpb25zLmxhYmVsIT09dGhpcy5vcmlnaW5hbExhYmVsJiYodGhpcy5pc0lucHV0P3RoaXMuZWxlbWVudC52YWwodGhpcy5vcHRpb25zLmxhYmVsKTp0aGlzLmVsZW1lbnQuaHRtbCh0aGlzLm9wdGlvbnMubGFiZWwpKSx0aGlzLl9hZGRDbGFzcyhcInVpLWJ1dHRvblwiLFwidWktd2lkZ2V0XCIpLHRoaXMuX3NldE9wdGlvbihcImRpc2FibGVkXCIsdGhpcy5vcHRpb25zLmRpc2FibGVkKSx0aGlzLl9lbmhhbmNlKCksdGhpcy5lbGVtZW50LmlzKFwiYVwiKSYmdGhpcy5fb24oe2tleXVwOmZ1bmN0aW9uKGUpe2Uua2V5Q29kZT09PXQudWkua2V5Q29kZS5TUEFDRSYmKGUucHJldmVudERlZmF1bHQoKSx0aGlzLmVsZW1lbnRbMF0uY2xpY2s/dGhpcy5lbGVtZW50WzBdLmNsaWNrKCk6dGhpcy5lbGVtZW50LnRyaWdnZXIoXCJjbGlja1wiKSl9fSl9LF9lbmhhbmNlOmZ1bmN0aW9uKCl7dGhpcy5lbGVtZW50LmlzKFwiYnV0dG9uXCIpfHx0aGlzLmVsZW1lbnQuYXR0cihcInJvbGVcIixcImJ1dHRvblwiKSx0aGlzLm9wdGlvbnMuaWNvbiYmKHRoaXMuX3VwZGF0ZUljb24oXCJpY29uXCIsdGhpcy5vcHRpb25zLmljb24pLHRoaXMuX3VwZGF0ZVRvb2x0aXAoKSl9LF91cGRhdGVUb29sdGlwOmZ1bmN0aW9uKCl7dGhpcy50aXRsZT10aGlzLmVsZW1lbnQuYXR0cihcInRpdGxlXCIpLHRoaXMub3B0aW9ucy5zaG93TGFiZWx8fHRoaXMudGl0bGV8fHRoaXMuZWxlbWVudC5hdHRyKFwidGl0bGVcIix0aGlzLm9wdGlvbnMubGFiZWwpfSxfdXBkYXRlSWNvbjpmdW5jdGlvbihlLGkpe3ZhciBzPVwiaWNvblBvc2l0aW9uXCIhPT1lLG49cz90aGlzLm9wdGlvbnMuaWNvblBvc2l0aW9uOmksbz1cInRvcFwiPT09bnx8XCJib3R0b21cIj09PW47dGhpcy5pY29uP3MmJnRoaXMuX3JlbW92ZUNsYXNzKHRoaXMuaWNvbixudWxsLHRoaXMub3B0aW9ucy5pY29uKToodGhpcy5pY29uPXQoXCI8c3Bhbj5cIiksdGhpcy5fYWRkQ2xhc3ModGhpcy5pY29uLFwidWktYnV0dG9uLWljb25cIixcInVpLWljb25cIiksdGhpcy5vcHRpb25zLnNob3dMYWJlbHx8dGhpcy5fYWRkQ2xhc3MoXCJ1aS1idXR0b24taWNvbi1vbmx5XCIpKSxzJiZ0aGlzLl9hZGRDbGFzcyh0aGlzLmljb24sbnVsbCxpKSx0aGlzLl9hdHRhY2hJY29uKG4pLG8/KHRoaXMuX2FkZENsYXNzKHRoaXMuaWNvbixudWxsLFwidWktd2lkZ2V0LWljb24tYmxvY2tcIiksdGhpcy5pY29uU3BhY2UmJnRoaXMuaWNvblNwYWNlLnJlbW92ZSgpKToodGhpcy5pY29uU3BhY2V8fCh0aGlzLmljb25TcGFjZT10KFwiPHNwYW4+IDwvc3Bhbj5cIiksdGhpcy5fYWRkQ2xhc3ModGhpcy5pY29uU3BhY2UsXCJ1aS1idXR0b24taWNvbi1zcGFjZVwiKSksdGhpcy5fcmVtb3ZlQ2xhc3ModGhpcy5pY29uLG51bGwsXCJ1aS13aWdldC1pY29uLWJsb2NrXCIpLHRoaXMuX2F0dGFjaEljb25TcGFjZShuKSl9LF9kZXN0cm95OmZ1bmN0aW9uKCl7dGhpcy5lbGVtZW50LnJlbW92ZUF0dHIoXCJyb2xlXCIpLHRoaXMuaWNvbiYmdGhpcy5pY29uLnJlbW92ZSgpLHRoaXMuaWNvblNwYWNlJiZ0aGlzLmljb25TcGFjZS5yZW1vdmUoKSx0aGlzLmhhc1RpdGxlfHx0aGlzLmVsZW1lbnQucmVtb3ZlQXR0cihcInRpdGxlXCIpfSxfYXR0YWNoSWNvblNwYWNlOmZ1bmN0aW9uKHQpe3RoaXMuaWNvblsvXig/OmVuZHxib3R0b20pLy50ZXN0KHQpP1wiYmVmb3JlXCI6XCJhZnRlclwiXSh0aGlzLmljb25TcGFjZSl9LF9hdHRhY2hJY29uOmZ1bmN0aW9uKHQpe3RoaXMuZWxlbWVudFsvXig/OmVuZHxib3R0b20pLy50ZXN0KHQpP1wiYXBwZW5kXCI6XCJwcmVwZW5kXCJdKHRoaXMuaWNvbil9LF9zZXRPcHRpb25zOmZ1bmN0aW9uKHQpe3ZhciBlPXZvaWQgMD09PXQuc2hvd0xhYmVsP3RoaXMub3B0aW9ucy5zaG93TGFiZWw6dC5zaG93TGFiZWwsaT12b2lkIDA9PT10Lmljb24/dGhpcy5vcHRpb25zLmljb246dC5pY29uO2V8fGl8fCh0LnNob3dMYWJlbD0hMCksdGhpcy5fc3VwZXIodCl9LF9zZXRPcHRpb246ZnVuY3Rpb24odCxlKXtcImljb25cIj09PXQmJihlP3RoaXMuX3VwZGF0ZUljb24odCxlKTp0aGlzLmljb24mJih0aGlzLmljb24ucmVtb3ZlKCksdGhpcy5pY29uU3BhY2UmJnRoaXMuaWNvblNwYWNlLnJlbW92ZSgpKSksXCJpY29uUG9zaXRpb25cIj09PXQmJnRoaXMuX3VwZGF0ZUljb24odCxlKSxcInNob3dMYWJlbFwiPT09dCYmKHRoaXMuX3RvZ2dsZUNsYXNzKFwidWktYnV0dG9uLWljb24tb25seVwiLG51bGwsIWUpLHRoaXMuX3VwZGF0ZVRvb2x0aXAoKSksXCJsYWJlbFwiPT09dCYmKHRoaXMuaXNJbnB1dD90aGlzLmVsZW1lbnQudmFsKGUpOih0aGlzLmVsZW1lbnQuaHRtbChlKSx0aGlzLmljb24mJih0aGlzLl9hdHRhY2hJY29uKHRoaXMub3B0aW9ucy5pY29uUG9zaXRpb24pLHRoaXMuX2F0dGFjaEljb25TcGFjZSh0aGlzLm9wdGlvbnMuaWNvblBvc2l0aW9uKSkpKSx0aGlzLl9zdXBlcih0LGUpLFwiZGlzYWJsZWRcIj09PXQmJih0aGlzLl90b2dnbGVDbGFzcyhudWxsLFwidWktc3RhdGUtZGlzYWJsZWRcIixlKSx0aGlzLmVsZW1lbnRbMF0uZGlzYWJsZWQ9ZSxlJiZ0aGlzLmVsZW1lbnQuYmx1cigpKX0scmVmcmVzaDpmdW5jdGlvbigpe3ZhciB0PXRoaXMuZWxlbWVudC5pcyhcImlucHV0LCBidXR0b25cIik/dGhpcy5lbGVtZW50WzBdLmRpc2FibGVkOnRoaXMuZWxlbWVudC5oYXNDbGFzcyhcInVpLWJ1dHRvbi1kaXNhYmxlZFwiKTt0IT09dGhpcy5vcHRpb25zLmRpc2FibGVkJiZ0aGlzLl9zZXRPcHRpb25zKHtkaXNhYmxlZDp0fSksdGhpcy5fdXBkYXRlVG9vbHRpcCgpfX0pLHQudWlCYWNrQ29tcGF0IT09ITEmJih0LndpZGdldChcInVpLmJ1dHRvblwiLHQudWkuYnV0dG9uLHtvcHRpb25zOnt0ZXh0OiEwLGljb25zOntwcmltYXJ5Om51bGwsc2Vjb25kYXJ5Om51bGx9fSxfY3JlYXRlOmZ1bmN0aW9uKCl7dGhpcy5vcHRpb25zLnNob3dMYWJlbCYmIXRoaXMub3B0aW9ucy50ZXh0JiYodGhpcy5vcHRpb25zLnNob3dMYWJlbD10aGlzLm9wdGlvbnMudGV4dCksIXRoaXMub3B0aW9ucy5zaG93TGFiZWwmJnRoaXMub3B0aW9ucy50ZXh0JiYodGhpcy5vcHRpb25zLnRleHQ9dGhpcy5vcHRpb25zLnNob3dMYWJlbCksdGhpcy5vcHRpb25zLmljb258fCF0aGlzLm9wdGlvbnMuaWNvbnMucHJpbWFyeSYmIXRoaXMub3B0aW9ucy5pY29ucy5zZWNvbmRhcnk/dGhpcy5vcHRpb25zLmljb24mJih0aGlzLm9wdGlvbnMuaWNvbnMucHJpbWFyeT10aGlzLm9wdGlvbnMuaWNvbik6dGhpcy5vcHRpb25zLmljb25zLnByaW1hcnk/dGhpcy5vcHRpb25zLmljb249dGhpcy5vcHRpb25zLmljb25zLnByaW1hcnk6KHRoaXMub3B0aW9ucy5pY29uPXRoaXMub3B0aW9ucy5pY29ucy5zZWNvbmRhcnksdGhpcy5vcHRpb25zLmljb25Qb3NpdGlvbj1cImVuZFwiKSx0aGlzLl9zdXBlcigpfSxfc2V0T3B0aW9uOmZ1bmN0aW9uKHQsZSl7cmV0dXJuXCJ0ZXh0XCI9PT10Pyh0aGlzLl9zdXBlcihcInNob3dMYWJlbFwiLGUpLHZvaWQgMCk6KFwic2hvd0xhYmVsXCI9PT10JiYodGhpcy5vcHRpb25zLnRleHQ9ZSksXCJpY29uXCI9PT10JiYodGhpcy5vcHRpb25zLmljb25zLnByaW1hcnk9ZSksXCJpY29uc1wiPT09dCYmKGUucHJpbWFyeT8odGhpcy5fc3VwZXIoXCJpY29uXCIsZS5wcmltYXJ5KSx0aGlzLl9zdXBlcihcImljb25Qb3NpdGlvblwiLFwiYmVnaW5uaW5nXCIpKTplLnNlY29uZGFyeSYmKHRoaXMuX3N1cGVyKFwiaWNvblwiLGUuc2Vjb25kYXJ5KSx0aGlzLl9zdXBlcihcImljb25Qb3NpdGlvblwiLFwiZW5kXCIpKSksdGhpcy5fc3VwZXJBcHBseShhcmd1bWVudHMpLHZvaWQgMCl9fSksdC5mbi5idXR0b249ZnVuY3Rpb24oZSl7cmV0dXJuIGZ1bmN0aW9uKCl7cmV0dXJuIXRoaXMubGVuZ3RofHx0aGlzLmxlbmd0aCYmXCJJTlBVVFwiIT09dGhpc1swXS50YWdOYW1lfHx0aGlzLmxlbmd0aCYmXCJJTlBVVFwiPT09dGhpc1swXS50YWdOYW1lJiZcImNoZWNrYm94XCIhPT10aGlzLmF0dHIoXCJ0eXBlXCIpJiZcInJhZGlvXCIhPT10aGlzLmF0dHIoXCJ0eXBlXCIpP2UuYXBwbHkodGhpcyxhcmd1bWVudHMpOih0LnVpLmNoZWNrYm94cmFkaW98fHQuZXJyb3IoXCJDaGVja2JveHJhZGlvIHdpZGdldCBtaXNzaW5nXCIpLDA9PT1hcmd1bWVudHMubGVuZ3RoP3RoaXMuY2hlY2tib3hyYWRpbyh7aWNvbjohMX0pOnRoaXMuY2hlY2tib3hyYWRpby5hcHBseSh0aGlzLGFyZ3VtZW50cykpfX0odC5mbi5idXR0b24pLHQuZm4uYnV0dG9uc2V0PWZ1bmN0aW9uKCl7cmV0dXJuIHQudWkuY29udHJvbGdyb3VwfHx0LmVycm9yKFwiQ29udHJvbGdyb3VwIHdpZGdldCBtaXNzaW5nXCIpLFwib3B0aW9uXCI9PT1hcmd1bWVudHNbMF0mJlwiaXRlbXNcIj09PWFyZ3VtZW50c1sxXSYmYXJndW1lbnRzWzJdP3RoaXMuY29udHJvbGdyb3VwLmFwcGx5KHRoaXMsW2FyZ3VtZW50c1swXSxcIml0ZW1zLmJ1dHRvblwiLGFyZ3VtZW50c1syXV0pOlwib3B0aW9uXCI9PT1hcmd1bWVudHNbMF0mJlwiaXRlbXNcIj09PWFyZ3VtZW50c1sxXT90aGlzLmNvbnRyb2xncm91cC5hcHBseSh0aGlzLFthcmd1bWVudHNbMF0sXCJpdGVtcy5idXR0b25cIl0pOihcIm9iamVjdFwiPT10eXBlb2YgYXJndW1lbnRzWzBdJiZhcmd1bWVudHNbMF0uaXRlbXMmJihhcmd1bWVudHNbMF0uaXRlbXM9e2J1dHRvbjphcmd1bWVudHNbMF0uaXRlbXN9KSx0aGlzLmNvbnRyb2xncm91cC5hcHBseSh0aGlzLGFyZ3VtZW50cykpfSksdC51aS5idXR0b24sdC5leHRlbmQodC51aSx7ZGF0ZXBpY2tlcjp7dmVyc2lvbjpcIjEuMTIuMVwifX0pO3ZhciBwO3QuZXh0ZW5kKHMucHJvdG90eXBlLHttYXJrZXJDbGFzc05hbWU6XCJoYXNEYXRlcGlja2VyXCIsbWF4Um93czo0LF93aWRnZXREYXRlcGlja2VyOmZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMuZHBEaXZ9LHNldERlZmF1bHRzOmZ1bmN0aW9uKHQpe3JldHVybiBhKHRoaXMuX2RlZmF1bHRzLHR8fHt9KSx0aGlzfSxfYXR0YWNoRGF0ZXBpY2tlcjpmdW5jdGlvbihlLGkpe3ZhciBzLG4sbztzPWUubm9kZU5hbWUudG9Mb3dlckNhc2UoKSxuPVwiZGl2XCI9PT1zfHxcInNwYW5cIj09PXMsZS5pZHx8KHRoaXMudXVpZCs9MSxlLmlkPVwiZHBcIit0aGlzLnV1aWQpLG89dGhpcy5fbmV3SW5zdCh0KGUpLG4pLG8uc2V0dGluZ3M9dC5leHRlbmQoe30saXx8e30pLFwiaW5wdXRcIj09PXM/dGhpcy5fY29ubmVjdERhdGVwaWNrZXIoZSxvKTpuJiZ0aGlzLl9pbmxpbmVEYXRlcGlja2VyKGUsbyl9LF9uZXdJbnN0OmZ1bmN0aW9uKGUsaSl7dmFyIHM9ZVswXS5pZC5yZXBsYWNlKC8oW15BLVphLXowLTlfXFwtXSkvZyxcIlxcXFxcXFxcJDFcIik7cmV0dXJue2lkOnMsaW5wdXQ6ZSxzZWxlY3RlZERheTowLHNlbGVjdGVkTW9udGg6MCxzZWxlY3RlZFllYXI6MCxkcmF3TW9udGg6MCxkcmF3WWVhcjowLGlubGluZTppLGRwRGl2Omk/bih0KFwiPGRpdiBjbGFzcz0nXCIrdGhpcy5faW5saW5lQ2xhc3MrXCIgdWktZGF0ZXBpY2tlciB1aS13aWRnZXQgdWktd2lkZ2V0LWNvbnRlbnQgdWktaGVscGVyLWNsZWFyZml4IHVpLWNvcm5lci1hbGwnPjwvZGl2PlwiKSk6dGhpcy5kcERpdn19LF9jb25uZWN0RGF0ZXBpY2tlcjpmdW5jdGlvbihlLGkpe3ZhciBzPXQoZSk7aS5hcHBlbmQ9dChbXSksaS50cmlnZ2VyPXQoW10pLHMuaGFzQ2xhc3ModGhpcy5tYXJrZXJDbGFzc05hbWUpfHwodGhpcy5fYXR0YWNobWVudHMocyxpKSxzLmFkZENsYXNzKHRoaXMubWFya2VyQ2xhc3NOYW1lKS5vbihcImtleWRvd25cIix0aGlzLl9kb0tleURvd24pLm9uKFwia2V5cHJlc3NcIix0aGlzLl9kb0tleVByZXNzKS5vbihcImtleXVwXCIsdGhpcy5fZG9LZXlVcCksdGhpcy5fYXV0b1NpemUoaSksdC5kYXRhKGUsXCJkYXRlcGlja2VyXCIsaSksaS5zZXR0aW5ncy5kaXNhYmxlZCYmdGhpcy5fZGlzYWJsZURhdGVwaWNrZXIoZSkpfSxfYXR0YWNobWVudHM6ZnVuY3Rpb24oZSxpKXt2YXIgcyxuLG8sYT10aGlzLl9nZXQoaSxcImFwcGVuZFRleHRcIikscj10aGlzLl9nZXQoaSxcImlzUlRMXCIpO2kuYXBwZW5kJiZpLmFwcGVuZC5yZW1vdmUoKSxhJiYoaS5hcHBlbmQ9dChcIjxzcGFuIGNsYXNzPSdcIit0aGlzLl9hcHBlbmRDbGFzcytcIic+XCIrYStcIjwvc3Bhbj5cIiksZVtyP1wiYmVmb3JlXCI6XCJhZnRlclwiXShpLmFwcGVuZCkpLGUub2ZmKFwiZm9jdXNcIix0aGlzLl9zaG93RGF0ZXBpY2tlciksaS50cmlnZ2VyJiZpLnRyaWdnZXIucmVtb3ZlKCkscz10aGlzLl9nZXQoaSxcInNob3dPblwiKSwoXCJmb2N1c1wiPT09c3x8XCJib3RoXCI9PT1zKSYmZS5vbihcImZvY3VzXCIsdGhpcy5fc2hvd0RhdGVwaWNrZXIpLChcImJ1dHRvblwiPT09c3x8XCJib3RoXCI9PT1zKSYmKG49dGhpcy5fZ2V0KGksXCJidXR0b25UZXh0XCIpLG89dGhpcy5fZ2V0KGksXCJidXR0b25JbWFnZVwiKSxpLnRyaWdnZXI9dCh0aGlzLl9nZXQoaSxcImJ1dHRvbkltYWdlT25seVwiKT90KFwiPGltZy8+XCIpLmFkZENsYXNzKHRoaXMuX3RyaWdnZXJDbGFzcykuYXR0cih7c3JjOm8sYWx0Om4sdGl0bGU6bn0pOnQoXCI8YnV0dG9uIHR5cGU9J2J1dHRvbic+PC9idXR0b24+XCIpLmFkZENsYXNzKHRoaXMuX3RyaWdnZXJDbGFzcykuaHRtbChvP3QoXCI8aW1nLz5cIikuYXR0cih7c3JjOm8sYWx0Om4sdGl0bGU6bn0pOm4pKSxlW3I/XCJiZWZvcmVcIjpcImFmdGVyXCJdKGkudHJpZ2dlciksaS50cmlnZ2VyLm9uKFwiY2xpY2tcIixmdW5jdGlvbigpe3JldHVybiB0LmRhdGVwaWNrZXIuX2RhdGVwaWNrZXJTaG93aW5nJiZ0LmRhdGVwaWNrZXIuX2xhc3RJbnB1dD09PWVbMF0/dC5kYXRlcGlja2VyLl9oaWRlRGF0ZXBpY2tlcigpOnQuZGF0ZXBpY2tlci5fZGF0ZXBpY2tlclNob3dpbmcmJnQuZGF0ZXBpY2tlci5fbGFzdElucHV0IT09ZVswXT8odC5kYXRlcGlja2VyLl9oaWRlRGF0ZXBpY2tlcigpLHQuZGF0ZXBpY2tlci5fc2hvd0RhdGVwaWNrZXIoZVswXSkpOnQuZGF0ZXBpY2tlci5fc2hvd0RhdGVwaWNrZXIoZVswXSksITF9KSl9LF9hdXRvU2l6ZTpmdW5jdGlvbih0KXtpZih0aGlzLl9nZXQodCxcImF1dG9TaXplXCIpJiYhdC5pbmxpbmUpe3ZhciBlLGkscyxuLG89bmV3IERhdGUoMjAwOSwxMSwyMCksYT10aGlzLl9nZXQodCxcImRhdGVGb3JtYXRcIik7YS5tYXRjaCgvW0RNXS8pJiYoZT1mdW5jdGlvbih0KXtmb3IoaT0wLHM9MCxuPTA7dC5sZW5ndGg+bjtuKyspdFtuXS5sZW5ndGg+aSYmKGk9dFtuXS5sZW5ndGgscz1uKTtyZXR1cm4gc30sby5zZXRNb250aChlKHRoaXMuX2dldCh0LGEubWF0Y2goL01NLyk/XCJtb250aE5hbWVzXCI6XCJtb250aE5hbWVzU2hvcnRcIikpKSxvLnNldERhdGUoZSh0aGlzLl9nZXQodCxhLm1hdGNoKC9ERC8pP1wiZGF5TmFtZXNcIjpcImRheU5hbWVzU2hvcnRcIikpKzIwLW8uZ2V0RGF5KCkpKSx0LmlucHV0LmF0dHIoXCJzaXplXCIsdGhpcy5fZm9ybWF0RGF0ZSh0LG8pLmxlbmd0aCl9fSxfaW5saW5lRGF0ZXBpY2tlcjpmdW5jdGlvbihlLGkpe3ZhciBzPXQoZSk7cy5oYXNDbGFzcyh0aGlzLm1hcmtlckNsYXNzTmFtZSl8fChzLmFkZENsYXNzKHRoaXMubWFya2VyQ2xhc3NOYW1lKS5hcHBlbmQoaS5kcERpdiksdC5kYXRhKGUsXCJkYXRlcGlja2VyXCIsaSksdGhpcy5fc2V0RGF0ZShpLHRoaXMuX2dldERlZmF1bHREYXRlKGkpLCEwKSx0aGlzLl91cGRhdGVEYXRlcGlja2VyKGkpLHRoaXMuX3VwZGF0ZUFsdGVybmF0ZShpKSxpLnNldHRpbmdzLmRpc2FibGVkJiZ0aGlzLl9kaXNhYmxlRGF0ZXBpY2tlcihlKSxpLmRwRGl2LmNzcyhcImRpc3BsYXlcIixcImJsb2NrXCIpKX0sX2RpYWxvZ0RhdGVwaWNrZXI6ZnVuY3Rpb24oZSxpLHMsbixvKXt2YXIgcixoLGwsYyx1LGQ9dGhpcy5fZGlhbG9nSW5zdDtyZXR1cm4gZHx8KHRoaXMudXVpZCs9MSxyPVwiZHBcIit0aGlzLnV1aWQsdGhpcy5fZGlhbG9nSW5wdXQ9dChcIjxpbnB1dCB0eXBlPSd0ZXh0JyBpZD0nXCIrcitcIicgc3R5bGU9J3Bvc2l0aW9uOiBhYnNvbHV0ZTsgdG9wOiAtMTAwcHg7IHdpZHRoOiAwcHg7Jy8+XCIpLHRoaXMuX2RpYWxvZ0lucHV0Lm9uKFwia2V5ZG93blwiLHRoaXMuX2RvS2V5RG93biksdChcImJvZHlcIikuYXBwZW5kKHRoaXMuX2RpYWxvZ0lucHV0KSxkPXRoaXMuX2RpYWxvZ0luc3Q9dGhpcy5fbmV3SW5zdCh0aGlzLl9kaWFsb2dJbnB1dCwhMSksZC5zZXR0aW5ncz17fSx0LmRhdGEodGhpcy5fZGlhbG9nSW5wdXRbMF0sXCJkYXRlcGlja2VyXCIsZCkpLGEoZC5zZXR0aW5ncyxufHx7fSksaT1pJiZpLmNvbnN0cnVjdG9yPT09RGF0ZT90aGlzLl9mb3JtYXREYXRlKGQsaSk6aSx0aGlzLl9kaWFsb2dJbnB1dC52YWwoaSksdGhpcy5fcG9zPW8/by5sZW5ndGg/bzpbby5wYWdlWCxvLnBhZ2VZXTpudWxsLHRoaXMuX3Bvc3x8KGg9ZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LmNsaWVudFdpZHRoLGw9ZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LmNsaWVudEhlaWdodCxjPWRvY3VtZW50LmRvY3VtZW50RWxlbWVudC5zY3JvbGxMZWZ0fHxkb2N1bWVudC5ib2R5LnNjcm9sbExlZnQsdT1kb2N1bWVudC5kb2N1bWVudEVsZW1lbnQuc2Nyb2xsVG9wfHxkb2N1bWVudC5ib2R5LnNjcm9sbFRvcCx0aGlzLl9wb3M9W2gvMi0xMDArYyxsLzItMTUwK3VdKSx0aGlzLl9kaWFsb2dJbnB1dC5jc3MoXCJsZWZ0XCIsdGhpcy5fcG9zWzBdKzIwK1wicHhcIikuY3NzKFwidG9wXCIsdGhpcy5fcG9zWzFdK1wicHhcIiksZC5zZXR0aW5ncy5vblNlbGVjdD1zLHRoaXMuX2luRGlhbG9nPSEwLHRoaXMuZHBEaXYuYWRkQ2xhc3ModGhpcy5fZGlhbG9nQ2xhc3MpLHRoaXMuX3Nob3dEYXRlcGlja2VyKHRoaXMuX2RpYWxvZ0lucHV0WzBdKSx0LmJsb2NrVUkmJnQuYmxvY2tVSSh0aGlzLmRwRGl2KSx0LmRhdGEodGhpcy5fZGlhbG9nSW5wdXRbMF0sXCJkYXRlcGlja2VyXCIsZCksdGhpc30sX2Rlc3Ryb3lEYXRlcGlja2VyOmZ1bmN0aW9uKGUpe3ZhciBpLHM9dChlKSxuPXQuZGF0YShlLFwiZGF0ZXBpY2tlclwiKTtzLmhhc0NsYXNzKHRoaXMubWFya2VyQ2xhc3NOYW1lKSYmKGk9ZS5ub2RlTmFtZS50b0xvd2VyQ2FzZSgpLHQucmVtb3ZlRGF0YShlLFwiZGF0ZXBpY2tlclwiKSxcImlucHV0XCI9PT1pPyhuLmFwcGVuZC5yZW1vdmUoKSxuLnRyaWdnZXIucmVtb3ZlKCkscy5yZW1vdmVDbGFzcyh0aGlzLm1hcmtlckNsYXNzTmFtZSkub2ZmKFwiZm9jdXNcIix0aGlzLl9zaG93RGF0ZXBpY2tlcikub2ZmKFwia2V5ZG93blwiLHRoaXMuX2RvS2V5RG93bikub2ZmKFwia2V5cHJlc3NcIix0aGlzLl9kb0tleVByZXNzKS5vZmYoXCJrZXl1cFwiLHRoaXMuX2RvS2V5VXApKTooXCJkaXZcIj09PWl8fFwic3BhblwiPT09aSkmJnMucmVtb3ZlQ2xhc3ModGhpcy5tYXJrZXJDbGFzc05hbWUpLmVtcHR5KCkscD09PW4mJihwPW51bGwpKX0sX2VuYWJsZURhdGVwaWNrZXI6ZnVuY3Rpb24oZSl7dmFyIGkscyxuPXQoZSksbz10LmRhdGEoZSxcImRhdGVwaWNrZXJcIik7bi5oYXNDbGFzcyh0aGlzLm1hcmtlckNsYXNzTmFtZSkmJihpPWUubm9kZU5hbWUudG9Mb3dlckNhc2UoKSxcImlucHV0XCI9PT1pPyhlLmRpc2FibGVkPSExLG8udHJpZ2dlci5maWx0ZXIoXCJidXR0b25cIikuZWFjaChmdW5jdGlvbigpe3RoaXMuZGlzYWJsZWQ9ITF9KS5lbmQoKS5maWx0ZXIoXCJpbWdcIikuY3NzKHtvcGFjaXR5OlwiMS4wXCIsY3Vyc29yOlwiXCJ9KSk6KFwiZGl2XCI9PT1pfHxcInNwYW5cIj09PWkpJiYocz1uLmNoaWxkcmVuKFwiLlwiK3RoaXMuX2lubGluZUNsYXNzKSxzLmNoaWxkcmVuKCkucmVtb3ZlQ2xhc3MoXCJ1aS1zdGF0ZS1kaXNhYmxlZFwiKSxzLmZpbmQoXCJzZWxlY3QudWktZGF0ZXBpY2tlci1tb250aCwgc2VsZWN0LnVpLWRhdGVwaWNrZXIteWVhclwiKS5wcm9wKFwiZGlzYWJsZWRcIiwhMSkpLHRoaXMuX2Rpc2FibGVkSW5wdXRzPXQubWFwKHRoaXMuX2Rpc2FibGVkSW5wdXRzLGZ1bmN0aW9uKHQpe3JldHVybiB0PT09ZT9udWxsOnR9KSl9LF9kaXNhYmxlRGF0ZXBpY2tlcjpmdW5jdGlvbihlKXt2YXIgaSxzLG49dChlKSxvPXQuZGF0YShlLFwiZGF0ZXBpY2tlclwiKTtuLmhhc0NsYXNzKHRoaXMubWFya2VyQ2xhc3NOYW1lKSYmKGk9ZS5ub2RlTmFtZS50b0xvd2VyQ2FzZSgpLFwiaW5wdXRcIj09PWk/KGUuZGlzYWJsZWQ9ITAsby50cmlnZ2VyLmZpbHRlcihcImJ1dHRvblwiKS5lYWNoKGZ1bmN0aW9uKCl7dGhpcy5kaXNhYmxlZD0hMH0pLmVuZCgpLmZpbHRlcihcImltZ1wiKS5jc3Moe29wYWNpdHk6XCIwLjVcIixjdXJzb3I6XCJkZWZhdWx0XCJ9KSk6KFwiZGl2XCI9PT1pfHxcInNwYW5cIj09PWkpJiYocz1uLmNoaWxkcmVuKFwiLlwiK3RoaXMuX2lubGluZUNsYXNzKSxzLmNoaWxkcmVuKCkuYWRkQ2xhc3MoXCJ1aS1zdGF0ZS1kaXNhYmxlZFwiKSxzLmZpbmQoXCJzZWxlY3QudWktZGF0ZXBpY2tlci1tb250aCwgc2VsZWN0LnVpLWRhdGVwaWNrZXIteWVhclwiKS5wcm9wKFwiZGlzYWJsZWRcIiwhMCkpLHRoaXMuX2Rpc2FibGVkSW5wdXRzPXQubWFwKHRoaXMuX2Rpc2FibGVkSW5wdXRzLGZ1bmN0aW9uKHQpe3JldHVybiB0PT09ZT9udWxsOnR9KSx0aGlzLl9kaXNhYmxlZElucHV0c1t0aGlzLl9kaXNhYmxlZElucHV0cy5sZW5ndGhdPWUpfSxfaXNEaXNhYmxlZERhdGVwaWNrZXI6ZnVuY3Rpb24odCl7aWYoIXQpcmV0dXJuITE7Zm9yKHZhciBlPTA7dGhpcy5fZGlzYWJsZWRJbnB1dHMubGVuZ3RoPmU7ZSsrKWlmKHRoaXMuX2Rpc2FibGVkSW5wdXRzW2VdPT09dClyZXR1cm4hMDtyZXR1cm4hMX0sX2dldEluc3Q6ZnVuY3Rpb24oZSl7dHJ5e3JldHVybiB0LmRhdGEoZSxcImRhdGVwaWNrZXJcIil9Y2F0Y2goaSl7dGhyb3dcIk1pc3NpbmcgaW5zdGFuY2UgZGF0YSBmb3IgdGhpcyBkYXRlcGlja2VyXCJ9fSxfb3B0aW9uRGF0ZXBpY2tlcjpmdW5jdGlvbihlLGkscyl7dmFyIG4sbyxyLGgsbD10aGlzLl9nZXRJbnN0KGUpO3JldHVybiAyPT09YXJndW1lbnRzLmxlbmd0aCYmXCJzdHJpbmdcIj09dHlwZW9mIGk/XCJkZWZhdWx0c1wiPT09aT90LmV4dGVuZCh7fSx0LmRhdGVwaWNrZXIuX2RlZmF1bHRzKTpsP1wiYWxsXCI9PT1pP3QuZXh0ZW5kKHt9LGwuc2V0dGluZ3MpOnRoaXMuX2dldChsLGkpOm51bGw6KG49aXx8e30sXCJzdHJpbmdcIj09dHlwZW9mIGkmJihuPXt9LG5baV09cyksbCYmKHRoaXMuX2N1ckluc3Q9PT1sJiZ0aGlzLl9oaWRlRGF0ZXBpY2tlcigpLG89dGhpcy5fZ2V0RGF0ZURhdGVwaWNrZXIoZSwhMCkscj10aGlzLl9nZXRNaW5NYXhEYXRlKGwsXCJtaW5cIiksaD10aGlzLl9nZXRNaW5NYXhEYXRlKGwsXCJtYXhcIiksYShsLnNldHRpbmdzLG4pLG51bGwhPT1yJiZ2b2lkIDAhPT1uLmRhdGVGb3JtYXQmJnZvaWQgMD09PW4ubWluRGF0ZSYmKGwuc2V0dGluZ3MubWluRGF0ZT10aGlzLl9mb3JtYXREYXRlKGwscikpLG51bGwhPT1oJiZ2b2lkIDAhPT1uLmRhdGVGb3JtYXQmJnZvaWQgMD09PW4ubWF4RGF0ZSYmKGwuc2V0dGluZ3MubWF4RGF0ZT10aGlzLl9mb3JtYXREYXRlKGwsaCkpLFwiZGlzYWJsZWRcImluIG4mJihuLmRpc2FibGVkP3RoaXMuX2Rpc2FibGVEYXRlcGlja2VyKGUpOnRoaXMuX2VuYWJsZURhdGVwaWNrZXIoZSkpLHRoaXMuX2F0dGFjaG1lbnRzKHQoZSksbCksdGhpcy5fYXV0b1NpemUobCksdGhpcy5fc2V0RGF0ZShsLG8pLHRoaXMuX3VwZGF0ZUFsdGVybmF0ZShsKSx0aGlzLl91cGRhdGVEYXRlcGlja2VyKGwpKSx2b2lkIDApfSxfY2hhbmdlRGF0ZXBpY2tlcjpmdW5jdGlvbih0LGUsaSl7dGhpcy5fb3B0aW9uRGF0ZXBpY2tlcih0LGUsaSl9LF9yZWZyZXNoRGF0ZXBpY2tlcjpmdW5jdGlvbih0KXt2YXIgZT10aGlzLl9nZXRJbnN0KHQpO2UmJnRoaXMuX3VwZGF0ZURhdGVwaWNrZXIoZSl9LF9zZXREYXRlRGF0ZXBpY2tlcjpmdW5jdGlvbih0LGUpe3ZhciBpPXRoaXMuX2dldEluc3QodCk7aSYmKHRoaXMuX3NldERhdGUoaSxlKSx0aGlzLl91cGRhdGVEYXRlcGlja2VyKGkpLHRoaXMuX3VwZGF0ZUFsdGVybmF0ZShpKSl9LF9nZXREYXRlRGF0ZXBpY2tlcjpmdW5jdGlvbih0LGUpe3ZhciBpPXRoaXMuX2dldEluc3QodCk7cmV0dXJuIGkmJiFpLmlubGluZSYmdGhpcy5fc2V0RGF0ZUZyb21GaWVsZChpLGUpLGk/dGhpcy5fZ2V0RGF0ZShpKTpudWxsfSxfZG9LZXlEb3duOmZ1bmN0aW9uKGUpe3ZhciBpLHMsbixvPXQuZGF0ZXBpY2tlci5fZ2V0SW5zdChlLnRhcmdldCksYT0hMCxyPW8uZHBEaXYuaXMoXCIudWktZGF0ZXBpY2tlci1ydGxcIik7aWYoby5fa2V5RXZlbnQ9ITAsdC5kYXRlcGlja2VyLl9kYXRlcGlja2VyU2hvd2luZylzd2l0Y2goZS5rZXlDb2RlKXtjYXNlIDk6dC5kYXRlcGlja2VyLl9oaWRlRGF0ZXBpY2tlcigpLGE9ITE7YnJlYWs7Y2FzZSAxMzpyZXR1cm4gbj10KFwidGQuXCIrdC5kYXRlcGlja2VyLl9kYXlPdmVyQ2xhc3MrXCI6bm90KC5cIit0LmRhdGVwaWNrZXIuX2N1cnJlbnRDbGFzcytcIilcIixvLmRwRGl2KSxuWzBdJiZ0LmRhdGVwaWNrZXIuX3NlbGVjdERheShlLnRhcmdldCxvLnNlbGVjdGVkTW9udGgsby5zZWxlY3RlZFllYXIsblswXSksaT10LmRhdGVwaWNrZXIuX2dldChvLFwib25TZWxlY3RcIiksaT8ocz10LmRhdGVwaWNrZXIuX2Zvcm1hdERhdGUobyksaS5hcHBseShvLmlucHV0P28uaW5wdXRbMF06bnVsbCxbcyxvXSkpOnQuZGF0ZXBpY2tlci5faGlkZURhdGVwaWNrZXIoKSwhMTtjYXNlIDI3OnQuZGF0ZXBpY2tlci5faGlkZURhdGVwaWNrZXIoKTticmVhaztjYXNlIDMzOnQuZGF0ZXBpY2tlci5fYWRqdXN0RGF0ZShlLnRhcmdldCxlLmN0cmxLZXk/LXQuZGF0ZXBpY2tlci5fZ2V0KG8sXCJzdGVwQmlnTW9udGhzXCIpOi10LmRhdGVwaWNrZXIuX2dldChvLFwic3RlcE1vbnRoc1wiKSxcIk1cIik7YnJlYWs7Y2FzZSAzNDp0LmRhdGVwaWNrZXIuX2FkanVzdERhdGUoZS50YXJnZXQsZS5jdHJsS2V5Pyt0LmRhdGVwaWNrZXIuX2dldChvLFwic3RlcEJpZ01vbnRoc1wiKTordC5kYXRlcGlja2VyLl9nZXQobyxcInN0ZXBNb250aHNcIiksXCJNXCIpO2JyZWFrO2Nhc2UgMzU6KGUuY3RybEtleXx8ZS5tZXRhS2V5KSYmdC5kYXRlcGlja2VyLl9jbGVhckRhdGUoZS50YXJnZXQpLGE9ZS5jdHJsS2V5fHxlLm1ldGFLZXk7YnJlYWs7Y2FzZSAzNjooZS5jdHJsS2V5fHxlLm1ldGFLZXkpJiZ0LmRhdGVwaWNrZXIuX2dvdG9Ub2RheShlLnRhcmdldCksYT1lLmN0cmxLZXl8fGUubWV0YUtleTticmVhaztjYXNlIDM3OihlLmN0cmxLZXl8fGUubWV0YUtleSkmJnQuZGF0ZXBpY2tlci5fYWRqdXN0RGF0ZShlLnRhcmdldCxyPzE6LTEsXCJEXCIpLGE9ZS5jdHJsS2V5fHxlLm1ldGFLZXksZS5vcmlnaW5hbEV2ZW50LmFsdEtleSYmdC5kYXRlcGlja2VyLl9hZGp1c3REYXRlKGUudGFyZ2V0LGUuY3RybEtleT8tdC5kYXRlcGlja2VyLl9nZXQobyxcInN0ZXBCaWdNb250aHNcIik6LXQuZGF0ZXBpY2tlci5fZ2V0KG8sXCJzdGVwTW9udGhzXCIpLFwiTVwiKTticmVhaztjYXNlIDM4OihlLmN0cmxLZXl8fGUubWV0YUtleSkmJnQuZGF0ZXBpY2tlci5fYWRqdXN0RGF0ZShlLnRhcmdldCwtNyxcIkRcIiksYT1lLmN0cmxLZXl8fGUubWV0YUtleTticmVhaztjYXNlIDM5OihlLmN0cmxLZXl8fGUubWV0YUtleSkmJnQuZGF0ZXBpY2tlci5fYWRqdXN0RGF0ZShlLnRhcmdldCxyPy0xOjEsXCJEXCIpLGE9ZS5jdHJsS2V5fHxlLm1ldGFLZXksZS5vcmlnaW5hbEV2ZW50LmFsdEtleSYmdC5kYXRlcGlja2VyLl9hZGp1c3REYXRlKGUudGFyZ2V0LGUuY3RybEtleT8rdC5kYXRlcGlja2VyLl9nZXQobyxcInN0ZXBCaWdNb250aHNcIik6K3QuZGF0ZXBpY2tlci5fZ2V0KG8sXCJzdGVwTW9udGhzXCIpLFwiTVwiKTticmVhaztjYXNlIDQwOihlLmN0cmxLZXl8fGUubWV0YUtleSkmJnQuZGF0ZXBpY2tlci5fYWRqdXN0RGF0ZShlLnRhcmdldCw3LFwiRFwiKSxhPWUuY3RybEtleXx8ZS5tZXRhS2V5O2JyZWFrO2RlZmF1bHQ6YT0hMX1lbHNlIDM2PT09ZS5rZXlDb2RlJiZlLmN0cmxLZXk/dC5kYXRlcGlja2VyLl9zaG93RGF0ZXBpY2tlcih0aGlzKTphPSExO2EmJihlLnByZXZlbnREZWZhdWx0KCksZS5zdG9wUHJvcGFnYXRpb24oKSl9LF9kb0tleVByZXNzOmZ1bmN0aW9uKGUpe3ZhciBpLHMsbj10LmRhdGVwaWNrZXIuX2dldEluc3QoZS50YXJnZXQpO3JldHVybiB0LmRhdGVwaWNrZXIuX2dldChuLFwiY29uc3RyYWluSW5wdXRcIik/KGk9dC5kYXRlcGlja2VyLl9wb3NzaWJsZUNoYXJzKHQuZGF0ZXBpY2tlci5fZ2V0KG4sXCJkYXRlRm9ybWF0XCIpKSxzPVN0cmluZy5mcm9tQ2hhckNvZGUobnVsbD09ZS5jaGFyQ29kZT9lLmtleUNvZGU6ZS5jaGFyQ29kZSksZS5jdHJsS2V5fHxlLm1ldGFLZXl8fFwiIFwiPnN8fCFpfHxpLmluZGV4T2Yocyk+LTEpOnZvaWQgMH0sX2RvS2V5VXA6ZnVuY3Rpb24oZSl7dmFyIGkscz10LmRhdGVwaWNrZXIuX2dldEluc3QoZS50YXJnZXQpO2lmKHMuaW5wdXQudmFsKCkhPT1zLmxhc3RWYWwpdHJ5e2k9dC5kYXRlcGlja2VyLnBhcnNlRGF0ZSh0LmRhdGVwaWNrZXIuX2dldChzLFwiZGF0ZUZvcm1hdFwiKSxzLmlucHV0P3MuaW5wdXQudmFsKCk6bnVsbCx0LmRhdGVwaWNrZXIuX2dldEZvcm1hdENvbmZpZyhzKSksaSYmKHQuZGF0ZXBpY2tlci5fc2V0RGF0ZUZyb21GaWVsZChzKSx0LmRhdGVwaWNrZXIuX3VwZGF0ZUFsdGVybmF0ZShzKSx0LmRhdGVwaWNrZXIuX3VwZGF0ZURhdGVwaWNrZXIocykpfWNhdGNoKG4pe31yZXR1cm4hMH0sX3Nob3dEYXRlcGlja2VyOmZ1bmN0aW9uKGUpe2lmKGU9ZS50YXJnZXR8fGUsXCJpbnB1dFwiIT09ZS5ub2RlTmFtZS50b0xvd2VyQ2FzZSgpJiYoZT10KFwiaW5wdXRcIixlLnBhcmVudE5vZGUpWzBdKSwhdC5kYXRlcGlja2VyLl9pc0Rpc2FibGVkRGF0ZXBpY2tlcihlKSYmdC5kYXRlcGlja2VyLl9sYXN0SW5wdXQhPT1lKXt2YXIgcyxuLG8scixoLGwsYztzPXQuZGF0ZXBpY2tlci5fZ2V0SW5zdChlKSx0LmRhdGVwaWNrZXIuX2N1ckluc3QmJnQuZGF0ZXBpY2tlci5fY3VySW5zdCE9PXMmJih0LmRhdGVwaWNrZXIuX2N1ckluc3QuZHBEaXYuc3RvcCghMCwhMCkscyYmdC5kYXRlcGlja2VyLl9kYXRlcGlja2VyU2hvd2luZyYmdC5kYXRlcGlja2VyLl9oaWRlRGF0ZXBpY2tlcih0LmRhdGVwaWNrZXIuX2N1ckluc3QuaW5wdXRbMF0pKSxuPXQuZGF0ZXBpY2tlci5fZ2V0KHMsXCJiZWZvcmVTaG93XCIpLG89bj9uLmFwcGx5KGUsW2Usc10pOnt9LG8hPT0hMSYmKGEocy5zZXR0aW5ncyxvKSxzLmxhc3RWYWw9bnVsbCx0LmRhdGVwaWNrZXIuX2xhc3RJbnB1dD1lLHQuZGF0ZXBpY2tlci5fc2V0RGF0ZUZyb21GaWVsZChzKSx0LmRhdGVwaWNrZXIuX2luRGlhbG9nJiYoZS52YWx1ZT1cIlwiKSx0LmRhdGVwaWNrZXIuX3Bvc3x8KHQuZGF0ZXBpY2tlci5fcG9zPXQuZGF0ZXBpY2tlci5fZmluZFBvcyhlKSx0LmRhdGVwaWNrZXIuX3Bvc1sxXSs9ZS5vZmZzZXRIZWlnaHQpLHI9ITEsdChlKS5wYXJlbnRzKCkuZWFjaChmdW5jdGlvbigpe3JldHVybiByfD1cImZpeGVkXCI9PT10KHRoaXMpLmNzcyhcInBvc2l0aW9uXCIpLCFyfSksaD17bGVmdDp0LmRhdGVwaWNrZXIuX3Bvc1swXSx0b3A6dC5kYXRlcGlja2VyLl9wb3NbMV19LHQuZGF0ZXBpY2tlci5fcG9zPW51bGwscy5kcERpdi5lbXB0eSgpLHMuZHBEaXYuY3NzKHtwb3NpdGlvbjpcImFic29sdXRlXCIsZGlzcGxheTpcImJsb2NrXCIsdG9wOlwiLTEwMDBweFwifSksdC5kYXRlcGlja2VyLl91cGRhdGVEYXRlcGlja2VyKHMpLGg9dC5kYXRlcGlja2VyLl9jaGVja09mZnNldChzLGgscikscy5kcERpdi5jc3Moe3Bvc2l0aW9uOnQuZGF0ZXBpY2tlci5faW5EaWFsb2cmJnQuYmxvY2tVST9cInN0YXRpY1wiOnI/XCJmaXhlZFwiOlwiYWJzb2x1dGVcIixkaXNwbGF5Olwibm9uZVwiLGxlZnQ6aC5sZWZ0K1wicHhcIix0b3A6aC50b3ArXCJweFwifSkscy5pbmxpbmV8fChsPXQuZGF0ZXBpY2tlci5fZ2V0KHMsXCJzaG93QW5pbVwiKSxjPXQuZGF0ZXBpY2tlci5fZ2V0KHMsXCJkdXJhdGlvblwiKSxzLmRwRGl2LmNzcyhcInotaW5kZXhcIixpKHQoZSkpKzEpLHQuZGF0ZXBpY2tlci5fZGF0ZXBpY2tlclNob3dpbmc9ITAsdC5lZmZlY3RzJiZ0LmVmZmVjdHMuZWZmZWN0W2xdP3MuZHBEaXYuc2hvdyhsLHQuZGF0ZXBpY2tlci5fZ2V0KHMsXCJzaG93T3B0aW9uc1wiKSxjKTpzLmRwRGl2W2x8fFwic2hvd1wiXShsP2M6bnVsbCksdC5kYXRlcGlja2VyLl9zaG91bGRGb2N1c0lucHV0KHMpJiZzLmlucHV0LnRyaWdnZXIoXCJmb2N1c1wiKSx0LmRhdGVwaWNrZXIuX2N1ckluc3Q9cykpfX0sX3VwZGF0ZURhdGVwaWNrZXI6ZnVuY3Rpb24oZSl7dGhpcy5tYXhSb3dzPTQscD1lLGUuZHBEaXYuZW1wdHkoKS5hcHBlbmQodGhpcy5fZ2VuZXJhdGVIVE1MKGUpKSx0aGlzLl9hdHRhY2hIYW5kbGVycyhlKTt2YXIgaSxzPXRoaXMuX2dldE51bWJlck9mTW9udGhzKGUpLG49c1sxXSxhPTE3LHI9ZS5kcERpdi5maW5kKFwiLlwiK3RoaXMuX2RheU92ZXJDbGFzcytcIiBhXCIpO3IubGVuZ3RoPjAmJm8uYXBwbHkoci5nZXQoMCkpLGUuZHBEaXYucmVtb3ZlQ2xhc3MoXCJ1aS1kYXRlcGlja2VyLW11bHRpLTIgdWktZGF0ZXBpY2tlci1tdWx0aS0zIHVpLWRhdGVwaWNrZXItbXVsdGktNFwiKS53aWR0aChcIlwiKSxuPjEmJmUuZHBEaXYuYWRkQ2xhc3MoXCJ1aS1kYXRlcGlja2VyLW11bHRpLVwiK24pLmNzcyhcIndpZHRoXCIsYSpuK1wiZW1cIiksZS5kcERpdlsoMSE9PXNbMF18fDEhPT1zWzFdP1wiYWRkXCI6XCJyZW1vdmVcIikrXCJDbGFzc1wiXShcInVpLWRhdGVwaWNrZXItbXVsdGlcIiksZS5kcERpdlsodGhpcy5fZ2V0KGUsXCJpc1JUTFwiKT9cImFkZFwiOlwicmVtb3ZlXCIpK1wiQ2xhc3NcIl0oXCJ1aS1kYXRlcGlja2VyLXJ0bFwiKSxlPT09dC5kYXRlcGlja2VyLl9jdXJJbnN0JiZ0LmRhdGVwaWNrZXIuX2RhdGVwaWNrZXJTaG93aW5nJiZ0LmRhdGVwaWNrZXIuX3Nob3VsZEZvY3VzSW5wdXQoZSkmJmUuaW5wdXQudHJpZ2dlcihcImZvY3VzXCIpLGUueWVhcnNodG1sJiYoaT1lLnllYXJzaHRtbCxzZXRUaW1lb3V0KGZ1bmN0aW9uKCl7aT09PWUueWVhcnNodG1sJiZlLnllYXJzaHRtbCYmZS5kcERpdi5maW5kKFwic2VsZWN0LnVpLWRhdGVwaWNrZXIteWVhcjpmaXJzdFwiKS5yZXBsYWNlV2l0aChlLnllYXJzaHRtbCksaT1lLnllYXJzaHRtbD1udWxsfSwwKSl9LF9zaG91bGRGb2N1c0lucHV0OmZ1bmN0aW9uKHQpe3JldHVybiB0LmlucHV0JiZ0LmlucHV0LmlzKFwiOnZpc2libGVcIikmJiF0LmlucHV0LmlzKFwiOmRpc2FibGVkXCIpJiYhdC5pbnB1dC5pcyhcIjpmb2N1c1wiKX0sX2NoZWNrT2Zmc2V0OmZ1bmN0aW9uKGUsaSxzKXt2YXIgbj1lLmRwRGl2Lm91dGVyV2lkdGgoKSxvPWUuZHBEaXYub3V0ZXJIZWlnaHQoKSxhPWUuaW5wdXQ/ZS5pbnB1dC5vdXRlcldpZHRoKCk6MCxyPWUuaW5wdXQ/ZS5pbnB1dC5vdXRlckhlaWdodCgpOjAsaD1kb2N1bWVudC5kb2N1bWVudEVsZW1lbnQuY2xpZW50V2lkdGgrKHM/MDp0KGRvY3VtZW50KS5zY3JvbGxMZWZ0KCkpLGw9ZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LmNsaWVudEhlaWdodCsocz8wOnQoZG9jdW1lbnQpLnNjcm9sbFRvcCgpKTtyZXR1cm4gaS5sZWZ0LT10aGlzLl9nZXQoZSxcImlzUlRMXCIpP24tYTowLGkubGVmdC09cyYmaS5sZWZ0PT09ZS5pbnB1dC5vZmZzZXQoKS5sZWZ0P3QoZG9jdW1lbnQpLnNjcm9sbExlZnQoKTowLGkudG9wLT1zJiZpLnRvcD09PWUuaW5wdXQub2Zmc2V0KCkudG9wK3I/dChkb2N1bWVudCkuc2Nyb2xsVG9wKCk6MCxpLmxlZnQtPU1hdGgubWluKGkubGVmdCxpLmxlZnQrbj5oJiZoPm4/TWF0aC5hYnMoaS5sZWZ0K24taCk6MCksaS50b3AtPU1hdGgubWluKGkudG9wLGkudG9wK28+bCYmbD5vP01hdGguYWJzKG8rcik6MCksaX0sX2ZpbmRQb3M6ZnVuY3Rpb24oZSl7Zm9yKHZhciBpLHM9dGhpcy5fZ2V0SW5zdChlKSxuPXRoaXMuX2dldChzLFwiaXNSVExcIik7ZSYmKFwiaGlkZGVuXCI9PT1lLnR5cGV8fDEhPT1lLm5vZGVUeXBlfHx0LmV4cHIuZmlsdGVycy5oaWRkZW4oZSkpOyllPWVbbj9cInByZXZpb3VzU2libGluZ1wiOlwibmV4dFNpYmxpbmdcIl07cmV0dXJuIGk9dChlKS5vZmZzZXQoKSxbaS5sZWZ0LGkudG9wXX0sX2hpZGVEYXRlcGlja2VyOmZ1bmN0aW9uKGUpe3ZhciBpLHMsbixvLGE9dGhpcy5fY3VySW5zdDshYXx8ZSYmYSE9PXQuZGF0YShlLFwiZGF0ZXBpY2tlclwiKXx8dGhpcy5fZGF0ZXBpY2tlclNob3dpbmcmJihpPXRoaXMuX2dldChhLFwic2hvd0FuaW1cIikscz10aGlzLl9nZXQoYSxcImR1cmF0aW9uXCIpLG49ZnVuY3Rpb24oKXt0LmRhdGVwaWNrZXIuX3RpZHlEaWFsb2coYSl9LHQuZWZmZWN0cyYmKHQuZWZmZWN0cy5lZmZlY3RbaV18fHQuZWZmZWN0c1tpXSk/YS5kcERpdi5oaWRlKGksdC5kYXRlcGlja2VyLl9nZXQoYSxcInNob3dPcHRpb25zXCIpLHMsbik6YS5kcERpdltcInNsaWRlRG93blwiPT09aT9cInNsaWRlVXBcIjpcImZhZGVJblwiPT09aT9cImZhZGVPdXRcIjpcImhpZGVcIl0oaT9zOm51bGwsbiksaXx8bigpLHRoaXMuX2RhdGVwaWNrZXJTaG93aW5nPSExLG89dGhpcy5fZ2V0KGEsXCJvbkNsb3NlXCIpLG8mJm8uYXBwbHkoYS5pbnB1dD9hLmlucHV0WzBdOm51bGwsW2EuaW5wdXQ/YS5pbnB1dC52YWwoKTpcIlwiLGFdKSx0aGlzLl9sYXN0SW5wdXQ9bnVsbCx0aGlzLl9pbkRpYWxvZyYmKHRoaXMuX2RpYWxvZ0lucHV0LmNzcyh7cG9zaXRpb246XCJhYnNvbHV0ZVwiLGxlZnQ6XCIwXCIsdG9wOlwiLTEwMHB4XCJ9KSx0LmJsb2NrVUkmJih0LnVuYmxvY2tVSSgpLHQoXCJib2R5XCIpLmFwcGVuZCh0aGlzLmRwRGl2KSkpLHRoaXMuX2luRGlhbG9nPSExKX0sX3RpZHlEaWFsb2c6ZnVuY3Rpb24odCl7dC5kcERpdi5yZW1vdmVDbGFzcyh0aGlzLl9kaWFsb2dDbGFzcykub2ZmKFwiLnVpLWRhdGVwaWNrZXItY2FsZW5kYXJcIil9LF9jaGVja0V4dGVybmFsQ2xpY2s6ZnVuY3Rpb24oZSl7aWYodC5kYXRlcGlja2VyLl9jdXJJbnN0KXt2YXIgaT10KGUudGFyZ2V0KSxzPXQuZGF0ZXBpY2tlci5fZ2V0SW5zdChpWzBdKTsoaVswXS5pZCE9PXQuZGF0ZXBpY2tlci5fbWFpbkRpdklkJiYwPT09aS5wYXJlbnRzKFwiI1wiK3QuZGF0ZXBpY2tlci5fbWFpbkRpdklkKS5sZW5ndGgmJiFpLmhhc0NsYXNzKHQuZGF0ZXBpY2tlci5tYXJrZXJDbGFzc05hbWUpJiYhaS5jbG9zZXN0KFwiLlwiK3QuZGF0ZXBpY2tlci5fdHJpZ2dlckNsYXNzKS5sZW5ndGgmJnQuZGF0ZXBpY2tlci5fZGF0ZXBpY2tlclNob3dpbmcmJighdC5kYXRlcGlja2VyLl9pbkRpYWxvZ3x8IXQuYmxvY2tVSSl8fGkuaGFzQ2xhc3ModC5kYXRlcGlja2VyLm1hcmtlckNsYXNzTmFtZSkmJnQuZGF0ZXBpY2tlci5fY3VySW5zdCE9PXMpJiZ0LmRhdGVwaWNrZXIuX2hpZGVEYXRlcGlja2VyKCl9fSxfYWRqdXN0RGF0ZTpmdW5jdGlvbihlLGkscyl7dmFyIG49dChlKSxvPXRoaXMuX2dldEluc3QoblswXSk7dGhpcy5faXNEaXNhYmxlZERhdGVwaWNrZXIoblswXSl8fCh0aGlzLl9hZGp1c3RJbnN0RGF0ZShvLGkrKFwiTVwiPT09cz90aGlzLl9nZXQobyxcInNob3dDdXJyZW50QXRQb3NcIik6MCkscyksdGhpcy5fdXBkYXRlRGF0ZXBpY2tlcihvKSl9LF9nb3RvVG9kYXk6ZnVuY3Rpb24oZSl7dmFyIGkscz10KGUpLG49dGhpcy5fZ2V0SW5zdChzWzBdKTt0aGlzLl9nZXQobixcImdvdG9DdXJyZW50XCIpJiZuLmN1cnJlbnREYXk/KG4uc2VsZWN0ZWREYXk9bi5jdXJyZW50RGF5LG4uZHJhd01vbnRoPW4uc2VsZWN0ZWRNb250aD1uLmN1cnJlbnRNb250aCxuLmRyYXdZZWFyPW4uc2VsZWN0ZWRZZWFyPW4uY3VycmVudFllYXIpOihpPW5ldyBEYXRlLG4uc2VsZWN0ZWREYXk9aS5nZXREYXRlKCksbi5kcmF3TW9udGg9bi5zZWxlY3RlZE1vbnRoPWkuZ2V0TW9udGgoKSxuLmRyYXdZZWFyPW4uc2VsZWN0ZWRZZWFyPWkuZ2V0RnVsbFllYXIoKSksdGhpcy5fbm90aWZ5Q2hhbmdlKG4pLHRoaXMuX2FkanVzdERhdGUocyl9LF9zZWxlY3RNb250aFllYXI6ZnVuY3Rpb24oZSxpLHMpe3ZhciBuPXQoZSksbz10aGlzLl9nZXRJbnN0KG5bMF0pO29bXCJzZWxlY3RlZFwiKyhcIk1cIj09PXM/XCJNb250aFwiOlwiWWVhclwiKV09b1tcImRyYXdcIisoXCJNXCI9PT1zP1wiTW9udGhcIjpcIlllYXJcIildPXBhcnNlSW50KGkub3B0aW9uc1tpLnNlbGVjdGVkSW5kZXhdLnZhbHVlLDEwKSx0aGlzLl9ub3RpZnlDaGFuZ2UobyksdGhpcy5fYWRqdXN0RGF0ZShuKX0sX3NlbGVjdERheTpmdW5jdGlvbihlLGkscyxuKXt2YXIgbyxhPXQoZSk7dChuKS5oYXNDbGFzcyh0aGlzLl91bnNlbGVjdGFibGVDbGFzcyl8fHRoaXMuX2lzRGlzYWJsZWREYXRlcGlja2VyKGFbMF0pfHwobz10aGlzLl9nZXRJbnN0KGFbMF0pLG8uc2VsZWN0ZWREYXk9by5jdXJyZW50RGF5PXQoXCJhXCIsbikuaHRtbCgpLG8uc2VsZWN0ZWRNb250aD1vLmN1cnJlbnRNb250aD1pLG8uc2VsZWN0ZWRZZWFyPW8uY3VycmVudFllYXI9cyx0aGlzLl9zZWxlY3REYXRlKGUsdGhpcy5fZm9ybWF0RGF0ZShvLG8uY3VycmVudERheSxvLmN1cnJlbnRNb250aCxvLmN1cnJlbnRZZWFyKSkpfSxfY2xlYXJEYXRlOmZ1bmN0aW9uKGUpe3ZhciBpPXQoZSk7dGhpcy5fc2VsZWN0RGF0ZShpLFwiXCIpfSxfc2VsZWN0RGF0ZTpmdW5jdGlvbihlLGkpe3ZhciBzLG49dChlKSxvPXRoaXMuX2dldEluc3QoblswXSk7aT1udWxsIT1pP2k6dGhpcy5fZm9ybWF0RGF0ZShvKSxvLmlucHV0JiZvLmlucHV0LnZhbChpKSx0aGlzLl91cGRhdGVBbHRlcm5hdGUobykscz10aGlzLl9nZXQobyxcIm9uU2VsZWN0XCIpLHM/cy5hcHBseShvLmlucHV0P28uaW5wdXRbMF06bnVsbCxbaSxvXSk6by5pbnB1dCYmby5pbnB1dC50cmlnZ2VyKFwiY2hhbmdlXCIpLG8uaW5saW5lP3RoaXMuX3VwZGF0ZURhdGVwaWNrZXIobyk6KHRoaXMuX2hpZGVEYXRlcGlja2VyKCksdGhpcy5fbGFzdElucHV0PW8uaW5wdXRbMF0sXCJvYmplY3RcIiE9dHlwZW9mIG8uaW5wdXRbMF0mJm8uaW5wdXQudHJpZ2dlcihcImZvY3VzXCIpLHRoaXMuX2xhc3RJbnB1dD1udWxsKX0sX3VwZGF0ZUFsdGVybmF0ZTpmdW5jdGlvbihlKXt2YXIgaSxzLG4sbz10aGlzLl9nZXQoZSxcImFsdEZpZWxkXCIpO28mJihpPXRoaXMuX2dldChlLFwiYWx0Rm9ybWF0XCIpfHx0aGlzLl9nZXQoZSxcImRhdGVGb3JtYXRcIikscz10aGlzLl9nZXREYXRlKGUpLG49dGhpcy5mb3JtYXREYXRlKGkscyx0aGlzLl9nZXRGb3JtYXRDb25maWcoZSkpLHQobykudmFsKG4pKX0sbm9XZWVrZW5kczpmdW5jdGlvbih0KXt2YXIgZT10LmdldERheSgpO3JldHVybltlPjAmJjY+ZSxcIlwiXX0saXNvODYwMVdlZWs6ZnVuY3Rpb24odCl7dmFyIGUsaT1uZXcgRGF0ZSh0LmdldFRpbWUoKSk7cmV0dXJuIGkuc2V0RGF0ZShpLmdldERhdGUoKSs0LShpLmdldERheSgpfHw3KSksZT1pLmdldFRpbWUoKSxpLnNldE1vbnRoKDApLGkuc2V0RGF0ZSgxKSxNYXRoLmZsb29yKE1hdGgucm91bmQoKGUtaSkvODY0ZTUpLzcpKzF9LHBhcnNlRGF0ZTpmdW5jdGlvbihlLGkscyl7aWYobnVsbD09ZXx8bnVsbD09aSl0aHJvd1wiSW52YWxpZCBhcmd1bWVudHNcIjtpZihpPVwib2JqZWN0XCI9PXR5cGVvZiBpP1wiXCIraTppK1wiXCIsXCJcIj09PWkpcmV0dXJuIG51bGw7dmFyIG4sbyxhLHIsaD0wLGw9KHM/cy5zaG9ydFllYXJDdXRvZmY6bnVsbCl8fHRoaXMuX2RlZmF1bHRzLnNob3J0WWVhckN1dG9mZixjPVwic3RyaW5nXCIhPXR5cGVvZiBsP2w6KG5ldyBEYXRlKS5nZXRGdWxsWWVhcigpJTEwMCtwYXJzZUludChsLDEwKSx1PShzP3MuZGF5TmFtZXNTaG9ydDpudWxsKXx8dGhpcy5fZGVmYXVsdHMuZGF5TmFtZXNTaG9ydCxkPShzP3MuZGF5TmFtZXM6bnVsbCl8fHRoaXMuX2RlZmF1bHRzLmRheU5hbWVzLHA9KHM/cy5tb250aE5hbWVzU2hvcnQ6bnVsbCl8fHRoaXMuX2RlZmF1bHRzLm1vbnRoTmFtZXNTaG9ydCxmPShzP3MubW9udGhOYW1lczpudWxsKXx8dGhpcy5fZGVmYXVsdHMubW9udGhOYW1lcyxnPS0xLG09LTEsXz0tMSx2PS0xLGI9ITEseT1mdW5jdGlvbih0KXt2YXIgaT1lLmxlbmd0aD5uKzEmJmUuY2hhckF0KG4rMSk9PT10O3JldHVybiBpJiZuKyssaX0sdz1mdW5jdGlvbih0KXt2YXIgZT15KHQpLHM9XCJAXCI9PT10PzE0OlwiIVwiPT09dD8yMDpcInlcIj09PXQmJmU/NDpcIm9cIj09PXQ/MzoyLG49XCJ5XCI9PT10P3M6MSxvPVJlZ0V4cChcIl5cXFxcZHtcIituK1wiLFwiK3MrXCJ9XCIpLGE9aS5zdWJzdHJpbmcoaCkubWF0Y2gobyk7aWYoIWEpdGhyb3dcIk1pc3NpbmcgbnVtYmVyIGF0IHBvc2l0aW9uIFwiK2g7cmV0dXJuIGgrPWFbMF0ubGVuZ3RoLHBhcnNlSW50KGFbMF0sMTApfSxrPWZ1bmN0aW9uKGUscyxuKXt2YXIgbz0tMSxhPXQubWFwKHkoZSk/bjpzLGZ1bmN0aW9uKHQsZSl7cmV0dXJuW1tlLHRdXX0pLnNvcnQoZnVuY3Rpb24odCxlKXtyZXR1cm4tKHRbMV0ubGVuZ3RoLWVbMV0ubGVuZ3RoKX0pO2lmKHQuZWFjaChhLGZ1bmN0aW9uKHQsZSl7dmFyIHM9ZVsxXTtyZXR1cm4gaS5zdWJzdHIoaCxzLmxlbmd0aCkudG9Mb3dlckNhc2UoKT09PXMudG9Mb3dlckNhc2UoKT8obz1lWzBdLGgrPXMubGVuZ3RoLCExKTp2b2lkIDB9KSwtMSE9PW8pcmV0dXJuIG8rMTt0aHJvd1wiVW5rbm93biBuYW1lIGF0IHBvc2l0aW9uIFwiK2h9LHg9ZnVuY3Rpb24oKXtpZihpLmNoYXJBdChoKSE9PWUuY2hhckF0KG4pKXRocm93XCJVbmV4cGVjdGVkIGxpdGVyYWwgYXQgcG9zaXRpb24gXCIraDtoKyt9O2ZvcihuPTA7ZS5sZW5ndGg+bjtuKyspaWYoYilcIidcIiE9PWUuY2hhckF0KG4pfHx5KFwiJ1wiKT94KCk6Yj0hMTtlbHNlIHN3aXRjaChlLmNoYXJBdChuKSl7Y2FzZVwiZFwiOl89dyhcImRcIik7YnJlYWs7Y2FzZVwiRFwiOmsoXCJEXCIsdSxkKTticmVhaztjYXNlXCJvXCI6dj13KFwib1wiKTticmVhaztjYXNlXCJtXCI6bT13KFwibVwiKTticmVhaztjYXNlXCJNXCI6bT1rKFwiTVwiLHAsZik7YnJlYWs7Y2FzZVwieVwiOmc9dyhcInlcIik7YnJlYWs7Y2FzZVwiQFwiOnI9bmV3IERhdGUodyhcIkBcIikpLGc9ci5nZXRGdWxsWWVhcigpLG09ci5nZXRNb250aCgpKzEsXz1yLmdldERhdGUoKTticmVhaztjYXNlXCIhXCI6cj1uZXcgRGF0ZSgodyhcIiFcIiktdGhpcy5fdGlja3NUbzE5NzApLzFlNCksZz1yLmdldEZ1bGxZZWFyKCksbT1yLmdldE1vbnRoKCkrMSxfPXIuZ2V0RGF0ZSgpO2JyZWFrO2Nhc2VcIidcIjp5KFwiJ1wiKT94KCk6Yj0hMDticmVhaztkZWZhdWx0OngoKX1pZihpLmxlbmd0aD5oJiYoYT1pLnN1YnN0cihoKSwhL15cXHMrLy50ZXN0KGEpKSl0aHJvd1wiRXh0cmEvdW5wYXJzZWQgY2hhcmFjdGVycyBmb3VuZCBpbiBkYXRlOiBcIithO2lmKC0xPT09Zz9nPShuZXcgRGF0ZSkuZ2V0RnVsbFllYXIoKToxMDA+ZyYmKGcrPShuZXcgRGF0ZSkuZ2V0RnVsbFllYXIoKS0obmV3IERhdGUpLmdldEZ1bGxZZWFyKCklMTAwKyhjPj1nPzA6LTEwMCkpLHY+LTEpZm9yKG09MSxfPXY7Oyl7aWYobz10aGlzLl9nZXREYXlzSW5Nb250aChnLG0tMSksbz49XylicmVhazttKyssXy09b31pZihyPXRoaXMuX2RheWxpZ2h0U2F2aW5nQWRqdXN0KG5ldyBEYXRlKGcsbS0xLF8pKSxyLmdldEZ1bGxZZWFyKCkhPT1nfHxyLmdldE1vbnRoKCkrMSE9PW18fHIuZ2V0RGF0ZSgpIT09Xyl0aHJvd1wiSW52YWxpZCBkYXRlXCI7cmV0dXJuIHJ9LEFUT006XCJ5eS1tbS1kZFwiLENPT0tJRTpcIkQsIGRkIE0geXlcIixJU09fODYwMTpcInl5LW1tLWRkXCIsUkZDXzgyMjpcIkQsIGQgTSB5XCIsUkZDXzg1MDpcIkRELCBkZC1NLXlcIixSRkNfMTAzNjpcIkQsIGQgTSB5XCIsUkZDXzExMjM6XCJELCBkIE0geXlcIixSRkNfMjgyMjpcIkQsIGQgTSB5eVwiLFJTUzpcIkQsIGQgTSB5XCIsVElDS1M6XCIhXCIsVElNRVNUQU1QOlwiQFwiLFczQzpcInl5LW1tLWRkXCIsX3RpY2tzVG8xOTcwOjFlNyo2MCo2MCoyNCooNzE4Njg1K01hdGguZmxvb3IoNDkyLjUpLU1hdGguZmxvb3IoMTkuNykrTWF0aC5mbG9vcig0LjkyNSkpLGZvcm1hdERhdGU6ZnVuY3Rpb24odCxlLGkpe2lmKCFlKXJldHVyblwiXCI7dmFyIHMsbj0oaT9pLmRheU5hbWVzU2hvcnQ6bnVsbCl8fHRoaXMuX2RlZmF1bHRzLmRheU5hbWVzU2hvcnQsbz0oaT9pLmRheU5hbWVzOm51bGwpfHx0aGlzLl9kZWZhdWx0cy5kYXlOYW1lcyxhPShpP2kubW9udGhOYW1lc1Nob3J0Om51bGwpfHx0aGlzLl9kZWZhdWx0cy5tb250aE5hbWVzU2hvcnQscj0oaT9pLm1vbnRoTmFtZXM6bnVsbCl8fHRoaXMuX2RlZmF1bHRzLm1vbnRoTmFtZXMsaD1mdW5jdGlvbihlKXt2YXIgaT10Lmxlbmd0aD5zKzEmJnQuY2hhckF0KHMrMSk9PT1lO3JldHVybiBpJiZzKyssaX0sbD1mdW5jdGlvbih0LGUsaSl7dmFyIHM9XCJcIitlO2lmKGgodCkpZm9yKDtpPnMubGVuZ3RoOylzPVwiMFwiK3M7cmV0dXJuIHN9LGM9ZnVuY3Rpb24odCxlLGkscyl7cmV0dXJuIGgodCk/c1tlXTppW2VdfSx1PVwiXCIsZD0hMTtpZihlKWZvcihzPTA7dC5sZW5ndGg+cztzKyspaWYoZClcIidcIiE9PXQuY2hhckF0KHMpfHxoKFwiJ1wiKT91Kz10LmNoYXJBdChzKTpkPSExO2Vsc2Ugc3dpdGNoKHQuY2hhckF0KHMpKXtjYXNlXCJkXCI6dSs9bChcImRcIixlLmdldERhdGUoKSwyKTticmVhaztjYXNlXCJEXCI6dSs9YyhcIkRcIixlLmdldERheSgpLG4sbyk7YnJlYWs7Y2FzZVwib1wiOnUrPWwoXCJvXCIsTWF0aC5yb3VuZCgobmV3IERhdGUoZS5nZXRGdWxsWWVhcigpLGUuZ2V0TW9udGgoKSxlLmdldERhdGUoKSkuZ2V0VGltZSgpLW5ldyBEYXRlKGUuZ2V0RnVsbFllYXIoKSwwLDApLmdldFRpbWUoKSkvODY0ZTUpLDMpO2JyZWFrO2Nhc2VcIm1cIjp1Kz1sKFwibVwiLGUuZ2V0TW9udGgoKSsxLDIpO2JyZWFrO2Nhc2VcIk1cIjp1Kz1jKFwiTVwiLGUuZ2V0TW9udGgoKSxhLHIpO2JyZWFrO2Nhc2VcInlcIjp1Kz1oKFwieVwiKT9lLmdldEZ1bGxZZWFyKCk6KDEwPmUuZ2V0RnVsbFllYXIoKSUxMDA/XCIwXCI6XCJcIikrZS5nZXRGdWxsWWVhcigpJTEwMDticmVhaztjYXNlXCJAXCI6dSs9ZS5nZXRUaW1lKCk7YnJlYWs7Y2FzZVwiIVwiOnUrPTFlNCplLmdldFRpbWUoKSt0aGlzLl90aWNrc1RvMTk3MDticmVhaztjYXNlXCInXCI6aChcIidcIik/dSs9XCInXCI6ZD0hMDticmVhaztkZWZhdWx0OnUrPXQuY2hhckF0KHMpfXJldHVybiB1fSxfcG9zc2libGVDaGFyczpmdW5jdGlvbih0KXt2YXIgZSxpPVwiXCIscz0hMSxuPWZ1bmN0aW9uKGkpe3ZhciBzPXQubGVuZ3RoPmUrMSYmdC5jaGFyQXQoZSsxKT09PWk7cmV0dXJuIHMmJmUrKyxzfTtmb3IoZT0wO3QubGVuZ3RoPmU7ZSsrKWlmKHMpXCInXCIhPT10LmNoYXJBdChlKXx8bihcIidcIik/aSs9dC5jaGFyQXQoZSk6cz0hMTtlbHNlIHN3aXRjaCh0LmNoYXJBdChlKSl7Y2FzZVwiZFwiOmNhc2VcIm1cIjpjYXNlXCJ5XCI6Y2FzZVwiQFwiOmkrPVwiMDEyMzQ1Njc4OVwiO2JyZWFrO2Nhc2VcIkRcIjpjYXNlXCJNXCI6cmV0dXJuIG51bGw7Y2FzZVwiJ1wiOm4oXCInXCIpP2krPVwiJ1wiOnM9ITA7YnJlYWs7ZGVmYXVsdDppKz10LmNoYXJBdChlKX1yZXR1cm4gaX0sX2dldDpmdW5jdGlvbih0LGUpe3JldHVybiB2b2lkIDAhPT10LnNldHRpbmdzW2VdP3Quc2V0dGluZ3NbZV06dGhpcy5fZGVmYXVsdHNbZV19LF9zZXREYXRlRnJvbUZpZWxkOmZ1bmN0aW9uKHQsZSl7aWYodC5pbnB1dC52YWwoKSE9PXQubGFzdFZhbCl7dmFyIGk9dGhpcy5fZ2V0KHQsXCJkYXRlRm9ybWF0XCIpLHM9dC5sYXN0VmFsPXQuaW5wdXQ/dC5pbnB1dC52YWwoKTpudWxsLG49dGhpcy5fZ2V0RGVmYXVsdERhdGUodCksbz1uLGE9dGhpcy5fZ2V0Rm9ybWF0Q29uZmlnKHQpO3RyeXtvPXRoaXMucGFyc2VEYXRlKGkscyxhKXx8bn1jYXRjaChyKXtzPWU/XCJcIjpzfXQuc2VsZWN0ZWREYXk9by5nZXREYXRlKCksdC5kcmF3TW9udGg9dC5zZWxlY3RlZE1vbnRoPW8uZ2V0TW9udGgoKSx0LmRyYXdZZWFyPXQuc2VsZWN0ZWRZZWFyPW8uZ2V0RnVsbFllYXIoKSx0LmN1cnJlbnREYXk9cz9vLmdldERhdGUoKTowLHQuY3VycmVudE1vbnRoPXM/by5nZXRNb250aCgpOjAsdC5jdXJyZW50WWVhcj1zP28uZ2V0RnVsbFllYXIoKTowLHRoaXMuX2FkanVzdEluc3REYXRlKHQpfX0sX2dldERlZmF1bHREYXRlOmZ1bmN0aW9uKHQpe3JldHVybiB0aGlzLl9yZXN0cmljdE1pbk1heCh0LHRoaXMuX2RldGVybWluZURhdGUodCx0aGlzLl9nZXQodCxcImRlZmF1bHREYXRlXCIpLG5ldyBEYXRlKSl9LF9kZXRlcm1pbmVEYXRlOmZ1bmN0aW9uKGUsaSxzKXt2YXIgbj1mdW5jdGlvbih0KXt2YXIgZT1uZXcgRGF0ZTtyZXR1cm4gZS5zZXREYXRlKGUuZ2V0RGF0ZSgpK3QpLGV9LG89ZnVuY3Rpb24oaSl7dHJ5e3JldHVybiB0LmRhdGVwaWNrZXIucGFyc2VEYXRlKHQuZGF0ZXBpY2tlci5fZ2V0KGUsXCJkYXRlRm9ybWF0XCIpLGksdC5kYXRlcGlja2VyLl9nZXRGb3JtYXRDb25maWcoZSkpfWNhdGNoKHMpe31mb3IodmFyIG49KGkudG9Mb3dlckNhc2UoKS5tYXRjaCgvXmMvKT90LmRhdGVwaWNrZXIuX2dldERhdGUoZSk6bnVsbCl8fG5ldyBEYXRlLG89bi5nZXRGdWxsWWVhcigpLGE9bi5nZXRNb250aCgpLHI9bi5nZXREYXRlKCksaD0vKFsrXFwtXT9bMC05XSspXFxzKihkfER8d3xXfG18TXx5fFkpPy9nLGw9aC5leGVjKGkpO2w7KXtzd2l0Y2gobFsyXXx8XCJkXCIpe2Nhc2VcImRcIjpjYXNlXCJEXCI6cis9cGFyc2VJbnQobFsxXSwxMCk7YnJlYWs7Y2FzZVwid1wiOmNhc2VcIldcIjpyKz03KnBhcnNlSW50KGxbMV0sMTApO2JyZWFrO2Nhc2VcIm1cIjpjYXNlXCJNXCI6YSs9cGFyc2VJbnQobFsxXSwxMCkscj1NYXRoLm1pbihyLHQuZGF0ZXBpY2tlci5fZ2V0RGF5c0luTW9udGgobyxhKSk7YnJlYWs7Y2FzZVwieVwiOmNhc2VcIllcIjpvKz1wYXJzZUludChsWzFdLDEwKSxyPU1hdGgubWluKHIsdC5kYXRlcGlja2VyLl9nZXREYXlzSW5Nb250aChvLGEpKX1sPWguZXhlYyhpKX1yZXR1cm4gbmV3IERhdGUobyxhLHIpfSxhPW51bGw9PWl8fFwiXCI9PT1pP3M6XCJzdHJpbmdcIj09dHlwZW9mIGk/byhpKTpcIm51bWJlclwiPT10eXBlb2YgaT9pc05hTihpKT9zOm4oaSk6bmV3IERhdGUoaS5nZXRUaW1lKCkpO3JldHVybiBhPWEmJlwiSW52YWxpZCBEYXRlXCI9PVwiXCIrYT9zOmEsYSYmKGEuc2V0SG91cnMoMCksYS5zZXRNaW51dGVzKDApLGEuc2V0U2Vjb25kcygwKSxhLnNldE1pbGxpc2Vjb25kcygwKSksdGhpcy5fZGF5bGlnaHRTYXZpbmdBZGp1c3QoYSl9LF9kYXlsaWdodFNhdmluZ0FkanVzdDpmdW5jdGlvbih0KXtyZXR1cm4gdD8odC5zZXRIb3Vycyh0LmdldEhvdXJzKCk+MTI/dC5nZXRIb3VycygpKzI6MCksdCk6bnVsbH0sX3NldERhdGU6ZnVuY3Rpb24odCxlLGkpe3ZhciBzPSFlLG49dC5zZWxlY3RlZE1vbnRoLG89dC5zZWxlY3RlZFllYXIsYT10aGlzLl9yZXN0cmljdE1pbk1heCh0LHRoaXMuX2RldGVybWluZURhdGUodCxlLG5ldyBEYXRlKSk7dC5zZWxlY3RlZERheT10LmN1cnJlbnREYXk9YS5nZXREYXRlKCksdC5kcmF3TW9udGg9dC5zZWxlY3RlZE1vbnRoPXQuY3VycmVudE1vbnRoPWEuZ2V0TW9udGgoKSx0LmRyYXdZZWFyPXQuc2VsZWN0ZWRZZWFyPXQuY3VycmVudFllYXI9YS5nZXRGdWxsWWVhcigpLG49PT10LnNlbGVjdGVkTW9udGgmJm89PT10LnNlbGVjdGVkWWVhcnx8aXx8dGhpcy5fbm90aWZ5Q2hhbmdlKHQpLHRoaXMuX2FkanVzdEluc3REYXRlKHQpLHQuaW5wdXQmJnQuaW5wdXQudmFsKHM/XCJcIjp0aGlzLl9mb3JtYXREYXRlKHQpKX0sX2dldERhdGU6ZnVuY3Rpb24odCl7dmFyIGU9IXQuY3VycmVudFllYXJ8fHQuaW5wdXQmJlwiXCI9PT10LmlucHV0LnZhbCgpP251bGw6dGhpcy5fZGF5bGlnaHRTYXZpbmdBZGp1c3QobmV3IERhdGUodC5jdXJyZW50WWVhcix0LmN1cnJlbnRNb250aCx0LmN1cnJlbnREYXkpKTtyZXR1cm4gZX0sX2F0dGFjaEhhbmRsZXJzOmZ1bmN0aW9uKGUpe3ZhciBpPXRoaXMuX2dldChlLFwic3RlcE1vbnRoc1wiKSxzPVwiI1wiK2UuaWQucmVwbGFjZSgvXFxcXFxcXFwvZyxcIlxcXFxcIik7ZS5kcERpdi5maW5kKFwiW2RhdGEtaGFuZGxlcl1cIikubWFwKGZ1bmN0aW9uKCl7dmFyIGU9e3ByZXY6ZnVuY3Rpb24oKXt0LmRhdGVwaWNrZXIuX2FkanVzdERhdGUocywtaSxcIk1cIil9LG5leHQ6ZnVuY3Rpb24oKXt0LmRhdGVwaWNrZXIuX2FkanVzdERhdGUocywraSxcIk1cIil9LGhpZGU6ZnVuY3Rpb24oKXt0LmRhdGVwaWNrZXIuX2hpZGVEYXRlcGlja2VyKCl9LHRvZGF5OmZ1bmN0aW9uKCl7dC5kYXRlcGlja2VyLl9nb3RvVG9kYXkocyl9LHNlbGVjdERheTpmdW5jdGlvbigpe3JldHVybiB0LmRhdGVwaWNrZXIuX3NlbGVjdERheShzLCt0aGlzLmdldEF0dHJpYnV0ZShcImRhdGEtbW9udGhcIiksK3RoaXMuZ2V0QXR0cmlidXRlKFwiZGF0YS15ZWFyXCIpLHRoaXMpLCExfSxzZWxlY3RNb250aDpmdW5jdGlvbigpe3JldHVybiB0LmRhdGVwaWNrZXIuX3NlbGVjdE1vbnRoWWVhcihzLHRoaXMsXCJNXCIpLCExfSxzZWxlY3RZZWFyOmZ1bmN0aW9uKCl7cmV0dXJuIHQuZGF0ZXBpY2tlci5fc2VsZWN0TW9udGhZZWFyKHMsdGhpcyxcIllcIiksITF9fTt0KHRoaXMpLm9uKHRoaXMuZ2V0QXR0cmlidXRlKFwiZGF0YS1ldmVudFwiKSxlW3RoaXMuZ2V0QXR0cmlidXRlKFwiZGF0YS1oYW5kbGVyXCIpXSl9KX0sX2dlbmVyYXRlSFRNTDpmdW5jdGlvbih0KXt2YXIgZSxpLHMsbixvLGEscixoLGwsYyx1LGQscCxmLGcsbSxfLHYsYix5LHcsayx4LEMsRCxJLFQsUCxNLFMsSCx6LE8sQSxOLFcsRSxGLEwsUj1uZXcgRGF0ZSxCPXRoaXMuX2RheWxpZ2h0U2F2aW5nQWRqdXN0KG5ldyBEYXRlKFIuZ2V0RnVsbFllYXIoKSxSLmdldE1vbnRoKCksUi5nZXREYXRlKCkpKSxZPXRoaXMuX2dldCh0LFwiaXNSVExcIiksaj10aGlzLl9nZXQodCxcInNob3dCdXR0b25QYW5lbFwiKSxxPXRoaXMuX2dldCh0LFwiaGlkZUlmTm9QcmV2TmV4dFwiKSxLPXRoaXMuX2dldCh0LFwibmF2aWdhdGlvbkFzRGF0ZUZvcm1hdFwiKSxVPXRoaXMuX2dldE51bWJlck9mTW9udGhzKHQpLFY9dGhpcy5fZ2V0KHQsXCJzaG93Q3VycmVudEF0UG9zXCIpLCQ9dGhpcy5fZ2V0KHQsXCJzdGVwTW9udGhzXCIpLFg9MSE9PVVbMF18fDEhPT1VWzFdLEc9dGhpcy5fZGF5bGlnaHRTYXZpbmdBZGp1c3QodC5jdXJyZW50RGF5P25ldyBEYXRlKHQuY3VycmVudFllYXIsdC5jdXJyZW50TW9udGgsdC5jdXJyZW50RGF5KTpuZXcgRGF0ZSg5OTk5LDksOSkpLFE9dGhpcy5fZ2V0TWluTWF4RGF0ZSh0LFwibWluXCIpLEo9dGhpcy5fZ2V0TWluTWF4RGF0ZSh0LFwibWF4XCIpLFo9dC5kcmF3TW9udGgtVix0ZT10LmRyYXdZZWFyO2lmKDA+WiYmKForPTEyLHRlLS0pLEopZm9yKGU9dGhpcy5fZGF5bGlnaHRTYXZpbmdBZGp1c3QobmV3IERhdGUoSi5nZXRGdWxsWWVhcigpLEouZ2V0TW9udGgoKS1VWzBdKlVbMV0rMSxKLmdldERhdGUoKSkpLGU9USYmUT5lP1E6ZTt0aGlzLl9kYXlsaWdodFNhdmluZ0FkanVzdChuZXcgRGF0ZSh0ZSxaLDEpKT5lOylaLS0sMD5aJiYoWj0xMSx0ZS0tKTtmb3IodC5kcmF3TW9udGg9Wix0LmRyYXdZZWFyPXRlLGk9dGhpcy5fZ2V0KHQsXCJwcmV2VGV4dFwiKSxpPUs/dGhpcy5mb3JtYXREYXRlKGksdGhpcy5fZGF5bGlnaHRTYXZpbmdBZGp1c3QobmV3IERhdGUodGUsWi0kLDEpKSx0aGlzLl9nZXRGb3JtYXRDb25maWcodCkpOmkscz10aGlzLl9jYW5BZGp1c3RNb250aCh0LC0xLHRlLFopP1wiPGEgY2xhc3M9J3VpLWRhdGVwaWNrZXItcHJldiB1aS1jb3JuZXItYWxsJyBkYXRhLWhhbmRsZXI9J3ByZXYnIGRhdGEtZXZlbnQ9J2NsaWNrJyB0aXRsZT0nXCIraStcIic+PHNwYW4gY2xhc3M9J3VpLWljb24gdWktaWNvbi1jaXJjbGUtdHJpYW5nbGUtXCIrKFk/XCJlXCI6XCJ3XCIpK1wiJz5cIitpK1wiPC9zcGFuPjwvYT5cIjpxP1wiXCI6XCI8YSBjbGFzcz0ndWktZGF0ZXBpY2tlci1wcmV2IHVpLWNvcm5lci1hbGwgdWktc3RhdGUtZGlzYWJsZWQnIHRpdGxlPSdcIitpK1wiJz48c3BhbiBjbGFzcz0ndWktaWNvbiB1aS1pY29uLWNpcmNsZS10cmlhbmdsZS1cIisoWT9cImVcIjpcIndcIikrXCInPlwiK2krXCI8L3NwYW4+PC9hPlwiLG49dGhpcy5fZ2V0KHQsXCJuZXh0VGV4dFwiKSxuPUs/dGhpcy5mb3JtYXREYXRlKG4sdGhpcy5fZGF5bGlnaHRTYXZpbmdBZGp1c3QobmV3IERhdGUodGUsWiskLDEpKSx0aGlzLl9nZXRGb3JtYXRDb25maWcodCkpOm4sbz10aGlzLl9jYW5BZGp1c3RNb250aCh0LDEsdGUsWik/XCI8YSBjbGFzcz0ndWktZGF0ZXBpY2tlci1uZXh0IHVpLWNvcm5lci1hbGwnIGRhdGEtaGFuZGxlcj0nbmV4dCcgZGF0YS1ldmVudD0nY2xpY2snIHRpdGxlPSdcIituK1wiJz48c3BhbiBjbGFzcz0ndWktaWNvbiB1aS1pY29uLWNpcmNsZS10cmlhbmdsZS1cIisoWT9cIndcIjpcImVcIikrXCInPlwiK24rXCI8L3NwYW4+PC9hPlwiOnE/XCJcIjpcIjxhIGNsYXNzPSd1aS1kYXRlcGlja2VyLW5leHQgdWktY29ybmVyLWFsbCB1aS1zdGF0ZS1kaXNhYmxlZCcgdGl0bGU9J1wiK24rXCInPjxzcGFuIGNsYXNzPSd1aS1pY29uIHVpLWljb24tY2lyY2xlLXRyaWFuZ2xlLVwiKyhZP1wid1wiOlwiZVwiKStcIic+XCIrbitcIjwvc3Bhbj48L2E+XCIsYT10aGlzLl9nZXQodCxcImN1cnJlbnRUZXh0XCIpLHI9dGhpcy5fZ2V0KHQsXCJnb3RvQ3VycmVudFwiKSYmdC5jdXJyZW50RGF5P0c6QixhPUs/dGhpcy5mb3JtYXREYXRlKGEscix0aGlzLl9nZXRGb3JtYXRDb25maWcodCkpOmEsaD10LmlubGluZT9cIlwiOlwiPGJ1dHRvbiB0eXBlPSdidXR0b24nIGNsYXNzPSd1aS1kYXRlcGlja2VyLWNsb3NlIHVpLXN0YXRlLWRlZmF1bHQgdWktcHJpb3JpdHktcHJpbWFyeSB1aS1jb3JuZXItYWxsJyBkYXRhLWhhbmRsZXI9J2hpZGUnIGRhdGEtZXZlbnQ9J2NsaWNrJz5cIit0aGlzLl9nZXQodCxcImNsb3NlVGV4dFwiKStcIjwvYnV0dG9uPlwiLGw9aj9cIjxkaXYgY2xhc3M9J3VpLWRhdGVwaWNrZXItYnV0dG9ucGFuZSB1aS13aWRnZXQtY29udGVudCc+XCIrKFk/aDpcIlwiKSsodGhpcy5faXNJblJhbmdlKHQscik/XCI8YnV0dG9uIHR5cGU9J2J1dHRvbicgY2xhc3M9J3VpLWRhdGVwaWNrZXItY3VycmVudCB1aS1zdGF0ZS1kZWZhdWx0IHVpLXByaW9yaXR5LXNlY29uZGFyeSB1aS1jb3JuZXItYWxsJyBkYXRhLWhhbmRsZXI9J3RvZGF5JyBkYXRhLWV2ZW50PSdjbGljayc+XCIrYStcIjwvYnV0dG9uPlwiOlwiXCIpKyhZP1wiXCI6aCkrXCI8L2Rpdj5cIjpcIlwiLGM9cGFyc2VJbnQodGhpcy5fZ2V0KHQsXCJmaXJzdERheVwiKSwxMCksYz1pc05hTihjKT8wOmMsdT10aGlzLl9nZXQodCxcInNob3dXZWVrXCIpLGQ9dGhpcy5fZ2V0KHQsXCJkYXlOYW1lc1wiKSxwPXRoaXMuX2dldCh0LFwiZGF5TmFtZXNNaW5cIiksZj10aGlzLl9nZXQodCxcIm1vbnRoTmFtZXNcIiksZz10aGlzLl9nZXQodCxcIm1vbnRoTmFtZXNTaG9ydFwiKSxtPXRoaXMuX2dldCh0LFwiYmVmb3JlU2hvd0RheVwiKSxfPXRoaXMuX2dldCh0LFwic2hvd090aGVyTW9udGhzXCIpLHY9dGhpcy5fZ2V0KHQsXCJzZWxlY3RPdGhlck1vbnRoc1wiKSxiPXRoaXMuX2dldERlZmF1bHREYXRlKHQpLHk9XCJcIixrPTA7VVswXT5rO2srKyl7Zm9yKHg9XCJcIix0aGlzLm1heFJvd3M9NCxDPTA7VVsxXT5DO0MrKyl7aWYoRD10aGlzLl9kYXlsaWdodFNhdmluZ0FkanVzdChuZXcgRGF0ZSh0ZSxaLHQuc2VsZWN0ZWREYXkpKSxJPVwiIHVpLWNvcm5lci1hbGxcIixUPVwiXCIsWCl7aWYoVCs9XCI8ZGl2IGNsYXNzPSd1aS1kYXRlcGlja2VyLWdyb3VwXCIsVVsxXT4xKXN3aXRjaChDKXtjYXNlIDA6VCs9XCIgdWktZGF0ZXBpY2tlci1ncm91cC1maXJzdFwiLEk9XCIgdWktY29ybmVyLVwiKyhZP1wicmlnaHRcIjpcImxlZnRcIik7XG5icmVhaztjYXNlIFVbMV0tMTpUKz1cIiB1aS1kYXRlcGlja2VyLWdyb3VwLWxhc3RcIixJPVwiIHVpLWNvcm5lci1cIisoWT9cImxlZnRcIjpcInJpZ2h0XCIpO2JyZWFrO2RlZmF1bHQ6VCs9XCIgdWktZGF0ZXBpY2tlci1ncm91cC1taWRkbGVcIixJPVwiXCJ9VCs9XCInPlwifWZvcihUKz1cIjxkaXYgY2xhc3M9J3VpLWRhdGVwaWNrZXItaGVhZGVyIHVpLXdpZGdldC1oZWFkZXIgdWktaGVscGVyLWNsZWFyZml4XCIrSStcIic+XCIrKC9hbGx8bGVmdC8udGVzdChJKSYmMD09PWs/WT9vOnM6XCJcIikrKC9hbGx8cmlnaHQvLnRlc3QoSSkmJjA9PT1rP1k/czpvOlwiXCIpK3RoaXMuX2dlbmVyYXRlTW9udGhZZWFySGVhZGVyKHQsWix0ZSxRLEosaz4wfHxDPjAsZixnKStcIjwvZGl2Pjx0YWJsZSBjbGFzcz0ndWktZGF0ZXBpY2tlci1jYWxlbmRhcic+PHRoZWFkPlwiK1wiPHRyPlwiLFA9dT9cIjx0aCBjbGFzcz0ndWktZGF0ZXBpY2tlci13ZWVrLWNvbCc+XCIrdGhpcy5fZ2V0KHQsXCJ3ZWVrSGVhZGVyXCIpK1wiPC90aD5cIjpcIlwiLHc9MDs3Pnc7dysrKU09KHcrYyklNyxQKz1cIjx0aCBzY29wZT0nY29sJ1wiKygodytjKzYpJTc+PTU/XCIgY2xhc3M9J3VpLWRhdGVwaWNrZXItd2Vlay1lbmQnXCI6XCJcIikrXCI+XCIrXCI8c3BhbiB0aXRsZT0nXCIrZFtNXStcIic+XCIrcFtNXStcIjwvc3Bhbj48L3RoPlwiO2ZvcihUKz1QK1wiPC90cj48L3RoZWFkPjx0Ym9keT5cIixTPXRoaXMuX2dldERheXNJbk1vbnRoKHRlLFopLHRlPT09dC5zZWxlY3RlZFllYXImJlo9PT10LnNlbGVjdGVkTW9udGgmJih0LnNlbGVjdGVkRGF5PU1hdGgubWluKHQuc2VsZWN0ZWREYXksUykpLEg9KHRoaXMuX2dldEZpcnN0RGF5T2ZNb250aCh0ZSxaKS1jKzcpJTcsej1NYXRoLmNlaWwoKEgrUykvNyksTz1YP3RoaXMubWF4Um93cz56P3RoaXMubWF4Um93czp6OnosdGhpcy5tYXhSb3dzPU8sQT10aGlzLl9kYXlsaWdodFNhdmluZ0FkanVzdChuZXcgRGF0ZSh0ZSxaLDEtSCkpLE49MDtPPk47TisrKXtmb3IoVCs9XCI8dHI+XCIsVz11P1wiPHRkIGNsYXNzPSd1aS1kYXRlcGlja2VyLXdlZWstY29sJz5cIit0aGlzLl9nZXQodCxcImNhbGN1bGF0ZVdlZWtcIikoQSkrXCI8L3RkPlwiOlwiXCIsdz0wOzc+dzt3KyspRT1tP20uYXBwbHkodC5pbnB1dD90LmlucHV0WzBdOm51bGwsW0FdKTpbITAsXCJcIl0sRj1BLmdldE1vbnRoKCkhPT1aLEw9RiYmIXZ8fCFFWzBdfHxRJiZRPkF8fEomJkE+SixXKz1cIjx0ZCBjbGFzcz0nXCIrKCh3K2MrNiklNz49NT9cIiB1aS1kYXRlcGlja2VyLXdlZWstZW5kXCI6XCJcIikrKEY/XCIgdWktZGF0ZXBpY2tlci1vdGhlci1tb250aFwiOlwiXCIpKyhBLmdldFRpbWUoKT09PUQuZ2V0VGltZSgpJiZaPT09dC5zZWxlY3RlZE1vbnRoJiZ0Ll9rZXlFdmVudHx8Yi5nZXRUaW1lKCk9PT1BLmdldFRpbWUoKSYmYi5nZXRUaW1lKCk9PT1ELmdldFRpbWUoKT9cIiBcIit0aGlzLl9kYXlPdmVyQ2xhc3M6XCJcIikrKEw/XCIgXCIrdGhpcy5fdW5zZWxlY3RhYmxlQ2xhc3MrXCIgdWktc3RhdGUtZGlzYWJsZWRcIjpcIlwiKSsoRiYmIV8/XCJcIjpcIiBcIitFWzFdKyhBLmdldFRpbWUoKT09PUcuZ2V0VGltZSgpP1wiIFwiK3RoaXMuX2N1cnJlbnRDbGFzczpcIlwiKSsoQS5nZXRUaW1lKCk9PT1CLmdldFRpbWUoKT9cIiB1aS1kYXRlcGlja2VyLXRvZGF5XCI6XCJcIikpK1wiJ1wiKyhGJiYhX3x8IUVbMl0/XCJcIjpcIiB0aXRsZT0nXCIrRVsyXS5yZXBsYWNlKC8nL2csXCImIzM5O1wiKStcIidcIikrKEw/XCJcIjpcIiBkYXRhLWhhbmRsZXI9J3NlbGVjdERheScgZGF0YS1ldmVudD0nY2xpY2snIGRhdGEtbW9udGg9J1wiK0EuZ2V0TW9udGgoKStcIicgZGF0YS15ZWFyPSdcIitBLmdldEZ1bGxZZWFyKCkrXCInXCIpK1wiPlwiKyhGJiYhXz9cIiYjeGEwO1wiOkw/XCI8c3BhbiBjbGFzcz0ndWktc3RhdGUtZGVmYXVsdCc+XCIrQS5nZXREYXRlKCkrXCI8L3NwYW4+XCI6XCI8YSBjbGFzcz0ndWktc3RhdGUtZGVmYXVsdFwiKyhBLmdldFRpbWUoKT09PUIuZ2V0VGltZSgpP1wiIHVpLXN0YXRlLWhpZ2hsaWdodFwiOlwiXCIpKyhBLmdldFRpbWUoKT09PUcuZ2V0VGltZSgpP1wiIHVpLXN0YXRlLWFjdGl2ZVwiOlwiXCIpKyhGP1wiIHVpLXByaW9yaXR5LXNlY29uZGFyeVwiOlwiXCIpK1wiJyBocmVmPScjJz5cIitBLmdldERhdGUoKStcIjwvYT5cIikrXCI8L3RkPlwiLEEuc2V0RGF0ZShBLmdldERhdGUoKSsxKSxBPXRoaXMuX2RheWxpZ2h0U2F2aW5nQWRqdXN0KEEpO1QrPVcrXCI8L3RyPlwifVorKyxaPjExJiYoWj0wLHRlKyspLFQrPVwiPC90Ym9keT48L3RhYmxlPlwiKyhYP1wiPC9kaXY+XCIrKFVbMF0+MCYmQz09PVVbMV0tMT9cIjxkaXYgY2xhc3M9J3VpLWRhdGVwaWNrZXItcm93LWJyZWFrJz48L2Rpdj5cIjpcIlwiKTpcIlwiKSx4Kz1UfXkrPXh9cmV0dXJuIHkrPWwsdC5fa2V5RXZlbnQ9ITEseX0sX2dlbmVyYXRlTW9udGhZZWFySGVhZGVyOmZ1bmN0aW9uKHQsZSxpLHMsbixvLGEscil7dmFyIGgsbCxjLHUsZCxwLGYsZyxtPXRoaXMuX2dldCh0LFwiY2hhbmdlTW9udGhcIiksXz10aGlzLl9nZXQodCxcImNoYW5nZVllYXJcIiksdj10aGlzLl9nZXQodCxcInNob3dNb250aEFmdGVyWWVhclwiKSxiPVwiPGRpdiBjbGFzcz0ndWktZGF0ZXBpY2tlci10aXRsZSc+XCIseT1cIlwiO2lmKG98fCFtKXkrPVwiPHNwYW4gY2xhc3M9J3VpLWRhdGVwaWNrZXItbW9udGgnPlwiK2FbZV0rXCI8L3NwYW4+XCI7ZWxzZXtmb3IoaD1zJiZzLmdldEZ1bGxZZWFyKCk9PT1pLGw9biYmbi5nZXRGdWxsWWVhcigpPT09aSx5Kz1cIjxzZWxlY3QgY2xhc3M9J3VpLWRhdGVwaWNrZXItbW9udGgnIGRhdGEtaGFuZGxlcj0nc2VsZWN0TW9udGgnIGRhdGEtZXZlbnQ9J2NoYW5nZSc+XCIsYz0wOzEyPmM7YysrKSghaHx8Yz49cy5nZXRNb250aCgpKSYmKCFsfHxuLmdldE1vbnRoKCk+PWMpJiYoeSs9XCI8b3B0aW9uIHZhbHVlPSdcIitjK1wiJ1wiKyhjPT09ZT9cIiBzZWxlY3RlZD0nc2VsZWN0ZWQnXCI6XCJcIikrXCI+XCIrcltjXStcIjwvb3B0aW9uPlwiKTt5Kz1cIjwvc2VsZWN0PlwifWlmKHZ8fChiKz15KyghbyYmbSYmXz9cIlwiOlwiJiN4YTA7XCIpKSwhdC55ZWFyc2h0bWwpaWYodC55ZWFyc2h0bWw9XCJcIixvfHwhXyliKz1cIjxzcGFuIGNsYXNzPSd1aS1kYXRlcGlja2VyLXllYXInPlwiK2krXCI8L3NwYW4+XCI7ZWxzZXtmb3IodT10aGlzLl9nZXQodCxcInllYXJSYW5nZVwiKS5zcGxpdChcIjpcIiksZD0obmV3IERhdGUpLmdldEZ1bGxZZWFyKCkscD1mdW5jdGlvbih0KXt2YXIgZT10Lm1hdGNoKC9jWytcXC1dLiovKT9pK3BhcnNlSW50KHQuc3Vic3RyaW5nKDEpLDEwKTp0Lm1hdGNoKC9bK1xcLV0uKi8pP2QrcGFyc2VJbnQodCwxMCk6cGFyc2VJbnQodCwxMCk7cmV0dXJuIGlzTmFOKGUpP2Q6ZX0sZj1wKHVbMF0pLGc9TWF0aC5tYXgoZixwKHVbMV18fFwiXCIpKSxmPXM/TWF0aC5tYXgoZixzLmdldEZ1bGxZZWFyKCkpOmYsZz1uP01hdGgubWluKGcsbi5nZXRGdWxsWWVhcigpKTpnLHQueWVhcnNodG1sKz1cIjxzZWxlY3QgY2xhc3M9J3VpLWRhdGVwaWNrZXIteWVhcicgZGF0YS1oYW5kbGVyPSdzZWxlY3RZZWFyJyBkYXRhLWV2ZW50PSdjaGFuZ2UnPlwiO2c+PWY7ZisrKXQueWVhcnNodG1sKz1cIjxvcHRpb24gdmFsdWU9J1wiK2YrXCInXCIrKGY9PT1pP1wiIHNlbGVjdGVkPSdzZWxlY3RlZCdcIjpcIlwiKStcIj5cIitmK1wiPC9vcHRpb24+XCI7dC55ZWFyc2h0bWwrPVwiPC9zZWxlY3Q+XCIsYis9dC55ZWFyc2h0bWwsdC55ZWFyc2h0bWw9bnVsbH1yZXR1cm4gYis9dGhpcy5fZ2V0KHQsXCJ5ZWFyU3VmZml4XCIpLHYmJihiKz0oIW8mJm0mJl8/XCJcIjpcIiYjeGEwO1wiKSt5KSxiKz1cIjwvZGl2PlwifSxfYWRqdXN0SW5zdERhdGU6ZnVuY3Rpb24odCxlLGkpe3ZhciBzPXQuc2VsZWN0ZWRZZWFyKyhcIllcIj09PWk/ZTowKSxuPXQuc2VsZWN0ZWRNb250aCsoXCJNXCI9PT1pP2U6MCksbz1NYXRoLm1pbih0LnNlbGVjdGVkRGF5LHRoaXMuX2dldERheXNJbk1vbnRoKHMsbikpKyhcIkRcIj09PWk/ZTowKSxhPXRoaXMuX3Jlc3RyaWN0TWluTWF4KHQsdGhpcy5fZGF5bGlnaHRTYXZpbmdBZGp1c3QobmV3IERhdGUocyxuLG8pKSk7dC5zZWxlY3RlZERheT1hLmdldERhdGUoKSx0LmRyYXdNb250aD10LnNlbGVjdGVkTW9udGg9YS5nZXRNb250aCgpLHQuZHJhd1llYXI9dC5zZWxlY3RlZFllYXI9YS5nZXRGdWxsWWVhcigpLChcIk1cIj09PWl8fFwiWVwiPT09aSkmJnRoaXMuX25vdGlmeUNoYW5nZSh0KX0sX3Jlc3RyaWN0TWluTWF4OmZ1bmN0aW9uKHQsZSl7dmFyIGk9dGhpcy5fZ2V0TWluTWF4RGF0ZSh0LFwibWluXCIpLHM9dGhpcy5fZ2V0TWluTWF4RGF0ZSh0LFwibWF4XCIpLG49aSYmaT5lP2k6ZTtyZXR1cm4gcyYmbj5zP3M6bn0sX25vdGlmeUNoYW5nZTpmdW5jdGlvbih0KXt2YXIgZT10aGlzLl9nZXQodCxcIm9uQ2hhbmdlTW9udGhZZWFyXCIpO2UmJmUuYXBwbHkodC5pbnB1dD90LmlucHV0WzBdOm51bGwsW3Quc2VsZWN0ZWRZZWFyLHQuc2VsZWN0ZWRNb250aCsxLHRdKX0sX2dldE51bWJlck9mTW9udGhzOmZ1bmN0aW9uKHQpe3ZhciBlPXRoaXMuX2dldCh0LFwibnVtYmVyT2ZNb250aHNcIik7cmV0dXJuIG51bGw9PWU/WzEsMV06XCJudW1iZXJcIj09dHlwZW9mIGU/WzEsZV06ZX0sX2dldE1pbk1heERhdGU6ZnVuY3Rpb24odCxlKXtyZXR1cm4gdGhpcy5fZGV0ZXJtaW5lRGF0ZSh0LHRoaXMuX2dldCh0LGUrXCJEYXRlXCIpLG51bGwpfSxfZ2V0RGF5c0luTW9udGg6ZnVuY3Rpb24odCxlKXtyZXR1cm4gMzItdGhpcy5fZGF5bGlnaHRTYXZpbmdBZGp1c3QobmV3IERhdGUodCxlLDMyKSkuZ2V0RGF0ZSgpfSxfZ2V0Rmlyc3REYXlPZk1vbnRoOmZ1bmN0aW9uKHQsZSl7cmV0dXJuIG5ldyBEYXRlKHQsZSwxKS5nZXREYXkoKX0sX2NhbkFkanVzdE1vbnRoOmZ1bmN0aW9uKHQsZSxpLHMpe3ZhciBuPXRoaXMuX2dldE51bWJlck9mTW9udGhzKHQpLG89dGhpcy5fZGF5bGlnaHRTYXZpbmdBZGp1c3QobmV3IERhdGUoaSxzKygwPmU/ZTpuWzBdKm5bMV0pLDEpKTtyZXR1cm4gMD5lJiZvLnNldERhdGUodGhpcy5fZ2V0RGF5c0luTW9udGgoby5nZXRGdWxsWWVhcigpLG8uZ2V0TW9udGgoKSkpLHRoaXMuX2lzSW5SYW5nZSh0LG8pfSxfaXNJblJhbmdlOmZ1bmN0aW9uKHQsZSl7dmFyIGkscyxuPXRoaXMuX2dldE1pbk1heERhdGUodCxcIm1pblwiKSxvPXRoaXMuX2dldE1pbk1heERhdGUodCxcIm1heFwiKSxhPW51bGwscj1udWxsLGg9dGhpcy5fZ2V0KHQsXCJ5ZWFyUmFuZ2VcIik7cmV0dXJuIGgmJihpPWguc3BsaXQoXCI6XCIpLHM9KG5ldyBEYXRlKS5nZXRGdWxsWWVhcigpLGE9cGFyc2VJbnQoaVswXSwxMCkscj1wYXJzZUludChpWzFdLDEwKSxpWzBdLm1hdGNoKC9bK1xcLV0uKi8pJiYoYSs9cyksaVsxXS5tYXRjaCgvWytcXC1dLiovKSYmKHIrPXMpKSwoIW58fGUuZ2V0VGltZSgpPj1uLmdldFRpbWUoKSkmJighb3x8ZS5nZXRUaW1lKCk8PW8uZ2V0VGltZSgpKSYmKCFhfHxlLmdldEZ1bGxZZWFyKCk+PWEpJiYoIXJ8fHI+PWUuZ2V0RnVsbFllYXIoKSl9LF9nZXRGb3JtYXRDb25maWc6ZnVuY3Rpb24odCl7dmFyIGU9dGhpcy5fZ2V0KHQsXCJzaG9ydFllYXJDdXRvZmZcIik7cmV0dXJuIGU9XCJzdHJpbmdcIiE9dHlwZW9mIGU/ZToobmV3IERhdGUpLmdldEZ1bGxZZWFyKCklMTAwK3BhcnNlSW50KGUsMTApLHtzaG9ydFllYXJDdXRvZmY6ZSxkYXlOYW1lc1Nob3J0OnRoaXMuX2dldCh0LFwiZGF5TmFtZXNTaG9ydFwiKSxkYXlOYW1lczp0aGlzLl9nZXQodCxcImRheU5hbWVzXCIpLG1vbnRoTmFtZXNTaG9ydDp0aGlzLl9nZXQodCxcIm1vbnRoTmFtZXNTaG9ydFwiKSxtb250aE5hbWVzOnRoaXMuX2dldCh0LFwibW9udGhOYW1lc1wiKX19LF9mb3JtYXREYXRlOmZ1bmN0aW9uKHQsZSxpLHMpe2V8fCh0LmN1cnJlbnREYXk9dC5zZWxlY3RlZERheSx0LmN1cnJlbnRNb250aD10LnNlbGVjdGVkTW9udGgsdC5jdXJyZW50WWVhcj10LnNlbGVjdGVkWWVhcik7dmFyIG49ZT9cIm9iamVjdFwiPT10eXBlb2YgZT9lOnRoaXMuX2RheWxpZ2h0U2F2aW5nQWRqdXN0KG5ldyBEYXRlKHMsaSxlKSk6dGhpcy5fZGF5bGlnaHRTYXZpbmdBZGp1c3QobmV3IERhdGUodC5jdXJyZW50WWVhcix0LmN1cnJlbnRNb250aCx0LmN1cnJlbnREYXkpKTtyZXR1cm4gdGhpcy5mb3JtYXREYXRlKHRoaXMuX2dldCh0LFwiZGF0ZUZvcm1hdFwiKSxuLHRoaXMuX2dldEZvcm1hdENvbmZpZyh0KSl9fSksdC5mbi5kYXRlcGlja2VyPWZ1bmN0aW9uKGUpe2lmKCF0aGlzLmxlbmd0aClyZXR1cm4gdGhpczt0LmRhdGVwaWNrZXIuaW5pdGlhbGl6ZWR8fCh0KGRvY3VtZW50KS5vbihcIm1vdXNlZG93blwiLHQuZGF0ZXBpY2tlci5fY2hlY2tFeHRlcm5hbENsaWNrKSx0LmRhdGVwaWNrZXIuaW5pdGlhbGl6ZWQ9ITApLDA9PT10KFwiI1wiK3QuZGF0ZXBpY2tlci5fbWFpbkRpdklkKS5sZW5ndGgmJnQoXCJib2R5XCIpLmFwcGVuZCh0LmRhdGVwaWNrZXIuZHBEaXYpO3ZhciBpPUFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cywxKTtyZXR1cm5cInN0cmluZ1wiIT10eXBlb2YgZXx8XCJpc0Rpc2FibGVkXCIhPT1lJiZcImdldERhdGVcIiE9PWUmJlwid2lkZ2V0XCIhPT1lP1wib3B0aW9uXCI9PT1lJiYyPT09YXJndW1lbnRzLmxlbmd0aCYmXCJzdHJpbmdcIj09dHlwZW9mIGFyZ3VtZW50c1sxXT90LmRhdGVwaWNrZXJbXCJfXCIrZStcIkRhdGVwaWNrZXJcIl0uYXBwbHkodC5kYXRlcGlja2VyLFt0aGlzWzBdXS5jb25jYXQoaSkpOnRoaXMuZWFjaChmdW5jdGlvbigpe1wic3RyaW5nXCI9PXR5cGVvZiBlP3QuZGF0ZXBpY2tlcltcIl9cIitlK1wiRGF0ZXBpY2tlclwiXS5hcHBseSh0LmRhdGVwaWNrZXIsW3RoaXNdLmNvbmNhdChpKSk6dC5kYXRlcGlja2VyLl9hdHRhY2hEYXRlcGlja2VyKHRoaXMsZSl9KTp0LmRhdGVwaWNrZXJbXCJfXCIrZStcIkRhdGVwaWNrZXJcIl0uYXBwbHkodC5kYXRlcGlja2VyLFt0aGlzWzBdXS5jb25jYXQoaSkpfSx0LmRhdGVwaWNrZXI9bmV3IHMsdC5kYXRlcGlja2VyLmluaXRpYWxpemVkPSExLHQuZGF0ZXBpY2tlci51dWlkPShuZXcgRGF0ZSkuZ2V0VGltZSgpLHQuZGF0ZXBpY2tlci52ZXJzaW9uPVwiMS4xMi4xXCIsdC5kYXRlcGlja2VyLHQud2lkZ2V0KFwidWkuZGlhbG9nXCIse3ZlcnNpb246XCIxLjEyLjFcIixvcHRpb25zOnthcHBlbmRUbzpcImJvZHlcIixhdXRvT3BlbjohMCxidXR0b25zOltdLGNsYXNzZXM6e1widWktZGlhbG9nXCI6XCJ1aS1jb3JuZXItYWxsXCIsXCJ1aS1kaWFsb2ctdGl0bGViYXJcIjpcInVpLWNvcm5lci1hbGxcIn0sY2xvc2VPbkVzY2FwZTohMCxjbG9zZVRleHQ6XCJDbG9zZVwiLGRyYWdnYWJsZTohMCxoaWRlOm51bGwsaGVpZ2h0OlwiYXV0b1wiLG1heEhlaWdodDpudWxsLG1heFdpZHRoOm51bGwsbWluSGVpZ2h0OjE1MCxtaW5XaWR0aDoxNTAsbW9kYWw6ITEscG9zaXRpb246e215OlwiY2VudGVyXCIsYXQ6XCJjZW50ZXJcIixvZjp3aW5kb3csY29sbGlzaW9uOlwiZml0XCIsdXNpbmc6ZnVuY3Rpb24oZSl7dmFyIGk9dCh0aGlzKS5jc3MoZSkub2Zmc2V0KCkudG9wOzA+aSYmdCh0aGlzKS5jc3MoXCJ0b3BcIixlLnRvcC1pKX19LHJlc2l6YWJsZTohMCxzaG93Om51bGwsdGl0bGU6bnVsbCx3aWR0aDozMDAsYmVmb3JlQ2xvc2U6bnVsbCxjbG9zZTpudWxsLGRyYWc6bnVsbCxkcmFnU3RhcnQ6bnVsbCxkcmFnU3RvcDpudWxsLGZvY3VzOm51bGwsb3BlbjpudWxsLHJlc2l6ZTpudWxsLHJlc2l6ZVN0YXJ0Om51bGwscmVzaXplU3RvcDpudWxsfSxzaXplUmVsYXRlZE9wdGlvbnM6e2J1dHRvbnM6ITAsaGVpZ2h0OiEwLG1heEhlaWdodDohMCxtYXhXaWR0aDohMCxtaW5IZWlnaHQ6ITAsbWluV2lkdGg6ITAsd2lkdGg6ITB9LHJlc2l6YWJsZVJlbGF0ZWRPcHRpb25zOnttYXhIZWlnaHQ6ITAsbWF4V2lkdGg6ITAsbWluSGVpZ2h0OiEwLG1pbldpZHRoOiEwfSxfY3JlYXRlOmZ1bmN0aW9uKCl7dGhpcy5vcmlnaW5hbENzcz17ZGlzcGxheTp0aGlzLmVsZW1lbnRbMF0uc3R5bGUuZGlzcGxheSx3aWR0aDp0aGlzLmVsZW1lbnRbMF0uc3R5bGUud2lkdGgsbWluSGVpZ2h0OnRoaXMuZWxlbWVudFswXS5zdHlsZS5taW5IZWlnaHQsbWF4SGVpZ2h0OnRoaXMuZWxlbWVudFswXS5zdHlsZS5tYXhIZWlnaHQsaGVpZ2h0OnRoaXMuZWxlbWVudFswXS5zdHlsZS5oZWlnaHR9LHRoaXMub3JpZ2luYWxQb3NpdGlvbj17cGFyZW50OnRoaXMuZWxlbWVudC5wYXJlbnQoKSxpbmRleDp0aGlzLmVsZW1lbnQucGFyZW50KCkuY2hpbGRyZW4oKS5pbmRleCh0aGlzLmVsZW1lbnQpfSx0aGlzLm9yaWdpbmFsVGl0bGU9dGhpcy5lbGVtZW50LmF0dHIoXCJ0aXRsZVwiKSxudWxsPT10aGlzLm9wdGlvbnMudGl0bGUmJm51bGwhPXRoaXMub3JpZ2luYWxUaXRsZSYmKHRoaXMub3B0aW9ucy50aXRsZT10aGlzLm9yaWdpbmFsVGl0bGUpLHRoaXMub3B0aW9ucy5kaXNhYmxlZCYmKHRoaXMub3B0aW9ucy5kaXNhYmxlZD0hMSksdGhpcy5fY3JlYXRlV3JhcHBlcigpLHRoaXMuZWxlbWVudC5zaG93KCkucmVtb3ZlQXR0cihcInRpdGxlXCIpLmFwcGVuZFRvKHRoaXMudWlEaWFsb2cpLHRoaXMuX2FkZENsYXNzKFwidWktZGlhbG9nLWNvbnRlbnRcIixcInVpLXdpZGdldC1jb250ZW50XCIpLHRoaXMuX2NyZWF0ZVRpdGxlYmFyKCksdGhpcy5fY3JlYXRlQnV0dG9uUGFuZSgpLHRoaXMub3B0aW9ucy5kcmFnZ2FibGUmJnQuZm4uZHJhZ2dhYmxlJiZ0aGlzLl9tYWtlRHJhZ2dhYmxlKCksdGhpcy5vcHRpb25zLnJlc2l6YWJsZSYmdC5mbi5yZXNpemFibGUmJnRoaXMuX21ha2VSZXNpemFibGUoKSx0aGlzLl9pc09wZW49ITEsdGhpcy5fdHJhY2tGb2N1cygpfSxfaW5pdDpmdW5jdGlvbigpe3RoaXMub3B0aW9ucy5hdXRvT3BlbiYmdGhpcy5vcGVuKCl9LF9hcHBlbmRUbzpmdW5jdGlvbigpe3ZhciBlPXRoaXMub3B0aW9ucy5hcHBlbmRUbztyZXR1cm4gZSYmKGUuanF1ZXJ5fHxlLm5vZGVUeXBlKT90KGUpOnRoaXMuZG9jdW1lbnQuZmluZChlfHxcImJvZHlcIikuZXEoMCl9LF9kZXN0cm95OmZ1bmN0aW9uKCl7dmFyIHQsZT10aGlzLm9yaWdpbmFsUG9zaXRpb247dGhpcy5fdW50cmFja0luc3RhbmNlKCksdGhpcy5fZGVzdHJveU92ZXJsYXkoKSx0aGlzLmVsZW1lbnQucmVtb3ZlVW5pcXVlSWQoKS5jc3ModGhpcy5vcmlnaW5hbENzcykuZGV0YWNoKCksdGhpcy51aURpYWxvZy5yZW1vdmUoKSx0aGlzLm9yaWdpbmFsVGl0bGUmJnRoaXMuZWxlbWVudC5hdHRyKFwidGl0bGVcIix0aGlzLm9yaWdpbmFsVGl0bGUpLHQ9ZS5wYXJlbnQuY2hpbGRyZW4oKS5lcShlLmluZGV4KSx0Lmxlbmd0aCYmdFswXSE9PXRoaXMuZWxlbWVudFswXT90LmJlZm9yZSh0aGlzLmVsZW1lbnQpOmUucGFyZW50LmFwcGVuZCh0aGlzLmVsZW1lbnQpfSx3aWRnZXQ6ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy51aURpYWxvZ30sZGlzYWJsZTp0Lm5vb3AsZW5hYmxlOnQubm9vcCxjbG9zZTpmdW5jdGlvbihlKXt2YXIgaT10aGlzO3RoaXMuX2lzT3BlbiYmdGhpcy5fdHJpZ2dlcihcImJlZm9yZUNsb3NlXCIsZSkhPT0hMSYmKHRoaXMuX2lzT3Blbj0hMSx0aGlzLl9mb2N1c2VkRWxlbWVudD1udWxsLHRoaXMuX2Rlc3Ryb3lPdmVybGF5KCksdGhpcy5fdW50cmFja0luc3RhbmNlKCksdGhpcy5vcGVuZXIuZmlsdGVyKFwiOmZvY3VzYWJsZVwiKS50cmlnZ2VyKFwiZm9jdXNcIikubGVuZ3RofHx0LnVpLnNhZmVCbHVyKHQudWkuc2FmZUFjdGl2ZUVsZW1lbnQodGhpcy5kb2N1bWVudFswXSkpLHRoaXMuX2hpZGUodGhpcy51aURpYWxvZyx0aGlzLm9wdGlvbnMuaGlkZSxmdW5jdGlvbigpe2kuX3RyaWdnZXIoXCJjbG9zZVwiLGUpfSkpfSxpc09wZW46ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5faXNPcGVufSxtb3ZlVG9Ub3A6ZnVuY3Rpb24oKXt0aGlzLl9tb3ZlVG9Ub3AoKX0sX21vdmVUb1RvcDpmdW5jdGlvbihlLGkpe3ZhciBzPSExLG49dGhpcy51aURpYWxvZy5zaWJsaW5ncyhcIi51aS1mcm9udDp2aXNpYmxlXCIpLm1hcChmdW5jdGlvbigpe3JldHVybit0KHRoaXMpLmNzcyhcInotaW5kZXhcIil9KS5nZXQoKSxvPU1hdGgubWF4LmFwcGx5KG51bGwsbik7cmV0dXJuIG8+PSt0aGlzLnVpRGlhbG9nLmNzcyhcInotaW5kZXhcIikmJih0aGlzLnVpRGlhbG9nLmNzcyhcInotaW5kZXhcIixvKzEpLHM9ITApLHMmJiFpJiZ0aGlzLl90cmlnZ2VyKFwiZm9jdXNcIixlKSxzfSxvcGVuOmZ1bmN0aW9uKCl7dmFyIGU9dGhpcztyZXR1cm4gdGhpcy5faXNPcGVuPyh0aGlzLl9tb3ZlVG9Ub3AoKSYmdGhpcy5fZm9jdXNUYWJiYWJsZSgpLHZvaWQgMCk6KHRoaXMuX2lzT3Blbj0hMCx0aGlzLm9wZW5lcj10KHQudWkuc2FmZUFjdGl2ZUVsZW1lbnQodGhpcy5kb2N1bWVudFswXSkpLHRoaXMuX3NpemUoKSx0aGlzLl9wb3NpdGlvbigpLHRoaXMuX2NyZWF0ZU92ZXJsYXkoKSx0aGlzLl9tb3ZlVG9Ub3AobnVsbCwhMCksdGhpcy5vdmVybGF5JiZ0aGlzLm92ZXJsYXkuY3NzKFwiei1pbmRleFwiLHRoaXMudWlEaWFsb2cuY3NzKFwiei1pbmRleFwiKS0xKSx0aGlzLl9zaG93KHRoaXMudWlEaWFsb2csdGhpcy5vcHRpb25zLnNob3csZnVuY3Rpb24oKXtlLl9mb2N1c1RhYmJhYmxlKCksZS5fdHJpZ2dlcihcImZvY3VzXCIpfSksdGhpcy5fbWFrZUZvY3VzVGFyZ2V0KCksdGhpcy5fdHJpZ2dlcihcIm9wZW5cIiksdm9pZCAwKX0sX2ZvY3VzVGFiYmFibGU6ZnVuY3Rpb24oKXt2YXIgdD10aGlzLl9mb2N1c2VkRWxlbWVudDt0fHwodD10aGlzLmVsZW1lbnQuZmluZChcIlthdXRvZm9jdXNdXCIpKSx0Lmxlbmd0aHx8KHQ9dGhpcy5lbGVtZW50LmZpbmQoXCI6dGFiYmFibGVcIikpLHQubGVuZ3RofHwodD10aGlzLnVpRGlhbG9nQnV0dG9uUGFuZS5maW5kKFwiOnRhYmJhYmxlXCIpKSx0Lmxlbmd0aHx8KHQ9dGhpcy51aURpYWxvZ1RpdGxlYmFyQ2xvc2UuZmlsdGVyKFwiOnRhYmJhYmxlXCIpKSx0Lmxlbmd0aHx8KHQ9dGhpcy51aURpYWxvZyksdC5lcSgwKS50cmlnZ2VyKFwiZm9jdXNcIil9LF9rZWVwRm9jdXM6ZnVuY3Rpb24oZSl7ZnVuY3Rpb24gaSgpe3ZhciBlPXQudWkuc2FmZUFjdGl2ZUVsZW1lbnQodGhpcy5kb2N1bWVudFswXSksaT10aGlzLnVpRGlhbG9nWzBdPT09ZXx8dC5jb250YWlucyh0aGlzLnVpRGlhbG9nWzBdLGUpO2l8fHRoaXMuX2ZvY3VzVGFiYmFibGUoKX1lLnByZXZlbnREZWZhdWx0KCksaS5jYWxsKHRoaXMpLHRoaXMuX2RlbGF5KGkpfSxfY3JlYXRlV3JhcHBlcjpmdW5jdGlvbigpe3RoaXMudWlEaWFsb2c9dChcIjxkaXY+XCIpLmhpZGUoKS5hdHRyKHt0YWJJbmRleDotMSxyb2xlOlwiZGlhbG9nXCJ9KS5hcHBlbmRUbyh0aGlzLl9hcHBlbmRUbygpKSx0aGlzLl9hZGRDbGFzcyh0aGlzLnVpRGlhbG9nLFwidWktZGlhbG9nXCIsXCJ1aS13aWRnZXQgdWktd2lkZ2V0LWNvbnRlbnQgdWktZnJvbnRcIiksdGhpcy5fb24odGhpcy51aURpYWxvZyx7a2V5ZG93bjpmdW5jdGlvbihlKXtpZih0aGlzLm9wdGlvbnMuY2xvc2VPbkVzY2FwZSYmIWUuaXNEZWZhdWx0UHJldmVudGVkKCkmJmUua2V5Q29kZSYmZS5rZXlDb2RlPT09dC51aS5rZXlDb2RlLkVTQ0FQRSlyZXR1cm4gZS5wcmV2ZW50RGVmYXVsdCgpLHRoaXMuY2xvc2UoZSksdm9pZCAwO2lmKGUua2V5Q29kZT09PXQudWkua2V5Q29kZS5UQUImJiFlLmlzRGVmYXVsdFByZXZlbnRlZCgpKXt2YXIgaT10aGlzLnVpRGlhbG9nLmZpbmQoXCI6dGFiYmFibGVcIikscz1pLmZpbHRlcihcIjpmaXJzdFwiKSxuPWkuZmlsdGVyKFwiOmxhc3RcIik7ZS50YXJnZXQhPT1uWzBdJiZlLnRhcmdldCE9PXRoaXMudWlEaWFsb2dbMF18fGUuc2hpZnRLZXk/ZS50YXJnZXQhPT1zWzBdJiZlLnRhcmdldCE9PXRoaXMudWlEaWFsb2dbMF18fCFlLnNoaWZ0S2V5fHwodGhpcy5fZGVsYXkoZnVuY3Rpb24oKXtuLnRyaWdnZXIoXCJmb2N1c1wiKX0pLGUucHJldmVudERlZmF1bHQoKSk6KHRoaXMuX2RlbGF5KGZ1bmN0aW9uKCl7cy50cmlnZ2VyKFwiZm9jdXNcIil9KSxlLnByZXZlbnREZWZhdWx0KCkpfX0sbW91c2Vkb3duOmZ1bmN0aW9uKHQpe3RoaXMuX21vdmVUb1RvcCh0KSYmdGhpcy5fZm9jdXNUYWJiYWJsZSgpfX0pLHRoaXMuZWxlbWVudC5maW5kKFwiW2FyaWEtZGVzY3JpYmVkYnldXCIpLmxlbmd0aHx8dGhpcy51aURpYWxvZy5hdHRyKHtcImFyaWEtZGVzY3JpYmVkYnlcIjp0aGlzLmVsZW1lbnQudW5pcXVlSWQoKS5hdHRyKFwiaWRcIil9KX0sX2NyZWF0ZVRpdGxlYmFyOmZ1bmN0aW9uKCl7dmFyIGU7dGhpcy51aURpYWxvZ1RpdGxlYmFyPXQoXCI8ZGl2PlwiKSx0aGlzLl9hZGRDbGFzcyh0aGlzLnVpRGlhbG9nVGl0bGViYXIsXCJ1aS1kaWFsb2ctdGl0bGViYXJcIixcInVpLXdpZGdldC1oZWFkZXIgdWktaGVscGVyLWNsZWFyZml4XCIpLHRoaXMuX29uKHRoaXMudWlEaWFsb2dUaXRsZWJhcix7bW91c2Vkb3duOmZ1bmN0aW9uKGUpe3QoZS50YXJnZXQpLmNsb3Nlc3QoXCIudWktZGlhbG9nLXRpdGxlYmFyLWNsb3NlXCIpfHx0aGlzLnVpRGlhbG9nLnRyaWdnZXIoXCJmb2N1c1wiKX19KSx0aGlzLnVpRGlhbG9nVGl0bGViYXJDbG9zZT10KFwiPGJ1dHRvbiB0eXBlPSdidXR0b24nPjwvYnV0dG9uPlwiKS5idXR0b24oe2xhYmVsOnQoXCI8YT5cIikudGV4dCh0aGlzLm9wdGlvbnMuY2xvc2VUZXh0KS5odG1sKCksaWNvbjpcInVpLWljb24tY2xvc2V0aGlja1wiLHNob3dMYWJlbDohMX0pLmFwcGVuZFRvKHRoaXMudWlEaWFsb2dUaXRsZWJhciksdGhpcy5fYWRkQ2xhc3ModGhpcy51aURpYWxvZ1RpdGxlYmFyQ2xvc2UsXCJ1aS1kaWFsb2ctdGl0bGViYXItY2xvc2VcIiksdGhpcy5fb24odGhpcy51aURpYWxvZ1RpdGxlYmFyQ2xvc2Use2NsaWNrOmZ1bmN0aW9uKHQpe3QucHJldmVudERlZmF1bHQoKSx0aGlzLmNsb3NlKHQpfX0pLGU9dChcIjxzcGFuPlwiKS51bmlxdWVJZCgpLnByZXBlbmRUbyh0aGlzLnVpRGlhbG9nVGl0bGViYXIpLHRoaXMuX2FkZENsYXNzKGUsXCJ1aS1kaWFsb2ctdGl0bGVcIiksdGhpcy5fdGl0bGUoZSksdGhpcy51aURpYWxvZ1RpdGxlYmFyLnByZXBlbmRUbyh0aGlzLnVpRGlhbG9nKSx0aGlzLnVpRGlhbG9nLmF0dHIoe1wiYXJpYS1sYWJlbGxlZGJ5XCI6ZS5hdHRyKFwiaWRcIil9KX0sX3RpdGxlOmZ1bmN0aW9uKHQpe3RoaXMub3B0aW9ucy50aXRsZT90LnRleHQodGhpcy5vcHRpb25zLnRpdGxlKTp0Lmh0bWwoXCImIzE2MDtcIil9LF9jcmVhdGVCdXR0b25QYW5lOmZ1bmN0aW9uKCl7dGhpcy51aURpYWxvZ0J1dHRvblBhbmU9dChcIjxkaXY+XCIpLHRoaXMuX2FkZENsYXNzKHRoaXMudWlEaWFsb2dCdXR0b25QYW5lLFwidWktZGlhbG9nLWJ1dHRvbnBhbmVcIixcInVpLXdpZGdldC1jb250ZW50IHVpLWhlbHBlci1jbGVhcmZpeFwiKSx0aGlzLnVpQnV0dG9uU2V0PXQoXCI8ZGl2PlwiKS5hcHBlbmRUbyh0aGlzLnVpRGlhbG9nQnV0dG9uUGFuZSksdGhpcy5fYWRkQ2xhc3ModGhpcy51aUJ1dHRvblNldCxcInVpLWRpYWxvZy1idXR0b25zZXRcIiksdGhpcy5fY3JlYXRlQnV0dG9ucygpfSxfY3JlYXRlQnV0dG9uczpmdW5jdGlvbigpe3ZhciBlPXRoaXMsaT10aGlzLm9wdGlvbnMuYnV0dG9ucztyZXR1cm4gdGhpcy51aURpYWxvZ0J1dHRvblBhbmUucmVtb3ZlKCksdGhpcy51aUJ1dHRvblNldC5lbXB0eSgpLHQuaXNFbXB0eU9iamVjdChpKXx8dC5pc0FycmF5KGkpJiYhaS5sZW5ndGg/KHRoaXMuX3JlbW92ZUNsYXNzKHRoaXMudWlEaWFsb2csXCJ1aS1kaWFsb2ctYnV0dG9uc1wiKSx2b2lkIDApOih0LmVhY2goaSxmdW5jdGlvbihpLHMpe3ZhciBuLG87cz10LmlzRnVuY3Rpb24ocyk/e2NsaWNrOnMsdGV4dDppfTpzLHM9dC5leHRlbmQoe3R5cGU6XCJidXR0b25cIn0scyksbj1zLmNsaWNrLG89e2ljb246cy5pY29uLGljb25Qb3NpdGlvbjpzLmljb25Qb3NpdGlvbixzaG93TGFiZWw6cy5zaG93TGFiZWwsaWNvbnM6cy5pY29ucyx0ZXh0OnMudGV4dH0sZGVsZXRlIHMuY2xpY2ssZGVsZXRlIHMuaWNvbixkZWxldGUgcy5pY29uUG9zaXRpb24sZGVsZXRlIHMuc2hvd0xhYmVsLGRlbGV0ZSBzLmljb25zLFwiYm9vbGVhblwiPT10eXBlb2Ygcy50ZXh0JiZkZWxldGUgcy50ZXh0LHQoXCI8YnV0dG9uPjwvYnV0dG9uPlwiLHMpLmJ1dHRvbihvKS5hcHBlbmRUbyhlLnVpQnV0dG9uU2V0KS5vbihcImNsaWNrXCIsZnVuY3Rpb24oKXtuLmFwcGx5KGUuZWxlbWVudFswXSxhcmd1bWVudHMpfSl9KSx0aGlzLl9hZGRDbGFzcyh0aGlzLnVpRGlhbG9nLFwidWktZGlhbG9nLWJ1dHRvbnNcIiksdGhpcy51aURpYWxvZ0J1dHRvblBhbmUuYXBwZW5kVG8odGhpcy51aURpYWxvZyksdm9pZCAwKX0sX21ha2VEcmFnZ2FibGU6ZnVuY3Rpb24oKXtmdW5jdGlvbiBlKHQpe3JldHVybntwb3NpdGlvbjp0LnBvc2l0aW9uLG9mZnNldDp0Lm9mZnNldH19dmFyIGk9dGhpcyxzPXRoaXMub3B0aW9uczt0aGlzLnVpRGlhbG9nLmRyYWdnYWJsZSh7Y2FuY2VsOlwiLnVpLWRpYWxvZy1jb250ZW50LCAudWktZGlhbG9nLXRpdGxlYmFyLWNsb3NlXCIsaGFuZGxlOlwiLnVpLWRpYWxvZy10aXRsZWJhclwiLGNvbnRhaW5tZW50OlwiZG9jdW1lbnRcIixzdGFydDpmdW5jdGlvbihzLG4pe2kuX2FkZENsYXNzKHQodGhpcyksXCJ1aS1kaWFsb2ctZHJhZ2dpbmdcIiksaS5fYmxvY2tGcmFtZXMoKSxpLl90cmlnZ2VyKFwiZHJhZ1N0YXJ0XCIscyxlKG4pKX0sZHJhZzpmdW5jdGlvbih0LHMpe2kuX3RyaWdnZXIoXCJkcmFnXCIsdCxlKHMpKX0sc3RvcDpmdW5jdGlvbihuLG8pe3ZhciBhPW8ub2Zmc2V0LmxlZnQtaS5kb2N1bWVudC5zY3JvbGxMZWZ0KCkscj1vLm9mZnNldC50b3AtaS5kb2N1bWVudC5zY3JvbGxUb3AoKTtzLnBvc2l0aW9uPXtteTpcImxlZnQgdG9wXCIsYXQ6XCJsZWZ0XCIrKGE+PTA/XCIrXCI6XCJcIikrYStcIiBcIitcInRvcFwiKyhyPj0wP1wiK1wiOlwiXCIpK3Isb2Y6aS53aW5kb3d9LGkuX3JlbW92ZUNsYXNzKHQodGhpcyksXCJ1aS1kaWFsb2ctZHJhZ2dpbmdcIiksaS5fdW5ibG9ja0ZyYW1lcygpLGkuX3RyaWdnZXIoXCJkcmFnU3RvcFwiLG4sZShvKSl9fSl9LF9tYWtlUmVzaXphYmxlOmZ1bmN0aW9uKCl7ZnVuY3Rpb24gZSh0KXtyZXR1cm57b3JpZ2luYWxQb3NpdGlvbjp0Lm9yaWdpbmFsUG9zaXRpb24sb3JpZ2luYWxTaXplOnQub3JpZ2luYWxTaXplLHBvc2l0aW9uOnQucG9zaXRpb24sc2l6ZTp0LnNpemV9fXZhciBpPXRoaXMscz10aGlzLm9wdGlvbnMsbj1zLnJlc2l6YWJsZSxvPXRoaXMudWlEaWFsb2cuY3NzKFwicG9zaXRpb25cIiksYT1cInN0cmluZ1wiPT10eXBlb2Ygbj9uOlwibixlLHMsdyxzZSxzdyxuZSxud1wiO3RoaXMudWlEaWFsb2cucmVzaXphYmxlKHtjYW5jZWw6XCIudWktZGlhbG9nLWNvbnRlbnRcIixjb250YWlubWVudDpcImRvY3VtZW50XCIsYWxzb1Jlc2l6ZTp0aGlzLmVsZW1lbnQsbWF4V2lkdGg6cy5tYXhXaWR0aCxtYXhIZWlnaHQ6cy5tYXhIZWlnaHQsbWluV2lkdGg6cy5taW5XaWR0aCxtaW5IZWlnaHQ6dGhpcy5fbWluSGVpZ2h0KCksaGFuZGxlczphLHN0YXJ0OmZ1bmN0aW9uKHMsbil7aS5fYWRkQ2xhc3ModCh0aGlzKSxcInVpLWRpYWxvZy1yZXNpemluZ1wiKSxpLl9ibG9ja0ZyYW1lcygpLGkuX3RyaWdnZXIoXCJyZXNpemVTdGFydFwiLHMsZShuKSl9LHJlc2l6ZTpmdW5jdGlvbih0LHMpe2kuX3RyaWdnZXIoXCJyZXNpemVcIix0LGUocykpfSxzdG9wOmZ1bmN0aW9uKG4sbyl7dmFyIGE9aS51aURpYWxvZy5vZmZzZXQoKSxyPWEubGVmdC1pLmRvY3VtZW50LnNjcm9sbExlZnQoKSxoPWEudG9wLWkuZG9jdW1lbnQuc2Nyb2xsVG9wKCk7cy5oZWlnaHQ9aS51aURpYWxvZy5oZWlnaHQoKSxzLndpZHRoPWkudWlEaWFsb2cud2lkdGgoKSxzLnBvc2l0aW9uPXtteTpcImxlZnQgdG9wXCIsYXQ6XCJsZWZ0XCIrKHI+PTA/XCIrXCI6XCJcIikrcitcIiBcIitcInRvcFwiKyhoPj0wP1wiK1wiOlwiXCIpK2gsb2Y6aS53aW5kb3d9LGkuX3JlbW92ZUNsYXNzKHQodGhpcyksXCJ1aS1kaWFsb2ctcmVzaXppbmdcIiksaS5fdW5ibG9ja0ZyYW1lcygpLGkuX3RyaWdnZXIoXCJyZXNpemVTdG9wXCIsbixlKG8pKX19KS5jc3MoXCJwb3NpdGlvblwiLG8pfSxfdHJhY2tGb2N1czpmdW5jdGlvbigpe3RoaXMuX29uKHRoaXMud2lkZ2V0KCkse2ZvY3VzaW46ZnVuY3Rpb24oZSl7dGhpcy5fbWFrZUZvY3VzVGFyZ2V0KCksdGhpcy5fZm9jdXNlZEVsZW1lbnQ9dChlLnRhcmdldCl9fSl9LF9tYWtlRm9jdXNUYXJnZXQ6ZnVuY3Rpb24oKXt0aGlzLl91bnRyYWNrSW5zdGFuY2UoKSx0aGlzLl90cmFja2luZ0luc3RhbmNlcygpLnVuc2hpZnQodGhpcyl9LF91bnRyYWNrSW5zdGFuY2U6ZnVuY3Rpb24oKXt2YXIgZT10aGlzLl90cmFja2luZ0luc3RhbmNlcygpLGk9dC5pbkFycmF5KHRoaXMsZSk7LTEhPT1pJiZlLnNwbGljZShpLDEpfSxfdHJhY2tpbmdJbnN0YW5jZXM6ZnVuY3Rpb24oKXt2YXIgdD10aGlzLmRvY3VtZW50LmRhdGEoXCJ1aS1kaWFsb2ctaW5zdGFuY2VzXCIpO3JldHVybiB0fHwodD1bXSx0aGlzLmRvY3VtZW50LmRhdGEoXCJ1aS1kaWFsb2ctaW5zdGFuY2VzXCIsdCkpLHR9LF9taW5IZWlnaHQ6ZnVuY3Rpb24oKXt2YXIgdD10aGlzLm9wdGlvbnM7cmV0dXJuXCJhdXRvXCI9PT10LmhlaWdodD90Lm1pbkhlaWdodDpNYXRoLm1pbih0Lm1pbkhlaWdodCx0LmhlaWdodCl9LF9wb3NpdGlvbjpmdW5jdGlvbigpe3ZhciB0PXRoaXMudWlEaWFsb2cuaXMoXCI6dmlzaWJsZVwiKTt0fHx0aGlzLnVpRGlhbG9nLnNob3coKSx0aGlzLnVpRGlhbG9nLnBvc2l0aW9uKHRoaXMub3B0aW9ucy5wb3NpdGlvbiksdHx8dGhpcy51aURpYWxvZy5oaWRlKCl9LF9zZXRPcHRpb25zOmZ1bmN0aW9uKGUpe3ZhciBpPXRoaXMscz0hMSxuPXt9O3QuZWFjaChlLGZ1bmN0aW9uKHQsZSl7aS5fc2V0T3B0aW9uKHQsZSksdCBpbiBpLnNpemVSZWxhdGVkT3B0aW9ucyYmKHM9ITApLHQgaW4gaS5yZXNpemFibGVSZWxhdGVkT3B0aW9ucyYmKG5bdF09ZSl9KSxzJiYodGhpcy5fc2l6ZSgpLHRoaXMuX3Bvc2l0aW9uKCkpLHRoaXMudWlEaWFsb2cuaXMoXCI6ZGF0YSh1aS1yZXNpemFibGUpXCIpJiZ0aGlzLnVpRGlhbG9nLnJlc2l6YWJsZShcIm9wdGlvblwiLG4pfSxfc2V0T3B0aW9uOmZ1bmN0aW9uKGUsaSl7dmFyIHMsbixvPXRoaXMudWlEaWFsb2c7XCJkaXNhYmxlZFwiIT09ZSYmKHRoaXMuX3N1cGVyKGUsaSksXCJhcHBlbmRUb1wiPT09ZSYmdGhpcy51aURpYWxvZy5hcHBlbmRUbyh0aGlzLl9hcHBlbmRUbygpKSxcImJ1dHRvbnNcIj09PWUmJnRoaXMuX2NyZWF0ZUJ1dHRvbnMoKSxcImNsb3NlVGV4dFwiPT09ZSYmdGhpcy51aURpYWxvZ1RpdGxlYmFyQ2xvc2UuYnV0dG9uKHtsYWJlbDp0KFwiPGE+XCIpLnRleHQoXCJcIit0aGlzLm9wdGlvbnMuY2xvc2VUZXh0KS5odG1sKCl9KSxcImRyYWdnYWJsZVwiPT09ZSYmKHM9by5pcyhcIjpkYXRhKHVpLWRyYWdnYWJsZSlcIikscyYmIWkmJm8uZHJhZ2dhYmxlKFwiZGVzdHJveVwiKSwhcyYmaSYmdGhpcy5fbWFrZURyYWdnYWJsZSgpKSxcInBvc2l0aW9uXCI9PT1lJiZ0aGlzLl9wb3NpdGlvbigpLFwicmVzaXphYmxlXCI9PT1lJiYobj1vLmlzKFwiOmRhdGEodWktcmVzaXphYmxlKVwiKSxuJiYhaSYmby5yZXNpemFibGUoXCJkZXN0cm95XCIpLG4mJlwic3RyaW5nXCI9PXR5cGVvZiBpJiZvLnJlc2l6YWJsZShcIm9wdGlvblwiLFwiaGFuZGxlc1wiLGkpLG58fGk9PT0hMXx8dGhpcy5fbWFrZVJlc2l6YWJsZSgpKSxcInRpdGxlXCI9PT1lJiZ0aGlzLl90aXRsZSh0aGlzLnVpRGlhbG9nVGl0bGViYXIuZmluZChcIi51aS1kaWFsb2ctdGl0bGVcIikpKX0sX3NpemU6ZnVuY3Rpb24oKXt2YXIgdCxlLGkscz10aGlzLm9wdGlvbnM7dGhpcy5lbGVtZW50LnNob3coKS5jc3Moe3dpZHRoOlwiYXV0b1wiLG1pbkhlaWdodDowLG1heEhlaWdodDpcIm5vbmVcIixoZWlnaHQ6MH0pLHMubWluV2lkdGg+cy53aWR0aCYmKHMud2lkdGg9cy5taW5XaWR0aCksdD10aGlzLnVpRGlhbG9nLmNzcyh7aGVpZ2h0OlwiYXV0b1wiLHdpZHRoOnMud2lkdGh9KS5vdXRlckhlaWdodCgpLGU9TWF0aC5tYXgoMCxzLm1pbkhlaWdodC10KSxpPVwibnVtYmVyXCI9PXR5cGVvZiBzLm1heEhlaWdodD9NYXRoLm1heCgwLHMubWF4SGVpZ2h0LXQpOlwibm9uZVwiLFwiYXV0b1wiPT09cy5oZWlnaHQ/dGhpcy5lbGVtZW50LmNzcyh7bWluSGVpZ2h0OmUsbWF4SGVpZ2h0OmksaGVpZ2h0OlwiYXV0b1wifSk6dGhpcy5lbGVtZW50LmhlaWdodChNYXRoLm1heCgwLHMuaGVpZ2h0LXQpKSx0aGlzLnVpRGlhbG9nLmlzKFwiOmRhdGEodWktcmVzaXphYmxlKVwiKSYmdGhpcy51aURpYWxvZy5yZXNpemFibGUoXCJvcHRpb25cIixcIm1pbkhlaWdodFwiLHRoaXMuX21pbkhlaWdodCgpKX0sX2Jsb2NrRnJhbWVzOmZ1bmN0aW9uKCl7dGhpcy5pZnJhbWVCbG9ja3M9dGhpcy5kb2N1bWVudC5maW5kKFwiaWZyYW1lXCIpLm1hcChmdW5jdGlvbigpe3ZhciBlPXQodGhpcyk7cmV0dXJuIHQoXCI8ZGl2PlwiKS5jc3Moe3Bvc2l0aW9uOlwiYWJzb2x1dGVcIix3aWR0aDplLm91dGVyV2lkdGgoKSxoZWlnaHQ6ZS5vdXRlckhlaWdodCgpfSkuYXBwZW5kVG8oZS5wYXJlbnQoKSkub2Zmc2V0KGUub2Zmc2V0KCkpWzBdfSl9LF91bmJsb2NrRnJhbWVzOmZ1bmN0aW9uKCl7dGhpcy5pZnJhbWVCbG9ja3MmJih0aGlzLmlmcmFtZUJsb2Nrcy5yZW1vdmUoKSxkZWxldGUgdGhpcy5pZnJhbWVCbG9ja3MpfSxfYWxsb3dJbnRlcmFjdGlvbjpmdW5jdGlvbihlKXtyZXR1cm4gdChlLnRhcmdldCkuY2xvc2VzdChcIi51aS1kaWFsb2dcIikubGVuZ3RoPyEwOiEhdChlLnRhcmdldCkuY2xvc2VzdChcIi51aS1kYXRlcGlja2VyXCIpLmxlbmd0aH0sX2NyZWF0ZU92ZXJsYXk6ZnVuY3Rpb24oKXtpZih0aGlzLm9wdGlvbnMubW9kYWwpe3ZhciBlPSEwO3RoaXMuX2RlbGF5KGZ1bmN0aW9uKCl7ZT0hMX0pLHRoaXMuZG9jdW1lbnQuZGF0YShcInVpLWRpYWxvZy1vdmVybGF5c1wiKXx8dGhpcy5fb24odGhpcy5kb2N1bWVudCx7Zm9jdXNpbjpmdW5jdGlvbih0KXtlfHx0aGlzLl9hbGxvd0ludGVyYWN0aW9uKHQpfHwodC5wcmV2ZW50RGVmYXVsdCgpLHRoaXMuX3RyYWNraW5nSW5zdGFuY2VzKClbMF0uX2ZvY3VzVGFiYmFibGUoKSl9fSksdGhpcy5vdmVybGF5PXQoXCI8ZGl2PlwiKS5hcHBlbmRUbyh0aGlzLl9hcHBlbmRUbygpKSx0aGlzLl9hZGRDbGFzcyh0aGlzLm92ZXJsYXksbnVsbCxcInVpLXdpZGdldC1vdmVybGF5IHVpLWZyb250XCIpLHRoaXMuX29uKHRoaXMub3ZlcmxheSx7bW91c2Vkb3duOlwiX2tlZXBGb2N1c1wifSksdGhpcy5kb2N1bWVudC5kYXRhKFwidWktZGlhbG9nLW92ZXJsYXlzXCIsKHRoaXMuZG9jdW1lbnQuZGF0YShcInVpLWRpYWxvZy1vdmVybGF5c1wiKXx8MCkrMSl9fSxfZGVzdHJveU92ZXJsYXk6ZnVuY3Rpb24oKXtpZih0aGlzLm9wdGlvbnMubW9kYWwmJnRoaXMub3ZlcmxheSl7dmFyIHQ9dGhpcy5kb2N1bWVudC5kYXRhKFwidWktZGlhbG9nLW92ZXJsYXlzXCIpLTE7dD90aGlzLmRvY3VtZW50LmRhdGEoXCJ1aS1kaWFsb2ctb3ZlcmxheXNcIix0KToodGhpcy5fb2ZmKHRoaXMuZG9jdW1lbnQsXCJmb2N1c2luXCIpLHRoaXMuZG9jdW1lbnQucmVtb3ZlRGF0YShcInVpLWRpYWxvZy1vdmVybGF5c1wiKSksdGhpcy5vdmVybGF5LnJlbW92ZSgpLHRoaXMub3ZlcmxheT1udWxsfX19KSx0LnVpQmFja0NvbXBhdCE9PSExJiZ0LndpZGdldChcInVpLmRpYWxvZ1wiLHQudWkuZGlhbG9nLHtvcHRpb25zOntkaWFsb2dDbGFzczpcIlwifSxfY3JlYXRlV3JhcHBlcjpmdW5jdGlvbigpe3RoaXMuX3N1cGVyKCksdGhpcy51aURpYWxvZy5hZGRDbGFzcyh0aGlzLm9wdGlvbnMuZGlhbG9nQ2xhc3MpfSxfc2V0T3B0aW9uOmZ1bmN0aW9uKHQsZSl7XCJkaWFsb2dDbGFzc1wiPT09dCYmdGhpcy51aURpYWxvZy5yZW1vdmVDbGFzcyh0aGlzLm9wdGlvbnMuZGlhbG9nQ2xhc3MpLmFkZENsYXNzKGUpLHRoaXMuX3N1cGVyQXBwbHkoYXJndW1lbnRzKX19KSx0LnVpLmRpYWxvZyx0LndpZGdldChcInVpLnByb2dyZXNzYmFyXCIse3ZlcnNpb246XCIxLjEyLjFcIixvcHRpb25zOntjbGFzc2VzOntcInVpLXByb2dyZXNzYmFyXCI6XCJ1aS1jb3JuZXItYWxsXCIsXCJ1aS1wcm9ncmVzc2Jhci12YWx1ZVwiOlwidWktY29ybmVyLWxlZnRcIixcInVpLXByb2dyZXNzYmFyLWNvbXBsZXRlXCI6XCJ1aS1jb3JuZXItcmlnaHRcIn0sbWF4OjEwMCx2YWx1ZTowLGNoYW5nZTpudWxsLGNvbXBsZXRlOm51bGx9LG1pbjowLF9jcmVhdGU6ZnVuY3Rpb24oKXt0aGlzLm9sZFZhbHVlPXRoaXMub3B0aW9ucy52YWx1ZT10aGlzLl9jb25zdHJhaW5lZFZhbHVlKCksdGhpcy5lbGVtZW50LmF0dHIoe3JvbGU6XCJwcm9ncmVzc2JhclwiLFwiYXJpYS12YWx1ZW1pblwiOnRoaXMubWlufSksdGhpcy5fYWRkQ2xhc3MoXCJ1aS1wcm9ncmVzc2JhclwiLFwidWktd2lkZ2V0IHVpLXdpZGdldC1jb250ZW50XCIpLHRoaXMudmFsdWVEaXY9dChcIjxkaXY+XCIpLmFwcGVuZFRvKHRoaXMuZWxlbWVudCksdGhpcy5fYWRkQ2xhc3ModGhpcy52YWx1ZURpdixcInVpLXByb2dyZXNzYmFyLXZhbHVlXCIsXCJ1aS13aWRnZXQtaGVhZGVyXCIpLHRoaXMuX3JlZnJlc2hWYWx1ZSgpfSxfZGVzdHJveTpmdW5jdGlvbigpe3RoaXMuZWxlbWVudC5yZW1vdmVBdHRyKFwicm9sZSBhcmlhLXZhbHVlbWluIGFyaWEtdmFsdWVtYXggYXJpYS12YWx1ZW5vd1wiKSx0aGlzLnZhbHVlRGl2LnJlbW92ZSgpfSx2YWx1ZTpmdW5jdGlvbih0KXtyZXR1cm4gdm9pZCAwPT09dD90aGlzLm9wdGlvbnMudmFsdWU6KHRoaXMub3B0aW9ucy52YWx1ZT10aGlzLl9jb25zdHJhaW5lZFZhbHVlKHQpLHRoaXMuX3JlZnJlc2hWYWx1ZSgpLHZvaWQgMCl9LF9jb25zdHJhaW5lZFZhbHVlOmZ1bmN0aW9uKHQpe3JldHVybiB2b2lkIDA9PT10JiYodD10aGlzLm9wdGlvbnMudmFsdWUpLHRoaXMuaW5kZXRlcm1pbmF0ZT10PT09ITEsXCJudW1iZXJcIiE9dHlwZW9mIHQmJih0PTApLHRoaXMuaW5kZXRlcm1pbmF0ZT8hMTpNYXRoLm1pbih0aGlzLm9wdGlvbnMubWF4LE1hdGgubWF4KHRoaXMubWluLHQpKX0sX3NldE9wdGlvbnM6ZnVuY3Rpb24odCl7dmFyIGU9dC52YWx1ZTtkZWxldGUgdC52YWx1ZSx0aGlzLl9zdXBlcih0KSx0aGlzLm9wdGlvbnMudmFsdWU9dGhpcy5fY29uc3RyYWluZWRWYWx1ZShlKSx0aGlzLl9yZWZyZXNoVmFsdWUoKX0sX3NldE9wdGlvbjpmdW5jdGlvbih0LGUpe1wibWF4XCI9PT10JiYoZT1NYXRoLm1heCh0aGlzLm1pbixlKSksdGhpcy5fc3VwZXIodCxlKX0sX3NldE9wdGlvbkRpc2FibGVkOmZ1bmN0aW9uKHQpe3RoaXMuX3N1cGVyKHQpLHRoaXMuZWxlbWVudC5hdHRyKFwiYXJpYS1kaXNhYmxlZFwiLHQpLHRoaXMuX3RvZ2dsZUNsYXNzKG51bGwsXCJ1aS1zdGF0ZS1kaXNhYmxlZFwiLCEhdCl9LF9wZXJjZW50YWdlOmZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMuaW5kZXRlcm1pbmF0ZT8xMDA6MTAwKih0aGlzLm9wdGlvbnMudmFsdWUtdGhpcy5taW4pLyh0aGlzLm9wdGlvbnMubWF4LXRoaXMubWluKX0sX3JlZnJlc2hWYWx1ZTpmdW5jdGlvbigpe3ZhciBlPXRoaXMub3B0aW9ucy52YWx1ZSxpPXRoaXMuX3BlcmNlbnRhZ2UoKTt0aGlzLnZhbHVlRGl2LnRvZ2dsZSh0aGlzLmluZGV0ZXJtaW5hdGV8fGU+dGhpcy5taW4pLndpZHRoKGkudG9GaXhlZCgwKStcIiVcIiksdGhpcy5fdG9nZ2xlQ2xhc3ModGhpcy52YWx1ZURpdixcInVpLXByb2dyZXNzYmFyLWNvbXBsZXRlXCIsbnVsbCxlPT09dGhpcy5vcHRpb25zLm1heCkuX3RvZ2dsZUNsYXNzKFwidWktcHJvZ3Jlc3NiYXItaW5kZXRlcm1pbmF0ZVwiLG51bGwsdGhpcy5pbmRldGVybWluYXRlKSx0aGlzLmluZGV0ZXJtaW5hdGU/KHRoaXMuZWxlbWVudC5yZW1vdmVBdHRyKFwiYXJpYS12YWx1ZW5vd1wiKSx0aGlzLm92ZXJsYXlEaXZ8fCh0aGlzLm92ZXJsYXlEaXY9dChcIjxkaXY+XCIpLmFwcGVuZFRvKHRoaXMudmFsdWVEaXYpLHRoaXMuX2FkZENsYXNzKHRoaXMub3ZlcmxheURpdixcInVpLXByb2dyZXNzYmFyLW92ZXJsYXlcIikpKToodGhpcy5lbGVtZW50LmF0dHIoe1wiYXJpYS12YWx1ZW1heFwiOnRoaXMub3B0aW9ucy5tYXgsXCJhcmlhLXZhbHVlbm93XCI6ZX0pLHRoaXMub3ZlcmxheURpdiYmKHRoaXMub3ZlcmxheURpdi5yZW1vdmUoKSx0aGlzLm92ZXJsYXlEaXY9bnVsbCkpLHRoaXMub2xkVmFsdWUhPT1lJiYodGhpcy5vbGRWYWx1ZT1lLHRoaXMuX3RyaWdnZXIoXCJjaGFuZ2VcIikpLGU9PT10aGlzLm9wdGlvbnMubWF4JiZ0aGlzLl90cmlnZ2VyKFwiY29tcGxldGVcIil9fSksdC53aWRnZXQoXCJ1aS5zZWxlY3RtZW51XCIsW3QudWkuZm9ybVJlc2V0TWl4aW4se3ZlcnNpb246XCIxLjEyLjFcIixkZWZhdWx0RWxlbWVudDpcIjxzZWxlY3Q+XCIsb3B0aW9uczp7YXBwZW5kVG86bnVsbCxjbGFzc2VzOntcInVpLXNlbGVjdG1lbnUtYnV0dG9uLW9wZW5cIjpcInVpLWNvcm5lci10b3BcIixcInVpLXNlbGVjdG1lbnUtYnV0dG9uLWNsb3NlZFwiOlwidWktY29ybmVyLWFsbFwifSxkaXNhYmxlZDpudWxsLGljb25zOntidXR0b246XCJ1aS1pY29uLXRyaWFuZ2xlLTEtc1wifSxwb3NpdGlvbjp7bXk6XCJsZWZ0IHRvcFwiLGF0OlwibGVmdCBib3R0b21cIixjb2xsaXNpb246XCJub25lXCJ9LHdpZHRoOiExLGNoYW5nZTpudWxsLGNsb3NlOm51bGwsZm9jdXM6bnVsbCxvcGVuOm51bGwsc2VsZWN0Om51bGx9LF9jcmVhdGU6ZnVuY3Rpb24oKXt2YXIgZT10aGlzLmVsZW1lbnQudW5pcXVlSWQoKS5hdHRyKFwiaWRcIik7dGhpcy5pZHM9e2VsZW1lbnQ6ZSxidXR0b246ZStcIi1idXR0b25cIixtZW51OmUrXCItbWVudVwifSx0aGlzLl9kcmF3QnV0dG9uKCksdGhpcy5fZHJhd01lbnUoKSx0aGlzLl9iaW5kRm9ybVJlc2V0SGFuZGxlcigpLHRoaXMuX3JlbmRlcmVkPSExLHRoaXMubWVudUl0ZW1zPXQoKX0sX2RyYXdCdXR0b246ZnVuY3Rpb24oKXt2YXIgZSxpPXRoaXMscz10aGlzLl9wYXJzZU9wdGlvbih0aGlzLmVsZW1lbnQuZmluZChcIm9wdGlvbjpzZWxlY3RlZFwiKSx0aGlzLmVsZW1lbnRbMF0uc2VsZWN0ZWRJbmRleCk7dGhpcy5sYWJlbHM9dGhpcy5lbGVtZW50LmxhYmVscygpLmF0dHIoXCJmb3JcIix0aGlzLmlkcy5idXR0b24pLHRoaXMuX29uKHRoaXMubGFiZWxzLHtjbGljazpmdW5jdGlvbih0KXt0aGlzLmJ1dHRvbi5mb2N1cygpLHQucHJldmVudERlZmF1bHQoKX19KSx0aGlzLmVsZW1lbnQuaGlkZSgpLHRoaXMuYnV0dG9uPXQoXCI8c3Bhbj5cIix7dGFiaW5kZXg6dGhpcy5vcHRpb25zLmRpc2FibGVkPy0xOjAsaWQ6dGhpcy5pZHMuYnV0dG9uLHJvbGU6XCJjb21ib2JveFwiLFwiYXJpYS1leHBhbmRlZFwiOlwiZmFsc2VcIixcImFyaWEtYXV0b2NvbXBsZXRlXCI6XCJsaXN0XCIsXCJhcmlhLW93bnNcIjp0aGlzLmlkcy5tZW51LFwiYXJpYS1oYXNwb3B1cFwiOlwidHJ1ZVwiLHRpdGxlOnRoaXMuZWxlbWVudC5hdHRyKFwidGl0bGVcIil9KS5pbnNlcnRBZnRlcih0aGlzLmVsZW1lbnQpLHRoaXMuX2FkZENsYXNzKHRoaXMuYnV0dG9uLFwidWktc2VsZWN0bWVudS1idXR0b24gdWktc2VsZWN0bWVudS1idXR0b24tY2xvc2VkXCIsXCJ1aS1idXR0b24gdWktd2lkZ2V0XCIpLGU9dChcIjxzcGFuPlwiKS5hcHBlbmRUbyh0aGlzLmJ1dHRvbiksdGhpcy5fYWRkQ2xhc3MoZSxcInVpLXNlbGVjdG1lbnUtaWNvblwiLFwidWktaWNvbiBcIit0aGlzLm9wdGlvbnMuaWNvbnMuYnV0dG9uKSx0aGlzLmJ1dHRvbkl0ZW09dGhpcy5fcmVuZGVyQnV0dG9uSXRlbShzKS5hcHBlbmRUbyh0aGlzLmJ1dHRvbiksdGhpcy5vcHRpb25zLndpZHRoIT09ITEmJnRoaXMuX3Jlc2l6ZUJ1dHRvbigpLHRoaXMuX29uKHRoaXMuYnV0dG9uLHRoaXMuX2J1dHRvbkV2ZW50cyksdGhpcy5idXR0b24ub25lKFwiZm9jdXNpblwiLGZ1bmN0aW9uKCl7aS5fcmVuZGVyZWR8fGkuX3JlZnJlc2hNZW51KCl9KX0sX2RyYXdNZW51OmZ1bmN0aW9uKCl7dmFyIGU9dGhpczt0aGlzLm1lbnU9dChcIjx1bD5cIix7XCJhcmlhLWhpZGRlblwiOlwidHJ1ZVwiLFwiYXJpYS1sYWJlbGxlZGJ5XCI6dGhpcy5pZHMuYnV0dG9uLGlkOnRoaXMuaWRzLm1lbnV9KSx0aGlzLm1lbnVXcmFwPXQoXCI8ZGl2PlwiKS5hcHBlbmQodGhpcy5tZW51KSx0aGlzLl9hZGRDbGFzcyh0aGlzLm1lbnVXcmFwLFwidWktc2VsZWN0bWVudS1tZW51XCIsXCJ1aS1mcm9udFwiKSx0aGlzLm1lbnVXcmFwLmFwcGVuZFRvKHRoaXMuX2FwcGVuZFRvKCkpLHRoaXMubWVudUluc3RhbmNlPXRoaXMubWVudS5tZW51KHtjbGFzc2VzOntcInVpLW1lbnVcIjpcInVpLWNvcm5lci1ib3R0b21cIn0scm9sZTpcImxpc3Rib3hcIixzZWxlY3Q6ZnVuY3Rpb24odCxpKXt0LnByZXZlbnREZWZhdWx0KCksZS5fc2V0U2VsZWN0aW9uKCksZS5fc2VsZWN0KGkuaXRlbS5kYXRhKFwidWktc2VsZWN0bWVudS1pdGVtXCIpLHQpfSxmb2N1czpmdW5jdGlvbih0LGkpe3ZhciBzPWkuaXRlbS5kYXRhKFwidWktc2VsZWN0bWVudS1pdGVtXCIpO251bGwhPWUuZm9jdXNJbmRleCYmcy5pbmRleCE9PWUuZm9jdXNJbmRleCYmKGUuX3RyaWdnZXIoXCJmb2N1c1wiLHQse2l0ZW06c30pLGUuaXNPcGVufHxlLl9zZWxlY3Qocyx0KSksZS5mb2N1c0luZGV4PXMuaW5kZXgsZS5idXR0b24uYXR0cihcImFyaWEtYWN0aXZlZGVzY2VuZGFudFwiLGUubWVudUl0ZW1zLmVxKHMuaW5kZXgpLmF0dHIoXCJpZFwiKSl9fSkubWVudShcImluc3RhbmNlXCIpLHRoaXMubWVudUluc3RhbmNlLl9vZmYodGhpcy5tZW51LFwibW91c2VsZWF2ZVwiKSx0aGlzLm1lbnVJbnN0YW5jZS5fY2xvc2VPbkRvY3VtZW50Q2xpY2s9ZnVuY3Rpb24oKXtyZXR1cm4hMX0sdGhpcy5tZW51SW5zdGFuY2UuX2lzRGl2aWRlcj1mdW5jdGlvbigpe3JldHVybiExfX0scmVmcmVzaDpmdW5jdGlvbigpe3RoaXMuX3JlZnJlc2hNZW51KCksdGhpcy5idXR0b25JdGVtLnJlcGxhY2VXaXRoKHRoaXMuYnV0dG9uSXRlbT10aGlzLl9yZW5kZXJCdXR0b25JdGVtKHRoaXMuX2dldFNlbGVjdGVkSXRlbSgpLmRhdGEoXCJ1aS1zZWxlY3RtZW51LWl0ZW1cIil8fHt9KSksbnVsbD09PXRoaXMub3B0aW9ucy53aWR0aCYmdGhpcy5fcmVzaXplQnV0dG9uKCl9LF9yZWZyZXNoTWVudTpmdW5jdGlvbigpe3ZhciB0LGU9dGhpcy5lbGVtZW50LmZpbmQoXCJvcHRpb25cIik7dGhpcy5tZW51LmVtcHR5KCksdGhpcy5fcGFyc2VPcHRpb25zKGUpLHRoaXMuX3JlbmRlck1lbnUodGhpcy5tZW51LHRoaXMuaXRlbXMpLHRoaXMubWVudUluc3RhbmNlLnJlZnJlc2goKSx0aGlzLm1lbnVJdGVtcz10aGlzLm1lbnUuZmluZChcImxpXCIpLm5vdChcIi51aS1zZWxlY3RtZW51LW9wdGdyb3VwXCIpLmZpbmQoXCIudWktbWVudS1pdGVtLXdyYXBwZXJcIiksdGhpcy5fcmVuZGVyZWQ9ITAsZS5sZW5ndGgmJih0PXRoaXMuX2dldFNlbGVjdGVkSXRlbSgpLHRoaXMubWVudUluc3RhbmNlLmZvY3VzKG51bGwsdCksdGhpcy5fc2V0QXJpYSh0LmRhdGEoXCJ1aS1zZWxlY3RtZW51LWl0ZW1cIikpLHRoaXMuX3NldE9wdGlvbihcImRpc2FibGVkXCIsdGhpcy5lbGVtZW50LnByb3AoXCJkaXNhYmxlZFwiKSkpfSxvcGVuOmZ1bmN0aW9uKHQpe3RoaXMub3B0aW9ucy5kaXNhYmxlZHx8KHRoaXMuX3JlbmRlcmVkPyh0aGlzLl9yZW1vdmVDbGFzcyh0aGlzLm1lbnUuZmluZChcIi51aS1zdGF0ZS1hY3RpdmVcIiksbnVsbCxcInVpLXN0YXRlLWFjdGl2ZVwiKSx0aGlzLm1lbnVJbnN0YW5jZS5mb2N1cyhudWxsLHRoaXMuX2dldFNlbGVjdGVkSXRlbSgpKSk6dGhpcy5fcmVmcmVzaE1lbnUoKSx0aGlzLm1lbnVJdGVtcy5sZW5ndGgmJih0aGlzLmlzT3Blbj0hMCx0aGlzLl90b2dnbGVBdHRyKCksdGhpcy5fcmVzaXplTWVudSgpLHRoaXMuX3Bvc2l0aW9uKCksdGhpcy5fb24odGhpcy5kb2N1bWVudCx0aGlzLl9kb2N1bWVudENsaWNrKSx0aGlzLl90cmlnZ2VyKFwib3BlblwiLHQpKSl9LF9wb3NpdGlvbjpmdW5jdGlvbigpe3RoaXMubWVudVdyYXAucG9zaXRpb24odC5leHRlbmQoe29mOnRoaXMuYnV0dG9ufSx0aGlzLm9wdGlvbnMucG9zaXRpb24pKX0sY2xvc2U6ZnVuY3Rpb24odCl7dGhpcy5pc09wZW4mJih0aGlzLmlzT3Blbj0hMSx0aGlzLl90b2dnbGVBdHRyKCksdGhpcy5yYW5nZT1udWxsLHRoaXMuX29mZih0aGlzLmRvY3VtZW50KSx0aGlzLl90cmlnZ2VyKFwiY2xvc2VcIix0KSl9LHdpZGdldDpmdW5jdGlvbigpe3JldHVybiB0aGlzLmJ1dHRvbn0sbWVudVdpZGdldDpmdW5jdGlvbigpe3JldHVybiB0aGlzLm1lbnV9LF9yZW5kZXJCdXR0b25JdGVtOmZ1bmN0aW9uKGUpe3ZhciBpPXQoXCI8c3Bhbj5cIik7cmV0dXJuIHRoaXMuX3NldFRleHQoaSxlLmxhYmVsKSx0aGlzLl9hZGRDbGFzcyhpLFwidWktc2VsZWN0bWVudS10ZXh0XCIpLGl9LF9yZW5kZXJNZW51OmZ1bmN0aW9uKGUsaSl7dmFyIHM9dGhpcyxuPVwiXCI7dC5lYWNoKGksZnVuY3Rpb24oaSxvKXt2YXIgYTtvLm9wdGdyb3VwIT09biYmKGE9dChcIjxsaT5cIix7dGV4dDpvLm9wdGdyb3VwfSkscy5fYWRkQ2xhc3MoYSxcInVpLXNlbGVjdG1lbnUtb3B0Z3JvdXBcIixcInVpLW1lbnUtZGl2aWRlclwiKyhvLmVsZW1lbnQucGFyZW50KFwib3B0Z3JvdXBcIikucHJvcChcImRpc2FibGVkXCIpP1wiIHVpLXN0YXRlLWRpc2FibGVkXCI6XCJcIikpLGEuYXBwZW5kVG8oZSksbj1vLm9wdGdyb3VwKSxzLl9yZW5kZXJJdGVtRGF0YShlLG8pfSl9LF9yZW5kZXJJdGVtRGF0YTpmdW5jdGlvbih0LGUpe3JldHVybiB0aGlzLl9yZW5kZXJJdGVtKHQsZSkuZGF0YShcInVpLXNlbGVjdG1lbnUtaXRlbVwiLGUpfSxfcmVuZGVySXRlbTpmdW5jdGlvbihlLGkpe3ZhciBzPXQoXCI8bGk+XCIpLG49dChcIjxkaXY+XCIse3RpdGxlOmkuZWxlbWVudC5hdHRyKFwidGl0bGVcIil9KTtyZXR1cm4gaS5kaXNhYmxlZCYmdGhpcy5fYWRkQ2xhc3MocyxudWxsLFwidWktc3RhdGUtZGlzYWJsZWRcIiksdGhpcy5fc2V0VGV4dChuLGkubGFiZWwpLHMuYXBwZW5kKG4pLmFwcGVuZFRvKGUpfSxfc2V0VGV4dDpmdW5jdGlvbih0LGUpe2U/dC50ZXh0KGUpOnQuaHRtbChcIiYjMTYwO1wiKX0sX21vdmU6ZnVuY3Rpb24odCxlKXt2YXIgaSxzLG49XCIudWktbWVudS1pdGVtXCI7dGhpcy5pc09wZW4/aT10aGlzLm1lbnVJdGVtcy5lcSh0aGlzLmZvY3VzSW5kZXgpLnBhcmVudChcImxpXCIpOihpPXRoaXMubWVudUl0ZW1zLmVxKHRoaXMuZWxlbWVudFswXS5zZWxlY3RlZEluZGV4KS5wYXJlbnQoXCJsaVwiKSxuKz1cIjpub3QoLnVpLXN0YXRlLWRpc2FibGVkKVwiKSxzPVwiZmlyc3RcIj09PXR8fFwibGFzdFwiPT09dD9pW1wiZmlyc3RcIj09PXQ/XCJwcmV2QWxsXCI6XCJuZXh0QWxsXCJdKG4pLmVxKC0xKTppW3QrXCJBbGxcIl0obikuZXEoMCkscy5sZW5ndGgmJnRoaXMubWVudUluc3RhbmNlLmZvY3VzKGUscyl9LF9nZXRTZWxlY3RlZEl0ZW06ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5tZW51SXRlbXMuZXEodGhpcy5lbGVtZW50WzBdLnNlbGVjdGVkSW5kZXgpLnBhcmVudChcImxpXCIpfSxfdG9nZ2xlOmZ1bmN0aW9uKHQpe3RoaXNbdGhpcy5pc09wZW4/XCJjbG9zZVwiOlwib3BlblwiXSh0KX0sX3NldFNlbGVjdGlvbjpmdW5jdGlvbigpe3ZhciB0O3RoaXMucmFuZ2UmJih3aW5kb3cuZ2V0U2VsZWN0aW9uPyh0PXdpbmRvdy5nZXRTZWxlY3Rpb24oKSx0LnJlbW92ZUFsbFJhbmdlcygpLHQuYWRkUmFuZ2UodGhpcy5yYW5nZSkpOnRoaXMucmFuZ2Uuc2VsZWN0KCksdGhpcy5idXR0b24uZm9jdXMoKSl9LF9kb2N1bWVudENsaWNrOnttb3VzZWRvd246ZnVuY3Rpb24oZSl7dGhpcy5pc09wZW4mJih0KGUudGFyZ2V0KS5jbG9zZXN0KFwiLnVpLXNlbGVjdG1lbnUtbWVudSwgI1wiK3QudWkuZXNjYXBlU2VsZWN0b3IodGhpcy5pZHMuYnV0dG9uKSkubGVuZ3RofHx0aGlzLmNsb3NlKGUpKX19LF9idXR0b25FdmVudHM6e21vdXNlZG93bjpmdW5jdGlvbigpe3ZhciB0O3dpbmRvdy5nZXRTZWxlY3Rpb24/KHQ9d2luZG93LmdldFNlbGVjdGlvbigpLHQucmFuZ2VDb3VudCYmKHRoaXMucmFuZ2U9dC5nZXRSYW5nZUF0KDApKSk6dGhpcy5yYW5nZT1kb2N1bWVudC5zZWxlY3Rpb24uY3JlYXRlUmFuZ2UoKX0sY2xpY2s6ZnVuY3Rpb24odCl7dGhpcy5fc2V0U2VsZWN0aW9uKCksdGhpcy5fdG9nZ2xlKHQpfSxrZXlkb3duOmZ1bmN0aW9uKGUpe3ZhciBpPSEwO3N3aXRjaChlLmtleUNvZGUpe2Nhc2UgdC51aS5rZXlDb2RlLlRBQjpjYXNlIHQudWkua2V5Q29kZS5FU0NBUEU6dGhpcy5jbG9zZShlKSxpPSExO2JyZWFrO2Nhc2UgdC51aS5rZXlDb2RlLkVOVEVSOnRoaXMuaXNPcGVuJiZ0aGlzLl9zZWxlY3RGb2N1c2VkSXRlbShlKTticmVhaztjYXNlIHQudWkua2V5Q29kZS5VUDplLmFsdEtleT90aGlzLl90b2dnbGUoZSk6dGhpcy5fbW92ZShcInByZXZcIixlKTticmVhaztjYXNlIHQudWkua2V5Q29kZS5ET1dOOmUuYWx0S2V5P3RoaXMuX3RvZ2dsZShlKTp0aGlzLl9tb3ZlKFwibmV4dFwiLGUpO2JyZWFrO2Nhc2UgdC51aS5rZXlDb2RlLlNQQUNFOnRoaXMuaXNPcGVuP3RoaXMuX3NlbGVjdEZvY3VzZWRJdGVtKGUpOnRoaXMuX3RvZ2dsZShlKTticmVhaztjYXNlIHQudWkua2V5Q29kZS5MRUZUOnRoaXMuX21vdmUoXCJwcmV2XCIsZSk7YnJlYWs7Y2FzZSB0LnVpLmtleUNvZGUuUklHSFQ6dGhpcy5fbW92ZShcIm5leHRcIixlKTticmVhaztjYXNlIHQudWkua2V5Q29kZS5IT01FOmNhc2UgdC51aS5rZXlDb2RlLlBBR0VfVVA6dGhpcy5fbW92ZShcImZpcnN0XCIsZSk7YnJlYWs7Y2FzZSB0LnVpLmtleUNvZGUuRU5EOmNhc2UgdC51aS5rZXlDb2RlLlBBR0VfRE9XTjp0aGlzLl9tb3ZlKFwibGFzdFwiLGUpO2JyZWFrO2RlZmF1bHQ6dGhpcy5tZW51LnRyaWdnZXIoZSksaT0hMX1pJiZlLnByZXZlbnREZWZhdWx0KCl9fSxfc2VsZWN0Rm9jdXNlZEl0ZW06ZnVuY3Rpb24odCl7dmFyIGU9dGhpcy5tZW51SXRlbXMuZXEodGhpcy5mb2N1c0luZGV4KS5wYXJlbnQoXCJsaVwiKTtlLmhhc0NsYXNzKFwidWktc3RhdGUtZGlzYWJsZWRcIil8fHRoaXMuX3NlbGVjdChlLmRhdGEoXCJ1aS1zZWxlY3RtZW51LWl0ZW1cIiksdCl9LF9zZWxlY3Q6ZnVuY3Rpb24odCxlKXt2YXIgaT10aGlzLmVsZW1lbnRbMF0uc2VsZWN0ZWRJbmRleDt0aGlzLmVsZW1lbnRbMF0uc2VsZWN0ZWRJbmRleD10LmluZGV4LHRoaXMuYnV0dG9uSXRlbS5yZXBsYWNlV2l0aCh0aGlzLmJ1dHRvbkl0ZW09dGhpcy5fcmVuZGVyQnV0dG9uSXRlbSh0KSksdGhpcy5fc2V0QXJpYSh0KSx0aGlzLl90cmlnZ2VyKFwic2VsZWN0XCIsZSx7aXRlbTp0fSksdC5pbmRleCE9PWkmJnRoaXMuX3RyaWdnZXIoXCJjaGFuZ2VcIixlLHtpdGVtOnR9KSx0aGlzLmNsb3NlKGUpfSxfc2V0QXJpYTpmdW5jdGlvbih0KXt2YXIgZT10aGlzLm1lbnVJdGVtcy5lcSh0LmluZGV4KS5hdHRyKFwiaWRcIik7dGhpcy5idXR0b24uYXR0cih7XCJhcmlhLWxhYmVsbGVkYnlcIjplLFwiYXJpYS1hY3RpdmVkZXNjZW5kYW50XCI6ZX0pLHRoaXMubWVudS5hdHRyKFwiYXJpYS1hY3RpdmVkZXNjZW5kYW50XCIsZSl9LF9zZXRPcHRpb246ZnVuY3Rpb24odCxlKXtpZihcImljb25zXCI9PT10KXt2YXIgaT10aGlzLmJ1dHRvbi5maW5kKFwic3Bhbi51aS1pY29uXCIpO3RoaXMuX3JlbW92ZUNsYXNzKGksbnVsbCx0aGlzLm9wdGlvbnMuaWNvbnMuYnV0dG9uKS5fYWRkQ2xhc3MoaSxudWxsLGUuYnV0dG9uKX10aGlzLl9zdXBlcih0LGUpLFwiYXBwZW5kVG9cIj09PXQmJnRoaXMubWVudVdyYXAuYXBwZW5kVG8odGhpcy5fYXBwZW5kVG8oKSksXCJ3aWR0aFwiPT09dCYmdGhpcy5fcmVzaXplQnV0dG9uKCl9LF9zZXRPcHRpb25EaXNhYmxlZDpmdW5jdGlvbih0KXt0aGlzLl9zdXBlcih0KSx0aGlzLm1lbnVJbnN0YW5jZS5vcHRpb24oXCJkaXNhYmxlZFwiLHQpLHRoaXMuYnV0dG9uLmF0dHIoXCJhcmlhLWRpc2FibGVkXCIsdCksdGhpcy5fdG9nZ2xlQ2xhc3ModGhpcy5idXR0b24sbnVsbCxcInVpLXN0YXRlLWRpc2FibGVkXCIsdCksdGhpcy5lbGVtZW50LnByb3AoXCJkaXNhYmxlZFwiLHQpLHQ/KHRoaXMuYnV0dG9uLmF0dHIoXCJ0YWJpbmRleFwiLC0xKSx0aGlzLmNsb3NlKCkpOnRoaXMuYnV0dG9uLmF0dHIoXCJ0YWJpbmRleFwiLDApfSxfYXBwZW5kVG86ZnVuY3Rpb24oKXt2YXIgZT10aGlzLm9wdGlvbnMuYXBwZW5kVG87cmV0dXJuIGUmJihlPWUuanF1ZXJ5fHxlLm5vZGVUeXBlP3QoZSk6dGhpcy5kb2N1bWVudC5maW5kKGUpLmVxKDApKSxlJiZlWzBdfHwoZT10aGlzLmVsZW1lbnQuY2xvc2VzdChcIi51aS1mcm9udCwgZGlhbG9nXCIpKSxlLmxlbmd0aHx8KGU9dGhpcy5kb2N1bWVudFswXS5ib2R5KSxlfSxfdG9nZ2xlQXR0cjpmdW5jdGlvbigpe3RoaXMuYnV0dG9uLmF0dHIoXCJhcmlhLWV4cGFuZGVkXCIsdGhpcy5pc09wZW4pLHRoaXMuX3JlbW92ZUNsYXNzKHRoaXMuYnV0dG9uLFwidWktc2VsZWN0bWVudS1idXR0b24tXCIrKHRoaXMuaXNPcGVuP1wiY2xvc2VkXCI6XCJvcGVuXCIpKS5fYWRkQ2xhc3ModGhpcy5idXR0b24sXCJ1aS1zZWxlY3RtZW51LWJ1dHRvbi1cIisodGhpcy5pc09wZW4/XCJvcGVuXCI6XCJjbG9zZWRcIikpLl90b2dnbGVDbGFzcyh0aGlzLm1lbnVXcmFwLFwidWktc2VsZWN0bWVudS1vcGVuXCIsbnVsbCx0aGlzLmlzT3BlbiksdGhpcy5tZW51LmF0dHIoXCJhcmlhLWhpZGRlblwiLCF0aGlzLmlzT3Blbil9LF9yZXNpemVCdXR0b246ZnVuY3Rpb24oKXt2YXIgdD10aGlzLm9wdGlvbnMud2lkdGg7cmV0dXJuIHQ9PT0hMT8odGhpcy5idXR0b24uY3NzKFwid2lkdGhcIixcIlwiKSx2b2lkIDApOihudWxsPT09dCYmKHQ9dGhpcy5lbGVtZW50LnNob3coKS5vdXRlcldpZHRoKCksdGhpcy5lbGVtZW50LmhpZGUoKSksdGhpcy5idXR0b24ub3V0ZXJXaWR0aCh0KSx2b2lkIDApfSxfcmVzaXplTWVudTpmdW5jdGlvbigpe3RoaXMubWVudS5vdXRlcldpZHRoKE1hdGgubWF4KHRoaXMuYnV0dG9uLm91dGVyV2lkdGgoKSx0aGlzLm1lbnUud2lkdGgoXCJcIikub3V0ZXJXaWR0aCgpKzEpKX0sX2dldENyZWF0ZU9wdGlvbnM6ZnVuY3Rpb24oKXt2YXIgdD10aGlzLl9zdXBlcigpO3JldHVybiB0LmRpc2FibGVkPXRoaXMuZWxlbWVudC5wcm9wKFwiZGlzYWJsZWRcIiksdH0sX3BhcnNlT3B0aW9uczpmdW5jdGlvbihlKXt2YXIgaT10aGlzLHM9W107ZS5lYWNoKGZ1bmN0aW9uKGUsbil7cy5wdXNoKGkuX3BhcnNlT3B0aW9uKHQobiksZSkpfSksdGhpcy5pdGVtcz1zfSxfcGFyc2VPcHRpb246ZnVuY3Rpb24odCxlKXt2YXIgaT10LnBhcmVudChcIm9wdGdyb3VwXCIpO3JldHVybntlbGVtZW50OnQsaW5kZXg6ZSx2YWx1ZTp0LnZhbCgpLGxhYmVsOnQudGV4dCgpLG9wdGdyb3VwOmkuYXR0cihcImxhYmVsXCIpfHxcIlwiLGRpc2FibGVkOmkucHJvcChcImRpc2FibGVkXCIpfHx0LnByb3AoXCJkaXNhYmxlZFwiKX19LF9kZXN0cm95OmZ1bmN0aW9uKCl7dGhpcy5fdW5iaW5kRm9ybVJlc2V0SGFuZGxlcigpLHRoaXMubWVudVdyYXAucmVtb3ZlKCksdGhpcy5idXR0b24ucmVtb3ZlKCksdGhpcy5lbGVtZW50LnNob3coKSx0aGlzLmVsZW1lbnQucmVtb3ZlVW5pcXVlSWQoKSx0aGlzLmxhYmVscy5hdHRyKFwiZm9yXCIsdGhpcy5pZHMuZWxlbWVudCl9fV0pLHQud2lkZ2V0KFwidWkuc2xpZGVyXCIsdC51aS5tb3VzZSx7dmVyc2lvbjpcIjEuMTIuMVwiLHdpZGdldEV2ZW50UHJlZml4Olwic2xpZGVcIixvcHRpb25zOnthbmltYXRlOiExLGNsYXNzZXM6e1widWktc2xpZGVyXCI6XCJ1aS1jb3JuZXItYWxsXCIsXCJ1aS1zbGlkZXItaGFuZGxlXCI6XCJ1aS1jb3JuZXItYWxsXCIsXCJ1aS1zbGlkZXItcmFuZ2VcIjpcInVpLWNvcm5lci1hbGwgdWktd2lkZ2V0LWhlYWRlclwifSxkaXN0YW5jZTowLG1heDoxMDAsbWluOjAsb3JpZW50YXRpb246XCJob3Jpem9udGFsXCIscmFuZ2U6ITEsc3RlcDoxLHZhbHVlOjAsdmFsdWVzOm51bGwsY2hhbmdlOm51bGwsc2xpZGU6bnVsbCxzdGFydDpudWxsLHN0b3A6bnVsbH0sbnVtUGFnZXM6NSxfY3JlYXRlOmZ1bmN0aW9uKCl7dGhpcy5fa2V5U2xpZGluZz0hMSx0aGlzLl9tb3VzZVNsaWRpbmc9ITEsdGhpcy5fYW5pbWF0ZU9mZj0hMCx0aGlzLl9oYW5kbGVJbmRleD1udWxsLHRoaXMuX2RldGVjdE9yaWVudGF0aW9uKCksdGhpcy5fbW91c2VJbml0KCksdGhpcy5fY2FsY3VsYXRlTmV3TWF4KCksdGhpcy5fYWRkQ2xhc3MoXCJ1aS1zbGlkZXIgdWktc2xpZGVyLVwiK3RoaXMub3JpZW50YXRpb24sXCJ1aS13aWRnZXQgdWktd2lkZ2V0LWNvbnRlbnRcIiksdGhpcy5fcmVmcmVzaCgpLHRoaXMuX2FuaW1hdGVPZmY9ITF9LF9yZWZyZXNoOmZ1bmN0aW9uKCl7dGhpcy5fY3JlYXRlUmFuZ2UoKSx0aGlzLl9jcmVhdGVIYW5kbGVzKCksdGhpcy5fc2V0dXBFdmVudHMoKSx0aGlzLl9yZWZyZXNoVmFsdWUoKX0sX2NyZWF0ZUhhbmRsZXM6ZnVuY3Rpb24oKXt2YXIgZSxpLHM9dGhpcy5vcHRpb25zLG49dGhpcy5lbGVtZW50LmZpbmQoXCIudWktc2xpZGVyLWhhbmRsZVwiKSxvPVwiPHNwYW4gdGFiaW5kZXg9JzAnPjwvc3Bhbj5cIixhPVtdO2ZvcihpPXMudmFsdWVzJiZzLnZhbHVlcy5sZW5ndGh8fDEsbi5sZW5ndGg+aSYmKG4uc2xpY2UoaSkucmVtb3ZlKCksbj1uLnNsaWNlKDAsaSkpLGU9bi5sZW5ndGg7aT5lO2UrKylhLnB1c2gobyk7dGhpcy5oYW5kbGVzPW4uYWRkKHQoYS5qb2luKFwiXCIpKS5hcHBlbmRUbyh0aGlzLmVsZW1lbnQpKSx0aGlzLl9hZGRDbGFzcyh0aGlzLmhhbmRsZXMsXCJ1aS1zbGlkZXItaGFuZGxlXCIsXCJ1aS1zdGF0ZS1kZWZhdWx0XCIpLHRoaXMuaGFuZGxlPXRoaXMuaGFuZGxlcy5lcSgwKSx0aGlzLmhhbmRsZXMuZWFjaChmdW5jdGlvbihlKXt0KHRoaXMpLmRhdGEoXCJ1aS1zbGlkZXItaGFuZGxlLWluZGV4XCIsZSkuYXR0cihcInRhYkluZGV4XCIsMCl9KX0sX2NyZWF0ZVJhbmdlOmZ1bmN0aW9uKCl7dmFyIGU9dGhpcy5vcHRpb25zO2UucmFuZ2U/KGUucmFuZ2U9PT0hMCYmKGUudmFsdWVzP2UudmFsdWVzLmxlbmd0aCYmMiE9PWUudmFsdWVzLmxlbmd0aD9lLnZhbHVlcz1bZS52YWx1ZXNbMF0sZS52YWx1ZXNbMF1dOnQuaXNBcnJheShlLnZhbHVlcykmJihlLnZhbHVlcz1lLnZhbHVlcy5zbGljZSgwKSk6ZS52YWx1ZXM9W3RoaXMuX3ZhbHVlTWluKCksdGhpcy5fdmFsdWVNaW4oKV0pLHRoaXMucmFuZ2UmJnRoaXMucmFuZ2UubGVuZ3RoPyh0aGlzLl9yZW1vdmVDbGFzcyh0aGlzLnJhbmdlLFwidWktc2xpZGVyLXJhbmdlLW1pbiB1aS1zbGlkZXItcmFuZ2UtbWF4XCIpLHRoaXMucmFuZ2UuY3NzKHtsZWZ0OlwiXCIsYm90dG9tOlwiXCJ9KSk6KHRoaXMucmFuZ2U9dChcIjxkaXY+XCIpLmFwcGVuZFRvKHRoaXMuZWxlbWVudCksdGhpcy5fYWRkQ2xhc3ModGhpcy5yYW5nZSxcInVpLXNsaWRlci1yYW5nZVwiKSksKFwibWluXCI9PT1lLnJhbmdlfHxcIm1heFwiPT09ZS5yYW5nZSkmJnRoaXMuX2FkZENsYXNzKHRoaXMucmFuZ2UsXCJ1aS1zbGlkZXItcmFuZ2UtXCIrZS5yYW5nZSkpOih0aGlzLnJhbmdlJiZ0aGlzLnJhbmdlLnJlbW92ZSgpLHRoaXMucmFuZ2U9bnVsbClcbn0sX3NldHVwRXZlbnRzOmZ1bmN0aW9uKCl7dGhpcy5fb2ZmKHRoaXMuaGFuZGxlcyksdGhpcy5fb24odGhpcy5oYW5kbGVzLHRoaXMuX2hhbmRsZUV2ZW50cyksdGhpcy5faG92ZXJhYmxlKHRoaXMuaGFuZGxlcyksdGhpcy5fZm9jdXNhYmxlKHRoaXMuaGFuZGxlcyl9LF9kZXN0cm95OmZ1bmN0aW9uKCl7dGhpcy5oYW5kbGVzLnJlbW92ZSgpLHRoaXMucmFuZ2UmJnRoaXMucmFuZ2UucmVtb3ZlKCksdGhpcy5fbW91c2VEZXN0cm95KCl9LF9tb3VzZUNhcHR1cmU6ZnVuY3Rpb24oZSl7dmFyIGkscyxuLG8sYSxyLGgsbCxjPXRoaXMsdT10aGlzLm9wdGlvbnM7cmV0dXJuIHUuZGlzYWJsZWQ/ITE6KHRoaXMuZWxlbWVudFNpemU9e3dpZHRoOnRoaXMuZWxlbWVudC5vdXRlcldpZHRoKCksaGVpZ2h0OnRoaXMuZWxlbWVudC5vdXRlckhlaWdodCgpfSx0aGlzLmVsZW1lbnRPZmZzZXQ9dGhpcy5lbGVtZW50Lm9mZnNldCgpLGk9e3g6ZS5wYWdlWCx5OmUucGFnZVl9LHM9dGhpcy5fbm9ybVZhbHVlRnJvbU1vdXNlKGkpLG49dGhpcy5fdmFsdWVNYXgoKS10aGlzLl92YWx1ZU1pbigpKzEsdGhpcy5oYW5kbGVzLmVhY2goZnVuY3Rpb24oZSl7dmFyIGk9TWF0aC5hYnMocy1jLnZhbHVlcyhlKSk7KG4+aXx8bj09PWkmJihlPT09Yy5fbGFzdENoYW5nZWRWYWx1ZXx8Yy52YWx1ZXMoZSk9PT11Lm1pbikpJiYobj1pLG89dCh0aGlzKSxhPWUpfSkscj10aGlzLl9zdGFydChlLGEpLHI9PT0hMT8hMToodGhpcy5fbW91c2VTbGlkaW5nPSEwLHRoaXMuX2hhbmRsZUluZGV4PWEsdGhpcy5fYWRkQ2xhc3MobyxudWxsLFwidWktc3RhdGUtYWN0aXZlXCIpLG8udHJpZ2dlcihcImZvY3VzXCIpLGg9by5vZmZzZXQoKSxsPSF0KGUudGFyZ2V0KS5wYXJlbnRzKCkuYWRkQmFjaygpLmlzKFwiLnVpLXNsaWRlci1oYW5kbGVcIiksdGhpcy5fY2xpY2tPZmZzZXQ9bD97bGVmdDowLHRvcDowfTp7bGVmdDplLnBhZ2VYLWgubGVmdC1vLndpZHRoKCkvMix0b3A6ZS5wYWdlWS1oLnRvcC1vLmhlaWdodCgpLzItKHBhcnNlSW50KG8uY3NzKFwiYm9yZGVyVG9wV2lkdGhcIiksMTApfHwwKS0ocGFyc2VJbnQoby5jc3MoXCJib3JkZXJCb3R0b21XaWR0aFwiKSwxMCl8fDApKyhwYXJzZUludChvLmNzcyhcIm1hcmdpblRvcFwiKSwxMCl8fDApfSx0aGlzLmhhbmRsZXMuaGFzQ2xhc3MoXCJ1aS1zdGF0ZS1ob3ZlclwiKXx8dGhpcy5fc2xpZGUoZSxhLHMpLHRoaXMuX2FuaW1hdGVPZmY9ITAsITApKX0sX21vdXNlU3RhcnQ6ZnVuY3Rpb24oKXtyZXR1cm4hMH0sX21vdXNlRHJhZzpmdW5jdGlvbih0KXt2YXIgZT17eDp0LnBhZ2VYLHk6dC5wYWdlWX0saT10aGlzLl9ub3JtVmFsdWVGcm9tTW91c2UoZSk7cmV0dXJuIHRoaXMuX3NsaWRlKHQsdGhpcy5faGFuZGxlSW5kZXgsaSksITF9LF9tb3VzZVN0b3A6ZnVuY3Rpb24odCl7cmV0dXJuIHRoaXMuX3JlbW92ZUNsYXNzKHRoaXMuaGFuZGxlcyxudWxsLFwidWktc3RhdGUtYWN0aXZlXCIpLHRoaXMuX21vdXNlU2xpZGluZz0hMSx0aGlzLl9zdG9wKHQsdGhpcy5faGFuZGxlSW5kZXgpLHRoaXMuX2NoYW5nZSh0LHRoaXMuX2hhbmRsZUluZGV4KSx0aGlzLl9oYW5kbGVJbmRleD1udWxsLHRoaXMuX2NsaWNrT2Zmc2V0PW51bGwsdGhpcy5fYW5pbWF0ZU9mZj0hMSwhMX0sX2RldGVjdE9yaWVudGF0aW9uOmZ1bmN0aW9uKCl7dGhpcy5vcmllbnRhdGlvbj1cInZlcnRpY2FsXCI9PT10aGlzLm9wdGlvbnMub3JpZW50YXRpb24/XCJ2ZXJ0aWNhbFwiOlwiaG9yaXpvbnRhbFwifSxfbm9ybVZhbHVlRnJvbU1vdXNlOmZ1bmN0aW9uKHQpe3ZhciBlLGkscyxuLG87cmV0dXJuXCJob3Jpem9udGFsXCI9PT10aGlzLm9yaWVudGF0aW9uPyhlPXRoaXMuZWxlbWVudFNpemUud2lkdGgsaT10LngtdGhpcy5lbGVtZW50T2Zmc2V0LmxlZnQtKHRoaXMuX2NsaWNrT2Zmc2V0P3RoaXMuX2NsaWNrT2Zmc2V0LmxlZnQ6MCkpOihlPXRoaXMuZWxlbWVudFNpemUuaGVpZ2h0LGk9dC55LXRoaXMuZWxlbWVudE9mZnNldC50b3AtKHRoaXMuX2NsaWNrT2Zmc2V0P3RoaXMuX2NsaWNrT2Zmc2V0LnRvcDowKSkscz1pL2Uscz4xJiYocz0xKSwwPnMmJihzPTApLFwidmVydGljYWxcIj09PXRoaXMub3JpZW50YXRpb24mJihzPTEtcyksbj10aGlzLl92YWx1ZU1heCgpLXRoaXMuX3ZhbHVlTWluKCksbz10aGlzLl92YWx1ZU1pbigpK3Mqbix0aGlzLl90cmltQWxpZ25WYWx1ZShvKX0sX3VpSGFzaDpmdW5jdGlvbih0LGUsaSl7dmFyIHM9e2hhbmRsZTp0aGlzLmhhbmRsZXNbdF0saGFuZGxlSW5kZXg6dCx2YWx1ZTp2b2lkIDAhPT1lP2U6dGhpcy52YWx1ZSgpfTtyZXR1cm4gdGhpcy5faGFzTXVsdGlwbGVWYWx1ZXMoKSYmKHMudmFsdWU9dm9pZCAwIT09ZT9lOnRoaXMudmFsdWVzKHQpLHMudmFsdWVzPWl8fHRoaXMudmFsdWVzKCkpLHN9LF9oYXNNdWx0aXBsZVZhbHVlczpmdW5jdGlvbigpe3JldHVybiB0aGlzLm9wdGlvbnMudmFsdWVzJiZ0aGlzLm9wdGlvbnMudmFsdWVzLmxlbmd0aH0sX3N0YXJ0OmZ1bmN0aW9uKHQsZSl7cmV0dXJuIHRoaXMuX3RyaWdnZXIoXCJzdGFydFwiLHQsdGhpcy5fdWlIYXNoKGUpKX0sX3NsaWRlOmZ1bmN0aW9uKHQsZSxpKXt2YXIgcyxuLG89dGhpcy52YWx1ZSgpLGE9dGhpcy52YWx1ZXMoKTt0aGlzLl9oYXNNdWx0aXBsZVZhbHVlcygpJiYobj10aGlzLnZhbHVlcyhlPzA6MSksbz10aGlzLnZhbHVlcyhlKSwyPT09dGhpcy5vcHRpb25zLnZhbHVlcy5sZW5ndGgmJnRoaXMub3B0aW9ucy5yYW5nZT09PSEwJiYoaT0wPT09ZT9NYXRoLm1pbihuLGkpOk1hdGgubWF4KG4saSkpLGFbZV09aSksaSE9PW8mJihzPXRoaXMuX3RyaWdnZXIoXCJzbGlkZVwiLHQsdGhpcy5fdWlIYXNoKGUsaSxhKSkscyE9PSExJiYodGhpcy5faGFzTXVsdGlwbGVWYWx1ZXMoKT90aGlzLnZhbHVlcyhlLGkpOnRoaXMudmFsdWUoaSkpKX0sX3N0b3A6ZnVuY3Rpb24odCxlKXt0aGlzLl90cmlnZ2VyKFwic3RvcFwiLHQsdGhpcy5fdWlIYXNoKGUpKX0sX2NoYW5nZTpmdW5jdGlvbih0LGUpe3RoaXMuX2tleVNsaWRpbmd8fHRoaXMuX21vdXNlU2xpZGluZ3x8KHRoaXMuX2xhc3RDaGFuZ2VkVmFsdWU9ZSx0aGlzLl90cmlnZ2VyKFwiY2hhbmdlXCIsdCx0aGlzLl91aUhhc2goZSkpKX0sdmFsdWU6ZnVuY3Rpb24odCl7cmV0dXJuIGFyZ3VtZW50cy5sZW5ndGg/KHRoaXMub3B0aW9ucy52YWx1ZT10aGlzLl90cmltQWxpZ25WYWx1ZSh0KSx0aGlzLl9yZWZyZXNoVmFsdWUoKSx0aGlzLl9jaGFuZ2UobnVsbCwwKSx2b2lkIDApOnRoaXMuX3ZhbHVlKCl9LHZhbHVlczpmdW5jdGlvbihlLGkpe3ZhciBzLG4sbztpZihhcmd1bWVudHMubGVuZ3RoPjEpcmV0dXJuIHRoaXMub3B0aW9ucy52YWx1ZXNbZV09dGhpcy5fdHJpbUFsaWduVmFsdWUoaSksdGhpcy5fcmVmcmVzaFZhbHVlKCksdGhpcy5fY2hhbmdlKG51bGwsZSksdm9pZCAwO2lmKCFhcmd1bWVudHMubGVuZ3RoKXJldHVybiB0aGlzLl92YWx1ZXMoKTtpZighdC5pc0FycmF5KGFyZ3VtZW50c1swXSkpcmV0dXJuIHRoaXMuX2hhc011bHRpcGxlVmFsdWVzKCk/dGhpcy5fdmFsdWVzKGUpOnRoaXMudmFsdWUoKTtmb3Iocz10aGlzLm9wdGlvbnMudmFsdWVzLG49YXJndW1lbnRzWzBdLG89MDtzLmxlbmd0aD5vO28rPTEpc1tvXT10aGlzLl90cmltQWxpZ25WYWx1ZShuW29dKSx0aGlzLl9jaGFuZ2UobnVsbCxvKTt0aGlzLl9yZWZyZXNoVmFsdWUoKX0sX3NldE9wdGlvbjpmdW5jdGlvbihlLGkpe3ZhciBzLG49MDtzd2l0Y2goXCJyYW5nZVwiPT09ZSYmdGhpcy5vcHRpb25zLnJhbmdlPT09ITAmJihcIm1pblwiPT09aT8odGhpcy5vcHRpb25zLnZhbHVlPXRoaXMuX3ZhbHVlcygwKSx0aGlzLm9wdGlvbnMudmFsdWVzPW51bGwpOlwibWF4XCI9PT1pJiYodGhpcy5vcHRpb25zLnZhbHVlPXRoaXMuX3ZhbHVlcyh0aGlzLm9wdGlvbnMudmFsdWVzLmxlbmd0aC0xKSx0aGlzLm9wdGlvbnMudmFsdWVzPW51bGwpKSx0LmlzQXJyYXkodGhpcy5vcHRpb25zLnZhbHVlcykmJihuPXRoaXMub3B0aW9ucy52YWx1ZXMubGVuZ3RoKSx0aGlzLl9zdXBlcihlLGkpLGUpe2Nhc2VcIm9yaWVudGF0aW9uXCI6dGhpcy5fZGV0ZWN0T3JpZW50YXRpb24oKSx0aGlzLl9yZW1vdmVDbGFzcyhcInVpLXNsaWRlci1ob3Jpem9udGFsIHVpLXNsaWRlci12ZXJ0aWNhbFwiKS5fYWRkQ2xhc3MoXCJ1aS1zbGlkZXItXCIrdGhpcy5vcmllbnRhdGlvbiksdGhpcy5fcmVmcmVzaFZhbHVlKCksdGhpcy5vcHRpb25zLnJhbmdlJiZ0aGlzLl9yZWZyZXNoUmFuZ2UoaSksdGhpcy5oYW5kbGVzLmNzcyhcImhvcml6b250YWxcIj09PWk/XCJib3R0b21cIjpcImxlZnRcIixcIlwiKTticmVhaztjYXNlXCJ2YWx1ZVwiOnRoaXMuX2FuaW1hdGVPZmY9ITAsdGhpcy5fcmVmcmVzaFZhbHVlKCksdGhpcy5fY2hhbmdlKG51bGwsMCksdGhpcy5fYW5pbWF0ZU9mZj0hMTticmVhaztjYXNlXCJ2YWx1ZXNcIjpmb3IodGhpcy5fYW5pbWF0ZU9mZj0hMCx0aGlzLl9yZWZyZXNoVmFsdWUoKSxzPW4tMTtzPj0wO3MtLSl0aGlzLl9jaGFuZ2UobnVsbCxzKTt0aGlzLl9hbmltYXRlT2ZmPSExO2JyZWFrO2Nhc2VcInN0ZXBcIjpjYXNlXCJtaW5cIjpjYXNlXCJtYXhcIjp0aGlzLl9hbmltYXRlT2ZmPSEwLHRoaXMuX2NhbGN1bGF0ZU5ld01heCgpLHRoaXMuX3JlZnJlc2hWYWx1ZSgpLHRoaXMuX2FuaW1hdGVPZmY9ITE7YnJlYWs7Y2FzZVwicmFuZ2VcIjp0aGlzLl9hbmltYXRlT2ZmPSEwLHRoaXMuX3JlZnJlc2goKSx0aGlzLl9hbmltYXRlT2ZmPSExfX0sX3NldE9wdGlvbkRpc2FibGVkOmZ1bmN0aW9uKHQpe3RoaXMuX3N1cGVyKHQpLHRoaXMuX3RvZ2dsZUNsYXNzKG51bGwsXCJ1aS1zdGF0ZS1kaXNhYmxlZFwiLCEhdCl9LF92YWx1ZTpmdW5jdGlvbigpe3ZhciB0PXRoaXMub3B0aW9ucy52YWx1ZTtyZXR1cm4gdD10aGlzLl90cmltQWxpZ25WYWx1ZSh0KX0sX3ZhbHVlczpmdW5jdGlvbih0KXt2YXIgZSxpLHM7aWYoYXJndW1lbnRzLmxlbmd0aClyZXR1cm4gZT10aGlzLm9wdGlvbnMudmFsdWVzW3RdLGU9dGhpcy5fdHJpbUFsaWduVmFsdWUoZSk7aWYodGhpcy5faGFzTXVsdGlwbGVWYWx1ZXMoKSl7Zm9yKGk9dGhpcy5vcHRpb25zLnZhbHVlcy5zbGljZSgpLHM9MDtpLmxlbmd0aD5zO3MrPTEpaVtzXT10aGlzLl90cmltQWxpZ25WYWx1ZShpW3NdKTtyZXR1cm4gaX1yZXR1cm5bXX0sX3RyaW1BbGlnblZhbHVlOmZ1bmN0aW9uKHQpe2lmKHRoaXMuX3ZhbHVlTWluKCk+PXQpcmV0dXJuIHRoaXMuX3ZhbHVlTWluKCk7aWYodD49dGhpcy5fdmFsdWVNYXgoKSlyZXR1cm4gdGhpcy5fdmFsdWVNYXgoKTt2YXIgZT10aGlzLm9wdGlvbnMuc3RlcD4wP3RoaXMub3B0aW9ucy5zdGVwOjEsaT0odC10aGlzLl92YWx1ZU1pbigpKSVlLHM9dC1pO3JldHVybiAyKk1hdGguYWJzKGkpPj1lJiYocys9aT4wP2U6LWUpLHBhcnNlRmxvYXQocy50b0ZpeGVkKDUpKX0sX2NhbGN1bGF0ZU5ld01heDpmdW5jdGlvbigpe3ZhciB0PXRoaXMub3B0aW9ucy5tYXgsZT10aGlzLl92YWx1ZU1pbigpLGk9dGhpcy5vcHRpb25zLnN0ZXAscz1NYXRoLnJvdW5kKCh0LWUpL2kpKmk7dD1zK2UsdD50aGlzLm9wdGlvbnMubWF4JiYodC09aSksdGhpcy5tYXg9cGFyc2VGbG9hdCh0LnRvRml4ZWQodGhpcy5fcHJlY2lzaW9uKCkpKX0sX3ByZWNpc2lvbjpmdW5jdGlvbigpe3ZhciB0PXRoaXMuX3ByZWNpc2lvbk9mKHRoaXMub3B0aW9ucy5zdGVwKTtyZXR1cm4gbnVsbCE9PXRoaXMub3B0aW9ucy5taW4mJih0PU1hdGgubWF4KHQsdGhpcy5fcHJlY2lzaW9uT2YodGhpcy5vcHRpb25zLm1pbikpKSx0fSxfcHJlY2lzaW9uT2Y6ZnVuY3Rpb24odCl7dmFyIGU9XCJcIit0LGk9ZS5pbmRleE9mKFwiLlwiKTtyZXR1cm4tMT09PWk/MDplLmxlbmd0aC1pLTF9LF92YWx1ZU1pbjpmdW5jdGlvbigpe3JldHVybiB0aGlzLm9wdGlvbnMubWlufSxfdmFsdWVNYXg6ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5tYXh9LF9yZWZyZXNoUmFuZ2U6ZnVuY3Rpb24odCl7XCJ2ZXJ0aWNhbFwiPT09dCYmdGhpcy5yYW5nZS5jc3Moe3dpZHRoOlwiXCIsbGVmdDpcIlwifSksXCJob3Jpem9udGFsXCI9PT10JiZ0aGlzLnJhbmdlLmNzcyh7aGVpZ2h0OlwiXCIsYm90dG9tOlwiXCJ9KX0sX3JlZnJlc2hWYWx1ZTpmdW5jdGlvbigpe3ZhciBlLGkscyxuLG8sYT10aGlzLm9wdGlvbnMucmFuZ2Uscj10aGlzLm9wdGlvbnMsaD10aGlzLGw9dGhpcy5fYW5pbWF0ZU9mZj8hMTpyLmFuaW1hdGUsYz17fTt0aGlzLl9oYXNNdWx0aXBsZVZhbHVlcygpP3RoaXMuaGFuZGxlcy5lYWNoKGZ1bmN0aW9uKHMpe2k9MTAwKigoaC52YWx1ZXMocyktaC5fdmFsdWVNaW4oKSkvKGguX3ZhbHVlTWF4KCktaC5fdmFsdWVNaW4oKSkpLGNbXCJob3Jpem9udGFsXCI9PT1oLm9yaWVudGF0aW9uP1wibGVmdFwiOlwiYm90dG9tXCJdPWkrXCIlXCIsdCh0aGlzKS5zdG9wKDEsMSlbbD9cImFuaW1hdGVcIjpcImNzc1wiXShjLHIuYW5pbWF0ZSksaC5vcHRpb25zLnJhbmdlPT09ITAmJihcImhvcml6b250YWxcIj09PWgub3JpZW50YXRpb24/KDA9PT1zJiZoLnJhbmdlLnN0b3AoMSwxKVtsP1wiYW5pbWF0ZVwiOlwiY3NzXCJdKHtsZWZ0OmkrXCIlXCJ9LHIuYW5pbWF0ZSksMT09PXMmJmgucmFuZ2VbbD9cImFuaW1hdGVcIjpcImNzc1wiXSh7d2lkdGg6aS1lK1wiJVwifSx7cXVldWU6ITEsZHVyYXRpb246ci5hbmltYXRlfSkpOigwPT09cyYmaC5yYW5nZS5zdG9wKDEsMSlbbD9cImFuaW1hdGVcIjpcImNzc1wiXSh7Ym90dG9tOmkrXCIlXCJ9LHIuYW5pbWF0ZSksMT09PXMmJmgucmFuZ2VbbD9cImFuaW1hdGVcIjpcImNzc1wiXSh7aGVpZ2h0OmktZStcIiVcIn0se3F1ZXVlOiExLGR1cmF0aW9uOnIuYW5pbWF0ZX0pKSksZT1pfSk6KHM9dGhpcy52YWx1ZSgpLG49dGhpcy5fdmFsdWVNaW4oKSxvPXRoaXMuX3ZhbHVlTWF4KCksaT1vIT09bj8xMDAqKChzLW4pLyhvLW4pKTowLGNbXCJob3Jpem9udGFsXCI9PT10aGlzLm9yaWVudGF0aW9uP1wibGVmdFwiOlwiYm90dG9tXCJdPWkrXCIlXCIsdGhpcy5oYW5kbGUuc3RvcCgxLDEpW2w/XCJhbmltYXRlXCI6XCJjc3NcIl0oYyxyLmFuaW1hdGUpLFwibWluXCI9PT1hJiZcImhvcml6b250YWxcIj09PXRoaXMub3JpZW50YXRpb24mJnRoaXMucmFuZ2Uuc3RvcCgxLDEpW2w/XCJhbmltYXRlXCI6XCJjc3NcIl0oe3dpZHRoOmkrXCIlXCJ9LHIuYW5pbWF0ZSksXCJtYXhcIj09PWEmJlwiaG9yaXpvbnRhbFwiPT09dGhpcy5vcmllbnRhdGlvbiYmdGhpcy5yYW5nZS5zdG9wKDEsMSlbbD9cImFuaW1hdGVcIjpcImNzc1wiXSh7d2lkdGg6MTAwLWkrXCIlXCJ9LHIuYW5pbWF0ZSksXCJtaW5cIj09PWEmJlwidmVydGljYWxcIj09PXRoaXMub3JpZW50YXRpb24mJnRoaXMucmFuZ2Uuc3RvcCgxLDEpW2w/XCJhbmltYXRlXCI6XCJjc3NcIl0oe2hlaWdodDppK1wiJVwifSxyLmFuaW1hdGUpLFwibWF4XCI9PT1hJiZcInZlcnRpY2FsXCI9PT10aGlzLm9yaWVudGF0aW9uJiZ0aGlzLnJhbmdlLnN0b3AoMSwxKVtsP1wiYW5pbWF0ZVwiOlwiY3NzXCJdKHtoZWlnaHQ6MTAwLWkrXCIlXCJ9LHIuYW5pbWF0ZSkpfSxfaGFuZGxlRXZlbnRzOntrZXlkb3duOmZ1bmN0aW9uKGUpe3ZhciBpLHMsbixvLGE9dChlLnRhcmdldCkuZGF0YShcInVpLXNsaWRlci1oYW5kbGUtaW5kZXhcIik7c3dpdGNoKGUua2V5Q29kZSl7Y2FzZSB0LnVpLmtleUNvZGUuSE9NRTpjYXNlIHQudWkua2V5Q29kZS5FTkQ6Y2FzZSB0LnVpLmtleUNvZGUuUEFHRV9VUDpjYXNlIHQudWkua2V5Q29kZS5QQUdFX0RPV046Y2FzZSB0LnVpLmtleUNvZGUuVVA6Y2FzZSB0LnVpLmtleUNvZGUuUklHSFQ6Y2FzZSB0LnVpLmtleUNvZGUuRE9XTjpjYXNlIHQudWkua2V5Q29kZS5MRUZUOmlmKGUucHJldmVudERlZmF1bHQoKSwhdGhpcy5fa2V5U2xpZGluZyYmKHRoaXMuX2tleVNsaWRpbmc9ITAsdGhpcy5fYWRkQ2xhc3ModChlLnRhcmdldCksbnVsbCxcInVpLXN0YXRlLWFjdGl2ZVwiKSxpPXRoaXMuX3N0YXJ0KGUsYSksaT09PSExKSlyZXR1cm59c3dpdGNoKG89dGhpcy5vcHRpb25zLnN0ZXAscz1uPXRoaXMuX2hhc011bHRpcGxlVmFsdWVzKCk/dGhpcy52YWx1ZXMoYSk6dGhpcy52YWx1ZSgpLGUua2V5Q29kZSl7Y2FzZSB0LnVpLmtleUNvZGUuSE9NRTpuPXRoaXMuX3ZhbHVlTWluKCk7YnJlYWs7Y2FzZSB0LnVpLmtleUNvZGUuRU5EOm49dGhpcy5fdmFsdWVNYXgoKTticmVhaztjYXNlIHQudWkua2V5Q29kZS5QQUdFX1VQOm49dGhpcy5fdHJpbUFsaWduVmFsdWUocysodGhpcy5fdmFsdWVNYXgoKS10aGlzLl92YWx1ZU1pbigpKS90aGlzLm51bVBhZ2VzKTticmVhaztjYXNlIHQudWkua2V5Q29kZS5QQUdFX0RPV046bj10aGlzLl90cmltQWxpZ25WYWx1ZShzLSh0aGlzLl92YWx1ZU1heCgpLXRoaXMuX3ZhbHVlTWluKCkpL3RoaXMubnVtUGFnZXMpO2JyZWFrO2Nhc2UgdC51aS5rZXlDb2RlLlVQOmNhc2UgdC51aS5rZXlDb2RlLlJJR0hUOmlmKHM9PT10aGlzLl92YWx1ZU1heCgpKXJldHVybjtuPXRoaXMuX3RyaW1BbGlnblZhbHVlKHMrbyk7YnJlYWs7Y2FzZSB0LnVpLmtleUNvZGUuRE9XTjpjYXNlIHQudWkua2V5Q29kZS5MRUZUOmlmKHM9PT10aGlzLl92YWx1ZU1pbigpKXJldHVybjtuPXRoaXMuX3RyaW1BbGlnblZhbHVlKHMtbyl9dGhpcy5fc2xpZGUoZSxhLG4pfSxrZXl1cDpmdW5jdGlvbihlKXt2YXIgaT10KGUudGFyZ2V0KS5kYXRhKFwidWktc2xpZGVyLWhhbmRsZS1pbmRleFwiKTt0aGlzLl9rZXlTbGlkaW5nJiYodGhpcy5fa2V5U2xpZGluZz0hMSx0aGlzLl9zdG9wKGUsaSksdGhpcy5fY2hhbmdlKGUsaSksdGhpcy5fcmVtb3ZlQ2xhc3ModChlLnRhcmdldCksbnVsbCxcInVpLXN0YXRlLWFjdGl2ZVwiKSl9fX0pLHQud2lkZ2V0KFwidWkuc3Bpbm5lclwiLHt2ZXJzaW9uOlwiMS4xMi4xXCIsZGVmYXVsdEVsZW1lbnQ6XCI8aW5wdXQ+XCIsd2lkZ2V0RXZlbnRQcmVmaXg6XCJzcGluXCIsb3B0aW9uczp7Y2xhc3Nlczp7XCJ1aS1zcGlubmVyXCI6XCJ1aS1jb3JuZXItYWxsXCIsXCJ1aS1zcGlubmVyLWRvd25cIjpcInVpLWNvcm5lci1iclwiLFwidWktc3Bpbm5lci11cFwiOlwidWktY29ybmVyLXRyXCJ9LGN1bHR1cmU6bnVsbCxpY29uczp7ZG93bjpcInVpLWljb24tdHJpYW5nbGUtMS1zXCIsdXA6XCJ1aS1pY29uLXRyaWFuZ2xlLTEtblwifSxpbmNyZW1lbnRhbDohMCxtYXg6bnVsbCxtaW46bnVsbCxudW1iZXJGb3JtYXQ6bnVsbCxwYWdlOjEwLHN0ZXA6MSxjaGFuZ2U6bnVsbCxzcGluOm51bGwsc3RhcnQ6bnVsbCxzdG9wOm51bGx9LF9jcmVhdGU6ZnVuY3Rpb24oKXt0aGlzLl9zZXRPcHRpb24oXCJtYXhcIix0aGlzLm9wdGlvbnMubWF4KSx0aGlzLl9zZXRPcHRpb24oXCJtaW5cIix0aGlzLm9wdGlvbnMubWluKSx0aGlzLl9zZXRPcHRpb24oXCJzdGVwXCIsdGhpcy5vcHRpb25zLnN0ZXApLFwiXCIhPT10aGlzLnZhbHVlKCkmJnRoaXMuX3ZhbHVlKHRoaXMuZWxlbWVudC52YWwoKSwhMCksdGhpcy5fZHJhdygpLHRoaXMuX29uKHRoaXMuX2V2ZW50cyksdGhpcy5fcmVmcmVzaCgpLHRoaXMuX29uKHRoaXMud2luZG93LHtiZWZvcmV1bmxvYWQ6ZnVuY3Rpb24oKXt0aGlzLmVsZW1lbnQucmVtb3ZlQXR0cihcImF1dG9jb21wbGV0ZVwiKX19KX0sX2dldENyZWF0ZU9wdGlvbnM6ZnVuY3Rpb24oKXt2YXIgZT10aGlzLl9zdXBlcigpLGk9dGhpcy5lbGVtZW50O3JldHVybiB0LmVhY2goW1wibWluXCIsXCJtYXhcIixcInN0ZXBcIl0sZnVuY3Rpb24odCxzKXt2YXIgbj1pLmF0dHIocyk7bnVsbCE9biYmbi5sZW5ndGgmJihlW3NdPW4pfSksZX0sX2V2ZW50czp7a2V5ZG93bjpmdW5jdGlvbih0KXt0aGlzLl9zdGFydCh0KSYmdGhpcy5fa2V5ZG93bih0KSYmdC5wcmV2ZW50RGVmYXVsdCgpfSxrZXl1cDpcIl9zdG9wXCIsZm9jdXM6ZnVuY3Rpb24oKXt0aGlzLnByZXZpb3VzPXRoaXMuZWxlbWVudC52YWwoKX0sYmx1cjpmdW5jdGlvbih0KXtyZXR1cm4gdGhpcy5jYW5jZWxCbHVyPyhkZWxldGUgdGhpcy5jYW5jZWxCbHVyLHZvaWQgMCk6KHRoaXMuX3N0b3AoKSx0aGlzLl9yZWZyZXNoKCksdGhpcy5wcmV2aW91cyE9PXRoaXMuZWxlbWVudC52YWwoKSYmdGhpcy5fdHJpZ2dlcihcImNoYW5nZVwiLHQpLHZvaWQgMCl9LG1vdXNld2hlZWw6ZnVuY3Rpb24odCxlKXtpZihlKXtpZighdGhpcy5zcGlubmluZyYmIXRoaXMuX3N0YXJ0KHQpKXJldHVybiExO3RoaXMuX3NwaW4oKGU+MD8xOi0xKSp0aGlzLm9wdGlvbnMuc3RlcCx0KSxjbGVhclRpbWVvdXQodGhpcy5tb3VzZXdoZWVsVGltZXIpLHRoaXMubW91c2V3aGVlbFRpbWVyPXRoaXMuX2RlbGF5KGZ1bmN0aW9uKCl7dGhpcy5zcGlubmluZyYmdGhpcy5fc3RvcCh0KX0sMTAwKSx0LnByZXZlbnREZWZhdWx0KCl9fSxcIm1vdXNlZG93biAudWktc3Bpbm5lci1idXR0b25cIjpmdW5jdGlvbihlKXtmdW5jdGlvbiBpKCl7dmFyIGU9dGhpcy5lbGVtZW50WzBdPT09dC51aS5zYWZlQWN0aXZlRWxlbWVudCh0aGlzLmRvY3VtZW50WzBdKTtlfHwodGhpcy5lbGVtZW50LnRyaWdnZXIoXCJmb2N1c1wiKSx0aGlzLnByZXZpb3VzPXMsdGhpcy5fZGVsYXkoZnVuY3Rpb24oKXt0aGlzLnByZXZpb3VzPXN9KSl9dmFyIHM7cz10aGlzLmVsZW1lbnRbMF09PT10LnVpLnNhZmVBY3RpdmVFbGVtZW50KHRoaXMuZG9jdW1lbnRbMF0pP3RoaXMucHJldmlvdXM6dGhpcy5lbGVtZW50LnZhbCgpLGUucHJldmVudERlZmF1bHQoKSxpLmNhbGwodGhpcyksdGhpcy5jYW5jZWxCbHVyPSEwLHRoaXMuX2RlbGF5KGZ1bmN0aW9uKCl7ZGVsZXRlIHRoaXMuY2FuY2VsQmx1cixpLmNhbGwodGhpcyl9KSx0aGlzLl9zdGFydChlKSE9PSExJiZ0aGlzLl9yZXBlYXQobnVsbCx0KGUuY3VycmVudFRhcmdldCkuaGFzQ2xhc3MoXCJ1aS1zcGlubmVyLXVwXCIpPzE6LTEsZSl9LFwibW91c2V1cCAudWktc3Bpbm5lci1idXR0b25cIjpcIl9zdG9wXCIsXCJtb3VzZWVudGVyIC51aS1zcGlubmVyLWJ1dHRvblwiOmZ1bmN0aW9uKGUpe3JldHVybiB0KGUuY3VycmVudFRhcmdldCkuaGFzQ2xhc3MoXCJ1aS1zdGF0ZS1hY3RpdmVcIik/dGhpcy5fc3RhcnQoZSk9PT0hMT8hMToodGhpcy5fcmVwZWF0KG51bGwsdChlLmN1cnJlbnRUYXJnZXQpLmhhc0NsYXNzKFwidWktc3Bpbm5lci11cFwiKT8xOi0xLGUpLHZvaWQgMCk6dm9pZCAwfSxcIm1vdXNlbGVhdmUgLnVpLXNwaW5uZXItYnV0dG9uXCI6XCJfc3RvcFwifSxfZW5oYW5jZTpmdW5jdGlvbigpe3RoaXMudWlTcGlubmVyPXRoaXMuZWxlbWVudC5hdHRyKFwiYXV0b2NvbXBsZXRlXCIsXCJvZmZcIikud3JhcChcIjxzcGFuPlwiKS5wYXJlbnQoKS5hcHBlbmQoXCI8YT48L2E+PGE+PC9hPlwiKX0sX2RyYXc6ZnVuY3Rpb24oKXt0aGlzLl9lbmhhbmNlKCksdGhpcy5fYWRkQ2xhc3ModGhpcy51aVNwaW5uZXIsXCJ1aS1zcGlubmVyXCIsXCJ1aS13aWRnZXQgdWktd2lkZ2V0LWNvbnRlbnRcIiksdGhpcy5fYWRkQ2xhc3MoXCJ1aS1zcGlubmVyLWlucHV0XCIpLHRoaXMuZWxlbWVudC5hdHRyKFwicm9sZVwiLFwic3BpbmJ1dHRvblwiKSx0aGlzLmJ1dHRvbnM9dGhpcy51aVNwaW5uZXIuY2hpbGRyZW4oXCJhXCIpLmF0dHIoXCJ0YWJJbmRleFwiLC0xKS5hdHRyKFwiYXJpYS1oaWRkZW5cIiwhMCkuYnV0dG9uKHtjbGFzc2VzOntcInVpLWJ1dHRvblwiOlwiXCJ9fSksdGhpcy5fcmVtb3ZlQ2xhc3ModGhpcy5idXR0b25zLFwidWktY29ybmVyLWFsbFwiKSx0aGlzLl9hZGRDbGFzcyh0aGlzLmJ1dHRvbnMuZmlyc3QoKSxcInVpLXNwaW5uZXItYnV0dG9uIHVpLXNwaW5uZXItdXBcIiksdGhpcy5fYWRkQ2xhc3ModGhpcy5idXR0b25zLmxhc3QoKSxcInVpLXNwaW5uZXItYnV0dG9uIHVpLXNwaW5uZXItZG93blwiKSx0aGlzLmJ1dHRvbnMuZmlyc3QoKS5idXR0b24oe2ljb246dGhpcy5vcHRpb25zLmljb25zLnVwLHNob3dMYWJlbDohMX0pLHRoaXMuYnV0dG9ucy5sYXN0KCkuYnV0dG9uKHtpY29uOnRoaXMub3B0aW9ucy5pY29ucy5kb3duLHNob3dMYWJlbDohMX0pLHRoaXMuYnV0dG9ucy5oZWlnaHQoKT5NYXRoLmNlaWwoLjUqdGhpcy51aVNwaW5uZXIuaGVpZ2h0KCkpJiZ0aGlzLnVpU3Bpbm5lci5oZWlnaHQoKT4wJiZ0aGlzLnVpU3Bpbm5lci5oZWlnaHQodGhpcy51aVNwaW5uZXIuaGVpZ2h0KCkpfSxfa2V5ZG93bjpmdW5jdGlvbihlKXt2YXIgaT10aGlzLm9wdGlvbnMscz10LnVpLmtleUNvZGU7c3dpdGNoKGUua2V5Q29kZSl7Y2FzZSBzLlVQOnJldHVybiB0aGlzLl9yZXBlYXQobnVsbCwxLGUpLCEwO2Nhc2Ugcy5ET1dOOnJldHVybiB0aGlzLl9yZXBlYXQobnVsbCwtMSxlKSwhMDtjYXNlIHMuUEFHRV9VUDpyZXR1cm4gdGhpcy5fcmVwZWF0KG51bGwsaS5wYWdlLGUpLCEwO2Nhc2Ugcy5QQUdFX0RPV046cmV0dXJuIHRoaXMuX3JlcGVhdChudWxsLC1pLnBhZ2UsZSksITB9cmV0dXJuITF9LF9zdGFydDpmdW5jdGlvbih0KXtyZXR1cm4gdGhpcy5zcGlubmluZ3x8dGhpcy5fdHJpZ2dlcihcInN0YXJ0XCIsdCkhPT0hMT8odGhpcy5jb3VudGVyfHwodGhpcy5jb3VudGVyPTEpLHRoaXMuc3Bpbm5pbmc9ITAsITApOiExfSxfcmVwZWF0OmZ1bmN0aW9uKHQsZSxpKXt0PXR8fDUwMCxjbGVhclRpbWVvdXQodGhpcy50aW1lciksdGhpcy50aW1lcj10aGlzLl9kZWxheShmdW5jdGlvbigpe3RoaXMuX3JlcGVhdCg0MCxlLGkpfSx0KSx0aGlzLl9zcGluKGUqdGhpcy5vcHRpb25zLnN0ZXAsaSl9LF9zcGluOmZ1bmN0aW9uKHQsZSl7dmFyIGk9dGhpcy52YWx1ZSgpfHwwO3RoaXMuY291bnRlcnx8KHRoaXMuY291bnRlcj0xKSxpPXRoaXMuX2FkanVzdFZhbHVlKGkrdCp0aGlzLl9pbmNyZW1lbnQodGhpcy5jb3VudGVyKSksdGhpcy5zcGlubmluZyYmdGhpcy5fdHJpZ2dlcihcInNwaW5cIixlLHt2YWx1ZTppfSk9PT0hMXx8KHRoaXMuX3ZhbHVlKGkpLHRoaXMuY291bnRlcisrKX0sX2luY3JlbWVudDpmdW5jdGlvbihlKXt2YXIgaT10aGlzLm9wdGlvbnMuaW5jcmVtZW50YWw7cmV0dXJuIGk/dC5pc0Z1bmN0aW9uKGkpP2koZSk6TWF0aC5mbG9vcihlKmUqZS81ZTQtZSplLzUwMCsxNyplLzIwMCsxKToxfSxfcHJlY2lzaW9uOmZ1bmN0aW9uKCl7dmFyIHQ9dGhpcy5fcHJlY2lzaW9uT2YodGhpcy5vcHRpb25zLnN0ZXApO3JldHVybiBudWxsIT09dGhpcy5vcHRpb25zLm1pbiYmKHQ9TWF0aC5tYXgodCx0aGlzLl9wcmVjaXNpb25PZih0aGlzLm9wdGlvbnMubWluKSkpLHR9LF9wcmVjaXNpb25PZjpmdW5jdGlvbih0KXt2YXIgZT1cIlwiK3QsaT1lLmluZGV4T2YoXCIuXCIpO3JldHVybi0xPT09aT8wOmUubGVuZ3RoLWktMX0sX2FkanVzdFZhbHVlOmZ1bmN0aW9uKHQpe3ZhciBlLGkscz10aGlzLm9wdGlvbnM7cmV0dXJuIGU9bnVsbCE9PXMubWluP3MubWluOjAsaT10LWUsaT1NYXRoLnJvdW5kKGkvcy5zdGVwKSpzLnN0ZXAsdD1lK2ksdD1wYXJzZUZsb2F0KHQudG9GaXhlZCh0aGlzLl9wcmVjaXNpb24oKSkpLG51bGwhPT1zLm1heCYmdD5zLm1heD9zLm1heDpudWxsIT09cy5taW4mJnMubWluPnQ/cy5taW46dH0sX3N0b3A6ZnVuY3Rpb24odCl7dGhpcy5zcGlubmluZyYmKGNsZWFyVGltZW91dCh0aGlzLnRpbWVyKSxjbGVhclRpbWVvdXQodGhpcy5tb3VzZXdoZWVsVGltZXIpLHRoaXMuY291bnRlcj0wLHRoaXMuc3Bpbm5pbmc9ITEsdGhpcy5fdHJpZ2dlcihcInN0b3BcIix0KSl9LF9zZXRPcHRpb246ZnVuY3Rpb24odCxlKXt2YXIgaSxzLG47cmV0dXJuXCJjdWx0dXJlXCI9PT10fHxcIm51bWJlckZvcm1hdFwiPT09dD8oaT10aGlzLl9wYXJzZSh0aGlzLmVsZW1lbnQudmFsKCkpLHRoaXMub3B0aW9uc1t0XT1lLHRoaXMuZWxlbWVudC52YWwodGhpcy5fZm9ybWF0KGkpKSx2b2lkIDApOigoXCJtYXhcIj09PXR8fFwibWluXCI9PT10fHxcInN0ZXBcIj09PXQpJiZcInN0cmluZ1wiPT10eXBlb2YgZSYmKGU9dGhpcy5fcGFyc2UoZSkpLFwiaWNvbnNcIj09PXQmJihzPXRoaXMuYnV0dG9ucy5maXJzdCgpLmZpbmQoXCIudWktaWNvblwiKSx0aGlzLl9yZW1vdmVDbGFzcyhzLG51bGwsdGhpcy5vcHRpb25zLmljb25zLnVwKSx0aGlzLl9hZGRDbGFzcyhzLG51bGwsZS51cCksbj10aGlzLmJ1dHRvbnMubGFzdCgpLmZpbmQoXCIudWktaWNvblwiKSx0aGlzLl9yZW1vdmVDbGFzcyhuLG51bGwsdGhpcy5vcHRpb25zLmljb25zLmRvd24pLHRoaXMuX2FkZENsYXNzKG4sbnVsbCxlLmRvd24pKSx0aGlzLl9zdXBlcih0LGUpLHZvaWQgMCl9LF9zZXRPcHRpb25EaXNhYmxlZDpmdW5jdGlvbih0KXt0aGlzLl9zdXBlcih0KSx0aGlzLl90b2dnbGVDbGFzcyh0aGlzLnVpU3Bpbm5lcixudWxsLFwidWktc3RhdGUtZGlzYWJsZWRcIiwhIXQpLHRoaXMuZWxlbWVudC5wcm9wKFwiZGlzYWJsZWRcIiwhIXQpLHRoaXMuYnV0dG9ucy5idXR0b24odD9cImRpc2FibGVcIjpcImVuYWJsZVwiKX0sX3NldE9wdGlvbnM6cihmdW5jdGlvbih0KXt0aGlzLl9zdXBlcih0KX0pLF9wYXJzZTpmdW5jdGlvbih0KXtyZXR1cm5cInN0cmluZ1wiPT10eXBlb2YgdCYmXCJcIiE9PXQmJih0PXdpbmRvdy5HbG9iYWxpemUmJnRoaXMub3B0aW9ucy5udW1iZXJGb3JtYXQ/R2xvYmFsaXplLnBhcnNlRmxvYXQodCwxMCx0aGlzLm9wdGlvbnMuY3VsdHVyZSk6K3QpLFwiXCI9PT10fHxpc05hTih0KT9udWxsOnR9LF9mb3JtYXQ6ZnVuY3Rpb24odCl7cmV0dXJuXCJcIj09PXQ/XCJcIjp3aW5kb3cuR2xvYmFsaXplJiZ0aGlzLm9wdGlvbnMubnVtYmVyRm9ybWF0P0dsb2JhbGl6ZS5mb3JtYXQodCx0aGlzLm9wdGlvbnMubnVtYmVyRm9ybWF0LHRoaXMub3B0aW9ucy5jdWx0dXJlKTp0fSxfcmVmcmVzaDpmdW5jdGlvbigpe3RoaXMuZWxlbWVudC5hdHRyKHtcImFyaWEtdmFsdWVtaW5cIjp0aGlzLm9wdGlvbnMubWluLFwiYXJpYS12YWx1ZW1heFwiOnRoaXMub3B0aW9ucy5tYXgsXCJhcmlhLXZhbHVlbm93XCI6dGhpcy5fcGFyc2UodGhpcy5lbGVtZW50LnZhbCgpKX0pfSxpc1ZhbGlkOmZ1bmN0aW9uKCl7dmFyIHQ9dGhpcy52YWx1ZSgpO3JldHVybiBudWxsPT09dD8hMTp0PT09dGhpcy5fYWRqdXN0VmFsdWUodCl9LF92YWx1ZTpmdW5jdGlvbih0LGUpe3ZhciBpO1wiXCIhPT10JiYoaT10aGlzLl9wYXJzZSh0KSxudWxsIT09aSYmKGV8fChpPXRoaXMuX2FkanVzdFZhbHVlKGkpKSx0PXRoaXMuX2Zvcm1hdChpKSkpLHRoaXMuZWxlbWVudC52YWwodCksdGhpcy5fcmVmcmVzaCgpfSxfZGVzdHJveTpmdW5jdGlvbigpe3RoaXMuZWxlbWVudC5wcm9wKFwiZGlzYWJsZWRcIiwhMSkucmVtb3ZlQXR0cihcImF1dG9jb21wbGV0ZSByb2xlIGFyaWEtdmFsdWVtaW4gYXJpYS12YWx1ZW1heCBhcmlhLXZhbHVlbm93XCIpLHRoaXMudWlTcGlubmVyLnJlcGxhY2VXaXRoKHRoaXMuZWxlbWVudCl9LHN0ZXBVcDpyKGZ1bmN0aW9uKHQpe3RoaXMuX3N0ZXBVcCh0KX0pLF9zdGVwVXA6ZnVuY3Rpb24odCl7dGhpcy5fc3RhcnQoKSYmKHRoaXMuX3NwaW4oKHR8fDEpKnRoaXMub3B0aW9ucy5zdGVwKSx0aGlzLl9zdG9wKCkpfSxzdGVwRG93bjpyKGZ1bmN0aW9uKHQpe3RoaXMuX3N0ZXBEb3duKHQpfSksX3N0ZXBEb3duOmZ1bmN0aW9uKHQpe3RoaXMuX3N0YXJ0KCkmJih0aGlzLl9zcGluKCh0fHwxKSotdGhpcy5vcHRpb25zLnN0ZXApLHRoaXMuX3N0b3AoKSl9LHBhZ2VVcDpyKGZ1bmN0aW9uKHQpe3RoaXMuX3N0ZXBVcCgodHx8MSkqdGhpcy5vcHRpb25zLnBhZ2UpfSkscGFnZURvd246cihmdW5jdGlvbih0KXt0aGlzLl9zdGVwRG93bigodHx8MSkqdGhpcy5vcHRpb25zLnBhZ2UpfSksdmFsdWU6ZnVuY3Rpb24odCl7cmV0dXJuIGFyZ3VtZW50cy5sZW5ndGg/KHIodGhpcy5fdmFsdWUpLmNhbGwodGhpcyx0KSx2b2lkIDApOnRoaXMuX3BhcnNlKHRoaXMuZWxlbWVudC52YWwoKSl9LHdpZGdldDpmdW5jdGlvbigpe3JldHVybiB0aGlzLnVpU3Bpbm5lcn19KSx0LnVpQmFja0NvbXBhdCE9PSExJiZ0LndpZGdldChcInVpLnNwaW5uZXJcIix0LnVpLnNwaW5uZXIse19lbmhhbmNlOmZ1bmN0aW9uKCl7dGhpcy51aVNwaW5uZXI9dGhpcy5lbGVtZW50LmF0dHIoXCJhdXRvY29tcGxldGVcIixcIm9mZlwiKS53cmFwKHRoaXMuX3VpU3Bpbm5lckh0bWwoKSkucGFyZW50KCkuYXBwZW5kKHRoaXMuX2J1dHRvbkh0bWwoKSl9LF91aVNwaW5uZXJIdG1sOmZ1bmN0aW9uKCl7cmV0dXJuXCI8c3Bhbj5cIn0sX2J1dHRvbkh0bWw6ZnVuY3Rpb24oKXtyZXR1cm5cIjxhPjwvYT48YT48L2E+XCJ9fSksdC51aS5zcGlubmVyLHQud2lkZ2V0KFwidWkudGFic1wiLHt2ZXJzaW9uOlwiMS4xMi4xXCIsZGVsYXk6MzAwLG9wdGlvbnM6e2FjdGl2ZTpudWxsLGNsYXNzZXM6e1widWktdGFic1wiOlwidWktY29ybmVyLWFsbFwiLFwidWktdGFicy1uYXZcIjpcInVpLWNvcm5lci1hbGxcIixcInVpLXRhYnMtcGFuZWxcIjpcInVpLWNvcm5lci1ib3R0b21cIixcInVpLXRhYnMtdGFiXCI6XCJ1aS1jb3JuZXItdG9wXCJ9LGNvbGxhcHNpYmxlOiExLGV2ZW50OlwiY2xpY2tcIixoZWlnaHRTdHlsZTpcImNvbnRlbnRcIixoaWRlOm51bGwsc2hvdzpudWxsLGFjdGl2YXRlOm51bGwsYmVmb3JlQWN0aXZhdGU6bnVsbCxiZWZvcmVMb2FkOm51bGwsbG9hZDpudWxsfSxfaXNMb2NhbDpmdW5jdGlvbigpe3ZhciB0PS8jLiokLztyZXR1cm4gZnVuY3Rpb24oZSl7dmFyIGkscztpPWUuaHJlZi5yZXBsYWNlKHQsXCJcIikscz1sb2NhdGlvbi5ocmVmLnJlcGxhY2UodCxcIlwiKTt0cnl7aT1kZWNvZGVVUklDb21wb25lbnQoaSl9Y2F0Y2gobil7fXRyeXtzPWRlY29kZVVSSUNvbXBvbmVudChzKX1jYXRjaChuKXt9cmV0dXJuIGUuaGFzaC5sZW5ndGg+MSYmaT09PXN9fSgpLF9jcmVhdGU6ZnVuY3Rpb24oKXt2YXIgZT10aGlzLGk9dGhpcy5vcHRpb25zO3RoaXMucnVubmluZz0hMSx0aGlzLl9hZGRDbGFzcyhcInVpLXRhYnNcIixcInVpLXdpZGdldCB1aS13aWRnZXQtY29udGVudFwiKSx0aGlzLl90b2dnbGVDbGFzcyhcInVpLXRhYnMtY29sbGFwc2libGVcIixudWxsLGkuY29sbGFwc2libGUpLHRoaXMuX3Byb2Nlc3NUYWJzKCksaS5hY3RpdmU9dGhpcy5faW5pdGlhbEFjdGl2ZSgpLHQuaXNBcnJheShpLmRpc2FibGVkKSYmKGkuZGlzYWJsZWQ9dC51bmlxdWUoaS5kaXNhYmxlZC5jb25jYXQodC5tYXAodGhpcy50YWJzLmZpbHRlcihcIi51aS1zdGF0ZS1kaXNhYmxlZFwiKSxmdW5jdGlvbih0KXtyZXR1cm4gZS50YWJzLmluZGV4KHQpfSkpKS5zb3J0KCkpLHRoaXMuYWN0aXZlPXRoaXMub3B0aW9ucy5hY3RpdmUhPT0hMSYmdGhpcy5hbmNob3JzLmxlbmd0aD90aGlzLl9maW5kQWN0aXZlKGkuYWN0aXZlKTp0KCksdGhpcy5fcmVmcmVzaCgpLHRoaXMuYWN0aXZlLmxlbmd0aCYmdGhpcy5sb2FkKGkuYWN0aXZlKX0sX2luaXRpYWxBY3RpdmU6ZnVuY3Rpb24oKXt2YXIgZT10aGlzLm9wdGlvbnMuYWN0aXZlLGk9dGhpcy5vcHRpb25zLmNvbGxhcHNpYmxlLHM9bG9jYXRpb24uaGFzaC5zdWJzdHJpbmcoMSk7cmV0dXJuIG51bGw9PT1lJiYocyYmdGhpcy50YWJzLmVhY2goZnVuY3Rpb24oaSxuKXtyZXR1cm4gdChuKS5hdHRyKFwiYXJpYS1jb250cm9sc1wiKT09PXM/KGU9aSwhMSk6dm9pZCAwfSksbnVsbD09PWUmJihlPXRoaXMudGFicy5pbmRleCh0aGlzLnRhYnMuZmlsdGVyKFwiLnVpLXRhYnMtYWN0aXZlXCIpKSksKG51bGw9PT1lfHwtMT09PWUpJiYoZT10aGlzLnRhYnMubGVuZ3RoPzA6ITEpKSxlIT09ITEmJihlPXRoaXMudGFicy5pbmRleCh0aGlzLnRhYnMuZXEoZSkpLC0xPT09ZSYmKGU9aT8hMTowKSksIWkmJmU9PT0hMSYmdGhpcy5hbmNob3JzLmxlbmd0aCYmKGU9MCksZX0sX2dldENyZWF0ZUV2ZW50RGF0YTpmdW5jdGlvbigpe3JldHVybnt0YWI6dGhpcy5hY3RpdmUscGFuZWw6dGhpcy5hY3RpdmUubGVuZ3RoP3RoaXMuX2dldFBhbmVsRm9yVGFiKHRoaXMuYWN0aXZlKTp0KCl9fSxfdGFiS2V5ZG93bjpmdW5jdGlvbihlKXt2YXIgaT10KHQudWkuc2FmZUFjdGl2ZUVsZW1lbnQodGhpcy5kb2N1bWVudFswXSkpLmNsb3Nlc3QoXCJsaVwiKSxzPXRoaXMudGFicy5pbmRleChpKSxuPSEwO2lmKCF0aGlzLl9oYW5kbGVQYWdlTmF2KGUpKXtzd2l0Y2goZS5rZXlDb2RlKXtjYXNlIHQudWkua2V5Q29kZS5SSUdIVDpjYXNlIHQudWkua2V5Q29kZS5ET1dOOnMrKzticmVhaztjYXNlIHQudWkua2V5Q29kZS5VUDpjYXNlIHQudWkua2V5Q29kZS5MRUZUOm49ITEscy0tO2JyZWFrO2Nhc2UgdC51aS5rZXlDb2RlLkVORDpzPXRoaXMuYW5jaG9ycy5sZW5ndGgtMTticmVhaztjYXNlIHQudWkua2V5Q29kZS5IT01FOnM9MDticmVhaztjYXNlIHQudWkua2V5Q29kZS5TUEFDRTpyZXR1cm4gZS5wcmV2ZW50RGVmYXVsdCgpLGNsZWFyVGltZW91dCh0aGlzLmFjdGl2YXRpbmcpLHRoaXMuX2FjdGl2YXRlKHMpLHZvaWQgMDtjYXNlIHQudWkua2V5Q29kZS5FTlRFUjpyZXR1cm4gZS5wcmV2ZW50RGVmYXVsdCgpLGNsZWFyVGltZW91dCh0aGlzLmFjdGl2YXRpbmcpLHRoaXMuX2FjdGl2YXRlKHM9PT10aGlzLm9wdGlvbnMuYWN0aXZlPyExOnMpLHZvaWQgMDtkZWZhdWx0OnJldHVybn1lLnByZXZlbnREZWZhdWx0KCksY2xlYXJUaW1lb3V0KHRoaXMuYWN0aXZhdGluZykscz10aGlzLl9mb2N1c05leHRUYWIocyxuKSxlLmN0cmxLZXl8fGUubWV0YUtleXx8KGkuYXR0cihcImFyaWEtc2VsZWN0ZWRcIixcImZhbHNlXCIpLHRoaXMudGFicy5lcShzKS5hdHRyKFwiYXJpYS1zZWxlY3RlZFwiLFwidHJ1ZVwiKSx0aGlzLmFjdGl2YXRpbmc9dGhpcy5fZGVsYXkoZnVuY3Rpb24oKXt0aGlzLm9wdGlvbihcImFjdGl2ZVwiLHMpfSx0aGlzLmRlbGF5KSl9fSxfcGFuZWxLZXlkb3duOmZ1bmN0aW9uKGUpe3RoaXMuX2hhbmRsZVBhZ2VOYXYoZSl8fGUuY3RybEtleSYmZS5rZXlDb2RlPT09dC51aS5rZXlDb2RlLlVQJiYoZS5wcmV2ZW50RGVmYXVsdCgpLHRoaXMuYWN0aXZlLnRyaWdnZXIoXCJmb2N1c1wiKSl9LF9oYW5kbGVQYWdlTmF2OmZ1bmN0aW9uKGUpe3JldHVybiBlLmFsdEtleSYmZS5rZXlDb2RlPT09dC51aS5rZXlDb2RlLlBBR0VfVVA/KHRoaXMuX2FjdGl2YXRlKHRoaXMuX2ZvY3VzTmV4dFRhYih0aGlzLm9wdGlvbnMuYWN0aXZlLTEsITEpKSwhMCk6ZS5hbHRLZXkmJmUua2V5Q29kZT09PXQudWkua2V5Q29kZS5QQUdFX0RPV04/KHRoaXMuX2FjdGl2YXRlKHRoaXMuX2ZvY3VzTmV4dFRhYih0aGlzLm9wdGlvbnMuYWN0aXZlKzEsITApKSwhMCk6dm9pZCAwfSxfZmluZE5leHRUYWI6ZnVuY3Rpb24oZSxpKXtmdW5jdGlvbiBzKCl7cmV0dXJuIGU+biYmKGU9MCksMD5lJiYoZT1uKSxlfWZvcih2YXIgbj10aGlzLnRhYnMubGVuZ3RoLTE7LTEhPT10LmluQXJyYXkocygpLHRoaXMub3B0aW9ucy5kaXNhYmxlZCk7KWU9aT9lKzE6ZS0xO3JldHVybiBlfSxfZm9jdXNOZXh0VGFiOmZ1bmN0aW9uKHQsZSl7cmV0dXJuIHQ9dGhpcy5fZmluZE5leHRUYWIodCxlKSx0aGlzLnRhYnMuZXEodCkudHJpZ2dlcihcImZvY3VzXCIpLHR9LF9zZXRPcHRpb246ZnVuY3Rpb24odCxlKXtyZXR1cm5cImFjdGl2ZVwiPT09dD8odGhpcy5fYWN0aXZhdGUoZSksdm9pZCAwKToodGhpcy5fc3VwZXIodCxlKSxcImNvbGxhcHNpYmxlXCI9PT10JiYodGhpcy5fdG9nZ2xlQ2xhc3MoXCJ1aS10YWJzLWNvbGxhcHNpYmxlXCIsbnVsbCxlKSxlfHx0aGlzLm9wdGlvbnMuYWN0aXZlIT09ITF8fHRoaXMuX2FjdGl2YXRlKDApKSxcImV2ZW50XCI9PT10JiZ0aGlzLl9zZXR1cEV2ZW50cyhlKSxcImhlaWdodFN0eWxlXCI9PT10JiZ0aGlzLl9zZXR1cEhlaWdodFN0eWxlKGUpLHZvaWQgMCl9LF9zYW5pdGl6ZVNlbGVjdG9yOmZ1bmN0aW9uKHQpe3JldHVybiB0P3QucmVwbGFjZSgvWyFcIiQlJicoKSorLC5cXC86Ozw9Pj9AXFxbXFxdXFxeYHt8fX5dL2csXCJcXFxcJCZcIik6XCJcIn0scmVmcmVzaDpmdW5jdGlvbigpe3ZhciBlPXRoaXMub3B0aW9ucyxpPXRoaXMudGFibGlzdC5jaGlsZHJlbihcIjpoYXMoYVtocmVmXSlcIik7ZS5kaXNhYmxlZD10Lm1hcChpLmZpbHRlcihcIi51aS1zdGF0ZS1kaXNhYmxlZFwiKSxmdW5jdGlvbih0KXtyZXR1cm4gaS5pbmRleCh0KX0pLHRoaXMuX3Byb2Nlc3NUYWJzKCksZS5hY3RpdmUhPT0hMSYmdGhpcy5hbmNob3JzLmxlbmd0aD90aGlzLmFjdGl2ZS5sZW5ndGgmJiF0LmNvbnRhaW5zKHRoaXMudGFibGlzdFswXSx0aGlzLmFjdGl2ZVswXSk/dGhpcy50YWJzLmxlbmd0aD09PWUuZGlzYWJsZWQubGVuZ3RoPyhlLmFjdGl2ZT0hMSx0aGlzLmFjdGl2ZT10KCkpOnRoaXMuX2FjdGl2YXRlKHRoaXMuX2ZpbmROZXh0VGFiKE1hdGgubWF4KDAsZS5hY3RpdmUtMSksITEpKTplLmFjdGl2ZT10aGlzLnRhYnMuaW5kZXgodGhpcy5hY3RpdmUpOihlLmFjdGl2ZT0hMSx0aGlzLmFjdGl2ZT10KCkpLHRoaXMuX3JlZnJlc2goKX0sX3JlZnJlc2g6ZnVuY3Rpb24oKXt0aGlzLl9zZXRPcHRpb25EaXNhYmxlZCh0aGlzLm9wdGlvbnMuZGlzYWJsZWQpLHRoaXMuX3NldHVwRXZlbnRzKHRoaXMub3B0aW9ucy5ldmVudCksdGhpcy5fc2V0dXBIZWlnaHRTdHlsZSh0aGlzLm9wdGlvbnMuaGVpZ2h0U3R5bGUpLHRoaXMudGFicy5ub3QodGhpcy5hY3RpdmUpLmF0dHIoe1wiYXJpYS1zZWxlY3RlZFwiOlwiZmFsc2VcIixcImFyaWEtZXhwYW5kZWRcIjpcImZhbHNlXCIsdGFiSW5kZXg6LTF9KSx0aGlzLnBhbmVscy5ub3QodGhpcy5fZ2V0UGFuZWxGb3JUYWIodGhpcy5hY3RpdmUpKS5oaWRlKCkuYXR0cih7XCJhcmlhLWhpZGRlblwiOlwidHJ1ZVwifSksdGhpcy5hY3RpdmUubGVuZ3RoPyh0aGlzLmFjdGl2ZS5hdHRyKHtcImFyaWEtc2VsZWN0ZWRcIjpcInRydWVcIixcImFyaWEtZXhwYW5kZWRcIjpcInRydWVcIix0YWJJbmRleDowfSksdGhpcy5fYWRkQ2xhc3ModGhpcy5hY3RpdmUsXCJ1aS10YWJzLWFjdGl2ZVwiLFwidWktc3RhdGUtYWN0aXZlXCIpLHRoaXMuX2dldFBhbmVsRm9yVGFiKHRoaXMuYWN0aXZlKS5zaG93KCkuYXR0cih7XCJhcmlhLWhpZGRlblwiOlwiZmFsc2VcIn0pKTp0aGlzLnRhYnMuZXEoMCkuYXR0cihcInRhYkluZGV4XCIsMCl9LF9wcm9jZXNzVGFiczpmdW5jdGlvbigpe3ZhciBlPXRoaXMsaT10aGlzLnRhYnMscz10aGlzLmFuY2hvcnMsbj10aGlzLnBhbmVsczt0aGlzLnRhYmxpc3Q9dGhpcy5fZ2V0TGlzdCgpLmF0dHIoXCJyb2xlXCIsXCJ0YWJsaXN0XCIpLHRoaXMuX2FkZENsYXNzKHRoaXMudGFibGlzdCxcInVpLXRhYnMtbmF2XCIsXCJ1aS1oZWxwZXItcmVzZXQgdWktaGVscGVyLWNsZWFyZml4IHVpLXdpZGdldC1oZWFkZXJcIiksdGhpcy50YWJsaXN0Lm9uKFwibW91c2Vkb3duXCIrdGhpcy5ldmVudE5hbWVzcGFjZSxcIj4gbGlcIixmdW5jdGlvbihlKXt0KHRoaXMpLmlzKFwiLnVpLXN0YXRlLWRpc2FibGVkXCIpJiZlLnByZXZlbnREZWZhdWx0KCl9KS5vbihcImZvY3VzXCIrdGhpcy5ldmVudE5hbWVzcGFjZSxcIi51aS10YWJzLWFuY2hvclwiLGZ1bmN0aW9uKCl7dCh0aGlzKS5jbG9zZXN0KFwibGlcIikuaXMoXCIudWktc3RhdGUtZGlzYWJsZWRcIikmJnRoaXMuYmx1cigpfSksdGhpcy50YWJzPXRoaXMudGFibGlzdC5maW5kKFwiPiBsaTpoYXMoYVtocmVmXSlcIikuYXR0cih7cm9sZTpcInRhYlwiLHRhYkluZGV4Oi0xfSksdGhpcy5fYWRkQ2xhc3ModGhpcy50YWJzLFwidWktdGFicy10YWJcIixcInVpLXN0YXRlLWRlZmF1bHRcIiksdGhpcy5hbmNob3JzPXRoaXMudGFicy5tYXAoZnVuY3Rpb24oKXtyZXR1cm4gdChcImFcIix0aGlzKVswXX0pLmF0dHIoe3JvbGU6XCJwcmVzZW50YXRpb25cIix0YWJJbmRleDotMX0pLHRoaXMuX2FkZENsYXNzKHRoaXMuYW5jaG9ycyxcInVpLXRhYnMtYW5jaG9yXCIpLHRoaXMucGFuZWxzPXQoKSx0aGlzLmFuY2hvcnMuZWFjaChmdW5jdGlvbihpLHMpe3ZhciBuLG8sYSxyPXQocykudW5pcXVlSWQoKS5hdHRyKFwiaWRcIiksaD10KHMpLmNsb3Nlc3QoXCJsaVwiKSxsPWguYXR0cihcImFyaWEtY29udHJvbHNcIik7ZS5faXNMb2NhbChzKT8obj1zLmhhc2gsYT1uLnN1YnN0cmluZygxKSxvPWUuZWxlbWVudC5maW5kKGUuX3Nhbml0aXplU2VsZWN0b3IobikpKTooYT1oLmF0dHIoXCJhcmlhLWNvbnRyb2xzXCIpfHx0KHt9KS51bmlxdWVJZCgpWzBdLmlkLG49XCIjXCIrYSxvPWUuZWxlbWVudC5maW5kKG4pLG8ubGVuZ3RofHwobz1lLl9jcmVhdGVQYW5lbChhKSxvLmluc2VydEFmdGVyKGUucGFuZWxzW2ktMV18fGUudGFibGlzdCkpLG8uYXR0cihcImFyaWEtbGl2ZVwiLFwicG9saXRlXCIpKSxvLmxlbmd0aCYmKGUucGFuZWxzPWUucGFuZWxzLmFkZChvKSksbCYmaC5kYXRhKFwidWktdGFicy1hcmlhLWNvbnRyb2xzXCIsbCksaC5hdHRyKHtcImFyaWEtY29udHJvbHNcIjphLFwiYXJpYS1sYWJlbGxlZGJ5XCI6cn0pLG8uYXR0cihcImFyaWEtbGFiZWxsZWRieVwiLHIpfSksdGhpcy5wYW5lbHMuYXR0cihcInJvbGVcIixcInRhYnBhbmVsXCIpLHRoaXMuX2FkZENsYXNzKHRoaXMucGFuZWxzLFwidWktdGFicy1wYW5lbFwiLFwidWktd2lkZ2V0LWNvbnRlbnRcIiksaSYmKHRoaXMuX29mZihpLm5vdCh0aGlzLnRhYnMpKSx0aGlzLl9vZmYocy5ub3QodGhpcy5hbmNob3JzKSksdGhpcy5fb2ZmKG4ubm90KHRoaXMucGFuZWxzKSkpfSxfZ2V0TGlzdDpmdW5jdGlvbigpe3JldHVybiB0aGlzLnRhYmxpc3R8fHRoaXMuZWxlbWVudC5maW5kKFwib2wsIHVsXCIpLmVxKDApfSxfY3JlYXRlUGFuZWw6ZnVuY3Rpb24oZSl7cmV0dXJuIHQoXCI8ZGl2PlwiKS5hdHRyKFwiaWRcIixlKS5kYXRhKFwidWktdGFicy1kZXN0cm95XCIsITApfSxfc2V0T3B0aW9uRGlzYWJsZWQ6ZnVuY3Rpb24oZSl7dmFyIGkscyxuO2Zvcih0LmlzQXJyYXkoZSkmJihlLmxlbmd0aD9lLmxlbmd0aD09PXRoaXMuYW5jaG9ycy5sZW5ndGgmJihlPSEwKTplPSExKSxuPTA7cz10aGlzLnRhYnNbbl07bisrKWk9dChzKSxlPT09ITB8fC0xIT09dC5pbkFycmF5KG4sZSk/KGkuYXR0cihcImFyaWEtZGlzYWJsZWRcIixcInRydWVcIiksdGhpcy5fYWRkQ2xhc3MoaSxudWxsLFwidWktc3RhdGUtZGlzYWJsZWRcIikpOihpLnJlbW92ZUF0dHIoXCJhcmlhLWRpc2FibGVkXCIpLHRoaXMuX3JlbW92ZUNsYXNzKGksbnVsbCxcInVpLXN0YXRlLWRpc2FibGVkXCIpKTt0aGlzLm9wdGlvbnMuZGlzYWJsZWQ9ZSx0aGlzLl90b2dnbGVDbGFzcyh0aGlzLndpZGdldCgpLHRoaXMud2lkZ2V0RnVsbE5hbWUrXCItZGlzYWJsZWRcIixudWxsLGU9PT0hMCl9LF9zZXR1cEV2ZW50czpmdW5jdGlvbihlKXt2YXIgaT17fTtlJiZ0LmVhY2goZS5zcGxpdChcIiBcIiksZnVuY3Rpb24odCxlKXtpW2VdPVwiX2V2ZW50SGFuZGxlclwifSksdGhpcy5fb2ZmKHRoaXMuYW5jaG9ycy5hZGQodGhpcy50YWJzKS5hZGQodGhpcy5wYW5lbHMpKSx0aGlzLl9vbighMCx0aGlzLmFuY2hvcnMse2NsaWNrOmZ1bmN0aW9uKHQpe3QucHJldmVudERlZmF1bHQoKX19KSx0aGlzLl9vbih0aGlzLmFuY2hvcnMsaSksdGhpcy5fb24odGhpcy50YWJzLHtrZXlkb3duOlwiX3RhYktleWRvd25cIn0pLHRoaXMuX29uKHRoaXMucGFuZWxzLHtrZXlkb3duOlwiX3BhbmVsS2V5ZG93blwifSksdGhpcy5fZm9jdXNhYmxlKHRoaXMudGFicyksdGhpcy5faG92ZXJhYmxlKHRoaXMudGFicyl9LF9zZXR1cEhlaWdodFN0eWxlOmZ1bmN0aW9uKGUpe3ZhciBpLHM9dGhpcy5lbGVtZW50LnBhcmVudCgpO1wiZmlsbFwiPT09ZT8oaT1zLmhlaWdodCgpLGktPXRoaXMuZWxlbWVudC5vdXRlckhlaWdodCgpLXRoaXMuZWxlbWVudC5oZWlnaHQoKSx0aGlzLmVsZW1lbnQuc2libGluZ3MoXCI6dmlzaWJsZVwiKS5lYWNoKGZ1bmN0aW9uKCl7dmFyIGU9dCh0aGlzKSxzPWUuY3NzKFwicG9zaXRpb25cIik7XCJhYnNvbHV0ZVwiIT09cyYmXCJmaXhlZFwiIT09cyYmKGktPWUub3V0ZXJIZWlnaHQoITApKX0pLHRoaXMuZWxlbWVudC5jaGlsZHJlbigpLm5vdCh0aGlzLnBhbmVscykuZWFjaChmdW5jdGlvbigpe2ktPXQodGhpcykub3V0ZXJIZWlnaHQoITApfSksdGhpcy5wYW5lbHMuZWFjaChmdW5jdGlvbigpe3QodGhpcykuaGVpZ2h0KE1hdGgubWF4KDAsaS10KHRoaXMpLmlubmVySGVpZ2h0KCkrdCh0aGlzKS5oZWlnaHQoKSkpfSkuY3NzKFwib3ZlcmZsb3dcIixcImF1dG9cIikpOlwiYXV0b1wiPT09ZSYmKGk9MCx0aGlzLnBhbmVscy5lYWNoKGZ1bmN0aW9uKCl7aT1NYXRoLm1heChpLHQodGhpcykuaGVpZ2h0KFwiXCIpLmhlaWdodCgpKX0pLmhlaWdodChpKSl9LF9ldmVudEhhbmRsZXI6ZnVuY3Rpb24oZSl7dmFyIGk9dGhpcy5vcHRpb25zLHM9dGhpcy5hY3RpdmUsbj10KGUuY3VycmVudFRhcmdldCksbz1uLmNsb3Nlc3QoXCJsaVwiKSxhPW9bMF09PT1zWzBdLHI9YSYmaS5jb2xsYXBzaWJsZSxoPXI/dCgpOnRoaXMuX2dldFBhbmVsRm9yVGFiKG8pLGw9cy5sZW5ndGg/dGhpcy5fZ2V0UGFuZWxGb3JUYWIocyk6dCgpLGM9e29sZFRhYjpzLG9sZFBhbmVsOmwsbmV3VGFiOnI/dCgpOm8sbmV3UGFuZWw6aH07ZS5wcmV2ZW50RGVmYXVsdCgpLG8uaGFzQ2xhc3MoXCJ1aS1zdGF0ZS1kaXNhYmxlZFwiKXx8by5oYXNDbGFzcyhcInVpLXRhYnMtbG9hZGluZ1wiKXx8dGhpcy5ydW5uaW5nfHxhJiYhaS5jb2xsYXBzaWJsZXx8dGhpcy5fdHJpZ2dlcihcImJlZm9yZUFjdGl2YXRlXCIsZSxjKT09PSExfHwoaS5hY3RpdmU9cj8hMTp0aGlzLnRhYnMuaW5kZXgobyksdGhpcy5hY3RpdmU9YT90KCk6byx0aGlzLnhociYmdGhpcy54aHIuYWJvcnQoKSxsLmxlbmd0aHx8aC5sZW5ndGh8fHQuZXJyb3IoXCJqUXVlcnkgVUkgVGFiczogTWlzbWF0Y2hpbmcgZnJhZ21lbnQgaWRlbnRpZmllci5cIiksaC5sZW5ndGgmJnRoaXMubG9hZCh0aGlzLnRhYnMuaW5kZXgobyksZSksdGhpcy5fdG9nZ2xlKGUsYykpfSxfdG9nZ2xlOmZ1bmN0aW9uKGUsaSl7ZnVuY3Rpb24gcygpe28ucnVubmluZz0hMSxvLl90cmlnZ2VyKFwiYWN0aXZhdGVcIixlLGkpfWZ1bmN0aW9uIG4oKXtvLl9hZGRDbGFzcyhpLm5ld1RhYi5jbG9zZXN0KFwibGlcIiksXCJ1aS10YWJzLWFjdGl2ZVwiLFwidWktc3RhdGUtYWN0aXZlXCIpLGEubGVuZ3RoJiZvLm9wdGlvbnMuc2hvdz9vLl9zaG93KGEsby5vcHRpb25zLnNob3cscyk6KGEuc2hvdygpLHMoKSl9dmFyIG89dGhpcyxhPWkubmV3UGFuZWwscj1pLm9sZFBhbmVsO3RoaXMucnVubmluZz0hMCxyLmxlbmd0aCYmdGhpcy5vcHRpb25zLmhpZGU/dGhpcy5faGlkZShyLHRoaXMub3B0aW9ucy5oaWRlLGZ1bmN0aW9uKCl7by5fcmVtb3ZlQ2xhc3MoaS5vbGRUYWIuY2xvc2VzdChcImxpXCIpLFwidWktdGFicy1hY3RpdmVcIixcInVpLXN0YXRlLWFjdGl2ZVwiKSxuKCl9KToodGhpcy5fcmVtb3ZlQ2xhc3MoaS5vbGRUYWIuY2xvc2VzdChcImxpXCIpLFwidWktdGFicy1hY3RpdmVcIixcInVpLXN0YXRlLWFjdGl2ZVwiKSxyLmhpZGUoKSxuKCkpLHIuYXR0cihcImFyaWEtaGlkZGVuXCIsXCJ0cnVlXCIpLGkub2xkVGFiLmF0dHIoe1wiYXJpYS1zZWxlY3RlZFwiOlwiZmFsc2VcIixcImFyaWEtZXhwYW5kZWRcIjpcImZhbHNlXCJ9KSxhLmxlbmd0aCYmci5sZW5ndGg/aS5vbGRUYWIuYXR0cihcInRhYkluZGV4XCIsLTEpOmEubGVuZ3RoJiZ0aGlzLnRhYnMuZmlsdGVyKGZ1bmN0aW9uKCl7cmV0dXJuIDA9PT10KHRoaXMpLmF0dHIoXCJ0YWJJbmRleFwiKX0pLmF0dHIoXCJ0YWJJbmRleFwiLC0xKSxhLmF0dHIoXCJhcmlhLWhpZGRlblwiLFwiZmFsc2VcIiksaS5uZXdUYWIuYXR0cih7XCJhcmlhLXNlbGVjdGVkXCI6XCJ0cnVlXCIsXCJhcmlhLWV4cGFuZGVkXCI6XCJ0cnVlXCIsdGFiSW5kZXg6MH0pfSxfYWN0aXZhdGU6ZnVuY3Rpb24oZSl7dmFyIGkscz10aGlzLl9maW5kQWN0aXZlKGUpO3NbMF0hPT10aGlzLmFjdGl2ZVswXSYmKHMubGVuZ3RofHwocz10aGlzLmFjdGl2ZSksaT1zLmZpbmQoXCIudWktdGFicy1hbmNob3JcIilbMF0sdGhpcy5fZXZlbnRIYW5kbGVyKHt0YXJnZXQ6aSxjdXJyZW50VGFyZ2V0OmkscHJldmVudERlZmF1bHQ6dC5ub29wfSkpfSxfZmluZEFjdGl2ZTpmdW5jdGlvbihlKXtyZXR1cm4gZT09PSExP3QoKTp0aGlzLnRhYnMuZXEoZSl9LF9nZXRJbmRleDpmdW5jdGlvbihlKXtyZXR1cm5cInN0cmluZ1wiPT10eXBlb2YgZSYmKGU9dGhpcy5hbmNob3JzLmluZGV4KHRoaXMuYW5jaG9ycy5maWx0ZXIoXCJbaHJlZiQ9J1wiK3QudWkuZXNjYXBlU2VsZWN0b3IoZSkrXCInXVwiKSkpLGV9LF9kZXN0cm95OmZ1bmN0aW9uKCl7dGhpcy54aHImJnRoaXMueGhyLmFib3J0KCksdGhpcy50YWJsaXN0LnJlbW92ZUF0dHIoXCJyb2xlXCIpLm9mZih0aGlzLmV2ZW50TmFtZXNwYWNlKSx0aGlzLmFuY2hvcnMucmVtb3ZlQXR0cihcInJvbGUgdGFiSW5kZXhcIikucmVtb3ZlVW5pcXVlSWQoKSx0aGlzLnRhYnMuYWRkKHRoaXMucGFuZWxzKS5lYWNoKGZ1bmN0aW9uKCl7dC5kYXRhKHRoaXMsXCJ1aS10YWJzLWRlc3Ryb3lcIik/dCh0aGlzKS5yZW1vdmUoKTp0KHRoaXMpLnJlbW92ZUF0dHIoXCJyb2xlIHRhYkluZGV4IGFyaWEtbGl2ZSBhcmlhLWJ1c3kgYXJpYS1zZWxlY3RlZCBhcmlhLWxhYmVsbGVkYnkgYXJpYS1oaWRkZW4gYXJpYS1leHBhbmRlZFwiKX0pLHRoaXMudGFicy5lYWNoKGZ1bmN0aW9uKCl7dmFyIGU9dCh0aGlzKSxpPWUuZGF0YShcInVpLXRhYnMtYXJpYS1jb250cm9sc1wiKTtpP2UuYXR0cihcImFyaWEtY29udHJvbHNcIixpKS5yZW1vdmVEYXRhKFwidWktdGFicy1hcmlhLWNvbnRyb2xzXCIpOmUucmVtb3ZlQXR0cihcImFyaWEtY29udHJvbHNcIil9KSx0aGlzLnBhbmVscy5zaG93KCksXCJjb250ZW50XCIhPT10aGlzLm9wdGlvbnMuaGVpZ2h0U3R5bGUmJnRoaXMucGFuZWxzLmNzcyhcImhlaWdodFwiLFwiXCIpfSxlbmFibGU6ZnVuY3Rpb24oZSl7dmFyIGk9dGhpcy5vcHRpb25zLmRpc2FibGVkO2khPT0hMSYmKHZvaWQgMD09PWU/aT0hMTooZT10aGlzLl9nZXRJbmRleChlKSxpPXQuaXNBcnJheShpKT90Lm1hcChpLGZ1bmN0aW9uKHQpe3JldHVybiB0IT09ZT90Om51bGx9KTp0Lm1hcCh0aGlzLnRhYnMsZnVuY3Rpb24odCxpKXtyZXR1cm4gaSE9PWU/aTpudWxsfSkpLHRoaXMuX3NldE9wdGlvbkRpc2FibGVkKGkpKX0sZGlzYWJsZTpmdW5jdGlvbihlKXt2YXIgaT10aGlzLm9wdGlvbnMuZGlzYWJsZWQ7aWYoaSE9PSEwKXtpZih2b2lkIDA9PT1lKWk9ITA7ZWxzZXtpZihlPXRoaXMuX2dldEluZGV4KGUpLC0xIT09dC5pbkFycmF5KGUsaSkpcmV0dXJuO2k9dC5pc0FycmF5KGkpP3QubWVyZ2UoW2VdLGkpLnNvcnQoKTpbZV19dGhpcy5fc2V0T3B0aW9uRGlzYWJsZWQoaSl9fSxsb2FkOmZ1bmN0aW9uKGUsaSl7ZT10aGlzLl9nZXRJbmRleChlKTt2YXIgcz10aGlzLG49dGhpcy50YWJzLmVxKGUpLG89bi5maW5kKFwiLnVpLXRhYnMtYW5jaG9yXCIpLGE9dGhpcy5fZ2V0UGFuZWxGb3JUYWIobikscj17dGFiOm4scGFuZWw6YX0saD1mdW5jdGlvbih0LGUpe1wiYWJvcnRcIj09PWUmJnMucGFuZWxzLnN0b3AoITEsITApLHMuX3JlbW92ZUNsYXNzKG4sXCJ1aS10YWJzLWxvYWRpbmdcIiksYS5yZW1vdmVBdHRyKFwiYXJpYS1idXN5XCIpLHQ9PT1zLnhociYmZGVsZXRlIHMueGhyfTt0aGlzLl9pc0xvY2FsKG9bMF0pfHwodGhpcy54aHI9dC5hamF4KHRoaXMuX2FqYXhTZXR0aW5ncyhvLGkscikpLHRoaXMueGhyJiZcImNhbmNlbGVkXCIhPT10aGlzLnhoci5zdGF0dXNUZXh0JiYodGhpcy5fYWRkQ2xhc3MobixcInVpLXRhYnMtbG9hZGluZ1wiKSxhLmF0dHIoXCJhcmlhLWJ1c3lcIixcInRydWVcIiksdGhpcy54aHIuZG9uZShmdW5jdGlvbih0LGUsbil7c2V0VGltZW91dChmdW5jdGlvbigpe2EuaHRtbCh0KSxzLl90cmlnZ2VyKFwibG9hZFwiLGksciksaChuLGUpfSwxKX0pLmZhaWwoZnVuY3Rpb24odCxlKXtzZXRUaW1lb3V0KGZ1bmN0aW9uKCl7aCh0LGUpfSwxKX0pKSl9LF9hamF4U2V0dGluZ3M6ZnVuY3Rpb24oZSxpLHMpe3ZhciBuPXRoaXM7cmV0dXJue3VybDplLmF0dHIoXCJocmVmXCIpLnJlcGxhY2UoLyMuKiQvLFwiXCIpLGJlZm9yZVNlbmQ6ZnVuY3Rpb24oZSxvKXtyZXR1cm4gbi5fdHJpZ2dlcihcImJlZm9yZUxvYWRcIixpLHQuZXh0ZW5kKHtqcVhIUjplLGFqYXhTZXR0aW5nczpvfSxzKSl9fX0sX2dldFBhbmVsRm9yVGFiOmZ1bmN0aW9uKGUpe3ZhciBpPXQoZSkuYXR0cihcImFyaWEtY29udHJvbHNcIik7cmV0dXJuIHRoaXMuZWxlbWVudC5maW5kKHRoaXMuX3Nhbml0aXplU2VsZWN0b3IoXCIjXCIraSkpfX0pLHQudWlCYWNrQ29tcGF0IT09ITEmJnQud2lkZ2V0KFwidWkudGFic1wiLHQudWkudGFicyx7X3Byb2Nlc3NUYWJzOmZ1bmN0aW9uKCl7dGhpcy5fc3VwZXJBcHBseShhcmd1bWVudHMpLHRoaXMuX2FkZENsYXNzKHRoaXMudGFicyxcInVpLXRhYlwiKX19KSx0LnVpLnRhYnMsdC53aWRnZXQoXCJ1aS50b29sdGlwXCIse3ZlcnNpb246XCIxLjEyLjFcIixvcHRpb25zOntjbGFzc2VzOntcInVpLXRvb2x0aXBcIjpcInVpLWNvcm5lci1hbGwgdWktd2lkZ2V0LXNoYWRvd1wifSxjb250ZW50OmZ1bmN0aW9uKCl7dmFyIGU9dCh0aGlzKS5hdHRyKFwidGl0bGVcIil8fFwiXCI7cmV0dXJuIHQoXCI8YT5cIikudGV4dChlKS5odG1sKCl9LGhpZGU6ITAsaXRlbXM6XCJbdGl0bGVdOm5vdChbZGlzYWJsZWRdKVwiLHBvc2l0aW9uOntteTpcImxlZnQgdG9wKzE1XCIsYXQ6XCJsZWZ0IGJvdHRvbVwiLGNvbGxpc2lvbjpcImZsaXBmaXQgZmxpcFwifSxzaG93OiEwLHRyYWNrOiExLGNsb3NlOm51bGwsb3BlbjpudWxsfSxfYWRkRGVzY3JpYmVkQnk6ZnVuY3Rpb24oZSxpKXt2YXIgcz0oZS5hdHRyKFwiYXJpYS1kZXNjcmliZWRieVwiKXx8XCJcIikuc3BsaXQoL1xccysvKTtzLnB1c2goaSksZS5kYXRhKFwidWktdG9vbHRpcC1pZFwiLGkpLmF0dHIoXCJhcmlhLWRlc2NyaWJlZGJ5XCIsdC50cmltKHMuam9pbihcIiBcIikpKX0sX3JlbW92ZURlc2NyaWJlZEJ5OmZ1bmN0aW9uKGUpe3ZhciBpPWUuZGF0YShcInVpLXRvb2x0aXAtaWRcIikscz0oZS5hdHRyKFwiYXJpYS1kZXNjcmliZWRieVwiKXx8XCJcIikuc3BsaXQoL1xccysvKSxuPXQuaW5BcnJheShpLHMpOy0xIT09biYmcy5zcGxpY2UobiwxKSxlLnJlbW92ZURhdGEoXCJ1aS10b29sdGlwLWlkXCIpLHM9dC50cmltKHMuam9pbihcIiBcIikpLHM/ZS5hdHRyKFwiYXJpYS1kZXNjcmliZWRieVwiLHMpOmUucmVtb3ZlQXR0cihcImFyaWEtZGVzY3JpYmVkYnlcIil9LF9jcmVhdGU6ZnVuY3Rpb24oKXt0aGlzLl9vbih7bW91c2VvdmVyOlwib3BlblwiLGZvY3VzaW46XCJvcGVuXCJ9KSx0aGlzLnRvb2x0aXBzPXt9LHRoaXMucGFyZW50cz17fSx0aGlzLmxpdmVSZWdpb249dChcIjxkaXY+XCIpLmF0dHIoe3JvbGU6XCJsb2dcIixcImFyaWEtbGl2ZVwiOlwiYXNzZXJ0aXZlXCIsXCJhcmlhLXJlbGV2YW50XCI6XCJhZGRpdGlvbnNcIn0pLmFwcGVuZFRvKHRoaXMuZG9jdW1lbnRbMF0uYm9keSksdGhpcy5fYWRkQ2xhc3ModGhpcy5saXZlUmVnaW9uLG51bGwsXCJ1aS1oZWxwZXItaGlkZGVuLWFjY2Vzc2libGVcIiksdGhpcy5kaXNhYmxlZFRpdGxlcz10KFtdKX0sX3NldE9wdGlvbjpmdW5jdGlvbihlLGkpe3ZhciBzPXRoaXM7dGhpcy5fc3VwZXIoZSxpKSxcImNvbnRlbnRcIj09PWUmJnQuZWFjaCh0aGlzLnRvb2x0aXBzLGZ1bmN0aW9uKHQsZSl7cy5fdXBkYXRlQ29udGVudChlLmVsZW1lbnQpfSl9LF9zZXRPcHRpb25EaXNhYmxlZDpmdW5jdGlvbih0KXt0aGlzW3Q/XCJfZGlzYWJsZVwiOlwiX2VuYWJsZVwiXSgpfSxfZGlzYWJsZTpmdW5jdGlvbigpe3ZhciBlPXRoaXM7dC5lYWNoKHRoaXMudG9vbHRpcHMsZnVuY3Rpb24oaSxzKXt2YXIgbj10LkV2ZW50KFwiYmx1clwiKTtuLnRhcmdldD1uLmN1cnJlbnRUYXJnZXQ9cy5lbGVtZW50WzBdLGUuY2xvc2UobiwhMCl9KSx0aGlzLmRpc2FibGVkVGl0bGVzPXRoaXMuZGlzYWJsZWRUaXRsZXMuYWRkKHRoaXMuZWxlbWVudC5maW5kKHRoaXMub3B0aW9ucy5pdGVtcykuYWRkQmFjaygpLmZpbHRlcihmdW5jdGlvbigpe3ZhciBlPXQodGhpcyk7cmV0dXJuIGUuaXMoXCJbdGl0bGVdXCIpP2UuZGF0YShcInVpLXRvb2x0aXAtdGl0bGVcIixlLmF0dHIoXCJ0aXRsZVwiKSkucmVtb3ZlQXR0cihcInRpdGxlXCIpOnZvaWQgMH0pKX0sX2VuYWJsZTpmdW5jdGlvbigpe3RoaXMuZGlzYWJsZWRUaXRsZXMuZWFjaChmdW5jdGlvbigpe3ZhciBlPXQodGhpcyk7ZS5kYXRhKFwidWktdG9vbHRpcC10aXRsZVwiKSYmZS5hdHRyKFwidGl0bGVcIixlLmRhdGEoXCJ1aS10b29sdGlwLXRpdGxlXCIpKX0pLHRoaXMuZGlzYWJsZWRUaXRsZXM9dChbXSl9LG9wZW46ZnVuY3Rpb24oZSl7dmFyIGk9dGhpcyxzPXQoZT9lLnRhcmdldDp0aGlzLmVsZW1lbnQpLmNsb3Nlc3QodGhpcy5vcHRpb25zLml0ZW1zKTtzLmxlbmd0aCYmIXMuZGF0YShcInVpLXRvb2x0aXAtaWRcIikmJihzLmF0dHIoXCJ0aXRsZVwiKSYmcy5kYXRhKFwidWktdG9vbHRpcC10aXRsZVwiLHMuYXR0cihcInRpdGxlXCIpKSxzLmRhdGEoXCJ1aS10b29sdGlwLW9wZW5cIiwhMCksZSYmXCJtb3VzZW92ZXJcIj09PWUudHlwZSYmcy5wYXJlbnRzKCkuZWFjaChmdW5jdGlvbigpe3ZhciBlLHM9dCh0aGlzKTtzLmRhdGEoXCJ1aS10b29sdGlwLW9wZW5cIikmJihlPXQuRXZlbnQoXCJibHVyXCIpLGUudGFyZ2V0PWUuY3VycmVudFRhcmdldD10aGlzLGkuY2xvc2UoZSwhMCkpLHMuYXR0cihcInRpdGxlXCIpJiYocy51bmlxdWVJZCgpLGkucGFyZW50c1t0aGlzLmlkXT17ZWxlbWVudDp0aGlzLHRpdGxlOnMuYXR0cihcInRpdGxlXCIpfSxzLmF0dHIoXCJ0aXRsZVwiLFwiXCIpKX0pLHRoaXMuX3JlZ2lzdGVyQ2xvc2VIYW5kbGVycyhlLHMpLHRoaXMuX3VwZGF0ZUNvbnRlbnQocyxlKSl9LF91cGRhdGVDb250ZW50OmZ1bmN0aW9uKHQsZSl7dmFyIGkscz10aGlzLm9wdGlvbnMuY29udGVudCxuPXRoaXMsbz1lP2UudHlwZTpudWxsO3JldHVyblwic3RyaW5nXCI9PXR5cGVvZiBzfHxzLm5vZGVUeXBlfHxzLmpxdWVyeT90aGlzLl9vcGVuKGUsdCxzKTooaT1zLmNhbGwodFswXSxmdW5jdGlvbihpKXtuLl9kZWxheShmdW5jdGlvbigpe3QuZGF0YShcInVpLXRvb2x0aXAtb3BlblwiKSYmKGUmJihlLnR5cGU9byksdGhpcy5fb3BlbihlLHQsaSkpfSl9KSxpJiZ0aGlzLl9vcGVuKGUsdCxpKSx2b2lkIDApfSxfb3BlbjpmdW5jdGlvbihlLGkscyl7ZnVuY3Rpb24gbih0KXtsLm9mPXQsYS5pcyhcIjpoaWRkZW5cIil8fGEucG9zaXRpb24obCl9dmFyIG8sYSxyLGgsbD10LmV4dGVuZCh7fSx0aGlzLm9wdGlvbnMucG9zaXRpb24pO2lmKHMpe2lmKG89dGhpcy5fZmluZChpKSlyZXR1cm4gby50b29sdGlwLmZpbmQoXCIudWktdG9vbHRpcC1jb250ZW50XCIpLmh0bWwocyksdm9pZCAwO2kuaXMoXCJbdGl0bGVdXCIpJiYoZSYmXCJtb3VzZW92ZXJcIj09PWUudHlwZT9pLmF0dHIoXCJ0aXRsZVwiLFwiXCIpOmkucmVtb3ZlQXR0cihcInRpdGxlXCIpKSxvPXRoaXMuX3Rvb2x0aXAoaSksYT1vLnRvb2x0aXAsdGhpcy5fYWRkRGVzY3JpYmVkQnkoaSxhLmF0dHIoXCJpZFwiKSksYS5maW5kKFwiLnVpLXRvb2x0aXAtY29udGVudFwiKS5odG1sKHMpLHRoaXMubGl2ZVJlZ2lvbi5jaGlsZHJlbigpLmhpZGUoKSxoPXQoXCI8ZGl2PlwiKS5odG1sKGEuZmluZChcIi51aS10b29sdGlwLWNvbnRlbnRcIikuaHRtbCgpKSxoLnJlbW92ZUF0dHIoXCJuYW1lXCIpLmZpbmQoXCJbbmFtZV1cIikucmVtb3ZlQXR0cihcIm5hbWVcIiksaC5yZW1vdmVBdHRyKFwiaWRcIikuZmluZChcIltpZF1cIikucmVtb3ZlQXR0cihcImlkXCIpLGguYXBwZW5kVG8odGhpcy5saXZlUmVnaW9uKSx0aGlzLm9wdGlvbnMudHJhY2smJmUmJi9ebW91c2UvLnRlc3QoZS50eXBlKT8odGhpcy5fb24odGhpcy5kb2N1bWVudCx7bW91c2Vtb3ZlOm59KSxuKGUpKTphLnBvc2l0aW9uKHQuZXh0ZW5kKHtvZjppfSx0aGlzLm9wdGlvbnMucG9zaXRpb24pKSxhLmhpZGUoKSx0aGlzLl9zaG93KGEsdGhpcy5vcHRpb25zLnNob3cpLHRoaXMub3B0aW9ucy50cmFjayYmdGhpcy5vcHRpb25zLnNob3cmJnRoaXMub3B0aW9ucy5zaG93LmRlbGF5JiYocj10aGlzLmRlbGF5ZWRTaG93PXNldEludGVydmFsKGZ1bmN0aW9uKCl7YS5pcyhcIjp2aXNpYmxlXCIpJiYobihsLm9mKSxjbGVhckludGVydmFsKHIpKX0sdC5meC5pbnRlcnZhbCkpLHRoaXMuX3RyaWdnZXIoXCJvcGVuXCIsZSx7dG9vbHRpcDphfSl9fSxfcmVnaXN0ZXJDbG9zZUhhbmRsZXJzOmZ1bmN0aW9uKGUsaSl7dmFyIHM9e2tleXVwOmZ1bmN0aW9uKGUpe2lmKGUua2V5Q29kZT09PXQudWkua2V5Q29kZS5FU0NBUEUpe3ZhciBzPXQuRXZlbnQoZSk7cy5jdXJyZW50VGFyZ2V0PWlbMF0sdGhpcy5jbG9zZShzLCEwKX19fTtpWzBdIT09dGhpcy5lbGVtZW50WzBdJiYocy5yZW1vdmU9ZnVuY3Rpb24oKXt0aGlzLl9yZW1vdmVUb29sdGlwKHRoaXMuX2ZpbmQoaSkudG9vbHRpcCl9KSxlJiZcIm1vdXNlb3ZlclwiIT09ZS50eXBlfHwocy5tb3VzZWxlYXZlPVwiY2xvc2VcIiksZSYmXCJmb2N1c2luXCIhPT1lLnR5cGV8fChzLmZvY3Vzb3V0PVwiY2xvc2VcIiksdGhpcy5fb24oITAsaSxzKX0sY2xvc2U6ZnVuY3Rpb24oZSl7dmFyIGkscz10aGlzLG49dChlP2UuY3VycmVudFRhcmdldDp0aGlzLmVsZW1lbnQpLG89dGhpcy5fZmluZChuKTtyZXR1cm4gbz8oaT1vLnRvb2x0aXAsby5jbG9zaW5nfHwoY2xlYXJJbnRlcnZhbCh0aGlzLmRlbGF5ZWRTaG93KSxuLmRhdGEoXCJ1aS10b29sdGlwLXRpdGxlXCIpJiYhbi5hdHRyKFwidGl0bGVcIikmJm4uYXR0cihcInRpdGxlXCIsbi5kYXRhKFwidWktdG9vbHRpcC10aXRsZVwiKSksdGhpcy5fcmVtb3ZlRGVzY3JpYmVkQnkobiksby5oaWRpbmc9ITAsaS5zdG9wKCEwKSx0aGlzLl9oaWRlKGksdGhpcy5vcHRpb25zLmhpZGUsZnVuY3Rpb24oKXtzLl9yZW1vdmVUb29sdGlwKHQodGhpcykpfSksbi5yZW1vdmVEYXRhKFwidWktdG9vbHRpcC1vcGVuXCIpLHRoaXMuX29mZihuLFwibW91c2VsZWF2ZSBmb2N1c291dCBrZXl1cFwiKSxuWzBdIT09dGhpcy5lbGVtZW50WzBdJiZ0aGlzLl9vZmYobixcInJlbW92ZVwiKSx0aGlzLl9vZmYodGhpcy5kb2N1bWVudCxcIm1vdXNlbW92ZVwiKSxlJiZcIm1vdXNlbGVhdmVcIj09PWUudHlwZSYmdC5lYWNoKHRoaXMucGFyZW50cyxmdW5jdGlvbihlLGkpe3QoaS5lbGVtZW50KS5hdHRyKFwidGl0bGVcIixpLnRpdGxlKSxkZWxldGUgcy5wYXJlbnRzW2VdXG59KSxvLmNsb3Npbmc9ITAsdGhpcy5fdHJpZ2dlcihcImNsb3NlXCIsZSx7dG9vbHRpcDppfSksby5oaWRpbmd8fChvLmNsb3Npbmc9ITEpKSx2b2lkIDApOihuLnJlbW92ZURhdGEoXCJ1aS10b29sdGlwLW9wZW5cIiksdm9pZCAwKX0sX3Rvb2x0aXA6ZnVuY3Rpb24oZSl7dmFyIGk9dChcIjxkaXY+XCIpLmF0dHIoXCJyb2xlXCIsXCJ0b29sdGlwXCIpLHM9dChcIjxkaXY+XCIpLmFwcGVuZFRvKGkpLG49aS51bmlxdWVJZCgpLmF0dHIoXCJpZFwiKTtyZXR1cm4gdGhpcy5fYWRkQ2xhc3MocyxcInVpLXRvb2x0aXAtY29udGVudFwiKSx0aGlzLl9hZGRDbGFzcyhpLFwidWktdG9vbHRpcFwiLFwidWktd2lkZ2V0IHVpLXdpZGdldC1jb250ZW50XCIpLGkuYXBwZW5kVG8odGhpcy5fYXBwZW5kVG8oZSkpLHRoaXMudG9vbHRpcHNbbl09e2VsZW1lbnQ6ZSx0b29sdGlwOml9fSxfZmluZDpmdW5jdGlvbih0KXt2YXIgZT10LmRhdGEoXCJ1aS10b29sdGlwLWlkXCIpO3JldHVybiBlP3RoaXMudG9vbHRpcHNbZV06bnVsbH0sX3JlbW92ZVRvb2x0aXA6ZnVuY3Rpb24odCl7dC5yZW1vdmUoKSxkZWxldGUgdGhpcy50b29sdGlwc1t0LmF0dHIoXCJpZFwiKV19LF9hcHBlbmRUbzpmdW5jdGlvbih0KXt2YXIgZT10LmNsb3Nlc3QoXCIudWktZnJvbnQsIGRpYWxvZ1wiKTtyZXR1cm4gZS5sZW5ndGh8fChlPXRoaXMuZG9jdW1lbnRbMF0uYm9keSksZX0sX2Rlc3Ryb3k6ZnVuY3Rpb24oKXt2YXIgZT10aGlzO3QuZWFjaCh0aGlzLnRvb2x0aXBzLGZ1bmN0aW9uKGkscyl7dmFyIG49dC5FdmVudChcImJsdXJcIiksbz1zLmVsZW1lbnQ7bi50YXJnZXQ9bi5jdXJyZW50VGFyZ2V0PW9bMF0sZS5jbG9zZShuLCEwKSx0KFwiI1wiK2kpLnJlbW92ZSgpLG8uZGF0YShcInVpLXRvb2x0aXAtdGl0bGVcIikmJihvLmF0dHIoXCJ0aXRsZVwiKXx8by5hdHRyKFwidGl0bGVcIixvLmRhdGEoXCJ1aS10b29sdGlwLXRpdGxlXCIpKSxvLnJlbW92ZURhdGEoXCJ1aS10b29sdGlwLXRpdGxlXCIpKX0pLHRoaXMubGl2ZVJlZ2lvbi5yZW1vdmUoKX19KSx0LnVpQmFja0NvbXBhdCE9PSExJiZ0LndpZGdldChcInVpLnRvb2x0aXBcIix0LnVpLnRvb2x0aXAse29wdGlvbnM6e3Rvb2x0aXBDbGFzczpudWxsfSxfdG9vbHRpcDpmdW5jdGlvbigpe3ZhciB0PXRoaXMuX3N1cGVyQXBwbHkoYXJndW1lbnRzKTtyZXR1cm4gdGhpcy5vcHRpb25zLnRvb2x0aXBDbGFzcyYmdC50b29sdGlwLmFkZENsYXNzKHRoaXMub3B0aW9ucy50b29sdGlwQ2xhc3MpLHR9fSksdC51aS50b29sdGlwO3ZhciBmPVwidWktZWZmZWN0cy1cIixnPVwidWktZWZmZWN0cy1zdHlsZVwiLG09XCJ1aS1lZmZlY3RzLWFuaW1hdGVkXCIsXz10O3QuZWZmZWN0cz17ZWZmZWN0Ont9fSxmdW5jdGlvbih0LGUpe2Z1bmN0aW9uIGkodCxlLGkpe3ZhciBzPXVbZS50eXBlXXx8e307cmV0dXJuIG51bGw9PXQ/aXx8IWUuZGVmP251bGw6ZS5kZWY6KHQ9cy5mbG9vcj9+fnQ6cGFyc2VGbG9hdCh0KSxpc05hTih0KT9lLmRlZjpzLm1vZD8odCtzLm1vZCklcy5tb2Q6MD50PzA6dD5zLm1heD9zLm1heDp0KX1mdW5jdGlvbiBzKGkpe3ZhciBzPWwoKSxuPXMuX3JnYmE9W107cmV0dXJuIGk9aS50b0xvd2VyQ2FzZSgpLGYoaCxmdW5jdGlvbih0LG8pe3ZhciBhLHI9by5yZS5leGVjKGkpLGg9ciYmby5wYXJzZShyKSxsPW8uc3BhY2V8fFwicmdiYVwiO3JldHVybiBoPyhhPXNbbF0oaCksc1tjW2xdLmNhY2hlXT1hW2NbbF0uY2FjaGVdLG49cy5fcmdiYT1hLl9yZ2JhLCExKTplfSksbi5sZW5ndGg/KFwiMCwwLDAsMFwiPT09bi5qb2luKCkmJnQuZXh0ZW5kKG4sby50cmFuc3BhcmVudCkscyk6b1tpXX1mdW5jdGlvbiBuKHQsZSxpKXtyZXR1cm4gaT0oaSsxKSUxLDE+NippP3QrNiooZS10KSppOjE+MippP2U6Mj4zKmk/dCs2KihlLXQpKigyLzMtaSk6dH12YXIgbyxhPVwiYmFja2dyb3VuZENvbG9yIGJvcmRlckJvdHRvbUNvbG9yIGJvcmRlckxlZnRDb2xvciBib3JkZXJSaWdodENvbG9yIGJvcmRlclRvcENvbG9yIGNvbG9yIGNvbHVtblJ1bGVDb2xvciBvdXRsaW5lQ29sb3IgdGV4dERlY29yYXRpb25Db2xvciB0ZXh0RW1waGFzaXNDb2xvclwiLHI9L14oW1xcLStdKT1cXHMqKFxcZCtcXC4/XFxkKikvLGg9W3tyZTovcmdiYT9cXChcXHMqKFxcZHsxLDN9KVxccyosXFxzKihcXGR7MSwzfSlcXHMqLFxccyooXFxkezEsM30pXFxzKig/OixcXHMqKFxcZD8oPzpcXC5cXGQrKT8pXFxzKik/XFwpLyxwYXJzZTpmdW5jdGlvbih0KXtyZXR1cm5bdFsxXSx0WzJdLHRbM10sdFs0XV19fSx7cmU6L3JnYmE/XFwoXFxzKihcXGQrKD86XFwuXFxkKyk/KVxcJVxccyosXFxzKihcXGQrKD86XFwuXFxkKyk/KVxcJVxccyosXFxzKihcXGQrKD86XFwuXFxkKyk/KVxcJVxccyooPzosXFxzKihcXGQ/KD86XFwuXFxkKyk/KVxccyopP1xcKS8scGFyc2U6ZnVuY3Rpb24odCl7cmV0dXJuWzIuNTUqdFsxXSwyLjU1KnRbMl0sMi41NSp0WzNdLHRbNF1dfX0se3JlOi8jKFthLWYwLTldezJ9KShbYS1mMC05XXsyfSkoW2EtZjAtOV17Mn0pLyxwYXJzZTpmdW5jdGlvbih0KXtyZXR1cm5bcGFyc2VJbnQodFsxXSwxNikscGFyc2VJbnQodFsyXSwxNikscGFyc2VJbnQodFszXSwxNildfX0se3JlOi8jKFthLWYwLTldKShbYS1mMC05XSkoW2EtZjAtOV0pLyxwYXJzZTpmdW5jdGlvbih0KXtyZXR1cm5bcGFyc2VJbnQodFsxXSt0WzFdLDE2KSxwYXJzZUludCh0WzJdK3RbMl0sMTYpLHBhcnNlSW50KHRbM10rdFszXSwxNildfX0se3JlOi9oc2xhP1xcKFxccyooXFxkKyg/OlxcLlxcZCspPylcXHMqLFxccyooXFxkKyg/OlxcLlxcZCspPylcXCVcXHMqLFxccyooXFxkKyg/OlxcLlxcZCspPylcXCVcXHMqKD86LFxccyooXFxkPyg/OlxcLlxcZCspPylcXHMqKT9cXCkvLHNwYWNlOlwiaHNsYVwiLHBhcnNlOmZ1bmN0aW9uKHQpe3JldHVyblt0WzFdLHRbMl0vMTAwLHRbM10vMTAwLHRbNF1dfX1dLGw9dC5Db2xvcj1mdW5jdGlvbihlLGkscyxuKXtyZXR1cm4gbmV3IHQuQ29sb3IuZm4ucGFyc2UoZSxpLHMsbil9LGM9e3JnYmE6e3Byb3BzOntyZWQ6e2lkeDowLHR5cGU6XCJieXRlXCJ9LGdyZWVuOntpZHg6MSx0eXBlOlwiYnl0ZVwifSxibHVlOntpZHg6Mix0eXBlOlwiYnl0ZVwifX19LGhzbGE6e3Byb3BzOntodWU6e2lkeDowLHR5cGU6XCJkZWdyZWVzXCJ9LHNhdHVyYXRpb246e2lkeDoxLHR5cGU6XCJwZXJjZW50XCJ9LGxpZ2h0bmVzczp7aWR4OjIsdHlwZTpcInBlcmNlbnRcIn19fX0sdT17XCJieXRlXCI6e2Zsb29yOiEwLG1heDoyNTV9LHBlcmNlbnQ6e21heDoxfSxkZWdyZWVzOnttb2Q6MzYwLGZsb29yOiEwfX0sZD1sLnN1cHBvcnQ9e30scD10KFwiPHA+XCIpWzBdLGY9dC5lYWNoO3Auc3R5bGUuY3NzVGV4dD1cImJhY2tncm91bmQtY29sb3I6cmdiYSgxLDEsMSwuNSlcIixkLnJnYmE9cC5zdHlsZS5iYWNrZ3JvdW5kQ29sb3IuaW5kZXhPZihcInJnYmFcIik+LTEsZihjLGZ1bmN0aW9uKHQsZSl7ZS5jYWNoZT1cIl9cIit0LGUucHJvcHMuYWxwaGE9e2lkeDozLHR5cGU6XCJwZXJjZW50XCIsZGVmOjF9fSksbC5mbj10LmV4dGVuZChsLnByb3RvdHlwZSx7cGFyc2U6ZnVuY3Rpb24obixhLHIsaCl7aWYobj09PWUpcmV0dXJuIHRoaXMuX3JnYmE9W251bGwsbnVsbCxudWxsLG51bGxdLHRoaXM7KG4uanF1ZXJ5fHxuLm5vZGVUeXBlKSYmKG49dChuKS5jc3MoYSksYT1lKTt2YXIgdT10aGlzLGQ9dC50eXBlKG4pLHA9dGhpcy5fcmdiYT1bXTtyZXR1cm4gYSE9PWUmJihuPVtuLGEscixoXSxkPVwiYXJyYXlcIiksXCJzdHJpbmdcIj09PWQ/dGhpcy5wYXJzZShzKG4pfHxvLl9kZWZhdWx0KTpcImFycmF5XCI9PT1kPyhmKGMucmdiYS5wcm9wcyxmdW5jdGlvbih0LGUpe3BbZS5pZHhdPWkobltlLmlkeF0sZSl9KSx0aGlzKTpcIm9iamVjdFwiPT09ZD8obiBpbnN0YW5jZW9mIGw/ZihjLGZ1bmN0aW9uKHQsZSl7bltlLmNhY2hlXSYmKHVbZS5jYWNoZV09bltlLmNhY2hlXS5zbGljZSgpKX0pOmYoYyxmdW5jdGlvbihlLHMpe3ZhciBvPXMuY2FjaGU7ZihzLnByb3BzLGZ1bmN0aW9uKHQsZSl7aWYoIXVbb10mJnMudG8pe2lmKFwiYWxwaGFcIj09PXR8fG51bGw9PW5bdF0pcmV0dXJuO3Vbb109cy50byh1Ll9yZ2JhKX11W29dW2UuaWR4XT1pKG5bdF0sZSwhMCl9KSx1W29dJiYwPnQuaW5BcnJheShudWxsLHVbb10uc2xpY2UoMCwzKSkmJih1W29dWzNdPTEscy5mcm9tJiYodS5fcmdiYT1zLmZyb20odVtvXSkpKX0pLHRoaXMpOmV9LGlzOmZ1bmN0aW9uKHQpe3ZhciBpPWwodCkscz0hMCxuPXRoaXM7cmV0dXJuIGYoYyxmdW5jdGlvbih0LG8pe3ZhciBhLHI9aVtvLmNhY2hlXTtyZXR1cm4gciYmKGE9bltvLmNhY2hlXXx8by50byYmby50byhuLl9yZ2JhKXx8W10sZihvLnByb3BzLGZ1bmN0aW9uKHQsaSl7cmV0dXJuIG51bGwhPXJbaS5pZHhdP3M9cltpLmlkeF09PT1hW2kuaWR4XTplfSkpLHN9KSxzfSxfc3BhY2U6ZnVuY3Rpb24oKXt2YXIgdD1bXSxlPXRoaXM7cmV0dXJuIGYoYyxmdW5jdGlvbihpLHMpe2Vbcy5jYWNoZV0mJnQucHVzaChpKX0pLHQucG9wKCl9LHRyYW5zaXRpb246ZnVuY3Rpb24odCxlKXt2YXIgcz1sKHQpLG49cy5fc3BhY2UoKSxvPWNbbl0sYT0wPT09dGhpcy5hbHBoYSgpP2woXCJ0cmFuc3BhcmVudFwiKTp0aGlzLHI9YVtvLmNhY2hlXXx8by50byhhLl9yZ2JhKSxoPXIuc2xpY2UoKTtyZXR1cm4gcz1zW28uY2FjaGVdLGYoby5wcm9wcyxmdW5jdGlvbih0LG4pe3ZhciBvPW4uaWR4LGE9cltvXSxsPXNbb10sYz11W24udHlwZV18fHt9O251bGwhPT1sJiYobnVsbD09PWE/aFtvXT1sOihjLm1vZCYmKGwtYT5jLm1vZC8yP2ErPWMubW9kOmEtbD5jLm1vZC8yJiYoYS09Yy5tb2QpKSxoW29dPWkoKGwtYSkqZSthLG4pKSl9KSx0aGlzW25dKGgpfSxibGVuZDpmdW5jdGlvbihlKXtpZigxPT09dGhpcy5fcmdiYVszXSlyZXR1cm4gdGhpczt2YXIgaT10aGlzLl9yZ2JhLnNsaWNlKCkscz1pLnBvcCgpLG49bChlKS5fcmdiYTtyZXR1cm4gbCh0Lm1hcChpLGZ1bmN0aW9uKHQsZSl7cmV0dXJuKDEtcykqbltlXStzKnR9KSl9LHRvUmdiYVN0cmluZzpmdW5jdGlvbigpe3ZhciBlPVwicmdiYShcIixpPXQubWFwKHRoaXMuX3JnYmEsZnVuY3Rpb24odCxlKXtyZXR1cm4gbnVsbD09dD9lPjI/MTowOnR9KTtyZXR1cm4gMT09PWlbM10mJihpLnBvcCgpLGU9XCJyZ2IoXCIpLGUraS5qb2luKCkrXCIpXCJ9LHRvSHNsYVN0cmluZzpmdW5jdGlvbigpe3ZhciBlPVwiaHNsYShcIixpPXQubWFwKHRoaXMuaHNsYSgpLGZ1bmN0aW9uKHQsZSl7cmV0dXJuIG51bGw9PXQmJih0PWU+Mj8xOjApLGUmJjM+ZSYmKHQ9TWF0aC5yb3VuZCgxMDAqdCkrXCIlXCIpLHR9KTtyZXR1cm4gMT09PWlbM10mJihpLnBvcCgpLGU9XCJoc2woXCIpLGUraS5qb2luKCkrXCIpXCJ9LHRvSGV4U3RyaW5nOmZ1bmN0aW9uKGUpe3ZhciBpPXRoaXMuX3JnYmEuc2xpY2UoKSxzPWkucG9wKCk7cmV0dXJuIGUmJmkucHVzaCh+figyNTUqcykpLFwiI1wiK3QubWFwKGksZnVuY3Rpb24odCl7cmV0dXJuIHQ9KHR8fDApLnRvU3RyaW5nKDE2KSwxPT09dC5sZW5ndGg/XCIwXCIrdDp0fSkuam9pbihcIlwiKX0sdG9TdHJpbmc6ZnVuY3Rpb24oKXtyZXR1cm4gMD09PXRoaXMuX3JnYmFbM10/XCJ0cmFuc3BhcmVudFwiOnRoaXMudG9SZ2JhU3RyaW5nKCl9fSksbC5mbi5wYXJzZS5wcm90b3R5cGU9bC5mbixjLmhzbGEudG89ZnVuY3Rpb24odCl7aWYobnVsbD09dFswXXx8bnVsbD09dFsxXXx8bnVsbD09dFsyXSlyZXR1cm5bbnVsbCxudWxsLG51bGwsdFszXV07dmFyIGUsaSxzPXRbMF0vMjU1LG49dFsxXS8yNTUsbz10WzJdLzI1NSxhPXRbM10scj1NYXRoLm1heChzLG4sbyksaD1NYXRoLm1pbihzLG4sbyksbD1yLWgsYz1yK2gsdT0uNSpjO3JldHVybiBlPWg9PT1yPzA6cz09PXI/NjAqKG4tbykvbCszNjA6bj09PXI/NjAqKG8tcykvbCsxMjA6NjAqKHMtbikvbCsyNDAsaT0wPT09bD8wOi41Pj11P2wvYzpsLygyLWMpLFtNYXRoLnJvdW5kKGUpJTM2MCxpLHUsbnVsbD09YT8xOmFdfSxjLmhzbGEuZnJvbT1mdW5jdGlvbih0KXtpZihudWxsPT10WzBdfHxudWxsPT10WzFdfHxudWxsPT10WzJdKXJldHVybltudWxsLG51bGwsbnVsbCx0WzNdXTt2YXIgZT10WzBdLzM2MCxpPXRbMV0scz10WzJdLG89dFszXSxhPS41Pj1zP3MqKDEraSk6cytpLXMqaSxyPTIqcy1hO3JldHVybltNYXRoLnJvdW5kKDI1NSpuKHIsYSxlKzEvMykpLE1hdGgucm91bmQoMjU1Km4ocixhLGUpKSxNYXRoLnJvdW5kKDI1NSpuKHIsYSxlLTEvMykpLG9dfSxmKGMsZnVuY3Rpb24ocyxuKXt2YXIgbz1uLnByb3BzLGE9bi5jYWNoZSxoPW4udG8sYz1uLmZyb207bC5mbltzXT1mdW5jdGlvbihzKXtpZihoJiYhdGhpc1thXSYmKHRoaXNbYV09aCh0aGlzLl9yZ2JhKSkscz09PWUpcmV0dXJuIHRoaXNbYV0uc2xpY2UoKTt2YXIgbixyPXQudHlwZShzKSx1PVwiYXJyYXlcIj09PXJ8fFwib2JqZWN0XCI9PT1yP3M6YXJndW1lbnRzLGQ9dGhpc1thXS5zbGljZSgpO3JldHVybiBmKG8sZnVuY3Rpb24odCxlKXt2YXIgcz11W1wib2JqZWN0XCI9PT1yP3Q6ZS5pZHhdO251bGw9PXMmJihzPWRbZS5pZHhdKSxkW2UuaWR4XT1pKHMsZSl9KSxjPyhuPWwoYyhkKSksblthXT1kLG4pOmwoZCl9LGYobyxmdW5jdGlvbihlLGkpe2wuZm5bZV18fChsLmZuW2VdPWZ1bmN0aW9uKG4pe3ZhciBvLGE9dC50eXBlKG4pLGg9XCJhbHBoYVwiPT09ZT90aGlzLl9oc2xhP1wiaHNsYVwiOlwicmdiYVwiOnMsbD10aGlzW2hdKCksYz1sW2kuaWR4XTtyZXR1cm5cInVuZGVmaW5lZFwiPT09YT9jOihcImZ1bmN0aW9uXCI9PT1hJiYobj1uLmNhbGwodGhpcyxjKSxhPXQudHlwZShuKSksbnVsbD09biYmaS5lbXB0eT90aGlzOihcInN0cmluZ1wiPT09YSYmKG89ci5leGVjKG4pLG8mJihuPWMrcGFyc2VGbG9hdChvWzJdKSooXCIrXCI9PT1vWzFdPzE6LTEpKSksbFtpLmlkeF09bix0aGlzW2hdKGwpKSl9KX0pfSksbC5ob29rPWZ1bmN0aW9uKGUpe3ZhciBpPWUuc3BsaXQoXCIgXCIpO2YoaSxmdW5jdGlvbihlLGkpe3QuY3NzSG9va3NbaV09e3NldDpmdW5jdGlvbihlLG4pe3ZhciBvLGEscj1cIlwiO2lmKFwidHJhbnNwYXJlbnRcIiE9PW4mJihcInN0cmluZ1wiIT09dC50eXBlKG4pfHwobz1zKG4pKSkpe2lmKG49bChvfHxuKSwhZC5yZ2JhJiYxIT09bi5fcmdiYVszXSl7Zm9yKGE9XCJiYWNrZ3JvdW5kQ29sb3JcIj09PWk/ZS5wYXJlbnROb2RlOmU7KFwiXCI9PT1yfHxcInRyYW5zcGFyZW50XCI9PT1yKSYmYSYmYS5zdHlsZTspdHJ5e3I9dC5jc3MoYSxcImJhY2tncm91bmRDb2xvclwiKSxhPWEucGFyZW50Tm9kZX1jYXRjaChoKXt9bj1uLmJsZW5kKHImJlwidHJhbnNwYXJlbnRcIiE9PXI/cjpcIl9kZWZhdWx0XCIpfW49bi50b1JnYmFTdHJpbmcoKX10cnl7ZS5zdHlsZVtpXT1ufWNhdGNoKGgpe319fSx0LmZ4LnN0ZXBbaV09ZnVuY3Rpb24oZSl7ZS5jb2xvckluaXR8fChlLnN0YXJ0PWwoZS5lbGVtLGkpLGUuZW5kPWwoZS5lbmQpLGUuY29sb3JJbml0PSEwKSx0LmNzc0hvb2tzW2ldLnNldChlLmVsZW0sZS5zdGFydC50cmFuc2l0aW9uKGUuZW5kLGUucG9zKSl9fSl9LGwuaG9vayhhKSx0LmNzc0hvb2tzLmJvcmRlckNvbG9yPXtleHBhbmQ6ZnVuY3Rpb24odCl7dmFyIGU9e307cmV0dXJuIGYoW1wiVG9wXCIsXCJSaWdodFwiLFwiQm90dG9tXCIsXCJMZWZ0XCJdLGZ1bmN0aW9uKGkscyl7ZVtcImJvcmRlclwiK3MrXCJDb2xvclwiXT10fSksZX19LG89dC5Db2xvci5uYW1lcz17YXF1YTpcIiMwMGZmZmZcIixibGFjazpcIiMwMDAwMDBcIixibHVlOlwiIzAwMDBmZlwiLGZ1Y2hzaWE6XCIjZmYwMGZmXCIsZ3JheTpcIiM4MDgwODBcIixncmVlbjpcIiMwMDgwMDBcIixsaW1lOlwiIzAwZmYwMFwiLG1hcm9vbjpcIiM4MDAwMDBcIixuYXZ5OlwiIzAwMDA4MFwiLG9saXZlOlwiIzgwODAwMFwiLHB1cnBsZTpcIiM4MDAwODBcIixyZWQ6XCIjZmYwMDAwXCIsc2lsdmVyOlwiI2MwYzBjMFwiLHRlYWw6XCIjMDA4MDgwXCIsd2hpdGU6XCIjZmZmZmZmXCIseWVsbG93OlwiI2ZmZmYwMFwiLHRyYW5zcGFyZW50OltudWxsLG51bGwsbnVsbCwwXSxfZGVmYXVsdDpcIiNmZmZmZmZcIn19KF8pLGZ1bmN0aW9uKCl7ZnVuY3Rpb24gZShlKXt2YXIgaSxzLG49ZS5vd25lckRvY3VtZW50LmRlZmF1bHRWaWV3P2Uub3duZXJEb2N1bWVudC5kZWZhdWx0Vmlldy5nZXRDb21wdXRlZFN0eWxlKGUsbnVsbCk6ZS5jdXJyZW50U3R5bGUsbz17fTtpZihuJiZuLmxlbmd0aCYmblswXSYmbltuWzBdXSlmb3Iocz1uLmxlbmd0aDtzLS07KWk9bltzXSxcInN0cmluZ1wiPT10eXBlb2YgbltpXSYmKG9bdC5jYW1lbENhc2UoaSldPW5baV0pO2Vsc2UgZm9yKGkgaW4gbilcInN0cmluZ1wiPT10eXBlb2YgbltpXSYmKG9baV09bltpXSk7cmV0dXJuIG99ZnVuY3Rpb24gaShlLGkpe3ZhciBzLG8sYT17fTtmb3IocyBpbiBpKW89aVtzXSxlW3NdIT09byYmKG5bc118fCh0LmZ4LnN0ZXBbc118fCFpc05hTihwYXJzZUZsb2F0KG8pKSkmJihhW3NdPW8pKTtyZXR1cm4gYX12YXIgcz1bXCJhZGRcIixcInJlbW92ZVwiLFwidG9nZ2xlXCJdLG49e2JvcmRlcjoxLGJvcmRlckJvdHRvbToxLGJvcmRlckNvbG9yOjEsYm9yZGVyTGVmdDoxLGJvcmRlclJpZ2h0OjEsYm9yZGVyVG9wOjEsYm9yZGVyV2lkdGg6MSxtYXJnaW46MSxwYWRkaW5nOjF9O3QuZWFjaChbXCJib3JkZXJMZWZ0U3R5bGVcIixcImJvcmRlclJpZ2h0U3R5bGVcIixcImJvcmRlckJvdHRvbVN0eWxlXCIsXCJib3JkZXJUb3BTdHlsZVwiXSxmdW5jdGlvbihlLGkpe3QuZnguc3RlcFtpXT1mdW5jdGlvbih0KXsoXCJub25lXCIhPT10LmVuZCYmIXQuc2V0QXR0cnx8MT09PXQucG9zJiYhdC5zZXRBdHRyKSYmKF8uc3R5bGUodC5lbGVtLGksdC5lbmQpLHQuc2V0QXR0cj0hMCl9fSksdC5mbi5hZGRCYWNrfHwodC5mbi5hZGRCYWNrPWZ1bmN0aW9uKHQpe3JldHVybiB0aGlzLmFkZChudWxsPT10P3RoaXMucHJldk9iamVjdDp0aGlzLnByZXZPYmplY3QuZmlsdGVyKHQpKX0pLHQuZWZmZWN0cy5hbmltYXRlQ2xhc3M9ZnVuY3Rpb24obixvLGEscil7dmFyIGg9dC5zcGVlZChvLGEscik7cmV0dXJuIHRoaXMucXVldWUoZnVuY3Rpb24oKXt2YXIgbyxhPXQodGhpcykscj1hLmF0dHIoXCJjbGFzc1wiKXx8XCJcIixsPWguY2hpbGRyZW4/YS5maW5kKFwiKlwiKS5hZGRCYWNrKCk6YTtsPWwubWFwKGZ1bmN0aW9uKCl7dmFyIGk9dCh0aGlzKTtyZXR1cm57ZWw6aSxzdGFydDplKHRoaXMpfX0pLG89ZnVuY3Rpb24oKXt0LmVhY2gocyxmdW5jdGlvbih0LGUpe25bZV0mJmFbZStcIkNsYXNzXCJdKG5bZV0pfSl9LG8oKSxsPWwubWFwKGZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMuZW5kPWUodGhpcy5lbFswXSksdGhpcy5kaWZmPWkodGhpcy5zdGFydCx0aGlzLmVuZCksdGhpc30pLGEuYXR0cihcImNsYXNzXCIsciksbD1sLm1hcChmdW5jdGlvbigpe3ZhciBlPXRoaXMsaT10LkRlZmVycmVkKCkscz10LmV4dGVuZCh7fSxoLHtxdWV1ZTohMSxjb21wbGV0ZTpmdW5jdGlvbigpe2kucmVzb2x2ZShlKX19KTtyZXR1cm4gdGhpcy5lbC5hbmltYXRlKHRoaXMuZGlmZixzKSxpLnByb21pc2UoKX0pLHQud2hlbi5hcHBseSh0LGwuZ2V0KCkpLmRvbmUoZnVuY3Rpb24oKXtvKCksdC5lYWNoKGFyZ3VtZW50cyxmdW5jdGlvbigpe3ZhciBlPXRoaXMuZWw7dC5lYWNoKHRoaXMuZGlmZixmdW5jdGlvbih0KXtlLmNzcyh0LFwiXCIpfSl9KSxoLmNvbXBsZXRlLmNhbGwoYVswXSl9KX0pfSx0LmZuLmV4dGVuZCh7YWRkQ2xhc3M6ZnVuY3Rpb24oZSl7cmV0dXJuIGZ1bmN0aW9uKGkscyxuLG8pe3JldHVybiBzP3QuZWZmZWN0cy5hbmltYXRlQ2xhc3MuY2FsbCh0aGlzLHthZGQ6aX0scyxuLG8pOmUuYXBwbHkodGhpcyxhcmd1bWVudHMpfX0odC5mbi5hZGRDbGFzcykscmVtb3ZlQ2xhc3M6ZnVuY3Rpb24oZSl7cmV0dXJuIGZ1bmN0aW9uKGkscyxuLG8pe3JldHVybiBhcmd1bWVudHMubGVuZ3RoPjE/dC5lZmZlY3RzLmFuaW1hdGVDbGFzcy5jYWxsKHRoaXMse3JlbW92ZTppfSxzLG4sbyk6ZS5hcHBseSh0aGlzLGFyZ3VtZW50cyl9fSh0LmZuLnJlbW92ZUNsYXNzKSx0b2dnbGVDbGFzczpmdW5jdGlvbihlKXtyZXR1cm4gZnVuY3Rpb24oaSxzLG4sbyxhKXtyZXR1cm5cImJvb2xlYW5cIj09dHlwZW9mIHN8fHZvaWQgMD09PXM/bj90LmVmZmVjdHMuYW5pbWF0ZUNsYXNzLmNhbGwodGhpcyxzP3thZGQ6aX06e3JlbW92ZTppfSxuLG8sYSk6ZS5hcHBseSh0aGlzLGFyZ3VtZW50cyk6dC5lZmZlY3RzLmFuaW1hdGVDbGFzcy5jYWxsKHRoaXMse3RvZ2dsZTppfSxzLG4sbyl9fSh0LmZuLnRvZ2dsZUNsYXNzKSxzd2l0Y2hDbGFzczpmdW5jdGlvbihlLGkscyxuLG8pe3JldHVybiB0LmVmZmVjdHMuYW5pbWF0ZUNsYXNzLmNhbGwodGhpcyx7YWRkOmkscmVtb3ZlOmV9LHMsbixvKX19KX0oKSxmdW5jdGlvbigpe2Z1bmN0aW9uIGUoZSxpLHMsbil7cmV0dXJuIHQuaXNQbGFpbk9iamVjdChlKSYmKGk9ZSxlPWUuZWZmZWN0KSxlPXtlZmZlY3Q6ZX0sbnVsbD09aSYmKGk9e30pLHQuaXNGdW5jdGlvbihpKSYmKG49aSxzPW51bGwsaT17fSksKFwibnVtYmVyXCI9PXR5cGVvZiBpfHx0LmZ4LnNwZWVkc1tpXSkmJihuPXMscz1pLGk9e30pLHQuaXNGdW5jdGlvbihzKSYmKG49cyxzPW51bGwpLGkmJnQuZXh0ZW5kKGUsaSkscz1zfHxpLmR1cmF0aW9uLGUuZHVyYXRpb249dC5meC5vZmY/MDpcIm51bWJlclwiPT10eXBlb2Ygcz9zOnMgaW4gdC5meC5zcGVlZHM/dC5meC5zcGVlZHNbc106dC5meC5zcGVlZHMuX2RlZmF1bHQsZS5jb21wbGV0ZT1ufHxpLmNvbXBsZXRlLGV9ZnVuY3Rpb24gaShlKXtyZXR1cm4hZXx8XCJudW1iZXJcIj09dHlwZW9mIGV8fHQuZnguc3BlZWRzW2VdPyEwOlwic3RyaW5nXCIhPXR5cGVvZiBlfHx0LmVmZmVjdHMuZWZmZWN0W2VdP3QuaXNGdW5jdGlvbihlKT8hMDpcIm9iamVjdFwiIT10eXBlb2YgZXx8ZS5lZmZlY3Q/ITE6ITA6ITB9ZnVuY3Rpb24gcyh0LGUpe3ZhciBpPWUub3V0ZXJXaWR0aCgpLHM9ZS5vdXRlckhlaWdodCgpLG49L15yZWN0XFwoKC0/XFxkKlxcLj9cXGQqcHh8LT9cXGQrJXxhdXRvKSw/XFxzKigtP1xcZCpcXC4/XFxkKnB4fC0/XFxkKyV8YXV0byksP1xccyooLT9cXGQqXFwuP1xcZCpweHwtP1xcZCslfGF1dG8pLD9cXHMqKC0/XFxkKlxcLj9cXGQqcHh8LT9cXGQrJXxhdXRvKVxcKSQvLG89bi5leGVjKHQpfHxbXCJcIiwwLGkscywwXTtyZXR1cm57dG9wOnBhcnNlRmxvYXQob1sxXSl8fDAscmlnaHQ6XCJhdXRvXCI9PT1vWzJdP2k6cGFyc2VGbG9hdChvWzJdKSxib3R0b206XCJhdXRvXCI9PT1vWzNdP3M6cGFyc2VGbG9hdChvWzNdKSxsZWZ0OnBhcnNlRmxvYXQob1s0XSl8fDB9fXQuZXhwciYmdC5leHByLmZpbHRlcnMmJnQuZXhwci5maWx0ZXJzLmFuaW1hdGVkJiYodC5leHByLmZpbHRlcnMuYW5pbWF0ZWQ9ZnVuY3Rpb24oZSl7cmV0dXJuIGZ1bmN0aW9uKGkpe3JldHVybiEhdChpKS5kYXRhKG0pfHxlKGkpfX0odC5leHByLmZpbHRlcnMuYW5pbWF0ZWQpKSx0LnVpQmFja0NvbXBhdCE9PSExJiZ0LmV4dGVuZCh0LmVmZmVjdHMse3NhdmU6ZnVuY3Rpb24odCxlKXtmb3IodmFyIGk9MCxzPWUubGVuZ3RoO3M+aTtpKyspbnVsbCE9PWVbaV0mJnQuZGF0YShmK2VbaV0sdFswXS5zdHlsZVtlW2ldXSl9LHJlc3RvcmU6ZnVuY3Rpb24odCxlKXtmb3IodmFyIGkscz0wLG49ZS5sZW5ndGg7bj5zO3MrKyludWxsIT09ZVtzXSYmKGk9dC5kYXRhKGYrZVtzXSksdC5jc3MoZVtzXSxpKSl9LHNldE1vZGU6ZnVuY3Rpb24odCxlKXtyZXR1cm5cInRvZ2dsZVwiPT09ZSYmKGU9dC5pcyhcIjpoaWRkZW5cIik/XCJzaG93XCI6XCJoaWRlXCIpLGV9LGNyZWF0ZVdyYXBwZXI6ZnVuY3Rpb24oZSl7aWYoZS5wYXJlbnQoKS5pcyhcIi51aS1lZmZlY3RzLXdyYXBwZXJcIikpcmV0dXJuIGUucGFyZW50KCk7dmFyIGk9e3dpZHRoOmUub3V0ZXJXaWR0aCghMCksaGVpZ2h0OmUub3V0ZXJIZWlnaHQoITApLFwiZmxvYXRcIjplLmNzcyhcImZsb2F0XCIpfSxzPXQoXCI8ZGl2PjwvZGl2PlwiKS5hZGRDbGFzcyhcInVpLWVmZmVjdHMtd3JhcHBlclwiKS5jc3Moe2ZvbnRTaXplOlwiMTAwJVwiLGJhY2tncm91bmQ6XCJ0cmFuc3BhcmVudFwiLGJvcmRlcjpcIm5vbmVcIixtYXJnaW46MCxwYWRkaW5nOjB9KSxuPXt3aWR0aDplLndpZHRoKCksaGVpZ2h0OmUuaGVpZ2h0KCl9LG89ZG9jdW1lbnQuYWN0aXZlRWxlbWVudDt0cnl7by5pZH1jYXRjaChhKXtvPWRvY3VtZW50LmJvZHl9cmV0dXJuIGUud3JhcChzKSwoZVswXT09PW98fHQuY29udGFpbnMoZVswXSxvKSkmJnQobykudHJpZ2dlcihcImZvY3VzXCIpLHM9ZS5wYXJlbnQoKSxcInN0YXRpY1wiPT09ZS5jc3MoXCJwb3NpdGlvblwiKT8ocy5jc3Moe3Bvc2l0aW9uOlwicmVsYXRpdmVcIn0pLGUuY3NzKHtwb3NpdGlvbjpcInJlbGF0aXZlXCJ9KSk6KHQuZXh0ZW5kKGkse3Bvc2l0aW9uOmUuY3NzKFwicG9zaXRpb25cIiksekluZGV4OmUuY3NzKFwiei1pbmRleFwiKX0pLHQuZWFjaChbXCJ0b3BcIixcImxlZnRcIixcImJvdHRvbVwiLFwicmlnaHRcIl0sZnVuY3Rpb24odCxzKXtpW3NdPWUuY3NzKHMpLGlzTmFOKHBhcnNlSW50KGlbc10sMTApKSYmKGlbc109XCJhdXRvXCIpfSksZS5jc3Moe3Bvc2l0aW9uOlwicmVsYXRpdmVcIix0b3A6MCxsZWZ0OjAscmlnaHQ6XCJhdXRvXCIsYm90dG9tOlwiYXV0b1wifSkpLGUuY3NzKG4pLHMuY3NzKGkpLnNob3coKX0scmVtb3ZlV3JhcHBlcjpmdW5jdGlvbihlKXt2YXIgaT1kb2N1bWVudC5hY3RpdmVFbGVtZW50O3JldHVybiBlLnBhcmVudCgpLmlzKFwiLnVpLWVmZmVjdHMtd3JhcHBlclwiKSYmKGUucGFyZW50KCkucmVwbGFjZVdpdGgoZSksKGVbMF09PT1pfHx0LmNvbnRhaW5zKGVbMF0saSkpJiZ0KGkpLnRyaWdnZXIoXCJmb2N1c1wiKSksZX19KSx0LmV4dGVuZCh0LmVmZmVjdHMse3ZlcnNpb246XCIxLjEyLjFcIixkZWZpbmU6ZnVuY3Rpb24oZSxpLHMpe3JldHVybiBzfHwocz1pLGk9XCJlZmZlY3RcIiksdC5lZmZlY3RzLmVmZmVjdFtlXT1zLHQuZWZmZWN0cy5lZmZlY3RbZV0ubW9kZT1pLHN9LHNjYWxlZERpbWVuc2lvbnM6ZnVuY3Rpb24odCxlLGkpe2lmKDA9PT1lKXJldHVybntoZWlnaHQ6MCx3aWR0aDowLG91dGVySGVpZ2h0OjAsb3V0ZXJXaWR0aDowfTt2YXIgcz1cImhvcml6b250YWxcIiE9PWk/KGV8fDEwMCkvMTAwOjEsbj1cInZlcnRpY2FsXCIhPT1pPyhlfHwxMDApLzEwMDoxO3JldHVybntoZWlnaHQ6dC5oZWlnaHQoKSpuLHdpZHRoOnQud2lkdGgoKSpzLG91dGVySGVpZ2h0OnQub3V0ZXJIZWlnaHQoKSpuLG91dGVyV2lkdGg6dC5vdXRlcldpZHRoKCkqc319LGNsaXBUb0JveDpmdW5jdGlvbih0KXtyZXR1cm57d2lkdGg6dC5jbGlwLnJpZ2h0LXQuY2xpcC5sZWZ0LGhlaWdodDp0LmNsaXAuYm90dG9tLXQuY2xpcC50b3AsbGVmdDp0LmNsaXAubGVmdCx0b3A6dC5jbGlwLnRvcH19LHVuc2hpZnQ6ZnVuY3Rpb24odCxlLGkpe3ZhciBzPXQucXVldWUoKTtlPjEmJnMuc3BsaWNlLmFwcGx5KHMsWzEsMF0uY29uY2F0KHMuc3BsaWNlKGUsaSkpKSx0LmRlcXVldWUoKX0sc2F2ZVN0eWxlOmZ1bmN0aW9uKHQpe3QuZGF0YShnLHRbMF0uc3R5bGUuY3NzVGV4dCl9LHJlc3RvcmVTdHlsZTpmdW5jdGlvbih0KXt0WzBdLnN0eWxlLmNzc1RleHQ9dC5kYXRhKGcpfHxcIlwiLHQucmVtb3ZlRGF0YShnKX0sbW9kZTpmdW5jdGlvbih0LGUpe3ZhciBpPXQuaXMoXCI6aGlkZGVuXCIpO3JldHVyblwidG9nZ2xlXCI9PT1lJiYoZT1pP1wic2hvd1wiOlwiaGlkZVwiKSwoaT9cImhpZGVcIj09PWU6XCJzaG93XCI9PT1lKSYmKGU9XCJub25lXCIpLGV9LGdldEJhc2VsaW5lOmZ1bmN0aW9uKHQsZSl7dmFyIGkscztzd2l0Y2godFswXSl7Y2FzZVwidG9wXCI6aT0wO2JyZWFrO2Nhc2VcIm1pZGRsZVwiOmk9LjU7YnJlYWs7Y2FzZVwiYm90dG9tXCI6aT0xO2JyZWFrO2RlZmF1bHQ6aT10WzBdL2UuaGVpZ2h0fXN3aXRjaCh0WzFdKXtjYXNlXCJsZWZ0XCI6cz0wO2JyZWFrO2Nhc2VcImNlbnRlclwiOnM9LjU7YnJlYWs7Y2FzZVwicmlnaHRcIjpzPTE7YnJlYWs7ZGVmYXVsdDpzPXRbMV0vZS53aWR0aH1yZXR1cm57eDpzLHk6aX19LGNyZWF0ZVBsYWNlaG9sZGVyOmZ1bmN0aW9uKGUpe3ZhciBpLHM9ZS5jc3MoXCJwb3NpdGlvblwiKSxuPWUucG9zaXRpb24oKTtyZXR1cm4gZS5jc3Moe21hcmdpblRvcDplLmNzcyhcIm1hcmdpblRvcFwiKSxtYXJnaW5Cb3R0b206ZS5jc3MoXCJtYXJnaW5Cb3R0b21cIiksbWFyZ2luTGVmdDplLmNzcyhcIm1hcmdpbkxlZnRcIiksbWFyZ2luUmlnaHQ6ZS5jc3MoXCJtYXJnaW5SaWdodFwiKX0pLm91dGVyV2lkdGgoZS5vdXRlcldpZHRoKCkpLm91dGVySGVpZ2h0KGUub3V0ZXJIZWlnaHQoKSksL14oc3RhdGljfHJlbGF0aXZlKS8udGVzdChzKSYmKHM9XCJhYnNvbHV0ZVwiLGk9dChcIjxcIitlWzBdLm5vZGVOYW1lK1wiPlwiKS5pbnNlcnRBZnRlcihlKS5jc3Moe2Rpc3BsYXk6L14oaW5saW5lfHJ1YnkpLy50ZXN0KGUuY3NzKFwiZGlzcGxheVwiKSk/XCJpbmxpbmUtYmxvY2tcIjpcImJsb2NrXCIsdmlzaWJpbGl0eTpcImhpZGRlblwiLG1hcmdpblRvcDplLmNzcyhcIm1hcmdpblRvcFwiKSxtYXJnaW5Cb3R0b206ZS5jc3MoXCJtYXJnaW5Cb3R0b21cIiksbWFyZ2luTGVmdDplLmNzcyhcIm1hcmdpbkxlZnRcIiksbWFyZ2luUmlnaHQ6ZS5jc3MoXCJtYXJnaW5SaWdodFwiKSxcImZsb2F0XCI6ZS5jc3MoXCJmbG9hdFwiKX0pLm91dGVyV2lkdGgoZS5vdXRlcldpZHRoKCkpLm91dGVySGVpZ2h0KGUub3V0ZXJIZWlnaHQoKSkuYWRkQ2xhc3MoXCJ1aS1lZmZlY3RzLXBsYWNlaG9sZGVyXCIpLGUuZGF0YShmK1wicGxhY2Vob2xkZXJcIixpKSksZS5jc3Moe3Bvc2l0aW9uOnMsbGVmdDpuLmxlZnQsdG9wOm4udG9wfSksaX0scmVtb3ZlUGxhY2Vob2xkZXI6ZnVuY3Rpb24odCl7dmFyIGU9ZitcInBsYWNlaG9sZGVyXCIsaT10LmRhdGEoZSk7aSYmKGkucmVtb3ZlKCksdC5yZW1vdmVEYXRhKGUpKX0sY2xlYW5VcDpmdW5jdGlvbihlKXt0LmVmZmVjdHMucmVzdG9yZVN0eWxlKGUpLHQuZWZmZWN0cy5yZW1vdmVQbGFjZWhvbGRlcihlKX0sc2V0VHJhbnNpdGlvbjpmdW5jdGlvbihlLGkscyxuKXtyZXR1cm4gbj1ufHx7fSx0LmVhY2goaSxmdW5jdGlvbih0LGkpe3ZhciBvPWUuY3NzVW5pdChpKTtvWzBdPjAmJihuW2ldPW9bMF0qcytvWzFdKX0pLG59fSksdC5mbi5leHRlbmQoe2VmZmVjdDpmdW5jdGlvbigpe2Z1bmN0aW9uIGkoZSl7ZnVuY3Rpb24gaSgpe3IucmVtb3ZlRGF0YShtKSx0LmVmZmVjdHMuY2xlYW5VcChyKSxcImhpZGVcIj09PXMubW9kZSYmci5oaWRlKCksYSgpfWZ1bmN0aW9uIGEoKXt0LmlzRnVuY3Rpb24oaCkmJmguY2FsbChyWzBdKSx0LmlzRnVuY3Rpb24oZSkmJmUoKX12YXIgcj10KHRoaXMpO3MubW9kZT1jLnNoaWZ0KCksdC51aUJhY2tDb21wYXQ9PT0hMXx8bz9cIm5vbmVcIj09PXMubW9kZT8ocltsXSgpLGEoKSk6bi5jYWxsKHJbMF0scyxpKTooci5pcyhcIjpoaWRkZW5cIik/XCJoaWRlXCI9PT1sOlwic2hvd1wiPT09bCk/KHJbbF0oKSxhKCkpOm4uY2FsbChyWzBdLHMsYSl9dmFyIHM9ZS5hcHBseSh0aGlzLGFyZ3VtZW50cyksbj10LmVmZmVjdHMuZWZmZWN0W3MuZWZmZWN0XSxvPW4ubW9kZSxhPXMucXVldWUscj1hfHxcImZ4XCIsaD1zLmNvbXBsZXRlLGw9cy5tb2RlLGM9W10sdT1mdW5jdGlvbihlKXt2YXIgaT10KHRoaXMpLHM9dC5lZmZlY3RzLm1vZGUoaSxsKXx8bztpLmRhdGEobSwhMCksYy5wdXNoKHMpLG8mJihcInNob3dcIj09PXN8fHM9PT1vJiZcImhpZGVcIj09PXMpJiZpLnNob3coKSxvJiZcIm5vbmVcIj09PXN8fHQuZWZmZWN0cy5zYXZlU3R5bGUoaSksdC5pc0Z1bmN0aW9uKGUpJiZlKCl9O3JldHVybiB0LmZ4Lm9mZnx8IW4/bD90aGlzW2xdKHMuZHVyYXRpb24saCk6dGhpcy5lYWNoKGZ1bmN0aW9uKCl7aCYmaC5jYWxsKHRoaXMpfSk6YT09PSExP3RoaXMuZWFjaCh1KS5lYWNoKGkpOnRoaXMucXVldWUocix1KS5xdWV1ZShyLGkpfSxzaG93OmZ1bmN0aW9uKHQpe3JldHVybiBmdW5jdGlvbihzKXtpZihpKHMpKXJldHVybiB0LmFwcGx5KHRoaXMsYXJndW1lbnRzKTt2YXIgbj1lLmFwcGx5KHRoaXMsYXJndW1lbnRzKTtyZXR1cm4gbi5tb2RlPVwic2hvd1wiLHRoaXMuZWZmZWN0LmNhbGwodGhpcyxuKX19KHQuZm4uc2hvdyksaGlkZTpmdW5jdGlvbih0KXtyZXR1cm4gZnVuY3Rpb24ocyl7aWYoaShzKSlyZXR1cm4gdC5hcHBseSh0aGlzLGFyZ3VtZW50cyk7dmFyIG49ZS5hcHBseSh0aGlzLGFyZ3VtZW50cyk7cmV0dXJuIG4ubW9kZT1cImhpZGVcIix0aGlzLmVmZmVjdC5jYWxsKHRoaXMsbil9fSh0LmZuLmhpZGUpLHRvZ2dsZTpmdW5jdGlvbih0KXtyZXR1cm4gZnVuY3Rpb24ocyl7aWYoaShzKXx8XCJib29sZWFuXCI9PXR5cGVvZiBzKXJldHVybiB0LmFwcGx5KHRoaXMsYXJndW1lbnRzKTt2YXIgbj1lLmFwcGx5KHRoaXMsYXJndW1lbnRzKTtyZXR1cm4gbi5tb2RlPVwidG9nZ2xlXCIsdGhpcy5lZmZlY3QuY2FsbCh0aGlzLG4pfX0odC5mbi50b2dnbGUpLGNzc1VuaXQ6ZnVuY3Rpb24oZSl7dmFyIGk9dGhpcy5jc3MoZSkscz1bXTtyZXR1cm4gdC5lYWNoKFtcImVtXCIsXCJweFwiLFwiJVwiLFwicHRcIl0sZnVuY3Rpb24odCxlKXtpLmluZGV4T2YoZSk+MCYmKHM9W3BhcnNlRmxvYXQoaSksZV0pfSksc30sY3NzQ2xpcDpmdW5jdGlvbih0KXtyZXR1cm4gdD90aGlzLmNzcyhcImNsaXBcIixcInJlY3QoXCIrdC50b3ArXCJweCBcIit0LnJpZ2h0K1wicHggXCIrdC5ib3R0b20rXCJweCBcIit0LmxlZnQrXCJweClcIik6cyh0aGlzLmNzcyhcImNsaXBcIiksdGhpcyl9LHRyYW5zZmVyOmZ1bmN0aW9uKGUsaSl7dmFyIHM9dCh0aGlzKSxuPXQoZS50byksbz1cImZpeGVkXCI9PT1uLmNzcyhcInBvc2l0aW9uXCIpLGE9dChcImJvZHlcIikscj1vP2Euc2Nyb2xsVG9wKCk6MCxoPW8/YS5zY3JvbGxMZWZ0KCk6MCxsPW4ub2Zmc2V0KCksYz17dG9wOmwudG9wLXIsbGVmdDpsLmxlZnQtaCxoZWlnaHQ6bi5pbm5lckhlaWdodCgpLHdpZHRoOm4uaW5uZXJXaWR0aCgpfSx1PXMub2Zmc2V0KCksZD10KFwiPGRpdiBjbGFzcz0ndWktZWZmZWN0cy10cmFuc2Zlcic+PC9kaXY+XCIpLmFwcGVuZFRvKFwiYm9keVwiKS5hZGRDbGFzcyhlLmNsYXNzTmFtZSkuY3NzKHt0b3A6dS50b3AtcixsZWZ0OnUubGVmdC1oLGhlaWdodDpzLmlubmVySGVpZ2h0KCksd2lkdGg6cy5pbm5lcldpZHRoKCkscG9zaXRpb246bz9cImZpeGVkXCI6XCJhYnNvbHV0ZVwifSkuYW5pbWF0ZShjLGUuZHVyYXRpb24sZS5lYXNpbmcsZnVuY3Rpb24oKXtkLnJlbW92ZSgpLHQuaXNGdW5jdGlvbihpKSYmaSgpfSl9fSksdC5meC5zdGVwLmNsaXA9ZnVuY3Rpb24oZSl7ZS5jbGlwSW5pdHx8KGUuc3RhcnQ9dChlLmVsZW0pLmNzc0NsaXAoKSxcInN0cmluZ1wiPT10eXBlb2YgZS5lbmQmJihlLmVuZD1zKGUuZW5kLGUuZWxlbSkpLGUuY2xpcEluaXQ9ITApLHQoZS5lbGVtKS5jc3NDbGlwKHt0b3A6ZS5wb3MqKGUuZW5kLnRvcC1lLnN0YXJ0LnRvcCkrZS5zdGFydC50b3AscmlnaHQ6ZS5wb3MqKGUuZW5kLnJpZ2h0LWUuc3RhcnQucmlnaHQpK2Uuc3RhcnQucmlnaHQsYm90dG9tOmUucG9zKihlLmVuZC5ib3R0b20tZS5zdGFydC5ib3R0b20pK2Uuc3RhcnQuYm90dG9tLGxlZnQ6ZS5wb3MqKGUuZW5kLmxlZnQtZS5zdGFydC5sZWZ0KStlLnN0YXJ0LmxlZnR9KX19KCksZnVuY3Rpb24oKXt2YXIgZT17fTt0LmVhY2goW1wiUXVhZFwiLFwiQ3ViaWNcIixcIlF1YXJ0XCIsXCJRdWludFwiLFwiRXhwb1wiXSxmdW5jdGlvbih0LGkpe2VbaV09ZnVuY3Rpb24oZSl7cmV0dXJuIE1hdGgucG93KGUsdCsyKX19KSx0LmV4dGVuZChlLHtTaW5lOmZ1bmN0aW9uKHQpe3JldHVybiAxLU1hdGguY29zKHQqTWF0aC5QSS8yKX0sQ2lyYzpmdW5jdGlvbih0KXtyZXR1cm4gMS1NYXRoLnNxcnQoMS10KnQpfSxFbGFzdGljOmZ1bmN0aW9uKHQpe3JldHVybiAwPT09dHx8MT09PXQ/dDotTWF0aC5wb3coMiw4Kih0LTEpKSpNYXRoLnNpbigoODAqKHQtMSktNy41KSpNYXRoLlBJLzE1KX0sQmFjazpmdW5jdGlvbih0KXtyZXR1cm4gdCp0KigzKnQtMil9LEJvdW5jZTpmdW5jdGlvbih0KXtmb3IodmFyIGUsaT00OygoZT1NYXRoLnBvdygyLC0taSkpLTEpLzExPnQ7KTtyZXR1cm4gMS9NYXRoLnBvdyg0LDMtaSktNy41NjI1Kk1hdGgucG93KCgzKmUtMikvMjItdCwyKX19KSx0LmVhY2goZSxmdW5jdGlvbihlLGkpe3QuZWFzaW5nW1wiZWFzZUluXCIrZV09aSx0LmVhc2luZ1tcImVhc2VPdXRcIitlXT1mdW5jdGlvbih0KXtyZXR1cm4gMS1pKDEtdCl9LHQuZWFzaW5nW1wiZWFzZUluT3V0XCIrZV09ZnVuY3Rpb24odCl7cmV0dXJuLjU+dD9pKDIqdCkvMjoxLWkoLTIqdCsyKS8yfX0pfSgpO3ZhciB2PXQuZWZmZWN0czt0LmVmZmVjdHMuZGVmaW5lKFwiYmxpbmRcIixcImhpZGVcIixmdW5jdGlvbihlLGkpe3ZhciBzPXt1cDpbXCJib3R0b21cIixcInRvcFwiXSx2ZXJ0aWNhbDpbXCJib3R0b21cIixcInRvcFwiXSxkb3duOltcInRvcFwiLFwiYm90dG9tXCJdLGxlZnQ6W1wicmlnaHRcIixcImxlZnRcIl0saG9yaXpvbnRhbDpbXCJyaWdodFwiLFwibGVmdFwiXSxyaWdodDpbXCJsZWZ0XCIsXCJyaWdodFwiXX0sbj10KHRoaXMpLG89ZS5kaXJlY3Rpb258fFwidXBcIixhPW4uY3NzQ2xpcCgpLHI9e2NsaXA6dC5leHRlbmQoe30sYSl9LGg9dC5lZmZlY3RzLmNyZWF0ZVBsYWNlaG9sZGVyKG4pO3IuY2xpcFtzW29dWzBdXT1yLmNsaXBbc1tvXVsxXV0sXCJzaG93XCI9PT1lLm1vZGUmJihuLmNzc0NsaXAoci5jbGlwKSxoJiZoLmNzcyh0LmVmZmVjdHMuY2xpcFRvQm94KHIpKSxyLmNsaXA9YSksaCYmaC5hbmltYXRlKHQuZWZmZWN0cy5jbGlwVG9Cb3gociksZS5kdXJhdGlvbixlLmVhc2luZyksbi5hbmltYXRlKHIse3F1ZXVlOiExLGR1cmF0aW9uOmUuZHVyYXRpb24sZWFzaW5nOmUuZWFzaW5nLGNvbXBsZXRlOml9KX0pLHQuZWZmZWN0cy5kZWZpbmUoXCJib3VuY2VcIixmdW5jdGlvbihlLGkpe3ZhciBzLG4sbyxhPXQodGhpcykscj1lLm1vZGUsaD1cImhpZGVcIj09PXIsbD1cInNob3dcIj09PXIsYz1lLmRpcmVjdGlvbnx8XCJ1cFwiLHU9ZS5kaXN0YW5jZSxkPWUudGltZXN8fDUscD0yKmQrKGx8fGg/MTowKSxmPWUuZHVyYXRpb24vcCxnPWUuZWFzaW5nLG09XCJ1cFwiPT09Y3x8XCJkb3duXCI9PT1jP1widG9wXCI6XCJsZWZ0XCIsXz1cInVwXCI9PT1jfHxcImxlZnRcIj09PWMsdj0wLGI9YS5xdWV1ZSgpLmxlbmd0aDtmb3IodC5lZmZlY3RzLmNyZWF0ZVBsYWNlaG9sZGVyKGEpLG89YS5jc3MobSksdXx8KHU9YVtcInRvcFwiPT09bT9cIm91dGVySGVpZ2h0XCI6XCJvdXRlcldpZHRoXCJdKCkvMyksbCYmKG49e29wYWNpdHk6MX0sblttXT1vLGEuY3NzKFwib3BhY2l0eVwiLDApLmNzcyhtLF8/MiotdToyKnUpLmFuaW1hdGUobixmLGcpKSxoJiYodS89TWF0aC5wb3coMixkLTEpKSxuPXt9LG5bbV09bztkPnY7disrKXM9e30sc1ttXT0oXz9cIi09XCI6XCIrPVwiKSt1LGEuYW5pbWF0ZShzLGYsZykuYW5pbWF0ZShuLGYsZyksdT1oPzIqdTp1LzI7aCYmKHM9e29wYWNpdHk6MH0sc1ttXT0oXz9cIi09XCI6XCIrPVwiKSt1LGEuYW5pbWF0ZShzLGYsZykpLGEucXVldWUoaSksdC5lZmZlY3RzLnVuc2hpZnQoYSxiLHArMSl9KSx0LmVmZmVjdHMuZGVmaW5lKFwiY2xpcFwiLFwiaGlkZVwiLGZ1bmN0aW9uKGUsaSl7dmFyIHMsbj17fSxvPXQodGhpcyksYT1lLmRpcmVjdGlvbnx8XCJ2ZXJ0aWNhbFwiLHI9XCJib3RoXCI9PT1hLGg9cnx8XCJob3Jpem9udGFsXCI9PT1hLGw9cnx8XCJ2ZXJ0aWNhbFwiPT09YTtzPW8uY3NzQ2xpcCgpLG4uY2xpcD17dG9wOmw/KHMuYm90dG9tLXMudG9wKS8yOnMudG9wLHJpZ2h0Omg/KHMucmlnaHQtcy5sZWZ0KS8yOnMucmlnaHQsYm90dG9tOmw/KHMuYm90dG9tLXMudG9wKS8yOnMuYm90dG9tLGxlZnQ6aD8ocy5yaWdodC1zLmxlZnQpLzI6cy5sZWZ0fSx0LmVmZmVjdHMuY3JlYXRlUGxhY2Vob2xkZXIobyksXCJzaG93XCI9PT1lLm1vZGUmJihvLmNzc0NsaXAobi5jbGlwKSxuLmNsaXA9cyksby5hbmltYXRlKG4se3F1ZXVlOiExLGR1cmF0aW9uOmUuZHVyYXRpb24sZWFzaW5nOmUuZWFzaW5nLGNvbXBsZXRlOml9KX0pLHQuZWZmZWN0cy5kZWZpbmUoXCJkcm9wXCIsXCJoaWRlXCIsZnVuY3Rpb24oZSxpKXt2YXIgcyxuPXQodGhpcyksbz1lLm1vZGUsYT1cInNob3dcIj09PW8scj1lLmRpcmVjdGlvbnx8XCJsZWZ0XCIsaD1cInVwXCI9PT1yfHxcImRvd25cIj09PXI/XCJ0b3BcIjpcImxlZnRcIixsPVwidXBcIj09PXJ8fFwibGVmdFwiPT09cj9cIi09XCI6XCIrPVwiLGM9XCIrPVwiPT09bD9cIi09XCI6XCIrPVwiLHU9e29wYWNpdHk6MH07dC5lZmZlY3RzLmNyZWF0ZVBsYWNlaG9sZGVyKG4pLHM9ZS5kaXN0YW5jZXx8bltcInRvcFwiPT09aD9cIm91dGVySGVpZ2h0XCI6XCJvdXRlcldpZHRoXCJdKCEwKS8yLHVbaF09bCtzLGEmJihuLmNzcyh1KSx1W2hdPWMrcyx1Lm9wYWNpdHk9MSksbi5hbmltYXRlKHUse3F1ZXVlOiExLGR1cmF0aW9uOmUuZHVyYXRpb24sZWFzaW5nOmUuZWFzaW5nLGNvbXBsZXRlOml9KX0pLHQuZWZmZWN0cy5kZWZpbmUoXCJleHBsb2RlXCIsXCJoaWRlXCIsZnVuY3Rpb24oZSxpKXtmdW5jdGlvbiBzKCl7Yi5wdXNoKHRoaXMpLGIubGVuZ3RoPT09dSpkJiZuKCl9ZnVuY3Rpb24gbigpe3AuY3NzKHt2aXNpYmlsaXR5OlwidmlzaWJsZVwifSksdChiKS5yZW1vdmUoKSxpKCl9dmFyIG8sYSxyLGgsbCxjLHU9ZS5waWVjZXM/TWF0aC5yb3VuZChNYXRoLnNxcnQoZS5waWVjZXMpKTozLGQ9dSxwPXQodGhpcyksZj1lLm1vZGUsZz1cInNob3dcIj09PWYsbT1wLnNob3coKS5jc3MoXCJ2aXNpYmlsaXR5XCIsXCJoaWRkZW5cIikub2Zmc2V0KCksXz1NYXRoLmNlaWwocC5vdXRlcldpZHRoKCkvZCksdj1NYXRoLmNlaWwocC5vdXRlckhlaWdodCgpL3UpLGI9W107Zm9yKG89MDt1Pm87bysrKWZvcihoPW0udG9wK28qdixjPW8tKHUtMSkvMixhPTA7ZD5hO2ErKylyPW0ubGVmdCthKl8sbD1hLShkLTEpLzIscC5jbG9uZSgpLmFwcGVuZFRvKFwiYm9keVwiKS53cmFwKFwiPGRpdj48L2Rpdj5cIikuY3NzKHtwb3NpdGlvbjpcImFic29sdXRlXCIsdmlzaWJpbGl0eTpcInZpc2libGVcIixsZWZ0Oi1hKl8sdG9wOi1vKnZ9KS5wYXJlbnQoKS5hZGRDbGFzcyhcInVpLWVmZmVjdHMtZXhwbG9kZVwiKS5jc3Moe3Bvc2l0aW9uOlwiYWJzb2x1dGVcIixvdmVyZmxvdzpcImhpZGRlblwiLHdpZHRoOl8saGVpZ2h0OnYsbGVmdDpyKyhnP2wqXzowKSx0b3A6aCsoZz9jKnY6MCksb3BhY2l0eTpnPzA6MX0pLmFuaW1hdGUoe2xlZnQ6cisoZz8wOmwqXyksdG9wOmgrKGc/MDpjKnYpLG9wYWNpdHk6Zz8xOjB9LGUuZHVyYXRpb258fDUwMCxlLmVhc2luZyxzKX0pLHQuZWZmZWN0cy5kZWZpbmUoXCJmYWRlXCIsXCJ0b2dnbGVcIixmdW5jdGlvbihlLGkpe3ZhciBzPVwic2hvd1wiPT09ZS5tb2RlO3QodGhpcykuY3NzKFwib3BhY2l0eVwiLHM/MDoxKS5hbmltYXRlKHtvcGFjaXR5OnM/MTowfSx7cXVldWU6ITEsZHVyYXRpb246ZS5kdXJhdGlvbixlYXNpbmc6ZS5lYXNpbmcsY29tcGxldGU6aX0pfSksdC5lZmZlY3RzLmRlZmluZShcImZvbGRcIixcImhpZGVcIixmdW5jdGlvbihlLGkpe3ZhciBzPXQodGhpcyksbj1lLm1vZGUsbz1cInNob3dcIj09PW4sYT1cImhpZGVcIj09PW4scj1lLnNpemV8fDE1LGg9LyhbMC05XSspJS8uZXhlYyhyKSxsPSEhZS5ob3JpekZpcnN0LGM9bD9bXCJyaWdodFwiLFwiYm90dG9tXCJdOltcImJvdHRvbVwiLFwicmlnaHRcIl0sdT1lLmR1cmF0aW9uLzIsZD10LmVmZmVjdHMuY3JlYXRlUGxhY2Vob2xkZXIocykscD1zLmNzc0NsaXAoKSxmPXtjbGlwOnQuZXh0ZW5kKHt9LHApfSxnPXtjbGlwOnQuZXh0ZW5kKHt9LHApfSxtPVtwW2NbMF1dLHBbY1sxXV1dLF89cy5xdWV1ZSgpLmxlbmd0aDtoJiYocj1wYXJzZUludChoWzFdLDEwKS8xMDAqbVthPzA6MV0pLGYuY2xpcFtjWzBdXT1yLGcuY2xpcFtjWzBdXT1yLGcuY2xpcFtjWzFdXT0wLG8mJihzLmNzc0NsaXAoZy5jbGlwKSxkJiZkLmNzcyh0LmVmZmVjdHMuY2xpcFRvQm94KGcpKSxnLmNsaXA9cCkscy5xdWV1ZShmdW5jdGlvbihpKXtkJiZkLmFuaW1hdGUodC5lZmZlY3RzLmNsaXBUb0JveChmKSx1LGUuZWFzaW5nKS5hbmltYXRlKHQuZWZmZWN0cy5jbGlwVG9Cb3goZyksdSxlLmVhc2luZyksaSgpfSkuYW5pbWF0ZShmLHUsZS5lYXNpbmcpLmFuaW1hdGUoZyx1LGUuZWFzaW5nKS5xdWV1ZShpKSx0LmVmZmVjdHMudW5zaGlmdChzLF8sNCl9KSx0LmVmZmVjdHMuZGVmaW5lKFwiaGlnaGxpZ2h0XCIsXCJzaG93XCIsZnVuY3Rpb24oZSxpKXt2YXIgcz10KHRoaXMpLG49e2JhY2tncm91bmRDb2xvcjpzLmNzcyhcImJhY2tncm91bmRDb2xvclwiKX07XCJoaWRlXCI9PT1lLm1vZGUmJihuLm9wYWNpdHk9MCksdC5lZmZlY3RzLnNhdmVTdHlsZShzKSxzLmNzcyh7YmFja2dyb3VuZEltYWdlOlwibm9uZVwiLGJhY2tncm91bmRDb2xvcjplLmNvbG9yfHxcIiNmZmZmOTlcIn0pLmFuaW1hdGUobix7cXVldWU6ITEsZHVyYXRpb246ZS5kdXJhdGlvbixlYXNpbmc6ZS5lYXNpbmcsY29tcGxldGU6aX0pfSksdC5lZmZlY3RzLmRlZmluZShcInNpemVcIixmdW5jdGlvbihlLGkpe3ZhciBzLG4sbyxhPXQodGhpcykscj1bXCJmb250U2l6ZVwiXSxoPVtcImJvcmRlclRvcFdpZHRoXCIsXCJib3JkZXJCb3R0b21XaWR0aFwiLFwicGFkZGluZ1RvcFwiLFwicGFkZGluZ0JvdHRvbVwiXSxsPVtcImJvcmRlckxlZnRXaWR0aFwiLFwiYm9yZGVyUmlnaHRXaWR0aFwiLFwicGFkZGluZ0xlZnRcIixcInBhZGRpbmdSaWdodFwiXSxjPWUubW9kZSx1PVwiZWZmZWN0XCIhPT1jLGQ9ZS5zY2FsZXx8XCJib3RoXCIscD1lLm9yaWdpbnx8W1wibWlkZGxlXCIsXCJjZW50ZXJcIl0sZj1hLmNzcyhcInBvc2l0aW9uXCIpLGc9YS5wb3NpdGlvbigpLG09dC5lZmZlY3RzLnNjYWxlZERpbWVuc2lvbnMoYSksXz1lLmZyb218fG0sdj1lLnRvfHx0LmVmZmVjdHMuc2NhbGVkRGltZW5zaW9ucyhhLDApO3QuZWZmZWN0cy5jcmVhdGVQbGFjZWhvbGRlcihhKSxcInNob3dcIj09PWMmJihvPV8sXz12LHY9byksbj17ZnJvbTp7eTpfLmhlaWdodC9tLmhlaWdodCx4Ol8ud2lkdGgvbS53aWR0aH0sdG86e3k6di5oZWlnaHQvbS5oZWlnaHQseDp2LndpZHRoL20ud2lkdGh9fSwoXCJib3hcIj09PWR8fFwiYm90aFwiPT09ZCkmJihuLmZyb20ueSE9PW4udG8ueSYmKF89dC5lZmZlY3RzLnNldFRyYW5zaXRpb24oYSxoLG4uZnJvbS55LF8pLHY9dC5lZmZlY3RzLnNldFRyYW5zaXRpb24oYSxoLG4udG8ueSx2KSksbi5mcm9tLnghPT1uLnRvLngmJihfPXQuZWZmZWN0cy5zZXRUcmFuc2l0aW9uKGEsbCxuLmZyb20ueCxfKSx2PXQuZWZmZWN0cy5zZXRUcmFuc2l0aW9uKGEsbCxuLnRvLngsdikpKSwoXCJjb250ZW50XCI9PT1kfHxcImJvdGhcIj09PWQpJiZuLmZyb20ueSE9PW4udG8ueSYmKF89dC5lZmZlY3RzLnNldFRyYW5zaXRpb24oYSxyLG4uZnJvbS55LF8pLHY9dC5lZmZlY3RzLnNldFRyYW5zaXRpb24oYSxyLG4udG8ueSx2KSkscCYmKHM9dC5lZmZlY3RzLmdldEJhc2VsaW5lKHAsbSksXy50b3A9KG0ub3V0ZXJIZWlnaHQtXy5vdXRlckhlaWdodCkqcy55K2cudG9wLF8ubGVmdD0obS5vdXRlcldpZHRoLV8ub3V0ZXJXaWR0aCkqcy54K2cubGVmdCx2LnRvcD0obS5vdXRlckhlaWdodC12Lm91dGVySGVpZ2h0KSpzLnkrZy50b3Asdi5sZWZ0PShtLm91dGVyV2lkdGgtdi5vdXRlcldpZHRoKSpzLngrZy5sZWZ0KSxhLmNzcyhfKSwoXCJjb250ZW50XCI9PT1kfHxcImJvdGhcIj09PWQpJiYoaD1oLmNvbmNhdChbXCJtYXJnaW5Ub3BcIixcIm1hcmdpbkJvdHRvbVwiXSkuY29uY2F0KHIpLGw9bC5jb25jYXQoW1wibWFyZ2luTGVmdFwiLFwibWFyZ2luUmlnaHRcIl0pLGEuZmluZChcIipbd2lkdGhdXCIpLmVhY2goZnVuY3Rpb24oKXt2YXIgaT10KHRoaXMpLHM9dC5lZmZlY3RzLnNjYWxlZERpbWVuc2lvbnMoaSksbz17aGVpZ2h0OnMuaGVpZ2h0Km4uZnJvbS55LHdpZHRoOnMud2lkdGgqbi5mcm9tLngsb3V0ZXJIZWlnaHQ6cy5vdXRlckhlaWdodCpuLmZyb20ueSxvdXRlcldpZHRoOnMub3V0ZXJXaWR0aCpuLmZyb20ueH0sYT17aGVpZ2h0OnMuaGVpZ2h0Km4udG8ueSx3aWR0aDpzLndpZHRoKm4udG8ueCxvdXRlckhlaWdodDpzLmhlaWdodCpuLnRvLnksb3V0ZXJXaWR0aDpzLndpZHRoKm4udG8ueH07bi5mcm9tLnkhPT1uLnRvLnkmJihvPXQuZWZmZWN0cy5zZXRUcmFuc2l0aW9uKGksaCxuLmZyb20ueSxvKSxhPXQuZWZmZWN0cy5zZXRUcmFuc2l0aW9uKGksaCxuLnRvLnksYSkpLG4uZnJvbS54IT09bi50by54JiYobz10LmVmZmVjdHMuc2V0VHJhbnNpdGlvbihpLGwsbi5mcm9tLngsbyksYT10LmVmZmVjdHMuc2V0VHJhbnNpdGlvbihpLGwsbi50by54LGEpKSx1JiZ0LmVmZmVjdHMuc2F2ZVN0eWxlKGkpLGkuY3NzKG8pLGkuYW5pbWF0ZShhLGUuZHVyYXRpb24sZS5lYXNpbmcsZnVuY3Rpb24oKXt1JiZ0LmVmZmVjdHMucmVzdG9yZVN0eWxlKGkpfSl9KSksYS5hbmltYXRlKHYse3F1ZXVlOiExLGR1cmF0aW9uOmUuZHVyYXRpb24sZWFzaW5nOmUuZWFzaW5nLGNvbXBsZXRlOmZ1bmN0aW9uKCl7dmFyIGU9YS5vZmZzZXQoKTswPT09di5vcGFjaXR5JiZhLmNzcyhcIm9wYWNpdHlcIixfLm9wYWNpdHkpLHV8fChhLmNzcyhcInBvc2l0aW9uXCIsXCJzdGF0aWNcIj09PWY/XCJyZWxhdGl2ZVwiOmYpLm9mZnNldChlKSx0LmVmZmVjdHMuc2F2ZVN0eWxlKGEpKSxpKCl9fSl9KSx0LmVmZmVjdHMuZGVmaW5lKFwic2NhbGVcIixmdW5jdGlvbihlLGkpe3ZhciBzPXQodGhpcyksbj1lLm1vZGUsbz1wYXJzZUludChlLnBlcmNlbnQsMTApfHwoMD09PXBhcnNlSW50KGUucGVyY2VudCwxMCk/MDpcImVmZmVjdFwiIT09bj8wOjEwMCksYT10LmV4dGVuZCghMCx7ZnJvbTp0LmVmZmVjdHMuc2NhbGVkRGltZW5zaW9ucyhzKSx0bzp0LmVmZmVjdHMuc2NhbGVkRGltZW5zaW9ucyhzLG8sZS5kaXJlY3Rpb258fFwiYm90aFwiKSxvcmlnaW46ZS5vcmlnaW58fFtcIm1pZGRsZVwiLFwiY2VudGVyXCJdfSxlKTtlLmZhZGUmJihhLmZyb20ub3BhY2l0eT0xLGEudG8ub3BhY2l0eT0wKSx0LmVmZmVjdHMuZWZmZWN0LnNpemUuY2FsbCh0aGlzLGEsaSl9KSx0LmVmZmVjdHMuZGVmaW5lKFwicHVmZlwiLFwiaGlkZVwiLGZ1bmN0aW9uKGUsaSl7dmFyIHM9dC5leHRlbmQoITAse30sZSx7ZmFkZTohMCxwZXJjZW50OnBhcnNlSW50KGUucGVyY2VudCwxMCl8fDE1MH0pO3QuZWZmZWN0cy5lZmZlY3Quc2NhbGUuY2FsbCh0aGlzLHMsaSl9KSx0LmVmZmVjdHMuZGVmaW5lKFwicHVsc2F0ZVwiLFwic2hvd1wiLGZ1bmN0aW9uKGUsaSl7dmFyIHM9dCh0aGlzKSxuPWUubW9kZSxvPVwic2hvd1wiPT09bixhPVwiaGlkZVwiPT09bixyPW98fGEsaD0yKihlLnRpbWVzfHw1KSsocj8xOjApLGw9ZS5kdXJhdGlvbi9oLGM9MCx1PTEsZD1zLnF1ZXVlKCkubGVuZ3RoO2Zvcigob3x8IXMuaXMoXCI6dmlzaWJsZVwiKSkmJihzLmNzcyhcIm9wYWNpdHlcIiwwKS5zaG93KCksYz0xKTtoPnU7dSsrKXMuYW5pbWF0ZSh7b3BhY2l0eTpjfSxsLGUuZWFzaW5nKSxjPTEtYztzLmFuaW1hdGUoe29wYWNpdHk6Y30sbCxlLmVhc2luZykscy5xdWV1ZShpKSx0LmVmZmVjdHMudW5zaGlmdChzLGQsaCsxKX0pLHQuZWZmZWN0cy5kZWZpbmUoXCJzaGFrZVwiLGZ1bmN0aW9uKGUsaSl7dmFyIHM9MSxuPXQodGhpcyksbz1lLmRpcmVjdGlvbnx8XCJsZWZ0XCIsYT1lLmRpc3RhbmNlfHwyMCxyPWUudGltZXN8fDMsaD0yKnIrMSxsPU1hdGgucm91bmQoZS5kdXJhdGlvbi9oKSxjPVwidXBcIj09PW98fFwiZG93blwiPT09bz9cInRvcFwiOlwibGVmdFwiLHU9XCJ1cFwiPT09b3x8XCJsZWZ0XCI9PT1vLGQ9e30scD17fSxmPXt9LGc9bi5xdWV1ZSgpLmxlbmd0aDtmb3IodC5lZmZlY3RzLmNyZWF0ZVBsYWNlaG9sZGVyKG4pLGRbY109KHU/XCItPVwiOlwiKz1cIikrYSxwW2NdPSh1P1wiKz1cIjpcIi09XCIpKzIqYSxmW2NdPSh1P1wiLT1cIjpcIis9XCIpKzIqYSxuLmFuaW1hdGUoZCxsLGUuZWFzaW5nKTtyPnM7cysrKW4uYW5pbWF0ZShwLGwsZS5lYXNpbmcpLmFuaW1hdGUoZixsLGUuZWFzaW5nKTtuLmFuaW1hdGUocCxsLGUuZWFzaW5nKS5hbmltYXRlKGQsbC8yLGUuZWFzaW5nKS5xdWV1ZShpKSx0LmVmZmVjdHMudW5zaGlmdChuLGcsaCsxKX0pLHQuZWZmZWN0cy5kZWZpbmUoXCJzbGlkZVwiLFwic2hvd1wiLGZ1bmN0aW9uKGUsaSl7dmFyIHMsbixvPXQodGhpcyksYT17dXA6W1wiYm90dG9tXCIsXCJ0b3BcIl0sZG93bjpbXCJ0b3BcIixcImJvdHRvbVwiXSxsZWZ0OltcInJpZ2h0XCIsXCJsZWZ0XCJdLHJpZ2h0OltcImxlZnRcIixcInJpZ2h0XCJdfSxyPWUubW9kZSxoPWUuZGlyZWN0aW9ufHxcImxlZnRcIixsPVwidXBcIj09PWh8fFwiZG93blwiPT09aD9cInRvcFwiOlwibGVmdFwiLGM9XCJ1cFwiPT09aHx8XCJsZWZ0XCI9PT1oLHU9ZS5kaXN0YW5jZXx8b1tcInRvcFwiPT09bD9cIm91dGVySGVpZ2h0XCI6XCJvdXRlcldpZHRoXCJdKCEwKSxkPXt9O3QuZWZmZWN0cy5jcmVhdGVQbGFjZWhvbGRlcihvKSxzPW8uY3NzQ2xpcCgpLG49by5wb3NpdGlvbigpW2xdLGRbbF09KGM/LTE6MSkqdStuLGQuY2xpcD1vLmNzc0NsaXAoKSxkLmNsaXBbYVtoXVsxXV09ZC5jbGlwW2FbaF1bMF1dLFwic2hvd1wiPT09ciYmKG8uY3NzQ2xpcChkLmNsaXApLG8uY3NzKGwsZFtsXSksZC5jbGlwPXMsZFtsXT1uKSxvLmFuaW1hdGUoZCx7cXVldWU6ITEsZHVyYXRpb246ZS5kdXJhdGlvbixlYXNpbmc6ZS5lYXNpbmcsY29tcGxldGU6aX0pfSk7dmFyIHY7dC51aUJhY2tDb21wYXQhPT0hMSYmKHY9dC5lZmZlY3RzLmRlZmluZShcInRyYW5zZmVyXCIsZnVuY3Rpb24oZSxpKXt0KHRoaXMpLnRyYW5zZmVyKGUsaSl9KSl9KTtcblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyAuL25vZGVfbW9kdWxlcy9qcXVlcnktdWktYnVuZGxlL2pxdWVyeS11aS5taW4uanNcbi8vIG1vZHVsZSBpZCA9IDdcbi8vIG1vZHVsZSBjaHVua3MgPSAwIiwiXG53aW5kb3cuXyA9IHJlcXVpcmUoJ2xvZGFzaCcpO1xuXG4vKipcbiAqIFdlJ2xsIGxvYWQgalF1ZXJ5IGFuZCB0aGUgQm9vdHN0cmFwIGpRdWVyeSBwbHVnaW4gd2hpY2ggcHJvdmlkZXMgc3VwcG9ydFxuICogZm9yIEphdmFTY3JpcHQgYmFzZWQgQm9vdHN0cmFwIGZlYXR1cmVzIHN1Y2ggYXMgbW9kYWxzIGFuZCB0YWJzLiBUaGlzXG4gKiBjb2RlIG1heSBiZSBtb2RpZmllZCB0byBmaXQgdGhlIHNwZWNpZmljIG5lZWRzIG9mIHlvdXIgYXBwbGljYXRpb24uXG4gKi9cblxud2luZG93LiQgPSB3aW5kb3cualF1ZXJ5ID0gcmVxdWlyZSgnanF1ZXJ5Jyk7XG5yZXF1aXJlKCdib290c3RyYXAtbGVzcycpO1xuXG4vKipcbiAqIFZ1ZSBpcyBhIG1vZGVybiBKYXZhU2NyaXB0IGxpYnJhcnkgZm9yIGJ1aWxkaW5nIGludGVyYWN0aXZlIHdlYiBpbnRlcmZhY2VzXG4gKiB1c2luZyByZWFjdGl2ZSBkYXRhIGJpbmRpbmcgYW5kIHJldXNhYmxlIGNvbXBvbmVudHMuIFZ1ZSdzIEFQSSBpcyBjbGVhblxuICogYW5kIHNpbXBsZSwgbGVhdmluZyB5b3UgdG8gZm9jdXMgb24gYnVpbGRpbmcgeW91ciBuZXh0IGdyZWF0IHByb2plY3QuXG4gKi9cblxud2luZG93LlZ1ZSA9IHJlcXVpcmUoJ3Z1ZScpO1xud2luZG93LmV2ZW50SHViID0gbmV3IFZ1ZSgpO1xucmVxdWlyZSgndnVlLXJlc291cmNlJyk7XG5cbi8qKlxuICogV2UnbGwgcmVnaXN0ZXIgYSBIVFRQIGludGVyY2VwdG9yIHRvIGF0dGFjaCB0aGUgXCJDU1JGXCIgaGVhZGVyIHRvIGVhY2ggb2ZcbiAqIHRoZSBvdXRnb2luZyByZXF1ZXN0cyBpc3N1ZWQgYnkgdGhpcyBhcHBsaWNhdGlvbi4gVGhlIENTUkYgbWlkZGxld2FyZVxuICogaW5jbHVkZWQgd2l0aCBMYXJhdmVsIHdpbGwgYXV0b21hdGljYWxseSB2ZXJpZnkgdGhlIGhlYWRlcidzIHZhbHVlLlxuICovXG5cblZ1ZS5odHRwLmludGVyY2VwdG9ycy5wdXNoKChyZXF1ZXN0LCBuZXh0KSA9PiB7XG4gICAgcmVxdWVzdC5oZWFkZXJzLnNldCgnWC1DU1JGLVRPS0VOJywgTGFyYXZlbC5jc3JmVG9rZW4pO1xuXG4gICAgbmV4dCgpO1xufSk7XG5cbi8qKlxuICogRWNobyBleHBvc2VzIGFuIGV4cHJlc3NpdmUgQVBJIGZvciBzdWJzY3JpYmluZyB0byBjaGFubmVscyBhbmQgbGlzdGVuaW5nXG4gKiBmb3IgZXZlbnRzIHRoYXQgYXJlIGJyb2FkY2FzdCBieSBMYXJhdmVsLiBFY2hvIGFuZCBldmVudCBicm9hZGNhc3RpbmdcbiAqIGFsbG93cyB5b3VyIHRlYW0gdG8gZWFzaWx5IGJ1aWxkIHJvYnVzdCByZWFsLXRpbWUgd2ViIGFwcGxpY2F0aW9ucy5cbiAqL1xuXG4vLyBpbXBvcnQgRWNobyBmcm9tIFwibGFyYXZlbC1lY2hvXCJcblxuLy8gd2luZG93LkVjaG8gPSBuZXcgRWNobyh7XG4vLyAgICAgYnJvYWRjYXN0ZXI6ICdwdXNoZXInLFxuLy8gICAgIGtleTogJ3lvdXItcHVzaGVyLWtleSdcbi8vIH0pO1xuXG5cblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL3Jlc291cmNlcy9hc3NldHMvanMvYm9vdHN0cmFwLmpzIiwiLyoqXG4gKiBAbGljZW5zZVxuICogTG9kYXNoIDxodHRwczovL2xvZGFzaC5jb20vPlxuICogQ29weXJpZ2h0IEpTIEZvdW5kYXRpb24gYW5kIG90aGVyIGNvbnRyaWJ1dG9ycyA8aHR0cHM6Ly9qcy5mb3VuZGF0aW9uLz5cbiAqIFJlbGVhc2VkIHVuZGVyIE1JVCBsaWNlbnNlIDxodHRwczovL2xvZGFzaC5jb20vbGljZW5zZT5cbiAqIEJhc2VkIG9uIFVuZGVyc2NvcmUuanMgMS44LjMgPGh0dHA6Ly91bmRlcnNjb3JlanMub3JnL0xJQ0VOU0U+XG4gKiBDb3B5cmlnaHQgSmVyZW15IEFzaGtlbmFzLCBEb2N1bWVudENsb3VkIGFuZCBJbnZlc3RpZ2F0aXZlIFJlcG9ydGVycyAmIEVkaXRvcnNcbiAqL1xuOyhmdW5jdGlvbigpIHtcblxuICAvKiogVXNlZCBhcyBhIHNhZmUgcmVmZXJlbmNlIGZvciBgdW5kZWZpbmVkYCBpbiBwcmUtRVM1IGVudmlyb25tZW50cy4gKi9cbiAgdmFyIHVuZGVmaW5lZDtcblxuICAvKiogVXNlZCBhcyB0aGUgc2VtYW50aWMgdmVyc2lvbiBudW1iZXIuICovXG4gIHZhciBWRVJTSU9OID0gJzQuMTcuNCc7XG5cbiAgLyoqIFVzZWQgYXMgdGhlIHNpemUgdG8gZW5hYmxlIGxhcmdlIGFycmF5IG9wdGltaXphdGlvbnMuICovXG4gIHZhciBMQVJHRV9BUlJBWV9TSVpFID0gMjAwO1xuXG4gIC8qKiBFcnJvciBtZXNzYWdlIGNvbnN0YW50cy4gKi9cbiAgdmFyIENPUkVfRVJST1JfVEVYVCA9ICdVbnN1cHBvcnRlZCBjb3JlLWpzIHVzZS4gVHJ5IGh0dHBzOi8vbnBtcy5pby9zZWFyY2g/cT1wb255ZmlsbC4nLFxuICAgICAgRlVOQ19FUlJPUl9URVhUID0gJ0V4cGVjdGVkIGEgZnVuY3Rpb24nO1xuXG4gIC8qKiBVc2VkIHRvIHN0YW5kLWluIGZvciBgdW5kZWZpbmVkYCBoYXNoIHZhbHVlcy4gKi9cbiAgdmFyIEhBU0hfVU5ERUZJTkVEID0gJ19fbG9kYXNoX2hhc2hfdW5kZWZpbmVkX18nO1xuXG4gIC8qKiBVc2VkIGFzIHRoZSBtYXhpbXVtIG1lbW9pemUgY2FjaGUgc2l6ZS4gKi9cbiAgdmFyIE1BWF9NRU1PSVpFX1NJWkUgPSA1MDA7XG5cbiAgLyoqIFVzZWQgYXMgdGhlIGludGVybmFsIGFyZ3VtZW50IHBsYWNlaG9sZGVyLiAqL1xuICB2YXIgUExBQ0VIT0xERVIgPSAnX19sb2Rhc2hfcGxhY2Vob2xkZXJfXyc7XG5cbiAgLyoqIFVzZWQgdG8gY29tcG9zZSBiaXRtYXNrcyBmb3IgY2xvbmluZy4gKi9cbiAgdmFyIENMT05FX0RFRVBfRkxBRyA9IDEsXG4gICAgICBDTE9ORV9GTEFUX0ZMQUcgPSAyLFxuICAgICAgQ0xPTkVfU1lNQk9MU19GTEFHID0gNDtcblxuICAvKiogVXNlZCB0byBjb21wb3NlIGJpdG1hc2tzIGZvciB2YWx1ZSBjb21wYXJpc29ucy4gKi9cbiAgdmFyIENPTVBBUkVfUEFSVElBTF9GTEFHID0gMSxcbiAgICAgIENPTVBBUkVfVU5PUkRFUkVEX0ZMQUcgPSAyO1xuXG4gIC8qKiBVc2VkIHRvIGNvbXBvc2UgYml0bWFza3MgZm9yIGZ1bmN0aW9uIG1ldGFkYXRhLiAqL1xuICB2YXIgV1JBUF9CSU5EX0ZMQUcgPSAxLFxuICAgICAgV1JBUF9CSU5EX0tFWV9GTEFHID0gMixcbiAgICAgIFdSQVBfQ1VSUllfQk9VTkRfRkxBRyA9IDQsXG4gICAgICBXUkFQX0NVUlJZX0ZMQUcgPSA4LFxuICAgICAgV1JBUF9DVVJSWV9SSUdIVF9GTEFHID0gMTYsXG4gICAgICBXUkFQX1BBUlRJQUxfRkxBRyA9IDMyLFxuICAgICAgV1JBUF9QQVJUSUFMX1JJR0hUX0ZMQUcgPSA2NCxcbiAgICAgIFdSQVBfQVJZX0ZMQUcgPSAxMjgsXG4gICAgICBXUkFQX1JFQVJHX0ZMQUcgPSAyNTYsXG4gICAgICBXUkFQX0ZMSVBfRkxBRyA9IDUxMjtcblxuICAvKiogVXNlZCBhcyBkZWZhdWx0IG9wdGlvbnMgZm9yIGBfLnRydW5jYXRlYC4gKi9cbiAgdmFyIERFRkFVTFRfVFJVTkNfTEVOR1RIID0gMzAsXG4gICAgICBERUZBVUxUX1RSVU5DX09NSVNTSU9OID0gJy4uLic7XG5cbiAgLyoqIFVzZWQgdG8gZGV0ZWN0IGhvdCBmdW5jdGlvbnMgYnkgbnVtYmVyIG9mIGNhbGxzIHdpdGhpbiBhIHNwYW4gb2YgbWlsbGlzZWNvbmRzLiAqL1xuICB2YXIgSE9UX0NPVU5UID0gODAwLFxuICAgICAgSE9UX1NQQU4gPSAxNjtcblxuICAvKiogVXNlZCB0byBpbmRpY2F0ZSB0aGUgdHlwZSBvZiBsYXp5IGl0ZXJhdGVlcy4gKi9cbiAgdmFyIExBWllfRklMVEVSX0ZMQUcgPSAxLFxuICAgICAgTEFaWV9NQVBfRkxBRyA9IDIsXG4gICAgICBMQVpZX1dISUxFX0ZMQUcgPSAzO1xuXG4gIC8qKiBVc2VkIGFzIHJlZmVyZW5jZXMgZm9yIHZhcmlvdXMgYE51bWJlcmAgY29uc3RhbnRzLiAqL1xuICB2YXIgSU5GSU5JVFkgPSAxIC8gMCxcbiAgICAgIE1BWF9TQUZFX0lOVEVHRVIgPSA5MDA3MTk5MjU0NzQwOTkxLFxuICAgICAgTUFYX0lOVEVHRVIgPSAxLjc5NzY5MzEzNDg2MjMxNTdlKzMwOCxcbiAgICAgIE5BTiA9IDAgLyAwO1xuXG4gIC8qKiBVc2VkIGFzIHJlZmVyZW5jZXMgZm9yIHRoZSBtYXhpbXVtIGxlbmd0aCBhbmQgaW5kZXggb2YgYW4gYXJyYXkuICovXG4gIHZhciBNQVhfQVJSQVlfTEVOR1RIID0gNDI5NDk2NzI5NSxcbiAgICAgIE1BWF9BUlJBWV9JTkRFWCA9IE1BWF9BUlJBWV9MRU5HVEggLSAxLFxuICAgICAgSEFMRl9NQVhfQVJSQVlfTEVOR1RIID0gTUFYX0FSUkFZX0xFTkdUSCA+Pj4gMTtcblxuICAvKiogVXNlZCB0byBhc3NvY2lhdGUgd3JhcCBtZXRob2RzIHdpdGggdGhlaXIgYml0IGZsYWdzLiAqL1xuICB2YXIgd3JhcEZsYWdzID0gW1xuICAgIFsnYXJ5JywgV1JBUF9BUllfRkxBR10sXG4gICAgWydiaW5kJywgV1JBUF9CSU5EX0ZMQUddLFxuICAgIFsnYmluZEtleScsIFdSQVBfQklORF9LRVlfRkxBR10sXG4gICAgWydjdXJyeScsIFdSQVBfQ1VSUllfRkxBR10sXG4gICAgWydjdXJyeVJpZ2h0JywgV1JBUF9DVVJSWV9SSUdIVF9GTEFHXSxcbiAgICBbJ2ZsaXAnLCBXUkFQX0ZMSVBfRkxBR10sXG4gICAgWydwYXJ0aWFsJywgV1JBUF9QQVJUSUFMX0ZMQUddLFxuICAgIFsncGFydGlhbFJpZ2h0JywgV1JBUF9QQVJUSUFMX1JJR0hUX0ZMQUddLFxuICAgIFsncmVhcmcnLCBXUkFQX1JFQVJHX0ZMQUddXG4gIF07XG5cbiAgLyoqIGBPYmplY3QjdG9TdHJpbmdgIHJlc3VsdCByZWZlcmVuY2VzLiAqL1xuICB2YXIgYXJnc1RhZyA9ICdbb2JqZWN0IEFyZ3VtZW50c10nLFxuICAgICAgYXJyYXlUYWcgPSAnW29iamVjdCBBcnJheV0nLFxuICAgICAgYXN5bmNUYWcgPSAnW29iamVjdCBBc3luY0Z1bmN0aW9uXScsXG4gICAgICBib29sVGFnID0gJ1tvYmplY3QgQm9vbGVhbl0nLFxuICAgICAgZGF0ZVRhZyA9ICdbb2JqZWN0IERhdGVdJyxcbiAgICAgIGRvbUV4Y1RhZyA9ICdbb2JqZWN0IERPTUV4Y2VwdGlvbl0nLFxuICAgICAgZXJyb3JUYWcgPSAnW29iamVjdCBFcnJvcl0nLFxuICAgICAgZnVuY1RhZyA9ICdbb2JqZWN0IEZ1bmN0aW9uXScsXG4gICAgICBnZW5UYWcgPSAnW29iamVjdCBHZW5lcmF0b3JGdW5jdGlvbl0nLFxuICAgICAgbWFwVGFnID0gJ1tvYmplY3QgTWFwXScsXG4gICAgICBudW1iZXJUYWcgPSAnW29iamVjdCBOdW1iZXJdJyxcbiAgICAgIG51bGxUYWcgPSAnW29iamVjdCBOdWxsXScsXG4gICAgICBvYmplY3RUYWcgPSAnW29iamVjdCBPYmplY3RdJyxcbiAgICAgIHByb21pc2VUYWcgPSAnW29iamVjdCBQcm9taXNlXScsXG4gICAgICBwcm94eVRhZyA9ICdbb2JqZWN0IFByb3h5XScsXG4gICAgICByZWdleHBUYWcgPSAnW29iamVjdCBSZWdFeHBdJyxcbiAgICAgIHNldFRhZyA9ICdbb2JqZWN0IFNldF0nLFxuICAgICAgc3RyaW5nVGFnID0gJ1tvYmplY3QgU3RyaW5nXScsXG4gICAgICBzeW1ib2xUYWcgPSAnW29iamVjdCBTeW1ib2xdJyxcbiAgICAgIHVuZGVmaW5lZFRhZyA9ICdbb2JqZWN0IFVuZGVmaW5lZF0nLFxuICAgICAgd2Vha01hcFRhZyA9ICdbb2JqZWN0IFdlYWtNYXBdJyxcbiAgICAgIHdlYWtTZXRUYWcgPSAnW29iamVjdCBXZWFrU2V0XSc7XG5cbiAgdmFyIGFycmF5QnVmZmVyVGFnID0gJ1tvYmplY3QgQXJyYXlCdWZmZXJdJyxcbiAgICAgIGRhdGFWaWV3VGFnID0gJ1tvYmplY3QgRGF0YVZpZXddJyxcbiAgICAgIGZsb2F0MzJUYWcgPSAnW29iamVjdCBGbG9hdDMyQXJyYXldJyxcbiAgICAgIGZsb2F0NjRUYWcgPSAnW29iamVjdCBGbG9hdDY0QXJyYXldJyxcbiAgICAgIGludDhUYWcgPSAnW29iamVjdCBJbnQ4QXJyYXldJyxcbiAgICAgIGludDE2VGFnID0gJ1tvYmplY3QgSW50MTZBcnJheV0nLFxuICAgICAgaW50MzJUYWcgPSAnW29iamVjdCBJbnQzMkFycmF5XScsXG4gICAgICB1aW50OFRhZyA9ICdbb2JqZWN0IFVpbnQ4QXJyYXldJyxcbiAgICAgIHVpbnQ4Q2xhbXBlZFRhZyA9ICdbb2JqZWN0IFVpbnQ4Q2xhbXBlZEFycmF5XScsXG4gICAgICB1aW50MTZUYWcgPSAnW29iamVjdCBVaW50MTZBcnJheV0nLFxuICAgICAgdWludDMyVGFnID0gJ1tvYmplY3QgVWludDMyQXJyYXldJztcblxuICAvKiogVXNlZCB0byBtYXRjaCBlbXB0eSBzdHJpbmcgbGl0ZXJhbHMgaW4gY29tcGlsZWQgdGVtcGxhdGUgc291cmNlLiAqL1xuICB2YXIgcmVFbXB0eVN0cmluZ0xlYWRpbmcgPSAvXFxiX19wIFxcKz0gJyc7L2csXG4gICAgICByZUVtcHR5U3RyaW5nTWlkZGxlID0gL1xcYihfX3AgXFwrPSkgJycgXFwrL2csXG4gICAgICByZUVtcHR5U3RyaW5nVHJhaWxpbmcgPSAvKF9fZVxcKC4qP1xcKXxcXGJfX3RcXCkpIFxcK1xcbicnOy9nO1xuXG4gIC8qKiBVc2VkIHRvIG1hdGNoIEhUTUwgZW50aXRpZXMgYW5kIEhUTUwgY2hhcmFjdGVycy4gKi9cbiAgdmFyIHJlRXNjYXBlZEh0bWwgPSAvJig/OmFtcHxsdHxndHxxdW90fCMzOSk7L2csXG4gICAgICByZVVuZXNjYXBlZEh0bWwgPSAvWyY8PlwiJ10vZyxcbiAgICAgIHJlSGFzRXNjYXBlZEh0bWwgPSBSZWdFeHAocmVFc2NhcGVkSHRtbC5zb3VyY2UpLFxuICAgICAgcmVIYXNVbmVzY2FwZWRIdG1sID0gUmVnRXhwKHJlVW5lc2NhcGVkSHRtbC5zb3VyY2UpO1xuXG4gIC8qKiBVc2VkIHRvIG1hdGNoIHRlbXBsYXRlIGRlbGltaXRlcnMuICovXG4gIHZhciByZUVzY2FwZSA9IC88JS0oW1xcc1xcU10rPyklPi9nLFxuICAgICAgcmVFdmFsdWF0ZSA9IC88JShbXFxzXFxTXSs/KSU+L2csXG4gICAgICByZUludGVycG9sYXRlID0gLzwlPShbXFxzXFxTXSs/KSU+L2c7XG5cbiAgLyoqIFVzZWQgdG8gbWF0Y2ggcHJvcGVydHkgbmFtZXMgd2l0aGluIHByb3BlcnR5IHBhdGhzLiAqL1xuICB2YXIgcmVJc0RlZXBQcm9wID0gL1xcLnxcXFsoPzpbXltcXF1dKnwoW1wiJ10pKD86KD8hXFwxKVteXFxcXF18XFxcXC4pKj9cXDEpXFxdLyxcbiAgICAgIHJlSXNQbGFpblByb3AgPSAvXlxcdyokLyxcbiAgICAgIHJlTGVhZGluZ0RvdCA9IC9eXFwuLyxcbiAgICAgIHJlUHJvcE5hbWUgPSAvW14uW1xcXV0rfFxcWyg/OigtP1xcZCsoPzpcXC5cXGQrKT8pfChbXCInXSkoKD86KD8hXFwyKVteXFxcXF18XFxcXC4pKj8pXFwyKVxcXXwoPz0oPzpcXC58XFxbXFxdKSg/OlxcLnxcXFtcXF18JCkpL2c7XG5cbiAgLyoqXG4gICAqIFVzZWQgdG8gbWF0Y2ggYFJlZ0V4cGBcbiAgICogW3N5bnRheCBjaGFyYWN0ZXJzXShodHRwOi8vZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi83LjAvI3NlYy1wYXR0ZXJucykuXG4gICAqL1xuICB2YXIgcmVSZWdFeHBDaGFyID0gL1tcXFxcXiQuKis/KClbXFxde318XS9nLFxuICAgICAgcmVIYXNSZWdFeHBDaGFyID0gUmVnRXhwKHJlUmVnRXhwQ2hhci5zb3VyY2UpO1xuXG4gIC8qKiBVc2VkIHRvIG1hdGNoIGxlYWRpbmcgYW5kIHRyYWlsaW5nIHdoaXRlc3BhY2UuICovXG4gIHZhciByZVRyaW0gPSAvXlxccyt8XFxzKyQvZyxcbiAgICAgIHJlVHJpbVN0YXJ0ID0gL15cXHMrLyxcbiAgICAgIHJlVHJpbUVuZCA9IC9cXHMrJC87XG5cbiAgLyoqIFVzZWQgdG8gbWF0Y2ggd3JhcCBkZXRhaWwgY29tbWVudHMuICovXG4gIHZhciByZVdyYXBDb21tZW50ID0gL1xceyg/OlxcblxcL1xcKiBcXFt3cmFwcGVkIHdpdGggLitcXF0gXFwqXFwvKT9cXG4/LyxcbiAgICAgIHJlV3JhcERldGFpbHMgPSAvXFx7XFxuXFwvXFwqIFxcW3dyYXBwZWQgd2l0aCAoLispXFxdIFxcKi8sXG4gICAgICByZVNwbGl0RGV0YWlscyA9IC8sPyAmIC87XG5cbiAgLyoqIFVzZWQgdG8gbWF0Y2ggd29yZHMgY29tcG9zZWQgb2YgYWxwaGFudW1lcmljIGNoYXJhY3RlcnMuICovXG4gIHZhciByZUFzY2lpV29yZCA9IC9bXlxceDAwLVxceDJmXFx4M2EtXFx4NDBcXHg1Yi1cXHg2MFxceDdiLVxceDdmXSsvZztcblxuICAvKiogVXNlZCB0byBtYXRjaCBiYWNrc2xhc2hlcyBpbiBwcm9wZXJ0eSBwYXRocy4gKi9cbiAgdmFyIHJlRXNjYXBlQ2hhciA9IC9cXFxcKFxcXFwpPy9nO1xuXG4gIC8qKlxuICAgKiBVc2VkIHRvIG1hdGNoXG4gICAqIFtFUyB0ZW1wbGF0ZSBkZWxpbWl0ZXJzXShodHRwOi8vZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi83LjAvI3NlYy10ZW1wbGF0ZS1saXRlcmFsLWxleGljYWwtY29tcG9uZW50cykuXG4gICAqL1xuICB2YXIgcmVFc1RlbXBsYXRlID0gL1xcJFxceyhbXlxcXFx9XSooPzpcXFxcLlteXFxcXH1dKikqKVxcfS9nO1xuXG4gIC8qKiBVc2VkIHRvIG1hdGNoIGBSZWdFeHBgIGZsYWdzIGZyb20gdGhlaXIgY29lcmNlZCBzdHJpbmcgdmFsdWVzLiAqL1xuICB2YXIgcmVGbGFncyA9IC9cXHcqJC87XG5cbiAgLyoqIFVzZWQgdG8gZGV0ZWN0IGJhZCBzaWduZWQgaGV4YWRlY2ltYWwgc3RyaW5nIHZhbHVlcy4gKi9cbiAgdmFyIHJlSXNCYWRIZXggPSAvXlstK10weFswLTlhLWZdKyQvaTtcblxuICAvKiogVXNlZCB0byBkZXRlY3QgYmluYXJ5IHN0cmluZyB2YWx1ZXMuICovXG4gIHZhciByZUlzQmluYXJ5ID0gL14wYlswMV0rJC9pO1xuXG4gIC8qKiBVc2VkIHRvIGRldGVjdCBob3N0IGNvbnN0cnVjdG9ycyAoU2FmYXJpKS4gKi9cbiAgdmFyIHJlSXNIb3N0Q3RvciA9IC9eXFxbb2JqZWN0IC4rP0NvbnN0cnVjdG9yXFxdJC87XG5cbiAgLyoqIFVzZWQgdG8gZGV0ZWN0IG9jdGFsIHN0cmluZyB2YWx1ZXMuICovXG4gIHZhciByZUlzT2N0YWwgPSAvXjBvWzAtN10rJC9pO1xuXG4gIC8qKiBVc2VkIHRvIGRldGVjdCB1bnNpZ25lZCBpbnRlZ2VyIHZhbHVlcy4gKi9cbiAgdmFyIHJlSXNVaW50ID0gL14oPzowfFsxLTldXFxkKikkLztcblxuICAvKiogVXNlZCB0byBtYXRjaCBMYXRpbiBVbmljb2RlIGxldHRlcnMgKGV4Y2x1ZGluZyBtYXRoZW1hdGljYWwgb3BlcmF0b3JzKS4gKi9cbiAgdmFyIHJlTGF0aW4gPSAvW1xceGMwLVxceGQ2XFx4ZDgtXFx4ZjZcXHhmOC1cXHhmZlxcdTAxMDAtXFx1MDE3Zl0vZztcblxuICAvKiogVXNlZCB0byBlbnN1cmUgY2FwdHVyaW5nIG9yZGVyIG9mIHRlbXBsYXRlIGRlbGltaXRlcnMuICovXG4gIHZhciByZU5vTWF0Y2ggPSAvKCReKS87XG5cbiAgLyoqIFVzZWQgdG8gbWF0Y2ggdW5lc2NhcGVkIGNoYXJhY3RlcnMgaW4gY29tcGlsZWQgc3RyaW5nIGxpdGVyYWxzLiAqL1xuICB2YXIgcmVVbmVzY2FwZWRTdHJpbmcgPSAvWydcXG5cXHJcXHUyMDI4XFx1MjAyOVxcXFxdL2c7XG5cbiAgLyoqIFVzZWQgdG8gY29tcG9zZSB1bmljb2RlIGNoYXJhY3RlciBjbGFzc2VzLiAqL1xuICB2YXIgcnNBc3RyYWxSYW5nZSA9ICdcXFxcdWQ4MDAtXFxcXHVkZmZmJyxcbiAgICAgIHJzQ29tYm9NYXJrc1JhbmdlID0gJ1xcXFx1MDMwMC1cXFxcdTAzNmYnLFxuICAgICAgcmVDb21ib0hhbGZNYXJrc1JhbmdlID0gJ1xcXFx1ZmUyMC1cXFxcdWZlMmYnLFxuICAgICAgcnNDb21ib1N5bWJvbHNSYW5nZSA9ICdcXFxcdTIwZDAtXFxcXHUyMGZmJyxcbiAgICAgIHJzQ29tYm9SYW5nZSA9IHJzQ29tYm9NYXJrc1JhbmdlICsgcmVDb21ib0hhbGZNYXJrc1JhbmdlICsgcnNDb21ib1N5bWJvbHNSYW5nZSxcbiAgICAgIHJzRGluZ2JhdFJhbmdlID0gJ1xcXFx1MjcwMC1cXFxcdTI3YmYnLFxuICAgICAgcnNMb3dlclJhbmdlID0gJ2EtelxcXFx4ZGYtXFxcXHhmNlxcXFx4ZjgtXFxcXHhmZicsXG4gICAgICByc01hdGhPcFJhbmdlID0gJ1xcXFx4YWNcXFxceGIxXFxcXHhkN1xcXFx4ZjcnLFxuICAgICAgcnNOb25DaGFyUmFuZ2UgPSAnXFxcXHgwMC1cXFxceDJmXFxcXHgzYS1cXFxceDQwXFxcXHg1Yi1cXFxceDYwXFxcXHg3Yi1cXFxceGJmJyxcbiAgICAgIHJzUHVuY3R1YXRpb25SYW5nZSA9ICdcXFxcdTIwMDAtXFxcXHUyMDZmJyxcbiAgICAgIHJzU3BhY2VSYW5nZSA9ICcgXFxcXHRcXFxceDBiXFxcXGZcXFxceGEwXFxcXHVmZWZmXFxcXG5cXFxcclxcXFx1MjAyOFxcXFx1MjAyOVxcXFx1MTY4MFxcXFx1MTgwZVxcXFx1MjAwMFxcXFx1MjAwMVxcXFx1MjAwMlxcXFx1MjAwM1xcXFx1MjAwNFxcXFx1MjAwNVxcXFx1MjAwNlxcXFx1MjAwN1xcXFx1MjAwOFxcXFx1MjAwOVxcXFx1MjAwYVxcXFx1MjAyZlxcXFx1MjA1ZlxcXFx1MzAwMCcsXG4gICAgICByc1VwcGVyUmFuZ2UgPSAnQS1aXFxcXHhjMC1cXFxceGQ2XFxcXHhkOC1cXFxceGRlJyxcbiAgICAgIHJzVmFyUmFuZ2UgPSAnXFxcXHVmZTBlXFxcXHVmZTBmJyxcbiAgICAgIHJzQnJlYWtSYW5nZSA9IHJzTWF0aE9wUmFuZ2UgKyByc05vbkNoYXJSYW5nZSArIHJzUHVuY3R1YXRpb25SYW5nZSArIHJzU3BhY2VSYW5nZTtcblxuICAvKiogVXNlZCB0byBjb21wb3NlIHVuaWNvZGUgY2FwdHVyZSBncm91cHMuICovXG4gIHZhciByc0Fwb3MgPSBcIlsnXFx1MjAxOV1cIixcbiAgICAgIHJzQXN0cmFsID0gJ1snICsgcnNBc3RyYWxSYW5nZSArICddJyxcbiAgICAgIHJzQnJlYWsgPSAnWycgKyByc0JyZWFrUmFuZ2UgKyAnXScsXG4gICAgICByc0NvbWJvID0gJ1snICsgcnNDb21ib1JhbmdlICsgJ10nLFxuICAgICAgcnNEaWdpdHMgPSAnXFxcXGQrJyxcbiAgICAgIHJzRGluZ2JhdCA9ICdbJyArIHJzRGluZ2JhdFJhbmdlICsgJ10nLFxuICAgICAgcnNMb3dlciA9ICdbJyArIHJzTG93ZXJSYW5nZSArICddJyxcbiAgICAgIHJzTWlzYyA9ICdbXicgKyByc0FzdHJhbFJhbmdlICsgcnNCcmVha1JhbmdlICsgcnNEaWdpdHMgKyByc0RpbmdiYXRSYW5nZSArIHJzTG93ZXJSYW5nZSArIHJzVXBwZXJSYW5nZSArICddJyxcbiAgICAgIHJzRml0eiA9ICdcXFxcdWQ4M2NbXFxcXHVkZmZiLVxcXFx1ZGZmZl0nLFxuICAgICAgcnNNb2RpZmllciA9ICcoPzonICsgcnNDb21ibyArICd8JyArIHJzRml0eiArICcpJyxcbiAgICAgIHJzTm9uQXN0cmFsID0gJ1teJyArIHJzQXN0cmFsUmFuZ2UgKyAnXScsXG4gICAgICByc1JlZ2lvbmFsID0gJyg/OlxcXFx1ZDgzY1tcXFxcdWRkZTYtXFxcXHVkZGZmXSl7Mn0nLFxuICAgICAgcnNTdXJyUGFpciA9ICdbXFxcXHVkODAwLVxcXFx1ZGJmZl1bXFxcXHVkYzAwLVxcXFx1ZGZmZl0nLFxuICAgICAgcnNVcHBlciA9ICdbJyArIHJzVXBwZXJSYW5nZSArICddJyxcbiAgICAgIHJzWldKID0gJ1xcXFx1MjAwZCc7XG5cbiAgLyoqIFVzZWQgdG8gY29tcG9zZSB1bmljb2RlIHJlZ2V4ZXMuICovXG4gIHZhciByc01pc2NMb3dlciA9ICcoPzonICsgcnNMb3dlciArICd8JyArIHJzTWlzYyArICcpJyxcbiAgICAgIHJzTWlzY1VwcGVyID0gJyg/OicgKyByc1VwcGVyICsgJ3wnICsgcnNNaXNjICsgJyknLFxuICAgICAgcnNPcHRDb250ckxvd2VyID0gJyg/OicgKyByc0Fwb3MgKyAnKD86ZHxsbHxtfHJlfHN8dHx2ZSkpPycsXG4gICAgICByc09wdENvbnRyVXBwZXIgPSAnKD86JyArIHJzQXBvcyArICcoPzpEfExMfE18UkV8U3xUfFZFKSk/JyxcbiAgICAgIHJlT3B0TW9kID0gcnNNb2RpZmllciArICc/JyxcbiAgICAgIHJzT3B0VmFyID0gJ1snICsgcnNWYXJSYW5nZSArICddPycsXG4gICAgICByc09wdEpvaW4gPSAnKD86JyArIHJzWldKICsgJyg/OicgKyBbcnNOb25Bc3RyYWwsIHJzUmVnaW9uYWwsIHJzU3VyclBhaXJdLmpvaW4oJ3wnKSArICcpJyArIHJzT3B0VmFyICsgcmVPcHRNb2QgKyAnKSonLFxuICAgICAgcnNPcmRMb3dlciA9ICdcXFxcZCooPzooPzoxc3R8Mm5kfDNyZHwoPyFbMTIzXSlcXFxcZHRoKVxcXFxiKScsXG4gICAgICByc09yZFVwcGVyID0gJ1xcXFxkKig/Oig/OjFTVHwyTkR8M1JEfCg/IVsxMjNdKVxcXFxkVEgpXFxcXGIpJyxcbiAgICAgIHJzU2VxID0gcnNPcHRWYXIgKyByZU9wdE1vZCArIHJzT3B0Sm9pbixcbiAgICAgIHJzRW1vamkgPSAnKD86JyArIFtyc0RpbmdiYXQsIHJzUmVnaW9uYWwsIHJzU3VyclBhaXJdLmpvaW4oJ3wnKSArICcpJyArIHJzU2VxLFxuICAgICAgcnNTeW1ib2wgPSAnKD86JyArIFtyc05vbkFzdHJhbCArIHJzQ29tYm8gKyAnPycsIHJzQ29tYm8sIHJzUmVnaW9uYWwsIHJzU3VyclBhaXIsIHJzQXN0cmFsXS5qb2luKCd8JykgKyAnKSc7XG5cbiAgLyoqIFVzZWQgdG8gbWF0Y2ggYXBvc3Ryb3BoZXMuICovXG4gIHZhciByZUFwb3MgPSBSZWdFeHAocnNBcG9zLCAnZycpO1xuXG4gIC8qKlxuICAgKiBVc2VkIHRvIG1hdGNoIFtjb21iaW5pbmcgZGlhY3JpdGljYWwgbWFya3NdKGh0dHBzOi8vZW4ud2lraXBlZGlhLm9yZy93aWtpL0NvbWJpbmluZ19EaWFjcml0aWNhbF9NYXJrcykgYW5kXG4gICAqIFtjb21iaW5pbmcgZGlhY3JpdGljYWwgbWFya3MgZm9yIHN5bWJvbHNdKGh0dHBzOi8vZW4ud2lraXBlZGlhLm9yZy93aWtpL0NvbWJpbmluZ19EaWFjcml0aWNhbF9NYXJrc19mb3JfU3ltYm9scykuXG4gICAqL1xuICB2YXIgcmVDb21ib01hcmsgPSBSZWdFeHAocnNDb21ibywgJ2cnKTtcblxuICAvKiogVXNlZCB0byBtYXRjaCBbc3RyaW5nIHN5bWJvbHNdKGh0dHBzOi8vbWF0aGlhc2J5bmVucy5iZS9ub3Rlcy9qYXZhc2NyaXB0LXVuaWNvZGUpLiAqL1xuICB2YXIgcmVVbmljb2RlID0gUmVnRXhwKHJzRml0eiArICcoPz0nICsgcnNGaXR6ICsgJyl8JyArIHJzU3ltYm9sICsgcnNTZXEsICdnJyk7XG5cbiAgLyoqIFVzZWQgdG8gbWF0Y2ggY29tcGxleCBvciBjb21wb3VuZCB3b3Jkcy4gKi9cbiAgdmFyIHJlVW5pY29kZVdvcmQgPSBSZWdFeHAoW1xuICAgIHJzVXBwZXIgKyAnPycgKyByc0xvd2VyICsgJysnICsgcnNPcHRDb250ckxvd2VyICsgJyg/PScgKyBbcnNCcmVhaywgcnNVcHBlciwgJyQnXS5qb2luKCd8JykgKyAnKScsXG4gICAgcnNNaXNjVXBwZXIgKyAnKycgKyByc09wdENvbnRyVXBwZXIgKyAnKD89JyArIFtyc0JyZWFrLCByc1VwcGVyICsgcnNNaXNjTG93ZXIsICckJ10uam9pbignfCcpICsgJyknLFxuICAgIHJzVXBwZXIgKyAnPycgKyByc01pc2NMb3dlciArICcrJyArIHJzT3B0Q29udHJMb3dlcixcbiAgICByc1VwcGVyICsgJysnICsgcnNPcHRDb250clVwcGVyLFxuICAgIHJzT3JkVXBwZXIsXG4gICAgcnNPcmRMb3dlcixcbiAgICByc0RpZ2l0cyxcbiAgICByc0Vtb2ppXG4gIF0uam9pbignfCcpLCAnZycpO1xuXG4gIC8qKiBVc2VkIHRvIGRldGVjdCBzdHJpbmdzIHdpdGggW3plcm8td2lkdGggam9pbmVycyBvciBjb2RlIHBvaW50cyBmcm9tIHRoZSBhc3RyYWwgcGxhbmVzXShodHRwOi8vZWV2LmVlL2Jsb2cvMjAxNS8wOS8xMi9kYXJrLWNvcm5lcnMtb2YtdW5pY29kZS8pLiAqL1xuICB2YXIgcmVIYXNVbmljb2RlID0gUmVnRXhwKCdbJyArIHJzWldKICsgcnNBc3RyYWxSYW5nZSAgKyByc0NvbWJvUmFuZ2UgKyByc1ZhclJhbmdlICsgJ10nKTtcblxuICAvKiogVXNlZCB0byBkZXRlY3Qgc3RyaW5ncyB0aGF0IG5lZWQgYSBtb3JlIHJvYnVzdCByZWdleHAgdG8gbWF0Y2ggd29yZHMuICovXG4gIHZhciByZUhhc1VuaWNvZGVXb3JkID0gL1thLXpdW0EtWl18W0EtWl17Mix9W2Etel18WzAtOV1bYS16QS1aXXxbYS16QS1aXVswLTldfFteYS16QS1aMC05IF0vO1xuXG4gIC8qKiBVc2VkIHRvIGFzc2lnbiBkZWZhdWx0IGBjb250ZXh0YCBvYmplY3QgcHJvcGVydGllcy4gKi9cbiAgdmFyIGNvbnRleHRQcm9wcyA9IFtcbiAgICAnQXJyYXknLCAnQnVmZmVyJywgJ0RhdGFWaWV3JywgJ0RhdGUnLCAnRXJyb3InLCAnRmxvYXQzMkFycmF5JywgJ0Zsb2F0NjRBcnJheScsXG4gICAgJ0Z1bmN0aW9uJywgJ0ludDhBcnJheScsICdJbnQxNkFycmF5JywgJ0ludDMyQXJyYXknLCAnTWFwJywgJ01hdGgnLCAnT2JqZWN0JyxcbiAgICAnUHJvbWlzZScsICdSZWdFeHAnLCAnU2V0JywgJ1N0cmluZycsICdTeW1ib2wnLCAnVHlwZUVycm9yJywgJ1VpbnQ4QXJyYXknLFxuICAgICdVaW50OENsYW1wZWRBcnJheScsICdVaW50MTZBcnJheScsICdVaW50MzJBcnJheScsICdXZWFrTWFwJyxcbiAgICAnXycsICdjbGVhclRpbWVvdXQnLCAnaXNGaW5pdGUnLCAncGFyc2VJbnQnLCAnc2V0VGltZW91dCdcbiAgXTtcblxuICAvKiogVXNlZCB0byBtYWtlIHRlbXBsYXRlIHNvdXJjZVVSTHMgZWFzaWVyIHRvIGlkZW50aWZ5LiAqL1xuICB2YXIgdGVtcGxhdGVDb3VudGVyID0gLTE7XG5cbiAgLyoqIFVzZWQgdG8gaWRlbnRpZnkgYHRvU3RyaW5nVGFnYCB2YWx1ZXMgb2YgdHlwZWQgYXJyYXlzLiAqL1xuICB2YXIgdHlwZWRBcnJheVRhZ3MgPSB7fTtcbiAgdHlwZWRBcnJheVRhZ3NbZmxvYXQzMlRhZ10gPSB0eXBlZEFycmF5VGFnc1tmbG9hdDY0VGFnXSA9XG4gIHR5cGVkQXJyYXlUYWdzW2ludDhUYWddID0gdHlwZWRBcnJheVRhZ3NbaW50MTZUYWddID1cbiAgdHlwZWRBcnJheVRhZ3NbaW50MzJUYWddID0gdHlwZWRBcnJheVRhZ3NbdWludDhUYWddID1cbiAgdHlwZWRBcnJheVRhZ3NbdWludDhDbGFtcGVkVGFnXSA9IHR5cGVkQXJyYXlUYWdzW3VpbnQxNlRhZ10gPVxuICB0eXBlZEFycmF5VGFnc1t1aW50MzJUYWddID0gdHJ1ZTtcbiAgdHlwZWRBcnJheVRhZ3NbYXJnc1RhZ10gPSB0eXBlZEFycmF5VGFnc1thcnJheVRhZ10gPVxuICB0eXBlZEFycmF5VGFnc1thcnJheUJ1ZmZlclRhZ10gPSB0eXBlZEFycmF5VGFnc1tib29sVGFnXSA9XG4gIHR5cGVkQXJyYXlUYWdzW2RhdGFWaWV3VGFnXSA9IHR5cGVkQXJyYXlUYWdzW2RhdGVUYWddID1cbiAgdHlwZWRBcnJheVRhZ3NbZXJyb3JUYWddID0gdHlwZWRBcnJheVRhZ3NbZnVuY1RhZ10gPVxuICB0eXBlZEFycmF5VGFnc1ttYXBUYWddID0gdHlwZWRBcnJheVRhZ3NbbnVtYmVyVGFnXSA9XG4gIHR5cGVkQXJyYXlUYWdzW29iamVjdFRhZ10gPSB0eXBlZEFycmF5VGFnc1tyZWdleHBUYWddID1cbiAgdHlwZWRBcnJheVRhZ3Nbc2V0VGFnXSA9IHR5cGVkQXJyYXlUYWdzW3N0cmluZ1RhZ10gPVxuICB0eXBlZEFycmF5VGFnc1t3ZWFrTWFwVGFnXSA9IGZhbHNlO1xuXG4gIC8qKiBVc2VkIHRvIGlkZW50aWZ5IGB0b1N0cmluZ1RhZ2AgdmFsdWVzIHN1cHBvcnRlZCBieSBgXy5jbG9uZWAuICovXG4gIHZhciBjbG9uZWFibGVUYWdzID0ge307XG4gIGNsb25lYWJsZVRhZ3NbYXJnc1RhZ10gPSBjbG9uZWFibGVUYWdzW2FycmF5VGFnXSA9XG4gIGNsb25lYWJsZVRhZ3NbYXJyYXlCdWZmZXJUYWddID0gY2xvbmVhYmxlVGFnc1tkYXRhVmlld1RhZ10gPVxuICBjbG9uZWFibGVUYWdzW2Jvb2xUYWddID0gY2xvbmVhYmxlVGFnc1tkYXRlVGFnXSA9XG4gIGNsb25lYWJsZVRhZ3NbZmxvYXQzMlRhZ10gPSBjbG9uZWFibGVUYWdzW2Zsb2F0NjRUYWddID1cbiAgY2xvbmVhYmxlVGFnc1tpbnQ4VGFnXSA9IGNsb25lYWJsZVRhZ3NbaW50MTZUYWddID1cbiAgY2xvbmVhYmxlVGFnc1tpbnQzMlRhZ10gPSBjbG9uZWFibGVUYWdzW21hcFRhZ10gPVxuICBjbG9uZWFibGVUYWdzW251bWJlclRhZ10gPSBjbG9uZWFibGVUYWdzW29iamVjdFRhZ10gPVxuICBjbG9uZWFibGVUYWdzW3JlZ2V4cFRhZ10gPSBjbG9uZWFibGVUYWdzW3NldFRhZ10gPVxuICBjbG9uZWFibGVUYWdzW3N0cmluZ1RhZ10gPSBjbG9uZWFibGVUYWdzW3N5bWJvbFRhZ10gPVxuICBjbG9uZWFibGVUYWdzW3VpbnQ4VGFnXSA9IGNsb25lYWJsZVRhZ3NbdWludDhDbGFtcGVkVGFnXSA9XG4gIGNsb25lYWJsZVRhZ3NbdWludDE2VGFnXSA9IGNsb25lYWJsZVRhZ3NbdWludDMyVGFnXSA9IHRydWU7XG4gIGNsb25lYWJsZVRhZ3NbZXJyb3JUYWddID0gY2xvbmVhYmxlVGFnc1tmdW5jVGFnXSA9XG4gIGNsb25lYWJsZVRhZ3Nbd2Vha01hcFRhZ10gPSBmYWxzZTtcblxuICAvKiogVXNlZCB0byBtYXAgTGF0aW4gVW5pY29kZSBsZXR0ZXJzIHRvIGJhc2ljIExhdGluIGxldHRlcnMuICovXG4gIHZhciBkZWJ1cnJlZExldHRlcnMgPSB7XG4gICAgLy8gTGF0aW4tMSBTdXBwbGVtZW50IGJsb2NrLlxuICAgICdcXHhjMCc6ICdBJywgICdcXHhjMSc6ICdBJywgJ1xceGMyJzogJ0EnLCAnXFx4YzMnOiAnQScsICdcXHhjNCc6ICdBJywgJ1xceGM1JzogJ0EnLFxuICAgICdcXHhlMCc6ICdhJywgICdcXHhlMSc6ICdhJywgJ1xceGUyJzogJ2EnLCAnXFx4ZTMnOiAnYScsICdcXHhlNCc6ICdhJywgJ1xceGU1JzogJ2EnLFxuICAgICdcXHhjNyc6ICdDJywgICdcXHhlNyc6ICdjJyxcbiAgICAnXFx4ZDAnOiAnRCcsICAnXFx4ZjAnOiAnZCcsXG4gICAgJ1xceGM4JzogJ0UnLCAgJ1xceGM5JzogJ0UnLCAnXFx4Y2EnOiAnRScsICdcXHhjYic6ICdFJyxcbiAgICAnXFx4ZTgnOiAnZScsICAnXFx4ZTknOiAnZScsICdcXHhlYSc6ICdlJywgJ1xceGViJzogJ2UnLFxuICAgICdcXHhjYyc6ICdJJywgICdcXHhjZCc6ICdJJywgJ1xceGNlJzogJ0knLCAnXFx4Y2YnOiAnSScsXG4gICAgJ1xceGVjJzogJ2knLCAgJ1xceGVkJzogJ2knLCAnXFx4ZWUnOiAnaScsICdcXHhlZic6ICdpJyxcbiAgICAnXFx4ZDEnOiAnTicsICAnXFx4ZjEnOiAnbicsXG4gICAgJ1xceGQyJzogJ08nLCAgJ1xceGQzJzogJ08nLCAnXFx4ZDQnOiAnTycsICdcXHhkNSc6ICdPJywgJ1xceGQ2JzogJ08nLCAnXFx4ZDgnOiAnTycsXG4gICAgJ1xceGYyJzogJ28nLCAgJ1xceGYzJzogJ28nLCAnXFx4ZjQnOiAnbycsICdcXHhmNSc6ICdvJywgJ1xceGY2JzogJ28nLCAnXFx4ZjgnOiAnbycsXG4gICAgJ1xceGQ5JzogJ1UnLCAgJ1xceGRhJzogJ1UnLCAnXFx4ZGInOiAnVScsICdcXHhkYyc6ICdVJyxcbiAgICAnXFx4ZjknOiAndScsICAnXFx4ZmEnOiAndScsICdcXHhmYic6ICd1JywgJ1xceGZjJzogJ3UnLFxuICAgICdcXHhkZCc6ICdZJywgICdcXHhmZCc6ICd5JywgJ1xceGZmJzogJ3knLFxuICAgICdcXHhjNic6ICdBZScsICdcXHhlNic6ICdhZScsXG4gICAgJ1xceGRlJzogJ1RoJywgJ1xceGZlJzogJ3RoJyxcbiAgICAnXFx4ZGYnOiAnc3MnLFxuICAgIC8vIExhdGluIEV4dGVuZGVkLUEgYmxvY2suXG4gICAgJ1xcdTAxMDAnOiAnQScsICAnXFx1MDEwMic6ICdBJywgJ1xcdTAxMDQnOiAnQScsXG4gICAgJ1xcdTAxMDEnOiAnYScsICAnXFx1MDEwMyc6ICdhJywgJ1xcdTAxMDUnOiAnYScsXG4gICAgJ1xcdTAxMDYnOiAnQycsICAnXFx1MDEwOCc6ICdDJywgJ1xcdTAxMGEnOiAnQycsICdcXHUwMTBjJzogJ0MnLFxuICAgICdcXHUwMTA3JzogJ2MnLCAgJ1xcdTAxMDknOiAnYycsICdcXHUwMTBiJzogJ2MnLCAnXFx1MDEwZCc6ICdjJyxcbiAgICAnXFx1MDEwZSc6ICdEJywgICdcXHUwMTEwJzogJ0QnLCAnXFx1MDEwZic6ICdkJywgJ1xcdTAxMTEnOiAnZCcsXG4gICAgJ1xcdTAxMTInOiAnRScsICAnXFx1MDExNCc6ICdFJywgJ1xcdTAxMTYnOiAnRScsICdcXHUwMTE4JzogJ0UnLCAnXFx1MDExYSc6ICdFJyxcbiAgICAnXFx1MDExMyc6ICdlJywgICdcXHUwMTE1JzogJ2UnLCAnXFx1MDExNyc6ICdlJywgJ1xcdTAxMTknOiAnZScsICdcXHUwMTFiJzogJ2UnLFxuICAgICdcXHUwMTFjJzogJ0cnLCAgJ1xcdTAxMWUnOiAnRycsICdcXHUwMTIwJzogJ0cnLCAnXFx1MDEyMic6ICdHJyxcbiAgICAnXFx1MDExZCc6ICdnJywgICdcXHUwMTFmJzogJ2cnLCAnXFx1MDEyMSc6ICdnJywgJ1xcdTAxMjMnOiAnZycsXG4gICAgJ1xcdTAxMjQnOiAnSCcsICAnXFx1MDEyNic6ICdIJywgJ1xcdTAxMjUnOiAnaCcsICdcXHUwMTI3JzogJ2gnLFxuICAgICdcXHUwMTI4JzogJ0knLCAgJ1xcdTAxMmEnOiAnSScsICdcXHUwMTJjJzogJ0knLCAnXFx1MDEyZSc6ICdJJywgJ1xcdTAxMzAnOiAnSScsXG4gICAgJ1xcdTAxMjknOiAnaScsICAnXFx1MDEyYic6ICdpJywgJ1xcdTAxMmQnOiAnaScsICdcXHUwMTJmJzogJ2knLCAnXFx1MDEzMSc6ICdpJyxcbiAgICAnXFx1MDEzNCc6ICdKJywgICdcXHUwMTM1JzogJ2onLFxuICAgICdcXHUwMTM2JzogJ0snLCAgJ1xcdTAxMzcnOiAnaycsICdcXHUwMTM4JzogJ2snLFxuICAgICdcXHUwMTM5JzogJ0wnLCAgJ1xcdTAxM2InOiAnTCcsICdcXHUwMTNkJzogJ0wnLCAnXFx1MDEzZic6ICdMJywgJ1xcdTAxNDEnOiAnTCcsXG4gICAgJ1xcdTAxM2EnOiAnbCcsICAnXFx1MDEzYyc6ICdsJywgJ1xcdTAxM2UnOiAnbCcsICdcXHUwMTQwJzogJ2wnLCAnXFx1MDE0Mic6ICdsJyxcbiAgICAnXFx1MDE0Myc6ICdOJywgICdcXHUwMTQ1JzogJ04nLCAnXFx1MDE0Nyc6ICdOJywgJ1xcdTAxNGEnOiAnTicsXG4gICAgJ1xcdTAxNDQnOiAnbicsICAnXFx1MDE0Nic6ICduJywgJ1xcdTAxNDgnOiAnbicsICdcXHUwMTRiJzogJ24nLFxuICAgICdcXHUwMTRjJzogJ08nLCAgJ1xcdTAxNGUnOiAnTycsICdcXHUwMTUwJzogJ08nLFxuICAgICdcXHUwMTRkJzogJ28nLCAgJ1xcdTAxNGYnOiAnbycsICdcXHUwMTUxJzogJ28nLFxuICAgICdcXHUwMTU0JzogJ1InLCAgJ1xcdTAxNTYnOiAnUicsICdcXHUwMTU4JzogJ1InLFxuICAgICdcXHUwMTU1JzogJ3InLCAgJ1xcdTAxNTcnOiAncicsICdcXHUwMTU5JzogJ3InLFxuICAgICdcXHUwMTVhJzogJ1MnLCAgJ1xcdTAxNWMnOiAnUycsICdcXHUwMTVlJzogJ1MnLCAnXFx1MDE2MCc6ICdTJyxcbiAgICAnXFx1MDE1Yic6ICdzJywgICdcXHUwMTVkJzogJ3MnLCAnXFx1MDE1Zic6ICdzJywgJ1xcdTAxNjEnOiAncycsXG4gICAgJ1xcdTAxNjInOiAnVCcsICAnXFx1MDE2NCc6ICdUJywgJ1xcdTAxNjYnOiAnVCcsXG4gICAgJ1xcdTAxNjMnOiAndCcsICAnXFx1MDE2NSc6ICd0JywgJ1xcdTAxNjcnOiAndCcsXG4gICAgJ1xcdTAxNjgnOiAnVScsICAnXFx1MDE2YSc6ICdVJywgJ1xcdTAxNmMnOiAnVScsICdcXHUwMTZlJzogJ1UnLCAnXFx1MDE3MCc6ICdVJywgJ1xcdTAxNzInOiAnVScsXG4gICAgJ1xcdTAxNjknOiAndScsICAnXFx1MDE2Yic6ICd1JywgJ1xcdTAxNmQnOiAndScsICdcXHUwMTZmJzogJ3UnLCAnXFx1MDE3MSc6ICd1JywgJ1xcdTAxNzMnOiAndScsXG4gICAgJ1xcdTAxNzQnOiAnVycsICAnXFx1MDE3NSc6ICd3JyxcbiAgICAnXFx1MDE3Nic6ICdZJywgICdcXHUwMTc3JzogJ3knLCAnXFx1MDE3OCc6ICdZJyxcbiAgICAnXFx1MDE3OSc6ICdaJywgICdcXHUwMTdiJzogJ1onLCAnXFx1MDE3ZCc6ICdaJyxcbiAgICAnXFx1MDE3YSc6ICd6JywgICdcXHUwMTdjJzogJ3onLCAnXFx1MDE3ZSc6ICd6JyxcbiAgICAnXFx1MDEzMic6ICdJSicsICdcXHUwMTMzJzogJ2lqJyxcbiAgICAnXFx1MDE1Mic6ICdPZScsICdcXHUwMTUzJzogJ29lJyxcbiAgICAnXFx1MDE0OSc6IFwiJ25cIiwgJ1xcdTAxN2YnOiAncydcbiAgfTtcblxuICAvKiogVXNlZCB0byBtYXAgY2hhcmFjdGVycyB0byBIVE1MIGVudGl0aWVzLiAqL1xuICB2YXIgaHRtbEVzY2FwZXMgPSB7XG4gICAgJyYnOiAnJmFtcDsnLFxuICAgICc8JzogJyZsdDsnLFxuICAgICc+JzogJyZndDsnLFxuICAgICdcIic6ICcmcXVvdDsnLFxuICAgIFwiJ1wiOiAnJiMzOTsnXG4gIH07XG5cbiAgLyoqIFVzZWQgdG8gbWFwIEhUTUwgZW50aXRpZXMgdG8gY2hhcmFjdGVycy4gKi9cbiAgdmFyIGh0bWxVbmVzY2FwZXMgPSB7XG4gICAgJyZhbXA7JzogJyYnLFxuICAgICcmbHQ7JzogJzwnLFxuICAgICcmZ3Q7JzogJz4nLFxuICAgICcmcXVvdDsnOiAnXCInLFxuICAgICcmIzM5Oyc6IFwiJ1wiXG4gIH07XG5cbiAgLyoqIFVzZWQgdG8gZXNjYXBlIGNoYXJhY3RlcnMgZm9yIGluY2x1c2lvbiBpbiBjb21waWxlZCBzdHJpbmcgbGl0ZXJhbHMuICovXG4gIHZhciBzdHJpbmdFc2NhcGVzID0ge1xuICAgICdcXFxcJzogJ1xcXFwnLFxuICAgIFwiJ1wiOiBcIidcIixcbiAgICAnXFxuJzogJ24nLFxuICAgICdcXHInOiAncicsXG4gICAgJ1xcdTIwMjgnOiAndTIwMjgnLFxuICAgICdcXHUyMDI5JzogJ3UyMDI5J1xuICB9O1xuXG4gIC8qKiBCdWlsdC1pbiBtZXRob2QgcmVmZXJlbmNlcyB3aXRob3V0IGEgZGVwZW5kZW5jeSBvbiBgcm9vdGAuICovXG4gIHZhciBmcmVlUGFyc2VGbG9hdCA9IHBhcnNlRmxvYXQsXG4gICAgICBmcmVlUGFyc2VJbnQgPSBwYXJzZUludDtcblxuICAvKiogRGV0ZWN0IGZyZWUgdmFyaWFibGUgYGdsb2JhbGAgZnJvbSBOb2RlLmpzLiAqL1xuICB2YXIgZnJlZUdsb2JhbCA9IHR5cGVvZiBnbG9iYWwgPT0gJ29iamVjdCcgJiYgZ2xvYmFsICYmIGdsb2JhbC5PYmplY3QgPT09IE9iamVjdCAmJiBnbG9iYWw7XG5cbiAgLyoqIERldGVjdCBmcmVlIHZhcmlhYmxlIGBzZWxmYC4gKi9cbiAgdmFyIGZyZWVTZWxmID0gdHlwZW9mIHNlbGYgPT0gJ29iamVjdCcgJiYgc2VsZiAmJiBzZWxmLk9iamVjdCA9PT0gT2JqZWN0ICYmIHNlbGY7XG5cbiAgLyoqIFVzZWQgYXMgYSByZWZlcmVuY2UgdG8gdGhlIGdsb2JhbCBvYmplY3QuICovXG4gIHZhciByb290ID0gZnJlZUdsb2JhbCB8fCBmcmVlU2VsZiB8fCBGdW5jdGlvbigncmV0dXJuIHRoaXMnKSgpO1xuXG4gIC8qKiBEZXRlY3QgZnJlZSB2YXJpYWJsZSBgZXhwb3J0c2AuICovXG4gIHZhciBmcmVlRXhwb3J0cyA9IHR5cGVvZiBleHBvcnRzID09ICdvYmplY3QnICYmIGV4cG9ydHMgJiYgIWV4cG9ydHMubm9kZVR5cGUgJiYgZXhwb3J0cztcblxuICAvKiogRGV0ZWN0IGZyZWUgdmFyaWFibGUgYG1vZHVsZWAuICovXG4gIHZhciBmcmVlTW9kdWxlID0gZnJlZUV4cG9ydHMgJiYgdHlwZW9mIG1vZHVsZSA9PSAnb2JqZWN0JyAmJiBtb2R1bGUgJiYgIW1vZHVsZS5ub2RlVHlwZSAmJiBtb2R1bGU7XG5cbiAgLyoqIERldGVjdCB0aGUgcG9wdWxhciBDb21tb25KUyBleHRlbnNpb24gYG1vZHVsZS5leHBvcnRzYC4gKi9cbiAgdmFyIG1vZHVsZUV4cG9ydHMgPSBmcmVlTW9kdWxlICYmIGZyZWVNb2R1bGUuZXhwb3J0cyA9PT0gZnJlZUV4cG9ydHM7XG5cbiAgLyoqIERldGVjdCBmcmVlIHZhcmlhYmxlIGBwcm9jZXNzYCBmcm9tIE5vZGUuanMuICovXG4gIHZhciBmcmVlUHJvY2VzcyA9IG1vZHVsZUV4cG9ydHMgJiYgZnJlZUdsb2JhbC5wcm9jZXNzO1xuXG4gIC8qKiBVc2VkIHRvIGFjY2VzcyBmYXN0ZXIgTm9kZS5qcyBoZWxwZXJzLiAqL1xuICB2YXIgbm9kZVV0aWwgPSAoZnVuY3Rpb24oKSB7XG4gICAgdHJ5IHtcbiAgICAgIHJldHVybiBmcmVlUHJvY2VzcyAmJiBmcmVlUHJvY2Vzcy5iaW5kaW5nICYmIGZyZWVQcm9jZXNzLmJpbmRpbmcoJ3V0aWwnKTtcbiAgICB9IGNhdGNoIChlKSB7fVxuICB9KCkpO1xuXG4gIC8qIE5vZGUuanMgaGVscGVyIHJlZmVyZW5jZXMuICovXG4gIHZhciBub2RlSXNBcnJheUJ1ZmZlciA9IG5vZGVVdGlsICYmIG5vZGVVdGlsLmlzQXJyYXlCdWZmZXIsXG4gICAgICBub2RlSXNEYXRlID0gbm9kZVV0aWwgJiYgbm9kZVV0aWwuaXNEYXRlLFxuICAgICAgbm9kZUlzTWFwID0gbm9kZVV0aWwgJiYgbm9kZVV0aWwuaXNNYXAsXG4gICAgICBub2RlSXNSZWdFeHAgPSBub2RlVXRpbCAmJiBub2RlVXRpbC5pc1JlZ0V4cCxcbiAgICAgIG5vZGVJc1NldCA9IG5vZGVVdGlsICYmIG5vZGVVdGlsLmlzU2V0LFxuICAgICAgbm9kZUlzVHlwZWRBcnJheSA9IG5vZGVVdGlsICYmIG5vZGVVdGlsLmlzVHlwZWRBcnJheTtcblxuICAvKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi9cblxuICAvKipcbiAgICogQWRkcyB0aGUga2V5LXZhbHVlIGBwYWlyYCB0byBgbWFwYC5cbiAgICpcbiAgICogQHByaXZhdGVcbiAgICogQHBhcmFtIHtPYmplY3R9IG1hcCBUaGUgbWFwIHRvIG1vZGlmeS5cbiAgICogQHBhcmFtIHtBcnJheX0gcGFpciBUaGUga2V5LXZhbHVlIHBhaXIgdG8gYWRkLlxuICAgKiBAcmV0dXJucyB7T2JqZWN0fSBSZXR1cm5zIGBtYXBgLlxuICAgKi9cbiAgZnVuY3Rpb24gYWRkTWFwRW50cnkobWFwLCBwYWlyKSB7XG4gICAgLy8gRG9uJ3QgcmV0dXJuIGBtYXAuc2V0YCBiZWNhdXNlIGl0J3Mgbm90IGNoYWluYWJsZSBpbiBJRSAxMS5cbiAgICBtYXAuc2V0KHBhaXJbMF0sIHBhaXJbMV0pO1xuICAgIHJldHVybiBtYXA7XG4gIH1cblxuICAvKipcbiAgICogQWRkcyBgdmFsdWVgIHRvIGBzZXRgLlxuICAgKlxuICAgKiBAcHJpdmF0ZVxuICAgKiBAcGFyYW0ge09iamVjdH0gc2V0IFRoZSBzZXQgdG8gbW9kaWZ5LlxuICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBhZGQuXG4gICAqIEByZXR1cm5zIHtPYmplY3R9IFJldHVybnMgYHNldGAuXG4gICAqL1xuICBmdW5jdGlvbiBhZGRTZXRFbnRyeShzZXQsIHZhbHVlKSB7XG4gICAgLy8gRG9uJ3QgcmV0dXJuIGBzZXQuYWRkYCBiZWNhdXNlIGl0J3Mgbm90IGNoYWluYWJsZSBpbiBJRSAxMS5cbiAgICBzZXQuYWRkKHZhbHVlKTtcbiAgICByZXR1cm4gc2V0O1xuICB9XG5cbiAgLyoqXG4gICAqIEEgZmFzdGVyIGFsdGVybmF0aXZlIHRvIGBGdW5jdGlvbiNhcHBseWAsIHRoaXMgZnVuY3Rpb24gaW52b2tlcyBgZnVuY2BcbiAgICogd2l0aCB0aGUgYHRoaXNgIGJpbmRpbmcgb2YgYHRoaXNBcmdgIGFuZCB0aGUgYXJndW1lbnRzIG9mIGBhcmdzYC5cbiAgICpcbiAgICogQHByaXZhdGVcbiAgICogQHBhcmFtIHtGdW5jdGlvbn0gZnVuYyBUaGUgZnVuY3Rpb24gdG8gaW52b2tlLlxuICAgKiBAcGFyYW0geyp9IHRoaXNBcmcgVGhlIGB0aGlzYCBiaW5kaW5nIG9mIGBmdW5jYC5cbiAgICogQHBhcmFtIHtBcnJheX0gYXJncyBUaGUgYXJndW1lbnRzIHRvIGludm9rZSBgZnVuY2Agd2l0aC5cbiAgICogQHJldHVybnMgeyp9IFJldHVybnMgdGhlIHJlc3VsdCBvZiBgZnVuY2AuXG4gICAqL1xuICBmdW5jdGlvbiBhcHBseShmdW5jLCB0aGlzQXJnLCBhcmdzKSB7XG4gICAgc3dpdGNoIChhcmdzLmxlbmd0aCkge1xuICAgICAgY2FzZSAwOiByZXR1cm4gZnVuYy5jYWxsKHRoaXNBcmcpO1xuICAgICAgY2FzZSAxOiByZXR1cm4gZnVuYy5jYWxsKHRoaXNBcmcsIGFyZ3NbMF0pO1xuICAgICAgY2FzZSAyOiByZXR1cm4gZnVuYy5jYWxsKHRoaXNBcmcsIGFyZ3NbMF0sIGFyZ3NbMV0pO1xuICAgICAgY2FzZSAzOiByZXR1cm4gZnVuYy5jYWxsKHRoaXNBcmcsIGFyZ3NbMF0sIGFyZ3NbMV0sIGFyZ3NbMl0pO1xuICAgIH1cbiAgICByZXR1cm4gZnVuYy5hcHBseSh0aGlzQXJnLCBhcmdzKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBBIHNwZWNpYWxpemVkIHZlcnNpb24gb2YgYGJhc2VBZ2dyZWdhdG9yYCBmb3IgYXJyYXlzLlxuICAgKlxuICAgKiBAcHJpdmF0ZVxuICAgKiBAcGFyYW0ge0FycmF5fSBbYXJyYXldIFRoZSBhcnJheSB0byBpdGVyYXRlIG92ZXIuXG4gICAqIEBwYXJhbSB7RnVuY3Rpb259IHNldHRlciBUaGUgZnVuY3Rpb24gdG8gc2V0IGBhY2N1bXVsYXRvcmAgdmFsdWVzLlxuICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBpdGVyYXRlZSBUaGUgaXRlcmF0ZWUgdG8gdHJhbnNmb3JtIGtleXMuXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBhY2N1bXVsYXRvciBUaGUgaW5pdGlhbCBhZ2dyZWdhdGVkIG9iamVjdC5cbiAgICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIGBhY2N1bXVsYXRvcmAuXG4gICAqL1xuICBmdW5jdGlvbiBhcnJheUFnZ3JlZ2F0b3IoYXJyYXksIHNldHRlciwgaXRlcmF0ZWUsIGFjY3VtdWxhdG9yKSB7XG4gICAgdmFyIGluZGV4ID0gLTEsXG4gICAgICAgIGxlbmd0aCA9IGFycmF5ID09IG51bGwgPyAwIDogYXJyYXkubGVuZ3RoO1xuXG4gICAgd2hpbGUgKCsraW5kZXggPCBsZW5ndGgpIHtcbiAgICAgIHZhciB2YWx1ZSA9IGFycmF5W2luZGV4XTtcbiAgICAgIHNldHRlcihhY2N1bXVsYXRvciwgdmFsdWUsIGl0ZXJhdGVlKHZhbHVlKSwgYXJyYXkpO1xuICAgIH1cbiAgICByZXR1cm4gYWNjdW11bGF0b3I7XG4gIH1cblxuICAvKipcbiAgICogQSBzcGVjaWFsaXplZCB2ZXJzaW9uIG9mIGBfLmZvckVhY2hgIGZvciBhcnJheXMgd2l0aG91dCBzdXBwb3J0IGZvclxuICAgKiBpdGVyYXRlZSBzaG9ydGhhbmRzLlxuICAgKlxuICAgKiBAcHJpdmF0ZVxuICAgKiBAcGFyYW0ge0FycmF5fSBbYXJyYXldIFRoZSBhcnJheSB0byBpdGVyYXRlIG92ZXIuXG4gICAqIEBwYXJhbSB7RnVuY3Rpb259IGl0ZXJhdGVlIFRoZSBmdW5jdGlvbiBpbnZva2VkIHBlciBpdGVyYXRpb24uXG4gICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyBgYXJyYXlgLlxuICAgKi9cbiAgZnVuY3Rpb24gYXJyYXlFYWNoKGFycmF5LCBpdGVyYXRlZSkge1xuICAgIHZhciBpbmRleCA9IC0xLFxuICAgICAgICBsZW5ndGggPSBhcnJheSA9PSBudWxsID8gMCA6IGFycmF5Lmxlbmd0aDtcblxuICAgIHdoaWxlICgrK2luZGV4IDwgbGVuZ3RoKSB7XG4gICAgICBpZiAoaXRlcmF0ZWUoYXJyYXlbaW5kZXhdLCBpbmRleCwgYXJyYXkpID09PSBmYWxzZSkge1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIGFycmF5O1xuICB9XG5cbiAgLyoqXG4gICAqIEEgc3BlY2lhbGl6ZWQgdmVyc2lvbiBvZiBgXy5mb3JFYWNoUmlnaHRgIGZvciBhcnJheXMgd2l0aG91dCBzdXBwb3J0IGZvclxuICAgKiBpdGVyYXRlZSBzaG9ydGhhbmRzLlxuICAgKlxuICAgKiBAcHJpdmF0ZVxuICAgKiBAcGFyYW0ge0FycmF5fSBbYXJyYXldIFRoZSBhcnJheSB0byBpdGVyYXRlIG92ZXIuXG4gICAqIEBwYXJhbSB7RnVuY3Rpb259IGl0ZXJhdGVlIFRoZSBmdW5jdGlvbiBpbnZva2VkIHBlciBpdGVyYXRpb24uXG4gICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyBgYXJyYXlgLlxuICAgKi9cbiAgZnVuY3Rpb24gYXJyYXlFYWNoUmlnaHQoYXJyYXksIGl0ZXJhdGVlKSB7XG4gICAgdmFyIGxlbmd0aCA9IGFycmF5ID09IG51bGwgPyAwIDogYXJyYXkubGVuZ3RoO1xuXG4gICAgd2hpbGUgKGxlbmd0aC0tKSB7XG4gICAgICBpZiAoaXRlcmF0ZWUoYXJyYXlbbGVuZ3RoXSwgbGVuZ3RoLCBhcnJheSkgPT09IGZhbHNlKSB7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gYXJyYXk7XG4gIH1cblxuICAvKipcbiAgICogQSBzcGVjaWFsaXplZCB2ZXJzaW9uIG9mIGBfLmV2ZXJ5YCBmb3IgYXJyYXlzIHdpdGhvdXQgc3VwcG9ydCBmb3JcbiAgICogaXRlcmF0ZWUgc2hvcnRoYW5kcy5cbiAgICpcbiAgICogQHByaXZhdGVcbiAgICogQHBhcmFtIHtBcnJheX0gW2FycmF5XSBUaGUgYXJyYXkgdG8gaXRlcmF0ZSBvdmVyLlxuICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBwcmVkaWNhdGUgVGhlIGZ1bmN0aW9uIGludm9rZWQgcGVyIGl0ZXJhdGlvbi5cbiAgICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGFsbCBlbGVtZW50cyBwYXNzIHRoZSBwcmVkaWNhdGUgY2hlY2ssXG4gICAqICBlbHNlIGBmYWxzZWAuXG4gICAqL1xuICBmdW5jdGlvbiBhcnJheUV2ZXJ5KGFycmF5LCBwcmVkaWNhdGUpIHtcbiAgICB2YXIgaW5kZXggPSAtMSxcbiAgICAgICAgbGVuZ3RoID0gYXJyYXkgPT0gbnVsbCA/IDAgOiBhcnJheS5sZW5ndGg7XG5cbiAgICB3aGlsZSAoKytpbmRleCA8IGxlbmd0aCkge1xuICAgICAgaWYgKCFwcmVkaWNhdGUoYXJyYXlbaW5kZXhdLCBpbmRleCwgYXJyYXkpKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cblxuICAvKipcbiAgICogQSBzcGVjaWFsaXplZCB2ZXJzaW9uIG9mIGBfLmZpbHRlcmAgZm9yIGFycmF5cyB3aXRob3V0IHN1cHBvcnQgZm9yXG4gICAqIGl0ZXJhdGVlIHNob3J0aGFuZHMuXG4gICAqXG4gICAqIEBwcml2YXRlXG4gICAqIEBwYXJhbSB7QXJyYXl9IFthcnJheV0gVGhlIGFycmF5IHRvIGl0ZXJhdGUgb3Zlci5cbiAgICogQHBhcmFtIHtGdW5jdGlvbn0gcHJlZGljYXRlIFRoZSBmdW5jdGlvbiBpbnZva2VkIHBlciBpdGVyYXRpb24uXG4gICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgbmV3IGZpbHRlcmVkIGFycmF5LlxuICAgKi9cbiAgZnVuY3Rpb24gYXJyYXlGaWx0ZXIoYXJyYXksIHByZWRpY2F0ZSkge1xuICAgIHZhciBpbmRleCA9IC0xLFxuICAgICAgICBsZW5ndGggPSBhcnJheSA9PSBudWxsID8gMCA6IGFycmF5Lmxlbmd0aCxcbiAgICAgICAgcmVzSW5kZXggPSAwLFxuICAgICAgICByZXN1bHQgPSBbXTtcblxuICAgIHdoaWxlICgrK2luZGV4IDwgbGVuZ3RoKSB7XG4gICAgICB2YXIgdmFsdWUgPSBhcnJheVtpbmRleF07XG4gICAgICBpZiAocHJlZGljYXRlKHZhbHVlLCBpbmRleCwgYXJyYXkpKSB7XG4gICAgICAgIHJlc3VsdFtyZXNJbmRleCsrXSA9IHZhbHVlO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gcmVzdWx0O1xuICB9XG5cbiAgLyoqXG4gICAqIEEgc3BlY2lhbGl6ZWQgdmVyc2lvbiBvZiBgXy5pbmNsdWRlc2AgZm9yIGFycmF5cyB3aXRob3V0IHN1cHBvcnQgZm9yXG4gICAqIHNwZWNpZnlpbmcgYW4gaW5kZXggdG8gc2VhcmNoIGZyb20uXG4gICAqXG4gICAqIEBwcml2YXRlXG4gICAqIEBwYXJhbSB7QXJyYXl9IFthcnJheV0gVGhlIGFycmF5IHRvIGluc3BlY3QuXG4gICAqIEBwYXJhbSB7Kn0gdGFyZ2V0IFRoZSB2YWx1ZSB0byBzZWFyY2ggZm9yLlxuICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHRhcmdldGAgaXMgZm91bmQsIGVsc2UgYGZhbHNlYC5cbiAgICovXG4gIGZ1bmN0aW9uIGFycmF5SW5jbHVkZXMoYXJyYXksIHZhbHVlKSB7XG4gICAgdmFyIGxlbmd0aCA9IGFycmF5ID09IG51bGwgPyAwIDogYXJyYXkubGVuZ3RoO1xuICAgIHJldHVybiAhIWxlbmd0aCAmJiBiYXNlSW5kZXhPZihhcnJheSwgdmFsdWUsIDApID4gLTE7XG4gIH1cblxuICAvKipcbiAgICogVGhpcyBmdW5jdGlvbiBpcyBsaWtlIGBhcnJheUluY2x1ZGVzYCBleGNlcHQgdGhhdCBpdCBhY2NlcHRzIGEgY29tcGFyYXRvci5cbiAgICpcbiAgICogQHByaXZhdGVcbiAgICogQHBhcmFtIHtBcnJheX0gW2FycmF5XSBUaGUgYXJyYXkgdG8gaW5zcGVjdC5cbiAgICogQHBhcmFtIHsqfSB0YXJnZXQgVGhlIHZhbHVlIHRvIHNlYXJjaCBmb3IuXG4gICAqIEBwYXJhbSB7RnVuY3Rpb259IGNvbXBhcmF0b3IgVGhlIGNvbXBhcmF0b3IgaW52b2tlZCBwZXIgZWxlbWVudC5cbiAgICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGB0YXJnZXRgIGlzIGZvdW5kLCBlbHNlIGBmYWxzZWAuXG4gICAqL1xuICBmdW5jdGlvbiBhcnJheUluY2x1ZGVzV2l0aChhcnJheSwgdmFsdWUsIGNvbXBhcmF0b3IpIHtcbiAgICB2YXIgaW5kZXggPSAtMSxcbiAgICAgICAgbGVuZ3RoID0gYXJyYXkgPT0gbnVsbCA/IDAgOiBhcnJheS5sZW5ndGg7XG5cbiAgICB3aGlsZSAoKytpbmRleCA8IGxlbmd0aCkge1xuICAgICAgaWYgKGNvbXBhcmF0b3IodmFsdWUsIGFycmF5W2luZGV4XSkpIHtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIC8qKlxuICAgKiBBIHNwZWNpYWxpemVkIHZlcnNpb24gb2YgYF8ubWFwYCBmb3IgYXJyYXlzIHdpdGhvdXQgc3VwcG9ydCBmb3IgaXRlcmF0ZWVcbiAgICogc2hvcnRoYW5kcy5cbiAgICpcbiAgICogQHByaXZhdGVcbiAgICogQHBhcmFtIHtBcnJheX0gW2FycmF5XSBUaGUgYXJyYXkgdG8gaXRlcmF0ZSBvdmVyLlxuICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBpdGVyYXRlZSBUaGUgZnVuY3Rpb24gaW52b2tlZCBwZXIgaXRlcmF0aW9uLlxuICAgKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIG5ldyBtYXBwZWQgYXJyYXkuXG4gICAqL1xuICBmdW5jdGlvbiBhcnJheU1hcChhcnJheSwgaXRlcmF0ZWUpIHtcbiAgICB2YXIgaW5kZXggPSAtMSxcbiAgICAgICAgbGVuZ3RoID0gYXJyYXkgPT0gbnVsbCA/IDAgOiBhcnJheS5sZW5ndGgsXG4gICAgICAgIHJlc3VsdCA9IEFycmF5KGxlbmd0aCk7XG5cbiAgICB3aGlsZSAoKytpbmRleCA8IGxlbmd0aCkge1xuICAgICAgcmVzdWx0W2luZGV4XSA9IGl0ZXJhdGVlKGFycmF5W2luZGV4XSwgaW5kZXgsIGFycmF5KTtcbiAgICB9XG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfVxuXG4gIC8qKlxuICAgKiBBcHBlbmRzIHRoZSBlbGVtZW50cyBvZiBgdmFsdWVzYCB0byBgYXJyYXlgLlxuICAgKlxuICAgKiBAcHJpdmF0ZVxuICAgKiBAcGFyYW0ge0FycmF5fSBhcnJheSBUaGUgYXJyYXkgdG8gbW9kaWZ5LlxuICAgKiBAcGFyYW0ge0FycmF5fSB2YWx1ZXMgVGhlIHZhbHVlcyB0byBhcHBlbmQuXG4gICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyBgYXJyYXlgLlxuICAgKi9cbiAgZnVuY3Rpb24gYXJyYXlQdXNoKGFycmF5LCB2YWx1ZXMpIHtcbiAgICB2YXIgaW5kZXggPSAtMSxcbiAgICAgICAgbGVuZ3RoID0gdmFsdWVzLmxlbmd0aCxcbiAgICAgICAgb2Zmc2V0ID0gYXJyYXkubGVuZ3RoO1xuXG4gICAgd2hpbGUgKCsraW5kZXggPCBsZW5ndGgpIHtcbiAgICAgIGFycmF5W29mZnNldCArIGluZGV4XSA9IHZhbHVlc1tpbmRleF07XG4gICAgfVxuICAgIHJldHVybiBhcnJheTtcbiAgfVxuXG4gIC8qKlxuICAgKiBBIHNwZWNpYWxpemVkIHZlcnNpb24gb2YgYF8ucmVkdWNlYCBmb3IgYXJyYXlzIHdpdGhvdXQgc3VwcG9ydCBmb3JcbiAgICogaXRlcmF0ZWUgc2hvcnRoYW5kcy5cbiAgICpcbiAgICogQHByaXZhdGVcbiAgICogQHBhcmFtIHtBcnJheX0gW2FycmF5XSBUaGUgYXJyYXkgdG8gaXRlcmF0ZSBvdmVyLlxuICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBpdGVyYXRlZSBUaGUgZnVuY3Rpb24gaW52b2tlZCBwZXIgaXRlcmF0aW9uLlxuICAgKiBAcGFyYW0geyp9IFthY2N1bXVsYXRvcl0gVGhlIGluaXRpYWwgdmFsdWUuXG4gICAqIEBwYXJhbSB7Ym9vbGVhbn0gW2luaXRBY2N1bV0gU3BlY2lmeSB1c2luZyB0aGUgZmlyc3QgZWxlbWVudCBvZiBgYXJyYXlgIGFzXG4gICAqICB0aGUgaW5pdGlhbCB2YWx1ZS5cbiAgICogQHJldHVybnMgeyp9IFJldHVybnMgdGhlIGFjY3VtdWxhdGVkIHZhbHVlLlxuICAgKi9cbiAgZnVuY3Rpb24gYXJyYXlSZWR1Y2UoYXJyYXksIGl0ZXJhdGVlLCBhY2N1bXVsYXRvciwgaW5pdEFjY3VtKSB7XG4gICAgdmFyIGluZGV4ID0gLTEsXG4gICAgICAgIGxlbmd0aCA9IGFycmF5ID09IG51bGwgPyAwIDogYXJyYXkubGVuZ3RoO1xuXG4gICAgaWYgKGluaXRBY2N1bSAmJiBsZW5ndGgpIHtcbiAgICAgIGFjY3VtdWxhdG9yID0gYXJyYXlbKytpbmRleF07XG4gICAgfVxuICAgIHdoaWxlICgrK2luZGV4IDwgbGVuZ3RoKSB7XG4gICAgICBhY2N1bXVsYXRvciA9IGl0ZXJhdGVlKGFjY3VtdWxhdG9yLCBhcnJheVtpbmRleF0sIGluZGV4LCBhcnJheSk7XG4gICAgfVxuICAgIHJldHVybiBhY2N1bXVsYXRvcjtcbiAgfVxuXG4gIC8qKlxuICAgKiBBIHNwZWNpYWxpemVkIHZlcnNpb24gb2YgYF8ucmVkdWNlUmlnaHRgIGZvciBhcnJheXMgd2l0aG91dCBzdXBwb3J0IGZvclxuICAgKiBpdGVyYXRlZSBzaG9ydGhhbmRzLlxuICAgKlxuICAgKiBAcHJpdmF0ZVxuICAgKiBAcGFyYW0ge0FycmF5fSBbYXJyYXldIFRoZSBhcnJheSB0byBpdGVyYXRlIG92ZXIuXG4gICAqIEBwYXJhbSB7RnVuY3Rpb259IGl0ZXJhdGVlIFRoZSBmdW5jdGlvbiBpbnZva2VkIHBlciBpdGVyYXRpb24uXG4gICAqIEBwYXJhbSB7Kn0gW2FjY3VtdWxhdG9yXSBUaGUgaW5pdGlhbCB2YWx1ZS5cbiAgICogQHBhcmFtIHtib29sZWFufSBbaW5pdEFjY3VtXSBTcGVjaWZ5IHVzaW5nIHRoZSBsYXN0IGVsZW1lbnQgb2YgYGFycmF5YCBhc1xuICAgKiAgdGhlIGluaXRpYWwgdmFsdWUuXG4gICAqIEByZXR1cm5zIHsqfSBSZXR1cm5zIHRoZSBhY2N1bXVsYXRlZCB2YWx1ZS5cbiAgICovXG4gIGZ1bmN0aW9uIGFycmF5UmVkdWNlUmlnaHQoYXJyYXksIGl0ZXJhdGVlLCBhY2N1bXVsYXRvciwgaW5pdEFjY3VtKSB7XG4gICAgdmFyIGxlbmd0aCA9IGFycmF5ID09IG51bGwgPyAwIDogYXJyYXkubGVuZ3RoO1xuICAgIGlmIChpbml0QWNjdW0gJiYgbGVuZ3RoKSB7XG4gICAgICBhY2N1bXVsYXRvciA9IGFycmF5Wy0tbGVuZ3RoXTtcbiAgICB9XG4gICAgd2hpbGUgKGxlbmd0aC0tKSB7XG4gICAgICBhY2N1bXVsYXRvciA9IGl0ZXJhdGVlKGFjY3VtdWxhdG9yLCBhcnJheVtsZW5ndGhdLCBsZW5ndGgsIGFycmF5KTtcbiAgICB9XG4gICAgcmV0dXJuIGFjY3VtdWxhdG9yO1xuICB9XG5cbiAgLyoqXG4gICAqIEEgc3BlY2lhbGl6ZWQgdmVyc2lvbiBvZiBgXy5zb21lYCBmb3IgYXJyYXlzIHdpdGhvdXQgc3VwcG9ydCBmb3IgaXRlcmF0ZWVcbiAgICogc2hvcnRoYW5kcy5cbiAgICpcbiAgICogQHByaXZhdGVcbiAgICogQHBhcmFtIHtBcnJheX0gW2FycmF5XSBUaGUgYXJyYXkgdG8gaXRlcmF0ZSBvdmVyLlxuICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBwcmVkaWNhdGUgVGhlIGZ1bmN0aW9uIGludm9rZWQgcGVyIGl0ZXJhdGlvbi5cbiAgICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGFueSBlbGVtZW50IHBhc3NlcyB0aGUgcHJlZGljYXRlIGNoZWNrLFxuICAgKiAgZWxzZSBgZmFsc2VgLlxuICAgKi9cbiAgZnVuY3Rpb24gYXJyYXlTb21lKGFycmF5LCBwcmVkaWNhdGUpIHtcbiAgICB2YXIgaW5kZXggPSAtMSxcbiAgICAgICAgbGVuZ3RoID0gYXJyYXkgPT0gbnVsbCA/IDAgOiBhcnJheS5sZW5ndGg7XG5cbiAgICB3aGlsZSAoKytpbmRleCA8IGxlbmd0aCkge1xuICAgICAgaWYgKHByZWRpY2F0ZShhcnJheVtpbmRleF0sIGluZGV4LCBhcnJheSkpIHtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHZXRzIHRoZSBzaXplIG9mIGFuIEFTQ0lJIGBzdHJpbmdgLlxuICAgKlxuICAgKiBAcHJpdmF0ZVxuICAgKiBAcGFyYW0ge3N0cmluZ30gc3RyaW5nIFRoZSBzdHJpbmcgaW5zcGVjdC5cbiAgICogQHJldHVybnMge251bWJlcn0gUmV0dXJucyB0aGUgc3RyaW5nIHNpemUuXG4gICAqL1xuICB2YXIgYXNjaWlTaXplID0gYmFzZVByb3BlcnR5KCdsZW5ndGgnKTtcblxuICAvKipcbiAgICogQ29udmVydHMgYW4gQVNDSUkgYHN0cmluZ2AgdG8gYW4gYXJyYXkuXG4gICAqXG4gICAqIEBwcml2YXRlXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBzdHJpbmcgVGhlIHN0cmluZyB0byBjb252ZXJ0LlxuICAgKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIGNvbnZlcnRlZCBhcnJheS5cbiAgICovXG4gIGZ1bmN0aW9uIGFzY2lpVG9BcnJheShzdHJpbmcpIHtcbiAgICByZXR1cm4gc3RyaW5nLnNwbGl0KCcnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBTcGxpdHMgYW4gQVNDSUkgYHN0cmluZ2AgaW50byBhbiBhcnJheSBvZiBpdHMgd29yZHMuXG4gICAqXG4gICAqIEBwcml2YXRlXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBUaGUgc3RyaW5nIHRvIGluc3BlY3QuXG4gICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgd29yZHMgb2YgYHN0cmluZ2AuXG4gICAqL1xuICBmdW5jdGlvbiBhc2NpaVdvcmRzKHN0cmluZykge1xuICAgIHJldHVybiBzdHJpbmcubWF0Y2gocmVBc2NpaVdvcmQpIHx8IFtdO1xuICB9XG5cbiAgLyoqXG4gICAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIG1ldGhvZHMgbGlrZSBgXy5maW5kS2V5YCBhbmQgYF8uZmluZExhc3RLZXlgLFxuICAgKiB3aXRob3V0IHN1cHBvcnQgZm9yIGl0ZXJhdGVlIHNob3J0aGFuZHMsIHdoaWNoIGl0ZXJhdGVzIG92ZXIgYGNvbGxlY3Rpb25gXG4gICAqIHVzaW5nIGBlYWNoRnVuY2AuXG4gICAqXG4gICAqIEBwcml2YXRlXG4gICAqIEBwYXJhbSB7QXJyYXl8T2JqZWN0fSBjb2xsZWN0aW9uIFRoZSBjb2xsZWN0aW9uIHRvIGluc3BlY3QuXG4gICAqIEBwYXJhbSB7RnVuY3Rpb259IHByZWRpY2F0ZSBUaGUgZnVuY3Rpb24gaW52b2tlZCBwZXIgaXRlcmF0aW9uLlxuICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBlYWNoRnVuYyBUaGUgZnVuY3Rpb24gdG8gaXRlcmF0ZSBvdmVyIGBjb2xsZWN0aW9uYC5cbiAgICogQHJldHVybnMgeyp9IFJldHVybnMgdGhlIGZvdW5kIGVsZW1lbnQgb3IgaXRzIGtleSwgZWxzZSBgdW5kZWZpbmVkYC5cbiAgICovXG4gIGZ1bmN0aW9uIGJhc2VGaW5kS2V5KGNvbGxlY3Rpb24sIHByZWRpY2F0ZSwgZWFjaEZ1bmMpIHtcbiAgICB2YXIgcmVzdWx0O1xuICAgIGVhY2hGdW5jKGNvbGxlY3Rpb24sIGZ1bmN0aW9uKHZhbHVlLCBrZXksIGNvbGxlY3Rpb24pIHtcbiAgICAgIGlmIChwcmVkaWNhdGUodmFsdWUsIGtleSwgY29sbGVjdGlvbikpIHtcbiAgICAgICAgcmVzdWx0ID0ga2V5O1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG4gICAgfSk7XG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfVxuXG4gIC8qKlxuICAgKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5maW5kSW5kZXhgIGFuZCBgXy5maW5kTGFzdEluZGV4YCB3aXRob3V0XG4gICAqIHN1cHBvcnQgZm9yIGl0ZXJhdGVlIHNob3J0aGFuZHMuXG4gICAqXG4gICAqIEBwcml2YXRlXG4gICAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBhcnJheSB0byBpbnNwZWN0LlxuICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBwcmVkaWNhdGUgVGhlIGZ1bmN0aW9uIGludm9rZWQgcGVyIGl0ZXJhdGlvbi5cbiAgICogQHBhcmFtIHtudW1iZXJ9IGZyb21JbmRleCBUaGUgaW5kZXggdG8gc2VhcmNoIGZyb20uXG4gICAqIEBwYXJhbSB7Ym9vbGVhbn0gW2Zyb21SaWdodF0gU3BlY2lmeSBpdGVyYXRpbmcgZnJvbSByaWdodCB0byBsZWZ0LlxuICAgKiBAcmV0dXJucyB7bnVtYmVyfSBSZXR1cm5zIHRoZSBpbmRleCBvZiB0aGUgbWF0Y2hlZCB2YWx1ZSwgZWxzZSBgLTFgLlxuICAgKi9cbiAgZnVuY3Rpb24gYmFzZUZpbmRJbmRleChhcnJheSwgcHJlZGljYXRlLCBmcm9tSW5kZXgsIGZyb21SaWdodCkge1xuICAgIHZhciBsZW5ndGggPSBhcnJheS5sZW5ndGgsXG4gICAgICAgIGluZGV4ID0gZnJvbUluZGV4ICsgKGZyb21SaWdodCA/IDEgOiAtMSk7XG5cbiAgICB3aGlsZSAoKGZyb21SaWdodCA/IGluZGV4LS0gOiArK2luZGV4IDwgbGVuZ3RoKSkge1xuICAgICAgaWYgKHByZWRpY2F0ZShhcnJheVtpbmRleF0sIGluZGV4LCBhcnJheSkpIHtcbiAgICAgICAgcmV0dXJuIGluZGV4O1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gLTE7XG4gIH1cblxuICAvKipcbiAgICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8uaW5kZXhPZmAgd2l0aG91dCBgZnJvbUluZGV4YCBib3VuZHMgY2hlY2tzLlxuICAgKlxuICAgKiBAcHJpdmF0ZVxuICAgKiBAcGFyYW0ge0FycmF5fSBhcnJheSBUaGUgYXJyYXkgdG8gaW5zcGVjdC5cbiAgICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gc2VhcmNoIGZvci5cbiAgICogQHBhcmFtIHtudW1iZXJ9IGZyb21JbmRleCBUaGUgaW5kZXggdG8gc2VhcmNoIGZyb20uXG4gICAqIEByZXR1cm5zIHtudW1iZXJ9IFJldHVybnMgdGhlIGluZGV4IG9mIHRoZSBtYXRjaGVkIHZhbHVlLCBlbHNlIGAtMWAuXG4gICAqL1xuICBmdW5jdGlvbiBiYXNlSW5kZXhPZihhcnJheSwgdmFsdWUsIGZyb21JbmRleCkge1xuICAgIHJldHVybiB2YWx1ZSA9PT0gdmFsdWVcbiAgICAgID8gc3RyaWN0SW5kZXhPZihhcnJheSwgdmFsdWUsIGZyb21JbmRleClcbiAgICAgIDogYmFzZUZpbmRJbmRleChhcnJheSwgYmFzZUlzTmFOLCBmcm9tSW5kZXgpO1xuICB9XG5cbiAgLyoqXG4gICAqIFRoaXMgZnVuY3Rpb24gaXMgbGlrZSBgYmFzZUluZGV4T2ZgIGV4Y2VwdCB0aGF0IGl0IGFjY2VwdHMgYSBjb21wYXJhdG9yLlxuICAgKlxuICAgKiBAcHJpdmF0ZVxuICAgKiBAcGFyYW0ge0FycmF5fSBhcnJheSBUaGUgYXJyYXkgdG8gaW5zcGVjdC5cbiAgICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gc2VhcmNoIGZvci5cbiAgICogQHBhcmFtIHtudW1iZXJ9IGZyb21JbmRleCBUaGUgaW5kZXggdG8gc2VhcmNoIGZyb20uXG4gICAqIEBwYXJhbSB7RnVuY3Rpb259IGNvbXBhcmF0b3IgVGhlIGNvbXBhcmF0b3IgaW52b2tlZCBwZXIgZWxlbWVudC5cbiAgICogQHJldHVybnMge251bWJlcn0gUmV0dXJucyB0aGUgaW5kZXggb2YgdGhlIG1hdGNoZWQgdmFsdWUsIGVsc2UgYC0xYC5cbiAgICovXG4gIGZ1bmN0aW9uIGJhc2VJbmRleE9mV2l0aChhcnJheSwgdmFsdWUsIGZyb21JbmRleCwgY29tcGFyYXRvcikge1xuICAgIHZhciBpbmRleCA9IGZyb21JbmRleCAtIDEsXG4gICAgICAgIGxlbmd0aCA9IGFycmF5Lmxlbmd0aDtcblxuICAgIHdoaWxlICgrK2luZGV4IDwgbGVuZ3RoKSB7XG4gICAgICBpZiAoY29tcGFyYXRvcihhcnJheVtpbmRleF0sIHZhbHVlKSkge1xuICAgICAgICByZXR1cm4gaW5kZXg7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiAtMTtcbiAgfVxuXG4gIC8qKlxuICAgKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5pc05hTmAgd2l0aG91dCBzdXBwb3J0IGZvciBudW1iZXIgb2JqZWN0cy5cbiAgICpcbiAgICogQHByaXZhdGVcbiAgICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY2hlY2suXG4gICAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlzIGBOYU5gLCBlbHNlIGBmYWxzZWAuXG4gICAqL1xuICBmdW5jdGlvbiBiYXNlSXNOYU4odmFsdWUpIHtcbiAgICByZXR1cm4gdmFsdWUgIT09IHZhbHVlO1xuICB9XG5cbiAgLyoqXG4gICAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLm1lYW5gIGFuZCBgXy5tZWFuQnlgIHdpdGhvdXQgc3VwcG9ydCBmb3JcbiAgICogaXRlcmF0ZWUgc2hvcnRoYW5kcy5cbiAgICpcbiAgICogQHByaXZhdGVcbiAgICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIGl0ZXJhdGUgb3Zlci5cbiAgICogQHBhcmFtIHtGdW5jdGlvbn0gaXRlcmF0ZWUgVGhlIGZ1bmN0aW9uIGludm9rZWQgcGVyIGl0ZXJhdGlvbi5cbiAgICogQHJldHVybnMge251bWJlcn0gUmV0dXJucyB0aGUgbWVhbi5cbiAgICovXG4gIGZ1bmN0aW9uIGJhc2VNZWFuKGFycmF5LCBpdGVyYXRlZSkge1xuICAgIHZhciBsZW5ndGggPSBhcnJheSA9PSBudWxsID8gMCA6IGFycmF5Lmxlbmd0aDtcbiAgICByZXR1cm4gbGVuZ3RoID8gKGJhc2VTdW0oYXJyYXksIGl0ZXJhdGVlKSAvIGxlbmd0aCkgOiBOQU47XG4gIH1cblxuICAvKipcbiAgICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8ucHJvcGVydHlgIHdpdGhvdXQgc3VwcG9ydCBmb3IgZGVlcCBwYXRocy5cbiAgICpcbiAgICogQHByaXZhdGVcbiAgICogQHBhcmFtIHtzdHJpbmd9IGtleSBUaGUga2V5IG9mIHRoZSBwcm9wZXJ0eSB0byBnZXQuXG4gICAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyB0aGUgbmV3IGFjY2Vzc29yIGZ1bmN0aW9uLlxuICAgKi9cbiAgZnVuY3Rpb24gYmFzZVByb3BlcnR5KGtleSkge1xuICAgIHJldHVybiBmdW5jdGlvbihvYmplY3QpIHtcbiAgICAgIHJldHVybiBvYmplY3QgPT0gbnVsbCA/IHVuZGVmaW5lZCA6IG9iamVjdFtrZXldO1xuICAgIH07XG4gIH1cblxuICAvKipcbiAgICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8ucHJvcGVydHlPZmAgd2l0aG91dCBzdXBwb3J0IGZvciBkZWVwIHBhdGhzLlxuICAgKlxuICAgKiBAcHJpdmF0ZVxuICAgKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gcXVlcnkuXG4gICAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyB0aGUgbmV3IGFjY2Vzc29yIGZ1bmN0aW9uLlxuICAgKi9cbiAgZnVuY3Rpb24gYmFzZVByb3BlcnR5T2Yob2JqZWN0KSB7XG4gICAgcmV0dXJuIGZ1bmN0aW9uKGtleSkge1xuICAgICAgcmV0dXJuIG9iamVjdCA9PSBudWxsID8gdW5kZWZpbmVkIDogb2JqZWN0W2tleV07XG4gICAgfTtcbiAgfVxuXG4gIC8qKlxuICAgKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5yZWR1Y2VgIGFuZCBgXy5yZWR1Y2VSaWdodGAsIHdpdGhvdXQgc3VwcG9ydFxuICAgKiBmb3IgaXRlcmF0ZWUgc2hvcnRoYW5kcywgd2hpY2ggaXRlcmF0ZXMgb3ZlciBgY29sbGVjdGlvbmAgdXNpbmcgYGVhY2hGdW5jYC5cbiAgICpcbiAgICogQHByaXZhdGVcbiAgICogQHBhcmFtIHtBcnJheXxPYmplY3R9IGNvbGxlY3Rpb24gVGhlIGNvbGxlY3Rpb24gdG8gaXRlcmF0ZSBvdmVyLlxuICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBpdGVyYXRlZSBUaGUgZnVuY3Rpb24gaW52b2tlZCBwZXIgaXRlcmF0aW9uLlxuICAgKiBAcGFyYW0geyp9IGFjY3VtdWxhdG9yIFRoZSBpbml0aWFsIHZhbHVlLlxuICAgKiBAcGFyYW0ge2Jvb2xlYW59IGluaXRBY2N1bSBTcGVjaWZ5IHVzaW5nIHRoZSBmaXJzdCBvciBsYXN0IGVsZW1lbnQgb2ZcbiAgICogIGBjb2xsZWN0aW9uYCBhcyB0aGUgaW5pdGlhbCB2YWx1ZS5cbiAgICogQHBhcmFtIHtGdW5jdGlvbn0gZWFjaEZ1bmMgVGhlIGZ1bmN0aW9uIHRvIGl0ZXJhdGUgb3ZlciBgY29sbGVjdGlvbmAuXG4gICAqIEByZXR1cm5zIHsqfSBSZXR1cm5zIHRoZSBhY2N1bXVsYXRlZCB2YWx1ZS5cbiAgICovXG4gIGZ1bmN0aW9uIGJhc2VSZWR1Y2UoY29sbGVjdGlvbiwgaXRlcmF0ZWUsIGFjY3VtdWxhdG9yLCBpbml0QWNjdW0sIGVhY2hGdW5jKSB7XG4gICAgZWFjaEZ1bmMoY29sbGVjdGlvbiwgZnVuY3Rpb24odmFsdWUsIGluZGV4LCBjb2xsZWN0aW9uKSB7XG4gICAgICBhY2N1bXVsYXRvciA9IGluaXRBY2N1bVxuICAgICAgICA/IChpbml0QWNjdW0gPSBmYWxzZSwgdmFsdWUpXG4gICAgICAgIDogaXRlcmF0ZWUoYWNjdW11bGF0b3IsIHZhbHVlLCBpbmRleCwgY29sbGVjdGlvbik7XG4gICAgfSk7XG4gICAgcmV0dXJuIGFjY3VtdWxhdG9yO1xuICB9XG5cbiAgLyoqXG4gICAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLnNvcnRCeWAgd2hpY2ggdXNlcyBgY29tcGFyZXJgIHRvIGRlZmluZSB0aGVcbiAgICogc29ydCBvcmRlciBvZiBgYXJyYXlgIGFuZCByZXBsYWNlcyBjcml0ZXJpYSBvYmplY3RzIHdpdGggdGhlaXIgY29ycmVzcG9uZGluZ1xuICAgKiB2YWx1ZXMuXG4gICAqXG4gICAqIEBwcml2YXRlXG4gICAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBhcnJheSB0byBzb3J0LlxuICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBjb21wYXJlciBUaGUgZnVuY3Rpb24gdG8gZGVmaW5lIHNvcnQgb3JkZXIuXG4gICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyBgYXJyYXlgLlxuICAgKi9cbiAgZnVuY3Rpb24gYmFzZVNvcnRCeShhcnJheSwgY29tcGFyZXIpIHtcbiAgICB2YXIgbGVuZ3RoID0gYXJyYXkubGVuZ3RoO1xuXG4gICAgYXJyYXkuc29ydChjb21wYXJlcik7XG4gICAgd2hpbGUgKGxlbmd0aC0tKSB7XG4gICAgICBhcnJheVtsZW5ndGhdID0gYXJyYXlbbGVuZ3RoXS52YWx1ZTtcbiAgICB9XG4gICAgcmV0dXJuIGFycmF5O1xuICB9XG5cbiAgLyoqXG4gICAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLnN1bWAgYW5kIGBfLnN1bUJ5YCB3aXRob3V0IHN1cHBvcnQgZm9yXG4gICAqIGl0ZXJhdGVlIHNob3J0aGFuZHMuXG4gICAqXG4gICAqIEBwcml2YXRlXG4gICAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBhcnJheSB0byBpdGVyYXRlIG92ZXIuXG4gICAqIEBwYXJhbSB7RnVuY3Rpb259IGl0ZXJhdGVlIFRoZSBmdW5jdGlvbiBpbnZva2VkIHBlciBpdGVyYXRpb24uXG4gICAqIEByZXR1cm5zIHtudW1iZXJ9IFJldHVybnMgdGhlIHN1bS5cbiAgICovXG4gIGZ1bmN0aW9uIGJhc2VTdW0oYXJyYXksIGl0ZXJhdGVlKSB7XG4gICAgdmFyIHJlc3VsdCxcbiAgICAgICAgaW5kZXggPSAtMSxcbiAgICAgICAgbGVuZ3RoID0gYXJyYXkubGVuZ3RoO1xuXG4gICAgd2hpbGUgKCsraW5kZXggPCBsZW5ndGgpIHtcbiAgICAgIHZhciBjdXJyZW50ID0gaXRlcmF0ZWUoYXJyYXlbaW5kZXhdKTtcbiAgICAgIGlmIChjdXJyZW50ICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgcmVzdWx0ID0gcmVzdWx0ID09PSB1bmRlZmluZWQgPyBjdXJyZW50IDogKHJlc3VsdCArIGN1cnJlbnQpO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gcmVzdWx0O1xuICB9XG5cbiAgLyoqXG4gICAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLnRpbWVzYCB3aXRob3V0IHN1cHBvcnQgZm9yIGl0ZXJhdGVlIHNob3J0aGFuZHNcbiAgICogb3IgbWF4IGFycmF5IGxlbmd0aCBjaGVja3MuXG4gICAqXG4gICAqIEBwcml2YXRlXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBuIFRoZSBudW1iZXIgb2YgdGltZXMgdG8gaW52b2tlIGBpdGVyYXRlZWAuXG4gICAqIEBwYXJhbSB7RnVuY3Rpb259IGl0ZXJhdGVlIFRoZSBmdW5jdGlvbiBpbnZva2VkIHBlciBpdGVyYXRpb24uXG4gICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgYXJyYXkgb2YgcmVzdWx0cy5cbiAgICovXG4gIGZ1bmN0aW9uIGJhc2VUaW1lcyhuLCBpdGVyYXRlZSkge1xuICAgIHZhciBpbmRleCA9IC0xLFxuICAgICAgICByZXN1bHQgPSBBcnJheShuKTtcblxuICAgIHdoaWxlICgrK2luZGV4IDwgbikge1xuICAgICAgcmVzdWx0W2luZGV4XSA9IGl0ZXJhdGVlKGluZGV4KTtcbiAgICB9XG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfVxuXG4gIC8qKlxuICAgKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy50b1BhaXJzYCBhbmQgYF8udG9QYWlyc0luYCB3aGljaCBjcmVhdGVzIGFuIGFycmF5XG4gICAqIG9mIGtleS12YWx1ZSBwYWlycyBmb3IgYG9iamVjdGAgY29ycmVzcG9uZGluZyB0byB0aGUgcHJvcGVydHkgbmFtZXMgb2YgYHByb3BzYC5cbiAgICpcbiAgICogQHByaXZhdGVcbiAgICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIHF1ZXJ5LlxuICAgKiBAcGFyYW0ge0FycmF5fSBwcm9wcyBUaGUgcHJvcGVydHkgbmFtZXMgdG8gZ2V0IHZhbHVlcyBmb3IuXG4gICAqIEByZXR1cm5zIHtPYmplY3R9IFJldHVybnMgdGhlIGtleS12YWx1ZSBwYWlycy5cbiAgICovXG4gIGZ1bmN0aW9uIGJhc2VUb1BhaXJzKG9iamVjdCwgcHJvcHMpIHtcbiAgICByZXR1cm4gYXJyYXlNYXAocHJvcHMsIGZ1bmN0aW9uKGtleSkge1xuICAgICAgcmV0dXJuIFtrZXksIG9iamVjdFtrZXldXTtcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy51bmFyeWAgd2l0aG91dCBzdXBwb3J0IGZvciBzdG9yaW5nIG1ldGFkYXRhLlxuICAgKlxuICAgKiBAcHJpdmF0ZVxuICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBmdW5jIFRoZSBmdW5jdGlvbiB0byBjYXAgYXJndW1lbnRzIGZvci5cbiAgICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBuZXcgY2FwcGVkIGZ1bmN0aW9uLlxuICAgKi9cbiAgZnVuY3Rpb24gYmFzZVVuYXJ5KGZ1bmMpIHtcbiAgICByZXR1cm4gZnVuY3Rpb24odmFsdWUpIHtcbiAgICAgIHJldHVybiBmdW5jKHZhbHVlKTtcbiAgICB9O1xuICB9XG5cbiAgLyoqXG4gICAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLnZhbHVlc2AgYW5kIGBfLnZhbHVlc0luYCB3aGljaCBjcmVhdGVzIGFuXG4gICAqIGFycmF5IG9mIGBvYmplY3RgIHByb3BlcnR5IHZhbHVlcyBjb3JyZXNwb25kaW5nIHRvIHRoZSBwcm9wZXJ0eSBuYW1lc1xuICAgKiBvZiBgcHJvcHNgLlxuICAgKlxuICAgKiBAcHJpdmF0ZVxuICAgKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gcXVlcnkuXG4gICAqIEBwYXJhbSB7QXJyYXl9IHByb3BzIFRoZSBwcm9wZXJ0eSBuYW1lcyB0byBnZXQgdmFsdWVzIGZvci5cbiAgICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyB0aGUgYXJyYXkgb2YgcHJvcGVydHkgdmFsdWVzLlxuICAgKi9cbiAgZnVuY3Rpb24gYmFzZVZhbHVlcyhvYmplY3QsIHByb3BzKSB7XG4gICAgcmV0dXJuIGFycmF5TWFwKHByb3BzLCBmdW5jdGlvbihrZXkpIHtcbiAgICAgIHJldHVybiBvYmplY3Rba2V5XTtcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDaGVja3MgaWYgYSBgY2FjaGVgIHZhbHVlIGZvciBga2V5YCBleGlzdHMuXG4gICAqXG4gICAqIEBwcml2YXRlXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBjYWNoZSBUaGUgY2FjaGUgdG8gcXVlcnkuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBrZXkgVGhlIGtleSBvZiB0aGUgZW50cnkgdG8gY2hlY2suXG4gICAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBhbiBlbnRyeSBmb3IgYGtleWAgZXhpc3RzLCBlbHNlIGBmYWxzZWAuXG4gICAqL1xuICBmdW5jdGlvbiBjYWNoZUhhcyhjYWNoZSwga2V5KSB7XG4gICAgcmV0dXJuIGNhY2hlLmhhcyhrZXkpO1xuICB9XG5cbiAgLyoqXG4gICAqIFVzZWQgYnkgYF8udHJpbWAgYW5kIGBfLnRyaW1TdGFydGAgdG8gZ2V0IHRoZSBpbmRleCBvZiB0aGUgZmlyc3Qgc3RyaW5nIHN5bWJvbFxuICAgKiB0aGF0IGlzIG5vdCBmb3VuZCBpbiB0aGUgY2hhcmFjdGVyIHN5bWJvbHMuXG4gICAqXG4gICAqIEBwcml2YXRlXG4gICAqIEBwYXJhbSB7QXJyYXl9IHN0clN5bWJvbHMgVGhlIHN0cmluZyBzeW1ib2xzIHRvIGluc3BlY3QuXG4gICAqIEBwYXJhbSB7QXJyYXl9IGNoclN5bWJvbHMgVGhlIGNoYXJhY3RlciBzeW1ib2xzIHRvIGZpbmQuXG4gICAqIEByZXR1cm5zIHtudW1iZXJ9IFJldHVybnMgdGhlIGluZGV4IG9mIHRoZSBmaXJzdCB1bm1hdGNoZWQgc3RyaW5nIHN5bWJvbC5cbiAgICovXG4gIGZ1bmN0aW9uIGNoYXJzU3RhcnRJbmRleChzdHJTeW1ib2xzLCBjaHJTeW1ib2xzKSB7XG4gICAgdmFyIGluZGV4ID0gLTEsXG4gICAgICAgIGxlbmd0aCA9IHN0clN5bWJvbHMubGVuZ3RoO1xuXG4gICAgd2hpbGUgKCsraW5kZXggPCBsZW5ndGggJiYgYmFzZUluZGV4T2YoY2hyU3ltYm9scywgc3RyU3ltYm9sc1tpbmRleF0sIDApID4gLTEpIHt9XG4gICAgcmV0dXJuIGluZGV4O1xuICB9XG5cbiAgLyoqXG4gICAqIFVzZWQgYnkgYF8udHJpbWAgYW5kIGBfLnRyaW1FbmRgIHRvIGdldCB0aGUgaW5kZXggb2YgdGhlIGxhc3Qgc3RyaW5nIHN5bWJvbFxuICAgKiB0aGF0IGlzIG5vdCBmb3VuZCBpbiB0aGUgY2hhcmFjdGVyIHN5bWJvbHMuXG4gICAqXG4gICAqIEBwcml2YXRlXG4gICAqIEBwYXJhbSB7QXJyYXl9IHN0clN5bWJvbHMgVGhlIHN0cmluZyBzeW1ib2xzIHRvIGluc3BlY3QuXG4gICAqIEBwYXJhbSB7QXJyYXl9IGNoclN5bWJvbHMgVGhlIGNoYXJhY3RlciBzeW1ib2xzIHRvIGZpbmQuXG4gICAqIEByZXR1cm5zIHtudW1iZXJ9IFJldHVybnMgdGhlIGluZGV4IG9mIHRoZSBsYXN0IHVubWF0Y2hlZCBzdHJpbmcgc3ltYm9sLlxuICAgKi9cbiAgZnVuY3Rpb24gY2hhcnNFbmRJbmRleChzdHJTeW1ib2xzLCBjaHJTeW1ib2xzKSB7XG4gICAgdmFyIGluZGV4ID0gc3RyU3ltYm9scy5sZW5ndGg7XG5cbiAgICB3aGlsZSAoaW5kZXgtLSAmJiBiYXNlSW5kZXhPZihjaHJTeW1ib2xzLCBzdHJTeW1ib2xzW2luZGV4XSwgMCkgPiAtMSkge31cbiAgICByZXR1cm4gaW5kZXg7XG4gIH1cblxuICAvKipcbiAgICogR2V0cyB0aGUgbnVtYmVyIG9mIGBwbGFjZWhvbGRlcmAgb2NjdXJyZW5jZXMgaW4gYGFycmF5YC5cbiAgICpcbiAgICogQHByaXZhdGVcbiAgICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIGluc3BlY3QuXG4gICAqIEBwYXJhbSB7Kn0gcGxhY2Vob2xkZXIgVGhlIHBsYWNlaG9sZGVyIHRvIHNlYXJjaCBmb3IuXG4gICAqIEByZXR1cm5zIHtudW1iZXJ9IFJldHVybnMgdGhlIHBsYWNlaG9sZGVyIGNvdW50LlxuICAgKi9cbiAgZnVuY3Rpb24gY291bnRIb2xkZXJzKGFycmF5LCBwbGFjZWhvbGRlcikge1xuICAgIHZhciBsZW5ndGggPSBhcnJheS5sZW5ndGgsXG4gICAgICAgIHJlc3VsdCA9IDA7XG5cbiAgICB3aGlsZSAobGVuZ3RoLS0pIHtcbiAgICAgIGlmIChhcnJheVtsZW5ndGhdID09PSBwbGFjZWhvbGRlcikge1xuICAgICAgICArK3Jlc3VsdDtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfVxuXG4gIC8qKlxuICAgKiBVc2VkIGJ5IGBfLmRlYnVycmAgdG8gY29udmVydCBMYXRpbi0xIFN1cHBsZW1lbnQgYW5kIExhdGluIEV4dGVuZGVkLUFcbiAgICogbGV0dGVycyB0byBiYXNpYyBMYXRpbiBsZXR0ZXJzLlxuICAgKlxuICAgKiBAcHJpdmF0ZVxuICAgKiBAcGFyYW0ge3N0cmluZ30gbGV0dGVyIFRoZSBtYXRjaGVkIGxldHRlciB0byBkZWJ1cnIuXG4gICAqIEByZXR1cm5zIHtzdHJpbmd9IFJldHVybnMgdGhlIGRlYnVycmVkIGxldHRlci5cbiAgICovXG4gIHZhciBkZWJ1cnJMZXR0ZXIgPSBiYXNlUHJvcGVydHlPZihkZWJ1cnJlZExldHRlcnMpO1xuXG4gIC8qKlxuICAgKiBVc2VkIGJ5IGBfLmVzY2FwZWAgdG8gY29udmVydCBjaGFyYWN0ZXJzIHRvIEhUTUwgZW50aXRpZXMuXG4gICAqXG4gICAqIEBwcml2YXRlXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBjaHIgVGhlIG1hdGNoZWQgY2hhcmFjdGVyIHRvIGVzY2FwZS5cbiAgICogQHJldHVybnMge3N0cmluZ30gUmV0dXJucyB0aGUgZXNjYXBlZCBjaGFyYWN0ZXIuXG4gICAqL1xuICB2YXIgZXNjYXBlSHRtbENoYXIgPSBiYXNlUHJvcGVydHlPZihodG1sRXNjYXBlcyk7XG5cbiAgLyoqXG4gICAqIFVzZWQgYnkgYF8udGVtcGxhdGVgIHRvIGVzY2FwZSBjaGFyYWN0ZXJzIGZvciBpbmNsdXNpb24gaW4gY29tcGlsZWQgc3RyaW5nIGxpdGVyYWxzLlxuICAgKlxuICAgKiBAcHJpdmF0ZVxuICAgKiBAcGFyYW0ge3N0cmluZ30gY2hyIFRoZSBtYXRjaGVkIGNoYXJhY3RlciB0byBlc2NhcGUuXG4gICAqIEByZXR1cm5zIHtzdHJpbmd9IFJldHVybnMgdGhlIGVzY2FwZWQgY2hhcmFjdGVyLlxuICAgKi9cbiAgZnVuY3Rpb24gZXNjYXBlU3RyaW5nQ2hhcihjaHIpIHtcbiAgICByZXR1cm4gJ1xcXFwnICsgc3RyaW5nRXNjYXBlc1tjaHJdO1xuICB9XG5cbiAgLyoqXG4gICAqIEdldHMgdGhlIHZhbHVlIGF0IGBrZXlgIG9mIGBvYmplY3RgLlxuICAgKlxuICAgKiBAcHJpdmF0ZVxuICAgKiBAcGFyYW0ge09iamVjdH0gW29iamVjdF0gVGhlIG9iamVjdCB0byBxdWVyeS5cbiAgICogQHBhcmFtIHtzdHJpbmd9IGtleSBUaGUga2V5IG9mIHRoZSBwcm9wZXJ0eSB0byBnZXQuXG4gICAqIEByZXR1cm5zIHsqfSBSZXR1cm5zIHRoZSBwcm9wZXJ0eSB2YWx1ZS5cbiAgICovXG4gIGZ1bmN0aW9uIGdldFZhbHVlKG9iamVjdCwga2V5KSB7XG4gICAgcmV0dXJuIG9iamVjdCA9PSBudWxsID8gdW5kZWZpbmVkIDogb2JqZWN0W2tleV07XG4gIH1cblxuICAvKipcbiAgICogQ2hlY2tzIGlmIGBzdHJpbmdgIGNvbnRhaW5zIFVuaWNvZGUgc3ltYm9scy5cbiAgICpcbiAgICogQHByaXZhdGVcbiAgICogQHBhcmFtIHtzdHJpbmd9IHN0cmluZyBUaGUgc3RyaW5nIHRvIGluc3BlY3QuXG4gICAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBhIHN5bWJvbCBpcyBmb3VuZCwgZWxzZSBgZmFsc2VgLlxuICAgKi9cbiAgZnVuY3Rpb24gaGFzVW5pY29kZShzdHJpbmcpIHtcbiAgICByZXR1cm4gcmVIYXNVbmljb2RlLnRlc3Qoc3RyaW5nKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDaGVja3MgaWYgYHN0cmluZ2AgY29udGFpbnMgYSB3b3JkIGNvbXBvc2VkIG9mIFVuaWNvZGUgc3ltYm9scy5cbiAgICpcbiAgICogQHByaXZhdGVcbiAgICogQHBhcmFtIHtzdHJpbmd9IHN0cmluZyBUaGUgc3RyaW5nIHRvIGluc3BlY3QuXG4gICAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBhIHdvcmQgaXMgZm91bmQsIGVsc2UgYGZhbHNlYC5cbiAgICovXG4gIGZ1bmN0aW9uIGhhc1VuaWNvZGVXb3JkKHN0cmluZykge1xuICAgIHJldHVybiByZUhhc1VuaWNvZGVXb3JkLnRlc3Qoc3RyaW5nKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDb252ZXJ0cyBgaXRlcmF0b3JgIHRvIGFuIGFycmF5LlxuICAgKlxuICAgKiBAcHJpdmF0ZVxuICAgKiBAcGFyYW0ge09iamVjdH0gaXRlcmF0b3IgVGhlIGl0ZXJhdG9yIHRvIGNvbnZlcnQuXG4gICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgY29udmVydGVkIGFycmF5LlxuICAgKi9cbiAgZnVuY3Rpb24gaXRlcmF0b3JUb0FycmF5KGl0ZXJhdG9yKSB7XG4gICAgdmFyIGRhdGEsXG4gICAgICAgIHJlc3VsdCA9IFtdO1xuXG4gICAgd2hpbGUgKCEoZGF0YSA9IGl0ZXJhdG9yLm5leHQoKSkuZG9uZSkge1xuICAgICAgcmVzdWx0LnB1c2goZGF0YS52YWx1ZSk7XG4gICAgfVxuICAgIHJldHVybiByZXN1bHQ7XG4gIH1cblxuICAvKipcbiAgICogQ29udmVydHMgYG1hcGAgdG8gaXRzIGtleS12YWx1ZSBwYWlycy5cbiAgICpcbiAgICogQHByaXZhdGVcbiAgICogQHBhcmFtIHtPYmplY3R9IG1hcCBUaGUgbWFwIHRvIGNvbnZlcnQuXG4gICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUga2V5LXZhbHVlIHBhaXJzLlxuICAgKi9cbiAgZnVuY3Rpb24gbWFwVG9BcnJheShtYXApIHtcbiAgICB2YXIgaW5kZXggPSAtMSxcbiAgICAgICAgcmVzdWx0ID0gQXJyYXkobWFwLnNpemUpO1xuXG4gICAgbWFwLmZvckVhY2goZnVuY3Rpb24odmFsdWUsIGtleSkge1xuICAgICAgcmVzdWx0WysraW5kZXhdID0gW2tleSwgdmFsdWVdO1xuICAgIH0pO1xuICAgIHJldHVybiByZXN1bHQ7XG4gIH1cblxuICAvKipcbiAgICogQ3JlYXRlcyBhIHVuYXJ5IGZ1bmN0aW9uIHRoYXQgaW52b2tlcyBgZnVuY2Agd2l0aCBpdHMgYXJndW1lbnQgdHJhbnNmb3JtZWQuXG4gICAqXG4gICAqIEBwcml2YXRlXG4gICAqIEBwYXJhbSB7RnVuY3Rpb259IGZ1bmMgVGhlIGZ1bmN0aW9uIHRvIHdyYXAuXG4gICAqIEBwYXJhbSB7RnVuY3Rpb259IHRyYW5zZm9ybSBUaGUgYXJndW1lbnQgdHJhbnNmb3JtLlxuICAgKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyBmdW5jdGlvbi5cbiAgICovXG4gIGZ1bmN0aW9uIG92ZXJBcmcoZnVuYywgdHJhbnNmb3JtKSB7XG4gICAgcmV0dXJuIGZ1bmN0aW9uKGFyZykge1xuICAgICAgcmV0dXJuIGZ1bmModHJhbnNmb3JtKGFyZykpO1xuICAgIH07XG4gIH1cblxuICAvKipcbiAgICogUmVwbGFjZXMgYWxsIGBwbGFjZWhvbGRlcmAgZWxlbWVudHMgaW4gYGFycmF5YCB3aXRoIGFuIGludGVybmFsIHBsYWNlaG9sZGVyXG4gICAqIGFuZCByZXR1cm5zIGFuIGFycmF5IG9mIHRoZWlyIGluZGV4ZXMuXG4gICAqXG4gICAqIEBwcml2YXRlXG4gICAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBhcnJheSB0byBtb2RpZnkuXG4gICAqIEBwYXJhbSB7Kn0gcGxhY2Vob2xkZXIgVGhlIHBsYWNlaG9sZGVyIHRvIHJlcGxhY2UuXG4gICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgbmV3IGFycmF5IG9mIHBsYWNlaG9sZGVyIGluZGV4ZXMuXG4gICAqL1xuICBmdW5jdGlvbiByZXBsYWNlSG9sZGVycyhhcnJheSwgcGxhY2Vob2xkZXIpIHtcbiAgICB2YXIgaW5kZXggPSAtMSxcbiAgICAgICAgbGVuZ3RoID0gYXJyYXkubGVuZ3RoLFxuICAgICAgICByZXNJbmRleCA9IDAsXG4gICAgICAgIHJlc3VsdCA9IFtdO1xuXG4gICAgd2hpbGUgKCsraW5kZXggPCBsZW5ndGgpIHtcbiAgICAgIHZhciB2YWx1ZSA9IGFycmF5W2luZGV4XTtcbiAgICAgIGlmICh2YWx1ZSA9PT0gcGxhY2Vob2xkZXIgfHwgdmFsdWUgPT09IFBMQUNFSE9MREVSKSB7XG4gICAgICAgIGFycmF5W2luZGV4XSA9IFBMQUNFSE9MREVSO1xuICAgICAgICByZXN1bHRbcmVzSW5kZXgrK10gPSBpbmRleDtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfVxuXG4gIC8qKlxuICAgKiBDb252ZXJ0cyBgc2V0YCB0byBhbiBhcnJheSBvZiBpdHMgdmFsdWVzLlxuICAgKlxuICAgKiBAcHJpdmF0ZVxuICAgKiBAcGFyYW0ge09iamVjdH0gc2V0IFRoZSBzZXQgdG8gY29udmVydC5cbiAgICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSB2YWx1ZXMuXG4gICAqL1xuICBmdW5jdGlvbiBzZXRUb0FycmF5KHNldCkge1xuICAgIHZhciBpbmRleCA9IC0xLFxuICAgICAgICByZXN1bHQgPSBBcnJheShzZXQuc2l6ZSk7XG5cbiAgICBzZXQuZm9yRWFjaChmdW5jdGlvbih2YWx1ZSkge1xuICAgICAgcmVzdWx0WysraW5kZXhdID0gdmFsdWU7XG4gICAgfSk7XG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfVxuXG4gIC8qKlxuICAgKiBDb252ZXJ0cyBgc2V0YCB0byBpdHMgdmFsdWUtdmFsdWUgcGFpcnMuXG4gICAqXG4gICAqIEBwcml2YXRlXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBzZXQgVGhlIHNldCB0byBjb252ZXJ0LlxuICAgKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIHZhbHVlLXZhbHVlIHBhaXJzLlxuICAgKi9cbiAgZnVuY3Rpb24gc2V0VG9QYWlycyhzZXQpIHtcbiAgICB2YXIgaW5kZXggPSAtMSxcbiAgICAgICAgcmVzdWx0ID0gQXJyYXkoc2V0LnNpemUpO1xuXG4gICAgc2V0LmZvckVhY2goZnVuY3Rpb24odmFsdWUpIHtcbiAgICAgIHJlc3VsdFsrK2luZGV4XSA9IFt2YWx1ZSwgdmFsdWVdO1xuICAgIH0pO1xuICAgIHJldHVybiByZXN1bHQ7XG4gIH1cblxuICAvKipcbiAgICogQSBzcGVjaWFsaXplZCB2ZXJzaW9uIG9mIGBfLmluZGV4T2ZgIHdoaWNoIHBlcmZvcm1zIHN0cmljdCBlcXVhbGl0eVxuICAgKiBjb21wYXJpc29ucyBvZiB2YWx1ZXMsIGkuZS4gYD09PWAuXG4gICAqXG4gICAqIEBwcml2YXRlXG4gICAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBhcnJheSB0byBpbnNwZWN0LlxuICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBzZWFyY2ggZm9yLlxuICAgKiBAcGFyYW0ge251bWJlcn0gZnJvbUluZGV4IFRoZSBpbmRleCB0byBzZWFyY2ggZnJvbS5cbiAgICogQHJldHVybnMge251bWJlcn0gUmV0dXJucyB0aGUgaW5kZXggb2YgdGhlIG1hdGNoZWQgdmFsdWUsIGVsc2UgYC0xYC5cbiAgICovXG4gIGZ1bmN0aW9uIHN0cmljdEluZGV4T2YoYXJyYXksIHZhbHVlLCBmcm9tSW5kZXgpIHtcbiAgICB2YXIgaW5kZXggPSBmcm9tSW5kZXggLSAxLFxuICAgICAgICBsZW5ndGggPSBhcnJheS5sZW5ndGg7XG5cbiAgICB3aGlsZSAoKytpbmRleCA8IGxlbmd0aCkge1xuICAgICAgaWYgKGFycmF5W2luZGV4XSA9PT0gdmFsdWUpIHtcbiAgICAgICAgcmV0dXJuIGluZGV4O1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gLTE7XG4gIH1cblxuICAvKipcbiAgICogQSBzcGVjaWFsaXplZCB2ZXJzaW9uIG9mIGBfLmxhc3RJbmRleE9mYCB3aGljaCBwZXJmb3JtcyBzdHJpY3QgZXF1YWxpdHlcbiAgICogY29tcGFyaXNvbnMgb2YgdmFsdWVzLCBpLmUuIGA9PT1gLlxuICAgKlxuICAgKiBAcHJpdmF0ZVxuICAgKiBAcGFyYW0ge0FycmF5fSBhcnJheSBUaGUgYXJyYXkgdG8gaW5zcGVjdC5cbiAgICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gc2VhcmNoIGZvci5cbiAgICogQHBhcmFtIHtudW1iZXJ9IGZyb21JbmRleCBUaGUgaW5kZXggdG8gc2VhcmNoIGZyb20uXG4gICAqIEByZXR1cm5zIHtudW1iZXJ9IFJldHVybnMgdGhlIGluZGV4IG9mIHRoZSBtYXRjaGVkIHZhbHVlLCBlbHNlIGAtMWAuXG4gICAqL1xuICBmdW5jdGlvbiBzdHJpY3RMYXN0SW5kZXhPZihhcnJheSwgdmFsdWUsIGZyb21JbmRleCkge1xuICAgIHZhciBpbmRleCA9IGZyb21JbmRleCArIDE7XG4gICAgd2hpbGUgKGluZGV4LS0pIHtcbiAgICAgIGlmIChhcnJheVtpbmRleF0gPT09IHZhbHVlKSB7XG4gICAgICAgIHJldHVybiBpbmRleDtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIGluZGV4O1xuICB9XG5cbiAgLyoqXG4gICAqIEdldHMgdGhlIG51bWJlciBvZiBzeW1ib2xzIGluIGBzdHJpbmdgLlxuICAgKlxuICAgKiBAcHJpdmF0ZVxuICAgKiBAcGFyYW0ge3N0cmluZ30gc3RyaW5nIFRoZSBzdHJpbmcgdG8gaW5zcGVjdC5cbiAgICogQHJldHVybnMge251bWJlcn0gUmV0dXJucyB0aGUgc3RyaW5nIHNpemUuXG4gICAqL1xuICBmdW5jdGlvbiBzdHJpbmdTaXplKHN0cmluZykge1xuICAgIHJldHVybiBoYXNVbmljb2RlKHN0cmluZylcbiAgICAgID8gdW5pY29kZVNpemUoc3RyaW5nKVxuICAgICAgOiBhc2NpaVNpemUoc3RyaW5nKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDb252ZXJ0cyBgc3RyaW5nYCB0byBhbiBhcnJheS5cbiAgICpcbiAgICogQHByaXZhdGVcbiAgICogQHBhcmFtIHtzdHJpbmd9IHN0cmluZyBUaGUgc3RyaW5nIHRvIGNvbnZlcnQuXG4gICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgY29udmVydGVkIGFycmF5LlxuICAgKi9cbiAgZnVuY3Rpb24gc3RyaW5nVG9BcnJheShzdHJpbmcpIHtcbiAgICByZXR1cm4gaGFzVW5pY29kZShzdHJpbmcpXG4gICAgICA/IHVuaWNvZGVUb0FycmF5KHN0cmluZylcbiAgICAgIDogYXNjaWlUb0FycmF5KHN0cmluZyk7XG4gIH1cblxuICAvKipcbiAgICogVXNlZCBieSBgXy51bmVzY2FwZWAgdG8gY29udmVydCBIVE1MIGVudGl0aWVzIHRvIGNoYXJhY3RlcnMuXG4gICAqXG4gICAqIEBwcml2YXRlXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBjaHIgVGhlIG1hdGNoZWQgY2hhcmFjdGVyIHRvIHVuZXNjYXBlLlxuICAgKiBAcmV0dXJucyB7c3RyaW5nfSBSZXR1cm5zIHRoZSB1bmVzY2FwZWQgY2hhcmFjdGVyLlxuICAgKi9cbiAgdmFyIHVuZXNjYXBlSHRtbENoYXIgPSBiYXNlUHJvcGVydHlPZihodG1sVW5lc2NhcGVzKTtcblxuICAvKipcbiAgICogR2V0cyB0aGUgc2l6ZSBvZiBhIFVuaWNvZGUgYHN0cmluZ2AuXG4gICAqXG4gICAqIEBwcml2YXRlXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBzdHJpbmcgVGhlIHN0cmluZyBpbnNwZWN0LlxuICAgKiBAcmV0dXJucyB7bnVtYmVyfSBSZXR1cm5zIHRoZSBzdHJpbmcgc2l6ZS5cbiAgICovXG4gIGZ1bmN0aW9uIHVuaWNvZGVTaXplKHN0cmluZykge1xuICAgIHZhciByZXN1bHQgPSByZVVuaWNvZGUubGFzdEluZGV4ID0gMDtcbiAgICB3aGlsZSAocmVVbmljb2RlLnRlc3Qoc3RyaW5nKSkge1xuICAgICAgKytyZXN1bHQ7XG4gICAgfVxuICAgIHJldHVybiByZXN1bHQ7XG4gIH1cblxuICAvKipcbiAgICogQ29udmVydHMgYSBVbmljb2RlIGBzdHJpbmdgIHRvIGFuIGFycmF5LlxuICAgKlxuICAgKiBAcHJpdmF0ZVxuICAgKiBAcGFyYW0ge3N0cmluZ30gc3RyaW5nIFRoZSBzdHJpbmcgdG8gY29udmVydC5cbiAgICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBjb252ZXJ0ZWQgYXJyYXkuXG4gICAqL1xuICBmdW5jdGlvbiB1bmljb2RlVG9BcnJheShzdHJpbmcpIHtcbiAgICByZXR1cm4gc3RyaW5nLm1hdGNoKHJlVW5pY29kZSkgfHwgW107XG4gIH1cblxuICAvKipcbiAgICogU3BsaXRzIGEgVW5pY29kZSBgc3RyaW5nYCBpbnRvIGFuIGFycmF5IG9mIGl0cyB3b3Jkcy5cbiAgICpcbiAgICogQHByaXZhdGVcbiAgICogQHBhcmFtIHtzdHJpbmd9IFRoZSBzdHJpbmcgdG8gaW5zcGVjdC5cbiAgICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSB3b3JkcyBvZiBgc3RyaW5nYC5cbiAgICovXG4gIGZ1bmN0aW9uIHVuaWNvZGVXb3JkcyhzdHJpbmcpIHtcbiAgICByZXR1cm4gc3RyaW5nLm1hdGNoKHJlVW5pY29kZVdvcmQpIHx8IFtdO1xuICB9XG5cbiAgLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovXG5cbiAgLyoqXG4gICAqIENyZWF0ZSBhIG5ldyBwcmlzdGluZSBgbG9kYXNoYCBmdW5jdGlvbiB1c2luZyB0aGUgYGNvbnRleHRgIG9iamVjdC5cbiAgICpcbiAgICogQHN0YXRpY1xuICAgKiBAbWVtYmVyT2YgX1xuICAgKiBAc2luY2UgMS4xLjBcbiAgICogQGNhdGVnb3J5IFV0aWxcbiAgICogQHBhcmFtIHtPYmplY3R9IFtjb250ZXh0PXJvb3RdIFRoZSBjb250ZXh0IG9iamVjdC5cbiAgICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIGEgbmV3IGBsb2Rhc2hgIGZ1bmN0aW9uLlxuICAgKiBAZXhhbXBsZVxuICAgKlxuICAgKiBfLm1peGluKHsgJ2Zvbyc6IF8uY29uc3RhbnQoJ2ZvbycpIH0pO1xuICAgKlxuICAgKiB2YXIgbG9kYXNoID0gXy5ydW5JbkNvbnRleHQoKTtcbiAgICogbG9kYXNoLm1peGluKHsgJ2Jhcic6IGxvZGFzaC5jb25zdGFudCgnYmFyJykgfSk7XG4gICAqXG4gICAqIF8uaXNGdW5jdGlvbihfLmZvbyk7XG4gICAqIC8vID0+IHRydWVcbiAgICogXy5pc0Z1bmN0aW9uKF8uYmFyKTtcbiAgICogLy8gPT4gZmFsc2VcbiAgICpcbiAgICogbG9kYXNoLmlzRnVuY3Rpb24obG9kYXNoLmZvbyk7XG4gICAqIC8vID0+IGZhbHNlXG4gICAqIGxvZGFzaC5pc0Z1bmN0aW9uKGxvZGFzaC5iYXIpO1xuICAgKiAvLyA9PiB0cnVlXG4gICAqXG4gICAqIC8vIENyZWF0ZSBhIHN1cGVkLXVwIGBkZWZlcmAgaW4gTm9kZS5qcy5cbiAgICogdmFyIGRlZmVyID0gXy5ydW5JbkNvbnRleHQoeyAnc2V0VGltZW91dCc6IHNldEltbWVkaWF0ZSB9KS5kZWZlcjtcbiAgICovXG4gIHZhciBydW5JbkNvbnRleHQgPSAoZnVuY3Rpb24gcnVuSW5Db250ZXh0KGNvbnRleHQpIHtcbiAgICBjb250ZXh0ID0gY29udGV4dCA9PSBudWxsID8gcm9vdCA6IF8uZGVmYXVsdHMocm9vdC5PYmplY3QoKSwgY29udGV4dCwgXy5waWNrKHJvb3QsIGNvbnRleHRQcm9wcykpO1xuXG4gICAgLyoqIEJ1aWx0LWluIGNvbnN0cnVjdG9yIHJlZmVyZW5jZXMuICovXG4gICAgdmFyIEFycmF5ID0gY29udGV4dC5BcnJheSxcbiAgICAgICAgRGF0ZSA9IGNvbnRleHQuRGF0ZSxcbiAgICAgICAgRXJyb3IgPSBjb250ZXh0LkVycm9yLFxuICAgICAgICBGdW5jdGlvbiA9IGNvbnRleHQuRnVuY3Rpb24sXG4gICAgICAgIE1hdGggPSBjb250ZXh0Lk1hdGgsXG4gICAgICAgIE9iamVjdCA9IGNvbnRleHQuT2JqZWN0LFxuICAgICAgICBSZWdFeHAgPSBjb250ZXh0LlJlZ0V4cCxcbiAgICAgICAgU3RyaW5nID0gY29udGV4dC5TdHJpbmcsXG4gICAgICAgIFR5cGVFcnJvciA9IGNvbnRleHQuVHlwZUVycm9yO1xuXG4gICAgLyoqIFVzZWQgZm9yIGJ1aWx0LWluIG1ldGhvZCByZWZlcmVuY2VzLiAqL1xuICAgIHZhciBhcnJheVByb3RvID0gQXJyYXkucHJvdG90eXBlLFxuICAgICAgICBmdW5jUHJvdG8gPSBGdW5jdGlvbi5wcm90b3R5cGUsXG4gICAgICAgIG9iamVjdFByb3RvID0gT2JqZWN0LnByb3RvdHlwZTtcblxuICAgIC8qKiBVc2VkIHRvIGRldGVjdCBvdmVycmVhY2hpbmcgY29yZS1qcyBzaGltcy4gKi9cbiAgICB2YXIgY29yZUpzRGF0YSA9IGNvbnRleHRbJ19fY29yZS1qc19zaGFyZWRfXyddO1xuXG4gICAgLyoqIFVzZWQgdG8gcmVzb2x2ZSB0aGUgZGVjb21waWxlZCBzb3VyY2Ugb2YgZnVuY3Rpb25zLiAqL1xuICAgIHZhciBmdW5jVG9TdHJpbmcgPSBmdW5jUHJvdG8udG9TdHJpbmc7XG5cbiAgICAvKiogVXNlZCB0byBjaGVjayBvYmplY3RzIGZvciBvd24gcHJvcGVydGllcy4gKi9cbiAgICB2YXIgaGFzT3duUHJvcGVydHkgPSBvYmplY3RQcm90by5oYXNPd25Qcm9wZXJ0eTtcblxuICAgIC8qKiBVc2VkIHRvIGdlbmVyYXRlIHVuaXF1ZSBJRHMuICovXG4gICAgdmFyIGlkQ291bnRlciA9IDA7XG5cbiAgICAvKiogVXNlZCB0byBkZXRlY3QgbWV0aG9kcyBtYXNxdWVyYWRpbmcgYXMgbmF0aXZlLiAqL1xuICAgIHZhciBtYXNrU3JjS2V5ID0gKGZ1bmN0aW9uKCkge1xuICAgICAgdmFyIHVpZCA9IC9bXi5dKyQvLmV4ZWMoY29yZUpzRGF0YSAmJiBjb3JlSnNEYXRhLmtleXMgJiYgY29yZUpzRGF0YS5rZXlzLklFX1BST1RPIHx8ICcnKTtcbiAgICAgIHJldHVybiB1aWQgPyAoJ1N5bWJvbChzcmMpXzEuJyArIHVpZCkgOiAnJztcbiAgICB9KCkpO1xuXG4gICAgLyoqXG4gICAgICogVXNlZCB0byByZXNvbHZlIHRoZVxuICAgICAqIFtgdG9TdHJpbmdUYWdgXShodHRwOi8vZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi83LjAvI3NlYy1vYmplY3QucHJvdG90eXBlLnRvc3RyaW5nKVxuICAgICAqIG9mIHZhbHVlcy5cbiAgICAgKi9cbiAgICB2YXIgbmF0aXZlT2JqZWN0VG9TdHJpbmcgPSBvYmplY3RQcm90by50b1N0cmluZztcblxuICAgIC8qKiBVc2VkIHRvIGluZmVyIHRoZSBgT2JqZWN0YCBjb25zdHJ1Y3Rvci4gKi9cbiAgICB2YXIgb2JqZWN0Q3RvclN0cmluZyA9IGZ1bmNUb1N0cmluZy5jYWxsKE9iamVjdCk7XG5cbiAgICAvKiogVXNlZCB0byByZXN0b3JlIHRoZSBvcmlnaW5hbCBgX2AgcmVmZXJlbmNlIGluIGBfLm5vQ29uZmxpY3RgLiAqL1xuICAgIHZhciBvbGREYXNoID0gcm9vdC5fO1xuXG4gICAgLyoqIFVzZWQgdG8gZGV0ZWN0IGlmIGEgbWV0aG9kIGlzIG5hdGl2ZS4gKi9cbiAgICB2YXIgcmVJc05hdGl2ZSA9IFJlZ0V4cCgnXicgK1xuICAgICAgZnVuY1RvU3RyaW5nLmNhbGwoaGFzT3duUHJvcGVydHkpLnJlcGxhY2UocmVSZWdFeHBDaGFyLCAnXFxcXCQmJylcbiAgICAgIC5yZXBsYWNlKC9oYXNPd25Qcm9wZXJ0eXwoZnVuY3Rpb24pLio/KD89XFxcXFxcKCl8IGZvciAuKz8oPz1cXFxcXFxdKS9nLCAnJDEuKj8nKSArICckJ1xuICAgICk7XG5cbiAgICAvKiogQnVpbHQtaW4gdmFsdWUgcmVmZXJlbmNlcy4gKi9cbiAgICB2YXIgQnVmZmVyID0gbW9kdWxlRXhwb3J0cyA/IGNvbnRleHQuQnVmZmVyIDogdW5kZWZpbmVkLFxuICAgICAgICBTeW1ib2wgPSBjb250ZXh0LlN5bWJvbCxcbiAgICAgICAgVWludDhBcnJheSA9IGNvbnRleHQuVWludDhBcnJheSxcbiAgICAgICAgYWxsb2NVbnNhZmUgPSBCdWZmZXIgPyBCdWZmZXIuYWxsb2NVbnNhZmUgOiB1bmRlZmluZWQsXG4gICAgICAgIGdldFByb3RvdHlwZSA9IG92ZXJBcmcoT2JqZWN0LmdldFByb3RvdHlwZU9mLCBPYmplY3QpLFxuICAgICAgICBvYmplY3RDcmVhdGUgPSBPYmplY3QuY3JlYXRlLFxuICAgICAgICBwcm9wZXJ0eUlzRW51bWVyYWJsZSA9IG9iamVjdFByb3RvLnByb3BlcnR5SXNFbnVtZXJhYmxlLFxuICAgICAgICBzcGxpY2UgPSBhcnJheVByb3RvLnNwbGljZSxcbiAgICAgICAgc3ByZWFkYWJsZVN5bWJvbCA9IFN5bWJvbCA/IFN5bWJvbC5pc0NvbmNhdFNwcmVhZGFibGUgOiB1bmRlZmluZWQsXG4gICAgICAgIHN5bUl0ZXJhdG9yID0gU3ltYm9sID8gU3ltYm9sLml0ZXJhdG9yIDogdW5kZWZpbmVkLFxuICAgICAgICBzeW1Ub1N0cmluZ1RhZyA9IFN5bWJvbCA/IFN5bWJvbC50b1N0cmluZ1RhZyA6IHVuZGVmaW5lZDtcblxuICAgIHZhciBkZWZpbmVQcm9wZXJ0eSA9IChmdW5jdGlvbigpIHtcbiAgICAgIHRyeSB7XG4gICAgICAgIHZhciBmdW5jID0gZ2V0TmF0aXZlKE9iamVjdCwgJ2RlZmluZVByb3BlcnR5Jyk7XG4gICAgICAgIGZ1bmMoe30sICcnLCB7fSk7XG4gICAgICAgIHJldHVybiBmdW5jO1xuICAgICAgfSBjYXRjaCAoZSkge31cbiAgICB9KCkpO1xuXG4gICAgLyoqIE1vY2tlZCBidWlsdC1pbnMuICovXG4gICAgdmFyIGN0eENsZWFyVGltZW91dCA9IGNvbnRleHQuY2xlYXJUaW1lb3V0ICE9PSByb290LmNsZWFyVGltZW91dCAmJiBjb250ZXh0LmNsZWFyVGltZW91dCxcbiAgICAgICAgY3R4Tm93ID0gRGF0ZSAmJiBEYXRlLm5vdyAhPT0gcm9vdC5EYXRlLm5vdyAmJiBEYXRlLm5vdyxcbiAgICAgICAgY3R4U2V0VGltZW91dCA9IGNvbnRleHQuc2V0VGltZW91dCAhPT0gcm9vdC5zZXRUaW1lb3V0ICYmIGNvbnRleHQuc2V0VGltZW91dDtcblxuICAgIC8qIEJ1aWx0LWluIG1ldGhvZCByZWZlcmVuY2VzIGZvciB0aG9zZSB3aXRoIHRoZSBzYW1lIG5hbWUgYXMgb3RoZXIgYGxvZGFzaGAgbWV0aG9kcy4gKi9cbiAgICB2YXIgbmF0aXZlQ2VpbCA9IE1hdGguY2VpbCxcbiAgICAgICAgbmF0aXZlRmxvb3IgPSBNYXRoLmZsb29yLFxuICAgICAgICBuYXRpdmVHZXRTeW1ib2xzID0gT2JqZWN0LmdldE93blByb3BlcnR5U3ltYm9scyxcbiAgICAgICAgbmF0aXZlSXNCdWZmZXIgPSBCdWZmZXIgPyBCdWZmZXIuaXNCdWZmZXIgOiB1bmRlZmluZWQsXG4gICAgICAgIG5hdGl2ZUlzRmluaXRlID0gY29udGV4dC5pc0Zpbml0ZSxcbiAgICAgICAgbmF0aXZlSm9pbiA9IGFycmF5UHJvdG8uam9pbixcbiAgICAgICAgbmF0aXZlS2V5cyA9IG92ZXJBcmcoT2JqZWN0LmtleXMsIE9iamVjdCksXG4gICAgICAgIG5hdGl2ZU1heCA9IE1hdGgubWF4LFxuICAgICAgICBuYXRpdmVNaW4gPSBNYXRoLm1pbixcbiAgICAgICAgbmF0aXZlTm93ID0gRGF0ZS5ub3csXG4gICAgICAgIG5hdGl2ZVBhcnNlSW50ID0gY29udGV4dC5wYXJzZUludCxcbiAgICAgICAgbmF0aXZlUmFuZG9tID0gTWF0aC5yYW5kb20sXG4gICAgICAgIG5hdGl2ZVJldmVyc2UgPSBhcnJheVByb3RvLnJldmVyc2U7XG5cbiAgICAvKiBCdWlsdC1pbiBtZXRob2QgcmVmZXJlbmNlcyB0aGF0IGFyZSB2ZXJpZmllZCB0byBiZSBuYXRpdmUuICovXG4gICAgdmFyIERhdGFWaWV3ID0gZ2V0TmF0aXZlKGNvbnRleHQsICdEYXRhVmlldycpLFxuICAgICAgICBNYXAgPSBnZXROYXRpdmUoY29udGV4dCwgJ01hcCcpLFxuICAgICAgICBQcm9taXNlID0gZ2V0TmF0aXZlKGNvbnRleHQsICdQcm9taXNlJyksXG4gICAgICAgIFNldCA9IGdldE5hdGl2ZShjb250ZXh0LCAnU2V0JyksXG4gICAgICAgIFdlYWtNYXAgPSBnZXROYXRpdmUoY29udGV4dCwgJ1dlYWtNYXAnKSxcbiAgICAgICAgbmF0aXZlQ3JlYXRlID0gZ2V0TmF0aXZlKE9iamVjdCwgJ2NyZWF0ZScpO1xuXG4gICAgLyoqIFVzZWQgdG8gc3RvcmUgZnVuY3Rpb24gbWV0YWRhdGEuICovXG4gICAgdmFyIG1ldGFNYXAgPSBXZWFrTWFwICYmIG5ldyBXZWFrTWFwO1xuXG4gICAgLyoqIFVzZWQgdG8gbG9va3VwIHVubWluaWZpZWQgZnVuY3Rpb24gbmFtZXMuICovXG4gICAgdmFyIHJlYWxOYW1lcyA9IHt9O1xuXG4gICAgLyoqIFVzZWQgdG8gZGV0ZWN0IG1hcHMsIHNldHMsIGFuZCB3ZWFrbWFwcy4gKi9cbiAgICB2YXIgZGF0YVZpZXdDdG9yU3RyaW5nID0gdG9Tb3VyY2UoRGF0YVZpZXcpLFxuICAgICAgICBtYXBDdG9yU3RyaW5nID0gdG9Tb3VyY2UoTWFwKSxcbiAgICAgICAgcHJvbWlzZUN0b3JTdHJpbmcgPSB0b1NvdXJjZShQcm9taXNlKSxcbiAgICAgICAgc2V0Q3RvclN0cmluZyA9IHRvU291cmNlKFNldCksXG4gICAgICAgIHdlYWtNYXBDdG9yU3RyaW5nID0gdG9Tb3VyY2UoV2Vha01hcCk7XG5cbiAgICAvKiogVXNlZCB0byBjb252ZXJ0IHN5bWJvbHMgdG8gcHJpbWl0aXZlcyBhbmQgc3RyaW5ncy4gKi9cbiAgICB2YXIgc3ltYm9sUHJvdG8gPSBTeW1ib2wgPyBTeW1ib2wucHJvdG90eXBlIDogdW5kZWZpbmVkLFxuICAgICAgICBzeW1ib2xWYWx1ZU9mID0gc3ltYm9sUHJvdG8gPyBzeW1ib2xQcm90by52YWx1ZU9mIDogdW5kZWZpbmVkLFxuICAgICAgICBzeW1ib2xUb1N0cmluZyA9IHN5bWJvbFByb3RvID8gc3ltYm9sUHJvdG8udG9TdHJpbmcgOiB1bmRlZmluZWQ7XG5cbiAgICAvKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovXG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgYGxvZGFzaGAgb2JqZWN0IHdoaWNoIHdyYXBzIGB2YWx1ZWAgdG8gZW5hYmxlIGltcGxpY2l0IG1ldGhvZFxuICAgICAqIGNoYWluIHNlcXVlbmNlcy4gTWV0aG9kcyB0aGF0IG9wZXJhdGUgb24gYW5kIHJldHVybiBhcnJheXMsIGNvbGxlY3Rpb25zLFxuICAgICAqIGFuZCBmdW5jdGlvbnMgY2FuIGJlIGNoYWluZWQgdG9nZXRoZXIuIE1ldGhvZHMgdGhhdCByZXRyaWV2ZSBhIHNpbmdsZSB2YWx1ZVxuICAgICAqIG9yIG1heSByZXR1cm4gYSBwcmltaXRpdmUgdmFsdWUgd2lsbCBhdXRvbWF0aWNhbGx5IGVuZCB0aGUgY2hhaW4gc2VxdWVuY2VcbiAgICAgKiBhbmQgcmV0dXJuIHRoZSB1bndyYXBwZWQgdmFsdWUuIE90aGVyd2lzZSwgdGhlIHZhbHVlIG11c3QgYmUgdW53cmFwcGVkXG4gICAgICogd2l0aCBgXyN2YWx1ZWAuXG4gICAgICpcbiAgICAgKiBFeHBsaWNpdCBjaGFpbiBzZXF1ZW5jZXMsIHdoaWNoIG11c3QgYmUgdW53cmFwcGVkIHdpdGggYF8jdmFsdWVgLCBtYXkgYmVcbiAgICAgKiBlbmFibGVkIHVzaW5nIGBfLmNoYWluYC5cbiAgICAgKlxuICAgICAqIFRoZSBleGVjdXRpb24gb2YgY2hhaW5lZCBtZXRob2RzIGlzIGxhenksIHRoYXQgaXMsIGl0J3MgZGVmZXJyZWQgdW50aWxcbiAgICAgKiBgXyN2YWx1ZWAgaXMgaW1wbGljaXRseSBvciBleHBsaWNpdGx5IGNhbGxlZC5cbiAgICAgKlxuICAgICAqIExhenkgZXZhbHVhdGlvbiBhbGxvd3Mgc2V2ZXJhbCBtZXRob2RzIHRvIHN1cHBvcnQgc2hvcnRjdXQgZnVzaW9uLlxuICAgICAqIFNob3J0Y3V0IGZ1c2lvbiBpcyBhbiBvcHRpbWl6YXRpb24gdG8gbWVyZ2UgaXRlcmF0ZWUgY2FsbHM7IHRoaXMgYXZvaWRzXG4gICAgICogdGhlIGNyZWF0aW9uIG9mIGludGVybWVkaWF0ZSBhcnJheXMgYW5kIGNhbiBncmVhdGx5IHJlZHVjZSB0aGUgbnVtYmVyIG9mXG4gICAgICogaXRlcmF0ZWUgZXhlY3V0aW9ucy4gU2VjdGlvbnMgb2YgYSBjaGFpbiBzZXF1ZW5jZSBxdWFsaWZ5IGZvciBzaG9ydGN1dFxuICAgICAqIGZ1c2lvbiBpZiB0aGUgc2VjdGlvbiBpcyBhcHBsaWVkIHRvIGFuIGFycmF5IGFuZCBpdGVyYXRlZXMgYWNjZXB0IG9ubHlcbiAgICAgKiBvbmUgYXJndW1lbnQuIFRoZSBoZXVyaXN0aWMgZm9yIHdoZXRoZXIgYSBzZWN0aW9uIHF1YWxpZmllcyBmb3Igc2hvcnRjdXRcbiAgICAgKiBmdXNpb24gaXMgc3ViamVjdCB0byBjaGFuZ2UuXG4gICAgICpcbiAgICAgKiBDaGFpbmluZyBpcyBzdXBwb3J0ZWQgaW4gY3VzdG9tIGJ1aWxkcyBhcyBsb25nIGFzIHRoZSBgXyN2YWx1ZWAgbWV0aG9kIGlzXG4gICAgICogZGlyZWN0bHkgb3IgaW5kaXJlY3RseSBpbmNsdWRlZCBpbiB0aGUgYnVpbGQuXG4gICAgICpcbiAgICAgKiBJbiBhZGRpdGlvbiB0byBsb2Rhc2ggbWV0aG9kcywgd3JhcHBlcnMgaGF2ZSBgQXJyYXlgIGFuZCBgU3RyaW5nYCBtZXRob2RzLlxuICAgICAqXG4gICAgICogVGhlIHdyYXBwZXIgYEFycmF5YCBtZXRob2RzIGFyZTpcbiAgICAgKiBgY29uY2F0YCwgYGpvaW5gLCBgcG9wYCwgYHB1c2hgLCBgc2hpZnRgLCBgc29ydGAsIGBzcGxpY2VgLCBhbmQgYHVuc2hpZnRgXG4gICAgICpcbiAgICAgKiBUaGUgd3JhcHBlciBgU3RyaW5nYCBtZXRob2RzIGFyZTpcbiAgICAgKiBgcmVwbGFjZWAgYW5kIGBzcGxpdGBcbiAgICAgKlxuICAgICAqIFRoZSB3cmFwcGVyIG1ldGhvZHMgdGhhdCBzdXBwb3J0IHNob3J0Y3V0IGZ1c2lvbiBhcmU6XG4gICAgICogYGF0YCwgYGNvbXBhY3RgLCBgZHJvcGAsIGBkcm9wUmlnaHRgLCBgZHJvcFdoaWxlYCwgYGZpbHRlcmAsIGBmaW5kYCxcbiAgICAgKiBgZmluZExhc3RgLCBgaGVhZGAsIGBpbml0aWFsYCwgYGxhc3RgLCBgbWFwYCwgYHJlamVjdGAsIGByZXZlcnNlYCwgYHNsaWNlYCxcbiAgICAgKiBgdGFpbGAsIGB0YWtlYCwgYHRha2VSaWdodGAsIGB0YWtlUmlnaHRXaGlsZWAsIGB0YWtlV2hpbGVgLCBhbmQgYHRvQXJyYXlgXG4gICAgICpcbiAgICAgKiBUaGUgY2hhaW5hYmxlIHdyYXBwZXIgbWV0aG9kcyBhcmU6XG4gICAgICogYGFmdGVyYCwgYGFyeWAsIGBhc3NpZ25gLCBgYXNzaWduSW5gLCBgYXNzaWduSW5XaXRoYCwgYGFzc2lnbldpdGhgLCBgYXRgLFxuICAgICAqIGBiZWZvcmVgLCBgYmluZGAsIGBiaW5kQWxsYCwgYGJpbmRLZXlgLCBgY2FzdEFycmF5YCwgYGNoYWluYCwgYGNodW5rYCxcbiAgICAgKiBgY29tbWl0YCwgYGNvbXBhY3RgLCBgY29uY2F0YCwgYGNvbmZvcm1zYCwgYGNvbnN0YW50YCwgYGNvdW50QnlgLCBgY3JlYXRlYCxcbiAgICAgKiBgY3VycnlgLCBgZGVib3VuY2VgLCBgZGVmYXVsdHNgLCBgZGVmYXVsdHNEZWVwYCwgYGRlZmVyYCwgYGRlbGF5YCxcbiAgICAgKiBgZGlmZmVyZW5jZWAsIGBkaWZmZXJlbmNlQnlgLCBgZGlmZmVyZW5jZVdpdGhgLCBgZHJvcGAsIGBkcm9wUmlnaHRgLFxuICAgICAqIGBkcm9wUmlnaHRXaGlsZWAsIGBkcm9wV2hpbGVgLCBgZXh0ZW5kYCwgYGV4dGVuZFdpdGhgLCBgZmlsbGAsIGBmaWx0ZXJgLFxuICAgICAqIGBmbGF0TWFwYCwgYGZsYXRNYXBEZWVwYCwgYGZsYXRNYXBEZXB0aGAsIGBmbGF0dGVuYCwgYGZsYXR0ZW5EZWVwYCxcbiAgICAgKiBgZmxhdHRlbkRlcHRoYCwgYGZsaXBgLCBgZmxvd2AsIGBmbG93UmlnaHRgLCBgZnJvbVBhaXJzYCwgYGZ1bmN0aW9uc2AsXG4gICAgICogYGZ1bmN0aW9uc0luYCwgYGdyb3VwQnlgLCBgaW5pdGlhbGAsIGBpbnRlcnNlY3Rpb25gLCBgaW50ZXJzZWN0aW9uQnlgLFxuICAgICAqIGBpbnRlcnNlY3Rpb25XaXRoYCwgYGludmVydGAsIGBpbnZlcnRCeWAsIGBpbnZva2VNYXBgLCBgaXRlcmF0ZWVgLCBga2V5QnlgLFxuICAgICAqIGBrZXlzYCwgYGtleXNJbmAsIGBtYXBgLCBgbWFwS2V5c2AsIGBtYXBWYWx1ZXNgLCBgbWF0Y2hlc2AsIGBtYXRjaGVzUHJvcGVydHlgLFxuICAgICAqIGBtZW1vaXplYCwgYG1lcmdlYCwgYG1lcmdlV2l0aGAsIGBtZXRob2RgLCBgbWV0aG9kT2ZgLCBgbWl4aW5gLCBgbmVnYXRlYCxcbiAgICAgKiBgbnRoQXJnYCwgYG9taXRgLCBgb21pdEJ5YCwgYG9uY2VgLCBgb3JkZXJCeWAsIGBvdmVyYCwgYG92ZXJBcmdzYCxcbiAgICAgKiBgb3ZlckV2ZXJ5YCwgYG92ZXJTb21lYCwgYHBhcnRpYWxgLCBgcGFydGlhbFJpZ2h0YCwgYHBhcnRpdGlvbmAsIGBwaWNrYCxcbiAgICAgKiBgcGlja0J5YCwgYHBsYW50YCwgYHByb3BlcnR5YCwgYHByb3BlcnR5T2ZgLCBgcHVsbGAsIGBwdWxsQWxsYCwgYHB1bGxBbGxCeWAsXG4gICAgICogYHB1bGxBbGxXaXRoYCwgYHB1bGxBdGAsIGBwdXNoYCwgYHJhbmdlYCwgYHJhbmdlUmlnaHRgLCBgcmVhcmdgLCBgcmVqZWN0YCxcbiAgICAgKiBgcmVtb3ZlYCwgYHJlc3RgLCBgcmV2ZXJzZWAsIGBzYW1wbGVTaXplYCwgYHNldGAsIGBzZXRXaXRoYCwgYHNodWZmbGVgLFxuICAgICAqIGBzbGljZWAsIGBzb3J0YCwgYHNvcnRCeWAsIGBzcGxpY2VgLCBgc3ByZWFkYCwgYHRhaWxgLCBgdGFrZWAsIGB0YWtlUmlnaHRgLFxuICAgICAqIGB0YWtlUmlnaHRXaGlsZWAsIGB0YWtlV2hpbGVgLCBgdGFwYCwgYHRocm90dGxlYCwgYHRocnVgLCBgdG9BcnJheWAsXG4gICAgICogYHRvUGFpcnNgLCBgdG9QYWlyc0luYCwgYHRvUGF0aGAsIGB0b1BsYWluT2JqZWN0YCwgYHRyYW5zZm9ybWAsIGB1bmFyeWAsXG4gICAgICogYHVuaW9uYCwgYHVuaW9uQnlgLCBgdW5pb25XaXRoYCwgYHVuaXFgLCBgdW5pcUJ5YCwgYHVuaXFXaXRoYCwgYHVuc2V0YCxcbiAgICAgKiBgdW5zaGlmdGAsIGB1bnppcGAsIGB1bnppcFdpdGhgLCBgdXBkYXRlYCwgYHVwZGF0ZVdpdGhgLCBgdmFsdWVzYCxcbiAgICAgKiBgdmFsdWVzSW5gLCBgd2l0aG91dGAsIGB3cmFwYCwgYHhvcmAsIGB4b3JCeWAsIGB4b3JXaXRoYCwgYHppcGAsXG4gICAgICogYHppcE9iamVjdGAsIGB6aXBPYmplY3REZWVwYCwgYW5kIGB6aXBXaXRoYFxuICAgICAqXG4gICAgICogVGhlIHdyYXBwZXIgbWV0aG9kcyB0aGF0IGFyZSAqKm5vdCoqIGNoYWluYWJsZSBieSBkZWZhdWx0IGFyZTpcbiAgICAgKiBgYWRkYCwgYGF0dGVtcHRgLCBgY2FtZWxDYXNlYCwgYGNhcGl0YWxpemVgLCBgY2VpbGAsIGBjbGFtcGAsIGBjbG9uZWAsXG4gICAgICogYGNsb25lRGVlcGAsIGBjbG9uZURlZXBXaXRoYCwgYGNsb25lV2l0aGAsIGBjb25mb3Jtc1RvYCwgYGRlYnVycmAsXG4gICAgICogYGRlZmF1bHRUb2AsIGBkaXZpZGVgLCBgZWFjaGAsIGBlYWNoUmlnaHRgLCBgZW5kc1dpdGhgLCBgZXFgLCBgZXNjYXBlYCxcbiAgICAgKiBgZXNjYXBlUmVnRXhwYCwgYGV2ZXJ5YCwgYGZpbmRgLCBgZmluZEluZGV4YCwgYGZpbmRLZXlgLCBgZmluZExhc3RgLFxuICAgICAqIGBmaW5kTGFzdEluZGV4YCwgYGZpbmRMYXN0S2V5YCwgYGZpcnN0YCwgYGZsb29yYCwgYGZvckVhY2hgLCBgZm9yRWFjaFJpZ2h0YCxcbiAgICAgKiBgZm9ySW5gLCBgZm9ySW5SaWdodGAsIGBmb3JPd25gLCBgZm9yT3duUmlnaHRgLCBgZ2V0YCwgYGd0YCwgYGd0ZWAsIGBoYXNgLFxuICAgICAqIGBoYXNJbmAsIGBoZWFkYCwgYGlkZW50aXR5YCwgYGluY2x1ZGVzYCwgYGluZGV4T2ZgLCBgaW5SYW5nZWAsIGBpbnZva2VgLFxuICAgICAqIGBpc0FyZ3VtZW50c2AsIGBpc0FycmF5YCwgYGlzQXJyYXlCdWZmZXJgLCBgaXNBcnJheUxpa2VgLCBgaXNBcnJheUxpa2VPYmplY3RgLFxuICAgICAqIGBpc0Jvb2xlYW5gLCBgaXNCdWZmZXJgLCBgaXNEYXRlYCwgYGlzRWxlbWVudGAsIGBpc0VtcHR5YCwgYGlzRXF1YWxgLFxuICAgICAqIGBpc0VxdWFsV2l0aGAsIGBpc0Vycm9yYCwgYGlzRmluaXRlYCwgYGlzRnVuY3Rpb25gLCBgaXNJbnRlZ2VyYCwgYGlzTGVuZ3RoYCxcbiAgICAgKiBgaXNNYXBgLCBgaXNNYXRjaGAsIGBpc01hdGNoV2l0aGAsIGBpc05hTmAsIGBpc05hdGl2ZWAsIGBpc05pbGAsIGBpc051bGxgLFxuICAgICAqIGBpc051bWJlcmAsIGBpc09iamVjdGAsIGBpc09iamVjdExpa2VgLCBgaXNQbGFpbk9iamVjdGAsIGBpc1JlZ0V4cGAsXG4gICAgICogYGlzU2FmZUludGVnZXJgLCBgaXNTZXRgLCBgaXNTdHJpbmdgLCBgaXNVbmRlZmluZWRgLCBgaXNUeXBlZEFycmF5YCxcbiAgICAgKiBgaXNXZWFrTWFwYCwgYGlzV2Vha1NldGAsIGBqb2luYCwgYGtlYmFiQ2FzZWAsIGBsYXN0YCwgYGxhc3RJbmRleE9mYCxcbiAgICAgKiBgbG93ZXJDYXNlYCwgYGxvd2VyRmlyc3RgLCBgbHRgLCBgbHRlYCwgYG1heGAsIGBtYXhCeWAsIGBtZWFuYCwgYG1lYW5CeWAsXG4gICAgICogYG1pbmAsIGBtaW5CeWAsIGBtdWx0aXBseWAsIGBub0NvbmZsaWN0YCwgYG5vb3BgLCBgbm93YCwgYG50aGAsIGBwYWRgLFxuICAgICAqIGBwYWRFbmRgLCBgcGFkU3RhcnRgLCBgcGFyc2VJbnRgLCBgcG9wYCwgYHJhbmRvbWAsIGByZWR1Y2VgLCBgcmVkdWNlUmlnaHRgLFxuICAgICAqIGByZXBlYXRgLCBgcmVzdWx0YCwgYHJvdW5kYCwgYHJ1bkluQ29udGV4dGAsIGBzYW1wbGVgLCBgc2hpZnRgLCBgc2l6ZWAsXG4gICAgICogYHNuYWtlQ2FzZWAsIGBzb21lYCwgYHNvcnRlZEluZGV4YCwgYHNvcnRlZEluZGV4QnlgLCBgc29ydGVkTGFzdEluZGV4YCxcbiAgICAgKiBgc29ydGVkTGFzdEluZGV4QnlgLCBgc3RhcnRDYXNlYCwgYHN0YXJ0c1dpdGhgLCBgc3R1YkFycmF5YCwgYHN0dWJGYWxzZWAsXG4gICAgICogYHN0dWJPYmplY3RgLCBgc3R1YlN0cmluZ2AsIGBzdHViVHJ1ZWAsIGBzdWJ0cmFjdGAsIGBzdW1gLCBgc3VtQnlgLFxuICAgICAqIGB0ZW1wbGF0ZWAsIGB0aW1lc2AsIGB0b0Zpbml0ZWAsIGB0b0ludGVnZXJgLCBgdG9KU09OYCwgYHRvTGVuZ3RoYCxcbiAgICAgKiBgdG9Mb3dlcmAsIGB0b051bWJlcmAsIGB0b1NhZmVJbnRlZ2VyYCwgYHRvU3RyaW5nYCwgYHRvVXBwZXJgLCBgdHJpbWAsXG4gICAgICogYHRyaW1FbmRgLCBgdHJpbVN0YXJ0YCwgYHRydW5jYXRlYCwgYHVuZXNjYXBlYCwgYHVuaXF1ZUlkYCwgYHVwcGVyQ2FzZWAsXG4gICAgICogYHVwcGVyRmlyc3RgLCBgdmFsdWVgLCBhbmQgYHdvcmRzYFxuICAgICAqXG4gICAgICogQG5hbWUgX1xuICAgICAqIEBjb25zdHJ1Y3RvclxuICAgICAqIEBjYXRlZ29yeSBTZXFcbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byB3cmFwIGluIGEgYGxvZGFzaGAgaW5zdGFuY2UuXG4gICAgICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyB0aGUgbmV3IGBsb2Rhc2hgIHdyYXBwZXIgaW5zdGFuY2UuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIGZ1bmN0aW9uIHNxdWFyZShuKSB7XG4gICAgICogICByZXR1cm4gbiAqIG47XG4gICAgICogfVxuICAgICAqXG4gICAgICogdmFyIHdyYXBwZWQgPSBfKFsxLCAyLCAzXSk7XG4gICAgICpcbiAgICAgKiAvLyBSZXR1cm5zIGFuIHVud3JhcHBlZCB2YWx1ZS5cbiAgICAgKiB3cmFwcGVkLnJlZHVjZShfLmFkZCk7XG4gICAgICogLy8gPT4gNlxuICAgICAqXG4gICAgICogLy8gUmV0dXJucyBhIHdyYXBwZWQgdmFsdWUuXG4gICAgICogdmFyIHNxdWFyZXMgPSB3cmFwcGVkLm1hcChzcXVhcmUpO1xuICAgICAqXG4gICAgICogXy5pc0FycmF5KHNxdWFyZXMpO1xuICAgICAqIC8vID0+IGZhbHNlXG4gICAgICpcbiAgICAgKiBfLmlzQXJyYXkoc3F1YXJlcy52YWx1ZSgpKTtcbiAgICAgKiAvLyA9PiB0cnVlXG4gICAgICovXG4gICAgZnVuY3Rpb24gbG9kYXNoKHZhbHVlKSB7XG4gICAgICBpZiAoaXNPYmplY3RMaWtlKHZhbHVlKSAmJiAhaXNBcnJheSh2YWx1ZSkgJiYgISh2YWx1ZSBpbnN0YW5jZW9mIExhenlXcmFwcGVyKSkge1xuICAgICAgICBpZiAodmFsdWUgaW5zdGFuY2VvZiBMb2Rhc2hXcmFwcGVyKSB7XG4gICAgICAgICAgcmV0dXJuIHZhbHVlO1xuICAgICAgICB9XG4gICAgICAgIGlmIChoYXNPd25Qcm9wZXJ0eS5jYWxsKHZhbHVlLCAnX193cmFwcGVkX18nKSkge1xuICAgICAgICAgIHJldHVybiB3cmFwcGVyQ2xvbmUodmFsdWUpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICByZXR1cm4gbmV3IExvZGFzaFdyYXBwZXIodmFsdWUpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLmNyZWF0ZWAgd2l0aG91dCBzdXBwb3J0IGZvciBhc3NpZ25pbmdcbiAgICAgKiBwcm9wZXJ0aWVzIHRvIHRoZSBjcmVhdGVkIG9iamVjdC5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtPYmplY3R9IHByb3RvIFRoZSBvYmplY3QgdG8gaW5oZXJpdCBmcm9tLlxuICAgICAqIEByZXR1cm5zIHtPYmplY3R9IFJldHVybnMgdGhlIG5ldyBvYmplY3QuXG4gICAgICovXG4gICAgdmFyIGJhc2VDcmVhdGUgPSAoZnVuY3Rpb24oKSB7XG4gICAgICBmdW5jdGlvbiBvYmplY3QoKSB7fVxuICAgICAgcmV0dXJuIGZ1bmN0aW9uKHByb3RvKSB7XG4gICAgICAgIGlmICghaXNPYmplY3QocHJvdG8pKSB7XG4gICAgICAgICAgcmV0dXJuIHt9O1xuICAgICAgICB9XG4gICAgICAgIGlmIChvYmplY3RDcmVhdGUpIHtcbiAgICAgICAgICByZXR1cm4gb2JqZWN0Q3JlYXRlKHByb3RvKTtcbiAgICAgICAgfVxuICAgICAgICBvYmplY3QucHJvdG90eXBlID0gcHJvdG87XG4gICAgICAgIHZhciByZXN1bHQgPSBuZXcgb2JqZWN0O1xuICAgICAgICBvYmplY3QucHJvdG90eXBlID0gdW5kZWZpbmVkO1xuICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgICAgfTtcbiAgICB9KCkpO1xuXG4gICAgLyoqXG4gICAgICogVGhlIGZ1bmN0aW9uIHdob3NlIHByb3RvdHlwZSBjaGFpbiBzZXF1ZW5jZSB3cmFwcGVycyBpbmhlcml0IGZyb20uXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGJhc2VMb2Rhc2goKSB7XG4gICAgICAvLyBObyBvcGVyYXRpb24gcGVyZm9ybWVkLlxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoZSBiYXNlIGNvbnN0cnVjdG9yIGZvciBjcmVhdGluZyBgbG9kYXNoYCB3cmFwcGVyIG9iamVjdHMuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIHdyYXAuXG4gICAgICogQHBhcmFtIHtib29sZWFufSBbY2hhaW5BbGxdIEVuYWJsZSBleHBsaWNpdCBtZXRob2QgY2hhaW4gc2VxdWVuY2VzLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIExvZGFzaFdyYXBwZXIodmFsdWUsIGNoYWluQWxsKSB7XG4gICAgICB0aGlzLl9fd3JhcHBlZF9fID0gdmFsdWU7XG4gICAgICB0aGlzLl9fYWN0aW9uc19fID0gW107XG4gICAgICB0aGlzLl9fY2hhaW5fXyA9ICEhY2hhaW5BbGw7XG4gICAgICB0aGlzLl9faW5kZXhfXyA9IDA7XG4gICAgICB0aGlzLl9fdmFsdWVzX18gPSB1bmRlZmluZWQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQnkgZGVmYXVsdCwgdGhlIHRlbXBsYXRlIGRlbGltaXRlcnMgdXNlZCBieSBsb2Rhc2ggYXJlIGxpa2UgdGhvc2UgaW5cbiAgICAgKiBlbWJlZGRlZCBSdWJ5IChFUkIpIGFzIHdlbGwgYXMgRVMyMDE1IHRlbXBsYXRlIHN0cmluZ3MuIENoYW5nZSB0aGVcbiAgICAgKiBmb2xsb3dpbmcgdGVtcGxhdGUgc2V0dGluZ3MgdG8gdXNlIGFsdGVybmF0aXZlIGRlbGltaXRlcnMuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAdHlwZSB7T2JqZWN0fVxuICAgICAqL1xuICAgIGxvZGFzaC50ZW1wbGF0ZVNldHRpbmdzID0ge1xuXG4gICAgICAvKipcbiAgICAgICAqIFVzZWQgdG8gZGV0ZWN0IGBkYXRhYCBwcm9wZXJ0eSB2YWx1ZXMgdG8gYmUgSFRNTC1lc2NhcGVkLlxuICAgICAgICpcbiAgICAgICAqIEBtZW1iZXJPZiBfLnRlbXBsYXRlU2V0dGluZ3NcbiAgICAgICAqIEB0eXBlIHtSZWdFeHB9XG4gICAgICAgKi9cbiAgICAgICdlc2NhcGUnOiByZUVzY2FwZSxcblxuICAgICAgLyoqXG4gICAgICAgKiBVc2VkIHRvIGRldGVjdCBjb2RlIHRvIGJlIGV2YWx1YXRlZC5cbiAgICAgICAqXG4gICAgICAgKiBAbWVtYmVyT2YgXy50ZW1wbGF0ZVNldHRpbmdzXG4gICAgICAgKiBAdHlwZSB7UmVnRXhwfVxuICAgICAgICovXG4gICAgICAnZXZhbHVhdGUnOiByZUV2YWx1YXRlLFxuXG4gICAgICAvKipcbiAgICAgICAqIFVzZWQgdG8gZGV0ZWN0IGBkYXRhYCBwcm9wZXJ0eSB2YWx1ZXMgdG8gaW5qZWN0LlxuICAgICAgICpcbiAgICAgICAqIEBtZW1iZXJPZiBfLnRlbXBsYXRlU2V0dGluZ3NcbiAgICAgICAqIEB0eXBlIHtSZWdFeHB9XG4gICAgICAgKi9cbiAgICAgICdpbnRlcnBvbGF0ZSc6IHJlSW50ZXJwb2xhdGUsXG5cbiAgICAgIC8qKlxuICAgICAgICogVXNlZCB0byByZWZlcmVuY2UgdGhlIGRhdGEgb2JqZWN0IGluIHRoZSB0ZW1wbGF0ZSB0ZXh0LlxuICAgICAgICpcbiAgICAgICAqIEBtZW1iZXJPZiBfLnRlbXBsYXRlU2V0dGluZ3NcbiAgICAgICAqIEB0eXBlIHtzdHJpbmd9XG4gICAgICAgKi9cbiAgICAgICd2YXJpYWJsZSc6ICcnLFxuXG4gICAgICAvKipcbiAgICAgICAqIFVzZWQgdG8gaW1wb3J0IHZhcmlhYmxlcyBpbnRvIHRoZSBjb21waWxlZCB0ZW1wbGF0ZS5cbiAgICAgICAqXG4gICAgICAgKiBAbWVtYmVyT2YgXy50ZW1wbGF0ZVNldHRpbmdzXG4gICAgICAgKiBAdHlwZSB7T2JqZWN0fVxuICAgICAgICovXG4gICAgICAnaW1wb3J0cyc6IHtcblxuICAgICAgICAvKipcbiAgICAgICAgICogQSByZWZlcmVuY2UgdG8gdGhlIGBsb2Rhc2hgIGZ1bmN0aW9uLlxuICAgICAgICAgKlxuICAgICAgICAgKiBAbWVtYmVyT2YgXy50ZW1wbGF0ZVNldHRpbmdzLmltcG9ydHNcbiAgICAgICAgICogQHR5cGUge0Z1bmN0aW9ufVxuICAgICAgICAgKi9cbiAgICAgICAgJ18nOiBsb2Rhc2hcbiAgICAgIH1cbiAgICB9O1xuXG4gICAgLy8gRW5zdXJlIHdyYXBwZXJzIGFyZSBpbnN0YW5jZXMgb2YgYGJhc2VMb2Rhc2hgLlxuICAgIGxvZGFzaC5wcm90b3R5cGUgPSBiYXNlTG9kYXNoLnByb3RvdHlwZTtcbiAgICBsb2Rhc2gucHJvdG90eXBlLmNvbnN0cnVjdG9yID0gbG9kYXNoO1xuXG4gICAgTG9kYXNoV3JhcHBlci5wcm90b3R5cGUgPSBiYXNlQ3JlYXRlKGJhc2VMb2Rhc2gucHJvdG90eXBlKTtcbiAgICBMb2Rhc2hXcmFwcGVyLnByb3RvdHlwZS5jb25zdHJ1Y3RvciA9IExvZGFzaFdyYXBwZXI7XG5cbiAgICAvKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovXG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgbGF6eSB3cmFwcGVyIG9iamVjdCB3aGljaCB3cmFwcyBgdmFsdWVgIHRvIGVuYWJsZSBsYXp5IGV2YWx1YXRpb24uXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBjb25zdHJ1Y3RvclxuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIHdyYXAuXG4gICAgICovXG4gICAgZnVuY3Rpb24gTGF6eVdyYXBwZXIodmFsdWUpIHtcbiAgICAgIHRoaXMuX193cmFwcGVkX18gPSB2YWx1ZTtcbiAgICAgIHRoaXMuX19hY3Rpb25zX18gPSBbXTtcbiAgICAgIHRoaXMuX19kaXJfXyA9IDE7XG4gICAgICB0aGlzLl9fZmlsdGVyZWRfXyA9IGZhbHNlO1xuICAgICAgdGhpcy5fX2l0ZXJhdGVlc19fID0gW107XG4gICAgICB0aGlzLl9fdGFrZUNvdW50X18gPSBNQVhfQVJSQVlfTEVOR1RIO1xuICAgICAgdGhpcy5fX3ZpZXdzX18gPSBbXTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgY2xvbmUgb2YgdGhlIGxhenkgd3JhcHBlciBvYmplY3QuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBuYW1lIGNsb25lXG4gICAgICogQG1lbWJlck9mIExhenlXcmFwcGVyXG4gICAgICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyB0aGUgY2xvbmVkIGBMYXp5V3JhcHBlcmAgb2JqZWN0LlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGxhenlDbG9uZSgpIHtcbiAgICAgIHZhciByZXN1bHQgPSBuZXcgTGF6eVdyYXBwZXIodGhpcy5fX3dyYXBwZWRfXyk7XG4gICAgICByZXN1bHQuX19hY3Rpb25zX18gPSBjb3B5QXJyYXkodGhpcy5fX2FjdGlvbnNfXyk7XG4gICAgICByZXN1bHQuX19kaXJfXyA9IHRoaXMuX19kaXJfXztcbiAgICAgIHJlc3VsdC5fX2ZpbHRlcmVkX18gPSB0aGlzLl9fZmlsdGVyZWRfXztcbiAgICAgIHJlc3VsdC5fX2l0ZXJhdGVlc19fID0gY29weUFycmF5KHRoaXMuX19pdGVyYXRlZXNfXyk7XG4gICAgICByZXN1bHQuX190YWtlQ291bnRfXyA9IHRoaXMuX190YWtlQ291bnRfXztcbiAgICAgIHJlc3VsdC5fX3ZpZXdzX18gPSBjb3B5QXJyYXkodGhpcy5fX3ZpZXdzX18pO1xuICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBSZXZlcnNlcyB0aGUgZGlyZWN0aW9uIG9mIGxhenkgaXRlcmF0aW9uLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAbmFtZSByZXZlcnNlXG4gICAgICogQG1lbWJlck9mIExhenlXcmFwcGVyXG4gICAgICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyB0aGUgbmV3IHJldmVyc2VkIGBMYXp5V3JhcHBlcmAgb2JqZWN0LlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGxhenlSZXZlcnNlKCkge1xuICAgICAgaWYgKHRoaXMuX19maWx0ZXJlZF9fKSB7XG4gICAgICAgIHZhciByZXN1bHQgPSBuZXcgTGF6eVdyYXBwZXIodGhpcyk7XG4gICAgICAgIHJlc3VsdC5fX2Rpcl9fID0gLTE7XG4gICAgICAgIHJlc3VsdC5fX2ZpbHRlcmVkX18gPSB0cnVlO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmVzdWx0ID0gdGhpcy5jbG9uZSgpO1xuICAgICAgICByZXN1bHQuX19kaXJfXyAqPSAtMTtcbiAgICAgIH1cbiAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogRXh0cmFjdHMgdGhlIHVud3JhcHBlZCB2YWx1ZSBmcm9tIGl0cyBsYXp5IHdyYXBwZXIuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBuYW1lIHZhbHVlXG4gICAgICogQG1lbWJlck9mIExhenlXcmFwcGVyXG4gICAgICogQHJldHVybnMgeyp9IFJldHVybnMgdGhlIHVud3JhcHBlZCB2YWx1ZS5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBsYXp5VmFsdWUoKSB7XG4gICAgICB2YXIgYXJyYXkgPSB0aGlzLl9fd3JhcHBlZF9fLnZhbHVlKCksXG4gICAgICAgICAgZGlyID0gdGhpcy5fX2Rpcl9fLFxuICAgICAgICAgIGlzQXJyID0gaXNBcnJheShhcnJheSksXG4gICAgICAgICAgaXNSaWdodCA9IGRpciA8IDAsXG4gICAgICAgICAgYXJyTGVuZ3RoID0gaXNBcnIgPyBhcnJheS5sZW5ndGggOiAwLFxuICAgICAgICAgIHZpZXcgPSBnZXRWaWV3KDAsIGFyckxlbmd0aCwgdGhpcy5fX3ZpZXdzX18pLFxuICAgICAgICAgIHN0YXJ0ID0gdmlldy5zdGFydCxcbiAgICAgICAgICBlbmQgPSB2aWV3LmVuZCxcbiAgICAgICAgICBsZW5ndGggPSBlbmQgLSBzdGFydCxcbiAgICAgICAgICBpbmRleCA9IGlzUmlnaHQgPyBlbmQgOiAoc3RhcnQgLSAxKSxcbiAgICAgICAgICBpdGVyYXRlZXMgPSB0aGlzLl9faXRlcmF0ZWVzX18sXG4gICAgICAgICAgaXRlckxlbmd0aCA9IGl0ZXJhdGVlcy5sZW5ndGgsXG4gICAgICAgICAgcmVzSW5kZXggPSAwLFxuICAgICAgICAgIHRha2VDb3VudCA9IG5hdGl2ZU1pbihsZW5ndGgsIHRoaXMuX190YWtlQ291bnRfXyk7XG5cbiAgICAgIGlmICghaXNBcnIgfHwgKCFpc1JpZ2h0ICYmIGFyckxlbmd0aCA9PSBsZW5ndGggJiYgdGFrZUNvdW50ID09IGxlbmd0aCkpIHtcbiAgICAgICAgcmV0dXJuIGJhc2VXcmFwcGVyVmFsdWUoYXJyYXksIHRoaXMuX19hY3Rpb25zX18pO1xuICAgICAgfVxuICAgICAgdmFyIHJlc3VsdCA9IFtdO1xuXG4gICAgICBvdXRlcjpcbiAgICAgIHdoaWxlIChsZW5ndGgtLSAmJiByZXNJbmRleCA8IHRha2VDb3VudCkge1xuICAgICAgICBpbmRleCArPSBkaXI7XG5cbiAgICAgICAgdmFyIGl0ZXJJbmRleCA9IC0xLFxuICAgICAgICAgICAgdmFsdWUgPSBhcnJheVtpbmRleF07XG5cbiAgICAgICAgd2hpbGUgKCsraXRlckluZGV4IDwgaXRlckxlbmd0aCkge1xuICAgICAgICAgIHZhciBkYXRhID0gaXRlcmF0ZWVzW2l0ZXJJbmRleF0sXG4gICAgICAgICAgICAgIGl0ZXJhdGVlID0gZGF0YS5pdGVyYXRlZSxcbiAgICAgICAgICAgICAgdHlwZSA9IGRhdGEudHlwZSxcbiAgICAgICAgICAgICAgY29tcHV0ZWQgPSBpdGVyYXRlZSh2YWx1ZSk7XG5cbiAgICAgICAgICBpZiAodHlwZSA9PSBMQVpZX01BUF9GTEFHKSB7XG4gICAgICAgICAgICB2YWx1ZSA9IGNvbXB1dGVkO1xuICAgICAgICAgIH0gZWxzZSBpZiAoIWNvbXB1dGVkKSB7XG4gICAgICAgICAgICBpZiAodHlwZSA9PSBMQVpZX0ZJTFRFUl9GTEFHKSB7XG4gICAgICAgICAgICAgIGNvbnRpbnVlIG91dGVyO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgYnJlYWsgb3V0ZXI7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJlc3VsdFtyZXNJbmRleCsrXSA9IHZhbHVlO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9XG5cbiAgICAvLyBFbnN1cmUgYExhenlXcmFwcGVyYCBpcyBhbiBpbnN0YW5jZSBvZiBgYmFzZUxvZGFzaGAuXG4gICAgTGF6eVdyYXBwZXIucHJvdG90eXBlID0gYmFzZUNyZWF0ZShiYXNlTG9kYXNoLnByb3RvdHlwZSk7XG4gICAgTGF6eVdyYXBwZXIucHJvdG90eXBlLmNvbnN0cnVjdG9yID0gTGF6eVdyYXBwZXI7XG5cbiAgICAvKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovXG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgaGFzaCBvYmplY3QuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBjb25zdHJ1Y3RvclxuICAgICAqIEBwYXJhbSB7QXJyYXl9IFtlbnRyaWVzXSBUaGUga2V5LXZhbHVlIHBhaXJzIHRvIGNhY2hlLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIEhhc2goZW50cmllcykge1xuICAgICAgdmFyIGluZGV4ID0gLTEsXG4gICAgICAgICAgbGVuZ3RoID0gZW50cmllcyA9PSBudWxsID8gMCA6IGVudHJpZXMubGVuZ3RoO1xuXG4gICAgICB0aGlzLmNsZWFyKCk7XG4gICAgICB3aGlsZSAoKytpbmRleCA8IGxlbmd0aCkge1xuICAgICAgICB2YXIgZW50cnkgPSBlbnRyaWVzW2luZGV4XTtcbiAgICAgICAgdGhpcy5zZXQoZW50cnlbMF0sIGVudHJ5WzFdKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBSZW1vdmVzIGFsbCBrZXktdmFsdWUgZW50cmllcyBmcm9tIHRoZSBoYXNoLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAbmFtZSBjbGVhclxuICAgICAqIEBtZW1iZXJPZiBIYXNoXG4gICAgICovXG4gICAgZnVuY3Rpb24gaGFzaENsZWFyKCkge1xuICAgICAgdGhpcy5fX2RhdGFfXyA9IG5hdGl2ZUNyZWF0ZSA/IG5hdGl2ZUNyZWF0ZShudWxsKSA6IHt9O1xuICAgICAgdGhpcy5zaXplID0gMDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBSZW1vdmVzIGBrZXlgIGFuZCBpdHMgdmFsdWUgZnJvbSB0aGUgaGFzaC5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQG5hbWUgZGVsZXRlXG4gICAgICogQG1lbWJlck9mIEhhc2hcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gaGFzaCBUaGUgaGFzaCB0byBtb2RpZnkuXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IGtleSBUaGUga2V5IG9mIHRoZSB2YWx1ZSB0byByZW1vdmUuXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIHRoZSBlbnRyeSB3YXMgcmVtb3ZlZCwgZWxzZSBgZmFsc2VgLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGhhc2hEZWxldGUoa2V5KSB7XG4gICAgICB2YXIgcmVzdWx0ID0gdGhpcy5oYXMoa2V5KSAmJiBkZWxldGUgdGhpcy5fX2RhdGFfX1trZXldO1xuICAgICAgdGhpcy5zaXplIC09IHJlc3VsdCA/IDEgOiAwO1xuICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBHZXRzIHRoZSBoYXNoIHZhbHVlIGZvciBga2V5YC5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQG5hbWUgZ2V0XG4gICAgICogQG1lbWJlck9mIEhhc2hcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30ga2V5IFRoZSBrZXkgb2YgdGhlIHZhbHVlIHRvIGdldC5cbiAgICAgKiBAcmV0dXJucyB7Kn0gUmV0dXJucyB0aGUgZW50cnkgdmFsdWUuXG4gICAgICovXG4gICAgZnVuY3Rpb24gaGFzaEdldChrZXkpIHtcbiAgICAgIHZhciBkYXRhID0gdGhpcy5fX2RhdGFfXztcbiAgICAgIGlmIChuYXRpdmVDcmVhdGUpIHtcbiAgICAgICAgdmFyIHJlc3VsdCA9IGRhdGFba2V5XTtcbiAgICAgICAgcmV0dXJuIHJlc3VsdCA9PT0gSEFTSF9VTkRFRklORUQgPyB1bmRlZmluZWQgOiByZXN1bHQ7XG4gICAgICB9XG4gICAgICByZXR1cm4gaGFzT3duUHJvcGVydHkuY2FsbChkYXRhLCBrZXkpID8gZGF0YVtrZXldIDogdW5kZWZpbmVkO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENoZWNrcyBpZiBhIGhhc2ggdmFsdWUgZm9yIGBrZXlgIGV4aXN0cy5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQG5hbWUgaGFzXG4gICAgICogQG1lbWJlck9mIEhhc2hcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30ga2V5IFRoZSBrZXkgb2YgdGhlIGVudHJ5IHRvIGNoZWNrLlxuICAgICAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBhbiBlbnRyeSBmb3IgYGtleWAgZXhpc3RzLCBlbHNlIGBmYWxzZWAuXG4gICAgICovXG4gICAgZnVuY3Rpb24gaGFzaEhhcyhrZXkpIHtcbiAgICAgIHZhciBkYXRhID0gdGhpcy5fX2RhdGFfXztcbiAgICAgIHJldHVybiBuYXRpdmVDcmVhdGUgPyAoZGF0YVtrZXldICE9PSB1bmRlZmluZWQpIDogaGFzT3duUHJvcGVydHkuY2FsbChkYXRhLCBrZXkpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFNldHMgdGhlIGhhc2ggYGtleWAgdG8gYHZhbHVlYC5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQG5hbWUgc2V0XG4gICAgICogQG1lbWJlck9mIEhhc2hcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30ga2V5IFRoZSBrZXkgb2YgdGhlIHZhbHVlIHRvIHNldC5cbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBzZXQuXG4gICAgICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyB0aGUgaGFzaCBpbnN0YW5jZS5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBoYXNoU2V0KGtleSwgdmFsdWUpIHtcbiAgICAgIHZhciBkYXRhID0gdGhpcy5fX2RhdGFfXztcbiAgICAgIHRoaXMuc2l6ZSArPSB0aGlzLmhhcyhrZXkpID8gMCA6IDE7XG4gICAgICBkYXRhW2tleV0gPSAobmF0aXZlQ3JlYXRlICYmIHZhbHVlID09PSB1bmRlZmluZWQpID8gSEFTSF9VTkRFRklORUQgOiB2YWx1ZTtcbiAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8vIEFkZCBtZXRob2RzIHRvIGBIYXNoYC5cbiAgICBIYXNoLnByb3RvdHlwZS5jbGVhciA9IGhhc2hDbGVhcjtcbiAgICBIYXNoLnByb3RvdHlwZVsnZGVsZXRlJ10gPSBoYXNoRGVsZXRlO1xuICAgIEhhc2gucHJvdG90eXBlLmdldCA9IGhhc2hHZXQ7XG4gICAgSGFzaC5wcm90b3R5cGUuaGFzID0gaGFzaEhhcztcbiAgICBIYXNoLnByb3RvdHlwZS5zZXQgPSBoYXNoU2V0O1xuXG4gICAgLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qL1xuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhbiBsaXN0IGNhY2hlIG9iamVjdC5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQGNvbnN0cnVjdG9yXG4gICAgICogQHBhcmFtIHtBcnJheX0gW2VudHJpZXNdIFRoZSBrZXktdmFsdWUgcGFpcnMgdG8gY2FjaGUuXG4gICAgICovXG4gICAgZnVuY3Rpb24gTGlzdENhY2hlKGVudHJpZXMpIHtcbiAgICAgIHZhciBpbmRleCA9IC0xLFxuICAgICAgICAgIGxlbmd0aCA9IGVudHJpZXMgPT0gbnVsbCA/IDAgOiBlbnRyaWVzLmxlbmd0aDtcblxuICAgICAgdGhpcy5jbGVhcigpO1xuICAgICAgd2hpbGUgKCsraW5kZXggPCBsZW5ndGgpIHtcbiAgICAgICAgdmFyIGVudHJ5ID0gZW50cmllc1tpbmRleF07XG4gICAgICAgIHRoaXMuc2V0KGVudHJ5WzBdLCBlbnRyeVsxXSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUmVtb3ZlcyBhbGwga2V5LXZhbHVlIGVudHJpZXMgZnJvbSB0aGUgbGlzdCBjYWNoZS5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQG5hbWUgY2xlYXJcbiAgICAgKiBAbWVtYmVyT2YgTGlzdENhY2hlXG4gICAgICovXG4gICAgZnVuY3Rpb24gbGlzdENhY2hlQ2xlYXIoKSB7XG4gICAgICB0aGlzLl9fZGF0YV9fID0gW107XG4gICAgICB0aGlzLnNpemUgPSAwO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJlbW92ZXMgYGtleWAgYW5kIGl0cyB2YWx1ZSBmcm9tIHRoZSBsaXN0IGNhY2hlLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAbmFtZSBkZWxldGVcbiAgICAgKiBAbWVtYmVyT2YgTGlzdENhY2hlXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IGtleSBUaGUga2V5IG9mIHRoZSB2YWx1ZSB0byByZW1vdmUuXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIHRoZSBlbnRyeSB3YXMgcmVtb3ZlZCwgZWxzZSBgZmFsc2VgLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGxpc3RDYWNoZURlbGV0ZShrZXkpIHtcbiAgICAgIHZhciBkYXRhID0gdGhpcy5fX2RhdGFfXyxcbiAgICAgICAgICBpbmRleCA9IGFzc29jSW5kZXhPZihkYXRhLCBrZXkpO1xuXG4gICAgICBpZiAoaW5kZXggPCAwKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cbiAgICAgIHZhciBsYXN0SW5kZXggPSBkYXRhLmxlbmd0aCAtIDE7XG4gICAgICBpZiAoaW5kZXggPT0gbGFzdEluZGV4KSB7XG4gICAgICAgIGRhdGEucG9wKCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBzcGxpY2UuY2FsbChkYXRhLCBpbmRleCwgMSk7XG4gICAgICB9XG4gICAgICAtLXRoaXMuc2l6ZTtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEdldHMgdGhlIGxpc3QgY2FjaGUgdmFsdWUgZm9yIGBrZXlgLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAbmFtZSBnZXRcbiAgICAgKiBAbWVtYmVyT2YgTGlzdENhY2hlXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IGtleSBUaGUga2V5IG9mIHRoZSB2YWx1ZSB0byBnZXQuXG4gICAgICogQHJldHVybnMgeyp9IFJldHVybnMgdGhlIGVudHJ5IHZhbHVlLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGxpc3RDYWNoZUdldChrZXkpIHtcbiAgICAgIHZhciBkYXRhID0gdGhpcy5fX2RhdGFfXyxcbiAgICAgICAgICBpbmRleCA9IGFzc29jSW5kZXhPZihkYXRhLCBrZXkpO1xuXG4gICAgICByZXR1cm4gaW5kZXggPCAwID8gdW5kZWZpbmVkIDogZGF0YVtpbmRleF1bMV07XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ2hlY2tzIGlmIGEgbGlzdCBjYWNoZSB2YWx1ZSBmb3IgYGtleWAgZXhpc3RzLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAbmFtZSBoYXNcbiAgICAgKiBAbWVtYmVyT2YgTGlzdENhY2hlXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IGtleSBUaGUga2V5IG9mIHRoZSBlbnRyeSB0byBjaGVjay5cbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYW4gZW50cnkgZm9yIGBrZXlgIGV4aXN0cywgZWxzZSBgZmFsc2VgLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGxpc3RDYWNoZUhhcyhrZXkpIHtcbiAgICAgIHJldHVybiBhc3NvY0luZGV4T2YodGhpcy5fX2RhdGFfXywga2V5KSA+IC0xO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFNldHMgdGhlIGxpc3QgY2FjaGUgYGtleWAgdG8gYHZhbHVlYC5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQG5hbWUgc2V0XG4gICAgICogQG1lbWJlck9mIExpc3RDYWNoZVxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBrZXkgVGhlIGtleSBvZiB0aGUgdmFsdWUgdG8gc2V0LlxuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIHNldC5cbiAgICAgKiBAcmV0dXJucyB7T2JqZWN0fSBSZXR1cm5zIHRoZSBsaXN0IGNhY2hlIGluc3RhbmNlLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGxpc3RDYWNoZVNldChrZXksIHZhbHVlKSB7XG4gICAgICB2YXIgZGF0YSA9IHRoaXMuX19kYXRhX18sXG4gICAgICAgICAgaW5kZXggPSBhc3NvY0luZGV4T2YoZGF0YSwga2V5KTtcblxuICAgICAgaWYgKGluZGV4IDwgMCkge1xuICAgICAgICArK3RoaXMuc2l6ZTtcbiAgICAgICAgZGF0YS5wdXNoKFtrZXksIHZhbHVlXSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBkYXRhW2luZGV4XVsxXSA9IHZhbHVlO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLy8gQWRkIG1ldGhvZHMgdG8gYExpc3RDYWNoZWAuXG4gICAgTGlzdENhY2hlLnByb3RvdHlwZS5jbGVhciA9IGxpc3RDYWNoZUNsZWFyO1xuICAgIExpc3RDYWNoZS5wcm90b3R5cGVbJ2RlbGV0ZSddID0gbGlzdENhY2hlRGVsZXRlO1xuICAgIExpc3RDYWNoZS5wcm90b3R5cGUuZ2V0ID0gbGlzdENhY2hlR2V0O1xuICAgIExpc3RDYWNoZS5wcm90b3R5cGUuaGFzID0gbGlzdENhY2hlSGFzO1xuICAgIExpc3RDYWNoZS5wcm90b3R5cGUuc2V0ID0gbGlzdENhY2hlU2V0O1xuXG4gICAgLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qL1xuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIG1hcCBjYWNoZSBvYmplY3QgdG8gc3RvcmUga2V5LXZhbHVlIHBhaXJzLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAY29uc3RydWN0b3JcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBbZW50cmllc10gVGhlIGtleS12YWx1ZSBwYWlycyB0byBjYWNoZS5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBNYXBDYWNoZShlbnRyaWVzKSB7XG4gICAgICB2YXIgaW5kZXggPSAtMSxcbiAgICAgICAgICBsZW5ndGggPSBlbnRyaWVzID09IG51bGwgPyAwIDogZW50cmllcy5sZW5ndGg7XG5cbiAgICAgIHRoaXMuY2xlYXIoKTtcbiAgICAgIHdoaWxlICgrK2luZGV4IDwgbGVuZ3RoKSB7XG4gICAgICAgIHZhciBlbnRyeSA9IGVudHJpZXNbaW5kZXhdO1xuICAgICAgICB0aGlzLnNldChlbnRyeVswXSwgZW50cnlbMV0pO1xuICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJlbW92ZXMgYWxsIGtleS12YWx1ZSBlbnRyaWVzIGZyb20gdGhlIG1hcC5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQG5hbWUgY2xlYXJcbiAgICAgKiBAbWVtYmVyT2YgTWFwQ2FjaGVcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBtYXBDYWNoZUNsZWFyKCkge1xuICAgICAgdGhpcy5zaXplID0gMDtcbiAgICAgIHRoaXMuX19kYXRhX18gPSB7XG4gICAgICAgICdoYXNoJzogbmV3IEhhc2gsXG4gICAgICAgICdtYXAnOiBuZXcgKE1hcCB8fCBMaXN0Q2FjaGUpLFxuICAgICAgICAnc3RyaW5nJzogbmV3IEhhc2hcbiAgICAgIH07XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUmVtb3ZlcyBga2V5YCBhbmQgaXRzIHZhbHVlIGZyb20gdGhlIG1hcC5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQG5hbWUgZGVsZXRlXG4gICAgICogQG1lbWJlck9mIE1hcENhY2hlXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IGtleSBUaGUga2V5IG9mIHRoZSB2YWx1ZSB0byByZW1vdmUuXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIHRoZSBlbnRyeSB3YXMgcmVtb3ZlZCwgZWxzZSBgZmFsc2VgLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIG1hcENhY2hlRGVsZXRlKGtleSkge1xuICAgICAgdmFyIHJlc3VsdCA9IGdldE1hcERhdGEodGhpcywga2V5KVsnZGVsZXRlJ10oa2V5KTtcbiAgICAgIHRoaXMuc2l6ZSAtPSByZXN1bHQgPyAxIDogMDtcbiAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogR2V0cyB0aGUgbWFwIHZhbHVlIGZvciBga2V5YC5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQG5hbWUgZ2V0XG4gICAgICogQG1lbWJlck9mIE1hcENhY2hlXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IGtleSBUaGUga2V5IG9mIHRoZSB2YWx1ZSB0byBnZXQuXG4gICAgICogQHJldHVybnMgeyp9IFJldHVybnMgdGhlIGVudHJ5IHZhbHVlLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIG1hcENhY2hlR2V0KGtleSkge1xuICAgICAgcmV0dXJuIGdldE1hcERhdGEodGhpcywga2V5KS5nZXQoa2V5KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDaGVja3MgaWYgYSBtYXAgdmFsdWUgZm9yIGBrZXlgIGV4aXN0cy5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQG5hbWUgaGFzXG4gICAgICogQG1lbWJlck9mIE1hcENhY2hlXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IGtleSBUaGUga2V5IG9mIHRoZSBlbnRyeSB0byBjaGVjay5cbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYW4gZW50cnkgZm9yIGBrZXlgIGV4aXN0cywgZWxzZSBgZmFsc2VgLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIG1hcENhY2hlSGFzKGtleSkge1xuICAgICAgcmV0dXJuIGdldE1hcERhdGEodGhpcywga2V5KS5oYXMoa2V5KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBTZXRzIHRoZSBtYXAgYGtleWAgdG8gYHZhbHVlYC5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQG5hbWUgc2V0XG4gICAgICogQG1lbWJlck9mIE1hcENhY2hlXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IGtleSBUaGUga2V5IG9mIHRoZSB2YWx1ZSB0byBzZXQuXG4gICAgICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gc2V0LlxuICAgICAqIEByZXR1cm5zIHtPYmplY3R9IFJldHVybnMgdGhlIG1hcCBjYWNoZSBpbnN0YW5jZS5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBtYXBDYWNoZVNldChrZXksIHZhbHVlKSB7XG4gICAgICB2YXIgZGF0YSA9IGdldE1hcERhdGEodGhpcywga2V5KSxcbiAgICAgICAgICBzaXplID0gZGF0YS5zaXplO1xuXG4gICAgICBkYXRhLnNldChrZXksIHZhbHVlKTtcbiAgICAgIHRoaXMuc2l6ZSArPSBkYXRhLnNpemUgPT0gc2l6ZSA/IDAgOiAxO1xuICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLy8gQWRkIG1ldGhvZHMgdG8gYE1hcENhY2hlYC5cbiAgICBNYXBDYWNoZS5wcm90b3R5cGUuY2xlYXIgPSBtYXBDYWNoZUNsZWFyO1xuICAgIE1hcENhY2hlLnByb3RvdHlwZVsnZGVsZXRlJ10gPSBtYXBDYWNoZURlbGV0ZTtcbiAgICBNYXBDYWNoZS5wcm90b3R5cGUuZ2V0ID0gbWFwQ2FjaGVHZXQ7XG4gICAgTWFwQ2FjaGUucHJvdG90eXBlLmhhcyA9IG1hcENhY2hlSGFzO1xuICAgIE1hcENhY2hlLnByb3RvdHlwZS5zZXQgPSBtYXBDYWNoZVNldDtcblxuICAgIC8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi9cblxuICAgIC8qKlxuICAgICAqXG4gICAgICogQ3JlYXRlcyBhbiBhcnJheSBjYWNoZSBvYmplY3QgdG8gc3RvcmUgdW5pcXVlIHZhbHVlcy5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQGNvbnN0cnVjdG9yXG4gICAgICogQHBhcmFtIHtBcnJheX0gW3ZhbHVlc10gVGhlIHZhbHVlcyB0byBjYWNoZS5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBTZXRDYWNoZSh2YWx1ZXMpIHtcbiAgICAgIHZhciBpbmRleCA9IC0xLFxuICAgICAgICAgIGxlbmd0aCA9IHZhbHVlcyA9PSBudWxsID8gMCA6IHZhbHVlcy5sZW5ndGg7XG5cbiAgICAgIHRoaXMuX19kYXRhX18gPSBuZXcgTWFwQ2FjaGU7XG4gICAgICB3aGlsZSAoKytpbmRleCA8IGxlbmd0aCkge1xuICAgICAgICB0aGlzLmFkZCh2YWx1ZXNbaW5kZXhdKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBBZGRzIGB2YWx1ZWAgdG8gdGhlIGFycmF5IGNhY2hlLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAbmFtZSBhZGRcbiAgICAgKiBAbWVtYmVyT2YgU2V0Q2FjaGVcbiAgICAgKiBAYWxpYXMgcHVzaFxuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNhY2hlLlxuICAgICAqIEByZXR1cm5zIHtPYmplY3R9IFJldHVybnMgdGhlIGNhY2hlIGluc3RhbmNlLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIHNldENhY2hlQWRkKHZhbHVlKSB7XG4gICAgICB0aGlzLl9fZGF0YV9fLnNldCh2YWx1ZSwgSEFTSF9VTkRFRklORUQpO1xuICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ2hlY2tzIGlmIGB2YWx1ZWAgaXMgaW4gdGhlIGFycmF5IGNhY2hlLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAbmFtZSBoYXNcbiAgICAgKiBAbWVtYmVyT2YgU2V0Q2FjaGVcbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBzZWFyY2ggZm9yLlxuICAgICAqIEByZXR1cm5zIHtudW1iZXJ9IFJldHVybnMgYHRydWVgIGlmIGB2YWx1ZWAgaXMgZm91bmQsIGVsc2UgYGZhbHNlYC5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBzZXRDYWNoZUhhcyh2YWx1ZSkge1xuICAgICAgcmV0dXJuIHRoaXMuX19kYXRhX18uaGFzKHZhbHVlKTtcbiAgICB9XG5cbiAgICAvLyBBZGQgbWV0aG9kcyB0byBgU2V0Q2FjaGVgLlxuICAgIFNldENhY2hlLnByb3RvdHlwZS5hZGQgPSBTZXRDYWNoZS5wcm90b3R5cGUucHVzaCA9IHNldENhY2hlQWRkO1xuICAgIFNldENhY2hlLnByb3RvdHlwZS5oYXMgPSBzZXRDYWNoZUhhcztcblxuICAgIC8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi9cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBzdGFjayBjYWNoZSBvYmplY3QgdG8gc3RvcmUga2V5LXZhbHVlIHBhaXJzLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAY29uc3RydWN0b3JcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBbZW50cmllc10gVGhlIGtleS12YWx1ZSBwYWlycyB0byBjYWNoZS5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBTdGFjayhlbnRyaWVzKSB7XG4gICAgICB2YXIgZGF0YSA9IHRoaXMuX19kYXRhX18gPSBuZXcgTGlzdENhY2hlKGVudHJpZXMpO1xuICAgICAgdGhpcy5zaXplID0gZGF0YS5zaXplO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJlbW92ZXMgYWxsIGtleS12YWx1ZSBlbnRyaWVzIGZyb20gdGhlIHN0YWNrLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAbmFtZSBjbGVhclxuICAgICAqIEBtZW1iZXJPZiBTdGFja1xuICAgICAqL1xuICAgIGZ1bmN0aW9uIHN0YWNrQ2xlYXIoKSB7XG4gICAgICB0aGlzLl9fZGF0YV9fID0gbmV3IExpc3RDYWNoZTtcbiAgICAgIHRoaXMuc2l6ZSA9IDA7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUmVtb3ZlcyBga2V5YCBhbmQgaXRzIHZhbHVlIGZyb20gdGhlIHN0YWNrLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAbmFtZSBkZWxldGVcbiAgICAgKiBAbWVtYmVyT2YgU3RhY2tcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30ga2V5IFRoZSBrZXkgb2YgdGhlIHZhbHVlIHRvIHJlbW92ZS5cbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgdGhlIGVudHJ5IHdhcyByZW1vdmVkLCBlbHNlIGBmYWxzZWAuXG4gICAgICovXG4gICAgZnVuY3Rpb24gc3RhY2tEZWxldGUoa2V5KSB7XG4gICAgICB2YXIgZGF0YSA9IHRoaXMuX19kYXRhX18sXG4gICAgICAgICAgcmVzdWx0ID0gZGF0YVsnZGVsZXRlJ10oa2V5KTtcblxuICAgICAgdGhpcy5zaXplID0gZGF0YS5zaXplO1xuICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBHZXRzIHRoZSBzdGFjayB2YWx1ZSBmb3IgYGtleWAuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBuYW1lIGdldFxuICAgICAqIEBtZW1iZXJPZiBTdGFja1xuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBrZXkgVGhlIGtleSBvZiB0aGUgdmFsdWUgdG8gZ2V0LlxuICAgICAqIEByZXR1cm5zIHsqfSBSZXR1cm5zIHRoZSBlbnRyeSB2YWx1ZS5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBzdGFja0dldChrZXkpIHtcbiAgICAgIHJldHVybiB0aGlzLl9fZGF0YV9fLmdldChrZXkpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENoZWNrcyBpZiBhIHN0YWNrIHZhbHVlIGZvciBga2V5YCBleGlzdHMuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBuYW1lIGhhc1xuICAgICAqIEBtZW1iZXJPZiBTdGFja1xuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBrZXkgVGhlIGtleSBvZiB0aGUgZW50cnkgdG8gY2hlY2suXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGFuIGVudHJ5IGZvciBga2V5YCBleGlzdHMsIGVsc2UgYGZhbHNlYC5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBzdGFja0hhcyhrZXkpIHtcbiAgICAgIHJldHVybiB0aGlzLl9fZGF0YV9fLmhhcyhrZXkpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFNldHMgdGhlIHN0YWNrIGBrZXlgIHRvIGB2YWx1ZWAuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBuYW1lIHNldFxuICAgICAqIEBtZW1iZXJPZiBTdGFja1xuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBrZXkgVGhlIGtleSBvZiB0aGUgdmFsdWUgdG8gc2V0LlxuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIHNldC5cbiAgICAgKiBAcmV0dXJucyB7T2JqZWN0fSBSZXR1cm5zIHRoZSBzdGFjayBjYWNoZSBpbnN0YW5jZS5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBzdGFja1NldChrZXksIHZhbHVlKSB7XG4gICAgICB2YXIgZGF0YSA9IHRoaXMuX19kYXRhX187XG4gICAgICBpZiAoZGF0YSBpbnN0YW5jZW9mIExpc3RDYWNoZSkge1xuICAgICAgICB2YXIgcGFpcnMgPSBkYXRhLl9fZGF0YV9fO1xuICAgICAgICBpZiAoIU1hcCB8fCAocGFpcnMubGVuZ3RoIDwgTEFSR0VfQVJSQVlfU0laRSAtIDEpKSB7XG4gICAgICAgICAgcGFpcnMucHVzaChba2V5LCB2YWx1ZV0pO1xuICAgICAgICAgIHRoaXMuc2l6ZSA9ICsrZGF0YS5zaXplO1xuICAgICAgICAgIHJldHVybiB0aGlzO1xuICAgICAgICB9XG4gICAgICAgIGRhdGEgPSB0aGlzLl9fZGF0YV9fID0gbmV3IE1hcENhY2hlKHBhaXJzKTtcbiAgICAgIH1cbiAgICAgIGRhdGEuc2V0KGtleSwgdmFsdWUpO1xuICAgICAgdGhpcy5zaXplID0gZGF0YS5zaXplO1xuICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLy8gQWRkIG1ldGhvZHMgdG8gYFN0YWNrYC5cbiAgICBTdGFjay5wcm90b3R5cGUuY2xlYXIgPSBzdGFja0NsZWFyO1xuICAgIFN0YWNrLnByb3RvdHlwZVsnZGVsZXRlJ10gPSBzdGFja0RlbGV0ZTtcbiAgICBTdGFjay5wcm90b3R5cGUuZ2V0ID0gc3RhY2tHZXQ7XG4gICAgU3RhY2sucHJvdG90eXBlLmhhcyA9IHN0YWNrSGFzO1xuICAgIFN0YWNrLnByb3RvdHlwZS5zZXQgPSBzdGFja1NldDtcblxuICAgIC8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi9cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYW4gYXJyYXkgb2YgdGhlIGVudW1lcmFibGUgcHJvcGVydHkgbmFtZXMgb2YgdGhlIGFycmF5LWxpa2UgYHZhbHVlYC5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gcXVlcnkuXG4gICAgICogQHBhcmFtIHtib29sZWFufSBpbmhlcml0ZWQgU3BlY2lmeSByZXR1cm5pbmcgaW5oZXJpdGVkIHByb3BlcnR5IG5hbWVzLlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgYXJyYXkgb2YgcHJvcGVydHkgbmFtZXMuXG4gICAgICovXG4gICAgZnVuY3Rpb24gYXJyYXlMaWtlS2V5cyh2YWx1ZSwgaW5oZXJpdGVkKSB7XG4gICAgICB2YXIgaXNBcnIgPSBpc0FycmF5KHZhbHVlKSxcbiAgICAgICAgICBpc0FyZyA9ICFpc0FyciAmJiBpc0FyZ3VtZW50cyh2YWx1ZSksXG4gICAgICAgICAgaXNCdWZmID0gIWlzQXJyICYmICFpc0FyZyAmJiBpc0J1ZmZlcih2YWx1ZSksXG4gICAgICAgICAgaXNUeXBlID0gIWlzQXJyICYmICFpc0FyZyAmJiAhaXNCdWZmICYmIGlzVHlwZWRBcnJheSh2YWx1ZSksXG4gICAgICAgICAgc2tpcEluZGV4ZXMgPSBpc0FyciB8fCBpc0FyZyB8fCBpc0J1ZmYgfHwgaXNUeXBlLFxuICAgICAgICAgIHJlc3VsdCA9IHNraXBJbmRleGVzID8gYmFzZVRpbWVzKHZhbHVlLmxlbmd0aCwgU3RyaW5nKSA6IFtdLFxuICAgICAgICAgIGxlbmd0aCA9IHJlc3VsdC5sZW5ndGg7XG5cbiAgICAgIGZvciAodmFyIGtleSBpbiB2YWx1ZSkge1xuICAgICAgICBpZiAoKGluaGVyaXRlZCB8fCBoYXNPd25Qcm9wZXJ0eS5jYWxsKHZhbHVlLCBrZXkpKSAmJlxuICAgICAgICAgICAgIShza2lwSW5kZXhlcyAmJiAoXG4gICAgICAgICAgICAgICAvLyBTYWZhcmkgOSBoYXMgZW51bWVyYWJsZSBgYXJndW1lbnRzLmxlbmd0aGAgaW4gc3RyaWN0IG1vZGUuXG4gICAgICAgICAgICAgICBrZXkgPT0gJ2xlbmd0aCcgfHxcbiAgICAgICAgICAgICAgIC8vIE5vZGUuanMgMC4xMCBoYXMgZW51bWVyYWJsZSBub24taW5kZXggcHJvcGVydGllcyBvbiBidWZmZXJzLlxuICAgICAgICAgICAgICAgKGlzQnVmZiAmJiAoa2V5ID09ICdvZmZzZXQnIHx8IGtleSA9PSAncGFyZW50JykpIHx8XG4gICAgICAgICAgICAgICAvLyBQaGFudG9tSlMgMiBoYXMgZW51bWVyYWJsZSBub24taW5kZXggcHJvcGVydGllcyBvbiB0eXBlZCBhcnJheXMuXG4gICAgICAgICAgICAgICAoaXNUeXBlICYmIChrZXkgPT0gJ2J1ZmZlcicgfHwga2V5ID09ICdieXRlTGVuZ3RoJyB8fCBrZXkgPT0gJ2J5dGVPZmZzZXQnKSkgfHxcbiAgICAgICAgICAgICAgIC8vIFNraXAgaW5kZXggcHJvcGVydGllcy5cbiAgICAgICAgICAgICAgIGlzSW5kZXgoa2V5LCBsZW5ndGgpXG4gICAgICAgICAgICApKSkge1xuICAgICAgICAgIHJlc3VsdC5wdXNoKGtleSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQSBzcGVjaWFsaXplZCB2ZXJzaW9uIG9mIGBfLnNhbXBsZWAgZm9yIGFycmF5cy5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIHNhbXBsZS5cbiAgICAgKiBAcmV0dXJucyB7Kn0gUmV0dXJucyB0aGUgcmFuZG9tIGVsZW1lbnQuXG4gICAgICovXG4gICAgZnVuY3Rpb24gYXJyYXlTYW1wbGUoYXJyYXkpIHtcbiAgICAgIHZhciBsZW5ndGggPSBhcnJheS5sZW5ndGg7XG4gICAgICByZXR1cm4gbGVuZ3RoID8gYXJyYXlbYmFzZVJhbmRvbSgwLCBsZW5ndGggLSAxKV0gOiB1bmRlZmluZWQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQSBzcGVjaWFsaXplZCB2ZXJzaW9uIG9mIGBfLnNhbXBsZVNpemVgIGZvciBhcnJheXMuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBhcnJheSB0byBzYW1wbGUuXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IG4gVGhlIG51bWJlciBvZiBlbGVtZW50cyB0byBzYW1wbGUuXG4gICAgICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSByYW5kb20gZWxlbWVudHMuXG4gICAgICovXG4gICAgZnVuY3Rpb24gYXJyYXlTYW1wbGVTaXplKGFycmF5LCBuKSB7XG4gICAgICByZXR1cm4gc2h1ZmZsZVNlbGYoY29weUFycmF5KGFycmF5KSwgYmFzZUNsYW1wKG4sIDAsIGFycmF5Lmxlbmd0aCkpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEEgc3BlY2lhbGl6ZWQgdmVyc2lvbiBvZiBgXy5zaHVmZmxlYCBmb3IgYXJyYXlzLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBhcnJheSBUaGUgYXJyYXkgdG8gc2h1ZmZsZS5cbiAgICAgKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIG5ldyBzaHVmZmxlZCBhcnJheS5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBhcnJheVNodWZmbGUoYXJyYXkpIHtcbiAgICAgIHJldHVybiBzaHVmZmxlU2VsZihjb3B5QXJyYXkoYXJyYXkpKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGlzIGZ1bmN0aW9uIGlzIGxpa2UgYGFzc2lnblZhbHVlYCBleGNlcHQgdGhhdCBpdCBkb2Vzbid0IGFzc2lnblxuICAgICAqIGB1bmRlZmluZWRgIHZhbHVlcy5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIG1vZGlmeS5cbiAgICAgKiBAcGFyYW0ge3N0cmluZ30ga2V5IFRoZSBrZXkgb2YgdGhlIHByb3BlcnR5IHRvIGFzc2lnbi5cbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBhc3NpZ24uXG4gICAgICovXG4gICAgZnVuY3Rpb24gYXNzaWduTWVyZ2VWYWx1ZShvYmplY3QsIGtleSwgdmFsdWUpIHtcbiAgICAgIGlmICgodmFsdWUgIT09IHVuZGVmaW5lZCAmJiAhZXEob2JqZWN0W2tleV0sIHZhbHVlKSkgfHxcbiAgICAgICAgICAodmFsdWUgPT09IHVuZGVmaW5lZCAmJiAhKGtleSBpbiBvYmplY3QpKSkge1xuICAgICAgICBiYXNlQXNzaWduVmFsdWUob2JqZWN0LCBrZXksIHZhbHVlKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBBc3NpZ25zIGB2YWx1ZWAgdG8gYGtleWAgb2YgYG9iamVjdGAgaWYgdGhlIGV4aXN0aW5nIHZhbHVlIGlzIG5vdCBlcXVpdmFsZW50XG4gICAgICogdXNpbmcgW2BTYW1lVmFsdWVaZXJvYF0oaHR0cDovL2VjbWEtaW50ZXJuYXRpb25hbC5vcmcvZWNtYS0yNjIvNy4wLyNzZWMtc2FtZXZhbHVlemVybylcbiAgICAgKiBmb3IgZXF1YWxpdHkgY29tcGFyaXNvbnMuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBtb2RpZnkuXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IGtleSBUaGUga2V5IG9mIHRoZSBwcm9wZXJ0eSB0byBhc3NpZ24uXG4gICAgICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gYXNzaWduLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGFzc2lnblZhbHVlKG9iamVjdCwga2V5LCB2YWx1ZSkge1xuICAgICAgdmFyIG9ialZhbHVlID0gb2JqZWN0W2tleV07XG4gICAgICBpZiAoIShoYXNPd25Qcm9wZXJ0eS5jYWxsKG9iamVjdCwga2V5KSAmJiBlcShvYmpWYWx1ZSwgdmFsdWUpKSB8fFxuICAgICAgICAgICh2YWx1ZSA9PT0gdW5kZWZpbmVkICYmICEoa2V5IGluIG9iamVjdCkpKSB7XG4gICAgICAgIGJhc2VBc3NpZ25WYWx1ZShvYmplY3QsIGtleSwgdmFsdWUpO1xuICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEdldHMgdGhlIGluZGV4IGF0IHdoaWNoIHRoZSBga2V5YCBpcyBmb3VuZCBpbiBgYXJyYXlgIG9mIGtleS12YWx1ZSBwYWlycy5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIGluc3BlY3QuXG4gICAgICogQHBhcmFtIHsqfSBrZXkgVGhlIGtleSB0byBzZWFyY2ggZm9yLlxuICAgICAqIEByZXR1cm5zIHtudW1iZXJ9IFJldHVybnMgdGhlIGluZGV4IG9mIHRoZSBtYXRjaGVkIHZhbHVlLCBlbHNlIGAtMWAuXG4gICAgICovXG4gICAgZnVuY3Rpb24gYXNzb2NJbmRleE9mKGFycmF5LCBrZXkpIHtcbiAgICAgIHZhciBsZW5ndGggPSBhcnJheS5sZW5ndGg7XG4gICAgICB3aGlsZSAobGVuZ3RoLS0pIHtcbiAgICAgICAgaWYgKGVxKGFycmF5W2xlbmd0aF1bMF0sIGtleSkpIHtcbiAgICAgICAgICByZXR1cm4gbGVuZ3RoO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICByZXR1cm4gLTE7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQWdncmVnYXRlcyBlbGVtZW50cyBvZiBgY29sbGVjdGlvbmAgb24gYGFjY3VtdWxhdG9yYCB3aXRoIGtleXMgdHJhbnNmb3JtZWRcbiAgICAgKiBieSBgaXRlcmF0ZWVgIGFuZCB2YWx1ZXMgc2V0IGJ5IGBzZXR0ZXJgLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge0FycmF5fE9iamVjdH0gY29sbGVjdGlvbiBUaGUgY29sbGVjdGlvbiB0byBpdGVyYXRlIG92ZXIuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gc2V0dGVyIFRoZSBmdW5jdGlvbiB0byBzZXQgYGFjY3VtdWxhdG9yYCB2YWx1ZXMuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gaXRlcmF0ZWUgVGhlIGl0ZXJhdGVlIHRvIHRyYW5zZm9ybSBrZXlzLlxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBhY2N1bXVsYXRvciBUaGUgaW5pdGlhbCBhZ2dyZWdhdGVkIG9iamVjdC5cbiAgICAgKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgYGFjY3VtdWxhdG9yYC5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBiYXNlQWdncmVnYXRvcihjb2xsZWN0aW9uLCBzZXR0ZXIsIGl0ZXJhdGVlLCBhY2N1bXVsYXRvcikge1xuICAgICAgYmFzZUVhY2goY29sbGVjdGlvbiwgZnVuY3Rpb24odmFsdWUsIGtleSwgY29sbGVjdGlvbikge1xuICAgICAgICBzZXR0ZXIoYWNjdW11bGF0b3IsIHZhbHVlLCBpdGVyYXRlZSh2YWx1ZSksIGNvbGxlY3Rpb24pO1xuICAgICAgfSk7XG4gICAgICByZXR1cm4gYWNjdW11bGF0b3I7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8uYXNzaWduYCB3aXRob3V0IHN1cHBvcnQgZm9yIG11bHRpcGxlIHNvdXJjZXNcbiAgICAgKiBvciBgY3VzdG9taXplcmAgZnVuY3Rpb25zLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBkZXN0aW5hdGlvbiBvYmplY3QuXG4gICAgICogQHBhcmFtIHtPYmplY3R9IHNvdXJjZSBUaGUgc291cmNlIG9iamVjdC5cbiAgICAgKiBAcmV0dXJucyB7T2JqZWN0fSBSZXR1cm5zIGBvYmplY3RgLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGJhc2VBc3NpZ24ob2JqZWN0LCBzb3VyY2UpIHtcbiAgICAgIHJldHVybiBvYmplY3QgJiYgY29weU9iamVjdChzb3VyY2UsIGtleXMoc291cmNlKSwgb2JqZWN0KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5hc3NpZ25JbmAgd2l0aG91dCBzdXBwb3J0IGZvciBtdWx0aXBsZSBzb3VyY2VzXG4gICAgICogb3IgYGN1c3RvbWl6ZXJgIGZ1bmN0aW9ucy5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgZGVzdGluYXRpb24gb2JqZWN0LlxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBzb3VyY2UgVGhlIHNvdXJjZSBvYmplY3QuXG4gICAgICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyBgb2JqZWN0YC5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBiYXNlQXNzaWduSW4ob2JqZWN0LCBzb3VyY2UpIHtcbiAgICAgIHJldHVybiBvYmplY3QgJiYgY29weU9iamVjdChzb3VyY2UsIGtleXNJbihzb3VyY2UpLCBvYmplY3QpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBhc3NpZ25WYWx1ZWAgYW5kIGBhc3NpZ25NZXJnZVZhbHVlYCB3aXRob3V0XG4gICAgICogdmFsdWUgY2hlY2tzLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gbW9kaWZ5LlxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBrZXkgVGhlIGtleSBvZiB0aGUgcHJvcGVydHkgdG8gYXNzaWduLlxuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGFzc2lnbi5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBiYXNlQXNzaWduVmFsdWUob2JqZWN0LCBrZXksIHZhbHVlKSB7XG4gICAgICBpZiAoa2V5ID09ICdfX3Byb3RvX18nICYmIGRlZmluZVByb3BlcnR5KSB7XG4gICAgICAgIGRlZmluZVByb3BlcnR5KG9iamVjdCwga2V5LCB7XG4gICAgICAgICAgJ2NvbmZpZ3VyYWJsZSc6IHRydWUsXG4gICAgICAgICAgJ2VudW1lcmFibGUnOiB0cnVlLFxuICAgICAgICAgICd2YWx1ZSc6IHZhbHVlLFxuICAgICAgICAgICd3cml0YWJsZSc6IHRydWVcbiAgICAgICAgfSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBvYmplY3Rba2V5XSA9IHZhbHVlO1xuICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLmF0YCB3aXRob3V0IHN1cHBvcnQgZm9yIGluZGl2aWR1YWwgcGF0aHMuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBpdGVyYXRlIG92ZXIuXG4gICAgICogQHBhcmFtIHtzdHJpbmdbXX0gcGF0aHMgVGhlIHByb3BlcnR5IHBhdGhzIHRvIHBpY2suXG4gICAgICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBwaWNrZWQgZWxlbWVudHMuXG4gICAgICovXG4gICAgZnVuY3Rpb24gYmFzZUF0KG9iamVjdCwgcGF0aHMpIHtcbiAgICAgIHZhciBpbmRleCA9IC0xLFxuICAgICAgICAgIGxlbmd0aCA9IHBhdGhzLmxlbmd0aCxcbiAgICAgICAgICByZXN1bHQgPSBBcnJheShsZW5ndGgpLFxuICAgICAgICAgIHNraXAgPSBvYmplY3QgPT0gbnVsbDtcblxuICAgICAgd2hpbGUgKCsraW5kZXggPCBsZW5ndGgpIHtcbiAgICAgICAgcmVzdWx0W2luZGV4XSA9IHNraXAgPyB1bmRlZmluZWQgOiBnZXQob2JqZWN0LCBwYXRoc1tpbmRleF0pO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5jbGFtcGAgd2hpY2ggZG9lc24ndCBjb2VyY2UgYXJndW1lbnRzLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge251bWJlcn0gbnVtYmVyIFRoZSBudW1iZXIgdG8gY2xhbXAuXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IFtsb3dlcl0gVGhlIGxvd2VyIGJvdW5kLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSB1cHBlciBUaGUgdXBwZXIgYm91bmQuXG4gICAgICogQHJldHVybnMge251bWJlcn0gUmV0dXJucyB0aGUgY2xhbXBlZCBudW1iZXIuXG4gICAgICovXG4gICAgZnVuY3Rpb24gYmFzZUNsYW1wKG51bWJlciwgbG93ZXIsIHVwcGVyKSB7XG4gICAgICBpZiAobnVtYmVyID09PSBudW1iZXIpIHtcbiAgICAgICAgaWYgKHVwcGVyICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICBudW1iZXIgPSBudW1iZXIgPD0gdXBwZXIgPyBudW1iZXIgOiB1cHBlcjtcbiAgICAgICAgfVxuICAgICAgICBpZiAobG93ZXIgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgIG51bWJlciA9IG51bWJlciA+PSBsb3dlciA/IG51bWJlciA6IGxvd2VyO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICByZXR1cm4gbnVtYmVyO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLmNsb25lYCBhbmQgYF8uY2xvbmVEZWVwYCB3aGljaCB0cmFja3NcbiAgICAgKiB0cmF2ZXJzZWQgb2JqZWN0cy5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY2xvbmUuXG4gICAgICogQHBhcmFtIHtib29sZWFufSBiaXRtYXNrIFRoZSBiaXRtYXNrIGZsYWdzLlxuICAgICAqICAxIC0gRGVlcCBjbG9uZVxuICAgICAqICAyIC0gRmxhdHRlbiBpbmhlcml0ZWQgcHJvcGVydGllc1xuICAgICAqICA0IC0gQ2xvbmUgc3ltYm9sc1xuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IFtjdXN0b21pemVyXSBUaGUgZnVuY3Rpb24gdG8gY3VzdG9taXplIGNsb25pbmcuXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IFtrZXldIFRoZSBrZXkgb2YgYHZhbHVlYC5cbiAgICAgKiBAcGFyYW0ge09iamVjdH0gW29iamVjdF0gVGhlIHBhcmVudCBvYmplY3Qgb2YgYHZhbHVlYC5cbiAgICAgKiBAcGFyYW0ge09iamVjdH0gW3N0YWNrXSBUcmFja3MgdHJhdmVyc2VkIG9iamVjdHMgYW5kIHRoZWlyIGNsb25lIGNvdW50ZXJwYXJ0cy5cbiAgICAgKiBAcmV0dXJucyB7Kn0gUmV0dXJucyB0aGUgY2xvbmVkIHZhbHVlLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGJhc2VDbG9uZSh2YWx1ZSwgYml0bWFzaywgY3VzdG9taXplciwga2V5LCBvYmplY3QsIHN0YWNrKSB7XG4gICAgICB2YXIgcmVzdWx0LFxuICAgICAgICAgIGlzRGVlcCA9IGJpdG1hc2sgJiBDTE9ORV9ERUVQX0ZMQUcsXG4gICAgICAgICAgaXNGbGF0ID0gYml0bWFzayAmIENMT05FX0ZMQVRfRkxBRyxcbiAgICAgICAgICBpc0Z1bGwgPSBiaXRtYXNrICYgQ0xPTkVfU1lNQk9MU19GTEFHO1xuXG4gICAgICBpZiAoY3VzdG9taXplcikge1xuICAgICAgICByZXN1bHQgPSBvYmplY3QgPyBjdXN0b21pemVyKHZhbHVlLCBrZXksIG9iamVjdCwgc3RhY2spIDogY3VzdG9taXplcih2YWx1ZSk7XG4gICAgICB9XG4gICAgICBpZiAocmVzdWx0ICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICAgIH1cbiAgICAgIGlmICghaXNPYmplY3QodmFsdWUpKSB7XG4gICAgICAgIHJldHVybiB2YWx1ZTtcbiAgICAgIH1cbiAgICAgIHZhciBpc0FyciA9IGlzQXJyYXkodmFsdWUpO1xuICAgICAgaWYgKGlzQXJyKSB7XG4gICAgICAgIHJlc3VsdCA9IGluaXRDbG9uZUFycmF5KHZhbHVlKTtcbiAgICAgICAgaWYgKCFpc0RlZXApIHtcbiAgICAgICAgICByZXR1cm4gY29weUFycmF5KHZhbHVlLCByZXN1bHQpO1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB2YXIgdGFnID0gZ2V0VGFnKHZhbHVlKSxcbiAgICAgICAgICAgIGlzRnVuYyA9IHRhZyA9PSBmdW5jVGFnIHx8IHRhZyA9PSBnZW5UYWc7XG5cbiAgICAgICAgaWYgKGlzQnVmZmVyKHZhbHVlKSkge1xuICAgICAgICAgIHJldHVybiBjbG9uZUJ1ZmZlcih2YWx1ZSwgaXNEZWVwKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAodGFnID09IG9iamVjdFRhZyB8fCB0YWcgPT0gYXJnc1RhZyB8fCAoaXNGdW5jICYmICFvYmplY3QpKSB7XG4gICAgICAgICAgcmVzdWx0ID0gKGlzRmxhdCB8fCBpc0Z1bmMpID8ge30gOiBpbml0Q2xvbmVPYmplY3QodmFsdWUpO1xuICAgICAgICAgIGlmICghaXNEZWVwKSB7XG4gICAgICAgICAgICByZXR1cm4gaXNGbGF0XG4gICAgICAgICAgICAgID8gY29weVN5bWJvbHNJbih2YWx1ZSwgYmFzZUFzc2lnbkluKHJlc3VsdCwgdmFsdWUpKVxuICAgICAgICAgICAgICA6IGNvcHlTeW1ib2xzKHZhbHVlLCBiYXNlQXNzaWduKHJlc3VsdCwgdmFsdWUpKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgaWYgKCFjbG9uZWFibGVUYWdzW3RhZ10pIHtcbiAgICAgICAgICAgIHJldHVybiBvYmplY3QgPyB2YWx1ZSA6IHt9O1xuICAgICAgICAgIH1cbiAgICAgICAgICByZXN1bHQgPSBpbml0Q2xvbmVCeVRhZyh2YWx1ZSwgdGFnLCBiYXNlQ2xvbmUsIGlzRGVlcCk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIC8vIENoZWNrIGZvciBjaXJjdWxhciByZWZlcmVuY2VzIGFuZCByZXR1cm4gaXRzIGNvcnJlc3BvbmRpbmcgY2xvbmUuXG4gICAgICBzdGFjayB8fCAoc3RhY2sgPSBuZXcgU3RhY2spO1xuICAgICAgdmFyIHN0YWNrZWQgPSBzdGFjay5nZXQodmFsdWUpO1xuICAgICAgaWYgKHN0YWNrZWQpIHtcbiAgICAgICAgcmV0dXJuIHN0YWNrZWQ7XG4gICAgICB9XG4gICAgICBzdGFjay5zZXQodmFsdWUsIHJlc3VsdCk7XG5cbiAgICAgIHZhciBrZXlzRnVuYyA9IGlzRnVsbFxuICAgICAgICA/IChpc0ZsYXQgPyBnZXRBbGxLZXlzSW4gOiBnZXRBbGxLZXlzKVxuICAgICAgICA6IChpc0ZsYXQgPyBrZXlzSW4gOiBrZXlzKTtcblxuICAgICAgdmFyIHByb3BzID0gaXNBcnIgPyB1bmRlZmluZWQgOiBrZXlzRnVuYyh2YWx1ZSk7XG4gICAgICBhcnJheUVhY2gocHJvcHMgfHwgdmFsdWUsIGZ1bmN0aW9uKHN1YlZhbHVlLCBrZXkpIHtcbiAgICAgICAgaWYgKHByb3BzKSB7XG4gICAgICAgICAga2V5ID0gc3ViVmFsdWU7XG4gICAgICAgICAgc3ViVmFsdWUgPSB2YWx1ZVtrZXldO1xuICAgICAgICB9XG4gICAgICAgIC8vIFJlY3Vyc2l2ZWx5IHBvcHVsYXRlIGNsb25lIChzdXNjZXB0aWJsZSB0byBjYWxsIHN0YWNrIGxpbWl0cykuXG4gICAgICAgIGFzc2lnblZhbHVlKHJlc3VsdCwga2V5LCBiYXNlQ2xvbmUoc3ViVmFsdWUsIGJpdG1hc2ssIGN1c3RvbWl6ZXIsIGtleSwgdmFsdWUsIHN0YWNrKSk7XG4gICAgICB9KTtcbiAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8uY29uZm9ybXNgIHdoaWNoIGRvZXNuJ3QgY2xvbmUgYHNvdXJjZWAuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBzb3VyY2UgVGhlIG9iamVjdCBvZiBwcm9wZXJ0eSBwcmVkaWNhdGVzIHRvIGNvbmZvcm0gdG8uXG4gICAgICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBuZXcgc3BlYyBmdW5jdGlvbi5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBiYXNlQ29uZm9ybXMoc291cmNlKSB7XG4gICAgICB2YXIgcHJvcHMgPSBrZXlzKHNvdXJjZSk7XG4gICAgICByZXR1cm4gZnVuY3Rpb24ob2JqZWN0KSB7XG4gICAgICAgIHJldHVybiBiYXNlQ29uZm9ybXNUbyhvYmplY3QsIHNvdXJjZSwgcHJvcHMpO1xuICAgICAgfTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5jb25mb3Jtc1RvYCB3aGljaCBhY2NlcHRzIGBwcm9wc2AgdG8gY2hlY2suXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBpbnNwZWN0LlxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBzb3VyY2UgVGhlIG9iamVjdCBvZiBwcm9wZXJ0eSBwcmVkaWNhdGVzIHRvIGNvbmZvcm0gdG8uXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGBvYmplY3RgIGNvbmZvcm1zLCBlbHNlIGBmYWxzZWAuXG4gICAgICovXG4gICAgZnVuY3Rpb24gYmFzZUNvbmZvcm1zVG8ob2JqZWN0LCBzb3VyY2UsIHByb3BzKSB7XG4gICAgICB2YXIgbGVuZ3RoID0gcHJvcHMubGVuZ3RoO1xuICAgICAgaWYgKG9iamVjdCA9PSBudWxsKSB7XG4gICAgICAgIHJldHVybiAhbGVuZ3RoO1xuICAgICAgfVxuICAgICAgb2JqZWN0ID0gT2JqZWN0KG9iamVjdCk7XG4gICAgICB3aGlsZSAobGVuZ3RoLS0pIHtcbiAgICAgICAgdmFyIGtleSA9IHByb3BzW2xlbmd0aF0sXG4gICAgICAgICAgICBwcmVkaWNhdGUgPSBzb3VyY2Vba2V5XSxcbiAgICAgICAgICAgIHZhbHVlID0gb2JqZWN0W2tleV07XG5cbiAgICAgICAgaWYgKCh2YWx1ZSA9PT0gdW5kZWZpbmVkICYmICEoa2V5IGluIG9iamVjdCkpIHx8ICFwcmVkaWNhdGUodmFsdWUpKSB7XG4gICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5kZWxheWAgYW5kIGBfLmRlZmVyYCB3aGljaCBhY2NlcHRzIGBhcmdzYFxuICAgICAqIHRvIHByb3ZpZGUgdG8gYGZ1bmNgLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBmdW5jIFRoZSBmdW5jdGlvbiB0byBkZWxheS5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gd2FpdCBUaGUgbnVtYmVyIG9mIG1pbGxpc2Vjb25kcyB0byBkZWxheSBpbnZvY2F0aW9uLlxuICAgICAqIEBwYXJhbSB7QXJyYXl9IGFyZ3MgVGhlIGFyZ3VtZW50cyB0byBwcm92aWRlIHRvIGBmdW5jYC5cbiAgICAgKiBAcmV0dXJucyB7bnVtYmVyfE9iamVjdH0gUmV0dXJucyB0aGUgdGltZXIgaWQgb3IgdGltZW91dCBvYmplY3QuXG4gICAgICovXG4gICAgZnVuY3Rpb24gYmFzZURlbGF5KGZ1bmMsIHdhaXQsIGFyZ3MpIHtcbiAgICAgIGlmICh0eXBlb2YgZnVuYyAhPSAnZnVuY3Rpb24nKSB7XG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoRlVOQ19FUlJPUl9URVhUKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBzZXRUaW1lb3V0KGZ1bmN0aW9uKCkgeyBmdW5jLmFwcGx5KHVuZGVmaW5lZCwgYXJncyk7IH0sIHdhaXQpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIG1ldGhvZHMgbGlrZSBgXy5kaWZmZXJlbmNlYCB3aXRob3V0IHN1cHBvcnRcbiAgICAgKiBmb3IgZXhjbHVkaW5nIG11bHRpcGxlIGFycmF5cyBvciBpdGVyYXRlZSBzaG9ydGhhbmRzLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBhcnJheSBUaGUgYXJyYXkgdG8gaW5zcGVjdC5cbiAgICAgKiBAcGFyYW0ge0FycmF5fSB2YWx1ZXMgVGhlIHZhbHVlcyB0byBleGNsdWRlLlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IFtpdGVyYXRlZV0gVGhlIGl0ZXJhdGVlIGludm9rZWQgcGVyIGVsZW1lbnQuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gW2NvbXBhcmF0b3JdIFRoZSBjb21wYXJhdG9yIGludm9rZWQgcGVyIGVsZW1lbnQuXG4gICAgICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBuZXcgYXJyYXkgb2YgZmlsdGVyZWQgdmFsdWVzLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGJhc2VEaWZmZXJlbmNlKGFycmF5LCB2YWx1ZXMsIGl0ZXJhdGVlLCBjb21wYXJhdG9yKSB7XG4gICAgICB2YXIgaW5kZXggPSAtMSxcbiAgICAgICAgICBpbmNsdWRlcyA9IGFycmF5SW5jbHVkZXMsXG4gICAgICAgICAgaXNDb21tb24gPSB0cnVlLFxuICAgICAgICAgIGxlbmd0aCA9IGFycmF5Lmxlbmd0aCxcbiAgICAgICAgICByZXN1bHQgPSBbXSxcbiAgICAgICAgICB2YWx1ZXNMZW5ndGggPSB2YWx1ZXMubGVuZ3RoO1xuXG4gICAgICBpZiAoIWxlbmd0aCkge1xuICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgICAgfVxuICAgICAgaWYgKGl0ZXJhdGVlKSB7XG4gICAgICAgIHZhbHVlcyA9IGFycmF5TWFwKHZhbHVlcywgYmFzZVVuYXJ5KGl0ZXJhdGVlKSk7XG4gICAgICB9XG4gICAgICBpZiAoY29tcGFyYXRvcikge1xuICAgICAgICBpbmNsdWRlcyA9IGFycmF5SW5jbHVkZXNXaXRoO1xuICAgICAgICBpc0NvbW1vbiA9IGZhbHNlO1xuICAgICAgfVxuICAgICAgZWxzZSBpZiAodmFsdWVzLmxlbmd0aCA+PSBMQVJHRV9BUlJBWV9TSVpFKSB7XG4gICAgICAgIGluY2x1ZGVzID0gY2FjaGVIYXM7XG4gICAgICAgIGlzQ29tbW9uID0gZmFsc2U7XG4gICAgICAgIHZhbHVlcyA9IG5ldyBTZXRDYWNoZSh2YWx1ZXMpO1xuICAgICAgfVxuICAgICAgb3V0ZXI6XG4gICAgICB3aGlsZSAoKytpbmRleCA8IGxlbmd0aCkge1xuICAgICAgICB2YXIgdmFsdWUgPSBhcnJheVtpbmRleF0sXG4gICAgICAgICAgICBjb21wdXRlZCA9IGl0ZXJhdGVlID09IG51bGwgPyB2YWx1ZSA6IGl0ZXJhdGVlKHZhbHVlKTtcblxuICAgICAgICB2YWx1ZSA9IChjb21wYXJhdG9yIHx8IHZhbHVlICE9PSAwKSA/IHZhbHVlIDogMDtcbiAgICAgICAgaWYgKGlzQ29tbW9uICYmIGNvbXB1dGVkID09PSBjb21wdXRlZCkge1xuICAgICAgICAgIHZhciB2YWx1ZXNJbmRleCA9IHZhbHVlc0xlbmd0aDtcbiAgICAgICAgICB3aGlsZSAodmFsdWVzSW5kZXgtLSkge1xuICAgICAgICAgICAgaWYgKHZhbHVlc1t2YWx1ZXNJbmRleF0gPT09IGNvbXB1dGVkKSB7XG4gICAgICAgICAgICAgIGNvbnRpbnVlIG91dGVyO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgICByZXN1bHQucHVzaCh2YWx1ZSk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAoIWluY2x1ZGVzKHZhbHVlcywgY29tcHV0ZWQsIGNvbXBhcmF0b3IpKSB7XG4gICAgICAgICAgcmVzdWx0LnB1c2godmFsdWUpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLmZvckVhY2hgIHdpdGhvdXQgc3VwcG9ydCBmb3IgaXRlcmF0ZWUgc2hvcnRoYW5kcy5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtBcnJheXxPYmplY3R9IGNvbGxlY3Rpb24gVGhlIGNvbGxlY3Rpb24gdG8gaXRlcmF0ZSBvdmVyLlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IGl0ZXJhdGVlIFRoZSBmdW5jdGlvbiBpbnZva2VkIHBlciBpdGVyYXRpb24uXG4gICAgICogQHJldHVybnMge0FycmF5fE9iamVjdH0gUmV0dXJucyBgY29sbGVjdGlvbmAuXG4gICAgICovXG4gICAgdmFyIGJhc2VFYWNoID0gY3JlYXRlQmFzZUVhY2goYmFzZUZvck93bik7XG5cbiAgICAvKipcbiAgICAgKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5mb3JFYWNoUmlnaHRgIHdpdGhvdXQgc3VwcG9ydCBmb3IgaXRlcmF0ZWUgc2hvcnRoYW5kcy5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtBcnJheXxPYmplY3R9IGNvbGxlY3Rpb24gVGhlIGNvbGxlY3Rpb24gdG8gaXRlcmF0ZSBvdmVyLlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IGl0ZXJhdGVlIFRoZSBmdW5jdGlvbiBpbnZva2VkIHBlciBpdGVyYXRpb24uXG4gICAgICogQHJldHVybnMge0FycmF5fE9iamVjdH0gUmV0dXJucyBgY29sbGVjdGlvbmAuXG4gICAgICovXG4gICAgdmFyIGJhc2VFYWNoUmlnaHQgPSBjcmVhdGVCYXNlRWFjaChiYXNlRm9yT3duUmlnaHQsIHRydWUpO1xuXG4gICAgLyoqXG4gICAgICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8uZXZlcnlgIHdpdGhvdXQgc3VwcG9ydCBmb3IgaXRlcmF0ZWUgc2hvcnRoYW5kcy5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtBcnJheXxPYmplY3R9IGNvbGxlY3Rpb24gVGhlIGNvbGxlY3Rpb24gdG8gaXRlcmF0ZSBvdmVyLlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IHByZWRpY2F0ZSBUaGUgZnVuY3Rpb24gaW52b2tlZCBwZXIgaXRlcmF0aW9uLlxuICAgICAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBhbGwgZWxlbWVudHMgcGFzcyB0aGUgcHJlZGljYXRlIGNoZWNrLFxuICAgICAqICBlbHNlIGBmYWxzZWBcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBiYXNlRXZlcnkoY29sbGVjdGlvbiwgcHJlZGljYXRlKSB7XG4gICAgICB2YXIgcmVzdWx0ID0gdHJ1ZTtcbiAgICAgIGJhc2VFYWNoKGNvbGxlY3Rpb24sIGZ1bmN0aW9uKHZhbHVlLCBpbmRleCwgY29sbGVjdGlvbikge1xuICAgICAgICByZXN1bHQgPSAhIXByZWRpY2F0ZSh2YWx1ZSwgaW5kZXgsIGNvbGxlY3Rpb24pO1xuICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgICAgfSk7XG4gICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIG1ldGhvZHMgbGlrZSBgXy5tYXhgIGFuZCBgXy5taW5gIHdoaWNoIGFjY2VwdHMgYVxuICAgICAqIGBjb21wYXJhdG9yYCB0byBkZXRlcm1pbmUgdGhlIGV4dHJlbXVtIHZhbHVlLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBhcnJheSBUaGUgYXJyYXkgdG8gaXRlcmF0ZSBvdmVyLlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IGl0ZXJhdGVlIFRoZSBpdGVyYXRlZSBpbnZva2VkIHBlciBpdGVyYXRpb24uXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gY29tcGFyYXRvciBUaGUgY29tcGFyYXRvciB1c2VkIHRvIGNvbXBhcmUgdmFsdWVzLlxuICAgICAqIEByZXR1cm5zIHsqfSBSZXR1cm5zIHRoZSBleHRyZW11bSB2YWx1ZS5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBiYXNlRXh0cmVtdW0oYXJyYXksIGl0ZXJhdGVlLCBjb21wYXJhdG9yKSB7XG4gICAgICB2YXIgaW5kZXggPSAtMSxcbiAgICAgICAgICBsZW5ndGggPSBhcnJheS5sZW5ndGg7XG5cbiAgICAgIHdoaWxlICgrK2luZGV4IDwgbGVuZ3RoKSB7XG4gICAgICAgIHZhciB2YWx1ZSA9IGFycmF5W2luZGV4XSxcbiAgICAgICAgICAgIGN1cnJlbnQgPSBpdGVyYXRlZSh2YWx1ZSk7XG5cbiAgICAgICAgaWYgKGN1cnJlbnQgIT0gbnVsbCAmJiAoY29tcHV0ZWQgPT09IHVuZGVmaW5lZFxuICAgICAgICAgICAgICA/IChjdXJyZW50ID09PSBjdXJyZW50ICYmICFpc1N5bWJvbChjdXJyZW50KSlcbiAgICAgICAgICAgICAgOiBjb21wYXJhdG9yKGN1cnJlbnQsIGNvbXB1dGVkKVxuICAgICAgICAgICAgKSkge1xuICAgICAgICAgIHZhciBjb21wdXRlZCA9IGN1cnJlbnQsXG4gICAgICAgICAgICAgIHJlc3VsdCA9IHZhbHVlO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLmZpbGxgIHdpdGhvdXQgYW4gaXRlcmF0ZWUgY2FsbCBndWFyZC5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIGZpbGwuXG4gICAgICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gZmlsbCBgYXJyYXlgIHdpdGguXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IFtzdGFydD0wXSBUaGUgc3RhcnQgcG9zaXRpb24uXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IFtlbmQ9YXJyYXkubGVuZ3RoXSBUaGUgZW5kIHBvc2l0aW9uLlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyBgYXJyYXlgLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGJhc2VGaWxsKGFycmF5LCB2YWx1ZSwgc3RhcnQsIGVuZCkge1xuICAgICAgdmFyIGxlbmd0aCA9IGFycmF5Lmxlbmd0aDtcblxuICAgICAgc3RhcnQgPSB0b0ludGVnZXIoc3RhcnQpO1xuICAgICAgaWYgKHN0YXJ0IDwgMCkge1xuICAgICAgICBzdGFydCA9IC1zdGFydCA+IGxlbmd0aCA/IDAgOiAobGVuZ3RoICsgc3RhcnQpO1xuICAgICAgfVxuICAgICAgZW5kID0gKGVuZCA9PT0gdW5kZWZpbmVkIHx8IGVuZCA+IGxlbmd0aCkgPyBsZW5ndGggOiB0b0ludGVnZXIoZW5kKTtcbiAgICAgIGlmIChlbmQgPCAwKSB7XG4gICAgICAgIGVuZCArPSBsZW5ndGg7XG4gICAgICB9XG4gICAgICBlbmQgPSBzdGFydCA+IGVuZCA/IDAgOiB0b0xlbmd0aChlbmQpO1xuICAgICAgd2hpbGUgKHN0YXJ0IDwgZW5kKSB7XG4gICAgICAgIGFycmF5W3N0YXJ0KytdID0gdmFsdWU7XG4gICAgICB9XG4gICAgICByZXR1cm4gYXJyYXk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8uZmlsdGVyYCB3aXRob3V0IHN1cHBvcnQgZm9yIGl0ZXJhdGVlIHNob3J0aGFuZHMuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7QXJyYXl8T2JqZWN0fSBjb2xsZWN0aW9uIFRoZSBjb2xsZWN0aW9uIHRvIGl0ZXJhdGUgb3Zlci5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBwcmVkaWNhdGUgVGhlIGZ1bmN0aW9uIGludm9rZWQgcGVyIGl0ZXJhdGlvbi5cbiAgICAgKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIG5ldyBmaWx0ZXJlZCBhcnJheS5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBiYXNlRmlsdGVyKGNvbGxlY3Rpb24sIHByZWRpY2F0ZSkge1xuICAgICAgdmFyIHJlc3VsdCA9IFtdO1xuICAgICAgYmFzZUVhY2goY29sbGVjdGlvbiwgZnVuY3Rpb24odmFsdWUsIGluZGV4LCBjb2xsZWN0aW9uKSB7XG4gICAgICAgIGlmIChwcmVkaWNhdGUodmFsdWUsIGluZGV4LCBjb2xsZWN0aW9uKSkge1xuICAgICAgICAgIHJlc3VsdC5wdXNoKHZhbHVlKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLmZsYXR0ZW5gIHdpdGggc3VwcG9ydCBmb3IgcmVzdHJpY3RpbmcgZmxhdHRlbmluZy5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIGZsYXR0ZW4uXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IGRlcHRoIFRoZSBtYXhpbXVtIHJlY3Vyc2lvbiBkZXB0aC5cbiAgICAgKiBAcGFyYW0ge2Jvb2xlYW59IFtwcmVkaWNhdGU9aXNGbGF0dGVuYWJsZV0gVGhlIGZ1bmN0aW9uIGludm9rZWQgcGVyIGl0ZXJhdGlvbi5cbiAgICAgKiBAcGFyYW0ge2Jvb2xlYW59IFtpc1N0cmljdF0gUmVzdHJpY3QgdG8gdmFsdWVzIHRoYXQgcGFzcyBgcHJlZGljYXRlYCBjaGVja3MuXG4gICAgICogQHBhcmFtIHtBcnJheX0gW3Jlc3VsdD1bXV0gVGhlIGluaXRpYWwgcmVzdWx0IHZhbHVlLlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgbmV3IGZsYXR0ZW5lZCBhcnJheS5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBiYXNlRmxhdHRlbihhcnJheSwgZGVwdGgsIHByZWRpY2F0ZSwgaXNTdHJpY3QsIHJlc3VsdCkge1xuICAgICAgdmFyIGluZGV4ID0gLTEsXG4gICAgICAgICAgbGVuZ3RoID0gYXJyYXkubGVuZ3RoO1xuXG4gICAgICBwcmVkaWNhdGUgfHwgKHByZWRpY2F0ZSA9IGlzRmxhdHRlbmFibGUpO1xuICAgICAgcmVzdWx0IHx8IChyZXN1bHQgPSBbXSk7XG5cbiAgICAgIHdoaWxlICgrK2luZGV4IDwgbGVuZ3RoKSB7XG4gICAgICAgIHZhciB2YWx1ZSA9IGFycmF5W2luZGV4XTtcbiAgICAgICAgaWYgKGRlcHRoID4gMCAmJiBwcmVkaWNhdGUodmFsdWUpKSB7XG4gICAgICAgICAgaWYgKGRlcHRoID4gMSkge1xuICAgICAgICAgICAgLy8gUmVjdXJzaXZlbHkgZmxhdHRlbiBhcnJheXMgKHN1c2NlcHRpYmxlIHRvIGNhbGwgc3RhY2sgbGltaXRzKS5cbiAgICAgICAgICAgIGJhc2VGbGF0dGVuKHZhbHVlLCBkZXB0aCAtIDEsIHByZWRpY2F0ZSwgaXNTdHJpY3QsIHJlc3VsdCk7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGFycmF5UHVzaChyZXN1bHQsIHZhbHVlKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSBpZiAoIWlzU3RyaWN0KSB7XG4gICAgICAgICAgcmVzdWx0W3Jlc3VsdC5sZW5ndGhdID0gdmFsdWU7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYGJhc2VGb3JPd25gIHdoaWNoIGl0ZXJhdGVzIG92ZXIgYG9iamVjdGBcbiAgICAgKiBwcm9wZXJ0aWVzIHJldHVybmVkIGJ5IGBrZXlzRnVuY2AgYW5kIGludm9rZXMgYGl0ZXJhdGVlYCBmb3IgZWFjaCBwcm9wZXJ0eS5cbiAgICAgKiBJdGVyYXRlZSBmdW5jdGlvbnMgbWF5IGV4aXQgaXRlcmF0aW9uIGVhcmx5IGJ5IGV4cGxpY2l0bHkgcmV0dXJuaW5nIGBmYWxzZWAuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBpdGVyYXRlIG92ZXIuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gaXRlcmF0ZWUgVGhlIGZ1bmN0aW9uIGludm9rZWQgcGVyIGl0ZXJhdGlvbi5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBrZXlzRnVuYyBUaGUgZnVuY3Rpb24gdG8gZ2V0IHRoZSBrZXlzIG9mIGBvYmplY3RgLlxuICAgICAqIEByZXR1cm5zIHtPYmplY3R9IFJldHVybnMgYG9iamVjdGAuXG4gICAgICovXG4gICAgdmFyIGJhc2VGb3IgPSBjcmVhdGVCYXNlRm9yKCk7XG5cbiAgICAvKipcbiAgICAgKiBUaGlzIGZ1bmN0aW9uIGlzIGxpa2UgYGJhc2VGb3JgIGV4Y2VwdCB0aGF0IGl0IGl0ZXJhdGVzIG92ZXIgcHJvcGVydGllc1xuICAgICAqIGluIHRoZSBvcHBvc2l0ZSBvcmRlci5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIGl0ZXJhdGUgb3Zlci5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBpdGVyYXRlZSBUaGUgZnVuY3Rpb24gaW52b2tlZCBwZXIgaXRlcmF0aW9uLlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IGtleXNGdW5jIFRoZSBmdW5jdGlvbiB0byBnZXQgdGhlIGtleXMgb2YgYG9iamVjdGAuXG4gICAgICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyBgb2JqZWN0YC5cbiAgICAgKi9cbiAgICB2YXIgYmFzZUZvclJpZ2h0ID0gY3JlYXRlQmFzZUZvcih0cnVlKTtcblxuICAgIC8qKlxuICAgICAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLmZvck93bmAgd2l0aG91dCBzdXBwb3J0IGZvciBpdGVyYXRlZSBzaG9ydGhhbmRzLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gaXRlcmF0ZSBvdmVyLlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IGl0ZXJhdGVlIFRoZSBmdW5jdGlvbiBpbnZva2VkIHBlciBpdGVyYXRpb24uXG4gICAgICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyBgb2JqZWN0YC5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBiYXNlRm9yT3duKG9iamVjdCwgaXRlcmF0ZWUpIHtcbiAgICAgIHJldHVybiBvYmplY3QgJiYgYmFzZUZvcihvYmplY3QsIGl0ZXJhdGVlLCBrZXlzKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5mb3JPd25SaWdodGAgd2l0aG91dCBzdXBwb3J0IGZvciBpdGVyYXRlZSBzaG9ydGhhbmRzLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gaXRlcmF0ZSBvdmVyLlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IGl0ZXJhdGVlIFRoZSBmdW5jdGlvbiBpbnZva2VkIHBlciBpdGVyYXRpb24uXG4gICAgICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyBgb2JqZWN0YC5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBiYXNlRm9yT3duUmlnaHQob2JqZWN0LCBpdGVyYXRlZSkge1xuICAgICAgcmV0dXJuIG9iamVjdCAmJiBiYXNlRm9yUmlnaHQob2JqZWN0LCBpdGVyYXRlZSwga2V5cyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8uZnVuY3Rpb25zYCB3aGljaCBjcmVhdGVzIGFuIGFycmF5IG9mXG4gICAgICogYG9iamVjdGAgZnVuY3Rpb24gcHJvcGVydHkgbmFtZXMgZmlsdGVyZWQgZnJvbSBgcHJvcHNgLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gaW5zcGVjdC5cbiAgICAgKiBAcGFyYW0ge0FycmF5fSBwcm9wcyBUaGUgcHJvcGVydHkgbmFtZXMgdG8gZmlsdGVyLlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgZnVuY3Rpb24gbmFtZXMuXG4gICAgICovXG4gICAgZnVuY3Rpb24gYmFzZUZ1bmN0aW9ucyhvYmplY3QsIHByb3BzKSB7XG4gICAgICByZXR1cm4gYXJyYXlGaWx0ZXIocHJvcHMsIGZ1bmN0aW9uKGtleSkge1xuICAgICAgICByZXR1cm4gaXNGdW5jdGlvbihvYmplY3Rba2V5XSk7XG4gICAgICB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5nZXRgIHdpdGhvdXQgc3VwcG9ydCBmb3IgZGVmYXVsdCB2YWx1ZXMuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBxdWVyeS5cbiAgICAgKiBAcGFyYW0ge0FycmF5fHN0cmluZ30gcGF0aCBUaGUgcGF0aCBvZiB0aGUgcHJvcGVydHkgdG8gZ2V0LlxuICAgICAqIEByZXR1cm5zIHsqfSBSZXR1cm5zIHRoZSByZXNvbHZlZCB2YWx1ZS5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBiYXNlR2V0KG9iamVjdCwgcGF0aCkge1xuICAgICAgcGF0aCA9IGNhc3RQYXRoKHBhdGgsIG9iamVjdCk7XG5cbiAgICAgIHZhciBpbmRleCA9IDAsXG4gICAgICAgICAgbGVuZ3RoID0gcGF0aC5sZW5ndGg7XG5cbiAgICAgIHdoaWxlIChvYmplY3QgIT0gbnVsbCAmJiBpbmRleCA8IGxlbmd0aCkge1xuICAgICAgICBvYmplY3QgPSBvYmplY3RbdG9LZXkocGF0aFtpbmRleCsrXSldO1xuICAgICAgfVxuICAgICAgcmV0dXJuIChpbmRleCAmJiBpbmRleCA9PSBsZW5ndGgpID8gb2JqZWN0IDogdW5kZWZpbmVkO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBnZXRBbGxLZXlzYCBhbmQgYGdldEFsbEtleXNJbmAgd2hpY2ggdXNlc1xuICAgICAqIGBrZXlzRnVuY2AgYW5kIGBzeW1ib2xzRnVuY2AgdG8gZ2V0IHRoZSBlbnVtZXJhYmxlIHByb3BlcnR5IG5hbWVzIGFuZFxuICAgICAqIHN5bWJvbHMgb2YgYG9iamVjdGAuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBxdWVyeS5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBrZXlzRnVuYyBUaGUgZnVuY3Rpb24gdG8gZ2V0IHRoZSBrZXlzIG9mIGBvYmplY3RgLlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IHN5bWJvbHNGdW5jIFRoZSBmdW5jdGlvbiB0byBnZXQgdGhlIHN5bWJvbHMgb2YgYG9iamVjdGAuXG4gICAgICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBhcnJheSBvZiBwcm9wZXJ0eSBuYW1lcyBhbmQgc3ltYm9scy5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBiYXNlR2V0QWxsS2V5cyhvYmplY3QsIGtleXNGdW5jLCBzeW1ib2xzRnVuYykge1xuICAgICAgdmFyIHJlc3VsdCA9IGtleXNGdW5jKG9iamVjdCk7XG4gICAgICByZXR1cm4gaXNBcnJheShvYmplY3QpID8gcmVzdWx0IDogYXJyYXlQdXNoKHJlc3VsdCwgc3ltYm9sc0Z1bmMob2JqZWN0KSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYGdldFRhZ2Agd2l0aG91dCBmYWxsYmFja3MgZm9yIGJ1Z2d5IGVudmlyb25tZW50cy5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gcXVlcnkuXG4gICAgICogQHJldHVybnMge3N0cmluZ30gUmV0dXJucyB0aGUgYHRvU3RyaW5nVGFnYC5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBiYXNlR2V0VGFnKHZhbHVlKSB7XG4gICAgICBpZiAodmFsdWUgPT0gbnVsbCkge1xuICAgICAgICByZXR1cm4gdmFsdWUgPT09IHVuZGVmaW5lZCA/IHVuZGVmaW5lZFRhZyA6IG51bGxUYWc7XG4gICAgICB9XG4gICAgICByZXR1cm4gKHN5bVRvU3RyaW5nVGFnICYmIHN5bVRvU3RyaW5nVGFnIGluIE9iamVjdCh2YWx1ZSkpXG4gICAgICAgID8gZ2V0UmF3VGFnKHZhbHVlKVxuICAgICAgICA6IG9iamVjdFRvU3RyaW5nKHZhbHVlKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5ndGAgd2hpY2ggZG9lc24ndCBjb2VyY2UgYXJndW1lbnRzLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjb21wYXJlLlxuICAgICAqIEBwYXJhbSB7Kn0gb3RoZXIgVGhlIG90aGVyIHZhbHVlIHRvIGNvbXBhcmUuXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGB2YWx1ZWAgaXMgZ3JlYXRlciB0aGFuIGBvdGhlcmAsXG4gICAgICogIGVsc2UgYGZhbHNlYC5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBiYXNlR3QodmFsdWUsIG90aGVyKSB7XG4gICAgICByZXR1cm4gdmFsdWUgPiBvdGhlcjtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5oYXNgIHdpdGhvdXQgc3VwcG9ydCBmb3IgZGVlcCBwYXRocy5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtPYmplY3R9IFtvYmplY3RdIFRoZSBvYmplY3QgdG8gcXVlcnkuXG4gICAgICogQHBhcmFtIHtBcnJheXxzdHJpbmd9IGtleSBUaGUga2V5IHRvIGNoZWNrLlxuICAgICAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBga2V5YCBleGlzdHMsIGVsc2UgYGZhbHNlYC5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBiYXNlSGFzKG9iamVjdCwga2V5KSB7XG4gICAgICByZXR1cm4gb2JqZWN0ICE9IG51bGwgJiYgaGFzT3duUHJvcGVydHkuY2FsbChvYmplY3QsIGtleSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8uaGFzSW5gIHdpdGhvdXQgc3VwcG9ydCBmb3IgZGVlcCBwYXRocy5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtPYmplY3R9IFtvYmplY3RdIFRoZSBvYmplY3QgdG8gcXVlcnkuXG4gICAgICogQHBhcmFtIHtBcnJheXxzdHJpbmd9IGtleSBUaGUga2V5IHRvIGNoZWNrLlxuICAgICAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBga2V5YCBleGlzdHMsIGVsc2UgYGZhbHNlYC5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBiYXNlSGFzSW4ob2JqZWN0LCBrZXkpIHtcbiAgICAgIHJldHVybiBvYmplY3QgIT0gbnVsbCAmJiBrZXkgaW4gT2JqZWN0KG9iamVjdCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8uaW5SYW5nZWAgd2hpY2ggZG9lc24ndCBjb2VyY2UgYXJndW1lbnRzLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge251bWJlcn0gbnVtYmVyIFRoZSBudW1iZXIgdG8gY2hlY2suXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IHN0YXJ0IFRoZSBzdGFydCBvZiB0aGUgcmFuZ2UuXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IGVuZCBUaGUgZW5kIG9mIHRoZSByYW5nZS5cbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYG51bWJlcmAgaXMgaW4gdGhlIHJhbmdlLCBlbHNlIGBmYWxzZWAuXG4gICAgICovXG4gICAgZnVuY3Rpb24gYmFzZUluUmFuZ2UobnVtYmVyLCBzdGFydCwgZW5kKSB7XG4gICAgICByZXR1cm4gbnVtYmVyID49IG5hdGl2ZU1pbihzdGFydCwgZW5kKSAmJiBudW1iZXIgPCBuYXRpdmVNYXgoc3RhcnQsIGVuZCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgbWV0aG9kcyBsaWtlIGBfLmludGVyc2VjdGlvbmAsIHdpdGhvdXQgc3VwcG9ydFxuICAgICAqIGZvciBpdGVyYXRlZSBzaG9ydGhhbmRzLCB0aGF0IGFjY2VwdHMgYW4gYXJyYXkgb2YgYXJyYXlzIHRvIGluc3BlY3QuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7QXJyYXl9IGFycmF5cyBUaGUgYXJyYXlzIHRvIGluc3BlY3QuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gW2l0ZXJhdGVlXSBUaGUgaXRlcmF0ZWUgaW52b2tlZCBwZXIgZWxlbWVudC5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBbY29tcGFyYXRvcl0gVGhlIGNvbXBhcmF0b3IgaW52b2tlZCBwZXIgZWxlbWVudC5cbiAgICAgKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIG5ldyBhcnJheSBvZiBzaGFyZWQgdmFsdWVzLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGJhc2VJbnRlcnNlY3Rpb24oYXJyYXlzLCBpdGVyYXRlZSwgY29tcGFyYXRvcikge1xuICAgICAgdmFyIGluY2x1ZGVzID0gY29tcGFyYXRvciA/IGFycmF5SW5jbHVkZXNXaXRoIDogYXJyYXlJbmNsdWRlcyxcbiAgICAgICAgICBsZW5ndGggPSBhcnJheXNbMF0ubGVuZ3RoLFxuICAgICAgICAgIG90aExlbmd0aCA9IGFycmF5cy5sZW5ndGgsXG4gICAgICAgICAgb3RoSW5kZXggPSBvdGhMZW5ndGgsXG4gICAgICAgICAgY2FjaGVzID0gQXJyYXkob3RoTGVuZ3RoKSxcbiAgICAgICAgICBtYXhMZW5ndGggPSBJbmZpbml0eSxcbiAgICAgICAgICByZXN1bHQgPSBbXTtcblxuICAgICAgd2hpbGUgKG90aEluZGV4LS0pIHtcbiAgICAgICAgdmFyIGFycmF5ID0gYXJyYXlzW290aEluZGV4XTtcbiAgICAgICAgaWYgKG90aEluZGV4ICYmIGl0ZXJhdGVlKSB7XG4gICAgICAgICAgYXJyYXkgPSBhcnJheU1hcChhcnJheSwgYmFzZVVuYXJ5KGl0ZXJhdGVlKSk7XG4gICAgICAgIH1cbiAgICAgICAgbWF4TGVuZ3RoID0gbmF0aXZlTWluKGFycmF5Lmxlbmd0aCwgbWF4TGVuZ3RoKTtcbiAgICAgICAgY2FjaGVzW290aEluZGV4XSA9ICFjb21wYXJhdG9yICYmIChpdGVyYXRlZSB8fCAobGVuZ3RoID49IDEyMCAmJiBhcnJheS5sZW5ndGggPj0gMTIwKSlcbiAgICAgICAgICA/IG5ldyBTZXRDYWNoZShvdGhJbmRleCAmJiBhcnJheSlcbiAgICAgICAgICA6IHVuZGVmaW5lZDtcbiAgICAgIH1cbiAgICAgIGFycmF5ID0gYXJyYXlzWzBdO1xuXG4gICAgICB2YXIgaW5kZXggPSAtMSxcbiAgICAgICAgICBzZWVuID0gY2FjaGVzWzBdO1xuXG4gICAgICBvdXRlcjpcbiAgICAgIHdoaWxlICgrK2luZGV4IDwgbGVuZ3RoICYmIHJlc3VsdC5sZW5ndGggPCBtYXhMZW5ndGgpIHtcbiAgICAgICAgdmFyIHZhbHVlID0gYXJyYXlbaW5kZXhdLFxuICAgICAgICAgICAgY29tcHV0ZWQgPSBpdGVyYXRlZSA/IGl0ZXJhdGVlKHZhbHVlKSA6IHZhbHVlO1xuXG4gICAgICAgIHZhbHVlID0gKGNvbXBhcmF0b3IgfHwgdmFsdWUgIT09IDApID8gdmFsdWUgOiAwO1xuICAgICAgICBpZiAoIShzZWVuXG4gICAgICAgICAgICAgID8gY2FjaGVIYXMoc2VlbiwgY29tcHV0ZWQpXG4gICAgICAgICAgICAgIDogaW5jbHVkZXMocmVzdWx0LCBjb21wdXRlZCwgY29tcGFyYXRvcilcbiAgICAgICAgICAgICkpIHtcbiAgICAgICAgICBvdGhJbmRleCA9IG90aExlbmd0aDtcbiAgICAgICAgICB3aGlsZSAoLS1vdGhJbmRleCkge1xuICAgICAgICAgICAgdmFyIGNhY2hlID0gY2FjaGVzW290aEluZGV4XTtcbiAgICAgICAgICAgIGlmICghKGNhY2hlXG4gICAgICAgICAgICAgICAgICA/IGNhY2hlSGFzKGNhY2hlLCBjb21wdXRlZClcbiAgICAgICAgICAgICAgICAgIDogaW5jbHVkZXMoYXJyYXlzW290aEluZGV4XSwgY29tcHV0ZWQsIGNvbXBhcmF0b3IpKVxuICAgICAgICAgICAgICAgICkge1xuICAgICAgICAgICAgICBjb250aW51ZSBvdXRlcjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgICAgaWYgKHNlZW4pIHtcbiAgICAgICAgICAgIHNlZW4ucHVzaChjb21wdXRlZCk7XG4gICAgICAgICAgfVxuICAgICAgICAgIHJlc3VsdC5wdXNoKHZhbHVlKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5pbnZlcnRgIGFuZCBgXy5pbnZlcnRCeWAgd2hpY2ggaW52ZXJ0c1xuICAgICAqIGBvYmplY3RgIHdpdGggdmFsdWVzIHRyYW5zZm9ybWVkIGJ5IGBpdGVyYXRlZWAgYW5kIHNldCBieSBgc2V0dGVyYC5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIGl0ZXJhdGUgb3Zlci5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBzZXR0ZXIgVGhlIGZ1bmN0aW9uIHRvIHNldCBgYWNjdW11bGF0b3JgIHZhbHVlcy5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBpdGVyYXRlZSBUaGUgaXRlcmF0ZWUgdG8gdHJhbnNmb3JtIHZhbHVlcy5cbiAgICAgKiBAcGFyYW0ge09iamVjdH0gYWNjdW11bGF0b3IgVGhlIGluaXRpYWwgaW52ZXJ0ZWQgb2JqZWN0LlxuICAgICAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyBgYWNjdW11bGF0b3JgLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGJhc2VJbnZlcnRlcihvYmplY3QsIHNldHRlciwgaXRlcmF0ZWUsIGFjY3VtdWxhdG9yKSB7XG4gICAgICBiYXNlRm9yT3duKG9iamVjdCwgZnVuY3Rpb24odmFsdWUsIGtleSwgb2JqZWN0KSB7XG4gICAgICAgIHNldHRlcihhY2N1bXVsYXRvciwgaXRlcmF0ZWUodmFsdWUpLCBrZXksIG9iamVjdCk7XG4gICAgICB9KTtcbiAgICAgIHJldHVybiBhY2N1bXVsYXRvcjtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5pbnZva2VgIHdpdGhvdXQgc3VwcG9ydCBmb3IgaW5kaXZpZHVhbFxuICAgICAqIG1ldGhvZCBhcmd1bWVudHMuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBxdWVyeS5cbiAgICAgKiBAcGFyYW0ge0FycmF5fHN0cmluZ30gcGF0aCBUaGUgcGF0aCBvZiB0aGUgbWV0aG9kIHRvIGludm9rZS5cbiAgICAgKiBAcGFyYW0ge0FycmF5fSBhcmdzIFRoZSBhcmd1bWVudHMgdG8gaW52b2tlIHRoZSBtZXRob2Qgd2l0aC5cbiAgICAgKiBAcmV0dXJucyB7Kn0gUmV0dXJucyB0aGUgcmVzdWx0IG9mIHRoZSBpbnZva2VkIG1ldGhvZC5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBiYXNlSW52b2tlKG9iamVjdCwgcGF0aCwgYXJncykge1xuICAgICAgcGF0aCA9IGNhc3RQYXRoKHBhdGgsIG9iamVjdCk7XG4gICAgICBvYmplY3QgPSBwYXJlbnQob2JqZWN0LCBwYXRoKTtcbiAgICAgIHZhciBmdW5jID0gb2JqZWN0ID09IG51bGwgPyBvYmplY3QgOiBvYmplY3RbdG9LZXkobGFzdChwYXRoKSldO1xuICAgICAgcmV0dXJuIGZ1bmMgPT0gbnVsbCA/IHVuZGVmaW5lZCA6IGFwcGx5KGZ1bmMsIG9iamVjdCwgYXJncyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8uaXNBcmd1bWVudHNgLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjaGVjay5cbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBhbiBgYXJndW1lbnRzYCBvYmplY3QsXG4gICAgICovXG4gICAgZnVuY3Rpb24gYmFzZUlzQXJndW1lbnRzKHZhbHVlKSB7XG4gICAgICByZXR1cm4gaXNPYmplY3RMaWtlKHZhbHVlKSAmJiBiYXNlR2V0VGFnKHZhbHVlKSA9PSBhcmdzVGFnO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLmlzQXJyYXlCdWZmZXJgIHdpdGhvdXQgTm9kZS5qcyBvcHRpbWl6YXRpb25zLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjaGVjay5cbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBhbiBhcnJheSBidWZmZXIsIGVsc2UgYGZhbHNlYC5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBiYXNlSXNBcnJheUJ1ZmZlcih2YWx1ZSkge1xuICAgICAgcmV0dXJuIGlzT2JqZWN0TGlrZSh2YWx1ZSkgJiYgYmFzZUdldFRhZyh2YWx1ZSkgPT0gYXJyYXlCdWZmZXJUYWc7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8uaXNEYXRlYCB3aXRob3V0IE5vZGUuanMgb3B0aW1pemF0aW9ucy5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY2hlY2suXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGB2YWx1ZWAgaXMgYSBkYXRlIG9iamVjdCwgZWxzZSBgZmFsc2VgLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGJhc2VJc0RhdGUodmFsdWUpIHtcbiAgICAgIHJldHVybiBpc09iamVjdExpa2UodmFsdWUpICYmIGJhc2VHZXRUYWcodmFsdWUpID09IGRhdGVUYWc7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8uaXNFcXVhbGAgd2hpY2ggc3VwcG9ydHMgcGFydGlhbCBjb21wYXJpc29uc1xuICAgICAqIGFuZCB0cmFja3MgdHJhdmVyc2VkIG9iamVjdHMuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNvbXBhcmUuXG4gICAgICogQHBhcmFtIHsqfSBvdGhlciBUaGUgb3RoZXIgdmFsdWUgdG8gY29tcGFyZS5cbiAgICAgKiBAcGFyYW0ge2Jvb2xlYW59IGJpdG1hc2sgVGhlIGJpdG1hc2sgZmxhZ3MuXG4gICAgICogIDEgLSBVbm9yZGVyZWQgY29tcGFyaXNvblxuICAgICAqICAyIC0gUGFydGlhbCBjb21wYXJpc29uXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gW2N1c3RvbWl6ZXJdIFRoZSBmdW5jdGlvbiB0byBjdXN0b21pemUgY29tcGFyaXNvbnMuXG4gICAgICogQHBhcmFtIHtPYmplY3R9IFtzdGFja10gVHJhY2tzIHRyYXZlcnNlZCBgdmFsdWVgIGFuZCBgb3RoZXJgIG9iamVjdHMuXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIHRoZSB2YWx1ZXMgYXJlIGVxdWl2YWxlbnQsIGVsc2UgYGZhbHNlYC5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBiYXNlSXNFcXVhbCh2YWx1ZSwgb3RoZXIsIGJpdG1hc2ssIGN1c3RvbWl6ZXIsIHN0YWNrKSB7XG4gICAgICBpZiAodmFsdWUgPT09IG90aGVyKSB7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgfVxuICAgICAgaWYgKHZhbHVlID09IG51bGwgfHwgb3RoZXIgPT0gbnVsbCB8fCAoIWlzT2JqZWN0TGlrZSh2YWx1ZSkgJiYgIWlzT2JqZWN0TGlrZShvdGhlcikpKSB7XG4gICAgICAgIHJldHVybiB2YWx1ZSAhPT0gdmFsdWUgJiYgb3RoZXIgIT09IG90aGVyO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGJhc2VJc0VxdWFsRGVlcCh2YWx1ZSwgb3RoZXIsIGJpdG1hc2ssIGN1c3RvbWl6ZXIsIGJhc2VJc0VxdWFsLCBzdGFjayk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQSBzcGVjaWFsaXplZCB2ZXJzaW9uIG9mIGBiYXNlSXNFcXVhbGAgZm9yIGFycmF5cyBhbmQgb2JqZWN0cyB3aGljaCBwZXJmb3Jtc1xuICAgICAqIGRlZXAgY29tcGFyaXNvbnMgYW5kIHRyYWNrcyB0cmF2ZXJzZWQgb2JqZWN0cyBlbmFibGluZyBvYmplY3RzIHdpdGggY2lyY3VsYXJcbiAgICAgKiByZWZlcmVuY2VzIHRvIGJlIGNvbXBhcmVkLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gY29tcGFyZS5cbiAgICAgKiBAcGFyYW0ge09iamVjdH0gb3RoZXIgVGhlIG90aGVyIG9iamVjdCB0byBjb21wYXJlLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBiaXRtYXNrIFRoZSBiaXRtYXNrIGZsYWdzLiBTZWUgYGJhc2VJc0VxdWFsYCBmb3IgbW9yZSBkZXRhaWxzLlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IGN1c3RvbWl6ZXIgVGhlIGZ1bmN0aW9uIHRvIGN1c3RvbWl6ZSBjb21wYXJpc29ucy5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBlcXVhbEZ1bmMgVGhlIGZ1bmN0aW9uIHRvIGRldGVybWluZSBlcXVpdmFsZW50cyBvZiB2YWx1ZXMuXG4gICAgICogQHBhcmFtIHtPYmplY3R9IFtzdGFja10gVHJhY2tzIHRyYXZlcnNlZCBgb2JqZWN0YCBhbmQgYG90aGVyYCBvYmplY3RzLlxuICAgICAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiB0aGUgb2JqZWN0cyBhcmUgZXF1aXZhbGVudCwgZWxzZSBgZmFsc2VgLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGJhc2VJc0VxdWFsRGVlcChvYmplY3QsIG90aGVyLCBiaXRtYXNrLCBjdXN0b21pemVyLCBlcXVhbEZ1bmMsIHN0YWNrKSB7XG4gICAgICB2YXIgb2JqSXNBcnIgPSBpc0FycmF5KG9iamVjdCksXG4gICAgICAgICAgb3RoSXNBcnIgPSBpc0FycmF5KG90aGVyKSxcbiAgICAgICAgICBvYmpUYWcgPSBvYmpJc0FyciA/IGFycmF5VGFnIDogZ2V0VGFnKG9iamVjdCksXG4gICAgICAgICAgb3RoVGFnID0gb3RoSXNBcnIgPyBhcnJheVRhZyA6IGdldFRhZyhvdGhlcik7XG5cbiAgICAgIG9ialRhZyA9IG9ialRhZyA9PSBhcmdzVGFnID8gb2JqZWN0VGFnIDogb2JqVGFnO1xuICAgICAgb3RoVGFnID0gb3RoVGFnID09IGFyZ3NUYWcgPyBvYmplY3RUYWcgOiBvdGhUYWc7XG5cbiAgICAgIHZhciBvYmpJc09iaiA9IG9ialRhZyA9PSBvYmplY3RUYWcsXG4gICAgICAgICAgb3RoSXNPYmogPSBvdGhUYWcgPT0gb2JqZWN0VGFnLFxuICAgICAgICAgIGlzU2FtZVRhZyA9IG9ialRhZyA9PSBvdGhUYWc7XG5cbiAgICAgIGlmIChpc1NhbWVUYWcgJiYgaXNCdWZmZXIob2JqZWN0KSkge1xuICAgICAgICBpZiAoIWlzQnVmZmVyKG90aGVyKSkge1xuICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgICBvYmpJc0FyciA9IHRydWU7XG4gICAgICAgIG9iaklzT2JqID0gZmFsc2U7XG4gICAgICB9XG4gICAgICBpZiAoaXNTYW1lVGFnICYmICFvYmpJc09iaikge1xuICAgICAgICBzdGFjayB8fCAoc3RhY2sgPSBuZXcgU3RhY2spO1xuICAgICAgICByZXR1cm4gKG9iaklzQXJyIHx8IGlzVHlwZWRBcnJheShvYmplY3QpKVxuICAgICAgICAgID8gZXF1YWxBcnJheXMob2JqZWN0LCBvdGhlciwgYml0bWFzaywgY3VzdG9taXplciwgZXF1YWxGdW5jLCBzdGFjaylcbiAgICAgICAgICA6IGVxdWFsQnlUYWcob2JqZWN0LCBvdGhlciwgb2JqVGFnLCBiaXRtYXNrLCBjdXN0b21pemVyLCBlcXVhbEZ1bmMsIHN0YWNrKTtcbiAgICAgIH1cbiAgICAgIGlmICghKGJpdG1hc2sgJiBDT01QQVJFX1BBUlRJQUxfRkxBRykpIHtcbiAgICAgICAgdmFyIG9iaklzV3JhcHBlZCA9IG9iaklzT2JqICYmIGhhc093blByb3BlcnR5LmNhbGwob2JqZWN0LCAnX193cmFwcGVkX18nKSxcbiAgICAgICAgICAgIG90aElzV3JhcHBlZCA9IG90aElzT2JqICYmIGhhc093blByb3BlcnR5LmNhbGwob3RoZXIsICdfX3dyYXBwZWRfXycpO1xuXG4gICAgICAgIGlmIChvYmpJc1dyYXBwZWQgfHwgb3RoSXNXcmFwcGVkKSB7XG4gICAgICAgICAgdmFyIG9ialVud3JhcHBlZCA9IG9iaklzV3JhcHBlZCA/IG9iamVjdC52YWx1ZSgpIDogb2JqZWN0LFxuICAgICAgICAgICAgICBvdGhVbndyYXBwZWQgPSBvdGhJc1dyYXBwZWQgPyBvdGhlci52YWx1ZSgpIDogb3RoZXI7XG5cbiAgICAgICAgICBzdGFjayB8fCAoc3RhY2sgPSBuZXcgU3RhY2spO1xuICAgICAgICAgIHJldHVybiBlcXVhbEZ1bmMob2JqVW53cmFwcGVkLCBvdGhVbndyYXBwZWQsIGJpdG1hc2ssIGN1c3RvbWl6ZXIsIHN0YWNrKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaWYgKCFpc1NhbWVUYWcpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuICAgICAgc3RhY2sgfHwgKHN0YWNrID0gbmV3IFN0YWNrKTtcbiAgICAgIHJldHVybiBlcXVhbE9iamVjdHMob2JqZWN0LCBvdGhlciwgYml0bWFzaywgY3VzdG9taXplciwgZXF1YWxGdW5jLCBzdGFjayk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8uaXNNYXBgIHdpdGhvdXQgTm9kZS5qcyBvcHRpbWl6YXRpb25zLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjaGVjay5cbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBhIG1hcCwgZWxzZSBgZmFsc2VgLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGJhc2VJc01hcCh2YWx1ZSkge1xuICAgICAgcmV0dXJuIGlzT2JqZWN0TGlrZSh2YWx1ZSkgJiYgZ2V0VGFnKHZhbHVlKSA9PSBtYXBUYWc7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8uaXNNYXRjaGAgd2l0aG91dCBzdXBwb3J0IGZvciBpdGVyYXRlZSBzaG9ydGhhbmRzLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gaW5zcGVjdC5cbiAgICAgKiBAcGFyYW0ge09iamVjdH0gc291cmNlIFRoZSBvYmplY3Qgb2YgcHJvcGVydHkgdmFsdWVzIHRvIG1hdGNoLlxuICAgICAqIEBwYXJhbSB7QXJyYXl9IG1hdGNoRGF0YSBUaGUgcHJvcGVydHkgbmFtZXMsIHZhbHVlcywgYW5kIGNvbXBhcmUgZmxhZ3MgdG8gbWF0Y2guXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gW2N1c3RvbWl6ZXJdIFRoZSBmdW5jdGlvbiB0byBjdXN0b21pemUgY29tcGFyaXNvbnMuXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGBvYmplY3RgIGlzIGEgbWF0Y2gsIGVsc2UgYGZhbHNlYC5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBiYXNlSXNNYXRjaChvYmplY3QsIHNvdXJjZSwgbWF0Y2hEYXRhLCBjdXN0b21pemVyKSB7XG4gICAgICB2YXIgaW5kZXggPSBtYXRjaERhdGEubGVuZ3RoLFxuICAgICAgICAgIGxlbmd0aCA9IGluZGV4LFxuICAgICAgICAgIG5vQ3VzdG9taXplciA9ICFjdXN0b21pemVyO1xuXG4gICAgICBpZiAob2JqZWN0ID09IG51bGwpIHtcbiAgICAgICAgcmV0dXJuICFsZW5ndGg7XG4gICAgICB9XG4gICAgICBvYmplY3QgPSBPYmplY3Qob2JqZWN0KTtcbiAgICAgIHdoaWxlIChpbmRleC0tKSB7XG4gICAgICAgIHZhciBkYXRhID0gbWF0Y2hEYXRhW2luZGV4XTtcbiAgICAgICAgaWYgKChub0N1c3RvbWl6ZXIgJiYgZGF0YVsyXSlcbiAgICAgICAgICAgICAgPyBkYXRhWzFdICE9PSBvYmplY3RbZGF0YVswXV1cbiAgICAgICAgICAgICAgOiAhKGRhdGFbMF0gaW4gb2JqZWN0KVxuICAgICAgICAgICAgKSB7XG4gICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICB3aGlsZSAoKytpbmRleCA8IGxlbmd0aCkge1xuICAgICAgICBkYXRhID0gbWF0Y2hEYXRhW2luZGV4XTtcbiAgICAgICAgdmFyIGtleSA9IGRhdGFbMF0sXG4gICAgICAgICAgICBvYmpWYWx1ZSA9IG9iamVjdFtrZXldLFxuICAgICAgICAgICAgc3JjVmFsdWUgPSBkYXRhWzFdO1xuXG4gICAgICAgIGlmIChub0N1c3RvbWl6ZXIgJiYgZGF0YVsyXSkge1xuICAgICAgICAgIGlmIChvYmpWYWx1ZSA9PT0gdW5kZWZpbmVkICYmICEoa2V5IGluIG9iamVjdCkpIHtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgdmFyIHN0YWNrID0gbmV3IFN0YWNrO1xuICAgICAgICAgIGlmIChjdXN0b21pemVyKSB7XG4gICAgICAgICAgICB2YXIgcmVzdWx0ID0gY3VzdG9taXplcihvYmpWYWx1ZSwgc3JjVmFsdWUsIGtleSwgb2JqZWN0LCBzb3VyY2UsIHN0YWNrKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgaWYgKCEocmVzdWx0ID09PSB1bmRlZmluZWRcbiAgICAgICAgICAgICAgICA/IGJhc2VJc0VxdWFsKHNyY1ZhbHVlLCBvYmpWYWx1ZSwgQ09NUEFSRV9QQVJUSUFMX0ZMQUcgfCBDT01QQVJFX1VOT1JERVJFRF9GTEFHLCBjdXN0b21pemVyLCBzdGFjaylcbiAgICAgICAgICAgICAgICA6IHJlc3VsdFxuICAgICAgICAgICAgICApKSB7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5pc05hdGl2ZWAgd2l0aG91dCBiYWQgc2hpbSBjaGVja3MuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrLlxuICAgICAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlzIGEgbmF0aXZlIGZ1bmN0aW9uLFxuICAgICAqICBlbHNlIGBmYWxzZWAuXG4gICAgICovXG4gICAgZnVuY3Rpb24gYmFzZUlzTmF0aXZlKHZhbHVlKSB7XG4gICAgICBpZiAoIWlzT2JqZWN0KHZhbHVlKSB8fCBpc01hc2tlZCh2YWx1ZSkpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuICAgICAgdmFyIHBhdHRlcm4gPSBpc0Z1bmN0aW9uKHZhbHVlKSA/IHJlSXNOYXRpdmUgOiByZUlzSG9zdEN0b3I7XG4gICAgICByZXR1cm4gcGF0dGVybi50ZXN0KHRvU291cmNlKHZhbHVlKSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8uaXNSZWdFeHBgIHdpdGhvdXQgTm9kZS5qcyBvcHRpbWl6YXRpb25zLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjaGVjay5cbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBhIHJlZ2V4cCwgZWxzZSBgZmFsc2VgLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGJhc2VJc1JlZ0V4cCh2YWx1ZSkge1xuICAgICAgcmV0dXJuIGlzT2JqZWN0TGlrZSh2YWx1ZSkgJiYgYmFzZUdldFRhZyh2YWx1ZSkgPT0gcmVnZXhwVGFnO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLmlzU2V0YCB3aXRob3V0IE5vZGUuanMgb3B0aW1pemF0aW9ucy5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY2hlY2suXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGB2YWx1ZWAgaXMgYSBzZXQsIGVsc2UgYGZhbHNlYC5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBiYXNlSXNTZXQodmFsdWUpIHtcbiAgICAgIHJldHVybiBpc09iamVjdExpa2UodmFsdWUpICYmIGdldFRhZyh2YWx1ZSkgPT0gc2V0VGFnO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLmlzVHlwZWRBcnJheWAgd2l0aG91dCBOb2RlLmpzIG9wdGltaXphdGlvbnMuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrLlxuICAgICAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlzIGEgdHlwZWQgYXJyYXksIGVsc2UgYGZhbHNlYC5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBiYXNlSXNUeXBlZEFycmF5KHZhbHVlKSB7XG4gICAgICByZXR1cm4gaXNPYmplY3RMaWtlKHZhbHVlKSAmJlxuICAgICAgICBpc0xlbmd0aCh2YWx1ZS5sZW5ndGgpICYmICEhdHlwZWRBcnJheVRhZ3NbYmFzZUdldFRhZyh2YWx1ZSldO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLml0ZXJhdGVlYC5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHsqfSBbdmFsdWU9Xy5pZGVudGl0eV0gVGhlIHZhbHVlIHRvIGNvbnZlcnQgdG8gYW4gaXRlcmF0ZWUuXG4gICAgICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBpdGVyYXRlZS5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBiYXNlSXRlcmF0ZWUodmFsdWUpIHtcbiAgICAgIC8vIERvbid0IHN0b3JlIHRoZSBgdHlwZW9mYCByZXN1bHQgaW4gYSB2YXJpYWJsZSB0byBhdm9pZCBhIEpJVCBidWcgaW4gU2FmYXJpIDkuXG4gICAgICAvLyBTZWUgaHR0cHM6Ly9idWdzLndlYmtpdC5vcmcvc2hvd19idWcuY2dpP2lkPTE1NjAzNCBmb3IgbW9yZSBkZXRhaWxzLlxuICAgICAgaWYgKHR5cGVvZiB2YWx1ZSA9PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgIHJldHVybiB2YWx1ZTtcbiAgICAgIH1cbiAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7XG4gICAgICAgIHJldHVybiBpZGVudGl0eTtcbiAgICAgIH1cbiAgICAgIGlmICh0eXBlb2YgdmFsdWUgPT0gJ29iamVjdCcpIHtcbiAgICAgICAgcmV0dXJuIGlzQXJyYXkodmFsdWUpXG4gICAgICAgICAgPyBiYXNlTWF0Y2hlc1Byb3BlcnR5KHZhbHVlWzBdLCB2YWx1ZVsxXSlcbiAgICAgICAgICA6IGJhc2VNYXRjaGVzKHZhbHVlKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBwcm9wZXJ0eSh2YWx1ZSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8ua2V5c2Agd2hpY2ggZG9lc24ndCB0cmVhdCBzcGFyc2UgYXJyYXlzIGFzIGRlbnNlLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gcXVlcnkuXG4gICAgICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBhcnJheSBvZiBwcm9wZXJ0eSBuYW1lcy5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBiYXNlS2V5cyhvYmplY3QpIHtcbiAgICAgIGlmICghaXNQcm90b3R5cGUob2JqZWN0KSkge1xuICAgICAgICByZXR1cm4gbmF0aXZlS2V5cyhvYmplY3QpO1xuICAgICAgfVxuICAgICAgdmFyIHJlc3VsdCA9IFtdO1xuICAgICAgZm9yICh2YXIga2V5IGluIE9iamVjdChvYmplY3QpKSB7XG4gICAgICAgIGlmIChoYXNPd25Qcm9wZXJ0eS5jYWxsKG9iamVjdCwga2V5KSAmJiBrZXkgIT0gJ2NvbnN0cnVjdG9yJykge1xuICAgICAgICAgIHJlc3VsdC5wdXNoKGtleSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8ua2V5c0luYCB3aGljaCBkb2Vzbid0IHRyZWF0IHNwYXJzZSBhcnJheXMgYXMgZGVuc2UuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBxdWVyeS5cbiAgICAgKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIGFycmF5IG9mIHByb3BlcnR5IG5hbWVzLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGJhc2VLZXlzSW4ob2JqZWN0KSB7XG4gICAgICBpZiAoIWlzT2JqZWN0KG9iamVjdCkpIHtcbiAgICAgICAgcmV0dXJuIG5hdGl2ZUtleXNJbihvYmplY3QpO1xuICAgICAgfVxuICAgICAgdmFyIGlzUHJvdG8gPSBpc1Byb3RvdHlwZShvYmplY3QpLFxuICAgICAgICAgIHJlc3VsdCA9IFtdO1xuXG4gICAgICBmb3IgKHZhciBrZXkgaW4gb2JqZWN0KSB7XG4gICAgICAgIGlmICghKGtleSA9PSAnY29uc3RydWN0b3InICYmIChpc1Byb3RvIHx8ICFoYXNPd25Qcm9wZXJ0eS5jYWxsKG9iamVjdCwga2V5KSkpKSB7XG4gICAgICAgICAgcmVzdWx0LnB1c2goa2V5KTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5sdGAgd2hpY2ggZG9lc24ndCBjb2VyY2UgYXJndW1lbnRzLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjb21wYXJlLlxuICAgICAqIEBwYXJhbSB7Kn0gb3RoZXIgVGhlIG90aGVyIHZhbHVlIHRvIGNvbXBhcmUuXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGB2YWx1ZWAgaXMgbGVzcyB0aGFuIGBvdGhlcmAsXG4gICAgICogIGVsc2UgYGZhbHNlYC5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBiYXNlTHQodmFsdWUsIG90aGVyKSB7XG4gICAgICByZXR1cm4gdmFsdWUgPCBvdGhlcjtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5tYXBgIHdpdGhvdXQgc3VwcG9ydCBmb3IgaXRlcmF0ZWUgc2hvcnRoYW5kcy5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtBcnJheXxPYmplY3R9IGNvbGxlY3Rpb24gVGhlIGNvbGxlY3Rpb24gdG8gaXRlcmF0ZSBvdmVyLlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IGl0ZXJhdGVlIFRoZSBmdW5jdGlvbiBpbnZva2VkIHBlciBpdGVyYXRpb24uXG4gICAgICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBuZXcgbWFwcGVkIGFycmF5LlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGJhc2VNYXAoY29sbGVjdGlvbiwgaXRlcmF0ZWUpIHtcbiAgICAgIHZhciBpbmRleCA9IC0xLFxuICAgICAgICAgIHJlc3VsdCA9IGlzQXJyYXlMaWtlKGNvbGxlY3Rpb24pID8gQXJyYXkoY29sbGVjdGlvbi5sZW5ndGgpIDogW107XG5cbiAgICAgIGJhc2VFYWNoKGNvbGxlY3Rpb24sIGZ1bmN0aW9uKHZhbHVlLCBrZXksIGNvbGxlY3Rpb24pIHtcbiAgICAgICAgcmVzdWx0WysraW5kZXhdID0gaXRlcmF0ZWUodmFsdWUsIGtleSwgY29sbGVjdGlvbik7XG4gICAgICB9KTtcbiAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8ubWF0Y2hlc2Agd2hpY2ggZG9lc24ndCBjbG9uZSBgc291cmNlYC5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtPYmplY3R9IHNvdXJjZSBUaGUgb2JqZWN0IG9mIHByb3BlcnR5IHZhbHVlcyB0byBtYXRjaC5cbiAgICAgKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyBzcGVjIGZ1bmN0aW9uLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGJhc2VNYXRjaGVzKHNvdXJjZSkge1xuICAgICAgdmFyIG1hdGNoRGF0YSA9IGdldE1hdGNoRGF0YShzb3VyY2UpO1xuICAgICAgaWYgKG1hdGNoRGF0YS5sZW5ndGggPT0gMSAmJiBtYXRjaERhdGFbMF1bMl0pIHtcbiAgICAgICAgcmV0dXJuIG1hdGNoZXNTdHJpY3RDb21wYXJhYmxlKG1hdGNoRGF0YVswXVswXSwgbWF0Y2hEYXRhWzBdWzFdKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBmdW5jdGlvbihvYmplY3QpIHtcbiAgICAgICAgcmV0dXJuIG9iamVjdCA9PT0gc291cmNlIHx8IGJhc2VJc01hdGNoKG9iamVjdCwgc291cmNlLCBtYXRjaERhdGEpO1xuICAgICAgfTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5tYXRjaGVzUHJvcGVydHlgIHdoaWNoIGRvZXNuJ3QgY2xvbmUgYHNyY1ZhbHVlYC5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IHBhdGggVGhlIHBhdGggb2YgdGhlIHByb3BlcnR5IHRvIGdldC5cbiAgICAgKiBAcGFyYW0geyp9IHNyY1ZhbHVlIFRoZSB2YWx1ZSB0byBtYXRjaC5cbiAgICAgKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyBzcGVjIGZ1bmN0aW9uLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGJhc2VNYXRjaGVzUHJvcGVydHkocGF0aCwgc3JjVmFsdWUpIHtcbiAgICAgIGlmIChpc0tleShwYXRoKSAmJiBpc1N0cmljdENvbXBhcmFibGUoc3JjVmFsdWUpKSB7XG4gICAgICAgIHJldHVybiBtYXRjaGVzU3RyaWN0Q29tcGFyYWJsZSh0b0tleShwYXRoKSwgc3JjVmFsdWUpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGZ1bmN0aW9uKG9iamVjdCkge1xuICAgICAgICB2YXIgb2JqVmFsdWUgPSBnZXQob2JqZWN0LCBwYXRoKTtcbiAgICAgICAgcmV0dXJuIChvYmpWYWx1ZSA9PT0gdW5kZWZpbmVkICYmIG9ialZhbHVlID09PSBzcmNWYWx1ZSlcbiAgICAgICAgICA/IGhhc0luKG9iamVjdCwgcGF0aClcbiAgICAgICAgICA6IGJhc2VJc0VxdWFsKHNyY1ZhbHVlLCBvYmpWYWx1ZSwgQ09NUEFSRV9QQVJUSUFMX0ZMQUcgfCBDT01QQVJFX1VOT1JERVJFRF9GTEFHKTtcbiAgICAgIH07XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8ubWVyZ2VgIHdpdGhvdXQgc3VwcG9ydCBmb3IgbXVsdGlwbGUgc291cmNlcy5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgZGVzdGluYXRpb24gb2JqZWN0LlxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBzb3VyY2UgVGhlIHNvdXJjZSBvYmplY3QuXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IHNyY0luZGV4IFRoZSBpbmRleCBvZiBgc291cmNlYC5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBbY3VzdG9taXplcl0gVGhlIGZ1bmN0aW9uIHRvIGN1c3RvbWl6ZSBtZXJnZWQgdmFsdWVzLlxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBbc3RhY2tdIFRyYWNrcyB0cmF2ZXJzZWQgc291cmNlIHZhbHVlcyBhbmQgdGhlaXIgbWVyZ2VkXG4gICAgICogIGNvdW50ZXJwYXJ0cy5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBiYXNlTWVyZ2Uob2JqZWN0LCBzb3VyY2UsIHNyY0luZGV4LCBjdXN0b21pemVyLCBzdGFjaykge1xuICAgICAgaWYgKG9iamVjdCA9PT0gc291cmNlKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIGJhc2VGb3Ioc291cmNlLCBmdW5jdGlvbihzcmNWYWx1ZSwga2V5KSB7XG4gICAgICAgIGlmIChpc09iamVjdChzcmNWYWx1ZSkpIHtcbiAgICAgICAgICBzdGFjayB8fCAoc3RhY2sgPSBuZXcgU3RhY2spO1xuICAgICAgICAgIGJhc2VNZXJnZURlZXAob2JqZWN0LCBzb3VyY2UsIGtleSwgc3JjSW5kZXgsIGJhc2VNZXJnZSwgY3VzdG9taXplciwgc3RhY2spO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgIHZhciBuZXdWYWx1ZSA9IGN1c3RvbWl6ZXJcbiAgICAgICAgICAgID8gY3VzdG9taXplcihvYmplY3Rba2V5XSwgc3JjVmFsdWUsIChrZXkgKyAnJyksIG9iamVjdCwgc291cmNlLCBzdGFjaylcbiAgICAgICAgICAgIDogdW5kZWZpbmVkO1xuXG4gICAgICAgICAgaWYgKG5ld1ZhbHVlID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIG5ld1ZhbHVlID0gc3JjVmFsdWU7XG4gICAgICAgICAgfVxuICAgICAgICAgIGFzc2lnbk1lcmdlVmFsdWUob2JqZWN0LCBrZXksIG5ld1ZhbHVlKTtcbiAgICAgICAgfVxuICAgICAgfSwga2V5c0luKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBBIHNwZWNpYWxpemVkIHZlcnNpb24gb2YgYGJhc2VNZXJnZWAgZm9yIGFycmF5cyBhbmQgb2JqZWN0cyB3aGljaCBwZXJmb3Jtc1xuICAgICAqIGRlZXAgbWVyZ2VzIGFuZCB0cmFja3MgdHJhdmVyc2VkIG9iamVjdHMgZW5hYmxpbmcgb2JqZWN0cyB3aXRoIGNpcmN1bGFyXG4gICAgICogcmVmZXJlbmNlcyB0byBiZSBtZXJnZWQuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIGRlc3RpbmF0aW9uIG9iamVjdC5cbiAgICAgKiBAcGFyYW0ge09iamVjdH0gc291cmNlIFRoZSBzb3VyY2Ugb2JqZWN0LlxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBrZXkgVGhlIGtleSBvZiB0aGUgdmFsdWUgdG8gbWVyZ2UuXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IHNyY0luZGV4IFRoZSBpbmRleCBvZiBgc291cmNlYC5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBtZXJnZUZ1bmMgVGhlIGZ1bmN0aW9uIHRvIG1lcmdlIHZhbHVlcy5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBbY3VzdG9taXplcl0gVGhlIGZ1bmN0aW9uIHRvIGN1c3RvbWl6ZSBhc3NpZ25lZCB2YWx1ZXMuXG4gICAgICogQHBhcmFtIHtPYmplY3R9IFtzdGFja10gVHJhY2tzIHRyYXZlcnNlZCBzb3VyY2UgdmFsdWVzIGFuZCB0aGVpciBtZXJnZWRcbiAgICAgKiAgY291bnRlcnBhcnRzLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGJhc2VNZXJnZURlZXAob2JqZWN0LCBzb3VyY2UsIGtleSwgc3JjSW5kZXgsIG1lcmdlRnVuYywgY3VzdG9taXplciwgc3RhY2spIHtcbiAgICAgIHZhciBvYmpWYWx1ZSA9IG9iamVjdFtrZXldLFxuICAgICAgICAgIHNyY1ZhbHVlID0gc291cmNlW2tleV0sXG4gICAgICAgICAgc3RhY2tlZCA9IHN0YWNrLmdldChzcmNWYWx1ZSk7XG5cbiAgICAgIGlmIChzdGFja2VkKSB7XG4gICAgICAgIGFzc2lnbk1lcmdlVmFsdWUob2JqZWN0LCBrZXksIHN0YWNrZWQpO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICB2YXIgbmV3VmFsdWUgPSBjdXN0b21pemVyXG4gICAgICAgID8gY3VzdG9taXplcihvYmpWYWx1ZSwgc3JjVmFsdWUsIChrZXkgKyAnJyksIG9iamVjdCwgc291cmNlLCBzdGFjaylcbiAgICAgICAgOiB1bmRlZmluZWQ7XG5cbiAgICAgIHZhciBpc0NvbW1vbiA9IG5ld1ZhbHVlID09PSB1bmRlZmluZWQ7XG5cbiAgICAgIGlmIChpc0NvbW1vbikge1xuICAgICAgICB2YXIgaXNBcnIgPSBpc0FycmF5KHNyY1ZhbHVlKSxcbiAgICAgICAgICAgIGlzQnVmZiA9ICFpc0FyciAmJiBpc0J1ZmZlcihzcmNWYWx1ZSksXG4gICAgICAgICAgICBpc1R5cGVkID0gIWlzQXJyICYmICFpc0J1ZmYgJiYgaXNUeXBlZEFycmF5KHNyY1ZhbHVlKTtcblxuICAgICAgICBuZXdWYWx1ZSA9IHNyY1ZhbHVlO1xuICAgICAgICBpZiAoaXNBcnIgfHwgaXNCdWZmIHx8IGlzVHlwZWQpIHtcbiAgICAgICAgICBpZiAoaXNBcnJheShvYmpWYWx1ZSkpIHtcbiAgICAgICAgICAgIG5ld1ZhbHVlID0gb2JqVmFsdWU7XG4gICAgICAgICAgfVxuICAgICAgICAgIGVsc2UgaWYgKGlzQXJyYXlMaWtlT2JqZWN0KG9ialZhbHVlKSkge1xuICAgICAgICAgICAgbmV3VmFsdWUgPSBjb3B5QXJyYXkob2JqVmFsdWUpO1xuICAgICAgICAgIH1cbiAgICAgICAgICBlbHNlIGlmIChpc0J1ZmYpIHtcbiAgICAgICAgICAgIGlzQ29tbW9uID0gZmFsc2U7XG4gICAgICAgICAgICBuZXdWYWx1ZSA9IGNsb25lQnVmZmVyKHNyY1ZhbHVlLCB0cnVlKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgZWxzZSBpZiAoaXNUeXBlZCkge1xuICAgICAgICAgICAgaXNDb21tb24gPSBmYWxzZTtcbiAgICAgICAgICAgIG5ld1ZhbHVlID0gY2xvbmVUeXBlZEFycmF5KHNyY1ZhbHVlLCB0cnVlKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBuZXdWYWx1ZSA9IFtdO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmIChpc1BsYWluT2JqZWN0KHNyY1ZhbHVlKSB8fCBpc0FyZ3VtZW50cyhzcmNWYWx1ZSkpIHtcbiAgICAgICAgICBuZXdWYWx1ZSA9IG9ialZhbHVlO1xuICAgICAgICAgIGlmIChpc0FyZ3VtZW50cyhvYmpWYWx1ZSkpIHtcbiAgICAgICAgICAgIG5ld1ZhbHVlID0gdG9QbGFpbk9iamVjdChvYmpWYWx1ZSk7XG4gICAgICAgICAgfVxuICAgICAgICAgIGVsc2UgaWYgKCFpc09iamVjdChvYmpWYWx1ZSkgfHwgKHNyY0luZGV4ICYmIGlzRnVuY3Rpb24ob2JqVmFsdWUpKSkge1xuICAgICAgICAgICAgbmV3VmFsdWUgPSBpbml0Q2xvbmVPYmplY3Qoc3JjVmFsdWUpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICBpc0NvbW1vbiA9IGZhbHNlO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBpZiAoaXNDb21tb24pIHtcbiAgICAgICAgLy8gUmVjdXJzaXZlbHkgbWVyZ2Ugb2JqZWN0cyBhbmQgYXJyYXlzIChzdXNjZXB0aWJsZSB0byBjYWxsIHN0YWNrIGxpbWl0cykuXG4gICAgICAgIHN0YWNrLnNldChzcmNWYWx1ZSwgbmV3VmFsdWUpO1xuICAgICAgICBtZXJnZUZ1bmMobmV3VmFsdWUsIHNyY1ZhbHVlLCBzcmNJbmRleCwgY3VzdG9taXplciwgc3RhY2spO1xuICAgICAgICBzdGFja1snZGVsZXRlJ10oc3JjVmFsdWUpO1xuICAgICAgfVxuICAgICAgYXNzaWduTWVyZ2VWYWx1ZShvYmplY3QsIGtleSwgbmV3VmFsdWUpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLm50aGAgd2hpY2ggZG9lc24ndCBjb2VyY2UgYXJndW1lbnRzLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBhcnJheSBUaGUgYXJyYXkgdG8gcXVlcnkuXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IG4gVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi5cbiAgICAgKiBAcmV0dXJucyB7Kn0gUmV0dXJucyB0aGUgbnRoIGVsZW1lbnQgb2YgYGFycmF5YC5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBiYXNlTnRoKGFycmF5LCBuKSB7XG4gICAgICB2YXIgbGVuZ3RoID0gYXJyYXkubGVuZ3RoO1xuICAgICAgaWYgKCFsZW5ndGgpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgbiArPSBuIDwgMCA/IGxlbmd0aCA6IDA7XG4gICAgICByZXR1cm4gaXNJbmRleChuLCBsZW5ndGgpID8gYXJyYXlbbl0gOiB1bmRlZmluZWQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8ub3JkZXJCeWAgd2l0aG91dCBwYXJhbSBndWFyZHMuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7QXJyYXl8T2JqZWN0fSBjb2xsZWN0aW9uIFRoZSBjb2xsZWN0aW9uIHRvIGl0ZXJhdGUgb3Zlci5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9uW118T2JqZWN0W118c3RyaW5nW119IGl0ZXJhdGVlcyBUaGUgaXRlcmF0ZWVzIHRvIHNvcnQgYnkuXG4gICAgICogQHBhcmFtIHtzdHJpbmdbXX0gb3JkZXJzIFRoZSBzb3J0IG9yZGVycyBvZiBgaXRlcmF0ZWVzYC5cbiAgICAgKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIG5ldyBzb3J0ZWQgYXJyYXkuXG4gICAgICovXG4gICAgZnVuY3Rpb24gYmFzZU9yZGVyQnkoY29sbGVjdGlvbiwgaXRlcmF0ZWVzLCBvcmRlcnMpIHtcbiAgICAgIHZhciBpbmRleCA9IC0xO1xuICAgICAgaXRlcmF0ZWVzID0gYXJyYXlNYXAoaXRlcmF0ZWVzLmxlbmd0aCA/IGl0ZXJhdGVlcyA6IFtpZGVudGl0eV0sIGJhc2VVbmFyeShnZXRJdGVyYXRlZSgpKSk7XG5cbiAgICAgIHZhciByZXN1bHQgPSBiYXNlTWFwKGNvbGxlY3Rpb24sIGZ1bmN0aW9uKHZhbHVlLCBrZXksIGNvbGxlY3Rpb24pIHtcbiAgICAgICAgdmFyIGNyaXRlcmlhID0gYXJyYXlNYXAoaXRlcmF0ZWVzLCBmdW5jdGlvbihpdGVyYXRlZSkge1xuICAgICAgICAgIHJldHVybiBpdGVyYXRlZSh2YWx1ZSk7XG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm4geyAnY3JpdGVyaWEnOiBjcml0ZXJpYSwgJ2luZGV4JzogKytpbmRleCwgJ3ZhbHVlJzogdmFsdWUgfTtcbiAgICAgIH0pO1xuXG4gICAgICByZXR1cm4gYmFzZVNvcnRCeShyZXN1bHQsIGZ1bmN0aW9uKG9iamVjdCwgb3RoZXIpIHtcbiAgICAgICAgcmV0dXJuIGNvbXBhcmVNdWx0aXBsZShvYmplY3QsIG90aGVyLCBvcmRlcnMpO1xuICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8ucGlja2Agd2l0aG91dCBzdXBwb3J0IGZvciBpbmRpdmlkdWFsXG4gICAgICogcHJvcGVydHkgaWRlbnRpZmllcnMuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIHNvdXJjZSBvYmplY3QuXG4gICAgICogQHBhcmFtIHtzdHJpbmdbXX0gcGF0aHMgVGhlIHByb3BlcnR5IHBhdGhzIHRvIHBpY2suXG4gICAgICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyB0aGUgbmV3IG9iamVjdC5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBiYXNlUGljayhvYmplY3QsIHBhdGhzKSB7XG4gICAgICByZXR1cm4gYmFzZVBpY2tCeShvYmplY3QsIHBhdGhzLCBmdW5jdGlvbih2YWx1ZSwgcGF0aCkge1xuICAgICAgICByZXR1cm4gaGFzSW4ob2JqZWN0LCBwYXRoKTtcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mICBgXy5waWNrQnlgIHdpdGhvdXQgc3VwcG9ydCBmb3IgaXRlcmF0ZWUgc2hvcnRoYW5kcy5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgc291cmNlIG9iamVjdC5cbiAgICAgKiBAcGFyYW0ge3N0cmluZ1tdfSBwYXRocyBUaGUgcHJvcGVydHkgcGF0aHMgdG8gcGljay5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBwcmVkaWNhdGUgVGhlIGZ1bmN0aW9uIGludm9rZWQgcGVyIHByb3BlcnR5LlxuICAgICAqIEByZXR1cm5zIHtPYmplY3R9IFJldHVybnMgdGhlIG5ldyBvYmplY3QuXG4gICAgICovXG4gICAgZnVuY3Rpb24gYmFzZVBpY2tCeShvYmplY3QsIHBhdGhzLCBwcmVkaWNhdGUpIHtcbiAgICAgIHZhciBpbmRleCA9IC0xLFxuICAgICAgICAgIGxlbmd0aCA9IHBhdGhzLmxlbmd0aCxcbiAgICAgICAgICByZXN1bHQgPSB7fTtcblxuICAgICAgd2hpbGUgKCsraW5kZXggPCBsZW5ndGgpIHtcbiAgICAgICAgdmFyIHBhdGggPSBwYXRoc1tpbmRleF0sXG4gICAgICAgICAgICB2YWx1ZSA9IGJhc2VHZXQob2JqZWN0LCBwYXRoKTtcblxuICAgICAgICBpZiAocHJlZGljYXRlKHZhbHVlLCBwYXRoKSkge1xuICAgICAgICAgIGJhc2VTZXQocmVzdWx0LCBjYXN0UGF0aChwYXRoLCBvYmplY3QpLCB2YWx1ZSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQSBzcGVjaWFsaXplZCB2ZXJzaW9uIG9mIGBiYXNlUHJvcGVydHlgIHdoaWNoIHN1cHBvcnRzIGRlZXAgcGF0aHMuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7QXJyYXl8c3RyaW5nfSBwYXRoIFRoZSBwYXRoIG9mIHRoZSBwcm9wZXJ0eSB0byBnZXQuXG4gICAgICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBuZXcgYWNjZXNzb3IgZnVuY3Rpb24uXG4gICAgICovXG4gICAgZnVuY3Rpb24gYmFzZVByb3BlcnR5RGVlcChwYXRoKSB7XG4gICAgICByZXR1cm4gZnVuY3Rpb24ob2JqZWN0KSB7XG4gICAgICAgIHJldHVybiBiYXNlR2V0KG9iamVjdCwgcGF0aCk7XG4gICAgICB9O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLnB1bGxBbGxCeWAgd2l0aG91dCBzdXBwb3J0IGZvciBpdGVyYXRlZVxuICAgICAqIHNob3J0aGFuZHMuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBhcnJheSB0byBtb2RpZnkuXG4gICAgICogQHBhcmFtIHtBcnJheX0gdmFsdWVzIFRoZSB2YWx1ZXMgdG8gcmVtb3ZlLlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IFtpdGVyYXRlZV0gVGhlIGl0ZXJhdGVlIGludm9rZWQgcGVyIGVsZW1lbnQuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gW2NvbXBhcmF0b3JdIFRoZSBjb21wYXJhdG9yIGludm9rZWQgcGVyIGVsZW1lbnQuXG4gICAgICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIGBhcnJheWAuXG4gICAgICovXG4gICAgZnVuY3Rpb24gYmFzZVB1bGxBbGwoYXJyYXksIHZhbHVlcywgaXRlcmF0ZWUsIGNvbXBhcmF0b3IpIHtcbiAgICAgIHZhciBpbmRleE9mID0gY29tcGFyYXRvciA/IGJhc2VJbmRleE9mV2l0aCA6IGJhc2VJbmRleE9mLFxuICAgICAgICAgIGluZGV4ID0gLTEsXG4gICAgICAgICAgbGVuZ3RoID0gdmFsdWVzLmxlbmd0aCxcbiAgICAgICAgICBzZWVuID0gYXJyYXk7XG5cbiAgICAgIGlmIChhcnJheSA9PT0gdmFsdWVzKSB7XG4gICAgICAgIHZhbHVlcyA9IGNvcHlBcnJheSh2YWx1ZXMpO1xuICAgICAgfVxuICAgICAgaWYgKGl0ZXJhdGVlKSB7XG4gICAgICAgIHNlZW4gPSBhcnJheU1hcChhcnJheSwgYmFzZVVuYXJ5KGl0ZXJhdGVlKSk7XG4gICAgICB9XG4gICAgICB3aGlsZSAoKytpbmRleCA8IGxlbmd0aCkge1xuICAgICAgICB2YXIgZnJvbUluZGV4ID0gMCxcbiAgICAgICAgICAgIHZhbHVlID0gdmFsdWVzW2luZGV4XSxcbiAgICAgICAgICAgIGNvbXB1dGVkID0gaXRlcmF0ZWUgPyBpdGVyYXRlZSh2YWx1ZSkgOiB2YWx1ZTtcblxuICAgICAgICB3aGlsZSAoKGZyb21JbmRleCA9IGluZGV4T2Yoc2VlbiwgY29tcHV0ZWQsIGZyb21JbmRleCwgY29tcGFyYXRvcikpID4gLTEpIHtcbiAgICAgICAgICBpZiAoc2VlbiAhPT0gYXJyYXkpIHtcbiAgICAgICAgICAgIHNwbGljZS5jYWxsKHNlZW4sIGZyb21JbmRleCwgMSk7XG4gICAgICAgICAgfVxuICAgICAgICAgIHNwbGljZS5jYWxsKGFycmF5LCBmcm9tSW5kZXgsIDEpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICByZXR1cm4gYXJyYXk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8ucHVsbEF0YCB3aXRob3V0IHN1cHBvcnQgZm9yIGluZGl2aWR1YWxcbiAgICAgKiBpbmRleGVzIG9yIGNhcHR1cmluZyB0aGUgcmVtb3ZlZCBlbGVtZW50cy5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIG1vZGlmeS5cbiAgICAgKiBAcGFyYW0ge251bWJlcltdfSBpbmRleGVzIFRoZSBpbmRleGVzIG9mIGVsZW1lbnRzIHRvIHJlbW92ZS5cbiAgICAgKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgYGFycmF5YC5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBiYXNlUHVsbEF0KGFycmF5LCBpbmRleGVzKSB7XG4gICAgICB2YXIgbGVuZ3RoID0gYXJyYXkgPyBpbmRleGVzLmxlbmd0aCA6IDAsXG4gICAgICAgICAgbGFzdEluZGV4ID0gbGVuZ3RoIC0gMTtcblxuICAgICAgd2hpbGUgKGxlbmd0aC0tKSB7XG4gICAgICAgIHZhciBpbmRleCA9IGluZGV4ZXNbbGVuZ3RoXTtcbiAgICAgICAgaWYgKGxlbmd0aCA9PSBsYXN0SW5kZXggfHwgaW5kZXggIT09IHByZXZpb3VzKSB7XG4gICAgICAgICAgdmFyIHByZXZpb3VzID0gaW5kZXg7XG4gICAgICAgICAgaWYgKGlzSW5kZXgoaW5kZXgpKSB7XG4gICAgICAgICAgICBzcGxpY2UuY2FsbChhcnJheSwgaW5kZXgsIDEpO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBiYXNlVW5zZXQoYXJyYXksIGluZGV4KTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHJldHVybiBhcnJheTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5yYW5kb21gIHdpdGhvdXQgc3VwcG9ydCBmb3IgcmV0dXJuaW5nXG4gICAgICogZmxvYXRpbmctcG9pbnQgbnVtYmVycy5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IGxvd2VyIFRoZSBsb3dlciBib3VuZC5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gdXBwZXIgVGhlIHVwcGVyIGJvdW5kLlxuICAgICAqIEByZXR1cm5zIHtudW1iZXJ9IFJldHVybnMgdGhlIHJhbmRvbSBudW1iZXIuXG4gICAgICovXG4gICAgZnVuY3Rpb24gYmFzZVJhbmRvbShsb3dlciwgdXBwZXIpIHtcbiAgICAgIHJldHVybiBsb3dlciArIG5hdGl2ZUZsb29yKG5hdGl2ZVJhbmRvbSgpICogKHVwcGVyIC0gbG93ZXIgKyAxKSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8ucmFuZ2VgIGFuZCBgXy5yYW5nZVJpZ2h0YCB3aGljaCBkb2Vzbid0XG4gICAgICogY29lcmNlIGFyZ3VtZW50cy5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IHN0YXJ0IFRoZSBzdGFydCBvZiB0aGUgcmFuZ2UuXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IGVuZCBUaGUgZW5kIG9mIHRoZSByYW5nZS5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gc3RlcCBUaGUgdmFsdWUgdG8gaW5jcmVtZW50IG9yIGRlY3JlbWVudCBieS5cbiAgICAgKiBAcGFyYW0ge2Jvb2xlYW59IFtmcm9tUmlnaHRdIFNwZWNpZnkgaXRlcmF0aW5nIGZyb20gcmlnaHQgdG8gbGVmdC5cbiAgICAgKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIHJhbmdlIG9mIG51bWJlcnMuXG4gICAgICovXG4gICAgZnVuY3Rpb24gYmFzZVJhbmdlKHN0YXJ0LCBlbmQsIHN0ZXAsIGZyb21SaWdodCkge1xuICAgICAgdmFyIGluZGV4ID0gLTEsXG4gICAgICAgICAgbGVuZ3RoID0gbmF0aXZlTWF4KG5hdGl2ZUNlaWwoKGVuZCAtIHN0YXJ0KSAvIChzdGVwIHx8IDEpKSwgMCksXG4gICAgICAgICAgcmVzdWx0ID0gQXJyYXkobGVuZ3RoKTtcblxuICAgICAgd2hpbGUgKGxlbmd0aC0tKSB7XG4gICAgICAgIHJlc3VsdFtmcm9tUmlnaHQgPyBsZW5ndGggOiArK2luZGV4XSA9IHN0YXJ0O1xuICAgICAgICBzdGFydCArPSBzdGVwO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5yZXBlYXRgIHdoaWNoIGRvZXNuJ3QgY29lcmNlIGFyZ3VtZW50cy5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IHN0cmluZyBUaGUgc3RyaW5nIHRvIHJlcGVhdC5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gbiBUaGUgbnVtYmVyIG9mIHRpbWVzIHRvIHJlcGVhdCB0aGUgc3RyaW5nLlxuICAgICAqIEByZXR1cm5zIHtzdHJpbmd9IFJldHVybnMgdGhlIHJlcGVhdGVkIHN0cmluZy5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBiYXNlUmVwZWF0KHN0cmluZywgbikge1xuICAgICAgdmFyIHJlc3VsdCA9ICcnO1xuICAgICAgaWYgKCFzdHJpbmcgfHwgbiA8IDEgfHwgbiA+IE1BWF9TQUZFX0lOVEVHRVIpIHtcbiAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICAgIH1cbiAgICAgIC8vIExldmVyYWdlIHRoZSBleHBvbmVudGlhdGlvbiBieSBzcXVhcmluZyBhbGdvcml0aG0gZm9yIGEgZmFzdGVyIHJlcGVhdC5cbiAgICAgIC8vIFNlZSBodHRwczovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9FeHBvbmVudGlhdGlvbl9ieV9zcXVhcmluZyBmb3IgbW9yZSBkZXRhaWxzLlxuICAgICAgZG8ge1xuICAgICAgICBpZiAobiAlIDIpIHtcbiAgICAgICAgICByZXN1bHQgKz0gc3RyaW5nO1xuICAgICAgICB9XG4gICAgICAgIG4gPSBuYXRpdmVGbG9vcihuIC8gMik7XG4gICAgICAgIGlmIChuKSB7XG4gICAgICAgICAgc3RyaW5nICs9IHN0cmluZztcbiAgICAgICAgfVxuICAgICAgfSB3aGlsZSAobik7XG5cbiAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8ucmVzdGAgd2hpY2ggZG9lc24ndCB2YWxpZGF0ZSBvciBjb2VyY2UgYXJndW1lbnRzLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBmdW5jIFRoZSBmdW5jdGlvbiB0byBhcHBseSBhIHJlc3QgcGFyYW1ldGVyIHRvLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbc3RhcnQ9ZnVuYy5sZW5ndGgtMV0gVGhlIHN0YXJ0IHBvc2l0aW9uIG9mIHRoZSByZXN0IHBhcmFtZXRlci5cbiAgICAgKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyBmdW5jdGlvbi5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBiYXNlUmVzdChmdW5jLCBzdGFydCkge1xuICAgICAgcmV0dXJuIHNldFRvU3RyaW5nKG92ZXJSZXN0KGZ1bmMsIHN0YXJ0LCBpZGVudGl0eSksIGZ1bmMgKyAnJyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8uc2FtcGxlYC5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtBcnJheXxPYmplY3R9IGNvbGxlY3Rpb24gVGhlIGNvbGxlY3Rpb24gdG8gc2FtcGxlLlxuICAgICAqIEByZXR1cm5zIHsqfSBSZXR1cm5zIHRoZSByYW5kb20gZWxlbWVudC5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBiYXNlU2FtcGxlKGNvbGxlY3Rpb24pIHtcbiAgICAgIHJldHVybiBhcnJheVNhbXBsZSh2YWx1ZXMoY29sbGVjdGlvbikpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLnNhbXBsZVNpemVgIHdpdGhvdXQgcGFyYW0gZ3VhcmRzLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge0FycmF5fE9iamVjdH0gY29sbGVjdGlvbiBUaGUgY29sbGVjdGlvbiB0byBzYW1wbGUuXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IG4gVGhlIG51bWJlciBvZiBlbGVtZW50cyB0byBzYW1wbGUuXG4gICAgICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSByYW5kb20gZWxlbWVudHMuXG4gICAgICovXG4gICAgZnVuY3Rpb24gYmFzZVNhbXBsZVNpemUoY29sbGVjdGlvbiwgbikge1xuICAgICAgdmFyIGFycmF5ID0gdmFsdWVzKGNvbGxlY3Rpb24pO1xuICAgICAgcmV0dXJuIHNodWZmbGVTZWxmKGFycmF5LCBiYXNlQ2xhbXAobiwgMCwgYXJyYXkubGVuZ3RoKSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8uc2V0YC5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIG1vZGlmeS5cbiAgICAgKiBAcGFyYW0ge0FycmF5fHN0cmluZ30gcGF0aCBUaGUgcGF0aCBvZiB0aGUgcHJvcGVydHkgdG8gc2V0LlxuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIHNldC5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBbY3VzdG9taXplcl0gVGhlIGZ1bmN0aW9uIHRvIGN1c3RvbWl6ZSBwYXRoIGNyZWF0aW9uLlxuICAgICAqIEByZXR1cm5zIHtPYmplY3R9IFJldHVybnMgYG9iamVjdGAuXG4gICAgICovXG4gICAgZnVuY3Rpb24gYmFzZVNldChvYmplY3QsIHBhdGgsIHZhbHVlLCBjdXN0b21pemVyKSB7XG4gICAgICBpZiAoIWlzT2JqZWN0KG9iamVjdCkpIHtcbiAgICAgICAgcmV0dXJuIG9iamVjdDtcbiAgICAgIH1cbiAgICAgIHBhdGggPSBjYXN0UGF0aChwYXRoLCBvYmplY3QpO1xuXG4gICAgICB2YXIgaW5kZXggPSAtMSxcbiAgICAgICAgICBsZW5ndGggPSBwYXRoLmxlbmd0aCxcbiAgICAgICAgICBsYXN0SW5kZXggPSBsZW5ndGggLSAxLFxuICAgICAgICAgIG5lc3RlZCA9IG9iamVjdDtcblxuICAgICAgd2hpbGUgKG5lc3RlZCAhPSBudWxsICYmICsraW5kZXggPCBsZW5ndGgpIHtcbiAgICAgICAgdmFyIGtleSA9IHRvS2V5KHBhdGhbaW5kZXhdKSxcbiAgICAgICAgICAgIG5ld1ZhbHVlID0gdmFsdWU7XG5cbiAgICAgICAgaWYgKGluZGV4ICE9IGxhc3RJbmRleCkge1xuICAgICAgICAgIHZhciBvYmpWYWx1ZSA9IG5lc3RlZFtrZXldO1xuICAgICAgICAgIG5ld1ZhbHVlID0gY3VzdG9taXplciA/IGN1c3RvbWl6ZXIob2JqVmFsdWUsIGtleSwgbmVzdGVkKSA6IHVuZGVmaW5lZDtcbiAgICAgICAgICBpZiAobmV3VmFsdWUgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgbmV3VmFsdWUgPSBpc09iamVjdChvYmpWYWx1ZSlcbiAgICAgICAgICAgICAgPyBvYmpWYWx1ZVxuICAgICAgICAgICAgICA6IChpc0luZGV4KHBhdGhbaW5kZXggKyAxXSkgPyBbXSA6IHt9KTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgYXNzaWduVmFsdWUobmVzdGVkLCBrZXksIG5ld1ZhbHVlKTtcbiAgICAgICAgbmVzdGVkID0gbmVzdGVkW2tleV07XG4gICAgICB9XG4gICAgICByZXR1cm4gb2JqZWN0O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBzZXREYXRhYCB3aXRob3V0IHN1cHBvcnQgZm9yIGhvdCBsb29wIHNob3J0aW5nLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBmdW5jIFRoZSBmdW5jdGlvbiB0byBhc3NvY2lhdGUgbWV0YWRhdGEgd2l0aC5cbiAgICAgKiBAcGFyYW0geyp9IGRhdGEgVGhlIG1ldGFkYXRhLlxuICAgICAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyBgZnVuY2AuXG4gICAgICovXG4gICAgdmFyIGJhc2VTZXREYXRhID0gIW1ldGFNYXAgPyBpZGVudGl0eSA6IGZ1bmN0aW9uKGZ1bmMsIGRhdGEpIHtcbiAgICAgIG1ldGFNYXAuc2V0KGZ1bmMsIGRhdGEpO1xuICAgICAgcmV0dXJuIGZ1bmM7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBzZXRUb1N0cmluZ2Agd2l0aG91dCBzdXBwb3J0IGZvciBob3QgbG9vcCBzaG9ydGluZy5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gZnVuYyBUaGUgZnVuY3Rpb24gdG8gbW9kaWZ5LlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IHN0cmluZyBUaGUgYHRvU3RyaW5nYCByZXN1bHQuXG4gICAgICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIGBmdW5jYC5cbiAgICAgKi9cbiAgICB2YXIgYmFzZVNldFRvU3RyaW5nID0gIWRlZmluZVByb3BlcnR5ID8gaWRlbnRpdHkgOiBmdW5jdGlvbihmdW5jLCBzdHJpbmcpIHtcbiAgICAgIHJldHVybiBkZWZpbmVQcm9wZXJ0eShmdW5jLCAndG9TdHJpbmcnLCB7XG4gICAgICAgICdjb25maWd1cmFibGUnOiB0cnVlLFxuICAgICAgICAnZW51bWVyYWJsZSc6IGZhbHNlLFxuICAgICAgICAndmFsdWUnOiBjb25zdGFudChzdHJpbmcpLFxuICAgICAgICAnd3JpdGFibGUnOiB0cnVlXG4gICAgICB9KTtcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8uc2h1ZmZsZWAuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7QXJyYXl8T2JqZWN0fSBjb2xsZWN0aW9uIFRoZSBjb2xsZWN0aW9uIHRvIHNodWZmbGUuXG4gICAgICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBuZXcgc2h1ZmZsZWQgYXJyYXkuXG4gICAgICovXG4gICAgZnVuY3Rpb24gYmFzZVNodWZmbGUoY29sbGVjdGlvbikge1xuICAgICAgcmV0dXJuIHNodWZmbGVTZWxmKHZhbHVlcyhjb2xsZWN0aW9uKSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8uc2xpY2VgIHdpdGhvdXQgYW4gaXRlcmF0ZWUgY2FsbCBndWFyZC5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIHNsaWNlLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbc3RhcnQ9MF0gVGhlIHN0YXJ0IHBvc2l0aW9uLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbZW5kPWFycmF5Lmxlbmd0aF0gVGhlIGVuZCBwb3NpdGlvbi5cbiAgICAgKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIHNsaWNlIG9mIGBhcnJheWAuXG4gICAgICovXG4gICAgZnVuY3Rpb24gYmFzZVNsaWNlKGFycmF5LCBzdGFydCwgZW5kKSB7XG4gICAgICB2YXIgaW5kZXggPSAtMSxcbiAgICAgICAgICBsZW5ndGggPSBhcnJheS5sZW5ndGg7XG5cbiAgICAgIGlmIChzdGFydCA8IDApIHtcbiAgICAgICAgc3RhcnQgPSAtc3RhcnQgPiBsZW5ndGggPyAwIDogKGxlbmd0aCArIHN0YXJ0KTtcbiAgICAgIH1cbiAgICAgIGVuZCA9IGVuZCA+IGxlbmd0aCA/IGxlbmd0aCA6IGVuZDtcbiAgICAgIGlmIChlbmQgPCAwKSB7XG4gICAgICAgIGVuZCArPSBsZW5ndGg7XG4gICAgICB9XG4gICAgICBsZW5ndGggPSBzdGFydCA+IGVuZCA/IDAgOiAoKGVuZCAtIHN0YXJ0KSA+Pj4gMCk7XG4gICAgICBzdGFydCA+Pj49IDA7XG5cbiAgICAgIHZhciByZXN1bHQgPSBBcnJheShsZW5ndGgpO1xuICAgICAgd2hpbGUgKCsraW5kZXggPCBsZW5ndGgpIHtcbiAgICAgICAgcmVzdWx0W2luZGV4XSA9IGFycmF5W2luZGV4ICsgc3RhcnRdO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5zb21lYCB3aXRob3V0IHN1cHBvcnQgZm9yIGl0ZXJhdGVlIHNob3J0aGFuZHMuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7QXJyYXl8T2JqZWN0fSBjb2xsZWN0aW9uIFRoZSBjb2xsZWN0aW9uIHRvIGl0ZXJhdGUgb3Zlci5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBwcmVkaWNhdGUgVGhlIGZ1bmN0aW9uIGludm9rZWQgcGVyIGl0ZXJhdGlvbi5cbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYW55IGVsZW1lbnQgcGFzc2VzIHRoZSBwcmVkaWNhdGUgY2hlY2ssXG4gICAgICogIGVsc2UgYGZhbHNlYC5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBiYXNlU29tZShjb2xsZWN0aW9uLCBwcmVkaWNhdGUpIHtcbiAgICAgIHZhciByZXN1bHQ7XG5cbiAgICAgIGJhc2VFYWNoKGNvbGxlY3Rpb24sIGZ1bmN0aW9uKHZhbHVlLCBpbmRleCwgY29sbGVjdGlvbikge1xuICAgICAgICByZXN1bHQgPSBwcmVkaWNhdGUodmFsdWUsIGluZGV4LCBjb2xsZWN0aW9uKTtcbiAgICAgICAgcmV0dXJuICFyZXN1bHQ7XG4gICAgICB9KTtcbiAgICAgIHJldHVybiAhIXJlc3VsdDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5zb3J0ZWRJbmRleGAgYW5kIGBfLnNvcnRlZExhc3RJbmRleGAgd2hpY2hcbiAgICAgKiBwZXJmb3JtcyBhIGJpbmFyeSBzZWFyY2ggb2YgYGFycmF5YCB0byBkZXRlcm1pbmUgdGhlIGluZGV4IGF0IHdoaWNoIGB2YWx1ZWBcbiAgICAgKiBzaG91bGQgYmUgaW5zZXJ0ZWQgaW50byBgYXJyYXlgIGluIG9yZGVyIHRvIG1haW50YWluIGl0cyBzb3J0IG9yZGVyLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBhcnJheSBUaGUgc29ydGVkIGFycmF5IHRvIGluc3BlY3QuXG4gICAgICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gZXZhbHVhdGUuXG4gICAgICogQHBhcmFtIHtib29sZWFufSBbcmV0SGlnaGVzdF0gU3BlY2lmeSByZXR1cm5pbmcgdGhlIGhpZ2hlc3QgcXVhbGlmaWVkIGluZGV4LlxuICAgICAqIEByZXR1cm5zIHtudW1iZXJ9IFJldHVybnMgdGhlIGluZGV4IGF0IHdoaWNoIGB2YWx1ZWAgc2hvdWxkIGJlIGluc2VydGVkXG4gICAgICogIGludG8gYGFycmF5YC5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBiYXNlU29ydGVkSW5kZXgoYXJyYXksIHZhbHVlLCByZXRIaWdoZXN0KSB7XG4gICAgICB2YXIgbG93ID0gMCxcbiAgICAgICAgICBoaWdoID0gYXJyYXkgPT0gbnVsbCA/IGxvdyA6IGFycmF5Lmxlbmd0aDtcblxuICAgICAgaWYgKHR5cGVvZiB2YWx1ZSA9PSAnbnVtYmVyJyAmJiB2YWx1ZSA9PT0gdmFsdWUgJiYgaGlnaCA8PSBIQUxGX01BWF9BUlJBWV9MRU5HVEgpIHtcbiAgICAgICAgd2hpbGUgKGxvdyA8IGhpZ2gpIHtcbiAgICAgICAgICB2YXIgbWlkID0gKGxvdyArIGhpZ2gpID4+PiAxLFxuICAgICAgICAgICAgICBjb21wdXRlZCA9IGFycmF5W21pZF07XG5cbiAgICAgICAgICBpZiAoY29tcHV0ZWQgIT09IG51bGwgJiYgIWlzU3ltYm9sKGNvbXB1dGVkKSAmJlxuICAgICAgICAgICAgICAocmV0SGlnaGVzdCA/IChjb21wdXRlZCA8PSB2YWx1ZSkgOiAoY29tcHV0ZWQgPCB2YWx1ZSkpKSB7XG4gICAgICAgICAgICBsb3cgPSBtaWQgKyAxO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBoaWdoID0gbWlkO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gaGlnaDtcbiAgICAgIH1cbiAgICAgIHJldHVybiBiYXNlU29ydGVkSW5kZXhCeShhcnJheSwgdmFsdWUsIGlkZW50aXR5LCByZXRIaWdoZXN0KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5zb3J0ZWRJbmRleEJ5YCBhbmQgYF8uc29ydGVkTGFzdEluZGV4QnlgXG4gICAgICogd2hpY2ggaW52b2tlcyBgaXRlcmF0ZWVgIGZvciBgdmFsdWVgIGFuZCBlYWNoIGVsZW1lbnQgb2YgYGFycmF5YCB0byBjb21wdXRlXG4gICAgICogdGhlaXIgc29ydCByYW5raW5nLiBUaGUgaXRlcmF0ZWUgaXMgaW52b2tlZCB3aXRoIG9uZSBhcmd1bWVudDsgKHZhbHVlKS5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIHNvcnRlZCBhcnJheSB0byBpbnNwZWN0LlxuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGV2YWx1YXRlLlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IGl0ZXJhdGVlIFRoZSBpdGVyYXRlZSBpbnZva2VkIHBlciBlbGVtZW50LlxuICAgICAqIEBwYXJhbSB7Ym9vbGVhbn0gW3JldEhpZ2hlc3RdIFNwZWNpZnkgcmV0dXJuaW5nIHRoZSBoaWdoZXN0IHF1YWxpZmllZCBpbmRleC5cbiAgICAgKiBAcmV0dXJucyB7bnVtYmVyfSBSZXR1cm5zIHRoZSBpbmRleCBhdCB3aGljaCBgdmFsdWVgIHNob3VsZCBiZSBpbnNlcnRlZFxuICAgICAqICBpbnRvIGBhcnJheWAuXG4gICAgICovXG4gICAgZnVuY3Rpb24gYmFzZVNvcnRlZEluZGV4QnkoYXJyYXksIHZhbHVlLCBpdGVyYXRlZSwgcmV0SGlnaGVzdCkge1xuICAgICAgdmFsdWUgPSBpdGVyYXRlZSh2YWx1ZSk7XG5cbiAgICAgIHZhciBsb3cgPSAwLFxuICAgICAgICAgIGhpZ2ggPSBhcnJheSA9PSBudWxsID8gMCA6IGFycmF5Lmxlbmd0aCxcbiAgICAgICAgICB2YWxJc05hTiA9IHZhbHVlICE9PSB2YWx1ZSxcbiAgICAgICAgICB2YWxJc051bGwgPSB2YWx1ZSA9PT0gbnVsbCxcbiAgICAgICAgICB2YWxJc1N5bWJvbCA9IGlzU3ltYm9sKHZhbHVlKSxcbiAgICAgICAgICB2YWxJc1VuZGVmaW5lZCA9IHZhbHVlID09PSB1bmRlZmluZWQ7XG5cbiAgICAgIHdoaWxlIChsb3cgPCBoaWdoKSB7XG4gICAgICAgIHZhciBtaWQgPSBuYXRpdmVGbG9vcigobG93ICsgaGlnaCkgLyAyKSxcbiAgICAgICAgICAgIGNvbXB1dGVkID0gaXRlcmF0ZWUoYXJyYXlbbWlkXSksXG4gICAgICAgICAgICBvdGhJc0RlZmluZWQgPSBjb21wdXRlZCAhPT0gdW5kZWZpbmVkLFxuICAgICAgICAgICAgb3RoSXNOdWxsID0gY29tcHV0ZWQgPT09IG51bGwsXG4gICAgICAgICAgICBvdGhJc1JlZmxleGl2ZSA9IGNvbXB1dGVkID09PSBjb21wdXRlZCxcbiAgICAgICAgICAgIG90aElzU3ltYm9sID0gaXNTeW1ib2woY29tcHV0ZWQpO1xuXG4gICAgICAgIGlmICh2YWxJc05hTikge1xuICAgICAgICAgIHZhciBzZXRMb3cgPSByZXRIaWdoZXN0IHx8IG90aElzUmVmbGV4aXZlO1xuICAgICAgICB9IGVsc2UgaWYgKHZhbElzVW5kZWZpbmVkKSB7XG4gICAgICAgICAgc2V0TG93ID0gb3RoSXNSZWZsZXhpdmUgJiYgKHJldEhpZ2hlc3QgfHwgb3RoSXNEZWZpbmVkKTtcbiAgICAgICAgfSBlbHNlIGlmICh2YWxJc051bGwpIHtcbiAgICAgICAgICBzZXRMb3cgPSBvdGhJc1JlZmxleGl2ZSAmJiBvdGhJc0RlZmluZWQgJiYgKHJldEhpZ2hlc3QgfHwgIW90aElzTnVsbCk7XG4gICAgICAgIH0gZWxzZSBpZiAodmFsSXNTeW1ib2wpIHtcbiAgICAgICAgICBzZXRMb3cgPSBvdGhJc1JlZmxleGl2ZSAmJiBvdGhJc0RlZmluZWQgJiYgIW90aElzTnVsbCAmJiAocmV0SGlnaGVzdCB8fCAhb3RoSXNTeW1ib2wpO1xuICAgICAgICB9IGVsc2UgaWYgKG90aElzTnVsbCB8fCBvdGhJc1N5bWJvbCkge1xuICAgICAgICAgIHNldExvdyA9IGZhbHNlO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHNldExvdyA9IHJldEhpZ2hlc3QgPyAoY29tcHV0ZWQgPD0gdmFsdWUpIDogKGNvbXB1dGVkIDwgdmFsdWUpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChzZXRMb3cpIHtcbiAgICAgICAgICBsb3cgPSBtaWQgKyAxO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGhpZ2ggPSBtaWQ7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHJldHVybiBuYXRpdmVNaW4oaGlnaCwgTUFYX0FSUkFZX0lOREVYKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5zb3J0ZWRVbmlxYCBhbmQgYF8uc29ydGVkVW5pcUJ5YCB3aXRob3V0XG4gICAgICogc3VwcG9ydCBmb3IgaXRlcmF0ZWUgc2hvcnRoYW5kcy5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIGluc3BlY3QuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gW2l0ZXJhdGVlXSBUaGUgaXRlcmF0ZWUgaW52b2tlZCBwZXIgZWxlbWVudC5cbiAgICAgKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIG5ldyBkdXBsaWNhdGUgZnJlZSBhcnJheS5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBiYXNlU29ydGVkVW5pcShhcnJheSwgaXRlcmF0ZWUpIHtcbiAgICAgIHZhciBpbmRleCA9IC0xLFxuICAgICAgICAgIGxlbmd0aCA9IGFycmF5Lmxlbmd0aCxcbiAgICAgICAgICByZXNJbmRleCA9IDAsXG4gICAgICAgICAgcmVzdWx0ID0gW107XG5cbiAgICAgIHdoaWxlICgrK2luZGV4IDwgbGVuZ3RoKSB7XG4gICAgICAgIHZhciB2YWx1ZSA9IGFycmF5W2luZGV4XSxcbiAgICAgICAgICAgIGNvbXB1dGVkID0gaXRlcmF0ZWUgPyBpdGVyYXRlZSh2YWx1ZSkgOiB2YWx1ZTtcblxuICAgICAgICBpZiAoIWluZGV4IHx8ICFlcShjb21wdXRlZCwgc2VlbikpIHtcbiAgICAgICAgICB2YXIgc2VlbiA9IGNvbXB1dGVkO1xuICAgICAgICAgIHJlc3VsdFtyZXNJbmRleCsrXSA9IHZhbHVlID09PSAwID8gMCA6IHZhbHVlO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLnRvTnVtYmVyYCB3aGljaCBkb2Vzbid0IGVuc3VyZSBjb3JyZWN0XG4gICAgICogY29udmVyc2lvbnMgb2YgYmluYXJ5LCBoZXhhZGVjaW1hbCwgb3Igb2N0YWwgc3RyaW5nIHZhbHVlcy5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gcHJvY2Vzcy5cbiAgICAgKiBAcmV0dXJucyB7bnVtYmVyfSBSZXR1cm5zIHRoZSBudW1iZXIuXG4gICAgICovXG4gICAgZnVuY3Rpb24gYmFzZVRvTnVtYmVyKHZhbHVlKSB7XG4gICAgICBpZiAodHlwZW9mIHZhbHVlID09ICdudW1iZXInKSB7XG4gICAgICAgIHJldHVybiB2YWx1ZTtcbiAgICAgIH1cbiAgICAgIGlmIChpc1N5bWJvbCh2YWx1ZSkpIHtcbiAgICAgICAgcmV0dXJuIE5BTjtcbiAgICAgIH1cbiAgICAgIHJldHVybiArdmFsdWU7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8udG9TdHJpbmdgIHdoaWNoIGRvZXNuJ3QgY29udmVydCBudWxsaXNoXG4gICAgICogdmFsdWVzIHRvIGVtcHR5IHN0cmluZ3MuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIHByb2Nlc3MuXG4gICAgICogQHJldHVybnMge3N0cmluZ30gUmV0dXJucyB0aGUgc3RyaW5nLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGJhc2VUb1N0cmluZyh2YWx1ZSkge1xuICAgICAgLy8gRXhpdCBlYXJseSBmb3Igc3RyaW5ncyB0byBhdm9pZCBhIHBlcmZvcm1hbmNlIGhpdCBpbiBzb21lIGVudmlyb25tZW50cy5cbiAgICAgIGlmICh0eXBlb2YgdmFsdWUgPT0gJ3N0cmluZycpIHtcbiAgICAgICAgcmV0dXJuIHZhbHVlO1xuICAgICAgfVxuICAgICAgaWYgKGlzQXJyYXkodmFsdWUpKSB7XG4gICAgICAgIC8vIFJlY3Vyc2l2ZWx5IGNvbnZlcnQgdmFsdWVzIChzdXNjZXB0aWJsZSB0byBjYWxsIHN0YWNrIGxpbWl0cykuXG4gICAgICAgIHJldHVybiBhcnJheU1hcCh2YWx1ZSwgYmFzZVRvU3RyaW5nKSArICcnO1xuICAgICAgfVxuICAgICAgaWYgKGlzU3ltYm9sKHZhbHVlKSkge1xuICAgICAgICByZXR1cm4gc3ltYm9sVG9TdHJpbmcgPyBzeW1ib2xUb1N0cmluZy5jYWxsKHZhbHVlKSA6ICcnO1xuICAgICAgfVxuICAgICAgdmFyIHJlc3VsdCA9ICh2YWx1ZSArICcnKTtcbiAgICAgIHJldHVybiAocmVzdWx0ID09ICcwJyAmJiAoMSAvIHZhbHVlKSA9PSAtSU5GSU5JVFkpID8gJy0wJyA6IHJlc3VsdDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy51bmlxQnlgIHdpdGhvdXQgc3VwcG9ydCBmb3IgaXRlcmF0ZWUgc2hvcnRoYW5kcy5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIGluc3BlY3QuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gW2l0ZXJhdGVlXSBUaGUgaXRlcmF0ZWUgaW52b2tlZCBwZXIgZWxlbWVudC5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBbY29tcGFyYXRvcl0gVGhlIGNvbXBhcmF0b3IgaW52b2tlZCBwZXIgZWxlbWVudC5cbiAgICAgKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIG5ldyBkdXBsaWNhdGUgZnJlZSBhcnJheS5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBiYXNlVW5pcShhcnJheSwgaXRlcmF0ZWUsIGNvbXBhcmF0b3IpIHtcbiAgICAgIHZhciBpbmRleCA9IC0xLFxuICAgICAgICAgIGluY2x1ZGVzID0gYXJyYXlJbmNsdWRlcyxcbiAgICAgICAgICBsZW5ndGggPSBhcnJheS5sZW5ndGgsXG4gICAgICAgICAgaXNDb21tb24gPSB0cnVlLFxuICAgICAgICAgIHJlc3VsdCA9IFtdLFxuICAgICAgICAgIHNlZW4gPSByZXN1bHQ7XG5cbiAgICAgIGlmIChjb21wYXJhdG9yKSB7XG4gICAgICAgIGlzQ29tbW9uID0gZmFsc2U7XG4gICAgICAgIGluY2x1ZGVzID0gYXJyYXlJbmNsdWRlc1dpdGg7XG4gICAgICB9XG4gICAgICBlbHNlIGlmIChsZW5ndGggPj0gTEFSR0VfQVJSQVlfU0laRSkge1xuICAgICAgICB2YXIgc2V0ID0gaXRlcmF0ZWUgPyBudWxsIDogY3JlYXRlU2V0KGFycmF5KTtcbiAgICAgICAgaWYgKHNldCkge1xuICAgICAgICAgIHJldHVybiBzZXRUb0FycmF5KHNldCk7XG4gICAgICAgIH1cbiAgICAgICAgaXNDb21tb24gPSBmYWxzZTtcbiAgICAgICAgaW5jbHVkZXMgPSBjYWNoZUhhcztcbiAgICAgICAgc2VlbiA9IG5ldyBTZXRDYWNoZTtcbiAgICAgIH1cbiAgICAgIGVsc2Uge1xuICAgICAgICBzZWVuID0gaXRlcmF0ZWUgPyBbXSA6IHJlc3VsdDtcbiAgICAgIH1cbiAgICAgIG91dGVyOlxuICAgICAgd2hpbGUgKCsraW5kZXggPCBsZW5ndGgpIHtcbiAgICAgICAgdmFyIHZhbHVlID0gYXJyYXlbaW5kZXhdLFxuICAgICAgICAgICAgY29tcHV0ZWQgPSBpdGVyYXRlZSA/IGl0ZXJhdGVlKHZhbHVlKSA6IHZhbHVlO1xuXG4gICAgICAgIHZhbHVlID0gKGNvbXBhcmF0b3IgfHwgdmFsdWUgIT09IDApID8gdmFsdWUgOiAwO1xuICAgICAgICBpZiAoaXNDb21tb24gJiYgY29tcHV0ZWQgPT09IGNvbXB1dGVkKSB7XG4gICAgICAgICAgdmFyIHNlZW5JbmRleCA9IHNlZW4ubGVuZ3RoO1xuICAgICAgICAgIHdoaWxlIChzZWVuSW5kZXgtLSkge1xuICAgICAgICAgICAgaWYgKHNlZW5bc2VlbkluZGV4XSA9PT0gY29tcHV0ZWQpIHtcbiAgICAgICAgICAgICAgY29udGludWUgb3V0ZXI7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICAgIGlmIChpdGVyYXRlZSkge1xuICAgICAgICAgICAgc2Vlbi5wdXNoKGNvbXB1dGVkKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgcmVzdWx0LnB1c2godmFsdWUpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKCFpbmNsdWRlcyhzZWVuLCBjb21wdXRlZCwgY29tcGFyYXRvcikpIHtcbiAgICAgICAgICBpZiAoc2VlbiAhPT0gcmVzdWx0KSB7XG4gICAgICAgICAgICBzZWVuLnB1c2goY29tcHV0ZWQpO1xuICAgICAgICAgIH1cbiAgICAgICAgICByZXN1bHQucHVzaCh2YWx1ZSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8udW5zZXRgLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gbW9kaWZ5LlxuICAgICAqIEBwYXJhbSB7QXJyYXl8c3RyaW5nfSBwYXRoIFRoZSBwcm9wZXJ0eSBwYXRoIHRvIHVuc2V0LlxuICAgICAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiB0aGUgcHJvcGVydHkgaXMgZGVsZXRlZCwgZWxzZSBgZmFsc2VgLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGJhc2VVbnNldChvYmplY3QsIHBhdGgpIHtcbiAgICAgIHBhdGggPSBjYXN0UGF0aChwYXRoLCBvYmplY3QpO1xuICAgICAgb2JqZWN0ID0gcGFyZW50KG9iamVjdCwgcGF0aCk7XG4gICAgICByZXR1cm4gb2JqZWN0ID09IG51bGwgfHwgZGVsZXRlIG9iamVjdFt0b0tleShsYXN0KHBhdGgpKV07XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8udXBkYXRlYC5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIG1vZGlmeS5cbiAgICAgKiBAcGFyYW0ge0FycmF5fHN0cmluZ30gcGF0aCBUaGUgcGF0aCBvZiB0aGUgcHJvcGVydHkgdG8gdXBkYXRlLlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IHVwZGF0ZXIgVGhlIGZ1bmN0aW9uIHRvIHByb2R1Y2UgdGhlIHVwZGF0ZWQgdmFsdWUuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gW2N1c3RvbWl6ZXJdIFRoZSBmdW5jdGlvbiB0byBjdXN0b21pemUgcGF0aCBjcmVhdGlvbi5cbiAgICAgKiBAcmV0dXJucyB7T2JqZWN0fSBSZXR1cm5zIGBvYmplY3RgLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGJhc2VVcGRhdGUob2JqZWN0LCBwYXRoLCB1cGRhdGVyLCBjdXN0b21pemVyKSB7XG4gICAgICByZXR1cm4gYmFzZVNldChvYmplY3QsIHBhdGgsIHVwZGF0ZXIoYmFzZUdldChvYmplY3QsIHBhdGgpKSwgY3VzdG9taXplcik7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgbWV0aG9kcyBsaWtlIGBfLmRyb3BXaGlsZWAgYW5kIGBfLnRha2VXaGlsZWBcbiAgICAgKiB3aXRob3V0IHN1cHBvcnQgZm9yIGl0ZXJhdGVlIHNob3J0aGFuZHMuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBhcnJheSB0byBxdWVyeS5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBwcmVkaWNhdGUgVGhlIGZ1bmN0aW9uIGludm9rZWQgcGVyIGl0ZXJhdGlvbi5cbiAgICAgKiBAcGFyYW0ge2Jvb2xlYW59IFtpc0Ryb3BdIFNwZWNpZnkgZHJvcHBpbmcgZWxlbWVudHMgaW5zdGVhZCBvZiB0YWtpbmcgdGhlbS5cbiAgICAgKiBAcGFyYW0ge2Jvb2xlYW59IFtmcm9tUmlnaHRdIFNwZWNpZnkgaXRlcmF0aW5nIGZyb20gcmlnaHQgdG8gbGVmdC5cbiAgICAgKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIHNsaWNlIG9mIGBhcnJheWAuXG4gICAgICovXG4gICAgZnVuY3Rpb24gYmFzZVdoaWxlKGFycmF5LCBwcmVkaWNhdGUsIGlzRHJvcCwgZnJvbVJpZ2h0KSB7XG4gICAgICB2YXIgbGVuZ3RoID0gYXJyYXkubGVuZ3RoLFxuICAgICAgICAgIGluZGV4ID0gZnJvbVJpZ2h0ID8gbGVuZ3RoIDogLTE7XG5cbiAgICAgIHdoaWxlICgoZnJvbVJpZ2h0ID8gaW5kZXgtLSA6ICsraW5kZXggPCBsZW5ndGgpICYmXG4gICAgICAgIHByZWRpY2F0ZShhcnJheVtpbmRleF0sIGluZGV4LCBhcnJheSkpIHt9XG5cbiAgICAgIHJldHVybiBpc0Ryb3BcbiAgICAgICAgPyBiYXNlU2xpY2UoYXJyYXksIChmcm9tUmlnaHQgPyAwIDogaW5kZXgpLCAoZnJvbVJpZ2h0ID8gaW5kZXggKyAxIDogbGVuZ3RoKSlcbiAgICAgICAgOiBiYXNlU2xpY2UoYXJyYXksIChmcm9tUmlnaHQgPyBpbmRleCArIDEgOiAwKSwgKGZyb21SaWdodCA/IGxlbmd0aCA6IGluZGV4KSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYHdyYXBwZXJWYWx1ZWAgd2hpY2ggcmV0dXJucyB0aGUgcmVzdWx0IG9mXG4gICAgICogcGVyZm9ybWluZyBhIHNlcXVlbmNlIG9mIGFjdGlvbnMgb24gdGhlIHVud3JhcHBlZCBgdmFsdWVgLCB3aGVyZSBlYWNoXG4gICAgICogc3VjY2Vzc2l2ZSBhY3Rpb24gaXMgc3VwcGxpZWQgdGhlIHJldHVybiB2YWx1ZSBvZiB0aGUgcHJldmlvdXMuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHVud3JhcHBlZCB2YWx1ZS5cbiAgICAgKiBAcGFyYW0ge0FycmF5fSBhY3Rpb25zIEFjdGlvbnMgdG8gcGVyZm9ybSB0byByZXNvbHZlIHRoZSB1bndyYXBwZWQgdmFsdWUuXG4gICAgICogQHJldHVybnMgeyp9IFJldHVybnMgdGhlIHJlc29sdmVkIHZhbHVlLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGJhc2VXcmFwcGVyVmFsdWUodmFsdWUsIGFjdGlvbnMpIHtcbiAgICAgIHZhciByZXN1bHQgPSB2YWx1ZTtcbiAgICAgIGlmIChyZXN1bHQgaW5zdGFuY2VvZiBMYXp5V3JhcHBlcikge1xuICAgICAgICByZXN1bHQgPSByZXN1bHQudmFsdWUoKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBhcnJheVJlZHVjZShhY3Rpb25zLCBmdW5jdGlvbihyZXN1bHQsIGFjdGlvbikge1xuICAgICAgICByZXR1cm4gYWN0aW9uLmZ1bmMuYXBwbHkoYWN0aW9uLnRoaXNBcmcsIGFycmF5UHVzaChbcmVzdWx0XSwgYWN0aW9uLmFyZ3MpKTtcbiAgICAgIH0sIHJlc3VsdCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgbWV0aG9kcyBsaWtlIGBfLnhvcmAsIHdpdGhvdXQgc3VwcG9ydCBmb3JcbiAgICAgKiBpdGVyYXRlZSBzaG9ydGhhbmRzLCB0aGF0IGFjY2VwdHMgYW4gYXJyYXkgb2YgYXJyYXlzIHRvIGluc3BlY3QuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7QXJyYXl9IGFycmF5cyBUaGUgYXJyYXlzIHRvIGluc3BlY3QuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gW2l0ZXJhdGVlXSBUaGUgaXRlcmF0ZWUgaW52b2tlZCBwZXIgZWxlbWVudC5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBbY29tcGFyYXRvcl0gVGhlIGNvbXBhcmF0b3IgaW52b2tlZCBwZXIgZWxlbWVudC5cbiAgICAgKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIG5ldyBhcnJheSBvZiB2YWx1ZXMuXG4gICAgICovXG4gICAgZnVuY3Rpb24gYmFzZVhvcihhcnJheXMsIGl0ZXJhdGVlLCBjb21wYXJhdG9yKSB7XG4gICAgICB2YXIgbGVuZ3RoID0gYXJyYXlzLmxlbmd0aDtcbiAgICAgIGlmIChsZW5ndGggPCAyKSB7XG4gICAgICAgIHJldHVybiBsZW5ndGggPyBiYXNlVW5pcShhcnJheXNbMF0pIDogW107XG4gICAgICB9XG4gICAgICB2YXIgaW5kZXggPSAtMSxcbiAgICAgICAgICByZXN1bHQgPSBBcnJheShsZW5ndGgpO1xuXG4gICAgICB3aGlsZSAoKytpbmRleCA8IGxlbmd0aCkge1xuICAgICAgICB2YXIgYXJyYXkgPSBhcnJheXNbaW5kZXhdLFxuICAgICAgICAgICAgb3RoSW5kZXggPSAtMTtcblxuICAgICAgICB3aGlsZSAoKytvdGhJbmRleCA8IGxlbmd0aCkge1xuICAgICAgICAgIGlmIChvdGhJbmRleCAhPSBpbmRleCkge1xuICAgICAgICAgICAgcmVzdWx0W2luZGV4XSA9IGJhc2VEaWZmZXJlbmNlKHJlc3VsdFtpbmRleF0gfHwgYXJyYXksIGFycmF5c1tvdGhJbmRleF0sIGl0ZXJhdGVlLCBjb21wYXJhdG9yKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHJldHVybiBiYXNlVW5pcShiYXNlRmxhdHRlbihyZXN1bHQsIDEpLCBpdGVyYXRlZSwgY29tcGFyYXRvcik7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhpcyBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLnppcE9iamVjdGAgd2hpY2ggYXNzaWducyB2YWx1ZXMgdXNpbmcgYGFzc2lnbkZ1bmNgLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBwcm9wcyBUaGUgcHJvcGVydHkgaWRlbnRpZmllcnMuXG4gICAgICogQHBhcmFtIHtBcnJheX0gdmFsdWVzIFRoZSBwcm9wZXJ0eSB2YWx1ZXMuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gYXNzaWduRnVuYyBUaGUgZnVuY3Rpb24gdG8gYXNzaWduIHZhbHVlcy5cbiAgICAgKiBAcmV0dXJucyB7T2JqZWN0fSBSZXR1cm5zIHRoZSBuZXcgb2JqZWN0LlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGJhc2VaaXBPYmplY3QocHJvcHMsIHZhbHVlcywgYXNzaWduRnVuYykge1xuICAgICAgdmFyIGluZGV4ID0gLTEsXG4gICAgICAgICAgbGVuZ3RoID0gcHJvcHMubGVuZ3RoLFxuICAgICAgICAgIHZhbHNMZW5ndGggPSB2YWx1ZXMubGVuZ3RoLFxuICAgICAgICAgIHJlc3VsdCA9IHt9O1xuXG4gICAgICB3aGlsZSAoKytpbmRleCA8IGxlbmd0aCkge1xuICAgICAgICB2YXIgdmFsdWUgPSBpbmRleCA8IHZhbHNMZW5ndGggPyB2YWx1ZXNbaW5kZXhdIDogdW5kZWZpbmVkO1xuICAgICAgICBhc3NpZ25GdW5jKHJlc3VsdCwgcHJvcHNbaW5kZXhdLCB2YWx1ZSk7XG4gICAgICB9XG4gICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENhc3RzIGB2YWx1ZWAgdG8gYW4gZW1wdHkgYXJyYXkgaWYgaXQncyBub3QgYW4gYXJyYXkgbGlrZSBvYmplY3QuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGluc3BlY3QuXG4gICAgICogQHJldHVybnMge0FycmF5fE9iamVjdH0gUmV0dXJucyB0aGUgY2FzdCBhcnJheS1saWtlIG9iamVjdC5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBjYXN0QXJyYXlMaWtlT2JqZWN0KHZhbHVlKSB7XG4gICAgICByZXR1cm4gaXNBcnJheUxpa2VPYmplY3QodmFsdWUpID8gdmFsdWUgOiBbXTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDYXN0cyBgdmFsdWVgIHRvIGBpZGVudGl0eWAgaWYgaXQncyBub3QgYSBmdW5jdGlvbi5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gaW5zcGVjdC5cbiAgICAgKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgY2FzdCBmdW5jdGlvbi5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBjYXN0RnVuY3Rpb24odmFsdWUpIHtcbiAgICAgIHJldHVybiB0eXBlb2YgdmFsdWUgPT0gJ2Z1bmN0aW9uJyA/IHZhbHVlIDogaWRlbnRpdHk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ2FzdHMgYHZhbHVlYCB0byBhIHBhdGggYXJyYXkgaWYgaXQncyBub3Qgb25lLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBpbnNwZWN0LlxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBbb2JqZWN0XSBUaGUgb2JqZWN0IHRvIHF1ZXJ5IGtleXMgb24uXG4gICAgICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBjYXN0IHByb3BlcnR5IHBhdGggYXJyYXkuXG4gICAgICovXG4gICAgZnVuY3Rpb24gY2FzdFBhdGgodmFsdWUsIG9iamVjdCkge1xuICAgICAgaWYgKGlzQXJyYXkodmFsdWUpKSB7XG4gICAgICAgIHJldHVybiB2YWx1ZTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBpc0tleSh2YWx1ZSwgb2JqZWN0KSA/IFt2YWx1ZV0gOiBzdHJpbmdUb1BhdGgodG9TdHJpbmcodmFsdWUpKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBBIGBiYXNlUmVzdGAgYWxpYXMgd2hpY2ggY2FuIGJlIHJlcGxhY2VkIHdpdGggYGlkZW50aXR5YCBieSBtb2R1bGVcbiAgICAgKiByZXBsYWNlbWVudCBwbHVnaW5zLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7RnVuY3Rpb259XG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gZnVuYyBUaGUgZnVuY3Rpb24gdG8gYXBwbHkgYSByZXN0IHBhcmFtZXRlciB0by5cbiAgICAgKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyBmdW5jdGlvbi5cbiAgICAgKi9cbiAgICB2YXIgY2FzdFJlc3QgPSBiYXNlUmVzdDtcblxuICAgIC8qKlxuICAgICAqIENhc3RzIGBhcnJheWAgdG8gYSBzbGljZSBpZiBpdCdzIG5lZWRlZC5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIGluc3BlY3QuXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IHN0YXJ0IFRoZSBzdGFydCBwb3NpdGlvbi5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gW2VuZD1hcnJheS5sZW5ndGhdIFRoZSBlbmQgcG9zaXRpb24uXG4gICAgICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBjYXN0IHNsaWNlLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGNhc3RTbGljZShhcnJheSwgc3RhcnQsIGVuZCkge1xuICAgICAgdmFyIGxlbmd0aCA9IGFycmF5Lmxlbmd0aDtcbiAgICAgIGVuZCA9IGVuZCA9PT0gdW5kZWZpbmVkID8gbGVuZ3RoIDogZW5kO1xuICAgICAgcmV0dXJuICghc3RhcnQgJiYgZW5kID49IGxlbmd0aCkgPyBhcnJheSA6IGJhc2VTbGljZShhcnJheSwgc3RhcnQsIGVuZCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQSBzaW1wbGUgd3JhcHBlciBhcm91bmQgdGhlIGdsb2JhbCBbYGNsZWFyVGltZW91dGBdKGh0dHBzOi8vbWRuLmlvL2NsZWFyVGltZW91dCkuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7bnVtYmVyfE9iamVjdH0gaWQgVGhlIHRpbWVyIGlkIG9yIHRpbWVvdXQgb2JqZWN0IG9mIHRoZSB0aW1lciB0byBjbGVhci5cbiAgICAgKi9cbiAgICB2YXIgY2xlYXJUaW1lb3V0ID0gY3R4Q2xlYXJUaW1lb3V0IHx8IGZ1bmN0aW9uKGlkKSB7XG4gICAgICByZXR1cm4gcm9vdC5jbGVhclRpbWVvdXQoaWQpO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgY2xvbmUgb2YgIGBidWZmZXJgLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge0J1ZmZlcn0gYnVmZmVyIFRoZSBidWZmZXIgdG8gY2xvbmUuXG4gICAgICogQHBhcmFtIHtib29sZWFufSBbaXNEZWVwXSBTcGVjaWZ5IGEgZGVlcCBjbG9uZS5cbiAgICAgKiBAcmV0dXJucyB7QnVmZmVyfSBSZXR1cm5zIHRoZSBjbG9uZWQgYnVmZmVyLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGNsb25lQnVmZmVyKGJ1ZmZlciwgaXNEZWVwKSB7XG4gICAgICBpZiAoaXNEZWVwKSB7XG4gICAgICAgIHJldHVybiBidWZmZXIuc2xpY2UoKTtcbiAgICAgIH1cbiAgICAgIHZhciBsZW5ndGggPSBidWZmZXIubGVuZ3RoLFxuICAgICAgICAgIHJlc3VsdCA9IGFsbG9jVW5zYWZlID8gYWxsb2NVbnNhZmUobGVuZ3RoKSA6IG5ldyBidWZmZXIuY29uc3RydWN0b3IobGVuZ3RoKTtcblxuICAgICAgYnVmZmVyLmNvcHkocmVzdWx0KTtcbiAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIGNsb25lIG9mIGBhcnJheUJ1ZmZlcmAuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7QXJyYXlCdWZmZXJ9IGFycmF5QnVmZmVyIFRoZSBhcnJheSBidWZmZXIgdG8gY2xvbmUuXG4gICAgICogQHJldHVybnMge0FycmF5QnVmZmVyfSBSZXR1cm5zIHRoZSBjbG9uZWQgYXJyYXkgYnVmZmVyLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGNsb25lQXJyYXlCdWZmZXIoYXJyYXlCdWZmZXIpIHtcbiAgICAgIHZhciByZXN1bHQgPSBuZXcgYXJyYXlCdWZmZXIuY29uc3RydWN0b3IoYXJyYXlCdWZmZXIuYnl0ZUxlbmd0aCk7XG4gICAgICBuZXcgVWludDhBcnJheShyZXN1bHQpLnNldChuZXcgVWludDhBcnJheShhcnJheUJ1ZmZlcikpO1xuICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgY2xvbmUgb2YgYGRhdGFWaWV3YC5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtPYmplY3R9IGRhdGFWaWV3IFRoZSBkYXRhIHZpZXcgdG8gY2xvbmUuXG4gICAgICogQHBhcmFtIHtib29sZWFufSBbaXNEZWVwXSBTcGVjaWZ5IGEgZGVlcCBjbG9uZS5cbiAgICAgKiBAcmV0dXJucyB7T2JqZWN0fSBSZXR1cm5zIHRoZSBjbG9uZWQgZGF0YSB2aWV3LlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGNsb25lRGF0YVZpZXcoZGF0YVZpZXcsIGlzRGVlcCkge1xuICAgICAgdmFyIGJ1ZmZlciA9IGlzRGVlcCA/IGNsb25lQXJyYXlCdWZmZXIoZGF0YVZpZXcuYnVmZmVyKSA6IGRhdGFWaWV3LmJ1ZmZlcjtcbiAgICAgIHJldHVybiBuZXcgZGF0YVZpZXcuY29uc3RydWN0b3IoYnVmZmVyLCBkYXRhVmlldy5ieXRlT2Zmc2V0LCBkYXRhVmlldy5ieXRlTGVuZ3RoKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgY2xvbmUgb2YgYG1hcGAuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBtYXAgVGhlIG1hcCB0byBjbG9uZS5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBjbG9uZUZ1bmMgVGhlIGZ1bmN0aW9uIHRvIGNsb25lIHZhbHVlcy5cbiAgICAgKiBAcGFyYW0ge2Jvb2xlYW59IFtpc0RlZXBdIFNwZWNpZnkgYSBkZWVwIGNsb25lLlxuICAgICAqIEByZXR1cm5zIHtPYmplY3R9IFJldHVybnMgdGhlIGNsb25lZCBtYXAuXG4gICAgICovXG4gICAgZnVuY3Rpb24gY2xvbmVNYXAobWFwLCBpc0RlZXAsIGNsb25lRnVuYykge1xuICAgICAgdmFyIGFycmF5ID0gaXNEZWVwID8gY2xvbmVGdW5jKG1hcFRvQXJyYXkobWFwKSwgQ0xPTkVfREVFUF9GTEFHKSA6IG1hcFRvQXJyYXkobWFwKTtcbiAgICAgIHJldHVybiBhcnJheVJlZHVjZShhcnJheSwgYWRkTWFwRW50cnksIG5ldyBtYXAuY29uc3RydWN0b3IpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBjbG9uZSBvZiBgcmVnZXhwYC5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtPYmplY3R9IHJlZ2V4cCBUaGUgcmVnZXhwIHRvIGNsb25lLlxuICAgICAqIEByZXR1cm5zIHtPYmplY3R9IFJldHVybnMgdGhlIGNsb25lZCByZWdleHAuXG4gICAgICovXG4gICAgZnVuY3Rpb24gY2xvbmVSZWdFeHAocmVnZXhwKSB7XG4gICAgICB2YXIgcmVzdWx0ID0gbmV3IHJlZ2V4cC5jb25zdHJ1Y3RvcihyZWdleHAuc291cmNlLCByZUZsYWdzLmV4ZWMocmVnZXhwKSk7XG4gICAgICByZXN1bHQubGFzdEluZGV4ID0gcmVnZXhwLmxhc3RJbmRleDtcbiAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIGNsb25lIG9mIGBzZXRgLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gc2V0IFRoZSBzZXQgdG8gY2xvbmUuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gY2xvbmVGdW5jIFRoZSBmdW5jdGlvbiB0byBjbG9uZSB2YWx1ZXMuXG4gICAgICogQHBhcmFtIHtib29sZWFufSBbaXNEZWVwXSBTcGVjaWZ5IGEgZGVlcCBjbG9uZS5cbiAgICAgKiBAcmV0dXJucyB7T2JqZWN0fSBSZXR1cm5zIHRoZSBjbG9uZWQgc2V0LlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGNsb25lU2V0KHNldCwgaXNEZWVwLCBjbG9uZUZ1bmMpIHtcbiAgICAgIHZhciBhcnJheSA9IGlzRGVlcCA/IGNsb25lRnVuYyhzZXRUb0FycmF5KHNldCksIENMT05FX0RFRVBfRkxBRykgOiBzZXRUb0FycmF5KHNldCk7XG4gICAgICByZXR1cm4gYXJyYXlSZWR1Y2UoYXJyYXksIGFkZFNldEVudHJ5LCBuZXcgc2V0LmNvbnN0cnVjdG9yKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgY2xvbmUgb2YgdGhlIGBzeW1ib2xgIG9iamVjdC5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtPYmplY3R9IHN5bWJvbCBUaGUgc3ltYm9sIG9iamVjdCB0byBjbG9uZS5cbiAgICAgKiBAcmV0dXJucyB7T2JqZWN0fSBSZXR1cm5zIHRoZSBjbG9uZWQgc3ltYm9sIG9iamVjdC5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBjbG9uZVN5bWJvbChzeW1ib2wpIHtcbiAgICAgIHJldHVybiBzeW1ib2xWYWx1ZU9mID8gT2JqZWN0KHN5bWJvbFZhbHVlT2YuY2FsbChzeW1ib2wpKSA6IHt9O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBjbG9uZSBvZiBgdHlwZWRBcnJheWAuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSB0eXBlZEFycmF5IFRoZSB0eXBlZCBhcnJheSB0byBjbG9uZS5cbiAgICAgKiBAcGFyYW0ge2Jvb2xlYW59IFtpc0RlZXBdIFNwZWNpZnkgYSBkZWVwIGNsb25lLlxuICAgICAqIEByZXR1cm5zIHtPYmplY3R9IFJldHVybnMgdGhlIGNsb25lZCB0eXBlZCBhcnJheS5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBjbG9uZVR5cGVkQXJyYXkodHlwZWRBcnJheSwgaXNEZWVwKSB7XG4gICAgICB2YXIgYnVmZmVyID0gaXNEZWVwID8gY2xvbmVBcnJheUJ1ZmZlcih0eXBlZEFycmF5LmJ1ZmZlcikgOiB0eXBlZEFycmF5LmJ1ZmZlcjtcbiAgICAgIHJldHVybiBuZXcgdHlwZWRBcnJheS5jb25zdHJ1Y3RvcihidWZmZXIsIHR5cGVkQXJyYXkuYnl0ZU9mZnNldCwgdHlwZWRBcnJheS5sZW5ndGgpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENvbXBhcmVzIHZhbHVlcyB0byBzb3J0IHRoZW0gaW4gYXNjZW5kaW5nIG9yZGVyLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjb21wYXJlLlxuICAgICAqIEBwYXJhbSB7Kn0gb3RoZXIgVGhlIG90aGVyIHZhbHVlIHRvIGNvbXBhcmUuXG4gICAgICogQHJldHVybnMge251bWJlcn0gUmV0dXJucyB0aGUgc29ydCBvcmRlciBpbmRpY2F0b3IgZm9yIGB2YWx1ZWAuXG4gICAgICovXG4gICAgZnVuY3Rpb24gY29tcGFyZUFzY2VuZGluZyh2YWx1ZSwgb3RoZXIpIHtcbiAgICAgIGlmICh2YWx1ZSAhPT0gb3RoZXIpIHtcbiAgICAgICAgdmFyIHZhbElzRGVmaW5lZCA9IHZhbHVlICE9PSB1bmRlZmluZWQsXG4gICAgICAgICAgICB2YWxJc051bGwgPSB2YWx1ZSA9PT0gbnVsbCxcbiAgICAgICAgICAgIHZhbElzUmVmbGV4aXZlID0gdmFsdWUgPT09IHZhbHVlLFxuICAgICAgICAgICAgdmFsSXNTeW1ib2wgPSBpc1N5bWJvbCh2YWx1ZSk7XG5cbiAgICAgICAgdmFyIG90aElzRGVmaW5lZCA9IG90aGVyICE9PSB1bmRlZmluZWQsXG4gICAgICAgICAgICBvdGhJc051bGwgPSBvdGhlciA9PT0gbnVsbCxcbiAgICAgICAgICAgIG90aElzUmVmbGV4aXZlID0gb3RoZXIgPT09IG90aGVyLFxuICAgICAgICAgICAgb3RoSXNTeW1ib2wgPSBpc1N5bWJvbChvdGhlcik7XG5cbiAgICAgICAgaWYgKCghb3RoSXNOdWxsICYmICFvdGhJc1N5bWJvbCAmJiAhdmFsSXNTeW1ib2wgJiYgdmFsdWUgPiBvdGhlcikgfHxcbiAgICAgICAgICAgICh2YWxJc1N5bWJvbCAmJiBvdGhJc0RlZmluZWQgJiYgb3RoSXNSZWZsZXhpdmUgJiYgIW90aElzTnVsbCAmJiAhb3RoSXNTeW1ib2wpIHx8XG4gICAgICAgICAgICAodmFsSXNOdWxsICYmIG90aElzRGVmaW5lZCAmJiBvdGhJc1JlZmxleGl2ZSkgfHxcbiAgICAgICAgICAgICghdmFsSXNEZWZpbmVkICYmIG90aElzUmVmbGV4aXZlKSB8fFxuICAgICAgICAgICAgIXZhbElzUmVmbGV4aXZlKSB7XG4gICAgICAgICAgcmV0dXJuIDE7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKCghdmFsSXNOdWxsICYmICF2YWxJc1N5bWJvbCAmJiAhb3RoSXNTeW1ib2wgJiYgdmFsdWUgPCBvdGhlcikgfHxcbiAgICAgICAgICAgIChvdGhJc1N5bWJvbCAmJiB2YWxJc0RlZmluZWQgJiYgdmFsSXNSZWZsZXhpdmUgJiYgIXZhbElzTnVsbCAmJiAhdmFsSXNTeW1ib2wpIHx8XG4gICAgICAgICAgICAob3RoSXNOdWxsICYmIHZhbElzRGVmaW5lZCAmJiB2YWxJc1JlZmxleGl2ZSkgfHxcbiAgICAgICAgICAgICghb3RoSXNEZWZpbmVkICYmIHZhbElzUmVmbGV4aXZlKSB8fFxuICAgICAgICAgICAgIW90aElzUmVmbGV4aXZlKSB7XG4gICAgICAgICAgcmV0dXJuIC0xO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICByZXR1cm4gMDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBVc2VkIGJ5IGBfLm9yZGVyQnlgIHRvIGNvbXBhcmUgbXVsdGlwbGUgcHJvcGVydGllcyBvZiBhIHZhbHVlIHRvIGFub3RoZXJcbiAgICAgKiBhbmQgc3RhYmxlIHNvcnQgdGhlbS5cbiAgICAgKlxuICAgICAqIElmIGBvcmRlcnNgIGlzIHVuc3BlY2lmaWVkLCBhbGwgdmFsdWVzIGFyZSBzb3J0ZWQgaW4gYXNjZW5kaW5nIG9yZGVyLiBPdGhlcndpc2UsXG4gICAgICogc3BlY2lmeSBhbiBvcmRlciBvZiBcImRlc2NcIiBmb3IgZGVzY2VuZGluZyBvciBcImFzY1wiIGZvciBhc2NlbmRpbmcgc29ydCBvcmRlclxuICAgICAqIG9mIGNvcnJlc3BvbmRpbmcgdmFsdWVzLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gY29tcGFyZS5cbiAgICAgKiBAcGFyYW0ge09iamVjdH0gb3RoZXIgVGhlIG90aGVyIG9iamVjdCB0byBjb21wYXJlLlxuICAgICAqIEBwYXJhbSB7Ym9vbGVhbltdfHN0cmluZ1tdfSBvcmRlcnMgVGhlIG9yZGVyIHRvIHNvcnQgYnkgZm9yIGVhY2ggcHJvcGVydHkuXG4gICAgICogQHJldHVybnMge251bWJlcn0gUmV0dXJucyB0aGUgc29ydCBvcmRlciBpbmRpY2F0b3IgZm9yIGBvYmplY3RgLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGNvbXBhcmVNdWx0aXBsZShvYmplY3QsIG90aGVyLCBvcmRlcnMpIHtcbiAgICAgIHZhciBpbmRleCA9IC0xLFxuICAgICAgICAgIG9iakNyaXRlcmlhID0gb2JqZWN0LmNyaXRlcmlhLFxuICAgICAgICAgIG90aENyaXRlcmlhID0gb3RoZXIuY3JpdGVyaWEsXG4gICAgICAgICAgbGVuZ3RoID0gb2JqQ3JpdGVyaWEubGVuZ3RoLFxuICAgICAgICAgIG9yZGVyc0xlbmd0aCA9IG9yZGVycy5sZW5ndGg7XG5cbiAgICAgIHdoaWxlICgrK2luZGV4IDwgbGVuZ3RoKSB7XG4gICAgICAgIHZhciByZXN1bHQgPSBjb21wYXJlQXNjZW5kaW5nKG9iakNyaXRlcmlhW2luZGV4XSwgb3RoQ3JpdGVyaWFbaW5kZXhdKTtcbiAgICAgICAgaWYgKHJlc3VsdCkge1xuICAgICAgICAgIGlmIChpbmRleCA+PSBvcmRlcnNMZW5ndGgpIHtcbiAgICAgICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgICAgICAgfVxuICAgICAgICAgIHZhciBvcmRlciA9IG9yZGVyc1tpbmRleF07XG4gICAgICAgICAgcmV0dXJuIHJlc3VsdCAqIChvcmRlciA9PSAnZGVzYycgPyAtMSA6IDEpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICAvLyBGaXhlcyBhbiBgQXJyYXkjc29ydGAgYnVnIGluIHRoZSBKUyBlbmdpbmUgZW1iZWRkZWQgaW4gQWRvYmUgYXBwbGljYXRpb25zXG4gICAgICAvLyB0aGF0IGNhdXNlcyBpdCwgdW5kZXIgY2VydGFpbiBjaXJjdW1zdGFuY2VzLCB0byBwcm92aWRlIHRoZSBzYW1lIHZhbHVlIGZvclxuICAgICAgLy8gYG9iamVjdGAgYW5kIGBvdGhlcmAuIFNlZSBodHRwczovL2dpdGh1Yi5jb20vamFzaGtlbmFzL3VuZGVyc2NvcmUvcHVsbC8xMjQ3XG4gICAgICAvLyBmb3IgbW9yZSBkZXRhaWxzLlxuICAgICAgLy9cbiAgICAgIC8vIFRoaXMgYWxzbyBlbnN1cmVzIGEgc3RhYmxlIHNvcnQgaW4gVjggYW5kIG90aGVyIGVuZ2luZXMuXG4gICAgICAvLyBTZWUgaHR0cHM6Ly9idWdzLmNocm9taXVtLm9yZy9wL3Y4L2lzc3Vlcy9kZXRhaWw/aWQ9OTAgZm9yIG1vcmUgZGV0YWlscy5cbiAgICAgIHJldHVybiBvYmplY3QuaW5kZXggLSBvdGhlci5pbmRleDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGFuIGFycmF5IHRoYXQgaXMgdGhlIGNvbXBvc2l0aW9uIG9mIHBhcnRpYWxseSBhcHBsaWVkIGFyZ3VtZW50cyxcbiAgICAgKiBwbGFjZWhvbGRlcnMsIGFuZCBwcm92aWRlZCBhcmd1bWVudHMgaW50byBhIHNpbmdsZSBhcnJheSBvZiBhcmd1bWVudHMuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7QXJyYXl9IGFyZ3MgVGhlIHByb3ZpZGVkIGFyZ3VtZW50cy5cbiAgICAgKiBAcGFyYW0ge0FycmF5fSBwYXJ0aWFscyBUaGUgYXJndW1lbnRzIHRvIHByZXBlbmQgdG8gdGhvc2UgcHJvdmlkZWQuXG4gICAgICogQHBhcmFtIHtBcnJheX0gaG9sZGVycyBUaGUgYHBhcnRpYWxzYCBwbGFjZWhvbGRlciBpbmRleGVzLlxuICAgICAqIEBwYXJhbXMge2Jvb2xlYW59IFtpc0N1cnJpZWRdIFNwZWNpZnkgY29tcG9zaW5nIGZvciBhIGN1cnJpZWQgZnVuY3Rpb24uXG4gICAgICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBuZXcgYXJyYXkgb2YgY29tcG9zZWQgYXJndW1lbnRzLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGNvbXBvc2VBcmdzKGFyZ3MsIHBhcnRpYWxzLCBob2xkZXJzLCBpc0N1cnJpZWQpIHtcbiAgICAgIHZhciBhcmdzSW5kZXggPSAtMSxcbiAgICAgICAgICBhcmdzTGVuZ3RoID0gYXJncy5sZW5ndGgsXG4gICAgICAgICAgaG9sZGVyc0xlbmd0aCA9IGhvbGRlcnMubGVuZ3RoLFxuICAgICAgICAgIGxlZnRJbmRleCA9IC0xLFxuICAgICAgICAgIGxlZnRMZW5ndGggPSBwYXJ0aWFscy5sZW5ndGgsXG4gICAgICAgICAgcmFuZ2VMZW5ndGggPSBuYXRpdmVNYXgoYXJnc0xlbmd0aCAtIGhvbGRlcnNMZW5ndGgsIDApLFxuICAgICAgICAgIHJlc3VsdCA9IEFycmF5KGxlZnRMZW5ndGggKyByYW5nZUxlbmd0aCksXG4gICAgICAgICAgaXNVbmN1cnJpZWQgPSAhaXNDdXJyaWVkO1xuXG4gICAgICB3aGlsZSAoKytsZWZ0SW5kZXggPCBsZWZ0TGVuZ3RoKSB7XG4gICAgICAgIHJlc3VsdFtsZWZ0SW5kZXhdID0gcGFydGlhbHNbbGVmdEluZGV4XTtcbiAgICAgIH1cbiAgICAgIHdoaWxlICgrK2FyZ3NJbmRleCA8IGhvbGRlcnNMZW5ndGgpIHtcbiAgICAgICAgaWYgKGlzVW5jdXJyaWVkIHx8IGFyZ3NJbmRleCA8IGFyZ3NMZW5ndGgpIHtcbiAgICAgICAgICByZXN1bHRbaG9sZGVyc1thcmdzSW5kZXhdXSA9IGFyZ3NbYXJnc0luZGV4XTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgd2hpbGUgKHJhbmdlTGVuZ3RoLS0pIHtcbiAgICAgICAgcmVzdWx0W2xlZnRJbmRleCsrXSA9IGFyZ3NbYXJnc0luZGV4KytdO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGlzIGZ1bmN0aW9uIGlzIGxpa2UgYGNvbXBvc2VBcmdzYCBleGNlcHQgdGhhdCB0aGUgYXJndW1lbnRzIGNvbXBvc2l0aW9uXG4gICAgICogaXMgdGFpbG9yZWQgZm9yIGBfLnBhcnRpYWxSaWdodGAuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7QXJyYXl9IGFyZ3MgVGhlIHByb3ZpZGVkIGFyZ3VtZW50cy5cbiAgICAgKiBAcGFyYW0ge0FycmF5fSBwYXJ0aWFscyBUaGUgYXJndW1lbnRzIHRvIGFwcGVuZCB0byB0aG9zZSBwcm92aWRlZC5cbiAgICAgKiBAcGFyYW0ge0FycmF5fSBob2xkZXJzIFRoZSBgcGFydGlhbHNgIHBsYWNlaG9sZGVyIGluZGV4ZXMuXG4gICAgICogQHBhcmFtcyB7Ym9vbGVhbn0gW2lzQ3VycmllZF0gU3BlY2lmeSBjb21wb3NpbmcgZm9yIGEgY3VycmllZCBmdW5jdGlvbi5cbiAgICAgKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIG5ldyBhcnJheSBvZiBjb21wb3NlZCBhcmd1bWVudHMuXG4gICAgICovXG4gICAgZnVuY3Rpb24gY29tcG9zZUFyZ3NSaWdodChhcmdzLCBwYXJ0aWFscywgaG9sZGVycywgaXNDdXJyaWVkKSB7XG4gICAgICB2YXIgYXJnc0luZGV4ID0gLTEsXG4gICAgICAgICAgYXJnc0xlbmd0aCA9IGFyZ3MubGVuZ3RoLFxuICAgICAgICAgIGhvbGRlcnNJbmRleCA9IC0xLFxuICAgICAgICAgIGhvbGRlcnNMZW5ndGggPSBob2xkZXJzLmxlbmd0aCxcbiAgICAgICAgICByaWdodEluZGV4ID0gLTEsXG4gICAgICAgICAgcmlnaHRMZW5ndGggPSBwYXJ0aWFscy5sZW5ndGgsXG4gICAgICAgICAgcmFuZ2VMZW5ndGggPSBuYXRpdmVNYXgoYXJnc0xlbmd0aCAtIGhvbGRlcnNMZW5ndGgsIDApLFxuICAgICAgICAgIHJlc3VsdCA9IEFycmF5KHJhbmdlTGVuZ3RoICsgcmlnaHRMZW5ndGgpLFxuICAgICAgICAgIGlzVW5jdXJyaWVkID0gIWlzQ3VycmllZDtcblxuICAgICAgd2hpbGUgKCsrYXJnc0luZGV4IDwgcmFuZ2VMZW5ndGgpIHtcbiAgICAgICAgcmVzdWx0W2FyZ3NJbmRleF0gPSBhcmdzW2FyZ3NJbmRleF07XG4gICAgICB9XG4gICAgICB2YXIgb2Zmc2V0ID0gYXJnc0luZGV4O1xuICAgICAgd2hpbGUgKCsrcmlnaHRJbmRleCA8IHJpZ2h0TGVuZ3RoKSB7XG4gICAgICAgIHJlc3VsdFtvZmZzZXQgKyByaWdodEluZGV4XSA9IHBhcnRpYWxzW3JpZ2h0SW5kZXhdO1xuICAgICAgfVxuICAgICAgd2hpbGUgKCsraG9sZGVyc0luZGV4IDwgaG9sZGVyc0xlbmd0aCkge1xuICAgICAgICBpZiAoaXNVbmN1cnJpZWQgfHwgYXJnc0luZGV4IDwgYXJnc0xlbmd0aCkge1xuICAgICAgICAgIHJlc3VsdFtvZmZzZXQgKyBob2xkZXJzW2hvbGRlcnNJbmRleF1dID0gYXJnc1thcmdzSW5kZXgrK107XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ29waWVzIHRoZSB2YWx1ZXMgb2YgYHNvdXJjZWAgdG8gYGFycmF5YC5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtBcnJheX0gc291cmNlIFRoZSBhcnJheSB0byBjb3B5IHZhbHVlcyBmcm9tLlxuICAgICAqIEBwYXJhbSB7QXJyYXl9IFthcnJheT1bXV0gVGhlIGFycmF5IHRvIGNvcHkgdmFsdWVzIHRvLlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyBgYXJyYXlgLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGNvcHlBcnJheShzb3VyY2UsIGFycmF5KSB7XG4gICAgICB2YXIgaW5kZXggPSAtMSxcbiAgICAgICAgICBsZW5ndGggPSBzb3VyY2UubGVuZ3RoO1xuXG4gICAgICBhcnJheSB8fCAoYXJyYXkgPSBBcnJheShsZW5ndGgpKTtcbiAgICAgIHdoaWxlICgrK2luZGV4IDwgbGVuZ3RoKSB7XG4gICAgICAgIGFycmF5W2luZGV4XSA9IHNvdXJjZVtpbmRleF07XG4gICAgICB9XG4gICAgICByZXR1cm4gYXJyYXk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ29waWVzIHByb3BlcnRpZXMgb2YgYHNvdXJjZWAgdG8gYG9iamVjdGAuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBzb3VyY2UgVGhlIG9iamVjdCB0byBjb3B5IHByb3BlcnRpZXMgZnJvbS5cbiAgICAgKiBAcGFyYW0ge0FycmF5fSBwcm9wcyBUaGUgcHJvcGVydHkgaWRlbnRpZmllcnMgdG8gY29weS5cbiAgICAgKiBAcGFyYW0ge09iamVjdH0gW29iamVjdD17fV0gVGhlIG9iamVjdCB0byBjb3B5IHByb3BlcnRpZXMgdG8uXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gW2N1c3RvbWl6ZXJdIFRoZSBmdW5jdGlvbiB0byBjdXN0b21pemUgY29waWVkIHZhbHVlcy5cbiAgICAgKiBAcmV0dXJucyB7T2JqZWN0fSBSZXR1cm5zIGBvYmplY3RgLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGNvcHlPYmplY3Qoc291cmNlLCBwcm9wcywgb2JqZWN0LCBjdXN0b21pemVyKSB7XG4gICAgICB2YXIgaXNOZXcgPSAhb2JqZWN0O1xuICAgICAgb2JqZWN0IHx8IChvYmplY3QgPSB7fSk7XG5cbiAgICAgIHZhciBpbmRleCA9IC0xLFxuICAgICAgICAgIGxlbmd0aCA9IHByb3BzLmxlbmd0aDtcblxuICAgICAgd2hpbGUgKCsraW5kZXggPCBsZW5ndGgpIHtcbiAgICAgICAgdmFyIGtleSA9IHByb3BzW2luZGV4XTtcblxuICAgICAgICB2YXIgbmV3VmFsdWUgPSBjdXN0b21pemVyXG4gICAgICAgICAgPyBjdXN0b21pemVyKG9iamVjdFtrZXldLCBzb3VyY2Vba2V5XSwga2V5LCBvYmplY3QsIHNvdXJjZSlcbiAgICAgICAgICA6IHVuZGVmaW5lZDtcblxuICAgICAgICBpZiAobmV3VmFsdWUgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgIG5ld1ZhbHVlID0gc291cmNlW2tleV07XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGlzTmV3KSB7XG4gICAgICAgICAgYmFzZUFzc2lnblZhbHVlKG9iamVjdCwga2V5LCBuZXdWYWx1ZSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgYXNzaWduVmFsdWUob2JqZWN0LCBrZXksIG5ld1ZhbHVlKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgcmV0dXJuIG9iamVjdDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDb3BpZXMgb3duIHN5bWJvbHMgb2YgYHNvdXJjZWAgdG8gYG9iamVjdGAuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBzb3VyY2UgVGhlIG9iamVjdCB0byBjb3B5IHN5bWJvbHMgZnJvbS5cbiAgICAgKiBAcGFyYW0ge09iamVjdH0gW29iamVjdD17fV0gVGhlIG9iamVjdCB0byBjb3B5IHN5bWJvbHMgdG8uXG4gICAgICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyBgb2JqZWN0YC5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBjb3B5U3ltYm9scyhzb3VyY2UsIG9iamVjdCkge1xuICAgICAgcmV0dXJuIGNvcHlPYmplY3Qoc291cmNlLCBnZXRTeW1ib2xzKHNvdXJjZSksIG9iamVjdCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ29waWVzIG93biBhbmQgaW5oZXJpdGVkIHN5bWJvbHMgb2YgYHNvdXJjZWAgdG8gYG9iamVjdGAuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBzb3VyY2UgVGhlIG9iamVjdCB0byBjb3B5IHN5bWJvbHMgZnJvbS5cbiAgICAgKiBAcGFyYW0ge09iamVjdH0gW29iamVjdD17fV0gVGhlIG9iamVjdCB0byBjb3B5IHN5bWJvbHMgdG8uXG4gICAgICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyBgb2JqZWN0YC5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBjb3B5U3ltYm9sc0luKHNvdXJjZSwgb2JqZWN0KSB7XG4gICAgICByZXR1cm4gY29weU9iamVjdChzb3VyY2UsIGdldFN5bWJvbHNJbihzb3VyY2UpLCBvYmplY3QpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBmdW5jdGlvbiBsaWtlIGBfLmdyb3VwQnlgLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBzZXR0ZXIgVGhlIGZ1bmN0aW9uIHRvIHNldCBhY2N1bXVsYXRvciB2YWx1ZXMuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gW2luaXRpYWxpemVyXSBUaGUgYWNjdW11bGF0b3Igb2JqZWN0IGluaXRpYWxpemVyLlxuICAgICAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyB0aGUgbmV3IGFnZ3JlZ2F0b3IgZnVuY3Rpb24uXG4gICAgICovXG4gICAgZnVuY3Rpb24gY3JlYXRlQWdncmVnYXRvcihzZXR0ZXIsIGluaXRpYWxpemVyKSB7XG4gICAgICByZXR1cm4gZnVuY3Rpb24oY29sbGVjdGlvbiwgaXRlcmF0ZWUpIHtcbiAgICAgICAgdmFyIGZ1bmMgPSBpc0FycmF5KGNvbGxlY3Rpb24pID8gYXJyYXlBZ2dyZWdhdG9yIDogYmFzZUFnZ3JlZ2F0b3IsXG4gICAgICAgICAgICBhY2N1bXVsYXRvciA9IGluaXRpYWxpemVyID8gaW5pdGlhbGl6ZXIoKSA6IHt9O1xuXG4gICAgICAgIHJldHVybiBmdW5jKGNvbGxlY3Rpb24sIHNldHRlciwgZ2V0SXRlcmF0ZWUoaXRlcmF0ZWUsIDIpLCBhY2N1bXVsYXRvcik7XG4gICAgICB9O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBmdW5jdGlvbiBsaWtlIGBfLmFzc2lnbmAuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IGFzc2lnbmVyIFRoZSBmdW5jdGlvbiB0byBhc3NpZ24gdmFsdWVzLlxuICAgICAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyB0aGUgbmV3IGFzc2lnbmVyIGZ1bmN0aW9uLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGNyZWF0ZUFzc2lnbmVyKGFzc2lnbmVyKSB7XG4gICAgICByZXR1cm4gYmFzZVJlc3QoZnVuY3Rpb24ob2JqZWN0LCBzb3VyY2VzKSB7XG4gICAgICAgIHZhciBpbmRleCA9IC0xLFxuICAgICAgICAgICAgbGVuZ3RoID0gc291cmNlcy5sZW5ndGgsXG4gICAgICAgICAgICBjdXN0b21pemVyID0gbGVuZ3RoID4gMSA/IHNvdXJjZXNbbGVuZ3RoIC0gMV0gOiB1bmRlZmluZWQsXG4gICAgICAgICAgICBndWFyZCA9IGxlbmd0aCA+IDIgPyBzb3VyY2VzWzJdIDogdW5kZWZpbmVkO1xuXG4gICAgICAgIGN1c3RvbWl6ZXIgPSAoYXNzaWduZXIubGVuZ3RoID4gMyAmJiB0eXBlb2YgY3VzdG9taXplciA9PSAnZnVuY3Rpb24nKVxuICAgICAgICAgID8gKGxlbmd0aC0tLCBjdXN0b21pemVyKVxuICAgICAgICAgIDogdW5kZWZpbmVkO1xuXG4gICAgICAgIGlmIChndWFyZCAmJiBpc0l0ZXJhdGVlQ2FsbChzb3VyY2VzWzBdLCBzb3VyY2VzWzFdLCBndWFyZCkpIHtcbiAgICAgICAgICBjdXN0b21pemVyID0gbGVuZ3RoIDwgMyA/IHVuZGVmaW5lZCA6IGN1c3RvbWl6ZXI7XG4gICAgICAgICAgbGVuZ3RoID0gMTtcbiAgICAgICAgfVxuICAgICAgICBvYmplY3QgPSBPYmplY3Qob2JqZWN0KTtcbiAgICAgICAgd2hpbGUgKCsraW5kZXggPCBsZW5ndGgpIHtcbiAgICAgICAgICB2YXIgc291cmNlID0gc291cmNlc1tpbmRleF07XG4gICAgICAgICAgaWYgKHNvdXJjZSkge1xuICAgICAgICAgICAgYXNzaWduZXIob2JqZWN0LCBzb3VyY2UsIGluZGV4LCBjdXN0b21pemVyKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG9iamVjdDtcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBgYmFzZUVhY2hgIG9yIGBiYXNlRWFjaFJpZ2h0YCBmdW5jdGlvbi5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gZWFjaEZ1bmMgVGhlIGZ1bmN0aW9uIHRvIGl0ZXJhdGUgb3ZlciBhIGNvbGxlY3Rpb24uXG4gICAgICogQHBhcmFtIHtib29sZWFufSBbZnJvbVJpZ2h0XSBTcGVjaWZ5IGl0ZXJhdGluZyBmcm9tIHJpZ2h0IHRvIGxlZnQuXG4gICAgICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBuZXcgYmFzZSBmdW5jdGlvbi5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBjcmVhdGVCYXNlRWFjaChlYWNoRnVuYywgZnJvbVJpZ2h0KSB7XG4gICAgICByZXR1cm4gZnVuY3Rpb24oY29sbGVjdGlvbiwgaXRlcmF0ZWUpIHtcbiAgICAgICAgaWYgKGNvbGxlY3Rpb24gPT0gbnVsbCkge1xuICAgICAgICAgIHJldHVybiBjb2xsZWN0aW9uO1xuICAgICAgICB9XG4gICAgICAgIGlmICghaXNBcnJheUxpa2UoY29sbGVjdGlvbikpIHtcbiAgICAgICAgICByZXR1cm4gZWFjaEZ1bmMoY29sbGVjdGlvbiwgaXRlcmF0ZWUpO1xuICAgICAgICB9XG4gICAgICAgIHZhciBsZW5ndGggPSBjb2xsZWN0aW9uLmxlbmd0aCxcbiAgICAgICAgICAgIGluZGV4ID0gZnJvbVJpZ2h0ID8gbGVuZ3RoIDogLTEsXG4gICAgICAgICAgICBpdGVyYWJsZSA9IE9iamVjdChjb2xsZWN0aW9uKTtcblxuICAgICAgICB3aGlsZSAoKGZyb21SaWdodCA/IGluZGV4LS0gOiArK2luZGV4IDwgbGVuZ3RoKSkge1xuICAgICAgICAgIGlmIChpdGVyYXRlZShpdGVyYWJsZVtpbmRleF0sIGluZGV4LCBpdGVyYWJsZSkgPT09IGZhbHNlKSB7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGNvbGxlY3Rpb247XG4gICAgICB9O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBiYXNlIGZ1bmN0aW9uIGZvciBtZXRob2RzIGxpa2UgYF8uZm9ySW5gIGFuZCBgXy5mb3JPd25gLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge2Jvb2xlYW59IFtmcm9tUmlnaHRdIFNwZWNpZnkgaXRlcmF0aW5nIGZyb20gcmlnaHQgdG8gbGVmdC5cbiAgICAgKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyBiYXNlIGZ1bmN0aW9uLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGNyZWF0ZUJhc2VGb3IoZnJvbVJpZ2h0KSB7XG4gICAgICByZXR1cm4gZnVuY3Rpb24ob2JqZWN0LCBpdGVyYXRlZSwga2V5c0Z1bmMpIHtcbiAgICAgICAgdmFyIGluZGV4ID0gLTEsXG4gICAgICAgICAgICBpdGVyYWJsZSA9IE9iamVjdChvYmplY3QpLFxuICAgICAgICAgICAgcHJvcHMgPSBrZXlzRnVuYyhvYmplY3QpLFxuICAgICAgICAgICAgbGVuZ3RoID0gcHJvcHMubGVuZ3RoO1xuXG4gICAgICAgIHdoaWxlIChsZW5ndGgtLSkge1xuICAgICAgICAgIHZhciBrZXkgPSBwcm9wc1tmcm9tUmlnaHQgPyBsZW5ndGggOiArK2luZGV4XTtcbiAgICAgICAgICBpZiAoaXRlcmF0ZWUoaXRlcmFibGVba2V5XSwga2V5LCBpdGVyYWJsZSkgPT09IGZhbHNlKSB7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG9iamVjdDtcbiAgICAgIH07XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIGZ1bmN0aW9uIHRoYXQgd3JhcHMgYGZ1bmNgIHRvIGludm9rZSBpdCB3aXRoIHRoZSBvcHRpb25hbCBgdGhpc2BcbiAgICAgKiBiaW5kaW5nIG9mIGB0aGlzQXJnYC5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gZnVuYyBUaGUgZnVuY3Rpb24gdG8gd3JhcC5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gYml0bWFzayBUaGUgYml0bWFzayBmbGFncy4gU2VlIGBjcmVhdGVXcmFwYCBmb3IgbW9yZSBkZXRhaWxzLlxuICAgICAqIEBwYXJhbSB7Kn0gW3RoaXNBcmddIFRoZSBgdGhpc2AgYmluZGluZyBvZiBgZnVuY2AuXG4gICAgICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBuZXcgd3JhcHBlZCBmdW5jdGlvbi5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBjcmVhdGVCaW5kKGZ1bmMsIGJpdG1hc2ssIHRoaXNBcmcpIHtcbiAgICAgIHZhciBpc0JpbmQgPSBiaXRtYXNrICYgV1JBUF9CSU5EX0ZMQUcsXG4gICAgICAgICAgQ3RvciA9IGNyZWF0ZUN0b3IoZnVuYyk7XG5cbiAgICAgIGZ1bmN0aW9uIHdyYXBwZXIoKSB7XG4gICAgICAgIHZhciBmbiA9ICh0aGlzICYmIHRoaXMgIT09IHJvb3QgJiYgdGhpcyBpbnN0YW5jZW9mIHdyYXBwZXIpID8gQ3RvciA6IGZ1bmM7XG4gICAgICAgIHJldHVybiBmbi5hcHBseShpc0JpbmQgPyB0aGlzQXJnIDogdGhpcywgYXJndW1lbnRzKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiB3cmFwcGVyO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBmdW5jdGlvbiBsaWtlIGBfLmxvd2VyRmlyc3RgLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gbWV0aG9kTmFtZSBUaGUgbmFtZSBvZiB0aGUgYFN0cmluZ2AgY2FzZSBtZXRob2QgdG8gdXNlLlxuICAgICAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyB0aGUgbmV3IGNhc2UgZnVuY3Rpb24uXG4gICAgICovXG4gICAgZnVuY3Rpb24gY3JlYXRlQ2FzZUZpcnN0KG1ldGhvZE5hbWUpIHtcbiAgICAgIHJldHVybiBmdW5jdGlvbihzdHJpbmcpIHtcbiAgICAgICAgc3RyaW5nID0gdG9TdHJpbmcoc3RyaW5nKTtcblxuICAgICAgICB2YXIgc3RyU3ltYm9scyA9IGhhc1VuaWNvZGUoc3RyaW5nKVxuICAgICAgICAgID8gc3RyaW5nVG9BcnJheShzdHJpbmcpXG4gICAgICAgICAgOiB1bmRlZmluZWQ7XG5cbiAgICAgICAgdmFyIGNociA9IHN0clN5bWJvbHNcbiAgICAgICAgICA/IHN0clN5bWJvbHNbMF1cbiAgICAgICAgICA6IHN0cmluZy5jaGFyQXQoMCk7XG5cbiAgICAgICAgdmFyIHRyYWlsaW5nID0gc3RyU3ltYm9sc1xuICAgICAgICAgID8gY2FzdFNsaWNlKHN0clN5bWJvbHMsIDEpLmpvaW4oJycpXG4gICAgICAgICAgOiBzdHJpbmcuc2xpY2UoMSk7XG5cbiAgICAgICAgcmV0dXJuIGNoclttZXRob2ROYW1lXSgpICsgdHJhaWxpbmc7XG4gICAgICB9O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBmdW5jdGlvbiBsaWtlIGBfLmNhbWVsQ2FzZWAuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IGNhbGxiYWNrIFRoZSBmdW5jdGlvbiB0byBjb21iaW5lIGVhY2ggd29yZC5cbiAgICAgKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyBjb21wb3VuZGVyIGZ1bmN0aW9uLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGNyZWF0ZUNvbXBvdW5kZXIoY2FsbGJhY2spIHtcbiAgICAgIHJldHVybiBmdW5jdGlvbihzdHJpbmcpIHtcbiAgICAgICAgcmV0dXJuIGFycmF5UmVkdWNlKHdvcmRzKGRlYnVycihzdHJpbmcpLnJlcGxhY2UocmVBcG9zLCAnJykpLCBjYWxsYmFjaywgJycpO1xuICAgICAgfTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgZnVuY3Rpb24gdGhhdCBwcm9kdWNlcyBhbiBpbnN0YW5jZSBvZiBgQ3RvcmAgcmVnYXJkbGVzcyBvZlxuICAgICAqIHdoZXRoZXIgaXQgd2FzIGludm9rZWQgYXMgcGFydCBvZiBhIGBuZXdgIGV4cHJlc3Npb24gb3IgYnkgYGNhbGxgIG9yIGBhcHBseWAuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IEN0b3IgVGhlIGNvbnN0cnVjdG9yIHRvIHdyYXAuXG4gICAgICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBuZXcgd3JhcHBlZCBmdW5jdGlvbi5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBjcmVhdGVDdG9yKEN0b3IpIHtcbiAgICAgIHJldHVybiBmdW5jdGlvbigpIHtcbiAgICAgICAgLy8gVXNlIGEgYHN3aXRjaGAgc3RhdGVtZW50IHRvIHdvcmsgd2l0aCBjbGFzcyBjb25zdHJ1Y3RvcnMuIFNlZVxuICAgICAgICAvLyBodHRwOi8vZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi83LjAvI3NlYy1lY21hc2NyaXB0LWZ1bmN0aW9uLW9iamVjdHMtY2FsbC10aGlzYXJndW1lbnQtYXJndW1lbnRzbGlzdFxuICAgICAgICAvLyBmb3IgbW9yZSBkZXRhaWxzLlxuICAgICAgICB2YXIgYXJncyA9IGFyZ3VtZW50cztcbiAgICAgICAgc3dpdGNoIChhcmdzLmxlbmd0aCkge1xuICAgICAgICAgIGNhc2UgMDogcmV0dXJuIG5ldyBDdG9yO1xuICAgICAgICAgIGNhc2UgMTogcmV0dXJuIG5ldyBDdG9yKGFyZ3NbMF0pO1xuICAgICAgICAgIGNhc2UgMjogcmV0dXJuIG5ldyBDdG9yKGFyZ3NbMF0sIGFyZ3NbMV0pO1xuICAgICAgICAgIGNhc2UgMzogcmV0dXJuIG5ldyBDdG9yKGFyZ3NbMF0sIGFyZ3NbMV0sIGFyZ3NbMl0pO1xuICAgICAgICAgIGNhc2UgNDogcmV0dXJuIG5ldyBDdG9yKGFyZ3NbMF0sIGFyZ3NbMV0sIGFyZ3NbMl0sIGFyZ3NbM10pO1xuICAgICAgICAgIGNhc2UgNTogcmV0dXJuIG5ldyBDdG9yKGFyZ3NbMF0sIGFyZ3NbMV0sIGFyZ3NbMl0sIGFyZ3NbM10sIGFyZ3NbNF0pO1xuICAgICAgICAgIGNhc2UgNjogcmV0dXJuIG5ldyBDdG9yKGFyZ3NbMF0sIGFyZ3NbMV0sIGFyZ3NbMl0sIGFyZ3NbM10sIGFyZ3NbNF0sIGFyZ3NbNV0pO1xuICAgICAgICAgIGNhc2UgNzogcmV0dXJuIG5ldyBDdG9yKGFyZ3NbMF0sIGFyZ3NbMV0sIGFyZ3NbMl0sIGFyZ3NbM10sIGFyZ3NbNF0sIGFyZ3NbNV0sIGFyZ3NbNl0pO1xuICAgICAgICB9XG4gICAgICAgIHZhciB0aGlzQmluZGluZyA9IGJhc2VDcmVhdGUoQ3Rvci5wcm90b3R5cGUpLFxuICAgICAgICAgICAgcmVzdWx0ID0gQ3Rvci5hcHBseSh0aGlzQmluZGluZywgYXJncyk7XG5cbiAgICAgICAgLy8gTWltaWMgdGhlIGNvbnN0cnVjdG9yJ3MgYHJldHVybmAgYmVoYXZpb3IuXG4gICAgICAgIC8vIFNlZSBodHRwczovL2VzNS5naXRodWIuaW8vI3gxMy4yLjIgZm9yIG1vcmUgZGV0YWlscy5cbiAgICAgICAgcmV0dXJuIGlzT2JqZWN0KHJlc3VsdCkgPyByZXN1bHQgOiB0aGlzQmluZGluZztcbiAgICAgIH07XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIGZ1bmN0aW9uIHRoYXQgd3JhcHMgYGZ1bmNgIHRvIGVuYWJsZSBjdXJyeWluZy5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gZnVuYyBUaGUgZnVuY3Rpb24gdG8gd3JhcC5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gYml0bWFzayBUaGUgYml0bWFzayBmbGFncy4gU2VlIGBjcmVhdGVXcmFwYCBmb3IgbW9yZSBkZXRhaWxzLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBhcml0eSBUaGUgYXJpdHkgb2YgYGZ1bmNgLlxuICAgICAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyB0aGUgbmV3IHdyYXBwZWQgZnVuY3Rpb24uXG4gICAgICovXG4gICAgZnVuY3Rpb24gY3JlYXRlQ3VycnkoZnVuYywgYml0bWFzaywgYXJpdHkpIHtcbiAgICAgIHZhciBDdG9yID0gY3JlYXRlQ3RvcihmdW5jKTtcblxuICAgICAgZnVuY3Rpb24gd3JhcHBlcigpIHtcbiAgICAgICAgdmFyIGxlbmd0aCA9IGFyZ3VtZW50cy5sZW5ndGgsXG4gICAgICAgICAgICBhcmdzID0gQXJyYXkobGVuZ3RoKSxcbiAgICAgICAgICAgIGluZGV4ID0gbGVuZ3RoLFxuICAgICAgICAgICAgcGxhY2Vob2xkZXIgPSBnZXRIb2xkZXIod3JhcHBlcik7XG5cbiAgICAgICAgd2hpbGUgKGluZGV4LS0pIHtcbiAgICAgICAgICBhcmdzW2luZGV4XSA9IGFyZ3VtZW50c1tpbmRleF07XG4gICAgICAgIH1cbiAgICAgICAgdmFyIGhvbGRlcnMgPSAobGVuZ3RoIDwgMyAmJiBhcmdzWzBdICE9PSBwbGFjZWhvbGRlciAmJiBhcmdzW2xlbmd0aCAtIDFdICE9PSBwbGFjZWhvbGRlcilcbiAgICAgICAgICA/IFtdXG4gICAgICAgICAgOiByZXBsYWNlSG9sZGVycyhhcmdzLCBwbGFjZWhvbGRlcik7XG5cbiAgICAgICAgbGVuZ3RoIC09IGhvbGRlcnMubGVuZ3RoO1xuICAgICAgICBpZiAobGVuZ3RoIDwgYXJpdHkpIHtcbiAgICAgICAgICByZXR1cm4gY3JlYXRlUmVjdXJyeShcbiAgICAgICAgICAgIGZ1bmMsIGJpdG1hc2ssIGNyZWF0ZUh5YnJpZCwgd3JhcHBlci5wbGFjZWhvbGRlciwgdW5kZWZpbmVkLFxuICAgICAgICAgICAgYXJncywgaG9sZGVycywgdW5kZWZpbmVkLCB1bmRlZmluZWQsIGFyaXR5IC0gbGVuZ3RoKTtcbiAgICAgICAgfVxuICAgICAgICB2YXIgZm4gPSAodGhpcyAmJiB0aGlzICE9PSByb290ICYmIHRoaXMgaW5zdGFuY2VvZiB3cmFwcGVyKSA/IEN0b3IgOiBmdW5jO1xuICAgICAgICByZXR1cm4gYXBwbHkoZm4sIHRoaXMsIGFyZ3MpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHdyYXBwZXI7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIGBfLmZpbmRgIG9yIGBfLmZpbmRMYXN0YCBmdW5jdGlvbi5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gZmluZEluZGV4RnVuYyBUaGUgZnVuY3Rpb24gdG8gZmluZCB0aGUgY29sbGVjdGlvbiBpbmRleC5cbiAgICAgKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyBmaW5kIGZ1bmN0aW9uLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGNyZWF0ZUZpbmQoZmluZEluZGV4RnVuYykge1xuICAgICAgcmV0dXJuIGZ1bmN0aW9uKGNvbGxlY3Rpb24sIHByZWRpY2F0ZSwgZnJvbUluZGV4KSB7XG4gICAgICAgIHZhciBpdGVyYWJsZSA9IE9iamVjdChjb2xsZWN0aW9uKTtcbiAgICAgICAgaWYgKCFpc0FycmF5TGlrZShjb2xsZWN0aW9uKSkge1xuICAgICAgICAgIHZhciBpdGVyYXRlZSA9IGdldEl0ZXJhdGVlKHByZWRpY2F0ZSwgMyk7XG4gICAgICAgICAgY29sbGVjdGlvbiA9IGtleXMoY29sbGVjdGlvbik7XG4gICAgICAgICAgcHJlZGljYXRlID0gZnVuY3Rpb24oa2V5KSB7IHJldHVybiBpdGVyYXRlZShpdGVyYWJsZVtrZXldLCBrZXksIGl0ZXJhYmxlKTsgfTtcbiAgICAgICAgfVxuICAgICAgICB2YXIgaW5kZXggPSBmaW5kSW5kZXhGdW5jKGNvbGxlY3Rpb24sIHByZWRpY2F0ZSwgZnJvbUluZGV4KTtcbiAgICAgICAgcmV0dXJuIGluZGV4ID4gLTEgPyBpdGVyYWJsZVtpdGVyYXRlZSA/IGNvbGxlY3Rpb25baW5kZXhdIDogaW5kZXhdIDogdW5kZWZpbmVkO1xuICAgICAgfTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgYF8uZmxvd2Agb3IgYF8uZmxvd1JpZ2h0YCBmdW5jdGlvbi5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtib29sZWFufSBbZnJvbVJpZ2h0XSBTcGVjaWZ5IGl0ZXJhdGluZyBmcm9tIHJpZ2h0IHRvIGxlZnQuXG4gICAgICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBuZXcgZmxvdyBmdW5jdGlvbi5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBjcmVhdGVGbG93KGZyb21SaWdodCkge1xuICAgICAgcmV0dXJuIGZsYXRSZXN0KGZ1bmN0aW9uKGZ1bmNzKSB7XG4gICAgICAgIHZhciBsZW5ndGggPSBmdW5jcy5sZW5ndGgsXG4gICAgICAgICAgICBpbmRleCA9IGxlbmd0aCxcbiAgICAgICAgICAgIHByZXJlcSA9IExvZGFzaFdyYXBwZXIucHJvdG90eXBlLnRocnU7XG5cbiAgICAgICAgaWYgKGZyb21SaWdodCkge1xuICAgICAgICAgIGZ1bmNzLnJldmVyc2UoKTtcbiAgICAgICAgfVxuICAgICAgICB3aGlsZSAoaW5kZXgtLSkge1xuICAgICAgICAgIHZhciBmdW5jID0gZnVuY3NbaW5kZXhdO1xuICAgICAgICAgIGlmICh0eXBlb2YgZnVuYyAhPSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKEZVTkNfRVJST1JfVEVYVCk7XG4gICAgICAgICAgfVxuICAgICAgICAgIGlmIChwcmVyZXEgJiYgIXdyYXBwZXIgJiYgZ2V0RnVuY05hbWUoZnVuYykgPT0gJ3dyYXBwZXInKSB7XG4gICAgICAgICAgICB2YXIgd3JhcHBlciA9IG5ldyBMb2Rhc2hXcmFwcGVyKFtdLCB0cnVlKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaW5kZXggPSB3cmFwcGVyID8gaW5kZXggOiBsZW5ndGg7XG4gICAgICAgIHdoaWxlICgrK2luZGV4IDwgbGVuZ3RoKSB7XG4gICAgICAgICAgZnVuYyA9IGZ1bmNzW2luZGV4XTtcblxuICAgICAgICAgIHZhciBmdW5jTmFtZSA9IGdldEZ1bmNOYW1lKGZ1bmMpLFxuICAgICAgICAgICAgICBkYXRhID0gZnVuY05hbWUgPT0gJ3dyYXBwZXInID8gZ2V0RGF0YShmdW5jKSA6IHVuZGVmaW5lZDtcblxuICAgICAgICAgIGlmIChkYXRhICYmIGlzTGF6aWFibGUoZGF0YVswXSkgJiZcbiAgICAgICAgICAgICAgICBkYXRhWzFdID09IChXUkFQX0FSWV9GTEFHIHwgV1JBUF9DVVJSWV9GTEFHIHwgV1JBUF9QQVJUSUFMX0ZMQUcgfCBXUkFQX1JFQVJHX0ZMQUcpICYmXG4gICAgICAgICAgICAgICAgIWRhdGFbNF0ubGVuZ3RoICYmIGRhdGFbOV0gPT0gMVxuICAgICAgICAgICAgICApIHtcbiAgICAgICAgICAgIHdyYXBwZXIgPSB3cmFwcGVyW2dldEZ1bmNOYW1lKGRhdGFbMF0pXS5hcHBseSh3cmFwcGVyLCBkYXRhWzNdKTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgd3JhcHBlciA9IChmdW5jLmxlbmd0aCA9PSAxICYmIGlzTGF6aWFibGUoZnVuYykpXG4gICAgICAgICAgICAgID8gd3JhcHBlcltmdW5jTmFtZV0oKVxuICAgICAgICAgICAgICA6IHdyYXBwZXIudGhydShmdW5jKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGZ1bmN0aW9uKCkge1xuICAgICAgICAgIHZhciBhcmdzID0gYXJndW1lbnRzLFxuICAgICAgICAgICAgICB2YWx1ZSA9IGFyZ3NbMF07XG5cbiAgICAgICAgICBpZiAod3JhcHBlciAmJiBhcmdzLmxlbmd0aCA9PSAxICYmIGlzQXJyYXkodmFsdWUpKSB7XG4gICAgICAgICAgICByZXR1cm4gd3JhcHBlci5wbGFudCh2YWx1ZSkudmFsdWUoKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgdmFyIGluZGV4ID0gMCxcbiAgICAgICAgICAgICAgcmVzdWx0ID0gbGVuZ3RoID8gZnVuY3NbaW5kZXhdLmFwcGx5KHRoaXMsIGFyZ3MpIDogdmFsdWU7XG5cbiAgICAgICAgICB3aGlsZSAoKytpbmRleCA8IGxlbmd0aCkge1xuICAgICAgICAgICAgcmVzdWx0ID0gZnVuY3NbaW5kZXhdLmNhbGwodGhpcywgcmVzdWx0KTtcbiAgICAgICAgICB9XG4gICAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICAgICAgfTtcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBmdW5jdGlvbiB0aGF0IHdyYXBzIGBmdW5jYCB0byBpbnZva2UgaXQgd2l0aCBvcHRpb25hbCBgdGhpc2BcbiAgICAgKiBiaW5kaW5nIG9mIGB0aGlzQXJnYCwgcGFydGlhbCBhcHBsaWNhdGlvbiwgYW5kIGN1cnJ5aW5nLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufHN0cmluZ30gZnVuYyBUaGUgZnVuY3Rpb24gb3IgbWV0aG9kIG5hbWUgdG8gd3JhcC5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gYml0bWFzayBUaGUgYml0bWFzayBmbGFncy4gU2VlIGBjcmVhdGVXcmFwYCBmb3IgbW9yZSBkZXRhaWxzLlxuICAgICAqIEBwYXJhbSB7Kn0gW3RoaXNBcmddIFRoZSBgdGhpc2AgYmluZGluZyBvZiBgZnVuY2AuXG4gICAgICogQHBhcmFtIHtBcnJheX0gW3BhcnRpYWxzXSBUaGUgYXJndW1lbnRzIHRvIHByZXBlbmQgdG8gdGhvc2UgcHJvdmlkZWQgdG9cbiAgICAgKiAgdGhlIG5ldyBmdW5jdGlvbi5cbiAgICAgKiBAcGFyYW0ge0FycmF5fSBbaG9sZGVyc10gVGhlIGBwYXJ0aWFsc2AgcGxhY2Vob2xkZXIgaW5kZXhlcy5cbiAgICAgKiBAcGFyYW0ge0FycmF5fSBbcGFydGlhbHNSaWdodF0gVGhlIGFyZ3VtZW50cyB0byBhcHBlbmQgdG8gdGhvc2UgcHJvdmlkZWRcbiAgICAgKiAgdG8gdGhlIG5ldyBmdW5jdGlvbi5cbiAgICAgKiBAcGFyYW0ge0FycmF5fSBbaG9sZGVyc1JpZ2h0XSBUaGUgYHBhcnRpYWxzUmlnaHRgIHBsYWNlaG9sZGVyIGluZGV4ZXMuXG4gICAgICogQHBhcmFtIHtBcnJheX0gW2FyZ1Bvc10gVGhlIGFyZ3VtZW50IHBvc2l0aW9ucyBvZiB0aGUgbmV3IGZ1bmN0aW9uLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbYXJ5XSBUaGUgYXJpdHkgY2FwIG9mIGBmdW5jYC5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gW2FyaXR5XSBUaGUgYXJpdHkgb2YgYGZ1bmNgLlxuICAgICAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyB0aGUgbmV3IHdyYXBwZWQgZnVuY3Rpb24uXG4gICAgICovXG4gICAgZnVuY3Rpb24gY3JlYXRlSHlicmlkKGZ1bmMsIGJpdG1hc2ssIHRoaXNBcmcsIHBhcnRpYWxzLCBob2xkZXJzLCBwYXJ0aWFsc1JpZ2h0LCBob2xkZXJzUmlnaHQsIGFyZ1BvcywgYXJ5LCBhcml0eSkge1xuICAgICAgdmFyIGlzQXJ5ID0gYml0bWFzayAmIFdSQVBfQVJZX0ZMQUcsXG4gICAgICAgICAgaXNCaW5kID0gYml0bWFzayAmIFdSQVBfQklORF9GTEFHLFxuICAgICAgICAgIGlzQmluZEtleSA9IGJpdG1hc2sgJiBXUkFQX0JJTkRfS0VZX0ZMQUcsXG4gICAgICAgICAgaXNDdXJyaWVkID0gYml0bWFzayAmIChXUkFQX0NVUlJZX0ZMQUcgfCBXUkFQX0NVUlJZX1JJR0hUX0ZMQUcpLFxuICAgICAgICAgIGlzRmxpcCA9IGJpdG1hc2sgJiBXUkFQX0ZMSVBfRkxBRyxcbiAgICAgICAgICBDdG9yID0gaXNCaW5kS2V5ID8gdW5kZWZpbmVkIDogY3JlYXRlQ3RvcihmdW5jKTtcblxuICAgICAgZnVuY3Rpb24gd3JhcHBlcigpIHtcbiAgICAgICAgdmFyIGxlbmd0aCA9IGFyZ3VtZW50cy5sZW5ndGgsXG4gICAgICAgICAgICBhcmdzID0gQXJyYXkobGVuZ3RoKSxcbiAgICAgICAgICAgIGluZGV4ID0gbGVuZ3RoO1xuXG4gICAgICAgIHdoaWxlIChpbmRleC0tKSB7XG4gICAgICAgICAgYXJnc1tpbmRleF0gPSBhcmd1bWVudHNbaW5kZXhdO1xuICAgICAgICB9XG4gICAgICAgIGlmIChpc0N1cnJpZWQpIHtcbiAgICAgICAgICB2YXIgcGxhY2Vob2xkZXIgPSBnZXRIb2xkZXIod3JhcHBlciksXG4gICAgICAgICAgICAgIGhvbGRlcnNDb3VudCA9IGNvdW50SG9sZGVycyhhcmdzLCBwbGFjZWhvbGRlcik7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHBhcnRpYWxzKSB7XG4gICAgICAgICAgYXJncyA9IGNvbXBvc2VBcmdzKGFyZ3MsIHBhcnRpYWxzLCBob2xkZXJzLCBpc0N1cnJpZWQpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChwYXJ0aWFsc1JpZ2h0KSB7XG4gICAgICAgICAgYXJncyA9IGNvbXBvc2VBcmdzUmlnaHQoYXJncywgcGFydGlhbHNSaWdodCwgaG9sZGVyc1JpZ2h0LCBpc0N1cnJpZWQpO1xuICAgICAgICB9XG4gICAgICAgIGxlbmd0aCAtPSBob2xkZXJzQ291bnQ7XG4gICAgICAgIGlmIChpc0N1cnJpZWQgJiYgbGVuZ3RoIDwgYXJpdHkpIHtcbiAgICAgICAgICB2YXIgbmV3SG9sZGVycyA9IHJlcGxhY2VIb2xkZXJzKGFyZ3MsIHBsYWNlaG9sZGVyKTtcbiAgICAgICAgICByZXR1cm4gY3JlYXRlUmVjdXJyeShcbiAgICAgICAgICAgIGZ1bmMsIGJpdG1hc2ssIGNyZWF0ZUh5YnJpZCwgd3JhcHBlci5wbGFjZWhvbGRlciwgdGhpc0FyZyxcbiAgICAgICAgICAgIGFyZ3MsIG5ld0hvbGRlcnMsIGFyZ1BvcywgYXJ5LCBhcml0eSAtIGxlbmd0aFxuICAgICAgICAgICk7XG4gICAgICAgIH1cbiAgICAgICAgdmFyIHRoaXNCaW5kaW5nID0gaXNCaW5kID8gdGhpc0FyZyA6IHRoaXMsXG4gICAgICAgICAgICBmbiA9IGlzQmluZEtleSA/IHRoaXNCaW5kaW5nW2Z1bmNdIDogZnVuYztcblxuICAgICAgICBsZW5ndGggPSBhcmdzLmxlbmd0aDtcbiAgICAgICAgaWYgKGFyZ1Bvcykge1xuICAgICAgICAgIGFyZ3MgPSByZW9yZGVyKGFyZ3MsIGFyZ1Bvcyk7XG4gICAgICAgIH0gZWxzZSBpZiAoaXNGbGlwICYmIGxlbmd0aCA+IDEpIHtcbiAgICAgICAgICBhcmdzLnJldmVyc2UoKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoaXNBcnkgJiYgYXJ5IDwgbGVuZ3RoKSB7XG4gICAgICAgICAgYXJncy5sZW5ndGggPSBhcnk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRoaXMgJiYgdGhpcyAhPT0gcm9vdCAmJiB0aGlzIGluc3RhbmNlb2Ygd3JhcHBlcikge1xuICAgICAgICAgIGZuID0gQ3RvciB8fCBjcmVhdGVDdG9yKGZuKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gZm4uYXBwbHkodGhpc0JpbmRpbmcsIGFyZ3MpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHdyYXBwZXI7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIGZ1bmN0aW9uIGxpa2UgYF8uaW52ZXJ0QnlgLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBzZXR0ZXIgVGhlIGZ1bmN0aW9uIHRvIHNldCBhY2N1bXVsYXRvciB2YWx1ZXMuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gdG9JdGVyYXRlZSBUaGUgZnVuY3Rpb24gdG8gcmVzb2x2ZSBpdGVyYXRlZXMuXG4gICAgICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBuZXcgaW52ZXJ0ZXIgZnVuY3Rpb24uXG4gICAgICovXG4gICAgZnVuY3Rpb24gY3JlYXRlSW52ZXJ0ZXIoc2V0dGVyLCB0b0l0ZXJhdGVlKSB7XG4gICAgICByZXR1cm4gZnVuY3Rpb24ob2JqZWN0LCBpdGVyYXRlZSkge1xuICAgICAgICByZXR1cm4gYmFzZUludmVydGVyKG9iamVjdCwgc2V0dGVyLCB0b0l0ZXJhdGVlKGl0ZXJhdGVlKSwge30pO1xuICAgICAgfTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgZnVuY3Rpb24gdGhhdCBwZXJmb3JtcyBhIG1hdGhlbWF0aWNhbCBvcGVyYXRpb24gb24gdHdvIHZhbHVlcy5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gb3BlcmF0b3IgVGhlIGZ1bmN0aW9uIHRvIHBlcmZvcm0gdGhlIG9wZXJhdGlvbi5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gW2RlZmF1bHRWYWx1ZV0gVGhlIHZhbHVlIHVzZWQgZm9yIGB1bmRlZmluZWRgIGFyZ3VtZW50cy5cbiAgICAgKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyBtYXRoZW1hdGljYWwgb3BlcmF0aW9uIGZ1bmN0aW9uLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGNyZWF0ZU1hdGhPcGVyYXRpb24ob3BlcmF0b3IsIGRlZmF1bHRWYWx1ZSkge1xuICAgICAgcmV0dXJuIGZ1bmN0aW9uKHZhbHVlLCBvdGhlcikge1xuICAgICAgICB2YXIgcmVzdWx0O1xuICAgICAgICBpZiAodmFsdWUgPT09IHVuZGVmaW5lZCAmJiBvdGhlciA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgcmV0dXJuIGRlZmF1bHRWYWx1ZTtcbiAgICAgICAgfVxuICAgICAgICBpZiAodmFsdWUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgIHJlc3VsdCA9IHZhbHVlO1xuICAgICAgICB9XG4gICAgICAgIGlmIChvdGhlciAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgaWYgKHJlc3VsdCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICByZXR1cm4gb3RoZXI7XG4gICAgICAgICAgfVxuICAgICAgICAgIGlmICh0eXBlb2YgdmFsdWUgPT0gJ3N0cmluZycgfHwgdHlwZW9mIG90aGVyID09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgICB2YWx1ZSA9IGJhc2VUb1N0cmluZyh2YWx1ZSk7XG4gICAgICAgICAgICBvdGhlciA9IGJhc2VUb1N0cmluZyhvdGhlcik7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHZhbHVlID0gYmFzZVRvTnVtYmVyKHZhbHVlKTtcbiAgICAgICAgICAgIG90aGVyID0gYmFzZVRvTnVtYmVyKG90aGVyKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgcmVzdWx0ID0gb3BlcmF0b3IodmFsdWUsIG90aGVyKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgICAgfTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgZnVuY3Rpb24gbGlrZSBgXy5vdmVyYC5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gYXJyYXlGdW5jIFRoZSBmdW5jdGlvbiB0byBpdGVyYXRlIG92ZXIgaXRlcmF0ZWVzLlxuICAgICAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyB0aGUgbmV3IG92ZXIgZnVuY3Rpb24uXG4gICAgICovXG4gICAgZnVuY3Rpb24gY3JlYXRlT3ZlcihhcnJheUZ1bmMpIHtcbiAgICAgIHJldHVybiBmbGF0UmVzdChmdW5jdGlvbihpdGVyYXRlZXMpIHtcbiAgICAgICAgaXRlcmF0ZWVzID0gYXJyYXlNYXAoaXRlcmF0ZWVzLCBiYXNlVW5hcnkoZ2V0SXRlcmF0ZWUoKSkpO1xuICAgICAgICByZXR1cm4gYmFzZVJlc3QoZnVuY3Rpb24oYXJncykge1xuICAgICAgICAgIHZhciB0aGlzQXJnID0gdGhpcztcbiAgICAgICAgICByZXR1cm4gYXJyYXlGdW5jKGl0ZXJhdGVlcywgZnVuY3Rpb24oaXRlcmF0ZWUpIHtcbiAgICAgICAgICAgIHJldHVybiBhcHBseShpdGVyYXRlZSwgdGhpc0FyZywgYXJncyk7XG4gICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyB0aGUgcGFkZGluZyBmb3IgYHN0cmluZ2AgYmFzZWQgb24gYGxlbmd0aGAuIFRoZSBgY2hhcnNgIHN0cmluZ1xuICAgICAqIGlzIHRydW5jYXRlZCBpZiB0aGUgbnVtYmVyIG9mIGNoYXJhY3RlcnMgZXhjZWVkcyBgbGVuZ3RoYC5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IGxlbmd0aCBUaGUgcGFkZGluZyBsZW5ndGguXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IFtjaGFycz0nICddIFRoZSBzdHJpbmcgdXNlZCBhcyBwYWRkaW5nLlxuICAgICAqIEByZXR1cm5zIHtzdHJpbmd9IFJldHVybnMgdGhlIHBhZGRpbmcgZm9yIGBzdHJpbmdgLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGNyZWF0ZVBhZGRpbmcobGVuZ3RoLCBjaGFycykge1xuICAgICAgY2hhcnMgPSBjaGFycyA9PT0gdW5kZWZpbmVkID8gJyAnIDogYmFzZVRvU3RyaW5nKGNoYXJzKTtcblxuICAgICAgdmFyIGNoYXJzTGVuZ3RoID0gY2hhcnMubGVuZ3RoO1xuICAgICAgaWYgKGNoYXJzTGVuZ3RoIDwgMikge1xuICAgICAgICByZXR1cm4gY2hhcnNMZW5ndGggPyBiYXNlUmVwZWF0KGNoYXJzLCBsZW5ndGgpIDogY2hhcnM7XG4gICAgICB9XG4gICAgICB2YXIgcmVzdWx0ID0gYmFzZVJlcGVhdChjaGFycywgbmF0aXZlQ2VpbChsZW5ndGggLyBzdHJpbmdTaXplKGNoYXJzKSkpO1xuICAgICAgcmV0dXJuIGhhc1VuaWNvZGUoY2hhcnMpXG4gICAgICAgID8gY2FzdFNsaWNlKHN0cmluZ1RvQXJyYXkocmVzdWx0KSwgMCwgbGVuZ3RoKS5qb2luKCcnKVxuICAgICAgICA6IHJlc3VsdC5zbGljZSgwLCBsZW5ndGgpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBmdW5jdGlvbiB0aGF0IHdyYXBzIGBmdW5jYCB0byBpbnZva2UgaXQgd2l0aCB0aGUgYHRoaXNgIGJpbmRpbmdcbiAgICAgKiBvZiBgdGhpc0FyZ2AgYW5kIGBwYXJ0aWFsc2AgcHJlcGVuZGVkIHRvIHRoZSBhcmd1bWVudHMgaXQgcmVjZWl2ZXMuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IGZ1bmMgVGhlIGZ1bmN0aW9uIHRvIHdyYXAuXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IGJpdG1hc2sgVGhlIGJpdG1hc2sgZmxhZ3MuIFNlZSBgY3JlYXRlV3JhcGAgZm9yIG1vcmUgZGV0YWlscy5cbiAgICAgKiBAcGFyYW0geyp9IHRoaXNBcmcgVGhlIGB0aGlzYCBiaW5kaW5nIG9mIGBmdW5jYC5cbiAgICAgKiBAcGFyYW0ge0FycmF5fSBwYXJ0aWFscyBUaGUgYXJndW1lbnRzIHRvIHByZXBlbmQgdG8gdGhvc2UgcHJvdmlkZWQgdG9cbiAgICAgKiAgdGhlIG5ldyBmdW5jdGlvbi5cbiAgICAgKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyB3cmFwcGVkIGZ1bmN0aW9uLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGNyZWF0ZVBhcnRpYWwoZnVuYywgYml0bWFzaywgdGhpc0FyZywgcGFydGlhbHMpIHtcbiAgICAgIHZhciBpc0JpbmQgPSBiaXRtYXNrICYgV1JBUF9CSU5EX0ZMQUcsXG4gICAgICAgICAgQ3RvciA9IGNyZWF0ZUN0b3IoZnVuYyk7XG5cbiAgICAgIGZ1bmN0aW9uIHdyYXBwZXIoKSB7XG4gICAgICAgIHZhciBhcmdzSW5kZXggPSAtMSxcbiAgICAgICAgICAgIGFyZ3NMZW5ndGggPSBhcmd1bWVudHMubGVuZ3RoLFxuICAgICAgICAgICAgbGVmdEluZGV4ID0gLTEsXG4gICAgICAgICAgICBsZWZ0TGVuZ3RoID0gcGFydGlhbHMubGVuZ3RoLFxuICAgICAgICAgICAgYXJncyA9IEFycmF5KGxlZnRMZW5ndGggKyBhcmdzTGVuZ3RoKSxcbiAgICAgICAgICAgIGZuID0gKHRoaXMgJiYgdGhpcyAhPT0gcm9vdCAmJiB0aGlzIGluc3RhbmNlb2Ygd3JhcHBlcikgPyBDdG9yIDogZnVuYztcblxuICAgICAgICB3aGlsZSAoKytsZWZ0SW5kZXggPCBsZWZ0TGVuZ3RoKSB7XG4gICAgICAgICAgYXJnc1tsZWZ0SW5kZXhdID0gcGFydGlhbHNbbGVmdEluZGV4XTtcbiAgICAgICAgfVxuICAgICAgICB3aGlsZSAoYXJnc0xlbmd0aC0tKSB7XG4gICAgICAgICAgYXJnc1tsZWZ0SW5kZXgrK10gPSBhcmd1bWVudHNbKythcmdzSW5kZXhdO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBhcHBseShmbiwgaXNCaW5kID8gdGhpc0FyZyA6IHRoaXMsIGFyZ3MpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHdyYXBwZXI7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIGBfLnJhbmdlYCBvciBgXy5yYW5nZVJpZ2h0YCBmdW5jdGlvbi5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtib29sZWFufSBbZnJvbVJpZ2h0XSBTcGVjaWZ5IGl0ZXJhdGluZyBmcm9tIHJpZ2h0IHRvIGxlZnQuXG4gICAgICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBuZXcgcmFuZ2UgZnVuY3Rpb24uXG4gICAgICovXG4gICAgZnVuY3Rpb24gY3JlYXRlUmFuZ2UoZnJvbVJpZ2h0KSB7XG4gICAgICByZXR1cm4gZnVuY3Rpb24oc3RhcnQsIGVuZCwgc3RlcCkge1xuICAgICAgICBpZiAoc3RlcCAmJiB0eXBlb2Ygc3RlcCAhPSAnbnVtYmVyJyAmJiBpc0l0ZXJhdGVlQ2FsbChzdGFydCwgZW5kLCBzdGVwKSkge1xuICAgICAgICAgIGVuZCA9IHN0ZXAgPSB1bmRlZmluZWQ7XG4gICAgICAgIH1cbiAgICAgICAgLy8gRW5zdXJlIHRoZSBzaWduIG9mIGAtMGAgaXMgcHJlc2VydmVkLlxuICAgICAgICBzdGFydCA9IHRvRmluaXRlKHN0YXJ0KTtcbiAgICAgICAgaWYgKGVuZCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgZW5kID0gc3RhcnQ7XG4gICAgICAgICAgc3RhcnQgPSAwO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGVuZCA9IHRvRmluaXRlKGVuZCk7XG4gICAgICAgIH1cbiAgICAgICAgc3RlcCA9IHN0ZXAgPT09IHVuZGVmaW5lZCA/IChzdGFydCA8IGVuZCA/IDEgOiAtMSkgOiB0b0Zpbml0ZShzdGVwKTtcbiAgICAgICAgcmV0dXJuIGJhc2VSYW5nZShzdGFydCwgZW5kLCBzdGVwLCBmcm9tUmlnaHQpO1xuICAgICAgfTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgZnVuY3Rpb24gdGhhdCBwZXJmb3JtcyBhIHJlbGF0aW9uYWwgb3BlcmF0aW9uIG9uIHR3byB2YWx1ZXMuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IG9wZXJhdG9yIFRoZSBmdW5jdGlvbiB0byBwZXJmb3JtIHRoZSBvcGVyYXRpb24uXG4gICAgICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBuZXcgcmVsYXRpb25hbCBvcGVyYXRpb24gZnVuY3Rpb24uXG4gICAgICovXG4gICAgZnVuY3Rpb24gY3JlYXRlUmVsYXRpb25hbE9wZXJhdGlvbihvcGVyYXRvcikge1xuICAgICAgcmV0dXJuIGZ1bmN0aW9uKHZhbHVlLCBvdGhlcikge1xuICAgICAgICBpZiAoISh0eXBlb2YgdmFsdWUgPT0gJ3N0cmluZycgJiYgdHlwZW9mIG90aGVyID09ICdzdHJpbmcnKSkge1xuICAgICAgICAgIHZhbHVlID0gdG9OdW1iZXIodmFsdWUpO1xuICAgICAgICAgIG90aGVyID0gdG9OdW1iZXIob3RoZXIpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBvcGVyYXRvcih2YWx1ZSwgb3RoZXIpO1xuICAgICAgfTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgZnVuY3Rpb24gdGhhdCB3cmFwcyBgZnVuY2AgdG8gY29udGludWUgY3VycnlpbmcuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IGZ1bmMgVGhlIGZ1bmN0aW9uIHRvIHdyYXAuXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IGJpdG1hc2sgVGhlIGJpdG1hc2sgZmxhZ3MuIFNlZSBgY3JlYXRlV3JhcGAgZm9yIG1vcmUgZGV0YWlscy5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSB3cmFwRnVuYyBUaGUgZnVuY3Rpb24gdG8gY3JlYXRlIHRoZSBgZnVuY2Agd3JhcHBlci5cbiAgICAgKiBAcGFyYW0geyp9IHBsYWNlaG9sZGVyIFRoZSBwbGFjZWhvbGRlciB2YWx1ZS5cbiAgICAgKiBAcGFyYW0geyp9IFt0aGlzQXJnXSBUaGUgYHRoaXNgIGJpbmRpbmcgb2YgYGZ1bmNgLlxuICAgICAqIEBwYXJhbSB7QXJyYXl9IFtwYXJ0aWFsc10gVGhlIGFyZ3VtZW50cyB0byBwcmVwZW5kIHRvIHRob3NlIHByb3ZpZGVkIHRvXG4gICAgICogIHRoZSBuZXcgZnVuY3Rpb24uXG4gICAgICogQHBhcmFtIHtBcnJheX0gW2hvbGRlcnNdIFRoZSBgcGFydGlhbHNgIHBsYWNlaG9sZGVyIGluZGV4ZXMuXG4gICAgICogQHBhcmFtIHtBcnJheX0gW2FyZ1Bvc10gVGhlIGFyZ3VtZW50IHBvc2l0aW9ucyBvZiB0aGUgbmV3IGZ1bmN0aW9uLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbYXJ5XSBUaGUgYXJpdHkgY2FwIG9mIGBmdW5jYC5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gW2FyaXR5XSBUaGUgYXJpdHkgb2YgYGZ1bmNgLlxuICAgICAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyB0aGUgbmV3IHdyYXBwZWQgZnVuY3Rpb24uXG4gICAgICovXG4gICAgZnVuY3Rpb24gY3JlYXRlUmVjdXJyeShmdW5jLCBiaXRtYXNrLCB3cmFwRnVuYywgcGxhY2Vob2xkZXIsIHRoaXNBcmcsIHBhcnRpYWxzLCBob2xkZXJzLCBhcmdQb3MsIGFyeSwgYXJpdHkpIHtcbiAgICAgIHZhciBpc0N1cnJ5ID0gYml0bWFzayAmIFdSQVBfQ1VSUllfRkxBRyxcbiAgICAgICAgICBuZXdIb2xkZXJzID0gaXNDdXJyeSA/IGhvbGRlcnMgOiB1bmRlZmluZWQsXG4gICAgICAgICAgbmV3SG9sZGVyc1JpZ2h0ID0gaXNDdXJyeSA/IHVuZGVmaW5lZCA6IGhvbGRlcnMsXG4gICAgICAgICAgbmV3UGFydGlhbHMgPSBpc0N1cnJ5ID8gcGFydGlhbHMgOiB1bmRlZmluZWQsXG4gICAgICAgICAgbmV3UGFydGlhbHNSaWdodCA9IGlzQ3VycnkgPyB1bmRlZmluZWQgOiBwYXJ0aWFscztcblxuICAgICAgYml0bWFzayB8PSAoaXNDdXJyeSA/IFdSQVBfUEFSVElBTF9GTEFHIDogV1JBUF9QQVJUSUFMX1JJR0hUX0ZMQUcpO1xuICAgICAgYml0bWFzayAmPSB+KGlzQ3VycnkgPyBXUkFQX1BBUlRJQUxfUklHSFRfRkxBRyA6IFdSQVBfUEFSVElBTF9GTEFHKTtcblxuICAgICAgaWYgKCEoYml0bWFzayAmIFdSQVBfQ1VSUllfQk9VTkRfRkxBRykpIHtcbiAgICAgICAgYml0bWFzayAmPSB+KFdSQVBfQklORF9GTEFHIHwgV1JBUF9CSU5EX0tFWV9GTEFHKTtcbiAgICAgIH1cbiAgICAgIHZhciBuZXdEYXRhID0gW1xuICAgICAgICBmdW5jLCBiaXRtYXNrLCB0aGlzQXJnLCBuZXdQYXJ0aWFscywgbmV3SG9sZGVycywgbmV3UGFydGlhbHNSaWdodCxcbiAgICAgICAgbmV3SG9sZGVyc1JpZ2h0LCBhcmdQb3MsIGFyeSwgYXJpdHlcbiAgICAgIF07XG5cbiAgICAgIHZhciByZXN1bHQgPSB3cmFwRnVuYy5hcHBseSh1bmRlZmluZWQsIG5ld0RhdGEpO1xuICAgICAgaWYgKGlzTGF6aWFibGUoZnVuYykpIHtcbiAgICAgICAgc2V0RGF0YShyZXN1bHQsIG5ld0RhdGEpO1xuICAgICAgfVxuICAgICAgcmVzdWx0LnBsYWNlaG9sZGVyID0gcGxhY2Vob2xkZXI7XG4gICAgICByZXR1cm4gc2V0V3JhcFRvU3RyaW5nKHJlc3VsdCwgZnVuYywgYml0bWFzayk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIGZ1bmN0aW9uIGxpa2UgYF8ucm91bmRgLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gbWV0aG9kTmFtZSBUaGUgbmFtZSBvZiB0aGUgYE1hdGhgIG1ldGhvZCB0byB1c2Ugd2hlbiByb3VuZGluZy5cbiAgICAgKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyByb3VuZCBmdW5jdGlvbi5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBjcmVhdGVSb3VuZChtZXRob2ROYW1lKSB7XG4gICAgICB2YXIgZnVuYyA9IE1hdGhbbWV0aG9kTmFtZV07XG4gICAgICByZXR1cm4gZnVuY3Rpb24obnVtYmVyLCBwcmVjaXNpb24pIHtcbiAgICAgICAgbnVtYmVyID0gdG9OdW1iZXIobnVtYmVyKTtcbiAgICAgICAgcHJlY2lzaW9uID0gcHJlY2lzaW9uID09IG51bGwgPyAwIDogbmF0aXZlTWluKHRvSW50ZWdlcihwcmVjaXNpb24pLCAyOTIpO1xuICAgICAgICBpZiAocHJlY2lzaW9uKSB7XG4gICAgICAgICAgLy8gU2hpZnQgd2l0aCBleHBvbmVudGlhbCBub3RhdGlvbiB0byBhdm9pZCBmbG9hdGluZy1wb2ludCBpc3N1ZXMuXG4gICAgICAgICAgLy8gU2VlIFtNRE5dKGh0dHBzOi8vbWRuLmlvL3JvdW5kI0V4YW1wbGVzKSBmb3IgbW9yZSBkZXRhaWxzLlxuICAgICAgICAgIHZhciBwYWlyID0gKHRvU3RyaW5nKG51bWJlcikgKyAnZScpLnNwbGl0KCdlJyksXG4gICAgICAgICAgICAgIHZhbHVlID0gZnVuYyhwYWlyWzBdICsgJ2UnICsgKCtwYWlyWzFdICsgcHJlY2lzaW9uKSk7XG5cbiAgICAgICAgICBwYWlyID0gKHRvU3RyaW5nKHZhbHVlKSArICdlJykuc3BsaXQoJ2UnKTtcbiAgICAgICAgICByZXR1cm4gKyhwYWlyWzBdICsgJ2UnICsgKCtwYWlyWzFdIC0gcHJlY2lzaW9uKSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGZ1bmMobnVtYmVyKTtcbiAgICAgIH07XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIHNldCBvYmplY3Qgb2YgYHZhbHVlc2AuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7QXJyYXl9IHZhbHVlcyBUaGUgdmFsdWVzIHRvIGFkZCB0byB0aGUgc2V0LlxuICAgICAqIEByZXR1cm5zIHtPYmplY3R9IFJldHVybnMgdGhlIG5ldyBzZXQuXG4gICAgICovXG4gICAgdmFyIGNyZWF0ZVNldCA9ICEoU2V0ICYmICgxIC8gc2V0VG9BcnJheShuZXcgU2V0KFssLTBdKSlbMV0pID09IElORklOSVRZKSA/IG5vb3AgOiBmdW5jdGlvbih2YWx1ZXMpIHtcbiAgICAgIHJldHVybiBuZXcgU2V0KHZhbHVlcyk7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBgXy50b1BhaXJzYCBvciBgXy50b1BhaXJzSW5gIGZ1bmN0aW9uLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBrZXlzRnVuYyBUaGUgZnVuY3Rpb24gdG8gZ2V0IHRoZSBrZXlzIG9mIGEgZ2l2ZW4gb2JqZWN0LlxuICAgICAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyB0aGUgbmV3IHBhaXJzIGZ1bmN0aW9uLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGNyZWF0ZVRvUGFpcnMoa2V5c0Z1bmMpIHtcbiAgICAgIHJldHVybiBmdW5jdGlvbihvYmplY3QpIHtcbiAgICAgICAgdmFyIHRhZyA9IGdldFRhZyhvYmplY3QpO1xuICAgICAgICBpZiAodGFnID09IG1hcFRhZykge1xuICAgICAgICAgIHJldHVybiBtYXBUb0FycmF5KG9iamVjdCk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRhZyA9PSBzZXRUYWcpIHtcbiAgICAgICAgICByZXR1cm4gc2V0VG9QYWlycyhvYmplY3QpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBiYXNlVG9QYWlycyhvYmplY3QsIGtleXNGdW5jKG9iamVjdCkpO1xuICAgICAgfTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgZnVuY3Rpb24gdGhhdCBlaXRoZXIgY3VycmllcyBvciBpbnZva2VzIGBmdW5jYCB3aXRoIG9wdGlvbmFsXG4gICAgICogYHRoaXNgIGJpbmRpbmcgYW5kIHBhcnRpYWxseSBhcHBsaWVkIGFyZ3VtZW50cy5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbnxzdHJpbmd9IGZ1bmMgVGhlIGZ1bmN0aW9uIG9yIG1ldGhvZCBuYW1lIHRvIHdyYXAuXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IGJpdG1hc2sgVGhlIGJpdG1hc2sgZmxhZ3MuXG4gICAgICogICAgMSAtIGBfLmJpbmRgXG4gICAgICogICAgMiAtIGBfLmJpbmRLZXlgXG4gICAgICogICAgNCAtIGBfLmN1cnJ5YCBvciBgXy5jdXJyeVJpZ2h0YCBvZiBhIGJvdW5kIGZ1bmN0aW9uXG4gICAgICogICAgOCAtIGBfLmN1cnJ5YFxuICAgICAqICAgMTYgLSBgXy5jdXJyeVJpZ2h0YFxuICAgICAqICAgMzIgLSBgXy5wYXJ0aWFsYFxuICAgICAqICAgNjQgLSBgXy5wYXJ0aWFsUmlnaHRgXG4gICAgICogIDEyOCAtIGBfLnJlYXJnYFxuICAgICAqICAyNTYgLSBgXy5hcnlgXG4gICAgICogIDUxMiAtIGBfLmZsaXBgXG4gICAgICogQHBhcmFtIHsqfSBbdGhpc0FyZ10gVGhlIGB0aGlzYCBiaW5kaW5nIG9mIGBmdW5jYC5cbiAgICAgKiBAcGFyYW0ge0FycmF5fSBbcGFydGlhbHNdIFRoZSBhcmd1bWVudHMgdG8gYmUgcGFydGlhbGx5IGFwcGxpZWQuXG4gICAgICogQHBhcmFtIHtBcnJheX0gW2hvbGRlcnNdIFRoZSBgcGFydGlhbHNgIHBsYWNlaG9sZGVyIGluZGV4ZXMuXG4gICAgICogQHBhcmFtIHtBcnJheX0gW2FyZ1Bvc10gVGhlIGFyZ3VtZW50IHBvc2l0aW9ucyBvZiB0aGUgbmV3IGZ1bmN0aW9uLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbYXJ5XSBUaGUgYXJpdHkgY2FwIG9mIGBmdW5jYC5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gW2FyaXR5XSBUaGUgYXJpdHkgb2YgYGZ1bmNgLlxuICAgICAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyB0aGUgbmV3IHdyYXBwZWQgZnVuY3Rpb24uXG4gICAgICovXG4gICAgZnVuY3Rpb24gY3JlYXRlV3JhcChmdW5jLCBiaXRtYXNrLCB0aGlzQXJnLCBwYXJ0aWFscywgaG9sZGVycywgYXJnUG9zLCBhcnksIGFyaXR5KSB7XG4gICAgICB2YXIgaXNCaW5kS2V5ID0gYml0bWFzayAmIFdSQVBfQklORF9LRVlfRkxBRztcbiAgICAgIGlmICghaXNCaW5kS2V5ICYmIHR5cGVvZiBmdW5jICE9ICdmdW5jdGlvbicpIHtcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihGVU5DX0VSUk9SX1RFWFQpO1xuICAgICAgfVxuICAgICAgdmFyIGxlbmd0aCA9IHBhcnRpYWxzID8gcGFydGlhbHMubGVuZ3RoIDogMDtcbiAgICAgIGlmICghbGVuZ3RoKSB7XG4gICAgICAgIGJpdG1hc2sgJj0gfihXUkFQX1BBUlRJQUxfRkxBRyB8IFdSQVBfUEFSVElBTF9SSUdIVF9GTEFHKTtcbiAgICAgICAgcGFydGlhbHMgPSBob2xkZXJzID0gdW5kZWZpbmVkO1xuICAgICAgfVxuICAgICAgYXJ5ID0gYXJ5ID09PSB1bmRlZmluZWQgPyBhcnkgOiBuYXRpdmVNYXgodG9JbnRlZ2VyKGFyeSksIDApO1xuICAgICAgYXJpdHkgPSBhcml0eSA9PT0gdW5kZWZpbmVkID8gYXJpdHkgOiB0b0ludGVnZXIoYXJpdHkpO1xuICAgICAgbGVuZ3RoIC09IGhvbGRlcnMgPyBob2xkZXJzLmxlbmd0aCA6IDA7XG5cbiAgICAgIGlmIChiaXRtYXNrICYgV1JBUF9QQVJUSUFMX1JJR0hUX0ZMQUcpIHtcbiAgICAgICAgdmFyIHBhcnRpYWxzUmlnaHQgPSBwYXJ0aWFscyxcbiAgICAgICAgICAgIGhvbGRlcnNSaWdodCA9IGhvbGRlcnM7XG5cbiAgICAgICAgcGFydGlhbHMgPSBob2xkZXJzID0gdW5kZWZpbmVkO1xuICAgICAgfVxuICAgICAgdmFyIGRhdGEgPSBpc0JpbmRLZXkgPyB1bmRlZmluZWQgOiBnZXREYXRhKGZ1bmMpO1xuXG4gICAgICB2YXIgbmV3RGF0YSA9IFtcbiAgICAgICAgZnVuYywgYml0bWFzaywgdGhpc0FyZywgcGFydGlhbHMsIGhvbGRlcnMsIHBhcnRpYWxzUmlnaHQsIGhvbGRlcnNSaWdodCxcbiAgICAgICAgYXJnUG9zLCBhcnksIGFyaXR5XG4gICAgICBdO1xuXG4gICAgICBpZiAoZGF0YSkge1xuICAgICAgICBtZXJnZURhdGEobmV3RGF0YSwgZGF0YSk7XG4gICAgICB9XG4gICAgICBmdW5jID0gbmV3RGF0YVswXTtcbiAgICAgIGJpdG1hc2sgPSBuZXdEYXRhWzFdO1xuICAgICAgdGhpc0FyZyA9IG5ld0RhdGFbMl07XG4gICAgICBwYXJ0aWFscyA9IG5ld0RhdGFbM107XG4gICAgICBob2xkZXJzID0gbmV3RGF0YVs0XTtcbiAgICAgIGFyaXR5ID0gbmV3RGF0YVs5XSA9IG5ld0RhdGFbOV0gPT09IHVuZGVmaW5lZFxuICAgICAgICA/IChpc0JpbmRLZXkgPyAwIDogZnVuYy5sZW5ndGgpXG4gICAgICAgIDogbmF0aXZlTWF4KG5ld0RhdGFbOV0gLSBsZW5ndGgsIDApO1xuXG4gICAgICBpZiAoIWFyaXR5ICYmIGJpdG1hc2sgJiAoV1JBUF9DVVJSWV9GTEFHIHwgV1JBUF9DVVJSWV9SSUdIVF9GTEFHKSkge1xuICAgICAgICBiaXRtYXNrICY9IH4oV1JBUF9DVVJSWV9GTEFHIHwgV1JBUF9DVVJSWV9SSUdIVF9GTEFHKTtcbiAgICAgIH1cbiAgICAgIGlmICghYml0bWFzayB8fCBiaXRtYXNrID09IFdSQVBfQklORF9GTEFHKSB7XG4gICAgICAgIHZhciByZXN1bHQgPSBjcmVhdGVCaW5kKGZ1bmMsIGJpdG1hc2ssIHRoaXNBcmcpO1xuICAgICAgfSBlbHNlIGlmIChiaXRtYXNrID09IFdSQVBfQ1VSUllfRkxBRyB8fCBiaXRtYXNrID09IFdSQVBfQ1VSUllfUklHSFRfRkxBRykge1xuICAgICAgICByZXN1bHQgPSBjcmVhdGVDdXJyeShmdW5jLCBiaXRtYXNrLCBhcml0eSk7XG4gICAgICB9IGVsc2UgaWYgKChiaXRtYXNrID09IFdSQVBfUEFSVElBTF9GTEFHIHx8IGJpdG1hc2sgPT0gKFdSQVBfQklORF9GTEFHIHwgV1JBUF9QQVJUSUFMX0ZMQUcpKSAmJiAhaG9sZGVycy5sZW5ndGgpIHtcbiAgICAgICAgcmVzdWx0ID0gY3JlYXRlUGFydGlhbChmdW5jLCBiaXRtYXNrLCB0aGlzQXJnLCBwYXJ0aWFscyk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZXN1bHQgPSBjcmVhdGVIeWJyaWQuYXBwbHkodW5kZWZpbmVkLCBuZXdEYXRhKTtcbiAgICAgIH1cbiAgICAgIHZhciBzZXR0ZXIgPSBkYXRhID8gYmFzZVNldERhdGEgOiBzZXREYXRhO1xuICAgICAgcmV0dXJuIHNldFdyYXBUb1N0cmluZyhzZXR0ZXIocmVzdWx0LCBuZXdEYXRhKSwgZnVuYywgYml0bWFzayk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVXNlZCBieSBgXy5kZWZhdWx0c2AgdG8gY3VzdG9taXplIGl0cyBgXy5hc3NpZ25JbmAgdXNlIHRvIGFzc2lnbiBwcm9wZXJ0aWVzXG4gICAgICogb2Ygc291cmNlIG9iamVjdHMgdG8gdGhlIGRlc3RpbmF0aW9uIG9iamVjdCBmb3IgYWxsIGRlc3RpbmF0aW9uIHByb3BlcnRpZXNcbiAgICAgKiB0aGF0IHJlc29sdmUgdG8gYHVuZGVmaW5lZGAuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7Kn0gb2JqVmFsdWUgVGhlIGRlc3RpbmF0aW9uIHZhbHVlLlxuICAgICAqIEBwYXJhbSB7Kn0gc3JjVmFsdWUgVGhlIHNvdXJjZSB2YWx1ZS5cbiAgICAgKiBAcGFyYW0ge3N0cmluZ30ga2V5IFRoZSBrZXkgb2YgdGhlIHByb3BlcnR5IHRvIGFzc2lnbi5cbiAgICAgKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBwYXJlbnQgb2JqZWN0IG9mIGBvYmpWYWx1ZWAuXG4gICAgICogQHJldHVybnMgeyp9IFJldHVybnMgdGhlIHZhbHVlIHRvIGFzc2lnbi5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBjdXN0b21EZWZhdWx0c0Fzc2lnbkluKG9ialZhbHVlLCBzcmNWYWx1ZSwga2V5LCBvYmplY3QpIHtcbiAgICAgIGlmIChvYmpWYWx1ZSA9PT0gdW5kZWZpbmVkIHx8XG4gICAgICAgICAgKGVxKG9ialZhbHVlLCBvYmplY3RQcm90b1trZXldKSAmJiAhaGFzT3duUHJvcGVydHkuY2FsbChvYmplY3QsIGtleSkpKSB7XG4gICAgICAgIHJldHVybiBzcmNWYWx1ZTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBvYmpWYWx1ZTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBVc2VkIGJ5IGBfLmRlZmF1bHRzRGVlcGAgdG8gY3VzdG9taXplIGl0cyBgXy5tZXJnZWAgdXNlIHRvIG1lcmdlIHNvdXJjZVxuICAgICAqIG9iamVjdHMgaW50byBkZXN0aW5hdGlvbiBvYmplY3RzIHRoYXQgYXJlIHBhc3NlZCB0aHJ1LlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0geyp9IG9ialZhbHVlIFRoZSBkZXN0aW5hdGlvbiB2YWx1ZS5cbiAgICAgKiBAcGFyYW0geyp9IHNyY1ZhbHVlIFRoZSBzb3VyY2UgdmFsdWUuXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IGtleSBUaGUga2V5IG9mIHRoZSBwcm9wZXJ0eSB0byBtZXJnZS5cbiAgICAgKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBwYXJlbnQgb2JqZWN0IG9mIGBvYmpWYWx1ZWAuXG4gICAgICogQHBhcmFtIHtPYmplY3R9IHNvdXJjZSBUaGUgcGFyZW50IG9iamVjdCBvZiBgc3JjVmFsdWVgLlxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBbc3RhY2tdIFRyYWNrcyB0cmF2ZXJzZWQgc291cmNlIHZhbHVlcyBhbmQgdGhlaXIgbWVyZ2VkXG4gICAgICogIGNvdW50ZXJwYXJ0cy5cbiAgICAgKiBAcmV0dXJucyB7Kn0gUmV0dXJucyB0aGUgdmFsdWUgdG8gYXNzaWduLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGN1c3RvbURlZmF1bHRzTWVyZ2Uob2JqVmFsdWUsIHNyY1ZhbHVlLCBrZXksIG9iamVjdCwgc291cmNlLCBzdGFjaykge1xuICAgICAgaWYgKGlzT2JqZWN0KG9ialZhbHVlKSAmJiBpc09iamVjdChzcmNWYWx1ZSkpIHtcbiAgICAgICAgLy8gUmVjdXJzaXZlbHkgbWVyZ2Ugb2JqZWN0cyBhbmQgYXJyYXlzIChzdXNjZXB0aWJsZSB0byBjYWxsIHN0YWNrIGxpbWl0cykuXG4gICAgICAgIHN0YWNrLnNldChzcmNWYWx1ZSwgb2JqVmFsdWUpO1xuICAgICAgICBiYXNlTWVyZ2Uob2JqVmFsdWUsIHNyY1ZhbHVlLCB1bmRlZmluZWQsIGN1c3RvbURlZmF1bHRzTWVyZ2UsIHN0YWNrKTtcbiAgICAgICAgc3RhY2tbJ2RlbGV0ZSddKHNyY1ZhbHVlKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBvYmpWYWx1ZTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBVc2VkIGJ5IGBfLm9taXRgIHRvIGN1c3RvbWl6ZSBpdHMgYF8uY2xvbmVEZWVwYCB1c2UgdG8gb25seSBjbG9uZSBwbGFpblxuICAgICAqIG9iamVjdHMuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGluc3BlY3QuXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IGtleSBUaGUga2V5IG9mIHRoZSBwcm9wZXJ0eSB0byBpbnNwZWN0LlxuICAgICAqIEByZXR1cm5zIHsqfSBSZXR1cm5zIHRoZSB1bmNsb25lZCB2YWx1ZSBvciBgdW5kZWZpbmVkYCB0byBkZWZlciBjbG9uaW5nIHRvIGBfLmNsb25lRGVlcGAuXG4gICAgICovXG4gICAgZnVuY3Rpb24gY3VzdG9tT21pdENsb25lKHZhbHVlKSB7XG4gICAgICByZXR1cm4gaXNQbGFpbk9iamVjdCh2YWx1ZSkgPyB1bmRlZmluZWQgOiB2YWx1ZTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBBIHNwZWNpYWxpemVkIHZlcnNpb24gb2YgYGJhc2VJc0VxdWFsRGVlcGAgZm9yIGFycmF5cyB3aXRoIHN1cHBvcnQgZm9yXG4gICAgICogcGFydGlhbCBkZWVwIGNvbXBhcmlzb25zLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBhcnJheSBUaGUgYXJyYXkgdG8gY29tcGFyZS5cbiAgICAgKiBAcGFyYW0ge0FycmF5fSBvdGhlciBUaGUgb3RoZXIgYXJyYXkgdG8gY29tcGFyZS5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gYml0bWFzayBUaGUgYml0bWFzayBmbGFncy4gU2VlIGBiYXNlSXNFcXVhbGAgZm9yIG1vcmUgZGV0YWlscy5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBjdXN0b21pemVyIFRoZSBmdW5jdGlvbiB0byBjdXN0b21pemUgY29tcGFyaXNvbnMuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gZXF1YWxGdW5jIFRoZSBmdW5jdGlvbiB0byBkZXRlcm1pbmUgZXF1aXZhbGVudHMgb2YgdmFsdWVzLlxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBzdGFjayBUcmFja3MgdHJhdmVyc2VkIGBhcnJheWAgYW5kIGBvdGhlcmAgb2JqZWN0cy5cbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgdGhlIGFycmF5cyBhcmUgZXF1aXZhbGVudCwgZWxzZSBgZmFsc2VgLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGVxdWFsQXJyYXlzKGFycmF5LCBvdGhlciwgYml0bWFzaywgY3VzdG9taXplciwgZXF1YWxGdW5jLCBzdGFjaykge1xuICAgICAgdmFyIGlzUGFydGlhbCA9IGJpdG1hc2sgJiBDT01QQVJFX1BBUlRJQUxfRkxBRyxcbiAgICAgICAgICBhcnJMZW5ndGggPSBhcnJheS5sZW5ndGgsXG4gICAgICAgICAgb3RoTGVuZ3RoID0gb3RoZXIubGVuZ3RoO1xuXG4gICAgICBpZiAoYXJyTGVuZ3RoICE9IG90aExlbmd0aCAmJiAhKGlzUGFydGlhbCAmJiBvdGhMZW5ndGggPiBhcnJMZW5ndGgpKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cbiAgICAgIC8vIEFzc3VtZSBjeWNsaWMgdmFsdWVzIGFyZSBlcXVhbC5cbiAgICAgIHZhciBzdGFja2VkID0gc3RhY2suZ2V0KGFycmF5KTtcbiAgICAgIGlmIChzdGFja2VkICYmIHN0YWNrLmdldChvdGhlcikpIHtcbiAgICAgICAgcmV0dXJuIHN0YWNrZWQgPT0gb3RoZXI7XG4gICAgICB9XG4gICAgICB2YXIgaW5kZXggPSAtMSxcbiAgICAgICAgICByZXN1bHQgPSB0cnVlLFxuICAgICAgICAgIHNlZW4gPSAoYml0bWFzayAmIENPTVBBUkVfVU5PUkRFUkVEX0ZMQUcpID8gbmV3IFNldENhY2hlIDogdW5kZWZpbmVkO1xuXG4gICAgICBzdGFjay5zZXQoYXJyYXksIG90aGVyKTtcbiAgICAgIHN0YWNrLnNldChvdGhlciwgYXJyYXkpO1xuXG4gICAgICAvLyBJZ25vcmUgbm9uLWluZGV4IHByb3BlcnRpZXMuXG4gICAgICB3aGlsZSAoKytpbmRleCA8IGFyckxlbmd0aCkge1xuICAgICAgICB2YXIgYXJyVmFsdWUgPSBhcnJheVtpbmRleF0sXG4gICAgICAgICAgICBvdGhWYWx1ZSA9IG90aGVyW2luZGV4XTtcblxuICAgICAgICBpZiAoY3VzdG9taXplcikge1xuICAgICAgICAgIHZhciBjb21wYXJlZCA9IGlzUGFydGlhbFxuICAgICAgICAgICAgPyBjdXN0b21pemVyKG90aFZhbHVlLCBhcnJWYWx1ZSwgaW5kZXgsIG90aGVyLCBhcnJheSwgc3RhY2spXG4gICAgICAgICAgICA6IGN1c3RvbWl6ZXIoYXJyVmFsdWUsIG90aFZhbHVlLCBpbmRleCwgYXJyYXksIG90aGVyLCBzdGFjayk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGNvbXBhcmVkICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICBpZiAoY29tcGFyZWQpIHtcbiAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgIH1cbiAgICAgICAgICByZXN1bHQgPSBmYWxzZTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgICAvLyBSZWN1cnNpdmVseSBjb21wYXJlIGFycmF5cyAoc3VzY2VwdGlibGUgdG8gY2FsbCBzdGFjayBsaW1pdHMpLlxuICAgICAgICBpZiAoc2Vlbikge1xuICAgICAgICAgIGlmICghYXJyYXlTb21lKG90aGVyLCBmdW5jdGlvbihvdGhWYWx1ZSwgb3RoSW5kZXgpIHtcbiAgICAgICAgICAgICAgICBpZiAoIWNhY2hlSGFzKHNlZW4sIG90aEluZGV4KSAmJlxuICAgICAgICAgICAgICAgICAgICAoYXJyVmFsdWUgPT09IG90aFZhbHVlIHx8IGVxdWFsRnVuYyhhcnJWYWx1ZSwgb3RoVmFsdWUsIGJpdG1hc2ssIGN1c3RvbWl6ZXIsIHN0YWNrKSkpIHtcbiAgICAgICAgICAgICAgICAgIHJldHVybiBzZWVuLnB1c2gob3RoSW5kZXgpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgfSkpIHtcbiAgICAgICAgICAgIHJlc3VsdCA9IGZhbHNlO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuICAgICAgICB9IGVsc2UgaWYgKCEoXG4gICAgICAgICAgICAgIGFyclZhbHVlID09PSBvdGhWYWx1ZSB8fFxuICAgICAgICAgICAgICAgIGVxdWFsRnVuYyhhcnJWYWx1ZSwgb3RoVmFsdWUsIGJpdG1hc2ssIGN1c3RvbWl6ZXIsIHN0YWNrKVxuICAgICAgICAgICAgKSkge1xuICAgICAgICAgIHJlc3VsdCA9IGZhbHNlO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBzdGFja1snZGVsZXRlJ10oYXJyYXkpO1xuICAgICAgc3RhY2tbJ2RlbGV0ZSddKG90aGVyKTtcbiAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQSBzcGVjaWFsaXplZCB2ZXJzaW9uIG9mIGBiYXNlSXNFcXVhbERlZXBgIGZvciBjb21wYXJpbmcgb2JqZWN0cyBvZlxuICAgICAqIHRoZSBzYW1lIGB0b1N0cmluZ1RhZ2AuXG4gICAgICpcbiAgICAgKiAqKk5vdGU6KiogVGhpcyBmdW5jdGlvbiBvbmx5IHN1cHBvcnRzIGNvbXBhcmluZyB2YWx1ZXMgd2l0aCB0YWdzIG9mXG4gICAgICogYEJvb2xlYW5gLCBgRGF0ZWAsIGBFcnJvcmAsIGBOdW1iZXJgLCBgUmVnRXhwYCwgb3IgYFN0cmluZ2AuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBjb21wYXJlLlxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBvdGhlciBUaGUgb3RoZXIgb2JqZWN0IHRvIGNvbXBhcmUuXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IHRhZyBUaGUgYHRvU3RyaW5nVGFnYCBvZiB0aGUgb2JqZWN0cyB0byBjb21wYXJlLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBiaXRtYXNrIFRoZSBiaXRtYXNrIGZsYWdzLiBTZWUgYGJhc2VJc0VxdWFsYCBmb3IgbW9yZSBkZXRhaWxzLlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IGN1c3RvbWl6ZXIgVGhlIGZ1bmN0aW9uIHRvIGN1c3RvbWl6ZSBjb21wYXJpc29ucy5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBlcXVhbEZ1bmMgVGhlIGZ1bmN0aW9uIHRvIGRldGVybWluZSBlcXVpdmFsZW50cyBvZiB2YWx1ZXMuXG4gICAgICogQHBhcmFtIHtPYmplY3R9IHN0YWNrIFRyYWNrcyB0cmF2ZXJzZWQgYG9iamVjdGAgYW5kIGBvdGhlcmAgb2JqZWN0cy5cbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgdGhlIG9iamVjdHMgYXJlIGVxdWl2YWxlbnQsIGVsc2UgYGZhbHNlYC5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBlcXVhbEJ5VGFnKG9iamVjdCwgb3RoZXIsIHRhZywgYml0bWFzaywgY3VzdG9taXplciwgZXF1YWxGdW5jLCBzdGFjaykge1xuICAgICAgc3dpdGNoICh0YWcpIHtcbiAgICAgICAgY2FzZSBkYXRhVmlld1RhZzpcbiAgICAgICAgICBpZiAoKG9iamVjdC5ieXRlTGVuZ3RoICE9IG90aGVyLmJ5dGVMZW5ndGgpIHx8XG4gICAgICAgICAgICAgIChvYmplY3QuYnl0ZU9mZnNldCAhPSBvdGhlci5ieXRlT2Zmc2V0KSkge1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgIH1cbiAgICAgICAgICBvYmplY3QgPSBvYmplY3QuYnVmZmVyO1xuICAgICAgICAgIG90aGVyID0gb3RoZXIuYnVmZmVyO1xuXG4gICAgICAgIGNhc2UgYXJyYXlCdWZmZXJUYWc6XG4gICAgICAgICAgaWYgKChvYmplY3QuYnl0ZUxlbmd0aCAhPSBvdGhlci5ieXRlTGVuZ3RoKSB8fFxuICAgICAgICAgICAgICAhZXF1YWxGdW5jKG5ldyBVaW50OEFycmF5KG9iamVjdCksIG5ldyBVaW50OEFycmF5KG90aGVyKSkpIHtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICB9XG4gICAgICAgICAgcmV0dXJuIHRydWU7XG5cbiAgICAgICAgY2FzZSBib29sVGFnOlxuICAgICAgICBjYXNlIGRhdGVUYWc6XG4gICAgICAgIGNhc2UgbnVtYmVyVGFnOlxuICAgICAgICAgIC8vIENvZXJjZSBib29sZWFucyB0byBgMWAgb3IgYDBgIGFuZCBkYXRlcyB0byBtaWxsaXNlY29uZHMuXG4gICAgICAgICAgLy8gSW52YWxpZCBkYXRlcyBhcmUgY29lcmNlZCB0byBgTmFOYC5cbiAgICAgICAgICByZXR1cm4gZXEoK29iamVjdCwgK290aGVyKTtcblxuICAgICAgICBjYXNlIGVycm9yVGFnOlxuICAgICAgICAgIHJldHVybiBvYmplY3QubmFtZSA9PSBvdGhlci5uYW1lICYmIG9iamVjdC5tZXNzYWdlID09IG90aGVyLm1lc3NhZ2U7XG5cbiAgICAgICAgY2FzZSByZWdleHBUYWc6XG4gICAgICAgIGNhc2Ugc3RyaW5nVGFnOlxuICAgICAgICAgIC8vIENvZXJjZSByZWdleGVzIHRvIHN0cmluZ3MgYW5kIHRyZWF0IHN0cmluZ3MsIHByaW1pdGl2ZXMgYW5kIG9iamVjdHMsXG4gICAgICAgICAgLy8gYXMgZXF1YWwuIFNlZSBodHRwOi8vd3d3LmVjbWEtaW50ZXJuYXRpb25hbC5vcmcvZWNtYS0yNjIvNy4wLyNzZWMtcmVnZXhwLnByb3RvdHlwZS50b3N0cmluZ1xuICAgICAgICAgIC8vIGZvciBtb3JlIGRldGFpbHMuXG4gICAgICAgICAgcmV0dXJuIG9iamVjdCA9PSAob3RoZXIgKyAnJyk7XG5cbiAgICAgICAgY2FzZSBtYXBUYWc6XG4gICAgICAgICAgdmFyIGNvbnZlcnQgPSBtYXBUb0FycmF5O1xuXG4gICAgICAgIGNhc2Ugc2V0VGFnOlxuICAgICAgICAgIHZhciBpc1BhcnRpYWwgPSBiaXRtYXNrICYgQ09NUEFSRV9QQVJUSUFMX0ZMQUc7XG4gICAgICAgICAgY29udmVydCB8fCAoY29udmVydCA9IHNldFRvQXJyYXkpO1xuXG4gICAgICAgICAgaWYgKG9iamVjdC5zaXplICE9IG90aGVyLnNpemUgJiYgIWlzUGFydGlhbCkge1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgIH1cbiAgICAgICAgICAvLyBBc3N1bWUgY3ljbGljIHZhbHVlcyBhcmUgZXF1YWwuXG4gICAgICAgICAgdmFyIHN0YWNrZWQgPSBzdGFjay5nZXQob2JqZWN0KTtcbiAgICAgICAgICBpZiAoc3RhY2tlZCkge1xuICAgICAgICAgICAgcmV0dXJuIHN0YWNrZWQgPT0gb3RoZXI7XG4gICAgICAgICAgfVxuICAgICAgICAgIGJpdG1hc2sgfD0gQ09NUEFSRV9VTk9SREVSRURfRkxBRztcblxuICAgICAgICAgIC8vIFJlY3Vyc2l2ZWx5IGNvbXBhcmUgb2JqZWN0cyAoc3VzY2VwdGlibGUgdG8gY2FsbCBzdGFjayBsaW1pdHMpLlxuICAgICAgICAgIHN0YWNrLnNldChvYmplY3QsIG90aGVyKTtcbiAgICAgICAgICB2YXIgcmVzdWx0ID0gZXF1YWxBcnJheXMoY29udmVydChvYmplY3QpLCBjb252ZXJ0KG90aGVyKSwgYml0bWFzaywgY3VzdG9taXplciwgZXF1YWxGdW5jLCBzdGFjayk7XG4gICAgICAgICAgc3RhY2tbJ2RlbGV0ZSddKG9iamVjdCk7XG4gICAgICAgICAgcmV0dXJuIHJlc3VsdDtcblxuICAgICAgICBjYXNlIHN5bWJvbFRhZzpcbiAgICAgICAgICBpZiAoc3ltYm9sVmFsdWVPZikge1xuICAgICAgICAgICAgcmV0dXJuIHN5bWJvbFZhbHVlT2YuY2FsbChvYmplY3QpID09IHN5bWJvbFZhbHVlT2YuY2FsbChvdGhlcik7XG4gICAgICAgICAgfVxuICAgICAgfVxuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEEgc3BlY2lhbGl6ZWQgdmVyc2lvbiBvZiBgYmFzZUlzRXF1YWxEZWVwYCBmb3Igb2JqZWN0cyB3aXRoIHN1cHBvcnQgZm9yXG4gICAgICogcGFydGlhbCBkZWVwIGNvbXBhcmlzb25zLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gY29tcGFyZS5cbiAgICAgKiBAcGFyYW0ge09iamVjdH0gb3RoZXIgVGhlIG90aGVyIG9iamVjdCB0byBjb21wYXJlLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBiaXRtYXNrIFRoZSBiaXRtYXNrIGZsYWdzLiBTZWUgYGJhc2VJc0VxdWFsYCBmb3IgbW9yZSBkZXRhaWxzLlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IGN1c3RvbWl6ZXIgVGhlIGZ1bmN0aW9uIHRvIGN1c3RvbWl6ZSBjb21wYXJpc29ucy5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBlcXVhbEZ1bmMgVGhlIGZ1bmN0aW9uIHRvIGRldGVybWluZSBlcXVpdmFsZW50cyBvZiB2YWx1ZXMuXG4gICAgICogQHBhcmFtIHtPYmplY3R9IHN0YWNrIFRyYWNrcyB0cmF2ZXJzZWQgYG9iamVjdGAgYW5kIGBvdGhlcmAgb2JqZWN0cy5cbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgdGhlIG9iamVjdHMgYXJlIGVxdWl2YWxlbnQsIGVsc2UgYGZhbHNlYC5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBlcXVhbE9iamVjdHMob2JqZWN0LCBvdGhlciwgYml0bWFzaywgY3VzdG9taXplciwgZXF1YWxGdW5jLCBzdGFjaykge1xuICAgICAgdmFyIGlzUGFydGlhbCA9IGJpdG1hc2sgJiBDT01QQVJFX1BBUlRJQUxfRkxBRyxcbiAgICAgICAgICBvYmpQcm9wcyA9IGdldEFsbEtleXMob2JqZWN0KSxcbiAgICAgICAgICBvYmpMZW5ndGggPSBvYmpQcm9wcy5sZW5ndGgsXG4gICAgICAgICAgb3RoUHJvcHMgPSBnZXRBbGxLZXlzKG90aGVyKSxcbiAgICAgICAgICBvdGhMZW5ndGggPSBvdGhQcm9wcy5sZW5ndGg7XG5cbiAgICAgIGlmIChvYmpMZW5ndGggIT0gb3RoTGVuZ3RoICYmICFpc1BhcnRpYWwpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuICAgICAgdmFyIGluZGV4ID0gb2JqTGVuZ3RoO1xuICAgICAgd2hpbGUgKGluZGV4LS0pIHtcbiAgICAgICAgdmFyIGtleSA9IG9ialByb3BzW2luZGV4XTtcbiAgICAgICAgaWYgKCEoaXNQYXJ0aWFsID8ga2V5IGluIG90aGVyIDogaGFzT3duUHJvcGVydHkuY2FsbChvdGhlciwga2V5KSkpIHtcbiAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIC8vIEFzc3VtZSBjeWNsaWMgdmFsdWVzIGFyZSBlcXVhbC5cbiAgICAgIHZhciBzdGFja2VkID0gc3RhY2suZ2V0KG9iamVjdCk7XG4gICAgICBpZiAoc3RhY2tlZCAmJiBzdGFjay5nZXQob3RoZXIpKSB7XG4gICAgICAgIHJldHVybiBzdGFja2VkID09IG90aGVyO1xuICAgICAgfVxuICAgICAgdmFyIHJlc3VsdCA9IHRydWU7XG4gICAgICBzdGFjay5zZXQob2JqZWN0LCBvdGhlcik7XG4gICAgICBzdGFjay5zZXQob3RoZXIsIG9iamVjdCk7XG5cbiAgICAgIHZhciBza2lwQ3RvciA9IGlzUGFydGlhbDtcbiAgICAgIHdoaWxlICgrK2luZGV4IDwgb2JqTGVuZ3RoKSB7XG4gICAgICAgIGtleSA9IG9ialByb3BzW2luZGV4XTtcbiAgICAgICAgdmFyIG9ialZhbHVlID0gb2JqZWN0W2tleV0sXG4gICAgICAgICAgICBvdGhWYWx1ZSA9IG90aGVyW2tleV07XG5cbiAgICAgICAgaWYgKGN1c3RvbWl6ZXIpIHtcbiAgICAgICAgICB2YXIgY29tcGFyZWQgPSBpc1BhcnRpYWxcbiAgICAgICAgICAgID8gY3VzdG9taXplcihvdGhWYWx1ZSwgb2JqVmFsdWUsIGtleSwgb3RoZXIsIG9iamVjdCwgc3RhY2spXG4gICAgICAgICAgICA6IGN1c3RvbWl6ZXIob2JqVmFsdWUsIG90aFZhbHVlLCBrZXksIG9iamVjdCwgb3RoZXIsIHN0YWNrKTtcbiAgICAgICAgfVxuICAgICAgICAvLyBSZWN1cnNpdmVseSBjb21wYXJlIG9iamVjdHMgKHN1c2NlcHRpYmxlIHRvIGNhbGwgc3RhY2sgbGltaXRzKS5cbiAgICAgICAgaWYgKCEoY29tcGFyZWQgPT09IHVuZGVmaW5lZFxuICAgICAgICAgICAgICA/IChvYmpWYWx1ZSA9PT0gb3RoVmFsdWUgfHwgZXF1YWxGdW5jKG9ialZhbHVlLCBvdGhWYWx1ZSwgYml0bWFzaywgY3VzdG9taXplciwgc3RhY2spKVxuICAgICAgICAgICAgICA6IGNvbXBhcmVkXG4gICAgICAgICAgICApKSB7XG4gICAgICAgICAgcmVzdWx0ID0gZmFsc2U7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgICAgc2tpcEN0b3IgfHwgKHNraXBDdG9yID0ga2V5ID09ICdjb25zdHJ1Y3RvcicpO1xuICAgICAgfVxuICAgICAgaWYgKHJlc3VsdCAmJiAhc2tpcEN0b3IpIHtcbiAgICAgICAgdmFyIG9iakN0b3IgPSBvYmplY3QuY29uc3RydWN0b3IsXG4gICAgICAgICAgICBvdGhDdG9yID0gb3RoZXIuY29uc3RydWN0b3I7XG5cbiAgICAgICAgLy8gTm9uIGBPYmplY3RgIG9iamVjdCBpbnN0YW5jZXMgd2l0aCBkaWZmZXJlbnQgY29uc3RydWN0b3JzIGFyZSBub3QgZXF1YWwuXG4gICAgICAgIGlmIChvYmpDdG9yICE9IG90aEN0b3IgJiZcbiAgICAgICAgICAgICgnY29uc3RydWN0b3InIGluIG9iamVjdCAmJiAnY29uc3RydWN0b3InIGluIG90aGVyKSAmJlxuICAgICAgICAgICAgISh0eXBlb2Ygb2JqQ3RvciA9PSAnZnVuY3Rpb24nICYmIG9iakN0b3IgaW5zdGFuY2VvZiBvYmpDdG9yICYmXG4gICAgICAgICAgICAgIHR5cGVvZiBvdGhDdG9yID09ICdmdW5jdGlvbicgJiYgb3RoQ3RvciBpbnN0YW5jZW9mIG90aEN0b3IpKSB7XG4gICAgICAgICAgcmVzdWx0ID0gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHN0YWNrWydkZWxldGUnXShvYmplY3QpO1xuICAgICAgc3RhY2tbJ2RlbGV0ZSddKG90aGVyKTtcbiAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQSBzcGVjaWFsaXplZCB2ZXJzaW9uIG9mIGBiYXNlUmVzdGAgd2hpY2ggZmxhdHRlbnMgdGhlIHJlc3QgYXJyYXkuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IGZ1bmMgVGhlIGZ1bmN0aW9uIHRvIGFwcGx5IGEgcmVzdCBwYXJhbWV0ZXIgdG8uXG4gICAgICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBuZXcgZnVuY3Rpb24uXG4gICAgICovXG4gICAgZnVuY3Rpb24gZmxhdFJlc3QoZnVuYykge1xuICAgICAgcmV0dXJuIHNldFRvU3RyaW5nKG92ZXJSZXN0KGZ1bmMsIHVuZGVmaW5lZCwgZmxhdHRlbiksIGZ1bmMgKyAnJyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhbiBhcnJheSBvZiBvd24gZW51bWVyYWJsZSBwcm9wZXJ0eSBuYW1lcyBhbmQgc3ltYm9scyBvZiBgb2JqZWN0YC5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIHF1ZXJ5LlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgYXJyYXkgb2YgcHJvcGVydHkgbmFtZXMgYW5kIHN5bWJvbHMuXG4gICAgICovXG4gICAgZnVuY3Rpb24gZ2V0QWxsS2V5cyhvYmplY3QpIHtcbiAgICAgIHJldHVybiBiYXNlR2V0QWxsS2V5cyhvYmplY3QsIGtleXMsIGdldFN5bWJvbHMpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYW4gYXJyYXkgb2Ygb3duIGFuZCBpbmhlcml0ZWQgZW51bWVyYWJsZSBwcm9wZXJ0eSBuYW1lcyBhbmRcbiAgICAgKiBzeW1ib2xzIG9mIGBvYmplY3RgLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gcXVlcnkuXG4gICAgICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBhcnJheSBvZiBwcm9wZXJ0eSBuYW1lcyBhbmQgc3ltYm9scy5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBnZXRBbGxLZXlzSW4ob2JqZWN0KSB7XG4gICAgICByZXR1cm4gYmFzZUdldEFsbEtleXMob2JqZWN0LCBrZXlzSW4sIGdldFN5bWJvbHNJbik7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogR2V0cyBtZXRhZGF0YSBmb3IgYGZ1bmNgLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBmdW5jIFRoZSBmdW5jdGlvbiB0byBxdWVyeS5cbiAgICAgKiBAcmV0dXJucyB7Kn0gUmV0dXJucyB0aGUgbWV0YWRhdGEgZm9yIGBmdW5jYC5cbiAgICAgKi9cbiAgICB2YXIgZ2V0RGF0YSA9ICFtZXRhTWFwID8gbm9vcCA6IGZ1bmN0aW9uKGZ1bmMpIHtcbiAgICAgIHJldHVybiBtZXRhTWFwLmdldChmdW5jKTtcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogR2V0cyB0aGUgbmFtZSBvZiBgZnVuY2AuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IGZ1bmMgVGhlIGZ1bmN0aW9uIHRvIHF1ZXJ5LlxuICAgICAqIEByZXR1cm5zIHtzdHJpbmd9IFJldHVybnMgdGhlIGZ1bmN0aW9uIG5hbWUuXG4gICAgICovXG4gICAgZnVuY3Rpb24gZ2V0RnVuY05hbWUoZnVuYykge1xuICAgICAgdmFyIHJlc3VsdCA9IChmdW5jLm5hbWUgKyAnJyksXG4gICAgICAgICAgYXJyYXkgPSByZWFsTmFtZXNbcmVzdWx0XSxcbiAgICAgICAgICBsZW5ndGggPSBoYXNPd25Qcm9wZXJ0eS5jYWxsKHJlYWxOYW1lcywgcmVzdWx0KSA/IGFycmF5Lmxlbmd0aCA6IDA7XG5cbiAgICAgIHdoaWxlIChsZW5ndGgtLSkge1xuICAgICAgICB2YXIgZGF0YSA9IGFycmF5W2xlbmd0aF0sXG4gICAgICAgICAgICBvdGhlckZ1bmMgPSBkYXRhLmZ1bmM7XG4gICAgICAgIGlmIChvdGhlckZ1bmMgPT0gbnVsbCB8fCBvdGhlckZ1bmMgPT0gZnVuYykge1xuICAgICAgICAgIHJldHVybiBkYXRhLm5hbWU7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogR2V0cyB0aGUgYXJndW1lbnQgcGxhY2Vob2xkZXIgdmFsdWUgZm9yIGBmdW5jYC5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gZnVuYyBUaGUgZnVuY3Rpb24gdG8gaW5zcGVjdC5cbiAgICAgKiBAcmV0dXJucyB7Kn0gUmV0dXJucyB0aGUgcGxhY2Vob2xkZXIgdmFsdWUuXG4gICAgICovXG4gICAgZnVuY3Rpb24gZ2V0SG9sZGVyKGZ1bmMpIHtcbiAgICAgIHZhciBvYmplY3QgPSBoYXNPd25Qcm9wZXJ0eS5jYWxsKGxvZGFzaCwgJ3BsYWNlaG9sZGVyJykgPyBsb2Rhc2ggOiBmdW5jO1xuICAgICAgcmV0dXJuIG9iamVjdC5wbGFjZWhvbGRlcjtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBHZXRzIHRoZSBhcHByb3ByaWF0ZSBcIml0ZXJhdGVlXCIgZnVuY3Rpb24uIElmIGBfLml0ZXJhdGVlYCBpcyBjdXN0b21pemVkLFxuICAgICAqIHRoaXMgZnVuY3Rpb24gcmV0dXJucyB0aGUgY3VzdG9tIG1ldGhvZCwgb3RoZXJ3aXNlIGl0IHJldHVybnMgYGJhc2VJdGVyYXRlZWAuXG4gICAgICogSWYgYXJndW1lbnRzIGFyZSBwcm92aWRlZCwgdGhlIGNob3NlbiBmdW5jdGlvbiBpcyBpbnZva2VkIHdpdGggdGhlbSBhbmRcbiAgICAgKiBpdHMgcmVzdWx0IGlzIHJldHVybmVkLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0geyp9IFt2YWx1ZV0gVGhlIHZhbHVlIHRvIGNvbnZlcnQgdG8gYW4gaXRlcmF0ZWUuXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IFthcml0eV0gVGhlIGFyaXR5IG9mIHRoZSBjcmVhdGVkIGl0ZXJhdGVlLlxuICAgICAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyB0aGUgY2hvc2VuIGZ1bmN0aW9uIG9yIGl0cyByZXN1bHQuXG4gICAgICovXG4gICAgZnVuY3Rpb24gZ2V0SXRlcmF0ZWUoKSB7XG4gICAgICB2YXIgcmVzdWx0ID0gbG9kYXNoLml0ZXJhdGVlIHx8IGl0ZXJhdGVlO1xuICAgICAgcmVzdWx0ID0gcmVzdWx0ID09PSBpdGVyYXRlZSA/IGJhc2VJdGVyYXRlZSA6IHJlc3VsdDtcbiAgICAgIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID8gcmVzdWx0KGFyZ3VtZW50c1swXSwgYXJndW1lbnRzWzFdKSA6IHJlc3VsdDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBHZXRzIHRoZSBkYXRhIGZvciBgbWFwYC5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtPYmplY3R9IG1hcCBUaGUgbWFwIHRvIHF1ZXJ5LlxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBrZXkgVGhlIHJlZmVyZW5jZSBrZXkuXG4gICAgICogQHJldHVybnMgeyp9IFJldHVybnMgdGhlIG1hcCBkYXRhLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGdldE1hcERhdGEobWFwLCBrZXkpIHtcbiAgICAgIHZhciBkYXRhID0gbWFwLl9fZGF0YV9fO1xuICAgICAgcmV0dXJuIGlzS2V5YWJsZShrZXkpXG4gICAgICAgID8gZGF0YVt0eXBlb2Yga2V5ID09ICdzdHJpbmcnID8gJ3N0cmluZycgOiAnaGFzaCddXG4gICAgICAgIDogZGF0YS5tYXA7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogR2V0cyB0aGUgcHJvcGVydHkgbmFtZXMsIHZhbHVlcywgYW5kIGNvbXBhcmUgZmxhZ3Mgb2YgYG9iamVjdGAuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBxdWVyeS5cbiAgICAgKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIG1hdGNoIGRhdGEgb2YgYG9iamVjdGAuXG4gICAgICovXG4gICAgZnVuY3Rpb24gZ2V0TWF0Y2hEYXRhKG9iamVjdCkge1xuICAgICAgdmFyIHJlc3VsdCA9IGtleXMob2JqZWN0KSxcbiAgICAgICAgICBsZW5ndGggPSByZXN1bHQubGVuZ3RoO1xuXG4gICAgICB3aGlsZSAobGVuZ3RoLS0pIHtcbiAgICAgICAgdmFyIGtleSA9IHJlc3VsdFtsZW5ndGhdLFxuICAgICAgICAgICAgdmFsdWUgPSBvYmplY3Rba2V5XTtcblxuICAgICAgICByZXN1bHRbbGVuZ3RoXSA9IFtrZXksIHZhbHVlLCBpc1N0cmljdENvbXBhcmFibGUodmFsdWUpXTtcbiAgICAgIH1cbiAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogR2V0cyB0aGUgbmF0aXZlIGZ1bmN0aW9uIGF0IGBrZXlgIG9mIGBvYmplY3RgLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gcXVlcnkuXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IGtleSBUaGUga2V5IG9mIHRoZSBtZXRob2QgdG8gZ2V0LlxuICAgICAqIEByZXR1cm5zIHsqfSBSZXR1cm5zIHRoZSBmdW5jdGlvbiBpZiBpdCdzIG5hdGl2ZSwgZWxzZSBgdW5kZWZpbmVkYC5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBnZXROYXRpdmUob2JqZWN0LCBrZXkpIHtcbiAgICAgIHZhciB2YWx1ZSA9IGdldFZhbHVlKG9iamVjdCwga2V5KTtcbiAgICAgIHJldHVybiBiYXNlSXNOYXRpdmUodmFsdWUpID8gdmFsdWUgOiB1bmRlZmluZWQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQSBzcGVjaWFsaXplZCB2ZXJzaW9uIG9mIGBiYXNlR2V0VGFnYCB3aGljaCBpZ25vcmVzIGBTeW1ib2wudG9TdHJpbmdUYWdgIHZhbHVlcy5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gcXVlcnkuXG4gICAgICogQHJldHVybnMge3N0cmluZ30gUmV0dXJucyB0aGUgcmF3IGB0b1N0cmluZ1RhZ2AuXG4gICAgICovXG4gICAgZnVuY3Rpb24gZ2V0UmF3VGFnKHZhbHVlKSB7XG4gICAgICB2YXIgaXNPd24gPSBoYXNPd25Qcm9wZXJ0eS5jYWxsKHZhbHVlLCBzeW1Ub1N0cmluZ1RhZyksXG4gICAgICAgICAgdGFnID0gdmFsdWVbc3ltVG9TdHJpbmdUYWddO1xuXG4gICAgICB0cnkge1xuICAgICAgICB2YWx1ZVtzeW1Ub1N0cmluZ1RhZ10gPSB1bmRlZmluZWQ7XG4gICAgICAgIHZhciB1bm1hc2tlZCA9IHRydWU7XG4gICAgICB9IGNhdGNoIChlKSB7fVxuXG4gICAgICB2YXIgcmVzdWx0ID0gbmF0aXZlT2JqZWN0VG9TdHJpbmcuY2FsbCh2YWx1ZSk7XG4gICAgICBpZiAodW5tYXNrZWQpIHtcbiAgICAgICAgaWYgKGlzT3duKSB7XG4gICAgICAgICAgdmFsdWVbc3ltVG9TdHJpbmdUYWddID0gdGFnO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGRlbGV0ZSB2YWx1ZVtzeW1Ub1N0cmluZ1RhZ107XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhbiBhcnJheSBvZiB0aGUgb3duIGVudW1lcmFibGUgc3ltYm9scyBvZiBgb2JqZWN0YC5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIHF1ZXJ5LlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgYXJyYXkgb2Ygc3ltYm9scy5cbiAgICAgKi9cbiAgICB2YXIgZ2V0U3ltYm9scyA9ICFuYXRpdmVHZXRTeW1ib2xzID8gc3R1YkFycmF5IDogZnVuY3Rpb24ob2JqZWN0KSB7XG4gICAgICBpZiAob2JqZWN0ID09IG51bGwpIHtcbiAgICAgICAgcmV0dXJuIFtdO1xuICAgICAgfVxuICAgICAgb2JqZWN0ID0gT2JqZWN0KG9iamVjdCk7XG4gICAgICByZXR1cm4gYXJyYXlGaWx0ZXIobmF0aXZlR2V0U3ltYm9scyhvYmplY3QpLCBmdW5jdGlvbihzeW1ib2wpIHtcbiAgICAgICAgcmV0dXJuIHByb3BlcnR5SXNFbnVtZXJhYmxlLmNhbGwob2JqZWN0LCBzeW1ib2wpO1xuICAgICAgfSk7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYW4gYXJyYXkgb2YgdGhlIG93biBhbmQgaW5oZXJpdGVkIGVudW1lcmFibGUgc3ltYm9scyBvZiBgb2JqZWN0YC5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIHF1ZXJ5LlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgYXJyYXkgb2Ygc3ltYm9scy5cbiAgICAgKi9cbiAgICB2YXIgZ2V0U3ltYm9sc0luID0gIW5hdGl2ZUdldFN5bWJvbHMgPyBzdHViQXJyYXkgOiBmdW5jdGlvbihvYmplY3QpIHtcbiAgICAgIHZhciByZXN1bHQgPSBbXTtcbiAgICAgIHdoaWxlIChvYmplY3QpIHtcbiAgICAgICAgYXJyYXlQdXNoKHJlc3VsdCwgZ2V0U3ltYm9scyhvYmplY3QpKTtcbiAgICAgICAgb2JqZWN0ID0gZ2V0UHJvdG90eXBlKG9iamVjdCk7XG4gICAgICB9XG4gICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBHZXRzIHRoZSBgdG9TdHJpbmdUYWdgIG9mIGB2YWx1ZWAuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIHF1ZXJ5LlxuICAgICAqIEByZXR1cm5zIHtzdHJpbmd9IFJldHVybnMgdGhlIGB0b1N0cmluZ1RhZ2AuXG4gICAgICovXG4gICAgdmFyIGdldFRhZyA9IGJhc2VHZXRUYWc7XG5cbiAgICAvLyBGYWxsYmFjayBmb3IgZGF0YSB2aWV3cywgbWFwcywgc2V0cywgYW5kIHdlYWsgbWFwcyBpbiBJRSAxMSBhbmQgcHJvbWlzZXMgaW4gTm9kZS5qcyA8IDYuXG4gICAgaWYgKChEYXRhVmlldyAmJiBnZXRUYWcobmV3IERhdGFWaWV3KG5ldyBBcnJheUJ1ZmZlcigxKSkpICE9IGRhdGFWaWV3VGFnKSB8fFxuICAgICAgICAoTWFwICYmIGdldFRhZyhuZXcgTWFwKSAhPSBtYXBUYWcpIHx8XG4gICAgICAgIChQcm9taXNlICYmIGdldFRhZyhQcm9taXNlLnJlc29sdmUoKSkgIT0gcHJvbWlzZVRhZykgfHxcbiAgICAgICAgKFNldCAmJiBnZXRUYWcobmV3IFNldCkgIT0gc2V0VGFnKSB8fFxuICAgICAgICAoV2Vha01hcCAmJiBnZXRUYWcobmV3IFdlYWtNYXApICE9IHdlYWtNYXBUYWcpKSB7XG4gICAgICBnZXRUYWcgPSBmdW5jdGlvbih2YWx1ZSkge1xuICAgICAgICB2YXIgcmVzdWx0ID0gYmFzZUdldFRhZyh2YWx1ZSksXG4gICAgICAgICAgICBDdG9yID0gcmVzdWx0ID09IG9iamVjdFRhZyA/IHZhbHVlLmNvbnN0cnVjdG9yIDogdW5kZWZpbmVkLFxuICAgICAgICAgICAgY3RvclN0cmluZyA9IEN0b3IgPyB0b1NvdXJjZShDdG9yKSA6ICcnO1xuXG4gICAgICAgIGlmIChjdG9yU3RyaW5nKSB7XG4gICAgICAgICAgc3dpdGNoIChjdG9yU3RyaW5nKSB7XG4gICAgICAgICAgICBjYXNlIGRhdGFWaWV3Q3RvclN0cmluZzogcmV0dXJuIGRhdGFWaWV3VGFnO1xuICAgICAgICAgICAgY2FzZSBtYXBDdG9yU3RyaW5nOiByZXR1cm4gbWFwVGFnO1xuICAgICAgICAgICAgY2FzZSBwcm9taXNlQ3RvclN0cmluZzogcmV0dXJuIHByb21pc2VUYWc7XG4gICAgICAgICAgICBjYXNlIHNldEN0b3JTdHJpbmc6IHJldHVybiBzZXRUYWc7XG4gICAgICAgICAgICBjYXNlIHdlYWtNYXBDdG9yU3RyaW5nOiByZXR1cm4gd2Vha01hcFRhZztcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICAgIH07XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogR2V0cyB0aGUgdmlldywgYXBwbHlpbmcgYW55IGB0cmFuc2Zvcm1zYCB0byB0aGUgYHN0YXJ0YCBhbmQgYGVuZGAgcG9zaXRpb25zLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge251bWJlcn0gc3RhcnQgVGhlIHN0YXJ0IG9mIHRoZSB2aWV3LlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBlbmQgVGhlIGVuZCBvZiB0aGUgdmlldy5cbiAgICAgKiBAcGFyYW0ge0FycmF5fSB0cmFuc2Zvcm1zIFRoZSB0cmFuc2Zvcm1hdGlvbnMgdG8gYXBwbHkgdG8gdGhlIHZpZXcuXG4gICAgICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyBhbiBvYmplY3QgY29udGFpbmluZyB0aGUgYHN0YXJ0YCBhbmQgYGVuZGBcbiAgICAgKiAgcG9zaXRpb25zIG9mIHRoZSB2aWV3LlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGdldFZpZXcoc3RhcnQsIGVuZCwgdHJhbnNmb3Jtcykge1xuICAgICAgdmFyIGluZGV4ID0gLTEsXG4gICAgICAgICAgbGVuZ3RoID0gdHJhbnNmb3Jtcy5sZW5ndGg7XG5cbiAgICAgIHdoaWxlICgrK2luZGV4IDwgbGVuZ3RoKSB7XG4gICAgICAgIHZhciBkYXRhID0gdHJhbnNmb3Jtc1tpbmRleF0sXG4gICAgICAgICAgICBzaXplID0gZGF0YS5zaXplO1xuXG4gICAgICAgIHN3aXRjaCAoZGF0YS50eXBlKSB7XG4gICAgICAgICAgY2FzZSAnZHJvcCc6ICAgICAgc3RhcnQgKz0gc2l6ZTsgYnJlYWs7XG4gICAgICAgICAgY2FzZSAnZHJvcFJpZ2h0JzogZW5kIC09IHNpemU7IGJyZWFrO1xuICAgICAgICAgIGNhc2UgJ3Rha2UnOiAgICAgIGVuZCA9IG5hdGl2ZU1pbihlbmQsIHN0YXJ0ICsgc2l6ZSk7IGJyZWFrO1xuICAgICAgICAgIGNhc2UgJ3Rha2VSaWdodCc6IHN0YXJ0ID0gbmF0aXZlTWF4KHN0YXJ0LCBlbmQgLSBzaXplKTsgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHJldHVybiB7ICdzdGFydCc6IHN0YXJ0LCAnZW5kJzogZW5kIH07XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogRXh0cmFjdHMgd3JhcHBlciBkZXRhaWxzIGZyb20gdGhlIGBzb3VyY2VgIGJvZHkgY29tbWVudC5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IHNvdXJjZSBUaGUgc291cmNlIHRvIGluc3BlY3QuXG4gICAgICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSB3cmFwcGVyIGRldGFpbHMuXG4gICAgICovXG4gICAgZnVuY3Rpb24gZ2V0V3JhcERldGFpbHMoc291cmNlKSB7XG4gICAgICB2YXIgbWF0Y2ggPSBzb3VyY2UubWF0Y2gocmVXcmFwRGV0YWlscyk7XG4gICAgICByZXR1cm4gbWF0Y2ggPyBtYXRjaFsxXS5zcGxpdChyZVNwbGl0RGV0YWlscykgOiBbXTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDaGVja3MgaWYgYHBhdGhgIGV4aXN0cyBvbiBgb2JqZWN0YC5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIHF1ZXJ5LlxuICAgICAqIEBwYXJhbSB7QXJyYXl8c3RyaW5nfSBwYXRoIFRoZSBwYXRoIHRvIGNoZWNrLlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IGhhc0Z1bmMgVGhlIGZ1bmN0aW9uIHRvIGNoZWNrIHByb3BlcnRpZXMuXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGBwYXRoYCBleGlzdHMsIGVsc2UgYGZhbHNlYC5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBoYXNQYXRoKG9iamVjdCwgcGF0aCwgaGFzRnVuYykge1xuICAgICAgcGF0aCA9IGNhc3RQYXRoKHBhdGgsIG9iamVjdCk7XG5cbiAgICAgIHZhciBpbmRleCA9IC0xLFxuICAgICAgICAgIGxlbmd0aCA9IHBhdGgubGVuZ3RoLFxuICAgICAgICAgIHJlc3VsdCA9IGZhbHNlO1xuXG4gICAgICB3aGlsZSAoKytpbmRleCA8IGxlbmd0aCkge1xuICAgICAgICB2YXIga2V5ID0gdG9LZXkocGF0aFtpbmRleF0pO1xuICAgICAgICBpZiAoIShyZXN1bHQgPSBvYmplY3QgIT0gbnVsbCAmJiBoYXNGdW5jKG9iamVjdCwga2V5KSkpIHtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgICBvYmplY3QgPSBvYmplY3Rba2V5XTtcbiAgICAgIH1cbiAgICAgIGlmIChyZXN1bHQgfHwgKytpbmRleCAhPSBsZW5ndGgpIHtcbiAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICAgIH1cbiAgICAgIGxlbmd0aCA9IG9iamVjdCA9PSBudWxsID8gMCA6IG9iamVjdC5sZW5ndGg7XG4gICAgICByZXR1cm4gISFsZW5ndGggJiYgaXNMZW5ndGgobGVuZ3RoKSAmJiBpc0luZGV4KGtleSwgbGVuZ3RoKSAmJlxuICAgICAgICAoaXNBcnJheShvYmplY3QpIHx8IGlzQXJndW1lbnRzKG9iamVjdCkpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEluaXRpYWxpemVzIGFuIGFycmF5IGNsb25lLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBhcnJheSBUaGUgYXJyYXkgdG8gY2xvbmUuXG4gICAgICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBpbml0aWFsaXplZCBjbG9uZS5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBpbml0Q2xvbmVBcnJheShhcnJheSkge1xuICAgICAgdmFyIGxlbmd0aCA9IGFycmF5Lmxlbmd0aCxcbiAgICAgICAgICByZXN1bHQgPSBhcnJheS5jb25zdHJ1Y3RvcihsZW5ndGgpO1xuXG4gICAgICAvLyBBZGQgcHJvcGVydGllcyBhc3NpZ25lZCBieSBgUmVnRXhwI2V4ZWNgLlxuICAgICAgaWYgKGxlbmd0aCAmJiB0eXBlb2YgYXJyYXlbMF0gPT0gJ3N0cmluZycgJiYgaGFzT3duUHJvcGVydHkuY2FsbChhcnJheSwgJ2luZGV4JykpIHtcbiAgICAgICAgcmVzdWx0LmluZGV4ID0gYXJyYXkuaW5kZXg7XG4gICAgICAgIHJlc3VsdC5pbnB1dCA9IGFycmF5LmlucHV0O1xuICAgICAgfVxuICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBJbml0aWFsaXplcyBhbiBvYmplY3QgY2xvbmUuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBjbG9uZS5cbiAgICAgKiBAcmV0dXJucyB7T2JqZWN0fSBSZXR1cm5zIHRoZSBpbml0aWFsaXplZCBjbG9uZS5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBpbml0Q2xvbmVPYmplY3Qob2JqZWN0KSB7XG4gICAgICByZXR1cm4gKHR5cGVvZiBvYmplY3QuY29uc3RydWN0b3IgPT0gJ2Z1bmN0aW9uJyAmJiAhaXNQcm90b3R5cGUob2JqZWN0KSlcbiAgICAgICAgPyBiYXNlQ3JlYXRlKGdldFByb3RvdHlwZShvYmplY3QpKVxuICAgICAgICA6IHt9O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEluaXRpYWxpemVzIGFuIG9iamVjdCBjbG9uZSBiYXNlZCBvbiBpdHMgYHRvU3RyaW5nVGFnYC5cbiAgICAgKlxuICAgICAqICoqTm90ZToqKiBUaGlzIGZ1bmN0aW9uIG9ubHkgc3VwcG9ydHMgY2xvbmluZyB2YWx1ZXMgd2l0aCB0YWdzIG9mXG4gICAgICogYEJvb2xlYW5gLCBgRGF0ZWAsIGBFcnJvcmAsIGBOdW1iZXJgLCBgUmVnRXhwYCwgb3IgYFN0cmluZ2AuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBjbG9uZS5cbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gdGFnIFRoZSBgdG9TdHJpbmdUYWdgIG9mIHRoZSBvYmplY3QgdG8gY2xvbmUuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gY2xvbmVGdW5jIFRoZSBmdW5jdGlvbiB0byBjbG9uZSB2YWx1ZXMuXG4gICAgICogQHBhcmFtIHtib29sZWFufSBbaXNEZWVwXSBTcGVjaWZ5IGEgZGVlcCBjbG9uZS5cbiAgICAgKiBAcmV0dXJucyB7T2JqZWN0fSBSZXR1cm5zIHRoZSBpbml0aWFsaXplZCBjbG9uZS5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBpbml0Q2xvbmVCeVRhZyhvYmplY3QsIHRhZywgY2xvbmVGdW5jLCBpc0RlZXApIHtcbiAgICAgIHZhciBDdG9yID0gb2JqZWN0LmNvbnN0cnVjdG9yO1xuICAgICAgc3dpdGNoICh0YWcpIHtcbiAgICAgICAgY2FzZSBhcnJheUJ1ZmZlclRhZzpcbiAgICAgICAgICByZXR1cm4gY2xvbmVBcnJheUJ1ZmZlcihvYmplY3QpO1xuXG4gICAgICAgIGNhc2UgYm9vbFRhZzpcbiAgICAgICAgY2FzZSBkYXRlVGFnOlxuICAgICAgICAgIHJldHVybiBuZXcgQ3Rvcigrb2JqZWN0KTtcblxuICAgICAgICBjYXNlIGRhdGFWaWV3VGFnOlxuICAgICAgICAgIHJldHVybiBjbG9uZURhdGFWaWV3KG9iamVjdCwgaXNEZWVwKTtcblxuICAgICAgICBjYXNlIGZsb2F0MzJUYWc6IGNhc2UgZmxvYXQ2NFRhZzpcbiAgICAgICAgY2FzZSBpbnQ4VGFnOiBjYXNlIGludDE2VGFnOiBjYXNlIGludDMyVGFnOlxuICAgICAgICBjYXNlIHVpbnQ4VGFnOiBjYXNlIHVpbnQ4Q2xhbXBlZFRhZzogY2FzZSB1aW50MTZUYWc6IGNhc2UgdWludDMyVGFnOlxuICAgICAgICAgIHJldHVybiBjbG9uZVR5cGVkQXJyYXkob2JqZWN0LCBpc0RlZXApO1xuXG4gICAgICAgIGNhc2UgbWFwVGFnOlxuICAgICAgICAgIHJldHVybiBjbG9uZU1hcChvYmplY3QsIGlzRGVlcCwgY2xvbmVGdW5jKTtcblxuICAgICAgICBjYXNlIG51bWJlclRhZzpcbiAgICAgICAgY2FzZSBzdHJpbmdUYWc6XG4gICAgICAgICAgcmV0dXJuIG5ldyBDdG9yKG9iamVjdCk7XG5cbiAgICAgICAgY2FzZSByZWdleHBUYWc6XG4gICAgICAgICAgcmV0dXJuIGNsb25lUmVnRXhwKG9iamVjdCk7XG5cbiAgICAgICAgY2FzZSBzZXRUYWc6XG4gICAgICAgICAgcmV0dXJuIGNsb25lU2V0KG9iamVjdCwgaXNEZWVwLCBjbG9uZUZ1bmMpO1xuXG4gICAgICAgIGNhc2Ugc3ltYm9sVGFnOlxuICAgICAgICAgIHJldHVybiBjbG9uZVN5bWJvbChvYmplY3QpO1xuICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEluc2VydHMgd3JhcHBlciBgZGV0YWlsc2AgaW4gYSBjb21tZW50IGF0IHRoZSB0b3Agb2YgdGhlIGBzb3VyY2VgIGJvZHkuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBzb3VyY2UgVGhlIHNvdXJjZSB0byBtb2RpZnkuXG4gICAgICogQHJldHVybnMge0FycmF5fSBkZXRhaWxzIFRoZSBkZXRhaWxzIHRvIGluc2VydC5cbiAgICAgKiBAcmV0dXJucyB7c3RyaW5nfSBSZXR1cm5zIHRoZSBtb2RpZmllZCBzb3VyY2UuXG4gICAgICovXG4gICAgZnVuY3Rpb24gaW5zZXJ0V3JhcERldGFpbHMoc291cmNlLCBkZXRhaWxzKSB7XG4gICAgICB2YXIgbGVuZ3RoID0gZGV0YWlscy5sZW5ndGg7XG4gICAgICBpZiAoIWxlbmd0aCkge1xuICAgICAgICByZXR1cm4gc291cmNlO1xuICAgICAgfVxuICAgICAgdmFyIGxhc3RJbmRleCA9IGxlbmd0aCAtIDE7XG4gICAgICBkZXRhaWxzW2xhc3RJbmRleF0gPSAobGVuZ3RoID4gMSA/ICcmICcgOiAnJykgKyBkZXRhaWxzW2xhc3RJbmRleF07XG4gICAgICBkZXRhaWxzID0gZGV0YWlscy5qb2luKGxlbmd0aCA+IDIgPyAnLCAnIDogJyAnKTtcbiAgICAgIHJldHVybiBzb3VyY2UucmVwbGFjZShyZVdyYXBDb21tZW50LCAne1xcbi8qIFt3cmFwcGVkIHdpdGggJyArIGRldGFpbHMgKyAnXSAqL1xcbicpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENoZWNrcyBpZiBgdmFsdWVgIGlzIGEgZmxhdHRlbmFibGUgYGFyZ3VtZW50c2Agb2JqZWN0IG9yIGFycmF5LlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjaGVjay5cbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBmbGF0dGVuYWJsZSwgZWxzZSBgZmFsc2VgLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGlzRmxhdHRlbmFibGUodmFsdWUpIHtcbiAgICAgIHJldHVybiBpc0FycmF5KHZhbHVlKSB8fCBpc0FyZ3VtZW50cyh2YWx1ZSkgfHxcbiAgICAgICAgISEoc3ByZWFkYWJsZVN5bWJvbCAmJiB2YWx1ZSAmJiB2YWx1ZVtzcHJlYWRhYmxlU3ltYm9sXSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ2hlY2tzIGlmIGB2YWx1ZWAgaXMgYSB2YWxpZCBhcnJheS1saWtlIGluZGV4LlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjaGVjay5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gW2xlbmd0aD1NQVhfU0FGRV9JTlRFR0VSXSBUaGUgdXBwZXIgYm91bmRzIG9mIGEgdmFsaWQgaW5kZXguXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGB2YWx1ZWAgaXMgYSB2YWxpZCBpbmRleCwgZWxzZSBgZmFsc2VgLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGlzSW5kZXgodmFsdWUsIGxlbmd0aCkge1xuICAgICAgbGVuZ3RoID0gbGVuZ3RoID09IG51bGwgPyBNQVhfU0FGRV9JTlRFR0VSIDogbGVuZ3RoO1xuICAgICAgcmV0dXJuICEhbGVuZ3RoICYmXG4gICAgICAgICh0eXBlb2YgdmFsdWUgPT0gJ251bWJlcicgfHwgcmVJc1VpbnQudGVzdCh2YWx1ZSkpICYmXG4gICAgICAgICh2YWx1ZSA+IC0xICYmIHZhbHVlICUgMSA9PSAwICYmIHZhbHVlIDwgbGVuZ3RoKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDaGVja3MgaWYgdGhlIGdpdmVuIGFyZ3VtZW50cyBhcmUgZnJvbSBhbiBpdGVyYXRlZSBjYWxsLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSBwb3RlbnRpYWwgaXRlcmF0ZWUgdmFsdWUgYXJndW1lbnQuXG4gICAgICogQHBhcmFtIHsqfSBpbmRleCBUaGUgcG90ZW50aWFsIGl0ZXJhdGVlIGluZGV4IG9yIGtleSBhcmd1bWVudC5cbiAgICAgKiBAcGFyYW0geyp9IG9iamVjdCBUaGUgcG90ZW50aWFsIGl0ZXJhdGVlIG9iamVjdCBhcmd1bWVudC5cbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgdGhlIGFyZ3VtZW50cyBhcmUgZnJvbSBhbiBpdGVyYXRlZSBjYWxsLFxuICAgICAqICBlbHNlIGBmYWxzZWAuXG4gICAgICovXG4gICAgZnVuY3Rpb24gaXNJdGVyYXRlZUNhbGwodmFsdWUsIGluZGV4LCBvYmplY3QpIHtcbiAgICAgIGlmICghaXNPYmplY3Qob2JqZWN0KSkge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG4gICAgICB2YXIgdHlwZSA9IHR5cGVvZiBpbmRleDtcbiAgICAgIGlmICh0eXBlID09ICdudW1iZXInXG4gICAgICAgICAgICA/IChpc0FycmF5TGlrZShvYmplY3QpICYmIGlzSW5kZXgoaW5kZXgsIG9iamVjdC5sZW5ndGgpKVxuICAgICAgICAgICAgOiAodHlwZSA9PSAnc3RyaW5nJyAmJiBpbmRleCBpbiBvYmplY3QpXG4gICAgICAgICAgKSB7XG4gICAgICAgIHJldHVybiBlcShvYmplY3RbaW5kZXhdLCB2YWx1ZSk7XG4gICAgICB9XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ2hlY2tzIGlmIGB2YWx1ZWAgaXMgYSBwcm9wZXJ0eSBuYW1lIGFuZCBub3QgYSBwcm9wZXJ0eSBwYXRoLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjaGVjay5cbiAgICAgKiBAcGFyYW0ge09iamVjdH0gW29iamVjdF0gVGhlIG9iamVjdCB0byBxdWVyeSBrZXlzIG9uLlxuICAgICAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlzIGEgcHJvcGVydHkgbmFtZSwgZWxzZSBgZmFsc2VgLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGlzS2V5KHZhbHVlLCBvYmplY3QpIHtcbiAgICAgIGlmIChpc0FycmF5KHZhbHVlKSkge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG4gICAgICB2YXIgdHlwZSA9IHR5cGVvZiB2YWx1ZTtcbiAgICAgIGlmICh0eXBlID09ICdudW1iZXInIHx8IHR5cGUgPT0gJ3N5bWJvbCcgfHwgdHlwZSA9PSAnYm9vbGVhbicgfHxcbiAgICAgICAgICB2YWx1ZSA9PSBudWxsIHx8IGlzU3ltYm9sKHZhbHVlKSkge1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgIH1cbiAgICAgIHJldHVybiByZUlzUGxhaW5Qcm9wLnRlc3QodmFsdWUpIHx8ICFyZUlzRGVlcFByb3AudGVzdCh2YWx1ZSkgfHxcbiAgICAgICAgKG9iamVjdCAhPSBudWxsICYmIHZhbHVlIGluIE9iamVjdChvYmplY3QpKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDaGVja3MgaWYgYHZhbHVlYCBpcyBzdWl0YWJsZSBmb3IgdXNlIGFzIHVuaXF1ZSBvYmplY3Qga2V5LlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjaGVjay5cbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBzdWl0YWJsZSwgZWxzZSBgZmFsc2VgLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGlzS2V5YWJsZSh2YWx1ZSkge1xuICAgICAgdmFyIHR5cGUgPSB0eXBlb2YgdmFsdWU7XG4gICAgICByZXR1cm4gKHR5cGUgPT0gJ3N0cmluZycgfHwgdHlwZSA9PSAnbnVtYmVyJyB8fCB0eXBlID09ICdzeW1ib2wnIHx8IHR5cGUgPT0gJ2Jvb2xlYW4nKVxuICAgICAgICA/ICh2YWx1ZSAhPT0gJ19fcHJvdG9fXycpXG4gICAgICAgIDogKHZhbHVlID09PSBudWxsKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDaGVja3MgaWYgYGZ1bmNgIGhhcyBhIGxhenkgY291bnRlcnBhcnQuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IGZ1bmMgVGhlIGZ1bmN0aW9uIHRvIGNoZWNrLlxuICAgICAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgZnVuY2AgaGFzIGEgbGF6eSBjb3VudGVycGFydCxcbiAgICAgKiAgZWxzZSBgZmFsc2VgLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGlzTGF6aWFibGUoZnVuYykge1xuICAgICAgdmFyIGZ1bmNOYW1lID0gZ2V0RnVuY05hbWUoZnVuYyksXG4gICAgICAgICAgb3RoZXIgPSBsb2Rhc2hbZnVuY05hbWVdO1xuXG4gICAgICBpZiAodHlwZW9mIG90aGVyICE9ICdmdW5jdGlvbicgfHwgIShmdW5jTmFtZSBpbiBMYXp5V3JhcHBlci5wcm90b3R5cGUpKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cbiAgICAgIGlmIChmdW5jID09PSBvdGhlcikge1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgIH1cbiAgICAgIHZhciBkYXRhID0gZ2V0RGF0YShvdGhlcik7XG4gICAgICByZXR1cm4gISFkYXRhICYmIGZ1bmMgPT09IGRhdGFbMF07XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ2hlY2tzIGlmIGBmdW5jYCBoYXMgaXRzIHNvdXJjZSBtYXNrZWQuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IGZ1bmMgVGhlIGZ1bmN0aW9uIHRvIGNoZWNrLlxuICAgICAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgZnVuY2AgaXMgbWFza2VkLCBlbHNlIGBmYWxzZWAuXG4gICAgICovXG4gICAgZnVuY3Rpb24gaXNNYXNrZWQoZnVuYykge1xuICAgICAgcmV0dXJuICEhbWFza1NyY0tleSAmJiAobWFza1NyY0tleSBpbiBmdW5jKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDaGVja3MgaWYgYGZ1bmNgIGlzIGNhcGFibGUgb2YgYmVpbmcgbWFza2VkLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjaGVjay5cbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYGZ1bmNgIGlzIG1hc2thYmxlLCBlbHNlIGBmYWxzZWAuXG4gICAgICovXG4gICAgdmFyIGlzTWFza2FibGUgPSBjb3JlSnNEYXRhID8gaXNGdW5jdGlvbiA6IHN0dWJGYWxzZTtcblxuICAgIC8qKlxuICAgICAqIENoZWNrcyBpZiBgdmFsdWVgIGlzIGxpa2VseSBhIHByb3RvdHlwZSBvYmplY3QuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrLlxuICAgICAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlzIGEgcHJvdG90eXBlLCBlbHNlIGBmYWxzZWAuXG4gICAgICovXG4gICAgZnVuY3Rpb24gaXNQcm90b3R5cGUodmFsdWUpIHtcbiAgICAgIHZhciBDdG9yID0gdmFsdWUgJiYgdmFsdWUuY29uc3RydWN0b3IsXG4gICAgICAgICAgcHJvdG8gPSAodHlwZW9mIEN0b3IgPT0gJ2Z1bmN0aW9uJyAmJiBDdG9yLnByb3RvdHlwZSkgfHwgb2JqZWN0UHJvdG87XG5cbiAgICAgIHJldHVybiB2YWx1ZSA9PT0gcHJvdG87XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ2hlY2tzIGlmIGB2YWx1ZWAgaXMgc3VpdGFibGUgZm9yIHN0cmljdCBlcXVhbGl0eSBjb21wYXJpc29ucywgaS5lLiBgPT09YC5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY2hlY2suXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGB2YWx1ZWAgaWYgc3VpdGFibGUgZm9yIHN0cmljdFxuICAgICAqICBlcXVhbGl0eSBjb21wYXJpc29ucywgZWxzZSBgZmFsc2VgLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGlzU3RyaWN0Q29tcGFyYWJsZSh2YWx1ZSkge1xuICAgICAgcmV0dXJuIHZhbHVlID09PSB2YWx1ZSAmJiAhaXNPYmplY3QodmFsdWUpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEEgc3BlY2lhbGl6ZWQgdmVyc2lvbiBvZiBgbWF0Y2hlc1Byb3BlcnR5YCBmb3Igc291cmNlIHZhbHVlcyBzdWl0YWJsZVxuICAgICAqIGZvciBzdHJpY3QgZXF1YWxpdHkgY29tcGFyaXNvbnMsIGkuZS4gYD09PWAuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBrZXkgVGhlIGtleSBvZiB0aGUgcHJvcGVydHkgdG8gZ2V0LlxuICAgICAqIEBwYXJhbSB7Kn0gc3JjVmFsdWUgVGhlIHZhbHVlIHRvIG1hdGNoLlxuICAgICAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyB0aGUgbmV3IHNwZWMgZnVuY3Rpb24uXG4gICAgICovXG4gICAgZnVuY3Rpb24gbWF0Y2hlc1N0cmljdENvbXBhcmFibGUoa2V5LCBzcmNWYWx1ZSkge1xuICAgICAgcmV0dXJuIGZ1bmN0aW9uKG9iamVjdCkge1xuICAgICAgICBpZiAob2JqZWN0ID09IG51bGwpIHtcbiAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG9iamVjdFtrZXldID09PSBzcmNWYWx1ZSAmJlxuICAgICAgICAgIChzcmNWYWx1ZSAhPT0gdW5kZWZpbmVkIHx8IChrZXkgaW4gT2JqZWN0KG9iamVjdCkpKTtcbiAgICAgIH07XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQSBzcGVjaWFsaXplZCB2ZXJzaW9uIG9mIGBfLm1lbW9pemVgIHdoaWNoIGNsZWFycyB0aGUgbWVtb2l6ZWQgZnVuY3Rpb24nc1xuICAgICAqIGNhY2hlIHdoZW4gaXQgZXhjZWVkcyBgTUFYX01FTU9JWkVfU0laRWAuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IGZ1bmMgVGhlIGZ1bmN0aW9uIHRvIGhhdmUgaXRzIG91dHB1dCBtZW1vaXplZC5cbiAgICAgKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyBtZW1vaXplZCBmdW5jdGlvbi5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBtZW1vaXplQ2FwcGVkKGZ1bmMpIHtcbiAgICAgIHZhciByZXN1bHQgPSBtZW1vaXplKGZ1bmMsIGZ1bmN0aW9uKGtleSkge1xuICAgICAgICBpZiAoY2FjaGUuc2l6ZSA9PT0gTUFYX01FTU9JWkVfU0laRSkge1xuICAgICAgICAgIGNhY2hlLmNsZWFyKCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGtleTtcbiAgICAgIH0pO1xuXG4gICAgICB2YXIgY2FjaGUgPSByZXN1bHQuY2FjaGU7XG4gICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIE1lcmdlcyB0aGUgZnVuY3Rpb24gbWV0YWRhdGEgb2YgYHNvdXJjZWAgaW50byBgZGF0YWAuXG4gICAgICpcbiAgICAgKiBNZXJnaW5nIG1ldGFkYXRhIHJlZHVjZXMgdGhlIG51bWJlciBvZiB3cmFwcGVycyB1c2VkIHRvIGludm9rZSBhIGZ1bmN0aW9uLlxuICAgICAqIFRoaXMgaXMgcG9zc2libGUgYmVjYXVzZSBtZXRob2RzIGxpa2UgYF8uYmluZGAsIGBfLmN1cnJ5YCwgYW5kIGBfLnBhcnRpYWxgXG4gICAgICogbWF5IGJlIGFwcGxpZWQgcmVnYXJkbGVzcyBvZiBleGVjdXRpb24gb3JkZXIuIE1ldGhvZHMgbGlrZSBgXy5hcnlgIGFuZFxuICAgICAqIGBfLnJlYXJnYCBtb2RpZnkgZnVuY3Rpb24gYXJndW1lbnRzLCBtYWtpbmcgdGhlIG9yZGVyIGluIHdoaWNoIHRoZXkgYXJlXG4gICAgICogZXhlY3V0ZWQgaW1wb3J0YW50LCBwcmV2ZW50aW5nIHRoZSBtZXJnaW5nIG9mIG1ldGFkYXRhLiBIb3dldmVyLCB3ZSBtYWtlXG4gICAgICogYW4gZXhjZXB0aW9uIGZvciBhIHNhZmUgY29tYmluZWQgY2FzZSB3aGVyZSBjdXJyaWVkIGZ1bmN0aW9ucyBoYXZlIGBfLmFyeWBcbiAgICAgKiBhbmQgb3IgYF8ucmVhcmdgIGFwcGxpZWQuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7QXJyYXl9IGRhdGEgVGhlIGRlc3RpbmF0aW9uIG1ldGFkYXRhLlxuICAgICAqIEBwYXJhbSB7QXJyYXl9IHNvdXJjZSBUaGUgc291cmNlIG1ldGFkYXRhLlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyBgZGF0YWAuXG4gICAgICovXG4gICAgZnVuY3Rpb24gbWVyZ2VEYXRhKGRhdGEsIHNvdXJjZSkge1xuICAgICAgdmFyIGJpdG1hc2sgPSBkYXRhWzFdLFxuICAgICAgICAgIHNyY0JpdG1hc2sgPSBzb3VyY2VbMV0sXG4gICAgICAgICAgbmV3Qml0bWFzayA9IGJpdG1hc2sgfCBzcmNCaXRtYXNrLFxuICAgICAgICAgIGlzQ29tbW9uID0gbmV3Qml0bWFzayA8IChXUkFQX0JJTkRfRkxBRyB8IFdSQVBfQklORF9LRVlfRkxBRyB8IFdSQVBfQVJZX0ZMQUcpO1xuXG4gICAgICB2YXIgaXNDb21ibyA9XG4gICAgICAgICgoc3JjQml0bWFzayA9PSBXUkFQX0FSWV9GTEFHKSAmJiAoYml0bWFzayA9PSBXUkFQX0NVUlJZX0ZMQUcpKSB8fFxuICAgICAgICAoKHNyY0JpdG1hc2sgPT0gV1JBUF9BUllfRkxBRykgJiYgKGJpdG1hc2sgPT0gV1JBUF9SRUFSR19GTEFHKSAmJiAoZGF0YVs3XS5sZW5ndGggPD0gc291cmNlWzhdKSkgfHxcbiAgICAgICAgKChzcmNCaXRtYXNrID09IChXUkFQX0FSWV9GTEFHIHwgV1JBUF9SRUFSR19GTEFHKSkgJiYgKHNvdXJjZVs3XS5sZW5ndGggPD0gc291cmNlWzhdKSAmJiAoYml0bWFzayA9PSBXUkFQX0NVUlJZX0ZMQUcpKTtcblxuICAgICAgLy8gRXhpdCBlYXJseSBpZiBtZXRhZGF0YSBjYW4ndCBiZSBtZXJnZWQuXG4gICAgICBpZiAoIShpc0NvbW1vbiB8fCBpc0NvbWJvKSkge1xuICAgICAgICByZXR1cm4gZGF0YTtcbiAgICAgIH1cbiAgICAgIC8vIFVzZSBzb3VyY2UgYHRoaXNBcmdgIGlmIGF2YWlsYWJsZS5cbiAgICAgIGlmIChzcmNCaXRtYXNrICYgV1JBUF9CSU5EX0ZMQUcpIHtcbiAgICAgICAgZGF0YVsyXSA9IHNvdXJjZVsyXTtcbiAgICAgICAgLy8gU2V0IHdoZW4gY3VycnlpbmcgYSBib3VuZCBmdW5jdGlvbi5cbiAgICAgICAgbmV3Qml0bWFzayB8PSBiaXRtYXNrICYgV1JBUF9CSU5EX0ZMQUcgPyAwIDogV1JBUF9DVVJSWV9CT1VORF9GTEFHO1xuICAgICAgfVxuICAgICAgLy8gQ29tcG9zZSBwYXJ0aWFsIGFyZ3VtZW50cy5cbiAgICAgIHZhciB2YWx1ZSA9IHNvdXJjZVszXTtcbiAgICAgIGlmICh2YWx1ZSkge1xuICAgICAgICB2YXIgcGFydGlhbHMgPSBkYXRhWzNdO1xuICAgICAgICBkYXRhWzNdID0gcGFydGlhbHMgPyBjb21wb3NlQXJncyhwYXJ0aWFscywgdmFsdWUsIHNvdXJjZVs0XSkgOiB2YWx1ZTtcbiAgICAgICAgZGF0YVs0XSA9IHBhcnRpYWxzID8gcmVwbGFjZUhvbGRlcnMoZGF0YVszXSwgUExBQ0VIT0xERVIpIDogc291cmNlWzRdO1xuICAgICAgfVxuICAgICAgLy8gQ29tcG9zZSBwYXJ0aWFsIHJpZ2h0IGFyZ3VtZW50cy5cbiAgICAgIHZhbHVlID0gc291cmNlWzVdO1xuICAgICAgaWYgKHZhbHVlKSB7XG4gICAgICAgIHBhcnRpYWxzID0gZGF0YVs1XTtcbiAgICAgICAgZGF0YVs1XSA9IHBhcnRpYWxzID8gY29tcG9zZUFyZ3NSaWdodChwYXJ0aWFscywgdmFsdWUsIHNvdXJjZVs2XSkgOiB2YWx1ZTtcbiAgICAgICAgZGF0YVs2XSA9IHBhcnRpYWxzID8gcmVwbGFjZUhvbGRlcnMoZGF0YVs1XSwgUExBQ0VIT0xERVIpIDogc291cmNlWzZdO1xuICAgICAgfVxuICAgICAgLy8gVXNlIHNvdXJjZSBgYXJnUG9zYCBpZiBhdmFpbGFibGUuXG4gICAgICB2YWx1ZSA9IHNvdXJjZVs3XTtcbiAgICAgIGlmICh2YWx1ZSkge1xuICAgICAgICBkYXRhWzddID0gdmFsdWU7XG4gICAgICB9XG4gICAgICAvLyBVc2Ugc291cmNlIGBhcnlgIGlmIGl0J3Mgc21hbGxlci5cbiAgICAgIGlmIChzcmNCaXRtYXNrICYgV1JBUF9BUllfRkxBRykge1xuICAgICAgICBkYXRhWzhdID0gZGF0YVs4XSA9PSBudWxsID8gc291cmNlWzhdIDogbmF0aXZlTWluKGRhdGFbOF0sIHNvdXJjZVs4XSk7XG4gICAgICB9XG4gICAgICAvLyBVc2Ugc291cmNlIGBhcml0eWAgaWYgb25lIGlzIG5vdCBwcm92aWRlZC5cbiAgICAgIGlmIChkYXRhWzldID09IG51bGwpIHtcbiAgICAgICAgZGF0YVs5XSA9IHNvdXJjZVs5XTtcbiAgICAgIH1cbiAgICAgIC8vIFVzZSBzb3VyY2UgYGZ1bmNgIGFuZCBtZXJnZSBiaXRtYXNrcy5cbiAgICAgIGRhdGFbMF0gPSBzb3VyY2VbMF07XG4gICAgICBkYXRhWzFdID0gbmV3Qml0bWFzaztcblxuICAgICAgcmV0dXJuIGRhdGE7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhpcyBmdW5jdGlvbiBpcyBsaWtlXG4gICAgICogW2BPYmplY3Qua2V5c2BdKGh0dHA6Ly9lY21hLWludGVybmF0aW9uYWwub3JnL2VjbWEtMjYyLzcuMC8jc2VjLW9iamVjdC5rZXlzKVxuICAgICAqIGV4Y2VwdCB0aGF0IGl0IGluY2x1ZGVzIGluaGVyaXRlZCBlbnVtZXJhYmxlIHByb3BlcnRpZXMuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBxdWVyeS5cbiAgICAgKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIGFycmF5IG9mIHByb3BlcnR5IG5hbWVzLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIG5hdGl2ZUtleXNJbihvYmplY3QpIHtcbiAgICAgIHZhciByZXN1bHQgPSBbXTtcbiAgICAgIGlmIChvYmplY3QgIT0gbnVsbCkge1xuICAgICAgICBmb3IgKHZhciBrZXkgaW4gT2JqZWN0KG9iamVjdCkpIHtcbiAgICAgICAgICByZXN1bHQucHVzaChrZXkpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENvbnZlcnRzIGB2YWx1ZWAgdG8gYSBzdHJpbmcgdXNpbmcgYE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmdgLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjb252ZXJ0LlxuICAgICAqIEByZXR1cm5zIHtzdHJpbmd9IFJldHVybnMgdGhlIGNvbnZlcnRlZCBzdHJpbmcuXG4gICAgICovXG4gICAgZnVuY3Rpb24gb2JqZWN0VG9TdHJpbmcodmFsdWUpIHtcbiAgICAgIHJldHVybiBuYXRpdmVPYmplY3RUb1N0cmluZy5jYWxsKHZhbHVlKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBBIHNwZWNpYWxpemVkIHZlcnNpb24gb2YgYGJhc2VSZXN0YCB3aGljaCB0cmFuc2Zvcm1zIHRoZSByZXN0IGFycmF5LlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBmdW5jIFRoZSBmdW5jdGlvbiB0byBhcHBseSBhIHJlc3QgcGFyYW1ldGVyIHRvLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbc3RhcnQ9ZnVuYy5sZW5ndGgtMV0gVGhlIHN0YXJ0IHBvc2l0aW9uIG9mIHRoZSByZXN0IHBhcmFtZXRlci5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSB0cmFuc2Zvcm0gVGhlIHJlc3QgYXJyYXkgdHJhbnNmb3JtLlxuICAgICAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyB0aGUgbmV3IGZ1bmN0aW9uLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIG92ZXJSZXN0KGZ1bmMsIHN0YXJ0LCB0cmFuc2Zvcm0pIHtcbiAgICAgIHN0YXJ0ID0gbmF0aXZlTWF4KHN0YXJ0ID09PSB1bmRlZmluZWQgPyAoZnVuYy5sZW5ndGggLSAxKSA6IHN0YXJ0LCAwKTtcbiAgICAgIHJldHVybiBmdW5jdGlvbigpIHtcbiAgICAgICAgdmFyIGFyZ3MgPSBhcmd1bWVudHMsXG4gICAgICAgICAgICBpbmRleCA9IC0xLFxuICAgICAgICAgICAgbGVuZ3RoID0gbmF0aXZlTWF4KGFyZ3MubGVuZ3RoIC0gc3RhcnQsIDApLFxuICAgICAgICAgICAgYXJyYXkgPSBBcnJheShsZW5ndGgpO1xuXG4gICAgICAgIHdoaWxlICgrK2luZGV4IDwgbGVuZ3RoKSB7XG4gICAgICAgICAgYXJyYXlbaW5kZXhdID0gYXJnc1tzdGFydCArIGluZGV4XTtcbiAgICAgICAgfVxuICAgICAgICBpbmRleCA9IC0xO1xuICAgICAgICB2YXIgb3RoZXJBcmdzID0gQXJyYXkoc3RhcnQgKyAxKTtcbiAgICAgICAgd2hpbGUgKCsraW5kZXggPCBzdGFydCkge1xuICAgICAgICAgIG90aGVyQXJnc1tpbmRleF0gPSBhcmdzW2luZGV4XTtcbiAgICAgICAgfVxuICAgICAgICBvdGhlckFyZ3Nbc3RhcnRdID0gdHJhbnNmb3JtKGFycmF5KTtcbiAgICAgICAgcmV0dXJuIGFwcGx5KGZ1bmMsIHRoaXMsIG90aGVyQXJncyk7XG4gICAgICB9O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEdldHMgdGhlIHBhcmVudCB2YWx1ZSBhdCBgcGF0aGAgb2YgYG9iamVjdGAuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBxdWVyeS5cbiAgICAgKiBAcGFyYW0ge0FycmF5fSBwYXRoIFRoZSBwYXRoIHRvIGdldCB0aGUgcGFyZW50IHZhbHVlIG9mLlxuICAgICAqIEByZXR1cm5zIHsqfSBSZXR1cm5zIHRoZSBwYXJlbnQgdmFsdWUuXG4gICAgICovXG4gICAgZnVuY3Rpb24gcGFyZW50KG9iamVjdCwgcGF0aCkge1xuICAgICAgcmV0dXJuIHBhdGgubGVuZ3RoIDwgMiA/IG9iamVjdCA6IGJhc2VHZXQob2JqZWN0LCBiYXNlU2xpY2UocGF0aCwgMCwgLTEpKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBSZW9yZGVyIGBhcnJheWAgYWNjb3JkaW5nIHRvIHRoZSBzcGVjaWZpZWQgaW5kZXhlcyB3aGVyZSB0aGUgZWxlbWVudCBhdFxuICAgICAqIHRoZSBmaXJzdCBpbmRleCBpcyBhc3NpZ25lZCBhcyB0aGUgZmlyc3QgZWxlbWVudCwgdGhlIGVsZW1lbnQgYXRcbiAgICAgKiB0aGUgc2Vjb25kIGluZGV4IGlzIGFzc2lnbmVkIGFzIHRoZSBzZWNvbmQgZWxlbWVudCwgYW5kIHNvIG9uLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBhcnJheSBUaGUgYXJyYXkgdG8gcmVvcmRlci5cbiAgICAgKiBAcGFyYW0ge0FycmF5fSBpbmRleGVzIFRoZSBhcnJhbmdlZCBhcnJheSBpbmRleGVzLlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyBgYXJyYXlgLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIHJlb3JkZXIoYXJyYXksIGluZGV4ZXMpIHtcbiAgICAgIHZhciBhcnJMZW5ndGggPSBhcnJheS5sZW5ndGgsXG4gICAgICAgICAgbGVuZ3RoID0gbmF0aXZlTWluKGluZGV4ZXMubGVuZ3RoLCBhcnJMZW5ndGgpLFxuICAgICAgICAgIG9sZEFycmF5ID0gY29weUFycmF5KGFycmF5KTtcblxuICAgICAgd2hpbGUgKGxlbmd0aC0tKSB7XG4gICAgICAgIHZhciBpbmRleCA9IGluZGV4ZXNbbGVuZ3RoXTtcbiAgICAgICAgYXJyYXlbbGVuZ3RoXSA9IGlzSW5kZXgoaW5kZXgsIGFyckxlbmd0aCkgPyBvbGRBcnJheVtpbmRleF0gOiB1bmRlZmluZWQ7XG4gICAgICB9XG4gICAgICByZXR1cm4gYXJyYXk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogU2V0cyBtZXRhZGF0YSBmb3IgYGZ1bmNgLlxuICAgICAqXG4gICAgICogKipOb3RlOioqIElmIHRoaXMgZnVuY3Rpb24gYmVjb21lcyBob3QsIGkuZS4gaXMgaW52b2tlZCBhIGxvdCBpbiBhIHNob3J0XG4gICAgICogcGVyaW9kIG9mIHRpbWUsIGl0IHdpbGwgdHJpcCBpdHMgYnJlYWtlciBhbmQgdHJhbnNpdGlvbiB0byBhbiBpZGVudGl0eVxuICAgICAqIGZ1bmN0aW9uIHRvIGF2b2lkIGdhcmJhZ2UgY29sbGVjdGlvbiBwYXVzZXMgaW4gVjguIFNlZVxuICAgICAqIFtWOCBpc3N1ZSAyMDcwXShodHRwczovL2J1Z3MuY2hyb21pdW0ub3JnL3AvdjgvaXNzdWVzL2RldGFpbD9pZD0yMDcwKVxuICAgICAqIGZvciBtb3JlIGRldGFpbHMuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IGZ1bmMgVGhlIGZ1bmN0aW9uIHRvIGFzc29jaWF0ZSBtZXRhZGF0YSB3aXRoLlxuICAgICAqIEBwYXJhbSB7Kn0gZGF0YSBUaGUgbWV0YWRhdGEuXG4gICAgICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIGBmdW5jYC5cbiAgICAgKi9cbiAgICB2YXIgc2V0RGF0YSA9IHNob3J0T3V0KGJhc2VTZXREYXRhKTtcblxuICAgIC8qKlxuICAgICAqIEEgc2ltcGxlIHdyYXBwZXIgYXJvdW5kIHRoZSBnbG9iYWwgW2BzZXRUaW1lb3V0YF0oaHR0cHM6Ly9tZG4uaW8vc2V0VGltZW91dCkuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IGZ1bmMgVGhlIGZ1bmN0aW9uIHRvIGRlbGF5LlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSB3YWl0IFRoZSBudW1iZXIgb2YgbWlsbGlzZWNvbmRzIHRvIGRlbGF5IGludm9jYXRpb24uXG4gICAgICogQHJldHVybnMge251bWJlcnxPYmplY3R9IFJldHVybnMgdGhlIHRpbWVyIGlkIG9yIHRpbWVvdXQgb2JqZWN0LlxuICAgICAqL1xuICAgIHZhciBzZXRUaW1lb3V0ID0gY3R4U2V0VGltZW91dCB8fCBmdW5jdGlvbihmdW5jLCB3YWl0KSB7XG4gICAgICByZXR1cm4gcm9vdC5zZXRUaW1lb3V0KGZ1bmMsIHdhaXQpO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBTZXRzIHRoZSBgdG9TdHJpbmdgIG1ldGhvZCBvZiBgZnVuY2AgdG8gcmV0dXJuIGBzdHJpbmdgLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBmdW5jIFRoZSBmdW5jdGlvbiB0byBtb2RpZnkuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gc3RyaW5nIFRoZSBgdG9TdHJpbmdgIHJlc3VsdC5cbiAgICAgKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgYGZ1bmNgLlxuICAgICAqL1xuICAgIHZhciBzZXRUb1N0cmluZyA9IHNob3J0T3V0KGJhc2VTZXRUb1N0cmluZyk7XG5cbiAgICAvKipcbiAgICAgKiBTZXRzIHRoZSBgdG9TdHJpbmdgIG1ldGhvZCBvZiBgd3JhcHBlcmAgdG8gbWltaWMgdGhlIHNvdXJjZSBvZiBgcmVmZXJlbmNlYFxuICAgICAqIHdpdGggd3JhcHBlciBkZXRhaWxzIGluIGEgY29tbWVudCBhdCB0aGUgdG9wIG9mIHRoZSBzb3VyY2UgYm9keS5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gd3JhcHBlciBUaGUgZnVuY3Rpb24gdG8gbW9kaWZ5LlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IHJlZmVyZW5jZSBUaGUgcmVmZXJlbmNlIGZ1bmN0aW9uLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBiaXRtYXNrIFRoZSBiaXRtYXNrIGZsYWdzLiBTZWUgYGNyZWF0ZVdyYXBgIGZvciBtb3JlIGRldGFpbHMuXG4gICAgICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIGB3cmFwcGVyYC5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBzZXRXcmFwVG9TdHJpbmcod3JhcHBlciwgcmVmZXJlbmNlLCBiaXRtYXNrKSB7XG4gICAgICB2YXIgc291cmNlID0gKHJlZmVyZW5jZSArICcnKTtcbiAgICAgIHJldHVybiBzZXRUb1N0cmluZyh3cmFwcGVyLCBpbnNlcnRXcmFwRGV0YWlscyhzb3VyY2UsIHVwZGF0ZVdyYXBEZXRhaWxzKGdldFdyYXBEZXRhaWxzKHNvdXJjZSksIGJpdG1hc2spKSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIGZ1bmN0aW9uIHRoYXQnbGwgc2hvcnQgb3V0IGFuZCBpbnZva2UgYGlkZW50aXR5YCBpbnN0ZWFkXG4gICAgICogb2YgYGZ1bmNgIHdoZW4gaXQncyBjYWxsZWQgYEhPVF9DT1VOVGAgb3IgbW9yZSB0aW1lcyBpbiBgSE9UX1NQQU5gXG4gICAgICogbWlsbGlzZWNvbmRzLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBmdW5jIFRoZSBmdW5jdGlvbiB0byByZXN0cmljdC5cbiAgICAgKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyBzaG9ydGFibGUgZnVuY3Rpb24uXG4gICAgICovXG4gICAgZnVuY3Rpb24gc2hvcnRPdXQoZnVuYykge1xuICAgICAgdmFyIGNvdW50ID0gMCxcbiAgICAgICAgICBsYXN0Q2FsbGVkID0gMDtcblxuICAgICAgcmV0dXJuIGZ1bmN0aW9uKCkge1xuICAgICAgICB2YXIgc3RhbXAgPSBuYXRpdmVOb3coKSxcbiAgICAgICAgICAgIHJlbWFpbmluZyA9IEhPVF9TUEFOIC0gKHN0YW1wIC0gbGFzdENhbGxlZCk7XG5cbiAgICAgICAgbGFzdENhbGxlZCA9IHN0YW1wO1xuICAgICAgICBpZiAocmVtYWluaW5nID4gMCkge1xuICAgICAgICAgIGlmICgrK2NvdW50ID49IEhPVF9DT1VOVCkge1xuICAgICAgICAgICAgcmV0dXJuIGFyZ3VtZW50c1swXTtcbiAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgY291bnQgPSAwO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBmdW5jLmFwcGx5KHVuZGVmaW5lZCwgYXJndW1lbnRzKTtcbiAgICAgIH07XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQSBzcGVjaWFsaXplZCB2ZXJzaW9uIG9mIGBfLnNodWZmbGVgIHdoaWNoIG11dGF0ZXMgYW5kIHNldHMgdGhlIHNpemUgb2YgYGFycmF5YC5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIHNodWZmbGUuXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IFtzaXplPWFycmF5Lmxlbmd0aF0gVGhlIHNpemUgb2YgYGFycmF5YC5cbiAgICAgKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgYGFycmF5YC5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBzaHVmZmxlU2VsZihhcnJheSwgc2l6ZSkge1xuICAgICAgdmFyIGluZGV4ID0gLTEsXG4gICAgICAgICAgbGVuZ3RoID0gYXJyYXkubGVuZ3RoLFxuICAgICAgICAgIGxhc3RJbmRleCA9IGxlbmd0aCAtIDE7XG5cbiAgICAgIHNpemUgPSBzaXplID09PSB1bmRlZmluZWQgPyBsZW5ndGggOiBzaXplO1xuICAgICAgd2hpbGUgKCsraW5kZXggPCBzaXplKSB7XG4gICAgICAgIHZhciByYW5kID0gYmFzZVJhbmRvbShpbmRleCwgbGFzdEluZGV4KSxcbiAgICAgICAgICAgIHZhbHVlID0gYXJyYXlbcmFuZF07XG5cbiAgICAgICAgYXJyYXlbcmFuZF0gPSBhcnJheVtpbmRleF07XG4gICAgICAgIGFycmF5W2luZGV4XSA9IHZhbHVlO1xuICAgICAgfVxuICAgICAgYXJyYXkubGVuZ3RoID0gc2l6ZTtcbiAgICAgIHJldHVybiBhcnJheTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDb252ZXJ0cyBgc3RyaW5nYCB0byBhIHByb3BlcnR5IHBhdGggYXJyYXkuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBzdHJpbmcgVGhlIHN0cmluZyB0byBjb252ZXJ0LlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgcHJvcGVydHkgcGF0aCBhcnJheS5cbiAgICAgKi9cbiAgICB2YXIgc3RyaW5nVG9QYXRoID0gbWVtb2l6ZUNhcHBlZChmdW5jdGlvbihzdHJpbmcpIHtcbiAgICAgIHZhciByZXN1bHQgPSBbXTtcbiAgICAgIGlmIChyZUxlYWRpbmdEb3QudGVzdChzdHJpbmcpKSB7XG4gICAgICAgIHJlc3VsdC5wdXNoKCcnKTtcbiAgICAgIH1cbiAgICAgIHN0cmluZy5yZXBsYWNlKHJlUHJvcE5hbWUsIGZ1bmN0aW9uKG1hdGNoLCBudW1iZXIsIHF1b3RlLCBzdHJpbmcpIHtcbiAgICAgICAgcmVzdWx0LnB1c2gocXVvdGUgPyBzdHJpbmcucmVwbGFjZShyZUVzY2FwZUNoYXIsICckMScpIDogKG51bWJlciB8fCBtYXRjaCkpO1xuICAgICAgfSk7XG4gICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH0pO1xuXG4gICAgLyoqXG4gICAgICogQ29udmVydHMgYHZhbHVlYCB0byBhIHN0cmluZyBrZXkgaWYgaXQncyBub3QgYSBzdHJpbmcgb3Igc3ltYm9sLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBpbnNwZWN0LlxuICAgICAqIEByZXR1cm5zIHtzdHJpbmd8c3ltYm9sfSBSZXR1cm5zIHRoZSBrZXkuXG4gICAgICovXG4gICAgZnVuY3Rpb24gdG9LZXkodmFsdWUpIHtcbiAgICAgIGlmICh0eXBlb2YgdmFsdWUgPT0gJ3N0cmluZycgfHwgaXNTeW1ib2wodmFsdWUpKSB7XG4gICAgICAgIHJldHVybiB2YWx1ZTtcbiAgICAgIH1cbiAgICAgIHZhciByZXN1bHQgPSAodmFsdWUgKyAnJyk7XG4gICAgICByZXR1cm4gKHJlc3VsdCA9PSAnMCcgJiYgKDEgLyB2YWx1ZSkgPT0gLUlORklOSVRZKSA/ICctMCcgOiByZXN1bHQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ29udmVydHMgYGZ1bmNgIHRvIGl0cyBzb3VyY2UgY29kZS5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gZnVuYyBUaGUgZnVuY3Rpb24gdG8gY29udmVydC5cbiAgICAgKiBAcmV0dXJucyB7c3RyaW5nfSBSZXR1cm5zIHRoZSBzb3VyY2UgY29kZS5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiB0b1NvdXJjZShmdW5jKSB7XG4gICAgICBpZiAoZnVuYyAhPSBudWxsKSB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgcmV0dXJuIGZ1bmNUb1N0cmluZy5jYWxsKGZ1bmMpO1xuICAgICAgICB9IGNhdGNoIChlKSB7fVxuICAgICAgICB0cnkge1xuICAgICAgICAgIHJldHVybiAoZnVuYyArICcnKTtcbiAgICAgICAgfSBjYXRjaCAoZSkge31cbiAgICAgIH1cbiAgICAgIHJldHVybiAnJztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBVcGRhdGVzIHdyYXBwZXIgYGRldGFpbHNgIGJhc2VkIG9uIGBiaXRtYXNrYCBmbGFncy5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHJldHVybnMge0FycmF5fSBkZXRhaWxzIFRoZSBkZXRhaWxzIHRvIG1vZGlmeS5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gYml0bWFzayBUaGUgYml0bWFzayBmbGFncy4gU2VlIGBjcmVhdGVXcmFwYCBmb3IgbW9yZSBkZXRhaWxzLlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyBgZGV0YWlsc2AuXG4gICAgICovXG4gICAgZnVuY3Rpb24gdXBkYXRlV3JhcERldGFpbHMoZGV0YWlscywgYml0bWFzaykge1xuICAgICAgYXJyYXlFYWNoKHdyYXBGbGFncywgZnVuY3Rpb24ocGFpcikge1xuICAgICAgICB2YXIgdmFsdWUgPSAnXy4nICsgcGFpclswXTtcbiAgICAgICAgaWYgKChiaXRtYXNrICYgcGFpclsxXSkgJiYgIWFycmF5SW5jbHVkZXMoZGV0YWlscywgdmFsdWUpKSB7XG4gICAgICAgICAgZGV0YWlscy5wdXNoKHZhbHVlKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgICByZXR1cm4gZGV0YWlscy5zb3J0KCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIGNsb25lIG9mIGB3cmFwcGVyYC5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtPYmplY3R9IHdyYXBwZXIgVGhlIHdyYXBwZXIgdG8gY2xvbmUuXG4gICAgICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyB0aGUgY2xvbmVkIHdyYXBwZXIuXG4gICAgICovXG4gICAgZnVuY3Rpb24gd3JhcHBlckNsb25lKHdyYXBwZXIpIHtcbiAgICAgIGlmICh3cmFwcGVyIGluc3RhbmNlb2YgTGF6eVdyYXBwZXIpIHtcbiAgICAgICAgcmV0dXJuIHdyYXBwZXIuY2xvbmUoKTtcbiAgICAgIH1cbiAgICAgIHZhciByZXN1bHQgPSBuZXcgTG9kYXNoV3JhcHBlcih3cmFwcGVyLl9fd3JhcHBlZF9fLCB3cmFwcGVyLl9fY2hhaW5fXyk7XG4gICAgICByZXN1bHQuX19hY3Rpb25zX18gPSBjb3B5QXJyYXkod3JhcHBlci5fX2FjdGlvbnNfXyk7XG4gICAgICByZXN1bHQuX19pbmRleF9fICA9IHdyYXBwZXIuX19pbmRleF9fO1xuICAgICAgcmVzdWx0Ll9fdmFsdWVzX18gPSB3cmFwcGVyLl9fdmFsdWVzX187XG4gICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH1cblxuICAgIC8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi9cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYW4gYXJyYXkgb2YgZWxlbWVudHMgc3BsaXQgaW50byBncm91cHMgdGhlIGxlbmd0aCBvZiBgc2l6ZWAuXG4gICAgICogSWYgYGFycmF5YCBjYW4ndCBiZSBzcGxpdCBldmVubHksIHRoZSBmaW5hbCBjaHVuayB3aWxsIGJlIHRoZSByZW1haW5pbmdcbiAgICAgKiBlbGVtZW50cy5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAzLjAuMFxuICAgICAqIEBjYXRlZ29yeSBBcnJheVxuICAgICAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBhcnJheSB0byBwcm9jZXNzLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbc2l6ZT0xXSBUaGUgbGVuZ3RoIG9mIGVhY2ggY2h1bmtcbiAgICAgKiBAcGFyYW0tIHtPYmplY3R9IFtndWFyZF0gRW5hYmxlcyB1c2UgYXMgYW4gaXRlcmF0ZWUgZm9yIG1ldGhvZHMgbGlrZSBgXy5tYXBgLlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgbmV3IGFycmF5IG9mIGNodW5rcy5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy5jaHVuayhbJ2EnLCAnYicsICdjJywgJ2QnXSwgMik7XG4gICAgICogLy8gPT4gW1snYScsICdiJ10sIFsnYycsICdkJ11dXG4gICAgICpcbiAgICAgKiBfLmNodW5rKFsnYScsICdiJywgJ2MnLCAnZCddLCAzKTtcbiAgICAgKiAvLyA9PiBbWydhJywgJ2InLCAnYyddLCBbJ2QnXV1cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBjaHVuayhhcnJheSwgc2l6ZSwgZ3VhcmQpIHtcbiAgICAgIGlmICgoZ3VhcmQgPyBpc0l0ZXJhdGVlQ2FsbChhcnJheSwgc2l6ZSwgZ3VhcmQpIDogc2l6ZSA9PT0gdW5kZWZpbmVkKSkge1xuICAgICAgICBzaXplID0gMTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHNpemUgPSBuYXRpdmVNYXgodG9JbnRlZ2VyKHNpemUpLCAwKTtcbiAgICAgIH1cbiAgICAgIHZhciBsZW5ndGggPSBhcnJheSA9PSBudWxsID8gMCA6IGFycmF5Lmxlbmd0aDtcbiAgICAgIGlmICghbGVuZ3RoIHx8IHNpemUgPCAxKSB7XG4gICAgICAgIHJldHVybiBbXTtcbiAgICAgIH1cbiAgICAgIHZhciBpbmRleCA9IDAsXG4gICAgICAgICAgcmVzSW5kZXggPSAwLFxuICAgICAgICAgIHJlc3VsdCA9IEFycmF5KG5hdGl2ZUNlaWwobGVuZ3RoIC8gc2l6ZSkpO1xuXG4gICAgICB3aGlsZSAoaW5kZXggPCBsZW5ndGgpIHtcbiAgICAgICAgcmVzdWx0W3Jlc0luZGV4KytdID0gYmFzZVNsaWNlKGFycmF5LCBpbmRleCwgKGluZGV4ICs9IHNpemUpKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhbiBhcnJheSB3aXRoIGFsbCBmYWxzZXkgdmFsdWVzIHJlbW92ZWQuIFRoZSB2YWx1ZXMgYGZhbHNlYCwgYG51bGxgLFxuICAgICAqIGAwYCwgYFwiXCJgLCBgdW5kZWZpbmVkYCwgYW5kIGBOYU5gIGFyZSBmYWxzZXkuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMC4xLjBcbiAgICAgKiBAY2F0ZWdvcnkgQXJyYXlcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBhcnJheSBUaGUgYXJyYXkgdG8gY29tcGFjdC5cbiAgICAgKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIG5ldyBhcnJheSBvZiBmaWx0ZXJlZCB2YWx1ZXMuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8uY29tcGFjdChbMCwgMSwgZmFsc2UsIDIsICcnLCAzXSk7XG4gICAgICogLy8gPT4gWzEsIDIsIDNdXG4gICAgICovXG4gICAgZnVuY3Rpb24gY29tcGFjdChhcnJheSkge1xuICAgICAgdmFyIGluZGV4ID0gLTEsXG4gICAgICAgICAgbGVuZ3RoID0gYXJyYXkgPT0gbnVsbCA/IDAgOiBhcnJheS5sZW5ndGgsXG4gICAgICAgICAgcmVzSW5kZXggPSAwLFxuICAgICAgICAgIHJlc3VsdCA9IFtdO1xuXG4gICAgICB3aGlsZSAoKytpbmRleCA8IGxlbmd0aCkge1xuICAgICAgICB2YXIgdmFsdWUgPSBhcnJheVtpbmRleF07XG4gICAgICAgIGlmICh2YWx1ZSkge1xuICAgICAgICAgIHJlc3VsdFtyZXNJbmRleCsrXSA9IHZhbHVlO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBuZXcgYXJyYXkgY29uY2F0ZW5hdGluZyBgYXJyYXlgIHdpdGggYW55IGFkZGl0aW9uYWwgYXJyYXlzXG4gICAgICogYW5kL29yIHZhbHVlcy5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSA0LjAuMFxuICAgICAqIEBjYXRlZ29yeSBBcnJheVxuICAgICAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBhcnJheSB0byBjb25jYXRlbmF0ZS5cbiAgICAgKiBAcGFyYW0gey4uLip9IFt2YWx1ZXNdIFRoZSB2YWx1ZXMgdG8gY29uY2F0ZW5hdGUuXG4gICAgICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBuZXcgY29uY2F0ZW5hdGVkIGFycmF5LlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiB2YXIgYXJyYXkgPSBbMV07XG4gICAgICogdmFyIG90aGVyID0gXy5jb25jYXQoYXJyYXksIDIsIFszXSwgW1s0XV0pO1xuICAgICAqXG4gICAgICogY29uc29sZS5sb2cob3RoZXIpO1xuICAgICAqIC8vID0+IFsxLCAyLCAzLCBbNF1dXG4gICAgICpcbiAgICAgKiBjb25zb2xlLmxvZyhhcnJheSk7XG4gICAgICogLy8gPT4gWzFdXG4gICAgICovXG4gICAgZnVuY3Rpb24gY29uY2F0KCkge1xuICAgICAgdmFyIGxlbmd0aCA9IGFyZ3VtZW50cy5sZW5ndGg7XG4gICAgICBpZiAoIWxlbmd0aCkge1xuICAgICAgICByZXR1cm4gW107XG4gICAgICB9XG4gICAgICB2YXIgYXJncyA9IEFycmF5KGxlbmd0aCAtIDEpLFxuICAgICAgICAgIGFycmF5ID0gYXJndW1lbnRzWzBdLFxuICAgICAgICAgIGluZGV4ID0gbGVuZ3RoO1xuXG4gICAgICB3aGlsZSAoaW5kZXgtLSkge1xuICAgICAgICBhcmdzW2luZGV4IC0gMV0gPSBhcmd1bWVudHNbaW5kZXhdO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGFycmF5UHVzaChpc0FycmF5KGFycmF5KSA/IGNvcHlBcnJheShhcnJheSkgOiBbYXJyYXldLCBiYXNlRmxhdHRlbihhcmdzLCAxKSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhbiBhcnJheSBvZiBgYXJyYXlgIHZhbHVlcyBub3QgaW5jbHVkZWQgaW4gdGhlIG90aGVyIGdpdmVuIGFycmF5c1xuICAgICAqIHVzaW5nIFtgU2FtZVZhbHVlWmVyb2BdKGh0dHA6Ly9lY21hLWludGVybmF0aW9uYWwub3JnL2VjbWEtMjYyLzcuMC8jc2VjLXNhbWV2YWx1ZXplcm8pXG4gICAgICogZm9yIGVxdWFsaXR5IGNvbXBhcmlzb25zLiBUaGUgb3JkZXIgYW5kIHJlZmVyZW5jZXMgb2YgcmVzdWx0IHZhbHVlcyBhcmVcbiAgICAgKiBkZXRlcm1pbmVkIGJ5IHRoZSBmaXJzdCBhcnJheS5cbiAgICAgKlxuICAgICAqICoqTm90ZToqKiBVbmxpa2UgYF8ucHVsbEFsbGAsIHRoaXMgbWV0aG9kIHJldHVybnMgYSBuZXcgYXJyYXkuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMC4xLjBcbiAgICAgKiBAY2F0ZWdvcnkgQXJyYXlcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBhcnJheSBUaGUgYXJyYXkgdG8gaW5zcGVjdC5cbiAgICAgKiBAcGFyYW0gey4uLkFycmF5fSBbdmFsdWVzXSBUaGUgdmFsdWVzIHRvIGV4Y2x1ZGUuXG4gICAgICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBuZXcgYXJyYXkgb2YgZmlsdGVyZWQgdmFsdWVzLlxuICAgICAqIEBzZWUgXy53aXRob3V0LCBfLnhvclxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLmRpZmZlcmVuY2UoWzIsIDFdLCBbMiwgM10pO1xuICAgICAqIC8vID0+IFsxXVxuICAgICAqL1xuICAgIHZhciBkaWZmZXJlbmNlID0gYmFzZVJlc3QoZnVuY3Rpb24oYXJyYXksIHZhbHVlcykge1xuICAgICAgcmV0dXJuIGlzQXJyYXlMaWtlT2JqZWN0KGFycmF5KVxuICAgICAgICA/IGJhc2VEaWZmZXJlbmNlKGFycmF5LCBiYXNlRmxhdHRlbih2YWx1ZXMsIDEsIGlzQXJyYXlMaWtlT2JqZWN0LCB0cnVlKSlcbiAgICAgICAgOiBbXTtcbiAgICB9KTtcblxuICAgIC8qKlxuICAgICAqIFRoaXMgbWV0aG9kIGlzIGxpa2UgYF8uZGlmZmVyZW5jZWAgZXhjZXB0IHRoYXQgaXQgYWNjZXB0cyBgaXRlcmF0ZWVgIHdoaWNoXG4gICAgICogaXMgaW52b2tlZCBmb3IgZWFjaCBlbGVtZW50IG9mIGBhcnJheWAgYW5kIGB2YWx1ZXNgIHRvIGdlbmVyYXRlIHRoZSBjcml0ZXJpb25cbiAgICAgKiBieSB3aGljaCB0aGV5J3JlIGNvbXBhcmVkLiBUaGUgb3JkZXIgYW5kIHJlZmVyZW5jZXMgb2YgcmVzdWx0IHZhbHVlcyBhcmVcbiAgICAgKiBkZXRlcm1pbmVkIGJ5IHRoZSBmaXJzdCBhcnJheS4gVGhlIGl0ZXJhdGVlIGlzIGludm9rZWQgd2l0aCBvbmUgYXJndW1lbnQ6XG4gICAgICogKHZhbHVlKS5cbiAgICAgKlxuICAgICAqICoqTm90ZToqKiBVbmxpa2UgYF8ucHVsbEFsbEJ5YCwgdGhpcyBtZXRob2QgcmV0dXJucyBhIG5ldyBhcnJheS5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSA0LjAuMFxuICAgICAqIEBjYXRlZ29yeSBBcnJheVxuICAgICAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBhcnJheSB0byBpbnNwZWN0LlxuICAgICAqIEBwYXJhbSB7Li4uQXJyYXl9IFt2YWx1ZXNdIFRoZSB2YWx1ZXMgdG8gZXhjbHVkZS5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBbaXRlcmF0ZWU9Xy5pZGVudGl0eV0gVGhlIGl0ZXJhdGVlIGludm9rZWQgcGVyIGVsZW1lbnQuXG4gICAgICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBuZXcgYXJyYXkgb2YgZmlsdGVyZWQgdmFsdWVzLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLmRpZmZlcmVuY2VCeShbMi4xLCAxLjJdLCBbMi4zLCAzLjRdLCBNYXRoLmZsb29yKTtcbiAgICAgKiAvLyA9PiBbMS4yXVxuICAgICAqXG4gICAgICogLy8gVGhlIGBfLnByb3BlcnR5YCBpdGVyYXRlZSBzaG9ydGhhbmQuXG4gICAgICogXy5kaWZmZXJlbmNlQnkoW3sgJ3gnOiAyIH0sIHsgJ3gnOiAxIH1dLCBbeyAneCc6IDEgfV0sICd4Jyk7XG4gICAgICogLy8gPT4gW3sgJ3gnOiAyIH1dXG4gICAgICovXG4gICAgdmFyIGRpZmZlcmVuY2VCeSA9IGJhc2VSZXN0KGZ1bmN0aW9uKGFycmF5LCB2YWx1ZXMpIHtcbiAgICAgIHZhciBpdGVyYXRlZSA9IGxhc3QodmFsdWVzKTtcbiAgICAgIGlmIChpc0FycmF5TGlrZU9iamVjdChpdGVyYXRlZSkpIHtcbiAgICAgICAgaXRlcmF0ZWUgPSB1bmRlZmluZWQ7XG4gICAgICB9XG4gICAgICByZXR1cm4gaXNBcnJheUxpa2VPYmplY3QoYXJyYXkpXG4gICAgICAgID8gYmFzZURpZmZlcmVuY2UoYXJyYXksIGJhc2VGbGF0dGVuKHZhbHVlcywgMSwgaXNBcnJheUxpa2VPYmplY3QsIHRydWUpLCBnZXRJdGVyYXRlZShpdGVyYXRlZSwgMikpXG4gICAgICAgIDogW107XG4gICAgfSk7XG5cbiAgICAvKipcbiAgICAgKiBUaGlzIG1ldGhvZCBpcyBsaWtlIGBfLmRpZmZlcmVuY2VgIGV4Y2VwdCB0aGF0IGl0IGFjY2VwdHMgYGNvbXBhcmF0b3JgXG4gICAgICogd2hpY2ggaXMgaW52b2tlZCB0byBjb21wYXJlIGVsZW1lbnRzIG9mIGBhcnJheWAgdG8gYHZhbHVlc2AuIFRoZSBvcmRlciBhbmRcbiAgICAgKiByZWZlcmVuY2VzIG9mIHJlc3VsdCB2YWx1ZXMgYXJlIGRldGVybWluZWQgYnkgdGhlIGZpcnN0IGFycmF5LiBUaGUgY29tcGFyYXRvclxuICAgICAqIGlzIGludm9rZWQgd2l0aCB0d28gYXJndW1lbnRzOiAoYXJyVmFsLCBvdGhWYWwpLlxuICAgICAqXG4gICAgICogKipOb3RlOioqIFVubGlrZSBgXy5wdWxsQWxsV2l0aGAsIHRoaXMgbWV0aG9kIHJldHVybnMgYSBuZXcgYXJyYXkuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgNC4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgQXJyYXlcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBhcnJheSBUaGUgYXJyYXkgdG8gaW5zcGVjdC5cbiAgICAgKiBAcGFyYW0gey4uLkFycmF5fSBbdmFsdWVzXSBUaGUgdmFsdWVzIHRvIGV4Y2x1ZGUuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gW2NvbXBhcmF0b3JdIFRoZSBjb21wYXJhdG9yIGludm9rZWQgcGVyIGVsZW1lbnQuXG4gICAgICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBuZXcgYXJyYXkgb2YgZmlsdGVyZWQgdmFsdWVzLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiB2YXIgb2JqZWN0cyA9IFt7ICd4JzogMSwgJ3knOiAyIH0sIHsgJ3gnOiAyLCAneSc6IDEgfV07XG4gICAgICpcbiAgICAgKiBfLmRpZmZlcmVuY2VXaXRoKG9iamVjdHMsIFt7ICd4JzogMSwgJ3knOiAyIH1dLCBfLmlzRXF1YWwpO1xuICAgICAqIC8vID0+IFt7ICd4JzogMiwgJ3knOiAxIH1dXG4gICAgICovXG4gICAgdmFyIGRpZmZlcmVuY2VXaXRoID0gYmFzZVJlc3QoZnVuY3Rpb24oYXJyYXksIHZhbHVlcykge1xuICAgICAgdmFyIGNvbXBhcmF0b3IgPSBsYXN0KHZhbHVlcyk7XG4gICAgICBpZiAoaXNBcnJheUxpa2VPYmplY3QoY29tcGFyYXRvcikpIHtcbiAgICAgICAgY29tcGFyYXRvciA9IHVuZGVmaW5lZDtcbiAgICAgIH1cbiAgICAgIHJldHVybiBpc0FycmF5TGlrZU9iamVjdChhcnJheSlcbiAgICAgICAgPyBiYXNlRGlmZmVyZW5jZShhcnJheSwgYmFzZUZsYXR0ZW4odmFsdWVzLCAxLCBpc0FycmF5TGlrZU9iamVjdCwgdHJ1ZSksIHVuZGVmaW5lZCwgY29tcGFyYXRvcilcbiAgICAgICAgOiBbXTtcbiAgICB9KTtcblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBzbGljZSBvZiBgYXJyYXlgIHdpdGggYG5gIGVsZW1lbnRzIGRyb3BwZWQgZnJvbSB0aGUgYmVnaW5uaW5nLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDAuNS4wXG4gICAgICogQGNhdGVnb3J5IEFycmF5XG4gICAgICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIHF1ZXJ5LlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbbj0xXSBUaGUgbnVtYmVyIG9mIGVsZW1lbnRzIHRvIGRyb3AuXG4gICAgICogQHBhcmFtLSB7T2JqZWN0fSBbZ3VhcmRdIEVuYWJsZXMgdXNlIGFzIGFuIGl0ZXJhdGVlIGZvciBtZXRob2RzIGxpa2UgYF8ubWFwYC5cbiAgICAgKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIHNsaWNlIG9mIGBhcnJheWAuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8uZHJvcChbMSwgMiwgM10pO1xuICAgICAqIC8vID0+IFsyLCAzXVxuICAgICAqXG4gICAgICogXy5kcm9wKFsxLCAyLCAzXSwgMik7XG4gICAgICogLy8gPT4gWzNdXG4gICAgICpcbiAgICAgKiBfLmRyb3AoWzEsIDIsIDNdLCA1KTtcbiAgICAgKiAvLyA9PiBbXVxuICAgICAqXG4gICAgICogXy5kcm9wKFsxLCAyLCAzXSwgMCk7XG4gICAgICogLy8gPT4gWzEsIDIsIDNdXG4gICAgICovXG4gICAgZnVuY3Rpb24gZHJvcChhcnJheSwgbiwgZ3VhcmQpIHtcbiAgICAgIHZhciBsZW5ndGggPSBhcnJheSA9PSBudWxsID8gMCA6IGFycmF5Lmxlbmd0aDtcbiAgICAgIGlmICghbGVuZ3RoKSB7XG4gICAgICAgIHJldHVybiBbXTtcbiAgICAgIH1cbiAgICAgIG4gPSAoZ3VhcmQgfHwgbiA9PT0gdW5kZWZpbmVkKSA/IDEgOiB0b0ludGVnZXIobik7XG4gICAgICByZXR1cm4gYmFzZVNsaWNlKGFycmF5LCBuIDwgMCA/IDAgOiBuLCBsZW5ndGgpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBzbGljZSBvZiBgYXJyYXlgIHdpdGggYG5gIGVsZW1lbnRzIGRyb3BwZWQgZnJvbSB0aGUgZW5kLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDMuMC4wXG4gICAgICogQGNhdGVnb3J5IEFycmF5XG4gICAgICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIHF1ZXJ5LlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbbj0xXSBUaGUgbnVtYmVyIG9mIGVsZW1lbnRzIHRvIGRyb3AuXG4gICAgICogQHBhcmFtLSB7T2JqZWN0fSBbZ3VhcmRdIEVuYWJsZXMgdXNlIGFzIGFuIGl0ZXJhdGVlIGZvciBtZXRob2RzIGxpa2UgYF8ubWFwYC5cbiAgICAgKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIHNsaWNlIG9mIGBhcnJheWAuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8uZHJvcFJpZ2h0KFsxLCAyLCAzXSk7XG4gICAgICogLy8gPT4gWzEsIDJdXG4gICAgICpcbiAgICAgKiBfLmRyb3BSaWdodChbMSwgMiwgM10sIDIpO1xuICAgICAqIC8vID0+IFsxXVxuICAgICAqXG4gICAgICogXy5kcm9wUmlnaHQoWzEsIDIsIDNdLCA1KTtcbiAgICAgKiAvLyA9PiBbXVxuICAgICAqXG4gICAgICogXy5kcm9wUmlnaHQoWzEsIDIsIDNdLCAwKTtcbiAgICAgKiAvLyA9PiBbMSwgMiwgM11cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBkcm9wUmlnaHQoYXJyYXksIG4sIGd1YXJkKSB7XG4gICAgICB2YXIgbGVuZ3RoID0gYXJyYXkgPT0gbnVsbCA/IDAgOiBhcnJheS5sZW5ndGg7XG4gICAgICBpZiAoIWxlbmd0aCkge1xuICAgICAgICByZXR1cm4gW107XG4gICAgICB9XG4gICAgICBuID0gKGd1YXJkIHx8IG4gPT09IHVuZGVmaW5lZCkgPyAxIDogdG9JbnRlZ2VyKG4pO1xuICAgICAgbiA9IGxlbmd0aCAtIG47XG4gICAgICByZXR1cm4gYmFzZVNsaWNlKGFycmF5LCAwLCBuIDwgMCA/IDAgOiBuKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgc2xpY2Ugb2YgYGFycmF5YCBleGNsdWRpbmcgZWxlbWVudHMgZHJvcHBlZCBmcm9tIHRoZSBlbmQuXG4gICAgICogRWxlbWVudHMgYXJlIGRyb3BwZWQgdW50aWwgYHByZWRpY2F0ZWAgcmV0dXJucyBmYWxzZXkuIFRoZSBwcmVkaWNhdGUgaXNcbiAgICAgKiBpbnZva2VkIHdpdGggdGhyZWUgYXJndW1lbnRzOiAodmFsdWUsIGluZGV4LCBhcnJheSkuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMy4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgQXJyYXlcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBhcnJheSBUaGUgYXJyYXkgdG8gcXVlcnkuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gW3ByZWRpY2F0ZT1fLmlkZW50aXR5XSBUaGUgZnVuY3Rpb24gaW52b2tlZCBwZXIgaXRlcmF0aW9uLlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgc2xpY2Ugb2YgYGFycmF5YC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogdmFyIHVzZXJzID0gW1xuICAgICAqICAgeyAndXNlcic6ICdiYXJuZXknLCAgJ2FjdGl2ZSc6IHRydWUgfSxcbiAgICAgKiAgIHsgJ3VzZXInOiAnZnJlZCcsICAgICdhY3RpdmUnOiBmYWxzZSB9LFxuICAgICAqICAgeyAndXNlcic6ICdwZWJibGVzJywgJ2FjdGl2ZSc6IGZhbHNlIH1cbiAgICAgKiBdO1xuICAgICAqXG4gICAgICogXy5kcm9wUmlnaHRXaGlsZSh1c2VycywgZnVuY3Rpb24obykgeyByZXR1cm4gIW8uYWN0aXZlOyB9KTtcbiAgICAgKiAvLyA9PiBvYmplY3RzIGZvciBbJ2Jhcm5leSddXG4gICAgICpcbiAgICAgKiAvLyBUaGUgYF8ubWF0Y2hlc2AgaXRlcmF0ZWUgc2hvcnRoYW5kLlxuICAgICAqIF8uZHJvcFJpZ2h0V2hpbGUodXNlcnMsIHsgJ3VzZXInOiAncGViYmxlcycsICdhY3RpdmUnOiBmYWxzZSB9KTtcbiAgICAgKiAvLyA9PiBvYmplY3RzIGZvciBbJ2Jhcm5leScsICdmcmVkJ11cbiAgICAgKlxuICAgICAqIC8vIFRoZSBgXy5tYXRjaGVzUHJvcGVydHlgIGl0ZXJhdGVlIHNob3J0aGFuZC5cbiAgICAgKiBfLmRyb3BSaWdodFdoaWxlKHVzZXJzLCBbJ2FjdGl2ZScsIGZhbHNlXSk7XG4gICAgICogLy8gPT4gb2JqZWN0cyBmb3IgWydiYXJuZXknXVxuICAgICAqXG4gICAgICogLy8gVGhlIGBfLnByb3BlcnR5YCBpdGVyYXRlZSBzaG9ydGhhbmQuXG4gICAgICogXy5kcm9wUmlnaHRXaGlsZSh1c2VycywgJ2FjdGl2ZScpO1xuICAgICAqIC8vID0+IG9iamVjdHMgZm9yIFsnYmFybmV5JywgJ2ZyZWQnLCAncGViYmxlcyddXG4gICAgICovXG4gICAgZnVuY3Rpb24gZHJvcFJpZ2h0V2hpbGUoYXJyYXksIHByZWRpY2F0ZSkge1xuICAgICAgcmV0dXJuIChhcnJheSAmJiBhcnJheS5sZW5ndGgpXG4gICAgICAgID8gYmFzZVdoaWxlKGFycmF5LCBnZXRJdGVyYXRlZShwcmVkaWNhdGUsIDMpLCB0cnVlLCB0cnVlKVxuICAgICAgICA6IFtdO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBzbGljZSBvZiBgYXJyYXlgIGV4Y2x1ZGluZyBlbGVtZW50cyBkcm9wcGVkIGZyb20gdGhlIGJlZ2lubmluZy5cbiAgICAgKiBFbGVtZW50cyBhcmUgZHJvcHBlZCB1bnRpbCBgcHJlZGljYXRlYCByZXR1cm5zIGZhbHNleS4gVGhlIHByZWRpY2F0ZSBpc1xuICAgICAqIGludm9rZWQgd2l0aCB0aHJlZSBhcmd1bWVudHM6ICh2YWx1ZSwgaW5kZXgsIGFycmF5KS5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAzLjAuMFxuICAgICAqIEBjYXRlZ29yeSBBcnJheVxuICAgICAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBhcnJheSB0byBxdWVyeS5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBbcHJlZGljYXRlPV8uaWRlbnRpdHldIFRoZSBmdW5jdGlvbiBpbnZva2VkIHBlciBpdGVyYXRpb24uXG4gICAgICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBzbGljZSBvZiBgYXJyYXlgLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiB2YXIgdXNlcnMgPSBbXG4gICAgICogICB7ICd1c2VyJzogJ2Jhcm5leScsICAnYWN0aXZlJzogZmFsc2UgfSxcbiAgICAgKiAgIHsgJ3VzZXInOiAnZnJlZCcsICAgICdhY3RpdmUnOiBmYWxzZSB9LFxuICAgICAqICAgeyAndXNlcic6ICdwZWJibGVzJywgJ2FjdGl2ZSc6IHRydWUgfVxuICAgICAqIF07XG4gICAgICpcbiAgICAgKiBfLmRyb3BXaGlsZSh1c2VycywgZnVuY3Rpb24obykgeyByZXR1cm4gIW8uYWN0aXZlOyB9KTtcbiAgICAgKiAvLyA9PiBvYmplY3RzIGZvciBbJ3BlYmJsZXMnXVxuICAgICAqXG4gICAgICogLy8gVGhlIGBfLm1hdGNoZXNgIGl0ZXJhdGVlIHNob3J0aGFuZC5cbiAgICAgKiBfLmRyb3BXaGlsZSh1c2VycywgeyAndXNlcic6ICdiYXJuZXknLCAnYWN0aXZlJzogZmFsc2UgfSk7XG4gICAgICogLy8gPT4gb2JqZWN0cyBmb3IgWydmcmVkJywgJ3BlYmJsZXMnXVxuICAgICAqXG4gICAgICogLy8gVGhlIGBfLm1hdGNoZXNQcm9wZXJ0eWAgaXRlcmF0ZWUgc2hvcnRoYW5kLlxuICAgICAqIF8uZHJvcFdoaWxlKHVzZXJzLCBbJ2FjdGl2ZScsIGZhbHNlXSk7XG4gICAgICogLy8gPT4gb2JqZWN0cyBmb3IgWydwZWJibGVzJ11cbiAgICAgKlxuICAgICAqIC8vIFRoZSBgXy5wcm9wZXJ0eWAgaXRlcmF0ZWUgc2hvcnRoYW5kLlxuICAgICAqIF8uZHJvcFdoaWxlKHVzZXJzLCAnYWN0aXZlJyk7XG4gICAgICogLy8gPT4gb2JqZWN0cyBmb3IgWydiYXJuZXknLCAnZnJlZCcsICdwZWJibGVzJ11cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBkcm9wV2hpbGUoYXJyYXksIHByZWRpY2F0ZSkge1xuICAgICAgcmV0dXJuIChhcnJheSAmJiBhcnJheS5sZW5ndGgpXG4gICAgICAgID8gYmFzZVdoaWxlKGFycmF5LCBnZXRJdGVyYXRlZShwcmVkaWNhdGUsIDMpLCB0cnVlKVxuICAgICAgICA6IFtdO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEZpbGxzIGVsZW1lbnRzIG9mIGBhcnJheWAgd2l0aCBgdmFsdWVgIGZyb20gYHN0YXJ0YCB1cCB0bywgYnV0IG5vdFxuICAgICAqIGluY2x1ZGluZywgYGVuZGAuXG4gICAgICpcbiAgICAgKiAqKk5vdGU6KiogVGhpcyBtZXRob2QgbXV0YXRlcyBgYXJyYXlgLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDMuMi4wXG4gICAgICogQGNhdGVnb3J5IEFycmF5XG4gICAgICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIGZpbGwuXG4gICAgICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gZmlsbCBgYXJyYXlgIHdpdGguXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IFtzdGFydD0wXSBUaGUgc3RhcnQgcG9zaXRpb24uXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IFtlbmQ9YXJyYXkubGVuZ3RoXSBUaGUgZW5kIHBvc2l0aW9uLlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyBgYXJyYXlgLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiB2YXIgYXJyYXkgPSBbMSwgMiwgM107XG4gICAgICpcbiAgICAgKiBfLmZpbGwoYXJyYXksICdhJyk7XG4gICAgICogY29uc29sZS5sb2coYXJyYXkpO1xuICAgICAqIC8vID0+IFsnYScsICdhJywgJ2EnXVxuICAgICAqXG4gICAgICogXy5maWxsKEFycmF5KDMpLCAyKTtcbiAgICAgKiAvLyA9PiBbMiwgMiwgMl1cbiAgICAgKlxuICAgICAqIF8uZmlsbChbNCwgNiwgOCwgMTBdLCAnKicsIDEsIDMpO1xuICAgICAqIC8vID0+IFs0LCAnKicsICcqJywgMTBdXG4gICAgICovXG4gICAgZnVuY3Rpb24gZmlsbChhcnJheSwgdmFsdWUsIHN0YXJ0LCBlbmQpIHtcbiAgICAgIHZhciBsZW5ndGggPSBhcnJheSA9PSBudWxsID8gMCA6IGFycmF5Lmxlbmd0aDtcbiAgICAgIGlmICghbGVuZ3RoKSB7XG4gICAgICAgIHJldHVybiBbXTtcbiAgICAgIH1cbiAgICAgIGlmIChzdGFydCAmJiB0eXBlb2Ygc3RhcnQgIT0gJ251bWJlcicgJiYgaXNJdGVyYXRlZUNhbGwoYXJyYXksIHZhbHVlLCBzdGFydCkpIHtcbiAgICAgICAgc3RhcnQgPSAwO1xuICAgICAgICBlbmQgPSBsZW5ndGg7XG4gICAgICB9XG4gICAgICByZXR1cm4gYmFzZUZpbGwoYXJyYXksIHZhbHVlLCBzdGFydCwgZW5kKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGlzIG1ldGhvZCBpcyBsaWtlIGBfLmZpbmRgIGV4Y2VwdCB0aGF0IGl0IHJldHVybnMgdGhlIGluZGV4IG9mIHRoZSBmaXJzdFxuICAgICAqIGVsZW1lbnQgYHByZWRpY2F0ZWAgcmV0dXJucyB0cnV0aHkgZm9yIGluc3RlYWQgb2YgdGhlIGVsZW1lbnQgaXRzZWxmLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDEuMS4wXG4gICAgICogQGNhdGVnb3J5IEFycmF5XG4gICAgICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIGluc3BlY3QuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gW3ByZWRpY2F0ZT1fLmlkZW50aXR5XSBUaGUgZnVuY3Rpb24gaW52b2tlZCBwZXIgaXRlcmF0aW9uLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbZnJvbUluZGV4PTBdIFRoZSBpbmRleCB0byBzZWFyY2ggZnJvbS5cbiAgICAgKiBAcmV0dXJucyB7bnVtYmVyfSBSZXR1cm5zIHRoZSBpbmRleCBvZiB0aGUgZm91bmQgZWxlbWVudCwgZWxzZSBgLTFgLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiB2YXIgdXNlcnMgPSBbXG4gICAgICogICB7ICd1c2VyJzogJ2Jhcm5leScsICAnYWN0aXZlJzogZmFsc2UgfSxcbiAgICAgKiAgIHsgJ3VzZXInOiAnZnJlZCcsICAgICdhY3RpdmUnOiBmYWxzZSB9LFxuICAgICAqICAgeyAndXNlcic6ICdwZWJibGVzJywgJ2FjdGl2ZSc6IHRydWUgfVxuICAgICAqIF07XG4gICAgICpcbiAgICAgKiBfLmZpbmRJbmRleCh1c2VycywgZnVuY3Rpb24obykgeyByZXR1cm4gby51c2VyID09ICdiYXJuZXknOyB9KTtcbiAgICAgKiAvLyA9PiAwXG4gICAgICpcbiAgICAgKiAvLyBUaGUgYF8ubWF0Y2hlc2AgaXRlcmF0ZWUgc2hvcnRoYW5kLlxuICAgICAqIF8uZmluZEluZGV4KHVzZXJzLCB7ICd1c2VyJzogJ2ZyZWQnLCAnYWN0aXZlJzogZmFsc2UgfSk7XG4gICAgICogLy8gPT4gMVxuICAgICAqXG4gICAgICogLy8gVGhlIGBfLm1hdGNoZXNQcm9wZXJ0eWAgaXRlcmF0ZWUgc2hvcnRoYW5kLlxuICAgICAqIF8uZmluZEluZGV4KHVzZXJzLCBbJ2FjdGl2ZScsIGZhbHNlXSk7XG4gICAgICogLy8gPT4gMFxuICAgICAqXG4gICAgICogLy8gVGhlIGBfLnByb3BlcnR5YCBpdGVyYXRlZSBzaG9ydGhhbmQuXG4gICAgICogXy5maW5kSW5kZXgodXNlcnMsICdhY3RpdmUnKTtcbiAgICAgKiAvLyA9PiAyXG4gICAgICovXG4gICAgZnVuY3Rpb24gZmluZEluZGV4KGFycmF5LCBwcmVkaWNhdGUsIGZyb21JbmRleCkge1xuICAgICAgdmFyIGxlbmd0aCA9IGFycmF5ID09IG51bGwgPyAwIDogYXJyYXkubGVuZ3RoO1xuICAgICAgaWYgKCFsZW5ndGgpIHtcbiAgICAgICAgcmV0dXJuIC0xO1xuICAgICAgfVxuICAgICAgdmFyIGluZGV4ID0gZnJvbUluZGV4ID09IG51bGwgPyAwIDogdG9JbnRlZ2VyKGZyb21JbmRleCk7XG4gICAgICBpZiAoaW5kZXggPCAwKSB7XG4gICAgICAgIGluZGV4ID0gbmF0aXZlTWF4KGxlbmd0aCArIGluZGV4LCAwKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBiYXNlRmluZEluZGV4KGFycmF5LCBnZXRJdGVyYXRlZShwcmVkaWNhdGUsIDMpLCBpbmRleCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhpcyBtZXRob2QgaXMgbGlrZSBgXy5maW5kSW5kZXhgIGV4Y2VwdCB0aGF0IGl0IGl0ZXJhdGVzIG92ZXIgZWxlbWVudHNcbiAgICAgKiBvZiBgY29sbGVjdGlvbmAgZnJvbSByaWdodCB0byBsZWZ0LlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDIuMC4wXG4gICAgICogQGNhdGVnb3J5IEFycmF5XG4gICAgICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIGluc3BlY3QuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gW3ByZWRpY2F0ZT1fLmlkZW50aXR5XSBUaGUgZnVuY3Rpb24gaW52b2tlZCBwZXIgaXRlcmF0aW9uLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbZnJvbUluZGV4PWFycmF5Lmxlbmd0aC0xXSBUaGUgaW5kZXggdG8gc2VhcmNoIGZyb20uXG4gICAgICogQHJldHVybnMge251bWJlcn0gUmV0dXJucyB0aGUgaW5kZXggb2YgdGhlIGZvdW5kIGVsZW1lbnQsIGVsc2UgYC0xYC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogdmFyIHVzZXJzID0gW1xuICAgICAqICAgeyAndXNlcic6ICdiYXJuZXknLCAgJ2FjdGl2ZSc6IHRydWUgfSxcbiAgICAgKiAgIHsgJ3VzZXInOiAnZnJlZCcsICAgICdhY3RpdmUnOiBmYWxzZSB9LFxuICAgICAqICAgeyAndXNlcic6ICdwZWJibGVzJywgJ2FjdGl2ZSc6IGZhbHNlIH1cbiAgICAgKiBdO1xuICAgICAqXG4gICAgICogXy5maW5kTGFzdEluZGV4KHVzZXJzLCBmdW5jdGlvbihvKSB7IHJldHVybiBvLnVzZXIgPT0gJ3BlYmJsZXMnOyB9KTtcbiAgICAgKiAvLyA9PiAyXG4gICAgICpcbiAgICAgKiAvLyBUaGUgYF8ubWF0Y2hlc2AgaXRlcmF0ZWUgc2hvcnRoYW5kLlxuICAgICAqIF8uZmluZExhc3RJbmRleCh1c2VycywgeyAndXNlcic6ICdiYXJuZXknLCAnYWN0aXZlJzogdHJ1ZSB9KTtcbiAgICAgKiAvLyA9PiAwXG4gICAgICpcbiAgICAgKiAvLyBUaGUgYF8ubWF0Y2hlc1Byb3BlcnR5YCBpdGVyYXRlZSBzaG9ydGhhbmQuXG4gICAgICogXy5maW5kTGFzdEluZGV4KHVzZXJzLCBbJ2FjdGl2ZScsIGZhbHNlXSk7XG4gICAgICogLy8gPT4gMlxuICAgICAqXG4gICAgICogLy8gVGhlIGBfLnByb3BlcnR5YCBpdGVyYXRlZSBzaG9ydGhhbmQuXG4gICAgICogXy5maW5kTGFzdEluZGV4KHVzZXJzLCAnYWN0aXZlJyk7XG4gICAgICogLy8gPT4gMFxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGZpbmRMYXN0SW5kZXgoYXJyYXksIHByZWRpY2F0ZSwgZnJvbUluZGV4KSB7XG4gICAgICB2YXIgbGVuZ3RoID0gYXJyYXkgPT0gbnVsbCA/IDAgOiBhcnJheS5sZW5ndGg7XG4gICAgICBpZiAoIWxlbmd0aCkge1xuICAgICAgICByZXR1cm4gLTE7XG4gICAgICB9XG4gICAgICB2YXIgaW5kZXggPSBsZW5ndGggLSAxO1xuICAgICAgaWYgKGZyb21JbmRleCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIGluZGV4ID0gdG9JbnRlZ2VyKGZyb21JbmRleCk7XG4gICAgICAgIGluZGV4ID0gZnJvbUluZGV4IDwgMFxuICAgICAgICAgID8gbmF0aXZlTWF4KGxlbmd0aCArIGluZGV4LCAwKVxuICAgICAgICAgIDogbmF0aXZlTWluKGluZGV4LCBsZW5ndGggLSAxKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBiYXNlRmluZEluZGV4KGFycmF5LCBnZXRJdGVyYXRlZShwcmVkaWNhdGUsIDMpLCBpbmRleCwgdHJ1ZSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogRmxhdHRlbnMgYGFycmF5YCBhIHNpbmdsZSBsZXZlbCBkZWVwLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDAuMS4wXG4gICAgICogQGNhdGVnb3J5IEFycmF5XG4gICAgICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIGZsYXR0ZW4uXG4gICAgICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBuZXcgZmxhdHRlbmVkIGFycmF5LlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLmZsYXR0ZW4oWzEsIFsyLCBbMywgWzRdXSwgNV1dKTtcbiAgICAgKiAvLyA9PiBbMSwgMiwgWzMsIFs0XV0sIDVdXG4gICAgICovXG4gICAgZnVuY3Rpb24gZmxhdHRlbihhcnJheSkge1xuICAgICAgdmFyIGxlbmd0aCA9IGFycmF5ID09IG51bGwgPyAwIDogYXJyYXkubGVuZ3RoO1xuICAgICAgcmV0dXJuIGxlbmd0aCA/IGJhc2VGbGF0dGVuKGFycmF5LCAxKSA6IFtdO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJlY3Vyc2l2ZWx5IGZsYXR0ZW5zIGBhcnJheWAuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMy4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgQXJyYXlcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBhcnJheSBUaGUgYXJyYXkgdG8gZmxhdHRlbi5cbiAgICAgKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIG5ldyBmbGF0dGVuZWQgYXJyYXkuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8uZmxhdHRlbkRlZXAoWzEsIFsyLCBbMywgWzRdXSwgNV1dKTtcbiAgICAgKiAvLyA9PiBbMSwgMiwgMywgNCwgNV1cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBmbGF0dGVuRGVlcChhcnJheSkge1xuICAgICAgdmFyIGxlbmd0aCA9IGFycmF5ID09IG51bGwgPyAwIDogYXJyYXkubGVuZ3RoO1xuICAgICAgcmV0dXJuIGxlbmd0aCA/IGJhc2VGbGF0dGVuKGFycmF5LCBJTkZJTklUWSkgOiBbXTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBSZWN1cnNpdmVseSBmbGF0dGVuIGBhcnJheWAgdXAgdG8gYGRlcHRoYCB0aW1lcy5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSA0LjQuMFxuICAgICAqIEBjYXRlZ29yeSBBcnJheVxuICAgICAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBhcnJheSB0byBmbGF0dGVuLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbZGVwdGg9MV0gVGhlIG1heGltdW0gcmVjdXJzaW9uIGRlcHRoLlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgbmV3IGZsYXR0ZW5lZCBhcnJheS5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogdmFyIGFycmF5ID0gWzEsIFsyLCBbMywgWzRdXSwgNV1dO1xuICAgICAqXG4gICAgICogXy5mbGF0dGVuRGVwdGgoYXJyYXksIDEpO1xuICAgICAqIC8vID0+IFsxLCAyLCBbMywgWzRdXSwgNV1cbiAgICAgKlxuICAgICAqIF8uZmxhdHRlbkRlcHRoKGFycmF5LCAyKTtcbiAgICAgKiAvLyA9PiBbMSwgMiwgMywgWzRdLCA1XVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGZsYXR0ZW5EZXB0aChhcnJheSwgZGVwdGgpIHtcbiAgICAgIHZhciBsZW5ndGggPSBhcnJheSA9PSBudWxsID8gMCA6IGFycmF5Lmxlbmd0aDtcbiAgICAgIGlmICghbGVuZ3RoKSB7XG4gICAgICAgIHJldHVybiBbXTtcbiAgICAgIH1cbiAgICAgIGRlcHRoID0gZGVwdGggPT09IHVuZGVmaW5lZCA/IDEgOiB0b0ludGVnZXIoZGVwdGgpO1xuICAgICAgcmV0dXJuIGJhc2VGbGF0dGVuKGFycmF5LCBkZXB0aCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhlIGludmVyc2Ugb2YgYF8udG9QYWlyc2A7IHRoaXMgbWV0aG9kIHJldHVybnMgYW4gb2JqZWN0IGNvbXBvc2VkXG4gICAgICogZnJvbSBrZXktdmFsdWUgYHBhaXJzYC5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSA0LjAuMFxuICAgICAqIEBjYXRlZ29yeSBBcnJheVxuICAgICAqIEBwYXJhbSB7QXJyYXl9IHBhaXJzIFRoZSBrZXktdmFsdWUgcGFpcnMuXG4gICAgICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyB0aGUgbmV3IG9iamVjdC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy5mcm9tUGFpcnMoW1snYScsIDFdLCBbJ2InLCAyXV0pO1xuICAgICAqIC8vID0+IHsgJ2EnOiAxLCAnYic6IDIgfVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGZyb21QYWlycyhwYWlycykge1xuICAgICAgdmFyIGluZGV4ID0gLTEsXG4gICAgICAgICAgbGVuZ3RoID0gcGFpcnMgPT0gbnVsbCA/IDAgOiBwYWlycy5sZW5ndGgsXG4gICAgICAgICAgcmVzdWx0ID0ge307XG5cbiAgICAgIHdoaWxlICgrK2luZGV4IDwgbGVuZ3RoKSB7XG4gICAgICAgIHZhciBwYWlyID0gcGFpcnNbaW5kZXhdO1xuICAgICAgICByZXN1bHRbcGFpclswXV0gPSBwYWlyWzFdO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBHZXRzIHRoZSBmaXJzdCBlbGVtZW50IG9mIGBhcnJheWAuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMC4xLjBcbiAgICAgKiBAYWxpYXMgZmlyc3RcbiAgICAgKiBAY2F0ZWdvcnkgQXJyYXlcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBhcnJheSBUaGUgYXJyYXkgdG8gcXVlcnkuXG4gICAgICogQHJldHVybnMgeyp9IFJldHVybnMgdGhlIGZpcnN0IGVsZW1lbnQgb2YgYGFycmF5YC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy5oZWFkKFsxLCAyLCAzXSk7XG4gICAgICogLy8gPT4gMVxuICAgICAqXG4gICAgICogXy5oZWFkKFtdKTtcbiAgICAgKiAvLyA9PiB1bmRlZmluZWRcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBoZWFkKGFycmF5KSB7XG4gICAgICByZXR1cm4gKGFycmF5ICYmIGFycmF5Lmxlbmd0aCkgPyBhcnJheVswXSA6IHVuZGVmaW5lZDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBHZXRzIHRoZSBpbmRleCBhdCB3aGljaCB0aGUgZmlyc3Qgb2NjdXJyZW5jZSBvZiBgdmFsdWVgIGlzIGZvdW5kIGluIGBhcnJheWBcbiAgICAgKiB1c2luZyBbYFNhbWVWYWx1ZVplcm9gXShodHRwOi8vZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi83LjAvI3NlYy1zYW1ldmFsdWV6ZXJvKVxuICAgICAqIGZvciBlcXVhbGl0eSBjb21wYXJpc29ucy4gSWYgYGZyb21JbmRleGAgaXMgbmVnYXRpdmUsIGl0J3MgdXNlZCBhcyB0aGVcbiAgICAgKiBvZmZzZXQgZnJvbSB0aGUgZW5kIG9mIGBhcnJheWAuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMC4xLjBcbiAgICAgKiBAY2F0ZWdvcnkgQXJyYXlcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBhcnJheSBUaGUgYXJyYXkgdG8gaW5zcGVjdC5cbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBzZWFyY2ggZm9yLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbZnJvbUluZGV4PTBdIFRoZSBpbmRleCB0byBzZWFyY2ggZnJvbS5cbiAgICAgKiBAcmV0dXJucyB7bnVtYmVyfSBSZXR1cm5zIHRoZSBpbmRleCBvZiB0aGUgbWF0Y2hlZCB2YWx1ZSwgZWxzZSBgLTFgLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLmluZGV4T2YoWzEsIDIsIDEsIDJdLCAyKTtcbiAgICAgKiAvLyA9PiAxXG4gICAgICpcbiAgICAgKiAvLyBTZWFyY2ggZnJvbSB0aGUgYGZyb21JbmRleGAuXG4gICAgICogXy5pbmRleE9mKFsxLCAyLCAxLCAyXSwgMiwgMik7XG4gICAgICogLy8gPT4gM1xuICAgICAqL1xuICAgIGZ1bmN0aW9uIGluZGV4T2YoYXJyYXksIHZhbHVlLCBmcm9tSW5kZXgpIHtcbiAgICAgIHZhciBsZW5ndGggPSBhcnJheSA9PSBudWxsID8gMCA6IGFycmF5Lmxlbmd0aDtcbiAgICAgIGlmICghbGVuZ3RoKSB7XG4gICAgICAgIHJldHVybiAtMTtcbiAgICAgIH1cbiAgICAgIHZhciBpbmRleCA9IGZyb21JbmRleCA9PSBudWxsID8gMCA6IHRvSW50ZWdlcihmcm9tSW5kZXgpO1xuICAgICAgaWYgKGluZGV4IDwgMCkge1xuICAgICAgICBpbmRleCA9IG5hdGl2ZU1heChsZW5ndGggKyBpbmRleCwgMCk7XG4gICAgICB9XG4gICAgICByZXR1cm4gYmFzZUluZGV4T2YoYXJyYXksIHZhbHVlLCBpbmRleCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogR2V0cyBhbGwgYnV0IHRoZSBsYXN0IGVsZW1lbnQgb2YgYGFycmF5YC5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAwLjEuMFxuICAgICAqIEBjYXRlZ29yeSBBcnJheVxuICAgICAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBhcnJheSB0byBxdWVyeS5cbiAgICAgKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIHNsaWNlIG9mIGBhcnJheWAuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8uaW5pdGlhbChbMSwgMiwgM10pO1xuICAgICAqIC8vID0+IFsxLCAyXVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGluaXRpYWwoYXJyYXkpIHtcbiAgICAgIHZhciBsZW5ndGggPSBhcnJheSA9PSBudWxsID8gMCA6IGFycmF5Lmxlbmd0aDtcbiAgICAgIHJldHVybiBsZW5ndGggPyBiYXNlU2xpY2UoYXJyYXksIDAsIC0xKSA6IFtdO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYW4gYXJyYXkgb2YgdW5pcXVlIHZhbHVlcyB0aGF0IGFyZSBpbmNsdWRlZCBpbiBhbGwgZ2l2ZW4gYXJyYXlzXG4gICAgICogdXNpbmcgW2BTYW1lVmFsdWVaZXJvYF0oaHR0cDovL2VjbWEtaW50ZXJuYXRpb25hbC5vcmcvZWNtYS0yNjIvNy4wLyNzZWMtc2FtZXZhbHVlemVybylcbiAgICAgKiBmb3IgZXF1YWxpdHkgY29tcGFyaXNvbnMuIFRoZSBvcmRlciBhbmQgcmVmZXJlbmNlcyBvZiByZXN1bHQgdmFsdWVzIGFyZVxuICAgICAqIGRldGVybWluZWQgYnkgdGhlIGZpcnN0IGFycmF5LlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDAuMS4wXG4gICAgICogQGNhdGVnb3J5IEFycmF5XG4gICAgICogQHBhcmFtIHsuLi5BcnJheX0gW2FycmF5c10gVGhlIGFycmF5cyB0byBpbnNwZWN0LlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgbmV3IGFycmF5IG9mIGludGVyc2VjdGluZyB2YWx1ZXMuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8uaW50ZXJzZWN0aW9uKFsyLCAxXSwgWzIsIDNdKTtcbiAgICAgKiAvLyA9PiBbMl1cbiAgICAgKi9cbiAgICB2YXIgaW50ZXJzZWN0aW9uID0gYmFzZVJlc3QoZnVuY3Rpb24oYXJyYXlzKSB7XG4gICAgICB2YXIgbWFwcGVkID0gYXJyYXlNYXAoYXJyYXlzLCBjYXN0QXJyYXlMaWtlT2JqZWN0KTtcbiAgICAgIHJldHVybiAobWFwcGVkLmxlbmd0aCAmJiBtYXBwZWRbMF0gPT09IGFycmF5c1swXSlcbiAgICAgICAgPyBiYXNlSW50ZXJzZWN0aW9uKG1hcHBlZClcbiAgICAgICAgOiBbXTtcbiAgICB9KTtcblxuICAgIC8qKlxuICAgICAqIFRoaXMgbWV0aG9kIGlzIGxpa2UgYF8uaW50ZXJzZWN0aW9uYCBleGNlcHQgdGhhdCBpdCBhY2NlcHRzIGBpdGVyYXRlZWBcbiAgICAgKiB3aGljaCBpcyBpbnZva2VkIGZvciBlYWNoIGVsZW1lbnQgb2YgZWFjaCBgYXJyYXlzYCB0byBnZW5lcmF0ZSB0aGUgY3JpdGVyaW9uXG4gICAgICogYnkgd2hpY2ggdGhleSdyZSBjb21wYXJlZC4gVGhlIG9yZGVyIGFuZCByZWZlcmVuY2VzIG9mIHJlc3VsdCB2YWx1ZXMgYXJlXG4gICAgICogZGV0ZXJtaW5lZCBieSB0aGUgZmlyc3QgYXJyYXkuIFRoZSBpdGVyYXRlZSBpcyBpbnZva2VkIHdpdGggb25lIGFyZ3VtZW50OlxuICAgICAqICh2YWx1ZSkuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgNC4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgQXJyYXlcbiAgICAgKiBAcGFyYW0gey4uLkFycmF5fSBbYXJyYXlzXSBUaGUgYXJyYXlzIHRvIGluc3BlY3QuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gW2l0ZXJhdGVlPV8uaWRlbnRpdHldIFRoZSBpdGVyYXRlZSBpbnZva2VkIHBlciBlbGVtZW50LlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgbmV3IGFycmF5IG9mIGludGVyc2VjdGluZyB2YWx1ZXMuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8uaW50ZXJzZWN0aW9uQnkoWzIuMSwgMS4yXSwgWzIuMywgMy40XSwgTWF0aC5mbG9vcik7XG4gICAgICogLy8gPT4gWzIuMV1cbiAgICAgKlxuICAgICAqIC8vIFRoZSBgXy5wcm9wZXJ0eWAgaXRlcmF0ZWUgc2hvcnRoYW5kLlxuICAgICAqIF8uaW50ZXJzZWN0aW9uQnkoW3sgJ3gnOiAxIH1dLCBbeyAneCc6IDIgfSwgeyAneCc6IDEgfV0sICd4Jyk7XG4gICAgICogLy8gPT4gW3sgJ3gnOiAxIH1dXG4gICAgICovXG4gICAgdmFyIGludGVyc2VjdGlvbkJ5ID0gYmFzZVJlc3QoZnVuY3Rpb24oYXJyYXlzKSB7XG4gICAgICB2YXIgaXRlcmF0ZWUgPSBsYXN0KGFycmF5cyksXG4gICAgICAgICAgbWFwcGVkID0gYXJyYXlNYXAoYXJyYXlzLCBjYXN0QXJyYXlMaWtlT2JqZWN0KTtcblxuICAgICAgaWYgKGl0ZXJhdGVlID09PSBsYXN0KG1hcHBlZCkpIHtcbiAgICAgICAgaXRlcmF0ZWUgPSB1bmRlZmluZWQ7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBtYXBwZWQucG9wKCk7XG4gICAgICB9XG4gICAgICByZXR1cm4gKG1hcHBlZC5sZW5ndGggJiYgbWFwcGVkWzBdID09PSBhcnJheXNbMF0pXG4gICAgICAgID8gYmFzZUludGVyc2VjdGlvbihtYXBwZWQsIGdldEl0ZXJhdGVlKGl0ZXJhdGVlLCAyKSlcbiAgICAgICAgOiBbXTtcbiAgICB9KTtcblxuICAgIC8qKlxuICAgICAqIFRoaXMgbWV0aG9kIGlzIGxpa2UgYF8uaW50ZXJzZWN0aW9uYCBleGNlcHQgdGhhdCBpdCBhY2NlcHRzIGBjb21wYXJhdG9yYFxuICAgICAqIHdoaWNoIGlzIGludm9rZWQgdG8gY29tcGFyZSBlbGVtZW50cyBvZiBgYXJyYXlzYC4gVGhlIG9yZGVyIGFuZCByZWZlcmVuY2VzXG4gICAgICogb2YgcmVzdWx0IHZhbHVlcyBhcmUgZGV0ZXJtaW5lZCBieSB0aGUgZmlyc3QgYXJyYXkuIFRoZSBjb21wYXJhdG9yIGlzXG4gICAgICogaW52b2tlZCB3aXRoIHR3byBhcmd1bWVudHM6IChhcnJWYWwsIG90aFZhbCkuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgNC4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgQXJyYXlcbiAgICAgKiBAcGFyYW0gey4uLkFycmF5fSBbYXJyYXlzXSBUaGUgYXJyYXlzIHRvIGluc3BlY3QuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gW2NvbXBhcmF0b3JdIFRoZSBjb21wYXJhdG9yIGludm9rZWQgcGVyIGVsZW1lbnQuXG4gICAgICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBuZXcgYXJyYXkgb2YgaW50ZXJzZWN0aW5nIHZhbHVlcy5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogdmFyIG9iamVjdHMgPSBbeyAneCc6IDEsICd5JzogMiB9LCB7ICd4JzogMiwgJ3knOiAxIH1dO1xuICAgICAqIHZhciBvdGhlcnMgPSBbeyAneCc6IDEsICd5JzogMSB9LCB7ICd4JzogMSwgJ3knOiAyIH1dO1xuICAgICAqXG4gICAgICogXy5pbnRlcnNlY3Rpb25XaXRoKG9iamVjdHMsIG90aGVycywgXy5pc0VxdWFsKTtcbiAgICAgKiAvLyA9PiBbeyAneCc6IDEsICd5JzogMiB9XVxuICAgICAqL1xuICAgIHZhciBpbnRlcnNlY3Rpb25XaXRoID0gYmFzZVJlc3QoZnVuY3Rpb24oYXJyYXlzKSB7XG4gICAgICB2YXIgY29tcGFyYXRvciA9IGxhc3QoYXJyYXlzKSxcbiAgICAgICAgICBtYXBwZWQgPSBhcnJheU1hcChhcnJheXMsIGNhc3RBcnJheUxpa2VPYmplY3QpO1xuXG4gICAgICBjb21wYXJhdG9yID0gdHlwZW9mIGNvbXBhcmF0b3IgPT0gJ2Z1bmN0aW9uJyA/IGNvbXBhcmF0b3IgOiB1bmRlZmluZWQ7XG4gICAgICBpZiAoY29tcGFyYXRvcikge1xuICAgICAgICBtYXBwZWQucG9wKCk7XG4gICAgICB9XG4gICAgICByZXR1cm4gKG1hcHBlZC5sZW5ndGggJiYgbWFwcGVkWzBdID09PSBhcnJheXNbMF0pXG4gICAgICAgID8gYmFzZUludGVyc2VjdGlvbihtYXBwZWQsIHVuZGVmaW5lZCwgY29tcGFyYXRvcilcbiAgICAgICAgOiBbXTtcbiAgICB9KTtcblxuICAgIC8qKlxuICAgICAqIENvbnZlcnRzIGFsbCBlbGVtZW50cyBpbiBgYXJyYXlgIGludG8gYSBzdHJpbmcgc2VwYXJhdGVkIGJ5IGBzZXBhcmF0b3JgLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDQuMC4wXG4gICAgICogQGNhdGVnb3J5IEFycmF5XG4gICAgICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIGNvbnZlcnQuXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IFtzZXBhcmF0b3I9JywnXSBUaGUgZWxlbWVudCBzZXBhcmF0b3IuXG4gICAgICogQHJldHVybnMge3N0cmluZ30gUmV0dXJucyB0aGUgam9pbmVkIHN0cmluZy5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy5qb2luKFsnYScsICdiJywgJ2MnXSwgJ34nKTtcbiAgICAgKiAvLyA9PiAnYX5ifmMnXG4gICAgICovXG4gICAgZnVuY3Rpb24gam9pbihhcnJheSwgc2VwYXJhdG9yKSB7XG4gICAgICByZXR1cm4gYXJyYXkgPT0gbnVsbCA/ICcnIDogbmF0aXZlSm9pbi5jYWxsKGFycmF5LCBzZXBhcmF0b3IpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEdldHMgdGhlIGxhc3QgZWxlbWVudCBvZiBgYXJyYXlgLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDAuMS4wXG4gICAgICogQGNhdGVnb3J5IEFycmF5XG4gICAgICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIHF1ZXJ5LlxuICAgICAqIEByZXR1cm5zIHsqfSBSZXR1cm5zIHRoZSBsYXN0IGVsZW1lbnQgb2YgYGFycmF5YC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy5sYXN0KFsxLCAyLCAzXSk7XG4gICAgICogLy8gPT4gM1xuICAgICAqL1xuICAgIGZ1bmN0aW9uIGxhc3QoYXJyYXkpIHtcbiAgICAgIHZhciBsZW5ndGggPSBhcnJheSA9PSBudWxsID8gMCA6IGFycmF5Lmxlbmd0aDtcbiAgICAgIHJldHVybiBsZW5ndGggPyBhcnJheVtsZW5ndGggLSAxXSA6IHVuZGVmaW5lZDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGlzIG1ldGhvZCBpcyBsaWtlIGBfLmluZGV4T2ZgIGV4Y2VwdCB0aGF0IGl0IGl0ZXJhdGVzIG92ZXIgZWxlbWVudHMgb2ZcbiAgICAgKiBgYXJyYXlgIGZyb20gcmlnaHQgdG8gbGVmdC5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAwLjEuMFxuICAgICAqIEBjYXRlZ29yeSBBcnJheVxuICAgICAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBhcnJheSB0byBpbnNwZWN0LlxuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIHNlYXJjaCBmb3IuXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IFtmcm9tSW5kZXg9YXJyYXkubGVuZ3RoLTFdIFRoZSBpbmRleCB0byBzZWFyY2ggZnJvbS5cbiAgICAgKiBAcmV0dXJucyB7bnVtYmVyfSBSZXR1cm5zIHRoZSBpbmRleCBvZiB0aGUgbWF0Y2hlZCB2YWx1ZSwgZWxzZSBgLTFgLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLmxhc3RJbmRleE9mKFsxLCAyLCAxLCAyXSwgMik7XG4gICAgICogLy8gPT4gM1xuICAgICAqXG4gICAgICogLy8gU2VhcmNoIGZyb20gdGhlIGBmcm9tSW5kZXhgLlxuICAgICAqIF8ubGFzdEluZGV4T2YoWzEsIDIsIDEsIDJdLCAyLCAyKTtcbiAgICAgKiAvLyA9PiAxXG4gICAgICovXG4gICAgZnVuY3Rpb24gbGFzdEluZGV4T2YoYXJyYXksIHZhbHVlLCBmcm9tSW5kZXgpIHtcbiAgICAgIHZhciBsZW5ndGggPSBhcnJheSA9PSBudWxsID8gMCA6IGFycmF5Lmxlbmd0aDtcbiAgICAgIGlmICghbGVuZ3RoKSB7XG4gICAgICAgIHJldHVybiAtMTtcbiAgICAgIH1cbiAgICAgIHZhciBpbmRleCA9IGxlbmd0aDtcbiAgICAgIGlmIChmcm9tSW5kZXggIT09IHVuZGVmaW5lZCkge1xuICAgICAgICBpbmRleCA9IHRvSW50ZWdlcihmcm9tSW5kZXgpO1xuICAgICAgICBpbmRleCA9IGluZGV4IDwgMCA/IG5hdGl2ZU1heChsZW5ndGggKyBpbmRleCwgMCkgOiBuYXRpdmVNaW4oaW5kZXgsIGxlbmd0aCAtIDEpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHZhbHVlID09PSB2YWx1ZVxuICAgICAgICA/IHN0cmljdExhc3RJbmRleE9mKGFycmF5LCB2YWx1ZSwgaW5kZXgpXG4gICAgICAgIDogYmFzZUZpbmRJbmRleChhcnJheSwgYmFzZUlzTmFOLCBpbmRleCwgdHJ1ZSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogR2V0cyB0aGUgZWxlbWVudCBhdCBpbmRleCBgbmAgb2YgYGFycmF5YC4gSWYgYG5gIGlzIG5lZ2F0aXZlLCB0aGUgbnRoXG4gICAgICogZWxlbWVudCBmcm9tIHRoZSBlbmQgaXMgcmV0dXJuZWQuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgNC4xMS4wXG4gICAgICogQGNhdGVnb3J5IEFycmF5XG4gICAgICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIHF1ZXJ5LlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbbj0wXSBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLlxuICAgICAqIEByZXR1cm5zIHsqfSBSZXR1cm5zIHRoZSBudGggZWxlbWVudCBvZiBgYXJyYXlgLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiB2YXIgYXJyYXkgPSBbJ2EnLCAnYicsICdjJywgJ2QnXTtcbiAgICAgKlxuICAgICAqIF8ubnRoKGFycmF5LCAxKTtcbiAgICAgKiAvLyA9PiAnYidcbiAgICAgKlxuICAgICAqIF8ubnRoKGFycmF5LCAtMik7XG4gICAgICogLy8gPT4gJ2MnO1xuICAgICAqL1xuICAgIGZ1bmN0aW9uIG50aChhcnJheSwgbikge1xuICAgICAgcmV0dXJuIChhcnJheSAmJiBhcnJheS5sZW5ndGgpID8gYmFzZU50aChhcnJheSwgdG9JbnRlZ2VyKG4pKSA6IHVuZGVmaW5lZDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBSZW1vdmVzIGFsbCBnaXZlbiB2YWx1ZXMgZnJvbSBgYXJyYXlgIHVzaW5nXG4gICAgICogW2BTYW1lVmFsdWVaZXJvYF0oaHR0cDovL2VjbWEtaW50ZXJuYXRpb25hbC5vcmcvZWNtYS0yNjIvNy4wLyNzZWMtc2FtZXZhbHVlemVybylcbiAgICAgKiBmb3IgZXF1YWxpdHkgY29tcGFyaXNvbnMuXG4gICAgICpcbiAgICAgKiAqKk5vdGU6KiogVW5saWtlIGBfLndpdGhvdXRgLCB0aGlzIG1ldGhvZCBtdXRhdGVzIGBhcnJheWAuIFVzZSBgXy5yZW1vdmVgXG4gICAgICogdG8gcmVtb3ZlIGVsZW1lbnRzIGZyb20gYW4gYXJyYXkgYnkgcHJlZGljYXRlLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDIuMC4wXG4gICAgICogQGNhdGVnb3J5IEFycmF5XG4gICAgICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIG1vZGlmeS5cbiAgICAgKiBAcGFyYW0gey4uLip9IFt2YWx1ZXNdIFRoZSB2YWx1ZXMgdG8gcmVtb3ZlLlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyBgYXJyYXlgLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiB2YXIgYXJyYXkgPSBbJ2EnLCAnYicsICdjJywgJ2EnLCAnYicsICdjJ107XG4gICAgICpcbiAgICAgKiBfLnB1bGwoYXJyYXksICdhJywgJ2MnKTtcbiAgICAgKiBjb25zb2xlLmxvZyhhcnJheSk7XG4gICAgICogLy8gPT4gWydiJywgJ2InXVxuICAgICAqL1xuICAgIHZhciBwdWxsID0gYmFzZVJlc3QocHVsbEFsbCk7XG5cbiAgICAvKipcbiAgICAgKiBUaGlzIG1ldGhvZCBpcyBsaWtlIGBfLnB1bGxgIGV4Y2VwdCB0aGF0IGl0IGFjY2VwdHMgYW4gYXJyYXkgb2YgdmFsdWVzIHRvIHJlbW92ZS5cbiAgICAgKlxuICAgICAqICoqTm90ZToqKiBVbmxpa2UgYF8uZGlmZmVyZW5jZWAsIHRoaXMgbWV0aG9kIG11dGF0ZXMgYGFycmF5YC5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSA0LjAuMFxuICAgICAqIEBjYXRlZ29yeSBBcnJheVxuICAgICAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBhcnJheSB0byBtb2RpZnkuXG4gICAgICogQHBhcmFtIHtBcnJheX0gdmFsdWVzIFRoZSB2YWx1ZXMgdG8gcmVtb3ZlLlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyBgYXJyYXlgLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiB2YXIgYXJyYXkgPSBbJ2EnLCAnYicsICdjJywgJ2EnLCAnYicsICdjJ107XG4gICAgICpcbiAgICAgKiBfLnB1bGxBbGwoYXJyYXksIFsnYScsICdjJ10pO1xuICAgICAqIGNvbnNvbGUubG9nKGFycmF5KTtcbiAgICAgKiAvLyA9PiBbJ2InLCAnYiddXG4gICAgICovXG4gICAgZnVuY3Rpb24gcHVsbEFsbChhcnJheSwgdmFsdWVzKSB7XG4gICAgICByZXR1cm4gKGFycmF5ICYmIGFycmF5Lmxlbmd0aCAmJiB2YWx1ZXMgJiYgdmFsdWVzLmxlbmd0aClcbiAgICAgICAgPyBiYXNlUHVsbEFsbChhcnJheSwgdmFsdWVzKVxuICAgICAgICA6IGFycmF5O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoaXMgbWV0aG9kIGlzIGxpa2UgYF8ucHVsbEFsbGAgZXhjZXB0IHRoYXQgaXQgYWNjZXB0cyBgaXRlcmF0ZWVgIHdoaWNoIGlzXG4gICAgICogaW52b2tlZCBmb3IgZWFjaCBlbGVtZW50IG9mIGBhcnJheWAgYW5kIGB2YWx1ZXNgIHRvIGdlbmVyYXRlIHRoZSBjcml0ZXJpb25cbiAgICAgKiBieSB3aGljaCB0aGV5J3JlIGNvbXBhcmVkLiBUaGUgaXRlcmF0ZWUgaXMgaW52b2tlZCB3aXRoIG9uZSBhcmd1bWVudDogKHZhbHVlKS5cbiAgICAgKlxuICAgICAqICoqTm90ZToqKiBVbmxpa2UgYF8uZGlmZmVyZW5jZUJ5YCwgdGhpcyBtZXRob2QgbXV0YXRlcyBgYXJyYXlgLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDQuMC4wXG4gICAgICogQGNhdGVnb3J5IEFycmF5XG4gICAgICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIG1vZGlmeS5cbiAgICAgKiBAcGFyYW0ge0FycmF5fSB2YWx1ZXMgVGhlIHZhbHVlcyB0byByZW1vdmUuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gW2l0ZXJhdGVlPV8uaWRlbnRpdHldIFRoZSBpdGVyYXRlZSBpbnZva2VkIHBlciBlbGVtZW50LlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyBgYXJyYXlgLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiB2YXIgYXJyYXkgPSBbeyAneCc6IDEgfSwgeyAneCc6IDIgfSwgeyAneCc6IDMgfSwgeyAneCc6IDEgfV07XG4gICAgICpcbiAgICAgKiBfLnB1bGxBbGxCeShhcnJheSwgW3sgJ3gnOiAxIH0sIHsgJ3gnOiAzIH1dLCAneCcpO1xuICAgICAqIGNvbnNvbGUubG9nKGFycmF5KTtcbiAgICAgKiAvLyA9PiBbeyAneCc6IDIgfV1cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBwdWxsQWxsQnkoYXJyYXksIHZhbHVlcywgaXRlcmF0ZWUpIHtcbiAgICAgIHJldHVybiAoYXJyYXkgJiYgYXJyYXkubGVuZ3RoICYmIHZhbHVlcyAmJiB2YWx1ZXMubGVuZ3RoKVxuICAgICAgICA/IGJhc2VQdWxsQWxsKGFycmF5LCB2YWx1ZXMsIGdldEl0ZXJhdGVlKGl0ZXJhdGVlLCAyKSlcbiAgICAgICAgOiBhcnJheTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGlzIG1ldGhvZCBpcyBsaWtlIGBfLnB1bGxBbGxgIGV4Y2VwdCB0aGF0IGl0IGFjY2VwdHMgYGNvbXBhcmF0b3JgIHdoaWNoXG4gICAgICogaXMgaW52b2tlZCB0byBjb21wYXJlIGVsZW1lbnRzIG9mIGBhcnJheWAgdG8gYHZhbHVlc2AuIFRoZSBjb21wYXJhdG9yIGlzXG4gICAgICogaW52b2tlZCB3aXRoIHR3byBhcmd1bWVudHM6IChhcnJWYWwsIG90aFZhbCkuXG4gICAgICpcbiAgICAgKiAqKk5vdGU6KiogVW5saWtlIGBfLmRpZmZlcmVuY2VXaXRoYCwgdGhpcyBtZXRob2QgbXV0YXRlcyBgYXJyYXlgLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDQuNi4wXG4gICAgICogQGNhdGVnb3J5IEFycmF5XG4gICAgICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIG1vZGlmeS5cbiAgICAgKiBAcGFyYW0ge0FycmF5fSB2YWx1ZXMgVGhlIHZhbHVlcyB0byByZW1vdmUuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gW2NvbXBhcmF0b3JdIFRoZSBjb21wYXJhdG9yIGludm9rZWQgcGVyIGVsZW1lbnQuXG4gICAgICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIGBhcnJheWAuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIHZhciBhcnJheSA9IFt7ICd4JzogMSwgJ3knOiAyIH0sIHsgJ3gnOiAzLCAneSc6IDQgfSwgeyAneCc6IDUsICd5JzogNiB9XTtcbiAgICAgKlxuICAgICAqIF8ucHVsbEFsbFdpdGgoYXJyYXksIFt7ICd4JzogMywgJ3knOiA0IH1dLCBfLmlzRXF1YWwpO1xuICAgICAqIGNvbnNvbGUubG9nKGFycmF5KTtcbiAgICAgKiAvLyA9PiBbeyAneCc6IDEsICd5JzogMiB9LCB7ICd4JzogNSwgJ3knOiA2IH1dXG4gICAgICovXG4gICAgZnVuY3Rpb24gcHVsbEFsbFdpdGgoYXJyYXksIHZhbHVlcywgY29tcGFyYXRvcikge1xuICAgICAgcmV0dXJuIChhcnJheSAmJiBhcnJheS5sZW5ndGggJiYgdmFsdWVzICYmIHZhbHVlcy5sZW5ndGgpXG4gICAgICAgID8gYmFzZVB1bGxBbGwoYXJyYXksIHZhbHVlcywgdW5kZWZpbmVkLCBjb21wYXJhdG9yKVxuICAgICAgICA6IGFycmF5O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJlbW92ZXMgZWxlbWVudHMgZnJvbSBgYXJyYXlgIGNvcnJlc3BvbmRpbmcgdG8gYGluZGV4ZXNgIGFuZCByZXR1cm5zIGFuXG4gICAgICogYXJyYXkgb2YgcmVtb3ZlZCBlbGVtZW50cy5cbiAgICAgKlxuICAgICAqICoqTm90ZToqKiBVbmxpa2UgYF8uYXRgLCB0aGlzIG1ldGhvZCBtdXRhdGVzIGBhcnJheWAuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMy4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgQXJyYXlcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBhcnJheSBUaGUgYXJyYXkgdG8gbW9kaWZ5LlxuICAgICAqIEBwYXJhbSB7Li4uKG51bWJlcnxudW1iZXJbXSl9IFtpbmRleGVzXSBUaGUgaW5kZXhlcyBvZiBlbGVtZW50cyB0byByZW1vdmUuXG4gICAgICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBuZXcgYXJyYXkgb2YgcmVtb3ZlZCBlbGVtZW50cy5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogdmFyIGFycmF5ID0gWydhJywgJ2InLCAnYycsICdkJ107XG4gICAgICogdmFyIHB1bGxlZCA9IF8ucHVsbEF0KGFycmF5LCBbMSwgM10pO1xuICAgICAqXG4gICAgICogY29uc29sZS5sb2coYXJyYXkpO1xuICAgICAqIC8vID0+IFsnYScsICdjJ11cbiAgICAgKlxuICAgICAqIGNvbnNvbGUubG9nKHB1bGxlZCk7XG4gICAgICogLy8gPT4gWydiJywgJ2QnXVxuICAgICAqL1xuICAgIHZhciBwdWxsQXQgPSBmbGF0UmVzdChmdW5jdGlvbihhcnJheSwgaW5kZXhlcykge1xuICAgICAgdmFyIGxlbmd0aCA9IGFycmF5ID09IG51bGwgPyAwIDogYXJyYXkubGVuZ3RoLFxuICAgICAgICAgIHJlc3VsdCA9IGJhc2VBdChhcnJheSwgaW5kZXhlcyk7XG5cbiAgICAgIGJhc2VQdWxsQXQoYXJyYXksIGFycmF5TWFwKGluZGV4ZXMsIGZ1bmN0aW9uKGluZGV4KSB7XG4gICAgICAgIHJldHVybiBpc0luZGV4KGluZGV4LCBsZW5ndGgpID8gK2luZGV4IDogaW5kZXg7XG4gICAgICB9KS5zb3J0KGNvbXBhcmVBc2NlbmRpbmcpKTtcblxuICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9KTtcblxuICAgIC8qKlxuICAgICAqIFJlbW92ZXMgYWxsIGVsZW1lbnRzIGZyb20gYGFycmF5YCB0aGF0IGBwcmVkaWNhdGVgIHJldHVybnMgdHJ1dGh5IGZvclxuICAgICAqIGFuZCByZXR1cm5zIGFuIGFycmF5IG9mIHRoZSByZW1vdmVkIGVsZW1lbnRzLiBUaGUgcHJlZGljYXRlIGlzIGludm9rZWRcbiAgICAgKiB3aXRoIHRocmVlIGFyZ3VtZW50czogKHZhbHVlLCBpbmRleCwgYXJyYXkpLlxuICAgICAqXG4gICAgICogKipOb3RlOioqIFVubGlrZSBgXy5maWx0ZXJgLCB0aGlzIG1ldGhvZCBtdXRhdGVzIGBhcnJheWAuIFVzZSBgXy5wdWxsYFxuICAgICAqIHRvIHB1bGwgZWxlbWVudHMgZnJvbSBhbiBhcnJheSBieSB2YWx1ZS5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAyLjAuMFxuICAgICAqIEBjYXRlZ29yeSBBcnJheVxuICAgICAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBhcnJheSB0byBtb2RpZnkuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gW3ByZWRpY2F0ZT1fLmlkZW50aXR5XSBUaGUgZnVuY3Rpb24gaW52b2tlZCBwZXIgaXRlcmF0aW9uLlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgbmV3IGFycmF5IG9mIHJlbW92ZWQgZWxlbWVudHMuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIHZhciBhcnJheSA9IFsxLCAyLCAzLCA0XTtcbiAgICAgKiB2YXIgZXZlbnMgPSBfLnJlbW92ZShhcnJheSwgZnVuY3Rpb24obikge1xuICAgICAqICAgcmV0dXJuIG4gJSAyID09IDA7XG4gICAgICogfSk7XG4gICAgICpcbiAgICAgKiBjb25zb2xlLmxvZyhhcnJheSk7XG4gICAgICogLy8gPT4gWzEsIDNdXG4gICAgICpcbiAgICAgKiBjb25zb2xlLmxvZyhldmVucyk7XG4gICAgICogLy8gPT4gWzIsIDRdXG4gICAgICovXG4gICAgZnVuY3Rpb24gcmVtb3ZlKGFycmF5LCBwcmVkaWNhdGUpIHtcbiAgICAgIHZhciByZXN1bHQgPSBbXTtcbiAgICAgIGlmICghKGFycmF5ICYmIGFycmF5Lmxlbmd0aCkpIHtcbiAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICAgIH1cbiAgICAgIHZhciBpbmRleCA9IC0xLFxuICAgICAgICAgIGluZGV4ZXMgPSBbXSxcbiAgICAgICAgICBsZW5ndGggPSBhcnJheS5sZW5ndGg7XG5cbiAgICAgIHByZWRpY2F0ZSA9IGdldEl0ZXJhdGVlKHByZWRpY2F0ZSwgMyk7XG4gICAgICB3aGlsZSAoKytpbmRleCA8IGxlbmd0aCkge1xuICAgICAgICB2YXIgdmFsdWUgPSBhcnJheVtpbmRleF07XG4gICAgICAgIGlmIChwcmVkaWNhdGUodmFsdWUsIGluZGV4LCBhcnJheSkpIHtcbiAgICAgICAgICByZXN1bHQucHVzaCh2YWx1ZSk7XG4gICAgICAgICAgaW5kZXhlcy5wdXNoKGluZGV4KTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgYmFzZVB1bGxBdChhcnJheSwgaW5kZXhlcyk7XG4gICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJldmVyc2VzIGBhcnJheWAgc28gdGhhdCB0aGUgZmlyc3QgZWxlbWVudCBiZWNvbWVzIHRoZSBsYXN0LCB0aGUgc2Vjb25kXG4gICAgICogZWxlbWVudCBiZWNvbWVzIHRoZSBzZWNvbmQgdG8gbGFzdCwgYW5kIHNvIG9uLlxuICAgICAqXG4gICAgICogKipOb3RlOioqIFRoaXMgbWV0aG9kIG11dGF0ZXMgYGFycmF5YCBhbmQgaXMgYmFzZWQgb25cbiAgICAgKiBbYEFycmF5I3JldmVyc2VgXShodHRwczovL21kbi5pby9BcnJheS9yZXZlcnNlKS5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSA0LjAuMFxuICAgICAqIEBjYXRlZ29yeSBBcnJheVxuICAgICAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBhcnJheSB0byBtb2RpZnkuXG4gICAgICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIGBhcnJheWAuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIHZhciBhcnJheSA9IFsxLCAyLCAzXTtcbiAgICAgKlxuICAgICAqIF8ucmV2ZXJzZShhcnJheSk7XG4gICAgICogLy8gPT4gWzMsIDIsIDFdXG4gICAgICpcbiAgICAgKiBjb25zb2xlLmxvZyhhcnJheSk7XG4gICAgICogLy8gPT4gWzMsIDIsIDFdXG4gICAgICovXG4gICAgZnVuY3Rpb24gcmV2ZXJzZShhcnJheSkge1xuICAgICAgcmV0dXJuIGFycmF5ID09IG51bGwgPyBhcnJheSA6IG5hdGl2ZVJldmVyc2UuY2FsbChhcnJheSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIHNsaWNlIG9mIGBhcnJheWAgZnJvbSBgc3RhcnRgIHVwIHRvLCBidXQgbm90IGluY2x1ZGluZywgYGVuZGAuXG4gICAgICpcbiAgICAgKiAqKk5vdGU6KiogVGhpcyBtZXRob2QgaXMgdXNlZCBpbnN0ZWFkIG9mXG4gICAgICogW2BBcnJheSNzbGljZWBdKGh0dHBzOi8vbWRuLmlvL0FycmF5L3NsaWNlKSB0byBlbnN1cmUgZGVuc2UgYXJyYXlzIGFyZVxuICAgICAqIHJldHVybmVkLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDMuMC4wXG4gICAgICogQGNhdGVnb3J5IEFycmF5XG4gICAgICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIHNsaWNlLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbc3RhcnQ9MF0gVGhlIHN0YXJ0IHBvc2l0aW9uLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbZW5kPWFycmF5Lmxlbmd0aF0gVGhlIGVuZCBwb3NpdGlvbi5cbiAgICAgKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIHNsaWNlIG9mIGBhcnJheWAuXG4gICAgICovXG4gICAgZnVuY3Rpb24gc2xpY2UoYXJyYXksIHN0YXJ0LCBlbmQpIHtcbiAgICAgIHZhciBsZW5ndGggPSBhcnJheSA9PSBudWxsID8gMCA6IGFycmF5Lmxlbmd0aDtcbiAgICAgIGlmICghbGVuZ3RoKSB7XG4gICAgICAgIHJldHVybiBbXTtcbiAgICAgIH1cbiAgICAgIGlmIChlbmQgJiYgdHlwZW9mIGVuZCAhPSAnbnVtYmVyJyAmJiBpc0l0ZXJhdGVlQ2FsbChhcnJheSwgc3RhcnQsIGVuZCkpIHtcbiAgICAgICAgc3RhcnQgPSAwO1xuICAgICAgICBlbmQgPSBsZW5ndGg7XG4gICAgICB9XG4gICAgICBlbHNlIHtcbiAgICAgICAgc3RhcnQgPSBzdGFydCA9PSBudWxsID8gMCA6IHRvSW50ZWdlcihzdGFydCk7XG4gICAgICAgIGVuZCA9IGVuZCA9PT0gdW5kZWZpbmVkID8gbGVuZ3RoIDogdG9JbnRlZ2VyKGVuZCk7XG4gICAgICB9XG4gICAgICByZXR1cm4gYmFzZVNsaWNlKGFycmF5LCBzdGFydCwgZW5kKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBVc2VzIGEgYmluYXJ5IHNlYXJjaCB0byBkZXRlcm1pbmUgdGhlIGxvd2VzdCBpbmRleCBhdCB3aGljaCBgdmFsdWVgXG4gICAgICogc2hvdWxkIGJlIGluc2VydGVkIGludG8gYGFycmF5YCBpbiBvcmRlciB0byBtYWludGFpbiBpdHMgc29ydCBvcmRlci5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAwLjEuMFxuICAgICAqIEBjYXRlZ29yeSBBcnJheVxuICAgICAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBzb3J0ZWQgYXJyYXkgdG8gaW5zcGVjdC5cbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBldmFsdWF0ZS5cbiAgICAgKiBAcmV0dXJucyB7bnVtYmVyfSBSZXR1cm5zIHRoZSBpbmRleCBhdCB3aGljaCBgdmFsdWVgIHNob3VsZCBiZSBpbnNlcnRlZFxuICAgICAqICBpbnRvIGBhcnJheWAuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8uc29ydGVkSW5kZXgoWzMwLCA1MF0sIDQwKTtcbiAgICAgKiAvLyA9PiAxXG4gICAgICovXG4gICAgZnVuY3Rpb24gc29ydGVkSW5kZXgoYXJyYXksIHZhbHVlKSB7XG4gICAgICByZXR1cm4gYmFzZVNvcnRlZEluZGV4KGFycmF5LCB2YWx1ZSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhpcyBtZXRob2QgaXMgbGlrZSBgXy5zb3J0ZWRJbmRleGAgZXhjZXB0IHRoYXQgaXQgYWNjZXB0cyBgaXRlcmF0ZWVgXG4gICAgICogd2hpY2ggaXMgaW52b2tlZCBmb3IgYHZhbHVlYCBhbmQgZWFjaCBlbGVtZW50IG9mIGBhcnJheWAgdG8gY29tcHV0ZSB0aGVpclxuICAgICAqIHNvcnQgcmFua2luZy4gVGhlIGl0ZXJhdGVlIGlzIGludm9rZWQgd2l0aCBvbmUgYXJndW1lbnQ6ICh2YWx1ZSkuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgNC4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgQXJyYXlcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBhcnJheSBUaGUgc29ydGVkIGFycmF5IHRvIGluc3BlY3QuXG4gICAgICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gZXZhbHVhdGUuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gW2l0ZXJhdGVlPV8uaWRlbnRpdHldIFRoZSBpdGVyYXRlZSBpbnZva2VkIHBlciBlbGVtZW50LlxuICAgICAqIEByZXR1cm5zIHtudW1iZXJ9IFJldHVybnMgdGhlIGluZGV4IGF0IHdoaWNoIGB2YWx1ZWAgc2hvdWxkIGJlIGluc2VydGVkXG4gICAgICogIGludG8gYGFycmF5YC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogdmFyIG9iamVjdHMgPSBbeyAneCc6IDQgfSwgeyAneCc6IDUgfV07XG4gICAgICpcbiAgICAgKiBfLnNvcnRlZEluZGV4Qnkob2JqZWN0cywgeyAneCc6IDQgfSwgZnVuY3Rpb24obykgeyByZXR1cm4gby54OyB9KTtcbiAgICAgKiAvLyA9PiAwXG4gICAgICpcbiAgICAgKiAvLyBUaGUgYF8ucHJvcGVydHlgIGl0ZXJhdGVlIHNob3J0aGFuZC5cbiAgICAgKiBfLnNvcnRlZEluZGV4Qnkob2JqZWN0cywgeyAneCc6IDQgfSwgJ3gnKTtcbiAgICAgKiAvLyA9PiAwXG4gICAgICovXG4gICAgZnVuY3Rpb24gc29ydGVkSW5kZXhCeShhcnJheSwgdmFsdWUsIGl0ZXJhdGVlKSB7XG4gICAgICByZXR1cm4gYmFzZVNvcnRlZEluZGV4QnkoYXJyYXksIHZhbHVlLCBnZXRJdGVyYXRlZShpdGVyYXRlZSwgMikpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoaXMgbWV0aG9kIGlzIGxpa2UgYF8uaW5kZXhPZmAgZXhjZXB0IHRoYXQgaXQgcGVyZm9ybXMgYSBiaW5hcnlcbiAgICAgKiBzZWFyY2ggb24gYSBzb3J0ZWQgYGFycmF5YC5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSA0LjAuMFxuICAgICAqIEBjYXRlZ29yeSBBcnJheVxuICAgICAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBhcnJheSB0byBpbnNwZWN0LlxuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIHNlYXJjaCBmb3IuXG4gICAgICogQHJldHVybnMge251bWJlcn0gUmV0dXJucyB0aGUgaW5kZXggb2YgdGhlIG1hdGNoZWQgdmFsdWUsIGVsc2UgYC0xYC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy5zb3J0ZWRJbmRleE9mKFs0LCA1LCA1LCA1LCA2XSwgNSk7XG4gICAgICogLy8gPT4gMVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIHNvcnRlZEluZGV4T2YoYXJyYXksIHZhbHVlKSB7XG4gICAgICB2YXIgbGVuZ3RoID0gYXJyYXkgPT0gbnVsbCA/IDAgOiBhcnJheS5sZW5ndGg7XG4gICAgICBpZiAobGVuZ3RoKSB7XG4gICAgICAgIHZhciBpbmRleCA9IGJhc2VTb3J0ZWRJbmRleChhcnJheSwgdmFsdWUpO1xuICAgICAgICBpZiAoaW5kZXggPCBsZW5ndGggJiYgZXEoYXJyYXlbaW5kZXhdLCB2YWx1ZSkpIHtcbiAgICAgICAgICByZXR1cm4gaW5kZXg7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHJldHVybiAtMTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGlzIG1ldGhvZCBpcyBsaWtlIGBfLnNvcnRlZEluZGV4YCBleGNlcHQgdGhhdCBpdCByZXR1cm5zIHRoZSBoaWdoZXN0XG4gICAgICogaW5kZXggYXQgd2hpY2ggYHZhbHVlYCBzaG91bGQgYmUgaW5zZXJ0ZWQgaW50byBgYXJyYXlgIGluIG9yZGVyIHRvXG4gICAgICogbWFpbnRhaW4gaXRzIHNvcnQgb3JkZXIuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMy4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgQXJyYXlcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBhcnJheSBUaGUgc29ydGVkIGFycmF5IHRvIGluc3BlY3QuXG4gICAgICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gZXZhbHVhdGUuXG4gICAgICogQHJldHVybnMge251bWJlcn0gUmV0dXJucyB0aGUgaW5kZXggYXQgd2hpY2ggYHZhbHVlYCBzaG91bGQgYmUgaW5zZXJ0ZWRcbiAgICAgKiAgaW50byBgYXJyYXlgLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLnNvcnRlZExhc3RJbmRleChbNCwgNSwgNSwgNSwgNl0sIDUpO1xuICAgICAqIC8vID0+IDRcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBzb3J0ZWRMYXN0SW5kZXgoYXJyYXksIHZhbHVlKSB7XG4gICAgICByZXR1cm4gYmFzZVNvcnRlZEluZGV4KGFycmF5LCB2YWx1ZSwgdHJ1ZSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhpcyBtZXRob2QgaXMgbGlrZSBgXy5zb3J0ZWRMYXN0SW5kZXhgIGV4Y2VwdCB0aGF0IGl0IGFjY2VwdHMgYGl0ZXJhdGVlYFxuICAgICAqIHdoaWNoIGlzIGludm9rZWQgZm9yIGB2YWx1ZWAgYW5kIGVhY2ggZWxlbWVudCBvZiBgYXJyYXlgIHRvIGNvbXB1dGUgdGhlaXJcbiAgICAgKiBzb3J0IHJhbmtpbmcuIFRoZSBpdGVyYXRlZSBpcyBpbnZva2VkIHdpdGggb25lIGFyZ3VtZW50OiAodmFsdWUpLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDQuMC4wXG4gICAgICogQGNhdGVnb3J5IEFycmF5XG4gICAgICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIHNvcnRlZCBhcnJheSB0byBpbnNwZWN0LlxuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGV2YWx1YXRlLlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IFtpdGVyYXRlZT1fLmlkZW50aXR5XSBUaGUgaXRlcmF0ZWUgaW52b2tlZCBwZXIgZWxlbWVudC5cbiAgICAgKiBAcmV0dXJucyB7bnVtYmVyfSBSZXR1cm5zIHRoZSBpbmRleCBhdCB3aGljaCBgdmFsdWVgIHNob3VsZCBiZSBpbnNlcnRlZFxuICAgICAqICBpbnRvIGBhcnJheWAuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIHZhciBvYmplY3RzID0gW3sgJ3gnOiA0IH0sIHsgJ3gnOiA1IH1dO1xuICAgICAqXG4gICAgICogXy5zb3J0ZWRMYXN0SW5kZXhCeShvYmplY3RzLCB7ICd4JzogNCB9LCBmdW5jdGlvbihvKSB7IHJldHVybiBvLng7IH0pO1xuICAgICAqIC8vID0+IDFcbiAgICAgKlxuICAgICAqIC8vIFRoZSBgXy5wcm9wZXJ0eWAgaXRlcmF0ZWUgc2hvcnRoYW5kLlxuICAgICAqIF8uc29ydGVkTGFzdEluZGV4Qnkob2JqZWN0cywgeyAneCc6IDQgfSwgJ3gnKTtcbiAgICAgKiAvLyA9PiAxXG4gICAgICovXG4gICAgZnVuY3Rpb24gc29ydGVkTGFzdEluZGV4QnkoYXJyYXksIHZhbHVlLCBpdGVyYXRlZSkge1xuICAgICAgcmV0dXJuIGJhc2VTb3J0ZWRJbmRleEJ5KGFycmF5LCB2YWx1ZSwgZ2V0SXRlcmF0ZWUoaXRlcmF0ZWUsIDIpLCB0cnVlKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGlzIG1ldGhvZCBpcyBsaWtlIGBfLmxhc3RJbmRleE9mYCBleGNlcHQgdGhhdCBpdCBwZXJmb3JtcyBhIGJpbmFyeVxuICAgICAqIHNlYXJjaCBvbiBhIHNvcnRlZCBgYXJyYXlgLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDQuMC4wXG4gICAgICogQGNhdGVnb3J5IEFycmF5XG4gICAgICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIGluc3BlY3QuXG4gICAgICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gc2VhcmNoIGZvci5cbiAgICAgKiBAcmV0dXJucyB7bnVtYmVyfSBSZXR1cm5zIHRoZSBpbmRleCBvZiB0aGUgbWF0Y2hlZCB2YWx1ZSwgZWxzZSBgLTFgLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLnNvcnRlZExhc3RJbmRleE9mKFs0LCA1LCA1LCA1LCA2XSwgNSk7XG4gICAgICogLy8gPT4gM1xuICAgICAqL1xuICAgIGZ1bmN0aW9uIHNvcnRlZExhc3RJbmRleE9mKGFycmF5LCB2YWx1ZSkge1xuICAgICAgdmFyIGxlbmd0aCA9IGFycmF5ID09IG51bGwgPyAwIDogYXJyYXkubGVuZ3RoO1xuICAgICAgaWYgKGxlbmd0aCkge1xuICAgICAgICB2YXIgaW5kZXggPSBiYXNlU29ydGVkSW5kZXgoYXJyYXksIHZhbHVlLCB0cnVlKSAtIDE7XG4gICAgICAgIGlmIChlcShhcnJheVtpbmRleF0sIHZhbHVlKSkge1xuICAgICAgICAgIHJldHVybiBpbmRleDtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgcmV0dXJuIC0xO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoaXMgbWV0aG9kIGlzIGxpa2UgYF8udW5pcWAgZXhjZXB0IHRoYXQgaXQncyBkZXNpZ25lZCBhbmQgb3B0aW1pemVkXG4gICAgICogZm9yIHNvcnRlZCBhcnJheXMuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgNC4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgQXJyYXlcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBhcnJheSBUaGUgYXJyYXkgdG8gaW5zcGVjdC5cbiAgICAgKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIG5ldyBkdXBsaWNhdGUgZnJlZSBhcnJheS5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy5zb3J0ZWRVbmlxKFsxLCAxLCAyXSk7XG4gICAgICogLy8gPT4gWzEsIDJdXG4gICAgICovXG4gICAgZnVuY3Rpb24gc29ydGVkVW5pcShhcnJheSkge1xuICAgICAgcmV0dXJuIChhcnJheSAmJiBhcnJheS5sZW5ndGgpXG4gICAgICAgID8gYmFzZVNvcnRlZFVuaXEoYXJyYXkpXG4gICAgICAgIDogW107XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhpcyBtZXRob2QgaXMgbGlrZSBgXy51bmlxQnlgIGV4Y2VwdCB0aGF0IGl0J3MgZGVzaWduZWQgYW5kIG9wdGltaXplZFxuICAgICAqIGZvciBzb3J0ZWQgYXJyYXlzLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDQuMC4wXG4gICAgICogQGNhdGVnb3J5IEFycmF5XG4gICAgICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIGluc3BlY3QuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gW2l0ZXJhdGVlXSBUaGUgaXRlcmF0ZWUgaW52b2tlZCBwZXIgZWxlbWVudC5cbiAgICAgKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIG5ldyBkdXBsaWNhdGUgZnJlZSBhcnJheS5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy5zb3J0ZWRVbmlxQnkoWzEuMSwgMS4yLCAyLjMsIDIuNF0sIE1hdGguZmxvb3IpO1xuICAgICAqIC8vID0+IFsxLjEsIDIuM11cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBzb3J0ZWRVbmlxQnkoYXJyYXksIGl0ZXJhdGVlKSB7XG4gICAgICByZXR1cm4gKGFycmF5ICYmIGFycmF5Lmxlbmd0aClcbiAgICAgICAgPyBiYXNlU29ydGVkVW5pcShhcnJheSwgZ2V0SXRlcmF0ZWUoaXRlcmF0ZWUsIDIpKVxuICAgICAgICA6IFtdO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEdldHMgYWxsIGJ1dCB0aGUgZmlyc3QgZWxlbWVudCBvZiBgYXJyYXlgLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDQuMC4wXG4gICAgICogQGNhdGVnb3J5IEFycmF5XG4gICAgICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIHF1ZXJ5LlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgc2xpY2Ugb2YgYGFycmF5YC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy50YWlsKFsxLCAyLCAzXSk7XG4gICAgICogLy8gPT4gWzIsIDNdXG4gICAgICovXG4gICAgZnVuY3Rpb24gdGFpbChhcnJheSkge1xuICAgICAgdmFyIGxlbmd0aCA9IGFycmF5ID09IG51bGwgPyAwIDogYXJyYXkubGVuZ3RoO1xuICAgICAgcmV0dXJuIGxlbmd0aCA/IGJhc2VTbGljZShhcnJheSwgMSwgbGVuZ3RoKSA6IFtdO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBzbGljZSBvZiBgYXJyYXlgIHdpdGggYG5gIGVsZW1lbnRzIHRha2VuIGZyb20gdGhlIGJlZ2lubmluZy5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAwLjEuMFxuICAgICAqIEBjYXRlZ29yeSBBcnJheVxuICAgICAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBhcnJheSB0byBxdWVyeS5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gW249MV0gVGhlIG51bWJlciBvZiBlbGVtZW50cyB0byB0YWtlLlxuICAgICAqIEBwYXJhbS0ge09iamVjdH0gW2d1YXJkXSBFbmFibGVzIHVzZSBhcyBhbiBpdGVyYXRlZSBmb3IgbWV0aG9kcyBsaWtlIGBfLm1hcGAuXG4gICAgICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBzbGljZSBvZiBgYXJyYXlgLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLnRha2UoWzEsIDIsIDNdKTtcbiAgICAgKiAvLyA9PiBbMV1cbiAgICAgKlxuICAgICAqIF8udGFrZShbMSwgMiwgM10sIDIpO1xuICAgICAqIC8vID0+IFsxLCAyXVxuICAgICAqXG4gICAgICogXy50YWtlKFsxLCAyLCAzXSwgNSk7XG4gICAgICogLy8gPT4gWzEsIDIsIDNdXG4gICAgICpcbiAgICAgKiBfLnRha2UoWzEsIDIsIDNdLCAwKTtcbiAgICAgKiAvLyA9PiBbXVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIHRha2UoYXJyYXksIG4sIGd1YXJkKSB7XG4gICAgICBpZiAoIShhcnJheSAmJiBhcnJheS5sZW5ndGgpKSB7XG4gICAgICAgIHJldHVybiBbXTtcbiAgICAgIH1cbiAgICAgIG4gPSAoZ3VhcmQgfHwgbiA9PT0gdW5kZWZpbmVkKSA/IDEgOiB0b0ludGVnZXIobik7XG4gICAgICByZXR1cm4gYmFzZVNsaWNlKGFycmF5LCAwLCBuIDwgMCA/IDAgOiBuKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgc2xpY2Ugb2YgYGFycmF5YCB3aXRoIGBuYCBlbGVtZW50cyB0YWtlbiBmcm9tIHRoZSBlbmQuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMy4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgQXJyYXlcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBhcnJheSBUaGUgYXJyYXkgdG8gcXVlcnkuXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IFtuPTFdIFRoZSBudW1iZXIgb2YgZWxlbWVudHMgdG8gdGFrZS5cbiAgICAgKiBAcGFyYW0tIHtPYmplY3R9IFtndWFyZF0gRW5hYmxlcyB1c2UgYXMgYW4gaXRlcmF0ZWUgZm9yIG1ldGhvZHMgbGlrZSBgXy5tYXBgLlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgc2xpY2Ugb2YgYGFycmF5YC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy50YWtlUmlnaHQoWzEsIDIsIDNdKTtcbiAgICAgKiAvLyA9PiBbM11cbiAgICAgKlxuICAgICAqIF8udGFrZVJpZ2h0KFsxLCAyLCAzXSwgMik7XG4gICAgICogLy8gPT4gWzIsIDNdXG4gICAgICpcbiAgICAgKiBfLnRha2VSaWdodChbMSwgMiwgM10sIDUpO1xuICAgICAqIC8vID0+IFsxLCAyLCAzXVxuICAgICAqXG4gICAgICogXy50YWtlUmlnaHQoWzEsIDIsIDNdLCAwKTtcbiAgICAgKiAvLyA9PiBbXVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIHRha2VSaWdodChhcnJheSwgbiwgZ3VhcmQpIHtcbiAgICAgIHZhciBsZW5ndGggPSBhcnJheSA9PSBudWxsID8gMCA6IGFycmF5Lmxlbmd0aDtcbiAgICAgIGlmICghbGVuZ3RoKSB7XG4gICAgICAgIHJldHVybiBbXTtcbiAgICAgIH1cbiAgICAgIG4gPSAoZ3VhcmQgfHwgbiA9PT0gdW5kZWZpbmVkKSA/IDEgOiB0b0ludGVnZXIobik7XG4gICAgICBuID0gbGVuZ3RoIC0gbjtcbiAgICAgIHJldHVybiBiYXNlU2xpY2UoYXJyYXksIG4gPCAwID8gMCA6IG4sIGxlbmd0aCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIHNsaWNlIG9mIGBhcnJheWAgd2l0aCBlbGVtZW50cyB0YWtlbiBmcm9tIHRoZSBlbmQuIEVsZW1lbnRzIGFyZVxuICAgICAqIHRha2VuIHVudGlsIGBwcmVkaWNhdGVgIHJldHVybnMgZmFsc2V5LiBUaGUgcHJlZGljYXRlIGlzIGludm9rZWQgd2l0aFxuICAgICAqIHRocmVlIGFyZ3VtZW50czogKHZhbHVlLCBpbmRleCwgYXJyYXkpLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDMuMC4wXG4gICAgICogQGNhdGVnb3J5IEFycmF5XG4gICAgICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIHF1ZXJ5LlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IFtwcmVkaWNhdGU9Xy5pZGVudGl0eV0gVGhlIGZ1bmN0aW9uIGludm9rZWQgcGVyIGl0ZXJhdGlvbi5cbiAgICAgKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIHNsaWNlIG9mIGBhcnJheWAuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIHZhciB1c2VycyA9IFtcbiAgICAgKiAgIHsgJ3VzZXInOiAnYmFybmV5JywgICdhY3RpdmUnOiB0cnVlIH0sXG4gICAgICogICB7ICd1c2VyJzogJ2ZyZWQnLCAgICAnYWN0aXZlJzogZmFsc2UgfSxcbiAgICAgKiAgIHsgJ3VzZXInOiAncGViYmxlcycsICdhY3RpdmUnOiBmYWxzZSB9XG4gICAgICogXTtcbiAgICAgKlxuICAgICAqIF8udGFrZVJpZ2h0V2hpbGUodXNlcnMsIGZ1bmN0aW9uKG8pIHsgcmV0dXJuICFvLmFjdGl2ZTsgfSk7XG4gICAgICogLy8gPT4gb2JqZWN0cyBmb3IgWydmcmVkJywgJ3BlYmJsZXMnXVxuICAgICAqXG4gICAgICogLy8gVGhlIGBfLm1hdGNoZXNgIGl0ZXJhdGVlIHNob3J0aGFuZC5cbiAgICAgKiBfLnRha2VSaWdodFdoaWxlKHVzZXJzLCB7ICd1c2VyJzogJ3BlYmJsZXMnLCAnYWN0aXZlJzogZmFsc2UgfSk7XG4gICAgICogLy8gPT4gb2JqZWN0cyBmb3IgWydwZWJibGVzJ11cbiAgICAgKlxuICAgICAqIC8vIFRoZSBgXy5tYXRjaGVzUHJvcGVydHlgIGl0ZXJhdGVlIHNob3J0aGFuZC5cbiAgICAgKiBfLnRha2VSaWdodFdoaWxlKHVzZXJzLCBbJ2FjdGl2ZScsIGZhbHNlXSk7XG4gICAgICogLy8gPT4gb2JqZWN0cyBmb3IgWydmcmVkJywgJ3BlYmJsZXMnXVxuICAgICAqXG4gICAgICogLy8gVGhlIGBfLnByb3BlcnR5YCBpdGVyYXRlZSBzaG9ydGhhbmQuXG4gICAgICogXy50YWtlUmlnaHRXaGlsZSh1c2VycywgJ2FjdGl2ZScpO1xuICAgICAqIC8vID0+IFtdXG4gICAgICovXG4gICAgZnVuY3Rpb24gdGFrZVJpZ2h0V2hpbGUoYXJyYXksIHByZWRpY2F0ZSkge1xuICAgICAgcmV0dXJuIChhcnJheSAmJiBhcnJheS5sZW5ndGgpXG4gICAgICAgID8gYmFzZVdoaWxlKGFycmF5LCBnZXRJdGVyYXRlZShwcmVkaWNhdGUsIDMpLCBmYWxzZSwgdHJ1ZSlcbiAgICAgICAgOiBbXTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgc2xpY2Ugb2YgYGFycmF5YCB3aXRoIGVsZW1lbnRzIHRha2VuIGZyb20gdGhlIGJlZ2lubmluZy4gRWxlbWVudHNcbiAgICAgKiBhcmUgdGFrZW4gdW50aWwgYHByZWRpY2F0ZWAgcmV0dXJucyBmYWxzZXkuIFRoZSBwcmVkaWNhdGUgaXMgaW52b2tlZCB3aXRoXG4gICAgICogdGhyZWUgYXJndW1lbnRzOiAodmFsdWUsIGluZGV4LCBhcnJheSkuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMy4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgQXJyYXlcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBhcnJheSBUaGUgYXJyYXkgdG8gcXVlcnkuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gW3ByZWRpY2F0ZT1fLmlkZW50aXR5XSBUaGUgZnVuY3Rpb24gaW52b2tlZCBwZXIgaXRlcmF0aW9uLlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgc2xpY2Ugb2YgYGFycmF5YC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogdmFyIHVzZXJzID0gW1xuICAgICAqICAgeyAndXNlcic6ICdiYXJuZXknLCAgJ2FjdGl2ZSc6IGZhbHNlIH0sXG4gICAgICogICB7ICd1c2VyJzogJ2ZyZWQnLCAgICAnYWN0aXZlJzogZmFsc2UgfSxcbiAgICAgKiAgIHsgJ3VzZXInOiAncGViYmxlcycsICdhY3RpdmUnOiB0cnVlIH1cbiAgICAgKiBdO1xuICAgICAqXG4gICAgICogXy50YWtlV2hpbGUodXNlcnMsIGZ1bmN0aW9uKG8pIHsgcmV0dXJuICFvLmFjdGl2ZTsgfSk7XG4gICAgICogLy8gPT4gb2JqZWN0cyBmb3IgWydiYXJuZXknLCAnZnJlZCddXG4gICAgICpcbiAgICAgKiAvLyBUaGUgYF8ubWF0Y2hlc2AgaXRlcmF0ZWUgc2hvcnRoYW5kLlxuICAgICAqIF8udGFrZVdoaWxlKHVzZXJzLCB7ICd1c2VyJzogJ2Jhcm5leScsICdhY3RpdmUnOiBmYWxzZSB9KTtcbiAgICAgKiAvLyA9PiBvYmplY3RzIGZvciBbJ2Jhcm5leSddXG4gICAgICpcbiAgICAgKiAvLyBUaGUgYF8ubWF0Y2hlc1Byb3BlcnR5YCBpdGVyYXRlZSBzaG9ydGhhbmQuXG4gICAgICogXy50YWtlV2hpbGUodXNlcnMsIFsnYWN0aXZlJywgZmFsc2VdKTtcbiAgICAgKiAvLyA9PiBvYmplY3RzIGZvciBbJ2Jhcm5leScsICdmcmVkJ11cbiAgICAgKlxuICAgICAqIC8vIFRoZSBgXy5wcm9wZXJ0eWAgaXRlcmF0ZWUgc2hvcnRoYW5kLlxuICAgICAqIF8udGFrZVdoaWxlKHVzZXJzLCAnYWN0aXZlJyk7XG4gICAgICogLy8gPT4gW11cbiAgICAgKi9cbiAgICBmdW5jdGlvbiB0YWtlV2hpbGUoYXJyYXksIHByZWRpY2F0ZSkge1xuICAgICAgcmV0dXJuIChhcnJheSAmJiBhcnJheS5sZW5ndGgpXG4gICAgICAgID8gYmFzZVdoaWxlKGFycmF5LCBnZXRJdGVyYXRlZShwcmVkaWNhdGUsIDMpKVxuICAgICAgICA6IFtdO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYW4gYXJyYXkgb2YgdW5pcXVlIHZhbHVlcywgaW4gb3JkZXIsIGZyb20gYWxsIGdpdmVuIGFycmF5cyB1c2luZ1xuICAgICAqIFtgU2FtZVZhbHVlWmVyb2BdKGh0dHA6Ly9lY21hLWludGVybmF0aW9uYWwub3JnL2VjbWEtMjYyLzcuMC8jc2VjLXNhbWV2YWx1ZXplcm8pXG4gICAgICogZm9yIGVxdWFsaXR5IGNvbXBhcmlzb25zLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDAuMS4wXG4gICAgICogQGNhdGVnb3J5IEFycmF5XG4gICAgICogQHBhcmFtIHsuLi5BcnJheX0gW2FycmF5c10gVGhlIGFycmF5cyB0byBpbnNwZWN0LlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgbmV3IGFycmF5IG9mIGNvbWJpbmVkIHZhbHVlcy5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy51bmlvbihbMl0sIFsxLCAyXSk7XG4gICAgICogLy8gPT4gWzIsIDFdXG4gICAgICovXG4gICAgdmFyIHVuaW9uID0gYmFzZVJlc3QoZnVuY3Rpb24oYXJyYXlzKSB7XG4gICAgICByZXR1cm4gYmFzZVVuaXEoYmFzZUZsYXR0ZW4oYXJyYXlzLCAxLCBpc0FycmF5TGlrZU9iamVjdCwgdHJ1ZSkpO1xuICAgIH0pO1xuXG4gICAgLyoqXG4gICAgICogVGhpcyBtZXRob2QgaXMgbGlrZSBgXy51bmlvbmAgZXhjZXB0IHRoYXQgaXQgYWNjZXB0cyBgaXRlcmF0ZWVgIHdoaWNoIGlzXG4gICAgICogaW52b2tlZCBmb3IgZWFjaCBlbGVtZW50IG9mIGVhY2ggYGFycmF5c2AgdG8gZ2VuZXJhdGUgdGhlIGNyaXRlcmlvbiBieVxuICAgICAqIHdoaWNoIHVuaXF1ZW5lc3MgaXMgY29tcHV0ZWQuIFJlc3VsdCB2YWx1ZXMgYXJlIGNob3NlbiBmcm9tIHRoZSBmaXJzdFxuICAgICAqIGFycmF5IGluIHdoaWNoIHRoZSB2YWx1ZSBvY2N1cnMuIFRoZSBpdGVyYXRlZSBpcyBpbnZva2VkIHdpdGggb25lIGFyZ3VtZW50OlxuICAgICAqICh2YWx1ZSkuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgNC4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgQXJyYXlcbiAgICAgKiBAcGFyYW0gey4uLkFycmF5fSBbYXJyYXlzXSBUaGUgYXJyYXlzIHRvIGluc3BlY3QuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gW2l0ZXJhdGVlPV8uaWRlbnRpdHldIFRoZSBpdGVyYXRlZSBpbnZva2VkIHBlciBlbGVtZW50LlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgbmV3IGFycmF5IG9mIGNvbWJpbmVkIHZhbHVlcy5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy51bmlvbkJ5KFsyLjFdLCBbMS4yLCAyLjNdLCBNYXRoLmZsb29yKTtcbiAgICAgKiAvLyA9PiBbMi4xLCAxLjJdXG4gICAgICpcbiAgICAgKiAvLyBUaGUgYF8ucHJvcGVydHlgIGl0ZXJhdGVlIHNob3J0aGFuZC5cbiAgICAgKiBfLnVuaW9uQnkoW3sgJ3gnOiAxIH1dLCBbeyAneCc6IDIgfSwgeyAneCc6IDEgfV0sICd4Jyk7XG4gICAgICogLy8gPT4gW3sgJ3gnOiAxIH0sIHsgJ3gnOiAyIH1dXG4gICAgICovXG4gICAgdmFyIHVuaW9uQnkgPSBiYXNlUmVzdChmdW5jdGlvbihhcnJheXMpIHtcbiAgICAgIHZhciBpdGVyYXRlZSA9IGxhc3QoYXJyYXlzKTtcbiAgICAgIGlmIChpc0FycmF5TGlrZU9iamVjdChpdGVyYXRlZSkpIHtcbiAgICAgICAgaXRlcmF0ZWUgPSB1bmRlZmluZWQ7XG4gICAgICB9XG4gICAgICByZXR1cm4gYmFzZVVuaXEoYmFzZUZsYXR0ZW4oYXJyYXlzLCAxLCBpc0FycmF5TGlrZU9iamVjdCwgdHJ1ZSksIGdldEl0ZXJhdGVlKGl0ZXJhdGVlLCAyKSk7XG4gICAgfSk7XG5cbiAgICAvKipcbiAgICAgKiBUaGlzIG1ldGhvZCBpcyBsaWtlIGBfLnVuaW9uYCBleGNlcHQgdGhhdCBpdCBhY2NlcHRzIGBjb21wYXJhdG9yYCB3aGljaFxuICAgICAqIGlzIGludm9rZWQgdG8gY29tcGFyZSBlbGVtZW50cyBvZiBgYXJyYXlzYC4gUmVzdWx0IHZhbHVlcyBhcmUgY2hvc2VuIGZyb21cbiAgICAgKiB0aGUgZmlyc3QgYXJyYXkgaW4gd2hpY2ggdGhlIHZhbHVlIG9jY3Vycy4gVGhlIGNvbXBhcmF0b3IgaXMgaW52b2tlZFxuICAgICAqIHdpdGggdHdvIGFyZ3VtZW50czogKGFyclZhbCwgb3RoVmFsKS5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSA0LjAuMFxuICAgICAqIEBjYXRlZ29yeSBBcnJheVxuICAgICAqIEBwYXJhbSB7Li4uQXJyYXl9IFthcnJheXNdIFRoZSBhcnJheXMgdG8gaW5zcGVjdC5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBbY29tcGFyYXRvcl0gVGhlIGNvbXBhcmF0b3IgaW52b2tlZCBwZXIgZWxlbWVudC5cbiAgICAgKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIG5ldyBhcnJheSBvZiBjb21iaW5lZCB2YWx1ZXMuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIHZhciBvYmplY3RzID0gW3sgJ3gnOiAxLCAneSc6IDIgfSwgeyAneCc6IDIsICd5JzogMSB9XTtcbiAgICAgKiB2YXIgb3RoZXJzID0gW3sgJ3gnOiAxLCAneSc6IDEgfSwgeyAneCc6IDEsICd5JzogMiB9XTtcbiAgICAgKlxuICAgICAqIF8udW5pb25XaXRoKG9iamVjdHMsIG90aGVycywgXy5pc0VxdWFsKTtcbiAgICAgKiAvLyA9PiBbeyAneCc6IDEsICd5JzogMiB9LCB7ICd4JzogMiwgJ3knOiAxIH0sIHsgJ3gnOiAxLCAneSc6IDEgfV1cbiAgICAgKi9cbiAgICB2YXIgdW5pb25XaXRoID0gYmFzZVJlc3QoZnVuY3Rpb24oYXJyYXlzKSB7XG4gICAgICB2YXIgY29tcGFyYXRvciA9IGxhc3QoYXJyYXlzKTtcbiAgICAgIGNvbXBhcmF0b3IgPSB0eXBlb2YgY29tcGFyYXRvciA9PSAnZnVuY3Rpb24nID8gY29tcGFyYXRvciA6IHVuZGVmaW5lZDtcbiAgICAgIHJldHVybiBiYXNlVW5pcShiYXNlRmxhdHRlbihhcnJheXMsIDEsIGlzQXJyYXlMaWtlT2JqZWN0LCB0cnVlKSwgdW5kZWZpbmVkLCBjb21wYXJhdG9yKTtcbiAgICB9KTtcblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBkdXBsaWNhdGUtZnJlZSB2ZXJzaW9uIG9mIGFuIGFycmF5LCB1c2luZ1xuICAgICAqIFtgU2FtZVZhbHVlWmVyb2BdKGh0dHA6Ly9lY21hLWludGVybmF0aW9uYWwub3JnL2VjbWEtMjYyLzcuMC8jc2VjLXNhbWV2YWx1ZXplcm8pXG4gICAgICogZm9yIGVxdWFsaXR5IGNvbXBhcmlzb25zLCBpbiB3aGljaCBvbmx5IHRoZSBmaXJzdCBvY2N1cnJlbmNlIG9mIGVhY2ggZWxlbWVudFxuICAgICAqIGlzIGtlcHQuIFRoZSBvcmRlciBvZiByZXN1bHQgdmFsdWVzIGlzIGRldGVybWluZWQgYnkgdGhlIG9yZGVyIHRoZXkgb2NjdXJcbiAgICAgKiBpbiB0aGUgYXJyYXkuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMC4xLjBcbiAgICAgKiBAY2F0ZWdvcnkgQXJyYXlcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBhcnJheSBUaGUgYXJyYXkgdG8gaW5zcGVjdC5cbiAgICAgKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIG5ldyBkdXBsaWNhdGUgZnJlZSBhcnJheS5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy51bmlxKFsyLCAxLCAyXSk7XG4gICAgICogLy8gPT4gWzIsIDFdXG4gICAgICovXG4gICAgZnVuY3Rpb24gdW5pcShhcnJheSkge1xuICAgICAgcmV0dXJuIChhcnJheSAmJiBhcnJheS5sZW5ndGgpID8gYmFzZVVuaXEoYXJyYXkpIDogW107XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhpcyBtZXRob2QgaXMgbGlrZSBgXy51bmlxYCBleGNlcHQgdGhhdCBpdCBhY2NlcHRzIGBpdGVyYXRlZWAgd2hpY2ggaXNcbiAgICAgKiBpbnZva2VkIGZvciBlYWNoIGVsZW1lbnQgaW4gYGFycmF5YCB0byBnZW5lcmF0ZSB0aGUgY3JpdGVyaW9uIGJ5IHdoaWNoXG4gICAgICogdW5pcXVlbmVzcyBpcyBjb21wdXRlZC4gVGhlIG9yZGVyIG9mIHJlc3VsdCB2YWx1ZXMgaXMgZGV0ZXJtaW5lZCBieSB0aGVcbiAgICAgKiBvcmRlciB0aGV5IG9jY3VyIGluIHRoZSBhcnJheS4gVGhlIGl0ZXJhdGVlIGlzIGludm9rZWQgd2l0aCBvbmUgYXJndW1lbnQ6XG4gICAgICogKHZhbHVlKS5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSA0LjAuMFxuICAgICAqIEBjYXRlZ29yeSBBcnJheVxuICAgICAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBhcnJheSB0byBpbnNwZWN0LlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IFtpdGVyYXRlZT1fLmlkZW50aXR5XSBUaGUgaXRlcmF0ZWUgaW52b2tlZCBwZXIgZWxlbWVudC5cbiAgICAgKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIG5ldyBkdXBsaWNhdGUgZnJlZSBhcnJheS5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy51bmlxQnkoWzIuMSwgMS4yLCAyLjNdLCBNYXRoLmZsb29yKTtcbiAgICAgKiAvLyA9PiBbMi4xLCAxLjJdXG4gICAgICpcbiAgICAgKiAvLyBUaGUgYF8ucHJvcGVydHlgIGl0ZXJhdGVlIHNob3J0aGFuZC5cbiAgICAgKiBfLnVuaXFCeShbeyAneCc6IDEgfSwgeyAneCc6IDIgfSwgeyAneCc6IDEgfV0sICd4Jyk7XG4gICAgICogLy8gPT4gW3sgJ3gnOiAxIH0sIHsgJ3gnOiAyIH1dXG4gICAgICovXG4gICAgZnVuY3Rpb24gdW5pcUJ5KGFycmF5LCBpdGVyYXRlZSkge1xuICAgICAgcmV0dXJuIChhcnJheSAmJiBhcnJheS5sZW5ndGgpID8gYmFzZVVuaXEoYXJyYXksIGdldEl0ZXJhdGVlKGl0ZXJhdGVlLCAyKSkgOiBbXTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGlzIG1ldGhvZCBpcyBsaWtlIGBfLnVuaXFgIGV4Y2VwdCB0aGF0IGl0IGFjY2VwdHMgYGNvbXBhcmF0b3JgIHdoaWNoXG4gICAgICogaXMgaW52b2tlZCB0byBjb21wYXJlIGVsZW1lbnRzIG9mIGBhcnJheWAuIFRoZSBvcmRlciBvZiByZXN1bHQgdmFsdWVzIGlzXG4gICAgICogZGV0ZXJtaW5lZCBieSB0aGUgb3JkZXIgdGhleSBvY2N1ciBpbiB0aGUgYXJyYXkuVGhlIGNvbXBhcmF0b3IgaXMgaW52b2tlZFxuICAgICAqIHdpdGggdHdvIGFyZ3VtZW50czogKGFyclZhbCwgb3RoVmFsKS5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSA0LjAuMFxuICAgICAqIEBjYXRlZ29yeSBBcnJheVxuICAgICAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBhcnJheSB0byBpbnNwZWN0LlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IFtjb21wYXJhdG9yXSBUaGUgY29tcGFyYXRvciBpbnZva2VkIHBlciBlbGVtZW50LlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgbmV3IGR1cGxpY2F0ZSBmcmVlIGFycmF5LlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiB2YXIgb2JqZWN0cyA9IFt7ICd4JzogMSwgJ3knOiAyIH0sIHsgJ3gnOiAyLCAneSc6IDEgfSwgeyAneCc6IDEsICd5JzogMiB9XTtcbiAgICAgKlxuICAgICAqIF8udW5pcVdpdGgob2JqZWN0cywgXy5pc0VxdWFsKTtcbiAgICAgKiAvLyA9PiBbeyAneCc6IDEsICd5JzogMiB9LCB7ICd4JzogMiwgJ3knOiAxIH1dXG4gICAgICovXG4gICAgZnVuY3Rpb24gdW5pcVdpdGgoYXJyYXksIGNvbXBhcmF0b3IpIHtcbiAgICAgIGNvbXBhcmF0b3IgPSB0eXBlb2YgY29tcGFyYXRvciA9PSAnZnVuY3Rpb24nID8gY29tcGFyYXRvciA6IHVuZGVmaW5lZDtcbiAgICAgIHJldHVybiAoYXJyYXkgJiYgYXJyYXkubGVuZ3RoKSA/IGJhc2VVbmlxKGFycmF5LCB1bmRlZmluZWQsIGNvbXBhcmF0b3IpIDogW107XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhpcyBtZXRob2QgaXMgbGlrZSBgXy56aXBgIGV4Y2VwdCB0aGF0IGl0IGFjY2VwdHMgYW4gYXJyYXkgb2YgZ3JvdXBlZFxuICAgICAqIGVsZW1lbnRzIGFuZCBjcmVhdGVzIGFuIGFycmF5IHJlZ3JvdXBpbmcgdGhlIGVsZW1lbnRzIHRvIHRoZWlyIHByZS16aXBcbiAgICAgKiBjb25maWd1cmF0aW9uLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDEuMi4wXG4gICAgICogQGNhdGVnb3J5IEFycmF5XG4gICAgICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IG9mIGdyb3VwZWQgZWxlbWVudHMgdG8gcHJvY2Vzcy5cbiAgICAgKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIG5ldyBhcnJheSBvZiByZWdyb3VwZWQgZWxlbWVudHMuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIHZhciB6aXBwZWQgPSBfLnppcChbJ2EnLCAnYiddLCBbMSwgMl0sIFt0cnVlLCBmYWxzZV0pO1xuICAgICAqIC8vID0+IFtbJ2EnLCAxLCB0cnVlXSwgWydiJywgMiwgZmFsc2VdXVxuICAgICAqXG4gICAgICogXy51bnppcCh6aXBwZWQpO1xuICAgICAqIC8vID0+IFtbJ2EnLCAnYiddLCBbMSwgMl0sIFt0cnVlLCBmYWxzZV1dXG4gICAgICovXG4gICAgZnVuY3Rpb24gdW56aXAoYXJyYXkpIHtcbiAgICAgIGlmICghKGFycmF5ICYmIGFycmF5Lmxlbmd0aCkpIHtcbiAgICAgICAgcmV0dXJuIFtdO1xuICAgICAgfVxuICAgICAgdmFyIGxlbmd0aCA9IDA7XG4gICAgICBhcnJheSA9IGFycmF5RmlsdGVyKGFycmF5LCBmdW5jdGlvbihncm91cCkge1xuICAgICAgICBpZiAoaXNBcnJheUxpa2VPYmplY3QoZ3JvdXApKSB7XG4gICAgICAgICAgbGVuZ3RoID0gbmF0aXZlTWF4KGdyb3VwLmxlbmd0aCwgbGVuZ3RoKTtcbiAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgICByZXR1cm4gYmFzZVRpbWVzKGxlbmd0aCwgZnVuY3Rpb24oaW5kZXgpIHtcbiAgICAgICAgcmV0dXJuIGFycmF5TWFwKGFycmF5LCBiYXNlUHJvcGVydHkoaW5kZXgpKTtcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoaXMgbWV0aG9kIGlzIGxpa2UgYF8udW56aXBgIGV4Y2VwdCB0aGF0IGl0IGFjY2VwdHMgYGl0ZXJhdGVlYCB0byBzcGVjaWZ5XG4gICAgICogaG93IHJlZ3JvdXBlZCB2YWx1ZXMgc2hvdWxkIGJlIGNvbWJpbmVkLiBUaGUgaXRlcmF0ZWUgaXMgaW52b2tlZCB3aXRoIHRoZVxuICAgICAqIGVsZW1lbnRzIG9mIGVhY2ggZ3JvdXA6ICguLi5ncm91cCkuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMy44LjBcbiAgICAgKiBAY2F0ZWdvcnkgQXJyYXlcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBhcnJheSBUaGUgYXJyYXkgb2YgZ3JvdXBlZCBlbGVtZW50cyB0byBwcm9jZXNzLlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IFtpdGVyYXRlZT1fLmlkZW50aXR5XSBUaGUgZnVuY3Rpb24gdG8gY29tYmluZVxuICAgICAqICByZWdyb3VwZWQgdmFsdWVzLlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgbmV3IGFycmF5IG9mIHJlZ3JvdXBlZCBlbGVtZW50cy5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogdmFyIHppcHBlZCA9IF8uemlwKFsxLCAyXSwgWzEwLCAyMF0sIFsxMDAsIDIwMF0pO1xuICAgICAqIC8vID0+IFtbMSwgMTAsIDEwMF0sIFsyLCAyMCwgMjAwXV1cbiAgICAgKlxuICAgICAqIF8udW56aXBXaXRoKHppcHBlZCwgXy5hZGQpO1xuICAgICAqIC8vID0+IFszLCAzMCwgMzAwXVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIHVuemlwV2l0aChhcnJheSwgaXRlcmF0ZWUpIHtcbiAgICAgIGlmICghKGFycmF5ICYmIGFycmF5Lmxlbmd0aCkpIHtcbiAgICAgICAgcmV0dXJuIFtdO1xuICAgICAgfVxuICAgICAgdmFyIHJlc3VsdCA9IHVuemlwKGFycmF5KTtcbiAgICAgIGlmIChpdGVyYXRlZSA9PSBudWxsKSB7XG4gICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgICB9XG4gICAgICByZXR1cm4gYXJyYXlNYXAocmVzdWx0LCBmdW5jdGlvbihncm91cCkge1xuICAgICAgICByZXR1cm4gYXBwbHkoaXRlcmF0ZWUsIHVuZGVmaW5lZCwgZ3JvdXApO1xuICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhbiBhcnJheSBleGNsdWRpbmcgYWxsIGdpdmVuIHZhbHVlcyB1c2luZ1xuICAgICAqIFtgU2FtZVZhbHVlWmVyb2BdKGh0dHA6Ly9lY21hLWludGVybmF0aW9uYWwub3JnL2VjbWEtMjYyLzcuMC8jc2VjLXNhbWV2YWx1ZXplcm8pXG4gICAgICogZm9yIGVxdWFsaXR5IGNvbXBhcmlzb25zLlxuICAgICAqXG4gICAgICogKipOb3RlOioqIFVubGlrZSBgXy5wdWxsYCwgdGhpcyBtZXRob2QgcmV0dXJucyBhIG5ldyBhcnJheS5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAwLjEuMFxuICAgICAqIEBjYXRlZ29yeSBBcnJheVxuICAgICAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBhcnJheSB0byBpbnNwZWN0LlxuICAgICAqIEBwYXJhbSB7Li4uKn0gW3ZhbHVlc10gVGhlIHZhbHVlcyB0byBleGNsdWRlLlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgbmV3IGFycmF5IG9mIGZpbHRlcmVkIHZhbHVlcy5cbiAgICAgKiBAc2VlIF8uZGlmZmVyZW5jZSwgXy54b3JcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy53aXRob3V0KFsyLCAxLCAyLCAzXSwgMSwgMik7XG4gICAgICogLy8gPT4gWzNdXG4gICAgICovXG4gICAgdmFyIHdpdGhvdXQgPSBiYXNlUmVzdChmdW5jdGlvbihhcnJheSwgdmFsdWVzKSB7XG4gICAgICByZXR1cm4gaXNBcnJheUxpa2VPYmplY3QoYXJyYXkpXG4gICAgICAgID8gYmFzZURpZmZlcmVuY2UoYXJyYXksIHZhbHVlcylcbiAgICAgICAgOiBbXTtcbiAgICB9KTtcblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYW4gYXJyYXkgb2YgdW5pcXVlIHZhbHVlcyB0aGF0IGlzIHRoZVxuICAgICAqIFtzeW1tZXRyaWMgZGlmZmVyZW5jZV0oaHR0cHM6Ly9lbi53aWtpcGVkaWEub3JnL3dpa2kvU3ltbWV0cmljX2RpZmZlcmVuY2UpXG4gICAgICogb2YgdGhlIGdpdmVuIGFycmF5cy4gVGhlIG9yZGVyIG9mIHJlc3VsdCB2YWx1ZXMgaXMgZGV0ZXJtaW5lZCBieSB0aGUgb3JkZXJcbiAgICAgKiB0aGV5IG9jY3VyIGluIHRoZSBhcnJheXMuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMi40LjBcbiAgICAgKiBAY2F0ZWdvcnkgQXJyYXlcbiAgICAgKiBAcGFyYW0gey4uLkFycmF5fSBbYXJyYXlzXSBUaGUgYXJyYXlzIHRvIGluc3BlY3QuXG4gICAgICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBuZXcgYXJyYXkgb2YgZmlsdGVyZWQgdmFsdWVzLlxuICAgICAqIEBzZWUgXy5kaWZmZXJlbmNlLCBfLndpdGhvdXRcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy54b3IoWzIsIDFdLCBbMiwgM10pO1xuICAgICAqIC8vID0+IFsxLCAzXVxuICAgICAqL1xuICAgIHZhciB4b3IgPSBiYXNlUmVzdChmdW5jdGlvbihhcnJheXMpIHtcbiAgICAgIHJldHVybiBiYXNlWG9yKGFycmF5RmlsdGVyKGFycmF5cywgaXNBcnJheUxpa2VPYmplY3QpKTtcbiAgICB9KTtcblxuICAgIC8qKlxuICAgICAqIFRoaXMgbWV0aG9kIGlzIGxpa2UgYF8ueG9yYCBleGNlcHQgdGhhdCBpdCBhY2NlcHRzIGBpdGVyYXRlZWAgd2hpY2ggaXNcbiAgICAgKiBpbnZva2VkIGZvciBlYWNoIGVsZW1lbnQgb2YgZWFjaCBgYXJyYXlzYCB0byBnZW5lcmF0ZSB0aGUgY3JpdGVyaW9uIGJ5XG4gICAgICogd2hpY2ggYnkgd2hpY2ggdGhleSdyZSBjb21wYXJlZC4gVGhlIG9yZGVyIG9mIHJlc3VsdCB2YWx1ZXMgaXMgZGV0ZXJtaW5lZFxuICAgICAqIGJ5IHRoZSBvcmRlciB0aGV5IG9jY3VyIGluIHRoZSBhcnJheXMuIFRoZSBpdGVyYXRlZSBpcyBpbnZva2VkIHdpdGggb25lXG4gICAgICogYXJndW1lbnQ6ICh2YWx1ZSkuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgNC4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgQXJyYXlcbiAgICAgKiBAcGFyYW0gey4uLkFycmF5fSBbYXJyYXlzXSBUaGUgYXJyYXlzIHRvIGluc3BlY3QuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gW2l0ZXJhdGVlPV8uaWRlbnRpdHldIFRoZSBpdGVyYXRlZSBpbnZva2VkIHBlciBlbGVtZW50LlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgbmV3IGFycmF5IG9mIGZpbHRlcmVkIHZhbHVlcy5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy54b3JCeShbMi4xLCAxLjJdLCBbMi4zLCAzLjRdLCBNYXRoLmZsb29yKTtcbiAgICAgKiAvLyA9PiBbMS4yLCAzLjRdXG4gICAgICpcbiAgICAgKiAvLyBUaGUgYF8ucHJvcGVydHlgIGl0ZXJhdGVlIHNob3J0aGFuZC5cbiAgICAgKiBfLnhvckJ5KFt7ICd4JzogMSB9XSwgW3sgJ3gnOiAyIH0sIHsgJ3gnOiAxIH1dLCAneCcpO1xuICAgICAqIC8vID0+IFt7ICd4JzogMiB9XVxuICAgICAqL1xuICAgIHZhciB4b3JCeSA9IGJhc2VSZXN0KGZ1bmN0aW9uKGFycmF5cykge1xuICAgICAgdmFyIGl0ZXJhdGVlID0gbGFzdChhcnJheXMpO1xuICAgICAgaWYgKGlzQXJyYXlMaWtlT2JqZWN0KGl0ZXJhdGVlKSkge1xuICAgICAgICBpdGVyYXRlZSA9IHVuZGVmaW5lZDtcbiAgICAgIH1cbiAgICAgIHJldHVybiBiYXNlWG9yKGFycmF5RmlsdGVyKGFycmF5cywgaXNBcnJheUxpa2VPYmplY3QpLCBnZXRJdGVyYXRlZShpdGVyYXRlZSwgMikpO1xuICAgIH0pO1xuXG4gICAgLyoqXG4gICAgICogVGhpcyBtZXRob2QgaXMgbGlrZSBgXy54b3JgIGV4Y2VwdCB0aGF0IGl0IGFjY2VwdHMgYGNvbXBhcmF0b3JgIHdoaWNoIGlzXG4gICAgICogaW52b2tlZCB0byBjb21wYXJlIGVsZW1lbnRzIG9mIGBhcnJheXNgLiBUaGUgb3JkZXIgb2YgcmVzdWx0IHZhbHVlcyBpc1xuICAgICAqIGRldGVybWluZWQgYnkgdGhlIG9yZGVyIHRoZXkgb2NjdXIgaW4gdGhlIGFycmF5cy4gVGhlIGNvbXBhcmF0b3IgaXMgaW52b2tlZFxuICAgICAqIHdpdGggdHdvIGFyZ3VtZW50czogKGFyclZhbCwgb3RoVmFsKS5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSA0LjAuMFxuICAgICAqIEBjYXRlZ29yeSBBcnJheVxuICAgICAqIEBwYXJhbSB7Li4uQXJyYXl9IFthcnJheXNdIFRoZSBhcnJheXMgdG8gaW5zcGVjdC5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBbY29tcGFyYXRvcl0gVGhlIGNvbXBhcmF0b3IgaW52b2tlZCBwZXIgZWxlbWVudC5cbiAgICAgKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIG5ldyBhcnJheSBvZiBmaWx0ZXJlZCB2YWx1ZXMuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIHZhciBvYmplY3RzID0gW3sgJ3gnOiAxLCAneSc6IDIgfSwgeyAneCc6IDIsICd5JzogMSB9XTtcbiAgICAgKiB2YXIgb3RoZXJzID0gW3sgJ3gnOiAxLCAneSc6IDEgfSwgeyAneCc6IDEsICd5JzogMiB9XTtcbiAgICAgKlxuICAgICAqIF8ueG9yV2l0aChvYmplY3RzLCBvdGhlcnMsIF8uaXNFcXVhbCk7XG4gICAgICogLy8gPT4gW3sgJ3gnOiAyLCAneSc6IDEgfSwgeyAneCc6IDEsICd5JzogMSB9XVxuICAgICAqL1xuICAgIHZhciB4b3JXaXRoID0gYmFzZVJlc3QoZnVuY3Rpb24oYXJyYXlzKSB7XG4gICAgICB2YXIgY29tcGFyYXRvciA9IGxhc3QoYXJyYXlzKTtcbiAgICAgIGNvbXBhcmF0b3IgPSB0eXBlb2YgY29tcGFyYXRvciA9PSAnZnVuY3Rpb24nID8gY29tcGFyYXRvciA6IHVuZGVmaW5lZDtcbiAgICAgIHJldHVybiBiYXNlWG9yKGFycmF5RmlsdGVyKGFycmF5cywgaXNBcnJheUxpa2VPYmplY3QpLCB1bmRlZmluZWQsIGNvbXBhcmF0b3IpO1xuICAgIH0pO1xuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhbiBhcnJheSBvZiBncm91cGVkIGVsZW1lbnRzLCB0aGUgZmlyc3Qgb2Ygd2hpY2ggY29udGFpbnMgdGhlXG4gICAgICogZmlyc3QgZWxlbWVudHMgb2YgdGhlIGdpdmVuIGFycmF5cywgdGhlIHNlY29uZCBvZiB3aGljaCBjb250YWlucyB0aGVcbiAgICAgKiBzZWNvbmQgZWxlbWVudHMgb2YgdGhlIGdpdmVuIGFycmF5cywgYW5kIHNvIG9uLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDAuMS4wXG4gICAgICogQGNhdGVnb3J5IEFycmF5XG4gICAgICogQHBhcmFtIHsuLi5BcnJheX0gW2FycmF5c10gVGhlIGFycmF5cyB0byBwcm9jZXNzLlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgbmV3IGFycmF5IG9mIGdyb3VwZWQgZWxlbWVudHMuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8uemlwKFsnYScsICdiJ10sIFsxLCAyXSwgW3RydWUsIGZhbHNlXSk7XG4gICAgICogLy8gPT4gW1snYScsIDEsIHRydWVdLCBbJ2InLCAyLCBmYWxzZV1dXG4gICAgICovXG4gICAgdmFyIHppcCA9IGJhc2VSZXN0KHVuemlwKTtcblxuICAgIC8qKlxuICAgICAqIFRoaXMgbWV0aG9kIGlzIGxpa2UgYF8uZnJvbVBhaXJzYCBleGNlcHQgdGhhdCBpdCBhY2NlcHRzIHR3byBhcnJheXMsXG4gICAgICogb25lIG9mIHByb3BlcnR5IGlkZW50aWZpZXJzIGFuZCBvbmUgb2YgY29ycmVzcG9uZGluZyB2YWx1ZXMuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMC40LjBcbiAgICAgKiBAY2F0ZWdvcnkgQXJyYXlcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBbcHJvcHM9W11dIFRoZSBwcm9wZXJ0eSBpZGVudGlmaWVycy5cbiAgICAgKiBAcGFyYW0ge0FycmF5fSBbdmFsdWVzPVtdXSBUaGUgcHJvcGVydHkgdmFsdWVzLlxuICAgICAqIEByZXR1cm5zIHtPYmplY3R9IFJldHVybnMgdGhlIG5ldyBvYmplY3QuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8uemlwT2JqZWN0KFsnYScsICdiJ10sIFsxLCAyXSk7XG4gICAgICogLy8gPT4geyAnYSc6IDEsICdiJzogMiB9XG4gICAgICovXG4gICAgZnVuY3Rpb24gemlwT2JqZWN0KHByb3BzLCB2YWx1ZXMpIHtcbiAgICAgIHJldHVybiBiYXNlWmlwT2JqZWN0KHByb3BzIHx8IFtdLCB2YWx1ZXMgfHwgW10sIGFzc2lnblZhbHVlKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGlzIG1ldGhvZCBpcyBsaWtlIGBfLnppcE9iamVjdGAgZXhjZXB0IHRoYXQgaXQgc3VwcG9ydHMgcHJvcGVydHkgcGF0aHMuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgNC4xLjBcbiAgICAgKiBAY2F0ZWdvcnkgQXJyYXlcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBbcHJvcHM9W11dIFRoZSBwcm9wZXJ0eSBpZGVudGlmaWVycy5cbiAgICAgKiBAcGFyYW0ge0FycmF5fSBbdmFsdWVzPVtdXSBUaGUgcHJvcGVydHkgdmFsdWVzLlxuICAgICAqIEByZXR1cm5zIHtPYmplY3R9IFJldHVybnMgdGhlIG5ldyBvYmplY3QuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8uemlwT2JqZWN0RGVlcChbJ2EuYlswXS5jJywgJ2EuYlsxXS5kJ10sIFsxLCAyXSk7XG4gICAgICogLy8gPT4geyAnYSc6IHsgJ2InOiBbeyAnYyc6IDEgfSwgeyAnZCc6IDIgfV0gfSB9XG4gICAgICovXG4gICAgZnVuY3Rpb24gemlwT2JqZWN0RGVlcChwcm9wcywgdmFsdWVzKSB7XG4gICAgICByZXR1cm4gYmFzZVppcE9iamVjdChwcm9wcyB8fCBbXSwgdmFsdWVzIHx8IFtdLCBiYXNlU2V0KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGlzIG1ldGhvZCBpcyBsaWtlIGBfLnppcGAgZXhjZXB0IHRoYXQgaXQgYWNjZXB0cyBgaXRlcmF0ZWVgIHRvIHNwZWNpZnlcbiAgICAgKiBob3cgZ3JvdXBlZCB2YWx1ZXMgc2hvdWxkIGJlIGNvbWJpbmVkLiBUaGUgaXRlcmF0ZWUgaXMgaW52b2tlZCB3aXRoIHRoZVxuICAgICAqIGVsZW1lbnRzIG9mIGVhY2ggZ3JvdXA6ICguLi5ncm91cCkuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMy44LjBcbiAgICAgKiBAY2F0ZWdvcnkgQXJyYXlcbiAgICAgKiBAcGFyYW0gey4uLkFycmF5fSBbYXJyYXlzXSBUaGUgYXJyYXlzIHRvIHByb2Nlc3MuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gW2l0ZXJhdGVlPV8uaWRlbnRpdHldIFRoZSBmdW5jdGlvbiB0byBjb21iaW5lXG4gICAgICogIGdyb3VwZWQgdmFsdWVzLlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgbmV3IGFycmF5IG9mIGdyb3VwZWQgZWxlbWVudHMuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8uemlwV2l0aChbMSwgMl0sIFsxMCwgMjBdLCBbMTAwLCAyMDBdLCBmdW5jdGlvbihhLCBiLCBjKSB7XG4gICAgICogICByZXR1cm4gYSArIGIgKyBjO1xuICAgICAqIH0pO1xuICAgICAqIC8vID0+IFsxMTEsIDIyMl1cbiAgICAgKi9cbiAgICB2YXIgemlwV2l0aCA9IGJhc2VSZXN0KGZ1bmN0aW9uKGFycmF5cykge1xuICAgICAgdmFyIGxlbmd0aCA9IGFycmF5cy5sZW5ndGgsXG4gICAgICAgICAgaXRlcmF0ZWUgPSBsZW5ndGggPiAxID8gYXJyYXlzW2xlbmd0aCAtIDFdIDogdW5kZWZpbmVkO1xuXG4gICAgICBpdGVyYXRlZSA9IHR5cGVvZiBpdGVyYXRlZSA9PSAnZnVuY3Rpb24nID8gKGFycmF5cy5wb3AoKSwgaXRlcmF0ZWUpIDogdW5kZWZpbmVkO1xuICAgICAgcmV0dXJuIHVuemlwV2l0aChhcnJheXMsIGl0ZXJhdGVlKTtcbiAgICB9KTtcblxuICAgIC8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi9cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBgbG9kYXNoYCB3cmFwcGVyIGluc3RhbmNlIHRoYXQgd3JhcHMgYHZhbHVlYCB3aXRoIGV4cGxpY2l0IG1ldGhvZFxuICAgICAqIGNoYWluIHNlcXVlbmNlcyBlbmFibGVkLiBUaGUgcmVzdWx0IG9mIHN1Y2ggc2VxdWVuY2VzIG11c3QgYmUgdW53cmFwcGVkXG4gICAgICogd2l0aCBgXyN2YWx1ZWAuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMS4zLjBcbiAgICAgKiBAY2F0ZWdvcnkgU2VxXG4gICAgICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gd3JhcC5cbiAgICAgKiBAcmV0dXJucyB7T2JqZWN0fSBSZXR1cm5zIHRoZSBuZXcgYGxvZGFzaGAgd3JhcHBlciBpbnN0YW5jZS5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogdmFyIHVzZXJzID0gW1xuICAgICAqICAgeyAndXNlcic6ICdiYXJuZXknLCAgJ2FnZSc6IDM2IH0sXG4gICAgICogICB7ICd1c2VyJzogJ2ZyZWQnLCAgICAnYWdlJzogNDAgfSxcbiAgICAgKiAgIHsgJ3VzZXInOiAncGViYmxlcycsICdhZ2UnOiAxIH1cbiAgICAgKiBdO1xuICAgICAqXG4gICAgICogdmFyIHlvdW5nZXN0ID0gX1xuICAgICAqICAgLmNoYWluKHVzZXJzKVxuICAgICAqICAgLnNvcnRCeSgnYWdlJylcbiAgICAgKiAgIC5tYXAoZnVuY3Rpb24obykge1xuICAgICAqICAgICByZXR1cm4gby51c2VyICsgJyBpcyAnICsgby5hZ2U7XG4gICAgICogICB9KVxuICAgICAqICAgLmhlYWQoKVxuICAgICAqICAgLnZhbHVlKCk7XG4gICAgICogLy8gPT4gJ3BlYmJsZXMgaXMgMSdcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBjaGFpbih2YWx1ZSkge1xuICAgICAgdmFyIHJlc3VsdCA9IGxvZGFzaCh2YWx1ZSk7XG4gICAgICByZXN1bHQuX19jaGFpbl9fID0gdHJ1ZTtcbiAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhpcyBtZXRob2QgaW52b2tlcyBgaW50ZXJjZXB0b3JgIGFuZCByZXR1cm5zIGB2YWx1ZWAuIFRoZSBpbnRlcmNlcHRvclxuICAgICAqIGlzIGludm9rZWQgd2l0aCBvbmUgYXJndW1lbnQ7ICh2YWx1ZSkuIFRoZSBwdXJwb3NlIG9mIHRoaXMgbWV0aG9kIGlzIHRvXG4gICAgICogXCJ0YXAgaW50b1wiIGEgbWV0aG9kIGNoYWluIHNlcXVlbmNlIGluIG9yZGVyIHRvIG1vZGlmeSBpbnRlcm1lZGlhdGUgcmVzdWx0cy5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAwLjEuMFxuICAgICAqIEBjYXRlZ29yeSBTZXFcbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBwcm92aWRlIHRvIGBpbnRlcmNlcHRvcmAuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gaW50ZXJjZXB0b3IgVGhlIGZ1bmN0aW9uIHRvIGludm9rZS5cbiAgICAgKiBAcmV0dXJucyB7Kn0gUmV0dXJucyBgdmFsdWVgLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfKFsxLCAyLCAzXSlcbiAgICAgKiAgLnRhcChmdW5jdGlvbihhcnJheSkge1xuICAgICAqICAgIC8vIE11dGF0ZSBpbnB1dCBhcnJheS5cbiAgICAgKiAgICBhcnJheS5wb3AoKTtcbiAgICAgKiAgfSlcbiAgICAgKiAgLnJldmVyc2UoKVxuICAgICAqICAudmFsdWUoKTtcbiAgICAgKiAvLyA9PiBbMiwgMV1cbiAgICAgKi9cbiAgICBmdW5jdGlvbiB0YXAodmFsdWUsIGludGVyY2VwdG9yKSB7XG4gICAgICBpbnRlcmNlcHRvcih2YWx1ZSk7XG4gICAgICByZXR1cm4gdmFsdWU7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhpcyBtZXRob2QgaXMgbGlrZSBgXy50YXBgIGV4Y2VwdCB0aGF0IGl0IHJldHVybnMgdGhlIHJlc3VsdCBvZiBgaW50ZXJjZXB0b3JgLlxuICAgICAqIFRoZSBwdXJwb3NlIG9mIHRoaXMgbWV0aG9kIGlzIHRvIFwicGFzcyB0aHJ1XCIgdmFsdWVzIHJlcGxhY2luZyBpbnRlcm1lZGlhdGVcbiAgICAgKiByZXN1bHRzIGluIGEgbWV0aG9kIGNoYWluIHNlcXVlbmNlLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDMuMC4wXG4gICAgICogQGNhdGVnb3J5IFNlcVxuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIHByb3ZpZGUgdG8gYGludGVyY2VwdG9yYC5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBpbnRlcmNlcHRvciBUaGUgZnVuY3Rpb24gdG8gaW52b2tlLlxuICAgICAqIEByZXR1cm5zIHsqfSBSZXR1cm5zIHRoZSByZXN1bHQgb2YgYGludGVyY2VwdG9yYC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXygnICBhYmMgICcpXG4gICAgICogIC5jaGFpbigpXG4gICAgICogIC50cmltKClcbiAgICAgKiAgLnRocnUoZnVuY3Rpb24odmFsdWUpIHtcbiAgICAgKiAgICByZXR1cm4gW3ZhbHVlXTtcbiAgICAgKiAgfSlcbiAgICAgKiAgLnZhbHVlKCk7XG4gICAgICogLy8gPT4gWydhYmMnXVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIHRocnUodmFsdWUsIGludGVyY2VwdG9yKSB7XG4gICAgICByZXR1cm4gaW50ZXJjZXB0b3IodmFsdWUpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoaXMgbWV0aG9kIGlzIHRoZSB3cmFwcGVyIHZlcnNpb24gb2YgYF8uYXRgLlxuICAgICAqXG4gICAgICogQG5hbWUgYXRcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAxLjAuMFxuICAgICAqIEBjYXRlZ29yeSBTZXFcbiAgICAgKiBAcGFyYW0gey4uLihzdHJpbmd8c3RyaW5nW10pfSBbcGF0aHNdIFRoZSBwcm9wZXJ0eSBwYXRocyB0byBwaWNrLlxuICAgICAqIEByZXR1cm5zIHtPYmplY3R9IFJldHVybnMgdGhlIG5ldyBgbG9kYXNoYCB3cmFwcGVyIGluc3RhbmNlLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiB2YXIgb2JqZWN0ID0geyAnYSc6IFt7ICdiJzogeyAnYyc6IDMgfSB9LCA0XSB9O1xuICAgICAqXG4gICAgICogXyhvYmplY3QpLmF0KFsnYVswXS5iLmMnLCAnYVsxXSddKS52YWx1ZSgpO1xuICAgICAqIC8vID0+IFszLCA0XVxuICAgICAqL1xuICAgIHZhciB3cmFwcGVyQXQgPSBmbGF0UmVzdChmdW5jdGlvbihwYXRocykge1xuICAgICAgdmFyIGxlbmd0aCA9IHBhdGhzLmxlbmd0aCxcbiAgICAgICAgICBzdGFydCA9IGxlbmd0aCA/IHBhdGhzWzBdIDogMCxcbiAgICAgICAgICB2YWx1ZSA9IHRoaXMuX193cmFwcGVkX18sXG4gICAgICAgICAgaW50ZXJjZXB0b3IgPSBmdW5jdGlvbihvYmplY3QpIHsgcmV0dXJuIGJhc2VBdChvYmplY3QsIHBhdGhzKTsgfTtcblxuICAgICAgaWYgKGxlbmd0aCA+IDEgfHwgdGhpcy5fX2FjdGlvbnNfXy5sZW5ndGggfHxcbiAgICAgICAgICAhKHZhbHVlIGluc3RhbmNlb2YgTGF6eVdyYXBwZXIpIHx8ICFpc0luZGV4KHN0YXJ0KSkge1xuICAgICAgICByZXR1cm4gdGhpcy50aHJ1KGludGVyY2VwdG9yKTtcbiAgICAgIH1cbiAgICAgIHZhbHVlID0gdmFsdWUuc2xpY2Uoc3RhcnQsICtzdGFydCArIChsZW5ndGggPyAxIDogMCkpO1xuICAgICAgdmFsdWUuX19hY3Rpb25zX18ucHVzaCh7XG4gICAgICAgICdmdW5jJzogdGhydSxcbiAgICAgICAgJ2FyZ3MnOiBbaW50ZXJjZXB0b3JdLFxuICAgICAgICAndGhpc0FyZyc6IHVuZGVmaW5lZFxuICAgICAgfSk7XG4gICAgICByZXR1cm4gbmV3IExvZGFzaFdyYXBwZXIodmFsdWUsIHRoaXMuX19jaGFpbl9fKS50aHJ1KGZ1bmN0aW9uKGFycmF5KSB7XG4gICAgICAgIGlmIChsZW5ndGggJiYgIWFycmF5Lmxlbmd0aCkge1xuICAgICAgICAgIGFycmF5LnB1c2godW5kZWZpbmVkKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gYXJyYXk7XG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBgbG9kYXNoYCB3cmFwcGVyIGluc3RhbmNlIHdpdGggZXhwbGljaXQgbWV0aG9kIGNoYWluIHNlcXVlbmNlcyBlbmFibGVkLlxuICAgICAqXG4gICAgICogQG5hbWUgY2hhaW5cbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAwLjEuMFxuICAgICAqIEBjYXRlZ29yeSBTZXFcbiAgICAgKiBAcmV0dXJucyB7T2JqZWN0fSBSZXR1cm5zIHRoZSBuZXcgYGxvZGFzaGAgd3JhcHBlciBpbnN0YW5jZS5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogdmFyIHVzZXJzID0gW1xuICAgICAqICAgeyAndXNlcic6ICdiYXJuZXknLCAnYWdlJzogMzYgfSxcbiAgICAgKiAgIHsgJ3VzZXInOiAnZnJlZCcsICAgJ2FnZSc6IDQwIH1cbiAgICAgKiBdO1xuICAgICAqXG4gICAgICogLy8gQSBzZXF1ZW5jZSB3aXRob3V0IGV4cGxpY2l0IGNoYWluaW5nLlxuICAgICAqIF8odXNlcnMpLmhlYWQoKTtcbiAgICAgKiAvLyA9PiB7ICd1c2VyJzogJ2Jhcm5leScsICdhZ2UnOiAzNiB9XG4gICAgICpcbiAgICAgKiAvLyBBIHNlcXVlbmNlIHdpdGggZXhwbGljaXQgY2hhaW5pbmcuXG4gICAgICogXyh1c2VycylcbiAgICAgKiAgIC5jaGFpbigpXG4gICAgICogICAuaGVhZCgpXG4gICAgICogICAucGljaygndXNlcicpXG4gICAgICogICAudmFsdWUoKTtcbiAgICAgKiAvLyA9PiB7ICd1c2VyJzogJ2Jhcm5leScgfVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIHdyYXBwZXJDaGFpbigpIHtcbiAgICAgIHJldHVybiBjaGFpbih0aGlzKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBFeGVjdXRlcyB0aGUgY2hhaW4gc2VxdWVuY2UgYW5kIHJldHVybnMgdGhlIHdyYXBwZWQgcmVzdWx0LlxuICAgICAqXG4gICAgICogQG5hbWUgY29tbWl0XG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMy4yLjBcbiAgICAgKiBAY2F0ZWdvcnkgU2VxXG4gICAgICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyB0aGUgbmV3IGBsb2Rhc2hgIHdyYXBwZXIgaW5zdGFuY2UuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIHZhciBhcnJheSA9IFsxLCAyXTtcbiAgICAgKiB2YXIgd3JhcHBlZCA9IF8oYXJyYXkpLnB1c2goMyk7XG4gICAgICpcbiAgICAgKiBjb25zb2xlLmxvZyhhcnJheSk7XG4gICAgICogLy8gPT4gWzEsIDJdXG4gICAgICpcbiAgICAgKiB3cmFwcGVkID0gd3JhcHBlZC5jb21taXQoKTtcbiAgICAgKiBjb25zb2xlLmxvZyhhcnJheSk7XG4gICAgICogLy8gPT4gWzEsIDIsIDNdXG4gICAgICpcbiAgICAgKiB3cmFwcGVkLmxhc3QoKTtcbiAgICAgKiAvLyA9PiAzXG4gICAgICpcbiAgICAgKiBjb25zb2xlLmxvZyhhcnJheSk7XG4gICAgICogLy8gPT4gWzEsIDIsIDNdXG4gICAgICovXG4gICAgZnVuY3Rpb24gd3JhcHBlckNvbW1pdCgpIHtcbiAgICAgIHJldHVybiBuZXcgTG9kYXNoV3JhcHBlcih0aGlzLnZhbHVlKCksIHRoaXMuX19jaGFpbl9fKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBHZXRzIHRoZSBuZXh0IHZhbHVlIG9uIGEgd3JhcHBlZCBvYmplY3QgZm9sbG93aW5nIHRoZVxuICAgICAqIFtpdGVyYXRvciBwcm90b2NvbF0oaHR0cHM6Ly9tZG4uaW8vaXRlcmF0aW9uX3Byb3RvY29scyNpdGVyYXRvcikuXG4gICAgICpcbiAgICAgKiBAbmFtZSBuZXh0XG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgNC4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgU2VxXG4gICAgICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyB0aGUgbmV4dCBpdGVyYXRvciB2YWx1ZS5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogdmFyIHdyYXBwZWQgPSBfKFsxLCAyXSk7XG4gICAgICpcbiAgICAgKiB3cmFwcGVkLm5leHQoKTtcbiAgICAgKiAvLyA9PiB7ICdkb25lJzogZmFsc2UsICd2YWx1ZSc6IDEgfVxuICAgICAqXG4gICAgICogd3JhcHBlZC5uZXh0KCk7XG4gICAgICogLy8gPT4geyAnZG9uZSc6IGZhbHNlLCAndmFsdWUnOiAyIH1cbiAgICAgKlxuICAgICAqIHdyYXBwZWQubmV4dCgpO1xuICAgICAqIC8vID0+IHsgJ2RvbmUnOiB0cnVlLCAndmFsdWUnOiB1bmRlZmluZWQgfVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIHdyYXBwZXJOZXh0KCkge1xuICAgICAgaWYgKHRoaXMuX192YWx1ZXNfXyA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHRoaXMuX192YWx1ZXNfXyA9IHRvQXJyYXkodGhpcy52YWx1ZSgpKTtcbiAgICAgIH1cbiAgICAgIHZhciBkb25lID0gdGhpcy5fX2luZGV4X18gPj0gdGhpcy5fX3ZhbHVlc19fLmxlbmd0aCxcbiAgICAgICAgICB2YWx1ZSA9IGRvbmUgPyB1bmRlZmluZWQgOiB0aGlzLl9fdmFsdWVzX19bdGhpcy5fX2luZGV4X18rK107XG5cbiAgICAgIHJldHVybiB7ICdkb25lJzogZG9uZSwgJ3ZhbHVlJzogdmFsdWUgfTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBFbmFibGVzIHRoZSB3cmFwcGVyIHRvIGJlIGl0ZXJhYmxlLlxuICAgICAqXG4gICAgICogQG5hbWUgU3ltYm9sLml0ZXJhdG9yXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgNC4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgU2VxXG4gICAgICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyB0aGUgd3JhcHBlciBvYmplY3QuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIHZhciB3cmFwcGVkID0gXyhbMSwgMl0pO1xuICAgICAqXG4gICAgICogd3JhcHBlZFtTeW1ib2wuaXRlcmF0b3JdKCkgPT09IHdyYXBwZWQ7XG4gICAgICogLy8gPT4gdHJ1ZVxuICAgICAqXG4gICAgICogQXJyYXkuZnJvbSh3cmFwcGVkKTtcbiAgICAgKiAvLyA9PiBbMSwgMl1cbiAgICAgKi9cbiAgICBmdW5jdGlvbiB3cmFwcGVyVG9JdGVyYXRvcigpIHtcbiAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBjbG9uZSBvZiB0aGUgY2hhaW4gc2VxdWVuY2UgcGxhbnRpbmcgYHZhbHVlYCBhcyB0aGUgd3JhcHBlZCB2YWx1ZS5cbiAgICAgKlxuICAgICAqIEBuYW1lIHBsYW50XG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMy4yLjBcbiAgICAgKiBAY2F0ZWdvcnkgU2VxXG4gICAgICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gcGxhbnQuXG4gICAgICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyB0aGUgbmV3IGBsb2Rhc2hgIHdyYXBwZXIgaW5zdGFuY2UuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIGZ1bmN0aW9uIHNxdWFyZShuKSB7XG4gICAgICogICByZXR1cm4gbiAqIG47XG4gICAgICogfVxuICAgICAqXG4gICAgICogdmFyIHdyYXBwZWQgPSBfKFsxLCAyXSkubWFwKHNxdWFyZSk7XG4gICAgICogdmFyIG90aGVyID0gd3JhcHBlZC5wbGFudChbMywgNF0pO1xuICAgICAqXG4gICAgICogb3RoZXIudmFsdWUoKTtcbiAgICAgKiAvLyA9PiBbOSwgMTZdXG4gICAgICpcbiAgICAgKiB3cmFwcGVkLnZhbHVlKCk7XG4gICAgICogLy8gPT4gWzEsIDRdXG4gICAgICovXG4gICAgZnVuY3Rpb24gd3JhcHBlclBsYW50KHZhbHVlKSB7XG4gICAgICB2YXIgcmVzdWx0LFxuICAgICAgICAgIHBhcmVudCA9IHRoaXM7XG5cbiAgICAgIHdoaWxlIChwYXJlbnQgaW5zdGFuY2VvZiBiYXNlTG9kYXNoKSB7XG4gICAgICAgIHZhciBjbG9uZSA9IHdyYXBwZXJDbG9uZShwYXJlbnQpO1xuICAgICAgICBjbG9uZS5fX2luZGV4X18gPSAwO1xuICAgICAgICBjbG9uZS5fX3ZhbHVlc19fID0gdW5kZWZpbmVkO1xuICAgICAgICBpZiAocmVzdWx0KSB7XG4gICAgICAgICAgcHJldmlvdXMuX193cmFwcGVkX18gPSBjbG9uZTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICByZXN1bHQgPSBjbG9uZTtcbiAgICAgICAgfVxuICAgICAgICB2YXIgcHJldmlvdXMgPSBjbG9uZTtcbiAgICAgICAgcGFyZW50ID0gcGFyZW50Ll9fd3JhcHBlZF9fO1xuICAgICAgfVxuICAgICAgcHJldmlvdXMuX193cmFwcGVkX18gPSB2YWx1ZTtcbiAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhpcyBtZXRob2QgaXMgdGhlIHdyYXBwZXIgdmVyc2lvbiBvZiBgXy5yZXZlcnNlYC5cbiAgICAgKlxuICAgICAqICoqTm90ZToqKiBUaGlzIG1ldGhvZCBtdXRhdGVzIHRoZSB3cmFwcGVkIGFycmF5LlxuICAgICAqXG4gICAgICogQG5hbWUgcmV2ZXJzZVxuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDAuMS4wXG4gICAgICogQGNhdGVnb3J5IFNlcVxuICAgICAqIEByZXR1cm5zIHtPYmplY3R9IFJldHVybnMgdGhlIG5ldyBgbG9kYXNoYCB3cmFwcGVyIGluc3RhbmNlLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiB2YXIgYXJyYXkgPSBbMSwgMiwgM107XG4gICAgICpcbiAgICAgKiBfKGFycmF5KS5yZXZlcnNlKCkudmFsdWUoKVxuICAgICAqIC8vID0+IFszLCAyLCAxXVxuICAgICAqXG4gICAgICogY29uc29sZS5sb2coYXJyYXkpO1xuICAgICAqIC8vID0+IFszLCAyLCAxXVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIHdyYXBwZXJSZXZlcnNlKCkge1xuICAgICAgdmFyIHZhbHVlID0gdGhpcy5fX3dyYXBwZWRfXztcbiAgICAgIGlmICh2YWx1ZSBpbnN0YW5jZW9mIExhenlXcmFwcGVyKSB7XG4gICAgICAgIHZhciB3cmFwcGVkID0gdmFsdWU7XG4gICAgICAgIGlmICh0aGlzLl9fYWN0aW9uc19fLmxlbmd0aCkge1xuICAgICAgICAgIHdyYXBwZWQgPSBuZXcgTGF6eVdyYXBwZXIodGhpcyk7XG4gICAgICAgIH1cbiAgICAgICAgd3JhcHBlZCA9IHdyYXBwZWQucmV2ZXJzZSgpO1xuICAgICAgICB3cmFwcGVkLl9fYWN0aW9uc19fLnB1c2goe1xuICAgICAgICAgICdmdW5jJzogdGhydSxcbiAgICAgICAgICAnYXJncyc6IFtyZXZlcnNlXSxcbiAgICAgICAgICAndGhpc0FyZyc6IHVuZGVmaW5lZFxuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIG5ldyBMb2Rhc2hXcmFwcGVyKHdyYXBwZWQsIHRoaXMuX19jaGFpbl9fKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiB0aGlzLnRocnUocmV2ZXJzZSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogRXhlY3V0ZXMgdGhlIGNoYWluIHNlcXVlbmNlIHRvIHJlc29sdmUgdGhlIHVud3JhcHBlZCB2YWx1ZS5cbiAgICAgKlxuICAgICAqIEBuYW1lIHZhbHVlXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMC4xLjBcbiAgICAgKiBAYWxpYXMgdG9KU09OLCB2YWx1ZU9mXG4gICAgICogQGNhdGVnb3J5IFNlcVxuICAgICAqIEByZXR1cm5zIHsqfSBSZXR1cm5zIHRoZSByZXNvbHZlZCB1bndyYXBwZWQgdmFsdWUuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8oWzEsIDIsIDNdKS52YWx1ZSgpO1xuICAgICAqIC8vID0+IFsxLCAyLCAzXVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIHdyYXBwZXJWYWx1ZSgpIHtcbiAgICAgIHJldHVybiBiYXNlV3JhcHBlclZhbHVlKHRoaXMuX193cmFwcGVkX18sIHRoaXMuX19hY3Rpb25zX18pO1xuICAgIH1cblxuICAgIC8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi9cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYW4gb2JqZWN0IGNvbXBvc2VkIG9mIGtleXMgZ2VuZXJhdGVkIGZyb20gdGhlIHJlc3VsdHMgb2YgcnVubmluZ1xuICAgICAqIGVhY2ggZWxlbWVudCBvZiBgY29sbGVjdGlvbmAgdGhydSBgaXRlcmF0ZWVgLiBUaGUgY29ycmVzcG9uZGluZyB2YWx1ZSBvZlxuICAgICAqIGVhY2gga2V5IGlzIHRoZSBudW1iZXIgb2YgdGltZXMgdGhlIGtleSB3YXMgcmV0dXJuZWQgYnkgYGl0ZXJhdGVlYC4gVGhlXG4gICAgICogaXRlcmF0ZWUgaXMgaW52b2tlZCB3aXRoIG9uZSBhcmd1bWVudDogKHZhbHVlKS5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAwLjUuMFxuICAgICAqIEBjYXRlZ29yeSBDb2xsZWN0aW9uXG4gICAgICogQHBhcmFtIHtBcnJheXxPYmplY3R9IGNvbGxlY3Rpb24gVGhlIGNvbGxlY3Rpb24gdG8gaXRlcmF0ZSBvdmVyLlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IFtpdGVyYXRlZT1fLmlkZW50aXR5XSBUaGUgaXRlcmF0ZWUgdG8gdHJhbnNmb3JtIGtleXMuXG4gICAgICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyB0aGUgY29tcG9zZWQgYWdncmVnYXRlIG9iamVjdC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy5jb3VudEJ5KFs2LjEsIDQuMiwgNi4zXSwgTWF0aC5mbG9vcik7XG4gICAgICogLy8gPT4geyAnNCc6IDEsICc2JzogMiB9XG4gICAgICpcbiAgICAgKiAvLyBUaGUgYF8ucHJvcGVydHlgIGl0ZXJhdGVlIHNob3J0aGFuZC5cbiAgICAgKiBfLmNvdW50QnkoWydvbmUnLCAndHdvJywgJ3RocmVlJ10sICdsZW5ndGgnKTtcbiAgICAgKiAvLyA9PiB7ICczJzogMiwgJzUnOiAxIH1cbiAgICAgKi9cbiAgICB2YXIgY291bnRCeSA9IGNyZWF0ZUFnZ3JlZ2F0b3IoZnVuY3Rpb24ocmVzdWx0LCB2YWx1ZSwga2V5KSB7XG4gICAgICBpZiAoaGFzT3duUHJvcGVydHkuY2FsbChyZXN1bHQsIGtleSkpIHtcbiAgICAgICAgKytyZXN1bHRba2V5XTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGJhc2VBc3NpZ25WYWx1ZShyZXN1bHQsIGtleSwgMSk7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICAvKipcbiAgICAgKiBDaGVja3MgaWYgYHByZWRpY2F0ZWAgcmV0dXJucyB0cnV0aHkgZm9yICoqYWxsKiogZWxlbWVudHMgb2YgYGNvbGxlY3Rpb25gLlxuICAgICAqIEl0ZXJhdGlvbiBpcyBzdG9wcGVkIG9uY2UgYHByZWRpY2F0ZWAgcmV0dXJucyBmYWxzZXkuIFRoZSBwcmVkaWNhdGUgaXNcbiAgICAgKiBpbnZva2VkIHdpdGggdGhyZWUgYXJndW1lbnRzOiAodmFsdWUsIGluZGV4fGtleSwgY29sbGVjdGlvbikuXG4gICAgICpcbiAgICAgKiAqKk5vdGU6KiogVGhpcyBtZXRob2QgcmV0dXJucyBgdHJ1ZWAgZm9yXG4gICAgICogW2VtcHR5IGNvbGxlY3Rpb25zXShodHRwczovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9FbXB0eV9zZXQpIGJlY2F1c2VcbiAgICAgKiBbZXZlcnl0aGluZyBpcyB0cnVlXShodHRwczovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9WYWN1b3VzX3RydXRoKSBvZlxuICAgICAqIGVsZW1lbnRzIG9mIGVtcHR5IGNvbGxlY3Rpb25zLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDAuMS4wXG4gICAgICogQGNhdGVnb3J5IENvbGxlY3Rpb25cbiAgICAgKiBAcGFyYW0ge0FycmF5fE9iamVjdH0gY29sbGVjdGlvbiBUaGUgY29sbGVjdGlvbiB0byBpdGVyYXRlIG92ZXIuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gW3ByZWRpY2F0ZT1fLmlkZW50aXR5XSBUaGUgZnVuY3Rpb24gaW52b2tlZCBwZXIgaXRlcmF0aW9uLlxuICAgICAqIEBwYXJhbS0ge09iamVjdH0gW2d1YXJkXSBFbmFibGVzIHVzZSBhcyBhbiBpdGVyYXRlZSBmb3IgbWV0aG9kcyBsaWtlIGBfLm1hcGAuXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGFsbCBlbGVtZW50cyBwYXNzIHRoZSBwcmVkaWNhdGUgY2hlY2ssXG4gICAgICogIGVsc2UgYGZhbHNlYC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy5ldmVyeShbdHJ1ZSwgMSwgbnVsbCwgJ3llcyddLCBCb29sZWFuKTtcbiAgICAgKiAvLyA9PiBmYWxzZVxuICAgICAqXG4gICAgICogdmFyIHVzZXJzID0gW1xuICAgICAqICAgeyAndXNlcic6ICdiYXJuZXknLCAnYWdlJzogMzYsICdhY3RpdmUnOiBmYWxzZSB9LFxuICAgICAqICAgeyAndXNlcic6ICdmcmVkJywgICAnYWdlJzogNDAsICdhY3RpdmUnOiBmYWxzZSB9XG4gICAgICogXTtcbiAgICAgKlxuICAgICAqIC8vIFRoZSBgXy5tYXRjaGVzYCBpdGVyYXRlZSBzaG9ydGhhbmQuXG4gICAgICogXy5ldmVyeSh1c2VycywgeyAndXNlcic6ICdiYXJuZXknLCAnYWN0aXZlJzogZmFsc2UgfSk7XG4gICAgICogLy8gPT4gZmFsc2VcbiAgICAgKlxuICAgICAqIC8vIFRoZSBgXy5tYXRjaGVzUHJvcGVydHlgIGl0ZXJhdGVlIHNob3J0aGFuZC5cbiAgICAgKiBfLmV2ZXJ5KHVzZXJzLCBbJ2FjdGl2ZScsIGZhbHNlXSk7XG4gICAgICogLy8gPT4gdHJ1ZVxuICAgICAqXG4gICAgICogLy8gVGhlIGBfLnByb3BlcnR5YCBpdGVyYXRlZSBzaG9ydGhhbmQuXG4gICAgICogXy5ldmVyeSh1c2VycywgJ2FjdGl2ZScpO1xuICAgICAqIC8vID0+IGZhbHNlXG4gICAgICovXG4gICAgZnVuY3Rpb24gZXZlcnkoY29sbGVjdGlvbiwgcHJlZGljYXRlLCBndWFyZCkge1xuICAgICAgdmFyIGZ1bmMgPSBpc0FycmF5KGNvbGxlY3Rpb24pID8gYXJyYXlFdmVyeSA6IGJhc2VFdmVyeTtcbiAgICAgIGlmIChndWFyZCAmJiBpc0l0ZXJhdGVlQ2FsbChjb2xsZWN0aW9uLCBwcmVkaWNhdGUsIGd1YXJkKSkge1xuICAgICAgICBwcmVkaWNhdGUgPSB1bmRlZmluZWQ7XG4gICAgICB9XG4gICAgICByZXR1cm4gZnVuYyhjb2xsZWN0aW9uLCBnZXRJdGVyYXRlZShwcmVkaWNhdGUsIDMpKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBJdGVyYXRlcyBvdmVyIGVsZW1lbnRzIG9mIGBjb2xsZWN0aW9uYCwgcmV0dXJuaW5nIGFuIGFycmF5IG9mIGFsbCBlbGVtZW50c1xuICAgICAqIGBwcmVkaWNhdGVgIHJldHVybnMgdHJ1dGh5IGZvci4gVGhlIHByZWRpY2F0ZSBpcyBpbnZva2VkIHdpdGggdGhyZWVcbiAgICAgKiBhcmd1bWVudHM6ICh2YWx1ZSwgaW5kZXh8a2V5LCBjb2xsZWN0aW9uKS5cbiAgICAgKlxuICAgICAqICoqTm90ZToqKiBVbmxpa2UgYF8ucmVtb3ZlYCwgdGhpcyBtZXRob2QgcmV0dXJucyBhIG5ldyBhcnJheS5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAwLjEuMFxuICAgICAqIEBjYXRlZ29yeSBDb2xsZWN0aW9uXG4gICAgICogQHBhcmFtIHtBcnJheXxPYmplY3R9IGNvbGxlY3Rpb24gVGhlIGNvbGxlY3Rpb24gdG8gaXRlcmF0ZSBvdmVyLlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IFtwcmVkaWNhdGU9Xy5pZGVudGl0eV0gVGhlIGZ1bmN0aW9uIGludm9rZWQgcGVyIGl0ZXJhdGlvbi5cbiAgICAgKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIG5ldyBmaWx0ZXJlZCBhcnJheS5cbiAgICAgKiBAc2VlIF8ucmVqZWN0XG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIHZhciB1c2VycyA9IFtcbiAgICAgKiAgIHsgJ3VzZXInOiAnYmFybmV5JywgJ2FnZSc6IDM2LCAnYWN0aXZlJzogdHJ1ZSB9LFxuICAgICAqICAgeyAndXNlcic6ICdmcmVkJywgICAnYWdlJzogNDAsICdhY3RpdmUnOiBmYWxzZSB9XG4gICAgICogXTtcbiAgICAgKlxuICAgICAqIF8uZmlsdGVyKHVzZXJzLCBmdW5jdGlvbihvKSB7IHJldHVybiAhby5hY3RpdmU7IH0pO1xuICAgICAqIC8vID0+IG9iamVjdHMgZm9yIFsnZnJlZCddXG4gICAgICpcbiAgICAgKiAvLyBUaGUgYF8ubWF0Y2hlc2AgaXRlcmF0ZWUgc2hvcnRoYW5kLlxuICAgICAqIF8uZmlsdGVyKHVzZXJzLCB7ICdhZ2UnOiAzNiwgJ2FjdGl2ZSc6IHRydWUgfSk7XG4gICAgICogLy8gPT4gb2JqZWN0cyBmb3IgWydiYXJuZXknXVxuICAgICAqXG4gICAgICogLy8gVGhlIGBfLm1hdGNoZXNQcm9wZXJ0eWAgaXRlcmF0ZWUgc2hvcnRoYW5kLlxuICAgICAqIF8uZmlsdGVyKHVzZXJzLCBbJ2FjdGl2ZScsIGZhbHNlXSk7XG4gICAgICogLy8gPT4gb2JqZWN0cyBmb3IgWydmcmVkJ11cbiAgICAgKlxuICAgICAqIC8vIFRoZSBgXy5wcm9wZXJ0eWAgaXRlcmF0ZWUgc2hvcnRoYW5kLlxuICAgICAqIF8uZmlsdGVyKHVzZXJzLCAnYWN0aXZlJyk7XG4gICAgICogLy8gPT4gb2JqZWN0cyBmb3IgWydiYXJuZXknXVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGZpbHRlcihjb2xsZWN0aW9uLCBwcmVkaWNhdGUpIHtcbiAgICAgIHZhciBmdW5jID0gaXNBcnJheShjb2xsZWN0aW9uKSA/IGFycmF5RmlsdGVyIDogYmFzZUZpbHRlcjtcbiAgICAgIHJldHVybiBmdW5jKGNvbGxlY3Rpb24sIGdldEl0ZXJhdGVlKHByZWRpY2F0ZSwgMykpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEl0ZXJhdGVzIG92ZXIgZWxlbWVudHMgb2YgYGNvbGxlY3Rpb25gLCByZXR1cm5pbmcgdGhlIGZpcnN0IGVsZW1lbnRcbiAgICAgKiBgcHJlZGljYXRlYCByZXR1cm5zIHRydXRoeSBmb3IuIFRoZSBwcmVkaWNhdGUgaXMgaW52b2tlZCB3aXRoIHRocmVlXG4gICAgICogYXJndW1lbnRzOiAodmFsdWUsIGluZGV4fGtleSwgY29sbGVjdGlvbikuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMC4xLjBcbiAgICAgKiBAY2F0ZWdvcnkgQ29sbGVjdGlvblxuICAgICAqIEBwYXJhbSB7QXJyYXl8T2JqZWN0fSBjb2xsZWN0aW9uIFRoZSBjb2xsZWN0aW9uIHRvIGluc3BlY3QuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gW3ByZWRpY2F0ZT1fLmlkZW50aXR5XSBUaGUgZnVuY3Rpb24gaW52b2tlZCBwZXIgaXRlcmF0aW9uLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbZnJvbUluZGV4PTBdIFRoZSBpbmRleCB0byBzZWFyY2ggZnJvbS5cbiAgICAgKiBAcmV0dXJucyB7Kn0gUmV0dXJucyB0aGUgbWF0Y2hlZCBlbGVtZW50LCBlbHNlIGB1bmRlZmluZWRgLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiB2YXIgdXNlcnMgPSBbXG4gICAgICogICB7ICd1c2VyJzogJ2Jhcm5leScsICAnYWdlJzogMzYsICdhY3RpdmUnOiB0cnVlIH0sXG4gICAgICogICB7ICd1c2VyJzogJ2ZyZWQnLCAgICAnYWdlJzogNDAsICdhY3RpdmUnOiBmYWxzZSB9LFxuICAgICAqICAgeyAndXNlcic6ICdwZWJibGVzJywgJ2FnZSc6IDEsICAnYWN0aXZlJzogdHJ1ZSB9XG4gICAgICogXTtcbiAgICAgKlxuICAgICAqIF8uZmluZCh1c2VycywgZnVuY3Rpb24obykgeyByZXR1cm4gby5hZ2UgPCA0MDsgfSk7XG4gICAgICogLy8gPT4gb2JqZWN0IGZvciAnYmFybmV5J1xuICAgICAqXG4gICAgICogLy8gVGhlIGBfLm1hdGNoZXNgIGl0ZXJhdGVlIHNob3J0aGFuZC5cbiAgICAgKiBfLmZpbmQodXNlcnMsIHsgJ2FnZSc6IDEsICdhY3RpdmUnOiB0cnVlIH0pO1xuICAgICAqIC8vID0+IG9iamVjdCBmb3IgJ3BlYmJsZXMnXG4gICAgICpcbiAgICAgKiAvLyBUaGUgYF8ubWF0Y2hlc1Byb3BlcnR5YCBpdGVyYXRlZSBzaG9ydGhhbmQuXG4gICAgICogXy5maW5kKHVzZXJzLCBbJ2FjdGl2ZScsIGZhbHNlXSk7XG4gICAgICogLy8gPT4gb2JqZWN0IGZvciAnZnJlZCdcbiAgICAgKlxuICAgICAqIC8vIFRoZSBgXy5wcm9wZXJ0eWAgaXRlcmF0ZWUgc2hvcnRoYW5kLlxuICAgICAqIF8uZmluZCh1c2VycywgJ2FjdGl2ZScpO1xuICAgICAqIC8vID0+IG9iamVjdCBmb3IgJ2Jhcm5leSdcbiAgICAgKi9cbiAgICB2YXIgZmluZCA9IGNyZWF0ZUZpbmQoZmluZEluZGV4KTtcblxuICAgIC8qKlxuICAgICAqIFRoaXMgbWV0aG9kIGlzIGxpa2UgYF8uZmluZGAgZXhjZXB0IHRoYXQgaXQgaXRlcmF0ZXMgb3ZlciBlbGVtZW50cyBvZlxuICAgICAqIGBjb2xsZWN0aW9uYCBmcm9tIHJpZ2h0IHRvIGxlZnQuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMi4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgQ29sbGVjdGlvblxuICAgICAqIEBwYXJhbSB7QXJyYXl8T2JqZWN0fSBjb2xsZWN0aW9uIFRoZSBjb2xsZWN0aW9uIHRvIGluc3BlY3QuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gW3ByZWRpY2F0ZT1fLmlkZW50aXR5XSBUaGUgZnVuY3Rpb24gaW52b2tlZCBwZXIgaXRlcmF0aW9uLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbZnJvbUluZGV4PWNvbGxlY3Rpb24ubGVuZ3RoLTFdIFRoZSBpbmRleCB0byBzZWFyY2ggZnJvbS5cbiAgICAgKiBAcmV0dXJucyB7Kn0gUmV0dXJucyB0aGUgbWF0Y2hlZCBlbGVtZW50LCBlbHNlIGB1bmRlZmluZWRgLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLmZpbmRMYXN0KFsxLCAyLCAzLCA0XSwgZnVuY3Rpb24obikge1xuICAgICAqICAgcmV0dXJuIG4gJSAyID09IDE7XG4gICAgICogfSk7XG4gICAgICogLy8gPT4gM1xuICAgICAqL1xuICAgIHZhciBmaW5kTGFzdCA9IGNyZWF0ZUZpbmQoZmluZExhc3RJbmRleCk7XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgZmxhdHRlbmVkIGFycmF5IG9mIHZhbHVlcyBieSBydW5uaW5nIGVhY2ggZWxlbWVudCBpbiBgY29sbGVjdGlvbmBcbiAgICAgKiB0aHJ1IGBpdGVyYXRlZWAgYW5kIGZsYXR0ZW5pbmcgdGhlIG1hcHBlZCByZXN1bHRzLiBUaGUgaXRlcmF0ZWUgaXMgaW52b2tlZFxuICAgICAqIHdpdGggdGhyZWUgYXJndW1lbnRzOiAodmFsdWUsIGluZGV4fGtleSwgY29sbGVjdGlvbikuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgNC4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgQ29sbGVjdGlvblxuICAgICAqIEBwYXJhbSB7QXJyYXl8T2JqZWN0fSBjb2xsZWN0aW9uIFRoZSBjb2xsZWN0aW9uIHRvIGl0ZXJhdGUgb3Zlci5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBbaXRlcmF0ZWU9Xy5pZGVudGl0eV0gVGhlIGZ1bmN0aW9uIGludm9rZWQgcGVyIGl0ZXJhdGlvbi5cbiAgICAgKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIG5ldyBmbGF0dGVuZWQgYXJyYXkuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIGZ1bmN0aW9uIGR1cGxpY2F0ZShuKSB7XG4gICAgICogICByZXR1cm4gW24sIG5dO1xuICAgICAqIH1cbiAgICAgKlxuICAgICAqIF8uZmxhdE1hcChbMSwgMl0sIGR1cGxpY2F0ZSk7XG4gICAgICogLy8gPT4gWzEsIDEsIDIsIDJdXG4gICAgICovXG4gICAgZnVuY3Rpb24gZmxhdE1hcChjb2xsZWN0aW9uLCBpdGVyYXRlZSkge1xuICAgICAgcmV0dXJuIGJhc2VGbGF0dGVuKG1hcChjb2xsZWN0aW9uLCBpdGVyYXRlZSksIDEpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoaXMgbWV0aG9kIGlzIGxpa2UgYF8uZmxhdE1hcGAgZXhjZXB0IHRoYXQgaXQgcmVjdXJzaXZlbHkgZmxhdHRlbnMgdGhlXG4gICAgICogbWFwcGVkIHJlc3VsdHMuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgNC43LjBcbiAgICAgKiBAY2F0ZWdvcnkgQ29sbGVjdGlvblxuICAgICAqIEBwYXJhbSB7QXJyYXl8T2JqZWN0fSBjb2xsZWN0aW9uIFRoZSBjb2xsZWN0aW9uIHRvIGl0ZXJhdGUgb3Zlci5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBbaXRlcmF0ZWU9Xy5pZGVudGl0eV0gVGhlIGZ1bmN0aW9uIGludm9rZWQgcGVyIGl0ZXJhdGlvbi5cbiAgICAgKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIG5ldyBmbGF0dGVuZWQgYXJyYXkuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIGZ1bmN0aW9uIGR1cGxpY2F0ZShuKSB7XG4gICAgICogICByZXR1cm4gW1tbbiwgbl1dXTtcbiAgICAgKiB9XG4gICAgICpcbiAgICAgKiBfLmZsYXRNYXBEZWVwKFsxLCAyXSwgZHVwbGljYXRlKTtcbiAgICAgKiAvLyA9PiBbMSwgMSwgMiwgMl1cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBmbGF0TWFwRGVlcChjb2xsZWN0aW9uLCBpdGVyYXRlZSkge1xuICAgICAgcmV0dXJuIGJhc2VGbGF0dGVuKG1hcChjb2xsZWN0aW9uLCBpdGVyYXRlZSksIElORklOSVRZKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGlzIG1ldGhvZCBpcyBsaWtlIGBfLmZsYXRNYXBgIGV4Y2VwdCB0aGF0IGl0IHJlY3Vyc2l2ZWx5IGZsYXR0ZW5zIHRoZVxuICAgICAqIG1hcHBlZCByZXN1bHRzIHVwIHRvIGBkZXB0aGAgdGltZXMuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgNC43LjBcbiAgICAgKiBAY2F0ZWdvcnkgQ29sbGVjdGlvblxuICAgICAqIEBwYXJhbSB7QXJyYXl8T2JqZWN0fSBjb2xsZWN0aW9uIFRoZSBjb2xsZWN0aW9uIHRvIGl0ZXJhdGUgb3Zlci5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBbaXRlcmF0ZWU9Xy5pZGVudGl0eV0gVGhlIGZ1bmN0aW9uIGludm9rZWQgcGVyIGl0ZXJhdGlvbi5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gW2RlcHRoPTFdIFRoZSBtYXhpbXVtIHJlY3Vyc2lvbiBkZXB0aC5cbiAgICAgKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIG5ldyBmbGF0dGVuZWQgYXJyYXkuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIGZ1bmN0aW9uIGR1cGxpY2F0ZShuKSB7XG4gICAgICogICByZXR1cm4gW1tbbiwgbl1dXTtcbiAgICAgKiB9XG4gICAgICpcbiAgICAgKiBfLmZsYXRNYXBEZXB0aChbMSwgMl0sIGR1cGxpY2F0ZSwgMik7XG4gICAgICogLy8gPT4gW1sxLCAxXSwgWzIsIDJdXVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGZsYXRNYXBEZXB0aChjb2xsZWN0aW9uLCBpdGVyYXRlZSwgZGVwdGgpIHtcbiAgICAgIGRlcHRoID0gZGVwdGggPT09IHVuZGVmaW5lZCA/IDEgOiB0b0ludGVnZXIoZGVwdGgpO1xuICAgICAgcmV0dXJuIGJhc2VGbGF0dGVuKG1hcChjb2xsZWN0aW9uLCBpdGVyYXRlZSksIGRlcHRoKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBJdGVyYXRlcyBvdmVyIGVsZW1lbnRzIG9mIGBjb2xsZWN0aW9uYCBhbmQgaW52b2tlcyBgaXRlcmF0ZWVgIGZvciBlYWNoIGVsZW1lbnQuXG4gICAgICogVGhlIGl0ZXJhdGVlIGlzIGludm9rZWQgd2l0aCB0aHJlZSBhcmd1bWVudHM6ICh2YWx1ZSwgaW5kZXh8a2V5LCBjb2xsZWN0aW9uKS5cbiAgICAgKiBJdGVyYXRlZSBmdW5jdGlvbnMgbWF5IGV4aXQgaXRlcmF0aW9uIGVhcmx5IGJ5IGV4cGxpY2l0bHkgcmV0dXJuaW5nIGBmYWxzZWAuXG4gICAgICpcbiAgICAgKiAqKk5vdGU6KiogQXMgd2l0aCBvdGhlciBcIkNvbGxlY3Rpb25zXCIgbWV0aG9kcywgb2JqZWN0cyB3aXRoIGEgXCJsZW5ndGhcIlxuICAgICAqIHByb3BlcnR5IGFyZSBpdGVyYXRlZCBsaWtlIGFycmF5cy4gVG8gYXZvaWQgdGhpcyBiZWhhdmlvciB1c2UgYF8uZm9ySW5gXG4gICAgICogb3IgYF8uZm9yT3duYCBmb3Igb2JqZWN0IGl0ZXJhdGlvbi5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAwLjEuMFxuICAgICAqIEBhbGlhcyBlYWNoXG4gICAgICogQGNhdGVnb3J5IENvbGxlY3Rpb25cbiAgICAgKiBAcGFyYW0ge0FycmF5fE9iamVjdH0gY29sbGVjdGlvbiBUaGUgY29sbGVjdGlvbiB0byBpdGVyYXRlIG92ZXIuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gW2l0ZXJhdGVlPV8uaWRlbnRpdHldIFRoZSBmdW5jdGlvbiBpbnZva2VkIHBlciBpdGVyYXRpb24uXG4gICAgICogQHJldHVybnMge0FycmF5fE9iamVjdH0gUmV0dXJucyBgY29sbGVjdGlvbmAuXG4gICAgICogQHNlZSBfLmZvckVhY2hSaWdodFxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLmZvckVhY2goWzEsIDJdLCBmdW5jdGlvbih2YWx1ZSkge1xuICAgICAqICAgY29uc29sZS5sb2codmFsdWUpO1xuICAgICAqIH0pO1xuICAgICAqIC8vID0+IExvZ3MgYDFgIHRoZW4gYDJgLlxuICAgICAqXG4gICAgICogXy5mb3JFYWNoKHsgJ2EnOiAxLCAnYic6IDIgfSwgZnVuY3Rpb24odmFsdWUsIGtleSkge1xuICAgICAqICAgY29uc29sZS5sb2coa2V5KTtcbiAgICAgKiB9KTtcbiAgICAgKiAvLyA9PiBMb2dzICdhJyB0aGVuICdiJyAoaXRlcmF0aW9uIG9yZGVyIGlzIG5vdCBndWFyYW50ZWVkKS5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBmb3JFYWNoKGNvbGxlY3Rpb24sIGl0ZXJhdGVlKSB7XG4gICAgICB2YXIgZnVuYyA9IGlzQXJyYXkoY29sbGVjdGlvbikgPyBhcnJheUVhY2ggOiBiYXNlRWFjaDtcbiAgICAgIHJldHVybiBmdW5jKGNvbGxlY3Rpb24sIGdldEl0ZXJhdGVlKGl0ZXJhdGVlLCAzKSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhpcyBtZXRob2QgaXMgbGlrZSBgXy5mb3JFYWNoYCBleGNlcHQgdGhhdCBpdCBpdGVyYXRlcyBvdmVyIGVsZW1lbnRzIG9mXG4gICAgICogYGNvbGxlY3Rpb25gIGZyb20gcmlnaHQgdG8gbGVmdC5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAyLjAuMFxuICAgICAqIEBhbGlhcyBlYWNoUmlnaHRcbiAgICAgKiBAY2F0ZWdvcnkgQ29sbGVjdGlvblxuICAgICAqIEBwYXJhbSB7QXJyYXl8T2JqZWN0fSBjb2xsZWN0aW9uIFRoZSBjb2xsZWN0aW9uIHRvIGl0ZXJhdGUgb3Zlci5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBbaXRlcmF0ZWU9Xy5pZGVudGl0eV0gVGhlIGZ1bmN0aW9uIGludm9rZWQgcGVyIGl0ZXJhdGlvbi5cbiAgICAgKiBAcmV0dXJucyB7QXJyYXl8T2JqZWN0fSBSZXR1cm5zIGBjb2xsZWN0aW9uYC5cbiAgICAgKiBAc2VlIF8uZm9yRWFjaFxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLmZvckVhY2hSaWdodChbMSwgMl0sIGZ1bmN0aW9uKHZhbHVlKSB7XG4gICAgICogICBjb25zb2xlLmxvZyh2YWx1ZSk7XG4gICAgICogfSk7XG4gICAgICogLy8gPT4gTG9ncyBgMmAgdGhlbiBgMWAuXG4gICAgICovXG4gICAgZnVuY3Rpb24gZm9yRWFjaFJpZ2h0KGNvbGxlY3Rpb24sIGl0ZXJhdGVlKSB7XG4gICAgICB2YXIgZnVuYyA9IGlzQXJyYXkoY29sbGVjdGlvbikgPyBhcnJheUVhY2hSaWdodCA6IGJhc2VFYWNoUmlnaHQ7XG4gICAgICByZXR1cm4gZnVuYyhjb2xsZWN0aW9uLCBnZXRJdGVyYXRlZShpdGVyYXRlZSwgMykpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYW4gb2JqZWN0IGNvbXBvc2VkIG9mIGtleXMgZ2VuZXJhdGVkIGZyb20gdGhlIHJlc3VsdHMgb2YgcnVubmluZ1xuICAgICAqIGVhY2ggZWxlbWVudCBvZiBgY29sbGVjdGlvbmAgdGhydSBgaXRlcmF0ZWVgLiBUaGUgb3JkZXIgb2YgZ3JvdXBlZCB2YWx1ZXNcbiAgICAgKiBpcyBkZXRlcm1pbmVkIGJ5IHRoZSBvcmRlciB0aGV5IG9jY3VyIGluIGBjb2xsZWN0aW9uYC4gVGhlIGNvcnJlc3BvbmRpbmdcbiAgICAgKiB2YWx1ZSBvZiBlYWNoIGtleSBpcyBhbiBhcnJheSBvZiBlbGVtZW50cyByZXNwb25zaWJsZSBmb3IgZ2VuZXJhdGluZyB0aGVcbiAgICAgKiBrZXkuIFRoZSBpdGVyYXRlZSBpcyBpbnZva2VkIHdpdGggb25lIGFyZ3VtZW50OiAodmFsdWUpLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDAuMS4wXG4gICAgICogQGNhdGVnb3J5IENvbGxlY3Rpb25cbiAgICAgKiBAcGFyYW0ge0FycmF5fE9iamVjdH0gY29sbGVjdGlvbiBUaGUgY29sbGVjdGlvbiB0byBpdGVyYXRlIG92ZXIuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gW2l0ZXJhdGVlPV8uaWRlbnRpdHldIFRoZSBpdGVyYXRlZSB0byB0cmFuc2Zvcm0ga2V5cy5cbiAgICAgKiBAcmV0dXJucyB7T2JqZWN0fSBSZXR1cm5zIHRoZSBjb21wb3NlZCBhZ2dyZWdhdGUgb2JqZWN0LlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLmdyb3VwQnkoWzYuMSwgNC4yLCA2LjNdLCBNYXRoLmZsb29yKTtcbiAgICAgKiAvLyA9PiB7ICc0JzogWzQuMl0sICc2JzogWzYuMSwgNi4zXSB9XG4gICAgICpcbiAgICAgKiAvLyBUaGUgYF8ucHJvcGVydHlgIGl0ZXJhdGVlIHNob3J0aGFuZC5cbiAgICAgKiBfLmdyb3VwQnkoWydvbmUnLCAndHdvJywgJ3RocmVlJ10sICdsZW5ndGgnKTtcbiAgICAgKiAvLyA9PiB7ICczJzogWydvbmUnLCAndHdvJ10sICc1JzogWyd0aHJlZSddIH1cbiAgICAgKi9cbiAgICB2YXIgZ3JvdXBCeSA9IGNyZWF0ZUFnZ3JlZ2F0b3IoZnVuY3Rpb24ocmVzdWx0LCB2YWx1ZSwga2V5KSB7XG4gICAgICBpZiAoaGFzT3duUHJvcGVydHkuY2FsbChyZXN1bHQsIGtleSkpIHtcbiAgICAgICAgcmVzdWx0W2tleV0ucHVzaCh2YWx1ZSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBiYXNlQXNzaWduVmFsdWUocmVzdWx0LCBrZXksIFt2YWx1ZV0pO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgLyoqXG4gICAgICogQ2hlY2tzIGlmIGB2YWx1ZWAgaXMgaW4gYGNvbGxlY3Rpb25gLiBJZiBgY29sbGVjdGlvbmAgaXMgYSBzdHJpbmcsIGl0J3NcbiAgICAgKiBjaGVja2VkIGZvciBhIHN1YnN0cmluZyBvZiBgdmFsdWVgLCBvdGhlcndpc2VcbiAgICAgKiBbYFNhbWVWYWx1ZVplcm9gXShodHRwOi8vZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi83LjAvI3NlYy1zYW1ldmFsdWV6ZXJvKVxuICAgICAqIGlzIHVzZWQgZm9yIGVxdWFsaXR5IGNvbXBhcmlzb25zLiBJZiBgZnJvbUluZGV4YCBpcyBuZWdhdGl2ZSwgaXQncyB1c2VkIGFzXG4gICAgICogdGhlIG9mZnNldCBmcm9tIHRoZSBlbmQgb2YgYGNvbGxlY3Rpb25gLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDAuMS4wXG4gICAgICogQGNhdGVnb3J5IENvbGxlY3Rpb25cbiAgICAgKiBAcGFyYW0ge0FycmF5fE9iamVjdHxzdHJpbmd9IGNvbGxlY3Rpb24gVGhlIGNvbGxlY3Rpb24gdG8gaW5zcGVjdC5cbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBzZWFyY2ggZm9yLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbZnJvbUluZGV4PTBdIFRoZSBpbmRleCB0byBzZWFyY2ggZnJvbS5cbiAgICAgKiBAcGFyYW0tIHtPYmplY3R9IFtndWFyZF0gRW5hYmxlcyB1c2UgYXMgYW4gaXRlcmF0ZWUgZm9yIG1ldGhvZHMgbGlrZSBgXy5yZWR1Y2VgLlxuICAgICAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlzIGZvdW5kLCBlbHNlIGBmYWxzZWAuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8uaW5jbHVkZXMoWzEsIDIsIDNdLCAxKTtcbiAgICAgKiAvLyA9PiB0cnVlXG4gICAgICpcbiAgICAgKiBfLmluY2x1ZGVzKFsxLCAyLCAzXSwgMSwgMik7XG4gICAgICogLy8gPT4gZmFsc2VcbiAgICAgKlxuICAgICAqIF8uaW5jbHVkZXMoeyAnYSc6IDEsICdiJzogMiB9LCAxKTtcbiAgICAgKiAvLyA9PiB0cnVlXG4gICAgICpcbiAgICAgKiBfLmluY2x1ZGVzKCdhYmNkJywgJ2JjJyk7XG4gICAgICogLy8gPT4gdHJ1ZVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGluY2x1ZGVzKGNvbGxlY3Rpb24sIHZhbHVlLCBmcm9tSW5kZXgsIGd1YXJkKSB7XG4gICAgICBjb2xsZWN0aW9uID0gaXNBcnJheUxpa2UoY29sbGVjdGlvbikgPyBjb2xsZWN0aW9uIDogdmFsdWVzKGNvbGxlY3Rpb24pO1xuICAgICAgZnJvbUluZGV4ID0gKGZyb21JbmRleCAmJiAhZ3VhcmQpID8gdG9JbnRlZ2VyKGZyb21JbmRleCkgOiAwO1xuXG4gICAgICB2YXIgbGVuZ3RoID0gY29sbGVjdGlvbi5sZW5ndGg7XG4gICAgICBpZiAoZnJvbUluZGV4IDwgMCkge1xuICAgICAgICBmcm9tSW5kZXggPSBuYXRpdmVNYXgobGVuZ3RoICsgZnJvbUluZGV4LCAwKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBpc1N0cmluZyhjb2xsZWN0aW9uKVxuICAgICAgICA/IChmcm9tSW5kZXggPD0gbGVuZ3RoICYmIGNvbGxlY3Rpb24uaW5kZXhPZih2YWx1ZSwgZnJvbUluZGV4KSA+IC0xKVxuICAgICAgICA6ICghIWxlbmd0aCAmJiBiYXNlSW5kZXhPZihjb2xsZWN0aW9uLCB2YWx1ZSwgZnJvbUluZGV4KSA+IC0xKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBJbnZva2VzIHRoZSBtZXRob2QgYXQgYHBhdGhgIG9mIGVhY2ggZWxlbWVudCBpbiBgY29sbGVjdGlvbmAsIHJldHVybmluZ1xuICAgICAqIGFuIGFycmF5IG9mIHRoZSByZXN1bHRzIG9mIGVhY2ggaW52b2tlZCBtZXRob2QuIEFueSBhZGRpdGlvbmFsIGFyZ3VtZW50c1xuICAgICAqIGFyZSBwcm92aWRlZCB0byBlYWNoIGludm9rZWQgbWV0aG9kLiBJZiBgcGF0aGAgaXMgYSBmdW5jdGlvbiwgaXQncyBpbnZva2VkXG4gICAgICogZm9yLCBhbmQgYHRoaXNgIGJvdW5kIHRvLCBlYWNoIGVsZW1lbnQgaW4gYGNvbGxlY3Rpb25gLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDQuMC4wXG4gICAgICogQGNhdGVnb3J5IENvbGxlY3Rpb25cbiAgICAgKiBAcGFyYW0ge0FycmF5fE9iamVjdH0gY29sbGVjdGlvbiBUaGUgY29sbGVjdGlvbiB0byBpdGVyYXRlIG92ZXIuXG4gICAgICogQHBhcmFtIHtBcnJheXxGdW5jdGlvbnxzdHJpbmd9IHBhdGggVGhlIHBhdGggb2YgdGhlIG1ldGhvZCB0byBpbnZva2Ugb3JcbiAgICAgKiAgdGhlIGZ1bmN0aW9uIGludm9rZWQgcGVyIGl0ZXJhdGlvbi5cbiAgICAgKiBAcGFyYW0gey4uLip9IFthcmdzXSBUaGUgYXJndW1lbnRzIHRvIGludm9rZSBlYWNoIG1ldGhvZCB3aXRoLlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgYXJyYXkgb2YgcmVzdWx0cy5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy5pbnZva2VNYXAoW1s1LCAxLCA3XSwgWzMsIDIsIDFdXSwgJ3NvcnQnKTtcbiAgICAgKiAvLyA9PiBbWzEsIDUsIDddLCBbMSwgMiwgM11dXG4gICAgICpcbiAgICAgKiBfLmludm9rZU1hcChbMTIzLCA0NTZdLCBTdHJpbmcucHJvdG90eXBlLnNwbGl0LCAnJyk7XG4gICAgICogLy8gPT4gW1snMScsICcyJywgJzMnXSwgWyc0JywgJzUnLCAnNiddXVxuICAgICAqL1xuICAgIHZhciBpbnZva2VNYXAgPSBiYXNlUmVzdChmdW5jdGlvbihjb2xsZWN0aW9uLCBwYXRoLCBhcmdzKSB7XG4gICAgICB2YXIgaW5kZXggPSAtMSxcbiAgICAgICAgICBpc0Z1bmMgPSB0eXBlb2YgcGF0aCA9PSAnZnVuY3Rpb24nLFxuICAgICAgICAgIHJlc3VsdCA9IGlzQXJyYXlMaWtlKGNvbGxlY3Rpb24pID8gQXJyYXkoY29sbGVjdGlvbi5sZW5ndGgpIDogW107XG5cbiAgICAgIGJhc2VFYWNoKGNvbGxlY3Rpb24sIGZ1bmN0aW9uKHZhbHVlKSB7XG4gICAgICAgIHJlc3VsdFsrK2luZGV4XSA9IGlzRnVuYyA/IGFwcGx5KHBhdGgsIHZhbHVlLCBhcmdzKSA6IGJhc2VJbnZva2UodmFsdWUsIHBhdGgsIGFyZ3MpO1xuICAgICAgfSk7XG4gICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH0pO1xuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhbiBvYmplY3QgY29tcG9zZWQgb2Yga2V5cyBnZW5lcmF0ZWQgZnJvbSB0aGUgcmVzdWx0cyBvZiBydW5uaW5nXG4gICAgICogZWFjaCBlbGVtZW50IG9mIGBjb2xsZWN0aW9uYCB0aHJ1IGBpdGVyYXRlZWAuIFRoZSBjb3JyZXNwb25kaW5nIHZhbHVlIG9mXG4gICAgICogZWFjaCBrZXkgaXMgdGhlIGxhc3QgZWxlbWVudCByZXNwb25zaWJsZSBmb3IgZ2VuZXJhdGluZyB0aGUga2V5LiBUaGVcbiAgICAgKiBpdGVyYXRlZSBpcyBpbnZva2VkIHdpdGggb25lIGFyZ3VtZW50OiAodmFsdWUpLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDQuMC4wXG4gICAgICogQGNhdGVnb3J5IENvbGxlY3Rpb25cbiAgICAgKiBAcGFyYW0ge0FycmF5fE9iamVjdH0gY29sbGVjdGlvbiBUaGUgY29sbGVjdGlvbiB0byBpdGVyYXRlIG92ZXIuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gW2l0ZXJhdGVlPV8uaWRlbnRpdHldIFRoZSBpdGVyYXRlZSB0byB0cmFuc2Zvcm0ga2V5cy5cbiAgICAgKiBAcmV0dXJucyB7T2JqZWN0fSBSZXR1cm5zIHRoZSBjb21wb3NlZCBhZ2dyZWdhdGUgb2JqZWN0LlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiB2YXIgYXJyYXkgPSBbXG4gICAgICogICB7ICdkaXInOiAnbGVmdCcsICdjb2RlJzogOTcgfSxcbiAgICAgKiAgIHsgJ2Rpcic6ICdyaWdodCcsICdjb2RlJzogMTAwIH1cbiAgICAgKiBdO1xuICAgICAqXG4gICAgICogXy5rZXlCeShhcnJheSwgZnVuY3Rpb24obykge1xuICAgICAqICAgcmV0dXJuIFN0cmluZy5mcm9tQ2hhckNvZGUoby5jb2RlKTtcbiAgICAgKiB9KTtcbiAgICAgKiAvLyA9PiB7ICdhJzogeyAnZGlyJzogJ2xlZnQnLCAnY29kZSc6IDk3IH0sICdkJzogeyAnZGlyJzogJ3JpZ2h0JywgJ2NvZGUnOiAxMDAgfSB9XG4gICAgICpcbiAgICAgKiBfLmtleUJ5KGFycmF5LCAnZGlyJyk7XG4gICAgICogLy8gPT4geyAnbGVmdCc6IHsgJ2Rpcic6ICdsZWZ0JywgJ2NvZGUnOiA5NyB9LCAncmlnaHQnOiB7ICdkaXInOiAncmlnaHQnLCAnY29kZSc6IDEwMCB9IH1cbiAgICAgKi9cbiAgICB2YXIga2V5QnkgPSBjcmVhdGVBZ2dyZWdhdG9yKGZ1bmN0aW9uKHJlc3VsdCwgdmFsdWUsIGtleSkge1xuICAgICAgYmFzZUFzc2lnblZhbHVlKHJlc3VsdCwga2V5LCB2YWx1ZSk7XG4gICAgfSk7XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGFuIGFycmF5IG9mIHZhbHVlcyBieSBydW5uaW5nIGVhY2ggZWxlbWVudCBpbiBgY29sbGVjdGlvbmAgdGhydVxuICAgICAqIGBpdGVyYXRlZWAuIFRoZSBpdGVyYXRlZSBpcyBpbnZva2VkIHdpdGggdGhyZWUgYXJndW1lbnRzOlxuICAgICAqICh2YWx1ZSwgaW5kZXh8a2V5LCBjb2xsZWN0aW9uKS5cbiAgICAgKlxuICAgICAqIE1hbnkgbG9kYXNoIG1ldGhvZHMgYXJlIGd1YXJkZWQgdG8gd29yayBhcyBpdGVyYXRlZXMgZm9yIG1ldGhvZHMgbGlrZVxuICAgICAqIGBfLmV2ZXJ5YCwgYF8uZmlsdGVyYCwgYF8ubWFwYCwgYF8ubWFwVmFsdWVzYCwgYF8ucmVqZWN0YCwgYW5kIGBfLnNvbWVgLlxuICAgICAqXG4gICAgICogVGhlIGd1YXJkZWQgbWV0aG9kcyBhcmU6XG4gICAgICogYGFyeWAsIGBjaHVua2AsIGBjdXJyeWAsIGBjdXJyeVJpZ2h0YCwgYGRyb3BgLCBgZHJvcFJpZ2h0YCwgYGV2ZXJ5YCxcbiAgICAgKiBgZmlsbGAsIGBpbnZlcnRgLCBgcGFyc2VJbnRgLCBgcmFuZG9tYCwgYHJhbmdlYCwgYHJhbmdlUmlnaHRgLCBgcmVwZWF0YCxcbiAgICAgKiBgc2FtcGxlU2l6ZWAsIGBzbGljZWAsIGBzb21lYCwgYHNvcnRCeWAsIGBzcGxpdGAsIGB0YWtlYCwgYHRha2VSaWdodGAsXG4gICAgICogYHRlbXBsYXRlYCwgYHRyaW1gLCBgdHJpbUVuZGAsIGB0cmltU3RhcnRgLCBhbmQgYHdvcmRzYFxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDAuMS4wXG4gICAgICogQGNhdGVnb3J5IENvbGxlY3Rpb25cbiAgICAgKiBAcGFyYW0ge0FycmF5fE9iamVjdH0gY29sbGVjdGlvbiBUaGUgY29sbGVjdGlvbiB0byBpdGVyYXRlIG92ZXIuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gW2l0ZXJhdGVlPV8uaWRlbnRpdHldIFRoZSBmdW5jdGlvbiBpbnZva2VkIHBlciBpdGVyYXRpb24uXG4gICAgICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBuZXcgbWFwcGVkIGFycmF5LlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBmdW5jdGlvbiBzcXVhcmUobikge1xuICAgICAqICAgcmV0dXJuIG4gKiBuO1xuICAgICAqIH1cbiAgICAgKlxuICAgICAqIF8ubWFwKFs0LCA4XSwgc3F1YXJlKTtcbiAgICAgKiAvLyA9PiBbMTYsIDY0XVxuICAgICAqXG4gICAgICogXy5tYXAoeyAnYSc6IDQsICdiJzogOCB9LCBzcXVhcmUpO1xuICAgICAqIC8vID0+IFsxNiwgNjRdIChpdGVyYXRpb24gb3JkZXIgaXMgbm90IGd1YXJhbnRlZWQpXG4gICAgICpcbiAgICAgKiB2YXIgdXNlcnMgPSBbXG4gICAgICogICB7ICd1c2VyJzogJ2Jhcm5leScgfSxcbiAgICAgKiAgIHsgJ3VzZXInOiAnZnJlZCcgfVxuICAgICAqIF07XG4gICAgICpcbiAgICAgKiAvLyBUaGUgYF8ucHJvcGVydHlgIGl0ZXJhdGVlIHNob3J0aGFuZC5cbiAgICAgKiBfLm1hcCh1c2VycywgJ3VzZXInKTtcbiAgICAgKiAvLyA9PiBbJ2Jhcm5leScsICdmcmVkJ11cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBtYXAoY29sbGVjdGlvbiwgaXRlcmF0ZWUpIHtcbiAgICAgIHZhciBmdW5jID0gaXNBcnJheShjb2xsZWN0aW9uKSA/IGFycmF5TWFwIDogYmFzZU1hcDtcbiAgICAgIHJldHVybiBmdW5jKGNvbGxlY3Rpb24sIGdldEl0ZXJhdGVlKGl0ZXJhdGVlLCAzKSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhpcyBtZXRob2QgaXMgbGlrZSBgXy5zb3J0QnlgIGV4Y2VwdCB0aGF0IGl0IGFsbG93cyBzcGVjaWZ5aW5nIHRoZSBzb3J0XG4gICAgICogb3JkZXJzIG9mIHRoZSBpdGVyYXRlZXMgdG8gc29ydCBieS4gSWYgYG9yZGVyc2AgaXMgdW5zcGVjaWZpZWQsIGFsbCB2YWx1ZXNcbiAgICAgKiBhcmUgc29ydGVkIGluIGFzY2VuZGluZyBvcmRlci4gT3RoZXJ3aXNlLCBzcGVjaWZ5IGFuIG9yZGVyIG9mIFwiZGVzY1wiIGZvclxuICAgICAqIGRlc2NlbmRpbmcgb3IgXCJhc2NcIiBmb3IgYXNjZW5kaW5nIHNvcnQgb3JkZXIgb2YgY29ycmVzcG9uZGluZyB2YWx1ZXMuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgNC4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgQ29sbGVjdGlvblxuICAgICAqIEBwYXJhbSB7QXJyYXl8T2JqZWN0fSBjb2xsZWN0aW9uIFRoZSBjb2xsZWN0aW9uIHRvIGl0ZXJhdGUgb3Zlci5cbiAgICAgKiBAcGFyYW0ge0FycmF5W118RnVuY3Rpb25bXXxPYmplY3RbXXxzdHJpbmdbXX0gW2l0ZXJhdGVlcz1bXy5pZGVudGl0eV1dXG4gICAgICogIFRoZSBpdGVyYXRlZXMgdG8gc29ydCBieS5cbiAgICAgKiBAcGFyYW0ge3N0cmluZ1tdfSBbb3JkZXJzXSBUaGUgc29ydCBvcmRlcnMgb2YgYGl0ZXJhdGVlc2AuXG4gICAgICogQHBhcmFtLSB7T2JqZWN0fSBbZ3VhcmRdIEVuYWJsZXMgdXNlIGFzIGFuIGl0ZXJhdGVlIGZvciBtZXRob2RzIGxpa2UgYF8ucmVkdWNlYC5cbiAgICAgKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIG5ldyBzb3J0ZWQgYXJyYXkuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIHZhciB1c2VycyA9IFtcbiAgICAgKiAgIHsgJ3VzZXInOiAnZnJlZCcsICAgJ2FnZSc6IDQ4IH0sXG4gICAgICogICB7ICd1c2VyJzogJ2Jhcm5leScsICdhZ2UnOiAzNCB9LFxuICAgICAqICAgeyAndXNlcic6ICdmcmVkJywgICAnYWdlJzogNDAgfSxcbiAgICAgKiAgIHsgJ3VzZXInOiAnYmFybmV5JywgJ2FnZSc6IDM2IH1cbiAgICAgKiBdO1xuICAgICAqXG4gICAgICogLy8gU29ydCBieSBgdXNlcmAgaW4gYXNjZW5kaW5nIG9yZGVyIGFuZCBieSBgYWdlYCBpbiBkZXNjZW5kaW5nIG9yZGVyLlxuICAgICAqIF8ub3JkZXJCeSh1c2VycywgWyd1c2VyJywgJ2FnZSddLCBbJ2FzYycsICdkZXNjJ10pO1xuICAgICAqIC8vID0+IG9iamVjdHMgZm9yIFtbJ2Jhcm5leScsIDM2XSwgWydiYXJuZXknLCAzNF0sIFsnZnJlZCcsIDQ4XSwgWydmcmVkJywgNDBdXVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIG9yZGVyQnkoY29sbGVjdGlvbiwgaXRlcmF0ZWVzLCBvcmRlcnMsIGd1YXJkKSB7XG4gICAgICBpZiAoY29sbGVjdGlvbiA9PSBudWxsKSB7XG4gICAgICAgIHJldHVybiBbXTtcbiAgICAgIH1cbiAgICAgIGlmICghaXNBcnJheShpdGVyYXRlZXMpKSB7XG4gICAgICAgIGl0ZXJhdGVlcyA9IGl0ZXJhdGVlcyA9PSBudWxsID8gW10gOiBbaXRlcmF0ZWVzXTtcbiAgICAgIH1cbiAgICAgIG9yZGVycyA9IGd1YXJkID8gdW5kZWZpbmVkIDogb3JkZXJzO1xuICAgICAgaWYgKCFpc0FycmF5KG9yZGVycykpIHtcbiAgICAgICAgb3JkZXJzID0gb3JkZXJzID09IG51bGwgPyBbXSA6IFtvcmRlcnNdO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGJhc2VPcmRlckJ5KGNvbGxlY3Rpb24sIGl0ZXJhdGVlcywgb3JkZXJzKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGFuIGFycmF5IG9mIGVsZW1lbnRzIHNwbGl0IGludG8gdHdvIGdyb3VwcywgdGhlIGZpcnN0IG9mIHdoaWNoXG4gICAgICogY29udGFpbnMgZWxlbWVudHMgYHByZWRpY2F0ZWAgcmV0dXJucyB0cnV0aHkgZm9yLCB0aGUgc2Vjb25kIG9mIHdoaWNoXG4gICAgICogY29udGFpbnMgZWxlbWVudHMgYHByZWRpY2F0ZWAgcmV0dXJucyBmYWxzZXkgZm9yLiBUaGUgcHJlZGljYXRlIGlzXG4gICAgICogaW52b2tlZCB3aXRoIG9uZSBhcmd1bWVudDogKHZhbHVlKS5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAzLjAuMFxuICAgICAqIEBjYXRlZ29yeSBDb2xsZWN0aW9uXG4gICAgICogQHBhcmFtIHtBcnJheXxPYmplY3R9IGNvbGxlY3Rpb24gVGhlIGNvbGxlY3Rpb24gdG8gaXRlcmF0ZSBvdmVyLlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IFtwcmVkaWNhdGU9Xy5pZGVudGl0eV0gVGhlIGZ1bmN0aW9uIGludm9rZWQgcGVyIGl0ZXJhdGlvbi5cbiAgICAgKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIGFycmF5IG9mIGdyb3VwZWQgZWxlbWVudHMuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIHZhciB1c2VycyA9IFtcbiAgICAgKiAgIHsgJ3VzZXInOiAnYmFybmV5JywgICdhZ2UnOiAzNiwgJ2FjdGl2ZSc6IGZhbHNlIH0sXG4gICAgICogICB7ICd1c2VyJzogJ2ZyZWQnLCAgICAnYWdlJzogNDAsICdhY3RpdmUnOiB0cnVlIH0sXG4gICAgICogICB7ICd1c2VyJzogJ3BlYmJsZXMnLCAnYWdlJzogMSwgICdhY3RpdmUnOiBmYWxzZSB9XG4gICAgICogXTtcbiAgICAgKlxuICAgICAqIF8ucGFydGl0aW9uKHVzZXJzLCBmdW5jdGlvbihvKSB7IHJldHVybiBvLmFjdGl2ZTsgfSk7XG4gICAgICogLy8gPT4gb2JqZWN0cyBmb3IgW1snZnJlZCddLCBbJ2Jhcm5leScsICdwZWJibGVzJ11dXG4gICAgICpcbiAgICAgKiAvLyBUaGUgYF8ubWF0Y2hlc2AgaXRlcmF0ZWUgc2hvcnRoYW5kLlxuICAgICAqIF8ucGFydGl0aW9uKHVzZXJzLCB7ICdhZ2UnOiAxLCAnYWN0aXZlJzogZmFsc2UgfSk7XG4gICAgICogLy8gPT4gb2JqZWN0cyBmb3IgW1sncGViYmxlcyddLCBbJ2Jhcm5leScsICdmcmVkJ11dXG4gICAgICpcbiAgICAgKiAvLyBUaGUgYF8ubWF0Y2hlc1Byb3BlcnR5YCBpdGVyYXRlZSBzaG9ydGhhbmQuXG4gICAgICogXy5wYXJ0aXRpb24odXNlcnMsIFsnYWN0aXZlJywgZmFsc2VdKTtcbiAgICAgKiAvLyA9PiBvYmplY3RzIGZvciBbWydiYXJuZXknLCAncGViYmxlcyddLCBbJ2ZyZWQnXV1cbiAgICAgKlxuICAgICAqIC8vIFRoZSBgXy5wcm9wZXJ0eWAgaXRlcmF0ZWUgc2hvcnRoYW5kLlxuICAgICAqIF8ucGFydGl0aW9uKHVzZXJzLCAnYWN0aXZlJyk7XG4gICAgICogLy8gPT4gb2JqZWN0cyBmb3IgW1snZnJlZCddLCBbJ2Jhcm5leScsICdwZWJibGVzJ11dXG4gICAgICovXG4gICAgdmFyIHBhcnRpdGlvbiA9IGNyZWF0ZUFnZ3JlZ2F0b3IoZnVuY3Rpb24ocmVzdWx0LCB2YWx1ZSwga2V5KSB7XG4gICAgICByZXN1bHRba2V5ID8gMCA6IDFdLnB1c2godmFsdWUpO1xuICAgIH0sIGZ1bmN0aW9uKCkgeyByZXR1cm4gW1tdLCBbXV07IH0pO1xuXG4gICAgLyoqXG4gICAgICogUmVkdWNlcyBgY29sbGVjdGlvbmAgdG8gYSB2YWx1ZSB3aGljaCBpcyB0aGUgYWNjdW11bGF0ZWQgcmVzdWx0IG9mIHJ1bm5pbmdcbiAgICAgKiBlYWNoIGVsZW1lbnQgaW4gYGNvbGxlY3Rpb25gIHRocnUgYGl0ZXJhdGVlYCwgd2hlcmUgZWFjaCBzdWNjZXNzaXZlXG4gICAgICogaW52b2NhdGlvbiBpcyBzdXBwbGllZCB0aGUgcmV0dXJuIHZhbHVlIG9mIHRoZSBwcmV2aW91cy4gSWYgYGFjY3VtdWxhdG9yYFxuICAgICAqIGlzIG5vdCBnaXZlbiwgdGhlIGZpcnN0IGVsZW1lbnQgb2YgYGNvbGxlY3Rpb25gIGlzIHVzZWQgYXMgdGhlIGluaXRpYWxcbiAgICAgKiB2YWx1ZS4gVGhlIGl0ZXJhdGVlIGlzIGludm9rZWQgd2l0aCBmb3VyIGFyZ3VtZW50czpcbiAgICAgKiAoYWNjdW11bGF0b3IsIHZhbHVlLCBpbmRleHxrZXksIGNvbGxlY3Rpb24pLlxuICAgICAqXG4gICAgICogTWFueSBsb2Rhc2ggbWV0aG9kcyBhcmUgZ3VhcmRlZCB0byB3b3JrIGFzIGl0ZXJhdGVlcyBmb3IgbWV0aG9kcyBsaWtlXG4gICAgICogYF8ucmVkdWNlYCwgYF8ucmVkdWNlUmlnaHRgLCBhbmQgYF8udHJhbnNmb3JtYC5cbiAgICAgKlxuICAgICAqIFRoZSBndWFyZGVkIG1ldGhvZHMgYXJlOlxuICAgICAqIGBhc3NpZ25gLCBgZGVmYXVsdHNgLCBgZGVmYXVsdHNEZWVwYCwgYGluY2x1ZGVzYCwgYG1lcmdlYCwgYG9yZGVyQnlgLFxuICAgICAqIGFuZCBgc29ydEJ5YFxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDAuMS4wXG4gICAgICogQGNhdGVnb3J5IENvbGxlY3Rpb25cbiAgICAgKiBAcGFyYW0ge0FycmF5fE9iamVjdH0gY29sbGVjdGlvbiBUaGUgY29sbGVjdGlvbiB0byBpdGVyYXRlIG92ZXIuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gW2l0ZXJhdGVlPV8uaWRlbnRpdHldIFRoZSBmdW5jdGlvbiBpbnZva2VkIHBlciBpdGVyYXRpb24uXG4gICAgICogQHBhcmFtIHsqfSBbYWNjdW11bGF0b3JdIFRoZSBpbml0aWFsIHZhbHVlLlxuICAgICAqIEByZXR1cm5zIHsqfSBSZXR1cm5zIHRoZSBhY2N1bXVsYXRlZCB2YWx1ZS5cbiAgICAgKiBAc2VlIF8ucmVkdWNlUmlnaHRcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy5yZWR1Y2UoWzEsIDJdLCBmdW5jdGlvbihzdW0sIG4pIHtcbiAgICAgKiAgIHJldHVybiBzdW0gKyBuO1xuICAgICAqIH0sIDApO1xuICAgICAqIC8vID0+IDNcbiAgICAgKlxuICAgICAqIF8ucmVkdWNlKHsgJ2EnOiAxLCAnYic6IDIsICdjJzogMSB9LCBmdW5jdGlvbihyZXN1bHQsIHZhbHVlLCBrZXkpIHtcbiAgICAgKiAgIChyZXN1bHRbdmFsdWVdIHx8IChyZXN1bHRbdmFsdWVdID0gW10pKS5wdXNoKGtleSk7XG4gICAgICogICByZXR1cm4gcmVzdWx0O1xuICAgICAqIH0sIHt9KTtcbiAgICAgKiAvLyA9PiB7ICcxJzogWydhJywgJ2MnXSwgJzInOiBbJ2InXSB9IChpdGVyYXRpb24gb3JkZXIgaXMgbm90IGd1YXJhbnRlZWQpXG4gICAgICovXG4gICAgZnVuY3Rpb24gcmVkdWNlKGNvbGxlY3Rpb24sIGl0ZXJhdGVlLCBhY2N1bXVsYXRvcikge1xuICAgICAgdmFyIGZ1bmMgPSBpc0FycmF5KGNvbGxlY3Rpb24pID8gYXJyYXlSZWR1Y2UgOiBiYXNlUmVkdWNlLFxuICAgICAgICAgIGluaXRBY2N1bSA9IGFyZ3VtZW50cy5sZW5ndGggPCAzO1xuXG4gICAgICByZXR1cm4gZnVuYyhjb2xsZWN0aW9uLCBnZXRJdGVyYXRlZShpdGVyYXRlZSwgNCksIGFjY3VtdWxhdG9yLCBpbml0QWNjdW0sIGJhc2VFYWNoKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGlzIG1ldGhvZCBpcyBsaWtlIGBfLnJlZHVjZWAgZXhjZXB0IHRoYXQgaXQgaXRlcmF0ZXMgb3ZlciBlbGVtZW50cyBvZlxuICAgICAqIGBjb2xsZWN0aW9uYCBmcm9tIHJpZ2h0IHRvIGxlZnQuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMC4xLjBcbiAgICAgKiBAY2F0ZWdvcnkgQ29sbGVjdGlvblxuICAgICAqIEBwYXJhbSB7QXJyYXl8T2JqZWN0fSBjb2xsZWN0aW9uIFRoZSBjb2xsZWN0aW9uIHRvIGl0ZXJhdGUgb3Zlci5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBbaXRlcmF0ZWU9Xy5pZGVudGl0eV0gVGhlIGZ1bmN0aW9uIGludm9rZWQgcGVyIGl0ZXJhdGlvbi5cbiAgICAgKiBAcGFyYW0geyp9IFthY2N1bXVsYXRvcl0gVGhlIGluaXRpYWwgdmFsdWUuXG4gICAgICogQHJldHVybnMgeyp9IFJldHVybnMgdGhlIGFjY3VtdWxhdGVkIHZhbHVlLlxuICAgICAqIEBzZWUgXy5yZWR1Y2VcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogdmFyIGFycmF5ID0gW1swLCAxXSwgWzIsIDNdLCBbNCwgNV1dO1xuICAgICAqXG4gICAgICogXy5yZWR1Y2VSaWdodChhcnJheSwgZnVuY3Rpb24oZmxhdHRlbmVkLCBvdGhlcikge1xuICAgICAqICAgcmV0dXJuIGZsYXR0ZW5lZC5jb25jYXQob3RoZXIpO1xuICAgICAqIH0sIFtdKTtcbiAgICAgKiAvLyA9PiBbNCwgNSwgMiwgMywgMCwgMV1cbiAgICAgKi9cbiAgICBmdW5jdGlvbiByZWR1Y2VSaWdodChjb2xsZWN0aW9uLCBpdGVyYXRlZSwgYWNjdW11bGF0b3IpIHtcbiAgICAgIHZhciBmdW5jID0gaXNBcnJheShjb2xsZWN0aW9uKSA/IGFycmF5UmVkdWNlUmlnaHQgOiBiYXNlUmVkdWNlLFxuICAgICAgICAgIGluaXRBY2N1bSA9IGFyZ3VtZW50cy5sZW5ndGggPCAzO1xuXG4gICAgICByZXR1cm4gZnVuYyhjb2xsZWN0aW9uLCBnZXRJdGVyYXRlZShpdGVyYXRlZSwgNCksIGFjY3VtdWxhdG9yLCBpbml0QWNjdW0sIGJhc2VFYWNoUmlnaHQpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoZSBvcHBvc2l0ZSBvZiBgXy5maWx0ZXJgOyB0aGlzIG1ldGhvZCByZXR1cm5zIHRoZSBlbGVtZW50cyBvZiBgY29sbGVjdGlvbmBcbiAgICAgKiB0aGF0IGBwcmVkaWNhdGVgIGRvZXMgKipub3QqKiByZXR1cm4gdHJ1dGh5IGZvci5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAwLjEuMFxuICAgICAqIEBjYXRlZ29yeSBDb2xsZWN0aW9uXG4gICAgICogQHBhcmFtIHtBcnJheXxPYmplY3R9IGNvbGxlY3Rpb24gVGhlIGNvbGxlY3Rpb24gdG8gaXRlcmF0ZSBvdmVyLlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IFtwcmVkaWNhdGU9Xy5pZGVudGl0eV0gVGhlIGZ1bmN0aW9uIGludm9rZWQgcGVyIGl0ZXJhdGlvbi5cbiAgICAgKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIG5ldyBmaWx0ZXJlZCBhcnJheS5cbiAgICAgKiBAc2VlIF8uZmlsdGVyXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIHZhciB1c2VycyA9IFtcbiAgICAgKiAgIHsgJ3VzZXInOiAnYmFybmV5JywgJ2FnZSc6IDM2LCAnYWN0aXZlJzogZmFsc2UgfSxcbiAgICAgKiAgIHsgJ3VzZXInOiAnZnJlZCcsICAgJ2FnZSc6IDQwLCAnYWN0aXZlJzogdHJ1ZSB9XG4gICAgICogXTtcbiAgICAgKlxuICAgICAqIF8ucmVqZWN0KHVzZXJzLCBmdW5jdGlvbihvKSB7IHJldHVybiAhby5hY3RpdmU7IH0pO1xuICAgICAqIC8vID0+IG9iamVjdHMgZm9yIFsnZnJlZCddXG4gICAgICpcbiAgICAgKiAvLyBUaGUgYF8ubWF0Y2hlc2AgaXRlcmF0ZWUgc2hvcnRoYW5kLlxuICAgICAqIF8ucmVqZWN0KHVzZXJzLCB7ICdhZ2UnOiA0MCwgJ2FjdGl2ZSc6IHRydWUgfSk7XG4gICAgICogLy8gPT4gb2JqZWN0cyBmb3IgWydiYXJuZXknXVxuICAgICAqXG4gICAgICogLy8gVGhlIGBfLm1hdGNoZXNQcm9wZXJ0eWAgaXRlcmF0ZWUgc2hvcnRoYW5kLlxuICAgICAqIF8ucmVqZWN0KHVzZXJzLCBbJ2FjdGl2ZScsIGZhbHNlXSk7XG4gICAgICogLy8gPT4gb2JqZWN0cyBmb3IgWydmcmVkJ11cbiAgICAgKlxuICAgICAqIC8vIFRoZSBgXy5wcm9wZXJ0eWAgaXRlcmF0ZWUgc2hvcnRoYW5kLlxuICAgICAqIF8ucmVqZWN0KHVzZXJzLCAnYWN0aXZlJyk7XG4gICAgICogLy8gPT4gb2JqZWN0cyBmb3IgWydiYXJuZXknXVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIHJlamVjdChjb2xsZWN0aW9uLCBwcmVkaWNhdGUpIHtcbiAgICAgIHZhciBmdW5jID0gaXNBcnJheShjb2xsZWN0aW9uKSA/IGFycmF5RmlsdGVyIDogYmFzZUZpbHRlcjtcbiAgICAgIHJldHVybiBmdW5jKGNvbGxlY3Rpb24sIG5lZ2F0ZShnZXRJdGVyYXRlZShwcmVkaWNhdGUsIDMpKSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogR2V0cyBhIHJhbmRvbSBlbGVtZW50IGZyb20gYGNvbGxlY3Rpb25gLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDIuMC4wXG4gICAgICogQGNhdGVnb3J5IENvbGxlY3Rpb25cbiAgICAgKiBAcGFyYW0ge0FycmF5fE9iamVjdH0gY29sbGVjdGlvbiBUaGUgY29sbGVjdGlvbiB0byBzYW1wbGUuXG4gICAgICogQHJldHVybnMgeyp9IFJldHVybnMgdGhlIHJhbmRvbSBlbGVtZW50LlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLnNhbXBsZShbMSwgMiwgMywgNF0pO1xuICAgICAqIC8vID0+IDJcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBzYW1wbGUoY29sbGVjdGlvbikge1xuICAgICAgdmFyIGZ1bmMgPSBpc0FycmF5KGNvbGxlY3Rpb24pID8gYXJyYXlTYW1wbGUgOiBiYXNlU2FtcGxlO1xuICAgICAgcmV0dXJuIGZ1bmMoY29sbGVjdGlvbik7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogR2V0cyBgbmAgcmFuZG9tIGVsZW1lbnRzIGF0IHVuaXF1ZSBrZXlzIGZyb20gYGNvbGxlY3Rpb25gIHVwIHRvIHRoZVxuICAgICAqIHNpemUgb2YgYGNvbGxlY3Rpb25gLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDQuMC4wXG4gICAgICogQGNhdGVnb3J5IENvbGxlY3Rpb25cbiAgICAgKiBAcGFyYW0ge0FycmF5fE9iamVjdH0gY29sbGVjdGlvbiBUaGUgY29sbGVjdGlvbiB0byBzYW1wbGUuXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IFtuPTFdIFRoZSBudW1iZXIgb2YgZWxlbWVudHMgdG8gc2FtcGxlLlxuICAgICAqIEBwYXJhbS0ge09iamVjdH0gW2d1YXJkXSBFbmFibGVzIHVzZSBhcyBhbiBpdGVyYXRlZSBmb3IgbWV0aG9kcyBsaWtlIGBfLm1hcGAuXG4gICAgICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSByYW5kb20gZWxlbWVudHMuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8uc2FtcGxlU2l6ZShbMSwgMiwgM10sIDIpO1xuICAgICAqIC8vID0+IFszLCAxXVxuICAgICAqXG4gICAgICogXy5zYW1wbGVTaXplKFsxLCAyLCAzXSwgNCk7XG4gICAgICogLy8gPT4gWzIsIDMsIDFdXG4gICAgICovXG4gICAgZnVuY3Rpb24gc2FtcGxlU2l6ZShjb2xsZWN0aW9uLCBuLCBndWFyZCkge1xuICAgICAgaWYgKChndWFyZCA/IGlzSXRlcmF0ZWVDYWxsKGNvbGxlY3Rpb24sIG4sIGd1YXJkKSA6IG4gPT09IHVuZGVmaW5lZCkpIHtcbiAgICAgICAgbiA9IDE7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBuID0gdG9JbnRlZ2VyKG4pO1xuICAgICAgfVxuICAgICAgdmFyIGZ1bmMgPSBpc0FycmF5KGNvbGxlY3Rpb24pID8gYXJyYXlTYW1wbGVTaXplIDogYmFzZVNhbXBsZVNpemU7XG4gICAgICByZXR1cm4gZnVuYyhjb2xsZWN0aW9uLCBuKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGFuIGFycmF5IG9mIHNodWZmbGVkIHZhbHVlcywgdXNpbmcgYSB2ZXJzaW9uIG9mIHRoZVxuICAgICAqIFtGaXNoZXItWWF0ZXMgc2h1ZmZsZV0oaHR0cHM6Ly9lbi53aWtpcGVkaWEub3JnL3dpa2kvRmlzaGVyLVlhdGVzX3NodWZmbGUpLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDAuMS4wXG4gICAgICogQGNhdGVnb3J5IENvbGxlY3Rpb25cbiAgICAgKiBAcGFyYW0ge0FycmF5fE9iamVjdH0gY29sbGVjdGlvbiBUaGUgY29sbGVjdGlvbiB0byBzaHVmZmxlLlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgbmV3IHNodWZmbGVkIGFycmF5LlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLnNodWZmbGUoWzEsIDIsIDMsIDRdKTtcbiAgICAgKiAvLyA9PiBbNCwgMSwgMywgMl1cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBzaHVmZmxlKGNvbGxlY3Rpb24pIHtcbiAgICAgIHZhciBmdW5jID0gaXNBcnJheShjb2xsZWN0aW9uKSA/IGFycmF5U2h1ZmZsZSA6IGJhc2VTaHVmZmxlO1xuICAgICAgcmV0dXJuIGZ1bmMoY29sbGVjdGlvbik7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogR2V0cyB0aGUgc2l6ZSBvZiBgY29sbGVjdGlvbmAgYnkgcmV0dXJuaW5nIGl0cyBsZW5ndGggZm9yIGFycmF5LWxpa2VcbiAgICAgKiB2YWx1ZXMgb3IgdGhlIG51bWJlciBvZiBvd24gZW51bWVyYWJsZSBzdHJpbmcga2V5ZWQgcHJvcGVydGllcyBmb3Igb2JqZWN0cy5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAwLjEuMFxuICAgICAqIEBjYXRlZ29yeSBDb2xsZWN0aW9uXG4gICAgICogQHBhcmFtIHtBcnJheXxPYmplY3R8c3RyaW5nfSBjb2xsZWN0aW9uIFRoZSBjb2xsZWN0aW9uIHRvIGluc3BlY3QuXG4gICAgICogQHJldHVybnMge251bWJlcn0gUmV0dXJucyB0aGUgY29sbGVjdGlvbiBzaXplLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLnNpemUoWzEsIDIsIDNdKTtcbiAgICAgKiAvLyA9PiAzXG4gICAgICpcbiAgICAgKiBfLnNpemUoeyAnYSc6IDEsICdiJzogMiB9KTtcbiAgICAgKiAvLyA9PiAyXG4gICAgICpcbiAgICAgKiBfLnNpemUoJ3BlYmJsZXMnKTtcbiAgICAgKiAvLyA9PiA3XG4gICAgICovXG4gICAgZnVuY3Rpb24gc2l6ZShjb2xsZWN0aW9uKSB7XG4gICAgICBpZiAoY29sbGVjdGlvbiA9PSBudWxsKSB7XG4gICAgICAgIHJldHVybiAwO1xuICAgICAgfVxuICAgICAgaWYgKGlzQXJyYXlMaWtlKGNvbGxlY3Rpb24pKSB7XG4gICAgICAgIHJldHVybiBpc1N0cmluZyhjb2xsZWN0aW9uKSA/IHN0cmluZ1NpemUoY29sbGVjdGlvbikgOiBjb2xsZWN0aW9uLmxlbmd0aDtcbiAgICAgIH1cbiAgICAgIHZhciB0YWcgPSBnZXRUYWcoY29sbGVjdGlvbik7XG4gICAgICBpZiAodGFnID09IG1hcFRhZyB8fCB0YWcgPT0gc2V0VGFnKSB7XG4gICAgICAgIHJldHVybiBjb2xsZWN0aW9uLnNpemU7XG4gICAgICB9XG4gICAgICByZXR1cm4gYmFzZUtleXMoY29sbGVjdGlvbikubGVuZ3RoO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENoZWNrcyBpZiBgcHJlZGljYXRlYCByZXR1cm5zIHRydXRoeSBmb3IgKiphbnkqKiBlbGVtZW50IG9mIGBjb2xsZWN0aW9uYC5cbiAgICAgKiBJdGVyYXRpb24gaXMgc3RvcHBlZCBvbmNlIGBwcmVkaWNhdGVgIHJldHVybnMgdHJ1dGh5LiBUaGUgcHJlZGljYXRlIGlzXG4gICAgICogaW52b2tlZCB3aXRoIHRocmVlIGFyZ3VtZW50czogKHZhbHVlLCBpbmRleHxrZXksIGNvbGxlY3Rpb24pLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDAuMS4wXG4gICAgICogQGNhdGVnb3J5IENvbGxlY3Rpb25cbiAgICAgKiBAcGFyYW0ge0FycmF5fE9iamVjdH0gY29sbGVjdGlvbiBUaGUgY29sbGVjdGlvbiB0byBpdGVyYXRlIG92ZXIuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gW3ByZWRpY2F0ZT1fLmlkZW50aXR5XSBUaGUgZnVuY3Rpb24gaW52b2tlZCBwZXIgaXRlcmF0aW9uLlxuICAgICAqIEBwYXJhbS0ge09iamVjdH0gW2d1YXJkXSBFbmFibGVzIHVzZSBhcyBhbiBpdGVyYXRlZSBmb3IgbWV0aG9kcyBsaWtlIGBfLm1hcGAuXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGFueSBlbGVtZW50IHBhc3NlcyB0aGUgcHJlZGljYXRlIGNoZWNrLFxuICAgICAqICBlbHNlIGBmYWxzZWAuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8uc29tZShbbnVsbCwgMCwgJ3llcycsIGZhbHNlXSwgQm9vbGVhbik7XG4gICAgICogLy8gPT4gdHJ1ZVxuICAgICAqXG4gICAgICogdmFyIHVzZXJzID0gW1xuICAgICAqICAgeyAndXNlcic6ICdiYXJuZXknLCAnYWN0aXZlJzogdHJ1ZSB9LFxuICAgICAqICAgeyAndXNlcic6ICdmcmVkJywgICAnYWN0aXZlJzogZmFsc2UgfVxuICAgICAqIF07XG4gICAgICpcbiAgICAgKiAvLyBUaGUgYF8ubWF0Y2hlc2AgaXRlcmF0ZWUgc2hvcnRoYW5kLlxuICAgICAqIF8uc29tZSh1c2VycywgeyAndXNlcic6ICdiYXJuZXknLCAnYWN0aXZlJzogZmFsc2UgfSk7XG4gICAgICogLy8gPT4gZmFsc2VcbiAgICAgKlxuICAgICAqIC8vIFRoZSBgXy5tYXRjaGVzUHJvcGVydHlgIGl0ZXJhdGVlIHNob3J0aGFuZC5cbiAgICAgKiBfLnNvbWUodXNlcnMsIFsnYWN0aXZlJywgZmFsc2VdKTtcbiAgICAgKiAvLyA9PiB0cnVlXG4gICAgICpcbiAgICAgKiAvLyBUaGUgYF8ucHJvcGVydHlgIGl0ZXJhdGVlIHNob3J0aGFuZC5cbiAgICAgKiBfLnNvbWUodXNlcnMsICdhY3RpdmUnKTtcbiAgICAgKiAvLyA9PiB0cnVlXG4gICAgICovXG4gICAgZnVuY3Rpb24gc29tZShjb2xsZWN0aW9uLCBwcmVkaWNhdGUsIGd1YXJkKSB7XG4gICAgICB2YXIgZnVuYyA9IGlzQXJyYXkoY29sbGVjdGlvbikgPyBhcnJheVNvbWUgOiBiYXNlU29tZTtcbiAgICAgIGlmIChndWFyZCAmJiBpc0l0ZXJhdGVlQ2FsbChjb2xsZWN0aW9uLCBwcmVkaWNhdGUsIGd1YXJkKSkge1xuICAgICAgICBwcmVkaWNhdGUgPSB1bmRlZmluZWQ7XG4gICAgICB9XG4gICAgICByZXR1cm4gZnVuYyhjb2xsZWN0aW9uLCBnZXRJdGVyYXRlZShwcmVkaWNhdGUsIDMpKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGFuIGFycmF5IG9mIGVsZW1lbnRzLCBzb3J0ZWQgaW4gYXNjZW5kaW5nIG9yZGVyIGJ5IHRoZSByZXN1bHRzIG9mXG4gICAgICogcnVubmluZyBlYWNoIGVsZW1lbnQgaW4gYSBjb2xsZWN0aW9uIHRocnUgZWFjaCBpdGVyYXRlZS4gVGhpcyBtZXRob2RcbiAgICAgKiBwZXJmb3JtcyBhIHN0YWJsZSBzb3J0LCB0aGF0IGlzLCBpdCBwcmVzZXJ2ZXMgdGhlIG9yaWdpbmFsIHNvcnQgb3JkZXIgb2ZcbiAgICAgKiBlcXVhbCBlbGVtZW50cy4gVGhlIGl0ZXJhdGVlcyBhcmUgaW52b2tlZCB3aXRoIG9uZSBhcmd1bWVudDogKHZhbHVlKS5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAwLjEuMFxuICAgICAqIEBjYXRlZ29yeSBDb2xsZWN0aW9uXG4gICAgICogQHBhcmFtIHtBcnJheXxPYmplY3R9IGNvbGxlY3Rpb24gVGhlIGNvbGxlY3Rpb24gdG8gaXRlcmF0ZSBvdmVyLlxuICAgICAqIEBwYXJhbSB7Li4uKEZ1bmN0aW9ufEZ1bmN0aW9uW10pfSBbaXRlcmF0ZWVzPVtfLmlkZW50aXR5XV1cbiAgICAgKiAgVGhlIGl0ZXJhdGVlcyB0byBzb3J0IGJ5LlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgbmV3IHNvcnRlZCBhcnJheS5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogdmFyIHVzZXJzID0gW1xuICAgICAqICAgeyAndXNlcic6ICdmcmVkJywgICAnYWdlJzogNDggfSxcbiAgICAgKiAgIHsgJ3VzZXInOiAnYmFybmV5JywgJ2FnZSc6IDM2IH0sXG4gICAgICogICB7ICd1c2VyJzogJ2ZyZWQnLCAgICdhZ2UnOiA0MCB9LFxuICAgICAqICAgeyAndXNlcic6ICdiYXJuZXknLCAnYWdlJzogMzQgfVxuICAgICAqIF07XG4gICAgICpcbiAgICAgKiBfLnNvcnRCeSh1c2VycywgW2Z1bmN0aW9uKG8pIHsgcmV0dXJuIG8udXNlcjsgfV0pO1xuICAgICAqIC8vID0+IG9iamVjdHMgZm9yIFtbJ2Jhcm5leScsIDM2XSwgWydiYXJuZXknLCAzNF0sIFsnZnJlZCcsIDQ4XSwgWydmcmVkJywgNDBdXVxuICAgICAqXG4gICAgICogXy5zb3J0QnkodXNlcnMsIFsndXNlcicsICdhZ2UnXSk7XG4gICAgICogLy8gPT4gb2JqZWN0cyBmb3IgW1snYmFybmV5JywgMzRdLCBbJ2Jhcm5leScsIDM2XSwgWydmcmVkJywgNDBdLCBbJ2ZyZWQnLCA0OF1dXG4gICAgICovXG4gICAgdmFyIHNvcnRCeSA9IGJhc2VSZXN0KGZ1bmN0aW9uKGNvbGxlY3Rpb24sIGl0ZXJhdGVlcykge1xuICAgICAgaWYgKGNvbGxlY3Rpb24gPT0gbnVsbCkge1xuICAgICAgICByZXR1cm4gW107XG4gICAgICB9XG4gICAgICB2YXIgbGVuZ3RoID0gaXRlcmF0ZWVzLmxlbmd0aDtcbiAgICAgIGlmIChsZW5ndGggPiAxICYmIGlzSXRlcmF0ZWVDYWxsKGNvbGxlY3Rpb24sIGl0ZXJhdGVlc1swXSwgaXRlcmF0ZWVzWzFdKSkge1xuICAgICAgICBpdGVyYXRlZXMgPSBbXTtcbiAgICAgIH0gZWxzZSBpZiAobGVuZ3RoID4gMiAmJiBpc0l0ZXJhdGVlQ2FsbChpdGVyYXRlZXNbMF0sIGl0ZXJhdGVlc1sxXSwgaXRlcmF0ZWVzWzJdKSkge1xuICAgICAgICBpdGVyYXRlZXMgPSBbaXRlcmF0ZWVzWzBdXTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBiYXNlT3JkZXJCeShjb2xsZWN0aW9uLCBiYXNlRmxhdHRlbihpdGVyYXRlZXMsIDEpLCBbXSk7XG4gICAgfSk7XG5cbiAgICAvKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovXG5cbiAgICAvKipcbiAgICAgKiBHZXRzIHRoZSB0aW1lc3RhbXAgb2YgdGhlIG51bWJlciBvZiBtaWxsaXNlY29uZHMgdGhhdCBoYXZlIGVsYXBzZWQgc2luY2VcbiAgICAgKiB0aGUgVW5peCBlcG9jaCAoMSBKYW51YXJ5IDE5NzAgMDA6MDA6MDAgVVRDKS5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAyLjQuMFxuICAgICAqIEBjYXRlZ29yeSBEYXRlXG4gICAgICogQHJldHVybnMge251bWJlcn0gUmV0dXJucyB0aGUgdGltZXN0YW1wLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLmRlZmVyKGZ1bmN0aW9uKHN0YW1wKSB7XG4gICAgICogICBjb25zb2xlLmxvZyhfLm5vdygpIC0gc3RhbXApO1xuICAgICAqIH0sIF8ubm93KCkpO1xuICAgICAqIC8vID0+IExvZ3MgdGhlIG51bWJlciBvZiBtaWxsaXNlY29uZHMgaXQgdG9vayBmb3IgdGhlIGRlZmVycmVkIGludm9jYXRpb24uXG4gICAgICovXG4gICAgdmFyIG5vdyA9IGN0eE5vdyB8fCBmdW5jdGlvbigpIHtcbiAgICAgIHJldHVybiByb290LkRhdGUubm93KCk7XG4gICAgfTtcblxuICAgIC8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi9cblxuICAgIC8qKlxuICAgICAqIFRoZSBvcHBvc2l0ZSBvZiBgXy5iZWZvcmVgOyB0aGlzIG1ldGhvZCBjcmVhdGVzIGEgZnVuY3Rpb24gdGhhdCBpbnZva2VzXG4gICAgICogYGZ1bmNgIG9uY2UgaXQncyBjYWxsZWQgYG5gIG9yIG1vcmUgdGltZXMuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMC4xLjBcbiAgICAgKiBAY2F0ZWdvcnkgRnVuY3Rpb25cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gbiBUaGUgbnVtYmVyIG9mIGNhbGxzIGJlZm9yZSBgZnVuY2AgaXMgaW52b2tlZC5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBmdW5jIFRoZSBmdW5jdGlvbiB0byByZXN0cmljdC5cbiAgICAgKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyByZXN0cmljdGVkIGZ1bmN0aW9uLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiB2YXIgc2F2ZXMgPSBbJ3Byb2ZpbGUnLCAnc2V0dGluZ3MnXTtcbiAgICAgKlxuICAgICAqIHZhciBkb25lID0gXy5hZnRlcihzYXZlcy5sZW5ndGgsIGZ1bmN0aW9uKCkge1xuICAgICAqICAgY29uc29sZS5sb2coJ2RvbmUgc2F2aW5nIScpO1xuICAgICAqIH0pO1xuICAgICAqXG4gICAgICogXy5mb3JFYWNoKHNhdmVzLCBmdW5jdGlvbih0eXBlKSB7XG4gICAgICogICBhc3luY1NhdmUoeyAndHlwZSc6IHR5cGUsICdjb21wbGV0ZSc6IGRvbmUgfSk7XG4gICAgICogfSk7XG4gICAgICogLy8gPT4gTG9ncyAnZG9uZSBzYXZpbmchJyBhZnRlciB0aGUgdHdvIGFzeW5jIHNhdmVzIGhhdmUgY29tcGxldGVkLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGFmdGVyKG4sIGZ1bmMpIHtcbiAgICAgIGlmICh0eXBlb2YgZnVuYyAhPSAnZnVuY3Rpb24nKSB7XG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoRlVOQ19FUlJPUl9URVhUKTtcbiAgICAgIH1cbiAgICAgIG4gPSB0b0ludGVnZXIobik7XG4gICAgICByZXR1cm4gZnVuY3Rpb24oKSB7XG4gICAgICAgIGlmICgtLW4gPCAxKSB7XG4gICAgICAgICAgcmV0dXJuIGZ1bmMuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICAgICAgfVxuICAgICAgfTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgZnVuY3Rpb24gdGhhdCBpbnZva2VzIGBmdW5jYCwgd2l0aCB1cCB0byBgbmAgYXJndW1lbnRzLFxuICAgICAqIGlnbm9yaW5nIGFueSBhZGRpdGlvbmFsIGFyZ3VtZW50cy5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAzLjAuMFxuICAgICAqIEBjYXRlZ29yeSBGdW5jdGlvblxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IGZ1bmMgVGhlIGZ1bmN0aW9uIHRvIGNhcCBhcmd1bWVudHMgZm9yLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbbj1mdW5jLmxlbmd0aF0gVGhlIGFyaXR5IGNhcC5cbiAgICAgKiBAcGFyYW0tIHtPYmplY3R9IFtndWFyZF0gRW5hYmxlcyB1c2UgYXMgYW4gaXRlcmF0ZWUgZm9yIG1ldGhvZHMgbGlrZSBgXy5tYXBgLlxuICAgICAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyB0aGUgbmV3IGNhcHBlZCBmdW5jdGlvbi5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy5tYXAoWyc2JywgJzgnLCAnMTAnXSwgXy5hcnkocGFyc2VJbnQsIDEpKTtcbiAgICAgKiAvLyA9PiBbNiwgOCwgMTBdXG4gICAgICovXG4gICAgZnVuY3Rpb24gYXJ5KGZ1bmMsIG4sIGd1YXJkKSB7XG4gICAgICBuID0gZ3VhcmQgPyB1bmRlZmluZWQgOiBuO1xuICAgICAgbiA9IChmdW5jICYmIG4gPT0gbnVsbCkgPyBmdW5jLmxlbmd0aCA6IG47XG4gICAgICByZXR1cm4gY3JlYXRlV3JhcChmdW5jLCBXUkFQX0FSWV9GTEFHLCB1bmRlZmluZWQsIHVuZGVmaW5lZCwgdW5kZWZpbmVkLCB1bmRlZmluZWQsIG4pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBmdW5jdGlvbiB0aGF0IGludm9rZXMgYGZ1bmNgLCB3aXRoIHRoZSBgdGhpc2AgYmluZGluZyBhbmQgYXJndW1lbnRzXG4gICAgICogb2YgdGhlIGNyZWF0ZWQgZnVuY3Rpb24sIHdoaWxlIGl0J3MgY2FsbGVkIGxlc3MgdGhhbiBgbmAgdGltZXMuIFN1YnNlcXVlbnRcbiAgICAgKiBjYWxscyB0byB0aGUgY3JlYXRlZCBmdW5jdGlvbiByZXR1cm4gdGhlIHJlc3VsdCBvZiB0aGUgbGFzdCBgZnVuY2AgaW52b2NhdGlvbi5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAzLjAuMFxuICAgICAqIEBjYXRlZ29yeSBGdW5jdGlvblxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBuIFRoZSBudW1iZXIgb2YgY2FsbHMgYXQgd2hpY2ggYGZ1bmNgIGlzIG5vIGxvbmdlciBpbnZva2VkLlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IGZ1bmMgVGhlIGZ1bmN0aW9uIHRvIHJlc3RyaWN0LlxuICAgICAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyB0aGUgbmV3IHJlc3RyaWN0ZWQgZnVuY3Rpb24uXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIGpRdWVyeShlbGVtZW50KS5vbignY2xpY2snLCBfLmJlZm9yZSg1LCBhZGRDb250YWN0VG9MaXN0KSk7XG4gICAgICogLy8gPT4gQWxsb3dzIGFkZGluZyB1cCB0byA0IGNvbnRhY3RzIHRvIHRoZSBsaXN0LlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGJlZm9yZShuLCBmdW5jKSB7XG4gICAgICB2YXIgcmVzdWx0O1xuICAgICAgaWYgKHR5cGVvZiBmdW5jICE9ICdmdW5jdGlvbicpIHtcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihGVU5DX0VSUk9SX1RFWFQpO1xuICAgICAgfVxuICAgICAgbiA9IHRvSW50ZWdlcihuKTtcbiAgICAgIHJldHVybiBmdW5jdGlvbigpIHtcbiAgICAgICAgaWYgKC0tbiA+IDApIHtcbiAgICAgICAgICByZXN1bHQgPSBmdW5jLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKG4gPD0gMSkge1xuICAgICAgICAgIGZ1bmMgPSB1bmRlZmluZWQ7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICAgIH07XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIGZ1bmN0aW9uIHRoYXQgaW52b2tlcyBgZnVuY2Agd2l0aCB0aGUgYHRoaXNgIGJpbmRpbmcgb2YgYHRoaXNBcmdgXG4gICAgICogYW5kIGBwYXJ0aWFsc2AgcHJlcGVuZGVkIHRvIHRoZSBhcmd1bWVudHMgaXQgcmVjZWl2ZXMuXG4gICAgICpcbiAgICAgKiBUaGUgYF8uYmluZC5wbGFjZWhvbGRlcmAgdmFsdWUsIHdoaWNoIGRlZmF1bHRzIHRvIGBfYCBpbiBtb25vbGl0aGljIGJ1aWxkcyxcbiAgICAgKiBtYXkgYmUgdXNlZCBhcyBhIHBsYWNlaG9sZGVyIGZvciBwYXJ0aWFsbHkgYXBwbGllZCBhcmd1bWVudHMuXG4gICAgICpcbiAgICAgKiAqKk5vdGU6KiogVW5saWtlIG5hdGl2ZSBgRnVuY3Rpb24jYmluZGAsIHRoaXMgbWV0aG9kIGRvZXNuJ3Qgc2V0IHRoZSBcImxlbmd0aFwiXG4gICAgICogcHJvcGVydHkgb2YgYm91bmQgZnVuY3Rpb25zLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDAuMS4wXG4gICAgICogQGNhdGVnb3J5IEZ1bmN0aW9uXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gZnVuYyBUaGUgZnVuY3Rpb24gdG8gYmluZC5cbiAgICAgKiBAcGFyYW0geyp9IHRoaXNBcmcgVGhlIGB0aGlzYCBiaW5kaW5nIG9mIGBmdW5jYC5cbiAgICAgKiBAcGFyYW0gey4uLip9IFtwYXJ0aWFsc10gVGhlIGFyZ3VtZW50cyB0byBiZSBwYXJ0aWFsbHkgYXBwbGllZC5cbiAgICAgKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyBib3VuZCBmdW5jdGlvbi5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogZnVuY3Rpb24gZ3JlZXQoZ3JlZXRpbmcsIHB1bmN0dWF0aW9uKSB7XG4gICAgICogICByZXR1cm4gZ3JlZXRpbmcgKyAnICcgKyB0aGlzLnVzZXIgKyBwdW5jdHVhdGlvbjtcbiAgICAgKiB9XG4gICAgICpcbiAgICAgKiB2YXIgb2JqZWN0ID0geyAndXNlcic6ICdmcmVkJyB9O1xuICAgICAqXG4gICAgICogdmFyIGJvdW5kID0gXy5iaW5kKGdyZWV0LCBvYmplY3QsICdoaScpO1xuICAgICAqIGJvdW5kKCchJyk7XG4gICAgICogLy8gPT4gJ2hpIGZyZWQhJ1xuICAgICAqXG4gICAgICogLy8gQm91bmQgd2l0aCBwbGFjZWhvbGRlcnMuXG4gICAgICogdmFyIGJvdW5kID0gXy5iaW5kKGdyZWV0LCBvYmplY3QsIF8sICchJyk7XG4gICAgICogYm91bmQoJ2hpJyk7XG4gICAgICogLy8gPT4gJ2hpIGZyZWQhJ1xuICAgICAqL1xuICAgIHZhciBiaW5kID0gYmFzZVJlc3QoZnVuY3Rpb24oZnVuYywgdGhpc0FyZywgcGFydGlhbHMpIHtcbiAgICAgIHZhciBiaXRtYXNrID0gV1JBUF9CSU5EX0ZMQUc7XG4gICAgICBpZiAocGFydGlhbHMubGVuZ3RoKSB7XG4gICAgICAgIHZhciBob2xkZXJzID0gcmVwbGFjZUhvbGRlcnMocGFydGlhbHMsIGdldEhvbGRlcihiaW5kKSk7XG4gICAgICAgIGJpdG1hc2sgfD0gV1JBUF9QQVJUSUFMX0ZMQUc7XG4gICAgICB9XG4gICAgICByZXR1cm4gY3JlYXRlV3JhcChmdW5jLCBiaXRtYXNrLCB0aGlzQXJnLCBwYXJ0aWFscywgaG9sZGVycyk7XG4gICAgfSk7XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgZnVuY3Rpb24gdGhhdCBpbnZva2VzIHRoZSBtZXRob2QgYXQgYG9iamVjdFtrZXldYCB3aXRoIGBwYXJ0aWFsc2BcbiAgICAgKiBwcmVwZW5kZWQgdG8gdGhlIGFyZ3VtZW50cyBpdCByZWNlaXZlcy5cbiAgICAgKlxuICAgICAqIFRoaXMgbWV0aG9kIGRpZmZlcnMgZnJvbSBgXy5iaW5kYCBieSBhbGxvd2luZyBib3VuZCBmdW5jdGlvbnMgdG8gcmVmZXJlbmNlXG4gICAgICogbWV0aG9kcyB0aGF0IG1heSBiZSByZWRlZmluZWQgb3IgZG9uJ3QgeWV0IGV4aXN0LiBTZWVcbiAgICAgKiBbUGV0ZXIgTWljaGF1eCdzIGFydGljbGVdKGh0dHA6Ly9wZXRlci5taWNoYXV4LmNhL2FydGljbGVzL2xhenktZnVuY3Rpb24tZGVmaW5pdGlvbi1wYXR0ZXJuKVxuICAgICAqIGZvciBtb3JlIGRldGFpbHMuXG4gICAgICpcbiAgICAgKiBUaGUgYF8uYmluZEtleS5wbGFjZWhvbGRlcmAgdmFsdWUsIHdoaWNoIGRlZmF1bHRzIHRvIGBfYCBpbiBtb25vbGl0aGljXG4gICAgICogYnVpbGRzLCBtYXkgYmUgdXNlZCBhcyBhIHBsYWNlaG9sZGVyIGZvciBwYXJ0aWFsbHkgYXBwbGllZCBhcmd1bWVudHMuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMC4xMC4wXG4gICAgICogQGNhdGVnb3J5IEZ1bmN0aW9uXG4gICAgICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIGludm9rZSB0aGUgbWV0aG9kIG9uLlxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBrZXkgVGhlIGtleSBvZiB0aGUgbWV0aG9kLlxuICAgICAqIEBwYXJhbSB7Li4uKn0gW3BhcnRpYWxzXSBUaGUgYXJndW1lbnRzIHRvIGJlIHBhcnRpYWxseSBhcHBsaWVkLlxuICAgICAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyB0aGUgbmV3IGJvdW5kIGZ1bmN0aW9uLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiB2YXIgb2JqZWN0ID0ge1xuICAgICAqICAgJ3VzZXInOiAnZnJlZCcsXG4gICAgICogICAnZ3JlZXQnOiBmdW5jdGlvbihncmVldGluZywgcHVuY3R1YXRpb24pIHtcbiAgICAgKiAgICAgcmV0dXJuIGdyZWV0aW5nICsgJyAnICsgdGhpcy51c2VyICsgcHVuY3R1YXRpb247XG4gICAgICogICB9XG4gICAgICogfTtcbiAgICAgKlxuICAgICAqIHZhciBib3VuZCA9IF8uYmluZEtleShvYmplY3QsICdncmVldCcsICdoaScpO1xuICAgICAqIGJvdW5kKCchJyk7XG4gICAgICogLy8gPT4gJ2hpIGZyZWQhJ1xuICAgICAqXG4gICAgICogb2JqZWN0LmdyZWV0ID0gZnVuY3Rpb24oZ3JlZXRpbmcsIHB1bmN0dWF0aW9uKSB7XG4gICAgICogICByZXR1cm4gZ3JlZXRpbmcgKyAneWEgJyArIHRoaXMudXNlciArIHB1bmN0dWF0aW9uO1xuICAgICAqIH07XG4gICAgICpcbiAgICAgKiBib3VuZCgnIScpO1xuICAgICAqIC8vID0+ICdoaXlhIGZyZWQhJ1xuICAgICAqXG4gICAgICogLy8gQm91bmQgd2l0aCBwbGFjZWhvbGRlcnMuXG4gICAgICogdmFyIGJvdW5kID0gXy5iaW5kS2V5KG9iamVjdCwgJ2dyZWV0JywgXywgJyEnKTtcbiAgICAgKiBib3VuZCgnaGknKTtcbiAgICAgKiAvLyA9PiAnaGl5YSBmcmVkISdcbiAgICAgKi9cbiAgICB2YXIgYmluZEtleSA9IGJhc2VSZXN0KGZ1bmN0aW9uKG9iamVjdCwga2V5LCBwYXJ0aWFscykge1xuICAgICAgdmFyIGJpdG1hc2sgPSBXUkFQX0JJTkRfRkxBRyB8IFdSQVBfQklORF9LRVlfRkxBRztcbiAgICAgIGlmIChwYXJ0aWFscy5sZW5ndGgpIHtcbiAgICAgICAgdmFyIGhvbGRlcnMgPSByZXBsYWNlSG9sZGVycyhwYXJ0aWFscywgZ2V0SG9sZGVyKGJpbmRLZXkpKTtcbiAgICAgICAgYml0bWFzayB8PSBXUkFQX1BBUlRJQUxfRkxBRztcbiAgICAgIH1cbiAgICAgIHJldHVybiBjcmVhdGVXcmFwKGtleSwgYml0bWFzaywgb2JqZWN0LCBwYXJ0aWFscywgaG9sZGVycyk7XG4gICAgfSk7XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgZnVuY3Rpb24gdGhhdCBhY2NlcHRzIGFyZ3VtZW50cyBvZiBgZnVuY2AgYW5kIGVpdGhlciBpbnZva2VzXG4gICAgICogYGZ1bmNgIHJldHVybmluZyBpdHMgcmVzdWx0LCBpZiBhdCBsZWFzdCBgYXJpdHlgIG51bWJlciBvZiBhcmd1bWVudHMgaGF2ZVxuICAgICAqIGJlZW4gcHJvdmlkZWQsIG9yIHJldHVybnMgYSBmdW5jdGlvbiB0aGF0IGFjY2VwdHMgdGhlIHJlbWFpbmluZyBgZnVuY2BcbiAgICAgKiBhcmd1bWVudHMsIGFuZCBzbyBvbi4gVGhlIGFyaXR5IG9mIGBmdW5jYCBtYXkgYmUgc3BlY2lmaWVkIGlmIGBmdW5jLmxlbmd0aGBcbiAgICAgKiBpcyBub3Qgc3VmZmljaWVudC5cbiAgICAgKlxuICAgICAqIFRoZSBgXy5jdXJyeS5wbGFjZWhvbGRlcmAgdmFsdWUsIHdoaWNoIGRlZmF1bHRzIHRvIGBfYCBpbiBtb25vbGl0aGljIGJ1aWxkcyxcbiAgICAgKiBtYXkgYmUgdXNlZCBhcyBhIHBsYWNlaG9sZGVyIGZvciBwcm92aWRlZCBhcmd1bWVudHMuXG4gICAgICpcbiAgICAgKiAqKk5vdGU6KiogVGhpcyBtZXRob2QgZG9lc24ndCBzZXQgdGhlIFwibGVuZ3RoXCIgcHJvcGVydHkgb2YgY3VycmllZCBmdW5jdGlvbnMuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMi4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgRnVuY3Rpb25cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBmdW5jIFRoZSBmdW5jdGlvbiB0byBjdXJyeS5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gW2FyaXR5PWZ1bmMubGVuZ3RoXSBUaGUgYXJpdHkgb2YgYGZ1bmNgLlxuICAgICAqIEBwYXJhbS0ge09iamVjdH0gW2d1YXJkXSBFbmFibGVzIHVzZSBhcyBhbiBpdGVyYXRlZSBmb3IgbWV0aG9kcyBsaWtlIGBfLm1hcGAuXG4gICAgICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBuZXcgY3VycmllZCBmdW5jdGlvbi5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogdmFyIGFiYyA9IGZ1bmN0aW9uKGEsIGIsIGMpIHtcbiAgICAgKiAgIHJldHVybiBbYSwgYiwgY107XG4gICAgICogfTtcbiAgICAgKlxuICAgICAqIHZhciBjdXJyaWVkID0gXy5jdXJyeShhYmMpO1xuICAgICAqXG4gICAgICogY3VycmllZCgxKSgyKSgzKTtcbiAgICAgKiAvLyA9PiBbMSwgMiwgM11cbiAgICAgKlxuICAgICAqIGN1cnJpZWQoMSwgMikoMyk7XG4gICAgICogLy8gPT4gWzEsIDIsIDNdXG4gICAgICpcbiAgICAgKiBjdXJyaWVkKDEsIDIsIDMpO1xuICAgICAqIC8vID0+IFsxLCAyLCAzXVxuICAgICAqXG4gICAgICogLy8gQ3VycmllZCB3aXRoIHBsYWNlaG9sZGVycy5cbiAgICAgKiBjdXJyaWVkKDEpKF8sIDMpKDIpO1xuICAgICAqIC8vID0+IFsxLCAyLCAzXVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGN1cnJ5KGZ1bmMsIGFyaXR5LCBndWFyZCkge1xuICAgICAgYXJpdHkgPSBndWFyZCA/IHVuZGVmaW5lZCA6IGFyaXR5O1xuICAgICAgdmFyIHJlc3VsdCA9IGNyZWF0ZVdyYXAoZnVuYywgV1JBUF9DVVJSWV9GTEFHLCB1bmRlZmluZWQsIHVuZGVmaW5lZCwgdW5kZWZpbmVkLCB1bmRlZmluZWQsIHVuZGVmaW5lZCwgYXJpdHkpO1xuICAgICAgcmVzdWx0LnBsYWNlaG9sZGVyID0gY3VycnkucGxhY2Vob2xkZXI7XG4gICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoaXMgbWV0aG9kIGlzIGxpa2UgYF8uY3VycnlgIGV4Y2VwdCB0aGF0IGFyZ3VtZW50cyBhcmUgYXBwbGllZCB0byBgZnVuY2BcbiAgICAgKiBpbiB0aGUgbWFubmVyIG9mIGBfLnBhcnRpYWxSaWdodGAgaW5zdGVhZCBvZiBgXy5wYXJ0aWFsYC5cbiAgICAgKlxuICAgICAqIFRoZSBgXy5jdXJyeVJpZ2h0LnBsYWNlaG9sZGVyYCB2YWx1ZSwgd2hpY2ggZGVmYXVsdHMgdG8gYF9gIGluIG1vbm9saXRoaWNcbiAgICAgKiBidWlsZHMsIG1heSBiZSB1c2VkIGFzIGEgcGxhY2Vob2xkZXIgZm9yIHByb3ZpZGVkIGFyZ3VtZW50cy5cbiAgICAgKlxuICAgICAqICoqTm90ZToqKiBUaGlzIG1ldGhvZCBkb2Vzbid0IHNldCB0aGUgXCJsZW5ndGhcIiBwcm9wZXJ0eSBvZiBjdXJyaWVkIGZ1bmN0aW9ucy5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAzLjAuMFxuICAgICAqIEBjYXRlZ29yeSBGdW5jdGlvblxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IGZ1bmMgVGhlIGZ1bmN0aW9uIHRvIGN1cnJ5LlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbYXJpdHk9ZnVuYy5sZW5ndGhdIFRoZSBhcml0eSBvZiBgZnVuY2AuXG4gICAgICogQHBhcmFtLSB7T2JqZWN0fSBbZ3VhcmRdIEVuYWJsZXMgdXNlIGFzIGFuIGl0ZXJhdGVlIGZvciBtZXRob2RzIGxpa2UgYF8ubWFwYC5cbiAgICAgKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyBjdXJyaWVkIGZ1bmN0aW9uLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiB2YXIgYWJjID0gZnVuY3Rpb24oYSwgYiwgYykge1xuICAgICAqICAgcmV0dXJuIFthLCBiLCBjXTtcbiAgICAgKiB9O1xuICAgICAqXG4gICAgICogdmFyIGN1cnJpZWQgPSBfLmN1cnJ5UmlnaHQoYWJjKTtcbiAgICAgKlxuICAgICAqIGN1cnJpZWQoMykoMikoMSk7XG4gICAgICogLy8gPT4gWzEsIDIsIDNdXG4gICAgICpcbiAgICAgKiBjdXJyaWVkKDIsIDMpKDEpO1xuICAgICAqIC8vID0+IFsxLCAyLCAzXVxuICAgICAqXG4gICAgICogY3VycmllZCgxLCAyLCAzKTtcbiAgICAgKiAvLyA9PiBbMSwgMiwgM11cbiAgICAgKlxuICAgICAqIC8vIEN1cnJpZWQgd2l0aCBwbGFjZWhvbGRlcnMuXG4gICAgICogY3VycmllZCgzKSgxLCBfKSgyKTtcbiAgICAgKiAvLyA9PiBbMSwgMiwgM11cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBjdXJyeVJpZ2h0KGZ1bmMsIGFyaXR5LCBndWFyZCkge1xuICAgICAgYXJpdHkgPSBndWFyZCA/IHVuZGVmaW5lZCA6IGFyaXR5O1xuICAgICAgdmFyIHJlc3VsdCA9IGNyZWF0ZVdyYXAoZnVuYywgV1JBUF9DVVJSWV9SSUdIVF9GTEFHLCB1bmRlZmluZWQsIHVuZGVmaW5lZCwgdW5kZWZpbmVkLCB1bmRlZmluZWQsIHVuZGVmaW5lZCwgYXJpdHkpO1xuICAgICAgcmVzdWx0LnBsYWNlaG9sZGVyID0gY3VycnlSaWdodC5wbGFjZWhvbGRlcjtcbiAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIGRlYm91bmNlZCBmdW5jdGlvbiB0aGF0IGRlbGF5cyBpbnZva2luZyBgZnVuY2AgdW50aWwgYWZ0ZXIgYHdhaXRgXG4gICAgICogbWlsbGlzZWNvbmRzIGhhdmUgZWxhcHNlZCBzaW5jZSB0aGUgbGFzdCB0aW1lIHRoZSBkZWJvdW5jZWQgZnVuY3Rpb24gd2FzXG4gICAgICogaW52b2tlZC4gVGhlIGRlYm91bmNlZCBmdW5jdGlvbiBjb21lcyB3aXRoIGEgYGNhbmNlbGAgbWV0aG9kIHRvIGNhbmNlbFxuICAgICAqIGRlbGF5ZWQgYGZ1bmNgIGludm9jYXRpb25zIGFuZCBhIGBmbHVzaGAgbWV0aG9kIHRvIGltbWVkaWF0ZWx5IGludm9rZSB0aGVtLlxuICAgICAqIFByb3ZpZGUgYG9wdGlvbnNgIHRvIGluZGljYXRlIHdoZXRoZXIgYGZ1bmNgIHNob3VsZCBiZSBpbnZva2VkIG9uIHRoZVxuICAgICAqIGxlYWRpbmcgYW5kL29yIHRyYWlsaW5nIGVkZ2Ugb2YgdGhlIGB3YWl0YCB0aW1lb3V0LiBUaGUgYGZ1bmNgIGlzIGludm9rZWRcbiAgICAgKiB3aXRoIHRoZSBsYXN0IGFyZ3VtZW50cyBwcm92aWRlZCB0byB0aGUgZGVib3VuY2VkIGZ1bmN0aW9uLiBTdWJzZXF1ZW50XG4gICAgICogY2FsbHMgdG8gdGhlIGRlYm91bmNlZCBmdW5jdGlvbiByZXR1cm4gdGhlIHJlc3VsdCBvZiB0aGUgbGFzdCBgZnVuY2BcbiAgICAgKiBpbnZvY2F0aW9uLlxuICAgICAqXG4gICAgICogKipOb3RlOioqIElmIGBsZWFkaW5nYCBhbmQgYHRyYWlsaW5nYCBvcHRpb25zIGFyZSBgdHJ1ZWAsIGBmdW5jYCBpc1xuICAgICAqIGludm9rZWQgb24gdGhlIHRyYWlsaW5nIGVkZ2Ugb2YgdGhlIHRpbWVvdXQgb25seSBpZiB0aGUgZGVib3VuY2VkIGZ1bmN0aW9uXG4gICAgICogaXMgaW52b2tlZCBtb3JlIHRoYW4gb25jZSBkdXJpbmcgdGhlIGB3YWl0YCB0aW1lb3V0LlxuICAgICAqXG4gICAgICogSWYgYHdhaXRgIGlzIGAwYCBhbmQgYGxlYWRpbmdgIGlzIGBmYWxzZWAsIGBmdW5jYCBpbnZvY2F0aW9uIGlzIGRlZmVycmVkXG4gICAgICogdW50aWwgdG8gdGhlIG5leHQgdGljaywgc2ltaWxhciB0byBgc2V0VGltZW91dGAgd2l0aCBhIHRpbWVvdXQgb2YgYDBgLlxuICAgICAqXG4gICAgICogU2VlIFtEYXZpZCBDb3JiYWNobydzIGFydGljbGVdKGh0dHBzOi8vY3NzLXRyaWNrcy5jb20vZGVib3VuY2luZy10aHJvdHRsaW5nLWV4cGxhaW5lZC1leGFtcGxlcy8pXG4gICAgICogZm9yIGRldGFpbHMgb3ZlciB0aGUgZGlmZmVyZW5jZXMgYmV0d2VlbiBgXy5kZWJvdW5jZWAgYW5kIGBfLnRocm90dGxlYC5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAwLjEuMFxuICAgICAqIEBjYXRlZ29yeSBGdW5jdGlvblxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IGZ1bmMgVGhlIGZ1bmN0aW9uIHRvIGRlYm91bmNlLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbd2FpdD0wXSBUaGUgbnVtYmVyIG9mIG1pbGxpc2Vjb25kcyB0byBkZWxheS5cbiAgICAgKiBAcGFyYW0ge09iamVjdH0gW29wdGlvbnM9e31dIFRoZSBvcHRpb25zIG9iamVjdC5cbiAgICAgKiBAcGFyYW0ge2Jvb2xlYW59IFtvcHRpb25zLmxlYWRpbmc9ZmFsc2VdXG4gICAgICogIFNwZWNpZnkgaW52b2tpbmcgb24gdGhlIGxlYWRpbmcgZWRnZSBvZiB0aGUgdGltZW91dC5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gW29wdGlvbnMubWF4V2FpdF1cbiAgICAgKiAgVGhlIG1heGltdW0gdGltZSBgZnVuY2AgaXMgYWxsb3dlZCB0byBiZSBkZWxheWVkIGJlZm9yZSBpdCdzIGludm9rZWQuXG4gICAgICogQHBhcmFtIHtib29sZWFufSBbb3B0aW9ucy50cmFpbGluZz10cnVlXVxuICAgICAqICBTcGVjaWZ5IGludm9raW5nIG9uIHRoZSB0cmFpbGluZyBlZGdlIG9mIHRoZSB0aW1lb3V0LlxuICAgICAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyB0aGUgbmV3IGRlYm91bmNlZCBmdW5jdGlvbi5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogLy8gQXZvaWQgY29zdGx5IGNhbGN1bGF0aW9ucyB3aGlsZSB0aGUgd2luZG93IHNpemUgaXMgaW4gZmx1eC5cbiAgICAgKiBqUXVlcnkod2luZG93KS5vbigncmVzaXplJywgXy5kZWJvdW5jZShjYWxjdWxhdGVMYXlvdXQsIDE1MCkpO1xuICAgICAqXG4gICAgICogLy8gSW52b2tlIGBzZW5kTWFpbGAgd2hlbiBjbGlja2VkLCBkZWJvdW5jaW5nIHN1YnNlcXVlbnQgY2FsbHMuXG4gICAgICogalF1ZXJ5KGVsZW1lbnQpLm9uKCdjbGljaycsIF8uZGVib3VuY2Uoc2VuZE1haWwsIDMwMCwge1xuICAgICAqICAgJ2xlYWRpbmcnOiB0cnVlLFxuICAgICAqICAgJ3RyYWlsaW5nJzogZmFsc2VcbiAgICAgKiB9KSk7XG4gICAgICpcbiAgICAgKiAvLyBFbnN1cmUgYGJhdGNoTG9nYCBpcyBpbnZva2VkIG9uY2UgYWZ0ZXIgMSBzZWNvbmQgb2YgZGVib3VuY2VkIGNhbGxzLlxuICAgICAqIHZhciBkZWJvdW5jZWQgPSBfLmRlYm91bmNlKGJhdGNoTG9nLCAyNTAsIHsgJ21heFdhaXQnOiAxMDAwIH0pO1xuICAgICAqIHZhciBzb3VyY2UgPSBuZXcgRXZlbnRTb3VyY2UoJy9zdHJlYW0nKTtcbiAgICAgKiBqUXVlcnkoc291cmNlKS5vbignbWVzc2FnZScsIGRlYm91bmNlZCk7XG4gICAgICpcbiAgICAgKiAvLyBDYW5jZWwgdGhlIHRyYWlsaW5nIGRlYm91bmNlZCBpbnZvY2F0aW9uLlxuICAgICAqIGpRdWVyeSh3aW5kb3cpLm9uKCdwb3BzdGF0ZScsIGRlYm91bmNlZC5jYW5jZWwpO1xuICAgICAqL1xuICAgIGZ1bmN0aW9uIGRlYm91bmNlKGZ1bmMsIHdhaXQsIG9wdGlvbnMpIHtcbiAgICAgIHZhciBsYXN0QXJncyxcbiAgICAgICAgICBsYXN0VGhpcyxcbiAgICAgICAgICBtYXhXYWl0LFxuICAgICAgICAgIHJlc3VsdCxcbiAgICAgICAgICB0aW1lcklkLFxuICAgICAgICAgIGxhc3RDYWxsVGltZSxcbiAgICAgICAgICBsYXN0SW52b2tlVGltZSA9IDAsXG4gICAgICAgICAgbGVhZGluZyA9IGZhbHNlLFxuICAgICAgICAgIG1heGluZyA9IGZhbHNlLFxuICAgICAgICAgIHRyYWlsaW5nID0gdHJ1ZTtcblxuICAgICAgaWYgKHR5cGVvZiBmdW5jICE9ICdmdW5jdGlvbicpIHtcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihGVU5DX0VSUk9SX1RFWFQpO1xuICAgICAgfVxuICAgICAgd2FpdCA9IHRvTnVtYmVyKHdhaXQpIHx8IDA7XG4gICAgICBpZiAoaXNPYmplY3Qob3B0aW9ucykpIHtcbiAgICAgICAgbGVhZGluZyA9ICEhb3B0aW9ucy5sZWFkaW5nO1xuICAgICAgICBtYXhpbmcgPSAnbWF4V2FpdCcgaW4gb3B0aW9ucztcbiAgICAgICAgbWF4V2FpdCA9IG1heGluZyA/IG5hdGl2ZU1heCh0b051bWJlcihvcHRpb25zLm1heFdhaXQpIHx8IDAsIHdhaXQpIDogbWF4V2FpdDtcbiAgICAgICAgdHJhaWxpbmcgPSAndHJhaWxpbmcnIGluIG9wdGlvbnMgPyAhIW9wdGlvbnMudHJhaWxpbmcgOiB0cmFpbGluZztcbiAgICAgIH1cblxuICAgICAgZnVuY3Rpb24gaW52b2tlRnVuYyh0aW1lKSB7XG4gICAgICAgIHZhciBhcmdzID0gbGFzdEFyZ3MsXG4gICAgICAgICAgICB0aGlzQXJnID0gbGFzdFRoaXM7XG5cbiAgICAgICAgbGFzdEFyZ3MgPSBsYXN0VGhpcyA9IHVuZGVmaW5lZDtcbiAgICAgICAgbGFzdEludm9rZVRpbWUgPSB0aW1lO1xuICAgICAgICByZXN1bHQgPSBmdW5jLmFwcGx5KHRoaXNBcmcsIGFyZ3MpO1xuICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgICAgfVxuXG4gICAgICBmdW5jdGlvbiBsZWFkaW5nRWRnZSh0aW1lKSB7XG4gICAgICAgIC8vIFJlc2V0IGFueSBgbWF4V2FpdGAgdGltZXIuXG4gICAgICAgIGxhc3RJbnZva2VUaW1lID0gdGltZTtcbiAgICAgICAgLy8gU3RhcnQgdGhlIHRpbWVyIGZvciB0aGUgdHJhaWxpbmcgZWRnZS5cbiAgICAgICAgdGltZXJJZCA9IHNldFRpbWVvdXQodGltZXJFeHBpcmVkLCB3YWl0KTtcbiAgICAgICAgLy8gSW52b2tlIHRoZSBsZWFkaW5nIGVkZ2UuXG4gICAgICAgIHJldHVybiBsZWFkaW5nID8gaW52b2tlRnVuYyh0aW1lKSA6IHJlc3VsdDtcbiAgICAgIH1cblxuICAgICAgZnVuY3Rpb24gcmVtYWluaW5nV2FpdCh0aW1lKSB7XG4gICAgICAgIHZhciB0aW1lU2luY2VMYXN0Q2FsbCA9IHRpbWUgLSBsYXN0Q2FsbFRpbWUsXG4gICAgICAgICAgICB0aW1lU2luY2VMYXN0SW52b2tlID0gdGltZSAtIGxhc3RJbnZva2VUaW1lLFxuICAgICAgICAgICAgcmVzdWx0ID0gd2FpdCAtIHRpbWVTaW5jZUxhc3RDYWxsO1xuXG4gICAgICAgIHJldHVybiBtYXhpbmcgPyBuYXRpdmVNaW4ocmVzdWx0LCBtYXhXYWl0IC0gdGltZVNpbmNlTGFzdEludm9rZSkgOiByZXN1bHQ7XG4gICAgICB9XG5cbiAgICAgIGZ1bmN0aW9uIHNob3VsZEludm9rZSh0aW1lKSB7XG4gICAgICAgIHZhciB0aW1lU2luY2VMYXN0Q2FsbCA9IHRpbWUgLSBsYXN0Q2FsbFRpbWUsXG4gICAgICAgICAgICB0aW1lU2luY2VMYXN0SW52b2tlID0gdGltZSAtIGxhc3RJbnZva2VUaW1lO1xuXG4gICAgICAgIC8vIEVpdGhlciB0aGlzIGlzIHRoZSBmaXJzdCBjYWxsLCBhY3Rpdml0eSBoYXMgc3RvcHBlZCBhbmQgd2UncmUgYXQgdGhlXG4gICAgICAgIC8vIHRyYWlsaW5nIGVkZ2UsIHRoZSBzeXN0ZW0gdGltZSBoYXMgZ29uZSBiYWNrd2FyZHMgYW5kIHdlJ3JlIHRyZWF0aW5nXG4gICAgICAgIC8vIGl0IGFzIHRoZSB0cmFpbGluZyBlZGdlLCBvciB3ZSd2ZSBoaXQgdGhlIGBtYXhXYWl0YCBsaW1pdC5cbiAgICAgICAgcmV0dXJuIChsYXN0Q2FsbFRpbWUgPT09IHVuZGVmaW5lZCB8fCAodGltZVNpbmNlTGFzdENhbGwgPj0gd2FpdCkgfHxcbiAgICAgICAgICAodGltZVNpbmNlTGFzdENhbGwgPCAwKSB8fCAobWF4aW5nICYmIHRpbWVTaW5jZUxhc3RJbnZva2UgPj0gbWF4V2FpdCkpO1xuICAgICAgfVxuXG4gICAgICBmdW5jdGlvbiB0aW1lckV4cGlyZWQoKSB7XG4gICAgICAgIHZhciB0aW1lID0gbm93KCk7XG4gICAgICAgIGlmIChzaG91bGRJbnZva2UodGltZSkpIHtcbiAgICAgICAgICByZXR1cm4gdHJhaWxpbmdFZGdlKHRpbWUpO1xuICAgICAgICB9XG4gICAgICAgIC8vIFJlc3RhcnQgdGhlIHRpbWVyLlxuICAgICAgICB0aW1lcklkID0gc2V0VGltZW91dCh0aW1lckV4cGlyZWQsIHJlbWFpbmluZ1dhaXQodGltZSkpO1xuICAgICAgfVxuXG4gICAgICBmdW5jdGlvbiB0cmFpbGluZ0VkZ2UodGltZSkge1xuICAgICAgICB0aW1lcklkID0gdW5kZWZpbmVkO1xuXG4gICAgICAgIC8vIE9ubHkgaW52b2tlIGlmIHdlIGhhdmUgYGxhc3RBcmdzYCB3aGljaCBtZWFucyBgZnVuY2AgaGFzIGJlZW5cbiAgICAgICAgLy8gZGVib3VuY2VkIGF0IGxlYXN0IG9uY2UuXG4gICAgICAgIGlmICh0cmFpbGluZyAmJiBsYXN0QXJncykge1xuICAgICAgICAgIHJldHVybiBpbnZva2VGdW5jKHRpbWUpO1xuICAgICAgICB9XG4gICAgICAgIGxhc3RBcmdzID0gbGFzdFRoaXMgPSB1bmRlZmluZWQ7XG4gICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgICB9XG5cbiAgICAgIGZ1bmN0aW9uIGNhbmNlbCgpIHtcbiAgICAgICAgaWYgKHRpbWVySWQgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgIGNsZWFyVGltZW91dCh0aW1lcklkKTtcbiAgICAgICAgfVxuICAgICAgICBsYXN0SW52b2tlVGltZSA9IDA7XG4gICAgICAgIGxhc3RBcmdzID0gbGFzdENhbGxUaW1lID0gbGFzdFRoaXMgPSB0aW1lcklkID0gdW5kZWZpbmVkO1xuICAgICAgfVxuXG4gICAgICBmdW5jdGlvbiBmbHVzaCgpIHtcbiAgICAgICAgcmV0dXJuIHRpbWVySWQgPT09IHVuZGVmaW5lZCA/IHJlc3VsdCA6IHRyYWlsaW5nRWRnZShub3coKSk7XG4gICAgICB9XG5cbiAgICAgIGZ1bmN0aW9uIGRlYm91bmNlZCgpIHtcbiAgICAgICAgdmFyIHRpbWUgPSBub3coKSxcbiAgICAgICAgICAgIGlzSW52b2tpbmcgPSBzaG91bGRJbnZva2UodGltZSk7XG5cbiAgICAgICAgbGFzdEFyZ3MgPSBhcmd1bWVudHM7XG4gICAgICAgIGxhc3RUaGlzID0gdGhpcztcbiAgICAgICAgbGFzdENhbGxUaW1lID0gdGltZTtcblxuICAgICAgICBpZiAoaXNJbnZva2luZykge1xuICAgICAgICAgIGlmICh0aW1lcklkID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHJldHVybiBsZWFkaW5nRWRnZShsYXN0Q2FsbFRpbWUpO1xuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAobWF4aW5nKSB7XG4gICAgICAgICAgICAvLyBIYW5kbGUgaW52b2NhdGlvbnMgaW4gYSB0aWdodCBsb29wLlxuICAgICAgICAgICAgdGltZXJJZCA9IHNldFRpbWVvdXQodGltZXJFeHBpcmVkLCB3YWl0KTtcbiAgICAgICAgICAgIHJldHVybiBpbnZva2VGdW5jKGxhc3RDYWxsVGltZSk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGlmICh0aW1lcklkID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICB0aW1lcklkID0gc2V0VGltZW91dCh0aW1lckV4cGlyZWQsIHdhaXQpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgICB9XG4gICAgICBkZWJvdW5jZWQuY2FuY2VsID0gY2FuY2VsO1xuICAgICAgZGVib3VuY2VkLmZsdXNoID0gZmx1c2g7XG4gICAgICByZXR1cm4gZGVib3VuY2VkO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIERlZmVycyBpbnZva2luZyB0aGUgYGZ1bmNgIHVudGlsIHRoZSBjdXJyZW50IGNhbGwgc3RhY2sgaGFzIGNsZWFyZWQuIEFueVxuICAgICAqIGFkZGl0aW9uYWwgYXJndW1lbnRzIGFyZSBwcm92aWRlZCB0byBgZnVuY2Agd2hlbiBpdCdzIGludm9rZWQuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMC4xLjBcbiAgICAgKiBAY2F0ZWdvcnkgRnVuY3Rpb25cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBmdW5jIFRoZSBmdW5jdGlvbiB0byBkZWZlci5cbiAgICAgKiBAcGFyYW0gey4uLip9IFthcmdzXSBUaGUgYXJndW1lbnRzIHRvIGludm9rZSBgZnVuY2Agd2l0aC5cbiAgICAgKiBAcmV0dXJucyB7bnVtYmVyfSBSZXR1cm5zIHRoZSB0aW1lciBpZC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy5kZWZlcihmdW5jdGlvbih0ZXh0KSB7XG4gICAgICogICBjb25zb2xlLmxvZyh0ZXh0KTtcbiAgICAgKiB9LCAnZGVmZXJyZWQnKTtcbiAgICAgKiAvLyA9PiBMb2dzICdkZWZlcnJlZCcgYWZ0ZXIgb25lIG1pbGxpc2Vjb25kLlxuICAgICAqL1xuICAgIHZhciBkZWZlciA9IGJhc2VSZXN0KGZ1bmN0aW9uKGZ1bmMsIGFyZ3MpIHtcbiAgICAgIHJldHVybiBiYXNlRGVsYXkoZnVuYywgMSwgYXJncyk7XG4gICAgfSk7XG5cbiAgICAvKipcbiAgICAgKiBJbnZva2VzIGBmdW5jYCBhZnRlciBgd2FpdGAgbWlsbGlzZWNvbmRzLiBBbnkgYWRkaXRpb25hbCBhcmd1bWVudHMgYXJlXG4gICAgICogcHJvdmlkZWQgdG8gYGZ1bmNgIHdoZW4gaXQncyBpbnZva2VkLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDAuMS4wXG4gICAgICogQGNhdGVnb3J5IEZ1bmN0aW9uXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gZnVuYyBUaGUgZnVuY3Rpb24gdG8gZGVsYXkuXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IHdhaXQgVGhlIG51bWJlciBvZiBtaWxsaXNlY29uZHMgdG8gZGVsYXkgaW52b2NhdGlvbi5cbiAgICAgKiBAcGFyYW0gey4uLip9IFthcmdzXSBUaGUgYXJndW1lbnRzIHRvIGludm9rZSBgZnVuY2Agd2l0aC5cbiAgICAgKiBAcmV0dXJucyB7bnVtYmVyfSBSZXR1cm5zIHRoZSB0aW1lciBpZC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy5kZWxheShmdW5jdGlvbih0ZXh0KSB7XG4gICAgICogICBjb25zb2xlLmxvZyh0ZXh0KTtcbiAgICAgKiB9LCAxMDAwLCAnbGF0ZXInKTtcbiAgICAgKiAvLyA9PiBMb2dzICdsYXRlcicgYWZ0ZXIgb25lIHNlY29uZC5cbiAgICAgKi9cbiAgICB2YXIgZGVsYXkgPSBiYXNlUmVzdChmdW5jdGlvbihmdW5jLCB3YWl0LCBhcmdzKSB7XG4gICAgICByZXR1cm4gYmFzZURlbGF5KGZ1bmMsIHRvTnVtYmVyKHdhaXQpIHx8IDAsIGFyZ3MpO1xuICAgIH0pO1xuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIGZ1bmN0aW9uIHRoYXQgaW52b2tlcyBgZnVuY2Agd2l0aCBhcmd1bWVudHMgcmV2ZXJzZWQuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgNC4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgRnVuY3Rpb25cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBmdW5jIFRoZSBmdW5jdGlvbiB0byBmbGlwIGFyZ3VtZW50cyBmb3IuXG4gICAgICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBuZXcgZmxpcHBlZCBmdW5jdGlvbi5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogdmFyIGZsaXBwZWQgPSBfLmZsaXAoZnVuY3Rpb24oKSB7XG4gICAgICogICByZXR1cm4gXy50b0FycmF5KGFyZ3VtZW50cyk7XG4gICAgICogfSk7XG4gICAgICpcbiAgICAgKiBmbGlwcGVkKCdhJywgJ2InLCAnYycsICdkJyk7XG4gICAgICogLy8gPT4gWydkJywgJ2MnLCAnYicsICdhJ11cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBmbGlwKGZ1bmMpIHtcbiAgICAgIHJldHVybiBjcmVhdGVXcmFwKGZ1bmMsIFdSQVBfRkxJUF9GTEFHKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgZnVuY3Rpb24gdGhhdCBtZW1vaXplcyB0aGUgcmVzdWx0IG9mIGBmdW5jYC4gSWYgYHJlc29sdmVyYCBpc1xuICAgICAqIHByb3ZpZGVkLCBpdCBkZXRlcm1pbmVzIHRoZSBjYWNoZSBrZXkgZm9yIHN0b3JpbmcgdGhlIHJlc3VsdCBiYXNlZCBvbiB0aGVcbiAgICAgKiBhcmd1bWVudHMgcHJvdmlkZWQgdG8gdGhlIG1lbW9pemVkIGZ1bmN0aW9uLiBCeSBkZWZhdWx0LCB0aGUgZmlyc3QgYXJndW1lbnRcbiAgICAgKiBwcm92aWRlZCB0byB0aGUgbWVtb2l6ZWQgZnVuY3Rpb24gaXMgdXNlZCBhcyB0aGUgbWFwIGNhY2hlIGtleS4gVGhlIGBmdW5jYFxuICAgICAqIGlzIGludm9rZWQgd2l0aCB0aGUgYHRoaXNgIGJpbmRpbmcgb2YgdGhlIG1lbW9pemVkIGZ1bmN0aW9uLlxuICAgICAqXG4gICAgICogKipOb3RlOioqIFRoZSBjYWNoZSBpcyBleHBvc2VkIGFzIHRoZSBgY2FjaGVgIHByb3BlcnR5IG9uIHRoZSBtZW1vaXplZFxuICAgICAqIGZ1bmN0aW9uLiBJdHMgY3JlYXRpb24gbWF5IGJlIGN1c3RvbWl6ZWQgYnkgcmVwbGFjaW5nIHRoZSBgXy5tZW1vaXplLkNhY2hlYFxuICAgICAqIGNvbnN0cnVjdG9yIHdpdGggb25lIHdob3NlIGluc3RhbmNlcyBpbXBsZW1lbnQgdGhlXG4gICAgICogW2BNYXBgXShodHRwOi8vZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi83LjAvI3NlYy1wcm9wZXJ0aWVzLW9mLXRoZS1tYXAtcHJvdG90eXBlLW9iamVjdClcbiAgICAgKiBtZXRob2QgaW50ZXJmYWNlIG9mIGBjbGVhcmAsIGBkZWxldGVgLCBgZ2V0YCwgYGhhc2AsIGFuZCBgc2V0YC5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAwLjEuMFxuICAgICAqIEBjYXRlZ29yeSBGdW5jdGlvblxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IGZ1bmMgVGhlIGZ1bmN0aW9uIHRvIGhhdmUgaXRzIG91dHB1dCBtZW1vaXplZC5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBbcmVzb2x2ZXJdIFRoZSBmdW5jdGlvbiB0byByZXNvbHZlIHRoZSBjYWNoZSBrZXkuXG4gICAgICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBuZXcgbWVtb2l6ZWQgZnVuY3Rpb24uXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIHZhciBvYmplY3QgPSB7ICdhJzogMSwgJ2InOiAyIH07XG4gICAgICogdmFyIG90aGVyID0geyAnYyc6IDMsICdkJzogNCB9O1xuICAgICAqXG4gICAgICogdmFyIHZhbHVlcyA9IF8ubWVtb2l6ZShfLnZhbHVlcyk7XG4gICAgICogdmFsdWVzKG9iamVjdCk7XG4gICAgICogLy8gPT4gWzEsIDJdXG4gICAgICpcbiAgICAgKiB2YWx1ZXMob3RoZXIpO1xuICAgICAqIC8vID0+IFszLCA0XVxuICAgICAqXG4gICAgICogb2JqZWN0LmEgPSAyO1xuICAgICAqIHZhbHVlcyhvYmplY3QpO1xuICAgICAqIC8vID0+IFsxLCAyXVxuICAgICAqXG4gICAgICogLy8gTW9kaWZ5IHRoZSByZXN1bHQgY2FjaGUuXG4gICAgICogdmFsdWVzLmNhY2hlLnNldChvYmplY3QsIFsnYScsICdiJ10pO1xuICAgICAqIHZhbHVlcyhvYmplY3QpO1xuICAgICAqIC8vID0+IFsnYScsICdiJ11cbiAgICAgKlxuICAgICAqIC8vIFJlcGxhY2UgYF8ubWVtb2l6ZS5DYWNoZWAuXG4gICAgICogXy5tZW1vaXplLkNhY2hlID0gV2Vha01hcDtcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBtZW1vaXplKGZ1bmMsIHJlc29sdmVyKSB7XG4gICAgICBpZiAodHlwZW9mIGZ1bmMgIT0gJ2Z1bmN0aW9uJyB8fCAocmVzb2x2ZXIgIT0gbnVsbCAmJiB0eXBlb2YgcmVzb2x2ZXIgIT0gJ2Z1bmN0aW9uJykpIHtcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihGVU5DX0VSUk9SX1RFWFQpO1xuICAgICAgfVxuICAgICAgdmFyIG1lbW9pemVkID0gZnVuY3Rpb24oKSB7XG4gICAgICAgIHZhciBhcmdzID0gYXJndW1lbnRzLFxuICAgICAgICAgICAga2V5ID0gcmVzb2x2ZXIgPyByZXNvbHZlci5hcHBseSh0aGlzLCBhcmdzKSA6IGFyZ3NbMF0sXG4gICAgICAgICAgICBjYWNoZSA9IG1lbW9pemVkLmNhY2hlO1xuXG4gICAgICAgIGlmIChjYWNoZS5oYXMoa2V5KSkge1xuICAgICAgICAgIHJldHVybiBjYWNoZS5nZXQoa2V5KTtcbiAgICAgICAgfVxuICAgICAgICB2YXIgcmVzdWx0ID0gZnVuYy5hcHBseSh0aGlzLCBhcmdzKTtcbiAgICAgICAgbWVtb2l6ZWQuY2FjaGUgPSBjYWNoZS5zZXQoa2V5LCByZXN1bHQpIHx8IGNhY2hlO1xuICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgICAgfTtcbiAgICAgIG1lbW9pemVkLmNhY2hlID0gbmV3IChtZW1vaXplLkNhY2hlIHx8IE1hcENhY2hlKTtcbiAgICAgIHJldHVybiBtZW1vaXplZDtcbiAgICB9XG5cbiAgICAvLyBFeHBvc2UgYE1hcENhY2hlYC5cbiAgICBtZW1vaXplLkNhY2hlID0gTWFwQ2FjaGU7XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgZnVuY3Rpb24gdGhhdCBuZWdhdGVzIHRoZSByZXN1bHQgb2YgdGhlIHByZWRpY2F0ZSBgZnVuY2AuIFRoZVxuICAgICAqIGBmdW5jYCBwcmVkaWNhdGUgaXMgaW52b2tlZCB3aXRoIHRoZSBgdGhpc2AgYmluZGluZyBhbmQgYXJndW1lbnRzIG9mIHRoZVxuICAgICAqIGNyZWF0ZWQgZnVuY3Rpb24uXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMy4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgRnVuY3Rpb25cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBwcmVkaWNhdGUgVGhlIHByZWRpY2F0ZSB0byBuZWdhdGUuXG4gICAgICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBuZXcgbmVnYXRlZCBmdW5jdGlvbi5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogZnVuY3Rpb24gaXNFdmVuKG4pIHtcbiAgICAgKiAgIHJldHVybiBuICUgMiA9PSAwO1xuICAgICAqIH1cbiAgICAgKlxuICAgICAqIF8uZmlsdGVyKFsxLCAyLCAzLCA0LCA1LCA2XSwgXy5uZWdhdGUoaXNFdmVuKSk7XG4gICAgICogLy8gPT4gWzEsIDMsIDVdXG4gICAgICovXG4gICAgZnVuY3Rpb24gbmVnYXRlKHByZWRpY2F0ZSkge1xuICAgICAgaWYgKHR5cGVvZiBwcmVkaWNhdGUgIT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKEZVTkNfRVJST1JfVEVYVCk7XG4gICAgICB9XG4gICAgICByZXR1cm4gZnVuY3Rpb24oKSB7XG4gICAgICAgIHZhciBhcmdzID0gYXJndW1lbnRzO1xuICAgICAgICBzd2l0Y2ggKGFyZ3MubGVuZ3RoKSB7XG4gICAgICAgICAgY2FzZSAwOiByZXR1cm4gIXByZWRpY2F0ZS5jYWxsKHRoaXMpO1xuICAgICAgICAgIGNhc2UgMTogcmV0dXJuICFwcmVkaWNhdGUuY2FsbCh0aGlzLCBhcmdzWzBdKTtcbiAgICAgICAgICBjYXNlIDI6IHJldHVybiAhcHJlZGljYXRlLmNhbGwodGhpcywgYXJnc1swXSwgYXJnc1sxXSk7XG4gICAgICAgICAgY2FzZSAzOiByZXR1cm4gIXByZWRpY2F0ZS5jYWxsKHRoaXMsIGFyZ3NbMF0sIGFyZ3NbMV0sIGFyZ3NbMl0pO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiAhcHJlZGljYXRlLmFwcGx5KHRoaXMsIGFyZ3MpO1xuICAgICAgfTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgZnVuY3Rpb24gdGhhdCBpcyByZXN0cmljdGVkIHRvIGludm9raW5nIGBmdW5jYCBvbmNlLiBSZXBlYXQgY2FsbHNcbiAgICAgKiB0byB0aGUgZnVuY3Rpb24gcmV0dXJuIHRoZSB2YWx1ZSBvZiB0aGUgZmlyc3QgaW52b2NhdGlvbi4gVGhlIGBmdW5jYCBpc1xuICAgICAqIGludm9rZWQgd2l0aCB0aGUgYHRoaXNgIGJpbmRpbmcgYW5kIGFyZ3VtZW50cyBvZiB0aGUgY3JlYXRlZCBmdW5jdGlvbi5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAwLjEuMFxuICAgICAqIEBjYXRlZ29yeSBGdW5jdGlvblxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IGZ1bmMgVGhlIGZ1bmN0aW9uIHRvIHJlc3RyaWN0LlxuICAgICAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyB0aGUgbmV3IHJlc3RyaWN0ZWQgZnVuY3Rpb24uXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIHZhciBpbml0aWFsaXplID0gXy5vbmNlKGNyZWF0ZUFwcGxpY2F0aW9uKTtcbiAgICAgKiBpbml0aWFsaXplKCk7XG4gICAgICogaW5pdGlhbGl6ZSgpO1xuICAgICAqIC8vID0+IGBjcmVhdGVBcHBsaWNhdGlvbmAgaXMgaW52b2tlZCBvbmNlXG4gICAgICovXG4gICAgZnVuY3Rpb24gb25jZShmdW5jKSB7XG4gICAgICByZXR1cm4gYmVmb3JlKDIsIGZ1bmMpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBmdW5jdGlvbiB0aGF0IGludm9rZXMgYGZ1bmNgIHdpdGggaXRzIGFyZ3VtZW50cyB0cmFuc2Zvcm1lZC5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAc2luY2UgNC4wLjBcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBjYXRlZ29yeSBGdW5jdGlvblxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IGZ1bmMgVGhlIGZ1bmN0aW9uIHRvIHdyYXAuXG4gICAgICogQHBhcmFtIHsuLi4oRnVuY3Rpb258RnVuY3Rpb25bXSl9IFt0cmFuc2Zvcm1zPVtfLmlkZW50aXR5XV1cbiAgICAgKiAgVGhlIGFyZ3VtZW50IHRyYW5zZm9ybXMuXG4gICAgICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBuZXcgZnVuY3Rpb24uXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIGZ1bmN0aW9uIGRvdWJsZWQobikge1xuICAgICAqICAgcmV0dXJuIG4gKiAyO1xuICAgICAqIH1cbiAgICAgKlxuICAgICAqIGZ1bmN0aW9uIHNxdWFyZShuKSB7XG4gICAgICogICByZXR1cm4gbiAqIG47XG4gICAgICogfVxuICAgICAqXG4gICAgICogdmFyIGZ1bmMgPSBfLm92ZXJBcmdzKGZ1bmN0aW9uKHgsIHkpIHtcbiAgICAgKiAgIHJldHVybiBbeCwgeV07XG4gICAgICogfSwgW3NxdWFyZSwgZG91YmxlZF0pO1xuICAgICAqXG4gICAgICogZnVuYyg5LCAzKTtcbiAgICAgKiAvLyA9PiBbODEsIDZdXG4gICAgICpcbiAgICAgKiBmdW5jKDEwLCA1KTtcbiAgICAgKiAvLyA9PiBbMTAwLCAxMF1cbiAgICAgKi9cbiAgICB2YXIgb3ZlckFyZ3MgPSBjYXN0UmVzdChmdW5jdGlvbihmdW5jLCB0cmFuc2Zvcm1zKSB7XG4gICAgICB0cmFuc2Zvcm1zID0gKHRyYW5zZm9ybXMubGVuZ3RoID09IDEgJiYgaXNBcnJheSh0cmFuc2Zvcm1zWzBdKSlcbiAgICAgICAgPyBhcnJheU1hcCh0cmFuc2Zvcm1zWzBdLCBiYXNlVW5hcnkoZ2V0SXRlcmF0ZWUoKSkpXG4gICAgICAgIDogYXJyYXlNYXAoYmFzZUZsYXR0ZW4odHJhbnNmb3JtcywgMSksIGJhc2VVbmFyeShnZXRJdGVyYXRlZSgpKSk7XG5cbiAgICAgIHZhciBmdW5jc0xlbmd0aCA9IHRyYW5zZm9ybXMubGVuZ3RoO1xuICAgICAgcmV0dXJuIGJhc2VSZXN0KGZ1bmN0aW9uKGFyZ3MpIHtcbiAgICAgICAgdmFyIGluZGV4ID0gLTEsXG4gICAgICAgICAgICBsZW5ndGggPSBuYXRpdmVNaW4oYXJncy5sZW5ndGgsIGZ1bmNzTGVuZ3RoKTtcblxuICAgICAgICB3aGlsZSAoKytpbmRleCA8IGxlbmd0aCkge1xuICAgICAgICAgIGFyZ3NbaW5kZXhdID0gdHJhbnNmb3Jtc1tpbmRleF0uY2FsbCh0aGlzLCBhcmdzW2luZGV4XSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGFwcGx5KGZ1bmMsIHRoaXMsIGFyZ3MpO1xuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgZnVuY3Rpb24gdGhhdCBpbnZva2VzIGBmdW5jYCB3aXRoIGBwYXJ0aWFsc2AgcHJlcGVuZGVkIHRvIHRoZVxuICAgICAqIGFyZ3VtZW50cyBpdCByZWNlaXZlcy4gVGhpcyBtZXRob2QgaXMgbGlrZSBgXy5iaW5kYCBleGNlcHQgaXQgZG9lcyAqKm5vdCoqXG4gICAgICogYWx0ZXIgdGhlIGB0aGlzYCBiaW5kaW5nLlxuICAgICAqXG4gICAgICogVGhlIGBfLnBhcnRpYWwucGxhY2Vob2xkZXJgIHZhbHVlLCB3aGljaCBkZWZhdWx0cyB0byBgX2AgaW4gbW9ub2xpdGhpY1xuICAgICAqIGJ1aWxkcywgbWF5IGJlIHVzZWQgYXMgYSBwbGFjZWhvbGRlciBmb3IgcGFydGlhbGx5IGFwcGxpZWQgYXJndW1lbnRzLlxuICAgICAqXG4gICAgICogKipOb3RlOioqIFRoaXMgbWV0aG9kIGRvZXNuJ3Qgc2V0IHRoZSBcImxlbmd0aFwiIHByb3BlcnR5IG9mIHBhcnRpYWxseVxuICAgICAqIGFwcGxpZWQgZnVuY3Rpb25zLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDAuMi4wXG4gICAgICogQGNhdGVnb3J5IEZ1bmN0aW9uXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gZnVuYyBUaGUgZnVuY3Rpb24gdG8gcGFydGlhbGx5IGFwcGx5IGFyZ3VtZW50cyB0by5cbiAgICAgKiBAcGFyYW0gey4uLip9IFtwYXJ0aWFsc10gVGhlIGFyZ3VtZW50cyB0byBiZSBwYXJ0aWFsbHkgYXBwbGllZC5cbiAgICAgKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyBwYXJ0aWFsbHkgYXBwbGllZCBmdW5jdGlvbi5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogZnVuY3Rpb24gZ3JlZXQoZ3JlZXRpbmcsIG5hbWUpIHtcbiAgICAgKiAgIHJldHVybiBncmVldGluZyArICcgJyArIG5hbWU7XG4gICAgICogfVxuICAgICAqXG4gICAgICogdmFyIHNheUhlbGxvVG8gPSBfLnBhcnRpYWwoZ3JlZXQsICdoZWxsbycpO1xuICAgICAqIHNheUhlbGxvVG8oJ2ZyZWQnKTtcbiAgICAgKiAvLyA9PiAnaGVsbG8gZnJlZCdcbiAgICAgKlxuICAgICAqIC8vIFBhcnRpYWxseSBhcHBsaWVkIHdpdGggcGxhY2Vob2xkZXJzLlxuICAgICAqIHZhciBncmVldEZyZWQgPSBfLnBhcnRpYWwoZ3JlZXQsIF8sICdmcmVkJyk7XG4gICAgICogZ3JlZXRGcmVkKCdoaScpO1xuICAgICAqIC8vID0+ICdoaSBmcmVkJ1xuICAgICAqL1xuICAgIHZhciBwYXJ0aWFsID0gYmFzZVJlc3QoZnVuY3Rpb24oZnVuYywgcGFydGlhbHMpIHtcbiAgICAgIHZhciBob2xkZXJzID0gcmVwbGFjZUhvbGRlcnMocGFydGlhbHMsIGdldEhvbGRlcihwYXJ0aWFsKSk7XG4gICAgICByZXR1cm4gY3JlYXRlV3JhcChmdW5jLCBXUkFQX1BBUlRJQUxfRkxBRywgdW5kZWZpbmVkLCBwYXJ0aWFscywgaG9sZGVycyk7XG4gICAgfSk7XG5cbiAgICAvKipcbiAgICAgKiBUaGlzIG1ldGhvZCBpcyBsaWtlIGBfLnBhcnRpYWxgIGV4Y2VwdCB0aGF0IHBhcnRpYWxseSBhcHBsaWVkIGFyZ3VtZW50c1xuICAgICAqIGFyZSBhcHBlbmRlZCB0byB0aGUgYXJndW1lbnRzIGl0IHJlY2VpdmVzLlxuICAgICAqXG4gICAgICogVGhlIGBfLnBhcnRpYWxSaWdodC5wbGFjZWhvbGRlcmAgdmFsdWUsIHdoaWNoIGRlZmF1bHRzIHRvIGBfYCBpbiBtb25vbGl0aGljXG4gICAgICogYnVpbGRzLCBtYXkgYmUgdXNlZCBhcyBhIHBsYWNlaG9sZGVyIGZvciBwYXJ0aWFsbHkgYXBwbGllZCBhcmd1bWVudHMuXG4gICAgICpcbiAgICAgKiAqKk5vdGU6KiogVGhpcyBtZXRob2QgZG9lc24ndCBzZXQgdGhlIFwibGVuZ3RoXCIgcHJvcGVydHkgb2YgcGFydGlhbGx5XG4gICAgICogYXBwbGllZCBmdW5jdGlvbnMuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMS4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgRnVuY3Rpb25cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBmdW5jIFRoZSBmdW5jdGlvbiB0byBwYXJ0aWFsbHkgYXBwbHkgYXJndW1lbnRzIHRvLlxuICAgICAqIEBwYXJhbSB7Li4uKn0gW3BhcnRpYWxzXSBUaGUgYXJndW1lbnRzIHRvIGJlIHBhcnRpYWxseSBhcHBsaWVkLlxuICAgICAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyB0aGUgbmV3IHBhcnRpYWxseSBhcHBsaWVkIGZ1bmN0aW9uLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBmdW5jdGlvbiBncmVldChncmVldGluZywgbmFtZSkge1xuICAgICAqICAgcmV0dXJuIGdyZWV0aW5nICsgJyAnICsgbmFtZTtcbiAgICAgKiB9XG4gICAgICpcbiAgICAgKiB2YXIgZ3JlZXRGcmVkID0gXy5wYXJ0aWFsUmlnaHQoZ3JlZXQsICdmcmVkJyk7XG4gICAgICogZ3JlZXRGcmVkKCdoaScpO1xuICAgICAqIC8vID0+ICdoaSBmcmVkJ1xuICAgICAqXG4gICAgICogLy8gUGFydGlhbGx5IGFwcGxpZWQgd2l0aCBwbGFjZWhvbGRlcnMuXG4gICAgICogdmFyIHNheUhlbGxvVG8gPSBfLnBhcnRpYWxSaWdodChncmVldCwgJ2hlbGxvJywgXyk7XG4gICAgICogc2F5SGVsbG9UbygnZnJlZCcpO1xuICAgICAqIC8vID0+ICdoZWxsbyBmcmVkJ1xuICAgICAqL1xuICAgIHZhciBwYXJ0aWFsUmlnaHQgPSBiYXNlUmVzdChmdW5jdGlvbihmdW5jLCBwYXJ0aWFscykge1xuICAgICAgdmFyIGhvbGRlcnMgPSByZXBsYWNlSG9sZGVycyhwYXJ0aWFscywgZ2V0SG9sZGVyKHBhcnRpYWxSaWdodCkpO1xuICAgICAgcmV0dXJuIGNyZWF0ZVdyYXAoZnVuYywgV1JBUF9QQVJUSUFMX1JJR0hUX0ZMQUcsIHVuZGVmaW5lZCwgcGFydGlhbHMsIGhvbGRlcnMpO1xuICAgIH0pO1xuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIGZ1bmN0aW9uIHRoYXQgaW52b2tlcyBgZnVuY2Agd2l0aCBhcmd1bWVudHMgYXJyYW5nZWQgYWNjb3JkaW5nXG4gICAgICogdG8gdGhlIHNwZWNpZmllZCBgaW5kZXhlc2Agd2hlcmUgdGhlIGFyZ3VtZW50IHZhbHVlIGF0IHRoZSBmaXJzdCBpbmRleCBpc1xuICAgICAqIHByb3ZpZGVkIGFzIHRoZSBmaXJzdCBhcmd1bWVudCwgdGhlIGFyZ3VtZW50IHZhbHVlIGF0IHRoZSBzZWNvbmQgaW5kZXggaXNcbiAgICAgKiBwcm92aWRlZCBhcyB0aGUgc2Vjb25kIGFyZ3VtZW50LCBhbmQgc28gb24uXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMy4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgRnVuY3Rpb25cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBmdW5jIFRoZSBmdW5jdGlvbiB0byByZWFycmFuZ2UgYXJndW1lbnRzIGZvci5cbiAgICAgKiBAcGFyYW0gey4uLihudW1iZXJ8bnVtYmVyW10pfSBpbmRleGVzIFRoZSBhcnJhbmdlZCBhcmd1bWVudCBpbmRleGVzLlxuICAgICAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyB0aGUgbmV3IGZ1bmN0aW9uLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiB2YXIgcmVhcmdlZCA9IF8ucmVhcmcoZnVuY3Rpb24oYSwgYiwgYykge1xuICAgICAqICAgcmV0dXJuIFthLCBiLCBjXTtcbiAgICAgKiB9LCBbMiwgMCwgMV0pO1xuICAgICAqXG4gICAgICogcmVhcmdlZCgnYicsICdjJywgJ2EnKVxuICAgICAqIC8vID0+IFsnYScsICdiJywgJ2MnXVxuICAgICAqL1xuICAgIHZhciByZWFyZyA9IGZsYXRSZXN0KGZ1bmN0aW9uKGZ1bmMsIGluZGV4ZXMpIHtcbiAgICAgIHJldHVybiBjcmVhdGVXcmFwKGZ1bmMsIFdSQVBfUkVBUkdfRkxBRywgdW5kZWZpbmVkLCB1bmRlZmluZWQsIHVuZGVmaW5lZCwgaW5kZXhlcyk7XG4gICAgfSk7XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgZnVuY3Rpb24gdGhhdCBpbnZva2VzIGBmdW5jYCB3aXRoIHRoZSBgdGhpc2AgYmluZGluZyBvZiB0aGVcbiAgICAgKiBjcmVhdGVkIGZ1bmN0aW9uIGFuZCBhcmd1bWVudHMgZnJvbSBgc3RhcnRgIGFuZCBiZXlvbmQgcHJvdmlkZWQgYXNcbiAgICAgKiBhbiBhcnJheS5cbiAgICAgKlxuICAgICAqICoqTm90ZToqKiBUaGlzIG1ldGhvZCBpcyBiYXNlZCBvbiB0aGVcbiAgICAgKiBbcmVzdCBwYXJhbWV0ZXJdKGh0dHBzOi8vbWRuLmlvL3Jlc3RfcGFyYW1ldGVycykuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgNC4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgRnVuY3Rpb25cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBmdW5jIFRoZSBmdW5jdGlvbiB0byBhcHBseSBhIHJlc3QgcGFyYW1ldGVyIHRvLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbc3RhcnQ9ZnVuYy5sZW5ndGgtMV0gVGhlIHN0YXJ0IHBvc2l0aW9uIG9mIHRoZSByZXN0IHBhcmFtZXRlci5cbiAgICAgKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyBmdW5jdGlvbi5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogdmFyIHNheSA9IF8ucmVzdChmdW5jdGlvbih3aGF0LCBuYW1lcykge1xuICAgICAqICAgcmV0dXJuIHdoYXQgKyAnICcgKyBfLmluaXRpYWwobmFtZXMpLmpvaW4oJywgJykgK1xuICAgICAqICAgICAoXy5zaXplKG5hbWVzKSA+IDEgPyAnLCAmICcgOiAnJykgKyBfLmxhc3QobmFtZXMpO1xuICAgICAqIH0pO1xuICAgICAqXG4gICAgICogc2F5KCdoZWxsbycsICdmcmVkJywgJ2Jhcm5leScsICdwZWJibGVzJyk7XG4gICAgICogLy8gPT4gJ2hlbGxvIGZyZWQsIGJhcm5leSwgJiBwZWJibGVzJ1xuICAgICAqL1xuICAgIGZ1bmN0aW9uIHJlc3QoZnVuYywgc3RhcnQpIHtcbiAgICAgIGlmICh0eXBlb2YgZnVuYyAhPSAnZnVuY3Rpb24nKSB7XG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoRlVOQ19FUlJPUl9URVhUKTtcbiAgICAgIH1cbiAgICAgIHN0YXJ0ID0gc3RhcnQgPT09IHVuZGVmaW5lZCA/IHN0YXJ0IDogdG9JbnRlZ2VyKHN0YXJ0KTtcbiAgICAgIHJldHVybiBiYXNlUmVzdChmdW5jLCBzdGFydCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIGZ1bmN0aW9uIHRoYXQgaW52b2tlcyBgZnVuY2Agd2l0aCB0aGUgYHRoaXNgIGJpbmRpbmcgb2YgdGhlXG4gICAgICogY3JlYXRlIGZ1bmN0aW9uIGFuZCBhbiBhcnJheSBvZiBhcmd1bWVudHMgbXVjaCBsaWtlXG4gICAgICogW2BGdW5jdGlvbiNhcHBseWBdKGh0dHA6Ly93d3cuZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi83LjAvI3NlYy1mdW5jdGlvbi5wcm90b3R5cGUuYXBwbHkpLlxuICAgICAqXG4gICAgICogKipOb3RlOioqIFRoaXMgbWV0aG9kIGlzIGJhc2VkIG9uIHRoZVxuICAgICAqIFtzcHJlYWQgb3BlcmF0b3JdKGh0dHBzOi8vbWRuLmlvL3NwcmVhZF9vcGVyYXRvcikuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMy4yLjBcbiAgICAgKiBAY2F0ZWdvcnkgRnVuY3Rpb25cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBmdW5jIFRoZSBmdW5jdGlvbiB0byBzcHJlYWQgYXJndW1lbnRzIG92ZXIuXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IFtzdGFydD0wXSBUaGUgc3RhcnQgcG9zaXRpb24gb2YgdGhlIHNwcmVhZC5cbiAgICAgKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyBmdW5jdGlvbi5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogdmFyIHNheSA9IF8uc3ByZWFkKGZ1bmN0aW9uKHdobywgd2hhdCkge1xuICAgICAqICAgcmV0dXJuIHdobyArICcgc2F5cyAnICsgd2hhdDtcbiAgICAgKiB9KTtcbiAgICAgKlxuICAgICAqIHNheShbJ2ZyZWQnLCAnaGVsbG8nXSk7XG4gICAgICogLy8gPT4gJ2ZyZWQgc2F5cyBoZWxsbydcbiAgICAgKlxuICAgICAqIHZhciBudW1iZXJzID0gUHJvbWlzZS5hbGwoW1xuICAgICAqICAgUHJvbWlzZS5yZXNvbHZlKDQwKSxcbiAgICAgKiAgIFByb21pc2UucmVzb2x2ZSgzNilcbiAgICAgKiBdKTtcbiAgICAgKlxuICAgICAqIG51bWJlcnMudGhlbihfLnNwcmVhZChmdW5jdGlvbih4LCB5KSB7XG4gICAgICogICByZXR1cm4geCArIHk7XG4gICAgICogfSkpO1xuICAgICAqIC8vID0+IGEgUHJvbWlzZSBvZiA3NlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIHNwcmVhZChmdW5jLCBzdGFydCkge1xuICAgICAgaWYgKHR5cGVvZiBmdW5jICE9ICdmdW5jdGlvbicpIHtcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihGVU5DX0VSUk9SX1RFWFQpO1xuICAgICAgfVxuICAgICAgc3RhcnQgPSBzdGFydCA9PSBudWxsID8gMCA6IG5hdGl2ZU1heCh0b0ludGVnZXIoc3RhcnQpLCAwKTtcbiAgICAgIHJldHVybiBiYXNlUmVzdChmdW5jdGlvbihhcmdzKSB7XG4gICAgICAgIHZhciBhcnJheSA9IGFyZ3Nbc3RhcnRdLFxuICAgICAgICAgICAgb3RoZXJBcmdzID0gY2FzdFNsaWNlKGFyZ3MsIDAsIHN0YXJ0KTtcblxuICAgICAgICBpZiAoYXJyYXkpIHtcbiAgICAgICAgICBhcnJheVB1c2gob3RoZXJBcmdzLCBhcnJheSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGFwcGx5KGZ1bmMsIHRoaXMsIG90aGVyQXJncyk7XG4gICAgICB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgdGhyb3R0bGVkIGZ1bmN0aW9uIHRoYXQgb25seSBpbnZva2VzIGBmdW5jYCBhdCBtb3N0IG9uY2UgcGVyXG4gICAgICogZXZlcnkgYHdhaXRgIG1pbGxpc2Vjb25kcy4gVGhlIHRocm90dGxlZCBmdW5jdGlvbiBjb21lcyB3aXRoIGEgYGNhbmNlbGBcbiAgICAgKiBtZXRob2QgdG8gY2FuY2VsIGRlbGF5ZWQgYGZ1bmNgIGludm9jYXRpb25zIGFuZCBhIGBmbHVzaGAgbWV0aG9kIHRvXG4gICAgICogaW1tZWRpYXRlbHkgaW52b2tlIHRoZW0uIFByb3ZpZGUgYG9wdGlvbnNgIHRvIGluZGljYXRlIHdoZXRoZXIgYGZ1bmNgXG4gICAgICogc2hvdWxkIGJlIGludm9rZWQgb24gdGhlIGxlYWRpbmcgYW5kL29yIHRyYWlsaW5nIGVkZ2Ugb2YgdGhlIGB3YWl0YFxuICAgICAqIHRpbWVvdXQuIFRoZSBgZnVuY2AgaXMgaW52b2tlZCB3aXRoIHRoZSBsYXN0IGFyZ3VtZW50cyBwcm92aWRlZCB0byB0aGVcbiAgICAgKiB0aHJvdHRsZWQgZnVuY3Rpb24uIFN1YnNlcXVlbnQgY2FsbHMgdG8gdGhlIHRocm90dGxlZCBmdW5jdGlvbiByZXR1cm4gdGhlXG4gICAgICogcmVzdWx0IG9mIHRoZSBsYXN0IGBmdW5jYCBpbnZvY2F0aW9uLlxuICAgICAqXG4gICAgICogKipOb3RlOioqIElmIGBsZWFkaW5nYCBhbmQgYHRyYWlsaW5nYCBvcHRpb25zIGFyZSBgdHJ1ZWAsIGBmdW5jYCBpc1xuICAgICAqIGludm9rZWQgb24gdGhlIHRyYWlsaW5nIGVkZ2Ugb2YgdGhlIHRpbWVvdXQgb25seSBpZiB0aGUgdGhyb3R0bGVkIGZ1bmN0aW9uXG4gICAgICogaXMgaW52b2tlZCBtb3JlIHRoYW4gb25jZSBkdXJpbmcgdGhlIGB3YWl0YCB0aW1lb3V0LlxuICAgICAqXG4gICAgICogSWYgYHdhaXRgIGlzIGAwYCBhbmQgYGxlYWRpbmdgIGlzIGBmYWxzZWAsIGBmdW5jYCBpbnZvY2F0aW9uIGlzIGRlZmVycmVkXG4gICAgICogdW50aWwgdG8gdGhlIG5leHQgdGljaywgc2ltaWxhciB0byBgc2V0VGltZW91dGAgd2l0aCBhIHRpbWVvdXQgb2YgYDBgLlxuICAgICAqXG4gICAgICogU2VlIFtEYXZpZCBDb3JiYWNobydzIGFydGljbGVdKGh0dHBzOi8vY3NzLXRyaWNrcy5jb20vZGVib3VuY2luZy10aHJvdHRsaW5nLWV4cGxhaW5lZC1leGFtcGxlcy8pXG4gICAgICogZm9yIGRldGFpbHMgb3ZlciB0aGUgZGlmZmVyZW5jZXMgYmV0d2VlbiBgXy50aHJvdHRsZWAgYW5kIGBfLmRlYm91bmNlYC5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAwLjEuMFxuICAgICAqIEBjYXRlZ29yeSBGdW5jdGlvblxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IGZ1bmMgVGhlIGZ1bmN0aW9uIHRvIHRocm90dGxlLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbd2FpdD0wXSBUaGUgbnVtYmVyIG9mIG1pbGxpc2Vjb25kcyB0byB0aHJvdHRsZSBpbnZvY2F0aW9ucyB0by5cbiAgICAgKiBAcGFyYW0ge09iamVjdH0gW29wdGlvbnM9e31dIFRoZSBvcHRpb25zIG9iamVjdC5cbiAgICAgKiBAcGFyYW0ge2Jvb2xlYW59IFtvcHRpb25zLmxlYWRpbmc9dHJ1ZV1cbiAgICAgKiAgU3BlY2lmeSBpbnZva2luZyBvbiB0aGUgbGVhZGluZyBlZGdlIG9mIHRoZSB0aW1lb3V0LlxuICAgICAqIEBwYXJhbSB7Ym9vbGVhbn0gW29wdGlvbnMudHJhaWxpbmc9dHJ1ZV1cbiAgICAgKiAgU3BlY2lmeSBpbnZva2luZyBvbiB0aGUgdHJhaWxpbmcgZWRnZSBvZiB0aGUgdGltZW91dC5cbiAgICAgKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyB0aHJvdHRsZWQgZnVuY3Rpb24uXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIC8vIEF2b2lkIGV4Y2Vzc2l2ZWx5IHVwZGF0aW5nIHRoZSBwb3NpdGlvbiB3aGlsZSBzY3JvbGxpbmcuXG4gICAgICogalF1ZXJ5KHdpbmRvdykub24oJ3Njcm9sbCcsIF8udGhyb3R0bGUodXBkYXRlUG9zaXRpb24sIDEwMCkpO1xuICAgICAqXG4gICAgICogLy8gSW52b2tlIGByZW5ld1Rva2VuYCB3aGVuIHRoZSBjbGljayBldmVudCBpcyBmaXJlZCwgYnV0IG5vdCBtb3JlIHRoYW4gb25jZSBldmVyeSA1IG1pbnV0ZXMuXG4gICAgICogdmFyIHRocm90dGxlZCA9IF8udGhyb3R0bGUocmVuZXdUb2tlbiwgMzAwMDAwLCB7ICd0cmFpbGluZyc6IGZhbHNlIH0pO1xuICAgICAqIGpRdWVyeShlbGVtZW50KS5vbignY2xpY2snLCB0aHJvdHRsZWQpO1xuICAgICAqXG4gICAgICogLy8gQ2FuY2VsIHRoZSB0cmFpbGluZyB0aHJvdHRsZWQgaW52b2NhdGlvbi5cbiAgICAgKiBqUXVlcnkod2luZG93KS5vbigncG9wc3RhdGUnLCB0aHJvdHRsZWQuY2FuY2VsKTtcbiAgICAgKi9cbiAgICBmdW5jdGlvbiB0aHJvdHRsZShmdW5jLCB3YWl0LCBvcHRpb25zKSB7XG4gICAgICB2YXIgbGVhZGluZyA9IHRydWUsXG4gICAgICAgICAgdHJhaWxpbmcgPSB0cnVlO1xuXG4gICAgICBpZiAodHlwZW9mIGZ1bmMgIT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKEZVTkNfRVJST1JfVEVYVCk7XG4gICAgICB9XG4gICAgICBpZiAoaXNPYmplY3Qob3B0aW9ucykpIHtcbiAgICAgICAgbGVhZGluZyA9ICdsZWFkaW5nJyBpbiBvcHRpb25zID8gISFvcHRpb25zLmxlYWRpbmcgOiBsZWFkaW5nO1xuICAgICAgICB0cmFpbGluZyA9ICd0cmFpbGluZycgaW4gb3B0aW9ucyA/ICEhb3B0aW9ucy50cmFpbGluZyA6IHRyYWlsaW5nO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGRlYm91bmNlKGZ1bmMsIHdhaXQsIHtcbiAgICAgICAgJ2xlYWRpbmcnOiBsZWFkaW5nLFxuICAgICAgICAnbWF4V2FpdCc6IHdhaXQsXG4gICAgICAgICd0cmFpbGluZyc6IHRyYWlsaW5nXG4gICAgICB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgZnVuY3Rpb24gdGhhdCBhY2NlcHRzIHVwIHRvIG9uZSBhcmd1bWVudCwgaWdub3JpbmcgYW55XG4gICAgICogYWRkaXRpb25hbCBhcmd1bWVudHMuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgNC4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgRnVuY3Rpb25cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBmdW5jIFRoZSBmdW5jdGlvbiB0byBjYXAgYXJndW1lbnRzIGZvci5cbiAgICAgKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyBjYXBwZWQgZnVuY3Rpb24uXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8ubWFwKFsnNicsICc4JywgJzEwJ10sIF8udW5hcnkocGFyc2VJbnQpKTtcbiAgICAgKiAvLyA9PiBbNiwgOCwgMTBdXG4gICAgICovXG4gICAgZnVuY3Rpb24gdW5hcnkoZnVuYykge1xuICAgICAgcmV0dXJuIGFyeShmdW5jLCAxKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgZnVuY3Rpb24gdGhhdCBwcm92aWRlcyBgdmFsdWVgIHRvIGB3cmFwcGVyYCBhcyBpdHMgZmlyc3RcbiAgICAgKiBhcmd1bWVudC4gQW55IGFkZGl0aW9uYWwgYXJndW1lbnRzIHByb3ZpZGVkIHRvIHRoZSBmdW5jdGlvbiBhcmUgYXBwZW5kZWRcbiAgICAgKiB0byB0aG9zZSBwcm92aWRlZCB0byB0aGUgYHdyYXBwZXJgLiBUaGUgd3JhcHBlciBpcyBpbnZva2VkIHdpdGggdGhlIGB0aGlzYFxuICAgICAqIGJpbmRpbmcgb2YgdGhlIGNyZWF0ZWQgZnVuY3Rpb24uXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMC4xLjBcbiAgICAgKiBAY2F0ZWdvcnkgRnVuY3Rpb25cbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byB3cmFwLlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IFt3cmFwcGVyPWlkZW50aXR5XSBUaGUgd3JhcHBlciBmdW5jdGlvbi5cbiAgICAgKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyBmdW5jdGlvbi5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogdmFyIHAgPSBfLndyYXAoXy5lc2NhcGUsIGZ1bmN0aW9uKGZ1bmMsIHRleHQpIHtcbiAgICAgKiAgIHJldHVybiAnPHA+JyArIGZ1bmModGV4dCkgKyAnPC9wPic7XG4gICAgICogfSk7XG4gICAgICpcbiAgICAgKiBwKCdmcmVkLCBiYXJuZXksICYgcGViYmxlcycpO1xuICAgICAqIC8vID0+ICc8cD5mcmVkLCBiYXJuZXksICZhbXA7IHBlYmJsZXM8L3A+J1xuICAgICAqL1xuICAgIGZ1bmN0aW9uIHdyYXAodmFsdWUsIHdyYXBwZXIpIHtcbiAgICAgIHJldHVybiBwYXJ0aWFsKGNhc3RGdW5jdGlvbih3cmFwcGVyKSwgdmFsdWUpO1xuICAgIH1cblxuICAgIC8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi9cblxuICAgIC8qKlxuICAgICAqIENhc3RzIGB2YWx1ZWAgYXMgYW4gYXJyYXkgaWYgaXQncyBub3Qgb25lLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDQuNC4wXG4gICAgICogQGNhdGVnb3J5IExhbmdcbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBpbnNwZWN0LlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgY2FzdCBhcnJheS5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy5jYXN0QXJyYXkoMSk7XG4gICAgICogLy8gPT4gWzFdXG4gICAgICpcbiAgICAgKiBfLmNhc3RBcnJheSh7ICdhJzogMSB9KTtcbiAgICAgKiAvLyA9PiBbeyAnYSc6IDEgfV1cbiAgICAgKlxuICAgICAqIF8uY2FzdEFycmF5KCdhYmMnKTtcbiAgICAgKiAvLyA9PiBbJ2FiYyddXG4gICAgICpcbiAgICAgKiBfLmNhc3RBcnJheShudWxsKTtcbiAgICAgKiAvLyA9PiBbbnVsbF1cbiAgICAgKlxuICAgICAqIF8uY2FzdEFycmF5KHVuZGVmaW5lZCk7XG4gICAgICogLy8gPT4gW3VuZGVmaW5lZF1cbiAgICAgKlxuICAgICAqIF8uY2FzdEFycmF5KCk7XG4gICAgICogLy8gPT4gW11cbiAgICAgKlxuICAgICAqIHZhciBhcnJheSA9IFsxLCAyLCAzXTtcbiAgICAgKiBjb25zb2xlLmxvZyhfLmNhc3RBcnJheShhcnJheSkgPT09IGFycmF5KTtcbiAgICAgKiAvLyA9PiB0cnVlXG4gICAgICovXG4gICAgZnVuY3Rpb24gY2FzdEFycmF5KCkge1xuICAgICAgaWYgKCFhcmd1bWVudHMubGVuZ3RoKSB7XG4gICAgICAgIHJldHVybiBbXTtcbiAgICAgIH1cbiAgICAgIHZhciB2YWx1ZSA9IGFyZ3VtZW50c1swXTtcbiAgICAgIHJldHVybiBpc0FycmF5KHZhbHVlKSA/IHZhbHVlIDogW3ZhbHVlXTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgc2hhbGxvdyBjbG9uZSBvZiBgdmFsdWVgLlxuICAgICAqXG4gICAgICogKipOb3RlOioqIFRoaXMgbWV0aG9kIGlzIGxvb3NlbHkgYmFzZWQgb24gdGhlXG4gICAgICogW3N0cnVjdHVyZWQgY2xvbmUgYWxnb3JpdGhtXShodHRwczovL21kbi5pby9TdHJ1Y3R1cmVkX2Nsb25lX2FsZ29yaXRobSlcbiAgICAgKiBhbmQgc3VwcG9ydHMgY2xvbmluZyBhcnJheXMsIGFycmF5IGJ1ZmZlcnMsIGJvb2xlYW5zLCBkYXRlIG9iamVjdHMsIG1hcHMsXG4gICAgICogbnVtYmVycywgYE9iamVjdGAgb2JqZWN0cywgcmVnZXhlcywgc2V0cywgc3RyaW5ncywgc3ltYm9scywgYW5kIHR5cGVkXG4gICAgICogYXJyYXlzLiBUaGUgb3duIGVudW1lcmFibGUgcHJvcGVydGllcyBvZiBgYXJndW1lbnRzYCBvYmplY3RzIGFyZSBjbG9uZWRcbiAgICAgKiBhcyBwbGFpbiBvYmplY3RzLiBBbiBlbXB0eSBvYmplY3QgaXMgcmV0dXJuZWQgZm9yIHVuY2xvbmVhYmxlIHZhbHVlcyBzdWNoXG4gICAgICogYXMgZXJyb3Igb2JqZWN0cywgZnVuY3Rpb25zLCBET00gbm9kZXMsIGFuZCBXZWFrTWFwcy5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAwLjEuMFxuICAgICAqIEBjYXRlZ29yeSBMYW5nXG4gICAgICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY2xvbmUuXG4gICAgICogQHJldHVybnMgeyp9IFJldHVybnMgdGhlIGNsb25lZCB2YWx1ZS5cbiAgICAgKiBAc2VlIF8uY2xvbmVEZWVwXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIHZhciBvYmplY3RzID0gW3sgJ2EnOiAxIH0sIHsgJ2InOiAyIH1dO1xuICAgICAqXG4gICAgICogdmFyIHNoYWxsb3cgPSBfLmNsb25lKG9iamVjdHMpO1xuICAgICAqIGNvbnNvbGUubG9nKHNoYWxsb3dbMF0gPT09IG9iamVjdHNbMF0pO1xuICAgICAqIC8vID0+IHRydWVcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBjbG9uZSh2YWx1ZSkge1xuICAgICAgcmV0dXJuIGJhc2VDbG9uZSh2YWx1ZSwgQ0xPTkVfU1lNQk9MU19GTEFHKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGlzIG1ldGhvZCBpcyBsaWtlIGBfLmNsb25lYCBleGNlcHQgdGhhdCBpdCBhY2NlcHRzIGBjdXN0b21pemVyYCB3aGljaFxuICAgICAqIGlzIGludm9rZWQgdG8gcHJvZHVjZSB0aGUgY2xvbmVkIHZhbHVlLiBJZiBgY3VzdG9taXplcmAgcmV0dXJucyBgdW5kZWZpbmVkYCxcbiAgICAgKiBjbG9uaW5nIGlzIGhhbmRsZWQgYnkgdGhlIG1ldGhvZCBpbnN0ZWFkLiBUaGUgYGN1c3RvbWl6ZXJgIGlzIGludm9rZWQgd2l0aFxuICAgICAqIHVwIHRvIGZvdXIgYXJndW1lbnRzOyAodmFsdWUgWywgaW5kZXh8a2V5LCBvYmplY3QsIHN0YWNrXSkuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgNC4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgTGFuZ1xuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNsb25lLlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IFtjdXN0b21pemVyXSBUaGUgZnVuY3Rpb24gdG8gY3VzdG9taXplIGNsb25pbmcuXG4gICAgICogQHJldHVybnMgeyp9IFJldHVybnMgdGhlIGNsb25lZCB2YWx1ZS5cbiAgICAgKiBAc2VlIF8uY2xvbmVEZWVwV2l0aFxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBmdW5jdGlvbiBjdXN0b21pemVyKHZhbHVlKSB7XG4gICAgICogICBpZiAoXy5pc0VsZW1lbnQodmFsdWUpKSB7XG4gICAgICogICAgIHJldHVybiB2YWx1ZS5jbG9uZU5vZGUoZmFsc2UpO1xuICAgICAqICAgfVxuICAgICAqIH1cbiAgICAgKlxuICAgICAqIHZhciBlbCA9IF8uY2xvbmVXaXRoKGRvY3VtZW50LmJvZHksIGN1c3RvbWl6ZXIpO1xuICAgICAqXG4gICAgICogY29uc29sZS5sb2coZWwgPT09IGRvY3VtZW50LmJvZHkpO1xuICAgICAqIC8vID0+IGZhbHNlXG4gICAgICogY29uc29sZS5sb2coZWwubm9kZU5hbWUpO1xuICAgICAqIC8vID0+ICdCT0RZJ1xuICAgICAqIGNvbnNvbGUubG9nKGVsLmNoaWxkTm9kZXMubGVuZ3RoKTtcbiAgICAgKiAvLyA9PiAwXG4gICAgICovXG4gICAgZnVuY3Rpb24gY2xvbmVXaXRoKHZhbHVlLCBjdXN0b21pemVyKSB7XG4gICAgICBjdXN0b21pemVyID0gdHlwZW9mIGN1c3RvbWl6ZXIgPT0gJ2Z1bmN0aW9uJyA/IGN1c3RvbWl6ZXIgOiB1bmRlZmluZWQ7XG4gICAgICByZXR1cm4gYmFzZUNsb25lKHZhbHVlLCBDTE9ORV9TWU1CT0xTX0ZMQUcsIGN1c3RvbWl6ZXIpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoaXMgbWV0aG9kIGlzIGxpa2UgYF8uY2xvbmVgIGV4Y2VwdCB0aGF0IGl0IHJlY3Vyc2l2ZWx5IGNsb25lcyBgdmFsdWVgLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDEuMC4wXG4gICAgICogQGNhdGVnb3J5IExhbmdcbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byByZWN1cnNpdmVseSBjbG9uZS5cbiAgICAgKiBAcmV0dXJucyB7Kn0gUmV0dXJucyB0aGUgZGVlcCBjbG9uZWQgdmFsdWUuXG4gICAgICogQHNlZSBfLmNsb25lXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIHZhciBvYmplY3RzID0gW3sgJ2EnOiAxIH0sIHsgJ2InOiAyIH1dO1xuICAgICAqXG4gICAgICogdmFyIGRlZXAgPSBfLmNsb25lRGVlcChvYmplY3RzKTtcbiAgICAgKiBjb25zb2xlLmxvZyhkZWVwWzBdID09PSBvYmplY3RzWzBdKTtcbiAgICAgKiAvLyA9PiBmYWxzZVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGNsb25lRGVlcCh2YWx1ZSkge1xuICAgICAgcmV0dXJuIGJhc2VDbG9uZSh2YWx1ZSwgQ0xPTkVfREVFUF9GTEFHIHwgQ0xPTkVfU1lNQk9MU19GTEFHKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGlzIG1ldGhvZCBpcyBsaWtlIGBfLmNsb25lV2l0aGAgZXhjZXB0IHRoYXQgaXQgcmVjdXJzaXZlbHkgY2xvbmVzIGB2YWx1ZWAuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgNC4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgTGFuZ1xuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIHJlY3Vyc2l2ZWx5IGNsb25lLlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IFtjdXN0b21pemVyXSBUaGUgZnVuY3Rpb24gdG8gY3VzdG9taXplIGNsb25pbmcuXG4gICAgICogQHJldHVybnMgeyp9IFJldHVybnMgdGhlIGRlZXAgY2xvbmVkIHZhbHVlLlxuICAgICAqIEBzZWUgXy5jbG9uZVdpdGhcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogZnVuY3Rpb24gY3VzdG9taXplcih2YWx1ZSkge1xuICAgICAqICAgaWYgKF8uaXNFbGVtZW50KHZhbHVlKSkge1xuICAgICAqICAgICByZXR1cm4gdmFsdWUuY2xvbmVOb2RlKHRydWUpO1xuICAgICAqICAgfVxuICAgICAqIH1cbiAgICAgKlxuICAgICAqIHZhciBlbCA9IF8uY2xvbmVEZWVwV2l0aChkb2N1bWVudC5ib2R5LCBjdXN0b21pemVyKTtcbiAgICAgKlxuICAgICAqIGNvbnNvbGUubG9nKGVsID09PSBkb2N1bWVudC5ib2R5KTtcbiAgICAgKiAvLyA9PiBmYWxzZVxuICAgICAqIGNvbnNvbGUubG9nKGVsLm5vZGVOYW1lKTtcbiAgICAgKiAvLyA9PiAnQk9EWSdcbiAgICAgKiBjb25zb2xlLmxvZyhlbC5jaGlsZE5vZGVzLmxlbmd0aCk7XG4gICAgICogLy8gPT4gMjBcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBjbG9uZURlZXBXaXRoKHZhbHVlLCBjdXN0b21pemVyKSB7XG4gICAgICBjdXN0b21pemVyID0gdHlwZW9mIGN1c3RvbWl6ZXIgPT0gJ2Z1bmN0aW9uJyA/IGN1c3RvbWl6ZXIgOiB1bmRlZmluZWQ7XG4gICAgICByZXR1cm4gYmFzZUNsb25lKHZhbHVlLCBDTE9ORV9ERUVQX0ZMQUcgfCBDTE9ORV9TWU1CT0xTX0ZMQUcsIGN1c3RvbWl6ZXIpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENoZWNrcyBpZiBgb2JqZWN0YCBjb25mb3JtcyB0byBgc291cmNlYCBieSBpbnZva2luZyB0aGUgcHJlZGljYXRlXG4gICAgICogcHJvcGVydGllcyBvZiBgc291cmNlYCB3aXRoIHRoZSBjb3JyZXNwb25kaW5nIHByb3BlcnR5IHZhbHVlcyBvZiBgb2JqZWN0YC5cbiAgICAgKlxuICAgICAqICoqTm90ZToqKiBUaGlzIG1ldGhvZCBpcyBlcXVpdmFsZW50IHRvIGBfLmNvbmZvcm1zYCB3aGVuIGBzb3VyY2VgIGlzXG4gICAgICogcGFydGlhbGx5IGFwcGxpZWQuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgNC4xNC4wXG4gICAgICogQGNhdGVnb3J5IExhbmdcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gaW5zcGVjdC5cbiAgICAgKiBAcGFyYW0ge09iamVjdH0gc291cmNlIFRoZSBvYmplY3Qgb2YgcHJvcGVydHkgcHJlZGljYXRlcyB0byBjb25mb3JtIHRvLlxuICAgICAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgb2JqZWN0YCBjb25mb3JtcywgZWxzZSBgZmFsc2VgLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiB2YXIgb2JqZWN0ID0geyAnYSc6IDEsICdiJzogMiB9O1xuICAgICAqXG4gICAgICogXy5jb25mb3Jtc1RvKG9iamVjdCwgeyAnYic6IGZ1bmN0aW9uKG4pIHsgcmV0dXJuIG4gPiAxOyB9IH0pO1xuICAgICAqIC8vID0+IHRydWVcbiAgICAgKlxuICAgICAqIF8uY29uZm9ybXNUbyhvYmplY3QsIHsgJ2InOiBmdW5jdGlvbihuKSB7IHJldHVybiBuID4gMjsgfSB9KTtcbiAgICAgKiAvLyA9PiBmYWxzZVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGNvbmZvcm1zVG8ob2JqZWN0LCBzb3VyY2UpIHtcbiAgICAgIHJldHVybiBzb3VyY2UgPT0gbnVsbCB8fCBiYXNlQ29uZm9ybXNUbyhvYmplY3QsIHNvdXJjZSwga2V5cyhzb3VyY2UpKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBQZXJmb3JtcyBhXG4gICAgICogW2BTYW1lVmFsdWVaZXJvYF0oaHR0cDovL2VjbWEtaW50ZXJuYXRpb25hbC5vcmcvZWNtYS0yNjIvNy4wLyNzZWMtc2FtZXZhbHVlemVybylcbiAgICAgKiBjb21wYXJpc29uIGJldHdlZW4gdHdvIHZhbHVlcyB0byBkZXRlcm1pbmUgaWYgdGhleSBhcmUgZXF1aXZhbGVudC5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSA0LjAuMFxuICAgICAqIEBjYXRlZ29yeSBMYW5nXG4gICAgICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY29tcGFyZS5cbiAgICAgKiBAcGFyYW0geyp9IG90aGVyIFRoZSBvdGhlciB2YWx1ZSB0byBjb21wYXJlLlxuICAgICAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiB0aGUgdmFsdWVzIGFyZSBlcXVpdmFsZW50LCBlbHNlIGBmYWxzZWAuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIHZhciBvYmplY3QgPSB7ICdhJzogMSB9O1xuICAgICAqIHZhciBvdGhlciA9IHsgJ2EnOiAxIH07XG4gICAgICpcbiAgICAgKiBfLmVxKG9iamVjdCwgb2JqZWN0KTtcbiAgICAgKiAvLyA9PiB0cnVlXG4gICAgICpcbiAgICAgKiBfLmVxKG9iamVjdCwgb3RoZXIpO1xuICAgICAqIC8vID0+IGZhbHNlXG4gICAgICpcbiAgICAgKiBfLmVxKCdhJywgJ2EnKTtcbiAgICAgKiAvLyA9PiB0cnVlXG4gICAgICpcbiAgICAgKiBfLmVxKCdhJywgT2JqZWN0KCdhJykpO1xuICAgICAqIC8vID0+IGZhbHNlXG4gICAgICpcbiAgICAgKiBfLmVxKE5hTiwgTmFOKTtcbiAgICAgKiAvLyA9PiB0cnVlXG4gICAgICovXG4gICAgZnVuY3Rpb24gZXEodmFsdWUsIG90aGVyKSB7XG4gICAgICByZXR1cm4gdmFsdWUgPT09IG90aGVyIHx8ICh2YWx1ZSAhPT0gdmFsdWUgJiYgb3RoZXIgIT09IG90aGVyKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDaGVja3MgaWYgYHZhbHVlYCBpcyBncmVhdGVyIHRoYW4gYG90aGVyYC5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAzLjkuMFxuICAgICAqIEBjYXRlZ29yeSBMYW5nXG4gICAgICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY29tcGFyZS5cbiAgICAgKiBAcGFyYW0geyp9IG90aGVyIFRoZSBvdGhlciB2YWx1ZSB0byBjb21wYXJlLlxuICAgICAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlzIGdyZWF0ZXIgdGhhbiBgb3RoZXJgLFxuICAgICAqICBlbHNlIGBmYWxzZWAuXG4gICAgICogQHNlZSBfLmx0XG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8uZ3QoMywgMSk7XG4gICAgICogLy8gPT4gdHJ1ZVxuICAgICAqXG4gICAgICogXy5ndCgzLCAzKTtcbiAgICAgKiAvLyA9PiBmYWxzZVxuICAgICAqXG4gICAgICogXy5ndCgxLCAzKTtcbiAgICAgKiAvLyA9PiBmYWxzZVxuICAgICAqL1xuICAgIHZhciBndCA9IGNyZWF0ZVJlbGF0aW9uYWxPcGVyYXRpb24oYmFzZUd0KTtcblxuICAgIC8qKlxuICAgICAqIENoZWNrcyBpZiBgdmFsdWVgIGlzIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byBgb3RoZXJgLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDMuOS4wXG4gICAgICogQGNhdGVnb3J5IExhbmdcbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjb21wYXJlLlxuICAgICAqIEBwYXJhbSB7Kn0gb3RoZXIgVGhlIG90aGVyIHZhbHVlIHRvIGNvbXBhcmUuXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGB2YWx1ZWAgaXMgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvXG4gICAgICogIGBvdGhlcmAsIGVsc2UgYGZhbHNlYC5cbiAgICAgKiBAc2VlIF8ubHRlXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8uZ3RlKDMsIDEpO1xuICAgICAqIC8vID0+IHRydWVcbiAgICAgKlxuICAgICAqIF8uZ3RlKDMsIDMpO1xuICAgICAqIC8vID0+IHRydWVcbiAgICAgKlxuICAgICAqIF8uZ3RlKDEsIDMpO1xuICAgICAqIC8vID0+IGZhbHNlXG4gICAgICovXG4gICAgdmFyIGd0ZSA9IGNyZWF0ZVJlbGF0aW9uYWxPcGVyYXRpb24oZnVuY3Rpb24odmFsdWUsIG90aGVyKSB7XG4gICAgICByZXR1cm4gdmFsdWUgPj0gb3RoZXI7XG4gICAgfSk7XG5cbiAgICAvKipcbiAgICAgKiBDaGVja3MgaWYgYHZhbHVlYCBpcyBsaWtlbHkgYW4gYGFyZ3VtZW50c2Agb2JqZWN0LlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDAuMS4wXG4gICAgICogQGNhdGVnb3J5IExhbmdcbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjaGVjay5cbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBhbiBgYXJndW1lbnRzYCBvYmplY3QsXG4gICAgICogIGVsc2UgYGZhbHNlYC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy5pc0FyZ3VtZW50cyhmdW5jdGlvbigpIHsgcmV0dXJuIGFyZ3VtZW50czsgfSgpKTtcbiAgICAgKiAvLyA9PiB0cnVlXG4gICAgICpcbiAgICAgKiBfLmlzQXJndW1lbnRzKFsxLCAyLCAzXSk7XG4gICAgICogLy8gPT4gZmFsc2VcbiAgICAgKi9cbiAgICB2YXIgaXNBcmd1bWVudHMgPSBiYXNlSXNBcmd1bWVudHMoZnVuY3Rpb24oKSB7IHJldHVybiBhcmd1bWVudHM7IH0oKSkgPyBiYXNlSXNBcmd1bWVudHMgOiBmdW5jdGlvbih2YWx1ZSkge1xuICAgICAgcmV0dXJuIGlzT2JqZWN0TGlrZSh2YWx1ZSkgJiYgaGFzT3duUHJvcGVydHkuY2FsbCh2YWx1ZSwgJ2NhbGxlZScpICYmXG4gICAgICAgICFwcm9wZXJ0eUlzRW51bWVyYWJsZS5jYWxsKHZhbHVlLCAnY2FsbGVlJyk7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIENoZWNrcyBpZiBgdmFsdWVgIGlzIGNsYXNzaWZpZWQgYXMgYW4gYEFycmF5YCBvYmplY3QuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMC4xLjBcbiAgICAgKiBAY2F0ZWdvcnkgTGFuZ1xuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrLlxuICAgICAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlzIGFuIGFycmF5LCBlbHNlIGBmYWxzZWAuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8uaXNBcnJheShbMSwgMiwgM10pO1xuICAgICAqIC8vID0+IHRydWVcbiAgICAgKlxuICAgICAqIF8uaXNBcnJheShkb2N1bWVudC5ib2R5LmNoaWxkcmVuKTtcbiAgICAgKiAvLyA9PiBmYWxzZVxuICAgICAqXG4gICAgICogXy5pc0FycmF5KCdhYmMnKTtcbiAgICAgKiAvLyA9PiBmYWxzZVxuICAgICAqXG4gICAgICogXy5pc0FycmF5KF8ubm9vcCk7XG4gICAgICogLy8gPT4gZmFsc2VcbiAgICAgKi9cbiAgICB2YXIgaXNBcnJheSA9IEFycmF5LmlzQXJyYXk7XG5cbiAgICAvKipcbiAgICAgKiBDaGVja3MgaWYgYHZhbHVlYCBpcyBjbGFzc2lmaWVkIGFzIGFuIGBBcnJheUJ1ZmZlcmAgb2JqZWN0LlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDQuMy4wXG4gICAgICogQGNhdGVnb3J5IExhbmdcbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjaGVjay5cbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBhbiBhcnJheSBidWZmZXIsIGVsc2UgYGZhbHNlYC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy5pc0FycmF5QnVmZmVyKG5ldyBBcnJheUJ1ZmZlcigyKSk7XG4gICAgICogLy8gPT4gdHJ1ZVxuICAgICAqXG4gICAgICogXy5pc0FycmF5QnVmZmVyKG5ldyBBcnJheSgyKSk7XG4gICAgICogLy8gPT4gZmFsc2VcbiAgICAgKi9cbiAgICB2YXIgaXNBcnJheUJ1ZmZlciA9IG5vZGVJc0FycmF5QnVmZmVyID8gYmFzZVVuYXJ5KG5vZGVJc0FycmF5QnVmZmVyKSA6IGJhc2VJc0FycmF5QnVmZmVyO1xuXG4gICAgLyoqXG4gICAgICogQ2hlY2tzIGlmIGB2YWx1ZWAgaXMgYXJyYXktbGlrZS4gQSB2YWx1ZSBpcyBjb25zaWRlcmVkIGFycmF5LWxpa2UgaWYgaXQnc1xuICAgICAqIG5vdCBhIGZ1bmN0aW9uIGFuZCBoYXMgYSBgdmFsdWUubGVuZ3RoYCB0aGF0J3MgYW4gaW50ZWdlciBncmVhdGVyIHRoYW4gb3JcbiAgICAgKiBlcXVhbCB0byBgMGAgYW5kIGxlc3MgdGhhbiBvciBlcXVhbCB0byBgTnVtYmVyLk1BWF9TQUZFX0lOVEVHRVJgLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDQuMC4wXG4gICAgICogQGNhdGVnb3J5IExhbmdcbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjaGVjay5cbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBhcnJheS1saWtlLCBlbHNlIGBmYWxzZWAuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8uaXNBcnJheUxpa2UoWzEsIDIsIDNdKTtcbiAgICAgKiAvLyA9PiB0cnVlXG4gICAgICpcbiAgICAgKiBfLmlzQXJyYXlMaWtlKGRvY3VtZW50LmJvZHkuY2hpbGRyZW4pO1xuICAgICAqIC8vID0+IHRydWVcbiAgICAgKlxuICAgICAqIF8uaXNBcnJheUxpa2UoJ2FiYycpO1xuICAgICAqIC8vID0+IHRydWVcbiAgICAgKlxuICAgICAqIF8uaXNBcnJheUxpa2UoXy5ub29wKTtcbiAgICAgKiAvLyA9PiBmYWxzZVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGlzQXJyYXlMaWtlKHZhbHVlKSB7XG4gICAgICByZXR1cm4gdmFsdWUgIT0gbnVsbCAmJiBpc0xlbmd0aCh2YWx1ZS5sZW5ndGgpICYmICFpc0Z1bmN0aW9uKHZhbHVlKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGlzIG1ldGhvZCBpcyBsaWtlIGBfLmlzQXJyYXlMaWtlYCBleGNlcHQgdGhhdCBpdCBhbHNvIGNoZWNrcyBpZiBgdmFsdWVgXG4gICAgICogaXMgYW4gb2JqZWN0LlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDQuMC4wXG4gICAgICogQGNhdGVnb3J5IExhbmdcbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjaGVjay5cbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBhbiBhcnJheS1saWtlIG9iamVjdCxcbiAgICAgKiAgZWxzZSBgZmFsc2VgLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLmlzQXJyYXlMaWtlT2JqZWN0KFsxLCAyLCAzXSk7XG4gICAgICogLy8gPT4gdHJ1ZVxuICAgICAqXG4gICAgICogXy5pc0FycmF5TGlrZU9iamVjdChkb2N1bWVudC5ib2R5LmNoaWxkcmVuKTtcbiAgICAgKiAvLyA9PiB0cnVlXG4gICAgICpcbiAgICAgKiBfLmlzQXJyYXlMaWtlT2JqZWN0KCdhYmMnKTtcbiAgICAgKiAvLyA9PiBmYWxzZVxuICAgICAqXG4gICAgICogXy5pc0FycmF5TGlrZU9iamVjdChfLm5vb3ApO1xuICAgICAqIC8vID0+IGZhbHNlXG4gICAgICovXG4gICAgZnVuY3Rpb24gaXNBcnJheUxpa2VPYmplY3QodmFsdWUpIHtcbiAgICAgIHJldHVybiBpc09iamVjdExpa2UodmFsdWUpICYmIGlzQXJyYXlMaWtlKHZhbHVlKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDaGVja3MgaWYgYHZhbHVlYCBpcyBjbGFzc2lmaWVkIGFzIGEgYm9vbGVhbiBwcmltaXRpdmUgb3Igb2JqZWN0LlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDAuMS4wXG4gICAgICogQGNhdGVnb3J5IExhbmdcbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjaGVjay5cbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBhIGJvb2xlYW4sIGVsc2UgYGZhbHNlYC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy5pc0Jvb2xlYW4oZmFsc2UpO1xuICAgICAqIC8vID0+IHRydWVcbiAgICAgKlxuICAgICAqIF8uaXNCb29sZWFuKG51bGwpO1xuICAgICAqIC8vID0+IGZhbHNlXG4gICAgICovXG4gICAgZnVuY3Rpb24gaXNCb29sZWFuKHZhbHVlKSB7XG4gICAgICByZXR1cm4gdmFsdWUgPT09IHRydWUgfHwgdmFsdWUgPT09IGZhbHNlIHx8XG4gICAgICAgIChpc09iamVjdExpa2UodmFsdWUpICYmIGJhc2VHZXRUYWcodmFsdWUpID09IGJvb2xUYWcpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENoZWNrcyBpZiBgdmFsdWVgIGlzIGEgYnVmZmVyLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDQuMy4wXG4gICAgICogQGNhdGVnb3J5IExhbmdcbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjaGVjay5cbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBhIGJ1ZmZlciwgZWxzZSBgZmFsc2VgLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLmlzQnVmZmVyKG5ldyBCdWZmZXIoMikpO1xuICAgICAqIC8vID0+IHRydWVcbiAgICAgKlxuICAgICAqIF8uaXNCdWZmZXIobmV3IFVpbnQ4QXJyYXkoMikpO1xuICAgICAqIC8vID0+IGZhbHNlXG4gICAgICovXG4gICAgdmFyIGlzQnVmZmVyID0gbmF0aXZlSXNCdWZmZXIgfHwgc3R1YkZhbHNlO1xuXG4gICAgLyoqXG4gICAgICogQ2hlY2tzIGlmIGB2YWx1ZWAgaXMgY2xhc3NpZmllZCBhcyBhIGBEYXRlYCBvYmplY3QuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMC4xLjBcbiAgICAgKiBAY2F0ZWdvcnkgTGFuZ1xuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrLlxuICAgICAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlzIGEgZGF0ZSBvYmplY3QsIGVsc2UgYGZhbHNlYC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy5pc0RhdGUobmV3IERhdGUpO1xuICAgICAqIC8vID0+IHRydWVcbiAgICAgKlxuICAgICAqIF8uaXNEYXRlKCdNb24gQXByaWwgMjMgMjAxMicpO1xuICAgICAqIC8vID0+IGZhbHNlXG4gICAgICovXG4gICAgdmFyIGlzRGF0ZSA9IG5vZGVJc0RhdGUgPyBiYXNlVW5hcnkobm9kZUlzRGF0ZSkgOiBiYXNlSXNEYXRlO1xuXG4gICAgLyoqXG4gICAgICogQ2hlY2tzIGlmIGB2YWx1ZWAgaXMgbGlrZWx5IGEgRE9NIGVsZW1lbnQuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMC4xLjBcbiAgICAgKiBAY2F0ZWdvcnkgTGFuZ1xuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrLlxuICAgICAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlzIGEgRE9NIGVsZW1lbnQsIGVsc2UgYGZhbHNlYC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy5pc0VsZW1lbnQoZG9jdW1lbnQuYm9keSk7XG4gICAgICogLy8gPT4gdHJ1ZVxuICAgICAqXG4gICAgICogXy5pc0VsZW1lbnQoJzxib2R5PicpO1xuICAgICAqIC8vID0+IGZhbHNlXG4gICAgICovXG4gICAgZnVuY3Rpb24gaXNFbGVtZW50KHZhbHVlKSB7XG4gICAgICByZXR1cm4gaXNPYmplY3RMaWtlKHZhbHVlKSAmJiB2YWx1ZS5ub2RlVHlwZSA9PT0gMSAmJiAhaXNQbGFpbk9iamVjdCh2YWx1ZSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ2hlY2tzIGlmIGB2YWx1ZWAgaXMgYW4gZW1wdHkgb2JqZWN0LCBjb2xsZWN0aW9uLCBtYXAsIG9yIHNldC5cbiAgICAgKlxuICAgICAqIE9iamVjdHMgYXJlIGNvbnNpZGVyZWQgZW1wdHkgaWYgdGhleSBoYXZlIG5vIG93biBlbnVtZXJhYmxlIHN0cmluZyBrZXllZFxuICAgICAqIHByb3BlcnRpZXMuXG4gICAgICpcbiAgICAgKiBBcnJheS1saWtlIHZhbHVlcyBzdWNoIGFzIGBhcmd1bWVudHNgIG9iamVjdHMsIGFycmF5cywgYnVmZmVycywgc3RyaW5ncywgb3JcbiAgICAgKiBqUXVlcnktbGlrZSBjb2xsZWN0aW9ucyBhcmUgY29uc2lkZXJlZCBlbXB0eSBpZiB0aGV5IGhhdmUgYSBgbGVuZ3RoYCBvZiBgMGAuXG4gICAgICogU2ltaWxhcmx5LCBtYXBzIGFuZCBzZXRzIGFyZSBjb25zaWRlcmVkIGVtcHR5IGlmIHRoZXkgaGF2ZSBhIGBzaXplYCBvZiBgMGAuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMC4xLjBcbiAgICAgKiBAY2F0ZWdvcnkgTGFuZ1xuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrLlxuICAgICAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlzIGVtcHR5LCBlbHNlIGBmYWxzZWAuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8uaXNFbXB0eShudWxsKTtcbiAgICAgKiAvLyA9PiB0cnVlXG4gICAgICpcbiAgICAgKiBfLmlzRW1wdHkodHJ1ZSk7XG4gICAgICogLy8gPT4gdHJ1ZVxuICAgICAqXG4gICAgICogXy5pc0VtcHR5KDEpO1xuICAgICAqIC8vID0+IHRydWVcbiAgICAgKlxuICAgICAqIF8uaXNFbXB0eShbMSwgMiwgM10pO1xuICAgICAqIC8vID0+IGZhbHNlXG4gICAgICpcbiAgICAgKiBfLmlzRW1wdHkoeyAnYSc6IDEgfSk7XG4gICAgICogLy8gPT4gZmFsc2VcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBpc0VtcHR5KHZhbHVlKSB7XG4gICAgICBpZiAodmFsdWUgPT0gbnVsbCkge1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgIH1cbiAgICAgIGlmIChpc0FycmF5TGlrZSh2YWx1ZSkgJiZcbiAgICAgICAgICAoaXNBcnJheSh2YWx1ZSkgfHwgdHlwZW9mIHZhbHVlID09ICdzdHJpbmcnIHx8IHR5cGVvZiB2YWx1ZS5zcGxpY2UgPT0gJ2Z1bmN0aW9uJyB8fFxuICAgICAgICAgICAgaXNCdWZmZXIodmFsdWUpIHx8IGlzVHlwZWRBcnJheSh2YWx1ZSkgfHwgaXNBcmd1bWVudHModmFsdWUpKSkge1xuICAgICAgICByZXR1cm4gIXZhbHVlLmxlbmd0aDtcbiAgICAgIH1cbiAgICAgIHZhciB0YWcgPSBnZXRUYWcodmFsdWUpO1xuICAgICAgaWYgKHRhZyA9PSBtYXBUYWcgfHwgdGFnID09IHNldFRhZykge1xuICAgICAgICByZXR1cm4gIXZhbHVlLnNpemU7XG4gICAgICB9XG4gICAgICBpZiAoaXNQcm90b3R5cGUodmFsdWUpKSB7XG4gICAgICAgIHJldHVybiAhYmFzZUtleXModmFsdWUpLmxlbmd0aDtcbiAgICAgIH1cbiAgICAgIGZvciAodmFyIGtleSBpbiB2YWx1ZSkge1xuICAgICAgICBpZiAoaGFzT3duUHJvcGVydHkuY2FsbCh2YWx1ZSwga2V5KSkge1xuICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUGVyZm9ybXMgYSBkZWVwIGNvbXBhcmlzb24gYmV0d2VlbiB0d28gdmFsdWVzIHRvIGRldGVybWluZSBpZiB0aGV5IGFyZVxuICAgICAqIGVxdWl2YWxlbnQuXG4gICAgICpcbiAgICAgKiAqKk5vdGU6KiogVGhpcyBtZXRob2Qgc3VwcG9ydHMgY29tcGFyaW5nIGFycmF5cywgYXJyYXkgYnVmZmVycywgYm9vbGVhbnMsXG4gICAgICogZGF0ZSBvYmplY3RzLCBlcnJvciBvYmplY3RzLCBtYXBzLCBudW1iZXJzLCBgT2JqZWN0YCBvYmplY3RzLCByZWdleGVzLFxuICAgICAqIHNldHMsIHN0cmluZ3MsIHN5bWJvbHMsIGFuZCB0eXBlZCBhcnJheXMuIGBPYmplY3RgIG9iamVjdHMgYXJlIGNvbXBhcmVkXG4gICAgICogYnkgdGhlaXIgb3duLCBub3QgaW5oZXJpdGVkLCBlbnVtZXJhYmxlIHByb3BlcnRpZXMuIEZ1bmN0aW9ucyBhbmQgRE9NXG4gICAgICogbm9kZXMgYXJlIGNvbXBhcmVkIGJ5IHN0cmljdCBlcXVhbGl0eSwgaS5lLiBgPT09YC5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAwLjEuMFxuICAgICAqIEBjYXRlZ29yeSBMYW5nXG4gICAgICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY29tcGFyZS5cbiAgICAgKiBAcGFyYW0geyp9IG90aGVyIFRoZSBvdGhlciB2YWx1ZSB0byBjb21wYXJlLlxuICAgICAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiB0aGUgdmFsdWVzIGFyZSBlcXVpdmFsZW50LCBlbHNlIGBmYWxzZWAuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIHZhciBvYmplY3QgPSB7ICdhJzogMSB9O1xuICAgICAqIHZhciBvdGhlciA9IHsgJ2EnOiAxIH07XG4gICAgICpcbiAgICAgKiBfLmlzRXF1YWwob2JqZWN0LCBvdGhlcik7XG4gICAgICogLy8gPT4gdHJ1ZVxuICAgICAqXG4gICAgICogb2JqZWN0ID09PSBvdGhlcjtcbiAgICAgKiAvLyA9PiBmYWxzZVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGlzRXF1YWwodmFsdWUsIG90aGVyKSB7XG4gICAgICByZXR1cm4gYmFzZUlzRXF1YWwodmFsdWUsIG90aGVyKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGlzIG1ldGhvZCBpcyBsaWtlIGBfLmlzRXF1YWxgIGV4Y2VwdCB0aGF0IGl0IGFjY2VwdHMgYGN1c3RvbWl6ZXJgIHdoaWNoXG4gICAgICogaXMgaW52b2tlZCB0byBjb21wYXJlIHZhbHVlcy4gSWYgYGN1c3RvbWl6ZXJgIHJldHVybnMgYHVuZGVmaW5lZGAsIGNvbXBhcmlzb25zXG4gICAgICogYXJlIGhhbmRsZWQgYnkgdGhlIG1ldGhvZCBpbnN0ZWFkLiBUaGUgYGN1c3RvbWl6ZXJgIGlzIGludm9rZWQgd2l0aCB1cCB0b1xuICAgICAqIHNpeCBhcmd1bWVudHM6IChvYmpWYWx1ZSwgb3RoVmFsdWUgWywgaW5kZXh8a2V5LCBvYmplY3QsIG90aGVyLCBzdGFja10pLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDQuMC4wXG4gICAgICogQGNhdGVnb3J5IExhbmdcbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjb21wYXJlLlxuICAgICAqIEBwYXJhbSB7Kn0gb3RoZXIgVGhlIG90aGVyIHZhbHVlIHRvIGNvbXBhcmUuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gW2N1c3RvbWl6ZXJdIFRoZSBmdW5jdGlvbiB0byBjdXN0b21pemUgY29tcGFyaXNvbnMuXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIHRoZSB2YWx1ZXMgYXJlIGVxdWl2YWxlbnQsIGVsc2UgYGZhbHNlYC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogZnVuY3Rpb24gaXNHcmVldGluZyh2YWx1ZSkge1xuICAgICAqICAgcmV0dXJuIC9eaCg/Oml8ZWxsbykkLy50ZXN0KHZhbHVlKTtcbiAgICAgKiB9XG4gICAgICpcbiAgICAgKiBmdW5jdGlvbiBjdXN0b21pemVyKG9ialZhbHVlLCBvdGhWYWx1ZSkge1xuICAgICAqICAgaWYgKGlzR3JlZXRpbmcob2JqVmFsdWUpICYmIGlzR3JlZXRpbmcob3RoVmFsdWUpKSB7XG4gICAgICogICAgIHJldHVybiB0cnVlO1xuICAgICAqICAgfVxuICAgICAqIH1cbiAgICAgKlxuICAgICAqIHZhciBhcnJheSA9IFsnaGVsbG8nLCAnZ29vZGJ5ZSddO1xuICAgICAqIHZhciBvdGhlciA9IFsnaGknLCAnZ29vZGJ5ZSddO1xuICAgICAqXG4gICAgICogXy5pc0VxdWFsV2l0aChhcnJheSwgb3RoZXIsIGN1c3RvbWl6ZXIpO1xuICAgICAqIC8vID0+IHRydWVcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBpc0VxdWFsV2l0aCh2YWx1ZSwgb3RoZXIsIGN1c3RvbWl6ZXIpIHtcbiAgICAgIGN1c3RvbWl6ZXIgPSB0eXBlb2YgY3VzdG9taXplciA9PSAnZnVuY3Rpb24nID8gY3VzdG9taXplciA6IHVuZGVmaW5lZDtcbiAgICAgIHZhciByZXN1bHQgPSBjdXN0b21pemVyID8gY3VzdG9taXplcih2YWx1ZSwgb3RoZXIpIDogdW5kZWZpbmVkO1xuICAgICAgcmV0dXJuIHJlc3VsdCA9PT0gdW5kZWZpbmVkID8gYmFzZUlzRXF1YWwodmFsdWUsIG90aGVyLCB1bmRlZmluZWQsIGN1c3RvbWl6ZXIpIDogISFyZXN1bHQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ2hlY2tzIGlmIGB2YWx1ZWAgaXMgYW4gYEVycm9yYCwgYEV2YWxFcnJvcmAsIGBSYW5nZUVycm9yYCwgYFJlZmVyZW5jZUVycm9yYCxcbiAgICAgKiBgU3ludGF4RXJyb3JgLCBgVHlwZUVycm9yYCwgb3IgYFVSSUVycm9yYCBvYmplY3QuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMy4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgTGFuZ1xuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrLlxuICAgICAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlzIGFuIGVycm9yIG9iamVjdCwgZWxzZSBgZmFsc2VgLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLmlzRXJyb3IobmV3IEVycm9yKTtcbiAgICAgKiAvLyA9PiB0cnVlXG4gICAgICpcbiAgICAgKiBfLmlzRXJyb3IoRXJyb3IpO1xuICAgICAqIC8vID0+IGZhbHNlXG4gICAgICovXG4gICAgZnVuY3Rpb24gaXNFcnJvcih2YWx1ZSkge1xuICAgICAgaWYgKCFpc09iamVjdExpa2UodmFsdWUpKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cbiAgICAgIHZhciB0YWcgPSBiYXNlR2V0VGFnKHZhbHVlKTtcbiAgICAgIHJldHVybiB0YWcgPT0gZXJyb3JUYWcgfHwgdGFnID09IGRvbUV4Y1RhZyB8fFxuICAgICAgICAodHlwZW9mIHZhbHVlLm1lc3NhZ2UgPT0gJ3N0cmluZycgJiYgdHlwZW9mIHZhbHVlLm5hbWUgPT0gJ3N0cmluZycgJiYgIWlzUGxhaW5PYmplY3QodmFsdWUpKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDaGVja3MgaWYgYHZhbHVlYCBpcyBhIGZpbml0ZSBwcmltaXRpdmUgbnVtYmVyLlxuICAgICAqXG4gICAgICogKipOb3RlOioqIFRoaXMgbWV0aG9kIGlzIGJhc2VkIG9uXG4gICAgICogW2BOdW1iZXIuaXNGaW5pdGVgXShodHRwczovL21kbi5pby9OdW1iZXIvaXNGaW5pdGUpLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDAuMS4wXG4gICAgICogQGNhdGVnb3J5IExhbmdcbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjaGVjay5cbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBhIGZpbml0ZSBudW1iZXIsIGVsc2UgYGZhbHNlYC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy5pc0Zpbml0ZSgzKTtcbiAgICAgKiAvLyA9PiB0cnVlXG4gICAgICpcbiAgICAgKiBfLmlzRmluaXRlKE51bWJlci5NSU5fVkFMVUUpO1xuICAgICAqIC8vID0+IHRydWVcbiAgICAgKlxuICAgICAqIF8uaXNGaW5pdGUoSW5maW5pdHkpO1xuICAgICAqIC8vID0+IGZhbHNlXG4gICAgICpcbiAgICAgKiBfLmlzRmluaXRlKCczJyk7XG4gICAgICogLy8gPT4gZmFsc2VcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBpc0Zpbml0ZSh2YWx1ZSkge1xuICAgICAgcmV0dXJuIHR5cGVvZiB2YWx1ZSA9PSAnbnVtYmVyJyAmJiBuYXRpdmVJc0Zpbml0ZSh2YWx1ZSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ2hlY2tzIGlmIGB2YWx1ZWAgaXMgY2xhc3NpZmllZCBhcyBhIGBGdW5jdGlvbmAgb2JqZWN0LlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDAuMS4wXG4gICAgICogQGNhdGVnb3J5IExhbmdcbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjaGVjay5cbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBhIGZ1bmN0aW9uLCBlbHNlIGBmYWxzZWAuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8uaXNGdW5jdGlvbihfKTtcbiAgICAgKiAvLyA9PiB0cnVlXG4gICAgICpcbiAgICAgKiBfLmlzRnVuY3Rpb24oL2FiYy8pO1xuICAgICAqIC8vID0+IGZhbHNlXG4gICAgICovXG4gICAgZnVuY3Rpb24gaXNGdW5jdGlvbih2YWx1ZSkge1xuICAgICAgaWYgKCFpc09iamVjdCh2YWx1ZSkpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuICAgICAgLy8gVGhlIHVzZSBvZiBgT2JqZWN0I3RvU3RyaW5nYCBhdm9pZHMgaXNzdWVzIHdpdGggdGhlIGB0eXBlb2ZgIG9wZXJhdG9yXG4gICAgICAvLyBpbiBTYWZhcmkgOSB3aGljaCByZXR1cm5zICdvYmplY3QnIGZvciB0eXBlZCBhcnJheXMgYW5kIG90aGVyIGNvbnN0cnVjdG9ycy5cbiAgICAgIHZhciB0YWcgPSBiYXNlR2V0VGFnKHZhbHVlKTtcbiAgICAgIHJldHVybiB0YWcgPT0gZnVuY1RhZyB8fCB0YWcgPT0gZ2VuVGFnIHx8IHRhZyA9PSBhc3luY1RhZyB8fCB0YWcgPT0gcHJveHlUYWc7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ2hlY2tzIGlmIGB2YWx1ZWAgaXMgYW4gaW50ZWdlci5cbiAgICAgKlxuICAgICAqICoqTm90ZToqKiBUaGlzIG1ldGhvZCBpcyBiYXNlZCBvblxuICAgICAqIFtgTnVtYmVyLmlzSW50ZWdlcmBdKGh0dHBzOi8vbWRuLmlvL051bWJlci9pc0ludGVnZXIpLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDQuMC4wXG4gICAgICogQGNhdGVnb3J5IExhbmdcbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjaGVjay5cbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBhbiBpbnRlZ2VyLCBlbHNlIGBmYWxzZWAuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8uaXNJbnRlZ2VyKDMpO1xuICAgICAqIC8vID0+IHRydWVcbiAgICAgKlxuICAgICAqIF8uaXNJbnRlZ2VyKE51bWJlci5NSU5fVkFMVUUpO1xuICAgICAqIC8vID0+IGZhbHNlXG4gICAgICpcbiAgICAgKiBfLmlzSW50ZWdlcihJbmZpbml0eSk7XG4gICAgICogLy8gPT4gZmFsc2VcbiAgICAgKlxuICAgICAqIF8uaXNJbnRlZ2VyKCczJyk7XG4gICAgICogLy8gPT4gZmFsc2VcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBpc0ludGVnZXIodmFsdWUpIHtcbiAgICAgIHJldHVybiB0eXBlb2YgdmFsdWUgPT0gJ251bWJlcicgJiYgdmFsdWUgPT0gdG9JbnRlZ2VyKHZhbHVlKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDaGVja3MgaWYgYHZhbHVlYCBpcyBhIHZhbGlkIGFycmF5LWxpa2UgbGVuZ3RoLlxuICAgICAqXG4gICAgICogKipOb3RlOioqIFRoaXMgbWV0aG9kIGlzIGxvb3NlbHkgYmFzZWQgb25cbiAgICAgKiBbYFRvTGVuZ3RoYF0oaHR0cDovL2VjbWEtaW50ZXJuYXRpb25hbC5vcmcvZWNtYS0yNjIvNy4wLyNzZWMtdG9sZW5ndGgpLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDQuMC4wXG4gICAgICogQGNhdGVnb3J5IExhbmdcbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjaGVjay5cbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBhIHZhbGlkIGxlbmd0aCwgZWxzZSBgZmFsc2VgLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLmlzTGVuZ3RoKDMpO1xuICAgICAqIC8vID0+IHRydWVcbiAgICAgKlxuICAgICAqIF8uaXNMZW5ndGgoTnVtYmVyLk1JTl9WQUxVRSk7XG4gICAgICogLy8gPT4gZmFsc2VcbiAgICAgKlxuICAgICAqIF8uaXNMZW5ndGgoSW5maW5pdHkpO1xuICAgICAqIC8vID0+IGZhbHNlXG4gICAgICpcbiAgICAgKiBfLmlzTGVuZ3RoKCczJyk7XG4gICAgICogLy8gPT4gZmFsc2VcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBpc0xlbmd0aCh2YWx1ZSkge1xuICAgICAgcmV0dXJuIHR5cGVvZiB2YWx1ZSA9PSAnbnVtYmVyJyAmJlxuICAgICAgICB2YWx1ZSA+IC0xICYmIHZhbHVlICUgMSA9PSAwICYmIHZhbHVlIDw9IE1BWF9TQUZFX0lOVEVHRVI7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ2hlY2tzIGlmIGB2YWx1ZWAgaXMgdGhlXG4gICAgICogW2xhbmd1YWdlIHR5cGVdKGh0dHA6Ly93d3cuZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi83LjAvI3NlYy1lY21hc2NyaXB0LWxhbmd1YWdlLXR5cGVzKVxuICAgICAqIG9mIGBPYmplY3RgLiAoZS5nLiBhcnJheXMsIGZ1bmN0aW9ucywgb2JqZWN0cywgcmVnZXhlcywgYG5ldyBOdW1iZXIoMClgLCBhbmQgYG5ldyBTdHJpbmcoJycpYClcbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAwLjEuMFxuICAgICAqIEBjYXRlZ29yeSBMYW5nXG4gICAgICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY2hlY2suXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGB2YWx1ZWAgaXMgYW4gb2JqZWN0LCBlbHNlIGBmYWxzZWAuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8uaXNPYmplY3Qoe30pO1xuICAgICAqIC8vID0+IHRydWVcbiAgICAgKlxuICAgICAqIF8uaXNPYmplY3QoWzEsIDIsIDNdKTtcbiAgICAgKiAvLyA9PiB0cnVlXG4gICAgICpcbiAgICAgKiBfLmlzT2JqZWN0KF8ubm9vcCk7XG4gICAgICogLy8gPT4gdHJ1ZVxuICAgICAqXG4gICAgICogXy5pc09iamVjdChudWxsKTtcbiAgICAgKiAvLyA9PiBmYWxzZVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGlzT2JqZWN0KHZhbHVlKSB7XG4gICAgICB2YXIgdHlwZSA9IHR5cGVvZiB2YWx1ZTtcbiAgICAgIHJldHVybiB2YWx1ZSAhPSBudWxsICYmICh0eXBlID09ICdvYmplY3QnIHx8IHR5cGUgPT0gJ2Z1bmN0aW9uJyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ2hlY2tzIGlmIGB2YWx1ZWAgaXMgb2JqZWN0LWxpa2UuIEEgdmFsdWUgaXMgb2JqZWN0LWxpa2UgaWYgaXQncyBub3QgYG51bGxgXG4gICAgICogYW5kIGhhcyBhIGB0eXBlb2ZgIHJlc3VsdCBvZiBcIm9iamVjdFwiLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDQuMC4wXG4gICAgICogQGNhdGVnb3J5IExhbmdcbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjaGVjay5cbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBvYmplY3QtbGlrZSwgZWxzZSBgZmFsc2VgLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLmlzT2JqZWN0TGlrZSh7fSk7XG4gICAgICogLy8gPT4gdHJ1ZVxuICAgICAqXG4gICAgICogXy5pc09iamVjdExpa2UoWzEsIDIsIDNdKTtcbiAgICAgKiAvLyA9PiB0cnVlXG4gICAgICpcbiAgICAgKiBfLmlzT2JqZWN0TGlrZShfLm5vb3ApO1xuICAgICAqIC8vID0+IGZhbHNlXG4gICAgICpcbiAgICAgKiBfLmlzT2JqZWN0TGlrZShudWxsKTtcbiAgICAgKiAvLyA9PiBmYWxzZVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGlzT2JqZWN0TGlrZSh2YWx1ZSkge1xuICAgICAgcmV0dXJuIHZhbHVlICE9IG51bGwgJiYgdHlwZW9mIHZhbHVlID09ICdvYmplY3QnO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENoZWNrcyBpZiBgdmFsdWVgIGlzIGNsYXNzaWZpZWQgYXMgYSBgTWFwYCBvYmplY3QuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgNC4zLjBcbiAgICAgKiBAY2F0ZWdvcnkgTGFuZ1xuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrLlxuICAgICAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlzIGEgbWFwLCBlbHNlIGBmYWxzZWAuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8uaXNNYXAobmV3IE1hcCk7XG4gICAgICogLy8gPT4gdHJ1ZVxuICAgICAqXG4gICAgICogXy5pc01hcChuZXcgV2Vha01hcCk7XG4gICAgICogLy8gPT4gZmFsc2VcbiAgICAgKi9cbiAgICB2YXIgaXNNYXAgPSBub2RlSXNNYXAgPyBiYXNlVW5hcnkobm9kZUlzTWFwKSA6IGJhc2VJc01hcDtcblxuICAgIC8qKlxuICAgICAqIFBlcmZvcm1zIGEgcGFydGlhbCBkZWVwIGNvbXBhcmlzb24gYmV0d2VlbiBgb2JqZWN0YCBhbmQgYHNvdXJjZWAgdG9cbiAgICAgKiBkZXRlcm1pbmUgaWYgYG9iamVjdGAgY29udGFpbnMgZXF1aXZhbGVudCBwcm9wZXJ0eSB2YWx1ZXMuXG4gICAgICpcbiAgICAgKiAqKk5vdGU6KiogVGhpcyBtZXRob2QgaXMgZXF1aXZhbGVudCB0byBgXy5tYXRjaGVzYCB3aGVuIGBzb3VyY2VgIGlzXG4gICAgICogcGFydGlhbGx5IGFwcGxpZWQuXG4gICAgICpcbiAgICAgKiBQYXJ0aWFsIGNvbXBhcmlzb25zIHdpbGwgbWF0Y2ggZW1wdHkgYXJyYXkgYW5kIGVtcHR5IG9iamVjdCBgc291cmNlYFxuICAgICAqIHZhbHVlcyBhZ2FpbnN0IGFueSBhcnJheSBvciBvYmplY3QgdmFsdWUsIHJlc3BlY3RpdmVseS4gU2VlIGBfLmlzRXF1YWxgXG4gICAgICogZm9yIGEgbGlzdCBvZiBzdXBwb3J0ZWQgdmFsdWUgY29tcGFyaXNvbnMuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMy4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgTGFuZ1xuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBpbnNwZWN0LlxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBzb3VyY2UgVGhlIG9iamVjdCBvZiBwcm9wZXJ0eSB2YWx1ZXMgdG8gbWF0Y2guXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGBvYmplY3RgIGlzIGEgbWF0Y2gsIGVsc2UgYGZhbHNlYC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogdmFyIG9iamVjdCA9IHsgJ2EnOiAxLCAnYic6IDIgfTtcbiAgICAgKlxuICAgICAqIF8uaXNNYXRjaChvYmplY3QsIHsgJ2InOiAyIH0pO1xuICAgICAqIC8vID0+IHRydWVcbiAgICAgKlxuICAgICAqIF8uaXNNYXRjaChvYmplY3QsIHsgJ2InOiAxIH0pO1xuICAgICAqIC8vID0+IGZhbHNlXG4gICAgICovXG4gICAgZnVuY3Rpb24gaXNNYXRjaChvYmplY3QsIHNvdXJjZSkge1xuICAgICAgcmV0dXJuIG9iamVjdCA9PT0gc291cmNlIHx8IGJhc2VJc01hdGNoKG9iamVjdCwgc291cmNlLCBnZXRNYXRjaERhdGEoc291cmNlKSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhpcyBtZXRob2QgaXMgbGlrZSBgXy5pc01hdGNoYCBleGNlcHQgdGhhdCBpdCBhY2NlcHRzIGBjdXN0b21pemVyYCB3aGljaFxuICAgICAqIGlzIGludm9rZWQgdG8gY29tcGFyZSB2YWx1ZXMuIElmIGBjdXN0b21pemVyYCByZXR1cm5zIGB1bmRlZmluZWRgLCBjb21wYXJpc29uc1xuICAgICAqIGFyZSBoYW5kbGVkIGJ5IHRoZSBtZXRob2QgaW5zdGVhZC4gVGhlIGBjdXN0b21pemVyYCBpcyBpbnZva2VkIHdpdGggZml2ZVxuICAgICAqIGFyZ3VtZW50czogKG9ialZhbHVlLCBzcmNWYWx1ZSwgaW5kZXh8a2V5LCBvYmplY3QsIHNvdXJjZSkuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgNC4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgTGFuZ1xuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBpbnNwZWN0LlxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBzb3VyY2UgVGhlIG9iamVjdCBvZiBwcm9wZXJ0eSB2YWx1ZXMgdG8gbWF0Y2guXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gW2N1c3RvbWl6ZXJdIFRoZSBmdW5jdGlvbiB0byBjdXN0b21pemUgY29tcGFyaXNvbnMuXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGBvYmplY3RgIGlzIGEgbWF0Y2gsIGVsc2UgYGZhbHNlYC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogZnVuY3Rpb24gaXNHcmVldGluZyh2YWx1ZSkge1xuICAgICAqICAgcmV0dXJuIC9eaCg/Oml8ZWxsbykkLy50ZXN0KHZhbHVlKTtcbiAgICAgKiB9XG4gICAgICpcbiAgICAgKiBmdW5jdGlvbiBjdXN0b21pemVyKG9ialZhbHVlLCBzcmNWYWx1ZSkge1xuICAgICAqICAgaWYgKGlzR3JlZXRpbmcob2JqVmFsdWUpICYmIGlzR3JlZXRpbmcoc3JjVmFsdWUpKSB7XG4gICAgICogICAgIHJldHVybiB0cnVlO1xuICAgICAqICAgfVxuICAgICAqIH1cbiAgICAgKlxuICAgICAqIHZhciBvYmplY3QgPSB7ICdncmVldGluZyc6ICdoZWxsbycgfTtcbiAgICAgKiB2YXIgc291cmNlID0geyAnZ3JlZXRpbmcnOiAnaGknIH07XG4gICAgICpcbiAgICAgKiBfLmlzTWF0Y2hXaXRoKG9iamVjdCwgc291cmNlLCBjdXN0b21pemVyKTtcbiAgICAgKiAvLyA9PiB0cnVlXG4gICAgICovXG4gICAgZnVuY3Rpb24gaXNNYXRjaFdpdGgob2JqZWN0LCBzb3VyY2UsIGN1c3RvbWl6ZXIpIHtcbiAgICAgIGN1c3RvbWl6ZXIgPSB0eXBlb2YgY3VzdG9taXplciA9PSAnZnVuY3Rpb24nID8gY3VzdG9taXplciA6IHVuZGVmaW5lZDtcbiAgICAgIHJldHVybiBiYXNlSXNNYXRjaChvYmplY3QsIHNvdXJjZSwgZ2V0TWF0Y2hEYXRhKHNvdXJjZSksIGN1c3RvbWl6ZXIpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENoZWNrcyBpZiBgdmFsdWVgIGlzIGBOYU5gLlxuICAgICAqXG4gICAgICogKipOb3RlOioqIFRoaXMgbWV0aG9kIGlzIGJhc2VkIG9uXG4gICAgICogW2BOdW1iZXIuaXNOYU5gXShodHRwczovL21kbi5pby9OdW1iZXIvaXNOYU4pIGFuZCBpcyBub3QgdGhlIHNhbWUgYXNcbiAgICAgKiBnbG9iYWwgW2Bpc05hTmBdKGh0dHBzOi8vbWRuLmlvL2lzTmFOKSB3aGljaCByZXR1cm5zIGB0cnVlYCBmb3JcbiAgICAgKiBgdW5kZWZpbmVkYCBhbmQgb3RoZXIgbm9uLW51bWJlciB2YWx1ZXMuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMC4xLjBcbiAgICAgKiBAY2F0ZWdvcnkgTGFuZ1xuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrLlxuICAgICAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlzIGBOYU5gLCBlbHNlIGBmYWxzZWAuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8uaXNOYU4oTmFOKTtcbiAgICAgKiAvLyA9PiB0cnVlXG4gICAgICpcbiAgICAgKiBfLmlzTmFOKG5ldyBOdW1iZXIoTmFOKSk7XG4gICAgICogLy8gPT4gdHJ1ZVxuICAgICAqXG4gICAgICogaXNOYU4odW5kZWZpbmVkKTtcbiAgICAgKiAvLyA9PiB0cnVlXG4gICAgICpcbiAgICAgKiBfLmlzTmFOKHVuZGVmaW5lZCk7XG4gICAgICogLy8gPT4gZmFsc2VcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBpc05hTih2YWx1ZSkge1xuICAgICAgLy8gQW4gYE5hTmAgcHJpbWl0aXZlIGlzIHRoZSBvbmx5IHZhbHVlIHRoYXQgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi5cbiAgICAgIC8vIFBlcmZvcm0gdGhlIGB0b1N0cmluZ1RhZ2AgY2hlY2sgZmlyc3QgdG8gYXZvaWQgZXJyb3JzIHdpdGggc29tZVxuICAgICAgLy8gQWN0aXZlWCBvYmplY3RzIGluIElFLlxuICAgICAgcmV0dXJuIGlzTnVtYmVyKHZhbHVlKSAmJiB2YWx1ZSAhPSArdmFsdWU7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ2hlY2tzIGlmIGB2YWx1ZWAgaXMgYSBwcmlzdGluZSBuYXRpdmUgZnVuY3Rpb24uXG4gICAgICpcbiAgICAgKiAqKk5vdGU6KiogVGhpcyBtZXRob2QgY2FuJ3QgcmVsaWFibHkgZGV0ZWN0IG5hdGl2ZSBmdW5jdGlvbnMgaW4gdGhlIHByZXNlbmNlXG4gICAgICogb2YgdGhlIGNvcmUtanMgcGFja2FnZSBiZWNhdXNlIGNvcmUtanMgY2lyY3VtdmVudHMgdGhpcyBraW5kIG9mIGRldGVjdGlvbi5cbiAgICAgKiBEZXNwaXRlIG11bHRpcGxlIHJlcXVlc3RzLCB0aGUgY29yZS1qcyBtYWludGFpbmVyIGhhcyBtYWRlIGl0IGNsZWFyOiBhbnlcbiAgICAgKiBhdHRlbXB0IHRvIGZpeCB0aGUgZGV0ZWN0aW9uIHdpbGwgYmUgb2JzdHJ1Y3RlZC4gQXMgYSByZXN1bHQsIHdlJ3JlIGxlZnRcbiAgICAgKiB3aXRoIGxpdHRsZSBjaG9pY2UgYnV0IHRvIHRocm93IGFuIGVycm9yLiBVbmZvcnR1bmF0ZWx5LCB0aGlzIGFsc28gYWZmZWN0c1xuICAgICAqIHBhY2thZ2VzLCBsaWtlIFtiYWJlbC1wb2x5ZmlsbF0oaHR0cHM6Ly93d3cubnBtanMuY29tL3BhY2thZ2UvYmFiZWwtcG9seWZpbGwpLFxuICAgICAqIHdoaWNoIHJlbHkgb24gY29yZS1qcy5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAzLjAuMFxuICAgICAqIEBjYXRlZ29yeSBMYW5nXG4gICAgICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY2hlY2suXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGB2YWx1ZWAgaXMgYSBuYXRpdmUgZnVuY3Rpb24sXG4gICAgICogIGVsc2UgYGZhbHNlYC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy5pc05hdGl2ZShBcnJheS5wcm90b3R5cGUucHVzaCk7XG4gICAgICogLy8gPT4gdHJ1ZVxuICAgICAqXG4gICAgICogXy5pc05hdGl2ZShfKTtcbiAgICAgKiAvLyA9PiBmYWxzZVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGlzTmF0aXZlKHZhbHVlKSB7XG4gICAgICBpZiAoaXNNYXNrYWJsZSh2YWx1ZSkpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKENPUkVfRVJST1JfVEVYVCk7XG4gICAgICB9XG4gICAgICByZXR1cm4gYmFzZUlzTmF0aXZlKHZhbHVlKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDaGVja3MgaWYgYHZhbHVlYCBpcyBgbnVsbGAuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMC4xLjBcbiAgICAgKiBAY2F0ZWdvcnkgTGFuZ1xuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrLlxuICAgICAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlzIGBudWxsYCwgZWxzZSBgZmFsc2VgLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLmlzTnVsbChudWxsKTtcbiAgICAgKiAvLyA9PiB0cnVlXG4gICAgICpcbiAgICAgKiBfLmlzTnVsbCh2b2lkIDApO1xuICAgICAqIC8vID0+IGZhbHNlXG4gICAgICovXG4gICAgZnVuY3Rpb24gaXNOdWxsKHZhbHVlKSB7XG4gICAgICByZXR1cm4gdmFsdWUgPT09IG51bGw7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ2hlY2tzIGlmIGB2YWx1ZWAgaXMgYG51bGxgIG9yIGB1bmRlZmluZWRgLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDQuMC4wXG4gICAgICogQGNhdGVnb3J5IExhbmdcbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjaGVjay5cbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBudWxsaXNoLCBlbHNlIGBmYWxzZWAuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8uaXNOaWwobnVsbCk7XG4gICAgICogLy8gPT4gdHJ1ZVxuICAgICAqXG4gICAgICogXy5pc05pbCh2b2lkIDApO1xuICAgICAqIC8vID0+IHRydWVcbiAgICAgKlxuICAgICAqIF8uaXNOaWwoTmFOKTtcbiAgICAgKiAvLyA9PiBmYWxzZVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGlzTmlsKHZhbHVlKSB7XG4gICAgICByZXR1cm4gdmFsdWUgPT0gbnVsbDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDaGVja3MgaWYgYHZhbHVlYCBpcyBjbGFzc2lmaWVkIGFzIGEgYE51bWJlcmAgcHJpbWl0aXZlIG9yIG9iamVjdC5cbiAgICAgKlxuICAgICAqICoqTm90ZToqKiBUbyBleGNsdWRlIGBJbmZpbml0eWAsIGAtSW5maW5pdHlgLCBhbmQgYE5hTmAsIHdoaWNoIGFyZVxuICAgICAqIGNsYXNzaWZpZWQgYXMgbnVtYmVycywgdXNlIHRoZSBgXy5pc0Zpbml0ZWAgbWV0aG9kLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDAuMS4wXG4gICAgICogQGNhdGVnb3J5IExhbmdcbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjaGVjay5cbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBhIG51bWJlciwgZWxzZSBgZmFsc2VgLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLmlzTnVtYmVyKDMpO1xuICAgICAqIC8vID0+IHRydWVcbiAgICAgKlxuICAgICAqIF8uaXNOdW1iZXIoTnVtYmVyLk1JTl9WQUxVRSk7XG4gICAgICogLy8gPT4gdHJ1ZVxuICAgICAqXG4gICAgICogXy5pc051bWJlcihJbmZpbml0eSk7XG4gICAgICogLy8gPT4gdHJ1ZVxuICAgICAqXG4gICAgICogXy5pc051bWJlcignMycpO1xuICAgICAqIC8vID0+IGZhbHNlXG4gICAgICovXG4gICAgZnVuY3Rpb24gaXNOdW1iZXIodmFsdWUpIHtcbiAgICAgIHJldHVybiB0eXBlb2YgdmFsdWUgPT0gJ251bWJlcicgfHxcbiAgICAgICAgKGlzT2JqZWN0TGlrZSh2YWx1ZSkgJiYgYmFzZUdldFRhZyh2YWx1ZSkgPT0gbnVtYmVyVGFnKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDaGVja3MgaWYgYHZhbHVlYCBpcyBhIHBsYWluIG9iamVjdCwgdGhhdCBpcywgYW4gb2JqZWN0IGNyZWF0ZWQgYnkgdGhlXG4gICAgICogYE9iamVjdGAgY29uc3RydWN0b3Igb3Igb25lIHdpdGggYSBgW1tQcm90b3R5cGVdXWAgb2YgYG51bGxgLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDAuOC4wXG4gICAgICogQGNhdGVnb3J5IExhbmdcbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjaGVjay5cbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBhIHBsYWluIG9iamVjdCwgZWxzZSBgZmFsc2VgLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBmdW5jdGlvbiBGb28oKSB7XG4gICAgICogICB0aGlzLmEgPSAxO1xuICAgICAqIH1cbiAgICAgKlxuICAgICAqIF8uaXNQbGFpbk9iamVjdChuZXcgRm9vKTtcbiAgICAgKiAvLyA9PiBmYWxzZVxuICAgICAqXG4gICAgICogXy5pc1BsYWluT2JqZWN0KFsxLCAyLCAzXSk7XG4gICAgICogLy8gPT4gZmFsc2VcbiAgICAgKlxuICAgICAqIF8uaXNQbGFpbk9iamVjdCh7ICd4JzogMCwgJ3knOiAwIH0pO1xuICAgICAqIC8vID0+IHRydWVcbiAgICAgKlxuICAgICAqIF8uaXNQbGFpbk9iamVjdChPYmplY3QuY3JlYXRlKG51bGwpKTtcbiAgICAgKiAvLyA9PiB0cnVlXG4gICAgICovXG4gICAgZnVuY3Rpb24gaXNQbGFpbk9iamVjdCh2YWx1ZSkge1xuICAgICAgaWYgKCFpc09iamVjdExpa2UodmFsdWUpIHx8IGJhc2VHZXRUYWcodmFsdWUpICE9IG9iamVjdFRhZykge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG4gICAgICB2YXIgcHJvdG8gPSBnZXRQcm90b3R5cGUodmFsdWUpO1xuICAgICAgaWYgKHByb3RvID09PSBudWxsKSB7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgfVxuICAgICAgdmFyIEN0b3IgPSBoYXNPd25Qcm9wZXJ0eS5jYWxsKHByb3RvLCAnY29uc3RydWN0b3InKSAmJiBwcm90by5jb25zdHJ1Y3RvcjtcbiAgICAgIHJldHVybiB0eXBlb2YgQ3RvciA9PSAnZnVuY3Rpb24nICYmIEN0b3IgaW5zdGFuY2VvZiBDdG9yICYmXG4gICAgICAgIGZ1bmNUb1N0cmluZy5jYWxsKEN0b3IpID09IG9iamVjdEN0b3JTdHJpbmc7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ2hlY2tzIGlmIGB2YWx1ZWAgaXMgY2xhc3NpZmllZCBhcyBhIGBSZWdFeHBgIG9iamVjdC5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAwLjEuMFxuICAgICAqIEBjYXRlZ29yeSBMYW5nXG4gICAgICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY2hlY2suXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGB2YWx1ZWAgaXMgYSByZWdleHAsIGVsc2UgYGZhbHNlYC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy5pc1JlZ0V4cCgvYWJjLyk7XG4gICAgICogLy8gPT4gdHJ1ZVxuICAgICAqXG4gICAgICogXy5pc1JlZ0V4cCgnL2FiYy8nKTtcbiAgICAgKiAvLyA9PiBmYWxzZVxuICAgICAqL1xuICAgIHZhciBpc1JlZ0V4cCA9IG5vZGVJc1JlZ0V4cCA/IGJhc2VVbmFyeShub2RlSXNSZWdFeHApIDogYmFzZUlzUmVnRXhwO1xuXG4gICAgLyoqXG4gICAgICogQ2hlY2tzIGlmIGB2YWx1ZWAgaXMgYSBzYWZlIGludGVnZXIuIEFuIGludGVnZXIgaXMgc2FmZSBpZiBpdCdzIGFuIElFRUUtNzU0XG4gICAgICogZG91YmxlIHByZWNpc2lvbiBudW1iZXIgd2hpY2ggaXNuJ3QgdGhlIHJlc3VsdCBvZiBhIHJvdW5kZWQgdW5zYWZlIGludGVnZXIuXG4gICAgICpcbiAgICAgKiAqKk5vdGU6KiogVGhpcyBtZXRob2QgaXMgYmFzZWQgb25cbiAgICAgKiBbYE51bWJlci5pc1NhZmVJbnRlZ2VyYF0oaHR0cHM6Ly9tZG4uaW8vTnVtYmVyL2lzU2FmZUludGVnZXIpLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDQuMC4wXG4gICAgICogQGNhdGVnb3J5IExhbmdcbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjaGVjay5cbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBhIHNhZmUgaW50ZWdlciwgZWxzZSBgZmFsc2VgLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLmlzU2FmZUludGVnZXIoMyk7XG4gICAgICogLy8gPT4gdHJ1ZVxuICAgICAqXG4gICAgICogXy5pc1NhZmVJbnRlZ2VyKE51bWJlci5NSU5fVkFMVUUpO1xuICAgICAqIC8vID0+IGZhbHNlXG4gICAgICpcbiAgICAgKiBfLmlzU2FmZUludGVnZXIoSW5maW5pdHkpO1xuICAgICAqIC8vID0+IGZhbHNlXG4gICAgICpcbiAgICAgKiBfLmlzU2FmZUludGVnZXIoJzMnKTtcbiAgICAgKiAvLyA9PiBmYWxzZVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGlzU2FmZUludGVnZXIodmFsdWUpIHtcbiAgICAgIHJldHVybiBpc0ludGVnZXIodmFsdWUpICYmIHZhbHVlID49IC1NQVhfU0FGRV9JTlRFR0VSICYmIHZhbHVlIDw9IE1BWF9TQUZFX0lOVEVHRVI7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ2hlY2tzIGlmIGB2YWx1ZWAgaXMgY2xhc3NpZmllZCBhcyBhIGBTZXRgIG9iamVjdC5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSA0LjMuMFxuICAgICAqIEBjYXRlZ29yeSBMYW5nXG4gICAgICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY2hlY2suXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGB2YWx1ZWAgaXMgYSBzZXQsIGVsc2UgYGZhbHNlYC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy5pc1NldChuZXcgU2V0KTtcbiAgICAgKiAvLyA9PiB0cnVlXG4gICAgICpcbiAgICAgKiBfLmlzU2V0KG5ldyBXZWFrU2V0KTtcbiAgICAgKiAvLyA9PiBmYWxzZVxuICAgICAqL1xuICAgIHZhciBpc1NldCA9IG5vZGVJc1NldCA/IGJhc2VVbmFyeShub2RlSXNTZXQpIDogYmFzZUlzU2V0O1xuXG4gICAgLyoqXG4gICAgICogQ2hlY2tzIGlmIGB2YWx1ZWAgaXMgY2xhc3NpZmllZCBhcyBhIGBTdHJpbmdgIHByaW1pdGl2ZSBvciBvYmplY3QuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQHNpbmNlIDAuMS4wXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAY2F0ZWdvcnkgTGFuZ1xuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrLlxuICAgICAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlzIGEgc3RyaW5nLCBlbHNlIGBmYWxzZWAuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8uaXNTdHJpbmcoJ2FiYycpO1xuICAgICAqIC8vID0+IHRydWVcbiAgICAgKlxuICAgICAqIF8uaXNTdHJpbmcoMSk7XG4gICAgICogLy8gPT4gZmFsc2VcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBpc1N0cmluZyh2YWx1ZSkge1xuICAgICAgcmV0dXJuIHR5cGVvZiB2YWx1ZSA9PSAnc3RyaW5nJyB8fFxuICAgICAgICAoIWlzQXJyYXkodmFsdWUpICYmIGlzT2JqZWN0TGlrZSh2YWx1ZSkgJiYgYmFzZUdldFRhZyh2YWx1ZSkgPT0gc3RyaW5nVGFnKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDaGVja3MgaWYgYHZhbHVlYCBpcyBjbGFzc2lmaWVkIGFzIGEgYFN5bWJvbGAgcHJpbWl0aXZlIG9yIG9iamVjdC5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSA0LjAuMFxuICAgICAqIEBjYXRlZ29yeSBMYW5nXG4gICAgICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY2hlY2suXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGB2YWx1ZWAgaXMgYSBzeW1ib2wsIGVsc2UgYGZhbHNlYC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy5pc1N5bWJvbChTeW1ib2wuaXRlcmF0b3IpO1xuICAgICAqIC8vID0+IHRydWVcbiAgICAgKlxuICAgICAqIF8uaXNTeW1ib2woJ2FiYycpO1xuICAgICAqIC8vID0+IGZhbHNlXG4gICAgICovXG4gICAgZnVuY3Rpb24gaXNTeW1ib2wodmFsdWUpIHtcbiAgICAgIHJldHVybiB0eXBlb2YgdmFsdWUgPT0gJ3N5bWJvbCcgfHxcbiAgICAgICAgKGlzT2JqZWN0TGlrZSh2YWx1ZSkgJiYgYmFzZUdldFRhZyh2YWx1ZSkgPT0gc3ltYm9sVGFnKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDaGVja3MgaWYgYHZhbHVlYCBpcyBjbGFzc2lmaWVkIGFzIGEgdHlwZWQgYXJyYXkuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMy4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgTGFuZ1xuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrLlxuICAgICAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlzIGEgdHlwZWQgYXJyYXksIGVsc2UgYGZhbHNlYC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy5pc1R5cGVkQXJyYXkobmV3IFVpbnQ4QXJyYXkpO1xuICAgICAqIC8vID0+IHRydWVcbiAgICAgKlxuICAgICAqIF8uaXNUeXBlZEFycmF5KFtdKTtcbiAgICAgKiAvLyA9PiBmYWxzZVxuICAgICAqL1xuICAgIHZhciBpc1R5cGVkQXJyYXkgPSBub2RlSXNUeXBlZEFycmF5ID8gYmFzZVVuYXJ5KG5vZGVJc1R5cGVkQXJyYXkpIDogYmFzZUlzVHlwZWRBcnJheTtcblxuICAgIC8qKlxuICAgICAqIENoZWNrcyBpZiBgdmFsdWVgIGlzIGB1bmRlZmluZWRgLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBzaW5jZSAwLjEuMFxuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQGNhdGVnb3J5IExhbmdcbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjaGVjay5cbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBgdW5kZWZpbmVkYCwgZWxzZSBgZmFsc2VgLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLmlzVW5kZWZpbmVkKHZvaWQgMCk7XG4gICAgICogLy8gPT4gdHJ1ZVxuICAgICAqXG4gICAgICogXy5pc1VuZGVmaW5lZChudWxsKTtcbiAgICAgKiAvLyA9PiBmYWxzZVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGlzVW5kZWZpbmVkKHZhbHVlKSB7XG4gICAgICByZXR1cm4gdmFsdWUgPT09IHVuZGVmaW5lZDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDaGVja3MgaWYgYHZhbHVlYCBpcyBjbGFzc2lmaWVkIGFzIGEgYFdlYWtNYXBgIG9iamVjdC5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSA0LjMuMFxuICAgICAqIEBjYXRlZ29yeSBMYW5nXG4gICAgICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY2hlY2suXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGB2YWx1ZWAgaXMgYSB3ZWFrIG1hcCwgZWxzZSBgZmFsc2VgLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLmlzV2Vha01hcChuZXcgV2Vha01hcCk7XG4gICAgICogLy8gPT4gdHJ1ZVxuICAgICAqXG4gICAgICogXy5pc1dlYWtNYXAobmV3IE1hcCk7XG4gICAgICogLy8gPT4gZmFsc2VcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBpc1dlYWtNYXAodmFsdWUpIHtcbiAgICAgIHJldHVybiBpc09iamVjdExpa2UodmFsdWUpICYmIGdldFRhZyh2YWx1ZSkgPT0gd2Vha01hcFRhZztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDaGVja3MgaWYgYHZhbHVlYCBpcyBjbGFzc2lmaWVkIGFzIGEgYFdlYWtTZXRgIG9iamVjdC5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSA0LjMuMFxuICAgICAqIEBjYXRlZ29yeSBMYW5nXG4gICAgICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY2hlY2suXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGB2YWx1ZWAgaXMgYSB3ZWFrIHNldCwgZWxzZSBgZmFsc2VgLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLmlzV2Vha1NldChuZXcgV2Vha1NldCk7XG4gICAgICogLy8gPT4gdHJ1ZVxuICAgICAqXG4gICAgICogXy5pc1dlYWtTZXQobmV3IFNldCk7XG4gICAgICogLy8gPT4gZmFsc2VcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBpc1dlYWtTZXQodmFsdWUpIHtcbiAgICAgIHJldHVybiBpc09iamVjdExpa2UodmFsdWUpICYmIGJhc2VHZXRUYWcodmFsdWUpID09IHdlYWtTZXRUYWc7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ2hlY2tzIGlmIGB2YWx1ZWAgaXMgbGVzcyB0aGFuIGBvdGhlcmAuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMy45LjBcbiAgICAgKiBAY2F0ZWdvcnkgTGFuZ1xuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNvbXBhcmUuXG4gICAgICogQHBhcmFtIHsqfSBvdGhlciBUaGUgb3RoZXIgdmFsdWUgdG8gY29tcGFyZS5cbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBsZXNzIHRoYW4gYG90aGVyYCxcbiAgICAgKiAgZWxzZSBgZmFsc2VgLlxuICAgICAqIEBzZWUgXy5ndFxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLmx0KDEsIDMpO1xuICAgICAqIC8vID0+IHRydWVcbiAgICAgKlxuICAgICAqIF8ubHQoMywgMyk7XG4gICAgICogLy8gPT4gZmFsc2VcbiAgICAgKlxuICAgICAqIF8ubHQoMywgMSk7XG4gICAgICogLy8gPT4gZmFsc2VcbiAgICAgKi9cbiAgICB2YXIgbHQgPSBjcmVhdGVSZWxhdGlvbmFsT3BlcmF0aW9uKGJhc2VMdCk7XG5cbiAgICAvKipcbiAgICAgKiBDaGVja3MgaWYgYHZhbHVlYCBpcyBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gYG90aGVyYC5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAzLjkuMFxuICAgICAqIEBjYXRlZ29yeSBMYW5nXG4gICAgICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY29tcGFyZS5cbiAgICAgKiBAcGFyYW0geyp9IG90aGVyIFRoZSBvdGhlciB2YWx1ZSB0byBjb21wYXJlLlxuICAgICAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlzIGxlc3MgdGhhbiBvciBlcXVhbCB0b1xuICAgICAqICBgb3RoZXJgLCBlbHNlIGBmYWxzZWAuXG4gICAgICogQHNlZSBfLmd0ZVxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLmx0ZSgxLCAzKTtcbiAgICAgKiAvLyA9PiB0cnVlXG4gICAgICpcbiAgICAgKiBfLmx0ZSgzLCAzKTtcbiAgICAgKiAvLyA9PiB0cnVlXG4gICAgICpcbiAgICAgKiBfLmx0ZSgzLCAxKTtcbiAgICAgKiAvLyA9PiBmYWxzZVxuICAgICAqL1xuICAgIHZhciBsdGUgPSBjcmVhdGVSZWxhdGlvbmFsT3BlcmF0aW9uKGZ1bmN0aW9uKHZhbHVlLCBvdGhlcikge1xuICAgICAgcmV0dXJuIHZhbHVlIDw9IG90aGVyO1xuICAgIH0pO1xuXG4gICAgLyoqXG4gICAgICogQ29udmVydHMgYHZhbHVlYCB0byBhbiBhcnJheS5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAc2luY2UgMC4xLjBcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBjYXRlZ29yeSBMYW5nXG4gICAgICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY29udmVydC5cbiAgICAgKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIGNvbnZlcnRlZCBhcnJheS5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy50b0FycmF5KHsgJ2EnOiAxLCAnYic6IDIgfSk7XG4gICAgICogLy8gPT4gWzEsIDJdXG4gICAgICpcbiAgICAgKiBfLnRvQXJyYXkoJ2FiYycpO1xuICAgICAqIC8vID0+IFsnYScsICdiJywgJ2MnXVxuICAgICAqXG4gICAgICogXy50b0FycmF5KDEpO1xuICAgICAqIC8vID0+IFtdXG4gICAgICpcbiAgICAgKiBfLnRvQXJyYXkobnVsbCk7XG4gICAgICogLy8gPT4gW11cbiAgICAgKi9cbiAgICBmdW5jdGlvbiB0b0FycmF5KHZhbHVlKSB7XG4gICAgICBpZiAoIXZhbHVlKSB7XG4gICAgICAgIHJldHVybiBbXTtcbiAgICAgIH1cbiAgICAgIGlmIChpc0FycmF5TGlrZSh2YWx1ZSkpIHtcbiAgICAgICAgcmV0dXJuIGlzU3RyaW5nKHZhbHVlKSA/IHN0cmluZ1RvQXJyYXkodmFsdWUpIDogY29weUFycmF5KHZhbHVlKTtcbiAgICAgIH1cbiAgICAgIGlmIChzeW1JdGVyYXRvciAmJiB2YWx1ZVtzeW1JdGVyYXRvcl0pIHtcbiAgICAgICAgcmV0dXJuIGl0ZXJhdG9yVG9BcnJheSh2YWx1ZVtzeW1JdGVyYXRvcl0oKSk7XG4gICAgICB9XG4gICAgICB2YXIgdGFnID0gZ2V0VGFnKHZhbHVlKSxcbiAgICAgICAgICBmdW5jID0gdGFnID09IG1hcFRhZyA/IG1hcFRvQXJyYXkgOiAodGFnID09IHNldFRhZyA/IHNldFRvQXJyYXkgOiB2YWx1ZXMpO1xuXG4gICAgICByZXR1cm4gZnVuYyh2YWx1ZSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ29udmVydHMgYHZhbHVlYCB0byBhIGZpbml0ZSBudW1iZXIuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgNC4xMi4wXG4gICAgICogQGNhdGVnb3J5IExhbmdcbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjb252ZXJ0LlxuICAgICAqIEByZXR1cm5zIHtudW1iZXJ9IFJldHVybnMgdGhlIGNvbnZlcnRlZCBudW1iZXIuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8udG9GaW5pdGUoMy4yKTtcbiAgICAgKiAvLyA9PiAzLjJcbiAgICAgKlxuICAgICAqIF8udG9GaW5pdGUoTnVtYmVyLk1JTl9WQUxVRSk7XG4gICAgICogLy8gPT4gNWUtMzI0XG4gICAgICpcbiAgICAgKiBfLnRvRmluaXRlKEluZmluaXR5KTtcbiAgICAgKiAvLyA9PiAxLjc5NzY5MzEzNDg2MjMxNTdlKzMwOFxuICAgICAqXG4gICAgICogXy50b0Zpbml0ZSgnMy4yJyk7XG4gICAgICogLy8gPT4gMy4yXG4gICAgICovXG4gICAgZnVuY3Rpb24gdG9GaW5pdGUodmFsdWUpIHtcbiAgICAgIGlmICghdmFsdWUpIHtcbiAgICAgICAgcmV0dXJuIHZhbHVlID09PSAwID8gdmFsdWUgOiAwO1xuICAgICAgfVxuICAgICAgdmFsdWUgPSB0b051bWJlcih2YWx1ZSk7XG4gICAgICBpZiAodmFsdWUgPT09IElORklOSVRZIHx8IHZhbHVlID09PSAtSU5GSU5JVFkpIHtcbiAgICAgICAgdmFyIHNpZ24gPSAodmFsdWUgPCAwID8gLTEgOiAxKTtcbiAgICAgICAgcmV0dXJuIHNpZ24gKiBNQVhfSU5URUdFUjtcbiAgICAgIH1cbiAgICAgIHJldHVybiB2YWx1ZSA9PT0gdmFsdWUgPyB2YWx1ZSA6IDA7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ29udmVydHMgYHZhbHVlYCB0byBhbiBpbnRlZ2VyLlxuICAgICAqXG4gICAgICogKipOb3RlOioqIFRoaXMgbWV0aG9kIGlzIGxvb3NlbHkgYmFzZWQgb25cbiAgICAgKiBbYFRvSW50ZWdlcmBdKGh0dHA6Ly93d3cuZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi83LjAvI3NlYy10b2ludGVnZXIpLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDQuMC4wXG4gICAgICogQGNhdGVnb3J5IExhbmdcbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjb252ZXJ0LlxuICAgICAqIEByZXR1cm5zIHtudW1iZXJ9IFJldHVybnMgdGhlIGNvbnZlcnRlZCBpbnRlZ2VyLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLnRvSW50ZWdlcigzLjIpO1xuICAgICAqIC8vID0+IDNcbiAgICAgKlxuICAgICAqIF8udG9JbnRlZ2VyKE51bWJlci5NSU5fVkFMVUUpO1xuICAgICAqIC8vID0+IDBcbiAgICAgKlxuICAgICAqIF8udG9JbnRlZ2VyKEluZmluaXR5KTtcbiAgICAgKiAvLyA9PiAxLjc5NzY5MzEzNDg2MjMxNTdlKzMwOFxuICAgICAqXG4gICAgICogXy50b0ludGVnZXIoJzMuMicpO1xuICAgICAqIC8vID0+IDNcbiAgICAgKi9cbiAgICBmdW5jdGlvbiB0b0ludGVnZXIodmFsdWUpIHtcbiAgICAgIHZhciByZXN1bHQgPSB0b0Zpbml0ZSh2YWx1ZSksXG4gICAgICAgICAgcmVtYWluZGVyID0gcmVzdWx0ICUgMTtcblxuICAgICAgcmV0dXJuIHJlc3VsdCA9PT0gcmVzdWx0ID8gKHJlbWFpbmRlciA/IHJlc3VsdCAtIHJlbWFpbmRlciA6IHJlc3VsdCkgOiAwO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENvbnZlcnRzIGB2YWx1ZWAgdG8gYW4gaW50ZWdlciBzdWl0YWJsZSBmb3IgdXNlIGFzIHRoZSBsZW5ndGggb2YgYW5cbiAgICAgKiBhcnJheS1saWtlIG9iamVjdC5cbiAgICAgKlxuICAgICAqICoqTm90ZToqKiBUaGlzIG1ldGhvZCBpcyBiYXNlZCBvblxuICAgICAqIFtgVG9MZW5ndGhgXShodHRwOi8vZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi83LjAvI3NlYy10b2xlbmd0aCkuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgNC4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgTGFuZ1xuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNvbnZlcnQuXG4gICAgICogQHJldHVybnMge251bWJlcn0gUmV0dXJucyB0aGUgY29udmVydGVkIGludGVnZXIuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8udG9MZW5ndGgoMy4yKTtcbiAgICAgKiAvLyA9PiAzXG4gICAgICpcbiAgICAgKiBfLnRvTGVuZ3RoKE51bWJlci5NSU5fVkFMVUUpO1xuICAgICAqIC8vID0+IDBcbiAgICAgKlxuICAgICAqIF8udG9MZW5ndGgoSW5maW5pdHkpO1xuICAgICAqIC8vID0+IDQyOTQ5NjcyOTVcbiAgICAgKlxuICAgICAqIF8udG9MZW5ndGgoJzMuMicpO1xuICAgICAqIC8vID0+IDNcbiAgICAgKi9cbiAgICBmdW5jdGlvbiB0b0xlbmd0aCh2YWx1ZSkge1xuICAgICAgcmV0dXJuIHZhbHVlID8gYmFzZUNsYW1wKHRvSW50ZWdlcih2YWx1ZSksIDAsIE1BWF9BUlJBWV9MRU5HVEgpIDogMDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDb252ZXJ0cyBgdmFsdWVgIHRvIGEgbnVtYmVyLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDQuMC4wXG4gICAgICogQGNhdGVnb3J5IExhbmdcbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBwcm9jZXNzLlxuICAgICAqIEByZXR1cm5zIHtudW1iZXJ9IFJldHVybnMgdGhlIG51bWJlci5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy50b051bWJlcigzLjIpO1xuICAgICAqIC8vID0+IDMuMlxuICAgICAqXG4gICAgICogXy50b051bWJlcihOdW1iZXIuTUlOX1ZBTFVFKTtcbiAgICAgKiAvLyA9PiA1ZS0zMjRcbiAgICAgKlxuICAgICAqIF8udG9OdW1iZXIoSW5maW5pdHkpO1xuICAgICAqIC8vID0+IEluZmluaXR5XG4gICAgICpcbiAgICAgKiBfLnRvTnVtYmVyKCczLjInKTtcbiAgICAgKiAvLyA9PiAzLjJcbiAgICAgKi9cbiAgICBmdW5jdGlvbiB0b051bWJlcih2YWx1ZSkge1xuICAgICAgaWYgKHR5cGVvZiB2YWx1ZSA9PSAnbnVtYmVyJykge1xuICAgICAgICByZXR1cm4gdmFsdWU7XG4gICAgICB9XG4gICAgICBpZiAoaXNTeW1ib2wodmFsdWUpKSB7XG4gICAgICAgIHJldHVybiBOQU47XG4gICAgICB9XG4gICAgICBpZiAoaXNPYmplY3QodmFsdWUpKSB7XG4gICAgICAgIHZhciBvdGhlciA9IHR5cGVvZiB2YWx1ZS52YWx1ZU9mID09ICdmdW5jdGlvbicgPyB2YWx1ZS52YWx1ZU9mKCkgOiB2YWx1ZTtcbiAgICAgICAgdmFsdWUgPSBpc09iamVjdChvdGhlcikgPyAob3RoZXIgKyAnJykgOiBvdGhlcjtcbiAgICAgIH1cbiAgICAgIGlmICh0eXBlb2YgdmFsdWUgIT0gJ3N0cmluZycpIHtcbiAgICAgICAgcmV0dXJuIHZhbHVlID09PSAwID8gdmFsdWUgOiArdmFsdWU7XG4gICAgICB9XG4gICAgICB2YWx1ZSA9IHZhbHVlLnJlcGxhY2UocmVUcmltLCAnJyk7XG4gICAgICB2YXIgaXNCaW5hcnkgPSByZUlzQmluYXJ5LnRlc3QodmFsdWUpO1xuICAgICAgcmV0dXJuIChpc0JpbmFyeSB8fCByZUlzT2N0YWwudGVzdCh2YWx1ZSkpXG4gICAgICAgID8gZnJlZVBhcnNlSW50KHZhbHVlLnNsaWNlKDIpLCBpc0JpbmFyeSA/IDIgOiA4KVxuICAgICAgICA6IChyZUlzQmFkSGV4LnRlc3QodmFsdWUpID8gTkFOIDogK3ZhbHVlKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDb252ZXJ0cyBgdmFsdWVgIHRvIGEgcGxhaW4gb2JqZWN0IGZsYXR0ZW5pbmcgaW5oZXJpdGVkIGVudW1lcmFibGUgc3RyaW5nXG4gICAgICoga2V5ZWQgcHJvcGVydGllcyBvZiBgdmFsdWVgIHRvIG93biBwcm9wZXJ0aWVzIG9mIHRoZSBwbGFpbiBvYmplY3QuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMy4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgTGFuZ1xuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNvbnZlcnQuXG4gICAgICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyB0aGUgY29udmVydGVkIHBsYWluIG9iamVjdC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogZnVuY3Rpb24gRm9vKCkge1xuICAgICAqICAgdGhpcy5iID0gMjtcbiAgICAgKiB9XG4gICAgICpcbiAgICAgKiBGb28ucHJvdG90eXBlLmMgPSAzO1xuICAgICAqXG4gICAgICogXy5hc3NpZ24oeyAnYSc6IDEgfSwgbmV3IEZvbyk7XG4gICAgICogLy8gPT4geyAnYSc6IDEsICdiJzogMiB9XG4gICAgICpcbiAgICAgKiBfLmFzc2lnbih7ICdhJzogMSB9LCBfLnRvUGxhaW5PYmplY3QobmV3IEZvbykpO1xuICAgICAqIC8vID0+IHsgJ2EnOiAxLCAnYic6IDIsICdjJzogMyB9XG4gICAgICovXG4gICAgZnVuY3Rpb24gdG9QbGFpbk9iamVjdCh2YWx1ZSkge1xuICAgICAgcmV0dXJuIGNvcHlPYmplY3QodmFsdWUsIGtleXNJbih2YWx1ZSkpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENvbnZlcnRzIGB2YWx1ZWAgdG8gYSBzYWZlIGludGVnZXIuIEEgc2FmZSBpbnRlZ2VyIGNhbiBiZSBjb21wYXJlZCBhbmRcbiAgICAgKiByZXByZXNlbnRlZCBjb3JyZWN0bHkuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgNC4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgTGFuZ1xuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNvbnZlcnQuXG4gICAgICogQHJldHVybnMge251bWJlcn0gUmV0dXJucyB0aGUgY29udmVydGVkIGludGVnZXIuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8udG9TYWZlSW50ZWdlcigzLjIpO1xuICAgICAqIC8vID0+IDNcbiAgICAgKlxuICAgICAqIF8udG9TYWZlSW50ZWdlcihOdW1iZXIuTUlOX1ZBTFVFKTtcbiAgICAgKiAvLyA9PiAwXG4gICAgICpcbiAgICAgKiBfLnRvU2FmZUludGVnZXIoSW5maW5pdHkpO1xuICAgICAqIC8vID0+IDkwMDcxOTkyNTQ3NDA5OTFcbiAgICAgKlxuICAgICAqIF8udG9TYWZlSW50ZWdlcignMy4yJyk7XG4gICAgICogLy8gPT4gM1xuICAgICAqL1xuICAgIGZ1bmN0aW9uIHRvU2FmZUludGVnZXIodmFsdWUpIHtcbiAgICAgIHJldHVybiB2YWx1ZVxuICAgICAgICA/IGJhc2VDbGFtcCh0b0ludGVnZXIodmFsdWUpLCAtTUFYX1NBRkVfSU5URUdFUiwgTUFYX1NBRkVfSU5URUdFUilcbiAgICAgICAgOiAodmFsdWUgPT09IDAgPyB2YWx1ZSA6IDApO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENvbnZlcnRzIGB2YWx1ZWAgdG8gYSBzdHJpbmcuIEFuIGVtcHR5IHN0cmluZyBpcyByZXR1cm5lZCBmb3IgYG51bGxgXG4gICAgICogYW5kIGB1bmRlZmluZWRgIHZhbHVlcy4gVGhlIHNpZ24gb2YgYC0wYCBpcyBwcmVzZXJ2ZWQuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgNC4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgTGFuZ1xuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNvbnZlcnQuXG4gICAgICogQHJldHVybnMge3N0cmluZ30gUmV0dXJucyB0aGUgY29udmVydGVkIHN0cmluZy5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy50b1N0cmluZyhudWxsKTtcbiAgICAgKiAvLyA9PiAnJ1xuICAgICAqXG4gICAgICogXy50b1N0cmluZygtMCk7XG4gICAgICogLy8gPT4gJy0wJ1xuICAgICAqXG4gICAgICogXy50b1N0cmluZyhbMSwgMiwgM10pO1xuICAgICAqIC8vID0+ICcxLDIsMydcbiAgICAgKi9cbiAgICBmdW5jdGlvbiB0b1N0cmluZyh2YWx1ZSkge1xuICAgICAgcmV0dXJuIHZhbHVlID09IG51bGwgPyAnJyA6IGJhc2VUb1N0cmluZyh2YWx1ZSk7XG4gICAgfVxuXG4gICAgLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qL1xuXG4gICAgLyoqXG4gICAgICogQXNzaWducyBvd24gZW51bWVyYWJsZSBzdHJpbmcga2V5ZWQgcHJvcGVydGllcyBvZiBzb3VyY2Ugb2JqZWN0cyB0byB0aGVcbiAgICAgKiBkZXN0aW5hdGlvbiBvYmplY3QuIFNvdXJjZSBvYmplY3RzIGFyZSBhcHBsaWVkIGZyb20gbGVmdCB0byByaWdodC5cbiAgICAgKiBTdWJzZXF1ZW50IHNvdXJjZXMgb3ZlcndyaXRlIHByb3BlcnR5IGFzc2lnbm1lbnRzIG9mIHByZXZpb3VzIHNvdXJjZXMuXG4gICAgICpcbiAgICAgKiAqKk5vdGU6KiogVGhpcyBtZXRob2QgbXV0YXRlcyBgb2JqZWN0YCBhbmQgaXMgbG9vc2VseSBiYXNlZCBvblxuICAgICAqIFtgT2JqZWN0LmFzc2lnbmBdKGh0dHBzOi8vbWRuLmlvL09iamVjdC9hc3NpZ24pLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDAuMTAuMFxuICAgICAqIEBjYXRlZ29yeSBPYmplY3RcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBkZXN0aW5hdGlvbiBvYmplY3QuXG4gICAgICogQHBhcmFtIHsuLi5PYmplY3R9IFtzb3VyY2VzXSBUaGUgc291cmNlIG9iamVjdHMuXG4gICAgICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyBgb2JqZWN0YC5cbiAgICAgKiBAc2VlIF8uYXNzaWduSW5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogZnVuY3Rpb24gRm9vKCkge1xuICAgICAqICAgdGhpcy5hID0gMTtcbiAgICAgKiB9XG4gICAgICpcbiAgICAgKiBmdW5jdGlvbiBCYXIoKSB7XG4gICAgICogICB0aGlzLmMgPSAzO1xuICAgICAqIH1cbiAgICAgKlxuICAgICAqIEZvby5wcm90b3R5cGUuYiA9IDI7XG4gICAgICogQmFyLnByb3RvdHlwZS5kID0gNDtcbiAgICAgKlxuICAgICAqIF8uYXNzaWduKHsgJ2EnOiAwIH0sIG5ldyBGb28sIG5ldyBCYXIpO1xuICAgICAqIC8vID0+IHsgJ2EnOiAxLCAnYyc6IDMgfVxuICAgICAqL1xuICAgIHZhciBhc3NpZ24gPSBjcmVhdGVBc3NpZ25lcihmdW5jdGlvbihvYmplY3QsIHNvdXJjZSkge1xuICAgICAgaWYgKGlzUHJvdG90eXBlKHNvdXJjZSkgfHwgaXNBcnJheUxpa2Uoc291cmNlKSkge1xuICAgICAgICBjb3B5T2JqZWN0KHNvdXJjZSwga2V5cyhzb3VyY2UpLCBvYmplY3QpO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICBmb3IgKHZhciBrZXkgaW4gc291cmNlKSB7XG4gICAgICAgIGlmIChoYXNPd25Qcm9wZXJ0eS5jYWxsKHNvdXJjZSwga2V5KSkge1xuICAgICAgICAgIGFzc2lnblZhbHVlKG9iamVjdCwga2V5LCBzb3VyY2Vba2V5XSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9KTtcblxuICAgIC8qKlxuICAgICAqIFRoaXMgbWV0aG9kIGlzIGxpa2UgYF8uYXNzaWduYCBleGNlcHQgdGhhdCBpdCBpdGVyYXRlcyBvdmVyIG93biBhbmRcbiAgICAgKiBpbmhlcml0ZWQgc291cmNlIHByb3BlcnRpZXMuXG4gICAgICpcbiAgICAgKiAqKk5vdGU6KiogVGhpcyBtZXRob2QgbXV0YXRlcyBgb2JqZWN0YC5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSA0LjAuMFxuICAgICAqIEBhbGlhcyBleHRlbmRcbiAgICAgKiBAY2F0ZWdvcnkgT2JqZWN0XG4gICAgICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgZGVzdGluYXRpb24gb2JqZWN0LlxuICAgICAqIEBwYXJhbSB7Li4uT2JqZWN0fSBbc291cmNlc10gVGhlIHNvdXJjZSBvYmplY3RzLlxuICAgICAqIEByZXR1cm5zIHtPYmplY3R9IFJldHVybnMgYG9iamVjdGAuXG4gICAgICogQHNlZSBfLmFzc2lnblxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBmdW5jdGlvbiBGb28oKSB7XG4gICAgICogICB0aGlzLmEgPSAxO1xuICAgICAqIH1cbiAgICAgKlxuICAgICAqIGZ1bmN0aW9uIEJhcigpIHtcbiAgICAgKiAgIHRoaXMuYyA9IDM7XG4gICAgICogfVxuICAgICAqXG4gICAgICogRm9vLnByb3RvdHlwZS5iID0gMjtcbiAgICAgKiBCYXIucHJvdG90eXBlLmQgPSA0O1xuICAgICAqXG4gICAgICogXy5hc3NpZ25Jbih7ICdhJzogMCB9LCBuZXcgRm9vLCBuZXcgQmFyKTtcbiAgICAgKiAvLyA9PiB7ICdhJzogMSwgJ2InOiAyLCAnYyc6IDMsICdkJzogNCB9XG4gICAgICovXG4gICAgdmFyIGFzc2lnbkluID0gY3JlYXRlQXNzaWduZXIoZnVuY3Rpb24ob2JqZWN0LCBzb3VyY2UpIHtcbiAgICAgIGNvcHlPYmplY3Qoc291cmNlLCBrZXlzSW4oc291cmNlKSwgb2JqZWN0KTtcbiAgICB9KTtcblxuICAgIC8qKlxuICAgICAqIFRoaXMgbWV0aG9kIGlzIGxpa2UgYF8uYXNzaWduSW5gIGV4Y2VwdCB0aGF0IGl0IGFjY2VwdHMgYGN1c3RvbWl6ZXJgXG4gICAgICogd2hpY2ggaXMgaW52b2tlZCB0byBwcm9kdWNlIHRoZSBhc3NpZ25lZCB2YWx1ZXMuIElmIGBjdXN0b21pemVyYCByZXR1cm5zXG4gICAgICogYHVuZGVmaW5lZGAsIGFzc2lnbm1lbnQgaXMgaGFuZGxlZCBieSB0aGUgbWV0aG9kIGluc3RlYWQuIFRoZSBgY3VzdG9taXplcmBcbiAgICAgKiBpcyBpbnZva2VkIHdpdGggZml2ZSBhcmd1bWVudHM6IChvYmpWYWx1ZSwgc3JjVmFsdWUsIGtleSwgb2JqZWN0LCBzb3VyY2UpLlxuICAgICAqXG4gICAgICogKipOb3RlOioqIFRoaXMgbWV0aG9kIG11dGF0ZXMgYG9iamVjdGAuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgNC4wLjBcbiAgICAgKiBAYWxpYXMgZXh0ZW5kV2l0aFxuICAgICAqIEBjYXRlZ29yeSBPYmplY3RcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBkZXN0aW5hdGlvbiBvYmplY3QuXG4gICAgICogQHBhcmFtIHsuLi5PYmplY3R9IHNvdXJjZXMgVGhlIHNvdXJjZSBvYmplY3RzLlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IFtjdXN0b21pemVyXSBUaGUgZnVuY3Rpb24gdG8gY3VzdG9taXplIGFzc2lnbmVkIHZhbHVlcy5cbiAgICAgKiBAcmV0dXJucyB7T2JqZWN0fSBSZXR1cm5zIGBvYmplY3RgLlxuICAgICAqIEBzZWUgXy5hc3NpZ25XaXRoXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIGZ1bmN0aW9uIGN1c3RvbWl6ZXIob2JqVmFsdWUsIHNyY1ZhbHVlKSB7XG4gICAgICogICByZXR1cm4gXy5pc1VuZGVmaW5lZChvYmpWYWx1ZSkgPyBzcmNWYWx1ZSA6IG9ialZhbHVlO1xuICAgICAqIH1cbiAgICAgKlxuICAgICAqIHZhciBkZWZhdWx0cyA9IF8ucGFydGlhbFJpZ2h0KF8uYXNzaWduSW5XaXRoLCBjdXN0b21pemVyKTtcbiAgICAgKlxuICAgICAqIGRlZmF1bHRzKHsgJ2EnOiAxIH0sIHsgJ2InOiAyIH0sIHsgJ2EnOiAzIH0pO1xuICAgICAqIC8vID0+IHsgJ2EnOiAxLCAnYic6IDIgfVxuICAgICAqL1xuICAgIHZhciBhc3NpZ25JbldpdGggPSBjcmVhdGVBc3NpZ25lcihmdW5jdGlvbihvYmplY3QsIHNvdXJjZSwgc3JjSW5kZXgsIGN1c3RvbWl6ZXIpIHtcbiAgICAgIGNvcHlPYmplY3Qoc291cmNlLCBrZXlzSW4oc291cmNlKSwgb2JqZWN0LCBjdXN0b21pemVyKTtcbiAgICB9KTtcblxuICAgIC8qKlxuICAgICAqIFRoaXMgbWV0aG9kIGlzIGxpa2UgYF8uYXNzaWduYCBleGNlcHQgdGhhdCBpdCBhY2NlcHRzIGBjdXN0b21pemVyYFxuICAgICAqIHdoaWNoIGlzIGludm9rZWQgdG8gcHJvZHVjZSB0aGUgYXNzaWduZWQgdmFsdWVzLiBJZiBgY3VzdG9taXplcmAgcmV0dXJuc1xuICAgICAqIGB1bmRlZmluZWRgLCBhc3NpZ25tZW50IGlzIGhhbmRsZWQgYnkgdGhlIG1ldGhvZCBpbnN0ZWFkLiBUaGUgYGN1c3RvbWl6ZXJgXG4gICAgICogaXMgaW52b2tlZCB3aXRoIGZpdmUgYXJndW1lbnRzOiAob2JqVmFsdWUsIHNyY1ZhbHVlLCBrZXksIG9iamVjdCwgc291cmNlKS5cbiAgICAgKlxuICAgICAqICoqTm90ZToqKiBUaGlzIG1ldGhvZCBtdXRhdGVzIGBvYmplY3RgLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDQuMC4wXG4gICAgICogQGNhdGVnb3J5IE9iamVjdFxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIGRlc3RpbmF0aW9uIG9iamVjdC5cbiAgICAgKiBAcGFyYW0gey4uLk9iamVjdH0gc291cmNlcyBUaGUgc291cmNlIG9iamVjdHMuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gW2N1c3RvbWl6ZXJdIFRoZSBmdW5jdGlvbiB0byBjdXN0b21pemUgYXNzaWduZWQgdmFsdWVzLlxuICAgICAqIEByZXR1cm5zIHtPYmplY3R9IFJldHVybnMgYG9iamVjdGAuXG4gICAgICogQHNlZSBfLmFzc2lnbkluV2l0aFxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBmdW5jdGlvbiBjdXN0b21pemVyKG9ialZhbHVlLCBzcmNWYWx1ZSkge1xuICAgICAqICAgcmV0dXJuIF8uaXNVbmRlZmluZWQob2JqVmFsdWUpID8gc3JjVmFsdWUgOiBvYmpWYWx1ZTtcbiAgICAgKiB9XG4gICAgICpcbiAgICAgKiB2YXIgZGVmYXVsdHMgPSBfLnBhcnRpYWxSaWdodChfLmFzc2lnbldpdGgsIGN1c3RvbWl6ZXIpO1xuICAgICAqXG4gICAgICogZGVmYXVsdHMoeyAnYSc6IDEgfSwgeyAnYic6IDIgfSwgeyAnYSc6IDMgfSk7XG4gICAgICogLy8gPT4geyAnYSc6IDEsICdiJzogMiB9XG4gICAgICovXG4gICAgdmFyIGFzc2lnbldpdGggPSBjcmVhdGVBc3NpZ25lcihmdW5jdGlvbihvYmplY3QsIHNvdXJjZSwgc3JjSW5kZXgsIGN1c3RvbWl6ZXIpIHtcbiAgICAgIGNvcHlPYmplY3Qoc291cmNlLCBrZXlzKHNvdXJjZSksIG9iamVjdCwgY3VzdG9taXplcik7XG4gICAgfSk7XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGFuIGFycmF5IG9mIHZhbHVlcyBjb3JyZXNwb25kaW5nIHRvIGBwYXRoc2Agb2YgYG9iamVjdGAuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMS4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgT2JqZWN0XG4gICAgICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIGl0ZXJhdGUgb3Zlci5cbiAgICAgKiBAcGFyYW0gey4uLihzdHJpbmd8c3RyaW5nW10pfSBbcGF0aHNdIFRoZSBwcm9wZXJ0eSBwYXRocyB0byBwaWNrLlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgcGlja2VkIHZhbHVlcy5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogdmFyIG9iamVjdCA9IHsgJ2EnOiBbeyAnYic6IHsgJ2MnOiAzIH0gfSwgNF0gfTtcbiAgICAgKlxuICAgICAqIF8uYXQob2JqZWN0LCBbJ2FbMF0uYi5jJywgJ2FbMV0nXSk7XG4gICAgICogLy8gPT4gWzMsIDRdXG4gICAgICovXG4gICAgdmFyIGF0ID0gZmxhdFJlc3QoYmFzZUF0KTtcblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYW4gb2JqZWN0IHRoYXQgaW5oZXJpdHMgZnJvbSB0aGUgYHByb3RvdHlwZWAgb2JqZWN0LiBJZiBhXG4gICAgICogYHByb3BlcnRpZXNgIG9iamVjdCBpcyBnaXZlbiwgaXRzIG93biBlbnVtZXJhYmxlIHN0cmluZyBrZXllZCBwcm9wZXJ0aWVzXG4gICAgICogYXJlIGFzc2lnbmVkIHRvIHRoZSBjcmVhdGVkIG9iamVjdC5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAyLjMuMFxuICAgICAqIEBjYXRlZ29yeSBPYmplY3RcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gcHJvdG90eXBlIFRoZSBvYmplY3QgdG8gaW5oZXJpdCBmcm9tLlxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBbcHJvcGVydGllc10gVGhlIHByb3BlcnRpZXMgdG8gYXNzaWduIHRvIHRoZSBvYmplY3QuXG4gICAgICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyB0aGUgbmV3IG9iamVjdC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogZnVuY3Rpb24gU2hhcGUoKSB7XG4gICAgICogICB0aGlzLnggPSAwO1xuICAgICAqICAgdGhpcy55ID0gMDtcbiAgICAgKiB9XG4gICAgICpcbiAgICAgKiBmdW5jdGlvbiBDaXJjbGUoKSB7XG4gICAgICogICBTaGFwZS5jYWxsKHRoaXMpO1xuICAgICAqIH1cbiAgICAgKlxuICAgICAqIENpcmNsZS5wcm90b3R5cGUgPSBfLmNyZWF0ZShTaGFwZS5wcm90b3R5cGUsIHtcbiAgICAgKiAgICdjb25zdHJ1Y3Rvcic6IENpcmNsZVxuICAgICAqIH0pO1xuICAgICAqXG4gICAgICogdmFyIGNpcmNsZSA9IG5ldyBDaXJjbGU7XG4gICAgICogY2lyY2xlIGluc3RhbmNlb2YgQ2lyY2xlO1xuICAgICAqIC8vID0+IHRydWVcbiAgICAgKlxuICAgICAqIGNpcmNsZSBpbnN0YW5jZW9mIFNoYXBlO1xuICAgICAqIC8vID0+IHRydWVcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBjcmVhdGUocHJvdG90eXBlLCBwcm9wZXJ0aWVzKSB7XG4gICAgICB2YXIgcmVzdWx0ID0gYmFzZUNyZWF0ZShwcm90b3R5cGUpO1xuICAgICAgcmV0dXJuIHByb3BlcnRpZXMgPT0gbnVsbCA/IHJlc3VsdCA6IGJhc2VBc3NpZ24ocmVzdWx0LCBwcm9wZXJ0aWVzKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBBc3NpZ25zIG93biBhbmQgaW5oZXJpdGVkIGVudW1lcmFibGUgc3RyaW5nIGtleWVkIHByb3BlcnRpZXMgb2Ygc291cmNlXG4gICAgICogb2JqZWN0cyB0byB0aGUgZGVzdGluYXRpb24gb2JqZWN0IGZvciBhbGwgZGVzdGluYXRpb24gcHJvcGVydGllcyB0aGF0XG4gICAgICogcmVzb2x2ZSB0byBgdW5kZWZpbmVkYC4gU291cmNlIG9iamVjdHMgYXJlIGFwcGxpZWQgZnJvbSBsZWZ0IHRvIHJpZ2h0LlxuICAgICAqIE9uY2UgYSBwcm9wZXJ0eSBpcyBzZXQsIGFkZGl0aW9uYWwgdmFsdWVzIG9mIHRoZSBzYW1lIHByb3BlcnR5IGFyZSBpZ25vcmVkLlxuICAgICAqXG4gICAgICogKipOb3RlOioqIFRoaXMgbWV0aG9kIG11dGF0ZXMgYG9iamVjdGAuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQHNpbmNlIDAuMS4wXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAY2F0ZWdvcnkgT2JqZWN0XG4gICAgICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgZGVzdGluYXRpb24gb2JqZWN0LlxuICAgICAqIEBwYXJhbSB7Li4uT2JqZWN0fSBbc291cmNlc10gVGhlIHNvdXJjZSBvYmplY3RzLlxuICAgICAqIEByZXR1cm5zIHtPYmplY3R9IFJldHVybnMgYG9iamVjdGAuXG4gICAgICogQHNlZSBfLmRlZmF1bHRzRGVlcFxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLmRlZmF1bHRzKHsgJ2EnOiAxIH0sIHsgJ2InOiAyIH0sIHsgJ2EnOiAzIH0pO1xuICAgICAqIC8vID0+IHsgJ2EnOiAxLCAnYic6IDIgfVxuICAgICAqL1xuICAgIHZhciBkZWZhdWx0cyA9IGJhc2VSZXN0KGZ1bmN0aW9uKGFyZ3MpIHtcbiAgICAgIGFyZ3MucHVzaCh1bmRlZmluZWQsIGN1c3RvbURlZmF1bHRzQXNzaWduSW4pO1xuICAgICAgcmV0dXJuIGFwcGx5KGFzc2lnbkluV2l0aCwgdW5kZWZpbmVkLCBhcmdzKTtcbiAgICB9KTtcblxuICAgIC8qKlxuICAgICAqIFRoaXMgbWV0aG9kIGlzIGxpa2UgYF8uZGVmYXVsdHNgIGV4Y2VwdCB0aGF0IGl0IHJlY3Vyc2l2ZWx5IGFzc2lnbnNcbiAgICAgKiBkZWZhdWx0IHByb3BlcnRpZXMuXG4gICAgICpcbiAgICAgKiAqKk5vdGU6KiogVGhpcyBtZXRob2QgbXV0YXRlcyBgb2JqZWN0YC5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAzLjEwLjBcbiAgICAgKiBAY2F0ZWdvcnkgT2JqZWN0XG4gICAgICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgZGVzdGluYXRpb24gb2JqZWN0LlxuICAgICAqIEBwYXJhbSB7Li4uT2JqZWN0fSBbc291cmNlc10gVGhlIHNvdXJjZSBvYmplY3RzLlxuICAgICAqIEByZXR1cm5zIHtPYmplY3R9IFJldHVybnMgYG9iamVjdGAuXG4gICAgICogQHNlZSBfLmRlZmF1bHRzXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8uZGVmYXVsdHNEZWVwKHsgJ2EnOiB7ICdiJzogMiB9IH0sIHsgJ2EnOiB7ICdiJzogMSwgJ2MnOiAzIH0gfSk7XG4gICAgICogLy8gPT4geyAnYSc6IHsgJ2InOiAyLCAnYyc6IDMgfSB9XG4gICAgICovXG4gICAgdmFyIGRlZmF1bHRzRGVlcCA9IGJhc2VSZXN0KGZ1bmN0aW9uKGFyZ3MpIHtcbiAgICAgIGFyZ3MucHVzaCh1bmRlZmluZWQsIGN1c3RvbURlZmF1bHRzTWVyZ2UpO1xuICAgICAgcmV0dXJuIGFwcGx5KG1lcmdlV2l0aCwgdW5kZWZpbmVkLCBhcmdzKTtcbiAgICB9KTtcblxuICAgIC8qKlxuICAgICAqIFRoaXMgbWV0aG9kIGlzIGxpa2UgYF8uZmluZGAgZXhjZXB0IHRoYXQgaXQgcmV0dXJucyB0aGUga2V5IG9mIHRoZSBmaXJzdFxuICAgICAqIGVsZW1lbnQgYHByZWRpY2F0ZWAgcmV0dXJucyB0cnV0aHkgZm9yIGluc3RlYWQgb2YgdGhlIGVsZW1lbnQgaXRzZWxmLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDEuMS4wXG4gICAgICogQGNhdGVnb3J5IE9iamVjdFxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBpbnNwZWN0LlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IFtwcmVkaWNhdGU9Xy5pZGVudGl0eV0gVGhlIGZ1bmN0aW9uIGludm9rZWQgcGVyIGl0ZXJhdGlvbi5cbiAgICAgKiBAcmV0dXJucyB7c3RyaW5nfHVuZGVmaW5lZH0gUmV0dXJucyB0aGUga2V5IG9mIHRoZSBtYXRjaGVkIGVsZW1lbnQsXG4gICAgICogIGVsc2UgYHVuZGVmaW5lZGAuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIHZhciB1c2VycyA9IHtcbiAgICAgKiAgICdiYXJuZXknOiAgeyAnYWdlJzogMzYsICdhY3RpdmUnOiB0cnVlIH0sXG4gICAgICogICAnZnJlZCc6ICAgIHsgJ2FnZSc6IDQwLCAnYWN0aXZlJzogZmFsc2UgfSxcbiAgICAgKiAgICdwZWJibGVzJzogeyAnYWdlJzogMSwgICdhY3RpdmUnOiB0cnVlIH1cbiAgICAgKiB9O1xuICAgICAqXG4gICAgICogXy5maW5kS2V5KHVzZXJzLCBmdW5jdGlvbihvKSB7IHJldHVybiBvLmFnZSA8IDQwOyB9KTtcbiAgICAgKiAvLyA9PiAnYmFybmV5JyAoaXRlcmF0aW9uIG9yZGVyIGlzIG5vdCBndWFyYW50ZWVkKVxuICAgICAqXG4gICAgICogLy8gVGhlIGBfLm1hdGNoZXNgIGl0ZXJhdGVlIHNob3J0aGFuZC5cbiAgICAgKiBfLmZpbmRLZXkodXNlcnMsIHsgJ2FnZSc6IDEsICdhY3RpdmUnOiB0cnVlIH0pO1xuICAgICAqIC8vID0+ICdwZWJibGVzJ1xuICAgICAqXG4gICAgICogLy8gVGhlIGBfLm1hdGNoZXNQcm9wZXJ0eWAgaXRlcmF0ZWUgc2hvcnRoYW5kLlxuICAgICAqIF8uZmluZEtleSh1c2VycywgWydhY3RpdmUnLCBmYWxzZV0pO1xuICAgICAqIC8vID0+ICdmcmVkJ1xuICAgICAqXG4gICAgICogLy8gVGhlIGBfLnByb3BlcnR5YCBpdGVyYXRlZSBzaG9ydGhhbmQuXG4gICAgICogXy5maW5kS2V5KHVzZXJzLCAnYWN0aXZlJyk7XG4gICAgICogLy8gPT4gJ2Jhcm5leSdcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBmaW5kS2V5KG9iamVjdCwgcHJlZGljYXRlKSB7XG4gICAgICByZXR1cm4gYmFzZUZpbmRLZXkob2JqZWN0LCBnZXRJdGVyYXRlZShwcmVkaWNhdGUsIDMpLCBiYXNlRm9yT3duKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGlzIG1ldGhvZCBpcyBsaWtlIGBfLmZpbmRLZXlgIGV4Y2VwdCB0aGF0IGl0IGl0ZXJhdGVzIG92ZXIgZWxlbWVudHMgb2ZcbiAgICAgKiBhIGNvbGxlY3Rpb24gaW4gdGhlIG9wcG9zaXRlIG9yZGVyLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDIuMC4wXG4gICAgICogQGNhdGVnb3J5IE9iamVjdFxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBpbnNwZWN0LlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IFtwcmVkaWNhdGU9Xy5pZGVudGl0eV0gVGhlIGZ1bmN0aW9uIGludm9rZWQgcGVyIGl0ZXJhdGlvbi5cbiAgICAgKiBAcmV0dXJucyB7c3RyaW5nfHVuZGVmaW5lZH0gUmV0dXJucyB0aGUga2V5IG9mIHRoZSBtYXRjaGVkIGVsZW1lbnQsXG4gICAgICogIGVsc2UgYHVuZGVmaW5lZGAuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIHZhciB1c2VycyA9IHtcbiAgICAgKiAgICdiYXJuZXknOiAgeyAnYWdlJzogMzYsICdhY3RpdmUnOiB0cnVlIH0sXG4gICAgICogICAnZnJlZCc6ICAgIHsgJ2FnZSc6IDQwLCAnYWN0aXZlJzogZmFsc2UgfSxcbiAgICAgKiAgICdwZWJibGVzJzogeyAnYWdlJzogMSwgICdhY3RpdmUnOiB0cnVlIH1cbiAgICAgKiB9O1xuICAgICAqXG4gICAgICogXy5maW5kTGFzdEtleSh1c2VycywgZnVuY3Rpb24obykgeyByZXR1cm4gby5hZ2UgPCA0MDsgfSk7XG4gICAgICogLy8gPT4gcmV0dXJucyAncGViYmxlcycgYXNzdW1pbmcgYF8uZmluZEtleWAgcmV0dXJucyAnYmFybmV5J1xuICAgICAqXG4gICAgICogLy8gVGhlIGBfLm1hdGNoZXNgIGl0ZXJhdGVlIHNob3J0aGFuZC5cbiAgICAgKiBfLmZpbmRMYXN0S2V5KHVzZXJzLCB7ICdhZ2UnOiAzNiwgJ2FjdGl2ZSc6IHRydWUgfSk7XG4gICAgICogLy8gPT4gJ2Jhcm5leSdcbiAgICAgKlxuICAgICAqIC8vIFRoZSBgXy5tYXRjaGVzUHJvcGVydHlgIGl0ZXJhdGVlIHNob3J0aGFuZC5cbiAgICAgKiBfLmZpbmRMYXN0S2V5KHVzZXJzLCBbJ2FjdGl2ZScsIGZhbHNlXSk7XG4gICAgICogLy8gPT4gJ2ZyZWQnXG4gICAgICpcbiAgICAgKiAvLyBUaGUgYF8ucHJvcGVydHlgIGl0ZXJhdGVlIHNob3J0aGFuZC5cbiAgICAgKiBfLmZpbmRMYXN0S2V5KHVzZXJzLCAnYWN0aXZlJyk7XG4gICAgICogLy8gPT4gJ3BlYmJsZXMnXG4gICAgICovXG4gICAgZnVuY3Rpb24gZmluZExhc3RLZXkob2JqZWN0LCBwcmVkaWNhdGUpIHtcbiAgICAgIHJldHVybiBiYXNlRmluZEtleShvYmplY3QsIGdldEl0ZXJhdGVlKHByZWRpY2F0ZSwgMyksIGJhc2VGb3JPd25SaWdodCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogSXRlcmF0ZXMgb3ZlciBvd24gYW5kIGluaGVyaXRlZCBlbnVtZXJhYmxlIHN0cmluZyBrZXllZCBwcm9wZXJ0aWVzIG9mIGFuXG4gICAgICogb2JqZWN0IGFuZCBpbnZva2VzIGBpdGVyYXRlZWAgZm9yIGVhY2ggcHJvcGVydHkuIFRoZSBpdGVyYXRlZSBpcyBpbnZva2VkXG4gICAgICogd2l0aCB0aHJlZSBhcmd1bWVudHM6ICh2YWx1ZSwga2V5LCBvYmplY3QpLiBJdGVyYXRlZSBmdW5jdGlvbnMgbWF5IGV4aXRcbiAgICAgKiBpdGVyYXRpb24gZWFybHkgYnkgZXhwbGljaXRseSByZXR1cm5pbmcgYGZhbHNlYC5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAwLjMuMFxuICAgICAqIEBjYXRlZ29yeSBPYmplY3RcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gaXRlcmF0ZSBvdmVyLlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IFtpdGVyYXRlZT1fLmlkZW50aXR5XSBUaGUgZnVuY3Rpb24gaW52b2tlZCBwZXIgaXRlcmF0aW9uLlxuICAgICAqIEByZXR1cm5zIHtPYmplY3R9IFJldHVybnMgYG9iamVjdGAuXG4gICAgICogQHNlZSBfLmZvckluUmlnaHRcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogZnVuY3Rpb24gRm9vKCkge1xuICAgICAqICAgdGhpcy5hID0gMTtcbiAgICAgKiAgIHRoaXMuYiA9IDI7XG4gICAgICogfVxuICAgICAqXG4gICAgICogRm9vLnByb3RvdHlwZS5jID0gMztcbiAgICAgKlxuICAgICAqIF8uZm9ySW4obmV3IEZvbywgZnVuY3Rpb24odmFsdWUsIGtleSkge1xuICAgICAqICAgY29uc29sZS5sb2coa2V5KTtcbiAgICAgKiB9KTtcbiAgICAgKiAvLyA9PiBMb2dzICdhJywgJ2InLCB0aGVuICdjJyAoaXRlcmF0aW9uIG9yZGVyIGlzIG5vdCBndWFyYW50ZWVkKS5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBmb3JJbihvYmplY3QsIGl0ZXJhdGVlKSB7XG4gICAgICByZXR1cm4gb2JqZWN0ID09IG51bGxcbiAgICAgICAgPyBvYmplY3RcbiAgICAgICAgOiBiYXNlRm9yKG9iamVjdCwgZ2V0SXRlcmF0ZWUoaXRlcmF0ZWUsIDMpLCBrZXlzSW4pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoaXMgbWV0aG9kIGlzIGxpa2UgYF8uZm9ySW5gIGV4Y2VwdCB0aGF0IGl0IGl0ZXJhdGVzIG92ZXIgcHJvcGVydGllcyBvZlxuICAgICAqIGBvYmplY3RgIGluIHRoZSBvcHBvc2l0ZSBvcmRlci5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAyLjAuMFxuICAgICAqIEBjYXRlZ29yeSBPYmplY3RcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gaXRlcmF0ZSBvdmVyLlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IFtpdGVyYXRlZT1fLmlkZW50aXR5XSBUaGUgZnVuY3Rpb24gaW52b2tlZCBwZXIgaXRlcmF0aW9uLlxuICAgICAqIEByZXR1cm5zIHtPYmplY3R9IFJldHVybnMgYG9iamVjdGAuXG4gICAgICogQHNlZSBfLmZvckluXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIGZ1bmN0aW9uIEZvbygpIHtcbiAgICAgKiAgIHRoaXMuYSA9IDE7XG4gICAgICogICB0aGlzLmIgPSAyO1xuICAgICAqIH1cbiAgICAgKlxuICAgICAqIEZvby5wcm90b3R5cGUuYyA9IDM7XG4gICAgICpcbiAgICAgKiBfLmZvckluUmlnaHQobmV3IEZvbywgZnVuY3Rpb24odmFsdWUsIGtleSkge1xuICAgICAqICAgY29uc29sZS5sb2coa2V5KTtcbiAgICAgKiB9KTtcbiAgICAgKiAvLyA9PiBMb2dzICdjJywgJ2InLCB0aGVuICdhJyBhc3N1bWluZyBgXy5mb3JJbmAgbG9ncyAnYScsICdiJywgdGhlbiAnYycuXG4gICAgICovXG4gICAgZnVuY3Rpb24gZm9ySW5SaWdodChvYmplY3QsIGl0ZXJhdGVlKSB7XG4gICAgICByZXR1cm4gb2JqZWN0ID09IG51bGxcbiAgICAgICAgPyBvYmplY3RcbiAgICAgICAgOiBiYXNlRm9yUmlnaHQob2JqZWN0LCBnZXRJdGVyYXRlZShpdGVyYXRlZSwgMyksIGtleXNJbik7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogSXRlcmF0ZXMgb3ZlciBvd24gZW51bWVyYWJsZSBzdHJpbmcga2V5ZWQgcHJvcGVydGllcyBvZiBhbiBvYmplY3QgYW5kXG4gICAgICogaW52b2tlcyBgaXRlcmF0ZWVgIGZvciBlYWNoIHByb3BlcnR5LiBUaGUgaXRlcmF0ZWUgaXMgaW52b2tlZCB3aXRoIHRocmVlXG4gICAgICogYXJndW1lbnRzOiAodmFsdWUsIGtleSwgb2JqZWN0KS4gSXRlcmF0ZWUgZnVuY3Rpb25zIG1heSBleGl0IGl0ZXJhdGlvblxuICAgICAqIGVhcmx5IGJ5IGV4cGxpY2l0bHkgcmV0dXJuaW5nIGBmYWxzZWAuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMC4zLjBcbiAgICAgKiBAY2F0ZWdvcnkgT2JqZWN0XG4gICAgICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIGl0ZXJhdGUgb3Zlci5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBbaXRlcmF0ZWU9Xy5pZGVudGl0eV0gVGhlIGZ1bmN0aW9uIGludm9rZWQgcGVyIGl0ZXJhdGlvbi5cbiAgICAgKiBAcmV0dXJucyB7T2JqZWN0fSBSZXR1cm5zIGBvYmplY3RgLlxuICAgICAqIEBzZWUgXy5mb3JPd25SaWdodFxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBmdW5jdGlvbiBGb28oKSB7XG4gICAgICogICB0aGlzLmEgPSAxO1xuICAgICAqICAgdGhpcy5iID0gMjtcbiAgICAgKiB9XG4gICAgICpcbiAgICAgKiBGb28ucHJvdG90eXBlLmMgPSAzO1xuICAgICAqXG4gICAgICogXy5mb3JPd24obmV3IEZvbywgZnVuY3Rpb24odmFsdWUsIGtleSkge1xuICAgICAqICAgY29uc29sZS5sb2coa2V5KTtcbiAgICAgKiB9KTtcbiAgICAgKiAvLyA9PiBMb2dzICdhJyB0aGVuICdiJyAoaXRlcmF0aW9uIG9yZGVyIGlzIG5vdCBndWFyYW50ZWVkKS5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBmb3JPd24ob2JqZWN0LCBpdGVyYXRlZSkge1xuICAgICAgcmV0dXJuIG9iamVjdCAmJiBiYXNlRm9yT3duKG9iamVjdCwgZ2V0SXRlcmF0ZWUoaXRlcmF0ZWUsIDMpKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGlzIG1ldGhvZCBpcyBsaWtlIGBfLmZvck93bmAgZXhjZXB0IHRoYXQgaXQgaXRlcmF0ZXMgb3ZlciBwcm9wZXJ0aWVzIG9mXG4gICAgICogYG9iamVjdGAgaW4gdGhlIG9wcG9zaXRlIG9yZGVyLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDIuMC4wXG4gICAgICogQGNhdGVnb3J5IE9iamVjdFxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBpdGVyYXRlIG92ZXIuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gW2l0ZXJhdGVlPV8uaWRlbnRpdHldIFRoZSBmdW5jdGlvbiBpbnZva2VkIHBlciBpdGVyYXRpb24uXG4gICAgICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyBgb2JqZWN0YC5cbiAgICAgKiBAc2VlIF8uZm9yT3duXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIGZ1bmN0aW9uIEZvbygpIHtcbiAgICAgKiAgIHRoaXMuYSA9IDE7XG4gICAgICogICB0aGlzLmIgPSAyO1xuICAgICAqIH1cbiAgICAgKlxuICAgICAqIEZvby5wcm90b3R5cGUuYyA9IDM7XG4gICAgICpcbiAgICAgKiBfLmZvck93blJpZ2h0KG5ldyBGb28sIGZ1bmN0aW9uKHZhbHVlLCBrZXkpIHtcbiAgICAgKiAgIGNvbnNvbGUubG9nKGtleSk7XG4gICAgICogfSk7XG4gICAgICogLy8gPT4gTG9ncyAnYicgdGhlbiAnYScgYXNzdW1pbmcgYF8uZm9yT3duYCBsb2dzICdhJyB0aGVuICdiJy5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBmb3JPd25SaWdodChvYmplY3QsIGl0ZXJhdGVlKSB7XG4gICAgICByZXR1cm4gb2JqZWN0ICYmIGJhc2VGb3JPd25SaWdodChvYmplY3QsIGdldEl0ZXJhdGVlKGl0ZXJhdGVlLCAzKSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhbiBhcnJheSBvZiBmdW5jdGlvbiBwcm9wZXJ0eSBuYW1lcyBmcm9tIG93biBlbnVtZXJhYmxlIHByb3BlcnRpZXNcbiAgICAgKiBvZiBgb2JqZWN0YC5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAc2luY2UgMC4xLjBcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBjYXRlZ29yeSBPYmplY3RcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gaW5zcGVjdC5cbiAgICAgKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIGZ1bmN0aW9uIG5hbWVzLlxuICAgICAqIEBzZWUgXy5mdW5jdGlvbnNJblxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBmdW5jdGlvbiBGb28oKSB7XG4gICAgICogICB0aGlzLmEgPSBfLmNvbnN0YW50KCdhJyk7XG4gICAgICogICB0aGlzLmIgPSBfLmNvbnN0YW50KCdiJyk7XG4gICAgICogfVxuICAgICAqXG4gICAgICogRm9vLnByb3RvdHlwZS5jID0gXy5jb25zdGFudCgnYycpO1xuICAgICAqXG4gICAgICogXy5mdW5jdGlvbnMobmV3IEZvbyk7XG4gICAgICogLy8gPT4gWydhJywgJ2InXVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGZ1bmN0aW9ucyhvYmplY3QpIHtcbiAgICAgIHJldHVybiBvYmplY3QgPT0gbnVsbCA/IFtdIDogYmFzZUZ1bmN0aW9ucyhvYmplY3QsIGtleXMob2JqZWN0KSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhbiBhcnJheSBvZiBmdW5jdGlvbiBwcm9wZXJ0eSBuYW1lcyBmcm9tIG93biBhbmQgaW5oZXJpdGVkXG4gICAgICogZW51bWVyYWJsZSBwcm9wZXJ0aWVzIG9mIGBvYmplY3RgLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDQuMC4wXG4gICAgICogQGNhdGVnb3J5IE9iamVjdFxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBpbnNwZWN0LlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgZnVuY3Rpb24gbmFtZXMuXG4gICAgICogQHNlZSBfLmZ1bmN0aW9uc1xuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBmdW5jdGlvbiBGb28oKSB7XG4gICAgICogICB0aGlzLmEgPSBfLmNvbnN0YW50KCdhJyk7XG4gICAgICogICB0aGlzLmIgPSBfLmNvbnN0YW50KCdiJyk7XG4gICAgICogfVxuICAgICAqXG4gICAgICogRm9vLnByb3RvdHlwZS5jID0gXy5jb25zdGFudCgnYycpO1xuICAgICAqXG4gICAgICogXy5mdW5jdGlvbnNJbihuZXcgRm9vKTtcbiAgICAgKiAvLyA9PiBbJ2EnLCAnYicsICdjJ11cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBmdW5jdGlvbnNJbihvYmplY3QpIHtcbiAgICAgIHJldHVybiBvYmplY3QgPT0gbnVsbCA/IFtdIDogYmFzZUZ1bmN0aW9ucyhvYmplY3QsIGtleXNJbihvYmplY3QpKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBHZXRzIHRoZSB2YWx1ZSBhdCBgcGF0aGAgb2YgYG9iamVjdGAuIElmIHRoZSByZXNvbHZlZCB2YWx1ZSBpc1xuICAgICAqIGB1bmRlZmluZWRgLCB0aGUgYGRlZmF1bHRWYWx1ZWAgaXMgcmV0dXJuZWQgaW4gaXRzIHBsYWNlLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDMuNy4wXG4gICAgICogQGNhdGVnb3J5IE9iamVjdFxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBxdWVyeS5cbiAgICAgKiBAcGFyYW0ge0FycmF5fHN0cmluZ30gcGF0aCBUaGUgcGF0aCBvZiB0aGUgcHJvcGVydHkgdG8gZ2V0LlxuICAgICAqIEBwYXJhbSB7Kn0gW2RlZmF1bHRWYWx1ZV0gVGhlIHZhbHVlIHJldHVybmVkIGZvciBgdW5kZWZpbmVkYCByZXNvbHZlZCB2YWx1ZXMuXG4gICAgICogQHJldHVybnMgeyp9IFJldHVybnMgdGhlIHJlc29sdmVkIHZhbHVlLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiB2YXIgb2JqZWN0ID0geyAnYSc6IFt7ICdiJzogeyAnYyc6IDMgfSB9XSB9O1xuICAgICAqXG4gICAgICogXy5nZXQob2JqZWN0LCAnYVswXS5iLmMnKTtcbiAgICAgKiAvLyA9PiAzXG4gICAgICpcbiAgICAgKiBfLmdldChvYmplY3QsIFsnYScsICcwJywgJ2InLCAnYyddKTtcbiAgICAgKiAvLyA9PiAzXG4gICAgICpcbiAgICAgKiBfLmdldChvYmplY3QsICdhLmIuYycsICdkZWZhdWx0Jyk7XG4gICAgICogLy8gPT4gJ2RlZmF1bHQnXG4gICAgICovXG4gICAgZnVuY3Rpb24gZ2V0KG9iamVjdCwgcGF0aCwgZGVmYXVsdFZhbHVlKSB7XG4gICAgICB2YXIgcmVzdWx0ID0gb2JqZWN0ID09IG51bGwgPyB1bmRlZmluZWQgOiBiYXNlR2V0KG9iamVjdCwgcGF0aCk7XG4gICAgICByZXR1cm4gcmVzdWx0ID09PSB1bmRlZmluZWQgPyBkZWZhdWx0VmFsdWUgOiByZXN1bHQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ2hlY2tzIGlmIGBwYXRoYCBpcyBhIGRpcmVjdCBwcm9wZXJ0eSBvZiBgb2JqZWN0YC5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAc2luY2UgMC4xLjBcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBjYXRlZ29yeSBPYmplY3RcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gcXVlcnkuXG4gICAgICogQHBhcmFtIHtBcnJheXxzdHJpbmd9IHBhdGggVGhlIHBhdGggdG8gY2hlY2suXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGBwYXRoYCBleGlzdHMsIGVsc2UgYGZhbHNlYC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogdmFyIG9iamVjdCA9IHsgJ2EnOiB7ICdiJzogMiB9IH07XG4gICAgICogdmFyIG90aGVyID0gXy5jcmVhdGUoeyAnYSc6IF8uY3JlYXRlKHsgJ2InOiAyIH0pIH0pO1xuICAgICAqXG4gICAgICogXy5oYXMob2JqZWN0LCAnYScpO1xuICAgICAqIC8vID0+IHRydWVcbiAgICAgKlxuICAgICAqIF8uaGFzKG9iamVjdCwgJ2EuYicpO1xuICAgICAqIC8vID0+IHRydWVcbiAgICAgKlxuICAgICAqIF8uaGFzKG9iamVjdCwgWydhJywgJ2InXSk7XG4gICAgICogLy8gPT4gdHJ1ZVxuICAgICAqXG4gICAgICogXy5oYXMob3RoZXIsICdhJyk7XG4gICAgICogLy8gPT4gZmFsc2VcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBoYXMob2JqZWN0LCBwYXRoKSB7XG4gICAgICByZXR1cm4gb2JqZWN0ICE9IG51bGwgJiYgaGFzUGF0aChvYmplY3QsIHBhdGgsIGJhc2VIYXMpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENoZWNrcyBpZiBgcGF0aGAgaXMgYSBkaXJlY3Qgb3IgaW5oZXJpdGVkIHByb3BlcnR5IG9mIGBvYmplY3RgLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDQuMC4wXG4gICAgICogQGNhdGVnb3J5IE9iamVjdFxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBxdWVyeS5cbiAgICAgKiBAcGFyYW0ge0FycmF5fHN0cmluZ30gcGF0aCBUaGUgcGF0aCB0byBjaGVjay5cbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHBhdGhgIGV4aXN0cywgZWxzZSBgZmFsc2VgLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiB2YXIgb2JqZWN0ID0gXy5jcmVhdGUoeyAnYSc6IF8uY3JlYXRlKHsgJ2InOiAyIH0pIH0pO1xuICAgICAqXG4gICAgICogXy5oYXNJbihvYmplY3QsICdhJyk7XG4gICAgICogLy8gPT4gdHJ1ZVxuICAgICAqXG4gICAgICogXy5oYXNJbihvYmplY3QsICdhLmInKTtcbiAgICAgKiAvLyA9PiB0cnVlXG4gICAgICpcbiAgICAgKiBfLmhhc0luKG9iamVjdCwgWydhJywgJ2InXSk7XG4gICAgICogLy8gPT4gdHJ1ZVxuICAgICAqXG4gICAgICogXy5oYXNJbihvYmplY3QsICdiJyk7XG4gICAgICogLy8gPT4gZmFsc2VcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBoYXNJbihvYmplY3QsIHBhdGgpIHtcbiAgICAgIHJldHVybiBvYmplY3QgIT0gbnVsbCAmJiBoYXNQYXRoKG9iamVjdCwgcGF0aCwgYmFzZUhhc0luKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGFuIG9iamVjdCBjb21wb3NlZCBvZiB0aGUgaW52ZXJ0ZWQga2V5cyBhbmQgdmFsdWVzIG9mIGBvYmplY3RgLlxuICAgICAqIElmIGBvYmplY3RgIGNvbnRhaW5zIGR1cGxpY2F0ZSB2YWx1ZXMsIHN1YnNlcXVlbnQgdmFsdWVzIG92ZXJ3cml0ZVxuICAgICAqIHByb3BlcnR5IGFzc2lnbm1lbnRzIG9mIHByZXZpb3VzIHZhbHVlcy5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAwLjcuMFxuICAgICAqIEBjYXRlZ29yeSBPYmplY3RcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gaW52ZXJ0LlxuICAgICAqIEByZXR1cm5zIHtPYmplY3R9IFJldHVybnMgdGhlIG5ldyBpbnZlcnRlZCBvYmplY3QuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIHZhciBvYmplY3QgPSB7ICdhJzogMSwgJ2InOiAyLCAnYyc6IDEgfTtcbiAgICAgKlxuICAgICAqIF8uaW52ZXJ0KG9iamVjdCk7XG4gICAgICogLy8gPT4geyAnMSc6ICdjJywgJzInOiAnYicgfVxuICAgICAqL1xuICAgIHZhciBpbnZlcnQgPSBjcmVhdGVJbnZlcnRlcihmdW5jdGlvbihyZXN1bHQsIHZhbHVlLCBrZXkpIHtcbiAgICAgIHJlc3VsdFt2YWx1ZV0gPSBrZXk7XG4gICAgfSwgY29uc3RhbnQoaWRlbnRpdHkpKTtcblxuICAgIC8qKlxuICAgICAqIFRoaXMgbWV0aG9kIGlzIGxpa2UgYF8uaW52ZXJ0YCBleGNlcHQgdGhhdCB0aGUgaW52ZXJ0ZWQgb2JqZWN0IGlzIGdlbmVyYXRlZFxuICAgICAqIGZyb20gdGhlIHJlc3VsdHMgb2YgcnVubmluZyBlYWNoIGVsZW1lbnQgb2YgYG9iamVjdGAgdGhydSBgaXRlcmF0ZWVgLiBUaGVcbiAgICAgKiBjb3JyZXNwb25kaW5nIGludmVydGVkIHZhbHVlIG9mIGVhY2ggaW52ZXJ0ZWQga2V5IGlzIGFuIGFycmF5IG9mIGtleXNcbiAgICAgKiByZXNwb25zaWJsZSBmb3IgZ2VuZXJhdGluZyB0aGUgaW52ZXJ0ZWQgdmFsdWUuIFRoZSBpdGVyYXRlZSBpcyBpbnZva2VkXG4gICAgICogd2l0aCBvbmUgYXJndW1lbnQ6ICh2YWx1ZSkuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgNC4xLjBcbiAgICAgKiBAY2F0ZWdvcnkgT2JqZWN0XG4gICAgICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIGludmVydC5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBbaXRlcmF0ZWU9Xy5pZGVudGl0eV0gVGhlIGl0ZXJhdGVlIGludm9rZWQgcGVyIGVsZW1lbnQuXG4gICAgICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyB0aGUgbmV3IGludmVydGVkIG9iamVjdC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogdmFyIG9iamVjdCA9IHsgJ2EnOiAxLCAnYic6IDIsICdjJzogMSB9O1xuICAgICAqXG4gICAgICogXy5pbnZlcnRCeShvYmplY3QpO1xuICAgICAqIC8vID0+IHsgJzEnOiBbJ2EnLCAnYyddLCAnMic6IFsnYiddIH1cbiAgICAgKlxuICAgICAqIF8uaW52ZXJ0Qnkob2JqZWN0LCBmdW5jdGlvbih2YWx1ZSkge1xuICAgICAqICAgcmV0dXJuICdncm91cCcgKyB2YWx1ZTtcbiAgICAgKiB9KTtcbiAgICAgKiAvLyA9PiB7ICdncm91cDEnOiBbJ2EnLCAnYyddLCAnZ3JvdXAyJzogWydiJ10gfVxuICAgICAqL1xuICAgIHZhciBpbnZlcnRCeSA9IGNyZWF0ZUludmVydGVyKGZ1bmN0aW9uKHJlc3VsdCwgdmFsdWUsIGtleSkge1xuICAgICAgaWYgKGhhc093blByb3BlcnR5LmNhbGwocmVzdWx0LCB2YWx1ZSkpIHtcbiAgICAgICAgcmVzdWx0W3ZhbHVlXS5wdXNoKGtleSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZXN1bHRbdmFsdWVdID0gW2tleV07XG4gICAgICB9XG4gICAgfSwgZ2V0SXRlcmF0ZWUpO1xuXG4gICAgLyoqXG4gICAgICogSW52b2tlcyB0aGUgbWV0aG9kIGF0IGBwYXRoYCBvZiBgb2JqZWN0YC5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSA0LjAuMFxuICAgICAqIEBjYXRlZ29yeSBPYmplY3RcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gcXVlcnkuXG4gICAgICogQHBhcmFtIHtBcnJheXxzdHJpbmd9IHBhdGggVGhlIHBhdGggb2YgdGhlIG1ldGhvZCB0byBpbnZva2UuXG4gICAgICogQHBhcmFtIHsuLi4qfSBbYXJnc10gVGhlIGFyZ3VtZW50cyB0byBpbnZva2UgdGhlIG1ldGhvZCB3aXRoLlxuICAgICAqIEByZXR1cm5zIHsqfSBSZXR1cm5zIHRoZSByZXN1bHQgb2YgdGhlIGludm9rZWQgbWV0aG9kLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiB2YXIgb2JqZWN0ID0geyAnYSc6IFt7ICdiJzogeyAnYyc6IFsxLCAyLCAzLCA0XSB9IH1dIH07XG4gICAgICpcbiAgICAgKiBfLmludm9rZShvYmplY3QsICdhWzBdLmIuYy5zbGljZScsIDEsIDMpO1xuICAgICAqIC8vID0+IFsyLCAzXVxuICAgICAqL1xuICAgIHZhciBpbnZva2UgPSBiYXNlUmVzdChiYXNlSW52b2tlKTtcblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYW4gYXJyYXkgb2YgdGhlIG93biBlbnVtZXJhYmxlIHByb3BlcnR5IG5hbWVzIG9mIGBvYmplY3RgLlxuICAgICAqXG4gICAgICogKipOb3RlOioqIE5vbi1vYmplY3QgdmFsdWVzIGFyZSBjb2VyY2VkIHRvIG9iamVjdHMuIFNlZSB0aGVcbiAgICAgKiBbRVMgc3BlY10oaHR0cDovL2VjbWEtaW50ZXJuYXRpb25hbC5vcmcvZWNtYS0yNjIvNy4wLyNzZWMtb2JqZWN0LmtleXMpXG4gICAgICogZm9yIG1vcmUgZGV0YWlscy5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAc2luY2UgMC4xLjBcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBjYXRlZ29yeSBPYmplY3RcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gcXVlcnkuXG4gICAgICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBhcnJheSBvZiBwcm9wZXJ0eSBuYW1lcy5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogZnVuY3Rpb24gRm9vKCkge1xuICAgICAqICAgdGhpcy5hID0gMTtcbiAgICAgKiAgIHRoaXMuYiA9IDI7XG4gICAgICogfVxuICAgICAqXG4gICAgICogRm9vLnByb3RvdHlwZS5jID0gMztcbiAgICAgKlxuICAgICAqIF8ua2V5cyhuZXcgRm9vKTtcbiAgICAgKiAvLyA9PiBbJ2EnLCAnYiddIChpdGVyYXRpb24gb3JkZXIgaXMgbm90IGd1YXJhbnRlZWQpXG4gICAgICpcbiAgICAgKiBfLmtleXMoJ2hpJyk7XG4gICAgICogLy8gPT4gWycwJywgJzEnXVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGtleXMob2JqZWN0KSB7XG4gICAgICByZXR1cm4gaXNBcnJheUxpa2Uob2JqZWN0KSA/IGFycmF5TGlrZUtleXMob2JqZWN0KSA6IGJhc2VLZXlzKG9iamVjdCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhbiBhcnJheSBvZiB0aGUgb3duIGFuZCBpbmhlcml0ZWQgZW51bWVyYWJsZSBwcm9wZXJ0eSBuYW1lcyBvZiBgb2JqZWN0YC5cbiAgICAgKlxuICAgICAqICoqTm90ZToqKiBOb24tb2JqZWN0IHZhbHVlcyBhcmUgY29lcmNlZCB0byBvYmplY3RzLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDMuMC4wXG4gICAgICogQGNhdGVnb3J5IE9iamVjdFxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBxdWVyeS5cbiAgICAgKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIGFycmF5IG9mIHByb3BlcnR5IG5hbWVzLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBmdW5jdGlvbiBGb28oKSB7XG4gICAgICogICB0aGlzLmEgPSAxO1xuICAgICAqICAgdGhpcy5iID0gMjtcbiAgICAgKiB9XG4gICAgICpcbiAgICAgKiBGb28ucHJvdG90eXBlLmMgPSAzO1xuICAgICAqXG4gICAgICogXy5rZXlzSW4obmV3IEZvbyk7XG4gICAgICogLy8gPT4gWydhJywgJ2InLCAnYyddIChpdGVyYXRpb24gb3JkZXIgaXMgbm90IGd1YXJhbnRlZWQpXG4gICAgICovXG4gICAgZnVuY3Rpb24ga2V5c0luKG9iamVjdCkge1xuICAgICAgcmV0dXJuIGlzQXJyYXlMaWtlKG9iamVjdCkgPyBhcnJheUxpa2VLZXlzKG9iamVjdCwgdHJ1ZSkgOiBiYXNlS2V5c0luKG9iamVjdCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhlIG9wcG9zaXRlIG9mIGBfLm1hcFZhbHVlc2A7IHRoaXMgbWV0aG9kIGNyZWF0ZXMgYW4gb2JqZWN0IHdpdGggdGhlXG4gICAgICogc2FtZSB2YWx1ZXMgYXMgYG9iamVjdGAgYW5kIGtleXMgZ2VuZXJhdGVkIGJ5IHJ1bm5pbmcgZWFjaCBvd24gZW51bWVyYWJsZVxuICAgICAqIHN0cmluZyBrZXllZCBwcm9wZXJ0eSBvZiBgb2JqZWN0YCB0aHJ1IGBpdGVyYXRlZWAuIFRoZSBpdGVyYXRlZSBpcyBpbnZva2VkXG4gICAgICogd2l0aCB0aHJlZSBhcmd1bWVudHM6ICh2YWx1ZSwga2V5LCBvYmplY3QpLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDMuOC4wXG4gICAgICogQGNhdGVnb3J5IE9iamVjdFxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBpdGVyYXRlIG92ZXIuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gW2l0ZXJhdGVlPV8uaWRlbnRpdHldIFRoZSBmdW5jdGlvbiBpbnZva2VkIHBlciBpdGVyYXRpb24uXG4gICAgICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyB0aGUgbmV3IG1hcHBlZCBvYmplY3QuXG4gICAgICogQHNlZSBfLm1hcFZhbHVlc1xuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLm1hcEtleXMoeyAnYSc6IDEsICdiJzogMiB9LCBmdW5jdGlvbih2YWx1ZSwga2V5KSB7XG4gICAgICogICByZXR1cm4ga2V5ICsgdmFsdWU7XG4gICAgICogfSk7XG4gICAgICogLy8gPT4geyAnYTEnOiAxLCAnYjInOiAyIH1cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBtYXBLZXlzKG9iamVjdCwgaXRlcmF0ZWUpIHtcbiAgICAgIHZhciByZXN1bHQgPSB7fTtcbiAgICAgIGl0ZXJhdGVlID0gZ2V0SXRlcmF0ZWUoaXRlcmF0ZWUsIDMpO1xuXG4gICAgICBiYXNlRm9yT3duKG9iamVjdCwgZnVuY3Rpb24odmFsdWUsIGtleSwgb2JqZWN0KSB7XG4gICAgICAgIGJhc2VBc3NpZ25WYWx1ZShyZXN1bHQsIGl0ZXJhdGVlKHZhbHVlLCBrZXksIG9iamVjdCksIHZhbHVlKTtcbiAgICAgIH0pO1xuICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGFuIG9iamVjdCB3aXRoIHRoZSBzYW1lIGtleXMgYXMgYG9iamVjdGAgYW5kIHZhbHVlcyBnZW5lcmF0ZWRcbiAgICAgKiBieSBydW5uaW5nIGVhY2ggb3duIGVudW1lcmFibGUgc3RyaW5nIGtleWVkIHByb3BlcnR5IG9mIGBvYmplY3RgIHRocnVcbiAgICAgKiBgaXRlcmF0ZWVgLiBUaGUgaXRlcmF0ZWUgaXMgaW52b2tlZCB3aXRoIHRocmVlIGFyZ3VtZW50czpcbiAgICAgKiAodmFsdWUsIGtleSwgb2JqZWN0KS5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAyLjQuMFxuICAgICAqIEBjYXRlZ29yeSBPYmplY3RcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gaXRlcmF0ZSBvdmVyLlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IFtpdGVyYXRlZT1fLmlkZW50aXR5XSBUaGUgZnVuY3Rpb24gaW52b2tlZCBwZXIgaXRlcmF0aW9uLlxuICAgICAqIEByZXR1cm5zIHtPYmplY3R9IFJldHVybnMgdGhlIG5ldyBtYXBwZWQgb2JqZWN0LlxuICAgICAqIEBzZWUgXy5tYXBLZXlzXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIHZhciB1c2VycyA9IHtcbiAgICAgKiAgICdmcmVkJzogICAgeyAndXNlcic6ICdmcmVkJywgICAgJ2FnZSc6IDQwIH0sXG4gICAgICogICAncGViYmxlcyc6IHsgJ3VzZXInOiAncGViYmxlcycsICdhZ2UnOiAxIH1cbiAgICAgKiB9O1xuICAgICAqXG4gICAgICogXy5tYXBWYWx1ZXModXNlcnMsIGZ1bmN0aW9uKG8pIHsgcmV0dXJuIG8uYWdlOyB9KTtcbiAgICAgKiAvLyA9PiB7ICdmcmVkJzogNDAsICdwZWJibGVzJzogMSB9IChpdGVyYXRpb24gb3JkZXIgaXMgbm90IGd1YXJhbnRlZWQpXG4gICAgICpcbiAgICAgKiAvLyBUaGUgYF8ucHJvcGVydHlgIGl0ZXJhdGVlIHNob3J0aGFuZC5cbiAgICAgKiBfLm1hcFZhbHVlcyh1c2VycywgJ2FnZScpO1xuICAgICAqIC8vID0+IHsgJ2ZyZWQnOiA0MCwgJ3BlYmJsZXMnOiAxIH0gKGl0ZXJhdGlvbiBvcmRlciBpcyBub3QgZ3VhcmFudGVlZClcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBtYXBWYWx1ZXMob2JqZWN0LCBpdGVyYXRlZSkge1xuICAgICAgdmFyIHJlc3VsdCA9IHt9O1xuICAgICAgaXRlcmF0ZWUgPSBnZXRJdGVyYXRlZShpdGVyYXRlZSwgMyk7XG5cbiAgICAgIGJhc2VGb3JPd24ob2JqZWN0LCBmdW5jdGlvbih2YWx1ZSwga2V5LCBvYmplY3QpIHtcbiAgICAgICAgYmFzZUFzc2lnblZhbHVlKHJlc3VsdCwga2V5LCBpdGVyYXRlZSh2YWx1ZSwga2V5LCBvYmplY3QpKTtcbiAgICAgIH0pO1xuICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGlzIG1ldGhvZCBpcyBsaWtlIGBfLmFzc2lnbmAgZXhjZXB0IHRoYXQgaXQgcmVjdXJzaXZlbHkgbWVyZ2VzIG93biBhbmRcbiAgICAgKiBpbmhlcml0ZWQgZW51bWVyYWJsZSBzdHJpbmcga2V5ZWQgcHJvcGVydGllcyBvZiBzb3VyY2Ugb2JqZWN0cyBpbnRvIHRoZVxuICAgICAqIGRlc3RpbmF0aW9uIG9iamVjdC4gU291cmNlIHByb3BlcnRpZXMgdGhhdCByZXNvbHZlIHRvIGB1bmRlZmluZWRgIGFyZVxuICAgICAqIHNraXBwZWQgaWYgYSBkZXN0aW5hdGlvbiB2YWx1ZSBleGlzdHMuIEFycmF5IGFuZCBwbGFpbiBvYmplY3QgcHJvcGVydGllc1xuICAgICAqIGFyZSBtZXJnZWQgcmVjdXJzaXZlbHkuIE90aGVyIG9iamVjdHMgYW5kIHZhbHVlIHR5cGVzIGFyZSBvdmVycmlkZGVuIGJ5XG4gICAgICogYXNzaWdubWVudC4gU291cmNlIG9iamVjdHMgYXJlIGFwcGxpZWQgZnJvbSBsZWZ0IHRvIHJpZ2h0LiBTdWJzZXF1ZW50XG4gICAgICogc291cmNlcyBvdmVyd3JpdGUgcHJvcGVydHkgYXNzaWdubWVudHMgb2YgcHJldmlvdXMgc291cmNlcy5cbiAgICAgKlxuICAgICAqICoqTm90ZToqKiBUaGlzIG1ldGhvZCBtdXRhdGVzIGBvYmplY3RgLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDAuNS4wXG4gICAgICogQGNhdGVnb3J5IE9iamVjdFxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIGRlc3RpbmF0aW9uIG9iamVjdC5cbiAgICAgKiBAcGFyYW0gey4uLk9iamVjdH0gW3NvdXJjZXNdIFRoZSBzb3VyY2Ugb2JqZWN0cy5cbiAgICAgKiBAcmV0dXJucyB7T2JqZWN0fSBSZXR1cm5zIGBvYmplY3RgLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiB2YXIgb2JqZWN0ID0ge1xuICAgICAqICAgJ2EnOiBbeyAnYic6IDIgfSwgeyAnZCc6IDQgfV1cbiAgICAgKiB9O1xuICAgICAqXG4gICAgICogdmFyIG90aGVyID0ge1xuICAgICAqICAgJ2EnOiBbeyAnYyc6IDMgfSwgeyAnZSc6IDUgfV1cbiAgICAgKiB9O1xuICAgICAqXG4gICAgICogXy5tZXJnZShvYmplY3QsIG90aGVyKTtcbiAgICAgKiAvLyA9PiB7ICdhJzogW3sgJ2InOiAyLCAnYyc6IDMgfSwgeyAnZCc6IDQsICdlJzogNSB9XSB9XG4gICAgICovXG4gICAgdmFyIG1lcmdlID0gY3JlYXRlQXNzaWduZXIoZnVuY3Rpb24ob2JqZWN0LCBzb3VyY2UsIHNyY0luZGV4KSB7XG4gICAgICBiYXNlTWVyZ2Uob2JqZWN0LCBzb3VyY2UsIHNyY0luZGV4KTtcbiAgICB9KTtcblxuICAgIC8qKlxuICAgICAqIFRoaXMgbWV0aG9kIGlzIGxpa2UgYF8ubWVyZ2VgIGV4Y2VwdCB0aGF0IGl0IGFjY2VwdHMgYGN1c3RvbWl6ZXJgIHdoaWNoXG4gICAgICogaXMgaW52b2tlZCB0byBwcm9kdWNlIHRoZSBtZXJnZWQgdmFsdWVzIG9mIHRoZSBkZXN0aW5hdGlvbiBhbmQgc291cmNlXG4gICAgICogcHJvcGVydGllcy4gSWYgYGN1c3RvbWl6ZXJgIHJldHVybnMgYHVuZGVmaW5lZGAsIG1lcmdpbmcgaXMgaGFuZGxlZCBieSB0aGVcbiAgICAgKiBtZXRob2QgaW5zdGVhZC4gVGhlIGBjdXN0b21pemVyYCBpcyBpbnZva2VkIHdpdGggc2l4IGFyZ3VtZW50czpcbiAgICAgKiAob2JqVmFsdWUsIHNyY1ZhbHVlLCBrZXksIG9iamVjdCwgc291cmNlLCBzdGFjaykuXG4gICAgICpcbiAgICAgKiAqKk5vdGU6KiogVGhpcyBtZXRob2QgbXV0YXRlcyBgb2JqZWN0YC5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSA0LjAuMFxuICAgICAqIEBjYXRlZ29yeSBPYmplY3RcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBkZXN0aW5hdGlvbiBvYmplY3QuXG4gICAgICogQHBhcmFtIHsuLi5PYmplY3R9IHNvdXJjZXMgVGhlIHNvdXJjZSBvYmplY3RzLlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IGN1c3RvbWl6ZXIgVGhlIGZ1bmN0aW9uIHRvIGN1c3RvbWl6ZSBhc3NpZ25lZCB2YWx1ZXMuXG4gICAgICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyBgb2JqZWN0YC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogZnVuY3Rpb24gY3VzdG9taXplcihvYmpWYWx1ZSwgc3JjVmFsdWUpIHtcbiAgICAgKiAgIGlmIChfLmlzQXJyYXkob2JqVmFsdWUpKSB7XG4gICAgICogICAgIHJldHVybiBvYmpWYWx1ZS5jb25jYXQoc3JjVmFsdWUpO1xuICAgICAqICAgfVxuICAgICAqIH1cbiAgICAgKlxuICAgICAqIHZhciBvYmplY3QgPSB7ICdhJzogWzFdLCAnYic6IFsyXSB9O1xuICAgICAqIHZhciBvdGhlciA9IHsgJ2EnOiBbM10sICdiJzogWzRdIH07XG4gICAgICpcbiAgICAgKiBfLm1lcmdlV2l0aChvYmplY3QsIG90aGVyLCBjdXN0b21pemVyKTtcbiAgICAgKiAvLyA9PiB7ICdhJzogWzEsIDNdLCAnYic6IFsyLCA0XSB9XG4gICAgICovXG4gICAgdmFyIG1lcmdlV2l0aCA9IGNyZWF0ZUFzc2lnbmVyKGZ1bmN0aW9uKG9iamVjdCwgc291cmNlLCBzcmNJbmRleCwgY3VzdG9taXplcikge1xuICAgICAgYmFzZU1lcmdlKG9iamVjdCwgc291cmNlLCBzcmNJbmRleCwgY3VzdG9taXplcik7XG4gICAgfSk7XG5cbiAgICAvKipcbiAgICAgKiBUaGUgb3Bwb3NpdGUgb2YgYF8ucGlja2A7IHRoaXMgbWV0aG9kIGNyZWF0ZXMgYW4gb2JqZWN0IGNvbXBvc2VkIG9mIHRoZVxuICAgICAqIG93biBhbmQgaW5oZXJpdGVkIGVudW1lcmFibGUgcHJvcGVydHkgcGF0aHMgb2YgYG9iamVjdGAgdGhhdCBhcmUgbm90IG9taXR0ZWQuXG4gICAgICpcbiAgICAgKiAqKk5vdGU6KiogVGhpcyBtZXRob2QgaXMgY29uc2lkZXJhYmx5IHNsb3dlciB0aGFuIGBfLnBpY2tgLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBzaW5jZSAwLjEuMFxuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQGNhdGVnb3J5IE9iamVjdFxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIHNvdXJjZSBvYmplY3QuXG4gICAgICogQHBhcmFtIHsuLi4oc3RyaW5nfHN0cmluZ1tdKX0gW3BhdGhzXSBUaGUgcHJvcGVydHkgcGF0aHMgdG8gb21pdC5cbiAgICAgKiBAcmV0dXJucyB7T2JqZWN0fSBSZXR1cm5zIHRoZSBuZXcgb2JqZWN0LlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiB2YXIgb2JqZWN0ID0geyAnYSc6IDEsICdiJzogJzInLCAnYyc6IDMgfTtcbiAgICAgKlxuICAgICAqIF8ub21pdChvYmplY3QsIFsnYScsICdjJ10pO1xuICAgICAqIC8vID0+IHsgJ2InOiAnMicgfVxuICAgICAqL1xuICAgIHZhciBvbWl0ID0gZmxhdFJlc3QoZnVuY3Rpb24ob2JqZWN0LCBwYXRocykge1xuICAgICAgdmFyIHJlc3VsdCA9IHt9O1xuICAgICAgaWYgKG9iamVjdCA9PSBudWxsKSB7XG4gICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgICB9XG4gICAgICB2YXIgaXNEZWVwID0gZmFsc2U7XG4gICAgICBwYXRocyA9IGFycmF5TWFwKHBhdGhzLCBmdW5jdGlvbihwYXRoKSB7XG4gICAgICAgIHBhdGggPSBjYXN0UGF0aChwYXRoLCBvYmplY3QpO1xuICAgICAgICBpc0RlZXAgfHwgKGlzRGVlcCA9IHBhdGgubGVuZ3RoID4gMSk7XG4gICAgICAgIHJldHVybiBwYXRoO1xuICAgICAgfSk7XG4gICAgICBjb3B5T2JqZWN0KG9iamVjdCwgZ2V0QWxsS2V5c0luKG9iamVjdCksIHJlc3VsdCk7XG4gICAgICBpZiAoaXNEZWVwKSB7XG4gICAgICAgIHJlc3VsdCA9IGJhc2VDbG9uZShyZXN1bHQsIENMT05FX0RFRVBfRkxBRyB8IENMT05FX0ZMQVRfRkxBRyB8IENMT05FX1NZTUJPTFNfRkxBRywgY3VzdG9tT21pdENsb25lKTtcbiAgICAgIH1cbiAgICAgIHZhciBsZW5ndGggPSBwYXRocy5sZW5ndGg7XG4gICAgICB3aGlsZSAobGVuZ3RoLS0pIHtcbiAgICAgICAgYmFzZVVuc2V0KHJlc3VsdCwgcGF0aHNbbGVuZ3RoXSk7XG4gICAgICB9XG4gICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH0pO1xuXG4gICAgLyoqXG4gICAgICogVGhlIG9wcG9zaXRlIG9mIGBfLnBpY2tCeWA7IHRoaXMgbWV0aG9kIGNyZWF0ZXMgYW4gb2JqZWN0IGNvbXBvc2VkIG9mXG4gICAgICogdGhlIG93biBhbmQgaW5oZXJpdGVkIGVudW1lcmFibGUgc3RyaW5nIGtleWVkIHByb3BlcnRpZXMgb2YgYG9iamVjdGAgdGhhdFxuICAgICAqIGBwcmVkaWNhdGVgIGRvZXNuJ3QgcmV0dXJuIHRydXRoeSBmb3IuIFRoZSBwcmVkaWNhdGUgaXMgaW52b2tlZCB3aXRoIHR3b1xuICAgICAqIGFyZ3VtZW50czogKHZhbHVlLCBrZXkpLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDQuMC4wXG4gICAgICogQGNhdGVnb3J5IE9iamVjdFxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIHNvdXJjZSBvYmplY3QuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gW3ByZWRpY2F0ZT1fLmlkZW50aXR5XSBUaGUgZnVuY3Rpb24gaW52b2tlZCBwZXIgcHJvcGVydHkuXG4gICAgICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyB0aGUgbmV3IG9iamVjdC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogdmFyIG9iamVjdCA9IHsgJ2EnOiAxLCAnYic6ICcyJywgJ2MnOiAzIH07XG4gICAgICpcbiAgICAgKiBfLm9taXRCeShvYmplY3QsIF8uaXNOdW1iZXIpO1xuICAgICAqIC8vID0+IHsgJ2InOiAnMicgfVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIG9taXRCeShvYmplY3QsIHByZWRpY2F0ZSkge1xuICAgICAgcmV0dXJuIHBpY2tCeShvYmplY3QsIG5lZ2F0ZShnZXRJdGVyYXRlZShwcmVkaWNhdGUpKSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhbiBvYmplY3QgY29tcG9zZWQgb2YgdGhlIHBpY2tlZCBgb2JqZWN0YCBwcm9wZXJ0aWVzLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBzaW5jZSAwLjEuMFxuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQGNhdGVnb3J5IE9iamVjdFxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIHNvdXJjZSBvYmplY3QuXG4gICAgICogQHBhcmFtIHsuLi4oc3RyaW5nfHN0cmluZ1tdKX0gW3BhdGhzXSBUaGUgcHJvcGVydHkgcGF0aHMgdG8gcGljay5cbiAgICAgKiBAcmV0dXJucyB7T2JqZWN0fSBSZXR1cm5zIHRoZSBuZXcgb2JqZWN0LlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiB2YXIgb2JqZWN0ID0geyAnYSc6IDEsICdiJzogJzInLCAnYyc6IDMgfTtcbiAgICAgKlxuICAgICAqIF8ucGljayhvYmplY3QsIFsnYScsICdjJ10pO1xuICAgICAqIC8vID0+IHsgJ2EnOiAxLCAnYyc6IDMgfVxuICAgICAqL1xuICAgIHZhciBwaWNrID0gZmxhdFJlc3QoZnVuY3Rpb24ob2JqZWN0LCBwYXRocykge1xuICAgICAgcmV0dXJuIG9iamVjdCA9PSBudWxsID8ge30gOiBiYXNlUGljayhvYmplY3QsIHBhdGhzKTtcbiAgICB9KTtcblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYW4gb2JqZWN0IGNvbXBvc2VkIG9mIHRoZSBgb2JqZWN0YCBwcm9wZXJ0aWVzIGBwcmVkaWNhdGVgIHJldHVybnNcbiAgICAgKiB0cnV0aHkgZm9yLiBUaGUgcHJlZGljYXRlIGlzIGludm9rZWQgd2l0aCB0d28gYXJndW1lbnRzOiAodmFsdWUsIGtleSkuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgNC4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgT2JqZWN0XG4gICAgICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgc291cmNlIG9iamVjdC5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBbcHJlZGljYXRlPV8uaWRlbnRpdHldIFRoZSBmdW5jdGlvbiBpbnZva2VkIHBlciBwcm9wZXJ0eS5cbiAgICAgKiBAcmV0dXJucyB7T2JqZWN0fSBSZXR1cm5zIHRoZSBuZXcgb2JqZWN0LlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiB2YXIgb2JqZWN0ID0geyAnYSc6IDEsICdiJzogJzInLCAnYyc6IDMgfTtcbiAgICAgKlxuICAgICAqIF8ucGlja0J5KG9iamVjdCwgXy5pc051bWJlcik7XG4gICAgICogLy8gPT4geyAnYSc6IDEsICdjJzogMyB9XG4gICAgICovXG4gICAgZnVuY3Rpb24gcGlja0J5KG9iamVjdCwgcHJlZGljYXRlKSB7XG4gICAgICBpZiAob2JqZWN0ID09IG51bGwpIHtcbiAgICAgICAgcmV0dXJuIHt9O1xuICAgICAgfVxuICAgICAgdmFyIHByb3BzID0gYXJyYXlNYXAoZ2V0QWxsS2V5c0luKG9iamVjdCksIGZ1bmN0aW9uKHByb3ApIHtcbiAgICAgICAgcmV0dXJuIFtwcm9wXTtcbiAgICAgIH0pO1xuICAgICAgcHJlZGljYXRlID0gZ2V0SXRlcmF0ZWUocHJlZGljYXRlKTtcbiAgICAgIHJldHVybiBiYXNlUGlja0J5KG9iamVjdCwgcHJvcHMsIGZ1bmN0aW9uKHZhbHVlLCBwYXRoKSB7XG4gICAgICAgIHJldHVybiBwcmVkaWNhdGUodmFsdWUsIHBhdGhbMF0pO1xuICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhpcyBtZXRob2QgaXMgbGlrZSBgXy5nZXRgIGV4Y2VwdCB0aGF0IGlmIHRoZSByZXNvbHZlZCB2YWx1ZSBpcyBhXG4gICAgICogZnVuY3Rpb24gaXQncyBpbnZva2VkIHdpdGggdGhlIGB0aGlzYCBiaW5kaW5nIG9mIGl0cyBwYXJlbnQgb2JqZWN0IGFuZFxuICAgICAqIGl0cyByZXN1bHQgaXMgcmV0dXJuZWQuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQHNpbmNlIDAuMS4wXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAY2F0ZWdvcnkgT2JqZWN0XG4gICAgICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIHF1ZXJ5LlxuICAgICAqIEBwYXJhbSB7QXJyYXl8c3RyaW5nfSBwYXRoIFRoZSBwYXRoIG9mIHRoZSBwcm9wZXJ0eSB0byByZXNvbHZlLlxuICAgICAqIEBwYXJhbSB7Kn0gW2RlZmF1bHRWYWx1ZV0gVGhlIHZhbHVlIHJldHVybmVkIGZvciBgdW5kZWZpbmVkYCByZXNvbHZlZCB2YWx1ZXMuXG4gICAgICogQHJldHVybnMgeyp9IFJldHVybnMgdGhlIHJlc29sdmVkIHZhbHVlLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiB2YXIgb2JqZWN0ID0geyAnYSc6IFt7ICdiJzogeyAnYzEnOiAzLCAnYzInOiBfLmNvbnN0YW50KDQpIH0gfV0gfTtcbiAgICAgKlxuICAgICAqIF8ucmVzdWx0KG9iamVjdCwgJ2FbMF0uYi5jMScpO1xuICAgICAqIC8vID0+IDNcbiAgICAgKlxuICAgICAqIF8ucmVzdWx0KG9iamVjdCwgJ2FbMF0uYi5jMicpO1xuICAgICAqIC8vID0+IDRcbiAgICAgKlxuICAgICAqIF8ucmVzdWx0KG9iamVjdCwgJ2FbMF0uYi5jMycsICdkZWZhdWx0Jyk7XG4gICAgICogLy8gPT4gJ2RlZmF1bHQnXG4gICAgICpcbiAgICAgKiBfLnJlc3VsdChvYmplY3QsICdhWzBdLmIuYzMnLCBfLmNvbnN0YW50KCdkZWZhdWx0JykpO1xuICAgICAqIC8vID0+ICdkZWZhdWx0J1xuICAgICAqL1xuICAgIGZ1bmN0aW9uIHJlc3VsdChvYmplY3QsIHBhdGgsIGRlZmF1bHRWYWx1ZSkge1xuICAgICAgcGF0aCA9IGNhc3RQYXRoKHBhdGgsIG9iamVjdCk7XG5cbiAgICAgIHZhciBpbmRleCA9IC0xLFxuICAgICAgICAgIGxlbmd0aCA9IHBhdGgubGVuZ3RoO1xuXG4gICAgICAvLyBFbnN1cmUgdGhlIGxvb3AgaXMgZW50ZXJlZCB3aGVuIHBhdGggaXMgZW1wdHkuXG4gICAgICBpZiAoIWxlbmd0aCkge1xuICAgICAgICBsZW5ndGggPSAxO1xuICAgICAgICBvYmplY3QgPSB1bmRlZmluZWQ7XG4gICAgICB9XG4gICAgICB3aGlsZSAoKytpbmRleCA8IGxlbmd0aCkge1xuICAgICAgICB2YXIgdmFsdWUgPSBvYmplY3QgPT0gbnVsbCA/IHVuZGVmaW5lZCA6IG9iamVjdFt0b0tleShwYXRoW2luZGV4XSldO1xuICAgICAgICBpZiAodmFsdWUgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgIGluZGV4ID0gbGVuZ3RoO1xuICAgICAgICAgIHZhbHVlID0gZGVmYXVsdFZhbHVlO1xuICAgICAgICB9XG4gICAgICAgIG9iamVjdCA9IGlzRnVuY3Rpb24odmFsdWUpID8gdmFsdWUuY2FsbChvYmplY3QpIDogdmFsdWU7XG4gICAgICB9XG4gICAgICByZXR1cm4gb2JqZWN0O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFNldHMgdGhlIHZhbHVlIGF0IGBwYXRoYCBvZiBgb2JqZWN0YC4gSWYgYSBwb3J0aW9uIG9mIGBwYXRoYCBkb2Vzbid0IGV4aXN0LFxuICAgICAqIGl0J3MgY3JlYXRlZC4gQXJyYXlzIGFyZSBjcmVhdGVkIGZvciBtaXNzaW5nIGluZGV4IHByb3BlcnRpZXMgd2hpbGUgb2JqZWN0c1xuICAgICAqIGFyZSBjcmVhdGVkIGZvciBhbGwgb3RoZXIgbWlzc2luZyBwcm9wZXJ0aWVzLiBVc2UgYF8uc2V0V2l0aGAgdG8gY3VzdG9taXplXG4gICAgICogYHBhdGhgIGNyZWF0aW9uLlxuICAgICAqXG4gICAgICogKipOb3RlOioqIFRoaXMgbWV0aG9kIG11dGF0ZXMgYG9iamVjdGAuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMy43LjBcbiAgICAgKiBAY2F0ZWdvcnkgT2JqZWN0XG4gICAgICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIG1vZGlmeS5cbiAgICAgKiBAcGFyYW0ge0FycmF5fHN0cmluZ30gcGF0aCBUaGUgcGF0aCBvZiB0aGUgcHJvcGVydHkgdG8gc2V0LlxuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIHNldC5cbiAgICAgKiBAcmV0dXJucyB7T2JqZWN0fSBSZXR1cm5zIGBvYmplY3RgLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiB2YXIgb2JqZWN0ID0geyAnYSc6IFt7ICdiJzogeyAnYyc6IDMgfSB9XSB9O1xuICAgICAqXG4gICAgICogXy5zZXQob2JqZWN0LCAnYVswXS5iLmMnLCA0KTtcbiAgICAgKiBjb25zb2xlLmxvZyhvYmplY3QuYVswXS5iLmMpO1xuICAgICAqIC8vID0+IDRcbiAgICAgKlxuICAgICAqIF8uc2V0KG9iamVjdCwgWyd4JywgJzAnLCAneScsICd6J10sIDUpO1xuICAgICAqIGNvbnNvbGUubG9nKG9iamVjdC54WzBdLnkueik7XG4gICAgICogLy8gPT4gNVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIHNldChvYmplY3QsIHBhdGgsIHZhbHVlKSB7XG4gICAgICByZXR1cm4gb2JqZWN0ID09IG51bGwgPyBvYmplY3QgOiBiYXNlU2V0KG9iamVjdCwgcGF0aCwgdmFsdWUpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoaXMgbWV0aG9kIGlzIGxpa2UgYF8uc2V0YCBleGNlcHQgdGhhdCBpdCBhY2NlcHRzIGBjdXN0b21pemVyYCB3aGljaCBpc1xuICAgICAqIGludm9rZWQgdG8gcHJvZHVjZSB0aGUgb2JqZWN0cyBvZiBgcGF0aGAuICBJZiBgY3VzdG9taXplcmAgcmV0dXJucyBgdW5kZWZpbmVkYFxuICAgICAqIHBhdGggY3JlYXRpb24gaXMgaGFuZGxlZCBieSB0aGUgbWV0aG9kIGluc3RlYWQuIFRoZSBgY3VzdG9taXplcmAgaXMgaW52b2tlZFxuICAgICAqIHdpdGggdGhyZWUgYXJndW1lbnRzOiAobnNWYWx1ZSwga2V5LCBuc09iamVjdCkuXG4gICAgICpcbiAgICAgKiAqKk5vdGU6KiogVGhpcyBtZXRob2QgbXV0YXRlcyBgb2JqZWN0YC5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSA0LjAuMFxuICAgICAqIEBjYXRlZ29yeSBPYmplY3RcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gbW9kaWZ5LlxuICAgICAqIEBwYXJhbSB7QXJyYXl8c3RyaW5nfSBwYXRoIFRoZSBwYXRoIG9mIHRoZSBwcm9wZXJ0eSB0byBzZXQuXG4gICAgICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gc2V0LlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IFtjdXN0b21pemVyXSBUaGUgZnVuY3Rpb24gdG8gY3VzdG9taXplIGFzc2lnbmVkIHZhbHVlcy5cbiAgICAgKiBAcmV0dXJucyB7T2JqZWN0fSBSZXR1cm5zIGBvYmplY3RgLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiB2YXIgb2JqZWN0ID0ge307XG4gICAgICpcbiAgICAgKiBfLnNldFdpdGgob2JqZWN0LCAnWzBdWzFdJywgJ2EnLCBPYmplY3QpO1xuICAgICAqIC8vID0+IHsgJzAnOiB7ICcxJzogJ2EnIH0gfVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIHNldFdpdGgob2JqZWN0LCBwYXRoLCB2YWx1ZSwgY3VzdG9taXplcikge1xuICAgICAgY3VzdG9taXplciA9IHR5cGVvZiBjdXN0b21pemVyID09ICdmdW5jdGlvbicgPyBjdXN0b21pemVyIDogdW5kZWZpbmVkO1xuICAgICAgcmV0dXJuIG9iamVjdCA9PSBudWxsID8gb2JqZWN0IDogYmFzZVNldChvYmplY3QsIHBhdGgsIHZhbHVlLCBjdXN0b21pemVyKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGFuIGFycmF5IG9mIG93biBlbnVtZXJhYmxlIHN0cmluZyBrZXllZC12YWx1ZSBwYWlycyBmb3IgYG9iamVjdGBcbiAgICAgKiB3aGljaCBjYW4gYmUgY29uc3VtZWQgYnkgYF8uZnJvbVBhaXJzYC4gSWYgYG9iamVjdGAgaXMgYSBtYXAgb3Igc2V0LCBpdHNcbiAgICAgKiBlbnRyaWVzIGFyZSByZXR1cm5lZC5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSA0LjAuMFxuICAgICAqIEBhbGlhcyBlbnRyaWVzXG4gICAgICogQGNhdGVnb3J5IE9iamVjdFxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBxdWVyeS5cbiAgICAgKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIGtleS12YWx1ZSBwYWlycy5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogZnVuY3Rpb24gRm9vKCkge1xuICAgICAqICAgdGhpcy5hID0gMTtcbiAgICAgKiAgIHRoaXMuYiA9IDI7XG4gICAgICogfVxuICAgICAqXG4gICAgICogRm9vLnByb3RvdHlwZS5jID0gMztcbiAgICAgKlxuICAgICAqIF8udG9QYWlycyhuZXcgRm9vKTtcbiAgICAgKiAvLyA9PiBbWydhJywgMV0sIFsnYicsIDJdXSAoaXRlcmF0aW9uIG9yZGVyIGlzIG5vdCBndWFyYW50ZWVkKVxuICAgICAqL1xuICAgIHZhciB0b1BhaXJzID0gY3JlYXRlVG9QYWlycyhrZXlzKTtcblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYW4gYXJyYXkgb2Ygb3duIGFuZCBpbmhlcml0ZWQgZW51bWVyYWJsZSBzdHJpbmcga2V5ZWQtdmFsdWUgcGFpcnNcbiAgICAgKiBmb3IgYG9iamVjdGAgd2hpY2ggY2FuIGJlIGNvbnN1bWVkIGJ5IGBfLmZyb21QYWlyc2AuIElmIGBvYmplY3RgIGlzIGEgbWFwXG4gICAgICogb3Igc2V0LCBpdHMgZW50cmllcyBhcmUgcmV0dXJuZWQuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgNC4wLjBcbiAgICAgKiBAYWxpYXMgZW50cmllc0luXG4gICAgICogQGNhdGVnb3J5IE9iamVjdFxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBxdWVyeS5cbiAgICAgKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIGtleS12YWx1ZSBwYWlycy5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogZnVuY3Rpb24gRm9vKCkge1xuICAgICAqICAgdGhpcy5hID0gMTtcbiAgICAgKiAgIHRoaXMuYiA9IDI7XG4gICAgICogfVxuICAgICAqXG4gICAgICogRm9vLnByb3RvdHlwZS5jID0gMztcbiAgICAgKlxuICAgICAqIF8udG9QYWlyc0luKG5ldyBGb28pO1xuICAgICAqIC8vID0+IFtbJ2EnLCAxXSwgWydiJywgMl0sIFsnYycsIDNdXSAoaXRlcmF0aW9uIG9yZGVyIGlzIG5vdCBndWFyYW50ZWVkKVxuICAgICAqL1xuICAgIHZhciB0b1BhaXJzSW4gPSBjcmVhdGVUb1BhaXJzKGtleXNJbik7XG5cbiAgICAvKipcbiAgICAgKiBBbiBhbHRlcm5hdGl2ZSB0byBgXy5yZWR1Y2VgOyB0aGlzIG1ldGhvZCB0cmFuc2Zvcm1zIGBvYmplY3RgIHRvIGEgbmV3XG4gICAgICogYGFjY3VtdWxhdG9yYCBvYmplY3Qgd2hpY2ggaXMgdGhlIHJlc3VsdCBvZiBydW5uaW5nIGVhY2ggb2YgaXRzIG93blxuICAgICAqIGVudW1lcmFibGUgc3RyaW5nIGtleWVkIHByb3BlcnRpZXMgdGhydSBgaXRlcmF0ZWVgLCB3aXRoIGVhY2ggaW52b2NhdGlvblxuICAgICAqIHBvdGVudGlhbGx5IG11dGF0aW5nIHRoZSBgYWNjdW11bGF0b3JgIG9iamVjdC4gSWYgYGFjY3VtdWxhdG9yYCBpcyBub3RcbiAgICAgKiBwcm92aWRlZCwgYSBuZXcgb2JqZWN0IHdpdGggdGhlIHNhbWUgYFtbUHJvdG90eXBlXV1gIHdpbGwgYmUgdXNlZC4gVGhlXG4gICAgICogaXRlcmF0ZWUgaXMgaW52b2tlZCB3aXRoIGZvdXIgYXJndW1lbnRzOiAoYWNjdW11bGF0b3IsIHZhbHVlLCBrZXksIG9iamVjdCkuXG4gICAgICogSXRlcmF0ZWUgZnVuY3Rpb25zIG1heSBleGl0IGl0ZXJhdGlvbiBlYXJseSBieSBleHBsaWNpdGx5IHJldHVybmluZyBgZmFsc2VgLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDEuMy4wXG4gICAgICogQGNhdGVnb3J5IE9iamVjdFxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBpdGVyYXRlIG92ZXIuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gW2l0ZXJhdGVlPV8uaWRlbnRpdHldIFRoZSBmdW5jdGlvbiBpbnZva2VkIHBlciBpdGVyYXRpb24uXG4gICAgICogQHBhcmFtIHsqfSBbYWNjdW11bGF0b3JdIFRoZSBjdXN0b20gYWNjdW11bGF0b3IgdmFsdWUuXG4gICAgICogQHJldHVybnMgeyp9IFJldHVybnMgdGhlIGFjY3VtdWxhdGVkIHZhbHVlLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLnRyYW5zZm9ybShbMiwgMywgNF0sIGZ1bmN0aW9uKHJlc3VsdCwgbikge1xuICAgICAqICAgcmVzdWx0LnB1c2gobiAqPSBuKTtcbiAgICAgKiAgIHJldHVybiBuICUgMiA9PSAwO1xuICAgICAqIH0sIFtdKTtcbiAgICAgKiAvLyA9PiBbNCwgOV1cbiAgICAgKlxuICAgICAqIF8udHJhbnNmb3JtKHsgJ2EnOiAxLCAnYic6IDIsICdjJzogMSB9LCBmdW5jdGlvbihyZXN1bHQsIHZhbHVlLCBrZXkpIHtcbiAgICAgKiAgIChyZXN1bHRbdmFsdWVdIHx8IChyZXN1bHRbdmFsdWVdID0gW10pKS5wdXNoKGtleSk7XG4gICAgICogfSwge30pO1xuICAgICAqIC8vID0+IHsgJzEnOiBbJ2EnLCAnYyddLCAnMic6IFsnYiddIH1cbiAgICAgKi9cbiAgICBmdW5jdGlvbiB0cmFuc2Zvcm0ob2JqZWN0LCBpdGVyYXRlZSwgYWNjdW11bGF0b3IpIHtcbiAgICAgIHZhciBpc0FyciA9IGlzQXJyYXkob2JqZWN0KSxcbiAgICAgICAgICBpc0Fyckxpa2UgPSBpc0FyciB8fCBpc0J1ZmZlcihvYmplY3QpIHx8IGlzVHlwZWRBcnJheShvYmplY3QpO1xuXG4gICAgICBpdGVyYXRlZSA9IGdldEl0ZXJhdGVlKGl0ZXJhdGVlLCA0KTtcbiAgICAgIGlmIChhY2N1bXVsYXRvciA9PSBudWxsKSB7XG4gICAgICAgIHZhciBDdG9yID0gb2JqZWN0ICYmIG9iamVjdC5jb25zdHJ1Y3RvcjtcbiAgICAgICAgaWYgKGlzQXJyTGlrZSkge1xuICAgICAgICAgIGFjY3VtdWxhdG9yID0gaXNBcnIgPyBuZXcgQ3RvciA6IFtdO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKGlzT2JqZWN0KG9iamVjdCkpIHtcbiAgICAgICAgICBhY2N1bXVsYXRvciA9IGlzRnVuY3Rpb24oQ3RvcikgPyBiYXNlQ3JlYXRlKGdldFByb3RvdHlwZShvYmplY3QpKSA6IHt9O1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgIGFjY3VtdWxhdG9yID0ge307XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIChpc0Fyckxpa2UgPyBhcnJheUVhY2ggOiBiYXNlRm9yT3duKShvYmplY3QsIGZ1bmN0aW9uKHZhbHVlLCBpbmRleCwgb2JqZWN0KSB7XG4gICAgICAgIHJldHVybiBpdGVyYXRlZShhY2N1bXVsYXRvciwgdmFsdWUsIGluZGV4LCBvYmplY3QpO1xuICAgICAgfSk7XG4gICAgICByZXR1cm4gYWNjdW11bGF0b3I7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUmVtb3ZlcyB0aGUgcHJvcGVydHkgYXQgYHBhdGhgIG9mIGBvYmplY3RgLlxuICAgICAqXG4gICAgICogKipOb3RlOioqIFRoaXMgbWV0aG9kIG11dGF0ZXMgYG9iamVjdGAuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgNC4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgT2JqZWN0XG4gICAgICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIG1vZGlmeS5cbiAgICAgKiBAcGFyYW0ge0FycmF5fHN0cmluZ30gcGF0aCBUaGUgcGF0aCBvZiB0aGUgcHJvcGVydHkgdG8gdW5zZXQuXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIHRoZSBwcm9wZXJ0eSBpcyBkZWxldGVkLCBlbHNlIGBmYWxzZWAuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIHZhciBvYmplY3QgPSB7ICdhJzogW3sgJ2InOiB7ICdjJzogNyB9IH1dIH07XG4gICAgICogXy51bnNldChvYmplY3QsICdhWzBdLmIuYycpO1xuICAgICAqIC8vID0+IHRydWVcbiAgICAgKlxuICAgICAqIGNvbnNvbGUubG9nKG9iamVjdCk7XG4gICAgICogLy8gPT4geyAnYSc6IFt7ICdiJzoge30gfV0gfTtcbiAgICAgKlxuICAgICAqIF8udW5zZXQob2JqZWN0LCBbJ2EnLCAnMCcsICdiJywgJ2MnXSk7XG4gICAgICogLy8gPT4gdHJ1ZVxuICAgICAqXG4gICAgICogY29uc29sZS5sb2cob2JqZWN0KTtcbiAgICAgKiAvLyA9PiB7ICdhJzogW3sgJ2InOiB7fSB9XSB9O1xuICAgICAqL1xuICAgIGZ1bmN0aW9uIHVuc2V0KG9iamVjdCwgcGF0aCkge1xuICAgICAgcmV0dXJuIG9iamVjdCA9PSBudWxsID8gdHJ1ZSA6IGJhc2VVbnNldChvYmplY3QsIHBhdGgpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoaXMgbWV0aG9kIGlzIGxpa2UgYF8uc2V0YCBleGNlcHQgdGhhdCBhY2NlcHRzIGB1cGRhdGVyYCB0byBwcm9kdWNlIHRoZVxuICAgICAqIHZhbHVlIHRvIHNldC4gVXNlIGBfLnVwZGF0ZVdpdGhgIHRvIGN1c3RvbWl6ZSBgcGF0aGAgY3JlYXRpb24uIFRoZSBgdXBkYXRlcmBcbiAgICAgKiBpcyBpbnZva2VkIHdpdGggb25lIGFyZ3VtZW50OiAodmFsdWUpLlxuICAgICAqXG4gICAgICogKipOb3RlOioqIFRoaXMgbWV0aG9kIG11dGF0ZXMgYG9iamVjdGAuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgNC42LjBcbiAgICAgKiBAY2F0ZWdvcnkgT2JqZWN0XG4gICAgICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIG1vZGlmeS5cbiAgICAgKiBAcGFyYW0ge0FycmF5fHN0cmluZ30gcGF0aCBUaGUgcGF0aCBvZiB0aGUgcHJvcGVydHkgdG8gc2V0LlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IHVwZGF0ZXIgVGhlIGZ1bmN0aW9uIHRvIHByb2R1Y2UgdGhlIHVwZGF0ZWQgdmFsdWUuXG4gICAgICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyBgb2JqZWN0YC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogdmFyIG9iamVjdCA9IHsgJ2EnOiBbeyAnYic6IHsgJ2MnOiAzIH0gfV0gfTtcbiAgICAgKlxuICAgICAqIF8udXBkYXRlKG9iamVjdCwgJ2FbMF0uYi5jJywgZnVuY3Rpb24obikgeyByZXR1cm4gbiAqIG47IH0pO1xuICAgICAqIGNvbnNvbGUubG9nKG9iamVjdC5hWzBdLmIuYyk7XG4gICAgICogLy8gPT4gOVxuICAgICAqXG4gICAgICogXy51cGRhdGUob2JqZWN0LCAneFswXS55LnonLCBmdW5jdGlvbihuKSB7IHJldHVybiBuID8gbiArIDEgOiAwOyB9KTtcbiAgICAgKiBjb25zb2xlLmxvZyhvYmplY3QueFswXS55LnopO1xuICAgICAqIC8vID0+IDBcbiAgICAgKi9cbiAgICBmdW5jdGlvbiB1cGRhdGUob2JqZWN0LCBwYXRoLCB1cGRhdGVyKSB7XG4gICAgICByZXR1cm4gb2JqZWN0ID09IG51bGwgPyBvYmplY3QgOiBiYXNlVXBkYXRlKG9iamVjdCwgcGF0aCwgY2FzdEZ1bmN0aW9uKHVwZGF0ZXIpKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGlzIG1ldGhvZCBpcyBsaWtlIGBfLnVwZGF0ZWAgZXhjZXB0IHRoYXQgaXQgYWNjZXB0cyBgY3VzdG9taXplcmAgd2hpY2ggaXNcbiAgICAgKiBpbnZva2VkIHRvIHByb2R1Y2UgdGhlIG9iamVjdHMgb2YgYHBhdGhgLiAgSWYgYGN1c3RvbWl6ZXJgIHJldHVybnMgYHVuZGVmaW5lZGBcbiAgICAgKiBwYXRoIGNyZWF0aW9uIGlzIGhhbmRsZWQgYnkgdGhlIG1ldGhvZCBpbnN0ZWFkLiBUaGUgYGN1c3RvbWl6ZXJgIGlzIGludm9rZWRcbiAgICAgKiB3aXRoIHRocmVlIGFyZ3VtZW50czogKG5zVmFsdWUsIGtleSwgbnNPYmplY3QpLlxuICAgICAqXG4gICAgICogKipOb3RlOioqIFRoaXMgbWV0aG9kIG11dGF0ZXMgYG9iamVjdGAuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgNC42LjBcbiAgICAgKiBAY2F0ZWdvcnkgT2JqZWN0XG4gICAgICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIG1vZGlmeS5cbiAgICAgKiBAcGFyYW0ge0FycmF5fHN0cmluZ30gcGF0aCBUaGUgcGF0aCBvZiB0aGUgcHJvcGVydHkgdG8gc2V0LlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IHVwZGF0ZXIgVGhlIGZ1bmN0aW9uIHRvIHByb2R1Y2UgdGhlIHVwZGF0ZWQgdmFsdWUuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gW2N1c3RvbWl6ZXJdIFRoZSBmdW5jdGlvbiB0byBjdXN0b21pemUgYXNzaWduZWQgdmFsdWVzLlxuICAgICAqIEByZXR1cm5zIHtPYmplY3R9IFJldHVybnMgYG9iamVjdGAuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIHZhciBvYmplY3QgPSB7fTtcbiAgICAgKlxuICAgICAqIF8udXBkYXRlV2l0aChvYmplY3QsICdbMF1bMV0nLCBfLmNvbnN0YW50KCdhJyksIE9iamVjdCk7XG4gICAgICogLy8gPT4geyAnMCc6IHsgJzEnOiAnYScgfSB9XG4gICAgICovXG4gICAgZnVuY3Rpb24gdXBkYXRlV2l0aChvYmplY3QsIHBhdGgsIHVwZGF0ZXIsIGN1c3RvbWl6ZXIpIHtcbiAgICAgIGN1c3RvbWl6ZXIgPSB0eXBlb2YgY3VzdG9taXplciA9PSAnZnVuY3Rpb24nID8gY3VzdG9taXplciA6IHVuZGVmaW5lZDtcbiAgICAgIHJldHVybiBvYmplY3QgPT0gbnVsbCA/IG9iamVjdCA6IGJhc2VVcGRhdGUob2JqZWN0LCBwYXRoLCBjYXN0RnVuY3Rpb24odXBkYXRlciksIGN1c3RvbWl6ZXIpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYW4gYXJyYXkgb2YgdGhlIG93biBlbnVtZXJhYmxlIHN0cmluZyBrZXllZCBwcm9wZXJ0eSB2YWx1ZXMgb2YgYG9iamVjdGAuXG4gICAgICpcbiAgICAgKiAqKk5vdGU6KiogTm9uLW9iamVjdCB2YWx1ZXMgYXJlIGNvZXJjZWQgdG8gb2JqZWN0cy5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAc2luY2UgMC4xLjBcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBjYXRlZ29yeSBPYmplY3RcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gcXVlcnkuXG4gICAgICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBhcnJheSBvZiBwcm9wZXJ0eSB2YWx1ZXMuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIGZ1bmN0aW9uIEZvbygpIHtcbiAgICAgKiAgIHRoaXMuYSA9IDE7XG4gICAgICogICB0aGlzLmIgPSAyO1xuICAgICAqIH1cbiAgICAgKlxuICAgICAqIEZvby5wcm90b3R5cGUuYyA9IDM7XG4gICAgICpcbiAgICAgKiBfLnZhbHVlcyhuZXcgRm9vKTtcbiAgICAgKiAvLyA9PiBbMSwgMl0gKGl0ZXJhdGlvbiBvcmRlciBpcyBub3QgZ3VhcmFudGVlZClcbiAgICAgKlxuICAgICAqIF8udmFsdWVzKCdoaScpO1xuICAgICAqIC8vID0+IFsnaCcsICdpJ11cbiAgICAgKi9cbiAgICBmdW5jdGlvbiB2YWx1ZXMob2JqZWN0KSB7XG4gICAgICByZXR1cm4gb2JqZWN0ID09IG51bGwgPyBbXSA6IGJhc2VWYWx1ZXMob2JqZWN0LCBrZXlzKG9iamVjdCkpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYW4gYXJyYXkgb2YgdGhlIG93biBhbmQgaW5oZXJpdGVkIGVudW1lcmFibGUgc3RyaW5nIGtleWVkIHByb3BlcnR5XG4gICAgICogdmFsdWVzIG9mIGBvYmplY3RgLlxuICAgICAqXG4gICAgICogKipOb3RlOioqIE5vbi1vYmplY3QgdmFsdWVzIGFyZSBjb2VyY2VkIHRvIG9iamVjdHMuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMy4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgT2JqZWN0XG4gICAgICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIHF1ZXJ5LlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgYXJyYXkgb2YgcHJvcGVydHkgdmFsdWVzLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBmdW5jdGlvbiBGb28oKSB7XG4gICAgICogICB0aGlzLmEgPSAxO1xuICAgICAqICAgdGhpcy5iID0gMjtcbiAgICAgKiB9XG4gICAgICpcbiAgICAgKiBGb28ucHJvdG90eXBlLmMgPSAzO1xuICAgICAqXG4gICAgICogXy52YWx1ZXNJbihuZXcgRm9vKTtcbiAgICAgKiAvLyA9PiBbMSwgMiwgM10gKGl0ZXJhdGlvbiBvcmRlciBpcyBub3QgZ3VhcmFudGVlZClcbiAgICAgKi9cbiAgICBmdW5jdGlvbiB2YWx1ZXNJbihvYmplY3QpIHtcbiAgICAgIHJldHVybiBvYmplY3QgPT0gbnVsbCA/IFtdIDogYmFzZVZhbHVlcyhvYmplY3QsIGtleXNJbihvYmplY3QpKTtcbiAgICB9XG5cbiAgICAvKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovXG5cbiAgICAvKipcbiAgICAgKiBDbGFtcHMgYG51bWJlcmAgd2l0aGluIHRoZSBpbmNsdXNpdmUgYGxvd2VyYCBhbmQgYHVwcGVyYCBib3VuZHMuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgNC4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgTnVtYmVyXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IG51bWJlciBUaGUgbnVtYmVyIHRvIGNsYW1wLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbbG93ZXJdIFRoZSBsb3dlciBib3VuZC5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gdXBwZXIgVGhlIHVwcGVyIGJvdW5kLlxuICAgICAqIEByZXR1cm5zIHtudW1iZXJ9IFJldHVybnMgdGhlIGNsYW1wZWQgbnVtYmVyLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLmNsYW1wKC0xMCwgLTUsIDUpO1xuICAgICAqIC8vID0+IC01XG4gICAgICpcbiAgICAgKiBfLmNsYW1wKDEwLCAtNSwgNSk7XG4gICAgICogLy8gPT4gNVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGNsYW1wKG51bWJlciwgbG93ZXIsIHVwcGVyKSB7XG4gICAgICBpZiAodXBwZXIgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICB1cHBlciA9IGxvd2VyO1xuICAgICAgICBsb3dlciA9IHVuZGVmaW5lZDtcbiAgICAgIH1cbiAgICAgIGlmICh1cHBlciAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHVwcGVyID0gdG9OdW1iZXIodXBwZXIpO1xuICAgICAgICB1cHBlciA9IHVwcGVyID09PSB1cHBlciA/IHVwcGVyIDogMDtcbiAgICAgIH1cbiAgICAgIGlmIChsb3dlciAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIGxvd2VyID0gdG9OdW1iZXIobG93ZXIpO1xuICAgICAgICBsb3dlciA9IGxvd2VyID09PSBsb3dlciA/IGxvd2VyIDogMDtcbiAgICAgIH1cbiAgICAgIHJldHVybiBiYXNlQ2xhbXAodG9OdW1iZXIobnVtYmVyKSwgbG93ZXIsIHVwcGVyKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDaGVja3MgaWYgYG5gIGlzIGJldHdlZW4gYHN0YXJ0YCBhbmQgdXAgdG8sIGJ1dCBub3QgaW5jbHVkaW5nLCBgZW5kYC4gSWZcbiAgICAgKiBgZW5kYCBpcyBub3Qgc3BlY2lmaWVkLCBpdCdzIHNldCB0byBgc3RhcnRgIHdpdGggYHN0YXJ0YCB0aGVuIHNldCB0byBgMGAuXG4gICAgICogSWYgYHN0YXJ0YCBpcyBncmVhdGVyIHRoYW4gYGVuZGAgdGhlIHBhcmFtcyBhcmUgc3dhcHBlZCB0byBzdXBwb3J0XG4gICAgICogbmVnYXRpdmUgcmFuZ2VzLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDMuMy4wXG4gICAgICogQGNhdGVnb3J5IE51bWJlclxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBudW1iZXIgVGhlIG51bWJlciB0byBjaGVjay5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gW3N0YXJ0PTBdIFRoZSBzdGFydCBvZiB0aGUgcmFuZ2UuXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IGVuZCBUaGUgZW5kIG9mIHRoZSByYW5nZS5cbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYG51bWJlcmAgaXMgaW4gdGhlIHJhbmdlLCBlbHNlIGBmYWxzZWAuXG4gICAgICogQHNlZSBfLnJhbmdlLCBfLnJhbmdlUmlnaHRcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy5pblJhbmdlKDMsIDIsIDQpO1xuICAgICAqIC8vID0+IHRydWVcbiAgICAgKlxuICAgICAqIF8uaW5SYW5nZSg0LCA4KTtcbiAgICAgKiAvLyA9PiB0cnVlXG4gICAgICpcbiAgICAgKiBfLmluUmFuZ2UoNCwgMik7XG4gICAgICogLy8gPT4gZmFsc2VcbiAgICAgKlxuICAgICAqIF8uaW5SYW5nZSgyLCAyKTtcbiAgICAgKiAvLyA9PiBmYWxzZVxuICAgICAqXG4gICAgICogXy5pblJhbmdlKDEuMiwgMik7XG4gICAgICogLy8gPT4gdHJ1ZVxuICAgICAqXG4gICAgICogXy5pblJhbmdlKDUuMiwgNCk7XG4gICAgICogLy8gPT4gZmFsc2VcbiAgICAgKlxuICAgICAqIF8uaW5SYW5nZSgtMywgLTIsIC02KTtcbiAgICAgKiAvLyA9PiB0cnVlXG4gICAgICovXG4gICAgZnVuY3Rpb24gaW5SYW5nZShudW1iZXIsIHN0YXJ0LCBlbmQpIHtcbiAgICAgIHN0YXJ0ID0gdG9GaW5pdGUoc3RhcnQpO1xuICAgICAgaWYgKGVuZCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIGVuZCA9IHN0YXJ0O1xuICAgICAgICBzdGFydCA9IDA7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBlbmQgPSB0b0Zpbml0ZShlbmQpO1xuICAgICAgfVxuICAgICAgbnVtYmVyID0gdG9OdW1iZXIobnVtYmVyKTtcbiAgICAgIHJldHVybiBiYXNlSW5SYW5nZShudW1iZXIsIHN0YXJ0LCBlbmQpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFByb2R1Y2VzIGEgcmFuZG9tIG51bWJlciBiZXR3ZWVuIHRoZSBpbmNsdXNpdmUgYGxvd2VyYCBhbmQgYHVwcGVyYCBib3VuZHMuXG4gICAgICogSWYgb25seSBvbmUgYXJndW1lbnQgaXMgcHJvdmlkZWQgYSBudW1iZXIgYmV0d2VlbiBgMGAgYW5kIHRoZSBnaXZlbiBudW1iZXJcbiAgICAgKiBpcyByZXR1cm5lZC4gSWYgYGZsb2F0aW5nYCBpcyBgdHJ1ZWAsIG9yIGVpdGhlciBgbG93ZXJgIG9yIGB1cHBlcmAgYXJlXG4gICAgICogZmxvYXRzLCBhIGZsb2F0aW5nLXBvaW50IG51bWJlciBpcyByZXR1cm5lZCBpbnN0ZWFkIG9mIGFuIGludGVnZXIuXG4gICAgICpcbiAgICAgKiAqKk5vdGU6KiogSmF2YVNjcmlwdCBmb2xsb3dzIHRoZSBJRUVFLTc1NCBzdGFuZGFyZCBmb3IgcmVzb2x2aW5nXG4gICAgICogZmxvYXRpbmctcG9pbnQgdmFsdWVzIHdoaWNoIGNhbiBwcm9kdWNlIHVuZXhwZWN0ZWQgcmVzdWx0cy5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAwLjcuMFxuICAgICAqIEBjYXRlZ29yeSBOdW1iZXJcbiAgICAgKiBAcGFyYW0ge251bWJlcn0gW2xvd2VyPTBdIFRoZSBsb3dlciBib3VuZC5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gW3VwcGVyPTFdIFRoZSB1cHBlciBib3VuZC5cbiAgICAgKiBAcGFyYW0ge2Jvb2xlYW59IFtmbG9hdGluZ10gU3BlY2lmeSByZXR1cm5pbmcgYSBmbG9hdGluZy1wb2ludCBudW1iZXIuXG4gICAgICogQHJldHVybnMge251bWJlcn0gUmV0dXJucyB0aGUgcmFuZG9tIG51bWJlci5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy5yYW5kb20oMCwgNSk7XG4gICAgICogLy8gPT4gYW4gaW50ZWdlciBiZXR3ZWVuIDAgYW5kIDVcbiAgICAgKlxuICAgICAqIF8ucmFuZG9tKDUpO1xuICAgICAqIC8vID0+IGFsc28gYW4gaW50ZWdlciBiZXR3ZWVuIDAgYW5kIDVcbiAgICAgKlxuICAgICAqIF8ucmFuZG9tKDUsIHRydWUpO1xuICAgICAqIC8vID0+IGEgZmxvYXRpbmctcG9pbnQgbnVtYmVyIGJldHdlZW4gMCBhbmQgNVxuICAgICAqXG4gICAgICogXy5yYW5kb20oMS4yLCA1LjIpO1xuICAgICAqIC8vID0+IGEgZmxvYXRpbmctcG9pbnQgbnVtYmVyIGJldHdlZW4gMS4yIGFuZCA1LjJcbiAgICAgKi9cbiAgICBmdW5jdGlvbiByYW5kb20obG93ZXIsIHVwcGVyLCBmbG9hdGluZykge1xuICAgICAgaWYgKGZsb2F0aW5nICYmIHR5cGVvZiBmbG9hdGluZyAhPSAnYm9vbGVhbicgJiYgaXNJdGVyYXRlZUNhbGwobG93ZXIsIHVwcGVyLCBmbG9hdGluZykpIHtcbiAgICAgICAgdXBwZXIgPSBmbG9hdGluZyA9IHVuZGVmaW5lZDtcbiAgICAgIH1cbiAgICAgIGlmIChmbG9hdGluZyA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIGlmICh0eXBlb2YgdXBwZXIgPT0gJ2Jvb2xlYW4nKSB7XG4gICAgICAgICAgZmxvYXRpbmcgPSB1cHBlcjtcbiAgICAgICAgICB1cHBlciA9IHVuZGVmaW5lZDtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmICh0eXBlb2YgbG93ZXIgPT0gJ2Jvb2xlYW4nKSB7XG4gICAgICAgICAgZmxvYXRpbmcgPSBsb3dlcjtcbiAgICAgICAgICBsb3dlciA9IHVuZGVmaW5lZDtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaWYgKGxvd2VyID09PSB1bmRlZmluZWQgJiYgdXBwZXIgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICBsb3dlciA9IDA7XG4gICAgICAgIHVwcGVyID0gMTtcbiAgICAgIH1cbiAgICAgIGVsc2Uge1xuICAgICAgICBsb3dlciA9IHRvRmluaXRlKGxvd2VyKTtcbiAgICAgICAgaWYgKHVwcGVyID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICB1cHBlciA9IGxvd2VyO1xuICAgICAgICAgIGxvd2VyID0gMDtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB1cHBlciA9IHRvRmluaXRlKHVwcGVyKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaWYgKGxvd2VyID4gdXBwZXIpIHtcbiAgICAgICAgdmFyIHRlbXAgPSBsb3dlcjtcbiAgICAgICAgbG93ZXIgPSB1cHBlcjtcbiAgICAgICAgdXBwZXIgPSB0ZW1wO1xuICAgICAgfVxuICAgICAgaWYgKGZsb2F0aW5nIHx8IGxvd2VyICUgMSB8fCB1cHBlciAlIDEpIHtcbiAgICAgICAgdmFyIHJhbmQgPSBuYXRpdmVSYW5kb20oKTtcbiAgICAgICAgcmV0dXJuIG5hdGl2ZU1pbihsb3dlciArIChyYW5kICogKHVwcGVyIC0gbG93ZXIgKyBmcmVlUGFyc2VGbG9hdCgnMWUtJyArICgocmFuZCArICcnKS5sZW5ndGggLSAxKSkpKSwgdXBwZXIpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGJhc2VSYW5kb20obG93ZXIsIHVwcGVyKTtcbiAgICB9XG5cbiAgICAvKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovXG5cbiAgICAvKipcbiAgICAgKiBDb252ZXJ0cyBgc3RyaW5nYCB0byBbY2FtZWwgY2FzZV0oaHR0cHM6Ly9lbi53aWtpcGVkaWEub3JnL3dpa2kvQ2FtZWxDYXNlKS5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAzLjAuMFxuICAgICAqIEBjYXRlZ29yeSBTdHJpbmdcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gW3N0cmluZz0nJ10gVGhlIHN0cmluZyB0byBjb252ZXJ0LlxuICAgICAqIEByZXR1cm5zIHtzdHJpbmd9IFJldHVybnMgdGhlIGNhbWVsIGNhc2VkIHN0cmluZy5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy5jYW1lbENhc2UoJ0ZvbyBCYXInKTtcbiAgICAgKiAvLyA9PiAnZm9vQmFyJ1xuICAgICAqXG4gICAgICogXy5jYW1lbENhc2UoJy0tZm9vLWJhci0tJyk7XG4gICAgICogLy8gPT4gJ2Zvb0JhcidcbiAgICAgKlxuICAgICAqIF8uY2FtZWxDYXNlKCdfX0ZPT19CQVJfXycpO1xuICAgICAqIC8vID0+ICdmb29CYXInXG4gICAgICovXG4gICAgdmFyIGNhbWVsQ2FzZSA9IGNyZWF0ZUNvbXBvdW5kZXIoZnVuY3Rpb24ocmVzdWx0LCB3b3JkLCBpbmRleCkge1xuICAgICAgd29yZCA9IHdvcmQudG9Mb3dlckNhc2UoKTtcbiAgICAgIHJldHVybiByZXN1bHQgKyAoaW5kZXggPyBjYXBpdGFsaXplKHdvcmQpIDogd29yZCk7XG4gICAgfSk7XG5cbiAgICAvKipcbiAgICAgKiBDb252ZXJ0cyB0aGUgZmlyc3QgY2hhcmFjdGVyIG9mIGBzdHJpbmdgIHRvIHVwcGVyIGNhc2UgYW5kIHRoZSByZW1haW5pbmdcbiAgICAgKiB0byBsb3dlciBjYXNlLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDMuMC4wXG4gICAgICogQGNhdGVnb3J5IFN0cmluZ1xuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBbc3RyaW5nPScnXSBUaGUgc3RyaW5nIHRvIGNhcGl0YWxpemUuXG4gICAgICogQHJldHVybnMge3N0cmluZ30gUmV0dXJucyB0aGUgY2FwaXRhbGl6ZWQgc3RyaW5nLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLmNhcGl0YWxpemUoJ0ZSRUQnKTtcbiAgICAgKiAvLyA9PiAnRnJlZCdcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBjYXBpdGFsaXplKHN0cmluZykge1xuICAgICAgcmV0dXJuIHVwcGVyRmlyc3QodG9TdHJpbmcoc3RyaW5nKS50b0xvd2VyQ2FzZSgpKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBEZWJ1cnJzIGBzdHJpbmdgIGJ5IGNvbnZlcnRpbmdcbiAgICAgKiBbTGF0aW4tMSBTdXBwbGVtZW50XShodHRwczovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9MYXRpbi0xX1N1cHBsZW1lbnRfKFVuaWNvZGVfYmxvY2spI0NoYXJhY3Rlcl90YWJsZSlcbiAgICAgKiBhbmQgW0xhdGluIEV4dGVuZGVkLUFdKGh0dHBzOi8vZW4ud2lraXBlZGlhLm9yZy93aWtpL0xhdGluX0V4dGVuZGVkLUEpXG4gICAgICogbGV0dGVycyB0byBiYXNpYyBMYXRpbiBsZXR0ZXJzIGFuZCByZW1vdmluZ1xuICAgICAqIFtjb21iaW5pbmcgZGlhY3JpdGljYWwgbWFya3NdKGh0dHBzOi8vZW4ud2lraXBlZGlhLm9yZy93aWtpL0NvbWJpbmluZ19EaWFjcml0aWNhbF9NYXJrcykuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMy4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgU3RyaW5nXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IFtzdHJpbmc9JyddIFRoZSBzdHJpbmcgdG8gZGVidXJyLlxuICAgICAqIEByZXR1cm5zIHtzdHJpbmd9IFJldHVybnMgdGhlIGRlYnVycmVkIHN0cmluZy5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy5kZWJ1cnIoJ2TDqWrDoCB2dScpO1xuICAgICAqIC8vID0+ICdkZWphIHZ1J1xuICAgICAqL1xuICAgIGZ1bmN0aW9uIGRlYnVycihzdHJpbmcpIHtcbiAgICAgIHN0cmluZyA9IHRvU3RyaW5nKHN0cmluZyk7XG4gICAgICByZXR1cm4gc3RyaW5nICYmIHN0cmluZy5yZXBsYWNlKHJlTGF0aW4sIGRlYnVyckxldHRlcikucmVwbGFjZShyZUNvbWJvTWFyaywgJycpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENoZWNrcyBpZiBgc3RyaW5nYCBlbmRzIHdpdGggdGhlIGdpdmVuIHRhcmdldCBzdHJpbmcuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMy4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgU3RyaW5nXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IFtzdHJpbmc9JyddIFRoZSBzdHJpbmcgdG8gaW5zcGVjdC5cbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gW3RhcmdldF0gVGhlIHN0cmluZyB0byBzZWFyY2ggZm9yLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbcG9zaXRpb249c3RyaW5nLmxlbmd0aF0gVGhlIHBvc2l0aW9uIHRvIHNlYXJjaCB1cCB0by5cbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHN0cmluZ2AgZW5kcyB3aXRoIGB0YXJnZXRgLFxuICAgICAqICBlbHNlIGBmYWxzZWAuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8uZW5kc1dpdGgoJ2FiYycsICdjJyk7XG4gICAgICogLy8gPT4gdHJ1ZVxuICAgICAqXG4gICAgICogXy5lbmRzV2l0aCgnYWJjJywgJ2InKTtcbiAgICAgKiAvLyA9PiBmYWxzZVxuICAgICAqXG4gICAgICogXy5lbmRzV2l0aCgnYWJjJywgJ2InLCAyKTtcbiAgICAgKiAvLyA9PiB0cnVlXG4gICAgICovXG4gICAgZnVuY3Rpb24gZW5kc1dpdGgoc3RyaW5nLCB0YXJnZXQsIHBvc2l0aW9uKSB7XG4gICAgICBzdHJpbmcgPSB0b1N0cmluZyhzdHJpbmcpO1xuICAgICAgdGFyZ2V0ID0gYmFzZVRvU3RyaW5nKHRhcmdldCk7XG5cbiAgICAgIHZhciBsZW5ndGggPSBzdHJpbmcubGVuZ3RoO1xuICAgICAgcG9zaXRpb24gPSBwb3NpdGlvbiA9PT0gdW5kZWZpbmVkXG4gICAgICAgID8gbGVuZ3RoXG4gICAgICAgIDogYmFzZUNsYW1wKHRvSW50ZWdlcihwb3NpdGlvbiksIDAsIGxlbmd0aCk7XG5cbiAgICAgIHZhciBlbmQgPSBwb3NpdGlvbjtcbiAgICAgIHBvc2l0aW9uIC09IHRhcmdldC5sZW5ndGg7XG4gICAgICByZXR1cm4gcG9zaXRpb24gPj0gMCAmJiBzdHJpbmcuc2xpY2UocG9zaXRpb24sIGVuZCkgPT0gdGFyZ2V0O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENvbnZlcnRzIHRoZSBjaGFyYWN0ZXJzIFwiJlwiLCBcIjxcIiwgXCI+XCIsICdcIicsIGFuZCBcIidcIiBpbiBgc3RyaW5nYCB0byB0aGVpclxuICAgICAqIGNvcnJlc3BvbmRpbmcgSFRNTCBlbnRpdGllcy5cbiAgICAgKlxuICAgICAqICoqTm90ZToqKiBObyBvdGhlciBjaGFyYWN0ZXJzIGFyZSBlc2NhcGVkLiBUbyBlc2NhcGUgYWRkaXRpb25hbFxuICAgICAqIGNoYXJhY3RlcnMgdXNlIGEgdGhpcmQtcGFydHkgbGlicmFyeSBsaWtlIFtfaGVfXShodHRwczovL210aHMuYmUvaGUpLlxuICAgICAqXG4gICAgICogVGhvdWdoIHRoZSBcIj5cIiBjaGFyYWN0ZXIgaXMgZXNjYXBlZCBmb3Igc3ltbWV0cnksIGNoYXJhY3RlcnMgbGlrZVxuICAgICAqIFwiPlwiIGFuZCBcIi9cIiBkb24ndCBuZWVkIGVzY2FwaW5nIGluIEhUTUwgYW5kIGhhdmUgbm8gc3BlY2lhbCBtZWFuaW5nXG4gICAgICogdW5sZXNzIHRoZXkncmUgcGFydCBvZiBhIHRhZyBvciB1bnF1b3RlZCBhdHRyaWJ1dGUgdmFsdWUuIFNlZVxuICAgICAqIFtNYXRoaWFzIEJ5bmVucydzIGFydGljbGVdKGh0dHBzOi8vbWF0aGlhc2J5bmVucy5iZS9ub3Rlcy9hbWJpZ3VvdXMtYW1wZXJzYW5kcylcbiAgICAgKiAodW5kZXIgXCJzZW1pLXJlbGF0ZWQgZnVuIGZhY3RcIikgZm9yIG1vcmUgZGV0YWlscy5cbiAgICAgKlxuICAgICAqIFdoZW4gd29ya2luZyB3aXRoIEhUTUwgeW91IHNob3VsZCBhbHdheXNcbiAgICAgKiBbcXVvdGUgYXR0cmlidXRlIHZhbHVlc10oaHR0cDovL3dvbmtvLmNvbS9wb3N0L2h0bWwtZXNjYXBpbmcpIHRvIHJlZHVjZVxuICAgICAqIFhTUyB2ZWN0b3JzLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBzaW5jZSAwLjEuMFxuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQGNhdGVnb3J5IFN0cmluZ1xuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBbc3RyaW5nPScnXSBUaGUgc3RyaW5nIHRvIGVzY2FwZS5cbiAgICAgKiBAcmV0dXJucyB7c3RyaW5nfSBSZXR1cm5zIHRoZSBlc2NhcGVkIHN0cmluZy5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy5lc2NhcGUoJ2ZyZWQsIGJhcm5leSwgJiBwZWJibGVzJyk7XG4gICAgICogLy8gPT4gJ2ZyZWQsIGJhcm5leSwgJmFtcDsgcGViYmxlcydcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBlc2NhcGUoc3RyaW5nKSB7XG4gICAgICBzdHJpbmcgPSB0b1N0cmluZyhzdHJpbmcpO1xuICAgICAgcmV0dXJuIChzdHJpbmcgJiYgcmVIYXNVbmVzY2FwZWRIdG1sLnRlc3Qoc3RyaW5nKSlcbiAgICAgICAgPyBzdHJpbmcucmVwbGFjZShyZVVuZXNjYXBlZEh0bWwsIGVzY2FwZUh0bWxDaGFyKVxuICAgICAgICA6IHN0cmluZztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBFc2NhcGVzIHRoZSBgUmVnRXhwYCBzcGVjaWFsIGNoYXJhY3RlcnMgXCJeXCIsIFwiJFwiLCBcIlxcXCIsIFwiLlwiLCBcIipcIiwgXCIrXCIsXG4gICAgICogXCI/XCIsIFwiKFwiLCBcIilcIiwgXCJbXCIsIFwiXVwiLCBcIntcIiwgXCJ9XCIsIGFuZCBcInxcIiBpbiBgc3RyaW5nYC5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAzLjAuMFxuICAgICAqIEBjYXRlZ29yeSBTdHJpbmdcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gW3N0cmluZz0nJ10gVGhlIHN0cmluZyB0byBlc2NhcGUuXG4gICAgICogQHJldHVybnMge3N0cmluZ30gUmV0dXJucyB0aGUgZXNjYXBlZCBzdHJpbmcuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8uZXNjYXBlUmVnRXhwKCdbbG9kYXNoXShodHRwczovL2xvZGFzaC5jb20vKScpO1xuICAgICAqIC8vID0+ICdcXFtsb2Rhc2hcXF1cXChodHRwczovL2xvZGFzaFxcLmNvbS9cXCknXG4gICAgICovXG4gICAgZnVuY3Rpb24gZXNjYXBlUmVnRXhwKHN0cmluZykge1xuICAgICAgc3RyaW5nID0gdG9TdHJpbmcoc3RyaW5nKTtcbiAgICAgIHJldHVybiAoc3RyaW5nICYmIHJlSGFzUmVnRXhwQ2hhci50ZXN0KHN0cmluZykpXG4gICAgICAgID8gc3RyaW5nLnJlcGxhY2UocmVSZWdFeHBDaGFyLCAnXFxcXCQmJylcbiAgICAgICAgOiBzdHJpbmc7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ29udmVydHMgYHN0cmluZ2AgdG9cbiAgICAgKiBba2ViYWIgY2FzZV0oaHR0cHM6Ly9lbi53aWtpcGVkaWEub3JnL3dpa2kvTGV0dGVyX2Nhc2UjU3BlY2lhbF9jYXNlX3N0eWxlcykuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMy4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgU3RyaW5nXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IFtzdHJpbmc9JyddIFRoZSBzdHJpbmcgdG8gY29udmVydC5cbiAgICAgKiBAcmV0dXJucyB7c3RyaW5nfSBSZXR1cm5zIHRoZSBrZWJhYiBjYXNlZCBzdHJpbmcuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8ua2ViYWJDYXNlKCdGb28gQmFyJyk7XG4gICAgICogLy8gPT4gJ2Zvby1iYXInXG4gICAgICpcbiAgICAgKiBfLmtlYmFiQ2FzZSgnZm9vQmFyJyk7XG4gICAgICogLy8gPT4gJ2Zvby1iYXInXG4gICAgICpcbiAgICAgKiBfLmtlYmFiQ2FzZSgnX19GT09fQkFSX18nKTtcbiAgICAgKiAvLyA9PiAnZm9vLWJhcidcbiAgICAgKi9cbiAgICB2YXIga2ViYWJDYXNlID0gY3JlYXRlQ29tcG91bmRlcihmdW5jdGlvbihyZXN1bHQsIHdvcmQsIGluZGV4KSB7XG4gICAgICByZXR1cm4gcmVzdWx0ICsgKGluZGV4ID8gJy0nIDogJycpICsgd29yZC50b0xvd2VyQ2FzZSgpO1xuICAgIH0pO1xuXG4gICAgLyoqXG4gICAgICogQ29udmVydHMgYHN0cmluZ2AsIGFzIHNwYWNlIHNlcGFyYXRlZCB3b3JkcywgdG8gbG93ZXIgY2FzZS5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSA0LjAuMFxuICAgICAqIEBjYXRlZ29yeSBTdHJpbmdcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gW3N0cmluZz0nJ10gVGhlIHN0cmluZyB0byBjb252ZXJ0LlxuICAgICAqIEByZXR1cm5zIHtzdHJpbmd9IFJldHVybnMgdGhlIGxvd2VyIGNhc2VkIHN0cmluZy5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy5sb3dlckNhc2UoJy0tRm9vLUJhci0tJyk7XG4gICAgICogLy8gPT4gJ2ZvbyBiYXInXG4gICAgICpcbiAgICAgKiBfLmxvd2VyQ2FzZSgnZm9vQmFyJyk7XG4gICAgICogLy8gPT4gJ2ZvbyBiYXInXG4gICAgICpcbiAgICAgKiBfLmxvd2VyQ2FzZSgnX19GT09fQkFSX18nKTtcbiAgICAgKiAvLyA9PiAnZm9vIGJhcidcbiAgICAgKi9cbiAgICB2YXIgbG93ZXJDYXNlID0gY3JlYXRlQ29tcG91bmRlcihmdW5jdGlvbihyZXN1bHQsIHdvcmQsIGluZGV4KSB7XG4gICAgICByZXR1cm4gcmVzdWx0ICsgKGluZGV4ID8gJyAnIDogJycpICsgd29yZC50b0xvd2VyQ2FzZSgpO1xuICAgIH0pO1xuXG4gICAgLyoqXG4gICAgICogQ29udmVydHMgdGhlIGZpcnN0IGNoYXJhY3RlciBvZiBgc3RyaW5nYCB0byBsb3dlciBjYXNlLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDQuMC4wXG4gICAgICogQGNhdGVnb3J5IFN0cmluZ1xuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBbc3RyaW5nPScnXSBUaGUgc3RyaW5nIHRvIGNvbnZlcnQuXG4gICAgICogQHJldHVybnMge3N0cmluZ30gUmV0dXJucyB0aGUgY29udmVydGVkIHN0cmluZy5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy5sb3dlckZpcnN0KCdGcmVkJyk7XG4gICAgICogLy8gPT4gJ2ZyZWQnXG4gICAgICpcbiAgICAgKiBfLmxvd2VyRmlyc3QoJ0ZSRUQnKTtcbiAgICAgKiAvLyA9PiAnZlJFRCdcbiAgICAgKi9cbiAgICB2YXIgbG93ZXJGaXJzdCA9IGNyZWF0ZUNhc2VGaXJzdCgndG9Mb3dlckNhc2UnKTtcblxuICAgIC8qKlxuICAgICAqIFBhZHMgYHN0cmluZ2Agb24gdGhlIGxlZnQgYW5kIHJpZ2h0IHNpZGVzIGlmIGl0J3Mgc2hvcnRlciB0aGFuIGBsZW5ndGhgLlxuICAgICAqIFBhZGRpbmcgY2hhcmFjdGVycyBhcmUgdHJ1bmNhdGVkIGlmIHRoZXkgY2FuJ3QgYmUgZXZlbmx5IGRpdmlkZWQgYnkgYGxlbmd0aGAuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMy4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgU3RyaW5nXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IFtzdHJpbmc9JyddIFRoZSBzdHJpbmcgdG8gcGFkLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbbGVuZ3RoPTBdIFRoZSBwYWRkaW5nIGxlbmd0aC5cbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gW2NoYXJzPScgJ10gVGhlIHN0cmluZyB1c2VkIGFzIHBhZGRpbmcuXG4gICAgICogQHJldHVybnMge3N0cmluZ30gUmV0dXJucyB0aGUgcGFkZGVkIHN0cmluZy5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy5wYWQoJ2FiYycsIDgpO1xuICAgICAqIC8vID0+ICcgIGFiYyAgICdcbiAgICAgKlxuICAgICAqIF8ucGFkKCdhYmMnLCA4LCAnXy0nKTtcbiAgICAgKiAvLyA9PiAnXy1hYmNfLV8nXG4gICAgICpcbiAgICAgKiBfLnBhZCgnYWJjJywgMyk7XG4gICAgICogLy8gPT4gJ2FiYydcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBwYWQoc3RyaW5nLCBsZW5ndGgsIGNoYXJzKSB7XG4gICAgICBzdHJpbmcgPSB0b1N0cmluZyhzdHJpbmcpO1xuICAgICAgbGVuZ3RoID0gdG9JbnRlZ2VyKGxlbmd0aCk7XG5cbiAgICAgIHZhciBzdHJMZW5ndGggPSBsZW5ndGggPyBzdHJpbmdTaXplKHN0cmluZykgOiAwO1xuICAgICAgaWYgKCFsZW5ndGggfHwgc3RyTGVuZ3RoID49IGxlbmd0aCkge1xuICAgICAgICByZXR1cm4gc3RyaW5nO1xuICAgICAgfVxuICAgICAgdmFyIG1pZCA9IChsZW5ndGggLSBzdHJMZW5ndGgpIC8gMjtcbiAgICAgIHJldHVybiAoXG4gICAgICAgIGNyZWF0ZVBhZGRpbmcobmF0aXZlRmxvb3IobWlkKSwgY2hhcnMpICtcbiAgICAgICAgc3RyaW5nICtcbiAgICAgICAgY3JlYXRlUGFkZGluZyhuYXRpdmVDZWlsKG1pZCksIGNoYXJzKVxuICAgICAgKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBQYWRzIGBzdHJpbmdgIG9uIHRoZSByaWdodCBzaWRlIGlmIGl0J3Mgc2hvcnRlciB0aGFuIGBsZW5ndGhgLiBQYWRkaW5nXG4gICAgICogY2hhcmFjdGVycyBhcmUgdHJ1bmNhdGVkIGlmIHRoZXkgZXhjZWVkIGBsZW5ndGhgLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDQuMC4wXG4gICAgICogQGNhdGVnb3J5IFN0cmluZ1xuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBbc3RyaW5nPScnXSBUaGUgc3RyaW5nIHRvIHBhZC5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gW2xlbmd0aD0wXSBUaGUgcGFkZGluZyBsZW5ndGguXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IFtjaGFycz0nICddIFRoZSBzdHJpbmcgdXNlZCBhcyBwYWRkaW5nLlxuICAgICAqIEByZXR1cm5zIHtzdHJpbmd9IFJldHVybnMgdGhlIHBhZGRlZCBzdHJpbmcuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8ucGFkRW5kKCdhYmMnLCA2KTtcbiAgICAgKiAvLyA9PiAnYWJjICAgJ1xuICAgICAqXG4gICAgICogXy5wYWRFbmQoJ2FiYycsIDYsICdfLScpO1xuICAgICAqIC8vID0+ICdhYmNfLV8nXG4gICAgICpcbiAgICAgKiBfLnBhZEVuZCgnYWJjJywgMyk7XG4gICAgICogLy8gPT4gJ2FiYydcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBwYWRFbmQoc3RyaW5nLCBsZW5ndGgsIGNoYXJzKSB7XG4gICAgICBzdHJpbmcgPSB0b1N0cmluZyhzdHJpbmcpO1xuICAgICAgbGVuZ3RoID0gdG9JbnRlZ2VyKGxlbmd0aCk7XG5cbiAgICAgIHZhciBzdHJMZW5ndGggPSBsZW5ndGggPyBzdHJpbmdTaXplKHN0cmluZykgOiAwO1xuICAgICAgcmV0dXJuIChsZW5ndGggJiYgc3RyTGVuZ3RoIDwgbGVuZ3RoKVxuICAgICAgICA/IChzdHJpbmcgKyBjcmVhdGVQYWRkaW5nKGxlbmd0aCAtIHN0ckxlbmd0aCwgY2hhcnMpKVxuICAgICAgICA6IHN0cmluZztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBQYWRzIGBzdHJpbmdgIG9uIHRoZSBsZWZ0IHNpZGUgaWYgaXQncyBzaG9ydGVyIHRoYW4gYGxlbmd0aGAuIFBhZGRpbmdcbiAgICAgKiBjaGFyYWN0ZXJzIGFyZSB0cnVuY2F0ZWQgaWYgdGhleSBleGNlZWQgYGxlbmd0aGAuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgNC4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgU3RyaW5nXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IFtzdHJpbmc9JyddIFRoZSBzdHJpbmcgdG8gcGFkLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbbGVuZ3RoPTBdIFRoZSBwYWRkaW5nIGxlbmd0aC5cbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gW2NoYXJzPScgJ10gVGhlIHN0cmluZyB1c2VkIGFzIHBhZGRpbmcuXG4gICAgICogQHJldHVybnMge3N0cmluZ30gUmV0dXJucyB0aGUgcGFkZGVkIHN0cmluZy5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy5wYWRTdGFydCgnYWJjJywgNik7XG4gICAgICogLy8gPT4gJyAgIGFiYydcbiAgICAgKlxuICAgICAqIF8ucGFkU3RhcnQoJ2FiYycsIDYsICdfLScpO1xuICAgICAqIC8vID0+ICdfLV9hYmMnXG4gICAgICpcbiAgICAgKiBfLnBhZFN0YXJ0KCdhYmMnLCAzKTtcbiAgICAgKiAvLyA9PiAnYWJjJ1xuICAgICAqL1xuICAgIGZ1bmN0aW9uIHBhZFN0YXJ0KHN0cmluZywgbGVuZ3RoLCBjaGFycykge1xuICAgICAgc3RyaW5nID0gdG9TdHJpbmcoc3RyaW5nKTtcbiAgICAgIGxlbmd0aCA9IHRvSW50ZWdlcihsZW5ndGgpO1xuXG4gICAgICB2YXIgc3RyTGVuZ3RoID0gbGVuZ3RoID8gc3RyaW5nU2l6ZShzdHJpbmcpIDogMDtcbiAgICAgIHJldHVybiAobGVuZ3RoICYmIHN0ckxlbmd0aCA8IGxlbmd0aClcbiAgICAgICAgPyAoY3JlYXRlUGFkZGluZyhsZW5ndGggLSBzdHJMZW5ndGgsIGNoYXJzKSArIHN0cmluZylcbiAgICAgICAgOiBzdHJpbmc7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ29udmVydHMgYHN0cmluZ2AgdG8gYW4gaW50ZWdlciBvZiB0aGUgc3BlY2lmaWVkIHJhZGl4LiBJZiBgcmFkaXhgIGlzXG4gICAgICogYHVuZGVmaW5lZGAgb3IgYDBgLCBhIGByYWRpeGAgb2YgYDEwYCBpcyB1c2VkIHVubGVzcyBgdmFsdWVgIGlzIGFcbiAgICAgKiBoZXhhZGVjaW1hbCwgaW4gd2hpY2ggY2FzZSBhIGByYWRpeGAgb2YgYDE2YCBpcyB1c2VkLlxuICAgICAqXG4gICAgICogKipOb3RlOioqIFRoaXMgbWV0aG9kIGFsaWducyB3aXRoIHRoZVxuICAgICAqIFtFUzUgaW1wbGVtZW50YXRpb25dKGh0dHBzOi8vZXM1LmdpdGh1Yi5pby8jeDE1LjEuMi4yKSBvZiBgcGFyc2VJbnRgLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDEuMS4wXG4gICAgICogQGNhdGVnb3J5IFN0cmluZ1xuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBzdHJpbmcgVGhlIHN0cmluZyB0byBjb252ZXJ0LlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbcmFkaXg9MTBdIFRoZSByYWRpeCB0byBpbnRlcnByZXQgYHZhbHVlYCBieS5cbiAgICAgKiBAcGFyYW0tIHtPYmplY3R9IFtndWFyZF0gRW5hYmxlcyB1c2UgYXMgYW4gaXRlcmF0ZWUgZm9yIG1ldGhvZHMgbGlrZSBgXy5tYXBgLlxuICAgICAqIEByZXR1cm5zIHtudW1iZXJ9IFJldHVybnMgdGhlIGNvbnZlcnRlZCBpbnRlZ2VyLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLnBhcnNlSW50KCcwOCcpO1xuICAgICAqIC8vID0+IDhcbiAgICAgKlxuICAgICAqIF8ubWFwKFsnNicsICcwOCcsICcxMCddLCBfLnBhcnNlSW50KTtcbiAgICAgKiAvLyA9PiBbNiwgOCwgMTBdXG4gICAgICovXG4gICAgZnVuY3Rpb24gcGFyc2VJbnQoc3RyaW5nLCByYWRpeCwgZ3VhcmQpIHtcbiAgICAgIGlmIChndWFyZCB8fCByYWRpeCA9PSBudWxsKSB7XG4gICAgICAgIHJhZGl4ID0gMDtcbiAgICAgIH0gZWxzZSBpZiAocmFkaXgpIHtcbiAgICAgICAgcmFkaXggPSArcmFkaXg7XG4gICAgICB9XG4gICAgICByZXR1cm4gbmF0aXZlUGFyc2VJbnQodG9TdHJpbmcoc3RyaW5nKS5yZXBsYWNlKHJlVHJpbVN0YXJ0LCAnJyksIHJhZGl4IHx8IDApO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJlcGVhdHMgdGhlIGdpdmVuIHN0cmluZyBgbmAgdGltZXMuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMy4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgU3RyaW5nXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IFtzdHJpbmc9JyddIFRoZSBzdHJpbmcgdG8gcmVwZWF0LlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbbj0xXSBUaGUgbnVtYmVyIG9mIHRpbWVzIHRvIHJlcGVhdCB0aGUgc3RyaW5nLlxuICAgICAqIEBwYXJhbS0ge09iamVjdH0gW2d1YXJkXSBFbmFibGVzIHVzZSBhcyBhbiBpdGVyYXRlZSBmb3IgbWV0aG9kcyBsaWtlIGBfLm1hcGAuXG4gICAgICogQHJldHVybnMge3N0cmluZ30gUmV0dXJucyB0aGUgcmVwZWF0ZWQgc3RyaW5nLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLnJlcGVhdCgnKicsIDMpO1xuICAgICAqIC8vID0+ICcqKionXG4gICAgICpcbiAgICAgKiBfLnJlcGVhdCgnYWJjJywgMik7XG4gICAgICogLy8gPT4gJ2FiY2FiYydcbiAgICAgKlxuICAgICAqIF8ucmVwZWF0KCdhYmMnLCAwKTtcbiAgICAgKiAvLyA9PiAnJ1xuICAgICAqL1xuICAgIGZ1bmN0aW9uIHJlcGVhdChzdHJpbmcsIG4sIGd1YXJkKSB7XG4gICAgICBpZiAoKGd1YXJkID8gaXNJdGVyYXRlZUNhbGwoc3RyaW5nLCBuLCBndWFyZCkgOiBuID09PSB1bmRlZmluZWQpKSB7XG4gICAgICAgIG4gPSAxO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgbiA9IHRvSW50ZWdlcihuKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBiYXNlUmVwZWF0KHRvU3RyaW5nKHN0cmluZyksIG4pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJlcGxhY2VzIG1hdGNoZXMgZm9yIGBwYXR0ZXJuYCBpbiBgc3RyaW5nYCB3aXRoIGByZXBsYWNlbWVudGAuXG4gICAgICpcbiAgICAgKiAqKk5vdGU6KiogVGhpcyBtZXRob2QgaXMgYmFzZWQgb25cbiAgICAgKiBbYFN0cmluZyNyZXBsYWNlYF0oaHR0cHM6Ly9tZG4uaW8vU3RyaW5nL3JlcGxhY2UpLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDQuMC4wXG4gICAgICogQGNhdGVnb3J5IFN0cmluZ1xuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBbc3RyaW5nPScnXSBUaGUgc3RyaW5nIHRvIG1vZGlmeS5cbiAgICAgKiBAcGFyYW0ge1JlZ0V4cHxzdHJpbmd9IHBhdHRlcm4gVGhlIHBhdHRlcm4gdG8gcmVwbGFjZS5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufHN0cmluZ30gcmVwbGFjZW1lbnQgVGhlIG1hdGNoIHJlcGxhY2VtZW50LlxuICAgICAqIEByZXR1cm5zIHtzdHJpbmd9IFJldHVybnMgdGhlIG1vZGlmaWVkIHN0cmluZy5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy5yZXBsYWNlKCdIaSBGcmVkJywgJ0ZyZWQnLCAnQmFybmV5Jyk7XG4gICAgICogLy8gPT4gJ0hpIEJhcm5leSdcbiAgICAgKi9cbiAgICBmdW5jdGlvbiByZXBsYWNlKCkge1xuICAgICAgdmFyIGFyZ3MgPSBhcmd1bWVudHMsXG4gICAgICAgICAgc3RyaW5nID0gdG9TdHJpbmcoYXJnc1swXSk7XG5cbiAgICAgIHJldHVybiBhcmdzLmxlbmd0aCA8IDMgPyBzdHJpbmcgOiBzdHJpbmcucmVwbGFjZShhcmdzWzFdLCBhcmdzWzJdKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDb252ZXJ0cyBgc3RyaW5nYCB0b1xuICAgICAqIFtzbmFrZSBjYXNlXShodHRwczovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9TbmFrZV9jYXNlKS5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAzLjAuMFxuICAgICAqIEBjYXRlZ29yeSBTdHJpbmdcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gW3N0cmluZz0nJ10gVGhlIHN0cmluZyB0byBjb252ZXJ0LlxuICAgICAqIEByZXR1cm5zIHtzdHJpbmd9IFJldHVybnMgdGhlIHNuYWtlIGNhc2VkIHN0cmluZy5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy5zbmFrZUNhc2UoJ0ZvbyBCYXInKTtcbiAgICAgKiAvLyA9PiAnZm9vX2JhcidcbiAgICAgKlxuICAgICAqIF8uc25ha2VDYXNlKCdmb29CYXInKTtcbiAgICAgKiAvLyA9PiAnZm9vX2JhcidcbiAgICAgKlxuICAgICAqIF8uc25ha2VDYXNlKCctLUZPTy1CQVItLScpO1xuICAgICAqIC8vID0+ICdmb29fYmFyJ1xuICAgICAqL1xuICAgIHZhciBzbmFrZUNhc2UgPSBjcmVhdGVDb21wb3VuZGVyKGZ1bmN0aW9uKHJlc3VsdCwgd29yZCwgaW5kZXgpIHtcbiAgICAgIHJldHVybiByZXN1bHQgKyAoaW5kZXggPyAnXycgOiAnJykgKyB3b3JkLnRvTG93ZXJDYXNlKCk7XG4gICAgfSk7XG5cbiAgICAvKipcbiAgICAgKiBTcGxpdHMgYHN0cmluZ2AgYnkgYHNlcGFyYXRvcmAuXG4gICAgICpcbiAgICAgKiAqKk5vdGU6KiogVGhpcyBtZXRob2QgaXMgYmFzZWQgb25cbiAgICAgKiBbYFN0cmluZyNzcGxpdGBdKGh0dHBzOi8vbWRuLmlvL1N0cmluZy9zcGxpdCkuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgNC4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgU3RyaW5nXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IFtzdHJpbmc9JyddIFRoZSBzdHJpbmcgdG8gc3BsaXQuXG4gICAgICogQHBhcmFtIHtSZWdFeHB8c3RyaW5nfSBzZXBhcmF0b3IgVGhlIHNlcGFyYXRvciBwYXR0ZXJuIHRvIHNwbGl0IGJ5LlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbbGltaXRdIFRoZSBsZW5ndGggdG8gdHJ1bmNhdGUgcmVzdWx0cyB0by5cbiAgICAgKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIHN0cmluZyBzZWdtZW50cy5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy5zcGxpdCgnYS1iLWMnLCAnLScsIDIpO1xuICAgICAqIC8vID0+IFsnYScsICdiJ11cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBzcGxpdChzdHJpbmcsIHNlcGFyYXRvciwgbGltaXQpIHtcbiAgICAgIGlmIChsaW1pdCAmJiB0eXBlb2YgbGltaXQgIT0gJ251bWJlcicgJiYgaXNJdGVyYXRlZUNhbGwoc3RyaW5nLCBzZXBhcmF0b3IsIGxpbWl0KSkge1xuICAgICAgICBzZXBhcmF0b3IgPSBsaW1pdCA9IHVuZGVmaW5lZDtcbiAgICAgIH1cbiAgICAgIGxpbWl0ID0gbGltaXQgPT09IHVuZGVmaW5lZCA/IE1BWF9BUlJBWV9MRU5HVEggOiBsaW1pdCA+Pj4gMDtcbiAgICAgIGlmICghbGltaXQpIHtcbiAgICAgICAgcmV0dXJuIFtdO1xuICAgICAgfVxuICAgICAgc3RyaW5nID0gdG9TdHJpbmcoc3RyaW5nKTtcbiAgICAgIGlmIChzdHJpbmcgJiYgKFxuICAgICAgICAgICAgdHlwZW9mIHNlcGFyYXRvciA9PSAnc3RyaW5nJyB8fFxuICAgICAgICAgICAgKHNlcGFyYXRvciAhPSBudWxsICYmICFpc1JlZ0V4cChzZXBhcmF0b3IpKVxuICAgICAgICAgICkpIHtcbiAgICAgICAgc2VwYXJhdG9yID0gYmFzZVRvU3RyaW5nKHNlcGFyYXRvcik7XG4gICAgICAgIGlmICghc2VwYXJhdG9yICYmIGhhc1VuaWNvZGUoc3RyaW5nKSkge1xuICAgICAgICAgIHJldHVybiBjYXN0U2xpY2Uoc3RyaW5nVG9BcnJheShzdHJpbmcpLCAwLCBsaW1pdCk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHJldHVybiBzdHJpbmcuc3BsaXQoc2VwYXJhdG9yLCBsaW1pdCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ29udmVydHMgYHN0cmluZ2AgdG9cbiAgICAgKiBbc3RhcnQgY2FzZV0oaHR0cHM6Ly9lbi53aWtpcGVkaWEub3JnL3dpa2kvTGV0dGVyX2Nhc2UjU3R5bGlzdGljX29yX3NwZWNpYWxpc2VkX3VzYWdlKS5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAzLjEuMFxuICAgICAqIEBjYXRlZ29yeSBTdHJpbmdcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gW3N0cmluZz0nJ10gVGhlIHN0cmluZyB0byBjb252ZXJ0LlxuICAgICAqIEByZXR1cm5zIHtzdHJpbmd9IFJldHVybnMgdGhlIHN0YXJ0IGNhc2VkIHN0cmluZy5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy5zdGFydENhc2UoJy0tZm9vLWJhci0tJyk7XG4gICAgICogLy8gPT4gJ0ZvbyBCYXInXG4gICAgICpcbiAgICAgKiBfLnN0YXJ0Q2FzZSgnZm9vQmFyJyk7XG4gICAgICogLy8gPT4gJ0ZvbyBCYXInXG4gICAgICpcbiAgICAgKiBfLnN0YXJ0Q2FzZSgnX19GT09fQkFSX18nKTtcbiAgICAgKiAvLyA9PiAnRk9PIEJBUidcbiAgICAgKi9cbiAgICB2YXIgc3RhcnRDYXNlID0gY3JlYXRlQ29tcG91bmRlcihmdW5jdGlvbihyZXN1bHQsIHdvcmQsIGluZGV4KSB7XG4gICAgICByZXR1cm4gcmVzdWx0ICsgKGluZGV4ID8gJyAnIDogJycpICsgdXBwZXJGaXJzdCh3b3JkKTtcbiAgICB9KTtcblxuICAgIC8qKlxuICAgICAqIENoZWNrcyBpZiBgc3RyaW5nYCBzdGFydHMgd2l0aCB0aGUgZ2l2ZW4gdGFyZ2V0IHN0cmluZy5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAzLjAuMFxuICAgICAqIEBjYXRlZ29yeSBTdHJpbmdcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gW3N0cmluZz0nJ10gVGhlIHN0cmluZyB0byBpbnNwZWN0LlxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBbdGFyZ2V0XSBUaGUgc3RyaW5nIHRvIHNlYXJjaCBmb3IuXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IFtwb3NpdGlvbj0wXSBUaGUgcG9zaXRpb24gdG8gc2VhcmNoIGZyb20uXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGBzdHJpbmdgIHN0YXJ0cyB3aXRoIGB0YXJnZXRgLFxuICAgICAqICBlbHNlIGBmYWxzZWAuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8uc3RhcnRzV2l0aCgnYWJjJywgJ2EnKTtcbiAgICAgKiAvLyA9PiB0cnVlXG4gICAgICpcbiAgICAgKiBfLnN0YXJ0c1dpdGgoJ2FiYycsICdiJyk7XG4gICAgICogLy8gPT4gZmFsc2VcbiAgICAgKlxuICAgICAqIF8uc3RhcnRzV2l0aCgnYWJjJywgJ2InLCAxKTtcbiAgICAgKiAvLyA9PiB0cnVlXG4gICAgICovXG4gICAgZnVuY3Rpb24gc3RhcnRzV2l0aChzdHJpbmcsIHRhcmdldCwgcG9zaXRpb24pIHtcbiAgICAgIHN0cmluZyA9IHRvU3RyaW5nKHN0cmluZyk7XG4gICAgICBwb3NpdGlvbiA9IHBvc2l0aW9uID09IG51bGxcbiAgICAgICAgPyAwXG4gICAgICAgIDogYmFzZUNsYW1wKHRvSW50ZWdlcihwb3NpdGlvbiksIDAsIHN0cmluZy5sZW5ndGgpO1xuXG4gICAgICB0YXJnZXQgPSBiYXNlVG9TdHJpbmcodGFyZ2V0KTtcbiAgICAgIHJldHVybiBzdHJpbmcuc2xpY2UocG9zaXRpb24sIHBvc2l0aW9uICsgdGFyZ2V0Lmxlbmd0aCkgPT0gdGFyZ2V0O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBjb21waWxlZCB0ZW1wbGF0ZSBmdW5jdGlvbiB0aGF0IGNhbiBpbnRlcnBvbGF0ZSBkYXRhIHByb3BlcnRpZXNcbiAgICAgKiBpbiBcImludGVycG9sYXRlXCIgZGVsaW1pdGVycywgSFRNTC1lc2NhcGUgaW50ZXJwb2xhdGVkIGRhdGEgcHJvcGVydGllcyBpblxuICAgICAqIFwiZXNjYXBlXCIgZGVsaW1pdGVycywgYW5kIGV4ZWN1dGUgSmF2YVNjcmlwdCBpbiBcImV2YWx1YXRlXCIgZGVsaW1pdGVycy4gRGF0YVxuICAgICAqIHByb3BlcnRpZXMgbWF5IGJlIGFjY2Vzc2VkIGFzIGZyZWUgdmFyaWFibGVzIGluIHRoZSB0ZW1wbGF0ZS4gSWYgYSBzZXR0aW5nXG4gICAgICogb2JqZWN0IGlzIGdpdmVuLCBpdCB0YWtlcyBwcmVjZWRlbmNlIG92ZXIgYF8udGVtcGxhdGVTZXR0aW5nc2AgdmFsdWVzLlxuICAgICAqXG4gICAgICogKipOb3RlOioqIEluIHRoZSBkZXZlbG9wbWVudCBidWlsZCBgXy50ZW1wbGF0ZWAgdXRpbGl6ZXNcbiAgICAgKiBbc291cmNlVVJMc10oaHR0cDovL3d3dy5odG1sNXJvY2tzLmNvbS9lbi90dXRvcmlhbHMvZGV2ZWxvcGVydG9vbHMvc291cmNlbWFwcy8jdG9jLXNvdXJjZXVybClcbiAgICAgKiBmb3IgZWFzaWVyIGRlYnVnZ2luZy5cbiAgICAgKlxuICAgICAqIEZvciBtb3JlIGluZm9ybWF0aW9uIG9uIHByZWNvbXBpbGluZyB0ZW1wbGF0ZXMgc2VlXG4gICAgICogW2xvZGFzaCdzIGN1c3RvbSBidWlsZHMgZG9jdW1lbnRhdGlvbl0oaHR0cHM6Ly9sb2Rhc2guY29tL2N1c3RvbS1idWlsZHMpLlxuICAgICAqXG4gICAgICogRm9yIG1vcmUgaW5mb3JtYXRpb24gb24gQ2hyb21lIGV4dGVuc2lvbiBzYW5kYm94ZXMgc2VlXG4gICAgICogW0Nocm9tZSdzIGV4dGVuc2lvbnMgZG9jdW1lbnRhdGlvbl0oaHR0cHM6Ly9kZXZlbG9wZXIuY2hyb21lLmNvbS9leHRlbnNpb25zL3NhbmRib3hpbmdFdmFsKS5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAc2luY2UgMC4xLjBcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBjYXRlZ29yeSBTdHJpbmdcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gW3N0cmluZz0nJ10gVGhlIHRlbXBsYXRlIHN0cmluZy5cbiAgICAgKiBAcGFyYW0ge09iamVjdH0gW29wdGlvbnM9e31dIFRoZSBvcHRpb25zIG9iamVjdC5cbiAgICAgKiBAcGFyYW0ge1JlZ0V4cH0gW29wdGlvbnMuZXNjYXBlPV8udGVtcGxhdGVTZXR0aW5ncy5lc2NhcGVdXG4gICAgICogIFRoZSBIVE1MIFwiZXNjYXBlXCIgZGVsaW1pdGVyLlxuICAgICAqIEBwYXJhbSB7UmVnRXhwfSBbb3B0aW9ucy5ldmFsdWF0ZT1fLnRlbXBsYXRlU2V0dGluZ3MuZXZhbHVhdGVdXG4gICAgICogIFRoZSBcImV2YWx1YXRlXCIgZGVsaW1pdGVyLlxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBbb3B0aW9ucy5pbXBvcnRzPV8udGVtcGxhdGVTZXR0aW5ncy5pbXBvcnRzXVxuICAgICAqICBBbiBvYmplY3QgdG8gaW1wb3J0IGludG8gdGhlIHRlbXBsYXRlIGFzIGZyZWUgdmFyaWFibGVzLlxuICAgICAqIEBwYXJhbSB7UmVnRXhwfSBbb3B0aW9ucy5pbnRlcnBvbGF0ZT1fLnRlbXBsYXRlU2V0dGluZ3MuaW50ZXJwb2xhdGVdXG4gICAgICogIFRoZSBcImludGVycG9sYXRlXCIgZGVsaW1pdGVyLlxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBbb3B0aW9ucy5zb3VyY2VVUkw9J2xvZGFzaC50ZW1wbGF0ZVNvdXJjZXNbbl0nXVxuICAgICAqICBUaGUgc291cmNlVVJMIG9mIHRoZSBjb21waWxlZCB0ZW1wbGF0ZS5cbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gW29wdGlvbnMudmFyaWFibGU9J29iaiddXG4gICAgICogIFRoZSBkYXRhIG9iamVjdCB2YXJpYWJsZSBuYW1lLlxuICAgICAqIEBwYXJhbS0ge09iamVjdH0gW2d1YXJkXSBFbmFibGVzIHVzZSBhcyBhbiBpdGVyYXRlZSBmb3IgbWV0aG9kcyBsaWtlIGBfLm1hcGAuXG4gICAgICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBjb21waWxlZCB0ZW1wbGF0ZSBmdW5jdGlvbi5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogLy8gVXNlIHRoZSBcImludGVycG9sYXRlXCIgZGVsaW1pdGVyIHRvIGNyZWF0ZSBhIGNvbXBpbGVkIHRlbXBsYXRlLlxuICAgICAqIHZhciBjb21waWxlZCA9IF8udGVtcGxhdGUoJ2hlbGxvIDwlPSB1c2VyICU+IScpO1xuICAgICAqIGNvbXBpbGVkKHsgJ3VzZXInOiAnZnJlZCcgfSk7XG4gICAgICogLy8gPT4gJ2hlbGxvIGZyZWQhJ1xuICAgICAqXG4gICAgICogLy8gVXNlIHRoZSBIVE1MIFwiZXNjYXBlXCIgZGVsaW1pdGVyIHRvIGVzY2FwZSBkYXRhIHByb3BlcnR5IHZhbHVlcy5cbiAgICAgKiB2YXIgY29tcGlsZWQgPSBfLnRlbXBsYXRlKCc8Yj48JS0gdmFsdWUgJT48L2I+Jyk7XG4gICAgICogY29tcGlsZWQoeyAndmFsdWUnOiAnPHNjcmlwdD4nIH0pO1xuICAgICAqIC8vID0+ICc8Yj4mbHQ7c2NyaXB0Jmd0OzwvYj4nXG4gICAgICpcbiAgICAgKiAvLyBVc2UgdGhlIFwiZXZhbHVhdGVcIiBkZWxpbWl0ZXIgdG8gZXhlY3V0ZSBKYXZhU2NyaXB0IGFuZCBnZW5lcmF0ZSBIVE1MLlxuICAgICAqIHZhciBjb21waWxlZCA9IF8udGVtcGxhdGUoJzwlIF8uZm9yRWFjaCh1c2VycywgZnVuY3Rpb24odXNlcikgeyAlPjxsaT48JS0gdXNlciAlPjwvbGk+PCUgfSk7ICU+Jyk7XG4gICAgICogY29tcGlsZWQoeyAndXNlcnMnOiBbJ2ZyZWQnLCAnYmFybmV5J10gfSk7XG4gICAgICogLy8gPT4gJzxsaT5mcmVkPC9saT48bGk+YmFybmV5PC9saT4nXG4gICAgICpcbiAgICAgKiAvLyBVc2UgdGhlIGludGVybmFsIGBwcmludGAgZnVuY3Rpb24gaW4gXCJldmFsdWF0ZVwiIGRlbGltaXRlcnMuXG4gICAgICogdmFyIGNvbXBpbGVkID0gXy50ZW1wbGF0ZSgnPCUgcHJpbnQoXCJoZWxsbyBcIiArIHVzZXIpOyAlPiEnKTtcbiAgICAgKiBjb21waWxlZCh7ICd1c2VyJzogJ2Jhcm5leScgfSk7XG4gICAgICogLy8gPT4gJ2hlbGxvIGJhcm5leSEnXG4gICAgICpcbiAgICAgKiAvLyBVc2UgdGhlIEVTIHRlbXBsYXRlIGxpdGVyYWwgZGVsaW1pdGVyIGFzIGFuIFwiaW50ZXJwb2xhdGVcIiBkZWxpbWl0ZXIuXG4gICAgICogLy8gRGlzYWJsZSBzdXBwb3J0IGJ5IHJlcGxhY2luZyB0aGUgXCJpbnRlcnBvbGF0ZVwiIGRlbGltaXRlci5cbiAgICAgKiB2YXIgY29tcGlsZWQgPSBfLnRlbXBsYXRlKCdoZWxsbyAkeyB1c2VyIH0hJyk7XG4gICAgICogY29tcGlsZWQoeyAndXNlcic6ICdwZWJibGVzJyB9KTtcbiAgICAgKiAvLyA9PiAnaGVsbG8gcGViYmxlcyEnXG4gICAgICpcbiAgICAgKiAvLyBVc2UgYmFja3NsYXNoZXMgdG8gdHJlYXQgZGVsaW1pdGVycyBhcyBwbGFpbiB0ZXh0LlxuICAgICAqIHZhciBjb21waWxlZCA9IF8udGVtcGxhdGUoJzwlPSBcIlxcXFw8JS0gdmFsdWUgJVxcXFw+XCIgJT4nKTtcbiAgICAgKiBjb21waWxlZCh7ICd2YWx1ZSc6ICdpZ25vcmVkJyB9KTtcbiAgICAgKiAvLyA9PiAnPCUtIHZhbHVlICU+J1xuICAgICAqXG4gICAgICogLy8gVXNlIHRoZSBgaW1wb3J0c2Agb3B0aW9uIHRvIGltcG9ydCBgalF1ZXJ5YCBhcyBganFgLlxuICAgICAqIHZhciB0ZXh0ID0gJzwlIGpxLmVhY2godXNlcnMsIGZ1bmN0aW9uKHVzZXIpIHsgJT48bGk+PCUtIHVzZXIgJT48L2xpPjwlIH0pOyAlPic7XG4gICAgICogdmFyIGNvbXBpbGVkID0gXy50ZW1wbGF0ZSh0ZXh0LCB7ICdpbXBvcnRzJzogeyAnanEnOiBqUXVlcnkgfSB9KTtcbiAgICAgKiBjb21waWxlZCh7ICd1c2Vycyc6IFsnZnJlZCcsICdiYXJuZXknXSB9KTtcbiAgICAgKiAvLyA9PiAnPGxpPmZyZWQ8L2xpPjxsaT5iYXJuZXk8L2xpPidcbiAgICAgKlxuICAgICAqIC8vIFVzZSB0aGUgYHNvdXJjZVVSTGAgb3B0aW9uIHRvIHNwZWNpZnkgYSBjdXN0b20gc291cmNlVVJMIGZvciB0aGUgdGVtcGxhdGUuXG4gICAgICogdmFyIGNvbXBpbGVkID0gXy50ZW1wbGF0ZSgnaGVsbG8gPCU9IHVzZXIgJT4hJywgeyAnc291cmNlVVJMJzogJy9iYXNpYy9ncmVldGluZy5qc3QnIH0pO1xuICAgICAqIGNvbXBpbGVkKGRhdGEpO1xuICAgICAqIC8vID0+IEZpbmQgdGhlIHNvdXJjZSBvZiBcImdyZWV0aW5nLmpzdFwiIHVuZGVyIHRoZSBTb3VyY2VzIHRhYiBvciBSZXNvdXJjZXMgcGFuZWwgb2YgdGhlIHdlYiBpbnNwZWN0b3IuXG4gICAgICpcbiAgICAgKiAvLyBVc2UgdGhlIGB2YXJpYWJsZWAgb3B0aW9uIHRvIGVuc3VyZSBhIHdpdGgtc3RhdGVtZW50IGlzbid0IHVzZWQgaW4gdGhlIGNvbXBpbGVkIHRlbXBsYXRlLlxuICAgICAqIHZhciBjb21waWxlZCA9IF8udGVtcGxhdGUoJ2hpIDwlPSBkYXRhLnVzZXIgJT4hJywgeyAndmFyaWFibGUnOiAnZGF0YScgfSk7XG4gICAgICogY29tcGlsZWQuc291cmNlO1xuICAgICAqIC8vID0+IGZ1bmN0aW9uKGRhdGEpIHtcbiAgICAgKiAvLyAgIHZhciBfX3QsIF9fcCA9ICcnO1xuICAgICAqIC8vICAgX19wICs9ICdoaSAnICsgKChfX3QgPSAoIGRhdGEudXNlciApKSA9PSBudWxsID8gJycgOiBfX3QpICsgJyEnO1xuICAgICAqIC8vICAgcmV0dXJuIF9fcDtcbiAgICAgKiAvLyB9XG4gICAgICpcbiAgICAgKiAvLyBVc2UgY3VzdG9tIHRlbXBsYXRlIGRlbGltaXRlcnMuXG4gICAgICogXy50ZW1wbGF0ZVNldHRpbmdzLmludGVycG9sYXRlID0gL3t7KFtcXHNcXFNdKz8pfX0vZztcbiAgICAgKiB2YXIgY29tcGlsZWQgPSBfLnRlbXBsYXRlKCdoZWxsbyB7eyB1c2VyIH19IScpO1xuICAgICAqIGNvbXBpbGVkKHsgJ3VzZXInOiAnbXVzdGFjaGUnIH0pO1xuICAgICAqIC8vID0+ICdoZWxsbyBtdXN0YWNoZSEnXG4gICAgICpcbiAgICAgKiAvLyBVc2UgdGhlIGBzb3VyY2VgIHByb3BlcnR5IHRvIGlubGluZSBjb21waWxlZCB0ZW1wbGF0ZXMgZm9yIG1lYW5pbmdmdWxcbiAgICAgKiAvLyBsaW5lIG51bWJlcnMgaW4gZXJyb3IgbWVzc2FnZXMgYW5kIHN0YWNrIHRyYWNlcy5cbiAgICAgKiBmcy53cml0ZUZpbGVTeW5jKHBhdGguam9pbihwcm9jZXNzLmN3ZCgpLCAnanN0LmpzJyksICdcXFxuICAgICAqICAgdmFyIEpTVCA9IHtcXFxuICAgICAqICAgICBcIm1haW5cIjogJyArIF8udGVtcGxhdGUobWFpblRleHQpLnNvdXJjZSArICdcXFxuICAgICAqICAgfTtcXFxuICAgICAqICcpO1xuICAgICAqL1xuICAgIGZ1bmN0aW9uIHRlbXBsYXRlKHN0cmluZywgb3B0aW9ucywgZ3VhcmQpIHtcbiAgICAgIC8vIEJhc2VkIG9uIEpvaG4gUmVzaWcncyBgdG1wbGAgaW1wbGVtZW50YXRpb25cbiAgICAgIC8vIChodHRwOi8vZWpvaG4ub3JnL2Jsb2cvamF2YXNjcmlwdC1taWNyby10ZW1wbGF0aW5nLylcbiAgICAgIC8vIGFuZCBMYXVyYSBEb2t0b3JvdmEncyBkb1QuanMgKGh0dHBzOi8vZ2l0aHViLmNvbS9vbGFkby9kb1QpLlxuICAgICAgdmFyIHNldHRpbmdzID0gbG9kYXNoLnRlbXBsYXRlU2V0dGluZ3M7XG5cbiAgICAgIGlmIChndWFyZCAmJiBpc0l0ZXJhdGVlQ2FsbChzdHJpbmcsIG9wdGlvbnMsIGd1YXJkKSkge1xuICAgICAgICBvcHRpb25zID0gdW5kZWZpbmVkO1xuICAgICAgfVxuICAgICAgc3RyaW5nID0gdG9TdHJpbmcoc3RyaW5nKTtcbiAgICAgIG9wdGlvbnMgPSBhc3NpZ25JbldpdGgoe30sIG9wdGlvbnMsIHNldHRpbmdzLCBjdXN0b21EZWZhdWx0c0Fzc2lnbkluKTtcblxuICAgICAgdmFyIGltcG9ydHMgPSBhc3NpZ25JbldpdGgoe30sIG9wdGlvbnMuaW1wb3J0cywgc2V0dGluZ3MuaW1wb3J0cywgY3VzdG9tRGVmYXVsdHNBc3NpZ25JbiksXG4gICAgICAgICAgaW1wb3J0c0tleXMgPSBrZXlzKGltcG9ydHMpLFxuICAgICAgICAgIGltcG9ydHNWYWx1ZXMgPSBiYXNlVmFsdWVzKGltcG9ydHMsIGltcG9ydHNLZXlzKTtcblxuICAgICAgdmFyIGlzRXNjYXBpbmcsXG4gICAgICAgICAgaXNFdmFsdWF0aW5nLFxuICAgICAgICAgIGluZGV4ID0gMCxcbiAgICAgICAgICBpbnRlcnBvbGF0ZSA9IG9wdGlvbnMuaW50ZXJwb2xhdGUgfHwgcmVOb01hdGNoLFxuICAgICAgICAgIHNvdXJjZSA9IFwiX19wICs9ICdcIjtcblxuICAgICAgLy8gQ29tcGlsZSB0aGUgcmVnZXhwIHRvIG1hdGNoIGVhY2ggZGVsaW1pdGVyLlxuICAgICAgdmFyIHJlRGVsaW1pdGVycyA9IFJlZ0V4cChcbiAgICAgICAgKG9wdGlvbnMuZXNjYXBlIHx8IHJlTm9NYXRjaCkuc291cmNlICsgJ3wnICtcbiAgICAgICAgaW50ZXJwb2xhdGUuc291cmNlICsgJ3wnICtcbiAgICAgICAgKGludGVycG9sYXRlID09PSByZUludGVycG9sYXRlID8gcmVFc1RlbXBsYXRlIDogcmVOb01hdGNoKS5zb3VyY2UgKyAnfCcgK1xuICAgICAgICAob3B0aW9ucy5ldmFsdWF0ZSB8fCByZU5vTWF0Y2gpLnNvdXJjZSArICd8JCdcbiAgICAgICwgJ2cnKTtcblxuICAgICAgLy8gVXNlIGEgc291cmNlVVJMIGZvciBlYXNpZXIgZGVidWdnaW5nLlxuICAgICAgdmFyIHNvdXJjZVVSTCA9ICcvLyMgc291cmNlVVJMPScgK1xuICAgICAgICAoJ3NvdXJjZVVSTCcgaW4gb3B0aW9uc1xuICAgICAgICAgID8gb3B0aW9ucy5zb3VyY2VVUkxcbiAgICAgICAgICA6ICgnbG9kYXNoLnRlbXBsYXRlU291cmNlc1snICsgKCsrdGVtcGxhdGVDb3VudGVyKSArICddJylcbiAgICAgICAgKSArICdcXG4nO1xuXG4gICAgICBzdHJpbmcucmVwbGFjZShyZURlbGltaXRlcnMsIGZ1bmN0aW9uKG1hdGNoLCBlc2NhcGVWYWx1ZSwgaW50ZXJwb2xhdGVWYWx1ZSwgZXNUZW1wbGF0ZVZhbHVlLCBldmFsdWF0ZVZhbHVlLCBvZmZzZXQpIHtcbiAgICAgICAgaW50ZXJwb2xhdGVWYWx1ZSB8fCAoaW50ZXJwb2xhdGVWYWx1ZSA9IGVzVGVtcGxhdGVWYWx1ZSk7XG5cbiAgICAgICAgLy8gRXNjYXBlIGNoYXJhY3RlcnMgdGhhdCBjYW4ndCBiZSBpbmNsdWRlZCBpbiBzdHJpbmcgbGl0ZXJhbHMuXG4gICAgICAgIHNvdXJjZSArPSBzdHJpbmcuc2xpY2UoaW5kZXgsIG9mZnNldCkucmVwbGFjZShyZVVuZXNjYXBlZFN0cmluZywgZXNjYXBlU3RyaW5nQ2hhcik7XG5cbiAgICAgICAgLy8gUmVwbGFjZSBkZWxpbWl0ZXJzIHdpdGggc25pcHBldHMuXG4gICAgICAgIGlmIChlc2NhcGVWYWx1ZSkge1xuICAgICAgICAgIGlzRXNjYXBpbmcgPSB0cnVlO1xuICAgICAgICAgIHNvdXJjZSArPSBcIicgK1xcbl9fZShcIiArIGVzY2FwZVZhbHVlICsgXCIpICtcXG4nXCI7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGV2YWx1YXRlVmFsdWUpIHtcbiAgICAgICAgICBpc0V2YWx1YXRpbmcgPSB0cnVlO1xuICAgICAgICAgIHNvdXJjZSArPSBcIic7XFxuXCIgKyBldmFsdWF0ZVZhbHVlICsgXCI7XFxuX19wICs9ICdcIjtcbiAgICAgICAgfVxuICAgICAgICBpZiAoaW50ZXJwb2xhdGVWYWx1ZSkge1xuICAgICAgICAgIHNvdXJjZSArPSBcIicgK1xcbigoX190ID0gKFwiICsgaW50ZXJwb2xhdGVWYWx1ZSArIFwiKSkgPT0gbnVsbCA/ICcnIDogX190KSArXFxuJ1wiO1xuICAgICAgICB9XG4gICAgICAgIGluZGV4ID0gb2Zmc2V0ICsgbWF0Y2gubGVuZ3RoO1xuXG4gICAgICAgIC8vIFRoZSBKUyBlbmdpbmUgZW1iZWRkZWQgaW4gQWRvYmUgcHJvZHVjdHMgbmVlZHMgYG1hdGNoYCByZXR1cm5lZCBpblxuICAgICAgICAvLyBvcmRlciB0byBwcm9kdWNlIHRoZSBjb3JyZWN0IGBvZmZzZXRgIHZhbHVlLlxuICAgICAgICByZXR1cm4gbWF0Y2g7XG4gICAgICB9KTtcblxuICAgICAgc291cmNlICs9IFwiJztcXG5cIjtcblxuICAgICAgLy8gSWYgYHZhcmlhYmxlYCBpcyBub3Qgc3BlY2lmaWVkIHdyYXAgYSB3aXRoLXN0YXRlbWVudCBhcm91bmQgdGhlIGdlbmVyYXRlZFxuICAgICAgLy8gY29kZSB0byBhZGQgdGhlIGRhdGEgb2JqZWN0IHRvIHRoZSB0b3Agb2YgdGhlIHNjb3BlIGNoYWluLlxuICAgICAgdmFyIHZhcmlhYmxlID0gb3B0aW9ucy52YXJpYWJsZTtcbiAgICAgIGlmICghdmFyaWFibGUpIHtcbiAgICAgICAgc291cmNlID0gJ3dpdGggKG9iaikge1xcbicgKyBzb3VyY2UgKyAnXFxufVxcbic7XG4gICAgICB9XG4gICAgICAvLyBDbGVhbnVwIGNvZGUgYnkgc3RyaXBwaW5nIGVtcHR5IHN0cmluZ3MuXG4gICAgICBzb3VyY2UgPSAoaXNFdmFsdWF0aW5nID8gc291cmNlLnJlcGxhY2UocmVFbXB0eVN0cmluZ0xlYWRpbmcsICcnKSA6IHNvdXJjZSlcbiAgICAgICAgLnJlcGxhY2UocmVFbXB0eVN0cmluZ01pZGRsZSwgJyQxJylcbiAgICAgICAgLnJlcGxhY2UocmVFbXB0eVN0cmluZ1RyYWlsaW5nLCAnJDE7Jyk7XG5cbiAgICAgIC8vIEZyYW1lIGNvZGUgYXMgdGhlIGZ1bmN0aW9uIGJvZHkuXG4gICAgICBzb3VyY2UgPSAnZnVuY3Rpb24oJyArICh2YXJpYWJsZSB8fCAnb2JqJykgKyAnKSB7XFxuJyArXG4gICAgICAgICh2YXJpYWJsZVxuICAgICAgICAgID8gJydcbiAgICAgICAgICA6ICdvYmogfHwgKG9iaiA9IHt9KTtcXG4nXG4gICAgICAgICkgK1xuICAgICAgICBcInZhciBfX3QsIF9fcCA9ICcnXCIgK1xuICAgICAgICAoaXNFc2NhcGluZ1xuICAgICAgICAgICA/ICcsIF9fZSA9IF8uZXNjYXBlJ1xuICAgICAgICAgICA6ICcnXG4gICAgICAgICkgK1xuICAgICAgICAoaXNFdmFsdWF0aW5nXG4gICAgICAgICAgPyAnLCBfX2ogPSBBcnJheS5wcm90b3R5cGUuam9pbjtcXG4nICtcbiAgICAgICAgICAgIFwiZnVuY3Rpb24gcHJpbnQoKSB7IF9fcCArPSBfX2ouY2FsbChhcmd1bWVudHMsICcnKSB9XFxuXCJcbiAgICAgICAgICA6ICc7XFxuJ1xuICAgICAgICApICtcbiAgICAgICAgc291cmNlICtcbiAgICAgICAgJ3JldHVybiBfX3BcXG59JztcblxuICAgICAgdmFyIHJlc3VsdCA9IGF0dGVtcHQoZnVuY3Rpb24oKSB7XG4gICAgICAgIHJldHVybiBGdW5jdGlvbihpbXBvcnRzS2V5cywgc291cmNlVVJMICsgJ3JldHVybiAnICsgc291cmNlKVxuICAgICAgICAgIC5hcHBseSh1bmRlZmluZWQsIGltcG9ydHNWYWx1ZXMpO1xuICAgICAgfSk7XG5cbiAgICAgIC8vIFByb3ZpZGUgdGhlIGNvbXBpbGVkIGZ1bmN0aW9uJ3Mgc291cmNlIGJ5IGl0cyBgdG9TdHJpbmdgIG1ldGhvZCBvclxuICAgICAgLy8gdGhlIGBzb3VyY2VgIHByb3BlcnR5IGFzIGEgY29udmVuaWVuY2UgZm9yIGlubGluaW5nIGNvbXBpbGVkIHRlbXBsYXRlcy5cbiAgICAgIHJlc3VsdC5zb3VyY2UgPSBzb3VyY2U7XG4gICAgICBpZiAoaXNFcnJvcihyZXN1bHQpKSB7XG4gICAgICAgIHRocm93IHJlc3VsdDtcbiAgICAgIH1cbiAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ29udmVydHMgYHN0cmluZ2AsIGFzIGEgd2hvbGUsIHRvIGxvd2VyIGNhc2UganVzdCBsaWtlXG4gICAgICogW1N0cmluZyN0b0xvd2VyQ2FzZV0oaHR0cHM6Ly9tZG4uaW8vdG9Mb3dlckNhc2UpLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDQuMC4wXG4gICAgICogQGNhdGVnb3J5IFN0cmluZ1xuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBbc3RyaW5nPScnXSBUaGUgc3RyaW5nIHRvIGNvbnZlcnQuXG4gICAgICogQHJldHVybnMge3N0cmluZ30gUmV0dXJucyB0aGUgbG93ZXIgY2FzZWQgc3RyaW5nLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLnRvTG93ZXIoJy0tRm9vLUJhci0tJyk7XG4gICAgICogLy8gPT4gJy0tZm9vLWJhci0tJ1xuICAgICAqXG4gICAgICogXy50b0xvd2VyKCdmb29CYXInKTtcbiAgICAgKiAvLyA9PiAnZm9vYmFyJ1xuICAgICAqXG4gICAgICogXy50b0xvd2VyKCdfX0ZPT19CQVJfXycpO1xuICAgICAqIC8vID0+ICdfX2Zvb19iYXJfXydcbiAgICAgKi9cbiAgICBmdW5jdGlvbiB0b0xvd2VyKHZhbHVlKSB7XG4gICAgICByZXR1cm4gdG9TdHJpbmcodmFsdWUpLnRvTG93ZXJDYXNlKCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ29udmVydHMgYHN0cmluZ2AsIGFzIGEgd2hvbGUsIHRvIHVwcGVyIGNhc2UganVzdCBsaWtlXG4gICAgICogW1N0cmluZyN0b1VwcGVyQ2FzZV0oaHR0cHM6Ly9tZG4uaW8vdG9VcHBlckNhc2UpLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDQuMC4wXG4gICAgICogQGNhdGVnb3J5IFN0cmluZ1xuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBbc3RyaW5nPScnXSBUaGUgc3RyaW5nIHRvIGNvbnZlcnQuXG4gICAgICogQHJldHVybnMge3N0cmluZ30gUmV0dXJucyB0aGUgdXBwZXIgY2FzZWQgc3RyaW5nLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLnRvVXBwZXIoJy0tZm9vLWJhci0tJyk7XG4gICAgICogLy8gPT4gJy0tRk9PLUJBUi0tJ1xuICAgICAqXG4gICAgICogXy50b1VwcGVyKCdmb29CYXInKTtcbiAgICAgKiAvLyA9PiAnRk9PQkFSJ1xuICAgICAqXG4gICAgICogXy50b1VwcGVyKCdfX2Zvb19iYXJfXycpO1xuICAgICAqIC8vID0+ICdfX0ZPT19CQVJfXydcbiAgICAgKi9cbiAgICBmdW5jdGlvbiB0b1VwcGVyKHZhbHVlKSB7XG4gICAgICByZXR1cm4gdG9TdHJpbmcodmFsdWUpLnRvVXBwZXJDYXNlKCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUmVtb3ZlcyBsZWFkaW5nIGFuZCB0cmFpbGluZyB3aGl0ZXNwYWNlIG9yIHNwZWNpZmllZCBjaGFyYWN0ZXJzIGZyb20gYHN0cmluZ2AuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMy4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgU3RyaW5nXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IFtzdHJpbmc9JyddIFRoZSBzdHJpbmcgdG8gdHJpbS5cbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gW2NoYXJzPXdoaXRlc3BhY2VdIFRoZSBjaGFyYWN0ZXJzIHRvIHRyaW0uXG4gICAgICogQHBhcmFtLSB7T2JqZWN0fSBbZ3VhcmRdIEVuYWJsZXMgdXNlIGFzIGFuIGl0ZXJhdGVlIGZvciBtZXRob2RzIGxpa2UgYF8ubWFwYC5cbiAgICAgKiBAcmV0dXJucyB7c3RyaW5nfSBSZXR1cm5zIHRoZSB0cmltbWVkIHN0cmluZy5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy50cmltKCcgIGFiYyAgJyk7XG4gICAgICogLy8gPT4gJ2FiYydcbiAgICAgKlxuICAgICAqIF8udHJpbSgnLV8tYWJjLV8tJywgJ18tJyk7XG4gICAgICogLy8gPT4gJ2FiYydcbiAgICAgKlxuICAgICAqIF8ubWFwKFsnICBmb28gICcsICcgIGJhciAgJ10sIF8udHJpbSk7XG4gICAgICogLy8gPT4gWydmb28nLCAnYmFyJ11cbiAgICAgKi9cbiAgICBmdW5jdGlvbiB0cmltKHN0cmluZywgY2hhcnMsIGd1YXJkKSB7XG4gICAgICBzdHJpbmcgPSB0b1N0cmluZyhzdHJpbmcpO1xuICAgICAgaWYgKHN0cmluZyAmJiAoZ3VhcmQgfHwgY2hhcnMgPT09IHVuZGVmaW5lZCkpIHtcbiAgICAgICAgcmV0dXJuIHN0cmluZy5yZXBsYWNlKHJlVHJpbSwgJycpO1xuICAgICAgfVxuICAgICAgaWYgKCFzdHJpbmcgfHwgIShjaGFycyA9IGJhc2VUb1N0cmluZyhjaGFycykpKSB7XG4gICAgICAgIHJldHVybiBzdHJpbmc7XG4gICAgICB9XG4gICAgICB2YXIgc3RyU3ltYm9scyA9IHN0cmluZ1RvQXJyYXkoc3RyaW5nKSxcbiAgICAgICAgICBjaHJTeW1ib2xzID0gc3RyaW5nVG9BcnJheShjaGFycyksXG4gICAgICAgICAgc3RhcnQgPSBjaGFyc1N0YXJ0SW5kZXgoc3RyU3ltYm9scywgY2hyU3ltYm9scyksXG4gICAgICAgICAgZW5kID0gY2hhcnNFbmRJbmRleChzdHJTeW1ib2xzLCBjaHJTeW1ib2xzKSArIDE7XG5cbiAgICAgIHJldHVybiBjYXN0U2xpY2Uoc3RyU3ltYm9scywgc3RhcnQsIGVuZCkuam9pbignJyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUmVtb3ZlcyB0cmFpbGluZyB3aGl0ZXNwYWNlIG9yIHNwZWNpZmllZCBjaGFyYWN0ZXJzIGZyb20gYHN0cmluZ2AuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgNC4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgU3RyaW5nXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IFtzdHJpbmc9JyddIFRoZSBzdHJpbmcgdG8gdHJpbS5cbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gW2NoYXJzPXdoaXRlc3BhY2VdIFRoZSBjaGFyYWN0ZXJzIHRvIHRyaW0uXG4gICAgICogQHBhcmFtLSB7T2JqZWN0fSBbZ3VhcmRdIEVuYWJsZXMgdXNlIGFzIGFuIGl0ZXJhdGVlIGZvciBtZXRob2RzIGxpa2UgYF8ubWFwYC5cbiAgICAgKiBAcmV0dXJucyB7c3RyaW5nfSBSZXR1cm5zIHRoZSB0cmltbWVkIHN0cmluZy5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy50cmltRW5kKCcgIGFiYyAgJyk7XG4gICAgICogLy8gPT4gJyAgYWJjJ1xuICAgICAqXG4gICAgICogXy50cmltRW5kKCctXy1hYmMtXy0nLCAnXy0nKTtcbiAgICAgKiAvLyA9PiAnLV8tYWJjJ1xuICAgICAqL1xuICAgIGZ1bmN0aW9uIHRyaW1FbmQoc3RyaW5nLCBjaGFycywgZ3VhcmQpIHtcbiAgICAgIHN0cmluZyA9IHRvU3RyaW5nKHN0cmluZyk7XG4gICAgICBpZiAoc3RyaW5nICYmIChndWFyZCB8fCBjaGFycyA9PT0gdW5kZWZpbmVkKSkge1xuICAgICAgICByZXR1cm4gc3RyaW5nLnJlcGxhY2UocmVUcmltRW5kLCAnJyk7XG4gICAgICB9XG4gICAgICBpZiAoIXN0cmluZyB8fCAhKGNoYXJzID0gYmFzZVRvU3RyaW5nKGNoYXJzKSkpIHtcbiAgICAgICAgcmV0dXJuIHN0cmluZztcbiAgICAgIH1cbiAgICAgIHZhciBzdHJTeW1ib2xzID0gc3RyaW5nVG9BcnJheShzdHJpbmcpLFxuICAgICAgICAgIGVuZCA9IGNoYXJzRW5kSW5kZXgoc3RyU3ltYm9scywgc3RyaW5nVG9BcnJheShjaGFycykpICsgMTtcblxuICAgICAgcmV0dXJuIGNhc3RTbGljZShzdHJTeW1ib2xzLCAwLCBlbmQpLmpvaW4oJycpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJlbW92ZXMgbGVhZGluZyB3aGl0ZXNwYWNlIG9yIHNwZWNpZmllZCBjaGFyYWN0ZXJzIGZyb20gYHN0cmluZ2AuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgNC4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgU3RyaW5nXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IFtzdHJpbmc9JyddIFRoZSBzdHJpbmcgdG8gdHJpbS5cbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gW2NoYXJzPXdoaXRlc3BhY2VdIFRoZSBjaGFyYWN0ZXJzIHRvIHRyaW0uXG4gICAgICogQHBhcmFtLSB7T2JqZWN0fSBbZ3VhcmRdIEVuYWJsZXMgdXNlIGFzIGFuIGl0ZXJhdGVlIGZvciBtZXRob2RzIGxpa2UgYF8ubWFwYC5cbiAgICAgKiBAcmV0dXJucyB7c3RyaW5nfSBSZXR1cm5zIHRoZSB0cmltbWVkIHN0cmluZy5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy50cmltU3RhcnQoJyAgYWJjICAnKTtcbiAgICAgKiAvLyA9PiAnYWJjICAnXG4gICAgICpcbiAgICAgKiBfLnRyaW1TdGFydCgnLV8tYWJjLV8tJywgJ18tJyk7XG4gICAgICogLy8gPT4gJ2FiYy1fLSdcbiAgICAgKi9cbiAgICBmdW5jdGlvbiB0cmltU3RhcnQoc3RyaW5nLCBjaGFycywgZ3VhcmQpIHtcbiAgICAgIHN0cmluZyA9IHRvU3RyaW5nKHN0cmluZyk7XG4gICAgICBpZiAoc3RyaW5nICYmIChndWFyZCB8fCBjaGFycyA9PT0gdW5kZWZpbmVkKSkge1xuICAgICAgICByZXR1cm4gc3RyaW5nLnJlcGxhY2UocmVUcmltU3RhcnQsICcnKTtcbiAgICAgIH1cbiAgICAgIGlmICghc3RyaW5nIHx8ICEoY2hhcnMgPSBiYXNlVG9TdHJpbmcoY2hhcnMpKSkge1xuICAgICAgICByZXR1cm4gc3RyaW5nO1xuICAgICAgfVxuICAgICAgdmFyIHN0clN5bWJvbHMgPSBzdHJpbmdUb0FycmF5KHN0cmluZyksXG4gICAgICAgICAgc3RhcnQgPSBjaGFyc1N0YXJ0SW5kZXgoc3RyU3ltYm9scywgc3RyaW5nVG9BcnJheShjaGFycykpO1xuXG4gICAgICByZXR1cm4gY2FzdFNsaWNlKHN0clN5bWJvbHMsIHN0YXJ0KS5qb2luKCcnKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUcnVuY2F0ZXMgYHN0cmluZ2AgaWYgaXQncyBsb25nZXIgdGhhbiB0aGUgZ2l2ZW4gbWF4aW11bSBzdHJpbmcgbGVuZ3RoLlxuICAgICAqIFRoZSBsYXN0IGNoYXJhY3RlcnMgb2YgdGhlIHRydW5jYXRlZCBzdHJpbmcgYXJlIHJlcGxhY2VkIHdpdGggdGhlIG9taXNzaW9uXG4gICAgICogc3RyaW5nIHdoaWNoIGRlZmF1bHRzIHRvIFwiLi4uXCIuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgNC4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgU3RyaW5nXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IFtzdHJpbmc9JyddIFRoZSBzdHJpbmcgdG8gdHJ1bmNhdGUuXG4gICAgICogQHBhcmFtIHtPYmplY3R9IFtvcHRpb25zPXt9XSBUaGUgb3B0aW9ucyBvYmplY3QuXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IFtvcHRpb25zLmxlbmd0aD0zMF0gVGhlIG1heGltdW0gc3RyaW5nIGxlbmd0aC5cbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gW29wdGlvbnMub21pc3Npb249Jy4uLiddIFRoZSBzdHJpbmcgdG8gaW5kaWNhdGUgdGV4dCBpcyBvbWl0dGVkLlxuICAgICAqIEBwYXJhbSB7UmVnRXhwfHN0cmluZ30gW29wdGlvbnMuc2VwYXJhdG9yXSBUaGUgc2VwYXJhdG9yIHBhdHRlcm4gdG8gdHJ1bmNhdGUgdG8uXG4gICAgICogQHJldHVybnMge3N0cmluZ30gUmV0dXJucyB0aGUgdHJ1bmNhdGVkIHN0cmluZy5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy50cnVuY2F0ZSgnaGktZGlkZGx5LWhvIHRoZXJlLCBuZWlnaGJvcmlubycpO1xuICAgICAqIC8vID0+ICdoaS1kaWRkbHktaG8gdGhlcmUsIG5laWdoYm8uLi4nXG4gICAgICpcbiAgICAgKiBfLnRydW5jYXRlKCdoaS1kaWRkbHktaG8gdGhlcmUsIG5laWdoYm9yaW5vJywge1xuICAgICAqICAgJ2xlbmd0aCc6IDI0LFxuICAgICAqICAgJ3NlcGFyYXRvcic6ICcgJ1xuICAgICAqIH0pO1xuICAgICAqIC8vID0+ICdoaS1kaWRkbHktaG8gdGhlcmUsLi4uJ1xuICAgICAqXG4gICAgICogXy50cnVuY2F0ZSgnaGktZGlkZGx5LWhvIHRoZXJlLCBuZWlnaGJvcmlubycsIHtcbiAgICAgKiAgICdsZW5ndGgnOiAyNCxcbiAgICAgKiAgICdzZXBhcmF0b3InOiAvLD8gKy9cbiAgICAgKiB9KTtcbiAgICAgKiAvLyA9PiAnaGktZGlkZGx5LWhvIHRoZXJlLi4uJ1xuICAgICAqXG4gICAgICogXy50cnVuY2F0ZSgnaGktZGlkZGx5LWhvIHRoZXJlLCBuZWlnaGJvcmlubycsIHtcbiAgICAgKiAgICdvbWlzc2lvbic6ICcgWy4uLl0nXG4gICAgICogfSk7XG4gICAgICogLy8gPT4gJ2hpLWRpZGRseS1obyB0aGVyZSwgbmVpZyBbLi4uXSdcbiAgICAgKi9cbiAgICBmdW5jdGlvbiB0cnVuY2F0ZShzdHJpbmcsIG9wdGlvbnMpIHtcbiAgICAgIHZhciBsZW5ndGggPSBERUZBVUxUX1RSVU5DX0xFTkdUSCxcbiAgICAgICAgICBvbWlzc2lvbiA9IERFRkFVTFRfVFJVTkNfT01JU1NJT047XG5cbiAgICAgIGlmIChpc09iamVjdChvcHRpb25zKSkge1xuICAgICAgICB2YXIgc2VwYXJhdG9yID0gJ3NlcGFyYXRvcicgaW4gb3B0aW9ucyA/IG9wdGlvbnMuc2VwYXJhdG9yIDogc2VwYXJhdG9yO1xuICAgICAgICBsZW5ndGggPSAnbGVuZ3RoJyBpbiBvcHRpb25zID8gdG9JbnRlZ2VyKG9wdGlvbnMubGVuZ3RoKSA6IGxlbmd0aDtcbiAgICAgICAgb21pc3Npb24gPSAnb21pc3Npb24nIGluIG9wdGlvbnMgPyBiYXNlVG9TdHJpbmcob3B0aW9ucy5vbWlzc2lvbikgOiBvbWlzc2lvbjtcbiAgICAgIH1cbiAgICAgIHN0cmluZyA9IHRvU3RyaW5nKHN0cmluZyk7XG5cbiAgICAgIHZhciBzdHJMZW5ndGggPSBzdHJpbmcubGVuZ3RoO1xuICAgICAgaWYgKGhhc1VuaWNvZGUoc3RyaW5nKSkge1xuICAgICAgICB2YXIgc3RyU3ltYm9scyA9IHN0cmluZ1RvQXJyYXkoc3RyaW5nKTtcbiAgICAgICAgc3RyTGVuZ3RoID0gc3RyU3ltYm9scy5sZW5ndGg7XG4gICAgICB9XG4gICAgICBpZiAobGVuZ3RoID49IHN0ckxlbmd0aCkge1xuICAgICAgICByZXR1cm4gc3RyaW5nO1xuICAgICAgfVxuICAgICAgdmFyIGVuZCA9IGxlbmd0aCAtIHN0cmluZ1NpemUob21pc3Npb24pO1xuICAgICAgaWYgKGVuZCA8IDEpIHtcbiAgICAgICAgcmV0dXJuIG9taXNzaW9uO1xuICAgICAgfVxuICAgICAgdmFyIHJlc3VsdCA9IHN0clN5bWJvbHNcbiAgICAgICAgPyBjYXN0U2xpY2Uoc3RyU3ltYm9scywgMCwgZW5kKS5qb2luKCcnKVxuICAgICAgICA6IHN0cmluZy5zbGljZSgwLCBlbmQpO1xuXG4gICAgICBpZiAoc2VwYXJhdG9yID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgcmV0dXJuIHJlc3VsdCArIG9taXNzaW9uO1xuICAgICAgfVxuICAgICAgaWYgKHN0clN5bWJvbHMpIHtcbiAgICAgICAgZW5kICs9IChyZXN1bHQubGVuZ3RoIC0gZW5kKTtcbiAgICAgIH1cbiAgICAgIGlmIChpc1JlZ0V4cChzZXBhcmF0b3IpKSB7XG4gICAgICAgIGlmIChzdHJpbmcuc2xpY2UoZW5kKS5zZWFyY2goc2VwYXJhdG9yKSkge1xuICAgICAgICAgIHZhciBtYXRjaCxcbiAgICAgICAgICAgICAgc3Vic3RyaW5nID0gcmVzdWx0O1xuXG4gICAgICAgICAgaWYgKCFzZXBhcmF0b3IuZ2xvYmFsKSB7XG4gICAgICAgICAgICBzZXBhcmF0b3IgPSBSZWdFeHAoc2VwYXJhdG9yLnNvdXJjZSwgdG9TdHJpbmcocmVGbGFncy5leGVjKHNlcGFyYXRvcikpICsgJ2cnKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgc2VwYXJhdG9yLmxhc3RJbmRleCA9IDA7XG4gICAgICAgICAgd2hpbGUgKChtYXRjaCA9IHNlcGFyYXRvci5leGVjKHN1YnN0cmluZykpKSB7XG4gICAgICAgICAgICB2YXIgbmV3RW5kID0gbWF0Y2guaW5kZXg7XG4gICAgICAgICAgfVxuICAgICAgICAgIHJlc3VsdCA9IHJlc3VsdC5zbGljZSgwLCBuZXdFbmQgPT09IHVuZGVmaW5lZCA/IGVuZCA6IG5ld0VuZCk7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSBpZiAoc3RyaW5nLmluZGV4T2YoYmFzZVRvU3RyaW5nKHNlcGFyYXRvciksIGVuZCkgIT0gZW5kKSB7XG4gICAgICAgIHZhciBpbmRleCA9IHJlc3VsdC5sYXN0SW5kZXhPZihzZXBhcmF0b3IpO1xuICAgICAgICBpZiAoaW5kZXggPiAtMSkge1xuICAgICAgICAgIHJlc3VsdCA9IHJlc3VsdC5zbGljZSgwLCBpbmRleCk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHJldHVybiByZXN1bHQgKyBvbWlzc2lvbjtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGUgaW52ZXJzZSBvZiBgXy5lc2NhcGVgOyB0aGlzIG1ldGhvZCBjb252ZXJ0cyB0aGUgSFRNTCBlbnRpdGllc1xuICAgICAqIGAmYW1wO2AsIGAmbHQ7YCwgYCZndDtgLCBgJnF1b3Q7YCwgYW5kIGAmIzM5O2AgaW4gYHN0cmluZ2AgdG9cbiAgICAgKiB0aGVpciBjb3JyZXNwb25kaW5nIGNoYXJhY3RlcnMuXG4gICAgICpcbiAgICAgKiAqKk5vdGU6KiogTm8gb3RoZXIgSFRNTCBlbnRpdGllcyBhcmUgdW5lc2NhcGVkLiBUbyB1bmVzY2FwZSBhZGRpdGlvbmFsXG4gICAgICogSFRNTCBlbnRpdGllcyB1c2UgYSB0aGlyZC1wYXJ0eSBsaWJyYXJ5IGxpa2UgW19oZV9dKGh0dHBzOi8vbXRocy5iZS9oZSkuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMC42LjBcbiAgICAgKiBAY2F0ZWdvcnkgU3RyaW5nXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IFtzdHJpbmc9JyddIFRoZSBzdHJpbmcgdG8gdW5lc2NhcGUuXG4gICAgICogQHJldHVybnMge3N0cmluZ30gUmV0dXJucyB0aGUgdW5lc2NhcGVkIHN0cmluZy5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy51bmVzY2FwZSgnZnJlZCwgYmFybmV5LCAmYW1wOyBwZWJibGVzJyk7XG4gICAgICogLy8gPT4gJ2ZyZWQsIGJhcm5leSwgJiBwZWJibGVzJ1xuICAgICAqL1xuICAgIGZ1bmN0aW9uIHVuZXNjYXBlKHN0cmluZykge1xuICAgICAgc3RyaW5nID0gdG9TdHJpbmcoc3RyaW5nKTtcbiAgICAgIHJldHVybiAoc3RyaW5nICYmIHJlSGFzRXNjYXBlZEh0bWwudGVzdChzdHJpbmcpKVxuICAgICAgICA/IHN0cmluZy5yZXBsYWNlKHJlRXNjYXBlZEh0bWwsIHVuZXNjYXBlSHRtbENoYXIpXG4gICAgICAgIDogc3RyaW5nO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENvbnZlcnRzIGBzdHJpbmdgLCBhcyBzcGFjZSBzZXBhcmF0ZWQgd29yZHMsIHRvIHVwcGVyIGNhc2UuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgNC4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgU3RyaW5nXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IFtzdHJpbmc9JyddIFRoZSBzdHJpbmcgdG8gY29udmVydC5cbiAgICAgKiBAcmV0dXJucyB7c3RyaW5nfSBSZXR1cm5zIHRoZSB1cHBlciBjYXNlZCBzdHJpbmcuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8udXBwZXJDYXNlKCctLWZvby1iYXInKTtcbiAgICAgKiAvLyA9PiAnRk9PIEJBUidcbiAgICAgKlxuICAgICAqIF8udXBwZXJDYXNlKCdmb29CYXInKTtcbiAgICAgKiAvLyA9PiAnRk9PIEJBUidcbiAgICAgKlxuICAgICAqIF8udXBwZXJDYXNlKCdfX2Zvb19iYXJfXycpO1xuICAgICAqIC8vID0+ICdGT08gQkFSJ1xuICAgICAqL1xuICAgIHZhciB1cHBlckNhc2UgPSBjcmVhdGVDb21wb3VuZGVyKGZ1bmN0aW9uKHJlc3VsdCwgd29yZCwgaW5kZXgpIHtcbiAgICAgIHJldHVybiByZXN1bHQgKyAoaW5kZXggPyAnICcgOiAnJykgKyB3b3JkLnRvVXBwZXJDYXNlKCk7XG4gICAgfSk7XG5cbiAgICAvKipcbiAgICAgKiBDb252ZXJ0cyB0aGUgZmlyc3QgY2hhcmFjdGVyIG9mIGBzdHJpbmdgIHRvIHVwcGVyIGNhc2UuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgNC4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgU3RyaW5nXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IFtzdHJpbmc9JyddIFRoZSBzdHJpbmcgdG8gY29udmVydC5cbiAgICAgKiBAcmV0dXJucyB7c3RyaW5nfSBSZXR1cm5zIHRoZSBjb252ZXJ0ZWQgc3RyaW5nLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLnVwcGVyRmlyc3QoJ2ZyZWQnKTtcbiAgICAgKiAvLyA9PiAnRnJlZCdcbiAgICAgKlxuICAgICAqIF8udXBwZXJGaXJzdCgnRlJFRCcpO1xuICAgICAqIC8vID0+ICdGUkVEJ1xuICAgICAqL1xuICAgIHZhciB1cHBlckZpcnN0ID0gY3JlYXRlQ2FzZUZpcnN0KCd0b1VwcGVyQ2FzZScpO1xuXG4gICAgLyoqXG4gICAgICogU3BsaXRzIGBzdHJpbmdgIGludG8gYW4gYXJyYXkgb2YgaXRzIHdvcmRzLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDMuMC4wXG4gICAgICogQGNhdGVnb3J5IFN0cmluZ1xuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBbc3RyaW5nPScnXSBUaGUgc3RyaW5nIHRvIGluc3BlY3QuXG4gICAgICogQHBhcmFtIHtSZWdFeHB8c3RyaW5nfSBbcGF0dGVybl0gVGhlIHBhdHRlcm4gdG8gbWF0Y2ggd29yZHMuXG4gICAgICogQHBhcmFtLSB7T2JqZWN0fSBbZ3VhcmRdIEVuYWJsZXMgdXNlIGFzIGFuIGl0ZXJhdGVlIGZvciBtZXRob2RzIGxpa2UgYF8ubWFwYC5cbiAgICAgKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIHdvcmRzIG9mIGBzdHJpbmdgLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLndvcmRzKCdmcmVkLCBiYXJuZXksICYgcGViYmxlcycpO1xuICAgICAqIC8vID0+IFsnZnJlZCcsICdiYXJuZXknLCAncGViYmxlcyddXG4gICAgICpcbiAgICAgKiBfLndvcmRzKCdmcmVkLCBiYXJuZXksICYgcGViYmxlcycsIC9bXiwgXSsvZyk7XG4gICAgICogLy8gPT4gWydmcmVkJywgJ2Jhcm5leScsICcmJywgJ3BlYmJsZXMnXVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIHdvcmRzKHN0cmluZywgcGF0dGVybiwgZ3VhcmQpIHtcbiAgICAgIHN0cmluZyA9IHRvU3RyaW5nKHN0cmluZyk7XG4gICAgICBwYXR0ZXJuID0gZ3VhcmQgPyB1bmRlZmluZWQgOiBwYXR0ZXJuO1xuXG4gICAgICBpZiAocGF0dGVybiA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHJldHVybiBoYXNVbmljb2RlV29yZChzdHJpbmcpID8gdW5pY29kZVdvcmRzKHN0cmluZykgOiBhc2NpaVdvcmRzKHN0cmluZyk7XG4gICAgICB9XG4gICAgICByZXR1cm4gc3RyaW5nLm1hdGNoKHBhdHRlcm4pIHx8IFtdO1xuICAgIH1cblxuICAgIC8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi9cblxuICAgIC8qKlxuICAgICAqIEF0dGVtcHRzIHRvIGludm9rZSBgZnVuY2AsIHJldHVybmluZyBlaXRoZXIgdGhlIHJlc3VsdCBvciB0aGUgY2F1Z2h0IGVycm9yXG4gICAgICogb2JqZWN0LiBBbnkgYWRkaXRpb25hbCBhcmd1bWVudHMgYXJlIHByb3ZpZGVkIHRvIGBmdW5jYCB3aGVuIGl0J3MgaW52b2tlZC5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAzLjAuMFxuICAgICAqIEBjYXRlZ29yeSBVdGlsXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gZnVuYyBUaGUgZnVuY3Rpb24gdG8gYXR0ZW1wdC5cbiAgICAgKiBAcGFyYW0gey4uLip9IFthcmdzXSBUaGUgYXJndW1lbnRzIHRvIGludm9rZSBgZnVuY2Agd2l0aC5cbiAgICAgKiBAcmV0dXJucyB7Kn0gUmV0dXJucyB0aGUgYGZ1bmNgIHJlc3VsdCBvciBlcnJvciBvYmplY3QuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIC8vIEF2b2lkIHRocm93aW5nIGVycm9ycyBmb3IgaW52YWxpZCBzZWxlY3RvcnMuXG4gICAgICogdmFyIGVsZW1lbnRzID0gXy5hdHRlbXB0KGZ1bmN0aW9uKHNlbGVjdG9yKSB7XG4gICAgICogICByZXR1cm4gZG9jdW1lbnQucXVlcnlTZWxlY3RvckFsbChzZWxlY3Rvcik7XG4gICAgICogfSwgJz5fPicpO1xuICAgICAqXG4gICAgICogaWYgKF8uaXNFcnJvcihlbGVtZW50cykpIHtcbiAgICAgKiAgIGVsZW1lbnRzID0gW107XG4gICAgICogfVxuICAgICAqL1xuICAgIHZhciBhdHRlbXB0ID0gYmFzZVJlc3QoZnVuY3Rpb24oZnVuYywgYXJncykge1xuICAgICAgdHJ5IHtcbiAgICAgICAgcmV0dXJuIGFwcGx5KGZ1bmMsIHVuZGVmaW5lZCwgYXJncyk7XG4gICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIHJldHVybiBpc0Vycm9yKGUpID8gZSA6IG5ldyBFcnJvcihlKTtcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIC8qKlxuICAgICAqIEJpbmRzIG1ldGhvZHMgb2YgYW4gb2JqZWN0IHRvIHRoZSBvYmplY3QgaXRzZWxmLCBvdmVyd3JpdGluZyB0aGUgZXhpc3RpbmdcbiAgICAgKiBtZXRob2QuXG4gICAgICpcbiAgICAgKiAqKk5vdGU6KiogVGhpcyBtZXRob2QgZG9lc24ndCBzZXQgdGhlIFwibGVuZ3RoXCIgcHJvcGVydHkgb2YgYm91bmQgZnVuY3Rpb25zLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBzaW5jZSAwLjEuMFxuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQGNhdGVnb3J5IFV0aWxcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gYmluZCBhbmQgYXNzaWduIHRoZSBib3VuZCBtZXRob2RzIHRvLlxuICAgICAqIEBwYXJhbSB7Li4uKHN0cmluZ3xzdHJpbmdbXSl9IG1ldGhvZE5hbWVzIFRoZSBvYmplY3QgbWV0aG9kIG5hbWVzIHRvIGJpbmQuXG4gICAgICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyBgb2JqZWN0YC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogdmFyIHZpZXcgPSB7XG4gICAgICogICAnbGFiZWwnOiAnZG9jcycsXG4gICAgICogICAnY2xpY2snOiBmdW5jdGlvbigpIHtcbiAgICAgKiAgICAgY29uc29sZS5sb2coJ2NsaWNrZWQgJyArIHRoaXMubGFiZWwpO1xuICAgICAqICAgfVxuICAgICAqIH07XG4gICAgICpcbiAgICAgKiBfLmJpbmRBbGwodmlldywgWydjbGljayddKTtcbiAgICAgKiBqUXVlcnkoZWxlbWVudCkub24oJ2NsaWNrJywgdmlldy5jbGljayk7XG4gICAgICogLy8gPT4gTG9ncyAnY2xpY2tlZCBkb2NzJyB3aGVuIGNsaWNrZWQuXG4gICAgICovXG4gICAgdmFyIGJpbmRBbGwgPSBmbGF0UmVzdChmdW5jdGlvbihvYmplY3QsIG1ldGhvZE5hbWVzKSB7XG4gICAgICBhcnJheUVhY2gobWV0aG9kTmFtZXMsIGZ1bmN0aW9uKGtleSkge1xuICAgICAgICBrZXkgPSB0b0tleShrZXkpO1xuICAgICAgICBiYXNlQXNzaWduVmFsdWUob2JqZWN0LCBrZXksIGJpbmQob2JqZWN0W2tleV0sIG9iamVjdCkpO1xuICAgICAgfSk7XG4gICAgICByZXR1cm4gb2JqZWN0O1xuICAgIH0pO1xuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIGZ1bmN0aW9uIHRoYXQgaXRlcmF0ZXMgb3ZlciBgcGFpcnNgIGFuZCBpbnZva2VzIHRoZSBjb3JyZXNwb25kaW5nXG4gICAgICogZnVuY3Rpb24gb2YgdGhlIGZpcnN0IHByZWRpY2F0ZSB0byByZXR1cm4gdHJ1dGh5LiBUaGUgcHJlZGljYXRlLWZ1bmN0aW9uXG4gICAgICogcGFpcnMgYXJlIGludm9rZWQgd2l0aCB0aGUgYHRoaXNgIGJpbmRpbmcgYW5kIGFyZ3VtZW50cyBvZiB0aGUgY3JlYXRlZFxuICAgICAqIGZ1bmN0aW9uLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDQuMC4wXG4gICAgICogQGNhdGVnb3J5IFV0aWxcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBwYWlycyBUaGUgcHJlZGljYXRlLWZ1bmN0aW9uIHBhaXJzLlxuICAgICAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyB0aGUgbmV3IGNvbXBvc2l0ZSBmdW5jdGlvbi5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogdmFyIGZ1bmMgPSBfLmNvbmQoW1xuICAgICAqICAgW18ubWF0Y2hlcyh7ICdhJzogMSB9KSwgICAgICAgICAgIF8uY29uc3RhbnQoJ21hdGNoZXMgQScpXSxcbiAgICAgKiAgIFtfLmNvbmZvcm1zKHsgJ2InOiBfLmlzTnVtYmVyIH0pLCBfLmNvbnN0YW50KCdtYXRjaGVzIEInKV0sXG4gICAgICogICBbXy5zdHViVHJ1ZSwgICAgICAgICAgICAgICAgICAgICAgXy5jb25zdGFudCgnbm8gbWF0Y2gnKV1cbiAgICAgKiBdKTtcbiAgICAgKlxuICAgICAqIGZ1bmMoeyAnYSc6IDEsICdiJzogMiB9KTtcbiAgICAgKiAvLyA9PiAnbWF0Y2hlcyBBJ1xuICAgICAqXG4gICAgICogZnVuYyh7ICdhJzogMCwgJ2InOiAxIH0pO1xuICAgICAqIC8vID0+ICdtYXRjaGVzIEInXG4gICAgICpcbiAgICAgKiBmdW5jKHsgJ2EnOiAnMScsICdiJzogJzInIH0pO1xuICAgICAqIC8vID0+ICdubyBtYXRjaCdcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBjb25kKHBhaXJzKSB7XG4gICAgICB2YXIgbGVuZ3RoID0gcGFpcnMgPT0gbnVsbCA/IDAgOiBwYWlycy5sZW5ndGgsXG4gICAgICAgICAgdG9JdGVyYXRlZSA9IGdldEl0ZXJhdGVlKCk7XG5cbiAgICAgIHBhaXJzID0gIWxlbmd0aCA/IFtdIDogYXJyYXlNYXAocGFpcnMsIGZ1bmN0aW9uKHBhaXIpIHtcbiAgICAgICAgaWYgKHR5cGVvZiBwYWlyWzFdICE9ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKEZVTkNfRVJST1JfVEVYVCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIFt0b0l0ZXJhdGVlKHBhaXJbMF0pLCBwYWlyWzFdXTtcbiAgICAgIH0pO1xuXG4gICAgICByZXR1cm4gYmFzZVJlc3QoZnVuY3Rpb24oYXJncykge1xuICAgICAgICB2YXIgaW5kZXggPSAtMTtcbiAgICAgICAgd2hpbGUgKCsraW5kZXggPCBsZW5ndGgpIHtcbiAgICAgICAgICB2YXIgcGFpciA9IHBhaXJzW2luZGV4XTtcbiAgICAgICAgICBpZiAoYXBwbHkocGFpclswXSwgdGhpcywgYXJncykpIHtcbiAgICAgICAgICAgIHJldHVybiBhcHBseShwYWlyWzFdLCB0aGlzLCBhcmdzKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBmdW5jdGlvbiB0aGF0IGludm9rZXMgdGhlIHByZWRpY2F0ZSBwcm9wZXJ0aWVzIG9mIGBzb3VyY2VgIHdpdGhcbiAgICAgKiB0aGUgY29ycmVzcG9uZGluZyBwcm9wZXJ0eSB2YWx1ZXMgb2YgYSBnaXZlbiBvYmplY3QsIHJldHVybmluZyBgdHJ1ZWAgaWZcbiAgICAgKiBhbGwgcHJlZGljYXRlcyByZXR1cm4gdHJ1dGh5LCBlbHNlIGBmYWxzZWAuXG4gICAgICpcbiAgICAgKiAqKk5vdGU6KiogVGhlIGNyZWF0ZWQgZnVuY3Rpb24gaXMgZXF1aXZhbGVudCB0byBgXy5jb25mb3Jtc1RvYCB3aXRoXG4gICAgICogYHNvdXJjZWAgcGFydGlhbGx5IGFwcGxpZWQuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgNC4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgVXRpbFxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBzb3VyY2UgVGhlIG9iamVjdCBvZiBwcm9wZXJ0eSBwcmVkaWNhdGVzIHRvIGNvbmZvcm0gdG8uXG4gICAgICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBuZXcgc3BlYyBmdW5jdGlvbi5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogdmFyIG9iamVjdHMgPSBbXG4gICAgICogICB7ICdhJzogMiwgJ2InOiAxIH0sXG4gICAgICogICB7ICdhJzogMSwgJ2InOiAyIH1cbiAgICAgKiBdO1xuICAgICAqXG4gICAgICogXy5maWx0ZXIob2JqZWN0cywgXy5jb25mb3Jtcyh7ICdiJzogZnVuY3Rpb24obikgeyByZXR1cm4gbiA+IDE7IH0gfSkpO1xuICAgICAqIC8vID0+IFt7ICdhJzogMSwgJ2InOiAyIH1dXG4gICAgICovXG4gICAgZnVuY3Rpb24gY29uZm9ybXMoc291cmNlKSB7XG4gICAgICByZXR1cm4gYmFzZUNvbmZvcm1zKGJhc2VDbG9uZShzb3VyY2UsIENMT05FX0RFRVBfRkxBRykpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBmdW5jdGlvbiB0aGF0IHJldHVybnMgYHZhbHVlYC5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAyLjQuMFxuICAgICAqIEBjYXRlZ29yeSBVdGlsXG4gICAgICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gcmV0dXJuIGZyb20gdGhlIG5ldyBmdW5jdGlvbi5cbiAgICAgKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyBjb25zdGFudCBmdW5jdGlvbi5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogdmFyIG9iamVjdHMgPSBfLnRpbWVzKDIsIF8uY29uc3RhbnQoeyAnYSc6IDEgfSkpO1xuICAgICAqXG4gICAgICogY29uc29sZS5sb2cob2JqZWN0cyk7XG4gICAgICogLy8gPT4gW3sgJ2EnOiAxIH0sIHsgJ2EnOiAxIH1dXG4gICAgICpcbiAgICAgKiBjb25zb2xlLmxvZyhvYmplY3RzWzBdID09PSBvYmplY3RzWzFdKTtcbiAgICAgKiAvLyA9PiB0cnVlXG4gICAgICovXG4gICAgZnVuY3Rpb24gY29uc3RhbnQodmFsdWUpIHtcbiAgICAgIHJldHVybiBmdW5jdGlvbigpIHtcbiAgICAgICAgcmV0dXJuIHZhbHVlO1xuICAgICAgfTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDaGVja3MgYHZhbHVlYCB0byBkZXRlcm1pbmUgd2hldGhlciBhIGRlZmF1bHQgdmFsdWUgc2hvdWxkIGJlIHJldHVybmVkIGluXG4gICAgICogaXRzIHBsYWNlLiBUaGUgYGRlZmF1bHRWYWx1ZWAgaXMgcmV0dXJuZWQgaWYgYHZhbHVlYCBpcyBgTmFOYCwgYG51bGxgLFxuICAgICAqIG9yIGB1bmRlZmluZWRgLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDQuMTQuMFxuICAgICAqIEBjYXRlZ29yeSBVdGlsXG4gICAgICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY2hlY2suXG4gICAgICogQHBhcmFtIHsqfSBkZWZhdWx0VmFsdWUgVGhlIGRlZmF1bHQgdmFsdWUuXG4gICAgICogQHJldHVybnMgeyp9IFJldHVybnMgdGhlIHJlc29sdmVkIHZhbHVlLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLmRlZmF1bHRUbygxLCAxMCk7XG4gICAgICogLy8gPT4gMVxuICAgICAqXG4gICAgICogXy5kZWZhdWx0VG8odW5kZWZpbmVkLCAxMCk7XG4gICAgICogLy8gPT4gMTBcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBkZWZhdWx0VG8odmFsdWUsIGRlZmF1bHRWYWx1ZSkge1xuICAgICAgcmV0dXJuICh2YWx1ZSA9PSBudWxsIHx8IHZhbHVlICE9PSB2YWx1ZSkgPyBkZWZhdWx0VmFsdWUgOiB2YWx1ZTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgZnVuY3Rpb24gdGhhdCByZXR1cm5zIHRoZSByZXN1bHQgb2YgaW52b2tpbmcgdGhlIGdpdmVuIGZ1bmN0aW9uc1xuICAgICAqIHdpdGggdGhlIGB0aGlzYCBiaW5kaW5nIG9mIHRoZSBjcmVhdGVkIGZ1bmN0aW9uLCB3aGVyZSBlYWNoIHN1Y2Nlc3NpdmVcbiAgICAgKiBpbnZvY2F0aW9uIGlzIHN1cHBsaWVkIHRoZSByZXR1cm4gdmFsdWUgb2YgdGhlIHByZXZpb3VzLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDMuMC4wXG4gICAgICogQGNhdGVnb3J5IFV0aWxcbiAgICAgKiBAcGFyYW0gey4uLihGdW5jdGlvbnxGdW5jdGlvbltdKX0gW2Z1bmNzXSBUaGUgZnVuY3Rpb25zIHRvIGludm9rZS5cbiAgICAgKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyBjb21wb3NpdGUgZnVuY3Rpb24uXG4gICAgICogQHNlZSBfLmZsb3dSaWdodFxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBmdW5jdGlvbiBzcXVhcmUobikge1xuICAgICAqICAgcmV0dXJuIG4gKiBuO1xuICAgICAqIH1cbiAgICAgKlxuICAgICAqIHZhciBhZGRTcXVhcmUgPSBfLmZsb3coW18uYWRkLCBzcXVhcmVdKTtcbiAgICAgKiBhZGRTcXVhcmUoMSwgMik7XG4gICAgICogLy8gPT4gOVxuICAgICAqL1xuICAgIHZhciBmbG93ID0gY3JlYXRlRmxvdygpO1xuXG4gICAgLyoqXG4gICAgICogVGhpcyBtZXRob2QgaXMgbGlrZSBgXy5mbG93YCBleGNlcHQgdGhhdCBpdCBjcmVhdGVzIGEgZnVuY3Rpb24gdGhhdFxuICAgICAqIGludm9rZXMgdGhlIGdpdmVuIGZ1bmN0aW9ucyBmcm9tIHJpZ2h0IHRvIGxlZnQuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQHNpbmNlIDMuMC4wXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAY2F0ZWdvcnkgVXRpbFxuICAgICAqIEBwYXJhbSB7Li4uKEZ1bmN0aW9ufEZ1bmN0aW9uW10pfSBbZnVuY3NdIFRoZSBmdW5jdGlvbnMgdG8gaW52b2tlLlxuICAgICAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyB0aGUgbmV3IGNvbXBvc2l0ZSBmdW5jdGlvbi5cbiAgICAgKiBAc2VlIF8uZmxvd1xuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBmdW5jdGlvbiBzcXVhcmUobikge1xuICAgICAqICAgcmV0dXJuIG4gKiBuO1xuICAgICAqIH1cbiAgICAgKlxuICAgICAqIHZhciBhZGRTcXVhcmUgPSBfLmZsb3dSaWdodChbc3F1YXJlLCBfLmFkZF0pO1xuICAgICAqIGFkZFNxdWFyZSgxLCAyKTtcbiAgICAgKiAvLyA9PiA5XG4gICAgICovXG4gICAgdmFyIGZsb3dSaWdodCA9IGNyZWF0ZUZsb3codHJ1ZSk7XG5cbiAgICAvKipcbiAgICAgKiBUaGlzIG1ldGhvZCByZXR1cm5zIHRoZSBmaXJzdCBhcmd1bWVudCBpdCByZWNlaXZlcy5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAc2luY2UgMC4xLjBcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBjYXRlZ29yeSBVdGlsXG4gICAgICogQHBhcmFtIHsqfSB2YWx1ZSBBbnkgdmFsdWUuXG4gICAgICogQHJldHVybnMgeyp9IFJldHVybnMgYHZhbHVlYC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogdmFyIG9iamVjdCA9IHsgJ2EnOiAxIH07XG4gICAgICpcbiAgICAgKiBjb25zb2xlLmxvZyhfLmlkZW50aXR5KG9iamVjdCkgPT09IG9iamVjdCk7XG4gICAgICogLy8gPT4gdHJ1ZVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGlkZW50aXR5KHZhbHVlKSB7XG4gICAgICByZXR1cm4gdmFsdWU7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIGZ1bmN0aW9uIHRoYXQgaW52b2tlcyBgZnVuY2Agd2l0aCB0aGUgYXJndW1lbnRzIG9mIHRoZSBjcmVhdGVkXG4gICAgICogZnVuY3Rpb24uIElmIGBmdW5jYCBpcyBhIHByb3BlcnR5IG5hbWUsIHRoZSBjcmVhdGVkIGZ1bmN0aW9uIHJldHVybnMgdGhlXG4gICAgICogcHJvcGVydHkgdmFsdWUgZm9yIGEgZ2l2ZW4gZWxlbWVudC4gSWYgYGZ1bmNgIGlzIGFuIGFycmF5IG9yIG9iamVjdCwgdGhlXG4gICAgICogY3JlYXRlZCBmdW5jdGlvbiByZXR1cm5zIGB0cnVlYCBmb3IgZWxlbWVudHMgdGhhdCBjb250YWluIHRoZSBlcXVpdmFsZW50XG4gICAgICogc291cmNlIHByb3BlcnRpZXMsIG90aGVyd2lzZSBpdCByZXR1cm5zIGBmYWxzZWAuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQHNpbmNlIDQuMC4wXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAY2F0ZWdvcnkgVXRpbFxuICAgICAqIEBwYXJhbSB7Kn0gW2Z1bmM9Xy5pZGVudGl0eV0gVGhlIHZhbHVlIHRvIGNvbnZlcnQgdG8gYSBjYWxsYmFjay5cbiAgICAgKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIGNhbGxiYWNrLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiB2YXIgdXNlcnMgPSBbXG4gICAgICogICB7ICd1c2VyJzogJ2Jhcm5leScsICdhZ2UnOiAzNiwgJ2FjdGl2ZSc6IHRydWUgfSxcbiAgICAgKiAgIHsgJ3VzZXInOiAnZnJlZCcsICAgJ2FnZSc6IDQwLCAnYWN0aXZlJzogZmFsc2UgfVxuICAgICAqIF07XG4gICAgICpcbiAgICAgKiAvLyBUaGUgYF8ubWF0Y2hlc2AgaXRlcmF0ZWUgc2hvcnRoYW5kLlxuICAgICAqIF8uZmlsdGVyKHVzZXJzLCBfLml0ZXJhdGVlKHsgJ3VzZXInOiAnYmFybmV5JywgJ2FjdGl2ZSc6IHRydWUgfSkpO1xuICAgICAqIC8vID0+IFt7ICd1c2VyJzogJ2Jhcm5leScsICdhZ2UnOiAzNiwgJ2FjdGl2ZSc6IHRydWUgfV1cbiAgICAgKlxuICAgICAqIC8vIFRoZSBgXy5tYXRjaGVzUHJvcGVydHlgIGl0ZXJhdGVlIHNob3J0aGFuZC5cbiAgICAgKiBfLmZpbHRlcih1c2VycywgXy5pdGVyYXRlZShbJ3VzZXInLCAnZnJlZCddKSk7XG4gICAgICogLy8gPT4gW3sgJ3VzZXInOiAnZnJlZCcsICdhZ2UnOiA0MCB9XVxuICAgICAqXG4gICAgICogLy8gVGhlIGBfLnByb3BlcnR5YCBpdGVyYXRlZSBzaG9ydGhhbmQuXG4gICAgICogXy5tYXAodXNlcnMsIF8uaXRlcmF0ZWUoJ3VzZXInKSk7XG4gICAgICogLy8gPT4gWydiYXJuZXknLCAnZnJlZCddXG4gICAgICpcbiAgICAgKiAvLyBDcmVhdGUgY3VzdG9tIGl0ZXJhdGVlIHNob3J0aGFuZHMuXG4gICAgICogXy5pdGVyYXRlZSA9IF8ud3JhcChfLml0ZXJhdGVlLCBmdW5jdGlvbihpdGVyYXRlZSwgZnVuYykge1xuICAgICAqICAgcmV0dXJuICFfLmlzUmVnRXhwKGZ1bmMpID8gaXRlcmF0ZWUoZnVuYykgOiBmdW5jdGlvbihzdHJpbmcpIHtcbiAgICAgKiAgICAgcmV0dXJuIGZ1bmMudGVzdChzdHJpbmcpO1xuICAgICAqICAgfTtcbiAgICAgKiB9KTtcbiAgICAgKlxuICAgICAqIF8uZmlsdGVyKFsnYWJjJywgJ2RlZiddLCAvZWYvKTtcbiAgICAgKiAvLyA9PiBbJ2RlZiddXG4gICAgICovXG4gICAgZnVuY3Rpb24gaXRlcmF0ZWUoZnVuYykge1xuICAgICAgcmV0dXJuIGJhc2VJdGVyYXRlZSh0eXBlb2YgZnVuYyA9PSAnZnVuY3Rpb24nID8gZnVuYyA6IGJhc2VDbG9uZShmdW5jLCBDTE9ORV9ERUVQX0ZMQUcpKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgZnVuY3Rpb24gdGhhdCBwZXJmb3JtcyBhIHBhcnRpYWwgZGVlcCBjb21wYXJpc29uIGJldHdlZW4gYSBnaXZlblxuICAgICAqIG9iamVjdCBhbmQgYHNvdXJjZWAsIHJldHVybmluZyBgdHJ1ZWAgaWYgdGhlIGdpdmVuIG9iamVjdCBoYXMgZXF1aXZhbGVudFxuICAgICAqIHByb3BlcnR5IHZhbHVlcywgZWxzZSBgZmFsc2VgLlxuICAgICAqXG4gICAgICogKipOb3RlOioqIFRoZSBjcmVhdGVkIGZ1bmN0aW9uIGlzIGVxdWl2YWxlbnQgdG8gYF8uaXNNYXRjaGAgd2l0aCBgc291cmNlYFxuICAgICAqIHBhcnRpYWxseSBhcHBsaWVkLlxuICAgICAqXG4gICAgICogUGFydGlhbCBjb21wYXJpc29ucyB3aWxsIG1hdGNoIGVtcHR5IGFycmF5IGFuZCBlbXB0eSBvYmplY3QgYHNvdXJjZWBcbiAgICAgKiB2YWx1ZXMgYWdhaW5zdCBhbnkgYXJyYXkgb3Igb2JqZWN0IHZhbHVlLCByZXNwZWN0aXZlbHkuIFNlZSBgXy5pc0VxdWFsYFxuICAgICAqIGZvciBhIGxpc3Qgb2Ygc3VwcG9ydGVkIHZhbHVlIGNvbXBhcmlzb25zLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDMuMC4wXG4gICAgICogQGNhdGVnb3J5IFV0aWxcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gc291cmNlIFRoZSBvYmplY3Qgb2YgcHJvcGVydHkgdmFsdWVzIHRvIG1hdGNoLlxuICAgICAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyB0aGUgbmV3IHNwZWMgZnVuY3Rpb24uXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIHZhciBvYmplY3RzID0gW1xuICAgICAqICAgeyAnYSc6IDEsICdiJzogMiwgJ2MnOiAzIH0sXG4gICAgICogICB7ICdhJzogNCwgJ2InOiA1LCAnYyc6IDYgfVxuICAgICAqIF07XG4gICAgICpcbiAgICAgKiBfLmZpbHRlcihvYmplY3RzLCBfLm1hdGNoZXMoeyAnYSc6IDQsICdjJzogNiB9KSk7XG4gICAgICogLy8gPT4gW3sgJ2EnOiA0LCAnYic6IDUsICdjJzogNiB9XVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIG1hdGNoZXMoc291cmNlKSB7XG4gICAgICByZXR1cm4gYmFzZU1hdGNoZXMoYmFzZUNsb25lKHNvdXJjZSwgQ0xPTkVfREVFUF9GTEFHKSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIGZ1bmN0aW9uIHRoYXQgcGVyZm9ybXMgYSBwYXJ0aWFsIGRlZXAgY29tcGFyaXNvbiBiZXR3ZWVuIHRoZVxuICAgICAqIHZhbHVlIGF0IGBwYXRoYCBvZiBhIGdpdmVuIG9iamVjdCB0byBgc3JjVmFsdWVgLCByZXR1cm5pbmcgYHRydWVgIGlmIHRoZVxuICAgICAqIG9iamVjdCB2YWx1ZSBpcyBlcXVpdmFsZW50LCBlbHNlIGBmYWxzZWAuXG4gICAgICpcbiAgICAgKiAqKk5vdGU6KiogUGFydGlhbCBjb21wYXJpc29ucyB3aWxsIG1hdGNoIGVtcHR5IGFycmF5IGFuZCBlbXB0eSBvYmplY3RcbiAgICAgKiBgc3JjVmFsdWVgIHZhbHVlcyBhZ2FpbnN0IGFueSBhcnJheSBvciBvYmplY3QgdmFsdWUsIHJlc3BlY3RpdmVseS4gU2VlXG4gICAgICogYF8uaXNFcXVhbGAgZm9yIGEgbGlzdCBvZiBzdXBwb3J0ZWQgdmFsdWUgY29tcGFyaXNvbnMuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMy4yLjBcbiAgICAgKiBAY2F0ZWdvcnkgVXRpbFxuICAgICAqIEBwYXJhbSB7QXJyYXl8c3RyaW5nfSBwYXRoIFRoZSBwYXRoIG9mIHRoZSBwcm9wZXJ0eSB0byBnZXQuXG4gICAgICogQHBhcmFtIHsqfSBzcmNWYWx1ZSBUaGUgdmFsdWUgdG8gbWF0Y2guXG4gICAgICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBuZXcgc3BlYyBmdW5jdGlvbi5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogdmFyIG9iamVjdHMgPSBbXG4gICAgICogICB7ICdhJzogMSwgJ2InOiAyLCAnYyc6IDMgfSxcbiAgICAgKiAgIHsgJ2EnOiA0LCAnYic6IDUsICdjJzogNiB9XG4gICAgICogXTtcbiAgICAgKlxuICAgICAqIF8uZmluZChvYmplY3RzLCBfLm1hdGNoZXNQcm9wZXJ0eSgnYScsIDQpKTtcbiAgICAgKiAvLyA9PiB7ICdhJzogNCwgJ2InOiA1LCAnYyc6IDYgfVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIG1hdGNoZXNQcm9wZXJ0eShwYXRoLCBzcmNWYWx1ZSkge1xuICAgICAgcmV0dXJuIGJhc2VNYXRjaGVzUHJvcGVydHkocGF0aCwgYmFzZUNsb25lKHNyY1ZhbHVlLCBDTE9ORV9ERUVQX0ZMQUcpKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgZnVuY3Rpb24gdGhhdCBpbnZva2VzIHRoZSBtZXRob2QgYXQgYHBhdGhgIG9mIGEgZ2l2ZW4gb2JqZWN0LlxuICAgICAqIEFueSBhZGRpdGlvbmFsIGFyZ3VtZW50cyBhcmUgcHJvdmlkZWQgdG8gdGhlIGludm9rZWQgbWV0aG9kLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDMuNy4wXG4gICAgICogQGNhdGVnb3J5IFV0aWxcbiAgICAgKiBAcGFyYW0ge0FycmF5fHN0cmluZ30gcGF0aCBUaGUgcGF0aCBvZiB0aGUgbWV0aG9kIHRvIGludm9rZS5cbiAgICAgKiBAcGFyYW0gey4uLip9IFthcmdzXSBUaGUgYXJndW1lbnRzIHRvIGludm9rZSB0aGUgbWV0aG9kIHdpdGguXG4gICAgICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBuZXcgaW52b2tlciBmdW5jdGlvbi5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogdmFyIG9iamVjdHMgPSBbXG4gICAgICogICB7ICdhJzogeyAnYic6IF8uY29uc3RhbnQoMikgfSB9LFxuICAgICAqICAgeyAnYSc6IHsgJ2InOiBfLmNvbnN0YW50KDEpIH0gfVxuICAgICAqIF07XG4gICAgICpcbiAgICAgKiBfLm1hcChvYmplY3RzLCBfLm1ldGhvZCgnYS5iJykpO1xuICAgICAqIC8vID0+IFsyLCAxXVxuICAgICAqXG4gICAgICogXy5tYXAob2JqZWN0cywgXy5tZXRob2QoWydhJywgJ2InXSkpO1xuICAgICAqIC8vID0+IFsyLCAxXVxuICAgICAqL1xuICAgIHZhciBtZXRob2QgPSBiYXNlUmVzdChmdW5jdGlvbihwYXRoLCBhcmdzKSB7XG4gICAgICByZXR1cm4gZnVuY3Rpb24ob2JqZWN0KSB7XG4gICAgICAgIHJldHVybiBiYXNlSW52b2tlKG9iamVjdCwgcGF0aCwgYXJncyk7XG4gICAgICB9O1xuICAgIH0pO1xuXG4gICAgLyoqXG4gICAgICogVGhlIG9wcG9zaXRlIG9mIGBfLm1ldGhvZGA7IHRoaXMgbWV0aG9kIGNyZWF0ZXMgYSBmdW5jdGlvbiB0aGF0IGludm9rZXNcbiAgICAgKiB0aGUgbWV0aG9kIGF0IGEgZ2l2ZW4gcGF0aCBvZiBgb2JqZWN0YC4gQW55IGFkZGl0aW9uYWwgYXJndW1lbnRzIGFyZVxuICAgICAqIHByb3ZpZGVkIHRvIHRoZSBpbnZva2VkIG1ldGhvZC5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAzLjcuMFxuICAgICAqIEBjYXRlZ29yeSBVdGlsXG4gICAgICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIHF1ZXJ5LlxuICAgICAqIEBwYXJhbSB7Li4uKn0gW2FyZ3NdIFRoZSBhcmd1bWVudHMgdG8gaW52b2tlIHRoZSBtZXRob2Qgd2l0aC5cbiAgICAgKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyBpbnZva2VyIGZ1bmN0aW9uLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiB2YXIgYXJyYXkgPSBfLnRpbWVzKDMsIF8uY29uc3RhbnQpLFxuICAgICAqICAgICBvYmplY3QgPSB7ICdhJzogYXJyYXksICdiJzogYXJyYXksICdjJzogYXJyYXkgfTtcbiAgICAgKlxuICAgICAqIF8ubWFwKFsnYVsyXScsICdjWzBdJ10sIF8ubWV0aG9kT2Yob2JqZWN0KSk7XG4gICAgICogLy8gPT4gWzIsIDBdXG4gICAgICpcbiAgICAgKiBfLm1hcChbWydhJywgJzInXSwgWydjJywgJzAnXV0sIF8ubWV0aG9kT2Yob2JqZWN0KSk7XG4gICAgICogLy8gPT4gWzIsIDBdXG4gICAgICovXG4gICAgdmFyIG1ldGhvZE9mID0gYmFzZVJlc3QoZnVuY3Rpb24ob2JqZWN0LCBhcmdzKSB7XG4gICAgICByZXR1cm4gZnVuY3Rpb24ocGF0aCkge1xuICAgICAgICByZXR1cm4gYmFzZUludm9rZShvYmplY3QsIHBhdGgsIGFyZ3MpO1xuICAgICAgfTtcbiAgICB9KTtcblxuICAgIC8qKlxuICAgICAqIEFkZHMgYWxsIG93biBlbnVtZXJhYmxlIHN0cmluZyBrZXllZCBmdW5jdGlvbiBwcm9wZXJ0aWVzIG9mIGEgc291cmNlXG4gICAgICogb2JqZWN0IHRvIHRoZSBkZXN0aW5hdGlvbiBvYmplY3QuIElmIGBvYmplY3RgIGlzIGEgZnVuY3Rpb24sIHRoZW4gbWV0aG9kc1xuICAgICAqIGFyZSBhZGRlZCB0byBpdHMgcHJvdG90eXBlIGFzIHdlbGwuXG4gICAgICpcbiAgICAgKiAqKk5vdGU6KiogVXNlIGBfLnJ1bkluQ29udGV4dGAgdG8gY3JlYXRlIGEgcHJpc3RpbmUgYGxvZGFzaGAgZnVuY3Rpb24gdG9cbiAgICAgKiBhdm9pZCBjb25mbGljdHMgY2F1c2VkIGJ5IG1vZGlmeWluZyB0aGUgb3JpZ2luYWwuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQHNpbmNlIDAuMS4wXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAY2F0ZWdvcnkgVXRpbFxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb258T2JqZWN0fSBbb2JqZWN0PWxvZGFzaF0gVGhlIGRlc3RpbmF0aW9uIG9iamVjdC5cbiAgICAgKiBAcGFyYW0ge09iamVjdH0gc291cmNlIFRoZSBvYmplY3Qgb2YgZnVuY3Rpb25zIHRvIGFkZC5cbiAgICAgKiBAcGFyYW0ge09iamVjdH0gW29wdGlvbnM9e31dIFRoZSBvcHRpb25zIG9iamVjdC5cbiAgICAgKiBAcGFyYW0ge2Jvb2xlYW59IFtvcHRpb25zLmNoYWluPXRydWVdIFNwZWNpZnkgd2hldGhlciBtaXhpbnMgYXJlIGNoYWluYWJsZS5cbiAgICAgKiBAcmV0dXJucyB7RnVuY3Rpb258T2JqZWN0fSBSZXR1cm5zIGBvYmplY3RgLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBmdW5jdGlvbiB2b3dlbHMoc3RyaW5nKSB7XG4gICAgICogICByZXR1cm4gXy5maWx0ZXIoc3RyaW5nLCBmdW5jdGlvbih2KSB7XG4gICAgICogICAgIHJldHVybiAvW2FlaW91XS9pLnRlc3Qodik7XG4gICAgICogICB9KTtcbiAgICAgKiB9XG4gICAgICpcbiAgICAgKiBfLm1peGluKHsgJ3Zvd2Vscyc6IHZvd2VscyB9KTtcbiAgICAgKiBfLnZvd2VscygnZnJlZCcpO1xuICAgICAqIC8vID0+IFsnZSddXG4gICAgICpcbiAgICAgKiBfKCdmcmVkJykudm93ZWxzKCkudmFsdWUoKTtcbiAgICAgKiAvLyA9PiBbJ2UnXVxuICAgICAqXG4gICAgICogXy5taXhpbih7ICd2b3dlbHMnOiB2b3dlbHMgfSwgeyAnY2hhaW4nOiBmYWxzZSB9KTtcbiAgICAgKiBfKCdmcmVkJykudm93ZWxzKCk7XG4gICAgICogLy8gPT4gWydlJ11cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBtaXhpbihvYmplY3QsIHNvdXJjZSwgb3B0aW9ucykge1xuICAgICAgdmFyIHByb3BzID0ga2V5cyhzb3VyY2UpLFxuICAgICAgICAgIG1ldGhvZE5hbWVzID0gYmFzZUZ1bmN0aW9ucyhzb3VyY2UsIHByb3BzKTtcblxuICAgICAgaWYgKG9wdGlvbnMgPT0gbnVsbCAmJlxuICAgICAgICAgICEoaXNPYmplY3Qoc291cmNlKSAmJiAobWV0aG9kTmFtZXMubGVuZ3RoIHx8ICFwcm9wcy5sZW5ndGgpKSkge1xuICAgICAgICBvcHRpb25zID0gc291cmNlO1xuICAgICAgICBzb3VyY2UgPSBvYmplY3Q7XG4gICAgICAgIG9iamVjdCA9IHRoaXM7XG4gICAgICAgIG1ldGhvZE5hbWVzID0gYmFzZUZ1bmN0aW9ucyhzb3VyY2UsIGtleXMoc291cmNlKSk7XG4gICAgICB9XG4gICAgICB2YXIgY2hhaW4gPSAhKGlzT2JqZWN0KG9wdGlvbnMpICYmICdjaGFpbicgaW4gb3B0aW9ucykgfHwgISFvcHRpb25zLmNoYWluLFxuICAgICAgICAgIGlzRnVuYyA9IGlzRnVuY3Rpb24ob2JqZWN0KTtcblxuICAgICAgYXJyYXlFYWNoKG1ldGhvZE5hbWVzLCBmdW5jdGlvbihtZXRob2ROYW1lKSB7XG4gICAgICAgIHZhciBmdW5jID0gc291cmNlW21ldGhvZE5hbWVdO1xuICAgICAgICBvYmplY3RbbWV0aG9kTmFtZV0gPSBmdW5jO1xuICAgICAgICBpZiAoaXNGdW5jKSB7XG4gICAgICAgICAgb2JqZWN0LnByb3RvdHlwZVttZXRob2ROYW1lXSA9IGZ1bmN0aW9uKCkge1xuICAgICAgICAgICAgdmFyIGNoYWluQWxsID0gdGhpcy5fX2NoYWluX187XG4gICAgICAgICAgICBpZiAoY2hhaW4gfHwgY2hhaW5BbGwpIHtcbiAgICAgICAgICAgICAgdmFyIHJlc3VsdCA9IG9iamVjdCh0aGlzLl9fd3JhcHBlZF9fKSxcbiAgICAgICAgICAgICAgICAgIGFjdGlvbnMgPSByZXN1bHQuX19hY3Rpb25zX18gPSBjb3B5QXJyYXkodGhpcy5fX2FjdGlvbnNfXyk7XG5cbiAgICAgICAgICAgICAgYWN0aW9ucy5wdXNoKHsgJ2Z1bmMnOiBmdW5jLCAnYXJncyc6IGFyZ3VtZW50cywgJ3RoaXNBcmcnOiBvYmplY3QgfSk7XG4gICAgICAgICAgICAgIHJlc3VsdC5fX2NoYWluX18gPSBjaGFpbkFsbDtcbiAgICAgICAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBmdW5jLmFwcGx5KG9iamVjdCwgYXJyYXlQdXNoKFt0aGlzLnZhbHVlKCldLCBhcmd1bWVudHMpKTtcbiAgICAgICAgICB9O1xuICAgICAgICB9XG4gICAgICB9KTtcblxuICAgICAgcmV0dXJuIG9iamVjdDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBSZXZlcnRzIHRoZSBgX2AgdmFyaWFibGUgdG8gaXRzIHByZXZpb3VzIHZhbHVlIGFuZCByZXR1cm5zIGEgcmVmZXJlbmNlIHRvXG4gICAgICogdGhlIGBsb2Rhc2hgIGZ1bmN0aW9uLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBzaW5jZSAwLjEuMFxuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQGNhdGVnb3J5IFV0aWxcbiAgICAgKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIGBsb2Rhc2hgIGZ1bmN0aW9uLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiB2YXIgbG9kYXNoID0gXy5ub0NvbmZsaWN0KCk7XG4gICAgICovXG4gICAgZnVuY3Rpb24gbm9Db25mbGljdCgpIHtcbiAgICAgIGlmIChyb290Ll8gPT09IHRoaXMpIHtcbiAgICAgICAgcm9vdC5fID0gb2xkRGFzaDtcbiAgICAgIH1cbiAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoaXMgbWV0aG9kIHJldHVybnMgYHVuZGVmaW5lZGAuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMi4zLjBcbiAgICAgKiBAY2F0ZWdvcnkgVXRpbFxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLnRpbWVzKDIsIF8ubm9vcCk7XG4gICAgICogLy8gPT4gW3VuZGVmaW5lZCwgdW5kZWZpbmVkXVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIG5vb3AoKSB7XG4gICAgICAvLyBObyBvcGVyYXRpb24gcGVyZm9ybWVkLlxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBmdW5jdGlvbiB0aGF0IGdldHMgdGhlIGFyZ3VtZW50IGF0IGluZGV4IGBuYC4gSWYgYG5gIGlzIG5lZ2F0aXZlLFxuICAgICAqIHRoZSBudGggYXJndW1lbnQgZnJvbSB0aGUgZW5kIGlzIHJldHVybmVkLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDQuMC4wXG4gICAgICogQGNhdGVnb3J5IFV0aWxcbiAgICAgKiBAcGFyYW0ge251bWJlcn0gW249MF0gVGhlIGluZGV4IG9mIHRoZSBhcmd1bWVudCB0byByZXR1cm4uXG4gICAgICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBuZXcgcGFzcy10aHJ1IGZ1bmN0aW9uLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiB2YXIgZnVuYyA9IF8ubnRoQXJnKDEpO1xuICAgICAqIGZ1bmMoJ2EnLCAnYicsICdjJywgJ2QnKTtcbiAgICAgKiAvLyA9PiAnYidcbiAgICAgKlxuICAgICAqIHZhciBmdW5jID0gXy5udGhBcmcoLTIpO1xuICAgICAqIGZ1bmMoJ2EnLCAnYicsICdjJywgJ2QnKTtcbiAgICAgKiAvLyA9PiAnYydcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBudGhBcmcobikge1xuICAgICAgbiA9IHRvSW50ZWdlcihuKTtcbiAgICAgIHJldHVybiBiYXNlUmVzdChmdW5jdGlvbihhcmdzKSB7XG4gICAgICAgIHJldHVybiBiYXNlTnRoKGFyZ3MsIG4pO1xuICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIGZ1bmN0aW9uIHRoYXQgaW52b2tlcyBgaXRlcmF0ZWVzYCB3aXRoIHRoZSBhcmd1bWVudHMgaXQgcmVjZWl2ZXNcbiAgICAgKiBhbmQgcmV0dXJucyB0aGVpciByZXN1bHRzLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDQuMC4wXG4gICAgICogQGNhdGVnb3J5IFV0aWxcbiAgICAgKiBAcGFyYW0gey4uLihGdW5jdGlvbnxGdW5jdGlvbltdKX0gW2l0ZXJhdGVlcz1bXy5pZGVudGl0eV1dXG4gICAgICogIFRoZSBpdGVyYXRlZXMgdG8gaW52b2tlLlxuICAgICAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyB0aGUgbmV3IGZ1bmN0aW9uLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiB2YXIgZnVuYyA9IF8ub3ZlcihbTWF0aC5tYXgsIE1hdGgubWluXSk7XG4gICAgICpcbiAgICAgKiBmdW5jKDEsIDIsIDMsIDQpO1xuICAgICAqIC8vID0+IFs0LCAxXVxuICAgICAqL1xuICAgIHZhciBvdmVyID0gY3JlYXRlT3ZlcihhcnJheU1hcCk7XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgZnVuY3Rpb24gdGhhdCBjaGVja3MgaWYgKiphbGwqKiBvZiB0aGUgYHByZWRpY2F0ZXNgIHJldHVyblxuICAgICAqIHRydXRoeSB3aGVuIGludm9rZWQgd2l0aCB0aGUgYXJndW1lbnRzIGl0IHJlY2VpdmVzLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDQuMC4wXG4gICAgICogQGNhdGVnb3J5IFV0aWxcbiAgICAgKiBAcGFyYW0gey4uLihGdW5jdGlvbnxGdW5jdGlvbltdKX0gW3ByZWRpY2F0ZXM9W18uaWRlbnRpdHldXVxuICAgICAqICBUaGUgcHJlZGljYXRlcyB0byBjaGVjay5cbiAgICAgKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyBmdW5jdGlvbi5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogdmFyIGZ1bmMgPSBfLm92ZXJFdmVyeShbQm9vbGVhbiwgaXNGaW5pdGVdKTtcbiAgICAgKlxuICAgICAqIGZ1bmMoJzEnKTtcbiAgICAgKiAvLyA9PiB0cnVlXG4gICAgICpcbiAgICAgKiBmdW5jKG51bGwpO1xuICAgICAqIC8vID0+IGZhbHNlXG4gICAgICpcbiAgICAgKiBmdW5jKE5hTik7XG4gICAgICogLy8gPT4gZmFsc2VcbiAgICAgKi9cbiAgICB2YXIgb3ZlckV2ZXJ5ID0gY3JlYXRlT3ZlcihhcnJheUV2ZXJ5KTtcblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBmdW5jdGlvbiB0aGF0IGNoZWNrcyBpZiAqKmFueSoqIG9mIHRoZSBgcHJlZGljYXRlc2AgcmV0dXJuXG4gICAgICogdHJ1dGh5IHdoZW4gaW52b2tlZCB3aXRoIHRoZSBhcmd1bWVudHMgaXQgcmVjZWl2ZXMuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgNC4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgVXRpbFxuICAgICAqIEBwYXJhbSB7Li4uKEZ1bmN0aW9ufEZ1bmN0aW9uW10pfSBbcHJlZGljYXRlcz1bXy5pZGVudGl0eV1dXG4gICAgICogIFRoZSBwcmVkaWNhdGVzIHRvIGNoZWNrLlxuICAgICAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyB0aGUgbmV3IGZ1bmN0aW9uLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiB2YXIgZnVuYyA9IF8ub3ZlclNvbWUoW0Jvb2xlYW4sIGlzRmluaXRlXSk7XG4gICAgICpcbiAgICAgKiBmdW5jKCcxJyk7XG4gICAgICogLy8gPT4gdHJ1ZVxuICAgICAqXG4gICAgICogZnVuYyhudWxsKTtcbiAgICAgKiAvLyA9PiB0cnVlXG4gICAgICpcbiAgICAgKiBmdW5jKE5hTik7XG4gICAgICogLy8gPT4gZmFsc2VcbiAgICAgKi9cbiAgICB2YXIgb3ZlclNvbWUgPSBjcmVhdGVPdmVyKGFycmF5U29tZSk7XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgZnVuY3Rpb24gdGhhdCByZXR1cm5zIHRoZSB2YWx1ZSBhdCBgcGF0aGAgb2YgYSBnaXZlbiBvYmplY3QuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMi40LjBcbiAgICAgKiBAY2F0ZWdvcnkgVXRpbFxuICAgICAqIEBwYXJhbSB7QXJyYXl8c3RyaW5nfSBwYXRoIFRoZSBwYXRoIG9mIHRoZSBwcm9wZXJ0eSB0byBnZXQuXG4gICAgICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBuZXcgYWNjZXNzb3IgZnVuY3Rpb24uXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIHZhciBvYmplY3RzID0gW1xuICAgICAqICAgeyAnYSc6IHsgJ2InOiAyIH0gfSxcbiAgICAgKiAgIHsgJ2EnOiB7ICdiJzogMSB9IH1cbiAgICAgKiBdO1xuICAgICAqXG4gICAgICogXy5tYXAob2JqZWN0cywgXy5wcm9wZXJ0eSgnYS5iJykpO1xuICAgICAqIC8vID0+IFsyLCAxXVxuICAgICAqXG4gICAgICogXy5tYXAoXy5zb3J0Qnkob2JqZWN0cywgXy5wcm9wZXJ0eShbJ2EnLCAnYiddKSksICdhLmInKTtcbiAgICAgKiAvLyA9PiBbMSwgMl1cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBwcm9wZXJ0eShwYXRoKSB7XG4gICAgICByZXR1cm4gaXNLZXkocGF0aCkgPyBiYXNlUHJvcGVydHkodG9LZXkocGF0aCkpIDogYmFzZVByb3BlcnR5RGVlcChwYXRoKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGUgb3Bwb3NpdGUgb2YgYF8ucHJvcGVydHlgOyB0aGlzIG1ldGhvZCBjcmVhdGVzIGEgZnVuY3Rpb24gdGhhdCByZXR1cm5zXG4gICAgICogdGhlIHZhbHVlIGF0IGEgZ2l2ZW4gcGF0aCBvZiBgb2JqZWN0YC5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAzLjAuMFxuICAgICAqIEBjYXRlZ29yeSBVdGlsXG4gICAgICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIHF1ZXJ5LlxuICAgICAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyB0aGUgbmV3IGFjY2Vzc29yIGZ1bmN0aW9uLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiB2YXIgYXJyYXkgPSBbMCwgMSwgMl0sXG4gICAgICogICAgIG9iamVjdCA9IHsgJ2EnOiBhcnJheSwgJ2InOiBhcnJheSwgJ2MnOiBhcnJheSB9O1xuICAgICAqXG4gICAgICogXy5tYXAoWydhWzJdJywgJ2NbMF0nXSwgXy5wcm9wZXJ0eU9mKG9iamVjdCkpO1xuICAgICAqIC8vID0+IFsyLCAwXVxuICAgICAqXG4gICAgICogXy5tYXAoW1snYScsICcyJ10sIFsnYycsICcwJ11dLCBfLnByb3BlcnR5T2Yob2JqZWN0KSk7XG4gICAgICogLy8gPT4gWzIsIDBdXG4gICAgICovXG4gICAgZnVuY3Rpb24gcHJvcGVydHlPZihvYmplY3QpIHtcbiAgICAgIHJldHVybiBmdW5jdGlvbihwYXRoKSB7XG4gICAgICAgIHJldHVybiBvYmplY3QgPT0gbnVsbCA/IHVuZGVmaW5lZCA6IGJhc2VHZXQob2JqZWN0LCBwYXRoKTtcbiAgICAgIH07XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhbiBhcnJheSBvZiBudW1iZXJzIChwb3NpdGl2ZSBhbmQvb3IgbmVnYXRpdmUpIHByb2dyZXNzaW5nIGZyb21cbiAgICAgKiBgc3RhcnRgIHVwIHRvLCBidXQgbm90IGluY2x1ZGluZywgYGVuZGAuIEEgc3RlcCBvZiBgLTFgIGlzIHVzZWQgaWYgYSBuZWdhdGl2ZVxuICAgICAqIGBzdGFydGAgaXMgc3BlY2lmaWVkIHdpdGhvdXQgYW4gYGVuZGAgb3IgYHN0ZXBgLiBJZiBgZW5kYCBpcyBub3Qgc3BlY2lmaWVkLFxuICAgICAqIGl0J3Mgc2V0IHRvIGBzdGFydGAgd2l0aCBgc3RhcnRgIHRoZW4gc2V0IHRvIGAwYC5cbiAgICAgKlxuICAgICAqICoqTm90ZToqKiBKYXZhU2NyaXB0IGZvbGxvd3MgdGhlIElFRUUtNzU0IHN0YW5kYXJkIGZvciByZXNvbHZpbmdcbiAgICAgKiBmbG9hdGluZy1wb2ludCB2YWx1ZXMgd2hpY2ggY2FuIHByb2R1Y2UgdW5leHBlY3RlZCByZXN1bHRzLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBzaW5jZSAwLjEuMFxuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQGNhdGVnb3J5IFV0aWxcbiAgICAgKiBAcGFyYW0ge251bWJlcn0gW3N0YXJ0PTBdIFRoZSBzdGFydCBvZiB0aGUgcmFuZ2UuXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IGVuZCBUaGUgZW5kIG9mIHRoZSByYW5nZS5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gW3N0ZXA9MV0gVGhlIHZhbHVlIHRvIGluY3JlbWVudCBvciBkZWNyZW1lbnQgYnkuXG4gICAgICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSByYW5nZSBvZiBudW1iZXJzLlxuICAgICAqIEBzZWUgXy5pblJhbmdlLCBfLnJhbmdlUmlnaHRcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy5yYW5nZSg0KTtcbiAgICAgKiAvLyA9PiBbMCwgMSwgMiwgM11cbiAgICAgKlxuICAgICAqIF8ucmFuZ2UoLTQpO1xuICAgICAqIC8vID0+IFswLCAtMSwgLTIsIC0zXVxuICAgICAqXG4gICAgICogXy5yYW5nZSgxLCA1KTtcbiAgICAgKiAvLyA9PiBbMSwgMiwgMywgNF1cbiAgICAgKlxuICAgICAqIF8ucmFuZ2UoMCwgMjAsIDUpO1xuICAgICAqIC8vID0+IFswLCA1LCAxMCwgMTVdXG4gICAgICpcbiAgICAgKiBfLnJhbmdlKDAsIC00LCAtMSk7XG4gICAgICogLy8gPT4gWzAsIC0xLCAtMiwgLTNdXG4gICAgICpcbiAgICAgKiBfLnJhbmdlKDEsIDQsIDApO1xuICAgICAqIC8vID0+IFsxLCAxLCAxXVxuICAgICAqXG4gICAgICogXy5yYW5nZSgwKTtcbiAgICAgKiAvLyA9PiBbXVxuICAgICAqL1xuICAgIHZhciByYW5nZSA9IGNyZWF0ZVJhbmdlKCk7XG5cbiAgICAvKipcbiAgICAgKiBUaGlzIG1ldGhvZCBpcyBsaWtlIGBfLnJhbmdlYCBleGNlcHQgdGhhdCBpdCBwb3B1bGF0ZXMgdmFsdWVzIGluXG4gICAgICogZGVzY2VuZGluZyBvcmRlci5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSA0LjAuMFxuICAgICAqIEBjYXRlZ29yeSBVdGlsXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IFtzdGFydD0wXSBUaGUgc3RhcnQgb2YgdGhlIHJhbmdlLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBlbmQgVGhlIGVuZCBvZiB0aGUgcmFuZ2UuXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IFtzdGVwPTFdIFRoZSB2YWx1ZSB0byBpbmNyZW1lbnQgb3IgZGVjcmVtZW50IGJ5LlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgcmFuZ2Ugb2YgbnVtYmVycy5cbiAgICAgKiBAc2VlIF8uaW5SYW5nZSwgXy5yYW5nZVxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLnJhbmdlUmlnaHQoNCk7XG4gICAgICogLy8gPT4gWzMsIDIsIDEsIDBdXG4gICAgICpcbiAgICAgKiBfLnJhbmdlUmlnaHQoLTQpO1xuICAgICAqIC8vID0+IFstMywgLTIsIC0xLCAwXVxuICAgICAqXG4gICAgICogXy5yYW5nZVJpZ2h0KDEsIDUpO1xuICAgICAqIC8vID0+IFs0LCAzLCAyLCAxXVxuICAgICAqXG4gICAgICogXy5yYW5nZVJpZ2h0KDAsIDIwLCA1KTtcbiAgICAgKiAvLyA9PiBbMTUsIDEwLCA1LCAwXVxuICAgICAqXG4gICAgICogXy5yYW5nZVJpZ2h0KDAsIC00LCAtMSk7XG4gICAgICogLy8gPT4gWy0zLCAtMiwgLTEsIDBdXG4gICAgICpcbiAgICAgKiBfLnJhbmdlUmlnaHQoMSwgNCwgMCk7XG4gICAgICogLy8gPT4gWzEsIDEsIDFdXG4gICAgICpcbiAgICAgKiBfLnJhbmdlUmlnaHQoMCk7XG4gICAgICogLy8gPT4gW11cbiAgICAgKi9cbiAgICB2YXIgcmFuZ2VSaWdodCA9IGNyZWF0ZVJhbmdlKHRydWUpO1xuXG4gICAgLyoqXG4gICAgICogVGhpcyBtZXRob2QgcmV0dXJucyBhIG5ldyBlbXB0eSBhcnJheS5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSA0LjEzLjBcbiAgICAgKiBAY2F0ZWdvcnkgVXRpbFxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgbmV3IGVtcHR5IGFycmF5LlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiB2YXIgYXJyYXlzID0gXy50aW1lcygyLCBfLnN0dWJBcnJheSk7XG4gICAgICpcbiAgICAgKiBjb25zb2xlLmxvZyhhcnJheXMpO1xuICAgICAqIC8vID0+IFtbXSwgW11dXG4gICAgICpcbiAgICAgKiBjb25zb2xlLmxvZyhhcnJheXNbMF0gPT09IGFycmF5c1sxXSk7XG4gICAgICogLy8gPT4gZmFsc2VcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBzdHViQXJyYXkoKSB7XG4gICAgICByZXR1cm4gW107XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhpcyBtZXRob2QgcmV0dXJucyBgZmFsc2VgLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDQuMTMuMFxuICAgICAqIEBjYXRlZ29yeSBVdGlsXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYGZhbHNlYC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy50aW1lcygyLCBfLnN0dWJGYWxzZSk7XG4gICAgICogLy8gPT4gW2ZhbHNlLCBmYWxzZV1cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBzdHViRmFsc2UoKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhpcyBtZXRob2QgcmV0dXJucyBhIG5ldyBlbXB0eSBvYmplY3QuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgNC4xMy4wXG4gICAgICogQGNhdGVnb3J5IFV0aWxcbiAgICAgKiBAcmV0dXJucyB7T2JqZWN0fSBSZXR1cm5zIHRoZSBuZXcgZW1wdHkgb2JqZWN0LlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiB2YXIgb2JqZWN0cyA9IF8udGltZXMoMiwgXy5zdHViT2JqZWN0KTtcbiAgICAgKlxuICAgICAqIGNvbnNvbGUubG9nKG9iamVjdHMpO1xuICAgICAqIC8vID0+IFt7fSwge31dXG4gICAgICpcbiAgICAgKiBjb25zb2xlLmxvZyhvYmplY3RzWzBdID09PSBvYmplY3RzWzFdKTtcbiAgICAgKiAvLyA9PiBmYWxzZVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIHN0dWJPYmplY3QoKSB7XG4gICAgICByZXR1cm4ge307XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhpcyBtZXRob2QgcmV0dXJucyBhbiBlbXB0eSBzdHJpbmcuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgNC4xMy4wXG4gICAgICogQGNhdGVnb3J5IFV0aWxcbiAgICAgKiBAcmV0dXJucyB7c3RyaW5nfSBSZXR1cm5zIHRoZSBlbXB0eSBzdHJpbmcuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8udGltZXMoMiwgXy5zdHViU3RyaW5nKTtcbiAgICAgKiAvLyA9PiBbJycsICcnXVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIHN0dWJTdHJpbmcoKSB7XG4gICAgICByZXR1cm4gJyc7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhpcyBtZXRob2QgcmV0dXJucyBgdHJ1ZWAuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgNC4xMy4wXG4gICAgICogQGNhdGVnb3J5IFV0aWxcbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8udGltZXMoMiwgXy5zdHViVHJ1ZSk7XG4gICAgICogLy8gPT4gW3RydWUsIHRydWVdXG4gICAgICovXG4gICAgZnVuY3Rpb24gc3R1YlRydWUoKSB7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBJbnZva2VzIHRoZSBpdGVyYXRlZSBgbmAgdGltZXMsIHJldHVybmluZyBhbiBhcnJheSBvZiB0aGUgcmVzdWx0cyBvZlxuICAgICAqIGVhY2ggaW52b2NhdGlvbi4gVGhlIGl0ZXJhdGVlIGlzIGludm9rZWQgd2l0aCBvbmUgYXJndW1lbnQ7IChpbmRleCkuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQHNpbmNlIDAuMS4wXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAY2F0ZWdvcnkgVXRpbFxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBuIFRoZSBudW1iZXIgb2YgdGltZXMgdG8gaW52b2tlIGBpdGVyYXRlZWAuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gW2l0ZXJhdGVlPV8uaWRlbnRpdHldIFRoZSBmdW5jdGlvbiBpbnZva2VkIHBlciBpdGVyYXRpb24uXG4gICAgICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBhcnJheSBvZiByZXN1bHRzLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLnRpbWVzKDMsIFN0cmluZyk7XG4gICAgICogLy8gPT4gWycwJywgJzEnLCAnMiddXG4gICAgICpcbiAgICAgKiAgXy50aW1lcyg0LCBfLmNvbnN0YW50KDApKTtcbiAgICAgKiAvLyA9PiBbMCwgMCwgMCwgMF1cbiAgICAgKi9cbiAgICBmdW5jdGlvbiB0aW1lcyhuLCBpdGVyYXRlZSkge1xuICAgICAgbiA9IHRvSW50ZWdlcihuKTtcbiAgICAgIGlmIChuIDwgMSB8fCBuID4gTUFYX1NBRkVfSU5URUdFUikge1xuICAgICAgICByZXR1cm4gW107XG4gICAgICB9XG4gICAgICB2YXIgaW5kZXggPSBNQVhfQVJSQVlfTEVOR1RILFxuICAgICAgICAgIGxlbmd0aCA9IG5hdGl2ZU1pbihuLCBNQVhfQVJSQVlfTEVOR1RIKTtcblxuICAgICAgaXRlcmF0ZWUgPSBnZXRJdGVyYXRlZShpdGVyYXRlZSk7XG4gICAgICBuIC09IE1BWF9BUlJBWV9MRU5HVEg7XG5cbiAgICAgIHZhciByZXN1bHQgPSBiYXNlVGltZXMobGVuZ3RoLCBpdGVyYXRlZSk7XG4gICAgICB3aGlsZSAoKytpbmRleCA8IG4pIHtcbiAgICAgICAgaXRlcmF0ZWUoaW5kZXgpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDb252ZXJ0cyBgdmFsdWVgIHRvIGEgcHJvcGVydHkgcGF0aCBhcnJheS5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSA0LjAuMFxuICAgICAqIEBjYXRlZ29yeSBVdGlsXG4gICAgICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY29udmVydC5cbiAgICAgKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIG5ldyBwcm9wZXJ0eSBwYXRoIGFycmF5LlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLnRvUGF0aCgnYS5iLmMnKTtcbiAgICAgKiAvLyA9PiBbJ2EnLCAnYicsICdjJ11cbiAgICAgKlxuICAgICAqIF8udG9QYXRoKCdhWzBdLmIuYycpO1xuICAgICAqIC8vID0+IFsnYScsICcwJywgJ2InLCAnYyddXG4gICAgICovXG4gICAgZnVuY3Rpb24gdG9QYXRoKHZhbHVlKSB7XG4gICAgICBpZiAoaXNBcnJheSh2YWx1ZSkpIHtcbiAgICAgICAgcmV0dXJuIGFycmF5TWFwKHZhbHVlLCB0b0tleSk7XG4gICAgICB9XG4gICAgICByZXR1cm4gaXNTeW1ib2wodmFsdWUpID8gW3ZhbHVlXSA6IGNvcHlBcnJheShzdHJpbmdUb1BhdGgodG9TdHJpbmcodmFsdWUpKSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogR2VuZXJhdGVzIGEgdW5pcXVlIElELiBJZiBgcHJlZml4YCBpcyBnaXZlbiwgdGhlIElEIGlzIGFwcGVuZGVkIHRvIGl0LlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBzaW5jZSAwLjEuMFxuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQGNhdGVnb3J5IFV0aWxcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gW3ByZWZpeD0nJ10gVGhlIHZhbHVlIHRvIHByZWZpeCB0aGUgSUQgd2l0aC5cbiAgICAgKiBAcmV0dXJucyB7c3RyaW5nfSBSZXR1cm5zIHRoZSB1bmlxdWUgSUQuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8udW5pcXVlSWQoJ2NvbnRhY3RfJyk7XG4gICAgICogLy8gPT4gJ2NvbnRhY3RfMTA0J1xuICAgICAqXG4gICAgICogXy51bmlxdWVJZCgpO1xuICAgICAqIC8vID0+ICcxMDUnXG4gICAgICovXG4gICAgZnVuY3Rpb24gdW5pcXVlSWQocHJlZml4KSB7XG4gICAgICB2YXIgaWQgPSArK2lkQ291bnRlcjtcbiAgICAgIHJldHVybiB0b1N0cmluZyhwcmVmaXgpICsgaWQ7XG4gICAgfVxuXG4gICAgLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qL1xuXG4gICAgLyoqXG4gICAgICogQWRkcyB0d28gbnVtYmVycy5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAzLjQuMFxuICAgICAqIEBjYXRlZ29yeSBNYXRoXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IGF1Z2VuZCBUaGUgZmlyc3QgbnVtYmVyIGluIGFuIGFkZGl0aW9uLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBhZGRlbmQgVGhlIHNlY29uZCBudW1iZXIgaW4gYW4gYWRkaXRpb24uXG4gICAgICogQHJldHVybnMge251bWJlcn0gUmV0dXJucyB0aGUgdG90YWwuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8uYWRkKDYsIDQpO1xuICAgICAqIC8vID0+IDEwXG4gICAgICovXG4gICAgdmFyIGFkZCA9IGNyZWF0ZU1hdGhPcGVyYXRpb24oZnVuY3Rpb24oYXVnZW5kLCBhZGRlbmQpIHtcbiAgICAgIHJldHVybiBhdWdlbmQgKyBhZGRlbmQ7XG4gICAgfSwgMCk7XG5cbiAgICAvKipcbiAgICAgKiBDb21wdXRlcyBgbnVtYmVyYCByb3VuZGVkIHVwIHRvIGBwcmVjaXNpb25gLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDMuMTAuMFxuICAgICAqIEBjYXRlZ29yeSBNYXRoXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IG51bWJlciBUaGUgbnVtYmVyIHRvIHJvdW5kIHVwLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbcHJlY2lzaW9uPTBdIFRoZSBwcmVjaXNpb24gdG8gcm91bmQgdXAgdG8uXG4gICAgICogQHJldHVybnMge251bWJlcn0gUmV0dXJucyB0aGUgcm91bmRlZCB1cCBudW1iZXIuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8uY2VpbCg0LjAwNik7XG4gICAgICogLy8gPT4gNVxuICAgICAqXG4gICAgICogXy5jZWlsKDYuMDA0LCAyKTtcbiAgICAgKiAvLyA9PiA2LjAxXG4gICAgICpcbiAgICAgKiBfLmNlaWwoNjA0MCwgLTIpO1xuICAgICAqIC8vID0+IDYxMDBcbiAgICAgKi9cbiAgICB2YXIgY2VpbCA9IGNyZWF0ZVJvdW5kKCdjZWlsJyk7XG5cbiAgICAvKipcbiAgICAgKiBEaXZpZGUgdHdvIG51bWJlcnMuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgNC43LjBcbiAgICAgKiBAY2F0ZWdvcnkgTWF0aFxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBkaXZpZGVuZCBUaGUgZmlyc3QgbnVtYmVyIGluIGEgZGl2aXNpb24uXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IGRpdmlzb3IgVGhlIHNlY29uZCBudW1iZXIgaW4gYSBkaXZpc2lvbi5cbiAgICAgKiBAcmV0dXJucyB7bnVtYmVyfSBSZXR1cm5zIHRoZSBxdW90aWVudC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy5kaXZpZGUoNiwgNCk7XG4gICAgICogLy8gPT4gMS41XG4gICAgICovXG4gICAgdmFyIGRpdmlkZSA9IGNyZWF0ZU1hdGhPcGVyYXRpb24oZnVuY3Rpb24oZGl2aWRlbmQsIGRpdmlzb3IpIHtcbiAgICAgIHJldHVybiBkaXZpZGVuZCAvIGRpdmlzb3I7XG4gICAgfSwgMSk7XG5cbiAgICAvKipcbiAgICAgKiBDb21wdXRlcyBgbnVtYmVyYCByb3VuZGVkIGRvd24gdG8gYHByZWNpc2lvbmAuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMy4xMC4wXG4gICAgICogQGNhdGVnb3J5IE1hdGhcbiAgICAgKiBAcGFyYW0ge251bWJlcn0gbnVtYmVyIFRoZSBudW1iZXIgdG8gcm91bmQgZG93bi5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gW3ByZWNpc2lvbj0wXSBUaGUgcHJlY2lzaW9uIHRvIHJvdW5kIGRvd24gdG8uXG4gICAgICogQHJldHVybnMge251bWJlcn0gUmV0dXJucyB0aGUgcm91bmRlZCBkb3duIG51bWJlci5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy5mbG9vcig0LjAwNik7XG4gICAgICogLy8gPT4gNFxuICAgICAqXG4gICAgICogXy5mbG9vcigwLjA0NiwgMik7XG4gICAgICogLy8gPT4gMC4wNFxuICAgICAqXG4gICAgICogXy5mbG9vcig0MDYwLCAtMik7XG4gICAgICogLy8gPT4gNDAwMFxuICAgICAqL1xuICAgIHZhciBmbG9vciA9IGNyZWF0ZVJvdW5kKCdmbG9vcicpO1xuXG4gICAgLyoqXG4gICAgICogQ29tcHV0ZXMgdGhlIG1heGltdW0gdmFsdWUgb2YgYGFycmF5YC4gSWYgYGFycmF5YCBpcyBlbXB0eSBvciBmYWxzZXksXG4gICAgICogYHVuZGVmaW5lZGAgaXMgcmV0dXJuZWQuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQHNpbmNlIDAuMS4wXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAY2F0ZWdvcnkgTWF0aFxuICAgICAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBhcnJheSB0byBpdGVyYXRlIG92ZXIuXG4gICAgICogQHJldHVybnMgeyp9IFJldHVybnMgdGhlIG1heGltdW0gdmFsdWUuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8ubWF4KFs0LCAyLCA4LCA2XSk7XG4gICAgICogLy8gPT4gOFxuICAgICAqXG4gICAgICogXy5tYXgoW10pO1xuICAgICAqIC8vID0+IHVuZGVmaW5lZFxuICAgICAqL1xuICAgIGZ1bmN0aW9uIG1heChhcnJheSkge1xuICAgICAgcmV0dXJuIChhcnJheSAmJiBhcnJheS5sZW5ndGgpXG4gICAgICAgID8gYmFzZUV4dHJlbXVtKGFycmF5LCBpZGVudGl0eSwgYmFzZUd0KVxuICAgICAgICA6IHVuZGVmaW5lZDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGlzIG1ldGhvZCBpcyBsaWtlIGBfLm1heGAgZXhjZXB0IHRoYXQgaXQgYWNjZXB0cyBgaXRlcmF0ZWVgIHdoaWNoIGlzXG4gICAgICogaW52b2tlZCBmb3IgZWFjaCBlbGVtZW50IGluIGBhcnJheWAgdG8gZ2VuZXJhdGUgdGhlIGNyaXRlcmlvbiBieSB3aGljaFxuICAgICAqIHRoZSB2YWx1ZSBpcyByYW5rZWQuIFRoZSBpdGVyYXRlZSBpcyBpbnZva2VkIHdpdGggb25lIGFyZ3VtZW50OiAodmFsdWUpLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDQuMC4wXG4gICAgICogQGNhdGVnb3J5IE1hdGhcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBhcnJheSBUaGUgYXJyYXkgdG8gaXRlcmF0ZSBvdmVyLlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IFtpdGVyYXRlZT1fLmlkZW50aXR5XSBUaGUgaXRlcmF0ZWUgaW52b2tlZCBwZXIgZWxlbWVudC5cbiAgICAgKiBAcmV0dXJucyB7Kn0gUmV0dXJucyB0aGUgbWF4aW11bSB2YWx1ZS5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogdmFyIG9iamVjdHMgPSBbeyAnbic6IDEgfSwgeyAnbic6IDIgfV07XG4gICAgICpcbiAgICAgKiBfLm1heEJ5KG9iamVjdHMsIGZ1bmN0aW9uKG8pIHsgcmV0dXJuIG8ubjsgfSk7XG4gICAgICogLy8gPT4geyAnbic6IDIgfVxuICAgICAqXG4gICAgICogLy8gVGhlIGBfLnByb3BlcnR5YCBpdGVyYXRlZSBzaG9ydGhhbmQuXG4gICAgICogXy5tYXhCeShvYmplY3RzLCAnbicpO1xuICAgICAqIC8vID0+IHsgJ24nOiAyIH1cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBtYXhCeShhcnJheSwgaXRlcmF0ZWUpIHtcbiAgICAgIHJldHVybiAoYXJyYXkgJiYgYXJyYXkubGVuZ3RoKVxuICAgICAgICA/IGJhc2VFeHRyZW11bShhcnJheSwgZ2V0SXRlcmF0ZWUoaXRlcmF0ZWUsIDIpLCBiYXNlR3QpXG4gICAgICAgIDogdW5kZWZpbmVkO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENvbXB1dGVzIHRoZSBtZWFuIG9mIHRoZSB2YWx1ZXMgaW4gYGFycmF5YC5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSA0LjAuMFxuICAgICAqIEBjYXRlZ29yeSBNYXRoXG4gICAgICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIGl0ZXJhdGUgb3Zlci5cbiAgICAgKiBAcmV0dXJucyB7bnVtYmVyfSBSZXR1cm5zIHRoZSBtZWFuLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLm1lYW4oWzQsIDIsIDgsIDZdKTtcbiAgICAgKiAvLyA9PiA1XG4gICAgICovXG4gICAgZnVuY3Rpb24gbWVhbihhcnJheSkge1xuICAgICAgcmV0dXJuIGJhc2VNZWFuKGFycmF5LCBpZGVudGl0eSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhpcyBtZXRob2QgaXMgbGlrZSBgXy5tZWFuYCBleGNlcHQgdGhhdCBpdCBhY2NlcHRzIGBpdGVyYXRlZWAgd2hpY2ggaXNcbiAgICAgKiBpbnZva2VkIGZvciBlYWNoIGVsZW1lbnQgaW4gYGFycmF5YCB0byBnZW5lcmF0ZSB0aGUgdmFsdWUgdG8gYmUgYXZlcmFnZWQuXG4gICAgICogVGhlIGl0ZXJhdGVlIGlzIGludm9rZWQgd2l0aCBvbmUgYXJndW1lbnQ6ICh2YWx1ZSkuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgNC43LjBcbiAgICAgKiBAY2F0ZWdvcnkgTWF0aFxuICAgICAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBhcnJheSB0byBpdGVyYXRlIG92ZXIuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gW2l0ZXJhdGVlPV8uaWRlbnRpdHldIFRoZSBpdGVyYXRlZSBpbnZva2VkIHBlciBlbGVtZW50LlxuICAgICAqIEByZXR1cm5zIHtudW1iZXJ9IFJldHVybnMgdGhlIG1lYW4uXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIHZhciBvYmplY3RzID0gW3sgJ24nOiA0IH0sIHsgJ24nOiAyIH0sIHsgJ24nOiA4IH0sIHsgJ24nOiA2IH1dO1xuICAgICAqXG4gICAgICogXy5tZWFuQnkob2JqZWN0cywgZnVuY3Rpb24obykgeyByZXR1cm4gby5uOyB9KTtcbiAgICAgKiAvLyA9PiA1XG4gICAgICpcbiAgICAgKiAvLyBUaGUgYF8ucHJvcGVydHlgIGl0ZXJhdGVlIHNob3J0aGFuZC5cbiAgICAgKiBfLm1lYW5CeShvYmplY3RzLCAnbicpO1xuICAgICAqIC8vID0+IDVcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBtZWFuQnkoYXJyYXksIGl0ZXJhdGVlKSB7XG4gICAgICByZXR1cm4gYmFzZU1lYW4oYXJyYXksIGdldEl0ZXJhdGVlKGl0ZXJhdGVlLCAyKSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ29tcHV0ZXMgdGhlIG1pbmltdW0gdmFsdWUgb2YgYGFycmF5YC4gSWYgYGFycmF5YCBpcyBlbXB0eSBvciBmYWxzZXksXG4gICAgICogYHVuZGVmaW5lZGAgaXMgcmV0dXJuZWQuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQHNpbmNlIDAuMS4wXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAY2F0ZWdvcnkgTWF0aFxuICAgICAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBhcnJheSB0byBpdGVyYXRlIG92ZXIuXG4gICAgICogQHJldHVybnMgeyp9IFJldHVybnMgdGhlIG1pbmltdW0gdmFsdWUuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8ubWluKFs0LCAyLCA4LCA2XSk7XG4gICAgICogLy8gPT4gMlxuICAgICAqXG4gICAgICogXy5taW4oW10pO1xuICAgICAqIC8vID0+IHVuZGVmaW5lZFxuICAgICAqL1xuICAgIGZ1bmN0aW9uIG1pbihhcnJheSkge1xuICAgICAgcmV0dXJuIChhcnJheSAmJiBhcnJheS5sZW5ndGgpXG4gICAgICAgID8gYmFzZUV4dHJlbXVtKGFycmF5LCBpZGVudGl0eSwgYmFzZUx0KVxuICAgICAgICA6IHVuZGVmaW5lZDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGlzIG1ldGhvZCBpcyBsaWtlIGBfLm1pbmAgZXhjZXB0IHRoYXQgaXQgYWNjZXB0cyBgaXRlcmF0ZWVgIHdoaWNoIGlzXG4gICAgICogaW52b2tlZCBmb3IgZWFjaCBlbGVtZW50IGluIGBhcnJheWAgdG8gZ2VuZXJhdGUgdGhlIGNyaXRlcmlvbiBieSB3aGljaFxuICAgICAqIHRoZSB2YWx1ZSBpcyByYW5rZWQuIFRoZSBpdGVyYXRlZSBpcyBpbnZva2VkIHdpdGggb25lIGFyZ3VtZW50OiAodmFsdWUpLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDQuMC4wXG4gICAgICogQGNhdGVnb3J5IE1hdGhcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBhcnJheSBUaGUgYXJyYXkgdG8gaXRlcmF0ZSBvdmVyLlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IFtpdGVyYXRlZT1fLmlkZW50aXR5XSBUaGUgaXRlcmF0ZWUgaW52b2tlZCBwZXIgZWxlbWVudC5cbiAgICAgKiBAcmV0dXJucyB7Kn0gUmV0dXJucyB0aGUgbWluaW11bSB2YWx1ZS5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogdmFyIG9iamVjdHMgPSBbeyAnbic6IDEgfSwgeyAnbic6IDIgfV07XG4gICAgICpcbiAgICAgKiBfLm1pbkJ5KG9iamVjdHMsIGZ1bmN0aW9uKG8pIHsgcmV0dXJuIG8ubjsgfSk7XG4gICAgICogLy8gPT4geyAnbic6IDEgfVxuICAgICAqXG4gICAgICogLy8gVGhlIGBfLnByb3BlcnR5YCBpdGVyYXRlZSBzaG9ydGhhbmQuXG4gICAgICogXy5taW5CeShvYmplY3RzLCAnbicpO1xuICAgICAqIC8vID0+IHsgJ24nOiAxIH1cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBtaW5CeShhcnJheSwgaXRlcmF0ZWUpIHtcbiAgICAgIHJldHVybiAoYXJyYXkgJiYgYXJyYXkubGVuZ3RoKVxuICAgICAgICA/IGJhc2VFeHRyZW11bShhcnJheSwgZ2V0SXRlcmF0ZWUoaXRlcmF0ZWUsIDIpLCBiYXNlTHQpXG4gICAgICAgIDogdW5kZWZpbmVkO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIE11bHRpcGx5IHR3byBudW1iZXJzLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDQuNy4wXG4gICAgICogQGNhdGVnb3J5IE1hdGhcbiAgICAgKiBAcGFyYW0ge251bWJlcn0gbXVsdGlwbGllciBUaGUgZmlyc3QgbnVtYmVyIGluIGEgbXVsdGlwbGljYXRpb24uXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IG11bHRpcGxpY2FuZCBUaGUgc2Vjb25kIG51bWJlciBpbiBhIG11bHRpcGxpY2F0aW9uLlxuICAgICAqIEByZXR1cm5zIHtudW1iZXJ9IFJldHVybnMgdGhlIHByb2R1Y3QuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8ubXVsdGlwbHkoNiwgNCk7XG4gICAgICogLy8gPT4gMjRcbiAgICAgKi9cbiAgICB2YXIgbXVsdGlwbHkgPSBjcmVhdGVNYXRoT3BlcmF0aW9uKGZ1bmN0aW9uKG11bHRpcGxpZXIsIG11bHRpcGxpY2FuZCkge1xuICAgICAgcmV0dXJuIG11bHRpcGxpZXIgKiBtdWx0aXBsaWNhbmQ7XG4gICAgfSwgMSk7XG5cbiAgICAvKipcbiAgICAgKiBDb21wdXRlcyBgbnVtYmVyYCByb3VuZGVkIHRvIGBwcmVjaXNpb25gLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDMuMTAuMFxuICAgICAqIEBjYXRlZ29yeSBNYXRoXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IG51bWJlciBUaGUgbnVtYmVyIHRvIHJvdW5kLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbcHJlY2lzaW9uPTBdIFRoZSBwcmVjaXNpb24gdG8gcm91bmQgdG8uXG4gICAgICogQHJldHVybnMge251bWJlcn0gUmV0dXJucyB0aGUgcm91bmRlZCBudW1iZXIuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8ucm91bmQoNC4wMDYpO1xuICAgICAqIC8vID0+IDRcbiAgICAgKlxuICAgICAqIF8ucm91bmQoNC4wMDYsIDIpO1xuICAgICAqIC8vID0+IDQuMDFcbiAgICAgKlxuICAgICAqIF8ucm91bmQoNDA2MCwgLTIpO1xuICAgICAqIC8vID0+IDQxMDBcbiAgICAgKi9cbiAgICB2YXIgcm91bmQgPSBjcmVhdGVSb3VuZCgncm91bmQnKTtcblxuICAgIC8qKlxuICAgICAqIFN1YnRyYWN0IHR3byBudW1iZXJzLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDQuMC4wXG4gICAgICogQGNhdGVnb3J5IE1hdGhcbiAgICAgKiBAcGFyYW0ge251bWJlcn0gbWludWVuZCBUaGUgZmlyc3QgbnVtYmVyIGluIGEgc3VidHJhY3Rpb24uXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IHN1YnRyYWhlbmQgVGhlIHNlY29uZCBudW1iZXIgaW4gYSBzdWJ0cmFjdGlvbi5cbiAgICAgKiBAcmV0dXJucyB7bnVtYmVyfSBSZXR1cm5zIHRoZSBkaWZmZXJlbmNlLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLnN1YnRyYWN0KDYsIDQpO1xuICAgICAqIC8vID0+IDJcbiAgICAgKi9cbiAgICB2YXIgc3VidHJhY3QgPSBjcmVhdGVNYXRoT3BlcmF0aW9uKGZ1bmN0aW9uKG1pbnVlbmQsIHN1YnRyYWhlbmQpIHtcbiAgICAgIHJldHVybiBtaW51ZW5kIC0gc3VidHJhaGVuZDtcbiAgICB9LCAwKTtcblxuICAgIC8qKlxuICAgICAqIENvbXB1dGVzIHRoZSBzdW0gb2YgdGhlIHZhbHVlcyBpbiBgYXJyYXlgLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDMuNC4wXG4gICAgICogQGNhdGVnb3J5IE1hdGhcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBhcnJheSBUaGUgYXJyYXkgdG8gaXRlcmF0ZSBvdmVyLlxuICAgICAqIEByZXR1cm5zIHtudW1iZXJ9IFJldHVybnMgdGhlIHN1bS5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy5zdW0oWzQsIDIsIDgsIDZdKTtcbiAgICAgKiAvLyA9PiAyMFxuICAgICAqL1xuICAgIGZ1bmN0aW9uIHN1bShhcnJheSkge1xuICAgICAgcmV0dXJuIChhcnJheSAmJiBhcnJheS5sZW5ndGgpXG4gICAgICAgID8gYmFzZVN1bShhcnJheSwgaWRlbnRpdHkpXG4gICAgICAgIDogMDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGlzIG1ldGhvZCBpcyBsaWtlIGBfLnN1bWAgZXhjZXB0IHRoYXQgaXQgYWNjZXB0cyBgaXRlcmF0ZWVgIHdoaWNoIGlzXG4gICAgICogaW52b2tlZCBmb3IgZWFjaCBlbGVtZW50IGluIGBhcnJheWAgdG8gZ2VuZXJhdGUgdGhlIHZhbHVlIHRvIGJlIHN1bW1lZC5cbiAgICAgKiBUaGUgaXRlcmF0ZWUgaXMgaW52b2tlZCB3aXRoIG9uZSBhcmd1bWVudDogKHZhbHVlKS5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSA0LjAuMFxuICAgICAqIEBjYXRlZ29yeSBNYXRoXG4gICAgICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIGl0ZXJhdGUgb3Zlci5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBbaXRlcmF0ZWU9Xy5pZGVudGl0eV0gVGhlIGl0ZXJhdGVlIGludm9rZWQgcGVyIGVsZW1lbnQuXG4gICAgICogQHJldHVybnMge251bWJlcn0gUmV0dXJucyB0aGUgc3VtLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiB2YXIgb2JqZWN0cyA9IFt7ICduJzogNCB9LCB7ICduJzogMiB9LCB7ICduJzogOCB9LCB7ICduJzogNiB9XTtcbiAgICAgKlxuICAgICAqIF8uc3VtQnkob2JqZWN0cywgZnVuY3Rpb24obykgeyByZXR1cm4gby5uOyB9KTtcbiAgICAgKiAvLyA9PiAyMFxuICAgICAqXG4gICAgICogLy8gVGhlIGBfLnByb3BlcnR5YCBpdGVyYXRlZSBzaG9ydGhhbmQuXG4gICAgICogXy5zdW1CeShvYmplY3RzLCAnbicpO1xuICAgICAqIC8vID0+IDIwXG4gICAgICovXG4gICAgZnVuY3Rpb24gc3VtQnkoYXJyYXksIGl0ZXJhdGVlKSB7XG4gICAgICByZXR1cm4gKGFycmF5ICYmIGFycmF5Lmxlbmd0aClcbiAgICAgICAgPyBiYXNlU3VtKGFycmF5LCBnZXRJdGVyYXRlZShpdGVyYXRlZSwgMikpXG4gICAgICAgIDogMDtcbiAgICB9XG5cbiAgICAvKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovXG5cbiAgICAvLyBBZGQgbWV0aG9kcyB0aGF0IHJldHVybiB3cmFwcGVkIHZhbHVlcyBpbiBjaGFpbiBzZXF1ZW5jZXMuXG4gICAgbG9kYXNoLmFmdGVyID0gYWZ0ZXI7XG4gICAgbG9kYXNoLmFyeSA9IGFyeTtcbiAgICBsb2Rhc2guYXNzaWduID0gYXNzaWduO1xuICAgIGxvZGFzaC5hc3NpZ25JbiA9IGFzc2lnbkluO1xuICAgIGxvZGFzaC5hc3NpZ25JbldpdGggPSBhc3NpZ25JbldpdGg7XG4gICAgbG9kYXNoLmFzc2lnbldpdGggPSBhc3NpZ25XaXRoO1xuICAgIGxvZGFzaC5hdCA9IGF0O1xuICAgIGxvZGFzaC5iZWZvcmUgPSBiZWZvcmU7XG4gICAgbG9kYXNoLmJpbmQgPSBiaW5kO1xuICAgIGxvZGFzaC5iaW5kQWxsID0gYmluZEFsbDtcbiAgICBsb2Rhc2guYmluZEtleSA9IGJpbmRLZXk7XG4gICAgbG9kYXNoLmNhc3RBcnJheSA9IGNhc3RBcnJheTtcbiAgICBsb2Rhc2guY2hhaW4gPSBjaGFpbjtcbiAgICBsb2Rhc2guY2h1bmsgPSBjaHVuaztcbiAgICBsb2Rhc2guY29tcGFjdCA9IGNvbXBhY3Q7XG4gICAgbG9kYXNoLmNvbmNhdCA9IGNvbmNhdDtcbiAgICBsb2Rhc2guY29uZCA9IGNvbmQ7XG4gICAgbG9kYXNoLmNvbmZvcm1zID0gY29uZm9ybXM7XG4gICAgbG9kYXNoLmNvbnN0YW50ID0gY29uc3RhbnQ7XG4gICAgbG9kYXNoLmNvdW50QnkgPSBjb3VudEJ5O1xuICAgIGxvZGFzaC5jcmVhdGUgPSBjcmVhdGU7XG4gICAgbG9kYXNoLmN1cnJ5ID0gY3Vycnk7XG4gICAgbG9kYXNoLmN1cnJ5UmlnaHQgPSBjdXJyeVJpZ2h0O1xuICAgIGxvZGFzaC5kZWJvdW5jZSA9IGRlYm91bmNlO1xuICAgIGxvZGFzaC5kZWZhdWx0cyA9IGRlZmF1bHRzO1xuICAgIGxvZGFzaC5kZWZhdWx0c0RlZXAgPSBkZWZhdWx0c0RlZXA7XG4gICAgbG9kYXNoLmRlZmVyID0gZGVmZXI7XG4gICAgbG9kYXNoLmRlbGF5ID0gZGVsYXk7XG4gICAgbG9kYXNoLmRpZmZlcmVuY2UgPSBkaWZmZXJlbmNlO1xuICAgIGxvZGFzaC5kaWZmZXJlbmNlQnkgPSBkaWZmZXJlbmNlQnk7XG4gICAgbG9kYXNoLmRpZmZlcmVuY2VXaXRoID0gZGlmZmVyZW5jZVdpdGg7XG4gICAgbG9kYXNoLmRyb3AgPSBkcm9wO1xuICAgIGxvZGFzaC5kcm9wUmlnaHQgPSBkcm9wUmlnaHQ7XG4gICAgbG9kYXNoLmRyb3BSaWdodFdoaWxlID0gZHJvcFJpZ2h0V2hpbGU7XG4gICAgbG9kYXNoLmRyb3BXaGlsZSA9IGRyb3BXaGlsZTtcbiAgICBsb2Rhc2guZmlsbCA9IGZpbGw7XG4gICAgbG9kYXNoLmZpbHRlciA9IGZpbHRlcjtcbiAgICBsb2Rhc2guZmxhdE1hcCA9IGZsYXRNYXA7XG4gICAgbG9kYXNoLmZsYXRNYXBEZWVwID0gZmxhdE1hcERlZXA7XG4gICAgbG9kYXNoLmZsYXRNYXBEZXB0aCA9IGZsYXRNYXBEZXB0aDtcbiAgICBsb2Rhc2guZmxhdHRlbiA9IGZsYXR0ZW47XG4gICAgbG9kYXNoLmZsYXR0ZW5EZWVwID0gZmxhdHRlbkRlZXA7XG4gICAgbG9kYXNoLmZsYXR0ZW5EZXB0aCA9IGZsYXR0ZW5EZXB0aDtcbiAgICBsb2Rhc2guZmxpcCA9IGZsaXA7XG4gICAgbG9kYXNoLmZsb3cgPSBmbG93O1xuICAgIGxvZGFzaC5mbG93UmlnaHQgPSBmbG93UmlnaHQ7XG4gICAgbG9kYXNoLmZyb21QYWlycyA9IGZyb21QYWlycztcbiAgICBsb2Rhc2guZnVuY3Rpb25zID0gZnVuY3Rpb25zO1xuICAgIGxvZGFzaC5mdW5jdGlvbnNJbiA9IGZ1bmN0aW9uc0luO1xuICAgIGxvZGFzaC5ncm91cEJ5ID0gZ3JvdXBCeTtcbiAgICBsb2Rhc2guaW5pdGlhbCA9IGluaXRpYWw7XG4gICAgbG9kYXNoLmludGVyc2VjdGlvbiA9IGludGVyc2VjdGlvbjtcbiAgICBsb2Rhc2guaW50ZXJzZWN0aW9uQnkgPSBpbnRlcnNlY3Rpb25CeTtcbiAgICBsb2Rhc2guaW50ZXJzZWN0aW9uV2l0aCA9IGludGVyc2VjdGlvbldpdGg7XG4gICAgbG9kYXNoLmludmVydCA9IGludmVydDtcbiAgICBsb2Rhc2guaW52ZXJ0QnkgPSBpbnZlcnRCeTtcbiAgICBsb2Rhc2guaW52b2tlTWFwID0gaW52b2tlTWFwO1xuICAgIGxvZGFzaC5pdGVyYXRlZSA9IGl0ZXJhdGVlO1xuICAgIGxvZGFzaC5rZXlCeSA9IGtleUJ5O1xuICAgIGxvZGFzaC5rZXlzID0ga2V5cztcbiAgICBsb2Rhc2gua2V5c0luID0ga2V5c0luO1xuICAgIGxvZGFzaC5tYXAgPSBtYXA7XG4gICAgbG9kYXNoLm1hcEtleXMgPSBtYXBLZXlzO1xuICAgIGxvZGFzaC5tYXBWYWx1ZXMgPSBtYXBWYWx1ZXM7XG4gICAgbG9kYXNoLm1hdGNoZXMgPSBtYXRjaGVzO1xuICAgIGxvZGFzaC5tYXRjaGVzUHJvcGVydHkgPSBtYXRjaGVzUHJvcGVydHk7XG4gICAgbG9kYXNoLm1lbW9pemUgPSBtZW1vaXplO1xuICAgIGxvZGFzaC5tZXJnZSA9IG1lcmdlO1xuICAgIGxvZGFzaC5tZXJnZVdpdGggPSBtZXJnZVdpdGg7XG4gICAgbG9kYXNoLm1ldGhvZCA9IG1ldGhvZDtcbiAgICBsb2Rhc2gubWV0aG9kT2YgPSBtZXRob2RPZjtcbiAgICBsb2Rhc2gubWl4aW4gPSBtaXhpbjtcbiAgICBsb2Rhc2gubmVnYXRlID0gbmVnYXRlO1xuICAgIGxvZGFzaC5udGhBcmcgPSBudGhBcmc7XG4gICAgbG9kYXNoLm9taXQgPSBvbWl0O1xuICAgIGxvZGFzaC5vbWl0QnkgPSBvbWl0Qnk7XG4gICAgbG9kYXNoLm9uY2UgPSBvbmNlO1xuICAgIGxvZGFzaC5vcmRlckJ5ID0gb3JkZXJCeTtcbiAgICBsb2Rhc2gub3ZlciA9IG92ZXI7XG4gICAgbG9kYXNoLm92ZXJBcmdzID0gb3ZlckFyZ3M7XG4gICAgbG9kYXNoLm92ZXJFdmVyeSA9IG92ZXJFdmVyeTtcbiAgICBsb2Rhc2gub3ZlclNvbWUgPSBvdmVyU29tZTtcbiAgICBsb2Rhc2gucGFydGlhbCA9IHBhcnRpYWw7XG4gICAgbG9kYXNoLnBhcnRpYWxSaWdodCA9IHBhcnRpYWxSaWdodDtcbiAgICBsb2Rhc2gucGFydGl0aW9uID0gcGFydGl0aW9uO1xuICAgIGxvZGFzaC5waWNrID0gcGljaztcbiAgICBsb2Rhc2gucGlja0J5ID0gcGlja0J5O1xuICAgIGxvZGFzaC5wcm9wZXJ0eSA9IHByb3BlcnR5O1xuICAgIGxvZGFzaC5wcm9wZXJ0eU9mID0gcHJvcGVydHlPZjtcbiAgICBsb2Rhc2gucHVsbCA9IHB1bGw7XG4gICAgbG9kYXNoLnB1bGxBbGwgPSBwdWxsQWxsO1xuICAgIGxvZGFzaC5wdWxsQWxsQnkgPSBwdWxsQWxsQnk7XG4gICAgbG9kYXNoLnB1bGxBbGxXaXRoID0gcHVsbEFsbFdpdGg7XG4gICAgbG9kYXNoLnB1bGxBdCA9IHB1bGxBdDtcbiAgICBsb2Rhc2gucmFuZ2UgPSByYW5nZTtcbiAgICBsb2Rhc2gucmFuZ2VSaWdodCA9IHJhbmdlUmlnaHQ7XG4gICAgbG9kYXNoLnJlYXJnID0gcmVhcmc7XG4gICAgbG9kYXNoLnJlamVjdCA9IHJlamVjdDtcbiAgICBsb2Rhc2gucmVtb3ZlID0gcmVtb3ZlO1xuICAgIGxvZGFzaC5yZXN0ID0gcmVzdDtcbiAgICBsb2Rhc2gucmV2ZXJzZSA9IHJldmVyc2U7XG4gICAgbG9kYXNoLnNhbXBsZVNpemUgPSBzYW1wbGVTaXplO1xuICAgIGxvZGFzaC5zZXQgPSBzZXQ7XG4gICAgbG9kYXNoLnNldFdpdGggPSBzZXRXaXRoO1xuICAgIGxvZGFzaC5zaHVmZmxlID0gc2h1ZmZsZTtcbiAgICBsb2Rhc2guc2xpY2UgPSBzbGljZTtcbiAgICBsb2Rhc2guc29ydEJ5ID0gc29ydEJ5O1xuICAgIGxvZGFzaC5zb3J0ZWRVbmlxID0gc29ydGVkVW5pcTtcbiAgICBsb2Rhc2guc29ydGVkVW5pcUJ5ID0gc29ydGVkVW5pcUJ5O1xuICAgIGxvZGFzaC5zcGxpdCA9IHNwbGl0O1xuICAgIGxvZGFzaC5zcHJlYWQgPSBzcHJlYWQ7XG4gICAgbG9kYXNoLnRhaWwgPSB0YWlsO1xuICAgIGxvZGFzaC50YWtlID0gdGFrZTtcbiAgICBsb2Rhc2gudGFrZVJpZ2h0ID0gdGFrZVJpZ2h0O1xuICAgIGxvZGFzaC50YWtlUmlnaHRXaGlsZSA9IHRha2VSaWdodFdoaWxlO1xuICAgIGxvZGFzaC50YWtlV2hpbGUgPSB0YWtlV2hpbGU7XG4gICAgbG9kYXNoLnRhcCA9IHRhcDtcbiAgICBsb2Rhc2gudGhyb3R0bGUgPSB0aHJvdHRsZTtcbiAgICBsb2Rhc2gudGhydSA9IHRocnU7XG4gICAgbG9kYXNoLnRvQXJyYXkgPSB0b0FycmF5O1xuICAgIGxvZGFzaC50b1BhaXJzID0gdG9QYWlycztcbiAgICBsb2Rhc2gudG9QYWlyc0luID0gdG9QYWlyc0luO1xuICAgIGxvZGFzaC50b1BhdGggPSB0b1BhdGg7XG4gICAgbG9kYXNoLnRvUGxhaW5PYmplY3QgPSB0b1BsYWluT2JqZWN0O1xuICAgIGxvZGFzaC50cmFuc2Zvcm0gPSB0cmFuc2Zvcm07XG4gICAgbG9kYXNoLnVuYXJ5ID0gdW5hcnk7XG4gICAgbG9kYXNoLnVuaW9uID0gdW5pb247XG4gICAgbG9kYXNoLnVuaW9uQnkgPSB1bmlvbkJ5O1xuICAgIGxvZGFzaC51bmlvbldpdGggPSB1bmlvbldpdGg7XG4gICAgbG9kYXNoLnVuaXEgPSB1bmlxO1xuICAgIGxvZGFzaC51bmlxQnkgPSB1bmlxQnk7XG4gICAgbG9kYXNoLnVuaXFXaXRoID0gdW5pcVdpdGg7XG4gICAgbG9kYXNoLnVuc2V0ID0gdW5zZXQ7XG4gICAgbG9kYXNoLnVuemlwID0gdW56aXA7XG4gICAgbG9kYXNoLnVuemlwV2l0aCA9IHVuemlwV2l0aDtcbiAgICBsb2Rhc2gudXBkYXRlID0gdXBkYXRlO1xuICAgIGxvZGFzaC51cGRhdGVXaXRoID0gdXBkYXRlV2l0aDtcbiAgICBsb2Rhc2gudmFsdWVzID0gdmFsdWVzO1xuICAgIGxvZGFzaC52YWx1ZXNJbiA9IHZhbHVlc0luO1xuICAgIGxvZGFzaC53aXRob3V0ID0gd2l0aG91dDtcbiAgICBsb2Rhc2gud29yZHMgPSB3b3JkcztcbiAgICBsb2Rhc2gud3JhcCA9IHdyYXA7XG4gICAgbG9kYXNoLnhvciA9IHhvcjtcbiAgICBsb2Rhc2gueG9yQnkgPSB4b3JCeTtcbiAgICBsb2Rhc2gueG9yV2l0aCA9IHhvcldpdGg7XG4gICAgbG9kYXNoLnppcCA9IHppcDtcbiAgICBsb2Rhc2guemlwT2JqZWN0ID0gemlwT2JqZWN0O1xuICAgIGxvZGFzaC56aXBPYmplY3REZWVwID0gemlwT2JqZWN0RGVlcDtcbiAgICBsb2Rhc2guemlwV2l0aCA9IHppcFdpdGg7XG5cbiAgICAvLyBBZGQgYWxpYXNlcy5cbiAgICBsb2Rhc2guZW50cmllcyA9IHRvUGFpcnM7XG4gICAgbG9kYXNoLmVudHJpZXNJbiA9IHRvUGFpcnNJbjtcbiAgICBsb2Rhc2guZXh0ZW5kID0gYXNzaWduSW47XG4gICAgbG9kYXNoLmV4dGVuZFdpdGggPSBhc3NpZ25JbldpdGg7XG5cbiAgICAvLyBBZGQgbWV0aG9kcyB0byBgbG9kYXNoLnByb3RvdHlwZWAuXG4gICAgbWl4aW4obG9kYXNoLCBsb2Rhc2gpO1xuXG4gICAgLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qL1xuXG4gICAgLy8gQWRkIG1ldGhvZHMgdGhhdCByZXR1cm4gdW53cmFwcGVkIHZhbHVlcyBpbiBjaGFpbiBzZXF1ZW5jZXMuXG4gICAgbG9kYXNoLmFkZCA9IGFkZDtcbiAgICBsb2Rhc2guYXR0ZW1wdCA9IGF0dGVtcHQ7XG4gICAgbG9kYXNoLmNhbWVsQ2FzZSA9IGNhbWVsQ2FzZTtcbiAgICBsb2Rhc2guY2FwaXRhbGl6ZSA9IGNhcGl0YWxpemU7XG4gICAgbG9kYXNoLmNlaWwgPSBjZWlsO1xuICAgIGxvZGFzaC5jbGFtcCA9IGNsYW1wO1xuICAgIGxvZGFzaC5jbG9uZSA9IGNsb25lO1xuICAgIGxvZGFzaC5jbG9uZURlZXAgPSBjbG9uZURlZXA7XG4gICAgbG9kYXNoLmNsb25lRGVlcFdpdGggPSBjbG9uZURlZXBXaXRoO1xuICAgIGxvZGFzaC5jbG9uZVdpdGggPSBjbG9uZVdpdGg7XG4gICAgbG9kYXNoLmNvbmZvcm1zVG8gPSBjb25mb3Jtc1RvO1xuICAgIGxvZGFzaC5kZWJ1cnIgPSBkZWJ1cnI7XG4gICAgbG9kYXNoLmRlZmF1bHRUbyA9IGRlZmF1bHRUbztcbiAgICBsb2Rhc2guZGl2aWRlID0gZGl2aWRlO1xuICAgIGxvZGFzaC5lbmRzV2l0aCA9IGVuZHNXaXRoO1xuICAgIGxvZGFzaC5lcSA9IGVxO1xuICAgIGxvZGFzaC5lc2NhcGUgPSBlc2NhcGU7XG4gICAgbG9kYXNoLmVzY2FwZVJlZ0V4cCA9IGVzY2FwZVJlZ0V4cDtcbiAgICBsb2Rhc2guZXZlcnkgPSBldmVyeTtcbiAgICBsb2Rhc2guZmluZCA9IGZpbmQ7XG4gICAgbG9kYXNoLmZpbmRJbmRleCA9IGZpbmRJbmRleDtcbiAgICBsb2Rhc2guZmluZEtleSA9IGZpbmRLZXk7XG4gICAgbG9kYXNoLmZpbmRMYXN0ID0gZmluZExhc3Q7XG4gICAgbG9kYXNoLmZpbmRMYXN0SW5kZXggPSBmaW5kTGFzdEluZGV4O1xuICAgIGxvZGFzaC5maW5kTGFzdEtleSA9IGZpbmRMYXN0S2V5O1xuICAgIGxvZGFzaC5mbG9vciA9IGZsb29yO1xuICAgIGxvZGFzaC5mb3JFYWNoID0gZm9yRWFjaDtcbiAgICBsb2Rhc2guZm9yRWFjaFJpZ2h0ID0gZm9yRWFjaFJpZ2h0O1xuICAgIGxvZGFzaC5mb3JJbiA9IGZvckluO1xuICAgIGxvZGFzaC5mb3JJblJpZ2h0ID0gZm9ySW5SaWdodDtcbiAgICBsb2Rhc2guZm9yT3duID0gZm9yT3duO1xuICAgIGxvZGFzaC5mb3JPd25SaWdodCA9IGZvck93blJpZ2h0O1xuICAgIGxvZGFzaC5nZXQgPSBnZXQ7XG4gICAgbG9kYXNoLmd0ID0gZ3Q7XG4gICAgbG9kYXNoLmd0ZSA9IGd0ZTtcbiAgICBsb2Rhc2guaGFzID0gaGFzO1xuICAgIGxvZGFzaC5oYXNJbiA9IGhhc0luO1xuICAgIGxvZGFzaC5oZWFkID0gaGVhZDtcbiAgICBsb2Rhc2guaWRlbnRpdHkgPSBpZGVudGl0eTtcbiAgICBsb2Rhc2guaW5jbHVkZXMgPSBpbmNsdWRlcztcbiAgICBsb2Rhc2guaW5kZXhPZiA9IGluZGV4T2Y7XG4gICAgbG9kYXNoLmluUmFuZ2UgPSBpblJhbmdlO1xuICAgIGxvZGFzaC5pbnZva2UgPSBpbnZva2U7XG4gICAgbG9kYXNoLmlzQXJndW1lbnRzID0gaXNBcmd1bWVudHM7XG4gICAgbG9kYXNoLmlzQXJyYXkgPSBpc0FycmF5O1xuICAgIGxvZGFzaC5pc0FycmF5QnVmZmVyID0gaXNBcnJheUJ1ZmZlcjtcbiAgICBsb2Rhc2guaXNBcnJheUxpa2UgPSBpc0FycmF5TGlrZTtcbiAgICBsb2Rhc2guaXNBcnJheUxpa2VPYmplY3QgPSBpc0FycmF5TGlrZU9iamVjdDtcbiAgICBsb2Rhc2guaXNCb29sZWFuID0gaXNCb29sZWFuO1xuICAgIGxvZGFzaC5pc0J1ZmZlciA9IGlzQnVmZmVyO1xuICAgIGxvZGFzaC5pc0RhdGUgPSBpc0RhdGU7XG4gICAgbG9kYXNoLmlzRWxlbWVudCA9IGlzRWxlbWVudDtcbiAgICBsb2Rhc2guaXNFbXB0eSA9IGlzRW1wdHk7XG4gICAgbG9kYXNoLmlzRXF1YWwgPSBpc0VxdWFsO1xuICAgIGxvZGFzaC5pc0VxdWFsV2l0aCA9IGlzRXF1YWxXaXRoO1xuICAgIGxvZGFzaC5pc0Vycm9yID0gaXNFcnJvcjtcbiAgICBsb2Rhc2guaXNGaW5pdGUgPSBpc0Zpbml0ZTtcbiAgICBsb2Rhc2guaXNGdW5jdGlvbiA9IGlzRnVuY3Rpb247XG4gICAgbG9kYXNoLmlzSW50ZWdlciA9IGlzSW50ZWdlcjtcbiAgICBsb2Rhc2guaXNMZW5ndGggPSBpc0xlbmd0aDtcbiAgICBsb2Rhc2guaXNNYXAgPSBpc01hcDtcbiAgICBsb2Rhc2guaXNNYXRjaCA9IGlzTWF0Y2g7XG4gICAgbG9kYXNoLmlzTWF0Y2hXaXRoID0gaXNNYXRjaFdpdGg7XG4gICAgbG9kYXNoLmlzTmFOID0gaXNOYU47XG4gICAgbG9kYXNoLmlzTmF0aXZlID0gaXNOYXRpdmU7XG4gICAgbG9kYXNoLmlzTmlsID0gaXNOaWw7XG4gICAgbG9kYXNoLmlzTnVsbCA9IGlzTnVsbDtcbiAgICBsb2Rhc2guaXNOdW1iZXIgPSBpc051bWJlcjtcbiAgICBsb2Rhc2guaXNPYmplY3QgPSBpc09iamVjdDtcbiAgICBsb2Rhc2guaXNPYmplY3RMaWtlID0gaXNPYmplY3RMaWtlO1xuICAgIGxvZGFzaC5pc1BsYWluT2JqZWN0ID0gaXNQbGFpbk9iamVjdDtcbiAgICBsb2Rhc2guaXNSZWdFeHAgPSBpc1JlZ0V4cDtcbiAgICBsb2Rhc2guaXNTYWZlSW50ZWdlciA9IGlzU2FmZUludGVnZXI7XG4gICAgbG9kYXNoLmlzU2V0ID0gaXNTZXQ7XG4gICAgbG9kYXNoLmlzU3RyaW5nID0gaXNTdHJpbmc7XG4gICAgbG9kYXNoLmlzU3ltYm9sID0gaXNTeW1ib2w7XG4gICAgbG9kYXNoLmlzVHlwZWRBcnJheSA9IGlzVHlwZWRBcnJheTtcbiAgICBsb2Rhc2guaXNVbmRlZmluZWQgPSBpc1VuZGVmaW5lZDtcbiAgICBsb2Rhc2guaXNXZWFrTWFwID0gaXNXZWFrTWFwO1xuICAgIGxvZGFzaC5pc1dlYWtTZXQgPSBpc1dlYWtTZXQ7XG4gICAgbG9kYXNoLmpvaW4gPSBqb2luO1xuICAgIGxvZGFzaC5rZWJhYkNhc2UgPSBrZWJhYkNhc2U7XG4gICAgbG9kYXNoLmxhc3QgPSBsYXN0O1xuICAgIGxvZGFzaC5sYXN0SW5kZXhPZiA9IGxhc3RJbmRleE9mO1xuICAgIGxvZGFzaC5sb3dlckNhc2UgPSBsb3dlckNhc2U7XG4gICAgbG9kYXNoLmxvd2VyRmlyc3QgPSBsb3dlckZpcnN0O1xuICAgIGxvZGFzaC5sdCA9IGx0O1xuICAgIGxvZGFzaC5sdGUgPSBsdGU7XG4gICAgbG9kYXNoLm1heCA9IG1heDtcbiAgICBsb2Rhc2gubWF4QnkgPSBtYXhCeTtcbiAgICBsb2Rhc2gubWVhbiA9IG1lYW47XG4gICAgbG9kYXNoLm1lYW5CeSA9IG1lYW5CeTtcbiAgICBsb2Rhc2gubWluID0gbWluO1xuICAgIGxvZGFzaC5taW5CeSA9IG1pbkJ5O1xuICAgIGxvZGFzaC5zdHViQXJyYXkgPSBzdHViQXJyYXk7XG4gICAgbG9kYXNoLnN0dWJGYWxzZSA9IHN0dWJGYWxzZTtcbiAgICBsb2Rhc2guc3R1Yk9iamVjdCA9IHN0dWJPYmplY3Q7XG4gICAgbG9kYXNoLnN0dWJTdHJpbmcgPSBzdHViU3RyaW5nO1xuICAgIGxvZGFzaC5zdHViVHJ1ZSA9IHN0dWJUcnVlO1xuICAgIGxvZGFzaC5tdWx0aXBseSA9IG11bHRpcGx5O1xuICAgIGxvZGFzaC5udGggPSBudGg7XG4gICAgbG9kYXNoLm5vQ29uZmxpY3QgPSBub0NvbmZsaWN0O1xuICAgIGxvZGFzaC5ub29wID0gbm9vcDtcbiAgICBsb2Rhc2gubm93ID0gbm93O1xuICAgIGxvZGFzaC5wYWQgPSBwYWQ7XG4gICAgbG9kYXNoLnBhZEVuZCA9IHBhZEVuZDtcbiAgICBsb2Rhc2gucGFkU3RhcnQgPSBwYWRTdGFydDtcbiAgICBsb2Rhc2gucGFyc2VJbnQgPSBwYXJzZUludDtcbiAgICBsb2Rhc2gucmFuZG9tID0gcmFuZG9tO1xuICAgIGxvZGFzaC5yZWR1Y2UgPSByZWR1Y2U7XG4gICAgbG9kYXNoLnJlZHVjZVJpZ2h0ID0gcmVkdWNlUmlnaHQ7XG4gICAgbG9kYXNoLnJlcGVhdCA9IHJlcGVhdDtcbiAgICBsb2Rhc2gucmVwbGFjZSA9IHJlcGxhY2U7XG4gICAgbG9kYXNoLnJlc3VsdCA9IHJlc3VsdDtcbiAgICBsb2Rhc2gucm91bmQgPSByb3VuZDtcbiAgICBsb2Rhc2gucnVuSW5Db250ZXh0ID0gcnVuSW5Db250ZXh0O1xuICAgIGxvZGFzaC5zYW1wbGUgPSBzYW1wbGU7XG4gICAgbG9kYXNoLnNpemUgPSBzaXplO1xuICAgIGxvZGFzaC5zbmFrZUNhc2UgPSBzbmFrZUNhc2U7XG4gICAgbG9kYXNoLnNvbWUgPSBzb21lO1xuICAgIGxvZGFzaC5zb3J0ZWRJbmRleCA9IHNvcnRlZEluZGV4O1xuICAgIGxvZGFzaC5zb3J0ZWRJbmRleEJ5ID0gc29ydGVkSW5kZXhCeTtcbiAgICBsb2Rhc2guc29ydGVkSW5kZXhPZiA9IHNvcnRlZEluZGV4T2Y7XG4gICAgbG9kYXNoLnNvcnRlZExhc3RJbmRleCA9IHNvcnRlZExhc3RJbmRleDtcbiAgICBsb2Rhc2guc29ydGVkTGFzdEluZGV4QnkgPSBzb3J0ZWRMYXN0SW5kZXhCeTtcbiAgICBsb2Rhc2guc29ydGVkTGFzdEluZGV4T2YgPSBzb3J0ZWRMYXN0SW5kZXhPZjtcbiAgICBsb2Rhc2guc3RhcnRDYXNlID0gc3RhcnRDYXNlO1xuICAgIGxvZGFzaC5zdGFydHNXaXRoID0gc3RhcnRzV2l0aDtcbiAgICBsb2Rhc2guc3VidHJhY3QgPSBzdWJ0cmFjdDtcbiAgICBsb2Rhc2guc3VtID0gc3VtO1xuICAgIGxvZGFzaC5zdW1CeSA9IHN1bUJ5O1xuICAgIGxvZGFzaC50ZW1wbGF0ZSA9IHRlbXBsYXRlO1xuICAgIGxvZGFzaC50aW1lcyA9IHRpbWVzO1xuICAgIGxvZGFzaC50b0Zpbml0ZSA9IHRvRmluaXRlO1xuICAgIGxvZGFzaC50b0ludGVnZXIgPSB0b0ludGVnZXI7XG4gICAgbG9kYXNoLnRvTGVuZ3RoID0gdG9MZW5ndGg7XG4gICAgbG9kYXNoLnRvTG93ZXIgPSB0b0xvd2VyO1xuICAgIGxvZGFzaC50b051bWJlciA9IHRvTnVtYmVyO1xuICAgIGxvZGFzaC50b1NhZmVJbnRlZ2VyID0gdG9TYWZlSW50ZWdlcjtcbiAgICBsb2Rhc2gudG9TdHJpbmcgPSB0b1N0cmluZztcbiAgICBsb2Rhc2gudG9VcHBlciA9IHRvVXBwZXI7XG4gICAgbG9kYXNoLnRyaW0gPSB0cmltO1xuICAgIGxvZGFzaC50cmltRW5kID0gdHJpbUVuZDtcbiAgICBsb2Rhc2gudHJpbVN0YXJ0ID0gdHJpbVN0YXJ0O1xuICAgIGxvZGFzaC50cnVuY2F0ZSA9IHRydW5jYXRlO1xuICAgIGxvZGFzaC51bmVzY2FwZSA9IHVuZXNjYXBlO1xuICAgIGxvZGFzaC51bmlxdWVJZCA9IHVuaXF1ZUlkO1xuICAgIGxvZGFzaC51cHBlckNhc2UgPSB1cHBlckNhc2U7XG4gICAgbG9kYXNoLnVwcGVyRmlyc3QgPSB1cHBlckZpcnN0O1xuXG4gICAgLy8gQWRkIGFsaWFzZXMuXG4gICAgbG9kYXNoLmVhY2ggPSBmb3JFYWNoO1xuICAgIGxvZGFzaC5lYWNoUmlnaHQgPSBmb3JFYWNoUmlnaHQ7XG4gICAgbG9kYXNoLmZpcnN0ID0gaGVhZDtcblxuICAgIG1peGluKGxvZGFzaCwgKGZ1bmN0aW9uKCkge1xuICAgICAgdmFyIHNvdXJjZSA9IHt9O1xuICAgICAgYmFzZUZvck93bihsb2Rhc2gsIGZ1bmN0aW9uKGZ1bmMsIG1ldGhvZE5hbWUpIHtcbiAgICAgICAgaWYgKCFoYXNPd25Qcm9wZXJ0eS5jYWxsKGxvZGFzaC5wcm90b3R5cGUsIG1ldGhvZE5hbWUpKSB7XG4gICAgICAgICAgc291cmNlW21ldGhvZE5hbWVdID0gZnVuYztcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgICByZXR1cm4gc291cmNlO1xuICAgIH0oKSksIHsgJ2NoYWluJzogZmFsc2UgfSk7XG5cbiAgICAvKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovXG5cbiAgICAvKipcbiAgICAgKiBUaGUgc2VtYW50aWMgdmVyc2lvbiBudW1iZXIuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAdHlwZSB7c3RyaW5nfVxuICAgICAqL1xuICAgIGxvZGFzaC5WRVJTSU9OID0gVkVSU0lPTjtcblxuICAgIC8vIEFzc2lnbiBkZWZhdWx0IHBsYWNlaG9sZGVycy5cbiAgICBhcnJheUVhY2goWydiaW5kJywgJ2JpbmRLZXknLCAnY3VycnknLCAnY3VycnlSaWdodCcsICdwYXJ0aWFsJywgJ3BhcnRpYWxSaWdodCddLCBmdW5jdGlvbihtZXRob2ROYW1lKSB7XG4gICAgICBsb2Rhc2hbbWV0aG9kTmFtZV0ucGxhY2Vob2xkZXIgPSBsb2Rhc2g7XG4gICAgfSk7XG5cbiAgICAvLyBBZGQgYExhenlXcmFwcGVyYCBtZXRob2RzIGZvciBgXy5kcm9wYCBhbmQgYF8udGFrZWAgdmFyaWFudHMuXG4gICAgYXJyYXlFYWNoKFsnZHJvcCcsICd0YWtlJ10sIGZ1bmN0aW9uKG1ldGhvZE5hbWUsIGluZGV4KSB7XG4gICAgICBMYXp5V3JhcHBlci5wcm90b3R5cGVbbWV0aG9kTmFtZV0gPSBmdW5jdGlvbihuKSB7XG4gICAgICAgIG4gPSBuID09PSB1bmRlZmluZWQgPyAxIDogbmF0aXZlTWF4KHRvSW50ZWdlcihuKSwgMCk7XG5cbiAgICAgICAgdmFyIHJlc3VsdCA9ICh0aGlzLl9fZmlsdGVyZWRfXyAmJiAhaW5kZXgpXG4gICAgICAgICAgPyBuZXcgTGF6eVdyYXBwZXIodGhpcylcbiAgICAgICAgICA6IHRoaXMuY2xvbmUoKTtcblxuICAgICAgICBpZiAocmVzdWx0Ll9fZmlsdGVyZWRfXykge1xuICAgICAgICAgIHJlc3VsdC5fX3Rha2VDb3VudF9fID0gbmF0aXZlTWluKG4sIHJlc3VsdC5fX3Rha2VDb3VudF9fKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICByZXN1bHQuX192aWV3c19fLnB1c2goe1xuICAgICAgICAgICAgJ3NpemUnOiBuYXRpdmVNaW4obiwgTUFYX0FSUkFZX0xFTkdUSCksXG4gICAgICAgICAgICAndHlwZSc6IG1ldGhvZE5hbWUgKyAocmVzdWx0Ll9fZGlyX18gPCAwID8gJ1JpZ2h0JyA6ICcnKVxuICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgICB9O1xuXG4gICAgICBMYXp5V3JhcHBlci5wcm90b3R5cGVbbWV0aG9kTmFtZSArICdSaWdodCddID0gZnVuY3Rpb24obikge1xuICAgICAgICByZXR1cm4gdGhpcy5yZXZlcnNlKClbbWV0aG9kTmFtZV0obikucmV2ZXJzZSgpO1xuICAgICAgfTtcbiAgICB9KTtcblxuICAgIC8vIEFkZCBgTGF6eVdyYXBwZXJgIG1ldGhvZHMgdGhhdCBhY2NlcHQgYW4gYGl0ZXJhdGVlYCB2YWx1ZS5cbiAgICBhcnJheUVhY2goWydmaWx0ZXInLCAnbWFwJywgJ3Rha2VXaGlsZSddLCBmdW5jdGlvbihtZXRob2ROYW1lLCBpbmRleCkge1xuICAgICAgdmFyIHR5cGUgPSBpbmRleCArIDEsXG4gICAgICAgICAgaXNGaWx0ZXIgPSB0eXBlID09IExBWllfRklMVEVSX0ZMQUcgfHwgdHlwZSA9PSBMQVpZX1dISUxFX0ZMQUc7XG5cbiAgICAgIExhenlXcmFwcGVyLnByb3RvdHlwZVttZXRob2ROYW1lXSA9IGZ1bmN0aW9uKGl0ZXJhdGVlKSB7XG4gICAgICAgIHZhciByZXN1bHQgPSB0aGlzLmNsb25lKCk7XG4gICAgICAgIHJlc3VsdC5fX2l0ZXJhdGVlc19fLnB1c2goe1xuICAgICAgICAgICdpdGVyYXRlZSc6IGdldEl0ZXJhdGVlKGl0ZXJhdGVlLCAzKSxcbiAgICAgICAgICAndHlwZSc6IHR5cGVcbiAgICAgICAgfSk7XG4gICAgICAgIHJlc3VsdC5fX2ZpbHRlcmVkX18gPSByZXN1bHQuX19maWx0ZXJlZF9fIHx8IGlzRmlsdGVyO1xuICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgICAgfTtcbiAgICB9KTtcblxuICAgIC8vIEFkZCBgTGF6eVdyYXBwZXJgIG1ldGhvZHMgZm9yIGBfLmhlYWRgIGFuZCBgXy5sYXN0YC5cbiAgICBhcnJheUVhY2goWydoZWFkJywgJ2xhc3QnXSwgZnVuY3Rpb24obWV0aG9kTmFtZSwgaW5kZXgpIHtcbiAgICAgIHZhciB0YWtlTmFtZSA9ICd0YWtlJyArIChpbmRleCA/ICdSaWdodCcgOiAnJyk7XG5cbiAgICAgIExhenlXcmFwcGVyLnByb3RvdHlwZVttZXRob2ROYW1lXSA9IGZ1bmN0aW9uKCkge1xuICAgICAgICByZXR1cm4gdGhpc1t0YWtlTmFtZV0oMSkudmFsdWUoKVswXTtcbiAgICAgIH07XG4gICAgfSk7XG5cbiAgICAvLyBBZGQgYExhenlXcmFwcGVyYCBtZXRob2RzIGZvciBgXy5pbml0aWFsYCBhbmQgYF8udGFpbGAuXG4gICAgYXJyYXlFYWNoKFsnaW5pdGlhbCcsICd0YWlsJ10sIGZ1bmN0aW9uKG1ldGhvZE5hbWUsIGluZGV4KSB7XG4gICAgICB2YXIgZHJvcE5hbWUgPSAnZHJvcCcgKyAoaW5kZXggPyAnJyA6ICdSaWdodCcpO1xuXG4gICAgICBMYXp5V3JhcHBlci5wcm90b3R5cGVbbWV0aG9kTmFtZV0gPSBmdW5jdGlvbigpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX19maWx0ZXJlZF9fID8gbmV3IExhenlXcmFwcGVyKHRoaXMpIDogdGhpc1tkcm9wTmFtZV0oMSk7XG4gICAgICB9O1xuICAgIH0pO1xuXG4gICAgTGF6eVdyYXBwZXIucHJvdG90eXBlLmNvbXBhY3QgPSBmdW5jdGlvbigpIHtcbiAgICAgIHJldHVybiB0aGlzLmZpbHRlcihpZGVudGl0eSk7XG4gICAgfTtcblxuICAgIExhenlXcmFwcGVyLnByb3RvdHlwZS5maW5kID0gZnVuY3Rpb24ocHJlZGljYXRlKSB7XG4gICAgICByZXR1cm4gdGhpcy5maWx0ZXIocHJlZGljYXRlKS5oZWFkKCk7XG4gICAgfTtcblxuICAgIExhenlXcmFwcGVyLnByb3RvdHlwZS5maW5kTGFzdCA9IGZ1bmN0aW9uKHByZWRpY2F0ZSkge1xuICAgICAgcmV0dXJuIHRoaXMucmV2ZXJzZSgpLmZpbmQocHJlZGljYXRlKTtcbiAgICB9O1xuXG4gICAgTGF6eVdyYXBwZXIucHJvdG90eXBlLmludm9rZU1hcCA9IGJhc2VSZXN0KGZ1bmN0aW9uKHBhdGgsIGFyZ3MpIHtcbiAgICAgIGlmICh0eXBlb2YgcGF0aCA9PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgIHJldHVybiBuZXcgTGF6eVdyYXBwZXIodGhpcyk7XG4gICAgICB9XG4gICAgICByZXR1cm4gdGhpcy5tYXAoZnVuY3Rpb24odmFsdWUpIHtcbiAgICAgICAgcmV0dXJuIGJhc2VJbnZva2UodmFsdWUsIHBhdGgsIGFyZ3MpO1xuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICBMYXp5V3JhcHBlci5wcm90b3R5cGUucmVqZWN0ID0gZnVuY3Rpb24ocHJlZGljYXRlKSB7XG4gICAgICByZXR1cm4gdGhpcy5maWx0ZXIobmVnYXRlKGdldEl0ZXJhdGVlKHByZWRpY2F0ZSkpKTtcbiAgICB9O1xuXG4gICAgTGF6eVdyYXBwZXIucHJvdG90eXBlLnNsaWNlID0gZnVuY3Rpb24oc3RhcnQsIGVuZCkge1xuICAgICAgc3RhcnQgPSB0b0ludGVnZXIoc3RhcnQpO1xuXG4gICAgICB2YXIgcmVzdWx0ID0gdGhpcztcbiAgICAgIGlmIChyZXN1bHQuX19maWx0ZXJlZF9fICYmIChzdGFydCA+IDAgfHwgZW5kIDwgMCkpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBMYXp5V3JhcHBlcihyZXN1bHQpO1xuICAgICAgfVxuICAgICAgaWYgKHN0YXJ0IDwgMCkge1xuICAgICAgICByZXN1bHQgPSByZXN1bHQudGFrZVJpZ2h0KC1zdGFydCk7XG4gICAgICB9IGVsc2UgaWYgKHN0YXJ0KSB7XG4gICAgICAgIHJlc3VsdCA9IHJlc3VsdC5kcm9wKHN0YXJ0KTtcbiAgICAgIH1cbiAgICAgIGlmIChlbmQgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICBlbmQgPSB0b0ludGVnZXIoZW5kKTtcbiAgICAgICAgcmVzdWx0ID0gZW5kIDwgMCA/IHJlc3VsdC5kcm9wUmlnaHQoLWVuZCkgOiByZXN1bHQudGFrZShlbmQgLSBzdGFydCk7XG4gICAgICB9XG4gICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH07XG5cbiAgICBMYXp5V3JhcHBlci5wcm90b3R5cGUudGFrZVJpZ2h0V2hpbGUgPSBmdW5jdGlvbihwcmVkaWNhdGUpIHtcbiAgICAgIHJldHVybiB0aGlzLnJldmVyc2UoKS50YWtlV2hpbGUocHJlZGljYXRlKS5yZXZlcnNlKCk7XG4gICAgfTtcblxuICAgIExhenlXcmFwcGVyLnByb3RvdHlwZS50b0FycmF5ID0gZnVuY3Rpb24oKSB7XG4gICAgICByZXR1cm4gdGhpcy50YWtlKE1BWF9BUlJBWV9MRU5HVEgpO1xuICAgIH07XG5cbiAgICAvLyBBZGQgYExhenlXcmFwcGVyYCBtZXRob2RzIHRvIGBsb2Rhc2gucHJvdG90eXBlYC5cbiAgICBiYXNlRm9yT3duKExhenlXcmFwcGVyLnByb3RvdHlwZSwgZnVuY3Rpb24oZnVuYywgbWV0aG9kTmFtZSkge1xuICAgICAgdmFyIGNoZWNrSXRlcmF0ZWUgPSAvXig/OmZpbHRlcnxmaW5kfG1hcHxyZWplY3QpfFdoaWxlJC8udGVzdChtZXRob2ROYW1lKSxcbiAgICAgICAgICBpc1Rha2VyID0gL14oPzpoZWFkfGxhc3QpJC8udGVzdChtZXRob2ROYW1lKSxcbiAgICAgICAgICBsb2Rhc2hGdW5jID0gbG9kYXNoW2lzVGFrZXIgPyAoJ3Rha2UnICsgKG1ldGhvZE5hbWUgPT0gJ2xhc3QnID8gJ1JpZ2h0JyA6ICcnKSkgOiBtZXRob2ROYW1lXSxcbiAgICAgICAgICByZXRVbndyYXBwZWQgPSBpc1Rha2VyIHx8IC9eZmluZC8udGVzdChtZXRob2ROYW1lKTtcblxuICAgICAgaWYgKCFsb2Rhc2hGdW5jKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIGxvZGFzaC5wcm90b3R5cGVbbWV0aG9kTmFtZV0gPSBmdW5jdGlvbigpIHtcbiAgICAgICAgdmFyIHZhbHVlID0gdGhpcy5fX3dyYXBwZWRfXyxcbiAgICAgICAgICAgIGFyZ3MgPSBpc1Rha2VyID8gWzFdIDogYXJndW1lbnRzLFxuICAgICAgICAgICAgaXNMYXp5ID0gdmFsdWUgaW5zdGFuY2VvZiBMYXp5V3JhcHBlcixcbiAgICAgICAgICAgIGl0ZXJhdGVlID0gYXJnc1swXSxcbiAgICAgICAgICAgIHVzZUxhenkgPSBpc0xhenkgfHwgaXNBcnJheSh2YWx1ZSk7XG5cbiAgICAgICAgdmFyIGludGVyY2VwdG9yID0gZnVuY3Rpb24odmFsdWUpIHtcbiAgICAgICAgICB2YXIgcmVzdWx0ID0gbG9kYXNoRnVuYy5hcHBseShsb2Rhc2gsIGFycmF5UHVzaChbdmFsdWVdLCBhcmdzKSk7XG4gICAgICAgICAgcmV0dXJuIChpc1Rha2VyICYmIGNoYWluQWxsKSA/IHJlc3VsdFswXSA6IHJlc3VsdDtcbiAgICAgICAgfTtcblxuICAgICAgICBpZiAodXNlTGF6eSAmJiBjaGVja0l0ZXJhdGVlICYmIHR5cGVvZiBpdGVyYXRlZSA9PSAnZnVuY3Rpb24nICYmIGl0ZXJhdGVlLmxlbmd0aCAhPSAxKSB7XG4gICAgICAgICAgLy8gQXZvaWQgbGF6eSB1c2UgaWYgdGhlIGl0ZXJhdGVlIGhhcyBhIFwibGVuZ3RoXCIgdmFsdWUgb3RoZXIgdGhhbiBgMWAuXG4gICAgICAgICAgaXNMYXp5ID0gdXNlTGF6eSA9IGZhbHNlO1xuICAgICAgICB9XG4gICAgICAgIHZhciBjaGFpbkFsbCA9IHRoaXMuX19jaGFpbl9fLFxuICAgICAgICAgICAgaXNIeWJyaWQgPSAhIXRoaXMuX19hY3Rpb25zX18ubGVuZ3RoLFxuICAgICAgICAgICAgaXNVbndyYXBwZWQgPSByZXRVbndyYXBwZWQgJiYgIWNoYWluQWxsLFxuICAgICAgICAgICAgb25seUxhenkgPSBpc0xhenkgJiYgIWlzSHlicmlkO1xuXG4gICAgICAgIGlmICghcmV0VW53cmFwcGVkICYmIHVzZUxhenkpIHtcbiAgICAgICAgICB2YWx1ZSA9IG9ubHlMYXp5ID8gdmFsdWUgOiBuZXcgTGF6eVdyYXBwZXIodGhpcyk7XG4gICAgICAgICAgdmFyIHJlc3VsdCA9IGZ1bmMuYXBwbHkodmFsdWUsIGFyZ3MpO1xuICAgICAgICAgIHJlc3VsdC5fX2FjdGlvbnNfXy5wdXNoKHsgJ2Z1bmMnOiB0aHJ1LCAnYXJncyc6IFtpbnRlcmNlcHRvcl0sICd0aGlzQXJnJzogdW5kZWZpbmVkIH0pO1xuICAgICAgICAgIHJldHVybiBuZXcgTG9kYXNoV3JhcHBlcihyZXN1bHQsIGNoYWluQWxsKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoaXNVbndyYXBwZWQgJiYgb25seUxhenkpIHtcbiAgICAgICAgICByZXR1cm4gZnVuYy5hcHBseSh0aGlzLCBhcmdzKTtcbiAgICAgICAgfVxuICAgICAgICByZXN1bHQgPSB0aGlzLnRocnUoaW50ZXJjZXB0b3IpO1xuICAgICAgICByZXR1cm4gaXNVbndyYXBwZWQgPyAoaXNUYWtlciA/IHJlc3VsdC52YWx1ZSgpWzBdIDogcmVzdWx0LnZhbHVlKCkpIDogcmVzdWx0O1xuICAgICAgfTtcbiAgICB9KTtcblxuICAgIC8vIEFkZCBgQXJyYXlgIG1ldGhvZHMgdG8gYGxvZGFzaC5wcm90b3R5cGVgLlxuICAgIGFycmF5RWFjaChbJ3BvcCcsICdwdXNoJywgJ3NoaWZ0JywgJ3NvcnQnLCAnc3BsaWNlJywgJ3Vuc2hpZnQnXSwgZnVuY3Rpb24obWV0aG9kTmFtZSkge1xuICAgICAgdmFyIGZ1bmMgPSBhcnJheVByb3RvW21ldGhvZE5hbWVdLFxuICAgICAgICAgIGNoYWluTmFtZSA9IC9eKD86cHVzaHxzb3J0fHVuc2hpZnQpJC8udGVzdChtZXRob2ROYW1lKSA/ICd0YXAnIDogJ3RocnUnLFxuICAgICAgICAgIHJldFVud3JhcHBlZCA9IC9eKD86cG9wfHNoaWZ0KSQvLnRlc3QobWV0aG9kTmFtZSk7XG5cbiAgICAgIGxvZGFzaC5wcm90b3R5cGVbbWV0aG9kTmFtZV0gPSBmdW5jdGlvbigpIHtcbiAgICAgICAgdmFyIGFyZ3MgPSBhcmd1bWVudHM7XG4gICAgICAgIGlmIChyZXRVbndyYXBwZWQgJiYgIXRoaXMuX19jaGFpbl9fKSB7XG4gICAgICAgICAgdmFyIHZhbHVlID0gdGhpcy52YWx1ZSgpO1xuICAgICAgICAgIHJldHVybiBmdW5jLmFwcGx5KGlzQXJyYXkodmFsdWUpID8gdmFsdWUgOiBbXSwgYXJncyk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXNbY2hhaW5OYW1lXShmdW5jdGlvbih2YWx1ZSkge1xuICAgICAgICAgIHJldHVybiBmdW5jLmFwcGx5KGlzQXJyYXkodmFsdWUpID8gdmFsdWUgOiBbXSwgYXJncyk7XG4gICAgICAgIH0pO1xuICAgICAgfTtcbiAgICB9KTtcblxuICAgIC8vIE1hcCBtaW5pZmllZCBtZXRob2QgbmFtZXMgdG8gdGhlaXIgcmVhbCBuYW1lcy5cbiAgICBiYXNlRm9yT3duKExhenlXcmFwcGVyLnByb3RvdHlwZSwgZnVuY3Rpb24oZnVuYywgbWV0aG9kTmFtZSkge1xuICAgICAgdmFyIGxvZGFzaEZ1bmMgPSBsb2Rhc2hbbWV0aG9kTmFtZV07XG4gICAgICBpZiAobG9kYXNoRnVuYykge1xuICAgICAgICB2YXIga2V5ID0gKGxvZGFzaEZ1bmMubmFtZSArICcnKSxcbiAgICAgICAgICAgIG5hbWVzID0gcmVhbE5hbWVzW2tleV0gfHwgKHJlYWxOYW1lc1trZXldID0gW10pO1xuXG4gICAgICAgIG5hbWVzLnB1c2goeyAnbmFtZSc6IG1ldGhvZE5hbWUsICdmdW5jJzogbG9kYXNoRnVuYyB9KTtcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIHJlYWxOYW1lc1tjcmVhdGVIeWJyaWQodW5kZWZpbmVkLCBXUkFQX0JJTkRfS0VZX0ZMQUcpLm5hbWVdID0gW3tcbiAgICAgICduYW1lJzogJ3dyYXBwZXInLFxuICAgICAgJ2Z1bmMnOiB1bmRlZmluZWRcbiAgICB9XTtcblxuICAgIC8vIEFkZCBtZXRob2RzIHRvIGBMYXp5V3JhcHBlcmAuXG4gICAgTGF6eVdyYXBwZXIucHJvdG90eXBlLmNsb25lID0gbGF6eUNsb25lO1xuICAgIExhenlXcmFwcGVyLnByb3RvdHlwZS5yZXZlcnNlID0gbGF6eVJldmVyc2U7XG4gICAgTGF6eVdyYXBwZXIucHJvdG90eXBlLnZhbHVlID0gbGF6eVZhbHVlO1xuXG4gICAgLy8gQWRkIGNoYWluIHNlcXVlbmNlIG1ldGhvZHMgdG8gdGhlIGBsb2Rhc2hgIHdyYXBwZXIuXG4gICAgbG9kYXNoLnByb3RvdHlwZS5hdCA9IHdyYXBwZXJBdDtcbiAgICBsb2Rhc2gucHJvdG90eXBlLmNoYWluID0gd3JhcHBlckNoYWluO1xuICAgIGxvZGFzaC5wcm90b3R5cGUuY29tbWl0ID0gd3JhcHBlckNvbW1pdDtcbiAgICBsb2Rhc2gucHJvdG90eXBlLm5leHQgPSB3cmFwcGVyTmV4dDtcbiAgICBsb2Rhc2gucHJvdG90eXBlLnBsYW50ID0gd3JhcHBlclBsYW50O1xuICAgIGxvZGFzaC5wcm90b3R5cGUucmV2ZXJzZSA9IHdyYXBwZXJSZXZlcnNlO1xuICAgIGxvZGFzaC5wcm90b3R5cGUudG9KU09OID0gbG9kYXNoLnByb3RvdHlwZS52YWx1ZU9mID0gbG9kYXNoLnByb3RvdHlwZS52YWx1ZSA9IHdyYXBwZXJWYWx1ZTtcblxuICAgIC8vIEFkZCBsYXp5IGFsaWFzZXMuXG4gICAgbG9kYXNoLnByb3RvdHlwZS5maXJzdCA9IGxvZGFzaC5wcm90b3R5cGUuaGVhZDtcblxuICAgIGlmIChzeW1JdGVyYXRvcikge1xuICAgICAgbG9kYXNoLnByb3RvdHlwZVtzeW1JdGVyYXRvcl0gPSB3cmFwcGVyVG9JdGVyYXRvcjtcbiAgICB9XG4gICAgcmV0dXJuIGxvZGFzaDtcbiAgfSk7XG5cbiAgLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovXG5cbiAgLy8gRXhwb3J0IGxvZGFzaC5cbiAgdmFyIF8gPSBydW5JbkNvbnRleHQoKTtcblxuICAvLyBTb21lIEFNRCBidWlsZCBvcHRpbWl6ZXJzLCBsaWtlIHIuanMsIGNoZWNrIGZvciBjb25kaXRpb24gcGF0dGVybnMgbGlrZTpcbiAgaWYgKHR5cGVvZiBkZWZpbmUgPT0gJ2Z1bmN0aW9uJyAmJiB0eXBlb2YgZGVmaW5lLmFtZCA9PSAnb2JqZWN0JyAmJiBkZWZpbmUuYW1kKSB7XG4gICAgLy8gRXhwb3NlIExvZGFzaCBvbiB0aGUgZ2xvYmFsIG9iamVjdCB0byBwcmV2ZW50IGVycm9ycyB3aGVuIExvZGFzaCBpc1xuICAgIC8vIGxvYWRlZCBieSBhIHNjcmlwdCB0YWcgaW4gdGhlIHByZXNlbmNlIG9mIGFuIEFNRCBsb2FkZXIuXG4gICAgLy8gU2VlIGh0dHA6Ly9yZXF1aXJlanMub3JnL2RvY3MvZXJyb3JzLmh0bWwjbWlzbWF0Y2ggZm9yIG1vcmUgZGV0YWlscy5cbiAgICAvLyBVc2UgYF8ubm9Db25mbGljdGAgdG8gcmVtb3ZlIExvZGFzaCBmcm9tIHRoZSBnbG9iYWwgb2JqZWN0LlxuICAgIHJvb3QuXyA9IF87XG5cbiAgICAvLyBEZWZpbmUgYXMgYW4gYW5vbnltb3VzIG1vZHVsZSBzbywgdGhyb3VnaCBwYXRoIG1hcHBpbmcsIGl0IGNhbiBiZVxuICAgIC8vIHJlZmVyZW5jZWQgYXMgdGhlIFwidW5kZXJzY29yZVwiIG1vZHVsZS5cbiAgICBkZWZpbmUoZnVuY3Rpb24oKSB7XG4gICAgICByZXR1cm4gXztcbiAgICB9KTtcbiAgfVxuICAvLyBDaGVjayBmb3IgYGV4cG9ydHNgIGFmdGVyIGBkZWZpbmVgIGluIGNhc2UgYSBidWlsZCBvcHRpbWl6ZXIgYWRkcyBpdC5cbiAgZWxzZSBpZiAoZnJlZU1vZHVsZSkge1xuICAgIC8vIEV4cG9ydCBmb3IgTm9kZS5qcy5cbiAgICAoZnJlZU1vZHVsZS5leHBvcnRzID0gXykuXyA9IF87XG4gICAgLy8gRXhwb3J0IGZvciBDb21tb25KUyBzdXBwb3J0LlxuICAgIGZyZWVFeHBvcnRzLl8gPSBfO1xuICB9XG4gIGVsc2Uge1xuICAgIC8vIEV4cG9ydCB0byB0aGUgZ2xvYmFsIG9iamVjdC5cbiAgICByb290Ll8gPSBfO1xuICB9XG59LmNhbGwodGhpcykpO1xuXG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gLi9ub2RlX21vZHVsZXMvbG9kYXNoL2xvZGFzaC5qc1xuLy8gbW9kdWxlIGlkID0gOVxuLy8gbW9kdWxlIGNodW5rcyA9IDAiLCJtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKG1vZHVsZSkge1xyXG5cdGlmKCFtb2R1bGUud2VicGFja1BvbHlmaWxsKSB7XHJcblx0XHRtb2R1bGUuZGVwcmVjYXRlID0gZnVuY3Rpb24oKSB7fTtcclxuXHRcdG1vZHVsZS5wYXRocyA9IFtdO1xyXG5cdFx0Ly8gbW9kdWxlLnBhcmVudCA9IHVuZGVmaW5lZCBieSBkZWZhdWx0XHJcblx0XHRpZighbW9kdWxlLmNoaWxkcmVuKSBtb2R1bGUuY2hpbGRyZW4gPSBbXTtcclxuXHRcdE9iamVjdC5kZWZpbmVQcm9wZXJ0eShtb2R1bGUsIFwibG9hZGVkXCIsIHtcclxuXHRcdFx0ZW51bWVyYWJsZTogdHJ1ZSxcclxuXHRcdFx0Z2V0OiBmdW5jdGlvbigpIHtcclxuXHRcdFx0XHRyZXR1cm4gbW9kdWxlLmw7XHJcblx0XHRcdH1cclxuXHRcdH0pO1xyXG5cdFx0T2JqZWN0LmRlZmluZVByb3BlcnR5KG1vZHVsZSwgXCJpZFwiLCB7XHJcblx0XHRcdGVudW1lcmFibGU6IHRydWUsXHJcblx0XHRcdGdldDogZnVuY3Rpb24oKSB7XHJcblx0XHRcdFx0cmV0dXJuIG1vZHVsZS5pO1xyXG5cdFx0XHR9XHJcblx0XHR9KTtcclxuXHRcdG1vZHVsZS53ZWJwYWNrUG9seWZpbGwgPSAxO1xyXG5cdH1cclxuXHRyZXR1cm4gbW9kdWxlO1xyXG59O1xyXG5cblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyAod2VicGFjaykvYnVpbGRpbi9tb2R1bGUuanNcbi8vIG1vZHVsZSBpZCA9IDEwXG4vLyBtb2R1bGUgY2h1bmtzID0gMCIsIi8qICovIFxuXCJmb3JtYXQgZ2xvYmFsXCI7XG5cImRlcHMganF1ZXJ5XCI7XG5cImV4cG9ydHMgJFwiO1xuLyohXG4gKiBCb290c3RyYXAgdjMuMy40IChodHRwOi8vZ2V0Ym9vdHN0cmFwLmNvbSlcbiAqIENvcHlyaWdodCAyMDExLTIwMTUgVHdpdHRlciwgSW5jLlxuICogTGljZW5zZWQgdW5kZXIgTUlUIChodHRwczovL2dpdGh1Yi5jb20vdHdicy9ib290c3RyYXAvYmxvYi9tYXN0ZXIvTElDRU5TRSlcbiAqL1xuXG5pZiAodHlwZW9mIGpRdWVyeSA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgdGhyb3cgbmV3IEVycm9yKCdCb290c3RyYXBcXCdzIEphdmFTY3JpcHQgcmVxdWlyZXMgalF1ZXJ5Jylcbn1cblxuK2Z1bmN0aW9uICgkKSB7XG4gICd1c2Ugc3RyaWN0JztcbiAgdmFyIHZlcnNpb24gPSAkLmZuLmpxdWVyeS5zcGxpdCgnICcpWzBdLnNwbGl0KCcuJylcbiAgaWYgKCh2ZXJzaW9uWzBdIDwgMiAmJiB2ZXJzaW9uWzFdIDwgOSkgfHwgKHZlcnNpb25bMF0gPT0gMSAmJiB2ZXJzaW9uWzFdID09IDkgJiYgdmVyc2lvblsyXSA8IDEpKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdCb290c3RyYXBcXCdzIEphdmFTY3JpcHQgcmVxdWlyZXMgalF1ZXJ5IHZlcnNpb24gMS45LjEgb3IgaGlnaGVyJylcbiAgfVxufShqUXVlcnkpO1xuXG4vKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAqIEJvb3RzdHJhcDogdHJhbnNpdGlvbi5qcyB2My4zLjRcbiAqIGh0dHA6Ly9nZXRib290c3RyYXAuY29tL2phdmFzY3JpcHQvI3RyYW5zaXRpb25zXG4gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAqIENvcHlyaWdodCAyMDExLTIwMTUgVHdpdHRlciwgSW5jLlxuICogTGljZW5zZWQgdW5kZXIgTUlUIChodHRwczovL2dpdGh1Yi5jb20vdHdicy9ib290c3RyYXAvYmxvYi9tYXN0ZXIvTElDRU5TRSlcbiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PSAqL1xuXG5cbitmdW5jdGlvbiAoJCkge1xuICAndXNlIHN0cmljdCc7XG5cbiAgLy8gQ1NTIFRSQU5TSVRJT04gU1VQUE9SVCAoU2hvdXRvdXQ6IGh0dHA6Ly93d3cubW9kZXJuaXpyLmNvbS8pXG4gIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuXG4gIGZ1bmN0aW9uIHRyYW5zaXRpb25FbmQoKSB7XG4gICAgdmFyIGVsID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnYm9vdHN0cmFwJylcblxuICAgIHZhciB0cmFuc0VuZEV2ZW50TmFtZXMgPSB7XG4gICAgICBXZWJraXRUcmFuc2l0aW9uIDogJ3dlYmtpdFRyYW5zaXRpb25FbmQnLFxuICAgICAgTW96VHJhbnNpdGlvbiAgICA6ICd0cmFuc2l0aW9uZW5kJyxcbiAgICAgIE9UcmFuc2l0aW9uICAgICAgOiAnb1RyYW5zaXRpb25FbmQgb3RyYW5zaXRpb25lbmQnLFxuICAgICAgdHJhbnNpdGlvbiAgICAgICA6ICd0cmFuc2l0aW9uZW5kJ1xuICAgIH1cblxuICAgIGZvciAodmFyIG5hbWUgaW4gdHJhbnNFbmRFdmVudE5hbWVzKSB7XG4gICAgICBpZiAoZWwuc3R5bGVbbmFtZV0gIT09IHVuZGVmaW5lZCkge1xuICAgICAgICByZXR1cm4geyBlbmQ6IHRyYW5zRW5kRXZlbnROYW1lc1tuYW1lXSB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIGZhbHNlIC8vIGV4cGxpY2l0IGZvciBpZTggKCAgLl8uKVxuICB9XG5cbiAgLy8gaHR0cDovL2Jsb2cuYWxleG1hY2Nhdy5jb20vY3NzLXRyYW5zaXRpb25zXG4gICQuZm4uZW11bGF0ZVRyYW5zaXRpb25FbmQgPSBmdW5jdGlvbiAoZHVyYXRpb24pIHtcbiAgICB2YXIgY2FsbGVkID0gZmFsc2VcbiAgICB2YXIgJGVsID0gdGhpc1xuICAgICQodGhpcykub25lKCdic1RyYW5zaXRpb25FbmQnLCBmdW5jdGlvbiAoKSB7IGNhbGxlZCA9IHRydWUgfSlcbiAgICB2YXIgY2FsbGJhY2sgPSBmdW5jdGlvbiAoKSB7IGlmICghY2FsbGVkKSAkKCRlbCkudHJpZ2dlcigkLnN1cHBvcnQudHJhbnNpdGlvbi5lbmQpIH1cbiAgICBzZXRUaW1lb3V0KGNhbGxiYWNrLCBkdXJhdGlvbilcbiAgICByZXR1cm4gdGhpc1xuICB9XG5cbiAgJChmdW5jdGlvbiAoKSB7XG4gICAgJC5zdXBwb3J0LnRyYW5zaXRpb24gPSB0cmFuc2l0aW9uRW5kKClcblxuICAgIGlmICghJC5zdXBwb3J0LnRyYW5zaXRpb24pIHJldHVyblxuXG4gICAgJC5ldmVudC5zcGVjaWFsLmJzVHJhbnNpdGlvbkVuZCA9IHtcbiAgICAgIGJpbmRUeXBlOiAkLnN1cHBvcnQudHJhbnNpdGlvbi5lbmQsXG4gICAgICBkZWxlZ2F0ZVR5cGU6ICQuc3VwcG9ydC50cmFuc2l0aW9uLmVuZCxcbiAgICAgIGhhbmRsZTogZnVuY3Rpb24gKGUpIHtcbiAgICAgICAgaWYgKCQoZS50YXJnZXQpLmlzKHRoaXMpKSByZXR1cm4gZS5oYW5kbGVPYmouaGFuZGxlci5hcHBseSh0aGlzLCBhcmd1bWVudHMpXG4gICAgICB9XG4gICAgfVxuICB9KVxuXG59KGpRdWVyeSk7XG5cbi8qID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuICogQm9vdHN0cmFwOiBhbGVydC5qcyB2My4zLjRcbiAqIGh0dHA6Ly9nZXRib290c3RyYXAuY29tL2phdmFzY3JpcHQvI2FsZXJ0c1xuICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4gKiBDb3B5cmlnaHQgMjAxMS0yMDE1IFR3aXR0ZXIsIEluYy5cbiAqIExpY2Vuc2VkIHVuZGVyIE1JVCAoaHR0cHM6Ly9naXRodWIuY29tL3R3YnMvYm9vdHN0cmFwL2Jsb2IvbWFzdGVyL0xJQ0VOU0UpXG4gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0gKi9cblxuXG4rZnVuY3Rpb24gKCQpIHtcbiAgJ3VzZSBzdHJpY3QnO1xuXG4gIC8vIEFMRVJUIENMQVNTIERFRklOSVRJT05cbiAgLy8gPT09PT09PT09PT09PT09PT09PT09PVxuXG4gIHZhciBkaXNtaXNzID0gJ1tkYXRhLWRpc21pc3M9XCJhbGVydFwiXSdcbiAgdmFyIEFsZXJ0ICAgPSBmdW5jdGlvbiAoZWwpIHtcbiAgICAkKGVsKS5vbignY2xpY2snLCBkaXNtaXNzLCB0aGlzLmNsb3NlKVxuICB9XG5cbiAgQWxlcnQuVkVSU0lPTiA9ICczLjMuNCdcblxuICBBbGVydC5UUkFOU0lUSU9OX0RVUkFUSU9OID0gMTUwXG5cbiAgQWxlcnQucHJvdG90eXBlLmNsb3NlID0gZnVuY3Rpb24gKGUpIHtcbiAgICB2YXIgJHRoaXMgICAgPSAkKHRoaXMpXG4gICAgdmFyIHNlbGVjdG9yID0gJHRoaXMuYXR0cignZGF0YS10YXJnZXQnKVxuXG4gICAgaWYgKCFzZWxlY3Rvcikge1xuICAgICAgc2VsZWN0b3IgPSAkdGhpcy5hdHRyKCdocmVmJylcbiAgICAgIHNlbGVjdG9yID0gc2VsZWN0b3IgJiYgc2VsZWN0b3IucmVwbGFjZSgvLiooPz0jW15cXHNdKiQpLywgJycpIC8vIHN0cmlwIGZvciBpZTdcbiAgICB9XG5cbiAgICB2YXIgJHBhcmVudCA9ICQoc2VsZWN0b3IpXG5cbiAgICBpZiAoZSkgZS5wcmV2ZW50RGVmYXVsdCgpXG5cbiAgICBpZiAoISRwYXJlbnQubGVuZ3RoKSB7XG4gICAgICAkcGFyZW50ID0gJHRoaXMuY2xvc2VzdCgnLmFsZXJ0JylcbiAgICB9XG5cbiAgICAkcGFyZW50LnRyaWdnZXIoZSA9ICQuRXZlbnQoJ2Nsb3NlLmJzLmFsZXJ0JykpXG5cbiAgICBpZiAoZS5pc0RlZmF1bHRQcmV2ZW50ZWQoKSkgcmV0dXJuXG5cbiAgICAkcGFyZW50LnJlbW92ZUNsYXNzKCdpbicpXG5cbiAgICBmdW5jdGlvbiByZW1vdmVFbGVtZW50KCkge1xuICAgICAgLy8gZGV0YWNoIGZyb20gcGFyZW50LCBmaXJlIGV2ZW50IHRoZW4gY2xlYW4gdXAgZGF0YVxuICAgICAgJHBhcmVudC5kZXRhY2goKS50cmlnZ2VyKCdjbG9zZWQuYnMuYWxlcnQnKS5yZW1vdmUoKVxuICAgIH1cblxuICAgICQuc3VwcG9ydC50cmFuc2l0aW9uICYmICRwYXJlbnQuaGFzQ2xhc3MoJ2ZhZGUnKSA/XG4gICAgICAkcGFyZW50XG4gICAgICAgIC5vbmUoJ2JzVHJhbnNpdGlvbkVuZCcsIHJlbW92ZUVsZW1lbnQpXG4gICAgICAgIC5lbXVsYXRlVHJhbnNpdGlvbkVuZChBbGVydC5UUkFOU0lUSU9OX0RVUkFUSU9OKSA6XG4gICAgICByZW1vdmVFbGVtZW50KClcbiAgfVxuXG5cbiAgLy8gQUxFUlQgUExVR0lOIERFRklOSVRJT05cbiAgLy8gPT09PT09PT09PT09PT09PT09PT09PT1cblxuICBmdW5jdGlvbiBQbHVnaW4ob3B0aW9uKSB7XG4gICAgcmV0dXJuIHRoaXMuZWFjaChmdW5jdGlvbiAoKSB7XG4gICAgICB2YXIgJHRoaXMgPSAkKHRoaXMpXG4gICAgICB2YXIgZGF0YSAgPSAkdGhpcy5kYXRhKCdicy5hbGVydCcpXG5cbiAgICAgIGlmICghZGF0YSkgJHRoaXMuZGF0YSgnYnMuYWxlcnQnLCAoZGF0YSA9IG5ldyBBbGVydCh0aGlzKSkpXG4gICAgICBpZiAodHlwZW9mIG9wdGlvbiA9PSAnc3RyaW5nJykgZGF0YVtvcHRpb25dLmNhbGwoJHRoaXMpXG4gICAgfSlcbiAgfVxuXG4gIHZhciBvbGQgPSAkLmZuLmFsZXJ0XG5cbiAgJC5mbi5hbGVydCAgICAgICAgICAgICA9IFBsdWdpblxuICAkLmZuLmFsZXJ0LkNvbnN0cnVjdG9yID0gQWxlcnRcblxuXG4gIC8vIEFMRVJUIE5PIENPTkZMSUNUXG4gIC8vID09PT09PT09PT09PT09PT09XG5cbiAgJC5mbi5hbGVydC5ub0NvbmZsaWN0ID0gZnVuY3Rpb24gKCkge1xuICAgICQuZm4uYWxlcnQgPSBvbGRcbiAgICByZXR1cm4gdGhpc1xuICB9XG5cblxuICAvLyBBTEVSVCBEQVRBLUFQSVxuICAvLyA9PT09PT09PT09PT09PVxuXG4gICQoZG9jdW1lbnQpLm9uKCdjbGljay5icy5hbGVydC5kYXRhLWFwaScsIGRpc21pc3MsIEFsZXJ0LnByb3RvdHlwZS5jbG9zZSlcblxufShqUXVlcnkpO1xuXG4vKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAqIEJvb3RzdHJhcDogYnV0dG9uLmpzIHYzLjMuNFxuICogaHR0cDovL2dldGJvb3RzdHJhcC5jb20vamF2YXNjcmlwdC8jYnV0dG9uc1xuICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4gKiBDb3B5cmlnaHQgMjAxMS0yMDE1IFR3aXR0ZXIsIEluYy5cbiAqIExpY2Vuc2VkIHVuZGVyIE1JVCAoaHR0cHM6Ly9naXRodWIuY29tL3R3YnMvYm9vdHN0cmFwL2Jsb2IvbWFzdGVyL0xJQ0VOU0UpXG4gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0gKi9cblxuXG4rZnVuY3Rpb24gKCQpIHtcbiAgJ3VzZSBzdHJpY3QnO1xuXG4gIC8vIEJVVFRPTiBQVUJMSUMgQ0xBU1MgREVGSU5JVElPTlxuICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cblxuICB2YXIgQnV0dG9uID0gZnVuY3Rpb24gKGVsZW1lbnQsIG9wdGlvbnMpIHtcbiAgICB0aGlzLiRlbGVtZW50ICA9ICQoZWxlbWVudClcbiAgICB0aGlzLm9wdGlvbnMgICA9ICQuZXh0ZW5kKHt9LCBCdXR0b24uREVGQVVMVFMsIG9wdGlvbnMpXG4gICAgdGhpcy5pc0xvYWRpbmcgPSBmYWxzZVxuICB9XG5cbiAgQnV0dG9uLlZFUlNJT04gID0gJzMuMy40J1xuXG4gIEJ1dHRvbi5ERUZBVUxUUyA9IHtcbiAgICBsb2FkaW5nVGV4dDogJ2xvYWRpbmcuLi4nXG4gIH1cblxuICBCdXR0b24ucHJvdG90eXBlLnNldFN0YXRlID0gZnVuY3Rpb24gKHN0YXRlKSB7XG4gICAgdmFyIGQgICAgPSAnZGlzYWJsZWQnXG4gICAgdmFyICRlbCAgPSB0aGlzLiRlbGVtZW50XG4gICAgdmFyIHZhbCAgPSAkZWwuaXMoJ2lucHV0JykgPyAndmFsJyA6ICdodG1sJ1xuICAgIHZhciBkYXRhID0gJGVsLmRhdGEoKVxuXG4gICAgc3RhdGUgPSBzdGF0ZSArICdUZXh0J1xuXG4gICAgaWYgKGRhdGEucmVzZXRUZXh0ID09IG51bGwpICRlbC5kYXRhKCdyZXNldFRleHQnLCAkZWxbdmFsXSgpKVxuXG4gICAgLy8gcHVzaCB0byBldmVudCBsb29wIHRvIGFsbG93IGZvcm1zIHRvIHN1Ym1pdFxuICAgIHNldFRpbWVvdXQoJC5wcm94eShmdW5jdGlvbiAoKSB7XG4gICAgICAkZWxbdmFsXShkYXRhW3N0YXRlXSA9PSBudWxsID8gdGhpcy5vcHRpb25zW3N0YXRlXSA6IGRhdGFbc3RhdGVdKVxuXG4gICAgICBpZiAoc3RhdGUgPT0gJ2xvYWRpbmdUZXh0Jykge1xuICAgICAgICB0aGlzLmlzTG9hZGluZyA9IHRydWVcbiAgICAgICAgJGVsLmFkZENsYXNzKGQpLmF0dHIoZCwgZClcbiAgICAgIH0gZWxzZSBpZiAodGhpcy5pc0xvYWRpbmcpIHtcbiAgICAgICAgdGhpcy5pc0xvYWRpbmcgPSBmYWxzZVxuICAgICAgICAkZWwucmVtb3ZlQ2xhc3MoZCkucmVtb3ZlQXR0cihkKVxuICAgICAgfVxuICAgIH0sIHRoaXMpLCAwKVxuICB9XG5cbiAgQnV0dG9uLnByb3RvdHlwZS50b2dnbGUgPSBmdW5jdGlvbiAoKSB7XG4gICAgdmFyIGNoYW5nZWQgPSB0cnVlXG4gICAgdmFyICRwYXJlbnQgPSB0aGlzLiRlbGVtZW50LmNsb3Nlc3QoJ1tkYXRhLXRvZ2dsZT1cImJ1dHRvbnNcIl0nKVxuXG4gICAgaWYgKCRwYXJlbnQubGVuZ3RoKSB7XG4gICAgICB2YXIgJGlucHV0ID0gdGhpcy4kZWxlbWVudC5maW5kKCdpbnB1dCcpXG4gICAgICBpZiAoJGlucHV0LnByb3AoJ3R5cGUnKSA9PSAncmFkaW8nKSB7XG4gICAgICAgIGlmICgkaW5wdXQucHJvcCgnY2hlY2tlZCcpICYmIHRoaXMuJGVsZW1lbnQuaGFzQ2xhc3MoJ2FjdGl2ZScpKSBjaGFuZ2VkID0gZmFsc2VcbiAgICAgICAgZWxzZSAkcGFyZW50LmZpbmQoJy5hY3RpdmUnKS5yZW1vdmVDbGFzcygnYWN0aXZlJylcbiAgICAgIH1cbiAgICAgIGlmIChjaGFuZ2VkKSAkaW5wdXQucHJvcCgnY2hlY2tlZCcsICF0aGlzLiRlbGVtZW50Lmhhc0NsYXNzKCdhY3RpdmUnKSkudHJpZ2dlcignY2hhbmdlJylcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy4kZWxlbWVudC5hdHRyKCdhcmlhLXByZXNzZWQnLCAhdGhpcy4kZWxlbWVudC5oYXNDbGFzcygnYWN0aXZlJykpXG4gICAgfVxuXG4gICAgaWYgKGNoYW5nZWQpIHRoaXMuJGVsZW1lbnQudG9nZ2xlQ2xhc3MoJ2FjdGl2ZScpXG4gIH1cblxuXG4gIC8vIEJVVFRPTiBQTFVHSU4gREVGSU5JVElPTlxuICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT1cblxuICBmdW5jdGlvbiBQbHVnaW4ob3B0aW9uKSB7XG4gICAgcmV0dXJuIHRoaXMuZWFjaChmdW5jdGlvbiAoKSB7XG4gICAgICB2YXIgJHRoaXMgICA9ICQodGhpcylcbiAgICAgIHZhciBkYXRhICAgID0gJHRoaXMuZGF0YSgnYnMuYnV0dG9uJylcbiAgICAgIHZhciBvcHRpb25zID0gdHlwZW9mIG9wdGlvbiA9PSAnb2JqZWN0JyAmJiBvcHRpb25cblxuICAgICAgaWYgKCFkYXRhKSAkdGhpcy5kYXRhKCdicy5idXR0b24nLCAoZGF0YSA9IG5ldyBCdXR0b24odGhpcywgb3B0aW9ucykpKVxuXG4gICAgICBpZiAob3B0aW9uID09ICd0b2dnbGUnKSBkYXRhLnRvZ2dsZSgpXG4gICAgICBlbHNlIGlmIChvcHRpb24pIGRhdGEuc2V0U3RhdGUob3B0aW9uKVxuICAgIH0pXG4gIH1cblxuICB2YXIgb2xkID0gJC5mbi5idXR0b25cblxuICAkLmZuLmJ1dHRvbiAgICAgICAgICAgICA9IFBsdWdpblxuICAkLmZuLmJ1dHRvbi5Db25zdHJ1Y3RvciA9IEJ1dHRvblxuXG5cbiAgLy8gQlVUVE9OIE5PIENPTkZMSUNUXG4gIC8vID09PT09PT09PT09PT09PT09PVxuXG4gICQuZm4uYnV0dG9uLm5vQ29uZmxpY3QgPSBmdW5jdGlvbiAoKSB7XG4gICAgJC5mbi5idXR0b24gPSBvbGRcbiAgICByZXR1cm4gdGhpc1xuICB9XG5cblxuICAvLyBCVVRUT04gREFUQS1BUElcbiAgLy8gPT09PT09PT09PT09PT09XG5cbiAgJChkb2N1bWVudClcbiAgICAub24oJ2NsaWNrLmJzLmJ1dHRvbi5kYXRhLWFwaScsICdbZGF0YS10b2dnbGVePVwiYnV0dG9uXCJdJywgZnVuY3Rpb24gKGUpIHtcbiAgICAgIHZhciAkYnRuID0gJChlLnRhcmdldClcbiAgICAgIGlmICghJGJ0bi5oYXNDbGFzcygnYnRuJykpICRidG4gPSAkYnRuLmNsb3Nlc3QoJy5idG4nKVxuICAgICAgUGx1Z2luLmNhbGwoJGJ0biwgJ3RvZ2dsZScpXG4gICAgICBlLnByZXZlbnREZWZhdWx0KClcbiAgICB9KVxuICAgIC5vbignZm9jdXMuYnMuYnV0dG9uLmRhdGEtYXBpIGJsdXIuYnMuYnV0dG9uLmRhdGEtYXBpJywgJ1tkYXRhLXRvZ2dsZV49XCJidXR0b25cIl0nLCBmdW5jdGlvbiAoZSkge1xuICAgICAgJChlLnRhcmdldCkuY2xvc2VzdCgnLmJ0bicpLnRvZ2dsZUNsYXNzKCdmb2N1cycsIC9eZm9jdXMoaW4pPyQvLnRlc3QoZS50eXBlKSlcbiAgICB9KVxuXG59KGpRdWVyeSk7XG5cbi8qID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuICogQm9vdHN0cmFwOiBjYXJvdXNlbC5qcyB2My4zLjRcbiAqIGh0dHA6Ly9nZXRib290c3RyYXAuY29tL2phdmFzY3JpcHQvI2Nhcm91c2VsXG4gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAqIENvcHlyaWdodCAyMDExLTIwMTUgVHdpdHRlciwgSW5jLlxuICogTGljZW5zZWQgdW5kZXIgTUlUIChodHRwczovL2dpdGh1Yi5jb20vdHdicy9ib290c3RyYXAvYmxvYi9tYXN0ZXIvTElDRU5TRSlcbiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PSAqL1xuXG5cbitmdW5jdGlvbiAoJCkge1xuICAndXNlIHN0cmljdCc7XG5cbiAgLy8gQ0FST1VTRUwgQ0xBU1MgREVGSU5JVElPTlxuICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT09XG5cbiAgdmFyIENhcm91c2VsID0gZnVuY3Rpb24gKGVsZW1lbnQsIG9wdGlvbnMpIHtcbiAgICB0aGlzLiRlbGVtZW50ICAgID0gJChlbGVtZW50KVxuICAgIHRoaXMuJGluZGljYXRvcnMgPSB0aGlzLiRlbGVtZW50LmZpbmQoJy5jYXJvdXNlbC1pbmRpY2F0b3JzJylcbiAgICB0aGlzLm9wdGlvbnMgICAgID0gb3B0aW9uc1xuICAgIHRoaXMucGF1c2VkICAgICAgPSBudWxsXG4gICAgdGhpcy5zbGlkaW5nICAgICA9IG51bGxcbiAgICB0aGlzLmludGVydmFsICAgID0gbnVsbFxuICAgIHRoaXMuJGFjdGl2ZSAgICAgPSBudWxsXG4gICAgdGhpcy4kaXRlbXMgICAgICA9IG51bGxcblxuICAgIHRoaXMub3B0aW9ucy5rZXlib2FyZCAmJiB0aGlzLiRlbGVtZW50Lm9uKCdrZXlkb3duLmJzLmNhcm91c2VsJywgJC5wcm94eSh0aGlzLmtleWRvd24sIHRoaXMpKVxuXG4gICAgdGhpcy5vcHRpb25zLnBhdXNlID09ICdob3ZlcicgJiYgISgnb250b3VjaHN0YXJ0JyBpbiBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQpICYmIHRoaXMuJGVsZW1lbnRcbiAgICAgIC5vbignbW91c2VlbnRlci5icy5jYXJvdXNlbCcsICQucHJveHkodGhpcy5wYXVzZSwgdGhpcykpXG4gICAgICAub24oJ21vdXNlbGVhdmUuYnMuY2Fyb3VzZWwnLCAkLnByb3h5KHRoaXMuY3ljbGUsIHRoaXMpKVxuICB9XG5cbiAgQ2Fyb3VzZWwuVkVSU0lPTiAgPSAnMy4zLjQnXG5cbiAgQ2Fyb3VzZWwuVFJBTlNJVElPTl9EVVJBVElPTiA9IDYwMFxuXG4gIENhcm91c2VsLkRFRkFVTFRTID0ge1xuICAgIGludGVydmFsOiA1MDAwLFxuICAgIHBhdXNlOiAnaG92ZXInLFxuICAgIHdyYXA6IHRydWUsXG4gICAga2V5Ym9hcmQ6IHRydWVcbiAgfVxuXG4gIENhcm91c2VsLnByb3RvdHlwZS5rZXlkb3duID0gZnVuY3Rpb24gKGUpIHtcbiAgICBpZiAoL2lucHV0fHRleHRhcmVhL2kudGVzdChlLnRhcmdldC50YWdOYW1lKSkgcmV0dXJuXG4gICAgc3dpdGNoIChlLndoaWNoKSB7XG4gICAgICBjYXNlIDM3OiB0aGlzLnByZXYoKTsgYnJlYWtcbiAgICAgIGNhc2UgMzk6IHRoaXMubmV4dCgpOyBicmVha1xuICAgICAgZGVmYXVsdDogcmV0dXJuXG4gICAgfVxuXG4gICAgZS5wcmV2ZW50RGVmYXVsdCgpXG4gIH1cblxuICBDYXJvdXNlbC5wcm90b3R5cGUuY3ljbGUgPSBmdW5jdGlvbiAoZSkge1xuICAgIGUgfHwgKHRoaXMucGF1c2VkID0gZmFsc2UpXG5cbiAgICB0aGlzLmludGVydmFsICYmIGNsZWFySW50ZXJ2YWwodGhpcy5pbnRlcnZhbClcblxuICAgIHRoaXMub3B0aW9ucy5pbnRlcnZhbFxuICAgICAgJiYgIXRoaXMucGF1c2VkXG4gICAgICAmJiAodGhpcy5pbnRlcnZhbCA9IHNldEludGVydmFsKCQucHJveHkodGhpcy5uZXh0LCB0aGlzKSwgdGhpcy5vcHRpb25zLmludGVydmFsKSlcblxuICAgIHJldHVybiB0aGlzXG4gIH1cblxuICBDYXJvdXNlbC5wcm90b3R5cGUuZ2V0SXRlbUluZGV4ID0gZnVuY3Rpb24gKGl0ZW0pIHtcbiAgICB0aGlzLiRpdGVtcyA9IGl0ZW0ucGFyZW50KCkuY2hpbGRyZW4oJy5pdGVtJylcbiAgICByZXR1cm4gdGhpcy4kaXRlbXMuaW5kZXgoaXRlbSB8fCB0aGlzLiRhY3RpdmUpXG4gIH1cblxuICBDYXJvdXNlbC5wcm90b3R5cGUuZ2V0SXRlbUZvckRpcmVjdGlvbiA9IGZ1bmN0aW9uIChkaXJlY3Rpb24sIGFjdGl2ZSkge1xuICAgIHZhciBhY3RpdmVJbmRleCA9IHRoaXMuZ2V0SXRlbUluZGV4KGFjdGl2ZSlcbiAgICB2YXIgd2lsbFdyYXAgPSAoZGlyZWN0aW9uID09ICdwcmV2JyAmJiBhY3RpdmVJbmRleCA9PT0gMClcbiAgICAgICAgICAgICAgICB8fCAoZGlyZWN0aW9uID09ICduZXh0JyAmJiBhY3RpdmVJbmRleCA9PSAodGhpcy4kaXRlbXMubGVuZ3RoIC0gMSkpXG4gICAgaWYgKHdpbGxXcmFwICYmICF0aGlzLm9wdGlvbnMud3JhcCkgcmV0dXJuIGFjdGl2ZVxuICAgIHZhciBkZWx0YSA9IGRpcmVjdGlvbiA9PSAncHJldicgPyAtMSA6IDFcbiAgICB2YXIgaXRlbUluZGV4ID0gKGFjdGl2ZUluZGV4ICsgZGVsdGEpICUgdGhpcy4kaXRlbXMubGVuZ3RoXG4gICAgcmV0dXJuIHRoaXMuJGl0ZW1zLmVxKGl0ZW1JbmRleClcbiAgfVxuXG4gIENhcm91c2VsLnByb3RvdHlwZS50byA9IGZ1bmN0aW9uIChwb3MpIHtcbiAgICB2YXIgdGhhdCAgICAgICAgPSB0aGlzXG4gICAgdmFyIGFjdGl2ZUluZGV4ID0gdGhpcy5nZXRJdGVtSW5kZXgodGhpcy4kYWN0aXZlID0gdGhpcy4kZWxlbWVudC5maW5kKCcuaXRlbS5hY3RpdmUnKSlcblxuICAgIGlmIChwb3MgPiAodGhpcy4kaXRlbXMubGVuZ3RoIC0gMSkgfHwgcG9zIDwgMCkgcmV0dXJuXG5cbiAgICBpZiAodGhpcy5zbGlkaW5nKSAgICAgICByZXR1cm4gdGhpcy4kZWxlbWVudC5vbmUoJ3NsaWQuYnMuY2Fyb3VzZWwnLCBmdW5jdGlvbiAoKSB7IHRoYXQudG8ocG9zKSB9KSAvLyB5ZXMsIFwic2xpZFwiXG4gICAgaWYgKGFjdGl2ZUluZGV4ID09IHBvcykgcmV0dXJuIHRoaXMucGF1c2UoKS5jeWNsZSgpXG5cbiAgICByZXR1cm4gdGhpcy5zbGlkZShwb3MgPiBhY3RpdmVJbmRleCA/ICduZXh0JyA6ICdwcmV2JywgdGhpcy4kaXRlbXMuZXEocG9zKSlcbiAgfVxuXG4gIENhcm91c2VsLnByb3RvdHlwZS5wYXVzZSA9IGZ1bmN0aW9uIChlKSB7XG4gICAgZSB8fCAodGhpcy5wYXVzZWQgPSB0cnVlKVxuXG4gICAgaWYgKHRoaXMuJGVsZW1lbnQuZmluZCgnLm5leHQsIC5wcmV2JykubGVuZ3RoICYmICQuc3VwcG9ydC50cmFuc2l0aW9uKSB7XG4gICAgICB0aGlzLiRlbGVtZW50LnRyaWdnZXIoJC5zdXBwb3J0LnRyYW5zaXRpb24uZW5kKVxuICAgICAgdGhpcy5jeWNsZSh0cnVlKVxuICAgIH1cblxuICAgIHRoaXMuaW50ZXJ2YWwgPSBjbGVhckludGVydmFsKHRoaXMuaW50ZXJ2YWwpXG5cbiAgICByZXR1cm4gdGhpc1xuICB9XG5cbiAgQ2Fyb3VzZWwucHJvdG90eXBlLm5leHQgPSBmdW5jdGlvbiAoKSB7XG4gICAgaWYgKHRoaXMuc2xpZGluZykgcmV0dXJuXG4gICAgcmV0dXJuIHRoaXMuc2xpZGUoJ25leHQnKVxuICB9XG5cbiAgQ2Fyb3VzZWwucHJvdG90eXBlLnByZXYgPSBmdW5jdGlvbiAoKSB7XG4gICAgaWYgKHRoaXMuc2xpZGluZykgcmV0dXJuXG4gICAgcmV0dXJuIHRoaXMuc2xpZGUoJ3ByZXYnKVxuICB9XG5cbiAgQ2Fyb3VzZWwucHJvdG90eXBlLnNsaWRlID0gZnVuY3Rpb24gKHR5cGUsIG5leHQpIHtcbiAgICB2YXIgJGFjdGl2ZSAgID0gdGhpcy4kZWxlbWVudC5maW5kKCcuaXRlbS5hY3RpdmUnKVxuICAgIHZhciAkbmV4dCAgICAgPSBuZXh0IHx8IHRoaXMuZ2V0SXRlbUZvckRpcmVjdGlvbih0eXBlLCAkYWN0aXZlKVxuICAgIHZhciBpc0N5Y2xpbmcgPSB0aGlzLmludGVydmFsXG4gICAgdmFyIGRpcmVjdGlvbiA9IHR5cGUgPT0gJ25leHQnID8gJ2xlZnQnIDogJ3JpZ2h0J1xuICAgIHZhciB0aGF0ICAgICAgPSB0aGlzXG5cbiAgICBpZiAoJG5leHQuaGFzQ2xhc3MoJ2FjdGl2ZScpKSByZXR1cm4gKHRoaXMuc2xpZGluZyA9IGZhbHNlKVxuXG4gICAgdmFyIHJlbGF0ZWRUYXJnZXQgPSAkbmV4dFswXVxuICAgIHZhciBzbGlkZUV2ZW50ID0gJC5FdmVudCgnc2xpZGUuYnMuY2Fyb3VzZWwnLCB7XG4gICAgICByZWxhdGVkVGFyZ2V0OiByZWxhdGVkVGFyZ2V0LFxuICAgICAgZGlyZWN0aW9uOiBkaXJlY3Rpb25cbiAgICB9KVxuICAgIHRoaXMuJGVsZW1lbnQudHJpZ2dlcihzbGlkZUV2ZW50KVxuICAgIGlmIChzbGlkZUV2ZW50LmlzRGVmYXVsdFByZXZlbnRlZCgpKSByZXR1cm5cblxuICAgIHRoaXMuc2xpZGluZyA9IHRydWVcblxuICAgIGlzQ3ljbGluZyAmJiB0aGlzLnBhdXNlKClcblxuICAgIGlmICh0aGlzLiRpbmRpY2F0b3JzLmxlbmd0aCkge1xuICAgICAgdGhpcy4kaW5kaWNhdG9ycy5maW5kKCcuYWN0aXZlJykucmVtb3ZlQ2xhc3MoJ2FjdGl2ZScpXG4gICAgICB2YXIgJG5leHRJbmRpY2F0b3IgPSAkKHRoaXMuJGluZGljYXRvcnMuY2hpbGRyZW4oKVt0aGlzLmdldEl0ZW1JbmRleCgkbmV4dCldKVxuICAgICAgJG5leHRJbmRpY2F0b3IgJiYgJG5leHRJbmRpY2F0b3IuYWRkQ2xhc3MoJ2FjdGl2ZScpXG4gICAgfVxuXG4gICAgdmFyIHNsaWRFdmVudCA9ICQuRXZlbnQoJ3NsaWQuYnMuY2Fyb3VzZWwnLCB7IHJlbGF0ZWRUYXJnZXQ6IHJlbGF0ZWRUYXJnZXQsIGRpcmVjdGlvbjogZGlyZWN0aW9uIH0pIC8vIHllcywgXCJzbGlkXCJcbiAgICBpZiAoJC5zdXBwb3J0LnRyYW5zaXRpb24gJiYgdGhpcy4kZWxlbWVudC5oYXNDbGFzcygnc2xpZGUnKSkge1xuICAgICAgJG5leHQuYWRkQ2xhc3ModHlwZSlcbiAgICAgICRuZXh0WzBdLm9mZnNldFdpZHRoIC8vIGZvcmNlIHJlZmxvd1xuICAgICAgJGFjdGl2ZS5hZGRDbGFzcyhkaXJlY3Rpb24pXG4gICAgICAkbmV4dC5hZGRDbGFzcyhkaXJlY3Rpb24pXG4gICAgICAkYWN0aXZlXG4gICAgICAgIC5vbmUoJ2JzVHJhbnNpdGlvbkVuZCcsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAkbmV4dC5yZW1vdmVDbGFzcyhbdHlwZSwgZGlyZWN0aW9uXS5qb2luKCcgJykpLmFkZENsYXNzKCdhY3RpdmUnKVxuICAgICAgICAgICRhY3RpdmUucmVtb3ZlQ2xhc3MoWydhY3RpdmUnLCBkaXJlY3Rpb25dLmpvaW4oJyAnKSlcbiAgICAgICAgICB0aGF0LnNsaWRpbmcgPSBmYWxzZVxuICAgICAgICAgIHNldFRpbWVvdXQoZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgdGhhdC4kZWxlbWVudC50cmlnZ2VyKHNsaWRFdmVudClcbiAgICAgICAgICB9LCAwKVxuICAgICAgICB9KVxuICAgICAgICAuZW11bGF0ZVRyYW5zaXRpb25FbmQoQ2Fyb3VzZWwuVFJBTlNJVElPTl9EVVJBVElPTilcbiAgICB9IGVsc2Uge1xuICAgICAgJGFjdGl2ZS5yZW1vdmVDbGFzcygnYWN0aXZlJylcbiAgICAgICRuZXh0LmFkZENsYXNzKCdhY3RpdmUnKVxuICAgICAgdGhpcy5zbGlkaW5nID0gZmFsc2VcbiAgICAgIHRoaXMuJGVsZW1lbnQudHJpZ2dlcihzbGlkRXZlbnQpXG4gICAgfVxuXG4gICAgaXNDeWNsaW5nICYmIHRoaXMuY3ljbGUoKVxuXG4gICAgcmV0dXJuIHRoaXNcbiAgfVxuXG5cbiAgLy8gQ0FST1VTRUwgUExVR0lOIERFRklOSVRJT05cbiAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT1cblxuICBmdW5jdGlvbiBQbHVnaW4ob3B0aW9uKSB7XG4gICAgcmV0dXJuIHRoaXMuZWFjaChmdW5jdGlvbiAoKSB7XG4gICAgICB2YXIgJHRoaXMgICA9ICQodGhpcylcbiAgICAgIHZhciBkYXRhICAgID0gJHRoaXMuZGF0YSgnYnMuY2Fyb3VzZWwnKVxuICAgICAgdmFyIG9wdGlvbnMgPSAkLmV4dGVuZCh7fSwgQ2Fyb3VzZWwuREVGQVVMVFMsICR0aGlzLmRhdGEoKSwgdHlwZW9mIG9wdGlvbiA9PSAnb2JqZWN0JyAmJiBvcHRpb24pXG4gICAgICB2YXIgYWN0aW9uICA9IHR5cGVvZiBvcHRpb24gPT0gJ3N0cmluZycgPyBvcHRpb24gOiBvcHRpb25zLnNsaWRlXG5cbiAgICAgIGlmICghZGF0YSkgJHRoaXMuZGF0YSgnYnMuY2Fyb3VzZWwnLCAoZGF0YSA9IG5ldyBDYXJvdXNlbCh0aGlzLCBvcHRpb25zKSkpXG4gICAgICBpZiAodHlwZW9mIG9wdGlvbiA9PSAnbnVtYmVyJykgZGF0YS50byhvcHRpb24pXG4gICAgICBlbHNlIGlmIChhY3Rpb24pIGRhdGFbYWN0aW9uXSgpXG4gICAgICBlbHNlIGlmIChvcHRpb25zLmludGVydmFsKSBkYXRhLnBhdXNlKCkuY3ljbGUoKVxuICAgIH0pXG4gIH1cblxuICB2YXIgb2xkID0gJC5mbi5jYXJvdXNlbFxuXG4gICQuZm4uY2Fyb3VzZWwgICAgICAgICAgICAgPSBQbHVnaW5cbiAgJC5mbi5jYXJvdXNlbC5Db25zdHJ1Y3RvciA9IENhcm91c2VsXG5cblxuICAvLyBDQVJPVVNFTCBOTyBDT05GTElDVFxuICAvLyA9PT09PT09PT09PT09PT09PT09PVxuXG4gICQuZm4uY2Fyb3VzZWwubm9Db25mbGljdCA9IGZ1bmN0aW9uICgpIHtcbiAgICAkLmZuLmNhcm91c2VsID0gb2xkXG4gICAgcmV0dXJuIHRoaXNcbiAgfVxuXG5cbiAgLy8gQ0FST1VTRUwgREFUQS1BUElcbiAgLy8gPT09PT09PT09PT09PT09PT1cblxuICB2YXIgY2xpY2tIYW5kbGVyID0gZnVuY3Rpb24gKGUpIHtcbiAgICB2YXIgaHJlZlxuICAgIHZhciAkdGhpcyAgID0gJCh0aGlzKVxuICAgIHZhciAkdGFyZ2V0ID0gJCgkdGhpcy5hdHRyKCdkYXRhLXRhcmdldCcpIHx8IChocmVmID0gJHRoaXMuYXR0cignaHJlZicpKSAmJiBocmVmLnJlcGxhY2UoLy4qKD89I1teXFxzXSskKS8sICcnKSkgLy8gc3RyaXAgZm9yIGllN1xuICAgIGlmICghJHRhcmdldC5oYXNDbGFzcygnY2Fyb3VzZWwnKSkgcmV0dXJuXG4gICAgdmFyIG9wdGlvbnMgPSAkLmV4dGVuZCh7fSwgJHRhcmdldC5kYXRhKCksICR0aGlzLmRhdGEoKSlcbiAgICB2YXIgc2xpZGVJbmRleCA9ICR0aGlzLmF0dHIoJ2RhdGEtc2xpZGUtdG8nKVxuICAgIGlmIChzbGlkZUluZGV4KSBvcHRpb25zLmludGVydmFsID0gZmFsc2VcblxuICAgIFBsdWdpbi5jYWxsKCR0YXJnZXQsIG9wdGlvbnMpXG5cbiAgICBpZiAoc2xpZGVJbmRleCkge1xuICAgICAgJHRhcmdldC5kYXRhKCdicy5jYXJvdXNlbCcpLnRvKHNsaWRlSW5kZXgpXG4gICAgfVxuXG4gICAgZS5wcmV2ZW50RGVmYXVsdCgpXG4gIH1cblxuICAkKGRvY3VtZW50KVxuICAgIC5vbignY2xpY2suYnMuY2Fyb3VzZWwuZGF0YS1hcGknLCAnW2RhdGEtc2xpZGVdJywgY2xpY2tIYW5kbGVyKVxuICAgIC5vbignY2xpY2suYnMuY2Fyb3VzZWwuZGF0YS1hcGknLCAnW2RhdGEtc2xpZGUtdG9dJywgY2xpY2tIYW5kbGVyKVxuXG4gICQod2luZG93KS5vbignbG9hZCcsIGZ1bmN0aW9uICgpIHtcbiAgICAkKCdbZGF0YS1yaWRlPVwiY2Fyb3VzZWxcIl0nKS5lYWNoKGZ1bmN0aW9uICgpIHtcbiAgICAgIHZhciAkY2Fyb3VzZWwgPSAkKHRoaXMpXG4gICAgICBQbHVnaW4uY2FsbCgkY2Fyb3VzZWwsICRjYXJvdXNlbC5kYXRhKCkpXG4gICAgfSlcbiAgfSlcblxufShqUXVlcnkpO1xuXG4vKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAqIEJvb3RzdHJhcDogY29sbGFwc2UuanMgdjMuMy40XG4gKiBodHRwOi8vZ2V0Ym9vdHN0cmFwLmNvbS9qYXZhc2NyaXB0LyNjb2xsYXBzZVxuICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4gKiBDb3B5cmlnaHQgMjAxMS0yMDE1IFR3aXR0ZXIsIEluYy5cbiAqIExpY2Vuc2VkIHVuZGVyIE1JVCAoaHR0cHM6Ly9naXRodWIuY29tL3R3YnMvYm9vdHN0cmFwL2Jsb2IvbWFzdGVyL0xJQ0VOU0UpXG4gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0gKi9cblxuXG4rZnVuY3Rpb24gKCQpIHtcbiAgJ3VzZSBzdHJpY3QnO1xuXG4gIC8vIENPTExBUFNFIFBVQkxJQyBDTEFTUyBERUZJTklUSU9OXG4gIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG5cbiAgdmFyIENvbGxhcHNlID0gZnVuY3Rpb24gKGVsZW1lbnQsIG9wdGlvbnMpIHtcbiAgICB0aGlzLiRlbGVtZW50ICAgICAgPSAkKGVsZW1lbnQpXG4gICAgdGhpcy5vcHRpb25zICAgICAgID0gJC5leHRlbmQoe30sIENvbGxhcHNlLkRFRkFVTFRTLCBvcHRpb25zKVxuICAgIHRoaXMuJHRyaWdnZXIgICAgICA9ICQoJ1tkYXRhLXRvZ2dsZT1cImNvbGxhcHNlXCJdW2hyZWY9XCIjJyArIGVsZW1lbnQuaWQgKyAnXCJdLCcgK1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgJ1tkYXRhLXRvZ2dsZT1cImNvbGxhcHNlXCJdW2RhdGEtdGFyZ2V0PVwiIycgKyBlbGVtZW50LmlkICsgJ1wiXScpXG4gICAgdGhpcy50cmFuc2l0aW9uaW5nID0gbnVsbFxuXG4gICAgaWYgKHRoaXMub3B0aW9ucy5wYXJlbnQpIHtcbiAgICAgIHRoaXMuJHBhcmVudCA9IHRoaXMuZ2V0UGFyZW50KClcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5hZGRBcmlhQW5kQ29sbGFwc2VkQ2xhc3ModGhpcy4kZWxlbWVudCwgdGhpcy4kdHJpZ2dlcilcbiAgICB9XG5cbiAgICBpZiAodGhpcy5vcHRpb25zLnRvZ2dsZSkgdGhpcy50b2dnbGUoKVxuICB9XG5cbiAgQ29sbGFwc2UuVkVSU0lPTiAgPSAnMy4zLjQnXG5cbiAgQ29sbGFwc2UuVFJBTlNJVElPTl9EVVJBVElPTiA9IDM1MFxuXG4gIENvbGxhcHNlLkRFRkFVTFRTID0ge1xuICAgIHRvZ2dsZTogdHJ1ZVxuICB9XG5cbiAgQ29sbGFwc2UucHJvdG90eXBlLmRpbWVuc2lvbiA9IGZ1bmN0aW9uICgpIHtcbiAgICB2YXIgaGFzV2lkdGggPSB0aGlzLiRlbGVtZW50Lmhhc0NsYXNzKCd3aWR0aCcpXG4gICAgcmV0dXJuIGhhc1dpZHRoID8gJ3dpZHRoJyA6ICdoZWlnaHQnXG4gIH1cblxuICBDb2xsYXBzZS5wcm90b3R5cGUuc2hvdyA9IGZ1bmN0aW9uICgpIHtcbiAgICBpZiAodGhpcy50cmFuc2l0aW9uaW5nIHx8IHRoaXMuJGVsZW1lbnQuaGFzQ2xhc3MoJ2luJykpIHJldHVyblxuXG4gICAgdmFyIGFjdGl2ZXNEYXRhXG4gICAgdmFyIGFjdGl2ZXMgPSB0aGlzLiRwYXJlbnQgJiYgdGhpcy4kcGFyZW50LmNoaWxkcmVuKCcucGFuZWwnKS5jaGlsZHJlbignLmluLCAuY29sbGFwc2luZycpXG5cbiAgICBpZiAoYWN0aXZlcyAmJiBhY3RpdmVzLmxlbmd0aCkge1xuICAgICAgYWN0aXZlc0RhdGEgPSBhY3RpdmVzLmRhdGEoJ2JzLmNvbGxhcHNlJylcbiAgICAgIGlmIChhY3RpdmVzRGF0YSAmJiBhY3RpdmVzRGF0YS50cmFuc2l0aW9uaW5nKSByZXR1cm5cbiAgICB9XG5cbiAgICB2YXIgc3RhcnRFdmVudCA9ICQuRXZlbnQoJ3Nob3cuYnMuY29sbGFwc2UnKVxuICAgIHRoaXMuJGVsZW1lbnQudHJpZ2dlcihzdGFydEV2ZW50KVxuICAgIGlmIChzdGFydEV2ZW50LmlzRGVmYXVsdFByZXZlbnRlZCgpKSByZXR1cm5cblxuICAgIGlmIChhY3RpdmVzICYmIGFjdGl2ZXMubGVuZ3RoKSB7XG4gICAgICBQbHVnaW4uY2FsbChhY3RpdmVzLCAnaGlkZScpXG4gICAgICBhY3RpdmVzRGF0YSB8fCBhY3RpdmVzLmRhdGEoJ2JzLmNvbGxhcHNlJywgbnVsbClcbiAgICB9XG5cbiAgICB2YXIgZGltZW5zaW9uID0gdGhpcy5kaW1lbnNpb24oKVxuXG4gICAgdGhpcy4kZWxlbWVudFxuICAgICAgLnJlbW92ZUNsYXNzKCdjb2xsYXBzZScpXG4gICAgICAuYWRkQ2xhc3MoJ2NvbGxhcHNpbmcnKVtkaW1lbnNpb25dKDApXG4gICAgICAuYXR0cignYXJpYS1leHBhbmRlZCcsIHRydWUpXG5cbiAgICB0aGlzLiR0cmlnZ2VyXG4gICAgICAucmVtb3ZlQ2xhc3MoJ2NvbGxhcHNlZCcpXG4gICAgICAuYXR0cignYXJpYS1leHBhbmRlZCcsIHRydWUpXG5cbiAgICB0aGlzLnRyYW5zaXRpb25pbmcgPSAxXG5cbiAgICB2YXIgY29tcGxldGUgPSBmdW5jdGlvbiAoKSB7XG4gICAgICB0aGlzLiRlbGVtZW50XG4gICAgICAgIC5yZW1vdmVDbGFzcygnY29sbGFwc2luZycpXG4gICAgICAgIC5hZGRDbGFzcygnY29sbGFwc2UgaW4nKVtkaW1lbnNpb25dKCcnKVxuICAgICAgdGhpcy50cmFuc2l0aW9uaW5nID0gMFxuICAgICAgdGhpcy4kZWxlbWVudFxuICAgICAgICAudHJpZ2dlcignc2hvd24uYnMuY29sbGFwc2UnKVxuICAgIH1cblxuICAgIGlmICghJC5zdXBwb3J0LnRyYW5zaXRpb24pIHJldHVybiBjb21wbGV0ZS5jYWxsKHRoaXMpXG5cbiAgICB2YXIgc2Nyb2xsU2l6ZSA9ICQuY2FtZWxDYXNlKFsnc2Nyb2xsJywgZGltZW5zaW9uXS5qb2luKCctJykpXG5cbiAgICB0aGlzLiRlbGVtZW50XG4gICAgICAub25lKCdic1RyYW5zaXRpb25FbmQnLCAkLnByb3h5KGNvbXBsZXRlLCB0aGlzKSlcbiAgICAgIC5lbXVsYXRlVHJhbnNpdGlvbkVuZChDb2xsYXBzZS5UUkFOU0lUSU9OX0RVUkFUSU9OKVtkaW1lbnNpb25dKHRoaXMuJGVsZW1lbnRbMF1bc2Nyb2xsU2l6ZV0pXG4gIH1cblxuICBDb2xsYXBzZS5wcm90b3R5cGUuaGlkZSA9IGZ1bmN0aW9uICgpIHtcbiAgICBpZiAodGhpcy50cmFuc2l0aW9uaW5nIHx8ICF0aGlzLiRlbGVtZW50Lmhhc0NsYXNzKCdpbicpKSByZXR1cm5cblxuICAgIHZhciBzdGFydEV2ZW50ID0gJC5FdmVudCgnaGlkZS5icy5jb2xsYXBzZScpXG4gICAgdGhpcy4kZWxlbWVudC50cmlnZ2VyKHN0YXJ0RXZlbnQpXG4gICAgaWYgKHN0YXJ0RXZlbnQuaXNEZWZhdWx0UHJldmVudGVkKCkpIHJldHVyblxuXG4gICAgdmFyIGRpbWVuc2lvbiA9IHRoaXMuZGltZW5zaW9uKClcblxuICAgIHRoaXMuJGVsZW1lbnRbZGltZW5zaW9uXSh0aGlzLiRlbGVtZW50W2RpbWVuc2lvbl0oKSlbMF0ub2Zmc2V0SGVpZ2h0XG5cbiAgICB0aGlzLiRlbGVtZW50XG4gICAgICAuYWRkQ2xhc3MoJ2NvbGxhcHNpbmcnKVxuICAgICAgLnJlbW92ZUNsYXNzKCdjb2xsYXBzZSBpbicpXG4gICAgICAuYXR0cignYXJpYS1leHBhbmRlZCcsIGZhbHNlKVxuXG4gICAgdGhpcy4kdHJpZ2dlclxuICAgICAgLmFkZENsYXNzKCdjb2xsYXBzZWQnKVxuICAgICAgLmF0dHIoJ2FyaWEtZXhwYW5kZWQnLCBmYWxzZSlcblxuICAgIHRoaXMudHJhbnNpdGlvbmluZyA9IDFcblxuICAgIHZhciBjb21wbGV0ZSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgIHRoaXMudHJhbnNpdGlvbmluZyA9IDBcbiAgICAgIHRoaXMuJGVsZW1lbnRcbiAgICAgICAgLnJlbW92ZUNsYXNzKCdjb2xsYXBzaW5nJylcbiAgICAgICAgLmFkZENsYXNzKCdjb2xsYXBzZScpXG4gICAgICAgIC50cmlnZ2VyKCdoaWRkZW4uYnMuY29sbGFwc2UnKVxuICAgIH1cblxuICAgIGlmICghJC5zdXBwb3J0LnRyYW5zaXRpb24pIHJldHVybiBjb21wbGV0ZS5jYWxsKHRoaXMpXG5cbiAgICB0aGlzLiRlbGVtZW50XG4gICAgICBbZGltZW5zaW9uXSgwKVxuICAgICAgLm9uZSgnYnNUcmFuc2l0aW9uRW5kJywgJC5wcm94eShjb21wbGV0ZSwgdGhpcykpXG4gICAgICAuZW11bGF0ZVRyYW5zaXRpb25FbmQoQ29sbGFwc2UuVFJBTlNJVElPTl9EVVJBVElPTilcbiAgfVxuXG4gIENvbGxhcHNlLnByb3RvdHlwZS50b2dnbGUgPSBmdW5jdGlvbiAoKSB7XG4gICAgdGhpc1t0aGlzLiRlbGVtZW50Lmhhc0NsYXNzKCdpbicpID8gJ2hpZGUnIDogJ3Nob3cnXSgpXG4gIH1cblxuICBDb2xsYXBzZS5wcm90b3R5cGUuZ2V0UGFyZW50ID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiAkKHRoaXMub3B0aW9ucy5wYXJlbnQpXG4gICAgICAuZmluZCgnW2RhdGEtdG9nZ2xlPVwiY29sbGFwc2VcIl1bZGF0YS1wYXJlbnQ9XCInICsgdGhpcy5vcHRpb25zLnBhcmVudCArICdcIl0nKVxuICAgICAgLmVhY2goJC5wcm94eShmdW5jdGlvbiAoaSwgZWxlbWVudCkge1xuICAgICAgICB2YXIgJGVsZW1lbnQgPSAkKGVsZW1lbnQpXG4gICAgICAgIHRoaXMuYWRkQXJpYUFuZENvbGxhcHNlZENsYXNzKGdldFRhcmdldEZyb21UcmlnZ2VyKCRlbGVtZW50KSwgJGVsZW1lbnQpXG4gICAgICB9LCB0aGlzKSlcbiAgICAgIC5lbmQoKVxuICB9XG5cbiAgQ29sbGFwc2UucHJvdG90eXBlLmFkZEFyaWFBbmRDb2xsYXBzZWRDbGFzcyA9IGZ1bmN0aW9uICgkZWxlbWVudCwgJHRyaWdnZXIpIHtcbiAgICB2YXIgaXNPcGVuID0gJGVsZW1lbnQuaGFzQ2xhc3MoJ2luJylcblxuICAgICRlbGVtZW50LmF0dHIoJ2FyaWEtZXhwYW5kZWQnLCBpc09wZW4pXG4gICAgJHRyaWdnZXJcbiAgICAgIC50b2dnbGVDbGFzcygnY29sbGFwc2VkJywgIWlzT3BlbilcbiAgICAgIC5hdHRyKCdhcmlhLWV4cGFuZGVkJywgaXNPcGVuKVxuICB9XG5cbiAgZnVuY3Rpb24gZ2V0VGFyZ2V0RnJvbVRyaWdnZXIoJHRyaWdnZXIpIHtcbiAgICB2YXIgaHJlZlxuICAgIHZhciB0YXJnZXQgPSAkdHJpZ2dlci5hdHRyKCdkYXRhLXRhcmdldCcpXG4gICAgICB8fCAoaHJlZiA9ICR0cmlnZ2VyLmF0dHIoJ2hyZWYnKSkgJiYgaHJlZi5yZXBsYWNlKC8uKig/PSNbXlxcc10rJCkvLCAnJykgLy8gc3RyaXAgZm9yIGllN1xuXG4gICAgcmV0dXJuICQodGFyZ2V0KVxuICB9XG5cblxuICAvLyBDT0xMQVBTRSBQTFVHSU4gREVGSU5JVElPTlxuICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PVxuXG4gIGZ1bmN0aW9uIFBsdWdpbihvcHRpb24pIHtcbiAgICByZXR1cm4gdGhpcy5lYWNoKGZ1bmN0aW9uICgpIHtcbiAgICAgIHZhciAkdGhpcyAgID0gJCh0aGlzKVxuICAgICAgdmFyIGRhdGEgICAgPSAkdGhpcy5kYXRhKCdicy5jb2xsYXBzZScpXG4gICAgICB2YXIgb3B0aW9ucyA9ICQuZXh0ZW5kKHt9LCBDb2xsYXBzZS5ERUZBVUxUUywgJHRoaXMuZGF0YSgpLCB0eXBlb2Ygb3B0aW9uID09ICdvYmplY3QnICYmIG9wdGlvbilcblxuICAgICAgaWYgKCFkYXRhICYmIG9wdGlvbnMudG9nZ2xlICYmIC9zaG93fGhpZGUvLnRlc3Qob3B0aW9uKSkgb3B0aW9ucy50b2dnbGUgPSBmYWxzZVxuICAgICAgaWYgKCFkYXRhKSAkdGhpcy5kYXRhKCdicy5jb2xsYXBzZScsIChkYXRhID0gbmV3IENvbGxhcHNlKHRoaXMsIG9wdGlvbnMpKSlcbiAgICAgIGlmICh0eXBlb2Ygb3B0aW9uID09ICdzdHJpbmcnKSBkYXRhW29wdGlvbl0oKVxuICAgIH0pXG4gIH1cblxuICB2YXIgb2xkID0gJC5mbi5jb2xsYXBzZVxuXG4gICQuZm4uY29sbGFwc2UgICAgICAgICAgICAgPSBQbHVnaW5cbiAgJC5mbi5jb2xsYXBzZS5Db25zdHJ1Y3RvciA9IENvbGxhcHNlXG5cblxuICAvLyBDT0xMQVBTRSBOTyBDT05GTElDVFxuICAvLyA9PT09PT09PT09PT09PT09PT09PVxuXG4gICQuZm4uY29sbGFwc2Uubm9Db25mbGljdCA9IGZ1bmN0aW9uICgpIHtcbiAgICAkLmZuLmNvbGxhcHNlID0gb2xkXG4gICAgcmV0dXJuIHRoaXNcbiAgfVxuXG5cbiAgLy8gQ09MTEFQU0UgREFUQS1BUElcbiAgLy8gPT09PT09PT09PT09PT09PT1cblxuICAkKGRvY3VtZW50KS5vbignY2xpY2suYnMuY29sbGFwc2UuZGF0YS1hcGknLCAnW2RhdGEtdG9nZ2xlPVwiY29sbGFwc2VcIl0nLCBmdW5jdGlvbiAoZSkge1xuICAgIHZhciAkdGhpcyAgID0gJCh0aGlzKVxuXG4gICAgaWYgKCEkdGhpcy5hdHRyKCdkYXRhLXRhcmdldCcpKSBlLnByZXZlbnREZWZhdWx0KClcblxuICAgIHZhciAkdGFyZ2V0ID0gZ2V0VGFyZ2V0RnJvbVRyaWdnZXIoJHRoaXMpXG4gICAgdmFyIGRhdGEgICAgPSAkdGFyZ2V0LmRhdGEoJ2JzLmNvbGxhcHNlJylcbiAgICB2YXIgb3B0aW9uICA9IGRhdGEgPyAndG9nZ2xlJyA6ICR0aGlzLmRhdGEoKVxuXG4gICAgUGx1Z2luLmNhbGwoJHRhcmdldCwgb3B0aW9uKVxuICB9KVxuXG59KGpRdWVyeSk7XG5cbi8qID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuICogQm9vdHN0cmFwOiBkcm9wZG93bi5qcyB2My4zLjRcbiAqIGh0dHA6Ly9nZXRib290c3RyYXAuY29tL2phdmFzY3JpcHQvI2Ryb3Bkb3duc1xuICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4gKiBDb3B5cmlnaHQgMjAxMS0yMDE1IFR3aXR0ZXIsIEluYy5cbiAqIExpY2Vuc2VkIHVuZGVyIE1JVCAoaHR0cHM6Ly9naXRodWIuY29tL3R3YnMvYm9vdHN0cmFwL2Jsb2IvbWFzdGVyL0xJQ0VOU0UpXG4gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0gKi9cblxuXG4rZnVuY3Rpb24gKCQpIHtcbiAgJ3VzZSBzdHJpY3QnO1xuXG4gIC8vIERST1BET1dOIENMQVNTIERFRklOSVRJT05cbiAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PVxuXG4gIHZhciBiYWNrZHJvcCA9ICcuZHJvcGRvd24tYmFja2Ryb3AnXG4gIHZhciB0b2dnbGUgICA9ICdbZGF0YS10b2dnbGU9XCJkcm9wZG93blwiXSdcbiAgdmFyIERyb3Bkb3duID0gZnVuY3Rpb24gKGVsZW1lbnQpIHtcbiAgICAkKGVsZW1lbnQpLm9uKCdjbGljay5icy5kcm9wZG93bicsIHRoaXMudG9nZ2xlKVxuICB9XG5cbiAgRHJvcGRvd24uVkVSU0lPTiA9ICczLjMuNCdcblxuICBEcm9wZG93bi5wcm90b3R5cGUudG9nZ2xlID0gZnVuY3Rpb24gKGUpIHtcbiAgICB2YXIgJHRoaXMgPSAkKHRoaXMpXG5cbiAgICBpZiAoJHRoaXMuaXMoJy5kaXNhYmxlZCwgOmRpc2FibGVkJykpIHJldHVyblxuXG4gICAgdmFyICRwYXJlbnQgID0gZ2V0UGFyZW50KCR0aGlzKVxuICAgIHZhciBpc0FjdGl2ZSA9ICRwYXJlbnQuaGFzQ2xhc3MoJ29wZW4nKVxuXG4gICAgY2xlYXJNZW51cygpXG5cbiAgICBpZiAoIWlzQWN0aXZlKSB7XG4gICAgICBpZiAoJ29udG91Y2hzdGFydCcgaW4gZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50ICYmICEkcGFyZW50LmNsb3Nlc3QoJy5uYXZiYXItbmF2JykubGVuZ3RoKSB7XG4gICAgICAgIC8vIGlmIG1vYmlsZSB3ZSB1c2UgYSBiYWNrZHJvcCBiZWNhdXNlIGNsaWNrIGV2ZW50cyBkb24ndCBkZWxlZ2F0ZVxuICAgICAgICAkKCc8ZGl2IGNsYXNzPVwiZHJvcGRvd24tYmFja2Ryb3BcIi8+JykuaW5zZXJ0QWZ0ZXIoJCh0aGlzKSkub24oJ2NsaWNrJywgY2xlYXJNZW51cylcbiAgICAgIH1cblxuICAgICAgdmFyIHJlbGF0ZWRUYXJnZXQgPSB7IHJlbGF0ZWRUYXJnZXQ6IHRoaXMgfVxuICAgICAgJHBhcmVudC50cmlnZ2VyKGUgPSAkLkV2ZW50KCdzaG93LmJzLmRyb3Bkb3duJywgcmVsYXRlZFRhcmdldCkpXG5cbiAgICAgIGlmIChlLmlzRGVmYXVsdFByZXZlbnRlZCgpKSByZXR1cm5cblxuICAgICAgJHRoaXNcbiAgICAgICAgLnRyaWdnZXIoJ2ZvY3VzJylcbiAgICAgICAgLmF0dHIoJ2FyaWEtZXhwYW5kZWQnLCAndHJ1ZScpXG5cbiAgICAgICRwYXJlbnRcbiAgICAgICAgLnRvZ2dsZUNsYXNzKCdvcGVuJylcbiAgICAgICAgLnRyaWdnZXIoJ3Nob3duLmJzLmRyb3Bkb3duJywgcmVsYXRlZFRhcmdldClcbiAgICB9XG5cbiAgICByZXR1cm4gZmFsc2VcbiAgfVxuXG4gIERyb3Bkb3duLnByb3RvdHlwZS5rZXlkb3duID0gZnVuY3Rpb24gKGUpIHtcbiAgICBpZiAoIS8oMzh8NDB8Mjd8MzIpLy50ZXN0KGUud2hpY2gpIHx8IC9pbnB1dHx0ZXh0YXJlYS9pLnRlc3QoZS50YXJnZXQudGFnTmFtZSkpIHJldHVyblxuXG4gICAgdmFyICR0aGlzID0gJCh0aGlzKVxuXG4gICAgZS5wcmV2ZW50RGVmYXVsdCgpXG4gICAgZS5zdG9wUHJvcGFnYXRpb24oKVxuXG4gICAgaWYgKCR0aGlzLmlzKCcuZGlzYWJsZWQsIDpkaXNhYmxlZCcpKSByZXR1cm5cblxuICAgIHZhciAkcGFyZW50ICA9IGdldFBhcmVudCgkdGhpcylcbiAgICB2YXIgaXNBY3RpdmUgPSAkcGFyZW50Lmhhc0NsYXNzKCdvcGVuJylcblxuICAgIGlmICgoIWlzQWN0aXZlICYmIGUud2hpY2ggIT0gMjcpIHx8IChpc0FjdGl2ZSAmJiBlLndoaWNoID09IDI3KSkge1xuICAgICAgaWYgKGUud2hpY2ggPT0gMjcpICRwYXJlbnQuZmluZCh0b2dnbGUpLnRyaWdnZXIoJ2ZvY3VzJylcbiAgICAgIHJldHVybiAkdGhpcy50cmlnZ2VyKCdjbGljaycpXG4gICAgfVxuXG4gICAgdmFyIGRlc2MgPSAnIGxpOm5vdCguZGlzYWJsZWQpOnZpc2libGUgYSdcbiAgICB2YXIgJGl0ZW1zID0gJHBhcmVudC5maW5kKCdbcm9sZT1cIm1lbnVcIl0nICsgZGVzYyArICcsIFtyb2xlPVwibGlzdGJveFwiXScgKyBkZXNjKVxuXG4gICAgaWYgKCEkaXRlbXMubGVuZ3RoKSByZXR1cm5cblxuICAgIHZhciBpbmRleCA9ICRpdGVtcy5pbmRleChlLnRhcmdldClcblxuICAgIGlmIChlLndoaWNoID09IDM4ICYmIGluZGV4ID4gMCkgICAgICAgICAgICAgICAgIGluZGV4LS0gICAgICAgICAgICAgICAgICAgICAgICAvLyB1cFxuICAgIGlmIChlLndoaWNoID09IDQwICYmIGluZGV4IDwgJGl0ZW1zLmxlbmd0aCAtIDEpIGluZGV4KysgICAgICAgICAgICAgICAgICAgICAgICAvLyBkb3duXG4gICAgaWYgKCF+aW5kZXgpICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbmRleCA9IDBcblxuICAgICRpdGVtcy5lcShpbmRleCkudHJpZ2dlcignZm9jdXMnKVxuICB9XG5cbiAgZnVuY3Rpb24gY2xlYXJNZW51cyhlKSB7XG4gICAgaWYgKGUgJiYgZS53aGljaCA9PT0gMykgcmV0dXJuXG4gICAgJChiYWNrZHJvcCkucmVtb3ZlKClcbiAgICAkKHRvZ2dsZSkuZWFjaChmdW5jdGlvbiAoKSB7XG4gICAgICB2YXIgJHRoaXMgICAgICAgICA9ICQodGhpcylcbiAgICAgIHZhciAkcGFyZW50ICAgICAgID0gZ2V0UGFyZW50KCR0aGlzKVxuICAgICAgdmFyIHJlbGF0ZWRUYXJnZXQgPSB7IHJlbGF0ZWRUYXJnZXQ6IHRoaXMgfVxuXG4gICAgICBpZiAoISRwYXJlbnQuaGFzQ2xhc3MoJ29wZW4nKSkgcmV0dXJuXG5cbiAgICAgICRwYXJlbnQudHJpZ2dlcihlID0gJC5FdmVudCgnaGlkZS5icy5kcm9wZG93bicsIHJlbGF0ZWRUYXJnZXQpKVxuXG4gICAgICBpZiAoZS5pc0RlZmF1bHRQcmV2ZW50ZWQoKSkgcmV0dXJuXG5cbiAgICAgICR0aGlzLmF0dHIoJ2FyaWEtZXhwYW5kZWQnLCAnZmFsc2UnKVxuICAgICAgJHBhcmVudC5yZW1vdmVDbGFzcygnb3BlbicpLnRyaWdnZXIoJ2hpZGRlbi5icy5kcm9wZG93bicsIHJlbGF0ZWRUYXJnZXQpXG4gICAgfSlcbiAgfVxuXG4gIGZ1bmN0aW9uIGdldFBhcmVudCgkdGhpcykge1xuICAgIHZhciBzZWxlY3RvciA9ICR0aGlzLmF0dHIoJ2RhdGEtdGFyZ2V0JylcblxuICAgIGlmICghc2VsZWN0b3IpIHtcbiAgICAgIHNlbGVjdG9yID0gJHRoaXMuYXR0cignaHJlZicpXG4gICAgICBzZWxlY3RvciA9IHNlbGVjdG9yICYmIC8jW0EtWmEtel0vLnRlc3Qoc2VsZWN0b3IpICYmIHNlbGVjdG9yLnJlcGxhY2UoLy4qKD89I1teXFxzXSokKS8sICcnKSAvLyBzdHJpcCBmb3IgaWU3XG4gICAgfVxuXG4gICAgdmFyICRwYXJlbnQgPSBzZWxlY3RvciAmJiAkKHNlbGVjdG9yKVxuXG4gICAgcmV0dXJuICRwYXJlbnQgJiYgJHBhcmVudC5sZW5ndGggPyAkcGFyZW50IDogJHRoaXMucGFyZW50KClcbiAgfVxuXG5cbiAgLy8gRFJPUERPV04gUExVR0lOIERFRklOSVRJT05cbiAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT1cblxuICBmdW5jdGlvbiBQbHVnaW4ob3B0aW9uKSB7XG4gICAgcmV0dXJuIHRoaXMuZWFjaChmdW5jdGlvbiAoKSB7XG4gICAgICB2YXIgJHRoaXMgPSAkKHRoaXMpXG4gICAgICB2YXIgZGF0YSAgPSAkdGhpcy5kYXRhKCdicy5kcm9wZG93bicpXG5cbiAgICAgIGlmICghZGF0YSkgJHRoaXMuZGF0YSgnYnMuZHJvcGRvd24nLCAoZGF0YSA9IG5ldyBEcm9wZG93bih0aGlzKSkpXG4gICAgICBpZiAodHlwZW9mIG9wdGlvbiA9PSAnc3RyaW5nJykgZGF0YVtvcHRpb25dLmNhbGwoJHRoaXMpXG4gICAgfSlcbiAgfVxuXG4gIHZhciBvbGQgPSAkLmZuLmRyb3Bkb3duXG5cbiAgJC5mbi5kcm9wZG93biAgICAgICAgICAgICA9IFBsdWdpblxuICAkLmZuLmRyb3Bkb3duLkNvbnN0cnVjdG9yID0gRHJvcGRvd25cblxuXG4gIC8vIERST1BET1dOIE5PIENPTkZMSUNUXG4gIC8vID09PT09PT09PT09PT09PT09PT09XG5cbiAgJC5mbi5kcm9wZG93bi5ub0NvbmZsaWN0ID0gZnVuY3Rpb24gKCkge1xuICAgICQuZm4uZHJvcGRvd24gPSBvbGRcbiAgICByZXR1cm4gdGhpc1xuICB9XG5cblxuICAvLyBBUFBMWSBUTyBTVEFOREFSRCBEUk9QRE9XTiBFTEVNRU5UU1xuICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuXG4gICQoZG9jdW1lbnQpXG4gICAgLm9uKCdjbGljay5icy5kcm9wZG93bi5kYXRhLWFwaScsIGNsZWFyTWVudXMpXG4gICAgLm9uKCdjbGljay5icy5kcm9wZG93bi5kYXRhLWFwaScsICcuZHJvcGRvd24gZm9ybScsIGZ1bmN0aW9uIChlKSB7IGUuc3RvcFByb3BhZ2F0aW9uKCkgfSlcbiAgICAub24oJ2NsaWNrLmJzLmRyb3Bkb3duLmRhdGEtYXBpJywgdG9nZ2xlLCBEcm9wZG93bi5wcm90b3R5cGUudG9nZ2xlKVxuICAgIC5vbigna2V5ZG93bi5icy5kcm9wZG93bi5kYXRhLWFwaScsIHRvZ2dsZSwgRHJvcGRvd24ucHJvdG90eXBlLmtleWRvd24pXG4gICAgLm9uKCdrZXlkb3duLmJzLmRyb3Bkb3duLmRhdGEtYXBpJywgJ1tyb2xlPVwibWVudVwiXScsIERyb3Bkb3duLnByb3RvdHlwZS5rZXlkb3duKVxuICAgIC5vbigna2V5ZG93bi5icy5kcm9wZG93bi5kYXRhLWFwaScsICdbcm9sZT1cImxpc3Rib3hcIl0nLCBEcm9wZG93bi5wcm90b3R5cGUua2V5ZG93bilcblxufShqUXVlcnkpO1xuXG4vKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAqIEJvb3RzdHJhcDogbW9kYWwuanMgdjMuMy40XG4gKiBodHRwOi8vZ2V0Ym9vdHN0cmFwLmNvbS9qYXZhc2NyaXB0LyNtb2RhbHNcbiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuICogQ29weXJpZ2h0IDIwMTEtMjAxNSBUd2l0dGVyLCBJbmMuXG4gKiBMaWNlbnNlZCB1bmRlciBNSVQgKGh0dHBzOi8vZ2l0aHViLmNvbS90d2JzL2Jvb3RzdHJhcC9ibG9iL21hc3Rlci9MSUNFTlNFKVxuICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09ICovXG5cblxuK2Z1bmN0aW9uICgkKSB7XG4gICd1c2Ugc3RyaWN0JztcblxuICAvLyBNT0RBTCBDTEFTUyBERUZJTklUSU9OXG4gIC8vID09PT09PT09PT09PT09PT09PT09PT1cblxuICB2YXIgTW9kYWwgPSBmdW5jdGlvbiAoZWxlbWVudCwgb3B0aW9ucykge1xuICAgIHRoaXMub3B0aW9ucyAgICAgICAgICAgICA9IG9wdGlvbnNcbiAgICB0aGlzLiRib2R5ICAgICAgICAgICAgICAgPSAkKGRvY3VtZW50LmJvZHkpXG4gICAgdGhpcy4kZWxlbWVudCAgICAgICAgICAgID0gJChlbGVtZW50KVxuICAgIHRoaXMuJGRpYWxvZyAgICAgICAgICAgICA9IHRoaXMuJGVsZW1lbnQuZmluZCgnLm1vZGFsLWRpYWxvZycpXG4gICAgdGhpcy4kYmFja2Ryb3AgICAgICAgICAgID0gbnVsbFxuICAgIHRoaXMuaXNTaG93biAgICAgICAgICAgICA9IG51bGxcbiAgICB0aGlzLm9yaWdpbmFsQm9keVBhZCAgICAgPSBudWxsXG4gICAgdGhpcy5zY3JvbGxiYXJXaWR0aCAgICAgID0gMFxuICAgIHRoaXMuaWdub3JlQmFja2Ryb3BDbGljayA9IGZhbHNlXG5cbiAgICBpZiAodGhpcy5vcHRpb25zLnJlbW90ZSkge1xuICAgICAgdGhpcy4kZWxlbWVudFxuICAgICAgICAuZmluZCgnLm1vZGFsLWNvbnRlbnQnKVxuICAgICAgICAubG9hZCh0aGlzLm9wdGlvbnMucmVtb3RlLCAkLnByb3h5KGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICB0aGlzLiRlbGVtZW50LnRyaWdnZXIoJ2xvYWRlZC5icy5tb2RhbCcpXG4gICAgICAgIH0sIHRoaXMpKVxuICAgIH1cbiAgfVxuXG4gIE1vZGFsLlZFUlNJT04gID0gJzMuMy40J1xuXG4gIE1vZGFsLlRSQU5TSVRJT05fRFVSQVRJT04gPSAzMDBcbiAgTW9kYWwuQkFDS0RST1BfVFJBTlNJVElPTl9EVVJBVElPTiA9IDE1MFxuXG4gIE1vZGFsLkRFRkFVTFRTID0ge1xuICAgIGJhY2tkcm9wOiB0cnVlLFxuICAgIGtleWJvYXJkOiB0cnVlLFxuICAgIHNob3c6IHRydWVcbiAgfVxuXG4gIE1vZGFsLnByb3RvdHlwZS50b2dnbGUgPSBmdW5jdGlvbiAoX3JlbGF0ZWRUYXJnZXQpIHtcbiAgICByZXR1cm4gdGhpcy5pc1Nob3duID8gdGhpcy5oaWRlKCkgOiB0aGlzLnNob3coX3JlbGF0ZWRUYXJnZXQpXG4gIH1cblxuICBNb2RhbC5wcm90b3R5cGUuc2hvdyA9IGZ1bmN0aW9uIChfcmVsYXRlZFRhcmdldCkge1xuICAgIHZhciB0aGF0ID0gdGhpc1xuICAgIHZhciBlICAgID0gJC5FdmVudCgnc2hvdy5icy5tb2RhbCcsIHsgcmVsYXRlZFRhcmdldDogX3JlbGF0ZWRUYXJnZXQgfSlcblxuICAgIHRoaXMuJGVsZW1lbnQudHJpZ2dlcihlKVxuXG4gICAgaWYgKHRoaXMuaXNTaG93biB8fCBlLmlzRGVmYXVsdFByZXZlbnRlZCgpKSByZXR1cm5cblxuICAgIHRoaXMuaXNTaG93biA9IHRydWVcblxuICAgIHRoaXMuY2hlY2tTY3JvbGxiYXIoKVxuICAgIHRoaXMuc2V0U2Nyb2xsYmFyKClcbiAgICB0aGlzLiRib2R5LmFkZENsYXNzKCdtb2RhbC1vcGVuJylcblxuICAgIHRoaXMuZXNjYXBlKClcbiAgICB0aGlzLnJlc2l6ZSgpXG5cbiAgICB0aGlzLiRlbGVtZW50Lm9uKCdjbGljay5kaXNtaXNzLmJzLm1vZGFsJywgJ1tkYXRhLWRpc21pc3M9XCJtb2RhbFwiXScsICQucHJveHkodGhpcy5oaWRlLCB0aGlzKSlcblxuICAgIHRoaXMuJGRpYWxvZy5vbignbW91c2Vkb3duLmRpc21pc3MuYnMubW9kYWwnLCBmdW5jdGlvbiAoKSB7XG4gICAgICB0aGF0LiRlbGVtZW50Lm9uZSgnbW91c2V1cC5kaXNtaXNzLmJzLm1vZGFsJywgZnVuY3Rpb24gKGUpIHtcbiAgICAgICAgaWYgKCQoZS50YXJnZXQpLmlzKHRoYXQuJGVsZW1lbnQpKSB0aGF0Lmlnbm9yZUJhY2tkcm9wQ2xpY2sgPSB0cnVlXG4gICAgICB9KVxuICAgIH0pXG5cbiAgICB0aGlzLmJhY2tkcm9wKGZ1bmN0aW9uICgpIHtcbiAgICAgIHZhciB0cmFuc2l0aW9uID0gJC5zdXBwb3J0LnRyYW5zaXRpb24gJiYgdGhhdC4kZWxlbWVudC5oYXNDbGFzcygnZmFkZScpXG5cbiAgICAgIGlmICghdGhhdC4kZWxlbWVudC5wYXJlbnQoKS5sZW5ndGgpIHtcbiAgICAgICAgdGhhdC4kZWxlbWVudC5hcHBlbmRUbyh0aGF0LiRib2R5KSAvLyBkb24ndCBtb3ZlIG1vZGFscyBkb20gcG9zaXRpb25cbiAgICAgIH1cblxuICAgICAgdGhhdC4kZWxlbWVudFxuICAgICAgICAuc2hvdygpXG4gICAgICAgIC5zY3JvbGxUb3AoMClcblxuICAgICAgdGhhdC5hZGp1c3REaWFsb2coKVxuXG4gICAgICBpZiAodHJhbnNpdGlvbikge1xuICAgICAgICB0aGF0LiRlbGVtZW50WzBdLm9mZnNldFdpZHRoIC8vIGZvcmNlIHJlZmxvd1xuICAgICAgfVxuXG4gICAgICB0aGF0LiRlbGVtZW50XG4gICAgICAgIC5hZGRDbGFzcygnaW4nKVxuICAgICAgICAuYXR0cignYXJpYS1oaWRkZW4nLCBmYWxzZSlcblxuICAgICAgdGhhdC5lbmZvcmNlRm9jdXMoKVxuXG4gICAgICB2YXIgZSA9ICQuRXZlbnQoJ3Nob3duLmJzLm1vZGFsJywgeyByZWxhdGVkVGFyZ2V0OiBfcmVsYXRlZFRhcmdldCB9KVxuXG4gICAgICB0cmFuc2l0aW9uID9cbiAgICAgICAgdGhhdC4kZGlhbG9nIC8vIHdhaXQgZm9yIG1vZGFsIHRvIHNsaWRlIGluXG4gICAgICAgICAgLm9uZSgnYnNUcmFuc2l0aW9uRW5kJywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgdGhhdC4kZWxlbWVudC50cmlnZ2VyKCdmb2N1cycpLnRyaWdnZXIoZSlcbiAgICAgICAgICB9KVxuICAgICAgICAgIC5lbXVsYXRlVHJhbnNpdGlvbkVuZChNb2RhbC5UUkFOU0lUSU9OX0RVUkFUSU9OKSA6XG4gICAgICAgIHRoYXQuJGVsZW1lbnQudHJpZ2dlcignZm9jdXMnKS50cmlnZ2VyKGUpXG4gICAgfSlcbiAgfVxuXG4gIE1vZGFsLnByb3RvdHlwZS5oaWRlID0gZnVuY3Rpb24gKGUpIHtcbiAgICBpZiAoZSkgZS5wcmV2ZW50RGVmYXVsdCgpXG5cbiAgICBlID0gJC5FdmVudCgnaGlkZS5icy5tb2RhbCcpXG5cbiAgICB0aGlzLiRlbGVtZW50LnRyaWdnZXIoZSlcblxuICAgIGlmICghdGhpcy5pc1Nob3duIHx8IGUuaXNEZWZhdWx0UHJldmVudGVkKCkpIHJldHVyblxuXG4gICAgdGhpcy5pc1Nob3duID0gZmFsc2VcblxuICAgIHRoaXMuZXNjYXBlKClcbiAgICB0aGlzLnJlc2l6ZSgpXG5cbiAgICAkKGRvY3VtZW50KS5vZmYoJ2ZvY3VzaW4uYnMubW9kYWwnKVxuXG4gICAgdGhpcy4kZWxlbWVudFxuICAgICAgLnJlbW92ZUNsYXNzKCdpbicpXG4gICAgICAuYXR0cignYXJpYS1oaWRkZW4nLCB0cnVlKVxuICAgICAgLm9mZignY2xpY2suZGlzbWlzcy5icy5tb2RhbCcpXG4gICAgICAub2ZmKCdtb3VzZXVwLmRpc21pc3MuYnMubW9kYWwnKVxuXG4gICAgdGhpcy4kZGlhbG9nLm9mZignbW91c2Vkb3duLmRpc21pc3MuYnMubW9kYWwnKVxuXG4gICAgJC5zdXBwb3J0LnRyYW5zaXRpb24gJiYgdGhpcy4kZWxlbWVudC5oYXNDbGFzcygnZmFkZScpID9cbiAgICAgIHRoaXMuJGVsZW1lbnRcbiAgICAgICAgLm9uZSgnYnNUcmFuc2l0aW9uRW5kJywgJC5wcm94eSh0aGlzLmhpZGVNb2RhbCwgdGhpcykpXG4gICAgICAgIC5lbXVsYXRlVHJhbnNpdGlvbkVuZChNb2RhbC5UUkFOU0lUSU9OX0RVUkFUSU9OKSA6XG4gICAgICB0aGlzLmhpZGVNb2RhbCgpXG4gIH1cblxuICBNb2RhbC5wcm90b3R5cGUuZW5mb3JjZUZvY3VzID0gZnVuY3Rpb24gKCkge1xuICAgICQoZG9jdW1lbnQpXG4gICAgICAub2ZmKCdmb2N1c2luLmJzLm1vZGFsJykgLy8gZ3VhcmQgYWdhaW5zdCBpbmZpbml0ZSBmb2N1cyBsb29wXG4gICAgICAub24oJ2ZvY3VzaW4uYnMubW9kYWwnLCAkLnByb3h5KGZ1bmN0aW9uIChlKSB7XG4gICAgICAgIGlmICh0aGlzLiRlbGVtZW50WzBdICE9PSBlLnRhcmdldCAmJiAhdGhpcy4kZWxlbWVudC5oYXMoZS50YXJnZXQpLmxlbmd0aCkge1xuICAgICAgICAgIHRoaXMuJGVsZW1lbnQudHJpZ2dlcignZm9jdXMnKVxuICAgICAgICB9XG4gICAgICB9LCB0aGlzKSlcbiAgfVxuXG4gIE1vZGFsLnByb3RvdHlwZS5lc2NhcGUgPSBmdW5jdGlvbiAoKSB7XG4gICAgaWYgKHRoaXMuaXNTaG93biAmJiB0aGlzLm9wdGlvbnMua2V5Ym9hcmQpIHtcbiAgICAgIHRoaXMuJGVsZW1lbnQub24oJ2tleWRvd24uZGlzbWlzcy5icy5tb2RhbCcsICQucHJveHkoZnVuY3Rpb24gKGUpIHtcbiAgICAgICAgZS53aGljaCA9PSAyNyAmJiB0aGlzLmhpZGUoKVxuICAgICAgfSwgdGhpcykpXG4gICAgfSBlbHNlIGlmICghdGhpcy5pc1Nob3duKSB7XG4gICAgICB0aGlzLiRlbGVtZW50Lm9mZigna2V5ZG93bi5kaXNtaXNzLmJzLm1vZGFsJylcbiAgICB9XG4gIH1cblxuICBNb2RhbC5wcm90b3R5cGUucmVzaXplID0gZnVuY3Rpb24gKCkge1xuICAgIGlmICh0aGlzLmlzU2hvd24pIHtcbiAgICAgICQod2luZG93KS5vbigncmVzaXplLmJzLm1vZGFsJywgJC5wcm94eSh0aGlzLmhhbmRsZVVwZGF0ZSwgdGhpcykpXG4gICAgfSBlbHNlIHtcbiAgICAgICQod2luZG93KS5vZmYoJ3Jlc2l6ZS5icy5tb2RhbCcpXG4gICAgfVxuICB9XG5cbiAgTW9kYWwucHJvdG90eXBlLmhpZGVNb2RhbCA9IGZ1bmN0aW9uICgpIHtcbiAgICB2YXIgdGhhdCA9IHRoaXNcbiAgICB0aGlzLiRlbGVtZW50LmhpZGUoKVxuICAgIHRoaXMuYmFja2Ryb3AoZnVuY3Rpb24gKCkge1xuICAgICAgdGhhdC4kYm9keS5yZW1vdmVDbGFzcygnbW9kYWwtb3BlbicpXG4gICAgICB0aGF0LnJlc2V0QWRqdXN0bWVudHMoKVxuICAgICAgdGhhdC5yZXNldFNjcm9sbGJhcigpXG4gICAgICB0aGF0LiRlbGVtZW50LnRyaWdnZXIoJ2hpZGRlbi5icy5tb2RhbCcpXG4gICAgfSlcbiAgfVxuXG4gIE1vZGFsLnByb3RvdHlwZS5yZW1vdmVCYWNrZHJvcCA9IGZ1bmN0aW9uICgpIHtcbiAgICB0aGlzLiRiYWNrZHJvcCAmJiB0aGlzLiRiYWNrZHJvcC5yZW1vdmUoKVxuICAgIHRoaXMuJGJhY2tkcm9wID0gbnVsbFxuICB9XG5cbiAgTW9kYWwucHJvdG90eXBlLmJhY2tkcm9wID0gZnVuY3Rpb24gKGNhbGxiYWNrKSB7XG4gICAgdmFyIHRoYXQgPSB0aGlzXG4gICAgdmFyIGFuaW1hdGUgPSB0aGlzLiRlbGVtZW50Lmhhc0NsYXNzKCdmYWRlJykgPyAnZmFkZScgOiAnJ1xuXG4gICAgaWYgKHRoaXMuaXNTaG93biAmJiB0aGlzLm9wdGlvbnMuYmFja2Ryb3ApIHtcbiAgICAgIHZhciBkb0FuaW1hdGUgPSAkLnN1cHBvcnQudHJhbnNpdGlvbiAmJiBhbmltYXRlXG5cbiAgICAgIHRoaXMuJGJhY2tkcm9wID0gJCgnPGRpdiBjbGFzcz1cIm1vZGFsLWJhY2tkcm9wICcgKyBhbmltYXRlICsgJ1wiIC8+JylcbiAgICAgICAgLmFwcGVuZFRvKHRoaXMuJGJvZHkpXG5cbiAgICAgIHRoaXMuJGVsZW1lbnQub24oJ2NsaWNrLmRpc21pc3MuYnMubW9kYWwnLCAkLnByb3h5KGZ1bmN0aW9uIChlKSB7XG4gICAgICAgIGlmICh0aGlzLmlnbm9yZUJhY2tkcm9wQ2xpY2spIHtcbiAgICAgICAgICB0aGlzLmlnbm9yZUJhY2tkcm9wQ2xpY2sgPSBmYWxzZVxuICAgICAgICAgIHJldHVyblxuICAgICAgICB9XG4gICAgICAgIGlmIChlLnRhcmdldCAhPT0gZS5jdXJyZW50VGFyZ2V0KSByZXR1cm5cbiAgICAgICAgdGhpcy5vcHRpb25zLmJhY2tkcm9wID09ICdzdGF0aWMnXG4gICAgICAgICAgPyB0aGlzLiRlbGVtZW50WzBdLmZvY3VzKClcbiAgICAgICAgICA6IHRoaXMuaGlkZSgpXG4gICAgICB9LCB0aGlzKSlcblxuICAgICAgaWYgKGRvQW5pbWF0ZSkgdGhpcy4kYmFja2Ryb3BbMF0ub2Zmc2V0V2lkdGggLy8gZm9yY2UgcmVmbG93XG5cbiAgICAgIHRoaXMuJGJhY2tkcm9wLmFkZENsYXNzKCdpbicpXG5cbiAgICAgIGlmICghY2FsbGJhY2spIHJldHVyblxuXG4gICAgICBkb0FuaW1hdGUgP1xuICAgICAgICB0aGlzLiRiYWNrZHJvcFxuICAgICAgICAgIC5vbmUoJ2JzVHJhbnNpdGlvbkVuZCcsIGNhbGxiYWNrKVxuICAgICAgICAgIC5lbXVsYXRlVHJhbnNpdGlvbkVuZChNb2RhbC5CQUNLRFJPUF9UUkFOU0lUSU9OX0RVUkFUSU9OKSA6XG4gICAgICAgIGNhbGxiYWNrKClcblxuICAgIH0gZWxzZSBpZiAoIXRoaXMuaXNTaG93biAmJiB0aGlzLiRiYWNrZHJvcCkge1xuICAgICAgdGhpcy4kYmFja2Ryb3AucmVtb3ZlQ2xhc3MoJ2luJylcblxuICAgICAgdmFyIGNhbGxiYWNrUmVtb3ZlID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB0aGF0LnJlbW92ZUJhY2tkcm9wKClcbiAgICAgICAgY2FsbGJhY2sgJiYgY2FsbGJhY2soKVxuICAgICAgfVxuICAgICAgJC5zdXBwb3J0LnRyYW5zaXRpb24gJiYgdGhpcy4kZWxlbWVudC5oYXNDbGFzcygnZmFkZScpID9cbiAgICAgICAgdGhpcy4kYmFja2Ryb3BcbiAgICAgICAgICAub25lKCdic1RyYW5zaXRpb25FbmQnLCBjYWxsYmFja1JlbW92ZSlcbiAgICAgICAgICAuZW11bGF0ZVRyYW5zaXRpb25FbmQoTW9kYWwuQkFDS0RST1BfVFJBTlNJVElPTl9EVVJBVElPTikgOlxuICAgICAgICBjYWxsYmFja1JlbW92ZSgpXG5cbiAgICB9IGVsc2UgaWYgKGNhbGxiYWNrKSB7XG4gICAgICBjYWxsYmFjaygpXG4gICAgfVxuICB9XG5cbiAgLy8gdGhlc2UgZm9sbG93aW5nIG1ldGhvZHMgYXJlIHVzZWQgdG8gaGFuZGxlIG92ZXJmbG93aW5nIG1vZGFsc1xuXG4gIE1vZGFsLnByb3RvdHlwZS5oYW5kbGVVcGRhdGUgPSBmdW5jdGlvbiAoKSB7XG4gICAgdGhpcy5hZGp1c3REaWFsb2coKVxuICB9XG5cbiAgTW9kYWwucHJvdG90eXBlLmFkanVzdERpYWxvZyA9IGZ1bmN0aW9uICgpIHtcbiAgICB2YXIgbW9kYWxJc092ZXJmbG93aW5nID0gdGhpcy4kZWxlbWVudFswXS5zY3JvbGxIZWlnaHQgPiBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQuY2xpZW50SGVpZ2h0XG5cbiAgICB0aGlzLiRlbGVtZW50LmNzcyh7XG4gICAgICBwYWRkaW5nTGVmdDogICF0aGlzLmJvZHlJc092ZXJmbG93aW5nICYmIG1vZGFsSXNPdmVyZmxvd2luZyA/IHRoaXMuc2Nyb2xsYmFyV2lkdGggOiAnJyxcbiAgICAgIHBhZGRpbmdSaWdodDogdGhpcy5ib2R5SXNPdmVyZmxvd2luZyAmJiAhbW9kYWxJc092ZXJmbG93aW5nID8gdGhpcy5zY3JvbGxiYXJXaWR0aCA6ICcnXG4gICAgfSlcbiAgfVxuXG4gIE1vZGFsLnByb3RvdHlwZS5yZXNldEFkanVzdG1lbnRzID0gZnVuY3Rpb24gKCkge1xuICAgIHRoaXMuJGVsZW1lbnQuY3NzKHtcbiAgICAgIHBhZGRpbmdMZWZ0OiAnJyxcbiAgICAgIHBhZGRpbmdSaWdodDogJydcbiAgICB9KVxuICB9XG5cbiAgTW9kYWwucHJvdG90eXBlLmNoZWNrU2Nyb2xsYmFyID0gZnVuY3Rpb24gKCkge1xuICAgIHZhciBmdWxsV2luZG93V2lkdGggPSB3aW5kb3cuaW5uZXJXaWR0aFxuICAgIGlmICghZnVsbFdpbmRvd1dpZHRoKSB7IC8vIHdvcmthcm91bmQgZm9yIG1pc3Npbmcgd2luZG93LmlubmVyV2lkdGggaW4gSUU4XG4gICAgICB2YXIgZG9jdW1lbnRFbGVtZW50UmVjdCA9IGRvY3VtZW50LmRvY3VtZW50RWxlbWVudC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKVxuICAgICAgZnVsbFdpbmRvd1dpZHRoID0gZG9jdW1lbnRFbGVtZW50UmVjdC5yaWdodCAtIE1hdGguYWJzKGRvY3VtZW50RWxlbWVudFJlY3QubGVmdClcbiAgICB9XG4gICAgdGhpcy5ib2R5SXNPdmVyZmxvd2luZyA9IGRvY3VtZW50LmJvZHkuY2xpZW50V2lkdGggPCBmdWxsV2luZG93V2lkdGhcbiAgICB0aGlzLnNjcm9sbGJhcldpZHRoID0gdGhpcy5tZWFzdXJlU2Nyb2xsYmFyKClcbiAgfVxuXG4gIE1vZGFsLnByb3RvdHlwZS5zZXRTY3JvbGxiYXIgPSBmdW5jdGlvbiAoKSB7XG4gICAgdmFyIGJvZHlQYWQgPSBwYXJzZUludCgodGhpcy4kYm9keS5jc3MoJ3BhZGRpbmctcmlnaHQnKSB8fCAwKSwgMTApXG4gICAgdGhpcy5vcmlnaW5hbEJvZHlQYWQgPSBkb2N1bWVudC5ib2R5LnN0eWxlLnBhZGRpbmdSaWdodCB8fCAnJ1xuICAgIGlmICh0aGlzLmJvZHlJc092ZXJmbG93aW5nKSB0aGlzLiRib2R5LmNzcygncGFkZGluZy1yaWdodCcsIGJvZHlQYWQgKyB0aGlzLnNjcm9sbGJhcldpZHRoKVxuICB9XG5cbiAgTW9kYWwucHJvdG90eXBlLnJlc2V0U2Nyb2xsYmFyID0gZnVuY3Rpb24gKCkge1xuICAgIHRoaXMuJGJvZHkuY3NzKCdwYWRkaW5nLXJpZ2h0JywgdGhpcy5vcmlnaW5hbEJvZHlQYWQpXG4gIH1cblxuICBNb2RhbC5wcm90b3R5cGUubWVhc3VyZVNjcm9sbGJhciA9IGZ1bmN0aW9uICgpIHsgLy8gdGh4IHdhbHNoXG4gICAgdmFyIHNjcm9sbERpdiA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpXG4gICAgc2Nyb2xsRGl2LmNsYXNzTmFtZSA9ICdtb2RhbC1zY3JvbGxiYXItbWVhc3VyZSdcbiAgICB0aGlzLiRib2R5LmFwcGVuZChzY3JvbGxEaXYpXG4gICAgdmFyIHNjcm9sbGJhcldpZHRoID0gc2Nyb2xsRGl2Lm9mZnNldFdpZHRoIC0gc2Nyb2xsRGl2LmNsaWVudFdpZHRoXG4gICAgdGhpcy4kYm9keVswXS5yZW1vdmVDaGlsZChzY3JvbGxEaXYpXG4gICAgcmV0dXJuIHNjcm9sbGJhcldpZHRoXG4gIH1cblxuXG4gIC8vIE1PREFMIFBMVUdJTiBERUZJTklUSU9OXG4gIC8vID09PT09PT09PT09PT09PT09PT09PT09XG5cbiAgZnVuY3Rpb24gUGx1Z2luKG9wdGlvbiwgX3JlbGF0ZWRUYXJnZXQpIHtcbiAgICByZXR1cm4gdGhpcy5lYWNoKGZ1bmN0aW9uICgpIHtcbiAgICAgIHZhciAkdGhpcyAgID0gJCh0aGlzKVxuICAgICAgdmFyIGRhdGEgICAgPSAkdGhpcy5kYXRhKCdicy5tb2RhbCcpXG4gICAgICB2YXIgb3B0aW9ucyA9ICQuZXh0ZW5kKHt9LCBNb2RhbC5ERUZBVUxUUywgJHRoaXMuZGF0YSgpLCB0eXBlb2Ygb3B0aW9uID09ICdvYmplY3QnICYmIG9wdGlvbilcblxuICAgICAgaWYgKCFkYXRhKSAkdGhpcy5kYXRhKCdicy5tb2RhbCcsIChkYXRhID0gbmV3IE1vZGFsKHRoaXMsIG9wdGlvbnMpKSlcbiAgICAgIGlmICh0eXBlb2Ygb3B0aW9uID09ICdzdHJpbmcnKSBkYXRhW29wdGlvbl0oX3JlbGF0ZWRUYXJnZXQpXG4gICAgICBlbHNlIGlmIChvcHRpb25zLnNob3cpIGRhdGEuc2hvdyhfcmVsYXRlZFRhcmdldClcbiAgICB9KVxuICB9XG5cbiAgdmFyIG9sZCA9ICQuZm4ubW9kYWxcblxuICAkLmZuLm1vZGFsICAgICAgICAgICAgID0gUGx1Z2luXG4gICQuZm4ubW9kYWwuQ29uc3RydWN0b3IgPSBNb2RhbFxuXG5cbiAgLy8gTU9EQUwgTk8gQ09ORkxJQ1RcbiAgLy8gPT09PT09PT09PT09PT09PT1cblxuICAkLmZuLm1vZGFsLm5vQ29uZmxpY3QgPSBmdW5jdGlvbiAoKSB7XG4gICAgJC5mbi5tb2RhbCA9IG9sZFxuICAgIHJldHVybiB0aGlzXG4gIH1cblxuXG4gIC8vIE1PREFMIERBVEEtQVBJXG4gIC8vID09PT09PT09PT09PT09XG5cbiAgJChkb2N1bWVudCkub24oJ2NsaWNrLmJzLm1vZGFsLmRhdGEtYXBpJywgJ1tkYXRhLXRvZ2dsZT1cIm1vZGFsXCJdJywgZnVuY3Rpb24gKGUpIHtcbiAgICB2YXIgJHRoaXMgICA9ICQodGhpcylcbiAgICB2YXIgaHJlZiAgICA9ICR0aGlzLmF0dHIoJ2hyZWYnKVxuICAgIHZhciAkdGFyZ2V0ID0gJCgkdGhpcy5hdHRyKCdkYXRhLXRhcmdldCcpIHx8IChocmVmICYmIGhyZWYucmVwbGFjZSgvLiooPz0jW15cXHNdKyQpLywgJycpKSkgLy8gc3RyaXAgZm9yIGllN1xuICAgIHZhciBvcHRpb24gID0gJHRhcmdldC5kYXRhKCdicy5tb2RhbCcpID8gJ3RvZ2dsZScgOiAkLmV4dGVuZCh7IHJlbW90ZTogIS8jLy50ZXN0KGhyZWYpICYmIGhyZWYgfSwgJHRhcmdldC5kYXRhKCksICR0aGlzLmRhdGEoKSlcblxuICAgIGlmICgkdGhpcy5pcygnYScpKSBlLnByZXZlbnREZWZhdWx0KClcblxuICAgICR0YXJnZXQub25lKCdzaG93LmJzLm1vZGFsJywgZnVuY3Rpb24gKHNob3dFdmVudCkge1xuICAgICAgaWYgKHNob3dFdmVudC5pc0RlZmF1bHRQcmV2ZW50ZWQoKSkgcmV0dXJuIC8vIG9ubHkgcmVnaXN0ZXIgZm9jdXMgcmVzdG9yZXIgaWYgbW9kYWwgd2lsbCBhY3R1YWxseSBnZXQgc2hvd25cbiAgICAgICR0YXJnZXQub25lKCdoaWRkZW4uYnMubW9kYWwnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICR0aGlzLmlzKCc6dmlzaWJsZScpICYmICR0aGlzLnRyaWdnZXIoJ2ZvY3VzJylcbiAgICAgIH0pXG4gICAgfSlcbiAgICBQbHVnaW4uY2FsbCgkdGFyZ2V0LCBvcHRpb24sIHRoaXMpXG4gIH0pXG5cbn0oalF1ZXJ5KTtcblxuLyogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4gKiBCb290c3RyYXA6IHRvb2x0aXAuanMgdjMuMy40XG4gKiBodHRwOi8vZ2V0Ym9vdHN0cmFwLmNvbS9qYXZhc2NyaXB0LyN0b29sdGlwXG4gKiBJbnNwaXJlZCBieSB0aGUgb3JpZ2luYWwgalF1ZXJ5LnRpcHN5IGJ5IEphc29uIEZyYW1lXG4gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAqIENvcHlyaWdodCAyMDExLTIwMTUgVHdpdHRlciwgSW5jLlxuICogTGljZW5zZWQgdW5kZXIgTUlUIChodHRwczovL2dpdGh1Yi5jb20vdHdicy9ib290c3RyYXAvYmxvYi9tYXN0ZXIvTElDRU5TRSlcbiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PSAqL1xuXG5cbitmdW5jdGlvbiAoJCkge1xuICAndXNlIHN0cmljdCc7XG5cbiAgLy8gVE9PTFRJUCBQVUJMSUMgQ0xBU1MgREVGSU5JVElPTlxuICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG5cbiAgdmFyIFRvb2x0aXAgPSBmdW5jdGlvbiAoZWxlbWVudCwgb3B0aW9ucykge1xuICAgIHRoaXMudHlwZSAgICAgICA9IG51bGxcbiAgICB0aGlzLm9wdGlvbnMgICAgPSBudWxsXG4gICAgdGhpcy5lbmFibGVkICAgID0gbnVsbFxuICAgIHRoaXMudGltZW91dCAgICA9IG51bGxcbiAgICB0aGlzLmhvdmVyU3RhdGUgPSBudWxsXG4gICAgdGhpcy4kZWxlbWVudCAgID0gbnVsbFxuXG4gICAgdGhpcy5pbml0KCd0b29sdGlwJywgZWxlbWVudCwgb3B0aW9ucylcbiAgfVxuXG4gIFRvb2x0aXAuVkVSU0lPTiAgPSAnMy4zLjQnXG5cbiAgVG9vbHRpcC5UUkFOU0lUSU9OX0RVUkFUSU9OID0gMTUwXG5cbiAgVG9vbHRpcC5ERUZBVUxUUyA9IHtcbiAgICBhbmltYXRpb246IHRydWUsXG4gICAgcGxhY2VtZW50OiAndG9wJyxcbiAgICBzZWxlY3RvcjogZmFsc2UsXG4gICAgdGVtcGxhdGU6ICc8ZGl2IGNsYXNzPVwidG9vbHRpcFwiIHJvbGU9XCJ0b29sdGlwXCI+PGRpdiBjbGFzcz1cInRvb2x0aXAtYXJyb3dcIj48L2Rpdj48ZGl2IGNsYXNzPVwidG9vbHRpcC1pbm5lclwiPjwvZGl2PjwvZGl2PicsXG4gICAgdHJpZ2dlcjogJ2hvdmVyIGZvY3VzJyxcbiAgICB0aXRsZTogJycsXG4gICAgZGVsYXk6IDAsXG4gICAgaHRtbDogZmFsc2UsXG4gICAgY29udGFpbmVyOiBmYWxzZSxcbiAgICB2aWV3cG9ydDoge1xuICAgICAgc2VsZWN0b3I6ICdib2R5JyxcbiAgICAgIHBhZGRpbmc6IDBcbiAgICB9XG4gIH1cblxuICBUb29sdGlwLnByb3RvdHlwZS5pbml0ID0gZnVuY3Rpb24gKHR5cGUsIGVsZW1lbnQsIG9wdGlvbnMpIHtcbiAgICB0aGlzLmVuYWJsZWQgICA9IHRydWVcbiAgICB0aGlzLnR5cGUgICAgICA9IHR5cGVcbiAgICB0aGlzLiRlbGVtZW50ICA9ICQoZWxlbWVudClcbiAgICB0aGlzLm9wdGlvbnMgICA9IHRoaXMuZ2V0T3B0aW9ucyhvcHRpb25zKVxuICAgIHRoaXMuJHZpZXdwb3J0ID0gdGhpcy5vcHRpb25zLnZpZXdwb3J0ICYmICQodGhpcy5vcHRpb25zLnZpZXdwb3J0LnNlbGVjdG9yIHx8IHRoaXMub3B0aW9ucy52aWV3cG9ydClcblxuICAgIGlmICh0aGlzLiRlbGVtZW50WzBdIGluc3RhbmNlb2YgZG9jdW1lbnQuY29uc3RydWN0b3IgJiYgIXRoaXMub3B0aW9ucy5zZWxlY3Rvcikge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdgc2VsZWN0b3JgIG9wdGlvbiBtdXN0IGJlIHNwZWNpZmllZCB3aGVuIGluaXRpYWxpemluZyAnICsgdGhpcy50eXBlICsgJyBvbiB0aGUgd2luZG93LmRvY3VtZW50IG9iamVjdCEnKVxuICAgIH1cblxuICAgIHZhciB0cmlnZ2VycyA9IHRoaXMub3B0aW9ucy50cmlnZ2VyLnNwbGl0KCcgJylcblxuICAgIGZvciAodmFyIGkgPSB0cmlnZ2Vycy5sZW5ndGg7IGktLTspIHtcbiAgICAgIHZhciB0cmlnZ2VyID0gdHJpZ2dlcnNbaV1cblxuICAgICAgaWYgKHRyaWdnZXIgPT0gJ2NsaWNrJykge1xuICAgICAgICB0aGlzLiRlbGVtZW50Lm9uKCdjbGljay4nICsgdGhpcy50eXBlLCB0aGlzLm9wdGlvbnMuc2VsZWN0b3IsICQucHJveHkodGhpcy50b2dnbGUsIHRoaXMpKVxuICAgICAgfSBlbHNlIGlmICh0cmlnZ2VyICE9ICdtYW51YWwnKSB7XG4gICAgICAgIHZhciBldmVudEluICA9IHRyaWdnZXIgPT0gJ2hvdmVyJyA/ICdtb3VzZWVudGVyJyA6ICdmb2N1c2luJ1xuICAgICAgICB2YXIgZXZlbnRPdXQgPSB0cmlnZ2VyID09ICdob3ZlcicgPyAnbW91c2VsZWF2ZScgOiAnZm9jdXNvdXQnXG5cbiAgICAgICAgdGhpcy4kZWxlbWVudC5vbihldmVudEluICArICcuJyArIHRoaXMudHlwZSwgdGhpcy5vcHRpb25zLnNlbGVjdG9yLCAkLnByb3h5KHRoaXMuZW50ZXIsIHRoaXMpKVxuICAgICAgICB0aGlzLiRlbGVtZW50Lm9uKGV2ZW50T3V0ICsgJy4nICsgdGhpcy50eXBlLCB0aGlzLm9wdGlvbnMuc2VsZWN0b3IsICQucHJveHkodGhpcy5sZWF2ZSwgdGhpcykpXG4gICAgICB9XG4gICAgfVxuXG4gICAgdGhpcy5vcHRpb25zLnNlbGVjdG9yID9cbiAgICAgICh0aGlzLl9vcHRpb25zID0gJC5leHRlbmQoe30sIHRoaXMub3B0aW9ucywgeyB0cmlnZ2VyOiAnbWFudWFsJywgc2VsZWN0b3I6ICcnIH0pKSA6XG4gICAgICB0aGlzLmZpeFRpdGxlKClcbiAgfVxuXG4gIFRvb2x0aXAucHJvdG90eXBlLmdldERlZmF1bHRzID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiBUb29sdGlwLkRFRkFVTFRTXG4gIH1cblxuICBUb29sdGlwLnByb3RvdHlwZS5nZXRPcHRpb25zID0gZnVuY3Rpb24gKG9wdGlvbnMpIHtcbiAgICBvcHRpb25zID0gJC5leHRlbmQoe30sIHRoaXMuZ2V0RGVmYXVsdHMoKSwgdGhpcy4kZWxlbWVudC5kYXRhKCksIG9wdGlvbnMpXG5cbiAgICBpZiAob3B0aW9ucy5kZWxheSAmJiB0eXBlb2Ygb3B0aW9ucy5kZWxheSA9PSAnbnVtYmVyJykge1xuICAgICAgb3B0aW9ucy5kZWxheSA9IHtcbiAgICAgICAgc2hvdzogb3B0aW9ucy5kZWxheSxcbiAgICAgICAgaGlkZTogb3B0aW9ucy5kZWxheVxuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBvcHRpb25zXG4gIH1cblxuICBUb29sdGlwLnByb3RvdHlwZS5nZXREZWxlZ2F0ZU9wdGlvbnMgPSBmdW5jdGlvbiAoKSB7XG4gICAgdmFyIG9wdGlvbnMgID0ge31cbiAgICB2YXIgZGVmYXVsdHMgPSB0aGlzLmdldERlZmF1bHRzKClcblxuICAgIHRoaXMuX29wdGlvbnMgJiYgJC5lYWNoKHRoaXMuX29wdGlvbnMsIGZ1bmN0aW9uIChrZXksIHZhbHVlKSB7XG4gICAgICBpZiAoZGVmYXVsdHNba2V5XSAhPSB2YWx1ZSkgb3B0aW9uc1trZXldID0gdmFsdWVcbiAgICB9KVxuXG4gICAgcmV0dXJuIG9wdGlvbnNcbiAgfVxuXG4gIFRvb2x0aXAucHJvdG90eXBlLmVudGVyID0gZnVuY3Rpb24gKG9iaikge1xuICAgIHZhciBzZWxmID0gb2JqIGluc3RhbmNlb2YgdGhpcy5jb25zdHJ1Y3RvciA/XG4gICAgICBvYmogOiAkKG9iai5jdXJyZW50VGFyZ2V0KS5kYXRhKCdicy4nICsgdGhpcy50eXBlKVxuXG4gICAgaWYgKHNlbGYgJiYgc2VsZi4kdGlwICYmIHNlbGYuJHRpcC5pcygnOnZpc2libGUnKSkge1xuICAgICAgc2VsZi5ob3ZlclN0YXRlID0gJ2luJ1xuICAgICAgcmV0dXJuXG4gICAgfVxuXG4gICAgaWYgKCFzZWxmKSB7XG4gICAgICBzZWxmID0gbmV3IHRoaXMuY29uc3RydWN0b3Iob2JqLmN1cnJlbnRUYXJnZXQsIHRoaXMuZ2V0RGVsZWdhdGVPcHRpb25zKCkpXG4gICAgICAkKG9iai5jdXJyZW50VGFyZ2V0KS5kYXRhKCdicy4nICsgdGhpcy50eXBlLCBzZWxmKVxuICAgIH1cblxuICAgIGNsZWFyVGltZW91dChzZWxmLnRpbWVvdXQpXG5cbiAgICBzZWxmLmhvdmVyU3RhdGUgPSAnaW4nXG5cbiAgICBpZiAoIXNlbGYub3B0aW9ucy5kZWxheSB8fCAhc2VsZi5vcHRpb25zLmRlbGF5LnNob3cpIHJldHVybiBzZWxmLnNob3coKVxuXG4gICAgc2VsZi50aW1lb3V0ID0gc2V0VGltZW91dChmdW5jdGlvbiAoKSB7XG4gICAgICBpZiAoc2VsZi5ob3ZlclN0YXRlID09ICdpbicpIHNlbGYuc2hvdygpXG4gICAgfSwgc2VsZi5vcHRpb25zLmRlbGF5LnNob3cpXG4gIH1cblxuICBUb29sdGlwLnByb3RvdHlwZS5sZWF2ZSA9IGZ1bmN0aW9uIChvYmopIHtcbiAgICB2YXIgc2VsZiA9IG9iaiBpbnN0YW5jZW9mIHRoaXMuY29uc3RydWN0b3IgP1xuICAgICAgb2JqIDogJChvYmouY3VycmVudFRhcmdldCkuZGF0YSgnYnMuJyArIHRoaXMudHlwZSlcblxuICAgIGlmICghc2VsZikge1xuICAgICAgc2VsZiA9IG5ldyB0aGlzLmNvbnN0cnVjdG9yKG9iai5jdXJyZW50VGFyZ2V0LCB0aGlzLmdldERlbGVnYXRlT3B0aW9ucygpKVxuICAgICAgJChvYmouY3VycmVudFRhcmdldCkuZGF0YSgnYnMuJyArIHRoaXMudHlwZSwgc2VsZilcbiAgICB9XG5cbiAgICBjbGVhclRpbWVvdXQoc2VsZi50aW1lb3V0KVxuXG4gICAgc2VsZi5ob3ZlclN0YXRlID0gJ291dCdcblxuICAgIGlmICghc2VsZi5vcHRpb25zLmRlbGF5IHx8ICFzZWxmLm9wdGlvbnMuZGVsYXkuaGlkZSkgcmV0dXJuIHNlbGYuaGlkZSgpXG5cbiAgICBzZWxmLnRpbWVvdXQgPSBzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHtcbiAgICAgIGlmIChzZWxmLmhvdmVyU3RhdGUgPT0gJ291dCcpIHNlbGYuaGlkZSgpXG4gICAgfSwgc2VsZi5vcHRpb25zLmRlbGF5LmhpZGUpXG4gIH1cblxuICBUb29sdGlwLnByb3RvdHlwZS5zaG93ID0gZnVuY3Rpb24gKCkge1xuICAgIHZhciBlID0gJC5FdmVudCgnc2hvdy5icy4nICsgdGhpcy50eXBlKVxuXG4gICAgaWYgKHRoaXMuaGFzQ29udGVudCgpICYmIHRoaXMuZW5hYmxlZCkge1xuICAgICAgdGhpcy4kZWxlbWVudC50cmlnZ2VyKGUpXG5cbiAgICAgIHZhciBpbkRvbSA9ICQuY29udGFpbnModGhpcy4kZWxlbWVudFswXS5vd25lckRvY3VtZW50LmRvY3VtZW50RWxlbWVudCwgdGhpcy4kZWxlbWVudFswXSlcbiAgICAgIGlmIChlLmlzRGVmYXVsdFByZXZlbnRlZCgpIHx8ICFpbkRvbSkgcmV0dXJuXG4gICAgICB2YXIgdGhhdCA9IHRoaXNcblxuICAgICAgdmFyICR0aXAgPSB0aGlzLnRpcCgpXG5cbiAgICAgIHZhciB0aXBJZCA9IHRoaXMuZ2V0VUlEKHRoaXMudHlwZSlcblxuICAgICAgdGhpcy5zZXRDb250ZW50KClcbiAgICAgICR0aXAuYXR0cignaWQnLCB0aXBJZClcbiAgICAgIHRoaXMuJGVsZW1lbnQuYXR0cignYXJpYS1kZXNjcmliZWRieScsIHRpcElkKVxuXG4gICAgICBpZiAodGhpcy5vcHRpb25zLmFuaW1hdGlvbikgJHRpcC5hZGRDbGFzcygnZmFkZScpXG5cbiAgICAgIHZhciBwbGFjZW1lbnQgPSB0eXBlb2YgdGhpcy5vcHRpb25zLnBsYWNlbWVudCA9PSAnZnVuY3Rpb24nID9cbiAgICAgICAgdGhpcy5vcHRpb25zLnBsYWNlbWVudC5jYWxsKHRoaXMsICR0aXBbMF0sIHRoaXMuJGVsZW1lbnRbMF0pIDpcbiAgICAgICAgdGhpcy5vcHRpb25zLnBsYWNlbWVudFxuXG4gICAgICB2YXIgYXV0b1Rva2VuID0gL1xccz9hdXRvP1xccz8vaVxuICAgICAgdmFyIGF1dG9QbGFjZSA9IGF1dG9Ub2tlbi50ZXN0KHBsYWNlbWVudClcbiAgICAgIGlmIChhdXRvUGxhY2UpIHBsYWNlbWVudCA9IHBsYWNlbWVudC5yZXBsYWNlKGF1dG9Ub2tlbiwgJycpIHx8ICd0b3AnXG5cbiAgICAgICR0aXBcbiAgICAgICAgLmRldGFjaCgpXG4gICAgICAgIC5jc3MoeyB0b3A6IDAsIGxlZnQ6IDAsIGRpc3BsYXk6ICdibG9jaycgfSlcbiAgICAgICAgLmFkZENsYXNzKHBsYWNlbWVudClcbiAgICAgICAgLmRhdGEoJ2JzLicgKyB0aGlzLnR5cGUsIHRoaXMpXG5cbiAgICAgIHRoaXMub3B0aW9ucy5jb250YWluZXIgPyAkdGlwLmFwcGVuZFRvKHRoaXMub3B0aW9ucy5jb250YWluZXIpIDogJHRpcC5pbnNlcnRBZnRlcih0aGlzLiRlbGVtZW50KVxuXG4gICAgICB2YXIgcG9zICAgICAgICAgID0gdGhpcy5nZXRQb3NpdGlvbigpXG4gICAgICB2YXIgYWN0dWFsV2lkdGggID0gJHRpcFswXS5vZmZzZXRXaWR0aFxuICAgICAgdmFyIGFjdHVhbEhlaWdodCA9ICR0aXBbMF0ub2Zmc2V0SGVpZ2h0XG5cbiAgICAgIGlmIChhdXRvUGxhY2UpIHtcbiAgICAgICAgdmFyIG9yZ1BsYWNlbWVudCA9IHBsYWNlbWVudFxuICAgICAgICB2YXIgJGNvbnRhaW5lciAgID0gdGhpcy5vcHRpb25zLmNvbnRhaW5lciA/ICQodGhpcy5vcHRpb25zLmNvbnRhaW5lcikgOiB0aGlzLiRlbGVtZW50LnBhcmVudCgpXG4gICAgICAgIHZhciBjb250YWluZXJEaW0gPSB0aGlzLmdldFBvc2l0aW9uKCRjb250YWluZXIpXG5cbiAgICAgICAgcGxhY2VtZW50ID0gcGxhY2VtZW50ID09ICdib3R0b20nICYmIHBvcy5ib3R0b20gKyBhY3R1YWxIZWlnaHQgPiBjb250YWluZXJEaW0uYm90dG9tID8gJ3RvcCcgICAgOlxuICAgICAgICAgICAgICAgICAgICBwbGFjZW1lbnQgPT0gJ3RvcCcgICAgJiYgcG9zLnRvcCAgICAtIGFjdHVhbEhlaWdodCA8IGNvbnRhaW5lckRpbS50b3AgICAgPyAnYm90dG9tJyA6XG4gICAgICAgICAgICAgICAgICAgIHBsYWNlbWVudCA9PSAncmlnaHQnICAmJiBwb3MucmlnaHQgICsgYWN0dWFsV2lkdGggID4gY29udGFpbmVyRGltLndpZHRoICA/ICdsZWZ0JyAgIDpcbiAgICAgICAgICAgICAgICAgICAgcGxhY2VtZW50ID09ICdsZWZ0JyAgICYmIHBvcy5sZWZ0ICAgLSBhY3R1YWxXaWR0aCAgPCBjb250YWluZXJEaW0ubGVmdCAgID8gJ3JpZ2h0JyAgOlxuICAgICAgICAgICAgICAgICAgICBwbGFjZW1lbnRcblxuICAgICAgICAkdGlwXG4gICAgICAgICAgLnJlbW92ZUNsYXNzKG9yZ1BsYWNlbWVudClcbiAgICAgICAgICAuYWRkQ2xhc3MocGxhY2VtZW50KVxuICAgICAgfVxuXG4gICAgICB2YXIgY2FsY3VsYXRlZE9mZnNldCA9IHRoaXMuZ2V0Q2FsY3VsYXRlZE9mZnNldChwbGFjZW1lbnQsIHBvcywgYWN0dWFsV2lkdGgsIGFjdHVhbEhlaWdodClcblxuICAgICAgdGhpcy5hcHBseVBsYWNlbWVudChjYWxjdWxhdGVkT2Zmc2V0LCBwbGFjZW1lbnQpXG5cbiAgICAgIHZhciBjb21wbGV0ZSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIHByZXZIb3ZlclN0YXRlID0gdGhhdC5ob3ZlclN0YXRlXG4gICAgICAgIHRoYXQuJGVsZW1lbnQudHJpZ2dlcignc2hvd24uYnMuJyArIHRoYXQudHlwZSlcbiAgICAgICAgdGhhdC5ob3ZlclN0YXRlID0gbnVsbFxuXG4gICAgICAgIGlmIChwcmV2SG92ZXJTdGF0ZSA9PSAnb3V0JykgdGhhdC5sZWF2ZSh0aGF0KVxuICAgICAgfVxuXG4gICAgICAkLnN1cHBvcnQudHJhbnNpdGlvbiAmJiB0aGlzLiR0aXAuaGFzQ2xhc3MoJ2ZhZGUnKSA/XG4gICAgICAgICR0aXBcbiAgICAgICAgICAub25lKCdic1RyYW5zaXRpb25FbmQnLCBjb21wbGV0ZSlcbiAgICAgICAgICAuZW11bGF0ZVRyYW5zaXRpb25FbmQoVG9vbHRpcC5UUkFOU0lUSU9OX0RVUkFUSU9OKSA6XG4gICAgICAgIGNvbXBsZXRlKClcbiAgICB9XG4gIH1cblxuICBUb29sdGlwLnByb3RvdHlwZS5hcHBseVBsYWNlbWVudCA9IGZ1bmN0aW9uIChvZmZzZXQsIHBsYWNlbWVudCkge1xuICAgIHZhciAkdGlwICAgPSB0aGlzLnRpcCgpXG4gICAgdmFyIHdpZHRoICA9ICR0aXBbMF0ub2Zmc2V0V2lkdGhcbiAgICB2YXIgaGVpZ2h0ID0gJHRpcFswXS5vZmZzZXRIZWlnaHRcblxuICAgIC8vIG1hbnVhbGx5IHJlYWQgbWFyZ2lucyBiZWNhdXNlIGdldEJvdW5kaW5nQ2xpZW50UmVjdCBpbmNsdWRlcyBkaWZmZXJlbmNlXG4gICAgdmFyIG1hcmdpblRvcCA9IHBhcnNlSW50KCR0aXAuY3NzKCdtYXJnaW4tdG9wJyksIDEwKVxuICAgIHZhciBtYXJnaW5MZWZ0ID0gcGFyc2VJbnQoJHRpcC5jc3MoJ21hcmdpbi1sZWZ0JyksIDEwKVxuXG4gICAgLy8gd2UgbXVzdCBjaGVjayBmb3IgTmFOIGZvciBpZSA4LzlcbiAgICBpZiAoaXNOYU4obWFyZ2luVG9wKSkgIG1hcmdpblRvcCAgPSAwXG4gICAgaWYgKGlzTmFOKG1hcmdpbkxlZnQpKSBtYXJnaW5MZWZ0ID0gMFxuXG4gICAgb2Zmc2V0LnRvcCAgPSBvZmZzZXQudG9wICArIG1hcmdpblRvcFxuICAgIG9mZnNldC5sZWZ0ID0gb2Zmc2V0LmxlZnQgKyBtYXJnaW5MZWZ0XG5cbiAgICAvLyAkLmZuLm9mZnNldCBkb2Vzbid0IHJvdW5kIHBpeGVsIHZhbHVlc1xuICAgIC8vIHNvIHdlIHVzZSBzZXRPZmZzZXQgZGlyZWN0bHkgd2l0aCBvdXIgb3duIGZ1bmN0aW9uIEItMFxuICAgICQub2Zmc2V0LnNldE9mZnNldCgkdGlwWzBdLCAkLmV4dGVuZCh7XG4gICAgICB1c2luZzogZnVuY3Rpb24gKHByb3BzKSB7XG4gICAgICAgICR0aXAuY3NzKHtcbiAgICAgICAgICB0b3A6IE1hdGgucm91bmQocHJvcHMudG9wKSxcbiAgICAgICAgICBsZWZ0OiBNYXRoLnJvdW5kKHByb3BzLmxlZnQpXG4gICAgICAgIH0pXG4gICAgICB9XG4gICAgfSwgb2Zmc2V0KSwgMClcblxuICAgICR0aXAuYWRkQ2xhc3MoJ2luJylcblxuICAgIC8vIGNoZWNrIHRvIHNlZSBpZiBwbGFjaW5nIHRpcCBpbiBuZXcgb2Zmc2V0IGNhdXNlZCB0aGUgdGlwIHRvIHJlc2l6ZSBpdHNlbGZcbiAgICB2YXIgYWN0dWFsV2lkdGggID0gJHRpcFswXS5vZmZzZXRXaWR0aFxuICAgIHZhciBhY3R1YWxIZWlnaHQgPSAkdGlwWzBdLm9mZnNldEhlaWdodFxuXG4gICAgaWYgKHBsYWNlbWVudCA9PSAndG9wJyAmJiBhY3R1YWxIZWlnaHQgIT0gaGVpZ2h0KSB7XG4gICAgICBvZmZzZXQudG9wID0gb2Zmc2V0LnRvcCArIGhlaWdodCAtIGFjdHVhbEhlaWdodFxuICAgIH1cblxuICAgIHZhciBkZWx0YSA9IHRoaXMuZ2V0Vmlld3BvcnRBZGp1c3RlZERlbHRhKHBsYWNlbWVudCwgb2Zmc2V0LCBhY3R1YWxXaWR0aCwgYWN0dWFsSGVpZ2h0KVxuXG4gICAgaWYgKGRlbHRhLmxlZnQpIG9mZnNldC5sZWZ0ICs9IGRlbHRhLmxlZnRcbiAgICBlbHNlIG9mZnNldC50b3AgKz0gZGVsdGEudG9wXG5cbiAgICB2YXIgaXNWZXJ0aWNhbCAgICAgICAgICA9IC90b3B8Ym90dG9tLy50ZXN0KHBsYWNlbWVudClcbiAgICB2YXIgYXJyb3dEZWx0YSAgICAgICAgICA9IGlzVmVydGljYWwgPyBkZWx0YS5sZWZ0ICogMiAtIHdpZHRoICsgYWN0dWFsV2lkdGggOiBkZWx0YS50b3AgKiAyIC0gaGVpZ2h0ICsgYWN0dWFsSGVpZ2h0XG4gICAgdmFyIGFycm93T2Zmc2V0UG9zaXRpb24gPSBpc1ZlcnRpY2FsID8gJ29mZnNldFdpZHRoJyA6ICdvZmZzZXRIZWlnaHQnXG5cbiAgICAkdGlwLm9mZnNldChvZmZzZXQpXG4gICAgdGhpcy5yZXBsYWNlQXJyb3coYXJyb3dEZWx0YSwgJHRpcFswXVthcnJvd09mZnNldFBvc2l0aW9uXSwgaXNWZXJ0aWNhbClcbiAgfVxuXG4gIFRvb2x0aXAucHJvdG90eXBlLnJlcGxhY2VBcnJvdyA9IGZ1bmN0aW9uIChkZWx0YSwgZGltZW5zaW9uLCBpc1ZlcnRpY2FsKSB7XG4gICAgdGhpcy5hcnJvdygpXG4gICAgICAuY3NzKGlzVmVydGljYWwgPyAnbGVmdCcgOiAndG9wJywgNTAgKiAoMSAtIGRlbHRhIC8gZGltZW5zaW9uKSArICclJylcbiAgICAgIC5jc3MoaXNWZXJ0aWNhbCA/ICd0b3AnIDogJ2xlZnQnLCAnJylcbiAgfVxuXG4gIFRvb2x0aXAucHJvdG90eXBlLnNldENvbnRlbnQgPSBmdW5jdGlvbiAoKSB7XG4gICAgdmFyICR0aXAgID0gdGhpcy50aXAoKVxuICAgIHZhciB0aXRsZSA9IHRoaXMuZ2V0VGl0bGUoKVxuXG4gICAgJHRpcC5maW5kKCcudG9vbHRpcC1pbm5lcicpW3RoaXMub3B0aW9ucy5odG1sID8gJ2h0bWwnIDogJ3RleHQnXSh0aXRsZSlcbiAgICAkdGlwLnJlbW92ZUNsYXNzKCdmYWRlIGluIHRvcCBib3R0b20gbGVmdCByaWdodCcpXG4gIH1cblxuICBUb29sdGlwLnByb3RvdHlwZS5oaWRlID0gZnVuY3Rpb24gKGNhbGxiYWNrKSB7XG4gICAgdmFyIHRoYXQgPSB0aGlzXG4gICAgdmFyICR0aXAgPSAkKHRoaXMuJHRpcClcbiAgICB2YXIgZSAgICA9ICQuRXZlbnQoJ2hpZGUuYnMuJyArIHRoaXMudHlwZSlcblxuICAgIGZ1bmN0aW9uIGNvbXBsZXRlKCkge1xuICAgICAgaWYgKHRoYXQuaG92ZXJTdGF0ZSAhPSAnaW4nKSAkdGlwLmRldGFjaCgpXG4gICAgICB0aGF0LiRlbGVtZW50XG4gICAgICAgIC5yZW1vdmVBdHRyKCdhcmlhLWRlc2NyaWJlZGJ5JylcbiAgICAgICAgLnRyaWdnZXIoJ2hpZGRlbi5icy4nICsgdGhhdC50eXBlKVxuICAgICAgY2FsbGJhY2sgJiYgY2FsbGJhY2soKVxuICAgIH1cblxuICAgIHRoaXMuJGVsZW1lbnQudHJpZ2dlcihlKVxuXG4gICAgaWYgKGUuaXNEZWZhdWx0UHJldmVudGVkKCkpIHJldHVyblxuXG4gICAgJHRpcC5yZW1vdmVDbGFzcygnaW4nKVxuXG4gICAgJC5zdXBwb3J0LnRyYW5zaXRpb24gJiYgJHRpcC5oYXNDbGFzcygnZmFkZScpID9cbiAgICAgICR0aXBcbiAgICAgICAgLm9uZSgnYnNUcmFuc2l0aW9uRW5kJywgY29tcGxldGUpXG4gICAgICAgIC5lbXVsYXRlVHJhbnNpdGlvbkVuZChUb29sdGlwLlRSQU5TSVRJT05fRFVSQVRJT04pIDpcbiAgICAgIGNvbXBsZXRlKClcblxuICAgIHRoaXMuaG92ZXJTdGF0ZSA9IG51bGxcblxuICAgIHJldHVybiB0aGlzXG4gIH1cblxuICBUb29sdGlwLnByb3RvdHlwZS5maXhUaXRsZSA9IGZ1bmN0aW9uICgpIHtcbiAgICB2YXIgJGUgPSB0aGlzLiRlbGVtZW50XG4gICAgaWYgKCRlLmF0dHIoJ3RpdGxlJykgfHwgdHlwZW9mICgkZS5hdHRyKCdkYXRhLW9yaWdpbmFsLXRpdGxlJykpICE9ICdzdHJpbmcnKSB7XG4gICAgICAkZS5hdHRyKCdkYXRhLW9yaWdpbmFsLXRpdGxlJywgJGUuYXR0cigndGl0bGUnKSB8fCAnJykuYXR0cigndGl0bGUnLCAnJylcbiAgICB9XG4gIH1cblxuICBUb29sdGlwLnByb3RvdHlwZS5oYXNDb250ZW50ID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiB0aGlzLmdldFRpdGxlKClcbiAgfVxuXG4gIFRvb2x0aXAucHJvdG90eXBlLmdldFBvc2l0aW9uID0gZnVuY3Rpb24gKCRlbGVtZW50KSB7XG4gICAgJGVsZW1lbnQgICA9ICRlbGVtZW50IHx8IHRoaXMuJGVsZW1lbnRcblxuICAgIHZhciBlbCAgICAgPSAkZWxlbWVudFswXVxuICAgIHZhciBpc0JvZHkgPSBlbC50YWdOYW1lID09ICdCT0RZJ1xuXG4gICAgdmFyIGVsUmVjdCAgICA9IGVsLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpXG4gICAgaWYgKGVsUmVjdC53aWR0aCA9PSBudWxsKSB7XG4gICAgICAvLyB3aWR0aCBhbmQgaGVpZ2h0IGFyZSBtaXNzaW5nIGluIElFOCwgc28gY29tcHV0ZSB0aGVtIG1hbnVhbGx5OyBzZWUgaHR0cHM6Ly9naXRodWIuY29tL3R3YnMvYm9vdHN0cmFwL2lzc3Vlcy8xNDA5M1xuICAgICAgZWxSZWN0ID0gJC5leHRlbmQoe30sIGVsUmVjdCwgeyB3aWR0aDogZWxSZWN0LnJpZ2h0IC0gZWxSZWN0LmxlZnQsIGhlaWdodDogZWxSZWN0LmJvdHRvbSAtIGVsUmVjdC50b3AgfSlcbiAgICB9XG4gICAgdmFyIGVsT2Zmc2V0ICA9IGlzQm9keSA/IHsgdG9wOiAwLCBsZWZ0OiAwIH0gOiAkZWxlbWVudC5vZmZzZXQoKVxuICAgIHZhciBzY3JvbGwgICAgPSB7IHNjcm9sbDogaXNCb2R5ID8gZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LnNjcm9sbFRvcCB8fCBkb2N1bWVudC5ib2R5LnNjcm9sbFRvcCA6ICRlbGVtZW50LnNjcm9sbFRvcCgpIH1cbiAgICB2YXIgb3V0ZXJEaW1zID0gaXNCb2R5ID8geyB3aWR0aDogJCh3aW5kb3cpLndpZHRoKCksIGhlaWdodDogJCh3aW5kb3cpLmhlaWdodCgpIH0gOiBudWxsXG5cbiAgICByZXR1cm4gJC5leHRlbmQoe30sIGVsUmVjdCwgc2Nyb2xsLCBvdXRlckRpbXMsIGVsT2Zmc2V0KVxuICB9XG5cbiAgVG9vbHRpcC5wcm90b3R5cGUuZ2V0Q2FsY3VsYXRlZE9mZnNldCA9IGZ1bmN0aW9uIChwbGFjZW1lbnQsIHBvcywgYWN0dWFsV2lkdGgsIGFjdHVhbEhlaWdodCkge1xuICAgIHJldHVybiBwbGFjZW1lbnQgPT0gJ2JvdHRvbScgPyB7IHRvcDogcG9zLnRvcCArIHBvcy5oZWlnaHQsICAgbGVmdDogcG9zLmxlZnQgKyBwb3Mud2lkdGggLyAyIC0gYWN0dWFsV2lkdGggLyAyIH0gOlxuICAgICAgICAgICBwbGFjZW1lbnQgPT0gJ3RvcCcgICAgPyB7IHRvcDogcG9zLnRvcCAtIGFjdHVhbEhlaWdodCwgbGVmdDogcG9zLmxlZnQgKyBwb3Mud2lkdGggLyAyIC0gYWN0dWFsV2lkdGggLyAyIH0gOlxuICAgICAgICAgICBwbGFjZW1lbnQgPT0gJ2xlZnQnICAgPyB7IHRvcDogcG9zLnRvcCArIHBvcy5oZWlnaHQgLyAyIC0gYWN0dWFsSGVpZ2h0IC8gMiwgbGVmdDogcG9zLmxlZnQgLSBhY3R1YWxXaWR0aCB9IDpcbiAgICAgICAgLyogcGxhY2VtZW50ID09ICdyaWdodCcgKi8geyB0b3A6IHBvcy50b3AgKyBwb3MuaGVpZ2h0IC8gMiAtIGFjdHVhbEhlaWdodCAvIDIsIGxlZnQ6IHBvcy5sZWZ0ICsgcG9zLndpZHRoIH1cblxuICB9XG5cbiAgVG9vbHRpcC5wcm90b3R5cGUuZ2V0Vmlld3BvcnRBZGp1c3RlZERlbHRhID0gZnVuY3Rpb24gKHBsYWNlbWVudCwgcG9zLCBhY3R1YWxXaWR0aCwgYWN0dWFsSGVpZ2h0KSB7XG4gICAgdmFyIGRlbHRhID0geyB0b3A6IDAsIGxlZnQ6IDAgfVxuICAgIGlmICghdGhpcy4kdmlld3BvcnQpIHJldHVybiBkZWx0YVxuXG4gICAgdmFyIHZpZXdwb3J0UGFkZGluZyA9IHRoaXMub3B0aW9ucy52aWV3cG9ydCAmJiB0aGlzLm9wdGlvbnMudmlld3BvcnQucGFkZGluZyB8fCAwXG4gICAgdmFyIHZpZXdwb3J0RGltZW5zaW9ucyA9IHRoaXMuZ2V0UG9zaXRpb24odGhpcy4kdmlld3BvcnQpXG5cbiAgICBpZiAoL3JpZ2h0fGxlZnQvLnRlc3QocGxhY2VtZW50KSkge1xuICAgICAgdmFyIHRvcEVkZ2VPZmZzZXQgICAgPSBwb3MudG9wIC0gdmlld3BvcnRQYWRkaW5nIC0gdmlld3BvcnREaW1lbnNpb25zLnNjcm9sbFxuICAgICAgdmFyIGJvdHRvbUVkZ2VPZmZzZXQgPSBwb3MudG9wICsgdmlld3BvcnRQYWRkaW5nIC0gdmlld3BvcnREaW1lbnNpb25zLnNjcm9sbCArIGFjdHVhbEhlaWdodFxuICAgICAgaWYgKHRvcEVkZ2VPZmZzZXQgPCB2aWV3cG9ydERpbWVuc2lvbnMudG9wKSB7IC8vIHRvcCBvdmVyZmxvd1xuICAgICAgICBkZWx0YS50b3AgPSB2aWV3cG9ydERpbWVuc2lvbnMudG9wIC0gdG9wRWRnZU9mZnNldFxuICAgICAgfSBlbHNlIGlmIChib3R0b21FZGdlT2Zmc2V0ID4gdmlld3BvcnREaW1lbnNpb25zLnRvcCArIHZpZXdwb3J0RGltZW5zaW9ucy5oZWlnaHQpIHsgLy8gYm90dG9tIG92ZXJmbG93XG4gICAgICAgIGRlbHRhLnRvcCA9IHZpZXdwb3J0RGltZW5zaW9ucy50b3AgKyB2aWV3cG9ydERpbWVuc2lvbnMuaGVpZ2h0IC0gYm90dG9tRWRnZU9mZnNldFxuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICB2YXIgbGVmdEVkZ2VPZmZzZXQgID0gcG9zLmxlZnQgLSB2aWV3cG9ydFBhZGRpbmdcbiAgICAgIHZhciByaWdodEVkZ2VPZmZzZXQgPSBwb3MubGVmdCArIHZpZXdwb3J0UGFkZGluZyArIGFjdHVhbFdpZHRoXG4gICAgICBpZiAobGVmdEVkZ2VPZmZzZXQgPCB2aWV3cG9ydERpbWVuc2lvbnMubGVmdCkgeyAvLyBsZWZ0IG92ZXJmbG93XG4gICAgICAgIGRlbHRhLmxlZnQgPSB2aWV3cG9ydERpbWVuc2lvbnMubGVmdCAtIGxlZnRFZGdlT2Zmc2V0XG4gICAgICB9IGVsc2UgaWYgKHJpZ2h0RWRnZU9mZnNldCA+IHZpZXdwb3J0RGltZW5zaW9ucy53aWR0aCkgeyAvLyByaWdodCBvdmVyZmxvd1xuICAgICAgICBkZWx0YS5sZWZ0ID0gdmlld3BvcnREaW1lbnNpb25zLmxlZnQgKyB2aWV3cG9ydERpbWVuc2lvbnMud2lkdGggLSByaWdodEVkZ2VPZmZzZXRcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gZGVsdGFcbiAgfVxuXG4gIFRvb2x0aXAucHJvdG90eXBlLmdldFRpdGxlID0gZnVuY3Rpb24gKCkge1xuICAgIHZhciB0aXRsZVxuICAgIHZhciAkZSA9IHRoaXMuJGVsZW1lbnRcbiAgICB2YXIgbyAgPSB0aGlzLm9wdGlvbnNcblxuICAgIHRpdGxlID0gJGUuYXR0cignZGF0YS1vcmlnaW5hbC10aXRsZScpXG4gICAgICB8fCAodHlwZW9mIG8udGl0bGUgPT0gJ2Z1bmN0aW9uJyA/IG8udGl0bGUuY2FsbCgkZVswXSkgOiAgby50aXRsZSlcblxuICAgIHJldHVybiB0aXRsZVxuICB9XG5cbiAgVG9vbHRpcC5wcm90b3R5cGUuZ2V0VUlEID0gZnVuY3Rpb24gKHByZWZpeCkge1xuICAgIGRvIHByZWZpeCArPSB+fihNYXRoLnJhbmRvbSgpICogMTAwMDAwMClcbiAgICB3aGlsZSAoZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQocHJlZml4KSlcbiAgICByZXR1cm4gcHJlZml4XG4gIH1cblxuICBUb29sdGlwLnByb3RvdHlwZS50aXAgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuICh0aGlzLiR0aXAgPSB0aGlzLiR0aXAgfHwgJCh0aGlzLm9wdGlvbnMudGVtcGxhdGUpKVxuICB9XG5cbiAgVG9vbHRpcC5wcm90b3R5cGUuYXJyb3cgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuICh0aGlzLiRhcnJvdyA9IHRoaXMuJGFycm93IHx8IHRoaXMudGlwKCkuZmluZCgnLnRvb2x0aXAtYXJyb3cnKSlcbiAgfVxuXG4gIFRvb2x0aXAucHJvdG90eXBlLmVuYWJsZSA9IGZ1bmN0aW9uICgpIHtcbiAgICB0aGlzLmVuYWJsZWQgPSB0cnVlXG4gIH1cblxuICBUb29sdGlwLnByb3RvdHlwZS5kaXNhYmxlID0gZnVuY3Rpb24gKCkge1xuICAgIHRoaXMuZW5hYmxlZCA9IGZhbHNlXG4gIH1cblxuICBUb29sdGlwLnByb3RvdHlwZS50b2dnbGVFbmFibGVkID0gZnVuY3Rpb24gKCkge1xuICAgIHRoaXMuZW5hYmxlZCA9ICF0aGlzLmVuYWJsZWRcbiAgfVxuXG4gIFRvb2x0aXAucHJvdG90eXBlLnRvZ2dsZSA9IGZ1bmN0aW9uIChlKSB7XG4gICAgdmFyIHNlbGYgPSB0aGlzXG4gICAgaWYgKGUpIHtcbiAgICAgIHNlbGYgPSAkKGUuY3VycmVudFRhcmdldCkuZGF0YSgnYnMuJyArIHRoaXMudHlwZSlcbiAgICAgIGlmICghc2VsZikge1xuICAgICAgICBzZWxmID0gbmV3IHRoaXMuY29uc3RydWN0b3IoZS5jdXJyZW50VGFyZ2V0LCB0aGlzLmdldERlbGVnYXRlT3B0aW9ucygpKVxuICAgICAgICAkKGUuY3VycmVudFRhcmdldCkuZGF0YSgnYnMuJyArIHRoaXMudHlwZSwgc2VsZilcbiAgICAgIH1cbiAgICB9XG5cbiAgICBzZWxmLnRpcCgpLmhhc0NsYXNzKCdpbicpID8gc2VsZi5sZWF2ZShzZWxmKSA6IHNlbGYuZW50ZXIoc2VsZilcbiAgfVxuXG4gIFRvb2x0aXAucHJvdG90eXBlLmRlc3Ryb3kgPSBmdW5jdGlvbiAoKSB7XG4gICAgdmFyIHRoYXQgPSB0aGlzXG4gICAgY2xlYXJUaW1lb3V0KHRoaXMudGltZW91dClcbiAgICB0aGlzLmhpZGUoZnVuY3Rpb24gKCkge1xuICAgICAgdGhhdC4kZWxlbWVudC5vZmYoJy4nICsgdGhhdC50eXBlKS5yZW1vdmVEYXRhKCdicy4nICsgdGhhdC50eXBlKVxuICAgIH0pXG4gIH1cblxuXG4gIC8vIFRPT0xUSVAgUExVR0lOIERFRklOSVRJT05cbiAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PVxuXG4gIGZ1bmN0aW9uIFBsdWdpbihvcHRpb24pIHtcbiAgICByZXR1cm4gdGhpcy5lYWNoKGZ1bmN0aW9uICgpIHtcbiAgICAgIHZhciAkdGhpcyAgID0gJCh0aGlzKVxuICAgICAgdmFyIGRhdGEgICAgPSAkdGhpcy5kYXRhKCdicy50b29sdGlwJylcbiAgICAgIHZhciBvcHRpb25zID0gdHlwZW9mIG9wdGlvbiA9PSAnb2JqZWN0JyAmJiBvcHRpb25cblxuICAgICAgaWYgKCFkYXRhICYmIC9kZXN0cm95fGhpZGUvLnRlc3Qob3B0aW9uKSkgcmV0dXJuXG4gICAgICBpZiAoIWRhdGEpICR0aGlzLmRhdGEoJ2JzLnRvb2x0aXAnLCAoZGF0YSA9IG5ldyBUb29sdGlwKHRoaXMsIG9wdGlvbnMpKSlcbiAgICAgIGlmICh0eXBlb2Ygb3B0aW9uID09ICdzdHJpbmcnKSBkYXRhW29wdGlvbl0oKVxuICAgIH0pXG4gIH1cblxuICB2YXIgb2xkID0gJC5mbi50b29sdGlwXG5cbiAgJC5mbi50b29sdGlwICAgICAgICAgICAgID0gUGx1Z2luXG4gICQuZm4udG9vbHRpcC5Db25zdHJ1Y3RvciA9IFRvb2x0aXBcblxuXG4gIC8vIFRPT0xUSVAgTk8gQ09ORkxJQ1RcbiAgLy8gPT09PT09PT09PT09PT09PT09PVxuXG4gICQuZm4udG9vbHRpcC5ub0NvbmZsaWN0ID0gZnVuY3Rpb24gKCkge1xuICAgICQuZm4udG9vbHRpcCA9IG9sZFxuICAgIHJldHVybiB0aGlzXG4gIH1cblxufShqUXVlcnkpO1xuXG4vKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAqIEJvb3RzdHJhcDogcG9wb3Zlci5qcyB2My4zLjRcbiAqIGh0dHA6Ly9nZXRib290c3RyYXAuY29tL2phdmFzY3JpcHQvI3BvcG92ZXJzXG4gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAqIENvcHlyaWdodCAyMDExLTIwMTUgVHdpdHRlciwgSW5jLlxuICogTGljZW5zZWQgdW5kZXIgTUlUIChodHRwczovL2dpdGh1Yi5jb20vdHdicy9ib290c3RyYXAvYmxvYi9tYXN0ZXIvTElDRU5TRSlcbiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PSAqL1xuXG5cbitmdW5jdGlvbiAoJCkge1xuICAndXNlIHN0cmljdCc7XG5cbiAgLy8gUE9QT1ZFUiBQVUJMSUMgQ0xBU1MgREVGSU5JVElPTlxuICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG5cbiAgdmFyIFBvcG92ZXIgPSBmdW5jdGlvbiAoZWxlbWVudCwgb3B0aW9ucykge1xuICAgIHRoaXMuaW5pdCgncG9wb3ZlcicsIGVsZW1lbnQsIG9wdGlvbnMpXG4gIH1cblxuICBpZiAoISQuZm4udG9vbHRpcCkgdGhyb3cgbmV3IEVycm9yKCdQb3BvdmVyIHJlcXVpcmVzIHRvb2x0aXAuanMnKVxuXG4gIFBvcG92ZXIuVkVSU0lPTiAgPSAnMy4zLjQnXG5cbiAgUG9wb3Zlci5ERUZBVUxUUyA9ICQuZXh0ZW5kKHt9LCAkLmZuLnRvb2x0aXAuQ29uc3RydWN0b3IuREVGQVVMVFMsIHtcbiAgICBwbGFjZW1lbnQ6ICdyaWdodCcsXG4gICAgdHJpZ2dlcjogJ2NsaWNrJyxcbiAgICBjb250ZW50OiAnJyxcbiAgICB0ZW1wbGF0ZTogJzxkaXYgY2xhc3M9XCJwb3BvdmVyXCIgcm9sZT1cInRvb2x0aXBcIj48ZGl2IGNsYXNzPVwiYXJyb3dcIj48L2Rpdj48aDMgY2xhc3M9XCJwb3BvdmVyLXRpdGxlXCI+PC9oMz48ZGl2IGNsYXNzPVwicG9wb3Zlci1jb250ZW50XCI+PC9kaXY+PC9kaXY+J1xuICB9KVxuXG5cbiAgLy8gTk9URTogUE9QT1ZFUiBFWFRFTkRTIHRvb2x0aXAuanNcbiAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cblxuICBQb3BvdmVyLnByb3RvdHlwZSA9ICQuZXh0ZW5kKHt9LCAkLmZuLnRvb2x0aXAuQ29uc3RydWN0b3IucHJvdG90eXBlKVxuXG4gIFBvcG92ZXIucHJvdG90eXBlLmNvbnN0cnVjdG9yID0gUG9wb3ZlclxuXG4gIFBvcG92ZXIucHJvdG90eXBlLmdldERlZmF1bHRzID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiBQb3BvdmVyLkRFRkFVTFRTXG4gIH1cblxuICBQb3BvdmVyLnByb3RvdHlwZS5zZXRDb250ZW50ID0gZnVuY3Rpb24gKCkge1xuICAgIHZhciAkdGlwICAgID0gdGhpcy50aXAoKVxuICAgIHZhciB0aXRsZSAgID0gdGhpcy5nZXRUaXRsZSgpXG4gICAgdmFyIGNvbnRlbnQgPSB0aGlzLmdldENvbnRlbnQoKVxuXG4gICAgJHRpcC5maW5kKCcucG9wb3Zlci10aXRsZScpW3RoaXMub3B0aW9ucy5odG1sID8gJ2h0bWwnIDogJ3RleHQnXSh0aXRsZSlcbiAgICAkdGlwLmZpbmQoJy5wb3BvdmVyLWNvbnRlbnQnKS5jaGlsZHJlbigpLmRldGFjaCgpLmVuZCgpWyAvLyB3ZSB1c2UgYXBwZW5kIGZvciBodG1sIG9iamVjdHMgdG8gbWFpbnRhaW4ganMgZXZlbnRzXG4gICAgICB0aGlzLm9wdGlvbnMuaHRtbCA/ICh0eXBlb2YgY29udGVudCA9PSAnc3RyaW5nJyA/ICdodG1sJyA6ICdhcHBlbmQnKSA6ICd0ZXh0J1xuICAgIF0oY29udGVudClcblxuICAgICR0aXAucmVtb3ZlQ2xhc3MoJ2ZhZGUgdG9wIGJvdHRvbSBsZWZ0IHJpZ2h0IGluJylcblxuICAgIC8vIElFOCBkb2Vzbid0IGFjY2VwdCBoaWRpbmcgdmlhIHRoZSBgOmVtcHR5YCBwc2V1ZG8gc2VsZWN0b3IsIHdlIGhhdmUgdG8gZG9cbiAgICAvLyB0aGlzIG1hbnVhbGx5IGJ5IGNoZWNraW5nIHRoZSBjb250ZW50cy5cbiAgICBpZiAoISR0aXAuZmluZCgnLnBvcG92ZXItdGl0bGUnKS5odG1sKCkpICR0aXAuZmluZCgnLnBvcG92ZXItdGl0bGUnKS5oaWRlKClcbiAgfVxuXG4gIFBvcG92ZXIucHJvdG90eXBlLmhhc0NvbnRlbnQgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIHRoaXMuZ2V0VGl0bGUoKSB8fCB0aGlzLmdldENvbnRlbnQoKVxuICB9XG5cbiAgUG9wb3Zlci5wcm90b3R5cGUuZ2V0Q29udGVudCA9IGZ1bmN0aW9uICgpIHtcbiAgICB2YXIgJGUgPSB0aGlzLiRlbGVtZW50XG4gICAgdmFyIG8gID0gdGhpcy5vcHRpb25zXG5cbiAgICByZXR1cm4gJGUuYXR0cignZGF0YS1jb250ZW50JylcbiAgICAgIHx8ICh0eXBlb2Ygby5jb250ZW50ID09ICdmdW5jdGlvbicgP1xuICAgICAgICAgICAgby5jb250ZW50LmNhbGwoJGVbMF0pIDpcbiAgICAgICAgICAgIG8uY29udGVudClcbiAgfVxuXG4gIFBvcG92ZXIucHJvdG90eXBlLmFycm93ID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiAodGhpcy4kYXJyb3cgPSB0aGlzLiRhcnJvdyB8fCB0aGlzLnRpcCgpLmZpbmQoJy5hcnJvdycpKVxuICB9XG5cblxuICAvLyBQT1BPVkVSIFBMVUdJTiBERUZJTklUSU9OXG4gIC8vID09PT09PT09PT09PT09PT09PT09PT09PT1cblxuICBmdW5jdGlvbiBQbHVnaW4ob3B0aW9uKSB7XG4gICAgcmV0dXJuIHRoaXMuZWFjaChmdW5jdGlvbiAoKSB7XG4gICAgICB2YXIgJHRoaXMgICA9ICQodGhpcylcbiAgICAgIHZhciBkYXRhICAgID0gJHRoaXMuZGF0YSgnYnMucG9wb3ZlcicpXG4gICAgICB2YXIgb3B0aW9ucyA9IHR5cGVvZiBvcHRpb24gPT0gJ29iamVjdCcgJiYgb3B0aW9uXG5cbiAgICAgIGlmICghZGF0YSAmJiAvZGVzdHJveXxoaWRlLy50ZXN0KG9wdGlvbikpIHJldHVyblxuICAgICAgaWYgKCFkYXRhKSAkdGhpcy5kYXRhKCdicy5wb3BvdmVyJywgKGRhdGEgPSBuZXcgUG9wb3Zlcih0aGlzLCBvcHRpb25zKSkpXG4gICAgICBpZiAodHlwZW9mIG9wdGlvbiA9PSAnc3RyaW5nJykgZGF0YVtvcHRpb25dKClcbiAgICB9KVxuICB9XG5cbiAgdmFyIG9sZCA9ICQuZm4ucG9wb3ZlclxuXG4gICQuZm4ucG9wb3ZlciAgICAgICAgICAgICA9IFBsdWdpblxuICAkLmZuLnBvcG92ZXIuQ29uc3RydWN0b3IgPSBQb3BvdmVyXG5cblxuICAvLyBQT1BPVkVSIE5PIENPTkZMSUNUXG4gIC8vID09PT09PT09PT09PT09PT09PT1cblxuICAkLmZuLnBvcG92ZXIubm9Db25mbGljdCA9IGZ1bmN0aW9uICgpIHtcbiAgICAkLmZuLnBvcG92ZXIgPSBvbGRcbiAgICByZXR1cm4gdGhpc1xuICB9XG5cbn0oalF1ZXJ5KTtcblxuLyogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4gKiBCb290c3RyYXA6IHNjcm9sbHNweS5qcyB2My4zLjRcbiAqIGh0dHA6Ly9nZXRib290c3RyYXAuY29tL2phdmFzY3JpcHQvI3Njcm9sbHNweVxuICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4gKiBDb3B5cmlnaHQgMjAxMS0yMDE1IFR3aXR0ZXIsIEluYy5cbiAqIExpY2Vuc2VkIHVuZGVyIE1JVCAoaHR0cHM6Ly9naXRodWIuY29tL3R3YnMvYm9vdHN0cmFwL2Jsb2IvbWFzdGVyL0xJQ0VOU0UpXG4gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0gKi9cblxuXG4rZnVuY3Rpb24gKCQpIHtcbiAgJ3VzZSBzdHJpY3QnO1xuXG4gIC8vIFNDUk9MTFNQWSBDTEFTUyBERUZJTklUSU9OXG4gIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09XG5cbiAgZnVuY3Rpb24gU2Nyb2xsU3B5KGVsZW1lbnQsIG9wdGlvbnMpIHtcbiAgICB0aGlzLiRib2R5ICAgICAgICAgID0gJChkb2N1bWVudC5ib2R5KVxuICAgIHRoaXMuJHNjcm9sbEVsZW1lbnQgPSAkKGVsZW1lbnQpLmlzKGRvY3VtZW50LmJvZHkpID8gJCh3aW5kb3cpIDogJChlbGVtZW50KVxuICAgIHRoaXMub3B0aW9ucyAgICAgICAgPSAkLmV4dGVuZCh7fSwgU2Nyb2xsU3B5LkRFRkFVTFRTLCBvcHRpb25zKVxuICAgIHRoaXMuc2VsZWN0b3IgICAgICAgPSAodGhpcy5vcHRpb25zLnRhcmdldCB8fCAnJykgKyAnIC5uYXYgbGkgPiBhJ1xuICAgIHRoaXMub2Zmc2V0cyAgICAgICAgPSBbXVxuICAgIHRoaXMudGFyZ2V0cyAgICAgICAgPSBbXVxuICAgIHRoaXMuYWN0aXZlVGFyZ2V0ICAgPSBudWxsXG4gICAgdGhpcy5zY3JvbGxIZWlnaHQgICA9IDBcblxuICAgIHRoaXMuJHNjcm9sbEVsZW1lbnQub24oJ3Njcm9sbC5icy5zY3JvbGxzcHknLCAkLnByb3h5KHRoaXMucHJvY2VzcywgdGhpcykpXG4gICAgdGhpcy5yZWZyZXNoKClcbiAgICB0aGlzLnByb2Nlc3MoKVxuICB9XG5cbiAgU2Nyb2xsU3B5LlZFUlNJT04gID0gJzMuMy40J1xuXG4gIFNjcm9sbFNweS5ERUZBVUxUUyA9IHtcbiAgICBvZmZzZXQ6IDEwXG4gIH1cblxuICBTY3JvbGxTcHkucHJvdG90eXBlLmdldFNjcm9sbEhlaWdodCA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gdGhpcy4kc2Nyb2xsRWxlbWVudFswXS5zY3JvbGxIZWlnaHQgfHwgTWF0aC5tYXgodGhpcy4kYm9keVswXS5zY3JvbGxIZWlnaHQsIGRvY3VtZW50LmRvY3VtZW50RWxlbWVudC5zY3JvbGxIZWlnaHQpXG4gIH1cblxuICBTY3JvbGxTcHkucHJvdG90eXBlLnJlZnJlc2ggPSBmdW5jdGlvbiAoKSB7XG4gICAgdmFyIHRoYXQgICAgICAgICAgPSB0aGlzXG4gICAgdmFyIG9mZnNldE1ldGhvZCAgPSAnb2Zmc2V0J1xuICAgIHZhciBvZmZzZXRCYXNlICAgID0gMFxuXG4gICAgdGhpcy5vZmZzZXRzICAgICAgPSBbXVxuICAgIHRoaXMudGFyZ2V0cyAgICAgID0gW11cbiAgICB0aGlzLnNjcm9sbEhlaWdodCA9IHRoaXMuZ2V0U2Nyb2xsSGVpZ2h0KClcblxuICAgIGlmICghJC5pc1dpbmRvdyh0aGlzLiRzY3JvbGxFbGVtZW50WzBdKSkge1xuICAgICAgb2Zmc2V0TWV0aG9kID0gJ3Bvc2l0aW9uJ1xuICAgICAgb2Zmc2V0QmFzZSAgID0gdGhpcy4kc2Nyb2xsRWxlbWVudC5zY3JvbGxUb3AoKVxuICAgIH1cblxuICAgIHRoaXMuJGJvZHlcbiAgICAgIC5maW5kKHRoaXMuc2VsZWN0b3IpXG4gICAgICAubWFwKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyICRlbCAgID0gJCh0aGlzKVxuICAgICAgICB2YXIgaHJlZiAgPSAkZWwuZGF0YSgndGFyZ2V0JykgfHwgJGVsLmF0dHIoJ2hyZWYnKVxuICAgICAgICB2YXIgJGhyZWYgPSAvXiMuLy50ZXN0KGhyZWYpICYmICQoaHJlZilcblxuICAgICAgICByZXR1cm4gKCRocmVmXG4gICAgICAgICAgJiYgJGhyZWYubGVuZ3RoXG4gICAgICAgICAgJiYgJGhyZWYuaXMoJzp2aXNpYmxlJylcbiAgICAgICAgICAmJiBbWyRocmVmW29mZnNldE1ldGhvZF0oKS50b3AgKyBvZmZzZXRCYXNlLCBocmVmXV0pIHx8IG51bGxcbiAgICAgIH0pXG4gICAgICAuc29ydChmdW5jdGlvbiAoYSwgYikgeyByZXR1cm4gYVswXSAtIGJbMF0gfSlcbiAgICAgIC5lYWNoKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdGhhdC5vZmZzZXRzLnB1c2godGhpc1swXSlcbiAgICAgICAgdGhhdC50YXJnZXRzLnB1c2godGhpc1sxXSlcbiAgICAgIH0pXG4gIH1cblxuICBTY3JvbGxTcHkucHJvdG90eXBlLnByb2Nlc3MgPSBmdW5jdGlvbiAoKSB7XG4gICAgdmFyIHNjcm9sbFRvcCAgICA9IHRoaXMuJHNjcm9sbEVsZW1lbnQuc2Nyb2xsVG9wKCkgKyB0aGlzLm9wdGlvbnMub2Zmc2V0XG4gICAgdmFyIHNjcm9sbEhlaWdodCA9IHRoaXMuZ2V0U2Nyb2xsSGVpZ2h0KClcbiAgICB2YXIgbWF4U2Nyb2xsICAgID0gdGhpcy5vcHRpb25zLm9mZnNldCArIHNjcm9sbEhlaWdodCAtIHRoaXMuJHNjcm9sbEVsZW1lbnQuaGVpZ2h0KClcbiAgICB2YXIgb2Zmc2V0cyAgICAgID0gdGhpcy5vZmZzZXRzXG4gICAgdmFyIHRhcmdldHMgICAgICA9IHRoaXMudGFyZ2V0c1xuICAgIHZhciBhY3RpdmVUYXJnZXQgPSB0aGlzLmFjdGl2ZVRhcmdldFxuICAgIHZhciBpXG5cbiAgICBpZiAodGhpcy5zY3JvbGxIZWlnaHQgIT0gc2Nyb2xsSGVpZ2h0KSB7XG4gICAgICB0aGlzLnJlZnJlc2goKVxuICAgIH1cblxuICAgIGlmIChzY3JvbGxUb3AgPj0gbWF4U2Nyb2xsKSB7XG4gICAgICByZXR1cm4gYWN0aXZlVGFyZ2V0ICE9IChpID0gdGFyZ2V0c1t0YXJnZXRzLmxlbmd0aCAtIDFdKSAmJiB0aGlzLmFjdGl2YXRlKGkpXG4gICAgfVxuXG4gICAgaWYgKGFjdGl2ZVRhcmdldCAmJiBzY3JvbGxUb3AgPCBvZmZzZXRzWzBdKSB7XG4gICAgICB0aGlzLmFjdGl2ZVRhcmdldCA9IG51bGxcbiAgICAgIHJldHVybiB0aGlzLmNsZWFyKClcbiAgICB9XG5cbiAgICBmb3IgKGkgPSBvZmZzZXRzLmxlbmd0aDsgaS0tOykge1xuICAgICAgYWN0aXZlVGFyZ2V0ICE9IHRhcmdldHNbaV1cbiAgICAgICAgJiYgc2Nyb2xsVG9wID49IG9mZnNldHNbaV1cbiAgICAgICAgJiYgKG9mZnNldHNbaSArIDFdID09PSB1bmRlZmluZWQgfHwgc2Nyb2xsVG9wIDwgb2Zmc2V0c1tpICsgMV0pXG4gICAgICAgICYmIHRoaXMuYWN0aXZhdGUodGFyZ2V0c1tpXSlcbiAgICB9XG4gIH1cblxuICBTY3JvbGxTcHkucHJvdG90eXBlLmFjdGl2YXRlID0gZnVuY3Rpb24gKHRhcmdldCkge1xuICAgIHRoaXMuYWN0aXZlVGFyZ2V0ID0gdGFyZ2V0XG5cbiAgICB0aGlzLmNsZWFyKClcblxuICAgIHZhciBzZWxlY3RvciA9IHRoaXMuc2VsZWN0b3IgK1xuICAgICAgJ1tkYXRhLXRhcmdldD1cIicgKyB0YXJnZXQgKyAnXCJdLCcgK1xuICAgICAgdGhpcy5zZWxlY3RvciArICdbaHJlZj1cIicgKyB0YXJnZXQgKyAnXCJdJ1xuXG4gICAgdmFyIGFjdGl2ZSA9ICQoc2VsZWN0b3IpXG4gICAgICAucGFyZW50cygnbGknKVxuICAgICAgLmFkZENsYXNzKCdhY3RpdmUnKVxuXG4gICAgaWYgKGFjdGl2ZS5wYXJlbnQoJy5kcm9wZG93bi1tZW51JykubGVuZ3RoKSB7XG4gICAgICBhY3RpdmUgPSBhY3RpdmVcbiAgICAgICAgLmNsb3Nlc3QoJ2xpLmRyb3Bkb3duJylcbiAgICAgICAgLmFkZENsYXNzKCdhY3RpdmUnKVxuICAgIH1cblxuICAgIGFjdGl2ZS50cmlnZ2VyKCdhY3RpdmF0ZS5icy5zY3JvbGxzcHknKVxuICB9XG5cbiAgU2Nyb2xsU3B5LnByb3RvdHlwZS5jbGVhciA9IGZ1bmN0aW9uICgpIHtcbiAgICAkKHRoaXMuc2VsZWN0b3IpXG4gICAgICAucGFyZW50c1VudGlsKHRoaXMub3B0aW9ucy50YXJnZXQsICcuYWN0aXZlJylcbiAgICAgIC5yZW1vdmVDbGFzcygnYWN0aXZlJylcbiAgfVxuXG5cbiAgLy8gU0NST0xMU1BZIFBMVUdJTiBERUZJTklUSU9OXG4gIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PVxuXG4gIGZ1bmN0aW9uIFBsdWdpbihvcHRpb24pIHtcbiAgICByZXR1cm4gdGhpcy5lYWNoKGZ1bmN0aW9uICgpIHtcbiAgICAgIHZhciAkdGhpcyAgID0gJCh0aGlzKVxuICAgICAgdmFyIGRhdGEgICAgPSAkdGhpcy5kYXRhKCdicy5zY3JvbGxzcHknKVxuICAgICAgdmFyIG9wdGlvbnMgPSB0eXBlb2Ygb3B0aW9uID09ICdvYmplY3QnICYmIG9wdGlvblxuXG4gICAgICBpZiAoIWRhdGEpICR0aGlzLmRhdGEoJ2JzLnNjcm9sbHNweScsIChkYXRhID0gbmV3IFNjcm9sbFNweSh0aGlzLCBvcHRpb25zKSkpXG4gICAgICBpZiAodHlwZW9mIG9wdGlvbiA9PSAnc3RyaW5nJykgZGF0YVtvcHRpb25dKClcbiAgICB9KVxuICB9XG5cbiAgdmFyIG9sZCA9ICQuZm4uc2Nyb2xsc3B5XG5cbiAgJC5mbi5zY3JvbGxzcHkgICAgICAgICAgICAgPSBQbHVnaW5cbiAgJC5mbi5zY3JvbGxzcHkuQ29uc3RydWN0b3IgPSBTY3JvbGxTcHlcblxuXG4gIC8vIFNDUk9MTFNQWSBOTyBDT05GTElDVFxuICAvLyA9PT09PT09PT09PT09PT09PT09PT1cblxuICAkLmZuLnNjcm9sbHNweS5ub0NvbmZsaWN0ID0gZnVuY3Rpb24gKCkge1xuICAgICQuZm4uc2Nyb2xsc3B5ID0gb2xkXG4gICAgcmV0dXJuIHRoaXNcbiAgfVxuXG5cbiAgLy8gU0NST0xMU1BZIERBVEEtQVBJXG4gIC8vID09PT09PT09PT09PT09PT09PVxuXG4gICQod2luZG93KS5vbignbG9hZC5icy5zY3JvbGxzcHkuZGF0YS1hcGknLCBmdW5jdGlvbiAoKSB7XG4gICAgJCgnW2RhdGEtc3B5PVwic2Nyb2xsXCJdJykuZWFjaChmdW5jdGlvbiAoKSB7XG4gICAgICB2YXIgJHNweSA9ICQodGhpcylcbiAgICAgIFBsdWdpbi5jYWxsKCRzcHksICRzcHkuZGF0YSgpKVxuICAgIH0pXG4gIH0pXG5cbn0oalF1ZXJ5KTtcblxuLyogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4gKiBCb290c3RyYXA6IHRhYi5qcyB2My4zLjRcbiAqIGh0dHA6Ly9nZXRib290c3RyYXAuY29tL2phdmFzY3JpcHQvI3RhYnNcbiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuICogQ29weXJpZ2h0IDIwMTEtMjAxNSBUd2l0dGVyLCBJbmMuXG4gKiBMaWNlbnNlZCB1bmRlciBNSVQgKGh0dHBzOi8vZ2l0aHViLmNvbS90d2JzL2Jvb3RzdHJhcC9ibG9iL21hc3Rlci9MSUNFTlNFKVxuICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09ICovXG5cblxuK2Z1bmN0aW9uICgkKSB7XG4gICd1c2Ugc3RyaWN0JztcblxuICAvLyBUQUIgQ0xBU1MgREVGSU5JVElPTlxuICAvLyA9PT09PT09PT09PT09PT09PT09PVxuXG4gIHZhciBUYWIgPSBmdW5jdGlvbiAoZWxlbWVudCkge1xuICAgIHRoaXMuZWxlbWVudCA9ICQoZWxlbWVudClcbiAgfVxuXG4gIFRhYi5WRVJTSU9OID0gJzMuMy40J1xuXG4gIFRhYi5UUkFOU0lUSU9OX0RVUkFUSU9OID0gMTUwXG5cbiAgVGFiLnByb3RvdHlwZS5zaG93ID0gZnVuY3Rpb24gKCkge1xuICAgIHZhciAkdGhpcyAgICA9IHRoaXMuZWxlbWVudFxuICAgIHZhciAkdWwgICAgICA9ICR0aGlzLmNsb3Nlc3QoJ3VsOm5vdCguZHJvcGRvd24tbWVudSknKVxuICAgIHZhciBzZWxlY3RvciA9ICR0aGlzLmRhdGEoJ3RhcmdldCcpXG5cbiAgICBpZiAoIXNlbGVjdG9yKSB7XG4gICAgICBzZWxlY3RvciA9ICR0aGlzLmF0dHIoJ2hyZWYnKVxuICAgICAgc2VsZWN0b3IgPSBzZWxlY3RvciAmJiBzZWxlY3Rvci5yZXBsYWNlKC8uKig/PSNbXlxcc10qJCkvLCAnJykgLy8gc3RyaXAgZm9yIGllN1xuICAgIH1cblxuICAgIGlmICgkdGhpcy5wYXJlbnQoJ2xpJykuaGFzQ2xhc3MoJ2FjdGl2ZScpKSByZXR1cm5cblxuICAgIHZhciAkcHJldmlvdXMgPSAkdWwuZmluZCgnLmFjdGl2ZTpsYXN0IGEnKVxuICAgIHZhciBoaWRlRXZlbnQgPSAkLkV2ZW50KCdoaWRlLmJzLnRhYicsIHtcbiAgICAgIHJlbGF0ZWRUYXJnZXQ6ICR0aGlzWzBdXG4gICAgfSlcbiAgICB2YXIgc2hvd0V2ZW50ID0gJC5FdmVudCgnc2hvdy5icy50YWInLCB7XG4gICAgICByZWxhdGVkVGFyZ2V0OiAkcHJldmlvdXNbMF1cbiAgICB9KVxuXG4gICAgJHByZXZpb3VzLnRyaWdnZXIoaGlkZUV2ZW50KVxuICAgICR0aGlzLnRyaWdnZXIoc2hvd0V2ZW50KVxuXG4gICAgaWYgKHNob3dFdmVudC5pc0RlZmF1bHRQcmV2ZW50ZWQoKSB8fCBoaWRlRXZlbnQuaXNEZWZhdWx0UHJldmVudGVkKCkpIHJldHVyblxuXG4gICAgdmFyICR0YXJnZXQgPSAkKHNlbGVjdG9yKVxuXG4gICAgdGhpcy5hY3RpdmF0ZSgkdGhpcy5jbG9zZXN0KCdsaScpLCAkdWwpXG4gICAgdGhpcy5hY3RpdmF0ZSgkdGFyZ2V0LCAkdGFyZ2V0LnBhcmVudCgpLCBmdW5jdGlvbiAoKSB7XG4gICAgICAkcHJldmlvdXMudHJpZ2dlcih7XG4gICAgICAgIHR5cGU6ICdoaWRkZW4uYnMudGFiJyxcbiAgICAgICAgcmVsYXRlZFRhcmdldDogJHRoaXNbMF1cbiAgICAgIH0pXG4gICAgICAkdGhpcy50cmlnZ2VyKHtcbiAgICAgICAgdHlwZTogJ3Nob3duLmJzLnRhYicsXG4gICAgICAgIHJlbGF0ZWRUYXJnZXQ6ICRwcmV2aW91c1swXVxuICAgICAgfSlcbiAgICB9KVxuICB9XG5cbiAgVGFiLnByb3RvdHlwZS5hY3RpdmF0ZSA9IGZ1bmN0aW9uIChlbGVtZW50LCBjb250YWluZXIsIGNhbGxiYWNrKSB7XG4gICAgdmFyICRhY3RpdmUgICAgPSBjb250YWluZXIuZmluZCgnPiAuYWN0aXZlJylcbiAgICB2YXIgdHJhbnNpdGlvbiA9IGNhbGxiYWNrXG4gICAgICAmJiAkLnN1cHBvcnQudHJhbnNpdGlvblxuICAgICAgJiYgKCgkYWN0aXZlLmxlbmd0aCAmJiAkYWN0aXZlLmhhc0NsYXNzKCdmYWRlJykpIHx8ICEhY29udGFpbmVyLmZpbmQoJz4gLmZhZGUnKS5sZW5ndGgpXG5cbiAgICBmdW5jdGlvbiBuZXh0KCkge1xuICAgICAgJGFjdGl2ZVxuICAgICAgICAucmVtb3ZlQ2xhc3MoJ2FjdGl2ZScpXG4gICAgICAgIC5maW5kKCc+IC5kcm9wZG93bi1tZW51ID4gLmFjdGl2ZScpXG4gICAgICAgICAgLnJlbW92ZUNsYXNzKCdhY3RpdmUnKVxuICAgICAgICAuZW5kKClcbiAgICAgICAgLmZpbmQoJ1tkYXRhLXRvZ2dsZT1cInRhYlwiXScpXG4gICAgICAgICAgLmF0dHIoJ2FyaWEtZXhwYW5kZWQnLCBmYWxzZSlcblxuICAgICAgZWxlbWVudFxuICAgICAgICAuYWRkQ2xhc3MoJ2FjdGl2ZScpXG4gICAgICAgIC5maW5kKCdbZGF0YS10b2dnbGU9XCJ0YWJcIl0nKVxuICAgICAgICAgIC5hdHRyKCdhcmlhLWV4cGFuZGVkJywgdHJ1ZSlcblxuICAgICAgaWYgKHRyYW5zaXRpb24pIHtcbiAgICAgICAgZWxlbWVudFswXS5vZmZzZXRXaWR0aCAvLyByZWZsb3cgZm9yIHRyYW5zaXRpb25cbiAgICAgICAgZWxlbWVudC5hZGRDbGFzcygnaW4nKVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgZWxlbWVudC5yZW1vdmVDbGFzcygnZmFkZScpXG4gICAgICB9XG5cbiAgICAgIGlmIChlbGVtZW50LnBhcmVudCgnLmRyb3Bkb3duLW1lbnUnKS5sZW5ndGgpIHtcbiAgICAgICAgZWxlbWVudFxuICAgICAgICAgIC5jbG9zZXN0KCdsaS5kcm9wZG93bicpXG4gICAgICAgICAgICAuYWRkQ2xhc3MoJ2FjdGl2ZScpXG4gICAgICAgICAgLmVuZCgpXG4gICAgICAgICAgLmZpbmQoJ1tkYXRhLXRvZ2dsZT1cInRhYlwiXScpXG4gICAgICAgICAgICAuYXR0cignYXJpYS1leHBhbmRlZCcsIHRydWUpXG4gICAgICB9XG5cbiAgICAgIGNhbGxiYWNrICYmIGNhbGxiYWNrKClcbiAgICB9XG5cbiAgICAkYWN0aXZlLmxlbmd0aCAmJiB0cmFuc2l0aW9uID9cbiAgICAgICRhY3RpdmVcbiAgICAgICAgLm9uZSgnYnNUcmFuc2l0aW9uRW5kJywgbmV4dClcbiAgICAgICAgLmVtdWxhdGVUcmFuc2l0aW9uRW5kKFRhYi5UUkFOU0lUSU9OX0RVUkFUSU9OKSA6XG4gICAgICBuZXh0KClcblxuICAgICRhY3RpdmUucmVtb3ZlQ2xhc3MoJ2luJylcbiAgfVxuXG5cbiAgLy8gVEFCIFBMVUdJTiBERUZJTklUSU9OXG4gIC8vID09PT09PT09PT09PT09PT09PT09PVxuXG4gIGZ1bmN0aW9uIFBsdWdpbihvcHRpb24pIHtcbiAgICByZXR1cm4gdGhpcy5lYWNoKGZ1bmN0aW9uICgpIHtcbiAgICAgIHZhciAkdGhpcyA9ICQodGhpcylcbiAgICAgIHZhciBkYXRhICA9ICR0aGlzLmRhdGEoJ2JzLnRhYicpXG5cbiAgICAgIGlmICghZGF0YSkgJHRoaXMuZGF0YSgnYnMudGFiJywgKGRhdGEgPSBuZXcgVGFiKHRoaXMpKSlcbiAgICAgIGlmICh0eXBlb2Ygb3B0aW9uID09ICdzdHJpbmcnKSBkYXRhW29wdGlvbl0oKVxuICAgIH0pXG4gIH1cblxuICB2YXIgb2xkID0gJC5mbi50YWJcblxuICAkLmZuLnRhYiAgICAgICAgICAgICA9IFBsdWdpblxuICAkLmZuLnRhYi5Db25zdHJ1Y3RvciA9IFRhYlxuXG5cbiAgLy8gVEFCIE5PIENPTkZMSUNUXG4gIC8vID09PT09PT09PT09PT09PVxuXG4gICQuZm4udGFiLm5vQ29uZmxpY3QgPSBmdW5jdGlvbiAoKSB7XG4gICAgJC5mbi50YWIgPSBvbGRcbiAgICByZXR1cm4gdGhpc1xuICB9XG5cblxuICAvLyBUQUIgREFUQS1BUElcbiAgLy8gPT09PT09PT09PT09XG5cbiAgdmFyIGNsaWNrSGFuZGxlciA9IGZ1bmN0aW9uIChlKSB7XG4gICAgZS5wcmV2ZW50RGVmYXVsdCgpXG4gICAgUGx1Z2luLmNhbGwoJCh0aGlzKSwgJ3Nob3cnKVxuICB9XG5cbiAgJChkb2N1bWVudClcbiAgICAub24oJ2NsaWNrLmJzLnRhYi5kYXRhLWFwaScsICdbZGF0YS10b2dnbGU9XCJ0YWJcIl0nLCBjbGlja0hhbmRsZXIpXG4gICAgLm9uKCdjbGljay5icy50YWIuZGF0YS1hcGknLCAnW2RhdGEtdG9nZ2xlPVwicGlsbFwiXScsIGNsaWNrSGFuZGxlcilcblxufShqUXVlcnkpO1xuXG4vKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAqIEJvb3RzdHJhcDogYWZmaXguanMgdjMuMy40XG4gKiBodHRwOi8vZ2V0Ym9vdHN0cmFwLmNvbS9qYXZhc2NyaXB0LyNhZmZpeFxuICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4gKiBDb3B5cmlnaHQgMjAxMS0yMDE1IFR3aXR0ZXIsIEluYy5cbiAqIExpY2Vuc2VkIHVuZGVyIE1JVCAoaHR0cHM6Ly9naXRodWIuY29tL3R3YnMvYm9vdHN0cmFwL2Jsb2IvbWFzdGVyL0xJQ0VOU0UpXG4gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0gKi9cblxuXG4rZnVuY3Rpb24gKCQpIHtcbiAgJ3VzZSBzdHJpY3QnO1xuXG4gIC8vIEFGRklYIENMQVNTIERFRklOSVRJT05cbiAgLy8gPT09PT09PT09PT09PT09PT09PT09PVxuXG4gIHZhciBBZmZpeCA9IGZ1bmN0aW9uIChlbGVtZW50LCBvcHRpb25zKSB7XG4gICAgdGhpcy5vcHRpb25zID0gJC5leHRlbmQoe30sIEFmZml4LkRFRkFVTFRTLCBvcHRpb25zKVxuXG4gICAgdGhpcy4kdGFyZ2V0ID0gJCh0aGlzLm9wdGlvbnMudGFyZ2V0KVxuICAgICAgLm9uKCdzY3JvbGwuYnMuYWZmaXguZGF0YS1hcGknLCAkLnByb3h5KHRoaXMuY2hlY2tQb3NpdGlvbiwgdGhpcykpXG4gICAgICAub24oJ2NsaWNrLmJzLmFmZml4LmRhdGEtYXBpJywgICQucHJveHkodGhpcy5jaGVja1Bvc2l0aW9uV2l0aEV2ZW50TG9vcCwgdGhpcykpXG5cbiAgICB0aGlzLiRlbGVtZW50ICAgICA9ICQoZWxlbWVudClcbiAgICB0aGlzLmFmZml4ZWQgICAgICA9IG51bGxcbiAgICB0aGlzLnVucGluICAgICAgICA9IG51bGxcbiAgICB0aGlzLnBpbm5lZE9mZnNldCA9IG51bGxcblxuICAgIHRoaXMuY2hlY2tQb3NpdGlvbigpXG4gIH1cblxuICBBZmZpeC5WRVJTSU9OICA9ICczLjMuNCdcblxuICBBZmZpeC5SRVNFVCAgICA9ICdhZmZpeCBhZmZpeC10b3AgYWZmaXgtYm90dG9tJ1xuXG4gIEFmZml4LkRFRkFVTFRTID0ge1xuICAgIG9mZnNldDogMCxcbiAgICB0YXJnZXQ6IHdpbmRvd1xuICB9XG5cbiAgQWZmaXgucHJvdG90eXBlLmdldFN0YXRlID0gZnVuY3Rpb24gKHNjcm9sbEhlaWdodCwgaGVpZ2h0LCBvZmZzZXRUb3AsIG9mZnNldEJvdHRvbSkge1xuICAgIHZhciBzY3JvbGxUb3AgICAgPSB0aGlzLiR0YXJnZXQuc2Nyb2xsVG9wKClcbiAgICB2YXIgcG9zaXRpb24gICAgID0gdGhpcy4kZWxlbWVudC5vZmZzZXQoKVxuICAgIHZhciB0YXJnZXRIZWlnaHQgPSB0aGlzLiR0YXJnZXQuaGVpZ2h0KClcblxuICAgIGlmIChvZmZzZXRUb3AgIT0gbnVsbCAmJiB0aGlzLmFmZml4ZWQgPT0gJ3RvcCcpIHJldHVybiBzY3JvbGxUb3AgPCBvZmZzZXRUb3AgPyAndG9wJyA6IGZhbHNlXG5cbiAgICBpZiAodGhpcy5hZmZpeGVkID09ICdib3R0b20nKSB7XG4gICAgICBpZiAob2Zmc2V0VG9wICE9IG51bGwpIHJldHVybiAoc2Nyb2xsVG9wICsgdGhpcy51bnBpbiA8PSBwb3NpdGlvbi50b3ApID8gZmFsc2UgOiAnYm90dG9tJ1xuICAgICAgcmV0dXJuIChzY3JvbGxUb3AgKyB0YXJnZXRIZWlnaHQgPD0gc2Nyb2xsSGVpZ2h0IC0gb2Zmc2V0Qm90dG9tKSA/IGZhbHNlIDogJ2JvdHRvbSdcbiAgICB9XG5cbiAgICB2YXIgaW5pdGlhbGl6aW5nICAgPSB0aGlzLmFmZml4ZWQgPT0gbnVsbFxuICAgIHZhciBjb2xsaWRlclRvcCAgICA9IGluaXRpYWxpemluZyA/IHNjcm9sbFRvcCA6IHBvc2l0aW9uLnRvcFxuICAgIHZhciBjb2xsaWRlckhlaWdodCA9IGluaXRpYWxpemluZyA/IHRhcmdldEhlaWdodCA6IGhlaWdodFxuXG4gICAgaWYgKG9mZnNldFRvcCAhPSBudWxsICYmIHNjcm9sbFRvcCA8PSBvZmZzZXRUb3ApIHJldHVybiAndG9wJ1xuICAgIGlmIChvZmZzZXRCb3R0b20gIT0gbnVsbCAmJiAoY29sbGlkZXJUb3AgKyBjb2xsaWRlckhlaWdodCA+PSBzY3JvbGxIZWlnaHQgLSBvZmZzZXRCb3R0b20pKSByZXR1cm4gJ2JvdHRvbSdcblxuICAgIHJldHVybiBmYWxzZVxuICB9XG5cbiAgQWZmaXgucHJvdG90eXBlLmdldFBpbm5lZE9mZnNldCA9IGZ1bmN0aW9uICgpIHtcbiAgICBpZiAodGhpcy5waW5uZWRPZmZzZXQpIHJldHVybiB0aGlzLnBpbm5lZE9mZnNldFxuICAgIHRoaXMuJGVsZW1lbnQucmVtb3ZlQ2xhc3MoQWZmaXguUkVTRVQpLmFkZENsYXNzKCdhZmZpeCcpXG4gICAgdmFyIHNjcm9sbFRvcCA9IHRoaXMuJHRhcmdldC5zY3JvbGxUb3AoKVxuICAgIHZhciBwb3NpdGlvbiAgPSB0aGlzLiRlbGVtZW50Lm9mZnNldCgpXG4gICAgcmV0dXJuICh0aGlzLnBpbm5lZE9mZnNldCA9IHBvc2l0aW9uLnRvcCAtIHNjcm9sbFRvcClcbiAgfVxuXG4gIEFmZml4LnByb3RvdHlwZS5jaGVja1Bvc2l0aW9uV2l0aEV2ZW50TG9vcCA9IGZ1bmN0aW9uICgpIHtcbiAgICBzZXRUaW1lb3V0KCQucHJveHkodGhpcy5jaGVja1Bvc2l0aW9uLCB0aGlzKSwgMSlcbiAgfVxuXG4gIEFmZml4LnByb3RvdHlwZS5jaGVja1Bvc2l0aW9uID0gZnVuY3Rpb24gKCkge1xuICAgIGlmICghdGhpcy4kZWxlbWVudC5pcygnOnZpc2libGUnKSkgcmV0dXJuXG5cbiAgICB2YXIgaGVpZ2h0ICAgICAgID0gdGhpcy4kZWxlbWVudC5oZWlnaHQoKVxuICAgIHZhciBvZmZzZXQgICAgICAgPSB0aGlzLm9wdGlvbnMub2Zmc2V0XG4gICAgdmFyIG9mZnNldFRvcCAgICA9IG9mZnNldC50b3BcbiAgICB2YXIgb2Zmc2V0Qm90dG9tID0gb2Zmc2V0LmJvdHRvbVxuICAgIHZhciBzY3JvbGxIZWlnaHQgPSAkKGRvY3VtZW50LmJvZHkpLmhlaWdodCgpXG5cbiAgICBpZiAodHlwZW9mIG9mZnNldCAhPSAnb2JqZWN0JykgICAgICAgICBvZmZzZXRCb3R0b20gPSBvZmZzZXRUb3AgPSBvZmZzZXRcbiAgICBpZiAodHlwZW9mIG9mZnNldFRvcCA9PSAnZnVuY3Rpb24nKSAgICBvZmZzZXRUb3AgICAgPSBvZmZzZXQudG9wKHRoaXMuJGVsZW1lbnQpXG4gICAgaWYgKHR5cGVvZiBvZmZzZXRCb3R0b20gPT0gJ2Z1bmN0aW9uJykgb2Zmc2V0Qm90dG9tID0gb2Zmc2V0LmJvdHRvbSh0aGlzLiRlbGVtZW50KVxuXG4gICAgdmFyIGFmZml4ID0gdGhpcy5nZXRTdGF0ZShzY3JvbGxIZWlnaHQsIGhlaWdodCwgb2Zmc2V0VG9wLCBvZmZzZXRCb3R0b20pXG5cbiAgICBpZiAodGhpcy5hZmZpeGVkICE9IGFmZml4KSB7XG4gICAgICBpZiAodGhpcy51bnBpbiAhPSBudWxsKSB0aGlzLiRlbGVtZW50LmNzcygndG9wJywgJycpXG5cbiAgICAgIHZhciBhZmZpeFR5cGUgPSAnYWZmaXgnICsgKGFmZml4ID8gJy0nICsgYWZmaXggOiAnJylcbiAgICAgIHZhciBlICAgICAgICAgPSAkLkV2ZW50KGFmZml4VHlwZSArICcuYnMuYWZmaXgnKVxuXG4gICAgICB0aGlzLiRlbGVtZW50LnRyaWdnZXIoZSlcblxuICAgICAgaWYgKGUuaXNEZWZhdWx0UHJldmVudGVkKCkpIHJldHVyblxuXG4gICAgICB0aGlzLmFmZml4ZWQgPSBhZmZpeFxuICAgICAgdGhpcy51bnBpbiA9IGFmZml4ID09ICdib3R0b20nID8gdGhpcy5nZXRQaW5uZWRPZmZzZXQoKSA6IG51bGxcblxuICAgICAgdGhpcy4kZWxlbWVudFxuICAgICAgICAucmVtb3ZlQ2xhc3MoQWZmaXguUkVTRVQpXG4gICAgICAgIC5hZGRDbGFzcyhhZmZpeFR5cGUpXG4gICAgICAgIC50cmlnZ2VyKGFmZml4VHlwZS5yZXBsYWNlKCdhZmZpeCcsICdhZmZpeGVkJykgKyAnLmJzLmFmZml4JylcbiAgICB9XG5cbiAgICBpZiAoYWZmaXggPT0gJ2JvdHRvbScpIHtcbiAgICAgIHRoaXMuJGVsZW1lbnQub2Zmc2V0KHtcbiAgICAgICAgdG9wOiBzY3JvbGxIZWlnaHQgLSBoZWlnaHQgLSBvZmZzZXRCb3R0b21cbiAgICAgIH0pXG4gICAgfVxuICB9XG5cblxuICAvLyBBRkZJWCBQTFVHSU4gREVGSU5JVElPTlxuICAvLyA9PT09PT09PT09PT09PT09PT09PT09PVxuXG4gIGZ1bmN0aW9uIFBsdWdpbihvcHRpb24pIHtcbiAgICByZXR1cm4gdGhpcy5lYWNoKGZ1bmN0aW9uICgpIHtcbiAgICAgIHZhciAkdGhpcyAgID0gJCh0aGlzKVxuICAgICAgdmFyIGRhdGEgICAgPSAkdGhpcy5kYXRhKCdicy5hZmZpeCcpXG4gICAgICB2YXIgb3B0aW9ucyA9IHR5cGVvZiBvcHRpb24gPT0gJ29iamVjdCcgJiYgb3B0aW9uXG5cbiAgICAgIGlmICghZGF0YSkgJHRoaXMuZGF0YSgnYnMuYWZmaXgnLCAoZGF0YSA9IG5ldyBBZmZpeCh0aGlzLCBvcHRpb25zKSkpXG4gICAgICBpZiAodHlwZW9mIG9wdGlvbiA9PSAnc3RyaW5nJykgZGF0YVtvcHRpb25dKClcbiAgICB9KVxuICB9XG5cbiAgdmFyIG9sZCA9ICQuZm4uYWZmaXhcblxuICAkLmZuLmFmZml4ICAgICAgICAgICAgID0gUGx1Z2luXG4gICQuZm4uYWZmaXguQ29uc3RydWN0b3IgPSBBZmZpeFxuXG5cbiAgLy8gQUZGSVggTk8gQ09ORkxJQ1RcbiAgLy8gPT09PT09PT09PT09PT09PT1cblxuICAkLmZuLmFmZml4Lm5vQ29uZmxpY3QgPSBmdW5jdGlvbiAoKSB7XG4gICAgJC5mbi5hZmZpeCA9IG9sZFxuICAgIHJldHVybiB0aGlzXG4gIH1cblxuXG4gIC8vIEFGRklYIERBVEEtQVBJXG4gIC8vID09PT09PT09PT09PT09XG5cbiAgJCh3aW5kb3cpLm9uKCdsb2FkJywgZnVuY3Rpb24gKCkge1xuICAgICQoJ1tkYXRhLXNweT1cImFmZml4XCJdJykuZWFjaChmdW5jdGlvbiAoKSB7XG4gICAgICB2YXIgJHNweSA9ICQodGhpcylcbiAgICAgIHZhciBkYXRhID0gJHNweS5kYXRhKClcblxuICAgICAgZGF0YS5vZmZzZXQgPSBkYXRhLm9mZnNldCB8fCB7fVxuXG4gICAgICBpZiAoZGF0YS5vZmZzZXRCb3R0b20gIT0gbnVsbCkgZGF0YS5vZmZzZXQuYm90dG9tID0gZGF0YS5vZmZzZXRCb3R0b21cbiAgICAgIGlmIChkYXRhLm9mZnNldFRvcCAgICAhPSBudWxsKSBkYXRhLm9mZnNldC50b3AgICAgPSBkYXRhLm9mZnNldFRvcFxuXG4gICAgICBQbHVnaW4uY2FsbCgkc3B5LCBkYXRhKVxuICAgIH0pXG4gIH0pXG5cbn0oalF1ZXJ5KTtcblxuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIC4vbm9kZV9tb2R1bGVzL2Jvb3RzdHJhcC1sZXNzL2pzL2Jvb3RzdHJhcC5qc1xuLy8gbW9kdWxlIGlkID0gMTFcbi8vIG1vZHVsZSBjaHVua3MgPSAwIiwiLyohXG4gKiBWdWUuanMgdjIuNC40XG4gKiAoYykgMjAxNC0yMDE3IEV2YW4gWW91XG4gKiBSZWxlYXNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG4gKi9cbid1c2Ugc3RyaWN0JztcblxuLyogICovXG5cbi8vIHRoZXNlIGhlbHBlcnMgcHJvZHVjZXMgYmV0dGVyIHZtIGNvZGUgaW4gSlMgZW5naW5lcyBkdWUgdG8gdGhlaXJcbi8vIGV4cGxpY2l0bmVzcyBhbmQgZnVuY3Rpb24gaW5saW5pbmdcbmZ1bmN0aW9uIGlzVW5kZWYgKHYpIHtcbiAgcmV0dXJuIHYgPT09IHVuZGVmaW5lZCB8fCB2ID09PSBudWxsXG59XG5cbmZ1bmN0aW9uIGlzRGVmICh2KSB7XG4gIHJldHVybiB2ICE9PSB1bmRlZmluZWQgJiYgdiAhPT0gbnVsbFxufVxuXG5mdW5jdGlvbiBpc1RydWUgKHYpIHtcbiAgcmV0dXJuIHYgPT09IHRydWVcbn1cblxuZnVuY3Rpb24gaXNGYWxzZSAodikge1xuICByZXR1cm4gdiA9PT0gZmFsc2Vcbn1cblxuLyoqXG4gKiBDaGVjayBpZiB2YWx1ZSBpcyBwcmltaXRpdmVcbiAqL1xuZnVuY3Rpb24gaXNQcmltaXRpdmUgKHZhbHVlKSB7XG4gIHJldHVybiAoXG4gICAgdHlwZW9mIHZhbHVlID09PSAnc3RyaW5nJyB8fFxuICAgIHR5cGVvZiB2YWx1ZSA9PT0gJ251bWJlcicgfHxcbiAgICB0eXBlb2YgdmFsdWUgPT09ICdib29sZWFuJ1xuICApXG59XG5cbi8qKlxuICogUXVpY2sgb2JqZWN0IGNoZWNrIC0gdGhpcyBpcyBwcmltYXJpbHkgdXNlZCB0byB0ZWxsXG4gKiBPYmplY3RzIGZyb20gcHJpbWl0aXZlIHZhbHVlcyB3aGVuIHdlIGtub3cgdGhlIHZhbHVlXG4gKiBpcyBhIEpTT04tY29tcGxpYW50IHR5cGUuXG4gKi9cbmZ1bmN0aW9uIGlzT2JqZWN0IChvYmopIHtcbiAgcmV0dXJuIG9iaiAhPT0gbnVsbCAmJiB0eXBlb2Ygb2JqID09PSAnb2JqZWN0J1xufVxuXG52YXIgX3RvU3RyaW5nID0gT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZztcblxuLyoqXG4gKiBTdHJpY3Qgb2JqZWN0IHR5cGUgY2hlY2suIE9ubHkgcmV0dXJucyB0cnVlXG4gKiBmb3IgcGxhaW4gSmF2YVNjcmlwdCBvYmplY3RzLlxuICovXG5mdW5jdGlvbiBpc1BsYWluT2JqZWN0IChvYmopIHtcbiAgcmV0dXJuIF90b1N0cmluZy5jYWxsKG9iaikgPT09ICdbb2JqZWN0IE9iamVjdF0nXG59XG5cbmZ1bmN0aW9uIGlzUmVnRXhwICh2KSB7XG4gIHJldHVybiBfdG9TdHJpbmcuY2FsbCh2KSA9PT0gJ1tvYmplY3QgUmVnRXhwXSdcbn1cblxuLyoqXG4gKiBDaGVjayBpZiB2YWwgaXMgYSB2YWxpZCBhcnJheSBpbmRleC5cbiAqL1xuZnVuY3Rpb24gaXNWYWxpZEFycmF5SW5kZXggKHZhbCkge1xuICB2YXIgbiA9IHBhcnNlRmxvYXQodmFsKTtcbiAgcmV0dXJuIG4gPj0gMCAmJiBNYXRoLmZsb29yKG4pID09PSBuICYmIGlzRmluaXRlKHZhbClcbn1cblxuLyoqXG4gKiBDb252ZXJ0IGEgdmFsdWUgdG8gYSBzdHJpbmcgdGhhdCBpcyBhY3R1YWxseSByZW5kZXJlZC5cbiAqL1xuZnVuY3Rpb24gdG9TdHJpbmcgKHZhbCkge1xuICByZXR1cm4gdmFsID09IG51bGxcbiAgICA/ICcnXG4gICAgOiB0eXBlb2YgdmFsID09PSAnb2JqZWN0J1xuICAgICAgPyBKU09OLnN0cmluZ2lmeSh2YWwsIG51bGwsIDIpXG4gICAgICA6IFN0cmluZyh2YWwpXG59XG5cbi8qKlxuICogQ29udmVydCBhIGlucHV0IHZhbHVlIHRvIGEgbnVtYmVyIGZvciBwZXJzaXN0ZW5jZS5cbiAqIElmIHRoZSBjb252ZXJzaW9uIGZhaWxzLCByZXR1cm4gb3JpZ2luYWwgc3RyaW5nLlxuICovXG5mdW5jdGlvbiB0b051bWJlciAodmFsKSB7XG4gIHZhciBuID0gcGFyc2VGbG9hdCh2YWwpO1xuICByZXR1cm4gaXNOYU4obikgPyB2YWwgOiBuXG59XG5cbi8qKlxuICogTWFrZSBhIG1hcCBhbmQgcmV0dXJuIGEgZnVuY3Rpb24gZm9yIGNoZWNraW5nIGlmIGEga2V5XG4gKiBpcyBpbiB0aGF0IG1hcC5cbiAqL1xuZnVuY3Rpb24gbWFrZU1hcCAoXG4gIHN0cixcbiAgZXhwZWN0c0xvd2VyQ2FzZVxuKSB7XG4gIHZhciBtYXAgPSBPYmplY3QuY3JlYXRlKG51bGwpO1xuICB2YXIgbGlzdCA9IHN0ci5zcGxpdCgnLCcpO1xuICBmb3IgKHZhciBpID0gMDsgaSA8IGxpc3QubGVuZ3RoOyBpKyspIHtcbiAgICBtYXBbbGlzdFtpXV0gPSB0cnVlO1xuICB9XG4gIHJldHVybiBleHBlY3RzTG93ZXJDYXNlXG4gICAgPyBmdW5jdGlvbiAodmFsKSB7IHJldHVybiBtYXBbdmFsLnRvTG93ZXJDYXNlKCldOyB9XG4gICAgOiBmdW5jdGlvbiAodmFsKSB7IHJldHVybiBtYXBbdmFsXTsgfVxufVxuXG4vKipcbiAqIENoZWNrIGlmIGEgdGFnIGlzIGEgYnVpbHQtaW4gdGFnLlxuICovXG52YXIgaXNCdWlsdEluVGFnID0gbWFrZU1hcCgnc2xvdCxjb21wb25lbnQnLCB0cnVlKTtcblxuLyoqXG4gKiBDaGVjayBpZiBhIGF0dHJpYnV0ZSBpcyBhIHJlc2VydmVkIGF0dHJpYnV0ZS5cbiAqL1xudmFyIGlzUmVzZXJ2ZWRBdHRyaWJ1dGUgPSBtYWtlTWFwKCdrZXkscmVmLHNsb3QsaXMnKTtcblxuLyoqXG4gKiBSZW1vdmUgYW4gaXRlbSBmcm9tIGFuIGFycmF5XG4gKi9cbmZ1bmN0aW9uIHJlbW92ZSAoYXJyLCBpdGVtKSB7XG4gIGlmIChhcnIubGVuZ3RoKSB7XG4gICAgdmFyIGluZGV4ID0gYXJyLmluZGV4T2YoaXRlbSk7XG4gICAgaWYgKGluZGV4ID4gLTEpIHtcbiAgICAgIHJldHVybiBhcnIuc3BsaWNlKGluZGV4LCAxKVxuICAgIH1cbiAgfVxufVxuXG4vKipcbiAqIENoZWNrIHdoZXRoZXIgdGhlIG9iamVjdCBoYXMgdGhlIHByb3BlcnR5LlxuICovXG52YXIgaGFzT3duUHJvcGVydHkgPSBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5O1xuZnVuY3Rpb24gaGFzT3duIChvYmosIGtleSkge1xuICByZXR1cm4gaGFzT3duUHJvcGVydHkuY2FsbChvYmosIGtleSlcbn1cblxuLyoqXG4gKiBDcmVhdGUgYSBjYWNoZWQgdmVyc2lvbiBvZiBhIHB1cmUgZnVuY3Rpb24uXG4gKi9cbmZ1bmN0aW9uIGNhY2hlZCAoZm4pIHtcbiAgdmFyIGNhY2hlID0gT2JqZWN0LmNyZWF0ZShudWxsKTtcbiAgcmV0dXJuIChmdW5jdGlvbiBjYWNoZWRGbiAoc3RyKSB7XG4gICAgdmFyIGhpdCA9IGNhY2hlW3N0cl07XG4gICAgcmV0dXJuIGhpdCB8fCAoY2FjaGVbc3RyXSA9IGZuKHN0cikpXG4gIH0pXG59XG5cbi8qKlxuICogQ2FtZWxpemUgYSBoeXBoZW4tZGVsaW1pdGVkIHN0cmluZy5cbiAqL1xudmFyIGNhbWVsaXplUkUgPSAvLShcXHcpL2c7XG52YXIgY2FtZWxpemUgPSBjYWNoZWQoZnVuY3Rpb24gKHN0cikge1xuICByZXR1cm4gc3RyLnJlcGxhY2UoY2FtZWxpemVSRSwgZnVuY3Rpb24gKF8sIGMpIHsgcmV0dXJuIGMgPyBjLnRvVXBwZXJDYXNlKCkgOiAnJzsgfSlcbn0pO1xuXG4vKipcbiAqIENhcGl0YWxpemUgYSBzdHJpbmcuXG4gKi9cbnZhciBjYXBpdGFsaXplID0gY2FjaGVkKGZ1bmN0aW9uIChzdHIpIHtcbiAgcmV0dXJuIHN0ci5jaGFyQXQoMCkudG9VcHBlckNhc2UoKSArIHN0ci5zbGljZSgxKVxufSk7XG5cbi8qKlxuICogSHlwaGVuYXRlIGEgY2FtZWxDYXNlIHN0cmluZy5cbiAqL1xudmFyIGh5cGhlbmF0ZVJFID0gL1xcQihbQS1aXSkvZztcbnZhciBoeXBoZW5hdGUgPSBjYWNoZWQoZnVuY3Rpb24gKHN0cikge1xuICByZXR1cm4gc3RyLnJlcGxhY2UoaHlwaGVuYXRlUkUsICctJDEnKS50b0xvd2VyQ2FzZSgpXG59KTtcblxuLyoqXG4gKiBTaW1wbGUgYmluZCwgZmFzdGVyIHRoYW4gbmF0aXZlXG4gKi9cbmZ1bmN0aW9uIGJpbmQgKGZuLCBjdHgpIHtcbiAgZnVuY3Rpb24gYm91bmRGbiAoYSkge1xuICAgIHZhciBsID0gYXJndW1lbnRzLmxlbmd0aDtcbiAgICByZXR1cm4gbFxuICAgICAgPyBsID4gMVxuICAgICAgICA/IGZuLmFwcGx5KGN0eCwgYXJndW1lbnRzKVxuICAgICAgICA6IGZuLmNhbGwoY3R4LCBhKVxuICAgICAgOiBmbi5jYWxsKGN0eClcbiAgfVxuICAvLyByZWNvcmQgb3JpZ2luYWwgZm4gbGVuZ3RoXG4gIGJvdW5kRm4uX2xlbmd0aCA9IGZuLmxlbmd0aDtcbiAgcmV0dXJuIGJvdW5kRm5cbn1cblxuLyoqXG4gKiBDb252ZXJ0IGFuIEFycmF5LWxpa2Ugb2JqZWN0IHRvIGEgcmVhbCBBcnJheS5cbiAqL1xuZnVuY3Rpb24gdG9BcnJheSAobGlzdCwgc3RhcnQpIHtcbiAgc3RhcnQgPSBzdGFydCB8fCAwO1xuICB2YXIgaSA9IGxpc3QubGVuZ3RoIC0gc3RhcnQ7XG4gIHZhciByZXQgPSBuZXcgQXJyYXkoaSk7XG4gIHdoaWxlIChpLS0pIHtcbiAgICByZXRbaV0gPSBsaXN0W2kgKyBzdGFydF07XG4gIH1cbiAgcmV0dXJuIHJldFxufVxuXG4vKipcbiAqIE1peCBwcm9wZXJ0aWVzIGludG8gdGFyZ2V0IG9iamVjdC5cbiAqL1xuZnVuY3Rpb24gZXh0ZW5kICh0bywgX2Zyb20pIHtcbiAgZm9yICh2YXIga2V5IGluIF9mcm9tKSB7XG4gICAgdG9ba2V5XSA9IF9mcm9tW2tleV07XG4gIH1cbiAgcmV0dXJuIHRvXG59XG5cbi8qKlxuICogTWVyZ2UgYW4gQXJyYXkgb2YgT2JqZWN0cyBpbnRvIGEgc2luZ2xlIE9iamVjdC5cbiAqL1xuZnVuY3Rpb24gdG9PYmplY3QgKGFycikge1xuICB2YXIgcmVzID0ge307XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgYXJyLmxlbmd0aDsgaSsrKSB7XG4gICAgaWYgKGFycltpXSkge1xuICAgICAgZXh0ZW5kKHJlcywgYXJyW2ldKTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIHJlc1xufVxuXG4vKipcbiAqIFBlcmZvcm0gbm8gb3BlcmF0aW9uLlxuICogU3R1YmJpbmcgYXJncyB0byBtYWtlIEZsb3cgaGFwcHkgd2l0aG91dCBsZWF2aW5nIHVzZWxlc3MgdHJhbnNwaWxlZCBjb2RlXG4gKiB3aXRoIC4uLnJlc3QgKGh0dHBzOi8vZmxvdy5vcmcvYmxvZy8yMDE3LzA1LzA3L1N0cmljdC1GdW5jdGlvbi1DYWxsLUFyaXR5LylcbiAqL1xuZnVuY3Rpb24gbm9vcCAoYSwgYiwgYykge31cblxuLyoqXG4gKiBBbHdheXMgcmV0dXJuIGZhbHNlLlxuICovXG52YXIgbm8gPSBmdW5jdGlvbiAoYSwgYiwgYykgeyByZXR1cm4gZmFsc2U7IH07XG5cbi8qKlxuICogUmV0dXJuIHNhbWUgdmFsdWVcbiAqL1xudmFyIGlkZW50aXR5ID0gZnVuY3Rpb24gKF8pIHsgcmV0dXJuIF87IH07XG5cbi8qKlxuICogR2VuZXJhdGUgYSBzdGF0aWMga2V5cyBzdHJpbmcgZnJvbSBjb21waWxlciBtb2R1bGVzLlxuICovXG5mdW5jdGlvbiBnZW5TdGF0aWNLZXlzIChtb2R1bGVzKSB7XG4gIHJldHVybiBtb2R1bGVzLnJlZHVjZShmdW5jdGlvbiAoa2V5cywgbSkge1xuICAgIHJldHVybiBrZXlzLmNvbmNhdChtLnN0YXRpY0tleXMgfHwgW10pXG4gIH0sIFtdKS5qb2luKCcsJylcbn1cblxuLyoqXG4gKiBDaGVjayBpZiB0d28gdmFsdWVzIGFyZSBsb29zZWx5IGVxdWFsIC0gdGhhdCBpcyxcbiAqIGlmIHRoZXkgYXJlIHBsYWluIG9iamVjdHMsIGRvIHRoZXkgaGF2ZSB0aGUgc2FtZSBzaGFwZT9cbiAqL1xuZnVuY3Rpb24gbG9vc2VFcXVhbCAoYSwgYikge1xuICBpZiAoYSA9PT0gYikgeyByZXR1cm4gdHJ1ZSB9XG4gIHZhciBpc09iamVjdEEgPSBpc09iamVjdChhKTtcbiAgdmFyIGlzT2JqZWN0QiA9IGlzT2JqZWN0KGIpO1xuICBpZiAoaXNPYmplY3RBICYmIGlzT2JqZWN0Qikge1xuICAgIHRyeSB7XG4gICAgICB2YXIgaXNBcnJheUEgPSBBcnJheS5pc0FycmF5KGEpO1xuICAgICAgdmFyIGlzQXJyYXlCID0gQXJyYXkuaXNBcnJheShiKTtcbiAgICAgIGlmIChpc0FycmF5QSAmJiBpc0FycmF5Qikge1xuICAgICAgICByZXR1cm4gYS5sZW5ndGggPT09IGIubGVuZ3RoICYmIGEuZXZlcnkoZnVuY3Rpb24gKGUsIGkpIHtcbiAgICAgICAgICByZXR1cm4gbG9vc2VFcXVhbChlLCBiW2ldKVxuICAgICAgICB9KVxuICAgICAgfSBlbHNlIGlmICghaXNBcnJheUEgJiYgIWlzQXJyYXlCKSB7XG4gICAgICAgIHZhciBrZXlzQSA9IE9iamVjdC5rZXlzKGEpO1xuICAgICAgICB2YXIga2V5c0IgPSBPYmplY3Qua2V5cyhiKTtcbiAgICAgICAgcmV0dXJuIGtleXNBLmxlbmd0aCA9PT0ga2V5c0IubGVuZ3RoICYmIGtleXNBLmV2ZXJ5KGZ1bmN0aW9uIChrZXkpIHtcbiAgICAgICAgICByZXR1cm4gbG9vc2VFcXVhbChhW2tleV0sIGJba2V5XSlcbiAgICAgICAgfSlcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIC8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0ICovXG4gICAgICAgIHJldHVybiBmYWxzZVxuICAgICAgfVxuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIC8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0ICovXG4gICAgICByZXR1cm4gZmFsc2VcbiAgICB9XG4gIH0gZWxzZSBpZiAoIWlzT2JqZWN0QSAmJiAhaXNPYmplY3RCKSB7XG4gICAgcmV0dXJuIFN0cmluZyhhKSA9PT0gU3RyaW5nKGIpXG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIGZhbHNlXG4gIH1cbn1cblxuZnVuY3Rpb24gbG9vc2VJbmRleE9mIChhcnIsIHZhbCkge1xuICBmb3IgKHZhciBpID0gMDsgaSA8IGFyci5sZW5ndGg7IGkrKykge1xuICAgIGlmIChsb29zZUVxdWFsKGFycltpXSwgdmFsKSkgeyByZXR1cm4gaSB9XG4gIH1cbiAgcmV0dXJuIC0xXG59XG5cbi8qKlxuICogRW5zdXJlIGEgZnVuY3Rpb24gaXMgY2FsbGVkIG9ubHkgb25jZS5cbiAqL1xuZnVuY3Rpb24gb25jZSAoZm4pIHtcbiAgdmFyIGNhbGxlZCA9IGZhbHNlO1xuICByZXR1cm4gZnVuY3Rpb24gKCkge1xuICAgIGlmICghY2FsbGVkKSB7XG4gICAgICBjYWxsZWQgPSB0cnVlO1xuICAgICAgZm4uYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICB9XG4gIH1cbn1cblxudmFyIFNTUl9BVFRSID0gJ2RhdGEtc2VydmVyLXJlbmRlcmVkJztcblxudmFyIEFTU0VUX1RZUEVTID0gW1xuICAnY29tcG9uZW50JyxcbiAgJ2RpcmVjdGl2ZScsXG4gICdmaWx0ZXInXG5dO1xuXG52YXIgTElGRUNZQ0xFX0hPT0tTID0gW1xuICAnYmVmb3JlQ3JlYXRlJyxcbiAgJ2NyZWF0ZWQnLFxuICAnYmVmb3JlTW91bnQnLFxuICAnbW91bnRlZCcsXG4gICdiZWZvcmVVcGRhdGUnLFxuICAndXBkYXRlZCcsXG4gICdiZWZvcmVEZXN0cm95JyxcbiAgJ2Rlc3Ryb3llZCcsXG4gICdhY3RpdmF0ZWQnLFxuICAnZGVhY3RpdmF0ZWQnXG5dO1xuXG4vKiAgKi9cblxudmFyIGNvbmZpZyA9ICh7XG4gIC8qKlxuICAgKiBPcHRpb24gbWVyZ2Ugc3RyYXRlZ2llcyAodXNlZCBpbiBjb3JlL3V0aWwvb3B0aW9ucylcbiAgICovXG4gIG9wdGlvbk1lcmdlU3RyYXRlZ2llczogT2JqZWN0LmNyZWF0ZShudWxsKSxcblxuICAvKipcbiAgICogV2hldGhlciB0byBzdXBwcmVzcyB3YXJuaW5ncy5cbiAgICovXG4gIHNpbGVudDogZmFsc2UsXG5cbiAgLyoqXG4gICAqIFNob3cgcHJvZHVjdGlvbiBtb2RlIHRpcCBtZXNzYWdlIG9uIGJvb3Q/XG4gICAqL1xuICBwcm9kdWN0aW9uVGlwOiBwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nLFxuXG4gIC8qKlxuICAgKiBXaGV0aGVyIHRvIGVuYWJsZSBkZXZ0b29sc1xuICAgKi9cbiAgZGV2dG9vbHM6IHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicsXG5cbiAgLyoqXG4gICAqIFdoZXRoZXIgdG8gcmVjb3JkIHBlcmZcbiAgICovXG4gIHBlcmZvcm1hbmNlOiBmYWxzZSxcblxuICAvKipcbiAgICogRXJyb3IgaGFuZGxlciBmb3Igd2F0Y2hlciBlcnJvcnNcbiAgICovXG4gIGVycm9ySGFuZGxlcjogbnVsbCxcblxuICAvKipcbiAgICogV2FybiBoYW5kbGVyIGZvciB3YXRjaGVyIHdhcm5zXG4gICAqL1xuICB3YXJuSGFuZGxlcjogbnVsbCxcblxuICAvKipcbiAgICogSWdub3JlIGNlcnRhaW4gY3VzdG9tIGVsZW1lbnRzXG4gICAqL1xuICBpZ25vcmVkRWxlbWVudHM6IFtdLFxuXG4gIC8qKlxuICAgKiBDdXN0b20gdXNlciBrZXkgYWxpYXNlcyBmb3Igdi1vblxuICAgKi9cbiAga2V5Q29kZXM6IE9iamVjdC5jcmVhdGUobnVsbCksXG5cbiAgLyoqXG4gICAqIENoZWNrIGlmIGEgdGFnIGlzIHJlc2VydmVkIHNvIHRoYXQgaXQgY2Fubm90IGJlIHJlZ2lzdGVyZWQgYXMgYVxuICAgKiBjb21wb25lbnQuIFRoaXMgaXMgcGxhdGZvcm0tZGVwZW5kZW50IGFuZCBtYXkgYmUgb3ZlcndyaXR0ZW4uXG4gICAqL1xuICBpc1Jlc2VydmVkVGFnOiBubyxcblxuICAvKipcbiAgICogQ2hlY2sgaWYgYW4gYXR0cmlidXRlIGlzIHJlc2VydmVkIHNvIHRoYXQgaXQgY2Fubm90IGJlIHVzZWQgYXMgYSBjb21wb25lbnRcbiAgICogcHJvcC4gVGhpcyBpcyBwbGF0Zm9ybS1kZXBlbmRlbnQgYW5kIG1heSBiZSBvdmVyd3JpdHRlbi5cbiAgICovXG4gIGlzUmVzZXJ2ZWRBdHRyOiBubyxcblxuICAvKipcbiAgICogQ2hlY2sgaWYgYSB0YWcgaXMgYW4gdW5rbm93biBlbGVtZW50LlxuICAgKiBQbGF0Zm9ybS1kZXBlbmRlbnQuXG4gICAqL1xuICBpc1Vua25vd25FbGVtZW50OiBubyxcblxuICAvKipcbiAgICogR2V0IHRoZSBuYW1lc3BhY2Ugb2YgYW4gZWxlbWVudFxuICAgKi9cbiAgZ2V0VGFnTmFtZXNwYWNlOiBub29wLFxuXG4gIC8qKlxuICAgKiBQYXJzZSB0aGUgcmVhbCB0YWcgbmFtZSBmb3IgdGhlIHNwZWNpZmljIHBsYXRmb3JtLlxuICAgKi9cbiAgcGFyc2VQbGF0Zm9ybVRhZ05hbWU6IGlkZW50aXR5LFxuXG4gIC8qKlxuICAgKiBDaGVjayBpZiBhbiBhdHRyaWJ1dGUgbXVzdCBiZSBib3VuZCB1c2luZyBwcm9wZXJ0eSwgZS5nLiB2YWx1ZVxuICAgKiBQbGF0Zm9ybS1kZXBlbmRlbnQuXG4gICAqL1xuICBtdXN0VXNlUHJvcDogbm8sXG5cbiAgLyoqXG4gICAqIEV4cG9zZWQgZm9yIGxlZ2FjeSByZWFzb25zXG4gICAqL1xuICBfbGlmZWN5Y2xlSG9va3M6IExJRkVDWUNMRV9IT09LU1xufSk7XG5cbi8qICAqL1xuXG52YXIgZW1wdHlPYmplY3QgPSBPYmplY3QuZnJlZXplKHt9KTtcblxuLyoqXG4gKiBDaGVjayBpZiBhIHN0cmluZyBzdGFydHMgd2l0aCAkIG9yIF9cbiAqL1xuZnVuY3Rpb24gaXNSZXNlcnZlZCAoc3RyKSB7XG4gIHZhciBjID0gKHN0ciArICcnKS5jaGFyQ29kZUF0KDApO1xuICByZXR1cm4gYyA9PT0gMHgyNCB8fCBjID09PSAweDVGXG59XG5cbi8qKlxuICogRGVmaW5lIGEgcHJvcGVydHkuXG4gKi9cbmZ1bmN0aW9uIGRlZiAob2JqLCBrZXksIHZhbCwgZW51bWVyYWJsZSkge1xuICBPYmplY3QuZGVmaW5lUHJvcGVydHkob2JqLCBrZXksIHtcbiAgICB2YWx1ZTogdmFsLFxuICAgIGVudW1lcmFibGU6ICEhZW51bWVyYWJsZSxcbiAgICB3cml0YWJsZTogdHJ1ZSxcbiAgICBjb25maWd1cmFibGU6IHRydWVcbiAgfSk7XG59XG5cbi8qKlxuICogUGFyc2Ugc2ltcGxlIHBhdGguXG4gKi9cbnZhciBiYWlsUkUgPSAvW15cXHcuJF0vO1xuZnVuY3Rpb24gcGFyc2VQYXRoIChwYXRoKSB7XG4gIGlmIChiYWlsUkUudGVzdChwYXRoKSkge1xuICAgIHJldHVyblxuICB9XG4gIHZhciBzZWdtZW50cyA9IHBhdGguc3BsaXQoJy4nKTtcbiAgcmV0dXJuIGZ1bmN0aW9uIChvYmopIHtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IHNlZ21lbnRzLmxlbmd0aDsgaSsrKSB7XG4gICAgICBpZiAoIW9iaikgeyByZXR1cm4gfVxuICAgICAgb2JqID0gb2JqW3NlZ21lbnRzW2ldXTtcbiAgICB9XG4gICAgcmV0dXJuIG9ialxuICB9XG59XG5cbi8qICAqL1xuXG52YXIgd2FybiA9IG5vb3A7XG52YXIgdGlwID0gbm9vcDtcbnZhciBmb3JtYXRDb21wb25lbnROYW1lID0gKG51bGwpOyAvLyB3b3JrIGFyb3VuZCBmbG93IGNoZWNrXG5cbmlmIChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nKSB7XG4gIHZhciBoYXNDb25zb2xlID0gdHlwZW9mIGNvbnNvbGUgIT09ICd1bmRlZmluZWQnO1xuICB2YXIgY2xhc3NpZnlSRSA9IC8oPzpefFstX10pKFxcdykvZztcbiAgdmFyIGNsYXNzaWZ5ID0gZnVuY3Rpb24gKHN0cikgeyByZXR1cm4gc3RyXG4gICAgLnJlcGxhY2UoY2xhc3NpZnlSRSwgZnVuY3Rpb24gKGMpIHsgcmV0dXJuIGMudG9VcHBlckNhc2UoKTsgfSlcbiAgICAucmVwbGFjZSgvWy1fXS9nLCAnJyk7IH07XG5cbiAgd2FybiA9IGZ1bmN0aW9uIChtc2csIHZtKSB7XG4gICAgdmFyIHRyYWNlID0gdm0gPyBnZW5lcmF0ZUNvbXBvbmVudFRyYWNlKHZtKSA6ICcnO1xuXG4gICAgaWYgKGNvbmZpZy53YXJuSGFuZGxlcikge1xuICAgICAgY29uZmlnLndhcm5IYW5kbGVyLmNhbGwobnVsbCwgbXNnLCB2bSwgdHJhY2UpO1xuICAgIH0gZWxzZSBpZiAoaGFzQ29uc29sZSAmJiAoIWNvbmZpZy5zaWxlbnQpKSB7XG4gICAgICBjb25zb2xlLmVycm9yKChcIltWdWUgd2Fybl06IFwiICsgbXNnICsgdHJhY2UpKTtcbiAgICB9XG4gIH07XG5cbiAgdGlwID0gZnVuY3Rpb24gKG1zZywgdm0pIHtcbiAgICBpZiAoaGFzQ29uc29sZSAmJiAoIWNvbmZpZy5zaWxlbnQpKSB7XG4gICAgICBjb25zb2xlLndhcm4oXCJbVnVlIHRpcF06IFwiICsgbXNnICsgKFxuICAgICAgICB2bSA/IGdlbmVyYXRlQ29tcG9uZW50VHJhY2Uodm0pIDogJydcbiAgICAgICkpO1xuICAgIH1cbiAgfTtcblxuICBmb3JtYXRDb21wb25lbnROYW1lID0gZnVuY3Rpb24gKHZtLCBpbmNsdWRlRmlsZSkge1xuICAgIGlmICh2bS4kcm9vdCA9PT0gdm0pIHtcbiAgICAgIHJldHVybiAnPFJvb3Q+J1xuICAgIH1cbiAgICB2YXIgbmFtZSA9IHR5cGVvZiB2bSA9PT0gJ3N0cmluZydcbiAgICAgID8gdm1cbiAgICAgIDogdHlwZW9mIHZtID09PSAnZnVuY3Rpb24nICYmIHZtLm9wdGlvbnNcbiAgICAgICAgPyB2bS5vcHRpb25zLm5hbWVcbiAgICAgICAgOiB2bS5faXNWdWVcbiAgICAgICAgICA/IHZtLiRvcHRpb25zLm5hbWUgfHwgdm0uJG9wdGlvbnMuX2NvbXBvbmVudFRhZ1xuICAgICAgICAgIDogdm0ubmFtZTtcblxuICAgIHZhciBmaWxlID0gdm0uX2lzVnVlICYmIHZtLiRvcHRpb25zLl9fZmlsZTtcbiAgICBpZiAoIW5hbWUgJiYgZmlsZSkge1xuICAgICAgdmFyIG1hdGNoID0gZmlsZS5tYXRjaCgvKFteL1xcXFxdKylcXC52dWUkLyk7XG4gICAgICBuYW1lID0gbWF0Y2ggJiYgbWF0Y2hbMV07XG4gICAgfVxuXG4gICAgcmV0dXJuIChcbiAgICAgIChuYW1lID8gKFwiPFwiICsgKGNsYXNzaWZ5KG5hbWUpKSArIFwiPlwiKSA6IFwiPEFub255bW91cz5cIikgK1xuICAgICAgKGZpbGUgJiYgaW5jbHVkZUZpbGUgIT09IGZhbHNlID8gKFwiIGF0IFwiICsgZmlsZSkgOiAnJylcbiAgICApXG4gIH07XG5cbiAgdmFyIHJlcGVhdCA9IGZ1bmN0aW9uIChzdHIsIG4pIHtcbiAgICB2YXIgcmVzID0gJyc7XG4gICAgd2hpbGUgKG4pIHtcbiAgICAgIGlmIChuICUgMiA9PT0gMSkgeyByZXMgKz0gc3RyOyB9XG4gICAgICBpZiAobiA+IDEpIHsgc3RyICs9IHN0cjsgfVxuICAgICAgbiA+Pj0gMTtcbiAgICB9XG4gICAgcmV0dXJuIHJlc1xuICB9O1xuXG4gIHZhciBnZW5lcmF0ZUNvbXBvbmVudFRyYWNlID0gZnVuY3Rpb24gKHZtKSB7XG4gICAgaWYgKHZtLl9pc1Z1ZSAmJiB2bS4kcGFyZW50KSB7XG4gICAgICB2YXIgdHJlZSA9IFtdO1xuICAgICAgdmFyIGN1cnJlbnRSZWN1cnNpdmVTZXF1ZW5jZSA9IDA7XG4gICAgICB3aGlsZSAodm0pIHtcbiAgICAgICAgaWYgKHRyZWUubGVuZ3RoID4gMCkge1xuICAgICAgICAgIHZhciBsYXN0ID0gdHJlZVt0cmVlLmxlbmd0aCAtIDFdO1xuICAgICAgICAgIGlmIChsYXN0LmNvbnN0cnVjdG9yID09PSB2bS5jb25zdHJ1Y3Rvcikge1xuICAgICAgICAgICAgY3VycmVudFJlY3Vyc2l2ZVNlcXVlbmNlKys7XG4gICAgICAgICAgICB2bSA9IHZtLiRwYXJlbnQ7XG4gICAgICAgICAgICBjb250aW51ZVxuICAgICAgICAgIH0gZWxzZSBpZiAoY3VycmVudFJlY3Vyc2l2ZVNlcXVlbmNlID4gMCkge1xuICAgICAgICAgICAgdHJlZVt0cmVlLmxlbmd0aCAtIDFdID0gW2xhc3QsIGN1cnJlbnRSZWN1cnNpdmVTZXF1ZW5jZV07XG4gICAgICAgICAgICBjdXJyZW50UmVjdXJzaXZlU2VxdWVuY2UgPSAwO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICB0cmVlLnB1c2godm0pO1xuICAgICAgICB2bSA9IHZtLiRwYXJlbnQ7XG4gICAgICB9XG4gICAgICByZXR1cm4gJ1xcblxcbmZvdW5kIGluXFxuXFxuJyArIHRyZWVcbiAgICAgICAgLm1hcChmdW5jdGlvbiAodm0sIGkpIHsgcmV0dXJuIChcIlwiICsgKGkgPT09IDAgPyAnLS0tPiAnIDogcmVwZWF0KCcgJywgNSArIGkgKiAyKSkgKyAoQXJyYXkuaXNBcnJheSh2bSlcbiAgICAgICAgICAgID8gKChmb3JtYXRDb21wb25lbnROYW1lKHZtWzBdKSkgKyBcIi4uLiAoXCIgKyAodm1bMV0pICsgXCIgcmVjdXJzaXZlIGNhbGxzKVwiKVxuICAgICAgICAgICAgOiBmb3JtYXRDb21wb25lbnROYW1lKHZtKSkpOyB9KVxuICAgICAgICAuam9pbignXFxuJylcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIChcIlxcblxcbihmb3VuZCBpbiBcIiArIChmb3JtYXRDb21wb25lbnROYW1lKHZtKSkgKyBcIilcIilcbiAgICB9XG4gIH07XG59XG5cbi8qICAqL1xuXG5mdW5jdGlvbiBoYW5kbGVFcnJvciAoZXJyLCB2bSwgaW5mbykge1xuICBpZiAoY29uZmlnLmVycm9ySGFuZGxlcikge1xuICAgIGNvbmZpZy5lcnJvckhhbmRsZXIuY2FsbChudWxsLCBlcnIsIHZtLCBpbmZvKTtcbiAgfSBlbHNlIHtcbiAgICBpZiAocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJykge1xuICAgICAgd2FybigoXCJFcnJvciBpbiBcIiArIGluZm8gKyBcIjogXFxcIlwiICsgKGVyci50b1N0cmluZygpKSArIFwiXFxcIlwiKSwgdm0pO1xuICAgIH1cbiAgICAvKiBpc3RhbmJ1bCBpZ25vcmUgZWxzZSAqL1xuICAgIGlmIChpbkJyb3dzZXIgJiYgdHlwZW9mIGNvbnNvbGUgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICBjb25zb2xlLmVycm9yKGVycik7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRocm93IGVyclxuICAgIH1cbiAgfVxufVxuXG4vKiAgKi9cbi8qIGdsb2JhbHMgTXV0YXRpb25PYnNlcnZlciAqL1xuXG4vLyBjYW4gd2UgdXNlIF9fcHJvdG9fXz9cbnZhciBoYXNQcm90byA9ICdfX3Byb3RvX18nIGluIHt9O1xuXG4vLyBCcm93c2VyIGVudmlyb25tZW50IHNuaWZmaW5nXG52YXIgaW5Ccm93c2VyID0gdHlwZW9mIHdpbmRvdyAhPT0gJ3VuZGVmaW5lZCc7XG52YXIgVUEgPSBpbkJyb3dzZXIgJiYgd2luZG93Lm5hdmlnYXRvci51c2VyQWdlbnQudG9Mb3dlckNhc2UoKTtcbnZhciBpc0lFID0gVUEgJiYgL21zaWV8dHJpZGVudC8udGVzdChVQSk7XG52YXIgaXNJRTkgPSBVQSAmJiBVQS5pbmRleE9mKCdtc2llIDkuMCcpID4gMDtcbnZhciBpc0VkZ2UgPSBVQSAmJiBVQS5pbmRleE9mKCdlZGdlLycpID4gMDtcbnZhciBpc0FuZHJvaWQgPSBVQSAmJiBVQS5pbmRleE9mKCdhbmRyb2lkJykgPiAwO1xudmFyIGlzSU9TID0gVUEgJiYgL2lwaG9uZXxpcGFkfGlwb2R8aW9zLy50ZXN0KFVBKTtcbnZhciBpc0Nocm9tZSA9IFVBICYmIC9jaHJvbWVcXC9cXGQrLy50ZXN0KFVBKSAmJiAhaXNFZGdlO1xuXG4vLyBGaXJlZm94IGhhcyBhIFwid2F0Y2hcIiBmdW5jdGlvbiBvbiBPYmplY3QucHJvdG90eXBlLi4uXG52YXIgbmF0aXZlV2F0Y2ggPSAoe30pLndhdGNoO1xuXG52YXIgc3VwcG9ydHNQYXNzaXZlID0gZmFsc2U7XG5pZiAoaW5Ccm93c2VyKSB7XG4gIHRyeSB7XG4gICAgdmFyIG9wdHMgPSB7fTtcbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkob3B0cywgJ3Bhc3NpdmUnLCAoe1xuICAgICAgZ2V0OiBmdW5jdGlvbiBnZXQgKCkge1xuICAgICAgICAvKiBpc3RhbmJ1bCBpZ25vcmUgbmV4dCAqL1xuICAgICAgICBzdXBwb3J0c1Bhc3NpdmUgPSB0cnVlO1xuICAgICAgfVxuICAgIH0pKTsgLy8gaHR0cHM6Ly9naXRodWIuY29tL2ZhY2Vib29rL2Zsb3cvaXNzdWVzLzI4NVxuICAgIHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKCd0ZXN0LXBhc3NpdmUnLCBudWxsLCBvcHRzKTtcbiAgfSBjYXRjaCAoZSkge31cbn1cblxuLy8gdGhpcyBuZWVkcyB0byBiZSBsYXp5LWV2YWxlZCBiZWNhdXNlIHZ1ZSBtYXkgYmUgcmVxdWlyZWQgYmVmb3JlXG4vLyB2dWUtc2VydmVyLXJlbmRlcmVyIGNhbiBzZXQgVlVFX0VOVlxudmFyIF9pc1NlcnZlcjtcbnZhciBpc1NlcnZlclJlbmRlcmluZyA9IGZ1bmN0aW9uICgpIHtcbiAgaWYgKF9pc1NlcnZlciA9PT0gdW5kZWZpbmVkKSB7XG4gICAgLyogaXN0YW5idWwgaWdub3JlIGlmICovXG4gICAgaWYgKCFpbkJyb3dzZXIgJiYgdHlwZW9mIGdsb2JhbCAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgIC8vIGRldGVjdCBwcmVzZW5jZSBvZiB2dWUtc2VydmVyLXJlbmRlcmVyIGFuZCBhdm9pZFxuICAgICAgLy8gV2VicGFjayBzaGltbWluZyB0aGUgcHJvY2Vzc1xuICAgICAgX2lzU2VydmVyID0gZ2xvYmFsWydwcm9jZXNzJ10uZW52LlZVRV9FTlYgPT09ICdzZXJ2ZXInO1xuICAgIH0gZWxzZSB7XG4gICAgICBfaXNTZXJ2ZXIgPSBmYWxzZTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIF9pc1NlcnZlclxufTtcblxuLy8gZGV0ZWN0IGRldnRvb2xzXG52YXIgZGV2dG9vbHMgPSBpbkJyb3dzZXIgJiYgd2luZG93Ll9fVlVFX0RFVlRPT0xTX0dMT0JBTF9IT09LX187XG5cbi8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0ICovXG5mdW5jdGlvbiBpc05hdGl2ZSAoQ3Rvcikge1xuICByZXR1cm4gdHlwZW9mIEN0b3IgPT09ICdmdW5jdGlvbicgJiYgL25hdGl2ZSBjb2RlLy50ZXN0KEN0b3IudG9TdHJpbmcoKSlcbn1cblxudmFyIGhhc1N5bWJvbCA9XG4gIHR5cGVvZiBTeW1ib2wgIT09ICd1bmRlZmluZWQnICYmIGlzTmF0aXZlKFN5bWJvbCkgJiZcbiAgdHlwZW9mIFJlZmxlY3QgIT09ICd1bmRlZmluZWQnICYmIGlzTmF0aXZlKFJlZmxlY3Qub3duS2V5cyk7XG5cbi8qKlxuICogRGVmZXIgYSB0YXNrIHRvIGV4ZWN1dGUgaXQgYXN5bmNocm9ub3VzbHkuXG4gKi9cbnZhciBuZXh0VGljayA9IChmdW5jdGlvbiAoKSB7XG4gIHZhciBjYWxsYmFja3MgPSBbXTtcbiAgdmFyIHBlbmRpbmcgPSBmYWxzZTtcbiAgdmFyIHRpbWVyRnVuYztcblxuICBmdW5jdGlvbiBuZXh0VGlja0hhbmRsZXIgKCkge1xuICAgIHBlbmRpbmcgPSBmYWxzZTtcbiAgICB2YXIgY29waWVzID0gY2FsbGJhY2tzLnNsaWNlKDApO1xuICAgIGNhbGxiYWNrcy5sZW5ndGggPSAwO1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgY29waWVzLmxlbmd0aDsgaSsrKSB7XG4gICAgICBjb3BpZXNbaV0oKTtcbiAgICB9XG4gIH1cblxuICAvLyB0aGUgbmV4dFRpY2sgYmVoYXZpb3IgbGV2ZXJhZ2VzIHRoZSBtaWNyb3Rhc2sgcXVldWUsIHdoaWNoIGNhbiBiZSBhY2Nlc3NlZFxuICAvLyB2aWEgZWl0aGVyIG5hdGl2ZSBQcm9taXNlLnRoZW4gb3IgTXV0YXRpb25PYnNlcnZlci5cbiAgLy8gTXV0YXRpb25PYnNlcnZlciBoYXMgd2lkZXIgc3VwcG9ydCwgaG93ZXZlciBpdCBpcyBzZXJpb3VzbHkgYnVnZ2VkIGluXG4gIC8vIFVJV2ViVmlldyBpbiBpT1MgPj0gOS4zLjMgd2hlbiB0cmlnZ2VyZWQgaW4gdG91Y2ggZXZlbnQgaGFuZGxlcnMuIEl0XG4gIC8vIGNvbXBsZXRlbHkgc3RvcHMgd29ya2luZyBhZnRlciB0cmlnZ2VyaW5nIGEgZmV3IHRpbWVzLi4uIHNvLCBpZiBuYXRpdmVcbiAgLy8gUHJvbWlzZSBpcyBhdmFpbGFibGUsIHdlIHdpbGwgdXNlIGl0OlxuICAvKiBpc3RhbmJ1bCBpZ25vcmUgaWYgKi9cbiAgaWYgKHR5cGVvZiBQcm9taXNlICE9PSAndW5kZWZpbmVkJyAmJiBpc05hdGl2ZShQcm9taXNlKSkge1xuICAgIHZhciBwID0gUHJvbWlzZS5yZXNvbHZlKCk7XG4gICAgdmFyIGxvZ0Vycm9yID0gZnVuY3Rpb24gKGVycikgeyBjb25zb2xlLmVycm9yKGVycik7IH07XG4gICAgdGltZXJGdW5jID0gZnVuY3Rpb24gKCkge1xuICAgICAgcC50aGVuKG5leHRUaWNrSGFuZGxlcikuY2F0Y2gobG9nRXJyb3IpO1xuICAgICAgLy8gaW4gcHJvYmxlbWF0aWMgVUlXZWJWaWV3cywgUHJvbWlzZS50aGVuIGRvZXNuJ3QgY29tcGxldGVseSBicmVhaywgYnV0XG4gICAgICAvLyBpdCBjYW4gZ2V0IHN0dWNrIGluIGEgd2VpcmQgc3RhdGUgd2hlcmUgY2FsbGJhY2tzIGFyZSBwdXNoZWQgaW50byB0aGVcbiAgICAgIC8vIG1pY3JvdGFzayBxdWV1ZSBidXQgdGhlIHF1ZXVlIGlzbid0IGJlaW5nIGZsdXNoZWQsIHVudGlsIHRoZSBicm93c2VyXG4gICAgICAvLyBuZWVkcyB0byBkbyBzb21lIG90aGVyIHdvcmssIGUuZy4gaGFuZGxlIGEgdGltZXIuIFRoZXJlZm9yZSB3ZSBjYW5cbiAgICAgIC8vIFwiZm9yY2VcIiB0aGUgbWljcm90YXNrIHF1ZXVlIHRvIGJlIGZsdXNoZWQgYnkgYWRkaW5nIGFuIGVtcHR5IHRpbWVyLlxuICAgICAgaWYgKGlzSU9TKSB7IHNldFRpbWVvdXQobm9vcCk7IH1cbiAgICB9O1xuICB9IGVsc2UgaWYgKCFpc0lFICYmIHR5cGVvZiBNdXRhdGlvbk9ic2VydmVyICE9PSAndW5kZWZpbmVkJyAmJiAoXG4gICAgaXNOYXRpdmUoTXV0YXRpb25PYnNlcnZlcikgfHxcbiAgICAvLyBQaGFudG9tSlMgYW5kIGlPUyA3LnhcbiAgICBNdXRhdGlvbk9ic2VydmVyLnRvU3RyaW5nKCkgPT09ICdbb2JqZWN0IE11dGF0aW9uT2JzZXJ2ZXJDb25zdHJ1Y3Rvcl0nXG4gICkpIHtcbiAgICAvLyB1c2UgTXV0YXRpb25PYnNlcnZlciB3aGVyZSBuYXRpdmUgUHJvbWlzZSBpcyBub3QgYXZhaWxhYmxlLFxuICAgIC8vIGUuZy4gUGhhbnRvbUpTLCBpT1M3LCBBbmRyb2lkIDQuNFxuICAgIHZhciBjb3VudGVyID0gMTtcbiAgICB2YXIgb2JzZXJ2ZXIgPSBuZXcgTXV0YXRpb25PYnNlcnZlcihuZXh0VGlja0hhbmRsZXIpO1xuICAgIHZhciB0ZXh0Tm9kZSA9IGRvY3VtZW50LmNyZWF0ZVRleHROb2RlKFN0cmluZyhjb3VudGVyKSk7XG4gICAgb2JzZXJ2ZXIub2JzZXJ2ZSh0ZXh0Tm9kZSwge1xuICAgICAgY2hhcmFjdGVyRGF0YTogdHJ1ZVxuICAgIH0pO1xuICAgIHRpbWVyRnVuYyA9IGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvdW50ZXIgPSAoY291bnRlciArIDEpICUgMjtcbiAgICAgIHRleHROb2RlLmRhdGEgPSBTdHJpbmcoY291bnRlcik7XG4gICAgfTtcbiAgfSBlbHNlIHtcbiAgICAvLyBmYWxsYmFjayB0byBzZXRUaW1lb3V0XG4gICAgLyogaXN0YW5idWwgaWdub3JlIG5leHQgKi9cbiAgICB0aW1lckZ1bmMgPSBmdW5jdGlvbiAoKSB7XG4gICAgICBzZXRUaW1lb3V0KG5leHRUaWNrSGFuZGxlciwgMCk7XG4gICAgfTtcbiAgfVxuXG4gIHJldHVybiBmdW5jdGlvbiBxdWV1ZU5leHRUaWNrIChjYiwgY3R4KSB7XG4gICAgdmFyIF9yZXNvbHZlO1xuICAgIGNhbGxiYWNrcy5wdXNoKGZ1bmN0aW9uICgpIHtcbiAgICAgIGlmIChjYikge1xuICAgICAgICB0cnkge1xuICAgICAgICAgIGNiLmNhbGwoY3R4KTtcbiAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgIGhhbmRsZUVycm9yKGUsIGN0eCwgJ25leHRUaWNrJyk7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSBpZiAoX3Jlc29sdmUpIHtcbiAgICAgICAgX3Jlc29sdmUoY3R4KTtcbiAgICAgIH1cbiAgICB9KTtcbiAgICBpZiAoIXBlbmRpbmcpIHtcbiAgICAgIHBlbmRpbmcgPSB0cnVlO1xuICAgICAgdGltZXJGdW5jKCk7XG4gICAgfVxuICAgIGlmICghY2IgJiYgdHlwZW9mIFByb21pc2UgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICByZXR1cm4gbmV3IFByb21pc2UoZnVuY3Rpb24gKHJlc29sdmUsIHJlamVjdCkge1xuICAgICAgICBfcmVzb2x2ZSA9IHJlc29sdmU7XG4gICAgICB9KVxuICAgIH1cbiAgfVxufSkoKTtcblxudmFyIF9TZXQ7XG4vKiBpc3RhbmJ1bCBpZ25vcmUgaWYgKi9cbmlmICh0eXBlb2YgU2V0ICE9PSAndW5kZWZpbmVkJyAmJiBpc05hdGl2ZShTZXQpKSB7XG4gIC8vIHVzZSBuYXRpdmUgU2V0IHdoZW4gYXZhaWxhYmxlLlxuICBfU2V0ID0gU2V0O1xufSBlbHNlIHtcbiAgLy8gYSBub24tc3RhbmRhcmQgU2V0IHBvbHlmaWxsIHRoYXQgb25seSB3b3JrcyB3aXRoIHByaW1pdGl2ZSBrZXlzLlxuICBfU2V0ID0gKGZ1bmN0aW9uICgpIHtcbiAgICBmdW5jdGlvbiBTZXQgKCkge1xuICAgICAgdGhpcy5zZXQgPSBPYmplY3QuY3JlYXRlKG51bGwpO1xuICAgIH1cbiAgICBTZXQucHJvdG90eXBlLmhhcyA9IGZ1bmN0aW9uIGhhcyAoa2V5KSB7XG4gICAgICByZXR1cm4gdGhpcy5zZXRba2V5XSA9PT0gdHJ1ZVxuICAgIH07XG4gICAgU2V0LnByb3RvdHlwZS5hZGQgPSBmdW5jdGlvbiBhZGQgKGtleSkge1xuICAgICAgdGhpcy5zZXRba2V5XSA9IHRydWU7XG4gICAgfTtcbiAgICBTZXQucHJvdG90eXBlLmNsZWFyID0gZnVuY3Rpb24gY2xlYXIgKCkge1xuICAgICAgdGhpcy5zZXQgPSBPYmplY3QuY3JlYXRlKG51bGwpO1xuICAgIH07XG5cbiAgICByZXR1cm4gU2V0O1xuICB9KCkpO1xufVxuXG4vKiAgKi9cblxuXG52YXIgdWlkID0gMDtcblxuLyoqXG4gKiBBIGRlcCBpcyBhbiBvYnNlcnZhYmxlIHRoYXQgY2FuIGhhdmUgbXVsdGlwbGVcbiAqIGRpcmVjdGl2ZXMgc3Vic2NyaWJpbmcgdG8gaXQuXG4gKi9cbnZhciBEZXAgPSBmdW5jdGlvbiBEZXAgKCkge1xuICB0aGlzLmlkID0gdWlkKys7XG4gIHRoaXMuc3VicyA9IFtdO1xufTtcblxuRGVwLnByb3RvdHlwZS5hZGRTdWIgPSBmdW5jdGlvbiBhZGRTdWIgKHN1Yikge1xuICB0aGlzLnN1YnMucHVzaChzdWIpO1xufTtcblxuRGVwLnByb3RvdHlwZS5yZW1vdmVTdWIgPSBmdW5jdGlvbiByZW1vdmVTdWIgKHN1Yikge1xuICByZW1vdmUodGhpcy5zdWJzLCBzdWIpO1xufTtcblxuRGVwLnByb3RvdHlwZS5kZXBlbmQgPSBmdW5jdGlvbiBkZXBlbmQgKCkge1xuICBpZiAoRGVwLnRhcmdldCkge1xuICAgIERlcC50YXJnZXQuYWRkRGVwKHRoaXMpO1xuICB9XG59O1xuXG5EZXAucHJvdG90eXBlLm5vdGlmeSA9IGZ1bmN0aW9uIG5vdGlmeSAoKSB7XG4gIC8vIHN0YWJpbGl6ZSB0aGUgc3Vic2NyaWJlciBsaXN0IGZpcnN0XG4gIHZhciBzdWJzID0gdGhpcy5zdWJzLnNsaWNlKCk7XG4gIGZvciAodmFyIGkgPSAwLCBsID0gc3Vicy5sZW5ndGg7IGkgPCBsOyBpKyspIHtcbiAgICBzdWJzW2ldLnVwZGF0ZSgpO1xuICB9XG59O1xuXG4vLyB0aGUgY3VycmVudCB0YXJnZXQgd2F0Y2hlciBiZWluZyBldmFsdWF0ZWQuXG4vLyB0aGlzIGlzIGdsb2JhbGx5IHVuaXF1ZSBiZWNhdXNlIHRoZXJlIGNvdWxkIGJlIG9ubHkgb25lXG4vLyB3YXRjaGVyIGJlaW5nIGV2YWx1YXRlZCBhdCBhbnkgdGltZS5cbkRlcC50YXJnZXQgPSBudWxsO1xudmFyIHRhcmdldFN0YWNrID0gW107XG5cbmZ1bmN0aW9uIHB1c2hUYXJnZXQgKF90YXJnZXQpIHtcbiAgaWYgKERlcC50YXJnZXQpIHsgdGFyZ2V0U3RhY2sucHVzaChEZXAudGFyZ2V0KTsgfVxuICBEZXAudGFyZ2V0ID0gX3RhcmdldDtcbn1cblxuZnVuY3Rpb24gcG9wVGFyZ2V0ICgpIHtcbiAgRGVwLnRhcmdldCA9IHRhcmdldFN0YWNrLnBvcCgpO1xufVxuXG4vKlxuICogbm90IHR5cGUgY2hlY2tpbmcgdGhpcyBmaWxlIGJlY2F1c2UgZmxvdyBkb2Vzbid0IHBsYXkgd2VsbCB3aXRoXG4gKiBkeW5hbWljYWxseSBhY2Nlc3NpbmcgbWV0aG9kcyBvbiBBcnJheSBwcm90b3R5cGVcbiAqL1xuXG52YXIgYXJyYXlQcm90byA9IEFycmF5LnByb3RvdHlwZTtcbnZhciBhcnJheU1ldGhvZHMgPSBPYmplY3QuY3JlYXRlKGFycmF5UHJvdG8pO1tcbiAgJ3B1c2gnLFxuICAncG9wJyxcbiAgJ3NoaWZ0JyxcbiAgJ3Vuc2hpZnQnLFxuICAnc3BsaWNlJyxcbiAgJ3NvcnQnLFxuICAncmV2ZXJzZSdcbl1cbi5mb3JFYWNoKGZ1bmN0aW9uIChtZXRob2QpIHtcbiAgLy8gY2FjaGUgb3JpZ2luYWwgbWV0aG9kXG4gIHZhciBvcmlnaW5hbCA9IGFycmF5UHJvdG9bbWV0aG9kXTtcbiAgZGVmKGFycmF5TWV0aG9kcywgbWV0aG9kLCBmdW5jdGlvbiBtdXRhdG9yICgpIHtcbiAgICB2YXIgYXJncyA9IFtdLCBsZW4gPSBhcmd1bWVudHMubGVuZ3RoO1xuICAgIHdoaWxlICggbGVuLS0gKSBhcmdzWyBsZW4gXSA9IGFyZ3VtZW50c1sgbGVuIF07XG5cbiAgICB2YXIgcmVzdWx0ID0gb3JpZ2luYWwuYXBwbHkodGhpcywgYXJncyk7XG4gICAgdmFyIG9iID0gdGhpcy5fX29iX187XG4gICAgdmFyIGluc2VydGVkO1xuICAgIHN3aXRjaCAobWV0aG9kKSB7XG4gICAgICBjYXNlICdwdXNoJzpcbiAgICAgIGNhc2UgJ3Vuc2hpZnQnOlxuICAgICAgICBpbnNlcnRlZCA9IGFyZ3M7XG4gICAgICAgIGJyZWFrXG4gICAgICBjYXNlICdzcGxpY2UnOlxuICAgICAgICBpbnNlcnRlZCA9IGFyZ3Muc2xpY2UoMik7XG4gICAgICAgIGJyZWFrXG4gICAgfVxuICAgIGlmIChpbnNlcnRlZCkgeyBvYi5vYnNlcnZlQXJyYXkoaW5zZXJ0ZWQpOyB9XG4gICAgLy8gbm90aWZ5IGNoYW5nZVxuICAgIG9iLmRlcC5ub3RpZnkoKTtcbiAgICByZXR1cm4gcmVzdWx0XG4gIH0pO1xufSk7XG5cbi8qICAqL1xuXG52YXIgYXJyYXlLZXlzID0gT2JqZWN0LmdldE93blByb3BlcnR5TmFtZXMoYXJyYXlNZXRob2RzKTtcblxuLyoqXG4gKiBCeSBkZWZhdWx0LCB3aGVuIGEgcmVhY3RpdmUgcHJvcGVydHkgaXMgc2V0LCB0aGUgbmV3IHZhbHVlIGlzXG4gKiBhbHNvIGNvbnZlcnRlZCB0byBiZWNvbWUgcmVhY3RpdmUuIEhvd2V2ZXIgd2hlbiBwYXNzaW5nIGRvd24gcHJvcHMsXG4gKiB3ZSBkb24ndCB3YW50IHRvIGZvcmNlIGNvbnZlcnNpb24gYmVjYXVzZSB0aGUgdmFsdWUgbWF5IGJlIGEgbmVzdGVkIHZhbHVlXG4gKiB1bmRlciBhIGZyb3plbiBkYXRhIHN0cnVjdHVyZS4gQ29udmVydGluZyBpdCB3b3VsZCBkZWZlYXQgdGhlIG9wdGltaXphdGlvbi5cbiAqL1xudmFyIG9ic2VydmVyU3RhdGUgPSB7XG4gIHNob3VsZENvbnZlcnQ6IHRydWVcbn07XG5cbi8qKlxuICogT2JzZXJ2ZXIgY2xhc3MgdGhhdCBhcmUgYXR0YWNoZWQgdG8gZWFjaCBvYnNlcnZlZFxuICogb2JqZWN0LiBPbmNlIGF0dGFjaGVkLCB0aGUgb2JzZXJ2ZXIgY29udmVydHMgdGFyZ2V0XG4gKiBvYmplY3QncyBwcm9wZXJ0eSBrZXlzIGludG8gZ2V0dGVyL3NldHRlcnMgdGhhdFxuICogY29sbGVjdCBkZXBlbmRlbmNpZXMgYW5kIGRpc3BhdGNoZXMgdXBkYXRlcy5cbiAqL1xudmFyIE9ic2VydmVyID0gZnVuY3Rpb24gT2JzZXJ2ZXIgKHZhbHVlKSB7XG4gIHRoaXMudmFsdWUgPSB2YWx1ZTtcbiAgdGhpcy5kZXAgPSBuZXcgRGVwKCk7XG4gIHRoaXMudm1Db3VudCA9IDA7XG4gIGRlZih2YWx1ZSwgJ19fb2JfXycsIHRoaXMpO1xuICBpZiAoQXJyYXkuaXNBcnJheSh2YWx1ZSkpIHtcbiAgICB2YXIgYXVnbWVudCA9IGhhc1Byb3RvXG4gICAgICA/IHByb3RvQXVnbWVudFxuICAgICAgOiBjb3B5QXVnbWVudDtcbiAgICBhdWdtZW50KHZhbHVlLCBhcnJheU1ldGhvZHMsIGFycmF5S2V5cyk7XG4gICAgdGhpcy5vYnNlcnZlQXJyYXkodmFsdWUpO1xuICB9IGVsc2Uge1xuICAgIHRoaXMud2Fsayh2YWx1ZSk7XG4gIH1cbn07XG5cbi8qKlxuICogV2FsayB0aHJvdWdoIGVhY2ggcHJvcGVydHkgYW5kIGNvbnZlcnQgdGhlbSBpbnRvXG4gKiBnZXR0ZXIvc2V0dGVycy4gVGhpcyBtZXRob2Qgc2hvdWxkIG9ubHkgYmUgY2FsbGVkIHdoZW5cbiAqIHZhbHVlIHR5cGUgaXMgT2JqZWN0LlxuICovXG5PYnNlcnZlci5wcm90b3R5cGUud2FsayA9IGZ1bmN0aW9uIHdhbGsgKG9iaikge1xuICB2YXIga2V5cyA9IE9iamVjdC5rZXlzKG9iaik7XG4gIGZvciAodmFyIGkgPSAwOyBpIDwga2V5cy5sZW5ndGg7IGkrKykge1xuICAgIGRlZmluZVJlYWN0aXZlJCQxKG9iaiwga2V5c1tpXSwgb2JqW2tleXNbaV1dKTtcbiAgfVxufTtcblxuLyoqXG4gKiBPYnNlcnZlIGEgbGlzdCBvZiBBcnJheSBpdGVtcy5cbiAqL1xuT2JzZXJ2ZXIucHJvdG90eXBlLm9ic2VydmVBcnJheSA9IGZ1bmN0aW9uIG9ic2VydmVBcnJheSAoaXRlbXMpIHtcbiAgZm9yICh2YXIgaSA9IDAsIGwgPSBpdGVtcy5sZW5ndGg7IGkgPCBsOyBpKyspIHtcbiAgICBvYnNlcnZlKGl0ZW1zW2ldKTtcbiAgfVxufTtcblxuLy8gaGVscGVyc1xuXG4vKipcbiAqIEF1Z21lbnQgYW4gdGFyZ2V0IE9iamVjdCBvciBBcnJheSBieSBpbnRlcmNlcHRpbmdcbiAqIHRoZSBwcm90b3R5cGUgY2hhaW4gdXNpbmcgX19wcm90b19fXG4gKi9cbmZ1bmN0aW9uIHByb3RvQXVnbWVudCAodGFyZ2V0LCBzcmMsIGtleXMpIHtcbiAgLyogZXNsaW50LWRpc2FibGUgbm8tcHJvdG8gKi9cbiAgdGFyZ2V0Ll9fcHJvdG9fXyA9IHNyYztcbiAgLyogZXNsaW50LWVuYWJsZSBuby1wcm90byAqL1xufVxuXG4vKipcbiAqIEF1Z21lbnQgYW4gdGFyZ2V0IE9iamVjdCBvciBBcnJheSBieSBkZWZpbmluZ1xuICogaGlkZGVuIHByb3BlcnRpZXMuXG4gKi9cbi8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0ICovXG5mdW5jdGlvbiBjb3B5QXVnbWVudCAodGFyZ2V0LCBzcmMsIGtleXMpIHtcbiAgZm9yICh2YXIgaSA9IDAsIGwgPSBrZXlzLmxlbmd0aDsgaSA8IGw7IGkrKykge1xuICAgIHZhciBrZXkgPSBrZXlzW2ldO1xuICAgIGRlZih0YXJnZXQsIGtleSwgc3JjW2tleV0pO1xuICB9XG59XG5cbi8qKlxuICogQXR0ZW1wdCB0byBjcmVhdGUgYW4gb2JzZXJ2ZXIgaW5zdGFuY2UgZm9yIGEgdmFsdWUsXG4gKiByZXR1cm5zIHRoZSBuZXcgb2JzZXJ2ZXIgaWYgc3VjY2Vzc2Z1bGx5IG9ic2VydmVkLFxuICogb3IgdGhlIGV4aXN0aW5nIG9ic2VydmVyIGlmIHRoZSB2YWx1ZSBhbHJlYWR5IGhhcyBvbmUuXG4gKi9cbmZ1bmN0aW9uIG9ic2VydmUgKHZhbHVlLCBhc1Jvb3REYXRhKSB7XG4gIGlmICghaXNPYmplY3QodmFsdWUpKSB7XG4gICAgcmV0dXJuXG4gIH1cbiAgdmFyIG9iO1xuICBpZiAoaGFzT3duKHZhbHVlLCAnX19vYl9fJykgJiYgdmFsdWUuX19vYl9fIGluc3RhbmNlb2YgT2JzZXJ2ZXIpIHtcbiAgICBvYiA9IHZhbHVlLl9fb2JfXztcbiAgfSBlbHNlIGlmIChcbiAgICBvYnNlcnZlclN0YXRlLnNob3VsZENvbnZlcnQgJiZcbiAgICAhaXNTZXJ2ZXJSZW5kZXJpbmcoKSAmJlxuICAgIChBcnJheS5pc0FycmF5KHZhbHVlKSB8fCBpc1BsYWluT2JqZWN0KHZhbHVlKSkgJiZcbiAgICBPYmplY3QuaXNFeHRlbnNpYmxlKHZhbHVlKSAmJlxuICAgICF2YWx1ZS5faXNWdWVcbiAgKSB7XG4gICAgb2IgPSBuZXcgT2JzZXJ2ZXIodmFsdWUpO1xuICB9XG4gIGlmIChhc1Jvb3REYXRhICYmIG9iKSB7XG4gICAgb2Iudm1Db3VudCsrO1xuICB9XG4gIHJldHVybiBvYlxufVxuXG4vKipcbiAqIERlZmluZSBhIHJlYWN0aXZlIHByb3BlcnR5IG9uIGFuIE9iamVjdC5cbiAqL1xuZnVuY3Rpb24gZGVmaW5lUmVhY3RpdmUkJDEgKFxuICBvYmosXG4gIGtleSxcbiAgdmFsLFxuICBjdXN0b21TZXR0ZXIsXG4gIHNoYWxsb3dcbikge1xuICB2YXIgZGVwID0gbmV3IERlcCgpO1xuXG4gIHZhciBwcm9wZXJ0eSA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3Iob2JqLCBrZXkpO1xuICBpZiAocHJvcGVydHkgJiYgcHJvcGVydHkuY29uZmlndXJhYmxlID09PSBmYWxzZSkge1xuICAgIHJldHVyblxuICB9XG5cbiAgLy8gY2F0ZXIgZm9yIHByZS1kZWZpbmVkIGdldHRlci9zZXR0ZXJzXG4gIHZhciBnZXR0ZXIgPSBwcm9wZXJ0eSAmJiBwcm9wZXJ0eS5nZXQ7XG4gIHZhciBzZXR0ZXIgPSBwcm9wZXJ0eSAmJiBwcm9wZXJ0eS5zZXQ7XG5cbiAgdmFyIGNoaWxkT2IgPSAhc2hhbGxvdyAmJiBvYnNlcnZlKHZhbCk7XG4gIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShvYmosIGtleSwge1xuICAgIGVudW1lcmFibGU6IHRydWUsXG4gICAgY29uZmlndXJhYmxlOiB0cnVlLFxuICAgIGdldDogZnVuY3Rpb24gcmVhY3RpdmVHZXR0ZXIgKCkge1xuICAgICAgdmFyIHZhbHVlID0gZ2V0dGVyID8gZ2V0dGVyLmNhbGwob2JqKSA6IHZhbDtcbiAgICAgIGlmIChEZXAudGFyZ2V0KSB7XG4gICAgICAgIGRlcC5kZXBlbmQoKTtcbiAgICAgICAgaWYgKGNoaWxkT2IpIHtcbiAgICAgICAgICBjaGlsZE9iLmRlcC5kZXBlbmQoKTtcbiAgICAgICAgICBpZiAoQXJyYXkuaXNBcnJheSh2YWx1ZSkpIHtcbiAgICAgICAgICAgIGRlcGVuZEFycmF5KHZhbHVlKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHJldHVybiB2YWx1ZVxuICAgIH0sXG4gICAgc2V0OiBmdW5jdGlvbiByZWFjdGl2ZVNldHRlciAobmV3VmFsKSB7XG4gICAgICB2YXIgdmFsdWUgPSBnZXR0ZXIgPyBnZXR0ZXIuY2FsbChvYmopIDogdmFsO1xuICAgICAgLyogZXNsaW50LWRpc2FibGUgbm8tc2VsZi1jb21wYXJlICovXG4gICAgICBpZiAobmV3VmFsID09PSB2YWx1ZSB8fCAobmV3VmFsICE9PSBuZXdWYWwgJiYgdmFsdWUgIT09IHZhbHVlKSkge1xuICAgICAgICByZXR1cm5cbiAgICAgIH1cbiAgICAgIC8qIGVzbGludC1lbmFibGUgbm8tc2VsZi1jb21wYXJlICovXG4gICAgICBpZiAocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJyAmJiBjdXN0b21TZXR0ZXIpIHtcbiAgICAgICAgY3VzdG9tU2V0dGVyKCk7XG4gICAgICB9XG4gICAgICBpZiAoc2V0dGVyKSB7XG4gICAgICAgIHNldHRlci5jYWxsKG9iaiwgbmV3VmFsKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHZhbCA9IG5ld1ZhbDtcbiAgICAgIH1cbiAgICAgIGNoaWxkT2IgPSAhc2hhbGxvdyAmJiBvYnNlcnZlKG5ld1ZhbCk7XG4gICAgICBkZXAubm90aWZ5KCk7XG4gICAgfVxuICB9KTtcbn1cblxuLyoqXG4gKiBTZXQgYSBwcm9wZXJ0eSBvbiBhbiBvYmplY3QuIEFkZHMgdGhlIG5ldyBwcm9wZXJ0eSBhbmRcbiAqIHRyaWdnZXJzIGNoYW5nZSBub3RpZmljYXRpb24gaWYgdGhlIHByb3BlcnR5IGRvZXNuJ3RcbiAqIGFscmVhZHkgZXhpc3QuXG4gKi9cbmZ1bmN0aW9uIHNldCAodGFyZ2V0LCBrZXksIHZhbCkge1xuICBpZiAoQXJyYXkuaXNBcnJheSh0YXJnZXQpICYmIGlzVmFsaWRBcnJheUluZGV4KGtleSkpIHtcbiAgICB0YXJnZXQubGVuZ3RoID0gTWF0aC5tYXgodGFyZ2V0Lmxlbmd0aCwga2V5KTtcbiAgICB0YXJnZXQuc3BsaWNlKGtleSwgMSwgdmFsKTtcbiAgICByZXR1cm4gdmFsXG4gIH1cbiAgaWYgKGhhc093bih0YXJnZXQsIGtleSkpIHtcbiAgICB0YXJnZXRba2V5XSA9IHZhbDtcbiAgICByZXR1cm4gdmFsXG4gIH1cbiAgdmFyIG9iID0gKHRhcmdldCkuX19vYl9fO1xuICBpZiAodGFyZ2V0Ll9pc1Z1ZSB8fCAob2IgJiYgb2Iudm1Db3VudCkpIHtcbiAgICBwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nICYmIHdhcm4oXG4gICAgICAnQXZvaWQgYWRkaW5nIHJlYWN0aXZlIHByb3BlcnRpZXMgdG8gYSBWdWUgaW5zdGFuY2Ugb3IgaXRzIHJvb3QgJGRhdGEgJyArXG4gICAgICAnYXQgcnVudGltZSAtIGRlY2xhcmUgaXQgdXBmcm9udCBpbiB0aGUgZGF0YSBvcHRpb24uJ1xuICAgICk7XG4gICAgcmV0dXJuIHZhbFxuICB9XG4gIGlmICghb2IpIHtcbiAgICB0YXJnZXRba2V5XSA9IHZhbDtcbiAgICByZXR1cm4gdmFsXG4gIH1cbiAgZGVmaW5lUmVhY3RpdmUkJDEob2IudmFsdWUsIGtleSwgdmFsKTtcbiAgb2IuZGVwLm5vdGlmeSgpO1xuICByZXR1cm4gdmFsXG59XG5cbi8qKlxuICogRGVsZXRlIGEgcHJvcGVydHkgYW5kIHRyaWdnZXIgY2hhbmdlIGlmIG5lY2Vzc2FyeS5cbiAqL1xuZnVuY3Rpb24gZGVsICh0YXJnZXQsIGtleSkge1xuICBpZiAoQXJyYXkuaXNBcnJheSh0YXJnZXQpICYmIGlzVmFsaWRBcnJheUluZGV4KGtleSkpIHtcbiAgICB0YXJnZXQuc3BsaWNlKGtleSwgMSk7XG4gICAgcmV0dXJuXG4gIH1cbiAgdmFyIG9iID0gKHRhcmdldCkuX19vYl9fO1xuICBpZiAodGFyZ2V0Ll9pc1Z1ZSB8fCAob2IgJiYgb2Iudm1Db3VudCkpIHtcbiAgICBwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nICYmIHdhcm4oXG4gICAgICAnQXZvaWQgZGVsZXRpbmcgcHJvcGVydGllcyBvbiBhIFZ1ZSBpbnN0YW5jZSBvciBpdHMgcm9vdCAkZGF0YSAnICtcbiAgICAgICctIGp1c3Qgc2V0IGl0IHRvIG51bGwuJ1xuICAgICk7XG4gICAgcmV0dXJuXG4gIH1cbiAgaWYgKCFoYXNPd24odGFyZ2V0LCBrZXkpKSB7XG4gICAgcmV0dXJuXG4gIH1cbiAgZGVsZXRlIHRhcmdldFtrZXldO1xuICBpZiAoIW9iKSB7XG4gICAgcmV0dXJuXG4gIH1cbiAgb2IuZGVwLm5vdGlmeSgpO1xufVxuXG4vKipcbiAqIENvbGxlY3QgZGVwZW5kZW5jaWVzIG9uIGFycmF5IGVsZW1lbnRzIHdoZW4gdGhlIGFycmF5IGlzIHRvdWNoZWQsIHNpbmNlXG4gKiB3ZSBjYW5ub3QgaW50ZXJjZXB0IGFycmF5IGVsZW1lbnQgYWNjZXNzIGxpa2UgcHJvcGVydHkgZ2V0dGVycy5cbiAqL1xuZnVuY3Rpb24gZGVwZW5kQXJyYXkgKHZhbHVlKSB7XG4gIGZvciAodmFyIGUgPSAodm9pZCAwKSwgaSA9IDAsIGwgPSB2YWx1ZS5sZW5ndGg7IGkgPCBsOyBpKyspIHtcbiAgICBlID0gdmFsdWVbaV07XG4gICAgZSAmJiBlLl9fb2JfXyAmJiBlLl9fb2JfXy5kZXAuZGVwZW5kKCk7XG4gICAgaWYgKEFycmF5LmlzQXJyYXkoZSkpIHtcbiAgICAgIGRlcGVuZEFycmF5KGUpO1xuICAgIH1cbiAgfVxufVxuXG4vKiAgKi9cblxuLyoqXG4gKiBPcHRpb24gb3ZlcndyaXRpbmcgc3RyYXRlZ2llcyBhcmUgZnVuY3Rpb25zIHRoYXQgaGFuZGxlXG4gKiBob3cgdG8gbWVyZ2UgYSBwYXJlbnQgb3B0aW9uIHZhbHVlIGFuZCBhIGNoaWxkIG9wdGlvblxuICogdmFsdWUgaW50byB0aGUgZmluYWwgdmFsdWUuXG4gKi9cbnZhciBzdHJhdHMgPSBjb25maWcub3B0aW9uTWVyZ2VTdHJhdGVnaWVzO1xuXG4vKipcbiAqIE9wdGlvbnMgd2l0aCByZXN0cmljdGlvbnNcbiAqL1xuaWYgKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicpIHtcbiAgc3RyYXRzLmVsID0gc3RyYXRzLnByb3BzRGF0YSA9IGZ1bmN0aW9uIChwYXJlbnQsIGNoaWxkLCB2bSwga2V5KSB7XG4gICAgaWYgKCF2bSkge1xuICAgICAgd2FybihcbiAgICAgICAgXCJvcHRpb24gXFxcIlwiICsga2V5ICsgXCJcXFwiIGNhbiBvbmx5IGJlIHVzZWQgZHVyaW5nIGluc3RhbmNlIFwiICtcbiAgICAgICAgJ2NyZWF0aW9uIHdpdGggdGhlIGBuZXdgIGtleXdvcmQuJ1xuICAgICAgKTtcbiAgICB9XG4gICAgcmV0dXJuIGRlZmF1bHRTdHJhdChwYXJlbnQsIGNoaWxkKVxuICB9O1xufVxuXG4vKipcbiAqIEhlbHBlciB0aGF0IHJlY3Vyc2l2ZWx5IG1lcmdlcyB0d28gZGF0YSBvYmplY3RzIHRvZ2V0aGVyLlxuICovXG5mdW5jdGlvbiBtZXJnZURhdGEgKHRvLCBmcm9tKSB7XG4gIGlmICghZnJvbSkgeyByZXR1cm4gdG8gfVxuICB2YXIga2V5LCB0b1ZhbCwgZnJvbVZhbDtcbiAgdmFyIGtleXMgPSBPYmplY3Qua2V5cyhmcm9tKTtcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBrZXlzLmxlbmd0aDsgaSsrKSB7XG4gICAga2V5ID0ga2V5c1tpXTtcbiAgICB0b1ZhbCA9IHRvW2tleV07XG4gICAgZnJvbVZhbCA9IGZyb21ba2V5XTtcbiAgICBpZiAoIWhhc093bih0bywga2V5KSkge1xuICAgICAgc2V0KHRvLCBrZXksIGZyb21WYWwpO1xuICAgIH0gZWxzZSBpZiAoaXNQbGFpbk9iamVjdCh0b1ZhbCkgJiYgaXNQbGFpbk9iamVjdChmcm9tVmFsKSkge1xuICAgICAgbWVyZ2VEYXRhKHRvVmFsLCBmcm9tVmFsKTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIHRvXG59XG5cbi8qKlxuICogRGF0YVxuICovXG5mdW5jdGlvbiBtZXJnZURhdGFPckZuIChcbiAgcGFyZW50VmFsLFxuICBjaGlsZFZhbCxcbiAgdm1cbikge1xuICBpZiAoIXZtKSB7XG4gICAgLy8gaW4gYSBWdWUuZXh0ZW5kIG1lcmdlLCBib3RoIHNob3VsZCBiZSBmdW5jdGlvbnNcbiAgICBpZiAoIWNoaWxkVmFsKSB7XG4gICAgICByZXR1cm4gcGFyZW50VmFsXG4gICAgfVxuICAgIGlmICghcGFyZW50VmFsKSB7XG4gICAgICByZXR1cm4gY2hpbGRWYWxcbiAgICB9XG4gICAgLy8gd2hlbiBwYXJlbnRWYWwgJiBjaGlsZFZhbCBhcmUgYm90aCBwcmVzZW50LFxuICAgIC8vIHdlIG5lZWQgdG8gcmV0dXJuIGEgZnVuY3Rpb24gdGhhdCByZXR1cm5zIHRoZVxuICAgIC8vIG1lcmdlZCByZXN1bHQgb2YgYm90aCBmdW5jdGlvbnMuLi4gbm8gbmVlZCB0b1xuICAgIC8vIGNoZWNrIGlmIHBhcmVudFZhbCBpcyBhIGZ1bmN0aW9uIGhlcmUgYmVjYXVzZVxuICAgIC8vIGl0IGhhcyB0byBiZSBhIGZ1bmN0aW9uIHRvIHBhc3MgcHJldmlvdXMgbWVyZ2VzLlxuICAgIHJldHVybiBmdW5jdGlvbiBtZXJnZWREYXRhRm4gKCkge1xuICAgICAgcmV0dXJuIG1lcmdlRGF0YShcbiAgICAgICAgdHlwZW9mIGNoaWxkVmFsID09PSAnZnVuY3Rpb24nID8gY2hpbGRWYWwuY2FsbCh0aGlzKSA6IGNoaWxkVmFsLFxuICAgICAgICB0eXBlb2YgcGFyZW50VmFsID09PSAnZnVuY3Rpb24nID8gcGFyZW50VmFsLmNhbGwodGhpcykgOiBwYXJlbnRWYWxcbiAgICAgIClcbiAgICB9XG4gIH0gZWxzZSBpZiAocGFyZW50VmFsIHx8IGNoaWxkVmFsKSB7XG4gICAgcmV0dXJuIGZ1bmN0aW9uIG1lcmdlZEluc3RhbmNlRGF0YUZuICgpIHtcbiAgICAgIC8vIGluc3RhbmNlIG1lcmdlXG4gICAgICB2YXIgaW5zdGFuY2VEYXRhID0gdHlwZW9mIGNoaWxkVmFsID09PSAnZnVuY3Rpb24nXG4gICAgICAgID8gY2hpbGRWYWwuY2FsbCh2bSlcbiAgICAgICAgOiBjaGlsZFZhbDtcbiAgICAgIHZhciBkZWZhdWx0RGF0YSA9IHR5cGVvZiBwYXJlbnRWYWwgPT09ICdmdW5jdGlvbidcbiAgICAgICAgPyBwYXJlbnRWYWwuY2FsbCh2bSlcbiAgICAgICAgOiBwYXJlbnRWYWw7XG4gICAgICBpZiAoaW5zdGFuY2VEYXRhKSB7XG4gICAgICAgIHJldHVybiBtZXJnZURhdGEoaW5zdGFuY2VEYXRhLCBkZWZhdWx0RGF0YSlcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiBkZWZhdWx0RGF0YVxuICAgICAgfVxuICAgIH1cbiAgfVxufVxuXG5zdHJhdHMuZGF0YSA9IGZ1bmN0aW9uIChcbiAgcGFyZW50VmFsLFxuICBjaGlsZFZhbCxcbiAgdm1cbikge1xuICBpZiAoIXZtKSB7XG4gICAgaWYgKGNoaWxkVmFsICYmIHR5cGVvZiBjaGlsZFZhbCAhPT0gJ2Z1bmN0aW9uJykge1xuICAgICAgcHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJyAmJiB3YXJuKFxuICAgICAgICAnVGhlIFwiZGF0YVwiIG9wdGlvbiBzaG91bGQgYmUgYSBmdW5jdGlvbiAnICtcbiAgICAgICAgJ3RoYXQgcmV0dXJucyBhIHBlci1pbnN0YW5jZSB2YWx1ZSBpbiBjb21wb25lbnQgJyArXG4gICAgICAgICdkZWZpbml0aW9ucy4nLFxuICAgICAgICB2bVxuICAgICAgKTtcblxuICAgICAgcmV0dXJuIHBhcmVudFZhbFxuICAgIH1cbiAgICByZXR1cm4gbWVyZ2VEYXRhT3JGbi5jYWxsKHRoaXMsIHBhcmVudFZhbCwgY2hpbGRWYWwpXG4gIH1cblxuICByZXR1cm4gbWVyZ2VEYXRhT3JGbihwYXJlbnRWYWwsIGNoaWxkVmFsLCB2bSlcbn07XG5cbi8qKlxuICogSG9va3MgYW5kIHByb3BzIGFyZSBtZXJnZWQgYXMgYXJyYXlzLlxuICovXG5mdW5jdGlvbiBtZXJnZUhvb2sgKFxuICBwYXJlbnRWYWwsXG4gIGNoaWxkVmFsXG4pIHtcbiAgcmV0dXJuIGNoaWxkVmFsXG4gICAgPyBwYXJlbnRWYWxcbiAgICAgID8gcGFyZW50VmFsLmNvbmNhdChjaGlsZFZhbClcbiAgICAgIDogQXJyYXkuaXNBcnJheShjaGlsZFZhbClcbiAgICAgICAgPyBjaGlsZFZhbFxuICAgICAgICA6IFtjaGlsZFZhbF1cbiAgICA6IHBhcmVudFZhbFxufVxuXG5MSUZFQ1lDTEVfSE9PS1MuZm9yRWFjaChmdW5jdGlvbiAoaG9vaykge1xuICBzdHJhdHNbaG9va10gPSBtZXJnZUhvb2s7XG59KTtcblxuLyoqXG4gKiBBc3NldHNcbiAqXG4gKiBXaGVuIGEgdm0gaXMgcHJlc2VudCAoaW5zdGFuY2UgY3JlYXRpb24pLCB3ZSBuZWVkIHRvIGRvXG4gKiBhIHRocmVlLXdheSBtZXJnZSBiZXR3ZWVuIGNvbnN0cnVjdG9yIG9wdGlvbnMsIGluc3RhbmNlXG4gKiBvcHRpb25zIGFuZCBwYXJlbnQgb3B0aW9ucy5cbiAqL1xuZnVuY3Rpb24gbWVyZ2VBc3NldHMgKHBhcmVudFZhbCwgY2hpbGRWYWwpIHtcbiAgdmFyIHJlcyA9IE9iamVjdC5jcmVhdGUocGFyZW50VmFsIHx8IG51bGwpO1xuICByZXR1cm4gY2hpbGRWYWxcbiAgICA/IGV4dGVuZChyZXMsIGNoaWxkVmFsKVxuICAgIDogcmVzXG59XG5cbkFTU0VUX1RZUEVTLmZvckVhY2goZnVuY3Rpb24gKHR5cGUpIHtcbiAgc3RyYXRzW3R5cGUgKyAncyddID0gbWVyZ2VBc3NldHM7XG59KTtcblxuLyoqXG4gKiBXYXRjaGVycy5cbiAqXG4gKiBXYXRjaGVycyBoYXNoZXMgc2hvdWxkIG5vdCBvdmVyd3JpdGUgb25lXG4gKiBhbm90aGVyLCBzbyB3ZSBtZXJnZSB0aGVtIGFzIGFycmF5cy5cbiAqL1xuc3RyYXRzLndhdGNoID0gZnVuY3Rpb24gKHBhcmVudFZhbCwgY2hpbGRWYWwpIHtcbiAgLy8gd29yayBhcm91bmQgRmlyZWZveCdzIE9iamVjdC5wcm90b3R5cGUud2F0Y2guLi5cbiAgaWYgKHBhcmVudFZhbCA9PT0gbmF0aXZlV2F0Y2gpIHsgcGFyZW50VmFsID0gdW5kZWZpbmVkOyB9XG4gIGlmIChjaGlsZFZhbCA9PT0gbmF0aXZlV2F0Y2gpIHsgY2hpbGRWYWwgPSB1bmRlZmluZWQ7IH1cbiAgLyogaXN0YW5idWwgaWdub3JlIGlmICovXG4gIGlmICghY2hpbGRWYWwpIHsgcmV0dXJuIE9iamVjdC5jcmVhdGUocGFyZW50VmFsIHx8IG51bGwpIH1cbiAgaWYgKCFwYXJlbnRWYWwpIHsgcmV0dXJuIGNoaWxkVmFsIH1cbiAgdmFyIHJldCA9IHt9O1xuICBleHRlbmQocmV0LCBwYXJlbnRWYWwpO1xuICBmb3IgKHZhciBrZXkgaW4gY2hpbGRWYWwpIHtcbiAgICB2YXIgcGFyZW50ID0gcmV0W2tleV07XG4gICAgdmFyIGNoaWxkID0gY2hpbGRWYWxba2V5XTtcbiAgICBpZiAocGFyZW50ICYmICFBcnJheS5pc0FycmF5KHBhcmVudCkpIHtcbiAgICAgIHBhcmVudCA9IFtwYXJlbnRdO1xuICAgIH1cbiAgICByZXRba2V5XSA9IHBhcmVudFxuICAgICAgPyBwYXJlbnQuY29uY2F0KGNoaWxkKVxuICAgICAgOiBBcnJheS5pc0FycmF5KGNoaWxkKSA/IGNoaWxkIDogW2NoaWxkXTtcbiAgfVxuICByZXR1cm4gcmV0XG59O1xuXG4vKipcbiAqIE90aGVyIG9iamVjdCBoYXNoZXMuXG4gKi9cbnN0cmF0cy5wcm9wcyA9XG5zdHJhdHMubWV0aG9kcyA9XG5zdHJhdHMuaW5qZWN0ID1cbnN0cmF0cy5jb21wdXRlZCA9IGZ1bmN0aW9uIChwYXJlbnRWYWwsIGNoaWxkVmFsKSB7XG4gIGlmICghcGFyZW50VmFsKSB7IHJldHVybiBjaGlsZFZhbCB9XG4gIHZhciByZXQgPSBPYmplY3QuY3JlYXRlKG51bGwpO1xuICBleHRlbmQocmV0LCBwYXJlbnRWYWwpO1xuICBpZiAoY2hpbGRWYWwpIHsgZXh0ZW5kKHJldCwgY2hpbGRWYWwpOyB9XG4gIHJldHVybiByZXRcbn07XG5zdHJhdHMucHJvdmlkZSA9IG1lcmdlRGF0YU9yRm47XG5cbi8qKlxuICogRGVmYXVsdCBzdHJhdGVneS5cbiAqL1xudmFyIGRlZmF1bHRTdHJhdCA9IGZ1bmN0aW9uIChwYXJlbnRWYWwsIGNoaWxkVmFsKSB7XG4gIHJldHVybiBjaGlsZFZhbCA9PT0gdW5kZWZpbmVkXG4gICAgPyBwYXJlbnRWYWxcbiAgICA6IGNoaWxkVmFsXG59O1xuXG4vKipcbiAqIFZhbGlkYXRlIGNvbXBvbmVudCBuYW1lc1xuICovXG5mdW5jdGlvbiBjaGVja0NvbXBvbmVudHMgKG9wdGlvbnMpIHtcbiAgZm9yICh2YXIga2V5IGluIG9wdGlvbnMuY29tcG9uZW50cykge1xuICAgIHZhciBsb3dlciA9IGtleS50b0xvd2VyQ2FzZSgpO1xuICAgIGlmIChpc0J1aWx0SW5UYWcobG93ZXIpIHx8IGNvbmZpZy5pc1Jlc2VydmVkVGFnKGxvd2VyKSkge1xuICAgICAgd2FybihcbiAgICAgICAgJ0RvIG5vdCB1c2UgYnVpbHQtaW4gb3IgcmVzZXJ2ZWQgSFRNTCBlbGVtZW50cyBhcyBjb21wb25lbnQgJyArXG4gICAgICAgICdpZDogJyArIGtleVxuICAgICAgKTtcbiAgICB9XG4gIH1cbn1cblxuLyoqXG4gKiBFbnN1cmUgYWxsIHByb3BzIG9wdGlvbiBzeW50YXggYXJlIG5vcm1hbGl6ZWQgaW50byB0aGVcbiAqIE9iamVjdC1iYXNlZCBmb3JtYXQuXG4gKi9cbmZ1bmN0aW9uIG5vcm1hbGl6ZVByb3BzIChvcHRpb25zKSB7XG4gIHZhciBwcm9wcyA9IG9wdGlvbnMucHJvcHM7XG4gIGlmICghcHJvcHMpIHsgcmV0dXJuIH1cbiAgdmFyIHJlcyA9IHt9O1xuICB2YXIgaSwgdmFsLCBuYW1lO1xuICBpZiAoQXJyYXkuaXNBcnJheShwcm9wcykpIHtcbiAgICBpID0gcHJvcHMubGVuZ3RoO1xuICAgIHdoaWxlIChpLS0pIHtcbiAgICAgIHZhbCA9IHByb3BzW2ldO1xuICAgICAgaWYgKHR5cGVvZiB2YWwgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgIG5hbWUgPSBjYW1lbGl6ZSh2YWwpO1xuICAgICAgICByZXNbbmFtZV0gPSB7IHR5cGU6IG51bGwgfTtcbiAgICAgIH0gZWxzZSBpZiAocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJykge1xuICAgICAgICB3YXJuKCdwcm9wcyBtdXN0IGJlIHN0cmluZ3Mgd2hlbiB1c2luZyBhcnJheSBzeW50YXguJyk7XG4gICAgICB9XG4gICAgfVxuICB9IGVsc2UgaWYgKGlzUGxhaW5PYmplY3QocHJvcHMpKSB7XG4gICAgZm9yICh2YXIga2V5IGluIHByb3BzKSB7XG4gICAgICB2YWwgPSBwcm9wc1trZXldO1xuICAgICAgbmFtZSA9IGNhbWVsaXplKGtleSk7XG4gICAgICByZXNbbmFtZV0gPSBpc1BsYWluT2JqZWN0KHZhbClcbiAgICAgICAgPyB2YWxcbiAgICAgICAgOiB7IHR5cGU6IHZhbCB9O1xuICAgIH1cbiAgfVxuICBvcHRpb25zLnByb3BzID0gcmVzO1xufVxuXG4vKipcbiAqIE5vcm1hbGl6ZSBhbGwgaW5qZWN0aW9ucyBpbnRvIE9iamVjdC1iYXNlZCBmb3JtYXRcbiAqL1xuZnVuY3Rpb24gbm9ybWFsaXplSW5qZWN0IChvcHRpb25zKSB7XG4gIHZhciBpbmplY3QgPSBvcHRpb25zLmluamVjdDtcbiAgaWYgKEFycmF5LmlzQXJyYXkoaW5qZWN0KSkge1xuICAgIHZhciBub3JtYWxpemVkID0gb3B0aW9ucy5pbmplY3QgPSB7fTtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGluamVjdC5sZW5ndGg7IGkrKykge1xuICAgICAgbm9ybWFsaXplZFtpbmplY3RbaV1dID0gaW5qZWN0W2ldO1xuICAgIH1cbiAgfVxufVxuXG4vKipcbiAqIE5vcm1hbGl6ZSByYXcgZnVuY3Rpb24gZGlyZWN0aXZlcyBpbnRvIG9iamVjdCBmb3JtYXQuXG4gKi9cbmZ1bmN0aW9uIG5vcm1hbGl6ZURpcmVjdGl2ZXMgKG9wdGlvbnMpIHtcbiAgdmFyIGRpcnMgPSBvcHRpb25zLmRpcmVjdGl2ZXM7XG4gIGlmIChkaXJzKSB7XG4gICAgZm9yICh2YXIga2V5IGluIGRpcnMpIHtcbiAgICAgIHZhciBkZWYgPSBkaXJzW2tleV07XG4gICAgICBpZiAodHlwZW9mIGRlZiA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICBkaXJzW2tleV0gPSB7IGJpbmQ6IGRlZiwgdXBkYXRlOiBkZWYgfTtcbiAgICAgIH1cbiAgICB9XG4gIH1cbn1cblxuLyoqXG4gKiBNZXJnZSB0d28gb3B0aW9uIG9iamVjdHMgaW50byBhIG5ldyBvbmUuXG4gKiBDb3JlIHV0aWxpdHkgdXNlZCBpbiBib3RoIGluc3RhbnRpYXRpb24gYW5kIGluaGVyaXRhbmNlLlxuICovXG5mdW5jdGlvbiBtZXJnZU9wdGlvbnMgKFxuICBwYXJlbnQsXG4gIGNoaWxkLFxuICB2bVxuKSB7XG4gIGlmIChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nKSB7XG4gICAgY2hlY2tDb21wb25lbnRzKGNoaWxkKTtcbiAgfVxuXG4gIGlmICh0eXBlb2YgY2hpbGQgPT09ICdmdW5jdGlvbicpIHtcbiAgICBjaGlsZCA9IGNoaWxkLm9wdGlvbnM7XG4gIH1cblxuICBub3JtYWxpemVQcm9wcyhjaGlsZCk7XG4gIG5vcm1hbGl6ZUluamVjdChjaGlsZCk7XG4gIG5vcm1hbGl6ZURpcmVjdGl2ZXMoY2hpbGQpO1xuICB2YXIgZXh0ZW5kc0Zyb20gPSBjaGlsZC5leHRlbmRzO1xuICBpZiAoZXh0ZW5kc0Zyb20pIHtcbiAgICBwYXJlbnQgPSBtZXJnZU9wdGlvbnMocGFyZW50LCBleHRlbmRzRnJvbSwgdm0pO1xuICB9XG4gIGlmIChjaGlsZC5taXhpbnMpIHtcbiAgICBmb3IgKHZhciBpID0gMCwgbCA9IGNoaWxkLm1peGlucy5sZW5ndGg7IGkgPCBsOyBpKyspIHtcbiAgICAgIHBhcmVudCA9IG1lcmdlT3B0aW9ucyhwYXJlbnQsIGNoaWxkLm1peGluc1tpXSwgdm0pO1xuICAgIH1cbiAgfVxuICB2YXIgb3B0aW9ucyA9IHt9O1xuICB2YXIga2V5O1xuICBmb3IgKGtleSBpbiBwYXJlbnQpIHtcbiAgICBtZXJnZUZpZWxkKGtleSk7XG4gIH1cbiAgZm9yIChrZXkgaW4gY2hpbGQpIHtcbiAgICBpZiAoIWhhc093bihwYXJlbnQsIGtleSkpIHtcbiAgICAgIG1lcmdlRmllbGQoa2V5KTtcbiAgICB9XG4gIH1cbiAgZnVuY3Rpb24gbWVyZ2VGaWVsZCAoa2V5KSB7XG4gICAgdmFyIHN0cmF0ID0gc3RyYXRzW2tleV0gfHwgZGVmYXVsdFN0cmF0O1xuICAgIG9wdGlvbnNba2V5XSA9IHN0cmF0KHBhcmVudFtrZXldLCBjaGlsZFtrZXldLCB2bSwga2V5KTtcbiAgfVxuICByZXR1cm4gb3B0aW9uc1xufVxuXG4vKipcbiAqIFJlc29sdmUgYW4gYXNzZXQuXG4gKiBUaGlzIGZ1bmN0aW9uIGlzIHVzZWQgYmVjYXVzZSBjaGlsZCBpbnN0YW5jZXMgbmVlZCBhY2Nlc3NcbiAqIHRvIGFzc2V0cyBkZWZpbmVkIGluIGl0cyBhbmNlc3RvciBjaGFpbi5cbiAqL1xuZnVuY3Rpb24gcmVzb2x2ZUFzc2V0IChcbiAgb3B0aW9ucyxcbiAgdHlwZSxcbiAgaWQsXG4gIHdhcm5NaXNzaW5nXG4pIHtcbiAgLyogaXN0YW5idWwgaWdub3JlIGlmICovXG4gIGlmICh0eXBlb2YgaWQgIT09ICdzdHJpbmcnKSB7XG4gICAgcmV0dXJuXG4gIH1cbiAgdmFyIGFzc2V0cyA9IG9wdGlvbnNbdHlwZV07XG4gIC8vIGNoZWNrIGxvY2FsIHJlZ2lzdHJhdGlvbiB2YXJpYXRpb25zIGZpcnN0XG4gIGlmIChoYXNPd24oYXNzZXRzLCBpZCkpIHsgcmV0dXJuIGFzc2V0c1tpZF0gfVxuICB2YXIgY2FtZWxpemVkSWQgPSBjYW1lbGl6ZShpZCk7XG4gIGlmIChoYXNPd24oYXNzZXRzLCBjYW1lbGl6ZWRJZCkpIHsgcmV0dXJuIGFzc2V0c1tjYW1lbGl6ZWRJZF0gfVxuICB2YXIgUGFzY2FsQ2FzZUlkID0gY2FwaXRhbGl6ZShjYW1lbGl6ZWRJZCk7XG4gIGlmIChoYXNPd24oYXNzZXRzLCBQYXNjYWxDYXNlSWQpKSB7IHJldHVybiBhc3NldHNbUGFzY2FsQ2FzZUlkXSB9XG4gIC8vIGZhbGxiYWNrIHRvIHByb3RvdHlwZSBjaGFpblxuICB2YXIgcmVzID0gYXNzZXRzW2lkXSB8fCBhc3NldHNbY2FtZWxpemVkSWRdIHx8IGFzc2V0c1tQYXNjYWxDYXNlSWRdO1xuICBpZiAocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJyAmJiB3YXJuTWlzc2luZyAmJiAhcmVzKSB7XG4gICAgd2FybihcbiAgICAgICdGYWlsZWQgdG8gcmVzb2x2ZSAnICsgdHlwZS5zbGljZSgwLCAtMSkgKyAnOiAnICsgaWQsXG4gICAgICBvcHRpb25zXG4gICAgKTtcbiAgfVxuICByZXR1cm4gcmVzXG59XG5cbi8qICAqL1xuXG5mdW5jdGlvbiB2YWxpZGF0ZVByb3AgKFxuICBrZXksXG4gIHByb3BPcHRpb25zLFxuICBwcm9wc0RhdGEsXG4gIHZtXG4pIHtcbiAgdmFyIHByb3AgPSBwcm9wT3B0aW9uc1trZXldO1xuICB2YXIgYWJzZW50ID0gIWhhc093bihwcm9wc0RhdGEsIGtleSk7XG4gIHZhciB2YWx1ZSA9IHByb3BzRGF0YVtrZXldO1xuICAvLyBoYW5kbGUgYm9vbGVhbiBwcm9wc1xuICBpZiAoaXNUeXBlKEJvb2xlYW4sIHByb3AudHlwZSkpIHtcbiAgICBpZiAoYWJzZW50ICYmICFoYXNPd24ocHJvcCwgJ2RlZmF1bHQnKSkge1xuICAgICAgdmFsdWUgPSBmYWxzZTtcbiAgICB9IGVsc2UgaWYgKCFpc1R5cGUoU3RyaW5nLCBwcm9wLnR5cGUpICYmICh2YWx1ZSA9PT0gJycgfHwgdmFsdWUgPT09IGh5cGhlbmF0ZShrZXkpKSkge1xuICAgICAgdmFsdWUgPSB0cnVlO1xuICAgIH1cbiAgfVxuICAvLyBjaGVjayBkZWZhdWx0IHZhbHVlXG4gIGlmICh2YWx1ZSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgdmFsdWUgPSBnZXRQcm9wRGVmYXVsdFZhbHVlKHZtLCBwcm9wLCBrZXkpO1xuICAgIC8vIHNpbmNlIHRoZSBkZWZhdWx0IHZhbHVlIGlzIGEgZnJlc2ggY29weSxcbiAgICAvLyBtYWtlIHN1cmUgdG8gb2JzZXJ2ZSBpdC5cbiAgICB2YXIgcHJldlNob3VsZENvbnZlcnQgPSBvYnNlcnZlclN0YXRlLnNob3VsZENvbnZlcnQ7XG4gICAgb2JzZXJ2ZXJTdGF0ZS5zaG91bGRDb252ZXJ0ID0gdHJ1ZTtcbiAgICBvYnNlcnZlKHZhbHVlKTtcbiAgICBvYnNlcnZlclN0YXRlLnNob3VsZENvbnZlcnQgPSBwcmV2U2hvdWxkQ29udmVydDtcbiAgfVxuICBpZiAocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJykge1xuICAgIGFzc2VydFByb3AocHJvcCwga2V5LCB2YWx1ZSwgdm0sIGFic2VudCk7XG4gIH1cbiAgcmV0dXJuIHZhbHVlXG59XG5cbi8qKlxuICogR2V0IHRoZSBkZWZhdWx0IHZhbHVlIG9mIGEgcHJvcC5cbiAqL1xuZnVuY3Rpb24gZ2V0UHJvcERlZmF1bHRWYWx1ZSAodm0sIHByb3AsIGtleSkge1xuICAvLyBubyBkZWZhdWx0LCByZXR1cm4gdW5kZWZpbmVkXG4gIGlmICghaGFzT3duKHByb3AsICdkZWZhdWx0JykpIHtcbiAgICByZXR1cm4gdW5kZWZpbmVkXG4gIH1cbiAgdmFyIGRlZiA9IHByb3AuZGVmYXVsdDtcbiAgLy8gd2FybiBhZ2FpbnN0IG5vbi1mYWN0b3J5IGRlZmF1bHRzIGZvciBPYmplY3QgJiBBcnJheVxuICBpZiAocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJyAmJiBpc09iamVjdChkZWYpKSB7XG4gICAgd2FybihcbiAgICAgICdJbnZhbGlkIGRlZmF1bHQgdmFsdWUgZm9yIHByb3AgXCInICsga2V5ICsgJ1wiOiAnICtcbiAgICAgICdQcm9wcyB3aXRoIHR5cGUgT2JqZWN0L0FycmF5IG11c3QgdXNlIGEgZmFjdG9yeSBmdW5jdGlvbiAnICtcbiAgICAgICd0byByZXR1cm4gdGhlIGRlZmF1bHQgdmFsdWUuJyxcbiAgICAgIHZtXG4gICAgKTtcbiAgfVxuICAvLyB0aGUgcmF3IHByb3AgdmFsdWUgd2FzIGFsc28gdW5kZWZpbmVkIGZyb20gcHJldmlvdXMgcmVuZGVyLFxuICAvLyByZXR1cm4gcHJldmlvdXMgZGVmYXVsdCB2YWx1ZSB0byBhdm9pZCB1bm5lY2Vzc2FyeSB3YXRjaGVyIHRyaWdnZXJcbiAgaWYgKHZtICYmIHZtLiRvcHRpb25zLnByb3BzRGF0YSAmJlxuICAgIHZtLiRvcHRpb25zLnByb3BzRGF0YVtrZXldID09PSB1bmRlZmluZWQgJiZcbiAgICB2bS5fcHJvcHNba2V5XSAhPT0gdW5kZWZpbmVkXG4gICkge1xuICAgIHJldHVybiB2bS5fcHJvcHNba2V5XVxuICB9XG4gIC8vIGNhbGwgZmFjdG9yeSBmdW5jdGlvbiBmb3Igbm9uLUZ1bmN0aW9uIHR5cGVzXG4gIC8vIGEgdmFsdWUgaXMgRnVuY3Rpb24gaWYgaXRzIHByb3RvdHlwZSBpcyBmdW5jdGlvbiBldmVuIGFjcm9zcyBkaWZmZXJlbnQgZXhlY3V0aW9uIGNvbnRleHRcbiAgcmV0dXJuIHR5cGVvZiBkZWYgPT09ICdmdW5jdGlvbicgJiYgZ2V0VHlwZShwcm9wLnR5cGUpICE9PSAnRnVuY3Rpb24nXG4gICAgPyBkZWYuY2FsbCh2bSlcbiAgICA6IGRlZlxufVxuXG4vKipcbiAqIEFzc2VydCB3aGV0aGVyIGEgcHJvcCBpcyB2YWxpZC5cbiAqL1xuZnVuY3Rpb24gYXNzZXJ0UHJvcCAoXG4gIHByb3AsXG4gIG5hbWUsXG4gIHZhbHVlLFxuICB2bSxcbiAgYWJzZW50XG4pIHtcbiAgaWYgKHByb3AucmVxdWlyZWQgJiYgYWJzZW50KSB7XG4gICAgd2FybihcbiAgICAgICdNaXNzaW5nIHJlcXVpcmVkIHByb3A6IFwiJyArIG5hbWUgKyAnXCInLFxuICAgICAgdm1cbiAgICApO1xuICAgIHJldHVyblxuICB9XG4gIGlmICh2YWx1ZSA9PSBudWxsICYmICFwcm9wLnJlcXVpcmVkKSB7XG4gICAgcmV0dXJuXG4gIH1cbiAgdmFyIHR5cGUgPSBwcm9wLnR5cGU7XG4gIHZhciB2YWxpZCA9ICF0eXBlIHx8IHR5cGUgPT09IHRydWU7XG4gIHZhciBleHBlY3RlZFR5cGVzID0gW107XG4gIGlmICh0eXBlKSB7XG4gICAgaWYgKCFBcnJheS5pc0FycmF5KHR5cGUpKSB7XG4gICAgICB0eXBlID0gW3R5cGVdO1xuICAgIH1cbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IHR5cGUubGVuZ3RoICYmICF2YWxpZDsgaSsrKSB7XG4gICAgICB2YXIgYXNzZXJ0ZWRUeXBlID0gYXNzZXJ0VHlwZSh2YWx1ZSwgdHlwZVtpXSk7XG4gICAgICBleHBlY3RlZFR5cGVzLnB1c2goYXNzZXJ0ZWRUeXBlLmV4cGVjdGVkVHlwZSB8fCAnJyk7XG4gICAgICB2YWxpZCA9IGFzc2VydGVkVHlwZS52YWxpZDtcbiAgICB9XG4gIH1cbiAgaWYgKCF2YWxpZCkge1xuICAgIHdhcm4oXG4gICAgICAnSW52YWxpZCBwcm9wOiB0eXBlIGNoZWNrIGZhaWxlZCBmb3IgcHJvcCBcIicgKyBuYW1lICsgJ1wiLicgK1xuICAgICAgJyBFeHBlY3RlZCAnICsgZXhwZWN0ZWRUeXBlcy5tYXAoY2FwaXRhbGl6ZSkuam9pbignLCAnKSArXG4gICAgICAnLCBnb3QgJyArIE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbCh2YWx1ZSkuc2xpY2UoOCwgLTEpICsgJy4nLFxuICAgICAgdm1cbiAgICApO1xuICAgIHJldHVyblxuICB9XG4gIHZhciB2YWxpZGF0b3IgPSBwcm9wLnZhbGlkYXRvcjtcbiAgaWYgKHZhbGlkYXRvcikge1xuICAgIGlmICghdmFsaWRhdG9yKHZhbHVlKSkge1xuICAgICAgd2FybihcbiAgICAgICAgJ0ludmFsaWQgcHJvcDogY3VzdG9tIHZhbGlkYXRvciBjaGVjayBmYWlsZWQgZm9yIHByb3AgXCInICsgbmFtZSArICdcIi4nLFxuICAgICAgICB2bVxuICAgICAgKTtcbiAgICB9XG4gIH1cbn1cblxudmFyIHNpbXBsZUNoZWNrUkUgPSAvXihTdHJpbmd8TnVtYmVyfEJvb2xlYW58RnVuY3Rpb258U3ltYm9sKSQvO1xuXG5mdW5jdGlvbiBhc3NlcnRUeXBlICh2YWx1ZSwgdHlwZSkge1xuICB2YXIgdmFsaWQ7XG4gIHZhciBleHBlY3RlZFR5cGUgPSBnZXRUeXBlKHR5cGUpO1xuICBpZiAoc2ltcGxlQ2hlY2tSRS50ZXN0KGV4cGVjdGVkVHlwZSkpIHtcbiAgICB2YXIgdCA9IHR5cGVvZiB2YWx1ZTtcbiAgICB2YWxpZCA9IHQgPT09IGV4cGVjdGVkVHlwZS50b0xvd2VyQ2FzZSgpO1xuICAgIC8vIGZvciBwcmltaXRpdmUgd3JhcHBlciBvYmplY3RzXG4gICAgaWYgKCF2YWxpZCAmJiB0ID09PSAnb2JqZWN0Jykge1xuICAgICAgdmFsaWQgPSB2YWx1ZSBpbnN0YW5jZW9mIHR5cGU7XG4gICAgfVxuICB9IGVsc2UgaWYgKGV4cGVjdGVkVHlwZSA9PT0gJ09iamVjdCcpIHtcbiAgICB2YWxpZCA9IGlzUGxhaW5PYmplY3QodmFsdWUpO1xuICB9IGVsc2UgaWYgKGV4cGVjdGVkVHlwZSA9PT0gJ0FycmF5Jykge1xuICAgIHZhbGlkID0gQXJyYXkuaXNBcnJheSh2YWx1ZSk7XG4gIH0gZWxzZSB7XG4gICAgdmFsaWQgPSB2YWx1ZSBpbnN0YW5jZW9mIHR5cGU7XG4gIH1cbiAgcmV0dXJuIHtcbiAgICB2YWxpZDogdmFsaWQsXG4gICAgZXhwZWN0ZWRUeXBlOiBleHBlY3RlZFR5cGVcbiAgfVxufVxuXG4vKipcbiAqIFVzZSBmdW5jdGlvbiBzdHJpbmcgbmFtZSB0byBjaGVjayBidWlsdC1pbiB0eXBlcyxcbiAqIGJlY2F1c2UgYSBzaW1wbGUgZXF1YWxpdHkgY2hlY2sgd2lsbCBmYWlsIHdoZW4gcnVubmluZ1xuICogYWNyb3NzIGRpZmZlcmVudCB2bXMgLyBpZnJhbWVzLlxuICovXG5mdW5jdGlvbiBnZXRUeXBlIChmbikge1xuICB2YXIgbWF0Y2ggPSBmbiAmJiBmbi50b1N0cmluZygpLm1hdGNoKC9eXFxzKmZ1bmN0aW9uIChcXHcrKS8pO1xuICByZXR1cm4gbWF0Y2ggPyBtYXRjaFsxXSA6ICcnXG59XG5cbmZ1bmN0aW9uIGlzVHlwZSAodHlwZSwgZm4pIHtcbiAgaWYgKCFBcnJheS5pc0FycmF5KGZuKSkge1xuICAgIHJldHVybiBnZXRUeXBlKGZuKSA9PT0gZ2V0VHlwZSh0eXBlKVxuICB9XG4gIGZvciAodmFyIGkgPSAwLCBsZW4gPSBmbi5sZW5ndGg7IGkgPCBsZW47IGkrKykge1xuICAgIGlmIChnZXRUeXBlKGZuW2ldKSA9PT0gZ2V0VHlwZSh0eXBlKSkge1xuICAgICAgcmV0dXJuIHRydWVcbiAgICB9XG4gIH1cbiAgLyogaXN0YW5idWwgaWdub3JlIG5leHQgKi9cbiAgcmV0dXJuIGZhbHNlXG59XG5cbi8qICAqL1xuXG52YXIgbWFyaztcbnZhciBtZWFzdXJlO1xuXG5pZiAocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJykge1xuICB2YXIgcGVyZiA9IGluQnJvd3NlciAmJiB3aW5kb3cucGVyZm9ybWFuY2U7XG4gIC8qIGlzdGFuYnVsIGlnbm9yZSBpZiAqL1xuICBpZiAoXG4gICAgcGVyZiAmJlxuICAgIHBlcmYubWFyayAmJlxuICAgIHBlcmYubWVhc3VyZSAmJlxuICAgIHBlcmYuY2xlYXJNYXJrcyAmJlxuICAgIHBlcmYuY2xlYXJNZWFzdXJlc1xuICApIHtcbiAgICBtYXJrID0gZnVuY3Rpb24gKHRhZykgeyByZXR1cm4gcGVyZi5tYXJrKHRhZyk7IH07XG4gICAgbWVhc3VyZSA9IGZ1bmN0aW9uIChuYW1lLCBzdGFydFRhZywgZW5kVGFnKSB7XG4gICAgICBwZXJmLm1lYXN1cmUobmFtZSwgc3RhcnRUYWcsIGVuZFRhZyk7XG4gICAgICBwZXJmLmNsZWFyTWFya3Moc3RhcnRUYWcpO1xuICAgICAgcGVyZi5jbGVhck1hcmtzKGVuZFRhZyk7XG4gICAgICBwZXJmLmNsZWFyTWVhc3VyZXMobmFtZSk7XG4gICAgfTtcbiAgfVxufVxuXG4vKiBub3QgdHlwZSBjaGVja2luZyB0aGlzIGZpbGUgYmVjYXVzZSBmbG93IGRvZXNuJ3QgcGxheSB3ZWxsIHdpdGggUHJveHkgKi9cblxudmFyIGluaXRQcm94eTtcblxuaWYgKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicpIHtcbiAgdmFyIGFsbG93ZWRHbG9iYWxzID0gbWFrZU1hcChcbiAgICAnSW5maW5pdHksdW5kZWZpbmVkLE5hTixpc0Zpbml0ZSxpc05hTiwnICtcbiAgICAncGFyc2VGbG9hdCxwYXJzZUludCxkZWNvZGVVUkksZGVjb2RlVVJJQ29tcG9uZW50LGVuY29kZVVSSSxlbmNvZGVVUklDb21wb25lbnQsJyArXG4gICAgJ01hdGgsTnVtYmVyLERhdGUsQXJyYXksT2JqZWN0LEJvb2xlYW4sU3RyaW5nLFJlZ0V4cCxNYXAsU2V0LEpTT04sSW50bCwnICtcbiAgICAncmVxdWlyZScgLy8gZm9yIFdlYnBhY2svQnJvd3NlcmlmeVxuICApO1xuXG4gIHZhciB3YXJuTm9uUHJlc2VudCA9IGZ1bmN0aW9uICh0YXJnZXQsIGtleSkge1xuICAgIHdhcm4oXG4gICAgICBcIlByb3BlcnR5IG9yIG1ldGhvZCBcXFwiXCIgKyBrZXkgKyBcIlxcXCIgaXMgbm90IGRlZmluZWQgb24gdGhlIGluc3RhbmNlIGJ1dCBcIiArXG4gICAgICBcInJlZmVyZW5jZWQgZHVyaW5nIHJlbmRlci4gTWFrZSBzdXJlIHRvIGRlY2xhcmUgcmVhY3RpdmUgZGF0YSBcIiArXG4gICAgICBcInByb3BlcnRpZXMgaW4gdGhlIGRhdGEgb3B0aW9uLlwiLFxuICAgICAgdGFyZ2V0XG4gICAgKTtcbiAgfTtcblxuICB2YXIgaGFzUHJveHkgPVxuICAgIHR5cGVvZiBQcm94eSAhPT0gJ3VuZGVmaW5lZCcgJiZcbiAgICBQcm94eS50b1N0cmluZygpLm1hdGNoKC9uYXRpdmUgY29kZS8pO1xuXG4gIGlmIChoYXNQcm94eSkge1xuICAgIHZhciBpc0J1aWx0SW5Nb2RpZmllciA9IG1ha2VNYXAoJ3N0b3AscHJldmVudCxzZWxmLGN0cmwsc2hpZnQsYWx0LG1ldGEnKTtcbiAgICBjb25maWcua2V5Q29kZXMgPSBuZXcgUHJveHkoY29uZmlnLmtleUNvZGVzLCB7XG4gICAgICBzZXQ6IGZ1bmN0aW9uIHNldCAodGFyZ2V0LCBrZXksIHZhbHVlKSB7XG4gICAgICAgIGlmIChpc0J1aWx0SW5Nb2RpZmllcihrZXkpKSB7XG4gICAgICAgICAgd2FybigoXCJBdm9pZCBvdmVyd3JpdGluZyBidWlsdC1pbiBtb2RpZmllciBpbiBjb25maWcua2V5Q29kZXM6IC5cIiArIGtleSkpO1xuICAgICAgICAgIHJldHVybiBmYWxzZVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHRhcmdldFtrZXldID0gdmFsdWU7XG4gICAgICAgICAgcmV0dXJuIHRydWVcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0pO1xuICB9XG5cbiAgdmFyIGhhc0hhbmRsZXIgPSB7XG4gICAgaGFzOiBmdW5jdGlvbiBoYXMgKHRhcmdldCwga2V5KSB7XG4gICAgICB2YXIgaGFzID0ga2V5IGluIHRhcmdldDtcbiAgICAgIHZhciBpc0FsbG93ZWQgPSBhbGxvd2VkR2xvYmFscyhrZXkpIHx8IGtleS5jaGFyQXQoMCkgPT09ICdfJztcbiAgICAgIGlmICghaGFzICYmICFpc0FsbG93ZWQpIHtcbiAgICAgICAgd2Fybk5vblByZXNlbnQodGFyZ2V0LCBrZXkpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGhhcyB8fCAhaXNBbGxvd2VkXG4gICAgfVxuICB9O1xuXG4gIHZhciBnZXRIYW5kbGVyID0ge1xuICAgIGdldDogZnVuY3Rpb24gZ2V0ICh0YXJnZXQsIGtleSkge1xuICAgICAgaWYgKHR5cGVvZiBrZXkgPT09ICdzdHJpbmcnICYmICEoa2V5IGluIHRhcmdldCkpIHtcbiAgICAgICAgd2Fybk5vblByZXNlbnQodGFyZ2V0LCBrZXkpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHRhcmdldFtrZXldXG4gICAgfVxuICB9O1xuXG4gIGluaXRQcm94eSA9IGZ1bmN0aW9uIGluaXRQcm94eSAodm0pIHtcbiAgICBpZiAoaGFzUHJveHkpIHtcbiAgICAgIC8vIGRldGVybWluZSB3aGljaCBwcm94eSBoYW5kbGVyIHRvIHVzZVxuICAgICAgdmFyIG9wdGlvbnMgPSB2bS4kb3B0aW9ucztcbiAgICAgIHZhciBoYW5kbGVycyA9IG9wdGlvbnMucmVuZGVyICYmIG9wdGlvbnMucmVuZGVyLl93aXRoU3RyaXBwZWRcbiAgICAgICAgPyBnZXRIYW5kbGVyXG4gICAgICAgIDogaGFzSGFuZGxlcjtcbiAgICAgIHZtLl9yZW5kZXJQcm94eSA9IG5ldyBQcm94eSh2bSwgaGFuZGxlcnMpO1xuICAgIH0gZWxzZSB7XG4gICAgICB2bS5fcmVuZGVyUHJveHkgPSB2bTtcbiAgICB9XG4gIH07XG59XG5cbi8qICAqL1xuXG52YXIgVk5vZGUgPSBmdW5jdGlvbiBWTm9kZSAoXG4gIHRhZyxcbiAgZGF0YSxcbiAgY2hpbGRyZW4sXG4gIHRleHQsXG4gIGVsbSxcbiAgY29udGV4dCxcbiAgY29tcG9uZW50T3B0aW9ucyxcbiAgYXN5bmNGYWN0b3J5XG4pIHtcbiAgdGhpcy50YWcgPSB0YWc7XG4gIHRoaXMuZGF0YSA9IGRhdGE7XG4gIHRoaXMuY2hpbGRyZW4gPSBjaGlsZHJlbjtcbiAgdGhpcy50ZXh0ID0gdGV4dDtcbiAgdGhpcy5lbG0gPSBlbG07XG4gIHRoaXMubnMgPSB1bmRlZmluZWQ7XG4gIHRoaXMuY29udGV4dCA9IGNvbnRleHQ7XG4gIHRoaXMuZnVuY3Rpb25hbENvbnRleHQgPSB1bmRlZmluZWQ7XG4gIHRoaXMua2V5ID0gZGF0YSAmJiBkYXRhLmtleTtcbiAgdGhpcy5jb21wb25lbnRPcHRpb25zID0gY29tcG9uZW50T3B0aW9ucztcbiAgdGhpcy5jb21wb25lbnRJbnN0YW5jZSA9IHVuZGVmaW5lZDtcbiAgdGhpcy5wYXJlbnQgPSB1bmRlZmluZWQ7XG4gIHRoaXMucmF3ID0gZmFsc2U7XG4gIHRoaXMuaXNTdGF0aWMgPSBmYWxzZTtcbiAgdGhpcy5pc1Jvb3RJbnNlcnQgPSB0cnVlO1xuICB0aGlzLmlzQ29tbWVudCA9IGZhbHNlO1xuICB0aGlzLmlzQ2xvbmVkID0gZmFsc2U7XG4gIHRoaXMuaXNPbmNlID0gZmFsc2U7XG4gIHRoaXMuYXN5bmNGYWN0b3J5ID0gYXN5bmNGYWN0b3J5O1xuICB0aGlzLmFzeW5jTWV0YSA9IHVuZGVmaW5lZDtcbiAgdGhpcy5pc0FzeW5jUGxhY2Vob2xkZXIgPSBmYWxzZTtcbn07XG5cbnZhciBwcm90b3R5cGVBY2Nlc3NvcnMgPSB7IGNoaWxkOiB7fSB9O1xuXG4vLyBERVBSRUNBVEVEOiBhbGlhcyBmb3IgY29tcG9uZW50SW5zdGFuY2UgZm9yIGJhY2t3YXJkcyBjb21wYXQuXG4vKiBpc3RhbmJ1bCBpZ25vcmUgbmV4dCAqL1xucHJvdG90eXBlQWNjZXNzb3JzLmNoaWxkLmdldCA9IGZ1bmN0aW9uICgpIHtcbiAgcmV0dXJuIHRoaXMuY29tcG9uZW50SW5zdGFuY2Vcbn07XG5cbk9iamVjdC5kZWZpbmVQcm9wZXJ0aWVzKCBWTm9kZS5wcm90b3R5cGUsIHByb3RvdHlwZUFjY2Vzc29ycyApO1xuXG52YXIgY3JlYXRlRW1wdHlWTm9kZSA9IGZ1bmN0aW9uICh0ZXh0KSB7XG4gIGlmICggdGV4dCA9PT0gdm9pZCAwICkgdGV4dCA9ICcnO1xuXG4gIHZhciBub2RlID0gbmV3IFZOb2RlKCk7XG4gIG5vZGUudGV4dCA9IHRleHQ7XG4gIG5vZGUuaXNDb21tZW50ID0gdHJ1ZTtcbiAgcmV0dXJuIG5vZGVcbn07XG5cbmZ1bmN0aW9uIGNyZWF0ZVRleHRWTm9kZSAodmFsKSB7XG4gIHJldHVybiBuZXcgVk5vZGUodW5kZWZpbmVkLCB1bmRlZmluZWQsIHVuZGVmaW5lZCwgU3RyaW5nKHZhbCkpXG59XG5cbi8vIG9wdGltaXplZCBzaGFsbG93IGNsb25lXG4vLyB1c2VkIGZvciBzdGF0aWMgbm9kZXMgYW5kIHNsb3Qgbm9kZXMgYmVjYXVzZSB0aGV5IG1heSBiZSByZXVzZWQgYWNyb3NzXG4vLyBtdWx0aXBsZSByZW5kZXJzLCBjbG9uaW5nIHRoZW0gYXZvaWRzIGVycm9ycyB3aGVuIERPTSBtYW5pcHVsYXRpb25zIHJlbHlcbi8vIG9uIHRoZWlyIGVsbSByZWZlcmVuY2UuXG5mdW5jdGlvbiBjbG9uZVZOb2RlICh2bm9kZSwgZGVlcCkge1xuICB2YXIgY2xvbmVkID0gbmV3IFZOb2RlKFxuICAgIHZub2RlLnRhZyxcbiAgICB2bm9kZS5kYXRhLFxuICAgIHZub2RlLmNoaWxkcmVuLFxuICAgIHZub2RlLnRleHQsXG4gICAgdm5vZGUuZWxtLFxuICAgIHZub2RlLmNvbnRleHQsXG4gICAgdm5vZGUuY29tcG9uZW50T3B0aW9ucyxcbiAgICB2bm9kZS5hc3luY0ZhY3RvcnlcbiAgKTtcbiAgY2xvbmVkLm5zID0gdm5vZGUubnM7XG4gIGNsb25lZC5pc1N0YXRpYyA9IHZub2RlLmlzU3RhdGljO1xuICBjbG9uZWQua2V5ID0gdm5vZGUua2V5O1xuICBjbG9uZWQuaXNDb21tZW50ID0gdm5vZGUuaXNDb21tZW50O1xuICBjbG9uZWQuaXNDbG9uZWQgPSB0cnVlO1xuICBpZiAoZGVlcCAmJiB2bm9kZS5jaGlsZHJlbikge1xuICAgIGNsb25lZC5jaGlsZHJlbiA9IGNsb25lVk5vZGVzKHZub2RlLmNoaWxkcmVuKTtcbiAgfVxuICByZXR1cm4gY2xvbmVkXG59XG5cbmZ1bmN0aW9uIGNsb25lVk5vZGVzICh2bm9kZXMsIGRlZXApIHtcbiAgdmFyIGxlbiA9IHZub2Rlcy5sZW5ndGg7XG4gIHZhciByZXMgPSBuZXcgQXJyYXkobGVuKTtcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW47IGkrKykge1xuICAgIHJlc1tpXSA9IGNsb25lVk5vZGUodm5vZGVzW2ldLCBkZWVwKTtcbiAgfVxuICByZXR1cm4gcmVzXG59XG5cbi8qICAqL1xuXG52YXIgbm9ybWFsaXplRXZlbnQgPSBjYWNoZWQoZnVuY3Rpb24gKG5hbWUpIHtcbiAgdmFyIHBhc3NpdmUgPSBuYW1lLmNoYXJBdCgwKSA9PT0gJyYnO1xuICBuYW1lID0gcGFzc2l2ZSA/IG5hbWUuc2xpY2UoMSkgOiBuYW1lO1xuICB2YXIgb25jZSQkMSA9IG5hbWUuY2hhckF0KDApID09PSAnfic7IC8vIFByZWZpeGVkIGxhc3QsIGNoZWNrZWQgZmlyc3RcbiAgbmFtZSA9IG9uY2UkJDEgPyBuYW1lLnNsaWNlKDEpIDogbmFtZTtcbiAgdmFyIGNhcHR1cmUgPSBuYW1lLmNoYXJBdCgwKSA9PT0gJyEnO1xuICBuYW1lID0gY2FwdHVyZSA/IG5hbWUuc2xpY2UoMSkgOiBuYW1lO1xuICB2YXIgcGxhaW4gPSAhKHBhc3NpdmUgfHwgb25jZSQkMSB8fCBjYXB0dXJlKTtcbiAgcmV0dXJuIHtcbiAgICBuYW1lOiBuYW1lLFxuICAgIHBsYWluOiBwbGFpbixcbiAgICBvbmNlOiBvbmNlJCQxLFxuICAgIGNhcHR1cmU6IGNhcHR1cmUsXG4gICAgcGFzc2l2ZTogcGFzc2l2ZVxuICB9XG59KTtcblxuZnVuY3Rpb24gY3JlYXRlRm5JbnZva2VyIChmbnMpIHtcbiAgZnVuY3Rpb24gaW52b2tlciAoKSB7XG4gICAgdmFyIGFyZ3VtZW50cyQxID0gYXJndW1lbnRzO1xuXG4gICAgdmFyIGZucyA9IGludm9rZXIuZm5zO1xuICAgIGlmIChBcnJheS5pc0FycmF5KGZucykpIHtcbiAgICAgIHZhciBjbG9uZWQgPSBmbnMuc2xpY2UoKTtcbiAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgY2xvbmVkLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIGNsb25lZFtpXS5hcHBseShudWxsLCBhcmd1bWVudHMkMSk7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIHJldHVybiBoYW5kbGVyIHJldHVybiB2YWx1ZSBmb3Igc2luZ2xlIGhhbmRsZXJzXG4gICAgICByZXR1cm4gZm5zLmFwcGx5KG51bGwsIGFyZ3VtZW50cylcbiAgICB9XG4gIH1cbiAgaW52b2tlci5mbnMgPSBmbnM7XG4gIHJldHVybiBpbnZva2VyXG59XG5cbi8vICM2NTUyXG5mdW5jdGlvbiBwcmlvcml0aXplUGxhaW5FdmVudHMgKGEsIGIpIHtcbiAgcmV0dXJuIGEucGxhaW4gPyAtMSA6IGIucGxhaW4gPyAxIDogMFxufVxuXG5mdW5jdGlvbiB1cGRhdGVMaXN0ZW5lcnMgKFxuICBvbixcbiAgb2xkT24sXG4gIGFkZCxcbiAgcmVtb3ZlJCQxLFxuICB2bVxuKSB7XG4gIHZhciBuYW1lLCBjdXIsIG9sZCwgZXZlbnQ7XG4gIHZhciB0b0FkZCA9IFtdO1xuICB2YXIgaGFzTW9kaWZpZXIgPSBmYWxzZTtcbiAgZm9yIChuYW1lIGluIG9uKSB7XG4gICAgY3VyID0gb25bbmFtZV07XG4gICAgb2xkID0gb2xkT25bbmFtZV07XG4gICAgZXZlbnQgPSBub3JtYWxpemVFdmVudChuYW1lKTtcbiAgICBpZiAoIWV2ZW50LnBsYWluKSB7IGhhc01vZGlmaWVyID0gdHJ1ZTsgfVxuICAgIGlmIChpc1VuZGVmKGN1cikpIHtcbiAgICAgIHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicgJiYgd2FybihcbiAgICAgICAgXCJJbnZhbGlkIGhhbmRsZXIgZm9yIGV2ZW50IFxcXCJcIiArIChldmVudC5uYW1lKSArIFwiXFxcIjogZ290IFwiICsgU3RyaW5nKGN1ciksXG4gICAgICAgIHZtXG4gICAgICApO1xuICAgIH0gZWxzZSBpZiAoaXNVbmRlZihvbGQpKSB7XG4gICAgICBpZiAoaXNVbmRlZihjdXIuZm5zKSkge1xuICAgICAgICBjdXIgPSBvbltuYW1lXSA9IGNyZWF0ZUZuSW52b2tlcihjdXIpO1xuICAgICAgfVxuICAgICAgZXZlbnQuaGFuZGxlciA9IGN1cjtcbiAgICAgIHRvQWRkLnB1c2goZXZlbnQpO1xuICAgIH0gZWxzZSBpZiAoY3VyICE9PSBvbGQpIHtcbiAgICAgIG9sZC5mbnMgPSBjdXI7XG4gICAgICBvbltuYW1lXSA9IG9sZDtcbiAgICB9XG4gIH1cbiAgaWYgKHRvQWRkLmxlbmd0aCkge1xuICAgIGlmIChoYXNNb2RpZmllcikgeyB0b0FkZC5zb3J0KHByaW9yaXRpemVQbGFpbkV2ZW50cyk7IH1cbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IHRvQWRkLmxlbmd0aDsgaSsrKSB7XG4gICAgICB2YXIgZXZlbnQkMSA9IHRvQWRkW2ldO1xuICAgICAgYWRkKGV2ZW50JDEubmFtZSwgZXZlbnQkMS5oYW5kbGVyLCBldmVudCQxLm9uY2UsIGV2ZW50JDEuY2FwdHVyZSwgZXZlbnQkMS5wYXNzaXZlKTtcbiAgICB9XG4gIH1cbiAgZm9yIChuYW1lIGluIG9sZE9uKSB7XG4gICAgaWYgKGlzVW5kZWYob25bbmFtZV0pKSB7XG4gICAgICBldmVudCA9IG5vcm1hbGl6ZUV2ZW50KG5hbWUpO1xuICAgICAgcmVtb3ZlJCQxKGV2ZW50Lm5hbWUsIG9sZE9uW25hbWVdLCBldmVudC5jYXB0dXJlKTtcbiAgICB9XG4gIH1cbn1cblxuLyogICovXG5cbmZ1bmN0aW9uIG1lcmdlVk5vZGVIb29rIChkZWYsIGhvb2tLZXksIGhvb2spIHtcbiAgdmFyIGludm9rZXI7XG4gIHZhciBvbGRIb29rID0gZGVmW2hvb2tLZXldO1xuXG4gIGZ1bmN0aW9uIHdyYXBwZWRIb29rICgpIHtcbiAgICBob29rLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgLy8gaW1wb3J0YW50OiByZW1vdmUgbWVyZ2VkIGhvb2sgdG8gZW5zdXJlIGl0J3MgY2FsbGVkIG9ubHkgb25jZVxuICAgIC8vIGFuZCBwcmV2ZW50IG1lbW9yeSBsZWFrXG4gICAgcmVtb3ZlKGludm9rZXIuZm5zLCB3cmFwcGVkSG9vayk7XG4gIH1cblxuICBpZiAoaXNVbmRlZihvbGRIb29rKSkge1xuICAgIC8vIG5vIGV4aXN0aW5nIGhvb2tcbiAgICBpbnZva2VyID0gY3JlYXRlRm5JbnZva2VyKFt3cmFwcGVkSG9va10pO1xuICB9IGVsc2Uge1xuICAgIC8qIGlzdGFuYnVsIGlnbm9yZSBpZiAqL1xuICAgIGlmIChpc0RlZihvbGRIb29rLmZucykgJiYgaXNUcnVlKG9sZEhvb2subWVyZ2VkKSkge1xuICAgICAgLy8gYWxyZWFkeSBhIG1lcmdlZCBpbnZva2VyXG4gICAgICBpbnZva2VyID0gb2xkSG9vaztcbiAgICAgIGludm9rZXIuZm5zLnB1c2god3JhcHBlZEhvb2spO1xuICAgIH0gZWxzZSB7XG4gICAgICAvLyBleGlzdGluZyBwbGFpbiBob29rXG4gICAgICBpbnZva2VyID0gY3JlYXRlRm5JbnZva2VyKFtvbGRIb29rLCB3cmFwcGVkSG9va10pO1xuICAgIH1cbiAgfVxuXG4gIGludm9rZXIubWVyZ2VkID0gdHJ1ZTtcbiAgZGVmW2hvb2tLZXldID0gaW52b2tlcjtcbn1cblxuLyogICovXG5cbmZ1bmN0aW9uIGV4dHJhY3RQcm9wc0Zyb21WTm9kZURhdGEgKFxuICBkYXRhLFxuICBDdG9yLFxuICB0YWdcbikge1xuICAvLyB3ZSBhcmUgb25seSBleHRyYWN0aW5nIHJhdyB2YWx1ZXMgaGVyZS5cbiAgLy8gdmFsaWRhdGlvbiBhbmQgZGVmYXVsdCB2YWx1ZXMgYXJlIGhhbmRsZWQgaW4gdGhlIGNoaWxkXG4gIC8vIGNvbXBvbmVudCBpdHNlbGYuXG4gIHZhciBwcm9wT3B0aW9ucyA9IEN0b3Iub3B0aW9ucy5wcm9wcztcbiAgaWYgKGlzVW5kZWYocHJvcE9wdGlvbnMpKSB7XG4gICAgcmV0dXJuXG4gIH1cbiAgdmFyIHJlcyA9IHt9O1xuICB2YXIgYXR0cnMgPSBkYXRhLmF0dHJzO1xuICB2YXIgcHJvcHMgPSBkYXRhLnByb3BzO1xuICBpZiAoaXNEZWYoYXR0cnMpIHx8IGlzRGVmKHByb3BzKSkge1xuICAgIGZvciAodmFyIGtleSBpbiBwcm9wT3B0aW9ucykge1xuICAgICAgdmFyIGFsdEtleSA9IGh5cGhlbmF0ZShrZXkpO1xuICAgICAgaWYgKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicpIHtcbiAgICAgICAgdmFyIGtleUluTG93ZXJDYXNlID0ga2V5LnRvTG93ZXJDYXNlKCk7XG4gICAgICAgIGlmIChcbiAgICAgICAgICBrZXkgIT09IGtleUluTG93ZXJDYXNlICYmXG4gICAgICAgICAgYXR0cnMgJiYgaGFzT3duKGF0dHJzLCBrZXlJbkxvd2VyQ2FzZSlcbiAgICAgICAgKSB7XG4gICAgICAgICAgdGlwKFxuICAgICAgICAgICAgXCJQcm9wIFxcXCJcIiArIGtleUluTG93ZXJDYXNlICsgXCJcXFwiIGlzIHBhc3NlZCB0byBjb21wb25lbnQgXCIgK1xuICAgICAgICAgICAgKGZvcm1hdENvbXBvbmVudE5hbWUodGFnIHx8IEN0b3IpKSArIFwiLCBidXQgdGhlIGRlY2xhcmVkIHByb3AgbmFtZSBpc1wiICtcbiAgICAgICAgICAgIFwiIFxcXCJcIiArIGtleSArIFwiXFxcIi4gXCIgK1xuICAgICAgICAgICAgXCJOb3RlIHRoYXQgSFRNTCBhdHRyaWJ1dGVzIGFyZSBjYXNlLWluc2Vuc2l0aXZlIGFuZCBjYW1lbENhc2VkIFwiICtcbiAgICAgICAgICAgIFwicHJvcHMgbmVlZCB0byB1c2UgdGhlaXIga2ViYWItY2FzZSBlcXVpdmFsZW50cyB3aGVuIHVzaW5nIGluLURPTSBcIiArXG4gICAgICAgICAgICBcInRlbXBsYXRlcy4gWW91IHNob3VsZCBwcm9iYWJseSB1c2UgXFxcIlwiICsgYWx0S2V5ICsgXCJcXFwiIGluc3RlYWQgb2YgXFxcIlwiICsga2V5ICsgXCJcXFwiLlwiXG4gICAgICAgICAgKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgY2hlY2tQcm9wKHJlcywgcHJvcHMsIGtleSwgYWx0S2V5LCB0cnVlKSB8fFxuICAgICAgY2hlY2tQcm9wKHJlcywgYXR0cnMsIGtleSwgYWx0S2V5LCBmYWxzZSk7XG4gICAgfVxuICB9XG4gIHJldHVybiByZXNcbn1cblxuZnVuY3Rpb24gY2hlY2tQcm9wIChcbiAgcmVzLFxuICBoYXNoLFxuICBrZXksXG4gIGFsdEtleSxcbiAgcHJlc2VydmVcbikge1xuICBpZiAoaXNEZWYoaGFzaCkpIHtcbiAgICBpZiAoaGFzT3duKGhhc2gsIGtleSkpIHtcbiAgICAgIHJlc1trZXldID0gaGFzaFtrZXldO1xuICAgICAgaWYgKCFwcmVzZXJ2ZSkge1xuICAgICAgICBkZWxldGUgaGFzaFtrZXldO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHRydWVcbiAgICB9IGVsc2UgaWYgKGhhc093bihoYXNoLCBhbHRLZXkpKSB7XG4gICAgICByZXNba2V5XSA9IGhhc2hbYWx0S2V5XTtcbiAgICAgIGlmICghcHJlc2VydmUpIHtcbiAgICAgICAgZGVsZXRlIGhhc2hbYWx0S2V5XTtcbiAgICAgIH1cbiAgICAgIHJldHVybiB0cnVlXG4gICAgfVxuICB9XG4gIHJldHVybiBmYWxzZVxufVxuXG4vKiAgKi9cblxuLy8gVGhlIHRlbXBsYXRlIGNvbXBpbGVyIGF0dGVtcHRzIHRvIG1pbmltaXplIHRoZSBuZWVkIGZvciBub3JtYWxpemF0aW9uIGJ5XG4vLyBzdGF0aWNhbGx5IGFuYWx5emluZyB0aGUgdGVtcGxhdGUgYXQgY29tcGlsZSB0aW1lLlxuLy9cbi8vIEZvciBwbGFpbiBIVE1MIG1hcmt1cCwgbm9ybWFsaXphdGlvbiBjYW4gYmUgY29tcGxldGVseSBza2lwcGVkIGJlY2F1c2UgdGhlXG4vLyBnZW5lcmF0ZWQgcmVuZGVyIGZ1bmN0aW9uIGlzIGd1YXJhbnRlZWQgdG8gcmV0dXJuIEFycmF5PFZOb2RlPi4gVGhlcmUgYXJlXG4vLyB0d28gY2FzZXMgd2hlcmUgZXh0cmEgbm9ybWFsaXphdGlvbiBpcyBuZWVkZWQ6XG5cbi8vIDEuIFdoZW4gdGhlIGNoaWxkcmVuIGNvbnRhaW5zIGNvbXBvbmVudHMgLSBiZWNhdXNlIGEgZnVuY3Rpb25hbCBjb21wb25lbnRcbi8vIG1heSByZXR1cm4gYW4gQXJyYXkgaW5zdGVhZCBvZiBhIHNpbmdsZSByb290LiBJbiB0aGlzIGNhc2UsIGp1c3QgYSBzaW1wbGVcbi8vIG5vcm1hbGl6YXRpb24gaXMgbmVlZGVkIC0gaWYgYW55IGNoaWxkIGlzIGFuIEFycmF5LCB3ZSBmbGF0dGVuIHRoZSB3aG9sZVxuLy8gdGhpbmcgd2l0aCBBcnJheS5wcm90b3R5cGUuY29uY2F0LiBJdCBpcyBndWFyYW50ZWVkIHRvIGJlIG9ubHkgMS1sZXZlbCBkZWVwXG4vLyBiZWNhdXNlIGZ1bmN0aW9uYWwgY29tcG9uZW50cyBhbHJlYWR5IG5vcm1hbGl6ZSB0aGVpciBvd24gY2hpbGRyZW4uXG5mdW5jdGlvbiBzaW1wbGVOb3JtYWxpemVDaGlsZHJlbiAoY2hpbGRyZW4pIHtcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBjaGlsZHJlbi5sZW5ndGg7IGkrKykge1xuICAgIGlmIChBcnJheS5pc0FycmF5KGNoaWxkcmVuW2ldKSkge1xuICAgICAgcmV0dXJuIEFycmF5LnByb3RvdHlwZS5jb25jYXQuYXBwbHkoW10sIGNoaWxkcmVuKVxuICAgIH1cbiAgfVxuICByZXR1cm4gY2hpbGRyZW5cbn1cblxuLy8gMi4gV2hlbiB0aGUgY2hpbGRyZW4gY29udGFpbnMgY29uc3RydWN0cyB0aGF0IGFsd2F5cyBnZW5lcmF0ZWQgbmVzdGVkIEFycmF5cyxcbi8vIGUuZy4gPHRlbXBsYXRlPiwgPHNsb3Q+LCB2LWZvciwgb3Igd2hlbiB0aGUgY2hpbGRyZW4gaXMgcHJvdmlkZWQgYnkgdXNlclxuLy8gd2l0aCBoYW5kLXdyaXR0ZW4gcmVuZGVyIGZ1bmN0aW9ucyAvIEpTWC4gSW4gc3VjaCBjYXNlcyBhIGZ1bGwgbm9ybWFsaXphdGlvblxuLy8gaXMgbmVlZGVkIHRvIGNhdGVyIHRvIGFsbCBwb3NzaWJsZSB0eXBlcyBvZiBjaGlsZHJlbiB2YWx1ZXMuXG5mdW5jdGlvbiBub3JtYWxpemVDaGlsZHJlbiAoY2hpbGRyZW4pIHtcbiAgcmV0dXJuIGlzUHJpbWl0aXZlKGNoaWxkcmVuKVxuICAgID8gW2NyZWF0ZVRleHRWTm9kZShjaGlsZHJlbildXG4gICAgOiBBcnJheS5pc0FycmF5KGNoaWxkcmVuKVxuICAgICAgPyBub3JtYWxpemVBcnJheUNoaWxkcmVuKGNoaWxkcmVuKVxuICAgICAgOiB1bmRlZmluZWRcbn1cblxuZnVuY3Rpb24gaXNUZXh0Tm9kZSAobm9kZSkge1xuICByZXR1cm4gaXNEZWYobm9kZSkgJiYgaXNEZWYobm9kZS50ZXh0KSAmJiBpc0ZhbHNlKG5vZGUuaXNDb21tZW50KVxufVxuXG5mdW5jdGlvbiBub3JtYWxpemVBcnJheUNoaWxkcmVuIChjaGlsZHJlbiwgbmVzdGVkSW5kZXgpIHtcbiAgdmFyIHJlcyA9IFtdO1xuICB2YXIgaSwgYywgbGFzdDtcbiAgZm9yIChpID0gMDsgaSA8IGNoaWxkcmVuLmxlbmd0aDsgaSsrKSB7XG4gICAgYyA9IGNoaWxkcmVuW2ldO1xuICAgIGlmIChpc1VuZGVmKGMpIHx8IHR5cGVvZiBjID09PSAnYm9vbGVhbicpIHsgY29udGludWUgfVxuICAgIGxhc3QgPSByZXNbcmVzLmxlbmd0aCAtIDFdO1xuICAgIC8vICBuZXN0ZWRcbiAgICBpZiAoQXJyYXkuaXNBcnJheShjKSkge1xuICAgICAgcmVzLnB1c2guYXBwbHkocmVzLCBub3JtYWxpemVBcnJheUNoaWxkcmVuKGMsICgobmVzdGVkSW5kZXggfHwgJycpICsgXCJfXCIgKyBpKSkpO1xuICAgIH0gZWxzZSBpZiAoaXNQcmltaXRpdmUoYykpIHtcbiAgICAgIGlmIChpc1RleHROb2RlKGxhc3QpKSB7XG4gICAgICAgIC8vIG1lcmdlIGFkamFjZW50IHRleHQgbm9kZXNcbiAgICAgICAgLy8gdGhpcyBpcyBuZWNlc3NhcnkgZm9yIFNTUiBoeWRyYXRpb24gYmVjYXVzZSB0ZXh0IG5vZGVzIGFyZVxuICAgICAgICAvLyBlc3NlbnRpYWxseSBtZXJnZWQgd2hlbiByZW5kZXJlZCB0byBIVE1MIHN0cmluZ3NcbiAgICAgICAgKGxhc3QpLnRleHQgKz0gU3RyaW5nKGMpO1xuICAgICAgfSBlbHNlIGlmIChjICE9PSAnJykge1xuICAgICAgICAvLyBjb252ZXJ0IHByaW1pdGl2ZSB0byB2bm9kZVxuICAgICAgICByZXMucHVzaChjcmVhdGVUZXh0Vk5vZGUoYykpO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICBpZiAoaXNUZXh0Tm9kZShjKSAmJiBpc1RleHROb2RlKGxhc3QpKSB7XG4gICAgICAgIC8vIG1lcmdlIGFkamFjZW50IHRleHQgbm9kZXNcbiAgICAgICAgcmVzW3Jlcy5sZW5ndGggLSAxXSA9IGNyZWF0ZVRleHRWTm9kZShsYXN0LnRleHQgKyBjLnRleHQpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgLy8gZGVmYXVsdCBrZXkgZm9yIG5lc3RlZCBhcnJheSBjaGlsZHJlbiAobGlrZWx5IGdlbmVyYXRlZCBieSB2LWZvcilcbiAgICAgICAgaWYgKGlzVHJ1ZShjaGlsZHJlbi5faXNWTGlzdCkgJiZcbiAgICAgICAgICBpc0RlZihjLnRhZykgJiZcbiAgICAgICAgICBpc1VuZGVmKGMua2V5KSAmJlxuICAgICAgICAgIGlzRGVmKG5lc3RlZEluZGV4KSkge1xuICAgICAgICAgIGMua2V5ID0gXCJfX3ZsaXN0XCIgKyBuZXN0ZWRJbmRleCArIFwiX1wiICsgaSArIFwiX19cIjtcbiAgICAgICAgfVxuICAgICAgICByZXMucHVzaChjKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cbiAgcmV0dXJuIHJlc1xufVxuXG4vKiAgKi9cblxuZnVuY3Rpb24gZW5zdXJlQ3RvciAoY29tcCwgYmFzZSkge1xuICBpZiAoY29tcC5fX2VzTW9kdWxlICYmIGNvbXAuZGVmYXVsdCkge1xuICAgIGNvbXAgPSBjb21wLmRlZmF1bHQ7XG4gIH1cbiAgcmV0dXJuIGlzT2JqZWN0KGNvbXApXG4gICAgPyBiYXNlLmV4dGVuZChjb21wKVxuICAgIDogY29tcFxufVxuXG5mdW5jdGlvbiBjcmVhdGVBc3luY1BsYWNlaG9sZGVyIChcbiAgZmFjdG9yeSxcbiAgZGF0YSxcbiAgY29udGV4dCxcbiAgY2hpbGRyZW4sXG4gIHRhZ1xuKSB7XG4gIHZhciBub2RlID0gY3JlYXRlRW1wdHlWTm9kZSgpO1xuICBub2RlLmFzeW5jRmFjdG9yeSA9IGZhY3Rvcnk7XG4gIG5vZGUuYXN5bmNNZXRhID0geyBkYXRhOiBkYXRhLCBjb250ZXh0OiBjb250ZXh0LCBjaGlsZHJlbjogY2hpbGRyZW4sIHRhZzogdGFnIH07XG4gIHJldHVybiBub2RlXG59XG5cbmZ1bmN0aW9uIHJlc29sdmVBc3luY0NvbXBvbmVudCAoXG4gIGZhY3RvcnksXG4gIGJhc2VDdG9yLFxuICBjb250ZXh0XG4pIHtcbiAgaWYgKGlzVHJ1ZShmYWN0b3J5LmVycm9yKSAmJiBpc0RlZihmYWN0b3J5LmVycm9yQ29tcCkpIHtcbiAgICByZXR1cm4gZmFjdG9yeS5lcnJvckNvbXBcbiAgfVxuXG4gIGlmIChpc0RlZihmYWN0b3J5LnJlc29sdmVkKSkge1xuICAgIHJldHVybiBmYWN0b3J5LnJlc29sdmVkXG4gIH1cblxuICBpZiAoaXNUcnVlKGZhY3RvcnkubG9hZGluZykgJiYgaXNEZWYoZmFjdG9yeS5sb2FkaW5nQ29tcCkpIHtcbiAgICByZXR1cm4gZmFjdG9yeS5sb2FkaW5nQ29tcFxuICB9XG5cbiAgaWYgKGlzRGVmKGZhY3RvcnkuY29udGV4dHMpKSB7XG4gICAgLy8gYWxyZWFkeSBwZW5kaW5nXG4gICAgZmFjdG9yeS5jb250ZXh0cy5wdXNoKGNvbnRleHQpO1xuICB9IGVsc2Uge1xuICAgIHZhciBjb250ZXh0cyA9IGZhY3RvcnkuY29udGV4dHMgPSBbY29udGV4dF07XG4gICAgdmFyIHN5bmMgPSB0cnVlO1xuXG4gICAgdmFyIGZvcmNlUmVuZGVyID0gZnVuY3Rpb24gKCkge1xuICAgICAgZm9yICh2YXIgaSA9IDAsIGwgPSBjb250ZXh0cy5sZW5ndGg7IGkgPCBsOyBpKyspIHtcbiAgICAgICAgY29udGV4dHNbaV0uJGZvcmNlVXBkYXRlKCk7XG4gICAgICB9XG4gICAgfTtcblxuICAgIHZhciByZXNvbHZlID0gb25jZShmdW5jdGlvbiAocmVzKSB7XG4gICAgICAvLyBjYWNoZSByZXNvbHZlZFxuICAgICAgZmFjdG9yeS5yZXNvbHZlZCA9IGVuc3VyZUN0b3IocmVzLCBiYXNlQ3Rvcik7XG4gICAgICAvLyBpbnZva2UgY2FsbGJhY2tzIG9ubHkgaWYgdGhpcyBpcyBub3QgYSBzeW5jaHJvbm91cyByZXNvbHZlXG4gICAgICAvLyAoYXN5bmMgcmVzb2x2ZXMgYXJlIHNoaW1tZWQgYXMgc3luY2hyb25vdXMgZHVyaW5nIFNTUilcbiAgICAgIGlmICghc3luYykge1xuICAgICAgICBmb3JjZVJlbmRlcigpO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgdmFyIHJlamVjdCA9IG9uY2UoZnVuY3Rpb24gKHJlYXNvbikge1xuICAgICAgcHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJyAmJiB3YXJuKFxuICAgICAgICBcIkZhaWxlZCB0byByZXNvbHZlIGFzeW5jIGNvbXBvbmVudDogXCIgKyAoU3RyaW5nKGZhY3RvcnkpKSArXG4gICAgICAgIChyZWFzb24gPyAoXCJcXG5SZWFzb246IFwiICsgcmVhc29uKSA6ICcnKVxuICAgICAgKTtcbiAgICAgIGlmIChpc0RlZihmYWN0b3J5LmVycm9yQ29tcCkpIHtcbiAgICAgICAgZmFjdG9yeS5lcnJvciA9IHRydWU7XG4gICAgICAgIGZvcmNlUmVuZGVyKCk7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICB2YXIgcmVzID0gZmFjdG9yeShyZXNvbHZlLCByZWplY3QpO1xuXG4gICAgaWYgKGlzT2JqZWN0KHJlcykpIHtcbiAgICAgIGlmICh0eXBlb2YgcmVzLnRoZW4gPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgLy8gKCkgPT4gUHJvbWlzZVxuICAgICAgICBpZiAoaXNVbmRlZihmYWN0b3J5LnJlc29sdmVkKSkge1xuICAgICAgICAgIHJlcy50aGVuKHJlc29sdmUsIHJlamVjdCk7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSBpZiAoaXNEZWYocmVzLmNvbXBvbmVudCkgJiYgdHlwZW9mIHJlcy5jb21wb25lbnQudGhlbiA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICByZXMuY29tcG9uZW50LnRoZW4ocmVzb2x2ZSwgcmVqZWN0KTtcblxuICAgICAgICBpZiAoaXNEZWYocmVzLmVycm9yKSkge1xuICAgICAgICAgIGZhY3RvcnkuZXJyb3JDb21wID0gZW5zdXJlQ3RvcihyZXMuZXJyb3IsIGJhc2VDdG9yKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChpc0RlZihyZXMubG9hZGluZykpIHtcbiAgICAgICAgICBmYWN0b3J5LmxvYWRpbmdDb21wID0gZW5zdXJlQ3RvcihyZXMubG9hZGluZywgYmFzZUN0b3IpO1xuICAgICAgICAgIGlmIChyZXMuZGVsYXkgPT09IDApIHtcbiAgICAgICAgICAgIGZhY3RvcnkubG9hZGluZyA9IHRydWU7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHNldFRpbWVvdXQoZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICBpZiAoaXNVbmRlZihmYWN0b3J5LnJlc29sdmVkKSAmJiBpc1VuZGVmKGZhY3RvcnkuZXJyb3IpKSB7XG4gICAgICAgICAgICAgICAgZmFjdG9yeS5sb2FkaW5nID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICBmb3JjZVJlbmRlcigpO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9LCByZXMuZGVsYXkgfHwgMjAwKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoaXNEZWYocmVzLnRpbWVvdXQpKSB7XG4gICAgICAgICAgc2V0VGltZW91dChmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBpZiAoaXNVbmRlZihmYWN0b3J5LnJlc29sdmVkKSkge1xuICAgICAgICAgICAgICByZWplY3QoXG4gICAgICAgICAgICAgICAgcHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJ1xuICAgICAgICAgICAgICAgICAgPyAoXCJ0aW1lb3V0IChcIiArIChyZXMudGltZW91dCkgKyBcIm1zKVwiKVxuICAgICAgICAgICAgICAgICAgOiBudWxsXG4gICAgICAgICAgICAgICk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSwgcmVzLnRpbWVvdXQpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgc3luYyA9IGZhbHNlO1xuICAgIC8vIHJldHVybiBpbiBjYXNlIHJlc29sdmVkIHN5bmNocm9ub3VzbHlcbiAgICByZXR1cm4gZmFjdG9yeS5sb2FkaW5nXG4gICAgICA/IGZhY3RvcnkubG9hZGluZ0NvbXBcbiAgICAgIDogZmFjdG9yeS5yZXNvbHZlZFxuICB9XG59XG5cbi8qICAqL1xuXG5mdW5jdGlvbiBpc0FzeW5jUGxhY2Vob2xkZXIgKG5vZGUpIHtcbiAgcmV0dXJuIG5vZGUuaXNDb21tZW50ICYmIG5vZGUuYXN5bmNGYWN0b3J5XG59XG5cbi8qICAqL1xuXG5mdW5jdGlvbiBnZXRGaXJzdENvbXBvbmVudENoaWxkIChjaGlsZHJlbikge1xuICBpZiAoQXJyYXkuaXNBcnJheShjaGlsZHJlbikpIHtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGNoaWxkcmVuLmxlbmd0aDsgaSsrKSB7XG4gICAgICB2YXIgYyA9IGNoaWxkcmVuW2ldO1xuICAgICAgaWYgKGlzRGVmKGMpICYmIChpc0RlZihjLmNvbXBvbmVudE9wdGlvbnMpIHx8IGlzQXN5bmNQbGFjZWhvbGRlcihjKSkpIHtcbiAgICAgICAgcmV0dXJuIGNcbiAgICAgIH1cbiAgICB9XG4gIH1cbn1cblxuLyogICovXG5cbi8qICAqL1xuXG5mdW5jdGlvbiBpbml0RXZlbnRzICh2bSkge1xuICB2bS5fZXZlbnRzID0gT2JqZWN0LmNyZWF0ZShudWxsKTtcbiAgdm0uX2hhc0hvb2tFdmVudCA9IGZhbHNlO1xuICAvLyBpbml0IHBhcmVudCBhdHRhY2hlZCBldmVudHNcbiAgdmFyIGxpc3RlbmVycyA9IHZtLiRvcHRpb25zLl9wYXJlbnRMaXN0ZW5lcnM7XG4gIGlmIChsaXN0ZW5lcnMpIHtcbiAgICB1cGRhdGVDb21wb25lbnRMaXN0ZW5lcnModm0sIGxpc3RlbmVycyk7XG4gIH1cbn1cblxudmFyIHRhcmdldDtcblxuZnVuY3Rpb24gYWRkIChldmVudCwgZm4sIG9uY2UkJDEpIHtcbiAgaWYgKG9uY2UkJDEpIHtcbiAgICB0YXJnZXQuJG9uY2UoZXZlbnQsIGZuKTtcbiAgfSBlbHNlIHtcbiAgICB0YXJnZXQuJG9uKGV2ZW50LCBmbik7XG4gIH1cbn1cblxuZnVuY3Rpb24gcmVtb3ZlJDEgKGV2ZW50LCBmbikge1xuICB0YXJnZXQuJG9mZihldmVudCwgZm4pO1xufVxuXG5mdW5jdGlvbiB1cGRhdGVDb21wb25lbnRMaXN0ZW5lcnMgKFxuICB2bSxcbiAgbGlzdGVuZXJzLFxuICBvbGRMaXN0ZW5lcnNcbikge1xuICB0YXJnZXQgPSB2bTtcbiAgdXBkYXRlTGlzdGVuZXJzKGxpc3RlbmVycywgb2xkTGlzdGVuZXJzIHx8IHt9LCBhZGQsIHJlbW92ZSQxLCB2bSk7XG59XG5cbmZ1bmN0aW9uIGV2ZW50c01peGluIChWdWUpIHtcbiAgdmFyIGhvb2tSRSA9IC9eaG9vazovO1xuICBWdWUucHJvdG90eXBlLiRvbiA9IGZ1bmN0aW9uIChldmVudCwgZm4pIHtcbiAgICB2YXIgdGhpcyQxID0gdGhpcztcblxuICAgIHZhciB2bSA9IHRoaXM7XG4gICAgaWYgKEFycmF5LmlzQXJyYXkoZXZlbnQpKSB7XG4gICAgICBmb3IgKHZhciBpID0gMCwgbCA9IGV2ZW50Lmxlbmd0aDsgaSA8IGw7IGkrKykge1xuICAgICAgICB0aGlzJDEuJG9uKGV2ZW50W2ldLCBmbik7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgICh2bS5fZXZlbnRzW2V2ZW50XSB8fCAodm0uX2V2ZW50c1tldmVudF0gPSBbXSkpLnB1c2goZm4pO1xuICAgICAgLy8gb3B0aW1pemUgaG9vazpldmVudCBjb3N0IGJ5IHVzaW5nIGEgYm9vbGVhbiBmbGFnIG1hcmtlZCBhdCByZWdpc3RyYXRpb25cbiAgICAgIC8vIGluc3RlYWQgb2YgYSBoYXNoIGxvb2t1cFxuICAgICAgaWYgKGhvb2tSRS50ZXN0KGV2ZW50KSkge1xuICAgICAgICB2bS5faGFzSG9va0V2ZW50ID0gdHJ1ZTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHZtXG4gIH07XG5cbiAgVnVlLnByb3RvdHlwZS4kb25jZSA9IGZ1bmN0aW9uIChldmVudCwgZm4pIHtcbiAgICB2YXIgdm0gPSB0aGlzO1xuICAgIGZ1bmN0aW9uIG9uICgpIHtcbiAgICAgIHZtLiRvZmYoZXZlbnQsIG9uKTtcbiAgICAgIGZuLmFwcGx5KHZtLCBhcmd1bWVudHMpO1xuICAgIH1cbiAgICBvbi5mbiA9IGZuO1xuICAgIHZtLiRvbihldmVudCwgb24pO1xuICAgIHJldHVybiB2bVxuICB9O1xuXG4gIFZ1ZS5wcm90b3R5cGUuJG9mZiA9IGZ1bmN0aW9uIChldmVudCwgZm4pIHtcbiAgICB2YXIgdGhpcyQxID0gdGhpcztcblxuICAgIHZhciB2bSA9IHRoaXM7XG4gICAgLy8gYWxsXG4gICAgaWYgKCFhcmd1bWVudHMubGVuZ3RoKSB7XG4gICAgICB2bS5fZXZlbnRzID0gT2JqZWN0LmNyZWF0ZShudWxsKTtcbiAgICAgIHJldHVybiB2bVxuICAgIH1cbiAgICAvLyBhcnJheSBvZiBldmVudHNcbiAgICBpZiAoQXJyYXkuaXNBcnJheShldmVudCkpIHtcbiAgICAgIGZvciAodmFyIGkgPSAwLCBsID0gZXZlbnQubGVuZ3RoOyBpIDwgbDsgaSsrKSB7XG4gICAgICAgIHRoaXMkMS4kb2ZmKGV2ZW50W2ldLCBmbik7XG4gICAgICB9XG4gICAgICByZXR1cm4gdm1cbiAgICB9XG4gICAgLy8gc3BlY2lmaWMgZXZlbnRcbiAgICB2YXIgY2JzID0gdm0uX2V2ZW50c1tldmVudF07XG4gICAgaWYgKCFjYnMpIHtcbiAgICAgIHJldHVybiB2bVxuICAgIH1cbiAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCA9PT0gMSkge1xuICAgICAgdm0uX2V2ZW50c1tldmVudF0gPSBudWxsO1xuICAgICAgcmV0dXJuIHZtXG4gICAgfVxuICAgIGlmIChmbikge1xuICAgICAgLy8gc3BlY2lmaWMgaGFuZGxlclxuICAgICAgdmFyIGNiO1xuICAgICAgdmFyIGkkMSA9IGNicy5sZW5ndGg7XG4gICAgICB3aGlsZSAoaSQxLS0pIHtcbiAgICAgICAgY2IgPSBjYnNbaSQxXTtcbiAgICAgICAgaWYgKGNiID09PSBmbiB8fCBjYi5mbiA9PT0gZm4pIHtcbiAgICAgICAgICBjYnMuc3BsaWNlKGkkMSwgMSk7XG4gICAgICAgICAgYnJlYWtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gdm1cbiAgfTtcblxuICBWdWUucHJvdG90eXBlLiRlbWl0ID0gZnVuY3Rpb24gKGV2ZW50KSB7XG4gICAgdmFyIHZtID0gdGhpcztcbiAgICBpZiAocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJykge1xuICAgICAgdmFyIGxvd2VyQ2FzZUV2ZW50ID0gZXZlbnQudG9Mb3dlckNhc2UoKTtcbiAgICAgIGlmIChsb3dlckNhc2VFdmVudCAhPT0gZXZlbnQgJiYgdm0uX2V2ZW50c1tsb3dlckNhc2VFdmVudF0pIHtcbiAgICAgICAgdGlwKFxuICAgICAgICAgIFwiRXZlbnQgXFxcIlwiICsgbG93ZXJDYXNlRXZlbnQgKyBcIlxcXCIgaXMgZW1pdHRlZCBpbiBjb21wb25lbnQgXCIgK1xuICAgICAgICAgIChmb3JtYXRDb21wb25lbnROYW1lKHZtKSkgKyBcIiBidXQgdGhlIGhhbmRsZXIgaXMgcmVnaXN0ZXJlZCBmb3IgXFxcIlwiICsgZXZlbnQgKyBcIlxcXCIuIFwiICtcbiAgICAgICAgICBcIk5vdGUgdGhhdCBIVE1MIGF0dHJpYnV0ZXMgYXJlIGNhc2UtaW5zZW5zaXRpdmUgYW5kIHlvdSBjYW5ub3QgdXNlIFwiICtcbiAgICAgICAgICBcInYtb24gdG8gbGlzdGVuIHRvIGNhbWVsQ2FzZSBldmVudHMgd2hlbiB1c2luZyBpbi1ET00gdGVtcGxhdGVzLiBcIiArXG4gICAgICAgICAgXCJZb3Ugc2hvdWxkIHByb2JhYmx5IHVzZSBcXFwiXCIgKyAoaHlwaGVuYXRlKGV2ZW50KSkgKyBcIlxcXCIgaW5zdGVhZCBvZiBcXFwiXCIgKyBldmVudCArIFwiXFxcIi5cIlxuICAgICAgICApO1xuICAgICAgfVxuICAgIH1cbiAgICB2YXIgY2JzID0gdm0uX2V2ZW50c1tldmVudF07XG4gICAgaWYgKGNicykge1xuICAgICAgY2JzID0gY2JzLmxlbmd0aCA+IDEgPyB0b0FycmF5KGNicykgOiBjYnM7XG4gICAgICB2YXIgYXJncyA9IHRvQXJyYXkoYXJndW1lbnRzLCAxKTtcbiAgICAgIGZvciAodmFyIGkgPSAwLCBsID0gY2JzLmxlbmd0aDsgaSA8IGw7IGkrKykge1xuICAgICAgICB0cnkge1xuICAgICAgICAgIGNic1tpXS5hcHBseSh2bSwgYXJncyk7XG4gICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICBoYW5kbGVFcnJvcihlLCB2bSwgKFwiZXZlbnQgaGFuZGxlciBmb3IgXFxcIlwiICsgZXZlbnQgKyBcIlxcXCJcIikpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiB2bVxuICB9O1xufVxuXG4vKiAgKi9cblxuLyoqXG4gKiBSdW50aW1lIGhlbHBlciBmb3IgcmVzb2x2aW5nIHJhdyBjaGlsZHJlbiBWTm9kZXMgaW50byBhIHNsb3Qgb2JqZWN0LlxuICovXG5mdW5jdGlvbiByZXNvbHZlU2xvdHMgKFxuICBjaGlsZHJlbixcbiAgY29udGV4dFxuKSB7XG4gIHZhciBzbG90cyA9IHt9O1xuICBpZiAoIWNoaWxkcmVuKSB7XG4gICAgcmV0dXJuIHNsb3RzXG4gIH1cbiAgdmFyIGRlZmF1bHRTbG90ID0gW107XG4gIGZvciAodmFyIGkgPSAwLCBsID0gY2hpbGRyZW4ubGVuZ3RoOyBpIDwgbDsgaSsrKSB7XG4gICAgdmFyIGNoaWxkID0gY2hpbGRyZW5baV07XG4gICAgdmFyIGRhdGEgPSBjaGlsZC5kYXRhO1xuICAgIC8vIHJlbW92ZSBzbG90IGF0dHJpYnV0ZSBpZiB0aGUgbm9kZSBpcyByZXNvbHZlZCBhcyBhIFZ1ZSBzbG90IG5vZGVcbiAgICBpZiAoZGF0YSAmJiBkYXRhLmF0dHJzICYmIGRhdGEuYXR0cnMuc2xvdCkge1xuICAgICAgZGVsZXRlIGRhdGEuYXR0cnMuc2xvdDtcbiAgICB9XG4gICAgLy8gbmFtZWQgc2xvdHMgc2hvdWxkIG9ubHkgYmUgcmVzcGVjdGVkIGlmIHRoZSB2bm9kZSB3YXMgcmVuZGVyZWQgaW4gdGhlXG4gICAgLy8gc2FtZSBjb250ZXh0LlxuICAgIGlmICgoY2hpbGQuY29udGV4dCA9PT0gY29udGV4dCB8fCBjaGlsZC5mdW5jdGlvbmFsQ29udGV4dCA9PT0gY29udGV4dCkgJiZcbiAgICAgIGRhdGEgJiYgZGF0YS5zbG90ICE9IG51bGxcbiAgICApIHtcbiAgICAgIHZhciBuYW1lID0gY2hpbGQuZGF0YS5zbG90O1xuICAgICAgdmFyIHNsb3QgPSAoc2xvdHNbbmFtZV0gfHwgKHNsb3RzW25hbWVdID0gW10pKTtcbiAgICAgIGlmIChjaGlsZC50YWcgPT09ICd0ZW1wbGF0ZScpIHtcbiAgICAgICAgc2xvdC5wdXNoLmFwcGx5KHNsb3QsIGNoaWxkLmNoaWxkcmVuKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHNsb3QucHVzaChjaGlsZCk7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIGRlZmF1bHRTbG90LnB1c2goY2hpbGQpO1xuICAgIH1cbiAgfVxuICAvLyBpZ25vcmUgd2hpdGVzcGFjZVxuICBpZiAoIWRlZmF1bHRTbG90LmV2ZXJ5KGlzV2hpdGVzcGFjZSkpIHtcbiAgICBzbG90cy5kZWZhdWx0ID0gZGVmYXVsdFNsb3Q7XG4gIH1cbiAgcmV0dXJuIHNsb3RzXG59XG5cbmZ1bmN0aW9uIGlzV2hpdGVzcGFjZSAobm9kZSkge1xuICByZXR1cm4gbm9kZS5pc0NvbW1lbnQgfHwgbm9kZS50ZXh0ID09PSAnICdcbn1cblxuZnVuY3Rpb24gcmVzb2x2ZVNjb3BlZFNsb3RzIChcbiAgZm5zLCAvLyBzZWUgZmxvdy92bm9kZVxuICByZXNcbikge1xuICByZXMgPSByZXMgfHwge307XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgZm5zLmxlbmd0aDsgaSsrKSB7XG4gICAgaWYgKEFycmF5LmlzQXJyYXkoZm5zW2ldKSkge1xuICAgICAgcmVzb2x2ZVNjb3BlZFNsb3RzKGZuc1tpXSwgcmVzKTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmVzW2Zuc1tpXS5rZXldID0gZm5zW2ldLmZuO1xuICAgIH1cbiAgfVxuICByZXR1cm4gcmVzXG59XG5cbi8qICAqL1xuXG52YXIgYWN0aXZlSW5zdGFuY2UgPSBudWxsO1xudmFyIGlzVXBkYXRpbmdDaGlsZENvbXBvbmVudCA9IGZhbHNlO1xuXG5mdW5jdGlvbiBpbml0TGlmZWN5Y2xlICh2bSkge1xuICB2YXIgb3B0aW9ucyA9IHZtLiRvcHRpb25zO1xuXG4gIC8vIGxvY2F0ZSBmaXJzdCBub24tYWJzdHJhY3QgcGFyZW50XG4gIHZhciBwYXJlbnQgPSBvcHRpb25zLnBhcmVudDtcbiAgaWYgKHBhcmVudCAmJiAhb3B0aW9ucy5hYnN0cmFjdCkge1xuICAgIHdoaWxlIChwYXJlbnQuJG9wdGlvbnMuYWJzdHJhY3QgJiYgcGFyZW50LiRwYXJlbnQpIHtcbiAgICAgIHBhcmVudCA9IHBhcmVudC4kcGFyZW50O1xuICAgIH1cbiAgICBwYXJlbnQuJGNoaWxkcmVuLnB1c2godm0pO1xuICB9XG5cbiAgdm0uJHBhcmVudCA9IHBhcmVudDtcbiAgdm0uJHJvb3QgPSBwYXJlbnQgPyBwYXJlbnQuJHJvb3QgOiB2bTtcblxuICB2bS4kY2hpbGRyZW4gPSBbXTtcbiAgdm0uJHJlZnMgPSB7fTtcblxuICB2bS5fd2F0Y2hlciA9IG51bGw7XG4gIHZtLl9pbmFjdGl2ZSA9IG51bGw7XG4gIHZtLl9kaXJlY3RJbmFjdGl2ZSA9IGZhbHNlO1xuICB2bS5faXNNb3VudGVkID0gZmFsc2U7XG4gIHZtLl9pc0Rlc3Ryb3llZCA9IGZhbHNlO1xuICB2bS5faXNCZWluZ0Rlc3Ryb3llZCA9IGZhbHNlO1xufVxuXG5mdW5jdGlvbiBsaWZlY3ljbGVNaXhpbiAoVnVlKSB7XG4gIFZ1ZS5wcm90b3R5cGUuX3VwZGF0ZSA9IGZ1bmN0aW9uICh2bm9kZSwgaHlkcmF0aW5nKSB7XG4gICAgdmFyIHZtID0gdGhpcztcbiAgICBpZiAodm0uX2lzTW91bnRlZCkge1xuICAgICAgY2FsbEhvb2sodm0sICdiZWZvcmVVcGRhdGUnKTtcbiAgICB9XG4gICAgdmFyIHByZXZFbCA9IHZtLiRlbDtcbiAgICB2YXIgcHJldlZub2RlID0gdm0uX3Zub2RlO1xuICAgIHZhciBwcmV2QWN0aXZlSW5zdGFuY2UgPSBhY3RpdmVJbnN0YW5jZTtcbiAgICBhY3RpdmVJbnN0YW5jZSA9IHZtO1xuICAgIHZtLl92bm9kZSA9IHZub2RlO1xuICAgIC8vIFZ1ZS5wcm90b3R5cGUuX19wYXRjaF9fIGlzIGluamVjdGVkIGluIGVudHJ5IHBvaW50c1xuICAgIC8vIGJhc2VkIG9uIHRoZSByZW5kZXJpbmcgYmFja2VuZCB1c2VkLlxuICAgIGlmICghcHJldlZub2RlKSB7XG4gICAgICAvLyBpbml0aWFsIHJlbmRlclxuICAgICAgdm0uJGVsID0gdm0uX19wYXRjaF9fKFxuICAgICAgICB2bS4kZWwsIHZub2RlLCBoeWRyYXRpbmcsIGZhbHNlIC8qIHJlbW92ZU9ubHkgKi8sXG4gICAgICAgIHZtLiRvcHRpb25zLl9wYXJlbnRFbG0sXG4gICAgICAgIHZtLiRvcHRpb25zLl9yZWZFbG1cbiAgICAgICk7XG4gICAgICAvLyBubyBuZWVkIGZvciB0aGUgcmVmIG5vZGVzIGFmdGVyIGluaXRpYWwgcGF0Y2hcbiAgICAgIC8vIHRoaXMgcHJldmVudHMga2VlcGluZyBhIGRldGFjaGVkIERPTSB0cmVlIGluIG1lbW9yeSAoIzU4NTEpXG4gICAgICB2bS4kb3B0aW9ucy5fcGFyZW50RWxtID0gdm0uJG9wdGlvbnMuX3JlZkVsbSA9IG51bGw7XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIHVwZGF0ZXNcbiAgICAgIHZtLiRlbCA9IHZtLl9fcGF0Y2hfXyhwcmV2Vm5vZGUsIHZub2RlKTtcbiAgICB9XG4gICAgYWN0aXZlSW5zdGFuY2UgPSBwcmV2QWN0aXZlSW5zdGFuY2U7XG4gICAgLy8gdXBkYXRlIF9fdnVlX18gcmVmZXJlbmNlXG4gICAgaWYgKHByZXZFbCkge1xuICAgICAgcHJldkVsLl9fdnVlX18gPSBudWxsO1xuICAgIH1cbiAgICBpZiAodm0uJGVsKSB7XG4gICAgICB2bS4kZWwuX192dWVfXyA9IHZtO1xuICAgIH1cbiAgICAvLyBpZiBwYXJlbnQgaXMgYW4gSE9DLCB1cGRhdGUgaXRzICRlbCBhcyB3ZWxsXG4gICAgaWYgKHZtLiR2bm9kZSAmJiB2bS4kcGFyZW50ICYmIHZtLiR2bm9kZSA9PT0gdm0uJHBhcmVudC5fdm5vZGUpIHtcbiAgICAgIHZtLiRwYXJlbnQuJGVsID0gdm0uJGVsO1xuICAgIH1cbiAgICAvLyB1cGRhdGVkIGhvb2sgaXMgY2FsbGVkIGJ5IHRoZSBzY2hlZHVsZXIgdG8gZW5zdXJlIHRoYXQgY2hpbGRyZW4gYXJlXG4gICAgLy8gdXBkYXRlZCBpbiBhIHBhcmVudCdzIHVwZGF0ZWQgaG9vay5cbiAgfTtcblxuICBWdWUucHJvdG90eXBlLiRmb3JjZVVwZGF0ZSA9IGZ1bmN0aW9uICgpIHtcbiAgICB2YXIgdm0gPSB0aGlzO1xuICAgIGlmICh2bS5fd2F0Y2hlcikge1xuICAgICAgdm0uX3dhdGNoZXIudXBkYXRlKCk7XG4gICAgfVxuICB9O1xuXG4gIFZ1ZS5wcm90b3R5cGUuJGRlc3Ryb3kgPSBmdW5jdGlvbiAoKSB7XG4gICAgdmFyIHZtID0gdGhpcztcbiAgICBpZiAodm0uX2lzQmVpbmdEZXN0cm95ZWQpIHtcbiAgICAgIHJldHVyblxuICAgIH1cbiAgICBjYWxsSG9vayh2bSwgJ2JlZm9yZURlc3Ryb3knKTtcbiAgICB2bS5faXNCZWluZ0Rlc3Ryb3llZCA9IHRydWU7XG4gICAgLy8gcmVtb3ZlIHNlbGYgZnJvbSBwYXJlbnRcbiAgICB2YXIgcGFyZW50ID0gdm0uJHBhcmVudDtcbiAgICBpZiAocGFyZW50ICYmICFwYXJlbnQuX2lzQmVpbmdEZXN0cm95ZWQgJiYgIXZtLiRvcHRpb25zLmFic3RyYWN0KSB7XG4gICAgICByZW1vdmUocGFyZW50LiRjaGlsZHJlbiwgdm0pO1xuICAgIH1cbiAgICAvLyB0ZWFyZG93biB3YXRjaGVyc1xuICAgIGlmICh2bS5fd2F0Y2hlcikge1xuICAgICAgdm0uX3dhdGNoZXIudGVhcmRvd24oKTtcbiAgICB9XG4gICAgdmFyIGkgPSB2bS5fd2F0Y2hlcnMubGVuZ3RoO1xuICAgIHdoaWxlIChpLS0pIHtcbiAgICAgIHZtLl93YXRjaGVyc1tpXS50ZWFyZG93bigpO1xuICAgIH1cbiAgICAvLyByZW1vdmUgcmVmZXJlbmNlIGZyb20gZGF0YSBvYlxuICAgIC8vIGZyb3plbiBvYmplY3QgbWF5IG5vdCBoYXZlIG9ic2VydmVyLlxuICAgIGlmICh2bS5fZGF0YS5fX29iX18pIHtcbiAgICAgIHZtLl9kYXRhLl9fb2JfXy52bUNvdW50LS07XG4gICAgfVxuICAgIC8vIGNhbGwgdGhlIGxhc3QgaG9vay4uLlxuICAgIHZtLl9pc0Rlc3Ryb3llZCA9IHRydWU7XG4gICAgLy8gaW52b2tlIGRlc3Ryb3kgaG9va3Mgb24gY3VycmVudCByZW5kZXJlZCB0cmVlXG4gICAgdm0uX19wYXRjaF9fKHZtLl92bm9kZSwgbnVsbCk7XG4gICAgLy8gZmlyZSBkZXN0cm95ZWQgaG9va1xuICAgIGNhbGxIb29rKHZtLCAnZGVzdHJveWVkJyk7XG4gICAgLy8gdHVybiBvZmYgYWxsIGluc3RhbmNlIGxpc3RlbmVycy5cbiAgICB2bS4kb2ZmKCk7XG4gICAgLy8gcmVtb3ZlIF9fdnVlX18gcmVmZXJlbmNlXG4gICAgaWYgKHZtLiRlbCkge1xuICAgICAgdm0uJGVsLl9fdnVlX18gPSBudWxsO1xuICAgIH1cbiAgfTtcbn1cblxuZnVuY3Rpb24gbW91bnRDb21wb25lbnQgKFxuICB2bSxcbiAgZWwsXG4gIGh5ZHJhdGluZ1xuKSB7XG4gIHZtLiRlbCA9IGVsO1xuICBpZiAoIXZtLiRvcHRpb25zLnJlbmRlcikge1xuICAgIHZtLiRvcHRpb25zLnJlbmRlciA9IGNyZWF0ZUVtcHR5Vk5vZGU7XG4gICAgaWYgKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicpIHtcbiAgICAgIC8qIGlzdGFuYnVsIGlnbm9yZSBpZiAqL1xuICAgICAgaWYgKCh2bS4kb3B0aW9ucy50ZW1wbGF0ZSAmJiB2bS4kb3B0aW9ucy50ZW1wbGF0ZS5jaGFyQXQoMCkgIT09ICcjJykgfHxcbiAgICAgICAgdm0uJG9wdGlvbnMuZWwgfHwgZWwpIHtcbiAgICAgICAgd2FybihcbiAgICAgICAgICAnWW91IGFyZSB1c2luZyB0aGUgcnVudGltZS1vbmx5IGJ1aWxkIG9mIFZ1ZSB3aGVyZSB0aGUgdGVtcGxhdGUgJyArXG4gICAgICAgICAgJ2NvbXBpbGVyIGlzIG5vdCBhdmFpbGFibGUuIEVpdGhlciBwcmUtY29tcGlsZSB0aGUgdGVtcGxhdGVzIGludG8gJyArXG4gICAgICAgICAgJ3JlbmRlciBmdW5jdGlvbnMsIG9yIHVzZSB0aGUgY29tcGlsZXItaW5jbHVkZWQgYnVpbGQuJyxcbiAgICAgICAgICB2bVxuICAgICAgICApO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgd2FybihcbiAgICAgICAgICAnRmFpbGVkIHRvIG1vdW50IGNvbXBvbmVudDogdGVtcGxhdGUgb3IgcmVuZGVyIGZ1bmN0aW9uIG5vdCBkZWZpbmVkLicsXG4gICAgICAgICAgdm1cbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cbiAgY2FsbEhvb2sodm0sICdiZWZvcmVNb3VudCcpO1xuXG4gIHZhciB1cGRhdGVDb21wb25lbnQ7XG4gIC8qIGlzdGFuYnVsIGlnbm9yZSBpZiAqL1xuICBpZiAocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJyAmJiBjb25maWcucGVyZm9ybWFuY2UgJiYgbWFyaykge1xuICAgIHVwZGF0ZUNvbXBvbmVudCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgIHZhciBuYW1lID0gdm0uX25hbWU7XG4gICAgICB2YXIgaWQgPSB2bS5fdWlkO1xuICAgICAgdmFyIHN0YXJ0VGFnID0gXCJ2dWUtcGVyZi1zdGFydDpcIiArIGlkO1xuICAgICAgdmFyIGVuZFRhZyA9IFwidnVlLXBlcmYtZW5kOlwiICsgaWQ7XG5cbiAgICAgIG1hcmsoc3RhcnRUYWcpO1xuICAgICAgdmFyIHZub2RlID0gdm0uX3JlbmRlcigpO1xuICAgICAgbWFyayhlbmRUYWcpO1xuICAgICAgbWVhc3VyZSgobmFtZSArIFwiIHJlbmRlclwiKSwgc3RhcnRUYWcsIGVuZFRhZyk7XG5cbiAgICAgIG1hcmsoc3RhcnRUYWcpO1xuICAgICAgdm0uX3VwZGF0ZSh2bm9kZSwgaHlkcmF0aW5nKTtcbiAgICAgIG1hcmsoZW5kVGFnKTtcbiAgICAgIG1lYXN1cmUoKG5hbWUgKyBcIiBwYXRjaFwiKSwgc3RhcnRUYWcsIGVuZFRhZyk7XG4gICAgfTtcbiAgfSBlbHNlIHtcbiAgICB1cGRhdGVDb21wb25lbnQgPSBmdW5jdGlvbiAoKSB7XG4gICAgICB2bS5fdXBkYXRlKHZtLl9yZW5kZXIoKSwgaHlkcmF0aW5nKTtcbiAgICB9O1xuICB9XG5cbiAgdm0uX3dhdGNoZXIgPSBuZXcgV2F0Y2hlcih2bSwgdXBkYXRlQ29tcG9uZW50LCBub29wKTtcbiAgaHlkcmF0aW5nID0gZmFsc2U7XG5cbiAgLy8gbWFudWFsbHkgbW91bnRlZCBpbnN0YW5jZSwgY2FsbCBtb3VudGVkIG9uIHNlbGZcbiAgLy8gbW91bnRlZCBpcyBjYWxsZWQgZm9yIHJlbmRlci1jcmVhdGVkIGNoaWxkIGNvbXBvbmVudHMgaW4gaXRzIGluc2VydGVkIGhvb2tcbiAgaWYgKHZtLiR2bm9kZSA9PSBudWxsKSB7XG4gICAgdm0uX2lzTW91bnRlZCA9IHRydWU7XG4gICAgY2FsbEhvb2sodm0sICdtb3VudGVkJyk7XG4gIH1cbiAgcmV0dXJuIHZtXG59XG5cbmZ1bmN0aW9uIHVwZGF0ZUNoaWxkQ29tcG9uZW50IChcbiAgdm0sXG4gIHByb3BzRGF0YSxcbiAgbGlzdGVuZXJzLFxuICBwYXJlbnRWbm9kZSxcbiAgcmVuZGVyQ2hpbGRyZW5cbikge1xuICBpZiAocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJykge1xuICAgIGlzVXBkYXRpbmdDaGlsZENvbXBvbmVudCA9IHRydWU7XG4gIH1cblxuICAvLyBkZXRlcm1pbmUgd2hldGhlciBjb21wb25lbnQgaGFzIHNsb3QgY2hpbGRyZW5cbiAgLy8gd2UgbmVlZCB0byBkbyB0aGlzIGJlZm9yZSBvdmVyd3JpdGluZyAkb3B0aW9ucy5fcmVuZGVyQ2hpbGRyZW5cbiAgdmFyIGhhc0NoaWxkcmVuID0gISEoXG4gICAgcmVuZGVyQ2hpbGRyZW4gfHwgICAgICAgICAgICAgICAvLyBoYXMgbmV3IHN0YXRpYyBzbG90c1xuICAgIHZtLiRvcHRpb25zLl9yZW5kZXJDaGlsZHJlbiB8fCAgLy8gaGFzIG9sZCBzdGF0aWMgc2xvdHNcbiAgICBwYXJlbnRWbm9kZS5kYXRhLnNjb3BlZFNsb3RzIHx8IC8vIGhhcyBuZXcgc2NvcGVkIHNsb3RzXG4gICAgdm0uJHNjb3BlZFNsb3RzICE9PSBlbXB0eU9iamVjdCAvLyBoYXMgb2xkIHNjb3BlZCBzbG90c1xuICApO1xuXG4gIHZtLiRvcHRpb25zLl9wYXJlbnRWbm9kZSA9IHBhcmVudFZub2RlO1xuICB2bS4kdm5vZGUgPSBwYXJlbnRWbm9kZTsgLy8gdXBkYXRlIHZtJ3MgcGxhY2Vob2xkZXIgbm9kZSB3aXRob3V0IHJlLXJlbmRlclxuXG4gIGlmICh2bS5fdm5vZGUpIHsgLy8gdXBkYXRlIGNoaWxkIHRyZWUncyBwYXJlbnRcbiAgICB2bS5fdm5vZGUucGFyZW50ID0gcGFyZW50Vm5vZGU7XG4gIH1cbiAgdm0uJG9wdGlvbnMuX3JlbmRlckNoaWxkcmVuID0gcmVuZGVyQ2hpbGRyZW47XG5cbiAgLy8gdXBkYXRlICRhdHRycyBhbmQgJGxpc3RlbmVycyBoYXNoXG4gIC8vIHRoZXNlIGFyZSBhbHNvIHJlYWN0aXZlIHNvIHRoZXkgbWF5IHRyaWdnZXIgY2hpbGQgdXBkYXRlIGlmIHRoZSBjaGlsZFxuICAvLyB1c2VkIHRoZW0gZHVyaW5nIHJlbmRlclxuICB2bS4kYXR0cnMgPSAocGFyZW50Vm5vZGUuZGF0YSAmJiBwYXJlbnRWbm9kZS5kYXRhLmF0dHJzKSB8fCBlbXB0eU9iamVjdDtcbiAgdm0uJGxpc3RlbmVycyA9IGxpc3RlbmVycyB8fCBlbXB0eU9iamVjdDtcblxuICAvLyB1cGRhdGUgcHJvcHNcbiAgaWYgKHByb3BzRGF0YSAmJiB2bS4kb3B0aW9ucy5wcm9wcykge1xuICAgIG9ic2VydmVyU3RhdGUuc2hvdWxkQ29udmVydCA9IGZhbHNlO1xuICAgIHZhciBwcm9wcyA9IHZtLl9wcm9wcztcbiAgICB2YXIgcHJvcEtleXMgPSB2bS4kb3B0aW9ucy5fcHJvcEtleXMgfHwgW107XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBwcm9wS2V5cy5sZW5ndGg7IGkrKykge1xuICAgICAgdmFyIGtleSA9IHByb3BLZXlzW2ldO1xuICAgICAgcHJvcHNba2V5XSA9IHZhbGlkYXRlUHJvcChrZXksIHZtLiRvcHRpb25zLnByb3BzLCBwcm9wc0RhdGEsIHZtKTtcbiAgICB9XG4gICAgb2JzZXJ2ZXJTdGF0ZS5zaG91bGRDb252ZXJ0ID0gdHJ1ZTtcbiAgICAvLyBrZWVwIGEgY29weSBvZiByYXcgcHJvcHNEYXRhXG4gICAgdm0uJG9wdGlvbnMucHJvcHNEYXRhID0gcHJvcHNEYXRhO1xuICB9XG5cbiAgLy8gdXBkYXRlIGxpc3RlbmVyc1xuICBpZiAobGlzdGVuZXJzKSB7XG4gICAgdmFyIG9sZExpc3RlbmVycyA9IHZtLiRvcHRpb25zLl9wYXJlbnRMaXN0ZW5lcnM7XG4gICAgdm0uJG9wdGlvbnMuX3BhcmVudExpc3RlbmVycyA9IGxpc3RlbmVycztcbiAgICB1cGRhdGVDb21wb25lbnRMaXN0ZW5lcnModm0sIGxpc3RlbmVycywgb2xkTGlzdGVuZXJzKTtcbiAgfVxuICAvLyByZXNvbHZlIHNsb3RzICsgZm9yY2UgdXBkYXRlIGlmIGhhcyBjaGlsZHJlblxuICBpZiAoaGFzQ2hpbGRyZW4pIHtcbiAgICB2bS4kc2xvdHMgPSByZXNvbHZlU2xvdHMocmVuZGVyQ2hpbGRyZW4sIHBhcmVudFZub2RlLmNvbnRleHQpO1xuICAgIHZtLiRmb3JjZVVwZGF0ZSgpO1xuICB9XG5cbiAgaWYgKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicpIHtcbiAgICBpc1VwZGF0aW5nQ2hpbGRDb21wb25lbnQgPSBmYWxzZTtcbiAgfVxufVxuXG5mdW5jdGlvbiBpc0luSW5hY3RpdmVUcmVlICh2bSkge1xuICB3aGlsZSAodm0gJiYgKHZtID0gdm0uJHBhcmVudCkpIHtcbiAgICBpZiAodm0uX2luYWN0aXZlKSB7IHJldHVybiB0cnVlIH1cbiAgfVxuICByZXR1cm4gZmFsc2Vcbn1cblxuZnVuY3Rpb24gYWN0aXZhdGVDaGlsZENvbXBvbmVudCAodm0sIGRpcmVjdCkge1xuICBpZiAoZGlyZWN0KSB7XG4gICAgdm0uX2RpcmVjdEluYWN0aXZlID0gZmFsc2U7XG4gICAgaWYgKGlzSW5JbmFjdGl2ZVRyZWUodm0pKSB7XG4gICAgICByZXR1cm5cbiAgICB9XG4gIH0gZWxzZSBpZiAodm0uX2RpcmVjdEluYWN0aXZlKSB7XG4gICAgcmV0dXJuXG4gIH1cbiAgaWYgKHZtLl9pbmFjdGl2ZSB8fCB2bS5faW5hY3RpdmUgPT09IG51bGwpIHtcbiAgICB2bS5faW5hY3RpdmUgPSBmYWxzZTtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IHZtLiRjaGlsZHJlbi5sZW5ndGg7IGkrKykge1xuICAgICAgYWN0aXZhdGVDaGlsZENvbXBvbmVudCh2bS4kY2hpbGRyZW5baV0pO1xuICAgIH1cbiAgICBjYWxsSG9vayh2bSwgJ2FjdGl2YXRlZCcpO1xuICB9XG59XG5cbmZ1bmN0aW9uIGRlYWN0aXZhdGVDaGlsZENvbXBvbmVudCAodm0sIGRpcmVjdCkge1xuICBpZiAoZGlyZWN0KSB7XG4gICAgdm0uX2RpcmVjdEluYWN0aXZlID0gdHJ1ZTtcbiAgICBpZiAoaXNJbkluYWN0aXZlVHJlZSh2bSkpIHtcbiAgICAgIHJldHVyblxuICAgIH1cbiAgfVxuICBpZiAoIXZtLl9pbmFjdGl2ZSkge1xuICAgIHZtLl9pbmFjdGl2ZSA9IHRydWU7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCB2bS4kY2hpbGRyZW4ubGVuZ3RoOyBpKyspIHtcbiAgICAgIGRlYWN0aXZhdGVDaGlsZENvbXBvbmVudCh2bS4kY2hpbGRyZW5baV0pO1xuICAgIH1cbiAgICBjYWxsSG9vayh2bSwgJ2RlYWN0aXZhdGVkJyk7XG4gIH1cbn1cblxuZnVuY3Rpb24gY2FsbEhvb2sgKHZtLCBob29rKSB7XG4gIHZhciBoYW5kbGVycyA9IHZtLiRvcHRpb25zW2hvb2tdO1xuICBpZiAoaGFuZGxlcnMpIHtcbiAgICBmb3IgKHZhciBpID0gMCwgaiA9IGhhbmRsZXJzLmxlbmd0aDsgaSA8IGo7IGkrKykge1xuICAgICAgdHJ5IHtcbiAgICAgICAgaGFuZGxlcnNbaV0uY2FsbCh2bSk7XG4gICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIGhhbmRsZUVycm9yKGUsIHZtLCAoaG9vayArIFwiIGhvb2tcIikpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuICBpZiAodm0uX2hhc0hvb2tFdmVudCkge1xuICAgIHZtLiRlbWl0KCdob29rOicgKyBob29rKTtcbiAgfVxufVxuXG4vKiAgKi9cblxuXG52YXIgTUFYX1VQREFURV9DT1VOVCA9IDEwMDtcblxudmFyIHF1ZXVlID0gW107XG52YXIgYWN0aXZhdGVkQ2hpbGRyZW4gPSBbXTtcbnZhciBoYXMgPSB7fTtcbnZhciBjaXJjdWxhciA9IHt9O1xudmFyIHdhaXRpbmcgPSBmYWxzZTtcbnZhciBmbHVzaGluZyA9IGZhbHNlO1xudmFyIGluZGV4ID0gMDtcblxuLyoqXG4gKiBSZXNldCB0aGUgc2NoZWR1bGVyJ3Mgc3RhdGUuXG4gKi9cbmZ1bmN0aW9uIHJlc2V0U2NoZWR1bGVyU3RhdGUgKCkge1xuICBpbmRleCA9IHF1ZXVlLmxlbmd0aCA9IGFjdGl2YXRlZENoaWxkcmVuLmxlbmd0aCA9IDA7XG4gIGhhcyA9IHt9O1xuICBpZiAocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJykge1xuICAgIGNpcmN1bGFyID0ge307XG4gIH1cbiAgd2FpdGluZyA9IGZsdXNoaW5nID0gZmFsc2U7XG59XG5cbi8qKlxuICogRmx1c2ggYm90aCBxdWV1ZXMgYW5kIHJ1biB0aGUgd2F0Y2hlcnMuXG4gKi9cbmZ1bmN0aW9uIGZsdXNoU2NoZWR1bGVyUXVldWUgKCkge1xuICBmbHVzaGluZyA9IHRydWU7XG4gIHZhciB3YXRjaGVyLCBpZDtcblxuICAvLyBTb3J0IHF1ZXVlIGJlZm9yZSBmbHVzaC5cbiAgLy8gVGhpcyBlbnN1cmVzIHRoYXQ6XG4gIC8vIDEuIENvbXBvbmVudHMgYXJlIHVwZGF0ZWQgZnJvbSBwYXJlbnQgdG8gY2hpbGQuIChiZWNhdXNlIHBhcmVudCBpcyBhbHdheXNcbiAgLy8gICAgY3JlYXRlZCBiZWZvcmUgdGhlIGNoaWxkKVxuICAvLyAyLiBBIGNvbXBvbmVudCdzIHVzZXIgd2F0Y2hlcnMgYXJlIHJ1biBiZWZvcmUgaXRzIHJlbmRlciB3YXRjaGVyIChiZWNhdXNlXG4gIC8vICAgIHVzZXIgd2F0Y2hlcnMgYXJlIGNyZWF0ZWQgYmVmb3JlIHRoZSByZW5kZXIgd2F0Y2hlcilcbiAgLy8gMy4gSWYgYSBjb21wb25lbnQgaXMgZGVzdHJveWVkIGR1cmluZyBhIHBhcmVudCBjb21wb25lbnQncyB3YXRjaGVyIHJ1bixcbiAgLy8gICAgaXRzIHdhdGNoZXJzIGNhbiBiZSBza2lwcGVkLlxuICBxdWV1ZS5zb3J0KGZ1bmN0aW9uIChhLCBiKSB7IHJldHVybiBhLmlkIC0gYi5pZDsgfSk7XG5cbiAgLy8gZG8gbm90IGNhY2hlIGxlbmd0aCBiZWNhdXNlIG1vcmUgd2F0Y2hlcnMgbWlnaHQgYmUgcHVzaGVkXG4gIC8vIGFzIHdlIHJ1biBleGlzdGluZyB3YXRjaGVyc1xuICBmb3IgKGluZGV4ID0gMDsgaW5kZXggPCBxdWV1ZS5sZW5ndGg7IGluZGV4KyspIHtcbiAgICB3YXRjaGVyID0gcXVldWVbaW5kZXhdO1xuICAgIGlkID0gd2F0Y2hlci5pZDtcbiAgICBoYXNbaWRdID0gbnVsbDtcbiAgICB3YXRjaGVyLnJ1bigpO1xuICAgIC8vIGluIGRldiBidWlsZCwgY2hlY2sgYW5kIHN0b3AgY2lyY3VsYXIgdXBkYXRlcy5cbiAgICBpZiAocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJyAmJiBoYXNbaWRdICE9IG51bGwpIHtcbiAgICAgIGNpcmN1bGFyW2lkXSA9IChjaXJjdWxhcltpZF0gfHwgMCkgKyAxO1xuICAgICAgaWYgKGNpcmN1bGFyW2lkXSA+IE1BWF9VUERBVEVfQ09VTlQpIHtcbiAgICAgICAgd2FybihcbiAgICAgICAgICAnWW91IG1heSBoYXZlIGFuIGluZmluaXRlIHVwZGF0ZSBsb29wICcgKyAoXG4gICAgICAgICAgICB3YXRjaGVyLnVzZXJcbiAgICAgICAgICAgICAgPyAoXCJpbiB3YXRjaGVyIHdpdGggZXhwcmVzc2lvbiBcXFwiXCIgKyAod2F0Y2hlci5leHByZXNzaW9uKSArIFwiXFxcIlwiKVxuICAgICAgICAgICAgICA6IFwiaW4gYSBjb21wb25lbnQgcmVuZGVyIGZ1bmN0aW9uLlwiXG4gICAgICAgICAgKSxcbiAgICAgICAgICB3YXRjaGVyLnZtXG4gICAgICAgICk7XG4gICAgICAgIGJyZWFrXG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgLy8ga2VlcCBjb3BpZXMgb2YgcG9zdCBxdWV1ZXMgYmVmb3JlIHJlc2V0dGluZyBzdGF0ZVxuICB2YXIgYWN0aXZhdGVkUXVldWUgPSBhY3RpdmF0ZWRDaGlsZHJlbi5zbGljZSgpO1xuICB2YXIgdXBkYXRlZFF1ZXVlID0gcXVldWUuc2xpY2UoKTtcblxuICByZXNldFNjaGVkdWxlclN0YXRlKCk7XG5cbiAgLy8gY2FsbCBjb21wb25lbnQgdXBkYXRlZCBhbmQgYWN0aXZhdGVkIGhvb2tzXG4gIGNhbGxBY3RpdmF0ZWRIb29rcyhhY3RpdmF0ZWRRdWV1ZSk7XG4gIGNhbGxVcGRhdGVkSG9va3ModXBkYXRlZFF1ZXVlKTtcblxuICAvLyBkZXZ0b29sIGhvb2tcbiAgLyogaXN0YW5idWwgaWdub3JlIGlmICovXG4gIGlmIChkZXZ0b29scyAmJiBjb25maWcuZGV2dG9vbHMpIHtcbiAgICBkZXZ0b29scy5lbWl0KCdmbHVzaCcpO1xuICB9XG59XG5cbmZ1bmN0aW9uIGNhbGxVcGRhdGVkSG9va3MgKHF1ZXVlKSB7XG4gIHZhciBpID0gcXVldWUubGVuZ3RoO1xuICB3aGlsZSAoaS0tKSB7XG4gICAgdmFyIHdhdGNoZXIgPSBxdWV1ZVtpXTtcbiAgICB2YXIgdm0gPSB3YXRjaGVyLnZtO1xuICAgIGlmICh2bS5fd2F0Y2hlciA9PT0gd2F0Y2hlciAmJiB2bS5faXNNb3VudGVkKSB7XG4gICAgICBjYWxsSG9vayh2bSwgJ3VwZGF0ZWQnKTtcbiAgICB9XG4gIH1cbn1cblxuLyoqXG4gKiBRdWV1ZSBhIGtlcHQtYWxpdmUgY29tcG9uZW50IHRoYXQgd2FzIGFjdGl2YXRlZCBkdXJpbmcgcGF0Y2guXG4gKiBUaGUgcXVldWUgd2lsbCBiZSBwcm9jZXNzZWQgYWZ0ZXIgdGhlIGVudGlyZSB0cmVlIGhhcyBiZWVuIHBhdGNoZWQuXG4gKi9cbmZ1bmN0aW9uIHF1ZXVlQWN0aXZhdGVkQ29tcG9uZW50ICh2bSkge1xuICAvLyBzZXR0aW5nIF9pbmFjdGl2ZSB0byBmYWxzZSBoZXJlIHNvIHRoYXQgYSByZW5kZXIgZnVuY3Rpb24gY2FuXG4gIC8vIHJlbHkgb24gY2hlY2tpbmcgd2hldGhlciBpdCdzIGluIGFuIGluYWN0aXZlIHRyZWUgKGUuZy4gcm91dGVyLXZpZXcpXG4gIHZtLl9pbmFjdGl2ZSA9IGZhbHNlO1xuICBhY3RpdmF0ZWRDaGlsZHJlbi5wdXNoKHZtKTtcbn1cblxuZnVuY3Rpb24gY2FsbEFjdGl2YXRlZEhvb2tzIChxdWV1ZSkge1xuICBmb3IgKHZhciBpID0gMDsgaSA8IHF1ZXVlLmxlbmd0aDsgaSsrKSB7XG4gICAgcXVldWVbaV0uX2luYWN0aXZlID0gdHJ1ZTtcbiAgICBhY3RpdmF0ZUNoaWxkQ29tcG9uZW50KHF1ZXVlW2ldLCB0cnVlIC8qIHRydWUgKi8pO1xuICB9XG59XG5cbi8qKlxuICogUHVzaCBhIHdhdGNoZXIgaW50byB0aGUgd2F0Y2hlciBxdWV1ZS5cbiAqIEpvYnMgd2l0aCBkdXBsaWNhdGUgSURzIHdpbGwgYmUgc2tpcHBlZCB1bmxlc3MgaXQnc1xuICogcHVzaGVkIHdoZW4gdGhlIHF1ZXVlIGlzIGJlaW5nIGZsdXNoZWQuXG4gKi9cbmZ1bmN0aW9uIHF1ZXVlV2F0Y2hlciAod2F0Y2hlcikge1xuICB2YXIgaWQgPSB3YXRjaGVyLmlkO1xuICBpZiAoaGFzW2lkXSA9PSBudWxsKSB7XG4gICAgaGFzW2lkXSA9IHRydWU7XG4gICAgaWYgKCFmbHVzaGluZykge1xuICAgICAgcXVldWUucHVzaCh3YXRjaGVyKTtcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gaWYgYWxyZWFkeSBmbHVzaGluZywgc3BsaWNlIHRoZSB3YXRjaGVyIGJhc2VkIG9uIGl0cyBpZFxuICAgICAgLy8gaWYgYWxyZWFkeSBwYXN0IGl0cyBpZCwgaXQgd2lsbCBiZSBydW4gbmV4dCBpbW1lZGlhdGVseS5cbiAgICAgIHZhciBpID0gcXVldWUubGVuZ3RoIC0gMTtcbiAgICAgIHdoaWxlIChpID4gaW5kZXggJiYgcXVldWVbaV0uaWQgPiB3YXRjaGVyLmlkKSB7XG4gICAgICAgIGktLTtcbiAgICAgIH1cbiAgICAgIHF1ZXVlLnNwbGljZShpICsgMSwgMCwgd2F0Y2hlcik7XG4gICAgfVxuICAgIC8vIHF1ZXVlIHRoZSBmbHVzaFxuICAgIGlmICghd2FpdGluZykge1xuICAgICAgd2FpdGluZyA9IHRydWU7XG4gICAgICBuZXh0VGljayhmbHVzaFNjaGVkdWxlclF1ZXVlKTtcbiAgICB9XG4gIH1cbn1cblxuLyogICovXG5cbnZhciB1aWQkMiA9IDA7XG5cbi8qKlxuICogQSB3YXRjaGVyIHBhcnNlcyBhbiBleHByZXNzaW9uLCBjb2xsZWN0cyBkZXBlbmRlbmNpZXMsXG4gKiBhbmQgZmlyZXMgY2FsbGJhY2sgd2hlbiB0aGUgZXhwcmVzc2lvbiB2YWx1ZSBjaGFuZ2VzLlxuICogVGhpcyBpcyB1c2VkIGZvciBib3RoIHRoZSAkd2F0Y2goKSBhcGkgYW5kIGRpcmVjdGl2ZXMuXG4gKi9cbnZhciBXYXRjaGVyID0gZnVuY3Rpb24gV2F0Y2hlciAoXG4gIHZtLFxuICBleHBPckZuLFxuICBjYixcbiAgb3B0aW9uc1xuKSB7XG4gIHRoaXMudm0gPSB2bTtcbiAgdm0uX3dhdGNoZXJzLnB1c2godGhpcyk7XG4gIC8vIG9wdGlvbnNcbiAgaWYgKG9wdGlvbnMpIHtcbiAgICB0aGlzLmRlZXAgPSAhIW9wdGlvbnMuZGVlcDtcbiAgICB0aGlzLnVzZXIgPSAhIW9wdGlvbnMudXNlcjtcbiAgICB0aGlzLmxhenkgPSAhIW9wdGlvbnMubGF6eTtcbiAgICB0aGlzLnN5bmMgPSAhIW9wdGlvbnMuc3luYztcbiAgfSBlbHNlIHtcbiAgICB0aGlzLmRlZXAgPSB0aGlzLnVzZXIgPSB0aGlzLmxhenkgPSB0aGlzLnN5bmMgPSBmYWxzZTtcbiAgfVxuICB0aGlzLmNiID0gY2I7XG4gIHRoaXMuaWQgPSArK3VpZCQyOyAvLyB1aWQgZm9yIGJhdGNoaW5nXG4gIHRoaXMuYWN0aXZlID0gdHJ1ZTtcbiAgdGhpcy5kaXJ0eSA9IHRoaXMubGF6eTsgLy8gZm9yIGxhenkgd2F0Y2hlcnNcbiAgdGhpcy5kZXBzID0gW107XG4gIHRoaXMubmV3RGVwcyA9IFtdO1xuICB0aGlzLmRlcElkcyA9IG5ldyBfU2V0KCk7XG4gIHRoaXMubmV3RGVwSWRzID0gbmV3IF9TZXQoKTtcbiAgdGhpcy5leHByZXNzaW9uID0gcHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJ1xuICAgID8gZXhwT3JGbi50b1N0cmluZygpXG4gICAgOiAnJztcbiAgLy8gcGFyc2UgZXhwcmVzc2lvbiBmb3IgZ2V0dGVyXG4gIGlmICh0eXBlb2YgZXhwT3JGbiA9PT0gJ2Z1bmN0aW9uJykge1xuICAgIHRoaXMuZ2V0dGVyID0gZXhwT3JGbjtcbiAgfSBlbHNlIHtcbiAgICB0aGlzLmdldHRlciA9IHBhcnNlUGF0aChleHBPckZuKTtcbiAgICBpZiAoIXRoaXMuZ2V0dGVyKSB7XG4gICAgICB0aGlzLmdldHRlciA9IGZ1bmN0aW9uICgpIHt9O1xuICAgICAgcHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJyAmJiB3YXJuKFxuICAgICAgICBcIkZhaWxlZCB3YXRjaGluZyBwYXRoOiBcXFwiXCIgKyBleHBPckZuICsgXCJcXFwiIFwiICtcbiAgICAgICAgJ1dhdGNoZXIgb25seSBhY2NlcHRzIHNpbXBsZSBkb3QtZGVsaW1pdGVkIHBhdGhzLiAnICtcbiAgICAgICAgJ0ZvciBmdWxsIGNvbnRyb2wsIHVzZSBhIGZ1bmN0aW9uIGluc3RlYWQuJyxcbiAgICAgICAgdm1cbiAgICAgICk7XG4gICAgfVxuICB9XG4gIHRoaXMudmFsdWUgPSB0aGlzLmxhenlcbiAgICA/IHVuZGVmaW5lZFxuICAgIDogdGhpcy5nZXQoKTtcbn07XG5cbi8qKlxuICogRXZhbHVhdGUgdGhlIGdldHRlciwgYW5kIHJlLWNvbGxlY3QgZGVwZW5kZW5jaWVzLlxuICovXG5XYXRjaGVyLnByb3RvdHlwZS5nZXQgPSBmdW5jdGlvbiBnZXQgKCkge1xuICBwdXNoVGFyZ2V0KHRoaXMpO1xuICB2YXIgdmFsdWU7XG4gIHZhciB2bSA9IHRoaXMudm07XG4gIHRyeSB7XG4gICAgdmFsdWUgPSB0aGlzLmdldHRlci5jYWxsKHZtLCB2bSk7XG4gIH0gY2F0Y2ggKGUpIHtcbiAgICBpZiAodGhpcy51c2VyKSB7XG4gICAgICBoYW5kbGVFcnJvcihlLCB2bSwgKFwiZ2V0dGVyIGZvciB3YXRjaGVyIFxcXCJcIiArICh0aGlzLmV4cHJlc3Npb24pICsgXCJcXFwiXCIpKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhyb3cgZVxuICAgIH1cbiAgfSBmaW5hbGx5IHtcbiAgICAvLyBcInRvdWNoXCIgZXZlcnkgcHJvcGVydHkgc28gdGhleSBhcmUgYWxsIHRyYWNrZWQgYXNcbiAgICAvLyBkZXBlbmRlbmNpZXMgZm9yIGRlZXAgd2F0Y2hpbmdcbiAgICBpZiAodGhpcy5kZWVwKSB7XG4gICAgICB0cmF2ZXJzZSh2YWx1ZSk7XG4gICAgfVxuICAgIHBvcFRhcmdldCgpO1xuICAgIHRoaXMuY2xlYW51cERlcHMoKTtcbiAgfVxuICByZXR1cm4gdmFsdWVcbn07XG5cbi8qKlxuICogQWRkIGEgZGVwZW5kZW5jeSB0byB0aGlzIGRpcmVjdGl2ZS5cbiAqL1xuV2F0Y2hlci5wcm90b3R5cGUuYWRkRGVwID0gZnVuY3Rpb24gYWRkRGVwIChkZXApIHtcbiAgdmFyIGlkID0gZGVwLmlkO1xuICBpZiAoIXRoaXMubmV3RGVwSWRzLmhhcyhpZCkpIHtcbiAgICB0aGlzLm5ld0RlcElkcy5hZGQoaWQpO1xuICAgIHRoaXMubmV3RGVwcy5wdXNoKGRlcCk7XG4gICAgaWYgKCF0aGlzLmRlcElkcy5oYXMoaWQpKSB7XG4gICAgICBkZXAuYWRkU3ViKHRoaXMpO1xuICAgIH1cbiAgfVxufTtcblxuLyoqXG4gKiBDbGVhbiB1cCBmb3IgZGVwZW5kZW5jeSBjb2xsZWN0aW9uLlxuICovXG5XYXRjaGVyLnByb3RvdHlwZS5jbGVhbnVwRGVwcyA9IGZ1bmN0aW9uIGNsZWFudXBEZXBzICgpIHtcbiAgICB2YXIgdGhpcyQxID0gdGhpcztcblxuICB2YXIgaSA9IHRoaXMuZGVwcy5sZW5ndGg7XG4gIHdoaWxlIChpLS0pIHtcbiAgICB2YXIgZGVwID0gdGhpcyQxLmRlcHNbaV07XG4gICAgaWYgKCF0aGlzJDEubmV3RGVwSWRzLmhhcyhkZXAuaWQpKSB7XG4gICAgICBkZXAucmVtb3ZlU3ViKHRoaXMkMSk7XG4gICAgfVxuICB9XG4gIHZhciB0bXAgPSB0aGlzLmRlcElkcztcbiAgdGhpcy5kZXBJZHMgPSB0aGlzLm5ld0RlcElkcztcbiAgdGhpcy5uZXdEZXBJZHMgPSB0bXA7XG4gIHRoaXMubmV3RGVwSWRzLmNsZWFyKCk7XG4gIHRtcCA9IHRoaXMuZGVwcztcbiAgdGhpcy5kZXBzID0gdGhpcy5uZXdEZXBzO1xuICB0aGlzLm5ld0RlcHMgPSB0bXA7XG4gIHRoaXMubmV3RGVwcy5sZW5ndGggPSAwO1xufTtcblxuLyoqXG4gKiBTdWJzY3JpYmVyIGludGVyZmFjZS5cbiAqIFdpbGwgYmUgY2FsbGVkIHdoZW4gYSBkZXBlbmRlbmN5IGNoYW5nZXMuXG4gKi9cbldhdGNoZXIucHJvdG90eXBlLnVwZGF0ZSA9IGZ1bmN0aW9uIHVwZGF0ZSAoKSB7XG4gIC8qIGlzdGFuYnVsIGlnbm9yZSBlbHNlICovXG4gIGlmICh0aGlzLmxhenkpIHtcbiAgICB0aGlzLmRpcnR5ID0gdHJ1ZTtcbiAgfSBlbHNlIGlmICh0aGlzLnN5bmMpIHtcbiAgICB0aGlzLnJ1bigpO1xuICB9IGVsc2Uge1xuICAgIHF1ZXVlV2F0Y2hlcih0aGlzKTtcbiAgfVxufTtcblxuLyoqXG4gKiBTY2hlZHVsZXIgam9iIGludGVyZmFjZS5cbiAqIFdpbGwgYmUgY2FsbGVkIGJ5IHRoZSBzY2hlZHVsZXIuXG4gKi9cbldhdGNoZXIucHJvdG90eXBlLnJ1biA9IGZ1bmN0aW9uIHJ1biAoKSB7XG4gIGlmICh0aGlzLmFjdGl2ZSkge1xuICAgIHZhciB2YWx1ZSA9IHRoaXMuZ2V0KCk7XG4gICAgaWYgKFxuICAgICAgdmFsdWUgIT09IHRoaXMudmFsdWUgfHxcbiAgICAgIC8vIERlZXAgd2F0Y2hlcnMgYW5kIHdhdGNoZXJzIG9uIE9iamVjdC9BcnJheXMgc2hvdWxkIGZpcmUgZXZlblxuICAgICAgLy8gd2hlbiB0aGUgdmFsdWUgaXMgdGhlIHNhbWUsIGJlY2F1c2UgdGhlIHZhbHVlIG1heVxuICAgICAgLy8gaGF2ZSBtdXRhdGVkLlxuICAgICAgaXNPYmplY3QodmFsdWUpIHx8XG4gICAgICB0aGlzLmRlZXBcbiAgICApIHtcbiAgICAgIC8vIHNldCBuZXcgdmFsdWVcbiAgICAgIHZhciBvbGRWYWx1ZSA9IHRoaXMudmFsdWU7XG4gICAgICB0aGlzLnZhbHVlID0gdmFsdWU7XG4gICAgICBpZiAodGhpcy51c2VyKSB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgdGhpcy5jYi5jYWxsKHRoaXMudm0sIHZhbHVlLCBvbGRWYWx1ZSk7XG4gICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICBoYW5kbGVFcnJvcihlLCB0aGlzLnZtLCAoXCJjYWxsYmFjayBmb3Igd2F0Y2hlciBcXFwiXCIgKyAodGhpcy5leHByZXNzaW9uKSArIFwiXFxcIlwiKSk7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMuY2IuY2FsbCh0aGlzLnZtLCB2YWx1ZSwgb2xkVmFsdWUpO1xuICAgICAgfVxuICAgIH1cbiAgfVxufTtcblxuLyoqXG4gKiBFdmFsdWF0ZSB0aGUgdmFsdWUgb2YgdGhlIHdhdGNoZXIuXG4gKiBUaGlzIG9ubHkgZ2V0cyBjYWxsZWQgZm9yIGxhenkgd2F0Y2hlcnMuXG4gKi9cbldhdGNoZXIucHJvdG90eXBlLmV2YWx1YXRlID0gZnVuY3Rpb24gZXZhbHVhdGUgKCkge1xuICB0aGlzLnZhbHVlID0gdGhpcy5nZXQoKTtcbiAgdGhpcy5kaXJ0eSA9IGZhbHNlO1xufTtcblxuLyoqXG4gKiBEZXBlbmQgb24gYWxsIGRlcHMgY29sbGVjdGVkIGJ5IHRoaXMgd2F0Y2hlci5cbiAqL1xuV2F0Y2hlci5wcm90b3R5cGUuZGVwZW5kID0gZnVuY3Rpb24gZGVwZW5kICgpIHtcbiAgICB2YXIgdGhpcyQxID0gdGhpcztcblxuICB2YXIgaSA9IHRoaXMuZGVwcy5sZW5ndGg7XG4gIHdoaWxlIChpLS0pIHtcbiAgICB0aGlzJDEuZGVwc1tpXS5kZXBlbmQoKTtcbiAgfVxufTtcblxuLyoqXG4gKiBSZW1vdmUgc2VsZiBmcm9tIGFsbCBkZXBlbmRlbmNpZXMnIHN1YnNjcmliZXIgbGlzdC5cbiAqL1xuV2F0Y2hlci5wcm90b3R5cGUudGVhcmRvd24gPSBmdW5jdGlvbiB0ZWFyZG93biAoKSB7XG4gICAgdmFyIHRoaXMkMSA9IHRoaXM7XG5cbiAgaWYgKHRoaXMuYWN0aXZlKSB7XG4gICAgLy8gcmVtb3ZlIHNlbGYgZnJvbSB2bSdzIHdhdGNoZXIgbGlzdFxuICAgIC8vIHRoaXMgaXMgYSBzb21ld2hhdCBleHBlbnNpdmUgb3BlcmF0aW9uIHNvIHdlIHNraXAgaXRcbiAgICAvLyBpZiB0aGUgdm0gaXMgYmVpbmcgZGVzdHJveWVkLlxuICAgIGlmICghdGhpcy52bS5faXNCZWluZ0Rlc3Ryb3llZCkge1xuICAgICAgcmVtb3ZlKHRoaXMudm0uX3dhdGNoZXJzLCB0aGlzKTtcbiAgICB9XG4gICAgdmFyIGkgPSB0aGlzLmRlcHMubGVuZ3RoO1xuICAgIHdoaWxlIChpLS0pIHtcbiAgICAgIHRoaXMkMS5kZXBzW2ldLnJlbW92ZVN1Yih0aGlzJDEpO1xuICAgIH1cbiAgICB0aGlzLmFjdGl2ZSA9IGZhbHNlO1xuICB9XG59O1xuXG4vKipcbiAqIFJlY3Vyc2l2ZWx5IHRyYXZlcnNlIGFuIG9iamVjdCB0byBldm9rZSBhbGwgY29udmVydGVkXG4gKiBnZXR0ZXJzLCBzbyB0aGF0IGV2ZXJ5IG5lc3RlZCBwcm9wZXJ0eSBpbnNpZGUgdGhlIG9iamVjdFxuICogaXMgY29sbGVjdGVkIGFzIGEgXCJkZWVwXCIgZGVwZW5kZW5jeS5cbiAqL1xudmFyIHNlZW5PYmplY3RzID0gbmV3IF9TZXQoKTtcbmZ1bmN0aW9uIHRyYXZlcnNlICh2YWwpIHtcbiAgc2Vlbk9iamVjdHMuY2xlYXIoKTtcbiAgX3RyYXZlcnNlKHZhbCwgc2Vlbk9iamVjdHMpO1xufVxuXG5mdW5jdGlvbiBfdHJhdmVyc2UgKHZhbCwgc2Vlbikge1xuICB2YXIgaSwga2V5cztcbiAgdmFyIGlzQSA9IEFycmF5LmlzQXJyYXkodmFsKTtcbiAgaWYgKCghaXNBICYmICFpc09iamVjdCh2YWwpKSB8fCAhT2JqZWN0LmlzRXh0ZW5zaWJsZSh2YWwpKSB7XG4gICAgcmV0dXJuXG4gIH1cbiAgaWYgKHZhbC5fX29iX18pIHtcbiAgICB2YXIgZGVwSWQgPSB2YWwuX19vYl9fLmRlcC5pZDtcbiAgICBpZiAoc2Vlbi5oYXMoZGVwSWQpKSB7XG4gICAgICByZXR1cm5cbiAgICB9XG4gICAgc2Vlbi5hZGQoZGVwSWQpO1xuICB9XG4gIGlmIChpc0EpIHtcbiAgICBpID0gdmFsLmxlbmd0aDtcbiAgICB3aGlsZSAoaS0tKSB7IF90cmF2ZXJzZSh2YWxbaV0sIHNlZW4pOyB9XG4gIH0gZWxzZSB7XG4gICAga2V5cyA9IE9iamVjdC5rZXlzKHZhbCk7XG4gICAgaSA9IGtleXMubGVuZ3RoO1xuICAgIHdoaWxlIChpLS0pIHsgX3RyYXZlcnNlKHZhbFtrZXlzW2ldXSwgc2Vlbik7IH1cbiAgfVxufVxuXG4vKiAgKi9cblxudmFyIHNoYXJlZFByb3BlcnR5RGVmaW5pdGlvbiA9IHtcbiAgZW51bWVyYWJsZTogdHJ1ZSxcbiAgY29uZmlndXJhYmxlOiB0cnVlLFxuICBnZXQ6IG5vb3AsXG4gIHNldDogbm9vcFxufTtcblxuZnVuY3Rpb24gcHJveHkgKHRhcmdldCwgc291cmNlS2V5LCBrZXkpIHtcbiAgc2hhcmVkUHJvcGVydHlEZWZpbml0aW9uLmdldCA9IGZ1bmN0aW9uIHByb3h5R2V0dGVyICgpIHtcbiAgICByZXR1cm4gdGhpc1tzb3VyY2VLZXldW2tleV1cbiAgfTtcbiAgc2hhcmVkUHJvcGVydHlEZWZpbml0aW9uLnNldCA9IGZ1bmN0aW9uIHByb3h5U2V0dGVyICh2YWwpIHtcbiAgICB0aGlzW3NvdXJjZUtleV1ba2V5XSA9IHZhbDtcbiAgfTtcbiAgT2JqZWN0LmRlZmluZVByb3BlcnR5KHRhcmdldCwga2V5LCBzaGFyZWRQcm9wZXJ0eURlZmluaXRpb24pO1xufVxuXG5mdW5jdGlvbiBpbml0U3RhdGUgKHZtKSB7XG4gIHZtLl93YXRjaGVycyA9IFtdO1xuICB2YXIgb3B0cyA9IHZtLiRvcHRpb25zO1xuICBpZiAob3B0cy5wcm9wcykgeyBpbml0UHJvcHModm0sIG9wdHMucHJvcHMpOyB9XG4gIGlmIChvcHRzLm1ldGhvZHMpIHsgaW5pdE1ldGhvZHModm0sIG9wdHMubWV0aG9kcyk7IH1cbiAgaWYgKG9wdHMuZGF0YSkge1xuICAgIGluaXREYXRhKHZtKTtcbiAgfSBlbHNlIHtcbiAgICBvYnNlcnZlKHZtLl9kYXRhID0ge30sIHRydWUgLyogYXNSb290RGF0YSAqLyk7XG4gIH1cbiAgaWYgKG9wdHMuY29tcHV0ZWQpIHsgaW5pdENvbXB1dGVkKHZtLCBvcHRzLmNvbXB1dGVkKTsgfVxuICBpZiAob3B0cy53YXRjaCAmJiBvcHRzLndhdGNoICE9PSBuYXRpdmVXYXRjaCkge1xuICAgIGluaXRXYXRjaCh2bSwgb3B0cy53YXRjaCk7XG4gIH1cbn1cblxuZnVuY3Rpb24gY2hlY2tPcHRpb25UeXBlICh2bSwgbmFtZSkge1xuICB2YXIgb3B0aW9uID0gdm0uJG9wdGlvbnNbbmFtZV07XG4gIGlmICghaXNQbGFpbk9iamVjdChvcHRpb24pKSB7XG4gICAgd2FybihcbiAgICAgIChcImNvbXBvbmVudCBvcHRpb24gXFxcIlwiICsgbmFtZSArIFwiXFxcIiBzaG91bGQgYmUgYW4gb2JqZWN0LlwiKSxcbiAgICAgIHZtXG4gICAgKTtcbiAgfVxufVxuXG5mdW5jdGlvbiBpbml0UHJvcHMgKHZtLCBwcm9wc09wdGlvbnMpIHtcbiAgdmFyIHByb3BzRGF0YSA9IHZtLiRvcHRpb25zLnByb3BzRGF0YSB8fCB7fTtcbiAgdmFyIHByb3BzID0gdm0uX3Byb3BzID0ge307XG4gIC8vIGNhY2hlIHByb3Aga2V5cyBzbyB0aGF0IGZ1dHVyZSBwcm9wcyB1cGRhdGVzIGNhbiBpdGVyYXRlIHVzaW5nIEFycmF5XG4gIC8vIGluc3RlYWQgb2YgZHluYW1pYyBvYmplY3Qga2V5IGVudW1lcmF0aW9uLlxuICB2YXIga2V5cyA9IHZtLiRvcHRpb25zLl9wcm9wS2V5cyA9IFtdO1xuICB2YXIgaXNSb290ID0gIXZtLiRwYXJlbnQ7XG4gIC8vIHJvb3QgaW5zdGFuY2UgcHJvcHMgc2hvdWxkIGJlIGNvbnZlcnRlZFxuICBvYnNlcnZlclN0YXRlLnNob3VsZENvbnZlcnQgPSBpc1Jvb3Q7XG4gIHZhciBsb29wID0gZnVuY3Rpb24gKCBrZXkgKSB7XG4gICAga2V5cy5wdXNoKGtleSk7XG4gICAgdmFyIHZhbHVlID0gdmFsaWRhdGVQcm9wKGtleSwgcHJvcHNPcHRpb25zLCBwcm9wc0RhdGEsIHZtKTtcbiAgICAvKiBpc3RhbmJ1bCBpZ25vcmUgZWxzZSAqL1xuICAgIGlmIChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nKSB7XG4gICAgICBpZiAoaXNSZXNlcnZlZEF0dHJpYnV0ZShrZXkpIHx8IGNvbmZpZy5pc1Jlc2VydmVkQXR0cihrZXkpKSB7XG4gICAgICAgIHdhcm4oXG4gICAgICAgICAgKFwiXFxcIlwiICsga2V5ICsgXCJcXFwiIGlzIGEgcmVzZXJ2ZWQgYXR0cmlidXRlIGFuZCBjYW5ub3QgYmUgdXNlZCBhcyBjb21wb25lbnQgcHJvcC5cIiksXG4gICAgICAgICAgdm1cbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICAgIGRlZmluZVJlYWN0aXZlJCQxKHByb3BzLCBrZXksIHZhbHVlLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGlmICh2bS4kcGFyZW50ICYmICFpc1VwZGF0aW5nQ2hpbGRDb21wb25lbnQpIHtcbiAgICAgICAgICB3YXJuKFxuICAgICAgICAgICAgXCJBdm9pZCBtdXRhdGluZyBhIHByb3AgZGlyZWN0bHkgc2luY2UgdGhlIHZhbHVlIHdpbGwgYmUgXCIgK1xuICAgICAgICAgICAgXCJvdmVyd3JpdHRlbiB3aGVuZXZlciB0aGUgcGFyZW50IGNvbXBvbmVudCByZS1yZW5kZXJzLiBcIiArXG4gICAgICAgICAgICBcIkluc3RlYWQsIHVzZSBhIGRhdGEgb3IgY29tcHV0ZWQgcHJvcGVydHkgYmFzZWQgb24gdGhlIHByb3AncyBcIiArXG4gICAgICAgICAgICBcInZhbHVlLiBQcm9wIGJlaW5nIG11dGF0ZWQ6IFxcXCJcIiArIGtleSArIFwiXFxcIlwiLFxuICAgICAgICAgICAgdm1cbiAgICAgICAgICApO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICB9IGVsc2Uge1xuICAgICAgZGVmaW5lUmVhY3RpdmUkJDEocHJvcHMsIGtleSwgdmFsdWUpO1xuICAgIH1cbiAgICAvLyBzdGF0aWMgcHJvcHMgYXJlIGFscmVhZHkgcHJveGllZCBvbiB0aGUgY29tcG9uZW50J3MgcHJvdG90eXBlXG4gICAgLy8gZHVyaW5nIFZ1ZS5leHRlbmQoKS4gV2Ugb25seSBuZWVkIHRvIHByb3h5IHByb3BzIGRlZmluZWQgYXRcbiAgICAvLyBpbnN0YW50aWF0aW9uIGhlcmUuXG4gICAgaWYgKCEoa2V5IGluIHZtKSkge1xuICAgICAgcHJveHkodm0sIFwiX3Byb3BzXCIsIGtleSk7XG4gICAgfVxuICB9O1xuXG4gIGZvciAodmFyIGtleSBpbiBwcm9wc09wdGlvbnMpIGxvb3AoIGtleSApO1xuICBvYnNlcnZlclN0YXRlLnNob3VsZENvbnZlcnQgPSB0cnVlO1xufVxuXG5mdW5jdGlvbiBpbml0RGF0YSAodm0pIHtcbiAgdmFyIGRhdGEgPSB2bS4kb3B0aW9ucy5kYXRhO1xuICBkYXRhID0gdm0uX2RhdGEgPSB0eXBlb2YgZGF0YSA9PT0gJ2Z1bmN0aW9uJ1xuICAgID8gZ2V0RGF0YShkYXRhLCB2bSlcbiAgICA6IGRhdGEgfHwge307XG4gIGlmICghaXNQbGFpbk9iamVjdChkYXRhKSkge1xuICAgIGRhdGEgPSB7fTtcbiAgICBwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nICYmIHdhcm4oXG4gICAgICAnZGF0YSBmdW5jdGlvbnMgc2hvdWxkIHJldHVybiBhbiBvYmplY3Q6XFxuJyArXG4gICAgICAnaHR0cHM6Ly92dWVqcy5vcmcvdjIvZ3VpZGUvY29tcG9uZW50cy5odG1sI2RhdGEtTXVzdC1CZS1hLUZ1bmN0aW9uJyxcbiAgICAgIHZtXG4gICAgKTtcbiAgfVxuICAvLyBwcm94eSBkYXRhIG9uIGluc3RhbmNlXG4gIHZhciBrZXlzID0gT2JqZWN0LmtleXMoZGF0YSk7XG4gIHZhciBwcm9wcyA9IHZtLiRvcHRpb25zLnByb3BzO1xuICB2YXIgbWV0aG9kcyA9IHZtLiRvcHRpb25zLm1ldGhvZHM7XG4gIHZhciBpID0ga2V5cy5sZW5ndGg7XG4gIHdoaWxlIChpLS0pIHtcbiAgICB2YXIga2V5ID0ga2V5c1tpXTtcbiAgICBpZiAocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJykge1xuICAgICAgaWYgKG1ldGhvZHMgJiYgaGFzT3duKG1ldGhvZHMsIGtleSkpIHtcbiAgICAgICAgd2FybihcbiAgICAgICAgICAoXCJNZXRob2QgXFxcIlwiICsga2V5ICsgXCJcXFwiIGhhcyBhbHJlYWR5IGJlZW4gZGVmaW5lZCBhcyBhIGRhdGEgcHJvcGVydHkuXCIpLFxuICAgICAgICAgIHZtXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgfVxuICAgIGlmIChwcm9wcyAmJiBoYXNPd24ocHJvcHMsIGtleSkpIHtcbiAgICAgIHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicgJiYgd2FybihcbiAgICAgICAgXCJUaGUgZGF0YSBwcm9wZXJ0eSBcXFwiXCIgKyBrZXkgKyBcIlxcXCIgaXMgYWxyZWFkeSBkZWNsYXJlZCBhcyBhIHByb3AuIFwiICtcbiAgICAgICAgXCJVc2UgcHJvcCBkZWZhdWx0IHZhbHVlIGluc3RlYWQuXCIsXG4gICAgICAgIHZtXG4gICAgICApO1xuICAgIH0gZWxzZSBpZiAoIWlzUmVzZXJ2ZWQoa2V5KSkge1xuICAgICAgcHJveHkodm0sIFwiX2RhdGFcIiwga2V5KTtcbiAgICB9XG4gIH1cbiAgLy8gb2JzZXJ2ZSBkYXRhXG4gIG9ic2VydmUoZGF0YSwgdHJ1ZSAvKiBhc1Jvb3REYXRhICovKTtcbn1cblxuZnVuY3Rpb24gZ2V0RGF0YSAoZGF0YSwgdm0pIHtcbiAgdHJ5IHtcbiAgICByZXR1cm4gZGF0YS5jYWxsKHZtKVxuICB9IGNhdGNoIChlKSB7XG4gICAgaGFuZGxlRXJyb3IoZSwgdm0sIFwiZGF0YSgpXCIpO1xuICAgIHJldHVybiB7fVxuICB9XG59XG5cbnZhciBjb21wdXRlZFdhdGNoZXJPcHRpb25zID0geyBsYXp5OiB0cnVlIH07XG5cbmZ1bmN0aW9uIGluaXRDb21wdXRlZCAodm0sIGNvbXB1dGVkKSB7XG4gIHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicgJiYgY2hlY2tPcHRpb25UeXBlKHZtLCAnY29tcHV0ZWQnKTtcbiAgdmFyIHdhdGNoZXJzID0gdm0uX2NvbXB1dGVkV2F0Y2hlcnMgPSBPYmplY3QuY3JlYXRlKG51bGwpO1xuICAvLyBjb21wdXRlZCBwcm9wZXJ0aWVzIGFyZSBqdXN0IGdldHRlcnMgZHVyaW5nIFNTUlxuICB2YXIgaXNTU1IgPSBpc1NlcnZlclJlbmRlcmluZygpO1xuXG4gIGZvciAodmFyIGtleSBpbiBjb21wdXRlZCkge1xuICAgIHZhciB1c2VyRGVmID0gY29tcHV0ZWRba2V5XTtcbiAgICB2YXIgZ2V0dGVyID0gdHlwZW9mIHVzZXJEZWYgPT09ICdmdW5jdGlvbicgPyB1c2VyRGVmIDogdXNlckRlZi5nZXQ7XG4gICAgaWYgKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicgJiYgZ2V0dGVyID09IG51bGwpIHtcbiAgICAgIHdhcm4oXG4gICAgICAgIChcIkdldHRlciBpcyBtaXNzaW5nIGZvciBjb21wdXRlZCBwcm9wZXJ0eSBcXFwiXCIgKyBrZXkgKyBcIlxcXCIuXCIpLFxuICAgICAgICB2bVxuICAgICAgKTtcbiAgICB9XG5cbiAgICBpZiAoIWlzU1NSKSB7XG4gICAgICAvLyBjcmVhdGUgaW50ZXJuYWwgd2F0Y2hlciBmb3IgdGhlIGNvbXB1dGVkIHByb3BlcnR5LlxuICAgICAgd2F0Y2hlcnNba2V5XSA9IG5ldyBXYXRjaGVyKFxuICAgICAgICB2bSxcbiAgICAgICAgZ2V0dGVyIHx8IG5vb3AsXG4gICAgICAgIG5vb3AsXG4gICAgICAgIGNvbXB1dGVkV2F0Y2hlck9wdGlvbnNcbiAgICAgICk7XG4gICAgfVxuXG4gICAgLy8gY29tcG9uZW50LWRlZmluZWQgY29tcHV0ZWQgcHJvcGVydGllcyBhcmUgYWxyZWFkeSBkZWZpbmVkIG9uIHRoZVxuICAgIC8vIGNvbXBvbmVudCBwcm90b3R5cGUuIFdlIG9ubHkgbmVlZCB0byBkZWZpbmUgY29tcHV0ZWQgcHJvcGVydGllcyBkZWZpbmVkXG4gICAgLy8gYXQgaW5zdGFudGlhdGlvbiBoZXJlLlxuICAgIGlmICghKGtleSBpbiB2bSkpIHtcbiAgICAgIGRlZmluZUNvbXB1dGVkKHZtLCBrZXksIHVzZXJEZWYpO1xuICAgIH0gZWxzZSBpZiAocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJykge1xuICAgICAgaWYgKGtleSBpbiB2bS4kZGF0YSkge1xuICAgICAgICB3YXJuKChcIlRoZSBjb21wdXRlZCBwcm9wZXJ0eSBcXFwiXCIgKyBrZXkgKyBcIlxcXCIgaXMgYWxyZWFkeSBkZWZpbmVkIGluIGRhdGEuXCIpLCB2bSk7XG4gICAgICB9IGVsc2UgaWYgKHZtLiRvcHRpb25zLnByb3BzICYmIGtleSBpbiB2bS4kb3B0aW9ucy5wcm9wcykge1xuICAgICAgICB3YXJuKChcIlRoZSBjb21wdXRlZCBwcm9wZXJ0eSBcXFwiXCIgKyBrZXkgKyBcIlxcXCIgaXMgYWxyZWFkeSBkZWZpbmVkIGFzIGEgcHJvcC5cIiksIHZtKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cbn1cblxuZnVuY3Rpb24gZGVmaW5lQ29tcHV0ZWQgKFxuICB0YXJnZXQsXG4gIGtleSxcbiAgdXNlckRlZlxuKSB7XG4gIHZhciBzaG91bGRDYWNoZSA9ICFpc1NlcnZlclJlbmRlcmluZygpO1xuICBpZiAodHlwZW9mIHVzZXJEZWYgPT09ICdmdW5jdGlvbicpIHtcbiAgICBzaGFyZWRQcm9wZXJ0eURlZmluaXRpb24uZ2V0ID0gc2hvdWxkQ2FjaGVcbiAgICAgID8gY3JlYXRlQ29tcHV0ZWRHZXR0ZXIoa2V5KVxuICAgICAgOiB1c2VyRGVmO1xuICAgIHNoYXJlZFByb3BlcnR5RGVmaW5pdGlvbi5zZXQgPSBub29wO1xuICB9IGVsc2Uge1xuICAgIHNoYXJlZFByb3BlcnR5RGVmaW5pdGlvbi5nZXQgPSB1c2VyRGVmLmdldFxuICAgICAgPyBzaG91bGRDYWNoZSAmJiB1c2VyRGVmLmNhY2hlICE9PSBmYWxzZVxuICAgICAgICA/IGNyZWF0ZUNvbXB1dGVkR2V0dGVyKGtleSlcbiAgICAgICAgOiB1c2VyRGVmLmdldFxuICAgICAgOiBub29wO1xuICAgIHNoYXJlZFByb3BlcnR5RGVmaW5pdGlvbi5zZXQgPSB1c2VyRGVmLnNldFxuICAgICAgPyB1c2VyRGVmLnNldFxuICAgICAgOiBub29wO1xuICB9XG4gIGlmIChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nICYmXG4gICAgICBzaGFyZWRQcm9wZXJ0eURlZmluaXRpb24uc2V0ID09PSBub29wKSB7XG4gICAgc2hhcmVkUHJvcGVydHlEZWZpbml0aW9uLnNldCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgIHdhcm4oXG4gICAgICAgIChcIkNvbXB1dGVkIHByb3BlcnR5IFxcXCJcIiArIGtleSArIFwiXFxcIiB3YXMgYXNzaWduZWQgdG8gYnV0IGl0IGhhcyBubyBzZXR0ZXIuXCIpLFxuICAgICAgICB0aGlzXG4gICAgICApO1xuICAgIH07XG4gIH1cbiAgT2JqZWN0LmRlZmluZVByb3BlcnR5KHRhcmdldCwga2V5LCBzaGFyZWRQcm9wZXJ0eURlZmluaXRpb24pO1xufVxuXG5mdW5jdGlvbiBjcmVhdGVDb21wdXRlZEdldHRlciAoa2V5KSB7XG4gIHJldHVybiBmdW5jdGlvbiBjb21wdXRlZEdldHRlciAoKSB7XG4gICAgdmFyIHdhdGNoZXIgPSB0aGlzLl9jb21wdXRlZFdhdGNoZXJzICYmIHRoaXMuX2NvbXB1dGVkV2F0Y2hlcnNba2V5XTtcbiAgICBpZiAod2F0Y2hlcikge1xuICAgICAgaWYgKHdhdGNoZXIuZGlydHkpIHtcbiAgICAgICAgd2F0Y2hlci5ldmFsdWF0ZSgpO1xuICAgICAgfVxuICAgICAgaWYgKERlcC50YXJnZXQpIHtcbiAgICAgICAgd2F0Y2hlci5kZXBlbmQoKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiB3YXRjaGVyLnZhbHVlXG4gICAgfVxuICB9XG59XG5cbmZ1bmN0aW9uIGluaXRNZXRob2RzICh2bSwgbWV0aG9kcykge1xuICBwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nICYmIGNoZWNrT3B0aW9uVHlwZSh2bSwgJ21ldGhvZHMnKTtcbiAgdmFyIHByb3BzID0gdm0uJG9wdGlvbnMucHJvcHM7XG4gIGZvciAodmFyIGtleSBpbiBtZXRob2RzKSB7XG4gICAgaWYgKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicpIHtcbiAgICAgIGlmIChtZXRob2RzW2tleV0gPT0gbnVsbCkge1xuICAgICAgICB3YXJuKFxuICAgICAgICAgIFwiTWV0aG9kIFxcXCJcIiArIGtleSArIFwiXFxcIiBoYXMgYW4gdW5kZWZpbmVkIHZhbHVlIGluIHRoZSBjb21wb25lbnQgZGVmaW5pdGlvbi4gXCIgK1xuICAgICAgICAgIFwiRGlkIHlvdSByZWZlcmVuY2UgdGhlIGZ1bmN0aW9uIGNvcnJlY3RseT9cIixcbiAgICAgICAgICB2bVxuICAgICAgICApO1xuICAgICAgfVxuICAgICAgaWYgKHByb3BzICYmIGhhc093bihwcm9wcywga2V5KSkge1xuICAgICAgICB3YXJuKFxuICAgICAgICAgIChcIk1ldGhvZCBcXFwiXCIgKyBrZXkgKyBcIlxcXCIgaGFzIGFscmVhZHkgYmVlbiBkZWZpbmVkIGFzIGEgcHJvcC5cIiksXG4gICAgICAgICAgdm1cbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICAgIGlmICgoa2V5IGluIHZtKSAmJiBpc1Jlc2VydmVkKGtleSkpIHtcbiAgICAgICAgd2FybihcbiAgICAgICAgICBcIk1ldGhvZCBcXFwiXCIgKyBrZXkgKyBcIlxcXCIgY29uZmxpY3RzIHdpdGggYW4gZXhpc3RpbmcgVnVlIGluc3RhbmNlIG1ldGhvZC4gXCIgK1xuICAgICAgICAgIFwiQXZvaWQgZGVmaW5pbmcgY29tcG9uZW50IG1ldGhvZHMgdGhhdCBzdGFydCB3aXRoIF8gb3IgJC5cIlxuICAgICAgICApO1xuICAgICAgfVxuICAgIH1cbiAgICB2bVtrZXldID0gbWV0aG9kc1trZXldID09IG51bGwgPyBub29wIDogYmluZChtZXRob2RzW2tleV0sIHZtKTtcbiAgfVxufVxuXG5mdW5jdGlvbiBpbml0V2F0Y2ggKHZtLCB3YXRjaCkge1xuICBwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nICYmIGNoZWNrT3B0aW9uVHlwZSh2bSwgJ3dhdGNoJyk7XG4gIGZvciAodmFyIGtleSBpbiB3YXRjaCkge1xuICAgIHZhciBoYW5kbGVyID0gd2F0Y2hba2V5XTtcbiAgICBpZiAoQXJyYXkuaXNBcnJheShoYW5kbGVyKSkge1xuICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBoYW5kbGVyLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIGNyZWF0ZVdhdGNoZXIodm0sIGtleSwgaGFuZGxlcltpXSk7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIGNyZWF0ZVdhdGNoZXIodm0sIGtleSwgaGFuZGxlcik7XG4gICAgfVxuICB9XG59XG5cbmZ1bmN0aW9uIGNyZWF0ZVdhdGNoZXIgKFxuICB2bSxcbiAga2V5T3JGbixcbiAgaGFuZGxlcixcbiAgb3B0aW9uc1xuKSB7XG4gIGlmIChpc1BsYWluT2JqZWN0KGhhbmRsZXIpKSB7XG4gICAgb3B0aW9ucyA9IGhhbmRsZXI7XG4gICAgaGFuZGxlciA9IGhhbmRsZXIuaGFuZGxlcjtcbiAgfVxuICBpZiAodHlwZW9mIGhhbmRsZXIgPT09ICdzdHJpbmcnKSB7XG4gICAgaGFuZGxlciA9IHZtW2hhbmRsZXJdO1xuICB9XG4gIHJldHVybiB2bS4kd2F0Y2goa2V5T3JGbiwgaGFuZGxlciwgb3B0aW9ucylcbn1cblxuZnVuY3Rpb24gc3RhdGVNaXhpbiAoVnVlKSB7XG4gIC8vIGZsb3cgc29tZWhvdyBoYXMgcHJvYmxlbXMgd2l0aCBkaXJlY3RseSBkZWNsYXJlZCBkZWZpbml0aW9uIG9iamVjdFxuICAvLyB3aGVuIHVzaW5nIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSwgc28gd2UgaGF2ZSB0byBwcm9jZWR1cmFsbHkgYnVpbGQgdXBcbiAgLy8gdGhlIG9iamVjdCBoZXJlLlxuICB2YXIgZGF0YURlZiA9IHt9O1xuICBkYXRhRGVmLmdldCA9IGZ1bmN0aW9uICgpIHsgcmV0dXJuIHRoaXMuX2RhdGEgfTtcbiAgdmFyIHByb3BzRGVmID0ge307XG4gIHByb3BzRGVmLmdldCA9IGZ1bmN0aW9uICgpIHsgcmV0dXJuIHRoaXMuX3Byb3BzIH07XG4gIGlmIChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nKSB7XG4gICAgZGF0YURlZi5zZXQgPSBmdW5jdGlvbiAobmV3RGF0YSkge1xuICAgICAgd2FybihcbiAgICAgICAgJ0F2b2lkIHJlcGxhY2luZyBpbnN0YW5jZSByb290ICRkYXRhLiAnICtcbiAgICAgICAgJ1VzZSBuZXN0ZWQgZGF0YSBwcm9wZXJ0aWVzIGluc3RlYWQuJyxcbiAgICAgICAgdGhpc1xuICAgICAgKTtcbiAgICB9O1xuICAgIHByb3BzRGVmLnNldCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgIHdhcm4oXCIkcHJvcHMgaXMgcmVhZG9ubHkuXCIsIHRoaXMpO1xuICAgIH07XG4gIH1cbiAgT2JqZWN0LmRlZmluZVByb3BlcnR5KFZ1ZS5wcm90b3R5cGUsICckZGF0YScsIGRhdGFEZWYpO1xuICBPYmplY3QuZGVmaW5lUHJvcGVydHkoVnVlLnByb3RvdHlwZSwgJyRwcm9wcycsIHByb3BzRGVmKTtcblxuICBWdWUucHJvdG90eXBlLiRzZXQgPSBzZXQ7XG4gIFZ1ZS5wcm90b3R5cGUuJGRlbGV0ZSA9IGRlbDtcblxuICBWdWUucHJvdG90eXBlLiR3YXRjaCA9IGZ1bmN0aW9uIChcbiAgICBleHBPckZuLFxuICAgIGNiLFxuICAgIG9wdGlvbnNcbiAgKSB7XG4gICAgdmFyIHZtID0gdGhpcztcbiAgICBpZiAoaXNQbGFpbk9iamVjdChjYikpIHtcbiAgICAgIHJldHVybiBjcmVhdGVXYXRjaGVyKHZtLCBleHBPckZuLCBjYiwgb3B0aW9ucylcbiAgICB9XG4gICAgb3B0aW9ucyA9IG9wdGlvbnMgfHwge307XG4gICAgb3B0aW9ucy51c2VyID0gdHJ1ZTtcbiAgICB2YXIgd2F0Y2hlciA9IG5ldyBXYXRjaGVyKHZtLCBleHBPckZuLCBjYiwgb3B0aW9ucyk7XG4gICAgaWYgKG9wdGlvbnMuaW1tZWRpYXRlKSB7XG4gICAgICBjYi5jYWxsKHZtLCB3YXRjaGVyLnZhbHVlKTtcbiAgICB9XG4gICAgcmV0dXJuIGZ1bmN0aW9uIHVud2F0Y2hGbiAoKSB7XG4gICAgICB3YXRjaGVyLnRlYXJkb3duKCk7XG4gICAgfVxuICB9O1xufVxuXG4vKiAgKi9cblxuZnVuY3Rpb24gaW5pdFByb3ZpZGUgKHZtKSB7XG4gIHZhciBwcm92aWRlID0gdm0uJG9wdGlvbnMucHJvdmlkZTtcbiAgaWYgKHByb3ZpZGUpIHtcbiAgICB2bS5fcHJvdmlkZWQgPSB0eXBlb2YgcHJvdmlkZSA9PT0gJ2Z1bmN0aW9uJ1xuICAgICAgPyBwcm92aWRlLmNhbGwodm0pXG4gICAgICA6IHByb3ZpZGU7XG4gIH1cbn1cblxuZnVuY3Rpb24gaW5pdEluamVjdGlvbnMgKHZtKSB7XG4gIHZhciByZXN1bHQgPSByZXNvbHZlSW5qZWN0KHZtLiRvcHRpb25zLmluamVjdCwgdm0pO1xuICBpZiAocmVzdWx0KSB7XG4gICAgb2JzZXJ2ZXJTdGF0ZS5zaG91bGRDb252ZXJ0ID0gZmFsc2U7XG4gICAgT2JqZWN0LmtleXMocmVzdWx0KS5mb3JFYWNoKGZ1bmN0aW9uIChrZXkpIHtcbiAgICAgIC8qIGlzdGFuYnVsIGlnbm9yZSBlbHNlICovXG4gICAgICBpZiAocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJykge1xuICAgICAgICBkZWZpbmVSZWFjdGl2ZSQkMSh2bSwga2V5LCByZXN1bHRba2V5XSwgZnVuY3Rpb24gKCkge1xuICAgICAgICAgIHdhcm4oXG4gICAgICAgICAgICBcIkF2b2lkIG11dGF0aW5nIGFuIGluamVjdGVkIHZhbHVlIGRpcmVjdGx5IHNpbmNlIHRoZSBjaGFuZ2VzIHdpbGwgYmUgXCIgK1xuICAgICAgICAgICAgXCJvdmVyd3JpdHRlbiB3aGVuZXZlciB0aGUgcHJvdmlkZWQgY29tcG9uZW50IHJlLXJlbmRlcnMuIFwiICtcbiAgICAgICAgICAgIFwiaW5qZWN0aW9uIGJlaW5nIG11dGF0ZWQ6IFxcXCJcIiArIGtleSArIFwiXFxcIlwiLFxuICAgICAgICAgICAgdm1cbiAgICAgICAgICApO1xuICAgICAgICB9KTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGRlZmluZVJlYWN0aXZlJCQxKHZtLCBrZXksIHJlc3VsdFtrZXldKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgICBvYnNlcnZlclN0YXRlLnNob3VsZENvbnZlcnQgPSB0cnVlO1xuICB9XG59XG5cbmZ1bmN0aW9uIHJlc29sdmVJbmplY3QgKGluamVjdCwgdm0pIHtcbiAgaWYgKGluamVjdCkge1xuICAgIC8vIGluamVjdCBpcyA6YW55IGJlY2F1c2UgZmxvdyBpcyBub3Qgc21hcnQgZW5vdWdoIHRvIGZpZ3VyZSBvdXQgY2FjaGVkXG4gICAgdmFyIHJlc3VsdCA9IE9iamVjdC5jcmVhdGUobnVsbCk7XG4gICAgdmFyIGtleXMgPSBoYXNTeW1ib2xcbiAgICAgICAgPyBSZWZsZWN0Lm93bktleXMoaW5qZWN0KS5maWx0ZXIoZnVuY3Rpb24gKGtleSkge1xuICAgICAgICAgIC8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0ICovXG4gICAgICAgICAgcmV0dXJuIE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IoaW5qZWN0LCBrZXkpLmVudW1lcmFibGVcbiAgICAgICAgfSlcbiAgICAgICAgOiBPYmplY3Qua2V5cyhpbmplY3QpO1xuXG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBrZXlzLmxlbmd0aDsgaSsrKSB7XG4gICAgICB2YXIga2V5ID0ga2V5c1tpXTtcbiAgICAgIHZhciBwcm92aWRlS2V5ID0gaW5qZWN0W2tleV07XG4gICAgICB2YXIgc291cmNlID0gdm07XG4gICAgICB3aGlsZSAoc291cmNlKSB7XG4gICAgICAgIGlmIChzb3VyY2UuX3Byb3ZpZGVkICYmIHByb3ZpZGVLZXkgaW4gc291cmNlLl9wcm92aWRlZCkge1xuICAgICAgICAgIHJlc3VsdFtrZXldID0gc291cmNlLl9wcm92aWRlZFtwcm92aWRlS2V5XTtcbiAgICAgICAgICBicmVha1xuICAgICAgICB9XG4gICAgICAgIHNvdXJjZSA9IHNvdXJjZS4kcGFyZW50O1xuICAgICAgfVxuICAgICAgaWYgKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicgJiYgIXNvdXJjZSkge1xuICAgICAgICB3YXJuKChcIkluamVjdGlvbiBcXFwiXCIgKyBrZXkgKyBcIlxcXCIgbm90IGZvdW5kXCIpLCB2bSk7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiByZXN1bHRcbiAgfVxufVxuXG4vKiAgKi9cblxuZnVuY3Rpb24gY3JlYXRlRnVuY3Rpb25hbENvbXBvbmVudCAoXG4gIEN0b3IsXG4gIHByb3BzRGF0YSxcbiAgZGF0YSxcbiAgY29udGV4dCxcbiAgY2hpbGRyZW5cbikge1xuICB2YXIgcHJvcHMgPSB7fTtcbiAgdmFyIHByb3BPcHRpb25zID0gQ3Rvci5vcHRpb25zLnByb3BzO1xuICBpZiAoaXNEZWYocHJvcE9wdGlvbnMpKSB7XG4gICAgZm9yICh2YXIga2V5IGluIHByb3BPcHRpb25zKSB7XG4gICAgICBwcm9wc1trZXldID0gdmFsaWRhdGVQcm9wKGtleSwgcHJvcE9wdGlvbnMsIHByb3BzRGF0YSB8fCBlbXB0eU9iamVjdCk7XG4gICAgfVxuICB9IGVsc2Uge1xuICAgIGlmIChpc0RlZihkYXRhLmF0dHJzKSkgeyBtZXJnZVByb3BzKHByb3BzLCBkYXRhLmF0dHJzKTsgfVxuICAgIGlmIChpc0RlZihkYXRhLnByb3BzKSkgeyBtZXJnZVByb3BzKHByb3BzLCBkYXRhLnByb3BzKTsgfVxuICB9XG4gIC8vIGVuc3VyZSB0aGUgY3JlYXRlRWxlbWVudCBmdW5jdGlvbiBpbiBmdW5jdGlvbmFsIGNvbXBvbmVudHNcbiAgLy8gZ2V0cyBhIHVuaXF1ZSBjb250ZXh0IC0gdGhpcyBpcyBuZWNlc3NhcnkgZm9yIGNvcnJlY3QgbmFtZWQgc2xvdCBjaGVja1xuICB2YXIgX2NvbnRleHQgPSBPYmplY3QuY3JlYXRlKGNvbnRleHQpO1xuICB2YXIgaCA9IGZ1bmN0aW9uIChhLCBiLCBjLCBkKSB7IHJldHVybiBjcmVhdGVFbGVtZW50KF9jb250ZXh0LCBhLCBiLCBjLCBkLCB0cnVlKTsgfTtcbiAgdmFyIHZub2RlID0gQ3Rvci5vcHRpb25zLnJlbmRlci5jYWxsKG51bGwsIGgsIHtcbiAgICBkYXRhOiBkYXRhLFxuICAgIHByb3BzOiBwcm9wcyxcbiAgICBjaGlsZHJlbjogY2hpbGRyZW4sXG4gICAgcGFyZW50OiBjb250ZXh0LFxuICAgIGxpc3RlbmVyczogZGF0YS5vbiB8fCBlbXB0eU9iamVjdCxcbiAgICBpbmplY3Rpb25zOiByZXNvbHZlSW5qZWN0KEN0b3Iub3B0aW9ucy5pbmplY3QsIGNvbnRleHQpLFxuICAgIHNsb3RzOiBmdW5jdGlvbiAoKSB7IHJldHVybiByZXNvbHZlU2xvdHMoY2hpbGRyZW4sIGNvbnRleHQpOyB9XG4gIH0pO1xuICBpZiAodm5vZGUgaW5zdGFuY2VvZiBWTm9kZSkge1xuICAgIHZub2RlLmZ1bmN0aW9uYWxDb250ZXh0ID0gY29udGV4dDtcbiAgICB2bm9kZS5mdW5jdGlvbmFsT3B0aW9ucyA9IEN0b3Iub3B0aW9ucztcbiAgICBpZiAoZGF0YS5zbG90KSB7XG4gICAgICAodm5vZGUuZGF0YSB8fCAodm5vZGUuZGF0YSA9IHt9KSkuc2xvdCA9IGRhdGEuc2xvdDtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIHZub2RlXG59XG5cbmZ1bmN0aW9uIG1lcmdlUHJvcHMgKHRvLCBmcm9tKSB7XG4gIGZvciAodmFyIGtleSBpbiBmcm9tKSB7XG4gICAgdG9bY2FtZWxpemUoa2V5KV0gPSBmcm9tW2tleV07XG4gIH1cbn1cblxuLyogICovXG5cbi8vIGhvb2tzIHRvIGJlIGludm9rZWQgb24gY29tcG9uZW50IFZOb2RlcyBkdXJpbmcgcGF0Y2hcbnZhciBjb21wb25lbnRWTm9kZUhvb2tzID0ge1xuICBpbml0OiBmdW5jdGlvbiBpbml0IChcbiAgICB2bm9kZSxcbiAgICBoeWRyYXRpbmcsXG4gICAgcGFyZW50RWxtLFxuICAgIHJlZkVsbVxuICApIHtcbiAgICBpZiAoIXZub2RlLmNvbXBvbmVudEluc3RhbmNlIHx8IHZub2RlLmNvbXBvbmVudEluc3RhbmNlLl9pc0Rlc3Ryb3llZCkge1xuICAgICAgdmFyIGNoaWxkID0gdm5vZGUuY29tcG9uZW50SW5zdGFuY2UgPSBjcmVhdGVDb21wb25lbnRJbnN0YW5jZUZvclZub2RlKFxuICAgICAgICB2bm9kZSxcbiAgICAgICAgYWN0aXZlSW5zdGFuY2UsXG4gICAgICAgIHBhcmVudEVsbSxcbiAgICAgICAgcmVmRWxtXG4gICAgICApO1xuICAgICAgY2hpbGQuJG1vdW50KGh5ZHJhdGluZyA/IHZub2RlLmVsbSA6IHVuZGVmaW5lZCwgaHlkcmF0aW5nKTtcbiAgICB9IGVsc2UgaWYgKHZub2RlLmRhdGEua2VlcEFsaXZlKSB7XG4gICAgICAvLyBrZXB0LWFsaXZlIGNvbXBvbmVudHMsIHRyZWF0IGFzIGEgcGF0Y2hcbiAgICAgIHZhciBtb3VudGVkTm9kZSA9IHZub2RlOyAvLyB3b3JrIGFyb3VuZCBmbG93XG4gICAgICBjb21wb25lbnRWTm9kZUhvb2tzLnByZXBhdGNoKG1vdW50ZWROb2RlLCBtb3VudGVkTm9kZSk7XG4gICAgfVxuICB9LFxuXG4gIHByZXBhdGNoOiBmdW5jdGlvbiBwcmVwYXRjaCAob2xkVm5vZGUsIHZub2RlKSB7XG4gICAgdmFyIG9wdGlvbnMgPSB2bm9kZS5jb21wb25lbnRPcHRpb25zO1xuICAgIHZhciBjaGlsZCA9IHZub2RlLmNvbXBvbmVudEluc3RhbmNlID0gb2xkVm5vZGUuY29tcG9uZW50SW5zdGFuY2U7XG4gICAgdXBkYXRlQ2hpbGRDb21wb25lbnQoXG4gICAgICBjaGlsZCxcbiAgICAgIG9wdGlvbnMucHJvcHNEYXRhLCAvLyB1cGRhdGVkIHByb3BzXG4gICAgICBvcHRpb25zLmxpc3RlbmVycywgLy8gdXBkYXRlZCBsaXN0ZW5lcnNcbiAgICAgIHZub2RlLCAvLyBuZXcgcGFyZW50IHZub2RlXG4gICAgICBvcHRpb25zLmNoaWxkcmVuIC8vIG5ldyBjaGlsZHJlblxuICAgICk7XG4gIH0sXG5cbiAgaW5zZXJ0OiBmdW5jdGlvbiBpbnNlcnQgKHZub2RlKSB7XG4gICAgdmFyIGNvbnRleHQgPSB2bm9kZS5jb250ZXh0O1xuICAgIHZhciBjb21wb25lbnRJbnN0YW5jZSA9IHZub2RlLmNvbXBvbmVudEluc3RhbmNlO1xuICAgIGlmICghY29tcG9uZW50SW5zdGFuY2UuX2lzTW91bnRlZCkge1xuICAgICAgY29tcG9uZW50SW5zdGFuY2UuX2lzTW91bnRlZCA9IHRydWU7XG4gICAgICBjYWxsSG9vayhjb21wb25lbnRJbnN0YW5jZSwgJ21vdW50ZWQnKTtcbiAgICB9XG4gICAgaWYgKHZub2RlLmRhdGEua2VlcEFsaXZlKSB7XG4gICAgICBpZiAoY29udGV4dC5faXNNb3VudGVkKSB7XG4gICAgICAgIC8vIHZ1ZS1yb3V0ZXIjMTIxMlxuICAgICAgICAvLyBEdXJpbmcgdXBkYXRlcywgYSBrZXB0LWFsaXZlIGNvbXBvbmVudCdzIGNoaWxkIGNvbXBvbmVudHMgbWF5XG4gICAgICAgIC8vIGNoYW5nZSwgc28gZGlyZWN0bHkgd2Fsa2luZyB0aGUgdHJlZSBoZXJlIG1heSBjYWxsIGFjdGl2YXRlZCBob29rc1xuICAgICAgICAvLyBvbiBpbmNvcnJlY3QgY2hpbGRyZW4uIEluc3RlYWQgd2UgcHVzaCB0aGVtIGludG8gYSBxdWV1ZSB3aGljaCB3aWxsXG4gICAgICAgIC8vIGJlIHByb2Nlc3NlZCBhZnRlciB0aGUgd2hvbGUgcGF0Y2ggcHJvY2VzcyBlbmRlZC5cbiAgICAgICAgcXVldWVBY3RpdmF0ZWRDb21wb25lbnQoY29tcG9uZW50SW5zdGFuY2UpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgYWN0aXZhdGVDaGlsZENvbXBvbmVudChjb21wb25lbnRJbnN0YW5jZSwgdHJ1ZSAvKiBkaXJlY3QgKi8pO1xuICAgICAgfVxuICAgIH1cbiAgfSxcblxuICBkZXN0cm95OiBmdW5jdGlvbiBkZXN0cm95ICh2bm9kZSkge1xuICAgIHZhciBjb21wb25lbnRJbnN0YW5jZSA9IHZub2RlLmNvbXBvbmVudEluc3RhbmNlO1xuICAgIGlmICghY29tcG9uZW50SW5zdGFuY2UuX2lzRGVzdHJveWVkKSB7XG4gICAgICBpZiAoIXZub2RlLmRhdGEua2VlcEFsaXZlKSB7XG4gICAgICAgIGNvbXBvbmVudEluc3RhbmNlLiRkZXN0cm95KCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBkZWFjdGl2YXRlQ2hpbGRDb21wb25lbnQoY29tcG9uZW50SW5zdGFuY2UsIHRydWUgLyogZGlyZWN0ICovKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cbn07XG5cbnZhciBob29rc1RvTWVyZ2UgPSBPYmplY3Qua2V5cyhjb21wb25lbnRWTm9kZUhvb2tzKTtcblxuZnVuY3Rpb24gY3JlYXRlQ29tcG9uZW50IChcbiAgQ3RvcixcbiAgZGF0YSxcbiAgY29udGV4dCxcbiAgY2hpbGRyZW4sXG4gIHRhZ1xuKSB7XG4gIGlmIChpc1VuZGVmKEN0b3IpKSB7XG4gICAgcmV0dXJuXG4gIH1cblxuICB2YXIgYmFzZUN0b3IgPSBjb250ZXh0LiRvcHRpb25zLl9iYXNlO1xuXG4gIC8vIHBsYWluIG9wdGlvbnMgb2JqZWN0OiB0dXJuIGl0IGludG8gYSBjb25zdHJ1Y3RvclxuICBpZiAoaXNPYmplY3QoQ3RvcikpIHtcbiAgICBDdG9yID0gYmFzZUN0b3IuZXh0ZW5kKEN0b3IpO1xuICB9XG5cbiAgLy8gaWYgYXQgdGhpcyBzdGFnZSBpdCdzIG5vdCBhIGNvbnN0cnVjdG9yIG9yIGFuIGFzeW5jIGNvbXBvbmVudCBmYWN0b3J5LFxuICAvLyByZWplY3QuXG4gIGlmICh0eXBlb2YgQ3RvciAhPT0gJ2Z1bmN0aW9uJykge1xuICAgIGlmIChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nKSB7XG4gICAgICB3YXJuKChcIkludmFsaWQgQ29tcG9uZW50IGRlZmluaXRpb246IFwiICsgKFN0cmluZyhDdG9yKSkpLCBjb250ZXh0KTtcbiAgICB9XG4gICAgcmV0dXJuXG4gIH1cblxuICAvLyBhc3luYyBjb21wb25lbnRcbiAgdmFyIGFzeW5jRmFjdG9yeTtcbiAgaWYgKGlzVW5kZWYoQ3Rvci5jaWQpKSB7XG4gICAgYXN5bmNGYWN0b3J5ID0gQ3RvcjtcbiAgICBDdG9yID0gcmVzb2x2ZUFzeW5jQ29tcG9uZW50KGFzeW5jRmFjdG9yeSwgYmFzZUN0b3IsIGNvbnRleHQpO1xuICAgIGlmIChDdG9yID09PSB1bmRlZmluZWQpIHtcbiAgICAgIC8vIHJldHVybiBhIHBsYWNlaG9sZGVyIG5vZGUgZm9yIGFzeW5jIGNvbXBvbmVudCwgd2hpY2ggaXMgcmVuZGVyZWRcbiAgICAgIC8vIGFzIGEgY29tbWVudCBub2RlIGJ1dCBwcmVzZXJ2ZXMgYWxsIHRoZSByYXcgaW5mb3JtYXRpb24gZm9yIHRoZSBub2RlLlxuICAgICAgLy8gdGhlIGluZm9ybWF0aW9uIHdpbGwgYmUgdXNlZCBmb3IgYXN5bmMgc2VydmVyLXJlbmRlcmluZyBhbmQgaHlkcmF0aW9uLlxuICAgICAgcmV0dXJuIGNyZWF0ZUFzeW5jUGxhY2Vob2xkZXIoXG4gICAgICAgIGFzeW5jRmFjdG9yeSxcbiAgICAgICAgZGF0YSxcbiAgICAgICAgY29udGV4dCxcbiAgICAgICAgY2hpbGRyZW4sXG4gICAgICAgIHRhZ1xuICAgICAgKVxuICAgIH1cbiAgfVxuXG4gIGRhdGEgPSBkYXRhIHx8IHt9O1xuXG4gIC8vIHJlc29sdmUgY29uc3RydWN0b3Igb3B0aW9ucyBpbiBjYXNlIGdsb2JhbCBtaXhpbnMgYXJlIGFwcGxpZWQgYWZ0ZXJcbiAgLy8gY29tcG9uZW50IGNvbnN0cnVjdG9yIGNyZWF0aW9uXG4gIHJlc29sdmVDb25zdHJ1Y3Rvck9wdGlvbnMoQ3Rvcik7XG5cbiAgLy8gdHJhbnNmb3JtIGNvbXBvbmVudCB2LW1vZGVsIGRhdGEgaW50byBwcm9wcyAmIGV2ZW50c1xuICBpZiAoaXNEZWYoZGF0YS5tb2RlbCkpIHtcbiAgICB0cmFuc2Zvcm1Nb2RlbChDdG9yLm9wdGlvbnMsIGRhdGEpO1xuICB9XG5cbiAgLy8gZXh0cmFjdCBwcm9wc1xuICB2YXIgcHJvcHNEYXRhID0gZXh0cmFjdFByb3BzRnJvbVZOb2RlRGF0YShkYXRhLCBDdG9yLCB0YWcpO1xuXG4gIC8vIGZ1bmN0aW9uYWwgY29tcG9uZW50XG4gIGlmIChpc1RydWUoQ3Rvci5vcHRpb25zLmZ1bmN0aW9uYWwpKSB7XG4gICAgcmV0dXJuIGNyZWF0ZUZ1bmN0aW9uYWxDb21wb25lbnQoQ3RvciwgcHJvcHNEYXRhLCBkYXRhLCBjb250ZXh0LCBjaGlsZHJlbilcbiAgfVxuXG4gIC8vIGV4dHJhY3QgbGlzdGVuZXJzLCBzaW5jZSB0aGVzZSBuZWVkcyB0byBiZSB0cmVhdGVkIGFzXG4gIC8vIGNoaWxkIGNvbXBvbmVudCBsaXN0ZW5lcnMgaW5zdGVhZCBvZiBET00gbGlzdGVuZXJzXG4gIHZhciBsaXN0ZW5lcnMgPSBkYXRhLm9uO1xuICAvLyByZXBsYWNlIHdpdGggbGlzdGVuZXJzIHdpdGggLm5hdGl2ZSBtb2RpZmllclxuICAvLyBzbyBpdCBnZXRzIHByb2Nlc3NlZCBkdXJpbmcgcGFyZW50IGNvbXBvbmVudCBwYXRjaC5cbiAgZGF0YS5vbiA9IGRhdGEubmF0aXZlT247XG5cbiAgaWYgKGlzVHJ1ZShDdG9yLm9wdGlvbnMuYWJzdHJhY3QpKSB7XG4gICAgLy8gYWJzdHJhY3QgY29tcG9uZW50cyBkbyBub3Qga2VlcCBhbnl0aGluZ1xuICAgIC8vIG90aGVyIHRoYW4gcHJvcHMgJiBsaXN0ZW5lcnMgJiBzbG90XG5cbiAgICAvLyB3b3JrIGFyb3VuZCBmbG93XG4gICAgdmFyIHNsb3QgPSBkYXRhLnNsb3Q7XG4gICAgZGF0YSA9IHt9O1xuICAgIGlmIChzbG90KSB7XG4gICAgICBkYXRhLnNsb3QgPSBzbG90O1xuICAgIH1cbiAgfVxuXG4gIC8vIG1lcmdlIGNvbXBvbmVudCBtYW5hZ2VtZW50IGhvb2tzIG9udG8gdGhlIHBsYWNlaG9sZGVyIG5vZGVcbiAgbWVyZ2VIb29rcyhkYXRhKTtcblxuICAvLyByZXR1cm4gYSBwbGFjZWhvbGRlciB2bm9kZVxuICB2YXIgbmFtZSA9IEN0b3Iub3B0aW9ucy5uYW1lIHx8IHRhZztcbiAgdmFyIHZub2RlID0gbmV3IFZOb2RlKFxuICAgIChcInZ1ZS1jb21wb25lbnQtXCIgKyAoQ3Rvci5jaWQpICsgKG5hbWUgPyAoXCItXCIgKyBuYW1lKSA6ICcnKSksXG4gICAgZGF0YSwgdW5kZWZpbmVkLCB1bmRlZmluZWQsIHVuZGVmaW5lZCwgY29udGV4dCxcbiAgICB7IEN0b3I6IEN0b3IsIHByb3BzRGF0YTogcHJvcHNEYXRhLCBsaXN0ZW5lcnM6IGxpc3RlbmVycywgdGFnOiB0YWcsIGNoaWxkcmVuOiBjaGlsZHJlbiB9LFxuICAgIGFzeW5jRmFjdG9yeVxuICApO1xuICByZXR1cm4gdm5vZGVcbn1cblxuZnVuY3Rpb24gY3JlYXRlQ29tcG9uZW50SW5zdGFuY2VGb3JWbm9kZSAoXG4gIHZub2RlLCAvLyB3ZSBrbm93IGl0J3MgTW91bnRlZENvbXBvbmVudFZOb2RlIGJ1dCBmbG93IGRvZXNuJ3RcbiAgcGFyZW50LCAvLyBhY3RpdmVJbnN0YW5jZSBpbiBsaWZlY3ljbGUgc3RhdGVcbiAgcGFyZW50RWxtLFxuICByZWZFbG1cbikge1xuICB2YXIgdm5vZGVDb21wb25lbnRPcHRpb25zID0gdm5vZGUuY29tcG9uZW50T3B0aW9ucztcbiAgdmFyIG9wdGlvbnMgPSB7XG4gICAgX2lzQ29tcG9uZW50OiB0cnVlLFxuICAgIHBhcmVudDogcGFyZW50LFxuICAgIHByb3BzRGF0YTogdm5vZGVDb21wb25lbnRPcHRpb25zLnByb3BzRGF0YSxcbiAgICBfY29tcG9uZW50VGFnOiB2bm9kZUNvbXBvbmVudE9wdGlvbnMudGFnLFxuICAgIF9wYXJlbnRWbm9kZTogdm5vZGUsXG4gICAgX3BhcmVudExpc3RlbmVyczogdm5vZGVDb21wb25lbnRPcHRpb25zLmxpc3RlbmVycyxcbiAgICBfcmVuZGVyQ2hpbGRyZW46IHZub2RlQ29tcG9uZW50T3B0aW9ucy5jaGlsZHJlbixcbiAgICBfcGFyZW50RWxtOiBwYXJlbnRFbG0gfHwgbnVsbCxcbiAgICBfcmVmRWxtOiByZWZFbG0gfHwgbnVsbFxuICB9O1xuICAvLyBjaGVjayBpbmxpbmUtdGVtcGxhdGUgcmVuZGVyIGZ1bmN0aW9uc1xuICB2YXIgaW5saW5lVGVtcGxhdGUgPSB2bm9kZS5kYXRhLmlubGluZVRlbXBsYXRlO1xuICBpZiAoaXNEZWYoaW5saW5lVGVtcGxhdGUpKSB7XG4gICAgb3B0aW9ucy5yZW5kZXIgPSBpbmxpbmVUZW1wbGF0ZS5yZW5kZXI7XG4gICAgb3B0aW9ucy5zdGF0aWNSZW5kZXJGbnMgPSBpbmxpbmVUZW1wbGF0ZS5zdGF0aWNSZW5kZXJGbnM7XG4gIH1cbiAgcmV0dXJuIG5ldyB2bm9kZUNvbXBvbmVudE9wdGlvbnMuQ3RvcihvcHRpb25zKVxufVxuXG5mdW5jdGlvbiBtZXJnZUhvb2tzIChkYXRhKSB7XG4gIGlmICghZGF0YS5ob29rKSB7XG4gICAgZGF0YS5ob29rID0ge307XG4gIH1cbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBob29rc1RvTWVyZ2UubGVuZ3RoOyBpKyspIHtcbiAgICB2YXIga2V5ID0gaG9va3NUb01lcmdlW2ldO1xuICAgIHZhciBmcm9tUGFyZW50ID0gZGF0YS5ob29rW2tleV07XG4gICAgdmFyIG91cnMgPSBjb21wb25lbnRWTm9kZUhvb2tzW2tleV07XG4gICAgZGF0YS5ob29rW2tleV0gPSBmcm9tUGFyZW50ID8gbWVyZ2VIb29rJDEob3VycywgZnJvbVBhcmVudCkgOiBvdXJzO1xuICB9XG59XG5cbmZ1bmN0aW9uIG1lcmdlSG9vayQxIChvbmUsIHR3bykge1xuICByZXR1cm4gZnVuY3Rpb24gKGEsIGIsIGMsIGQpIHtcbiAgICBvbmUoYSwgYiwgYywgZCk7XG4gICAgdHdvKGEsIGIsIGMsIGQpO1xuICB9XG59XG5cbi8vIHRyYW5zZm9ybSBjb21wb25lbnQgdi1tb2RlbCBpbmZvICh2YWx1ZSBhbmQgY2FsbGJhY2spIGludG9cbi8vIHByb3AgYW5kIGV2ZW50IGhhbmRsZXIgcmVzcGVjdGl2ZWx5LlxuZnVuY3Rpb24gdHJhbnNmb3JtTW9kZWwgKG9wdGlvbnMsIGRhdGEpIHtcbiAgdmFyIHByb3AgPSAob3B0aW9ucy5tb2RlbCAmJiBvcHRpb25zLm1vZGVsLnByb3ApIHx8ICd2YWx1ZSc7XG4gIHZhciBldmVudCA9IChvcHRpb25zLm1vZGVsICYmIG9wdGlvbnMubW9kZWwuZXZlbnQpIHx8ICdpbnB1dCc7KGRhdGEucHJvcHMgfHwgKGRhdGEucHJvcHMgPSB7fSkpW3Byb3BdID0gZGF0YS5tb2RlbC52YWx1ZTtcbiAgdmFyIG9uID0gZGF0YS5vbiB8fCAoZGF0YS5vbiA9IHt9KTtcbiAgaWYgKGlzRGVmKG9uW2V2ZW50XSkpIHtcbiAgICBvbltldmVudF0gPSBbZGF0YS5tb2RlbC5jYWxsYmFja10uY29uY2F0KG9uW2V2ZW50XSk7XG4gIH0gZWxzZSB7XG4gICAgb25bZXZlbnRdID0gZGF0YS5tb2RlbC5jYWxsYmFjaztcbiAgfVxufVxuXG4vKiAgKi9cblxudmFyIFNJTVBMRV9OT1JNQUxJWkUgPSAxO1xudmFyIEFMV0FZU19OT1JNQUxJWkUgPSAyO1xuXG4vLyB3cmFwcGVyIGZ1bmN0aW9uIGZvciBwcm92aWRpbmcgYSBtb3JlIGZsZXhpYmxlIGludGVyZmFjZVxuLy8gd2l0aG91dCBnZXR0aW5nIHllbGxlZCBhdCBieSBmbG93XG5mdW5jdGlvbiBjcmVhdGVFbGVtZW50IChcbiAgY29udGV4dCxcbiAgdGFnLFxuICBkYXRhLFxuICBjaGlsZHJlbixcbiAgbm9ybWFsaXphdGlvblR5cGUsXG4gIGFsd2F5c05vcm1hbGl6ZVxuKSB7XG4gIGlmIChBcnJheS5pc0FycmF5KGRhdGEpIHx8IGlzUHJpbWl0aXZlKGRhdGEpKSB7XG4gICAgbm9ybWFsaXphdGlvblR5cGUgPSBjaGlsZHJlbjtcbiAgICBjaGlsZHJlbiA9IGRhdGE7XG4gICAgZGF0YSA9IHVuZGVmaW5lZDtcbiAgfVxuICBpZiAoaXNUcnVlKGFsd2F5c05vcm1hbGl6ZSkpIHtcbiAgICBub3JtYWxpemF0aW9uVHlwZSA9IEFMV0FZU19OT1JNQUxJWkU7XG4gIH1cbiAgcmV0dXJuIF9jcmVhdGVFbGVtZW50KGNvbnRleHQsIHRhZywgZGF0YSwgY2hpbGRyZW4sIG5vcm1hbGl6YXRpb25UeXBlKVxufVxuXG5mdW5jdGlvbiBfY3JlYXRlRWxlbWVudCAoXG4gIGNvbnRleHQsXG4gIHRhZyxcbiAgZGF0YSxcbiAgY2hpbGRyZW4sXG4gIG5vcm1hbGl6YXRpb25UeXBlXG4pIHtcbiAgaWYgKGlzRGVmKGRhdGEpICYmIGlzRGVmKChkYXRhKS5fX29iX18pKSB7XG4gICAgcHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJyAmJiB3YXJuKFxuICAgICAgXCJBdm9pZCB1c2luZyBvYnNlcnZlZCBkYXRhIG9iamVjdCBhcyB2bm9kZSBkYXRhOiBcIiArIChKU09OLnN0cmluZ2lmeShkYXRhKSkgKyBcIlxcblwiICtcbiAgICAgICdBbHdheXMgY3JlYXRlIGZyZXNoIHZub2RlIGRhdGEgb2JqZWN0cyBpbiBlYWNoIHJlbmRlciEnLFxuICAgICAgY29udGV4dFxuICAgICk7XG4gICAgcmV0dXJuIGNyZWF0ZUVtcHR5Vk5vZGUoKVxuICB9XG4gIC8vIG9iamVjdCBzeW50YXggaW4gdi1iaW5kXG4gIGlmIChpc0RlZihkYXRhKSAmJiBpc0RlZihkYXRhLmlzKSkge1xuICAgIHRhZyA9IGRhdGEuaXM7XG4gIH1cbiAgaWYgKCF0YWcpIHtcbiAgICAvLyBpbiBjYXNlIG9mIGNvbXBvbmVudCA6aXMgc2V0IHRvIGZhbHN5IHZhbHVlXG4gICAgcmV0dXJuIGNyZWF0ZUVtcHR5Vk5vZGUoKVxuICB9XG4gIC8vIHdhcm4gYWdhaW5zdCBub24tcHJpbWl0aXZlIGtleVxuICBpZiAocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJyAmJlxuICAgIGlzRGVmKGRhdGEpICYmIGlzRGVmKGRhdGEua2V5KSAmJiAhaXNQcmltaXRpdmUoZGF0YS5rZXkpXG4gICkge1xuICAgIHdhcm4oXG4gICAgICAnQXZvaWQgdXNpbmcgbm9uLXByaW1pdGl2ZSB2YWx1ZSBhcyBrZXksICcgK1xuICAgICAgJ3VzZSBzdHJpbmcvbnVtYmVyIHZhbHVlIGluc3RlYWQuJyxcbiAgICAgIGNvbnRleHRcbiAgICApO1xuICB9XG4gIC8vIHN1cHBvcnQgc2luZ2xlIGZ1bmN0aW9uIGNoaWxkcmVuIGFzIGRlZmF1bHQgc2NvcGVkIHNsb3RcbiAgaWYgKEFycmF5LmlzQXJyYXkoY2hpbGRyZW4pICYmXG4gICAgdHlwZW9mIGNoaWxkcmVuWzBdID09PSAnZnVuY3Rpb24nXG4gICkge1xuICAgIGRhdGEgPSBkYXRhIHx8IHt9O1xuICAgIGRhdGEuc2NvcGVkU2xvdHMgPSB7IGRlZmF1bHQ6IGNoaWxkcmVuWzBdIH07XG4gICAgY2hpbGRyZW4ubGVuZ3RoID0gMDtcbiAgfVxuICBpZiAobm9ybWFsaXphdGlvblR5cGUgPT09IEFMV0FZU19OT1JNQUxJWkUpIHtcbiAgICBjaGlsZHJlbiA9IG5vcm1hbGl6ZUNoaWxkcmVuKGNoaWxkcmVuKTtcbiAgfSBlbHNlIGlmIChub3JtYWxpemF0aW9uVHlwZSA9PT0gU0lNUExFX05PUk1BTElaRSkge1xuICAgIGNoaWxkcmVuID0gc2ltcGxlTm9ybWFsaXplQ2hpbGRyZW4oY2hpbGRyZW4pO1xuICB9XG4gIHZhciB2bm9kZSwgbnM7XG4gIGlmICh0eXBlb2YgdGFnID09PSAnc3RyaW5nJykge1xuICAgIHZhciBDdG9yO1xuICAgIG5zID0gKGNvbnRleHQuJHZub2RlICYmIGNvbnRleHQuJHZub2RlLm5zKSB8fCBjb25maWcuZ2V0VGFnTmFtZXNwYWNlKHRhZyk7XG4gICAgaWYgKGNvbmZpZy5pc1Jlc2VydmVkVGFnKHRhZykpIHtcbiAgICAgIC8vIHBsYXRmb3JtIGJ1aWx0LWluIGVsZW1lbnRzXG4gICAgICB2bm9kZSA9IG5ldyBWTm9kZShcbiAgICAgICAgY29uZmlnLnBhcnNlUGxhdGZvcm1UYWdOYW1lKHRhZyksIGRhdGEsIGNoaWxkcmVuLFxuICAgICAgICB1bmRlZmluZWQsIHVuZGVmaW5lZCwgY29udGV4dFxuICAgICAgKTtcbiAgICB9IGVsc2UgaWYgKGlzRGVmKEN0b3IgPSByZXNvbHZlQXNzZXQoY29udGV4dC4kb3B0aW9ucywgJ2NvbXBvbmVudHMnLCB0YWcpKSkge1xuICAgICAgLy8gY29tcG9uZW50XG4gICAgICB2bm9kZSA9IGNyZWF0ZUNvbXBvbmVudChDdG9yLCBkYXRhLCBjb250ZXh0LCBjaGlsZHJlbiwgdGFnKTtcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gdW5rbm93biBvciB1bmxpc3RlZCBuYW1lc3BhY2VkIGVsZW1lbnRzXG4gICAgICAvLyBjaGVjayBhdCBydW50aW1lIGJlY2F1c2UgaXQgbWF5IGdldCBhc3NpZ25lZCBhIG5hbWVzcGFjZSB3aGVuIGl0c1xuICAgICAgLy8gcGFyZW50IG5vcm1hbGl6ZXMgY2hpbGRyZW5cbiAgICAgIHZub2RlID0gbmV3IFZOb2RlKFxuICAgICAgICB0YWcsIGRhdGEsIGNoaWxkcmVuLFxuICAgICAgICB1bmRlZmluZWQsIHVuZGVmaW5lZCwgY29udGV4dFxuICAgICAgKTtcbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgLy8gZGlyZWN0IGNvbXBvbmVudCBvcHRpb25zIC8gY29uc3RydWN0b3JcbiAgICB2bm9kZSA9IGNyZWF0ZUNvbXBvbmVudCh0YWcsIGRhdGEsIGNvbnRleHQsIGNoaWxkcmVuKTtcbiAgfVxuICBpZiAoaXNEZWYodm5vZGUpKSB7XG4gICAgaWYgKG5zKSB7IGFwcGx5TlModm5vZGUsIG5zKTsgfVxuICAgIHJldHVybiB2bm9kZVxuICB9IGVsc2Uge1xuICAgIHJldHVybiBjcmVhdGVFbXB0eVZOb2RlKClcbiAgfVxufVxuXG5mdW5jdGlvbiBhcHBseU5TICh2bm9kZSwgbnMpIHtcbiAgdm5vZGUubnMgPSBucztcbiAgaWYgKHZub2RlLnRhZyA9PT0gJ2ZvcmVpZ25PYmplY3QnKSB7XG4gICAgLy8gdXNlIGRlZmF1bHQgbmFtZXNwYWNlIGluc2lkZSBmb3JlaWduT2JqZWN0XG4gICAgcmV0dXJuXG4gIH1cbiAgaWYgKGlzRGVmKHZub2RlLmNoaWxkcmVuKSkge1xuICAgIGZvciAodmFyIGkgPSAwLCBsID0gdm5vZGUuY2hpbGRyZW4ubGVuZ3RoOyBpIDwgbDsgaSsrKSB7XG4gICAgICB2YXIgY2hpbGQgPSB2bm9kZS5jaGlsZHJlbltpXTtcbiAgICAgIGlmIChpc0RlZihjaGlsZC50YWcpICYmIGlzVW5kZWYoY2hpbGQubnMpKSB7XG4gICAgICAgIGFwcGx5TlMoY2hpbGQsIG5zKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cbn1cblxuLyogICovXG5cbi8qKlxuICogUnVudGltZSBoZWxwZXIgZm9yIHJlbmRlcmluZyB2LWZvciBsaXN0cy5cbiAqL1xuZnVuY3Rpb24gcmVuZGVyTGlzdCAoXG4gIHZhbCxcbiAgcmVuZGVyXG4pIHtcbiAgdmFyIHJldCwgaSwgbCwga2V5cywga2V5O1xuICBpZiAoQXJyYXkuaXNBcnJheSh2YWwpIHx8IHR5cGVvZiB2YWwgPT09ICdzdHJpbmcnKSB7XG4gICAgcmV0ID0gbmV3IEFycmF5KHZhbC5sZW5ndGgpO1xuICAgIGZvciAoaSA9IDAsIGwgPSB2YWwubGVuZ3RoOyBpIDwgbDsgaSsrKSB7XG4gICAgICByZXRbaV0gPSByZW5kZXIodmFsW2ldLCBpKTtcbiAgICB9XG4gIH0gZWxzZSBpZiAodHlwZW9mIHZhbCA9PT0gJ251bWJlcicpIHtcbiAgICByZXQgPSBuZXcgQXJyYXkodmFsKTtcbiAgICBmb3IgKGkgPSAwOyBpIDwgdmFsOyBpKyspIHtcbiAgICAgIHJldFtpXSA9IHJlbmRlcihpICsgMSwgaSk7XG4gICAgfVxuICB9IGVsc2UgaWYgKGlzT2JqZWN0KHZhbCkpIHtcbiAgICBrZXlzID0gT2JqZWN0LmtleXModmFsKTtcbiAgICByZXQgPSBuZXcgQXJyYXkoa2V5cy5sZW5ndGgpO1xuICAgIGZvciAoaSA9IDAsIGwgPSBrZXlzLmxlbmd0aDsgaSA8IGw7IGkrKykge1xuICAgICAga2V5ID0ga2V5c1tpXTtcbiAgICAgIHJldFtpXSA9IHJlbmRlcih2YWxba2V5XSwga2V5LCBpKTtcbiAgICB9XG4gIH1cbiAgaWYgKGlzRGVmKHJldCkpIHtcbiAgICAocmV0KS5faXNWTGlzdCA9IHRydWU7XG4gIH1cbiAgcmV0dXJuIHJldFxufVxuXG4vKiAgKi9cblxuLyoqXG4gKiBSdW50aW1lIGhlbHBlciBmb3IgcmVuZGVyaW5nIDxzbG90PlxuICovXG5mdW5jdGlvbiByZW5kZXJTbG90IChcbiAgbmFtZSxcbiAgZmFsbGJhY2ssXG4gIHByb3BzLFxuICBiaW5kT2JqZWN0XG4pIHtcbiAgdmFyIHNjb3BlZFNsb3RGbiA9IHRoaXMuJHNjb3BlZFNsb3RzW25hbWVdO1xuICBpZiAoc2NvcGVkU2xvdEZuKSB7IC8vIHNjb3BlZCBzbG90XG4gICAgcHJvcHMgPSBwcm9wcyB8fCB7fTtcbiAgICBpZiAoYmluZE9iamVjdCkge1xuICAgICAgcHJvcHMgPSBleHRlbmQoZXh0ZW5kKHt9LCBiaW5kT2JqZWN0KSwgcHJvcHMpO1xuICAgIH1cbiAgICByZXR1cm4gc2NvcGVkU2xvdEZuKHByb3BzKSB8fCBmYWxsYmFja1xuICB9IGVsc2Uge1xuICAgIHZhciBzbG90Tm9kZXMgPSB0aGlzLiRzbG90c1tuYW1lXTtcbiAgICAvLyB3YXJuIGR1cGxpY2F0ZSBzbG90IHVzYWdlXG4gICAgaWYgKHNsb3ROb2RlcyAmJiBwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nKSB7XG4gICAgICBzbG90Tm9kZXMuX3JlbmRlcmVkICYmIHdhcm4oXG4gICAgICAgIFwiRHVwbGljYXRlIHByZXNlbmNlIG9mIHNsb3QgXFxcIlwiICsgbmFtZSArIFwiXFxcIiBmb3VuZCBpbiB0aGUgc2FtZSByZW5kZXIgdHJlZSBcIiArXG4gICAgICAgIFwiLSB0aGlzIHdpbGwgbGlrZWx5IGNhdXNlIHJlbmRlciBlcnJvcnMuXCIsXG4gICAgICAgIHRoaXNcbiAgICAgICk7XG4gICAgICBzbG90Tm9kZXMuX3JlbmRlcmVkID0gdHJ1ZTtcbiAgICB9XG4gICAgcmV0dXJuIHNsb3ROb2RlcyB8fCBmYWxsYmFja1xuICB9XG59XG5cbi8qICAqL1xuXG4vKipcbiAqIFJ1bnRpbWUgaGVscGVyIGZvciByZXNvbHZpbmcgZmlsdGVyc1xuICovXG5mdW5jdGlvbiByZXNvbHZlRmlsdGVyIChpZCkge1xuICByZXR1cm4gcmVzb2x2ZUFzc2V0KHRoaXMuJG9wdGlvbnMsICdmaWx0ZXJzJywgaWQsIHRydWUpIHx8IGlkZW50aXR5XG59XG5cbi8qICAqL1xuXG4vKipcbiAqIFJ1bnRpbWUgaGVscGVyIGZvciBjaGVja2luZyBrZXlDb2RlcyBmcm9tIGNvbmZpZy5cbiAqL1xuZnVuY3Rpb24gY2hlY2tLZXlDb2RlcyAoXG4gIGV2ZW50S2V5Q29kZSxcbiAga2V5LFxuICBidWlsdEluQWxpYXNcbikge1xuICB2YXIga2V5Q29kZXMgPSBjb25maWcua2V5Q29kZXNba2V5XSB8fCBidWlsdEluQWxpYXM7XG4gIGlmIChBcnJheS5pc0FycmF5KGtleUNvZGVzKSkge1xuICAgIHJldHVybiBrZXlDb2Rlcy5pbmRleE9mKGV2ZW50S2V5Q29kZSkgPT09IC0xXG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIGtleUNvZGVzICE9PSBldmVudEtleUNvZGVcbiAgfVxufVxuXG4vKiAgKi9cblxuLyoqXG4gKiBSdW50aW1lIGhlbHBlciBmb3IgbWVyZ2luZyB2LWJpbmQ9XCJvYmplY3RcIiBpbnRvIGEgVk5vZGUncyBkYXRhLlxuICovXG5mdW5jdGlvbiBiaW5kT2JqZWN0UHJvcHMgKFxuICBkYXRhLFxuICB0YWcsXG4gIHZhbHVlLFxuICBhc1Byb3AsXG4gIGlzU3luY1xuKSB7XG4gIGlmICh2YWx1ZSkge1xuICAgIGlmICghaXNPYmplY3QodmFsdWUpKSB7XG4gICAgICBwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nICYmIHdhcm4oXG4gICAgICAgICd2LWJpbmQgd2l0aG91dCBhcmd1bWVudCBleHBlY3RzIGFuIE9iamVjdCBvciBBcnJheSB2YWx1ZScsXG4gICAgICAgIHRoaXNcbiAgICAgICk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGlmIChBcnJheS5pc0FycmF5KHZhbHVlKSkge1xuICAgICAgICB2YWx1ZSA9IHRvT2JqZWN0KHZhbHVlKTtcbiAgICAgIH1cbiAgICAgIHZhciBoYXNoO1xuICAgICAgdmFyIGxvb3AgPSBmdW5jdGlvbiAoIGtleSApIHtcbiAgICAgICAgaWYgKFxuICAgICAgICAgIGtleSA9PT0gJ2NsYXNzJyB8fFxuICAgICAgICAgIGtleSA9PT0gJ3N0eWxlJyB8fFxuICAgICAgICAgIGlzUmVzZXJ2ZWRBdHRyaWJ1dGUoa2V5KVxuICAgICAgICApIHtcbiAgICAgICAgICBoYXNoID0gZGF0YTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB2YXIgdHlwZSA9IGRhdGEuYXR0cnMgJiYgZGF0YS5hdHRycy50eXBlO1xuICAgICAgICAgIGhhc2ggPSBhc1Byb3AgfHwgY29uZmlnLm11c3RVc2VQcm9wKHRhZywgdHlwZSwga2V5KVxuICAgICAgICAgICAgPyBkYXRhLmRvbVByb3BzIHx8IChkYXRhLmRvbVByb3BzID0ge30pXG4gICAgICAgICAgICA6IGRhdGEuYXR0cnMgfHwgKGRhdGEuYXR0cnMgPSB7fSk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKCEoa2V5IGluIGhhc2gpKSB7XG4gICAgICAgICAgaGFzaFtrZXldID0gdmFsdWVba2V5XTtcblxuICAgICAgICAgIGlmIChpc1N5bmMpIHtcbiAgICAgICAgICAgIHZhciBvbiA9IGRhdGEub24gfHwgKGRhdGEub24gPSB7fSk7XG4gICAgICAgICAgICBvblsoXCJ1cGRhdGU6XCIgKyBrZXkpXSA9IGZ1bmN0aW9uICgkZXZlbnQpIHtcbiAgICAgICAgICAgICAgdmFsdWVba2V5XSA9ICRldmVudDtcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9O1xuXG4gICAgICBmb3IgKHZhciBrZXkgaW4gdmFsdWUpIGxvb3AoIGtleSApO1xuICAgIH1cbiAgfVxuICByZXR1cm4gZGF0YVxufVxuXG4vKiAgKi9cblxuLyoqXG4gKiBSdW50aW1lIGhlbHBlciBmb3IgcmVuZGVyaW5nIHN0YXRpYyB0cmVlcy5cbiAqL1xuZnVuY3Rpb24gcmVuZGVyU3RhdGljIChcbiAgaW5kZXgsXG4gIGlzSW5Gb3Jcbikge1xuICB2YXIgdHJlZSA9IHRoaXMuX3N0YXRpY1RyZWVzW2luZGV4XTtcbiAgLy8gaWYgaGFzIGFscmVhZHktcmVuZGVyZWQgc3RhdGljIHRyZWUgYW5kIG5vdCBpbnNpZGUgdi1mb3IsXG4gIC8vIHdlIGNhbiByZXVzZSB0aGUgc2FtZSB0cmVlIGJ5IGRvaW5nIGEgc2hhbGxvdyBjbG9uZS5cbiAgaWYgKHRyZWUgJiYgIWlzSW5Gb3IpIHtcbiAgICByZXR1cm4gQXJyYXkuaXNBcnJheSh0cmVlKVxuICAgICAgPyBjbG9uZVZOb2Rlcyh0cmVlKVxuICAgICAgOiBjbG9uZVZOb2RlKHRyZWUpXG4gIH1cbiAgLy8gb3RoZXJ3aXNlLCByZW5kZXIgYSBmcmVzaCB0cmVlLlxuICB0cmVlID0gdGhpcy5fc3RhdGljVHJlZXNbaW5kZXhdID1cbiAgICB0aGlzLiRvcHRpb25zLnN0YXRpY1JlbmRlckZuc1tpbmRleF0uY2FsbCh0aGlzLl9yZW5kZXJQcm94eSk7XG4gIG1hcmtTdGF0aWModHJlZSwgKFwiX19zdGF0aWNfX1wiICsgaW5kZXgpLCBmYWxzZSk7XG4gIHJldHVybiB0cmVlXG59XG5cbi8qKlxuICogUnVudGltZSBoZWxwZXIgZm9yIHYtb25jZS5cbiAqIEVmZmVjdGl2ZWx5IGl0IG1lYW5zIG1hcmtpbmcgdGhlIG5vZGUgYXMgc3RhdGljIHdpdGggYSB1bmlxdWUga2V5LlxuICovXG5mdW5jdGlvbiBtYXJrT25jZSAoXG4gIHRyZWUsXG4gIGluZGV4LFxuICBrZXlcbikge1xuICBtYXJrU3RhdGljKHRyZWUsIChcIl9fb25jZV9fXCIgKyBpbmRleCArIChrZXkgPyAoXCJfXCIgKyBrZXkpIDogXCJcIikpLCB0cnVlKTtcbiAgcmV0dXJuIHRyZWVcbn1cblxuZnVuY3Rpb24gbWFya1N0YXRpYyAoXG4gIHRyZWUsXG4gIGtleSxcbiAgaXNPbmNlXG4pIHtcbiAgaWYgKEFycmF5LmlzQXJyYXkodHJlZSkpIHtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IHRyZWUubGVuZ3RoOyBpKyspIHtcbiAgICAgIGlmICh0cmVlW2ldICYmIHR5cGVvZiB0cmVlW2ldICE9PSAnc3RyaW5nJykge1xuICAgICAgICBtYXJrU3RhdGljTm9kZSh0cmVlW2ldLCAoa2V5ICsgXCJfXCIgKyBpKSwgaXNPbmNlKTtcbiAgICAgIH1cbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgbWFya1N0YXRpY05vZGUodHJlZSwga2V5LCBpc09uY2UpO1xuICB9XG59XG5cbmZ1bmN0aW9uIG1hcmtTdGF0aWNOb2RlIChub2RlLCBrZXksIGlzT25jZSkge1xuICBub2RlLmlzU3RhdGljID0gdHJ1ZTtcbiAgbm9kZS5rZXkgPSBrZXk7XG4gIG5vZGUuaXNPbmNlID0gaXNPbmNlO1xufVxuXG4vKiAgKi9cblxuZnVuY3Rpb24gYmluZE9iamVjdExpc3RlbmVycyAoZGF0YSwgdmFsdWUpIHtcbiAgaWYgKHZhbHVlKSB7XG4gICAgaWYgKCFpc1BsYWluT2JqZWN0KHZhbHVlKSkge1xuICAgICAgcHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJyAmJiB3YXJuKFxuICAgICAgICAndi1vbiB3aXRob3V0IGFyZ3VtZW50IGV4cGVjdHMgYW4gT2JqZWN0IHZhbHVlJyxcbiAgICAgICAgdGhpc1xuICAgICAgKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdmFyIG9uID0gZGF0YS5vbiA9IGRhdGEub24gPyBleHRlbmQoe30sIGRhdGEub24pIDoge307XG4gICAgICBmb3IgKHZhciBrZXkgaW4gdmFsdWUpIHtcbiAgICAgICAgdmFyIGV4aXN0aW5nID0gb25ba2V5XTtcbiAgICAgICAgdmFyIG91cnMgPSB2YWx1ZVtrZXldO1xuICAgICAgICBvbltrZXldID0gZXhpc3RpbmcgPyBbXS5jb25jYXQob3VycywgZXhpc3RpbmcpIDogb3VycztcbiAgICAgIH1cbiAgICB9XG4gIH1cbiAgcmV0dXJuIGRhdGFcbn1cblxuLyogICovXG5cbmZ1bmN0aW9uIGluaXRSZW5kZXIgKHZtKSB7XG4gIHZtLl92bm9kZSA9IG51bGw7IC8vIHRoZSByb290IG9mIHRoZSBjaGlsZCB0cmVlXG4gIHZtLl9zdGF0aWNUcmVlcyA9IG51bGw7XG4gIHZhciBwYXJlbnRWbm9kZSA9IHZtLiR2bm9kZSA9IHZtLiRvcHRpb25zLl9wYXJlbnRWbm9kZTsgLy8gdGhlIHBsYWNlaG9sZGVyIG5vZGUgaW4gcGFyZW50IHRyZWVcbiAgdmFyIHJlbmRlckNvbnRleHQgPSBwYXJlbnRWbm9kZSAmJiBwYXJlbnRWbm9kZS5jb250ZXh0O1xuICB2bS4kc2xvdHMgPSByZXNvbHZlU2xvdHModm0uJG9wdGlvbnMuX3JlbmRlckNoaWxkcmVuLCByZW5kZXJDb250ZXh0KTtcbiAgdm0uJHNjb3BlZFNsb3RzID0gZW1wdHlPYmplY3Q7XG4gIC8vIGJpbmQgdGhlIGNyZWF0ZUVsZW1lbnQgZm4gdG8gdGhpcyBpbnN0YW5jZVxuICAvLyBzbyB0aGF0IHdlIGdldCBwcm9wZXIgcmVuZGVyIGNvbnRleHQgaW5zaWRlIGl0LlxuICAvLyBhcmdzIG9yZGVyOiB0YWcsIGRhdGEsIGNoaWxkcmVuLCBub3JtYWxpemF0aW9uVHlwZSwgYWx3YXlzTm9ybWFsaXplXG4gIC8vIGludGVybmFsIHZlcnNpb24gaXMgdXNlZCBieSByZW5kZXIgZnVuY3Rpb25zIGNvbXBpbGVkIGZyb20gdGVtcGxhdGVzXG4gIHZtLl9jID0gZnVuY3Rpb24gKGEsIGIsIGMsIGQpIHsgcmV0dXJuIGNyZWF0ZUVsZW1lbnQodm0sIGEsIGIsIGMsIGQsIGZhbHNlKTsgfTtcbiAgLy8gbm9ybWFsaXphdGlvbiBpcyBhbHdheXMgYXBwbGllZCBmb3IgdGhlIHB1YmxpYyB2ZXJzaW9uLCB1c2VkIGluXG4gIC8vIHVzZXItd3JpdHRlbiByZW5kZXIgZnVuY3Rpb25zLlxuICB2bS4kY3JlYXRlRWxlbWVudCA9IGZ1bmN0aW9uIChhLCBiLCBjLCBkKSB7IHJldHVybiBjcmVhdGVFbGVtZW50KHZtLCBhLCBiLCBjLCBkLCB0cnVlKTsgfTtcblxuICAvLyAkYXR0cnMgJiAkbGlzdGVuZXJzIGFyZSBleHBvc2VkIGZvciBlYXNpZXIgSE9DIGNyZWF0aW9uLlxuICAvLyB0aGV5IG5lZWQgdG8gYmUgcmVhY3RpdmUgc28gdGhhdCBIT0NzIHVzaW5nIHRoZW0gYXJlIGFsd2F5cyB1cGRhdGVkXG4gIHZhciBwYXJlbnREYXRhID0gcGFyZW50Vm5vZGUgJiYgcGFyZW50Vm5vZGUuZGF0YTtcblxuICAvKiBpc3RhbmJ1bCBpZ25vcmUgZWxzZSAqL1xuICBpZiAocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJykge1xuICAgIGRlZmluZVJlYWN0aXZlJCQxKHZtLCAnJGF0dHJzJywgcGFyZW50RGF0YSAmJiBwYXJlbnREYXRhLmF0dHJzIHx8IGVtcHR5T2JqZWN0LCBmdW5jdGlvbiAoKSB7XG4gICAgICAhaXNVcGRhdGluZ0NoaWxkQ29tcG9uZW50ICYmIHdhcm4oXCIkYXR0cnMgaXMgcmVhZG9ubHkuXCIsIHZtKTtcbiAgICB9LCB0cnVlKTtcbiAgICBkZWZpbmVSZWFjdGl2ZSQkMSh2bSwgJyRsaXN0ZW5lcnMnLCB2bS4kb3B0aW9ucy5fcGFyZW50TGlzdGVuZXJzIHx8IGVtcHR5T2JqZWN0LCBmdW5jdGlvbiAoKSB7XG4gICAgICAhaXNVcGRhdGluZ0NoaWxkQ29tcG9uZW50ICYmIHdhcm4oXCIkbGlzdGVuZXJzIGlzIHJlYWRvbmx5LlwiLCB2bSk7XG4gICAgfSwgdHJ1ZSk7XG4gIH0gZWxzZSB7XG4gICAgZGVmaW5lUmVhY3RpdmUkJDEodm0sICckYXR0cnMnLCBwYXJlbnREYXRhICYmIHBhcmVudERhdGEuYXR0cnMgfHwgZW1wdHlPYmplY3QsIG51bGwsIHRydWUpO1xuICAgIGRlZmluZVJlYWN0aXZlJCQxKHZtLCAnJGxpc3RlbmVycycsIHZtLiRvcHRpb25zLl9wYXJlbnRMaXN0ZW5lcnMgfHwgZW1wdHlPYmplY3QsIG51bGwsIHRydWUpO1xuICB9XG59XG5cbmZ1bmN0aW9uIHJlbmRlck1peGluIChWdWUpIHtcbiAgVnVlLnByb3RvdHlwZS4kbmV4dFRpY2sgPSBmdW5jdGlvbiAoZm4pIHtcbiAgICByZXR1cm4gbmV4dFRpY2soZm4sIHRoaXMpXG4gIH07XG5cbiAgVnVlLnByb3RvdHlwZS5fcmVuZGVyID0gZnVuY3Rpb24gKCkge1xuICAgIHZhciB2bSA9IHRoaXM7XG4gICAgdmFyIHJlZiA9IHZtLiRvcHRpb25zO1xuICAgIHZhciByZW5kZXIgPSByZWYucmVuZGVyO1xuICAgIHZhciBzdGF0aWNSZW5kZXJGbnMgPSByZWYuc3RhdGljUmVuZGVyRm5zO1xuICAgIHZhciBfcGFyZW50Vm5vZGUgPSByZWYuX3BhcmVudFZub2RlO1xuXG4gICAgaWYgKHZtLl9pc01vdW50ZWQpIHtcbiAgICAgIC8vIGlmIHRoZSBwYXJlbnQgZGlkbid0IHVwZGF0ZSwgdGhlIHNsb3Qgbm9kZXMgd2lsbCBiZSB0aGUgb25lcyBmcm9tXG4gICAgICAvLyBsYXN0IHJlbmRlci4gVGhleSBuZWVkIHRvIGJlIGNsb25lZCB0byBlbnN1cmUgXCJmcmVzaG5lc3NcIiBmb3IgdGhpcyByZW5kZXIuXG4gICAgICBmb3IgKHZhciBrZXkgaW4gdm0uJHNsb3RzKSB7XG4gICAgICAgIHZhciBzbG90ID0gdm0uJHNsb3RzW2tleV07XG4gICAgICAgIGlmIChzbG90Ll9yZW5kZXJlZCkge1xuICAgICAgICAgIHZtLiRzbG90c1trZXldID0gY2xvbmVWTm9kZXMoc2xvdCwgdHJ1ZSAvKiBkZWVwICovKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIHZtLiRzY29wZWRTbG90cyA9IChfcGFyZW50Vm5vZGUgJiYgX3BhcmVudFZub2RlLmRhdGEuc2NvcGVkU2xvdHMpIHx8IGVtcHR5T2JqZWN0O1xuXG4gICAgaWYgKHN0YXRpY1JlbmRlckZucyAmJiAhdm0uX3N0YXRpY1RyZWVzKSB7XG4gICAgICB2bS5fc3RhdGljVHJlZXMgPSBbXTtcbiAgICB9XG4gICAgLy8gc2V0IHBhcmVudCB2bm9kZS4gdGhpcyBhbGxvd3MgcmVuZGVyIGZ1bmN0aW9ucyB0byBoYXZlIGFjY2Vzc1xuICAgIC8vIHRvIHRoZSBkYXRhIG9uIHRoZSBwbGFjZWhvbGRlciBub2RlLlxuICAgIHZtLiR2bm9kZSA9IF9wYXJlbnRWbm9kZTtcbiAgICAvLyByZW5kZXIgc2VsZlxuICAgIHZhciB2bm9kZTtcbiAgICB0cnkge1xuICAgICAgdm5vZGUgPSByZW5kZXIuY2FsbCh2bS5fcmVuZGVyUHJveHksIHZtLiRjcmVhdGVFbGVtZW50KTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICBoYW5kbGVFcnJvcihlLCB2bSwgXCJyZW5kZXIgZnVuY3Rpb25cIik7XG4gICAgICAvLyByZXR1cm4gZXJyb3IgcmVuZGVyIHJlc3VsdCxcbiAgICAgIC8vIG9yIHByZXZpb3VzIHZub2RlIHRvIHByZXZlbnQgcmVuZGVyIGVycm9yIGNhdXNpbmcgYmxhbmsgY29tcG9uZW50XG4gICAgICAvKiBpc3RhbmJ1bCBpZ25vcmUgZWxzZSAqL1xuICAgICAgaWYgKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicpIHtcbiAgICAgICAgdm5vZGUgPSB2bS4kb3B0aW9ucy5yZW5kZXJFcnJvclxuICAgICAgICAgID8gdm0uJG9wdGlvbnMucmVuZGVyRXJyb3IuY2FsbCh2bS5fcmVuZGVyUHJveHksIHZtLiRjcmVhdGVFbGVtZW50LCBlKVxuICAgICAgICAgIDogdm0uX3Zub2RlO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdm5vZGUgPSB2bS5fdm5vZGU7XG4gICAgICB9XG4gICAgfVxuICAgIC8vIHJldHVybiBlbXB0eSB2bm9kZSBpbiBjYXNlIHRoZSByZW5kZXIgZnVuY3Rpb24gZXJyb3JlZCBvdXRcbiAgICBpZiAoISh2bm9kZSBpbnN0YW5jZW9mIFZOb2RlKSkge1xuICAgICAgaWYgKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicgJiYgQXJyYXkuaXNBcnJheSh2bm9kZSkpIHtcbiAgICAgICAgd2FybihcbiAgICAgICAgICAnTXVsdGlwbGUgcm9vdCBub2RlcyByZXR1cm5lZCBmcm9tIHJlbmRlciBmdW5jdGlvbi4gUmVuZGVyIGZ1bmN0aW9uICcgK1xuICAgICAgICAgICdzaG91bGQgcmV0dXJuIGEgc2luZ2xlIHJvb3Qgbm9kZS4nLFxuICAgICAgICAgIHZtXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgICB2bm9kZSA9IGNyZWF0ZUVtcHR5Vk5vZGUoKTtcbiAgICB9XG4gICAgLy8gc2V0IHBhcmVudFxuICAgIHZub2RlLnBhcmVudCA9IF9wYXJlbnRWbm9kZTtcbiAgICByZXR1cm4gdm5vZGVcbiAgfTtcblxuICAvLyBpbnRlcm5hbCByZW5kZXIgaGVscGVycy5cbiAgLy8gdGhlc2UgYXJlIGV4cG9zZWQgb24gdGhlIGluc3RhbmNlIHByb3RvdHlwZSB0byByZWR1Y2UgZ2VuZXJhdGVkIHJlbmRlclxuICAvLyBjb2RlIHNpemUuXG4gIFZ1ZS5wcm90b3R5cGUuX28gPSBtYXJrT25jZTtcbiAgVnVlLnByb3RvdHlwZS5fbiA9IHRvTnVtYmVyO1xuICBWdWUucHJvdG90eXBlLl9zID0gdG9TdHJpbmc7XG4gIFZ1ZS5wcm90b3R5cGUuX2wgPSByZW5kZXJMaXN0O1xuICBWdWUucHJvdG90eXBlLl90ID0gcmVuZGVyU2xvdDtcbiAgVnVlLnByb3RvdHlwZS5fcSA9IGxvb3NlRXF1YWw7XG4gIFZ1ZS5wcm90b3R5cGUuX2kgPSBsb29zZUluZGV4T2Y7XG4gIFZ1ZS5wcm90b3R5cGUuX20gPSByZW5kZXJTdGF0aWM7XG4gIFZ1ZS5wcm90b3R5cGUuX2YgPSByZXNvbHZlRmlsdGVyO1xuICBWdWUucHJvdG90eXBlLl9rID0gY2hlY2tLZXlDb2RlcztcbiAgVnVlLnByb3RvdHlwZS5fYiA9IGJpbmRPYmplY3RQcm9wcztcbiAgVnVlLnByb3RvdHlwZS5fdiA9IGNyZWF0ZVRleHRWTm9kZTtcbiAgVnVlLnByb3RvdHlwZS5fZSA9IGNyZWF0ZUVtcHR5Vk5vZGU7XG4gIFZ1ZS5wcm90b3R5cGUuX3UgPSByZXNvbHZlU2NvcGVkU2xvdHM7XG4gIFZ1ZS5wcm90b3R5cGUuX2cgPSBiaW5kT2JqZWN0TGlzdGVuZXJzO1xufVxuXG4vKiAgKi9cblxudmFyIHVpZCQxID0gMDtcblxuZnVuY3Rpb24gaW5pdE1peGluIChWdWUpIHtcbiAgVnVlLnByb3RvdHlwZS5faW5pdCA9IGZ1bmN0aW9uIChvcHRpb25zKSB7XG4gICAgdmFyIHZtID0gdGhpcztcbiAgICAvLyBhIHVpZFxuICAgIHZtLl91aWQgPSB1aWQkMSsrO1xuXG4gICAgdmFyIHN0YXJ0VGFnLCBlbmRUYWc7XG4gICAgLyogaXN0YW5idWwgaWdub3JlIGlmICovXG4gICAgaWYgKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicgJiYgY29uZmlnLnBlcmZvcm1hbmNlICYmIG1hcmspIHtcbiAgICAgIHN0YXJ0VGFnID0gXCJ2dWUtcGVyZi1pbml0OlwiICsgKHZtLl91aWQpO1xuICAgICAgZW5kVGFnID0gXCJ2dWUtcGVyZi1lbmQ6XCIgKyAodm0uX3VpZCk7XG4gICAgICBtYXJrKHN0YXJ0VGFnKTtcbiAgICB9XG5cbiAgICAvLyBhIGZsYWcgdG8gYXZvaWQgdGhpcyBiZWluZyBvYnNlcnZlZFxuICAgIHZtLl9pc1Z1ZSA9IHRydWU7XG4gICAgLy8gbWVyZ2Ugb3B0aW9uc1xuICAgIGlmIChvcHRpb25zICYmIG9wdGlvbnMuX2lzQ29tcG9uZW50KSB7XG4gICAgICAvLyBvcHRpbWl6ZSBpbnRlcm5hbCBjb21wb25lbnQgaW5zdGFudGlhdGlvblxuICAgICAgLy8gc2luY2UgZHluYW1pYyBvcHRpb25zIG1lcmdpbmcgaXMgcHJldHR5IHNsb3csIGFuZCBub25lIG9mIHRoZVxuICAgICAgLy8gaW50ZXJuYWwgY29tcG9uZW50IG9wdGlvbnMgbmVlZHMgc3BlY2lhbCB0cmVhdG1lbnQuXG4gICAgICBpbml0SW50ZXJuYWxDb21wb25lbnQodm0sIG9wdGlvbnMpO1xuICAgIH0gZWxzZSB7XG4gICAgICB2bS4kb3B0aW9ucyA9IG1lcmdlT3B0aW9ucyhcbiAgICAgICAgcmVzb2x2ZUNvbnN0cnVjdG9yT3B0aW9ucyh2bS5jb25zdHJ1Y3RvciksXG4gICAgICAgIG9wdGlvbnMgfHwge30sXG4gICAgICAgIHZtXG4gICAgICApO1xuICAgIH1cbiAgICAvKiBpc3RhbmJ1bCBpZ25vcmUgZWxzZSAqL1xuICAgIGlmIChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nKSB7XG4gICAgICBpbml0UHJveHkodm0pO1xuICAgIH0gZWxzZSB7XG4gICAgICB2bS5fcmVuZGVyUHJveHkgPSB2bTtcbiAgICB9XG4gICAgLy8gZXhwb3NlIHJlYWwgc2VsZlxuICAgIHZtLl9zZWxmID0gdm07XG4gICAgaW5pdExpZmVjeWNsZSh2bSk7XG4gICAgaW5pdEV2ZW50cyh2bSk7XG4gICAgaW5pdFJlbmRlcih2bSk7XG4gICAgY2FsbEhvb2sodm0sICdiZWZvcmVDcmVhdGUnKTtcbiAgICBpbml0SW5qZWN0aW9ucyh2bSk7IC8vIHJlc29sdmUgaW5qZWN0aW9ucyBiZWZvcmUgZGF0YS9wcm9wc1xuICAgIGluaXRTdGF0ZSh2bSk7XG4gICAgaW5pdFByb3ZpZGUodm0pOyAvLyByZXNvbHZlIHByb3ZpZGUgYWZ0ZXIgZGF0YS9wcm9wc1xuICAgIGNhbGxIb29rKHZtLCAnY3JlYXRlZCcpO1xuXG4gICAgLyogaXN0YW5idWwgaWdub3JlIGlmICovXG4gICAgaWYgKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicgJiYgY29uZmlnLnBlcmZvcm1hbmNlICYmIG1hcmspIHtcbiAgICAgIHZtLl9uYW1lID0gZm9ybWF0Q29tcG9uZW50TmFtZSh2bSwgZmFsc2UpO1xuICAgICAgbWFyayhlbmRUYWcpO1xuICAgICAgbWVhc3VyZSgoKHZtLl9uYW1lKSArIFwiIGluaXRcIiksIHN0YXJ0VGFnLCBlbmRUYWcpO1xuICAgIH1cblxuICAgIGlmICh2bS4kb3B0aW9ucy5lbCkge1xuICAgICAgdm0uJG1vdW50KHZtLiRvcHRpb25zLmVsKTtcbiAgICB9XG4gIH07XG59XG5cbmZ1bmN0aW9uIGluaXRJbnRlcm5hbENvbXBvbmVudCAodm0sIG9wdGlvbnMpIHtcbiAgdmFyIG9wdHMgPSB2bS4kb3B0aW9ucyA9IE9iamVjdC5jcmVhdGUodm0uY29uc3RydWN0b3Iub3B0aW9ucyk7XG4gIC8vIGRvaW5nIHRoaXMgYmVjYXVzZSBpdCdzIGZhc3RlciB0aGFuIGR5bmFtaWMgZW51bWVyYXRpb24uXG4gIG9wdHMucGFyZW50ID0gb3B0aW9ucy5wYXJlbnQ7XG4gIG9wdHMucHJvcHNEYXRhID0gb3B0aW9ucy5wcm9wc0RhdGE7XG4gIG9wdHMuX3BhcmVudFZub2RlID0gb3B0aW9ucy5fcGFyZW50Vm5vZGU7XG4gIG9wdHMuX3BhcmVudExpc3RlbmVycyA9IG9wdGlvbnMuX3BhcmVudExpc3RlbmVycztcbiAgb3B0cy5fcmVuZGVyQ2hpbGRyZW4gPSBvcHRpb25zLl9yZW5kZXJDaGlsZHJlbjtcbiAgb3B0cy5fY29tcG9uZW50VGFnID0gb3B0aW9ucy5fY29tcG9uZW50VGFnO1xuICBvcHRzLl9wYXJlbnRFbG0gPSBvcHRpb25zLl9wYXJlbnRFbG07XG4gIG9wdHMuX3JlZkVsbSA9IG9wdGlvbnMuX3JlZkVsbTtcbiAgaWYgKG9wdGlvbnMucmVuZGVyKSB7XG4gICAgb3B0cy5yZW5kZXIgPSBvcHRpb25zLnJlbmRlcjtcbiAgICBvcHRzLnN0YXRpY1JlbmRlckZucyA9IG9wdGlvbnMuc3RhdGljUmVuZGVyRm5zO1xuICB9XG59XG5cbmZ1bmN0aW9uIHJlc29sdmVDb25zdHJ1Y3Rvck9wdGlvbnMgKEN0b3IpIHtcbiAgdmFyIG9wdGlvbnMgPSBDdG9yLm9wdGlvbnM7XG4gIGlmIChDdG9yLnN1cGVyKSB7XG4gICAgdmFyIHN1cGVyT3B0aW9ucyA9IHJlc29sdmVDb25zdHJ1Y3Rvck9wdGlvbnMoQ3Rvci5zdXBlcik7XG4gICAgdmFyIGNhY2hlZFN1cGVyT3B0aW9ucyA9IEN0b3Iuc3VwZXJPcHRpb25zO1xuICAgIGlmIChzdXBlck9wdGlvbnMgIT09IGNhY2hlZFN1cGVyT3B0aW9ucykge1xuICAgICAgLy8gc3VwZXIgb3B0aW9uIGNoYW5nZWQsXG4gICAgICAvLyBuZWVkIHRvIHJlc29sdmUgbmV3IG9wdGlvbnMuXG4gICAgICBDdG9yLnN1cGVyT3B0aW9ucyA9IHN1cGVyT3B0aW9ucztcbiAgICAgIC8vIGNoZWNrIGlmIHRoZXJlIGFyZSBhbnkgbGF0ZS1tb2RpZmllZC9hdHRhY2hlZCBvcHRpb25zICgjNDk3NilcbiAgICAgIHZhciBtb2RpZmllZE9wdGlvbnMgPSByZXNvbHZlTW9kaWZpZWRPcHRpb25zKEN0b3IpO1xuICAgICAgLy8gdXBkYXRlIGJhc2UgZXh0ZW5kIG9wdGlvbnNcbiAgICAgIGlmIChtb2RpZmllZE9wdGlvbnMpIHtcbiAgICAgICAgZXh0ZW5kKEN0b3IuZXh0ZW5kT3B0aW9ucywgbW9kaWZpZWRPcHRpb25zKTtcbiAgICAgIH1cbiAgICAgIG9wdGlvbnMgPSBDdG9yLm9wdGlvbnMgPSBtZXJnZU9wdGlvbnMoc3VwZXJPcHRpb25zLCBDdG9yLmV4dGVuZE9wdGlvbnMpO1xuICAgICAgaWYgKG9wdGlvbnMubmFtZSkge1xuICAgICAgICBvcHRpb25zLmNvbXBvbmVudHNbb3B0aW9ucy5uYW1lXSA9IEN0b3I7XG4gICAgICB9XG4gICAgfVxuICB9XG4gIHJldHVybiBvcHRpb25zXG59XG5cbmZ1bmN0aW9uIHJlc29sdmVNb2RpZmllZE9wdGlvbnMgKEN0b3IpIHtcbiAgdmFyIG1vZGlmaWVkO1xuICB2YXIgbGF0ZXN0ID0gQ3Rvci5vcHRpb25zO1xuICB2YXIgZXh0ZW5kZWQgPSBDdG9yLmV4dGVuZE9wdGlvbnM7XG4gIHZhciBzZWFsZWQgPSBDdG9yLnNlYWxlZE9wdGlvbnM7XG4gIGZvciAodmFyIGtleSBpbiBsYXRlc3QpIHtcbiAgICBpZiAobGF0ZXN0W2tleV0gIT09IHNlYWxlZFtrZXldKSB7XG4gICAgICBpZiAoIW1vZGlmaWVkKSB7IG1vZGlmaWVkID0ge307IH1cbiAgICAgIG1vZGlmaWVkW2tleV0gPSBkZWR1cGUobGF0ZXN0W2tleV0sIGV4dGVuZGVkW2tleV0sIHNlYWxlZFtrZXldKTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIG1vZGlmaWVkXG59XG5cbmZ1bmN0aW9uIGRlZHVwZSAobGF0ZXN0LCBleHRlbmRlZCwgc2VhbGVkKSB7XG4gIC8vIGNvbXBhcmUgbGF0ZXN0IGFuZCBzZWFsZWQgdG8gZW5zdXJlIGxpZmVjeWNsZSBob29rcyB3b24ndCBiZSBkdXBsaWNhdGVkXG4gIC8vIGJldHdlZW4gbWVyZ2VzXG4gIGlmIChBcnJheS5pc0FycmF5KGxhdGVzdCkpIHtcbiAgICB2YXIgcmVzID0gW107XG4gICAgc2VhbGVkID0gQXJyYXkuaXNBcnJheShzZWFsZWQpID8gc2VhbGVkIDogW3NlYWxlZF07XG4gICAgZXh0ZW5kZWQgPSBBcnJheS5pc0FycmF5KGV4dGVuZGVkKSA/IGV4dGVuZGVkIDogW2V4dGVuZGVkXTtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGxhdGVzdC5sZW5ndGg7IGkrKykge1xuICAgICAgLy8gcHVzaCBvcmlnaW5hbCBvcHRpb25zIGFuZCBub3Qgc2VhbGVkIG9wdGlvbnMgdG8gZXhjbHVkZSBkdXBsaWNhdGVkIG9wdGlvbnNcbiAgICAgIGlmIChleHRlbmRlZC5pbmRleE9mKGxhdGVzdFtpXSkgPj0gMCB8fCBzZWFsZWQuaW5kZXhPZihsYXRlc3RbaV0pIDwgMCkge1xuICAgICAgICByZXMucHVzaChsYXRlc3RbaV0pO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gcmVzXG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIGxhdGVzdFxuICB9XG59XG5cbmZ1bmN0aW9uIFZ1ZSQzIChvcHRpb25zKSB7XG4gIGlmIChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nICYmXG4gICAgISh0aGlzIGluc3RhbmNlb2YgVnVlJDMpXG4gICkge1xuICAgIHdhcm4oJ1Z1ZSBpcyBhIGNvbnN0cnVjdG9yIGFuZCBzaG91bGQgYmUgY2FsbGVkIHdpdGggdGhlIGBuZXdgIGtleXdvcmQnKTtcbiAgfVxuICB0aGlzLl9pbml0KG9wdGlvbnMpO1xufVxuXG5pbml0TWl4aW4oVnVlJDMpO1xuc3RhdGVNaXhpbihWdWUkMyk7XG5ldmVudHNNaXhpbihWdWUkMyk7XG5saWZlY3ljbGVNaXhpbihWdWUkMyk7XG5yZW5kZXJNaXhpbihWdWUkMyk7XG5cbi8qICAqL1xuXG5mdW5jdGlvbiBpbml0VXNlIChWdWUpIHtcbiAgVnVlLnVzZSA9IGZ1bmN0aW9uIChwbHVnaW4pIHtcbiAgICB2YXIgaW5zdGFsbGVkUGx1Z2lucyA9ICh0aGlzLl9pbnN0YWxsZWRQbHVnaW5zIHx8ICh0aGlzLl9pbnN0YWxsZWRQbHVnaW5zID0gW10pKTtcbiAgICBpZiAoaW5zdGFsbGVkUGx1Z2lucy5pbmRleE9mKHBsdWdpbikgPiAtMSkge1xuICAgICAgcmV0dXJuIHRoaXNcbiAgICB9XG5cbiAgICAvLyBhZGRpdGlvbmFsIHBhcmFtZXRlcnNcbiAgICB2YXIgYXJncyA9IHRvQXJyYXkoYXJndW1lbnRzLCAxKTtcbiAgICBhcmdzLnVuc2hpZnQodGhpcyk7XG4gICAgaWYgKHR5cGVvZiBwbHVnaW4uaW5zdGFsbCA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgcGx1Z2luLmluc3RhbGwuYXBwbHkocGx1Z2luLCBhcmdzKTtcbiAgICB9IGVsc2UgaWYgKHR5cGVvZiBwbHVnaW4gPT09ICdmdW5jdGlvbicpIHtcbiAgICAgIHBsdWdpbi5hcHBseShudWxsLCBhcmdzKTtcbiAgICB9XG4gICAgaW5zdGFsbGVkUGx1Z2lucy5wdXNoKHBsdWdpbik7XG4gICAgcmV0dXJuIHRoaXNcbiAgfTtcbn1cblxuLyogICovXG5cbmZ1bmN0aW9uIGluaXRNaXhpbiQxIChWdWUpIHtcbiAgVnVlLm1peGluID0gZnVuY3Rpb24gKG1peGluKSB7XG4gICAgdGhpcy5vcHRpb25zID0gbWVyZ2VPcHRpb25zKHRoaXMub3B0aW9ucywgbWl4aW4pO1xuICAgIHJldHVybiB0aGlzXG4gIH07XG59XG5cbi8qICAqL1xuXG5mdW5jdGlvbiBpbml0RXh0ZW5kIChWdWUpIHtcbiAgLyoqXG4gICAqIEVhY2ggaW5zdGFuY2UgY29uc3RydWN0b3IsIGluY2x1ZGluZyBWdWUsIGhhcyBhIHVuaXF1ZVxuICAgKiBjaWQuIFRoaXMgZW5hYmxlcyB1cyB0byBjcmVhdGUgd3JhcHBlZCBcImNoaWxkXG4gICAqIGNvbnN0cnVjdG9yc1wiIGZvciBwcm90b3R5cGFsIGluaGVyaXRhbmNlIGFuZCBjYWNoZSB0aGVtLlxuICAgKi9cbiAgVnVlLmNpZCA9IDA7XG4gIHZhciBjaWQgPSAxO1xuXG4gIC8qKlxuICAgKiBDbGFzcyBpbmhlcml0YW5jZVxuICAgKi9cbiAgVnVlLmV4dGVuZCA9IGZ1bmN0aW9uIChleHRlbmRPcHRpb25zKSB7XG4gICAgZXh0ZW5kT3B0aW9ucyA9IGV4dGVuZE9wdGlvbnMgfHwge307XG4gICAgdmFyIFN1cGVyID0gdGhpcztcbiAgICB2YXIgU3VwZXJJZCA9IFN1cGVyLmNpZDtcbiAgICB2YXIgY2FjaGVkQ3RvcnMgPSBleHRlbmRPcHRpb25zLl9DdG9yIHx8IChleHRlbmRPcHRpb25zLl9DdG9yID0ge30pO1xuICAgIGlmIChjYWNoZWRDdG9yc1tTdXBlcklkXSkge1xuICAgICAgcmV0dXJuIGNhY2hlZEN0b3JzW1N1cGVySWRdXG4gICAgfVxuXG4gICAgdmFyIG5hbWUgPSBleHRlbmRPcHRpb25zLm5hbWUgfHwgU3VwZXIub3B0aW9ucy5uYW1lO1xuICAgIGlmIChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nKSB7XG4gICAgICBpZiAoIS9eW2EtekEtWl1bXFx3LV0qJC8udGVzdChuYW1lKSkge1xuICAgICAgICB3YXJuKFxuICAgICAgICAgICdJbnZhbGlkIGNvbXBvbmVudCBuYW1lOiBcIicgKyBuYW1lICsgJ1wiLiBDb21wb25lbnQgbmFtZXMgJyArXG4gICAgICAgICAgJ2NhbiBvbmx5IGNvbnRhaW4gYWxwaGFudW1lcmljIGNoYXJhY3RlcnMgYW5kIHRoZSBoeXBoZW4sICcgK1xuICAgICAgICAgICdhbmQgbXVzdCBzdGFydCB3aXRoIGEgbGV0dGVyLidcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICB2YXIgU3ViID0gZnVuY3Rpb24gVnVlQ29tcG9uZW50IChvcHRpb25zKSB7XG4gICAgICB0aGlzLl9pbml0KG9wdGlvbnMpO1xuICAgIH07XG4gICAgU3ViLnByb3RvdHlwZSA9IE9iamVjdC5jcmVhdGUoU3VwZXIucHJvdG90eXBlKTtcbiAgICBTdWIucHJvdG90eXBlLmNvbnN0cnVjdG9yID0gU3ViO1xuICAgIFN1Yi5jaWQgPSBjaWQrKztcbiAgICBTdWIub3B0aW9ucyA9IG1lcmdlT3B0aW9ucyhcbiAgICAgIFN1cGVyLm9wdGlvbnMsXG4gICAgICBleHRlbmRPcHRpb25zXG4gICAgKTtcbiAgICBTdWJbJ3N1cGVyJ10gPSBTdXBlcjtcblxuICAgIC8vIEZvciBwcm9wcyBhbmQgY29tcHV0ZWQgcHJvcGVydGllcywgd2UgZGVmaW5lIHRoZSBwcm94eSBnZXR0ZXJzIG9uXG4gICAgLy8gdGhlIFZ1ZSBpbnN0YW5jZXMgYXQgZXh0ZW5zaW9uIHRpbWUsIG9uIHRoZSBleHRlbmRlZCBwcm90b3R5cGUuIFRoaXNcbiAgICAvLyBhdm9pZHMgT2JqZWN0LmRlZmluZVByb3BlcnR5IGNhbGxzIGZvciBlYWNoIGluc3RhbmNlIGNyZWF0ZWQuXG4gICAgaWYgKFN1Yi5vcHRpb25zLnByb3BzKSB7XG4gICAgICBpbml0UHJvcHMkMShTdWIpO1xuICAgIH1cbiAgICBpZiAoU3ViLm9wdGlvbnMuY29tcHV0ZWQpIHtcbiAgICAgIGluaXRDb21wdXRlZCQxKFN1Yik7XG4gICAgfVxuXG4gICAgLy8gYWxsb3cgZnVydGhlciBleHRlbnNpb24vbWl4aW4vcGx1Z2luIHVzYWdlXG4gICAgU3ViLmV4dGVuZCA9IFN1cGVyLmV4dGVuZDtcbiAgICBTdWIubWl4aW4gPSBTdXBlci5taXhpbjtcbiAgICBTdWIudXNlID0gU3VwZXIudXNlO1xuXG4gICAgLy8gY3JlYXRlIGFzc2V0IHJlZ2lzdGVycywgc28gZXh0ZW5kZWQgY2xhc3Nlc1xuICAgIC8vIGNhbiBoYXZlIHRoZWlyIHByaXZhdGUgYXNzZXRzIHRvby5cbiAgICBBU1NFVF9UWVBFUy5mb3JFYWNoKGZ1bmN0aW9uICh0eXBlKSB7XG4gICAgICBTdWJbdHlwZV0gPSBTdXBlclt0eXBlXTtcbiAgICB9KTtcbiAgICAvLyBlbmFibGUgcmVjdXJzaXZlIHNlbGYtbG9va3VwXG4gICAgaWYgKG5hbWUpIHtcbiAgICAgIFN1Yi5vcHRpb25zLmNvbXBvbmVudHNbbmFtZV0gPSBTdWI7XG4gICAgfVxuXG4gICAgLy8ga2VlcCBhIHJlZmVyZW5jZSB0byB0aGUgc3VwZXIgb3B0aW9ucyBhdCBleHRlbnNpb24gdGltZS5cbiAgICAvLyBsYXRlciBhdCBpbnN0YW50aWF0aW9uIHdlIGNhbiBjaGVjayBpZiBTdXBlcidzIG9wdGlvbnMgaGF2ZVxuICAgIC8vIGJlZW4gdXBkYXRlZC5cbiAgICBTdWIuc3VwZXJPcHRpb25zID0gU3VwZXIub3B0aW9ucztcbiAgICBTdWIuZXh0ZW5kT3B0aW9ucyA9IGV4dGVuZE9wdGlvbnM7XG4gICAgU3ViLnNlYWxlZE9wdGlvbnMgPSBleHRlbmQoe30sIFN1Yi5vcHRpb25zKTtcblxuICAgIC8vIGNhY2hlIGNvbnN0cnVjdG9yXG4gICAgY2FjaGVkQ3RvcnNbU3VwZXJJZF0gPSBTdWI7XG4gICAgcmV0dXJuIFN1YlxuICB9O1xufVxuXG5mdW5jdGlvbiBpbml0UHJvcHMkMSAoQ29tcCkge1xuICB2YXIgcHJvcHMgPSBDb21wLm9wdGlvbnMucHJvcHM7XG4gIGZvciAodmFyIGtleSBpbiBwcm9wcykge1xuICAgIHByb3h5KENvbXAucHJvdG90eXBlLCBcIl9wcm9wc1wiLCBrZXkpO1xuICB9XG59XG5cbmZ1bmN0aW9uIGluaXRDb21wdXRlZCQxIChDb21wKSB7XG4gIHZhciBjb21wdXRlZCA9IENvbXAub3B0aW9ucy5jb21wdXRlZDtcbiAgZm9yICh2YXIga2V5IGluIGNvbXB1dGVkKSB7XG4gICAgZGVmaW5lQ29tcHV0ZWQoQ29tcC5wcm90b3R5cGUsIGtleSwgY29tcHV0ZWRba2V5XSk7XG4gIH1cbn1cblxuLyogICovXG5cbmZ1bmN0aW9uIGluaXRBc3NldFJlZ2lzdGVycyAoVnVlKSB7XG4gIC8qKlxuICAgKiBDcmVhdGUgYXNzZXQgcmVnaXN0cmF0aW9uIG1ldGhvZHMuXG4gICAqL1xuICBBU1NFVF9UWVBFUy5mb3JFYWNoKGZ1bmN0aW9uICh0eXBlKSB7XG4gICAgVnVlW3R5cGVdID0gZnVuY3Rpb24gKFxuICAgICAgaWQsXG4gICAgICBkZWZpbml0aW9uXG4gICAgKSB7XG4gICAgICBpZiAoIWRlZmluaXRpb24pIHtcbiAgICAgICAgcmV0dXJuIHRoaXMub3B0aW9uc1t0eXBlICsgJ3MnXVtpZF1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIC8qIGlzdGFuYnVsIGlnbm9yZSBpZiAqL1xuICAgICAgICBpZiAocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJykge1xuICAgICAgICAgIGlmICh0eXBlID09PSAnY29tcG9uZW50JyAmJiBjb25maWcuaXNSZXNlcnZlZFRhZyhpZCkpIHtcbiAgICAgICAgICAgIHdhcm4oXG4gICAgICAgICAgICAgICdEbyBub3QgdXNlIGJ1aWx0LWluIG9yIHJlc2VydmVkIEhUTUwgZWxlbWVudHMgYXMgY29tcG9uZW50ICcgK1xuICAgICAgICAgICAgICAnaWQ6ICcgKyBpZFxuICAgICAgICAgICAgKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHR5cGUgPT09ICdjb21wb25lbnQnICYmIGlzUGxhaW5PYmplY3QoZGVmaW5pdGlvbikpIHtcbiAgICAgICAgICBkZWZpbml0aW9uLm5hbWUgPSBkZWZpbml0aW9uLm5hbWUgfHwgaWQ7XG4gICAgICAgICAgZGVmaW5pdGlvbiA9IHRoaXMub3B0aW9ucy5fYmFzZS5leHRlbmQoZGVmaW5pdGlvbik7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHR5cGUgPT09ICdkaXJlY3RpdmUnICYmIHR5cGVvZiBkZWZpbml0aW9uID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgZGVmaW5pdGlvbiA9IHsgYmluZDogZGVmaW5pdGlvbiwgdXBkYXRlOiBkZWZpbml0aW9uIH07XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5vcHRpb25zW3R5cGUgKyAncyddW2lkXSA9IGRlZmluaXRpb247XG4gICAgICAgIHJldHVybiBkZWZpbml0aW9uXG4gICAgICB9XG4gICAgfTtcbiAgfSk7XG59XG5cbi8qICAqL1xuXG52YXIgcGF0dGVyblR5cGVzID0gW1N0cmluZywgUmVnRXhwLCBBcnJheV07XG5cbmZ1bmN0aW9uIGdldENvbXBvbmVudE5hbWUgKG9wdHMpIHtcbiAgcmV0dXJuIG9wdHMgJiYgKG9wdHMuQ3Rvci5vcHRpb25zLm5hbWUgfHwgb3B0cy50YWcpXG59XG5cbmZ1bmN0aW9uIG1hdGNoZXMgKHBhdHRlcm4sIG5hbWUpIHtcbiAgaWYgKEFycmF5LmlzQXJyYXkocGF0dGVybikpIHtcbiAgICByZXR1cm4gcGF0dGVybi5pbmRleE9mKG5hbWUpID4gLTFcbiAgfSBlbHNlIGlmICh0eXBlb2YgcGF0dGVybiA9PT0gJ3N0cmluZycpIHtcbiAgICByZXR1cm4gcGF0dGVybi5zcGxpdCgnLCcpLmluZGV4T2YobmFtZSkgPiAtMVxuICB9IGVsc2UgaWYgKGlzUmVnRXhwKHBhdHRlcm4pKSB7XG4gICAgcmV0dXJuIHBhdHRlcm4udGVzdChuYW1lKVxuICB9XG4gIC8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0ICovXG4gIHJldHVybiBmYWxzZVxufVxuXG5mdW5jdGlvbiBwcnVuZUNhY2hlIChjYWNoZSwgY3VycmVudCwgZmlsdGVyKSB7XG4gIGZvciAodmFyIGtleSBpbiBjYWNoZSkge1xuICAgIHZhciBjYWNoZWROb2RlID0gY2FjaGVba2V5XTtcbiAgICBpZiAoY2FjaGVkTm9kZSkge1xuICAgICAgdmFyIG5hbWUgPSBnZXRDb21wb25lbnROYW1lKGNhY2hlZE5vZGUuY29tcG9uZW50T3B0aW9ucyk7XG4gICAgICBpZiAobmFtZSAmJiAhZmlsdGVyKG5hbWUpKSB7XG4gICAgICAgIGlmIChjYWNoZWROb2RlICE9PSBjdXJyZW50KSB7XG4gICAgICAgICAgcHJ1bmVDYWNoZUVudHJ5KGNhY2hlZE5vZGUpO1xuICAgICAgICB9XG4gICAgICAgIGNhY2hlW2tleV0gPSBudWxsO1xuICAgICAgfVxuICAgIH1cbiAgfVxufVxuXG5mdW5jdGlvbiBwcnVuZUNhY2hlRW50cnkgKHZub2RlKSB7XG4gIGlmICh2bm9kZSkge1xuICAgIHZub2RlLmNvbXBvbmVudEluc3RhbmNlLiRkZXN0cm95KCk7XG4gIH1cbn1cblxudmFyIEtlZXBBbGl2ZSA9IHtcbiAgbmFtZTogJ2tlZXAtYWxpdmUnLFxuICBhYnN0cmFjdDogdHJ1ZSxcblxuICBwcm9wczoge1xuICAgIGluY2x1ZGU6IHBhdHRlcm5UeXBlcyxcbiAgICBleGNsdWRlOiBwYXR0ZXJuVHlwZXNcbiAgfSxcblxuICBjcmVhdGVkOiBmdW5jdGlvbiBjcmVhdGVkICgpIHtcbiAgICB0aGlzLmNhY2hlID0gT2JqZWN0LmNyZWF0ZShudWxsKTtcbiAgfSxcblxuICBkZXN0cm95ZWQ6IGZ1bmN0aW9uIGRlc3Ryb3llZCAoKSB7XG4gICAgdmFyIHRoaXMkMSA9IHRoaXM7XG5cbiAgICBmb3IgKHZhciBrZXkgaW4gdGhpcyQxLmNhY2hlKSB7XG4gICAgICBwcnVuZUNhY2hlRW50cnkodGhpcyQxLmNhY2hlW2tleV0pO1xuICAgIH1cbiAgfSxcblxuICB3YXRjaDoge1xuICAgIGluY2x1ZGU6IGZ1bmN0aW9uIGluY2x1ZGUgKHZhbCkge1xuICAgICAgcHJ1bmVDYWNoZSh0aGlzLmNhY2hlLCB0aGlzLl92bm9kZSwgZnVuY3Rpb24gKG5hbWUpIHsgcmV0dXJuIG1hdGNoZXModmFsLCBuYW1lKTsgfSk7XG4gICAgfSxcbiAgICBleGNsdWRlOiBmdW5jdGlvbiBleGNsdWRlICh2YWwpIHtcbiAgICAgIHBydW5lQ2FjaGUodGhpcy5jYWNoZSwgdGhpcy5fdm5vZGUsIGZ1bmN0aW9uIChuYW1lKSB7IHJldHVybiAhbWF0Y2hlcyh2YWwsIG5hbWUpOyB9KTtcbiAgICB9XG4gIH0sXG5cbiAgcmVuZGVyOiBmdW5jdGlvbiByZW5kZXIgKCkge1xuICAgIHZhciB2bm9kZSA9IGdldEZpcnN0Q29tcG9uZW50Q2hpbGQodGhpcy4kc2xvdHMuZGVmYXVsdCk7XG4gICAgdmFyIGNvbXBvbmVudE9wdGlvbnMgPSB2bm9kZSAmJiB2bm9kZS5jb21wb25lbnRPcHRpb25zO1xuICAgIGlmIChjb21wb25lbnRPcHRpb25zKSB7XG4gICAgICAvLyBjaGVjayBwYXR0ZXJuXG4gICAgICB2YXIgbmFtZSA9IGdldENvbXBvbmVudE5hbWUoY29tcG9uZW50T3B0aW9ucyk7XG4gICAgICBpZiAobmFtZSAmJiAoXG4gICAgICAgICh0aGlzLmluY2x1ZGUgJiYgIW1hdGNoZXModGhpcy5pbmNsdWRlLCBuYW1lKSkgfHxcbiAgICAgICAgKHRoaXMuZXhjbHVkZSAmJiBtYXRjaGVzKHRoaXMuZXhjbHVkZSwgbmFtZSkpXG4gICAgICApKSB7XG4gICAgICAgIHJldHVybiB2bm9kZVxuICAgICAgfVxuICAgICAgdmFyIGtleSA9IHZub2RlLmtleSA9PSBudWxsXG4gICAgICAgIC8vIHNhbWUgY29uc3RydWN0b3IgbWF5IGdldCByZWdpc3RlcmVkIGFzIGRpZmZlcmVudCBsb2NhbCBjb21wb25lbnRzXG4gICAgICAgIC8vIHNvIGNpZCBhbG9uZSBpcyBub3QgZW5vdWdoICgjMzI2OSlcbiAgICAgICAgPyBjb21wb25lbnRPcHRpb25zLkN0b3IuY2lkICsgKGNvbXBvbmVudE9wdGlvbnMudGFnID8gKFwiOjpcIiArIChjb21wb25lbnRPcHRpb25zLnRhZykpIDogJycpXG4gICAgICAgIDogdm5vZGUua2V5O1xuICAgICAgaWYgKHRoaXMuY2FjaGVba2V5XSkge1xuICAgICAgICB2bm9kZS5jb21wb25lbnRJbnN0YW5jZSA9IHRoaXMuY2FjaGVba2V5XS5jb21wb25lbnRJbnN0YW5jZTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMuY2FjaGVba2V5XSA9IHZub2RlO1xuICAgICAgfVxuICAgICAgdm5vZGUuZGF0YS5rZWVwQWxpdmUgPSB0cnVlO1xuICAgIH1cbiAgICByZXR1cm4gdm5vZGVcbiAgfVxufTtcblxudmFyIGJ1aWx0SW5Db21wb25lbnRzID0ge1xuICBLZWVwQWxpdmU6IEtlZXBBbGl2ZVxufTtcblxuLyogICovXG5cbmZ1bmN0aW9uIGluaXRHbG9iYWxBUEkgKFZ1ZSkge1xuICAvLyBjb25maWdcbiAgdmFyIGNvbmZpZ0RlZiA9IHt9O1xuICBjb25maWdEZWYuZ2V0ID0gZnVuY3Rpb24gKCkgeyByZXR1cm4gY29uZmlnOyB9O1xuICBpZiAocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJykge1xuICAgIGNvbmZpZ0RlZi5zZXQgPSBmdW5jdGlvbiAoKSB7XG4gICAgICB3YXJuKFxuICAgICAgICAnRG8gbm90IHJlcGxhY2UgdGhlIFZ1ZS5jb25maWcgb2JqZWN0LCBzZXQgaW5kaXZpZHVhbCBmaWVsZHMgaW5zdGVhZC4nXG4gICAgICApO1xuICAgIH07XG4gIH1cbiAgT2JqZWN0LmRlZmluZVByb3BlcnR5KFZ1ZSwgJ2NvbmZpZycsIGNvbmZpZ0RlZik7XG5cbiAgLy8gZXhwb3NlZCB1dGlsIG1ldGhvZHMuXG4gIC8vIE5PVEU6IHRoZXNlIGFyZSBub3QgY29uc2lkZXJlZCBwYXJ0IG9mIHRoZSBwdWJsaWMgQVBJIC0gYXZvaWQgcmVseWluZyBvblxuICAvLyB0aGVtIHVubGVzcyB5b3UgYXJlIGF3YXJlIG9mIHRoZSByaXNrLlxuICBWdWUudXRpbCA9IHtcbiAgICB3YXJuOiB3YXJuLFxuICAgIGV4dGVuZDogZXh0ZW5kLFxuICAgIG1lcmdlT3B0aW9uczogbWVyZ2VPcHRpb25zLFxuICAgIGRlZmluZVJlYWN0aXZlOiBkZWZpbmVSZWFjdGl2ZSQkMVxuICB9O1xuXG4gIFZ1ZS5zZXQgPSBzZXQ7XG4gIFZ1ZS5kZWxldGUgPSBkZWw7XG4gIFZ1ZS5uZXh0VGljayA9IG5leHRUaWNrO1xuXG4gIFZ1ZS5vcHRpb25zID0gT2JqZWN0LmNyZWF0ZShudWxsKTtcbiAgQVNTRVRfVFlQRVMuZm9yRWFjaChmdW5jdGlvbiAodHlwZSkge1xuICAgIFZ1ZS5vcHRpb25zW3R5cGUgKyAncyddID0gT2JqZWN0LmNyZWF0ZShudWxsKTtcbiAgfSk7XG5cbiAgLy8gdGhpcyBpcyB1c2VkIHRvIGlkZW50aWZ5IHRoZSBcImJhc2VcIiBjb25zdHJ1Y3RvciB0byBleHRlbmQgYWxsIHBsYWluLW9iamVjdFxuICAvLyBjb21wb25lbnRzIHdpdGggaW4gV2VleCdzIG11bHRpLWluc3RhbmNlIHNjZW5hcmlvcy5cbiAgVnVlLm9wdGlvbnMuX2Jhc2UgPSBWdWU7XG5cbiAgZXh0ZW5kKFZ1ZS5vcHRpb25zLmNvbXBvbmVudHMsIGJ1aWx0SW5Db21wb25lbnRzKTtcblxuICBpbml0VXNlKFZ1ZSk7XG4gIGluaXRNaXhpbiQxKFZ1ZSk7XG4gIGluaXRFeHRlbmQoVnVlKTtcbiAgaW5pdEFzc2V0UmVnaXN0ZXJzKFZ1ZSk7XG59XG5cbmluaXRHbG9iYWxBUEkoVnVlJDMpO1xuXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoVnVlJDMucHJvdG90eXBlLCAnJGlzU2VydmVyJywge1xuICBnZXQ6IGlzU2VydmVyUmVuZGVyaW5nXG59KTtcblxuT2JqZWN0LmRlZmluZVByb3BlcnR5KFZ1ZSQzLnByb3RvdHlwZSwgJyRzc3JDb250ZXh0Jywge1xuICBnZXQ6IGZ1bmN0aW9uIGdldCAoKSB7XG4gICAgLyogaXN0YW5idWwgaWdub3JlIG5leHQgKi9cbiAgICByZXR1cm4gdGhpcy4kdm5vZGUgJiYgdGhpcy4kdm5vZGUuc3NyQ29udGV4dFxuICB9XG59KTtcblxuVnVlJDMudmVyc2lvbiA9ICcyLjQuNCc7XG5cbi8qICAqL1xuXG4vLyB0aGVzZSBhcmUgcmVzZXJ2ZWQgZm9yIHdlYiBiZWNhdXNlIHRoZXkgYXJlIGRpcmVjdGx5IGNvbXBpbGVkIGF3YXlcbi8vIGR1cmluZyB0ZW1wbGF0ZSBjb21waWxhdGlvblxudmFyIGlzUmVzZXJ2ZWRBdHRyID0gbWFrZU1hcCgnc3R5bGUsY2xhc3MnKTtcblxuLy8gYXR0cmlidXRlcyB0aGF0IHNob3VsZCBiZSB1c2luZyBwcm9wcyBmb3IgYmluZGluZ1xudmFyIGFjY2VwdFZhbHVlID0gbWFrZU1hcCgnaW5wdXQsdGV4dGFyZWEsb3B0aW9uLHNlbGVjdCxwcm9ncmVzcycpO1xudmFyIG11c3RVc2VQcm9wID0gZnVuY3Rpb24gKHRhZywgdHlwZSwgYXR0cikge1xuICByZXR1cm4gKFxuICAgIChhdHRyID09PSAndmFsdWUnICYmIGFjY2VwdFZhbHVlKHRhZykpICYmIHR5cGUgIT09ICdidXR0b24nIHx8XG4gICAgKGF0dHIgPT09ICdzZWxlY3RlZCcgJiYgdGFnID09PSAnb3B0aW9uJykgfHxcbiAgICAoYXR0ciA9PT0gJ2NoZWNrZWQnICYmIHRhZyA9PT0gJ2lucHV0JykgfHxcbiAgICAoYXR0ciA9PT0gJ211dGVkJyAmJiB0YWcgPT09ICd2aWRlbycpXG4gIClcbn07XG5cbnZhciBpc0VudW1lcmF0ZWRBdHRyID0gbWFrZU1hcCgnY29udGVudGVkaXRhYmxlLGRyYWdnYWJsZSxzcGVsbGNoZWNrJyk7XG5cbnZhciBpc0Jvb2xlYW5BdHRyID0gbWFrZU1hcChcbiAgJ2FsbG93ZnVsbHNjcmVlbixhc3luYyxhdXRvZm9jdXMsYXV0b3BsYXksY2hlY2tlZCxjb21wYWN0LGNvbnRyb2xzLGRlY2xhcmUsJyArXG4gICdkZWZhdWx0LGRlZmF1bHRjaGVja2VkLGRlZmF1bHRtdXRlZCxkZWZhdWx0c2VsZWN0ZWQsZGVmZXIsZGlzYWJsZWQsJyArXG4gICdlbmFibGVkLGZvcm1ub3ZhbGlkYXRlLGhpZGRlbixpbmRldGVybWluYXRlLGluZXJ0LGlzbWFwLGl0ZW1zY29wZSxsb29wLG11bHRpcGxlLCcgK1xuICAnbXV0ZWQsbm9ocmVmLG5vcmVzaXplLG5vc2hhZGUsbm92YWxpZGF0ZSxub3dyYXAsb3BlbixwYXVzZW9uZXhpdCxyZWFkb25seSwnICtcbiAgJ3JlcXVpcmVkLHJldmVyc2VkLHNjb3BlZCxzZWFtbGVzcyxzZWxlY3RlZCxzb3J0YWJsZSx0cmFuc2xhdGUsJyArXG4gICd0cnVlc3BlZWQsdHlwZW11c3RtYXRjaCx2aXNpYmxlJ1xuKTtcblxudmFyIHhsaW5rTlMgPSAnaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayc7XG5cbnZhciBpc1hsaW5rID0gZnVuY3Rpb24gKG5hbWUpIHtcbiAgcmV0dXJuIG5hbWUuY2hhckF0KDUpID09PSAnOicgJiYgbmFtZS5zbGljZSgwLCA1KSA9PT0gJ3hsaW5rJ1xufTtcblxudmFyIGdldFhsaW5rUHJvcCA9IGZ1bmN0aW9uIChuYW1lKSB7XG4gIHJldHVybiBpc1hsaW5rKG5hbWUpID8gbmFtZS5zbGljZSg2LCBuYW1lLmxlbmd0aCkgOiAnJ1xufTtcblxudmFyIGlzRmFsc3lBdHRyVmFsdWUgPSBmdW5jdGlvbiAodmFsKSB7XG4gIHJldHVybiB2YWwgPT0gbnVsbCB8fCB2YWwgPT09IGZhbHNlXG59O1xuXG4vKiAgKi9cblxuZnVuY3Rpb24gZ2VuQ2xhc3NGb3JWbm9kZSAodm5vZGUpIHtcbiAgdmFyIGRhdGEgPSB2bm9kZS5kYXRhO1xuICB2YXIgcGFyZW50Tm9kZSA9IHZub2RlO1xuICB2YXIgY2hpbGROb2RlID0gdm5vZGU7XG4gIHdoaWxlIChpc0RlZihjaGlsZE5vZGUuY29tcG9uZW50SW5zdGFuY2UpKSB7XG4gICAgY2hpbGROb2RlID0gY2hpbGROb2RlLmNvbXBvbmVudEluc3RhbmNlLl92bm9kZTtcbiAgICBpZiAoY2hpbGROb2RlLmRhdGEpIHtcbiAgICAgIGRhdGEgPSBtZXJnZUNsYXNzRGF0YShjaGlsZE5vZGUuZGF0YSwgZGF0YSk7XG4gICAgfVxuICB9XG4gIHdoaWxlIChpc0RlZihwYXJlbnROb2RlID0gcGFyZW50Tm9kZS5wYXJlbnQpKSB7XG4gICAgaWYgKHBhcmVudE5vZGUuZGF0YSkge1xuICAgICAgZGF0YSA9IG1lcmdlQ2xhc3NEYXRhKGRhdGEsIHBhcmVudE5vZGUuZGF0YSk7XG4gICAgfVxuICB9XG4gIHJldHVybiByZW5kZXJDbGFzcyhkYXRhLnN0YXRpY0NsYXNzLCBkYXRhLmNsYXNzKVxufVxuXG5mdW5jdGlvbiBtZXJnZUNsYXNzRGF0YSAoY2hpbGQsIHBhcmVudCkge1xuICByZXR1cm4ge1xuICAgIHN0YXRpY0NsYXNzOiBjb25jYXQoY2hpbGQuc3RhdGljQ2xhc3MsIHBhcmVudC5zdGF0aWNDbGFzcyksXG4gICAgY2xhc3M6IGlzRGVmKGNoaWxkLmNsYXNzKVxuICAgICAgPyBbY2hpbGQuY2xhc3MsIHBhcmVudC5jbGFzc11cbiAgICAgIDogcGFyZW50LmNsYXNzXG4gIH1cbn1cblxuZnVuY3Rpb24gcmVuZGVyQ2xhc3MgKFxuICBzdGF0aWNDbGFzcyxcbiAgZHluYW1pY0NsYXNzXG4pIHtcbiAgaWYgKGlzRGVmKHN0YXRpY0NsYXNzKSB8fCBpc0RlZihkeW5hbWljQ2xhc3MpKSB7XG4gICAgcmV0dXJuIGNvbmNhdChzdGF0aWNDbGFzcywgc3RyaW5naWZ5Q2xhc3MoZHluYW1pY0NsYXNzKSlcbiAgfVxuICAvKiBpc3RhbmJ1bCBpZ25vcmUgbmV4dCAqL1xuICByZXR1cm4gJydcbn1cblxuZnVuY3Rpb24gY29uY2F0IChhLCBiKSB7XG4gIHJldHVybiBhID8gYiA/IChhICsgJyAnICsgYikgOiBhIDogKGIgfHwgJycpXG59XG5cbmZ1bmN0aW9uIHN0cmluZ2lmeUNsYXNzICh2YWx1ZSkge1xuICBpZiAoQXJyYXkuaXNBcnJheSh2YWx1ZSkpIHtcbiAgICByZXR1cm4gc3RyaW5naWZ5QXJyYXkodmFsdWUpXG4gIH1cbiAgaWYgKGlzT2JqZWN0KHZhbHVlKSkge1xuICAgIHJldHVybiBzdHJpbmdpZnlPYmplY3QodmFsdWUpXG4gIH1cbiAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ3N0cmluZycpIHtcbiAgICByZXR1cm4gdmFsdWVcbiAgfVxuICAvKiBpc3RhbmJ1bCBpZ25vcmUgbmV4dCAqL1xuICByZXR1cm4gJydcbn1cblxuZnVuY3Rpb24gc3RyaW5naWZ5QXJyYXkgKHZhbHVlKSB7XG4gIHZhciByZXMgPSAnJztcbiAgdmFyIHN0cmluZ2lmaWVkO1xuICBmb3IgKHZhciBpID0gMCwgbCA9IHZhbHVlLmxlbmd0aDsgaSA8IGw7IGkrKykge1xuICAgIGlmIChpc0RlZihzdHJpbmdpZmllZCA9IHN0cmluZ2lmeUNsYXNzKHZhbHVlW2ldKSkgJiYgc3RyaW5naWZpZWQgIT09ICcnKSB7XG4gICAgICBpZiAocmVzKSB7IHJlcyArPSAnICc7IH1cbiAgICAgIHJlcyArPSBzdHJpbmdpZmllZDtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIHJlc1xufVxuXG5mdW5jdGlvbiBzdHJpbmdpZnlPYmplY3QgKHZhbHVlKSB7XG4gIHZhciByZXMgPSAnJztcbiAgZm9yICh2YXIga2V5IGluIHZhbHVlKSB7XG4gICAgaWYgKHZhbHVlW2tleV0pIHtcbiAgICAgIGlmIChyZXMpIHsgcmVzICs9ICcgJzsgfVxuICAgICAgcmVzICs9IGtleTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIHJlc1xufVxuXG4vKiAgKi9cblxudmFyIG5hbWVzcGFjZU1hcCA9IHtcbiAgc3ZnOiAnaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmcnLFxuICBtYXRoOiAnaHR0cDovL3d3dy53My5vcmcvMTk5OC9NYXRoL01hdGhNTCdcbn07XG5cbnZhciBpc0hUTUxUYWcgPSBtYWtlTWFwKFxuICAnaHRtbCxib2R5LGJhc2UsaGVhZCxsaW5rLG1ldGEsc3R5bGUsdGl0bGUsJyArXG4gICdhZGRyZXNzLGFydGljbGUsYXNpZGUsZm9vdGVyLGhlYWRlcixoMSxoMixoMyxoNCxoNSxoNixoZ3JvdXAsbmF2LHNlY3Rpb24sJyArXG4gICdkaXYsZGQsZGwsZHQsZmlnY2FwdGlvbixmaWd1cmUscGljdHVyZSxocixpbWcsbGksbWFpbixvbCxwLHByZSx1bCwnICtcbiAgJ2EsYixhYmJyLGJkaSxiZG8sYnIsY2l0ZSxjb2RlLGRhdGEsZGZuLGVtLGksa2JkLG1hcmsscSxycCxydCxydGMscnVieSwnICtcbiAgJ3Msc2FtcCxzbWFsbCxzcGFuLHN0cm9uZyxzdWIsc3VwLHRpbWUsdSx2YXIsd2JyLGFyZWEsYXVkaW8sbWFwLHRyYWNrLHZpZGVvLCcgK1xuICAnZW1iZWQsb2JqZWN0LHBhcmFtLHNvdXJjZSxjYW52YXMsc2NyaXB0LG5vc2NyaXB0LGRlbCxpbnMsJyArXG4gICdjYXB0aW9uLGNvbCxjb2xncm91cCx0YWJsZSx0aGVhZCx0Ym9keSx0ZCx0aCx0ciwnICtcbiAgJ2J1dHRvbixkYXRhbGlzdCxmaWVsZHNldCxmb3JtLGlucHV0LGxhYmVsLGxlZ2VuZCxtZXRlcixvcHRncm91cCxvcHRpb24sJyArXG4gICdvdXRwdXQscHJvZ3Jlc3Msc2VsZWN0LHRleHRhcmVhLCcgK1xuICAnZGV0YWlscyxkaWFsb2csbWVudSxtZW51aXRlbSxzdW1tYXJ5LCcgK1xuICAnY29udGVudCxlbGVtZW50LHNoYWRvdyx0ZW1wbGF0ZSxibG9ja3F1b3RlLGlmcmFtZSx0Zm9vdCdcbik7XG5cbi8vIHRoaXMgbWFwIGlzIGludGVudGlvbmFsbHkgc2VsZWN0aXZlLCBvbmx5IGNvdmVyaW5nIFNWRyBlbGVtZW50cyB0aGF0IG1heVxuLy8gY29udGFpbiBjaGlsZCBlbGVtZW50cy5cbnZhciBpc1NWRyA9IG1ha2VNYXAoXG4gICdzdmcsYW5pbWF0ZSxjaXJjbGUsY2xpcHBhdGgsY3Vyc29yLGRlZnMsZGVzYyxlbGxpcHNlLGZpbHRlcixmb250LWZhY2UsJyArXG4gICdmb3JlaWduT2JqZWN0LGcsZ2x5cGgsaW1hZ2UsbGluZSxtYXJrZXIsbWFzayxtaXNzaW5nLWdseXBoLHBhdGgscGF0dGVybiwnICtcbiAgJ3BvbHlnb24scG9seWxpbmUscmVjdCxzd2l0Y2gsc3ltYm9sLHRleHQsdGV4dHBhdGgsdHNwYW4sdXNlLHZpZXcnLFxuICB0cnVlXG4pO1xuXG52YXIgaXNQcmVUYWcgPSBmdW5jdGlvbiAodGFnKSB7IHJldHVybiB0YWcgPT09ICdwcmUnOyB9O1xuXG52YXIgaXNSZXNlcnZlZFRhZyA9IGZ1bmN0aW9uICh0YWcpIHtcbiAgcmV0dXJuIGlzSFRNTFRhZyh0YWcpIHx8IGlzU1ZHKHRhZylcbn07XG5cbmZ1bmN0aW9uIGdldFRhZ05hbWVzcGFjZSAodGFnKSB7XG4gIGlmIChpc1NWRyh0YWcpKSB7XG4gICAgcmV0dXJuICdzdmcnXG4gIH1cbiAgLy8gYmFzaWMgc3VwcG9ydCBmb3IgTWF0aE1MXG4gIC8vIG5vdGUgaXQgZG9lc24ndCBzdXBwb3J0IG90aGVyIE1hdGhNTCBlbGVtZW50cyBiZWluZyBjb21wb25lbnQgcm9vdHNcbiAgaWYgKHRhZyA9PT0gJ21hdGgnKSB7XG4gICAgcmV0dXJuICdtYXRoJ1xuICB9XG59XG5cbnZhciB1bmtub3duRWxlbWVudENhY2hlID0gT2JqZWN0LmNyZWF0ZShudWxsKTtcbmZ1bmN0aW9uIGlzVW5rbm93bkVsZW1lbnQgKHRhZykge1xuICAvKiBpc3RhbmJ1bCBpZ25vcmUgaWYgKi9cbiAgaWYgKCFpbkJyb3dzZXIpIHtcbiAgICByZXR1cm4gdHJ1ZVxuICB9XG4gIGlmIChpc1Jlc2VydmVkVGFnKHRhZykpIHtcbiAgICByZXR1cm4gZmFsc2VcbiAgfVxuICB0YWcgPSB0YWcudG9Mb3dlckNhc2UoKTtcbiAgLyogaXN0YW5idWwgaWdub3JlIGlmICovXG4gIGlmICh1bmtub3duRWxlbWVudENhY2hlW3RhZ10gIT0gbnVsbCkge1xuICAgIHJldHVybiB1bmtub3duRWxlbWVudENhY2hlW3RhZ11cbiAgfVxuICB2YXIgZWwgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KHRhZyk7XG4gIGlmICh0YWcuaW5kZXhPZignLScpID4gLTEpIHtcbiAgICAvLyBodHRwOi8vc3RhY2tvdmVyZmxvdy5jb20vYS8yODIxMDM2NC8xMDcwMjQ0XG4gICAgcmV0dXJuICh1bmtub3duRWxlbWVudENhY2hlW3RhZ10gPSAoXG4gICAgICBlbC5jb25zdHJ1Y3RvciA9PT0gd2luZG93LkhUTUxVbmtub3duRWxlbWVudCB8fFxuICAgICAgZWwuY29uc3RydWN0b3IgPT09IHdpbmRvdy5IVE1MRWxlbWVudFxuICAgICkpXG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuICh1bmtub3duRWxlbWVudENhY2hlW3RhZ10gPSAvSFRNTFVua25vd25FbGVtZW50Ly50ZXN0KGVsLnRvU3RyaW5nKCkpKVxuICB9XG59XG5cbnZhciBpc1RleHRJbnB1dFR5cGUgPSBtYWtlTWFwKCd0ZXh0LG51bWJlcixwYXNzd29yZCxzZWFyY2gsZW1haWwsdGVsLHVybCcpO1xuXG4vKiAgKi9cblxuLyoqXG4gKiBRdWVyeSBhbiBlbGVtZW50IHNlbGVjdG9yIGlmIGl0J3Mgbm90IGFuIGVsZW1lbnQgYWxyZWFkeS5cbiAqL1xuZnVuY3Rpb24gcXVlcnkgKGVsKSB7XG4gIGlmICh0eXBlb2YgZWwgPT09ICdzdHJpbmcnKSB7XG4gICAgdmFyIHNlbGVjdGVkID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcihlbCk7XG4gICAgaWYgKCFzZWxlY3RlZCkge1xuICAgICAgcHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJyAmJiB3YXJuKFxuICAgICAgICAnQ2Fubm90IGZpbmQgZWxlbWVudDogJyArIGVsXG4gICAgICApO1xuICAgICAgcmV0dXJuIGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpXG4gICAgfVxuICAgIHJldHVybiBzZWxlY3RlZFxuICB9IGVsc2Uge1xuICAgIHJldHVybiBlbFxuICB9XG59XG5cbi8qICAqL1xuXG5mdW5jdGlvbiBjcmVhdGVFbGVtZW50JDEgKHRhZ05hbWUsIHZub2RlKSB7XG4gIHZhciBlbG0gPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KHRhZ05hbWUpO1xuICBpZiAodGFnTmFtZSAhPT0gJ3NlbGVjdCcpIHtcbiAgICByZXR1cm4gZWxtXG4gIH1cbiAgLy8gZmFsc2Ugb3IgbnVsbCB3aWxsIHJlbW92ZSB0aGUgYXR0cmlidXRlIGJ1dCB1bmRlZmluZWQgd2lsbCBub3RcbiAgaWYgKHZub2RlLmRhdGEgJiYgdm5vZGUuZGF0YS5hdHRycyAmJiB2bm9kZS5kYXRhLmF0dHJzLm11bHRpcGxlICE9PSB1bmRlZmluZWQpIHtcbiAgICBlbG0uc2V0QXR0cmlidXRlKCdtdWx0aXBsZScsICdtdWx0aXBsZScpO1xuICB9XG4gIHJldHVybiBlbG1cbn1cblxuZnVuY3Rpb24gY3JlYXRlRWxlbWVudE5TIChuYW1lc3BhY2UsIHRhZ05hbWUpIHtcbiAgcmV0dXJuIGRvY3VtZW50LmNyZWF0ZUVsZW1lbnROUyhuYW1lc3BhY2VNYXBbbmFtZXNwYWNlXSwgdGFnTmFtZSlcbn1cblxuZnVuY3Rpb24gY3JlYXRlVGV4dE5vZGUgKHRleHQpIHtcbiAgcmV0dXJuIGRvY3VtZW50LmNyZWF0ZVRleHROb2RlKHRleHQpXG59XG5cbmZ1bmN0aW9uIGNyZWF0ZUNvbW1lbnQgKHRleHQpIHtcbiAgcmV0dXJuIGRvY3VtZW50LmNyZWF0ZUNvbW1lbnQodGV4dClcbn1cblxuZnVuY3Rpb24gaW5zZXJ0QmVmb3JlIChwYXJlbnROb2RlLCBuZXdOb2RlLCByZWZlcmVuY2VOb2RlKSB7XG4gIHBhcmVudE5vZGUuaW5zZXJ0QmVmb3JlKG5ld05vZGUsIHJlZmVyZW5jZU5vZGUpO1xufVxuXG5mdW5jdGlvbiByZW1vdmVDaGlsZCAobm9kZSwgY2hpbGQpIHtcbiAgbm9kZS5yZW1vdmVDaGlsZChjaGlsZCk7XG59XG5cbmZ1bmN0aW9uIGFwcGVuZENoaWxkIChub2RlLCBjaGlsZCkge1xuICBub2RlLmFwcGVuZENoaWxkKGNoaWxkKTtcbn1cblxuZnVuY3Rpb24gcGFyZW50Tm9kZSAobm9kZSkge1xuICByZXR1cm4gbm9kZS5wYXJlbnROb2RlXG59XG5cbmZ1bmN0aW9uIG5leHRTaWJsaW5nIChub2RlKSB7XG4gIHJldHVybiBub2RlLm5leHRTaWJsaW5nXG59XG5cbmZ1bmN0aW9uIHRhZ05hbWUgKG5vZGUpIHtcbiAgcmV0dXJuIG5vZGUudGFnTmFtZVxufVxuXG5mdW5jdGlvbiBzZXRUZXh0Q29udGVudCAobm9kZSwgdGV4dCkge1xuICBub2RlLnRleHRDb250ZW50ID0gdGV4dDtcbn1cblxuZnVuY3Rpb24gc2V0QXR0cmlidXRlIChub2RlLCBrZXksIHZhbCkge1xuICBub2RlLnNldEF0dHJpYnV0ZShrZXksIHZhbCk7XG59XG5cblxudmFyIG5vZGVPcHMgPSBPYmplY3QuZnJlZXplKHtcblx0Y3JlYXRlRWxlbWVudDogY3JlYXRlRWxlbWVudCQxLFxuXHRjcmVhdGVFbGVtZW50TlM6IGNyZWF0ZUVsZW1lbnROUyxcblx0Y3JlYXRlVGV4dE5vZGU6IGNyZWF0ZVRleHROb2RlLFxuXHRjcmVhdGVDb21tZW50OiBjcmVhdGVDb21tZW50LFxuXHRpbnNlcnRCZWZvcmU6IGluc2VydEJlZm9yZSxcblx0cmVtb3ZlQ2hpbGQ6IHJlbW92ZUNoaWxkLFxuXHRhcHBlbmRDaGlsZDogYXBwZW5kQ2hpbGQsXG5cdHBhcmVudE5vZGU6IHBhcmVudE5vZGUsXG5cdG5leHRTaWJsaW5nOiBuZXh0U2libGluZyxcblx0dGFnTmFtZTogdGFnTmFtZSxcblx0c2V0VGV4dENvbnRlbnQ6IHNldFRleHRDb250ZW50LFxuXHRzZXRBdHRyaWJ1dGU6IHNldEF0dHJpYnV0ZVxufSk7XG5cbi8qICAqL1xuXG52YXIgcmVmID0ge1xuICBjcmVhdGU6IGZ1bmN0aW9uIGNyZWF0ZSAoXywgdm5vZGUpIHtcbiAgICByZWdpc3RlclJlZih2bm9kZSk7XG4gIH0sXG4gIHVwZGF0ZTogZnVuY3Rpb24gdXBkYXRlIChvbGRWbm9kZSwgdm5vZGUpIHtcbiAgICBpZiAob2xkVm5vZGUuZGF0YS5yZWYgIT09IHZub2RlLmRhdGEucmVmKSB7XG4gICAgICByZWdpc3RlclJlZihvbGRWbm9kZSwgdHJ1ZSk7XG4gICAgICByZWdpc3RlclJlZih2bm9kZSk7XG4gICAgfVxuICB9LFxuICBkZXN0cm95OiBmdW5jdGlvbiBkZXN0cm95ICh2bm9kZSkge1xuICAgIHJlZ2lzdGVyUmVmKHZub2RlLCB0cnVlKTtcbiAgfVxufTtcblxuZnVuY3Rpb24gcmVnaXN0ZXJSZWYgKHZub2RlLCBpc1JlbW92YWwpIHtcbiAgdmFyIGtleSA9IHZub2RlLmRhdGEucmVmO1xuICBpZiAoIWtleSkgeyByZXR1cm4gfVxuXG4gIHZhciB2bSA9IHZub2RlLmNvbnRleHQ7XG4gIHZhciByZWYgPSB2bm9kZS5jb21wb25lbnRJbnN0YW5jZSB8fCB2bm9kZS5lbG07XG4gIHZhciByZWZzID0gdm0uJHJlZnM7XG4gIGlmIChpc1JlbW92YWwpIHtcbiAgICBpZiAoQXJyYXkuaXNBcnJheShyZWZzW2tleV0pKSB7XG4gICAgICByZW1vdmUocmVmc1trZXldLCByZWYpO1xuICAgIH0gZWxzZSBpZiAocmVmc1trZXldID09PSByZWYpIHtcbiAgICAgIHJlZnNba2V5XSA9IHVuZGVmaW5lZDtcbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgaWYgKHZub2RlLmRhdGEucmVmSW5Gb3IpIHtcbiAgICAgIGlmICghQXJyYXkuaXNBcnJheShyZWZzW2tleV0pKSB7XG4gICAgICAgIHJlZnNba2V5XSA9IFtyZWZdO1xuICAgICAgfSBlbHNlIGlmIChyZWZzW2tleV0uaW5kZXhPZihyZWYpIDwgMCkge1xuICAgICAgICAvLyAkZmxvdy1kaXNhYmxlLWxpbmVcbiAgICAgICAgcmVmc1trZXldLnB1c2gocmVmKTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgcmVmc1trZXldID0gcmVmO1xuICAgIH1cbiAgfVxufVxuXG4vKipcbiAqIFZpcnR1YWwgRE9NIHBhdGNoaW5nIGFsZ29yaXRobSBiYXNlZCBvbiBTbmFiYmRvbSBieVxuICogU2ltb24gRnJpaXMgVmluZHVtIChAcGFsZGVwaW5kKVxuICogTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlXG4gKiBodHRwczovL2dpdGh1Yi5jb20vcGFsZGVwaW5kL3NuYWJiZG9tL2Jsb2IvbWFzdGVyL0xJQ0VOU0VcbiAqXG4gKiBtb2RpZmllZCBieSBFdmFuIFlvdSAoQHl5eDk5MDgwMylcbiAqXG4gKiBOb3QgdHlwZS1jaGVja2luZyB0aGlzIGJlY2F1c2UgdGhpcyBmaWxlIGlzIHBlcmYtY3JpdGljYWwgYW5kIHRoZSBjb3N0XG4gKiBvZiBtYWtpbmcgZmxvdyB1bmRlcnN0YW5kIGl0IGlzIG5vdCB3b3J0aCBpdC5cbiAqL1xuXG52YXIgZW1wdHlOb2RlID0gbmV3IFZOb2RlKCcnLCB7fSwgW10pO1xuXG52YXIgaG9va3MgPSBbJ2NyZWF0ZScsICdhY3RpdmF0ZScsICd1cGRhdGUnLCAncmVtb3ZlJywgJ2Rlc3Ryb3knXTtcblxuZnVuY3Rpb24gc2FtZVZub2RlIChhLCBiKSB7XG4gIHJldHVybiAoXG4gICAgYS5rZXkgPT09IGIua2V5ICYmIChcbiAgICAgIChcbiAgICAgICAgYS50YWcgPT09IGIudGFnICYmXG4gICAgICAgIGEuaXNDb21tZW50ID09PSBiLmlzQ29tbWVudCAmJlxuICAgICAgICBpc0RlZihhLmRhdGEpID09PSBpc0RlZihiLmRhdGEpICYmXG4gICAgICAgIHNhbWVJbnB1dFR5cGUoYSwgYilcbiAgICAgICkgfHwgKFxuICAgICAgICBpc1RydWUoYS5pc0FzeW5jUGxhY2Vob2xkZXIpICYmXG4gICAgICAgIGEuYXN5bmNGYWN0b3J5ID09PSBiLmFzeW5jRmFjdG9yeSAmJlxuICAgICAgICBpc1VuZGVmKGIuYXN5bmNGYWN0b3J5LmVycm9yKVxuICAgICAgKVxuICAgIClcbiAgKVxufVxuXG5mdW5jdGlvbiBzYW1lSW5wdXRUeXBlIChhLCBiKSB7XG4gIGlmIChhLnRhZyAhPT0gJ2lucHV0JykgeyByZXR1cm4gdHJ1ZSB9XG4gIHZhciBpO1xuICB2YXIgdHlwZUEgPSBpc0RlZihpID0gYS5kYXRhKSAmJiBpc0RlZihpID0gaS5hdHRycykgJiYgaS50eXBlO1xuICB2YXIgdHlwZUIgPSBpc0RlZihpID0gYi5kYXRhKSAmJiBpc0RlZihpID0gaS5hdHRycykgJiYgaS50eXBlO1xuICByZXR1cm4gdHlwZUEgPT09IHR5cGVCIHx8IGlzVGV4dElucHV0VHlwZSh0eXBlQSkgJiYgaXNUZXh0SW5wdXRUeXBlKHR5cGVCKVxufVxuXG5mdW5jdGlvbiBjcmVhdGVLZXlUb09sZElkeCAoY2hpbGRyZW4sIGJlZ2luSWR4LCBlbmRJZHgpIHtcbiAgdmFyIGksIGtleTtcbiAgdmFyIG1hcCA9IHt9O1xuICBmb3IgKGkgPSBiZWdpbklkeDsgaSA8PSBlbmRJZHg7ICsraSkge1xuICAgIGtleSA9IGNoaWxkcmVuW2ldLmtleTtcbiAgICBpZiAoaXNEZWYoa2V5KSkgeyBtYXBba2V5XSA9IGk7IH1cbiAgfVxuICByZXR1cm4gbWFwXG59XG5cbmZ1bmN0aW9uIGNyZWF0ZVBhdGNoRnVuY3Rpb24gKGJhY2tlbmQpIHtcbiAgdmFyIGksIGo7XG4gIHZhciBjYnMgPSB7fTtcblxuICB2YXIgbW9kdWxlcyA9IGJhY2tlbmQubW9kdWxlcztcbiAgdmFyIG5vZGVPcHMgPSBiYWNrZW5kLm5vZGVPcHM7XG5cbiAgZm9yIChpID0gMDsgaSA8IGhvb2tzLmxlbmd0aDsgKytpKSB7XG4gICAgY2JzW2hvb2tzW2ldXSA9IFtdO1xuICAgIGZvciAoaiA9IDA7IGogPCBtb2R1bGVzLmxlbmd0aDsgKytqKSB7XG4gICAgICBpZiAoaXNEZWYobW9kdWxlc1tqXVtob29rc1tpXV0pKSB7XG4gICAgICAgIGNic1tob29rc1tpXV0ucHVzaChtb2R1bGVzW2pdW2hvb2tzW2ldXSk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgZnVuY3Rpb24gZW1wdHlOb2RlQXQgKGVsbSkge1xuICAgIHJldHVybiBuZXcgVk5vZGUobm9kZU9wcy50YWdOYW1lKGVsbSkudG9Mb3dlckNhc2UoKSwge30sIFtdLCB1bmRlZmluZWQsIGVsbSlcbiAgfVxuXG4gIGZ1bmN0aW9uIGNyZWF0ZVJtQ2IgKGNoaWxkRWxtLCBsaXN0ZW5lcnMpIHtcbiAgICBmdW5jdGlvbiByZW1vdmUkJDEgKCkge1xuICAgICAgaWYgKC0tcmVtb3ZlJCQxLmxpc3RlbmVycyA9PT0gMCkge1xuICAgICAgICByZW1vdmVOb2RlKGNoaWxkRWxtKTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmVtb3ZlJCQxLmxpc3RlbmVycyA9IGxpc3RlbmVycztcbiAgICByZXR1cm4gcmVtb3ZlJCQxXG4gIH1cblxuICBmdW5jdGlvbiByZW1vdmVOb2RlIChlbCkge1xuICAgIHZhciBwYXJlbnQgPSBub2RlT3BzLnBhcmVudE5vZGUoZWwpO1xuICAgIC8vIGVsZW1lbnQgbWF5IGhhdmUgYWxyZWFkeSBiZWVuIHJlbW92ZWQgZHVlIHRvIHYtaHRtbCAvIHYtdGV4dFxuICAgIGlmIChpc0RlZihwYXJlbnQpKSB7XG4gICAgICBub2RlT3BzLnJlbW92ZUNoaWxkKHBhcmVudCwgZWwpO1xuICAgIH1cbiAgfVxuXG4gIHZhciBpblByZSA9IDA7XG4gIGZ1bmN0aW9uIGNyZWF0ZUVsbSAodm5vZGUsIGluc2VydGVkVm5vZGVRdWV1ZSwgcGFyZW50RWxtLCByZWZFbG0sIG5lc3RlZCkge1xuICAgIHZub2RlLmlzUm9vdEluc2VydCA9ICFuZXN0ZWQ7IC8vIGZvciB0cmFuc2l0aW9uIGVudGVyIGNoZWNrXG4gICAgaWYgKGNyZWF0ZUNvbXBvbmVudCh2bm9kZSwgaW5zZXJ0ZWRWbm9kZVF1ZXVlLCBwYXJlbnRFbG0sIHJlZkVsbSkpIHtcbiAgICAgIHJldHVyblxuICAgIH1cblxuICAgIHZhciBkYXRhID0gdm5vZGUuZGF0YTtcbiAgICB2YXIgY2hpbGRyZW4gPSB2bm9kZS5jaGlsZHJlbjtcbiAgICB2YXIgdGFnID0gdm5vZGUudGFnO1xuICAgIGlmIChpc0RlZih0YWcpKSB7XG4gICAgICBpZiAocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJykge1xuICAgICAgICBpZiAoZGF0YSAmJiBkYXRhLnByZSkge1xuICAgICAgICAgIGluUHJlKys7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKFxuICAgICAgICAgICFpblByZSAmJlxuICAgICAgICAgICF2bm9kZS5ucyAmJlxuICAgICAgICAgICEoY29uZmlnLmlnbm9yZWRFbGVtZW50cy5sZW5ndGggJiYgY29uZmlnLmlnbm9yZWRFbGVtZW50cy5pbmRleE9mKHRhZykgPiAtMSkgJiZcbiAgICAgICAgICBjb25maWcuaXNVbmtub3duRWxlbWVudCh0YWcpXG4gICAgICAgICkge1xuICAgICAgICAgIHdhcm4oXG4gICAgICAgICAgICAnVW5rbm93biBjdXN0b20gZWxlbWVudDogPCcgKyB0YWcgKyAnPiAtIGRpZCB5b3UgJyArXG4gICAgICAgICAgICAncmVnaXN0ZXIgdGhlIGNvbXBvbmVudCBjb3JyZWN0bHk/IEZvciByZWN1cnNpdmUgY29tcG9uZW50cywgJyArXG4gICAgICAgICAgICAnbWFrZSBzdXJlIHRvIHByb3ZpZGUgdGhlIFwibmFtZVwiIG9wdGlvbi4nLFxuICAgICAgICAgICAgdm5vZGUuY29udGV4dFxuICAgICAgICAgICk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHZub2RlLmVsbSA9IHZub2RlLm5zXG4gICAgICAgID8gbm9kZU9wcy5jcmVhdGVFbGVtZW50TlModm5vZGUubnMsIHRhZylcbiAgICAgICAgOiBub2RlT3BzLmNyZWF0ZUVsZW1lbnQodGFnLCB2bm9kZSk7XG4gICAgICBzZXRTY29wZSh2bm9kZSk7XG5cbiAgICAgIC8qIGlzdGFuYnVsIGlnbm9yZSBpZiAqL1xuICAgICAge1xuICAgICAgICBjcmVhdGVDaGlsZHJlbih2bm9kZSwgY2hpbGRyZW4sIGluc2VydGVkVm5vZGVRdWV1ZSk7XG4gICAgICAgIGlmIChpc0RlZihkYXRhKSkge1xuICAgICAgICAgIGludm9rZUNyZWF0ZUhvb2tzKHZub2RlLCBpbnNlcnRlZFZub2RlUXVldWUpO1xuICAgICAgICB9XG4gICAgICAgIGluc2VydChwYXJlbnRFbG0sIHZub2RlLmVsbSwgcmVmRWxtKTtcbiAgICAgIH1cblxuICAgICAgaWYgKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicgJiYgZGF0YSAmJiBkYXRhLnByZSkge1xuICAgICAgICBpblByZS0tO1xuICAgICAgfVxuICAgIH0gZWxzZSBpZiAoaXNUcnVlKHZub2RlLmlzQ29tbWVudCkpIHtcbiAgICAgIHZub2RlLmVsbSA9IG5vZGVPcHMuY3JlYXRlQ29tbWVudCh2bm9kZS50ZXh0KTtcbiAgICAgIGluc2VydChwYXJlbnRFbG0sIHZub2RlLmVsbSwgcmVmRWxtKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdm5vZGUuZWxtID0gbm9kZU9wcy5jcmVhdGVUZXh0Tm9kZSh2bm9kZS50ZXh0KTtcbiAgICAgIGluc2VydChwYXJlbnRFbG0sIHZub2RlLmVsbSwgcmVmRWxtKTtcbiAgICB9XG4gIH1cblxuICBmdW5jdGlvbiBjcmVhdGVDb21wb25lbnQgKHZub2RlLCBpbnNlcnRlZFZub2RlUXVldWUsIHBhcmVudEVsbSwgcmVmRWxtKSB7XG4gICAgdmFyIGkgPSB2bm9kZS5kYXRhO1xuICAgIGlmIChpc0RlZihpKSkge1xuICAgICAgdmFyIGlzUmVhY3RpdmF0ZWQgPSBpc0RlZih2bm9kZS5jb21wb25lbnRJbnN0YW5jZSkgJiYgaS5rZWVwQWxpdmU7XG4gICAgICBpZiAoaXNEZWYoaSA9IGkuaG9vaykgJiYgaXNEZWYoaSA9IGkuaW5pdCkpIHtcbiAgICAgICAgaSh2bm9kZSwgZmFsc2UgLyogaHlkcmF0aW5nICovLCBwYXJlbnRFbG0sIHJlZkVsbSk7XG4gICAgICB9XG4gICAgICAvLyBhZnRlciBjYWxsaW5nIHRoZSBpbml0IGhvb2ssIGlmIHRoZSB2bm9kZSBpcyBhIGNoaWxkIGNvbXBvbmVudFxuICAgICAgLy8gaXQgc2hvdWxkJ3ZlIGNyZWF0ZWQgYSBjaGlsZCBpbnN0YW5jZSBhbmQgbW91bnRlZCBpdC4gdGhlIGNoaWxkXG4gICAgICAvLyBjb21wb25lbnQgYWxzbyBoYXMgc2V0IHRoZSBwbGFjZWhvbGRlciB2bm9kZSdzIGVsbS5cbiAgICAgIC8vIGluIHRoYXQgY2FzZSB3ZSBjYW4ganVzdCByZXR1cm4gdGhlIGVsZW1lbnQgYW5kIGJlIGRvbmUuXG4gICAgICBpZiAoaXNEZWYodm5vZGUuY29tcG9uZW50SW5zdGFuY2UpKSB7XG4gICAgICAgIGluaXRDb21wb25lbnQodm5vZGUsIGluc2VydGVkVm5vZGVRdWV1ZSk7XG4gICAgICAgIGlmIChpc1RydWUoaXNSZWFjdGl2YXRlZCkpIHtcbiAgICAgICAgICByZWFjdGl2YXRlQ29tcG9uZW50KHZub2RlLCBpbnNlcnRlZFZub2RlUXVldWUsIHBhcmVudEVsbSwgcmVmRWxtKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdHJ1ZVxuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIGZ1bmN0aW9uIGluaXRDb21wb25lbnQgKHZub2RlLCBpbnNlcnRlZFZub2RlUXVldWUpIHtcbiAgICBpZiAoaXNEZWYodm5vZGUuZGF0YS5wZW5kaW5nSW5zZXJ0KSkge1xuICAgICAgaW5zZXJ0ZWRWbm9kZVF1ZXVlLnB1c2guYXBwbHkoaW5zZXJ0ZWRWbm9kZVF1ZXVlLCB2bm9kZS5kYXRhLnBlbmRpbmdJbnNlcnQpO1xuICAgICAgdm5vZGUuZGF0YS5wZW5kaW5nSW5zZXJ0ID0gbnVsbDtcbiAgICB9XG4gICAgdm5vZGUuZWxtID0gdm5vZGUuY29tcG9uZW50SW5zdGFuY2UuJGVsO1xuICAgIGlmIChpc1BhdGNoYWJsZSh2bm9kZSkpIHtcbiAgICAgIGludm9rZUNyZWF0ZUhvb2tzKHZub2RlLCBpbnNlcnRlZFZub2RlUXVldWUpO1xuICAgICAgc2V0U2NvcGUodm5vZGUpO1xuICAgIH0gZWxzZSB7XG4gICAgICAvLyBlbXB0eSBjb21wb25lbnQgcm9vdC5cbiAgICAgIC8vIHNraXAgYWxsIGVsZW1lbnQtcmVsYXRlZCBtb2R1bGVzIGV4Y2VwdCBmb3IgcmVmICgjMzQ1NSlcbiAgICAgIHJlZ2lzdGVyUmVmKHZub2RlKTtcbiAgICAgIC8vIG1ha2Ugc3VyZSB0byBpbnZva2UgdGhlIGluc2VydCBob29rXG4gICAgICBpbnNlcnRlZFZub2RlUXVldWUucHVzaCh2bm9kZSk7XG4gICAgfVxuICB9XG5cbiAgZnVuY3Rpb24gcmVhY3RpdmF0ZUNvbXBvbmVudCAodm5vZGUsIGluc2VydGVkVm5vZGVRdWV1ZSwgcGFyZW50RWxtLCByZWZFbG0pIHtcbiAgICB2YXIgaTtcbiAgICAvLyBoYWNrIGZvciAjNDMzOTogYSByZWFjdGl2YXRlZCBjb21wb25lbnQgd2l0aCBpbm5lciB0cmFuc2l0aW9uXG4gICAgLy8gZG9lcyBub3QgdHJpZ2dlciBiZWNhdXNlIHRoZSBpbm5lciBub2RlJ3MgY3JlYXRlZCBob29rcyBhcmUgbm90IGNhbGxlZFxuICAgIC8vIGFnYWluLiBJdCdzIG5vdCBpZGVhbCB0byBpbnZvbHZlIG1vZHVsZS1zcGVjaWZpYyBsb2dpYyBpbiBoZXJlIGJ1dFxuICAgIC8vIHRoZXJlIGRvZXNuJ3Qgc2VlbSB0byBiZSBhIGJldHRlciB3YXkgdG8gZG8gaXQuXG4gICAgdmFyIGlubmVyTm9kZSA9IHZub2RlO1xuICAgIHdoaWxlIChpbm5lck5vZGUuY29tcG9uZW50SW5zdGFuY2UpIHtcbiAgICAgIGlubmVyTm9kZSA9IGlubmVyTm9kZS5jb21wb25lbnRJbnN0YW5jZS5fdm5vZGU7XG4gICAgICBpZiAoaXNEZWYoaSA9IGlubmVyTm9kZS5kYXRhKSAmJiBpc0RlZihpID0gaS50cmFuc2l0aW9uKSkge1xuICAgICAgICBmb3IgKGkgPSAwOyBpIDwgY2JzLmFjdGl2YXRlLmxlbmd0aDsgKytpKSB7XG4gICAgICAgICAgY2JzLmFjdGl2YXRlW2ldKGVtcHR5Tm9kZSwgaW5uZXJOb2RlKTtcbiAgICAgICAgfVxuICAgICAgICBpbnNlcnRlZFZub2RlUXVldWUucHVzaChpbm5lck5vZGUpO1xuICAgICAgICBicmVha1xuICAgICAgfVxuICAgIH1cbiAgICAvLyB1bmxpa2UgYSBuZXdseSBjcmVhdGVkIGNvbXBvbmVudCxcbiAgICAvLyBhIHJlYWN0aXZhdGVkIGtlZXAtYWxpdmUgY29tcG9uZW50IGRvZXNuJ3QgaW5zZXJ0IGl0c2VsZlxuICAgIGluc2VydChwYXJlbnRFbG0sIHZub2RlLmVsbSwgcmVmRWxtKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGluc2VydCAocGFyZW50LCBlbG0sIHJlZiQkMSkge1xuICAgIGlmIChpc0RlZihwYXJlbnQpKSB7XG4gICAgICBpZiAoaXNEZWYocmVmJCQxKSkge1xuICAgICAgICBpZiAocmVmJCQxLnBhcmVudE5vZGUgPT09IHBhcmVudCkge1xuICAgICAgICAgIG5vZGVPcHMuaW5zZXJ0QmVmb3JlKHBhcmVudCwgZWxtLCByZWYkJDEpO1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBub2RlT3BzLmFwcGVuZENoaWxkKHBhcmVudCwgZWxtKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBmdW5jdGlvbiBjcmVhdGVDaGlsZHJlbiAodm5vZGUsIGNoaWxkcmVuLCBpbnNlcnRlZFZub2RlUXVldWUpIHtcbiAgICBpZiAoQXJyYXkuaXNBcnJheShjaGlsZHJlbikpIHtcbiAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgY2hpbGRyZW4ubGVuZ3RoOyArK2kpIHtcbiAgICAgICAgY3JlYXRlRWxtKGNoaWxkcmVuW2ldLCBpbnNlcnRlZFZub2RlUXVldWUsIHZub2RlLmVsbSwgbnVsbCwgdHJ1ZSk7XG4gICAgICB9XG4gICAgfSBlbHNlIGlmIChpc1ByaW1pdGl2ZSh2bm9kZS50ZXh0KSkge1xuICAgICAgbm9kZU9wcy5hcHBlbmRDaGlsZCh2bm9kZS5lbG0sIG5vZGVPcHMuY3JlYXRlVGV4dE5vZGUodm5vZGUudGV4dCkpO1xuICAgIH1cbiAgfVxuXG4gIGZ1bmN0aW9uIGlzUGF0Y2hhYmxlICh2bm9kZSkge1xuICAgIHdoaWxlICh2bm9kZS5jb21wb25lbnRJbnN0YW5jZSkge1xuICAgICAgdm5vZGUgPSB2bm9kZS5jb21wb25lbnRJbnN0YW5jZS5fdm5vZGU7XG4gICAgfVxuICAgIHJldHVybiBpc0RlZih2bm9kZS50YWcpXG4gIH1cblxuICBmdW5jdGlvbiBpbnZva2VDcmVhdGVIb29rcyAodm5vZGUsIGluc2VydGVkVm5vZGVRdWV1ZSkge1xuICAgIGZvciAodmFyIGkkMSA9IDA7IGkkMSA8IGNicy5jcmVhdGUubGVuZ3RoOyArK2kkMSkge1xuICAgICAgY2JzLmNyZWF0ZVtpJDFdKGVtcHR5Tm9kZSwgdm5vZGUpO1xuICAgIH1cbiAgICBpID0gdm5vZGUuZGF0YS5ob29rOyAvLyBSZXVzZSB2YXJpYWJsZVxuICAgIGlmIChpc0RlZihpKSkge1xuICAgICAgaWYgKGlzRGVmKGkuY3JlYXRlKSkgeyBpLmNyZWF0ZShlbXB0eU5vZGUsIHZub2RlKTsgfVxuICAgICAgaWYgKGlzRGVmKGkuaW5zZXJ0KSkgeyBpbnNlcnRlZFZub2RlUXVldWUucHVzaCh2bm9kZSk7IH1cbiAgICB9XG4gIH1cblxuICAvLyBzZXQgc2NvcGUgaWQgYXR0cmlidXRlIGZvciBzY29wZWQgQ1NTLlxuICAvLyB0aGlzIGlzIGltcGxlbWVudGVkIGFzIGEgc3BlY2lhbCBjYXNlIHRvIGF2b2lkIHRoZSBvdmVyaGVhZFxuICAvLyBvZiBnb2luZyB0aHJvdWdoIHRoZSBub3JtYWwgYXR0cmlidXRlIHBhdGNoaW5nIHByb2Nlc3MuXG4gIGZ1bmN0aW9uIHNldFNjb3BlICh2bm9kZSkge1xuICAgIHZhciBpO1xuICAgIHZhciBhbmNlc3RvciA9IHZub2RlO1xuICAgIHdoaWxlIChhbmNlc3Rvcikge1xuICAgICAgaWYgKGlzRGVmKGkgPSBhbmNlc3Rvci5jb250ZXh0KSAmJiBpc0RlZihpID0gaS4kb3B0aW9ucy5fc2NvcGVJZCkpIHtcbiAgICAgICAgbm9kZU9wcy5zZXRBdHRyaWJ1dGUodm5vZGUuZWxtLCBpLCAnJyk7XG4gICAgICB9XG4gICAgICBhbmNlc3RvciA9IGFuY2VzdG9yLnBhcmVudDtcbiAgICB9XG4gICAgLy8gZm9yIHNsb3QgY29udGVudCB0aGV5IHNob3VsZCBhbHNvIGdldCB0aGUgc2NvcGVJZCBmcm9tIHRoZSBob3N0IGluc3RhbmNlLlxuICAgIGlmIChpc0RlZihpID0gYWN0aXZlSW5zdGFuY2UpICYmXG4gICAgICBpICE9PSB2bm9kZS5jb250ZXh0ICYmXG4gICAgICBpc0RlZihpID0gaS4kb3B0aW9ucy5fc2NvcGVJZClcbiAgICApIHtcbiAgICAgIG5vZGVPcHMuc2V0QXR0cmlidXRlKHZub2RlLmVsbSwgaSwgJycpO1xuICAgIH1cbiAgfVxuXG4gIGZ1bmN0aW9uIGFkZFZub2RlcyAocGFyZW50RWxtLCByZWZFbG0sIHZub2Rlcywgc3RhcnRJZHgsIGVuZElkeCwgaW5zZXJ0ZWRWbm9kZVF1ZXVlKSB7XG4gICAgZm9yICg7IHN0YXJ0SWR4IDw9IGVuZElkeDsgKytzdGFydElkeCkge1xuICAgICAgY3JlYXRlRWxtKHZub2Rlc1tzdGFydElkeF0sIGluc2VydGVkVm5vZGVRdWV1ZSwgcGFyZW50RWxtLCByZWZFbG0pO1xuICAgIH1cbiAgfVxuXG4gIGZ1bmN0aW9uIGludm9rZURlc3Ryb3lIb29rICh2bm9kZSkge1xuICAgIHZhciBpLCBqO1xuICAgIHZhciBkYXRhID0gdm5vZGUuZGF0YTtcbiAgICBpZiAoaXNEZWYoZGF0YSkpIHtcbiAgICAgIGlmIChpc0RlZihpID0gZGF0YS5ob29rKSAmJiBpc0RlZihpID0gaS5kZXN0cm95KSkgeyBpKHZub2RlKTsgfVxuICAgICAgZm9yIChpID0gMDsgaSA8IGNicy5kZXN0cm95Lmxlbmd0aDsgKytpKSB7IGNicy5kZXN0cm95W2ldKHZub2RlKTsgfVxuICAgIH1cbiAgICBpZiAoaXNEZWYoaSA9IHZub2RlLmNoaWxkcmVuKSkge1xuICAgICAgZm9yIChqID0gMDsgaiA8IHZub2RlLmNoaWxkcmVuLmxlbmd0aDsgKytqKSB7XG4gICAgICAgIGludm9rZURlc3Ryb3lIb29rKHZub2RlLmNoaWxkcmVuW2pdKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBmdW5jdGlvbiByZW1vdmVWbm9kZXMgKHBhcmVudEVsbSwgdm5vZGVzLCBzdGFydElkeCwgZW5kSWR4KSB7XG4gICAgZm9yICg7IHN0YXJ0SWR4IDw9IGVuZElkeDsgKytzdGFydElkeCkge1xuICAgICAgdmFyIGNoID0gdm5vZGVzW3N0YXJ0SWR4XTtcbiAgICAgIGlmIChpc0RlZihjaCkpIHtcbiAgICAgICAgaWYgKGlzRGVmKGNoLnRhZykpIHtcbiAgICAgICAgICByZW1vdmVBbmRJbnZva2VSZW1vdmVIb29rKGNoKTtcbiAgICAgICAgICBpbnZva2VEZXN0cm95SG9vayhjaCk7XG4gICAgICAgIH0gZWxzZSB7IC8vIFRleHQgbm9kZVxuICAgICAgICAgIHJlbW92ZU5vZGUoY2guZWxtKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIGZ1bmN0aW9uIHJlbW92ZUFuZEludm9rZVJlbW92ZUhvb2sgKHZub2RlLCBybSkge1xuICAgIGlmIChpc0RlZihybSkgfHwgaXNEZWYodm5vZGUuZGF0YSkpIHtcbiAgICAgIHZhciBpO1xuICAgICAgdmFyIGxpc3RlbmVycyA9IGNicy5yZW1vdmUubGVuZ3RoICsgMTtcbiAgICAgIGlmIChpc0RlZihybSkpIHtcbiAgICAgICAgLy8gd2UgaGF2ZSBhIHJlY3Vyc2l2ZWx5IHBhc3NlZCBkb3duIHJtIGNhbGxiYWNrXG4gICAgICAgIC8vIGluY3JlYXNlIHRoZSBsaXN0ZW5lcnMgY291bnRcbiAgICAgICAgcm0ubGlzdGVuZXJzICs9IGxpc3RlbmVycztcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIC8vIGRpcmVjdGx5IHJlbW92aW5nXG4gICAgICAgIHJtID0gY3JlYXRlUm1DYih2bm9kZS5lbG0sIGxpc3RlbmVycyk7XG4gICAgICB9XG4gICAgICAvLyByZWN1cnNpdmVseSBpbnZva2UgaG9va3Mgb24gY2hpbGQgY29tcG9uZW50IHJvb3Qgbm9kZVxuICAgICAgaWYgKGlzRGVmKGkgPSB2bm9kZS5jb21wb25lbnRJbnN0YW5jZSkgJiYgaXNEZWYoaSA9IGkuX3Zub2RlKSAmJiBpc0RlZihpLmRhdGEpKSB7XG4gICAgICAgIHJlbW92ZUFuZEludm9rZVJlbW92ZUhvb2soaSwgcm0pO1xuICAgICAgfVxuICAgICAgZm9yIChpID0gMDsgaSA8IGNicy5yZW1vdmUubGVuZ3RoOyArK2kpIHtcbiAgICAgICAgY2JzLnJlbW92ZVtpXSh2bm9kZSwgcm0pO1xuICAgICAgfVxuICAgICAgaWYgKGlzRGVmKGkgPSB2bm9kZS5kYXRhLmhvb2spICYmIGlzRGVmKGkgPSBpLnJlbW92ZSkpIHtcbiAgICAgICAgaSh2bm9kZSwgcm0pO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcm0oKTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgcmVtb3ZlTm9kZSh2bm9kZS5lbG0pO1xuICAgIH1cbiAgfVxuXG4gIGZ1bmN0aW9uIHVwZGF0ZUNoaWxkcmVuIChwYXJlbnRFbG0sIG9sZENoLCBuZXdDaCwgaW5zZXJ0ZWRWbm9kZVF1ZXVlLCByZW1vdmVPbmx5KSB7XG4gICAgdmFyIG9sZFN0YXJ0SWR4ID0gMDtcbiAgICB2YXIgbmV3U3RhcnRJZHggPSAwO1xuICAgIHZhciBvbGRFbmRJZHggPSBvbGRDaC5sZW5ndGggLSAxO1xuICAgIHZhciBvbGRTdGFydFZub2RlID0gb2xkQ2hbMF07XG4gICAgdmFyIG9sZEVuZFZub2RlID0gb2xkQ2hbb2xkRW5kSWR4XTtcbiAgICB2YXIgbmV3RW5kSWR4ID0gbmV3Q2gubGVuZ3RoIC0gMTtcbiAgICB2YXIgbmV3U3RhcnRWbm9kZSA9IG5ld0NoWzBdO1xuICAgIHZhciBuZXdFbmRWbm9kZSA9IG5ld0NoW25ld0VuZElkeF07XG4gICAgdmFyIG9sZEtleVRvSWR4LCBpZHhJbk9sZCwgZWxtVG9Nb3ZlLCByZWZFbG07XG5cbiAgICAvLyByZW1vdmVPbmx5IGlzIGEgc3BlY2lhbCBmbGFnIHVzZWQgb25seSBieSA8dHJhbnNpdGlvbi1ncm91cD5cbiAgICAvLyB0byBlbnN1cmUgcmVtb3ZlZCBlbGVtZW50cyBzdGF5IGluIGNvcnJlY3QgcmVsYXRpdmUgcG9zaXRpb25zXG4gICAgLy8gZHVyaW5nIGxlYXZpbmcgdHJhbnNpdGlvbnNcbiAgICB2YXIgY2FuTW92ZSA9ICFyZW1vdmVPbmx5O1xuXG4gICAgd2hpbGUgKG9sZFN0YXJ0SWR4IDw9IG9sZEVuZElkeCAmJiBuZXdTdGFydElkeCA8PSBuZXdFbmRJZHgpIHtcbiAgICAgIGlmIChpc1VuZGVmKG9sZFN0YXJ0Vm5vZGUpKSB7XG4gICAgICAgIG9sZFN0YXJ0Vm5vZGUgPSBvbGRDaFsrK29sZFN0YXJ0SWR4XTsgLy8gVm5vZGUgaGFzIGJlZW4gbW92ZWQgbGVmdFxuICAgICAgfSBlbHNlIGlmIChpc1VuZGVmKG9sZEVuZFZub2RlKSkge1xuICAgICAgICBvbGRFbmRWbm9kZSA9IG9sZENoWy0tb2xkRW5kSWR4XTtcbiAgICAgIH0gZWxzZSBpZiAoc2FtZVZub2RlKG9sZFN0YXJ0Vm5vZGUsIG5ld1N0YXJ0Vm5vZGUpKSB7XG4gICAgICAgIHBhdGNoVm5vZGUob2xkU3RhcnRWbm9kZSwgbmV3U3RhcnRWbm9kZSwgaW5zZXJ0ZWRWbm9kZVF1ZXVlKTtcbiAgICAgICAgb2xkU3RhcnRWbm9kZSA9IG9sZENoWysrb2xkU3RhcnRJZHhdO1xuICAgICAgICBuZXdTdGFydFZub2RlID0gbmV3Q2hbKytuZXdTdGFydElkeF07XG4gICAgICB9IGVsc2UgaWYgKHNhbWVWbm9kZShvbGRFbmRWbm9kZSwgbmV3RW5kVm5vZGUpKSB7XG4gICAgICAgIHBhdGNoVm5vZGUob2xkRW5kVm5vZGUsIG5ld0VuZFZub2RlLCBpbnNlcnRlZFZub2RlUXVldWUpO1xuICAgICAgICBvbGRFbmRWbm9kZSA9IG9sZENoWy0tb2xkRW5kSWR4XTtcbiAgICAgICAgbmV3RW5kVm5vZGUgPSBuZXdDaFstLW5ld0VuZElkeF07XG4gICAgICB9IGVsc2UgaWYgKHNhbWVWbm9kZShvbGRTdGFydFZub2RlLCBuZXdFbmRWbm9kZSkpIHsgLy8gVm5vZGUgbW92ZWQgcmlnaHRcbiAgICAgICAgcGF0Y2hWbm9kZShvbGRTdGFydFZub2RlLCBuZXdFbmRWbm9kZSwgaW5zZXJ0ZWRWbm9kZVF1ZXVlKTtcbiAgICAgICAgY2FuTW92ZSAmJiBub2RlT3BzLmluc2VydEJlZm9yZShwYXJlbnRFbG0sIG9sZFN0YXJ0Vm5vZGUuZWxtLCBub2RlT3BzLm5leHRTaWJsaW5nKG9sZEVuZFZub2RlLmVsbSkpO1xuICAgICAgICBvbGRTdGFydFZub2RlID0gb2xkQ2hbKytvbGRTdGFydElkeF07XG4gICAgICAgIG5ld0VuZFZub2RlID0gbmV3Q2hbLS1uZXdFbmRJZHhdO1xuICAgICAgfSBlbHNlIGlmIChzYW1lVm5vZGUob2xkRW5kVm5vZGUsIG5ld1N0YXJ0Vm5vZGUpKSB7IC8vIFZub2RlIG1vdmVkIGxlZnRcbiAgICAgICAgcGF0Y2hWbm9kZShvbGRFbmRWbm9kZSwgbmV3U3RhcnRWbm9kZSwgaW5zZXJ0ZWRWbm9kZVF1ZXVlKTtcbiAgICAgICAgY2FuTW92ZSAmJiBub2RlT3BzLmluc2VydEJlZm9yZShwYXJlbnRFbG0sIG9sZEVuZFZub2RlLmVsbSwgb2xkU3RhcnRWbm9kZS5lbG0pO1xuICAgICAgICBvbGRFbmRWbm9kZSA9IG9sZENoWy0tb2xkRW5kSWR4XTtcbiAgICAgICAgbmV3U3RhcnRWbm9kZSA9IG5ld0NoWysrbmV3U3RhcnRJZHhdO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgaWYgKGlzVW5kZWYob2xkS2V5VG9JZHgpKSB7IG9sZEtleVRvSWR4ID0gY3JlYXRlS2V5VG9PbGRJZHgob2xkQ2gsIG9sZFN0YXJ0SWR4LCBvbGRFbmRJZHgpOyB9XG4gICAgICAgIGlkeEluT2xkID0gaXNEZWYobmV3U3RhcnRWbm9kZS5rZXkpXG4gICAgICAgICAgPyBvbGRLZXlUb0lkeFtuZXdTdGFydFZub2RlLmtleV1cbiAgICAgICAgICA6IGZpbmRJZHhJbk9sZChuZXdTdGFydFZub2RlLCBvbGRDaCwgb2xkU3RhcnRJZHgsIG9sZEVuZElkeCk7XG4gICAgICAgIGlmIChpc1VuZGVmKGlkeEluT2xkKSkgeyAvLyBOZXcgZWxlbWVudFxuICAgICAgICAgIGNyZWF0ZUVsbShuZXdTdGFydFZub2RlLCBpbnNlcnRlZFZub2RlUXVldWUsIHBhcmVudEVsbSwgb2xkU3RhcnRWbm9kZS5lbG0pO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGVsbVRvTW92ZSA9IG9sZENoW2lkeEluT2xkXTtcbiAgICAgICAgICAvKiBpc3RhbmJ1bCBpZ25vcmUgaWYgKi9cbiAgICAgICAgICBpZiAocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJyAmJiAhZWxtVG9Nb3ZlKSB7XG4gICAgICAgICAgICB3YXJuKFxuICAgICAgICAgICAgICAnSXQgc2VlbXMgdGhlcmUgYXJlIGR1cGxpY2F0ZSBrZXlzIHRoYXQgaXMgY2F1c2luZyBhbiB1cGRhdGUgZXJyb3IuICcgK1xuICAgICAgICAgICAgICAnTWFrZSBzdXJlIGVhY2ggdi1mb3IgaXRlbSBoYXMgYSB1bmlxdWUga2V5LidcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgfVxuICAgICAgICAgIGlmIChzYW1lVm5vZGUoZWxtVG9Nb3ZlLCBuZXdTdGFydFZub2RlKSkge1xuICAgICAgICAgICAgcGF0Y2hWbm9kZShlbG1Ub01vdmUsIG5ld1N0YXJ0Vm5vZGUsIGluc2VydGVkVm5vZGVRdWV1ZSk7XG4gICAgICAgICAgICBvbGRDaFtpZHhJbk9sZF0gPSB1bmRlZmluZWQ7XG4gICAgICAgICAgICBjYW5Nb3ZlICYmIG5vZGVPcHMuaW5zZXJ0QmVmb3JlKHBhcmVudEVsbSwgZWxtVG9Nb3ZlLmVsbSwgb2xkU3RhcnRWbm9kZS5lbG0pO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAvLyBzYW1lIGtleSBidXQgZGlmZmVyZW50IGVsZW1lbnQuIHRyZWF0IGFzIG5ldyBlbGVtZW50XG4gICAgICAgICAgICBjcmVhdGVFbG0obmV3U3RhcnRWbm9kZSwgaW5zZXJ0ZWRWbm9kZVF1ZXVlLCBwYXJlbnRFbG0sIG9sZFN0YXJ0Vm5vZGUuZWxtKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgbmV3U3RhcnRWbm9kZSA9IG5ld0NoWysrbmV3U3RhcnRJZHhdO1xuICAgICAgfVxuICAgIH1cbiAgICBpZiAob2xkU3RhcnRJZHggPiBvbGRFbmRJZHgpIHtcbiAgICAgIHJlZkVsbSA9IGlzVW5kZWYobmV3Q2hbbmV3RW5kSWR4ICsgMV0pID8gbnVsbCA6IG5ld0NoW25ld0VuZElkeCArIDFdLmVsbTtcbiAgICAgIGFkZFZub2RlcyhwYXJlbnRFbG0sIHJlZkVsbSwgbmV3Q2gsIG5ld1N0YXJ0SWR4LCBuZXdFbmRJZHgsIGluc2VydGVkVm5vZGVRdWV1ZSk7XG4gICAgfSBlbHNlIGlmIChuZXdTdGFydElkeCA+IG5ld0VuZElkeCkge1xuICAgICAgcmVtb3ZlVm5vZGVzKHBhcmVudEVsbSwgb2xkQ2gsIG9sZFN0YXJ0SWR4LCBvbGRFbmRJZHgpO1xuICAgIH1cbiAgfVxuXG4gIGZ1bmN0aW9uIGZpbmRJZHhJbk9sZCAobm9kZSwgb2xkQ2gsIHN0YXJ0LCBlbmQpIHtcbiAgICBmb3IgKHZhciBpID0gc3RhcnQ7IGkgPCBlbmQ7IGkrKykge1xuICAgICAgdmFyIGMgPSBvbGRDaFtpXTtcbiAgICAgIGlmIChpc0RlZihjKSAmJiBzYW1lVm5vZGUobm9kZSwgYykpIHsgcmV0dXJuIGkgfVxuICAgIH1cbiAgfVxuXG4gIGZ1bmN0aW9uIHBhdGNoVm5vZGUgKG9sZFZub2RlLCB2bm9kZSwgaW5zZXJ0ZWRWbm9kZVF1ZXVlLCByZW1vdmVPbmx5KSB7XG4gICAgaWYgKG9sZFZub2RlID09PSB2bm9kZSkge1xuICAgICAgcmV0dXJuXG4gICAgfVxuXG4gICAgdmFyIGVsbSA9IHZub2RlLmVsbSA9IG9sZFZub2RlLmVsbTtcblxuICAgIGlmIChpc1RydWUob2xkVm5vZGUuaXNBc3luY1BsYWNlaG9sZGVyKSkge1xuICAgICAgaWYgKGlzRGVmKHZub2RlLmFzeW5jRmFjdG9yeS5yZXNvbHZlZCkpIHtcbiAgICAgICAgaHlkcmF0ZShvbGRWbm9kZS5lbG0sIHZub2RlLCBpbnNlcnRlZFZub2RlUXVldWUpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdm5vZGUuaXNBc3luY1BsYWNlaG9sZGVyID0gdHJ1ZTtcbiAgICAgIH1cbiAgICAgIHJldHVyblxuICAgIH1cblxuICAgIC8vIHJldXNlIGVsZW1lbnQgZm9yIHN0YXRpYyB0cmVlcy5cbiAgICAvLyBub3RlIHdlIG9ubHkgZG8gdGhpcyBpZiB0aGUgdm5vZGUgaXMgY2xvbmVkIC1cbiAgICAvLyBpZiB0aGUgbmV3IG5vZGUgaXMgbm90IGNsb25lZCBpdCBtZWFucyB0aGUgcmVuZGVyIGZ1bmN0aW9ucyBoYXZlIGJlZW5cbiAgICAvLyByZXNldCBieSB0aGUgaG90LXJlbG9hZC1hcGkgYW5kIHdlIG5lZWQgdG8gZG8gYSBwcm9wZXIgcmUtcmVuZGVyLlxuICAgIGlmIChpc1RydWUodm5vZGUuaXNTdGF0aWMpICYmXG4gICAgICBpc1RydWUob2xkVm5vZGUuaXNTdGF0aWMpICYmXG4gICAgICB2bm9kZS5rZXkgPT09IG9sZFZub2RlLmtleSAmJlxuICAgICAgKGlzVHJ1ZSh2bm9kZS5pc0Nsb25lZCkgfHwgaXNUcnVlKHZub2RlLmlzT25jZSkpXG4gICAgKSB7XG4gICAgICB2bm9kZS5jb21wb25lbnRJbnN0YW5jZSA9IG9sZFZub2RlLmNvbXBvbmVudEluc3RhbmNlO1xuICAgICAgcmV0dXJuXG4gICAgfVxuXG4gICAgdmFyIGk7XG4gICAgdmFyIGRhdGEgPSB2bm9kZS5kYXRhO1xuICAgIGlmIChpc0RlZihkYXRhKSAmJiBpc0RlZihpID0gZGF0YS5ob29rKSAmJiBpc0RlZihpID0gaS5wcmVwYXRjaCkpIHtcbiAgICAgIGkob2xkVm5vZGUsIHZub2RlKTtcbiAgICB9XG5cbiAgICB2YXIgb2xkQ2ggPSBvbGRWbm9kZS5jaGlsZHJlbjtcbiAgICB2YXIgY2ggPSB2bm9kZS5jaGlsZHJlbjtcbiAgICBpZiAoaXNEZWYoZGF0YSkgJiYgaXNQYXRjaGFibGUodm5vZGUpKSB7XG4gICAgICBmb3IgKGkgPSAwOyBpIDwgY2JzLnVwZGF0ZS5sZW5ndGg7ICsraSkgeyBjYnMudXBkYXRlW2ldKG9sZFZub2RlLCB2bm9kZSk7IH1cbiAgICAgIGlmIChpc0RlZihpID0gZGF0YS5ob29rKSAmJiBpc0RlZihpID0gaS51cGRhdGUpKSB7IGkob2xkVm5vZGUsIHZub2RlKTsgfVxuICAgIH1cbiAgICBpZiAoaXNVbmRlZih2bm9kZS50ZXh0KSkge1xuICAgICAgaWYgKGlzRGVmKG9sZENoKSAmJiBpc0RlZihjaCkpIHtcbiAgICAgICAgaWYgKG9sZENoICE9PSBjaCkgeyB1cGRhdGVDaGlsZHJlbihlbG0sIG9sZENoLCBjaCwgaW5zZXJ0ZWRWbm9kZVF1ZXVlLCByZW1vdmVPbmx5KTsgfVxuICAgICAgfSBlbHNlIGlmIChpc0RlZihjaCkpIHtcbiAgICAgICAgaWYgKGlzRGVmKG9sZFZub2RlLnRleHQpKSB7IG5vZGVPcHMuc2V0VGV4dENvbnRlbnQoZWxtLCAnJyk7IH1cbiAgICAgICAgYWRkVm5vZGVzKGVsbSwgbnVsbCwgY2gsIDAsIGNoLmxlbmd0aCAtIDEsIGluc2VydGVkVm5vZGVRdWV1ZSk7XG4gICAgICB9IGVsc2UgaWYgKGlzRGVmKG9sZENoKSkge1xuICAgICAgICByZW1vdmVWbm9kZXMoZWxtLCBvbGRDaCwgMCwgb2xkQ2gubGVuZ3RoIC0gMSk7XG4gICAgICB9IGVsc2UgaWYgKGlzRGVmKG9sZFZub2RlLnRleHQpKSB7XG4gICAgICAgIG5vZGVPcHMuc2V0VGV4dENvbnRlbnQoZWxtLCAnJyk7XG4gICAgICB9XG4gICAgfSBlbHNlIGlmIChvbGRWbm9kZS50ZXh0ICE9PSB2bm9kZS50ZXh0KSB7XG4gICAgICBub2RlT3BzLnNldFRleHRDb250ZW50KGVsbSwgdm5vZGUudGV4dCk7XG4gICAgfVxuICAgIGlmIChpc0RlZihkYXRhKSkge1xuICAgICAgaWYgKGlzRGVmKGkgPSBkYXRhLmhvb2spICYmIGlzRGVmKGkgPSBpLnBvc3RwYXRjaCkpIHsgaShvbGRWbm9kZSwgdm5vZGUpOyB9XG4gICAgfVxuICB9XG5cbiAgZnVuY3Rpb24gaW52b2tlSW5zZXJ0SG9vayAodm5vZGUsIHF1ZXVlLCBpbml0aWFsKSB7XG4gICAgLy8gZGVsYXkgaW5zZXJ0IGhvb2tzIGZvciBjb21wb25lbnQgcm9vdCBub2RlcywgaW52b2tlIHRoZW0gYWZ0ZXIgdGhlXG4gICAgLy8gZWxlbWVudCBpcyByZWFsbHkgaW5zZXJ0ZWRcbiAgICBpZiAoaXNUcnVlKGluaXRpYWwpICYmIGlzRGVmKHZub2RlLnBhcmVudCkpIHtcbiAgICAgIHZub2RlLnBhcmVudC5kYXRhLnBlbmRpbmdJbnNlcnQgPSBxdWV1ZTtcbiAgICB9IGVsc2Uge1xuICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBxdWV1ZS5sZW5ndGg7ICsraSkge1xuICAgICAgICBxdWV1ZVtpXS5kYXRhLmhvb2suaW5zZXJ0KHF1ZXVlW2ldKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICB2YXIgYmFpbGVkID0gZmFsc2U7XG4gIC8vIGxpc3Qgb2YgbW9kdWxlcyB0aGF0IGNhbiBza2lwIGNyZWF0ZSBob29rIGR1cmluZyBoeWRyYXRpb24gYmVjYXVzZSB0aGV5XG4gIC8vIGFyZSBhbHJlYWR5IHJlbmRlcmVkIG9uIHRoZSBjbGllbnQgb3IgaGFzIG5vIG5lZWQgZm9yIGluaXRpYWxpemF0aW9uXG4gIHZhciBpc1JlbmRlcmVkTW9kdWxlID0gbWFrZU1hcCgnYXR0cnMsc3R5bGUsY2xhc3Msc3RhdGljQ2xhc3Msc3RhdGljU3R5bGUsa2V5Jyk7XG5cbiAgLy8gTm90ZTogdGhpcyBpcyBhIGJyb3dzZXItb25seSBmdW5jdGlvbiBzbyB3ZSBjYW4gYXNzdW1lIGVsbXMgYXJlIERPTSBub2Rlcy5cbiAgZnVuY3Rpb24gaHlkcmF0ZSAoZWxtLCB2bm9kZSwgaW5zZXJ0ZWRWbm9kZVF1ZXVlKSB7XG4gICAgaWYgKGlzVHJ1ZSh2bm9kZS5pc0NvbW1lbnQpICYmIGlzRGVmKHZub2RlLmFzeW5jRmFjdG9yeSkpIHtcbiAgICAgIHZub2RlLmVsbSA9IGVsbTtcbiAgICAgIHZub2RlLmlzQXN5bmNQbGFjZWhvbGRlciA9IHRydWU7XG4gICAgICByZXR1cm4gdHJ1ZVxuICAgIH1cbiAgICBpZiAocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJykge1xuICAgICAgaWYgKCFhc3NlcnROb2RlTWF0Y2goZWxtLCB2bm9kZSkpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlXG4gICAgICB9XG4gICAgfVxuICAgIHZub2RlLmVsbSA9IGVsbTtcbiAgICB2YXIgdGFnID0gdm5vZGUudGFnO1xuICAgIHZhciBkYXRhID0gdm5vZGUuZGF0YTtcbiAgICB2YXIgY2hpbGRyZW4gPSB2bm9kZS5jaGlsZHJlbjtcbiAgICBpZiAoaXNEZWYoZGF0YSkpIHtcbiAgICAgIGlmIChpc0RlZihpID0gZGF0YS5ob29rKSAmJiBpc0RlZihpID0gaS5pbml0KSkgeyBpKHZub2RlLCB0cnVlIC8qIGh5ZHJhdGluZyAqLyk7IH1cbiAgICAgIGlmIChpc0RlZihpID0gdm5vZGUuY29tcG9uZW50SW5zdGFuY2UpKSB7XG4gICAgICAgIC8vIGNoaWxkIGNvbXBvbmVudC4gaXQgc2hvdWxkIGhhdmUgaHlkcmF0ZWQgaXRzIG93biB0cmVlLlxuICAgICAgICBpbml0Q29tcG9uZW50KHZub2RlLCBpbnNlcnRlZFZub2RlUXVldWUpO1xuICAgICAgICByZXR1cm4gdHJ1ZVxuICAgICAgfVxuICAgIH1cbiAgICBpZiAoaXNEZWYodGFnKSkge1xuICAgICAgaWYgKGlzRGVmKGNoaWxkcmVuKSkge1xuICAgICAgICAvLyBlbXB0eSBlbGVtZW50LCBhbGxvdyBjbGllbnQgdG8gcGljayB1cCBhbmQgcG9wdWxhdGUgY2hpbGRyZW5cbiAgICAgICAgaWYgKCFlbG0uaGFzQ2hpbGROb2RlcygpKSB7XG4gICAgICAgICAgY3JlYXRlQ2hpbGRyZW4odm5vZGUsIGNoaWxkcmVuLCBpbnNlcnRlZFZub2RlUXVldWUpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIC8vIHYtaHRtbCBhbmQgZG9tUHJvcHM6IGlubmVySFRNTFxuICAgICAgICAgIGlmIChpc0RlZihpID0gZGF0YSkgJiYgaXNEZWYoaSA9IGkuZG9tUHJvcHMpICYmIGlzRGVmKGkgPSBpLmlubmVySFRNTCkpIHtcbiAgICAgICAgICAgIGlmIChpICE9PSBlbG0uaW5uZXJIVE1MKSB7XG4gICAgICAgICAgICAgIC8qIGlzdGFuYnVsIGlnbm9yZSBpZiAqL1xuICAgICAgICAgICAgICBpZiAocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJyAmJlxuICAgICAgICAgICAgICAgIHR5cGVvZiBjb25zb2xlICE9PSAndW5kZWZpbmVkJyAmJlxuICAgICAgICAgICAgICAgICFiYWlsZWRcbiAgICAgICAgICAgICAgKSB7XG4gICAgICAgICAgICAgICAgYmFpbGVkID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICBjb25zb2xlLndhcm4oJ1BhcmVudDogJywgZWxtKTtcbiAgICAgICAgICAgICAgICBjb25zb2xlLndhcm4oJ3NlcnZlciBpbm5lckhUTUw6ICcsIGkpO1xuICAgICAgICAgICAgICAgIGNvbnNvbGUud2FybignY2xpZW50IGlubmVySFRNTDogJywgZWxtLmlubmVySFRNTCk7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlXG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIC8vIGl0ZXJhdGUgYW5kIGNvbXBhcmUgY2hpbGRyZW4gbGlzdHNcbiAgICAgICAgICAgIHZhciBjaGlsZHJlbk1hdGNoID0gdHJ1ZTtcbiAgICAgICAgICAgIHZhciBjaGlsZE5vZGUgPSBlbG0uZmlyc3RDaGlsZDtcbiAgICAgICAgICAgIGZvciAodmFyIGkkMSA9IDA7IGkkMSA8IGNoaWxkcmVuLmxlbmd0aDsgaSQxKyspIHtcbiAgICAgICAgICAgICAgaWYgKCFjaGlsZE5vZGUgfHwgIWh5ZHJhdGUoY2hpbGROb2RlLCBjaGlsZHJlbltpJDFdLCBpbnNlcnRlZFZub2RlUXVldWUpKSB7XG4gICAgICAgICAgICAgICAgY2hpbGRyZW5NYXRjaCA9IGZhbHNlO1xuICAgICAgICAgICAgICAgIGJyZWFrXG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgY2hpbGROb2RlID0gY2hpbGROb2RlLm5leHRTaWJsaW5nO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgLy8gaWYgY2hpbGROb2RlIGlzIG5vdCBudWxsLCBpdCBtZWFucyB0aGUgYWN0dWFsIGNoaWxkTm9kZXMgbGlzdCBpc1xuICAgICAgICAgICAgLy8gbG9uZ2VyIHRoYW4gdGhlIHZpcnR1YWwgY2hpbGRyZW4gbGlzdC5cbiAgICAgICAgICAgIGlmICghY2hpbGRyZW5NYXRjaCB8fCBjaGlsZE5vZGUpIHtcbiAgICAgICAgICAgICAgLyogaXN0YW5idWwgaWdub3JlIGlmICovXG4gICAgICAgICAgICAgIGlmIChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nICYmXG4gICAgICAgICAgICAgICAgdHlwZW9mIGNvbnNvbGUgIT09ICd1bmRlZmluZWQnICYmXG4gICAgICAgICAgICAgICAgIWJhaWxlZFxuICAgICAgICAgICAgICApIHtcbiAgICAgICAgICAgICAgICBiYWlsZWQgPSB0cnVlO1xuICAgICAgICAgICAgICAgIGNvbnNvbGUud2FybignUGFyZW50OiAnLCBlbG0pO1xuICAgICAgICAgICAgICAgIGNvbnNvbGUud2FybignTWlzbWF0Y2hpbmcgY2hpbGROb2RlcyB2cy4gVk5vZGVzOiAnLCBlbG0uY2hpbGROb2RlcywgY2hpbGRyZW4pO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIHJldHVybiBmYWxzZVxuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaWYgKGlzRGVmKGRhdGEpKSB7XG4gICAgICAgIGZvciAodmFyIGtleSBpbiBkYXRhKSB7XG4gICAgICAgICAgaWYgKCFpc1JlbmRlcmVkTW9kdWxlKGtleSkpIHtcbiAgICAgICAgICAgIGludm9rZUNyZWF0ZUhvb2tzKHZub2RlLCBpbnNlcnRlZFZub2RlUXVldWUpO1xuICAgICAgICAgICAgYnJlYWtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKGVsbS5kYXRhICE9PSB2bm9kZS50ZXh0KSB7XG4gICAgICBlbG0uZGF0YSA9IHZub2RlLnRleHQ7XG4gICAgfVxuICAgIHJldHVybiB0cnVlXG4gIH1cblxuICBmdW5jdGlvbiBhc3NlcnROb2RlTWF0Y2ggKG5vZGUsIHZub2RlKSB7XG4gICAgaWYgKGlzRGVmKHZub2RlLnRhZykpIHtcbiAgICAgIHJldHVybiAoXG4gICAgICAgIHZub2RlLnRhZy5pbmRleE9mKCd2dWUtY29tcG9uZW50JykgPT09IDAgfHxcbiAgICAgICAgdm5vZGUudGFnLnRvTG93ZXJDYXNlKCkgPT09IChub2RlLnRhZ05hbWUgJiYgbm9kZS50YWdOYW1lLnRvTG93ZXJDYXNlKCkpXG4gICAgICApXG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiBub2RlLm5vZGVUeXBlID09PSAodm5vZGUuaXNDb21tZW50ID8gOCA6IDMpXG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIGZ1bmN0aW9uIHBhdGNoIChvbGRWbm9kZSwgdm5vZGUsIGh5ZHJhdGluZywgcmVtb3ZlT25seSwgcGFyZW50RWxtLCByZWZFbG0pIHtcbiAgICBpZiAoaXNVbmRlZih2bm9kZSkpIHtcbiAgICAgIGlmIChpc0RlZihvbGRWbm9kZSkpIHsgaW52b2tlRGVzdHJveUhvb2sob2xkVm5vZGUpOyB9XG4gICAgICByZXR1cm5cbiAgICB9XG5cbiAgICB2YXIgaXNJbml0aWFsUGF0Y2ggPSBmYWxzZTtcbiAgICB2YXIgaW5zZXJ0ZWRWbm9kZVF1ZXVlID0gW107XG5cbiAgICBpZiAoaXNVbmRlZihvbGRWbm9kZSkpIHtcbiAgICAgIC8vIGVtcHR5IG1vdW50IChsaWtlbHkgYXMgY29tcG9uZW50KSwgY3JlYXRlIG5ldyByb290IGVsZW1lbnRcbiAgICAgIGlzSW5pdGlhbFBhdGNoID0gdHJ1ZTtcbiAgICAgIGNyZWF0ZUVsbSh2bm9kZSwgaW5zZXJ0ZWRWbm9kZVF1ZXVlLCBwYXJlbnRFbG0sIHJlZkVsbSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHZhciBpc1JlYWxFbGVtZW50ID0gaXNEZWYob2xkVm5vZGUubm9kZVR5cGUpO1xuICAgICAgaWYgKCFpc1JlYWxFbGVtZW50ICYmIHNhbWVWbm9kZShvbGRWbm9kZSwgdm5vZGUpKSB7XG4gICAgICAgIC8vIHBhdGNoIGV4aXN0aW5nIHJvb3Qgbm9kZVxuICAgICAgICBwYXRjaFZub2RlKG9sZFZub2RlLCB2bm9kZSwgaW5zZXJ0ZWRWbm9kZVF1ZXVlLCByZW1vdmVPbmx5KTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGlmIChpc1JlYWxFbGVtZW50KSB7XG4gICAgICAgICAgLy8gbW91bnRpbmcgdG8gYSByZWFsIGVsZW1lbnRcbiAgICAgICAgICAvLyBjaGVjayBpZiB0aGlzIGlzIHNlcnZlci1yZW5kZXJlZCBjb250ZW50IGFuZCBpZiB3ZSBjYW4gcGVyZm9ybVxuICAgICAgICAgIC8vIGEgc3VjY2Vzc2Z1bCBoeWRyYXRpb24uXG4gICAgICAgICAgaWYgKG9sZFZub2RlLm5vZGVUeXBlID09PSAxICYmIG9sZFZub2RlLmhhc0F0dHJpYnV0ZShTU1JfQVRUUikpIHtcbiAgICAgICAgICAgIG9sZFZub2RlLnJlbW92ZUF0dHJpYnV0ZShTU1JfQVRUUik7XG4gICAgICAgICAgICBoeWRyYXRpbmcgPSB0cnVlO1xuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAoaXNUcnVlKGh5ZHJhdGluZykpIHtcbiAgICAgICAgICAgIGlmIChoeWRyYXRlKG9sZFZub2RlLCB2bm9kZSwgaW5zZXJ0ZWRWbm9kZVF1ZXVlKSkge1xuICAgICAgICAgICAgICBpbnZva2VJbnNlcnRIb29rKHZub2RlLCBpbnNlcnRlZFZub2RlUXVldWUsIHRydWUpO1xuICAgICAgICAgICAgICByZXR1cm4gb2xkVm5vZGVcbiAgICAgICAgICAgIH0gZWxzZSBpZiAocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJykge1xuICAgICAgICAgICAgICB3YXJuKFxuICAgICAgICAgICAgICAgICdUaGUgY2xpZW50LXNpZGUgcmVuZGVyZWQgdmlydHVhbCBET00gdHJlZSBpcyBub3QgbWF0Y2hpbmcgJyArXG4gICAgICAgICAgICAgICAgJ3NlcnZlci1yZW5kZXJlZCBjb250ZW50LiBUaGlzIGlzIGxpa2VseSBjYXVzZWQgYnkgaW5jb3JyZWN0ICcgK1xuICAgICAgICAgICAgICAgICdIVE1MIG1hcmt1cCwgZm9yIGV4YW1wbGUgbmVzdGluZyBibG9jay1sZXZlbCBlbGVtZW50cyBpbnNpZGUgJyArXG4gICAgICAgICAgICAgICAgJzxwPiwgb3IgbWlzc2luZyA8dGJvZHk+LiBCYWlsaW5nIGh5ZHJhdGlvbiBhbmQgcGVyZm9ybWluZyAnICtcbiAgICAgICAgICAgICAgICAnZnVsbCBjbGllbnQtc2lkZSByZW5kZXIuJ1xuICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgICAvLyBlaXRoZXIgbm90IHNlcnZlci1yZW5kZXJlZCwgb3IgaHlkcmF0aW9uIGZhaWxlZC5cbiAgICAgICAgICAvLyBjcmVhdGUgYW4gZW1wdHkgbm9kZSBhbmQgcmVwbGFjZSBpdFxuICAgICAgICAgIG9sZFZub2RlID0gZW1wdHlOb2RlQXQob2xkVm5vZGUpO1xuICAgICAgICB9XG4gICAgICAgIC8vIHJlcGxhY2luZyBleGlzdGluZyBlbGVtZW50XG4gICAgICAgIHZhciBvbGRFbG0gPSBvbGRWbm9kZS5lbG07XG4gICAgICAgIHZhciBwYXJlbnRFbG0kMSA9IG5vZGVPcHMucGFyZW50Tm9kZShvbGRFbG0pO1xuICAgICAgICBjcmVhdGVFbG0oXG4gICAgICAgICAgdm5vZGUsXG4gICAgICAgICAgaW5zZXJ0ZWRWbm9kZVF1ZXVlLFxuICAgICAgICAgIC8vIGV4dHJlbWVseSByYXJlIGVkZ2UgY2FzZTogZG8gbm90IGluc2VydCBpZiBvbGQgZWxlbWVudCBpcyBpbiBhXG4gICAgICAgICAgLy8gbGVhdmluZyB0cmFuc2l0aW9uLiBPbmx5IGhhcHBlbnMgd2hlbiBjb21iaW5pbmcgdHJhbnNpdGlvbiArXG4gICAgICAgICAgLy8ga2VlcC1hbGl2ZSArIEhPQ3MuICgjNDU5MClcbiAgICAgICAgICBvbGRFbG0uX2xlYXZlQ2IgPyBudWxsIDogcGFyZW50RWxtJDEsXG4gICAgICAgICAgbm9kZU9wcy5uZXh0U2libGluZyhvbGRFbG0pXG4gICAgICAgICk7XG5cbiAgICAgICAgaWYgKGlzRGVmKHZub2RlLnBhcmVudCkpIHtcbiAgICAgICAgICAvLyBjb21wb25lbnQgcm9vdCBlbGVtZW50IHJlcGxhY2VkLlxuICAgICAgICAgIC8vIHVwZGF0ZSBwYXJlbnQgcGxhY2Vob2xkZXIgbm9kZSBlbGVtZW50LCByZWN1cnNpdmVseVxuICAgICAgICAgIHZhciBhbmNlc3RvciA9IHZub2RlLnBhcmVudDtcbiAgICAgICAgICB2YXIgcGF0Y2hhYmxlID0gaXNQYXRjaGFibGUodm5vZGUpO1xuICAgICAgICAgIHdoaWxlIChhbmNlc3Rvcikge1xuICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBjYnMuZGVzdHJveS5sZW5ndGg7ICsraSkge1xuICAgICAgICAgICAgICBjYnMuZGVzdHJveVtpXShhbmNlc3Rvcik7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBhbmNlc3Rvci5lbG0gPSB2bm9kZS5lbG07XG4gICAgICAgICAgICBpZiAocGF0Y2hhYmxlKSB7XG4gICAgICAgICAgICAgIGZvciAodmFyIGkkMSA9IDA7IGkkMSA8IGNicy5jcmVhdGUubGVuZ3RoOyArK2kkMSkge1xuICAgICAgICAgICAgICAgIGNicy5jcmVhdGVbaSQxXShlbXB0eU5vZGUsIGFuY2VzdG9yKTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAvLyAjNjUxM1xuICAgICAgICAgICAgICAvLyBpbnZva2UgaW5zZXJ0IGhvb2tzIHRoYXQgbWF5IGhhdmUgYmVlbiBtZXJnZWQgYnkgY3JlYXRlIGhvb2tzLlxuICAgICAgICAgICAgICAvLyBlLmcuIGZvciBkaXJlY3RpdmVzIHRoYXQgdXNlcyB0aGUgXCJpbnNlcnRlZFwiIGhvb2suXG4gICAgICAgICAgICAgIHZhciBpbnNlcnQgPSBhbmNlc3Rvci5kYXRhLmhvb2suaW5zZXJ0O1xuICAgICAgICAgICAgICBpZiAoaW5zZXJ0Lm1lcmdlZCkge1xuICAgICAgICAgICAgICAgIC8vIHN0YXJ0IGF0IGluZGV4IDEgdG8gYXZvaWQgcmUtaW52b2tpbmcgY29tcG9uZW50IG1vdW50ZWQgaG9va1xuICAgICAgICAgICAgICAgIGZvciAodmFyIGkkMiA9IDE7IGkkMiA8IGluc2VydC5mbnMubGVuZ3RoOyBpJDIrKykge1xuICAgICAgICAgICAgICAgICAgaW5zZXJ0LmZuc1tpJDJdKCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBhbmNlc3RvciA9IGFuY2VzdG9yLnBhcmVudDtcbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoaXNEZWYocGFyZW50RWxtJDEpKSB7XG4gICAgICAgICAgcmVtb3ZlVm5vZGVzKHBhcmVudEVsbSQxLCBbb2xkVm5vZGVdLCAwLCAwKTtcbiAgICAgICAgfSBlbHNlIGlmIChpc0RlZihvbGRWbm9kZS50YWcpKSB7XG4gICAgICAgICAgaW52b2tlRGVzdHJveUhvb2sob2xkVm5vZGUpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgaW52b2tlSW5zZXJ0SG9vayh2bm9kZSwgaW5zZXJ0ZWRWbm9kZVF1ZXVlLCBpc0luaXRpYWxQYXRjaCk7XG4gICAgcmV0dXJuIHZub2RlLmVsbVxuICB9XG59XG5cbi8qICAqL1xuXG52YXIgZGlyZWN0aXZlcyA9IHtcbiAgY3JlYXRlOiB1cGRhdGVEaXJlY3RpdmVzLFxuICB1cGRhdGU6IHVwZGF0ZURpcmVjdGl2ZXMsXG4gIGRlc3Ryb3k6IGZ1bmN0aW9uIHVuYmluZERpcmVjdGl2ZXMgKHZub2RlKSB7XG4gICAgdXBkYXRlRGlyZWN0aXZlcyh2bm9kZSwgZW1wdHlOb2RlKTtcbiAgfVxufTtcblxuZnVuY3Rpb24gdXBkYXRlRGlyZWN0aXZlcyAob2xkVm5vZGUsIHZub2RlKSB7XG4gIGlmIChvbGRWbm9kZS5kYXRhLmRpcmVjdGl2ZXMgfHwgdm5vZGUuZGF0YS5kaXJlY3RpdmVzKSB7XG4gICAgX3VwZGF0ZShvbGRWbm9kZSwgdm5vZGUpO1xuICB9XG59XG5cbmZ1bmN0aW9uIF91cGRhdGUgKG9sZFZub2RlLCB2bm9kZSkge1xuICB2YXIgaXNDcmVhdGUgPSBvbGRWbm9kZSA9PT0gZW1wdHlOb2RlO1xuICB2YXIgaXNEZXN0cm95ID0gdm5vZGUgPT09IGVtcHR5Tm9kZTtcbiAgdmFyIG9sZERpcnMgPSBub3JtYWxpemVEaXJlY3RpdmVzJDEob2xkVm5vZGUuZGF0YS5kaXJlY3RpdmVzLCBvbGRWbm9kZS5jb250ZXh0KTtcbiAgdmFyIG5ld0RpcnMgPSBub3JtYWxpemVEaXJlY3RpdmVzJDEodm5vZGUuZGF0YS5kaXJlY3RpdmVzLCB2bm9kZS5jb250ZXh0KTtcblxuICB2YXIgZGlyc1dpdGhJbnNlcnQgPSBbXTtcbiAgdmFyIGRpcnNXaXRoUG9zdHBhdGNoID0gW107XG5cbiAgdmFyIGtleSwgb2xkRGlyLCBkaXI7XG4gIGZvciAoa2V5IGluIG5ld0RpcnMpIHtcbiAgICBvbGREaXIgPSBvbGREaXJzW2tleV07XG4gICAgZGlyID0gbmV3RGlyc1trZXldO1xuICAgIGlmICghb2xkRGlyKSB7XG4gICAgICAvLyBuZXcgZGlyZWN0aXZlLCBiaW5kXG4gICAgICBjYWxsSG9vayQxKGRpciwgJ2JpbmQnLCB2bm9kZSwgb2xkVm5vZGUpO1xuICAgICAgaWYgKGRpci5kZWYgJiYgZGlyLmRlZi5pbnNlcnRlZCkge1xuICAgICAgICBkaXJzV2l0aEluc2VydC5wdXNoKGRpcik7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIGV4aXN0aW5nIGRpcmVjdGl2ZSwgdXBkYXRlXG4gICAgICBkaXIub2xkVmFsdWUgPSBvbGREaXIudmFsdWU7XG4gICAgICBjYWxsSG9vayQxKGRpciwgJ3VwZGF0ZScsIHZub2RlLCBvbGRWbm9kZSk7XG4gICAgICBpZiAoZGlyLmRlZiAmJiBkaXIuZGVmLmNvbXBvbmVudFVwZGF0ZWQpIHtcbiAgICAgICAgZGlyc1dpdGhQb3N0cGF0Y2gucHVzaChkaXIpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIGlmIChkaXJzV2l0aEluc2VydC5sZW5ndGgpIHtcbiAgICB2YXIgY2FsbEluc2VydCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgZGlyc1dpdGhJbnNlcnQubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgY2FsbEhvb2skMShkaXJzV2l0aEluc2VydFtpXSwgJ2luc2VydGVkJywgdm5vZGUsIG9sZFZub2RlKTtcbiAgICAgIH1cbiAgICB9O1xuICAgIGlmIChpc0NyZWF0ZSkge1xuICAgICAgbWVyZ2VWTm9kZUhvb2sodm5vZGUuZGF0YS5ob29rIHx8ICh2bm9kZS5kYXRhLmhvb2sgPSB7fSksICdpbnNlcnQnLCBjYWxsSW5zZXJ0KTtcbiAgICB9IGVsc2Uge1xuICAgICAgY2FsbEluc2VydCgpO1xuICAgIH1cbiAgfVxuXG4gIGlmIChkaXJzV2l0aFBvc3RwYXRjaC5sZW5ndGgpIHtcbiAgICBtZXJnZVZOb2RlSG9vayh2bm9kZS5kYXRhLmhvb2sgfHwgKHZub2RlLmRhdGEuaG9vayA9IHt9KSwgJ3Bvc3RwYXRjaCcsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgZGlyc1dpdGhQb3N0cGF0Y2gubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgY2FsbEhvb2skMShkaXJzV2l0aFBvc3RwYXRjaFtpXSwgJ2NvbXBvbmVudFVwZGF0ZWQnLCB2bm9kZSwgb2xkVm5vZGUpO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG5cbiAgaWYgKCFpc0NyZWF0ZSkge1xuICAgIGZvciAoa2V5IGluIG9sZERpcnMpIHtcbiAgICAgIGlmICghbmV3RGlyc1trZXldKSB7XG4gICAgICAgIC8vIG5vIGxvbmdlciBwcmVzZW50LCB1bmJpbmRcbiAgICAgICAgY2FsbEhvb2skMShvbGREaXJzW2tleV0sICd1bmJpbmQnLCBvbGRWbm9kZSwgb2xkVm5vZGUsIGlzRGVzdHJveSk7XG4gICAgICB9XG4gICAgfVxuICB9XG59XG5cbnZhciBlbXB0eU1vZGlmaWVycyA9IE9iamVjdC5jcmVhdGUobnVsbCk7XG5cbmZ1bmN0aW9uIG5vcm1hbGl6ZURpcmVjdGl2ZXMkMSAoXG4gIGRpcnMsXG4gIHZtXG4pIHtcbiAgdmFyIHJlcyA9IE9iamVjdC5jcmVhdGUobnVsbCk7XG4gIGlmICghZGlycykge1xuICAgIHJldHVybiByZXNcbiAgfVxuICB2YXIgaSwgZGlyO1xuICBmb3IgKGkgPSAwOyBpIDwgZGlycy5sZW5ndGg7IGkrKykge1xuICAgIGRpciA9IGRpcnNbaV07XG4gICAgaWYgKCFkaXIubW9kaWZpZXJzKSB7XG4gICAgICBkaXIubW9kaWZpZXJzID0gZW1wdHlNb2RpZmllcnM7XG4gICAgfVxuICAgIHJlc1tnZXRSYXdEaXJOYW1lKGRpcildID0gZGlyO1xuICAgIGRpci5kZWYgPSByZXNvbHZlQXNzZXQodm0uJG9wdGlvbnMsICdkaXJlY3RpdmVzJywgZGlyLm5hbWUsIHRydWUpO1xuICB9XG4gIHJldHVybiByZXNcbn1cblxuZnVuY3Rpb24gZ2V0UmF3RGlyTmFtZSAoZGlyKSB7XG4gIHJldHVybiBkaXIucmF3TmFtZSB8fCAoKGRpci5uYW1lKSArIFwiLlwiICsgKE9iamVjdC5rZXlzKGRpci5tb2RpZmllcnMgfHwge30pLmpvaW4oJy4nKSkpXG59XG5cbmZ1bmN0aW9uIGNhbGxIb29rJDEgKGRpciwgaG9vaywgdm5vZGUsIG9sZFZub2RlLCBpc0Rlc3Ryb3kpIHtcbiAgdmFyIGZuID0gZGlyLmRlZiAmJiBkaXIuZGVmW2hvb2tdO1xuICBpZiAoZm4pIHtcbiAgICB0cnkge1xuICAgICAgZm4odm5vZGUuZWxtLCBkaXIsIHZub2RlLCBvbGRWbm9kZSwgaXNEZXN0cm95KTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICBoYW5kbGVFcnJvcihlLCB2bm9kZS5jb250ZXh0LCAoXCJkaXJlY3RpdmUgXCIgKyAoZGlyLm5hbWUpICsgXCIgXCIgKyBob29rICsgXCIgaG9va1wiKSk7XG4gICAgfVxuICB9XG59XG5cbnZhciBiYXNlTW9kdWxlcyA9IFtcbiAgcmVmLFxuICBkaXJlY3RpdmVzXG5dO1xuXG4vKiAgKi9cblxuZnVuY3Rpb24gdXBkYXRlQXR0cnMgKG9sZFZub2RlLCB2bm9kZSkge1xuICB2YXIgb3B0cyA9IHZub2RlLmNvbXBvbmVudE9wdGlvbnM7XG4gIGlmIChpc0RlZihvcHRzKSAmJiBvcHRzLkN0b3Iub3B0aW9ucy5pbmhlcml0QXR0cnMgPT09IGZhbHNlKSB7XG4gICAgcmV0dXJuXG4gIH1cbiAgaWYgKGlzVW5kZWYob2xkVm5vZGUuZGF0YS5hdHRycykgJiYgaXNVbmRlZih2bm9kZS5kYXRhLmF0dHJzKSkge1xuICAgIHJldHVyblxuICB9XG4gIHZhciBrZXksIGN1ciwgb2xkO1xuICB2YXIgZWxtID0gdm5vZGUuZWxtO1xuICB2YXIgb2xkQXR0cnMgPSBvbGRWbm9kZS5kYXRhLmF0dHJzIHx8IHt9O1xuICB2YXIgYXR0cnMgPSB2bm9kZS5kYXRhLmF0dHJzIHx8IHt9O1xuICAvLyBjbG9uZSBvYnNlcnZlZCBvYmplY3RzLCBhcyB0aGUgdXNlciBwcm9iYWJseSB3YW50cyB0byBtdXRhdGUgaXRcbiAgaWYgKGlzRGVmKGF0dHJzLl9fb2JfXykpIHtcbiAgICBhdHRycyA9IHZub2RlLmRhdGEuYXR0cnMgPSBleHRlbmQoe30sIGF0dHJzKTtcbiAgfVxuXG4gIGZvciAoa2V5IGluIGF0dHJzKSB7XG4gICAgY3VyID0gYXR0cnNba2V5XTtcbiAgICBvbGQgPSBvbGRBdHRyc1trZXldO1xuICAgIGlmIChvbGQgIT09IGN1cikge1xuICAgICAgc2V0QXR0cihlbG0sIGtleSwgY3VyKTtcbiAgICB9XG4gIH1cbiAgLy8gIzQzOTE6IGluIElFOSwgc2V0dGluZyB0eXBlIGNhbiByZXNldCB2YWx1ZSBmb3IgaW5wdXRbdHlwZT1yYWRpb11cbiAgLyogaXN0YW5idWwgaWdub3JlIGlmICovXG4gIGlmIChpc0lFOSAmJiBhdHRycy52YWx1ZSAhPT0gb2xkQXR0cnMudmFsdWUpIHtcbiAgICBzZXRBdHRyKGVsbSwgJ3ZhbHVlJywgYXR0cnMudmFsdWUpO1xuICB9XG4gIGZvciAoa2V5IGluIG9sZEF0dHJzKSB7XG4gICAgaWYgKGlzVW5kZWYoYXR0cnNba2V5XSkpIHtcbiAgICAgIGlmIChpc1hsaW5rKGtleSkpIHtcbiAgICAgICAgZWxtLnJlbW92ZUF0dHJpYnV0ZU5TKHhsaW5rTlMsIGdldFhsaW5rUHJvcChrZXkpKTtcbiAgICAgIH0gZWxzZSBpZiAoIWlzRW51bWVyYXRlZEF0dHIoa2V5KSkge1xuICAgICAgICBlbG0ucmVtb3ZlQXR0cmlidXRlKGtleSk7XG4gICAgICB9XG4gICAgfVxuICB9XG59XG5cbmZ1bmN0aW9uIHNldEF0dHIgKGVsLCBrZXksIHZhbHVlKSB7XG4gIGlmIChpc0Jvb2xlYW5BdHRyKGtleSkpIHtcbiAgICAvLyBzZXQgYXR0cmlidXRlIGZvciBibGFuayB2YWx1ZVxuICAgIC8vIGUuZy4gPG9wdGlvbiBkaXNhYmxlZD5TZWxlY3Qgb25lPC9vcHRpb24+XG4gICAgaWYgKGlzRmFsc3lBdHRyVmFsdWUodmFsdWUpKSB7XG4gICAgICBlbC5yZW1vdmVBdHRyaWJ1dGUoa2V5KTtcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gdGVjaG5pY2FsbHkgYWxsb3dmdWxsc2NyZWVuIGlzIGEgYm9vbGVhbiBhdHRyaWJ1dGUgZm9yIDxpZnJhbWU+LFxuICAgICAgLy8gYnV0IEZsYXNoIGV4cGVjdHMgYSB2YWx1ZSBvZiBcInRydWVcIiB3aGVuIHVzZWQgb24gPGVtYmVkPiB0YWdcbiAgICAgIHZhbHVlID0ga2V5ID09PSAnYWxsb3dmdWxsc2NyZWVuJyAmJiBlbC50YWdOYW1lID09PSAnRU1CRUQnXG4gICAgICAgID8gJ3RydWUnXG4gICAgICAgIDoga2V5O1xuICAgICAgZWwuc2V0QXR0cmlidXRlKGtleSwgdmFsdWUpO1xuICAgIH1cbiAgfSBlbHNlIGlmIChpc0VudW1lcmF0ZWRBdHRyKGtleSkpIHtcbiAgICBlbC5zZXRBdHRyaWJ1dGUoa2V5LCBpc0ZhbHN5QXR0clZhbHVlKHZhbHVlKSB8fCB2YWx1ZSA9PT0gJ2ZhbHNlJyA/ICdmYWxzZScgOiAndHJ1ZScpO1xuICB9IGVsc2UgaWYgKGlzWGxpbmsoa2V5KSkge1xuICAgIGlmIChpc0ZhbHN5QXR0clZhbHVlKHZhbHVlKSkge1xuICAgICAgZWwucmVtb3ZlQXR0cmlidXRlTlMoeGxpbmtOUywgZ2V0WGxpbmtQcm9wKGtleSkpO1xuICAgIH0gZWxzZSB7XG4gICAgICBlbC5zZXRBdHRyaWJ1dGVOUyh4bGlua05TLCBrZXksIHZhbHVlKTtcbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgaWYgKGlzRmFsc3lBdHRyVmFsdWUodmFsdWUpKSB7XG4gICAgICBlbC5yZW1vdmVBdHRyaWJ1dGUoa2V5KTtcbiAgICB9IGVsc2Uge1xuICAgICAgZWwuc2V0QXR0cmlidXRlKGtleSwgdmFsdWUpO1xuICAgIH1cbiAgfVxufVxuXG52YXIgYXR0cnMgPSB7XG4gIGNyZWF0ZTogdXBkYXRlQXR0cnMsXG4gIHVwZGF0ZTogdXBkYXRlQXR0cnNcbn07XG5cbi8qICAqL1xuXG5mdW5jdGlvbiB1cGRhdGVDbGFzcyAob2xkVm5vZGUsIHZub2RlKSB7XG4gIHZhciBlbCA9IHZub2RlLmVsbTtcbiAgdmFyIGRhdGEgPSB2bm9kZS5kYXRhO1xuICB2YXIgb2xkRGF0YSA9IG9sZFZub2RlLmRhdGE7XG4gIGlmIChcbiAgICBpc1VuZGVmKGRhdGEuc3RhdGljQ2xhc3MpICYmXG4gICAgaXNVbmRlZihkYXRhLmNsYXNzKSAmJiAoXG4gICAgICBpc1VuZGVmKG9sZERhdGEpIHx8IChcbiAgICAgICAgaXNVbmRlZihvbGREYXRhLnN0YXRpY0NsYXNzKSAmJlxuICAgICAgICBpc1VuZGVmKG9sZERhdGEuY2xhc3MpXG4gICAgICApXG4gICAgKVxuICApIHtcbiAgICByZXR1cm5cbiAgfVxuXG4gIHZhciBjbHMgPSBnZW5DbGFzc0ZvclZub2RlKHZub2RlKTtcblxuICAvLyBoYW5kbGUgdHJhbnNpdGlvbiBjbGFzc2VzXG4gIHZhciB0cmFuc2l0aW9uQ2xhc3MgPSBlbC5fdHJhbnNpdGlvbkNsYXNzZXM7XG4gIGlmIChpc0RlZih0cmFuc2l0aW9uQ2xhc3MpKSB7XG4gICAgY2xzID0gY29uY2F0KGNscywgc3RyaW5naWZ5Q2xhc3ModHJhbnNpdGlvbkNsYXNzKSk7XG4gIH1cblxuICAvLyBzZXQgdGhlIGNsYXNzXG4gIGlmIChjbHMgIT09IGVsLl9wcmV2Q2xhc3MpIHtcbiAgICBlbC5zZXRBdHRyaWJ1dGUoJ2NsYXNzJywgY2xzKTtcbiAgICBlbC5fcHJldkNsYXNzID0gY2xzO1xuICB9XG59XG5cbnZhciBrbGFzcyA9IHtcbiAgY3JlYXRlOiB1cGRhdGVDbGFzcyxcbiAgdXBkYXRlOiB1cGRhdGVDbGFzc1xufTtcblxuLyogICovXG5cbnZhciB2YWxpZERpdmlzaW9uQ2hhclJFID0gL1tcXHcpLitcXC1fJFxcXV0vO1xuXG5mdW5jdGlvbiBwYXJzZUZpbHRlcnMgKGV4cCkge1xuICB2YXIgaW5TaW5nbGUgPSBmYWxzZTtcbiAgdmFyIGluRG91YmxlID0gZmFsc2U7XG4gIHZhciBpblRlbXBsYXRlU3RyaW5nID0gZmFsc2U7XG4gIHZhciBpblJlZ2V4ID0gZmFsc2U7XG4gIHZhciBjdXJseSA9IDA7XG4gIHZhciBzcXVhcmUgPSAwO1xuICB2YXIgcGFyZW4gPSAwO1xuICB2YXIgbGFzdEZpbHRlckluZGV4ID0gMDtcbiAgdmFyIGMsIHByZXYsIGksIGV4cHJlc3Npb24sIGZpbHRlcnM7XG5cbiAgZm9yIChpID0gMDsgaSA8IGV4cC5sZW5ndGg7IGkrKykge1xuICAgIHByZXYgPSBjO1xuICAgIGMgPSBleHAuY2hhckNvZGVBdChpKTtcbiAgICBpZiAoaW5TaW5nbGUpIHtcbiAgICAgIGlmIChjID09PSAweDI3ICYmIHByZXYgIT09IDB4NUMpIHsgaW5TaW5nbGUgPSBmYWxzZTsgfVxuICAgIH0gZWxzZSBpZiAoaW5Eb3VibGUpIHtcbiAgICAgIGlmIChjID09PSAweDIyICYmIHByZXYgIT09IDB4NUMpIHsgaW5Eb3VibGUgPSBmYWxzZTsgfVxuICAgIH0gZWxzZSBpZiAoaW5UZW1wbGF0ZVN0cmluZykge1xuICAgICAgaWYgKGMgPT09IDB4NjAgJiYgcHJldiAhPT0gMHg1QykgeyBpblRlbXBsYXRlU3RyaW5nID0gZmFsc2U7IH1cbiAgICB9IGVsc2UgaWYgKGluUmVnZXgpIHtcbiAgICAgIGlmIChjID09PSAweDJmICYmIHByZXYgIT09IDB4NUMpIHsgaW5SZWdleCA9IGZhbHNlOyB9XG4gICAgfSBlbHNlIGlmIChcbiAgICAgIGMgPT09IDB4N0MgJiYgLy8gcGlwZVxuICAgICAgZXhwLmNoYXJDb2RlQXQoaSArIDEpICE9PSAweDdDICYmXG4gICAgICBleHAuY2hhckNvZGVBdChpIC0gMSkgIT09IDB4N0MgJiZcbiAgICAgICFjdXJseSAmJiAhc3F1YXJlICYmICFwYXJlblxuICAgICkge1xuICAgICAgaWYgKGV4cHJlc3Npb24gPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAvLyBmaXJzdCBmaWx0ZXIsIGVuZCBvZiBleHByZXNzaW9uXG4gICAgICAgIGxhc3RGaWx0ZXJJbmRleCA9IGkgKyAxO1xuICAgICAgICBleHByZXNzaW9uID0gZXhwLnNsaWNlKDAsIGkpLnRyaW0oKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHB1c2hGaWx0ZXIoKTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgc3dpdGNoIChjKSB7XG4gICAgICAgIGNhc2UgMHgyMjogaW5Eb3VibGUgPSB0cnVlOyBicmVhayAgICAgICAgIC8vIFwiXG4gICAgICAgIGNhc2UgMHgyNzogaW5TaW5nbGUgPSB0cnVlOyBicmVhayAgICAgICAgIC8vICdcbiAgICAgICAgY2FzZSAweDYwOiBpblRlbXBsYXRlU3RyaW5nID0gdHJ1ZTsgYnJlYWsgLy8gYFxuICAgICAgICBjYXNlIDB4Mjg6IHBhcmVuKys7IGJyZWFrICAgICAgICAgICAgICAgICAvLyAoXG4gICAgICAgIGNhc2UgMHgyOTogcGFyZW4tLTsgYnJlYWsgICAgICAgICAgICAgICAgIC8vIClcbiAgICAgICAgY2FzZSAweDVCOiBzcXVhcmUrKzsgYnJlYWsgICAgICAgICAgICAgICAgLy8gW1xuICAgICAgICBjYXNlIDB4NUQ6IHNxdWFyZS0tOyBicmVhayAgICAgICAgICAgICAgICAvLyBdXG4gICAgICAgIGNhc2UgMHg3QjogY3VybHkrKzsgYnJlYWsgICAgICAgICAgICAgICAgIC8vIHtcbiAgICAgICAgY2FzZSAweDdEOiBjdXJseS0tOyBicmVhayAgICAgICAgICAgICAgICAgLy8gfVxuICAgICAgfVxuICAgICAgaWYgKGMgPT09IDB4MmYpIHsgLy8gL1xuICAgICAgICB2YXIgaiA9IGkgLSAxO1xuICAgICAgICB2YXIgcCA9ICh2b2lkIDApO1xuICAgICAgICAvLyBmaW5kIGZpcnN0IG5vbi13aGl0ZXNwYWNlIHByZXYgY2hhclxuICAgICAgICBmb3IgKDsgaiA+PSAwOyBqLS0pIHtcbiAgICAgICAgICBwID0gZXhwLmNoYXJBdChqKTtcbiAgICAgICAgICBpZiAocCAhPT0gJyAnKSB7IGJyZWFrIH1cbiAgICAgICAgfVxuICAgICAgICBpZiAoIXAgfHwgIXZhbGlkRGl2aXNpb25DaGFyUkUudGVzdChwKSkge1xuICAgICAgICAgIGluUmVnZXggPSB0cnVlO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgaWYgKGV4cHJlc3Npb24gPT09IHVuZGVmaW5lZCkge1xuICAgIGV4cHJlc3Npb24gPSBleHAuc2xpY2UoMCwgaSkudHJpbSgpO1xuICB9IGVsc2UgaWYgKGxhc3RGaWx0ZXJJbmRleCAhPT0gMCkge1xuICAgIHB1c2hGaWx0ZXIoKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIHB1c2hGaWx0ZXIgKCkge1xuICAgIChmaWx0ZXJzIHx8IChmaWx0ZXJzID0gW10pKS5wdXNoKGV4cC5zbGljZShsYXN0RmlsdGVySW5kZXgsIGkpLnRyaW0oKSk7XG4gICAgbGFzdEZpbHRlckluZGV4ID0gaSArIDE7XG4gIH1cblxuICBpZiAoZmlsdGVycykge1xuICAgIGZvciAoaSA9IDA7IGkgPCBmaWx0ZXJzLmxlbmd0aDsgaSsrKSB7XG4gICAgICBleHByZXNzaW9uID0gd3JhcEZpbHRlcihleHByZXNzaW9uLCBmaWx0ZXJzW2ldKTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gZXhwcmVzc2lvblxufVxuXG5mdW5jdGlvbiB3cmFwRmlsdGVyIChleHAsIGZpbHRlcikge1xuICB2YXIgaSA9IGZpbHRlci5pbmRleE9mKCcoJyk7XG4gIGlmIChpIDwgMCkge1xuICAgIC8vIF9mOiByZXNvbHZlRmlsdGVyXG4gICAgcmV0dXJuIChcIl9mKFxcXCJcIiArIGZpbHRlciArIFwiXFxcIikoXCIgKyBleHAgKyBcIilcIilcbiAgfSBlbHNlIHtcbiAgICB2YXIgbmFtZSA9IGZpbHRlci5zbGljZSgwLCBpKTtcbiAgICB2YXIgYXJncyA9IGZpbHRlci5zbGljZShpICsgMSk7XG4gICAgcmV0dXJuIChcIl9mKFxcXCJcIiArIG5hbWUgKyBcIlxcXCIpKFwiICsgZXhwICsgXCIsXCIgKyBhcmdzKVxuICB9XG59XG5cbi8qICAqL1xuXG5mdW5jdGlvbiBiYXNlV2FybiAobXNnKSB7XG4gIGNvbnNvbGUuZXJyb3IoKFwiW1Z1ZSBjb21waWxlcl06IFwiICsgbXNnKSk7XG59XG5cbmZ1bmN0aW9uIHBsdWNrTW9kdWxlRnVuY3Rpb24gKFxuICBtb2R1bGVzLFxuICBrZXlcbikge1xuICByZXR1cm4gbW9kdWxlc1xuICAgID8gbW9kdWxlcy5tYXAoZnVuY3Rpb24gKG0pIHsgcmV0dXJuIG1ba2V5XTsgfSkuZmlsdGVyKGZ1bmN0aW9uIChfKSB7IHJldHVybiBfOyB9KVxuICAgIDogW11cbn1cblxuZnVuY3Rpb24gYWRkUHJvcCAoZWwsIG5hbWUsIHZhbHVlKSB7XG4gIChlbC5wcm9wcyB8fCAoZWwucHJvcHMgPSBbXSkpLnB1c2goeyBuYW1lOiBuYW1lLCB2YWx1ZTogdmFsdWUgfSk7XG59XG5cbmZ1bmN0aW9uIGFkZEF0dHIgKGVsLCBuYW1lLCB2YWx1ZSkge1xuICAoZWwuYXR0cnMgfHwgKGVsLmF0dHJzID0gW10pKS5wdXNoKHsgbmFtZTogbmFtZSwgdmFsdWU6IHZhbHVlIH0pO1xufVxuXG5mdW5jdGlvbiBhZGREaXJlY3RpdmUgKFxuICBlbCxcbiAgbmFtZSxcbiAgcmF3TmFtZSxcbiAgdmFsdWUsXG4gIGFyZyxcbiAgbW9kaWZpZXJzXG4pIHtcbiAgKGVsLmRpcmVjdGl2ZXMgfHwgKGVsLmRpcmVjdGl2ZXMgPSBbXSkpLnB1c2goeyBuYW1lOiBuYW1lLCByYXdOYW1lOiByYXdOYW1lLCB2YWx1ZTogdmFsdWUsIGFyZzogYXJnLCBtb2RpZmllcnM6IG1vZGlmaWVycyB9KTtcbn1cblxuZnVuY3Rpb24gYWRkSGFuZGxlciAoXG4gIGVsLFxuICBuYW1lLFxuICB2YWx1ZSxcbiAgbW9kaWZpZXJzLFxuICBpbXBvcnRhbnQsXG4gIHdhcm5cbikge1xuICAvLyB3YXJuIHByZXZlbnQgYW5kIHBhc3NpdmUgbW9kaWZpZXJcbiAgLyogaXN0YW5idWwgaWdub3JlIGlmICovXG4gIGlmIChcbiAgICBwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nICYmIHdhcm4gJiZcbiAgICBtb2RpZmllcnMgJiYgbW9kaWZpZXJzLnByZXZlbnQgJiYgbW9kaWZpZXJzLnBhc3NpdmVcbiAgKSB7XG4gICAgd2FybihcbiAgICAgICdwYXNzaXZlIGFuZCBwcmV2ZW50IGNhblxcJ3QgYmUgdXNlZCB0b2dldGhlci4gJyArXG4gICAgICAnUGFzc2l2ZSBoYW5kbGVyIGNhblxcJ3QgcHJldmVudCBkZWZhdWx0IGV2ZW50LidcbiAgICApO1xuICB9XG4gIC8vIGNoZWNrIGNhcHR1cmUgbW9kaWZpZXJcbiAgaWYgKG1vZGlmaWVycyAmJiBtb2RpZmllcnMuY2FwdHVyZSkge1xuICAgIGRlbGV0ZSBtb2RpZmllcnMuY2FwdHVyZTtcbiAgICBuYW1lID0gJyEnICsgbmFtZTsgLy8gbWFyayB0aGUgZXZlbnQgYXMgY2FwdHVyZWRcbiAgfVxuICBpZiAobW9kaWZpZXJzICYmIG1vZGlmaWVycy5vbmNlKSB7XG4gICAgZGVsZXRlIG1vZGlmaWVycy5vbmNlO1xuICAgIG5hbWUgPSAnficgKyBuYW1lOyAvLyBtYXJrIHRoZSBldmVudCBhcyBvbmNlXG4gIH1cbiAgLyogaXN0YW5idWwgaWdub3JlIGlmICovXG4gIGlmIChtb2RpZmllcnMgJiYgbW9kaWZpZXJzLnBhc3NpdmUpIHtcbiAgICBkZWxldGUgbW9kaWZpZXJzLnBhc3NpdmU7XG4gICAgbmFtZSA9ICcmJyArIG5hbWU7IC8vIG1hcmsgdGhlIGV2ZW50IGFzIHBhc3NpdmVcbiAgfVxuICB2YXIgZXZlbnRzO1xuICBpZiAobW9kaWZpZXJzICYmIG1vZGlmaWVycy5uYXRpdmUpIHtcbiAgICBkZWxldGUgbW9kaWZpZXJzLm5hdGl2ZTtcbiAgICBldmVudHMgPSBlbC5uYXRpdmVFdmVudHMgfHwgKGVsLm5hdGl2ZUV2ZW50cyA9IHt9KTtcbiAgfSBlbHNlIHtcbiAgICBldmVudHMgPSBlbC5ldmVudHMgfHwgKGVsLmV2ZW50cyA9IHt9KTtcbiAgfVxuICB2YXIgbmV3SGFuZGxlciA9IHsgdmFsdWU6IHZhbHVlLCBtb2RpZmllcnM6IG1vZGlmaWVycyB9O1xuICB2YXIgaGFuZGxlcnMgPSBldmVudHNbbmFtZV07XG4gIC8qIGlzdGFuYnVsIGlnbm9yZSBpZiAqL1xuICBpZiAoQXJyYXkuaXNBcnJheShoYW5kbGVycykpIHtcbiAgICBpbXBvcnRhbnQgPyBoYW5kbGVycy51bnNoaWZ0KG5ld0hhbmRsZXIpIDogaGFuZGxlcnMucHVzaChuZXdIYW5kbGVyKTtcbiAgfSBlbHNlIGlmIChoYW5kbGVycykge1xuICAgIGV2ZW50c1tuYW1lXSA9IGltcG9ydGFudCA/IFtuZXdIYW5kbGVyLCBoYW5kbGVyc10gOiBbaGFuZGxlcnMsIG5ld0hhbmRsZXJdO1xuICB9IGVsc2Uge1xuICAgIGV2ZW50c1tuYW1lXSA9IG5ld0hhbmRsZXI7XG4gIH1cbn1cblxuZnVuY3Rpb24gZ2V0QmluZGluZ0F0dHIgKFxuICBlbCxcbiAgbmFtZSxcbiAgZ2V0U3RhdGljXG4pIHtcbiAgdmFyIGR5bmFtaWNWYWx1ZSA9XG4gICAgZ2V0QW5kUmVtb3ZlQXR0cihlbCwgJzonICsgbmFtZSkgfHxcbiAgICBnZXRBbmRSZW1vdmVBdHRyKGVsLCAndi1iaW5kOicgKyBuYW1lKTtcbiAgaWYgKGR5bmFtaWNWYWx1ZSAhPSBudWxsKSB7XG4gICAgcmV0dXJuIHBhcnNlRmlsdGVycyhkeW5hbWljVmFsdWUpXG4gIH0gZWxzZSBpZiAoZ2V0U3RhdGljICE9PSBmYWxzZSkge1xuICAgIHZhciBzdGF0aWNWYWx1ZSA9IGdldEFuZFJlbW92ZUF0dHIoZWwsIG5hbWUpO1xuICAgIGlmIChzdGF0aWNWYWx1ZSAhPSBudWxsKSB7XG4gICAgICByZXR1cm4gSlNPTi5zdHJpbmdpZnkoc3RhdGljVmFsdWUpXG4gICAgfVxuICB9XG59XG5cbmZ1bmN0aW9uIGdldEFuZFJlbW92ZUF0dHIgKGVsLCBuYW1lKSB7XG4gIHZhciB2YWw7XG4gIGlmICgodmFsID0gZWwuYXR0cnNNYXBbbmFtZV0pICE9IG51bGwpIHtcbiAgICB2YXIgbGlzdCA9IGVsLmF0dHJzTGlzdDtcbiAgICBmb3IgKHZhciBpID0gMCwgbCA9IGxpc3QubGVuZ3RoOyBpIDwgbDsgaSsrKSB7XG4gICAgICBpZiAobGlzdFtpXS5uYW1lID09PSBuYW1lKSB7XG4gICAgICAgIGxpc3Quc3BsaWNlKGksIDEpO1xuICAgICAgICBicmVha1xuICAgICAgfVxuICAgIH1cbiAgfVxuICByZXR1cm4gdmFsXG59XG5cbi8qICAqL1xuXG4vKipcbiAqIENyb3NzLXBsYXRmb3JtIGNvZGUgZ2VuZXJhdGlvbiBmb3IgY29tcG9uZW50IHYtbW9kZWxcbiAqL1xuZnVuY3Rpb24gZ2VuQ29tcG9uZW50TW9kZWwgKFxuICBlbCxcbiAgdmFsdWUsXG4gIG1vZGlmaWVyc1xuKSB7XG4gIHZhciByZWYgPSBtb2RpZmllcnMgfHwge307XG4gIHZhciBudW1iZXIgPSByZWYubnVtYmVyO1xuICB2YXIgdHJpbSA9IHJlZi50cmltO1xuXG4gIHZhciBiYXNlVmFsdWVFeHByZXNzaW9uID0gJyQkdic7XG4gIHZhciB2YWx1ZUV4cHJlc3Npb24gPSBiYXNlVmFsdWVFeHByZXNzaW9uO1xuICBpZiAodHJpbSkge1xuICAgIHZhbHVlRXhwcmVzc2lvbiA9XG4gICAgICBcIih0eXBlb2YgXCIgKyBiYXNlVmFsdWVFeHByZXNzaW9uICsgXCIgPT09ICdzdHJpbmcnXCIgK1xuICAgICAgICBcIj8gXCIgKyBiYXNlVmFsdWVFeHByZXNzaW9uICsgXCIudHJpbSgpXCIgK1xuICAgICAgICBcIjogXCIgKyBiYXNlVmFsdWVFeHByZXNzaW9uICsgXCIpXCI7XG4gIH1cbiAgaWYgKG51bWJlcikge1xuICAgIHZhbHVlRXhwcmVzc2lvbiA9IFwiX24oXCIgKyB2YWx1ZUV4cHJlc3Npb24gKyBcIilcIjtcbiAgfVxuICB2YXIgYXNzaWdubWVudCA9IGdlbkFzc2lnbm1lbnRDb2RlKHZhbHVlLCB2YWx1ZUV4cHJlc3Npb24pO1xuXG4gIGVsLm1vZGVsID0ge1xuICAgIHZhbHVlOiAoXCIoXCIgKyB2YWx1ZSArIFwiKVwiKSxcbiAgICBleHByZXNzaW9uOiAoXCJcXFwiXCIgKyB2YWx1ZSArIFwiXFxcIlwiKSxcbiAgICBjYWxsYmFjazogKFwiZnVuY3Rpb24gKFwiICsgYmFzZVZhbHVlRXhwcmVzc2lvbiArIFwiKSB7XCIgKyBhc3NpZ25tZW50ICsgXCJ9XCIpXG4gIH07XG59XG5cbi8qKlxuICogQ3Jvc3MtcGxhdGZvcm0gY29kZWdlbiBoZWxwZXIgZm9yIGdlbmVyYXRpbmcgdi1tb2RlbCB2YWx1ZSBhc3NpZ25tZW50IGNvZGUuXG4gKi9cbmZ1bmN0aW9uIGdlbkFzc2lnbm1lbnRDb2RlIChcbiAgdmFsdWUsXG4gIGFzc2lnbm1lbnRcbikge1xuICB2YXIgbW9kZWxScyA9IHBhcnNlTW9kZWwodmFsdWUpO1xuICBpZiAobW9kZWxScy5pZHggPT09IG51bGwpIHtcbiAgICByZXR1cm4gKHZhbHVlICsgXCI9XCIgKyBhc3NpZ25tZW50KVxuICB9IGVsc2Uge1xuICAgIHJldHVybiAoXCIkc2V0KFwiICsgKG1vZGVsUnMuZXhwKSArIFwiLCBcIiArIChtb2RlbFJzLmlkeCkgKyBcIiwgXCIgKyBhc3NpZ25tZW50ICsgXCIpXCIpXG4gIH1cbn1cblxuLyoqXG4gKiBwYXJzZSBkaXJlY3RpdmUgbW9kZWwgdG8gZG8gdGhlIGFycmF5IHVwZGF0ZSB0cmFuc2Zvcm0uIGFbaWR4XSA9IHZhbCA9PiAkJGEuc3BsaWNlKCQkaWR4LCAxLCB2YWwpXG4gKlxuICogZm9yIGxvb3AgcG9zc2libGUgY2FzZXM6XG4gKlxuICogLSB0ZXN0XG4gKiAtIHRlc3RbaWR4XVxuICogLSB0ZXN0W3Rlc3QxW2lkeF1dXG4gKiAtIHRlc3RbXCJhXCJdW2lkeF1cbiAqIC0geHh4LnRlc3RbYVthXS50ZXN0MVtpZHhdXVxuICogLSB0ZXN0Lnh4eC5hW1wiYXNhXCJdW3Rlc3QxW2lkeF1dXG4gKlxuICovXG5cbnZhciBsZW47XG52YXIgc3RyO1xudmFyIGNocjtcbnZhciBpbmRleCQxO1xudmFyIGV4cHJlc3Npb25Qb3M7XG52YXIgZXhwcmVzc2lvbkVuZFBvcztcblxuZnVuY3Rpb24gcGFyc2VNb2RlbCAodmFsKSB7XG4gIHN0ciA9IHZhbDtcbiAgbGVuID0gc3RyLmxlbmd0aDtcbiAgaW5kZXgkMSA9IGV4cHJlc3Npb25Qb3MgPSBleHByZXNzaW9uRW5kUG9zID0gMDtcblxuICBpZiAodmFsLmluZGV4T2YoJ1snKSA8IDAgfHwgdmFsLmxhc3RJbmRleE9mKCddJykgPCBsZW4gLSAxKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIGV4cDogdmFsLFxuICAgICAgaWR4OiBudWxsXG4gICAgfVxuICB9XG5cbiAgd2hpbGUgKCFlb2YoKSkge1xuICAgIGNociA9IG5leHQoKTtcbiAgICAvKiBpc3RhbmJ1bCBpZ25vcmUgaWYgKi9cbiAgICBpZiAoaXNTdHJpbmdTdGFydChjaHIpKSB7XG4gICAgICBwYXJzZVN0cmluZyhjaHIpO1xuICAgIH0gZWxzZSBpZiAoY2hyID09PSAweDVCKSB7XG4gICAgICBwYXJzZUJyYWNrZXQoY2hyKTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4ge1xuICAgIGV4cDogdmFsLnN1YnN0cmluZygwLCBleHByZXNzaW9uUG9zKSxcbiAgICBpZHg6IHZhbC5zdWJzdHJpbmcoZXhwcmVzc2lvblBvcyArIDEsIGV4cHJlc3Npb25FbmRQb3MpXG4gIH1cbn1cblxuZnVuY3Rpb24gbmV4dCAoKSB7XG4gIHJldHVybiBzdHIuY2hhckNvZGVBdCgrK2luZGV4JDEpXG59XG5cbmZ1bmN0aW9uIGVvZiAoKSB7XG4gIHJldHVybiBpbmRleCQxID49IGxlblxufVxuXG5mdW5jdGlvbiBpc1N0cmluZ1N0YXJ0IChjaHIpIHtcbiAgcmV0dXJuIGNociA9PT0gMHgyMiB8fCBjaHIgPT09IDB4Mjdcbn1cblxuZnVuY3Rpb24gcGFyc2VCcmFja2V0IChjaHIpIHtcbiAgdmFyIGluQnJhY2tldCA9IDE7XG4gIGV4cHJlc3Npb25Qb3MgPSBpbmRleCQxO1xuICB3aGlsZSAoIWVvZigpKSB7XG4gICAgY2hyID0gbmV4dCgpO1xuICAgIGlmIChpc1N0cmluZ1N0YXJ0KGNocikpIHtcbiAgICAgIHBhcnNlU3RyaW5nKGNocik7XG4gICAgICBjb250aW51ZVxuICAgIH1cbiAgICBpZiAoY2hyID09PSAweDVCKSB7IGluQnJhY2tldCsrOyB9XG4gICAgaWYgKGNociA9PT0gMHg1RCkgeyBpbkJyYWNrZXQtLTsgfVxuICAgIGlmIChpbkJyYWNrZXQgPT09IDApIHtcbiAgICAgIGV4cHJlc3Npb25FbmRQb3MgPSBpbmRleCQxO1xuICAgICAgYnJlYWtcbiAgICB9XG4gIH1cbn1cblxuZnVuY3Rpb24gcGFyc2VTdHJpbmcgKGNocikge1xuICB2YXIgc3RyaW5nUXVvdGUgPSBjaHI7XG4gIHdoaWxlICghZW9mKCkpIHtcbiAgICBjaHIgPSBuZXh0KCk7XG4gICAgaWYgKGNociA9PT0gc3RyaW5nUXVvdGUpIHtcbiAgICAgIGJyZWFrXG4gICAgfVxuICB9XG59XG5cbi8qICAqL1xuXG52YXIgd2FybiQxO1xuXG4vLyBpbiBzb21lIGNhc2VzLCB0aGUgZXZlbnQgdXNlZCBoYXMgdG8gYmUgZGV0ZXJtaW5lZCBhdCBydW50aW1lXG4vLyBzbyB3ZSB1c2VkIHNvbWUgcmVzZXJ2ZWQgdG9rZW5zIGR1cmluZyBjb21waWxlLlxudmFyIFJBTkdFX1RPS0VOID0gJ19fcic7XG52YXIgQ0hFQ0tCT1hfUkFESU9fVE9LRU4gPSAnX19jJztcblxuZnVuY3Rpb24gbW9kZWwgKFxuICBlbCxcbiAgZGlyLFxuICBfd2FyblxuKSB7XG4gIHdhcm4kMSA9IF93YXJuO1xuICB2YXIgdmFsdWUgPSBkaXIudmFsdWU7XG4gIHZhciBtb2RpZmllcnMgPSBkaXIubW9kaWZpZXJzO1xuICB2YXIgdGFnID0gZWwudGFnO1xuICB2YXIgdHlwZSA9IGVsLmF0dHJzTWFwLnR5cGU7XG5cbiAgaWYgKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicpIHtcbiAgICB2YXIgZHluYW1pY1R5cGUgPSBlbC5hdHRyc01hcFsndi1iaW5kOnR5cGUnXSB8fCBlbC5hdHRyc01hcFsnOnR5cGUnXTtcbiAgICBpZiAodGFnID09PSAnaW5wdXQnICYmIGR5bmFtaWNUeXBlKSB7XG4gICAgICB3YXJuJDEoXG4gICAgICAgIFwiPGlucHV0IDp0eXBlPVxcXCJcIiArIGR5bmFtaWNUeXBlICsgXCJcXFwiIHYtbW9kZWw9XFxcIlwiICsgdmFsdWUgKyBcIlxcXCI+OlxcblwiICtcbiAgICAgICAgXCJ2LW1vZGVsIGRvZXMgbm90IHN1cHBvcnQgZHluYW1pYyBpbnB1dCB0eXBlcy4gVXNlIHYtaWYgYnJhbmNoZXMgaW5zdGVhZC5cIlxuICAgICAgKTtcbiAgICB9XG4gICAgLy8gaW5wdXRzIHdpdGggdHlwZT1cImZpbGVcIiBhcmUgcmVhZCBvbmx5IGFuZCBzZXR0aW5nIHRoZSBpbnB1dCdzXG4gICAgLy8gdmFsdWUgd2lsbCB0aHJvdyBhbiBlcnJvci5cbiAgICBpZiAodGFnID09PSAnaW5wdXQnICYmIHR5cGUgPT09ICdmaWxlJykge1xuICAgICAgd2FybiQxKFxuICAgICAgICBcIjxcIiArIChlbC50YWcpICsgXCIgdi1tb2RlbD1cXFwiXCIgKyB2YWx1ZSArIFwiXFxcIiB0eXBlPVxcXCJmaWxlXFxcIj46XFxuXCIgK1xuICAgICAgICBcIkZpbGUgaW5wdXRzIGFyZSByZWFkIG9ubHkuIFVzZSBhIHYtb246Y2hhbmdlIGxpc3RlbmVyIGluc3RlYWQuXCJcbiAgICAgICk7XG4gICAgfVxuICB9XG5cbiAgaWYgKGVsLmNvbXBvbmVudCkge1xuICAgIGdlbkNvbXBvbmVudE1vZGVsKGVsLCB2YWx1ZSwgbW9kaWZpZXJzKTtcbiAgICAvLyBjb21wb25lbnQgdi1tb2RlbCBkb2Vzbid0IG5lZWQgZXh0cmEgcnVudGltZVxuICAgIHJldHVybiBmYWxzZVxuICB9IGVsc2UgaWYgKHRhZyA9PT0gJ3NlbGVjdCcpIHtcbiAgICBnZW5TZWxlY3QoZWwsIHZhbHVlLCBtb2RpZmllcnMpO1xuICB9IGVsc2UgaWYgKHRhZyA9PT0gJ2lucHV0JyAmJiB0eXBlID09PSAnY2hlY2tib3gnKSB7XG4gICAgZ2VuQ2hlY2tib3hNb2RlbChlbCwgdmFsdWUsIG1vZGlmaWVycyk7XG4gIH0gZWxzZSBpZiAodGFnID09PSAnaW5wdXQnICYmIHR5cGUgPT09ICdyYWRpbycpIHtcbiAgICBnZW5SYWRpb01vZGVsKGVsLCB2YWx1ZSwgbW9kaWZpZXJzKTtcbiAgfSBlbHNlIGlmICh0YWcgPT09ICdpbnB1dCcgfHwgdGFnID09PSAndGV4dGFyZWEnKSB7XG4gICAgZ2VuRGVmYXVsdE1vZGVsKGVsLCB2YWx1ZSwgbW9kaWZpZXJzKTtcbiAgfSBlbHNlIGlmICghY29uZmlnLmlzUmVzZXJ2ZWRUYWcodGFnKSkge1xuICAgIGdlbkNvbXBvbmVudE1vZGVsKGVsLCB2YWx1ZSwgbW9kaWZpZXJzKTtcbiAgICAvLyBjb21wb25lbnQgdi1tb2RlbCBkb2Vzbid0IG5lZWQgZXh0cmEgcnVudGltZVxuICAgIHJldHVybiBmYWxzZVxuICB9IGVsc2UgaWYgKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicpIHtcbiAgICB3YXJuJDEoXG4gICAgICBcIjxcIiArIChlbC50YWcpICsgXCIgdi1tb2RlbD1cXFwiXCIgKyB2YWx1ZSArIFwiXFxcIj46IFwiICtcbiAgICAgIFwidi1tb2RlbCBpcyBub3Qgc3VwcG9ydGVkIG9uIHRoaXMgZWxlbWVudCB0eXBlLiBcIiArXG4gICAgICAnSWYgeW91IGFyZSB3b3JraW5nIHdpdGggY29udGVudGVkaXRhYmxlLCBpdFxcJ3MgcmVjb21tZW5kZWQgdG8gJyArXG4gICAgICAnd3JhcCBhIGxpYnJhcnkgZGVkaWNhdGVkIGZvciB0aGF0IHB1cnBvc2UgaW5zaWRlIGEgY3VzdG9tIGNvbXBvbmVudC4nXG4gICAgKTtcbiAgfVxuXG4gIC8vIGVuc3VyZSBydW50aW1lIGRpcmVjdGl2ZSBtZXRhZGF0YVxuICByZXR1cm4gdHJ1ZVxufVxuXG5mdW5jdGlvbiBnZW5DaGVja2JveE1vZGVsIChcbiAgZWwsXG4gIHZhbHVlLFxuICBtb2RpZmllcnNcbikge1xuICB2YXIgbnVtYmVyID0gbW9kaWZpZXJzICYmIG1vZGlmaWVycy5udW1iZXI7XG4gIHZhciB2YWx1ZUJpbmRpbmcgPSBnZXRCaW5kaW5nQXR0cihlbCwgJ3ZhbHVlJykgfHwgJ251bGwnO1xuICB2YXIgdHJ1ZVZhbHVlQmluZGluZyA9IGdldEJpbmRpbmdBdHRyKGVsLCAndHJ1ZS12YWx1ZScpIHx8ICd0cnVlJztcbiAgdmFyIGZhbHNlVmFsdWVCaW5kaW5nID0gZ2V0QmluZGluZ0F0dHIoZWwsICdmYWxzZS12YWx1ZScpIHx8ICdmYWxzZSc7XG4gIGFkZFByb3AoZWwsICdjaGVja2VkJyxcbiAgICBcIkFycmF5LmlzQXJyYXkoXCIgKyB2YWx1ZSArIFwiKVwiICtcbiAgICAgIFwiP19pKFwiICsgdmFsdWUgKyBcIixcIiArIHZhbHVlQmluZGluZyArIFwiKT4tMVwiICsgKFxuICAgICAgICB0cnVlVmFsdWVCaW5kaW5nID09PSAndHJ1ZSdcbiAgICAgICAgICA/IChcIjooXCIgKyB2YWx1ZSArIFwiKVwiKVxuICAgICAgICAgIDogKFwiOl9xKFwiICsgdmFsdWUgKyBcIixcIiArIHRydWVWYWx1ZUJpbmRpbmcgKyBcIilcIilcbiAgICAgIClcbiAgKTtcbiAgYWRkSGFuZGxlcihlbCwgQ0hFQ0tCT1hfUkFESU9fVE9LRU4sXG4gICAgXCJ2YXIgJCRhPVwiICsgdmFsdWUgKyBcIixcIiArXG4gICAgICAgICckJGVsPSRldmVudC50YXJnZXQsJyArXG4gICAgICAgIFwiJCRjPSQkZWwuY2hlY2tlZD8oXCIgKyB0cnVlVmFsdWVCaW5kaW5nICsgXCIpOihcIiArIGZhbHNlVmFsdWVCaW5kaW5nICsgXCIpO1wiICtcbiAgICAnaWYoQXJyYXkuaXNBcnJheSgkJGEpKXsnICtcbiAgICAgIFwidmFyICQkdj1cIiArIChudW1iZXIgPyAnX24oJyArIHZhbHVlQmluZGluZyArICcpJyA6IHZhbHVlQmluZGluZykgKyBcIixcIiArXG4gICAgICAgICAgJyQkaT1faSgkJGEsJCR2KTsnICtcbiAgICAgIFwiaWYoJCRlbC5jaGVja2VkKXskJGk8MCYmKFwiICsgdmFsdWUgKyBcIj0kJGEuY29uY2F0KFskJHZdKSl9XCIgK1xuICAgICAgXCJlbHNleyQkaT4tMSYmKFwiICsgdmFsdWUgKyBcIj0kJGEuc2xpY2UoMCwkJGkpLmNvbmNhdCgkJGEuc2xpY2UoJCRpKzEpKSl9XCIgK1xuICAgIFwifWVsc2V7XCIgKyAoZ2VuQXNzaWdubWVudENvZGUodmFsdWUsICckJGMnKSkgKyBcIn1cIixcbiAgICBudWxsLCB0cnVlXG4gICk7XG59XG5cbmZ1bmN0aW9uIGdlblJhZGlvTW9kZWwgKFxuICAgIGVsLFxuICAgIHZhbHVlLFxuICAgIG1vZGlmaWVyc1xuKSB7XG4gIHZhciBudW1iZXIgPSBtb2RpZmllcnMgJiYgbW9kaWZpZXJzLm51bWJlcjtcbiAgdmFyIHZhbHVlQmluZGluZyA9IGdldEJpbmRpbmdBdHRyKGVsLCAndmFsdWUnKSB8fCAnbnVsbCc7XG4gIHZhbHVlQmluZGluZyA9IG51bWJlciA/IChcIl9uKFwiICsgdmFsdWVCaW5kaW5nICsgXCIpXCIpIDogdmFsdWVCaW5kaW5nO1xuICBhZGRQcm9wKGVsLCAnY2hlY2tlZCcsIChcIl9xKFwiICsgdmFsdWUgKyBcIixcIiArIHZhbHVlQmluZGluZyArIFwiKVwiKSk7XG4gIGFkZEhhbmRsZXIoZWwsIENIRUNLQk9YX1JBRElPX1RPS0VOLCBnZW5Bc3NpZ25tZW50Q29kZSh2YWx1ZSwgdmFsdWVCaW5kaW5nKSwgbnVsbCwgdHJ1ZSk7XG59XG5cbmZ1bmN0aW9uIGdlblNlbGVjdCAoXG4gICAgZWwsXG4gICAgdmFsdWUsXG4gICAgbW9kaWZpZXJzXG4pIHtcbiAgdmFyIG51bWJlciA9IG1vZGlmaWVycyAmJiBtb2RpZmllcnMubnVtYmVyO1xuICB2YXIgc2VsZWN0ZWRWYWwgPSBcIkFycmF5LnByb3RvdHlwZS5maWx0ZXJcIiArXG4gICAgXCIuY2FsbCgkZXZlbnQudGFyZ2V0Lm9wdGlvbnMsZnVuY3Rpb24obyl7cmV0dXJuIG8uc2VsZWN0ZWR9KVwiICtcbiAgICBcIi5tYXAoZnVuY3Rpb24obyl7dmFyIHZhbCA9IFxcXCJfdmFsdWVcXFwiIGluIG8gPyBvLl92YWx1ZSA6IG8udmFsdWU7XCIgK1xuICAgIFwicmV0dXJuIFwiICsgKG51bWJlciA/ICdfbih2YWwpJyA6ICd2YWwnKSArIFwifSlcIjtcblxuICB2YXIgYXNzaWdubWVudCA9ICckZXZlbnQudGFyZ2V0Lm11bHRpcGxlID8gJCRzZWxlY3RlZFZhbCA6ICQkc2VsZWN0ZWRWYWxbMF0nO1xuICB2YXIgY29kZSA9IFwidmFyICQkc2VsZWN0ZWRWYWwgPSBcIiArIHNlbGVjdGVkVmFsICsgXCI7XCI7XG4gIGNvZGUgPSBjb2RlICsgXCIgXCIgKyAoZ2VuQXNzaWdubWVudENvZGUodmFsdWUsIGFzc2lnbm1lbnQpKTtcbiAgYWRkSGFuZGxlcihlbCwgJ2NoYW5nZScsIGNvZGUsIG51bGwsIHRydWUpO1xufVxuXG5mdW5jdGlvbiBnZW5EZWZhdWx0TW9kZWwgKFxuICBlbCxcbiAgdmFsdWUsXG4gIG1vZGlmaWVyc1xuKSB7XG4gIHZhciB0eXBlID0gZWwuYXR0cnNNYXAudHlwZTtcbiAgdmFyIHJlZiA9IG1vZGlmaWVycyB8fCB7fTtcbiAgdmFyIGxhenkgPSByZWYubGF6eTtcbiAgdmFyIG51bWJlciA9IHJlZi5udW1iZXI7XG4gIHZhciB0cmltID0gcmVmLnRyaW07XG4gIHZhciBuZWVkQ29tcG9zaXRpb25HdWFyZCA9ICFsYXp5ICYmIHR5cGUgIT09ICdyYW5nZSc7XG4gIHZhciBldmVudCA9IGxhenlcbiAgICA/ICdjaGFuZ2UnXG4gICAgOiB0eXBlID09PSAncmFuZ2UnXG4gICAgICA/IFJBTkdFX1RPS0VOXG4gICAgICA6ICdpbnB1dCc7XG5cbiAgdmFyIHZhbHVlRXhwcmVzc2lvbiA9ICckZXZlbnQudGFyZ2V0LnZhbHVlJztcbiAgaWYgKHRyaW0pIHtcbiAgICB2YWx1ZUV4cHJlc3Npb24gPSBcIiRldmVudC50YXJnZXQudmFsdWUudHJpbSgpXCI7XG4gIH1cbiAgaWYgKG51bWJlcikge1xuICAgIHZhbHVlRXhwcmVzc2lvbiA9IFwiX24oXCIgKyB2YWx1ZUV4cHJlc3Npb24gKyBcIilcIjtcbiAgfVxuXG4gIHZhciBjb2RlID0gZ2VuQXNzaWdubWVudENvZGUodmFsdWUsIHZhbHVlRXhwcmVzc2lvbik7XG4gIGlmIChuZWVkQ29tcG9zaXRpb25HdWFyZCkge1xuICAgIGNvZGUgPSBcImlmKCRldmVudC50YXJnZXQuY29tcG9zaW5nKXJldHVybjtcIiArIGNvZGU7XG4gIH1cblxuICBhZGRQcm9wKGVsLCAndmFsdWUnLCAoXCIoXCIgKyB2YWx1ZSArIFwiKVwiKSk7XG4gIGFkZEhhbmRsZXIoZWwsIGV2ZW50LCBjb2RlLCBudWxsLCB0cnVlKTtcbiAgaWYgKHRyaW0gfHwgbnVtYmVyKSB7XG4gICAgYWRkSGFuZGxlcihlbCwgJ2JsdXInLCAnJGZvcmNlVXBkYXRlKCknKTtcbiAgfVxufVxuXG4vKiAgKi9cblxuLy8gbm9ybWFsaXplIHYtbW9kZWwgZXZlbnQgdG9rZW5zIHRoYXQgY2FuIG9ubHkgYmUgZGV0ZXJtaW5lZCBhdCBydW50aW1lLlxuLy8gaXQncyBpbXBvcnRhbnQgdG8gcGxhY2UgdGhlIGV2ZW50IGFzIHRoZSBmaXJzdCBpbiB0aGUgYXJyYXkgYmVjYXVzZVxuLy8gdGhlIHdob2xlIHBvaW50IGlzIGVuc3VyaW5nIHRoZSB2LW1vZGVsIGNhbGxiYWNrIGdldHMgY2FsbGVkIGJlZm9yZVxuLy8gdXNlci1hdHRhY2hlZCBoYW5kbGVycy5cbmZ1bmN0aW9uIG5vcm1hbGl6ZUV2ZW50cyAob24pIHtcbiAgdmFyIGV2ZW50O1xuICAvKiBpc3RhbmJ1bCBpZ25vcmUgaWYgKi9cbiAgaWYgKGlzRGVmKG9uW1JBTkdFX1RPS0VOXSkpIHtcbiAgICAvLyBJRSBpbnB1dFt0eXBlPXJhbmdlXSBvbmx5IHN1cHBvcnRzIGBjaGFuZ2VgIGV2ZW50XG4gICAgZXZlbnQgPSBpc0lFID8gJ2NoYW5nZScgOiAnaW5wdXQnO1xuICAgIG9uW2V2ZW50XSA9IFtdLmNvbmNhdChvbltSQU5HRV9UT0tFTl0sIG9uW2V2ZW50XSB8fCBbXSk7XG4gICAgZGVsZXRlIG9uW1JBTkdFX1RPS0VOXTtcbiAgfVxuICBpZiAoaXNEZWYob25bQ0hFQ0tCT1hfUkFESU9fVE9LRU5dKSkge1xuICAgIC8vIENocm9tZSBmaXJlcyBtaWNyb3Rhc2tzIGluIGJldHdlZW4gY2xpY2svY2hhbmdlLCBsZWFkcyB0byAjNDUyMVxuICAgIGV2ZW50ID0gaXNDaHJvbWUgPyAnY2xpY2snIDogJ2NoYW5nZSc7XG4gICAgb25bZXZlbnRdID0gW10uY29uY2F0KG9uW0NIRUNLQk9YX1JBRElPX1RPS0VOXSwgb25bZXZlbnRdIHx8IFtdKTtcbiAgICBkZWxldGUgb25bQ0hFQ0tCT1hfUkFESU9fVE9LRU5dO1xuICB9XG59XG5cbnZhciB0YXJnZXQkMTtcblxuZnVuY3Rpb24gYWRkJDEgKFxuICBldmVudCxcbiAgaGFuZGxlcixcbiAgb25jZSQkMSxcbiAgY2FwdHVyZSxcbiAgcGFzc2l2ZVxuKSB7XG4gIGlmIChvbmNlJCQxKSB7XG4gICAgdmFyIG9sZEhhbmRsZXIgPSBoYW5kbGVyO1xuICAgIHZhciBfdGFyZ2V0ID0gdGFyZ2V0JDE7IC8vIHNhdmUgY3VycmVudCB0YXJnZXQgZWxlbWVudCBpbiBjbG9zdXJlXG4gICAgaGFuZGxlciA9IGZ1bmN0aW9uIChldikge1xuICAgICAgdmFyIHJlcyA9IGFyZ3VtZW50cy5sZW5ndGggPT09IDFcbiAgICAgICAgPyBvbGRIYW5kbGVyKGV2KVxuICAgICAgICA6IG9sZEhhbmRsZXIuYXBwbHkobnVsbCwgYXJndW1lbnRzKTtcbiAgICAgIGlmIChyZXMgIT09IG51bGwpIHtcbiAgICAgICAgcmVtb3ZlJDIoZXZlbnQsIGhhbmRsZXIsIGNhcHR1cmUsIF90YXJnZXQpO1xuICAgICAgfVxuICAgIH07XG4gIH1cbiAgdGFyZ2V0JDEuYWRkRXZlbnRMaXN0ZW5lcihcbiAgICBldmVudCxcbiAgICBoYW5kbGVyLFxuICAgIHN1cHBvcnRzUGFzc2l2ZVxuICAgICAgPyB7IGNhcHR1cmU6IGNhcHR1cmUsIHBhc3NpdmU6IHBhc3NpdmUgfVxuICAgICAgOiBjYXB0dXJlXG4gICk7XG59XG5cbmZ1bmN0aW9uIHJlbW92ZSQyIChcbiAgZXZlbnQsXG4gIGhhbmRsZXIsXG4gIGNhcHR1cmUsXG4gIF90YXJnZXRcbikge1xuICAoX3RhcmdldCB8fCB0YXJnZXQkMSkucmVtb3ZlRXZlbnRMaXN0ZW5lcihldmVudCwgaGFuZGxlciwgY2FwdHVyZSk7XG59XG5cbmZ1bmN0aW9uIHVwZGF0ZURPTUxpc3RlbmVycyAob2xkVm5vZGUsIHZub2RlKSB7XG4gIGlmIChpc1VuZGVmKG9sZFZub2RlLmRhdGEub24pICYmIGlzVW5kZWYodm5vZGUuZGF0YS5vbikpIHtcbiAgICByZXR1cm5cbiAgfVxuICB2YXIgb24gPSB2bm9kZS5kYXRhLm9uIHx8IHt9O1xuICB2YXIgb2xkT24gPSBvbGRWbm9kZS5kYXRhLm9uIHx8IHt9O1xuICB0YXJnZXQkMSA9IHZub2RlLmVsbTtcbiAgbm9ybWFsaXplRXZlbnRzKG9uKTtcbiAgdXBkYXRlTGlzdGVuZXJzKG9uLCBvbGRPbiwgYWRkJDEsIHJlbW92ZSQyLCB2bm9kZS5jb250ZXh0KTtcbn1cblxudmFyIGV2ZW50cyA9IHtcbiAgY3JlYXRlOiB1cGRhdGVET01MaXN0ZW5lcnMsXG4gIHVwZGF0ZTogdXBkYXRlRE9NTGlzdGVuZXJzXG59O1xuXG4vKiAgKi9cblxuZnVuY3Rpb24gdXBkYXRlRE9NUHJvcHMgKG9sZFZub2RlLCB2bm9kZSkge1xuICBpZiAoaXNVbmRlZihvbGRWbm9kZS5kYXRhLmRvbVByb3BzKSAmJiBpc1VuZGVmKHZub2RlLmRhdGEuZG9tUHJvcHMpKSB7XG4gICAgcmV0dXJuXG4gIH1cbiAgdmFyIGtleSwgY3VyO1xuICB2YXIgZWxtID0gdm5vZGUuZWxtO1xuICB2YXIgb2xkUHJvcHMgPSBvbGRWbm9kZS5kYXRhLmRvbVByb3BzIHx8IHt9O1xuICB2YXIgcHJvcHMgPSB2bm9kZS5kYXRhLmRvbVByb3BzIHx8IHt9O1xuICAvLyBjbG9uZSBvYnNlcnZlZCBvYmplY3RzLCBhcyB0aGUgdXNlciBwcm9iYWJseSB3YW50cyB0byBtdXRhdGUgaXRcbiAgaWYgKGlzRGVmKHByb3BzLl9fb2JfXykpIHtcbiAgICBwcm9wcyA9IHZub2RlLmRhdGEuZG9tUHJvcHMgPSBleHRlbmQoe30sIHByb3BzKTtcbiAgfVxuXG4gIGZvciAoa2V5IGluIG9sZFByb3BzKSB7XG4gICAgaWYgKGlzVW5kZWYocHJvcHNba2V5XSkpIHtcbiAgICAgIGVsbVtrZXldID0gJyc7XG4gICAgfVxuICB9XG4gIGZvciAoa2V5IGluIHByb3BzKSB7XG4gICAgY3VyID0gcHJvcHNba2V5XTtcbiAgICAvLyBpZ25vcmUgY2hpbGRyZW4gaWYgdGhlIG5vZGUgaGFzIHRleHRDb250ZW50IG9yIGlubmVySFRNTCxcbiAgICAvLyBhcyB0aGVzZSB3aWxsIHRocm93IGF3YXkgZXhpc3RpbmcgRE9NIG5vZGVzIGFuZCBjYXVzZSByZW1vdmFsIGVycm9yc1xuICAgIC8vIG9uIHN1YnNlcXVlbnQgcGF0Y2hlcyAoIzMzNjApXG4gICAgaWYgKGtleSA9PT0gJ3RleHRDb250ZW50JyB8fCBrZXkgPT09ICdpbm5lckhUTUwnKSB7XG4gICAgICBpZiAodm5vZGUuY2hpbGRyZW4pIHsgdm5vZGUuY2hpbGRyZW4ubGVuZ3RoID0gMDsgfVxuICAgICAgaWYgKGN1ciA9PT0gb2xkUHJvcHNba2V5XSkgeyBjb250aW51ZSB9XG4gICAgfVxuXG4gICAgaWYgKGtleSA9PT0gJ3ZhbHVlJykge1xuICAgICAgLy8gc3RvcmUgdmFsdWUgYXMgX3ZhbHVlIGFzIHdlbGwgc2luY2VcbiAgICAgIC8vIG5vbi1zdHJpbmcgdmFsdWVzIHdpbGwgYmUgc3RyaW5naWZpZWRcbiAgICAgIGVsbS5fdmFsdWUgPSBjdXI7XG4gICAgICAvLyBhdm9pZCByZXNldHRpbmcgY3Vyc29yIHBvc2l0aW9uIHdoZW4gdmFsdWUgaXMgdGhlIHNhbWVcbiAgICAgIHZhciBzdHJDdXIgPSBpc1VuZGVmKGN1cikgPyAnJyA6IFN0cmluZyhjdXIpO1xuICAgICAgaWYgKHNob3VsZFVwZGF0ZVZhbHVlKGVsbSwgdm5vZGUsIHN0ckN1cikpIHtcbiAgICAgICAgZWxtLnZhbHVlID0gc3RyQ3VyO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICBlbG1ba2V5XSA9IGN1cjtcbiAgICB9XG4gIH1cbn1cblxuLy8gY2hlY2sgcGxhdGZvcm1zL3dlYi91dGlsL2F0dHJzLmpzIGFjY2VwdFZhbHVlXG5cblxuZnVuY3Rpb24gc2hvdWxkVXBkYXRlVmFsdWUgKFxuICBlbG0sXG4gIHZub2RlLFxuICBjaGVja1ZhbFxuKSB7XG4gIHJldHVybiAoIWVsbS5jb21wb3NpbmcgJiYgKFxuICAgIHZub2RlLnRhZyA9PT0gJ29wdGlvbicgfHxcbiAgICBpc0RpcnR5KGVsbSwgY2hlY2tWYWwpIHx8XG4gICAgaXNJbnB1dENoYW5nZWQoZWxtLCBjaGVja1ZhbClcbiAgKSlcbn1cblxuZnVuY3Rpb24gaXNEaXJ0eSAoZWxtLCBjaGVja1ZhbCkge1xuICAvLyByZXR1cm4gdHJ1ZSB3aGVuIHRleHRib3ggKC5udW1iZXIgYW5kIC50cmltKSBsb3NlcyBmb2N1cyBhbmQgaXRzIHZhbHVlIGlzXG4gIC8vIG5vdCBlcXVhbCB0byB0aGUgdXBkYXRlZCB2YWx1ZVxuICB2YXIgbm90SW5Gb2N1cyA9IHRydWU7XG4gIC8vICM2MTU3XG4gIC8vIHdvcmsgYXJvdW5kIElFIGJ1ZyB3aGVuIGFjY2Vzc2luZyBkb2N1bWVudC5hY3RpdmVFbGVtZW50IGluIGFuIGlmcmFtZVxuICB0cnkgeyBub3RJbkZvY3VzID0gZG9jdW1lbnQuYWN0aXZlRWxlbWVudCAhPT0gZWxtOyB9IGNhdGNoIChlKSB7fVxuICByZXR1cm4gbm90SW5Gb2N1cyAmJiBlbG0udmFsdWUgIT09IGNoZWNrVmFsXG59XG5cbmZ1bmN0aW9uIGlzSW5wdXRDaGFuZ2VkIChlbG0sIG5ld1ZhbCkge1xuICB2YXIgdmFsdWUgPSBlbG0udmFsdWU7XG4gIHZhciBtb2RpZmllcnMgPSBlbG0uX3ZNb2RpZmllcnM7IC8vIGluamVjdGVkIGJ5IHYtbW9kZWwgcnVudGltZVxuICBpZiAoaXNEZWYobW9kaWZpZXJzKSAmJiBtb2RpZmllcnMubnVtYmVyKSB7XG4gICAgcmV0dXJuIHRvTnVtYmVyKHZhbHVlKSAhPT0gdG9OdW1iZXIobmV3VmFsKVxuICB9XG4gIGlmIChpc0RlZihtb2RpZmllcnMpICYmIG1vZGlmaWVycy50cmltKSB7XG4gICAgcmV0dXJuIHZhbHVlLnRyaW0oKSAhPT0gbmV3VmFsLnRyaW0oKVxuICB9XG4gIHJldHVybiB2YWx1ZSAhPT0gbmV3VmFsXG59XG5cbnZhciBkb21Qcm9wcyA9IHtcbiAgY3JlYXRlOiB1cGRhdGVET01Qcm9wcyxcbiAgdXBkYXRlOiB1cGRhdGVET01Qcm9wc1xufTtcblxuLyogICovXG5cbnZhciBwYXJzZVN0eWxlVGV4dCA9IGNhY2hlZChmdW5jdGlvbiAoY3NzVGV4dCkge1xuICB2YXIgcmVzID0ge307XG4gIHZhciBsaXN0RGVsaW1pdGVyID0gLzsoPyFbXihdKlxcKSkvZztcbiAgdmFyIHByb3BlcnR5RGVsaW1pdGVyID0gLzooLispLztcbiAgY3NzVGV4dC5zcGxpdChsaXN0RGVsaW1pdGVyKS5mb3JFYWNoKGZ1bmN0aW9uIChpdGVtKSB7XG4gICAgaWYgKGl0ZW0pIHtcbiAgICAgIHZhciB0bXAgPSBpdGVtLnNwbGl0KHByb3BlcnR5RGVsaW1pdGVyKTtcbiAgICAgIHRtcC5sZW5ndGggPiAxICYmIChyZXNbdG1wWzBdLnRyaW0oKV0gPSB0bXBbMV0udHJpbSgpKTtcbiAgICB9XG4gIH0pO1xuICByZXR1cm4gcmVzXG59KTtcblxuLy8gbWVyZ2Ugc3RhdGljIGFuZCBkeW5hbWljIHN0eWxlIGRhdGEgb24gdGhlIHNhbWUgdm5vZGVcbmZ1bmN0aW9uIG5vcm1hbGl6ZVN0eWxlRGF0YSAoZGF0YSkge1xuICB2YXIgc3R5bGUgPSBub3JtYWxpemVTdHlsZUJpbmRpbmcoZGF0YS5zdHlsZSk7XG4gIC8vIHN0YXRpYyBzdHlsZSBpcyBwcmUtcHJvY2Vzc2VkIGludG8gYW4gb2JqZWN0IGR1cmluZyBjb21waWxhdGlvblxuICAvLyBhbmQgaXMgYWx3YXlzIGEgZnJlc2ggb2JqZWN0LCBzbyBpdCdzIHNhZmUgdG8gbWVyZ2UgaW50byBpdFxuICByZXR1cm4gZGF0YS5zdGF0aWNTdHlsZVxuICAgID8gZXh0ZW5kKGRhdGEuc3RhdGljU3R5bGUsIHN0eWxlKVxuICAgIDogc3R5bGVcbn1cblxuLy8gbm9ybWFsaXplIHBvc3NpYmxlIGFycmF5IC8gc3RyaW5nIHZhbHVlcyBpbnRvIE9iamVjdFxuZnVuY3Rpb24gbm9ybWFsaXplU3R5bGVCaW5kaW5nIChiaW5kaW5nU3R5bGUpIHtcbiAgaWYgKEFycmF5LmlzQXJyYXkoYmluZGluZ1N0eWxlKSkge1xuICAgIHJldHVybiB0b09iamVjdChiaW5kaW5nU3R5bGUpXG4gIH1cbiAgaWYgKHR5cGVvZiBiaW5kaW5nU3R5bGUgPT09ICdzdHJpbmcnKSB7XG4gICAgcmV0dXJuIHBhcnNlU3R5bGVUZXh0KGJpbmRpbmdTdHlsZSlcbiAgfVxuICByZXR1cm4gYmluZGluZ1N0eWxlXG59XG5cbi8qKlxuICogcGFyZW50IGNvbXBvbmVudCBzdHlsZSBzaG91bGQgYmUgYWZ0ZXIgY2hpbGQnc1xuICogc28gdGhhdCBwYXJlbnQgY29tcG9uZW50J3Mgc3R5bGUgY291bGQgb3ZlcnJpZGUgaXRcbiAqL1xuZnVuY3Rpb24gZ2V0U3R5bGUgKHZub2RlLCBjaGVja0NoaWxkKSB7XG4gIHZhciByZXMgPSB7fTtcbiAgdmFyIHN0eWxlRGF0YTtcblxuICBpZiAoY2hlY2tDaGlsZCkge1xuICAgIHZhciBjaGlsZE5vZGUgPSB2bm9kZTtcbiAgICB3aGlsZSAoY2hpbGROb2RlLmNvbXBvbmVudEluc3RhbmNlKSB7XG4gICAgICBjaGlsZE5vZGUgPSBjaGlsZE5vZGUuY29tcG9uZW50SW5zdGFuY2UuX3Zub2RlO1xuICAgICAgaWYgKGNoaWxkTm9kZS5kYXRhICYmIChzdHlsZURhdGEgPSBub3JtYWxpemVTdHlsZURhdGEoY2hpbGROb2RlLmRhdGEpKSkge1xuICAgICAgICBleHRlbmQocmVzLCBzdHlsZURhdGEpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIGlmICgoc3R5bGVEYXRhID0gbm9ybWFsaXplU3R5bGVEYXRhKHZub2RlLmRhdGEpKSkge1xuICAgIGV4dGVuZChyZXMsIHN0eWxlRGF0YSk7XG4gIH1cblxuICB2YXIgcGFyZW50Tm9kZSA9IHZub2RlO1xuICB3aGlsZSAoKHBhcmVudE5vZGUgPSBwYXJlbnROb2RlLnBhcmVudCkpIHtcbiAgICBpZiAocGFyZW50Tm9kZS5kYXRhICYmIChzdHlsZURhdGEgPSBub3JtYWxpemVTdHlsZURhdGEocGFyZW50Tm9kZS5kYXRhKSkpIHtcbiAgICAgIGV4dGVuZChyZXMsIHN0eWxlRGF0YSk7XG4gICAgfVxuICB9XG4gIHJldHVybiByZXNcbn1cblxuLyogICovXG5cbnZhciBjc3NWYXJSRSA9IC9eLS0vO1xudmFyIGltcG9ydGFudFJFID0gL1xccyohaW1wb3J0YW50JC87XG52YXIgc2V0UHJvcCA9IGZ1bmN0aW9uIChlbCwgbmFtZSwgdmFsKSB7XG4gIC8qIGlzdGFuYnVsIGlnbm9yZSBpZiAqL1xuICBpZiAoY3NzVmFyUkUudGVzdChuYW1lKSkge1xuICAgIGVsLnN0eWxlLnNldFByb3BlcnR5KG5hbWUsIHZhbCk7XG4gIH0gZWxzZSBpZiAoaW1wb3J0YW50UkUudGVzdCh2YWwpKSB7XG4gICAgZWwuc3R5bGUuc2V0UHJvcGVydHkobmFtZSwgdmFsLnJlcGxhY2UoaW1wb3J0YW50UkUsICcnKSwgJ2ltcG9ydGFudCcpO1xuICB9IGVsc2Uge1xuICAgIHZhciBub3JtYWxpemVkTmFtZSA9IG5vcm1hbGl6ZShuYW1lKTtcbiAgICBpZiAoQXJyYXkuaXNBcnJheSh2YWwpKSB7XG4gICAgICAvLyBTdXBwb3J0IHZhbHVlcyBhcnJheSBjcmVhdGVkIGJ5IGF1dG9wcmVmaXhlciwgZS5nLlxuICAgICAgLy8ge2Rpc3BsYXk6IFtcIi13ZWJraXQtYm94XCIsIFwiLW1zLWZsZXhib3hcIiwgXCJmbGV4XCJdfVxuICAgICAgLy8gU2V0IHRoZW0gb25lIGJ5IG9uZSwgYW5kIHRoZSBicm93c2VyIHdpbGwgb25seSBzZXQgdGhvc2UgaXQgY2FuIHJlY29nbml6ZVxuICAgICAgZm9yICh2YXIgaSA9IDAsIGxlbiA9IHZhbC5sZW5ndGg7IGkgPCBsZW47IGkrKykge1xuICAgICAgICBlbC5zdHlsZVtub3JtYWxpemVkTmFtZV0gPSB2YWxbaV07XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIGVsLnN0eWxlW25vcm1hbGl6ZWROYW1lXSA9IHZhbDtcbiAgICB9XG4gIH1cbn07XG5cbnZhciB2ZW5kb3JOYW1lcyA9IFsnV2Via2l0JywgJ01veicsICdtcyddO1xuXG52YXIgZW1wdHlTdHlsZTtcbnZhciBub3JtYWxpemUgPSBjYWNoZWQoZnVuY3Rpb24gKHByb3ApIHtcbiAgZW1wdHlTdHlsZSA9IGVtcHR5U3R5bGUgfHwgZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jykuc3R5bGU7XG4gIHByb3AgPSBjYW1lbGl6ZShwcm9wKTtcbiAgaWYgKHByb3AgIT09ICdmaWx0ZXInICYmIChwcm9wIGluIGVtcHR5U3R5bGUpKSB7XG4gICAgcmV0dXJuIHByb3BcbiAgfVxuICB2YXIgY2FwTmFtZSA9IHByb3AuY2hhckF0KDApLnRvVXBwZXJDYXNlKCkgKyBwcm9wLnNsaWNlKDEpO1xuICBmb3IgKHZhciBpID0gMDsgaSA8IHZlbmRvck5hbWVzLmxlbmd0aDsgaSsrKSB7XG4gICAgdmFyIG5hbWUgPSB2ZW5kb3JOYW1lc1tpXSArIGNhcE5hbWU7XG4gICAgaWYgKG5hbWUgaW4gZW1wdHlTdHlsZSkge1xuICAgICAgcmV0dXJuIG5hbWVcbiAgICB9XG4gIH1cbn0pO1xuXG5mdW5jdGlvbiB1cGRhdGVTdHlsZSAob2xkVm5vZGUsIHZub2RlKSB7XG4gIHZhciBkYXRhID0gdm5vZGUuZGF0YTtcbiAgdmFyIG9sZERhdGEgPSBvbGRWbm9kZS5kYXRhO1xuXG4gIGlmIChpc1VuZGVmKGRhdGEuc3RhdGljU3R5bGUpICYmIGlzVW5kZWYoZGF0YS5zdHlsZSkgJiZcbiAgICBpc1VuZGVmKG9sZERhdGEuc3RhdGljU3R5bGUpICYmIGlzVW5kZWYob2xkRGF0YS5zdHlsZSlcbiAgKSB7XG4gICAgcmV0dXJuXG4gIH1cblxuICB2YXIgY3VyLCBuYW1lO1xuICB2YXIgZWwgPSB2bm9kZS5lbG07XG4gIHZhciBvbGRTdGF0aWNTdHlsZSA9IG9sZERhdGEuc3RhdGljU3R5bGU7XG4gIHZhciBvbGRTdHlsZUJpbmRpbmcgPSBvbGREYXRhLm5vcm1hbGl6ZWRTdHlsZSB8fCBvbGREYXRhLnN0eWxlIHx8IHt9O1xuXG4gIC8vIGlmIHN0YXRpYyBzdHlsZSBleGlzdHMsIHN0eWxlYmluZGluZyBhbHJlYWR5IG1lcmdlZCBpbnRvIGl0IHdoZW4gZG9pbmcgbm9ybWFsaXplU3R5bGVEYXRhXG4gIHZhciBvbGRTdHlsZSA9IG9sZFN0YXRpY1N0eWxlIHx8IG9sZFN0eWxlQmluZGluZztcblxuICB2YXIgc3R5bGUgPSBub3JtYWxpemVTdHlsZUJpbmRpbmcodm5vZGUuZGF0YS5zdHlsZSkgfHwge307XG5cbiAgLy8gc3RvcmUgbm9ybWFsaXplZCBzdHlsZSB1bmRlciBhIGRpZmZlcmVudCBrZXkgZm9yIG5leHQgZGlmZlxuICAvLyBtYWtlIHN1cmUgdG8gY2xvbmUgaXQgaWYgaXQncyByZWFjdGl2ZSwgc2luY2UgdGhlIHVzZXIgbGlrZWx5IHdhbnRzXG4gIC8vIHRvIG11dGF0ZSBpdC5cbiAgdm5vZGUuZGF0YS5ub3JtYWxpemVkU3R5bGUgPSBpc0RlZihzdHlsZS5fX29iX18pXG4gICAgPyBleHRlbmQoe30sIHN0eWxlKVxuICAgIDogc3R5bGU7XG5cbiAgdmFyIG5ld1N0eWxlID0gZ2V0U3R5bGUodm5vZGUsIHRydWUpO1xuXG4gIGZvciAobmFtZSBpbiBvbGRTdHlsZSkge1xuICAgIGlmIChpc1VuZGVmKG5ld1N0eWxlW25hbWVdKSkge1xuICAgICAgc2V0UHJvcChlbCwgbmFtZSwgJycpO1xuICAgIH1cbiAgfVxuICBmb3IgKG5hbWUgaW4gbmV3U3R5bGUpIHtcbiAgICBjdXIgPSBuZXdTdHlsZVtuYW1lXTtcbiAgICBpZiAoY3VyICE9PSBvbGRTdHlsZVtuYW1lXSkge1xuICAgICAgLy8gaWU5IHNldHRpbmcgdG8gbnVsbCBoYXMgbm8gZWZmZWN0LCBtdXN0IHVzZSBlbXB0eSBzdHJpbmdcbiAgICAgIHNldFByb3AoZWwsIG5hbWUsIGN1ciA9PSBudWxsID8gJycgOiBjdXIpO1xuICAgIH1cbiAgfVxufVxuXG52YXIgc3R5bGUgPSB7XG4gIGNyZWF0ZTogdXBkYXRlU3R5bGUsXG4gIHVwZGF0ZTogdXBkYXRlU3R5bGVcbn07XG5cbi8qICAqL1xuXG4vKipcbiAqIEFkZCBjbGFzcyB3aXRoIGNvbXBhdGliaWxpdHkgZm9yIFNWRyBzaW5jZSBjbGFzc0xpc3QgaXMgbm90IHN1cHBvcnRlZCBvblxuICogU1ZHIGVsZW1lbnRzIGluIElFXG4gKi9cbmZ1bmN0aW9uIGFkZENsYXNzIChlbCwgY2xzKSB7XG4gIC8qIGlzdGFuYnVsIGlnbm9yZSBpZiAqL1xuICBpZiAoIWNscyB8fCAhKGNscyA9IGNscy50cmltKCkpKSB7XG4gICAgcmV0dXJuXG4gIH1cblxuICAvKiBpc3RhbmJ1bCBpZ25vcmUgZWxzZSAqL1xuICBpZiAoZWwuY2xhc3NMaXN0KSB7XG4gICAgaWYgKGNscy5pbmRleE9mKCcgJykgPiAtMSkge1xuICAgICAgY2xzLnNwbGl0KC9cXHMrLykuZm9yRWFjaChmdW5jdGlvbiAoYykgeyByZXR1cm4gZWwuY2xhc3NMaXN0LmFkZChjKTsgfSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGVsLmNsYXNzTGlzdC5hZGQoY2xzKTtcbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgdmFyIGN1ciA9IFwiIFwiICsgKGVsLmdldEF0dHJpYnV0ZSgnY2xhc3MnKSB8fCAnJykgKyBcIiBcIjtcbiAgICBpZiAoY3VyLmluZGV4T2YoJyAnICsgY2xzICsgJyAnKSA8IDApIHtcbiAgICAgIGVsLnNldEF0dHJpYnV0ZSgnY2xhc3MnLCAoY3VyICsgY2xzKS50cmltKCkpO1xuICAgIH1cbiAgfVxufVxuXG4vKipcbiAqIFJlbW92ZSBjbGFzcyB3aXRoIGNvbXBhdGliaWxpdHkgZm9yIFNWRyBzaW5jZSBjbGFzc0xpc3QgaXMgbm90IHN1cHBvcnRlZCBvblxuICogU1ZHIGVsZW1lbnRzIGluIElFXG4gKi9cbmZ1bmN0aW9uIHJlbW92ZUNsYXNzIChlbCwgY2xzKSB7XG4gIC8qIGlzdGFuYnVsIGlnbm9yZSBpZiAqL1xuICBpZiAoIWNscyB8fCAhKGNscyA9IGNscy50cmltKCkpKSB7XG4gICAgcmV0dXJuXG4gIH1cblxuICAvKiBpc3RhbmJ1bCBpZ25vcmUgZWxzZSAqL1xuICBpZiAoZWwuY2xhc3NMaXN0KSB7XG4gICAgaWYgKGNscy5pbmRleE9mKCcgJykgPiAtMSkge1xuICAgICAgY2xzLnNwbGl0KC9cXHMrLykuZm9yRWFjaChmdW5jdGlvbiAoYykgeyByZXR1cm4gZWwuY2xhc3NMaXN0LnJlbW92ZShjKTsgfSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGVsLmNsYXNzTGlzdC5yZW1vdmUoY2xzKTtcbiAgICB9XG4gICAgaWYgKCFlbC5jbGFzc0xpc3QubGVuZ3RoKSB7XG4gICAgICBlbC5yZW1vdmVBdHRyaWJ1dGUoJ2NsYXNzJyk7XG4gICAgfVxuICB9IGVsc2Uge1xuICAgIHZhciBjdXIgPSBcIiBcIiArIChlbC5nZXRBdHRyaWJ1dGUoJ2NsYXNzJykgfHwgJycpICsgXCIgXCI7XG4gICAgdmFyIHRhciA9ICcgJyArIGNscyArICcgJztcbiAgICB3aGlsZSAoY3VyLmluZGV4T2YodGFyKSA+PSAwKSB7XG4gICAgICBjdXIgPSBjdXIucmVwbGFjZSh0YXIsICcgJyk7XG4gICAgfVxuICAgIGN1ciA9IGN1ci50cmltKCk7XG4gICAgaWYgKGN1cikge1xuICAgICAgZWwuc2V0QXR0cmlidXRlKCdjbGFzcycsIGN1cik7XG4gICAgfSBlbHNlIHtcbiAgICAgIGVsLnJlbW92ZUF0dHJpYnV0ZSgnY2xhc3MnKTtcbiAgICB9XG4gIH1cbn1cblxuLyogICovXG5cbmZ1bmN0aW9uIHJlc29sdmVUcmFuc2l0aW9uIChkZWYkJDEpIHtcbiAgaWYgKCFkZWYkJDEpIHtcbiAgICByZXR1cm5cbiAgfVxuICAvKiBpc3RhbmJ1bCBpZ25vcmUgZWxzZSAqL1xuICBpZiAodHlwZW9mIGRlZiQkMSA9PT0gJ29iamVjdCcpIHtcbiAgICB2YXIgcmVzID0ge307XG4gICAgaWYgKGRlZiQkMS5jc3MgIT09IGZhbHNlKSB7XG4gICAgICBleHRlbmQocmVzLCBhdXRvQ3NzVHJhbnNpdGlvbihkZWYkJDEubmFtZSB8fCAndicpKTtcbiAgICB9XG4gICAgZXh0ZW5kKHJlcywgZGVmJCQxKTtcbiAgICByZXR1cm4gcmVzXG4gIH0gZWxzZSBpZiAodHlwZW9mIGRlZiQkMSA9PT0gJ3N0cmluZycpIHtcbiAgICByZXR1cm4gYXV0b0Nzc1RyYW5zaXRpb24oZGVmJCQxKVxuICB9XG59XG5cbnZhciBhdXRvQ3NzVHJhbnNpdGlvbiA9IGNhY2hlZChmdW5jdGlvbiAobmFtZSkge1xuICByZXR1cm4ge1xuICAgIGVudGVyQ2xhc3M6IChuYW1lICsgXCItZW50ZXJcIiksXG4gICAgZW50ZXJUb0NsYXNzOiAobmFtZSArIFwiLWVudGVyLXRvXCIpLFxuICAgIGVudGVyQWN0aXZlQ2xhc3M6IChuYW1lICsgXCItZW50ZXItYWN0aXZlXCIpLFxuICAgIGxlYXZlQ2xhc3M6IChuYW1lICsgXCItbGVhdmVcIiksXG4gICAgbGVhdmVUb0NsYXNzOiAobmFtZSArIFwiLWxlYXZlLXRvXCIpLFxuICAgIGxlYXZlQWN0aXZlQ2xhc3M6IChuYW1lICsgXCItbGVhdmUtYWN0aXZlXCIpXG4gIH1cbn0pO1xuXG52YXIgaGFzVHJhbnNpdGlvbiA9IGluQnJvd3NlciAmJiAhaXNJRTk7XG52YXIgVFJBTlNJVElPTiA9ICd0cmFuc2l0aW9uJztcbnZhciBBTklNQVRJT04gPSAnYW5pbWF0aW9uJztcblxuLy8gVHJhbnNpdGlvbiBwcm9wZXJ0eS9ldmVudCBzbmlmZmluZ1xudmFyIHRyYW5zaXRpb25Qcm9wID0gJ3RyYW5zaXRpb24nO1xudmFyIHRyYW5zaXRpb25FbmRFdmVudCA9ICd0cmFuc2l0aW9uZW5kJztcbnZhciBhbmltYXRpb25Qcm9wID0gJ2FuaW1hdGlvbic7XG52YXIgYW5pbWF0aW9uRW5kRXZlbnQgPSAnYW5pbWF0aW9uZW5kJztcbmlmIChoYXNUcmFuc2l0aW9uKSB7XG4gIC8qIGlzdGFuYnVsIGlnbm9yZSBpZiAqL1xuICBpZiAod2luZG93Lm9udHJhbnNpdGlvbmVuZCA9PT0gdW5kZWZpbmVkICYmXG4gICAgd2luZG93Lm9ud2Via2l0dHJhbnNpdGlvbmVuZCAhPT0gdW5kZWZpbmVkXG4gICkge1xuICAgIHRyYW5zaXRpb25Qcm9wID0gJ1dlYmtpdFRyYW5zaXRpb24nO1xuICAgIHRyYW5zaXRpb25FbmRFdmVudCA9ICd3ZWJraXRUcmFuc2l0aW9uRW5kJztcbiAgfVxuICBpZiAod2luZG93Lm9uYW5pbWF0aW9uZW5kID09PSB1bmRlZmluZWQgJiZcbiAgICB3aW5kb3cub253ZWJraXRhbmltYXRpb25lbmQgIT09IHVuZGVmaW5lZFxuICApIHtcbiAgICBhbmltYXRpb25Qcm9wID0gJ1dlYmtpdEFuaW1hdGlvbic7XG4gICAgYW5pbWF0aW9uRW5kRXZlbnQgPSAnd2Via2l0QW5pbWF0aW9uRW5kJztcbiAgfVxufVxuXG4vLyBiaW5kaW5nIHRvIHdpbmRvdyBpcyBuZWNlc3NhcnkgdG8gbWFrZSBob3QgcmVsb2FkIHdvcmsgaW4gSUUgaW4gc3RyaWN0IG1vZGVcbnZhciByYWYgPSBpbkJyb3dzZXIgJiYgd2luZG93LnJlcXVlc3RBbmltYXRpb25GcmFtZVxuICA/IHdpbmRvdy5yZXF1ZXN0QW5pbWF0aW9uRnJhbWUuYmluZCh3aW5kb3cpXG4gIDogc2V0VGltZW91dDtcblxuZnVuY3Rpb24gbmV4dEZyYW1lIChmbikge1xuICByYWYoZnVuY3Rpb24gKCkge1xuICAgIHJhZihmbik7XG4gIH0pO1xufVxuXG5mdW5jdGlvbiBhZGRUcmFuc2l0aW9uQ2xhc3MgKGVsLCBjbHMpIHtcbiAgdmFyIHRyYW5zaXRpb25DbGFzc2VzID0gZWwuX3RyYW5zaXRpb25DbGFzc2VzIHx8IChlbC5fdHJhbnNpdGlvbkNsYXNzZXMgPSBbXSk7XG4gIGlmICh0cmFuc2l0aW9uQ2xhc3Nlcy5pbmRleE9mKGNscykgPCAwKSB7XG4gICAgdHJhbnNpdGlvbkNsYXNzZXMucHVzaChjbHMpO1xuICAgIGFkZENsYXNzKGVsLCBjbHMpO1xuICB9XG59XG5cbmZ1bmN0aW9uIHJlbW92ZVRyYW5zaXRpb25DbGFzcyAoZWwsIGNscykge1xuICBpZiAoZWwuX3RyYW5zaXRpb25DbGFzc2VzKSB7XG4gICAgcmVtb3ZlKGVsLl90cmFuc2l0aW9uQ2xhc3NlcywgY2xzKTtcbiAgfVxuICByZW1vdmVDbGFzcyhlbCwgY2xzKTtcbn1cblxuZnVuY3Rpb24gd2hlblRyYW5zaXRpb25FbmRzIChcbiAgZWwsXG4gIGV4cGVjdGVkVHlwZSxcbiAgY2Jcbikge1xuICB2YXIgcmVmID0gZ2V0VHJhbnNpdGlvbkluZm8oZWwsIGV4cGVjdGVkVHlwZSk7XG4gIHZhciB0eXBlID0gcmVmLnR5cGU7XG4gIHZhciB0aW1lb3V0ID0gcmVmLnRpbWVvdXQ7XG4gIHZhciBwcm9wQ291bnQgPSByZWYucHJvcENvdW50O1xuICBpZiAoIXR5cGUpIHsgcmV0dXJuIGNiKCkgfVxuICB2YXIgZXZlbnQgPSB0eXBlID09PSBUUkFOU0lUSU9OID8gdHJhbnNpdGlvbkVuZEV2ZW50IDogYW5pbWF0aW9uRW5kRXZlbnQ7XG4gIHZhciBlbmRlZCA9IDA7XG4gIHZhciBlbmQgPSBmdW5jdGlvbiAoKSB7XG4gICAgZWwucmVtb3ZlRXZlbnRMaXN0ZW5lcihldmVudCwgb25FbmQpO1xuICAgIGNiKCk7XG4gIH07XG4gIHZhciBvbkVuZCA9IGZ1bmN0aW9uIChlKSB7XG4gICAgaWYgKGUudGFyZ2V0ID09PSBlbCkge1xuICAgICAgaWYgKCsrZW5kZWQgPj0gcHJvcENvdW50KSB7XG4gICAgICAgIGVuZCgpO1xuICAgICAgfVxuICAgIH1cbiAgfTtcbiAgc2V0VGltZW91dChmdW5jdGlvbiAoKSB7XG4gICAgaWYgKGVuZGVkIDwgcHJvcENvdW50KSB7XG4gICAgICBlbmQoKTtcbiAgICB9XG4gIH0sIHRpbWVvdXQgKyAxKTtcbiAgZWwuYWRkRXZlbnRMaXN0ZW5lcihldmVudCwgb25FbmQpO1xufVxuXG52YXIgdHJhbnNmb3JtUkUgPSAvXFxiKHRyYW5zZm9ybXxhbGwpKCx8JCkvO1xuXG5mdW5jdGlvbiBnZXRUcmFuc2l0aW9uSW5mbyAoZWwsIGV4cGVjdGVkVHlwZSkge1xuICB2YXIgc3R5bGVzID0gd2luZG93LmdldENvbXB1dGVkU3R5bGUoZWwpO1xuICB2YXIgdHJhbnNpdGlvbkRlbGF5cyA9IHN0eWxlc1t0cmFuc2l0aW9uUHJvcCArICdEZWxheSddLnNwbGl0KCcsICcpO1xuICB2YXIgdHJhbnNpdGlvbkR1cmF0aW9ucyA9IHN0eWxlc1t0cmFuc2l0aW9uUHJvcCArICdEdXJhdGlvbiddLnNwbGl0KCcsICcpO1xuICB2YXIgdHJhbnNpdGlvblRpbWVvdXQgPSBnZXRUaW1lb3V0KHRyYW5zaXRpb25EZWxheXMsIHRyYW5zaXRpb25EdXJhdGlvbnMpO1xuICB2YXIgYW5pbWF0aW9uRGVsYXlzID0gc3R5bGVzW2FuaW1hdGlvblByb3AgKyAnRGVsYXknXS5zcGxpdCgnLCAnKTtcbiAgdmFyIGFuaW1hdGlvbkR1cmF0aW9ucyA9IHN0eWxlc1thbmltYXRpb25Qcm9wICsgJ0R1cmF0aW9uJ10uc3BsaXQoJywgJyk7XG4gIHZhciBhbmltYXRpb25UaW1lb3V0ID0gZ2V0VGltZW91dChhbmltYXRpb25EZWxheXMsIGFuaW1hdGlvbkR1cmF0aW9ucyk7XG5cbiAgdmFyIHR5cGU7XG4gIHZhciB0aW1lb3V0ID0gMDtcbiAgdmFyIHByb3BDb3VudCA9IDA7XG4gIC8qIGlzdGFuYnVsIGlnbm9yZSBpZiAqL1xuICBpZiAoZXhwZWN0ZWRUeXBlID09PSBUUkFOU0lUSU9OKSB7XG4gICAgaWYgKHRyYW5zaXRpb25UaW1lb3V0ID4gMCkge1xuICAgICAgdHlwZSA9IFRSQU5TSVRJT047XG4gICAgICB0aW1lb3V0ID0gdHJhbnNpdGlvblRpbWVvdXQ7XG4gICAgICBwcm9wQ291bnQgPSB0cmFuc2l0aW9uRHVyYXRpb25zLmxlbmd0aDtcbiAgICB9XG4gIH0gZWxzZSBpZiAoZXhwZWN0ZWRUeXBlID09PSBBTklNQVRJT04pIHtcbiAgICBpZiAoYW5pbWF0aW9uVGltZW91dCA+IDApIHtcbiAgICAgIHR5cGUgPSBBTklNQVRJT047XG4gICAgICB0aW1lb3V0ID0gYW5pbWF0aW9uVGltZW91dDtcbiAgICAgIHByb3BDb3VudCA9IGFuaW1hdGlvbkR1cmF0aW9ucy5sZW5ndGg7XG4gICAgfVxuICB9IGVsc2Uge1xuICAgIHRpbWVvdXQgPSBNYXRoLm1heCh0cmFuc2l0aW9uVGltZW91dCwgYW5pbWF0aW9uVGltZW91dCk7XG4gICAgdHlwZSA9IHRpbWVvdXQgPiAwXG4gICAgICA/IHRyYW5zaXRpb25UaW1lb3V0ID4gYW5pbWF0aW9uVGltZW91dFxuICAgICAgICA/IFRSQU5TSVRJT05cbiAgICAgICAgOiBBTklNQVRJT05cbiAgICAgIDogbnVsbDtcbiAgICBwcm9wQ291bnQgPSB0eXBlXG4gICAgICA/IHR5cGUgPT09IFRSQU5TSVRJT05cbiAgICAgICAgPyB0cmFuc2l0aW9uRHVyYXRpb25zLmxlbmd0aFxuICAgICAgICA6IGFuaW1hdGlvbkR1cmF0aW9ucy5sZW5ndGhcbiAgICAgIDogMDtcbiAgfVxuICB2YXIgaGFzVHJhbnNmb3JtID1cbiAgICB0eXBlID09PSBUUkFOU0lUSU9OICYmXG4gICAgdHJhbnNmb3JtUkUudGVzdChzdHlsZXNbdHJhbnNpdGlvblByb3AgKyAnUHJvcGVydHknXSk7XG4gIHJldHVybiB7XG4gICAgdHlwZTogdHlwZSxcbiAgICB0aW1lb3V0OiB0aW1lb3V0LFxuICAgIHByb3BDb3VudDogcHJvcENvdW50LFxuICAgIGhhc1RyYW5zZm9ybTogaGFzVHJhbnNmb3JtXG4gIH1cbn1cblxuZnVuY3Rpb24gZ2V0VGltZW91dCAoZGVsYXlzLCBkdXJhdGlvbnMpIHtcbiAgLyogaXN0YW5idWwgaWdub3JlIG5leHQgKi9cbiAgd2hpbGUgKGRlbGF5cy5sZW5ndGggPCBkdXJhdGlvbnMubGVuZ3RoKSB7XG4gICAgZGVsYXlzID0gZGVsYXlzLmNvbmNhdChkZWxheXMpO1xuICB9XG5cbiAgcmV0dXJuIE1hdGgubWF4LmFwcGx5KG51bGwsIGR1cmF0aW9ucy5tYXAoZnVuY3Rpb24gKGQsIGkpIHtcbiAgICByZXR1cm4gdG9NcyhkKSArIHRvTXMoZGVsYXlzW2ldKVxuICB9KSlcbn1cblxuZnVuY3Rpb24gdG9NcyAocykge1xuICByZXR1cm4gTnVtYmVyKHMuc2xpY2UoMCwgLTEpKSAqIDEwMDBcbn1cblxuLyogICovXG5cbmZ1bmN0aW9uIGVudGVyICh2bm9kZSwgdG9nZ2xlRGlzcGxheSkge1xuICB2YXIgZWwgPSB2bm9kZS5lbG07XG5cbiAgLy8gY2FsbCBsZWF2ZSBjYWxsYmFjayBub3dcbiAgaWYgKGlzRGVmKGVsLl9sZWF2ZUNiKSkge1xuICAgIGVsLl9sZWF2ZUNiLmNhbmNlbGxlZCA9IHRydWU7XG4gICAgZWwuX2xlYXZlQ2IoKTtcbiAgfVxuXG4gIHZhciBkYXRhID0gcmVzb2x2ZVRyYW5zaXRpb24odm5vZGUuZGF0YS50cmFuc2l0aW9uKTtcbiAgaWYgKGlzVW5kZWYoZGF0YSkpIHtcbiAgICByZXR1cm5cbiAgfVxuXG4gIC8qIGlzdGFuYnVsIGlnbm9yZSBpZiAqL1xuICBpZiAoaXNEZWYoZWwuX2VudGVyQ2IpIHx8IGVsLm5vZGVUeXBlICE9PSAxKSB7XG4gICAgcmV0dXJuXG4gIH1cblxuICB2YXIgY3NzID0gZGF0YS5jc3M7XG4gIHZhciB0eXBlID0gZGF0YS50eXBlO1xuICB2YXIgZW50ZXJDbGFzcyA9IGRhdGEuZW50ZXJDbGFzcztcbiAgdmFyIGVudGVyVG9DbGFzcyA9IGRhdGEuZW50ZXJUb0NsYXNzO1xuICB2YXIgZW50ZXJBY3RpdmVDbGFzcyA9IGRhdGEuZW50ZXJBY3RpdmVDbGFzcztcbiAgdmFyIGFwcGVhckNsYXNzID0gZGF0YS5hcHBlYXJDbGFzcztcbiAgdmFyIGFwcGVhclRvQ2xhc3MgPSBkYXRhLmFwcGVhclRvQ2xhc3M7XG4gIHZhciBhcHBlYXJBY3RpdmVDbGFzcyA9IGRhdGEuYXBwZWFyQWN0aXZlQ2xhc3M7XG4gIHZhciBiZWZvcmVFbnRlciA9IGRhdGEuYmVmb3JlRW50ZXI7XG4gIHZhciBlbnRlciA9IGRhdGEuZW50ZXI7XG4gIHZhciBhZnRlckVudGVyID0gZGF0YS5hZnRlckVudGVyO1xuICB2YXIgZW50ZXJDYW5jZWxsZWQgPSBkYXRhLmVudGVyQ2FuY2VsbGVkO1xuICB2YXIgYmVmb3JlQXBwZWFyID0gZGF0YS5iZWZvcmVBcHBlYXI7XG4gIHZhciBhcHBlYXIgPSBkYXRhLmFwcGVhcjtcbiAgdmFyIGFmdGVyQXBwZWFyID0gZGF0YS5hZnRlckFwcGVhcjtcbiAgdmFyIGFwcGVhckNhbmNlbGxlZCA9IGRhdGEuYXBwZWFyQ2FuY2VsbGVkO1xuICB2YXIgZHVyYXRpb24gPSBkYXRhLmR1cmF0aW9uO1xuXG4gIC8vIGFjdGl2ZUluc3RhbmNlIHdpbGwgYWx3YXlzIGJlIHRoZSA8dHJhbnNpdGlvbj4gY29tcG9uZW50IG1hbmFnaW5nIHRoaXNcbiAgLy8gdHJhbnNpdGlvbi4gT25lIGVkZ2UgY2FzZSB0byBjaGVjayBpcyB3aGVuIHRoZSA8dHJhbnNpdGlvbj4gaXMgcGxhY2VkXG4gIC8vIGFzIHRoZSByb290IG5vZGUgb2YgYSBjaGlsZCBjb21wb25lbnQuIEluIHRoYXQgY2FzZSB3ZSBuZWVkIHRvIGNoZWNrXG4gIC8vIDx0cmFuc2l0aW9uPidzIHBhcmVudCBmb3IgYXBwZWFyIGNoZWNrLlxuICB2YXIgY29udGV4dCA9IGFjdGl2ZUluc3RhbmNlO1xuICB2YXIgdHJhbnNpdGlvbk5vZGUgPSBhY3RpdmVJbnN0YW5jZS4kdm5vZGU7XG4gIHdoaWxlICh0cmFuc2l0aW9uTm9kZSAmJiB0cmFuc2l0aW9uTm9kZS5wYXJlbnQpIHtcbiAgICB0cmFuc2l0aW9uTm9kZSA9IHRyYW5zaXRpb25Ob2RlLnBhcmVudDtcbiAgICBjb250ZXh0ID0gdHJhbnNpdGlvbk5vZGUuY29udGV4dDtcbiAgfVxuXG4gIHZhciBpc0FwcGVhciA9ICFjb250ZXh0Ll9pc01vdW50ZWQgfHwgIXZub2RlLmlzUm9vdEluc2VydDtcblxuICBpZiAoaXNBcHBlYXIgJiYgIWFwcGVhciAmJiBhcHBlYXIgIT09ICcnKSB7XG4gICAgcmV0dXJuXG4gIH1cblxuICB2YXIgc3RhcnRDbGFzcyA9IGlzQXBwZWFyICYmIGFwcGVhckNsYXNzXG4gICAgPyBhcHBlYXJDbGFzc1xuICAgIDogZW50ZXJDbGFzcztcbiAgdmFyIGFjdGl2ZUNsYXNzID0gaXNBcHBlYXIgJiYgYXBwZWFyQWN0aXZlQ2xhc3NcbiAgICA/IGFwcGVhckFjdGl2ZUNsYXNzXG4gICAgOiBlbnRlckFjdGl2ZUNsYXNzO1xuICB2YXIgdG9DbGFzcyA9IGlzQXBwZWFyICYmIGFwcGVhclRvQ2xhc3NcbiAgICA/IGFwcGVhclRvQ2xhc3NcbiAgICA6IGVudGVyVG9DbGFzcztcblxuICB2YXIgYmVmb3JlRW50ZXJIb29rID0gaXNBcHBlYXJcbiAgICA/IChiZWZvcmVBcHBlYXIgfHwgYmVmb3JlRW50ZXIpXG4gICAgOiBiZWZvcmVFbnRlcjtcbiAgdmFyIGVudGVySG9vayA9IGlzQXBwZWFyXG4gICAgPyAodHlwZW9mIGFwcGVhciA9PT0gJ2Z1bmN0aW9uJyA/IGFwcGVhciA6IGVudGVyKVxuICAgIDogZW50ZXI7XG4gIHZhciBhZnRlckVudGVySG9vayA9IGlzQXBwZWFyXG4gICAgPyAoYWZ0ZXJBcHBlYXIgfHwgYWZ0ZXJFbnRlcilcbiAgICA6IGFmdGVyRW50ZXI7XG4gIHZhciBlbnRlckNhbmNlbGxlZEhvb2sgPSBpc0FwcGVhclxuICAgID8gKGFwcGVhckNhbmNlbGxlZCB8fCBlbnRlckNhbmNlbGxlZClcbiAgICA6IGVudGVyQ2FuY2VsbGVkO1xuXG4gIHZhciBleHBsaWNpdEVudGVyRHVyYXRpb24gPSB0b051bWJlcihcbiAgICBpc09iamVjdChkdXJhdGlvbilcbiAgICAgID8gZHVyYXRpb24uZW50ZXJcbiAgICAgIDogZHVyYXRpb25cbiAgKTtcblxuICBpZiAocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJyAmJiBleHBsaWNpdEVudGVyRHVyYXRpb24gIT0gbnVsbCkge1xuICAgIGNoZWNrRHVyYXRpb24oZXhwbGljaXRFbnRlckR1cmF0aW9uLCAnZW50ZXInLCB2bm9kZSk7XG4gIH1cblxuICB2YXIgZXhwZWN0c0NTUyA9IGNzcyAhPT0gZmFsc2UgJiYgIWlzSUU5O1xuICB2YXIgdXNlcldhbnRzQ29udHJvbCA9IGdldEhvb2tBcmd1bWVudHNMZW5ndGgoZW50ZXJIb29rKTtcblxuICB2YXIgY2IgPSBlbC5fZW50ZXJDYiA9IG9uY2UoZnVuY3Rpb24gKCkge1xuICAgIGlmIChleHBlY3RzQ1NTKSB7XG4gICAgICByZW1vdmVUcmFuc2l0aW9uQ2xhc3MoZWwsIHRvQ2xhc3MpO1xuICAgICAgcmVtb3ZlVHJhbnNpdGlvbkNsYXNzKGVsLCBhY3RpdmVDbGFzcyk7XG4gICAgfVxuICAgIGlmIChjYi5jYW5jZWxsZWQpIHtcbiAgICAgIGlmIChleHBlY3RzQ1NTKSB7XG4gICAgICAgIHJlbW92ZVRyYW5zaXRpb25DbGFzcyhlbCwgc3RhcnRDbGFzcyk7XG4gICAgICB9XG4gICAgICBlbnRlckNhbmNlbGxlZEhvb2sgJiYgZW50ZXJDYW5jZWxsZWRIb29rKGVsKTtcbiAgICB9IGVsc2Uge1xuICAgICAgYWZ0ZXJFbnRlckhvb2sgJiYgYWZ0ZXJFbnRlckhvb2soZWwpO1xuICAgIH1cbiAgICBlbC5fZW50ZXJDYiA9IG51bGw7XG4gIH0pO1xuXG4gIGlmICghdm5vZGUuZGF0YS5zaG93KSB7XG4gICAgLy8gcmVtb3ZlIHBlbmRpbmcgbGVhdmUgZWxlbWVudCBvbiBlbnRlciBieSBpbmplY3RpbmcgYW4gaW5zZXJ0IGhvb2tcbiAgICBtZXJnZVZOb2RlSG9vayh2bm9kZS5kYXRhLmhvb2sgfHwgKHZub2RlLmRhdGEuaG9vayA9IHt9KSwgJ2luc2VydCcsIGZ1bmN0aW9uICgpIHtcbiAgICAgIHZhciBwYXJlbnQgPSBlbC5wYXJlbnROb2RlO1xuICAgICAgdmFyIHBlbmRpbmdOb2RlID0gcGFyZW50ICYmIHBhcmVudC5fcGVuZGluZyAmJiBwYXJlbnQuX3BlbmRpbmdbdm5vZGUua2V5XTtcbiAgICAgIGlmIChwZW5kaW5nTm9kZSAmJlxuICAgICAgICBwZW5kaW5nTm9kZS50YWcgPT09IHZub2RlLnRhZyAmJlxuICAgICAgICBwZW5kaW5nTm9kZS5lbG0uX2xlYXZlQ2JcbiAgICAgICkge1xuICAgICAgICBwZW5kaW5nTm9kZS5lbG0uX2xlYXZlQ2IoKTtcbiAgICAgIH1cbiAgICAgIGVudGVySG9vayAmJiBlbnRlckhvb2soZWwsIGNiKTtcbiAgICB9KTtcbiAgfVxuXG4gIC8vIHN0YXJ0IGVudGVyIHRyYW5zaXRpb25cbiAgYmVmb3JlRW50ZXJIb29rICYmIGJlZm9yZUVudGVySG9vayhlbCk7XG4gIGlmIChleHBlY3RzQ1NTKSB7XG4gICAgYWRkVHJhbnNpdGlvbkNsYXNzKGVsLCBzdGFydENsYXNzKTtcbiAgICBhZGRUcmFuc2l0aW9uQ2xhc3MoZWwsIGFjdGl2ZUNsYXNzKTtcbiAgICBuZXh0RnJhbWUoZnVuY3Rpb24gKCkge1xuICAgICAgYWRkVHJhbnNpdGlvbkNsYXNzKGVsLCB0b0NsYXNzKTtcbiAgICAgIHJlbW92ZVRyYW5zaXRpb25DbGFzcyhlbCwgc3RhcnRDbGFzcyk7XG4gICAgICBpZiAoIWNiLmNhbmNlbGxlZCAmJiAhdXNlcldhbnRzQ29udHJvbCkge1xuICAgICAgICBpZiAoaXNWYWxpZER1cmF0aW9uKGV4cGxpY2l0RW50ZXJEdXJhdGlvbikpIHtcbiAgICAgICAgICBzZXRUaW1lb3V0KGNiLCBleHBsaWNpdEVudGVyRHVyYXRpb24pO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHdoZW5UcmFuc2l0aW9uRW5kcyhlbCwgdHlwZSwgY2IpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSk7XG4gIH1cblxuICBpZiAodm5vZGUuZGF0YS5zaG93KSB7XG4gICAgdG9nZ2xlRGlzcGxheSAmJiB0b2dnbGVEaXNwbGF5KCk7XG4gICAgZW50ZXJIb29rICYmIGVudGVySG9vayhlbCwgY2IpO1xuICB9XG5cbiAgaWYgKCFleHBlY3RzQ1NTICYmICF1c2VyV2FudHNDb250cm9sKSB7XG4gICAgY2IoKTtcbiAgfVxufVxuXG5mdW5jdGlvbiBsZWF2ZSAodm5vZGUsIHJtKSB7XG4gIHZhciBlbCA9IHZub2RlLmVsbTtcblxuICAvLyBjYWxsIGVudGVyIGNhbGxiYWNrIG5vd1xuICBpZiAoaXNEZWYoZWwuX2VudGVyQ2IpKSB7XG4gICAgZWwuX2VudGVyQ2IuY2FuY2VsbGVkID0gdHJ1ZTtcbiAgICBlbC5fZW50ZXJDYigpO1xuICB9XG5cbiAgdmFyIGRhdGEgPSByZXNvbHZlVHJhbnNpdGlvbih2bm9kZS5kYXRhLnRyYW5zaXRpb24pO1xuICBpZiAoaXNVbmRlZihkYXRhKSkge1xuICAgIHJldHVybiBybSgpXG4gIH1cblxuICAvKiBpc3RhbmJ1bCBpZ25vcmUgaWYgKi9cbiAgaWYgKGlzRGVmKGVsLl9sZWF2ZUNiKSB8fCBlbC5ub2RlVHlwZSAhPT0gMSkge1xuICAgIHJldHVyblxuICB9XG5cbiAgdmFyIGNzcyA9IGRhdGEuY3NzO1xuICB2YXIgdHlwZSA9IGRhdGEudHlwZTtcbiAgdmFyIGxlYXZlQ2xhc3MgPSBkYXRhLmxlYXZlQ2xhc3M7XG4gIHZhciBsZWF2ZVRvQ2xhc3MgPSBkYXRhLmxlYXZlVG9DbGFzcztcbiAgdmFyIGxlYXZlQWN0aXZlQ2xhc3MgPSBkYXRhLmxlYXZlQWN0aXZlQ2xhc3M7XG4gIHZhciBiZWZvcmVMZWF2ZSA9IGRhdGEuYmVmb3JlTGVhdmU7XG4gIHZhciBsZWF2ZSA9IGRhdGEubGVhdmU7XG4gIHZhciBhZnRlckxlYXZlID0gZGF0YS5hZnRlckxlYXZlO1xuICB2YXIgbGVhdmVDYW5jZWxsZWQgPSBkYXRhLmxlYXZlQ2FuY2VsbGVkO1xuICB2YXIgZGVsYXlMZWF2ZSA9IGRhdGEuZGVsYXlMZWF2ZTtcbiAgdmFyIGR1cmF0aW9uID0gZGF0YS5kdXJhdGlvbjtcblxuICB2YXIgZXhwZWN0c0NTUyA9IGNzcyAhPT0gZmFsc2UgJiYgIWlzSUU5O1xuICB2YXIgdXNlcldhbnRzQ29udHJvbCA9IGdldEhvb2tBcmd1bWVudHNMZW5ndGgobGVhdmUpO1xuXG4gIHZhciBleHBsaWNpdExlYXZlRHVyYXRpb24gPSB0b051bWJlcihcbiAgICBpc09iamVjdChkdXJhdGlvbilcbiAgICAgID8gZHVyYXRpb24ubGVhdmVcbiAgICAgIDogZHVyYXRpb25cbiAgKTtcblxuICBpZiAocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJyAmJiBpc0RlZihleHBsaWNpdExlYXZlRHVyYXRpb24pKSB7XG4gICAgY2hlY2tEdXJhdGlvbihleHBsaWNpdExlYXZlRHVyYXRpb24sICdsZWF2ZScsIHZub2RlKTtcbiAgfVxuXG4gIHZhciBjYiA9IGVsLl9sZWF2ZUNiID0gb25jZShmdW5jdGlvbiAoKSB7XG4gICAgaWYgKGVsLnBhcmVudE5vZGUgJiYgZWwucGFyZW50Tm9kZS5fcGVuZGluZykge1xuICAgICAgZWwucGFyZW50Tm9kZS5fcGVuZGluZ1t2bm9kZS5rZXldID0gbnVsbDtcbiAgICB9XG4gICAgaWYgKGV4cGVjdHNDU1MpIHtcbiAgICAgIHJlbW92ZVRyYW5zaXRpb25DbGFzcyhlbCwgbGVhdmVUb0NsYXNzKTtcbiAgICAgIHJlbW92ZVRyYW5zaXRpb25DbGFzcyhlbCwgbGVhdmVBY3RpdmVDbGFzcyk7XG4gICAgfVxuICAgIGlmIChjYi5jYW5jZWxsZWQpIHtcbiAgICAgIGlmIChleHBlY3RzQ1NTKSB7XG4gICAgICAgIHJlbW92ZVRyYW5zaXRpb25DbGFzcyhlbCwgbGVhdmVDbGFzcyk7XG4gICAgICB9XG4gICAgICBsZWF2ZUNhbmNlbGxlZCAmJiBsZWF2ZUNhbmNlbGxlZChlbCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJtKCk7XG4gICAgICBhZnRlckxlYXZlICYmIGFmdGVyTGVhdmUoZWwpO1xuICAgIH1cbiAgICBlbC5fbGVhdmVDYiA9IG51bGw7XG4gIH0pO1xuXG4gIGlmIChkZWxheUxlYXZlKSB7XG4gICAgZGVsYXlMZWF2ZShwZXJmb3JtTGVhdmUpO1xuICB9IGVsc2Uge1xuICAgIHBlcmZvcm1MZWF2ZSgpO1xuICB9XG5cbiAgZnVuY3Rpb24gcGVyZm9ybUxlYXZlICgpIHtcbiAgICAvLyB0aGUgZGVsYXllZCBsZWF2ZSBtYXkgaGF2ZSBhbHJlYWR5IGJlZW4gY2FuY2VsbGVkXG4gICAgaWYgKGNiLmNhbmNlbGxlZCkge1xuICAgICAgcmV0dXJuXG4gICAgfVxuICAgIC8vIHJlY29yZCBsZWF2aW5nIGVsZW1lbnRcbiAgICBpZiAoIXZub2RlLmRhdGEuc2hvdykge1xuICAgICAgKGVsLnBhcmVudE5vZGUuX3BlbmRpbmcgfHwgKGVsLnBhcmVudE5vZGUuX3BlbmRpbmcgPSB7fSkpWyh2bm9kZS5rZXkpXSA9IHZub2RlO1xuICAgIH1cbiAgICBiZWZvcmVMZWF2ZSAmJiBiZWZvcmVMZWF2ZShlbCk7XG4gICAgaWYgKGV4cGVjdHNDU1MpIHtcbiAgICAgIGFkZFRyYW5zaXRpb25DbGFzcyhlbCwgbGVhdmVDbGFzcyk7XG4gICAgICBhZGRUcmFuc2l0aW9uQ2xhc3MoZWwsIGxlYXZlQWN0aXZlQ2xhc3MpO1xuICAgICAgbmV4dEZyYW1lKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgYWRkVHJhbnNpdGlvbkNsYXNzKGVsLCBsZWF2ZVRvQ2xhc3MpO1xuICAgICAgICByZW1vdmVUcmFuc2l0aW9uQ2xhc3MoZWwsIGxlYXZlQ2xhc3MpO1xuICAgICAgICBpZiAoIWNiLmNhbmNlbGxlZCAmJiAhdXNlcldhbnRzQ29udHJvbCkge1xuICAgICAgICAgIGlmIChpc1ZhbGlkRHVyYXRpb24oZXhwbGljaXRMZWF2ZUR1cmF0aW9uKSkge1xuICAgICAgICAgICAgc2V0VGltZW91dChjYiwgZXhwbGljaXRMZWF2ZUR1cmF0aW9uKTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgd2hlblRyYW5zaXRpb25FbmRzKGVsLCB0eXBlLCBjYik7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9KTtcbiAgICB9XG4gICAgbGVhdmUgJiYgbGVhdmUoZWwsIGNiKTtcbiAgICBpZiAoIWV4cGVjdHNDU1MgJiYgIXVzZXJXYW50c0NvbnRyb2wpIHtcbiAgICAgIGNiKCk7XG4gICAgfVxuICB9XG59XG5cbi8vIG9ubHkgdXNlZCBpbiBkZXYgbW9kZVxuZnVuY3Rpb24gY2hlY2tEdXJhdGlvbiAodmFsLCBuYW1lLCB2bm9kZSkge1xuICBpZiAodHlwZW9mIHZhbCAhPT0gJ251bWJlcicpIHtcbiAgICB3YXJuKFxuICAgICAgXCI8dHJhbnNpdGlvbj4gZXhwbGljaXQgXCIgKyBuYW1lICsgXCIgZHVyYXRpb24gaXMgbm90IGEgdmFsaWQgbnVtYmVyIC0gXCIgK1xuICAgICAgXCJnb3QgXCIgKyAoSlNPTi5zdHJpbmdpZnkodmFsKSkgKyBcIi5cIixcbiAgICAgIHZub2RlLmNvbnRleHRcbiAgICApO1xuICB9IGVsc2UgaWYgKGlzTmFOKHZhbCkpIHtcbiAgICB3YXJuKFxuICAgICAgXCI8dHJhbnNpdGlvbj4gZXhwbGljaXQgXCIgKyBuYW1lICsgXCIgZHVyYXRpb24gaXMgTmFOIC0gXCIgK1xuICAgICAgJ3RoZSBkdXJhdGlvbiBleHByZXNzaW9uIG1pZ2h0IGJlIGluY29ycmVjdC4nLFxuICAgICAgdm5vZGUuY29udGV4dFxuICAgICk7XG4gIH1cbn1cblxuZnVuY3Rpb24gaXNWYWxpZER1cmF0aW9uICh2YWwpIHtcbiAgcmV0dXJuIHR5cGVvZiB2YWwgPT09ICdudW1iZXInICYmICFpc05hTih2YWwpXG59XG5cbi8qKlxuICogTm9ybWFsaXplIGEgdHJhbnNpdGlvbiBob29rJ3MgYXJndW1lbnQgbGVuZ3RoLiBUaGUgaG9vayBtYXkgYmU6XG4gKiAtIGEgbWVyZ2VkIGhvb2sgKGludm9rZXIpIHdpdGggdGhlIG9yaWdpbmFsIGluIC5mbnNcbiAqIC0gYSB3cmFwcGVkIGNvbXBvbmVudCBtZXRob2QgKGNoZWNrIC5fbGVuZ3RoKVxuICogLSBhIHBsYWluIGZ1bmN0aW9uICgubGVuZ3RoKVxuICovXG5mdW5jdGlvbiBnZXRIb29rQXJndW1lbnRzTGVuZ3RoIChmbikge1xuICBpZiAoaXNVbmRlZihmbikpIHtcbiAgICByZXR1cm4gZmFsc2VcbiAgfVxuICB2YXIgaW52b2tlckZucyA9IGZuLmZucztcbiAgaWYgKGlzRGVmKGludm9rZXJGbnMpKSB7XG4gICAgLy8gaW52b2tlclxuICAgIHJldHVybiBnZXRIb29rQXJndW1lbnRzTGVuZ3RoKFxuICAgICAgQXJyYXkuaXNBcnJheShpbnZva2VyRm5zKVxuICAgICAgICA/IGludm9rZXJGbnNbMF1cbiAgICAgICAgOiBpbnZva2VyRm5zXG4gICAgKVxuICB9IGVsc2Uge1xuICAgIHJldHVybiAoZm4uX2xlbmd0aCB8fCBmbi5sZW5ndGgpID4gMVxuICB9XG59XG5cbmZ1bmN0aW9uIF9lbnRlciAoXywgdm5vZGUpIHtcbiAgaWYgKHZub2RlLmRhdGEuc2hvdyAhPT0gdHJ1ZSkge1xuICAgIGVudGVyKHZub2RlKTtcbiAgfVxufVxuXG52YXIgdHJhbnNpdGlvbiA9IGluQnJvd3NlciA/IHtcbiAgY3JlYXRlOiBfZW50ZXIsXG4gIGFjdGl2YXRlOiBfZW50ZXIsXG4gIHJlbW92ZTogZnVuY3Rpb24gcmVtb3ZlJCQxICh2bm9kZSwgcm0pIHtcbiAgICAvKiBpc3RhbmJ1bCBpZ25vcmUgZWxzZSAqL1xuICAgIGlmICh2bm9kZS5kYXRhLnNob3cgIT09IHRydWUpIHtcbiAgICAgIGxlYXZlKHZub2RlLCBybSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJtKCk7XG4gICAgfVxuICB9XG59IDoge307XG5cbnZhciBwbGF0Zm9ybU1vZHVsZXMgPSBbXG4gIGF0dHJzLFxuICBrbGFzcyxcbiAgZXZlbnRzLFxuICBkb21Qcm9wcyxcbiAgc3R5bGUsXG4gIHRyYW5zaXRpb25cbl07XG5cbi8qICAqL1xuXG4vLyB0aGUgZGlyZWN0aXZlIG1vZHVsZSBzaG91bGQgYmUgYXBwbGllZCBsYXN0LCBhZnRlciBhbGxcbi8vIGJ1aWx0LWluIG1vZHVsZXMgaGF2ZSBiZWVuIGFwcGxpZWQuXG52YXIgbW9kdWxlcyA9IHBsYXRmb3JtTW9kdWxlcy5jb25jYXQoYmFzZU1vZHVsZXMpO1xuXG52YXIgcGF0Y2ggPSBjcmVhdGVQYXRjaEZ1bmN0aW9uKHsgbm9kZU9wczogbm9kZU9wcywgbW9kdWxlczogbW9kdWxlcyB9KTtcblxuLyoqXG4gKiBOb3QgdHlwZSBjaGVja2luZyB0aGlzIGZpbGUgYmVjYXVzZSBmbG93IGRvZXNuJ3QgbGlrZSBhdHRhY2hpbmdcbiAqIHByb3BlcnRpZXMgdG8gRWxlbWVudHMuXG4gKi9cblxuLyogaXN0YW5idWwgaWdub3JlIGlmICovXG5pZiAoaXNJRTkpIHtcbiAgLy8gaHR0cDovL3d3dy5tYXR0czQxMS5jb20vcG9zdC9pbnRlcm5ldC1leHBsb3Jlci05LW9uaW5wdXQvXG4gIGRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoJ3NlbGVjdGlvbmNoYW5nZScsIGZ1bmN0aW9uICgpIHtcbiAgICB2YXIgZWwgPSBkb2N1bWVudC5hY3RpdmVFbGVtZW50O1xuICAgIGlmIChlbCAmJiBlbC52bW9kZWwpIHtcbiAgICAgIHRyaWdnZXIoZWwsICdpbnB1dCcpO1xuICAgIH1cbiAgfSk7XG59XG5cbnZhciBtb2RlbCQxID0ge1xuICBpbnNlcnRlZDogZnVuY3Rpb24gaW5zZXJ0ZWQgKGVsLCBiaW5kaW5nLCB2bm9kZSkge1xuICAgIGlmICh2bm9kZS50YWcgPT09ICdzZWxlY3QnKSB7XG4gICAgICBzZXRTZWxlY3RlZChlbCwgYmluZGluZywgdm5vZGUuY29udGV4dCk7XG4gICAgICBlbC5fdk9wdGlvbnMgPSBbXS5tYXAuY2FsbChlbC5vcHRpb25zLCBnZXRWYWx1ZSk7XG4gICAgfSBlbHNlIGlmICh2bm9kZS50YWcgPT09ICd0ZXh0YXJlYScgfHwgaXNUZXh0SW5wdXRUeXBlKGVsLnR5cGUpKSB7XG4gICAgICBlbC5fdk1vZGlmaWVycyA9IGJpbmRpbmcubW9kaWZpZXJzO1xuICAgICAgaWYgKCFiaW5kaW5nLm1vZGlmaWVycy5sYXp5KSB7XG4gICAgICAgIC8vIFNhZmFyaSA8IDEwLjIgJiBVSVdlYlZpZXcgZG9lc24ndCBmaXJlIGNvbXBvc2l0aW9uZW5kIHdoZW5cbiAgICAgICAgLy8gc3dpdGNoaW5nIGZvY3VzIGJlZm9yZSBjb25maXJtaW5nIGNvbXBvc2l0aW9uIGNob2ljZVxuICAgICAgICAvLyB0aGlzIGFsc28gZml4ZXMgdGhlIGlzc3VlIHdoZXJlIHNvbWUgYnJvd3NlcnMgZS5nLiBpT1MgQ2hyb21lXG4gICAgICAgIC8vIGZpcmVzIFwiY2hhbmdlXCIgaW5zdGVhZCBvZiBcImlucHV0XCIgb24gYXV0b2NvbXBsZXRlLlxuICAgICAgICBlbC5hZGRFdmVudExpc3RlbmVyKCdjaGFuZ2UnLCBvbkNvbXBvc2l0aW9uRW5kKTtcbiAgICAgICAgaWYgKCFpc0FuZHJvaWQpIHtcbiAgICAgICAgICBlbC5hZGRFdmVudExpc3RlbmVyKCdjb21wb3NpdGlvbnN0YXJ0Jywgb25Db21wb3NpdGlvblN0YXJ0KTtcbiAgICAgICAgICBlbC5hZGRFdmVudExpc3RlbmVyKCdjb21wb3NpdGlvbmVuZCcsIG9uQ29tcG9zaXRpb25FbmQpO1xuICAgICAgICB9XG4gICAgICAgIC8qIGlzdGFuYnVsIGlnbm9yZSBpZiAqL1xuICAgICAgICBpZiAoaXNJRTkpIHtcbiAgICAgICAgICBlbC52bW9kZWwgPSB0cnVlO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9LFxuICBjb21wb25lbnRVcGRhdGVkOiBmdW5jdGlvbiBjb21wb25lbnRVcGRhdGVkIChlbCwgYmluZGluZywgdm5vZGUpIHtcbiAgICBpZiAodm5vZGUudGFnID09PSAnc2VsZWN0Jykge1xuICAgICAgc2V0U2VsZWN0ZWQoZWwsIGJpbmRpbmcsIHZub2RlLmNvbnRleHQpO1xuICAgICAgLy8gaW4gY2FzZSB0aGUgb3B0aW9ucyByZW5kZXJlZCBieSB2LWZvciBoYXZlIGNoYW5nZWQsXG4gICAgICAvLyBpdCdzIHBvc3NpYmxlIHRoYXQgdGhlIHZhbHVlIGlzIG91dC1vZi1zeW5jIHdpdGggdGhlIHJlbmRlcmVkIG9wdGlvbnMuXG4gICAgICAvLyBkZXRlY3Qgc3VjaCBjYXNlcyBhbmQgZmlsdGVyIG91dCB2YWx1ZXMgdGhhdCBubyBsb25nZXIgaGFzIGEgbWF0Y2hpbmdcbiAgICAgIC8vIG9wdGlvbiBpbiB0aGUgRE9NLlxuICAgICAgdmFyIHByZXZPcHRpb25zID0gZWwuX3ZPcHRpb25zO1xuICAgICAgdmFyIGN1ck9wdGlvbnMgPSBlbC5fdk9wdGlvbnMgPSBbXS5tYXAuY2FsbChlbC5vcHRpb25zLCBnZXRWYWx1ZSk7XG4gICAgICBpZiAoY3VyT3B0aW9ucy5zb21lKGZ1bmN0aW9uIChvLCBpKSB7IHJldHVybiAhbG9vc2VFcXVhbChvLCBwcmV2T3B0aW9uc1tpXSk7IH0pKSB7XG4gICAgICAgIC8vIHRyaWdnZXIgY2hhbmdlIGV2ZW50IGlmXG4gICAgICAgIC8vIG5vIG1hdGNoaW5nIG9wdGlvbiBmb3VuZCBmb3IgYXQgbGVhc3Qgb25lIHZhbHVlXG4gICAgICAgIHZhciBuZWVkUmVzZXQgPSBlbC5tdWx0aXBsZVxuICAgICAgICAgID8gYmluZGluZy52YWx1ZS5zb21lKGZ1bmN0aW9uICh2KSB7IHJldHVybiBoYXNOb01hdGNoaW5nT3B0aW9uKHYsIGN1ck9wdGlvbnMpOyB9KVxuICAgICAgICAgIDogYmluZGluZy52YWx1ZSAhPT0gYmluZGluZy5vbGRWYWx1ZSAmJiBoYXNOb01hdGNoaW5nT3B0aW9uKGJpbmRpbmcudmFsdWUsIGN1ck9wdGlvbnMpO1xuICAgICAgICBpZiAobmVlZFJlc2V0KSB7XG4gICAgICAgICAgdHJpZ2dlcihlbCwgJ2NoYW5nZScpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9XG59O1xuXG5mdW5jdGlvbiBzZXRTZWxlY3RlZCAoZWwsIGJpbmRpbmcsIHZtKSB7XG4gIGFjdHVhbGx5U2V0U2VsZWN0ZWQoZWwsIGJpbmRpbmcsIHZtKTtcbiAgLyogaXN0YW5idWwgaWdub3JlIGlmICovXG4gIGlmIChpc0lFIHx8IGlzRWRnZSkge1xuICAgIHNldFRpbWVvdXQoZnVuY3Rpb24gKCkge1xuICAgICAgYWN0dWFsbHlTZXRTZWxlY3RlZChlbCwgYmluZGluZywgdm0pO1xuICAgIH0sIDApO1xuICB9XG59XG5cbmZ1bmN0aW9uIGFjdHVhbGx5U2V0U2VsZWN0ZWQgKGVsLCBiaW5kaW5nLCB2bSkge1xuICB2YXIgdmFsdWUgPSBiaW5kaW5nLnZhbHVlO1xuICB2YXIgaXNNdWx0aXBsZSA9IGVsLm11bHRpcGxlO1xuICBpZiAoaXNNdWx0aXBsZSAmJiAhQXJyYXkuaXNBcnJheSh2YWx1ZSkpIHtcbiAgICBwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nICYmIHdhcm4oXG4gICAgICBcIjxzZWxlY3QgbXVsdGlwbGUgdi1tb2RlbD1cXFwiXCIgKyAoYmluZGluZy5leHByZXNzaW9uKSArIFwiXFxcIj4gXCIgK1xuICAgICAgXCJleHBlY3RzIGFuIEFycmF5IHZhbHVlIGZvciBpdHMgYmluZGluZywgYnV0IGdvdCBcIiArIChPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwodmFsdWUpLnNsaWNlKDgsIC0xKSksXG4gICAgICB2bVxuICAgICk7XG4gICAgcmV0dXJuXG4gIH1cbiAgdmFyIHNlbGVjdGVkLCBvcHRpb247XG4gIGZvciAodmFyIGkgPSAwLCBsID0gZWwub3B0aW9ucy5sZW5ndGg7IGkgPCBsOyBpKyspIHtcbiAgICBvcHRpb24gPSBlbC5vcHRpb25zW2ldO1xuICAgIGlmIChpc011bHRpcGxlKSB7XG4gICAgICBzZWxlY3RlZCA9IGxvb3NlSW5kZXhPZih2YWx1ZSwgZ2V0VmFsdWUob3B0aW9uKSkgPiAtMTtcbiAgICAgIGlmIChvcHRpb24uc2VsZWN0ZWQgIT09IHNlbGVjdGVkKSB7XG4gICAgICAgIG9wdGlvbi5zZWxlY3RlZCA9IHNlbGVjdGVkO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICBpZiAobG9vc2VFcXVhbChnZXRWYWx1ZShvcHRpb24pLCB2YWx1ZSkpIHtcbiAgICAgICAgaWYgKGVsLnNlbGVjdGVkSW5kZXggIT09IGkpIHtcbiAgICAgICAgICBlbC5zZWxlY3RlZEluZGV4ID0gaTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm5cbiAgICAgIH1cbiAgICB9XG4gIH1cbiAgaWYgKCFpc011bHRpcGxlKSB7XG4gICAgZWwuc2VsZWN0ZWRJbmRleCA9IC0xO1xuICB9XG59XG5cbmZ1bmN0aW9uIGhhc05vTWF0Y2hpbmdPcHRpb24gKHZhbHVlLCBvcHRpb25zKSB7XG4gIHJldHVybiBvcHRpb25zLmV2ZXJ5KGZ1bmN0aW9uIChvKSB7IHJldHVybiAhbG9vc2VFcXVhbChvLCB2YWx1ZSk7IH0pXG59XG5cbmZ1bmN0aW9uIGdldFZhbHVlIChvcHRpb24pIHtcbiAgcmV0dXJuICdfdmFsdWUnIGluIG9wdGlvblxuICAgID8gb3B0aW9uLl92YWx1ZVxuICAgIDogb3B0aW9uLnZhbHVlXG59XG5cbmZ1bmN0aW9uIG9uQ29tcG9zaXRpb25TdGFydCAoZSkge1xuICBlLnRhcmdldC5jb21wb3NpbmcgPSB0cnVlO1xufVxuXG5mdW5jdGlvbiBvbkNvbXBvc2l0aW9uRW5kIChlKSB7XG4gIC8vIHByZXZlbnQgdHJpZ2dlcmluZyBhbiBpbnB1dCBldmVudCBmb3Igbm8gcmVhc29uXG4gIGlmICghZS50YXJnZXQuY29tcG9zaW5nKSB7IHJldHVybiB9XG4gIGUudGFyZ2V0LmNvbXBvc2luZyA9IGZhbHNlO1xuICB0cmlnZ2VyKGUudGFyZ2V0LCAnaW5wdXQnKTtcbn1cblxuZnVuY3Rpb24gdHJpZ2dlciAoZWwsIHR5cGUpIHtcbiAgdmFyIGUgPSBkb2N1bWVudC5jcmVhdGVFdmVudCgnSFRNTEV2ZW50cycpO1xuICBlLmluaXRFdmVudCh0eXBlLCB0cnVlLCB0cnVlKTtcbiAgZWwuZGlzcGF0Y2hFdmVudChlKTtcbn1cblxuLyogICovXG5cbi8vIHJlY3Vyc2l2ZWx5IHNlYXJjaCBmb3IgcG9zc2libGUgdHJhbnNpdGlvbiBkZWZpbmVkIGluc2lkZSB0aGUgY29tcG9uZW50IHJvb3RcbmZ1bmN0aW9uIGxvY2F0ZU5vZGUgKHZub2RlKSB7XG4gIHJldHVybiB2bm9kZS5jb21wb25lbnRJbnN0YW5jZSAmJiAoIXZub2RlLmRhdGEgfHwgIXZub2RlLmRhdGEudHJhbnNpdGlvbilcbiAgICA/IGxvY2F0ZU5vZGUodm5vZGUuY29tcG9uZW50SW5zdGFuY2UuX3Zub2RlKVxuICAgIDogdm5vZGVcbn1cblxudmFyIHNob3cgPSB7XG4gIGJpbmQ6IGZ1bmN0aW9uIGJpbmQgKGVsLCByZWYsIHZub2RlKSB7XG4gICAgdmFyIHZhbHVlID0gcmVmLnZhbHVlO1xuXG4gICAgdm5vZGUgPSBsb2NhdGVOb2RlKHZub2RlKTtcbiAgICB2YXIgdHJhbnNpdGlvbiQkMSA9IHZub2RlLmRhdGEgJiYgdm5vZGUuZGF0YS50cmFuc2l0aW9uO1xuICAgIHZhciBvcmlnaW5hbERpc3BsYXkgPSBlbC5fX3ZPcmlnaW5hbERpc3BsYXkgPVxuICAgICAgZWwuc3R5bGUuZGlzcGxheSA9PT0gJ25vbmUnID8gJycgOiBlbC5zdHlsZS5kaXNwbGF5O1xuICAgIGlmICh2YWx1ZSAmJiB0cmFuc2l0aW9uJCQxKSB7XG4gICAgICB2bm9kZS5kYXRhLnNob3cgPSB0cnVlO1xuICAgICAgZW50ZXIodm5vZGUsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgZWwuc3R5bGUuZGlzcGxheSA9IG9yaWdpbmFsRGlzcGxheTtcbiAgICAgIH0pO1xuICAgIH0gZWxzZSB7XG4gICAgICBlbC5zdHlsZS5kaXNwbGF5ID0gdmFsdWUgPyBvcmlnaW5hbERpc3BsYXkgOiAnbm9uZSc7XG4gICAgfVxuICB9LFxuXG4gIHVwZGF0ZTogZnVuY3Rpb24gdXBkYXRlIChlbCwgcmVmLCB2bm9kZSkge1xuICAgIHZhciB2YWx1ZSA9IHJlZi52YWx1ZTtcbiAgICB2YXIgb2xkVmFsdWUgPSByZWYub2xkVmFsdWU7XG5cbiAgICAvKiBpc3RhbmJ1bCBpZ25vcmUgaWYgKi9cbiAgICBpZiAodmFsdWUgPT09IG9sZFZhbHVlKSB7IHJldHVybiB9XG4gICAgdm5vZGUgPSBsb2NhdGVOb2RlKHZub2RlKTtcbiAgICB2YXIgdHJhbnNpdGlvbiQkMSA9IHZub2RlLmRhdGEgJiYgdm5vZGUuZGF0YS50cmFuc2l0aW9uO1xuICAgIGlmICh0cmFuc2l0aW9uJCQxKSB7XG4gICAgICB2bm9kZS5kYXRhLnNob3cgPSB0cnVlO1xuICAgICAgaWYgKHZhbHVlKSB7XG4gICAgICAgIGVudGVyKHZub2RlLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgZWwuc3R5bGUuZGlzcGxheSA9IGVsLl9fdk9yaWdpbmFsRGlzcGxheTtcbiAgICAgICAgfSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBsZWF2ZSh2bm9kZSwgZnVuY3Rpb24gKCkge1xuICAgICAgICAgIGVsLnN0eWxlLmRpc3BsYXkgPSAnbm9uZSc7XG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICBlbC5zdHlsZS5kaXNwbGF5ID0gdmFsdWUgPyBlbC5fX3ZPcmlnaW5hbERpc3BsYXkgOiAnbm9uZSc7XG4gICAgfVxuICB9LFxuXG4gIHVuYmluZDogZnVuY3Rpb24gdW5iaW5kIChcbiAgICBlbCxcbiAgICBiaW5kaW5nLFxuICAgIHZub2RlLFxuICAgIG9sZFZub2RlLFxuICAgIGlzRGVzdHJveVxuICApIHtcbiAgICBpZiAoIWlzRGVzdHJveSkge1xuICAgICAgZWwuc3R5bGUuZGlzcGxheSA9IGVsLl9fdk9yaWdpbmFsRGlzcGxheTtcbiAgICB9XG4gIH1cbn07XG5cbnZhciBwbGF0Zm9ybURpcmVjdGl2ZXMgPSB7XG4gIG1vZGVsOiBtb2RlbCQxLFxuICBzaG93OiBzaG93XG59O1xuXG4vKiAgKi9cblxuLy8gUHJvdmlkZXMgdHJhbnNpdGlvbiBzdXBwb3J0IGZvciBhIHNpbmdsZSBlbGVtZW50L2NvbXBvbmVudC5cbi8vIHN1cHBvcnRzIHRyYW5zaXRpb24gbW9kZSAob3V0LWluIC8gaW4tb3V0KVxuXG52YXIgdHJhbnNpdGlvblByb3BzID0ge1xuICBuYW1lOiBTdHJpbmcsXG4gIGFwcGVhcjogQm9vbGVhbixcbiAgY3NzOiBCb29sZWFuLFxuICBtb2RlOiBTdHJpbmcsXG4gIHR5cGU6IFN0cmluZyxcbiAgZW50ZXJDbGFzczogU3RyaW5nLFxuICBsZWF2ZUNsYXNzOiBTdHJpbmcsXG4gIGVudGVyVG9DbGFzczogU3RyaW5nLFxuICBsZWF2ZVRvQ2xhc3M6IFN0cmluZyxcbiAgZW50ZXJBY3RpdmVDbGFzczogU3RyaW5nLFxuICBsZWF2ZUFjdGl2ZUNsYXNzOiBTdHJpbmcsXG4gIGFwcGVhckNsYXNzOiBTdHJpbmcsXG4gIGFwcGVhckFjdGl2ZUNsYXNzOiBTdHJpbmcsXG4gIGFwcGVhclRvQ2xhc3M6IFN0cmluZyxcbiAgZHVyYXRpb246IFtOdW1iZXIsIFN0cmluZywgT2JqZWN0XVxufTtcblxuLy8gaW4gY2FzZSB0aGUgY2hpbGQgaXMgYWxzbyBhbiBhYnN0cmFjdCBjb21wb25lbnQsIGUuZy4gPGtlZXAtYWxpdmU+XG4vLyB3ZSB3YW50IHRvIHJlY3Vyc2l2ZWx5IHJldHJpZXZlIHRoZSByZWFsIGNvbXBvbmVudCB0byBiZSByZW5kZXJlZFxuZnVuY3Rpb24gZ2V0UmVhbENoaWxkICh2bm9kZSkge1xuICB2YXIgY29tcE9wdGlvbnMgPSB2bm9kZSAmJiB2bm9kZS5jb21wb25lbnRPcHRpb25zO1xuICBpZiAoY29tcE9wdGlvbnMgJiYgY29tcE9wdGlvbnMuQ3Rvci5vcHRpb25zLmFic3RyYWN0KSB7XG4gICAgcmV0dXJuIGdldFJlYWxDaGlsZChnZXRGaXJzdENvbXBvbmVudENoaWxkKGNvbXBPcHRpb25zLmNoaWxkcmVuKSlcbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gdm5vZGVcbiAgfVxufVxuXG5mdW5jdGlvbiBleHRyYWN0VHJhbnNpdGlvbkRhdGEgKGNvbXApIHtcbiAgdmFyIGRhdGEgPSB7fTtcbiAgdmFyIG9wdGlvbnMgPSBjb21wLiRvcHRpb25zO1xuICAvLyBwcm9wc1xuICBmb3IgKHZhciBrZXkgaW4gb3B0aW9ucy5wcm9wc0RhdGEpIHtcbiAgICBkYXRhW2tleV0gPSBjb21wW2tleV07XG4gIH1cbiAgLy8gZXZlbnRzLlxuICAvLyBleHRyYWN0IGxpc3RlbmVycyBhbmQgcGFzcyB0aGVtIGRpcmVjdGx5IHRvIHRoZSB0cmFuc2l0aW9uIG1ldGhvZHNcbiAgdmFyIGxpc3RlbmVycyA9IG9wdGlvbnMuX3BhcmVudExpc3RlbmVycztcbiAgZm9yICh2YXIga2V5JDEgaW4gbGlzdGVuZXJzKSB7XG4gICAgZGF0YVtjYW1lbGl6ZShrZXkkMSldID0gbGlzdGVuZXJzW2tleSQxXTtcbiAgfVxuICByZXR1cm4gZGF0YVxufVxuXG5mdW5jdGlvbiBwbGFjZWhvbGRlciAoaCwgcmF3Q2hpbGQpIHtcbiAgaWYgKC9cXGQta2VlcC1hbGl2ZSQvLnRlc3QocmF3Q2hpbGQudGFnKSkge1xuICAgIHJldHVybiBoKCdrZWVwLWFsaXZlJywge1xuICAgICAgcHJvcHM6IHJhd0NoaWxkLmNvbXBvbmVudE9wdGlvbnMucHJvcHNEYXRhXG4gICAgfSlcbiAgfVxufVxuXG5mdW5jdGlvbiBoYXNQYXJlbnRUcmFuc2l0aW9uICh2bm9kZSkge1xuICB3aGlsZSAoKHZub2RlID0gdm5vZGUucGFyZW50KSkge1xuICAgIGlmICh2bm9kZS5kYXRhLnRyYW5zaXRpb24pIHtcbiAgICAgIHJldHVybiB0cnVlXG4gICAgfVxuICB9XG59XG5cbmZ1bmN0aW9uIGlzU2FtZUNoaWxkIChjaGlsZCwgb2xkQ2hpbGQpIHtcbiAgcmV0dXJuIG9sZENoaWxkLmtleSA9PT0gY2hpbGQua2V5ICYmIG9sZENoaWxkLnRhZyA9PT0gY2hpbGQudGFnXG59XG5cbnZhciBUcmFuc2l0aW9uID0ge1xuICBuYW1lOiAndHJhbnNpdGlvbicsXG4gIHByb3BzOiB0cmFuc2l0aW9uUHJvcHMsXG4gIGFic3RyYWN0OiB0cnVlLFxuXG4gIHJlbmRlcjogZnVuY3Rpb24gcmVuZGVyIChoKSB7XG4gICAgdmFyIHRoaXMkMSA9IHRoaXM7XG5cbiAgICB2YXIgY2hpbGRyZW4gPSB0aGlzLiRvcHRpb25zLl9yZW5kZXJDaGlsZHJlbjtcbiAgICBpZiAoIWNoaWxkcmVuKSB7XG4gICAgICByZXR1cm5cbiAgICB9XG5cbiAgICAvLyBmaWx0ZXIgb3V0IHRleHQgbm9kZXMgKHBvc3NpYmxlIHdoaXRlc3BhY2VzKVxuICAgIGNoaWxkcmVuID0gY2hpbGRyZW4uZmlsdGVyKGZ1bmN0aW9uIChjKSB7IHJldHVybiBjLnRhZyB8fCBpc0FzeW5jUGxhY2Vob2xkZXIoYyk7IH0pO1xuICAgIC8qIGlzdGFuYnVsIGlnbm9yZSBpZiAqL1xuICAgIGlmICghY2hpbGRyZW4ubGVuZ3RoKSB7XG4gICAgICByZXR1cm5cbiAgICB9XG5cbiAgICAvLyB3YXJuIG11bHRpcGxlIGVsZW1lbnRzXG4gICAgaWYgKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicgJiYgY2hpbGRyZW4ubGVuZ3RoID4gMSkge1xuICAgICAgd2FybihcbiAgICAgICAgJzx0cmFuc2l0aW9uPiBjYW4gb25seSBiZSB1c2VkIG9uIGEgc2luZ2xlIGVsZW1lbnQuIFVzZSAnICtcbiAgICAgICAgJzx0cmFuc2l0aW9uLWdyb3VwPiBmb3IgbGlzdHMuJyxcbiAgICAgICAgdGhpcy4kcGFyZW50XG4gICAgICApO1xuICAgIH1cblxuICAgIHZhciBtb2RlID0gdGhpcy5tb2RlO1xuXG4gICAgLy8gd2FybiBpbnZhbGlkIG1vZGVcbiAgICBpZiAocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJyAmJlxuICAgICAgbW9kZSAmJiBtb2RlICE9PSAnaW4tb3V0JyAmJiBtb2RlICE9PSAnb3V0LWluJ1xuICAgICkge1xuICAgICAgd2FybihcbiAgICAgICAgJ2ludmFsaWQgPHRyYW5zaXRpb24+IG1vZGU6ICcgKyBtb2RlLFxuICAgICAgICB0aGlzLiRwYXJlbnRcbiAgICAgICk7XG4gICAgfVxuXG4gICAgdmFyIHJhd0NoaWxkID0gY2hpbGRyZW5bMF07XG5cbiAgICAvLyBpZiB0aGlzIGlzIGEgY29tcG9uZW50IHJvb3Qgbm9kZSBhbmQgdGhlIGNvbXBvbmVudCdzXG4gICAgLy8gcGFyZW50IGNvbnRhaW5lciBub2RlIGFsc28gaGFzIHRyYW5zaXRpb24sIHNraXAuXG4gICAgaWYgKGhhc1BhcmVudFRyYW5zaXRpb24odGhpcy4kdm5vZGUpKSB7XG4gICAgICByZXR1cm4gcmF3Q2hpbGRcbiAgICB9XG5cbiAgICAvLyBhcHBseSB0cmFuc2l0aW9uIGRhdGEgdG8gY2hpbGRcbiAgICAvLyB1c2UgZ2V0UmVhbENoaWxkKCkgdG8gaWdub3JlIGFic3RyYWN0IGNvbXBvbmVudHMgZS5nLiBrZWVwLWFsaXZlXG4gICAgdmFyIGNoaWxkID0gZ2V0UmVhbENoaWxkKHJhd0NoaWxkKTtcbiAgICAvKiBpc3RhbmJ1bCBpZ25vcmUgaWYgKi9cbiAgICBpZiAoIWNoaWxkKSB7XG4gICAgICByZXR1cm4gcmF3Q2hpbGRcbiAgICB9XG5cbiAgICBpZiAodGhpcy5fbGVhdmluZykge1xuICAgICAgcmV0dXJuIHBsYWNlaG9sZGVyKGgsIHJhd0NoaWxkKVxuICAgIH1cblxuICAgIC8vIGVuc3VyZSBhIGtleSB0aGF0IGlzIHVuaXF1ZSB0byB0aGUgdm5vZGUgdHlwZSBhbmQgdG8gdGhpcyB0cmFuc2l0aW9uXG4gICAgLy8gY29tcG9uZW50IGluc3RhbmNlLiBUaGlzIGtleSB3aWxsIGJlIHVzZWQgdG8gcmVtb3ZlIHBlbmRpbmcgbGVhdmluZyBub2Rlc1xuICAgIC8vIGR1cmluZyBlbnRlcmluZy5cbiAgICB2YXIgaWQgPSBcIl9fdHJhbnNpdGlvbi1cIiArICh0aGlzLl91aWQpICsgXCItXCI7XG4gICAgY2hpbGQua2V5ID0gY2hpbGQua2V5ID09IG51bGxcbiAgICAgID8gY2hpbGQuaXNDb21tZW50XG4gICAgICAgID8gaWQgKyAnY29tbWVudCdcbiAgICAgICAgOiBpZCArIGNoaWxkLnRhZ1xuICAgICAgOiBpc1ByaW1pdGl2ZShjaGlsZC5rZXkpXG4gICAgICAgID8gKFN0cmluZyhjaGlsZC5rZXkpLmluZGV4T2YoaWQpID09PSAwID8gY2hpbGQua2V5IDogaWQgKyBjaGlsZC5rZXkpXG4gICAgICAgIDogY2hpbGQua2V5O1xuXG4gICAgdmFyIGRhdGEgPSAoY2hpbGQuZGF0YSB8fCAoY2hpbGQuZGF0YSA9IHt9KSkudHJhbnNpdGlvbiA9IGV4dHJhY3RUcmFuc2l0aW9uRGF0YSh0aGlzKTtcbiAgICB2YXIgb2xkUmF3Q2hpbGQgPSB0aGlzLl92bm9kZTtcbiAgICB2YXIgb2xkQ2hpbGQgPSBnZXRSZWFsQ2hpbGQob2xkUmF3Q2hpbGQpO1xuXG4gICAgLy8gbWFyayB2LXNob3dcbiAgICAvLyBzbyB0aGF0IHRoZSB0cmFuc2l0aW9uIG1vZHVsZSBjYW4gaGFuZCBvdmVyIHRoZSBjb250cm9sIHRvIHRoZSBkaXJlY3RpdmVcbiAgICBpZiAoY2hpbGQuZGF0YS5kaXJlY3RpdmVzICYmIGNoaWxkLmRhdGEuZGlyZWN0aXZlcy5zb21lKGZ1bmN0aW9uIChkKSB7IHJldHVybiBkLm5hbWUgPT09ICdzaG93JzsgfSkpIHtcbiAgICAgIGNoaWxkLmRhdGEuc2hvdyA9IHRydWU7XG4gICAgfVxuXG4gICAgaWYgKFxuICAgICAgb2xkQ2hpbGQgJiZcbiAgICAgIG9sZENoaWxkLmRhdGEgJiZcbiAgICAgICFpc1NhbWVDaGlsZChjaGlsZCwgb2xkQ2hpbGQpICYmXG4gICAgICAhaXNBc3luY1BsYWNlaG9sZGVyKG9sZENoaWxkKVxuICAgICkge1xuICAgICAgLy8gcmVwbGFjZSBvbGQgY2hpbGQgdHJhbnNpdGlvbiBkYXRhIHdpdGggZnJlc2ggb25lXG4gICAgICAvLyBpbXBvcnRhbnQgZm9yIGR5bmFtaWMgdHJhbnNpdGlvbnMhXG4gICAgICB2YXIgb2xkRGF0YSA9IG9sZENoaWxkICYmIChvbGRDaGlsZC5kYXRhLnRyYW5zaXRpb24gPSBleHRlbmQoe30sIGRhdGEpKTtcbiAgICAgIC8vIGhhbmRsZSB0cmFuc2l0aW9uIG1vZGVcbiAgICAgIGlmIChtb2RlID09PSAnb3V0LWluJykge1xuICAgICAgICAvLyByZXR1cm4gcGxhY2Vob2xkZXIgbm9kZSBhbmQgcXVldWUgdXBkYXRlIHdoZW4gbGVhdmUgZmluaXNoZXNcbiAgICAgICAgdGhpcy5fbGVhdmluZyA9IHRydWU7XG4gICAgICAgIG1lcmdlVk5vZGVIb29rKG9sZERhdGEsICdhZnRlckxlYXZlJywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgIHRoaXMkMS5fbGVhdmluZyA9IGZhbHNlO1xuICAgICAgICAgIHRoaXMkMS4kZm9yY2VVcGRhdGUoKTtcbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybiBwbGFjZWhvbGRlcihoLCByYXdDaGlsZClcbiAgICAgIH0gZWxzZSBpZiAobW9kZSA9PT0gJ2luLW91dCcpIHtcbiAgICAgICAgaWYgKGlzQXN5bmNQbGFjZWhvbGRlcihjaGlsZCkpIHtcbiAgICAgICAgICByZXR1cm4gb2xkUmF3Q2hpbGRcbiAgICAgICAgfVxuICAgICAgICB2YXIgZGVsYXllZExlYXZlO1xuICAgICAgICB2YXIgcGVyZm9ybUxlYXZlID0gZnVuY3Rpb24gKCkgeyBkZWxheWVkTGVhdmUoKTsgfTtcbiAgICAgICAgbWVyZ2VWTm9kZUhvb2soZGF0YSwgJ2FmdGVyRW50ZXInLCBwZXJmb3JtTGVhdmUpO1xuICAgICAgICBtZXJnZVZOb2RlSG9vayhkYXRhLCAnZW50ZXJDYW5jZWxsZWQnLCBwZXJmb3JtTGVhdmUpO1xuICAgICAgICBtZXJnZVZOb2RlSG9vayhvbGREYXRhLCAnZGVsYXlMZWF2ZScsIGZ1bmN0aW9uIChsZWF2ZSkgeyBkZWxheWVkTGVhdmUgPSBsZWF2ZTsgfSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIHJhd0NoaWxkXG4gIH1cbn07XG5cbi8qICAqL1xuXG4vLyBQcm92aWRlcyB0cmFuc2l0aW9uIHN1cHBvcnQgZm9yIGxpc3QgaXRlbXMuXG4vLyBzdXBwb3J0cyBtb3ZlIHRyYW5zaXRpb25zIHVzaW5nIHRoZSBGTElQIHRlY2huaXF1ZS5cblxuLy8gQmVjYXVzZSB0aGUgdmRvbSdzIGNoaWxkcmVuIHVwZGF0ZSBhbGdvcml0aG0gaXMgXCJ1bnN0YWJsZVwiIC0gaS5lLlxuLy8gaXQgZG9lc24ndCBndWFyYW50ZWUgdGhlIHJlbGF0aXZlIHBvc2l0aW9uaW5nIG9mIHJlbW92ZWQgZWxlbWVudHMsXG4vLyB3ZSBmb3JjZSB0cmFuc2l0aW9uLWdyb3VwIHRvIHVwZGF0ZSBpdHMgY2hpbGRyZW4gaW50byB0d28gcGFzc2VzOlxuLy8gaW4gdGhlIGZpcnN0IHBhc3MsIHdlIHJlbW92ZSBhbGwgbm9kZXMgdGhhdCBuZWVkIHRvIGJlIHJlbW92ZWQsXG4vLyB0cmlnZ2VyaW5nIHRoZWlyIGxlYXZpbmcgdHJhbnNpdGlvbjsgaW4gdGhlIHNlY29uZCBwYXNzLCB3ZSBpbnNlcnQvbW92ZVxuLy8gaW50byB0aGUgZmluYWwgZGVzaXJlZCBzdGF0ZS4gVGhpcyB3YXkgaW4gdGhlIHNlY29uZCBwYXNzIHJlbW92ZWRcbi8vIG5vZGVzIHdpbGwgcmVtYWluIHdoZXJlIHRoZXkgc2hvdWxkIGJlLlxuXG52YXIgcHJvcHMgPSBleHRlbmQoe1xuICB0YWc6IFN0cmluZyxcbiAgbW92ZUNsYXNzOiBTdHJpbmdcbn0sIHRyYW5zaXRpb25Qcm9wcyk7XG5cbmRlbGV0ZSBwcm9wcy5tb2RlO1xuXG52YXIgVHJhbnNpdGlvbkdyb3VwID0ge1xuICBwcm9wczogcHJvcHMsXG5cbiAgcmVuZGVyOiBmdW5jdGlvbiByZW5kZXIgKGgpIHtcbiAgICB2YXIgdGFnID0gdGhpcy50YWcgfHwgdGhpcy4kdm5vZGUuZGF0YS50YWcgfHwgJ3NwYW4nO1xuICAgIHZhciBtYXAgPSBPYmplY3QuY3JlYXRlKG51bGwpO1xuICAgIHZhciBwcmV2Q2hpbGRyZW4gPSB0aGlzLnByZXZDaGlsZHJlbiA9IHRoaXMuY2hpbGRyZW47XG4gICAgdmFyIHJhd0NoaWxkcmVuID0gdGhpcy4kc2xvdHMuZGVmYXVsdCB8fCBbXTtcbiAgICB2YXIgY2hpbGRyZW4gPSB0aGlzLmNoaWxkcmVuID0gW107XG4gICAgdmFyIHRyYW5zaXRpb25EYXRhID0gZXh0cmFjdFRyYW5zaXRpb25EYXRhKHRoaXMpO1xuXG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCByYXdDaGlsZHJlbi5sZW5ndGg7IGkrKykge1xuICAgICAgdmFyIGMgPSByYXdDaGlsZHJlbltpXTtcbiAgICAgIGlmIChjLnRhZykge1xuICAgICAgICBpZiAoYy5rZXkgIT0gbnVsbCAmJiBTdHJpbmcoYy5rZXkpLmluZGV4T2YoJ19fdmxpc3QnKSAhPT0gMCkge1xuICAgICAgICAgIGNoaWxkcmVuLnB1c2goYyk7XG4gICAgICAgICAgbWFwW2Mua2V5XSA9IGNcbiAgICAgICAgICA7KGMuZGF0YSB8fCAoYy5kYXRhID0ge30pKS50cmFuc2l0aW9uID0gdHJhbnNpdGlvbkRhdGE7XG4gICAgICAgIH0gZWxzZSBpZiAocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJykge1xuICAgICAgICAgIHZhciBvcHRzID0gYy5jb21wb25lbnRPcHRpb25zO1xuICAgICAgICAgIHZhciBuYW1lID0gb3B0cyA/IChvcHRzLkN0b3Iub3B0aW9ucy5uYW1lIHx8IG9wdHMudGFnIHx8ICcnKSA6IGMudGFnO1xuICAgICAgICAgIHdhcm4oKFwiPHRyYW5zaXRpb24tZ3JvdXA+IGNoaWxkcmVuIG11c3QgYmUga2V5ZWQ6IDxcIiArIG5hbWUgKyBcIj5cIikpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKHByZXZDaGlsZHJlbikge1xuICAgICAgdmFyIGtlcHQgPSBbXTtcbiAgICAgIHZhciByZW1vdmVkID0gW107XG4gICAgICBmb3IgKHZhciBpJDEgPSAwOyBpJDEgPCBwcmV2Q2hpbGRyZW4ubGVuZ3RoOyBpJDErKykge1xuICAgICAgICB2YXIgYyQxID0gcHJldkNoaWxkcmVuW2kkMV07XG4gICAgICAgIGMkMS5kYXRhLnRyYW5zaXRpb24gPSB0cmFuc2l0aW9uRGF0YTtcbiAgICAgICAgYyQxLmRhdGEucG9zID0gYyQxLmVsbS5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcbiAgICAgICAgaWYgKG1hcFtjJDEua2V5XSkge1xuICAgICAgICAgIGtlcHQucHVzaChjJDEpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHJlbW92ZWQucHVzaChjJDEpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICB0aGlzLmtlcHQgPSBoKHRhZywgbnVsbCwga2VwdCk7XG4gICAgICB0aGlzLnJlbW92ZWQgPSByZW1vdmVkO1xuICAgIH1cblxuICAgIHJldHVybiBoKHRhZywgbnVsbCwgY2hpbGRyZW4pXG4gIH0sXG5cbiAgYmVmb3JlVXBkYXRlOiBmdW5jdGlvbiBiZWZvcmVVcGRhdGUgKCkge1xuICAgIC8vIGZvcmNlIHJlbW92aW5nIHBhc3NcbiAgICB0aGlzLl9fcGF0Y2hfXyhcbiAgICAgIHRoaXMuX3Zub2RlLFxuICAgICAgdGhpcy5rZXB0LFxuICAgICAgZmFsc2UsIC8vIGh5ZHJhdGluZ1xuICAgICAgdHJ1ZSAvLyByZW1vdmVPbmx5ICghaW1wb3J0YW50LCBhdm9pZHMgdW5uZWNlc3NhcnkgbW92ZXMpXG4gICAgKTtcbiAgICB0aGlzLl92bm9kZSA9IHRoaXMua2VwdDtcbiAgfSxcblxuICB1cGRhdGVkOiBmdW5jdGlvbiB1cGRhdGVkICgpIHtcbiAgICB2YXIgY2hpbGRyZW4gPSB0aGlzLnByZXZDaGlsZHJlbjtcbiAgICB2YXIgbW92ZUNsYXNzID0gdGhpcy5tb3ZlQ2xhc3MgfHwgKCh0aGlzLm5hbWUgfHwgJ3YnKSArICctbW92ZScpO1xuICAgIGlmICghY2hpbGRyZW4ubGVuZ3RoIHx8ICF0aGlzLmhhc01vdmUoY2hpbGRyZW5bMF0uZWxtLCBtb3ZlQ2xhc3MpKSB7XG4gICAgICByZXR1cm5cbiAgICB9XG5cbiAgICAvLyB3ZSBkaXZpZGUgdGhlIHdvcmsgaW50byB0aHJlZSBsb29wcyB0byBhdm9pZCBtaXhpbmcgRE9NIHJlYWRzIGFuZCB3cml0ZXNcbiAgICAvLyBpbiBlYWNoIGl0ZXJhdGlvbiAtIHdoaWNoIGhlbHBzIHByZXZlbnQgbGF5b3V0IHRocmFzaGluZy5cbiAgICBjaGlsZHJlbi5mb3JFYWNoKGNhbGxQZW5kaW5nQ2JzKTtcbiAgICBjaGlsZHJlbi5mb3JFYWNoKHJlY29yZFBvc2l0aW9uKTtcbiAgICBjaGlsZHJlbi5mb3JFYWNoKGFwcGx5VHJhbnNsYXRpb24pO1xuXG4gICAgLy8gZm9yY2UgcmVmbG93IHRvIHB1dCBldmVyeXRoaW5nIGluIHBvc2l0aW9uXG4gICAgdmFyIGJvZHkgPSBkb2N1bWVudC5ib2R5O1xuICAgIHZhciBmID0gYm9keS5vZmZzZXRIZWlnaHQ7IC8vIGVzbGludC1kaXNhYmxlLWxpbmVcblxuICAgIGNoaWxkcmVuLmZvckVhY2goZnVuY3Rpb24gKGMpIHtcbiAgICAgIGlmIChjLmRhdGEubW92ZWQpIHtcbiAgICAgICAgdmFyIGVsID0gYy5lbG07XG4gICAgICAgIHZhciBzID0gZWwuc3R5bGU7XG4gICAgICAgIGFkZFRyYW5zaXRpb25DbGFzcyhlbCwgbW92ZUNsYXNzKTtcbiAgICAgICAgcy50cmFuc2Zvcm0gPSBzLldlYmtpdFRyYW5zZm9ybSA9IHMudHJhbnNpdGlvbkR1cmF0aW9uID0gJyc7XG4gICAgICAgIGVsLmFkZEV2ZW50TGlzdGVuZXIodHJhbnNpdGlvbkVuZEV2ZW50LCBlbC5fbW92ZUNiID0gZnVuY3Rpb24gY2IgKGUpIHtcbiAgICAgICAgICBpZiAoIWUgfHwgL3RyYW5zZm9ybSQvLnRlc3QoZS5wcm9wZXJ0eU5hbWUpKSB7XG4gICAgICAgICAgICBlbC5yZW1vdmVFdmVudExpc3RlbmVyKHRyYW5zaXRpb25FbmRFdmVudCwgY2IpO1xuICAgICAgICAgICAgZWwuX21vdmVDYiA9IG51bGw7XG4gICAgICAgICAgICByZW1vdmVUcmFuc2l0aW9uQ2xhc3MoZWwsIG1vdmVDbGFzcyk7XG4gICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfSxcblxuICBtZXRob2RzOiB7XG4gICAgaGFzTW92ZTogZnVuY3Rpb24gaGFzTW92ZSAoZWwsIG1vdmVDbGFzcykge1xuICAgICAgLyogaXN0YW5idWwgaWdub3JlIGlmICovXG4gICAgICBpZiAoIWhhc1RyYW5zaXRpb24pIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlXG4gICAgICB9XG4gICAgICAvKiBpc3RhbmJ1bCBpZ25vcmUgaWYgKi9cbiAgICAgIGlmICh0aGlzLl9oYXNNb3ZlKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9oYXNNb3ZlXG4gICAgICB9XG4gICAgICAvLyBEZXRlY3Qgd2hldGhlciBhbiBlbGVtZW50IHdpdGggdGhlIG1vdmUgY2xhc3MgYXBwbGllZCBoYXNcbiAgICAgIC8vIENTUyB0cmFuc2l0aW9ucy4gU2luY2UgdGhlIGVsZW1lbnQgbWF5IGJlIGluc2lkZSBhbiBlbnRlcmluZ1xuICAgICAgLy8gdHJhbnNpdGlvbiBhdCB0aGlzIHZlcnkgbW9tZW50LCB3ZSBtYWtlIGEgY2xvbmUgb2YgaXQgYW5kIHJlbW92ZVxuICAgICAgLy8gYWxsIG90aGVyIHRyYW5zaXRpb24gY2xhc3NlcyBhcHBsaWVkIHRvIGVuc3VyZSBvbmx5IHRoZSBtb3ZlIGNsYXNzXG4gICAgICAvLyBpcyBhcHBsaWVkLlxuICAgICAgdmFyIGNsb25lID0gZWwuY2xvbmVOb2RlKCk7XG4gICAgICBpZiAoZWwuX3RyYW5zaXRpb25DbGFzc2VzKSB7XG4gICAgICAgIGVsLl90cmFuc2l0aW9uQ2xhc3Nlcy5mb3JFYWNoKGZ1bmN0aW9uIChjbHMpIHsgcmVtb3ZlQ2xhc3MoY2xvbmUsIGNscyk7IH0pO1xuICAgICAgfVxuICAgICAgYWRkQ2xhc3MoY2xvbmUsIG1vdmVDbGFzcyk7XG4gICAgICBjbG9uZS5zdHlsZS5kaXNwbGF5ID0gJ25vbmUnO1xuICAgICAgdGhpcy4kZWwuYXBwZW5kQ2hpbGQoY2xvbmUpO1xuICAgICAgdmFyIGluZm8gPSBnZXRUcmFuc2l0aW9uSW5mbyhjbG9uZSk7XG4gICAgICB0aGlzLiRlbC5yZW1vdmVDaGlsZChjbG9uZSk7XG4gICAgICByZXR1cm4gKHRoaXMuX2hhc01vdmUgPSBpbmZvLmhhc1RyYW5zZm9ybSlcbiAgICB9XG4gIH1cbn07XG5cbmZ1bmN0aW9uIGNhbGxQZW5kaW5nQ2JzIChjKSB7XG4gIC8qIGlzdGFuYnVsIGlnbm9yZSBpZiAqL1xuICBpZiAoYy5lbG0uX21vdmVDYikge1xuICAgIGMuZWxtLl9tb3ZlQ2IoKTtcbiAgfVxuICAvKiBpc3RhbmJ1bCBpZ25vcmUgaWYgKi9cbiAgaWYgKGMuZWxtLl9lbnRlckNiKSB7XG4gICAgYy5lbG0uX2VudGVyQ2IoKTtcbiAgfVxufVxuXG5mdW5jdGlvbiByZWNvcmRQb3NpdGlvbiAoYykge1xuICBjLmRhdGEubmV3UG9zID0gYy5lbG0uZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XG59XG5cbmZ1bmN0aW9uIGFwcGx5VHJhbnNsYXRpb24gKGMpIHtcbiAgdmFyIG9sZFBvcyA9IGMuZGF0YS5wb3M7XG4gIHZhciBuZXdQb3MgPSBjLmRhdGEubmV3UG9zO1xuICB2YXIgZHggPSBvbGRQb3MubGVmdCAtIG5ld1Bvcy5sZWZ0O1xuICB2YXIgZHkgPSBvbGRQb3MudG9wIC0gbmV3UG9zLnRvcDtcbiAgaWYgKGR4IHx8IGR5KSB7XG4gICAgYy5kYXRhLm1vdmVkID0gdHJ1ZTtcbiAgICB2YXIgcyA9IGMuZWxtLnN0eWxlO1xuICAgIHMudHJhbnNmb3JtID0gcy5XZWJraXRUcmFuc2Zvcm0gPSBcInRyYW5zbGF0ZShcIiArIGR4ICsgXCJweCxcIiArIGR5ICsgXCJweClcIjtcbiAgICBzLnRyYW5zaXRpb25EdXJhdGlvbiA9ICcwcyc7XG4gIH1cbn1cblxudmFyIHBsYXRmb3JtQ29tcG9uZW50cyA9IHtcbiAgVHJhbnNpdGlvbjogVHJhbnNpdGlvbixcbiAgVHJhbnNpdGlvbkdyb3VwOiBUcmFuc2l0aW9uR3JvdXBcbn07XG5cbi8qICAqL1xuXG4vLyBpbnN0YWxsIHBsYXRmb3JtIHNwZWNpZmljIHV0aWxzXG5WdWUkMy5jb25maWcubXVzdFVzZVByb3AgPSBtdXN0VXNlUHJvcDtcblZ1ZSQzLmNvbmZpZy5pc1Jlc2VydmVkVGFnID0gaXNSZXNlcnZlZFRhZztcblZ1ZSQzLmNvbmZpZy5pc1Jlc2VydmVkQXR0ciA9IGlzUmVzZXJ2ZWRBdHRyO1xuVnVlJDMuY29uZmlnLmdldFRhZ05hbWVzcGFjZSA9IGdldFRhZ05hbWVzcGFjZTtcblZ1ZSQzLmNvbmZpZy5pc1Vua25vd25FbGVtZW50ID0gaXNVbmtub3duRWxlbWVudDtcblxuLy8gaW5zdGFsbCBwbGF0Zm9ybSBydW50aW1lIGRpcmVjdGl2ZXMgJiBjb21wb25lbnRzXG5leHRlbmQoVnVlJDMub3B0aW9ucy5kaXJlY3RpdmVzLCBwbGF0Zm9ybURpcmVjdGl2ZXMpO1xuZXh0ZW5kKFZ1ZSQzLm9wdGlvbnMuY29tcG9uZW50cywgcGxhdGZvcm1Db21wb25lbnRzKTtcblxuLy8gaW5zdGFsbCBwbGF0Zm9ybSBwYXRjaCBmdW5jdGlvblxuVnVlJDMucHJvdG90eXBlLl9fcGF0Y2hfXyA9IGluQnJvd3NlciA/IHBhdGNoIDogbm9vcDtcblxuLy8gcHVibGljIG1vdW50IG1ldGhvZFxuVnVlJDMucHJvdG90eXBlLiRtb3VudCA9IGZ1bmN0aW9uIChcbiAgZWwsXG4gIGh5ZHJhdGluZ1xuKSB7XG4gIGVsID0gZWwgJiYgaW5Ccm93c2VyID8gcXVlcnkoZWwpIDogdW5kZWZpbmVkO1xuICByZXR1cm4gbW91bnRDb21wb25lbnQodGhpcywgZWwsIGh5ZHJhdGluZylcbn07XG5cbi8vIGRldnRvb2xzIGdsb2JhbCBob29rXG4vKiBpc3RhbmJ1bCBpZ25vcmUgbmV4dCAqL1xuc2V0VGltZW91dChmdW5jdGlvbiAoKSB7XG4gIGlmIChjb25maWcuZGV2dG9vbHMpIHtcbiAgICBpZiAoZGV2dG9vbHMpIHtcbiAgICAgIGRldnRvb2xzLmVtaXQoJ2luaXQnLCBWdWUkMyk7XG4gICAgfSBlbHNlIGlmIChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nICYmIGlzQ2hyb21lKSB7XG4gICAgICBjb25zb2xlW2NvbnNvbGUuaW5mbyA/ICdpbmZvJyA6ICdsb2cnXShcbiAgICAgICAgJ0Rvd25sb2FkIHRoZSBWdWUgRGV2dG9vbHMgZXh0ZW5zaW9uIGZvciBhIGJldHRlciBkZXZlbG9wbWVudCBleHBlcmllbmNlOlxcbicgK1xuICAgICAgICAnaHR0cHM6Ly9naXRodWIuY29tL3Z1ZWpzL3Z1ZS1kZXZ0b29scydcbiAgICAgICk7XG4gICAgfVxuICB9XG4gIGlmIChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nICYmXG4gICAgY29uZmlnLnByb2R1Y3Rpb25UaXAgIT09IGZhbHNlICYmXG4gICAgaW5Ccm93c2VyICYmIHR5cGVvZiBjb25zb2xlICE9PSAndW5kZWZpbmVkJ1xuICApIHtcbiAgICBjb25zb2xlW2NvbnNvbGUuaW5mbyA/ICdpbmZvJyA6ICdsb2cnXShcbiAgICAgIFwiWW91IGFyZSBydW5uaW5nIFZ1ZSBpbiBkZXZlbG9wbWVudCBtb2RlLlxcblwiICtcbiAgICAgIFwiTWFrZSBzdXJlIHRvIHR1cm4gb24gcHJvZHVjdGlvbiBtb2RlIHdoZW4gZGVwbG95aW5nIGZvciBwcm9kdWN0aW9uLlxcblwiICtcbiAgICAgIFwiU2VlIG1vcmUgdGlwcyBhdCBodHRwczovL3Z1ZWpzLm9yZy9ndWlkZS9kZXBsb3ltZW50Lmh0bWxcIlxuICAgICk7XG4gIH1cbn0sIDApO1xuXG4vKiAgKi9cblxuLy8gY2hlY2sgd2hldGhlciBjdXJyZW50IGJyb3dzZXIgZW5jb2RlcyBhIGNoYXIgaW5zaWRlIGF0dHJpYnV0ZSB2YWx1ZXNcbmZ1bmN0aW9uIHNob3VsZERlY29kZSAoY29udGVudCwgZW5jb2RlZCkge1xuICB2YXIgZGl2ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XG4gIGRpdi5pbm5lckhUTUwgPSBcIjxkaXYgYT1cXFwiXCIgKyBjb250ZW50ICsgXCJcXFwiLz5cIjtcbiAgcmV0dXJuIGRpdi5pbm5lckhUTUwuaW5kZXhPZihlbmNvZGVkKSA+IDBcbn1cblxuLy8gIzM2NjNcbi8vIElFIGVuY29kZXMgbmV3bGluZXMgaW5zaWRlIGF0dHJpYnV0ZSB2YWx1ZXMgd2hpbGUgb3RoZXIgYnJvd3NlcnMgZG9uJ3RcbnZhciBzaG91bGREZWNvZGVOZXdsaW5lcyA9IGluQnJvd3NlciA/IHNob3VsZERlY29kZSgnXFxuJywgJyYjMTA7JykgOiBmYWxzZTtcblxuLyogICovXG5cbnZhciBkZWZhdWx0VGFnUkUgPSAvXFx7XFx7KCg/Oi58XFxuKSs/KVxcfVxcfS9nO1xudmFyIHJlZ2V4RXNjYXBlUkUgPSAvWy0uKis/XiR7fSgpfFtcXF1cXC9cXFxcXS9nO1xuXG52YXIgYnVpbGRSZWdleCA9IGNhY2hlZChmdW5jdGlvbiAoZGVsaW1pdGVycykge1xuICB2YXIgb3BlbiA9IGRlbGltaXRlcnNbMF0ucmVwbGFjZShyZWdleEVzY2FwZVJFLCAnXFxcXCQmJyk7XG4gIHZhciBjbG9zZSA9IGRlbGltaXRlcnNbMV0ucmVwbGFjZShyZWdleEVzY2FwZVJFLCAnXFxcXCQmJyk7XG4gIHJldHVybiBuZXcgUmVnRXhwKG9wZW4gKyAnKCg/Oi58XFxcXG4pKz8pJyArIGNsb3NlLCAnZycpXG59KTtcblxuZnVuY3Rpb24gcGFyc2VUZXh0IChcbiAgdGV4dCxcbiAgZGVsaW1pdGVyc1xuKSB7XG4gIHZhciB0YWdSRSA9IGRlbGltaXRlcnMgPyBidWlsZFJlZ2V4KGRlbGltaXRlcnMpIDogZGVmYXVsdFRhZ1JFO1xuICBpZiAoIXRhZ1JFLnRlc3QodGV4dCkpIHtcbiAgICByZXR1cm5cbiAgfVxuICB2YXIgdG9rZW5zID0gW107XG4gIHZhciBsYXN0SW5kZXggPSB0YWdSRS5sYXN0SW5kZXggPSAwO1xuICB2YXIgbWF0Y2gsIGluZGV4O1xuICB3aGlsZSAoKG1hdGNoID0gdGFnUkUuZXhlYyh0ZXh0KSkpIHtcbiAgICBpbmRleCA9IG1hdGNoLmluZGV4O1xuICAgIC8vIHB1c2ggdGV4dCB0b2tlblxuICAgIGlmIChpbmRleCA+IGxhc3RJbmRleCkge1xuICAgICAgdG9rZW5zLnB1c2goSlNPTi5zdHJpbmdpZnkodGV4dC5zbGljZShsYXN0SW5kZXgsIGluZGV4KSkpO1xuICAgIH1cbiAgICAvLyB0YWcgdG9rZW5cbiAgICB2YXIgZXhwID0gcGFyc2VGaWx0ZXJzKG1hdGNoWzFdLnRyaW0oKSk7XG4gICAgdG9rZW5zLnB1c2goKFwiX3MoXCIgKyBleHAgKyBcIilcIikpO1xuICAgIGxhc3RJbmRleCA9IGluZGV4ICsgbWF0Y2hbMF0ubGVuZ3RoO1xuICB9XG4gIGlmIChsYXN0SW5kZXggPCB0ZXh0Lmxlbmd0aCkge1xuICAgIHRva2Vucy5wdXNoKEpTT04uc3RyaW5naWZ5KHRleHQuc2xpY2UobGFzdEluZGV4KSkpO1xuICB9XG4gIHJldHVybiB0b2tlbnMuam9pbignKycpXG59XG5cbi8qICAqL1xuXG5mdW5jdGlvbiB0cmFuc2Zvcm1Ob2RlIChlbCwgb3B0aW9ucykge1xuICB2YXIgd2FybiA9IG9wdGlvbnMud2FybiB8fCBiYXNlV2FybjtcbiAgdmFyIHN0YXRpY0NsYXNzID0gZ2V0QW5kUmVtb3ZlQXR0cihlbCwgJ2NsYXNzJyk7XG4gIGlmIChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nICYmIHN0YXRpY0NsYXNzKSB7XG4gICAgdmFyIGV4cHJlc3Npb24gPSBwYXJzZVRleHQoc3RhdGljQ2xhc3MsIG9wdGlvbnMuZGVsaW1pdGVycyk7XG4gICAgaWYgKGV4cHJlc3Npb24pIHtcbiAgICAgIHdhcm4oXG4gICAgICAgIFwiY2xhc3M9XFxcIlwiICsgc3RhdGljQ2xhc3MgKyBcIlxcXCI6IFwiICtcbiAgICAgICAgJ0ludGVycG9sYXRpb24gaW5zaWRlIGF0dHJpYnV0ZXMgaGFzIGJlZW4gcmVtb3ZlZC4gJyArXG4gICAgICAgICdVc2Ugdi1iaW5kIG9yIHRoZSBjb2xvbiBzaG9ydGhhbmQgaW5zdGVhZC4gRm9yIGV4YW1wbGUsICcgK1xuICAgICAgICAnaW5zdGVhZCBvZiA8ZGl2IGNsYXNzPVwie3sgdmFsIH19XCI+LCB1c2UgPGRpdiA6Y2xhc3M9XCJ2YWxcIj4uJ1xuICAgICAgKTtcbiAgICB9XG4gIH1cbiAgaWYgKHN0YXRpY0NsYXNzKSB7XG4gICAgZWwuc3RhdGljQ2xhc3MgPSBKU09OLnN0cmluZ2lmeShzdGF0aWNDbGFzcyk7XG4gIH1cbiAgdmFyIGNsYXNzQmluZGluZyA9IGdldEJpbmRpbmdBdHRyKGVsLCAnY2xhc3MnLCBmYWxzZSAvKiBnZXRTdGF0aWMgKi8pO1xuICBpZiAoY2xhc3NCaW5kaW5nKSB7XG4gICAgZWwuY2xhc3NCaW5kaW5nID0gY2xhc3NCaW5kaW5nO1xuICB9XG59XG5cbmZ1bmN0aW9uIGdlbkRhdGEgKGVsKSB7XG4gIHZhciBkYXRhID0gJyc7XG4gIGlmIChlbC5zdGF0aWNDbGFzcykge1xuICAgIGRhdGEgKz0gXCJzdGF0aWNDbGFzczpcIiArIChlbC5zdGF0aWNDbGFzcykgKyBcIixcIjtcbiAgfVxuICBpZiAoZWwuY2xhc3NCaW5kaW5nKSB7XG4gICAgZGF0YSArPSBcImNsYXNzOlwiICsgKGVsLmNsYXNzQmluZGluZykgKyBcIixcIjtcbiAgfVxuICByZXR1cm4gZGF0YVxufVxuXG52YXIga2xhc3MkMSA9IHtcbiAgc3RhdGljS2V5czogWydzdGF0aWNDbGFzcyddLFxuICB0cmFuc2Zvcm1Ob2RlOiB0cmFuc2Zvcm1Ob2RlLFxuICBnZW5EYXRhOiBnZW5EYXRhXG59O1xuXG4vKiAgKi9cblxuZnVuY3Rpb24gdHJhbnNmb3JtTm9kZSQxIChlbCwgb3B0aW9ucykge1xuICB2YXIgd2FybiA9IG9wdGlvbnMud2FybiB8fCBiYXNlV2FybjtcbiAgdmFyIHN0YXRpY1N0eWxlID0gZ2V0QW5kUmVtb3ZlQXR0cihlbCwgJ3N0eWxlJyk7XG4gIGlmIChzdGF0aWNTdHlsZSkge1xuICAgIC8qIGlzdGFuYnVsIGlnbm9yZSBpZiAqL1xuICAgIGlmIChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nKSB7XG4gICAgICB2YXIgZXhwcmVzc2lvbiA9IHBhcnNlVGV4dChzdGF0aWNTdHlsZSwgb3B0aW9ucy5kZWxpbWl0ZXJzKTtcbiAgICAgIGlmIChleHByZXNzaW9uKSB7XG4gICAgICAgIHdhcm4oXG4gICAgICAgICAgXCJzdHlsZT1cXFwiXCIgKyBzdGF0aWNTdHlsZSArIFwiXFxcIjogXCIgK1xuICAgICAgICAgICdJbnRlcnBvbGF0aW9uIGluc2lkZSBhdHRyaWJ1dGVzIGhhcyBiZWVuIHJlbW92ZWQuICcgK1xuICAgICAgICAgICdVc2Ugdi1iaW5kIG9yIHRoZSBjb2xvbiBzaG9ydGhhbmQgaW5zdGVhZC4gRm9yIGV4YW1wbGUsICcgK1xuICAgICAgICAgICdpbnN0ZWFkIG9mIDxkaXYgc3R5bGU9XCJ7eyB2YWwgfX1cIj4sIHVzZSA8ZGl2IDpzdHlsZT1cInZhbFwiPi4nXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgfVxuICAgIGVsLnN0YXRpY1N0eWxlID0gSlNPTi5zdHJpbmdpZnkocGFyc2VTdHlsZVRleHQoc3RhdGljU3R5bGUpKTtcbiAgfVxuXG4gIHZhciBzdHlsZUJpbmRpbmcgPSBnZXRCaW5kaW5nQXR0cihlbCwgJ3N0eWxlJywgZmFsc2UgLyogZ2V0U3RhdGljICovKTtcbiAgaWYgKHN0eWxlQmluZGluZykge1xuICAgIGVsLnN0eWxlQmluZGluZyA9IHN0eWxlQmluZGluZztcbiAgfVxufVxuXG5mdW5jdGlvbiBnZW5EYXRhJDEgKGVsKSB7XG4gIHZhciBkYXRhID0gJyc7XG4gIGlmIChlbC5zdGF0aWNTdHlsZSkge1xuICAgIGRhdGEgKz0gXCJzdGF0aWNTdHlsZTpcIiArIChlbC5zdGF0aWNTdHlsZSkgKyBcIixcIjtcbiAgfVxuICBpZiAoZWwuc3R5bGVCaW5kaW5nKSB7XG4gICAgZGF0YSArPSBcInN0eWxlOihcIiArIChlbC5zdHlsZUJpbmRpbmcpICsgXCIpLFwiO1xuICB9XG4gIHJldHVybiBkYXRhXG59XG5cbnZhciBzdHlsZSQxID0ge1xuICBzdGF0aWNLZXlzOiBbJ3N0YXRpY1N0eWxlJ10sXG4gIHRyYW5zZm9ybU5vZGU6IHRyYW5zZm9ybU5vZGUkMSxcbiAgZ2VuRGF0YTogZ2VuRGF0YSQxXG59O1xuXG52YXIgbW9kdWxlcyQxID0gW1xuICBrbGFzcyQxLFxuICBzdHlsZSQxXG5dO1xuXG4vKiAgKi9cblxuZnVuY3Rpb24gdGV4dCAoZWwsIGRpcikge1xuICBpZiAoZGlyLnZhbHVlKSB7XG4gICAgYWRkUHJvcChlbCwgJ3RleHRDb250ZW50JywgKFwiX3MoXCIgKyAoZGlyLnZhbHVlKSArIFwiKVwiKSk7XG4gIH1cbn1cblxuLyogICovXG5cbmZ1bmN0aW9uIGh0bWwgKGVsLCBkaXIpIHtcbiAgaWYgKGRpci52YWx1ZSkge1xuICAgIGFkZFByb3AoZWwsICdpbm5lckhUTUwnLCAoXCJfcyhcIiArIChkaXIudmFsdWUpICsgXCIpXCIpKTtcbiAgfVxufVxuXG52YXIgZGlyZWN0aXZlcyQxID0ge1xuICBtb2RlbDogbW9kZWwsXG4gIHRleHQ6IHRleHQsXG4gIGh0bWw6IGh0bWxcbn07XG5cbi8qICAqL1xuXG52YXIgaXNVbmFyeVRhZyA9IG1ha2VNYXAoXG4gICdhcmVhLGJhc2UsYnIsY29sLGVtYmVkLGZyYW1lLGhyLGltZyxpbnB1dCxpc2luZGV4LGtleWdlbiwnICtcbiAgJ2xpbmssbWV0YSxwYXJhbSxzb3VyY2UsdHJhY2ssd2JyJ1xuKTtcblxuLy8gRWxlbWVudHMgdGhhdCB5b3UgY2FuLCBpbnRlbnRpb25hbGx5LCBsZWF2ZSBvcGVuXG4vLyAoYW5kIHdoaWNoIGNsb3NlIHRoZW1zZWx2ZXMpXG52YXIgY2FuQmVMZWZ0T3BlblRhZyA9IG1ha2VNYXAoXG4gICdjb2xncm91cCxkZCxkdCxsaSxvcHRpb25zLHAsdGQsdGZvb3QsdGgsdGhlYWQsdHIsc291cmNlJ1xuKTtcblxuLy8gSFRNTDUgdGFncyBodHRwczovL2h0bWwuc3BlYy53aGF0d2cub3JnL211bHRpcGFnZS9pbmRpY2VzLmh0bWwjZWxlbWVudHMtM1xuLy8gUGhyYXNpbmcgQ29udGVudCBodHRwczovL2h0bWwuc3BlYy53aGF0d2cub3JnL211bHRpcGFnZS9kb20uaHRtbCNwaHJhc2luZy1jb250ZW50XG52YXIgaXNOb25QaHJhc2luZ1RhZyA9IG1ha2VNYXAoXG4gICdhZGRyZXNzLGFydGljbGUsYXNpZGUsYmFzZSxibG9ja3F1b3RlLGJvZHksY2FwdGlvbixjb2wsY29sZ3JvdXAsZGQsJyArXG4gICdkZXRhaWxzLGRpYWxvZyxkaXYsZGwsZHQsZmllbGRzZXQsZmlnY2FwdGlvbixmaWd1cmUsZm9vdGVyLGZvcm0sJyArXG4gICdoMSxoMixoMyxoNCxoNSxoNixoZWFkLGhlYWRlcixoZ3JvdXAsaHIsaHRtbCxsZWdlbmQsbGksbWVudWl0ZW0sbWV0YSwnICtcbiAgJ29wdGdyb3VwLG9wdGlvbixwYXJhbSxycCxydCxzb3VyY2Usc3R5bGUsc3VtbWFyeSx0Ym9keSx0ZCx0Zm9vdCx0aCx0aGVhZCwnICtcbiAgJ3RpdGxlLHRyLHRyYWNrJ1xuKTtcblxuLyogICovXG5cbnZhciBiYXNlT3B0aW9ucyA9IHtcbiAgZXhwZWN0SFRNTDogdHJ1ZSxcbiAgbW9kdWxlczogbW9kdWxlcyQxLFxuICBkaXJlY3RpdmVzOiBkaXJlY3RpdmVzJDEsXG4gIGlzUHJlVGFnOiBpc1ByZVRhZyxcbiAgaXNVbmFyeVRhZzogaXNVbmFyeVRhZyxcbiAgbXVzdFVzZVByb3A6IG11c3RVc2VQcm9wLFxuICBjYW5CZUxlZnRPcGVuVGFnOiBjYW5CZUxlZnRPcGVuVGFnLFxuICBpc1Jlc2VydmVkVGFnOiBpc1Jlc2VydmVkVGFnLFxuICBnZXRUYWdOYW1lc3BhY2U6IGdldFRhZ05hbWVzcGFjZSxcbiAgc3RhdGljS2V5czogZ2VuU3RhdGljS2V5cyhtb2R1bGVzJDEpXG59O1xuXG4vKiAgKi9cblxudmFyIGRlY29kZXI7XG5cbnZhciBoZSA9IHtcbiAgZGVjb2RlOiBmdW5jdGlvbiBkZWNvZGUgKGh0bWwpIHtcbiAgICBkZWNvZGVyID0gZGVjb2RlciB8fCBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcbiAgICBkZWNvZGVyLmlubmVySFRNTCA9IGh0bWw7XG4gICAgcmV0dXJuIGRlY29kZXIudGV4dENvbnRlbnRcbiAgfVxufTtcblxuLyoqXG4gKiBOb3QgdHlwZS1jaGVja2luZyB0aGlzIGZpbGUgYmVjYXVzZSBpdCdzIG1vc3RseSB2ZW5kb3IgY29kZS5cbiAqL1xuXG4vKiFcbiAqIEhUTUwgUGFyc2VyIEJ5IEpvaG4gUmVzaWcgKGVqb2huLm9yZylcbiAqIE1vZGlmaWVkIGJ5IEp1cml5IFwia2FuZ2F4XCIgWmF5dHNldlxuICogT3JpZ2luYWwgY29kZSBieSBFcmlrIEFydmlkc3NvbiwgTW96aWxsYSBQdWJsaWMgTGljZW5zZVxuICogaHR0cDovL2VyaWsuZWFlLm5ldC9zaW1wbGVodG1scGFyc2VyL3NpbXBsZWh0bWxwYXJzZXIuanNcbiAqL1xuXG4vLyBSZWd1bGFyIEV4cHJlc3Npb25zIGZvciBwYXJzaW5nIHRhZ3MgYW5kIGF0dHJpYnV0ZXNcbnZhciBhdHRyaWJ1dGUgPSAvXlxccyooW15cXHNcIic8PlxcLz1dKykoPzpcXHMqKD0pXFxzKig/OlwiKFteXCJdKilcIit8JyhbXiddKiknK3woW15cXHNcIic9PD5gXSspKSk/Lztcbi8vIGNvdWxkIHVzZSBodHRwczovL3d3dy53My5vcmcvVFIvMTk5OS9SRUMteG1sLW5hbWVzLTE5OTkwMTE0LyNOVC1RTmFtZVxuLy8gYnV0IGZvciBWdWUgdGVtcGxhdGVzIHdlIGNhbiBlbmZvcmNlIGEgc2ltcGxlIGNoYXJzZXRcbnZhciBuY25hbWUgPSAnW2EtekEtWl9dW1xcXFx3XFxcXC1cXFxcLl0qJztcbnZhciBxbmFtZUNhcHR1cmUgPSBcIigoPzpcIiArIG5jbmFtZSArIFwiXFxcXDopP1wiICsgbmNuYW1lICsgXCIpXCI7XG52YXIgc3RhcnRUYWdPcGVuID0gbmV3IFJlZ0V4cCgoXCJePFwiICsgcW5hbWVDYXB0dXJlKSk7XG52YXIgc3RhcnRUYWdDbG9zZSA9IC9eXFxzKihcXC8/KT4vO1xudmFyIGVuZFRhZyA9IG5ldyBSZWdFeHAoKFwiXjxcXFxcL1wiICsgcW5hbWVDYXB0dXJlICsgXCJbXj5dKj5cIikpO1xudmFyIGRvY3R5cGUgPSAvXjwhRE9DVFlQRSBbXj5dKz4vaTtcbnZhciBjb21tZW50ID0gL148IS0tLztcbnZhciBjb25kaXRpb25hbENvbW1lbnQgPSAvXjwhXFxbLztcblxudmFyIElTX1JFR0VYX0NBUFRVUklOR19CUk9LRU4gPSBmYWxzZTtcbid4Jy5yZXBsYWNlKC94KC4pPy9nLCBmdW5jdGlvbiAobSwgZykge1xuICBJU19SRUdFWF9DQVBUVVJJTkdfQlJPS0VOID0gZyA9PT0gJyc7XG59KTtcblxuLy8gU3BlY2lhbCBFbGVtZW50cyAoY2FuIGNvbnRhaW4gYW55dGhpbmcpXG52YXIgaXNQbGFpblRleHRFbGVtZW50ID0gbWFrZU1hcCgnc2NyaXB0LHN0eWxlLHRleHRhcmVhJywgdHJ1ZSk7XG52YXIgcmVDYWNoZSA9IHt9O1xuXG52YXIgZGVjb2RpbmdNYXAgPSB7XG4gICcmbHQ7JzogJzwnLFxuICAnJmd0Oyc6ICc+JyxcbiAgJyZxdW90Oyc6ICdcIicsXG4gICcmYW1wOyc6ICcmJyxcbiAgJyYjMTA7JzogJ1xcbidcbn07XG52YXIgZW5jb2RlZEF0dHIgPSAvJig/Omx0fGd0fHF1b3R8YW1wKTsvZztcbnZhciBlbmNvZGVkQXR0cldpdGhOZXdMaW5lcyA9IC8mKD86bHR8Z3R8cXVvdHxhbXB8IzEwKTsvZztcblxuLy8gIzU5OTJcbnZhciBpc0lnbm9yZU5ld2xpbmVUYWcgPSBtYWtlTWFwKCdwcmUsdGV4dGFyZWEnLCB0cnVlKTtcbnZhciBzaG91bGRJZ25vcmVGaXJzdE5ld2xpbmUgPSBmdW5jdGlvbiAodGFnLCBodG1sKSB7IHJldHVybiB0YWcgJiYgaXNJZ25vcmVOZXdsaW5lVGFnKHRhZykgJiYgaHRtbFswXSA9PT0gJ1xcbic7IH07XG5cbmZ1bmN0aW9uIGRlY29kZUF0dHIgKHZhbHVlLCBzaG91bGREZWNvZGVOZXdsaW5lcykge1xuICB2YXIgcmUgPSBzaG91bGREZWNvZGVOZXdsaW5lcyA/IGVuY29kZWRBdHRyV2l0aE5ld0xpbmVzIDogZW5jb2RlZEF0dHI7XG4gIHJldHVybiB2YWx1ZS5yZXBsYWNlKHJlLCBmdW5jdGlvbiAobWF0Y2gpIHsgcmV0dXJuIGRlY29kaW5nTWFwW21hdGNoXTsgfSlcbn1cblxuZnVuY3Rpb24gcGFyc2VIVE1MIChodG1sLCBvcHRpb25zKSB7XG4gIHZhciBzdGFjayA9IFtdO1xuICB2YXIgZXhwZWN0SFRNTCA9IG9wdGlvbnMuZXhwZWN0SFRNTDtcbiAgdmFyIGlzVW5hcnlUYWckJDEgPSBvcHRpb25zLmlzVW5hcnlUYWcgfHwgbm87XG4gIHZhciBjYW5CZUxlZnRPcGVuVGFnJCQxID0gb3B0aW9ucy5jYW5CZUxlZnRPcGVuVGFnIHx8IG5vO1xuICB2YXIgaW5kZXggPSAwO1xuICB2YXIgbGFzdCwgbGFzdFRhZztcbiAgd2hpbGUgKGh0bWwpIHtcbiAgICBsYXN0ID0gaHRtbDtcbiAgICAvLyBNYWtlIHN1cmUgd2UncmUgbm90IGluIGEgcGxhaW50ZXh0IGNvbnRlbnQgZWxlbWVudCBsaWtlIHNjcmlwdC9zdHlsZVxuICAgIGlmICghbGFzdFRhZyB8fCAhaXNQbGFpblRleHRFbGVtZW50KGxhc3RUYWcpKSB7XG4gICAgICB2YXIgdGV4dEVuZCA9IGh0bWwuaW5kZXhPZignPCcpO1xuICAgICAgaWYgKHRleHRFbmQgPT09IDApIHtcbiAgICAgICAgLy8gQ29tbWVudDpcbiAgICAgICAgaWYgKGNvbW1lbnQudGVzdChodG1sKSkge1xuICAgICAgICAgIHZhciBjb21tZW50RW5kID0gaHRtbC5pbmRleE9mKCctLT4nKTtcblxuICAgICAgICAgIGlmIChjb21tZW50RW5kID49IDApIHtcbiAgICAgICAgICAgIGlmIChvcHRpb25zLnNob3VsZEtlZXBDb21tZW50KSB7XG4gICAgICAgICAgICAgIG9wdGlvbnMuY29tbWVudChodG1sLnN1YnN0cmluZyg0LCBjb21tZW50RW5kKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBhZHZhbmNlKGNvbW1lbnRFbmQgKyAzKTtcbiAgICAgICAgICAgIGNvbnRpbnVlXG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgLy8gaHR0cDovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9Db25kaXRpb25hbF9jb21tZW50I0Rvd25sZXZlbC1yZXZlYWxlZF9jb25kaXRpb25hbF9jb21tZW50XG4gICAgICAgIGlmIChjb25kaXRpb25hbENvbW1lbnQudGVzdChodG1sKSkge1xuICAgICAgICAgIHZhciBjb25kaXRpb25hbEVuZCA9IGh0bWwuaW5kZXhPZignXT4nKTtcblxuICAgICAgICAgIGlmIChjb25kaXRpb25hbEVuZCA+PSAwKSB7XG4gICAgICAgICAgICBhZHZhbmNlKGNvbmRpdGlvbmFsRW5kICsgMik7XG4gICAgICAgICAgICBjb250aW51ZVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIC8vIERvY3R5cGU6XG4gICAgICAgIHZhciBkb2N0eXBlTWF0Y2ggPSBodG1sLm1hdGNoKGRvY3R5cGUpO1xuICAgICAgICBpZiAoZG9jdHlwZU1hdGNoKSB7XG4gICAgICAgICAgYWR2YW5jZShkb2N0eXBlTWF0Y2hbMF0ubGVuZ3RoKTtcbiAgICAgICAgICBjb250aW51ZVxuICAgICAgICB9XG5cbiAgICAgICAgLy8gRW5kIHRhZzpcbiAgICAgICAgdmFyIGVuZFRhZ01hdGNoID0gaHRtbC5tYXRjaChlbmRUYWcpO1xuICAgICAgICBpZiAoZW5kVGFnTWF0Y2gpIHtcbiAgICAgICAgICB2YXIgY3VySW5kZXggPSBpbmRleDtcbiAgICAgICAgICBhZHZhbmNlKGVuZFRhZ01hdGNoWzBdLmxlbmd0aCk7XG4gICAgICAgICAgcGFyc2VFbmRUYWcoZW5kVGFnTWF0Y2hbMV0sIGN1ckluZGV4LCBpbmRleCk7XG4gICAgICAgICAgY29udGludWVcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIFN0YXJ0IHRhZzpcbiAgICAgICAgdmFyIHN0YXJ0VGFnTWF0Y2ggPSBwYXJzZVN0YXJ0VGFnKCk7XG4gICAgICAgIGlmIChzdGFydFRhZ01hdGNoKSB7XG4gICAgICAgICAgaGFuZGxlU3RhcnRUYWcoc3RhcnRUYWdNYXRjaCk7XG4gICAgICAgICAgaWYgKHNob3VsZElnbm9yZUZpcnN0TmV3bGluZShsYXN0VGFnLCBodG1sKSkge1xuICAgICAgICAgICAgYWR2YW5jZSgxKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgY29udGludWVcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICB2YXIgdGV4dCA9ICh2b2lkIDApLCByZXN0ID0gKHZvaWQgMCksIG5leHQgPSAodm9pZCAwKTtcbiAgICAgIGlmICh0ZXh0RW5kID49IDApIHtcbiAgICAgICAgcmVzdCA9IGh0bWwuc2xpY2UodGV4dEVuZCk7XG4gICAgICAgIHdoaWxlIChcbiAgICAgICAgICAhZW5kVGFnLnRlc3QocmVzdCkgJiZcbiAgICAgICAgICAhc3RhcnRUYWdPcGVuLnRlc3QocmVzdCkgJiZcbiAgICAgICAgICAhY29tbWVudC50ZXN0KHJlc3QpICYmXG4gICAgICAgICAgIWNvbmRpdGlvbmFsQ29tbWVudC50ZXN0KHJlc3QpXG4gICAgICAgICkge1xuICAgICAgICAgIC8vIDwgaW4gcGxhaW4gdGV4dCwgYmUgZm9yZ2l2aW5nIGFuZCB0cmVhdCBpdCBhcyB0ZXh0XG4gICAgICAgICAgbmV4dCA9IHJlc3QuaW5kZXhPZignPCcsIDEpO1xuICAgICAgICAgIGlmIChuZXh0IDwgMCkgeyBicmVhayB9XG4gICAgICAgICAgdGV4dEVuZCArPSBuZXh0O1xuICAgICAgICAgIHJlc3QgPSBodG1sLnNsaWNlKHRleHRFbmQpO1xuICAgICAgICB9XG4gICAgICAgIHRleHQgPSBodG1sLnN1YnN0cmluZygwLCB0ZXh0RW5kKTtcbiAgICAgICAgYWR2YW5jZSh0ZXh0RW5kKTtcbiAgICAgIH1cblxuICAgICAgaWYgKHRleHRFbmQgPCAwKSB7XG4gICAgICAgIHRleHQgPSBodG1sO1xuICAgICAgICBodG1sID0gJyc7XG4gICAgICB9XG5cbiAgICAgIGlmIChvcHRpb25zLmNoYXJzICYmIHRleHQpIHtcbiAgICAgICAgb3B0aW9ucy5jaGFycyh0ZXh0KTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgdmFyIGVuZFRhZ0xlbmd0aCA9IDA7XG4gICAgICB2YXIgc3RhY2tlZFRhZyA9IGxhc3RUYWcudG9Mb3dlckNhc2UoKTtcbiAgICAgIHZhciByZVN0YWNrZWRUYWcgPSByZUNhY2hlW3N0YWNrZWRUYWddIHx8IChyZUNhY2hlW3N0YWNrZWRUYWddID0gbmV3IFJlZ0V4cCgnKFtcXFxcc1xcXFxTXSo/KSg8LycgKyBzdGFja2VkVGFnICsgJ1tePl0qPiknLCAnaScpKTtcbiAgICAgIHZhciByZXN0JDEgPSBodG1sLnJlcGxhY2UocmVTdGFja2VkVGFnLCBmdW5jdGlvbiAoYWxsLCB0ZXh0LCBlbmRUYWcpIHtcbiAgICAgICAgZW5kVGFnTGVuZ3RoID0gZW5kVGFnLmxlbmd0aDtcbiAgICAgICAgaWYgKCFpc1BsYWluVGV4dEVsZW1lbnQoc3RhY2tlZFRhZykgJiYgc3RhY2tlZFRhZyAhPT0gJ25vc2NyaXB0Jykge1xuICAgICAgICAgIHRleHQgPSB0ZXh0XG4gICAgICAgICAgICAucmVwbGFjZSgvPCEtLShbXFxzXFxTXSo/KS0tPi9nLCAnJDEnKVxuICAgICAgICAgICAgLnJlcGxhY2UoLzwhXFxbQ0RBVEFcXFsoW1xcc1xcU10qPyldXT4vZywgJyQxJyk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHNob3VsZElnbm9yZUZpcnN0TmV3bGluZShzdGFja2VkVGFnLCB0ZXh0KSkge1xuICAgICAgICAgIHRleHQgPSB0ZXh0LnNsaWNlKDEpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChvcHRpb25zLmNoYXJzKSB7XG4gICAgICAgICAgb3B0aW9ucy5jaGFycyh0ZXh0KTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gJydcbiAgICAgIH0pO1xuICAgICAgaW5kZXggKz0gaHRtbC5sZW5ndGggLSByZXN0JDEubGVuZ3RoO1xuICAgICAgaHRtbCA9IHJlc3QkMTtcbiAgICAgIHBhcnNlRW5kVGFnKHN0YWNrZWRUYWcsIGluZGV4IC0gZW5kVGFnTGVuZ3RoLCBpbmRleCk7XG4gICAgfVxuXG4gICAgaWYgKGh0bWwgPT09IGxhc3QpIHtcbiAgICAgIG9wdGlvbnMuY2hhcnMgJiYgb3B0aW9ucy5jaGFycyhodG1sKTtcbiAgICAgIGlmIChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nICYmICFzdGFjay5sZW5ndGggJiYgb3B0aW9ucy53YXJuKSB7XG4gICAgICAgIG9wdGlvbnMud2FybigoXCJNYWwtZm9ybWF0dGVkIHRhZyBhdCBlbmQgb2YgdGVtcGxhdGU6IFxcXCJcIiArIGh0bWwgKyBcIlxcXCJcIikpO1xuICAgICAgfVxuICAgICAgYnJlYWtcbiAgICB9XG4gIH1cblxuICAvLyBDbGVhbiB1cCBhbnkgcmVtYWluaW5nIHRhZ3NcbiAgcGFyc2VFbmRUYWcoKTtcblxuICBmdW5jdGlvbiBhZHZhbmNlIChuKSB7XG4gICAgaW5kZXggKz0gbjtcbiAgICBodG1sID0gaHRtbC5zdWJzdHJpbmcobik7XG4gIH1cblxuICBmdW5jdGlvbiBwYXJzZVN0YXJ0VGFnICgpIHtcbiAgICB2YXIgc3RhcnQgPSBodG1sLm1hdGNoKHN0YXJ0VGFnT3Blbik7XG4gICAgaWYgKHN0YXJ0KSB7XG4gICAgICB2YXIgbWF0Y2ggPSB7XG4gICAgICAgIHRhZ05hbWU6IHN0YXJ0WzFdLFxuICAgICAgICBhdHRyczogW10sXG4gICAgICAgIHN0YXJ0OiBpbmRleFxuICAgICAgfTtcbiAgICAgIGFkdmFuY2Uoc3RhcnRbMF0ubGVuZ3RoKTtcbiAgICAgIHZhciBlbmQsIGF0dHI7XG4gICAgICB3aGlsZSAoIShlbmQgPSBodG1sLm1hdGNoKHN0YXJ0VGFnQ2xvc2UpKSAmJiAoYXR0ciA9IGh0bWwubWF0Y2goYXR0cmlidXRlKSkpIHtcbiAgICAgICAgYWR2YW5jZShhdHRyWzBdLmxlbmd0aCk7XG4gICAgICAgIG1hdGNoLmF0dHJzLnB1c2goYXR0cik7XG4gICAgICB9XG4gICAgICBpZiAoZW5kKSB7XG4gICAgICAgIG1hdGNoLnVuYXJ5U2xhc2ggPSBlbmRbMV07XG4gICAgICAgIGFkdmFuY2UoZW5kWzBdLmxlbmd0aCk7XG4gICAgICAgIG1hdGNoLmVuZCA9IGluZGV4O1xuICAgICAgICByZXR1cm4gbWF0Y2hcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBmdW5jdGlvbiBoYW5kbGVTdGFydFRhZyAobWF0Y2gpIHtcbiAgICB2YXIgdGFnTmFtZSA9IG1hdGNoLnRhZ05hbWU7XG4gICAgdmFyIHVuYXJ5U2xhc2ggPSBtYXRjaC51bmFyeVNsYXNoO1xuXG4gICAgaWYgKGV4cGVjdEhUTUwpIHtcbiAgICAgIGlmIChsYXN0VGFnID09PSAncCcgJiYgaXNOb25QaHJhc2luZ1RhZyh0YWdOYW1lKSkge1xuICAgICAgICBwYXJzZUVuZFRhZyhsYXN0VGFnKTtcbiAgICAgIH1cbiAgICAgIGlmIChjYW5CZUxlZnRPcGVuVGFnJCQxKHRhZ05hbWUpICYmIGxhc3RUYWcgPT09IHRhZ05hbWUpIHtcbiAgICAgICAgcGFyc2VFbmRUYWcodGFnTmFtZSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgdmFyIHVuYXJ5ID0gaXNVbmFyeVRhZyQkMSh0YWdOYW1lKSB8fCAhIXVuYXJ5U2xhc2g7XG5cbiAgICB2YXIgbCA9IG1hdGNoLmF0dHJzLmxlbmd0aDtcbiAgICB2YXIgYXR0cnMgPSBuZXcgQXJyYXkobCk7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBsOyBpKyspIHtcbiAgICAgIHZhciBhcmdzID0gbWF0Y2guYXR0cnNbaV07XG4gICAgICAvLyBoYWNraXNoIHdvcmsgYXJvdW5kIEZGIGJ1ZyBodHRwczovL2J1Z3ppbGxhLm1vemlsbGEub3JnL3Nob3dfYnVnLmNnaT9pZD0zNjk3NzhcbiAgICAgIGlmIChJU19SRUdFWF9DQVBUVVJJTkdfQlJPS0VOICYmIGFyZ3NbMF0uaW5kZXhPZignXCJcIicpID09PSAtMSkge1xuICAgICAgICBpZiAoYXJnc1szXSA9PT0gJycpIHsgZGVsZXRlIGFyZ3NbM107IH1cbiAgICAgICAgaWYgKGFyZ3NbNF0gPT09ICcnKSB7IGRlbGV0ZSBhcmdzWzRdOyB9XG4gICAgICAgIGlmIChhcmdzWzVdID09PSAnJykgeyBkZWxldGUgYXJnc1s1XTsgfVxuICAgICAgfVxuICAgICAgdmFyIHZhbHVlID0gYXJnc1szXSB8fCBhcmdzWzRdIHx8IGFyZ3NbNV0gfHwgJyc7XG4gICAgICBhdHRyc1tpXSA9IHtcbiAgICAgICAgbmFtZTogYXJnc1sxXSxcbiAgICAgICAgdmFsdWU6IGRlY29kZUF0dHIoXG4gICAgICAgICAgdmFsdWUsXG4gICAgICAgICAgb3B0aW9ucy5zaG91bGREZWNvZGVOZXdsaW5lc1xuICAgICAgICApXG4gICAgICB9O1xuICAgIH1cblxuICAgIGlmICghdW5hcnkpIHtcbiAgICAgIHN0YWNrLnB1c2goeyB0YWc6IHRhZ05hbWUsIGxvd2VyQ2FzZWRUYWc6IHRhZ05hbWUudG9Mb3dlckNhc2UoKSwgYXR0cnM6IGF0dHJzIH0pO1xuICAgICAgbGFzdFRhZyA9IHRhZ05hbWU7XG4gICAgfVxuXG4gICAgaWYgKG9wdGlvbnMuc3RhcnQpIHtcbiAgICAgIG9wdGlvbnMuc3RhcnQodGFnTmFtZSwgYXR0cnMsIHVuYXJ5LCBtYXRjaC5zdGFydCwgbWF0Y2guZW5kKTtcbiAgICB9XG4gIH1cblxuICBmdW5jdGlvbiBwYXJzZUVuZFRhZyAodGFnTmFtZSwgc3RhcnQsIGVuZCkge1xuICAgIHZhciBwb3MsIGxvd2VyQ2FzZWRUYWdOYW1lO1xuICAgIGlmIChzdGFydCA9PSBudWxsKSB7IHN0YXJ0ID0gaW5kZXg7IH1cbiAgICBpZiAoZW5kID09IG51bGwpIHsgZW5kID0gaW5kZXg7IH1cblxuICAgIGlmICh0YWdOYW1lKSB7XG4gICAgICBsb3dlckNhc2VkVGFnTmFtZSA9IHRhZ05hbWUudG9Mb3dlckNhc2UoKTtcbiAgICB9XG5cbiAgICAvLyBGaW5kIHRoZSBjbG9zZXN0IG9wZW5lZCB0YWcgb2YgdGhlIHNhbWUgdHlwZVxuICAgIGlmICh0YWdOYW1lKSB7XG4gICAgICBmb3IgKHBvcyA9IHN0YWNrLmxlbmd0aCAtIDE7IHBvcyA+PSAwOyBwb3MtLSkge1xuICAgICAgICBpZiAoc3RhY2tbcG9zXS5sb3dlckNhc2VkVGFnID09PSBsb3dlckNhc2VkVGFnTmFtZSkge1xuICAgICAgICAgIGJyZWFrXG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgLy8gSWYgbm8gdGFnIG5hbWUgaXMgcHJvdmlkZWQsIGNsZWFuIHNob3BcbiAgICAgIHBvcyA9IDA7XG4gICAgfVxuXG4gICAgaWYgKHBvcyA+PSAwKSB7XG4gICAgICAvLyBDbG9zZSBhbGwgdGhlIG9wZW4gZWxlbWVudHMsIHVwIHRoZSBzdGFja1xuICAgICAgZm9yICh2YXIgaSA9IHN0YWNrLmxlbmd0aCAtIDE7IGkgPj0gcG9zOyBpLS0pIHtcbiAgICAgICAgaWYgKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicgJiZcbiAgICAgICAgICAoaSA+IHBvcyB8fCAhdGFnTmFtZSkgJiZcbiAgICAgICAgICBvcHRpb25zLndhcm5cbiAgICAgICAgKSB7XG4gICAgICAgICAgb3B0aW9ucy53YXJuKFxuICAgICAgICAgICAgKFwidGFnIDxcIiArIChzdGFja1tpXS50YWcpICsgXCI+IGhhcyBubyBtYXRjaGluZyBlbmQgdGFnLlwiKVxuICAgICAgICAgICk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKG9wdGlvbnMuZW5kKSB7XG4gICAgICAgICAgb3B0aW9ucy5lbmQoc3RhY2tbaV0udGFnLCBzdGFydCwgZW5kKTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICAvLyBSZW1vdmUgdGhlIG9wZW4gZWxlbWVudHMgZnJvbSB0aGUgc3RhY2tcbiAgICAgIHN0YWNrLmxlbmd0aCA9IHBvcztcbiAgICAgIGxhc3RUYWcgPSBwb3MgJiYgc3RhY2tbcG9zIC0gMV0udGFnO1xuICAgIH0gZWxzZSBpZiAobG93ZXJDYXNlZFRhZ05hbWUgPT09ICdicicpIHtcbiAgICAgIGlmIChvcHRpb25zLnN0YXJ0KSB7XG4gICAgICAgIG9wdGlvbnMuc3RhcnQodGFnTmFtZSwgW10sIHRydWUsIHN0YXJ0LCBlbmQpO1xuICAgICAgfVxuICAgIH0gZWxzZSBpZiAobG93ZXJDYXNlZFRhZ05hbWUgPT09ICdwJykge1xuICAgICAgaWYgKG9wdGlvbnMuc3RhcnQpIHtcbiAgICAgICAgb3B0aW9ucy5zdGFydCh0YWdOYW1lLCBbXSwgZmFsc2UsIHN0YXJ0LCBlbmQpO1xuICAgICAgfVxuICAgICAgaWYgKG9wdGlvbnMuZW5kKSB7XG4gICAgICAgIG9wdGlvbnMuZW5kKHRhZ05hbWUsIHN0YXJ0LCBlbmQpO1xuICAgICAgfVxuICAgIH1cbiAgfVxufVxuXG4vKiAgKi9cblxudmFyIG9uUkUgPSAvXkB8XnYtb246LztcbnZhciBkaXJSRSA9IC9edi18XkB8XjovO1xudmFyIGZvckFsaWFzUkUgPSAvKC4qPylcXHMrKD86aW58b2YpXFxzKyguKikvO1xudmFyIGZvckl0ZXJhdG9yUkUgPSAvXFwoKFxce1tefV0qXFx9fFteLF0qKSwoW14sXSopKD86LChbXixdKikpP1xcKS87XG5cbnZhciBhcmdSRSA9IC86KC4qKSQvO1xudmFyIGJpbmRSRSA9IC9eOnxedi1iaW5kOi87XG52YXIgbW9kaWZpZXJSRSA9IC9cXC5bXi5dKy9nO1xuXG52YXIgZGVjb2RlSFRNTENhY2hlZCA9IGNhY2hlZChoZS5kZWNvZGUpO1xuXG4vLyBjb25maWd1cmFibGUgc3RhdGVcbnZhciB3YXJuJDI7XG52YXIgZGVsaW1pdGVycztcbnZhciB0cmFuc2Zvcm1zO1xudmFyIHByZVRyYW5zZm9ybXM7XG52YXIgcG9zdFRyYW5zZm9ybXM7XG52YXIgcGxhdGZvcm1Jc1ByZVRhZztcbnZhciBwbGF0Zm9ybU11c3RVc2VQcm9wO1xudmFyIHBsYXRmb3JtR2V0VGFnTmFtZXNwYWNlO1xuXG4vKipcbiAqIENvbnZlcnQgSFRNTCBzdHJpbmcgdG8gQVNULlxuICovXG5mdW5jdGlvbiBwYXJzZSAoXG4gIHRlbXBsYXRlLFxuICBvcHRpb25zXG4pIHtcbiAgd2FybiQyID0gb3B0aW9ucy53YXJuIHx8IGJhc2VXYXJuO1xuXG4gIHBsYXRmb3JtSXNQcmVUYWcgPSBvcHRpb25zLmlzUHJlVGFnIHx8IG5vO1xuICBwbGF0Zm9ybU11c3RVc2VQcm9wID0gb3B0aW9ucy5tdXN0VXNlUHJvcCB8fCBubztcbiAgcGxhdGZvcm1HZXRUYWdOYW1lc3BhY2UgPSBvcHRpb25zLmdldFRhZ05hbWVzcGFjZSB8fCBubztcblxuICB0cmFuc2Zvcm1zID0gcGx1Y2tNb2R1bGVGdW5jdGlvbihvcHRpb25zLm1vZHVsZXMsICd0cmFuc2Zvcm1Ob2RlJyk7XG4gIHByZVRyYW5zZm9ybXMgPSBwbHVja01vZHVsZUZ1bmN0aW9uKG9wdGlvbnMubW9kdWxlcywgJ3ByZVRyYW5zZm9ybU5vZGUnKTtcbiAgcG9zdFRyYW5zZm9ybXMgPSBwbHVja01vZHVsZUZ1bmN0aW9uKG9wdGlvbnMubW9kdWxlcywgJ3Bvc3RUcmFuc2Zvcm1Ob2RlJyk7XG5cbiAgZGVsaW1pdGVycyA9IG9wdGlvbnMuZGVsaW1pdGVycztcblxuICB2YXIgc3RhY2sgPSBbXTtcbiAgdmFyIHByZXNlcnZlV2hpdGVzcGFjZSA9IG9wdGlvbnMucHJlc2VydmVXaGl0ZXNwYWNlICE9PSBmYWxzZTtcbiAgdmFyIHJvb3Q7XG4gIHZhciBjdXJyZW50UGFyZW50O1xuICB2YXIgaW5WUHJlID0gZmFsc2U7XG4gIHZhciBpblByZSA9IGZhbHNlO1xuICB2YXIgd2FybmVkID0gZmFsc2U7XG5cbiAgZnVuY3Rpb24gd2Fybk9uY2UgKG1zZykge1xuICAgIGlmICghd2FybmVkKSB7XG4gICAgICB3YXJuZWQgPSB0cnVlO1xuICAgICAgd2FybiQyKG1zZyk7XG4gICAgfVxuICB9XG5cbiAgZnVuY3Rpb24gZW5kUHJlIChlbGVtZW50KSB7XG4gICAgLy8gY2hlY2sgcHJlIHN0YXRlXG4gICAgaWYgKGVsZW1lbnQucHJlKSB7XG4gICAgICBpblZQcmUgPSBmYWxzZTtcbiAgICB9XG4gICAgaWYgKHBsYXRmb3JtSXNQcmVUYWcoZWxlbWVudC50YWcpKSB7XG4gICAgICBpblByZSA9IGZhbHNlO1xuICAgIH1cbiAgfVxuXG4gIHBhcnNlSFRNTCh0ZW1wbGF0ZSwge1xuICAgIHdhcm46IHdhcm4kMixcbiAgICBleHBlY3RIVE1MOiBvcHRpb25zLmV4cGVjdEhUTUwsXG4gICAgaXNVbmFyeVRhZzogb3B0aW9ucy5pc1VuYXJ5VGFnLFxuICAgIGNhbkJlTGVmdE9wZW5UYWc6IG9wdGlvbnMuY2FuQmVMZWZ0T3BlblRhZyxcbiAgICBzaG91bGREZWNvZGVOZXdsaW5lczogb3B0aW9ucy5zaG91bGREZWNvZGVOZXdsaW5lcyxcbiAgICBzaG91bGRLZWVwQ29tbWVudDogb3B0aW9ucy5jb21tZW50cyxcbiAgICBzdGFydDogZnVuY3Rpb24gc3RhcnQgKHRhZywgYXR0cnMsIHVuYXJ5KSB7XG4gICAgICAvLyBjaGVjayBuYW1lc3BhY2UuXG4gICAgICAvLyBpbmhlcml0IHBhcmVudCBucyBpZiB0aGVyZSBpcyBvbmVcbiAgICAgIHZhciBucyA9IChjdXJyZW50UGFyZW50ICYmIGN1cnJlbnRQYXJlbnQubnMpIHx8IHBsYXRmb3JtR2V0VGFnTmFtZXNwYWNlKHRhZyk7XG5cbiAgICAgIC8vIGhhbmRsZSBJRSBzdmcgYnVnXG4gICAgICAvKiBpc3RhbmJ1bCBpZ25vcmUgaWYgKi9cbiAgICAgIGlmIChpc0lFICYmIG5zID09PSAnc3ZnJykge1xuICAgICAgICBhdHRycyA9IGd1YXJkSUVTVkdCdWcoYXR0cnMpO1xuICAgICAgfVxuXG4gICAgICB2YXIgZWxlbWVudCA9IHtcbiAgICAgICAgdHlwZTogMSxcbiAgICAgICAgdGFnOiB0YWcsXG4gICAgICAgIGF0dHJzTGlzdDogYXR0cnMsXG4gICAgICAgIGF0dHJzTWFwOiBtYWtlQXR0cnNNYXAoYXR0cnMpLFxuICAgICAgICBwYXJlbnQ6IGN1cnJlbnRQYXJlbnQsXG4gICAgICAgIGNoaWxkcmVuOiBbXVxuICAgICAgfTtcbiAgICAgIGlmIChucykge1xuICAgICAgICBlbGVtZW50Lm5zID0gbnM7XG4gICAgICB9XG5cbiAgICAgIGlmIChpc0ZvcmJpZGRlblRhZyhlbGVtZW50KSAmJiAhaXNTZXJ2ZXJSZW5kZXJpbmcoKSkge1xuICAgICAgICBlbGVtZW50LmZvcmJpZGRlbiA9IHRydWU7XG4gICAgICAgIHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicgJiYgd2FybiQyKFxuICAgICAgICAgICdUZW1wbGF0ZXMgc2hvdWxkIG9ubHkgYmUgcmVzcG9uc2libGUgZm9yIG1hcHBpbmcgdGhlIHN0YXRlIHRvIHRoZSAnICtcbiAgICAgICAgICAnVUkuIEF2b2lkIHBsYWNpbmcgdGFncyB3aXRoIHNpZGUtZWZmZWN0cyBpbiB5b3VyIHRlbXBsYXRlcywgc3VjaCBhcyAnICtcbiAgICAgICAgICBcIjxcIiArIHRhZyArIFwiPlwiICsgJywgYXMgdGhleSB3aWxsIG5vdCBiZSBwYXJzZWQuJ1xuICAgICAgICApO1xuICAgICAgfVxuXG4gICAgICAvLyBhcHBseSBwcmUtdHJhbnNmb3Jtc1xuICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBwcmVUcmFuc2Zvcm1zLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIHByZVRyYW5zZm9ybXNbaV0oZWxlbWVudCwgb3B0aW9ucyk7XG4gICAgICB9XG5cbiAgICAgIGlmICghaW5WUHJlKSB7XG4gICAgICAgIHByb2Nlc3NQcmUoZWxlbWVudCk7XG4gICAgICAgIGlmIChlbGVtZW50LnByZSkge1xuICAgICAgICAgIGluVlByZSA9IHRydWU7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGlmIChwbGF0Zm9ybUlzUHJlVGFnKGVsZW1lbnQudGFnKSkge1xuICAgICAgICBpblByZSA9IHRydWU7XG4gICAgICB9XG4gICAgICBpZiAoaW5WUHJlKSB7XG4gICAgICAgIHByb2Nlc3NSYXdBdHRycyhlbGVtZW50KTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHByb2Nlc3NGb3IoZWxlbWVudCk7XG4gICAgICAgIHByb2Nlc3NJZihlbGVtZW50KTtcbiAgICAgICAgcHJvY2Vzc09uY2UoZWxlbWVudCk7XG4gICAgICAgIHByb2Nlc3NLZXkoZWxlbWVudCk7XG5cbiAgICAgICAgLy8gZGV0ZXJtaW5lIHdoZXRoZXIgdGhpcyBpcyBhIHBsYWluIGVsZW1lbnQgYWZ0ZXJcbiAgICAgICAgLy8gcmVtb3Zpbmcgc3RydWN0dXJhbCBhdHRyaWJ1dGVzXG4gICAgICAgIGVsZW1lbnQucGxhaW4gPSAhZWxlbWVudC5rZXkgJiYgIWF0dHJzLmxlbmd0aDtcblxuICAgICAgICBwcm9jZXNzUmVmKGVsZW1lbnQpO1xuICAgICAgICBwcm9jZXNzU2xvdChlbGVtZW50KTtcbiAgICAgICAgcHJvY2Vzc0NvbXBvbmVudChlbGVtZW50KTtcbiAgICAgICAgZm9yICh2YXIgaSQxID0gMDsgaSQxIDwgdHJhbnNmb3Jtcy5sZW5ndGg7IGkkMSsrKSB7XG4gICAgICAgICAgdHJhbnNmb3Jtc1tpJDFdKGVsZW1lbnQsIG9wdGlvbnMpO1xuICAgICAgICB9XG4gICAgICAgIHByb2Nlc3NBdHRycyhlbGVtZW50KTtcbiAgICAgIH1cblxuICAgICAgZnVuY3Rpb24gY2hlY2tSb290Q29uc3RyYWludHMgKGVsKSB7XG4gICAgICAgIGlmIChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nKSB7XG4gICAgICAgICAgaWYgKGVsLnRhZyA9PT0gJ3Nsb3QnIHx8IGVsLnRhZyA9PT0gJ3RlbXBsYXRlJykge1xuICAgICAgICAgICAgd2Fybk9uY2UoXG4gICAgICAgICAgICAgIFwiQ2Fubm90IHVzZSA8XCIgKyAoZWwudGFnKSArIFwiPiBhcyBjb21wb25lbnQgcm9vdCBlbGVtZW50IGJlY2F1c2UgaXQgbWF5IFwiICtcbiAgICAgICAgICAgICAgJ2NvbnRhaW4gbXVsdGlwbGUgbm9kZXMuJ1xuICAgICAgICAgICAgKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgaWYgKGVsLmF0dHJzTWFwLmhhc093blByb3BlcnR5KCd2LWZvcicpKSB7XG4gICAgICAgICAgICB3YXJuT25jZShcbiAgICAgICAgICAgICAgJ0Nhbm5vdCB1c2Ugdi1mb3Igb24gc3RhdGVmdWwgY29tcG9uZW50IHJvb3QgZWxlbWVudCBiZWNhdXNlICcgK1xuICAgICAgICAgICAgICAnaXQgcmVuZGVycyBtdWx0aXBsZSBlbGVtZW50cy4nXG4gICAgICAgICAgICApO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICAvLyB0cmVlIG1hbmFnZW1lbnRcbiAgICAgIGlmICghcm9vdCkge1xuICAgICAgICByb290ID0gZWxlbWVudDtcbiAgICAgICAgY2hlY2tSb290Q29uc3RyYWludHMocm9vdCk7XG4gICAgICB9IGVsc2UgaWYgKCFzdGFjay5sZW5ndGgpIHtcbiAgICAgICAgLy8gYWxsb3cgcm9vdCBlbGVtZW50cyB3aXRoIHYtaWYsIHYtZWxzZS1pZiBhbmQgdi1lbHNlXG4gICAgICAgIGlmIChyb290LmlmICYmIChlbGVtZW50LmVsc2VpZiB8fCBlbGVtZW50LmVsc2UpKSB7XG4gICAgICAgICAgY2hlY2tSb290Q29uc3RyYWludHMoZWxlbWVudCk7XG4gICAgICAgICAgYWRkSWZDb25kaXRpb24ocm9vdCwge1xuICAgICAgICAgICAgZXhwOiBlbGVtZW50LmVsc2VpZixcbiAgICAgICAgICAgIGJsb2NrOiBlbGVtZW50XG4gICAgICAgICAgfSk7XG4gICAgICAgIH0gZWxzZSBpZiAocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJykge1xuICAgICAgICAgIHdhcm5PbmNlKFxuICAgICAgICAgICAgXCJDb21wb25lbnQgdGVtcGxhdGUgc2hvdWxkIGNvbnRhaW4gZXhhY3RseSBvbmUgcm9vdCBlbGVtZW50LiBcIiArXG4gICAgICAgICAgICBcIklmIHlvdSBhcmUgdXNpbmcgdi1pZiBvbiBtdWx0aXBsZSBlbGVtZW50cywgXCIgK1xuICAgICAgICAgICAgXCJ1c2Ugdi1lbHNlLWlmIHRvIGNoYWluIHRoZW0gaW5zdGVhZC5cIlxuICAgICAgICAgICk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGlmIChjdXJyZW50UGFyZW50ICYmICFlbGVtZW50LmZvcmJpZGRlbikge1xuICAgICAgICBpZiAoZWxlbWVudC5lbHNlaWYgfHwgZWxlbWVudC5lbHNlKSB7XG4gICAgICAgICAgcHJvY2Vzc0lmQ29uZGl0aW9ucyhlbGVtZW50LCBjdXJyZW50UGFyZW50KTtcbiAgICAgICAgfSBlbHNlIGlmIChlbGVtZW50LnNsb3RTY29wZSkgeyAvLyBzY29wZWQgc2xvdFxuICAgICAgICAgIGN1cnJlbnRQYXJlbnQucGxhaW4gPSBmYWxzZTtcbiAgICAgICAgICB2YXIgbmFtZSA9IGVsZW1lbnQuc2xvdFRhcmdldCB8fCAnXCJkZWZhdWx0XCInOyhjdXJyZW50UGFyZW50LnNjb3BlZFNsb3RzIHx8IChjdXJyZW50UGFyZW50LnNjb3BlZFNsb3RzID0ge30pKVtuYW1lXSA9IGVsZW1lbnQ7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgY3VycmVudFBhcmVudC5jaGlsZHJlbi5wdXNoKGVsZW1lbnQpO1xuICAgICAgICAgIGVsZW1lbnQucGFyZW50ID0gY3VycmVudFBhcmVudDtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaWYgKCF1bmFyeSkge1xuICAgICAgICBjdXJyZW50UGFyZW50ID0gZWxlbWVudDtcbiAgICAgICAgc3RhY2sucHVzaChlbGVtZW50KTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGVuZFByZShlbGVtZW50KTtcbiAgICAgIH1cbiAgICAgIC8vIGFwcGx5IHBvc3QtdHJhbnNmb3Jtc1xuICAgICAgZm9yICh2YXIgaSQyID0gMDsgaSQyIDwgcG9zdFRyYW5zZm9ybXMubGVuZ3RoOyBpJDIrKykge1xuICAgICAgICBwb3N0VHJhbnNmb3Jtc1tpJDJdKGVsZW1lbnQsIG9wdGlvbnMpO1xuICAgICAgfVxuICAgIH0sXG5cbiAgICBlbmQ6IGZ1bmN0aW9uIGVuZCAoKSB7XG4gICAgICAvLyByZW1vdmUgdHJhaWxpbmcgd2hpdGVzcGFjZVxuICAgICAgdmFyIGVsZW1lbnQgPSBzdGFja1tzdGFjay5sZW5ndGggLSAxXTtcbiAgICAgIHZhciBsYXN0Tm9kZSA9IGVsZW1lbnQuY2hpbGRyZW5bZWxlbWVudC5jaGlsZHJlbi5sZW5ndGggLSAxXTtcbiAgICAgIGlmIChsYXN0Tm9kZSAmJiBsYXN0Tm9kZS50eXBlID09PSAzICYmIGxhc3ROb2RlLnRleHQgPT09ICcgJyAmJiAhaW5QcmUpIHtcbiAgICAgICAgZWxlbWVudC5jaGlsZHJlbi5wb3AoKTtcbiAgICAgIH1cbiAgICAgIC8vIHBvcCBzdGFja1xuICAgICAgc3RhY2subGVuZ3RoIC09IDE7XG4gICAgICBjdXJyZW50UGFyZW50ID0gc3RhY2tbc3RhY2subGVuZ3RoIC0gMV07XG4gICAgICBlbmRQcmUoZWxlbWVudCk7XG4gICAgfSxcblxuICAgIGNoYXJzOiBmdW5jdGlvbiBjaGFycyAodGV4dCkge1xuICAgICAgaWYgKCFjdXJyZW50UGFyZW50KSB7XG4gICAgICAgIGlmIChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nKSB7XG4gICAgICAgICAgaWYgKHRleHQgPT09IHRlbXBsYXRlKSB7XG4gICAgICAgICAgICB3YXJuT25jZShcbiAgICAgICAgICAgICAgJ0NvbXBvbmVudCB0ZW1wbGF0ZSByZXF1aXJlcyBhIHJvb3QgZWxlbWVudCwgcmF0aGVyIHRoYW4ganVzdCB0ZXh0LidcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgfSBlbHNlIGlmICgodGV4dCA9IHRleHQudHJpbSgpKSkge1xuICAgICAgICAgICAgd2Fybk9uY2UoXG4gICAgICAgICAgICAgIChcInRleHQgXFxcIlwiICsgdGV4dCArIFwiXFxcIiBvdXRzaWRlIHJvb3QgZWxlbWVudCB3aWxsIGJlIGlnbm9yZWQuXCIpXG4gICAgICAgICAgICApO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm5cbiAgICAgIH1cbiAgICAgIC8vIElFIHRleHRhcmVhIHBsYWNlaG9sZGVyIGJ1Z1xuICAgICAgLyogaXN0YW5idWwgaWdub3JlIGlmICovXG4gICAgICBpZiAoaXNJRSAmJlxuICAgICAgICBjdXJyZW50UGFyZW50LnRhZyA9PT0gJ3RleHRhcmVhJyAmJlxuICAgICAgICBjdXJyZW50UGFyZW50LmF0dHJzTWFwLnBsYWNlaG9sZGVyID09PSB0ZXh0XG4gICAgICApIHtcbiAgICAgICAgcmV0dXJuXG4gICAgICB9XG4gICAgICB2YXIgY2hpbGRyZW4gPSBjdXJyZW50UGFyZW50LmNoaWxkcmVuO1xuICAgICAgdGV4dCA9IGluUHJlIHx8IHRleHQudHJpbSgpXG4gICAgICAgID8gaXNUZXh0VGFnKGN1cnJlbnRQYXJlbnQpID8gdGV4dCA6IGRlY29kZUhUTUxDYWNoZWQodGV4dClcbiAgICAgICAgLy8gb25seSBwcmVzZXJ2ZSB3aGl0ZXNwYWNlIGlmIGl0cyBub3QgcmlnaHQgYWZ0ZXIgYSBzdGFydGluZyB0YWdcbiAgICAgICAgOiBwcmVzZXJ2ZVdoaXRlc3BhY2UgJiYgY2hpbGRyZW4ubGVuZ3RoID8gJyAnIDogJyc7XG4gICAgICBpZiAodGV4dCkge1xuICAgICAgICB2YXIgZXhwcmVzc2lvbjtcbiAgICAgICAgaWYgKCFpblZQcmUgJiYgdGV4dCAhPT0gJyAnICYmIChleHByZXNzaW9uID0gcGFyc2VUZXh0KHRleHQsIGRlbGltaXRlcnMpKSkge1xuICAgICAgICAgIGNoaWxkcmVuLnB1c2goe1xuICAgICAgICAgICAgdHlwZTogMixcbiAgICAgICAgICAgIGV4cHJlc3Npb246IGV4cHJlc3Npb24sXG4gICAgICAgICAgICB0ZXh0OiB0ZXh0XG4gICAgICAgICAgfSk7XG4gICAgICAgIH0gZWxzZSBpZiAodGV4dCAhPT0gJyAnIHx8ICFjaGlsZHJlbi5sZW5ndGggfHwgY2hpbGRyZW5bY2hpbGRyZW4ubGVuZ3RoIC0gMV0udGV4dCAhPT0gJyAnKSB7XG4gICAgICAgICAgY2hpbGRyZW4ucHVzaCh7XG4gICAgICAgICAgICB0eXBlOiAzLFxuICAgICAgICAgICAgdGV4dDogdGV4dFxuICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSxcbiAgICBjb21tZW50OiBmdW5jdGlvbiBjb21tZW50ICh0ZXh0KSB7XG4gICAgICBjdXJyZW50UGFyZW50LmNoaWxkcmVuLnB1c2goe1xuICAgICAgICB0eXBlOiAzLFxuICAgICAgICB0ZXh0OiB0ZXh0LFxuICAgICAgICBpc0NvbW1lbnQ6IHRydWVcbiAgICAgIH0pO1xuICAgIH1cbiAgfSk7XG4gIHJldHVybiByb290XG59XG5cbmZ1bmN0aW9uIHByb2Nlc3NQcmUgKGVsKSB7XG4gIGlmIChnZXRBbmRSZW1vdmVBdHRyKGVsLCAndi1wcmUnKSAhPSBudWxsKSB7XG4gICAgZWwucHJlID0gdHJ1ZTtcbiAgfVxufVxuXG5mdW5jdGlvbiBwcm9jZXNzUmF3QXR0cnMgKGVsKSB7XG4gIHZhciBsID0gZWwuYXR0cnNMaXN0Lmxlbmd0aDtcbiAgaWYgKGwpIHtcbiAgICB2YXIgYXR0cnMgPSBlbC5hdHRycyA9IG5ldyBBcnJheShsKTtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGw7IGkrKykge1xuICAgICAgYXR0cnNbaV0gPSB7XG4gICAgICAgIG5hbWU6IGVsLmF0dHJzTGlzdFtpXS5uYW1lLFxuICAgICAgICB2YWx1ZTogSlNPTi5zdHJpbmdpZnkoZWwuYXR0cnNMaXN0W2ldLnZhbHVlKVxuICAgICAgfTtcbiAgICB9XG4gIH0gZWxzZSBpZiAoIWVsLnByZSkge1xuICAgIC8vIG5vbiByb290IG5vZGUgaW4gcHJlIGJsb2NrcyB3aXRoIG5vIGF0dHJpYnV0ZXNcbiAgICBlbC5wbGFpbiA9IHRydWU7XG4gIH1cbn1cblxuZnVuY3Rpb24gcHJvY2Vzc0tleSAoZWwpIHtcbiAgdmFyIGV4cCA9IGdldEJpbmRpbmdBdHRyKGVsLCAna2V5Jyk7XG4gIGlmIChleHApIHtcbiAgICBpZiAocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJyAmJiBlbC50YWcgPT09ICd0ZW1wbGF0ZScpIHtcbiAgICAgIHdhcm4kMihcIjx0ZW1wbGF0ZT4gY2Fubm90IGJlIGtleWVkLiBQbGFjZSB0aGUga2V5IG9uIHJlYWwgZWxlbWVudHMgaW5zdGVhZC5cIik7XG4gICAgfVxuICAgIGVsLmtleSA9IGV4cDtcbiAgfVxufVxuXG5mdW5jdGlvbiBwcm9jZXNzUmVmIChlbCkge1xuICB2YXIgcmVmID0gZ2V0QmluZGluZ0F0dHIoZWwsICdyZWYnKTtcbiAgaWYgKHJlZikge1xuICAgIGVsLnJlZiA9IHJlZjtcbiAgICBlbC5yZWZJbkZvciA9IGNoZWNrSW5Gb3IoZWwpO1xuICB9XG59XG5cbmZ1bmN0aW9uIHByb2Nlc3NGb3IgKGVsKSB7XG4gIHZhciBleHA7XG4gIGlmICgoZXhwID0gZ2V0QW5kUmVtb3ZlQXR0cihlbCwgJ3YtZm9yJykpKSB7XG4gICAgdmFyIGluTWF0Y2ggPSBleHAubWF0Y2goZm9yQWxpYXNSRSk7XG4gICAgaWYgKCFpbk1hdGNoKSB7XG4gICAgICBwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nICYmIHdhcm4kMihcbiAgICAgICAgKFwiSW52YWxpZCB2LWZvciBleHByZXNzaW9uOiBcIiArIGV4cClcbiAgICAgICk7XG4gICAgICByZXR1cm5cbiAgICB9XG4gICAgZWwuZm9yID0gaW5NYXRjaFsyXS50cmltKCk7XG4gICAgdmFyIGFsaWFzID0gaW5NYXRjaFsxXS50cmltKCk7XG4gICAgdmFyIGl0ZXJhdG9yTWF0Y2ggPSBhbGlhcy5tYXRjaChmb3JJdGVyYXRvclJFKTtcbiAgICBpZiAoaXRlcmF0b3JNYXRjaCkge1xuICAgICAgZWwuYWxpYXMgPSBpdGVyYXRvck1hdGNoWzFdLnRyaW0oKTtcbiAgICAgIGVsLml0ZXJhdG9yMSA9IGl0ZXJhdG9yTWF0Y2hbMl0udHJpbSgpO1xuICAgICAgaWYgKGl0ZXJhdG9yTWF0Y2hbM10pIHtcbiAgICAgICAgZWwuaXRlcmF0b3IyID0gaXRlcmF0b3JNYXRjaFszXS50cmltKCk7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIGVsLmFsaWFzID0gYWxpYXM7XG4gICAgfVxuICB9XG59XG5cbmZ1bmN0aW9uIHByb2Nlc3NJZiAoZWwpIHtcbiAgdmFyIGV4cCA9IGdldEFuZFJlbW92ZUF0dHIoZWwsICd2LWlmJyk7XG4gIGlmIChleHApIHtcbiAgICBlbC5pZiA9IGV4cDtcbiAgICBhZGRJZkNvbmRpdGlvbihlbCwge1xuICAgICAgZXhwOiBleHAsXG4gICAgICBibG9jazogZWxcbiAgICB9KTtcbiAgfSBlbHNlIHtcbiAgICBpZiAoZ2V0QW5kUmVtb3ZlQXR0cihlbCwgJ3YtZWxzZScpICE9IG51bGwpIHtcbiAgICAgIGVsLmVsc2UgPSB0cnVlO1xuICAgIH1cbiAgICB2YXIgZWxzZWlmID0gZ2V0QW5kUmVtb3ZlQXR0cihlbCwgJ3YtZWxzZS1pZicpO1xuICAgIGlmIChlbHNlaWYpIHtcbiAgICAgIGVsLmVsc2VpZiA9IGVsc2VpZjtcbiAgICB9XG4gIH1cbn1cblxuZnVuY3Rpb24gcHJvY2Vzc0lmQ29uZGl0aW9ucyAoZWwsIHBhcmVudCkge1xuICB2YXIgcHJldiA9IGZpbmRQcmV2RWxlbWVudChwYXJlbnQuY2hpbGRyZW4pO1xuICBpZiAocHJldiAmJiBwcmV2LmlmKSB7XG4gICAgYWRkSWZDb25kaXRpb24ocHJldiwge1xuICAgICAgZXhwOiBlbC5lbHNlaWYsXG4gICAgICBibG9jazogZWxcbiAgICB9KTtcbiAgfSBlbHNlIGlmIChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nKSB7XG4gICAgd2FybiQyKFxuICAgICAgXCJ2LVwiICsgKGVsLmVsc2VpZiA/ICgnZWxzZS1pZj1cIicgKyBlbC5lbHNlaWYgKyAnXCInKSA6ICdlbHNlJykgKyBcIiBcIiArXG4gICAgICBcInVzZWQgb24gZWxlbWVudCA8XCIgKyAoZWwudGFnKSArIFwiPiB3aXRob3V0IGNvcnJlc3BvbmRpbmcgdi1pZi5cIlxuICAgICk7XG4gIH1cbn1cblxuZnVuY3Rpb24gZmluZFByZXZFbGVtZW50IChjaGlsZHJlbikge1xuICB2YXIgaSA9IGNoaWxkcmVuLmxlbmd0aDtcbiAgd2hpbGUgKGktLSkge1xuICAgIGlmIChjaGlsZHJlbltpXS50eXBlID09PSAxKSB7XG4gICAgICByZXR1cm4gY2hpbGRyZW5baV1cbiAgICB9IGVsc2Uge1xuICAgICAgaWYgKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicgJiYgY2hpbGRyZW5baV0udGV4dCAhPT0gJyAnKSB7XG4gICAgICAgIHdhcm4kMihcbiAgICAgICAgICBcInRleHQgXFxcIlwiICsgKGNoaWxkcmVuW2ldLnRleHQudHJpbSgpKSArIFwiXFxcIiBiZXR3ZWVuIHYtaWYgYW5kIHYtZWxzZSgtaWYpIFwiICtcbiAgICAgICAgICBcIndpbGwgYmUgaWdub3JlZC5cIlxuICAgICAgICApO1xuICAgICAgfVxuICAgICAgY2hpbGRyZW4ucG9wKCk7XG4gICAgfVxuICB9XG59XG5cbmZ1bmN0aW9uIGFkZElmQ29uZGl0aW9uIChlbCwgY29uZGl0aW9uKSB7XG4gIGlmICghZWwuaWZDb25kaXRpb25zKSB7XG4gICAgZWwuaWZDb25kaXRpb25zID0gW107XG4gIH1cbiAgZWwuaWZDb25kaXRpb25zLnB1c2goY29uZGl0aW9uKTtcbn1cblxuZnVuY3Rpb24gcHJvY2Vzc09uY2UgKGVsKSB7XG4gIHZhciBvbmNlJCQxID0gZ2V0QW5kUmVtb3ZlQXR0cihlbCwgJ3Ytb25jZScpO1xuICBpZiAob25jZSQkMSAhPSBudWxsKSB7XG4gICAgZWwub25jZSA9IHRydWU7XG4gIH1cbn1cblxuZnVuY3Rpb24gcHJvY2Vzc1Nsb3QgKGVsKSB7XG4gIGlmIChlbC50YWcgPT09ICdzbG90Jykge1xuICAgIGVsLnNsb3ROYW1lID0gZ2V0QmluZGluZ0F0dHIoZWwsICduYW1lJyk7XG4gICAgaWYgKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicgJiYgZWwua2V5KSB7XG4gICAgICB3YXJuJDIoXG4gICAgICAgIFwiYGtleWAgZG9lcyBub3Qgd29yayBvbiA8c2xvdD4gYmVjYXVzZSBzbG90cyBhcmUgYWJzdHJhY3Qgb3V0bGV0cyBcIiArXG4gICAgICAgIFwiYW5kIGNhbiBwb3NzaWJseSBleHBhbmQgaW50byBtdWx0aXBsZSBlbGVtZW50cy4gXCIgK1xuICAgICAgICBcIlVzZSB0aGUga2V5IG9uIGEgd3JhcHBpbmcgZWxlbWVudCBpbnN0ZWFkLlwiXG4gICAgICApO1xuICAgIH1cbiAgfSBlbHNlIHtcbiAgICB2YXIgc2xvdFRhcmdldCA9IGdldEJpbmRpbmdBdHRyKGVsLCAnc2xvdCcpO1xuICAgIGlmIChzbG90VGFyZ2V0KSB7XG4gICAgICBlbC5zbG90VGFyZ2V0ID0gc2xvdFRhcmdldCA9PT0gJ1wiXCInID8gJ1wiZGVmYXVsdFwiJyA6IHNsb3RUYXJnZXQ7XG4gICAgICAvLyBwcmVzZXJ2ZSBzbG90IGFzIGFuIGF0dHJpYnV0ZSBmb3IgbmF0aXZlIHNoYWRvdyBET00gY29tcGF0XG4gICAgICBhZGRBdHRyKGVsLCAnc2xvdCcsIHNsb3RUYXJnZXQpO1xuICAgIH1cbiAgICBpZiAoZWwudGFnID09PSAndGVtcGxhdGUnKSB7XG4gICAgICBlbC5zbG90U2NvcGUgPSBnZXRBbmRSZW1vdmVBdHRyKGVsLCAnc2NvcGUnKTtcbiAgICB9XG4gIH1cbn1cblxuZnVuY3Rpb24gcHJvY2Vzc0NvbXBvbmVudCAoZWwpIHtcbiAgdmFyIGJpbmRpbmc7XG4gIGlmICgoYmluZGluZyA9IGdldEJpbmRpbmdBdHRyKGVsLCAnaXMnKSkpIHtcbiAgICBlbC5jb21wb25lbnQgPSBiaW5kaW5nO1xuICB9XG4gIGlmIChnZXRBbmRSZW1vdmVBdHRyKGVsLCAnaW5saW5lLXRlbXBsYXRlJykgIT0gbnVsbCkge1xuICAgIGVsLmlubGluZVRlbXBsYXRlID0gdHJ1ZTtcbiAgfVxufVxuXG5mdW5jdGlvbiBwcm9jZXNzQXR0cnMgKGVsKSB7XG4gIHZhciBsaXN0ID0gZWwuYXR0cnNMaXN0O1xuICB2YXIgaSwgbCwgbmFtZSwgcmF3TmFtZSwgdmFsdWUsIG1vZGlmaWVycywgaXNQcm9wO1xuICBmb3IgKGkgPSAwLCBsID0gbGlzdC5sZW5ndGg7IGkgPCBsOyBpKyspIHtcbiAgICBuYW1lID0gcmF3TmFtZSA9IGxpc3RbaV0ubmFtZTtcbiAgICB2YWx1ZSA9IGxpc3RbaV0udmFsdWU7XG4gICAgaWYgKGRpclJFLnRlc3QobmFtZSkpIHtcbiAgICAgIC8vIG1hcmsgZWxlbWVudCBhcyBkeW5hbWljXG4gICAgICBlbC5oYXNCaW5kaW5ncyA9IHRydWU7XG4gICAgICAvLyBtb2RpZmllcnNcbiAgICAgIG1vZGlmaWVycyA9IHBhcnNlTW9kaWZpZXJzKG5hbWUpO1xuICAgICAgaWYgKG1vZGlmaWVycykge1xuICAgICAgICBuYW1lID0gbmFtZS5yZXBsYWNlKG1vZGlmaWVyUkUsICcnKTtcbiAgICAgIH1cbiAgICAgIGlmIChiaW5kUkUudGVzdChuYW1lKSkgeyAvLyB2LWJpbmRcbiAgICAgICAgbmFtZSA9IG5hbWUucmVwbGFjZShiaW5kUkUsICcnKTtcbiAgICAgICAgdmFsdWUgPSBwYXJzZUZpbHRlcnModmFsdWUpO1xuICAgICAgICBpc1Byb3AgPSBmYWxzZTtcbiAgICAgICAgaWYgKG1vZGlmaWVycykge1xuICAgICAgICAgIGlmIChtb2RpZmllcnMucHJvcCkge1xuICAgICAgICAgICAgaXNQcm9wID0gdHJ1ZTtcbiAgICAgICAgICAgIG5hbWUgPSBjYW1lbGl6ZShuYW1lKTtcbiAgICAgICAgICAgIGlmIChuYW1lID09PSAnaW5uZXJIdG1sJykgeyBuYW1lID0gJ2lubmVySFRNTCc7IH1cbiAgICAgICAgICB9XG4gICAgICAgICAgaWYgKG1vZGlmaWVycy5jYW1lbCkge1xuICAgICAgICAgICAgbmFtZSA9IGNhbWVsaXplKG5hbWUpO1xuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAobW9kaWZpZXJzLnN5bmMpIHtcbiAgICAgICAgICAgIGFkZEhhbmRsZXIoXG4gICAgICAgICAgICAgIGVsLFxuICAgICAgICAgICAgICAoXCJ1cGRhdGU6XCIgKyAoY2FtZWxpemUobmFtZSkpKSxcbiAgICAgICAgICAgICAgZ2VuQXNzaWdubWVudENvZGUodmFsdWUsIFwiJGV2ZW50XCIpXG4gICAgICAgICAgICApO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBpZiAoaXNQcm9wIHx8IChcbiAgICAgICAgICAhZWwuY29tcG9uZW50ICYmIHBsYXRmb3JtTXVzdFVzZVByb3AoZWwudGFnLCBlbC5hdHRyc01hcC50eXBlLCBuYW1lKVxuICAgICAgICApKSB7XG4gICAgICAgICAgYWRkUHJvcChlbCwgbmFtZSwgdmFsdWUpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGFkZEF0dHIoZWwsIG5hbWUsIHZhbHVlKTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIGlmIChvblJFLnRlc3QobmFtZSkpIHsgLy8gdi1vblxuICAgICAgICBuYW1lID0gbmFtZS5yZXBsYWNlKG9uUkUsICcnKTtcbiAgICAgICAgYWRkSGFuZGxlcihlbCwgbmFtZSwgdmFsdWUsIG1vZGlmaWVycywgZmFsc2UsIHdhcm4kMik7XG4gICAgICB9IGVsc2UgeyAvLyBub3JtYWwgZGlyZWN0aXZlc1xuICAgICAgICBuYW1lID0gbmFtZS5yZXBsYWNlKGRpclJFLCAnJyk7XG4gICAgICAgIC8vIHBhcnNlIGFyZ1xuICAgICAgICB2YXIgYXJnTWF0Y2ggPSBuYW1lLm1hdGNoKGFyZ1JFKTtcbiAgICAgICAgdmFyIGFyZyA9IGFyZ01hdGNoICYmIGFyZ01hdGNoWzFdO1xuICAgICAgICBpZiAoYXJnKSB7XG4gICAgICAgICAgbmFtZSA9IG5hbWUuc2xpY2UoMCwgLShhcmcubGVuZ3RoICsgMSkpO1xuICAgICAgICB9XG4gICAgICAgIGFkZERpcmVjdGl2ZShlbCwgbmFtZSwgcmF3TmFtZSwgdmFsdWUsIGFyZywgbW9kaWZpZXJzKTtcbiAgICAgICAgaWYgKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicgJiYgbmFtZSA9PT0gJ21vZGVsJykge1xuICAgICAgICAgIGNoZWNrRm9yQWxpYXNNb2RlbChlbCwgdmFsdWUpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIGxpdGVyYWwgYXR0cmlidXRlXG4gICAgICBpZiAocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJykge1xuICAgICAgICB2YXIgZXhwcmVzc2lvbiA9IHBhcnNlVGV4dCh2YWx1ZSwgZGVsaW1pdGVycyk7XG4gICAgICAgIGlmIChleHByZXNzaW9uKSB7XG4gICAgICAgICAgd2FybiQyKFxuICAgICAgICAgICAgbmFtZSArIFwiPVxcXCJcIiArIHZhbHVlICsgXCJcXFwiOiBcIiArXG4gICAgICAgICAgICAnSW50ZXJwb2xhdGlvbiBpbnNpZGUgYXR0cmlidXRlcyBoYXMgYmVlbiByZW1vdmVkLiAnICtcbiAgICAgICAgICAgICdVc2Ugdi1iaW5kIG9yIHRoZSBjb2xvbiBzaG9ydGhhbmQgaW5zdGVhZC4gRm9yIGV4YW1wbGUsICcgK1xuICAgICAgICAgICAgJ2luc3RlYWQgb2YgPGRpdiBpZD1cInt7IHZhbCB9fVwiPiwgdXNlIDxkaXYgOmlkPVwidmFsXCI+LidcbiAgICAgICAgICApO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBhZGRBdHRyKGVsLCBuYW1lLCBKU09OLnN0cmluZ2lmeSh2YWx1ZSkpO1xuICAgIH1cbiAgfVxufVxuXG5mdW5jdGlvbiBjaGVja0luRm9yIChlbCkge1xuICB2YXIgcGFyZW50ID0gZWw7XG4gIHdoaWxlIChwYXJlbnQpIHtcbiAgICBpZiAocGFyZW50LmZvciAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICByZXR1cm4gdHJ1ZVxuICAgIH1cbiAgICBwYXJlbnQgPSBwYXJlbnQucGFyZW50O1xuICB9XG4gIHJldHVybiBmYWxzZVxufVxuXG5mdW5jdGlvbiBwYXJzZU1vZGlmaWVycyAobmFtZSkge1xuICB2YXIgbWF0Y2ggPSBuYW1lLm1hdGNoKG1vZGlmaWVyUkUpO1xuICBpZiAobWF0Y2gpIHtcbiAgICB2YXIgcmV0ID0ge307XG4gICAgbWF0Y2guZm9yRWFjaChmdW5jdGlvbiAobSkgeyByZXRbbS5zbGljZSgxKV0gPSB0cnVlOyB9KTtcbiAgICByZXR1cm4gcmV0XG4gIH1cbn1cblxuZnVuY3Rpb24gbWFrZUF0dHJzTWFwIChhdHRycykge1xuICB2YXIgbWFwID0ge307XG4gIGZvciAodmFyIGkgPSAwLCBsID0gYXR0cnMubGVuZ3RoOyBpIDwgbDsgaSsrKSB7XG4gICAgaWYgKFxuICAgICAgcHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJyAmJlxuICAgICAgbWFwW2F0dHJzW2ldLm5hbWVdICYmICFpc0lFICYmICFpc0VkZ2VcbiAgICApIHtcbiAgICAgIHdhcm4kMignZHVwbGljYXRlIGF0dHJpYnV0ZTogJyArIGF0dHJzW2ldLm5hbWUpO1xuICAgIH1cbiAgICBtYXBbYXR0cnNbaV0ubmFtZV0gPSBhdHRyc1tpXS52YWx1ZTtcbiAgfVxuICByZXR1cm4gbWFwXG59XG5cbi8vIGZvciBzY3JpcHQgKGUuZy4gdHlwZT1cIngvdGVtcGxhdGVcIikgb3Igc3R5bGUsIGRvIG5vdCBkZWNvZGUgY29udGVudFxuZnVuY3Rpb24gaXNUZXh0VGFnIChlbCkge1xuICByZXR1cm4gZWwudGFnID09PSAnc2NyaXB0JyB8fCBlbC50YWcgPT09ICdzdHlsZSdcbn1cblxuZnVuY3Rpb24gaXNGb3JiaWRkZW5UYWcgKGVsKSB7XG4gIHJldHVybiAoXG4gICAgZWwudGFnID09PSAnc3R5bGUnIHx8XG4gICAgKGVsLnRhZyA9PT0gJ3NjcmlwdCcgJiYgKFxuICAgICAgIWVsLmF0dHJzTWFwLnR5cGUgfHxcbiAgICAgIGVsLmF0dHJzTWFwLnR5cGUgPT09ICd0ZXh0L2phdmFzY3JpcHQnXG4gICAgKSlcbiAgKVxufVxuXG52YXIgaWVOU0J1ZyA9IC9eeG1sbnM6TlNcXGQrLztcbnZhciBpZU5TUHJlZml4ID0gL15OU1xcZCs6LztcblxuLyogaXN0YW5idWwgaWdub3JlIG5leHQgKi9cbmZ1bmN0aW9uIGd1YXJkSUVTVkdCdWcgKGF0dHJzKSB7XG4gIHZhciByZXMgPSBbXTtcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBhdHRycy5sZW5ndGg7IGkrKykge1xuICAgIHZhciBhdHRyID0gYXR0cnNbaV07XG4gICAgaWYgKCFpZU5TQnVnLnRlc3QoYXR0ci5uYW1lKSkge1xuICAgICAgYXR0ci5uYW1lID0gYXR0ci5uYW1lLnJlcGxhY2UoaWVOU1ByZWZpeCwgJycpO1xuICAgICAgcmVzLnB1c2goYXR0cik7XG4gICAgfVxuICB9XG4gIHJldHVybiByZXNcbn1cblxuZnVuY3Rpb24gY2hlY2tGb3JBbGlhc01vZGVsIChlbCwgdmFsdWUpIHtcbiAgdmFyIF9lbCA9IGVsO1xuICB3aGlsZSAoX2VsKSB7XG4gICAgaWYgKF9lbC5mb3IgJiYgX2VsLmFsaWFzID09PSB2YWx1ZSkge1xuICAgICAgd2FybiQyKFxuICAgICAgICBcIjxcIiArIChlbC50YWcpICsgXCIgdi1tb2RlbD1cXFwiXCIgKyB2YWx1ZSArIFwiXFxcIj46IFwiICtcbiAgICAgICAgXCJZb3UgYXJlIGJpbmRpbmcgdi1tb2RlbCBkaXJlY3RseSB0byBhIHYtZm9yIGl0ZXJhdGlvbiBhbGlhcy4gXCIgK1xuICAgICAgICBcIlRoaXMgd2lsbCBub3QgYmUgYWJsZSB0byBtb2RpZnkgdGhlIHYtZm9yIHNvdXJjZSBhcnJheSBiZWNhdXNlIFwiICtcbiAgICAgICAgXCJ3cml0aW5nIHRvIHRoZSBhbGlhcyBpcyBsaWtlIG1vZGlmeWluZyBhIGZ1bmN0aW9uIGxvY2FsIHZhcmlhYmxlLiBcIiArXG4gICAgICAgIFwiQ29uc2lkZXIgdXNpbmcgYW4gYXJyYXkgb2Ygb2JqZWN0cyBhbmQgdXNlIHYtbW9kZWwgb24gYW4gb2JqZWN0IHByb3BlcnR5IGluc3RlYWQuXCJcbiAgICAgICk7XG4gICAgfVxuICAgIF9lbCA9IF9lbC5wYXJlbnQ7XG4gIH1cbn1cblxuLyogICovXG5cbnZhciBpc1N0YXRpY0tleTtcbnZhciBpc1BsYXRmb3JtUmVzZXJ2ZWRUYWc7XG5cbnZhciBnZW5TdGF0aWNLZXlzQ2FjaGVkID0gY2FjaGVkKGdlblN0YXRpY0tleXMkMSk7XG5cbi8qKlxuICogR29hbCBvZiB0aGUgb3B0aW1pemVyOiB3YWxrIHRoZSBnZW5lcmF0ZWQgdGVtcGxhdGUgQVNUIHRyZWVcbiAqIGFuZCBkZXRlY3Qgc3ViLXRyZWVzIHRoYXQgYXJlIHB1cmVseSBzdGF0aWMsIGkuZS4gcGFydHMgb2ZcbiAqIHRoZSBET00gdGhhdCBuZXZlciBuZWVkcyB0byBjaGFuZ2UuXG4gKlxuICogT25jZSB3ZSBkZXRlY3QgdGhlc2Ugc3ViLXRyZWVzLCB3ZSBjYW46XG4gKlxuICogMS4gSG9pc3QgdGhlbSBpbnRvIGNvbnN0YW50cywgc28gdGhhdCB3ZSBubyBsb25nZXIgbmVlZCB0b1xuICogICAgY3JlYXRlIGZyZXNoIG5vZGVzIGZvciB0aGVtIG9uIGVhY2ggcmUtcmVuZGVyO1xuICogMi4gQ29tcGxldGVseSBza2lwIHRoZW0gaW4gdGhlIHBhdGNoaW5nIHByb2Nlc3MuXG4gKi9cbmZ1bmN0aW9uIG9wdGltaXplIChyb290LCBvcHRpb25zKSB7XG4gIGlmICghcm9vdCkgeyByZXR1cm4gfVxuICBpc1N0YXRpY0tleSA9IGdlblN0YXRpY0tleXNDYWNoZWQob3B0aW9ucy5zdGF0aWNLZXlzIHx8ICcnKTtcbiAgaXNQbGF0Zm9ybVJlc2VydmVkVGFnID0gb3B0aW9ucy5pc1Jlc2VydmVkVGFnIHx8IG5vO1xuICAvLyBmaXJzdCBwYXNzOiBtYXJrIGFsbCBub24tc3RhdGljIG5vZGVzLlxuICBtYXJrU3RhdGljJDEocm9vdCk7XG4gIC8vIHNlY29uZCBwYXNzOiBtYXJrIHN0YXRpYyByb290cy5cbiAgbWFya1N0YXRpY1Jvb3RzKHJvb3QsIGZhbHNlKTtcbn1cblxuZnVuY3Rpb24gZ2VuU3RhdGljS2V5cyQxIChrZXlzKSB7XG4gIHJldHVybiBtYWtlTWFwKFxuICAgICd0eXBlLHRhZyxhdHRyc0xpc3QsYXR0cnNNYXAscGxhaW4scGFyZW50LGNoaWxkcmVuLGF0dHJzJyArXG4gICAgKGtleXMgPyAnLCcgKyBrZXlzIDogJycpXG4gIClcbn1cblxuZnVuY3Rpb24gbWFya1N0YXRpYyQxIChub2RlKSB7XG4gIG5vZGUuc3RhdGljID0gaXNTdGF0aWMobm9kZSk7XG4gIGlmIChub2RlLnR5cGUgPT09IDEpIHtcbiAgICAvLyBkbyBub3QgbWFrZSBjb21wb25lbnQgc2xvdCBjb250ZW50IHN0YXRpYy4gdGhpcyBhdm9pZHNcbiAgICAvLyAxLiBjb21wb25lbnRzIG5vdCBhYmxlIHRvIG11dGF0ZSBzbG90IG5vZGVzXG4gICAgLy8gMi4gc3RhdGljIHNsb3QgY29udGVudCBmYWlscyBmb3IgaG90LXJlbG9hZGluZ1xuICAgIGlmIChcbiAgICAgICFpc1BsYXRmb3JtUmVzZXJ2ZWRUYWcobm9kZS50YWcpICYmXG4gICAgICBub2RlLnRhZyAhPT0gJ3Nsb3QnICYmXG4gICAgICBub2RlLmF0dHJzTWFwWydpbmxpbmUtdGVtcGxhdGUnXSA9PSBudWxsXG4gICAgKSB7XG4gICAgICByZXR1cm5cbiAgICB9XG4gICAgZm9yICh2YXIgaSA9IDAsIGwgPSBub2RlLmNoaWxkcmVuLmxlbmd0aDsgaSA8IGw7IGkrKykge1xuICAgICAgdmFyIGNoaWxkID0gbm9kZS5jaGlsZHJlbltpXTtcbiAgICAgIG1hcmtTdGF0aWMkMShjaGlsZCk7XG4gICAgICBpZiAoIWNoaWxkLnN0YXRpYykge1xuICAgICAgICBub2RlLnN0YXRpYyA9IGZhbHNlO1xuICAgICAgfVxuICAgIH1cbiAgICBpZiAobm9kZS5pZkNvbmRpdGlvbnMpIHtcbiAgICAgIGZvciAodmFyIGkkMSA9IDEsIGwkMSA9IG5vZGUuaWZDb25kaXRpb25zLmxlbmd0aDsgaSQxIDwgbCQxOyBpJDErKykge1xuICAgICAgICB2YXIgYmxvY2sgPSBub2RlLmlmQ29uZGl0aW9uc1tpJDFdLmJsb2NrO1xuICAgICAgICBtYXJrU3RhdGljJDEoYmxvY2spO1xuICAgICAgICBpZiAoIWJsb2NrLnN0YXRpYykge1xuICAgICAgICAgIG5vZGUuc3RhdGljID0gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH1cbn1cblxuZnVuY3Rpb24gbWFya1N0YXRpY1Jvb3RzIChub2RlLCBpc0luRm9yKSB7XG4gIGlmIChub2RlLnR5cGUgPT09IDEpIHtcbiAgICBpZiAobm9kZS5zdGF0aWMgfHwgbm9kZS5vbmNlKSB7XG4gICAgICBub2RlLnN0YXRpY0luRm9yID0gaXNJbkZvcjtcbiAgICB9XG4gICAgLy8gRm9yIGEgbm9kZSB0byBxdWFsaWZ5IGFzIGEgc3RhdGljIHJvb3QsIGl0IHNob3VsZCBoYXZlIGNoaWxkcmVuIHRoYXRcbiAgICAvLyBhcmUgbm90IGp1c3Qgc3RhdGljIHRleHQuIE90aGVyd2lzZSB0aGUgY29zdCBvZiBob2lzdGluZyBvdXQgd2lsbFxuICAgIC8vIG91dHdlaWdoIHRoZSBiZW5lZml0cyBhbmQgaXQncyBiZXR0ZXIgb2ZmIHRvIGp1c3QgYWx3YXlzIHJlbmRlciBpdCBmcmVzaC5cbiAgICBpZiAobm9kZS5zdGF0aWMgJiYgbm9kZS5jaGlsZHJlbi5sZW5ndGggJiYgIShcbiAgICAgIG5vZGUuY2hpbGRyZW4ubGVuZ3RoID09PSAxICYmXG4gICAgICBub2RlLmNoaWxkcmVuWzBdLnR5cGUgPT09IDNcbiAgICApKSB7XG4gICAgICBub2RlLnN0YXRpY1Jvb3QgPSB0cnVlO1xuICAgICAgcmV0dXJuXG4gICAgfSBlbHNlIHtcbiAgICAgIG5vZGUuc3RhdGljUm9vdCA9IGZhbHNlO1xuICAgIH1cbiAgICBpZiAobm9kZS5jaGlsZHJlbikge1xuICAgICAgZm9yICh2YXIgaSA9IDAsIGwgPSBub2RlLmNoaWxkcmVuLmxlbmd0aDsgaSA8IGw7IGkrKykge1xuICAgICAgICBtYXJrU3RhdGljUm9vdHMobm9kZS5jaGlsZHJlbltpXSwgaXNJbkZvciB8fCAhIW5vZGUuZm9yKTtcbiAgICAgIH1cbiAgICB9XG4gICAgaWYgKG5vZGUuaWZDb25kaXRpb25zKSB7XG4gICAgICBmb3IgKHZhciBpJDEgPSAxLCBsJDEgPSBub2RlLmlmQ29uZGl0aW9ucy5sZW5ndGg7IGkkMSA8IGwkMTsgaSQxKyspIHtcbiAgICAgICAgbWFya1N0YXRpY1Jvb3RzKG5vZGUuaWZDb25kaXRpb25zW2kkMV0uYmxvY2ssIGlzSW5Gb3IpO1xuICAgICAgfVxuICAgIH1cbiAgfVxufVxuXG5mdW5jdGlvbiBpc1N0YXRpYyAobm9kZSkge1xuICBpZiAobm9kZS50eXBlID09PSAyKSB7IC8vIGV4cHJlc3Npb25cbiAgICByZXR1cm4gZmFsc2VcbiAgfVxuICBpZiAobm9kZS50eXBlID09PSAzKSB7IC8vIHRleHRcbiAgICByZXR1cm4gdHJ1ZVxuICB9XG4gIHJldHVybiAhIShub2RlLnByZSB8fCAoXG4gICAgIW5vZGUuaGFzQmluZGluZ3MgJiYgLy8gbm8gZHluYW1pYyBiaW5kaW5nc1xuICAgICFub2RlLmlmICYmICFub2RlLmZvciAmJiAvLyBub3Qgdi1pZiBvciB2LWZvciBvciB2LWVsc2VcbiAgICAhaXNCdWlsdEluVGFnKG5vZGUudGFnKSAmJiAvLyBub3QgYSBidWlsdC1pblxuICAgIGlzUGxhdGZvcm1SZXNlcnZlZFRhZyhub2RlLnRhZykgJiYgLy8gbm90IGEgY29tcG9uZW50XG4gICAgIWlzRGlyZWN0Q2hpbGRPZlRlbXBsYXRlRm9yKG5vZGUpICYmXG4gICAgT2JqZWN0LmtleXMobm9kZSkuZXZlcnkoaXNTdGF0aWNLZXkpXG4gICkpXG59XG5cbmZ1bmN0aW9uIGlzRGlyZWN0Q2hpbGRPZlRlbXBsYXRlRm9yIChub2RlKSB7XG4gIHdoaWxlIChub2RlLnBhcmVudCkge1xuICAgIG5vZGUgPSBub2RlLnBhcmVudDtcbiAgICBpZiAobm9kZS50YWcgIT09ICd0ZW1wbGF0ZScpIHtcbiAgICAgIHJldHVybiBmYWxzZVxuICAgIH1cbiAgICBpZiAobm9kZS5mb3IpIHtcbiAgICAgIHJldHVybiB0cnVlXG4gICAgfVxuICB9XG4gIHJldHVybiBmYWxzZVxufVxuXG4vKiAgKi9cblxudmFyIGZuRXhwUkUgPSAvXlxccyooW1xcdyRfXSt8XFwoW14pXSo/XFwpKVxccyo9PnxeZnVuY3Rpb25cXHMqXFwoLztcbnZhciBzaW1wbGVQYXRoUkUgPSAvXlxccypbQS1aYS16XyRdW1xcdyRdKig/OlxcLltBLVphLXpfJF1bXFx3JF0qfFxcWycuKj8nXXxcXFtcIi4qP1wiXXxcXFtcXGQrXXxcXFtbQS1aYS16XyRdW1xcdyRdKl0pKlxccyokLztcblxuLy8ga2V5Q29kZSBhbGlhc2VzXG52YXIga2V5Q29kZXMgPSB7XG4gIGVzYzogMjcsXG4gIHRhYjogOSxcbiAgZW50ZXI6IDEzLFxuICBzcGFjZTogMzIsXG4gIHVwOiAzOCxcbiAgbGVmdDogMzcsXG4gIHJpZ2h0OiAzOSxcbiAgZG93bjogNDAsXG4gICdkZWxldGUnOiBbOCwgNDZdXG59O1xuXG4vLyAjNDg2ODogbW9kaWZpZXJzIHRoYXQgcHJldmVudCB0aGUgZXhlY3V0aW9uIG9mIHRoZSBsaXN0ZW5lclxuLy8gbmVlZCB0byBleHBsaWNpdGx5IHJldHVybiBudWxsIHNvIHRoYXQgd2UgY2FuIGRldGVybWluZSB3aGV0aGVyIHRvIHJlbW92ZVxuLy8gdGhlIGxpc3RlbmVyIGZvciAub25jZVxudmFyIGdlbkd1YXJkID0gZnVuY3Rpb24gKGNvbmRpdGlvbikgeyByZXR1cm4gKFwiaWYoXCIgKyBjb25kaXRpb24gKyBcIilyZXR1cm4gbnVsbDtcIik7IH07XG5cbnZhciBtb2RpZmllckNvZGUgPSB7XG4gIHN0b3A6ICckZXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7JyxcbiAgcHJldmVudDogJyRldmVudC5wcmV2ZW50RGVmYXVsdCgpOycsXG4gIHNlbGY6IGdlbkd1YXJkKFwiJGV2ZW50LnRhcmdldCAhPT0gJGV2ZW50LmN1cnJlbnRUYXJnZXRcIiksXG4gIGN0cmw6IGdlbkd1YXJkKFwiISRldmVudC5jdHJsS2V5XCIpLFxuICBzaGlmdDogZ2VuR3VhcmQoXCIhJGV2ZW50LnNoaWZ0S2V5XCIpLFxuICBhbHQ6IGdlbkd1YXJkKFwiISRldmVudC5hbHRLZXlcIiksXG4gIG1ldGE6IGdlbkd1YXJkKFwiISRldmVudC5tZXRhS2V5XCIpLFxuICBsZWZ0OiBnZW5HdWFyZChcIididXR0b24nIGluICRldmVudCAmJiAkZXZlbnQuYnV0dG9uICE9PSAwXCIpLFxuICBtaWRkbGU6IGdlbkd1YXJkKFwiJ2J1dHRvbicgaW4gJGV2ZW50ICYmICRldmVudC5idXR0b24gIT09IDFcIiksXG4gIHJpZ2h0OiBnZW5HdWFyZChcIididXR0b24nIGluICRldmVudCAmJiAkZXZlbnQuYnV0dG9uICE9PSAyXCIpXG59O1xuXG5mdW5jdGlvbiBnZW5IYW5kbGVycyAoXG4gIGV2ZW50cyxcbiAgaXNOYXRpdmUsXG4gIHdhcm5cbikge1xuICB2YXIgcmVzID0gaXNOYXRpdmUgPyAnbmF0aXZlT246eycgOiAnb246eyc7XG4gIGZvciAodmFyIG5hbWUgaW4gZXZlbnRzKSB7XG4gICAgdmFyIGhhbmRsZXIgPSBldmVudHNbbmFtZV07XG4gICAgLy8gIzUzMzA6IHdhcm4gY2xpY2sucmlnaHQsIHNpbmNlIHJpZ2h0IGNsaWNrcyBkbyBub3QgYWN0dWFsbHkgZmlyZSBjbGljayBldmVudHMuXG4gICAgaWYgKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicgJiZcbiAgICAgIG5hbWUgPT09ICdjbGljaycgJiZcbiAgICAgIGhhbmRsZXIgJiYgaGFuZGxlci5tb2RpZmllcnMgJiYgaGFuZGxlci5tb2RpZmllcnMucmlnaHRcbiAgICApIHtcbiAgICAgIHdhcm4oXG4gICAgICAgIFwiVXNlIFxcXCJjb250ZXh0bWVudVxcXCIgaW5zdGVhZCBvZiBcXFwiY2xpY2sucmlnaHRcXFwiIHNpbmNlIHJpZ2h0IGNsaWNrcyBcIiArXG4gICAgICAgIFwiZG8gbm90IGFjdHVhbGx5IGZpcmUgXFxcImNsaWNrXFxcIiBldmVudHMuXCJcbiAgICAgICk7XG4gICAgfVxuICAgIHJlcyArPSBcIlxcXCJcIiArIG5hbWUgKyBcIlxcXCI6XCIgKyAoZ2VuSGFuZGxlcihuYW1lLCBoYW5kbGVyKSkgKyBcIixcIjtcbiAgfVxuICByZXR1cm4gcmVzLnNsaWNlKDAsIC0xKSArICd9J1xufVxuXG5mdW5jdGlvbiBnZW5IYW5kbGVyIChcbiAgbmFtZSxcbiAgaGFuZGxlclxuKSB7XG4gIGlmICghaGFuZGxlcikge1xuICAgIHJldHVybiAnZnVuY3Rpb24oKXt9J1xuICB9XG5cbiAgaWYgKEFycmF5LmlzQXJyYXkoaGFuZGxlcikpIHtcbiAgICByZXR1cm4gKFwiW1wiICsgKGhhbmRsZXIubWFwKGZ1bmN0aW9uIChoYW5kbGVyKSB7IHJldHVybiBnZW5IYW5kbGVyKG5hbWUsIGhhbmRsZXIpOyB9KS5qb2luKCcsJykpICsgXCJdXCIpXG4gIH1cblxuICB2YXIgaXNNZXRob2RQYXRoID0gc2ltcGxlUGF0aFJFLnRlc3QoaGFuZGxlci52YWx1ZSk7XG4gIHZhciBpc0Z1bmN0aW9uRXhwcmVzc2lvbiA9IGZuRXhwUkUudGVzdChoYW5kbGVyLnZhbHVlKTtcblxuICBpZiAoIWhhbmRsZXIubW9kaWZpZXJzKSB7XG4gICAgcmV0dXJuIGlzTWV0aG9kUGF0aCB8fCBpc0Z1bmN0aW9uRXhwcmVzc2lvblxuICAgICAgPyBoYW5kbGVyLnZhbHVlXG4gICAgICA6IChcImZ1bmN0aW9uKCRldmVudCl7XCIgKyAoaGFuZGxlci52YWx1ZSkgKyBcIn1cIikgLy8gaW5saW5lIHN0YXRlbWVudFxuICB9IGVsc2Uge1xuICAgIHZhciBjb2RlID0gJyc7XG4gICAgdmFyIGdlbk1vZGlmaWVyQ29kZSA9ICcnO1xuICAgIHZhciBrZXlzID0gW107XG4gICAgZm9yICh2YXIga2V5IGluIGhhbmRsZXIubW9kaWZpZXJzKSB7XG4gICAgICBpZiAobW9kaWZpZXJDb2RlW2tleV0pIHtcbiAgICAgICAgZ2VuTW9kaWZpZXJDb2RlICs9IG1vZGlmaWVyQ29kZVtrZXldO1xuICAgICAgICAvLyBsZWZ0L3JpZ2h0XG4gICAgICAgIGlmIChrZXlDb2Rlc1trZXldKSB7XG4gICAgICAgICAga2V5cy5wdXNoKGtleSk7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGtleXMucHVzaChrZXkpO1xuICAgICAgfVxuICAgIH1cbiAgICBpZiAoa2V5cy5sZW5ndGgpIHtcbiAgICAgIGNvZGUgKz0gZ2VuS2V5RmlsdGVyKGtleXMpO1xuICAgIH1cbiAgICAvLyBNYWtlIHN1cmUgbW9kaWZpZXJzIGxpa2UgcHJldmVudCBhbmQgc3RvcCBnZXQgZXhlY3V0ZWQgYWZ0ZXIga2V5IGZpbHRlcmluZ1xuICAgIGlmIChnZW5Nb2RpZmllckNvZGUpIHtcbiAgICAgIGNvZGUgKz0gZ2VuTW9kaWZpZXJDb2RlO1xuICAgIH1cbiAgICB2YXIgaGFuZGxlckNvZGUgPSBpc01ldGhvZFBhdGhcbiAgICAgID8gaGFuZGxlci52YWx1ZSArICcoJGV2ZW50KSdcbiAgICAgIDogaXNGdW5jdGlvbkV4cHJlc3Npb25cbiAgICAgICAgPyAoXCIoXCIgKyAoaGFuZGxlci52YWx1ZSkgKyBcIikoJGV2ZW50KVwiKVxuICAgICAgICA6IGhhbmRsZXIudmFsdWU7XG4gICAgcmV0dXJuIChcImZ1bmN0aW9uKCRldmVudCl7XCIgKyBjb2RlICsgaGFuZGxlckNvZGUgKyBcIn1cIilcbiAgfVxufVxuXG5mdW5jdGlvbiBnZW5LZXlGaWx0ZXIgKGtleXMpIHtcbiAgcmV0dXJuIChcImlmKCEoJ2J1dHRvbicgaW4gJGV2ZW50KSYmXCIgKyAoa2V5cy5tYXAoZ2VuRmlsdGVyQ29kZSkuam9pbignJiYnKSkgKyBcIilyZXR1cm4gbnVsbDtcIilcbn1cblxuZnVuY3Rpb24gZ2VuRmlsdGVyQ29kZSAoa2V5KSB7XG4gIHZhciBrZXlWYWwgPSBwYXJzZUludChrZXksIDEwKTtcbiAgaWYgKGtleVZhbCkge1xuICAgIHJldHVybiAoXCIkZXZlbnQua2V5Q29kZSE9PVwiICsga2V5VmFsKVxuICB9XG4gIHZhciBhbGlhcyA9IGtleUNvZGVzW2tleV07XG4gIHJldHVybiAoXCJfaygkZXZlbnQua2V5Q29kZSxcIiArIChKU09OLnN0cmluZ2lmeShrZXkpKSArIChhbGlhcyA/ICcsJyArIEpTT04uc3RyaW5naWZ5KGFsaWFzKSA6ICcnKSArIFwiKVwiKVxufVxuXG4vKiAgKi9cblxuZnVuY3Rpb24gb24gKGVsLCBkaXIpIHtcbiAgaWYgKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicgJiYgZGlyLm1vZGlmaWVycykge1xuICAgIHdhcm4oXCJ2LW9uIHdpdGhvdXQgYXJndW1lbnQgZG9lcyBub3Qgc3VwcG9ydCBtb2RpZmllcnMuXCIpO1xuICB9XG4gIGVsLndyYXBMaXN0ZW5lcnMgPSBmdW5jdGlvbiAoY29kZSkgeyByZXR1cm4gKFwiX2coXCIgKyBjb2RlICsgXCIsXCIgKyAoZGlyLnZhbHVlKSArIFwiKVwiKTsgfTtcbn1cblxuLyogICovXG5cbmZ1bmN0aW9uIGJpbmQkMSAoZWwsIGRpcikge1xuICBlbC53cmFwRGF0YSA9IGZ1bmN0aW9uIChjb2RlKSB7XG4gICAgcmV0dXJuIChcIl9iKFwiICsgY29kZSArIFwiLCdcIiArIChlbC50YWcpICsgXCInLFwiICsgKGRpci52YWx1ZSkgKyBcIixcIiArIChkaXIubW9kaWZpZXJzICYmIGRpci5tb2RpZmllcnMucHJvcCA/ICd0cnVlJyA6ICdmYWxzZScpICsgKGRpci5tb2RpZmllcnMgJiYgZGlyLm1vZGlmaWVycy5zeW5jID8gJyx0cnVlJyA6ICcnKSArIFwiKVwiKVxuICB9O1xufVxuXG4vKiAgKi9cblxudmFyIGJhc2VEaXJlY3RpdmVzID0ge1xuICBvbjogb24sXG4gIGJpbmQ6IGJpbmQkMSxcbiAgY2xvYWs6IG5vb3Bcbn07XG5cbi8qICAqL1xuXG52YXIgQ29kZWdlblN0YXRlID0gZnVuY3Rpb24gQ29kZWdlblN0YXRlIChvcHRpb25zKSB7XG4gIHRoaXMub3B0aW9ucyA9IG9wdGlvbnM7XG4gIHRoaXMud2FybiA9IG9wdGlvbnMud2FybiB8fCBiYXNlV2FybjtcbiAgdGhpcy50cmFuc2Zvcm1zID0gcGx1Y2tNb2R1bGVGdW5jdGlvbihvcHRpb25zLm1vZHVsZXMsICd0cmFuc2Zvcm1Db2RlJyk7XG4gIHRoaXMuZGF0YUdlbkZucyA9IHBsdWNrTW9kdWxlRnVuY3Rpb24ob3B0aW9ucy5tb2R1bGVzLCAnZ2VuRGF0YScpO1xuICB0aGlzLmRpcmVjdGl2ZXMgPSBleHRlbmQoZXh0ZW5kKHt9LCBiYXNlRGlyZWN0aXZlcyksIG9wdGlvbnMuZGlyZWN0aXZlcyk7XG4gIHZhciBpc1Jlc2VydmVkVGFnID0gb3B0aW9ucy5pc1Jlc2VydmVkVGFnIHx8IG5vO1xuICB0aGlzLm1heWJlQ29tcG9uZW50ID0gZnVuY3Rpb24gKGVsKSB7IHJldHVybiAhaXNSZXNlcnZlZFRhZyhlbC50YWcpOyB9O1xuICB0aGlzLm9uY2VJZCA9IDA7XG4gIHRoaXMuc3RhdGljUmVuZGVyRm5zID0gW107XG59O1xuXG5cblxuZnVuY3Rpb24gZ2VuZXJhdGUgKFxuICBhc3QsXG4gIG9wdGlvbnNcbikge1xuICB2YXIgc3RhdGUgPSBuZXcgQ29kZWdlblN0YXRlKG9wdGlvbnMpO1xuICB2YXIgY29kZSA9IGFzdCA/IGdlbkVsZW1lbnQoYXN0LCBzdGF0ZSkgOiAnX2MoXCJkaXZcIiknO1xuICByZXR1cm4ge1xuICAgIHJlbmRlcjogKFwid2l0aCh0aGlzKXtyZXR1cm4gXCIgKyBjb2RlICsgXCJ9XCIpLFxuICAgIHN0YXRpY1JlbmRlckZuczogc3RhdGUuc3RhdGljUmVuZGVyRm5zXG4gIH1cbn1cblxuZnVuY3Rpb24gZ2VuRWxlbWVudCAoZWwsIHN0YXRlKSB7XG4gIGlmIChlbC5zdGF0aWNSb290ICYmICFlbC5zdGF0aWNQcm9jZXNzZWQpIHtcbiAgICByZXR1cm4gZ2VuU3RhdGljKGVsLCBzdGF0ZSlcbiAgfSBlbHNlIGlmIChlbC5vbmNlICYmICFlbC5vbmNlUHJvY2Vzc2VkKSB7XG4gICAgcmV0dXJuIGdlbk9uY2UoZWwsIHN0YXRlKVxuICB9IGVsc2UgaWYgKGVsLmZvciAmJiAhZWwuZm9yUHJvY2Vzc2VkKSB7XG4gICAgcmV0dXJuIGdlbkZvcihlbCwgc3RhdGUpXG4gIH0gZWxzZSBpZiAoZWwuaWYgJiYgIWVsLmlmUHJvY2Vzc2VkKSB7XG4gICAgcmV0dXJuIGdlbklmKGVsLCBzdGF0ZSlcbiAgfSBlbHNlIGlmIChlbC50YWcgPT09ICd0ZW1wbGF0ZScgJiYgIWVsLnNsb3RUYXJnZXQpIHtcbiAgICByZXR1cm4gZ2VuQ2hpbGRyZW4oZWwsIHN0YXRlKSB8fCAndm9pZCAwJ1xuICB9IGVsc2UgaWYgKGVsLnRhZyA9PT0gJ3Nsb3QnKSB7XG4gICAgcmV0dXJuIGdlblNsb3QoZWwsIHN0YXRlKVxuICB9IGVsc2Uge1xuICAgIC8vIGNvbXBvbmVudCBvciBlbGVtZW50XG4gICAgdmFyIGNvZGU7XG4gICAgaWYgKGVsLmNvbXBvbmVudCkge1xuICAgICAgY29kZSA9IGdlbkNvbXBvbmVudChlbC5jb21wb25lbnQsIGVsLCBzdGF0ZSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHZhciBkYXRhID0gZWwucGxhaW4gPyB1bmRlZmluZWQgOiBnZW5EYXRhJDIoZWwsIHN0YXRlKTtcblxuICAgICAgdmFyIGNoaWxkcmVuID0gZWwuaW5saW5lVGVtcGxhdGUgPyBudWxsIDogZ2VuQ2hpbGRyZW4oZWwsIHN0YXRlLCB0cnVlKTtcbiAgICAgIGNvZGUgPSBcIl9jKCdcIiArIChlbC50YWcpICsgXCInXCIgKyAoZGF0YSA/IChcIixcIiArIGRhdGEpIDogJycpICsgKGNoaWxkcmVuID8gKFwiLFwiICsgY2hpbGRyZW4pIDogJycpICsgXCIpXCI7XG4gICAgfVxuICAgIC8vIG1vZHVsZSB0cmFuc2Zvcm1zXG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBzdGF0ZS50cmFuc2Zvcm1zLmxlbmd0aDsgaSsrKSB7XG4gICAgICBjb2RlID0gc3RhdGUudHJhbnNmb3Jtc1tpXShlbCwgY29kZSk7XG4gICAgfVxuICAgIHJldHVybiBjb2RlXG4gIH1cbn1cblxuLy8gaG9pc3Qgc3RhdGljIHN1Yi10cmVlcyBvdXRcbmZ1bmN0aW9uIGdlblN0YXRpYyAoZWwsIHN0YXRlKSB7XG4gIGVsLnN0YXRpY1Byb2Nlc3NlZCA9IHRydWU7XG4gIHN0YXRlLnN0YXRpY1JlbmRlckZucy5wdXNoKChcIndpdGgodGhpcyl7cmV0dXJuIFwiICsgKGdlbkVsZW1lbnQoZWwsIHN0YXRlKSkgKyBcIn1cIikpO1xuICByZXR1cm4gKFwiX20oXCIgKyAoc3RhdGUuc3RhdGljUmVuZGVyRm5zLmxlbmd0aCAtIDEpICsgKGVsLnN0YXRpY0luRm9yID8gJyx0cnVlJyA6ICcnKSArIFwiKVwiKVxufVxuXG4vLyB2LW9uY2VcbmZ1bmN0aW9uIGdlbk9uY2UgKGVsLCBzdGF0ZSkge1xuICBlbC5vbmNlUHJvY2Vzc2VkID0gdHJ1ZTtcbiAgaWYgKGVsLmlmICYmICFlbC5pZlByb2Nlc3NlZCkge1xuICAgIHJldHVybiBnZW5JZihlbCwgc3RhdGUpXG4gIH0gZWxzZSBpZiAoZWwuc3RhdGljSW5Gb3IpIHtcbiAgICB2YXIga2V5ID0gJyc7XG4gICAgdmFyIHBhcmVudCA9IGVsLnBhcmVudDtcbiAgICB3aGlsZSAocGFyZW50KSB7XG4gICAgICBpZiAocGFyZW50LmZvcikge1xuICAgICAgICBrZXkgPSBwYXJlbnQua2V5O1xuICAgICAgICBicmVha1xuICAgICAgfVxuICAgICAgcGFyZW50ID0gcGFyZW50LnBhcmVudDtcbiAgICB9XG4gICAgaWYgKCFrZXkpIHtcbiAgICAgIHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicgJiYgc3RhdGUud2FybihcbiAgICAgICAgXCJ2LW9uY2UgY2FuIG9ubHkgYmUgdXNlZCBpbnNpZGUgdi1mb3IgdGhhdCBpcyBrZXllZC4gXCJcbiAgICAgICk7XG4gICAgICByZXR1cm4gZ2VuRWxlbWVudChlbCwgc3RhdGUpXG4gICAgfVxuICAgIHJldHVybiAoXCJfbyhcIiArIChnZW5FbGVtZW50KGVsLCBzdGF0ZSkpICsgXCIsXCIgKyAoc3RhdGUub25jZUlkKyspICsgXCIsXCIgKyBrZXkgKyBcIilcIilcbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gZ2VuU3RhdGljKGVsLCBzdGF0ZSlcbiAgfVxufVxuXG5mdW5jdGlvbiBnZW5JZiAoXG4gIGVsLFxuICBzdGF0ZSxcbiAgYWx0R2VuLFxuICBhbHRFbXB0eVxuKSB7XG4gIGVsLmlmUHJvY2Vzc2VkID0gdHJ1ZTsgLy8gYXZvaWQgcmVjdXJzaW9uXG4gIHJldHVybiBnZW5JZkNvbmRpdGlvbnMoZWwuaWZDb25kaXRpb25zLnNsaWNlKCksIHN0YXRlLCBhbHRHZW4sIGFsdEVtcHR5KVxufVxuXG5mdW5jdGlvbiBnZW5JZkNvbmRpdGlvbnMgKFxuICBjb25kaXRpb25zLFxuICBzdGF0ZSxcbiAgYWx0R2VuLFxuICBhbHRFbXB0eVxuKSB7XG4gIGlmICghY29uZGl0aW9ucy5sZW5ndGgpIHtcbiAgICByZXR1cm4gYWx0RW1wdHkgfHwgJ19lKCknXG4gIH1cblxuICB2YXIgY29uZGl0aW9uID0gY29uZGl0aW9ucy5zaGlmdCgpO1xuICBpZiAoY29uZGl0aW9uLmV4cCkge1xuICAgIHJldHVybiAoXCIoXCIgKyAoY29uZGl0aW9uLmV4cCkgKyBcIik/XCIgKyAoZ2VuVGVybmFyeUV4cChjb25kaXRpb24uYmxvY2spKSArIFwiOlwiICsgKGdlbklmQ29uZGl0aW9ucyhjb25kaXRpb25zLCBzdGF0ZSwgYWx0R2VuLCBhbHRFbXB0eSkpKVxuICB9IGVsc2Uge1xuICAgIHJldHVybiAoXCJcIiArIChnZW5UZXJuYXJ5RXhwKGNvbmRpdGlvbi5ibG9jaykpKVxuICB9XG5cbiAgLy8gdi1pZiB3aXRoIHYtb25jZSBzaG91bGQgZ2VuZXJhdGUgY29kZSBsaWtlIChhKT9fbSgwKTpfbSgxKVxuICBmdW5jdGlvbiBnZW5UZXJuYXJ5RXhwIChlbCkge1xuICAgIHJldHVybiBhbHRHZW5cbiAgICAgID8gYWx0R2VuKGVsLCBzdGF0ZSlcbiAgICAgIDogZWwub25jZVxuICAgICAgICA/IGdlbk9uY2UoZWwsIHN0YXRlKVxuICAgICAgICA6IGdlbkVsZW1lbnQoZWwsIHN0YXRlKVxuICB9XG59XG5cbmZ1bmN0aW9uIGdlbkZvciAoXG4gIGVsLFxuICBzdGF0ZSxcbiAgYWx0R2VuLFxuICBhbHRIZWxwZXJcbikge1xuICB2YXIgZXhwID0gZWwuZm9yO1xuICB2YXIgYWxpYXMgPSBlbC5hbGlhcztcbiAgdmFyIGl0ZXJhdG9yMSA9IGVsLml0ZXJhdG9yMSA/IChcIixcIiArIChlbC5pdGVyYXRvcjEpKSA6ICcnO1xuICB2YXIgaXRlcmF0b3IyID0gZWwuaXRlcmF0b3IyID8gKFwiLFwiICsgKGVsLml0ZXJhdG9yMikpIDogJyc7XG5cbiAgaWYgKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicgJiZcbiAgICBzdGF0ZS5tYXliZUNvbXBvbmVudChlbCkgJiZcbiAgICBlbC50YWcgIT09ICdzbG90JyAmJlxuICAgIGVsLnRhZyAhPT0gJ3RlbXBsYXRlJyAmJlxuICAgICFlbC5rZXlcbiAgKSB7XG4gICAgc3RhdGUud2FybihcbiAgICAgIFwiPFwiICsgKGVsLnRhZykgKyBcIiB2LWZvcj1cXFwiXCIgKyBhbGlhcyArIFwiIGluIFwiICsgZXhwICsgXCJcXFwiPjogY29tcG9uZW50IGxpc3RzIHJlbmRlcmVkIHdpdGggXCIgK1xuICAgICAgXCJ2LWZvciBzaG91bGQgaGF2ZSBleHBsaWNpdCBrZXlzLiBcIiArXG4gICAgICBcIlNlZSBodHRwczovL3Z1ZWpzLm9yZy9ndWlkZS9saXN0Lmh0bWwja2V5IGZvciBtb3JlIGluZm8uXCIsXG4gICAgICB0cnVlIC8qIHRpcCAqL1xuICAgICk7XG4gIH1cblxuICBlbC5mb3JQcm9jZXNzZWQgPSB0cnVlOyAvLyBhdm9pZCByZWN1cnNpb25cbiAgcmV0dXJuIChhbHRIZWxwZXIgfHwgJ19sJykgKyBcIigoXCIgKyBleHAgKyBcIiksXCIgK1xuICAgIFwiZnVuY3Rpb24oXCIgKyBhbGlhcyArIGl0ZXJhdG9yMSArIGl0ZXJhdG9yMiArIFwiKXtcIiArXG4gICAgICBcInJldHVybiBcIiArICgoYWx0R2VuIHx8IGdlbkVsZW1lbnQpKGVsLCBzdGF0ZSkpICtcbiAgICAnfSknXG59XG5cbmZ1bmN0aW9uIGdlbkRhdGEkMiAoZWwsIHN0YXRlKSB7XG4gIHZhciBkYXRhID0gJ3snO1xuXG4gIC8vIGRpcmVjdGl2ZXMgZmlyc3QuXG4gIC8vIGRpcmVjdGl2ZXMgbWF5IG11dGF0ZSB0aGUgZWwncyBvdGhlciBwcm9wZXJ0aWVzIGJlZm9yZSB0aGV5IGFyZSBnZW5lcmF0ZWQuXG4gIHZhciBkaXJzID0gZ2VuRGlyZWN0aXZlcyhlbCwgc3RhdGUpO1xuICBpZiAoZGlycykgeyBkYXRhICs9IGRpcnMgKyAnLCc7IH1cblxuICAvLyBrZXlcbiAgaWYgKGVsLmtleSkge1xuICAgIGRhdGEgKz0gXCJrZXk6XCIgKyAoZWwua2V5KSArIFwiLFwiO1xuICB9XG4gIC8vIHJlZlxuICBpZiAoZWwucmVmKSB7XG4gICAgZGF0YSArPSBcInJlZjpcIiArIChlbC5yZWYpICsgXCIsXCI7XG4gIH1cbiAgaWYgKGVsLnJlZkluRm9yKSB7XG4gICAgZGF0YSArPSBcInJlZkluRm9yOnRydWUsXCI7XG4gIH1cbiAgLy8gcHJlXG4gIGlmIChlbC5wcmUpIHtcbiAgICBkYXRhICs9IFwicHJlOnRydWUsXCI7XG4gIH1cbiAgLy8gcmVjb3JkIG9yaWdpbmFsIHRhZyBuYW1lIGZvciBjb21wb25lbnRzIHVzaW5nIFwiaXNcIiBhdHRyaWJ1dGVcbiAgaWYgKGVsLmNvbXBvbmVudCkge1xuICAgIGRhdGEgKz0gXCJ0YWc6XFxcIlwiICsgKGVsLnRhZykgKyBcIlxcXCIsXCI7XG4gIH1cbiAgLy8gbW9kdWxlIGRhdGEgZ2VuZXJhdGlvbiBmdW5jdGlvbnNcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBzdGF0ZS5kYXRhR2VuRm5zLmxlbmd0aDsgaSsrKSB7XG4gICAgZGF0YSArPSBzdGF0ZS5kYXRhR2VuRm5zW2ldKGVsKTtcbiAgfVxuICAvLyBhdHRyaWJ1dGVzXG4gIGlmIChlbC5hdHRycykge1xuICAgIGRhdGEgKz0gXCJhdHRyczp7XCIgKyAoZ2VuUHJvcHMoZWwuYXR0cnMpKSArIFwifSxcIjtcbiAgfVxuICAvLyBET00gcHJvcHNcbiAgaWYgKGVsLnByb3BzKSB7XG4gICAgZGF0YSArPSBcImRvbVByb3BzOntcIiArIChnZW5Qcm9wcyhlbC5wcm9wcykpICsgXCJ9LFwiO1xuICB9XG4gIC8vIGV2ZW50IGhhbmRsZXJzXG4gIGlmIChlbC5ldmVudHMpIHtcbiAgICBkYXRhICs9IChnZW5IYW5kbGVycyhlbC5ldmVudHMsIGZhbHNlLCBzdGF0ZS53YXJuKSkgKyBcIixcIjtcbiAgfVxuICBpZiAoZWwubmF0aXZlRXZlbnRzKSB7XG4gICAgZGF0YSArPSAoZ2VuSGFuZGxlcnMoZWwubmF0aXZlRXZlbnRzLCB0cnVlLCBzdGF0ZS53YXJuKSkgKyBcIixcIjtcbiAgfVxuICAvLyBzbG90IHRhcmdldFxuICBpZiAoZWwuc2xvdFRhcmdldCkge1xuICAgIGRhdGEgKz0gXCJzbG90OlwiICsgKGVsLnNsb3RUYXJnZXQpICsgXCIsXCI7XG4gIH1cbiAgLy8gc2NvcGVkIHNsb3RzXG4gIGlmIChlbC5zY29wZWRTbG90cykge1xuICAgIGRhdGEgKz0gKGdlblNjb3BlZFNsb3RzKGVsLnNjb3BlZFNsb3RzLCBzdGF0ZSkpICsgXCIsXCI7XG4gIH1cbiAgLy8gY29tcG9uZW50IHYtbW9kZWxcbiAgaWYgKGVsLm1vZGVsKSB7XG4gICAgZGF0YSArPSBcIm1vZGVsOnt2YWx1ZTpcIiArIChlbC5tb2RlbC52YWx1ZSkgKyBcIixjYWxsYmFjazpcIiArIChlbC5tb2RlbC5jYWxsYmFjaykgKyBcIixleHByZXNzaW9uOlwiICsgKGVsLm1vZGVsLmV4cHJlc3Npb24pICsgXCJ9LFwiO1xuICB9XG4gIC8vIGlubGluZS10ZW1wbGF0ZVxuICBpZiAoZWwuaW5saW5lVGVtcGxhdGUpIHtcbiAgICB2YXIgaW5saW5lVGVtcGxhdGUgPSBnZW5JbmxpbmVUZW1wbGF0ZShlbCwgc3RhdGUpO1xuICAgIGlmIChpbmxpbmVUZW1wbGF0ZSkge1xuICAgICAgZGF0YSArPSBpbmxpbmVUZW1wbGF0ZSArIFwiLFwiO1xuICAgIH1cbiAgfVxuICBkYXRhID0gZGF0YS5yZXBsYWNlKC8sJC8sICcnKSArICd9JztcbiAgLy8gdi1iaW5kIGRhdGEgd3JhcFxuICBpZiAoZWwud3JhcERhdGEpIHtcbiAgICBkYXRhID0gZWwud3JhcERhdGEoZGF0YSk7XG4gIH1cbiAgLy8gdi1vbiBkYXRhIHdyYXBcbiAgaWYgKGVsLndyYXBMaXN0ZW5lcnMpIHtcbiAgICBkYXRhID0gZWwud3JhcExpc3RlbmVycyhkYXRhKTtcbiAgfVxuICByZXR1cm4gZGF0YVxufVxuXG5mdW5jdGlvbiBnZW5EaXJlY3RpdmVzIChlbCwgc3RhdGUpIHtcbiAgdmFyIGRpcnMgPSBlbC5kaXJlY3RpdmVzO1xuICBpZiAoIWRpcnMpIHsgcmV0dXJuIH1cbiAgdmFyIHJlcyA9ICdkaXJlY3RpdmVzOlsnO1xuICB2YXIgaGFzUnVudGltZSA9IGZhbHNlO1xuICB2YXIgaSwgbCwgZGlyLCBuZWVkUnVudGltZTtcbiAgZm9yIChpID0gMCwgbCA9IGRpcnMubGVuZ3RoOyBpIDwgbDsgaSsrKSB7XG4gICAgZGlyID0gZGlyc1tpXTtcbiAgICBuZWVkUnVudGltZSA9IHRydWU7XG4gICAgdmFyIGdlbiA9IHN0YXRlLmRpcmVjdGl2ZXNbZGlyLm5hbWVdO1xuICAgIGlmIChnZW4pIHtcbiAgICAgIC8vIGNvbXBpbGUtdGltZSBkaXJlY3RpdmUgdGhhdCBtYW5pcHVsYXRlcyBBU1QuXG4gICAgICAvLyByZXR1cm5zIHRydWUgaWYgaXQgYWxzbyBuZWVkcyBhIHJ1bnRpbWUgY291bnRlcnBhcnQuXG4gICAgICBuZWVkUnVudGltZSA9ICEhZ2VuKGVsLCBkaXIsIHN0YXRlLndhcm4pO1xuICAgIH1cbiAgICBpZiAobmVlZFJ1bnRpbWUpIHtcbiAgICAgIGhhc1J1bnRpbWUgPSB0cnVlO1xuICAgICAgcmVzICs9IFwie25hbWU6XFxcIlwiICsgKGRpci5uYW1lKSArIFwiXFxcIixyYXdOYW1lOlxcXCJcIiArIChkaXIucmF3TmFtZSkgKyBcIlxcXCJcIiArIChkaXIudmFsdWUgPyAoXCIsdmFsdWU6KFwiICsgKGRpci52YWx1ZSkgKyBcIiksZXhwcmVzc2lvbjpcIiArIChKU09OLnN0cmluZ2lmeShkaXIudmFsdWUpKSkgOiAnJykgKyAoZGlyLmFyZyA/IChcIixhcmc6XFxcIlwiICsgKGRpci5hcmcpICsgXCJcXFwiXCIpIDogJycpICsgKGRpci5tb2RpZmllcnMgPyAoXCIsbW9kaWZpZXJzOlwiICsgKEpTT04uc3RyaW5naWZ5KGRpci5tb2RpZmllcnMpKSkgOiAnJykgKyBcIn0sXCI7XG4gICAgfVxuICB9XG4gIGlmIChoYXNSdW50aW1lKSB7XG4gICAgcmV0dXJuIHJlcy5zbGljZSgwLCAtMSkgKyAnXSdcbiAgfVxufVxuXG5mdW5jdGlvbiBnZW5JbmxpbmVUZW1wbGF0ZSAoZWwsIHN0YXRlKSB7XG4gIHZhciBhc3QgPSBlbC5jaGlsZHJlblswXTtcbiAgaWYgKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicgJiYgKFxuICAgIGVsLmNoaWxkcmVuLmxlbmd0aCA+IDEgfHwgYXN0LnR5cGUgIT09IDFcbiAgKSkge1xuICAgIHN0YXRlLndhcm4oJ0lubGluZS10ZW1wbGF0ZSBjb21wb25lbnRzIG11c3QgaGF2ZSBleGFjdGx5IG9uZSBjaGlsZCBlbGVtZW50LicpO1xuICB9XG4gIGlmIChhc3QudHlwZSA9PT0gMSkge1xuICAgIHZhciBpbmxpbmVSZW5kZXJGbnMgPSBnZW5lcmF0ZShhc3QsIHN0YXRlLm9wdGlvbnMpO1xuICAgIHJldHVybiAoXCJpbmxpbmVUZW1wbGF0ZTp7cmVuZGVyOmZ1bmN0aW9uKCl7XCIgKyAoaW5saW5lUmVuZGVyRm5zLnJlbmRlcikgKyBcIn0sc3RhdGljUmVuZGVyRm5zOltcIiArIChpbmxpbmVSZW5kZXJGbnMuc3RhdGljUmVuZGVyRm5zLm1hcChmdW5jdGlvbiAoY29kZSkgeyByZXR1cm4gKFwiZnVuY3Rpb24oKXtcIiArIGNvZGUgKyBcIn1cIik7IH0pLmpvaW4oJywnKSkgKyBcIl19XCIpXG4gIH1cbn1cblxuZnVuY3Rpb24gZ2VuU2NvcGVkU2xvdHMgKFxuICBzbG90cyxcbiAgc3RhdGVcbikge1xuICByZXR1cm4gKFwic2NvcGVkU2xvdHM6X3UoW1wiICsgKE9iamVjdC5rZXlzKHNsb3RzKS5tYXAoZnVuY3Rpb24gKGtleSkge1xuICAgICAgcmV0dXJuIGdlblNjb3BlZFNsb3Qoa2V5LCBzbG90c1trZXldLCBzdGF0ZSlcbiAgICB9KS5qb2luKCcsJykpICsgXCJdKVwiKVxufVxuXG5mdW5jdGlvbiBnZW5TY29wZWRTbG90IChcbiAga2V5LFxuICBlbCxcbiAgc3RhdGVcbikge1xuICBpZiAoZWwuZm9yICYmICFlbC5mb3JQcm9jZXNzZWQpIHtcbiAgICByZXR1cm4gZ2VuRm9yU2NvcGVkU2xvdChrZXksIGVsLCBzdGF0ZSlcbiAgfVxuICByZXR1cm4gXCJ7a2V5OlwiICsga2V5ICsgXCIsZm46ZnVuY3Rpb24oXCIgKyAoU3RyaW5nKGVsLmF0dHJzTWFwLnNjb3BlKSkgKyBcIil7XCIgK1xuICAgIFwicmV0dXJuIFwiICsgKGVsLnRhZyA9PT0gJ3RlbXBsYXRlJ1xuICAgICAgPyBnZW5DaGlsZHJlbihlbCwgc3RhdGUpIHx8ICd2b2lkIDAnXG4gICAgICA6IGdlbkVsZW1lbnQoZWwsIHN0YXRlKSkgKyBcIn19XCJcbn1cblxuZnVuY3Rpb24gZ2VuRm9yU2NvcGVkU2xvdCAoXG4gIGtleSxcbiAgZWwsXG4gIHN0YXRlXG4pIHtcbiAgdmFyIGV4cCA9IGVsLmZvcjtcbiAgdmFyIGFsaWFzID0gZWwuYWxpYXM7XG4gIHZhciBpdGVyYXRvcjEgPSBlbC5pdGVyYXRvcjEgPyAoXCIsXCIgKyAoZWwuaXRlcmF0b3IxKSkgOiAnJztcbiAgdmFyIGl0ZXJhdG9yMiA9IGVsLml0ZXJhdG9yMiA/IChcIixcIiArIChlbC5pdGVyYXRvcjIpKSA6ICcnO1xuICBlbC5mb3JQcm9jZXNzZWQgPSB0cnVlOyAvLyBhdm9pZCByZWN1cnNpb25cbiAgcmV0dXJuIFwiX2woKFwiICsgZXhwICsgXCIpLFwiICtcbiAgICBcImZ1bmN0aW9uKFwiICsgYWxpYXMgKyBpdGVyYXRvcjEgKyBpdGVyYXRvcjIgKyBcIil7XCIgK1xuICAgICAgXCJyZXR1cm4gXCIgKyAoZ2VuU2NvcGVkU2xvdChrZXksIGVsLCBzdGF0ZSkpICtcbiAgICAnfSknXG59XG5cbmZ1bmN0aW9uIGdlbkNoaWxkcmVuIChcbiAgZWwsXG4gIHN0YXRlLFxuICBjaGVja1NraXAsXG4gIGFsdEdlbkVsZW1lbnQsXG4gIGFsdEdlbk5vZGVcbikge1xuICB2YXIgY2hpbGRyZW4gPSBlbC5jaGlsZHJlbjtcbiAgaWYgKGNoaWxkcmVuLmxlbmd0aCkge1xuICAgIHZhciBlbCQxID0gY2hpbGRyZW5bMF07XG4gICAgLy8gb3B0aW1pemUgc2luZ2xlIHYtZm9yXG4gICAgaWYgKGNoaWxkcmVuLmxlbmd0aCA9PT0gMSAmJlxuICAgICAgZWwkMS5mb3IgJiZcbiAgICAgIGVsJDEudGFnICE9PSAndGVtcGxhdGUnICYmXG4gICAgICBlbCQxLnRhZyAhPT0gJ3Nsb3QnXG4gICAgKSB7XG4gICAgICByZXR1cm4gKGFsdEdlbkVsZW1lbnQgfHwgZ2VuRWxlbWVudCkoZWwkMSwgc3RhdGUpXG4gICAgfVxuICAgIHZhciBub3JtYWxpemF0aW9uVHlwZSA9IGNoZWNrU2tpcFxuICAgICAgPyBnZXROb3JtYWxpemF0aW9uVHlwZShjaGlsZHJlbiwgc3RhdGUubWF5YmVDb21wb25lbnQpXG4gICAgICA6IDA7XG4gICAgdmFyIGdlbiA9IGFsdEdlbk5vZGUgfHwgZ2VuTm9kZTtcbiAgICByZXR1cm4gKFwiW1wiICsgKGNoaWxkcmVuLm1hcChmdW5jdGlvbiAoYykgeyByZXR1cm4gZ2VuKGMsIHN0YXRlKTsgfSkuam9pbignLCcpKSArIFwiXVwiICsgKG5vcm1hbGl6YXRpb25UeXBlID8gKFwiLFwiICsgbm9ybWFsaXphdGlvblR5cGUpIDogJycpKVxuICB9XG59XG5cbi8vIGRldGVybWluZSB0aGUgbm9ybWFsaXphdGlvbiBuZWVkZWQgZm9yIHRoZSBjaGlsZHJlbiBhcnJheS5cbi8vIDA6IG5vIG5vcm1hbGl6YXRpb24gbmVlZGVkXG4vLyAxOiBzaW1wbGUgbm9ybWFsaXphdGlvbiBuZWVkZWQgKHBvc3NpYmxlIDEtbGV2ZWwgZGVlcCBuZXN0ZWQgYXJyYXkpXG4vLyAyOiBmdWxsIG5vcm1hbGl6YXRpb24gbmVlZGVkXG5mdW5jdGlvbiBnZXROb3JtYWxpemF0aW9uVHlwZSAoXG4gIGNoaWxkcmVuLFxuICBtYXliZUNvbXBvbmVudFxuKSB7XG4gIHZhciByZXMgPSAwO1xuICBmb3IgKHZhciBpID0gMDsgaSA8IGNoaWxkcmVuLmxlbmd0aDsgaSsrKSB7XG4gICAgdmFyIGVsID0gY2hpbGRyZW5baV07XG4gICAgaWYgKGVsLnR5cGUgIT09IDEpIHtcbiAgICAgIGNvbnRpbnVlXG4gICAgfVxuICAgIGlmIChuZWVkc05vcm1hbGl6YXRpb24oZWwpIHx8XG4gICAgICAgIChlbC5pZkNvbmRpdGlvbnMgJiYgZWwuaWZDb25kaXRpb25zLnNvbWUoZnVuY3Rpb24gKGMpIHsgcmV0dXJuIG5lZWRzTm9ybWFsaXphdGlvbihjLmJsb2NrKTsgfSkpKSB7XG4gICAgICByZXMgPSAyO1xuICAgICAgYnJlYWtcbiAgICB9XG4gICAgaWYgKG1heWJlQ29tcG9uZW50KGVsKSB8fFxuICAgICAgICAoZWwuaWZDb25kaXRpb25zICYmIGVsLmlmQ29uZGl0aW9ucy5zb21lKGZ1bmN0aW9uIChjKSB7IHJldHVybiBtYXliZUNvbXBvbmVudChjLmJsb2NrKTsgfSkpKSB7XG4gICAgICByZXMgPSAxO1xuICAgIH1cbiAgfVxuICByZXR1cm4gcmVzXG59XG5cbmZ1bmN0aW9uIG5lZWRzTm9ybWFsaXphdGlvbiAoZWwpIHtcbiAgcmV0dXJuIGVsLmZvciAhPT0gdW5kZWZpbmVkIHx8IGVsLnRhZyA9PT0gJ3RlbXBsYXRlJyB8fCBlbC50YWcgPT09ICdzbG90J1xufVxuXG5mdW5jdGlvbiBnZW5Ob2RlIChub2RlLCBzdGF0ZSkge1xuICBpZiAobm9kZS50eXBlID09PSAxKSB7XG4gICAgcmV0dXJuIGdlbkVsZW1lbnQobm9kZSwgc3RhdGUpXG4gIH0gaWYgKG5vZGUudHlwZSA9PT0gMyAmJiBub2RlLmlzQ29tbWVudCkge1xuICAgIHJldHVybiBnZW5Db21tZW50KG5vZGUpXG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIGdlblRleHQobm9kZSlcbiAgfVxufVxuXG5mdW5jdGlvbiBnZW5UZXh0ICh0ZXh0KSB7XG4gIHJldHVybiAoXCJfdihcIiArICh0ZXh0LnR5cGUgPT09IDJcbiAgICA/IHRleHQuZXhwcmVzc2lvbiAvLyBubyBuZWVkIGZvciAoKSBiZWNhdXNlIGFscmVhZHkgd3JhcHBlZCBpbiBfcygpXG4gICAgOiB0cmFuc2Zvcm1TcGVjaWFsTmV3bGluZXMoSlNPTi5zdHJpbmdpZnkodGV4dC50ZXh0KSkpICsgXCIpXCIpXG59XG5cbmZ1bmN0aW9uIGdlbkNvbW1lbnQgKGNvbW1lbnQpIHtcbiAgcmV0dXJuIChcIl9lKFwiICsgKEpTT04uc3RyaW5naWZ5KGNvbW1lbnQudGV4dCkpICsgXCIpXCIpXG59XG5cbmZ1bmN0aW9uIGdlblNsb3QgKGVsLCBzdGF0ZSkge1xuICB2YXIgc2xvdE5hbWUgPSBlbC5zbG90TmFtZSB8fCAnXCJkZWZhdWx0XCInO1xuICB2YXIgY2hpbGRyZW4gPSBnZW5DaGlsZHJlbihlbCwgc3RhdGUpO1xuICB2YXIgcmVzID0gXCJfdChcIiArIHNsb3ROYW1lICsgKGNoaWxkcmVuID8gKFwiLFwiICsgY2hpbGRyZW4pIDogJycpO1xuICB2YXIgYXR0cnMgPSBlbC5hdHRycyAmJiAoXCJ7XCIgKyAoZWwuYXR0cnMubWFwKGZ1bmN0aW9uIChhKSB7IHJldHVybiAoKGNhbWVsaXplKGEubmFtZSkpICsgXCI6XCIgKyAoYS52YWx1ZSkpOyB9KS5qb2luKCcsJykpICsgXCJ9XCIpO1xuICB2YXIgYmluZCQkMSA9IGVsLmF0dHJzTWFwWyd2LWJpbmQnXTtcbiAgaWYgKChhdHRycyB8fCBiaW5kJCQxKSAmJiAhY2hpbGRyZW4pIHtcbiAgICByZXMgKz0gXCIsbnVsbFwiO1xuICB9XG4gIGlmIChhdHRycykge1xuICAgIHJlcyArPSBcIixcIiArIGF0dHJzO1xuICB9XG4gIGlmIChiaW5kJCQxKSB7XG4gICAgcmVzICs9IChhdHRycyA/ICcnIDogJyxudWxsJykgKyBcIixcIiArIGJpbmQkJDE7XG4gIH1cbiAgcmV0dXJuIHJlcyArICcpJ1xufVxuXG4vLyBjb21wb25lbnROYW1lIGlzIGVsLmNvbXBvbmVudCwgdGFrZSBpdCBhcyBhcmd1bWVudCB0byBzaHVuIGZsb3cncyBwZXNzaW1pc3RpYyByZWZpbmVtZW50XG5mdW5jdGlvbiBnZW5Db21wb25lbnQgKFxuICBjb21wb25lbnROYW1lLFxuICBlbCxcbiAgc3RhdGVcbikge1xuICB2YXIgY2hpbGRyZW4gPSBlbC5pbmxpbmVUZW1wbGF0ZSA/IG51bGwgOiBnZW5DaGlsZHJlbihlbCwgc3RhdGUsIHRydWUpO1xuICByZXR1cm4gKFwiX2MoXCIgKyBjb21wb25lbnROYW1lICsgXCIsXCIgKyAoZ2VuRGF0YSQyKGVsLCBzdGF0ZSkpICsgKGNoaWxkcmVuID8gKFwiLFwiICsgY2hpbGRyZW4pIDogJycpICsgXCIpXCIpXG59XG5cbmZ1bmN0aW9uIGdlblByb3BzIChwcm9wcykge1xuICB2YXIgcmVzID0gJyc7XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgcHJvcHMubGVuZ3RoOyBpKyspIHtcbiAgICB2YXIgcHJvcCA9IHByb3BzW2ldO1xuICAgIHJlcyArPSBcIlxcXCJcIiArIChwcm9wLm5hbWUpICsgXCJcXFwiOlwiICsgKHRyYW5zZm9ybVNwZWNpYWxOZXdsaW5lcyhwcm9wLnZhbHVlKSkgKyBcIixcIjtcbiAgfVxuICByZXR1cm4gcmVzLnNsaWNlKDAsIC0xKVxufVxuXG4vLyAjMzg5NSwgIzQyNjhcbmZ1bmN0aW9uIHRyYW5zZm9ybVNwZWNpYWxOZXdsaW5lcyAodGV4dCkge1xuICByZXR1cm4gdGV4dFxuICAgIC5yZXBsYWNlKC9cXHUyMDI4L2csICdcXFxcdTIwMjgnKVxuICAgIC5yZXBsYWNlKC9cXHUyMDI5L2csICdcXFxcdTIwMjknKVxufVxuXG4vKiAgKi9cblxuLy8gdGhlc2Uga2V5d29yZHMgc2hvdWxkIG5vdCBhcHBlYXIgaW5zaWRlIGV4cHJlc3Npb25zLCBidXQgb3BlcmF0b3JzIGxpa2Vcbi8vIHR5cGVvZiwgaW5zdGFuY2VvZiBhbmQgaW4gYXJlIGFsbG93ZWRcbnZhciBwcm9oaWJpdGVkS2V5d29yZFJFID0gbmV3IFJlZ0V4cCgnXFxcXGInICsgKFxuICAnZG8saWYsZm9yLGxldCxuZXcsdHJ5LHZhcixjYXNlLGVsc2Usd2l0aCxhd2FpdCxicmVhayxjYXRjaCxjbGFzcyxjb25zdCwnICtcbiAgJ3N1cGVyLHRocm93LHdoaWxlLHlpZWxkLGRlbGV0ZSxleHBvcnQsaW1wb3J0LHJldHVybixzd2l0Y2gsZGVmYXVsdCwnICtcbiAgJ2V4dGVuZHMsZmluYWxseSxjb250aW51ZSxkZWJ1Z2dlcixmdW5jdGlvbixhcmd1bWVudHMnXG4pLnNwbGl0KCcsJykuam9pbignXFxcXGJ8XFxcXGInKSArICdcXFxcYicpO1xuXG4vLyB0aGVzZSB1bmFyeSBvcGVyYXRvcnMgc2hvdWxkIG5vdCBiZSB1c2VkIGFzIHByb3BlcnR5L21ldGhvZCBuYW1lc1xudmFyIHVuYXJ5T3BlcmF0b3JzUkUgPSBuZXcgUmVnRXhwKCdcXFxcYicgKyAoXG4gICdkZWxldGUsdHlwZW9mLHZvaWQnXG4pLnNwbGl0KCcsJykuam9pbignXFxcXHMqXFxcXChbXlxcXFwpXSpcXFxcKXxcXFxcYicpICsgJ1xcXFxzKlxcXFwoW15cXFxcKV0qXFxcXCknKTtcblxuLy8gY2hlY2sgdmFsaWQgaWRlbnRpZmllciBmb3Igdi1mb3JcbnZhciBpZGVudFJFID0gL1tBLVphLXpfJF1bXFx3JF0qLztcblxuLy8gc3RyaXAgc3RyaW5ncyBpbiBleHByZXNzaW9uc1xudmFyIHN0cmlwU3RyaW5nUkUgPSAvJyg/OlteJ1xcXFxdfFxcXFwuKSonfFwiKD86W15cIlxcXFxdfFxcXFwuKSpcInxgKD86W15gXFxcXF18XFxcXC4pKlxcJFxce3xcXH0oPzpbXmBcXFxcXXxcXFxcLikqYHxgKD86W15gXFxcXF18XFxcXC4pKmAvZztcblxuLy8gZGV0ZWN0IHByb2JsZW1hdGljIGV4cHJlc3Npb25zIGluIGEgdGVtcGxhdGVcbmZ1bmN0aW9uIGRldGVjdEVycm9ycyAoYXN0KSB7XG4gIHZhciBlcnJvcnMgPSBbXTtcbiAgaWYgKGFzdCkge1xuICAgIGNoZWNrTm9kZShhc3QsIGVycm9ycyk7XG4gIH1cbiAgcmV0dXJuIGVycm9yc1xufVxuXG5mdW5jdGlvbiBjaGVja05vZGUgKG5vZGUsIGVycm9ycykge1xuICBpZiAobm9kZS50eXBlID09PSAxKSB7XG4gICAgZm9yICh2YXIgbmFtZSBpbiBub2RlLmF0dHJzTWFwKSB7XG4gICAgICBpZiAoZGlyUkUudGVzdChuYW1lKSkge1xuICAgICAgICB2YXIgdmFsdWUgPSBub2RlLmF0dHJzTWFwW25hbWVdO1xuICAgICAgICBpZiAodmFsdWUpIHtcbiAgICAgICAgICBpZiAobmFtZSA9PT0gJ3YtZm9yJykge1xuICAgICAgICAgICAgY2hlY2tGb3Iobm9kZSwgKFwidi1mb3I9XFxcIlwiICsgdmFsdWUgKyBcIlxcXCJcIiksIGVycm9ycyk7XG4gICAgICAgICAgfSBlbHNlIGlmIChvblJFLnRlc3QobmFtZSkpIHtcbiAgICAgICAgICAgIGNoZWNrRXZlbnQodmFsdWUsIChuYW1lICsgXCI9XFxcIlwiICsgdmFsdWUgKyBcIlxcXCJcIiksIGVycm9ycyk7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGNoZWNrRXhwcmVzc2lvbih2YWx1ZSwgKG5hbWUgKyBcIj1cXFwiXCIgKyB2YWx1ZSArIFwiXFxcIlwiKSwgZXJyb3JzKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gICAgaWYgKG5vZGUuY2hpbGRyZW4pIHtcbiAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbm9kZS5jaGlsZHJlbi5sZW5ndGg7IGkrKykge1xuICAgICAgICBjaGVja05vZGUobm9kZS5jaGlsZHJlbltpXSwgZXJyb3JzKTtcbiAgICAgIH1cbiAgICB9XG4gIH0gZWxzZSBpZiAobm9kZS50eXBlID09PSAyKSB7XG4gICAgY2hlY2tFeHByZXNzaW9uKG5vZGUuZXhwcmVzc2lvbiwgbm9kZS50ZXh0LCBlcnJvcnMpO1xuICB9XG59XG5cbmZ1bmN0aW9uIGNoZWNrRXZlbnQgKGV4cCwgdGV4dCwgZXJyb3JzKSB7XG4gIHZhciBzdGlwcGVkID0gZXhwLnJlcGxhY2Uoc3RyaXBTdHJpbmdSRSwgJycpO1xuICB2YXIga2V5d29yZE1hdGNoID0gc3RpcHBlZC5tYXRjaCh1bmFyeU9wZXJhdG9yc1JFKTtcbiAgaWYgKGtleXdvcmRNYXRjaCAmJiBzdGlwcGVkLmNoYXJBdChrZXl3b3JkTWF0Y2guaW5kZXggLSAxKSAhPT0gJyQnKSB7XG4gICAgZXJyb3JzLnB1c2goXG4gICAgICBcImF2b2lkIHVzaW5nIEphdmFTY3JpcHQgdW5hcnkgb3BlcmF0b3IgYXMgcHJvcGVydHkgbmFtZTogXCIgK1xuICAgICAgXCJcXFwiXCIgKyAoa2V5d29yZE1hdGNoWzBdKSArIFwiXFxcIiBpbiBleHByZXNzaW9uIFwiICsgKHRleHQudHJpbSgpKVxuICAgICk7XG4gIH1cbiAgY2hlY2tFeHByZXNzaW9uKGV4cCwgdGV4dCwgZXJyb3JzKTtcbn1cblxuZnVuY3Rpb24gY2hlY2tGb3IgKG5vZGUsIHRleHQsIGVycm9ycykge1xuICBjaGVja0V4cHJlc3Npb24obm9kZS5mb3IgfHwgJycsIHRleHQsIGVycm9ycyk7XG4gIGNoZWNrSWRlbnRpZmllcihub2RlLmFsaWFzLCAndi1mb3IgYWxpYXMnLCB0ZXh0LCBlcnJvcnMpO1xuICBjaGVja0lkZW50aWZpZXIobm9kZS5pdGVyYXRvcjEsICd2LWZvciBpdGVyYXRvcicsIHRleHQsIGVycm9ycyk7XG4gIGNoZWNrSWRlbnRpZmllcihub2RlLml0ZXJhdG9yMiwgJ3YtZm9yIGl0ZXJhdG9yJywgdGV4dCwgZXJyb3JzKTtcbn1cblxuZnVuY3Rpb24gY2hlY2tJZGVudGlmaWVyIChpZGVudCwgdHlwZSwgdGV4dCwgZXJyb3JzKSB7XG4gIGlmICh0eXBlb2YgaWRlbnQgPT09ICdzdHJpbmcnICYmICFpZGVudFJFLnRlc3QoaWRlbnQpKSB7XG4gICAgZXJyb3JzLnB1c2goKFwiaW52YWxpZCBcIiArIHR5cGUgKyBcIiBcXFwiXCIgKyBpZGVudCArIFwiXFxcIiBpbiBleHByZXNzaW9uOiBcIiArICh0ZXh0LnRyaW0oKSkpKTtcbiAgfVxufVxuXG5mdW5jdGlvbiBjaGVja0V4cHJlc3Npb24gKGV4cCwgdGV4dCwgZXJyb3JzKSB7XG4gIHRyeSB7XG4gICAgbmV3IEZ1bmN0aW9uKChcInJldHVybiBcIiArIGV4cCkpO1xuICB9IGNhdGNoIChlKSB7XG4gICAgdmFyIGtleXdvcmRNYXRjaCA9IGV4cC5yZXBsYWNlKHN0cmlwU3RyaW5nUkUsICcnKS5tYXRjaChwcm9oaWJpdGVkS2V5d29yZFJFKTtcbiAgICBpZiAoa2V5d29yZE1hdGNoKSB7XG4gICAgICBlcnJvcnMucHVzaChcbiAgICAgICAgXCJhdm9pZCB1c2luZyBKYXZhU2NyaXB0IGtleXdvcmQgYXMgcHJvcGVydHkgbmFtZTogXCIgK1xuICAgICAgICBcIlxcXCJcIiArIChrZXl3b3JkTWF0Y2hbMF0pICsgXCJcXFwiIGluIGV4cHJlc3Npb24gXCIgKyAodGV4dC50cmltKCkpXG4gICAgICApO1xuICAgIH0gZWxzZSB7XG4gICAgICBlcnJvcnMucHVzaCgoXCJpbnZhbGlkIGV4cHJlc3Npb246IFwiICsgKHRleHQudHJpbSgpKSkpO1xuICAgIH1cbiAgfVxufVxuXG4vKiAgKi9cblxuZnVuY3Rpb24gY3JlYXRlRnVuY3Rpb24gKGNvZGUsIGVycm9ycykge1xuICB0cnkge1xuICAgIHJldHVybiBuZXcgRnVuY3Rpb24oY29kZSlcbiAgfSBjYXRjaCAoZXJyKSB7XG4gICAgZXJyb3JzLnB1c2goeyBlcnI6IGVyciwgY29kZTogY29kZSB9KTtcbiAgICByZXR1cm4gbm9vcFxuICB9XG59XG5cbmZ1bmN0aW9uIGNyZWF0ZUNvbXBpbGVUb0Z1bmN0aW9uRm4gKGNvbXBpbGUpIHtcbiAgdmFyIGNhY2hlID0gT2JqZWN0LmNyZWF0ZShudWxsKTtcblxuICByZXR1cm4gZnVuY3Rpb24gY29tcGlsZVRvRnVuY3Rpb25zIChcbiAgICB0ZW1wbGF0ZSxcbiAgICBvcHRpb25zLFxuICAgIHZtXG4gICkge1xuICAgIG9wdGlvbnMgPSBvcHRpb25zIHx8IHt9O1xuXG4gICAgLyogaXN0YW5idWwgaWdub3JlIGlmICovXG4gICAgaWYgKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicpIHtcbiAgICAgIC8vIGRldGVjdCBwb3NzaWJsZSBDU1AgcmVzdHJpY3Rpb25cbiAgICAgIHRyeSB7XG4gICAgICAgIG5ldyBGdW5jdGlvbigncmV0dXJuIDEnKTtcbiAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgaWYgKGUudG9TdHJpbmcoKS5tYXRjaCgvdW5zYWZlLWV2YWx8Q1NQLykpIHtcbiAgICAgICAgICB3YXJuKFxuICAgICAgICAgICAgJ0l0IHNlZW1zIHlvdSBhcmUgdXNpbmcgdGhlIHN0YW5kYWxvbmUgYnVpbGQgb2YgVnVlLmpzIGluIGFuICcgK1xuICAgICAgICAgICAgJ2Vudmlyb25tZW50IHdpdGggQ29udGVudCBTZWN1cml0eSBQb2xpY3kgdGhhdCBwcm9oaWJpdHMgdW5zYWZlLWV2YWwuICcgK1xuICAgICAgICAgICAgJ1RoZSB0ZW1wbGF0ZSBjb21waWxlciBjYW5ub3Qgd29yayBpbiB0aGlzIGVudmlyb25tZW50LiBDb25zaWRlciAnICtcbiAgICAgICAgICAgICdyZWxheGluZyB0aGUgcG9saWN5IHRvIGFsbG93IHVuc2FmZS1ldmFsIG9yIHByZS1jb21waWxpbmcgeW91ciAnICtcbiAgICAgICAgICAgICd0ZW1wbGF0ZXMgaW50byByZW5kZXIgZnVuY3Rpb25zLidcbiAgICAgICAgICApO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gY2hlY2sgY2FjaGVcbiAgICB2YXIga2V5ID0gb3B0aW9ucy5kZWxpbWl0ZXJzXG4gICAgICA/IFN0cmluZyhvcHRpb25zLmRlbGltaXRlcnMpICsgdGVtcGxhdGVcbiAgICAgIDogdGVtcGxhdGU7XG4gICAgaWYgKGNhY2hlW2tleV0pIHtcbiAgICAgIHJldHVybiBjYWNoZVtrZXldXG4gICAgfVxuXG4gICAgLy8gY29tcGlsZVxuICAgIHZhciBjb21waWxlZCA9IGNvbXBpbGUodGVtcGxhdGUsIG9wdGlvbnMpO1xuXG4gICAgLy8gY2hlY2sgY29tcGlsYXRpb24gZXJyb3JzL3RpcHNcbiAgICBpZiAocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJykge1xuICAgICAgaWYgKGNvbXBpbGVkLmVycm9ycyAmJiBjb21waWxlZC5lcnJvcnMubGVuZ3RoKSB7XG4gICAgICAgIHdhcm4oXG4gICAgICAgICAgXCJFcnJvciBjb21waWxpbmcgdGVtcGxhdGU6XFxuXFxuXCIgKyB0ZW1wbGF0ZSArIFwiXFxuXFxuXCIgK1xuICAgICAgICAgIGNvbXBpbGVkLmVycm9ycy5tYXAoZnVuY3Rpb24gKGUpIHsgcmV0dXJuIChcIi0gXCIgKyBlKTsgfSkuam9pbignXFxuJykgKyAnXFxuJyxcbiAgICAgICAgICB2bVxuICAgICAgICApO1xuICAgICAgfVxuICAgICAgaWYgKGNvbXBpbGVkLnRpcHMgJiYgY29tcGlsZWQudGlwcy5sZW5ndGgpIHtcbiAgICAgICAgY29tcGlsZWQudGlwcy5mb3JFYWNoKGZ1bmN0aW9uIChtc2cpIHsgcmV0dXJuIHRpcChtc2csIHZtKTsgfSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gdHVybiBjb2RlIGludG8gZnVuY3Rpb25zXG4gICAgdmFyIHJlcyA9IHt9O1xuICAgIHZhciBmbkdlbkVycm9ycyA9IFtdO1xuICAgIHJlcy5yZW5kZXIgPSBjcmVhdGVGdW5jdGlvbihjb21waWxlZC5yZW5kZXIsIGZuR2VuRXJyb3JzKTtcbiAgICByZXMuc3RhdGljUmVuZGVyRm5zID0gY29tcGlsZWQuc3RhdGljUmVuZGVyRm5zLm1hcChmdW5jdGlvbiAoY29kZSkge1xuICAgICAgcmV0dXJuIGNyZWF0ZUZ1bmN0aW9uKGNvZGUsIGZuR2VuRXJyb3JzKVxuICAgIH0pO1xuXG4gICAgLy8gY2hlY2sgZnVuY3Rpb24gZ2VuZXJhdGlvbiBlcnJvcnMuXG4gICAgLy8gdGhpcyBzaG91bGQgb25seSBoYXBwZW4gaWYgdGhlcmUgaXMgYSBidWcgaW4gdGhlIGNvbXBpbGVyIGl0c2VsZi5cbiAgICAvLyBtb3N0bHkgZm9yIGNvZGVnZW4gZGV2ZWxvcG1lbnQgdXNlXG4gICAgLyogaXN0YW5idWwgaWdub3JlIGlmICovXG4gICAgaWYgKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicpIHtcbiAgICAgIGlmICgoIWNvbXBpbGVkLmVycm9ycyB8fCAhY29tcGlsZWQuZXJyb3JzLmxlbmd0aCkgJiYgZm5HZW5FcnJvcnMubGVuZ3RoKSB7XG4gICAgICAgIHdhcm4oXG4gICAgICAgICAgXCJGYWlsZWQgdG8gZ2VuZXJhdGUgcmVuZGVyIGZ1bmN0aW9uOlxcblxcblwiICtcbiAgICAgICAgICBmbkdlbkVycm9ycy5tYXAoZnVuY3Rpb24gKHJlZikge1xuICAgICAgICAgICAgdmFyIGVyciA9IHJlZi5lcnI7XG4gICAgICAgICAgICB2YXIgY29kZSA9IHJlZi5jb2RlO1xuXG4gICAgICAgICAgICByZXR1cm4gKChlcnIudG9TdHJpbmcoKSkgKyBcIiBpblxcblxcblwiICsgY29kZSArIFwiXFxuXCIpO1xuICAgICAgICB9KS5qb2luKCdcXG4nKSxcbiAgICAgICAgICB2bVxuICAgICAgICApO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiAoY2FjaGVba2V5XSA9IHJlcylcbiAgfVxufVxuXG4vKiAgKi9cblxuZnVuY3Rpb24gY3JlYXRlQ29tcGlsZXJDcmVhdG9yIChiYXNlQ29tcGlsZSkge1xuICByZXR1cm4gZnVuY3Rpb24gY3JlYXRlQ29tcGlsZXIgKGJhc2VPcHRpb25zKSB7XG4gICAgZnVuY3Rpb24gY29tcGlsZSAoXG4gICAgICB0ZW1wbGF0ZSxcbiAgICAgIG9wdGlvbnNcbiAgICApIHtcbiAgICAgIHZhciBmaW5hbE9wdGlvbnMgPSBPYmplY3QuY3JlYXRlKGJhc2VPcHRpb25zKTtcbiAgICAgIHZhciBlcnJvcnMgPSBbXTtcbiAgICAgIHZhciB0aXBzID0gW107XG4gICAgICBmaW5hbE9wdGlvbnMud2FybiA9IGZ1bmN0aW9uIChtc2csIHRpcCkge1xuICAgICAgICAodGlwID8gdGlwcyA6IGVycm9ycykucHVzaChtc2cpO1xuICAgICAgfTtcblxuICAgICAgaWYgKG9wdGlvbnMpIHtcbiAgICAgICAgLy8gbWVyZ2UgY3VzdG9tIG1vZHVsZXNcbiAgICAgICAgaWYgKG9wdGlvbnMubW9kdWxlcykge1xuICAgICAgICAgIGZpbmFsT3B0aW9ucy5tb2R1bGVzID1cbiAgICAgICAgICAgIChiYXNlT3B0aW9ucy5tb2R1bGVzIHx8IFtdKS5jb25jYXQob3B0aW9ucy5tb2R1bGVzKTtcbiAgICAgICAgfVxuICAgICAgICAvLyBtZXJnZSBjdXN0b20gZGlyZWN0aXZlc1xuICAgICAgICBpZiAob3B0aW9ucy5kaXJlY3RpdmVzKSB7XG4gICAgICAgICAgZmluYWxPcHRpb25zLmRpcmVjdGl2ZXMgPSBleHRlbmQoXG4gICAgICAgICAgICBPYmplY3QuY3JlYXRlKGJhc2VPcHRpb25zLmRpcmVjdGl2ZXMpLFxuICAgICAgICAgICAgb3B0aW9ucy5kaXJlY3RpdmVzXG4gICAgICAgICAgKTtcbiAgICAgICAgfVxuICAgICAgICAvLyBjb3B5IG90aGVyIG9wdGlvbnNcbiAgICAgICAgZm9yICh2YXIga2V5IGluIG9wdGlvbnMpIHtcbiAgICAgICAgICBpZiAoa2V5ICE9PSAnbW9kdWxlcycgJiYga2V5ICE9PSAnZGlyZWN0aXZlcycpIHtcbiAgICAgICAgICAgIGZpbmFsT3B0aW9uc1trZXldID0gb3B0aW9uc1trZXldO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICB2YXIgY29tcGlsZWQgPSBiYXNlQ29tcGlsZSh0ZW1wbGF0ZSwgZmluYWxPcHRpb25zKTtcbiAgICAgIGlmIChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nKSB7XG4gICAgICAgIGVycm9ycy5wdXNoLmFwcGx5KGVycm9ycywgZGV0ZWN0RXJyb3JzKGNvbXBpbGVkLmFzdCkpO1xuICAgICAgfVxuICAgICAgY29tcGlsZWQuZXJyb3JzID0gZXJyb3JzO1xuICAgICAgY29tcGlsZWQudGlwcyA9IHRpcHM7XG4gICAgICByZXR1cm4gY29tcGlsZWRcbiAgICB9XG5cbiAgICByZXR1cm4ge1xuICAgICAgY29tcGlsZTogY29tcGlsZSxcbiAgICAgIGNvbXBpbGVUb0Z1bmN0aW9uczogY3JlYXRlQ29tcGlsZVRvRnVuY3Rpb25Gbihjb21waWxlKVxuICAgIH1cbiAgfVxufVxuXG4vKiAgKi9cblxuLy8gYGNyZWF0ZUNvbXBpbGVyQ3JlYXRvcmAgYWxsb3dzIGNyZWF0aW5nIGNvbXBpbGVycyB0aGF0IHVzZSBhbHRlcm5hdGl2ZVxuLy8gcGFyc2VyL29wdGltaXplci9jb2RlZ2VuLCBlLmcgdGhlIFNTUiBvcHRpbWl6aW5nIGNvbXBpbGVyLlxuLy8gSGVyZSB3ZSBqdXN0IGV4cG9ydCBhIGRlZmF1bHQgY29tcGlsZXIgdXNpbmcgdGhlIGRlZmF1bHQgcGFydHMuXG52YXIgY3JlYXRlQ29tcGlsZXIgPSBjcmVhdGVDb21waWxlckNyZWF0b3IoZnVuY3Rpb24gYmFzZUNvbXBpbGUgKFxuICB0ZW1wbGF0ZSxcbiAgb3B0aW9uc1xuKSB7XG4gIHZhciBhc3QgPSBwYXJzZSh0ZW1wbGF0ZS50cmltKCksIG9wdGlvbnMpO1xuICBvcHRpbWl6ZShhc3QsIG9wdGlvbnMpO1xuICB2YXIgY29kZSA9IGdlbmVyYXRlKGFzdCwgb3B0aW9ucyk7XG4gIHJldHVybiB7XG4gICAgYXN0OiBhc3QsXG4gICAgcmVuZGVyOiBjb2RlLnJlbmRlcixcbiAgICBzdGF0aWNSZW5kZXJGbnM6IGNvZGUuc3RhdGljUmVuZGVyRm5zXG4gIH1cbn0pO1xuXG4vKiAgKi9cblxudmFyIHJlZiQxID0gY3JlYXRlQ29tcGlsZXIoYmFzZU9wdGlvbnMpO1xudmFyIGNvbXBpbGVUb0Z1bmN0aW9ucyA9IHJlZiQxLmNvbXBpbGVUb0Z1bmN0aW9ucztcblxuLyogICovXG5cbnZhciBpZFRvVGVtcGxhdGUgPSBjYWNoZWQoZnVuY3Rpb24gKGlkKSB7XG4gIHZhciBlbCA9IHF1ZXJ5KGlkKTtcbiAgcmV0dXJuIGVsICYmIGVsLmlubmVySFRNTFxufSk7XG5cbnZhciBtb3VudCA9IFZ1ZSQzLnByb3RvdHlwZS4kbW91bnQ7XG5WdWUkMy5wcm90b3R5cGUuJG1vdW50ID0gZnVuY3Rpb24gKFxuICBlbCxcbiAgaHlkcmF0aW5nXG4pIHtcbiAgZWwgPSBlbCAmJiBxdWVyeShlbCk7XG5cbiAgLyogaXN0YW5idWwgaWdub3JlIGlmICovXG4gIGlmIChlbCA9PT0gZG9jdW1lbnQuYm9keSB8fCBlbCA9PT0gZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50KSB7XG4gICAgcHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJyAmJiB3YXJuKFxuICAgICAgXCJEbyBub3QgbW91bnQgVnVlIHRvIDxodG1sPiBvciA8Ym9keT4gLSBtb3VudCB0byBub3JtYWwgZWxlbWVudHMgaW5zdGVhZC5cIlxuICAgICk7XG4gICAgcmV0dXJuIHRoaXNcbiAgfVxuXG4gIHZhciBvcHRpb25zID0gdGhpcy4kb3B0aW9ucztcbiAgLy8gcmVzb2x2ZSB0ZW1wbGF0ZS9lbCBhbmQgY29udmVydCB0byByZW5kZXIgZnVuY3Rpb25cbiAgaWYgKCFvcHRpb25zLnJlbmRlcikge1xuICAgIHZhciB0ZW1wbGF0ZSA9IG9wdGlvbnMudGVtcGxhdGU7XG4gICAgaWYgKHRlbXBsYXRlKSB7XG4gICAgICBpZiAodHlwZW9mIHRlbXBsYXRlID09PSAnc3RyaW5nJykge1xuICAgICAgICBpZiAodGVtcGxhdGUuY2hhckF0KDApID09PSAnIycpIHtcbiAgICAgICAgICB0ZW1wbGF0ZSA9IGlkVG9UZW1wbGF0ZSh0ZW1wbGF0ZSk7XG4gICAgICAgICAgLyogaXN0YW5idWwgaWdub3JlIGlmICovXG4gICAgICAgICAgaWYgKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicgJiYgIXRlbXBsYXRlKSB7XG4gICAgICAgICAgICB3YXJuKFxuICAgICAgICAgICAgICAoXCJUZW1wbGF0ZSBlbGVtZW50IG5vdCBmb3VuZCBvciBpcyBlbXB0eTogXCIgKyAob3B0aW9ucy50ZW1wbGF0ZSkpLFxuICAgICAgICAgICAgICB0aGlzXG4gICAgICAgICAgICApO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfSBlbHNlIGlmICh0ZW1wbGF0ZS5ub2RlVHlwZSkge1xuICAgICAgICB0ZW1wbGF0ZSA9IHRlbXBsYXRlLmlubmVySFRNTDtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGlmIChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nKSB7XG4gICAgICAgICAgd2FybignaW52YWxpZCB0ZW1wbGF0ZSBvcHRpb246JyArIHRlbXBsYXRlLCB0aGlzKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpc1xuICAgICAgfVxuICAgIH0gZWxzZSBpZiAoZWwpIHtcbiAgICAgIHRlbXBsYXRlID0gZ2V0T3V0ZXJIVE1MKGVsKTtcbiAgICB9XG4gICAgaWYgKHRlbXBsYXRlKSB7XG4gICAgICAvKiBpc3RhbmJ1bCBpZ25vcmUgaWYgKi9cbiAgICAgIGlmIChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nICYmIGNvbmZpZy5wZXJmb3JtYW5jZSAmJiBtYXJrKSB7XG4gICAgICAgIG1hcmsoJ2NvbXBpbGUnKTtcbiAgICAgIH1cblxuICAgICAgdmFyIHJlZiA9IGNvbXBpbGVUb0Z1bmN0aW9ucyh0ZW1wbGF0ZSwge1xuICAgICAgICBzaG91bGREZWNvZGVOZXdsaW5lczogc2hvdWxkRGVjb2RlTmV3bGluZXMsXG4gICAgICAgIGRlbGltaXRlcnM6IG9wdGlvbnMuZGVsaW1pdGVycyxcbiAgICAgICAgY29tbWVudHM6IG9wdGlvbnMuY29tbWVudHNcbiAgICAgIH0sIHRoaXMpO1xuICAgICAgdmFyIHJlbmRlciA9IHJlZi5yZW5kZXI7XG4gICAgICB2YXIgc3RhdGljUmVuZGVyRm5zID0gcmVmLnN0YXRpY1JlbmRlckZucztcbiAgICAgIG9wdGlvbnMucmVuZGVyID0gcmVuZGVyO1xuICAgICAgb3B0aW9ucy5zdGF0aWNSZW5kZXJGbnMgPSBzdGF0aWNSZW5kZXJGbnM7XG5cbiAgICAgIC8qIGlzdGFuYnVsIGlnbm9yZSBpZiAqL1xuICAgICAgaWYgKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicgJiYgY29uZmlnLnBlcmZvcm1hbmNlICYmIG1hcmspIHtcbiAgICAgICAgbWFyaygnY29tcGlsZSBlbmQnKTtcbiAgICAgICAgbWVhc3VyZSgoKHRoaXMuX25hbWUpICsgXCIgY29tcGlsZVwiKSwgJ2NvbXBpbGUnLCAnY29tcGlsZSBlbmQnKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cbiAgcmV0dXJuIG1vdW50LmNhbGwodGhpcywgZWwsIGh5ZHJhdGluZylcbn07XG5cbi8qKlxuICogR2V0IG91dGVySFRNTCBvZiBlbGVtZW50cywgdGFraW5nIGNhcmVcbiAqIG9mIFNWRyBlbGVtZW50cyBpbiBJRSBhcyB3ZWxsLlxuICovXG5mdW5jdGlvbiBnZXRPdXRlckhUTUwgKGVsKSB7XG4gIGlmIChlbC5vdXRlckhUTUwpIHtcbiAgICByZXR1cm4gZWwub3V0ZXJIVE1MXG4gIH0gZWxzZSB7XG4gICAgdmFyIGNvbnRhaW5lciA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuICAgIGNvbnRhaW5lci5hcHBlbmRDaGlsZChlbC5jbG9uZU5vZGUodHJ1ZSkpO1xuICAgIHJldHVybiBjb250YWluZXIuaW5uZXJIVE1MXG4gIH1cbn1cblxuVnVlJDMuY29tcGlsZSA9IGNvbXBpbGVUb0Z1bmN0aW9ucztcblxubW9kdWxlLmV4cG9ydHMgPSBWdWUkMztcblxuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIC4vbm9kZV9tb2R1bGVzL3Z1ZS9kaXN0L3Z1ZS5jb21tb24uanNcbi8vIG1vZHVsZSBpZCA9IDEyXG4vLyBtb2R1bGUgY2h1bmtzID0gMCIsIi8qIVxuICogdnVlLXJlc291cmNlIHYxLjMuNFxuICogaHR0cHM6Ly9naXRodWIuY29tL3BhZ2VraXQvdnVlLXJlc291cmNlXG4gKiBSZWxlYXNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG4gKi9cblxuLyoqXG4gKiBQcm9taXNlcy9BKyBwb2x5ZmlsbCB2MS4xLjQgKGh0dHBzOi8vZ2l0aHViLmNvbS9icmFtc3RlaW4vcHJvbWlzKVxuICovXG5cbnZhciBSRVNPTFZFRCA9IDA7XG52YXIgUkVKRUNURUQgPSAxO1xudmFyIFBFTkRJTkcgID0gMjtcblxuZnVuY3Rpb24gUHJvbWlzZSQxKGV4ZWN1dG9yKSB7XG5cbiAgICB0aGlzLnN0YXRlID0gUEVORElORztcbiAgICB0aGlzLnZhbHVlID0gdW5kZWZpbmVkO1xuICAgIHRoaXMuZGVmZXJyZWQgPSBbXTtcblxuICAgIHZhciBwcm9taXNlID0gdGhpcztcblxuICAgIHRyeSB7XG4gICAgICAgIGV4ZWN1dG9yKGZ1bmN0aW9uICh4KSB7XG4gICAgICAgICAgICBwcm9taXNlLnJlc29sdmUoeCk7XG4gICAgICAgIH0sIGZ1bmN0aW9uIChyKSB7XG4gICAgICAgICAgICBwcm9taXNlLnJlamVjdChyKTtcbiAgICAgICAgfSk7XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgICBwcm9taXNlLnJlamVjdChlKTtcbiAgICB9XG59XG5cblByb21pc2UkMS5yZWplY3QgPSBmdW5jdGlvbiAocikge1xuICAgIHJldHVybiBuZXcgUHJvbWlzZSQxKGZ1bmN0aW9uIChyZXNvbHZlLCByZWplY3QpIHtcbiAgICAgICAgcmVqZWN0KHIpO1xuICAgIH0pO1xufTtcblxuUHJvbWlzZSQxLnJlc29sdmUgPSBmdW5jdGlvbiAoeCkge1xuICAgIHJldHVybiBuZXcgUHJvbWlzZSQxKGZ1bmN0aW9uIChyZXNvbHZlLCByZWplY3QpIHtcbiAgICAgICAgcmVzb2x2ZSh4KTtcbiAgICB9KTtcbn07XG5cblByb21pc2UkMS5hbGwgPSBmdW5jdGlvbiBhbGwoaXRlcmFibGUpIHtcbiAgICByZXR1cm4gbmV3IFByb21pc2UkMShmdW5jdGlvbiAocmVzb2x2ZSwgcmVqZWN0KSB7XG4gICAgICAgIHZhciBjb3VudCA9IDAsIHJlc3VsdCA9IFtdO1xuXG4gICAgICAgIGlmIChpdGVyYWJsZS5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICAgIHJlc29sdmUocmVzdWx0KTtcbiAgICAgICAgfVxuXG4gICAgICAgIGZ1bmN0aW9uIHJlc29sdmVyKGkpIHtcbiAgICAgICAgICAgIHJldHVybiBmdW5jdGlvbiAoeCkge1xuICAgICAgICAgICAgICAgIHJlc3VsdFtpXSA9IHg7XG4gICAgICAgICAgICAgICAgY291bnQgKz0gMTtcblxuICAgICAgICAgICAgICAgIGlmIChjb3VudCA9PT0gaXRlcmFibGUubGVuZ3RoKSB7XG4gICAgICAgICAgICAgICAgICAgIHJlc29sdmUocmVzdWx0KTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9O1xuICAgICAgICB9XG5cbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBpdGVyYWJsZS5sZW5ndGg7IGkgKz0gMSkge1xuICAgICAgICAgICAgUHJvbWlzZSQxLnJlc29sdmUoaXRlcmFibGVbaV0pLnRoZW4ocmVzb2x2ZXIoaSksIHJlamVjdCk7XG4gICAgICAgIH1cbiAgICB9KTtcbn07XG5cblByb21pc2UkMS5yYWNlID0gZnVuY3Rpb24gcmFjZShpdGVyYWJsZSkge1xuICAgIHJldHVybiBuZXcgUHJvbWlzZSQxKGZ1bmN0aW9uIChyZXNvbHZlLCByZWplY3QpIHtcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBpdGVyYWJsZS5sZW5ndGg7IGkgKz0gMSkge1xuICAgICAgICAgICAgUHJvbWlzZSQxLnJlc29sdmUoaXRlcmFibGVbaV0pLnRoZW4ocmVzb2x2ZSwgcmVqZWN0KTtcbiAgICAgICAgfVxuICAgIH0pO1xufTtcblxudmFyIHAkMSA9IFByb21pc2UkMS5wcm90b3R5cGU7XG5cbnAkMS5yZXNvbHZlID0gZnVuY3Rpb24gcmVzb2x2ZSh4KSB7XG4gICAgdmFyIHByb21pc2UgPSB0aGlzO1xuXG4gICAgaWYgKHByb21pc2Uuc3RhdGUgPT09IFBFTkRJTkcpIHtcbiAgICAgICAgaWYgKHggPT09IHByb21pc2UpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ1Byb21pc2Ugc2V0dGxlZCB3aXRoIGl0c2VsZi4nKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHZhciBjYWxsZWQgPSBmYWxzZTtcblxuICAgICAgICB0cnkge1xuICAgICAgICAgICAgdmFyIHRoZW4gPSB4ICYmIHhbJ3RoZW4nXTtcblxuICAgICAgICAgICAgaWYgKHggIT09IG51bGwgJiYgdHlwZW9mIHggPT09ICdvYmplY3QnICYmIHR5cGVvZiB0aGVuID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgICAgICAgdGhlbi5jYWxsKHgsIGZ1bmN0aW9uICh4KSB7XG4gICAgICAgICAgICAgICAgICAgIGlmICghY2FsbGVkKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBwcm9taXNlLnJlc29sdmUoeCk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgY2FsbGVkID0gdHJ1ZTtcblxuICAgICAgICAgICAgICAgIH0sIGZ1bmN0aW9uIChyKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmICghY2FsbGVkKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBwcm9taXNlLnJlamVjdChyKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBjYWxsZWQgPSB0cnVlO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgICAgaWYgKCFjYWxsZWQpIHtcbiAgICAgICAgICAgICAgICBwcm9taXNlLnJlamVjdChlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIHByb21pc2Uuc3RhdGUgPSBSRVNPTFZFRDtcbiAgICAgICAgcHJvbWlzZS52YWx1ZSA9IHg7XG4gICAgICAgIHByb21pc2Uubm90aWZ5KCk7XG4gICAgfVxufTtcblxucCQxLnJlamVjdCA9IGZ1bmN0aW9uIHJlamVjdChyZWFzb24pIHtcbiAgICB2YXIgcHJvbWlzZSA9IHRoaXM7XG5cbiAgICBpZiAocHJvbWlzZS5zdGF0ZSA9PT0gUEVORElORykge1xuICAgICAgICBpZiAocmVhc29uID09PSBwcm9taXNlKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdQcm9taXNlIHNldHRsZWQgd2l0aCBpdHNlbGYuJyk7XG4gICAgICAgIH1cblxuICAgICAgICBwcm9taXNlLnN0YXRlID0gUkVKRUNURUQ7XG4gICAgICAgIHByb21pc2UudmFsdWUgPSByZWFzb247XG4gICAgICAgIHByb21pc2Uubm90aWZ5KCk7XG4gICAgfVxufTtcblxucCQxLm5vdGlmeSA9IGZ1bmN0aW9uIG5vdGlmeSgpIHtcbiAgICB2YXIgcHJvbWlzZSA9IHRoaXM7XG5cbiAgICBuZXh0VGljayhmdW5jdGlvbiAoKSB7XG4gICAgICAgIGlmIChwcm9taXNlLnN0YXRlICE9PSBQRU5ESU5HKSB7XG4gICAgICAgICAgICB3aGlsZSAocHJvbWlzZS5kZWZlcnJlZC5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgICB2YXIgZGVmZXJyZWQgPSBwcm9taXNlLmRlZmVycmVkLnNoaWZ0KCksXG4gICAgICAgICAgICAgICAgICAgIG9uUmVzb2x2ZWQgPSBkZWZlcnJlZFswXSxcbiAgICAgICAgICAgICAgICAgICAgb25SZWplY3RlZCA9IGRlZmVycmVkWzFdLFxuICAgICAgICAgICAgICAgICAgICByZXNvbHZlID0gZGVmZXJyZWRbMl0sXG4gICAgICAgICAgICAgICAgICAgIHJlamVjdCA9IGRlZmVycmVkWzNdO1xuXG4gICAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHByb21pc2Uuc3RhdGUgPT09IFJFU09MVkVEKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAodHlwZW9mIG9uUmVzb2x2ZWQgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXNvbHZlKG9uUmVzb2x2ZWQuY2FsbCh1bmRlZmluZWQsIHByb21pc2UudmFsdWUpKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZShwcm9taXNlLnZhbHVlKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChwcm9taXNlLnN0YXRlID09PSBSRUpFQ1RFRCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBvblJlamVjdGVkID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZShvblJlamVjdGVkLmNhbGwodW5kZWZpbmVkLCBwcm9taXNlLnZhbHVlKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdChwcm9taXNlLnZhbHVlKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgICAgICAgICAgcmVqZWN0KGUpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH0pO1xufTtcblxucCQxLnRoZW4gPSBmdW5jdGlvbiB0aGVuKG9uUmVzb2x2ZWQsIG9uUmVqZWN0ZWQpIHtcbiAgICB2YXIgcHJvbWlzZSA9IHRoaXM7XG5cbiAgICByZXR1cm4gbmV3IFByb21pc2UkMShmdW5jdGlvbiAocmVzb2x2ZSwgcmVqZWN0KSB7XG4gICAgICAgIHByb21pc2UuZGVmZXJyZWQucHVzaChbb25SZXNvbHZlZCwgb25SZWplY3RlZCwgcmVzb2x2ZSwgcmVqZWN0XSk7XG4gICAgICAgIHByb21pc2Uubm90aWZ5KCk7XG4gICAgfSk7XG59O1xuXG5wJDEuY2F0Y2ggPSBmdW5jdGlvbiAob25SZWplY3RlZCkge1xuICAgIHJldHVybiB0aGlzLnRoZW4odW5kZWZpbmVkLCBvblJlamVjdGVkKTtcbn07XG5cbi8qKlxuICogUHJvbWlzZSBhZGFwdGVyLlxuICovXG5cbmlmICh0eXBlb2YgUHJvbWlzZSA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICB3aW5kb3cuUHJvbWlzZSA9IFByb21pc2UkMTtcbn1cblxuZnVuY3Rpb24gUHJvbWlzZU9iaihleGVjdXRvciwgY29udGV4dCkge1xuXG4gICAgaWYgKGV4ZWN1dG9yIGluc3RhbmNlb2YgUHJvbWlzZSkge1xuICAgICAgICB0aGlzLnByb21pc2UgPSBleGVjdXRvcjtcbiAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLnByb21pc2UgPSBuZXcgUHJvbWlzZShleGVjdXRvci5iaW5kKGNvbnRleHQpKTtcbiAgICB9XG5cbiAgICB0aGlzLmNvbnRleHQgPSBjb250ZXh0O1xufVxuXG5Qcm9taXNlT2JqLmFsbCA9IGZ1bmN0aW9uIChpdGVyYWJsZSwgY29udGV4dCkge1xuICAgIHJldHVybiBuZXcgUHJvbWlzZU9iaihQcm9taXNlLmFsbChpdGVyYWJsZSksIGNvbnRleHQpO1xufTtcblxuUHJvbWlzZU9iai5yZXNvbHZlID0gZnVuY3Rpb24gKHZhbHVlLCBjb250ZXh0KSB7XG4gICAgcmV0dXJuIG5ldyBQcm9taXNlT2JqKFByb21pc2UucmVzb2x2ZSh2YWx1ZSksIGNvbnRleHQpO1xufTtcblxuUHJvbWlzZU9iai5yZWplY3QgPSBmdW5jdGlvbiAocmVhc29uLCBjb250ZXh0KSB7XG4gICAgcmV0dXJuIG5ldyBQcm9taXNlT2JqKFByb21pc2UucmVqZWN0KHJlYXNvbiksIGNvbnRleHQpO1xufTtcblxuUHJvbWlzZU9iai5yYWNlID0gZnVuY3Rpb24gKGl0ZXJhYmxlLCBjb250ZXh0KSB7XG4gICAgcmV0dXJuIG5ldyBQcm9taXNlT2JqKFByb21pc2UucmFjZShpdGVyYWJsZSksIGNvbnRleHQpO1xufTtcblxudmFyIHAgPSBQcm9taXNlT2JqLnByb3RvdHlwZTtcblxucC5iaW5kID0gZnVuY3Rpb24gKGNvbnRleHQpIHtcbiAgICB0aGlzLmNvbnRleHQgPSBjb250ZXh0O1xuICAgIHJldHVybiB0aGlzO1xufTtcblxucC50aGVuID0gZnVuY3Rpb24gKGZ1bGZpbGxlZCwgcmVqZWN0ZWQpIHtcblxuICAgIGlmIChmdWxmaWxsZWQgJiYgZnVsZmlsbGVkLmJpbmQgJiYgdGhpcy5jb250ZXh0KSB7XG4gICAgICAgIGZ1bGZpbGxlZCA9IGZ1bGZpbGxlZC5iaW5kKHRoaXMuY29udGV4dCk7XG4gICAgfVxuXG4gICAgaWYgKHJlamVjdGVkICYmIHJlamVjdGVkLmJpbmQgJiYgdGhpcy5jb250ZXh0KSB7XG4gICAgICAgIHJlamVjdGVkID0gcmVqZWN0ZWQuYmluZCh0aGlzLmNvbnRleHQpO1xuICAgIH1cblxuICAgIHJldHVybiBuZXcgUHJvbWlzZU9iaih0aGlzLnByb21pc2UudGhlbihmdWxmaWxsZWQsIHJlamVjdGVkKSwgdGhpcy5jb250ZXh0KTtcbn07XG5cbnAuY2F0Y2ggPSBmdW5jdGlvbiAocmVqZWN0ZWQpIHtcblxuICAgIGlmIChyZWplY3RlZCAmJiByZWplY3RlZC5iaW5kICYmIHRoaXMuY29udGV4dCkge1xuICAgICAgICByZWplY3RlZCA9IHJlamVjdGVkLmJpbmQodGhpcy5jb250ZXh0KTtcbiAgICB9XG5cbiAgICByZXR1cm4gbmV3IFByb21pc2VPYmoodGhpcy5wcm9taXNlLmNhdGNoKHJlamVjdGVkKSwgdGhpcy5jb250ZXh0KTtcbn07XG5cbnAuZmluYWxseSA9IGZ1bmN0aW9uIChjYWxsYmFjaykge1xuXG4gICAgcmV0dXJuIHRoaXMudGhlbihmdW5jdGlvbiAodmFsdWUpIHtcbiAgICAgICAgICAgIGNhbGxiYWNrLmNhbGwodGhpcyk7XG4gICAgICAgICAgICByZXR1cm4gdmFsdWU7XG4gICAgICAgIH0sIGZ1bmN0aW9uIChyZWFzb24pIHtcbiAgICAgICAgICAgIGNhbGxiYWNrLmNhbGwodGhpcyk7XG4gICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QocmVhc29uKTtcbiAgICAgICAgfVxuICAgICk7XG59O1xuXG4vKipcbiAqIFV0aWxpdHkgZnVuY3Rpb25zLlxuICovXG5cbnZhciByZWYgPSB7fTtcbnZhciBoYXNPd25Qcm9wZXJ0eSA9IHJlZi5oYXNPd25Qcm9wZXJ0eTtcblxudmFyIHJlZiQxID0gW107XG52YXIgc2xpY2UgPSByZWYkMS5zbGljZTtcbnZhciBkZWJ1ZyA9IGZhbHNlO1xudmFyIG50aWNrO1xuXG52YXIgaW5Ccm93c2VyID0gdHlwZW9mIHdpbmRvdyAhPT0gJ3VuZGVmaW5lZCc7XG5cbnZhciBVdGlsID0gZnVuY3Rpb24gKHJlZikge1xuICAgIHZhciBjb25maWcgPSByZWYuY29uZmlnO1xuICAgIHZhciBuZXh0VGljayA9IHJlZi5uZXh0VGljaztcblxuICAgIG50aWNrID0gbmV4dFRpY2s7XG4gICAgZGVidWcgPSBjb25maWcuZGVidWcgfHwgIWNvbmZpZy5zaWxlbnQ7XG59O1xuXG5mdW5jdGlvbiB3YXJuKG1zZykge1xuICAgIGlmICh0eXBlb2YgY29uc29sZSAhPT0gJ3VuZGVmaW5lZCcgJiYgZGVidWcpIHtcbiAgICAgICAgY29uc29sZS53YXJuKCdbVnVlUmVzb3VyY2Ugd2Fybl06ICcgKyBtc2cpO1xuICAgIH1cbn1cblxuZnVuY3Rpb24gZXJyb3IobXNnKSB7XG4gICAgaWYgKHR5cGVvZiBjb25zb2xlICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgICBjb25zb2xlLmVycm9yKG1zZyk7XG4gICAgfVxufVxuXG5mdW5jdGlvbiBuZXh0VGljayhjYiwgY3R4KSB7XG4gICAgcmV0dXJuIG50aWNrKGNiLCBjdHgpO1xufVxuXG5mdW5jdGlvbiB0cmltKHN0cikge1xuICAgIHJldHVybiBzdHIgPyBzdHIucmVwbGFjZSgvXlxccyp8XFxzKiQvZywgJycpIDogJyc7XG59XG5cbmZ1bmN0aW9uIHRyaW1FbmQoc3RyLCBjaGFycykge1xuXG4gICAgaWYgKHN0ciAmJiBjaGFycyA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHJldHVybiBzdHIucmVwbGFjZSgvXFxzKyQvLCAnJyk7XG4gICAgfVxuXG4gICAgaWYgKCFzdHIgfHwgIWNoYXJzKSB7XG4gICAgICAgIHJldHVybiBzdHI7XG4gICAgfVxuXG4gICAgcmV0dXJuIHN0ci5yZXBsYWNlKG5ldyBSZWdFeHAoKFwiW1wiICsgY2hhcnMgKyBcIl0rJFwiKSksICcnKTtcbn1cblxuZnVuY3Rpb24gdG9Mb3dlcihzdHIpIHtcbiAgICByZXR1cm4gc3RyID8gc3RyLnRvTG93ZXJDYXNlKCkgOiAnJztcbn1cblxuZnVuY3Rpb24gdG9VcHBlcihzdHIpIHtcbiAgICByZXR1cm4gc3RyID8gc3RyLnRvVXBwZXJDYXNlKCkgOiAnJztcbn1cblxudmFyIGlzQXJyYXkgPSBBcnJheS5pc0FycmF5O1xuXG5mdW5jdGlvbiBpc1N0cmluZyh2YWwpIHtcbiAgICByZXR1cm4gdHlwZW9mIHZhbCA9PT0gJ3N0cmluZyc7XG59XG5cblxuXG5mdW5jdGlvbiBpc0Z1bmN0aW9uKHZhbCkge1xuICAgIHJldHVybiB0eXBlb2YgdmFsID09PSAnZnVuY3Rpb24nO1xufVxuXG5mdW5jdGlvbiBpc09iamVjdChvYmopIHtcbiAgICByZXR1cm4gb2JqICE9PSBudWxsICYmIHR5cGVvZiBvYmogPT09ICdvYmplY3QnO1xufVxuXG5mdW5jdGlvbiBpc1BsYWluT2JqZWN0KG9iaikge1xuICAgIHJldHVybiBpc09iamVjdChvYmopICYmIE9iamVjdC5nZXRQcm90b3R5cGVPZihvYmopID09IE9iamVjdC5wcm90b3R5cGU7XG59XG5cbmZ1bmN0aW9uIGlzQmxvYihvYmopIHtcbiAgICByZXR1cm4gdHlwZW9mIEJsb2IgIT09ICd1bmRlZmluZWQnICYmIG9iaiBpbnN0YW5jZW9mIEJsb2I7XG59XG5cbmZ1bmN0aW9uIGlzRm9ybURhdGEob2JqKSB7XG4gICAgcmV0dXJuIHR5cGVvZiBGb3JtRGF0YSAhPT0gJ3VuZGVmaW5lZCcgJiYgb2JqIGluc3RhbmNlb2YgRm9ybURhdGE7XG59XG5cbmZ1bmN0aW9uIHdoZW4odmFsdWUsIGZ1bGZpbGxlZCwgcmVqZWN0ZWQpIHtcblxuICAgIHZhciBwcm9taXNlID0gUHJvbWlzZU9iai5yZXNvbHZlKHZhbHVlKTtcblxuICAgIGlmIChhcmd1bWVudHMubGVuZ3RoIDwgMikge1xuICAgICAgICByZXR1cm4gcHJvbWlzZTtcbiAgICB9XG5cbiAgICByZXR1cm4gcHJvbWlzZS50aGVuKGZ1bGZpbGxlZCwgcmVqZWN0ZWQpO1xufVxuXG5mdW5jdGlvbiBvcHRpb25zKGZuLCBvYmosIG9wdHMpIHtcblxuICAgIG9wdHMgPSBvcHRzIHx8IHt9O1xuXG4gICAgaWYgKGlzRnVuY3Rpb24ob3B0cykpIHtcbiAgICAgICAgb3B0cyA9IG9wdHMuY2FsbChvYmopO1xuICAgIH1cblxuICAgIHJldHVybiBtZXJnZShmbi5iaW5kKHskdm06IG9iaiwgJG9wdGlvbnM6IG9wdHN9KSwgZm4sIHskb3B0aW9uczogb3B0c30pO1xufVxuXG5mdW5jdGlvbiBlYWNoKG9iaiwgaXRlcmF0b3IpIHtcblxuICAgIHZhciBpLCBrZXk7XG5cbiAgICBpZiAoaXNBcnJheShvYmopKSB7XG4gICAgICAgIGZvciAoaSA9IDA7IGkgPCBvYmoubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIGl0ZXJhdG9yLmNhbGwob2JqW2ldLCBvYmpbaV0sIGkpO1xuICAgICAgICB9XG4gICAgfSBlbHNlIGlmIChpc09iamVjdChvYmopKSB7XG4gICAgICAgIGZvciAoa2V5IGluIG9iaikge1xuICAgICAgICAgICAgaWYgKGhhc093blByb3BlcnR5LmNhbGwob2JqLCBrZXkpKSB7XG4gICAgICAgICAgICAgICAgaXRlcmF0b3IuY2FsbChvYmpba2V5XSwgb2JqW2tleV0sIGtleSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gb2JqO1xufVxuXG52YXIgYXNzaWduID0gT2JqZWN0LmFzc2lnbiB8fCBfYXNzaWduO1xuXG5mdW5jdGlvbiBtZXJnZSh0YXJnZXQpIHtcblxuICAgIHZhciBhcmdzID0gc2xpY2UuY2FsbChhcmd1bWVudHMsIDEpO1xuXG4gICAgYXJncy5mb3JFYWNoKGZ1bmN0aW9uIChzb3VyY2UpIHtcbiAgICAgICAgX21lcmdlKHRhcmdldCwgc291cmNlLCB0cnVlKTtcbiAgICB9KTtcblxuICAgIHJldHVybiB0YXJnZXQ7XG59XG5cbmZ1bmN0aW9uIGRlZmF1bHRzKHRhcmdldCkge1xuXG4gICAgdmFyIGFyZ3MgPSBzbGljZS5jYWxsKGFyZ3VtZW50cywgMSk7XG5cbiAgICBhcmdzLmZvckVhY2goZnVuY3Rpb24gKHNvdXJjZSkge1xuXG4gICAgICAgIGZvciAodmFyIGtleSBpbiBzb3VyY2UpIHtcbiAgICAgICAgICAgIGlmICh0YXJnZXRba2V5XSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgdGFyZ2V0W2tleV0gPSBzb3VyY2Vba2V5XTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgfSk7XG5cbiAgICByZXR1cm4gdGFyZ2V0O1xufVxuXG5mdW5jdGlvbiBfYXNzaWduKHRhcmdldCkge1xuXG4gICAgdmFyIGFyZ3MgPSBzbGljZS5jYWxsKGFyZ3VtZW50cywgMSk7XG5cbiAgICBhcmdzLmZvckVhY2goZnVuY3Rpb24gKHNvdXJjZSkge1xuICAgICAgICBfbWVyZ2UodGFyZ2V0LCBzb3VyY2UpO1xuICAgIH0pO1xuXG4gICAgcmV0dXJuIHRhcmdldDtcbn1cblxuZnVuY3Rpb24gX21lcmdlKHRhcmdldCwgc291cmNlLCBkZWVwKSB7XG4gICAgZm9yICh2YXIga2V5IGluIHNvdXJjZSkge1xuICAgICAgICBpZiAoZGVlcCAmJiAoaXNQbGFpbk9iamVjdChzb3VyY2Vba2V5XSkgfHwgaXNBcnJheShzb3VyY2Vba2V5XSkpKSB7XG4gICAgICAgICAgICBpZiAoaXNQbGFpbk9iamVjdChzb3VyY2Vba2V5XSkgJiYgIWlzUGxhaW5PYmplY3QodGFyZ2V0W2tleV0pKSB7XG4gICAgICAgICAgICAgICAgdGFyZ2V0W2tleV0gPSB7fTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChpc0FycmF5KHNvdXJjZVtrZXldKSAmJiAhaXNBcnJheSh0YXJnZXRba2V5XSkpIHtcbiAgICAgICAgICAgICAgICB0YXJnZXRba2V5XSA9IFtdO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgX21lcmdlKHRhcmdldFtrZXldLCBzb3VyY2Vba2V5XSwgZGVlcCk7XG4gICAgICAgIH0gZWxzZSBpZiAoc291cmNlW2tleV0gIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgdGFyZ2V0W2tleV0gPSBzb3VyY2Vba2V5XTtcbiAgICAgICAgfVxuICAgIH1cbn1cblxuLyoqXG4gKiBSb290IFByZWZpeCBUcmFuc2Zvcm0uXG4gKi9cblxudmFyIHJvb3QgPSBmdW5jdGlvbiAob3B0aW9ucyQkMSwgbmV4dCkge1xuXG4gICAgdmFyIHVybCA9IG5leHQob3B0aW9ucyQkMSk7XG5cbiAgICBpZiAoaXNTdHJpbmcob3B0aW9ucyQkMS5yb290KSAmJiAhL14oaHR0cHM/Oik/XFwvLy50ZXN0KHVybCkpIHtcbiAgICAgICAgdXJsID0gdHJpbUVuZChvcHRpb25zJCQxLnJvb3QsICcvJykgKyAnLycgKyB1cmw7XG4gICAgfVxuXG4gICAgcmV0dXJuIHVybDtcbn07XG5cbi8qKlxuICogUXVlcnkgUGFyYW1ldGVyIFRyYW5zZm9ybS5cbiAqL1xuXG52YXIgcXVlcnkgPSBmdW5jdGlvbiAob3B0aW9ucyQkMSwgbmV4dCkge1xuXG4gICAgdmFyIHVybFBhcmFtcyA9IE9iamVjdC5rZXlzKFVybC5vcHRpb25zLnBhcmFtcyksIHF1ZXJ5ID0ge30sIHVybCA9IG5leHQob3B0aW9ucyQkMSk7XG5cbiAgICBlYWNoKG9wdGlvbnMkJDEucGFyYW1zLCBmdW5jdGlvbiAodmFsdWUsIGtleSkge1xuICAgICAgICBpZiAodXJsUGFyYW1zLmluZGV4T2Yoa2V5KSA9PT0gLTEpIHtcbiAgICAgICAgICAgIHF1ZXJ5W2tleV0gPSB2YWx1ZTtcbiAgICAgICAgfVxuICAgIH0pO1xuXG4gICAgcXVlcnkgPSBVcmwucGFyYW1zKHF1ZXJ5KTtcblxuICAgIGlmIChxdWVyeSkge1xuICAgICAgICB1cmwgKz0gKHVybC5pbmRleE9mKCc/JykgPT0gLTEgPyAnPycgOiAnJicpICsgcXVlcnk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHVybDtcbn07XG5cbi8qKlxuICogVVJMIFRlbXBsYXRlIHYyLjAuNiAoaHR0cHM6Ly9naXRodWIuY29tL2JyYW1zdGVpbi91cmwtdGVtcGxhdGUpXG4gKi9cblxuZnVuY3Rpb24gZXhwYW5kKHVybCwgcGFyYW1zLCB2YXJpYWJsZXMpIHtcblxuICAgIHZhciB0bXBsID0gcGFyc2UodXJsKSwgZXhwYW5kZWQgPSB0bXBsLmV4cGFuZChwYXJhbXMpO1xuXG4gICAgaWYgKHZhcmlhYmxlcykge1xuICAgICAgICB2YXJpYWJsZXMucHVzaC5hcHBseSh2YXJpYWJsZXMsIHRtcGwudmFycyk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGV4cGFuZGVkO1xufVxuXG5mdW5jdGlvbiBwYXJzZSh0ZW1wbGF0ZSkge1xuXG4gICAgdmFyIG9wZXJhdG9ycyA9IFsnKycsICcjJywgJy4nLCAnLycsICc7JywgJz8nLCAnJiddLCB2YXJpYWJsZXMgPSBbXTtcblxuICAgIHJldHVybiB7XG4gICAgICAgIHZhcnM6IHZhcmlhYmxlcyxcbiAgICAgICAgZXhwYW5kOiBmdW5jdGlvbiBleHBhbmQoY29udGV4dCkge1xuICAgICAgICAgICAgcmV0dXJuIHRlbXBsYXRlLnJlcGxhY2UoL1xceyhbXlxce1xcfV0rKVxcfXwoW15cXHtcXH1dKykvZywgZnVuY3Rpb24gKF8sIGV4cHJlc3Npb24sIGxpdGVyYWwpIHtcbiAgICAgICAgICAgICAgICBpZiAoZXhwcmVzc2lvbikge1xuXG4gICAgICAgICAgICAgICAgICAgIHZhciBvcGVyYXRvciA9IG51bGwsIHZhbHVlcyA9IFtdO1xuXG4gICAgICAgICAgICAgICAgICAgIGlmIChvcGVyYXRvcnMuaW5kZXhPZihleHByZXNzaW9uLmNoYXJBdCgwKSkgIT09IC0xKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBvcGVyYXRvciA9IGV4cHJlc3Npb24uY2hhckF0KDApO1xuICAgICAgICAgICAgICAgICAgICAgICAgZXhwcmVzc2lvbiA9IGV4cHJlc3Npb24uc3Vic3RyKDEpO1xuICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgZXhwcmVzc2lvbi5zcGxpdCgvLC9nKS5mb3JFYWNoKGZ1bmN0aW9uICh2YXJpYWJsZSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHRtcCA9IC8oW146XFwqXSopKD86OihcXGQrKXwoXFwqKSk/Ly5leGVjKHZhcmlhYmxlKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhbHVlcy5wdXNoLmFwcGx5KHZhbHVlcywgZ2V0VmFsdWVzKGNvbnRleHQsIG9wZXJhdG9yLCB0bXBbMV0sIHRtcFsyXSB8fCB0bXBbM10pKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhcmlhYmxlcy5wdXNoKHRtcFsxXSk7XG4gICAgICAgICAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICAgICAgICAgIGlmIChvcGVyYXRvciAmJiBvcGVyYXRvciAhPT0gJysnKSB7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBzZXBhcmF0b3IgPSAnLCc7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChvcGVyYXRvciA9PT0gJz8nKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VwYXJhdG9yID0gJyYnO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChvcGVyYXRvciAhPT0gJyMnKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VwYXJhdG9yID0gb3BlcmF0b3I7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiAodmFsdWVzLmxlbmd0aCAhPT0gMCA/IG9wZXJhdG9yIDogJycpICsgdmFsdWVzLmpvaW4oc2VwYXJhdG9yKTtcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB2YWx1ZXMuam9pbignLCcpO1xuICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gZW5jb2RlUmVzZXJ2ZWQobGl0ZXJhbCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICB9O1xufVxuXG5mdW5jdGlvbiBnZXRWYWx1ZXMoY29udGV4dCwgb3BlcmF0b3IsIGtleSwgbW9kaWZpZXIpIHtcblxuICAgIHZhciB2YWx1ZSA9IGNvbnRleHRba2V5XSwgcmVzdWx0ID0gW107XG5cbiAgICBpZiAoaXNEZWZpbmVkKHZhbHVlKSAmJiB2YWx1ZSAhPT0gJycpIHtcbiAgICAgICAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ3N0cmluZycgfHwgdHlwZW9mIHZhbHVlID09PSAnbnVtYmVyJyB8fCB0eXBlb2YgdmFsdWUgPT09ICdib29sZWFuJykge1xuICAgICAgICAgICAgdmFsdWUgPSB2YWx1ZS50b1N0cmluZygpO1xuXG4gICAgICAgICAgICBpZiAobW9kaWZpZXIgJiYgbW9kaWZpZXIgIT09ICcqJykge1xuICAgICAgICAgICAgICAgIHZhbHVlID0gdmFsdWUuc3Vic3RyaW5nKDAsIHBhcnNlSW50KG1vZGlmaWVyLCAxMCkpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICByZXN1bHQucHVzaChlbmNvZGVWYWx1ZShvcGVyYXRvciwgdmFsdWUsIGlzS2V5T3BlcmF0b3Iob3BlcmF0b3IpID8ga2V5IDogbnVsbCkpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgaWYgKG1vZGlmaWVyID09PSAnKicpIHtcbiAgICAgICAgICAgICAgICBpZiAoQXJyYXkuaXNBcnJheSh2YWx1ZSkpIHtcbiAgICAgICAgICAgICAgICAgICAgdmFsdWUuZmlsdGVyKGlzRGVmaW5lZCkuZm9yRWFjaChmdW5jdGlvbiAodmFsdWUpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlc3VsdC5wdXNoKGVuY29kZVZhbHVlKG9wZXJhdG9yLCB2YWx1ZSwgaXNLZXlPcGVyYXRvcihvcGVyYXRvcikgPyBrZXkgOiBudWxsKSk7XG4gICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIE9iamVjdC5rZXlzKHZhbHVlKS5mb3JFYWNoKGZ1bmN0aW9uIChrKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoaXNEZWZpbmVkKHZhbHVlW2tdKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlc3VsdC5wdXNoKGVuY29kZVZhbHVlKG9wZXJhdG9yLCB2YWx1ZVtrXSwgaykpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHZhciB0bXAgPSBbXTtcblxuICAgICAgICAgICAgICAgIGlmIChBcnJheS5pc0FycmF5KHZhbHVlKSkge1xuICAgICAgICAgICAgICAgICAgICB2YWx1ZS5maWx0ZXIoaXNEZWZpbmVkKS5mb3JFYWNoKGZ1bmN0aW9uICh2YWx1ZSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgdG1wLnB1c2goZW5jb2RlVmFsdWUob3BlcmF0b3IsIHZhbHVlKSk7XG4gICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIE9iamVjdC5rZXlzKHZhbHVlKS5mb3JFYWNoKGZ1bmN0aW9uIChrKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoaXNEZWZpbmVkKHZhbHVlW2tdKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRtcC5wdXNoKGVuY29kZVVSSUNvbXBvbmVudChrKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdG1wLnB1c2goZW5jb2RlVmFsdWUob3BlcmF0b3IsIHZhbHVlW2tdLnRvU3RyaW5nKCkpKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgaWYgKGlzS2V5T3BlcmF0b3Iob3BlcmF0b3IpKSB7XG4gICAgICAgICAgICAgICAgICAgIHJlc3VsdC5wdXNoKGVuY29kZVVSSUNvbXBvbmVudChrZXkpICsgJz0nICsgdG1wLmpvaW4oJywnKSk7XG4gICAgICAgICAgICAgICAgfSBlbHNlIGlmICh0bXAubGVuZ3RoICE9PSAwKSB7XG4gICAgICAgICAgICAgICAgICAgIHJlc3VsdC5wdXNoKHRtcC5qb2luKCcsJykpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICAgIGlmIChvcGVyYXRvciA9PT0gJzsnKSB7XG4gICAgICAgICAgICByZXN1bHQucHVzaChlbmNvZGVVUklDb21wb25lbnQoa2V5KSk7XG4gICAgICAgIH0gZWxzZSBpZiAodmFsdWUgPT09ICcnICYmIChvcGVyYXRvciA9PT0gJyYnIHx8IG9wZXJhdG9yID09PSAnPycpKSB7XG4gICAgICAgICAgICByZXN1bHQucHVzaChlbmNvZGVVUklDb21wb25lbnQoa2V5KSArICc9Jyk7XG4gICAgICAgIH0gZWxzZSBpZiAodmFsdWUgPT09ICcnKSB7XG4gICAgICAgICAgICByZXN1bHQucHVzaCgnJyk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gcmVzdWx0O1xufVxuXG5mdW5jdGlvbiBpc0RlZmluZWQodmFsdWUpIHtcbiAgICByZXR1cm4gdmFsdWUgIT09IHVuZGVmaW5lZCAmJiB2YWx1ZSAhPT0gbnVsbDtcbn1cblxuZnVuY3Rpb24gaXNLZXlPcGVyYXRvcihvcGVyYXRvcikge1xuICAgIHJldHVybiBvcGVyYXRvciA9PT0gJzsnIHx8IG9wZXJhdG9yID09PSAnJicgfHwgb3BlcmF0b3IgPT09ICc/Jztcbn1cblxuZnVuY3Rpb24gZW5jb2RlVmFsdWUob3BlcmF0b3IsIHZhbHVlLCBrZXkpIHtcblxuICAgIHZhbHVlID0gKG9wZXJhdG9yID09PSAnKycgfHwgb3BlcmF0b3IgPT09ICcjJykgPyBlbmNvZGVSZXNlcnZlZCh2YWx1ZSkgOiBlbmNvZGVVUklDb21wb25lbnQodmFsdWUpO1xuXG4gICAgaWYgKGtleSkge1xuICAgICAgICByZXR1cm4gZW5jb2RlVVJJQ29tcG9uZW50KGtleSkgKyAnPScgKyB2YWx1ZTtcbiAgICB9IGVsc2Uge1xuICAgICAgICByZXR1cm4gdmFsdWU7XG4gICAgfVxufVxuXG5mdW5jdGlvbiBlbmNvZGVSZXNlcnZlZChzdHIpIHtcbiAgICByZXR1cm4gc3RyLnNwbGl0KC8oJVswLTlBLUZhLWZdezJ9KS9nKS5tYXAoZnVuY3Rpb24gKHBhcnQpIHtcbiAgICAgICAgaWYgKCEvJVswLTlBLUZhLWZdLy50ZXN0KHBhcnQpKSB7XG4gICAgICAgICAgICBwYXJ0ID0gZW5jb2RlVVJJKHBhcnQpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBwYXJ0O1xuICAgIH0pLmpvaW4oJycpO1xufVxuXG4vKipcbiAqIFVSTCBUZW1wbGF0ZSAoUkZDIDY1NzApIFRyYW5zZm9ybS5cbiAqL1xuXG52YXIgdGVtcGxhdGUgPSBmdW5jdGlvbiAob3B0aW9ucykge1xuXG4gICAgdmFyIHZhcmlhYmxlcyA9IFtdLCB1cmwgPSBleHBhbmQob3B0aW9ucy51cmwsIG9wdGlvbnMucGFyYW1zLCB2YXJpYWJsZXMpO1xuXG4gICAgdmFyaWFibGVzLmZvckVhY2goZnVuY3Rpb24gKGtleSkge1xuICAgICAgICBkZWxldGUgb3B0aW9ucy5wYXJhbXNba2V5XTtcbiAgICB9KTtcblxuICAgIHJldHVybiB1cmw7XG59O1xuXG4vKipcbiAqIFNlcnZpY2UgZm9yIFVSTCB0ZW1wbGF0aW5nLlxuICovXG5cbmZ1bmN0aW9uIFVybCh1cmwsIHBhcmFtcykge1xuXG4gICAgdmFyIHNlbGYgPSB0aGlzIHx8IHt9LCBvcHRpb25zJCQxID0gdXJsLCB0cmFuc2Zvcm07XG5cbiAgICBpZiAoaXNTdHJpbmcodXJsKSkge1xuICAgICAgICBvcHRpb25zJCQxID0ge3VybDogdXJsLCBwYXJhbXM6IHBhcmFtc307XG4gICAgfVxuXG4gICAgb3B0aW9ucyQkMSA9IG1lcmdlKHt9LCBVcmwub3B0aW9ucywgc2VsZi4kb3B0aW9ucywgb3B0aW9ucyQkMSk7XG5cbiAgICBVcmwudHJhbnNmb3Jtcy5mb3JFYWNoKGZ1bmN0aW9uIChoYW5kbGVyKSB7XG5cbiAgICAgICAgaWYgKGlzU3RyaW5nKGhhbmRsZXIpKSB7XG4gICAgICAgICAgICBoYW5kbGVyID0gVXJsLnRyYW5zZm9ybVtoYW5kbGVyXTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChpc0Z1bmN0aW9uKGhhbmRsZXIpKSB7XG4gICAgICAgICAgICB0cmFuc2Zvcm0gPSBmYWN0b3J5KGhhbmRsZXIsIHRyYW5zZm9ybSwgc2VsZi4kdm0pO1xuICAgICAgICB9XG5cbiAgICB9KTtcblxuICAgIHJldHVybiB0cmFuc2Zvcm0ob3B0aW9ucyQkMSk7XG59XG5cbi8qKlxuICogVXJsIG9wdGlvbnMuXG4gKi9cblxuVXJsLm9wdGlvbnMgPSB7XG4gICAgdXJsOiAnJyxcbiAgICByb290OiBudWxsLFxuICAgIHBhcmFtczoge31cbn07XG5cbi8qKlxuICogVXJsIHRyYW5zZm9ybXMuXG4gKi9cblxuVXJsLnRyYW5zZm9ybSA9IHt0ZW1wbGF0ZTogdGVtcGxhdGUsIHF1ZXJ5OiBxdWVyeSwgcm9vdDogcm9vdH07XG5VcmwudHJhbnNmb3JtcyA9IFsndGVtcGxhdGUnLCAncXVlcnknLCAncm9vdCddO1xuXG4vKipcbiAqIEVuY29kZXMgYSBVcmwgcGFyYW1ldGVyIHN0cmluZy5cbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gb2JqXG4gKi9cblxuVXJsLnBhcmFtcyA9IGZ1bmN0aW9uIChvYmopIHtcblxuICAgIHZhciBwYXJhbXMgPSBbXSwgZXNjYXBlID0gZW5jb2RlVVJJQ29tcG9uZW50O1xuXG4gICAgcGFyYW1zLmFkZCA9IGZ1bmN0aW9uIChrZXksIHZhbHVlKSB7XG5cbiAgICAgICAgaWYgKGlzRnVuY3Rpb24odmFsdWUpKSB7XG4gICAgICAgICAgICB2YWx1ZSA9IHZhbHVlKCk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAodmFsdWUgPT09IG51bGwpIHtcbiAgICAgICAgICAgIHZhbHVlID0gJyc7XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLnB1c2goZXNjYXBlKGtleSkgKyAnPScgKyBlc2NhcGUodmFsdWUpKTtcbiAgICB9O1xuXG4gICAgc2VyaWFsaXplKHBhcmFtcywgb2JqKTtcblxuICAgIHJldHVybiBwYXJhbXMuam9pbignJicpLnJlcGxhY2UoLyUyMC9nLCAnKycpO1xufTtcblxuLyoqXG4gKiBQYXJzZSBhIFVSTCBhbmQgcmV0dXJuIGl0cyBjb21wb25lbnRzLlxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSB1cmxcbiAqL1xuXG5VcmwucGFyc2UgPSBmdW5jdGlvbiAodXJsKSB7XG5cbiAgICB2YXIgZWwgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdhJyk7XG5cbiAgICBpZiAoZG9jdW1lbnQuZG9jdW1lbnRNb2RlKSB7XG4gICAgICAgIGVsLmhyZWYgPSB1cmw7XG4gICAgICAgIHVybCA9IGVsLmhyZWY7XG4gICAgfVxuXG4gICAgZWwuaHJlZiA9IHVybDtcblxuICAgIHJldHVybiB7XG4gICAgICAgIGhyZWY6IGVsLmhyZWYsXG4gICAgICAgIHByb3RvY29sOiBlbC5wcm90b2NvbCA/IGVsLnByb3RvY29sLnJlcGxhY2UoLzokLywgJycpIDogJycsXG4gICAgICAgIHBvcnQ6IGVsLnBvcnQsXG4gICAgICAgIGhvc3Q6IGVsLmhvc3QsXG4gICAgICAgIGhvc3RuYW1lOiBlbC5ob3N0bmFtZSxcbiAgICAgICAgcGF0aG5hbWU6IGVsLnBhdGhuYW1lLmNoYXJBdCgwKSA9PT0gJy8nID8gZWwucGF0aG5hbWUgOiAnLycgKyBlbC5wYXRobmFtZSxcbiAgICAgICAgc2VhcmNoOiBlbC5zZWFyY2ggPyBlbC5zZWFyY2gucmVwbGFjZSgvXlxcPy8sICcnKSA6ICcnLFxuICAgICAgICBoYXNoOiBlbC5oYXNoID8gZWwuaGFzaC5yZXBsYWNlKC9eIy8sICcnKSA6ICcnXG4gICAgfTtcbn07XG5cbmZ1bmN0aW9uIGZhY3RvcnkoaGFuZGxlciwgbmV4dCwgdm0pIHtcbiAgICByZXR1cm4gZnVuY3Rpb24gKG9wdGlvbnMkJDEpIHtcbiAgICAgICAgcmV0dXJuIGhhbmRsZXIuY2FsbCh2bSwgb3B0aW9ucyQkMSwgbmV4dCk7XG4gICAgfTtcbn1cblxuZnVuY3Rpb24gc2VyaWFsaXplKHBhcmFtcywgb2JqLCBzY29wZSkge1xuXG4gICAgdmFyIGFycmF5ID0gaXNBcnJheShvYmopLCBwbGFpbiA9IGlzUGxhaW5PYmplY3Qob2JqKSwgaGFzaDtcblxuICAgIGVhY2gob2JqLCBmdW5jdGlvbiAodmFsdWUsIGtleSkge1xuXG4gICAgICAgIGhhc2ggPSBpc09iamVjdCh2YWx1ZSkgfHwgaXNBcnJheSh2YWx1ZSk7XG5cbiAgICAgICAgaWYgKHNjb3BlKSB7XG4gICAgICAgICAgICBrZXkgPSBzY29wZSArICdbJyArIChwbGFpbiB8fCBoYXNoID8ga2V5IDogJycpICsgJ10nO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKCFzY29wZSAmJiBhcnJheSkge1xuICAgICAgICAgICAgcGFyYW1zLmFkZCh2YWx1ZS5uYW1lLCB2YWx1ZS52YWx1ZSk7XG4gICAgICAgIH0gZWxzZSBpZiAoaGFzaCkge1xuICAgICAgICAgICAgc2VyaWFsaXplKHBhcmFtcywgdmFsdWUsIGtleSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBwYXJhbXMuYWRkKGtleSwgdmFsdWUpO1xuICAgICAgICB9XG4gICAgfSk7XG59XG5cbi8qKlxuICogWERvbWFpbiBjbGllbnQgKEludGVybmV0IEV4cGxvcmVyKS5cbiAqL1xuXG52YXIgeGRyQ2xpZW50ID0gZnVuY3Rpb24gKHJlcXVlc3QpIHtcbiAgICByZXR1cm4gbmV3IFByb21pc2VPYmooZnVuY3Rpb24gKHJlc29sdmUpIHtcblxuICAgICAgICB2YXIgeGRyID0gbmV3IFhEb21haW5SZXF1ZXN0KCksIGhhbmRsZXIgPSBmdW5jdGlvbiAocmVmKSB7XG4gICAgICAgICAgICB2YXIgdHlwZSA9IHJlZi50eXBlO1xuXG5cbiAgICAgICAgICAgIHZhciBzdGF0dXMgPSAwO1xuXG4gICAgICAgICAgICBpZiAodHlwZSA9PT0gJ2xvYWQnKSB7XG4gICAgICAgICAgICAgICAgc3RhdHVzID0gMjAwO1xuICAgICAgICAgICAgfSBlbHNlIGlmICh0eXBlID09PSAnZXJyb3InKSB7XG4gICAgICAgICAgICAgICAgc3RhdHVzID0gNTAwO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICByZXNvbHZlKHJlcXVlc3QucmVzcG9uZFdpdGgoeGRyLnJlc3BvbnNlVGV4dCwge3N0YXR1czogc3RhdHVzfSkpO1xuICAgICAgICB9O1xuXG4gICAgICAgIHJlcXVlc3QuYWJvcnQgPSBmdW5jdGlvbiAoKSB7IHJldHVybiB4ZHIuYWJvcnQoKTsgfTtcblxuICAgICAgICB4ZHIub3BlbihyZXF1ZXN0Lm1ldGhvZCwgcmVxdWVzdC5nZXRVcmwoKSk7XG5cbiAgICAgICAgaWYgKHJlcXVlc3QudGltZW91dCkge1xuICAgICAgICAgICAgeGRyLnRpbWVvdXQgPSByZXF1ZXN0LnRpbWVvdXQ7XG4gICAgICAgIH1cblxuICAgICAgICB4ZHIub25sb2FkID0gaGFuZGxlcjtcbiAgICAgICAgeGRyLm9uYWJvcnQgPSBoYW5kbGVyO1xuICAgICAgICB4ZHIub25lcnJvciA9IGhhbmRsZXI7XG4gICAgICAgIHhkci5vbnRpbWVvdXQgPSBoYW5kbGVyO1xuICAgICAgICB4ZHIub25wcm9ncmVzcyA9IGZ1bmN0aW9uICgpIHt9O1xuICAgICAgICB4ZHIuc2VuZChyZXF1ZXN0LmdldEJvZHkoKSk7XG4gICAgfSk7XG59O1xuXG4vKipcbiAqIENPUlMgSW50ZXJjZXB0b3IuXG4gKi9cblxudmFyIFNVUFBPUlRTX0NPUlMgPSBpbkJyb3dzZXIgJiYgJ3dpdGhDcmVkZW50aWFscycgaW4gbmV3IFhNTEh0dHBSZXF1ZXN0KCk7XG5cbnZhciBjb3JzID0gZnVuY3Rpb24gKHJlcXVlc3QsIG5leHQpIHtcblxuICAgIGlmIChpbkJyb3dzZXIpIHtcblxuICAgICAgICB2YXIgb3JnVXJsID0gVXJsLnBhcnNlKGxvY2F0aW9uLmhyZWYpO1xuICAgICAgICB2YXIgcmVxVXJsID0gVXJsLnBhcnNlKHJlcXVlc3QuZ2V0VXJsKCkpO1xuXG4gICAgICAgIGlmIChyZXFVcmwucHJvdG9jb2wgIT09IG9yZ1VybC5wcm90b2NvbCB8fCByZXFVcmwuaG9zdCAhPT0gb3JnVXJsLmhvc3QpIHtcblxuICAgICAgICAgICAgcmVxdWVzdC5jcm9zc09yaWdpbiA9IHRydWU7XG4gICAgICAgICAgICByZXF1ZXN0LmVtdWxhdGVIVFRQID0gZmFsc2U7XG5cbiAgICAgICAgICAgIGlmICghU1VQUE9SVFNfQ09SUykge1xuICAgICAgICAgICAgICAgIHJlcXVlc3QuY2xpZW50ID0geGRyQ2xpZW50O1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgbmV4dCgpO1xufTtcblxuLyoqXG4gKiBGb3JtIGRhdGEgSW50ZXJjZXB0b3IuXG4gKi9cblxudmFyIGZvcm0gPSBmdW5jdGlvbiAocmVxdWVzdCwgbmV4dCkge1xuXG4gICAgaWYgKGlzRm9ybURhdGEocmVxdWVzdC5ib2R5KSkge1xuXG4gICAgICAgIHJlcXVlc3QuaGVhZGVycy5kZWxldGUoJ0NvbnRlbnQtVHlwZScpO1xuXG4gICAgfSBlbHNlIGlmIChpc09iamVjdChyZXF1ZXN0LmJvZHkpICYmIHJlcXVlc3QuZW11bGF0ZUpTT04pIHtcblxuICAgICAgICByZXF1ZXN0LmJvZHkgPSBVcmwucGFyYW1zKHJlcXVlc3QuYm9keSk7XG4gICAgICAgIHJlcXVlc3QuaGVhZGVycy5zZXQoJ0NvbnRlbnQtVHlwZScsICdhcHBsaWNhdGlvbi94LXd3dy1mb3JtLXVybGVuY29kZWQnKTtcbiAgICB9XG5cbiAgICBuZXh0KCk7XG59O1xuXG4vKipcbiAqIEpTT04gSW50ZXJjZXB0b3IuXG4gKi9cblxudmFyIGpzb24gPSBmdW5jdGlvbiAocmVxdWVzdCwgbmV4dCkge1xuXG4gICAgdmFyIHR5cGUgPSByZXF1ZXN0LmhlYWRlcnMuZ2V0KCdDb250ZW50LVR5cGUnKSB8fCAnJztcblxuICAgIGlmIChpc09iamVjdChyZXF1ZXN0LmJvZHkpICYmIHR5cGUuaW5kZXhPZignYXBwbGljYXRpb24vanNvbicpID09PSAwKSB7XG4gICAgICAgIHJlcXVlc3QuYm9keSA9IEpTT04uc3RyaW5naWZ5KHJlcXVlc3QuYm9keSk7XG4gICAgfVxuXG4gICAgbmV4dChmdW5jdGlvbiAocmVzcG9uc2UpIHtcblxuICAgICAgICByZXR1cm4gcmVzcG9uc2UuYm9keVRleHQgPyB3aGVuKHJlc3BvbnNlLnRleHQoKSwgZnVuY3Rpb24gKHRleHQpIHtcblxuICAgICAgICAgICAgdHlwZSA9IHJlc3BvbnNlLmhlYWRlcnMuZ2V0KCdDb250ZW50LVR5cGUnKSB8fCAnJztcblxuICAgICAgICAgICAgaWYgKHR5cGUuaW5kZXhPZignYXBwbGljYXRpb24vanNvbicpID09PSAwIHx8IGlzSnNvbih0ZXh0KSkge1xuXG4gICAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICAgICAgcmVzcG9uc2UuYm9keSA9IEpTT04ucGFyc2UodGV4dCk7XG4gICAgICAgICAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgICAgICAgICAgICByZXNwb25zZS5ib2R5ID0gbnVsbDtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgcmVzcG9uc2UuYm9keSA9IHRleHQ7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHJldHVybiByZXNwb25zZTtcblxuICAgICAgICB9KSA6IHJlc3BvbnNlO1xuXG4gICAgfSk7XG59O1xuXG5mdW5jdGlvbiBpc0pzb24oc3RyKSB7XG5cbiAgICB2YXIgc3RhcnQgPSBzdHIubWF0Y2goL15cXFt8Xlxceyg/IVxceykvKSwgZW5kID0geydbJzogL10kLywgJ3snOiAvfSQvfTtcblxuICAgIHJldHVybiBzdGFydCAmJiBlbmRbc3RhcnRbMF1dLnRlc3Qoc3RyKTtcbn1cblxuLyoqXG4gKiBKU09OUCBjbGllbnQgKEJyb3dzZXIpLlxuICovXG5cbnZhciBqc29ucENsaWVudCA9IGZ1bmN0aW9uIChyZXF1ZXN0KSB7XG4gICAgcmV0dXJuIG5ldyBQcm9taXNlT2JqKGZ1bmN0aW9uIChyZXNvbHZlKSB7XG5cbiAgICAgICAgdmFyIG5hbWUgPSByZXF1ZXN0Lmpzb25wIHx8ICdjYWxsYmFjaycsIGNhbGxiYWNrID0gcmVxdWVzdC5qc29ucENhbGxiYWNrIHx8ICdfanNvbnAnICsgTWF0aC5yYW5kb20oKS50b1N0cmluZygzNikuc3Vic3RyKDIpLCBib2R5ID0gbnVsbCwgaGFuZGxlciwgc2NyaXB0O1xuXG4gICAgICAgIGhhbmRsZXIgPSBmdW5jdGlvbiAocmVmKSB7XG4gICAgICAgICAgICB2YXIgdHlwZSA9IHJlZi50eXBlO1xuXG5cbiAgICAgICAgICAgIHZhciBzdGF0dXMgPSAwO1xuXG4gICAgICAgICAgICBpZiAodHlwZSA9PT0gJ2xvYWQnICYmIGJvZHkgIT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICBzdGF0dXMgPSAyMDA7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKHR5cGUgPT09ICdlcnJvcicpIHtcbiAgICAgICAgICAgICAgICBzdGF0dXMgPSA1MDA7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmIChzdGF0dXMgJiYgd2luZG93W2NhbGxiYWNrXSkge1xuICAgICAgICAgICAgICAgIGRlbGV0ZSB3aW5kb3dbY2FsbGJhY2tdO1xuICAgICAgICAgICAgICAgIGRvY3VtZW50LmJvZHkucmVtb3ZlQ2hpbGQoc2NyaXB0KTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgcmVzb2x2ZShyZXF1ZXN0LnJlc3BvbmRXaXRoKGJvZHksIHtzdGF0dXM6IHN0YXR1c30pKTtcbiAgICAgICAgfTtcblxuICAgICAgICB3aW5kb3dbY2FsbGJhY2tdID0gZnVuY3Rpb24gKHJlc3VsdCkge1xuICAgICAgICAgICAgYm9keSA9IEpTT04uc3RyaW5naWZ5KHJlc3VsdCk7XG4gICAgICAgIH07XG5cbiAgICAgICAgcmVxdWVzdC5hYm9ydCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGhhbmRsZXIoe3R5cGU6ICdhYm9ydCd9KTtcbiAgICAgICAgfTtcblxuICAgICAgICByZXF1ZXN0LnBhcmFtc1tuYW1lXSA9IGNhbGxiYWNrO1xuXG4gICAgICAgIGlmIChyZXF1ZXN0LnRpbWVvdXQpIHtcbiAgICAgICAgICAgIHNldFRpbWVvdXQocmVxdWVzdC5hYm9ydCwgcmVxdWVzdC50aW1lb3V0KTtcbiAgICAgICAgfVxuXG4gICAgICAgIHNjcmlwdCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ3NjcmlwdCcpO1xuICAgICAgICBzY3JpcHQuc3JjID0gcmVxdWVzdC5nZXRVcmwoKTtcbiAgICAgICAgc2NyaXB0LnR5cGUgPSAndGV4dC9qYXZhc2NyaXB0JztcbiAgICAgICAgc2NyaXB0LmFzeW5jID0gdHJ1ZTtcbiAgICAgICAgc2NyaXB0Lm9ubG9hZCA9IGhhbmRsZXI7XG4gICAgICAgIHNjcmlwdC5vbmVycm9yID0gaGFuZGxlcjtcblxuICAgICAgICBkb2N1bWVudC5ib2R5LmFwcGVuZENoaWxkKHNjcmlwdCk7XG4gICAgfSk7XG59O1xuXG4vKipcbiAqIEpTT05QIEludGVyY2VwdG9yLlxuICovXG5cbnZhciBqc29ucCA9IGZ1bmN0aW9uIChyZXF1ZXN0LCBuZXh0KSB7XG5cbiAgICBpZiAocmVxdWVzdC5tZXRob2QgPT0gJ0pTT05QJykge1xuICAgICAgICByZXF1ZXN0LmNsaWVudCA9IGpzb25wQ2xpZW50O1xuICAgIH1cblxuICAgIG5leHQoKTtcbn07XG5cbi8qKlxuICogQmVmb3JlIEludGVyY2VwdG9yLlxuICovXG5cbnZhciBiZWZvcmUgPSBmdW5jdGlvbiAocmVxdWVzdCwgbmV4dCkge1xuXG4gICAgaWYgKGlzRnVuY3Rpb24ocmVxdWVzdC5iZWZvcmUpKSB7XG4gICAgICAgIHJlcXVlc3QuYmVmb3JlLmNhbGwodGhpcywgcmVxdWVzdCk7XG4gICAgfVxuXG4gICAgbmV4dCgpO1xufTtcblxuLyoqXG4gKiBIVFRQIG1ldGhvZCBvdmVycmlkZSBJbnRlcmNlcHRvci5cbiAqL1xuXG52YXIgbWV0aG9kID0gZnVuY3Rpb24gKHJlcXVlc3QsIG5leHQpIHtcblxuICAgIGlmIChyZXF1ZXN0LmVtdWxhdGVIVFRQICYmIC9eKFBVVHxQQVRDSHxERUxFVEUpJC9pLnRlc3QocmVxdWVzdC5tZXRob2QpKSB7XG4gICAgICAgIHJlcXVlc3QuaGVhZGVycy5zZXQoJ1gtSFRUUC1NZXRob2QtT3ZlcnJpZGUnLCByZXF1ZXN0Lm1ldGhvZCk7XG4gICAgICAgIHJlcXVlc3QubWV0aG9kID0gJ1BPU1QnO1xuICAgIH1cblxuICAgIG5leHQoKTtcbn07XG5cbi8qKlxuICogSGVhZGVyIEludGVyY2VwdG9yLlxuICovXG5cbnZhciBoZWFkZXIgPSBmdW5jdGlvbiAocmVxdWVzdCwgbmV4dCkge1xuXG4gICAgdmFyIGhlYWRlcnMgPSBhc3NpZ24oe30sIEh0dHAuaGVhZGVycy5jb21tb24sXG4gICAgICAgICFyZXF1ZXN0LmNyb3NzT3JpZ2luID8gSHR0cC5oZWFkZXJzLmN1c3RvbSA6IHt9LFxuICAgICAgICBIdHRwLmhlYWRlcnNbdG9Mb3dlcihyZXF1ZXN0Lm1ldGhvZCldXG4gICAgKTtcblxuICAgIGVhY2goaGVhZGVycywgZnVuY3Rpb24gKHZhbHVlLCBuYW1lKSB7XG4gICAgICAgIGlmICghcmVxdWVzdC5oZWFkZXJzLmhhcyhuYW1lKSkge1xuICAgICAgICAgICAgcmVxdWVzdC5oZWFkZXJzLnNldChuYW1lLCB2YWx1ZSk7XG4gICAgICAgIH1cbiAgICB9KTtcblxuICAgIG5leHQoKTtcbn07XG5cbi8qKlxuICogWE1MSHR0cCBjbGllbnQgKEJyb3dzZXIpLlxuICovXG5cbnZhciB4aHJDbGllbnQgPSBmdW5jdGlvbiAocmVxdWVzdCkge1xuICAgIHJldHVybiBuZXcgUHJvbWlzZU9iaihmdW5jdGlvbiAocmVzb2x2ZSkge1xuXG4gICAgICAgIHZhciB4aHIgPSBuZXcgWE1MSHR0cFJlcXVlc3QoKSwgaGFuZGxlciA9IGZ1bmN0aW9uIChldmVudCkge1xuXG4gICAgICAgICAgICB2YXIgcmVzcG9uc2UgPSByZXF1ZXN0LnJlc3BvbmRXaXRoKFxuICAgICAgICAgICAgICAgICdyZXNwb25zZScgaW4geGhyID8geGhyLnJlc3BvbnNlIDogeGhyLnJlc3BvbnNlVGV4dCwge1xuICAgICAgICAgICAgICAgICAgICBzdGF0dXM6IHhoci5zdGF0dXMgPT09IDEyMjMgPyAyMDQgOiB4aHIuc3RhdHVzLCAvLyBJRTkgc3RhdHVzIGJ1Z1xuICAgICAgICAgICAgICAgICAgICBzdGF0dXNUZXh0OiB4aHIuc3RhdHVzID09PSAxMjIzID8gJ05vIENvbnRlbnQnIDogdHJpbSh4aHIuc3RhdHVzVGV4dClcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICApO1xuXG4gICAgICAgICAgICBlYWNoKHRyaW0oeGhyLmdldEFsbFJlc3BvbnNlSGVhZGVycygpKS5zcGxpdCgnXFxuJyksIGZ1bmN0aW9uIChyb3cpIHtcbiAgICAgICAgICAgICAgICByZXNwb25zZS5oZWFkZXJzLmFwcGVuZChyb3cuc2xpY2UoMCwgcm93LmluZGV4T2YoJzonKSksIHJvdy5zbGljZShyb3cuaW5kZXhPZignOicpICsgMSkpO1xuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgIHJlc29sdmUocmVzcG9uc2UpO1xuICAgICAgICB9O1xuXG4gICAgICAgIHJlcXVlc3QuYWJvcnQgPSBmdW5jdGlvbiAoKSB7IHJldHVybiB4aHIuYWJvcnQoKTsgfTtcblxuICAgICAgICBpZiAocmVxdWVzdC5wcm9ncmVzcykge1xuICAgICAgICAgICAgaWYgKHJlcXVlc3QubWV0aG9kID09PSAnR0VUJykge1xuICAgICAgICAgICAgICAgIHhoci5hZGRFdmVudExpc3RlbmVyKCdwcm9ncmVzcycsIHJlcXVlc3QucHJvZ3Jlc3MpO1xuICAgICAgICAgICAgfSBlbHNlIGlmICgvXihQT1NUfFBVVCkkL2kudGVzdChyZXF1ZXN0Lm1ldGhvZCkpIHtcbiAgICAgICAgICAgICAgICB4aHIudXBsb2FkLmFkZEV2ZW50TGlzdGVuZXIoJ3Byb2dyZXNzJywgcmVxdWVzdC5wcm9ncmVzcyk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICB4aHIub3BlbihyZXF1ZXN0Lm1ldGhvZCwgcmVxdWVzdC5nZXRVcmwoKSwgdHJ1ZSk7XG5cbiAgICAgICAgaWYgKHJlcXVlc3QudGltZW91dCkge1xuICAgICAgICAgICAgeGhyLnRpbWVvdXQgPSByZXF1ZXN0LnRpbWVvdXQ7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAocmVxdWVzdC5yZXNwb25zZVR5cGUgJiYgJ3Jlc3BvbnNlVHlwZScgaW4geGhyKSB7XG4gICAgICAgICAgICB4aHIucmVzcG9uc2VUeXBlID0gcmVxdWVzdC5yZXNwb25zZVR5cGU7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAocmVxdWVzdC53aXRoQ3JlZGVudGlhbHMgfHwgcmVxdWVzdC5jcmVkZW50aWFscykge1xuICAgICAgICAgICAgeGhyLndpdGhDcmVkZW50aWFscyA9IHRydWU7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoIXJlcXVlc3QuY3Jvc3NPcmlnaW4pIHtcbiAgICAgICAgICAgIHJlcXVlc3QuaGVhZGVycy5zZXQoJ1gtUmVxdWVzdGVkLVdpdGgnLCAnWE1MSHR0cFJlcXVlc3QnKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJlcXVlc3QuaGVhZGVycy5mb3JFYWNoKGZ1bmN0aW9uICh2YWx1ZSwgbmFtZSkge1xuICAgICAgICAgICAgeGhyLnNldFJlcXVlc3RIZWFkZXIobmFtZSwgdmFsdWUpO1xuICAgICAgICB9KTtcblxuICAgICAgICB4aHIub25sb2FkID0gaGFuZGxlcjtcbiAgICAgICAgeGhyLm9uYWJvcnQgPSBoYW5kbGVyO1xuICAgICAgICB4aHIub25lcnJvciA9IGhhbmRsZXI7XG4gICAgICAgIHhoci5vbnRpbWVvdXQgPSBoYW5kbGVyO1xuICAgICAgICB4aHIuc2VuZChyZXF1ZXN0LmdldEJvZHkoKSk7XG4gICAgfSk7XG59O1xuXG4vKipcbiAqIEh0dHAgY2xpZW50IChOb2RlKS5cbiAqL1xuXG52YXIgbm9kZUNsaWVudCA9IGZ1bmN0aW9uIChyZXF1ZXN0KSB7XG5cbiAgICB2YXIgY2xpZW50ID0gcmVxdWlyZSgnZ290Jyk7XG5cbiAgICByZXR1cm4gbmV3IFByb21pc2VPYmooZnVuY3Rpb24gKHJlc29sdmUpIHtcblxuICAgICAgICB2YXIgdXJsID0gcmVxdWVzdC5nZXRVcmwoKTtcbiAgICAgICAgdmFyIGJvZHkgPSByZXF1ZXN0LmdldEJvZHkoKTtcbiAgICAgICAgdmFyIG1ldGhvZCA9IHJlcXVlc3QubWV0aG9kO1xuICAgICAgICB2YXIgaGVhZGVycyA9IHt9LCBoYW5kbGVyO1xuXG4gICAgICAgIHJlcXVlc3QuaGVhZGVycy5mb3JFYWNoKGZ1bmN0aW9uICh2YWx1ZSwgbmFtZSkge1xuICAgICAgICAgICAgaGVhZGVyc1tuYW1lXSA9IHZhbHVlO1xuICAgICAgICB9KTtcblxuICAgICAgICBjbGllbnQodXJsLCB7Ym9keTogYm9keSwgbWV0aG9kOiBtZXRob2QsIGhlYWRlcnM6IGhlYWRlcnN9KS50aGVuKGhhbmRsZXIgPSBmdW5jdGlvbiAocmVzcCkge1xuXG4gICAgICAgICAgICB2YXIgcmVzcG9uc2UgPSByZXF1ZXN0LnJlc3BvbmRXaXRoKHJlc3AuYm9keSwge1xuICAgICAgICAgICAgICAgICAgICBzdGF0dXM6IHJlc3Auc3RhdHVzQ29kZSxcbiAgICAgICAgICAgICAgICAgICAgc3RhdHVzVGV4dDogdHJpbShyZXNwLnN0YXR1c01lc3NhZ2UpXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgKTtcblxuICAgICAgICAgICAgZWFjaChyZXNwLmhlYWRlcnMsIGZ1bmN0aW9uICh2YWx1ZSwgbmFtZSkge1xuICAgICAgICAgICAgICAgIHJlc3BvbnNlLmhlYWRlcnMuc2V0KG5hbWUsIHZhbHVlKTtcbiAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICByZXNvbHZlKHJlc3BvbnNlKTtcblxuICAgICAgICB9LCBmdW5jdGlvbiAoZXJyb3IkJDEpIHsgcmV0dXJuIGhhbmRsZXIoZXJyb3IkJDEucmVzcG9uc2UpOyB9KTtcbiAgICB9KTtcbn07XG5cbi8qKlxuICogQmFzZSBjbGllbnQuXG4gKi9cblxudmFyIENsaWVudCA9IGZ1bmN0aW9uIChjb250ZXh0KSB7XG5cbiAgICB2YXIgcmVxSGFuZGxlcnMgPSBbc2VuZFJlcXVlc3RdLCByZXNIYW5kbGVycyA9IFtdLCBoYW5kbGVyO1xuXG4gICAgaWYgKCFpc09iamVjdChjb250ZXh0KSkge1xuICAgICAgICBjb250ZXh0ID0gbnVsbDtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBDbGllbnQocmVxdWVzdCkge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2VPYmooZnVuY3Rpb24gKHJlc29sdmUsIHJlamVjdCkge1xuXG4gICAgICAgICAgICBmdW5jdGlvbiBleGVjKCkge1xuXG4gICAgICAgICAgICAgICAgaGFuZGxlciA9IHJlcUhhbmRsZXJzLnBvcCgpO1xuXG4gICAgICAgICAgICAgICAgaWYgKGlzRnVuY3Rpb24oaGFuZGxlcikpIHtcbiAgICAgICAgICAgICAgICAgICAgaGFuZGxlci5jYWxsKGNvbnRleHQsIHJlcXVlc3QsIG5leHQpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIHdhcm4oKFwiSW52YWxpZCBpbnRlcmNlcHRvciBvZiB0eXBlIFwiICsgKHR5cGVvZiBoYW5kbGVyKSArIFwiLCBtdXN0IGJlIGEgZnVuY3Rpb25cIikpO1xuICAgICAgICAgICAgICAgICAgICBuZXh0KCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBmdW5jdGlvbiBuZXh0KHJlc3BvbnNlKSB7XG5cbiAgICAgICAgICAgICAgICBpZiAoaXNGdW5jdGlvbihyZXNwb25zZSkpIHtcblxuICAgICAgICAgICAgICAgICAgICByZXNIYW5kbGVycy51bnNoaWZ0KHJlc3BvbnNlKTtcblxuICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoaXNPYmplY3QocmVzcG9uc2UpKSB7XG5cbiAgICAgICAgICAgICAgICAgICAgcmVzSGFuZGxlcnMuZm9yRWFjaChmdW5jdGlvbiAoaGFuZGxlcikge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmVzcG9uc2UgPSB3aGVuKHJlc3BvbnNlLCBmdW5jdGlvbiAocmVzcG9uc2UpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gaGFuZGxlci5jYWxsKGNvbnRleHQsIHJlc3BvbnNlKSB8fCByZXNwb25zZTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH0sIHJlamVjdCk7XG4gICAgICAgICAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICAgICAgICAgIHdoZW4ocmVzcG9uc2UsIHJlc29sdmUsIHJlamVjdCk7XG5cbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIGV4ZWMoKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgZXhlYygpO1xuXG4gICAgICAgIH0sIGNvbnRleHQpO1xuICAgIH1cblxuICAgIENsaWVudC51c2UgPSBmdW5jdGlvbiAoaGFuZGxlcikge1xuICAgICAgICByZXFIYW5kbGVycy5wdXNoKGhhbmRsZXIpO1xuICAgIH07XG5cbiAgICByZXR1cm4gQ2xpZW50O1xufTtcblxuZnVuY3Rpb24gc2VuZFJlcXVlc3QocmVxdWVzdCwgcmVzb2x2ZSkge1xuXG4gICAgdmFyIGNsaWVudCA9IHJlcXVlc3QuY2xpZW50IHx8IChpbkJyb3dzZXIgPyB4aHJDbGllbnQgOiBub2RlQ2xpZW50KTtcblxuICAgIHJlc29sdmUoY2xpZW50KHJlcXVlc3QpKTtcbn1cblxuLyoqXG4gKiBIVFRQIEhlYWRlcnMuXG4gKi9cblxudmFyIEhlYWRlcnMgPSBmdW5jdGlvbiBIZWFkZXJzKGhlYWRlcnMpIHtcbiAgICB2YXIgdGhpcyQxID0gdGhpcztcblxuXG4gICAgdGhpcy5tYXAgPSB7fTtcblxuICAgIGVhY2goaGVhZGVycywgZnVuY3Rpb24gKHZhbHVlLCBuYW1lKSB7IHJldHVybiB0aGlzJDEuYXBwZW5kKG5hbWUsIHZhbHVlKTsgfSk7XG59O1xuXG5IZWFkZXJzLnByb3RvdHlwZS5oYXMgPSBmdW5jdGlvbiBoYXMgKG5hbWUpIHtcbiAgICByZXR1cm4gZ2V0TmFtZSh0aGlzLm1hcCwgbmFtZSkgIT09IG51bGw7XG59O1xuXG5IZWFkZXJzLnByb3RvdHlwZS5nZXQgPSBmdW5jdGlvbiBnZXQgKG5hbWUpIHtcblxuICAgIHZhciBsaXN0ID0gdGhpcy5tYXBbZ2V0TmFtZSh0aGlzLm1hcCwgbmFtZSldO1xuXG4gICAgcmV0dXJuIGxpc3QgPyBsaXN0LmpvaW4oKSA6IG51bGw7XG59O1xuXG5IZWFkZXJzLnByb3RvdHlwZS5nZXRBbGwgPSBmdW5jdGlvbiBnZXRBbGwgKG5hbWUpIHtcbiAgICByZXR1cm4gdGhpcy5tYXBbZ2V0TmFtZSh0aGlzLm1hcCwgbmFtZSldIHx8IFtdO1xufTtcblxuSGVhZGVycy5wcm90b3R5cGUuc2V0ID0gZnVuY3Rpb24gc2V0IChuYW1lLCB2YWx1ZSkge1xuICAgIHRoaXMubWFwW25vcm1hbGl6ZU5hbWUoZ2V0TmFtZSh0aGlzLm1hcCwgbmFtZSkgfHwgbmFtZSldID0gW3RyaW0odmFsdWUpXTtcbn07XG5cbkhlYWRlcnMucHJvdG90eXBlLmFwcGVuZCA9IGZ1bmN0aW9uIGFwcGVuZCAobmFtZSwgdmFsdWUpe1xuXG4gICAgdmFyIGxpc3QgPSB0aGlzLm1hcFtnZXROYW1lKHRoaXMubWFwLCBuYW1lKV07XG5cbiAgICBpZiAobGlzdCkge1xuICAgICAgICBsaXN0LnB1c2godHJpbSh2YWx1ZSkpO1xuICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMuc2V0KG5hbWUsIHZhbHVlKTtcbiAgICB9XG59O1xuXG5IZWFkZXJzLnByb3RvdHlwZS5kZWxldGUgPSBmdW5jdGlvbiBkZWxldGUkMSAobmFtZSl7XG4gICAgZGVsZXRlIHRoaXMubWFwW2dldE5hbWUodGhpcy5tYXAsIG5hbWUpXTtcbn07XG5cbkhlYWRlcnMucHJvdG90eXBlLmRlbGV0ZUFsbCA9IGZ1bmN0aW9uIGRlbGV0ZUFsbCAoKXtcbiAgICB0aGlzLm1hcCA9IHt9O1xufTtcblxuSGVhZGVycy5wcm90b3R5cGUuZm9yRWFjaCA9IGZ1bmN0aW9uIGZvckVhY2ggKGNhbGxiYWNrLCB0aGlzQXJnKSB7XG4gICAgICAgIHZhciB0aGlzJDEgPSB0aGlzO1xuXG4gICAgZWFjaCh0aGlzLm1hcCwgZnVuY3Rpb24gKGxpc3QsIG5hbWUpIHtcbiAgICAgICAgZWFjaChsaXN0LCBmdW5jdGlvbiAodmFsdWUpIHsgcmV0dXJuIGNhbGxiYWNrLmNhbGwodGhpc0FyZywgdmFsdWUsIG5hbWUsIHRoaXMkMSk7IH0pO1xuICAgIH0pO1xufTtcblxuZnVuY3Rpb24gZ2V0TmFtZShtYXAsIG5hbWUpIHtcbiAgICByZXR1cm4gT2JqZWN0LmtleXMobWFwKS5yZWR1Y2UoZnVuY3Rpb24gKHByZXYsIGN1cnIpIHtcbiAgICAgICAgcmV0dXJuIHRvTG93ZXIobmFtZSkgPT09IHRvTG93ZXIoY3VycikgPyBjdXJyIDogcHJldjtcbiAgICB9LCBudWxsKTtcbn1cblxuZnVuY3Rpb24gbm9ybWFsaXplTmFtZShuYW1lKSB7XG5cbiAgICBpZiAoL1teYS16MC05XFwtIyQlJicqKy5cXF5fYHx+XS9pLnRlc3QobmFtZSkpIHtcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignSW52YWxpZCBjaGFyYWN0ZXIgaW4gaGVhZGVyIGZpZWxkIG5hbWUnKTtcbiAgICB9XG5cbiAgICByZXR1cm4gdHJpbShuYW1lKTtcbn1cblxuLyoqXG4gKiBIVFRQIFJlc3BvbnNlLlxuICovXG5cbnZhciBSZXNwb25zZSA9IGZ1bmN0aW9uIFJlc3BvbnNlKGJvZHksIHJlZikge1xuICAgIHZhciB1cmwgPSByZWYudXJsO1xuICAgIHZhciBoZWFkZXJzID0gcmVmLmhlYWRlcnM7XG4gICAgdmFyIHN0YXR1cyA9IHJlZi5zdGF0dXM7XG4gICAgdmFyIHN0YXR1c1RleHQgPSByZWYuc3RhdHVzVGV4dDtcblxuXG4gICAgdGhpcy51cmwgPSB1cmw7XG4gICAgdGhpcy5vayA9IHN0YXR1cyA+PSAyMDAgJiYgc3RhdHVzIDwgMzAwO1xuICAgIHRoaXMuc3RhdHVzID0gc3RhdHVzIHx8IDA7XG4gICAgdGhpcy5zdGF0dXNUZXh0ID0gc3RhdHVzVGV4dCB8fCAnJztcbiAgICB0aGlzLmhlYWRlcnMgPSBuZXcgSGVhZGVycyhoZWFkZXJzKTtcbiAgICB0aGlzLmJvZHkgPSBib2R5O1xuXG4gICAgaWYgKGlzU3RyaW5nKGJvZHkpKSB7XG5cbiAgICAgICAgdGhpcy5ib2R5VGV4dCA9IGJvZHk7XG5cbiAgICB9IGVsc2UgaWYgKGlzQmxvYihib2R5KSkge1xuXG4gICAgICAgIHRoaXMuYm9keUJsb2IgPSBib2R5O1xuXG4gICAgICAgIGlmIChpc0Jsb2JUZXh0KGJvZHkpKSB7XG4gICAgICAgICAgICB0aGlzLmJvZHlUZXh0ID0gYmxvYlRleHQoYm9keSk7XG4gICAgICAgIH1cbiAgICB9XG59O1xuXG5SZXNwb25zZS5wcm90b3R5cGUuYmxvYiA9IGZ1bmN0aW9uIGJsb2IgKCkge1xuICAgIHJldHVybiB3aGVuKHRoaXMuYm9keUJsb2IpO1xufTtcblxuUmVzcG9uc2UucHJvdG90eXBlLnRleHQgPSBmdW5jdGlvbiB0ZXh0ICgpIHtcbiAgICByZXR1cm4gd2hlbih0aGlzLmJvZHlUZXh0KTtcbn07XG5cblJlc3BvbnNlLnByb3RvdHlwZS5qc29uID0gZnVuY3Rpb24ganNvbiAoKSB7XG4gICAgcmV0dXJuIHdoZW4odGhpcy50ZXh0KCksIGZ1bmN0aW9uICh0ZXh0KSB7IHJldHVybiBKU09OLnBhcnNlKHRleHQpOyB9KTtcbn07XG5cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShSZXNwb25zZS5wcm90b3R5cGUsICdkYXRhJywge1xuXG4gICAgZ2V0OiBmdW5jdGlvbiBnZXQoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmJvZHk7XG4gICAgfSxcblxuICAgIHNldDogZnVuY3Rpb24gc2V0KGJvZHkpIHtcbiAgICAgICAgdGhpcy5ib2R5ID0gYm9keTtcbiAgICB9XG5cbn0pO1xuXG5mdW5jdGlvbiBibG9iVGV4dChib2R5KSB7XG4gICAgcmV0dXJuIG5ldyBQcm9taXNlT2JqKGZ1bmN0aW9uIChyZXNvbHZlKSB7XG5cbiAgICAgICAgdmFyIHJlYWRlciA9IG5ldyBGaWxlUmVhZGVyKCk7XG5cbiAgICAgICAgcmVhZGVyLnJlYWRBc1RleHQoYm9keSk7XG4gICAgICAgIHJlYWRlci5vbmxvYWQgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICByZXNvbHZlKHJlYWRlci5yZXN1bHQpO1xuICAgICAgICB9O1xuXG4gICAgfSk7XG59XG5cbmZ1bmN0aW9uIGlzQmxvYlRleHQoYm9keSkge1xuICAgIHJldHVybiBib2R5LnR5cGUuaW5kZXhPZigndGV4dCcpID09PSAwIHx8IGJvZHkudHlwZS5pbmRleE9mKCdqc29uJykgIT09IC0xO1xufVxuXG4vKipcbiAqIEhUVFAgUmVxdWVzdC5cbiAqL1xuXG52YXIgUmVxdWVzdCA9IGZ1bmN0aW9uIFJlcXVlc3Qob3B0aW9ucyQkMSkge1xuXG4gICAgdGhpcy5ib2R5ID0gbnVsbDtcbiAgICB0aGlzLnBhcmFtcyA9IHt9O1xuXG4gICAgYXNzaWduKHRoaXMsIG9wdGlvbnMkJDEsIHtcbiAgICAgICAgbWV0aG9kOiB0b1VwcGVyKG9wdGlvbnMkJDEubWV0aG9kIHx8ICdHRVQnKVxuICAgIH0pO1xuXG4gICAgaWYgKCEodGhpcy5oZWFkZXJzIGluc3RhbmNlb2YgSGVhZGVycykpIHtcbiAgICAgICAgdGhpcy5oZWFkZXJzID0gbmV3IEhlYWRlcnModGhpcy5oZWFkZXJzKTtcbiAgICB9XG59O1xuXG5SZXF1ZXN0LnByb3RvdHlwZS5nZXRVcmwgPSBmdW5jdGlvbiBnZXRVcmwgKCl7XG4gICAgcmV0dXJuIFVybCh0aGlzKTtcbn07XG5cblJlcXVlc3QucHJvdG90eXBlLmdldEJvZHkgPSBmdW5jdGlvbiBnZXRCb2R5ICgpe1xuICAgIHJldHVybiB0aGlzLmJvZHk7XG59O1xuXG5SZXF1ZXN0LnByb3RvdHlwZS5yZXNwb25kV2l0aCA9IGZ1bmN0aW9uIHJlc3BvbmRXaXRoIChib2R5LCBvcHRpb25zJCQxKSB7XG4gICAgcmV0dXJuIG5ldyBSZXNwb25zZShib2R5LCBhc3NpZ24ob3B0aW9ucyQkMSB8fCB7fSwge3VybDogdGhpcy5nZXRVcmwoKX0pKTtcbn07XG5cbi8qKlxuICogU2VydmljZSBmb3Igc2VuZGluZyBuZXR3b3JrIHJlcXVlc3RzLlxuICovXG5cbnZhciBDT01NT05fSEVBREVSUyA9IHsnQWNjZXB0JzogJ2FwcGxpY2F0aW9uL2pzb24sIHRleHQvcGxhaW4sICovKid9O1xudmFyIEpTT05fQ09OVEVOVF9UWVBFID0geydDb250ZW50LVR5cGUnOiAnYXBwbGljYXRpb24vanNvbjtjaGFyc2V0PXV0Zi04J307XG5cbmZ1bmN0aW9uIEh0dHAob3B0aW9ucyQkMSkge1xuXG4gICAgdmFyIHNlbGYgPSB0aGlzIHx8IHt9LCBjbGllbnQgPSBDbGllbnQoc2VsZi4kdm0pO1xuXG4gICAgZGVmYXVsdHMob3B0aW9ucyQkMSB8fCB7fSwgc2VsZi4kb3B0aW9ucywgSHR0cC5vcHRpb25zKTtcblxuICAgIEh0dHAuaW50ZXJjZXB0b3JzLmZvckVhY2goZnVuY3Rpb24gKGhhbmRsZXIpIHtcblxuICAgICAgICBpZiAoaXNTdHJpbmcoaGFuZGxlcikpIHtcbiAgICAgICAgICAgIGhhbmRsZXIgPSBIdHRwLmludGVyY2VwdG9yW2hhbmRsZXJdO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGlzRnVuY3Rpb24oaGFuZGxlcikpIHtcbiAgICAgICAgICAgIGNsaWVudC51c2UoaGFuZGxlcik7XG4gICAgICAgIH1cblxuICAgIH0pO1xuXG4gICAgcmV0dXJuIGNsaWVudChuZXcgUmVxdWVzdChvcHRpb25zJCQxKSkudGhlbihmdW5jdGlvbiAocmVzcG9uc2UpIHtcblxuICAgICAgICByZXR1cm4gcmVzcG9uc2Uub2sgPyByZXNwb25zZSA6IFByb21pc2VPYmoucmVqZWN0KHJlc3BvbnNlKTtcblxuICAgIH0sIGZ1bmN0aW9uIChyZXNwb25zZSkge1xuXG4gICAgICAgIGlmIChyZXNwb25zZSBpbnN0YW5jZW9mIEVycm9yKSB7XG4gICAgICAgICAgICBlcnJvcihyZXNwb25zZSk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gUHJvbWlzZU9iai5yZWplY3QocmVzcG9uc2UpO1xuICAgIH0pO1xufVxuXG5IdHRwLm9wdGlvbnMgPSB7fTtcblxuSHR0cC5oZWFkZXJzID0ge1xuICAgIHB1dDogSlNPTl9DT05URU5UX1RZUEUsXG4gICAgcG9zdDogSlNPTl9DT05URU5UX1RZUEUsXG4gICAgcGF0Y2g6IEpTT05fQ09OVEVOVF9UWVBFLFxuICAgIGRlbGV0ZTogSlNPTl9DT05URU5UX1RZUEUsXG4gICAgY29tbW9uOiBDT01NT05fSEVBREVSUyxcbiAgICBjdXN0b206IHt9XG59O1xuXG5IdHRwLmludGVyY2VwdG9yID0ge2JlZm9yZTogYmVmb3JlLCBtZXRob2Q6IG1ldGhvZCwganNvbnA6IGpzb25wLCBqc29uOiBqc29uLCBmb3JtOiBmb3JtLCBoZWFkZXI6IGhlYWRlciwgY29yczogY29yc307XG5IdHRwLmludGVyY2VwdG9ycyA9IFsnYmVmb3JlJywgJ21ldGhvZCcsICdqc29ucCcsICdqc29uJywgJ2Zvcm0nLCAnaGVhZGVyJywgJ2NvcnMnXTtcblxuWydnZXQnLCAnZGVsZXRlJywgJ2hlYWQnLCAnanNvbnAnXS5mb3JFYWNoKGZ1bmN0aW9uIChtZXRob2QkJDEpIHtcblxuICAgIEh0dHBbbWV0aG9kJCQxXSA9IGZ1bmN0aW9uICh1cmwsIG9wdGlvbnMkJDEpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMoYXNzaWduKG9wdGlvbnMkJDEgfHwge30sIHt1cmw6IHVybCwgbWV0aG9kOiBtZXRob2QkJDF9KSk7XG4gICAgfTtcblxufSk7XG5cblsncG9zdCcsICdwdXQnLCAncGF0Y2gnXS5mb3JFYWNoKGZ1bmN0aW9uIChtZXRob2QkJDEpIHtcblxuICAgIEh0dHBbbWV0aG9kJCQxXSA9IGZ1bmN0aW9uICh1cmwsIGJvZHksIG9wdGlvbnMkJDEpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMoYXNzaWduKG9wdGlvbnMkJDEgfHwge30sIHt1cmw6IHVybCwgbWV0aG9kOiBtZXRob2QkJDEsIGJvZHk6IGJvZHl9KSk7XG4gICAgfTtcblxufSk7XG5cbi8qKlxuICogU2VydmljZSBmb3IgaW50ZXJhY3Rpbmcgd2l0aCBSRVNUZnVsIHNlcnZpY2VzLlxuICovXG5cbmZ1bmN0aW9uIFJlc291cmNlKHVybCwgcGFyYW1zLCBhY3Rpb25zLCBvcHRpb25zJCQxKSB7XG5cbiAgICB2YXIgc2VsZiA9IHRoaXMgfHwge30sIHJlc291cmNlID0ge307XG5cbiAgICBhY3Rpb25zID0gYXNzaWduKHt9LFxuICAgICAgICBSZXNvdXJjZS5hY3Rpb25zLFxuICAgICAgICBhY3Rpb25zXG4gICAgKTtcblxuICAgIGVhY2goYWN0aW9ucywgZnVuY3Rpb24gKGFjdGlvbiwgbmFtZSkge1xuXG4gICAgICAgIGFjdGlvbiA9IG1lcmdlKHt1cmw6IHVybCwgcGFyYW1zOiBhc3NpZ24oe30sIHBhcmFtcyl9LCBvcHRpb25zJCQxLCBhY3Rpb24pO1xuXG4gICAgICAgIHJlc291cmNlW25hbWVdID0gZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgcmV0dXJuIChzZWxmLiRodHRwIHx8IEh0dHApKG9wdHMoYWN0aW9uLCBhcmd1bWVudHMpKTtcbiAgICAgICAgfTtcbiAgICB9KTtcblxuICAgIHJldHVybiByZXNvdXJjZTtcbn1cblxuZnVuY3Rpb24gb3B0cyhhY3Rpb24sIGFyZ3MpIHtcblxuICAgIHZhciBvcHRpb25zJCQxID0gYXNzaWduKHt9LCBhY3Rpb24pLCBwYXJhbXMgPSB7fSwgYm9keTtcblxuICAgIHN3aXRjaCAoYXJncy5sZW5ndGgpIHtcblxuICAgICAgICBjYXNlIDI6XG5cbiAgICAgICAgICAgIHBhcmFtcyA9IGFyZ3NbMF07XG4gICAgICAgICAgICBib2R5ID0gYXJnc1sxXTtcblxuICAgICAgICAgICAgYnJlYWs7XG5cbiAgICAgICAgY2FzZSAxOlxuXG4gICAgICAgICAgICBpZiAoL14oUE9TVHxQVVR8UEFUQ0gpJC9pLnRlc3Qob3B0aW9ucyQkMS5tZXRob2QpKSB7XG4gICAgICAgICAgICAgICAgYm9keSA9IGFyZ3NbMF07XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHBhcmFtcyA9IGFyZ3NbMF07XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgIGNhc2UgMDpcblxuICAgICAgICAgICAgYnJlYWs7XG5cbiAgICAgICAgZGVmYXVsdDpcblxuICAgICAgICAgICAgdGhyb3cgJ0V4cGVjdGVkIHVwIHRvIDIgYXJndW1lbnRzIFtwYXJhbXMsIGJvZHldLCBnb3QgJyArIGFyZ3MubGVuZ3RoICsgJyBhcmd1bWVudHMnO1xuICAgIH1cblxuICAgIG9wdGlvbnMkJDEuYm9keSA9IGJvZHk7XG4gICAgb3B0aW9ucyQkMS5wYXJhbXMgPSBhc3NpZ24oe30sIG9wdGlvbnMkJDEucGFyYW1zLCBwYXJhbXMpO1xuXG4gICAgcmV0dXJuIG9wdGlvbnMkJDE7XG59XG5cblJlc291cmNlLmFjdGlvbnMgPSB7XG5cbiAgICBnZXQ6IHttZXRob2Q6ICdHRVQnfSxcbiAgICBzYXZlOiB7bWV0aG9kOiAnUE9TVCd9LFxuICAgIHF1ZXJ5OiB7bWV0aG9kOiAnR0VUJ30sXG4gICAgdXBkYXRlOiB7bWV0aG9kOiAnUFVUJ30sXG4gICAgcmVtb3ZlOiB7bWV0aG9kOiAnREVMRVRFJ30sXG4gICAgZGVsZXRlOiB7bWV0aG9kOiAnREVMRVRFJ31cblxufTtcblxuLyoqXG4gKiBJbnN0YWxsIHBsdWdpbi5cbiAqL1xuXG5mdW5jdGlvbiBwbHVnaW4oVnVlKSB7XG5cbiAgICBpZiAocGx1Z2luLmluc3RhbGxlZCkge1xuICAgICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgVXRpbChWdWUpO1xuXG4gICAgVnVlLnVybCA9IFVybDtcbiAgICBWdWUuaHR0cCA9IEh0dHA7XG4gICAgVnVlLnJlc291cmNlID0gUmVzb3VyY2U7XG4gICAgVnVlLlByb21pc2UgPSBQcm9taXNlT2JqO1xuXG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnRpZXMoVnVlLnByb3RvdHlwZSwge1xuXG4gICAgICAgICR1cmw6IHtcbiAgICAgICAgICAgIGdldDogZnVuY3Rpb24gZ2V0KCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBvcHRpb25zKFZ1ZS51cmwsIHRoaXMsIHRoaXMuJG9wdGlvbnMudXJsKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSxcblxuICAgICAgICAkaHR0cDoge1xuICAgICAgICAgICAgZ2V0OiBmdW5jdGlvbiBnZXQoKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIG9wdGlvbnMoVnVlLmh0dHAsIHRoaXMsIHRoaXMuJG9wdGlvbnMuaHR0cCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0sXG5cbiAgICAgICAgJHJlc291cmNlOiB7XG4gICAgICAgICAgICBnZXQ6IGZ1bmN0aW9uIGdldCgpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gVnVlLnJlc291cmNlLmJpbmQodGhpcyk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0sXG5cbiAgICAgICAgJHByb21pc2U6IHtcbiAgICAgICAgICAgIGdldDogZnVuY3Rpb24gZ2V0KCkge1xuICAgICAgICAgICAgICAgIHZhciB0aGlzJDEgPSB0aGlzO1xuXG4gICAgICAgICAgICAgICAgcmV0dXJuIGZ1bmN0aW9uIChleGVjdXRvcikgeyByZXR1cm4gbmV3IFZ1ZS5Qcm9taXNlKGV4ZWN1dG9yLCB0aGlzJDEpOyB9O1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICB9KTtcbn1cblxuaWYgKHR5cGVvZiB3aW5kb3cgIT09ICd1bmRlZmluZWQnICYmIHdpbmRvdy5WdWUpIHtcbiAgICB3aW5kb3cuVnVlLnVzZShwbHVnaW4pO1xufVxuXG5leHBvcnQgZGVmYXVsdCBwbHVnaW47XG5leHBvcnQgeyBVcmwsIEh0dHAsIFJlc291cmNlIH07XG5cblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyAuL25vZGVfbW9kdWxlcy92dWUtcmVzb3VyY2UvZGlzdC92dWUtcmVzb3VyY2UuZXMyMDE1LmpzXG4vLyBtb2R1bGUgaWQgPSAxM1xuLy8gbW9kdWxlIGNodW5rcyA9IDAiLCIvKiAoaWdub3JlZCkgKi9cblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyBnb3QgKGlnbm9yZWQpXG4vLyBtb2R1bGUgaWQgPSAxNFxuLy8gbW9kdWxlIGNodW5rcyA9IDAiLCJ2YXIgZGlzcG9zZWQgPSBmYWxzZVxuZnVuY3Rpb24gaW5qZWN0U3R5bGUgKHNzckNvbnRleHQpIHtcbiAgaWYgKGRpc3Bvc2VkKSByZXR1cm5cbiAgcmVxdWlyZShcIiEhdnVlLXN0eWxlLWxvYWRlciFjc3MtbG9hZGVyP3NvdXJjZU1hcCEuLi8uLi8uLi8uLi8uLi9ub2RlX21vZHVsZXMvdnVlLWxvYWRlci9saWIvc3R5bGUtY29tcGlsZXIvaW5kZXg/e1xcXCJ2dWVcXFwiOnRydWUsXFxcImlkXFxcIjpcXFwiZGF0YS12LWU5YzgwMzE4XFxcIixcXFwic2NvcGVkXFxcIjp0cnVlLFxcXCJoYXNJbmxpbmVDb25maWdcXFwiOnRydWV9IS4uLy4uLy4uLy4uLy4uL25vZGVfbW9kdWxlcy92dWUtbG9hZGVyL2xpYi9zZWxlY3Rvcj90eXBlPXN0eWxlcyZpbmRleD0wIS4vQ2xpZW50cy52dWVcIilcbn1cbnZhciBDb21wb25lbnQgPSByZXF1aXJlKFwiIS4uLy4uLy4uLy4uLy4uL25vZGVfbW9kdWxlcy92dWUtbG9hZGVyL2xpYi9jb21wb25lbnQtbm9ybWFsaXplclwiKShcbiAgLyogc2NyaXB0ICovXG4gIHJlcXVpcmUoXCIhIWJhYmVsLWxvYWRlcj97XFxcImNhY2hlRGlyZWN0b3J5XFxcIjp0cnVlLFxcXCJwcmVzZXRzXFxcIjpbW1xcXCJlbnZcXFwiLHtcXFwibW9kdWxlc1xcXCI6ZmFsc2UsXFxcInRhcmdldHNcXFwiOntcXFwiYnJvd3NlcnNcXFwiOltcXFwiPiAyJVxcXCJdLFxcXCJ1Z2xpZnlcXFwiOnRydWV9fV1dfSEuLi8uLi8uLi8uLi8uLi9ub2RlX21vZHVsZXMvdnVlLWxvYWRlci9saWIvc2VsZWN0b3I/dHlwZT1zY3JpcHQmaW5kZXg9MCEuL0NsaWVudHMudnVlXCIpLFxuICAvKiB0ZW1wbGF0ZSAqL1xuICByZXF1aXJlKFwiISEuLi8uLi8uLi8uLi8uLi9ub2RlX21vZHVsZXMvdnVlLWxvYWRlci9saWIvdGVtcGxhdGUtY29tcGlsZXIvaW5kZXg/e1xcXCJpZFxcXCI6XFxcImRhdGEtdi1lOWM4MDMxOFxcXCIsXFxcImhhc1Njb3BlZFxcXCI6dHJ1ZX0hLi4vLi4vLi4vLi4vLi4vbm9kZV9tb2R1bGVzL3Z1ZS1sb2FkZXIvbGliL3NlbGVjdG9yP3R5cGU9dGVtcGxhdGUmaW5kZXg9MCEuL0NsaWVudHMudnVlXCIpLFxuICAvKiBzdHlsZXMgKi9cbiAgaW5qZWN0U3R5bGUsXG4gIC8qIHNjb3BlSWQgKi9cbiAgXCJkYXRhLXYtZTljODAzMThcIixcbiAgLyogbW9kdWxlSWRlbnRpZmllciAoc2VydmVyIG9ubHkpICovXG4gIG51bGxcbilcbkNvbXBvbmVudC5vcHRpb25zLl9fZmlsZSA9IFwiL2hvbWUvaHlkcm9nZW4vd29yay9zbmlwZS1pdC9yZXNvdXJjZXMvYXNzZXRzL2pzL2NvbXBvbmVudHMvcGFzc3BvcnQvQ2xpZW50cy52dWVcIlxuaWYgKENvbXBvbmVudC5lc01vZHVsZSAmJiBPYmplY3Qua2V5cyhDb21wb25lbnQuZXNNb2R1bGUpLnNvbWUoZnVuY3Rpb24gKGtleSkge3JldHVybiBrZXkgIT09IFwiZGVmYXVsdFwiICYmIGtleS5zdWJzdHIoMCwgMikgIT09IFwiX19cIn0pKSB7Y29uc29sZS5lcnJvcihcIm5hbWVkIGV4cG9ydHMgYXJlIG5vdCBzdXBwb3J0ZWQgaW4gKi52dWUgZmlsZXMuXCIpfVxuaWYgKENvbXBvbmVudC5vcHRpb25zLmZ1bmN0aW9uYWwpIHtjb25zb2xlLmVycm9yKFwiW3Z1ZS1sb2FkZXJdIENsaWVudHMudnVlOiBmdW5jdGlvbmFsIGNvbXBvbmVudHMgYXJlIG5vdCBzdXBwb3J0ZWQgd2l0aCB0ZW1wbGF0ZXMsIHRoZXkgc2hvdWxkIHVzZSByZW5kZXIgZnVuY3Rpb25zLlwiKX1cblxuLyogaG90IHJlbG9hZCAqL1xuaWYgKG1vZHVsZS5ob3QpIHsoZnVuY3Rpb24gKCkge1xuICB2YXIgaG90QVBJID0gcmVxdWlyZShcInZ1ZS1ob3QtcmVsb2FkLWFwaVwiKVxuICBob3RBUEkuaW5zdGFsbChyZXF1aXJlKFwidnVlXCIpLCBmYWxzZSlcbiAgaWYgKCFob3RBUEkuY29tcGF0aWJsZSkgcmV0dXJuXG4gIG1vZHVsZS5ob3QuYWNjZXB0KClcbiAgaWYgKCFtb2R1bGUuaG90LmRhdGEpIHtcbiAgICBob3RBUEkuY3JlYXRlUmVjb3JkKFwiZGF0YS12LWU5YzgwMzE4XCIsIENvbXBvbmVudC5vcHRpb25zKVxuICB9IGVsc2Uge1xuICAgIGhvdEFQSS5yZWxvYWQoXCJkYXRhLXYtZTljODAzMThcIiwgQ29tcG9uZW50Lm9wdGlvbnMpXG4gIH1cbiAgbW9kdWxlLmhvdC5kaXNwb3NlKGZ1bmN0aW9uIChkYXRhKSB7XG4gICAgZGlzcG9zZWQgPSB0cnVlXG4gIH0pXG59KSgpfVxuXG5tb2R1bGUuZXhwb3J0cyA9IENvbXBvbmVudC5leHBvcnRzXG5cblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyAuL3Jlc291cmNlcy9hc3NldHMvanMvY29tcG9uZW50cy9wYXNzcG9ydC9DbGllbnRzLnZ1ZVxuLy8gbW9kdWxlIGlkID0gMTVcbi8vIG1vZHVsZSBjaHVua3MgPSAwIiwiLy8gc3R5bGUtbG9hZGVyOiBBZGRzIHNvbWUgY3NzIHRvIHRoZSBET00gYnkgYWRkaW5nIGEgPHN0eWxlPiB0YWdcblxuLy8gbG9hZCB0aGUgc3R5bGVzXG52YXIgY29udGVudCA9IHJlcXVpcmUoXCIhIS4uLy4uLy4uLy4uLy4uL25vZGVfbW9kdWxlcy9jc3MtbG9hZGVyL2luZGV4LmpzP3NvdXJjZU1hcCEuLi8uLi8uLi8uLi8uLi9ub2RlX21vZHVsZXMvdnVlLWxvYWRlci9saWIvc3R5bGUtY29tcGlsZXIvaW5kZXguanM/e1xcXCJ2dWVcXFwiOnRydWUsXFxcImlkXFxcIjpcXFwiZGF0YS12LWU5YzgwMzE4XFxcIixcXFwic2NvcGVkXFxcIjp0cnVlLFxcXCJoYXNJbmxpbmVDb25maWdcXFwiOnRydWV9IS4uLy4uLy4uLy4uLy4uL25vZGVfbW9kdWxlcy92dWUtbG9hZGVyL2xpYi9zZWxlY3Rvci5qcz90eXBlPXN0eWxlcyZpbmRleD0wIS4vQ2xpZW50cy52dWVcIik7XG5pZih0eXBlb2YgY29udGVudCA9PT0gJ3N0cmluZycpIGNvbnRlbnQgPSBbW21vZHVsZS5pZCwgY29udGVudCwgJyddXTtcbmlmKGNvbnRlbnQubG9jYWxzKSBtb2R1bGUuZXhwb3J0cyA9IGNvbnRlbnQubG9jYWxzO1xuLy8gYWRkIHRoZSBzdHlsZXMgdG8gdGhlIERPTVxudmFyIHVwZGF0ZSA9IHJlcXVpcmUoXCIhLi4vLi4vLi4vLi4vLi4vbm9kZV9tb2R1bGVzL3Z1ZS1zdHlsZS1sb2FkZXIvbGliL2FkZFN0eWxlc0NsaWVudC5qc1wiKShcImQzMzFjNDhhXCIsIGNvbnRlbnQsIGZhbHNlKTtcbi8vIEhvdCBNb2R1bGUgUmVwbGFjZW1lbnRcbmlmKG1vZHVsZS5ob3QpIHtcbiAvLyBXaGVuIHRoZSBzdHlsZXMgY2hhbmdlLCB1cGRhdGUgdGhlIDxzdHlsZT4gdGFnc1xuIGlmKCFjb250ZW50LmxvY2Fscykge1xuICAgbW9kdWxlLmhvdC5hY2NlcHQoXCIhIS4uLy4uLy4uLy4uLy4uL25vZGVfbW9kdWxlcy9jc3MtbG9hZGVyL2luZGV4LmpzP3NvdXJjZU1hcCEuLi8uLi8uLi8uLi8uLi9ub2RlX21vZHVsZXMvdnVlLWxvYWRlci9saWIvc3R5bGUtY29tcGlsZXIvaW5kZXguanM/e1xcXCJ2dWVcXFwiOnRydWUsXFxcImlkXFxcIjpcXFwiZGF0YS12LWU5YzgwMzE4XFxcIixcXFwic2NvcGVkXFxcIjp0cnVlLFxcXCJoYXNJbmxpbmVDb25maWdcXFwiOnRydWV9IS4uLy4uLy4uLy4uLy4uL25vZGVfbW9kdWxlcy92dWUtbG9hZGVyL2xpYi9zZWxlY3Rvci5qcz90eXBlPXN0eWxlcyZpbmRleD0wIS4vQ2xpZW50cy52dWVcIiwgZnVuY3Rpb24oKSB7XG4gICAgIHZhciBuZXdDb250ZW50ID0gcmVxdWlyZShcIiEhLi4vLi4vLi4vLi4vLi4vbm9kZV9tb2R1bGVzL2Nzcy1sb2FkZXIvaW5kZXguanM/c291cmNlTWFwIS4uLy4uLy4uLy4uLy4uL25vZGVfbW9kdWxlcy92dWUtbG9hZGVyL2xpYi9zdHlsZS1jb21waWxlci9pbmRleC5qcz97XFxcInZ1ZVxcXCI6dHJ1ZSxcXFwiaWRcXFwiOlxcXCJkYXRhLXYtZTljODAzMThcXFwiLFxcXCJzY29wZWRcXFwiOnRydWUsXFxcImhhc0lubGluZUNvbmZpZ1xcXCI6dHJ1ZX0hLi4vLi4vLi4vLi4vLi4vbm9kZV9tb2R1bGVzL3Z1ZS1sb2FkZXIvbGliL3NlbGVjdG9yLmpzP3R5cGU9c3R5bGVzJmluZGV4PTAhLi9DbGllbnRzLnZ1ZVwiKTtcbiAgICAgaWYodHlwZW9mIG5ld0NvbnRlbnQgPT09ICdzdHJpbmcnKSBuZXdDb250ZW50ID0gW1ttb2R1bGUuaWQsIG5ld0NvbnRlbnQsICcnXV07XG4gICAgIHVwZGF0ZShuZXdDb250ZW50KTtcbiAgIH0pO1xuIH1cbiAvLyBXaGVuIHRoZSBtb2R1bGUgaXMgZGlzcG9zZWQsIHJlbW92ZSB0aGUgPHN0eWxlPiB0YWdzXG4gbW9kdWxlLmhvdC5kaXNwb3NlKGZ1bmN0aW9uKCkgeyB1cGRhdGUoKTsgfSk7XG59XG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gLi9ub2RlX21vZHVsZXMvdnVlLXN0eWxlLWxvYWRlciEuL25vZGVfbW9kdWxlcy9jc3MtbG9hZGVyP3NvdXJjZU1hcCEuL25vZGVfbW9kdWxlcy92dWUtbG9hZGVyL2xpYi9zdHlsZS1jb21waWxlcj97XCJ2dWVcIjp0cnVlLFwiaWRcIjpcImRhdGEtdi1lOWM4MDMxOFwiLFwic2NvcGVkXCI6dHJ1ZSxcImhhc0lubGluZUNvbmZpZ1wiOnRydWV9IS4vbm9kZV9tb2R1bGVzL3Z1ZS1sb2FkZXIvbGliL3NlbGVjdG9yLmpzP3R5cGU9c3R5bGVzJmluZGV4PTAhLi9yZXNvdXJjZXMvYXNzZXRzL2pzL2NvbXBvbmVudHMvcGFzc3BvcnQvQ2xpZW50cy52dWVcbi8vIG1vZHVsZSBpZCA9IDE2XG4vLyBtb2R1bGUgY2h1bmtzID0gMCIsImV4cG9ydHMgPSBtb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoXCIuLi8uLi8uLi8uLi8uLi9ub2RlX21vZHVsZXMvY3NzLWxvYWRlci9saWIvY3NzLWJhc2UuanNcIikodHJ1ZSk7XG4vLyBpbXBvcnRzXG5cblxuLy8gbW9kdWxlXG5leHBvcnRzLnB1c2goW21vZHVsZS5pZCwgXCJcXG4uYWN0aW9uLWxpbmtbZGF0YS12LWU5YzgwMzE4XSB7XFxuICAgIGN1cnNvcjogcG9pbnRlcjtcXG59XFxuLm0tYi1ub25lW2RhdGEtdi1lOWM4MDMxOF0ge1xcbiAgICBtYXJnaW4tYm90dG9tOiAwO1xcbn1cXG5cIiwgXCJcIiwge1widmVyc2lvblwiOjMsXCJzb3VyY2VzXCI6W1wiL2hvbWUvaHlkcm9nZW4vd29yay9zbmlwZS1pdC9yZXNvdXJjZXMvYXNzZXRzL2pzL2NvbXBvbmVudHMvcGFzc3BvcnQvQ2xpZW50cy52dWU/MzU4NjdjZTRcIl0sXCJuYW1lc1wiOltdLFwibWFwcGluZ3NcIjpcIjtBQUNBO0lBQ0EsZ0JBQUE7Q0FDQTtBQUVBO0lBQ0EsaUJBQUE7Q0FDQVwiLFwiZmlsZVwiOlwiQ2xpZW50cy52dWVcIixcInNvdXJjZXNDb250ZW50XCI6W1wiPHN0eWxlIHNjb3BlZD5cXG4gICAgLmFjdGlvbi1saW5rIHtcXG4gICAgICAgIGN1cnNvcjogcG9pbnRlcjtcXG4gICAgfVxcblxcbiAgICAubS1iLW5vbmUge1xcbiAgICAgICAgbWFyZ2luLWJvdHRvbTogMDtcXG4gICAgfVxcbjwvc3R5bGU+XFxuXFxuPHRlbXBsYXRlPlxcbiAgICA8ZGl2PlxcbiAgICAgICAgPGRpdiBjbGFzcz1cXFwicGFuZWwgcGFuZWwtZGVmYXVsdFxcXCI+XFxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cXFwicGFuZWwtaGVhZGluZ1xcXCI+XFxuICAgICAgICAgICAgICAgIDxkaXYgc3R5bGU9XFxcImRpc3BsYXk6IGZsZXg7IGp1c3RpZnktY29udGVudDogc3BhY2UtYmV0d2VlbjsgYWxpZ24taXRlbXM6IGNlbnRlcjtcXFwiPlxcbiAgICAgICAgICAgICAgICAgICAgPHNwYW4+XFxuICAgICAgICAgICAgICAgICAgICAgICAgT0F1dGggQ2xpZW50c1xcbiAgICAgICAgICAgICAgICAgICAgPC9zcGFuPlxcblxcbiAgICAgICAgICAgICAgICAgICAgPGEgY2xhc3M9XFxcImFjdGlvbi1saW5rXFxcIiBAY2xpY2s9XFxcInNob3dDcmVhdGVDbGllbnRGb3JtXFxcIj5cXG4gICAgICAgICAgICAgICAgICAgICAgICBDcmVhdGUgTmV3IENsaWVudFxcbiAgICAgICAgICAgICAgICAgICAgPC9hPlxcbiAgICAgICAgICAgICAgICA8L2Rpdj5cXG4gICAgICAgICAgICA8L2Rpdj5cXG5cXG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVxcXCJwYW5lbC1ib2R5XFxcIj5cXG4gICAgICAgICAgICAgICAgPCEtLSBDdXJyZW50IENsaWVudHMgLS0+XFxuICAgICAgICAgICAgICAgIDxwIGNsYXNzPVxcXCJtLWItbm9uZVxcXCIgdi1pZj1cXFwiY2xpZW50cy5sZW5ndGggPT09IDBcXFwiPlxcbiAgICAgICAgICAgICAgICAgICAgWW91IGhhdmUgbm90IGNyZWF0ZWQgYW55IE9BdXRoIGNsaWVudHMuXFxuICAgICAgICAgICAgICAgIDwvcD5cXG5cXG4gICAgICAgICAgICAgICAgPHRhYmxlIGNsYXNzPVxcXCJ0YWJsZSB0YWJsZS1ib3JkZXJsZXNzIG0tYi1ub25lXFxcIiB2LWlmPVxcXCJjbGllbnRzLmxlbmd0aCA+IDBcXFwiPlxcbiAgICAgICAgICAgICAgICAgICAgPHRoZWFkPlxcbiAgICAgICAgICAgICAgICAgICAgICAgIDx0cj5cXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPHRoPkNsaWVudCBJRDwvdGg+XFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDx0aD5OYW1lPC90aD5cXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPHRoPlNlY3JldDwvdGg+XFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDx0aD48L3RoPlxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8dGg+PC90aD5cXG4gICAgICAgICAgICAgICAgICAgICAgICA8L3RyPlxcbiAgICAgICAgICAgICAgICAgICAgPC90aGVhZD5cXG5cXG4gICAgICAgICAgICAgICAgICAgIDx0Ym9keT5cXG4gICAgICAgICAgICAgICAgICAgICAgICA8dHIgdi1mb3I9XFxcImNsaWVudCBpbiBjbGllbnRzXFxcIj5cXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPCEtLSBJRCAtLT5cXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPHRkIHN0eWxlPVxcXCJ2ZXJ0aWNhbC1hbGlnbjogbWlkZGxlO1xcXCI+XFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7eyBjbGllbnQuaWQgfX1cXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC90ZD5cXG5cXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPCEtLSBOYW1lIC0tPlxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8dGQgc3R5bGU9XFxcInZlcnRpY2FsLWFsaWduOiBtaWRkbGU7XFxcIj5cXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHt7IGNsaWVudC5uYW1lIH19XFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvdGQ+XFxuXFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwhLS0gU2VjcmV0IC0tPlxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8dGQgc3R5bGU9XFxcInZlcnRpY2FsLWFsaWduOiBtaWRkbGU7XFxcIj5cXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxjb2RlPnt7IGNsaWVudC5zZWNyZXQgfX08L2NvZGU+XFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvdGQ+XFxuXFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwhLS0gRWRpdCBCdXR0b24gLS0+XFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDx0ZCBzdHlsZT1cXFwidmVydGljYWwtYWxpZ246IG1pZGRsZTtcXFwiPlxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGEgY2xhc3M9XFxcImFjdGlvbi1saW5rXFxcIiBAY2xpY2s9XFxcImVkaXQoY2xpZW50KVxcXCI+XFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRWRpdFxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9hPlxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3RkPlxcblxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8IS0tIERlbGV0ZSBCdXR0b24gLS0+XFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDx0ZCBzdHlsZT1cXFwidmVydGljYWwtYWxpZ246IG1pZGRsZTtcXFwiPlxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGEgY2xhc3M9XFxcImFjdGlvbi1saW5rIHRleHQtZGFuZ2VyXFxcIiBAY2xpY2s9XFxcImRlc3Ryb3koY2xpZW50KVxcXCI+XFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRGVsZXRlXFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2E+XFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvdGQ+XFxuICAgICAgICAgICAgICAgICAgICAgICAgPC90cj5cXG4gICAgICAgICAgICAgICAgICAgIDwvdGJvZHk+XFxuICAgICAgICAgICAgICAgIDwvdGFibGU+XFxuICAgICAgICAgICAgPC9kaXY+XFxuICAgICAgICA8L2Rpdj5cXG5cXG4gICAgICAgIDwhLS0gQ3JlYXRlIENsaWVudCBNb2RhbCAtLT5cXG4gICAgICAgIDxkaXYgY2xhc3M9XFxcIm1vZGFsIGZhZGVcXFwiIGlkPVxcXCJtb2RhbC1jcmVhdGUtY2xpZW50XFxcIiB0YWJpbmRleD1cXFwiLTFcXFwiIHJvbGU9XFxcImRpYWxvZ1xcXCI+XFxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cXFwibW9kYWwtZGlhbG9nXFxcIj5cXG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cXFwibW9kYWwtY29udGVudFxcXCI+XFxuICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVxcXCJtb2RhbC1oZWFkZXJcXFwiPlxcbiAgICAgICAgICAgICAgICAgICAgICAgIDxidXR0b24gdHlwZT1cXFwiYnV0dG9uIFxcXCIgY2xhc3M9XFxcImNsb3NlXFxcIiBkYXRhLWRpc21pc3M9XFxcIm1vZGFsXFxcIiBhcmlhLWhpZGRlbj1cXFwidHJ1ZVxcXCI+JnRpbWVzOzwvYnV0dG9uPlxcblxcbiAgICAgICAgICAgICAgICAgICAgICAgIDxoNCBjbGFzcz1cXFwibW9kYWwtdGl0bGVcXFwiPlxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBDcmVhdGUgQ2xpZW50XFxuICAgICAgICAgICAgICAgICAgICAgICAgPC9oND5cXG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxcblxcbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cXFwibW9kYWwtYm9keVxcXCI+XFxuICAgICAgICAgICAgICAgICAgICAgICAgPCEtLSBGb3JtIEVycm9ycyAtLT5cXG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVxcXCJhbGVydCBhbGVydC1kYW5nZXJcXFwiIHYtaWY9XFxcImNyZWF0ZUZvcm0uZXJyb3JzLmxlbmd0aCA+IDBcXFwiPlxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8cD48c3Ryb25nPldob29wcyE8L3N0cm9uZz4gU29tZXRoaW5nIHdlbnQgd3JvbmchPC9wPlxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8YnI+XFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDx1bD5cXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxsaSB2LWZvcj1cXFwiZXJyb3IgaW4gY3JlYXRlRm9ybS5lcnJvcnNcXFwiPlxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHt7IGVycm9yIH19XFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2xpPlxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3VsPlxcbiAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxcblxcbiAgICAgICAgICAgICAgICAgICAgICAgIDwhLS0gQ3JlYXRlIENsaWVudCBGb3JtIC0tPlxcbiAgICAgICAgICAgICAgICAgICAgICAgIDxmb3JtIGNsYXNzPVxcXCJmb3JtLWhvcml6b250YWxcXFwiIHJvbGU9XFxcImZvcm1cXFwiPlxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8IS0tIE5hbWUgLS0+XFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XFxcImZvcm0tZ3JvdXBcXFwiPlxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGxhYmVsIGNsYXNzPVxcXCJjb2wtbWQtMyBjb250cm9sLWxhYmVsXFxcIj5OYW1lPC9sYWJlbD5cXG5cXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XFxcImNvbC1tZC03XFxcIj5cXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aW5wdXQgaWQ9XFxcImNyZWF0ZS1jbGllbnQtbmFtZVxcXCIgdHlwZT1cXFwidGV4dFxcXCIgY2xhc3M9XFxcImZvcm0tY29udHJvbFxcXCJcXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQGtleXVwLmVudGVyPVxcXCJzdG9yZVxcXCIgdi1tb2RlbD1cXFwiY3JlYXRlRm9ybS5uYW1lXFxcIj5cXG5cXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cXFwiaGVscC1ibG9ja1xcXCI+XFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNvbWV0aGluZyB5b3VyIHVzZXJzIHdpbGwgcmVjb2duaXplIGFuZCB0cnVzdC5cXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3NwYW4+XFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XFxuXFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwhLS0gUmVkaXJlY3QgVVJMIC0tPlxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVxcXCJmb3JtLWdyb3VwXFxcIj5cXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxsYWJlbCBjbGFzcz1cXFwiY29sLW1kLTMgY29udHJvbC1sYWJlbFxcXCI+UmVkaXJlY3QgVVJMPC9sYWJlbD5cXG5cXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XFxcImNvbC1tZC03XFxcIj5cXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aW5wdXQgdHlwZT1cXFwidGV4dFxcXCIgY2xhc3M9XFxcImZvcm0tY29udHJvbFxcXCIgbmFtZT1cXFwicmVkaXJlY3RcXFwiXFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEBrZXl1cC5lbnRlcj1cXFwic3RvcmVcXFwiIHYtbW9kZWw9XFxcImNyZWF0ZUZvcm0ucmVkaXJlY3RcXFwiPlxcblxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVxcXCJoZWxwLWJsb2NrXFxcIj5cXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgWW91ciBhcHBsaWNhdGlvbidzIGF1dGhvcml6YXRpb24gY2FsbGJhY2sgVVJMLlxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvc3Bhbj5cXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cXG4gICAgICAgICAgICAgICAgICAgICAgICA8L2Zvcm0+XFxuICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cXG5cXG4gICAgICAgICAgICAgICAgICAgIDwhLS0gTW9kYWwgQWN0aW9ucyAtLT5cXG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XFxcIm1vZGFsLWZvb3RlclxcXCI+XFxuICAgICAgICAgICAgICAgICAgICAgICAgPGJ1dHRvbiB0eXBlPVxcXCJidXR0b25cXFwiIGNsYXNzPVxcXCJidG4gYnRuLWRlZmF1bHRcXFwiIGRhdGEtZGlzbWlzcz1cXFwibW9kYWxcXFwiPkNsb3NlPC9idXR0b24+XFxuXFxuICAgICAgICAgICAgICAgICAgICAgICAgPGJ1dHRvbiB0eXBlPVxcXCJidXR0b25cXFwiIGNsYXNzPVxcXCJidG4gYnRuLXByaW1hcnlcXFwiIEBjbGljaz1cXFwic3RvcmVcXFwiPlxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBDcmVhdGVcXG4gICAgICAgICAgICAgICAgICAgICAgICA8L2J1dHRvbj5cXG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxcbiAgICAgICAgICAgICAgICA8L2Rpdj5cXG4gICAgICAgICAgICA8L2Rpdj5cXG4gICAgICAgIDwvZGl2PlxcblxcbiAgICAgICAgPCEtLSBFZGl0IENsaWVudCBNb2RhbCAtLT5cXG4gICAgICAgIDxkaXYgY2xhc3M9XFxcIm1vZGFsIGZhZGVcXFwiIGlkPVxcXCJtb2RhbC1lZGl0LWNsaWVudFxcXCIgdGFiaW5kZXg9XFxcIi0xXFxcIiByb2xlPVxcXCJkaWFsb2dcXFwiPlxcbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XFxcIm1vZGFsLWRpYWxvZ1xcXCI+XFxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XFxcIm1vZGFsLWNvbnRlbnRcXFwiPlxcbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cXFwibW9kYWwtaGVhZGVyXFxcIj5cXG4gICAgICAgICAgICAgICAgICAgICAgICA8YnV0dG9uIHR5cGU9XFxcImJ1dHRvbiBcXFwiIGNsYXNzPVxcXCJjbG9zZVxcXCIgZGF0YS1kaXNtaXNzPVxcXCJtb2RhbFxcXCIgYXJpYS1oaWRkZW49XFxcInRydWVcXFwiPiZ0aW1lczs8L2J1dHRvbj5cXG5cXG4gICAgICAgICAgICAgICAgICAgICAgICA8aDQgY2xhc3M9XFxcIm1vZGFsLXRpdGxlXFxcIj5cXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgRWRpdCBDbGllbnRcXG4gICAgICAgICAgICAgICAgICAgICAgICA8L2g0PlxcbiAgICAgICAgICAgICAgICAgICAgPC9kaXY+XFxuXFxuICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVxcXCJtb2RhbC1ib2R5XFxcIj5cXG4gICAgICAgICAgICAgICAgICAgICAgICA8IS0tIEZvcm0gRXJyb3JzIC0tPlxcbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XFxcImFsZXJ0IGFsZXJ0LWRhbmdlclxcXCIgdi1pZj1cXFwiZWRpdEZvcm0uZXJyb3JzLmxlbmd0aCA+IDBcXFwiPlxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8cD48c3Ryb25nPldob29wcyE8L3N0cm9uZz4gU29tZXRoaW5nIHdlbnQgd3JvbmchPC9wPlxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8YnI+XFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDx1bD5cXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxsaSB2LWZvcj1cXFwiZXJyb3IgaW4gZWRpdEZvcm0uZXJyb3JzXFxcIj5cXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7eyBlcnJvciB9fVxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9saT5cXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC91bD5cXG4gICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cXG5cXG4gICAgICAgICAgICAgICAgICAgICAgICA8IS0tIEVkaXQgQ2xpZW50IEZvcm0gLS0+XFxuICAgICAgICAgICAgICAgICAgICAgICAgPGZvcm0gY2xhc3M9XFxcImZvcm0taG9yaXpvbnRhbFxcXCIgcm9sZT1cXFwiZm9ybVxcXCI+XFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwhLS0gTmFtZSAtLT5cXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cXFwiZm9ybS1ncm91cFxcXCI+XFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bGFiZWwgY2xhc3M9XFxcImNvbC1tZC0zIGNvbnRyb2wtbGFiZWxcXFwiPk5hbWU8L2xhYmVsPlxcblxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cXFwiY29sLW1kLTdcXFwiPlxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpbnB1dCBpZD1cXFwiZWRpdC1jbGllbnQtbmFtZVxcXCIgdHlwZT1cXFwidGV4dFxcXCIgY2xhc3M9XFxcImZvcm0tY29udHJvbFxcXCJcXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQGtleXVwLmVudGVyPVxcXCJ1cGRhdGVcXFwiIHYtbW9kZWw9XFxcImVkaXRGb3JtLm5hbWVcXFwiPlxcblxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVxcXCJoZWxwLWJsb2NrXFxcIj5cXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU29tZXRoaW5nIHlvdXIgdXNlcnMgd2lsbCByZWNvZ25pemUgYW5kIHRydXN0LlxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvc3Bhbj5cXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cXG5cXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPCEtLSBSZWRpcmVjdCBVUkwgLS0+XFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XFxcImZvcm0tZ3JvdXBcXFwiPlxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGxhYmVsIGNsYXNzPVxcXCJjb2wtbWQtMyBjb250cm9sLWxhYmVsXFxcIj5SZWRpcmVjdCBVUkw8L2xhYmVsPlxcblxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cXFwiY29sLW1kLTdcXFwiPlxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpbnB1dCB0eXBlPVxcXCJ0ZXh0XFxcIiBjbGFzcz1cXFwiZm9ybS1jb250cm9sXFxcIiBuYW1lPVxcXCJyZWRpcmVjdFxcXCJcXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQGtleXVwLmVudGVyPVxcXCJ1cGRhdGVcXFwiIHYtbW9kZWw9XFxcImVkaXRGb3JtLnJlZGlyZWN0XFxcIj5cXG5cXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cXFwiaGVscC1ibG9ja1xcXCI+XFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFlvdXIgYXBwbGljYXRpb24ncyBhdXRob3JpemF0aW9uIGNhbGxiYWNrIFVSTC5cXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3NwYW4+XFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XFxuICAgICAgICAgICAgICAgICAgICAgICAgPC9mb3JtPlxcbiAgICAgICAgICAgICAgICAgICAgPC9kaXY+XFxuXFxuICAgICAgICAgICAgICAgICAgICA8IS0tIE1vZGFsIEFjdGlvbnMgLS0+XFxuICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVxcXCJtb2RhbC1mb290ZXJcXFwiPlxcbiAgICAgICAgICAgICAgICAgICAgICAgIDxidXR0b24gdHlwZT1cXFwiYnV0dG9uXFxcIiBjbGFzcz1cXFwiYnRuIGJ0bi1kZWZhdWx0XFxcIiBkYXRhLWRpc21pc3M9XFxcIm1vZGFsXFxcIj5DbG9zZTwvYnV0dG9uPlxcblxcbiAgICAgICAgICAgICAgICAgICAgICAgIDxidXR0b24gdHlwZT1cXFwiYnV0dG9uXFxcIiBjbGFzcz1cXFwiYnRuIGJ0bi1wcmltYXJ5XFxcIiBAY2xpY2s9XFxcInVwZGF0ZVxcXCI+XFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNhdmUgQ2hhbmdlc1xcbiAgICAgICAgICAgICAgICAgICAgICAgIDwvYnV0dG9uPlxcbiAgICAgICAgICAgICAgICAgICAgPC9kaXY+XFxuICAgICAgICAgICAgICAgIDwvZGl2PlxcbiAgICAgICAgICAgIDwvZGl2PlxcbiAgICAgICAgPC9kaXY+XFxuICAgIDwvZGl2PlxcbjwvdGVtcGxhdGU+XFxuXFxuPHNjcmlwdD5cXG4gICAgZXhwb3J0IGRlZmF1bHQge1xcbiAgICAgICAgLypcXG4gICAgICAgICAqIFRoZSBjb21wb25lbnQncyBkYXRhLlxcbiAgICAgICAgICovXFxuICAgICAgICBkYXRhKCkge1xcbiAgICAgICAgICAgIHJldHVybiB7XFxuICAgICAgICAgICAgICAgIGNsaWVudHM6IFtdLFxcblxcbiAgICAgICAgICAgICAgICBjcmVhdGVGb3JtOiB7XFxuICAgICAgICAgICAgICAgICAgICBlcnJvcnM6IFtdLFxcbiAgICAgICAgICAgICAgICAgICAgbmFtZTogJycsXFxuICAgICAgICAgICAgICAgICAgICByZWRpcmVjdDogJydcXG4gICAgICAgICAgICAgICAgfSxcXG5cXG4gICAgICAgICAgICAgICAgZWRpdEZvcm06IHtcXG4gICAgICAgICAgICAgICAgICAgIGVycm9yczogW10sXFxuICAgICAgICAgICAgICAgICAgICBuYW1lOiAnJyxcXG4gICAgICAgICAgICAgICAgICAgIHJlZGlyZWN0OiAnJ1xcbiAgICAgICAgICAgICAgICB9XFxuICAgICAgICAgICAgfTtcXG4gICAgICAgIH0sXFxuXFxuICAgICAgICAvKipcXG4gICAgICAgICAqIFByZXBhcmUgdGhlIGNvbXBvbmVudCAoVnVlIDEueCkuXFxuICAgICAgICAgKi9cXG4gICAgICAgIHJlYWR5KCkge1xcbiAgICAgICAgICAgIHRoaXMucHJlcGFyZUNvbXBvbmVudCgpO1xcbiAgICAgICAgfSxcXG5cXG4gICAgICAgIC8qKlxcbiAgICAgICAgICogUHJlcGFyZSB0aGUgY29tcG9uZW50IChWdWUgMi54KS5cXG4gICAgICAgICAqL1xcbiAgICAgICAgbW91bnRlZCgpIHtcXG4gICAgICAgICAgICB0aGlzLnByZXBhcmVDb21wb25lbnQoKTtcXG4gICAgICAgIH0sXFxuXFxuICAgICAgICBtZXRob2RzOiB7XFxuICAgICAgICAgICAgLyoqXFxuICAgICAgICAgICAgICogUHJlcGFyZSB0aGUgY29tcG9uZW50LlxcbiAgICAgICAgICAgICAqL1xcbiAgICAgICAgICAgIHByZXBhcmVDb21wb25lbnQoKSB7XFxuICAgICAgICAgICAgICAgIHRoaXMuZ2V0Q2xpZW50cygpO1xcblxcbiAgICAgICAgICAgICAgICAkKCcjbW9kYWwtY3JlYXRlLWNsaWVudCcpLm9uKCdzaG93bi5icy5tb2RhbCcsICgpID0+IHtcXG4gICAgICAgICAgICAgICAgICAgICQoJyNjcmVhdGUtY2xpZW50LW5hbWUnKS5mb2N1cygpO1xcbiAgICAgICAgICAgICAgICB9KTtcXG5cXG4gICAgICAgICAgICAgICAgJCgnI21vZGFsLWVkaXQtY2xpZW50Jykub24oJ3Nob3duLmJzLm1vZGFsJywgKCkgPT4ge1xcbiAgICAgICAgICAgICAgICAgICAgJCgnI2VkaXQtY2xpZW50LW5hbWUnKS5mb2N1cygpO1xcbiAgICAgICAgICAgICAgICB9KTtcXG4gICAgICAgICAgICB9LFxcblxcbiAgICAgICAgICAgIC8qKlxcbiAgICAgICAgICAgICAqIEdldCBhbGwgb2YgdGhlIE9BdXRoIGNsaWVudHMgZm9yIHRoZSB1c2VyLlxcbiAgICAgICAgICAgICAqL1xcbiAgICAgICAgICAgIGdldENsaWVudHMoKSB7XFxuICAgICAgICAgICAgICAgIHRoaXMuJGh0dHAuZ2V0KCcvb2F1dGgvY2xpZW50cycpXFxuICAgICAgICAgICAgICAgICAgICAgICAgLnRoZW4ocmVzcG9uc2UgPT4ge1xcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmNsaWVudHMgPSByZXNwb25zZS5kYXRhO1xcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xcbiAgICAgICAgICAgIH0sXFxuXFxuICAgICAgICAgICAgLyoqXFxuICAgICAgICAgICAgICogU2hvdyB0aGUgZm9ybSBmb3IgY3JlYXRpbmcgbmV3IGNsaWVudHMuXFxuICAgICAgICAgICAgICovXFxuICAgICAgICAgICAgc2hvd0NyZWF0ZUNsaWVudEZvcm0oKSB7XFxuICAgICAgICAgICAgICAgICQoJyNtb2RhbC1jcmVhdGUtY2xpZW50JykubW9kYWwoJ3Nob3cnKTtcXG4gICAgICAgICAgICB9LFxcblxcbiAgICAgICAgICAgIC8qKlxcbiAgICAgICAgICAgICAqIENyZWF0ZSBhIG5ldyBPQXV0aCBjbGllbnQgZm9yIHRoZSB1c2VyLlxcbiAgICAgICAgICAgICAqL1xcbiAgICAgICAgICAgIHN0b3JlKCkge1xcbiAgICAgICAgICAgICAgICB0aGlzLnBlcnNpc3RDbGllbnQoXFxuICAgICAgICAgICAgICAgICAgICAncG9zdCcsICcvb2F1dGgvY2xpZW50cycsXFxuICAgICAgICAgICAgICAgICAgICB0aGlzLmNyZWF0ZUZvcm0sICcjbW9kYWwtY3JlYXRlLWNsaWVudCdcXG4gICAgICAgICAgICAgICAgKTtcXG4gICAgICAgICAgICB9LFxcblxcbiAgICAgICAgICAgIC8qKlxcbiAgICAgICAgICAgICAqIEVkaXQgdGhlIGdpdmVuIGNsaWVudC5cXG4gICAgICAgICAgICAgKi9cXG4gICAgICAgICAgICBlZGl0KGNsaWVudCkge1xcbiAgICAgICAgICAgICAgICB0aGlzLmVkaXRGb3JtLmlkID0gY2xpZW50LmlkO1xcbiAgICAgICAgICAgICAgICB0aGlzLmVkaXRGb3JtLm5hbWUgPSBjbGllbnQubmFtZTtcXG4gICAgICAgICAgICAgICAgdGhpcy5lZGl0Rm9ybS5yZWRpcmVjdCA9IGNsaWVudC5yZWRpcmVjdDtcXG5cXG4gICAgICAgICAgICAgICAgJCgnI21vZGFsLWVkaXQtY2xpZW50JykubW9kYWwoJ3Nob3cnKTtcXG4gICAgICAgICAgICB9LFxcblxcbiAgICAgICAgICAgIC8qKlxcbiAgICAgICAgICAgICAqIFVwZGF0ZSB0aGUgY2xpZW50IGJlaW5nIGVkaXRlZC5cXG4gICAgICAgICAgICAgKi9cXG4gICAgICAgICAgICB1cGRhdGUoKSB7XFxuICAgICAgICAgICAgICAgIHRoaXMucGVyc2lzdENsaWVudChcXG4gICAgICAgICAgICAgICAgICAgICdwdXQnLCAnL29hdXRoL2NsaWVudHMvJyArIHRoaXMuZWRpdEZvcm0uaWQsXFxuICAgICAgICAgICAgICAgICAgICB0aGlzLmVkaXRGb3JtLCAnI21vZGFsLWVkaXQtY2xpZW50J1xcbiAgICAgICAgICAgICAgICApO1xcbiAgICAgICAgICAgIH0sXFxuXFxuICAgICAgICAgICAgLyoqXFxuICAgICAgICAgICAgICogUGVyc2lzdCB0aGUgY2xpZW50IHRvIHN0b3JhZ2UgdXNpbmcgdGhlIGdpdmVuIGZvcm0uXFxuICAgICAgICAgICAgICovXFxuICAgICAgICAgICAgcGVyc2lzdENsaWVudChtZXRob2QsIHVyaSwgZm9ybSwgbW9kYWwpIHtcXG4gICAgICAgICAgICAgICAgZm9ybS5lcnJvcnMgPSBbXTtcXG5cXG4gICAgICAgICAgICAgICAgdGhpcy4kaHR0cFttZXRob2RdKHVyaSwgZm9ybSlcXG4gICAgICAgICAgICAgICAgICAgIC50aGVuKHJlc3BvbnNlID0+IHtcXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmdldENsaWVudHMoKTtcXG5cXG4gICAgICAgICAgICAgICAgICAgICAgICBmb3JtLm5hbWUgPSAnJztcXG4gICAgICAgICAgICAgICAgICAgICAgICBmb3JtLnJlZGlyZWN0ID0gJyc7XFxuICAgICAgICAgICAgICAgICAgICAgICAgZm9ybS5lcnJvcnMgPSBbXTtcXG5cXG4gICAgICAgICAgICAgICAgICAgICAgICAkKG1vZGFsKS5tb2RhbCgnaGlkZScpO1xcbiAgICAgICAgICAgICAgICAgICAgfSlcXG4gICAgICAgICAgICAgICAgICAgIC5jYXRjaChyZXNwb25zZSA9PiB7XFxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHR5cGVvZiByZXNwb25zZS5kYXRhID09PSAnb2JqZWN0Jykge1xcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb3JtLmVycm9ycyA9IF8uZmxhdHRlbihfLnRvQXJyYXkocmVzcG9uc2UuZGF0YSkpO1xcbiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvcm0uZXJyb3JzID0gWydTb21ldGhpbmcgd2VudCB3cm9uZy4gUGxlYXNlIHRyeSBhZ2Fpbi4nXTtcXG4gICAgICAgICAgICAgICAgICAgICAgICB9XFxuICAgICAgICAgICAgICAgICAgICB9KTtcXG4gICAgICAgICAgICB9LFxcblxcbiAgICAgICAgICAgIC8qKlxcbiAgICAgICAgICAgICAqIERlc3Ryb3kgdGhlIGdpdmVuIGNsaWVudC5cXG4gICAgICAgICAgICAgKi9cXG4gICAgICAgICAgICBkZXN0cm95KGNsaWVudCkge1xcbiAgICAgICAgICAgICAgICB0aGlzLiRodHRwLmRlbGV0ZSgnL29hdXRoL2NsaWVudHMvJyArIGNsaWVudC5pZClcXG4gICAgICAgICAgICAgICAgICAgICAgICAudGhlbihyZXNwb25zZSA9PiB7XFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuZ2V0Q2xpZW50cygpO1xcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xcbiAgICAgICAgICAgIH1cXG4gICAgICAgIH1cXG4gICAgfVxcbjwvc2NyaXB0PlxcblwiXSxcInNvdXJjZVJvb3RcIjpcIlwifV0pO1xuXG4vLyBleHBvcnRzXG5cblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyAuL25vZGVfbW9kdWxlcy9jc3MtbG9hZGVyP3NvdXJjZU1hcCEuL25vZGVfbW9kdWxlcy92dWUtbG9hZGVyL2xpYi9zdHlsZS1jb21waWxlcj97XCJ2dWVcIjp0cnVlLFwiaWRcIjpcImRhdGEtdi1lOWM4MDMxOFwiLFwic2NvcGVkXCI6dHJ1ZSxcImhhc0lubGluZUNvbmZpZ1wiOnRydWV9IS4vbm9kZV9tb2R1bGVzL3Z1ZS1sb2FkZXIvbGliL3NlbGVjdG9yLmpzP3R5cGU9c3R5bGVzJmluZGV4PTAhLi9yZXNvdXJjZXMvYXNzZXRzL2pzL2NvbXBvbmVudHMvcGFzc3BvcnQvQ2xpZW50cy52dWVcbi8vIG1vZHVsZSBpZCA9IDE3XG4vLyBtb2R1bGUgY2h1bmtzID0gMCIsIi8qKlxuICogVHJhbnNsYXRlcyB0aGUgbGlzdCBmb3JtYXQgcHJvZHVjZWQgYnkgY3NzLWxvYWRlciBpbnRvIHNvbWV0aGluZ1xuICogZWFzaWVyIHRvIG1hbmlwdWxhdGUuXG4gKi9cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gbGlzdFRvU3R5bGVzIChwYXJlbnRJZCwgbGlzdCkge1xuICB2YXIgc3R5bGVzID0gW11cbiAgdmFyIG5ld1N0eWxlcyA9IHt9XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgbGlzdC5sZW5ndGg7IGkrKykge1xuICAgIHZhciBpdGVtID0gbGlzdFtpXVxuICAgIHZhciBpZCA9IGl0ZW1bMF1cbiAgICB2YXIgY3NzID0gaXRlbVsxXVxuICAgIHZhciBtZWRpYSA9IGl0ZW1bMl1cbiAgICB2YXIgc291cmNlTWFwID0gaXRlbVszXVxuICAgIHZhciBwYXJ0ID0ge1xuICAgICAgaWQ6IHBhcmVudElkICsgJzonICsgaSxcbiAgICAgIGNzczogY3NzLFxuICAgICAgbWVkaWE6IG1lZGlhLFxuICAgICAgc291cmNlTWFwOiBzb3VyY2VNYXBcbiAgICB9XG4gICAgaWYgKCFuZXdTdHlsZXNbaWRdKSB7XG4gICAgICBzdHlsZXMucHVzaChuZXdTdHlsZXNbaWRdID0geyBpZDogaWQsIHBhcnRzOiBbcGFydF0gfSlcbiAgICB9IGVsc2Uge1xuICAgICAgbmV3U3R5bGVzW2lkXS5wYXJ0cy5wdXNoKHBhcnQpXG4gICAgfVxuICB9XG4gIHJldHVybiBzdHlsZXNcbn1cblxuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIC4vbm9kZV9tb2R1bGVzL3Z1ZS1zdHlsZS1sb2FkZXIvbGliL2xpc3RUb1N0eWxlcy5qc1xuLy8gbW9kdWxlIGlkID0gMThcbi8vIG1vZHVsZSBjaHVua3MgPSAwIiwiPHN0eWxlIHNjb3BlZD5cbiAgICAuYWN0aW9uLWxpbmsge1xuICAgICAgICBjdXJzb3I6IHBvaW50ZXI7XG4gICAgfVxuXG4gICAgLm0tYi1ub25lIHtcbiAgICAgICAgbWFyZ2luLWJvdHRvbTogMDtcbiAgICB9XG48L3N0eWxlPlxuXG48dGVtcGxhdGU+XG4gICAgPGRpdj5cbiAgICAgICAgPGRpdiBjbGFzcz1cInBhbmVsIHBhbmVsLWRlZmF1bHRcIj5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJwYW5lbC1oZWFkaW5nXCI+XG4gICAgICAgICAgICAgICAgPGRpdiBzdHlsZT1cImRpc3BsYXk6IGZsZXg7IGp1c3RpZnktY29udGVudDogc3BhY2UtYmV0d2VlbjsgYWxpZ24taXRlbXM6IGNlbnRlcjtcIj5cbiAgICAgICAgICAgICAgICAgICAgPHNwYW4+XG4gICAgICAgICAgICAgICAgICAgICAgICBPQXV0aCBDbGllbnRzXG4gICAgICAgICAgICAgICAgICAgIDwvc3Bhbj5cblxuICAgICAgICAgICAgICAgICAgICA8YSBjbGFzcz1cImFjdGlvbi1saW5rXCIgQGNsaWNrPVwic2hvd0NyZWF0ZUNsaWVudEZvcm1cIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIENyZWF0ZSBOZXcgQ2xpZW50XG4gICAgICAgICAgICAgICAgICAgIDwvYT5cbiAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDwvZGl2PlxuXG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwicGFuZWwtYm9keVwiPlxuICAgICAgICAgICAgICAgIDwhLS0gQ3VycmVudCBDbGllbnRzIC0tPlxuICAgICAgICAgICAgICAgIDxwIGNsYXNzPVwibS1iLW5vbmVcIiB2LWlmPVwiY2xpZW50cy5sZW5ndGggPT09IDBcIj5cbiAgICAgICAgICAgICAgICAgICAgWW91IGhhdmUgbm90IGNyZWF0ZWQgYW55IE9BdXRoIGNsaWVudHMuXG4gICAgICAgICAgICAgICAgPC9wPlxuXG4gICAgICAgICAgICAgICAgPHRhYmxlIGNsYXNzPVwidGFibGUgdGFibGUtYm9yZGVybGVzcyBtLWItbm9uZVwiIHYtaWY9XCJjbGllbnRzLmxlbmd0aCA+IDBcIj5cbiAgICAgICAgICAgICAgICAgICAgPHRoZWFkPlxuICAgICAgICAgICAgICAgICAgICAgICAgPHRyPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDx0aD5DbGllbnQgSUQ8L3RoPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDx0aD5OYW1lPC90aD5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8dGg+U2VjcmV0PC90aD5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8dGg+PC90aD5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8dGg+PC90aD5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvdHI+XG4gICAgICAgICAgICAgICAgICAgIDwvdGhlYWQ+XG5cbiAgICAgICAgICAgICAgICAgICAgPHRib2R5PlxuICAgICAgICAgICAgICAgICAgICAgICAgPHRyIHYtZm9yPVwiY2xpZW50IGluIGNsaWVudHNcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8IS0tIElEIC0tPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDx0ZCBzdHlsZT1cInZlcnRpY2FsLWFsaWduOiBtaWRkbGU7XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHt7IGNsaWVudC5pZCB9fVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvdGQ+XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8IS0tIE5hbWUgLS0+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPHRkIHN0eWxlPVwidmVydGljYWwtYWxpZ246IG1pZGRsZTtcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAge3sgY2xpZW50Lm5hbWUgfX1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3RkPlxuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPCEtLSBTZWNyZXQgLS0+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPHRkIHN0eWxlPVwidmVydGljYWwtYWxpZ246IG1pZGRsZTtcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGNvZGU+e3sgY2xpZW50LnNlY3JldCB9fTwvY29kZT5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3RkPlxuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPCEtLSBFZGl0IEJ1dHRvbiAtLT5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8dGQgc3R5bGU9XCJ2ZXJ0aWNhbC1hbGlnbjogbWlkZGxlO1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8YSBjbGFzcz1cImFjdGlvbi1saW5rXCIgQGNsaWNrPVwiZWRpdChjbGllbnQpXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBFZGl0XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvYT5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3RkPlxuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPCEtLSBEZWxldGUgQnV0dG9uIC0tPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDx0ZCBzdHlsZT1cInZlcnRpY2FsLWFsaWduOiBtaWRkbGU7XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxhIGNsYXNzPVwiYWN0aW9uLWxpbmsgdGV4dC1kYW5nZXJcIiBAY2xpY2s9XCJkZXN0cm95KGNsaWVudClcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERlbGV0ZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2E+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC90ZD5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvdHI+XG4gICAgICAgICAgICAgICAgICAgIDwvdGJvZHk+XG4gICAgICAgICAgICAgICAgPC90YWJsZT5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICA8L2Rpdj5cblxuICAgICAgICA8IS0tIENyZWF0ZSBDbGllbnQgTW9kYWwgLS0+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJtb2RhbCBmYWRlXCIgaWQ9XCJtb2RhbC1jcmVhdGUtY2xpZW50XCIgdGFiaW5kZXg9XCItMVwiIHJvbGU9XCJkaWFsb2dcIj5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJtb2RhbC1kaWFsb2dcIj5cbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwibW9kYWwtY29udGVudFwiPlxuICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwibW9kYWwtaGVhZGVyXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8YnV0dG9uIHR5cGU9XCJidXR0b24gXCIgY2xhc3M9XCJjbG9zZVwiIGRhdGEtZGlzbWlzcz1cIm1vZGFsXCIgYXJpYS1oaWRkZW49XCJ0cnVlXCI+JnRpbWVzOzwvYnV0dG9uPlxuXG4gICAgICAgICAgICAgICAgICAgICAgICA8aDQgY2xhc3M9XCJtb2RhbC10aXRsZVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIENyZWF0ZSBDbGllbnRcbiAgICAgICAgICAgICAgICAgICAgICAgIDwvaDQ+XG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuXG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJtb2RhbC1ib2R5XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8IS0tIEZvcm0gRXJyb3JzIC0tPlxuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImFsZXJ0IGFsZXJ0LWRhbmdlclwiIHYtaWY9XCJjcmVhdGVGb3JtLmVycm9ycy5sZW5ndGggPiAwXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPHA+PHN0cm9uZz5XaG9vcHMhPC9zdHJvbmc+IFNvbWV0aGluZyB3ZW50IHdyb25nITwvcD5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8YnI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPHVsPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bGkgdi1mb3I9XCJlcnJvciBpbiBjcmVhdGVGb3JtLmVycm9yc1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAge3sgZXJyb3IgfX1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9saT5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3VsPlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwhLS0gQ3JlYXRlIENsaWVudCBGb3JtIC0tPlxuICAgICAgICAgICAgICAgICAgICAgICAgPGZvcm0gY2xhc3M9XCJmb3JtLWhvcml6b250YWxcIiByb2xlPVwiZm9ybVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwhLS0gTmFtZSAtLT5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZm9ybS1ncm91cFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bGFiZWwgY2xhc3M9XCJjb2wtbWQtMyBjb250cm9sLWxhYmVsXCI+TmFtZTwvbGFiZWw+XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImNvbC1tZC03XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aW5wdXQgaWQ9XCJjcmVhdGUtY2xpZW50LW5hbWVcIiB0eXBlPVwidGV4dFwiIGNsYXNzPVwiZm9ybS1jb250cm9sXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBAa2V5dXAuZW50ZXI9XCJzdG9yZVwiIHYtbW9kZWw9XCJjcmVhdGVGb3JtLm5hbWVcIj5cblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJoZWxwLWJsb2NrXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU29tZXRoaW5nIHlvdXIgdXNlcnMgd2lsbCByZWNvZ25pemUgYW5kIHRydXN0LlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwhLS0gUmVkaXJlY3QgVVJMIC0tPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJmb3JtLWdyb3VwXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxsYWJlbCBjbGFzcz1cImNvbC1tZC0zIGNvbnRyb2wtbGFiZWxcIj5SZWRpcmVjdCBVUkw8L2xhYmVsPlxuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJjb2wtbWQtN1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGlucHV0IHR5cGU9XCJ0ZXh0XCIgY2xhc3M9XCJmb3JtLWNvbnRyb2xcIiBuYW1lPVwicmVkaXJlY3RcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEBrZXl1cC5lbnRlcj1cInN0b3JlXCIgdi1tb2RlbD1cImNyZWF0ZUZvcm0ucmVkaXJlY3RcIj5cblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJoZWxwLWJsb2NrXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgWW91ciBhcHBsaWNhdGlvbidzIGF1dGhvcml6YXRpb24gY2FsbGJhY2sgVVJMLlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvZm9ybT5cbiAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgICAgICAgICAgICAgPCEtLSBNb2RhbCBBY3Rpb25zIC0tPlxuICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwibW9kYWwtZm9vdGVyXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8YnV0dG9uIHR5cGU9XCJidXR0b25cIiBjbGFzcz1cImJ0biBidG4tZGVmYXVsdFwiIGRhdGEtZGlzbWlzcz1cIm1vZGFsXCI+Q2xvc2U8L2J1dHRvbj5cblxuICAgICAgICAgICAgICAgICAgICAgICAgPGJ1dHRvbiB0eXBlPVwiYnV0dG9uXCIgY2xhc3M9XCJidG4gYnRuLXByaW1hcnlcIiBAY2xpY2s9XCJzdG9yZVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIENyZWF0ZVxuICAgICAgICAgICAgICAgICAgICAgICAgPC9idXR0b24+XG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgIDwvZGl2PlxuXG4gICAgICAgIDwhLS0gRWRpdCBDbGllbnQgTW9kYWwgLS0+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJtb2RhbCBmYWRlXCIgaWQ9XCJtb2RhbC1lZGl0LWNsaWVudFwiIHRhYmluZGV4PVwiLTFcIiByb2xlPVwiZGlhbG9nXCI+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwibW9kYWwtZGlhbG9nXCI+XG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cIm1vZGFsLWNvbnRlbnRcIj5cbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cIm1vZGFsLWhlYWRlclwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPGJ1dHRvbiB0eXBlPVwiYnV0dG9uIFwiIGNsYXNzPVwiY2xvc2VcIiBkYXRhLWRpc21pc3M9XCJtb2RhbFwiIGFyaWEtaGlkZGVuPVwidHJ1ZVwiPiZ0aW1lczs8L2J1dHRvbj5cblxuICAgICAgICAgICAgICAgICAgICAgICAgPGg0IGNsYXNzPVwibW9kYWwtdGl0bGVcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBFZGl0IENsaWVudFxuICAgICAgICAgICAgICAgICAgICAgICAgPC9oND5cbiAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cIm1vZGFsLWJvZHlcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwhLS0gRm9ybSBFcnJvcnMgLS0+XG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiYWxlcnQgYWxlcnQtZGFuZ2VyXCIgdi1pZj1cImVkaXRGb3JtLmVycm9ycy5sZW5ndGggPiAwXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPHA+PHN0cm9uZz5XaG9vcHMhPC9zdHJvbmc+IFNvbWV0aGluZyB3ZW50IHdyb25nITwvcD5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8YnI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPHVsPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bGkgdi1mb3I9XCJlcnJvciBpbiBlZGl0Rm9ybS5lcnJvcnNcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHt7IGVycm9yIH19XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvbGk+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC91bD5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuXG4gICAgICAgICAgICAgICAgICAgICAgICA8IS0tIEVkaXQgQ2xpZW50IEZvcm0gLS0+XG4gICAgICAgICAgICAgICAgICAgICAgICA8Zm9ybSBjbGFzcz1cImZvcm0taG9yaXpvbnRhbFwiIHJvbGU9XCJmb3JtXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPCEtLSBOYW1lIC0tPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJmb3JtLWdyb3VwXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxsYWJlbCBjbGFzcz1cImNvbC1tZC0zIGNvbnRyb2wtbGFiZWxcIj5OYW1lPC9sYWJlbD5cblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiY29sLW1kLTdcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpbnB1dCBpZD1cImVkaXQtY2xpZW50LW5hbWVcIiB0eXBlPVwidGV4dFwiIGNsYXNzPVwiZm9ybS1jb250cm9sXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBAa2V5dXAuZW50ZXI9XCJ1cGRhdGVcIiB2LW1vZGVsPVwiZWRpdEZvcm0ubmFtZVwiPlxuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cImhlbHAtYmxvY2tcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTb21ldGhpbmcgeW91ciB1c2VycyB3aWxsIHJlY29nbml6ZSBhbmQgdHJ1c3QuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPCEtLSBSZWRpcmVjdCBVUkwgLS0+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImZvcm0tZ3JvdXBcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGxhYmVsIGNsYXNzPVwiY29sLW1kLTMgY29udHJvbC1sYWJlbFwiPlJlZGlyZWN0IFVSTDwvbGFiZWw+XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImNvbC1tZC03XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aW5wdXQgdHlwZT1cInRleHRcIiBjbGFzcz1cImZvcm0tY29udHJvbFwiIG5hbWU9XCJyZWRpcmVjdFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQGtleXVwLmVudGVyPVwidXBkYXRlXCIgdi1tb2RlbD1cImVkaXRGb3JtLnJlZGlyZWN0XCI+XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiaGVscC1ibG9ja1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFlvdXIgYXBwbGljYXRpb24ncyBhdXRob3JpemF0aW9uIGNhbGxiYWNrIFVSTC5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICA8L2Zvcm0+XG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuXG4gICAgICAgICAgICAgICAgICAgIDwhLS0gTW9kYWwgQWN0aW9ucyAtLT5cbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cIm1vZGFsLWZvb3RlclwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPGJ1dHRvbiB0eXBlPVwiYnV0dG9uXCIgY2xhc3M9XCJidG4gYnRuLWRlZmF1bHRcIiBkYXRhLWRpc21pc3M9XCJtb2RhbFwiPkNsb3NlPC9idXR0b24+XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxidXR0b24gdHlwZT1cImJ1dHRvblwiIGNsYXNzPVwiYnRuIGJ0bi1wcmltYXJ5XCIgQGNsaWNrPVwidXBkYXRlXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgU2F2ZSBDaGFuZ2VzXG4gICAgICAgICAgICAgICAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgPC9kaXY+XG4gICAgPC9kaXY+XG48L3RlbXBsYXRlPlxuXG48c2NyaXB0PlxuICAgIGV4cG9ydCBkZWZhdWx0IHtcbiAgICAgICAgLypcbiAgICAgICAgICogVGhlIGNvbXBvbmVudCdzIGRhdGEuXG4gICAgICAgICAqL1xuICAgICAgICBkYXRhKCkge1xuICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgICBjbGllbnRzOiBbXSxcblxuICAgICAgICAgICAgICAgIGNyZWF0ZUZvcm06IHtcbiAgICAgICAgICAgICAgICAgICAgZXJyb3JzOiBbXSxcbiAgICAgICAgICAgICAgICAgICAgbmFtZTogJycsXG4gICAgICAgICAgICAgICAgICAgIHJlZGlyZWN0OiAnJ1xuICAgICAgICAgICAgICAgIH0sXG5cbiAgICAgICAgICAgICAgICBlZGl0Rm9ybToge1xuICAgICAgICAgICAgICAgICAgICBlcnJvcnM6IFtdLFxuICAgICAgICAgICAgICAgICAgICBuYW1lOiAnJyxcbiAgICAgICAgICAgICAgICAgICAgcmVkaXJlY3Q6ICcnXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfTtcbiAgICAgICAgfSxcblxuICAgICAgICAvKipcbiAgICAgICAgICogUHJlcGFyZSB0aGUgY29tcG9uZW50IChWdWUgMS54KS5cbiAgICAgICAgICovXG4gICAgICAgIHJlYWR5KCkge1xuICAgICAgICAgICAgdGhpcy5wcmVwYXJlQ29tcG9uZW50KCk7XG4gICAgICAgIH0sXG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIFByZXBhcmUgdGhlIGNvbXBvbmVudCAoVnVlIDIueCkuXG4gICAgICAgICAqL1xuICAgICAgICBtb3VudGVkKCkge1xuICAgICAgICAgICAgdGhpcy5wcmVwYXJlQ29tcG9uZW50KCk7XG4gICAgICAgIH0sXG5cbiAgICAgICAgbWV0aG9kczoge1xuICAgICAgICAgICAgLyoqXG4gICAgICAgICAgICAgKiBQcmVwYXJlIHRoZSBjb21wb25lbnQuXG4gICAgICAgICAgICAgKi9cbiAgICAgICAgICAgIHByZXBhcmVDb21wb25lbnQoKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5nZXRDbGllbnRzKCk7XG5cbiAgICAgICAgICAgICAgICAkKCcjbW9kYWwtY3JlYXRlLWNsaWVudCcpLm9uKCdzaG93bi5icy5tb2RhbCcsICgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgJCgnI2NyZWF0ZS1jbGllbnQtbmFtZScpLmZvY3VzKCk7XG4gICAgICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgICAgICAkKCcjbW9kYWwtZWRpdC1jbGllbnQnKS5vbignc2hvd24uYnMubW9kYWwnLCAoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICQoJyNlZGl0LWNsaWVudC1uYW1lJykuZm9jdXMoKTtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH0sXG5cbiAgICAgICAgICAgIC8qKlxuICAgICAgICAgICAgICogR2V0IGFsbCBvZiB0aGUgT0F1dGggY2xpZW50cyBmb3IgdGhlIHVzZXIuXG4gICAgICAgICAgICAgKi9cbiAgICAgICAgICAgIGdldENsaWVudHMoKSB7XG4gICAgICAgICAgICAgICAgdGhpcy4kaHR0cC5nZXQoJy9vYXV0aC9jbGllbnRzJylcbiAgICAgICAgICAgICAgICAgICAgICAgIC50aGVuKHJlc3BvbnNlID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmNsaWVudHMgPSByZXNwb25zZS5kYXRhO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9LFxuXG4gICAgICAgICAgICAvKipcbiAgICAgICAgICAgICAqIFNob3cgdGhlIGZvcm0gZm9yIGNyZWF0aW5nIG5ldyBjbGllbnRzLlxuICAgICAgICAgICAgICovXG4gICAgICAgICAgICBzaG93Q3JlYXRlQ2xpZW50Rm9ybSgpIHtcbiAgICAgICAgICAgICAgICAkKCcjbW9kYWwtY3JlYXRlLWNsaWVudCcpLm1vZGFsKCdzaG93Jyk7XG4gICAgICAgICAgICB9LFxuXG4gICAgICAgICAgICAvKipcbiAgICAgICAgICAgICAqIENyZWF0ZSBhIG5ldyBPQXV0aCBjbGllbnQgZm9yIHRoZSB1c2VyLlxuICAgICAgICAgICAgICovXG4gICAgICAgICAgICBzdG9yZSgpIHtcbiAgICAgICAgICAgICAgICB0aGlzLnBlcnNpc3RDbGllbnQoXG4gICAgICAgICAgICAgICAgICAgICdwb3N0JywgJy9vYXV0aC9jbGllbnRzJyxcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5jcmVhdGVGb3JtLCAnI21vZGFsLWNyZWF0ZS1jbGllbnQnXG4gICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIH0sXG5cbiAgICAgICAgICAgIC8qKlxuICAgICAgICAgICAgICogRWRpdCB0aGUgZ2l2ZW4gY2xpZW50LlxuICAgICAgICAgICAgICovXG4gICAgICAgICAgICBlZGl0KGNsaWVudCkge1xuICAgICAgICAgICAgICAgIHRoaXMuZWRpdEZvcm0uaWQgPSBjbGllbnQuaWQ7XG4gICAgICAgICAgICAgICAgdGhpcy5lZGl0Rm9ybS5uYW1lID0gY2xpZW50Lm5hbWU7XG4gICAgICAgICAgICAgICAgdGhpcy5lZGl0Rm9ybS5yZWRpcmVjdCA9IGNsaWVudC5yZWRpcmVjdDtcblxuICAgICAgICAgICAgICAgICQoJyNtb2RhbC1lZGl0LWNsaWVudCcpLm1vZGFsKCdzaG93Jyk7XG4gICAgICAgICAgICB9LFxuXG4gICAgICAgICAgICAvKipcbiAgICAgICAgICAgICAqIFVwZGF0ZSB0aGUgY2xpZW50IGJlaW5nIGVkaXRlZC5cbiAgICAgICAgICAgICAqL1xuICAgICAgICAgICAgdXBkYXRlKCkge1xuICAgICAgICAgICAgICAgIHRoaXMucGVyc2lzdENsaWVudChcbiAgICAgICAgICAgICAgICAgICAgJ3B1dCcsICcvb2F1dGgvY2xpZW50cy8nICsgdGhpcy5lZGl0Rm9ybS5pZCxcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5lZGl0Rm9ybSwgJyNtb2RhbC1lZGl0LWNsaWVudCdcbiAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgfSxcblxuICAgICAgICAgICAgLyoqXG4gICAgICAgICAgICAgKiBQZXJzaXN0IHRoZSBjbGllbnQgdG8gc3RvcmFnZSB1c2luZyB0aGUgZ2l2ZW4gZm9ybS5cbiAgICAgICAgICAgICAqL1xuICAgICAgICAgICAgcGVyc2lzdENsaWVudChtZXRob2QsIHVyaSwgZm9ybSwgbW9kYWwpIHtcbiAgICAgICAgICAgICAgICBmb3JtLmVycm9ycyA9IFtdO1xuXG4gICAgICAgICAgICAgICAgdGhpcy4kaHR0cFttZXRob2RdKHVyaSwgZm9ybSlcbiAgICAgICAgICAgICAgICAgICAgLnRoZW4ocmVzcG9uc2UgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5nZXRDbGllbnRzKCk7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIGZvcm0ubmFtZSA9ICcnO1xuICAgICAgICAgICAgICAgICAgICAgICAgZm9ybS5yZWRpcmVjdCA9ICcnO1xuICAgICAgICAgICAgICAgICAgICAgICAgZm9ybS5lcnJvcnMgPSBbXTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgJChtb2RhbCkubW9kYWwoJ2hpZGUnKTtcbiAgICAgICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgICAgICAgLmNhdGNoKHJlc3BvbnNlID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0eXBlb2YgcmVzcG9uc2UuZGF0YSA9PT0gJ29iamVjdCcpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb3JtLmVycm9ycyA9IF8uZmxhdHRlbihfLnRvQXJyYXkocmVzcG9uc2UuZGF0YSkpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb3JtLmVycm9ycyA9IFsnU29tZXRoaW5nIHdlbnQgd3JvbmcuIFBsZWFzZSB0cnkgYWdhaW4uJ107XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfSxcblxuICAgICAgICAgICAgLyoqXG4gICAgICAgICAgICAgKiBEZXN0cm95IHRoZSBnaXZlbiBjbGllbnQuXG4gICAgICAgICAgICAgKi9cbiAgICAgICAgICAgIGRlc3Ryb3koY2xpZW50KSB7XG4gICAgICAgICAgICAgICAgdGhpcy4kaHR0cC5kZWxldGUoJy9vYXV0aC9jbGllbnRzLycgKyBjbGllbnQuaWQpXG4gICAgICAgICAgICAgICAgICAgICAgICAudGhlbihyZXNwb25zZSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5nZXRDbGllbnRzKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cbjwvc2NyaXB0PlxuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIENsaWVudHMudnVlPzM1ODY3Y2U0IiwibW9kdWxlLmV4cG9ydHM9e3JlbmRlcjpmdW5jdGlvbiAoKXt2YXIgX3ZtPXRoaXM7dmFyIF9oPV92bS4kY3JlYXRlRWxlbWVudDt2YXIgX2M9X3ZtLl9zZWxmLl9jfHxfaDtcbiAgcmV0dXJuIF9jKCdkaXYnLCBbX2MoJ2RpdicsIHtcbiAgICBzdGF0aWNDbGFzczogXCJwYW5lbCBwYW5lbC1kZWZhdWx0XCJcbiAgfSwgW19jKCdkaXYnLCB7XG4gICAgc3RhdGljQ2xhc3M6IFwicGFuZWwtaGVhZGluZ1wiXG4gIH0sIFtfYygnZGl2Jywge1xuICAgIHN0YXRpY1N0eWxlOiB7XG4gICAgICBcImRpc3BsYXlcIjogXCJmbGV4XCIsXG4gICAgICBcImp1c3RpZnktY29udGVudFwiOiBcInNwYWNlLWJldHdlZW5cIixcbiAgICAgIFwiYWxpZ24taXRlbXNcIjogXCJjZW50ZXJcIlxuICAgIH1cbiAgfSwgW19jKCdzcGFuJywgW192bS5fdihcIlxcbiAgICAgICAgICAgICAgICAgICAgT0F1dGggQ2xpZW50c1xcbiAgICAgICAgICAgICAgICBcIildKSwgX3ZtLl92KFwiIFwiKSwgX2MoJ2EnLCB7XG4gICAgc3RhdGljQ2xhc3M6IFwiYWN0aW9uLWxpbmtcIixcbiAgICBvbjoge1xuICAgICAgXCJjbGlja1wiOiBfdm0uc2hvd0NyZWF0ZUNsaWVudEZvcm1cbiAgICB9XG4gIH0sIFtfdm0uX3YoXCJcXG4gICAgICAgICAgICAgICAgICAgIENyZWF0ZSBOZXcgQ2xpZW50XFxuICAgICAgICAgICAgICAgIFwiKV0pXSldKSwgX3ZtLl92KFwiIFwiKSwgX2MoJ2RpdicsIHtcbiAgICBzdGF0aWNDbGFzczogXCJwYW5lbC1ib2R5XCJcbiAgfSwgWyhfdm0uY2xpZW50cy5sZW5ndGggPT09IDApID8gX2MoJ3AnLCB7XG4gICAgc3RhdGljQ2xhc3M6IFwibS1iLW5vbmVcIlxuICB9LCBbX3ZtLl92KFwiXFxuICAgICAgICAgICAgICAgIFlvdSBoYXZlIG5vdCBjcmVhdGVkIGFueSBPQXV0aCBjbGllbnRzLlxcbiAgICAgICAgICAgIFwiKV0pIDogX3ZtLl9lKCksIF92bS5fdihcIiBcIiksIChfdm0uY2xpZW50cy5sZW5ndGggPiAwKSA/IF9jKCd0YWJsZScsIHtcbiAgICBzdGF0aWNDbGFzczogXCJ0YWJsZSB0YWJsZS1ib3JkZXJsZXNzIG0tYi1ub25lXCJcbiAgfSwgW192bS5fbSgwKSwgX3ZtLl92KFwiIFwiKSwgX2MoJ3Rib2R5JywgX3ZtLl9sKChfdm0uY2xpZW50cyksIGZ1bmN0aW9uKGNsaWVudCkge1xuICAgIHJldHVybiBfYygndHInLCBbX2MoJ3RkJywge1xuICAgICAgc3RhdGljU3R5bGU6IHtcbiAgICAgICAgXCJ2ZXJ0aWNhbC1hbGlnblwiOiBcIm1pZGRsZVwiXG4gICAgICB9XG4gICAgfSwgW192bS5fdihcIlxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBcIiArIF92bS5fcyhjbGllbnQuaWQpICsgXCJcXG4gICAgICAgICAgICAgICAgICAgICAgICBcIildKSwgX3ZtLl92KFwiIFwiKSwgX2MoJ3RkJywge1xuICAgICAgc3RhdGljU3R5bGU6IHtcbiAgICAgICAgXCJ2ZXJ0aWNhbC1hbGlnblwiOiBcIm1pZGRsZVwiXG4gICAgICB9XG4gICAgfSwgW192bS5fdihcIlxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBcIiArIF92bS5fcyhjbGllbnQubmFtZSkgKyBcIlxcbiAgICAgICAgICAgICAgICAgICAgICAgIFwiKV0pLCBfdm0uX3YoXCIgXCIpLCBfYygndGQnLCB7XG4gICAgICBzdGF0aWNTdHlsZToge1xuICAgICAgICBcInZlcnRpY2FsLWFsaWduXCI6IFwibWlkZGxlXCJcbiAgICAgIH1cbiAgICB9LCBbX2MoJ2NvZGUnLCBbX3ZtLl92KF92bS5fcyhjbGllbnQuc2VjcmV0KSldKV0pLCBfdm0uX3YoXCIgXCIpLCBfYygndGQnLCB7XG4gICAgICBzdGF0aWNTdHlsZToge1xuICAgICAgICBcInZlcnRpY2FsLWFsaWduXCI6IFwibWlkZGxlXCJcbiAgICAgIH1cbiAgICB9LCBbX2MoJ2EnLCB7XG4gICAgICBzdGF0aWNDbGFzczogXCJhY3Rpb24tbGlua1wiLFxuICAgICAgb246IHtcbiAgICAgICAgXCJjbGlja1wiOiBmdW5jdGlvbigkZXZlbnQpIHtcbiAgICAgICAgICBfdm0uZWRpdChjbGllbnQpXG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9LCBbX3ZtLl92KFwiXFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBFZGl0XFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwiKV0pXSksIF92bS5fdihcIiBcIiksIF9jKCd0ZCcsIHtcbiAgICAgIHN0YXRpY1N0eWxlOiB7XG4gICAgICAgIFwidmVydGljYWwtYWxpZ25cIjogXCJtaWRkbGVcIlxuICAgICAgfVxuICAgIH0sIFtfYygnYScsIHtcbiAgICAgIHN0YXRpY0NsYXNzOiBcImFjdGlvbi1saW5rIHRleHQtZGFuZ2VyXCIsXG4gICAgICBvbjoge1xuICAgICAgICBcImNsaWNrXCI6IGZ1bmN0aW9uKCRldmVudCkge1xuICAgICAgICAgIF92bS5kZXN0cm95KGNsaWVudClcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0sIFtfdm0uX3YoXCJcXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERlbGV0ZVxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBcIildKV0pXSlcbiAgfSkpXSkgOiBfdm0uX2UoKV0pXSksIF92bS5fdihcIiBcIiksIF9jKCdkaXYnLCB7XG4gICAgc3RhdGljQ2xhc3M6IFwibW9kYWwgZmFkZVwiLFxuICAgIGF0dHJzOiB7XG4gICAgICBcImlkXCI6IFwibW9kYWwtY3JlYXRlLWNsaWVudFwiLFxuICAgICAgXCJ0YWJpbmRleFwiOiBcIi0xXCIsXG4gICAgICBcInJvbGVcIjogXCJkaWFsb2dcIlxuICAgIH1cbiAgfSwgW19jKCdkaXYnLCB7XG4gICAgc3RhdGljQ2xhc3M6IFwibW9kYWwtZGlhbG9nXCJcbiAgfSwgW19jKCdkaXYnLCB7XG4gICAgc3RhdGljQ2xhc3M6IFwibW9kYWwtY29udGVudFwiXG4gIH0sIFtfdm0uX20oMSksIF92bS5fdihcIiBcIiksIF9jKCdkaXYnLCB7XG4gICAgc3RhdGljQ2xhc3M6IFwibW9kYWwtYm9keVwiXG4gIH0sIFsoX3ZtLmNyZWF0ZUZvcm0uZXJyb3JzLmxlbmd0aCA+IDApID8gX2MoJ2RpdicsIHtcbiAgICBzdGF0aWNDbGFzczogXCJhbGVydCBhbGVydC1kYW5nZXJcIlxuICB9LCBbX3ZtLl9tKDIpLCBfdm0uX3YoXCIgXCIpLCBfYygnYnInKSwgX3ZtLl92KFwiIFwiKSwgX2MoJ3VsJywgX3ZtLl9sKChfdm0uY3JlYXRlRm9ybS5lcnJvcnMpLCBmdW5jdGlvbihlcnJvcikge1xuICAgIHJldHVybiBfYygnbGknLCBbX3ZtLl92KFwiXFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcIiArIF92bS5fcyhlcnJvcikgKyBcIlxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBcIildKVxuICB9KSldKSA6IF92bS5fZSgpLCBfdm0uX3YoXCIgXCIpLCBfYygnZm9ybScsIHtcbiAgICBzdGF0aWNDbGFzczogXCJmb3JtLWhvcml6b250YWxcIixcbiAgICBhdHRyczoge1xuICAgICAgXCJyb2xlXCI6IFwiZm9ybVwiXG4gICAgfVxuICB9LCBbX2MoJ2RpdicsIHtcbiAgICBzdGF0aWNDbGFzczogXCJmb3JtLWdyb3VwXCJcbiAgfSwgW19jKCdsYWJlbCcsIHtcbiAgICBzdGF0aWNDbGFzczogXCJjb2wtbWQtMyBjb250cm9sLWxhYmVsXCJcbiAgfSwgW192bS5fdihcIk5hbWVcIildKSwgX3ZtLl92KFwiIFwiKSwgX2MoJ2RpdicsIHtcbiAgICBzdGF0aWNDbGFzczogXCJjb2wtbWQtN1wiXG4gIH0sIFtfYygnaW5wdXQnLCB7XG4gICAgZGlyZWN0aXZlczogW3tcbiAgICAgIG5hbWU6IFwibW9kZWxcIixcbiAgICAgIHJhd05hbWU6IFwidi1tb2RlbFwiLFxuICAgICAgdmFsdWU6IChfdm0uY3JlYXRlRm9ybS5uYW1lKSxcbiAgICAgIGV4cHJlc3Npb246IFwiY3JlYXRlRm9ybS5uYW1lXCJcbiAgICB9XSxcbiAgICBzdGF0aWNDbGFzczogXCJmb3JtLWNvbnRyb2xcIixcbiAgICBhdHRyczoge1xuICAgICAgXCJpZFwiOiBcImNyZWF0ZS1jbGllbnQtbmFtZVwiLFxuICAgICAgXCJ0eXBlXCI6IFwidGV4dFwiXG4gICAgfSxcbiAgICBkb21Qcm9wczoge1xuICAgICAgXCJ2YWx1ZVwiOiAoX3ZtLmNyZWF0ZUZvcm0ubmFtZSlcbiAgICB9LFxuICAgIG9uOiB7XG4gICAgICBcImtleXVwXCI6IGZ1bmN0aW9uKCRldmVudCkge1xuICAgICAgICBpZiAoISgnYnV0dG9uJyBpbiAkZXZlbnQpICYmIF92bS5faygkZXZlbnQua2V5Q29kZSwgXCJlbnRlclwiLCAxMykpIHsgcmV0dXJuIG51bGw7IH1cbiAgICAgICAgX3ZtLnN0b3JlKCRldmVudClcbiAgICAgIH0sXG4gICAgICBcImlucHV0XCI6IGZ1bmN0aW9uKCRldmVudCkge1xuICAgICAgICBpZiAoJGV2ZW50LnRhcmdldC5jb21wb3NpbmcpIHsgcmV0dXJuOyB9XG4gICAgICAgIF92bS5jcmVhdGVGb3JtLm5hbWUgPSAkZXZlbnQudGFyZ2V0LnZhbHVlXG4gICAgICB9XG4gICAgfVxuICB9KSwgX3ZtLl92KFwiIFwiKSwgX2MoJ3NwYW4nLCB7XG4gICAgc3RhdGljQ2xhc3M6IFwiaGVscC1ibG9ja1wiXG4gIH0sIFtfdm0uX3YoXCJcXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTb21ldGhpbmcgeW91ciB1c2VycyB3aWxsIHJlY29nbml6ZSBhbmQgdHJ1c3QuXFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcIildKV0pXSksIF92bS5fdihcIiBcIiksIF9jKCdkaXYnLCB7XG4gICAgc3RhdGljQ2xhc3M6IFwiZm9ybS1ncm91cFwiXG4gIH0sIFtfYygnbGFiZWwnLCB7XG4gICAgc3RhdGljQ2xhc3M6IFwiY29sLW1kLTMgY29udHJvbC1sYWJlbFwiXG4gIH0sIFtfdm0uX3YoXCJSZWRpcmVjdCBVUkxcIildKSwgX3ZtLl92KFwiIFwiKSwgX2MoJ2RpdicsIHtcbiAgICBzdGF0aWNDbGFzczogXCJjb2wtbWQtN1wiXG4gIH0sIFtfYygnaW5wdXQnLCB7XG4gICAgZGlyZWN0aXZlczogW3tcbiAgICAgIG5hbWU6IFwibW9kZWxcIixcbiAgICAgIHJhd05hbWU6IFwidi1tb2RlbFwiLFxuICAgICAgdmFsdWU6IChfdm0uY3JlYXRlRm9ybS5yZWRpcmVjdCksXG4gICAgICBleHByZXNzaW9uOiBcImNyZWF0ZUZvcm0ucmVkaXJlY3RcIlxuICAgIH1dLFxuICAgIHN0YXRpY0NsYXNzOiBcImZvcm0tY29udHJvbFwiLFxuICAgIGF0dHJzOiB7XG4gICAgICBcInR5cGVcIjogXCJ0ZXh0XCIsXG4gICAgICBcIm5hbWVcIjogXCJyZWRpcmVjdFwiXG4gICAgfSxcbiAgICBkb21Qcm9wczoge1xuICAgICAgXCJ2YWx1ZVwiOiAoX3ZtLmNyZWF0ZUZvcm0ucmVkaXJlY3QpXG4gICAgfSxcbiAgICBvbjoge1xuICAgICAgXCJrZXl1cFwiOiBmdW5jdGlvbigkZXZlbnQpIHtcbiAgICAgICAgaWYgKCEoJ2J1dHRvbicgaW4gJGV2ZW50KSAmJiBfdm0uX2soJGV2ZW50LmtleUNvZGUsIFwiZW50ZXJcIiwgMTMpKSB7IHJldHVybiBudWxsOyB9XG4gICAgICAgIF92bS5zdG9yZSgkZXZlbnQpXG4gICAgICB9LFxuICAgICAgXCJpbnB1dFwiOiBmdW5jdGlvbigkZXZlbnQpIHtcbiAgICAgICAgaWYgKCRldmVudC50YXJnZXQuY29tcG9zaW5nKSB7IHJldHVybjsgfVxuICAgICAgICBfdm0uY3JlYXRlRm9ybS5yZWRpcmVjdCA9ICRldmVudC50YXJnZXQudmFsdWVcbiAgICAgIH1cbiAgICB9XG4gIH0pLCBfdm0uX3YoXCIgXCIpLCBfYygnc3BhbicsIHtcbiAgICBzdGF0aWNDbGFzczogXCJoZWxwLWJsb2NrXCJcbiAgfSwgW192bS5fdihcIlxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFlvdXIgYXBwbGljYXRpb24ncyBhdXRob3JpemF0aW9uIGNhbGxiYWNrIFVSTC5cXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwiKV0pXSldKV0pXSksIF92bS5fdihcIiBcIiksIF9jKCdkaXYnLCB7XG4gICAgc3RhdGljQ2xhc3M6IFwibW9kYWwtZm9vdGVyXCJcbiAgfSwgW19jKCdidXR0b24nLCB7XG4gICAgc3RhdGljQ2xhc3M6IFwiYnRuIGJ0bi1kZWZhdWx0XCIsXG4gICAgYXR0cnM6IHtcbiAgICAgIFwidHlwZVwiOiBcImJ1dHRvblwiLFxuICAgICAgXCJkYXRhLWRpc21pc3NcIjogXCJtb2RhbFwiXG4gICAgfVxuICB9LCBbX3ZtLl92KFwiQ2xvc2VcIildKSwgX3ZtLl92KFwiIFwiKSwgX2MoJ2J1dHRvbicsIHtcbiAgICBzdGF0aWNDbGFzczogXCJidG4gYnRuLXByaW1hcnlcIixcbiAgICBhdHRyczoge1xuICAgICAgXCJ0eXBlXCI6IFwiYnV0dG9uXCJcbiAgICB9LFxuICAgIG9uOiB7XG4gICAgICBcImNsaWNrXCI6IF92bS5zdG9yZVxuICAgIH1cbiAgfSwgW192bS5fdihcIlxcbiAgICAgICAgICAgICAgICAgICAgICAgIENyZWF0ZVxcbiAgICAgICAgICAgICAgICAgICAgXCIpXSldKV0pXSldKSwgX3ZtLl92KFwiIFwiKSwgX2MoJ2RpdicsIHtcbiAgICBzdGF0aWNDbGFzczogXCJtb2RhbCBmYWRlXCIsXG4gICAgYXR0cnM6IHtcbiAgICAgIFwiaWRcIjogXCJtb2RhbC1lZGl0LWNsaWVudFwiLFxuICAgICAgXCJ0YWJpbmRleFwiOiBcIi0xXCIsXG4gICAgICBcInJvbGVcIjogXCJkaWFsb2dcIlxuICAgIH1cbiAgfSwgW19jKCdkaXYnLCB7XG4gICAgc3RhdGljQ2xhc3M6IFwibW9kYWwtZGlhbG9nXCJcbiAgfSwgW19jKCdkaXYnLCB7XG4gICAgc3RhdGljQ2xhc3M6IFwibW9kYWwtY29udGVudFwiXG4gIH0sIFtfdm0uX20oMyksIF92bS5fdihcIiBcIiksIF9jKCdkaXYnLCB7XG4gICAgc3RhdGljQ2xhc3M6IFwibW9kYWwtYm9keVwiXG4gIH0sIFsoX3ZtLmVkaXRGb3JtLmVycm9ycy5sZW5ndGggPiAwKSA/IF9jKCdkaXYnLCB7XG4gICAgc3RhdGljQ2xhc3M6IFwiYWxlcnQgYWxlcnQtZGFuZ2VyXCJcbiAgfSwgW192bS5fbSg0KSwgX3ZtLl92KFwiIFwiKSwgX2MoJ2JyJyksIF92bS5fdihcIiBcIiksIF9jKCd1bCcsIF92bS5fbCgoX3ZtLmVkaXRGb3JtLmVycm9ycyksIGZ1bmN0aW9uKGVycm9yKSB7XG4gICAgcmV0dXJuIF9jKCdsaScsIFtfdm0uX3YoXCJcXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwiICsgX3ZtLl9zKGVycm9yKSArIFwiXFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwiKV0pXG4gIH0pKV0pIDogX3ZtLl9lKCksIF92bS5fdihcIiBcIiksIF9jKCdmb3JtJywge1xuICAgIHN0YXRpY0NsYXNzOiBcImZvcm0taG9yaXpvbnRhbFwiLFxuICAgIGF0dHJzOiB7XG4gICAgICBcInJvbGVcIjogXCJmb3JtXCJcbiAgICB9XG4gIH0sIFtfYygnZGl2Jywge1xuICAgIHN0YXRpY0NsYXNzOiBcImZvcm0tZ3JvdXBcIlxuICB9LCBbX2MoJ2xhYmVsJywge1xuICAgIHN0YXRpY0NsYXNzOiBcImNvbC1tZC0zIGNvbnRyb2wtbGFiZWxcIlxuICB9LCBbX3ZtLl92KFwiTmFtZVwiKV0pLCBfdm0uX3YoXCIgXCIpLCBfYygnZGl2Jywge1xuICAgIHN0YXRpY0NsYXNzOiBcImNvbC1tZC03XCJcbiAgfSwgW19jKCdpbnB1dCcsIHtcbiAgICBkaXJlY3RpdmVzOiBbe1xuICAgICAgbmFtZTogXCJtb2RlbFwiLFxuICAgICAgcmF3TmFtZTogXCJ2LW1vZGVsXCIsXG4gICAgICB2YWx1ZTogKF92bS5lZGl0Rm9ybS5uYW1lKSxcbiAgICAgIGV4cHJlc3Npb246IFwiZWRpdEZvcm0ubmFtZVwiXG4gICAgfV0sXG4gICAgc3RhdGljQ2xhc3M6IFwiZm9ybS1jb250cm9sXCIsXG4gICAgYXR0cnM6IHtcbiAgICAgIFwiaWRcIjogXCJlZGl0LWNsaWVudC1uYW1lXCIsXG4gICAgICBcInR5cGVcIjogXCJ0ZXh0XCJcbiAgICB9LFxuICAgIGRvbVByb3BzOiB7XG4gICAgICBcInZhbHVlXCI6IChfdm0uZWRpdEZvcm0ubmFtZSlcbiAgICB9LFxuICAgIG9uOiB7XG4gICAgICBcImtleXVwXCI6IGZ1bmN0aW9uKCRldmVudCkge1xuICAgICAgICBpZiAoISgnYnV0dG9uJyBpbiAkZXZlbnQpICYmIF92bS5faygkZXZlbnQua2V5Q29kZSwgXCJlbnRlclwiLCAxMykpIHsgcmV0dXJuIG51bGw7IH1cbiAgICAgICAgX3ZtLnVwZGF0ZSgkZXZlbnQpXG4gICAgICB9LFxuICAgICAgXCJpbnB1dFwiOiBmdW5jdGlvbigkZXZlbnQpIHtcbiAgICAgICAgaWYgKCRldmVudC50YXJnZXQuY29tcG9zaW5nKSB7IHJldHVybjsgfVxuICAgICAgICBfdm0uZWRpdEZvcm0ubmFtZSA9ICRldmVudC50YXJnZXQudmFsdWVcbiAgICAgIH1cbiAgICB9XG4gIH0pLCBfdm0uX3YoXCIgXCIpLCBfYygnc3BhbicsIHtcbiAgICBzdGF0aWNDbGFzczogXCJoZWxwLWJsb2NrXCJcbiAgfSwgW192bS5fdihcIlxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNvbWV0aGluZyB5b3VyIHVzZXJzIHdpbGwgcmVjb2duaXplIGFuZCB0cnVzdC5cXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwiKV0pXSldKSwgX3ZtLl92KFwiIFwiKSwgX2MoJ2RpdicsIHtcbiAgICBzdGF0aWNDbGFzczogXCJmb3JtLWdyb3VwXCJcbiAgfSwgW19jKCdsYWJlbCcsIHtcbiAgICBzdGF0aWNDbGFzczogXCJjb2wtbWQtMyBjb250cm9sLWxhYmVsXCJcbiAgfSwgW192bS5fdihcIlJlZGlyZWN0IFVSTFwiKV0pLCBfdm0uX3YoXCIgXCIpLCBfYygnZGl2Jywge1xuICAgIHN0YXRpY0NsYXNzOiBcImNvbC1tZC03XCJcbiAgfSwgW19jKCdpbnB1dCcsIHtcbiAgICBkaXJlY3RpdmVzOiBbe1xuICAgICAgbmFtZTogXCJtb2RlbFwiLFxuICAgICAgcmF3TmFtZTogXCJ2LW1vZGVsXCIsXG4gICAgICB2YWx1ZTogKF92bS5lZGl0Rm9ybS5yZWRpcmVjdCksXG4gICAgICBleHByZXNzaW9uOiBcImVkaXRGb3JtLnJlZGlyZWN0XCJcbiAgICB9XSxcbiAgICBzdGF0aWNDbGFzczogXCJmb3JtLWNvbnRyb2xcIixcbiAgICBhdHRyczoge1xuICAgICAgXCJ0eXBlXCI6IFwidGV4dFwiLFxuICAgICAgXCJuYW1lXCI6IFwicmVkaXJlY3RcIlxuICAgIH0sXG4gICAgZG9tUHJvcHM6IHtcbiAgICAgIFwidmFsdWVcIjogKF92bS5lZGl0Rm9ybS5yZWRpcmVjdClcbiAgICB9LFxuICAgIG9uOiB7XG4gICAgICBcImtleXVwXCI6IGZ1bmN0aW9uKCRldmVudCkge1xuICAgICAgICBpZiAoISgnYnV0dG9uJyBpbiAkZXZlbnQpICYmIF92bS5faygkZXZlbnQua2V5Q29kZSwgXCJlbnRlclwiLCAxMykpIHsgcmV0dXJuIG51bGw7IH1cbiAgICAgICAgX3ZtLnVwZGF0ZSgkZXZlbnQpXG4gICAgICB9LFxuICAgICAgXCJpbnB1dFwiOiBmdW5jdGlvbigkZXZlbnQpIHtcbiAgICAgICAgaWYgKCRldmVudC50YXJnZXQuY29tcG9zaW5nKSB7IHJldHVybjsgfVxuICAgICAgICBfdm0uZWRpdEZvcm0ucmVkaXJlY3QgPSAkZXZlbnQudGFyZ2V0LnZhbHVlXG4gICAgICB9XG4gICAgfVxuICB9KSwgX3ZtLl92KFwiIFwiKSwgX2MoJ3NwYW4nLCB7XG4gICAgc3RhdGljQ2xhc3M6IFwiaGVscC1ibG9ja1wiXG4gIH0sIFtfdm0uX3YoXCJcXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBZb3VyIGFwcGxpY2F0aW9uJ3MgYXV0aG9yaXphdGlvbiBjYWxsYmFjayBVUkwuXFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcIildKV0pXSldKV0pLCBfdm0uX3YoXCIgXCIpLCBfYygnZGl2Jywge1xuICAgIHN0YXRpY0NsYXNzOiBcIm1vZGFsLWZvb3RlclwiXG4gIH0sIFtfYygnYnV0dG9uJywge1xuICAgIHN0YXRpY0NsYXNzOiBcImJ0biBidG4tZGVmYXVsdFwiLFxuICAgIGF0dHJzOiB7XG4gICAgICBcInR5cGVcIjogXCJidXR0b25cIixcbiAgICAgIFwiZGF0YS1kaXNtaXNzXCI6IFwibW9kYWxcIlxuICAgIH1cbiAgfSwgW192bS5fdihcIkNsb3NlXCIpXSksIF92bS5fdihcIiBcIiksIF9jKCdidXR0b24nLCB7XG4gICAgc3RhdGljQ2xhc3M6IFwiYnRuIGJ0bi1wcmltYXJ5XCIsXG4gICAgYXR0cnM6IHtcbiAgICAgIFwidHlwZVwiOiBcImJ1dHRvblwiXG4gICAgfSxcbiAgICBvbjoge1xuICAgICAgXCJjbGlja1wiOiBfdm0udXBkYXRlXG4gICAgfVxuICB9LCBbX3ZtLl92KFwiXFxuICAgICAgICAgICAgICAgICAgICAgICAgU2F2ZSBDaGFuZ2VzXFxuICAgICAgICAgICAgICAgICAgICBcIildKV0pXSldKV0pXSlcbn0sc3RhdGljUmVuZGVyRm5zOiBbZnVuY3Rpb24gKCl7dmFyIF92bT10aGlzO3ZhciBfaD1fdm0uJGNyZWF0ZUVsZW1lbnQ7dmFyIF9jPV92bS5fc2VsZi5fY3x8X2g7XG4gIHJldHVybiBfYygndGhlYWQnLCBbX2MoJ3RyJywgW19jKCd0aCcsIFtfdm0uX3YoXCJDbGllbnQgSURcIildKSwgX3ZtLl92KFwiIFwiKSwgX2MoJ3RoJywgW192bS5fdihcIk5hbWVcIildKSwgX3ZtLl92KFwiIFwiKSwgX2MoJ3RoJywgW192bS5fdihcIlNlY3JldFwiKV0pLCBfdm0uX3YoXCIgXCIpLCBfYygndGgnKSwgX3ZtLl92KFwiIFwiKSwgX2MoJ3RoJyldKV0pXG59LGZ1bmN0aW9uICgpe3ZhciBfdm09dGhpczt2YXIgX2g9X3ZtLiRjcmVhdGVFbGVtZW50O3ZhciBfYz1fdm0uX3NlbGYuX2N8fF9oO1xuICByZXR1cm4gX2MoJ2RpdicsIHtcbiAgICBzdGF0aWNDbGFzczogXCJtb2RhbC1oZWFkZXJcIlxuICB9LCBbX2MoJ2J1dHRvbicsIHtcbiAgICBzdGF0aWNDbGFzczogXCJjbG9zZVwiLFxuICAgIGF0dHJzOiB7XG4gICAgICBcInR5cGVcIjogXCJidXR0b24gXCIsXG4gICAgICBcImRhdGEtZGlzbWlzc1wiOiBcIm1vZGFsXCIsXG4gICAgICBcImFyaWEtaGlkZGVuXCI6IFwidHJ1ZVwiXG4gICAgfVxuICB9LCBbX3ZtLl92KFwiw5dcIildKSwgX3ZtLl92KFwiIFwiKSwgX2MoJ2g0Jywge1xuICAgIHN0YXRpY0NsYXNzOiBcIm1vZGFsLXRpdGxlXCJcbiAgfSwgW192bS5fdihcIlxcbiAgICAgICAgICAgICAgICAgICAgICAgIENyZWF0ZSBDbGllbnRcXG4gICAgICAgICAgICAgICAgICAgIFwiKV0pXSlcbn0sZnVuY3Rpb24gKCl7dmFyIF92bT10aGlzO3ZhciBfaD1fdm0uJGNyZWF0ZUVsZW1lbnQ7dmFyIF9jPV92bS5fc2VsZi5fY3x8X2g7XG4gIHJldHVybiBfYygncCcsIFtfYygnc3Ryb25nJywgW192bS5fdihcIldob29wcyFcIildKSwgX3ZtLl92KFwiIFNvbWV0aGluZyB3ZW50IHdyb25nIVwiKV0pXG59LGZ1bmN0aW9uICgpe3ZhciBfdm09dGhpczt2YXIgX2g9X3ZtLiRjcmVhdGVFbGVtZW50O3ZhciBfYz1fdm0uX3NlbGYuX2N8fF9oO1xuICByZXR1cm4gX2MoJ2RpdicsIHtcbiAgICBzdGF0aWNDbGFzczogXCJtb2RhbC1oZWFkZXJcIlxuICB9LCBbX2MoJ2J1dHRvbicsIHtcbiAgICBzdGF0aWNDbGFzczogXCJjbG9zZVwiLFxuICAgIGF0dHJzOiB7XG4gICAgICBcInR5cGVcIjogXCJidXR0b24gXCIsXG4gICAgICBcImRhdGEtZGlzbWlzc1wiOiBcIm1vZGFsXCIsXG4gICAgICBcImFyaWEtaGlkZGVuXCI6IFwidHJ1ZVwiXG4gICAgfVxuICB9LCBbX3ZtLl92KFwiw5dcIildKSwgX3ZtLl92KFwiIFwiKSwgX2MoJ2g0Jywge1xuICAgIHN0YXRpY0NsYXNzOiBcIm1vZGFsLXRpdGxlXCJcbiAgfSwgW192bS5fdihcIlxcbiAgICAgICAgICAgICAgICAgICAgICAgIEVkaXQgQ2xpZW50XFxuICAgICAgICAgICAgICAgICAgICBcIildKV0pXG59LGZ1bmN0aW9uICgpe3ZhciBfdm09dGhpczt2YXIgX2g9X3ZtLiRjcmVhdGVFbGVtZW50O3ZhciBfYz1fdm0uX3NlbGYuX2N8fF9oO1xuICByZXR1cm4gX2MoJ3AnLCBbX2MoJ3N0cm9uZycsIFtfdm0uX3YoXCJXaG9vcHMhXCIpXSksIF92bS5fdihcIiBTb21ldGhpbmcgd2VudCB3cm9uZyFcIildKVxufV19XG5tb2R1bGUuZXhwb3J0cy5yZW5kZXIuX3dpdGhTdHJpcHBlZCA9IHRydWVcbmlmIChtb2R1bGUuaG90KSB7XG4gIG1vZHVsZS5ob3QuYWNjZXB0KClcbiAgaWYgKG1vZHVsZS5ob3QuZGF0YSkge1xuICAgICByZXF1aXJlKFwidnVlLWhvdC1yZWxvYWQtYXBpXCIpLnJlcmVuZGVyKFwiZGF0YS12LWU5YzgwMzE4XCIsIG1vZHVsZS5leHBvcnRzKVxuICB9XG59XG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gLi9ub2RlX21vZHVsZXMvdnVlLWxvYWRlci9saWIvdGVtcGxhdGUtY29tcGlsZXI/e1wiaWRcIjpcImRhdGEtdi1lOWM4MDMxOFwiLFwiaGFzU2NvcGVkXCI6dHJ1ZX0hLi9ub2RlX21vZHVsZXMvdnVlLWxvYWRlci9saWIvc2VsZWN0b3IuanM/dHlwZT10ZW1wbGF0ZSZpbmRleD0wIS4vcmVzb3VyY2VzL2Fzc2V0cy9qcy9jb21wb25lbnRzL3Bhc3Nwb3J0L0NsaWVudHMudnVlXG4vLyBtb2R1bGUgaWQgPSAyMFxuLy8gbW9kdWxlIGNodW5rcyA9IDAiLCJ2YXIgZGlzcG9zZWQgPSBmYWxzZVxuZnVuY3Rpb24gaW5qZWN0U3R5bGUgKHNzckNvbnRleHQpIHtcbiAgaWYgKGRpc3Bvc2VkKSByZXR1cm5cbiAgcmVxdWlyZShcIiEhdnVlLXN0eWxlLWxvYWRlciFjc3MtbG9hZGVyP3NvdXJjZU1hcCEuLi8uLi8uLi8uLi8uLi9ub2RlX21vZHVsZXMvdnVlLWxvYWRlci9saWIvc3R5bGUtY29tcGlsZXIvaW5kZXg/e1xcXCJ2dWVcXFwiOnRydWUsXFxcImlkXFxcIjpcXFwiZGF0YS12LWRlMGQwZTRlXFxcIixcXFwic2NvcGVkXFxcIjp0cnVlLFxcXCJoYXNJbmxpbmVDb25maWdcXFwiOnRydWV9IS4uLy4uLy4uLy4uLy4uL25vZGVfbW9kdWxlcy92dWUtbG9hZGVyL2xpYi9zZWxlY3Rvcj90eXBlPXN0eWxlcyZpbmRleD0wIS4vQXV0aG9yaXplZENsaWVudHMudnVlXCIpXG59XG52YXIgQ29tcG9uZW50ID0gcmVxdWlyZShcIiEuLi8uLi8uLi8uLi8uLi9ub2RlX21vZHVsZXMvdnVlLWxvYWRlci9saWIvY29tcG9uZW50LW5vcm1hbGl6ZXJcIikoXG4gIC8qIHNjcmlwdCAqL1xuICByZXF1aXJlKFwiISFiYWJlbC1sb2FkZXI/e1xcXCJjYWNoZURpcmVjdG9yeVxcXCI6dHJ1ZSxcXFwicHJlc2V0c1xcXCI6W1tcXFwiZW52XFxcIix7XFxcIm1vZHVsZXNcXFwiOmZhbHNlLFxcXCJ0YXJnZXRzXFxcIjp7XFxcImJyb3dzZXJzXFxcIjpbXFxcIj4gMiVcXFwiXSxcXFwidWdsaWZ5XFxcIjp0cnVlfX1dXX0hLi4vLi4vLi4vLi4vLi4vbm9kZV9tb2R1bGVzL3Z1ZS1sb2FkZXIvbGliL3NlbGVjdG9yP3R5cGU9c2NyaXB0JmluZGV4PTAhLi9BdXRob3JpemVkQ2xpZW50cy52dWVcIiksXG4gIC8qIHRlbXBsYXRlICovXG4gIHJlcXVpcmUoXCIhIS4uLy4uLy4uLy4uLy4uL25vZGVfbW9kdWxlcy92dWUtbG9hZGVyL2xpYi90ZW1wbGF0ZS1jb21waWxlci9pbmRleD97XFxcImlkXFxcIjpcXFwiZGF0YS12LWRlMGQwZTRlXFxcIixcXFwiaGFzU2NvcGVkXFxcIjp0cnVlfSEuLi8uLi8uLi8uLi8uLi9ub2RlX21vZHVsZXMvdnVlLWxvYWRlci9saWIvc2VsZWN0b3I/dHlwZT10ZW1wbGF0ZSZpbmRleD0wIS4vQXV0aG9yaXplZENsaWVudHMudnVlXCIpLFxuICAvKiBzdHlsZXMgKi9cbiAgaW5qZWN0U3R5bGUsXG4gIC8qIHNjb3BlSWQgKi9cbiAgXCJkYXRhLXYtZGUwZDBlNGVcIixcbiAgLyogbW9kdWxlSWRlbnRpZmllciAoc2VydmVyIG9ubHkpICovXG4gIG51bGxcbilcbkNvbXBvbmVudC5vcHRpb25zLl9fZmlsZSA9IFwiL2hvbWUvaHlkcm9nZW4vd29yay9zbmlwZS1pdC9yZXNvdXJjZXMvYXNzZXRzL2pzL2NvbXBvbmVudHMvcGFzc3BvcnQvQXV0aG9yaXplZENsaWVudHMudnVlXCJcbmlmIChDb21wb25lbnQuZXNNb2R1bGUgJiYgT2JqZWN0LmtleXMoQ29tcG9uZW50LmVzTW9kdWxlKS5zb21lKGZ1bmN0aW9uIChrZXkpIHtyZXR1cm4ga2V5ICE9PSBcImRlZmF1bHRcIiAmJiBrZXkuc3Vic3RyKDAsIDIpICE9PSBcIl9fXCJ9KSkge2NvbnNvbGUuZXJyb3IoXCJuYW1lZCBleHBvcnRzIGFyZSBub3Qgc3VwcG9ydGVkIGluICoudnVlIGZpbGVzLlwiKX1cbmlmIChDb21wb25lbnQub3B0aW9ucy5mdW5jdGlvbmFsKSB7Y29uc29sZS5lcnJvcihcIlt2dWUtbG9hZGVyXSBBdXRob3JpemVkQ2xpZW50cy52dWU6IGZ1bmN0aW9uYWwgY29tcG9uZW50cyBhcmUgbm90IHN1cHBvcnRlZCB3aXRoIHRlbXBsYXRlcywgdGhleSBzaG91bGQgdXNlIHJlbmRlciBmdW5jdGlvbnMuXCIpfVxuXG4vKiBob3QgcmVsb2FkICovXG5pZiAobW9kdWxlLmhvdCkgeyhmdW5jdGlvbiAoKSB7XG4gIHZhciBob3RBUEkgPSByZXF1aXJlKFwidnVlLWhvdC1yZWxvYWQtYXBpXCIpXG4gIGhvdEFQSS5pbnN0YWxsKHJlcXVpcmUoXCJ2dWVcIiksIGZhbHNlKVxuICBpZiAoIWhvdEFQSS5jb21wYXRpYmxlKSByZXR1cm5cbiAgbW9kdWxlLmhvdC5hY2NlcHQoKVxuICBpZiAoIW1vZHVsZS5ob3QuZGF0YSkge1xuICAgIGhvdEFQSS5jcmVhdGVSZWNvcmQoXCJkYXRhLXYtZGUwZDBlNGVcIiwgQ29tcG9uZW50Lm9wdGlvbnMpXG4gIH0gZWxzZSB7XG4gICAgaG90QVBJLnJlbG9hZChcImRhdGEtdi1kZTBkMGU0ZVwiLCBDb21wb25lbnQub3B0aW9ucylcbiAgfVxuICBtb2R1bGUuaG90LmRpc3Bvc2UoZnVuY3Rpb24gKGRhdGEpIHtcbiAgICBkaXNwb3NlZCA9IHRydWVcbiAgfSlcbn0pKCl9XG5cbm1vZHVsZS5leHBvcnRzID0gQ29tcG9uZW50LmV4cG9ydHNcblxuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIC4vcmVzb3VyY2VzL2Fzc2V0cy9qcy9jb21wb25lbnRzL3Bhc3Nwb3J0L0F1dGhvcml6ZWRDbGllbnRzLnZ1ZVxuLy8gbW9kdWxlIGlkID0gMjFcbi8vIG1vZHVsZSBjaHVua3MgPSAwIiwiLy8gc3R5bGUtbG9hZGVyOiBBZGRzIHNvbWUgY3NzIHRvIHRoZSBET00gYnkgYWRkaW5nIGEgPHN0eWxlPiB0YWdcblxuLy8gbG9hZCB0aGUgc3R5bGVzXG52YXIgY29udGVudCA9IHJlcXVpcmUoXCIhIS4uLy4uLy4uLy4uLy4uL25vZGVfbW9kdWxlcy9jc3MtbG9hZGVyL2luZGV4LmpzP3NvdXJjZU1hcCEuLi8uLi8uLi8uLi8uLi9ub2RlX21vZHVsZXMvdnVlLWxvYWRlci9saWIvc3R5bGUtY29tcGlsZXIvaW5kZXguanM/e1xcXCJ2dWVcXFwiOnRydWUsXFxcImlkXFxcIjpcXFwiZGF0YS12LWRlMGQwZTRlXFxcIixcXFwic2NvcGVkXFxcIjp0cnVlLFxcXCJoYXNJbmxpbmVDb25maWdcXFwiOnRydWV9IS4uLy4uLy4uLy4uLy4uL25vZGVfbW9kdWxlcy92dWUtbG9hZGVyL2xpYi9zZWxlY3Rvci5qcz90eXBlPXN0eWxlcyZpbmRleD0wIS4vQXV0aG9yaXplZENsaWVudHMudnVlXCIpO1xuaWYodHlwZW9mIGNvbnRlbnQgPT09ICdzdHJpbmcnKSBjb250ZW50ID0gW1ttb2R1bGUuaWQsIGNvbnRlbnQsICcnXV07XG5pZihjb250ZW50LmxvY2FscykgbW9kdWxlLmV4cG9ydHMgPSBjb250ZW50LmxvY2Fscztcbi8vIGFkZCB0aGUgc3R5bGVzIHRvIHRoZSBET01cbnZhciB1cGRhdGUgPSByZXF1aXJlKFwiIS4uLy4uLy4uLy4uLy4uL25vZGVfbW9kdWxlcy92dWUtc3R5bGUtbG9hZGVyL2xpYi9hZGRTdHlsZXNDbGllbnQuanNcIikoXCJlNWMzOTY4NFwiLCBjb250ZW50LCBmYWxzZSk7XG4vLyBIb3QgTW9kdWxlIFJlcGxhY2VtZW50XG5pZihtb2R1bGUuaG90KSB7XG4gLy8gV2hlbiB0aGUgc3R5bGVzIGNoYW5nZSwgdXBkYXRlIHRoZSA8c3R5bGU+IHRhZ3NcbiBpZighY29udGVudC5sb2NhbHMpIHtcbiAgIG1vZHVsZS5ob3QuYWNjZXB0KFwiISEuLi8uLi8uLi8uLi8uLi9ub2RlX21vZHVsZXMvY3NzLWxvYWRlci9pbmRleC5qcz9zb3VyY2VNYXAhLi4vLi4vLi4vLi4vLi4vbm9kZV9tb2R1bGVzL3Z1ZS1sb2FkZXIvbGliL3N0eWxlLWNvbXBpbGVyL2luZGV4LmpzP3tcXFwidnVlXFxcIjp0cnVlLFxcXCJpZFxcXCI6XFxcImRhdGEtdi1kZTBkMGU0ZVxcXCIsXFxcInNjb3BlZFxcXCI6dHJ1ZSxcXFwiaGFzSW5saW5lQ29uZmlnXFxcIjp0cnVlfSEuLi8uLi8uLi8uLi8uLi9ub2RlX21vZHVsZXMvdnVlLWxvYWRlci9saWIvc2VsZWN0b3IuanM/dHlwZT1zdHlsZXMmaW5kZXg9MCEuL0F1dGhvcml6ZWRDbGllbnRzLnZ1ZVwiLCBmdW5jdGlvbigpIHtcbiAgICAgdmFyIG5ld0NvbnRlbnQgPSByZXF1aXJlKFwiISEuLi8uLi8uLi8uLi8uLi9ub2RlX21vZHVsZXMvY3NzLWxvYWRlci9pbmRleC5qcz9zb3VyY2VNYXAhLi4vLi4vLi4vLi4vLi4vbm9kZV9tb2R1bGVzL3Z1ZS1sb2FkZXIvbGliL3N0eWxlLWNvbXBpbGVyL2luZGV4LmpzP3tcXFwidnVlXFxcIjp0cnVlLFxcXCJpZFxcXCI6XFxcImRhdGEtdi1kZTBkMGU0ZVxcXCIsXFxcInNjb3BlZFxcXCI6dHJ1ZSxcXFwiaGFzSW5saW5lQ29uZmlnXFxcIjp0cnVlfSEuLi8uLi8uLi8uLi8uLi9ub2RlX21vZHVsZXMvdnVlLWxvYWRlci9saWIvc2VsZWN0b3IuanM/dHlwZT1zdHlsZXMmaW5kZXg9MCEuL0F1dGhvcml6ZWRDbGllbnRzLnZ1ZVwiKTtcbiAgICAgaWYodHlwZW9mIG5ld0NvbnRlbnQgPT09ICdzdHJpbmcnKSBuZXdDb250ZW50ID0gW1ttb2R1bGUuaWQsIG5ld0NvbnRlbnQsICcnXV07XG4gICAgIHVwZGF0ZShuZXdDb250ZW50KTtcbiAgIH0pO1xuIH1cbiAvLyBXaGVuIHRoZSBtb2R1bGUgaXMgZGlzcG9zZWQsIHJlbW92ZSB0aGUgPHN0eWxlPiB0YWdzXG4gbW9kdWxlLmhvdC5kaXNwb3NlKGZ1bmN0aW9uKCkgeyB1cGRhdGUoKTsgfSk7XG59XG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gLi9ub2RlX21vZHVsZXMvdnVlLXN0eWxlLWxvYWRlciEuL25vZGVfbW9kdWxlcy9jc3MtbG9hZGVyP3NvdXJjZU1hcCEuL25vZGVfbW9kdWxlcy92dWUtbG9hZGVyL2xpYi9zdHlsZS1jb21waWxlcj97XCJ2dWVcIjp0cnVlLFwiaWRcIjpcImRhdGEtdi1kZTBkMGU0ZVwiLFwic2NvcGVkXCI6dHJ1ZSxcImhhc0lubGluZUNvbmZpZ1wiOnRydWV9IS4vbm9kZV9tb2R1bGVzL3Z1ZS1sb2FkZXIvbGliL3NlbGVjdG9yLmpzP3R5cGU9c3R5bGVzJmluZGV4PTAhLi9yZXNvdXJjZXMvYXNzZXRzL2pzL2NvbXBvbmVudHMvcGFzc3BvcnQvQXV0aG9yaXplZENsaWVudHMudnVlXG4vLyBtb2R1bGUgaWQgPSAyMlxuLy8gbW9kdWxlIGNodW5rcyA9IDAiLCJleHBvcnRzID0gbW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKFwiLi4vLi4vLi4vLi4vLi4vbm9kZV9tb2R1bGVzL2Nzcy1sb2FkZXIvbGliL2Nzcy1iYXNlLmpzXCIpKHRydWUpO1xuLy8gaW1wb3J0c1xuXG5cbi8vIG1vZHVsZVxuZXhwb3J0cy5wdXNoKFttb2R1bGUuaWQsIFwiXFxuLmFjdGlvbi1saW5rW2RhdGEtdi1kZTBkMGU0ZV0ge1xcbiAgICBjdXJzb3I6IHBvaW50ZXI7XFxufVxcbi5tLWItbm9uZVtkYXRhLXYtZGUwZDBlNGVdIHtcXG4gICAgbWFyZ2luLWJvdHRvbTogMDtcXG59XFxuXCIsIFwiXCIsIHtcInZlcnNpb25cIjozLFwic291cmNlc1wiOltcIi9ob21lL2h5ZHJvZ2VuL3dvcmsvc25pcGUtaXQvcmVzb3VyY2VzL2Fzc2V0cy9qcy9jb21wb25lbnRzL3Bhc3Nwb3J0L0F1dGhvcml6ZWRDbGllbnRzLnZ1ZT9hOTkwNzZjMFwiXSxcIm5hbWVzXCI6W10sXCJtYXBwaW5nc1wiOlwiO0FBQ0E7SUFDQSxnQkFBQTtDQUNBO0FBRUE7SUFDQSxpQkFBQTtDQUNBXCIsXCJmaWxlXCI6XCJBdXRob3JpemVkQ2xpZW50cy52dWVcIixcInNvdXJjZXNDb250ZW50XCI6W1wiPHN0eWxlIHNjb3BlZD5cXG4gICAgLmFjdGlvbi1saW5rIHtcXG4gICAgICAgIGN1cnNvcjogcG9pbnRlcjtcXG4gICAgfVxcblxcbiAgICAubS1iLW5vbmUge1xcbiAgICAgICAgbWFyZ2luLWJvdHRvbTogMDtcXG4gICAgfVxcbjwvc3R5bGU+XFxuXFxuPHRlbXBsYXRlPlxcbiAgICA8ZGl2PlxcbiAgICAgICAgPGRpdiB2LWlmPVxcXCJ0b2tlbnMubGVuZ3RoID4gMFxcXCI+XFxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cXFwicGFuZWwgcGFuZWwtZGVmYXVsdFxcXCI+XFxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XFxcInBhbmVsLWhlYWRpbmdcXFwiPkF1dGhvcml6ZWQgQXBwbGljYXRpb25zPC9kaXY+XFxuXFxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XFxcInBhbmVsLWJvZHlcXFwiPlxcbiAgICAgICAgICAgICAgICAgICAgPCEtLSBBdXRob3JpemVkIFRva2VucyAtLT5cXG4gICAgICAgICAgICAgICAgICAgIDx0YWJsZSBjbGFzcz1cXFwidGFibGUgdGFibGUtYm9yZGVybGVzcyBtLWItbm9uZVxcXCI+XFxuICAgICAgICAgICAgICAgICAgICAgICAgPHRoZWFkPlxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8dHI+XFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8dGg+TmFtZTwvdGg+XFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8dGg+U2NvcGVzPC90aD5cXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDx0aD48L3RoPlxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3RyPlxcbiAgICAgICAgICAgICAgICAgICAgICAgIDwvdGhlYWQ+XFxuXFxuICAgICAgICAgICAgICAgICAgICAgICAgPHRib2R5PlxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8dHIgdi1mb3I9XFxcInRva2VuIGluIHRva2Vuc1xcXCI+XFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8IS0tIENsaWVudCBOYW1lIC0tPlxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHRkIHN0eWxlPVxcXCJ2ZXJ0aWNhbC1hbGlnbjogbWlkZGxlO1xcXCI+XFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAge3sgdG9rZW4uY2xpZW50Lm5hbWUgfX1cXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvdGQ+XFxuXFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8IS0tIFNjb3BlcyAtLT5cXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDx0ZCBzdHlsZT1cXFwidmVydGljYWwtYWxpZ246IG1pZGRsZTtcXFwiPlxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIHYtaWY9XFxcInRva2VuLnNjb3Blcy5sZW5ndGggPiAwXFxcIj5cXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAge3sgdG9rZW4uc2NvcGVzLmpvaW4oJywgJykgfX1cXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3NwYW4+XFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3RkPlxcblxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPCEtLSBSZXZva2UgQnV0dG9uIC0tPlxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHRkIHN0eWxlPVxcXCJ2ZXJ0aWNhbC1hbGlnbjogbWlkZGxlO1xcXCI+XFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGEgY2xhc3M9XFxcImFjdGlvbi1saW5rIHRleHQtZGFuZ2VyXFxcIiBAY2xpY2s9XFxcInJldm9rZSh0b2tlbilcXFwiPlxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBSZXZva2VcXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2E+XFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3RkPlxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3RyPlxcbiAgICAgICAgICAgICAgICAgICAgICAgIDwvdGJvZHk+XFxuICAgICAgICAgICAgICAgICAgICA8L3RhYmxlPlxcbiAgICAgICAgICAgICAgICA8L2Rpdj5cXG4gICAgICAgICAgICA8L2Rpdj5cXG4gICAgICAgIDwvZGl2PlxcbiAgICA8L2Rpdj5cXG48L3RlbXBsYXRlPlxcblxcbjxzY3JpcHQ+XFxuICAgIGV4cG9ydCBkZWZhdWx0IHtcXG4gICAgICAgIC8qXFxuICAgICAgICAgKiBUaGUgY29tcG9uZW50J3MgZGF0YS5cXG4gICAgICAgICAqL1xcbiAgICAgICAgZGF0YSgpIHtcXG4gICAgICAgICAgICByZXR1cm4ge1xcbiAgICAgICAgICAgICAgICB0b2tlbnM6IFtdXFxuICAgICAgICAgICAgfTtcXG4gICAgICAgIH0sXFxuXFxuICAgICAgICAvKipcXG4gICAgICAgICAqIFByZXBhcmUgdGhlIGNvbXBvbmVudCAoVnVlIDEueCkuXFxuICAgICAgICAgKi9cXG4gICAgICAgIHJlYWR5KCkge1xcbiAgICAgICAgICAgIHRoaXMucHJlcGFyZUNvbXBvbmVudCgpO1xcbiAgICAgICAgfSxcXG5cXG4gICAgICAgIC8qKlxcbiAgICAgICAgICogUHJlcGFyZSB0aGUgY29tcG9uZW50IChWdWUgMi54KS5cXG4gICAgICAgICAqL1xcbiAgICAgICAgbW91bnRlZCgpIHtcXG4gICAgICAgICAgICB0aGlzLnByZXBhcmVDb21wb25lbnQoKTtcXG4gICAgICAgIH0sXFxuXFxuICAgICAgICBtZXRob2RzOiB7XFxuICAgICAgICAgICAgLyoqXFxuICAgICAgICAgICAgICogUHJlcGFyZSB0aGUgY29tcG9uZW50IChWdWUgMi54KS5cXG4gICAgICAgICAgICAgKi9cXG4gICAgICAgICAgICBwcmVwYXJlQ29tcG9uZW50KCkge1xcbiAgICAgICAgICAgICAgICB0aGlzLmdldFRva2VucygpO1xcbiAgICAgICAgICAgIH0sXFxuXFxuICAgICAgICAgICAgLyoqXFxuICAgICAgICAgICAgICogR2V0IGFsbCBvZiB0aGUgYXV0aG9yaXplZCB0b2tlbnMgZm9yIHRoZSB1c2VyLlxcbiAgICAgICAgICAgICAqL1xcbiAgICAgICAgICAgIGdldFRva2VucygpIHtcXG4gICAgICAgICAgICAgICAgdGhpcy4kaHR0cC5nZXQoJy9vYXV0aC90b2tlbnMnKVxcbiAgICAgICAgICAgICAgICAgICAgICAgIC50aGVuKHJlc3BvbnNlID0+IHtcXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy50b2tlbnMgPSByZXNwb25zZS5kYXRhO1xcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xcbiAgICAgICAgICAgIH0sXFxuXFxuICAgICAgICAgICAgLyoqXFxuICAgICAgICAgICAgICogUmV2b2tlIHRoZSBnaXZlbiB0b2tlbi5cXG4gICAgICAgICAgICAgKi9cXG4gICAgICAgICAgICByZXZva2UodG9rZW4pIHtcXG4gICAgICAgICAgICAgICAgdGhpcy4kaHR0cC5kZWxldGUoJy9vYXV0aC90b2tlbnMvJyArIHRva2VuLmlkKVxcbiAgICAgICAgICAgICAgICAgICAgICAgIC50aGVuKHJlc3BvbnNlID0+IHtcXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5nZXRUb2tlbnMoKTtcXG4gICAgICAgICAgICAgICAgICAgICAgICB9KTtcXG4gICAgICAgICAgICB9XFxuICAgICAgICB9XFxuICAgIH1cXG48L3NjcmlwdD5cXG5cIl0sXCJzb3VyY2VSb290XCI6XCJcIn1dKTtcblxuLy8gZXhwb3J0c1xuXG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gLi9ub2RlX21vZHVsZXMvY3NzLWxvYWRlcj9zb3VyY2VNYXAhLi9ub2RlX21vZHVsZXMvdnVlLWxvYWRlci9saWIvc3R5bGUtY29tcGlsZXI/e1widnVlXCI6dHJ1ZSxcImlkXCI6XCJkYXRhLXYtZGUwZDBlNGVcIixcInNjb3BlZFwiOnRydWUsXCJoYXNJbmxpbmVDb25maWdcIjp0cnVlfSEuL25vZGVfbW9kdWxlcy92dWUtbG9hZGVyL2xpYi9zZWxlY3Rvci5qcz90eXBlPXN0eWxlcyZpbmRleD0wIS4vcmVzb3VyY2VzL2Fzc2V0cy9qcy9jb21wb25lbnRzL3Bhc3Nwb3J0L0F1dGhvcml6ZWRDbGllbnRzLnZ1ZVxuLy8gbW9kdWxlIGlkID0gMjNcbi8vIG1vZHVsZSBjaHVua3MgPSAwIiwiPHN0eWxlIHNjb3BlZD5cbiAgICAuYWN0aW9uLWxpbmsge1xuICAgICAgICBjdXJzb3I6IHBvaW50ZXI7XG4gICAgfVxuXG4gICAgLm0tYi1ub25lIHtcbiAgICAgICAgbWFyZ2luLWJvdHRvbTogMDtcbiAgICB9XG48L3N0eWxlPlxuXG48dGVtcGxhdGU+XG4gICAgPGRpdj5cbiAgICAgICAgPGRpdiB2LWlmPVwidG9rZW5zLmxlbmd0aCA+IDBcIj5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJwYW5lbCBwYW5lbC1kZWZhdWx0XCI+XG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInBhbmVsLWhlYWRpbmdcIj5BdXRob3JpemVkIEFwcGxpY2F0aW9uczwvZGl2PlxuXG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInBhbmVsLWJvZHlcIj5cbiAgICAgICAgICAgICAgICAgICAgPCEtLSBBdXRob3JpemVkIFRva2VucyAtLT5cbiAgICAgICAgICAgICAgICAgICAgPHRhYmxlIGNsYXNzPVwidGFibGUgdGFibGUtYm9yZGVybGVzcyBtLWItbm9uZVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPHRoZWFkPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDx0cj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHRoPk5hbWU8L3RoPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8dGg+U2NvcGVzPC90aD5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHRoPjwvdGg+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC90cj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvdGhlYWQ+XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIDx0Ym9keT5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8dHIgdi1mb3I9XCJ0b2tlbiBpbiB0b2tlbnNcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPCEtLSBDbGllbnQgTmFtZSAtLT5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHRkIHN0eWxlPVwidmVydGljYWwtYWxpZ246IG1pZGRsZTtcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHt7IHRva2VuLmNsaWVudC5uYW1lIH19XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvdGQ+XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPCEtLSBTY29wZXMgLS0+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDx0ZCBzdHlsZT1cInZlcnRpY2FsLWFsaWduOiBtaWRkbGU7XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiB2LWlmPVwidG9rZW4uc2NvcGVzLmxlbmd0aCA+IDBcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7eyB0b2tlbi5zY29wZXMuam9pbignLCAnKSB9fVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3RkPlxuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwhLS0gUmV2b2tlIEJ1dHRvbiAtLT5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHRkIHN0eWxlPVwidmVydGljYWwtYWxpZ246IG1pZGRsZTtcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxhIGNsYXNzPVwiYWN0aW9uLWxpbmsgdGV4dC1kYW5nZXJcIiBAY2xpY2s9XCJyZXZva2UodG9rZW4pXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUmV2b2tlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2E+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvdGQ+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC90cj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvdGJvZHk+XG4gICAgICAgICAgICAgICAgICAgIDwvdGFibGU+XG4gICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgPC9kaXY+XG4gICAgPC9kaXY+XG48L3RlbXBsYXRlPlxuXG48c2NyaXB0PlxuICAgIGV4cG9ydCBkZWZhdWx0IHtcbiAgICAgICAgLypcbiAgICAgICAgICogVGhlIGNvbXBvbmVudCdzIGRhdGEuXG4gICAgICAgICAqL1xuICAgICAgICBkYXRhKCkge1xuICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgICB0b2tlbnM6IFtdXG4gICAgICAgICAgICB9O1xuICAgICAgICB9LFxuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBQcmVwYXJlIHRoZSBjb21wb25lbnQgKFZ1ZSAxLngpLlxuICAgICAgICAgKi9cbiAgICAgICAgcmVhZHkoKSB7XG4gICAgICAgICAgICB0aGlzLnByZXBhcmVDb21wb25lbnQoKTtcbiAgICAgICAgfSxcblxuICAgICAgICAvKipcbiAgICAgICAgICogUHJlcGFyZSB0aGUgY29tcG9uZW50IChWdWUgMi54KS5cbiAgICAgICAgICovXG4gICAgICAgIG1vdW50ZWQoKSB7XG4gICAgICAgICAgICB0aGlzLnByZXBhcmVDb21wb25lbnQoKTtcbiAgICAgICAgfSxcblxuICAgICAgICBtZXRob2RzOiB7XG4gICAgICAgICAgICAvKipcbiAgICAgICAgICAgICAqIFByZXBhcmUgdGhlIGNvbXBvbmVudCAoVnVlIDIueCkuXG4gICAgICAgICAgICAgKi9cbiAgICAgICAgICAgIHByZXBhcmVDb21wb25lbnQoKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5nZXRUb2tlbnMoKTtcbiAgICAgICAgICAgIH0sXG5cbiAgICAgICAgICAgIC8qKlxuICAgICAgICAgICAgICogR2V0IGFsbCBvZiB0aGUgYXV0aG9yaXplZCB0b2tlbnMgZm9yIHRoZSB1c2VyLlxuICAgICAgICAgICAgICovXG4gICAgICAgICAgICBnZXRUb2tlbnMoKSB7XG4gICAgICAgICAgICAgICAgdGhpcy4kaHR0cC5nZXQoJy9vYXV0aC90b2tlbnMnKVxuICAgICAgICAgICAgICAgICAgICAgICAgLnRoZW4ocmVzcG9uc2UgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMudG9rZW5zID0gcmVzcG9uc2UuZGF0YTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfSxcblxuICAgICAgICAgICAgLyoqXG4gICAgICAgICAgICAgKiBSZXZva2UgdGhlIGdpdmVuIHRva2VuLlxuICAgICAgICAgICAgICovXG4gICAgICAgICAgICByZXZva2UodG9rZW4pIHtcbiAgICAgICAgICAgICAgICB0aGlzLiRodHRwLmRlbGV0ZSgnL29hdXRoL3Rva2Vucy8nICsgdG9rZW4uaWQpXG4gICAgICAgICAgICAgICAgICAgICAgICAudGhlbihyZXNwb25zZSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5nZXRUb2tlbnMoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuPC9zY3JpcHQ+XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gQXV0aG9yaXplZENsaWVudHMudnVlP2E5OTA3NmMwIiwibW9kdWxlLmV4cG9ydHM9e3JlbmRlcjpmdW5jdGlvbiAoKXt2YXIgX3ZtPXRoaXM7dmFyIF9oPV92bS4kY3JlYXRlRWxlbWVudDt2YXIgX2M9X3ZtLl9zZWxmLl9jfHxfaDtcbiAgcmV0dXJuIF9jKCdkaXYnLCBbKF92bS50b2tlbnMubGVuZ3RoID4gMCkgPyBfYygnZGl2JywgW19jKCdkaXYnLCB7XG4gICAgc3RhdGljQ2xhc3M6IFwicGFuZWwgcGFuZWwtZGVmYXVsdFwiXG4gIH0sIFtfYygnZGl2Jywge1xuICAgIHN0YXRpY0NsYXNzOiBcInBhbmVsLWhlYWRpbmdcIlxuICB9LCBbX3ZtLl92KFwiQXV0aG9yaXplZCBBcHBsaWNhdGlvbnNcIildKSwgX3ZtLl92KFwiIFwiKSwgX2MoJ2RpdicsIHtcbiAgICBzdGF0aWNDbGFzczogXCJwYW5lbC1ib2R5XCJcbiAgfSwgW19jKCd0YWJsZScsIHtcbiAgICBzdGF0aWNDbGFzczogXCJ0YWJsZSB0YWJsZS1ib3JkZXJsZXNzIG0tYi1ub25lXCJcbiAgfSwgW192bS5fbSgwKSwgX3ZtLl92KFwiIFwiKSwgX2MoJ3Rib2R5JywgX3ZtLl9sKChfdm0udG9rZW5zKSwgZnVuY3Rpb24odG9rZW4pIHtcbiAgICByZXR1cm4gX2MoJ3RyJywgW19jKCd0ZCcsIHtcbiAgICAgIHN0YXRpY1N0eWxlOiB7XG4gICAgICAgIFwidmVydGljYWwtYWxpZ25cIjogXCJtaWRkbGVcIlxuICAgICAgfVxuICAgIH0sIFtfdm0uX3YoXCJcXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwiICsgX3ZtLl9zKHRva2VuLmNsaWVudC5uYW1lKSArIFwiXFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwiKV0pLCBfdm0uX3YoXCIgXCIpLCBfYygndGQnLCB7XG4gICAgICBzdGF0aWNTdHlsZToge1xuICAgICAgICBcInZlcnRpY2FsLWFsaWduXCI6IFwibWlkZGxlXCJcbiAgICAgIH1cbiAgICB9LCBbKHRva2VuLnNjb3Blcy5sZW5ndGggPiAwKSA/IF9jKCdzcGFuJywgW192bS5fdihcIlxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwiICsgX3ZtLl9zKHRva2VuLnNjb3Blcy5qb2luKCcsICcpKSArIFwiXFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcIildKSA6IF92bS5fZSgpXSksIF92bS5fdihcIiBcIiksIF9jKCd0ZCcsIHtcbiAgICAgIHN0YXRpY1N0eWxlOiB7XG4gICAgICAgIFwidmVydGljYWwtYWxpZ25cIjogXCJtaWRkbGVcIlxuICAgICAgfVxuICAgIH0sIFtfYygnYScsIHtcbiAgICAgIHN0YXRpY0NsYXNzOiBcImFjdGlvbi1saW5rIHRleHQtZGFuZ2VyXCIsXG4gICAgICBvbjoge1xuICAgICAgICBcImNsaWNrXCI6IGZ1bmN0aW9uKCRldmVudCkge1xuICAgICAgICAgIF92bS5yZXZva2UodG9rZW4pXG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9LCBbX3ZtLl92KFwiXFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUmV2b2tlXFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcIildKV0pXSlcbiAgfSkpXSldKV0pXSkgOiBfdm0uX2UoKV0pXG59LHN0YXRpY1JlbmRlckZuczogW2Z1bmN0aW9uICgpe3ZhciBfdm09dGhpczt2YXIgX2g9X3ZtLiRjcmVhdGVFbGVtZW50O3ZhciBfYz1fdm0uX3NlbGYuX2N8fF9oO1xuICByZXR1cm4gX2MoJ3RoZWFkJywgW19jKCd0cicsIFtfYygndGgnLCBbX3ZtLl92KFwiTmFtZVwiKV0pLCBfdm0uX3YoXCIgXCIpLCBfYygndGgnLCBbX3ZtLl92KFwiU2NvcGVzXCIpXSksIF92bS5fdihcIiBcIiksIF9jKCd0aCcpXSldKVxufV19XG5tb2R1bGUuZXhwb3J0cy5yZW5kZXIuX3dpdGhTdHJpcHBlZCA9IHRydWVcbmlmIChtb2R1bGUuaG90KSB7XG4gIG1vZHVsZS5ob3QuYWNjZXB0KClcbiAgaWYgKG1vZHVsZS5ob3QuZGF0YSkge1xuICAgICByZXF1aXJlKFwidnVlLWhvdC1yZWxvYWQtYXBpXCIpLnJlcmVuZGVyKFwiZGF0YS12LWRlMGQwZTRlXCIsIG1vZHVsZS5leHBvcnRzKVxuICB9XG59XG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gLi9ub2RlX21vZHVsZXMvdnVlLWxvYWRlci9saWIvdGVtcGxhdGUtY29tcGlsZXI/e1wiaWRcIjpcImRhdGEtdi1kZTBkMGU0ZVwiLFwiaGFzU2NvcGVkXCI6dHJ1ZX0hLi9ub2RlX21vZHVsZXMvdnVlLWxvYWRlci9saWIvc2VsZWN0b3IuanM/dHlwZT10ZW1wbGF0ZSZpbmRleD0wIS4vcmVzb3VyY2VzL2Fzc2V0cy9qcy9jb21wb25lbnRzL3Bhc3Nwb3J0L0F1dGhvcml6ZWRDbGllbnRzLnZ1ZVxuLy8gbW9kdWxlIGlkID0gMjVcbi8vIG1vZHVsZSBjaHVua3MgPSAwIiwidmFyIGRpc3Bvc2VkID0gZmFsc2VcbmZ1bmN0aW9uIGluamVjdFN0eWxlIChzc3JDb250ZXh0KSB7XG4gIGlmIChkaXNwb3NlZCkgcmV0dXJuXG4gIHJlcXVpcmUoXCIhIXZ1ZS1zdHlsZS1sb2FkZXIhY3NzLWxvYWRlcj9zb3VyY2VNYXAhLi4vLi4vLi4vLi4vLi4vbm9kZV9tb2R1bGVzL3Z1ZS1sb2FkZXIvbGliL3N0eWxlLWNvbXBpbGVyL2luZGV4P3tcXFwidnVlXFxcIjp0cnVlLFxcXCJpZFxcXCI6XFxcImRhdGEtdi0yMjU3NzhjMlxcXCIsXFxcInNjb3BlZFxcXCI6dHJ1ZSxcXFwiaGFzSW5saW5lQ29uZmlnXFxcIjp0cnVlfSEuLi8uLi8uLi8uLi8uLi9ub2RlX21vZHVsZXMvdnVlLWxvYWRlci9saWIvc2VsZWN0b3I/dHlwZT1zdHlsZXMmaW5kZXg9MCEuL1BlcnNvbmFsQWNjZXNzVG9rZW5zLnZ1ZVwiKVxufVxudmFyIENvbXBvbmVudCA9IHJlcXVpcmUoXCIhLi4vLi4vLi4vLi4vLi4vbm9kZV9tb2R1bGVzL3Z1ZS1sb2FkZXIvbGliL2NvbXBvbmVudC1ub3JtYWxpemVyXCIpKFxuICAvKiBzY3JpcHQgKi9cbiAgcmVxdWlyZShcIiEhYmFiZWwtbG9hZGVyP3tcXFwiY2FjaGVEaXJlY3RvcnlcXFwiOnRydWUsXFxcInByZXNldHNcXFwiOltbXFxcImVudlxcXCIse1xcXCJtb2R1bGVzXFxcIjpmYWxzZSxcXFwidGFyZ2V0c1xcXCI6e1xcXCJicm93c2Vyc1xcXCI6W1xcXCI+IDIlXFxcIl0sXFxcInVnbGlmeVxcXCI6dHJ1ZX19XV19IS4uLy4uLy4uLy4uLy4uL25vZGVfbW9kdWxlcy92dWUtbG9hZGVyL2xpYi9zZWxlY3Rvcj90eXBlPXNjcmlwdCZpbmRleD0wIS4vUGVyc29uYWxBY2Nlc3NUb2tlbnMudnVlXCIpLFxuICAvKiB0ZW1wbGF0ZSAqL1xuICByZXF1aXJlKFwiISEuLi8uLi8uLi8uLi8uLi9ub2RlX21vZHVsZXMvdnVlLWxvYWRlci9saWIvdGVtcGxhdGUtY29tcGlsZXIvaW5kZXg/e1xcXCJpZFxcXCI6XFxcImRhdGEtdi0yMjU3NzhjMlxcXCIsXFxcImhhc1Njb3BlZFxcXCI6dHJ1ZX0hLi4vLi4vLi4vLi4vLi4vbm9kZV9tb2R1bGVzL3Z1ZS1sb2FkZXIvbGliL3NlbGVjdG9yP3R5cGU9dGVtcGxhdGUmaW5kZXg9MCEuL1BlcnNvbmFsQWNjZXNzVG9rZW5zLnZ1ZVwiKSxcbiAgLyogc3R5bGVzICovXG4gIGluamVjdFN0eWxlLFxuICAvKiBzY29wZUlkICovXG4gIFwiZGF0YS12LTIyNTc3OGMyXCIsXG4gIC8qIG1vZHVsZUlkZW50aWZpZXIgKHNlcnZlciBvbmx5KSAqL1xuICBudWxsXG4pXG5Db21wb25lbnQub3B0aW9ucy5fX2ZpbGUgPSBcIi9ob21lL2h5ZHJvZ2VuL3dvcmsvc25pcGUtaXQvcmVzb3VyY2VzL2Fzc2V0cy9qcy9jb21wb25lbnRzL3Bhc3Nwb3J0L1BlcnNvbmFsQWNjZXNzVG9rZW5zLnZ1ZVwiXG5pZiAoQ29tcG9uZW50LmVzTW9kdWxlICYmIE9iamVjdC5rZXlzKENvbXBvbmVudC5lc01vZHVsZSkuc29tZShmdW5jdGlvbiAoa2V5KSB7cmV0dXJuIGtleSAhPT0gXCJkZWZhdWx0XCIgJiYga2V5LnN1YnN0cigwLCAyKSAhPT0gXCJfX1wifSkpIHtjb25zb2xlLmVycm9yKFwibmFtZWQgZXhwb3J0cyBhcmUgbm90IHN1cHBvcnRlZCBpbiAqLnZ1ZSBmaWxlcy5cIil9XG5pZiAoQ29tcG9uZW50Lm9wdGlvbnMuZnVuY3Rpb25hbCkge2NvbnNvbGUuZXJyb3IoXCJbdnVlLWxvYWRlcl0gUGVyc29uYWxBY2Nlc3NUb2tlbnMudnVlOiBmdW5jdGlvbmFsIGNvbXBvbmVudHMgYXJlIG5vdCBzdXBwb3J0ZWQgd2l0aCB0ZW1wbGF0ZXMsIHRoZXkgc2hvdWxkIHVzZSByZW5kZXIgZnVuY3Rpb25zLlwiKX1cblxuLyogaG90IHJlbG9hZCAqL1xuaWYgKG1vZHVsZS5ob3QpIHsoZnVuY3Rpb24gKCkge1xuICB2YXIgaG90QVBJID0gcmVxdWlyZShcInZ1ZS1ob3QtcmVsb2FkLWFwaVwiKVxuICBob3RBUEkuaW5zdGFsbChyZXF1aXJlKFwidnVlXCIpLCBmYWxzZSlcbiAgaWYgKCFob3RBUEkuY29tcGF0aWJsZSkgcmV0dXJuXG4gIG1vZHVsZS5ob3QuYWNjZXB0KClcbiAgaWYgKCFtb2R1bGUuaG90LmRhdGEpIHtcbiAgICBob3RBUEkuY3JlYXRlUmVjb3JkKFwiZGF0YS12LTIyNTc3OGMyXCIsIENvbXBvbmVudC5vcHRpb25zKVxuICB9IGVsc2Uge1xuICAgIGhvdEFQSS5yZWxvYWQoXCJkYXRhLXYtMjI1Nzc4YzJcIiwgQ29tcG9uZW50Lm9wdGlvbnMpXG4gIH1cbiAgbW9kdWxlLmhvdC5kaXNwb3NlKGZ1bmN0aW9uIChkYXRhKSB7XG4gICAgZGlzcG9zZWQgPSB0cnVlXG4gIH0pXG59KSgpfVxuXG5tb2R1bGUuZXhwb3J0cyA9IENvbXBvbmVudC5leHBvcnRzXG5cblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyAuL3Jlc291cmNlcy9hc3NldHMvanMvY29tcG9uZW50cy9wYXNzcG9ydC9QZXJzb25hbEFjY2Vzc1Rva2Vucy52dWVcbi8vIG1vZHVsZSBpZCA9IDI2XG4vLyBtb2R1bGUgY2h1bmtzID0gMCIsIi8vIHN0eWxlLWxvYWRlcjogQWRkcyBzb21lIGNzcyB0byB0aGUgRE9NIGJ5IGFkZGluZyBhIDxzdHlsZT4gdGFnXG5cbi8vIGxvYWQgdGhlIHN0eWxlc1xudmFyIGNvbnRlbnQgPSByZXF1aXJlKFwiISEuLi8uLi8uLi8uLi8uLi9ub2RlX21vZHVsZXMvY3NzLWxvYWRlci9pbmRleC5qcz9zb3VyY2VNYXAhLi4vLi4vLi4vLi4vLi4vbm9kZV9tb2R1bGVzL3Z1ZS1sb2FkZXIvbGliL3N0eWxlLWNvbXBpbGVyL2luZGV4LmpzP3tcXFwidnVlXFxcIjp0cnVlLFxcXCJpZFxcXCI6XFxcImRhdGEtdi0yMjU3NzhjMlxcXCIsXFxcInNjb3BlZFxcXCI6dHJ1ZSxcXFwiaGFzSW5saW5lQ29uZmlnXFxcIjp0cnVlfSEuLi8uLi8uLi8uLi8uLi9ub2RlX21vZHVsZXMvdnVlLWxvYWRlci9saWIvc2VsZWN0b3IuanM/dHlwZT1zdHlsZXMmaW5kZXg9MCEuL1BlcnNvbmFsQWNjZXNzVG9rZW5zLnZ1ZVwiKTtcbmlmKHR5cGVvZiBjb250ZW50ID09PSAnc3RyaW5nJykgY29udGVudCA9IFtbbW9kdWxlLmlkLCBjb250ZW50LCAnJ11dO1xuaWYoY29udGVudC5sb2NhbHMpIG1vZHVsZS5leHBvcnRzID0gY29udGVudC5sb2NhbHM7XG4vLyBhZGQgdGhlIHN0eWxlcyB0byB0aGUgRE9NXG52YXIgdXBkYXRlID0gcmVxdWlyZShcIiEuLi8uLi8uLi8uLi8uLi9ub2RlX21vZHVsZXMvdnVlLXN0eWxlLWxvYWRlci9saWIvYWRkU3R5bGVzQ2xpZW50LmpzXCIpKFwiZjRhMzllOThcIiwgY29udGVudCwgZmFsc2UpO1xuLy8gSG90IE1vZHVsZSBSZXBsYWNlbWVudFxuaWYobW9kdWxlLmhvdCkge1xuIC8vIFdoZW4gdGhlIHN0eWxlcyBjaGFuZ2UsIHVwZGF0ZSB0aGUgPHN0eWxlPiB0YWdzXG4gaWYoIWNvbnRlbnQubG9jYWxzKSB7XG4gICBtb2R1bGUuaG90LmFjY2VwdChcIiEhLi4vLi4vLi4vLi4vLi4vbm9kZV9tb2R1bGVzL2Nzcy1sb2FkZXIvaW5kZXguanM/c291cmNlTWFwIS4uLy4uLy4uLy4uLy4uL25vZGVfbW9kdWxlcy92dWUtbG9hZGVyL2xpYi9zdHlsZS1jb21waWxlci9pbmRleC5qcz97XFxcInZ1ZVxcXCI6dHJ1ZSxcXFwiaWRcXFwiOlxcXCJkYXRhLXYtMjI1Nzc4YzJcXFwiLFxcXCJzY29wZWRcXFwiOnRydWUsXFxcImhhc0lubGluZUNvbmZpZ1xcXCI6dHJ1ZX0hLi4vLi4vLi4vLi4vLi4vbm9kZV9tb2R1bGVzL3Z1ZS1sb2FkZXIvbGliL3NlbGVjdG9yLmpzP3R5cGU9c3R5bGVzJmluZGV4PTAhLi9QZXJzb25hbEFjY2Vzc1Rva2Vucy52dWVcIiwgZnVuY3Rpb24oKSB7XG4gICAgIHZhciBuZXdDb250ZW50ID0gcmVxdWlyZShcIiEhLi4vLi4vLi4vLi4vLi4vbm9kZV9tb2R1bGVzL2Nzcy1sb2FkZXIvaW5kZXguanM/c291cmNlTWFwIS4uLy4uLy4uLy4uLy4uL25vZGVfbW9kdWxlcy92dWUtbG9hZGVyL2xpYi9zdHlsZS1jb21waWxlci9pbmRleC5qcz97XFxcInZ1ZVxcXCI6dHJ1ZSxcXFwiaWRcXFwiOlxcXCJkYXRhLXYtMjI1Nzc4YzJcXFwiLFxcXCJzY29wZWRcXFwiOnRydWUsXFxcImhhc0lubGluZUNvbmZpZ1xcXCI6dHJ1ZX0hLi4vLi4vLi4vLi4vLi4vbm9kZV9tb2R1bGVzL3Z1ZS1sb2FkZXIvbGliL3NlbGVjdG9yLmpzP3R5cGU9c3R5bGVzJmluZGV4PTAhLi9QZXJzb25hbEFjY2Vzc1Rva2Vucy52dWVcIik7XG4gICAgIGlmKHR5cGVvZiBuZXdDb250ZW50ID09PSAnc3RyaW5nJykgbmV3Q29udGVudCA9IFtbbW9kdWxlLmlkLCBuZXdDb250ZW50LCAnJ11dO1xuICAgICB1cGRhdGUobmV3Q29udGVudCk7XG4gICB9KTtcbiB9XG4gLy8gV2hlbiB0aGUgbW9kdWxlIGlzIGRpc3Bvc2VkLCByZW1vdmUgdGhlIDxzdHlsZT4gdGFnc1xuIG1vZHVsZS5ob3QuZGlzcG9zZShmdW5jdGlvbigpIHsgdXBkYXRlKCk7IH0pO1xufVxuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIC4vbm9kZV9tb2R1bGVzL3Z1ZS1zdHlsZS1sb2FkZXIhLi9ub2RlX21vZHVsZXMvY3NzLWxvYWRlcj9zb3VyY2VNYXAhLi9ub2RlX21vZHVsZXMvdnVlLWxvYWRlci9saWIvc3R5bGUtY29tcGlsZXI/e1widnVlXCI6dHJ1ZSxcImlkXCI6XCJkYXRhLXYtMjI1Nzc4YzJcIixcInNjb3BlZFwiOnRydWUsXCJoYXNJbmxpbmVDb25maWdcIjp0cnVlfSEuL25vZGVfbW9kdWxlcy92dWUtbG9hZGVyL2xpYi9zZWxlY3Rvci5qcz90eXBlPXN0eWxlcyZpbmRleD0wIS4vcmVzb3VyY2VzL2Fzc2V0cy9qcy9jb21wb25lbnRzL3Bhc3Nwb3J0L1BlcnNvbmFsQWNjZXNzVG9rZW5zLnZ1ZVxuLy8gbW9kdWxlIGlkID0gMjdcbi8vIG1vZHVsZSBjaHVua3MgPSAwIiwiZXhwb3J0cyA9IG1vZHVsZS5leHBvcnRzID0gcmVxdWlyZShcIi4uLy4uLy4uLy4uLy4uL25vZGVfbW9kdWxlcy9jc3MtbG9hZGVyL2xpYi9jc3MtYmFzZS5qc1wiKSh0cnVlKTtcbi8vIGltcG9ydHNcblxuXG4vLyBtb2R1bGVcbmV4cG9ydHMucHVzaChbbW9kdWxlLmlkLCBcIlxcbi5hY3Rpb24tbGlua1tkYXRhLXYtMjI1Nzc4YzJdIHtcXG4gICAgY3Vyc29yOiBwb2ludGVyO1xcbn1cXG4ubS1iLW5vbmVbZGF0YS12LTIyNTc3OGMyXSB7XFxuICAgIG1hcmdpbi1ib3R0b206IDA7XFxufVxcblwiLCBcIlwiLCB7XCJ2ZXJzaW9uXCI6MyxcInNvdXJjZXNcIjpbXCIvaG9tZS9oeWRyb2dlbi93b3JrL3NuaXBlLWl0L3Jlc291cmNlcy9hc3NldHMvanMvY29tcG9uZW50cy9wYXNzcG9ydC9QZXJzb25hbEFjY2Vzc1Rva2Vucy52dWU/NTczNGY0ZTRcIl0sXCJuYW1lc1wiOltdLFwibWFwcGluZ3NcIjpcIjtBQUNBO0lBQ0EsZ0JBQUE7Q0FDQTtBQUVBO0lBQ0EsaUJBQUE7Q0FDQVwiLFwiZmlsZVwiOlwiUGVyc29uYWxBY2Nlc3NUb2tlbnMudnVlXCIsXCJzb3VyY2VzQ29udGVudFwiOltcIjxzdHlsZSBzY29wZWQ+XFxuICAgIC5hY3Rpb24tbGluayB7XFxuICAgICAgICBjdXJzb3I6IHBvaW50ZXI7XFxuICAgIH1cXG5cXG4gICAgLm0tYi1ub25lIHtcXG4gICAgICAgIG1hcmdpbi1ib3R0b206IDA7XFxuICAgIH1cXG48L3N0eWxlPlxcblxcbjx0ZW1wbGF0ZT5cXG4gICAgPGRpdj5cXG4gICAgICAgIDxkaXY+XFxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cXFwicGFuZWwgcGFuZWwtZGVmYXVsdFxcXCI+XFxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XFxcInBhbmVsLWhlYWRpbmdcXFwiPlxcbiAgICAgICAgICAgICAgICAgICAgPGRpdiBzdHlsZT1cXFwiZGlzcGxheTogZmxleDsganVzdGlmeS1jb250ZW50OiBzcGFjZS1iZXR3ZWVuOyBhbGlnbi1pdGVtczogY2VudGVyO1xcXCI+XFxuICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4+XFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFBlcnNvbmFsIEFjY2VzcyBUb2tlbnNcXG4gICAgICAgICAgICAgICAgICAgICAgICA8L3NwYW4+XFxuXFxuICAgICAgICAgICAgICAgICAgICAgICAgPGEgY2xhc3M9XFxcImFjdGlvbi1saW5rXFxcIiBAY2xpY2s9XFxcInNob3dDcmVhdGVUb2tlbkZvcm1cXFwiPlxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBDcmVhdGUgTmV3IFRva2VuXFxuICAgICAgICAgICAgICAgICAgICAgICAgPC9hPlxcbiAgICAgICAgICAgICAgICAgICAgPC9kaXY+XFxuICAgICAgICAgICAgICAgIDwvZGl2PlxcblxcbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVxcXCJwYW5lbC1ib2R5XFxcIj5cXG4gICAgICAgICAgICAgICAgICAgIDwhLS0gTm8gVG9rZW5zIE5vdGljZSAtLT5cXG4gICAgICAgICAgICAgICAgICAgIDxwIGNsYXNzPVxcXCJtLWItbm9uZVxcXCIgdi1pZj1cXFwidG9rZW5zLmxlbmd0aCA9PT0gMFxcXCI+XFxuICAgICAgICAgICAgICAgICAgICAgICAgWW91IGhhdmUgbm90IGNyZWF0ZWQgYW55IHBlcnNvbmFsIGFjY2VzcyB0b2tlbnMuXFxuICAgICAgICAgICAgICAgICAgICA8L3A+XFxuXFxuICAgICAgICAgICAgICAgICAgICA8IS0tIFBlcnNvbmFsIEFjY2VzcyBUb2tlbnMgLS0+XFxuICAgICAgICAgICAgICAgICAgICA8dGFibGUgY2xhc3M9XFxcInRhYmxlIHRhYmxlLWJvcmRlcmxlc3MgbS1iLW5vbmVcXFwiIHYtaWY9XFxcInRva2Vucy5sZW5ndGggPiAwXFxcIj5cXG4gICAgICAgICAgICAgICAgICAgICAgICA8dGhlYWQ+XFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDx0cj5cXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDx0aD5OYW1lPC90aD5cXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDx0aD48L3RoPlxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3RyPlxcbiAgICAgICAgICAgICAgICAgICAgICAgIDwvdGhlYWQ+XFxuXFxuICAgICAgICAgICAgICAgICAgICAgICAgPHRib2R5PlxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8dHIgdi1mb3I9XFxcInRva2VuIGluIHRva2Vuc1xcXCI+XFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8IS0tIENsaWVudCBOYW1lIC0tPlxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHRkIHN0eWxlPVxcXCJ2ZXJ0aWNhbC1hbGlnbjogbWlkZGxlO1xcXCI+XFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAge3sgdG9rZW4ubmFtZSB9fVxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC90ZD5cXG5cXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwhLS0gRGVsZXRlIEJ1dHRvbiAtLT5cXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDx0ZCBzdHlsZT1cXFwidmVydGljYWwtYWxpZ246IG1pZGRsZTtcXFwiPlxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxhIGNsYXNzPVxcXCJhY3Rpb24tbGluayB0ZXh0LWRhbmdlclxcXCIgQGNsaWNrPVxcXCJyZXZva2UodG9rZW4pXFxcIj5cXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRGVsZXRlXFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9hPlxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC90ZD5cXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC90cj5cXG4gICAgICAgICAgICAgICAgICAgICAgICA8L3Rib2R5PlxcbiAgICAgICAgICAgICAgICAgICAgPC90YWJsZT5cXG4gICAgICAgICAgICAgICAgPC9kaXY+XFxuICAgICAgICAgICAgPC9kaXY+XFxuICAgICAgICA8L2Rpdj5cXG5cXG4gICAgICAgIDwhLS0gQ3JlYXRlIFRva2VuIE1vZGFsIC0tPlxcbiAgICAgICAgPGRpdiBjbGFzcz1cXFwibW9kYWwgZmFkZVxcXCIgaWQ9XFxcIm1vZGFsLWNyZWF0ZS10b2tlblxcXCIgdGFiaW5kZXg9XFxcIi0xXFxcIiByb2xlPVxcXCJkaWFsb2dcXFwiPlxcbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XFxcIm1vZGFsLWRpYWxvZ1xcXCI+XFxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XFxcIm1vZGFsLWNvbnRlbnRcXFwiPlxcbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cXFwibW9kYWwtaGVhZGVyXFxcIj5cXG4gICAgICAgICAgICAgICAgICAgICAgICA8YnV0dG9uIHR5cGU9XFxcImJ1dHRvbiBcXFwiIGNsYXNzPVxcXCJjbG9zZVxcXCIgZGF0YS1kaXNtaXNzPVxcXCJtb2RhbFxcXCIgYXJpYS1oaWRkZW49XFxcInRydWVcXFwiPiZ0aW1lczs8L2J1dHRvbj5cXG5cXG4gICAgICAgICAgICAgICAgICAgICAgICA8aDQgY2xhc3M9XFxcIm1vZGFsLXRpdGxlXFxcIj5cXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgQ3JlYXRlIFRva2VuXFxuICAgICAgICAgICAgICAgICAgICAgICAgPC9oND5cXG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxcblxcbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cXFwibW9kYWwtYm9keVxcXCI+XFxuICAgICAgICAgICAgICAgICAgICAgICAgPCEtLSBGb3JtIEVycm9ycyAtLT5cXG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVxcXCJhbGVydCBhbGVydC1kYW5nZXJcXFwiIHYtaWY9XFxcImZvcm0uZXJyb3JzLmxlbmd0aCA+IDBcXFwiPlxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8cD48c3Ryb25nPldob29wcyE8L3N0cm9uZz4gU29tZXRoaW5nIHdlbnQgd3JvbmchPC9wPlxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8YnI+XFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDx1bD5cXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxsaSB2LWZvcj1cXFwiZXJyb3IgaW4gZm9ybS5lcnJvcnNcXFwiPlxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHt7IGVycm9yIH19XFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2xpPlxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3VsPlxcbiAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxcblxcbiAgICAgICAgICAgICAgICAgICAgICAgIDwhLS0gQ3JlYXRlIFRva2VuIEZvcm0gLS0+XFxuICAgICAgICAgICAgICAgICAgICAgICAgPGZvcm0gY2xhc3M9XFxcImZvcm0taG9yaXpvbnRhbFxcXCIgcm9sZT1cXFwiZm9ybVxcXCIgQHN1Ym1pdC5wcmV2ZW50PVxcXCJzdG9yZVxcXCI+XFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwhLS0gTmFtZSAtLT5cXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cXFwiZm9ybS1ncm91cFxcXCI+XFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bGFiZWwgY2xhc3M9XFxcImNvbC1tZC00IGNvbnRyb2wtbGFiZWxcXFwiPk5hbWU8L2xhYmVsPlxcblxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cXFwiY29sLW1kLTZcXFwiPlxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpbnB1dCBpZD1cXFwiY3JlYXRlLXRva2VuLW5hbWVcXFwiIHR5cGU9XFxcInRleHRcXFwiIGNsYXNzPVxcXCJmb3JtLWNvbnRyb2xcXFwiIG5hbWU9XFxcIm5hbWVcXFwiIHYtbW9kZWw9XFxcImZvcm0ubmFtZVxcXCI+XFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XFxuXFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwhLS0gU2NvcGVzIC0tPlxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVxcXCJmb3JtLWdyb3VwXFxcIiB2LWlmPVxcXCJzY29wZXMubGVuZ3RoID4gMFxcXCI+XFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bGFiZWwgY2xhc3M9XFxcImNvbC1tZC00IGNvbnRyb2wtbGFiZWxcXFwiPlNjb3BlczwvbGFiZWw+XFxuXFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVxcXCJjb2wtbWQtNlxcXCI+XFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiB2LWZvcj1cXFwic2NvcGUgaW4gc2NvcGVzXFxcIj5cXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cXFwiY2hlY2tib3hcXFwiPlxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGxhYmVsPlxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpbnB1dCB0eXBlPVxcXCJjaGVja2JveFxcXCJcXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQGNsaWNrPVxcXCJ0b2dnbGVTY29wZShzY29wZS5pZClcXFwiXFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDpjaGVja2VkPVxcXCJzY29wZUlzQXNzaWduZWQoc2NvcGUuaWQpXFxcIj5cXG5cXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAge3sgc2NvcGUuaWQgfX1cXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvbGFiZWw+XFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxcbiAgICAgICAgICAgICAgICAgICAgICAgIDwvZm9ybT5cXG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxcblxcbiAgICAgICAgICAgICAgICAgICAgPCEtLSBNb2RhbCBBY3Rpb25zIC0tPlxcbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cXFwibW9kYWwtZm9vdGVyXFxcIj5cXG4gICAgICAgICAgICAgICAgICAgICAgICA8YnV0dG9uIHR5cGU9XFxcImJ1dHRvblxcXCIgY2xhc3M9XFxcImJ0biBidG4tZGVmYXVsdFxcXCIgZGF0YS1kaXNtaXNzPVxcXCJtb2RhbFxcXCI+Q2xvc2U8L2J1dHRvbj5cXG5cXG4gICAgICAgICAgICAgICAgICAgICAgICA8YnV0dG9uIHR5cGU9XFxcImJ1dHRvblxcXCIgY2xhc3M9XFxcImJ0biBidG4tcHJpbWFyeVxcXCIgQGNsaWNrPVxcXCJzdG9yZVxcXCI+XFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIENyZWF0ZVxcbiAgICAgICAgICAgICAgICAgICAgICAgIDwvYnV0dG9uPlxcbiAgICAgICAgICAgICAgICAgICAgPC9kaXY+XFxuICAgICAgICAgICAgICAgIDwvZGl2PlxcbiAgICAgICAgICAgIDwvZGl2PlxcbiAgICAgICAgPC9kaXY+XFxuXFxuICAgICAgICA8IS0tIEFjY2VzcyBUb2tlbiBNb2RhbCAtLT5cXG4gICAgICAgIDxkaXYgY2xhc3M9XFxcIm1vZGFsIGZhZGVcXFwiIGlkPVxcXCJtb2RhbC1hY2Nlc3MtdG9rZW5cXFwiIHRhYmluZGV4PVxcXCItMVxcXCIgcm9sZT1cXFwiZGlhbG9nXFxcIj5cXG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVxcXCJtb2RhbC1kaWFsb2dcXFwiPlxcbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVxcXCJtb2RhbC1jb250ZW50XFxcIj5cXG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XFxcIm1vZGFsLWhlYWRlclxcXCI+XFxuICAgICAgICAgICAgICAgICAgICAgICAgPGJ1dHRvbiB0eXBlPVxcXCJidXR0b24gXFxcIiBjbGFzcz1cXFwiY2xvc2VcXFwiIGRhdGEtZGlzbWlzcz1cXFwibW9kYWxcXFwiIGFyaWEtaGlkZGVuPVxcXCJ0cnVlXFxcIj4mdGltZXM7PC9idXR0b24+XFxuXFxuICAgICAgICAgICAgICAgICAgICAgICAgPGg0IGNsYXNzPVxcXCJtb2RhbC10aXRsZVxcXCI+XFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFBlcnNvbmFsIEFjY2VzcyBUb2tlblxcbiAgICAgICAgICAgICAgICAgICAgICAgIDwvaDQ+XFxuICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cXG5cXG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XFxcIm1vZGFsLWJvZHlcXFwiPlxcbiAgICAgICAgICAgICAgICAgICAgICAgIDxwPlxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBIZXJlIGlzIHlvdXIgbmV3IHBlcnNvbmFsIGFjY2VzcyB0b2tlbi4gVGhpcyBpcyB0aGUgb25seSB0aW1lIGl0IHdpbGwgYmUgc2hvd24gc28gZG9uJ3QgbG9zZSBpdCFcXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgWW91IG1heSBub3cgdXNlIHRoaXMgdG9rZW4gdG8gbWFrZSBBUEkgcmVxdWVzdHMuXFxuICAgICAgICAgICAgICAgICAgICAgICAgPC9wPlxcblxcbiAgICAgICAgICAgICAgICAgICAgICAgIDxwcmU+PGNvZGU+e3sgYWNjZXNzVG9rZW4gfX08L2NvZGU+PC9wcmU+XFxuICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cXG5cXG4gICAgICAgICAgICAgICAgICAgIDwhLS0gTW9kYWwgQWN0aW9ucyAtLT5cXG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XFxcIm1vZGFsLWZvb3RlclxcXCI+XFxuICAgICAgICAgICAgICAgICAgICAgICAgPGJ1dHRvbiB0eXBlPVxcXCJidXR0b25cXFwiIGNsYXNzPVxcXCJidG4gYnRuLWRlZmF1bHRcXFwiIGRhdGEtZGlzbWlzcz1cXFwibW9kYWxcXFwiPkNsb3NlPC9idXR0b24+XFxuICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cXG4gICAgICAgICAgICAgICAgPC9kaXY+XFxuICAgICAgICAgICAgPC9kaXY+XFxuICAgICAgICA8L2Rpdj5cXG4gICAgPC9kaXY+XFxuPC90ZW1wbGF0ZT5cXG5cXG48c2NyaXB0PlxcbiAgICBleHBvcnQgZGVmYXVsdCB7XFxuICAgICAgICAvKlxcbiAgICAgICAgICogVGhlIGNvbXBvbmVudCdzIGRhdGEuXFxuICAgICAgICAgKi9cXG4gICAgICAgIGRhdGEoKSB7XFxuICAgICAgICAgICAgcmV0dXJuIHtcXG4gICAgICAgICAgICAgICAgYWNjZXNzVG9rZW46IG51bGwsXFxuXFxuICAgICAgICAgICAgICAgIHRva2VuczogW10sXFxuICAgICAgICAgICAgICAgIHNjb3BlczogW10sXFxuXFxuICAgICAgICAgICAgICAgIGZvcm06IHtcXG4gICAgICAgICAgICAgICAgICAgIG5hbWU6ICcnLFxcbiAgICAgICAgICAgICAgICAgICAgc2NvcGVzOiBbXSxcXG4gICAgICAgICAgICAgICAgICAgIGVycm9yczogW11cXG4gICAgICAgICAgICAgICAgfVxcbiAgICAgICAgICAgIH07XFxuICAgICAgICB9LFxcblxcbiAgICAgICAgLyoqXFxuICAgICAgICAgKiBQcmVwYXJlIHRoZSBjb21wb25lbnQgKFZ1ZSAxLngpLlxcbiAgICAgICAgICovXFxuICAgICAgICByZWFkeSgpIHtcXG4gICAgICAgICAgICB0aGlzLnByZXBhcmVDb21wb25lbnQoKTtcXG4gICAgICAgIH0sXFxuXFxuICAgICAgICAvKipcXG4gICAgICAgICAqIFByZXBhcmUgdGhlIGNvbXBvbmVudCAoVnVlIDIueCkuXFxuICAgICAgICAgKi9cXG4gICAgICAgIG1vdW50ZWQoKSB7XFxuICAgICAgICAgICAgdGhpcy5wcmVwYXJlQ29tcG9uZW50KCk7XFxuICAgICAgICB9LFxcblxcbiAgICAgICAgbWV0aG9kczoge1xcbiAgICAgICAgICAgIC8qKlxcbiAgICAgICAgICAgICAqIFByZXBhcmUgdGhlIGNvbXBvbmVudC5cXG4gICAgICAgICAgICAgKi9cXG4gICAgICAgICAgICBwcmVwYXJlQ29tcG9uZW50KCkge1xcbiAgICAgICAgICAgICAgICB0aGlzLmdldFRva2VucygpO1xcbiAgICAgICAgICAgICAgICB0aGlzLmdldFNjb3BlcygpO1xcblxcbiAgICAgICAgICAgICAgICAkKCcjbW9kYWwtY3JlYXRlLXRva2VuJykub24oJ3Nob3duLmJzLm1vZGFsJywgKCkgPT4ge1xcbiAgICAgICAgICAgICAgICAgICAgJCgnI2NyZWF0ZS10b2tlbi1uYW1lJykuZm9jdXMoKTtcXG4gICAgICAgICAgICAgICAgfSk7XFxuICAgICAgICAgICAgfSxcXG5cXG4gICAgICAgICAgICAvKipcXG4gICAgICAgICAgICAgKiBHZXQgYWxsIG9mIHRoZSBwZXJzb25hbCBhY2Nlc3MgdG9rZW5zIGZvciB0aGUgdXNlci5cXG4gICAgICAgICAgICAgKi9cXG4gICAgICAgICAgICBnZXRUb2tlbnMoKSB7XFxuICAgICAgICAgICAgICAgIHRoaXMuJGh0dHAuZ2V0KCcvb2F1dGgvcGVyc29uYWwtYWNjZXNzLXRva2VucycpXFxuICAgICAgICAgICAgICAgICAgICAgICAgLnRoZW4ocmVzcG9uc2UgPT4ge1xcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnRva2VucyA9IHJlc3BvbnNlLmRhdGE7XFxuICAgICAgICAgICAgICAgICAgICAgICAgfSk7XFxuICAgICAgICAgICAgfSxcXG5cXG4gICAgICAgICAgICAvKipcXG4gICAgICAgICAgICAgKiBHZXQgYWxsIG9mIHRoZSBhdmFpbGFibGUgc2NvcGVzLlxcbiAgICAgICAgICAgICAqL1xcbiAgICAgICAgICAgIGdldFNjb3BlcygpIHtcXG4gICAgICAgICAgICAgICAgdGhpcy4kaHR0cC5nZXQoJy9vYXV0aC9zY29wZXMnKVxcbiAgICAgICAgICAgICAgICAgICAgICAgIC50aGVuKHJlc3BvbnNlID0+IHtcXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zY29wZXMgPSByZXNwb25zZS5kYXRhO1xcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xcbiAgICAgICAgICAgIH0sXFxuXFxuICAgICAgICAgICAgLyoqXFxuICAgICAgICAgICAgICogU2hvdyB0aGUgZm9ybSBmb3IgY3JlYXRpbmcgbmV3IHRva2Vucy5cXG4gICAgICAgICAgICAgKi9cXG4gICAgICAgICAgICBzaG93Q3JlYXRlVG9rZW5Gb3JtKCkge1xcbiAgICAgICAgICAgICAgICAkKCcjbW9kYWwtY3JlYXRlLXRva2VuJykubW9kYWwoJ3Nob3cnKTtcXG4gICAgICAgICAgICB9LFxcblxcbiAgICAgICAgICAgIC8qKlxcbiAgICAgICAgICAgICAqIENyZWF0ZSBhIG5ldyBwZXJzb25hbCBhY2Nlc3MgdG9rZW4uXFxuICAgICAgICAgICAgICovXFxuICAgICAgICAgICAgc3RvcmUoKSB7XFxuICAgICAgICAgICAgICAgIHRoaXMuYWNjZXNzVG9rZW4gPSBudWxsO1xcblxcbiAgICAgICAgICAgICAgICB0aGlzLmZvcm0uZXJyb3JzID0gW107XFxuXFxuICAgICAgICAgICAgICAgIHRoaXMuJGh0dHAucG9zdCgnL29hdXRoL3BlcnNvbmFsLWFjY2Vzcy10b2tlbnMnLCB0aGlzLmZvcm0pXFxuICAgICAgICAgICAgICAgICAgICAgICAgLnRoZW4ocmVzcG9uc2UgPT4ge1xcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmZvcm0ubmFtZSA9ICcnO1xcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmZvcm0uc2NvcGVzID0gW107XFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuZm9ybS5lcnJvcnMgPSBbXTtcXG5cXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy50b2tlbnMucHVzaChyZXNwb25zZS5kYXRhLnRva2VuKTtcXG5cXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zaG93QWNjZXNzVG9rZW4ocmVzcG9uc2UuZGF0YS5hY2Nlc3NUb2tlbik7XFxuICAgICAgICAgICAgICAgICAgICAgICAgfSlcXG4gICAgICAgICAgICAgICAgICAgICAgICAuY2F0Y2gocmVzcG9uc2UgPT4ge1xcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAodHlwZW9mIHJlc3BvbnNlLmRhdGEgPT09ICdvYmplY3QnKSB7XFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmZvcm0uZXJyb3JzID0gXy5mbGF0dGVuKF8udG9BcnJheShyZXNwb25zZS5kYXRhKSk7XFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuZGlyKHRoaXMuZm9ybSk7XFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmZvcm0uZXJyb3JzID0gWydTb21ldGhpbmcgd2VudCB3cm9uZy4gUGxlYXNlIHRyeSBhZ2Fpbi4nXTtcXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xcbiAgICAgICAgICAgIH0sXFxuXFxuICAgICAgICAgICAgLyoqXFxuICAgICAgICAgICAgICogVG9nZ2xlIHRoZSBnaXZlbiBzY29wZSBpbiB0aGUgbGlzdCBvZiBhc3NpZ25lZCBzY29wZXMuXFxuICAgICAgICAgICAgICovXFxuICAgICAgICAgICAgdG9nZ2xlU2NvcGUoc2NvcGUpIHtcXG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuc2NvcGVJc0Fzc2lnbmVkKHNjb3BlKSkge1xcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5mb3JtLnNjb3BlcyA9IF8ucmVqZWN0KHRoaXMuZm9ybS5zY29wZXMsIHMgPT4gcyA9PSBzY29wZSk7XFxuICAgICAgICAgICAgICAgIH0gZWxzZSB7XFxuICAgICAgICAgICAgICAgICAgICB0aGlzLmZvcm0uc2NvcGVzLnB1c2goc2NvcGUpO1xcbiAgICAgICAgICAgICAgICB9XFxuICAgICAgICAgICAgfSxcXG5cXG4gICAgICAgICAgICAvKipcXG4gICAgICAgICAgICAgKiBEZXRlcm1pbmUgaWYgdGhlIGdpdmVuIHNjb3BlIGhhcyBiZWVuIGFzc2lnbmVkIHRvIHRoZSB0b2tlbi5cXG4gICAgICAgICAgICAgKi9cXG4gICAgICAgICAgICBzY29wZUlzQXNzaWduZWQoc2NvcGUpIHtcXG4gICAgICAgICAgICAgICAgcmV0dXJuIF8uaW5kZXhPZih0aGlzLmZvcm0uc2NvcGVzLCBzY29wZSkgPj0gMDtcXG4gICAgICAgICAgICB9LFxcblxcbiAgICAgICAgICAgIC8qKlxcbiAgICAgICAgICAgICAqIFNob3cgdGhlIGdpdmVuIGFjY2VzcyB0b2tlbiB0byB0aGUgdXNlci5cXG4gICAgICAgICAgICAgKi9cXG4gICAgICAgICAgICBzaG93QWNjZXNzVG9rZW4oYWNjZXNzVG9rZW4pIHtcXG4gICAgICAgICAgICAgICAgJCgnI21vZGFsLWNyZWF0ZS10b2tlbicpLm1vZGFsKCdoaWRlJyk7XFxuXFxuICAgICAgICAgICAgICAgIHRoaXMuYWNjZXNzVG9rZW4gPSBhY2Nlc3NUb2tlbjtcXG5cXG4gICAgICAgICAgICAgICAgJCgnI21vZGFsLWFjY2Vzcy10b2tlbicpLm1vZGFsKCdzaG93Jyk7XFxuICAgICAgICAgICAgfSxcXG5cXG4gICAgICAgICAgICAvKipcXG4gICAgICAgICAgICAgKiBSZXZva2UgdGhlIGdpdmVuIHRva2VuLlxcbiAgICAgICAgICAgICAqL1xcbiAgICAgICAgICAgIHJldm9rZSh0b2tlbikge1xcbiAgICAgICAgICAgICAgICB0aGlzLiRodHRwLmRlbGV0ZSgnL29hdXRoL3BlcnNvbmFsLWFjY2Vzcy10b2tlbnMvJyArIHRva2VuLmlkKVxcbiAgICAgICAgICAgICAgICAgICAgICAgIC50aGVuKHJlc3BvbnNlID0+IHtcXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5nZXRUb2tlbnMoKTtcXG4gICAgICAgICAgICAgICAgICAgICAgICB9KTtcXG4gICAgICAgICAgICB9XFxuICAgICAgICB9XFxuICAgIH1cXG48L3NjcmlwdD5cXG5cIl0sXCJzb3VyY2VSb290XCI6XCJcIn1dKTtcblxuLy8gZXhwb3J0c1xuXG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gLi9ub2RlX21vZHVsZXMvY3NzLWxvYWRlcj9zb3VyY2VNYXAhLi9ub2RlX21vZHVsZXMvdnVlLWxvYWRlci9saWIvc3R5bGUtY29tcGlsZXI/e1widnVlXCI6dHJ1ZSxcImlkXCI6XCJkYXRhLXYtMjI1Nzc4YzJcIixcInNjb3BlZFwiOnRydWUsXCJoYXNJbmxpbmVDb25maWdcIjp0cnVlfSEuL25vZGVfbW9kdWxlcy92dWUtbG9hZGVyL2xpYi9zZWxlY3Rvci5qcz90eXBlPXN0eWxlcyZpbmRleD0wIS4vcmVzb3VyY2VzL2Fzc2V0cy9qcy9jb21wb25lbnRzL3Bhc3Nwb3J0L1BlcnNvbmFsQWNjZXNzVG9rZW5zLnZ1ZVxuLy8gbW9kdWxlIGlkID0gMjhcbi8vIG1vZHVsZSBjaHVua3MgPSAwIiwiPHN0eWxlIHNjb3BlZD5cbiAgICAuYWN0aW9uLWxpbmsge1xuICAgICAgICBjdXJzb3I6IHBvaW50ZXI7XG4gICAgfVxuXG4gICAgLm0tYi1ub25lIHtcbiAgICAgICAgbWFyZ2luLWJvdHRvbTogMDtcbiAgICB9XG48L3N0eWxlPlxuXG48dGVtcGxhdGU+XG4gICAgPGRpdj5cbiAgICAgICAgPGRpdj5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJwYW5lbCBwYW5lbC1kZWZhdWx0XCI+XG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInBhbmVsLWhlYWRpbmdcIj5cbiAgICAgICAgICAgICAgICAgICAgPGRpdiBzdHlsZT1cImRpc3BsYXk6IGZsZXg7IGp1c3RpZnktY29udGVudDogc3BhY2UtYmV0d2VlbjsgYWxpZ24taXRlbXM6IGNlbnRlcjtcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFBlcnNvbmFsIEFjY2VzcyBUb2tlbnNcbiAgICAgICAgICAgICAgICAgICAgICAgIDwvc3Bhbj5cblxuICAgICAgICAgICAgICAgICAgICAgICAgPGEgY2xhc3M9XCJhY3Rpb24tbGlua1wiIEBjbGljaz1cInNob3dDcmVhdGVUb2tlbkZvcm1cIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBDcmVhdGUgTmV3IFRva2VuXG4gICAgICAgICAgICAgICAgICAgICAgICA8L2E+XG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuXG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInBhbmVsLWJvZHlcIj5cbiAgICAgICAgICAgICAgICAgICAgPCEtLSBObyBUb2tlbnMgTm90aWNlIC0tPlxuICAgICAgICAgICAgICAgICAgICA8cCBjbGFzcz1cIm0tYi1ub25lXCIgdi1pZj1cInRva2Vucy5sZW5ndGggPT09IDBcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIFlvdSBoYXZlIG5vdCBjcmVhdGVkIGFueSBwZXJzb25hbCBhY2Nlc3MgdG9rZW5zLlxuICAgICAgICAgICAgICAgICAgICA8L3A+XG5cbiAgICAgICAgICAgICAgICAgICAgPCEtLSBQZXJzb25hbCBBY2Nlc3MgVG9rZW5zIC0tPlxuICAgICAgICAgICAgICAgICAgICA8dGFibGUgY2xhc3M9XCJ0YWJsZSB0YWJsZS1ib3JkZXJsZXNzIG0tYi1ub25lXCIgdi1pZj1cInRva2Vucy5sZW5ndGggPiAwXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8dGhlYWQ+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPHRyPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8dGg+TmFtZTwvdGg+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDx0aD48L3RoPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvdHI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8L3RoZWFkPlxuXG4gICAgICAgICAgICAgICAgICAgICAgICA8dGJvZHk+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPHRyIHYtZm9yPVwidG9rZW4gaW4gdG9rZW5zXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwhLS0gQ2xpZW50IE5hbWUgLS0+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDx0ZCBzdHlsZT1cInZlcnRpY2FsLWFsaWduOiBtaWRkbGU7XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7eyB0b2tlbi5uYW1lIH19XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvdGQ+XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPCEtLSBEZWxldGUgQnV0dG9uIC0tPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8dGQgc3R5bGU9XCJ2ZXJ0aWNhbC1hbGlnbjogbWlkZGxlO1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGEgY2xhc3M9XCJhY3Rpb24tbGluayB0ZXh0LWRhbmdlclwiIEBjbGljaz1cInJldm9rZSh0b2tlbilcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEZWxldGVcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvYT5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC90ZD5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3RyPlxuICAgICAgICAgICAgICAgICAgICAgICAgPC90Ym9keT5cbiAgICAgICAgICAgICAgICAgICAgPC90YWJsZT5cbiAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICA8L2Rpdj5cblxuICAgICAgICA8IS0tIENyZWF0ZSBUb2tlbiBNb2RhbCAtLT5cbiAgICAgICAgPGRpdiBjbGFzcz1cIm1vZGFsIGZhZGVcIiBpZD1cIm1vZGFsLWNyZWF0ZS10b2tlblwiIHRhYmluZGV4PVwiLTFcIiByb2xlPVwiZGlhbG9nXCI+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwibW9kYWwtZGlhbG9nXCI+XG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cIm1vZGFsLWNvbnRlbnRcIj5cbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cIm1vZGFsLWhlYWRlclwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPGJ1dHRvbiB0eXBlPVwiYnV0dG9uIFwiIGNsYXNzPVwiY2xvc2VcIiBkYXRhLWRpc21pc3M9XCJtb2RhbFwiIGFyaWEtaGlkZGVuPVwidHJ1ZVwiPiZ0aW1lczs8L2J1dHRvbj5cblxuICAgICAgICAgICAgICAgICAgICAgICAgPGg0IGNsYXNzPVwibW9kYWwtdGl0bGVcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBDcmVhdGUgVG9rZW5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvaDQ+XG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuXG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJtb2RhbC1ib2R5XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8IS0tIEZvcm0gRXJyb3JzIC0tPlxuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImFsZXJ0IGFsZXJ0LWRhbmdlclwiIHYtaWY9XCJmb3JtLmVycm9ycy5sZW5ndGggPiAwXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPHA+PHN0cm9uZz5XaG9vcHMhPC9zdHJvbmc+IFNvbWV0aGluZyB3ZW50IHdyb25nITwvcD5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8YnI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPHVsPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bGkgdi1mb3I9XCJlcnJvciBpbiBmb3JtLmVycm9yc1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAge3sgZXJyb3IgfX1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9saT5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3VsPlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwhLS0gQ3JlYXRlIFRva2VuIEZvcm0gLS0+XG4gICAgICAgICAgICAgICAgICAgICAgICA8Zm9ybSBjbGFzcz1cImZvcm0taG9yaXpvbnRhbFwiIHJvbGU9XCJmb3JtXCIgQHN1Ym1pdC5wcmV2ZW50PVwic3RvcmVcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8IS0tIE5hbWUgLS0+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImZvcm0tZ3JvdXBcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGxhYmVsIGNsYXNzPVwiY29sLW1kLTQgY29udHJvbC1sYWJlbFwiPk5hbWU8L2xhYmVsPlxuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJjb2wtbWQtNlwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGlucHV0IGlkPVwiY3JlYXRlLXRva2VuLW5hbWVcIiB0eXBlPVwidGV4dFwiIGNsYXNzPVwiZm9ybS1jb250cm9sXCIgbmFtZT1cIm5hbWVcIiB2LW1vZGVsPVwiZm9ybS5uYW1lXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPCEtLSBTY29wZXMgLS0+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImZvcm0tZ3JvdXBcIiB2LWlmPVwic2NvcGVzLmxlbmd0aCA+IDBcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGxhYmVsIGNsYXNzPVwiY29sLW1kLTQgY29udHJvbC1sYWJlbFwiPlNjb3BlczwvbGFiZWw+XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImNvbC1tZC02XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IHYtZm9yPVwic2NvcGUgaW4gc2NvcGVzXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImNoZWNrYm94XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxsYWJlbD5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpbnB1dCB0eXBlPVwiY2hlY2tib3hcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEBjbGljaz1cInRvZ2dsZVNjb3BlKHNjb3BlLmlkKVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgOmNoZWNrZWQ9XCJzY29wZUlzQXNzaWduZWQoc2NvcGUuaWQpXCI+XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7eyBzY29wZS5pZCB9fVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2xhYmVsPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9mb3JtPlxuICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cblxuICAgICAgICAgICAgICAgICAgICA8IS0tIE1vZGFsIEFjdGlvbnMgLS0+XG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJtb2RhbC1mb290ZXJcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxidXR0b24gdHlwZT1cImJ1dHRvblwiIGNsYXNzPVwiYnRuIGJ0bi1kZWZhdWx0XCIgZGF0YS1kaXNtaXNzPVwibW9kYWxcIj5DbG9zZTwvYnV0dG9uPlxuXG4gICAgICAgICAgICAgICAgICAgICAgICA8YnV0dG9uIHR5cGU9XCJidXR0b25cIiBjbGFzcz1cImJ0biBidG4tcHJpbWFyeVwiIEBjbGljaz1cInN0b3JlXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgQ3JlYXRlXG4gICAgICAgICAgICAgICAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgPCEtLSBBY2Nlc3MgVG9rZW4gTW9kYWwgLS0+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJtb2RhbCBmYWRlXCIgaWQ9XCJtb2RhbC1hY2Nlc3MtdG9rZW5cIiB0YWJpbmRleD1cIi0xXCIgcm9sZT1cImRpYWxvZ1wiPlxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cIm1vZGFsLWRpYWxvZ1wiPlxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJtb2RhbC1jb250ZW50XCI+XG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJtb2RhbC1oZWFkZXJcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxidXR0b24gdHlwZT1cImJ1dHRvbiBcIiBjbGFzcz1cImNsb3NlXCIgZGF0YS1kaXNtaXNzPVwibW9kYWxcIiBhcmlhLWhpZGRlbj1cInRydWVcIj4mdGltZXM7PC9idXR0b24+XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxoNCBjbGFzcz1cIm1vZGFsLXRpdGxlXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgUGVyc29uYWwgQWNjZXNzIFRva2VuXG4gICAgICAgICAgICAgICAgICAgICAgICA8L2g0PlxuICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cblxuICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwibW9kYWwtYm9keVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPHA+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgSGVyZSBpcyB5b3VyIG5ldyBwZXJzb25hbCBhY2Nlc3MgdG9rZW4uIFRoaXMgaXMgdGhlIG9ubHkgdGltZSBpdCB3aWxsIGJlIHNob3duIHNvIGRvbid0IGxvc2UgaXQhXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgWW91IG1heSBub3cgdXNlIHRoaXMgdG9rZW4gdG8gbWFrZSBBUEkgcmVxdWVzdHMuXG4gICAgICAgICAgICAgICAgICAgICAgICA8L3A+XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxwcmU+PGNvZGU+e3sgYWNjZXNzVG9rZW4gfX08L2NvZGU+PC9wcmU+XG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuXG4gICAgICAgICAgICAgICAgICAgIDwhLS0gTW9kYWwgQWN0aW9ucyAtLT5cbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cIm1vZGFsLWZvb3RlclwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPGJ1dHRvbiB0eXBlPVwiYnV0dG9uXCIgY2xhc3M9XCJidG4gYnRuLWRlZmF1bHRcIiBkYXRhLWRpc21pc3M9XCJtb2RhbFwiPkNsb3NlPC9idXR0b24+XG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgIDwvZGl2PlxuICAgIDwvZGl2PlxuPC90ZW1wbGF0ZT5cblxuPHNjcmlwdD5cbiAgICBleHBvcnQgZGVmYXVsdCB7XG4gICAgICAgIC8qXG4gICAgICAgICAqIFRoZSBjb21wb25lbnQncyBkYXRhLlxuICAgICAgICAgKi9cbiAgICAgICAgZGF0YSgpIHtcbiAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgICAgYWNjZXNzVG9rZW46IG51bGwsXG5cbiAgICAgICAgICAgICAgICB0b2tlbnM6IFtdLFxuICAgICAgICAgICAgICAgIHNjb3BlczogW10sXG5cbiAgICAgICAgICAgICAgICBmb3JtOiB7XG4gICAgICAgICAgICAgICAgICAgIG5hbWU6ICcnLFxuICAgICAgICAgICAgICAgICAgICBzY29wZXM6IFtdLFxuICAgICAgICAgICAgICAgICAgICBlcnJvcnM6IFtdXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfTtcbiAgICAgICAgfSxcblxuICAgICAgICAvKipcbiAgICAgICAgICogUHJlcGFyZSB0aGUgY29tcG9uZW50IChWdWUgMS54KS5cbiAgICAgICAgICovXG4gICAgICAgIHJlYWR5KCkge1xuICAgICAgICAgICAgdGhpcy5wcmVwYXJlQ29tcG9uZW50KCk7XG4gICAgICAgIH0sXG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIFByZXBhcmUgdGhlIGNvbXBvbmVudCAoVnVlIDIueCkuXG4gICAgICAgICAqL1xuICAgICAgICBtb3VudGVkKCkge1xuICAgICAgICAgICAgdGhpcy5wcmVwYXJlQ29tcG9uZW50KCk7XG4gICAgICAgIH0sXG5cbiAgICAgICAgbWV0aG9kczoge1xuICAgICAgICAgICAgLyoqXG4gICAgICAgICAgICAgKiBQcmVwYXJlIHRoZSBjb21wb25lbnQuXG4gICAgICAgICAgICAgKi9cbiAgICAgICAgICAgIHByZXBhcmVDb21wb25lbnQoKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5nZXRUb2tlbnMoKTtcbiAgICAgICAgICAgICAgICB0aGlzLmdldFNjb3BlcygpO1xuXG4gICAgICAgICAgICAgICAgJCgnI21vZGFsLWNyZWF0ZS10b2tlbicpLm9uKCdzaG93bi5icy5tb2RhbCcsICgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgJCgnI2NyZWF0ZS10b2tlbi1uYW1lJykuZm9jdXMoKTtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH0sXG5cbiAgICAgICAgICAgIC8qKlxuICAgICAgICAgICAgICogR2V0IGFsbCBvZiB0aGUgcGVyc29uYWwgYWNjZXNzIHRva2VucyBmb3IgdGhlIHVzZXIuXG4gICAgICAgICAgICAgKi9cbiAgICAgICAgICAgIGdldFRva2VucygpIHtcbiAgICAgICAgICAgICAgICB0aGlzLiRodHRwLmdldCgnL29hdXRoL3BlcnNvbmFsLWFjY2Vzcy10b2tlbnMnKVxuICAgICAgICAgICAgICAgICAgICAgICAgLnRoZW4ocmVzcG9uc2UgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMudG9rZW5zID0gcmVzcG9uc2UuZGF0YTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfSxcblxuICAgICAgICAgICAgLyoqXG4gICAgICAgICAgICAgKiBHZXQgYWxsIG9mIHRoZSBhdmFpbGFibGUgc2NvcGVzLlxuICAgICAgICAgICAgICovXG4gICAgICAgICAgICBnZXRTY29wZXMoKSB7XG4gICAgICAgICAgICAgICAgdGhpcy4kaHR0cC5nZXQoJy9vYXV0aC9zY29wZXMnKVxuICAgICAgICAgICAgICAgICAgICAgICAgLnRoZW4ocmVzcG9uc2UgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc2NvcGVzID0gcmVzcG9uc2UuZGF0YTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfSxcblxuICAgICAgICAgICAgLyoqXG4gICAgICAgICAgICAgKiBTaG93IHRoZSBmb3JtIGZvciBjcmVhdGluZyBuZXcgdG9rZW5zLlxuICAgICAgICAgICAgICovXG4gICAgICAgICAgICBzaG93Q3JlYXRlVG9rZW5Gb3JtKCkge1xuICAgICAgICAgICAgICAgICQoJyNtb2RhbC1jcmVhdGUtdG9rZW4nKS5tb2RhbCgnc2hvdycpO1xuICAgICAgICAgICAgfSxcblxuICAgICAgICAgICAgLyoqXG4gICAgICAgICAgICAgKiBDcmVhdGUgYSBuZXcgcGVyc29uYWwgYWNjZXNzIHRva2VuLlxuICAgICAgICAgICAgICovXG4gICAgICAgICAgICBzdG9yZSgpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmFjY2Vzc1Rva2VuID0gbnVsbDtcblxuICAgICAgICAgICAgICAgIHRoaXMuZm9ybS5lcnJvcnMgPSBbXTtcblxuICAgICAgICAgICAgICAgIHRoaXMuJGh0dHAucG9zdCgnL29hdXRoL3BlcnNvbmFsLWFjY2Vzcy10b2tlbnMnLCB0aGlzLmZvcm0pXG4gICAgICAgICAgICAgICAgICAgICAgICAudGhlbihyZXNwb25zZSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5mb3JtLm5hbWUgPSAnJztcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmZvcm0uc2NvcGVzID0gW107XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5mb3JtLmVycm9ycyA9IFtdO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy50b2tlbnMucHVzaChyZXNwb25zZS5kYXRhLnRva2VuKTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc2hvd0FjY2Vzc1Rva2VuKHJlc3BvbnNlLmRhdGEuYWNjZXNzVG9rZW4pO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgICAgICAgICAgIC5jYXRjaChyZXNwb25zZSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHR5cGVvZiByZXNwb25zZS5kYXRhID09PSAnb2JqZWN0Jykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmZvcm0uZXJyb3JzID0gXy5mbGF0dGVuKF8udG9BcnJheShyZXNwb25zZS5kYXRhKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmRpcih0aGlzLmZvcm0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmZvcm0uZXJyb3JzID0gWydTb21ldGhpbmcgd2VudCB3cm9uZy4gUGxlYXNlIHRyeSBhZ2Fpbi4nXTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH0sXG5cbiAgICAgICAgICAgIC8qKlxuICAgICAgICAgICAgICogVG9nZ2xlIHRoZSBnaXZlbiBzY29wZSBpbiB0aGUgbGlzdCBvZiBhc3NpZ25lZCBzY29wZXMuXG4gICAgICAgICAgICAgKi9cbiAgICAgICAgICAgIHRvZ2dsZVNjb3BlKHNjb3BlKSB7XG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuc2NvcGVJc0Fzc2lnbmVkKHNjb3BlKSkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmZvcm0uc2NvcGVzID0gXy5yZWplY3QodGhpcy5mb3JtLnNjb3BlcywgcyA9PiBzID09IHNjb3BlKTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmZvcm0uc2NvcGVzLnB1c2goc2NvcGUpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0sXG5cbiAgICAgICAgICAgIC8qKlxuICAgICAgICAgICAgICogRGV0ZXJtaW5lIGlmIHRoZSBnaXZlbiBzY29wZSBoYXMgYmVlbiBhc3NpZ25lZCB0byB0aGUgdG9rZW4uXG4gICAgICAgICAgICAgKi9cbiAgICAgICAgICAgIHNjb3BlSXNBc3NpZ25lZChzY29wZSkge1xuICAgICAgICAgICAgICAgIHJldHVybiBfLmluZGV4T2YodGhpcy5mb3JtLnNjb3Blcywgc2NvcGUpID49IDA7XG4gICAgICAgICAgICB9LFxuXG4gICAgICAgICAgICAvKipcbiAgICAgICAgICAgICAqIFNob3cgdGhlIGdpdmVuIGFjY2VzcyB0b2tlbiB0byB0aGUgdXNlci5cbiAgICAgICAgICAgICAqL1xuICAgICAgICAgICAgc2hvd0FjY2Vzc1Rva2VuKGFjY2Vzc1Rva2VuKSB7XG4gICAgICAgICAgICAgICAgJCgnI21vZGFsLWNyZWF0ZS10b2tlbicpLm1vZGFsKCdoaWRlJyk7XG5cbiAgICAgICAgICAgICAgICB0aGlzLmFjY2Vzc1Rva2VuID0gYWNjZXNzVG9rZW47XG5cbiAgICAgICAgICAgICAgICAkKCcjbW9kYWwtYWNjZXNzLXRva2VuJykubW9kYWwoJ3Nob3cnKTtcbiAgICAgICAgICAgIH0sXG5cbiAgICAgICAgICAgIC8qKlxuICAgICAgICAgICAgICogUmV2b2tlIHRoZSBnaXZlbiB0b2tlbi5cbiAgICAgICAgICAgICAqL1xuICAgICAgICAgICAgcmV2b2tlKHRva2VuKSB7XG4gICAgICAgICAgICAgICAgdGhpcy4kaHR0cC5kZWxldGUoJy9vYXV0aC9wZXJzb25hbC1hY2Nlc3MtdG9rZW5zLycgKyB0b2tlbi5pZClcbiAgICAgICAgICAgICAgICAgICAgICAgIC50aGVuKHJlc3BvbnNlID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmdldFRva2VucygpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG48L3NjcmlwdD5cblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyBQZXJzb25hbEFjY2Vzc1Rva2Vucy52dWU/NTczNGY0ZTQiLCJtb2R1bGUuZXhwb3J0cz17cmVuZGVyOmZ1bmN0aW9uICgpe3ZhciBfdm09dGhpczt2YXIgX2g9X3ZtLiRjcmVhdGVFbGVtZW50O3ZhciBfYz1fdm0uX3NlbGYuX2N8fF9oO1xuICByZXR1cm4gX2MoJ2RpdicsIFtfYygnZGl2JywgW19jKCdkaXYnLCB7XG4gICAgc3RhdGljQ2xhc3M6IFwicGFuZWwgcGFuZWwtZGVmYXVsdFwiXG4gIH0sIFtfYygnZGl2Jywge1xuICAgIHN0YXRpY0NsYXNzOiBcInBhbmVsLWhlYWRpbmdcIlxuICB9LCBbX2MoJ2RpdicsIHtcbiAgICBzdGF0aWNTdHlsZToge1xuICAgICAgXCJkaXNwbGF5XCI6IFwiZmxleFwiLFxuICAgICAgXCJqdXN0aWZ5LWNvbnRlbnRcIjogXCJzcGFjZS1iZXR3ZWVuXCIsXG4gICAgICBcImFsaWduLWl0ZW1zXCI6IFwiY2VudGVyXCJcbiAgICB9XG4gIH0sIFtfYygnc3BhbicsIFtfdm0uX3YoXCJcXG4gICAgICAgICAgICAgICAgICAgICAgICBQZXJzb25hbCBBY2Nlc3MgVG9rZW5zXFxuICAgICAgICAgICAgICAgICAgICBcIildKSwgX3ZtLl92KFwiIFwiKSwgX2MoJ2EnLCB7XG4gICAgc3RhdGljQ2xhc3M6IFwiYWN0aW9uLWxpbmtcIixcbiAgICBvbjoge1xuICAgICAgXCJjbGlja1wiOiBfdm0uc2hvd0NyZWF0ZVRva2VuRm9ybVxuICAgIH1cbiAgfSwgW192bS5fdihcIlxcbiAgICAgICAgICAgICAgICAgICAgICAgIENyZWF0ZSBOZXcgVG9rZW5cXG4gICAgICAgICAgICAgICAgICAgIFwiKV0pXSldKSwgX3ZtLl92KFwiIFwiKSwgX2MoJ2RpdicsIHtcbiAgICBzdGF0aWNDbGFzczogXCJwYW5lbC1ib2R5XCJcbiAgfSwgWyhfdm0udG9rZW5zLmxlbmd0aCA9PT0gMCkgPyBfYygncCcsIHtcbiAgICBzdGF0aWNDbGFzczogXCJtLWItbm9uZVwiXG4gIH0sIFtfdm0uX3YoXCJcXG4gICAgICAgICAgICAgICAgICAgIFlvdSBoYXZlIG5vdCBjcmVhdGVkIGFueSBwZXJzb25hbCBhY2Nlc3MgdG9rZW5zLlxcbiAgICAgICAgICAgICAgICBcIildKSA6IF92bS5fZSgpLCBfdm0uX3YoXCIgXCIpLCAoX3ZtLnRva2Vucy5sZW5ndGggPiAwKSA/IF9jKCd0YWJsZScsIHtcbiAgICBzdGF0aWNDbGFzczogXCJ0YWJsZSB0YWJsZS1ib3JkZXJsZXNzIG0tYi1ub25lXCJcbiAgfSwgW192bS5fbSgwKSwgX3ZtLl92KFwiIFwiKSwgX2MoJ3Rib2R5JywgX3ZtLl9sKChfdm0udG9rZW5zKSwgZnVuY3Rpb24odG9rZW4pIHtcbiAgICByZXR1cm4gX2MoJ3RyJywgW19jKCd0ZCcsIHtcbiAgICAgIHN0YXRpY1N0eWxlOiB7XG4gICAgICAgIFwidmVydGljYWwtYWxpZ25cIjogXCJtaWRkbGVcIlxuICAgICAgfVxuICAgIH0sIFtfdm0uX3YoXCJcXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwiICsgX3ZtLl9zKHRva2VuLm5hbWUpICsgXCJcXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgXCIpXSksIF92bS5fdihcIiBcIiksIF9jKCd0ZCcsIHtcbiAgICAgIHN0YXRpY1N0eWxlOiB7XG4gICAgICAgIFwidmVydGljYWwtYWxpZ25cIjogXCJtaWRkbGVcIlxuICAgICAgfVxuICAgIH0sIFtfYygnYScsIHtcbiAgICAgIHN0YXRpY0NsYXNzOiBcImFjdGlvbi1saW5rIHRleHQtZGFuZ2VyXCIsXG4gICAgICBvbjoge1xuICAgICAgICBcImNsaWNrXCI6IGZ1bmN0aW9uKCRldmVudCkge1xuICAgICAgICAgIF92bS5yZXZva2UodG9rZW4pXG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9LCBbX3ZtLl92KFwiXFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRGVsZXRlXFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcIildKV0pXSlcbiAgfSkpXSkgOiBfdm0uX2UoKV0pXSldKSwgX3ZtLl92KFwiIFwiKSwgX2MoJ2RpdicsIHtcbiAgICBzdGF0aWNDbGFzczogXCJtb2RhbCBmYWRlXCIsXG4gICAgYXR0cnM6IHtcbiAgICAgIFwiaWRcIjogXCJtb2RhbC1jcmVhdGUtdG9rZW5cIixcbiAgICAgIFwidGFiaW5kZXhcIjogXCItMVwiLFxuICAgICAgXCJyb2xlXCI6IFwiZGlhbG9nXCJcbiAgICB9XG4gIH0sIFtfYygnZGl2Jywge1xuICAgIHN0YXRpY0NsYXNzOiBcIm1vZGFsLWRpYWxvZ1wiXG4gIH0sIFtfYygnZGl2Jywge1xuICAgIHN0YXRpY0NsYXNzOiBcIm1vZGFsLWNvbnRlbnRcIlxuICB9LCBbX3ZtLl9tKDEpLCBfdm0uX3YoXCIgXCIpLCBfYygnZGl2Jywge1xuICAgIHN0YXRpY0NsYXNzOiBcIm1vZGFsLWJvZHlcIlxuICB9LCBbKF92bS5mb3JtLmVycm9ycy5sZW5ndGggPiAwKSA/IF9jKCdkaXYnLCB7XG4gICAgc3RhdGljQ2xhc3M6IFwiYWxlcnQgYWxlcnQtZGFuZ2VyXCJcbiAgfSwgW192bS5fbSgyKSwgX3ZtLl92KFwiIFwiKSwgX2MoJ2JyJyksIF92bS5fdihcIiBcIiksIF9jKCd1bCcsIF92bS5fbCgoX3ZtLmZvcm0uZXJyb3JzKSwgZnVuY3Rpb24oZXJyb3IpIHtcbiAgICByZXR1cm4gX2MoJ2xpJywgW192bS5fdihcIlxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXCIgKyBfdm0uX3MoZXJyb3IpICsgXCJcXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgXCIpXSlcbiAgfSkpXSkgOiBfdm0uX2UoKSwgX3ZtLl92KFwiIFwiKSwgX2MoJ2Zvcm0nLCB7XG4gICAgc3RhdGljQ2xhc3M6IFwiZm9ybS1ob3Jpem9udGFsXCIsXG4gICAgYXR0cnM6IHtcbiAgICAgIFwicm9sZVwiOiBcImZvcm1cIlxuICAgIH0sXG4gICAgb246IHtcbiAgICAgIFwic3VibWl0XCI6IGZ1bmN0aW9uKCRldmVudCkge1xuICAgICAgICAkZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgX3ZtLnN0b3JlKCRldmVudClcbiAgICAgIH1cbiAgICB9XG4gIH0sIFtfYygnZGl2Jywge1xuICAgIHN0YXRpY0NsYXNzOiBcImZvcm0tZ3JvdXBcIlxuICB9LCBbX2MoJ2xhYmVsJywge1xuICAgIHN0YXRpY0NsYXNzOiBcImNvbC1tZC00IGNvbnRyb2wtbGFiZWxcIlxuICB9LCBbX3ZtLl92KFwiTmFtZVwiKV0pLCBfdm0uX3YoXCIgXCIpLCBfYygnZGl2Jywge1xuICAgIHN0YXRpY0NsYXNzOiBcImNvbC1tZC02XCJcbiAgfSwgW19jKCdpbnB1dCcsIHtcbiAgICBkaXJlY3RpdmVzOiBbe1xuICAgICAgbmFtZTogXCJtb2RlbFwiLFxuICAgICAgcmF3TmFtZTogXCJ2LW1vZGVsXCIsXG4gICAgICB2YWx1ZTogKF92bS5mb3JtLm5hbWUpLFxuICAgICAgZXhwcmVzc2lvbjogXCJmb3JtLm5hbWVcIlxuICAgIH1dLFxuICAgIHN0YXRpY0NsYXNzOiBcImZvcm0tY29udHJvbFwiLFxuICAgIGF0dHJzOiB7XG4gICAgICBcImlkXCI6IFwiY3JlYXRlLXRva2VuLW5hbWVcIixcbiAgICAgIFwidHlwZVwiOiBcInRleHRcIixcbiAgICAgIFwibmFtZVwiOiBcIm5hbWVcIlxuICAgIH0sXG4gICAgZG9tUHJvcHM6IHtcbiAgICAgIFwidmFsdWVcIjogKF92bS5mb3JtLm5hbWUpXG4gICAgfSxcbiAgICBvbjoge1xuICAgICAgXCJpbnB1dFwiOiBmdW5jdGlvbigkZXZlbnQpIHtcbiAgICAgICAgaWYgKCRldmVudC50YXJnZXQuY29tcG9zaW5nKSB7IHJldHVybjsgfVxuICAgICAgICBfdm0uZm9ybS5uYW1lID0gJGV2ZW50LnRhcmdldC52YWx1ZVxuICAgICAgfVxuICAgIH1cbiAgfSldKV0pLCBfdm0uX3YoXCIgXCIpLCAoX3ZtLnNjb3Blcy5sZW5ndGggPiAwKSA/IF9jKCdkaXYnLCB7XG4gICAgc3RhdGljQ2xhc3M6IFwiZm9ybS1ncm91cFwiXG4gIH0sIFtfYygnbGFiZWwnLCB7XG4gICAgc3RhdGljQ2xhc3M6IFwiY29sLW1kLTQgY29udHJvbC1sYWJlbFwiXG4gIH0sIFtfdm0uX3YoXCJTY29wZXNcIildKSwgX3ZtLl92KFwiIFwiKSwgX2MoJ2RpdicsIHtcbiAgICBzdGF0aWNDbGFzczogXCJjb2wtbWQtNlwiXG4gIH0sIF92bS5fbCgoX3ZtLnNjb3BlcyksIGZ1bmN0aW9uKHNjb3BlKSB7XG4gICAgcmV0dXJuIF9jKCdkaXYnLCBbX2MoJ2RpdicsIHtcbiAgICAgIHN0YXRpY0NsYXNzOiBcImNoZWNrYm94XCJcbiAgICB9LCBbX2MoJ2xhYmVsJywgW19jKCdpbnB1dCcsIHtcbiAgICAgIGF0dHJzOiB7XG4gICAgICAgIFwidHlwZVwiOiBcImNoZWNrYm94XCJcbiAgICAgIH0sXG4gICAgICBkb21Qcm9wczoge1xuICAgICAgICBcImNoZWNrZWRcIjogX3ZtLnNjb3BlSXNBc3NpZ25lZChzY29wZS5pZClcbiAgICAgIH0sXG4gICAgICBvbjoge1xuICAgICAgICBcImNsaWNrXCI6IGZ1bmN0aW9uKCRldmVudCkge1xuICAgICAgICAgIF92bS50b2dnbGVTY29wZShzY29wZS5pZClcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0pLCBfdm0uX3YoXCJcXG5cXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcIiArIF92bS5fcyhzY29wZS5pZCkgKyBcIlxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcIildKV0pXSlcbiAgfSkpXSkgOiBfdm0uX2UoKV0pXSksIF92bS5fdihcIiBcIiksIF9jKCdkaXYnLCB7XG4gICAgc3RhdGljQ2xhc3M6IFwibW9kYWwtZm9vdGVyXCJcbiAgfSwgW19jKCdidXR0b24nLCB7XG4gICAgc3RhdGljQ2xhc3M6IFwiYnRuIGJ0bi1kZWZhdWx0XCIsXG4gICAgYXR0cnM6IHtcbiAgICAgIFwidHlwZVwiOiBcImJ1dHRvblwiLFxuICAgICAgXCJkYXRhLWRpc21pc3NcIjogXCJtb2RhbFwiXG4gICAgfVxuICB9LCBbX3ZtLl92KFwiQ2xvc2VcIildKSwgX3ZtLl92KFwiIFwiKSwgX2MoJ2J1dHRvbicsIHtcbiAgICBzdGF0aWNDbGFzczogXCJidG4gYnRuLXByaW1hcnlcIixcbiAgICBhdHRyczoge1xuICAgICAgXCJ0eXBlXCI6IFwiYnV0dG9uXCJcbiAgICB9LFxuICAgIG9uOiB7XG4gICAgICBcImNsaWNrXCI6IF92bS5zdG9yZVxuICAgIH1cbiAgfSwgW192bS5fdihcIlxcbiAgICAgICAgICAgICAgICAgICAgICAgIENyZWF0ZVxcbiAgICAgICAgICAgICAgICAgICAgXCIpXSldKV0pXSldKSwgX3ZtLl92KFwiIFwiKSwgX2MoJ2RpdicsIHtcbiAgICBzdGF0aWNDbGFzczogXCJtb2RhbCBmYWRlXCIsXG4gICAgYXR0cnM6IHtcbiAgICAgIFwiaWRcIjogXCJtb2RhbC1hY2Nlc3MtdG9rZW5cIixcbiAgICAgIFwidGFiaW5kZXhcIjogXCItMVwiLFxuICAgICAgXCJyb2xlXCI6IFwiZGlhbG9nXCJcbiAgICB9XG4gIH0sIFtfYygnZGl2Jywge1xuICAgIHN0YXRpY0NsYXNzOiBcIm1vZGFsLWRpYWxvZ1wiXG4gIH0sIFtfYygnZGl2Jywge1xuICAgIHN0YXRpY0NsYXNzOiBcIm1vZGFsLWNvbnRlbnRcIlxuICB9LCBbX3ZtLl9tKDMpLCBfdm0uX3YoXCIgXCIpLCBfYygnZGl2Jywge1xuICAgIHN0YXRpY0NsYXNzOiBcIm1vZGFsLWJvZHlcIlxuICB9LCBbX2MoJ3AnLCBbX3ZtLl92KFwiXFxuICAgICAgICAgICAgICAgICAgICAgICAgSGVyZSBpcyB5b3VyIG5ldyBwZXJzb25hbCBhY2Nlc3MgdG9rZW4uIFRoaXMgaXMgdGhlIG9ubHkgdGltZSBpdCB3aWxsIGJlIHNob3duIHNvIGRvbid0IGxvc2UgaXQhXFxuICAgICAgICAgICAgICAgICAgICAgICAgWW91IG1heSBub3cgdXNlIHRoaXMgdG9rZW4gdG8gbWFrZSBBUEkgcmVxdWVzdHMuXFxuICAgICAgICAgICAgICAgICAgICBcIildKSwgX3ZtLl92KFwiIFwiKSwgX2MoJ3ByZScsIFtfYygnY29kZScsIFtfdm0uX3YoX3ZtLl9zKF92bS5hY2Nlc3NUb2tlbikpXSldKV0pLCBfdm0uX3YoXCIgXCIpLCBfdm0uX20oNCldKV0pXSldKVxufSxzdGF0aWNSZW5kZXJGbnM6IFtmdW5jdGlvbiAoKXt2YXIgX3ZtPXRoaXM7dmFyIF9oPV92bS4kY3JlYXRlRWxlbWVudDt2YXIgX2M9X3ZtLl9zZWxmLl9jfHxfaDtcbiAgcmV0dXJuIF9jKCd0aGVhZCcsIFtfYygndHInLCBbX2MoJ3RoJywgW192bS5fdihcIk5hbWVcIildKSwgX3ZtLl92KFwiIFwiKSwgX2MoJ3RoJyldKV0pXG59LGZ1bmN0aW9uICgpe3ZhciBfdm09dGhpczt2YXIgX2g9X3ZtLiRjcmVhdGVFbGVtZW50O3ZhciBfYz1fdm0uX3NlbGYuX2N8fF9oO1xuICByZXR1cm4gX2MoJ2RpdicsIHtcbiAgICBzdGF0aWNDbGFzczogXCJtb2RhbC1oZWFkZXJcIlxuICB9LCBbX2MoJ2J1dHRvbicsIHtcbiAgICBzdGF0aWNDbGFzczogXCJjbG9zZVwiLFxuICAgIGF0dHJzOiB7XG4gICAgICBcInR5cGVcIjogXCJidXR0b24gXCIsXG4gICAgICBcImRhdGEtZGlzbWlzc1wiOiBcIm1vZGFsXCIsXG4gICAgICBcImFyaWEtaGlkZGVuXCI6IFwidHJ1ZVwiXG4gICAgfVxuICB9LCBbX3ZtLl92KFwiw5dcIildKSwgX3ZtLl92KFwiIFwiKSwgX2MoJ2g0Jywge1xuICAgIHN0YXRpY0NsYXNzOiBcIm1vZGFsLXRpdGxlXCJcbiAgfSwgW192bS5fdihcIlxcbiAgICAgICAgICAgICAgICAgICAgICAgIENyZWF0ZSBUb2tlblxcbiAgICAgICAgICAgICAgICAgICAgXCIpXSldKVxufSxmdW5jdGlvbiAoKXt2YXIgX3ZtPXRoaXM7dmFyIF9oPV92bS4kY3JlYXRlRWxlbWVudDt2YXIgX2M9X3ZtLl9zZWxmLl9jfHxfaDtcbiAgcmV0dXJuIF9jKCdwJywgW19jKCdzdHJvbmcnLCBbX3ZtLl92KFwiV2hvb3BzIVwiKV0pLCBfdm0uX3YoXCIgU29tZXRoaW5nIHdlbnQgd3JvbmchXCIpXSlcbn0sZnVuY3Rpb24gKCl7dmFyIF92bT10aGlzO3ZhciBfaD1fdm0uJGNyZWF0ZUVsZW1lbnQ7dmFyIF9jPV92bS5fc2VsZi5fY3x8X2g7XG4gIHJldHVybiBfYygnZGl2Jywge1xuICAgIHN0YXRpY0NsYXNzOiBcIm1vZGFsLWhlYWRlclwiXG4gIH0sIFtfYygnYnV0dG9uJywge1xuICAgIHN0YXRpY0NsYXNzOiBcImNsb3NlXCIsXG4gICAgYXR0cnM6IHtcbiAgICAgIFwidHlwZVwiOiBcImJ1dHRvbiBcIixcbiAgICAgIFwiZGF0YS1kaXNtaXNzXCI6IFwibW9kYWxcIixcbiAgICAgIFwiYXJpYS1oaWRkZW5cIjogXCJ0cnVlXCJcbiAgICB9XG4gIH0sIFtfdm0uX3YoXCLDl1wiKV0pLCBfdm0uX3YoXCIgXCIpLCBfYygnaDQnLCB7XG4gICAgc3RhdGljQ2xhc3M6IFwibW9kYWwtdGl0bGVcIlxuICB9LCBbX3ZtLl92KFwiXFxuICAgICAgICAgICAgICAgICAgICAgICAgUGVyc29uYWwgQWNjZXNzIFRva2VuXFxuICAgICAgICAgICAgICAgICAgICBcIildKV0pXG59LGZ1bmN0aW9uICgpe3ZhciBfdm09dGhpczt2YXIgX2g9X3ZtLiRjcmVhdGVFbGVtZW50O3ZhciBfYz1fdm0uX3NlbGYuX2N8fF9oO1xuICByZXR1cm4gX2MoJ2RpdicsIHtcbiAgICBzdGF0aWNDbGFzczogXCJtb2RhbC1mb290ZXJcIlxuICB9LCBbX2MoJ2J1dHRvbicsIHtcbiAgICBzdGF0aWNDbGFzczogXCJidG4gYnRuLWRlZmF1bHRcIixcbiAgICBhdHRyczoge1xuICAgICAgXCJ0eXBlXCI6IFwiYnV0dG9uXCIsXG4gICAgICBcImRhdGEtZGlzbWlzc1wiOiBcIm1vZGFsXCJcbiAgICB9XG4gIH0sIFtfdm0uX3YoXCJDbG9zZVwiKV0pXSlcbn1dfVxubW9kdWxlLmV4cG9ydHMucmVuZGVyLl93aXRoU3RyaXBwZWQgPSB0cnVlXG5pZiAobW9kdWxlLmhvdCkge1xuICBtb2R1bGUuaG90LmFjY2VwdCgpXG4gIGlmIChtb2R1bGUuaG90LmRhdGEpIHtcbiAgICAgcmVxdWlyZShcInZ1ZS1ob3QtcmVsb2FkLWFwaVwiKS5yZXJlbmRlcihcImRhdGEtdi0yMjU3NzhjMlwiLCBtb2R1bGUuZXhwb3J0cylcbiAgfVxufVxuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIC4vbm9kZV9tb2R1bGVzL3Z1ZS1sb2FkZXIvbGliL3RlbXBsYXRlLWNvbXBpbGVyP3tcImlkXCI6XCJkYXRhLXYtMjI1Nzc4YzJcIixcImhhc1Njb3BlZFwiOnRydWV9IS4vbm9kZV9tb2R1bGVzL3Z1ZS1sb2FkZXIvbGliL3NlbGVjdG9yLmpzP3R5cGU9dGVtcGxhdGUmaW5kZXg9MCEuL3Jlc291cmNlcy9hc3NldHMvanMvY29tcG9uZW50cy9wYXNzcG9ydC9QZXJzb25hbEFjY2Vzc1Rva2Vucy52dWVcbi8vIG1vZHVsZSBpZCA9IDMwXG4vLyBtb2R1bGUgY2h1bmtzID0gMCIsInZhciBkaXNwb3NlZCA9IGZhbHNlXG5mdW5jdGlvbiBpbmplY3RTdHlsZSAoc3NyQ29udGV4dCkge1xuICBpZiAoZGlzcG9zZWQpIHJldHVyblxuICByZXF1aXJlKFwiISF2dWUtc3R5bGUtbG9hZGVyIWNzcy1sb2FkZXI/c291cmNlTWFwIS4uLy4uLy4uLy4uLy4uL25vZGVfbW9kdWxlcy92dWUtbG9hZGVyL2xpYi9zdHlsZS1jb21waWxlci9pbmRleD97XFxcInZ1ZVxcXCI6dHJ1ZSxcXFwiaWRcXFwiOlxcXCJkYXRhLXYtNTMwMWEyMzZcXFwiLFxcXCJzY29wZWRcXFwiOnRydWUsXFxcImhhc0lubGluZUNvbmZpZ1xcXCI6dHJ1ZX0hLi4vLi4vLi4vLi4vLi4vbm9kZV9tb2R1bGVzL3Z1ZS1sb2FkZXIvbGliL3NlbGVjdG9yP3R5cGU9c3R5bGVzJmluZGV4PTAhLi9pbXBvcnRlci52dWVcIilcbn1cbnZhciBDb21wb25lbnQgPSByZXF1aXJlKFwiIS4uLy4uLy4uLy4uLy4uL25vZGVfbW9kdWxlcy92dWUtbG9hZGVyL2xpYi9jb21wb25lbnQtbm9ybWFsaXplclwiKShcbiAgLyogc2NyaXB0ICovXG4gIHJlcXVpcmUoXCIhIWJhYmVsLWxvYWRlcj97XFxcImNhY2hlRGlyZWN0b3J5XFxcIjp0cnVlLFxcXCJwcmVzZXRzXFxcIjpbW1xcXCJlbnZcXFwiLHtcXFwibW9kdWxlc1xcXCI6ZmFsc2UsXFxcInRhcmdldHNcXFwiOntcXFwiYnJvd3NlcnNcXFwiOltcXFwiPiAyJVxcXCJdLFxcXCJ1Z2xpZnlcXFwiOnRydWV9fV1dfSEuLi8uLi8uLi8uLi8uLi9ub2RlX21vZHVsZXMvdnVlLWxvYWRlci9saWIvc2VsZWN0b3I/dHlwZT1zY3JpcHQmaW5kZXg9MCEuL2ltcG9ydGVyLnZ1ZVwiKSxcbiAgLyogdGVtcGxhdGUgKi9cbiAgbnVsbCxcbiAgLyogc3R5bGVzICovXG4gIGluamVjdFN0eWxlLFxuICAvKiBzY29wZUlkICovXG4gIFwiZGF0YS12LTUzMDFhMjM2XCIsXG4gIC8qIG1vZHVsZUlkZW50aWZpZXIgKHNlcnZlciBvbmx5KSAqL1xuICBudWxsXG4pXG5Db21wb25lbnQub3B0aW9ucy5fX2ZpbGUgPSBcIi9ob21lL2h5ZHJvZ2VuL3dvcmsvc25pcGUtaXQvcmVzb3VyY2VzL2Fzc2V0cy9qcy9jb21wb25lbnRzL2ltcG9ydGVyL2ltcG9ydGVyLnZ1ZVwiXG5pZiAoQ29tcG9uZW50LmVzTW9kdWxlICYmIE9iamVjdC5rZXlzKENvbXBvbmVudC5lc01vZHVsZSkuc29tZShmdW5jdGlvbiAoa2V5KSB7cmV0dXJuIGtleSAhPT0gXCJkZWZhdWx0XCIgJiYga2V5LnN1YnN0cigwLCAyKSAhPT0gXCJfX1wifSkpIHtjb25zb2xlLmVycm9yKFwibmFtZWQgZXhwb3J0cyBhcmUgbm90IHN1cHBvcnRlZCBpbiAqLnZ1ZSBmaWxlcy5cIil9XG5cbi8qIGhvdCByZWxvYWQgKi9cbmlmIChtb2R1bGUuaG90KSB7KGZ1bmN0aW9uICgpIHtcbiAgdmFyIGhvdEFQSSA9IHJlcXVpcmUoXCJ2dWUtaG90LXJlbG9hZC1hcGlcIilcbiAgaG90QVBJLmluc3RhbGwocmVxdWlyZShcInZ1ZVwiKSwgZmFsc2UpXG4gIGlmICghaG90QVBJLmNvbXBhdGlibGUpIHJldHVyblxuICBtb2R1bGUuaG90LmFjY2VwdCgpXG4gIGlmICghbW9kdWxlLmhvdC5kYXRhKSB7XG4gICAgaG90QVBJLmNyZWF0ZVJlY29yZChcImRhdGEtdi01MzAxYTIzNlwiLCBDb21wb25lbnQub3B0aW9ucylcbiAgfSBlbHNlIHtcbiAgICBob3RBUEkucmVsb2FkKFwiZGF0YS12LTUzMDFhMjM2XCIsIENvbXBvbmVudC5vcHRpb25zKVxuICB9XG4gIG1vZHVsZS5ob3QuZGlzcG9zZShmdW5jdGlvbiAoZGF0YSkge1xuICAgIGRpc3Bvc2VkID0gdHJ1ZVxuICB9KVxufSkoKX1cblxubW9kdWxlLmV4cG9ydHMgPSBDb21wb25lbnQuZXhwb3J0c1xuXG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gLi9yZXNvdXJjZXMvYXNzZXRzL2pzL2NvbXBvbmVudHMvaW1wb3J0ZXIvaW1wb3J0ZXIudnVlXG4vLyBtb2R1bGUgaWQgPSAzMVxuLy8gbW9kdWxlIGNodW5rcyA9IDAiLCIvLyBzdHlsZS1sb2FkZXI6IEFkZHMgc29tZSBjc3MgdG8gdGhlIERPTSBieSBhZGRpbmcgYSA8c3R5bGU+IHRhZ1xuXG4vLyBsb2FkIHRoZSBzdHlsZXNcbnZhciBjb250ZW50ID0gcmVxdWlyZShcIiEhLi4vLi4vLi4vLi4vLi4vbm9kZV9tb2R1bGVzL2Nzcy1sb2FkZXIvaW5kZXguanM/c291cmNlTWFwIS4uLy4uLy4uLy4uLy4uL25vZGVfbW9kdWxlcy92dWUtbG9hZGVyL2xpYi9zdHlsZS1jb21waWxlci9pbmRleC5qcz97XFxcInZ1ZVxcXCI6dHJ1ZSxcXFwiaWRcXFwiOlxcXCJkYXRhLXYtNTMwMWEyMzZcXFwiLFxcXCJzY29wZWRcXFwiOnRydWUsXFxcImhhc0lubGluZUNvbmZpZ1xcXCI6dHJ1ZX0hLi4vLi4vLi4vLi4vLi4vbm9kZV9tb2R1bGVzL3Z1ZS1sb2FkZXIvbGliL3NlbGVjdG9yLmpzP3R5cGU9c3R5bGVzJmluZGV4PTAhLi9pbXBvcnRlci52dWVcIik7XG5pZih0eXBlb2YgY29udGVudCA9PT0gJ3N0cmluZycpIGNvbnRlbnQgPSBbW21vZHVsZS5pZCwgY29udGVudCwgJyddXTtcbmlmKGNvbnRlbnQubG9jYWxzKSBtb2R1bGUuZXhwb3J0cyA9IGNvbnRlbnQubG9jYWxzO1xuLy8gYWRkIHRoZSBzdHlsZXMgdG8gdGhlIERPTVxudmFyIHVwZGF0ZSA9IHJlcXVpcmUoXCIhLi4vLi4vLi4vLi4vLi4vbm9kZV9tb2R1bGVzL3Z1ZS1zdHlsZS1sb2FkZXIvbGliL2FkZFN0eWxlc0NsaWVudC5qc1wiKShcImE1OTEwNmMyXCIsIGNvbnRlbnQsIGZhbHNlKTtcbi8vIEhvdCBNb2R1bGUgUmVwbGFjZW1lbnRcbmlmKG1vZHVsZS5ob3QpIHtcbiAvLyBXaGVuIHRoZSBzdHlsZXMgY2hhbmdlLCB1cGRhdGUgdGhlIDxzdHlsZT4gdGFnc1xuIGlmKCFjb250ZW50LmxvY2Fscykge1xuICAgbW9kdWxlLmhvdC5hY2NlcHQoXCIhIS4uLy4uLy4uLy4uLy4uL25vZGVfbW9kdWxlcy9jc3MtbG9hZGVyL2luZGV4LmpzP3NvdXJjZU1hcCEuLi8uLi8uLi8uLi8uLi9ub2RlX21vZHVsZXMvdnVlLWxvYWRlci9saWIvc3R5bGUtY29tcGlsZXIvaW5kZXguanM/e1xcXCJ2dWVcXFwiOnRydWUsXFxcImlkXFxcIjpcXFwiZGF0YS12LTUzMDFhMjM2XFxcIixcXFwic2NvcGVkXFxcIjp0cnVlLFxcXCJoYXNJbmxpbmVDb25maWdcXFwiOnRydWV9IS4uLy4uLy4uLy4uLy4uL25vZGVfbW9kdWxlcy92dWUtbG9hZGVyL2xpYi9zZWxlY3Rvci5qcz90eXBlPXN0eWxlcyZpbmRleD0wIS4vaW1wb3J0ZXIudnVlXCIsIGZ1bmN0aW9uKCkge1xuICAgICB2YXIgbmV3Q29udGVudCA9IHJlcXVpcmUoXCIhIS4uLy4uLy4uLy4uLy4uL25vZGVfbW9kdWxlcy9jc3MtbG9hZGVyL2luZGV4LmpzP3NvdXJjZU1hcCEuLi8uLi8uLi8uLi8uLi9ub2RlX21vZHVsZXMvdnVlLWxvYWRlci9saWIvc3R5bGUtY29tcGlsZXIvaW5kZXguanM/e1xcXCJ2dWVcXFwiOnRydWUsXFxcImlkXFxcIjpcXFwiZGF0YS12LTUzMDFhMjM2XFxcIixcXFwic2NvcGVkXFxcIjp0cnVlLFxcXCJoYXNJbmxpbmVDb25maWdcXFwiOnRydWV9IS4uLy4uLy4uLy4uLy4uL25vZGVfbW9kdWxlcy92dWUtbG9hZGVyL2xpYi9zZWxlY3Rvci5qcz90eXBlPXN0eWxlcyZpbmRleD0wIS4vaW1wb3J0ZXIudnVlXCIpO1xuICAgICBpZih0eXBlb2YgbmV3Q29udGVudCA9PT0gJ3N0cmluZycpIG5ld0NvbnRlbnQgPSBbW21vZHVsZS5pZCwgbmV3Q29udGVudCwgJyddXTtcbiAgICAgdXBkYXRlKG5ld0NvbnRlbnQpO1xuICAgfSk7XG4gfVxuIC8vIFdoZW4gdGhlIG1vZHVsZSBpcyBkaXNwb3NlZCwgcmVtb3ZlIHRoZSA8c3R5bGU+IHRhZ3NcbiBtb2R1bGUuaG90LmRpc3Bvc2UoZnVuY3Rpb24oKSB7IHVwZGF0ZSgpOyB9KTtcbn1cblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyAuL25vZGVfbW9kdWxlcy92dWUtc3R5bGUtbG9hZGVyIS4vbm9kZV9tb2R1bGVzL2Nzcy1sb2FkZXI/c291cmNlTWFwIS4vbm9kZV9tb2R1bGVzL3Z1ZS1sb2FkZXIvbGliL3N0eWxlLWNvbXBpbGVyP3tcInZ1ZVwiOnRydWUsXCJpZFwiOlwiZGF0YS12LTUzMDFhMjM2XCIsXCJzY29wZWRcIjp0cnVlLFwiaGFzSW5saW5lQ29uZmlnXCI6dHJ1ZX0hLi9ub2RlX21vZHVsZXMvdnVlLWxvYWRlci9saWIvc2VsZWN0b3IuanM/dHlwZT1zdHlsZXMmaW5kZXg9MCEuL3Jlc291cmNlcy9hc3NldHMvanMvY29tcG9uZW50cy9pbXBvcnRlci9pbXBvcnRlci52dWVcbi8vIG1vZHVsZSBpZCA9IDMyXG4vLyBtb2R1bGUgY2h1bmtzID0gMCIsImV4cG9ydHMgPSBtb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoXCIuLi8uLi8uLi8uLi8uLi9ub2RlX21vZHVsZXMvY3NzLWxvYWRlci9saWIvY3NzLWJhc2UuanNcIikodHJ1ZSk7XG4vLyBpbXBvcnRzXG5cblxuLy8gbW9kdWxlXG5leHBvcnRzLnB1c2goW21vZHVsZS5pZCwgXCJcXG50ZFtkYXRhLXYtNTMwMWEyMzZdIHtcXG4gICAgZm9udC1zaXplOiAxM3B4O1xcbn1cXG50aFtkYXRhLXYtNTMwMWEyMzZdIHtcXG4gICAgZm9udC1zaXplOiAxM3B4O1xcbn1cXG5cIiwgXCJcIiwge1widmVyc2lvblwiOjMsXCJzb3VyY2VzXCI6W1wiL2hvbWUvaHlkcm9nZW4vd29yay9zbmlwZS1pdC9yZXNvdXJjZXMvYXNzZXRzL2pzL2NvbXBvbmVudHMvaW1wb3J0ZXIvaW1wb3J0ZXIudnVlPzExZDNmZDBlXCJdLFwibmFtZXNcIjpbXSxcIm1hcHBpbmdzXCI6XCI7QUFDQTtJQUNBLGdCQUFBO0NBQ0E7QUFFQTtJQUNBLGdCQUFBO0NBQ0FcIixcImZpbGVcIjpcImltcG9ydGVyLnZ1ZVwiLFwic291cmNlc0NvbnRlbnRcIjpbXCI8c3R5bGUgc2NvcGVkPlxcbnRkIHtcXG4gICAgZm9udC1zaXplOiAxM3B4O1xcbn1cXG5cXG50aCB7XFxuICAgIGZvbnQtc2l6ZTogMTNweDtcXG59XFxuPC9zdHlsZT5cXG5cXG48c2NyaXB0PlxcbiAgICByZXF1aXJlKCdibHVlaW1wLWZpbGUtdXBsb2FkJyk7XFxuICAgIGV4cG9ydCBkZWZhdWx0IHtcXG5cXG4gICAgICAgIHByb3BzOiBbJ2ltcG9ydFVybCddLFxcbiAgICAgICAgLypcXG4gICAgICAgICAqIFRoZSBjb21wb25lbnQncyBkYXRhLlxcbiAgICAgICAgICovXFxuICAgICAgICBkYXRhKCkge1xcbiAgICAgICAgICAgIHJldHVybiB7XFxuICAgICAgICAgICAgICAgIGZpbGVzOiBbXSxcXG4gICAgICAgICAgICAgICAgZGlzcGxheUltcG9ydE1vZGFsOiBmYWxzZSxcXG4gICAgICAgICAgICAgICAgYWN0aXZlRmlsZTogbnVsbCxcXG4gICAgICAgICAgICAgICAgYWxlcnQ6IHtcXG4gICAgICAgICAgICAgICAgICAgIHR5cGU6IG51bGwsXFxuICAgICAgICAgICAgICAgICAgICBtZXNzYWdlOiBudWxsLFxcbiAgICAgICAgICAgICAgICAgICAgdmlzaWJsZTogZmFsc2UsXFxuICAgICAgICAgICAgICAgIH0sXFxuICAgICAgICAgICAgICAgIGltcG9ydEVycm9yczogbnVsbCxcXG4gICAgICAgICAgICAgICAgcHJvZ3Jlc3M6IHtcXG4gICAgICAgICAgICAgICAgICAgIGN1cnJlbnRDbGFzczogXFxcInByb2dyZXNzLWJhci13YXJuaW5nXFxcIixcXG4gICAgICAgICAgICAgICAgICAgIGN1cnJlbnRQZXJjZW50OiBcXFwiMFxcXCIsXFxuICAgICAgICAgICAgICAgICAgICBzdGF0dXNUZXh0OiAnJyxcXG4gICAgICAgICAgICAgICAgICAgIHZpc2libGU6IGZhbHNlXFxuICAgICAgICAgICAgICAgIH1cXG4gICAgICAgICAgICB9O1xcbiAgICAgICAgfSxcXG5cXG4gICAgICAgIG1vdW50ZWQoKSB7XFxuICAgICAgICAgICAgd2luZG93LmV2ZW50SHViLiRvbignaW1wb3J0RXJyb3JzJywgdGhpcy51cGRhdGVJbXBvcnRFcnJvcnMpO1xcbiAgICAgICAgICAgIHRoaXMuZmV0Y2hGaWxlcygpO1xcbiAgICAgICAgICAgIGxldCB2bSA9IHRoaXM7XFxuICAgICAgICAgICAgJCgnI2ZpbGV1cGxvYWQnKS5maWxldXBsb2FkKHtcXG4gICAgICAgICAgICAgICAgZGF0YVR5cGU6ICdqc29uJyxcXG4gICAgICAgICAgICAgICAgZG9uZShlLCBkYXRhKSB7XFxuICAgICAgICAgICAgICAgICAgICB2bS5wcm9ncmVzcy5jdXJyZW50Q2xhc3M9XFxcInByb2dyZXNzLWJhci1zdWNjZXNzXFxcIjtcXG4gICAgICAgICAgICAgICAgICAgIHZtLnByb2dyZXNzLnN0YXR1c1RleHQgPSBcXFwiU3VjY2VzcyFcXFwiO1xcbiAgICAgICAgICAgICAgICAgICAgdm0uZmlsZXMgPSBkYXRhLnJlc3VsdC5maWxlcy5jb25jYXQodm0uZmlsZXMpO1xcbiAgICAgICAgICAgICAgICAgICAgY29uc29sZS5sb2coZGF0YS5yZXN1bHQuaGVhZGVyX3Jvdyk7XFxuICAgICAgICAgICAgICAgIH0sXFxuICAgICAgICAgICAgICAgIGFkZChlLCBkYXRhKSB7XFxuICAgICAgICAgICAgICAgICAgICBkYXRhLmhlYWRlcnMgPSB7XFxuICAgICAgICAgICAgICAgICAgICAgICAgXFxcIlgtUmVxdWVzdGVkLVdpdGhcXFwiOiAnWE1MSHR0cFJlcXVlc3QnLFxcbiAgICAgICAgICAgICAgICAgICAgICAgIFxcXCJYLUNTUkYtVE9LRU5cXFwiOiBMYXJhdmVsLmNzcmZUb2tlblxcbiAgICAgICAgICAgICAgICAgICAgfTtcXG4gICAgICAgICAgICAgICAgICAgIGRhdGEucHJvY2VzcygpLmRvbmUoICgpID0+IHtkYXRhLnN1Ym1pdCgpO30pO1xcbiAgICAgICAgICAgICAgICAgICAgdm0ucHJvZ3Jlc3MudmlzaWJsZT10cnVlO1xcbiAgICAgICAgICAgICAgICB9LFxcbiAgICAgICAgICAgICAgICBwcm9ncmVzcyhlLCBkYXRhKSB7XFxuICAgICAgICAgICAgICAgICAgICB2YXIgcHJvZ3Jlc3MgPSBwYXJzZUludCgoZGF0YS5sb2FkZWQgLyBkYXRhLnRvdGFsICogMTAwLCAxMCkpO1xcbiAgICAgICAgICAgICAgICAgICAgdm0ucHJvZ3Jlc3MuY3VycmVudFBlcmNlbnQgPSBwcm9ncmVzcztcXG4gICAgICAgICAgICAgICAgICAgIHZtLnByb2dyZXNzLnN0YXR1c1RleHQgPSBwcm9ncmVzcysnJSBDb21wbGV0ZSc7XFxuICAgICAgICAgICAgICAgIH0sXFxuICAgICAgICAgICAgICAgIGZhaWwoZSwgZGF0YSkge1xcbiAgICAgICAgICAgICAgICAgICAgdm0ucHJvZ3Jlc3MuY3VycmVudENsYXNzID0gXFxcInByb2dyZXNzLWJhci1kYW5nZXJcXFwiO1xcbiAgICAgICAgICAgICAgICAgICAgLy8gRGlzcGxheSBhbnkgZXJyb3JzIHJldHVybmVkIGZyb20gdGhlICQuYWpheCgpXFxuICAgICAgICAgICAgICAgICAgICB2bS5wcm9ncmVzcy5zdGF0dXNUZXh0ID0gZGF0YS5qcVhIUi5yZXNwb25zZUpTT04ubWVzc2FnZXM7XFxuICAgICAgICAgICAgICAgIH1cXG4gICAgICAgICAgICB9KVxcbiAgICAgICAgfSxcXG5cXG4gICAgICAgIG1ldGhvZHM6IHtcXG4gICAgICAgICAgICBmZXRjaEZpbGVzKCkge1xcbiAgICAgICAgICAgICAgICB0aGlzLiRodHRwLmdldCh0aGlzLmltcG9ydFVybClcXG4gICAgICAgICAgICAgICAgLnRoZW4oICh7ZGF0YX0pID0+IHRoaXMuZmlsZXMgPSBkYXRhLCAvLyBTdWNjZXNzXFxuICAgICAgICAgICAgICAgICAgICAvL0ZhaWxcXG4gICAgICAgICAgICAgICAgKHJlc3BvbnNlKSA9PiB7XFxuICAgICAgICAgICAgICAgICAgICB0aGlzLmFsZXJ0LnR5cGU9XFxcImRhbmdlclxcXCI7XFxuICAgICAgICAgICAgICAgICAgICB0aGlzLmFsZXJ0LnZpc2libGU9dHJ1ZTtcXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuYWxlcnQubWVzc2FnZT1cXFwiU29tZXRoaW5nIHdlbnQgd3JvbmcgZmV0Y2hpbmcgZmlsZXMuLi5cXFwiO1xcbiAgICAgICAgICAgICAgICB9KTtcXG4gICAgICAgICAgICB9LFxcbiAgICAgICAgICAgIGRlbGV0ZUZpbGUoZmlsZSwga2V5KSB7XFxuICAgICAgICAgICAgICAgIHRoaXMuJGh0dHAuZGVsZXRlKHRoaXMuaW1wb3J0VXJsK1xcXCIvXFxcIitmaWxlLmlkKVxcbiAgICAgICAgICAgICAgICAudGhlbigocmVzcG9uc2UpID0+IHRoaXMuZmlsZXMuc3BsaWNlKGtleSwgMSksIC8vIFN1Y2Nlc3MsIHJlbW92ZSBmaWxlIGZyb20gYXJyYXkuXFxuICAgICAgICAgICAgICAgICAgICAocmVzcG9uc2UpID0+IHsvLyBGYWlsXFxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5hbGVydC50eXBlPVxcXCJkYW5nZXJcXFwiO1xcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuYWxlcnQudmlzaWJsZT10cnVlO1xcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuYWxlcnQubWVzc2FnZT1yZXNwb25zZS5ib2R5Lm1lc3NhZ2VzO1xcbiAgICAgICAgICAgICAgICAgICAgfVxcbiAgICAgICAgICAgICAgICApO1xcbiAgICAgICAgICAgIH0sXFxuICAgICAgICAgICAgdG9nZ2xlRXZlbnQoZmlsZUlkKSB7XFxuICAgICAgICAgICAgICAgIHdpbmRvdy5ldmVudEh1Yi4kZW1pdCgnc2hvd0RldGFpbHMnLCBmaWxlSWQpXFxuICAgICAgICAgICAgfSxcXG4gICAgICAgICAgICB1cGRhdGVBbGVydChhbGVydCkge1xcbiAgICAgICAgICAgICAgICB0aGlzLmFsZXJ0ID0gYWxlcnQ7XFxuICAgICAgICAgICAgfSxcXG4gICAgICAgICAgICB1cGRhdGVJbXBvcnRFcnJvcnMoZXJyb3JzKSB7XFxuICAgICAgICAgICAgICAgIHRoaXMuaW1wb3J0RXJyb3JzID0gZXJyb3JzO1xcbiAgICAgICAgICAgIH1cXG4gICAgICAgIH0sXFxuXFxuICAgICAgICBjb21wdXRlZDoge1xcbiAgICAgICAgICAgIHByb2dyZXNzV2lkdGgoKSB7XFxuICAgICAgICAgICAgICAgIHJldHVybiBcXFwid2lkdGg6IFxcXCIrdGhpcy5wcm9ncmVzcy5jdXJyZW50UGVyY2VudCoxMCsnJSc7XFxuICAgICAgICAgICAgfVxcbiAgICAgICAgfSxcXG5cXG4gICAgICAgIGNvbXBvbmVudHM6IHtcXG4gICAgICAgICAgICBhbGVydDogcmVxdWlyZSgnLi4vYWxlcnQudnVlJyksXFxuICAgICAgICAgICAgZXJyb3JzOiByZXF1aXJlKCcuL2ltcG9ydGVyLWVycm9ycy52dWUnKSxcXG4gICAgICAgICAgICBpbXBvcnRGaWxlOiByZXF1aXJlKCcuL2ltcG9ydGVyLWZpbGUudnVlJyksXFxuICAgICAgICB9XFxuICAgIH1cXG5cXG48L3NjcmlwdD5cXG5cIl0sXCJzb3VyY2VSb290XCI6XCJcIn1dKTtcblxuLy8gZXhwb3J0c1xuXG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gLi9ub2RlX21vZHVsZXMvY3NzLWxvYWRlcj9zb3VyY2VNYXAhLi9ub2RlX21vZHVsZXMvdnVlLWxvYWRlci9saWIvc3R5bGUtY29tcGlsZXI/e1widnVlXCI6dHJ1ZSxcImlkXCI6XCJkYXRhLXYtNTMwMWEyMzZcIixcInNjb3BlZFwiOnRydWUsXCJoYXNJbmxpbmVDb25maWdcIjp0cnVlfSEuL25vZGVfbW9kdWxlcy92dWUtbG9hZGVyL2xpYi9zZWxlY3Rvci5qcz90eXBlPXN0eWxlcyZpbmRleD0wIS4vcmVzb3VyY2VzL2Fzc2V0cy9qcy9jb21wb25lbnRzL2ltcG9ydGVyL2ltcG9ydGVyLnZ1ZVxuLy8gbW9kdWxlIGlkID0gMzNcbi8vIG1vZHVsZSBjaHVua3MgPSAwIiwiPHN0eWxlIHNjb3BlZD5cbnRkIHtcbiAgICBmb250LXNpemU6IDEzcHg7XG59XG5cbnRoIHtcbiAgICBmb250LXNpemU6IDEzcHg7XG59XG48L3N0eWxlPlxuXG48c2NyaXB0PlxuICAgIHJlcXVpcmUoJ2JsdWVpbXAtZmlsZS11cGxvYWQnKTtcbiAgICBleHBvcnQgZGVmYXVsdCB7XG5cbiAgICAgICAgcHJvcHM6IFsnaW1wb3J0VXJsJ10sXG4gICAgICAgIC8qXG4gICAgICAgICAqIFRoZSBjb21wb25lbnQncyBkYXRhLlxuICAgICAgICAgKi9cbiAgICAgICAgZGF0YSgpIHtcbiAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgICAgZmlsZXM6IFtdLFxuICAgICAgICAgICAgICAgIGRpc3BsYXlJbXBvcnRNb2RhbDogZmFsc2UsXG4gICAgICAgICAgICAgICAgYWN0aXZlRmlsZTogbnVsbCxcbiAgICAgICAgICAgICAgICBhbGVydDoge1xuICAgICAgICAgICAgICAgICAgICB0eXBlOiBudWxsLFxuICAgICAgICAgICAgICAgICAgICBtZXNzYWdlOiBudWxsLFxuICAgICAgICAgICAgICAgICAgICB2aXNpYmxlOiBmYWxzZSxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIGltcG9ydEVycm9yczogbnVsbCxcbiAgICAgICAgICAgICAgICBwcm9ncmVzczoge1xuICAgICAgICAgICAgICAgICAgICBjdXJyZW50Q2xhc3M6IFwicHJvZ3Jlc3MtYmFyLXdhcm5pbmdcIixcbiAgICAgICAgICAgICAgICAgICAgY3VycmVudFBlcmNlbnQ6IFwiMFwiLFxuICAgICAgICAgICAgICAgICAgICBzdGF0dXNUZXh0OiAnJyxcbiAgICAgICAgICAgICAgICAgICAgdmlzaWJsZTogZmFsc2VcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9O1xuICAgICAgICB9LFxuXG4gICAgICAgIG1vdW50ZWQoKSB7XG4gICAgICAgICAgICB3aW5kb3cuZXZlbnRIdWIuJG9uKCdpbXBvcnRFcnJvcnMnLCB0aGlzLnVwZGF0ZUltcG9ydEVycm9ycyk7XG4gICAgICAgICAgICB0aGlzLmZldGNoRmlsZXMoKTtcbiAgICAgICAgICAgIGxldCB2bSA9IHRoaXM7XG4gICAgICAgICAgICAkKCcjZmlsZXVwbG9hZCcpLmZpbGV1cGxvYWQoe1xuICAgICAgICAgICAgICAgIGRhdGFUeXBlOiAnanNvbicsXG4gICAgICAgICAgICAgICAgZG9uZShlLCBkYXRhKSB7XG4gICAgICAgICAgICAgICAgICAgIHZtLnByb2dyZXNzLmN1cnJlbnRDbGFzcz1cInByb2dyZXNzLWJhci1zdWNjZXNzXCI7XG4gICAgICAgICAgICAgICAgICAgIHZtLnByb2dyZXNzLnN0YXR1c1RleHQgPSBcIlN1Y2Nlc3MhXCI7XG4gICAgICAgICAgICAgICAgICAgIHZtLmZpbGVzID0gZGF0YS5yZXN1bHQuZmlsZXMuY29uY2F0KHZtLmZpbGVzKTtcbiAgICAgICAgICAgICAgICAgICAgY29uc29sZS5sb2coZGF0YS5yZXN1bHQuaGVhZGVyX3Jvdyk7XG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICBhZGQoZSwgZGF0YSkge1xuICAgICAgICAgICAgICAgICAgICBkYXRhLmhlYWRlcnMgPSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBcIlgtUmVxdWVzdGVkLVdpdGhcIjogJ1hNTEh0dHBSZXF1ZXN0JyxcbiAgICAgICAgICAgICAgICAgICAgICAgIFwiWC1DU1JGLVRPS0VOXCI6IExhcmF2ZWwuY3NyZlRva2VuXG4gICAgICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgICAgIGRhdGEucHJvY2VzcygpLmRvbmUoICgpID0+IHtkYXRhLnN1Ym1pdCgpO30pO1xuICAgICAgICAgICAgICAgICAgICB2bS5wcm9ncmVzcy52aXNpYmxlPXRydWU7XG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICBwcm9ncmVzcyhlLCBkYXRhKSB7XG4gICAgICAgICAgICAgICAgICAgIHZhciBwcm9ncmVzcyA9IHBhcnNlSW50KChkYXRhLmxvYWRlZCAvIGRhdGEudG90YWwgKiAxMDAsIDEwKSk7XG4gICAgICAgICAgICAgICAgICAgIHZtLnByb2dyZXNzLmN1cnJlbnRQZXJjZW50ID0gcHJvZ3Jlc3M7XG4gICAgICAgICAgICAgICAgICAgIHZtLnByb2dyZXNzLnN0YXR1c1RleHQgPSBwcm9ncmVzcysnJSBDb21wbGV0ZSc7XG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICBmYWlsKGUsIGRhdGEpIHtcbiAgICAgICAgICAgICAgICAgICAgdm0ucHJvZ3Jlc3MuY3VycmVudENsYXNzID0gXCJwcm9ncmVzcy1iYXItZGFuZ2VyXCI7XG4gICAgICAgICAgICAgICAgICAgIC8vIERpc3BsYXkgYW55IGVycm9ycyByZXR1cm5lZCBmcm9tIHRoZSAkLmFqYXgoKVxuICAgICAgICAgICAgICAgICAgICB2bS5wcm9ncmVzcy5zdGF0dXNUZXh0ID0gZGF0YS5qcVhIUi5yZXNwb25zZUpTT04ubWVzc2FnZXM7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSlcbiAgICAgICAgfSxcblxuICAgICAgICBtZXRob2RzOiB7XG4gICAgICAgICAgICBmZXRjaEZpbGVzKCkge1xuICAgICAgICAgICAgICAgIHRoaXMuJGh0dHAuZ2V0KHRoaXMuaW1wb3J0VXJsKVxuICAgICAgICAgICAgICAgIC50aGVuKCAoe2RhdGF9KSA9PiB0aGlzLmZpbGVzID0gZGF0YSwgLy8gU3VjY2Vzc1xuICAgICAgICAgICAgICAgICAgICAvL0ZhaWxcbiAgICAgICAgICAgICAgICAocmVzcG9uc2UpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5hbGVydC50eXBlPVwiZGFuZ2VyXCI7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuYWxlcnQudmlzaWJsZT10cnVlO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmFsZXJ0Lm1lc3NhZ2U9XCJTb21ldGhpbmcgd2VudCB3cm9uZyBmZXRjaGluZyBmaWxlcy4uLlwiO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGRlbGV0ZUZpbGUoZmlsZSwga2V5KSB7XG4gICAgICAgICAgICAgICAgdGhpcy4kaHR0cC5kZWxldGUodGhpcy5pbXBvcnRVcmwrXCIvXCIrZmlsZS5pZClcbiAgICAgICAgICAgICAgICAudGhlbigocmVzcG9uc2UpID0+IHRoaXMuZmlsZXMuc3BsaWNlKGtleSwgMSksIC8vIFN1Y2Nlc3MsIHJlbW92ZSBmaWxlIGZyb20gYXJyYXkuXG4gICAgICAgICAgICAgICAgICAgIChyZXNwb25zZSkgPT4gey8vIEZhaWxcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuYWxlcnQudHlwZT1cImRhbmdlclwiO1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5hbGVydC52aXNpYmxlPXRydWU7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmFsZXJ0Lm1lc3NhZ2U9cmVzcG9uc2UuYm9keS5tZXNzYWdlcztcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgdG9nZ2xlRXZlbnQoZmlsZUlkKSB7XG4gICAgICAgICAgICAgICAgd2luZG93LmV2ZW50SHViLiRlbWl0KCdzaG93RGV0YWlscycsIGZpbGVJZClcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB1cGRhdGVBbGVydChhbGVydCkge1xuICAgICAgICAgICAgICAgIHRoaXMuYWxlcnQgPSBhbGVydDtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB1cGRhdGVJbXBvcnRFcnJvcnMoZXJyb3JzKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5pbXBvcnRFcnJvcnMgPSBlcnJvcnM7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0sXG5cbiAgICAgICAgY29tcHV0ZWQ6IHtcbiAgICAgICAgICAgIHByb2dyZXNzV2lkdGgoKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIFwid2lkdGg6IFwiK3RoaXMucHJvZ3Jlc3MuY3VycmVudFBlcmNlbnQqMTArJyUnO1xuICAgICAgICAgICAgfVxuICAgICAgICB9LFxuXG4gICAgICAgIGNvbXBvbmVudHM6IHtcbiAgICAgICAgICAgIGFsZXJ0OiByZXF1aXJlKCcuLi9hbGVydC52dWUnKSxcbiAgICAgICAgICAgIGVycm9yczogcmVxdWlyZSgnLi9pbXBvcnRlci1lcnJvcnMudnVlJyksXG4gICAgICAgICAgICBpbXBvcnRGaWxlOiByZXF1aXJlKCcuL2ltcG9ydGVyLWZpbGUudnVlJyksXG4gICAgICAgIH1cbiAgICB9XG5cbjwvc2NyaXB0PlxuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIGltcG9ydGVyLnZ1ZT8xMWQzZmQwZSIsIi8qXG4gKiBqUXVlcnkgRmlsZSBVcGxvYWQgUGx1Z2luXG4gKiBodHRwczovL2dpdGh1Yi5jb20vYmx1ZWltcC9qUXVlcnktRmlsZS1VcGxvYWRcbiAqXG4gKiBDb3B5cmlnaHQgMjAxMCwgU2ViYXN0aWFuIFRzY2hhblxuICogaHR0cHM6Ly9ibHVlaW1wLm5ldFxuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgbGljZW5zZTpcbiAqIGh0dHBzOi8vb3BlbnNvdXJjZS5vcmcvbGljZW5zZXMvTUlUXG4gKi9cblxuLyoganNoaW50IG5vbWVuOmZhbHNlICovXG4vKiBnbG9iYWwgZGVmaW5lLCByZXF1aXJlLCB3aW5kb3csIGRvY3VtZW50LCBsb2NhdGlvbiwgQmxvYiwgRm9ybURhdGEgKi9cblxuOyhmdW5jdGlvbiAoZmFjdG9yeSkge1xuICAgICd1c2Ugc3RyaWN0JztcbiAgICBpZiAodHlwZW9mIGRlZmluZSA9PT0gJ2Z1bmN0aW9uJyAmJiBkZWZpbmUuYW1kKSB7XG4gICAgICAgIC8vIFJlZ2lzdGVyIGFzIGFuIGFub255bW91cyBBTUQgbW9kdWxlOlxuICAgICAgICBkZWZpbmUoW1xuICAgICAgICAgICAgJ2pxdWVyeScsXG4gICAgICAgICAgICAnanF1ZXJ5LXVpL3VpL3dpZGdldCdcbiAgICAgICAgXSwgZmFjdG9yeSk7XG4gICAgfSBlbHNlIGlmICh0eXBlb2YgZXhwb3J0cyA9PT0gJ29iamVjdCcpIHtcbiAgICAgICAgLy8gTm9kZS9Db21tb25KUzpcbiAgICAgICAgZmFjdG9yeShcbiAgICAgICAgICAgIHJlcXVpcmUoJ2pxdWVyeScpLFxuICAgICAgICAgICAgcmVxdWlyZSgnLi92ZW5kb3IvanF1ZXJ5LnVpLndpZGdldCcpXG4gICAgICAgICk7XG4gICAgfSBlbHNlIHtcbiAgICAgICAgLy8gQnJvd3NlciBnbG9iYWxzOlxuICAgICAgICBmYWN0b3J5KHdpbmRvdy5qUXVlcnkpO1xuICAgIH1cbn0oZnVuY3Rpb24gKCQpIHtcbiAgICAndXNlIHN0cmljdCc7XG5cbiAgICAvLyBEZXRlY3QgZmlsZSBpbnB1dCBzdXBwb3J0LCBiYXNlZCBvblxuICAgIC8vIGh0dHA6Ly92aWxqYW1pcy5jb20vYmxvZy8yMDEyL2ZpbGUtdXBsb2FkLXN1cHBvcnQtb24tbW9iaWxlL1xuICAgICQuc3VwcG9ydC5maWxlSW5wdXQgPSAhKG5ldyBSZWdFeHAoXG4gICAgICAgIC8vIEhhbmRsZSBkZXZpY2VzIHdoaWNoIGdpdmUgZmFsc2UgcG9zaXRpdmVzIGZvciB0aGUgZmVhdHVyZSBkZXRlY3Rpb246XG4gICAgICAgICcoQW5kcm9pZCAoMVxcXFwuWzAxNTZdfDJcXFxcLlswMV0pKScgK1xuICAgICAgICAgICAgJ3woV2luZG93cyBQaG9uZSAoT1MgN3w4XFxcXC4wKSl8KFhCTFdQKXwoWnVuZVdQKXwoV1BEZXNrdG9wKScgK1xuICAgICAgICAgICAgJ3wodyhlYik/T1NCcm93c2VyKXwod2ViT1MpJyArXG4gICAgICAgICAgICAnfChLaW5kbGUvKDFcXFxcLjB8MlxcXFwuWzA1XXwzXFxcXC4wKSknXG4gICAgKS50ZXN0KHdpbmRvdy5uYXZpZ2F0b3IudXNlckFnZW50KSB8fFxuICAgICAgICAvLyBGZWF0dXJlIGRldGVjdGlvbiBmb3IgYWxsIG90aGVyIGRldmljZXM6XG4gICAgICAgICQoJzxpbnB1dCB0eXBlPVwiZmlsZVwiPicpLnByb3AoJ2Rpc2FibGVkJykpO1xuXG4gICAgLy8gVGhlIEZpbGVSZWFkZXIgQVBJIGlzIG5vdCBhY3R1YWxseSB1c2VkLCBidXQgd29ya3MgYXMgZmVhdHVyZSBkZXRlY3Rpb24sXG4gICAgLy8gYXMgc29tZSBTYWZhcmkgdmVyc2lvbnMgKDU/KSBzdXBwb3J0IFhIUiBmaWxlIHVwbG9hZHMgdmlhIHRoZSBGb3JtRGF0YSBBUEksXG4gICAgLy8gYnV0IG5vdCBub24tbXVsdGlwYXJ0IFhIUiBmaWxlIHVwbG9hZHMuXG4gICAgLy8gd2luZG93LlhNTEh0dHBSZXF1ZXN0VXBsb2FkIGlzIG5vdCBhdmFpbGFibGUgb24gSUUxMCwgc28gd2UgY2hlY2sgZm9yXG4gICAgLy8gd2luZG93LlByb2dyZXNzRXZlbnQgaW5zdGVhZCB0byBkZXRlY3QgWEhSMiBmaWxlIHVwbG9hZCBjYXBhYmlsaXR5OlxuICAgICQuc3VwcG9ydC54aHJGaWxlVXBsb2FkID0gISEod2luZG93LlByb2dyZXNzRXZlbnQgJiYgd2luZG93LkZpbGVSZWFkZXIpO1xuICAgICQuc3VwcG9ydC54aHJGb3JtRGF0YUZpbGVVcGxvYWQgPSAhIXdpbmRvdy5Gb3JtRGF0YTtcblxuICAgIC8vIERldGVjdCBzdXBwb3J0IGZvciBCbG9iIHNsaWNpbmcgKHJlcXVpcmVkIGZvciBjaHVua2VkIHVwbG9hZHMpOlxuICAgICQuc3VwcG9ydC5ibG9iU2xpY2UgPSB3aW5kb3cuQmxvYiAmJiAoQmxvYi5wcm90b3R5cGUuc2xpY2UgfHxcbiAgICAgICAgQmxvYi5wcm90b3R5cGUud2Via2l0U2xpY2UgfHwgQmxvYi5wcm90b3R5cGUubW96U2xpY2UpO1xuXG4gICAgLy8gSGVscGVyIGZ1bmN0aW9uIHRvIGNyZWF0ZSBkcmFnIGhhbmRsZXJzIGZvciBkcmFnb3Zlci9kcmFnZW50ZXIvZHJhZ2xlYXZlOlxuICAgIGZ1bmN0aW9uIGdldERyYWdIYW5kbGVyKHR5cGUpIHtcbiAgICAgICAgdmFyIGlzRHJhZ092ZXIgPSB0eXBlID09PSAnZHJhZ292ZXInO1xuICAgICAgICByZXR1cm4gZnVuY3Rpb24gKGUpIHtcbiAgICAgICAgICAgIGUuZGF0YVRyYW5zZmVyID0gZS5vcmlnaW5hbEV2ZW50ICYmIGUub3JpZ2luYWxFdmVudC5kYXRhVHJhbnNmZXI7XG4gICAgICAgICAgICB2YXIgZGF0YVRyYW5zZmVyID0gZS5kYXRhVHJhbnNmZXI7XG4gICAgICAgICAgICBpZiAoZGF0YVRyYW5zZmVyICYmICQuaW5BcnJheSgnRmlsZXMnLCBkYXRhVHJhbnNmZXIudHlwZXMpICE9PSAtMSAmJlxuICAgICAgICAgICAgICAgICAgICB0aGlzLl90cmlnZ2VyKFxuICAgICAgICAgICAgICAgICAgICAgICAgdHlwZSxcbiAgICAgICAgICAgICAgICAgICAgICAgICQuRXZlbnQodHlwZSwge2RlbGVnYXRlZEV2ZW50OiBlfSlcbiAgICAgICAgICAgICAgICAgICAgKSAhPT0gZmFsc2UpIHtcbiAgICAgICAgICAgICAgICBlLnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgICAgICAgICAgaWYgKGlzRHJhZ092ZXIpIHtcbiAgICAgICAgICAgICAgICAgICAgZGF0YVRyYW5zZmVyLmRyb3BFZmZlY3QgPSAnY29weSc7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuICAgIH1cblxuICAgIC8vIFRoZSBmaWxldXBsb2FkIHdpZGdldCBsaXN0ZW5zIGZvciBjaGFuZ2UgZXZlbnRzIG9uIGZpbGUgaW5wdXQgZmllbGRzIGRlZmluZWRcbiAgICAvLyB2aWEgZmlsZUlucHV0IHNldHRpbmcgYW5kIHBhc3RlIG9yIGRyb3AgZXZlbnRzIG9mIHRoZSBnaXZlbiBkcm9wWm9uZS5cbiAgICAvLyBJbiBhZGRpdGlvbiB0byB0aGUgZGVmYXVsdCBqUXVlcnkgV2lkZ2V0IG1ldGhvZHMsIHRoZSBmaWxldXBsb2FkIHdpZGdldFxuICAgIC8vIGV4cG9zZXMgdGhlIFwiYWRkXCIgYW5kIFwic2VuZFwiIG1ldGhvZHMsIHRvIGFkZCBvciBkaXJlY3RseSBzZW5kIGZpbGVzIHVzaW5nXG4gICAgLy8gdGhlIGZpbGV1cGxvYWQgQVBJLlxuICAgIC8vIEJ5IGRlZmF1bHQsIGZpbGVzIGFkZGVkIHZpYSBmaWxlIGlucHV0IHNlbGVjdGlvbiwgcGFzdGUsIGRyYWcgJiBkcm9wIG9yXG4gICAgLy8gXCJhZGRcIiBtZXRob2QgYXJlIHVwbG9hZGVkIGltbWVkaWF0ZWx5LCBidXQgaXQgaXMgcG9zc2libGUgdG8gb3ZlcnJpZGVcbiAgICAvLyB0aGUgXCJhZGRcIiBjYWxsYmFjayBvcHRpb24gdG8gcXVldWUgZmlsZSB1cGxvYWRzLlxuICAgICQud2lkZ2V0KCdibHVlaW1wLmZpbGV1cGxvYWQnLCB7XG5cbiAgICAgICAgb3B0aW9uczoge1xuICAgICAgICAgICAgLy8gVGhlIGRyb3AgdGFyZ2V0IGVsZW1lbnQocyksIGJ5IHRoZSBkZWZhdWx0IHRoZSBjb21wbGV0ZSBkb2N1bWVudC5cbiAgICAgICAgICAgIC8vIFNldCB0byBudWxsIHRvIGRpc2FibGUgZHJhZyAmIGRyb3Agc3VwcG9ydDpcbiAgICAgICAgICAgIGRyb3Bab25lOiAkKGRvY3VtZW50KSxcbiAgICAgICAgICAgIC8vIFRoZSBwYXN0ZSB0YXJnZXQgZWxlbWVudChzKSwgYnkgdGhlIGRlZmF1bHQgdW5kZWZpbmVkLlxuICAgICAgICAgICAgLy8gU2V0IHRvIGEgRE9NIG5vZGUgb3IgalF1ZXJ5IG9iamVjdCB0byBlbmFibGUgZmlsZSBwYXN0aW5nOlxuICAgICAgICAgICAgcGFzdGVab25lOiB1bmRlZmluZWQsXG4gICAgICAgICAgICAvLyBUaGUgZmlsZSBpbnB1dCBmaWVsZChzKSwgdGhhdCBhcmUgbGlzdGVuZWQgdG8gZm9yIGNoYW5nZSBldmVudHMuXG4gICAgICAgICAgICAvLyBJZiB1bmRlZmluZWQsIGl0IGlzIHNldCB0byB0aGUgZmlsZSBpbnB1dCBmaWVsZHMgaW5zaWRlXG4gICAgICAgICAgICAvLyBvZiB0aGUgd2lkZ2V0IGVsZW1lbnQgb24gcGx1Z2luIGluaXRpYWxpemF0aW9uLlxuICAgICAgICAgICAgLy8gU2V0IHRvIG51bGwgdG8gZGlzYWJsZSB0aGUgY2hhbmdlIGxpc3RlbmVyLlxuICAgICAgICAgICAgZmlsZUlucHV0OiB1bmRlZmluZWQsXG4gICAgICAgICAgICAvLyBCeSBkZWZhdWx0LCB0aGUgZmlsZSBpbnB1dCBmaWVsZCBpcyByZXBsYWNlZCB3aXRoIGEgY2xvbmUgYWZ0ZXJcbiAgICAgICAgICAgIC8vIGVhY2ggaW5wdXQgZmllbGQgY2hhbmdlIGV2ZW50LiBUaGlzIGlzIHJlcXVpcmVkIGZvciBpZnJhbWUgdHJhbnNwb3J0XG4gICAgICAgICAgICAvLyBxdWV1ZXMgYW5kIGFsbG93cyBjaGFuZ2UgZXZlbnRzIHRvIGJlIGZpcmVkIGZvciB0aGUgc2FtZSBmaWxlXG4gICAgICAgICAgICAvLyBzZWxlY3Rpb24sIGJ1dCBjYW4gYmUgZGlzYWJsZWQgYnkgc2V0dGluZyB0aGUgZm9sbG93aW5nIG9wdGlvbiB0byBmYWxzZTpcbiAgICAgICAgICAgIHJlcGxhY2VGaWxlSW5wdXQ6IHRydWUsXG4gICAgICAgICAgICAvLyBUaGUgcGFyYW1ldGVyIG5hbWUgZm9yIHRoZSBmaWxlIGZvcm0gZGF0YSAodGhlIHJlcXVlc3QgYXJndW1lbnQgbmFtZSkuXG4gICAgICAgICAgICAvLyBJZiB1bmRlZmluZWQgb3IgZW1wdHksIHRoZSBuYW1lIHByb3BlcnR5IG9mIHRoZSBmaWxlIGlucHV0IGZpZWxkIGlzXG4gICAgICAgICAgICAvLyB1c2VkLCBvciBcImZpbGVzW11cIiBpZiB0aGUgZmlsZSBpbnB1dCBuYW1lIHByb3BlcnR5IGlzIGFsc28gZW1wdHksXG4gICAgICAgICAgICAvLyBjYW4gYmUgYSBzdHJpbmcgb3IgYW4gYXJyYXkgb2Ygc3RyaW5nczpcbiAgICAgICAgICAgIHBhcmFtTmFtZTogdW5kZWZpbmVkLFxuICAgICAgICAgICAgLy8gQnkgZGVmYXVsdCwgZWFjaCBmaWxlIG9mIGEgc2VsZWN0aW9uIGlzIHVwbG9hZGVkIHVzaW5nIGFuIGluZGl2aWR1YWxcbiAgICAgICAgICAgIC8vIHJlcXVlc3QgZm9yIFhIUiB0eXBlIHVwbG9hZHMuIFNldCB0byBmYWxzZSB0byB1cGxvYWQgZmlsZVxuICAgICAgICAgICAgLy8gc2VsZWN0aW9ucyBpbiBvbmUgcmVxdWVzdCBlYWNoOlxuICAgICAgICAgICAgc2luZ2xlRmlsZVVwbG9hZHM6IHRydWUsXG4gICAgICAgICAgICAvLyBUbyBsaW1pdCB0aGUgbnVtYmVyIG9mIGZpbGVzIHVwbG9hZGVkIHdpdGggb25lIFhIUiByZXF1ZXN0LFxuICAgICAgICAgICAgLy8gc2V0IHRoZSBmb2xsb3dpbmcgb3B0aW9uIHRvIGFuIGludGVnZXIgZ3JlYXRlciB0aGFuIDA6XG4gICAgICAgICAgICBsaW1pdE11bHRpRmlsZVVwbG9hZHM6IHVuZGVmaW5lZCxcbiAgICAgICAgICAgIC8vIFRoZSBmb2xsb3dpbmcgb3B0aW9uIGxpbWl0cyB0aGUgbnVtYmVyIG9mIGZpbGVzIHVwbG9hZGVkIHdpdGggb25lXG4gICAgICAgICAgICAvLyBYSFIgcmVxdWVzdCB0byBrZWVwIHRoZSByZXF1ZXN0IHNpemUgdW5kZXIgb3IgZXF1YWwgdG8gdGhlIGRlZmluZWRcbiAgICAgICAgICAgIC8vIGxpbWl0IGluIGJ5dGVzOlxuICAgICAgICAgICAgbGltaXRNdWx0aUZpbGVVcGxvYWRTaXplOiB1bmRlZmluZWQsXG4gICAgICAgICAgICAvLyBNdWx0aXBhcnQgZmlsZSB1cGxvYWRzIGFkZCBhIG51bWJlciBvZiBieXRlcyB0byBlYWNoIHVwbG9hZGVkIGZpbGUsXG4gICAgICAgICAgICAvLyB0aGVyZWZvcmUgdGhlIGZvbGxvd2luZyBvcHRpb24gYWRkcyBhbiBvdmVyaGVhZCBmb3IgZWFjaCBmaWxlIHVzZWRcbiAgICAgICAgICAgIC8vIGluIHRoZSBsaW1pdE11bHRpRmlsZVVwbG9hZFNpemUgY29uZmlndXJhdGlvbjpcbiAgICAgICAgICAgIGxpbWl0TXVsdGlGaWxlVXBsb2FkU2l6ZU92ZXJoZWFkOiA1MTIsXG4gICAgICAgICAgICAvLyBTZXQgdGhlIGZvbGxvd2luZyBvcHRpb24gdG8gdHJ1ZSB0byBpc3N1ZSBhbGwgZmlsZSB1cGxvYWQgcmVxdWVzdHNcbiAgICAgICAgICAgIC8vIGluIGEgc2VxdWVudGlhbCBvcmRlcjpcbiAgICAgICAgICAgIHNlcXVlbnRpYWxVcGxvYWRzOiBmYWxzZSxcbiAgICAgICAgICAgIC8vIFRvIGxpbWl0IHRoZSBudW1iZXIgb2YgY29uY3VycmVudCB1cGxvYWRzLFxuICAgICAgICAgICAgLy8gc2V0IHRoZSBmb2xsb3dpbmcgb3B0aW9uIHRvIGFuIGludGVnZXIgZ3JlYXRlciB0aGFuIDA6XG4gICAgICAgICAgICBsaW1pdENvbmN1cnJlbnRVcGxvYWRzOiB1bmRlZmluZWQsXG4gICAgICAgICAgICAvLyBTZXQgdGhlIGZvbGxvd2luZyBvcHRpb24gdG8gdHJ1ZSB0byBmb3JjZSBpZnJhbWUgdHJhbnNwb3J0IHVwbG9hZHM6XG4gICAgICAgICAgICBmb3JjZUlmcmFtZVRyYW5zcG9ydDogZmFsc2UsXG4gICAgICAgICAgICAvLyBTZXQgdGhlIGZvbGxvd2luZyBvcHRpb24gdG8gdGhlIGxvY2F0aW9uIG9mIGEgcmVkaXJlY3QgdXJsIG9uIHRoZVxuICAgICAgICAgICAgLy8gb3JpZ2luIHNlcnZlciwgZm9yIGNyb3NzLWRvbWFpbiBpZnJhbWUgdHJhbnNwb3J0IHVwbG9hZHM6XG4gICAgICAgICAgICByZWRpcmVjdDogdW5kZWZpbmVkLFxuICAgICAgICAgICAgLy8gVGhlIHBhcmFtZXRlciBuYW1lIGZvciB0aGUgcmVkaXJlY3QgdXJsLCBzZW50IGFzIHBhcnQgb2YgdGhlIGZvcm1cbiAgICAgICAgICAgIC8vIGRhdGEgYW5kIHNldCB0byAncmVkaXJlY3QnIGlmIHRoaXMgb3B0aW9uIGlzIGVtcHR5OlxuICAgICAgICAgICAgcmVkaXJlY3RQYXJhbU5hbWU6IHVuZGVmaW5lZCxcbiAgICAgICAgICAgIC8vIFNldCB0aGUgZm9sbG93aW5nIG9wdGlvbiB0byB0aGUgbG9jYXRpb24gb2YgYSBwb3N0TWVzc2FnZSB3aW5kb3csXG4gICAgICAgICAgICAvLyB0byBlbmFibGUgcG9zdE1lc3NhZ2UgdHJhbnNwb3J0IHVwbG9hZHM6XG4gICAgICAgICAgICBwb3N0TWVzc2FnZTogdW5kZWZpbmVkLFxuICAgICAgICAgICAgLy8gQnkgZGVmYXVsdCwgWEhSIGZpbGUgdXBsb2FkcyBhcmUgc2VudCBhcyBtdWx0aXBhcnQvZm9ybS1kYXRhLlxuICAgICAgICAgICAgLy8gVGhlIGlmcmFtZSB0cmFuc3BvcnQgaXMgYWx3YXlzIHVzaW5nIG11bHRpcGFydC9mb3JtLWRhdGEuXG4gICAgICAgICAgICAvLyBTZXQgdG8gZmFsc2UgdG8gZW5hYmxlIG5vbi1tdWx0aXBhcnQgWEhSIHVwbG9hZHM6XG4gICAgICAgICAgICBtdWx0aXBhcnQ6IHRydWUsXG4gICAgICAgICAgICAvLyBUbyB1cGxvYWQgbGFyZ2UgZmlsZXMgaW4gc21hbGxlciBjaHVua3MsIHNldCB0aGUgZm9sbG93aW5nIG9wdGlvblxuICAgICAgICAgICAgLy8gdG8gYSBwcmVmZXJyZWQgbWF4aW11bSBjaHVuayBzaXplLiBJZiBzZXQgdG8gMCwgbnVsbCBvciB1bmRlZmluZWQsXG4gICAgICAgICAgICAvLyBvciB0aGUgYnJvd3NlciBkb2VzIG5vdCBzdXBwb3J0IHRoZSByZXF1aXJlZCBCbG9iIEFQSSwgZmlsZXMgd2lsbFxuICAgICAgICAgICAgLy8gYmUgdXBsb2FkZWQgYXMgYSB3aG9sZS5cbiAgICAgICAgICAgIG1heENodW5rU2l6ZTogdW5kZWZpbmVkLFxuICAgICAgICAgICAgLy8gV2hlbiBhIG5vbi1tdWx0aXBhcnQgdXBsb2FkIG9yIGEgY2h1bmtlZCBtdWx0aXBhcnQgdXBsb2FkIGhhcyBiZWVuXG4gICAgICAgICAgICAvLyBhYm9ydGVkLCB0aGlzIG9wdGlvbiBjYW4gYmUgdXNlZCB0byByZXN1bWUgdGhlIHVwbG9hZCBieSBzZXR0aW5nXG4gICAgICAgICAgICAvLyBpdCB0byB0aGUgc2l6ZSBvZiB0aGUgYWxyZWFkeSB1cGxvYWRlZCBieXRlcy4gVGhpcyBvcHRpb24gaXMgbW9zdFxuICAgICAgICAgICAgLy8gdXNlZnVsIHdoZW4gbW9kaWZ5aW5nIHRoZSBvcHRpb25zIG9iamVjdCBpbnNpZGUgb2YgdGhlIFwiYWRkXCIgb3JcbiAgICAgICAgICAgIC8vIFwic2VuZFwiIGNhbGxiYWNrcywgYXMgdGhlIG9wdGlvbnMgYXJlIGNsb25lZCBmb3IgZWFjaCBmaWxlIHVwbG9hZC5cbiAgICAgICAgICAgIHVwbG9hZGVkQnl0ZXM6IHVuZGVmaW5lZCxcbiAgICAgICAgICAgIC8vIEJ5IGRlZmF1bHQsIGZhaWxlZCAoYWJvcnQgb3IgZXJyb3IpIGZpbGUgdXBsb2FkcyBhcmUgcmVtb3ZlZCBmcm9tIHRoZVxuICAgICAgICAgICAgLy8gZ2xvYmFsIHByb2dyZXNzIGNhbGN1bGF0aW9uLiBTZXQgdGhlIGZvbGxvd2luZyBvcHRpb24gdG8gZmFsc2UgdG9cbiAgICAgICAgICAgIC8vIHByZXZlbnQgcmVjYWxjdWxhdGluZyB0aGUgZ2xvYmFsIHByb2dyZXNzIGRhdGE6XG4gICAgICAgICAgICByZWNhbGN1bGF0ZVByb2dyZXNzOiB0cnVlLFxuICAgICAgICAgICAgLy8gSW50ZXJ2YWwgaW4gbWlsbGlzZWNvbmRzIHRvIGNhbGN1bGF0ZSBhbmQgdHJpZ2dlciBwcm9ncmVzcyBldmVudHM6XG4gICAgICAgICAgICBwcm9ncmVzc0ludGVydmFsOiAxMDAsXG4gICAgICAgICAgICAvLyBJbnRlcnZhbCBpbiBtaWxsaXNlY29uZHMgdG8gY2FsY3VsYXRlIHByb2dyZXNzIGJpdHJhdGU6XG4gICAgICAgICAgICBiaXRyYXRlSW50ZXJ2YWw6IDUwMCxcbiAgICAgICAgICAgIC8vIEJ5IGRlZmF1bHQsIHVwbG9hZHMgYXJlIHN0YXJ0ZWQgYXV0b21hdGljYWxseSB3aGVuIGFkZGluZyBmaWxlczpcbiAgICAgICAgICAgIGF1dG9VcGxvYWQ6IHRydWUsXG5cbiAgICAgICAgICAgIC8vIEVycm9yIGFuZCBpbmZvIG1lc3NhZ2VzOlxuICAgICAgICAgICAgbWVzc2FnZXM6IHtcbiAgICAgICAgICAgICAgICB1cGxvYWRlZEJ5dGVzOiAnVXBsb2FkZWQgYnl0ZXMgZXhjZWVkIGZpbGUgc2l6ZSdcbiAgICAgICAgICAgIH0sXG5cbiAgICAgICAgICAgIC8vIFRyYW5zbGF0aW9uIGZ1bmN0aW9uLCBnZXRzIHRoZSBtZXNzYWdlIGtleSB0byBiZSB0cmFuc2xhdGVkXG4gICAgICAgICAgICAvLyBhbmQgYW4gb2JqZWN0IHdpdGggY29udGV4dCBzcGVjaWZpYyBkYXRhIGFzIGFyZ3VtZW50czpcbiAgICAgICAgICAgIGkxOG46IGZ1bmN0aW9uIChtZXNzYWdlLCBjb250ZXh0KSB7XG4gICAgICAgICAgICAgICAgbWVzc2FnZSA9IHRoaXMubWVzc2FnZXNbbWVzc2FnZV0gfHwgbWVzc2FnZS50b1N0cmluZygpO1xuICAgICAgICAgICAgICAgIGlmIChjb250ZXh0KSB7XG4gICAgICAgICAgICAgICAgICAgICQuZWFjaChjb250ZXh0LCBmdW5jdGlvbiAoa2V5LCB2YWx1ZSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgbWVzc2FnZSA9IG1lc3NhZ2UucmVwbGFjZSgneycgKyBrZXkgKyAnfScsIHZhbHVlKTtcbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHJldHVybiBtZXNzYWdlO1xuICAgICAgICAgICAgfSxcblxuICAgICAgICAgICAgLy8gQWRkaXRpb25hbCBmb3JtIGRhdGEgdG8gYmUgc2VudCBhbG9uZyB3aXRoIHRoZSBmaWxlIHVwbG9hZHMgY2FuIGJlIHNldFxuICAgICAgICAgICAgLy8gdXNpbmcgdGhpcyBvcHRpb24sIHdoaWNoIGFjY2VwdHMgYW4gYXJyYXkgb2Ygb2JqZWN0cyB3aXRoIG5hbWUgYW5kXG4gICAgICAgICAgICAvLyB2YWx1ZSBwcm9wZXJ0aWVzLCBhIGZ1bmN0aW9uIHJldHVybmluZyBzdWNoIGFuIGFycmF5LCBhIEZvcm1EYXRhXG4gICAgICAgICAgICAvLyBvYmplY3QgKGZvciBYSFIgZmlsZSB1cGxvYWRzKSwgb3IgYSBzaW1wbGUgb2JqZWN0LlxuICAgICAgICAgICAgLy8gVGhlIGZvcm0gb2YgdGhlIGZpcnN0IGZpbGVJbnB1dCBpcyBnaXZlbiBhcyBwYXJhbWV0ZXIgdG8gdGhlIGZ1bmN0aW9uOlxuICAgICAgICAgICAgZm9ybURhdGE6IGZ1bmN0aW9uIChmb3JtKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGZvcm0uc2VyaWFsaXplQXJyYXkoKTtcbiAgICAgICAgICAgIH0sXG5cbiAgICAgICAgICAgIC8vIFRoZSBhZGQgY2FsbGJhY2sgaXMgaW52b2tlZCBhcyBzb29uIGFzIGZpbGVzIGFyZSBhZGRlZCB0byB0aGUgZmlsZXVwbG9hZFxuICAgICAgICAgICAgLy8gd2lkZ2V0ICh2aWEgZmlsZSBpbnB1dCBzZWxlY3Rpb24sIGRyYWcgJiBkcm9wLCBwYXN0ZSBvciBhZGQgQVBJIGNhbGwpLlxuICAgICAgICAgICAgLy8gSWYgdGhlIHNpbmdsZUZpbGVVcGxvYWRzIG9wdGlvbiBpcyBlbmFibGVkLCB0aGlzIGNhbGxiYWNrIHdpbGwgYmVcbiAgICAgICAgICAgIC8vIGNhbGxlZCBvbmNlIGZvciBlYWNoIGZpbGUgaW4gdGhlIHNlbGVjdGlvbiBmb3IgWEhSIGZpbGUgdXBsb2FkcywgZWxzZVxuICAgICAgICAgICAgLy8gb25jZSBmb3IgZWFjaCBmaWxlIHNlbGVjdGlvbi5cbiAgICAgICAgICAgIC8vXG4gICAgICAgICAgICAvLyBUaGUgdXBsb2FkIHN0YXJ0cyB3aGVuIHRoZSBzdWJtaXQgbWV0aG9kIGlzIGludm9rZWQgb24gdGhlIGRhdGEgcGFyYW1ldGVyLlxuICAgICAgICAgICAgLy8gVGhlIGRhdGEgb2JqZWN0IGNvbnRhaW5zIGEgZmlsZXMgcHJvcGVydHkgaG9sZGluZyB0aGUgYWRkZWQgZmlsZXNcbiAgICAgICAgICAgIC8vIGFuZCBhbGxvd3MgeW91IHRvIG92ZXJyaWRlIHBsdWdpbiBvcHRpb25zIGFzIHdlbGwgYXMgZGVmaW5lIGFqYXggc2V0dGluZ3MuXG4gICAgICAgICAgICAvL1xuICAgICAgICAgICAgLy8gTGlzdGVuZXJzIGZvciB0aGlzIGNhbGxiYWNrIGNhbiBhbHNvIGJlIGJvdW5kIHRoZSBmb2xsb3dpbmcgd2F5OlxuICAgICAgICAgICAgLy8gLmJpbmQoJ2ZpbGV1cGxvYWRhZGQnLCBmdW5jKTtcbiAgICAgICAgICAgIC8vXG4gICAgICAgICAgICAvLyBkYXRhLnN1Ym1pdCgpIHJldHVybnMgYSBQcm9taXNlIG9iamVjdCBhbmQgYWxsb3dzIHRvIGF0dGFjaCBhZGRpdGlvbmFsXG4gICAgICAgICAgICAvLyBoYW5kbGVycyB1c2luZyBqUXVlcnkncyBEZWZlcnJlZCBjYWxsYmFja3M6XG4gICAgICAgICAgICAvLyBkYXRhLnN1Ym1pdCgpLmRvbmUoZnVuYykuZmFpbChmdW5jKS5hbHdheXMoZnVuYyk7XG4gICAgICAgICAgICBhZGQ6IGZ1bmN0aW9uIChlLCBkYXRhKSB7XG4gICAgICAgICAgICAgICAgaWYgKGUuaXNEZWZhdWx0UHJldmVudGVkKCkpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpZiAoZGF0YS5hdXRvVXBsb2FkIHx8IChkYXRhLmF1dG9VcGxvYWQgIT09IGZhbHNlICYmXG4gICAgICAgICAgICAgICAgICAgICAgICAkKHRoaXMpLmZpbGV1cGxvYWQoJ29wdGlvbicsICdhdXRvVXBsb2FkJykpKSB7XG4gICAgICAgICAgICAgICAgICAgIGRhdGEucHJvY2VzcygpLmRvbmUoZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgZGF0YS5zdWJtaXQoKTtcbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSxcblxuICAgICAgICAgICAgLy8gT3RoZXIgY2FsbGJhY2tzOlxuXG4gICAgICAgICAgICAvLyBDYWxsYmFjayBmb3IgdGhlIHN1Ym1pdCBldmVudCBvZiBlYWNoIGZpbGUgdXBsb2FkOlxuICAgICAgICAgICAgLy8gc3VibWl0OiBmdW5jdGlvbiAoZSwgZGF0YSkge30sIC8vIC5iaW5kKCdmaWxldXBsb2Fkc3VibWl0JywgZnVuYyk7XG5cbiAgICAgICAgICAgIC8vIENhbGxiYWNrIGZvciB0aGUgc3RhcnQgb2YgZWFjaCBmaWxlIHVwbG9hZCByZXF1ZXN0OlxuICAgICAgICAgICAgLy8gc2VuZDogZnVuY3Rpb24gKGUsIGRhdGEpIHt9LCAvLyAuYmluZCgnZmlsZXVwbG9hZHNlbmQnLCBmdW5jKTtcblxuICAgICAgICAgICAgLy8gQ2FsbGJhY2sgZm9yIHN1Y2Nlc3NmdWwgdXBsb2FkczpcbiAgICAgICAgICAgIC8vIGRvbmU6IGZ1bmN0aW9uIChlLCBkYXRhKSB7fSwgLy8gLmJpbmQoJ2ZpbGV1cGxvYWRkb25lJywgZnVuYyk7XG5cbiAgICAgICAgICAgIC8vIENhbGxiYWNrIGZvciBmYWlsZWQgKGFib3J0IG9yIGVycm9yKSB1cGxvYWRzOlxuICAgICAgICAgICAgLy8gZmFpbDogZnVuY3Rpb24gKGUsIGRhdGEpIHt9LCAvLyAuYmluZCgnZmlsZXVwbG9hZGZhaWwnLCBmdW5jKTtcblxuICAgICAgICAgICAgLy8gQ2FsbGJhY2sgZm9yIGNvbXBsZXRlZCAoc3VjY2VzcywgYWJvcnQgb3IgZXJyb3IpIHJlcXVlc3RzOlxuICAgICAgICAgICAgLy8gYWx3YXlzOiBmdW5jdGlvbiAoZSwgZGF0YSkge30sIC8vIC5iaW5kKCdmaWxldXBsb2FkYWx3YXlzJywgZnVuYyk7XG5cbiAgICAgICAgICAgIC8vIENhbGxiYWNrIGZvciB1cGxvYWQgcHJvZ3Jlc3MgZXZlbnRzOlxuICAgICAgICAgICAgLy8gcHJvZ3Jlc3M6IGZ1bmN0aW9uIChlLCBkYXRhKSB7fSwgLy8gLmJpbmQoJ2ZpbGV1cGxvYWRwcm9ncmVzcycsIGZ1bmMpO1xuXG4gICAgICAgICAgICAvLyBDYWxsYmFjayBmb3IgZ2xvYmFsIHVwbG9hZCBwcm9ncmVzcyBldmVudHM6XG4gICAgICAgICAgICAvLyBwcm9ncmVzc2FsbDogZnVuY3Rpb24gKGUsIGRhdGEpIHt9LCAvLyAuYmluZCgnZmlsZXVwbG9hZHByb2dyZXNzYWxsJywgZnVuYyk7XG5cbiAgICAgICAgICAgIC8vIENhbGxiYWNrIGZvciB1cGxvYWRzIHN0YXJ0LCBlcXVpdmFsZW50IHRvIHRoZSBnbG9iYWwgYWpheFN0YXJ0IGV2ZW50OlxuICAgICAgICAgICAgLy8gc3RhcnQ6IGZ1bmN0aW9uIChlKSB7fSwgLy8gLmJpbmQoJ2ZpbGV1cGxvYWRzdGFydCcsIGZ1bmMpO1xuXG4gICAgICAgICAgICAvLyBDYWxsYmFjayBmb3IgdXBsb2FkcyBzdG9wLCBlcXVpdmFsZW50IHRvIHRoZSBnbG9iYWwgYWpheFN0b3AgZXZlbnQ6XG4gICAgICAgICAgICAvLyBzdG9wOiBmdW5jdGlvbiAoZSkge30sIC8vIC5iaW5kKCdmaWxldXBsb2Fkc3RvcCcsIGZ1bmMpO1xuXG4gICAgICAgICAgICAvLyBDYWxsYmFjayBmb3IgY2hhbmdlIGV2ZW50cyBvZiB0aGUgZmlsZUlucHV0KHMpOlxuICAgICAgICAgICAgLy8gY2hhbmdlOiBmdW5jdGlvbiAoZSwgZGF0YSkge30sIC8vIC5iaW5kKCdmaWxldXBsb2FkY2hhbmdlJywgZnVuYyk7XG5cbiAgICAgICAgICAgIC8vIENhbGxiYWNrIGZvciBwYXN0ZSBldmVudHMgdG8gdGhlIHBhc3RlWm9uZShzKTpcbiAgICAgICAgICAgIC8vIHBhc3RlOiBmdW5jdGlvbiAoZSwgZGF0YSkge30sIC8vIC5iaW5kKCdmaWxldXBsb2FkcGFzdGUnLCBmdW5jKTtcblxuICAgICAgICAgICAgLy8gQ2FsbGJhY2sgZm9yIGRyb3AgZXZlbnRzIG9mIHRoZSBkcm9wWm9uZShzKTpcbiAgICAgICAgICAgIC8vIGRyb3A6IGZ1bmN0aW9uIChlLCBkYXRhKSB7fSwgLy8gLmJpbmQoJ2ZpbGV1cGxvYWRkcm9wJywgZnVuYyk7XG5cbiAgICAgICAgICAgIC8vIENhbGxiYWNrIGZvciBkcmFnb3ZlciBldmVudHMgb2YgdGhlIGRyb3Bab25lKHMpOlxuICAgICAgICAgICAgLy8gZHJhZ292ZXI6IGZ1bmN0aW9uIChlKSB7fSwgLy8gLmJpbmQoJ2ZpbGV1cGxvYWRkcmFnb3ZlcicsIGZ1bmMpO1xuXG4gICAgICAgICAgICAvLyBDYWxsYmFjayBmb3IgdGhlIHN0YXJ0IG9mIGVhY2ggY2h1bmsgdXBsb2FkIHJlcXVlc3Q6XG4gICAgICAgICAgICAvLyBjaHVua3NlbmQ6IGZ1bmN0aW9uIChlLCBkYXRhKSB7fSwgLy8gLmJpbmQoJ2ZpbGV1cGxvYWRjaHVua3NlbmQnLCBmdW5jKTtcblxuICAgICAgICAgICAgLy8gQ2FsbGJhY2sgZm9yIHN1Y2Nlc3NmdWwgY2h1bmsgdXBsb2FkczpcbiAgICAgICAgICAgIC8vIGNodW5rZG9uZTogZnVuY3Rpb24gKGUsIGRhdGEpIHt9LCAvLyAuYmluZCgnZmlsZXVwbG9hZGNodW5rZG9uZScsIGZ1bmMpO1xuXG4gICAgICAgICAgICAvLyBDYWxsYmFjayBmb3IgZmFpbGVkIChhYm9ydCBvciBlcnJvcikgY2h1bmsgdXBsb2FkczpcbiAgICAgICAgICAgIC8vIGNodW5rZmFpbDogZnVuY3Rpb24gKGUsIGRhdGEpIHt9LCAvLyAuYmluZCgnZmlsZXVwbG9hZGNodW5rZmFpbCcsIGZ1bmMpO1xuXG4gICAgICAgICAgICAvLyBDYWxsYmFjayBmb3IgY29tcGxldGVkIChzdWNjZXNzLCBhYm9ydCBvciBlcnJvcikgY2h1bmsgdXBsb2FkIHJlcXVlc3RzOlxuICAgICAgICAgICAgLy8gY2h1bmthbHdheXM6IGZ1bmN0aW9uIChlLCBkYXRhKSB7fSwgLy8gLmJpbmQoJ2ZpbGV1cGxvYWRjaHVua2Fsd2F5cycsIGZ1bmMpO1xuXG4gICAgICAgICAgICAvLyBUaGUgcGx1Z2luIG9wdGlvbnMgYXJlIHVzZWQgYXMgc2V0dGluZ3Mgb2JqZWN0IGZvciB0aGUgYWpheCBjYWxscy5cbiAgICAgICAgICAgIC8vIFRoZSBmb2xsb3dpbmcgYXJlIGpRdWVyeSBhamF4IHNldHRpbmdzIHJlcXVpcmVkIGZvciB0aGUgZmlsZSB1cGxvYWRzOlxuICAgICAgICAgICAgcHJvY2Vzc0RhdGE6IGZhbHNlLFxuICAgICAgICAgICAgY29udGVudFR5cGU6IGZhbHNlLFxuICAgICAgICAgICAgY2FjaGU6IGZhbHNlLFxuICAgICAgICAgICAgdGltZW91dDogMFxuICAgICAgICB9LFxuXG4gICAgICAgIC8vIEEgbGlzdCBvZiBvcHRpb25zIHRoYXQgcmVxdWlyZSByZWluaXRpYWxpemluZyBldmVudCBsaXN0ZW5lcnMgYW5kL29yXG4gICAgICAgIC8vIHNwZWNpYWwgaW5pdGlhbGl6YXRpb24gY29kZTpcbiAgICAgICAgX3NwZWNpYWxPcHRpb25zOiBbXG4gICAgICAgICAgICAnZmlsZUlucHV0JyxcbiAgICAgICAgICAgICdkcm9wWm9uZScsXG4gICAgICAgICAgICAncGFzdGVab25lJyxcbiAgICAgICAgICAgICdtdWx0aXBhcnQnLFxuICAgICAgICAgICAgJ2ZvcmNlSWZyYW1lVHJhbnNwb3J0J1xuICAgICAgICBdLFxuXG4gICAgICAgIF9ibG9iU2xpY2U6ICQuc3VwcG9ydC5ibG9iU2xpY2UgJiYgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgdmFyIHNsaWNlID0gdGhpcy5zbGljZSB8fCB0aGlzLndlYmtpdFNsaWNlIHx8IHRoaXMubW96U2xpY2U7XG4gICAgICAgICAgICByZXR1cm4gc2xpY2UuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICAgICAgfSxcblxuICAgICAgICBfQml0cmF0ZVRpbWVyOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICB0aGlzLnRpbWVzdGFtcCA9ICgoRGF0ZS5ub3cpID8gRGF0ZS5ub3coKSA6IChuZXcgRGF0ZSgpKS5nZXRUaW1lKCkpO1xuICAgICAgICAgICAgdGhpcy5sb2FkZWQgPSAwO1xuICAgICAgICAgICAgdGhpcy5iaXRyYXRlID0gMDtcbiAgICAgICAgICAgIHRoaXMuZ2V0Qml0cmF0ZSA9IGZ1bmN0aW9uIChub3csIGxvYWRlZCwgaW50ZXJ2YWwpIHtcbiAgICAgICAgICAgICAgICB2YXIgdGltZURpZmYgPSBub3cgLSB0aGlzLnRpbWVzdGFtcDtcbiAgICAgICAgICAgICAgICBpZiAoIXRoaXMuYml0cmF0ZSB8fCAhaW50ZXJ2YWwgfHwgdGltZURpZmYgPiBpbnRlcnZhbCkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmJpdHJhdGUgPSAobG9hZGVkIC0gdGhpcy5sb2FkZWQpICogKDEwMDAgLyB0aW1lRGlmZikgKiA4O1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmxvYWRlZCA9IGxvYWRlZDtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy50aW1lc3RhbXAgPSBub3c7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmJpdHJhdGU7XG4gICAgICAgICAgICB9O1xuICAgICAgICB9LFxuXG4gICAgICAgIF9pc1hIUlVwbG9hZDogZnVuY3Rpb24gKG9wdGlvbnMpIHtcbiAgICAgICAgICAgIHJldHVybiAhb3B0aW9ucy5mb3JjZUlmcmFtZVRyYW5zcG9ydCAmJlxuICAgICAgICAgICAgICAgICgoIW9wdGlvbnMubXVsdGlwYXJ0ICYmICQuc3VwcG9ydC54aHJGaWxlVXBsb2FkKSB8fFxuICAgICAgICAgICAgICAgICQuc3VwcG9ydC54aHJGb3JtRGF0YUZpbGVVcGxvYWQpO1xuICAgICAgICB9LFxuXG4gICAgICAgIF9nZXRGb3JtRGF0YTogZnVuY3Rpb24gKG9wdGlvbnMpIHtcbiAgICAgICAgICAgIHZhciBmb3JtRGF0YTtcbiAgICAgICAgICAgIGlmICgkLnR5cGUob3B0aW9ucy5mb3JtRGF0YSkgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gb3B0aW9ucy5mb3JtRGF0YShvcHRpb25zLmZvcm0pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKCQuaXNBcnJheShvcHRpb25zLmZvcm1EYXRhKSkge1xuICAgICAgICAgICAgICAgIHJldHVybiBvcHRpb25zLmZvcm1EYXRhO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKCQudHlwZShvcHRpb25zLmZvcm1EYXRhKSA9PT0gJ29iamVjdCcpIHtcbiAgICAgICAgICAgICAgICBmb3JtRGF0YSA9IFtdO1xuICAgICAgICAgICAgICAgICQuZWFjaChvcHRpb25zLmZvcm1EYXRhLCBmdW5jdGlvbiAobmFtZSwgdmFsdWUpIHtcbiAgICAgICAgICAgICAgICAgICAgZm9ybURhdGEucHVzaCh7bmFtZTogbmFtZSwgdmFsdWU6IHZhbHVlfSk7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGZvcm1EYXRhO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIFtdO1xuICAgICAgICB9LFxuXG4gICAgICAgIF9nZXRUb3RhbDogZnVuY3Rpb24gKGZpbGVzKSB7XG4gICAgICAgICAgICB2YXIgdG90YWwgPSAwO1xuICAgICAgICAgICAgJC5lYWNoKGZpbGVzLCBmdW5jdGlvbiAoaW5kZXgsIGZpbGUpIHtcbiAgICAgICAgICAgICAgICB0b3RhbCArPSBmaWxlLnNpemUgfHwgMTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgcmV0dXJuIHRvdGFsO1xuICAgICAgICB9LFxuXG4gICAgICAgIF9pbml0UHJvZ3Jlc3NPYmplY3Q6IGZ1bmN0aW9uIChvYmopIHtcbiAgICAgICAgICAgIHZhciBwcm9ncmVzcyA9IHtcbiAgICAgICAgICAgICAgICBsb2FkZWQ6IDAsXG4gICAgICAgICAgICAgICAgdG90YWw6IDAsXG4gICAgICAgICAgICAgICAgYml0cmF0ZTogMFxuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIGlmIChvYmouX3Byb2dyZXNzKSB7XG4gICAgICAgICAgICAgICAgJC5leHRlbmQob2JqLl9wcm9ncmVzcywgcHJvZ3Jlc3MpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBvYmouX3Byb2dyZXNzID0gcHJvZ3Jlc3M7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0sXG5cbiAgICAgICAgX2luaXRSZXNwb25zZU9iamVjdDogZnVuY3Rpb24gKG9iaikge1xuICAgICAgICAgICAgdmFyIHByb3A7XG4gICAgICAgICAgICBpZiAob2JqLl9yZXNwb25zZSkge1xuICAgICAgICAgICAgICAgIGZvciAocHJvcCBpbiBvYmouX3Jlc3BvbnNlKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChvYmouX3Jlc3BvbnNlLmhhc093blByb3BlcnR5KHByb3ApKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBkZWxldGUgb2JqLl9yZXNwb25zZVtwcm9wXTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgb2JqLl9yZXNwb25zZSA9IHt9O1xuICAgICAgICAgICAgfVxuICAgICAgICB9LFxuXG4gICAgICAgIF9vblByb2dyZXNzOiBmdW5jdGlvbiAoZSwgZGF0YSkge1xuICAgICAgICAgICAgaWYgKGUubGVuZ3RoQ29tcHV0YWJsZSkge1xuICAgICAgICAgICAgICAgIHZhciBub3cgPSAoKERhdGUubm93KSA/IERhdGUubm93KCkgOiAobmV3IERhdGUoKSkuZ2V0VGltZSgpKSxcbiAgICAgICAgICAgICAgICAgICAgbG9hZGVkO1xuICAgICAgICAgICAgICAgIGlmIChkYXRhLl90aW1lICYmIGRhdGEucHJvZ3Jlc3NJbnRlcnZhbCAmJlxuICAgICAgICAgICAgICAgICAgICAgICAgKG5vdyAtIGRhdGEuX3RpbWUgPCBkYXRhLnByb2dyZXNzSW50ZXJ2YWwpICYmXG4gICAgICAgICAgICAgICAgICAgICAgICBlLmxvYWRlZCAhPT0gZS50b3RhbCkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGRhdGEuX3RpbWUgPSBub3c7XG4gICAgICAgICAgICAgICAgbG9hZGVkID0gTWF0aC5mbG9vcihcbiAgICAgICAgICAgICAgICAgICAgZS5sb2FkZWQgLyBlLnRvdGFsICogKGRhdGEuY2h1bmtTaXplIHx8IGRhdGEuX3Byb2dyZXNzLnRvdGFsKVxuICAgICAgICAgICAgICAgICkgKyAoZGF0YS51cGxvYWRlZEJ5dGVzIHx8IDApO1xuICAgICAgICAgICAgICAgIC8vIEFkZCB0aGUgZGlmZmVyZW5jZSBmcm9tIHRoZSBwcmV2aW91c2x5IGxvYWRlZCBzdGF0ZVxuICAgICAgICAgICAgICAgIC8vIHRvIHRoZSBnbG9iYWwgbG9hZGVkIGNvdW50ZXI6XG4gICAgICAgICAgICAgICAgdGhpcy5fcHJvZ3Jlc3MubG9hZGVkICs9IChsb2FkZWQgLSBkYXRhLl9wcm9ncmVzcy5sb2FkZWQpO1xuICAgICAgICAgICAgICAgIHRoaXMuX3Byb2dyZXNzLmJpdHJhdGUgPSB0aGlzLl9iaXRyYXRlVGltZXIuZ2V0Qml0cmF0ZShcbiAgICAgICAgICAgICAgICAgICAgbm93LFxuICAgICAgICAgICAgICAgICAgICB0aGlzLl9wcm9ncmVzcy5sb2FkZWQsXG4gICAgICAgICAgICAgICAgICAgIGRhdGEuYml0cmF0ZUludGVydmFsXG4gICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICBkYXRhLl9wcm9ncmVzcy5sb2FkZWQgPSBkYXRhLmxvYWRlZCA9IGxvYWRlZDtcbiAgICAgICAgICAgICAgICBkYXRhLl9wcm9ncmVzcy5iaXRyYXRlID0gZGF0YS5iaXRyYXRlID0gZGF0YS5fYml0cmF0ZVRpbWVyLmdldEJpdHJhdGUoXG4gICAgICAgICAgICAgICAgICAgIG5vdyxcbiAgICAgICAgICAgICAgICAgICAgbG9hZGVkLFxuICAgICAgICAgICAgICAgICAgICBkYXRhLmJpdHJhdGVJbnRlcnZhbFxuICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgLy8gVHJpZ2dlciBhIGN1c3RvbSBwcm9ncmVzcyBldmVudCB3aXRoIGEgdG90YWwgZGF0YSBwcm9wZXJ0eSBzZXRcbiAgICAgICAgICAgICAgICAvLyB0byB0aGUgZmlsZSBzaXplKHMpIG9mIHRoZSBjdXJyZW50IHVwbG9hZCBhbmQgYSBsb2FkZWQgZGF0YVxuICAgICAgICAgICAgICAgIC8vIHByb3BlcnR5IGNhbGN1bGF0ZWQgYWNjb3JkaW5nbHk6XG4gICAgICAgICAgICAgICAgdGhpcy5fdHJpZ2dlcihcbiAgICAgICAgICAgICAgICAgICAgJ3Byb2dyZXNzJyxcbiAgICAgICAgICAgICAgICAgICAgJC5FdmVudCgncHJvZ3Jlc3MnLCB7ZGVsZWdhdGVkRXZlbnQ6IGV9KSxcbiAgICAgICAgICAgICAgICAgICAgZGF0YVxuICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgLy8gVHJpZ2dlciBhIGdsb2JhbCBwcm9ncmVzcyBldmVudCBmb3IgYWxsIGN1cnJlbnQgZmlsZSB1cGxvYWRzLFxuICAgICAgICAgICAgICAgIC8vIGluY2x1ZGluZyBhamF4IGNhbGxzIHF1ZXVlZCBmb3Igc2VxdWVudGlhbCBmaWxlIHVwbG9hZHM6XG4gICAgICAgICAgICAgICAgdGhpcy5fdHJpZ2dlcihcbiAgICAgICAgICAgICAgICAgICAgJ3Byb2dyZXNzYWxsJyxcbiAgICAgICAgICAgICAgICAgICAgJC5FdmVudCgncHJvZ3Jlc3NhbGwnLCB7ZGVsZWdhdGVkRXZlbnQ6IGV9KSxcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5fcHJvZ3Jlc3NcbiAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgfVxuICAgICAgICB9LFxuXG4gICAgICAgIF9pbml0UHJvZ3Jlc3NMaXN0ZW5lcjogZnVuY3Rpb24gKG9wdGlvbnMpIHtcbiAgICAgICAgICAgIHZhciB0aGF0ID0gdGhpcyxcbiAgICAgICAgICAgICAgICB4aHIgPSBvcHRpb25zLnhociA/IG9wdGlvbnMueGhyKCkgOiAkLmFqYXhTZXR0aW5ncy54aHIoKTtcbiAgICAgICAgICAgIC8vIEFjY2Vzc3MgdG8gdGhlIG5hdGl2ZSBYSFIgb2JqZWN0IGlzIHJlcXVpcmVkIHRvIGFkZCBldmVudCBsaXN0ZW5lcnNcbiAgICAgICAgICAgIC8vIGZvciB0aGUgdXBsb2FkIHByb2dyZXNzIGV2ZW50OlxuICAgICAgICAgICAgaWYgKHhoci51cGxvYWQpIHtcbiAgICAgICAgICAgICAgICAkKHhoci51cGxvYWQpLmJpbmQoJ3Byb2dyZXNzJywgZnVuY3Rpb24gKGUpIHtcbiAgICAgICAgICAgICAgICAgICAgdmFyIG9lID0gZS5vcmlnaW5hbEV2ZW50O1xuICAgICAgICAgICAgICAgICAgICAvLyBNYWtlIHN1cmUgdGhlIHByb2dyZXNzIGV2ZW50IHByb3BlcnRpZXMgZ2V0IGNvcGllZCBvdmVyOlxuICAgICAgICAgICAgICAgICAgICBlLmxlbmd0aENvbXB1dGFibGUgPSBvZS5sZW5ndGhDb21wdXRhYmxlO1xuICAgICAgICAgICAgICAgICAgICBlLmxvYWRlZCA9IG9lLmxvYWRlZDtcbiAgICAgICAgICAgICAgICAgICAgZS50b3RhbCA9IG9lLnRvdGFsO1xuICAgICAgICAgICAgICAgICAgICB0aGF0Ll9vblByb2dyZXNzKGUsIG9wdGlvbnMpO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIG9wdGlvbnMueGhyID0gZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4geGhyO1xuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICB9XG4gICAgICAgIH0sXG5cbiAgICAgICAgX2lzSW5zdGFuY2VPZjogZnVuY3Rpb24gKHR5cGUsIG9iaikge1xuICAgICAgICAgICAgLy8gQ3Jvc3MtZnJhbWUgaW5zdGFuY2VvZiBjaGVja1xuICAgICAgICAgICAgcmV0dXJuIE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbChvYmopID09PSAnW29iamVjdCAnICsgdHlwZSArICddJztcbiAgICAgICAgfSxcblxuICAgICAgICBfaW5pdFhIUkRhdGE6IGZ1bmN0aW9uIChvcHRpb25zKSB7XG4gICAgICAgICAgICB2YXIgdGhhdCA9IHRoaXMsXG4gICAgICAgICAgICAgICAgZm9ybURhdGEsXG4gICAgICAgICAgICAgICAgZmlsZSA9IG9wdGlvbnMuZmlsZXNbMF0sXG4gICAgICAgICAgICAgICAgLy8gSWdub3JlIG5vbi1tdWx0aXBhcnQgc2V0dGluZyBpZiBub3Qgc3VwcG9ydGVkOlxuICAgICAgICAgICAgICAgIG11bHRpcGFydCA9IG9wdGlvbnMubXVsdGlwYXJ0IHx8ICEkLnN1cHBvcnQueGhyRmlsZVVwbG9hZCxcbiAgICAgICAgICAgICAgICBwYXJhbU5hbWUgPSAkLnR5cGUob3B0aW9ucy5wYXJhbU5hbWUpID09PSAnYXJyYXknID9cbiAgICAgICAgICAgICAgICAgICAgb3B0aW9ucy5wYXJhbU5hbWVbMF0gOiBvcHRpb25zLnBhcmFtTmFtZTtcbiAgICAgICAgICAgIG9wdGlvbnMuaGVhZGVycyA9ICQuZXh0ZW5kKHt9LCBvcHRpb25zLmhlYWRlcnMpO1xuICAgICAgICAgICAgaWYgKG9wdGlvbnMuY29udGVudFJhbmdlKSB7XG4gICAgICAgICAgICAgICAgb3B0aW9ucy5oZWFkZXJzWydDb250ZW50LVJhbmdlJ10gPSBvcHRpb25zLmNvbnRlbnRSYW5nZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmICghbXVsdGlwYXJ0IHx8IG9wdGlvbnMuYmxvYiB8fCAhdGhpcy5faXNJbnN0YW5jZU9mKCdGaWxlJywgZmlsZSkpIHtcbiAgICAgICAgICAgICAgICBvcHRpb25zLmhlYWRlcnNbJ0NvbnRlbnQtRGlzcG9zaXRpb24nXSA9ICdhdHRhY2htZW50OyBmaWxlbmFtZT1cIicgK1xuICAgICAgICAgICAgICAgICAgICBlbmNvZGVVUkkoZmlsZS5uYW1lKSArICdcIic7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoIW11bHRpcGFydCkge1xuICAgICAgICAgICAgICAgIG9wdGlvbnMuY29udGVudFR5cGUgPSBmaWxlLnR5cGUgfHwgJ2FwcGxpY2F0aW9uL29jdGV0LXN0cmVhbSc7XG4gICAgICAgICAgICAgICAgb3B0aW9ucy5kYXRhID0gb3B0aW9ucy5ibG9iIHx8IGZpbGU7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKCQuc3VwcG9ydC54aHJGb3JtRGF0YUZpbGVVcGxvYWQpIHtcbiAgICAgICAgICAgICAgICBpZiAob3B0aW9ucy5wb3N0TWVzc2FnZSkge1xuICAgICAgICAgICAgICAgICAgICAvLyB3aW5kb3cucG9zdE1lc3NhZ2UgZG9lcyBub3QgYWxsb3cgc2VuZGluZyBGb3JtRGF0YVxuICAgICAgICAgICAgICAgICAgICAvLyBvYmplY3RzLCBzbyB3ZSBqdXN0IGFkZCB0aGUgRmlsZS9CbG9iIG9iamVjdHMgdG9cbiAgICAgICAgICAgICAgICAgICAgLy8gdGhlIGZvcm1EYXRhIGFycmF5IGFuZCBsZXQgdGhlIHBvc3RNZXNzYWdlIHdpbmRvd1xuICAgICAgICAgICAgICAgICAgICAvLyBjcmVhdGUgdGhlIEZvcm1EYXRhIG9iamVjdCBvdXQgb2YgdGhpcyBhcnJheTpcbiAgICAgICAgICAgICAgICAgICAgZm9ybURhdGEgPSB0aGlzLl9nZXRGb3JtRGF0YShvcHRpb25zKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKG9wdGlvbnMuYmxvYikge1xuICAgICAgICAgICAgICAgICAgICAgICAgZm9ybURhdGEucHVzaCh7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbmFtZTogcGFyYW1OYW1lLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhbHVlOiBvcHRpb25zLmJsb2JcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgJC5lYWNoKG9wdGlvbnMuZmlsZXMsIGZ1bmN0aW9uIChpbmRleCwgZmlsZSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvcm1EYXRhLnB1c2goe1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuYW1lOiAoJC50eXBlKG9wdGlvbnMucGFyYW1OYW1lKSA9PT0gJ2FycmF5JyAmJlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb3B0aW9ucy5wYXJhbU5hbWVbaW5kZXhdKSB8fCBwYXJhbU5hbWUsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhbHVlOiBmaWxlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGlmICh0aGF0Ll9pc0luc3RhbmNlT2YoJ0Zvcm1EYXRhJywgb3B0aW9ucy5mb3JtRGF0YSkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGZvcm1EYXRhID0gb3B0aW9ucy5mb3JtRGF0YTtcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGZvcm1EYXRhID0gbmV3IEZvcm1EYXRhKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAkLmVhY2godGhpcy5fZ2V0Rm9ybURhdGEob3B0aW9ucyksIGZ1bmN0aW9uIChpbmRleCwgZmllbGQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb3JtRGF0YS5hcHBlbmQoZmllbGQubmFtZSwgZmllbGQudmFsdWUpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgaWYgKG9wdGlvbnMuYmxvYikge1xuICAgICAgICAgICAgICAgICAgICAgICAgZm9ybURhdGEuYXBwZW5kKHBhcmFtTmFtZSwgb3B0aW9ucy5ibG9iLCBmaWxlLm5hbWUpO1xuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgJC5lYWNoKG9wdGlvbnMuZmlsZXMsIGZ1bmN0aW9uIChpbmRleCwgZmlsZSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFRoaXMgY2hlY2sgYWxsb3dzIHRoZSB0ZXN0cyB0byBydW4gd2l0aFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGR1bW15IG9iamVjdHM6XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHRoYXQuX2lzSW5zdGFuY2VPZignRmlsZScsIGZpbGUpIHx8XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGF0Ll9pc0luc3RhbmNlT2YoJ0Jsb2InLCBmaWxlKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb3JtRGF0YS5hcHBlbmQoXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoJC50eXBlKG9wdGlvbnMucGFyYW1OYW1lKSA9PT0gJ2FycmF5JyAmJlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9wdGlvbnMucGFyYW1OYW1lW2luZGV4XSkgfHwgcGFyYW1OYW1lLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmlsZSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbGUudXBsb2FkTmFtZSB8fCBmaWxlLm5hbWVcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBvcHRpb25zLmRhdGEgPSBmb3JtRGF0YTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIC8vIEJsb2IgcmVmZXJlbmNlIGlzIG5vdCBuZWVkZWQgYW55bW9yZSwgZnJlZSBtZW1vcnk6XG4gICAgICAgICAgICBvcHRpb25zLmJsb2IgPSBudWxsO1xuICAgICAgICB9LFxuXG4gICAgICAgIF9pbml0SWZyYW1lU2V0dGluZ3M6IGZ1bmN0aW9uIChvcHRpb25zKSB7XG4gICAgICAgICAgICB2YXIgdGFyZ2V0SG9zdCA9ICQoJzxhPjwvYT4nKS5wcm9wKCdocmVmJywgb3B0aW9ucy51cmwpLnByb3AoJ2hvc3QnKTtcbiAgICAgICAgICAgIC8vIFNldHRpbmcgdGhlIGRhdGFUeXBlIHRvIGlmcmFtZSBlbmFibGVzIHRoZSBpZnJhbWUgdHJhbnNwb3J0OlxuICAgICAgICAgICAgb3B0aW9ucy5kYXRhVHlwZSA9ICdpZnJhbWUgJyArIChvcHRpb25zLmRhdGFUeXBlIHx8ICcnKTtcbiAgICAgICAgICAgIC8vIFRoZSBpZnJhbWUgdHJhbnNwb3J0IGFjY2VwdHMgYSBzZXJpYWxpemVkIGFycmF5IGFzIGZvcm0gZGF0YTpcbiAgICAgICAgICAgIG9wdGlvbnMuZm9ybURhdGEgPSB0aGlzLl9nZXRGb3JtRGF0YShvcHRpb25zKTtcbiAgICAgICAgICAgIC8vIEFkZCByZWRpcmVjdCB1cmwgdG8gZm9ybSBkYXRhIG9uIGNyb3NzLWRvbWFpbiB1cGxvYWRzOlxuICAgICAgICAgICAgaWYgKG9wdGlvbnMucmVkaXJlY3QgJiYgdGFyZ2V0SG9zdCAmJiB0YXJnZXRIb3N0ICE9PSBsb2NhdGlvbi5ob3N0KSB7XG4gICAgICAgICAgICAgICAgb3B0aW9ucy5mb3JtRGF0YS5wdXNoKHtcbiAgICAgICAgICAgICAgICAgICAgbmFtZTogb3B0aW9ucy5yZWRpcmVjdFBhcmFtTmFtZSB8fCAncmVkaXJlY3QnLFxuICAgICAgICAgICAgICAgICAgICB2YWx1ZTogb3B0aW9ucy5yZWRpcmVjdFxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9LFxuXG4gICAgICAgIF9pbml0RGF0YVNldHRpbmdzOiBmdW5jdGlvbiAob3B0aW9ucykge1xuICAgICAgICAgICAgaWYgKHRoaXMuX2lzWEhSVXBsb2FkKG9wdGlvbnMpKSB7XG4gICAgICAgICAgICAgICAgaWYgKCF0aGlzLl9jaHVua2VkVXBsb2FkKG9wdGlvbnMsIHRydWUpKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmICghb3B0aW9ucy5kYXRhKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl9pbml0WEhSRGF0YShvcHRpb25zKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB0aGlzLl9pbml0UHJvZ3Jlc3NMaXN0ZW5lcihvcHRpb25zKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWYgKG9wdGlvbnMucG9zdE1lc3NhZ2UpIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gU2V0dGluZyB0aGUgZGF0YVR5cGUgdG8gcG9zdG1lc3NhZ2UgZW5hYmxlcyB0aGVcbiAgICAgICAgICAgICAgICAgICAgLy8gcG9zdE1lc3NhZ2UgdHJhbnNwb3J0OlxuICAgICAgICAgICAgICAgICAgICBvcHRpb25zLmRhdGFUeXBlID0gJ3Bvc3RtZXNzYWdlICcgKyAob3B0aW9ucy5kYXRhVHlwZSB8fCAnJyk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICB0aGlzLl9pbml0SWZyYW1lU2V0dGluZ3Mob3B0aW9ucyk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0sXG5cbiAgICAgICAgX2dldFBhcmFtTmFtZTogZnVuY3Rpb24gKG9wdGlvbnMpIHtcbiAgICAgICAgICAgIHZhciBmaWxlSW5wdXQgPSAkKG9wdGlvbnMuZmlsZUlucHV0KSxcbiAgICAgICAgICAgICAgICBwYXJhbU5hbWUgPSBvcHRpb25zLnBhcmFtTmFtZTtcbiAgICAgICAgICAgIGlmICghcGFyYW1OYW1lKSB7XG4gICAgICAgICAgICAgICAgcGFyYW1OYW1lID0gW107XG4gICAgICAgICAgICAgICAgZmlsZUlucHV0LmVhY2goZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgICAgICB2YXIgaW5wdXQgPSAkKHRoaXMpLFxuICAgICAgICAgICAgICAgICAgICAgICAgbmFtZSA9IGlucHV0LnByb3AoJ25hbWUnKSB8fCAnZmlsZXNbXScsXG4gICAgICAgICAgICAgICAgICAgICAgICBpID0gKGlucHV0LnByb3AoJ2ZpbGVzJykgfHwgWzFdKS5sZW5ndGg7XG4gICAgICAgICAgICAgICAgICAgIHdoaWxlIChpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBwYXJhbU5hbWUucHVzaChuYW1lKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGkgLT0gMTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIGlmICghcGFyYW1OYW1lLmxlbmd0aCkge1xuICAgICAgICAgICAgICAgICAgICBwYXJhbU5hbWUgPSBbZmlsZUlucHV0LnByb3AoJ25hbWUnKSB8fCAnZmlsZXNbXSddO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0gZWxzZSBpZiAoISQuaXNBcnJheShwYXJhbU5hbWUpKSB7XG4gICAgICAgICAgICAgICAgcGFyYW1OYW1lID0gW3BhcmFtTmFtZV07XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gcGFyYW1OYW1lO1xuICAgICAgICB9LFxuXG4gICAgICAgIF9pbml0Rm9ybVNldHRpbmdzOiBmdW5jdGlvbiAob3B0aW9ucykge1xuICAgICAgICAgICAgLy8gUmV0cmlldmUgbWlzc2luZyBvcHRpb25zIGZyb20gdGhlIGlucHV0IGZpZWxkIGFuZCB0aGVcbiAgICAgICAgICAgIC8vIGFzc29jaWF0ZWQgZm9ybSwgaWYgYXZhaWxhYmxlOlxuICAgICAgICAgICAgaWYgKCFvcHRpb25zLmZvcm0gfHwgIW9wdGlvbnMuZm9ybS5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgICBvcHRpb25zLmZvcm0gPSAkKG9wdGlvbnMuZmlsZUlucHV0LnByb3AoJ2Zvcm0nKSk7XG4gICAgICAgICAgICAgICAgLy8gSWYgdGhlIGdpdmVuIGZpbGUgaW5wdXQgZG9lc24ndCBoYXZlIGFuIGFzc29jaWF0ZWQgZm9ybSxcbiAgICAgICAgICAgICAgICAvLyB1c2UgdGhlIGRlZmF1bHQgd2lkZ2V0IGZpbGUgaW5wdXQncyBmb3JtOlxuICAgICAgICAgICAgICAgIGlmICghb3B0aW9ucy5mb3JtLmxlbmd0aCkge1xuICAgICAgICAgICAgICAgICAgICBvcHRpb25zLmZvcm0gPSAkKHRoaXMub3B0aW9ucy5maWxlSW5wdXQucHJvcCgnZm9ybScpKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBvcHRpb25zLnBhcmFtTmFtZSA9IHRoaXMuX2dldFBhcmFtTmFtZShvcHRpb25zKTtcbiAgICAgICAgICAgIGlmICghb3B0aW9ucy51cmwpIHtcbiAgICAgICAgICAgICAgICBvcHRpb25zLnVybCA9IG9wdGlvbnMuZm9ybS5wcm9wKCdhY3Rpb24nKSB8fCBsb2NhdGlvbi5ocmVmO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgLy8gVGhlIEhUVFAgcmVxdWVzdCBtZXRob2QgbXVzdCBiZSBcIlBPU1RcIiBvciBcIlBVVFwiOlxuICAgICAgICAgICAgb3B0aW9ucy50eXBlID0gKG9wdGlvbnMudHlwZSB8fFxuICAgICAgICAgICAgICAgICgkLnR5cGUob3B0aW9ucy5mb3JtLnByb3AoJ21ldGhvZCcpKSA9PT0gJ3N0cmluZycgJiZcbiAgICAgICAgICAgICAgICAgICAgb3B0aW9ucy5mb3JtLnByb3AoJ21ldGhvZCcpKSB8fCAnJ1xuICAgICAgICAgICAgICAgICkudG9VcHBlckNhc2UoKTtcbiAgICAgICAgICAgIGlmIChvcHRpb25zLnR5cGUgIT09ICdQT1NUJyAmJiBvcHRpb25zLnR5cGUgIT09ICdQVVQnICYmXG4gICAgICAgICAgICAgICAgICAgIG9wdGlvbnMudHlwZSAhPT0gJ1BBVENIJykge1xuICAgICAgICAgICAgICAgIG9wdGlvbnMudHlwZSA9ICdQT1NUJztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmICghb3B0aW9ucy5mb3JtQWNjZXB0Q2hhcnNldCkge1xuICAgICAgICAgICAgICAgIG9wdGlvbnMuZm9ybUFjY2VwdENoYXJzZXQgPSBvcHRpb25zLmZvcm0uYXR0cignYWNjZXB0LWNoYXJzZXQnKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSxcblxuICAgICAgICBfZ2V0QUpBWFNldHRpbmdzOiBmdW5jdGlvbiAoZGF0YSkge1xuICAgICAgICAgICAgdmFyIG9wdGlvbnMgPSAkLmV4dGVuZCh7fSwgdGhpcy5vcHRpb25zLCBkYXRhKTtcbiAgICAgICAgICAgIHRoaXMuX2luaXRGb3JtU2V0dGluZ3Mob3B0aW9ucyk7XG4gICAgICAgICAgICB0aGlzLl9pbml0RGF0YVNldHRpbmdzKG9wdGlvbnMpO1xuICAgICAgICAgICAgcmV0dXJuIG9wdGlvbnM7XG4gICAgICAgIH0sXG5cbiAgICAgICAgLy8galF1ZXJ5IDEuNiBkb2Vzbid0IHByb3ZpZGUgLnN0YXRlKCksXG4gICAgICAgIC8vIHdoaWxlIGpRdWVyeSAxLjgrIHJlbW92ZWQgLmlzUmVqZWN0ZWQoKSBhbmQgLmlzUmVzb2x2ZWQoKTpcbiAgICAgICAgX2dldERlZmVycmVkU3RhdGU6IGZ1bmN0aW9uIChkZWZlcnJlZCkge1xuICAgICAgICAgICAgaWYgKGRlZmVycmVkLnN0YXRlKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGRlZmVycmVkLnN0YXRlKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoZGVmZXJyZWQuaXNSZXNvbHZlZCgpKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuICdyZXNvbHZlZCc7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoZGVmZXJyZWQuaXNSZWplY3RlZCgpKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuICdyZWplY3RlZCc7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gJ3BlbmRpbmcnO1xuICAgICAgICB9LFxuXG4gICAgICAgIC8vIE1hcHMganFYSFIgY2FsbGJhY2tzIHRvIHRoZSBlcXVpdmFsZW50XG4gICAgICAgIC8vIG1ldGhvZHMgb2YgdGhlIGdpdmVuIFByb21pc2Ugb2JqZWN0OlxuICAgICAgICBfZW5oYW5jZVByb21pc2U6IGZ1bmN0aW9uIChwcm9taXNlKSB7XG4gICAgICAgICAgICBwcm9taXNlLnN1Y2Nlc3MgPSBwcm9taXNlLmRvbmU7XG4gICAgICAgICAgICBwcm9taXNlLmVycm9yID0gcHJvbWlzZS5mYWlsO1xuICAgICAgICAgICAgcHJvbWlzZS5jb21wbGV0ZSA9IHByb21pc2UuYWx3YXlzO1xuICAgICAgICAgICAgcmV0dXJuIHByb21pc2U7XG4gICAgICAgIH0sXG5cbiAgICAgICAgLy8gQ3JlYXRlcyBhbmQgcmV0dXJucyBhIFByb21pc2Ugb2JqZWN0IGVuaGFuY2VkIHdpdGhcbiAgICAgICAgLy8gdGhlIGpxWEhSIG1ldGhvZHMgYWJvcnQsIHN1Y2Nlc3MsIGVycm9yIGFuZCBjb21wbGV0ZTpcbiAgICAgICAgX2dldFhIUlByb21pc2U6IGZ1bmN0aW9uIChyZXNvbHZlT3JSZWplY3QsIGNvbnRleHQsIGFyZ3MpIHtcbiAgICAgICAgICAgIHZhciBkZmQgPSAkLkRlZmVycmVkKCksXG4gICAgICAgICAgICAgICAgcHJvbWlzZSA9IGRmZC5wcm9taXNlKCk7XG4gICAgICAgICAgICBjb250ZXh0ID0gY29udGV4dCB8fCB0aGlzLm9wdGlvbnMuY29udGV4dCB8fCBwcm9taXNlO1xuICAgICAgICAgICAgaWYgKHJlc29sdmVPclJlamVjdCA9PT0gdHJ1ZSkge1xuICAgICAgICAgICAgICAgIGRmZC5yZXNvbHZlV2l0aChjb250ZXh0LCBhcmdzKTtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAocmVzb2x2ZU9yUmVqZWN0ID09PSBmYWxzZSkge1xuICAgICAgICAgICAgICAgIGRmZC5yZWplY3RXaXRoKGNvbnRleHQsIGFyZ3MpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcHJvbWlzZS5hYm9ydCA9IGRmZC5wcm9taXNlO1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2VuaGFuY2VQcm9taXNlKHByb21pc2UpO1xuICAgICAgICB9LFxuXG4gICAgICAgIC8vIEFkZHMgY29udmVuaWVuY2UgbWV0aG9kcyB0byB0aGUgZGF0YSBjYWxsYmFjayBhcmd1bWVudDpcbiAgICAgICAgX2FkZENvbnZlbmllbmNlTWV0aG9kczogZnVuY3Rpb24gKGUsIGRhdGEpIHtcbiAgICAgICAgICAgIHZhciB0aGF0ID0gdGhpcyxcbiAgICAgICAgICAgICAgICBnZXRQcm9taXNlID0gZnVuY3Rpb24gKGFyZ3MpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuICQuRGVmZXJyZWQoKS5yZXNvbHZlV2l0aCh0aGF0LCBhcmdzKS5wcm9taXNlKCk7XG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIGRhdGEucHJvY2VzcyA9IGZ1bmN0aW9uIChyZXNvbHZlRnVuYywgcmVqZWN0RnVuYykge1xuICAgICAgICAgICAgICAgIGlmIChyZXNvbHZlRnVuYyB8fCByZWplY3RGdW5jKSB7XG4gICAgICAgICAgICAgICAgICAgIGRhdGEuX3Byb2Nlc3NRdWV1ZSA9IHRoaXMuX3Byb2Nlc3NRdWV1ZSA9XG4gICAgICAgICAgICAgICAgICAgICAgICAodGhpcy5fcHJvY2Vzc1F1ZXVlIHx8IGdldFByb21pc2UoW3RoaXNdKSkudGhlbihcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChkYXRhLmVycm9yVGhyb3duKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gJC5EZWZlcnJlZCgpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLnJlamVjdFdpdGgodGhhdCwgW2RhdGFdKS5wcm9taXNlKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGdldFByb21pc2UoYXJndW1lbnRzKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICApLnRoZW4ocmVzb2x2ZUZ1bmMsIHJlamVjdEZ1bmMpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5fcHJvY2Vzc1F1ZXVlIHx8IGdldFByb21pc2UoW3RoaXNdKTtcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICBkYXRhLnN1Ym1pdCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5zdGF0ZSgpICE9PSAncGVuZGluZycpIHtcbiAgICAgICAgICAgICAgICAgICAgZGF0YS5qcVhIUiA9IHRoaXMuanFYSFIgPVxuICAgICAgICAgICAgICAgICAgICAgICAgKHRoYXQuX3RyaWdnZXIoXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgJ3N1Ym1pdCcsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgJC5FdmVudCgnc3VibWl0Jywge2RlbGVnYXRlZEV2ZW50OiBlfSksXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpc1xuICAgICAgICAgICAgICAgICAgICAgICAgKSAhPT0gZmFsc2UpICYmIHRoYXQuX29uU2VuZChlLCB0aGlzKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuanFYSFIgfHwgdGhhdC5fZ2V0WEhSUHJvbWlzZSgpO1xuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIGRhdGEuYWJvcnQgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuanFYSFIpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuanFYSFIuYWJvcnQoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgdGhpcy5lcnJvclRocm93biA9ICdhYm9ydCc7XG4gICAgICAgICAgICAgICAgdGhhdC5fdHJpZ2dlcignZmFpbCcsIG51bGwsIHRoaXMpO1xuICAgICAgICAgICAgICAgIHJldHVybiB0aGF0Ll9nZXRYSFJQcm9taXNlKGZhbHNlKTtcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICBkYXRhLnN0YXRlID0gZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIGlmICh0aGlzLmpxWEhSKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB0aGF0Ll9nZXREZWZlcnJlZFN0YXRlKHRoaXMuanFYSFIpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpZiAodGhpcy5fcHJvY2Vzc1F1ZXVlKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB0aGF0Ll9nZXREZWZlcnJlZFN0YXRlKHRoaXMuX3Byb2Nlc3NRdWV1ZSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIGRhdGEucHJvY2Vzc2luZyA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gIXRoaXMuanFYSFIgJiYgdGhpcy5fcHJvY2Vzc1F1ZXVlICYmIHRoYXRcbiAgICAgICAgICAgICAgICAgICAgLl9nZXREZWZlcnJlZFN0YXRlKHRoaXMuX3Byb2Nlc3NRdWV1ZSkgPT09ICdwZW5kaW5nJztcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICBkYXRhLnByb2dyZXNzID0gZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLl9wcm9ncmVzcztcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICBkYXRhLnJlc3BvbnNlID0gZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLl9yZXNwb25zZTtcbiAgICAgICAgICAgIH07XG4gICAgICAgIH0sXG5cbiAgICAgICAgLy8gUGFyc2VzIHRoZSBSYW5nZSBoZWFkZXIgZnJvbSB0aGUgc2VydmVyIHJlc3BvbnNlXG4gICAgICAgIC8vIGFuZCByZXR1cm5zIHRoZSB1cGxvYWRlZCBieXRlczpcbiAgICAgICAgX2dldFVwbG9hZGVkQnl0ZXM6IGZ1bmN0aW9uIChqcVhIUikge1xuICAgICAgICAgICAgdmFyIHJhbmdlID0ganFYSFIuZ2V0UmVzcG9uc2VIZWFkZXIoJ1JhbmdlJyksXG4gICAgICAgICAgICAgICAgcGFydHMgPSByYW5nZSAmJiByYW5nZS5zcGxpdCgnLScpLFxuICAgICAgICAgICAgICAgIHVwcGVyQnl0ZXNQb3MgPSBwYXJ0cyAmJiBwYXJ0cy5sZW5ndGggPiAxICYmXG4gICAgICAgICAgICAgICAgICAgIHBhcnNlSW50KHBhcnRzWzFdLCAxMCk7XG4gICAgICAgICAgICByZXR1cm4gdXBwZXJCeXRlc1BvcyAmJiB1cHBlckJ5dGVzUG9zICsgMTtcbiAgICAgICAgfSxcblxuICAgICAgICAvLyBVcGxvYWRzIGEgZmlsZSBpbiBtdWx0aXBsZSwgc2VxdWVudGlhbCByZXF1ZXN0c1xuICAgICAgICAvLyBieSBzcGxpdHRpbmcgdGhlIGZpbGUgdXAgaW4gbXVsdGlwbGUgYmxvYiBjaHVua3MuXG4gICAgICAgIC8vIElmIHRoZSBzZWNvbmQgcGFyYW1ldGVyIGlzIHRydWUsIG9ubHkgdGVzdHMgaWYgdGhlIGZpbGVcbiAgICAgICAgLy8gc2hvdWxkIGJlIHVwbG9hZGVkIGluIGNodW5rcywgYnV0IGRvZXMgbm90IGludm9rZSBhbnlcbiAgICAgICAgLy8gdXBsb2FkIHJlcXVlc3RzOlxuICAgICAgICBfY2h1bmtlZFVwbG9hZDogZnVuY3Rpb24gKG9wdGlvbnMsIHRlc3RPbmx5KSB7XG4gICAgICAgICAgICBvcHRpb25zLnVwbG9hZGVkQnl0ZXMgPSBvcHRpb25zLnVwbG9hZGVkQnl0ZXMgfHwgMDtcbiAgICAgICAgICAgIHZhciB0aGF0ID0gdGhpcyxcbiAgICAgICAgICAgICAgICBmaWxlID0gb3B0aW9ucy5maWxlc1swXSxcbiAgICAgICAgICAgICAgICBmcyA9IGZpbGUuc2l6ZSxcbiAgICAgICAgICAgICAgICB1YiA9IG9wdGlvbnMudXBsb2FkZWRCeXRlcyxcbiAgICAgICAgICAgICAgICBtY3MgPSBvcHRpb25zLm1heENodW5rU2l6ZSB8fCBmcyxcbiAgICAgICAgICAgICAgICBzbGljZSA9IHRoaXMuX2Jsb2JTbGljZSxcbiAgICAgICAgICAgICAgICBkZmQgPSAkLkRlZmVycmVkKCksXG4gICAgICAgICAgICAgICAgcHJvbWlzZSA9IGRmZC5wcm9taXNlKCksXG4gICAgICAgICAgICAgICAganFYSFIsXG4gICAgICAgICAgICAgICAgdXBsb2FkO1xuICAgICAgICAgICAgaWYgKCEodGhpcy5faXNYSFJVcGxvYWQob3B0aW9ucykgJiYgc2xpY2UgJiYgKHViIHx8ICgkLnR5cGUobWNzKSA9PT0gJ2Z1bmN0aW9uJyA/IG1jcyhvcHRpb25zKSA6IG1jcykgPCBmcykpIHx8XG4gICAgICAgICAgICAgICAgICAgIG9wdGlvbnMuZGF0YSkge1xuICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmICh0ZXN0T25seSkge1xuICAgICAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKHViID49IGZzKSB7XG4gICAgICAgICAgICAgICAgZmlsZS5lcnJvciA9IG9wdGlvbnMuaTE4bigndXBsb2FkZWRCeXRlcycpO1xuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLl9nZXRYSFJQcm9taXNlKFxuICAgICAgICAgICAgICAgICAgICBmYWxzZSxcbiAgICAgICAgICAgICAgICAgICAgb3B0aW9ucy5jb250ZXh0LFxuICAgICAgICAgICAgICAgICAgICBbbnVsbCwgJ2Vycm9yJywgZmlsZS5lcnJvcl1cbiAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgLy8gVGhlIGNodW5rIHVwbG9hZCBtZXRob2Q6XG4gICAgICAgICAgICB1cGxvYWQgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgLy8gQ2xvbmUgdGhlIG9wdGlvbnMgb2JqZWN0IGZvciBlYWNoIGNodW5rIHVwbG9hZDpcbiAgICAgICAgICAgICAgICB2YXIgbyA9ICQuZXh0ZW5kKHt9LCBvcHRpb25zKSxcbiAgICAgICAgICAgICAgICAgICAgY3VycmVudExvYWRlZCA9IG8uX3Byb2dyZXNzLmxvYWRlZDtcbiAgICAgICAgICAgICAgICBvLmJsb2IgPSBzbGljZS5jYWxsKFxuICAgICAgICAgICAgICAgICAgICBmaWxlLFxuICAgICAgICAgICAgICAgICAgICB1YixcbiAgICAgICAgICAgICAgICAgICAgdWIgKyAoJC50eXBlKG1jcykgPT09ICdmdW5jdGlvbicgPyBtY3MobykgOiBtY3MpLFxuICAgICAgICAgICAgICAgICAgICBmaWxlLnR5cGVcbiAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgIC8vIFN0b3JlIHRoZSBjdXJyZW50IGNodW5rIHNpemUsIGFzIHRoZSBibG9iIGl0c2VsZlxuICAgICAgICAgICAgICAgIC8vIHdpbGwgYmUgZGVyZWZlcmVuY2VkIGFmdGVyIGRhdGEgcHJvY2Vzc2luZzpcbiAgICAgICAgICAgICAgICBvLmNodW5rU2l6ZSA9IG8uYmxvYi5zaXplO1xuICAgICAgICAgICAgICAgIC8vIEV4cG9zZSB0aGUgY2h1bmsgYnl0ZXMgcG9zaXRpb24gcmFuZ2U6XG4gICAgICAgICAgICAgICAgby5jb250ZW50UmFuZ2UgPSAnYnl0ZXMgJyArIHViICsgJy0nICtcbiAgICAgICAgICAgICAgICAgICAgKHViICsgby5jaHVua1NpemUgLSAxKSArICcvJyArIGZzO1xuICAgICAgICAgICAgICAgIC8vIFByb2Nlc3MgdGhlIHVwbG9hZCBkYXRhICh0aGUgYmxvYiBhbmQgcG90ZW50aWFsIGZvcm0gZGF0YSk6XG4gICAgICAgICAgICAgICAgdGhhdC5faW5pdFhIUkRhdGEobyk7XG4gICAgICAgICAgICAgICAgLy8gQWRkIHByb2dyZXNzIGxpc3RlbmVycyBmb3IgdGhpcyBjaHVuayB1cGxvYWQ6XG4gICAgICAgICAgICAgICAgdGhhdC5faW5pdFByb2dyZXNzTGlzdGVuZXIobyk7XG4gICAgICAgICAgICAgICAganFYSFIgPSAoKHRoYXQuX3RyaWdnZXIoJ2NodW5rc2VuZCcsIG51bGwsIG8pICE9PSBmYWxzZSAmJiAkLmFqYXgobykpIHx8XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGF0Ll9nZXRYSFJQcm9taXNlKGZhbHNlLCBvLmNvbnRleHQpKVxuICAgICAgICAgICAgICAgICAgICAuZG9uZShmdW5jdGlvbiAocmVzdWx0LCB0ZXh0U3RhdHVzLCBqcVhIUikge1xuICAgICAgICAgICAgICAgICAgICAgICAgdWIgPSB0aGF0Ll9nZXRVcGxvYWRlZEJ5dGVzKGpxWEhSKSB8fFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICh1YiArIG8uY2h1bmtTaXplKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIENyZWF0ZSBhIHByb2dyZXNzIGV2ZW50IGlmIG5vIGZpbmFsIHByb2dyZXNzIGV2ZW50XG4gICAgICAgICAgICAgICAgICAgICAgICAvLyB3aXRoIGxvYWRlZCBlcXVhbGluZyB0b3RhbCBoYXMgYmVlbiB0cmlnZ2VyZWRcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIGZvciB0aGlzIGNodW5rOlxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGN1cnJlbnRMb2FkZWQgKyBvLmNodW5rU2l6ZSAtIG8uX3Byb2dyZXNzLmxvYWRlZCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoYXQuX29uUHJvZ3Jlc3MoJC5FdmVudCgncHJvZ3Jlc3MnLCB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxlbmd0aENvbXB1dGFibGU6IHRydWUsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxvYWRlZDogdWIgLSBvLnVwbG9hZGVkQnl0ZXMsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRvdGFsOiB1YiAtIG8udXBsb2FkZWRCeXRlc1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pLCBvKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIG9wdGlvbnMudXBsb2FkZWRCeXRlcyA9IG8udXBsb2FkZWRCeXRlcyA9IHViO1xuICAgICAgICAgICAgICAgICAgICAgICAgby5yZXN1bHQgPSByZXN1bHQ7XG4gICAgICAgICAgICAgICAgICAgICAgICBvLnRleHRTdGF0dXMgPSB0ZXh0U3RhdHVzO1xuICAgICAgICAgICAgICAgICAgICAgICAgby5qcVhIUiA9IGpxWEhSO1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhhdC5fdHJpZ2dlcignY2h1bmtkb25lJywgbnVsbCwgbyk7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGF0Ll90cmlnZ2VyKCdjaHVua2Fsd2F5cycsIG51bGwsIG8pO1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHViIDwgZnMpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBGaWxlIHVwbG9hZCBub3QgeWV0IGNvbXBsZXRlLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGNvbnRpbnVlIHdpdGggdGhlIG5leHQgY2h1bms6XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdXBsb2FkKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRmZC5yZXNvbHZlV2l0aChcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgby5jb250ZXh0LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbcmVzdWx0LCB0ZXh0U3RhdHVzLCBqcVhIUl1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgICAgICAuZmFpbChmdW5jdGlvbiAoanFYSFIsIHRleHRTdGF0dXMsIGVycm9yVGhyb3duKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBvLmpxWEhSID0ganFYSFI7XG4gICAgICAgICAgICAgICAgICAgICAgICBvLnRleHRTdGF0dXMgPSB0ZXh0U3RhdHVzO1xuICAgICAgICAgICAgICAgICAgICAgICAgby5lcnJvclRocm93biA9IGVycm9yVGhyb3duO1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhhdC5fdHJpZ2dlcignY2h1bmtmYWlsJywgbnVsbCwgbyk7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGF0Ll90cmlnZ2VyKCdjaHVua2Fsd2F5cycsIG51bGwsIG8pO1xuICAgICAgICAgICAgICAgICAgICAgICAgZGZkLnJlamVjdFdpdGgoXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgby5jb250ZXh0LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtqcVhIUiwgdGV4dFN0YXR1cywgZXJyb3JUaHJvd25dXG4gICAgICAgICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICB0aGlzLl9lbmhhbmNlUHJvbWlzZShwcm9taXNlKTtcbiAgICAgICAgICAgIHByb21pc2UuYWJvcnQgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGpxWEhSLmFib3J0KCk7XG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgdXBsb2FkKCk7XG4gICAgICAgICAgICByZXR1cm4gcHJvbWlzZTtcbiAgICAgICAgfSxcblxuICAgICAgICBfYmVmb3JlU2VuZDogZnVuY3Rpb24gKGUsIGRhdGEpIHtcbiAgICAgICAgICAgIGlmICh0aGlzLl9hY3RpdmUgPT09IDApIHtcbiAgICAgICAgICAgICAgICAvLyB0aGUgc3RhcnQgY2FsbGJhY2sgaXMgdHJpZ2dlcmVkIHdoZW4gYW4gdXBsb2FkIHN0YXJ0c1xuICAgICAgICAgICAgICAgIC8vIGFuZCBubyBvdGhlciB1cGxvYWRzIGFyZSBjdXJyZW50bHkgcnVubmluZyxcbiAgICAgICAgICAgICAgICAvLyBlcXVpdmFsZW50IHRvIHRoZSBnbG9iYWwgYWpheFN0YXJ0IGV2ZW50OlxuICAgICAgICAgICAgICAgIHRoaXMuX3RyaWdnZXIoJ3N0YXJ0Jyk7XG4gICAgICAgICAgICAgICAgLy8gU2V0IHRpbWVyIGZvciBnbG9iYWwgYml0cmF0ZSBwcm9ncmVzcyBjYWxjdWxhdGlvbjpcbiAgICAgICAgICAgICAgICB0aGlzLl9iaXRyYXRlVGltZXIgPSBuZXcgdGhpcy5fQml0cmF0ZVRpbWVyKCk7XG4gICAgICAgICAgICAgICAgLy8gUmVzZXQgdGhlIGdsb2JhbCBwcm9ncmVzcyB2YWx1ZXM6XG4gICAgICAgICAgICAgICAgdGhpcy5fcHJvZ3Jlc3MubG9hZGVkID0gdGhpcy5fcHJvZ3Jlc3MudG90YWwgPSAwO1xuICAgICAgICAgICAgICAgIHRoaXMuX3Byb2dyZXNzLmJpdHJhdGUgPSAwO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgLy8gTWFrZSBzdXJlIHRoZSBjb250YWluZXIgb2JqZWN0cyBmb3IgdGhlIC5yZXNwb25zZSgpIGFuZFxuICAgICAgICAgICAgLy8gLnByb2dyZXNzKCkgbWV0aG9kcyBvbiB0aGUgZGF0YSBvYmplY3QgYXJlIGF2YWlsYWJsZVxuICAgICAgICAgICAgLy8gYW5kIHJlc2V0IHRvIHRoZWlyIGluaXRpYWwgc3RhdGU6XG4gICAgICAgICAgICB0aGlzLl9pbml0UmVzcG9uc2VPYmplY3QoZGF0YSk7XG4gICAgICAgICAgICB0aGlzLl9pbml0UHJvZ3Jlc3NPYmplY3QoZGF0YSk7XG4gICAgICAgICAgICBkYXRhLl9wcm9ncmVzcy5sb2FkZWQgPSBkYXRhLmxvYWRlZCA9IGRhdGEudXBsb2FkZWRCeXRlcyB8fCAwO1xuICAgICAgICAgICAgZGF0YS5fcHJvZ3Jlc3MudG90YWwgPSBkYXRhLnRvdGFsID0gdGhpcy5fZ2V0VG90YWwoZGF0YS5maWxlcykgfHwgMTtcbiAgICAgICAgICAgIGRhdGEuX3Byb2dyZXNzLmJpdHJhdGUgPSBkYXRhLmJpdHJhdGUgPSAwO1xuICAgICAgICAgICAgdGhpcy5fYWN0aXZlICs9IDE7XG4gICAgICAgICAgICAvLyBJbml0aWFsaXplIHRoZSBnbG9iYWwgcHJvZ3Jlc3MgdmFsdWVzOlxuICAgICAgICAgICAgdGhpcy5fcHJvZ3Jlc3MubG9hZGVkICs9IGRhdGEubG9hZGVkO1xuICAgICAgICAgICAgdGhpcy5fcHJvZ3Jlc3MudG90YWwgKz0gZGF0YS50b3RhbDtcbiAgICAgICAgfSxcblxuICAgICAgICBfb25Eb25lOiBmdW5jdGlvbiAocmVzdWx0LCB0ZXh0U3RhdHVzLCBqcVhIUiwgb3B0aW9ucykge1xuICAgICAgICAgICAgdmFyIHRvdGFsID0gb3B0aW9ucy5fcHJvZ3Jlc3MudG90YWwsXG4gICAgICAgICAgICAgICAgcmVzcG9uc2UgPSBvcHRpb25zLl9yZXNwb25zZTtcbiAgICAgICAgICAgIGlmIChvcHRpb25zLl9wcm9ncmVzcy5sb2FkZWQgPCB0b3RhbCkge1xuICAgICAgICAgICAgICAgIC8vIENyZWF0ZSBhIHByb2dyZXNzIGV2ZW50IGlmIG5vIGZpbmFsIHByb2dyZXNzIGV2ZW50XG4gICAgICAgICAgICAgICAgLy8gd2l0aCBsb2FkZWQgZXF1YWxpbmcgdG90YWwgaGFzIGJlZW4gdHJpZ2dlcmVkOlxuICAgICAgICAgICAgICAgIHRoaXMuX29uUHJvZ3Jlc3MoJC5FdmVudCgncHJvZ3Jlc3MnLCB7XG4gICAgICAgICAgICAgICAgICAgIGxlbmd0aENvbXB1dGFibGU6IHRydWUsXG4gICAgICAgICAgICAgICAgICAgIGxvYWRlZDogdG90YWwsXG4gICAgICAgICAgICAgICAgICAgIHRvdGFsOiB0b3RhbFxuICAgICAgICAgICAgICAgIH0pLCBvcHRpb25zKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJlc3BvbnNlLnJlc3VsdCA9IG9wdGlvbnMucmVzdWx0ID0gcmVzdWx0O1xuICAgICAgICAgICAgcmVzcG9uc2UudGV4dFN0YXR1cyA9IG9wdGlvbnMudGV4dFN0YXR1cyA9IHRleHRTdGF0dXM7XG4gICAgICAgICAgICByZXNwb25zZS5qcVhIUiA9IG9wdGlvbnMuanFYSFIgPSBqcVhIUjtcbiAgICAgICAgICAgIHRoaXMuX3RyaWdnZXIoJ2RvbmUnLCBudWxsLCBvcHRpb25zKTtcbiAgICAgICAgfSxcblxuICAgICAgICBfb25GYWlsOiBmdW5jdGlvbiAoanFYSFIsIHRleHRTdGF0dXMsIGVycm9yVGhyb3duLCBvcHRpb25zKSB7XG4gICAgICAgICAgICB2YXIgcmVzcG9uc2UgPSBvcHRpb25zLl9yZXNwb25zZTtcbiAgICAgICAgICAgIGlmIChvcHRpb25zLnJlY2FsY3VsYXRlUHJvZ3Jlc3MpIHtcbiAgICAgICAgICAgICAgICAvLyBSZW1vdmUgdGhlIGZhaWxlZCAoZXJyb3Igb3IgYWJvcnQpIGZpbGUgdXBsb2FkIGZyb21cbiAgICAgICAgICAgICAgICAvLyB0aGUgZ2xvYmFsIHByb2dyZXNzIGNhbGN1bGF0aW9uOlxuICAgICAgICAgICAgICAgIHRoaXMuX3Byb2dyZXNzLmxvYWRlZCAtPSBvcHRpb25zLl9wcm9ncmVzcy5sb2FkZWQ7XG4gICAgICAgICAgICAgICAgdGhpcy5fcHJvZ3Jlc3MudG90YWwgLT0gb3B0aW9ucy5fcHJvZ3Jlc3MudG90YWw7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXNwb25zZS5qcVhIUiA9IG9wdGlvbnMuanFYSFIgPSBqcVhIUjtcbiAgICAgICAgICAgIHJlc3BvbnNlLnRleHRTdGF0dXMgPSBvcHRpb25zLnRleHRTdGF0dXMgPSB0ZXh0U3RhdHVzO1xuICAgICAgICAgICAgcmVzcG9uc2UuZXJyb3JUaHJvd24gPSBvcHRpb25zLmVycm9yVGhyb3duID0gZXJyb3JUaHJvd247XG4gICAgICAgICAgICB0aGlzLl90cmlnZ2VyKCdmYWlsJywgbnVsbCwgb3B0aW9ucyk7XG4gICAgICAgIH0sXG5cbiAgICAgICAgX29uQWx3YXlzOiBmdW5jdGlvbiAoanFYSFJvclJlc3VsdCwgdGV4dFN0YXR1cywganFYSFJvckVycm9yLCBvcHRpb25zKSB7XG4gICAgICAgICAgICAvLyBqcVhIUm9yUmVzdWx0LCB0ZXh0U3RhdHVzIGFuZCBqcVhIUm9yRXJyb3IgYXJlIGFkZGVkIHRvIHRoZVxuICAgICAgICAgICAgLy8gb3B0aW9ucyBvYmplY3QgdmlhIGRvbmUgYW5kIGZhaWwgY2FsbGJhY2tzXG4gICAgICAgICAgICB0aGlzLl90cmlnZ2VyKCdhbHdheXMnLCBudWxsLCBvcHRpb25zKTtcbiAgICAgICAgfSxcblxuICAgICAgICBfb25TZW5kOiBmdW5jdGlvbiAoZSwgZGF0YSkge1xuICAgICAgICAgICAgaWYgKCFkYXRhLnN1Ym1pdCkge1xuICAgICAgICAgICAgICAgIHRoaXMuX2FkZENvbnZlbmllbmNlTWV0aG9kcyhlLCBkYXRhKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHZhciB0aGF0ID0gdGhpcyxcbiAgICAgICAgICAgICAgICBqcVhIUixcbiAgICAgICAgICAgICAgICBhYm9ydGVkLFxuICAgICAgICAgICAgICAgIHNsb3QsXG4gICAgICAgICAgICAgICAgcGlwZSxcbiAgICAgICAgICAgICAgICBvcHRpb25zID0gdGhhdC5fZ2V0QUpBWFNldHRpbmdzKGRhdGEpLFxuICAgICAgICAgICAgICAgIHNlbmQgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoYXQuX3NlbmRpbmcgKz0gMTtcbiAgICAgICAgICAgICAgICAgICAgLy8gU2V0IHRpbWVyIGZvciBiaXRyYXRlIHByb2dyZXNzIGNhbGN1bGF0aW9uOlxuICAgICAgICAgICAgICAgICAgICBvcHRpb25zLl9iaXRyYXRlVGltZXIgPSBuZXcgdGhhdC5fQml0cmF0ZVRpbWVyKCk7XG4gICAgICAgICAgICAgICAgICAgIGpxWEhSID0ganFYSFIgfHwgKFxuICAgICAgICAgICAgICAgICAgICAgICAgKChhYm9ydGVkIHx8IHRoYXQuX3RyaWdnZXIoXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgJ3NlbmQnLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICQuRXZlbnQoJ3NlbmQnLCB7ZGVsZWdhdGVkRXZlbnQ6IGV9KSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBvcHRpb25zXG4gICAgICAgICAgICAgICAgICAgICAgICApID09PSBmYWxzZSkgJiZcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoYXQuX2dldFhIUlByb21pc2UoZmFsc2UsIG9wdGlvbnMuY29udGV4dCwgYWJvcnRlZCkpIHx8XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGF0Ll9jaHVua2VkVXBsb2FkKG9wdGlvbnMpIHx8ICQuYWpheChvcHRpb25zKVxuICAgICAgICAgICAgICAgICAgICApLmRvbmUoZnVuY3Rpb24gKHJlc3VsdCwgdGV4dFN0YXR1cywganFYSFIpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoYXQuX29uRG9uZShyZXN1bHQsIHRleHRTdGF0dXMsIGpxWEhSLCBvcHRpb25zKTtcbiAgICAgICAgICAgICAgICAgICAgfSkuZmFpbChmdW5jdGlvbiAoanFYSFIsIHRleHRTdGF0dXMsIGVycm9yVGhyb3duKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGF0Ll9vbkZhaWwoanFYSFIsIHRleHRTdGF0dXMsIGVycm9yVGhyb3duLCBvcHRpb25zKTtcbiAgICAgICAgICAgICAgICAgICAgfSkuYWx3YXlzKGZ1bmN0aW9uIChqcVhIUm9yUmVzdWx0LCB0ZXh0U3RhdHVzLCBqcVhIUm9yRXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoYXQuX29uQWx3YXlzKFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGpxWEhSb3JSZXN1bHQsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGV4dFN0YXR1cyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBqcVhIUm9yRXJyb3IsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgb3B0aW9uc1xuICAgICAgICAgICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoYXQuX3NlbmRpbmcgLT0gMTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoYXQuX2FjdGl2ZSAtPSAxO1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG9wdGlvbnMubGltaXRDb25jdXJyZW50VXBsb2FkcyAmJlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvcHRpb25zLmxpbWl0Q29uY3VycmVudFVwbG9hZHMgPiB0aGF0Ll9zZW5kaW5nKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gU3RhcnQgdGhlIG5leHQgcXVldWVkIHVwbG9hZCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyB0aGF0IGhhcyBub3QgYmVlbiBhYm9ydGVkOlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBuZXh0U2xvdCA9IHRoYXQuX3Nsb3RzLnNoaWZ0KCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgd2hpbGUgKG5leHRTbG90KSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0aGF0Ll9nZXREZWZlcnJlZFN0YXRlKG5leHRTbG90KSA9PT0gJ3BlbmRpbmcnKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXh0U2xvdC5yZXNvbHZlKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXh0U2xvdCA9IHRoYXQuX3Nsb3RzLnNoaWZ0KCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHRoYXQuX2FjdGl2ZSA9PT0gMCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFRoZSBzdG9wIGNhbGxiYWNrIGlzIHRyaWdnZXJlZCB3aGVuIGFsbCB1cGxvYWRzIGhhdmVcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBiZWVuIGNvbXBsZXRlZCwgZXF1aXZhbGVudCB0byB0aGUgZ2xvYmFsIGFqYXhTdG9wIGV2ZW50OlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoYXQuX3RyaWdnZXIoJ3N0b3AnKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBqcVhIUjtcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgdGhpcy5fYmVmb3JlU2VuZChlLCBvcHRpb25zKTtcbiAgICAgICAgICAgIGlmICh0aGlzLm9wdGlvbnMuc2VxdWVudGlhbFVwbG9hZHMgfHxcbiAgICAgICAgICAgICAgICAgICAgKHRoaXMub3B0aW9ucy5saW1pdENvbmN1cnJlbnRVcGxvYWRzICYmXG4gICAgICAgICAgICAgICAgICAgIHRoaXMub3B0aW9ucy5saW1pdENvbmN1cnJlbnRVcGxvYWRzIDw9IHRoaXMuX3NlbmRpbmcpKSB7XG4gICAgICAgICAgICAgICAgaWYgKHRoaXMub3B0aW9ucy5saW1pdENvbmN1cnJlbnRVcGxvYWRzID4gMSkge1xuICAgICAgICAgICAgICAgICAgICBzbG90ID0gJC5EZWZlcnJlZCgpO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLl9zbG90cy5wdXNoKHNsb3QpO1xuICAgICAgICAgICAgICAgICAgICBwaXBlID0gc2xvdC50aGVuKHNlbmQpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuX3NlcXVlbmNlID0gdGhpcy5fc2VxdWVuY2UudGhlbihzZW5kLCBzZW5kKTtcbiAgICAgICAgICAgICAgICAgICAgcGlwZSA9IHRoaXMuX3NlcXVlbmNlO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAvLyBSZXR1cm4gdGhlIHBpcGVkIFByb21pc2Ugb2JqZWN0LCBlbmhhbmNlZCB3aXRoIGFuIGFib3J0IG1ldGhvZCxcbiAgICAgICAgICAgICAgICAvLyB3aGljaCBpcyBkZWxlZ2F0ZWQgdG8gdGhlIGpxWEhSIG9iamVjdCBvZiB0aGUgY3VycmVudCB1cGxvYWQsXG4gICAgICAgICAgICAgICAgLy8gYW5kIGpxWEhSIGNhbGxiYWNrcyBtYXBwZWQgdG8gdGhlIGVxdWl2YWxlbnQgUHJvbWlzZSBtZXRob2RzOlxuICAgICAgICAgICAgICAgIHBpcGUuYWJvcnQgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgICAgIGFib3J0ZWQgPSBbdW5kZWZpbmVkLCAnYWJvcnQnLCAnYWJvcnQnXTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKCFqcVhIUikge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHNsb3QpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzbG90LnJlamVjdFdpdGgob3B0aW9ucy5jb250ZXh0LCBhYm9ydGVkKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBzZW5kKCk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGpxWEhSLmFib3J0KCk7XG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5fZW5oYW5jZVByb21pc2UocGlwZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gc2VuZCgpO1xuICAgICAgICB9LFxuXG4gICAgICAgIF9vbkFkZDogZnVuY3Rpb24gKGUsIGRhdGEpIHtcbiAgICAgICAgICAgIHZhciB0aGF0ID0gdGhpcyxcbiAgICAgICAgICAgICAgICByZXN1bHQgPSB0cnVlLFxuICAgICAgICAgICAgICAgIG9wdGlvbnMgPSAkLmV4dGVuZCh7fSwgdGhpcy5vcHRpb25zLCBkYXRhKSxcbiAgICAgICAgICAgICAgICBmaWxlcyA9IGRhdGEuZmlsZXMsXG4gICAgICAgICAgICAgICAgZmlsZXNMZW5ndGggPSBmaWxlcy5sZW5ndGgsXG4gICAgICAgICAgICAgICAgbGltaXQgPSBvcHRpb25zLmxpbWl0TXVsdGlGaWxlVXBsb2FkcyxcbiAgICAgICAgICAgICAgICBsaW1pdFNpemUgPSBvcHRpb25zLmxpbWl0TXVsdGlGaWxlVXBsb2FkU2l6ZSxcbiAgICAgICAgICAgICAgICBvdmVyaGVhZCA9IG9wdGlvbnMubGltaXRNdWx0aUZpbGVVcGxvYWRTaXplT3ZlcmhlYWQsXG4gICAgICAgICAgICAgICAgYmF0Y2hTaXplID0gMCxcbiAgICAgICAgICAgICAgICBwYXJhbU5hbWUgPSB0aGlzLl9nZXRQYXJhbU5hbWUob3B0aW9ucyksXG4gICAgICAgICAgICAgICAgcGFyYW1OYW1lU2V0LFxuICAgICAgICAgICAgICAgIHBhcmFtTmFtZVNsaWNlLFxuICAgICAgICAgICAgICAgIGZpbGVTZXQsXG4gICAgICAgICAgICAgICAgaSxcbiAgICAgICAgICAgICAgICBqID0gMDtcbiAgICAgICAgICAgIGlmICghZmlsZXNMZW5ndGgpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAobGltaXRTaXplICYmIGZpbGVzWzBdLnNpemUgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgIGxpbWl0U2l6ZSA9IHVuZGVmaW5lZDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmICghKG9wdGlvbnMuc2luZ2xlRmlsZVVwbG9hZHMgfHwgbGltaXQgfHwgbGltaXRTaXplKSB8fFxuICAgICAgICAgICAgICAgICAgICAhdGhpcy5faXNYSFJVcGxvYWQob3B0aW9ucykpIHtcbiAgICAgICAgICAgICAgICBmaWxlU2V0ID0gW2ZpbGVzXTtcbiAgICAgICAgICAgICAgICBwYXJhbU5hbWVTZXQgPSBbcGFyYW1OYW1lXTtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAoIShvcHRpb25zLnNpbmdsZUZpbGVVcGxvYWRzIHx8IGxpbWl0U2l6ZSkgJiYgbGltaXQpIHtcbiAgICAgICAgICAgICAgICBmaWxlU2V0ID0gW107XG4gICAgICAgICAgICAgICAgcGFyYW1OYW1lU2V0ID0gW107XG4gICAgICAgICAgICAgICAgZm9yIChpID0gMDsgaSA8IGZpbGVzTGVuZ3RoOyBpICs9IGxpbWl0KSB7XG4gICAgICAgICAgICAgICAgICAgIGZpbGVTZXQucHVzaChmaWxlcy5zbGljZShpLCBpICsgbGltaXQpKTtcbiAgICAgICAgICAgICAgICAgICAgcGFyYW1OYW1lU2xpY2UgPSBwYXJhbU5hbWUuc2xpY2UoaSwgaSArIGxpbWl0KTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKCFwYXJhbU5hbWVTbGljZS5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHBhcmFtTmFtZVNsaWNlID0gcGFyYW1OYW1lO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIHBhcmFtTmFtZVNldC5wdXNoKHBhcmFtTmFtZVNsaWNlKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGVsc2UgaWYgKCFvcHRpb25zLnNpbmdsZUZpbGVVcGxvYWRzICYmIGxpbWl0U2l6ZSkge1xuICAgICAgICAgICAgICAgIGZpbGVTZXQgPSBbXTtcbiAgICAgICAgICAgICAgICBwYXJhbU5hbWVTZXQgPSBbXTtcbiAgICAgICAgICAgICAgICBmb3IgKGkgPSAwOyBpIDwgZmlsZXNMZW5ndGg7IGkgPSBpICsgMSkge1xuICAgICAgICAgICAgICAgICAgICBiYXRjaFNpemUgKz0gZmlsZXNbaV0uc2l6ZSArIG92ZXJoZWFkO1xuICAgICAgICAgICAgICAgICAgICBpZiAoaSArIDEgPT09IGZpbGVzTGVuZ3RoIHx8XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgKChiYXRjaFNpemUgKyBmaWxlc1tpICsgMV0uc2l6ZSArIG92ZXJoZWFkKSA+IGxpbWl0U2l6ZSkgfHxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAobGltaXQgJiYgaSArIDEgLSBqID49IGxpbWl0KSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgZmlsZVNldC5wdXNoKGZpbGVzLnNsaWNlKGosIGkgKyAxKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBwYXJhbU5hbWVTbGljZSA9IHBhcmFtTmFtZS5zbGljZShqLCBpICsgMSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoIXBhcmFtTmFtZVNsaWNlLmxlbmd0aCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhcmFtTmFtZVNsaWNlID0gcGFyYW1OYW1lO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgcGFyYW1OYW1lU2V0LnB1c2gocGFyYW1OYW1lU2xpY2UpO1xuICAgICAgICAgICAgICAgICAgICAgICAgaiA9IGkgKyAxO1xuICAgICAgICAgICAgICAgICAgICAgICAgYmF0Y2hTaXplID0gMDtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgcGFyYW1OYW1lU2V0ID0gcGFyYW1OYW1lO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZGF0YS5vcmlnaW5hbEZpbGVzID0gZmlsZXM7XG4gICAgICAgICAgICAkLmVhY2goZmlsZVNldCB8fCBmaWxlcywgZnVuY3Rpb24gKGluZGV4LCBlbGVtZW50KSB7XG4gICAgICAgICAgICAgICAgdmFyIG5ld0RhdGEgPSAkLmV4dGVuZCh7fSwgZGF0YSk7XG4gICAgICAgICAgICAgICAgbmV3RGF0YS5maWxlcyA9IGZpbGVTZXQgPyBlbGVtZW50IDogW2VsZW1lbnRdO1xuICAgICAgICAgICAgICAgIG5ld0RhdGEucGFyYW1OYW1lID0gcGFyYW1OYW1lU2V0W2luZGV4XTtcbiAgICAgICAgICAgICAgICB0aGF0Ll9pbml0UmVzcG9uc2VPYmplY3QobmV3RGF0YSk7XG4gICAgICAgICAgICAgICAgdGhhdC5faW5pdFByb2dyZXNzT2JqZWN0KG5ld0RhdGEpO1xuICAgICAgICAgICAgICAgIHRoYXQuX2FkZENvbnZlbmllbmNlTWV0aG9kcyhlLCBuZXdEYXRhKTtcbiAgICAgICAgICAgICAgICByZXN1bHQgPSB0aGF0Ll90cmlnZ2VyKFxuICAgICAgICAgICAgICAgICAgICAnYWRkJyxcbiAgICAgICAgICAgICAgICAgICAgJC5FdmVudCgnYWRkJywge2RlbGVnYXRlZEV2ZW50OiBlfSksXG4gICAgICAgICAgICAgICAgICAgIG5ld0RhdGFcbiAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgICAgIH0sXG5cbiAgICAgICAgX3JlcGxhY2VGaWxlSW5wdXQ6IGZ1bmN0aW9uIChkYXRhKSB7XG4gICAgICAgICAgICB2YXIgaW5wdXQgPSBkYXRhLmZpbGVJbnB1dCxcbiAgICAgICAgICAgICAgICBpbnB1dENsb25lID0gaW5wdXQuY2xvbmUodHJ1ZSksXG4gICAgICAgICAgICAgICAgcmVzdG9yZUZvY3VzID0gaW5wdXQuaXMoZG9jdW1lbnQuYWN0aXZlRWxlbWVudCk7XG4gICAgICAgICAgICAvLyBBZGQgYSByZWZlcmVuY2UgZm9yIHRoZSBuZXcgY2xvbmVkIGZpbGUgaW5wdXQgdG8gdGhlIGRhdGEgYXJndW1lbnQ6XG4gICAgICAgICAgICBkYXRhLmZpbGVJbnB1dENsb25lID0gaW5wdXRDbG9uZTtcbiAgICAgICAgICAgICQoJzxmb3JtPjwvZm9ybT4nKS5hcHBlbmQoaW5wdXRDbG9uZSlbMF0ucmVzZXQoKTtcbiAgICAgICAgICAgIC8vIERldGFjaGluZyBhbGxvd3MgdG8gaW5zZXJ0IHRoZSBmaWxlSW5wdXQgb24gYW5vdGhlciBmb3JtXG4gICAgICAgICAgICAvLyB3aXRob3V0IGxvb3NpbmcgdGhlIGZpbGUgaW5wdXQgdmFsdWU6XG4gICAgICAgICAgICBpbnB1dC5hZnRlcihpbnB1dENsb25lKS5kZXRhY2goKTtcbiAgICAgICAgICAgIC8vIElmIHRoZSBmaWxlSW5wdXQgaGFkIGZvY3VzIGJlZm9yZSBpdCB3YXMgZGV0YWNoZWQsXG4gICAgICAgICAgICAvLyByZXN0b3JlIGZvY3VzIHRvIHRoZSBpbnB1dENsb25lLlxuICAgICAgICAgICAgaWYgKHJlc3RvcmVGb2N1cykge1xuICAgICAgICAgICAgICAgIGlucHV0Q2xvbmUuZm9jdXMoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIC8vIEF2b2lkIG1lbW9yeSBsZWFrcyB3aXRoIHRoZSBkZXRhY2hlZCBmaWxlIGlucHV0OlxuICAgICAgICAgICAgJC5jbGVhbkRhdGEoaW5wdXQudW5iaW5kKCdyZW1vdmUnKSk7XG4gICAgICAgICAgICAvLyBSZXBsYWNlIHRoZSBvcmlnaW5hbCBmaWxlIGlucHV0IGVsZW1lbnQgaW4gdGhlIGZpbGVJbnB1dFxuICAgICAgICAgICAgLy8gZWxlbWVudHMgc2V0IHdpdGggdGhlIGNsb25lLCB3aGljaCBoYXMgYmVlbiBjb3BpZWQgaW5jbHVkaW5nXG4gICAgICAgICAgICAvLyBldmVudCBoYW5kbGVyczpcbiAgICAgICAgICAgIHRoaXMub3B0aW9ucy5maWxlSW5wdXQgPSB0aGlzLm9wdGlvbnMuZmlsZUlucHV0Lm1hcChmdW5jdGlvbiAoaSwgZWwpIHtcbiAgICAgICAgICAgICAgICBpZiAoZWwgPT09IGlucHV0WzBdKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBpbnB1dENsb25lWzBdO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICByZXR1cm4gZWw7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIC8vIElmIHRoZSB3aWRnZXQgaGFzIGJlZW4gaW5pdGlhbGl6ZWQgb24gdGhlIGZpbGUgaW5wdXQgaXRzZWxmLFxuICAgICAgICAgICAgLy8gb3ZlcnJpZGUgdGhpcy5lbGVtZW50IHdpdGggdGhlIGZpbGUgaW5wdXQgY2xvbmU6XG4gICAgICAgICAgICBpZiAoaW5wdXRbMF0gPT09IHRoaXMuZWxlbWVudFswXSkge1xuICAgICAgICAgICAgICAgIHRoaXMuZWxlbWVudCA9IGlucHV0Q2xvbmU7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0sXG5cbiAgICAgICAgX2hhbmRsZUZpbGVUcmVlRW50cnk6IGZ1bmN0aW9uIChlbnRyeSwgcGF0aCkge1xuICAgICAgICAgICAgdmFyIHRoYXQgPSB0aGlzLFxuICAgICAgICAgICAgICAgIGRmZCA9ICQuRGVmZXJyZWQoKSxcbiAgICAgICAgICAgICAgICBlbnRyaWVzID0gW10sXG4gICAgICAgICAgICAgICAgZGlyUmVhZGVyLFxuICAgICAgICAgICAgICAgIGVycm9ySGFuZGxlciA9IGZ1bmN0aW9uIChlKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChlICYmICFlLmVudHJ5KSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBlLmVudHJ5ID0gZW50cnk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgLy8gU2luY2UgJC53aGVuIHJldHVybnMgaW1tZWRpYXRlbHkgaWYgb25lXG4gICAgICAgICAgICAgICAgICAgIC8vIERlZmVycmVkIGlzIHJlamVjdGVkLCB3ZSB1c2UgcmVzb2x2ZSBpbnN0ZWFkLlxuICAgICAgICAgICAgICAgICAgICAvLyBUaGlzIGFsbG93cyB2YWxpZCBmaWxlcyBhbmQgaW52YWxpZCBpdGVtc1xuICAgICAgICAgICAgICAgICAgICAvLyB0byBiZSByZXR1cm5lZCB0b2dldGhlciBpbiBvbmUgc2V0OlxuICAgICAgICAgICAgICAgICAgICBkZmQucmVzb2x2ZShbZV0pO1xuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgc3VjY2Vzc0hhbmRsZXIgPSBmdW5jdGlvbiAoZW50cmllcykge1xuICAgICAgICAgICAgICAgICAgICB0aGF0Ll9oYW5kbGVGaWxlVHJlZUVudHJpZXMoXG4gICAgICAgICAgICAgICAgICAgICAgICBlbnRyaWVzLFxuICAgICAgICAgICAgICAgICAgICAgICAgcGF0aCArIGVudHJ5Lm5hbWUgKyAnLydcbiAgICAgICAgICAgICAgICAgICAgKS5kb25lKGZ1bmN0aW9uIChmaWxlcykge1xuICAgICAgICAgICAgICAgICAgICAgICAgZGZkLnJlc29sdmUoZmlsZXMpO1xuICAgICAgICAgICAgICAgICAgICB9KS5mYWlsKGVycm9ySGFuZGxlcik7XG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICByZWFkRW50cmllcyA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICAgICAgZGlyUmVhZGVyLnJlYWRFbnRyaWVzKGZ1bmN0aW9uIChyZXN1bHRzKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoIXJlc3VsdHMubGVuZ3RoKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc3VjY2Vzc0hhbmRsZXIoZW50cmllcyk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVudHJpZXMgPSBlbnRyaWVzLmNvbmNhdChyZXN1bHRzKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWFkRW50cmllcygpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9LCBlcnJvckhhbmRsZXIpO1xuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICBwYXRoID0gcGF0aCB8fCAnJztcbiAgICAgICAgICAgIGlmIChlbnRyeS5pc0ZpbGUpIHtcbiAgICAgICAgICAgICAgICBpZiAoZW50cnkuX2ZpbGUpIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gV29ya2Fyb3VuZCBmb3IgQ2hyb21lIGJ1ZyAjMTQ5NzM1XG4gICAgICAgICAgICAgICAgICAgIGVudHJ5Ll9maWxlLnJlbGF0aXZlUGF0aCA9IHBhdGg7XG4gICAgICAgICAgICAgICAgICAgIGRmZC5yZXNvbHZlKGVudHJ5Ll9maWxlKTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBlbnRyeS5maWxlKGZ1bmN0aW9uIChmaWxlKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBmaWxlLnJlbGF0aXZlUGF0aCA9IHBhdGg7XG4gICAgICAgICAgICAgICAgICAgICAgICBkZmQucmVzb2x2ZShmaWxlKTtcbiAgICAgICAgICAgICAgICAgICAgfSwgZXJyb3JIYW5kbGVyKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGVsc2UgaWYgKGVudHJ5LmlzRGlyZWN0b3J5KSB7XG4gICAgICAgICAgICAgICAgZGlyUmVhZGVyID0gZW50cnkuY3JlYXRlUmVhZGVyKCk7XG4gICAgICAgICAgICAgICAgcmVhZEVudHJpZXMoKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgLy8gUmV0dXJuIGFuIGVtcHkgbGlzdCBmb3IgZmlsZSBzeXN0ZW0gaXRlbXNcbiAgICAgICAgICAgICAgICAvLyBvdGhlciB0aGFuIGZpbGVzIG9yIGRpcmVjdG9yaWVzOlxuICAgICAgICAgICAgICAgIGRmZC5yZXNvbHZlKFtdKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBkZmQucHJvbWlzZSgpO1xuICAgICAgICB9LFxuXG4gICAgICAgIF9oYW5kbGVGaWxlVHJlZUVudHJpZXM6IGZ1bmN0aW9uIChlbnRyaWVzLCBwYXRoKSB7XG4gICAgICAgICAgICB2YXIgdGhhdCA9IHRoaXM7XG4gICAgICAgICAgICByZXR1cm4gJC53aGVuLmFwcGx5KFxuICAgICAgICAgICAgICAgICQsXG4gICAgICAgICAgICAgICAgJC5tYXAoZW50cmllcywgZnVuY3Rpb24gKGVudHJ5KSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB0aGF0Ll9oYW5kbGVGaWxlVHJlZUVudHJ5KGVudHJ5LCBwYXRoKTtcbiAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgKS50aGVuKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gQXJyYXkucHJvdG90eXBlLmNvbmNhdC5hcHBseShcbiAgICAgICAgICAgICAgICAgICAgW10sXG4gICAgICAgICAgICAgICAgICAgIGFyZ3VtZW50c1xuICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSxcblxuICAgICAgICBfZ2V0RHJvcHBlZEZpbGVzOiBmdW5jdGlvbiAoZGF0YVRyYW5zZmVyKSB7XG4gICAgICAgICAgICBkYXRhVHJhbnNmZXIgPSBkYXRhVHJhbnNmZXIgfHwge307XG4gICAgICAgICAgICB2YXIgaXRlbXMgPSBkYXRhVHJhbnNmZXIuaXRlbXM7XG4gICAgICAgICAgICBpZiAoaXRlbXMgJiYgaXRlbXMubGVuZ3RoICYmIChpdGVtc1swXS53ZWJraXRHZXRBc0VudHJ5IHx8XG4gICAgICAgICAgICAgICAgICAgIGl0ZW1zWzBdLmdldEFzRW50cnkpKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2hhbmRsZUZpbGVUcmVlRW50cmllcyhcbiAgICAgICAgICAgICAgICAgICAgJC5tYXAoaXRlbXMsIGZ1bmN0aW9uIChpdGVtKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgZW50cnk7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoaXRlbS53ZWJraXRHZXRBc0VudHJ5KSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZW50cnkgPSBpdGVtLndlYmtpdEdldEFzRW50cnkoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoZW50cnkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gV29ya2Fyb3VuZCBmb3IgQ2hyb21lIGJ1ZyAjMTQ5NzM1OlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbnRyeS5fZmlsZSA9IGl0ZW0uZ2V0QXNGaWxlKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBlbnRyeTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBpdGVtLmdldEFzRW50cnkoKTtcbiAgICAgICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuICQuRGVmZXJyZWQoKS5yZXNvbHZlKFxuICAgICAgICAgICAgICAgICQubWFrZUFycmF5KGRhdGFUcmFuc2Zlci5maWxlcylcbiAgICAgICAgICAgICkucHJvbWlzZSgpO1xuICAgICAgICB9LFxuXG4gICAgICAgIF9nZXRTaW5nbGVGaWxlSW5wdXRGaWxlczogZnVuY3Rpb24gKGZpbGVJbnB1dCkge1xuICAgICAgICAgICAgZmlsZUlucHV0ID0gJChmaWxlSW5wdXQpO1xuICAgICAgICAgICAgdmFyIGVudHJpZXMgPSBmaWxlSW5wdXQucHJvcCgnd2Via2l0RW50cmllcycpIHx8XG4gICAgICAgICAgICAgICAgICAgIGZpbGVJbnB1dC5wcm9wKCdlbnRyaWVzJyksXG4gICAgICAgICAgICAgICAgZmlsZXMsXG4gICAgICAgICAgICAgICAgdmFsdWU7XG4gICAgICAgICAgICBpZiAoZW50cmllcyAmJiBlbnRyaWVzLmxlbmd0aCkge1xuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLl9oYW5kbGVGaWxlVHJlZUVudHJpZXMoZW50cmllcyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBmaWxlcyA9ICQubWFrZUFycmF5KGZpbGVJbnB1dC5wcm9wKCdmaWxlcycpKTtcbiAgICAgICAgICAgIGlmICghZmlsZXMubGVuZ3RoKSB7XG4gICAgICAgICAgICAgICAgdmFsdWUgPSBmaWxlSW5wdXQucHJvcCgndmFsdWUnKTtcbiAgICAgICAgICAgICAgICBpZiAoIXZhbHVlKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiAkLkRlZmVycmVkKCkucmVzb2x2ZShbXSkucHJvbWlzZSgpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAvLyBJZiB0aGUgZmlsZXMgcHJvcGVydHkgaXMgbm90IGF2YWlsYWJsZSwgdGhlIGJyb3dzZXIgZG9lcyBub3RcbiAgICAgICAgICAgICAgICAvLyBzdXBwb3J0IHRoZSBGaWxlIEFQSSBhbmQgd2UgYWRkIGEgcHNldWRvIEZpbGUgb2JqZWN0IHdpdGhcbiAgICAgICAgICAgICAgICAvLyB0aGUgaW5wdXQgdmFsdWUgYXMgbmFtZSB3aXRoIHBhdGggaW5mb3JtYXRpb24gcmVtb3ZlZDpcbiAgICAgICAgICAgICAgICBmaWxlcyA9IFt7bmFtZTogdmFsdWUucmVwbGFjZSgvXi4qXFxcXC8sICcnKX1dO1xuICAgICAgICAgICAgfSBlbHNlIGlmIChmaWxlc1swXS5uYW1lID09PSB1bmRlZmluZWQgJiYgZmlsZXNbMF0uZmlsZU5hbWUpIHtcbiAgICAgICAgICAgICAgICAvLyBGaWxlIG5vcm1hbGl6YXRpb24gZm9yIFNhZmFyaSA0IGFuZCBGaXJlZm94IDM6XG4gICAgICAgICAgICAgICAgJC5lYWNoKGZpbGVzLCBmdW5jdGlvbiAoaW5kZXgsIGZpbGUpIHtcbiAgICAgICAgICAgICAgICAgICAgZmlsZS5uYW1lID0gZmlsZS5maWxlTmFtZTtcbiAgICAgICAgICAgICAgICAgICAgZmlsZS5zaXplID0gZmlsZS5maWxlU2l6ZTtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiAkLkRlZmVycmVkKCkucmVzb2x2ZShmaWxlcykucHJvbWlzZSgpO1xuICAgICAgICB9LFxuXG4gICAgICAgIF9nZXRGaWxlSW5wdXRGaWxlczogZnVuY3Rpb24gKGZpbGVJbnB1dCkge1xuICAgICAgICAgICAgaWYgKCEoZmlsZUlucHV0IGluc3RhbmNlb2YgJCkgfHwgZmlsZUlucHV0Lmxlbmd0aCA9PT0gMSkge1xuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLl9nZXRTaW5nbGVGaWxlSW5wdXRGaWxlcyhmaWxlSW5wdXQpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuICQud2hlbi5hcHBseShcbiAgICAgICAgICAgICAgICAkLFxuICAgICAgICAgICAgICAgICQubWFwKGZpbGVJbnB1dCwgdGhpcy5fZ2V0U2luZ2xlRmlsZUlucHV0RmlsZXMpXG4gICAgICAgICAgICApLnRoZW4oZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBBcnJheS5wcm90b3R5cGUuY29uY2F0LmFwcGx5KFxuICAgICAgICAgICAgICAgICAgICBbXSxcbiAgICAgICAgICAgICAgICAgICAgYXJndW1lbnRzXG4gICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9LFxuXG4gICAgICAgIF9vbkNoYW5nZTogZnVuY3Rpb24gKGUpIHtcbiAgICAgICAgICAgIHZhciB0aGF0ID0gdGhpcyxcbiAgICAgICAgICAgICAgICBkYXRhID0ge1xuICAgICAgICAgICAgICAgICAgICBmaWxlSW5wdXQ6ICQoZS50YXJnZXQpLFxuICAgICAgICAgICAgICAgICAgICBmb3JtOiAkKGUudGFyZ2V0LmZvcm0pXG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIHRoaXMuX2dldEZpbGVJbnB1dEZpbGVzKGRhdGEuZmlsZUlucHV0KS5hbHdheXMoZnVuY3Rpb24gKGZpbGVzKSB7XG4gICAgICAgICAgICAgICAgZGF0YS5maWxlcyA9IGZpbGVzO1xuICAgICAgICAgICAgICAgIGlmICh0aGF0Lm9wdGlvbnMucmVwbGFjZUZpbGVJbnB1dCkge1xuICAgICAgICAgICAgICAgICAgICB0aGF0Ll9yZXBsYWNlRmlsZUlucHV0KGRhdGEpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpZiAodGhhdC5fdHJpZ2dlcihcbiAgICAgICAgICAgICAgICAgICAgICAgICdjaGFuZ2UnLFxuICAgICAgICAgICAgICAgICAgICAgICAgJC5FdmVudCgnY2hhbmdlJywge2RlbGVnYXRlZEV2ZW50OiBlfSksXG4gICAgICAgICAgICAgICAgICAgICAgICBkYXRhXG4gICAgICAgICAgICAgICAgICAgICkgIT09IGZhbHNlKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoYXQuX29uQWRkKGUsIGRhdGEpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9LFxuXG4gICAgICAgIF9vblBhc3RlOiBmdW5jdGlvbiAoZSkge1xuICAgICAgICAgICAgdmFyIGl0ZW1zID0gZS5vcmlnaW5hbEV2ZW50ICYmIGUub3JpZ2luYWxFdmVudC5jbGlwYm9hcmREYXRhICYmXG4gICAgICAgICAgICAgICAgICAgIGUub3JpZ2luYWxFdmVudC5jbGlwYm9hcmREYXRhLml0ZW1zLFxuICAgICAgICAgICAgICAgIGRhdGEgPSB7ZmlsZXM6IFtdfTtcbiAgICAgICAgICAgIGlmIChpdGVtcyAmJiBpdGVtcy5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgICAkLmVhY2goaXRlbXMsIGZ1bmN0aW9uIChpbmRleCwgaXRlbSkge1xuICAgICAgICAgICAgICAgICAgICB2YXIgZmlsZSA9IGl0ZW0uZ2V0QXNGaWxlICYmIGl0ZW0uZ2V0QXNGaWxlKCk7XG4gICAgICAgICAgICAgICAgICAgIGlmIChmaWxlKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBkYXRhLmZpbGVzLnB1c2goZmlsZSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5fdHJpZ2dlcihcbiAgICAgICAgICAgICAgICAgICAgICAgICdwYXN0ZScsXG4gICAgICAgICAgICAgICAgICAgICAgICAkLkV2ZW50KCdwYXN0ZScsIHtkZWxlZ2F0ZWRFdmVudDogZX0pLFxuICAgICAgICAgICAgICAgICAgICAgICAgZGF0YVxuICAgICAgICAgICAgICAgICAgICApICE9PSBmYWxzZSkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLl9vbkFkZChlLCBkYXRhKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH0sXG5cbiAgICAgICAgX29uRHJvcDogZnVuY3Rpb24gKGUpIHtcbiAgICAgICAgICAgIGUuZGF0YVRyYW5zZmVyID0gZS5vcmlnaW5hbEV2ZW50ICYmIGUub3JpZ2luYWxFdmVudC5kYXRhVHJhbnNmZXI7XG4gICAgICAgICAgICB2YXIgdGhhdCA9IHRoaXMsXG4gICAgICAgICAgICAgICAgZGF0YVRyYW5zZmVyID0gZS5kYXRhVHJhbnNmZXIsXG4gICAgICAgICAgICAgICAgZGF0YSA9IHt9O1xuICAgICAgICAgICAgaWYgKGRhdGFUcmFuc2ZlciAmJiBkYXRhVHJhbnNmZXIuZmlsZXMgJiYgZGF0YVRyYW5zZmVyLmZpbGVzLmxlbmd0aCkge1xuICAgICAgICAgICAgICAgIGUucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgICAgICAgICB0aGlzLl9nZXREcm9wcGVkRmlsZXMoZGF0YVRyYW5zZmVyKS5hbHdheXMoZnVuY3Rpb24gKGZpbGVzKSB7XG4gICAgICAgICAgICAgICAgICAgIGRhdGEuZmlsZXMgPSBmaWxlcztcbiAgICAgICAgICAgICAgICAgICAgaWYgKHRoYXQuX3RyaWdnZXIoXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgJ2Ryb3AnLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICQuRXZlbnQoJ2Ryb3AnLCB7ZGVsZWdhdGVkRXZlbnQ6IGV9KSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkYXRhXG4gICAgICAgICAgICAgICAgICAgICAgICApICE9PSBmYWxzZSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhhdC5fb25BZGQoZSwgZGF0YSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSxcblxuICAgICAgICBfb25EcmFnT3ZlcjogZ2V0RHJhZ0hhbmRsZXIoJ2RyYWdvdmVyJyksXG5cbiAgICAgICAgX29uRHJhZ0VudGVyOiBnZXREcmFnSGFuZGxlcignZHJhZ2VudGVyJyksXG5cbiAgICAgICAgX29uRHJhZ0xlYXZlOiBnZXREcmFnSGFuZGxlcignZHJhZ2xlYXZlJyksXG5cbiAgICAgICAgX2luaXRFdmVudEhhbmRsZXJzOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBpZiAodGhpcy5faXNYSFJVcGxvYWQodGhpcy5vcHRpb25zKSkge1xuICAgICAgICAgICAgICAgIHRoaXMuX29uKHRoaXMub3B0aW9ucy5kcm9wWm9uZSwge1xuICAgICAgICAgICAgICAgICAgICBkcmFnb3ZlcjogdGhpcy5fb25EcmFnT3ZlcixcbiAgICAgICAgICAgICAgICAgICAgZHJvcDogdGhpcy5fb25Ecm9wLFxuICAgICAgICAgICAgICAgICAgICAvLyBldmVudC5wcmV2ZW50RGVmYXVsdCgpIG9uIGRyYWdlbnRlciBpcyByZXF1aXJlZCBmb3IgSUUxMCs6XG4gICAgICAgICAgICAgICAgICAgIGRyYWdlbnRlcjogdGhpcy5fb25EcmFnRW50ZXIsXG4gICAgICAgICAgICAgICAgICAgIC8vIGRyYWdsZWF2ZSBpcyBub3QgcmVxdWlyZWQsIGJ1dCBhZGRlZCBmb3IgY29tcGxldGVuZXNzOlxuICAgICAgICAgICAgICAgICAgICBkcmFnbGVhdmU6IHRoaXMuX29uRHJhZ0xlYXZlXG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgdGhpcy5fb24odGhpcy5vcHRpb25zLnBhc3RlWm9uZSwge1xuICAgICAgICAgICAgICAgICAgICBwYXN0ZTogdGhpcy5fb25QYXN0ZVxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKCQuc3VwcG9ydC5maWxlSW5wdXQpIHtcbiAgICAgICAgICAgICAgICB0aGlzLl9vbih0aGlzLm9wdGlvbnMuZmlsZUlucHV0LCB7XG4gICAgICAgICAgICAgICAgICAgIGNoYW5nZTogdGhpcy5fb25DaGFuZ2VcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSxcblxuICAgICAgICBfZGVzdHJveUV2ZW50SGFuZGxlcnM6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHRoaXMuX29mZih0aGlzLm9wdGlvbnMuZHJvcFpvbmUsICdkcmFnZW50ZXIgZHJhZ2xlYXZlIGRyYWdvdmVyIGRyb3AnKTtcbiAgICAgICAgICAgIHRoaXMuX29mZih0aGlzLm9wdGlvbnMucGFzdGVab25lLCAncGFzdGUnKTtcbiAgICAgICAgICAgIHRoaXMuX29mZih0aGlzLm9wdGlvbnMuZmlsZUlucHV0LCAnY2hhbmdlJyk7XG4gICAgICAgIH0sXG5cbiAgICAgICAgX2Rlc3Ryb3k6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHRoaXMuX2Rlc3Ryb3lFdmVudEhhbmRsZXJzKCk7XG4gICAgICAgIH0sXG5cbiAgICAgICAgX3NldE9wdGlvbjogZnVuY3Rpb24gKGtleSwgdmFsdWUpIHtcbiAgICAgICAgICAgIHZhciByZWluaXQgPSAkLmluQXJyYXkoa2V5LCB0aGlzLl9zcGVjaWFsT3B0aW9ucykgIT09IC0xO1xuICAgICAgICAgICAgaWYgKHJlaW5pdCkge1xuICAgICAgICAgICAgICAgIHRoaXMuX2Rlc3Ryb3lFdmVudEhhbmRsZXJzKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aGlzLl9zdXBlcihrZXksIHZhbHVlKTtcbiAgICAgICAgICAgIGlmIChyZWluaXQpIHtcbiAgICAgICAgICAgICAgICB0aGlzLl9pbml0U3BlY2lhbE9wdGlvbnMoKTtcbiAgICAgICAgICAgICAgICB0aGlzLl9pbml0RXZlbnRIYW5kbGVycygpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9LFxuXG4gICAgICAgIF9pbml0U3BlY2lhbE9wdGlvbnM6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHZhciBvcHRpb25zID0gdGhpcy5vcHRpb25zO1xuICAgICAgICAgICAgaWYgKG9wdGlvbnMuZmlsZUlucHV0ID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICBvcHRpb25zLmZpbGVJbnB1dCA9IHRoaXMuZWxlbWVudC5pcygnaW5wdXRbdHlwZT1cImZpbGVcIl0nKSA/XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmVsZW1lbnQgOiB0aGlzLmVsZW1lbnQuZmluZCgnaW5wdXRbdHlwZT1cImZpbGVcIl0nKTtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAoIShvcHRpb25zLmZpbGVJbnB1dCBpbnN0YW5jZW9mICQpKSB7XG4gICAgICAgICAgICAgICAgb3B0aW9ucy5maWxlSW5wdXQgPSAkKG9wdGlvbnMuZmlsZUlucHV0KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmICghKG9wdGlvbnMuZHJvcFpvbmUgaW5zdGFuY2VvZiAkKSkge1xuICAgICAgICAgICAgICAgIG9wdGlvbnMuZHJvcFpvbmUgPSAkKG9wdGlvbnMuZHJvcFpvbmUpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKCEob3B0aW9ucy5wYXN0ZVpvbmUgaW5zdGFuY2VvZiAkKSkge1xuICAgICAgICAgICAgICAgIG9wdGlvbnMucGFzdGVab25lID0gJChvcHRpb25zLnBhc3RlWm9uZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0sXG5cbiAgICAgICAgX2dldFJlZ0V4cDogZnVuY3Rpb24gKHN0cikge1xuICAgICAgICAgICAgdmFyIHBhcnRzID0gc3RyLnNwbGl0KCcvJyksXG4gICAgICAgICAgICAgICAgbW9kaWZpZXJzID0gcGFydHMucG9wKCk7XG4gICAgICAgICAgICBwYXJ0cy5zaGlmdCgpO1xuICAgICAgICAgICAgcmV0dXJuIG5ldyBSZWdFeHAocGFydHMuam9pbignLycpLCBtb2RpZmllcnMpO1xuICAgICAgICB9LFxuXG4gICAgICAgIF9pc1JlZ0V4cE9wdGlvbjogZnVuY3Rpb24gKGtleSwgdmFsdWUpIHtcbiAgICAgICAgICAgIHJldHVybiBrZXkgIT09ICd1cmwnICYmICQudHlwZSh2YWx1ZSkgPT09ICdzdHJpbmcnICYmXG4gICAgICAgICAgICAgICAgL15cXC8uKlxcL1tpZ21dezAsM30kLy50ZXN0KHZhbHVlKTtcbiAgICAgICAgfSxcblxuICAgICAgICBfaW5pdERhdGFBdHRyaWJ1dGVzOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICB2YXIgdGhhdCA9IHRoaXMsXG4gICAgICAgICAgICAgICAgb3B0aW9ucyA9IHRoaXMub3B0aW9ucyxcbiAgICAgICAgICAgICAgICBkYXRhID0gdGhpcy5lbGVtZW50LmRhdGEoKTtcbiAgICAgICAgICAgIC8vIEluaXRpYWxpemUgb3B0aW9ucyBzZXQgdmlhIEhUTUw1IGRhdGEtYXR0cmlidXRlczpcbiAgICAgICAgICAgICQuZWFjaChcbiAgICAgICAgICAgICAgICB0aGlzLmVsZW1lbnRbMF0uYXR0cmlidXRlcyxcbiAgICAgICAgICAgICAgICBmdW5jdGlvbiAoaW5kZXgsIGF0dHIpIHtcbiAgICAgICAgICAgICAgICAgICAgdmFyIGtleSA9IGF0dHIubmFtZS50b0xvd2VyQ2FzZSgpLFxuICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWU7XG4gICAgICAgICAgICAgICAgICAgIGlmICgvXmRhdGEtLy50ZXN0KGtleSkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIENvbnZlcnQgaHlwaGVuLWF0ZWQga2V5IHRvIGNhbWVsQ2FzZTpcbiAgICAgICAgICAgICAgICAgICAgICAgIGtleSA9IGtleS5zbGljZSg1KS5yZXBsYWNlKC8tW2Etel0vZywgZnVuY3Rpb24gKHN0cikge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBzdHIuY2hhckF0KDEpLnRvVXBwZXJDYXNlKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhbHVlID0gZGF0YVtrZXldO1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHRoYXQuX2lzUmVnRXhwT3B0aW9uKGtleSwgdmFsdWUpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWUgPSB0aGF0Ll9nZXRSZWdFeHAodmFsdWUpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgb3B0aW9uc1trZXldID0gdmFsdWU7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICApO1xuICAgICAgICB9LFxuXG4gICAgICAgIF9jcmVhdGU6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHRoaXMuX2luaXREYXRhQXR0cmlidXRlcygpO1xuICAgICAgICAgICAgdGhpcy5faW5pdFNwZWNpYWxPcHRpb25zKCk7XG4gICAgICAgICAgICB0aGlzLl9zbG90cyA9IFtdO1xuICAgICAgICAgICAgdGhpcy5fc2VxdWVuY2UgPSB0aGlzLl9nZXRYSFJQcm9taXNlKHRydWUpO1xuICAgICAgICAgICAgdGhpcy5fc2VuZGluZyA9IHRoaXMuX2FjdGl2ZSA9IDA7XG4gICAgICAgICAgICB0aGlzLl9pbml0UHJvZ3Jlc3NPYmplY3QodGhpcyk7XG4gICAgICAgICAgICB0aGlzLl9pbml0RXZlbnRIYW5kbGVycygpO1xuICAgICAgICB9LFxuXG4gICAgICAgIC8vIFRoaXMgbWV0aG9kIGlzIGV4cG9zZWQgdG8gdGhlIHdpZGdldCBBUEkgYW5kIGFsbG93cyB0byBxdWVyeVxuICAgICAgICAvLyB0aGUgbnVtYmVyIG9mIGFjdGl2ZSB1cGxvYWRzOlxuICAgICAgICBhY3RpdmU6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9hY3RpdmU7XG4gICAgICAgIH0sXG5cbiAgICAgICAgLy8gVGhpcyBtZXRob2QgaXMgZXhwb3NlZCB0byB0aGUgd2lkZ2V0IEFQSSBhbmQgYWxsb3dzIHRvIHF1ZXJ5XG4gICAgICAgIC8vIHRoZSB3aWRnZXQgdXBsb2FkIHByb2dyZXNzLlxuICAgICAgICAvLyBJdCByZXR1cm5zIGFuIG9iamVjdCB3aXRoIGxvYWRlZCwgdG90YWwgYW5kIGJpdHJhdGUgcHJvcGVydGllc1xuICAgICAgICAvLyBmb3IgdGhlIHJ1bm5pbmcgdXBsb2FkczpcbiAgICAgICAgcHJvZ3Jlc3M6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9wcm9ncmVzcztcbiAgICAgICAgfSxcblxuICAgICAgICAvLyBUaGlzIG1ldGhvZCBpcyBleHBvc2VkIHRvIHRoZSB3aWRnZXQgQVBJIGFuZCBhbGxvd3MgYWRkaW5nIGZpbGVzXG4gICAgICAgIC8vIHVzaW5nIHRoZSBmaWxldXBsb2FkIEFQSS4gVGhlIGRhdGEgcGFyYW1ldGVyIGFjY2VwdHMgYW4gb2JqZWN0IHdoaWNoXG4gICAgICAgIC8vIG11c3QgaGF2ZSBhIGZpbGVzIHByb3BlcnR5IGFuZCBjYW4gY29udGFpbiBhZGRpdGlvbmFsIG9wdGlvbnM6XG4gICAgICAgIC8vIC5maWxldXBsb2FkKCdhZGQnLCB7ZmlsZXM6IGZpbGVzTGlzdH0pO1xuICAgICAgICBhZGQ6IGZ1bmN0aW9uIChkYXRhKSB7XG4gICAgICAgICAgICB2YXIgdGhhdCA9IHRoaXM7XG4gICAgICAgICAgICBpZiAoIWRhdGEgfHwgdGhpcy5vcHRpb25zLmRpc2FibGVkKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKGRhdGEuZmlsZUlucHV0ICYmICFkYXRhLmZpbGVzKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5fZ2V0RmlsZUlucHV0RmlsZXMoZGF0YS5maWxlSW5wdXQpLmFsd2F5cyhmdW5jdGlvbiAoZmlsZXMpIHtcbiAgICAgICAgICAgICAgICAgICAgZGF0YS5maWxlcyA9IGZpbGVzO1xuICAgICAgICAgICAgICAgICAgICB0aGF0Ll9vbkFkZChudWxsLCBkYXRhKTtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgZGF0YS5maWxlcyA9ICQubWFrZUFycmF5KGRhdGEuZmlsZXMpO1xuICAgICAgICAgICAgICAgIHRoaXMuX29uQWRkKG51bGwsIGRhdGEpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9LFxuXG4gICAgICAgIC8vIFRoaXMgbWV0aG9kIGlzIGV4cG9zZWQgdG8gdGhlIHdpZGdldCBBUEkgYW5kIGFsbG93cyBzZW5kaW5nIGZpbGVzXG4gICAgICAgIC8vIHVzaW5nIHRoZSBmaWxldXBsb2FkIEFQSS4gVGhlIGRhdGEgcGFyYW1ldGVyIGFjY2VwdHMgYW4gb2JqZWN0IHdoaWNoXG4gICAgICAgIC8vIG11c3QgaGF2ZSBhIGZpbGVzIG9yIGZpbGVJbnB1dCBwcm9wZXJ0eSBhbmQgY2FuIGNvbnRhaW4gYWRkaXRpb25hbCBvcHRpb25zOlxuICAgICAgICAvLyAuZmlsZXVwbG9hZCgnc2VuZCcsIHtmaWxlczogZmlsZXNMaXN0fSk7XG4gICAgICAgIC8vIFRoZSBtZXRob2QgcmV0dXJucyBhIFByb21pc2Ugb2JqZWN0IGZvciB0aGUgZmlsZSB1cGxvYWQgY2FsbC5cbiAgICAgICAgc2VuZDogZnVuY3Rpb24gKGRhdGEpIHtcbiAgICAgICAgICAgIGlmIChkYXRhICYmICF0aGlzLm9wdGlvbnMuZGlzYWJsZWQpIHtcbiAgICAgICAgICAgICAgICBpZiAoZGF0YS5maWxlSW5wdXQgJiYgIWRhdGEuZmlsZXMpIHtcbiAgICAgICAgICAgICAgICAgICAgdmFyIHRoYXQgPSB0aGlzLFxuICAgICAgICAgICAgICAgICAgICAgICAgZGZkID0gJC5EZWZlcnJlZCgpLFxuICAgICAgICAgICAgICAgICAgICAgICAgcHJvbWlzZSA9IGRmZC5wcm9taXNlKCksXG4gICAgICAgICAgICAgICAgICAgICAgICBqcVhIUixcbiAgICAgICAgICAgICAgICAgICAgICAgIGFib3J0ZWQ7XG4gICAgICAgICAgICAgICAgICAgIHByb21pc2UuYWJvcnQgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBhYm9ydGVkID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChqcVhIUikge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBqcVhIUi5hYm9ydCgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgZGZkLnJlamVjdChudWxsLCAnYWJvcnQnLCAnYWJvcnQnKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBwcm9taXNlO1xuICAgICAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgICAgICB0aGlzLl9nZXRGaWxlSW5wdXRGaWxlcyhkYXRhLmZpbGVJbnB1dCkuYWx3YXlzKFxuICAgICAgICAgICAgICAgICAgICAgICAgZnVuY3Rpb24gKGZpbGVzKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGFib3J0ZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoIWZpbGVzLmxlbmd0aCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZmQucmVqZWN0KCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZGF0YS5maWxlcyA9IGZpbGVzO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGpxWEhSID0gdGhhdC5fb25TZW5kKG51bGwsIGRhdGEpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGpxWEhSLnRoZW4oXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZ1bmN0aW9uIChyZXN1bHQsIHRleHRTdGF0dXMsIGpxWEhSKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZmQucmVzb2x2ZShyZXN1bHQsIHRleHRTdGF0dXMsIGpxWEhSKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZnVuY3Rpb24gKGpxWEhSLCB0ZXh0U3RhdHVzLCBlcnJvclRocm93bikge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGZkLnJlamVjdChqcVhIUiwgdGV4dFN0YXR1cywgZXJyb3JUaHJvd24pO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2VuaGFuY2VQcm9taXNlKHByb21pc2UpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBkYXRhLmZpbGVzID0gJC5tYWtlQXJyYXkoZGF0YS5maWxlcyk7XG4gICAgICAgICAgICAgICAgaWYgKGRhdGEuZmlsZXMubGVuZ3RoKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLl9vblNlbmQobnVsbCwgZGF0YSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2dldFhIUlByb21pc2UoZmFsc2UsIGRhdGEgJiYgZGF0YS5jb250ZXh0KTtcbiAgICAgICAgfVxuXG4gICAgfSk7XG5cbn0pKTtcblxuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIC4vbm9kZV9tb2R1bGVzL2JsdWVpbXAtZmlsZS11cGxvYWQvanMvanF1ZXJ5LmZpbGV1cGxvYWQuanNcbi8vIG1vZHVsZSBpZCA9IDM1XG4vLyBtb2R1bGUgY2h1bmtzID0gMCIsIi8qIVxuICogalF1ZXJ5IFVJIFdpZGdldCAxLjEyLjFcbiAqIGh0dHA6Ly9qcXVlcnl1aS5jb21cbiAqXG4gKiBDb3B5cmlnaHQgalF1ZXJ5IEZvdW5kYXRpb24gYW5kIG90aGVyIGNvbnRyaWJ1dG9yc1xuICogUmVsZWFzZWQgdW5kZXIgdGhlIE1JVCBsaWNlbnNlLlxuICogaHR0cDovL2pxdWVyeS5vcmcvbGljZW5zZVxuICovXG5cbi8vPj5sYWJlbDogV2lkZ2V0XG4vLz4+Z3JvdXA6IENvcmVcbi8vPj5kZXNjcmlwdGlvbjogUHJvdmlkZXMgYSBmYWN0b3J5IGZvciBjcmVhdGluZyBzdGF0ZWZ1bCB3aWRnZXRzIHdpdGggYSBjb21tb24gQVBJLlxuLy8+PmRvY3M6IGh0dHA6Ly9hcGkuanF1ZXJ5dWkuY29tL2pRdWVyeS53aWRnZXQvXG4vLz4+ZGVtb3M6IGh0dHA6Ly9qcXVlcnl1aS5jb20vd2lkZ2V0L1xuXG4oIGZ1bmN0aW9uKCBmYWN0b3J5ICkge1xuXHRpZiAoIHR5cGVvZiBkZWZpbmUgPT09IFwiZnVuY3Rpb25cIiAmJiBkZWZpbmUuYW1kICkge1xuXG5cdFx0Ly8gQU1ELiBSZWdpc3RlciBhcyBhbiBhbm9ueW1vdXMgbW9kdWxlLlxuXHRcdGRlZmluZSggWyBcImpxdWVyeVwiLCBcIi4vdmVyc2lvblwiIF0sIGZhY3RvcnkgKTtcblx0fSBlbHNlIHtcblxuXHRcdC8vIEJyb3dzZXIgZ2xvYmFsc1xuXHRcdGZhY3RvcnkoIGpRdWVyeSApO1xuXHR9XG59KCBmdW5jdGlvbiggJCApIHtcblxudmFyIHdpZGdldFV1aWQgPSAwO1xudmFyIHdpZGdldFNsaWNlID0gQXJyYXkucHJvdG90eXBlLnNsaWNlO1xuXG4kLmNsZWFuRGF0YSA9ICggZnVuY3Rpb24oIG9yaWcgKSB7XG5cdHJldHVybiBmdW5jdGlvbiggZWxlbXMgKSB7XG5cdFx0dmFyIGV2ZW50cywgZWxlbSwgaTtcblx0XHRmb3IgKCBpID0gMDsgKCBlbGVtID0gZWxlbXNbIGkgXSApICE9IG51bGw7IGkrKyApIHtcblx0XHRcdHRyeSB7XG5cblx0XHRcdFx0Ly8gT25seSB0cmlnZ2VyIHJlbW92ZSB3aGVuIG5lY2Vzc2FyeSB0byBzYXZlIHRpbWVcblx0XHRcdFx0ZXZlbnRzID0gJC5fZGF0YSggZWxlbSwgXCJldmVudHNcIiApO1xuXHRcdFx0XHRpZiAoIGV2ZW50cyAmJiBldmVudHMucmVtb3ZlICkge1xuXHRcdFx0XHRcdCQoIGVsZW0gKS50cmlnZ2VySGFuZGxlciggXCJyZW1vdmVcIiApO1xuXHRcdFx0XHR9XG5cblx0XHRcdC8vIEh0dHA6Ly9idWdzLmpxdWVyeS5jb20vdGlja2V0LzgyMzVcblx0XHRcdH0gY2F0Y2ggKCBlICkge31cblx0XHR9XG5cdFx0b3JpZyggZWxlbXMgKTtcblx0fTtcbn0gKSggJC5jbGVhbkRhdGEgKTtcblxuJC53aWRnZXQgPSBmdW5jdGlvbiggbmFtZSwgYmFzZSwgcHJvdG90eXBlICkge1xuXHR2YXIgZXhpc3RpbmdDb25zdHJ1Y3RvciwgY29uc3RydWN0b3IsIGJhc2VQcm90b3R5cGU7XG5cblx0Ly8gUHJveGllZFByb3RvdHlwZSBhbGxvd3MgdGhlIHByb3ZpZGVkIHByb3RvdHlwZSB0byByZW1haW4gdW5tb2RpZmllZFxuXHQvLyBzbyB0aGF0IGl0IGNhbiBiZSB1c2VkIGFzIGEgbWl4aW4gZm9yIG11bHRpcGxlIHdpZGdldHMgKCM4ODc2KVxuXHR2YXIgcHJveGllZFByb3RvdHlwZSA9IHt9O1xuXG5cdHZhciBuYW1lc3BhY2UgPSBuYW1lLnNwbGl0KCBcIi5cIiApWyAwIF07XG5cdG5hbWUgPSBuYW1lLnNwbGl0KCBcIi5cIiApWyAxIF07XG5cdHZhciBmdWxsTmFtZSA9IG5hbWVzcGFjZSArIFwiLVwiICsgbmFtZTtcblxuXHRpZiAoICFwcm90b3R5cGUgKSB7XG5cdFx0cHJvdG90eXBlID0gYmFzZTtcblx0XHRiYXNlID0gJC5XaWRnZXQ7XG5cdH1cblxuXHRpZiAoICQuaXNBcnJheSggcHJvdG90eXBlICkgKSB7XG5cdFx0cHJvdG90eXBlID0gJC5leHRlbmQuYXBwbHkoIG51bGwsIFsge30gXS5jb25jYXQoIHByb3RvdHlwZSApICk7XG5cdH1cblxuXHQvLyBDcmVhdGUgc2VsZWN0b3IgZm9yIHBsdWdpblxuXHQkLmV4cHJbIFwiOlwiIF1bIGZ1bGxOYW1lLnRvTG93ZXJDYXNlKCkgXSA9IGZ1bmN0aW9uKCBlbGVtICkge1xuXHRcdHJldHVybiAhISQuZGF0YSggZWxlbSwgZnVsbE5hbWUgKTtcblx0fTtcblxuXHQkWyBuYW1lc3BhY2UgXSA9ICRbIG5hbWVzcGFjZSBdIHx8IHt9O1xuXHRleGlzdGluZ0NvbnN0cnVjdG9yID0gJFsgbmFtZXNwYWNlIF1bIG5hbWUgXTtcblx0Y29uc3RydWN0b3IgPSAkWyBuYW1lc3BhY2UgXVsgbmFtZSBdID0gZnVuY3Rpb24oIG9wdGlvbnMsIGVsZW1lbnQgKSB7XG5cblx0XHQvLyBBbGxvdyBpbnN0YW50aWF0aW9uIHdpdGhvdXQgXCJuZXdcIiBrZXl3b3JkXG5cdFx0aWYgKCAhdGhpcy5fY3JlYXRlV2lkZ2V0ICkge1xuXHRcdFx0cmV0dXJuIG5ldyBjb25zdHJ1Y3Rvciggb3B0aW9ucywgZWxlbWVudCApO1xuXHRcdH1cblxuXHRcdC8vIEFsbG93IGluc3RhbnRpYXRpb24gd2l0aG91dCBpbml0aWFsaXppbmcgZm9yIHNpbXBsZSBpbmhlcml0YW5jZVxuXHRcdC8vIG11c3QgdXNlIFwibmV3XCIga2V5d29yZCAodGhlIGNvZGUgYWJvdmUgYWx3YXlzIHBhc3NlcyBhcmdzKVxuXHRcdGlmICggYXJndW1lbnRzLmxlbmd0aCApIHtcblx0XHRcdHRoaXMuX2NyZWF0ZVdpZGdldCggb3B0aW9ucywgZWxlbWVudCApO1xuXHRcdH1cblx0fTtcblxuXHQvLyBFeHRlbmQgd2l0aCB0aGUgZXhpc3RpbmcgY29uc3RydWN0b3IgdG8gY2Fycnkgb3ZlciBhbnkgc3RhdGljIHByb3BlcnRpZXNcblx0JC5leHRlbmQoIGNvbnN0cnVjdG9yLCBleGlzdGluZ0NvbnN0cnVjdG9yLCB7XG5cdFx0dmVyc2lvbjogcHJvdG90eXBlLnZlcnNpb24sXG5cblx0XHQvLyBDb3B5IHRoZSBvYmplY3QgdXNlZCB0byBjcmVhdGUgdGhlIHByb3RvdHlwZSBpbiBjYXNlIHdlIG5lZWQgdG9cblx0XHQvLyByZWRlZmluZSB0aGUgd2lkZ2V0IGxhdGVyXG5cdFx0X3Byb3RvOiAkLmV4dGVuZCgge30sIHByb3RvdHlwZSApLFxuXG5cdFx0Ly8gVHJhY2sgd2lkZ2V0cyB0aGF0IGluaGVyaXQgZnJvbSB0aGlzIHdpZGdldCBpbiBjYXNlIHRoaXMgd2lkZ2V0IGlzXG5cdFx0Ly8gcmVkZWZpbmVkIGFmdGVyIGEgd2lkZ2V0IGluaGVyaXRzIGZyb20gaXRcblx0XHRfY2hpbGRDb25zdHJ1Y3RvcnM6IFtdXG5cdH0gKTtcblxuXHRiYXNlUHJvdG90eXBlID0gbmV3IGJhc2UoKTtcblxuXHQvLyBXZSBuZWVkIHRvIG1ha2UgdGhlIG9wdGlvbnMgaGFzaCBhIHByb3BlcnR5IGRpcmVjdGx5IG9uIHRoZSBuZXcgaW5zdGFuY2Vcblx0Ly8gb3RoZXJ3aXNlIHdlJ2xsIG1vZGlmeSB0aGUgb3B0aW9ucyBoYXNoIG9uIHRoZSBwcm90b3R5cGUgdGhhdCB3ZSdyZVxuXHQvLyBpbmhlcml0aW5nIGZyb21cblx0YmFzZVByb3RvdHlwZS5vcHRpb25zID0gJC53aWRnZXQuZXh0ZW5kKCB7fSwgYmFzZVByb3RvdHlwZS5vcHRpb25zICk7XG5cdCQuZWFjaCggcHJvdG90eXBlLCBmdW5jdGlvbiggcHJvcCwgdmFsdWUgKSB7XG5cdFx0aWYgKCAhJC5pc0Z1bmN0aW9uKCB2YWx1ZSApICkge1xuXHRcdFx0cHJveGllZFByb3RvdHlwZVsgcHJvcCBdID0gdmFsdWU7XG5cdFx0XHRyZXR1cm47XG5cdFx0fVxuXHRcdHByb3hpZWRQcm90b3R5cGVbIHByb3AgXSA9ICggZnVuY3Rpb24oKSB7XG5cdFx0XHRmdW5jdGlvbiBfc3VwZXIoKSB7XG5cdFx0XHRcdHJldHVybiBiYXNlLnByb3RvdHlwZVsgcHJvcCBdLmFwcGx5KCB0aGlzLCBhcmd1bWVudHMgKTtcblx0XHRcdH1cblxuXHRcdFx0ZnVuY3Rpb24gX3N1cGVyQXBwbHkoIGFyZ3MgKSB7XG5cdFx0XHRcdHJldHVybiBiYXNlLnByb3RvdHlwZVsgcHJvcCBdLmFwcGx5KCB0aGlzLCBhcmdzICk7XG5cdFx0XHR9XG5cblx0XHRcdHJldHVybiBmdW5jdGlvbigpIHtcblx0XHRcdFx0dmFyIF9fc3VwZXIgPSB0aGlzLl9zdXBlcjtcblx0XHRcdFx0dmFyIF9fc3VwZXJBcHBseSA9IHRoaXMuX3N1cGVyQXBwbHk7XG5cdFx0XHRcdHZhciByZXR1cm5WYWx1ZTtcblxuXHRcdFx0XHR0aGlzLl9zdXBlciA9IF9zdXBlcjtcblx0XHRcdFx0dGhpcy5fc3VwZXJBcHBseSA9IF9zdXBlckFwcGx5O1xuXG5cdFx0XHRcdHJldHVyblZhbHVlID0gdmFsdWUuYXBwbHkoIHRoaXMsIGFyZ3VtZW50cyApO1xuXG5cdFx0XHRcdHRoaXMuX3N1cGVyID0gX19zdXBlcjtcblx0XHRcdFx0dGhpcy5fc3VwZXJBcHBseSA9IF9fc3VwZXJBcHBseTtcblxuXHRcdFx0XHRyZXR1cm4gcmV0dXJuVmFsdWU7XG5cdFx0XHR9O1xuXHRcdH0gKSgpO1xuXHR9ICk7XG5cdGNvbnN0cnVjdG9yLnByb3RvdHlwZSA9ICQud2lkZ2V0LmV4dGVuZCggYmFzZVByb3RvdHlwZSwge1xuXG5cdFx0Ly8gVE9ETzogcmVtb3ZlIHN1cHBvcnQgZm9yIHdpZGdldEV2ZW50UHJlZml4XG5cdFx0Ly8gYWx3YXlzIHVzZSB0aGUgbmFtZSArIGEgY29sb24gYXMgdGhlIHByZWZpeCwgZS5nLiwgZHJhZ2dhYmxlOnN0YXJ0XG5cdFx0Ly8gZG9uJ3QgcHJlZml4IGZvciB3aWRnZXRzIHRoYXQgYXJlbid0IERPTS1iYXNlZFxuXHRcdHdpZGdldEV2ZW50UHJlZml4OiBleGlzdGluZ0NvbnN0cnVjdG9yID8gKCBiYXNlUHJvdG90eXBlLndpZGdldEV2ZW50UHJlZml4IHx8IG5hbWUgKSA6IG5hbWVcblx0fSwgcHJveGllZFByb3RvdHlwZSwge1xuXHRcdGNvbnN0cnVjdG9yOiBjb25zdHJ1Y3Rvcixcblx0XHRuYW1lc3BhY2U6IG5hbWVzcGFjZSxcblx0XHR3aWRnZXROYW1lOiBuYW1lLFxuXHRcdHdpZGdldEZ1bGxOYW1lOiBmdWxsTmFtZVxuXHR9ICk7XG5cblx0Ly8gSWYgdGhpcyB3aWRnZXQgaXMgYmVpbmcgcmVkZWZpbmVkIHRoZW4gd2UgbmVlZCB0byBmaW5kIGFsbCB3aWRnZXRzIHRoYXRcblx0Ly8gYXJlIGluaGVyaXRpbmcgZnJvbSBpdCBhbmQgcmVkZWZpbmUgYWxsIG9mIHRoZW0gc28gdGhhdCB0aGV5IGluaGVyaXQgZnJvbVxuXHQvLyB0aGUgbmV3IHZlcnNpb24gb2YgdGhpcyB3aWRnZXQuIFdlJ3JlIGVzc2VudGlhbGx5IHRyeWluZyB0byByZXBsYWNlIG9uZVxuXHQvLyBsZXZlbCBpbiB0aGUgcHJvdG90eXBlIGNoYWluLlxuXHRpZiAoIGV4aXN0aW5nQ29uc3RydWN0b3IgKSB7XG5cdFx0JC5lYWNoKCBleGlzdGluZ0NvbnN0cnVjdG9yLl9jaGlsZENvbnN0cnVjdG9ycywgZnVuY3Rpb24oIGksIGNoaWxkICkge1xuXHRcdFx0dmFyIGNoaWxkUHJvdG90eXBlID0gY2hpbGQucHJvdG90eXBlO1xuXG5cdFx0XHQvLyBSZWRlZmluZSB0aGUgY2hpbGQgd2lkZ2V0IHVzaW5nIHRoZSBzYW1lIHByb3RvdHlwZSB0aGF0IHdhc1xuXHRcdFx0Ly8gb3JpZ2luYWxseSB1c2VkLCBidXQgaW5oZXJpdCBmcm9tIHRoZSBuZXcgdmVyc2lvbiBvZiB0aGUgYmFzZVxuXHRcdFx0JC53aWRnZXQoIGNoaWxkUHJvdG90eXBlLm5hbWVzcGFjZSArIFwiLlwiICsgY2hpbGRQcm90b3R5cGUud2lkZ2V0TmFtZSwgY29uc3RydWN0b3IsXG5cdFx0XHRcdGNoaWxkLl9wcm90byApO1xuXHRcdH0gKTtcblxuXHRcdC8vIFJlbW92ZSB0aGUgbGlzdCBvZiBleGlzdGluZyBjaGlsZCBjb25zdHJ1Y3RvcnMgZnJvbSB0aGUgb2xkIGNvbnN0cnVjdG9yXG5cdFx0Ly8gc28gdGhlIG9sZCBjaGlsZCBjb25zdHJ1Y3RvcnMgY2FuIGJlIGdhcmJhZ2UgY29sbGVjdGVkXG5cdFx0ZGVsZXRlIGV4aXN0aW5nQ29uc3RydWN0b3IuX2NoaWxkQ29uc3RydWN0b3JzO1xuXHR9IGVsc2Uge1xuXHRcdGJhc2UuX2NoaWxkQ29uc3RydWN0b3JzLnB1c2goIGNvbnN0cnVjdG9yICk7XG5cdH1cblxuXHQkLndpZGdldC5icmlkZ2UoIG5hbWUsIGNvbnN0cnVjdG9yICk7XG5cblx0cmV0dXJuIGNvbnN0cnVjdG9yO1xufTtcblxuJC53aWRnZXQuZXh0ZW5kID0gZnVuY3Rpb24oIHRhcmdldCApIHtcblx0dmFyIGlucHV0ID0gd2lkZ2V0U2xpY2UuY2FsbCggYXJndW1lbnRzLCAxICk7XG5cdHZhciBpbnB1dEluZGV4ID0gMDtcblx0dmFyIGlucHV0TGVuZ3RoID0gaW5wdXQubGVuZ3RoO1xuXHR2YXIga2V5O1xuXHR2YXIgdmFsdWU7XG5cblx0Zm9yICggOyBpbnB1dEluZGV4IDwgaW5wdXRMZW5ndGg7IGlucHV0SW5kZXgrKyApIHtcblx0XHRmb3IgKCBrZXkgaW4gaW5wdXRbIGlucHV0SW5kZXggXSApIHtcblx0XHRcdHZhbHVlID0gaW5wdXRbIGlucHV0SW5kZXggXVsga2V5IF07XG5cdFx0XHRpZiAoIGlucHV0WyBpbnB1dEluZGV4IF0uaGFzT3duUHJvcGVydHkoIGtleSApICYmIHZhbHVlICE9PSB1bmRlZmluZWQgKSB7XG5cblx0XHRcdFx0Ly8gQ2xvbmUgb2JqZWN0c1xuXHRcdFx0XHRpZiAoICQuaXNQbGFpbk9iamVjdCggdmFsdWUgKSApIHtcblx0XHRcdFx0XHR0YXJnZXRbIGtleSBdID0gJC5pc1BsYWluT2JqZWN0KCB0YXJnZXRbIGtleSBdICkgP1xuXHRcdFx0XHRcdFx0JC53aWRnZXQuZXh0ZW5kKCB7fSwgdGFyZ2V0WyBrZXkgXSwgdmFsdWUgKSA6XG5cblx0XHRcdFx0XHRcdC8vIERvbid0IGV4dGVuZCBzdHJpbmdzLCBhcnJheXMsIGV0Yy4gd2l0aCBvYmplY3RzXG5cdFx0XHRcdFx0XHQkLndpZGdldC5leHRlbmQoIHt9LCB2YWx1ZSApO1xuXG5cdFx0XHRcdC8vIENvcHkgZXZlcnl0aGluZyBlbHNlIGJ5IHJlZmVyZW5jZVxuXHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdHRhcmdldFsga2V5IF0gPSB2YWx1ZTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH1cblx0fVxuXHRyZXR1cm4gdGFyZ2V0O1xufTtcblxuJC53aWRnZXQuYnJpZGdlID0gZnVuY3Rpb24oIG5hbWUsIG9iamVjdCApIHtcblx0dmFyIGZ1bGxOYW1lID0gb2JqZWN0LnByb3RvdHlwZS53aWRnZXRGdWxsTmFtZSB8fCBuYW1lO1xuXHQkLmZuWyBuYW1lIF0gPSBmdW5jdGlvbiggb3B0aW9ucyApIHtcblx0XHR2YXIgaXNNZXRob2RDYWxsID0gdHlwZW9mIG9wdGlvbnMgPT09IFwic3RyaW5nXCI7XG5cdFx0dmFyIGFyZ3MgPSB3aWRnZXRTbGljZS5jYWxsKCBhcmd1bWVudHMsIDEgKTtcblx0XHR2YXIgcmV0dXJuVmFsdWUgPSB0aGlzO1xuXG5cdFx0aWYgKCBpc01ldGhvZENhbGwgKSB7XG5cblx0XHRcdC8vIElmIHRoaXMgaXMgYW4gZW1wdHkgY29sbGVjdGlvbiwgd2UgbmVlZCB0byBoYXZlIHRoZSBpbnN0YW5jZSBtZXRob2Rcblx0XHRcdC8vIHJldHVybiB1bmRlZmluZWQgaW5zdGVhZCBvZiB0aGUgalF1ZXJ5IGluc3RhbmNlXG5cdFx0XHRpZiAoICF0aGlzLmxlbmd0aCAmJiBvcHRpb25zID09PSBcImluc3RhbmNlXCIgKSB7XG5cdFx0XHRcdHJldHVyblZhbHVlID0gdW5kZWZpbmVkO1xuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0dGhpcy5lYWNoKCBmdW5jdGlvbigpIHtcblx0XHRcdFx0XHR2YXIgbWV0aG9kVmFsdWU7XG5cdFx0XHRcdFx0dmFyIGluc3RhbmNlID0gJC5kYXRhKCB0aGlzLCBmdWxsTmFtZSApO1xuXG5cdFx0XHRcdFx0aWYgKCBvcHRpb25zID09PSBcImluc3RhbmNlXCIgKSB7XG5cdFx0XHRcdFx0XHRyZXR1cm5WYWx1ZSA9IGluc3RhbmNlO1xuXHRcdFx0XHRcdFx0cmV0dXJuIGZhbHNlO1xuXHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdGlmICggIWluc3RhbmNlICkge1xuXHRcdFx0XHRcdFx0cmV0dXJuICQuZXJyb3IoIFwiY2Fubm90IGNhbGwgbWV0aG9kcyBvbiBcIiArIG5hbWUgK1xuXHRcdFx0XHRcdFx0XHRcIiBwcmlvciB0byBpbml0aWFsaXphdGlvbjsgXCIgK1xuXHRcdFx0XHRcdFx0XHRcImF0dGVtcHRlZCB0byBjYWxsIG1ldGhvZCAnXCIgKyBvcHRpb25zICsgXCInXCIgKTtcblx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHRpZiAoICEkLmlzRnVuY3Rpb24oIGluc3RhbmNlWyBvcHRpb25zIF0gKSB8fCBvcHRpb25zLmNoYXJBdCggMCApID09PSBcIl9cIiApIHtcblx0XHRcdFx0XHRcdHJldHVybiAkLmVycm9yKCBcIm5vIHN1Y2ggbWV0aG9kICdcIiArIG9wdGlvbnMgKyBcIicgZm9yIFwiICsgbmFtZSArXG5cdFx0XHRcdFx0XHRcdFwiIHdpZGdldCBpbnN0YW5jZVwiICk7XG5cdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0bWV0aG9kVmFsdWUgPSBpbnN0YW5jZVsgb3B0aW9ucyBdLmFwcGx5KCBpbnN0YW5jZSwgYXJncyApO1xuXG5cdFx0XHRcdFx0aWYgKCBtZXRob2RWYWx1ZSAhPT0gaW5zdGFuY2UgJiYgbWV0aG9kVmFsdWUgIT09IHVuZGVmaW5lZCApIHtcblx0XHRcdFx0XHRcdHJldHVyblZhbHVlID0gbWV0aG9kVmFsdWUgJiYgbWV0aG9kVmFsdWUuanF1ZXJ5ID9cblx0XHRcdFx0XHRcdFx0cmV0dXJuVmFsdWUucHVzaFN0YWNrKCBtZXRob2RWYWx1ZS5nZXQoKSApIDpcblx0XHRcdFx0XHRcdFx0bWV0aG9kVmFsdWU7XG5cdFx0XHRcdFx0XHRyZXR1cm4gZmFsc2U7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9ICk7XG5cdFx0XHR9XG5cdFx0fSBlbHNlIHtcblxuXHRcdFx0Ly8gQWxsb3cgbXVsdGlwbGUgaGFzaGVzIHRvIGJlIHBhc3NlZCBvbiBpbml0XG5cdFx0XHRpZiAoIGFyZ3MubGVuZ3RoICkge1xuXHRcdFx0XHRvcHRpb25zID0gJC53aWRnZXQuZXh0ZW5kLmFwcGx5KCBudWxsLCBbIG9wdGlvbnMgXS5jb25jYXQoIGFyZ3MgKSApO1xuXHRcdFx0fVxuXG5cdFx0XHR0aGlzLmVhY2goIGZ1bmN0aW9uKCkge1xuXHRcdFx0XHR2YXIgaW5zdGFuY2UgPSAkLmRhdGEoIHRoaXMsIGZ1bGxOYW1lICk7XG5cdFx0XHRcdGlmICggaW5zdGFuY2UgKSB7XG5cdFx0XHRcdFx0aW5zdGFuY2Uub3B0aW9uKCBvcHRpb25zIHx8IHt9ICk7XG5cdFx0XHRcdFx0aWYgKCBpbnN0YW5jZS5faW5pdCApIHtcblx0XHRcdFx0XHRcdGluc3RhbmNlLl9pbml0KCk7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdCQuZGF0YSggdGhpcywgZnVsbE5hbWUsIG5ldyBvYmplY3QoIG9wdGlvbnMsIHRoaXMgKSApO1xuXHRcdFx0XHR9XG5cdFx0XHR9ICk7XG5cdFx0fVxuXG5cdFx0cmV0dXJuIHJldHVyblZhbHVlO1xuXHR9O1xufTtcblxuJC5XaWRnZXQgPSBmdW5jdGlvbiggLyogb3B0aW9ucywgZWxlbWVudCAqLyApIHt9O1xuJC5XaWRnZXQuX2NoaWxkQ29uc3RydWN0b3JzID0gW107XG5cbiQuV2lkZ2V0LnByb3RvdHlwZSA9IHtcblx0d2lkZ2V0TmFtZTogXCJ3aWRnZXRcIixcblx0d2lkZ2V0RXZlbnRQcmVmaXg6IFwiXCIsXG5cdGRlZmF1bHRFbGVtZW50OiBcIjxkaXY+XCIsXG5cblx0b3B0aW9uczoge1xuXHRcdGNsYXNzZXM6IHt9LFxuXHRcdGRpc2FibGVkOiBmYWxzZSxcblxuXHRcdC8vIENhbGxiYWNrc1xuXHRcdGNyZWF0ZTogbnVsbFxuXHR9LFxuXG5cdF9jcmVhdGVXaWRnZXQ6IGZ1bmN0aW9uKCBvcHRpb25zLCBlbGVtZW50ICkge1xuXHRcdGVsZW1lbnQgPSAkKCBlbGVtZW50IHx8IHRoaXMuZGVmYXVsdEVsZW1lbnQgfHwgdGhpcyApWyAwIF07XG5cdFx0dGhpcy5lbGVtZW50ID0gJCggZWxlbWVudCApO1xuXHRcdHRoaXMudXVpZCA9IHdpZGdldFV1aWQrKztcblx0XHR0aGlzLmV2ZW50TmFtZXNwYWNlID0gXCIuXCIgKyB0aGlzLndpZGdldE5hbWUgKyB0aGlzLnV1aWQ7XG5cblx0XHR0aGlzLmJpbmRpbmdzID0gJCgpO1xuXHRcdHRoaXMuaG92ZXJhYmxlID0gJCgpO1xuXHRcdHRoaXMuZm9jdXNhYmxlID0gJCgpO1xuXHRcdHRoaXMuY2xhc3Nlc0VsZW1lbnRMb29rdXAgPSB7fTtcblxuXHRcdGlmICggZWxlbWVudCAhPT0gdGhpcyApIHtcblx0XHRcdCQuZGF0YSggZWxlbWVudCwgdGhpcy53aWRnZXRGdWxsTmFtZSwgdGhpcyApO1xuXHRcdFx0dGhpcy5fb24oIHRydWUsIHRoaXMuZWxlbWVudCwge1xuXHRcdFx0XHRyZW1vdmU6IGZ1bmN0aW9uKCBldmVudCApIHtcblx0XHRcdFx0XHRpZiAoIGV2ZW50LnRhcmdldCA9PT0gZWxlbWVudCApIHtcblx0XHRcdFx0XHRcdHRoaXMuZGVzdHJveSgpO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXHRcdFx0fSApO1xuXHRcdFx0dGhpcy5kb2N1bWVudCA9ICQoIGVsZW1lbnQuc3R5bGUgP1xuXG5cdFx0XHRcdC8vIEVsZW1lbnQgd2l0aGluIHRoZSBkb2N1bWVudFxuXHRcdFx0XHRlbGVtZW50Lm93bmVyRG9jdW1lbnQgOlxuXG5cdFx0XHRcdC8vIEVsZW1lbnQgaXMgd2luZG93IG9yIGRvY3VtZW50XG5cdFx0XHRcdGVsZW1lbnQuZG9jdW1lbnQgfHwgZWxlbWVudCApO1xuXHRcdFx0dGhpcy53aW5kb3cgPSAkKCB0aGlzLmRvY3VtZW50WyAwIF0uZGVmYXVsdFZpZXcgfHwgdGhpcy5kb2N1bWVudFsgMCBdLnBhcmVudFdpbmRvdyApO1xuXHRcdH1cblxuXHRcdHRoaXMub3B0aW9ucyA9ICQud2lkZ2V0LmV4dGVuZCgge30sXG5cdFx0XHR0aGlzLm9wdGlvbnMsXG5cdFx0XHR0aGlzLl9nZXRDcmVhdGVPcHRpb25zKCksXG5cdFx0XHRvcHRpb25zICk7XG5cblx0XHR0aGlzLl9jcmVhdGUoKTtcblxuXHRcdGlmICggdGhpcy5vcHRpb25zLmRpc2FibGVkICkge1xuXHRcdFx0dGhpcy5fc2V0T3B0aW9uRGlzYWJsZWQoIHRoaXMub3B0aW9ucy5kaXNhYmxlZCApO1xuXHRcdH1cblxuXHRcdHRoaXMuX3RyaWdnZXIoIFwiY3JlYXRlXCIsIG51bGwsIHRoaXMuX2dldENyZWF0ZUV2ZW50RGF0YSgpICk7XG5cdFx0dGhpcy5faW5pdCgpO1xuXHR9LFxuXG5cdF9nZXRDcmVhdGVPcHRpb25zOiBmdW5jdGlvbigpIHtcblx0XHRyZXR1cm4ge307XG5cdH0sXG5cblx0X2dldENyZWF0ZUV2ZW50RGF0YTogJC5ub29wLFxuXG5cdF9jcmVhdGU6ICQubm9vcCxcblxuXHRfaW5pdDogJC5ub29wLFxuXG5cdGRlc3Ryb3k6IGZ1bmN0aW9uKCkge1xuXHRcdHZhciB0aGF0ID0gdGhpcztcblxuXHRcdHRoaXMuX2Rlc3Ryb3koKTtcblx0XHQkLmVhY2goIHRoaXMuY2xhc3Nlc0VsZW1lbnRMb29rdXAsIGZ1bmN0aW9uKCBrZXksIHZhbHVlICkge1xuXHRcdFx0dGhhdC5fcmVtb3ZlQ2xhc3MoIHZhbHVlLCBrZXkgKTtcblx0XHR9ICk7XG5cblx0XHQvLyBXZSBjYW4gcHJvYmFibHkgcmVtb3ZlIHRoZSB1bmJpbmQgY2FsbHMgaW4gMi4wXG5cdFx0Ly8gYWxsIGV2ZW50IGJpbmRpbmdzIHNob3VsZCBnbyB0aHJvdWdoIHRoaXMuX29uKClcblx0XHR0aGlzLmVsZW1lbnRcblx0XHRcdC5vZmYoIHRoaXMuZXZlbnROYW1lc3BhY2UgKVxuXHRcdFx0LnJlbW92ZURhdGEoIHRoaXMud2lkZ2V0RnVsbE5hbWUgKTtcblx0XHR0aGlzLndpZGdldCgpXG5cdFx0XHQub2ZmKCB0aGlzLmV2ZW50TmFtZXNwYWNlIClcblx0XHRcdC5yZW1vdmVBdHRyKCBcImFyaWEtZGlzYWJsZWRcIiApO1xuXG5cdFx0Ly8gQ2xlYW4gdXAgZXZlbnRzIGFuZCBzdGF0ZXNcblx0XHR0aGlzLmJpbmRpbmdzLm9mZiggdGhpcy5ldmVudE5hbWVzcGFjZSApO1xuXHR9LFxuXG5cdF9kZXN0cm95OiAkLm5vb3AsXG5cblx0d2lkZ2V0OiBmdW5jdGlvbigpIHtcblx0XHRyZXR1cm4gdGhpcy5lbGVtZW50O1xuXHR9LFxuXG5cdG9wdGlvbjogZnVuY3Rpb24oIGtleSwgdmFsdWUgKSB7XG5cdFx0dmFyIG9wdGlvbnMgPSBrZXk7XG5cdFx0dmFyIHBhcnRzO1xuXHRcdHZhciBjdXJPcHRpb247XG5cdFx0dmFyIGk7XG5cblx0XHRpZiAoIGFyZ3VtZW50cy5sZW5ndGggPT09IDAgKSB7XG5cblx0XHRcdC8vIERvbid0IHJldHVybiBhIHJlZmVyZW5jZSB0byB0aGUgaW50ZXJuYWwgaGFzaFxuXHRcdFx0cmV0dXJuICQud2lkZ2V0LmV4dGVuZCgge30sIHRoaXMub3B0aW9ucyApO1xuXHRcdH1cblxuXHRcdGlmICggdHlwZW9mIGtleSA9PT0gXCJzdHJpbmdcIiApIHtcblxuXHRcdFx0Ly8gSGFuZGxlIG5lc3RlZCBrZXlzLCBlLmcuLCBcImZvby5iYXJcIiA9PiB7IGZvbzogeyBiYXI6IF9fXyB9IH1cblx0XHRcdG9wdGlvbnMgPSB7fTtcblx0XHRcdHBhcnRzID0ga2V5LnNwbGl0KCBcIi5cIiApO1xuXHRcdFx0a2V5ID0gcGFydHMuc2hpZnQoKTtcblx0XHRcdGlmICggcGFydHMubGVuZ3RoICkge1xuXHRcdFx0XHRjdXJPcHRpb24gPSBvcHRpb25zWyBrZXkgXSA9ICQud2lkZ2V0LmV4dGVuZCgge30sIHRoaXMub3B0aW9uc1sga2V5IF0gKTtcblx0XHRcdFx0Zm9yICggaSA9IDA7IGkgPCBwYXJ0cy5sZW5ndGggLSAxOyBpKysgKSB7XG5cdFx0XHRcdFx0Y3VyT3B0aW9uWyBwYXJ0c1sgaSBdIF0gPSBjdXJPcHRpb25bIHBhcnRzWyBpIF0gXSB8fCB7fTtcblx0XHRcdFx0XHRjdXJPcHRpb24gPSBjdXJPcHRpb25bIHBhcnRzWyBpIF0gXTtcblx0XHRcdFx0fVxuXHRcdFx0XHRrZXkgPSBwYXJ0cy5wb3AoKTtcblx0XHRcdFx0aWYgKCBhcmd1bWVudHMubGVuZ3RoID09PSAxICkge1xuXHRcdFx0XHRcdHJldHVybiBjdXJPcHRpb25bIGtleSBdID09PSB1bmRlZmluZWQgPyBudWxsIDogY3VyT3B0aW9uWyBrZXkgXTtcblx0XHRcdFx0fVxuXHRcdFx0XHRjdXJPcHRpb25bIGtleSBdID0gdmFsdWU7XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRpZiAoIGFyZ3VtZW50cy5sZW5ndGggPT09IDEgKSB7XG5cdFx0XHRcdFx0cmV0dXJuIHRoaXMub3B0aW9uc1sga2V5IF0gPT09IHVuZGVmaW5lZCA/IG51bGwgOiB0aGlzLm9wdGlvbnNbIGtleSBdO1xuXHRcdFx0XHR9XG5cdFx0XHRcdG9wdGlvbnNbIGtleSBdID0gdmFsdWU7XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0dGhpcy5fc2V0T3B0aW9ucyggb3B0aW9ucyApO1xuXG5cdFx0cmV0dXJuIHRoaXM7XG5cdH0sXG5cblx0X3NldE9wdGlvbnM6IGZ1bmN0aW9uKCBvcHRpb25zICkge1xuXHRcdHZhciBrZXk7XG5cblx0XHRmb3IgKCBrZXkgaW4gb3B0aW9ucyApIHtcblx0XHRcdHRoaXMuX3NldE9wdGlvbigga2V5LCBvcHRpb25zWyBrZXkgXSApO1xuXHRcdH1cblxuXHRcdHJldHVybiB0aGlzO1xuXHR9LFxuXG5cdF9zZXRPcHRpb246IGZ1bmN0aW9uKCBrZXksIHZhbHVlICkge1xuXHRcdGlmICgga2V5ID09PSBcImNsYXNzZXNcIiApIHtcblx0XHRcdHRoaXMuX3NldE9wdGlvbkNsYXNzZXMoIHZhbHVlICk7XG5cdFx0fVxuXG5cdFx0dGhpcy5vcHRpb25zWyBrZXkgXSA9IHZhbHVlO1xuXG5cdFx0aWYgKCBrZXkgPT09IFwiZGlzYWJsZWRcIiApIHtcblx0XHRcdHRoaXMuX3NldE9wdGlvbkRpc2FibGVkKCB2YWx1ZSApO1xuXHRcdH1cblxuXHRcdHJldHVybiB0aGlzO1xuXHR9LFxuXG5cdF9zZXRPcHRpb25DbGFzc2VzOiBmdW5jdGlvbiggdmFsdWUgKSB7XG5cdFx0dmFyIGNsYXNzS2V5LCBlbGVtZW50cywgY3VycmVudEVsZW1lbnRzO1xuXG5cdFx0Zm9yICggY2xhc3NLZXkgaW4gdmFsdWUgKSB7XG5cdFx0XHRjdXJyZW50RWxlbWVudHMgPSB0aGlzLmNsYXNzZXNFbGVtZW50TG9va3VwWyBjbGFzc0tleSBdO1xuXHRcdFx0aWYgKCB2YWx1ZVsgY2xhc3NLZXkgXSA9PT0gdGhpcy5vcHRpb25zLmNsYXNzZXNbIGNsYXNzS2V5IF0gfHxcblx0XHRcdFx0XHQhY3VycmVudEVsZW1lbnRzIHx8XG5cdFx0XHRcdFx0IWN1cnJlbnRFbGVtZW50cy5sZW5ndGggKSB7XG5cdFx0XHRcdGNvbnRpbnVlO1xuXHRcdFx0fVxuXG5cdFx0XHQvLyBXZSBhcmUgZG9pbmcgdGhpcyB0byBjcmVhdGUgYSBuZXcgalF1ZXJ5IG9iamVjdCBiZWNhdXNlIHRoZSBfcmVtb3ZlQ2xhc3MoKSBjYWxsXG5cdFx0XHQvLyBvbiB0aGUgbmV4dCBsaW5lIGlzIGdvaW5nIHRvIGRlc3Ryb3kgdGhlIHJlZmVyZW5jZSB0byB0aGUgY3VycmVudCBlbGVtZW50cyBiZWluZ1xuXHRcdFx0Ly8gdHJhY2tlZC4gV2UgbmVlZCB0byBzYXZlIGEgY29weSBvZiB0aGlzIGNvbGxlY3Rpb24gc28gdGhhdCB3ZSBjYW4gYWRkIHRoZSBuZXcgY2xhc3Nlc1xuXHRcdFx0Ly8gYmVsb3cuXG5cdFx0XHRlbGVtZW50cyA9ICQoIGN1cnJlbnRFbGVtZW50cy5nZXQoKSApO1xuXHRcdFx0dGhpcy5fcmVtb3ZlQ2xhc3MoIGN1cnJlbnRFbGVtZW50cywgY2xhc3NLZXkgKTtcblxuXHRcdFx0Ly8gV2UgZG9uJ3QgdXNlIF9hZGRDbGFzcygpIGhlcmUsIGJlY2F1c2UgdGhhdCB1c2VzIHRoaXMub3B0aW9ucy5jbGFzc2VzXG5cdFx0XHQvLyBmb3IgZ2VuZXJhdGluZyB0aGUgc3RyaW5nIG9mIGNsYXNzZXMuIFdlIHdhbnQgdG8gdXNlIHRoZSB2YWx1ZSBwYXNzZWQgaW4gZnJvbVxuXHRcdFx0Ly8gX3NldE9wdGlvbigpLCB0aGlzIGlzIHRoZSBuZXcgdmFsdWUgb2YgdGhlIGNsYXNzZXMgb3B0aW9uIHdoaWNoIHdhcyBwYXNzZWQgdG9cblx0XHRcdC8vIF9zZXRPcHRpb24oKS4gV2UgcGFzcyB0aGlzIHZhbHVlIGRpcmVjdGx5IHRvIF9jbGFzc2VzKCkuXG5cdFx0XHRlbGVtZW50cy5hZGRDbGFzcyggdGhpcy5fY2xhc3Nlcygge1xuXHRcdFx0XHRlbGVtZW50OiBlbGVtZW50cyxcblx0XHRcdFx0a2V5czogY2xhc3NLZXksXG5cdFx0XHRcdGNsYXNzZXM6IHZhbHVlLFxuXHRcdFx0XHRhZGQ6IHRydWVcblx0XHRcdH0gKSApO1xuXHRcdH1cblx0fSxcblxuXHRfc2V0T3B0aW9uRGlzYWJsZWQ6IGZ1bmN0aW9uKCB2YWx1ZSApIHtcblx0XHR0aGlzLl90b2dnbGVDbGFzcyggdGhpcy53aWRnZXQoKSwgdGhpcy53aWRnZXRGdWxsTmFtZSArIFwiLWRpc2FibGVkXCIsIG51bGwsICEhdmFsdWUgKTtcblxuXHRcdC8vIElmIHRoZSB3aWRnZXQgaXMgYmVjb21pbmcgZGlzYWJsZWQsIHRoZW4gbm90aGluZyBpcyBpbnRlcmFjdGl2ZVxuXHRcdGlmICggdmFsdWUgKSB7XG5cdFx0XHR0aGlzLl9yZW1vdmVDbGFzcyggdGhpcy5ob3ZlcmFibGUsIG51bGwsIFwidWktc3RhdGUtaG92ZXJcIiApO1xuXHRcdFx0dGhpcy5fcmVtb3ZlQ2xhc3MoIHRoaXMuZm9jdXNhYmxlLCBudWxsLCBcInVpLXN0YXRlLWZvY3VzXCIgKTtcblx0XHR9XG5cdH0sXG5cblx0ZW5hYmxlOiBmdW5jdGlvbigpIHtcblx0XHRyZXR1cm4gdGhpcy5fc2V0T3B0aW9ucyggeyBkaXNhYmxlZDogZmFsc2UgfSApO1xuXHR9LFxuXG5cdGRpc2FibGU6IGZ1bmN0aW9uKCkge1xuXHRcdHJldHVybiB0aGlzLl9zZXRPcHRpb25zKCB7IGRpc2FibGVkOiB0cnVlIH0gKTtcblx0fSxcblxuXHRfY2xhc3NlczogZnVuY3Rpb24oIG9wdGlvbnMgKSB7XG5cdFx0dmFyIGZ1bGwgPSBbXTtcblx0XHR2YXIgdGhhdCA9IHRoaXM7XG5cblx0XHRvcHRpb25zID0gJC5leHRlbmQoIHtcblx0XHRcdGVsZW1lbnQ6IHRoaXMuZWxlbWVudCxcblx0XHRcdGNsYXNzZXM6IHRoaXMub3B0aW9ucy5jbGFzc2VzIHx8IHt9XG5cdFx0fSwgb3B0aW9ucyApO1xuXG5cdFx0ZnVuY3Rpb24gcHJvY2Vzc0NsYXNzU3RyaW5nKCBjbGFzc2VzLCBjaGVja09wdGlvbiApIHtcblx0XHRcdHZhciBjdXJyZW50LCBpO1xuXHRcdFx0Zm9yICggaSA9IDA7IGkgPCBjbGFzc2VzLmxlbmd0aDsgaSsrICkge1xuXHRcdFx0XHRjdXJyZW50ID0gdGhhdC5jbGFzc2VzRWxlbWVudExvb2t1cFsgY2xhc3Nlc1sgaSBdIF0gfHwgJCgpO1xuXHRcdFx0XHRpZiAoIG9wdGlvbnMuYWRkICkge1xuXHRcdFx0XHRcdGN1cnJlbnQgPSAkKCAkLnVuaXF1ZSggY3VycmVudC5nZXQoKS5jb25jYXQoIG9wdGlvbnMuZWxlbWVudC5nZXQoKSApICkgKTtcblx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRjdXJyZW50ID0gJCggY3VycmVudC5ub3QoIG9wdGlvbnMuZWxlbWVudCApLmdldCgpICk7XG5cdFx0XHRcdH1cblx0XHRcdFx0dGhhdC5jbGFzc2VzRWxlbWVudExvb2t1cFsgY2xhc3Nlc1sgaSBdIF0gPSBjdXJyZW50O1xuXHRcdFx0XHRmdWxsLnB1c2goIGNsYXNzZXNbIGkgXSApO1xuXHRcdFx0XHRpZiAoIGNoZWNrT3B0aW9uICYmIG9wdGlvbnMuY2xhc3Nlc1sgY2xhc3Nlc1sgaSBdIF0gKSB7XG5cdFx0XHRcdFx0ZnVsbC5wdXNoKCBvcHRpb25zLmNsYXNzZXNbIGNsYXNzZXNbIGkgXSBdICk7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9XG5cblx0XHR0aGlzLl9vbiggb3B0aW9ucy5lbGVtZW50LCB7XG5cdFx0XHRcInJlbW92ZVwiOiBcIl91bnRyYWNrQ2xhc3Nlc0VsZW1lbnRcIlxuXHRcdH0gKTtcblxuXHRcdGlmICggb3B0aW9ucy5rZXlzICkge1xuXHRcdFx0cHJvY2Vzc0NsYXNzU3RyaW5nKCBvcHRpb25zLmtleXMubWF0Y2goIC9cXFMrL2cgKSB8fCBbXSwgdHJ1ZSApO1xuXHRcdH1cblx0XHRpZiAoIG9wdGlvbnMuZXh0cmEgKSB7XG5cdFx0XHRwcm9jZXNzQ2xhc3NTdHJpbmcoIG9wdGlvbnMuZXh0cmEubWF0Y2goIC9cXFMrL2cgKSB8fCBbXSApO1xuXHRcdH1cblxuXHRcdHJldHVybiBmdWxsLmpvaW4oIFwiIFwiICk7XG5cdH0sXG5cblx0X3VudHJhY2tDbGFzc2VzRWxlbWVudDogZnVuY3Rpb24oIGV2ZW50ICkge1xuXHRcdHZhciB0aGF0ID0gdGhpcztcblx0XHQkLmVhY2goIHRoYXQuY2xhc3Nlc0VsZW1lbnRMb29rdXAsIGZ1bmN0aW9uKCBrZXksIHZhbHVlICkge1xuXHRcdFx0aWYgKCAkLmluQXJyYXkoIGV2ZW50LnRhcmdldCwgdmFsdWUgKSAhPT0gLTEgKSB7XG5cdFx0XHRcdHRoYXQuY2xhc3Nlc0VsZW1lbnRMb29rdXBbIGtleSBdID0gJCggdmFsdWUubm90KCBldmVudC50YXJnZXQgKS5nZXQoKSApO1xuXHRcdFx0fVxuXHRcdH0gKTtcblx0fSxcblxuXHRfcmVtb3ZlQ2xhc3M6IGZ1bmN0aW9uKCBlbGVtZW50LCBrZXlzLCBleHRyYSApIHtcblx0XHRyZXR1cm4gdGhpcy5fdG9nZ2xlQ2xhc3MoIGVsZW1lbnQsIGtleXMsIGV4dHJhLCBmYWxzZSApO1xuXHR9LFxuXG5cdF9hZGRDbGFzczogZnVuY3Rpb24oIGVsZW1lbnQsIGtleXMsIGV4dHJhICkge1xuXHRcdHJldHVybiB0aGlzLl90b2dnbGVDbGFzcyggZWxlbWVudCwga2V5cywgZXh0cmEsIHRydWUgKTtcblx0fSxcblxuXHRfdG9nZ2xlQ2xhc3M6IGZ1bmN0aW9uKCBlbGVtZW50LCBrZXlzLCBleHRyYSwgYWRkICkge1xuXHRcdGFkZCA9ICggdHlwZW9mIGFkZCA9PT0gXCJib29sZWFuXCIgKSA/IGFkZCA6IGV4dHJhO1xuXHRcdHZhciBzaGlmdCA9ICggdHlwZW9mIGVsZW1lbnQgPT09IFwic3RyaW5nXCIgfHwgZWxlbWVudCA9PT0gbnVsbCApLFxuXHRcdFx0b3B0aW9ucyA9IHtcblx0XHRcdFx0ZXh0cmE6IHNoaWZ0ID8ga2V5cyA6IGV4dHJhLFxuXHRcdFx0XHRrZXlzOiBzaGlmdCA/IGVsZW1lbnQgOiBrZXlzLFxuXHRcdFx0XHRlbGVtZW50OiBzaGlmdCA/IHRoaXMuZWxlbWVudCA6IGVsZW1lbnQsXG5cdFx0XHRcdGFkZDogYWRkXG5cdFx0XHR9O1xuXHRcdG9wdGlvbnMuZWxlbWVudC50b2dnbGVDbGFzcyggdGhpcy5fY2xhc3Nlcyggb3B0aW9ucyApLCBhZGQgKTtcblx0XHRyZXR1cm4gdGhpcztcblx0fSxcblxuXHRfb246IGZ1bmN0aW9uKCBzdXBwcmVzc0Rpc2FibGVkQ2hlY2ssIGVsZW1lbnQsIGhhbmRsZXJzICkge1xuXHRcdHZhciBkZWxlZ2F0ZUVsZW1lbnQ7XG5cdFx0dmFyIGluc3RhbmNlID0gdGhpcztcblxuXHRcdC8vIE5vIHN1cHByZXNzRGlzYWJsZWRDaGVjayBmbGFnLCBzaHVmZmxlIGFyZ3VtZW50c1xuXHRcdGlmICggdHlwZW9mIHN1cHByZXNzRGlzYWJsZWRDaGVjayAhPT0gXCJib29sZWFuXCIgKSB7XG5cdFx0XHRoYW5kbGVycyA9IGVsZW1lbnQ7XG5cdFx0XHRlbGVtZW50ID0gc3VwcHJlc3NEaXNhYmxlZENoZWNrO1xuXHRcdFx0c3VwcHJlc3NEaXNhYmxlZENoZWNrID0gZmFsc2U7XG5cdFx0fVxuXG5cdFx0Ly8gTm8gZWxlbWVudCBhcmd1bWVudCwgc2h1ZmZsZSBhbmQgdXNlIHRoaXMuZWxlbWVudFxuXHRcdGlmICggIWhhbmRsZXJzICkge1xuXHRcdFx0aGFuZGxlcnMgPSBlbGVtZW50O1xuXHRcdFx0ZWxlbWVudCA9IHRoaXMuZWxlbWVudDtcblx0XHRcdGRlbGVnYXRlRWxlbWVudCA9IHRoaXMud2lkZ2V0KCk7XG5cdFx0fSBlbHNlIHtcblx0XHRcdGVsZW1lbnQgPSBkZWxlZ2F0ZUVsZW1lbnQgPSAkKCBlbGVtZW50ICk7XG5cdFx0XHR0aGlzLmJpbmRpbmdzID0gdGhpcy5iaW5kaW5ncy5hZGQoIGVsZW1lbnQgKTtcblx0XHR9XG5cblx0XHQkLmVhY2goIGhhbmRsZXJzLCBmdW5jdGlvbiggZXZlbnQsIGhhbmRsZXIgKSB7XG5cdFx0XHRmdW5jdGlvbiBoYW5kbGVyUHJveHkoKSB7XG5cblx0XHRcdFx0Ly8gQWxsb3cgd2lkZ2V0cyB0byBjdXN0b21pemUgdGhlIGRpc2FibGVkIGhhbmRsaW5nXG5cdFx0XHRcdC8vIC0gZGlzYWJsZWQgYXMgYW4gYXJyYXkgaW5zdGVhZCBvZiBib29sZWFuXG5cdFx0XHRcdC8vIC0gZGlzYWJsZWQgY2xhc3MgYXMgbWV0aG9kIGZvciBkaXNhYmxpbmcgaW5kaXZpZHVhbCBwYXJ0c1xuXHRcdFx0XHRpZiAoICFzdXBwcmVzc0Rpc2FibGVkQ2hlY2sgJiZcblx0XHRcdFx0XHRcdCggaW5zdGFuY2Uub3B0aW9ucy5kaXNhYmxlZCA9PT0gdHJ1ZSB8fFxuXHRcdFx0XHRcdFx0JCggdGhpcyApLmhhc0NsYXNzKCBcInVpLXN0YXRlLWRpc2FibGVkXCIgKSApICkge1xuXHRcdFx0XHRcdHJldHVybjtcblx0XHRcdFx0fVxuXHRcdFx0XHRyZXR1cm4gKCB0eXBlb2YgaGFuZGxlciA9PT0gXCJzdHJpbmdcIiA/IGluc3RhbmNlWyBoYW5kbGVyIF0gOiBoYW5kbGVyIClcblx0XHRcdFx0XHQuYXBwbHkoIGluc3RhbmNlLCBhcmd1bWVudHMgKTtcblx0XHRcdH1cblxuXHRcdFx0Ly8gQ29weSB0aGUgZ3VpZCBzbyBkaXJlY3QgdW5iaW5kaW5nIHdvcmtzXG5cdFx0XHRpZiAoIHR5cGVvZiBoYW5kbGVyICE9PSBcInN0cmluZ1wiICkge1xuXHRcdFx0XHRoYW5kbGVyUHJveHkuZ3VpZCA9IGhhbmRsZXIuZ3VpZCA9XG5cdFx0XHRcdFx0aGFuZGxlci5ndWlkIHx8IGhhbmRsZXJQcm94eS5ndWlkIHx8ICQuZ3VpZCsrO1xuXHRcdFx0fVxuXG5cdFx0XHR2YXIgbWF0Y2ggPSBldmVudC5tYXRjaCggL14oW1xcdzotXSopXFxzKiguKikkLyApO1xuXHRcdFx0dmFyIGV2ZW50TmFtZSA9IG1hdGNoWyAxIF0gKyBpbnN0YW5jZS5ldmVudE5hbWVzcGFjZTtcblx0XHRcdHZhciBzZWxlY3RvciA9IG1hdGNoWyAyIF07XG5cblx0XHRcdGlmICggc2VsZWN0b3IgKSB7XG5cdFx0XHRcdGRlbGVnYXRlRWxlbWVudC5vbiggZXZlbnROYW1lLCBzZWxlY3RvciwgaGFuZGxlclByb3h5ICk7XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRlbGVtZW50Lm9uKCBldmVudE5hbWUsIGhhbmRsZXJQcm94eSApO1xuXHRcdFx0fVxuXHRcdH0gKTtcblx0fSxcblxuXHRfb2ZmOiBmdW5jdGlvbiggZWxlbWVudCwgZXZlbnROYW1lICkge1xuXHRcdGV2ZW50TmFtZSA9ICggZXZlbnROYW1lIHx8IFwiXCIgKS5zcGxpdCggXCIgXCIgKS5qb2luKCB0aGlzLmV2ZW50TmFtZXNwYWNlICsgXCIgXCIgKSArXG5cdFx0XHR0aGlzLmV2ZW50TmFtZXNwYWNlO1xuXHRcdGVsZW1lbnQub2ZmKCBldmVudE5hbWUgKS5vZmYoIGV2ZW50TmFtZSApO1xuXG5cdFx0Ly8gQ2xlYXIgdGhlIHN0YWNrIHRvIGF2b2lkIG1lbW9yeSBsZWFrcyAoIzEwMDU2KVxuXHRcdHRoaXMuYmluZGluZ3MgPSAkKCB0aGlzLmJpbmRpbmdzLm5vdCggZWxlbWVudCApLmdldCgpICk7XG5cdFx0dGhpcy5mb2N1c2FibGUgPSAkKCB0aGlzLmZvY3VzYWJsZS5ub3QoIGVsZW1lbnQgKS5nZXQoKSApO1xuXHRcdHRoaXMuaG92ZXJhYmxlID0gJCggdGhpcy5ob3ZlcmFibGUubm90KCBlbGVtZW50ICkuZ2V0KCkgKTtcblx0fSxcblxuXHRfZGVsYXk6IGZ1bmN0aW9uKCBoYW5kbGVyLCBkZWxheSApIHtcblx0XHRmdW5jdGlvbiBoYW5kbGVyUHJveHkoKSB7XG5cdFx0XHRyZXR1cm4gKCB0eXBlb2YgaGFuZGxlciA9PT0gXCJzdHJpbmdcIiA/IGluc3RhbmNlWyBoYW5kbGVyIF0gOiBoYW5kbGVyIClcblx0XHRcdFx0LmFwcGx5KCBpbnN0YW5jZSwgYXJndW1lbnRzICk7XG5cdFx0fVxuXHRcdHZhciBpbnN0YW5jZSA9IHRoaXM7XG5cdFx0cmV0dXJuIHNldFRpbWVvdXQoIGhhbmRsZXJQcm94eSwgZGVsYXkgfHwgMCApO1xuXHR9LFxuXG5cdF9ob3ZlcmFibGU6IGZ1bmN0aW9uKCBlbGVtZW50ICkge1xuXHRcdHRoaXMuaG92ZXJhYmxlID0gdGhpcy5ob3ZlcmFibGUuYWRkKCBlbGVtZW50ICk7XG5cdFx0dGhpcy5fb24oIGVsZW1lbnQsIHtcblx0XHRcdG1vdXNlZW50ZXI6IGZ1bmN0aW9uKCBldmVudCApIHtcblx0XHRcdFx0dGhpcy5fYWRkQ2xhc3MoICQoIGV2ZW50LmN1cnJlbnRUYXJnZXQgKSwgbnVsbCwgXCJ1aS1zdGF0ZS1ob3ZlclwiICk7XG5cdFx0XHR9LFxuXHRcdFx0bW91c2VsZWF2ZTogZnVuY3Rpb24oIGV2ZW50ICkge1xuXHRcdFx0XHR0aGlzLl9yZW1vdmVDbGFzcyggJCggZXZlbnQuY3VycmVudFRhcmdldCApLCBudWxsLCBcInVpLXN0YXRlLWhvdmVyXCIgKTtcblx0XHRcdH1cblx0XHR9ICk7XG5cdH0sXG5cblx0X2ZvY3VzYWJsZTogZnVuY3Rpb24oIGVsZW1lbnQgKSB7XG5cdFx0dGhpcy5mb2N1c2FibGUgPSB0aGlzLmZvY3VzYWJsZS5hZGQoIGVsZW1lbnQgKTtcblx0XHR0aGlzLl9vbiggZWxlbWVudCwge1xuXHRcdFx0Zm9jdXNpbjogZnVuY3Rpb24oIGV2ZW50ICkge1xuXHRcdFx0XHR0aGlzLl9hZGRDbGFzcyggJCggZXZlbnQuY3VycmVudFRhcmdldCApLCBudWxsLCBcInVpLXN0YXRlLWZvY3VzXCIgKTtcblx0XHRcdH0sXG5cdFx0XHRmb2N1c291dDogZnVuY3Rpb24oIGV2ZW50ICkge1xuXHRcdFx0XHR0aGlzLl9yZW1vdmVDbGFzcyggJCggZXZlbnQuY3VycmVudFRhcmdldCApLCBudWxsLCBcInVpLXN0YXRlLWZvY3VzXCIgKTtcblx0XHRcdH1cblx0XHR9ICk7XG5cdH0sXG5cblx0X3RyaWdnZXI6IGZ1bmN0aW9uKCB0eXBlLCBldmVudCwgZGF0YSApIHtcblx0XHR2YXIgcHJvcCwgb3JpZztcblx0XHR2YXIgY2FsbGJhY2sgPSB0aGlzLm9wdGlvbnNbIHR5cGUgXTtcblxuXHRcdGRhdGEgPSBkYXRhIHx8IHt9O1xuXHRcdGV2ZW50ID0gJC5FdmVudCggZXZlbnQgKTtcblx0XHRldmVudC50eXBlID0gKCB0eXBlID09PSB0aGlzLndpZGdldEV2ZW50UHJlZml4ID9cblx0XHRcdHR5cGUgOlxuXHRcdFx0dGhpcy53aWRnZXRFdmVudFByZWZpeCArIHR5cGUgKS50b0xvd2VyQ2FzZSgpO1xuXG5cdFx0Ly8gVGhlIG9yaWdpbmFsIGV2ZW50IG1heSBjb21lIGZyb20gYW55IGVsZW1lbnRcblx0XHQvLyBzbyB3ZSBuZWVkIHRvIHJlc2V0IHRoZSB0YXJnZXQgb24gdGhlIG5ldyBldmVudFxuXHRcdGV2ZW50LnRhcmdldCA9IHRoaXMuZWxlbWVudFsgMCBdO1xuXG5cdFx0Ly8gQ29weSBvcmlnaW5hbCBldmVudCBwcm9wZXJ0aWVzIG92ZXIgdG8gdGhlIG5ldyBldmVudFxuXHRcdG9yaWcgPSBldmVudC5vcmlnaW5hbEV2ZW50O1xuXHRcdGlmICggb3JpZyApIHtcblx0XHRcdGZvciAoIHByb3AgaW4gb3JpZyApIHtcblx0XHRcdFx0aWYgKCAhKCBwcm9wIGluIGV2ZW50ICkgKSB7XG5cdFx0XHRcdFx0ZXZlbnRbIHByb3AgXSA9IG9yaWdbIHByb3AgXTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH1cblxuXHRcdHRoaXMuZWxlbWVudC50cmlnZ2VyKCBldmVudCwgZGF0YSApO1xuXHRcdHJldHVybiAhKCAkLmlzRnVuY3Rpb24oIGNhbGxiYWNrICkgJiZcblx0XHRcdGNhbGxiYWNrLmFwcGx5KCB0aGlzLmVsZW1lbnRbIDAgXSwgWyBldmVudCBdLmNvbmNhdCggZGF0YSApICkgPT09IGZhbHNlIHx8XG5cdFx0XHRldmVudC5pc0RlZmF1bHRQcmV2ZW50ZWQoKSApO1xuXHR9XG59O1xuXG4kLmVhY2goIHsgc2hvdzogXCJmYWRlSW5cIiwgaGlkZTogXCJmYWRlT3V0XCIgfSwgZnVuY3Rpb24oIG1ldGhvZCwgZGVmYXVsdEVmZmVjdCApIHtcblx0JC5XaWRnZXQucHJvdG90eXBlWyBcIl9cIiArIG1ldGhvZCBdID0gZnVuY3Rpb24oIGVsZW1lbnQsIG9wdGlvbnMsIGNhbGxiYWNrICkge1xuXHRcdGlmICggdHlwZW9mIG9wdGlvbnMgPT09IFwic3RyaW5nXCIgKSB7XG5cdFx0XHRvcHRpb25zID0geyBlZmZlY3Q6IG9wdGlvbnMgfTtcblx0XHR9XG5cblx0XHR2YXIgaGFzT3B0aW9ucztcblx0XHR2YXIgZWZmZWN0TmFtZSA9ICFvcHRpb25zID9cblx0XHRcdG1ldGhvZCA6XG5cdFx0XHRvcHRpb25zID09PSB0cnVlIHx8IHR5cGVvZiBvcHRpb25zID09PSBcIm51bWJlclwiID9cblx0XHRcdFx0ZGVmYXVsdEVmZmVjdCA6XG5cdFx0XHRcdG9wdGlvbnMuZWZmZWN0IHx8IGRlZmF1bHRFZmZlY3Q7XG5cblx0XHRvcHRpb25zID0gb3B0aW9ucyB8fCB7fTtcblx0XHRpZiAoIHR5cGVvZiBvcHRpb25zID09PSBcIm51bWJlclwiICkge1xuXHRcdFx0b3B0aW9ucyA9IHsgZHVyYXRpb246IG9wdGlvbnMgfTtcblx0XHR9XG5cblx0XHRoYXNPcHRpb25zID0gISQuaXNFbXB0eU9iamVjdCggb3B0aW9ucyApO1xuXHRcdG9wdGlvbnMuY29tcGxldGUgPSBjYWxsYmFjaztcblxuXHRcdGlmICggb3B0aW9ucy5kZWxheSApIHtcblx0XHRcdGVsZW1lbnQuZGVsYXkoIG9wdGlvbnMuZGVsYXkgKTtcblx0XHR9XG5cblx0XHRpZiAoIGhhc09wdGlvbnMgJiYgJC5lZmZlY3RzICYmICQuZWZmZWN0cy5lZmZlY3RbIGVmZmVjdE5hbWUgXSApIHtcblx0XHRcdGVsZW1lbnRbIG1ldGhvZCBdKCBvcHRpb25zICk7XG5cdFx0fSBlbHNlIGlmICggZWZmZWN0TmFtZSAhPT0gbWV0aG9kICYmIGVsZW1lbnRbIGVmZmVjdE5hbWUgXSApIHtcblx0XHRcdGVsZW1lbnRbIGVmZmVjdE5hbWUgXSggb3B0aW9ucy5kdXJhdGlvbiwgb3B0aW9ucy5lYXNpbmcsIGNhbGxiYWNrICk7XG5cdFx0fSBlbHNlIHtcblx0XHRcdGVsZW1lbnQucXVldWUoIGZ1bmN0aW9uKCBuZXh0ICkge1xuXHRcdFx0XHQkKCB0aGlzIClbIG1ldGhvZCBdKCk7XG5cdFx0XHRcdGlmICggY2FsbGJhY2sgKSB7XG5cdFx0XHRcdFx0Y2FsbGJhY2suY2FsbCggZWxlbWVudFsgMCBdICk7XG5cdFx0XHRcdH1cblx0XHRcdFx0bmV4dCgpO1xuXHRcdFx0fSApO1xuXHRcdH1cblx0fTtcbn0gKTtcblxucmV0dXJuICQud2lkZ2V0O1xuXG59ICkgKTtcblxuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIC4vbm9kZV9tb2R1bGVzL2pxdWVyeS11aS91aS93aWRnZXQuanNcbi8vIG1vZHVsZSBpZCA9IDM2XG4vLyBtb2R1bGUgY2h1bmtzID0gMCIsIiggZnVuY3Rpb24oIGZhY3RvcnkgKSB7XG5cdGlmICggdHlwZW9mIGRlZmluZSA9PT0gXCJmdW5jdGlvblwiICYmIGRlZmluZS5hbWQgKSB7XG5cblx0XHQvLyBBTUQuIFJlZ2lzdGVyIGFzIGFuIGFub255bW91cyBtb2R1bGUuXG5cdFx0ZGVmaW5lKCBbIFwianF1ZXJ5XCIgXSwgZmFjdG9yeSApO1xuXHR9IGVsc2Uge1xuXG5cdFx0Ly8gQnJvd3NlciBnbG9iYWxzXG5cdFx0ZmFjdG9yeSggalF1ZXJ5ICk7XG5cdH1cbn0gKCBmdW5jdGlvbiggJCApIHtcblxuJC51aSA9ICQudWkgfHwge307XG5cbnJldHVybiAkLnVpLnZlcnNpb24gPSBcIjEuMTIuMVwiO1xuXG59ICkgKTtcblxuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIC4vbm9kZV9tb2R1bGVzL2pxdWVyeS11aS91aS92ZXJzaW9uLmpzXG4vLyBtb2R1bGUgaWQgPSAzN1xuLy8gbW9kdWxlIGNodW5rcyA9IDAiLCJ2YXIgZGlzcG9zZWQgPSBmYWxzZVxuZnVuY3Rpb24gaW5qZWN0U3R5bGUgKHNzckNvbnRleHQpIHtcbiAgaWYgKGRpc3Bvc2VkKSByZXR1cm5cbiAgcmVxdWlyZShcIiEhdnVlLXN0eWxlLWxvYWRlciFjc3MtbG9hZGVyP3NvdXJjZU1hcCEuLi8uLi8uLi8uLi9ub2RlX21vZHVsZXMvdnVlLWxvYWRlci9saWIvc3R5bGUtY29tcGlsZXIvaW5kZXg/e1xcXCJ2dWVcXFwiOnRydWUsXFxcImlkXFxcIjpcXFwiZGF0YS12LTNlZGVmM2JhXFxcIixcXFwic2NvcGVkXFxcIjp0cnVlLFxcXCJoYXNJbmxpbmVDb25maWdcXFwiOnRydWV9IS4uLy4uLy4uLy4uL25vZGVfbW9kdWxlcy92dWUtbG9hZGVyL2xpYi9zZWxlY3Rvcj90eXBlPXN0eWxlcyZpbmRleD0wIS4vYWxlcnQudnVlXCIpXG59XG52YXIgQ29tcG9uZW50ID0gcmVxdWlyZShcIiEuLi8uLi8uLi8uLi9ub2RlX21vZHVsZXMvdnVlLWxvYWRlci9saWIvY29tcG9uZW50LW5vcm1hbGl6ZXJcIikoXG4gIC8qIHNjcmlwdCAqL1xuICByZXF1aXJlKFwiISFiYWJlbC1sb2FkZXI/e1xcXCJjYWNoZURpcmVjdG9yeVxcXCI6dHJ1ZSxcXFwicHJlc2V0c1xcXCI6W1tcXFwiZW52XFxcIix7XFxcIm1vZHVsZXNcXFwiOmZhbHNlLFxcXCJ0YXJnZXRzXFxcIjp7XFxcImJyb3dzZXJzXFxcIjpbXFxcIj4gMiVcXFwiXSxcXFwidWdsaWZ5XFxcIjp0cnVlfX1dXX0hLi4vLi4vLi4vLi4vbm9kZV9tb2R1bGVzL3Z1ZS1sb2FkZXIvbGliL3NlbGVjdG9yP3R5cGU9c2NyaXB0JmluZGV4PTAhLi9hbGVydC52dWVcIiksXG4gIC8qIHRlbXBsYXRlICovXG4gIHJlcXVpcmUoXCIhIS4uLy4uLy4uLy4uL25vZGVfbW9kdWxlcy92dWUtbG9hZGVyL2xpYi90ZW1wbGF0ZS1jb21waWxlci9pbmRleD97XFxcImlkXFxcIjpcXFwiZGF0YS12LTNlZGVmM2JhXFxcIixcXFwiaGFzU2NvcGVkXFxcIjp0cnVlfSEuLi8uLi8uLi8uLi9ub2RlX21vZHVsZXMvdnVlLWxvYWRlci9saWIvc2VsZWN0b3I/dHlwZT10ZW1wbGF0ZSZpbmRleD0wIS4vYWxlcnQudnVlXCIpLFxuICAvKiBzdHlsZXMgKi9cbiAgaW5qZWN0U3R5bGUsXG4gIC8qIHNjb3BlSWQgKi9cbiAgXCJkYXRhLXYtM2VkZWYzYmFcIixcbiAgLyogbW9kdWxlSWRlbnRpZmllciAoc2VydmVyIG9ubHkpICovXG4gIG51bGxcbilcbkNvbXBvbmVudC5vcHRpb25zLl9fZmlsZSA9IFwiL2hvbWUvaHlkcm9nZW4vd29yay9zbmlwZS1pdC9yZXNvdXJjZXMvYXNzZXRzL2pzL2NvbXBvbmVudHMvYWxlcnQudnVlXCJcbmlmIChDb21wb25lbnQuZXNNb2R1bGUgJiYgT2JqZWN0LmtleXMoQ29tcG9uZW50LmVzTW9kdWxlKS5zb21lKGZ1bmN0aW9uIChrZXkpIHtyZXR1cm4ga2V5ICE9PSBcImRlZmF1bHRcIiAmJiBrZXkuc3Vic3RyKDAsIDIpICE9PSBcIl9fXCJ9KSkge2NvbnNvbGUuZXJyb3IoXCJuYW1lZCBleHBvcnRzIGFyZSBub3Qgc3VwcG9ydGVkIGluICoudnVlIGZpbGVzLlwiKX1cbmlmIChDb21wb25lbnQub3B0aW9ucy5mdW5jdGlvbmFsKSB7Y29uc29sZS5lcnJvcihcIlt2dWUtbG9hZGVyXSBhbGVydC52dWU6IGZ1bmN0aW9uYWwgY29tcG9uZW50cyBhcmUgbm90IHN1cHBvcnRlZCB3aXRoIHRlbXBsYXRlcywgdGhleSBzaG91bGQgdXNlIHJlbmRlciBmdW5jdGlvbnMuXCIpfVxuXG4vKiBob3QgcmVsb2FkICovXG5pZiAobW9kdWxlLmhvdCkgeyhmdW5jdGlvbiAoKSB7XG4gIHZhciBob3RBUEkgPSByZXF1aXJlKFwidnVlLWhvdC1yZWxvYWQtYXBpXCIpXG4gIGhvdEFQSS5pbnN0YWxsKHJlcXVpcmUoXCJ2dWVcIiksIGZhbHNlKVxuICBpZiAoIWhvdEFQSS5jb21wYXRpYmxlKSByZXR1cm5cbiAgbW9kdWxlLmhvdC5hY2NlcHQoKVxuICBpZiAoIW1vZHVsZS5ob3QuZGF0YSkge1xuICAgIGhvdEFQSS5jcmVhdGVSZWNvcmQoXCJkYXRhLXYtM2VkZWYzYmFcIiwgQ29tcG9uZW50Lm9wdGlvbnMpXG4gIH0gZWxzZSB7XG4gICAgaG90QVBJLnJlbG9hZChcImRhdGEtdi0zZWRlZjNiYVwiLCBDb21wb25lbnQub3B0aW9ucylcbiAgfVxuICBtb2R1bGUuaG90LmRpc3Bvc2UoZnVuY3Rpb24gKGRhdGEpIHtcbiAgICBkaXNwb3NlZCA9IHRydWVcbiAgfSlcbn0pKCl9XG5cbm1vZHVsZS5leHBvcnRzID0gQ29tcG9uZW50LmV4cG9ydHNcblxuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIC4vcmVzb3VyY2VzL2Fzc2V0cy9qcy9jb21wb25lbnRzL2FsZXJ0LnZ1ZVxuLy8gbW9kdWxlIGlkID0gMzhcbi8vIG1vZHVsZSBjaHVua3MgPSAwIiwiLy8gc3R5bGUtbG9hZGVyOiBBZGRzIHNvbWUgY3NzIHRvIHRoZSBET00gYnkgYWRkaW5nIGEgPHN0eWxlPiB0YWdcblxuLy8gbG9hZCB0aGUgc3R5bGVzXG52YXIgY29udGVudCA9IHJlcXVpcmUoXCIhIS4uLy4uLy4uLy4uL25vZGVfbW9kdWxlcy9jc3MtbG9hZGVyL2luZGV4LmpzP3NvdXJjZU1hcCEuLi8uLi8uLi8uLi9ub2RlX21vZHVsZXMvdnVlLWxvYWRlci9saWIvc3R5bGUtY29tcGlsZXIvaW5kZXguanM/e1xcXCJ2dWVcXFwiOnRydWUsXFxcImlkXFxcIjpcXFwiZGF0YS12LTNlZGVmM2JhXFxcIixcXFwic2NvcGVkXFxcIjp0cnVlLFxcXCJoYXNJbmxpbmVDb25maWdcXFwiOnRydWV9IS4uLy4uLy4uLy4uL25vZGVfbW9kdWxlcy92dWUtbG9hZGVyL2xpYi9zZWxlY3Rvci5qcz90eXBlPXN0eWxlcyZpbmRleD0wIS4vYWxlcnQudnVlXCIpO1xuaWYodHlwZW9mIGNvbnRlbnQgPT09ICdzdHJpbmcnKSBjb250ZW50ID0gW1ttb2R1bGUuaWQsIGNvbnRlbnQsICcnXV07XG5pZihjb250ZW50LmxvY2FscykgbW9kdWxlLmV4cG9ydHMgPSBjb250ZW50LmxvY2Fscztcbi8vIGFkZCB0aGUgc3R5bGVzIHRvIHRoZSBET01cbnZhciB1cGRhdGUgPSByZXF1aXJlKFwiIS4uLy4uLy4uLy4uL25vZGVfbW9kdWxlcy92dWUtc3R5bGUtbG9hZGVyL2xpYi9hZGRTdHlsZXNDbGllbnQuanNcIikoXCJkZDkxYTk4Y1wiLCBjb250ZW50LCBmYWxzZSk7XG4vLyBIb3QgTW9kdWxlIFJlcGxhY2VtZW50XG5pZihtb2R1bGUuaG90KSB7XG4gLy8gV2hlbiB0aGUgc3R5bGVzIGNoYW5nZSwgdXBkYXRlIHRoZSA8c3R5bGU+IHRhZ3NcbiBpZighY29udGVudC5sb2NhbHMpIHtcbiAgIG1vZHVsZS5ob3QuYWNjZXB0KFwiISEuLi8uLi8uLi8uLi9ub2RlX21vZHVsZXMvY3NzLWxvYWRlci9pbmRleC5qcz9zb3VyY2VNYXAhLi4vLi4vLi4vLi4vbm9kZV9tb2R1bGVzL3Z1ZS1sb2FkZXIvbGliL3N0eWxlLWNvbXBpbGVyL2luZGV4LmpzP3tcXFwidnVlXFxcIjp0cnVlLFxcXCJpZFxcXCI6XFxcImRhdGEtdi0zZWRlZjNiYVxcXCIsXFxcInNjb3BlZFxcXCI6dHJ1ZSxcXFwiaGFzSW5saW5lQ29uZmlnXFxcIjp0cnVlfSEuLi8uLi8uLi8uLi9ub2RlX21vZHVsZXMvdnVlLWxvYWRlci9saWIvc2VsZWN0b3IuanM/dHlwZT1zdHlsZXMmaW5kZXg9MCEuL2FsZXJ0LnZ1ZVwiLCBmdW5jdGlvbigpIHtcbiAgICAgdmFyIG5ld0NvbnRlbnQgPSByZXF1aXJlKFwiISEuLi8uLi8uLi8uLi9ub2RlX21vZHVsZXMvY3NzLWxvYWRlci9pbmRleC5qcz9zb3VyY2VNYXAhLi4vLi4vLi4vLi4vbm9kZV9tb2R1bGVzL3Z1ZS1sb2FkZXIvbGliL3N0eWxlLWNvbXBpbGVyL2luZGV4LmpzP3tcXFwidnVlXFxcIjp0cnVlLFxcXCJpZFxcXCI6XFxcImRhdGEtdi0zZWRlZjNiYVxcXCIsXFxcInNjb3BlZFxcXCI6dHJ1ZSxcXFwiaGFzSW5saW5lQ29uZmlnXFxcIjp0cnVlfSEuLi8uLi8uLi8uLi9ub2RlX21vZHVsZXMvdnVlLWxvYWRlci9saWIvc2VsZWN0b3IuanM/dHlwZT1zdHlsZXMmaW5kZXg9MCEuL2FsZXJ0LnZ1ZVwiKTtcbiAgICAgaWYodHlwZW9mIG5ld0NvbnRlbnQgPT09ICdzdHJpbmcnKSBuZXdDb250ZW50ID0gW1ttb2R1bGUuaWQsIG5ld0NvbnRlbnQsICcnXV07XG4gICAgIHVwZGF0ZShuZXdDb250ZW50KTtcbiAgIH0pO1xuIH1cbiAvLyBXaGVuIHRoZSBtb2R1bGUgaXMgZGlzcG9zZWQsIHJlbW92ZSB0aGUgPHN0eWxlPiB0YWdzXG4gbW9kdWxlLmhvdC5kaXNwb3NlKGZ1bmN0aW9uKCkgeyB1cGRhdGUoKTsgfSk7XG59XG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gLi9ub2RlX21vZHVsZXMvdnVlLXN0eWxlLWxvYWRlciEuL25vZGVfbW9kdWxlcy9jc3MtbG9hZGVyP3NvdXJjZU1hcCEuL25vZGVfbW9kdWxlcy92dWUtbG9hZGVyL2xpYi9zdHlsZS1jb21waWxlcj97XCJ2dWVcIjp0cnVlLFwiaWRcIjpcImRhdGEtdi0zZWRlZjNiYVwiLFwic2NvcGVkXCI6dHJ1ZSxcImhhc0lubGluZUNvbmZpZ1wiOnRydWV9IS4vbm9kZV9tb2R1bGVzL3Z1ZS1sb2FkZXIvbGliL3NlbGVjdG9yLmpzP3R5cGU9c3R5bGVzJmluZGV4PTAhLi9yZXNvdXJjZXMvYXNzZXRzL2pzL2NvbXBvbmVudHMvYWxlcnQudnVlXG4vLyBtb2R1bGUgaWQgPSAzOVxuLy8gbW9kdWxlIGNodW5rcyA9IDAiLCJleHBvcnRzID0gbW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKFwiLi4vLi4vLi4vLi4vbm9kZV9tb2R1bGVzL2Nzcy1sb2FkZXIvbGliL2Nzcy1iYXNlLmpzXCIpKHRydWUpO1xuLy8gaW1wb3J0c1xuXG5cbi8vIG1vZHVsZVxuZXhwb3J0cy5wdXNoKFttb2R1bGUuaWQsIFwiXFxuXFxuXCIsIFwiXCIsIHtcInZlcnNpb25cIjozLFwic291cmNlc1wiOltdLFwibmFtZXNcIjpbXSxcIm1hcHBpbmdzXCI6XCJcIixcImZpbGVcIjpcImFsZXJ0LnZ1ZVwiLFwic291cmNlUm9vdFwiOlwiXCJ9XSk7XG5cbi8vIGV4cG9ydHNcblxuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIC4vbm9kZV9tb2R1bGVzL2Nzcy1sb2FkZXI/c291cmNlTWFwIS4vbm9kZV9tb2R1bGVzL3Z1ZS1sb2FkZXIvbGliL3N0eWxlLWNvbXBpbGVyP3tcInZ1ZVwiOnRydWUsXCJpZFwiOlwiZGF0YS12LTNlZGVmM2JhXCIsXCJzY29wZWRcIjp0cnVlLFwiaGFzSW5saW5lQ29uZmlnXCI6dHJ1ZX0hLi9ub2RlX21vZHVsZXMvdnVlLWxvYWRlci9saWIvc2VsZWN0b3IuanM/dHlwZT1zdHlsZXMmaW5kZXg9MCEuL3Jlc291cmNlcy9hc3NldHMvanMvY29tcG9uZW50cy9hbGVydC52dWVcbi8vIG1vZHVsZSBpZCA9IDQwXG4vLyBtb2R1bGUgY2h1bmtzID0gMCIsIlxuPHN0eWxlIHNjb3BlZD5cbjwvc3R5bGU+XG5cbjx0ZW1wbGF0ZT5cbiAgICAgICAgPGRpdiBjbGFzcz1cImNvbC1tZC0xMlwiIDpjbGFzcz1cImFsZXJ0VHlwZVwiPlxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cImFsZXJ0XCIgOmNsYXNzPVwiYWxlcnRDbGFzc05hbWVcIj5cbiAgICAgICAgICAgICAgICA8YnV0dG9uIHR5cGU9XCJidXR0b25cIiBjbGFzcz1cImNsb3NlXCIgQGNsaWNrPVwiaGlkZUV2ZW50XCI+JnRpbWVzOzwvYnV0dG9uPlxuICAgICAgICAgICAgICAgIDxpIGNsYXNzPVwiZmEgZmEtY2hlY2sgZmFhLXB1bHNlIGFuaW1hdGVkXCIgdi1zaG93PVwiYWxlcnRUeXBlID09ICdzdWNjZXNzJ1wiPjwvaT5cbiAgICAgICAgICAgICAgICA8c3Ryb25nPnt7IHRpdGxlIH19IDwvc3Ryb25nPlxuICAgICAgICAgICAgICAgIDxzbG90Pjwvc2xvdD5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICA8L2Rpdj5cbjwvdGVtcGxhdGU+XG5cbjxzY3JpcHQ+XG4gICAgZXhwb3J0IGRlZmF1bHQge1xuICAgICAgICAvKlxuICAgICAgICAgKiBUaGUgY29tcG9uZW50J3MgZGF0YS5cbiAgICAgICAgICovXG4gICAgICAgIHByb3BzOiBbJ2FsZXJ0VHlwZScsICd0aXRsZSddLFxuXG4gICAgICAgIGNvbXB1dGVkOiB7XG4gICAgICAgICAgICBhbGVydENsYXNzTmFtZSgpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gJ2FsZXJ0LScgKyB0aGlzLmFsZXJ0VHlwZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSxcblxuICAgICAgICBtZXRob2RzOiB7XG4gICAgICAgICAgICBoaWRlRXZlbnQoKSB7XG4gICAgICAgICAgICAgICAgdGhpcy4kZW1pdCgnaGlkZScpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG48L3NjcmlwdD5cblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyBhbGVydC52dWU/MGUxN2Y0MjQiLCJtb2R1bGUuZXhwb3J0cz17cmVuZGVyOmZ1bmN0aW9uICgpe3ZhciBfdm09dGhpczt2YXIgX2g9X3ZtLiRjcmVhdGVFbGVtZW50O3ZhciBfYz1fdm0uX3NlbGYuX2N8fF9oO1xuICByZXR1cm4gX2MoJ2RpdicsIHtcbiAgICBzdGF0aWNDbGFzczogXCJjb2wtbWQtMTJcIixcbiAgICBjbGFzczogX3ZtLmFsZXJ0VHlwZVxuICB9LCBbX2MoJ2RpdicsIHtcbiAgICBzdGF0aWNDbGFzczogXCJhbGVydFwiLFxuICAgIGNsYXNzOiBfdm0uYWxlcnRDbGFzc05hbWVcbiAgfSwgW19jKCdidXR0b24nLCB7XG4gICAgc3RhdGljQ2xhc3M6IFwiY2xvc2VcIixcbiAgICBhdHRyczoge1xuICAgICAgXCJ0eXBlXCI6IFwiYnV0dG9uXCJcbiAgICB9LFxuICAgIG9uOiB7XG4gICAgICBcImNsaWNrXCI6IF92bS5oaWRlRXZlbnRcbiAgICB9XG4gIH0sIFtfdm0uX3YoXCLDl1wiKV0pLCBfdm0uX3YoXCIgXCIpLCBfYygnaScsIHtcbiAgICBkaXJlY3RpdmVzOiBbe1xuICAgICAgbmFtZTogXCJzaG93XCIsXG4gICAgICByYXdOYW1lOiBcInYtc2hvd1wiLFxuICAgICAgdmFsdWU6IChfdm0uYWxlcnRUeXBlID09ICdzdWNjZXNzJyksXG4gICAgICBleHByZXNzaW9uOiBcImFsZXJ0VHlwZSA9PSAnc3VjY2VzcydcIlxuICAgIH1dLFxuICAgIHN0YXRpY0NsYXNzOiBcImZhIGZhLWNoZWNrIGZhYS1wdWxzZSBhbmltYXRlZFwiXG4gIH0pLCBfdm0uX3YoXCIgXCIpLCBfYygnc3Ryb25nJywgW192bS5fdihfdm0uX3MoX3ZtLnRpdGxlKSArIFwiIFwiKV0pLCBfdm0uX3YoXCIgXCIpLCBfdm0uX3QoXCJkZWZhdWx0XCIpXSwgMildKVxufSxzdGF0aWNSZW5kZXJGbnM6IFtdfVxubW9kdWxlLmV4cG9ydHMucmVuZGVyLl93aXRoU3RyaXBwZWQgPSB0cnVlXG5pZiAobW9kdWxlLmhvdCkge1xuICBtb2R1bGUuaG90LmFjY2VwdCgpXG4gIGlmIChtb2R1bGUuaG90LmRhdGEpIHtcbiAgICAgcmVxdWlyZShcInZ1ZS1ob3QtcmVsb2FkLWFwaVwiKS5yZXJlbmRlcihcImRhdGEtdi0zZWRlZjNiYVwiLCBtb2R1bGUuZXhwb3J0cylcbiAgfVxufVxuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIC4vbm9kZV9tb2R1bGVzL3Z1ZS1sb2FkZXIvbGliL3RlbXBsYXRlLWNvbXBpbGVyP3tcImlkXCI6XCJkYXRhLXYtM2VkZWYzYmFcIixcImhhc1Njb3BlZFwiOnRydWV9IS4vbm9kZV9tb2R1bGVzL3Z1ZS1sb2FkZXIvbGliL3NlbGVjdG9yLmpzP3R5cGU9dGVtcGxhdGUmaW5kZXg9MCEuL3Jlc291cmNlcy9hc3NldHMvanMvY29tcG9uZW50cy9hbGVydC52dWVcbi8vIG1vZHVsZSBpZCA9IDQyXG4vLyBtb2R1bGUgY2h1bmtzID0gMCIsInZhciBkaXNwb3NlZCA9IGZhbHNlXG5mdW5jdGlvbiBpbmplY3RTdHlsZSAoc3NyQ29udGV4dCkge1xuICBpZiAoZGlzcG9zZWQpIHJldHVyblxuICByZXF1aXJlKFwiISF2dWUtc3R5bGUtbG9hZGVyIWNzcy1sb2FkZXI/c291cmNlTWFwIS4uLy4uLy4uLy4uLy4uL25vZGVfbW9kdWxlcy92dWUtbG9hZGVyL2xpYi9zdHlsZS1jb21waWxlci9pbmRleD97XFxcInZ1ZVxcXCI6dHJ1ZSxcXFwiaWRcXFwiOlxcXCJkYXRhLXYtNTY2N2MzMTJcXFwiLFxcXCJzY29wZWRcXFwiOnRydWUsXFxcImhhc0lubGluZUNvbmZpZ1xcXCI6dHJ1ZX0hLi4vLi4vLi4vLi4vLi4vbm9kZV9tb2R1bGVzL3Z1ZS1sb2FkZXIvbGliL3NlbGVjdG9yP3R5cGU9c3R5bGVzJmluZGV4PTAhLi9pbXBvcnRlci1lcnJvcnMudnVlXCIpXG59XG52YXIgQ29tcG9uZW50ID0gcmVxdWlyZShcIiEuLi8uLi8uLi8uLi8uLi9ub2RlX21vZHVsZXMvdnVlLWxvYWRlci9saWIvY29tcG9uZW50LW5vcm1hbGl6ZXJcIikoXG4gIC8qIHNjcmlwdCAqL1xuICByZXF1aXJlKFwiISFiYWJlbC1sb2FkZXI/e1xcXCJjYWNoZURpcmVjdG9yeVxcXCI6dHJ1ZSxcXFwicHJlc2V0c1xcXCI6W1tcXFwiZW52XFxcIix7XFxcIm1vZHVsZXNcXFwiOmZhbHNlLFxcXCJ0YXJnZXRzXFxcIjp7XFxcImJyb3dzZXJzXFxcIjpbXFxcIj4gMiVcXFwiXSxcXFwidWdsaWZ5XFxcIjp0cnVlfX1dXX0hLi4vLi4vLi4vLi4vLi4vbm9kZV9tb2R1bGVzL3Z1ZS1sb2FkZXIvbGliL3NlbGVjdG9yP3R5cGU9c2NyaXB0JmluZGV4PTAhLi9pbXBvcnRlci1lcnJvcnMudnVlXCIpLFxuICAvKiB0ZW1wbGF0ZSAqL1xuICByZXF1aXJlKFwiISEuLi8uLi8uLi8uLi8uLi9ub2RlX21vZHVsZXMvdnVlLWxvYWRlci9saWIvdGVtcGxhdGUtY29tcGlsZXIvaW5kZXg/e1xcXCJpZFxcXCI6XFxcImRhdGEtdi01NjY3YzMxMlxcXCIsXFxcImhhc1Njb3BlZFxcXCI6dHJ1ZX0hLi4vLi4vLi4vLi4vLi4vbm9kZV9tb2R1bGVzL3Z1ZS1sb2FkZXIvbGliL3NlbGVjdG9yP3R5cGU9dGVtcGxhdGUmaW5kZXg9MCEuL2ltcG9ydGVyLWVycm9ycy52dWVcIiksXG4gIC8qIHN0eWxlcyAqL1xuICBpbmplY3RTdHlsZSxcbiAgLyogc2NvcGVJZCAqL1xuICBcImRhdGEtdi01NjY3YzMxMlwiLFxuICAvKiBtb2R1bGVJZGVudGlmaWVyIChzZXJ2ZXIgb25seSkgKi9cbiAgbnVsbFxuKVxuQ29tcG9uZW50Lm9wdGlvbnMuX19maWxlID0gXCIvaG9tZS9oeWRyb2dlbi93b3JrL3NuaXBlLWl0L3Jlc291cmNlcy9hc3NldHMvanMvY29tcG9uZW50cy9pbXBvcnRlci9pbXBvcnRlci1lcnJvcnMudnVlXCJcbmlmIChDb21wb25lbnQuZXNNb2R1bGUgJiYgT2JqZWN0LmtleXMoQ29tcG9uZW50LmVzTW9kdWxlKS5zb21lKGZ1bmN0aW9uIChrZXkpIHtyZXR1cm4ga2V5ICE9PSBcImRlZmF1bHRcIiAmJiBrZXkuc3Vic3RyKDAsIDIpICE9PSBcIl9fXCJ9KSkge2NvbnNvbGUuZXJyb3IoXCJuYW1lZCBleHBvcnRzIGFyZSBub3Qgc3VwcG9ydGVkIGluICoudnVlIGZpbGVzLlwiKX1cbmlmIChDb21wb25lbnQub3B0aW9ucy5mdW5jdGlvbmFsKSB7Y29uc29sZS5lcnJvcihcIlt2dWUtbG9hZGVyXSBpbXBvcnRlci1lcnJvcnMudnVlOiBmdW5jdGlvbmFsIGNvbXBvbmVudHMgYXJlIG5vdCBzdXBwb3J0ZWQgd2l0aCB0ZW1wbGF0ZXMsIHRoZXkgc2hvdWxkIHVzZSByZW5kZXIgZnVuY3Rpb25zLlwiKX1cblxuLyogaG90IHJlbG9hZCAqL1xuaWYgKG1vZHVsZS5ob3QpIHsoZnVuY3Rpb24gKCkge1xuICB2YXIgaG90QVBJID0gcmVxdWlyZShcInZ1ZS1ob3QtcmVsb2FkLWFwaVwiKVxuICBob3RBUEkuaW5zdGFsbChyZXF1aXJlKFwidnVlXCIpLCBmYWxzZSlcbiAgaWYgKCFob3RBUEkuY29tcGF0aWJsZSkgcmV0dXJuXG4gIG1vZHVsZS5ob3QuYWNjZXB0KClcbiAgaWYgKCFtb2R1bGUuaG90LmRhdGEpIHtcbiAgICBob3RBUEkuY3JlYXRlUmVjb3JkKFwiZGF0YS12LTU2NjdjMzEyXCIsIENvbXBvbmVudC5vcHRpb25zKVxuICB9IGVsc2Uge1xuICAgIGhvdEFQSS5yZWxvYWQoXCJkYXRhLXYtNTY2N2MzMTJcIiwgQ29tcG9uZW50Lm9wdGlvbnMpXG4gIH1cbiAgbW9kdWxlLmhvdC5kaXNwb3NlKGZ1bmN0aW9uIChkYXRhKSB7XG4gICAgZGlzcG9zZWQgPSB0cnVlXG4gIH0pXG59KSgpfVxuXG5tb2R1bGUuZXhwb3J0cyA9IENvbXBvbmVudC5leHBvcnRzXG5cblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyAuL3Jlc291cmNlcy9hc3NldHMvanMvY29tcG9uZW50cy9pbXBvcnRlci9pbXBvcnRlci1lcnJvcnMudnVlXG4vLyBtb2R1bGUgaWQgPSA0M1xuLy8gbW9kdWxlIGNodW5rcyA9IDAiLCIvLyBzdHlsZS1sb2FkZXI6IEFkZHMgc29tZSBjc3MgdG8gdGhlIERPTSBieSBhZGRpbmcgYSA8c3R5bGU+IHRhZ1xuXG4vLyBsb2FkIHRoZSBzdHlsZXNcbnZhciBjb250ZW50ID0gcmVxdWlyZShcIiEhLi4vLi4vLi4vLi4vLi4vbm9kZV9tb2R1bGVzL2Nzcy1sb2FkZXIvaW5kZXguanM/c291cmNlTWFwIS4uLy4uLy4uLy4uLy4uL25vZGVfbW9kdWxlcy92dWUtbG9hZGVyL2xpYi9zdHlsZS1jb21waWxlci9pbmRleC5qcz97XFxcInZ1ZVxcXCI6dHJ1ZSxcXFwiaWRcXFwiOlxcXCJkYXRhLXYtNTY2N2MzMTJcXFwiLFxcXCJzY29wZWRcXFwiOnRydWUsXFxcImhhc0lubGluZUNvbmZpZ1xcXCI6dHJ1ZX0hLi4vLi4vLi4vLi4vLi4vbm9kZV9tb2R1bGVzL3Z1ZS1sb2FkZXIvbGliL3NlbGVjdG9yLmpzP3R5cGU9c3R5bGVzJmluZGV4PTAhLi9pbXBvcnRlci1lcnJvcnMudnVlXCIpO1xuaWYodHlwZW9mIGNvbnRlbnQgPT09ICdzdHJpbmcnKSBjb250ZW50ID0gW1ttb2R1bGUuaWQsIGNvbnRlbnQsICcnXV07XG5pZihjb250ZW50LmxvY2FscykgbW9kdWxlLmV4cG9ydHMgPSBjb250ZW50LmxvY2Fscztcbi8vIGFkZCB0aGUgc3R5bGVzIHRvIHRoZSBET01cbnZhciB1cGRhdGUgPSByZXF1aXJlKFwiIS4uLy4uLy4uLy4uLy4uL25vZGVfbW9kdWxlcy92dWUtc3R5bGUtbG9hZGVyL2xpYi9hZGRTdHlsZXNDbGllbnQuanNcIikoXCIzMDlkZWViZFwiLCBjb250ZW50LCBmYWxzZSk7XG4vLyBIb3QgTW9kdWxlIFJlcGxhY2VtZW50XG5pZihtb2R1bGUuaG90KSB7XG4gLy8gV2hlbiB0aGUgc3R5bGVzIGNoYW5nZSwgdXBkYXRlIHRoZSA8c3R5bGU+IHRhZ3NcbiBpZighY29udGVudC5sb2NhbHMpIHtcbiAgIG1vZHVsZS5ob3QuYWNjZXB0KFwiISEuLi8uLi8uLi8uLi8uLi9ub2RlX21vZHVsZXMvY3NzLWxvYWRlci9pbmRleC5qcz9zb3VyY2VNYXAhLi4vLi4vLi4vLi4vLi4vbm9kZV9tb2R1bGVzL3Z1ZS1sb2FkZXIvbGliL3N0eWxlLWNvbXBpbGVyL2luZGV4LmpzP3tcXFwidnVlXFxcIjp0cnVlLFxcXCJpZFxcXCI6XFxcImRhdGEtdi01NjY3YzMxMlxcXCIsXFxcInNjb3BlZFxcXCI6dHJ1ZSxcXFwiaGFzSW5saW5lQ29uZmlnXFxcIjp0cnVlfSEuLi8uLi8uLi8uLi8uLi9ub2RlX21vZHVsZXMvdnVlLWxvYWRlci9saWIvc2VsZWN0b3IuanM/dHlwZT1zdHlsZXMmaW5kZXg9MCEuL2ltcG9ydGVyLWVycm9ycy52dWVcIiwgZnVuY3Rpb24oKSB7XG4gICAgIHZhciBuZXdDb250ZW50ID0gcmVxdWlyZShcIiEhLi4vLi4vLi4vLi4vLi4vbm9kZV9tb2R1bGVzL2Nzcy1sb2FkZXIvaW5kZXguanM/c291cmNlTWFwIS4uLy4uLy4uLy4uLy4uL25vZGVfbW9kdWxlcy92dWUtbG9hZGVyL2xpYi9zdHlsZS1jb21waWxlci9pbmRleC5qcz97XFxcInZ1ZVxcXCI6dHJ1ZSxcXFwiaWRcXFwiOlxcXCJkYXRhLXYtNTY2N2MzMTJcXFwiLFxcXCJzY29wZWRcXFwiOnRydWUsXFxcImhhc0lubGluZUNvbmZpZ1xcXCI6dHJ1ZX0hLi4vLi4vLi4vLi4vLi4vbm9kZV9tb2R1bGVzL3Z1ZS1sb2FkZXIvbGliL3NlbGVjdG9yLmpzP3R5cGU9c3R5bGVzJmluZGV4PTAhLi9pbXBvcnRlci1lcnJvcnMudnVlXCIpO1xuICAgICBpZih0eXBlb2YgbmV3Q29udGVudCA9PT0gJ3N0cmluZycpIG5ld0NvbnRlbnQgPSBbW21vZHVsZS5pZCwgbmV3Q29udGVudCwgJyddXTtcbiAgICAgdXBkYXRlKG5ld0NvbnRlbnQpO1xuICAgfSk7XG4gfVxuIC8vIFdoZW4gdGhlIG1vZHVsZSBpcyBkaXNwb3NlZCwgcmVtb3ZlIHRoZSA8c3R5bGU+IHRhZ3NcbiBtb2R1bGUuaG90LmRpc3Bvc2UoZnVuY3Rpb24oKSB7IHVwZGF0ZSgpOyB9KTtcbn1cblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyAuL25vZGVfbW9kdWxlcy92dWUtc3R5bGUtbG9hZGVyIS4vbm9kZV9tb2R1bGVzL2Nzcy1sb2FkZXI/c291cmNlTWFwIS4vbm9kZV9tb2R1bGVzL3Z1ZS1sb2FkZXIvbGliL3N0eWxlLWNvbXBpbGVyP3tcInZ1ZVwiOnRydWUsXCJpZFwiOlwiZGF0YS12LTU2NjdjMzEyXCIsXCJzY29wZWRcIjp0cnVlLFwiaGFzSW5saW5lQ29uZmlnXCI6dHJ1ZX0hLi9ub2RlX21vZHVsZXMvdnVlLWxvYWRlci9saWIvc2VsZWN0b3IuanM/dHlwZT1zdHlsZXMmaW5kZXg9MCEuL3Jlc291cmNlcy9hc3NldHMvanMvY29tcG9uZW50cy9pbXBvcnRlci9pbXBvcnRlci1lcnJvcnMudnVlXG4vLyBtb2R1bGUgaWQgPSA0NFxuLy8gbW9kdWxlIGNodW5rcyA9IDAiLCJleHBvcnRzID0gbW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKFwiLi4vLi4vLi4vLi4vLi4vbm9kZV9tb2R1bGVzL2Nzcy1sb2FkZXIvbGliL2Nzcy1iYXNlLmpzXCIpKHRydWUpO1xuLy8gaW1wb3J0c1xuXG5cbi8vIG1vZHVsZVxuZXhwb3J0cy5wdXNoKFttb2R1bGUuaWQsIFwiXFxuXFxuXCIsIFwiXCIsIHtcInZlcnNpb25cIjozLFwic291cmNlc1wiOltdLFwibmFtZXNcIjpbXSxcIm1hcHBpbmdzXCI6XCJcIixcImZpbGVcIjpcImltcG9ydGVyLWVycm9ycy52dWVcIixcInNvdXJjZVJvb3RcIjpcIlwifV0pO1xuXG4vLyBleHBvcnRzXG5cblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyAuL25vZGVfbW9kdWxlcy9jc3MtbG9hZGVyP3NvdXJjZU1hcCEuL25vZGVfbW9kdWxlcy92dWUtbG9hZGVyL2xpYi9zdHlsZS1jb21waWxlcj97XCJ2dWVcIjp0cnVlLFwiaWRcIjpcImRhdGEtdi01NjY3YzMxMlwiLFwic2NvcGVkXCI6dHJ1ZSxcImhhc0lubGluZUNvbmZpZ1wiOnRydWV9IS4vbm9kZV9tb2R1bGVzL3Z1ZS1sb2FkZXIvbGliL3NlbGVjdG9yLmpzP3R5cGU9c3R5bGVzJmluZGV4PTAhLi9yZXNvdXJjZXMvYXNzZXRzL2pzL2NvbXBvbmVudHMvaW1wb3J0ZXIvaW1wb3J0ZXItZXJyb3JzLnZ1ZVxuLy8gbW9kdWxlIGlkID0gNDVcbi8vIG1vZHVsZSBjaHVua3MgPSAwIiwiXG48c3R5bGUgc2NvcGVkPlxuPC9zdHlsZT5cblxuPHRlbXBsYXRlPlxuICAgIDxkaXYgY2xhc3M9XCJib3hcIiB2LWlmPVwiZXJyb3JzXCI+XG4gIDxkaXYgY2xhc3M9XCJib3gtYm9keVwiPlxuICAgIDxkaXYgY2xhc3M9XCJhbGVydCBhbGVydC13YXJuaW5nXCI+XG4gICAgICA8c3Ryb25nPldhcm5pbmc8L3N0cm9uZz4gU29tZSBFcnJvcnMgb2NjdXJlZCB3aGlsZSBpbXBvcnRpbmdcbiAgICA8L2Rpdj5cblxuICAgIDxkaXYgY2xhc3M9XCJlcnJvcnMtdGFibGVcIj5cbiAgICAgIDx0YWJsZSBjbGFzcz1cInRhYmxlIHRhYmxlLXN0cmlwZWQgdGFibGUtYm9yZGVyZWRcIiBpZD1cImVycm9ycy10YWJsZVwiPlxuICAgICAgICA8dGhlYWQ+XG4gICAgICAgICAgPHRoPkl0ZW08L3RoPlxuICAgICAgICAgIDx0aD5FcnJvcnM8L3RoPlxuICAgICAgICA8L3RoZWFkPlxuICAgICAgICA8dGJvZHk+XG4gICAgICAgICAgPHRyIHYtZm9yPVwiKGVycm9yLCBpdGVtKSBpbiBlcnJvcnNcIj5cbiAgICAgICAgICAgIDx0ZD57eyBpdGVtIH19PC90ZD5cbiAgICAgICAgICAgIDx0ZCB2LWZvcj1cIih2YWx1ZSwgZmllbGQpIGluIGVycm9yXCI+XG4gICAgICAgICAgICAgICAgPGI+e3sgZmllbGQgfX06PC9iPlxuICAgICAgICAgICAgICAgIDxzcGFuIHYtZm9yPVwiZXJyb3JTdHJpbmcgaW4gdmFsdWVcIj57e2Vycm9yU3RyaW5nWzBdfX08L3NwYW4+XG4gICAgICAgICAgICAgIDxiciAvPlxuICAgICAgICAgICAgPC90ZD5cbiAgICAgICAgICA8L3RyPlxuICAgICAgICA8L3Rib2R5PlxuICAgICAgPC90YWJsZT5cbiAgICA8L2Rpdj5cbiAgPC9kaXY+XG48L2Rpdj5cbjwvdGVtcGxhdGU+XG5cbjxzY3JpcHQ+XG4gICAgZXhwb3J0IGRlZmF1bHQge1xuICAgICAgICAvKlxuICAgICAgICAgKiBUaGUgY29tcG9uZW50J3MgZGF0YS5cbiAgICAgICAgICovXG4gICAgICAgICBwcm9wczogWydlcnJvcnMnXSxcbiAgICB9XG5cbjwvc2NyaXB0PlxuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIGltcG9ydGVyLWVycm9ycy52dWU/NThkNzNjOTEiLCJtb2R1bGUuZXhwb3J0cz17cmVuZGVyOmZ1bmN0aW9uICgpe3ZhciBfdm09dGhpczt2YXIgX2g9X3ZtLiRjcmVhdGVFbGVtZW50O3ZhciBfYz1fdm0uX3NlbGYuX2N8fF9oO1xuICByZXR1cm4gKF92bS5lcnJvcnMpID8gX2MoJ2RpdicsIHtcbiAgICBzdGF0aWNDbGFzczogXCJib3hcIlxuICB9LCBbX2MoJ2RpdicsIHtcbiAgICBzdGF0aWNDbGFzczogXCJib3gtYm9keVwiXG4gIH0sIFtfdm0uX20oMCksIF92bS5fdihcIiBcIiksIF9jKCdkaXYnLCB7XG4gICAgc3RhdGljQ2xhc3M6IFwiZXJyb3JzLXRhYmxlXCJcbiAgfSwgW19jKCd0YWJsZScsIHtcbiAgICBzdGF0aWNDbGFzczogXCJ0YWJsZSB0YWJsZS1zdHJpcGVkIHRhYmxlLWJvcmRlcmVkXCIsXG4gICAgYXR0cnM6IHtcbiAgICAgIFwiaWRcIjogXCJlcnJvcnMtdGFibGVcIlxuICAgIH1cbiAgfSwgW192bS5fbSgxKSwgX3ZtLl92KFwiIFwiKSwgX2MoJ3Rib2R5JywgX3ZtLl9sKChfdm0uZXJyb3JzKSwgZnVuY3Rpb24oZXJyb3IsIGl0ZW0pIHtcbiAgICByZXR1cm4gX2MoJ3RyJywgW19jKCd0ZCcsIFtfdm0uX3YoX3ZtLl9zKGl0ZW0pKV0pLCBfdm0uX3YoXCIgXCIpLCBfdm0uX2woKGVycm9yKSwgZnVuY3Rpb24odmFsdWUsIGZpZWxkKSB7XG4gICAgICByZXR1cm4gX2MoJ3RkJywgW19jKCdiJywgW192bS5fdihfdm0uX3MoZmllbGQpICsgXCI6XCIpXSksIF92bS5fdihcIiBcIiksIF92bS5fbCgodmFsdWUpLCBmdW5jdGlvbihlcnJvclN0cmluZykge1xuICAgICAgICByZXR1cm4gX2MoJ3NwYW4nLCBbX3ZtLl92KF92bS5fcyhlcnJvclN0cmluZ1swXSkpXSlcbiAgICAgIH0pLCBfdm0uX3YoXCIgXCIpLCBfYygnYnInKV0sIDIpXG4gICAgfSldLCAyKVxuICB9KSldKV0pXSldKSA6IF92bS5fZSgpXG59LHN0YXRpY1JlbmRlckZuczogW2Z1bmN0aW9uICgpe3ZhciBfdm09dGhpczt2YXIgX2g9X3ZtLiRjcmVhdGVFbGVtZW50O3ZhciBfYz1fdm0uX3NlbGYuX2N8fF9oO1xuICByZXR1cm4gX2MoJ2RpdicsIHtcbiAgICBzdGF0aWNDbGFzczogXCJhbGVydCBhbGVydC13YXJuaW5nXCJcbiAgfSwgW19jKCdzdHJvbmcnLCBbX3ZtLl92KFwiV2FybmluZ1wiKV0pLCBfdm0uX3YoXCIgU29tZSBFcnJvcnMgb2NjdXJlZCB3aGlsZSBpbXBvcnRpbmdcXG4gICAgXCIpXSlcbn0sZnVuY3Rpb24gKCl7dmFyIF92bT10aGlzO3ZhciBfaD1fdm0uJGNyZWF0ZUVsZW1lbnQ7dmFyIF9jPV92bS5fc2VsZi5fY3x8X2g7XG4gIHJldHVybiBfYygndGhlYWQnLCBbX2MoJ3RoJywgW192bS5fdihcIkl0ZW1cIildKSwgX3ZtLl92KFwiIFwiKSwgX2MoJ3RoJywgW192bS5fdihcIkVycm9yc1wiKV0pXSlcbn1dfVxubW9kdWxlLmV4cG9ydHMucmVuZGVyLl93aXRoU3RyaXBwZWQgPSB0cnVlXG5pZiAobW9kdWxlLmhvdCkge1xuICBtb2R1bGUuaG90LmFjY2VwdCgpXG4gIGlmIChtb2R1bGUuaG90LmRhdGEpIHtcbiAgICAgcmVxdWlyZShcInZ1ZS1ob3QtcmVsb2FkLWFwaVwiKS5yZXJlbmRlcihcImRhdGEtdi01NjY3YzMxMlwiLCBtb2R1bGUuZXhwb3J0cylcbiAgfVxufVxuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIC4vbm9kZV9tb2R1bGVzL3Z1ZS1sb2FkZXIvbGliL3RlbXBsYXRlLWNvbXBpbGVyP3tcImlkXCI6XCJkYXRhLXYtNTY2N2MzMTJcIixcImhhc1Njb3BlZFwiOnRydWV9IS4vbm9kZV9tb2R1bGVzL3Z1ZS1sb2FkZXIvbGliL3NlbGVjdG9yLmpzP3R5cGU9dGVtcGxhdGUmaW5kZXg9MCEuL3Jlc291cmNlcy9hc3NldHMvanMvY29tcG9uZW50cy9pbXBvcnRlci9pbXBvcnRlci1lcnJvcnMudnVlXG4vLyBtb2R1bGUgaWQgPSA0N1xuLy8gbW9kdWxlIGNodW5rcyA9IDAiLCJ2YXIgZGlzcG9zZWQgPSBmYWxzZVxuZnVuY3Rpb24gaW5qZWN0U3R5bGUgKHNzckNvbnRleHQpIHtcbiAgaWYgKGRpc3Bvc2VkKSByZXR1cm5cbiAgcmVxdWlyZShcIiEhdnVlLXN0eWxlLWxvYWRlciFjc3MtbG9hZGVyP3NvdXJjZU1hcCEuLi8uLi8uLi8uLi8uLi9ub2RlX21vZHVsZXMvdnVlLWxvYWRlci9saWIvc3R5bGUtY29tcGlsZXIvaW5kZXg/e1xcXCJ2dWVcXFwiOnRydWUsXFxcImlkXFxcIjpcXFwiZGF0YS12LTkxNjE5ZjNhXFxcIixcXFwic2NvcGVkXFxcIjpmYWxzZSxcXFwiaGFzSW5saW5lQ29uZmlnXFxcIjp0cnVlfSEuLi8uLi8uLi8uLi8uLi9ub2RlX21vZHVsZXMvdnVlLWxvYWRlci9saWIvc2VsZWN0b3I/dHlwZT1zdHlsZXMmaW5kZXg9MCEuL2ltcG9ydGVyLWZpbGUudnVlXCIpXG59XG52YXIgQ29tcG9uZW50ID0gcmVxdWlyZShcIiEuLi8uLi8uLi8uLi8uLi9ub2RlX21vZHVsZXMvdnVlLWxvYWRlci9saWIvY29tcG9uZW50LW5vcm1hbGl6ZXJcIikoXG4gIC8qIHNjcmlwdCAqL1xuICByZXF1aXJlKFwiISFiYWJlbC1sb2FkZXI/e1xcXCJjYWNoZURpcmVjdG9yeVxcXCI6dHJ1ZSxcXFwicHJlc2V0c1xcXCI6W1tcXFwiZW52XFxcIix7XFxcIm1vZHVsZXNcXFwiOmZhbHNlLFxcXCJ0YXJnZXRzXFxcIjp7XFxcImJyb3dzZXJzXFxcIjpbXFxcIj4gMiVcXFwiXSxcXFwidWdsaWZ5XFxcIjp0cnVlfX1dXX0hLi4vLi4vLi4vLi4vLi4vbm9kZV9tb2R1bGVzL3Z1ZS1sb2FkZXIvbGliL3NlbGVjdG9yP3R5cGU9c2NyaXB0JmluZGV4PTAhLi9pbXBvcnRlci1maWxlLnZ1ZVwiKSxcbiAgLyogdGVtcGxhdGUgKi9cbiAgcmVxdWlyZShcIiEhLi4vLi4vLi4vLi4vLi4vbm9kZV9tb2R1bGVzL3Z1ZS1sb2FkZXIvbGliL3RlbXBsYXRlLWNvbXBpbGVyL2luZGV4P3tcXFwiaWRcXFwiOlxcXCJkYXRhLXYtOTE2MTlmM2FcXFwiLFxcXCJoYXNTY29wZWRcXFwiOmZhbHNlfSEuLi8uLi8uLi8uLi8uLi9ub2RlX21vZHVsZXMvdnVlLWxvYWRlci9saWIvc2VsZWN0b3I/dHlwZT10ZW1wbGF0ZSZpbmRleD0wIS4vaW1wb3J0ZXItZmlsZS52dWVcIiksXG4gIC8qIHN0eWxlcyAqL1xuICBpbmplY3RTdHlsZSxcbiAgLyogc2NvcGVJZCAqL1xuICBudWxsLFxuICAvKiBtb2R1bGVJZGVudGlmaWVyIChzZXJ2ZXIgb25seSkgKi9cbiAgbnVsbFxuKVxuQ29tcG9uZW50Lm9wdGlvbnMuX19maWxlID0gXCIvaG9tZS9oeWRyb2dlbi93b3JrL3NuaXBlLWl0L3Jlc291cmNlcy9hc3NldHMvanMvY29tcG9uZW50cy9pbXBvcnRlci9pbXBvcnRlci1maWxlLnZ1ZVwiXG5pZiAoQ29tcG9uZW50LmVzTW9kdWxlICYmIE9iamVjdC5rZXlzKENvbXBvbmVudC5lc01vZHVsZSkuc29tZShmdW5jdGlvbiAoa2V5KSB7cmV0dXJuIGtleSAhPT0gXCJkZWZhdWx0XCIgJiYga2V5LnN1YnN0cigwLCAyKSAhPT0gXCJfX1wifSkpIHtjb25zb2xlLmVycm9yKFwibmFtZWQgZXhwb3J0cyBhcmUgbm90IHN1cHBvcnRlZCBpbiAqLnZ1ZSBmaWxlcy5cIil9XG5pZiAoQ29tcG9uZW50Lm9wdGlvbnMuZnVuY3Rpb25hbCkge2NvbnNvbGUuZXJyb3IoXCJbdnVlLWxvYWRlcl0gaW1wb3J0ZXItZmlsZS52dWU6IGZ1bmN0aW9uYWwgY29tcG9uZW50cyBhcmUgbm90IHN1cHBvcnRlZCB3aXRoIHRlbXBsYXRlcywgdGhleSBzaG91bGQgdXNlIHJlbmRlciBmdW5jdGlvbnMuXCIpfVxuXG4vKiBob3QgcmVsb2FkICovXG5pZiAobW9kdWxlLmhvdCkgeyhmdW5jdGlvbiAoKSB7XG4gIHZhciBob3RBUEkgPSByZXF1aXJlKFwidnVlLWhvdC1yZWxvYWQtYXBpXCIpXG4gIGhvdEFQSS5pbnN0YWxsKHJlcXVpcmUoXCJ2dWVcIiksIGZhbHNlKVxuICBpZiAoIWhvdEFQSS5jb21wYXRpYmxlKSByZXR1cm5cbiAgbW9kdWxlLmhvdC5hY2NlcHQoKVxuICBpZiAoIW1vZHVsZS5ob3QuZGF0YSkge1xuICAgIGhvdEFQSS5jcmVhdGVSZWNvcmQoXCJkYXRhLXYtOTE2MTlmM2FcIiwgQ29tcG9uZW50Lm9wdGlvbnMpXG4gIH0gZWxzZSB7XG4gICAgaG90QVBJLnJlbG9hZChcImRhdGEtdi05MTYxOWYzYVwiLCBDb21wb25lbnQub3B0aW9ucylcbiAgfVxuICBtb2R1bGUuaG90LmRpc3Bvc2UoZnVuY3Rpb24gKGRhdGEpIHtcbiAgICBkaXNwb3NlZCA9IHRydWVcbiAgfSlcbn0pKCl9XG5cbm1vZHVsZS5leHBvcnRzID0gQ29tcG9uZW50LmV4cG9ydHNcblxuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIC4vcmVzb3VyY2VzL2Fzc2V0cy9qcy9jb21wb25lbnRzL2ltcG9ydGVyL2ltcG9ydGVyLWZpbGUudnVlXG4vLyBtb2R1bGUgaWQgPSA0OFxuLy8gbW9kdWxlIGNodW5rcyA9IDAiLCIvLyBzdHlsZS1sb2FkZXI6IEFkZHMgc29tZSBjc3MgdG8gdGhlIERPTSBieSBhZGRpbmcgYSA8c3R5bGU+IHRhZ1xuXG4vLyBsb2FkIHRoZSBzdHlsZXNcbnZhciBjb250ZW50ID0gcmVxdWlyZShcIiEhLi4vLi4vLi4vLi4vLi4vbm9kZV9tb2R1bGVzL2Nzcy1sb2FkZXIvaW5kZXguanM/c291cmNlTWFwIS4uLy4uLy4uLy4uLy4uL25vZGVfbW9kdWxlcy92dWUtbG9hZGVyL2xpYi9zdHlsZS1jb21waWxlci9pbmRleC5qcz97XFxcInZ1ZVxcXCI6dHJ1ZSxcXFwiaWRcXFwiOlxcXCJkYXRhLXYtOTE2MTlmM2FcXFwiLFxcXCJzY29wZWRcXFwiOmZhbHNlLFxcXCJoYXNJbmxpbmVDb25maWdcXFwiOnRydWV9IS4uLy4uLy4uLy4uLy4uL25vZGVfbW9kdWxlcy92dWUtbG9hZGVyL2xpYi9zZWxlY3Rvci5qcz90eXBlPXN0eWxlcyZpbmRleD0wIS4vaW1wb3J0ZXItZmlsZS52dWVcIik7XG5pZih0eXBlb2YgY29udGVudCA9PT0gJ3N0cmluZycpIGNvbnRlbnQgPSBbW21vZHVsZS5pZCwgY29udGVudCwgJyddXTtcbmlmKGNvbnRlbnQubG9jYWxzKSBtb2R1bGUuZXhwb3J0cyA9IGNvbnRlbnQubG9jYWxzO1xuLy8gYWRkIHRoZSBzdHlsZXMgdG8gdGhlIERPTVxudmFyIHVwZGF0ZSA9IHJlcXVpcmUoXCIhLi4vLi4vLi4vLi4vLi4vbm9kZV9tb2R1bGVzL3Z1ZS1zdHlsZS1sb2FkZXIvbGliL2FkZFN0eWxlc0NsaWVudC5qc1wiKShcIjY3OGY0OGY0XCIsIGNvbnRlbnQsIGZhbHNlKTtcbi8vIEhvdCBNb2R1bGUgUmVwbGFjZW1lbnRcbmlmKG1vZHVsZS5ob3QpIHtcbiAvLyBXaGVuIHRoZSBzdHlsZXMgY2hhbmdlLCB1cGRhdGUgdGhlIDxzdHlsZT4gdGFnc1xuIGlmKCFjb250ZW50LmxvY2Fscykge1xuICAgbW9kdWxlLmhvdC5hY2NlcHQoXCIhIS4uLy4uLy4uLy4uLy4uL25vZGVfbW9kdWxlcy9jc3MtbG9hZGVyL2luZGV4LmpzP3NvdXJjZU1hcCEuLi8uLi8uLi8uLi8uLi9ub2RlX21vZHVsZXMvdnVlLWxvYWRlci9saWIvc3R5bGUtY29tcGlsZXIvaW5kZXguanM/e1xcXCJ2dWVcXFwiOnRydWUsXFxcImlkXFxcIjpcXFwiZGF0YS12LTkxNjE5ZjNhXFxcIixcXFwic2NvcGVkXFxcIjpmYWxzZSxcXFwiaGFzSW5saW5lQ29uZmlnXFxcIjp0cnVlfSEuLi8uLi8uLi8uLi8uLi9ub2RlX21vZHVsZXMvdnVlLWxvYWRlci9saWIvc2VsZWN0b3IuanM/dHlwZT1zdHlsZXMmaW5kZXg9MCEuL2ltcG9ydGVyLWZpbGUudnVlXCIsIGZ1bmN0aW9uKCkge1xuICAgICB2YXIgbmV3Q29udGVudCA9IHJlcXVpcmUoXCIhIS4uLy4uLy4uLy4uLy4uL25vZGVfbW9kdWxlcy9jc3MtbG9hZGVyL2luZGV4LmpzP3NvdXJjZU1hcCEuLi8uLi8uLi8uLi8uLi9ub2RlX21vZHVsZXMvdnVlLWxvYWRlci9saWIvc3R5bGUtY29tcGlsZXIvaW5kZXguanM/e1xcXCJ2dWVcXFwiOnRydWUsXFxcImlkXFxcIjpcXFwiZGF0YS12LTkxNjE5ZjNhXFxcIixcXFwic2NvcGVkXFxcIjpmYWxzZSxcXFwiaGFzSW5saW5lQ29uZmlnXFxcIjp0cnVlfSEuLi8uLi8uLi8uLi8uLi9ub2RlX21vZHVsZXMvdnVlLWxvYWRlci9saWIvc2VsZWN0b3IuanM/dHlwZT1zdHlsZXMmaW5kZXg9MCEuL2ltcG9ydGVyLWZpbGUudnVlXCIpO1xuICAgICBpZih0eXBlb2YgbmV3Q29udGVudCA9PT0gJ3N0cmluZycpIG5ld0NvbnRlbnQgPSBbW21vZHVsZS5pZCwgbmV3Q29udGVudCwgJyddXTtcbiAgICAgdXBkYXRlKG5ld0NvbnRlbnQpO1xuICAgfSk7XG4gfVxuIC8vIFdoZW4gdGhlIG1vZHVsZSBpcyBkaXNwb3NlZCwgcmVtb3ZlIHRoZSA8c3R5bGU+IHRhZ3NcbiBtb2R1bGUuaG90LmRpc3Bvc2UoZnVuY3Rpb24oKSB7IHVwZGF0ZSgpOyB9KTtcbn1cblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyAuL25vZGVfbW9kdWxlcy92dWUtc3R5bGUtbG9hZGVyIS4vbm9kZV9tb2R1bGVzL2Nzcy1sb2FkZXI/c291cmNlTWFwIS4vbm9kZV9tb2R1bGVzL3Z1ZS1sb2FkZXIvbGliL3N0eWxlLWNvbXBpbGVyP3tcInZ1ZVwiOnRydWUsXCJpZFwiOlwiZGF0YS12LTkxNjE5ZjNhXCIsXCJzY29wZWRcIjpmYWxzZSxcImhhc0lubGluZUNvbmZpZ1wiOnRydWV9IS4vbm9kZV9tb2R1bGVzL3Z1ZS1sb2FkZXIvbGliL3NlbGVjdG9yLmpzP3R5cGU9c3R5bGVzJmluZGV4PTAhLi9yZXNvdXJjZXMvYXNzZXRzL2pzL2NvbXBvbmVudHMvaW1wb3J0ZXIvaW1wb3J0ZXItZmlsZS52dWVcbi8vIG1vZHVsZSBpZCA9IDQ5XG4vLyBtb2R1bGUgY2h1bmtzID0gMCIsImV4cG9ydHMgPSBtb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoXCIuLi8uLi8uLi8uLi8uLi9ub2RlX21vZHVsZXMvY3NzLWxvYWRlci9saWIvY3NzLWJhc2UuanNcIikodHJ1ZSk7XG4vLyBpbXBvcnRzXG5cblxuLy8gbW9kdWxlXG5leHBvcnRzLnB1c2goW21vZHVsZS5pZCwgXCJcXG50ciB7XFxuICAgIHBhZGRpbmctbGVmdDozMHB4O1xcbn1cXG5cIiwgXCJcIiwge1widmVyc2lvblwiOjMsXCJzb3VyY2VzXCI6W1wiL2hvbWUvaHlkcm9nZW4vd29yay9zbmlwZS1pdC9yZXNvdXJjZXMvYXNzZXRzL2pzL2NvbXBvbmVudHMvaW1wb3J0ZXIvaW1wb3J0ZXItZmlsZS52dWU/NDcwNjM5NTlcIl0sXCJuYW1lc1wiOltdLFwibWFwcGluZ3NcIjpcIjtBQUNBO0lBQ0Esa0JBQUE7Q0FDQVwiLFwiZmlsZVwiOlwiaW1wb3J0ZXItZmlsZS52dWVcIixcInNvdXJjZXNDb250ZW50XCI6W1wiPHN0eWxlPlxcbnRyIHtcXG4gICAgcGFkZGluZy1sZWZ0OjMwcHg7XFxufVxcbjwvc3R5bGU+XFxuXFxuPHRlbXBsYXRlPlxcbiAgICA8dHIgdi1zaG93PVxcXCJwcm9jZXNzRGV0YWlsXFxcIj5cXG4gICAgICAgIDx0ZCBjb2xzcGFuPVxcXCIzXFxcIj5cXG4gICAgICAgICAgICA8aDQgY2xhc3M9XFxcIm1vZGFsLXRpdGxlXFxcIj5JbXBvcnQgRmlsZTo8L2g0PlxcbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XFxcImR5bmFtaWMtZm9ybS1yb3dcXFwiPlxcbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVxcXCJjb2wtbWQtNCBjb2wteHMtMTJcXFwiPlxcbiAgICAgICAgICAgICAgICAgICAgPGxhYmVsIGZvcj1cXFwiaW1wb3J0LXR5cGVcXFwiPkltcG9ydCBUeXBlOjwvbGFiZWw+XFxuICAgICAgICAgICAgICAgIDwvZGl2PlxcbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVxcXCJjb2wtbWQtNCBjb2wteHMtMTJcXFwiPlxcbiAgICAgICAgICAgICAgICAgICAgPHNlbGVjdDIgOm9wdGlvbnM9XFxcIm9wdGlvbnMuaW1wb3J0VHlwZXNcXFwiIHYtbW9kZWw9XFxcIm9wdGlvbnMuaW1wb3J0VHlwZVxcXCI+XFxuICAgICAgICAgICAgICAgICAgICAgICAgPG9wdGlvbiBkaXNhYmxlZCB2YWx1ZT1cXFwiMFxcXCI+PC9vcHRpb24+XFxuICAgICAgICAgICAgICAgICAgICA8L3NlbGVjdDI+XFxuICAgICAgICAgICAgICAgIDwvZGl2PlxcbiAgICAgICAgICAgIDwvZGl2PlxcbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XFxcImR5bmFtaWMtZm9ybS1yb3dcXFwiPlxcbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVxcXCJjb2wtbWQtNCBjb2wteHMtMTJcXFwiPlxcbiAgICAgICAgICAgICAgICAgICAgPGxhYmVsIGZvcj1cXFwiaW1wb3J0LXVwZGF0ZVxcXCI+VXBkYXRlIEV4aXN0aW5nIFZhbHVlcz86PC9sYWJlbD5cXG4gICAgICAgICAgICAgICAgPC9kaXY+XFxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XFxcImNvbC1tZC00IGNvbC14cy0xMlxcXCI+XFxuICAgICAgICAgICAgICAgICAgICA8aW5wdXQgdHlwZT1cXFwiY2hlY2tib3hcXFwiIG5hbWU9XFxcImltcG9ydC11cGRhdGVcXFwiIHYtbW9kZWw9XFxcIm9wdGlvbnMudXBkYXRlXFxcIj5cXG4gICAgICAgICAgICAgICAgPC9kaXY+XFxuICAgICAgICAgICAgPC9kaXY+XFxuXFxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cXFwiY29sLW1kLTEyXFxcIiBzdHlsZT1cXFwicGFkZGluZy10b3A6IDMwcHg7XFxcIj5cXG4gICAgICAgICAgICA8dGFibGUgY2xhc3M9XFxcInRhYmxlXFxcIj5cXG4gICAgICAgICAgICA8dGhlYWQ+XFxuICAgICAgICAgICAgICAgIDx0aD5IZWFkZXIgRmllbGQ8L3RoPlxcbiAgICAgICAgICAgICAgICA8dGg+SW1wb3J0IEZpZWxkPC90aD5cXG4gICAgICAgICAgICAgICAgPHRoPlNhbXBsZSBWYWx1ZTwvdGg+XFxuICAgICAgICAgICAgPC90aGVhZD5cXG4gICAgICAgICAgICA8dGJvZHk+XFxuICAgICAgICAgICAgPHRlbXBsYXRlIHYtZm9yPVxcXCIoaGVhZGVyLCBpbmRleCkgaW4gZmlsZS5oZWFkZXJfcm93XFxcIj5cXG4gICAgICAgICAgICAgICAgPHRyPlxcbiAgICAgICAgICAgICAgICAgICAgPHRkPlxcbiAgICAgICAgICAgICAgICAgICAgPGxhYmVsIDpmb3I9XFxcImhlYWRlclxcXCIgY2xhc3M9XFxcImNvbnRyb2xsYWJlbFxcXCI+e3sgaGVhZGVyIH19PC9sYWJlbD5cXG4gICAgICAgICAgICAgICAgICAgIDwvdGQ+XFxuICAgICAgICAgICAgICAgICAgICA8dGQ+XFxuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiByZXF1aXJlZD5cXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNlbGVjdDIgOm9wdGlvbnM9XFxcImNvbHVtbnNcXFwiIHYtbW9kZWw9XFxcImNvbHVtbk1hcHBpbmdzW2hlYWRlcl1cXFwiPlxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG9wdGlvbiB2YWx1ZT1cXFwiMFxcXCI+RG8gTm90IEltcG9ydDwvb3B0aW9uPlxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3NlbGVjdDI+XFxuICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XFxuICAgICAgICAgICAgICAgICAgICA8L3RkPlxcbiAgICAgICAgICAgICAgICAgICAgPHRkPlxcbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXY+e3sgYWN0aXZlRmlsZS5maXJzdF9yb3dbaW5kZXhdIH19PC9kaXY+XFxuICAgICAgICAgICAgICAgICAgICA8L3RkPlxcbiAgICAgICAgICAgICAgICA8L3RyPlxcbiAgICAgICAgICAgICAgICA8L3RlbXBsYXRlPlxcbiAgICAgICAgICAgIDwvdGJvZHk+XFxuICAgICAgICAgICAgPC90YWJsZT5cXG4gICAgICAgICAgICA8L2Rpdj5cXG4gICAgICAgIDwvdGQ+XFxuXFxuICAgICAgICA8dGQ+XFxuICAgICAgICAgICAgPGJ1dHRvbiB0eXBlPVxcXCJidXR0b25cXFwiIGNsYXNzPVxcXCJidG4gYnRuLWRlZmF1bHRcXFwiIEBjbGljaz1cXFwicHJvY2Vzc0RldGFpbCA9IGZhbHNlXFxcIj5DYW5jZWw8L2J1dHRvbj5cXG4gICAgICAgICAgICA8YnV0dG9uIHR5cGU9XFxcInN1Ym1pdFxcXCIgY2xhc3M9XFxcImJ0biBidG4tcHJpbWFyeVxcXCIgQGNsaWNrPVxcXCJwb3N0U2F2ZVxcXCI+SW1wb3J0PC9idXR0b24+XFxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cXFwiYWxlcnQgYWxlcnQtc3VjY2VzcyBjb2wtbWQtNSBjb2wtbWQtb2Zmc2V0LTFcXFwiIHN0eWxlPVxcXCJ0ZXh0LWFsaWduOmxlZnRcXFwiIHYtaWY9XFxcInN0YXR1c1RleHRcXFwiPnt7IHRoaXMuc3RhdHVzVGV4dCB9fTwvZGl2PlxcbiAgICAgICAgPC90ZD5cXG4gICAgPC90cj5cXG48L3RlbXBsYXRlPlxcblxcbjxzY3JpcHQ+XFxuICAgIGV4cG9ydCBkZWZhdWx0IHtcXG4gICAgICAgIHByb3BzOiBbJ2ZpbGUnLCAnY3VzdG9tRmllbGRVcmwnXSxcXG4gICAgICAgIGRhdGEoKSB7XFxuICAgICAgICAgICAgcmV0dXJuIHtcXG4gICAgICAgICAgICAgICAgYWN0aXZlRmlsZTogdGhpcy5maWxlLFxcbiAgICAgICAgICAgICAgICBwcm9jZXNzRGV0YWlsOiBmYWxzZSxcXG4gICAgICAgICAgICAgICAgc3RhdHVzVGV4dDogbnVsbCxcXG4gICAgICAgICAgICAgICAgb3B0aW9uczoge1xcbiAgICAgICAgICAgICAgICAgICAgaW1wb3J0VHlwZTogdGhpcy5maWxlLmltcG9ydF90eXBlLFxcbiAgICAgICAgICAgICAgICAgICAgdXBkYXRlOiBmYWxzZSxcXG4gICAgICAgICAgICAgICAgICAgIGltcG9ydFR5cGVzOiBbXFxuICAgICAgICAgICAgICAgICAgICAgICAgeyBpZDogJ2Fzc2V0JywgdGV4dDogJ0Fzc2V0cycgfSxcXG4gICAgICAgICAgICAgICAgICAgICAgICB7IGlkOiAnYWNjZXNzb3J5JywgdGV4dDogJ0FjY2Vzc29yaWVzJyB9LFxcbiAgICAgICAgICAgICAgICAgICAgICAgIHsgaWQ6ICdjb25zdW1hYmxlJywgdGV4dDogJ0NvbnN1bWFibGVzJyB9LFxcbiAgICAgICAgICAgICAgICAgICAgICAgIHsgaWQ6ICdjb21wb25lbnQnLCB0ZXh0OiAnQ29tcG9uZW50cycgfSxcXG4gICAgICAgICAgICAgICAgICAgICAgICB7IGlkOiAnbGljZW5zZScsIHRleHQ6ICdMaWNlbnNlcycgfSxcXG4gICAgICAgICAgICAgICAgICAgICAgICB7IGlkOiAndXNlcicsIHRleHQ6ICdVc2VycycgfVxcbiAgICAgICAgICAgICAgICAgICAgXSxcXG4gICAgICAgICAgICAgICAgICAgIHN0YXR1c1RleHQ6IG51bGwsXFxuICAgICAgICAgICAgICAgIH0sXFxuICAgICAgICAgICAgICAgIGNvbHVtbk9wdGlvbnM6IHtcXG4gICAgICAgICAgICAgICAgICAgIGdlbmVyYWw6IFtcXG4gICAgICAgICAgICAgICAgICAgICAgICB7aWQ6ICdjYXRlZ29yeScsIHRleHQ6ICdDYXRlZ29yeScgfSxcXG4gICAgICAgICAgICAgICAgICAgICAgICB7aWQ6ICdjb21wYW55JywgdGV4dDogJ0NvbXBhbnknIH0sXFxuICAgICAgICAgICAgICAgICAgICAgICAge2lkOiAnY2hlY2tvdXRfdG8nLCB0ZXh0OiAnQ2hlY2tlZCBvdXQgdG8nIH0sXFxuICAgICAgICAgICAgICAgICAgICAgICAge2lkOiAnZW1haWwnLCB0ZXh0OiAnRW1haWwnIH0sXFxuICAgICAgICAgICAgICAgICAgICAgICAge2lkOiAnZmlyc3RfbmFtZScsIHRleHQ6ICdGaXJzdCBOYW1lJyB9LFxcbiAgICAgICAgICAgICAgICAgICAgICAgIHtpZDogJ2l0ZW1fbmFtZScsIHRleHQ6ICdJdGVtIE5hbWUnIH0sXFxuICAgICAgICAgICAgICAgICAgICAgICAge2lkOiAnbGFzdF9uYW1lJywgdGV4dDogJ0xhc3QgTmFtZScgfSxcXG4gICAgICAgICAgICAgICAgICAgICAgICB7aWQ6ICdsb2NhdGlvbicsIHRleHQ6ICdMb2NhdGlvbicgfSxcXG4gICAgICAgICAgICAgICAgICAgICAgICB7aWQ6ICdtYWludGFpbmVkJywgdGV4dDogJ01haW50YWluZWQnIH0sXFxuICAgICAgICAgICAgICAgICAgICAgICAge2lkOiAnbWFudWZhY3R1cmVyJywgdGV4dDogJ01hbnVmYWN0dXJlcicgfSxcXG4gICAgICAgICAgICAgICAgICAgICAgICB7aWQ6ICdub3RlcycsIHRleHQ6ICdOb3RlcycgfSxcXG4gICAgICAgICAgICAgICAgICAgICAgICB7aWQ6ICdvcmRlcl9udW1iZXInLCB0ZXh0OiAnT3JkZXIgTnVtYmVyJyB9LFxcbiAgICAgICAgICAgICAgICAgICAgICAgIHtpZDogJ3B1cmNoYXNlX2Nvc3QnLCB0ZXh0OiAnUHVyY2hhc2UgQ29zdCcgfSxcXG4gICAgICAgICAgICAgICAgICAgICAgICB7aWQ6ICdwdXJjaGFzZV9kYXRlJywgdGV4dDogJ1B1cmNoYXNlIERhdGUnIH0sXFxuICAgICAgICAgICAgICAgICAgICAgICAge2lkOiAncXVhbnRpdHknLCB0ZXh0OiAnUXVhbnRpdHknIH0sXFxuICAgICAgICAgICAgICAgICAgICAgICAge2lkOiAncmVxdWVzdGFibGUnLCB0ZXh0OiAnUmVxdWVzdGFibGUnIH0sXFxuICAgICAgICAgICAgICAgICAgICAgICAge2lkOiAnc2VyaWFsJywgdGV4dDogJ1NlcmlhbCBOdW1iZXInIH0sXFxuICAgICAgICAgICAgICAgICAgICAgICAge2lkOiAnc3VwcGxpZXInLCB0ZXh0OiAnU3VwcGxpZXInIH0sXFxuICAgICAgICAgICAgICAgICAgICAgICAge2lkOiAndXNlcm5hbWUnLCB0ZXh0OiAnVXNlcm5hbWUnIH0sXFxuICAgICAgICAgICAgICAgICAgICBdLFxcbiAgICAgICAgICAgICAgICAgICAgYXNzZXRzOiBbXFxuICAgICAgICAgICAgICAgICAgICAgICAge2lkOiAnYXNzZXRfdGFnJywgdGV4dDogJ0Fzc2V0IFRhZycgfSxcXG4gICAgICAgICAgICAgICAgICAgICAgICB7aWQ6ICdhc3NldF9tb2RlbCcsIHRleHQ6ICdNb2RlbCBOYW1lJyB9LFxcbiAgICAgICAgICAgICAgICAgICAgICAgIHtpZDogJ2ltYWdlJywgdGV4dDogJ0ltYWdlIEZpbGVuYW1lJyB9LFxcbiAgICAgICAgICAgICAgICAgICAgICAgIHtpZDogJ21vZGVsX251bWJlcicsIHRleHQ6ICdNb2RlbCBOdW1iZXInIH0sXFxuICAgICAgICAgICAgICAgICAgICAgICAge2lkOiAnbmFtZScsIHRleHQ6ICdGdWxsIE5hbWUnIH0sXFxuICAgICAgICAgICAgICAgICAgICAgICAge2lkOiAnc3RhdHVzJywgdGV4dDogJ1N0YXR1cycgfSxcXG4gICAgICAgICAgICAgICAgICAgICAgICB7aWQ6ICd3YXJyYW50eV9tb250aHMnLCB0ZXh0OiAnV2FycmFudHkgTW9udGhzJyB9LFxcbiAgICAgICAgICAgICAgICAgICAgXSxcXG4gICAgICAgICAgICAgICAgICAgIGxpY2Vuc2VzOiBbXFxuICAgICAgICAgICAgICAgICAgICAgICAge2lkOiAnZXhwaXJhdGlvbl9kYXRlJywgdGV4dDogJ0V4cGlyYXRpb24gRGF0ZScgfSxcXG4gICAgICAgICAgICAgICAgICAgICAgICB7aWQ6ICdsaWNlbnNlX2VtYWlsJywgdGV4dDogJ0xpY2Vuc2VkIFRvIEVtYWlsJyB9LFxcbiAgICAgICAgICAgICAgICAgICAgICAgIHtpZDogJ2xpY2Vuc2VfbmFtZScsIHRleHQ6ICdMaWNlbnNlZCBUbyBOYW1lJyB9LFxcbiAgICAgICAgICAgICAgICAgICAgICAgIHtpZDogJ3B1cmNoYXNlX29yZGVyJywgdGV4dDogJ1B1cmNoYXNlIE9yZGVyJyB9LFxcbiAgICAgICAgICAgICAgICAgICAgICAgIHtpZDogJ3JlYXNzaWduYWJsZScsIHRleHQ6ICdSZWFzc2lnbmFibGUnIH0sXFxuICAgICAgICAgICAgICAgICAgICAgICAge2lkOiAnc2VhdHMnLCB0ZXh0OiAnU2VhdHMnIH0sXFxuICAgICAgICAgICAgICAgICAgICBdLFxcbiAgICAgICAgICAgICAgICAgICAgdXNlcnM6IFtcXG4gICAgICAgICAgICAgICAgICAgICAgICB7aWQ6ICdlbXBsb3llZV9udW0nLCB0ZXh0OiAnRW1wbG95ZWUgTnVtYmVyJyB9LFxcbiAgICAgICAgICAgICAgICAgICAgICAgIHtpZDogJ2pvYnRpdGxlJywgdGV4dDogJ0pvYiBUaXRsZScgfSxcXG4gICAgICAgICAgICAgICAgICAgICAgICB7aWQ6ICdwaG9uZV9udW1iZXInLCB0ZXh0OiAnUGhvbmUgTnVtYmVyJyB9LFxcbiAgICAgICAgICAgICAgICAgICAgXSxcXG4gICAgICAgICAgICAgICAgICAgIGN1c3RvbUZpZWxkczogW10sXFxuICAgICAgICAgICAgICAgIH0sXFxuICAgICAgICAgICAgICAgIGNvbHVtbk1hcHBpbmdzOiB0aGlzLmZpbGUuZmllbGRfbWFwIHx8IHt9LFxcbiAgICAgICAgICAgICAgICBhY3RpdmVDb2x1bW46IG51bGwsXFxuICAgICAgICAgICAgfVxcbiAgICAgICAgfSxcXG4gICAgICAgIGNyZWF0ZWQoKSB7XFxuICAgICAgICAgICAgdGhpcy5mZXRjaEN1c3RvbUZpZWxkcygpO1xcbiAgICAgICAgICAgIHdpbmRvdy5ldmVudEh1Yi4kb24oJ3Nob3dEZXRhaWxzJywgdGhpcy50b2dnbGVFeHRlbmRlZERpc3BsYXkpXFxuICAgICAgICAgICAgdGhpcy5wb3B1bGF0ZVNlbGVjdDJBY3RpdmVJdGVtcygpO1xcbiAgICAgICAgfSxcXG4gICAgICAgIGNvbXB1dGVkOiB7XFxuICAgICAgICAgICAgY29sdW1ucygpIHtcXG4gICAgICAgICAgICAgICAgc3dpdGNoKHRoaXMub3B0aW9ucy5pbXBvcnRUeXBlKSB7XFxuICAgICAgICAgICAgICAgICAgICBjYXNlICdhc3NldCc6XFxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuY29sdW1uT3B0aW9ucy5nZW5lcmFsLmNvbmNhdCh0aGlzLmNvbHVtbk9wdGlvbnMuYXNzZXRzKS5jb25jYXQodGhpcy5jb2x1bW5PcHRpb25zLmN1c3RvbUZpZWxkcyk7XFxuICAgICAgICAgICAgICAgICAgICBjYXNlICdsaWNlbnNlJzpcXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5jb2x1bW5PcHRpb25zLmdlbmVyYWwuY29uY2F0KHRoaXMuY29sdW1uT3B0aW9ucy5saWNlbnNlcyk7XFxuICAgICAgICAgICAgICAgICAgICBjYXNlICd1c2VyJzpcXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5jb2x1bW5PcHRpb25zLmdlbmVyYWwuY29uY2F0KHRoaXMuY29sdW1uT3B0aW9ucy51c2Vycyk7XFxuICAgICAgICAgICAgICAgIH1cXG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuY29sdW1uT3B0aW9ucy5nZW5lcmFsO1xcbiAgICAgICAgICAgIH1cXG4gICAgICAgIH0sXFxuICAgICAgICBtZXRob2RzOiB7XFxuICAgICAgICAgICAgZmV0Y2hDdXN0b21GaWVsZHMoKSB7XFxuICAgICAgICAgICAgICAgIHRoaXMuJGh0dHAuZ2V0KHRoaXMuY3VzdG9tRmllbGRVcmwpXFxuICAgICAgICAgICAgICAgIC50aGVuKCAoe2RhdGF9KSA9PiB7XFxuICAgICAgICAgICAgICAgICAgICBkYXRhID0gZGF0YS5yb3dzO1xcbiAgICAgICAgICAgICAgICAgICAgZGF0YS5mb3JFYWNoKChpdGVtKSA9PiB7XFxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5jb2x1bW5PcHRpb25zLmN1c3RvbUZpZWxkcy5wdXNoKHtcXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgJ2lkJzogaXRlbS5kYl9jb2x1bW5fbmFtZSxcXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgJ3RleHQnOiBpdGVtLm5hbWUsXFxuICAgICAgICAgICAgICAgICAgICAgICAgfSlcXG4gICAgICAgICAgICAgICAgICAgIH0pXFxuICAgICAgICAgICAgICAgIH0pO1xcbiAgICAgICAgICAgIH0sXFxuICAgICAgICAgICAgcG9zdFNhdmUoKSB7XFxuICAgICAgICAgICAgICAgIHRoaXMuc3RhdHVzVGV4dCA9IFxcXCJQcm9jZXNzaW5nLi4uXFxcIjtcXG4gICAgICAgICAgICAgICAgdGhpcy4kaHR0cC5wb3N0KHRoaXMuZmlsZS5wcm9jZXNzX3VybCwge1xcbiAgICAgICAgICAgICAgICAgICAgJ2ltcG9ydC11cGRhdGUnOiB0aGlzLm9wdGlvbnMudXBkYXRlLFxcbiAgICAgICAgICAgICAgICAgICAgJ2ltcG9ydC10eXBlJzogdGhpcy5vcHRpb25zLmltcG9ydFR5cGUsXFxuICAgICAgICAgICAgICAgICAgICAnY29sdW1uLW1hcHBpbmdzJzogdGhpcy5jb2x1bW5NYXBwaW5nc1xcbiAgICAgICAgICAgICAgICB9KS50aGVuKCAoe2JvZHl9KSA9PiB7XFxuICAgICAgICAgICAgICAgICAgICAvLyBTdWNjZXNzXFxuICAgICAgICAgICAgICAgICAgICB0aGlzLnN0YXR1c1RleHQgPSBcXFwiU3VjY2Vzcy4uLiBSZWRpcmVjdGluZy5cXFwiO1xcbiAgICAgICAgICAgICAgICAgICAgd2luZG93LmxvY2F0aW9uLmhyZWYgPSBib2R5Lm1lc3NhZ2VzLnJlZGlyZWN0X3VybDtcXG4gICAgICAgICAgICAgICAgfSwgKHtib2R5fSkgPT4ge1xcbiAgICAgICAgICAgICAgICAgICAgLy8gRmFpbHVyZVxcbiAgICAgICAgICAgICAgICAgICAgaWYoYm9keS5zdGF0dXMgPT0gJ2ltcG9ydC1lcnJvcnMnKSB7XFxuICAgICAgICAgICAgICAgICAgICAgICAgd2luZG93LmV2ZW50SHViLiRlbWl0KCdpbXBvcnRFcnJvcnMnLCBib2R5Lm1lc3NhZ2VzKTtcXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnN0YXR1c1RleHQgPSBcXFwiRXJyb3JcXFwiO1xcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLiRlbWl0KCdhbGVydCcsIHtcXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbWVzc2FnZTogYm9keS5tZXNzYWdlcyxcXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdHlwZTogXFxcImRhbmdlclxcXCIsXFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZpc2libGU6IHRydWUsXFxuICAgICAgICAgICAgICAgICAgICAgICAgfSlcXG4gICAgICAgICAgICAgICAgICAgIH1cXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuZGlzcGxheUltcG9ydE1vZGFsPWZhbHNlO1xcbiAgICAgICAgICAgICAgICB9KTtcXG4gICAgICAgICAgICB9LFxcbiAgICAgICAgICAgIHBvcHVsYXRlU2VsZWN0MkFjdGl2ZUl0ZW1zKCkge1xcbiAgICAgICAgICAgICAgICBpZih0aGlzLmZpbGUuZmllbGRfbWFwID09IG51bGwpIHtcXG4gICAgICAgICAgICAgICAgICAgIC8vIEJlZ2luIGJ5IHBvcHVsYXRpbmcgdGhlIGFjdGl2ZSBzZWxlY3Rpb24gaW4gZHJvcGRvd25zIHdpdGggYmxhbmsgdmFsdWVzLlxcbiAgICAgICAgICAgICAgICAgICAgZm9yICh2YXIgaT0wOyBpIDwgdGhpcy5maWxlLmhlYWRlcl9yb3cubGVuZ3RoOyBpKyspIHtcXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLiRzZXQodGhpcy5jb2x1bW5NYXBwaW5ncywgdGhpcy5maWxlLmhlYWRlcl9yb3dbaV0sIG51bGwpO1xcbiAgICAgICAgICAgICAgICAgICAgfVxcbiAgICAgICAgICAgICAgICAgICAgLy8gVGhlbiwgZm9yIGFueSB2YWx1ZXMgdGhhdCBoYXZlIGEgbGlrZWx5IG1hdGNoLCB3ZSBtYWtlIHRoYXQgYWN0aXZlLlxcbiAgICAgICAgICAgICAgICAgICAgZm9yKHZhciBqPTA7IGogPCB0aGlzLmNvbHVtbnMubGVuZ3RoOyBqKyspIHtcXG4gICAgICAgICAgICAgICAgICAgICAgICBsZXQgY29sdW1uID0gdGhpcy5jb2x1bW5zW2pdO1xcbiAgICAgICAgICAgICAgICAgICAgICAgIGxldCBpbmRleCA9IHRoaXMuZmlsZS5oZWFkZXJfcm93LmluZGV4T2YoY29sdW1uLnRleHQpXFxuICAgICAgICAgICAgICAgICAgICAgICAgaWYoaW5kZXggIT0gLTEpIHtcXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy4kc2V0KHRoaXMuY29sdW1uTWFwcGluZ3MsIHRoaXMuZmlsZS5oZWFkZXJfcm93W2luZGV4XSwgY29sdW1uLmlkKVxcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cXG4gICAgICAgICAgICAgICAgICAgIH1cXG4gICAgICAgICAgICAgICAgfVxcbiAgICAgICAgICAgIH0sXFxuICAgICAgICAgICAgdG9nZ2xlRXh0ZW5kZWREaXNwbGF5KGZpbGVJZCkge1xcbiAgICAgICAgICAgICAgICBpZihmaWxlSWQgPT0gdGhpcy5maWxlLmlkKSB7XFxuICAgICAgICAgICAgICAgICAgICB0aGlzLnByb2Nlc3NEZXRhaWwgPSAhdGhpcy5wcm9jZXNzRGV0YWlsXFxuICAgICAgICAgICAgICAgIH1cXG4gICAgICAgICAgICB9LFxcbiAgICAgICAgICAgIHVwZGF0ZU1vZGVsKGhlYWRlciwgdmFsdWUpIHtcXG4gICAgICAgICAgICAgICAgY29uc29sZS5sb2coaGVhZGVyLCB2YWx1ZSk7XFxuICAgICAgICAgICAgICAgIHRoaXMuY29sdW1uTWFwcGluZ3NbaGVhZGVyXSA9IHZhbHVlO1xcbiAgICAgICAgICAgIH1cXG4gICAgICAgIH0sXFxuICAgICAgICBjb21wb25lbnRzOiB7XFxuICAgICAgICAgICAgc2VsZWN0MjogcmVxdWlyZSgnLi4vc2VsZWN0Mi52dWUnKVxcbiAgICAgICAgfVxcbiAgICB9XFxuPC9zY3JpcHQ+XFxuXCJdLFwic291cmNlUm9vdFwiOlwiXCJ9XSk7XG5cbi8vIGV4cG9ydHNcblxuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIC4vbm9kZV9tb2R1bGVzL2Nzcy1sb2FkZXI/c291cmNlTWFwIS4vbm9kZV9tb2R1bGVzL3Z1ZS1sb2FkZXIvbGliL3N0eWxlLWNvbXBpbGVyP3tcInZ1ZVwiOnRydWUsXCJpZFwiOlwiZGF0YS12LTkxNjE5ZjNhXCIsXCJzY29wZWRcIjpmYWxzZSxcImhhc0lubGluZUNvbmZpZ1wiOnRydWV9IS4vbm9kZV9tb2R1bGVzL3Z1ZS1sb2FkZXIvbGliL3NlbGVjdG9yLmpzP3R5cGU9c3R5bGVzJmluZGV4PTAhLi9yZXNvdXJjZXMvYXNzZXRzL2pzL2NvbXBvbmVudHMvaW1wb3J0ZXIvaW1wb3J0ZXItZmlsZS52dWVcbi8vIG1vZHVsZSBpZCA9IDUwXG4vLyBtb2R1bGUgY2h1bmtzID0gMCIsIjxzdHlsZT5cbnRyIHtcbiAgICBwYWRkaW5nLWxlZnQ6MzBweDtcbn1cbjwvc3R5bGU+XG5cbjx0ZW1wbGF0ZT5cbiAgICA8dHIgdi1zaG93PVwicHJvY2Vzc0RldGFpbFwiPlxuICAgICAgICA8dGQgY29sc3Bhbj1cIjNcIj5cbiAgICAgICAgICAgIDxoNCBjbGFzcz1cIm1vZGFsLXRpdGxlXCI+SW1wb3J0IEZpbGU6PC9oND5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJkeW5hbWljLWZvcm0tcm93XCI+XG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImNvbC1tZC00IGNvbC14cy0xMlwiPlxuICAgICAgICAgICAgICAgICAgICA8bGFiZWwgZm9yPVwiaW1wb3J0LXR5cGVcIj5JbXBvcnQgVHlwZTo8L2xhYmVsPlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJjb2wtbWQtNCBjb2wteHMtMTJcIj5cbiAgICAgICAgICAgICAgICAgICAgPHNlbGVjdDIgOm9wdGlvbnM9XCJvcHRpb25zLmltcG9ydFR5cGVzXCIgdi1tb2RlbD1cIm9wdGlvbnMuaW1wb3J0VHlwZVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPG9wdGlvbiBkaXNhYmxlZCB2YWx1ZT1cIjBcIj48L29wdGlvbj5cbiAgICAgICAgICAgICAgICAgICAgPC9zZWxlY3QyPlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZHluYW1pYy1mb3JtLXJvd1wiPlxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJjb2wtbWQtNCBjb2wteHMtMTJcIj5cbiAgICAgICAgICAgICAgICAgICAgPGxhYmVsIGZvcj1cImltcG9ydC11cGRhdGVcIj5VcGRhdGUgRXhpc3RpbmcgVmFsdWVzPzo8L2xhYmVsPlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJjb2wtbWQtNCBjb2wteHMtMTJcIj5cbiAgICAgICAgICAgICAgICAgICAgPGlucHV0IHR5cGU9XCJjaGVja2JveFwiIG5hbWU9XCJpbXBvcnQtdXBkYXRlXCIgdi1tb2RlbD1cIm9wdGlvbnMudXBkYXRlXCI+XG4gICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8L2Rpdj5cblxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cImNvbC1tZC0xMlwiIHN0eWxlPVwicGFkZGluZy10b3A6IDMwcHg7XCI+XG4gICAgICAgICAgICA8dGFibGUgY2xhc3M9XCJ0YWJsZVwiPlxuICAgICAgICAgICAgPHRoZWFkPlxuICAgICAgICAgICAgICAgIDx0aD5IZWFkZXIgRmllbGQ8L3RoPlxuICAgICAgICAgICAgICAgIDx0aD5JbXBvcnQgRmllbGQ8L3RoPlxuICAgICAgICAgICAgICAgIDx0aD5TYW1wbGUgVmFsdWU8L3RoPlxuICAgICAgICAgICAgPC90aGVhZD5cbiAgICAgICAgICAgIDx0Ym9keT5cbiAgICAgICAgICAgIDx0ZW1wbGF0ZSB2LWZvcj1cIihoZWFkZXIsIGluZGV4KSBpbiBmaWxlLmhlYWRlcl9yb3dcIj5cbiAgICAgICAgICAgICAgICA8dHI+XG4gICAgICAgICAgICAgICAgICAgIDx0ZD5cbiAgICAgICAgICAgICAgICAgICAgPGxhYmVsIDpmb3I9XCJoZWFkZXJcIiBjbGFzcz1cImNvbnRyb2xsYWJlbFwiPnt7IGhlYWRlciB9fTwvbGFiZWw+XG4gICAgICAgICAgICAgICAgICAgIDwvdGQ+XG4gICAgICAgICAgICAgICAgICAgIDx0ZD5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgcmVxdWlyZWQ+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNlbGVjdDIgOm9wdGlvbnM9XCJjb2x1bW5zXCIgdi1tb2RlbD1cImNvbHVtbk1hcHBpbmdzW2hlYWRlcl1cIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG9wdGlvbiB2YWx1ZT1cIjBcIj5EbyBOb3QgSW1wb3J0PC9vcHRpb24+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9zZWxlY3QyPlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgIDwvdGQ+XG4gICAgICAgICAgICAgICAgICAgIDx0ZD5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXY+e3sgYWN0aXZlRmlsZS5maXJzdF9yb3dbaW5kZXhdIH19PC9kaXY+XG4gICAgICAgICAgICAgICAgICAgIDwvdGQ+XG4gICAgICAgICAgICAgICAgPC90cj5cbiAgICAgICAgICAgICAgICA8L3RlbXBsYXRlPlxuICAgICAgICAgICAgPC90Ym9keT5cbiAgICAgICAgICAgIDwvdGFibGU+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgPC90ZD5cblxuICAgICAgICA8dGQ+XG4gICAgICAgICAgICA8YnV0dG9uIHR5cGU9XCJidXR0b25cIiBjbGFzcz1cImJ0biBidG4tZGVmYXVsdFwiIEBjbGljaz1cInByb2Nlc3NEZXRhaWwgPSBmYWxzZVwiPkNhbmNlbDwvYnV0dG9uPlxuICAgICAgICAgICAgPGJ1dHRvbiB0eXBlPVwic3VibWl0XCIgY2xhc3M9XCJidG4gYnRuLXByaW1hcnlcIiBAY2xpY2s9XCJwb3N0U2F2ZVwiPkltcG9ydDwvYnV0dG9uPlxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cImFsZXJ0IGFsZXJ0LXN1Y2Nlc3MgY29sLW1kLTUgY29sLW1kLW9mZnNldC0xXCIgc3R5bGU9XCJ0ZXh0LWFsaWduOmxlZnRcIiB2LWlmPVwic3RhdHVzVGV4dFwiPnt7IHRoaXMuc3RhdHVzVGV4dCB9fTwvZGl2PlxuICAgICAgICA8L3RkPlxuICAgIDwvdHI+XG48L3RlbXBsYXRlPlxuXG48c2NyaXB0PlxuICAgIGV4cG9ydCBkZWZhdWx0IHtcbiAgICAgICAgcHJvcHM6IFsnZmlsZScsICdjdXN0b21GaWVsZFVybCddLFxuICAgICAgICBkYXRhKCkge1xuICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgICBhY3RpdmVGaWxlOiB0aGlzLmZpbGUsXG4gICAgICAgICAgICAgICAgcHJvY2Vzc0RldGFpbDogZmFsc2UsXG4gICAgICAgICAgICAgICAgc3RhdHVzVGV4dDogbnVsbCxcbiAgICAgICAgICAgICAgICBvcHRpb25zOiB7XG4gICAgICAgICAgICAgICAgICAgIGltcG9ydFR5cGU6IHRoaXMuZmlsZS5pbXBvcnRfdHlwZSxcbiAgICAgICAgICAgICAgICAgICAgdXBkYXRlOiBmYWxzZSxcbiAgICAgICAgICAgICAgICAgICAgaW1wb3J0VHlwZXM6IFtcbiAgICAgICAgICAgICAgICAgICAgICAgIHsgaWQ6ICdhc3NldCcsIHRleHQ6ICdBc3NldHMnIH0sXG4gICAgICAgICAgICAgICAgICAgICAgICB7IGlkOiAnYWNjZXNzb3J5JywgdGV4dDogJ0FjY2Vzc29yaWVzJyB9LFxuICAgICAgICAgICAgICAgICAgICAgICAgeyBpZDogJ2NvbnN1bWFibGUnLCB0ZXh0OiAnQ29uc3VtYWJsZXMnIH0sXG4gICAgICAgICAgICAgICAgICAgICAgICB7IGlkOiAnY29tcG9uZW50JywgdGV4dDogJ0NvbXBvbmVudHMnIH0sXG4gICAgICAgICAgICAgICAgICAgICAgICB7IGlkOiAnbGljZW5zZScsIHRleHQ6ICdMaWNlbnNlcycgfSxcbiAgICAgICAgICAgICAgICAgICAgICAgIHsgaWQ6ICd1c2VyJywgdGV4dDogJ1VzZXJzJyB9XG4gICAgICAgICAgICAgICAgICAgIF0sXG4gICAgICAgICAgICAgICAgICAgIHN0YXR1c1RleHQ6IG51bGwsXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICBjb2x1bW5PcHRpb25zOiB7XG4gICAgICAgICAgICAgICAgICAgIGdlbmVyYWw6IFtcbiAgICAgICAgICAgICAgICAgICAgICAgIHtpZDogJ2NhdGVnb3J5JywgdGV4dDogJ0NhdGVnb3J5JyB9LFxuICAgICAgICAgICAgICAgICAgICAgICAge2lkOiAnY29tcGFueScsIHRleHQ6ICdDb21wYW55JyB9LFxuICAgICAgICAgICAgICAgICAgICAgICAge2lkOiAnY2hlY2tvdXRfdG8nLCB0ZXh0OiAnQ2hlY2tlZCBvdXQgdG8nIH0sXG4gICAgICAgICAgICAgICAgICAgICAgICB7aWQ6ICdlbWFpbCcsIHRleHQ6ICdFbWFpbCcgfSxcbiAgICAgICAgICAgICAgICAgICAgICAgIHtpZDogJ2ZpcnN0X25hbWUnLCB0ZXh0OiAnRmlyc3QgTmFtZScgfSxcbiAgICAgICAgICAgICAgICAgICAgICAgIHtpZDogJ2l0ZW1fbmFtZScsIHRleHQ6ICdJdGVtIE5hbWUnIH0sXG4gICAgICAgICAgICAgICAgICAgICAgICB7aWQ6ICdsYXN0X25hbWUnLCB0ZXh0OiAnTGFzdCBOYW1lJyB9LFxuICAgICAgICAgICAgICAgICAgICAgICAge2lkOiAnbG9jYXRpb24nLCB0ZXh0OiAnTG9jYXRpb24nIH0sXG4gICAgICAgICAgICAgICAgICAgICAgICB7aWQ6ICdtYWludGFpbmVkJywgdGV4dDogJ01haW50YWluZWQnIH0sXG4gICAgICAgICAgICAgICAgICAgICAgICB7aWQ6ICdtYW51ZmFjdHVyZXInLCB0ZXh0OiAnTWFudWZhY3R1cmVyJyB9LFxuICAgICAgICAgICAgICAgICAgICAgICAge2lkOiAnbm90ZXMnLCB0ZXh0OiAnTm90ZXMnIH0sXG4gICAgICAgICAgICAgICAgICAgICAgICB7aWQ6ICdvcmRlcl9udW1iZXInLCB0ZXh0OiAnT3JkZXIgTnVtYmVyJyB9LFxuICAgICAgICAgICAgICAgICAgICAgICAge2lkOiAncHVyY2hhc2VfY29zdCcsIHRleHQ6ICdQdXJjaGFzZSBDb3N0JyB9LFxuICAgICAgICAgICAgICAgICAgICAgICAge2lkOiAncHVyY2hhc2VfZGF0ZScsIHRleHQ6ICdQdXJjaGFzZSBEYXRlJyB9LFxuICAgICAgICAgICAgICAgICAgICAgICAge2lkOiAncXVhbnRpdHknLCB0ZXh0OiAnUXVhbnRpdHknIH0sXG4gICAgICAgICAgICAgICAgICAgICAgICB7aWQ6ICdyZXF1ZXN0YWJsZScsIHRleHQ6ICdSZXF1ZXN0YWJsZScgfSxcbiAgICAgICAgICAgICAgICAgICAgICAgIHtpZDogJ3NlcmlhbCcsIHRleHQ6ICdTZXJpYWwgTnVtYmVyJyB9LFxuICAgICAgICAgICAgICAgICAgICAgICAge2lkOiAnc3VwcGxpZXInLCB0ZXh0OiAnU3VwcGxpZXInIH0sXG4gICAgICAgICAgICAgICAgICAgICAgICB7aWQ6ICd1c2VybmFtZScsIHRleHQ6ICdVc2VybmFtZScgfSxcbiAgICAgICAgICAgICAgICAgICAgXSxcbiAgICAgICAgICAgICAgICAgICAgYXNzZXRzOiBbXG4gICAgICAgICAgICAgICAgICAgICAgICB7aWQ6ICdhc3NldF90YWcnLCB0ZXh0OiAnQXNzZXQgVGFnJyB9LFxuICAgICAgICAgICAgICAgICAgICAgICAge2lkOiAnYXNzZXRfbW9kZWwnLCB0ZXh0OiAnTW9kZWwgTmFtZScgfSxcbiAgICAgICAgICAgICAgICAgICAgICAgIHtpZDogJ2ltYWdlJywgdGV4dDogJ0ltYWdlIEZpbGVuYW1lJyB9LFxuICAgICAgICAgICAgICAgICAgICAgICAge2lkOiAnbW9kZWxfbnVtYmVyJywgdGV4dDogJ01vZGVsIE51bWJlcicgfSxcbiAgICAgICAgICAgICAgICAgICAgICAgIHtpZDogJ25hbWUnLCB0ZXh0OiAnRnVsbCBOYW1lJyB9LFxuICAgICAgICAgICAgICAgICAgICAgICAge2lkOiAnc3RhdHVzJywgdGV4dDogJ1N0YXR1cycgfSxcbiAgICAgICAgICAgICAgICAgICAgICAgIHtpZDogJ3dhcnJhbnR5X21vbnRocycsIHRleHQ6ICdXYXJyYW50eSBNb250aHMnIH0sXG4gICAgICAgICAgICAgICAgICAgIF0sXG4gICAgICAgICAgICAgICAgICAgIGxpY2Vuc2VzOiBbXG4gICAgICAgICAgICAgICAgICAgICAgICB7aWQ6ICdleHBpcmF0aW9uX2RhdGUnLCB0ZXh0OiAnRXhwaXJhdGlvbiBEYXRlJyB9LFxuICAgICAgICAgICAgICAgICAgICAgICAge2lkOiAnbGljZW5zZV9lbWFpbCcsIHRleHQ6ICdMaWNlbnNlZCBUbyBFbWFpbCcgfSxcbiAgICAgICAgICAgICAgICAgICAgICAgIHtpZDogJ2xpY2Vuc2VfbmFtZScsIHRleHQ6ICdMaWNlbnNlZCBUbyBOYW1lJyB9LFxuICAgICAgICAgICAgICAgICAgICAgICAge2lkOiAncHVyY2hhc2Vfb3JkZXInLCB0ZXh0OiAnUHVyY2hhc2UgT3JkZXInIH0sXG4gICAgICAgICAgICAgICAgICAgICAgICB7aWQ6ICdyZWFzc2lnbmFibGUnLCB0ZXh0OiAnUmVhc3NpZ25hYmxlJyB9LFxuICAgICAgICAgICAgICAgICAgICAgICAge2lkOiAnc2VhdHMnLCB0ZXh0OiAnU2VhdHMnIH0sXG4gICAgICAgICAgICAgICAgICAgIF0sXG4gICAgICAgICAgICAgICAgICAgIHVzZXJzOiBbXG4gICAgICAgICAgICAgICAgICAgICAgICB7aWQ6ICdlbXBsb3llZV9udW0nLCB0ZXh0OiAnRW1wbG95ZWUgTnVtYmVyJyB9LFxuICAgICAgICAgICAgICAgICAgICAgICAge2lkOiAnam9idGl0bGUnLCB0ZXh0OiAnSm9iIFRpdGxlJyB9LFxuICAgICAgICAgICAgICAgICAgICAgICAge2lkOiAncGhvbmVfbnVtYmVyJywgdGV4dDogJ1Bob25lIE51bWJlcicgfSxcbiAgICAgICAgICAgICAgICAgICAgXSxcbiAgICAgICAgICAgICAgICAgICAgY3VzdG9tRmllbGRzOiBbXSxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIGNvbHVtbk1hcHBpbmdzOiB0aGlzLmZpbGUuZmllbGRfbWFwIHx8IHt9LFxuICAgICAgICAgICAgICAgIGFjdGl2ZUNvbHVtbjogbnVsbCxcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSxcbiAgICAgICAgY3JlYXRlZCgpIHtcbiAgICAgICAgICAgIHRoaXMuZmV0Y2hDdXN0b21GaWVsZHMoKTtcbiAgICAgICAgICAgIHdpbmRvdy5ldmVudEh1Yi4kb24oJ3Nob3dEZXRhaWxzJywgdGhpcy50b2dnbGVFeHRlbmRlZERpc3BsYXkpXG4gICAgICAgICAgICB0aGlzLnBvcHVsYXRlU2VsZWN0MkFjdGl2ZUl0ZW1zKCk7XG4gICAgICAgIH0sXG4gICAgICAgIGNvbXB1dGVkOiB7XG4gICAgICAgICAgICBjb2x1bW5zKCkge1xuICAgICAgICAgICAgICAgIHN3aXRjaCh0aGlzLm9wdGlvbnMuaW1wb3J0VHlwZSkge1xuICAgICAgICAgICAgICAgICAgICBjYXNlICdhc3NldCc6XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5jb2x1bW5PcHRpb25zLmdlbmVyYWwuY29uY2F0KHRoaXMuY29sdW1uT3B0aW9ucy5hc3NldHMpLmNvbmNhdCh0aGlzLmNvbHVtbk9wdGlvbnMuY3VzdG9tRmllbGRzKTtcbiAgICAgICAgICAgICAgICAgICAgY2FzZSAnbGljZW5zZSc6XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5jb2x1bW5PcHRpb25zLmdlbmVyYWwuY29uY2F0KHRoaXMuY29sdW1uT3B0aW9ucy5saWNlbnNlcyk7XG4gICAgICAgICAgICAgICAgICAgIGNhc2UgJ3VzZXInOlxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuY29sdW1uT3B0aW9ucy5nZW5lcmFsLmNvbmNhdCh0aGlzLmNvbHVtbk9wdGlvbnMudXNlcnMpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5jb2x1bW5PcHRpb25zLmdlbmVyYWw7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0sXG4gICAgICAgIG1ldGhvZHM6IHtcbiAgICAgICAgICAgIGZldGNoQ3VzdG9tRmllbGRzKCkge1xuICAgICAgICAgICAgICAgIHRoaXMuJGh0dHAuZ2V0KHRoaXMuY3VzdG9tRmllbGRVcmwpXG4gICAgICAgICAgICAgICAgLnRoZW4oICh7ZGF0YX0pID0+IHtcbiAgICAgICAgICAgICAgICAgICAgZGF0YSA9IGRhdGEucm93cztcbiAgICAgICAgICAgICAgICAgICAgZGF0YS5mb3JFYWNoKChpdGVtKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmNvbHVtbk9wdGlvbnMuY3VzdG9tRmllbGRzLnB1c2goe1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICdpZCc6IGl0ZW0uZGJfY29sdW1uX25hbWUsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgJ3RleHQnOiBpdGVtLm5hbWUsXG4gICAgICAgICAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHBvc3RTYXZlKCkge1xuICAgICAgICAgICAgICAgIHRoaXMuc3RhdHVzVGV4dCA9IFwiUHJvY2Vzc2luZy4uLlwiO1xuICAgICAgICAgICAgICAgIHRoaXMuJGh0dHAucG9zdCh0aGlzLmZpbGUucHJvY2Vzc191cmwsIHtcbiAgICAgICAgICAgICAgICAgICAgJ2ltcG9ydC11cGRhdGUnOiB0aGlzLm9wdGlvbnMudXBkYXRlLFxuICAgICAgICAgICAgICAgICAgICAnaW1wb3J0LXR5cGUnOiB0aGlzLm9wdGlvbnMuaW1wb3J0VHlwZSxcbiAgICAgICAgICAgICAgICAgICAgJ2NvbHVtbi1tYXBwaW5ncyc6IHRoaXMuY29sdW1uTWFwcGluZ3NcbiAgICAgICAgICAgICAgICB9KS50aGVuKCAoe2JvZHl9KSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIC8vIFN1Y2Nlc3NcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5zdGF0dXNUZXh0ID0gXCJTdWNjZXNzLi4uIFJlZGlyZWN0aW5nLlwiO1xuICAgICAgICAgICAgICAgICAgICB3aW5kb3cubG9jYXRpb24uaHJlZiA9IGJvZHkubWVzc2FnZXMucmVkaXJlY3RfdXJsO1xuICAgICAgICAgICAgICAgIH0sICh7Ym9keX0pID0+IHtcbiAgICAgICAgICAgICAgICAgICAgLy8gRmFpbHVyZVxuICAgICAgICAgICAgICAgICAgICBpZihib2R5LnN0YXR1cyA9PSAnaW1wb3J0LWVycm9ycycpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHdpbmRvdy5ldmVudEh1Yi4kZW1pdCgnaW1wb3J0RXJyb3JzJywgYm9keS5tZXNzYWdlcyk7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnN0YXR1c1RleHQgPSBcIkVycm9yXCI7XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLiRlbWl0KCdhbGVydCcsIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBtZXNzYWdlOiBib2R5Lm1lc3NhZ2VzLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHR5cGU6IFwiZGFuZ2VyXCIsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdmlzaWJsZTogdHJ1ZSxcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgdGhpcy5kaXNwbGF5SW1wb3J0TW9kYWw9ZmFsc2U7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgcG9wdWxhdGVTZWxlY3QyQWN0aXZlSXRlbXMoKSB7XG4gICAgICAgICAgICAgICAgaWYodGhpcy5maWxlLmZpZWxkX21hcCA9PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIEJlZ2luIGJ5IHBvcHVsYXRpbmcgdGhlIGFjdGl2ZSBzZWxlY3Rpb24gaW4gZHJvcGRvd25zIHdpdGggYmxhbmsgdmFsdWVzLlxuICAgICAgICAgICAgICAgICAgICBmb3IgKHZhciBpPTA7IGkgPCB0aGlzLmZpbGUuaGVhZGVyX3Jvdy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy4kc2V0KHRoaXMuY29sdW1uTWFwcGluZ3MsIHRoaXMuZmlsZS5oZWFkZXJfcm93W2ldLCBudWxsKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAvLyBUaGVuLCBmb3IgYW55IHZhbHVlcyB0aGF0IGhhdmUgYSBsaWtlbHkgbWF0Y2gsIHdlIG1ha2UgdGhhdCBhY3RpdmUuXG4gICAgICAgICAgICAgICAgICAgIGZvcih2YXIgaj0wOyBqIDwgdGhpcy5jb2x1bW5zLmxlbmd0aDsgaisrKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBsZXQgY29sdW1uID0gdGhpcy5jb2x1bW5zW2pdO1xuICAgICAgICAgICAgICAgICAgICAgICAgbGV0IGluZGV4ID0gdGhpcy5maWxlLmhlYWRlcl9yb3cuaW5kZXhPZihjb2x1bW4udGV4dClcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmKGluZGV4ICE9IC0xKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy4kc2V0KHRoaXMuY29sdW1uTWFwcGluZ3MsIHRoaXMuZmlsZS5oZWFkZXJfcm93W2luZGV4XSwgY29sdW1uLmlkKVxuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHRvZ2dsZUV4dGVuZGVkRGlzcGxheShmaWxlSWQpIHtcbiAgICAgICAgICAgICAgICBpZihmaWxlSWQgPT0gdGhpcy5maWxlLmlkKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMucHJvY2Vzc0RldGFpbCA9ICF0aGlzLnByb2Nlc3NEZXRhaWxcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgdXBkYXRlTW9kZWwoaGVhZGVyLCB2YWx1ZSkge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKGhlYWRlciwgdmFsdWUpO1xuICAgICAgICAgICAgICAgIHRoaXMuY29sdW1uTWFwcGluZ3NbaGVhZGVyXSA9IHZhbHVlO1xuICAgICAgICAgICAgfVxuICAgICAgICB9LFxuICAgICAgICBjb21wb25lbnRzOiB7XG4gICAgICAgICAgICBzZWxlY3QyOiByZXF1aXJlKCcuLi9zZWxlY3QyLnZ1ZScpXG4gICAgICAgIH1cbiAgICB9XG48L3NjcmlwdD5cblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyBpbXBvcnRlci1maWxlLnZ1ZT80NzA2Mzk1OSIsInZhciBkaXNwb3NlZCA9IGZhbHNlXG5mdW5jdGlvbiBpbmplY3RTdHlsZSAoc3NyQ29udGV4dCkge1xuICBpZiAoZGlzcG9zZWQpIHJldHVyblxuICByZXF1aXJlKFwiISF2dWUtc3R5bGUtbG9hZGVyIWNzcy1sb2FkZXI/c291cmNlTWFwIS4uLy4uLy4uLy4uL25vZGVfbW9kdWxlcy92dWUtbG9hZGVyL2xpYi9zdHlsZS1jb21waWxlci9pbmRleD97XFxcInZ1ZVxcXCI6dHJ1ZSxcXFwiaWRcXFwiOlxcXCJkYXRhLXYtZmY1NjRhODZcXFwiLFxcXCJzY29wZWRcXFwiOnRydWUsXFxcImhhc0lubGluZUNvbmZpZ1xcXCI6dHJ1ZX0hLi4vLi4vLi4vLi4vbm9kZV9tb2R1bGVzL3Z1ZS1sb2FkZXIvbGliL3NlbGVjdG9yP3R5cGU9c3R5bGVzJmluZGV4PTAhLi9zZWxlY3QyLnZ1ZVwiKVxufVxudmFyIENvbXBvbmVudCA9IHJlcXVpcmUoXCIhLi4vLi4vLi4vLi4vbm9kZV9tb2R1bGVzL3Z1ZS1sb2FkZXIvbGliL2NvbXBvbmVudC1ub3JtYWxpemVyXCIpKFxuICAvKiBzY3JpcHQgKi9cbiAgcmVxdWlyZShcIiEhYmFiZWwtbG9hZGVyP3tcXFwiY2FjaGVEaXJlY3RvcnlcXFwiOnRydWUsXFxcInByZXNldHNcXFwiOltbXFxcImVudlxcXCIse1xcXCJtb2R1bGVzXFxcIjpmYWxzZSxcXFwidGFyZ2V0c1xcXCI6e1xcXCJicm93c2Vyc1xcXCI6W1xcXCI+IDIlXFxcIl0sXFxcInVnbGlmeVxcXCI6dHJ1ZX19XV19IS4uLy4uLy4uLy4uL25vZGVfbW9kdWxlcy92dWUtbG9hZGVyL2xpYi9zZWxlY3Rvcj90eXBlPXNjcmlwdCZpbmRleD0wIS4vc2VsZWN0Mi52dWVcIiksXG4gIC8qIHRlbXBsYXRlICovXG4gIHJlcXVpcmUoXCIhIS4uLy4uLy4uLy4uL25vZGVfbW9kdWxlcy92dWUtbG9hZGVyL2xpYi90ZW1wbGF0ZS1jb21waWxlci9pbmRleD97XFxcImlkXFxcIjpcXFwiZGF0YS12LWZmNTY0YTg2XFxcIixcXFwiaGFzU2NvcGVkXFxcIjp0cnVlfSEuLi8uLi8uLi8uLi9ub2RlX21vZHVsZXMvdnVlLWxvYWRlci9saWIvc2VsZWN0b3I/dHlwZT10ZW1wbGF0ZSZpbmRleD0wIS4vc2VsZWN0Mi52dWVcIiksXG4gIC8qIHN0eWxlcyAqL1xuICBpbmplY3RTdHlsZSxcbiAgLyogc2NvcGVJZCAqL1xuICBcImRhdGEtdi1mZjU2NGE4NlwiLFxuICAvKiBtb2R1bGVJZGVudGlmaWVyIChzZXJ2ZXIgb25seSkgKi9cbiAgbnVsbFxuKVxuQ29tcG9uZW50Lm9wdGlvbnMuX19maWxlID0gXCIvaG9tZS9oeWRyb2dlbi93b3JrL3NuaXBlLWl0L3Jlc291cmNlcy9hc3NldHMvanMvY29tcG9uZW50cy9zZWxlY3QyLnZ1ZVwiXG5pZiAoQ29tcG9uZW50LmVzTW9kdWxlICYmIE9iamVjdC5rZXlzKENvbXBvbmVudC5lc01vZHVsZSkuc29tZShmdW5jdGlvbiAoa2V5KSB7cmV0dXJuIGtleSAhPT0gXCJkZWZhdWx0XCIgJiYga2V5LnN1YnN0cigwLCAyKSAhPT0gXCJfX1wifSkpIHtjb25zb2xlLmVycm9yKFwibmFtZWQgZXhwb3J0cyBhcmUgbm90IHN1cHBvcnRlZCBpbiAqLnZ1ZSBmaWxlcy5cIil9XG5pZiAoQ29tcG9uZW50Lm9wdGlvbnMuZnVuY3Rpb25hbCkge2NvbnNvbGUuZXJyb3IoXCJbdnVlLWxvYWRlcl0gc2VsZWN0Mi52dWU6IGZ1bmN0aW9uYWwgY29tcG9uZW50cyBhcmUgbm90IHN1cHBvcnRlZCB3aXRoIHRlbXBsYXRlcywgdGhleSBzaG91bGQgdXNlIHJlbmRlciBmdW5jdGlvbnMuXCIpfVxuXG4vKiBob3QgcmVsb2FkICovXG5pZiAobW9kdWxlLmhvdCkgeyhmdW5jdGlvbiAoKSB7XG4gIHZhciBob3RBUEkgPSByZXF1aXJlKFwidnVlLWhvdC1yZWxvYWQtYXBpXCIpXG4gIGhvdEFQSS5pbnN0YWxsKHJlcXVpcmUoXCJ2dWVcIiksIGZhbHNlKVxuICBpZiAoIWhvdEFQSS5jb21wYXRpYmxlKSByZXR1cm5cbiAgbW9kdWxlLmhvdC5hY2NlcHQoKVxuICBpZiAoIW1vZHVsZS5ob3QuZGF0YSkge1xuICAgIGhvdEFQSS5jcmVhdGVSZWNvcmQoXCJkYXRhLXYtZmY1NjRhODZcIiwgQ29tcG9uZW50Lm9wdGlvbnMpXG4gIH0gZWxzZSB7XG4gICAgaG90QVBJLnJlbG9hZChcImRhdGEtdi1mZjU2NGE4NlwiLCBDb21wb25lbnQub3B0aW9ucylcbiAgfVxuICBtb2R1bGUuaG90LmRpc3Bvc2UoZnVuY3Rpb24gKGRhdGEpIHtcbiAgICBkaXNwb3NlZCA9IHRydWVcbiAgfSlcbn0pKCl9XG5cbm1vZHVsZS5leHBvcnRzID0gQ29tcG9uZW50LmV4cG9ydHNcblxuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIC4vcmVzb3VyY2VzL2Fzc2V0cy9qcy9jb21wb25lbnRzL3NlbGVjdDIudnVlXG4vLyBtb2R1bGUgaWQgPSA1MlxuLy8gbW9kdWxlIGNodW5rcyA9IDAiLCIvLyBzdHlsZS1sb2FkZXI6IEFkZHMgc29tZSBjc3MgdG8gdGhlIERPTSBieSBhZGRpbmcgYSA8c3R5bGU+IHRhZ1xuXG4vLyBsb2FkIHRoZSBzdHlsZXNcbnZhciBjb250ZW50ID0gcmVxdWlyZShcIiEhLi4vLi4vLi4vLi4vbm9kZV9tb2R1bGVzL2Nzcy1sb2FkZXIvaW5kZXguanM/c291cmNlTWFwIS4uLy4uLy4uLy4uL25vZGVfbW9kdWxlcy92dWUtbG9hZGVyL2xpYi9zdHlsZS1jb21waWxlci9pbmRleC5qcz97XFxcInZ1ZVxcXCI6dHJ1ZSxcXFwiaWRcXFwiOlxcXCJkYXRhLXYtZmY1NjRhODZcXFwiLFxcXCJzY29wZWRcXFwiOnRydWUsXFxcImhhc0lubGluZUNvbmZpZ1xcXCI6dHJ1ZX0hLi4vLi4vLi4vLi4vbm9kZV9tb2R1bGVzL3Z1ZS1sb2FkZXIvbGliL3NlbGVjdG9yLmpzP3R5cGU9c3R5bGVzJmluZGV4PTAhLi9zZWxlY3QyLnZ1ZVwiKTtcbmlmKHR5cGVvZiBjb250ZW50ID09PSAnc3RyaW5nJykgY29udGVudCA9IFtbbW9kdWxlLmlkLCBjb250ZW50LCAnJ11dO1xuaWYoY29udGVudC5sb2NhbHMpIG1vZHVsZS5leHBvcnRzID0gY29udGVudC5sb2NhbHM7XG4vLyBhZGQgdGhlIHN0eWxlcyB0byB0aGUgRE9NXG52YXIgdXBkYXRlID0gcmVxdWlyZShcIiEuLi8uLi8uLi8uLi9ub2RlX21vZHVsZXMvdnVlLXN0eWxlLWxvYWRlci9saWIvYWRkU3R5bGVzQ2xpZW50LmpzXCIpKFwiNDhmNGQxNTNcIiwgY29udGVudCwgZmFsc2UpO1xuLy8gSG90IE1vZHVsZSBSZXBsYWNlbWVudFxuaWYobW9kdWxlLmhvdCkge1xuIC8vIFdoZW4gdGhlIHN0eWxlcyBjaGFuZ2UsIHVwZGF0ZSB0aGUgPHN0eWxlPiB0YWdzXG4gaWYoIWNvbnRlbnQubG9jYWxzKSB7XG4gICBtb2R1bGUuaG90LmFjY2VwdChcIiEhLi4vLi4vLi4vLi4vbm9kZV9tb2R1bGVzL2Nzcy1sb2FkZXIvaW5kZXguanM/c291cmNlTWFwIS4uLy4uLy4uLy4uL25vZGVfbW9kdWxlcy92dWUtbG9hZGVyL2xpYi9zdHlsZS1jb21waWxlci9pbmRleC5qcz97XFxcInZ1ZVxcXCI6dHJ1ZSxcXFwiaWRcXFwiOlxcXCJkYXRhLXYtZmY1NjRhODZcXFwiLFxcXCJzY29wZWRcXFwiOnRydWUsXFxcImhhc0lubGluZUNvbmZpZ1xcXCI6dHJ1ZX0hLi4vLi4vLi4vLi4vbm9kZV9tb2R1bGVzL3Z1ZS1sb2FkZXIvbGliL3NlbGVjdG9yLmpzP3R5cGU9c3R5bGVzJmluZGV4PTAhLi9zZWxlY3QyLnZ1ZVwiLCBmdW5jdGlvbigpIHtcbiAgICAgdmFyIG5ld0NvbnRlbnQgPSByZXF1aXJlKFwiISEuLi8uLi8uLi8uLi9ub2RlX21vZHVsZXMvY3NzLWxvYWRlci9pbmRleC5qcz9zb3VyY2VNYXAhLi4vLi4vLi4vLi4vbm9kZV9tb2R1bGVzL3Z1ZS1sb2FkZXIvbGliL3N0eWxlLWNvbXBpbGVyL2luZGV4LmpzP3tcXFwidnVlXFxcIjp0cnVlLFxcXCJpZFxcXCI6XFxcImRhdGEtdi1mZjU2NGE4NlxcXCIsXFxcInNjb3BlZFxcXCI6dHJ1ZSxcXFwiaGFzSW5saW5lQ29uZmlnXFxcIjp0cnVlfSEuLi8uLi8uLi8uLi9ub2RlX21vZHVsZXMvdnVlLWxvYWRlci9saWIvc2VsZWN0b3IuanM/dHlwZT1zdHlsZXMmaW5kZXg9MCEuL3NlbGVjdDIudnVlXCIpO1xuICAgICBpZih0eXBlb2YgbmV3Q29udGVudCA9PT0gJ3N0cmluZycpIG5ld0NvbnRlbnQgPSBbW21vZHVsZS5pZCwgbmV3Q29udGVudCwgJyddXTtcbiAgICAgdXBkYXRlKG5ld0NvbnRlbnQpO1xuICAgfSk7XG4gfVxuIC8vIFdoZW4gdGhlIG1vZHVsZSBpcyBkaXNwb3NlZCwgcmVtb3ZlIHRoZSA8c3R5bGU+IHRhZ3NcbiBtb2R1bGUuaG90LmRpc3Bvc2UoZnVuY3Rpb24oKSB7IHVwZGF0ZSgpOyB9KTtcbn1cblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyAuL25vZGVfbW9kdWxlcy92dWUtc3R5bGUtbG9hZGVyIS4vbm9kZV9tb2R1bGVzL2Nzcy1sb2FkZXI/c291cmNlTWFwIS4vbm9kZV9tb2R1bGVzL3Z1ZS1sb2FkZXIvbGliL3N0eWxlLWNvbXBpbGVyP3tcInZ1ZVwiOnRydWUsXCJpZFwiOlwiZGF0YS12LWZmNTY0YTg2XCIsXCJzY29wZWRcIjp0cnVlLFwiaGFzSW5saW5lQ29uZmlnXCI6dHJ1ZX0hLi9ub2RlX21vZHVsZXMvdnVlLWxvYWRlci9saWIvc2VsZWN0b3IuanM/dHlwZT1zdHlsZXMmaW5kZXg9MCEuL3Jlc291cmNlcy9hc3NldHMvanMvY29tcG9uZW50cy9zZWxlY3QyLnZ1ZVxuLy8gbW9kdWxlIGlkID0gNTNcbi8vIG1vZHVsZSBjaHVua3MgPSAwIiwiZXhwb3J0cyA9IG1vZHVsZS5leHBvcnRzID0gcmVxdWlyZShcIi4uLy4uLy4uLy4uL25vZGVfbW9kdWxlcy9jc3MtbG9hZGVyL2xpYi9jc3MtYmFzZS5qc1wiKSh0cnVlKTtcbi8vIGltcG9ydHNcblxuXG4vLyBtb2R1bGVcbmV4cG9ydHMucHVzaChbbW9kdWxlLmlkLCBcIlxcbi5zZWxlY3QyLWRyb3Bkb3duW2RhdGEtdi1mZjU2NGE4Nl0ge1xcbiAgICB6LWluZGV4Ojk5OTk7XFxufVxcblwiLCBcIlwiLCB7XCJ2ZXJzaW9uXCI6MyxcInNvdXJjZXNcIjpbXCIvaG9tZS9oeWRyb2dlbi93b3JrL3NuaXBlLWl0L3Jlc291cmNlcy9hc3NldHMvanMvY29tcG9uZW50cy9zZWxlY3QyLnZ1ZT81ZTE0YzQyYlwiXSxcIm5hbWVzXCI6W10sXCJtYXBwaW5nc1wiOlwiO0FBRUE7SUFDQSxhQUFBO0NBQ0FcIixcImZpbGVcIjpcInNlbGVjdDIudnVlXCIsXCJzb3VyY2VzQ29udGVudFwiOltcIlxcbjxzdHlsZSBzY29wZWQ+XFxuICAgIC5zZWxlY3QyLWRyb3Bkb3duIHtcXG4gICAgICAgIHotaW5kZXg6OTk5OTtcXG4gICAgfVxcbjwvc3R5bGU+XFxuXFxuPHRlbXBsYXRlPlxcbiAgICAgICAgPHNlbGVjdCBzdHlsZT1cXFwid2lkdGg6MTAwJVxcXCI+XFxuICAgICAgICAgICAgPHNsb3Q+PC9zbG90PlxcbiAgICAgICAgPC9zZWxlY3Q+XFxuPC90ZW1wbGF0ZT5cXG5cXG48c2NyaXB0PlxcbiAgICByZXF1aXJlKCdzZWxlY3QyJyk7XFxuICAgIGV4cG9ydCBkZWZhdWx0IHtcXG4gICAgICAgIC8qXFxuICAgICAgICAgKiBUaGUgY29tcG9uZW50J3MgZGF0YS5cXG4gICAgICAgICAqL1xcbiAgICAgICAgcHJvcHM6IFsnb3B0aW9ucycsICd2YWx1ZSddLFxcblxcbiAgICAgICAgbW91bnRlZCgpIHtcXG4gICAgICAgICAgICB2YXIgdm0gPSB0aGlzO1xcbiAgICAgICAgICAgICQodGhpcy4kZWwpXFxuICAgICAgICAgICAgICAgIC5zZWxlY3QyKHtcXG4gICAgICAgICAgICAgICAgICAgIGRhdGE6IHRoaXMub3B0aW9uc1xcbiAgICAgICAgICAgICAgICB9KVxcbiAgICAgICAgICAgICAgICAub24oJ2NoYW5nZScsIGZ1bmN0aW9uKCkgeyB2bS4kZW1pdCgnaW5wdXQnLCB0aGlzLnZhbHVlKSB9IClcXG4gICAgICAgICAgICAgICAgLnZhbCh0aGlzLnZhbHVlKS50cmlnZ2VyKCdjaGFuZ2UnKTtcXG4gICAgICAgIH0sXFxuICAgICAgICB3YXRjaDoge1xcbiAgICAgICAgICAgIHZhbHVlOiBmdW5jdGlvbiAodmFsdWUpIHtcXG4gICAgICAgICAgICAgICAgJCh0aGlzLiRlbCkudmFsKHZhbHVlKVxcbiAgICAgICAgICAgIH0sXFxuICAgICAgICAgICAgb3B0aW9uczogZnVuY3Rpb24gKG9wdGlvbnMpIHtcXG4gICAgICAgICAgICAgICAgdmFyIHZtID0gdGhpcztcXG4gICAgICAgICAgICAgICAgJCh0aGlzLiRlbCkuc2VsZWN0MignZGVzdHJveScpLmVtcHR5KCkuc2VsZWN0Mih7ZGF0YTogb3B0aW9uc30pXFxuICAgICAgICAgICAgICAgIC5vbignY2hhbmdlJywgZnVuY3Rpb24oKSB7IHZtLiRlbWl0KCdpbnB1dCcsIHRoaXMudmFsdWUpIH0gKVxcbiAgICAgICAgICAgICAgICAudmFsKHRoaXMudmFsdWUpLnRyaWdnZXIoJ2NoYW5nZScpO1xcbiAgICAgICAgICAgIH0sXFxuICAgICAgICAgICAgZGVzdHJveWVkOiBmdW5jdGlvbigpIHtcXG4gICAgICAgICAgICAgICAgJCh0aGlzLiRlbCkub2ZmKCkuc2VsZWN0MignZGVzdHJveScpXFxuICAgICAgICAgICAgfVxcbiAgICAgICAgfVxcbiAgICB9XFxuXFxuPC9zY3JpcHQ+XFxuXCJdLFwic291cmNlUm9vdFwiOlwiXCJ9XSk7XG5cbi8vIGV4cG9ydHNcblxuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIC4vbm9kZV9tb2R1bGVzL2Nzcy1sb2FkZXI/c291cmNlTWFwIS4vbm9kZV9tb2R1bGVzL3Z1ZS1sb2FkZXIvbGliL3N0eWxlLWNvbXBpbGVyP3tcInZ1ZVwiOnRydWUsXCJpZFwiOlwiZGF0YS12LWZmNTY0YTg2XCIsXCJzY29wZWRcIjp0cnVlLFwiaGFzSW5saW5lQ29uZmlnXCI6dHJ1ZX0hLi9ub2RlX21vZHVsZXMvdnVlLWxvYWRlci9saWIvc2VsZWN0b3IuanM/dHlwZT1zdHlsZXMmaW5kZXg9MCEuL3Jlc291cmNlcy9hc3NldHMvanMvY29tcG9uZW50cy9zZWxlY3QyLnZ1ZVxuLy8gbW9kdWxlIGlkID0gNTRcbi8vIG1vZHVsZSBjaHVua3MgPSAwIiwiXG48c3R5bGUgc2NvcGVkPlxuICAgIC5zZWxlY3QyLWRyb3Bkb3duIHtcbiAgICAgICAgei1pbmRleDo5OTk5O1xuICAgIH1cbjwvc3R5bGU+XG5cbjx0ZW1wbGF0ZT5cbiAgICAgICAgPHNlbGVjdCBzdHlsZT1cIndpZHRoOjEwMCVcIj5cbiAgICAgICAgICAgIDxzbG90Pjwvc2xvdD5cbiAgICAgICAgPC9zZWxlY3Q+XG48L3RlbXBsYXRlPlxuXG48c2NyaXB0PlxuICAgIHJlcXVpcmUoJ3NlbGVjdDInKTtcbiAgICBleHBvcnQgZGVmYXVsdCB7XG4gICAgICAgIC8qXG4gICAgICAgICAqIFRoZSBjb21wb25lbnQncyBkYXRhLlxuICAgICAgICAgKi9cbiAgICAgICAgcHJvcHM6IFsnb3B0aW9ucycsICd2YWx1ZSddLFxuXG4gICAgICAgIG1vdW50ZWQoKSB7XG4gICAgICAgICAgICB2YXIgdm0gPSB0aGlzO1xuICAgICAgICAgICAgJCh0aGlzLiRlbClcbiAgICAgICAgICAgICAgICAuc2VsZWN0Mih7XG4gICAgICAgICAgICAgICAgICAgIGRhdGE6IHRoaXMub3B0aW9uc1xuICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgICAgLm9uKCdjaGFuZ2UnLCBmdW5jdGlvbigpIHsgdm0uJGVtaXQoJ2lucHV0JywgdGhpcy52YWx1ZSkgfSApXG4gICAgICAgICAgICAgICAgLnZhbCh0aGlzLnZhbHVlKS50cmlnZ2VyKCdjaGFuZ2UnKTtcbiAgICAgICAgfSxcbiAgICAgICAgd2F0Y2g6IHtcbiAgICAgICAgICAgIHZhbHVlOiBmdW5jdGlvbiAodmFsdWUpIHtcbiAgICAgICAgICAgICAgICAkKHRoaXMuJGVsKS52YWwodmFsdWUpXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgb3B0aW9uczogZnVuY3Rpb24gKG9wdGlvbnMpIHtcbiAgICAgICAgICAgICAgICB2YXIgdm0gPSB0aGlzO1xuICAgICAgICAgICAgICAgICQodGhpcy4kZWwpLnNlbGVjdDIoJ2Rlc3Ryb3knKS5lbXB0eSgpLnNlbGVjdDIoe2RhdGE6IG9wdGlvbnN9KVxuICAgICAgICAgICAgICAgIC5vbignY2hhbmdlJywgZnVuY3Rpb24oKSB7IHZtLiRlbWl0KCdpbnB1dCcsIHRoaXMudmFsdWUpIH0gKVxuICAgICAgICAgICAgICAgIC52YWwodGhpcy52YWx1ZSkudHJpZ2dlcignY2hhbmdlJyk7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgZGVzdHJveWVkOiBmdW5jdGlvbigpIHtcbiAgICAgICAgICAgICAgICAkKHRoaXMuJGVsKS5vZmYoKS5zZWxlY3QyKCdkZXN0cm95JylcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuPC9zY3JpcHQ+XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gc2VsZWN0Mi52dWU/NWUxNGM0MmIiLCIvKiFcclxuICogU2VsZWN0MiA0LjAuM1xyXG4gKiBodHRwczovL3NlbGVjdDIuZ2l0aHViLmlvXHJcbiAqXHJcbiAqIFJlbGVhc2VkIHVuZGVyIHRoZSBNSVQgbGljZW5zZVxyXG4gKiBodHRwczovL2dpdGh1Yi5jb20vc2VsZWN0Mi9zZWxlY3QyL2Jsb2IvbWFzdGVyL0xJQ0VOU0UubWRcclxuICovXHJcbihmdW5jdGlvbiAoZmFjdG9yeSkge1xyXG4gIGlmICh0eXBlb2YgZGVmaW5lID09PSAnZnVuY3Rpb24nICYmIGRlZmluZS5hbWQpIHtcclxuICAgIC8vIEFNRC4gUmVnaXN0ZXIgYXMgYW4gYW5vbnltb3VzIG1vZHVsZS5cclxuICAgIGRlZmluZShbJ2pxdWVyeSddLCBmYWN0b3J5KTtcclxuICB9IGVsc2UgaWYgKHR5cGVvZiBleHBvcnRzID09PSAnb2JqZWN0Jykge1xyXG4gICAgLy8gTm9kZS9Db21tb25KU1xyXG4gICAgZmFjdG9yeShyZXF1aXJlKCdqcXVlcnknKSk7XHJcbiAgfSBlbHNlIHtcclxuICAgIC8vIEJyb3dzZXIgZ2xvYmFsc1xyXG4gICAgZmFjdG9yeShqUXVlcnkpO1xyXG4gIH1cclxufShmdW5jdGlvbiAoalF1ZXJ5KSB7XHJcbiAgLy8gVGhpcyBpcyBuZWVkZWQgc28gd2UgY2FuIGNhdGNoIHRoZSBBTUQgbG9hZGVyIGNvbmZpZ3VyYXRpb24gYW5kIHVzZSBpdFxyXG4gIC8vIFRoZSBpbm5lciBmaWxlIHNob3VsZCBiZSB3cmFwcGVkIChieSBgYmFubmVyLnN0YXJ0LmpzYCkgaW4gYSBmdW5jdGlvbiB0aGF0XHJcbiAgLy8gcmV0dXJucyB0aGUgQU1EIGxvYWRlciByZWZlcmVuY2VzLlxyXG4gIHZhciBTMiA9XHJcbihmdW5jdGlvbiAoKSB7XHJcbiAgLy8gUmVzdG9yZSB0aGUgU2VsZWN0MiBBTUQgbG9hZGVyIHNvIGl0IGNhbiBiZSB1c2VkXHJcbiAgLy8gTmVlZGVkIG1vc3RseSBpbiB0aGUgbGFuZ3VhZ2UgZmlsZXMsIHdoZXJlIHRoZSBsb2FkZXIgaXMgbm90IGluc2VydGVkXHJcbiAgaWYgKGpRdWVyeSAmJiBqUXVlcnkuZm4gJiYgalF1ZXJ5LmZuLnNlbGVjdDIgJiYgalF1ZXJ5LmZuLnNlbGVjdDIuYW1kKSB7XHJcbiAgICB2YXIgUzIgPSBqUXVlcnkuZm4uc2VsZWN0Mi5hbWQ7XHJcbiAgfVxyXG52YXIgUzI7KGZ1bmN0aW9uICgpIHsgaWYgKCFTMiB8fCAhUzIucmVxdWlyZWpzKSB7XG5pZiAoIVMyKSB7IFMyID0ge307IH0gZWxzZSB7IHJlcXVpcmUgPSBTMjsgfVxuLyoqXG4gKiBAbGljZW5zZSBhbG1vbmQgMC4zLjEgQ29weXJpZ2h0IChjKSAyMDExLTIwMTQsIFRoZSBEb2pvIEZvdW5kYXRpb24gQWxsIFJpZ2h0cyBSZXNlcnZlZC5cbiAqIEF2YWlsYWJsZSB2aWEgdGhlIE1JVCBvciBuZXcgQlNEIGxpY2Vuc2UuXG4gKiBzZWU6IGh0dHA6Ly9naXRodWIuY29tL2pyYnVya2UvYWxtb25kIGZvciBkZXRhaWxzXG4gKi9cbi8vR29pbmcgc2xvcHB5IHRvIGF2b2lkICd1c2Ugc3RyaWN0JyBzdHJpbmcgY29zdCwgYnV0IHN0cmljdCBwcmFjdGljZXMgc2hvdWxkXG4vL2JlIGZvbGxvd2VkLlxuLypqc2xpbnQgc2xvcHB5OiB0cnVlICovXG4vKmdsb2JhbCBzZXRUaW1lb3V0OiBmYWxzZSAqL1xuXG52YXIgcmVxdWlyZWpzLCByZXF1aXJlLCBkZWZpbmU7XG4oZnVuY3Rpb24gKHVuZGVmKSB7XG4gICAgdmFyIG1haW4sIHJlcSwgbWFrZU1hcCwgaGFuZGxlcnMsXG4gICAgICAgIGRlZmluZWQgPSB7fSxcbiAgICAgICAgd2FpdGluZyA9IHt9LFxuICAgICAgICBjb25maWcgPSB7fSxcbiAgICAgICAgZGVmaW5pbmcgPSB7fSxcbiAgICAgICAgaGFzT3duID0gT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eSxcbiAgICAgICAgYXBzID0gW10uc2xpY2UsXG4gICAgICAgIGpzU3VmZml4UmVnRXhwID0gL1xcLmpzJC87XG5cbiAgICBmdW5jdGlvbiBoYXNQcm9wKG9iaiwgcHJvcCkge1xuICAgICAgICByZXR1cm4gaGFzT3duLmNhbGwob2JqLCBwcm9wKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBHaXZlbiBhIHJlbGF0aXZlIG1vZHVsZSBuYW1lLCBsaWtlIC4vc29tZXRoaW5nLCBub3JtYWxpemUgaXQgdG9cbiAgICAgKiBhIHJlYWwgbmFtZSB0aGF0IGNhbiBiZSBtYXBwZWQgdG8gYSBwYXRoLlxuICAgICAqIEBwYXJhbSB7U3RyaW5nfSBuYW1lIHRoZSByZWxhdGl2ZSBuYW1lXG4gICAgICogQHBhcmFtIHtTdHJpbmd9IGJhc2VOYW1lIGEgcmVhbCBuYW1lIHRoYXQgdGhlIG5hbWUgYXJnIGlzIHJlbGF0aXZlXG4gICAgICogdG8uXG4gICAgICogQHJldHVybnMge1N0cmluZ30gbm9ybWFsaXplZCBuYW1lXG4gICAgICovXG4gICAgZnVuY3Rpb24gbm9ybWFsaXplKG5hbWUsIGJhc2VOYW1lKSB7XG4gICAgICAgIHZhciBuYW1lUGFydHMsIG5hbWVTZWdtZW50LCBtYXBWYWx1ZSwgZm91bmRNYXAsIGxhc3RJbmRleCxcbiAgICAgICAgICAgIGZvdW5kSSwgZm91bmRTdGFyTWFwLCBzdGFySSwgaSwgaiwgcGFydCxcbiAgICAgICAgICAgIGJhc2VQYXJ0cyA9IGJhc2VOYW1lICYmIGJhc2VOYW1lLnNwbGl0KFwiL1wiKSxcbiAgICAgICAgICAgIG1hcCA9IGNvbmZpZy5tYXAsXG4gICAgICAgICAgICBzdGFyTWFwID0gKG1hcCAmJiBtYXBbJyonXSkgfHwge307XG5cbiAgICAgICAgLy9BZGp1c3QgYW55IHJlbGF0aXZlIHBhdGhzLlxuICAgICAgICBpZiAobmFtZSAmJiBuYW1lLmNoYXJBdCgwKSA9PT0gXCIuXCIpIHtcbiAgICAgICAgICAgIC8vSWYgaGF2ZSBhIGJhc2UgbmFtZSwgdHJ5IHRvIG5vcm1hbGl6ZSBhZ2FpbnN0IGl0LFxuICAgICAgICAgICAgLy9vdGhlcndpc2UsIGFzc3VtZSBpdCBpcyBhIHRvcC1sZXZlbCByZXF1aXJlIHRoYXQgd2lsbFxuICAgICAgICAgICAgLy9iZSByZWxhdGl2ZSB0byBiYXNlVXJsIGluIHRoZSBlbmQuXG4gICAgICAgICAgICBpZiAoYmFzZU5hbWUpIHtcbiAgICAgICAgICAgICAgICBuYW1lID0gbmFtZS5zcGxpdCgnLycpO1xuICAgICAgICAgICAgICAgIGxhc3RJbmRleCA9IG5hbWUubGVuZ3RoIC0gMTtcblxuICAgICAgICAgICAgICAgIC8vIE5vZGUgLmpzIGFsbG93YW5jZTpcbiAgICAgICAgICAgICAgICBpZiAoY29uZmlnLm5vZGVJZENvbXBhdCAmJiBqc1N1ZmZpeFJlZ0V4cC50ZXN0KG5hbWVbbGFzdEluZGV4XSkpIHtcbiAgICAgICAgICAgICAgICAgICAgbmFtZVtsYXN0SW5kZXhdID0gbmFtZVtsYXN0SW5kZXhdLnJlcGxhY2UoanNTdWZmaXhSZWdFeHAsICcnKTtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAvL0xvcCBvZmYgdGhlIGxhc3QgcGFydCBvZiBiYXNlUGFydHMsIHNvIHRoYXQgLiBtYXRjaGVzIHRoZVxuICAgICAgICAgICAgICAgIC8vXCJkaXJlY3RvcnlcIiBhbmQgbm90IG5hbWUgb2YgdGhlIGJhc2VOYW1lJ3MgbW9kdWxlLiBGb3IgaW5zdGFuY2UsXG4gICAgICAgICAgICAgICAgLy9iYXNlTmFtZSBvZiBcIm9uZS90d28vdGhyZWVcIiwgbWFwcyB0byBcIm9uZS90d28vdGhyZWUuanNcIiwgYnV0IHdlXG4gICAgICAgICAgICAgICAgLy93YW50IHRoZSBkaXJlY3RvcnksIFwib25lL3R3b1wiIGZvciB0aGlzIG5vcm1hbGl6YXRpb24uXG4gICAgICAgICAgICAgICAgbmFtZSA9IGJhc2VQYXJ0cy5zbGljZSgwLCBiYXNlUGFydHMubGVuZ3RoIC0gMSkuY29uY2F0KG5hbWUpO1xuXG4gICAgICAgICAgICAgICAgLy9zdGFydCB0cmltRG90c1xuICAgICAgICAgICAgICAgIGZvciAoaSA9IDA7IGkgPCBuYW1lLmxlbmd0aDsgaSArPSAxKSB7XG4gICAgICAgICAgICAgICAgICAgIHBhcnQgPSBuYW1lW2ldO1xuICAgICAgICAgICAgICAgICAgICBpZiAocGFydCA9PT0gXCIuXCIpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIG5hbWUuc3BsaWNlKGksIDEpO1xuICAgICAgICAgICAgICAgICAgICAgICAgaSAtPSAxO1xuICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKHBhcnQgPT09IFwiLi5cIikge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGkgPT09IDEgJiYgKG5hbWVbMl0gPT09ICcuLicgfHwgbmFtZVswXSA9PT0gJy4uJykpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL0VuZCBvZiB0aGUgbGluZS4gS2VlcCBhdCBsZWFzdCBvbmUgbm9uLWRvdFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vcGF0aCBzZWdtZW50IGF0IHRoZSBmcm9udCBzbyBpdCBjYW4gYmUgbWFwcGVkXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy9jb3JyZWN0bHkgdG8gZGlzay4gT3RoZXJ3aXNlLCB0aGVyZSBpcyBsaWtlbHlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL25vIHBhdGggbWFwcGluZyBmb3IgYSBwYXRoIHN0YXJ0aW5nIHdpdGggJy4uJy5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL1RoaXMgY2FuIHN0aWxsIGZhaWwsIGJ1dCBjYXRjaGVzIHRoZSBtb3N0IHJlYXNvbmFibGVcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL3VzZXMgb2YgLi5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoaSA+IDApIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBuYW1lLnNwbGljZShpIC0gMSwgMik7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaSAtPSAyO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIC8vZW5kIHRyaW1Eb3RzXG5cbiAgICAgICAgICAgICAgICBuYW1lID0gbmFtZS5qb2luKFwiL1wiKTtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAobmFtZS5pbmRleE9mKCcuLycpID09PSAwKSB7XG4gICAgICAgICAgICAgICAgLy8gTm8gYmFzZU5hbWUsIHNvIHRoaXMgaXMgSUQgaXMgcmVzb2x2ZWQgcmVsYXRpdmVcbiAgICAgICAgICAgICAgICAvLyB0byBiYXNlVXJsLCBwdWxsIG9mZiB0aGUgbGVhZGluZyBkb3QuXG4gICAgICAgICAgICAgICAgbmFtZSA9IG5hbWUuc3Vic3RyaW5nKDIpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgLy9BcHBseSBtYXAgY29uZmlnIGlmIGF2YWlsYWJsZS5cbiAgICAgICAgaWYgKChiYXNlUGFydHMgfHwgc3Rhck1hcCkgJiYgbWFwKSB7XG4gICAgICAgICAgICBuYW1lUGFydHMgPSBuYW1lLnNwbGl0KCcvJyk7XG5cbiAgICAgICAgICAgIGZvciAoaSA9IG5hbWVQYXJ0cy5sZW5ndGg7IGkgPiAwOyBpIC09IDEpIHtcbiAgICAgICAgICAgICAgICBuYW1lU2VnbWVudCA9IG5hbWVQYXJ0cy5zbGljZSgwLCBpKS5qb2luKFwiL1wiKTtcblxuICAgICAgICAgICAgICAgIGlmIChiYXNlUGFydHMpIHtcbiAgICAgICAgICAgICAgICAgICAgLy9GaW5kIHRoZSBsb25nZXN0IGJhc2VOYW1lIHNlZ21lbnQgbWF0Y2ggaW4gdGhlIGNvbmZpZy5cbiAgICAgICAgICAgICAgICAgICAgLy9TbywgZG8gam9pbnMgb24gdGhlIGJpZ2dlc3QgdG8gc21hbGxlc3QgbGVuZ3RocyBvZiBiYXNlUGFydHMuXG4gICAgICAgICAgICAgICAgICAgIGZvciAoaiA9IGJhc2VQYXJ0cy5sZW5ndGg7IGogPiAwOyBqIC09IDEpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIG1hcFZhbHVlID0gbWFwW2Jhc2VQYXJ0cy5zbGljZSgwLCBqKS5qb2luKCcvJyldO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAvL2Jhc2VOYW1lIHNlZ21lbnQgaGFzICBjb25maWcsIGZpbmQgaWYgaXQgaGFzIG9uZSBmb3JcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vdGhpcyBuYW1lLlxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG1hcFZhbHVlKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbWFwVmFsdWUgPSBtYXBWYWx1ZVtuYW1lU2VnbWVudF07XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG1hcFZhbHVlKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vTWF0Y2gsIHVwZGF0ZSBuYW1lIHRvIHRoZSBuZXcgdmFsdWUuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvdW5kTWFwID0gbWFwVmFsdWU7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvdW5kSSA9IGk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIGlmIChmb3VuZE1hcCkge1xuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAvL0NoZWNrIGZvciBhIHN0YXIgbWFwIG1hdGNoLCBidXQganVzdCBob2xkIG9uIHRvIGl0LFxuICAgICAgICAgICAgICAgIC8vaWYgdGhlcmUgaXMgYSBzaG9ydGVyIHNlZ21lbnQgbWF0Y2ggbGF0ZXIgaW4gYSBtYXRjaGluZ1xuICAgICAgICAgICAgICAgIC8vY29uZmlnLCB0aGVuIGZhdm9yIG92ZXIgdGhpcyBzdGFyIG1hcC5cbiAgICAgICAgICAgICAgICBpZiAoIWZvdW5kU3Rhck1hcCAmJiBzdGFyTWFwICYmIHN0YXJNYXBbbmFtZVNlZ21lbnRdKSB7XG4gICAgICAgICAgICAgICAgICAgIGZvdW5kU3Rhck1hcCA9IHN0YXJNYXBbbmFtZVNlZ21lbnRdO1xuICAgICAgICAgICAgICAgICAgICBzdGFySSA9IGk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAoIWZvdW5kTWFwICYmIGZvdW5kU3Rhck1hcCkge1xuICAgICAgICAgICAgICAgIGZvdW5kTWFwID0gZm91bmRTdGFyTWFwO1xuICAgICAgICAgICAgICAgIGZvdW5kSSA9IHN0YXJJO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAoZm91bmRNYXApIHtcbiAgICAgICAgICAgICAgICBuYW1lUGFydHMuc3BsaWNlKDAsIGZvdW5kSSwgZm91bmRNYXApO1xuICAgICAgICAgICAgICAgIG5hbWUgPSBuYW1lUGFydHMuam9pbignLycpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIG5hbWU7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gbWFrZVJlcXVpcmUocmVsTmFtZSwgZm9yY2VTeW5jKSB7XG4gICAgICAgIHJldHVybiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAvL0EgdmVyc2lvbiBvZiBhIHJlcXVpcmUgZnVuY3Rpb24gdGhhdCBwYXNzZXMgYSBtb2R1bGVOYW1lXG4gICAgICAgICAgICAvL3ZhbHVlIGZvciBpdGVtcyB0aGF0IG1heSBuZWVkIHRvXG4gICAgICAgICAgICAvL2xvb2sgdXAgcGF0aHMgcmVsYXRpdmUgdG8gdGhlIG1vZHVsZU5hbWVcbiAgICAgICAgICAgIHZhciBhcmdzID0gYXBzLmNhbGwoYXJndW1lbnRzLCAwKTtcblxuICAgICAgICAgICAgLy9JZiBmaXJzdCBhcmcgaXMgbm90IHJlcXVpcmUoJ3N0cmluZycpLCBhbmQgdGhlcmUgaXMgb25seVxuICAgICAgICAgICAgLy9vbmUgYXJnLCBpdCBpcyB0aGUgYXJyYXkgZm9ybSB3aXRob3V0IGEgY2FsbGJhY2suIEluc2VydFxuICAgICAgICAgICAgLy9hIG51bGwgc28gdGhhdCB0aGUgZm9sbG93aW5nIGNvbmNhdCBpcyBjb3JyZWN0LlxuICAgICAgICAgICAgaWYgKHR5cGVvZiBhcmdzWzBdICE9PSAnc3RyaW5nJyAmJiBhcmdzLmxlbmd0aCA9PT0gMSkge1xuICAgICAgICAgICAgICAgIGFyZ3MucHVzaChudWxsKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiByZXEuYXBwbHkodW5kZWYsIGFyZ3MuY29uY2F0KFtyZWxOYW1lLCBmb3JjZVN5bmNdKSk7XG4gICAgICAgIH07XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gbWFrZU5vcm1hbGl6ZShyZWxOYW1lKSB7XG4gICAgICAgIHJldHVybiBmdW5jdGlvbiAobmFtZSkge1xuICAgICAgICAgICAgcmV0dXJuIG5vcm1hbGl6ZShuYW1lLCByZWxOYW1lKTtcbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBtYWtlTG9hZChkZXBOYW1lKSB7XG4gICAgICAgIHJldHVybiBmdW5jdGlvbiAodmFsdWUpIHtcbiAgICAgICAgICAgIGRlZmluZWRbZGVwTmFtZV0gPSB2YWx1ZTtcbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBjYWxsRGVwKG5hbWUpIHtcbiAgICAgICAgaWYgKGhhc1Byb3Aod2FpdGluZywgbmFtZSkpIHtcbiAgICAgICAgICAgIHZhciBhcmdzID0gd2FpdGluZ1tuYW1lXTtcbiAgICAgICAgICAgIGRlbGV0ZSB3YWl0aW5nW25hbWVdO1xuICAgICAgICAgICAgZGVmaW5pbmdbbmFtZV0gPSB0cnVlO1xuICAgICAgICAgICAgbWFpbi5hcHBseSh1bmRlZiwgYXJncyk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoIWhhc1Byb3AoZGVmaW5lZCwgbmFtZSkgJiYgIWhhc1Byb3AoZGVmaW5pbmcsIG5hbWUpKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ05vICcgKyBuYW1lKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gZGVmaW5lZFtuYW1lXTtcbiAgICB9XG5cbiAgICAvL1R1cm5zIGEgcGx1Z2luIXJlc291cmNlIHRvIFtwbHVnaW4sIHJlc291cmNlXVxuICAgIC8vd2l0aCB0aGUgcGx1Z2luIGJlaW5nIHVuZGVmaW5lZCBpZiB0aGUgbmFtZVxuICAgIC8vZGlkIG5vdCBoYXZlIGEgcGx1Z2luIHByZWZpeC5cbiAgICBmdW5jdGlvbiBzcGxpdFByZWZpeChuYW1lKSB7XG4gICAgICAgIHZhciBwcmVmaXgsXG4gICAgICAgICAgICBpbmRleCA9IG5hbWUgPyBuYW1lLmluZGV4T2YoJyEnKSA6IC0xO1xuICAgICAgICBpZiAoaW5kZXggPiAtMSkge1xuICAgICAgICAgICAgcHJlZml4ID0gbmFtZS5zdWJzdHJpbmcoMCwgaW5kZXgpO1xuICAgICAgICAgICAgbmFtZSA9IG5hbWUuc3Vic3RyaW5nKGluZGV4ICsgMSwgbmFtZS5sZW5ndGgpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBbcHJlZml4LCBuYW1lXTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBNYWtlcyBhIG5hbWUgbWFwLCBub3JtYWxpemluZyB0aGUgbmFtZSwgYW5kIHVzaW5nIGEgcGx1Z2luXG4gICAgICogZm9yIG5vcm1hbGl6YXRpb24gaWYgbmVjZXNzYXJ5LiBHcmFicyBhIHJlZiB0byBwbHVnaW5cbiAgICAgKiB0b28sIGFzIGFuIG9wdGltaXphdGlvbi5cbiAgICAgKi9cbiAgICBtYWtlTWFwID0gZnVuY3Rpb24gKG5hbWUsIHJlbE5hbWUpIHtcbiAgICAgICAgdmFyIHBsdWdpbixcbiAgICAgICAgICAgIHBhcnRzID0gc3BsaXRQcmVmaXgobmFtZSksXG4gICAgICAgICAgICBwcmVmaXggPSBwYXJ0c1swXTtcblxuICAgICAgICBuYW1lID0gcGFydHNbMV07XG5cbiAgICAgICAgaWYgKHByZWZpeCkge1xuICAgICAgICAgICAgcHJlZml4ID0gbm9ybWFsaXplKHByZWZpeCwgcmVsTmFtZSk7XG4gICAgICAgICAgICBwbHVnaW4gPSBjYWxsRGVwKHByZWZpeCk7XG4gICAgICAgIH1cblxuICAgICAgICAvL05vcm1hbGl6ZSBhY2NvcmRpbmdcbiAgICAgICAgaWYgKHByZWZpeCkge1xuICAgICAgICAgICAgaWYgKHBsdWdpbiAmJiBwbHVnaW4ubm9ybWFsaXplKSB7XG4gICAgICAgICAgICAgICAgbmFtZSA9IHBsdWdpbi5ub3JtYWxpemUobmFtZSwgbWFrZU5vcm1hbGl6ZShyZWxOYW1lKSk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIG5hbWUgPSBub3JtYWxpemUobmFtZSwgcmVsTmFtZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBuYW1lID0gbm9ybWFsaXplKG5hbWUsIHJlbE5hbWUpO1xuICAgICAgICAgICAgcGFydHMgPSBzcGxpdFByZWZpeChuYW1lKTtcbiAgICAgICAgICAgIHByZWZpeCA9IHBhcnRzWzBdO1xuICAgICAgICAgICAgbmFtZSA9IHBhcnRzWzFdO1xuICAgICAgICAgICAgaWYgKHByZWZpeCkge1xuICAgICAgICAgICAgICAgIHBsdWdpbiA9IGNhbGxEZXAocHJlZml4KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIC8vVXNpbmcgcmlkaWN1bG91cyBwcm9wZXJ0eSBuYW1lcyBmb3Igc3BhY2UgcmVhc29uc1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgZjogcHJlZml4ID8gcHJlZml4ICsgJyEnICsgbmFtZSA6IG5hbWUsIC8vZnVsbE5hbWVcbiAgICAgICAgICAgIG46IG5hbWUsXG4gICAgICAgICAgICBwcjogcHJlZml4LFxuICAgICAgICAgICAgcDogcGx1Z2luXG4gICAgICAgIH07XG4gICAgfTtcblxuICAgIGZ1bmN0aW9uIG1ha2VDb25maWcobmFtZSkge1xuICAgICAgICByZXR1cm4gZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgcmV0dXJuIChjb25maWcgJiYgY29uZmlnLmNvbmZpZyAmJiBjb25maWcuY29uZmlnW25hbWVdKSB8fCB7fTtcbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICBoYW5kbGVycyA9IHtcbiAgICAgICAgcmVxdWlyZTogZnVuY3Rpb24gKG5hbWUpIHtcbiAgICAgICAgICAgIHJldHVybiBtYWtlUmVxdWlyZShuYW1lKTtcbiAgICAgICAgfSxcbiAgICAgICAgZXhwb3J0czogZnVuY3Rpb24gKG5hbWUpIHtcbiAgICAgICAgICAgIHZhciBlID0gZGVmaW5lZFtuYW1lXTtcbiAgICAgICAgICAgIGlmICh0eXBlb2YgZSAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gZTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIChkZWZpbmVkW25hbWVdID0ge30pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9LFxuICAgICAgICBtb2R1bGU6IGZ1bmN0aW9uIChuYW1lKSB7XG4gICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAgIGlkOiBuYW1lLFxuICAgICAgICAgICAgICAgIHVyaTogJycsXG4gICAgICAgICAgICAgICAgZXhwb3J0czogZGVmaW5lZFtuYW1lXSxcbiAgICAgICAgICAgICAgICBjb25maWc6IG1ha2VDb25maWcobmFtZSlcbiAgICAgICAgICAgIH07XG4gICAgICAgIH1cbiAgICB9O1xuXG4gICAgbWFpbiA9IGZ1bmN0aW9uIChuYW1lLCBkZXBzLCBjYWxsYmFjaywgcmVsTmFtZSkge1xuICAgICAgICB2YXIgY2pzTW9kdWxlLCBkZXBOYW1lLCByZXQsIG1hcCwgaSxcbiAgICAgICAgICAgIGFyZ3MgPSBbXSxcbiAgICAgICAgICAgIGNhbGxiYWNrVHlwZSA9IHR5cGVvZiBjYWxsYmFjayxcbiAgICAgICAgICAgIHVzaW5nRXhwb3J0cztcblxuICAgICAgICAvL1VzZSBuYW1lIGlmIG5vIHJlbE5hbWVcbiAgICAgICAgcmVsTmFtZSA9IHJlbE5hbWUgfHwgbmFtZTtcblxuICAgICAgICAvL0NhbGwgdGhlIGNhbGxiYWNrIHRvIGRlZmluZSB0aGUgbW9kdWxlLCBpZiBuZWNlc3NhcnkuXG4gICAgICAgIGlmIChjYWxsYmFja1R5cGUgPT09ICd1bmRlZmluZWQnIHx8IGNhbGxiYWNrVHlwZSA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgICAgLy9QdWxsIG91dCB0aGUgZGVmaW5lZCBkZXBlbmRlbmNpZXMgYW5kIHBhc3MgdGhlIG9yZGVyZWRcbiAgICAgICAgICAgIC8vdmFsdWVzIHRvIHRoZSBjYWxsYmFjay5cbiAgICAgICAgICAgIC8vRGVmYXVsdCB0byBbcmVxdWlyZSwgZXhwb3J0cywgbW9kdWxlXSBpZiBubyBkZXBzXG4gICAgICAgICAgICBkZXBzID0gIWRlcHMubGVuZ3RoICYmIGNhbGxiYWNrLmxlbmd0aCA/IFsncmVxdWlyZScsICdleHBvcnRzJywgJ21vZHVsZSddIDogZGVwcztcbiAgICAgICAgICAgIGZvciAoaSA9IDA7IGkgPCBkZXBzLmxlbmd0aDsgaSArPSAxKSB7XG4gICAgICAgICAgICAgICAgbWFwID0gbWFrZU1hcChkZXBzW2ldLCByZWxOYW1lKTtcbiAgICAgICAgICAgICAgICBkZXBOYW1lID0gbWFwLmY7XG5cbiAgICAgICAgICAgICAgICAvL0Zhc3QgcGF0aCBDb21tb25KUyBzdGFuZGFyZCBkZXBlbmRlbmNpZXMuXG4gICAgICAgICAgICAgICAgaWYgKGRlcE5hbWUgPT09IFwicmVxdWlyZVwiKSB7XG4gICAgICAgICAgICAgICAgICAgIGFyZ3NbaV0gPSBoYW5kbGVycy5yZXF1aXJlKG5hbWUpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoZGVwTmFtZSA9PT0gXCJleHBvcnRzXCIpIHtcbiAgICAgICAgICAgICAgICAgICAgLy9Db21tb25KUyBtb2R1bGUgc3BlYyAxLjFcbiAgICAgICAgICAgICAgICAgICAgYXJnc1tpXSA9IGhhbmRsZXJzLmV4cG9ydHMobmFtZSk7XG4gICAgICAgICAgICAgICAgICAgIHVzaW5nRXhwb3J0cyA9IHRydWU7XG4gICAgICAgICAgICAgICAgfSBlbHNlIGlmIChkZXBOYW1lID09PSBcIm1vZHVsZVwiKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vQ29tbW9uSlMgbW9kdWxlIHNwZWMgMS4xXG4gICAgICAgICAgICAgICAgICAgIGNqc01vZHVsZSA9IGFyZ3NbaV0gPSBoYW5kbGVycy5tb2R1bGUobmFtZSk7XG4gICAgICAgICAgICAgICAgfSBlbHNlIGlmIChoYXNQcm9wKGRlZmluZWQsIGRlcE5hbWUpIHx8XG4gICAgICAgICAgICAgICAgICAgICAgICAgICBoYXNQcm9wKHdhaXRpbmcsIGRlcE5hbWUpIHx8XG4gICAgICAgICAgICAgICAgICAgICAgICAgICBoYXNQcm9wKGRlZmluaW5nLCBkZXBOYW1lKSkge1xuICAgICAgICAgICAgICAgICAgICBhcmdzW2ldID0gY2FsbERlcChkZXBOYW1lKTtcbiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKG1hcC5wKSB7XG4gICAgICAgICAgICAgICAgICAgIG1hcC5wLmxvYWQobWFwLm4sIG1ha2VSZXF1aXJlKHJlbE5hbWUsIHRydWUpLCBtYWtlTG9hZChkZXBOYW1lKSwge30pO1xuICAgICAgICAgICAgICAgICAgICBhcmdzW2ldID0gZGVmaW5lZFtkZXBOYW1lXTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IobmFtZSArICcgbWlzc2luZyAnICsgZGVwTmFtZSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICByZXQgPSBjYWxsYmFjayA/IGNhbGxiYWNrLmFwcGx5KGRlZmluZWRbbmFtZV0sIGFyZ3MpIDogdW5kZWZpbmVkO1xuXG4gICAgICAgICAgICBpZiAobmFtZSkge1xuICAgICAgICAgICAgICAgIC8vSWYgc2V0dGluZyBleHBvcnRzIHZpYSBcIm1vZHVsZVwiIGlzIGluIHBsYXksXG4gICAgICAgICAgICAgICAgLy9mYXZvciB0aGF0IG92ZXIgcmV0dXJuIHZhbHVlIGFuZCBleHBvcnRzLiBBZnRlciB0aGF0LFxuICAgICAgICAgICAgICAgIC8vZmF2b3IgYSBub24tdW5kZWZpbmVkIHJldHVybiB2YWx1ZSBvdmVyIGV4cG9ydHMgdXNlLlxuICAgICAgICAgICAgICAgIGlmIChjanNNb2R1bGUgJiYgY2pzTW9kdWxlLmV4cG9ydHMgIT09IHVuZGVmICYmXG4gICAgICAgICAgICAgICAgICAgICAgICBjanNNb2R1bGUuZXhwb3J0cyAhPT0gZGVmaW5lZFtuYW1lXSkge1xuICAgICAgICAgICAgICAgICAgICBkZWZpbmVkW25hbWVdID0gY2pzTW9kdWxlLmV4cG9ydHM7XG4gICAgICAgICAgICAgICAgfSBlbHNlIGlmIChyZXQgIT09IHVuZGVmIHx8ICF1c2luZ0V4cG9ydHMpIHtcbiAgICAgICAgICAgICAgICAgICAgLy9Vc2UgdGhlIHJldHVybiB2YWx1ZSBmcm9tIHRoZSBmdW5jdGlvbi5cbiAgICAgICAgICAgICAgICAgICAgZGVmaW5lZFtuYW1lXSA9IHJldDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSBpZiAobmFtZSkge1xuICAgICAgICAgICAgLy9NYXkganVzdCBiZSBhbiBvYmplY3QgZGVmaW5pdGlvbiBmb3IgdGhlIG1vZHVsZS4gT25seVxuICAgICAgICAgICAgLy93b3JyeSBhYm91dCBkZWZpbmluZyBpZiBoYXZlIGEgbW9kdWxlIG5hbWUuXG4gICAgICAgICAgICBkZWZpbmVkW25hbWVdID0gY2FsbGJhY2s7XG4gICAgICAgIH1cbiAgICB9O1xuXG4gICAgcmVxdWlyZWpzID0gcmVxdWlyZSA9IHJlcSA9IGZ1bmN0aW9uIChkZXBzLCBjYWxsYmFjaywgcmVsTmFtZSwgZm9yY2VTeW5jLCBhbHQpIHtcbiAgICAgICAgaWYgKHR5cGVvZiBkZXBzID09PSBcInN0cmluZ1wiKSB7XG4gICAgICAgICAgICBpZiAoaGFuZGxlcnNbZGVwc10pIHtcbiAgICAgICAgICAgICAgICAvL2NhbGxiYWNrIGluIHRoaXMgY2FzZSBpcyByZWFsbHkgcmVsTmFtZVxuICAgICAgICAgICAgICAgIHJldHVybiBoYW5kbGVyc1tkZXBzXShjYWxsYmFjayk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICAvL0p1c3QgcmV0dXJuIHRoZSBtb2R1bGUgd2FudGVkLiBJbiB0aGlzIHNjZW5hcmlvLCB0aGVcbiAgICAgICAgICAgIC8vZGVwcyBhcmcgaXMgdGhlIG1vZHVsZSBuYW1lLCBhbmQgc2Vjb25kIGFyZyAoaWYgcGFzc2VkKVxuICAgICAgICAgICAgLy9pcyBqdXN0IHRoZSByZWxOYW1lLlxuICAgICAgICAgICAgLy9Ob3JtYWxpemUgbW9kdWxlIG5hbWUsIGlmIGl0IGNvbnRhaW5zIC4gb3IgLi5cbiAgICAgICAgICAgIHJldHVybiBjYWxsRGVwKG1ha2VNYXAoZGVwcywgY2FsbGJhY2spLmYpO1xuICAgICAgICB9IGVsc2UgaWYgKCFkZXBzLnNwbGljZSkge1xuICAgICAgICAgICAgLy9kZXBzIGlzIGEgY29uZmlnIG9iamVjdCwgbm90IGFuIGFycmF5LlxuICAgICAgICAgICAgY29uZmlnID0gZGVwcztcbiAgICAgICAgICAgIGlmIChjb25maWcuZGVwcykge1xuICAgICAgICAgICAgICAgIHJlcShjb25maWcuZGVwcywgY29uZmlnLmNhbGxiYWNrKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmICghY2FsbGJhY2spIHtcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmIChjYWxsYmFjay5zcGxpY2UpIHtcbiAgICAgICAgICAgICAgICAvL2NhbGxiYWNrIGlzIGFuIGFycmF5LCB3aGljaCBtZWFucyBpdCBpcyBhIGRlcGVuZGVuY3kgbGlzdC5cbiAgICAgICAgICAgICAgICAvL0FkanVzdCBhcmdzIGlmIHRoZXJlIGFyZSBkZXBlbmRlbmNpZXNcbiAgICAgICAgICAgICAgICBkZXBzID0gY2FsbGJhY2s7XG4gICAgICAgICAgICAgICAgY2FsbGJhY2sgPSByZWxOYW1lO1xuICAgICAgICAgICAgICAgIHJlbE5hbWUgPSBudWxsO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBkZXBzID0gdW5kZWY7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICAvL1N1cHBvcnQgcmVxdWlyZShbJ2EnXSlcbiAgICAgICAgY2FsbGJhY2sgPSBjYWxsYmFjayB8fCBmdW5jdGlvbiAoKSB7fTtcblxuICAgICAgICAvL0lmIHJlbE5hbWUgaXMgYSBmdW5jdGlvbiwgaXQgaXMgYW4gZXJyYmFjayBoYW5kbGVyLFxuICAgICAgICAvL3NvIHJlbW92ZSBpdC5cbiAgICAgICAgaWYgKHR5cGVvZiByZWxOYW1lID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgICByZWxOYW1lID0gZm9yY2VTeW5jO1xuICAgICAgICAgICAgZm9yY2VTeW5jID0gYWx0O1xuICAgICAgICB9XG5cbiAgICAgICAgLy9TaW11bGF0ZSBhc3luYyBjYWxsYmFjaztcbiAgICAgICAgaWYgKGZvcmNlU3luYykge1xuICAgICAgICAgICAgbWFpbih1bmRlZiwgZGVwcywgY2FsbGJhY2ssIHJlbE5hbWUpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgLy9Vc2luZyBhIG5vbi16ZXJvIHZhbHVlIGJlY2F1c2Ugb2YgY29uY2VybiBmb3Igd2hhdCBvbGQgYnJvd3NlcnNcbiAgICAgICAgICAgIC8vZG8sIGFuZCBsYXRlc3QgYnJvd3NlcnMgXCJ1cGdyYWRlXCIgdG8gNCBpZiBsb3dlciB2YWx1ZSBpcyB1c2VkOlxuICAgICAgICAgICAgLy9odHRwOi8vd3d3LndoYXR3Zy5vcmcvc3BlY3Mvd2ViLWFwcHMvY3VycmVudC13b3JrL211bHRpcGFnZS90aW1lcnMuaHRtbCNkb20td2luZG93dGltZXJzLXNldHRpbWVvdXQ6XG4gICAgICAgICAgICAvL0lmIHdhbnQgYSB2YWx1ZSBpbW1lZGlhdGVseSwgdXNlIHJlcXVpcmUoJ2lkJykgaW5zdGVhZCAtLSBzb21ldGhpbmdcbiAgICAgICAgICAgIC8vdGhhdCB3b3JrcyBpbiBhbG1vbmQgb24gdGhlIGdsb2JhbCBsZXZlbCwgYnV0IG5vdCBndWFyYW50ZWVkIGFuZFxuICAgICAgICAgICAgLy91bmxpa2VseSB0byB3b3JrIGluIG90aGVyIEFNRCBpbXBsZW1lbnRhdGlvbnMuXG4gICAgICAgICAgICBzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICBtYWluKHVuZGVmLCBkZXBzLCBjYWxsYmFjaywgcmVsTmFtZSk7XG4gICAgICAgICAgICB9LCA0KTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiByZXE7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIEp1c3QgZHJvcHMgdGhlIGNvbmZpZyBvbiB0aGUgZmxvb3IsIGJ1dCByZXR1cm5zIHJlcSBpbiBjYXNlXG4gICAgICogdGhlIGNvbmZpZyByZXR1cm4gdmFsdWUgaXMgdXNlZC5cbiAgICAgKi9cbiAgICByZXEuY29uZmlnID0gZnVuY3Rpb24gKGNmZykge1xuICAgICAgICByZXR1cm4gcmVxKGNmZyk7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIEV4cG9zZSBtb2R1bGUgcmVnaXN0cnkgZm9yIGRlYnVnZ2luZyBhbmQgdG9vbGluZ1xuICAgICAqL1xuICAgIHJlcXVpcmVqcy5fZGVmaW5lZCA9IGRlZmluZWQ7XG5cbiAgICBkZWZpbmUgPSBmdW5jdGlvbiAobmFtZSwgZGVwcywgY2FsbGJhY2spIHtcbiAgICAgICAgaWYgKHR5cGVvZiBuYW1lICE9PSAnc3RyaW5nJykge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdTZWUgYWxtb25kIFJFQURNRTogaW5jb3JyZWN0IG1vZHVsZSBidWlsZCwgbm8gbW9kdWxlIG5hbWUnKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vVGhpcyBtb2R1bGUgbWF5IG5vdCBoYXZlIGRlcGVuZGVuY2llc1xuICAgICAgICBpZiAoIWRlcHMuc3BsaWNlKSB7XG4gICAgICAgICAgICAvL2RlcHMgaXMgbm90IGFuIGFycmF5LCBzbyBwcm9iYWJseSBtZWFuc1xuICAgICAgICAgICAgLy9hbiBvYmplY3QgbGl0ZXJhbCBvciBmYWN0b3J5IGZ1bmN0aW9uIGZvclxuICAgICAgICAgICAgLy90aGUgdmFsdWUuIEFkanVzdCBhcmdzLlxuICAgICAgICAgICAgY2FsbGJhY2sgPSBkZXBzO1xuICAgICAgICAgICAgZGVwcyA9IFtdO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKCFoYXNQcm9wKGRlZmluZWQsIG5hbWUpICYmICFoYXNQcm9wKHdhaXRpbmcsIG5hbWUpKSB7XG4gICAgICAgICAgICB3YWl0aW5nW25hbWVdID0gW25hbWUsIGRlcHMsIGNhbGxiYWNrXTtcbiAgICAgICAgfVxuICAgIH07XG5cbiAgICBkZWZpbmUuYW1kID0ge1xuICAgICAgICBqUXVlcnk6IHRydWVcbiAgICB9O1xufSgpKTtcblxuUzIucmVxdWlyZWpzID0gcmVxdWlyZWpzO1MyLnJlcXVpcmUgPSByZXF1aXJlO1MyLmRlZmluZSA9IGRlZmluZTtcbn1cbn0oKSk7XG5TMi5kZWZpbmUoXCJhbG1vbmRcIiwgZnVuY3Rpb24oKXt9KTtcblxuLyogZ2xvYmFsIGpRdWVyeTpmYWxzZSwgJDpmYWxzZSAqL1xyXG5TMi5kZWZpbmUoJ2pxdWVyeScsW10sZnVuY3Rpb24gKCkge1xyXG4gIHZhciBfJCA9IGpRdWVyeSB8fCAkO1xyXG5cclxuICBpZiAoXyQgPT0gbnVsbCAmJiBjb25zb2xlICYmIGNvbnNvbGUuZXJyb3IpIHtcclxuICAgIGNvbnNvbGUuZXJyb3IoXHJcbiAgICAgICdTZWxlY3QyOiBBbiBpbnN0YW5jZSBvZiBqUXVlcnkgb3IgYSBqUXVlcnktY29tcGF0aWJsZSBsaWJyYXJ5IHdhcyBub3QgJyArXHJcbiAgICAgICdmb3VuZC4gTWFrZSBzdXJlIHRoYXQgeW91IGFyZSBpbmNsdWRpbmcgalF1ZXJ5IGJlZm9yZSBTZWxlY3QyIG9uIHlvdXIgJyArXHJcbiAgICAgICd3ZWIgcGFnZS4nXHJcbiAgICApO1xyXG4gIH1cclxuXHJcbiAgcmV0dXJuIF8kO1xyXG59KTtcclxuXG5TMi5kZWZpbmUoJ3NlbGVjdDIvdXRpbHMnLFtcclxuICAnanF1ZXJ5J1xyXG5dLCBmdW5jdGlvbiAoJCkge1xyXG4gIHZhciBVdGlscyA9IHt9O1xyXG5cclxuICBVdGlscy5FeHRlbmQgPSBmdW5jdGlvbiAoQ2hpbGRDbGFzcywgU3VwZXJDbGFzcykge1xyXG4gICAgdmFyIF9faGFzUHJvcCA9IHt9Lmhhc093blByb3BlcnR5O1xyXG5cclxuICAgIGZ1bmN0aW9uIEJhc2VDb25zdHJ1Y3RvciAoKSB7XHJcbiAgICAgIHRoaXMuY29uc3RydWN0b3IgPSBDaGlsZENsYXNzO1xyXG4gICAgfVxyXG5cclxuICAgIGZvciAodmFyIGtleSBpbiBTdXBlckNsYXNzKSB7XHJcbiAgICAgIGlmIChfX2hhc1Byb3AuY2FsbChTdXBlckNsYXNzLCBrZXkpKSB7XHJcbiAgICAgICAgQ2hpbGRDbGFzc1trZXldID0gU3VwZXJDbGFzc1trZXldO1xyXG4gICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgQmFzZUNvbnN0cnVjdG9yLnByb3RvdHlwZSA9IFN1cGVyQ2xhc3MucHJvdG90eXBlO1xyXG4gICAgQ2hpbGRDbGFzcy5wcm90b3R5cGUgPSBuZXcgQmFzZUNvbnN0cnVjdG9yKCk7XHJcbiAgICBDaGlsZENsYXNzLl9fc3VwZXJfXyA9IFN1cGVyQ2xhc3MucHJvdG90eXBlO1xyXG5cclxuICAgIHJldHVybiBDaGlsZENsYXNzO1xyXG4gIH07XHJcblxyXG4gIGZ1bmN0aW9uIGdldE1ldGhvZHMgKHRoZUNsYXNzKSB7XHJcbiAgICB2YXIgcHJvdG8gPSB0aGVDbGFzcy5wcm90b3R5cGU7XHJcblxyXG4gICAgdmFyIG1ldGhvZHMgPSBbXTtcclxuXHJcbiAgICBmb3IgKHZhciBtZXRob2ROYW1lIGluIHByb3RvKSB7XHJcbiAgICAgIHZhciBtID0gcHJvdG9bbWV0aG9kTmFtZV07XHJcblxyXG4gICAgICBpZiAodHlwZW9mIG0gIT09ICdmdW5jdGlvbicpIHtcclxuICAgICAgICBjb250aW51ZTtcclxuICAgICAgfVxyXG5cclxuICAgICAgaWYgKG1ldGhvZE5hbWUgPT09ICdjb25zdHJ1Y3RvcicpIHtcclxuICAgICAgICBjb250aW51ZTtcclxuICAgICAgfVxyXG5cclxuICAgICAgbWV0aG9kcy5wdXNoKG1ldGhvZE5hbWUpO1xyXG4gICAgfVxyXG5cclxuICAgIHJldHVybiBtZXRob2RzO1xyXG4gIH1cclxuXHJcbiAgVXRpbHMuRGVjb3JhdGUgPSBmdW5jdGlvbiAoU3VwZXJDbGFzcywgRGVjb3JhdG9yQ2xhc3MpIHtcclxuICAgIHZhciBkZWNvcmF0ZWRNZXRob2RzID0gZ2V0TWV0aG9kcyhEZWNvcmF0b3JDbGFzcyk7XHJcbiAgICB2YXIgc3VwZXJNZXRob2RzID0gZ2V0TWV0aG9kcyhTdXBlckNsYXNzKTtcclxuXHJcbiAgICBmdW5jdGlvbiBEZWNvcmF0ZWRDbGFzcyAoKSB7XHJcbiAgICAgIHZhciB1bnNoaWZ0ID0gQXJyYXkucHJvdG90eXBlLnVuc2hpZnQ7XHJcblxyXG4gICAgICB2YXIgYXJnQ291bnQgPSBEZWNvcmF0b3JDbGFzcy5wcm90b3R5cGUuY29uc3RydWN0b3IubGVuZ3RoO1xyXG5cclxuICAgICAgdmFyIGNhbGxlZENvbnN0cnVjdG9yID0gU3VwZXJDbGFzcy5wcm90b3R5cGUuY29uc3RydWN0b3I7XHJcblxyXG4gICAgICBpZiAoYXJnQ291bnQgPiAwKSB7XHJcbiAgICAgICAgdW5zaGlmdC5jYWxsKGFyZ3VtZW50cywgU3VwZXJDbGFzcy5wcm90b3R5cGUuY29uc3RydWN0b3IpO1xyXG5cclxuICAgICAgICBjYWxsZWRDb25zdHJ1Y3RvciA9IERlY29yYXRvckNsYXNzLnByb3RvdHlwZS5jb25zdHJ1Y3RvcjtcclxuICAgICAgfVxyXG5cclxuICAgICAgY2FsbGVkQ29uc3RydWN0b3IuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcclxuICAgIH1cclxuXHJcbiAgICBEZWNvcmF0b3JDbGFzcy5kaXNwbGF5TmFtZSA9IFN1cGVyQ2xhc3MuZGlzcGxheU5hbWU7XHJcblxyXG4gICAgZnVuY3Rpb24gY3RyICgpIHtcclxuICAgICAgdGhpcy5jb25zdHJ1Y3RvciA9IERlY29yYXRlZENsYXNzO1xyXG4gICAgfVxyXG5cclxuICAgIERlY29yYXRlZENsYXNzLnByb3RvdHlwZSA9IG5ldyBjdHIoKTtcclxuXHJcbiAgICBmb3IgKHZhciBtID0gMDsgbSA8IHN1cGVyTWV0aG9kcy5sZW5ndGg7IG0rKykge1xyXG4gICAgICAgIHZhciBzdXBlck1ldGhvZCA9IHN1cGVyTWV0aG9kc1ttXTtcclxuXHJcbiAgICAgICAgRGVjb3JhdGVkQ2xhc3MucHJvdG90eXBlW3N1cGVyTWV0aG9kXSA9XHJcbiAgICAgICAgICBTdXBlckNsYXNzLnByb3RvdHlwZVtzdXBlck1ldGhvZF07XHJcbiAgICB9XHJcblxyXG4gICAgdmFyIGNhbGxlZE1ldGhvZCA9IGZ1bmN0aW9uIChtZXRob2ROYW1lKSB7XHJcbiAgICAgIC8vIFN0dWIgb3V0IHRoZSBvcmlnaW5hbCBtZXRob2QgaWYgaXQncyBub3QgZGVjb3JhdGluZyBhbiBhY3R1YWwgbWV0aG9kXHJcbiAgICAgIHZhciBvcmlnaW5hbE1ldGhvZCA9IGZ1bmN0aW9uICgpIHt9O1xyXG5cclxuICAgICAgaWYgKG1ldGhvZE5hbWUgaW4gRGVjb3JhdGVkQ2xhc3MucHJvdG90eXBlKSB7XHJcbiAgICAgICAgb3JpZ2luYWxNZXRob2QgPSBEZWNvcmF0ZWRDbGFzcy5wcm90b3R5cGVbbWV0aG9kTmFtZV07XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIHZhciBkZWNvcmF0ZWRNZXRob2QgPSBEZWNvcmF0b3JDbGFzcy5wcm90b3R5cGVbbWV0aG9kTmFtZV07XHJcblxyXG4gICAgICByZXR1cm4gZnVuY3Rpb24gKCkge1xyXG4gICAgICAgIHZhciB1bnNoaWZ0ID0gQXJyYXkucHJvdG90eXBlLnVuc2hpZnQ7XHJcblxyXG4gICAgICAgIHVuc2hpZnQuY2FsbChhcmd1bWVudHMsIG9yaWdpbmFsTWV0aG9kKTtcclxuXHJcbiAgICAgICAgcmV0dXJuIGRlY29yYXRlZE1ldGhvZC5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xyXG4gICAgICB9O1xyXG4gICAgfTtcclxuXHJcbiAgICBmb3IgKHZhciBkID0gMDsgZCA8IGRlY29yYXRlZE1ldGhvZHMubGVuZ3RoOyBkKyspIHtcclxuICAgICAgdmFyIGRlY29yYXRlZE1ldGhvZCA9IGRlY29yYXRlZE1ldGhvZHNbZF07XHJcblxyXG4gICAgICBEZWNvcmF0ZWRDbGFzcy5wcm90b3R5cGVbZGVjb3JhdGVkTWV0aG9kXSA9IGNhbGxlZE1ldGhvZChkZWNvcmF0ZWRNZXRob2QpO1xyXG4gICAgfVxyXG5cclxuICAgIHJldHVybiBEZWNvcmF0ZWRDbGFzcztcclxuICB9O1xyXG5cclxuICB2YXIgT2JzZXJ2YWJsZSA9IGZ1bmN0aW9uICgpIHtcclxuICAgIHRoaXMubGlzdGVuZXJzID0ge307XHJcbiAgfTtcclxuXHJcbiAgT2JzZXJ2YWJsZS5wcm90b3R5cGUub24gPSBmdW5jdGlvbiAoZXZlbnQsIGNhbGxiYWNrKSB7XHJcbiAgICB0aGlzLmxpc3RlbmVycyA9IHRoaXMubGlzdGVuZXJzIHx8IHt9O1xyXG5cclxuICAgIGlmIChldmVudCBpbiB0aGlzLmxpc3RlbmVycykge1xyXG4gICAgICB0aGlzLmxpc3RlbmVyc1tldmVudF0ucHVzaChjYWxsYmFjayk7XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICB0aGlzLmxpc3RlbmVyc1tldmVudF0gPSBbY2FsbGJhY2tdO1xyXG4gICAgfVxyXG4gIH07XHJcblxyXG4gIE9ic2VydmFibGUucHJvdG90eXBlLnRyaWdnZXIgPSBmdW5jdGlvbiAoZXZlbnQpIHtcclxuICAgIHZhciBzbGljZSA9IEFycmF5LnByb3RvdHlwZS5zbGljZTtcclxuICAgIHZhciBwYXJhbXMgPSBzbGljZS5jYWxsKGFyZ3VtZW50cywgMSk7XHJcblxyXG4gICAgdGhpcy5saXN0ZW5lcnMgPSB0aGlzLmxpc3RlbmVycyB8fCB7fTtcclxuXHJcbiAgICAvLyBQYXJhbXMgc2hvdWxkIGFsd2F5cyBjb21lIGluIGFzIGFuIGFycmF5XHJcbiAgICBpZiAocGFyYW1zID09IG51bGwpIHtcclxuICAgICAgcGFyYW1zID0gW107XHJcbiAgICB9XHJcblxyXG4gICAgLy8gSWYgdGhlcmUgYXJlIG5vIGFyZ3VtZW50cyB0byB0aGUgZXZlbnQsIHVzZSBhIHRlbXBvcmFyeSBvYmplY3RcclxuICAgIGlmIChwYXJhbXMubGVuZ3RoID09PSAwKSB7XHJcbiAgICAgIHBhcmFtcy5wdXNoKHt9KTtcclxuICAgIH1cclxuXHJcbiAgICAvLyBTZXQgdGhlIGBfdHlwZWAgb2YgdGhlIGZpcnN0IG9iamVjdCB0byB0aGUgZXZlbnRcclxuICAgIHBhcmFtc1swXS5fdHlwZSA9IGV2ZW50O1xyXG5cclxuICAgIGlmIChldmVudCBpbiB0aGlzLmxpc3RlbmVycykge1xyXG4gICAgICB0aGlzLmludm9rZSh0aGlzLmxpc3RlbmVyc1tldmVudF0sIHNsaWNlLmNhbGwoYXJndW1lbnRzLCAxKSk7XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKCcqJyBpbiB0aGlzLmxpc3RlbmVycykge1xyXG4gICAgICB0aGlzLmludm9rZSh0aGlzLmxpc3RlbmVyc1snKiddLCBhcmd1bWVudHMpO1xyXG4gICAgfVxyXG4gIH07XHJcblxyXG4gIE9ic2VydmFibGUucHJvdG90eXBlLmludm9rZSA9IGZ1bmN0aW9uIChsaXN0ZW5lcnMsIHBhcmFtcykge1xyXG4gICAgZm9yICh2YXIgaSA9IDAsIGxlbiA9IGxpc3RlbmVycy5sZW5ndGg7IGkgPCBsZW47IGkrKykge1xyXG4gICAgICBsaXN0ZW5lcnNbaV0uYXBwbHkodGhpcywgcGFyYW1zKTtcclxuICAgIH1cclxuICB9O1xyXG5cclxuICBVdGlscy5PYnNlcnZhYmxlID0gT2JzZXJ2YWJsZTtcclxuXHJcbiAgVXRpbHMuZ2VuZXJhdGVDaGFycyA9IGZ1bmN0aW9uIChsZW5ndGgpIHtcclxuICAgIHZhciBjaGFycyA9ICcnO1xyXG5cclxuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuZ3RoOyBpKyspIHtcclxuICAgICAgdmFyIHJhbmRvbUNoYXIgPSBNYXRoLmZsb29yKE1hdGgucmFuZG9tKCkgKiAzNik7XHJcbiAgICAgIGNoYXJzICs9IHJhbmRvbUNoYXIudG9TdHJpbmcoMzYpO1xyXG4gICAgfVxyXG5cclxuICAgIHJldHVybiBjaGFycztcclxuICB9O1xyXG5cclxuICBVdGlscy5iaW5kID0gZnVuY3Rpb24gKGZ1bmMsIGNvbnRleHQpIHtcclxuICAgIHJldHVybiBmdW5jdGlvbiAoKSB7XHJcbiAgICAgIGZ1bmMuYXBwbHkoY29udGV4dCwgYXJndW1lbnRzKTtcclxuICAgIH07XHJcbiAgfTtcclxuXHJcbiAgVXRpbHMuX2NvbnZlcnREYXRhID0gZnVuY3Rpb24gKGRhdGEpIHtcclxuICAgIGZvciAodmFyIG9yaWdpbmFsS2V5IGluIGRhdGEpIHtcclxuICAgICAgdmFyIGtleXMgPSBvcmlnaW5hbEtleS5zcGxpdCgnLScpO1xyXG5cclxuICAgICAgdmFyIGRhdGFMZXZlbCA9IGRhdGE7XHJcblxyXG4gICAgICBpZiAoa2V5cy5sZW5ndGggPT09IDEpIHtcclxuICAgICAgICBjb250aW51ZTtcclxuICAgICAgfVxyXG5cclxuICAgICAgZm9yICh2YXIgayA9IDA7IGsgPCBrZXlzLmxlbmd0aDsgaysrKSB7XHJcbiAgICAgICAgdmFyIGtleSA9IGtleXNba107XHJcblxyXG4gICAgICAgIC8vIExvd2VyY2FzZSB0aGUgZmlyc3QgbGV0dGVyXHJcbiAgICAgICAgLy8gQnkgZGVmYXVsdCwgZGFzaC1zZXBhcmF0ZWQgYmVjb21lcyBjYW1lbENhc2VcclxuICAgICAgICBrZXkgPSBrZXkuc3Vic3RyaW5nKDAsIDEpLnRvTG93ZXJDYXNlKCkgKyBrZXkuc3Vic3RyaW5nKDEpO1xyXG5cclxuICAgICAgICBpZiAoIShrZXkgaW4gZGF0YUxldmVsKSkge1xyXG4gICAgICAgICAgZGF0YUxldmVsW2tleV0gPSB7fTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGlmIChrID09IGtleXMubGVuZ3RoIC0gMSkge1xyXG4gICAgICAgICAgZGF0YUxldmVsW2tleV0gPSBkYXRhW29yaWdpbmFsS2V5XTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGRhdGFMZXZlbCA9IGRhdGFMZXZlbFtrZXldO1xyXG4gICAgICB9XHJcblxyXG4gICAgICBkZWxldGUgZGF0YVtvcmlnaW5hbEtleV07XHJcbiAgICB9XHJcblxyXG4gICAgcmV0dXJuIGRhdGE7XHJcbiAgfTtcclxuXHJcbiAgVXRpbHMuaGFzU2Nyb2xsID0gZnVuY3Rpb24gKGluZGV4LCBlbCkge1xyXG4gICAgLy8gQWRhcHRlZCBmcm9tIHRoZSBmdW5jdGlvbiBjcmVhdGVkIGJ5IEBTaGFkb3dTY3JpcHRlclxyXG4gICAgLy8gYW5kIGFkYXB0ZWQgYnkgQEJpbGxCYXJyeSBvbiB0aGUgU3RhY2sgRXhjaGFuZ2UgQ29kZSBSZXZpZXcgd2Vic2l0ZS5cclxuICAgIC8vIFRoZSBvcmlnaW5hbCBjb2RlIGNhbiBiZSBmb3VuZCBhdFxyXG4gICAgLy8gaHR0cDovL2NvZGVyZXZpZXcuc3RhY2tleGNoYW5nZS5jb20vcS8xMzMzOFxyXG4gICAgLy8gYW5kIHdhcyBkZXNpZ25lZCB0byBiZSB1c2VkIHdpdGggdGhlIFNpenpsZSBzZWxlY3RvciBlbmdpbmUuXHJcblxyXG4gICAgdmFyICRlbCA9ICQoZWwpO1xyXG4gICAgdmFyIG92ZXJmbG93WCA9IGVsLnN0eWxlLm92ZXJmbG93WDtcclxuICAgIHZhciBvdmVyZmxvd1kgPSBlbC5zdHlsZS5vdmVyZmxvd1k7XHJcblxyXG4gICAgLy9DaGVjayBib3RoIHggYW5kIHkgZGVjbGFyYXRpb25zXHJcbiAgICBpZiAob3ZlcmZsb3dYID09PSBvdmVyZmxvd1kgJiZcclxuICAgICAgICAob3ZlcmZsb3dZID09PSAnaGlkZGVuJyB8fCBvdmVyZmxvd1kgPT09ICd2aXNpYmxlJykpIHtcclxuICAgICAgcmV0dXJuIGZhbHNlO1xyXG4gICAgfVxyXG5cclxuICAgIGlmIChvdmVyZmxvd1ggPT09ICdzY3JvbGwnIHx8IG92ZXJmbG93WSA9PT0gJ3Njcm9sbCcpIHtcclxuICAgICAgcmV0dXJuIHRydWU7XHJcbiAgICB9XHJcblxyXG4gICAgcmV0dXJuICgkZWwuaW5uZXJIZWlnaHQoKSA8IGVsLnNjcm9sbEhlaWdodCB8fFxyXG4gICAgICAkZWwuaW5uZXJXaWR0aCgpIDwgZWwuc2Nyb2xsV2lkdGgpO1xyXG4gIH07XHJcblxyXG4gIFV0aWxzLmVzY2FwZU1hcmt1cCA9IGZ1bmN0aW9uIChtYXJrdXApIHtcclxuICAgIHZhciByZXBsYWNlTWFwID0ge1xyXG4gICAgICAnXFxcXCc6ICcmIzkyOycsXHJcbiAgICAgICcmJzogJyZhbXA7JyxcclxuICAgICAgJzwnOiAnJmx0OycsXHJcbiAgICAgICc+JzogJyZndDsnLFxyXG4gICAgICAnXCInOiAnJnF1b3Q7JyxcclxuICAgICAgJ1xcJyc6ICcmIzM5OycsXHJcbiAgICAgICcvJzogJyYjNDc7J1xyXG4gICAgfTtcclxuXHJcbiAgICAvLyBEbyBub3QgdHJ5IHRvIGVzY2FwZSB0aGUgbWFya3VwIGlmIGl0J3Mgbm90IGEgc3RyaW5nXHJcbiAgICBpZiAodHlwZW9mIG1hcmt1cCAhPT0gJ3N0cmluZycpIHtcclxuICAgICAgcmV0dXJuIG1hcmt1cDtcclxuICAgIH1cclxuXHJcbiAgICByZXR1cm4gU3RyaW5nKG1hcmt1cCkucmVwbGFjZSgvWyY8PlwiJ1xcL1xcXFxdL2csIGZ1bmN0aW9uIChtYXRjaCkge1xyXG4gICAgICByZXR1cm4gcmVwbGFjZU1hcFttYXRjaF07XHJcbiAgICB9KTtcclxuICB9O1xyXG5cclxuICAvLyBBcHBlbmQgYW4gYXJyYXkgb2YgalF1ZXJ5IG5vZGVzIHRvIGEgZ2l2ZW4gZWxlbWVudC5cclxuICBVdGlscy5hcHBlbmRNYW55ID0gZnVuY3Rpb24gKCRlbGVtZW50LCAkbm9kZXMpIHtcclxuICAgIC8vIGpRdWVyeSAxLjcueCBkb2VzIG5vdCBzdXBwb3J0ICQuZm4uYXBwZW5kKCkgd2l0aCBhbiBhcnJheVxyXG4gICAgLy8gRmFsbCBiYWNrIHRvIGEgalF1ZXJ5IG9iamVjdCBjb2xsZWN0aW9uIHVzaW5nICQuZm4uYWRkKClcclxuICAgIGlmICgkLmZuLmpxdWVyeS5zdWJzdHIoMCwgMykgPT09ICcxLjcnKSB7XHJcbiAgICAgIHZhciAkanFOb2RlcyA9ICQoKTtcclxuXHJcbiAgICAgICQubWFwKCRub2RlcywgZnVuY3Rpb24gKG5vZGUpIHtcclxuICAgICAgICAkanFOb2RlcyA9ICRqcU5vZGVzLmFkZChub2RlKTtcclxuICAgICAgfSk7XHJcblxyXG4gICAgICAkbm9kZXMgPSAkanFOb2RlcztcclxuICAgIH1cclxuXHJcbiAgICAkZWxlbWVudC5hcHBlbmQoJG5vZGVzKTtcclxuICB9O1xyXG5cclxuICByZXR1cm4gVXRpbHM7XHJcbn0pO1xyXG5cblMyLmRlZmluZSgnc2VsZWN0Mi9yZXN1bHRzJyxbXHJcbiAgJ2pxdWVyeScsXHJcbiAgJy4vdXRpbHMnXHJcbl0sIGZ1bmN0aW9uICgkLCBVdGlscykge1xyXG4gIGZ1bmN0aW9uIFJlc3VsdHMgKCRlbGVtZW50LCBvcHRpb25zLCBkYXRhQWRhcHRlcikge1xyXG4gICAgdGhpcy4kZWxlbWVudCA9ICRlbGVtZW50O1xyXG4gICAgdGhpcy5kYXRhID0gZGF0YUFkYXB0ZXI7XHJcbiAgICB0aGlzLm9wdGlvbnMgPSBvcHRpb25zO1xyXG5cclxuICAgIFJlc3VsdHMuX19zdXBlcl9fLmNvbnN0cnVjdG9yLmNhbGwodGhpcyk7XHJcbiAgfVxyXG5cclxuICBVdGlscy5FeHRlbmQoUmVzdWx0cywgVXRpbHMuT2JzZXJ2YWJsZSk7XHJcblxyXG4gIFJlc3VsdHMucHJvdG90eXBlLnJlbmRlciA9IGZ1bmN0aW9uICgpIHtcclxuICAgIHZhciAkcmVzdWx0cyA9ICQoXHJcbiAgICAgICc8dWwgY2xhc3M9XCJzZWxlY3QyLXJlc3VsdHNfX29wdGlvbnNcIiByb2xlPVwidHJlZVwiPjwvdWw+J1xyXG4gICAgKTtcclxuXHJcbiAgICBpZiAodGhpcy5vcHRpb25zLmdldCgnbXVsdGlwbGUnKSkge1xyXG4gICAgICAkcmVzdWx0cy5hdHRyKCdhcmlhLW11bHRpc2VsZWN0YWJsZScsICd0cnVlJyk7XHJcbiAgICB9XHJcblxyXG4gICAgdGhpcy4kcmVzdWx0cyA9ICRyZXN1bHRzO1xyXG5cclxuICAgIHJldHVybiAkcmVzdWx0cztcclxuICB9O1xyXG5cclxuICBSZXN1bHRzLnByb3RvdHlwZS5jbGVhciA9IGZ1bmN0aW9uICgpIHtcclxuICAgIHRoaXMuJHJlc3VsdHMuZW1wdHkoKTtcclxuICB9O1xyXG5cclxuICBSZXN1bHRzLnByb3RvdHlwZS5kaXNwbGF5TWVzc2FnZSA9IGZ1bmN0aW9uIChwYXJhbXMpIHtcclxuICAgIHZhciBlc2NhcGVNYXJrdXAgPSB0aGlzLm9wdGlvbnMuZ2V0KCdlc2NhcGVNYXJrdXAnKTtcclxuXHJcbiAgICB0aGlzLmNsZWFyKCk7XHJcbiAgICB0aGlzLmhpZGVMb2FkaW5nKCk7XHJcblxyXG4gICAgdmFyICRtZXNzYWdlID0gJChcclxuICAgICAgJzxsaSByb2xlPVwidHJlZWl0ZW1cIiBhcmlhLWxpdmU9XCJhc3NlcnRpdmVcIicgK1xyXG4gICAgICAnIGNsYXNzPVwic2VsZWN0Mi1yZXN1bHRzX19vcHRpb25cIj48L2xpPidcclxuICAgICk7XHJcblxyXG4gICAgdmFyIG1lc3NhZ2UgPSB0aGlzLm9wdGlvbnMuZ2V0KCd0cmFuc2xhdGlvbnMnKS5nZXQocGFyYW1zLm1lc3NhZ2UpO1xyXG5cclxuICAgICRtZXNzYWdlLmFwcGVuZChcclxuICAgICAgZXNjYXBlTWFya3VwKFxyXG4gICAgICAgIG1lc3NhZ2UocGFyYW1zLmFyZ3MpXHJcbiAgICAgIClcclxuICAgICk7XHJcblxyXG4gICAgJG1lc3NhZ2VbMF0uY2xhc3NOYW1lICs9ICcgc2VsZWN0Mi1yZXN1bHRzX19tZXNzYWdlJztcclxuXHJcbiAgICB0aGlzLiRyZXN1bHRzLmFwcGVuZCgkbWVzc2FnZSk7XHJcbiAgfTtcclxuXHJcbiAgUmVzdWx0cy5wcm90b3R5cGUuaGlkZU1lc3NhZ2VzID0gZnVuY3Rpb24gKCkge1xyXG4gICAgdGhpcy4kcmVzdWx0cy5maW5kKCcuc2VsZWN0Mi1yZXN1bHRzX19tZXNzYWdlJykucmVtb3ZlKCk7XHJcbiAgfTtcclxuXHJcbiAgUmVzdWx0cy5wcm90b3R5cGUuYXBwZW5kID0gZnVuY3Rpb24gKGRhdGEpIHtcclxuICAgIHRoaXMuaGlkZUxvYWRpbmcoKTtcclxuXHJcbiAgICB2YXIgJG9wdGlvbnMgPSBbXTtcclxuXHJcbiAgICBpZiAoZGF0YS5yZXN1bHRzID09IG51bGwgfHwgZGF0YS5yZXN1bHRzLmxlbmd0aCA9PT0gMCkge1xyXG4gICAgICBpZiAodGhpcy4kcmVzdWx0cy5jaGlsZHJlbigpLmxlbmd0aCA9PT0gMCkge1xyXG4gICAgICAgIHRoaXMudHJpZ2dlcigncmVzdWx0czptZXNzYWdlJywge1xyXG4gICAgICAgICAgbWVzc2FnZTogJ25vUmVzdWx0cydcclxuICAgICAgICB9KTtcclxuICAgICAgfVxyXG5cclxuICAgICAgcmV0dXJuO1xyXG4gICAgfVxyXG5cclxuICAgIGRhdGEucmVzdWx0cyA9IHRoaXMuc29ydChkYXRhLnJlc3VsdHMpO1xyXG5cclxuICAgIGZvciAodmFyIGQgPSAwOyBkIDwgZGF0YS5yZXN1bHRzLmxlbmd0aDsgZCsrKSB7XHJcbiAgICAgIHZhciBpdGVtID0gZGF0YS5yZXN1bHRzW2RdO1xyXG5cclxuICAgICAgdmFyICRvcHRpb24gPSB0aGlzLm9wdGlvbihpdGVtKTtcclxuXHJcbiAgICAgICRvcHRpb25zLnB1c2goJG9wdGlvbik7XHJcbiAgICB9XHJcblxyXG4gICAgdGhpcy4kcmVzdWx0cy5hcHBlbmQoJG9wdGlvbnMpO1xyXG4gIH07XHJcblxyXG4gIFJlc3VsdHMucHJvdG90eXBlLnBvc2l0aW9uID0gZnVuY3Rpb24gKCRyZXN1bHRzLCAkZHJvcGRvd24pIHtcclxuICAgIHZhciAkcmVzdWx0c0NvbnRhaW5lciA9ICRkcm9wZG93bi5maW5kKCcuc2VsZWN0Mi1yZXN1bHRzJyk7XHJcbiAgICAkcmVzdWx0c0NvbnRhaW5lci5hcHBlbmQoJHJlc3VsdHMpO1xyXG4gIH07XHJcblxyXG4gIFJlc3VsdHMucHJvdG90eXBlLnNvcnQgPSBmdW5jdGlvbiAoZGF0YSkge1xyXG4gICAgdmFyIHNvcnRlciA9IHRoaXMub3B0aW9ucy5nZXQoJ3NvcnRlcicpO1xyXG5cclxuICAgIHJldHVybiBzb3J0ZXIoZGF0YSk7XHJcbiAgfTtcclxuXHJcbiAgUmVzdWx0cy5wcm90b3R5cGUuaGlnaGxpZ2h0Rmlyc3RJdGVtID0gZnVuY3Rpb24gKCkge1xyXG4gICAgdmFyICRvcHRpb25zID0gdGhpcy4kcmVzdWx0c1xyXG4gICAgICAuZmluZCgnLnNlbGVjdDItcmVzdWx0c19fb3B0aW9uW2FyaWEtc2VsZWN0ZWRdJyk7XHJcblxyXG4gICAgdmFyICRzZWxlY3RlZCA9ICRvcHRpb25zLmZpbHRlcignW2FyaWEtc2VsZWN0ZWQ9dHJ1ZV0nKTtcclxuXHJcbiAgICAvLyBDaGVjayBpZiB0aGVyZSBhcmUgYW55IHNlbGVjdGVkIG9wdGlvbnNcclxuICAgIGlmICgkc2VsZWN0ZWQubGVuZ3RoID4gMCkge1xyXG4gICAgICAvLyBJZiB0aGVyZSBhcmUgc2VsZWN0ZWQgb3B0aW9ucywgaGlnaGxpZ2h0IHRoZSBmaXJzdFxyXG4gICAgICAkc2VsZWN0ZWQuZmlyc3QoKS50cmlnZ2VyKCdtb3VzZWVudGVyJyk7XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICAvLyBJZiB0aGVyZSBhcmUgbm8gc2VsZWN0ZWQgb3B0aW9ucywgaGlnaGxpZ2h0IHRoZSBmaXJzdCBvcHRpb25cclxuICAgICAgLy8gaW4gdGhlIGRyb3Bkb3duXHJcbiAgICAgICRvcHRpb25zLmZpcnN0KCkudHJpZ2dlcignbW91c2VlbnRlcicpO1xyXG4gICAgfVxyXG5cclxuICAgIHRoaXMuZW5zdXJlSGlnaGxpZ2h0VmlzaWJsZSgpO1xyXG4gIH07XHJcblxyXG4gIFJlc3VsdHMucHJvdG90eXBlLnNldENsYXNzZXMgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICB2YXIgc2VsZiA9IHRoaXM7XHJcblxyXG4gICAgdGhpcy5kYXRhLmN1cnJlbnQoZnVuY3Rpb24gKHNlbGVjdGVkKSB7XHJcbiAgICAgIHZhciBzZWxlY3RlZElkcyA9ICQubWFwKHNlbGVjdGVkLCBmdW5jdGlvbiAocykge1xyXG4gICAgICAgIHJldHVybiBzLmlkLnRvU3RyaW5nKCk7XHJcbiAgICAgIH0pO1xyXG5cclxuICAgICAgdmFyICRvcHRpb25zID0gc2VsZi4kcmVzdWx0c1xyXG4gICAgICAgIC5maW5kKCcuc2VsZWN0Mi1yZXN1bHRzX19vcHRpb25bYXJpYS1zZWxlY3RlZF0nKTtcclxuXHJcbiAgICAgICRvcHRpb25zLmVhY2goZnVuY3Rpb24gKCkge1xyXG4gICAgICAgIHZhciAkb3B0aW9uID0gJCh0aGlzKTtcclxuXHJcbiAgICAgICAgdmFyIGl0ZW0gPSAkLmRhdGEodGhpcywgJ2RhdGEnKTtcclxuXHJcbiAgICAgICAgLy8gaWQgbmVlZHMgdG8gYmUgY29udmVydGVkIHRvIGEgc3RyaW5nIHdoZW4gY29tcGFyaW5nXHJcbiAgICAgICAgdmFyIGlkID0gJycgKyBpdGVtLmlkO1xyXG5cclxuICAgICAgICBpZiAoKGl0ZW0uZWxlbWVudCAhPSBudWxsICYmIGl0ZW0uZWxlbWVudC5zZWxlY3RlZCkgfHxcclxuICAgICAgICAgICAgKGl0ZW0uZWxlbWVudCA9PSBudWxsICYmICQuaW5BcnJheShpZCwgc2VsZWN0ZWRJZHMpID4gLTEpKSB7XHJcbiAgICAgICAgICAkb3B0aW9uLmF0dHIoJ2FyaWEtc2VsZWN0ZWQnLCAndHJ1ZScpO1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAkb3B0aW9uLmF0dHIoJ2FyaWEtc2VsZWN0ZWQnLCAnZmFsc2UnKTtcclxuICAgICAgICB9XHJcbiAgICAgIH0pO1xyXG5cclxuICAgIH0pO1xyXG4gIH07XHJcblxyXG4gIFJlc3VsdHMucHJvdG90eXBlLnNob3dMb2FkaW5nID0gZnVuY3Rpb24gKHBhcmFtcykge1xyXG4gICAgdGhpcy5oaWRlTG9hZGluZygpO1xyXG5cclxuICAgIHZhciBsb2FkaW5nTW9yZSA9IHRoaXMub3B0aW9ucy5nZXQoJ3RyYW5zbGF0aW9ucycpLmdldCgnc2VhcmNoaW5nJyk7XHJcblxyXG4gICAgdmFyIGxvYWRpbmcgPSB7XHJcbiAgICAgIGRpc2FibGVkOiB0cnVlLFxyXG4gICAgICBsb2FkaW5nOiB0cnVlLFxyXG4gICAgICB0ZXh0OiBsb2FkaW5nTW9yZShwYXJhbXMpXHJcbiAgICB9O1xyXG4gICAgdmFyICRsb2FkaW5nID0gdGhpcy5vcHRpb24obG9hZGluZyk7XHJcbiAgICAkbG9hZGluZy5jbGFzc05hbWUgKz0gJyBsb2FkaW5nLXJlc3VsdHMnO1xyXG5cclxuICAgIHRoaXMuJHJlc3VsdHMucHJlcGVuZCgkbG9hZGluZyk7XHJcbiAgfTtcclxuXHJcbiAgUmVzdWx0cy5wcm90b3R5cGUuaGlkZUxvYWRpbmcgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICB0aGlzLiRyZXN1bHRzLmZpbmQoJy5sb2FkaW5nLXJlc3VsdHMnKS5yZW1vdmUoKTtcclxuICB9O1xyXG5cclxuICBSZXN1bHRzLnByb3RvdHlwZS5vcHRpb24gPSBmdW5jdGlvbiAoZGF0YSkge1xyXG4gICAgdmFyIG9wdGlvbiA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2xpJyk7XHJcbiAgICBvcHRpb24uY2xhc3NOYW1lID0gJ3NlbGVjdDItcmVzdWx0c19fb3B0aW9uJztcclxuXHJcbiAgICB2YXIgYXR0cnMgPSB7XHJcbiAgICAgICdyb2xlJzogJ3RyZWVpdGVtJyxcclxuICAgICAgJ2FyaWEtc2VsZWN0ZWQnOiAnZmFsc2UnXHJcbiAgICB9O1xyXG5cclxuICAgIGlmIChkYXRhLmRpc2FibGVkKSB7XHJcbiAgICAgIGRlbGV0ZSBhdHRyc1snYXJpYS1zZWxlY3RlZCddO1xyXG4gICAgICBhdHRyc1snYXJpYS1kaXNhYmxlZCddID0gJ3RydWUnO1xyXG4gICAgfVxyXG5cclxuICAgIGlmIChkYXRhLmlkID09IG51bGwpIHtcclxuICAgICAgZGVsZXRlIGF0dHJzWydhcmlhLXNlbGVjdGVkJ107XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKGRhdGEuX3Jlc3VsdElkICE9IG51bGwpIHtcclxuICAgICAgb3B0aW9uLmlkID0gZGF0YS5fcmVzdWx0SWQ7XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKGRhdGEudGl0bGUpIHtcclxuICAgICAgb3B0aW9uLnRpdGxlID0gZGF0YS50aXRsZTtcclxuICAgIH1cclxuXHJcbiAgICBpZiAoZGF0YS5jaGlsZHJlbikge1xyXG4gICAgICBhdHRycy5yb2xlID0gJ2dyb3VwJztcclxuICAgICAgYXR0cnNbJ2FyaWEtbGFiZWwnXSA9IGRhdGEudGV4dDtcclxuICAgICAgZGVsZXRlIGF0dHJzWydhcmlhLXNlbGVjdGVkJ107XHJcbiAgICB9XHJcblxyXG4gICAgZm9yICh2YXIgYXR0ciBpbiBhdHRycykge1xyXG4gICAgICB2YXIgdmFsID0gYXR0cnNbYXR0cl07XHJcblxyXG4gICAgICBvcHRpb24uc2V0QXR0cmlidXRlKGF0dHIsIHZhbCk7XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKGRhdGEuY2hpbGRyZW4pIHtcclxuICAgICAgdmFyICRvcHRpb24gPSAkKG9wdGlvbik7XHJcblxyXG4gICAgICB2YXIgbGFiZWwgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdzdHJvbmcnKTtcclxuICAgICAgbGFiZWwuY2xhc3NOYW1lID0gJ3NlbGVjdDItcmVzdWx0c19fZ3JvdXAnO1xyXG5cclxuICAgICAgdmFyICRsYWJlbCA9ICQobGFiZWwpO1xyXG4gICAgICB0aGlzLnRlbXBsYXRlKGRhdGEsIGxhYmVsKTtcclxuXHJcbiAgICAgIHZhciAkY2hpbGRyZW4gPSBbXTtcclxuXHJcbiAgICAgIGZvciAodmFyIGMgPSAwOyBjIDwgZGF0YS5jaGlsZHJlbi5sZW5ndGg7IGMrKykge1xyXG4gICAgICAgIHZhciBjaGlsZCA9IGRhdGEuY2hpbGRyZW5bY107XHJcblxyXG4gICAgICAgIHZhciAkY2hpbGQgPSB0aGlzLm9wdGlvbihjaGlsZCk7XHJcblxyXG4gICAgICAgICRjaGlsZHJlbi5wdXNoKCRjaGlsZCk7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIHZhciAkY2hpbGRyZW5Db250YWluZXIgPSAkKCc8dWw+PC91bD4nLCB7XHJcbiAgICAgICAgJ2NsYXNzJzogJ3NlbGVjdDItcmVzdWx0c19fb3B0aW9ucyBzZWxlY3QyLXJlc3VsdHNfX29wdGlvbnMtLW5lc3RlZCdcclxuICAgICAgfSk7XHJcblxyXG4gICAgICAkY2hpbGRyZW5Db250YWluZXIuYXBwZW5kKCRjaGlsZHJlbik7XHJcblxyXG4gICAgICAkb3B0aW9uLmFwcGVuZChsYWJlbCk7XHJcbiAgICAgICRvcHRpb24uYXBwZW5kKCRjaGlsZHJlbkNvbnRhaW5lcik7XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICB0aGlzLnRlbXBsYXRlKGRhdGEsIG9wdGlvbik7XHJcbiAgICB9XHJcblxyXG4gICAgJC5kYXRhKG9wdGlvbiwgJ2RhdGEnLCBkYXRhKTtcclxuXHJcbiAgICByZXR1cm4gb3B0aW9uO1xyXG4gIH07XHJcblxyXG4gIFJlc3VsdHMucHJvdG90eXBlLmJpbmQgPSBmdW5jdGlvbiAoY29udGFpbmVyLCAkY29udGFpbmVyKSB7XHJcbiAgICB2YXIgc2VsZiA9IHRoaXM7XHJcblxyXG4gICAgdmFyIGlkID0gY29udGFpbmVyLmlkICsgJy1yZXN1bHRzJztcclxuXHJcbiAgICB0aGlzLiRyZXN1bHRzLmF0dHIoJ2lkJywgaWQpO1xyXG5cclxuICAgIGNvbnRhaW5lci5vbigncmVzdWx0czphbGwnLCBmdW5jdGlvbiAocGFyYW1zKSB7XHJcbiAgICAgIHNlbGYuY2xlYXIoKTtcclxuICAgICAgc2VsZi5hcHBlbmQocGFyYW1zLmRhdGEpO1xyXG5cclxuICAgICAgaWYgKGNvbnRhaW5lci5pc09wZW4oKSkge1xyXG4gICAgICAgIHNlbGYuc2V0Q2xhc3NlcygpO1xyXG4gICAgICAgIHNlbGYuaGlnaGxpZ2h0Rmlyc3RJdGVtKCk7XHJcbiAgICAgIH1cclxuICAgIH0pO1xyXG5cclxuICAgIGNvbnRhaW5lci5vbigncmVzdWx0czphcHBlbmQnLCBmdW5jdGlvbiAocGFyYW1zKSB7XHJcbiAgICAgIHNlbGYuYXBwZW5kKHBhcmFtcy5kYXRhKTtcclxuXHJcbiAgICAgIGlmIChjb250YWluZXIuaXNPcGVuKCkpIHtcclxuICAgICAgICBzZWxmLnNldENsYXNzZXMoKTtcclxuICAgICAgfVxyXG4gICAgfSk7XHJcblxyXG4gICAgY29udGFpbmVyLm9uKCdxdWVyeScsIGZ1bmN0aW9uIChwYXJhbXMpIHtcclxuICAgICAgc2VsZi5oaWRlTWVzc2FnZXMoKTtcclxuICAgICAgc2VsZi5zaG93TG9hZGluZyhwYXJhbXMpO1xyXG4gICAgfSk7XHJcblxyXG4gICAgY29udGFpbmVyLm9uKCdzZWxlY3QnLCBmdW5jdGlvbiAoKSB7XHJcbiAgICAgIGlmICghY29udGFpbmVyLmlzT3BlbigpKSB7XHJcbiAgICAgICAgcmV0dXJuO1xyXG4gICAgICB9XHJcblxyXG4gICAgICBzZWxmLnNldENsYXNzZXMoKTtcclxuICAgICAgc2VsZi5oaWdobGlnaHRGaXJzdEl0ZW0oKTtcclxuICAgIH0pO1xyXG5cclxuICAgIGNvbnRhaW5lci5vbigndW5zZWxlY3QnLCBmdW5jdGlvbiAoKSB7XHJcbiAgICAgIGlmICghY29udGFpbmVyLmlzT3BlbigpKSB7XHJcbiAgICAgICAgcmV0dXJuO1xyXG4gICAgICB9XHJcblxyXG4gICAgICBzZWxmLnNldENsYXNzZXMoKTtcclxuICAgICAgc2VsZi5oaWdobGlnaHRGaXJzdEl0ZW0oKTtcclxuICAgIH0pO1xyXG5cclxuICAgIGNvbnRhaW5lci5vbignb3BlbicsIGZ1bmN0aW9uICgpIHtcclxuICAgICAgLy8gV2hlbiB0aGUgZHJvcGRvd24gaXMgb3BlbiwgYXJpYS1leHBlbmRlZD1cInRydWVcIlxyXG4gICAgICBzZWxmLiRyZXN1bHRzLmF0dHIoJ2FyaWEtZXhwYW5kZWQnLCAndHJ1ZScpO1xyXG4gICAgICBzZWxmLiRyZXN1bHRzLmF0dHIoJ2FyaWEtaGlkZGVuJywgJ2ZhbHNlJyk7XHJcblxyXG4gICAgICBzZWxmLnNldENsYXNzZXMoKTtcclxuICAgICAgc2VsZi5lbnN1cmVIaWdobGlnaHRWaXNpYmxlKCk7XHJcbiAgICB9KTtcclxuXHJcbiAgICBjb250YWluZXIub24oJ2Nsb3NlJywgZnVuY3Rpb24gKCkge1xyXG4gICAgICAvLyBXaGVuIHRoZSBkcm9wZG93biBpcyBjbG9zZWQsIGFyaWEtZXhwZW5kZWQ9XCJmYWxzZVwiXHJcbiAgICAgIHNlbGYuJHJlc3VsdHMuYXR0cignYXJpYS1leHBhbmRlZCcsICdmYWxzZScpO1xyXG4gICAgICBzZWxmLiRyZXN1bHRzLmF0dHIoJ2FyaWEtaGlkZGVuJywgJ3RydWUnKTtcclxuICAgICAgc2VsZi4kcmVzdWx0cy5yZW1vdmVBdHRyKCdhcmlhLWFjdGl2ZWRlc2NlbmRhbnQnKTtcclxuICAgIH0pO1xyXG5cclxuICAgIGNvbnRhaW5lci5vbigncmVzdWx0czp0b2dnbGUnLCBmdW5jdGlvbiAoKSB7XHJcbiAgICAgIHZhciAkaGlnaGxpZ2h0ZWQgPSBzZWxmLmdldEhpZ2hsaWdodGVkUmVzdWx0cygpO1xyXG5cclxuICAgICAgaWYgKCRoaWdobGlnaHRlZC5sZW5ndGggPT09IDApIHtcclxuICAgICAgICByZXR1cm47XHJcbiAgICAgIH1cclxuXHJcbiAgICAgICRoaWdobGlnaHRlZC50cmlnZ2VyKCdtb3VzZXVwJyk7XHJcbiAgICB9KTtcclxuXHJcbiAgICBjb250YWluZXIub24oJ3Jlc3VsdHM6c2VsZWN0JywgZnVuY3Rpb24gKCkge1xyXG4gICAgICB2YXIgJGhpZ2hsaWdodGVkID0gc2VsZi5nZXRIaWdobGlnaHRlZFJlc3VsdHMoKTtcclxuXHJcbiAgICAgIGlmICgkaGlnaGxpZ2h0ZWQubGVuZ3RoID09PSAwKSB7XHJcbiAgICAgICAgcmV0dXJuO1xyXG4gICAgICB9XHJcblxyXG4gICAgICB2YXIgZGF0YSA9ICRoaWdobGlnaHRlZC5kYXRhKCdkYXRhJyk7XHJcblxyXG4gICAgICBpZiAoJGhpZ2hsaWdodGVkLmF0dHIoJ2FyaWEtc2VsZWN0ZWQnKSA9PSAndHJ1ZScpIHtcclxuICAgICAgICBzZWxmLnRyaWdnZXIoJ2Nsb3NlJywge30pO1xyXG4gICAgICB9IGVsc2Uge1xyXG4gICAgICAgIHNlbGYudHJpZ2dlcignc2VsZWN0Jywge1xyXG4gICAgICAgICAgZGF0YTogZGF0YVxyXG4gICAgICAgIH0pO1xyXG4gICAgICB9XHJcbiAgICB9KTtcclxuXHJcbiAgICBjb250YWluZXIub24oJ3Jlc3VsdHM6cHJldmlvdXMnLCBmdW5jdGlvbiAoKSB7XHJcbiAgICAgIHZhciAkaGlnaGxpZ2h0ZWQgPSBzZWxmLmdldEhpZ2hsaWdodGVkUmVzdWx0cygpO1xyXG5cclxuICAgICAgdmFyICRvcHRpb25zID0gc2VsZi4kcmVzdWx0cy5maW5kKCdbYXJpYS1zZWxlY3RlZF0nKTtcclxuXHJcbiAgICAgIHZhciBjdXJyZW50SW5kZXggPSAkb3B0aW9ucy5pbmRleCgkaGlnaGxpZ2h0ZWQpO1xyXG5cclxuICAgICAgLy8gSWYgd2UgYXJlIGFscmVhZHkgYXQgdGUgdG9wLCBkb24ndCBtb3ZlIGZ1cnRoZXJcclxuICAgICAgaWYgKGN1cnJlbnRJbmRleCA9PT0gMCkge1xyXG4gICAgICAgIHJldHVybjtcclxuICAgICAgfVxyXG5cclxuICAgICAgdmFyIG5leHRJbmRleCA9IGN1cnJlbnRJbmRleCAtIDE7XHJcblxyXG4gICAgICAvLyBJZiBub25lIGFyZSBoaWdobGlnaHRlZCwgaGlnaGxpZ2h0IHRoZSBmaXJzdFxyXG4gICAgICBpZiAoJGhpZ2hsaWdodGVkLmxlbmd0aCA9PT0gMCkge1xyXG4gICAgICAgIG5leHRJbmRleCA9IDA7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIHZhciAkbmV4dCA9ICRvcHRpb25zLmVxKG5leHRJbmRleCk7XHJcblxyXG4gICAgICAkbmV4dC50cmlnZ2VyKCdtb3VzZWVudGVyJyk7XHJcblxyXG4gICAgICB2YXIgY3VycmVudE9mZnNldCA9IHNlbGYuJHJlc3VsdHMub2Zmc2V0KCkudG9wO1xyXG4gICAgICB2YXIgbmV4dFRvcCA9ICRuZXh0Lm9mZnNldCgpLnRvcDtcclxuICAgICAgdmFyIG5leHRPZmZzZXQgPSBzZWxmLiRyZXN1bHRzLnNjcm9sbFRvcCgpICsgKG5leHRUb3AgLSBjdXJyZW50T2Zmc2V0KTtcclxuXHJcbiAgICAgIGlmIChuZXh0SW5kZXggPT09IDApIHtcclxuICAgICAgICBzZWxmLiRyZXN1bHRzLnNjcm9sbFRvcCgwKTtcclxuICAgICAgfSBlbHNlIGlmIChuZXh0VG9wIC0gY3VycmVudE9mZnNldCA8IDApIHtcclxuICAgICAgICBzZWxmLiRyZXN1bHRzLnNjcm9sbFRvcChuZXh0T2Zmc2V0KTtcclxuICAgICAgfVxyXG4gICAgfSk7XHJcblxyXG4gICAgY29udGFpbmVyLm9uKCdyZXN1bHRzOm5leHQnLCBmdW5jdGlvbiAoKSB7XHJcbiAgICAgIHZhciAkaGlnaGxpZ2h0ZWQgPSBzZWxmLmdldEhpZ2hsaWdodGVkUmVzdWx0cygpO1xyXG5cclxuICAgICAgdmFyICRvcHRpb25zID0gc2VsZi4kcmVzdWx0cy5maW5kKCdbYXJpYS1zZWxlY3RlZF0nKTtcclxuXHJcbiAgICAgIHZhciBjdXJyZW50SW5kZXggPSAkb3B0aW9ucy5pbmRleCgkaGlnaGxpZ2h0ZWQpO1xyXG5cclxuICAgICAgdmFyIG5leHRJbmRleCA9IGN1cnJlbnRJbmRleCArIDE7XHJcblxyXG4gICAgICAvLyBJZiB3ZSBhcmUgYXQgdGhlIGxhc3Qgb3B0aW9uLCBzdGF5IHRoZXJlXHJcbiAgICAgIGlmIChuZXh0SW5kZXggPj0gJG9wdGlvbnMubGVuZ3RoKSB7XHJcbiAgICAgICAgcmV0dXJuO1xyXG4gICAgICB9XHJcblxyXG4gICAgICB2YXIgJG5leHQgPSAkb3B0aW9ucy5lcShuZXh0SW5kZXgpO1xyXG5cclxuICAgICAgJG5leHQudHJpZ2dlcignbW91c2VlbnRlcicpO1xyXG5cclxuICAgICAgdmFyIGN1cnJlbnRPZmZzZXQgPSBzZWxmLiRyZXN1bHRzLm9mZnNldCgpLnRvcCArXHJcbiAgICAgICAgc2VsZi4kcmVzdWx0cy5vdXRlckhlaWdodChmYWxzZSk7XHJcbiAgICAgIHZhciBuZXh0Qm90dG9tID0gJG5leHQub2Zmc2V0KCkudG9wICsgJG5leHQub3V0ZXJIZWlnaHQoZmFsc2UpO1xyXG4gICAgICB2YXIgbmV4dE9mZnNldCA9IHNlbGYuJHJlc3VsdHMuc2Nyb2xsVG9wKCkgKyBuZXh0Qm90dG9tIC0gY3VycmVudE9mZnNldDtcclxuXHJcbiAgICAgIGlmIChuZXh0SW5kZXggPT09IDApIHtcclxuICAgICAgICBzZWxmLiRyZXN1bHRzLnNjcm9sbFRvcCgwKTtcclxuICAgICAgfSBlbHNlIGlmIChuZXh0Qm90dG9tID4gY3VycmVudE9mZnNldCkge1xyXG4gICAgICAgIHNlbGYuJHJlc3VsdHMuc2Nyb2xsVG9wKG5leHRPZmZzZXQpO1xyXG4gICAgICB9XHJcbiAgICB9KTtcclxuXHJcbiAgICBjb250YWluZXIub24oJ3Jlc3VsdHM6Zm9jdXMnLCBmdW5jdGlvbiAocGFyYW1zKSB7XHJcbiAgICAgIHBhcmFtcy5lbGVtZW50LmFkZENsYXNzKCdzZWxlY3QyLXJlc3VsdHNfX29wdGlvbi0taGlnaGxpZ2h0ZWQnKTtcclxuICAgIH0pO1xyXG5cclxuICAgIGNvbnRhaW5lci5vbigncmVzdWx0czptZXNzYWdlJywgZnVuY3Rpb24gKHBhcmFtcykge1xyXG4gICAgICBzZWxmLmRpc3BsYXlNZXNzYWdlKHBhcmFtcyk7XHJcbiAgICB9KTtcclxuXHJcbiAgICBpZiAoJC5mbi5tb3VzZXdoZWVsKSB7XHJcbiAgICAgIHRoaXMuJHJlc3VsdHMub24oJ21vdXNld2hlZWwnLCBmdW5jdGlvbiAoZSkge1xyXG4gICAgICAgIHZhciB0b3AgPSBzZWxmLiRyZXN1bHRzLnNjcm9sbFRvcCgpO1xyXG5cclxuICAgICAgICB2YXIgYm90dG9tID0gc2VsZi4kcmVzdWx0cy5nZXQoMCkuc2Nyb2xsSGVpZ2h0IC0gdG9wICsgZS5kZWx0YVk7XHJcblxyXG4gICAgICAgIHZhciBpc0F0VG9wID0gZS5kZWx0YVkgPiAwICYmIHRvcCAtIGUuZGVsdGFZIDw9IDA7XHJcbiAgICAgICAgdmFyIGlzQXRCb3R0b20gPSBlLmRlbHRhWSA8IDAgJiYgYm90dG9tIDw9IHNlbGYuJHJlc3VsdHMuaGVpZ2h0KCk7XHJcblxyXG4gICAgICAgIGlmIChpc0F0VG9wKSB7XHJcbiAgICAgICAgICBzZWxmLiRyZXN1bHRzLnNjcm9sbFRvcCgwKTtcclxuXHJcbiAgICAgICAgICBlLnByZXZlbnREZWZhdWx0KCk7XHJcbiAgICAgICAgICBlLnN0b3BQcm9wYWdhdGlvbigpO1xyXG4gICAgICAgIH0gZWxzZSBpZiAoaXNBdEJvdHRvbSkge1xyXG4gICAgICAgICAgc2VsZi4kcmVzdWx0cy5zY3JvbGxUb3AoXHJcbiAgICAgICAgICAgIHNlbGYuJHJlc3VsdHMuZ2V0KDApLnNjcm9sbEhlaWdodCAtIHNlbGYuJHJlc3VsdHMuaGVpZ2h0KClcclxuICAgICAgICAgICk7XHJcblxyXG4gICAgICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xyXG4gICAgICAgICAgZS5zdG9wUHJvcGFnYXRpb24oKTtcclxuICAgICAgICB9XHJcbiAgICAgIH0pO1xyXG4gICAgfVxyXG5cclxuICAgIHRoaXMuJHJlc3VsdHMub24oJ21vdXNldXAnLCAnLnNlbGVjdDItcmVzdWx0c19fb3B0aW9uW2FyaWEtc2VsZWN0ZWRdJyxcclxuICAgICAgZnVuY3Rpb24gKGV2dCkge1xyXG4gICAgICB2YXIgJHRoaXMgPSAkKHRoaXMpO1xyXG5cclxuICAgICAgdmFyIGRhdGEgPSAkdGhpcy5kYXRhKCdkYXRhJyk7XHJcblxyXG4gICAgICBpZiAoJHRoaXMuYXR0cignYXJpYS1zZWxlY3RlZCcpID09PSAndHJ1ZScpIHtcclxuICAgICAgICBpZiAoc2VsZi5vcHRpb25zLmdldCgnbXVsdGlwbGUnKSkge1xyXG4gICAgICAgICAgc2VsZi50cmlnZ2VyKCd1bnNlbGVjdCcsIHtcclxuICAgICAgICAgICAgb3JpZ2luYWxFdmVudDogZXZ0LFxyXG4gICAgICAgICAgICBkYXRhOiBkYXRhXHJcbiAgICAgICAgICB9KTtcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgc2VsZi50cmlnZ2VyKCdjbG9zZScsIHt9KTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHJldHVybjtcclxuICAgICAgfVxyXG5cclxuICAgICAgc2VsZi50cmlnZ2VyKCdzZWxlY3QnLCB7XHJcbiAgICAgICAgb3JpZ2luYWxFdmVudDogZXZ0LFxyXG4gICAgICAgIGRhdGE6IGRhdGFcclxuICAgICAgfSk7XHJcbiAgICB9KTtcclxuXHJcbiAgICB0aGlzLiRyZXN1bHRzLm9uKCdtb3VzZWVudGVyJywgJy5zZWxlY3QyLXJlc3VsdHNfX29wdGlvblthcmlhLXNlbGVjdGVkXScsXHJcbiAgICAgIGZ1bmN0aW9uIChldnQpIHtcclxuICAgICAgdmFyIGRhdGEgPSAkKHRoaXMpLmRhdGEoJ2RhdGEnKTtcclxuXHJcbiAgICAgIHNlbGYuZ2V0SGlnaGxpZ2h0ZWRSZXN1bHRzKClcclxuICAgICAgICAgIC5yZW1vdmVDbGFzcygnc2VsZWN0Mi1yZXN1bHRzX19vcHRpb24tLWhpZ2hsaWdodGVkJyk7XHJcblxyXG4gICAgICBzZWxmLnRyaWdnZXIoJ3Jlc3VsdHM6Zm9jdXMnLCB7XHJcbiAgICAgICAgZGF0YTogZGF0YSxcclxuICAgICAgICBlbGVtZW50OiAkKHRoaXMpXHJcbiAgICAgIH0pO1xyXG4gICAgfSk7XHJcbiAgfTtcclxuXHJcbiAgUmVzdWx0cy5wcm90b3R5cGUuZ2V0SGlnaGxpZ2h0ZWRSZXN1bHRzID0gZnVuY3Rpb24gKCkge1xyXG4gICAgdmFyICRoaWdobGlnaHRlZCA9IHRoaXMuJHJlc3VsdHNcclxuICAgIC5maW5kKCcuc2VsZWN0Mi1yZXN1bHRzX19vcHRpb24tLWhpZ2hsaWdodGVkJyk7XHJcblxyXG4gICAgcmV0dXJuICRoaWdobGlnaHRlZDtcclxuICB9O1xyXG5cclxuICBSZXN1bHRzLnByb3RvdHlwZS5kZXN0cm95ID0gZnVuY3Rpb24gKCkge1xyXG4gICAgdGhpcy4kcmVzdWx0cy5yZW1vdmUoKTtcclxuICB9O1xyXG5cclxuICBSZXN1bHRzLnByb3RvdHlwZS5lbnN1cmVIaWdobGlnaHRWaXNpYmxlID0gZnVuY3Rpb24gKCkge1xyXG4gICAgdmFyICRoaWdobGlnaHRlZCA9IHRoaXMuZ2V0SGlnaGxpZ2h0ZWRSZXN1bHRzKCk7XHJcblxyXG4gICAgaWYgKCRoaWdobGlnaHRlZC5sZW5ndGggPT09IDApIHtcclxuICAgICAgcmV0dXJuO1xyXG4gICAgfVxyXG5cclxuICAgIHZhciAkb3B0aW9ucyA9IHRoaXMuJHJlc3VsdHMuZmluZCgnW2FyaWEtc2VsZWN0ZWRdJyk7XHJcblxyXG4gICAgdmFyIGN1cnJlbnRJbmRleCA9ICRvcHRpb25zLmluZGV4KCRoaWdobGlnaHRlZCk7XHJcblxyXG4gICAgdmFyIGN1cnJlbnRPZmZzZXQgPSB0aGlzLiRyZXN1bHRzLm9mZnNldCgpLnRvcDtcclxuICAgIHZhciBuZXh0VG9wID0gJGhpZ2hsaWdodGVkLm9mZnNldCgpLnRvcDtcclxuICAgIHZhciBuZXh0T2Zmc2V0ID0gdGhpcy4kcmVzdWx0cy5zY3JvbGxUb3AoKSArIChuZXh0VG9wIC0gY3VycmVudE9mZnNldCk7XHJcblxyXG4gICAgdmFyIG9mZnNldERlbHRhID0gbmV4dFRvcCAtIGN1cnJlbnRPZmZzZXQ7XHJcbiAgICBuZXh0T2Zmc2V0IC09ICRoaWdobGlnaHRlZC5vdXRlckhlaWdodChmYWxzZSkgKiAyO1xyXG5cclxuICAgIGlmIChjdXJyZW50SW5kZXggPD0gMikge1xyXG4gICAgICB0aGlzLiRyZXN1bHRzLnNjcm9sbFRvcCgwKTtcclxuICAgIH0gZWxzZSBpZiAob2Zmc2V0RGVsdGEgPiB0aGlzLiRyZXN1bHRzLm91dGVySGVpZ2h0KCkgfHwgb2Zmc2V0RGVsdGEgPCAwKSB7XHJcbiAgICAgIHRoaXMuJHJlc3VsdHMuc2Nyb2xsVG9wKG5leHRPZmZzZXQpO1xyXG4gICAgfVxyXG4gIH07XHJcblxyXG4gIFJlc3VsdHMucHJvdG90eXBlLnRlbXBsYXRlID0gZnVuY3Rpb24gKHJlc3VsdCwgY29udGFpbmVyKSB7XHJcbiAgICB2YXIgdGVtcGxhdGUgPSB0aGlzLm9wdGlvbnMuZ2V0KCd0ZW1wbGF0ZVJlc3VsdCcpO1xyXG4gICAgdmFyIGVzY2FwZU1hcmt1cCA9IHRoaXMub3B0aW9ucy5nZXQoJ2VzY2FwZU1hcmt1cCcpO1xyXG5cclxuICAgIHZhciBjb250ZW50ID0gdGVtcGxhdGUocmVzdWx0LCBjb250YWluZXIpO1xyXG5cclxuICAgIGlmIChjb250ZW50ID09IG51bGwpIHtcclxuICAgICAgY29udGFpbmVyLnN0eWxlLmRpc3BsYXkgPSAnbm9uZSc7XHJcbiAgICB9IGVsc2UgaWYgKHR5cGVvZiBjb250ZW50ID09PSAnc3RyaW5nJykge1xyXG4gICAgICBjb250YWluZXIuaW5uZXJIVE1MID0gZXNjYXBlTWFya3VwKGNvbnRlbnQpO1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgJChjb250YWluZXIpLmFwcGVuZChjb250ZW50KTtcclxuICAgIH1cclxuICB9O1xyXG5cclxuICByZXR1cm4gUmVzdWx0cztcclxufSk7XHJcblxuUzIuZGVmaW5lKCdzZWxlY3QyL2tleXMnLFtcclxuXHJcbl0sIGZ1bmN0aW9uICgpIHtcclxuICB2YXIgS0VZUyA9IHtcclxuICAgIEJBQ0tTUEFDRTogOCxcclxuICAgIFRBQjogOSxcclxuICAgIEVOVEVSOiAxMyxcclxuICAgIFNISUZUOiAxNixcclxuICAgIENUUkw6IDE3LFxyXG4gICAgQUxUOiAxOCxcclxuICAgIEVTQzogMjcsXHJcbiAgICBTUEFDRTogMzIsXHJcbiAgICBQQUdFX1VQOiAzMyxcclxuICAgIFBBR0VfRE9XTjogMzQsXHJcbiAgICBFTkQ6IDM1LFxyXG4gICAgSE9NRTogMzYsXHJcbiAgICBMRUZUOiAzNyxcclxuICAgIFVQOiAzOCxcclxuICAgIFJJR0hUOiAzOSxcclxuICAgIERPV046IDQwLFxyXG4gICAgREVMRVRFOiA0NlxyXG4gIH07XHJcblxyXG4gIHJldHVybiBLRVlTO1xyXG59KTtcclxuXG5TMi5kZWZpbmUoJ3NlbGVjdDIvc2VsZWN0aW9uL2Jhc2UnLFtcclxuICAnanF1ZXJ5JyxcclxuICAnLi4vdXRpbHMnLFxyXG4gICcuLi9rZXlzJ1xyXG5dLCBmdW5jdGlvbiAoJCwgVXRpbHMsIEtFWVMpIHtcclxuICBmdW5jdGlvbiBCYXNlU2VsZWN0aW9uICgkZWxlbWVudCwgb3B0aW9ucykge1xyXG4gICAgdGhpcy4kZWxlbWVudCA9ICRlbGVtZW50O1xyXG4gICAgdGhpcy5vcHRpb25zID0gb3B0aW9ucztcclxuXHJcbiAgICBCYXNlU2VsZWN0aW9uLl9fc3VwZXJfXy5jb25zdHJ1Y3Rvci5jYWxsKHRoaXMpO1xyXG4gIH1cclxuXHJcbiAgVXRpbHMuRXh0ZW5kKEJhc2VTZWxlY3Rpb24sIFV0aWxzLk9ic2VydmFibGUpO1xyXG5cclxuICBCYXNlU2VsZWN0aW9uLnByb3RvdHlwZS5yZW5kZXIgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICB2YXIgJHNlbGVjdGlvbiA9ICQoXHJcbiAgICAgICc8c3BhbiBjbGFzcz1cInNlbGVjdDItc2VsZWN0aW9uXCIgcm9sZT1cImNvbWJvYm94XCIgJyArXHJcbiAgICAgICcgYXJpYS1oYXNwb3B1cD1cInRydWVcIiBhcmlhLWV4cGFuZGVkPVwiZmFsc2VcIj4nICtcclxuICAgICAgJzwvc3Bhbj4nXHJcbiAgICApO1xyXG5cclxuICAgIHRoaXMuX3RhYmluZGV4ID0gMDtcclxuXHJcbiAgICBpZiAodGhpcy4kZWxlbWVudC5kYXRhKCdvbGQtdGFiaW5kZXgnKSAhPSBudWxsKSB7XHJcbiAgICAgIHRoaXMuX3RhYmluZGV4ID0gdGhpcy4kZWxlbWVudC5kYXRhKCdvbGQtdGFiaW5kZXgnKTtcclxuICAgIH0gZWxzZSBpZiAodGhpcy4kZWxlbWVudC5hdHRyKCd0YWJpbmRleCcpICE9IG51bGwpIHtcclxuICAgICAgdGhpcy5fdGFiaW5kZXggPSB0aGlzLiRlbGVtZW50LmF0dHIoJ3RhYmluZGV4Jyk7XHJcbiAgICB9XHJcblxyXG4gICAgJHNlbGVjdGlvbi5hdHRyKCd0aXRsZScsIHRoaXMuJGVsZW1lbnQuYXR0cigndGl0bGUnKSk7XHJcbiAgICAkc2VsZWN0aW9uLmF0dHIoJ3RhYmluZGV4JywgdGhpcy5fdGFiaW5kZXgpO1xyXG5cclxuICAgIHRoaXMuJHNlbGVjdGlvbiA9ICRzZWxlY3Rpb247XHJcblxyXG4gICAgcmV0dXJuICRzZWxlY3Rpb247XHJcbiAgfTtcclxuXHJcbiAgQmFzZVNlbGVjdGlvbi5wcm90b3R5cGUuYmluZCA9IGZ1bmN0aW9uIChjb250YWluZXIsICRjb250YWluZXIpIHtcclxuICAgIHZhciBzZWxmID0gdGhpcztcclxuXHJcbiAgICB2YXIgaWQgPSBjb250YWluZXIuaWQgKyAnLWNvbnRhaW5lcic7XHJcbiAgICB2YXIgcmVzdWx0c0lkID0gY29udGFpbmVyLmlkICsgJy1yZXN1bHRzJztcclxuXHJcbiAgICB0aGlzLmNvbnRhaW5lciA9IGNvbnRhaW5lcjtcclxuXHJcbiAgICB0aGlzLiRzZWxlY3Rpb24ub24oJ2ZvY3VzJywgZnVuY3Rpb24gKGV2dCkge1xyXG4gICAgICBzZWxmLnRyaWdnZXIoJ2ZvY3VzJywgZXZ0KTtcclxuICAgIH0pO1xyXG5cclxuICAgIHRoaXMuJHNlbGVjdGlvbi5vbignYmx1cicsIGZ1bmN0aW9uIChldnQpIHtcclxuICAgICAgc2VsZi5faGFuZGxlQmx1cihldnQpO1xyXG4gICAgfSk7XHJcblxyXG4gICAgdGhpcy4kc2VsZWN0aW9uLm9uKCdrZXlkb3duJywgZnVuY3Rpb24gKGV2dCkge1xyXG4gICAgICBzZWxmLnRyaWdnZXIoJ2tleXByZXNzJywgZXZ0KTtcclxuXHJcbiAgICAgIGlmIChldnQud2hpY2ggPT09IEtFWVMuU1BBQ0UpIHtcclxuICAgICAgICBldnQucHJldmVudERlZmF1bHQoKTtcclxuICAgICAgfVxyXG4gICAgfSk7XHJcblxyXG4gICAgY29udGFpbmVyLm9uKCdyZXN1bHRzOmZvY3VzJywgZnVuY3Rpb24gKHBhcmFtcykge1xyXG4gICAgICBzZWxmLiRzZWxlY3Rpb24uYXR0cignYXJpYS1hY3RpdmVkZXNjZW5kYW50JywgcGFyYW1zLmRhdGEuX3Jlc3VsdElkKTtcclxuICAgIH0pO1xyXG5cclxuICAgIGNvbnRhaW5lci5vbignc2VsZWN0aW9uOnVwZGF0ZScsIGZ1bmN0aW9uIChwYXJhbXMpIHtcclxuICAgICAgc2VsZi51cGRhdGUocGFyYW1zLmRhdGEpO1xyXG4gICAgfSk7XHJcblxyXG4gICAgY29udGFpbmVyLm9uKCdvcGVuJywgZnVuY3Rpb24gKCkge1xyXG4gICAgICAvLyBXaGVuIHRoZSBkcm9wZG93biBpcyBvcGVuLCBhcmlhLWV4cGFuZGVkPVwidHJ1ZVwiXHJcbiAgICAgIHNlbGYuJHNlbGVjdGlvbi5hdHRyKCdhcmlhLWV4cGFuZGVkJywgJ3RydWUnKTtcclxuICAgICAgc2VsZi4kc2VsZWN0aW9uLmF0dHIoJ2FyaWEtb3ducycsIHJlc3VsdHNJZCk7XHJcblxyXG4gICAgICBzZWxmLl9hdHRhY2hDbG9zZUhhbmRsZXIoY29udGFpbmVyKTtcclxuICAgIH0pO1xyXG5cclxuICAgIGNvbnRhaW5lci5vbignY2xvc2UnLCBmdW5jdGlvbiAoKSB7XHJcbiAgICAgIC8vIFdoZW4gdGhlIGRyb3Bkb3duIGlzIGNsb3NlZCwgYXJpYS1leHBhbmRlZD1cImZhbHNlXCJcclxuICAgICAgc2VsZi4kc2VsZWN0aW9uLmF0dHIoJ2FyaWEtZXhwYW5kZWQnLCAnZmFsc2UnKTtcclxuICAgICAgc2VsZi4kc2VsZWN0aW9uLnJlbW92ZUF0dHIoJ2FyaWEtYWN0aXZlZGVzY2VuZGFudCcpO1xyXG4gICAgICBzZWxmLiRzZWxlY3Rpb24ucmVtb3ZlQXR0cignYXJpYS1vd25zJyk7XHJcblxyXG4gICAgICBzZWxmLiRzZWxlY3Rpb24uZm9jdXMoKTtcclxuXHJcbiAgICAgIHNlbGYuX2RldGFjaENsb3NlSGFuZGxlcihjb250YWluZXIpO1xyXG4gICAgfSk7XHJcblxyXG4gICAgY29udGFpbmVyLm9uKCdlbmFibGUnLCBmdW5jdGlvbiAoKSB7XHJcbiAgICAgIHNlbGYuJHNlbGVjdGlvbi5hdHRyKCd0YWJpbmRleCcsIHNlbGYuX3RhYmluZGV4KTtcclxuICAgIH0pO1xyXG5cclxuICAgIGNvbnRhaW5lci5vbignZGlzYWJsZScsIGZ1bmN0aW9uICgpIHtcclxuICAgICAgc2VsZi4kc2VsZWN0aW9uLmF0dHIoJ3RhYmluZGV4JywgJy0xJyk7XHJcbiAgICB9KTtcclxuICB9O1xyXG5cclxuICBCYXNlU2VsZWN0aW9uLnByb3RvdHlwZS5faGFuZGxlQmx1ciA9IGZ1bmN0aW9uIChldnQpIHtcclxuICAgIHZhciBzZWxmID0gdGhpcztcclxuXHJcbiAgICAvLyBUaGlzIG5lZWRzIHRvIGJlIGRlbGF5ZWQgYXMgdGhlIGFjdGl2ZSBlbGVtZW50IGlzIHRoZSBib2R5IHdoZW4gdGhlIHRhYlxyXG4gICAgLy8ga2V5IGlzIHByZXNzZWQsIHBvc3NpYmx5IGFsb25nIHdpdGggb3RoZXJzLlxyXG4gICAgd2luZG93LnNldFRpbWVvdXQoZnVuY3Rpb24gKCkge1xyXG4gICAgICAvLyBEb24ndCB0cmlnZ2VyIGBibHVyYCBpZiB0aGUgZm9jdXMgaXMgc3RpbGwgaW4gdGhlIHNlbGVjdGlvblxyXG4gICAgICBpZiAoXHJcbiAgICAgICAgKGRvY3VtZW50LmFjdGl2ZUVsZW1lbnQgPT0gc2VsZi4kc2VsZWN0aW9uWzBdKSB8fFxyXG4gICAgICAgICgkLmNvbnRhaW5zKHNlbGYuJHNlbGVjdGlvblswXSwgZG9jdW1lbnQuYWN0aXZlRWxlbWVudCkpXHJcbiAgICAgICkge1xyXG4gICAgICAgIHJldHVybjtcclxuICAgICAgfVxyXG5cclxuICAgICAgc2VsZi50cmlnZ2VyKCdibHVyJywgZXZ0KTtcclxuICAgIH0sIDEpO1xyXG4gIH07XHJcblxyXG4gIEJhc2VTZWxlY3Rpb24ucHJvdG90eXBlLl9hdHRhY2hDbG9zZUhhbmRsZXIgPSBmdW5jdGlvbiAoY29udGFpbmVyKSB7XHJcbiAgICB2YXIgc2VsZiA9IHRoaXM7XHJcblxyXG4gICAgJChkb2N1bWVudC5ib2R5KS5vbignbW91c2Vkb3duLnNlbGVjdDIuJyArIGNvbnRhaW5lci5pZCwgZnVuY3Rpb24gKGUpIHtcclxuICAgICAgdmFyICR0YXJnZXQgPSAkKGUudGFyZ2V0KTtcclxuXHJcbiAgICAgIHZhciAkc2VsZWN0ID0gJHRhcmdldC5jbG9zZXN0KCcuc2VsZWN0MicpO1xyXG5cclxuICAgICAgdmFyICRhbGwgPSAkKCcuc2VsZWN0Mi5zZWxlY3QyLWNvbnRhaW5lci0tb3BlbicpO1xyXG5cclxuICAgICAgJGFsbC5lYWNoKGZ1bmN0aW9uICgpIHtcclxuICAgICAgICB2YXIgJHRoaXMgPSAkKHRoaXMpO1xyXG5cclxuICAgICAgICBpZiAodGhpcyA9PSAkc2VsZWN0WzBdKSB7XHJcbiAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICB2YXIgJGVsZW1lbnQgPSAkdGhpcy5kYXRhKCdlbGVtZW50Jyk7XHJcblxyXG4gICAgICAgICRlbGVtZW50LnNlbGVjdDIoJ2Nsb3NlJyk7XHJcbiAgICAgIH0pO1xyXG4gICAgfSk7XHJcbiAgfTtcclxuXHJcbiAgQmFzZVNlbGVjdGlvbi5wcm90b3R5cGUuX2RldGFjaENsb3NlSGFuZGxlciA9IGZ1bmN0aW9uIChjb250YWluZXIpIHtcclxuICAgICQoZG9jdW1lbnQuYm9keSkub2ZmKCdtb3VzZWRvd24uc2VsZWN0Mi4nICsgY29udGFpbmVyLmlkKTtcclxuICB9O1xyXG5cclxuICBCYXNlU2VsZWN0aW9uLnByb3RvdHlwZS5wb3NpdGlvbiA9IGZ1bmN0aW9uICgkc2VsZWN0aW9uLCAkY29udGFpbmVyKSB7XHJcbiAgICB2YXIgJHNlbGVjdGlvbkNvbnRhaW5lciA9ICRjb250YWluZXIuZmluZCgnLnNlbGVjdGlvbicpO1xyXG4gICAgJHNlbGVjdGlvbkNvbnRhaW5lci5hcHBlbmQoJHNlbGVjdGlvbik7XHJcbiAgfTtcclxuXHJcbiAgQmFzZVNlbGVjdGlvbi5wcm90b3R5cGUuZGVzdHJveSA9IGZ1bmN0aW9uICgpIHtcclxuICAgIHRoaXMuX2RldGFjaENsb3NlSGFuZGxlcih0aGlzLmNvbnRhaW5lcik7XHJcbiAgfTtcclxuXHJcbiAgQmFzZVNlbGVjdGlvbi5wcm90b3R5cGUudXBkYXRlID0gZnVuY3Rpb24gKGRhdGEpIHtcclxuICAgIHRocm93IG5ldyBFcnJvcignVGhlIGB1cGRhdGVgIG1ldGhvZCBtdXN0IGJlIGRlZmluZWQgaW4gY2hpbGQgY2xhc3Nlcy4nKTtcclxuICB9O1xyXG5cclxuICByZXR1cm4gQmFzZVNlbGVjdGlvbjtcclxufSk7XHJcblxuUzIuZGVmaW5lKCdzZWxlY3QyL3NlbGVjdGlvbi9zaW5nbGUnLFtcclxuICAnanF1ZXJ5JyxcclxuICAnLi9iYXNlJyxcclxuICAnLi4vdXRpbHMnLFxyXG4gICcuLi9rZXlzJ1xyXG5dLCBmdW5jdGlvbiAoJCwgQmFzZVNlbGVjdGlvbiwgVXRpbHMsIEtFWVMpIHtcclxuICBmdW5jdGlvbiBTaW5nbGVTZWxlY3Rpb24gKCkge1xyXG4gICAgU2luZ2xlU2VsZWN0aW9uLl9fc3VwZXJfXy5jb25zdHJ1Y3Rvci5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xyXG4gIH1cclxuXHJcbiAgVXRpbHMuRXh0ZW5kKFNpbmdsZVNlbGVjdGlvbiwgQmFzZVNlbGVjdGlvbik7XHJcblxyXG4gIFNpbmdsZVNlbGVjdGlvbi5wcm90b3R5cGUucmVuZGVyID0gZnVuY3Rpb24gKCkge1xyXG4gICAgdmFyICRzZWxlY3Rpb24gPSBTaW5nbGVTZWxlY3Rpb24uX19zdXBlcl9fLnJlbmRlci5jYWxsKHRoaXMpO1xyXG5cclxuICAgICRzZWxlY3Rpb24uYWRkQ2xhc3MoJ3NlbGVjdDItc2VsZWN0aW9uLS1zaW5nbGUnKTtcclxuXHJcbiAgICAkc2VsZWN0aW9uLmh0bWwoXHJcbiAgICAgICc8c3BhbiBjbGFzcz1cInNlbGVjdDItc2VsZWN0aW9uX19yZW5kZXJlZFwiPjwvc3Bhbj4nICtcclxuICAgICAgJzxzcGFuIGNsYXNzPVwic2VsZWN0Mi1zZWxlY3Rpb25fX2Fycm93XCIgcm9sZT1cInByZXNlbnRhdGlvblwiPicgK1xyXG4gICAgICAgICc8YiByb2xlPVwicHJlc2VudGF0aW9uXCI+PC9iPicgK1xyXG4gICAgICAnPC9zcGFuPidcclxuICAgICk7XHJcblxyXG4gICAgcmV0dXJuICRzZWxlY3Rpb247XHJcbiAgfTtcclxuXHJcbiAgU2luZ2xlU2VsZWN0aW9uLnByb3RvdHlwZS5iaW5kID0gZnVuY3Rpb24gKGNvbnRhaW5lciwgJGNvbnRhaW5lcikge1xyXG4gICAgdmFyIHNlbGYgPSB0aGlzO1xyXG5cclxuICAgIFNpbmdsZVNlbGVjdGlvbi5fX3N1cGVyX18uYmluZC5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xyXG5cclxuICAgIHZhciBpZCA9IGNvbnRhaW5lci5pZCArICctY29udGFpbmVyJztcclxuXHJcbiAgICB0aGlzLiRzZWxlY3Rpb24uZmluZCgnLnNlbGVjdDItc2VsZWN0aW9uX19yZW5kZXJlZCcpLmF0dHIoJ2lkJywgaWQpO1xyXG4gICAgdGhpcy4kc2VsZWN0aW9uLmF0dHIoJ2FyaWEtbGFiZWxsZWRieScsIGlkKTtcclxuXHJcbiAgICB0aGlzLiRzZWxlY3Rpb24ub24oJ21vdXNlZG93bicsIGZ1bmN0aW9uIChldnQpIHtcclxuICAgICAgLy8gT25seSByZXNwb25kIHRvIGxlZnQgY2xpY2tzXHJcbiAgICAgIGlmIChldnQud2hpY2ggIT09IDEpIHtcclxuICAgICAgICByZXR1cm47XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIHNlbGYudHJpZ2dlcigndG9nZ2xlJywge1xyXG4gICAgICAgIG9yaWdpbmFsRXZlbnQ6IGV2dFxyXG4gICAgICB9KTtcclxuICAgIH0pO1xyXG5cclxuICAgIHRoaXMuJHNlbGVjdGlvbi5vbignZm9jdXMnLCBmdW5jdGlvbiAoZXZ0KSB7XHJcbiAgICAgIC8vIFVzZXIgZm9jdXNlcyBvbiB0aGUgY29udGFpbmVyXHJcbiAgICB9KTtcclxuXHJcbiAgICB0aGlzLiRzZWxlY3Rpb24ub24oJ2JsdXInLCBmdW5jdGlvbiAoZXZ0KSB7XHJcbiAgICAgIC8vIFVzZXIgZXhpdHMgdGhlIGNvbnRhaW5lclxyXG4gICAgfSk7XHJcblxyXG4gICAgY29udGFpbmVyLm9uKCdmb2N1cycsIGZ1bmN0aW9uIChldnQpIHtcclxuICAgICAgaWYgKCFjb250YWluZXIuaXNPcGVuKCkpIHtcclxuICAgICAgICBzZWxmLiRzZWxlY3Rpb24uZm9jdXMoKTtcclxuICAgICAgfVxyXG4gICAgfSk7XHJcblxyXG4gICAgY29udGFpbmVyLm9uKCdzZWxlY3Rpb246dXBkYXRlJywgZnVuY3Rpb24gKHBhcmFtcykge1xyXG4gICAgICBzZWxmLnVwZGF0ZShwYXJhbXMuZGF0YSk7XHJcbiAgICB9KTtcclxuICB9O1xyXG5cclxuICBTaW5nbGVTZWxlY3Rpb24ucHJvdG90eXBlLmNsZWFyID0gZnVuY3Rpb24gKCkge1xyXG4gICAgdGhpcy4kc2VsZWN0aW9uLmZpbmQoJy5zZWxlY3QyLXNlbGVjdGlvbl9fcmVuZGVyZWQnKS5lbXB0eSgpO1xyXG4gIH07XHJcblxyXG4gIFNpbmdsZVNlbGVjdGlvbi5wcm90b3R5cGUuZGlzcGxheSA9IGZ1bmN0aW9uIChkYXRhLCBjb250YWluZXIpIHtcclxuICAgIHZhciB0ZW1wbGF0ZSA9IHRoaXMub3B0aW9ucy5nZXQoJ3RlbXBsYXRlU2VsZWN0aW9uJyk7XHJcbiAgICB2YXIgZXNjYXBlTWFya3VwID0gdGhpcy5vcHRpb25zLmdldCgnZXNjYXBlTWFya3VwJyk7XHJcblxyXG4gICAgcmV0dXJuIGVzY2FwZU1hcmt1cCh0ZW1wbGF0ZShkYXRhLCBjb250YWluZXIpKTtcclxuICB9O1xyXG5cclxuICBTaW5nbGVTZWxlY3Rpb24ucHJvdG90eXBlLnNlbGVjdGlvbkNvbnRhaW5lciA9IGZ1bmN0aW9uICgpIHtcclxuICAgIHJldHVybiAkKCc8c3Bhbj48L3NwYW4+Jyk7XHJcbiAgfTtcclxuXHJcbiAgU2luZ2xlU2VsZWN0aW9uLnByb3RvdHlwZS51cGRhdGUgPSBmdW5jdGlvbiAoZGF0YSkge1xyXG4gICAgaWYgKGRhdGEubGVuZ3RoID09PSAwKSB7XHJcbiAgICAgIHRoaXMuY2xlYXIoKTtcclxuICAgICAgcmV0dXJuO1xyXG4gICAgfVxyXG5cclxuICAgIHZhciBzZWxlY3Rpb24gPSBkYXRhWzBdO1xyXG5cclxuICAgIHZhciAkcmVuZGVyZWQgPSB0aGlzLiRzZWxlY3Rpb24uZmluZCgnLnNlbGVjdDItc2VsZWN0aW9uX19yZW5kZXJlZCcpO1xyXG4gICAgdmFyIGZvcm1hdHRlZCA9IHRoaXMuZGlzcGxheShzZWxlY3Rpb24sICRyZW5kZXJlZCk7XHJcblxyXG4gICAgJHJlbmRlcmVkLmVtcHR5KCkuYXBwZW5kKGZvcm1hdHRlZCk7XHJcbiAgICAkcmVuZGVyZWQucHJvcCgndGl0bGUnLCBzZWxlY3Rpb24udGl0bGUgfHwgc2VsZWN0aW9uLnRleHQpO1xyXG4gIH07XHJcblxyXG4gIHJldHVybiBTaW5nbGVTZWxlY3Rpb247XHJcbn0pO1xyXG5cblMyLmRlZmluZSgnc2VsZWN0Mi9zZWxlY3Rpb24vbXVsdGlwbGUnLFtcclxuICAnanF1ZXJ5JyxcclxuICAnLi9iYXNlJyxcclxuICAnLi4vdXRpbHMnXHJcbl0sIGZ1bmN0aW9uICgkLCBCYXNlU2VsZWN0aW9uLCBVdGlscykge1xyXG4gIGZ1bmN0aW9uIE11bHRpcGxlU2VsZWN0aW9uICgkZWxlbWVudCwgb3B0aW9ucykge1xyXG4gICAgTXVsdGlwbGVTZWxlY3Rpb24uX19zdXBlcl9fLmNvbnN0cnVjdG9yLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XHJcbiAgfVxyXG5cclxuICBVdGlscy5FeHRlbmQoTXVsdGlwbGVTZWxlY3Rpb24sIEJhc2VTZWxlY3Rpb24pO1xyXG5cclxuICBNdWx0aXBsZVNlbGVjdGlvbi5wcm90b3R5cGUucmVuZGVyID0gZnVuY3Rpb24gKCkge1xyXG4gICAgdmFyICRzZWxlY3Rpb24gPSBNdWx0aXBsZVNlbGVjdGlvbi5fX3N1cGVyX18ucmVuZGVyLmNhbGwodGhpcyk7XHJcblxyXG4gICAgJHNlbGVjdGlvbi5hZGRDbGFzcygnc2VsZWN0Mi1zZWxlY3Rpb24tLW11bHRpcGxlJyk7XHJcblxyXG4gICAgJHNlbGVjdGlvbi5odG1sKFxyXG4gICAgICAnPHVsIGNsYXNzPVwic2VsZWN0Mi1zZWxlY3Rpb25fX3JlbmRlcmVkXCI+PC91bD4nXHJcbiAgICApO1xyXG5cclxuICAgIHJldHVybiAkc2VsZWN0aW9uO1xyXG4gIH07XHJcblxyXG4gIE11bHRpcGxlU2VsZWN0aW9uLnByb3RvdHlwZS5iaW5kID0gZnVuY3Rpb24gKGNvbnRhaW5lciwgJGNvbnRhaW5lcikge1xyXG4gICAgdmFyIHNlbGYgPSB0aGlzO1xyXG5cclxuICAgIE11bHRpcGxlU2VsZWN0aW9uLl9fc3VwZXJfXy5iaW5kLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XHJcblxyXG4gICAgdGhpcy4kc2VsZWN0aW9uLm9uKCdjbGljaycsIGZ1bmN0aW9uIChldnQpIHtcclxuICAgICAgc2VsZi50cmlnZ2VyKCd0b2dnbGUnLCB7XHJcbiAgICAgICAgb3JpZ2luYWxFdmVudDogZXZ0XHJcbiAgICAgIH0pO1xyXG4gICAgfSk7XHJcblxyXG4gICAgdGhpcy4kc2VsZWN0aW9uLm9uKFxyXG4gICAgICAnY2xpY2snLFxyXG4gICAgICAnLnNlbGVjdDItc2VsZWN0aW9uX19jaG9pY2VfX3JlbW92ZScsXHJcbiAgICAgIGZ1bmN0aW9uIChldnQpIHtcclxuICAgICAgICAvLyBJZ25vcmUgdGhlIGV2ZW50IGlmIGl0IGlzIGRpc2FibGVkXHJcbiAgICAgICAgaWYgKHNlbGYub3B0aW9ucy5nZXQoJ2Rpc2FibGVkJykpIHtcclxuICAgICAgICAgIHJldHVybjtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHZhciAkcmVtb3ZlID0gJCh0aGlzKTtcclxuICAgICAgICB2YXIgJHNlbGVjdGlvbiA9ICRyZW1vdmUucGFyZW50KCk7XHJcblxyXG4gICAgICAgIHZhciBkYXRhID0gJHNlbGVjdGlvbi5kYXRhKCdkYXRhJyk7XHJcblxyXG4gICAgICAgIHNlbGYudHJpZ2dlcigndW5zZWxlY3QnLCB7XHJcbiAgICAgICAgICBvcmlnaW5hbEV2ZW50OiBldnQsXHJcbiAgICAgICAgICBkYXRhOiBkYXRhXHJcbiAgICAgICAgfSk7XHJcbiAgICAgIH1cclxuICAgICk7XHJcbiAgfTtcclxuXHJcbiAgTXVsdGlwbGVTZWxlY3Rpb24ucHJvdG90eXBlLmNsZWFyID0gZnVuY3Rpb24gKCkge1xyXG4gICAgdGhpcy4kc2VsZWN0aW9uLmZpbmQoJy5zZWxlY3QyLXNlbGVjdGlvbl9fcmVuZGVyZWQnKS5lbXB0eSgpO1xyXG4gIH07XHJcblxyXG4gIE11bHRpcGxlU2VsZWN0aW9uLnByb3RvdHlwZS5kaXNwbGF5ID0gZnVuY3Rpb24gKGRhdGEsIGNvbnRhaW5lcikge1xyXG4gICAgdmFyIHRlbXBsYXRlID0gdGhpcy5vcHRpb25zLmdldCgndGVtcGxhdGVTZWxlY3Rpb24nKTtcclxuICAgIHZhciBlc2NhcGVNYXJrdXAgPSB0aGlzLm9wdGlvbnMuZ2V0KCdlc2NhcGVNYXJrdXAnKTtcclxuXHJcbiAgICByZXR1cm4gZXNjYXBlTWFya3VwKHRlbXBsYXRlKGRhdGEsIGNvbnRhaW5lcikpO1xyXG4gIH07XHJcblxyXG4gIE11bHRpcGxlU2VsZWN0aW9uLnByb3RvdHlwZS5zZWxlY3Rpb25Db250YWluZXIgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICB2YXIgJGNvbnRhaW5lciA9ICQoXHJcbiAgICAgICc8bGkgY2xhc3M9XCJzZWxlY3QyLXNlbGVjdGlvbl9fY2hvaWNlXCI+JyArXHJcbiAgICAgICAgJzxzcGFuIGNsYXNzPVwic2VsZWN0Mi1zZWxlY3Rpb25fX2Nob2ljZV9fcmVtb3ZlXCIgcm9sZT1cInByZXNlbnRhdGlvblwiPicgK1xyXG4gICAgICAgICAgJyZ0aW1lczsnICtcclxuICAgICAgICAnPC9zcGFuPicgK1xyXG4gICAgICAnPC9saT4nXHJcbiAgICApO1xyXG5cclxuICAgIHJldHVybiAkY29udGFpbmVyO1xyXG4gIH07XHJcblxyXG4gIE11bHRpcGxlU2VsZWN0aW9uLnByb3RvdHlwZS51cGRhdGUgPSBmdW5jdGlvbiAoZGF0YSkge1xyXG4gICAgdGhpcy5jbGVhcigpO1xyXG5cclxuICAgIGlmIChkYXRhLmxlbmd0aCA9PT0gMCkge1xyXG4gICAgICByZXR1cm47XHJcbiAgICB9XHJcblxyXG4gICAgdmFyICRzZWxlY3Rpb25zID0gW107XHJcblxyXG4gICAgZm9yICh2YXIgZCA9IDA7IGQgPCBkYXRhLmxlbmd0aDsgZCsrKSB7XHJcbiAgICAgIHZhciBzZWxlY3Rpb24gPSBkYXRhW2RdO1xyXG5cclxuICAgICAgdmFyICRzZWxlY3Rpb24gPSB0aGlzLnNlbGVjdGlvbkNvbnRhaW5lcigpO1xyXG4gICAgICB2YXIgZm9ybWF0dGVkID0gdGhpcy5kaXNwbGF5KHNlbGVjdGlvbiwgJHNlbGVjdGlvbik7XHJcblxyXG4gICAgICAkc2VsZWN0aW9uLmFwcGVuZChmb3JtYXR0ZWQpO1xyXG4gICAgICAkc2VsZWN0aW9uLnByb3AoJ3RpdGxlJywgc2VsZWN0aW9uLnRpdGxlIHx8IHNlbGVjdGlvbi50ZXh0KTtcclxuXHJcbiAgICAgICRzZWxlY3Rpb24uZGF0YSgnZGF0YScsIHNlbGVjdGlvbik7XHJcblxyXG4gICAgICAkc2VsZWN0aW9ucy5wdXNoKCRzZWxlY3Rpb24pO1xyXG4gICAgfVxyXG5cclxuICAgIHZhciAkcmVuZGVyZWQgPSB0aGlzLiRzZWxlY3Rpb24uZmluZCgnLnNlbGVjdDItc2VsZWN0aW9uX19yZW5kZXJlZCcpO1xyXG5cclxuICAgIFV0aWxzLmFwcGVuZE1hbnkoJHJlbmRlcmVkLCAkc2VsZWN0aW9ucyk7XHJcbiAgfTtcclxuXHJcbiAgcmV0dXJuIE11bHRpcGxlU2VsZWN0aW9uO1xyXG59KTtcclxuXG5TMi5kZWZpbmUoJ3NlbGVjdDIvc2VsZWN0aW9uL3BsYWNlaG9sZGVyJyxbXHJcbiAgJy4uL3V0aWxzJ1xyXG5dLCBmdW5jdGlvbiAoVXRpbHMpIHtcclxuICBmdW5jdGlvbiBQbGFjZWhvbGRlciAoZGVjb3JhdGVkLCAkZWxlbWVudCwgb3B0aW9ucykge1xyXG4gICAgdGhpcy5wbGFjZWhvbGRlciA9IHRoaXMubm9ybWFsaXplUGxhY2Vob2xkZXIob3B0aW9ucy5nZXQoJ3BsYWNlaG9sZGVyJykpO1xyXG5cclxuICAgIGRlY29yYXRlZC5jYWxsKHRoaXMsICRlbGVtZW50LCBvcHRpb25zKTtcclxuICB9XHJcblxyXG4gIFBsYWNlaG9sZGVyLnByb3RvdHlwZS5ub3JtYWxpemVQbGFjZWhvbGRlciA9IGZ1bmN0aW9uIChfLCBwbGFjZWhvbGRlcikge1xyXG4gICAgaWYgKHR5cGVvZiBwbGFjZWhvbGRlciA9PT0gJ3N0cmluZycpIHtcclxuICAgICAgcGxhY2Vob2xkZXIgPSB7XHJcbiAgICAgICAgaWQ6ICcnLFxyXG4gICAgICAgIHRleHQ6IHBsYWNlaG9sZGVyXHJcbiAgICAgIH07XHJcbiAgICB9XHJcblxyXG4gICAgcmV0dXJuIHBsYWNlaG9sZGVyO1xyXG4gIH07XHJcblxyXG4gIFBsYWNlaG9sZGVyLnByb3RvdHlwZS5jcmVhdGVQbGFjZWhvbGRlciA9IGZ1bmN0aW9uIChkZWNvcmF0ZWQsIHBsYWNlaG9sZGVyKSB7XHJcbiAgICB2YXIgJHBsYWNlaG9sZGVyID0gdGhpcy5zZWxlY3Rpb25Db250YWluZXIoKTtcclxuXHJcbiAgICAkcGxhY2Vob2xkZXIuaHRtbCh0aGlzLmRpc3BsYXkocGxhY2Vob2xkZXIpKTtcclxuICAgICRwbGFjZWhvbGRlci5hZGRDbGFzcygnc2VsZWN0Mi1zZWxlY3Rpb25fX3BsYWNlaG9sZGVyJylcclxuICAgICAgICAgICAgICAgIC5yZW1vdmVDbGFzcygnc2VsZWN0Mi1zZWxlY3Rpb25fX2Nob2ljZScpO1xyXG5cclxuICAgIHJldHVybiAkcGxhY2Vob2xkZXI7XHJcbiAgfTtcclxuXHJcbiAgUGxhY2Vob2xkZXIucHJvdG90eXBlLnVwZGF0ZSA9IGZ1bmN0aW9uIChkZWNvcmF0ZWQsIGRhdGEpIHtcclxuICAgIHZhciBzaW5nbGVQbGFjZWhvbGRlciA9IChcclxuICAgICAgZGF0YS5sZW5ndGggPT0gMSAmJiBkYXRhWzBdLmlkICE9IHRoaXMucGxhY2Vob2xkZXIuaWRcclxuICAgICk7XHJcbiAgICB2YXIgbXVsdGlwbGVTZWxlY3Rpb25zID0gZGF0YS5sZW5ndGggPiAxO1xyXG5cclxuICAgIGlmIChtdWx0aXBsZVNlbGVjdGlvbnMgfHwgc2luZ2xlUGxhY2Vob2xkZXIpIHtcclxuICAgICAgcmV0dXJuIGRlY29yYXRlZC5jYWxsKHRoaXMsIGRhdGEpO1xyXG4gICAgfVxyXG5cclxuICAgIHRoaXMuY2xlYXIoKTtcclxuXHJcbiAgICB2YXIgJHBsYWNlaG9sZGVyID0gdGhpcy5jcmVhdGVQbGFjZWhvbGRlcih0aGlzLnBsYWNlaG9sZGVyKTtcclxuXHJcbiAgICB0aGlzLiRzZWxlY3Rpb24uZmluZCgnLnNlbGVjdDItc2VsZWN0aW9uX19yZW5kZXJlZCcpLmFwcGVuZCgkcGxhY2Vob2xkZXIpO1xyXG4gIH07XHJcblxyXG4gIHJldHVybiBQbGFjZWhvbGRlcjtcclxufSk7XHJcblxuUzIuZGVmaW5lKCdzZWxlY3QyL3NlbGVjdGlvbi9hbGxvd0NsZWFyJyxbXHJcbiAgJ2pxdWVyeScsXHJcbiAgJy4uL2tleXMnXHJcbl0sIGZ1bmN0aW9uICgkLCBLRVlTKSB7XHJcbiAgZnVuY3Rpb24gQWxsb3dDbGVhciAoKSB7IH1cclxuXHJcbiAgQWxsb3dDbGVhci5wcm90b3R5cGUuYmluZCA9IGZ1bmN0aW9uIChkZWNvcmF0ZWQsIGNvbnRhaW5lciwgJGNvbnRhaW5lcikge1xyXG4gICAgdmFyIHNlbGYgPSB0aGlzO1xyXG5cclxuICAgIGRlY29yYXRlZC5jYWxsKHRoaXMsIGNvbnRhaW5lciwgJGNvbnRhaW5lcik7XHJcblxyXG4gICAgaWYgKHRoaXMucGxhY2Vob2xkZXIgPT0gbnVsbCkge1xyXG4gICAgICBpZiAodGhpcy5vcHRpb25zLmdldCgnZGVidWcnKSAmJiB3aW5kb3cuY29uc29sZSAmJiBjb25zb2xlLmVycm9yKSB7XHJcbiAgICAgICAgY29uc29sZS5lcnJvcihcclxuICAgICAgICAgICdTZWxlY3QyOiBUaGUgYGFsbG93Q2xlYXJgIG9wdGlvbiBzaG91bGQgYmUgdXNlZCBpbiBjb21iaW5hdGlvbiAnICtcclxuICAgICAgICAgICd3aXRoIHRoZSBgcGxhY2Vob2xkZXJgIG9wdGlvbi4nXHJcbiAgICAgICAgKTtcclxuICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIHRoaXMuJHNlbGVjdGlvbi5vbignbW91c2Vkb3duJywgJy5zZWxlY3QyLXNlbGVjdGlvbl9fY2xlYXInLFxyXG4gICAgICBmdW5jdGlvbiAoZXZ0KSB7XHJcbiAgICAgICAgc2VsZi5faGFuZGxlQ2xlYXIoZXZ0KTtcclxuICAgIH0pO1xyXG5cclxuICAgIGNvbnRhaW5lci5vbigna2V5cHJlc3MnLCBmdW5jdGlvbiAoZXZ0KSB7XHJcbiAgICAgIHNlbGYuX2hhbmRsZUtleWJvYXJkQ2xlYXIoZXZ0LCBjb250YWluZXIpO1xyXG4gICAgfSk7XHJcbiAgfTtcclxuXHJcbiAgQWxsb3dDbGVhci5wcm90b3R5cGUuX2hhbmRsZUNsZWFyID0gZnVuY3Rpb24gKF8sIGV2dCkge1xyXG4gICAgLy8gSWdub3JlIHRoZSBldmVudCBpZiBpdCBpcyBkaXNhYmxlZFxyXG4gICAgaWYgKHRoaXMub3B0aW9ucy5nZXQoJ2Rpc2FibGVkJykpIHtcclxuICAgICAgcmV0dXJuO1xyXG4gICAgfVxyXG5cclxuICAgIHZhciAkY2xlYXIgPSB0aGlzLiRzZWxlY3Rpb24uZmluZCgnLnNlbGVjdDItc2VsZWN0aW9uX19jbGVhcicpO1xyXG5cclxuICAgIC8vIElnbm9yZSB0aGUgZXZlbnQgaWYgbm90aGluZyBoYXMgYmVlbiBzZWxlY3RlZFxyXG4gICAgaWYgKCRjbGVhci5sZW5ndGggPT09IDApIHtcclxuICAgICAgcmV0dXJuO1xyXG4gICAgfVxyXG5cclxuICAgIGV2dC5zdG9wUHJvcGFnYXRpb24oKTtcclxuXHJcbiAgICB2YXIgZGF0YSA9ICRjbGVhci5kYXRhKCdkYXRhJyk7XHJcblxyXG4gICAgZm9yICh2YXIgZCA9IDA7IGQgPCBkYXRhLmxlbmd0aDsgZCsrKSB7XHJcbiAgICAgIHZhciB1bnNlbGVjdERhdGEgPSB7XHJcbiAgICAgICAgZGF0YTogZGF0YVtkXVxyXG4gICAgICB9O1xyXG5cclxuICAgICAgLy8gVHJpZ2dlciB0aGUgYHVuc2VsZWN0YCBldmVudCwgc28gcGVvcGxlIGNhbiBwcmV2ZW50IGl0IGZyb20gYmVpbmdcclxuICAgICAgLy8gY2xlYXJlZC5cclxuICAgICAgdGhpcy50cmlnZ2VyKCd1bnNlbGVjdCcsIHVuc2VsZWN0RGF0YSk7XHJcblxyXG4gICAgICAvLyBJZiB0aGUgZXZlbnQgd2FzIHByZXZlbnRlZCwgZG9uJ3QgY2xlYXIgaXQgb3V0LlxyXG4gICAgICBpZiAodW5zZWxlY3REYXRhLnByZXZlbnRlZCkge1xyXG4gICAgICAgIHJldHVybjtcclxuICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIHRoaXMuJGVsZW1lbnQudmFsKHRoaXMucGxhY2Vob2xkZXIuaWQpLnRyaWdnZXIoJ2NoYW5nZScpO1xyXG5cclxuICAgIHRoaXMudHJpZ2dlcigndG9nZ2xlJywge30pO1xyXG4gIH07XHJcblxyXG4gIEFsbG93Q2xlYXIucHJvdG90eXBlLl9oYW5kbGVLZXlib2FyZENsZWFyID0gZnVuY3Rpb24gKF8sIGV2dCwgY29udGFpbmVyKSB7XHJcbiAgICBpZiAoY29udGFpbmVyLmlzT3BlbigpKSB7XHJcbiAgICAgIHJldHVybjtcclxuICAgIH1cclxuXHJcbiAgICBpZiAoZXZ0LndoaWNoID09IEtFWVMuREVMRVRFIHx8IGV2dC53aGljaCA9PSBLRVlTLkJBQ0tTUEFDRSkge1xyXG4gICAgICB0aGlzLl9oYW5kbGVDbGVhcihldnQpO1xyXG4gICAgfVxyXG4gIH07XHJcblxyXG4gIEFsbG93Q2xlYXIucHJvdG90eXBlLnVwZGF0ZSA9IGZ1bmN0aW9uIChkZWNvcmF0ZWQsIGRhdGEpIHtcclxuICAgIGRlY29yYXRlZC5jYWxsKHRoaXMsIGRhdGEpO1xyXG5cclxuICAgIGlmICh0aGlzLiRzZWxlY3Rpb24uZmluZCgnLnNlbGVjdDItc2VsZWN0aW9uX19wbGFjZWhvbGRlcicpLmxlbmd0aCA+IDAgfHxcclxuICAgICAgICBkYXRhLmxlbmd0aCA9PT0gMCkge1xyXG4gICAgICByZXR1cm47XHJcbiAgICB9XHJcblxyXG4gICAgdmFyICRyZW1vdmUgPSAkKFxyXG4gICAgICAnPHNwYW4gY2xhc3M9XCJzZWxlY3QyLXNlbGVjdGlvbl9fY2xlYXJcIj4nICtcclxuICAgICAgICAnJnRpbWVzOycgK1xyXG4gICAgICAnPC9zcGFuPidcclxuICAgICk7XHJcbiAgICAkcmVtb3ZlLmRhdGEoJ2RhdGEnLCBkYXRhKTtcclxuXHJcbiAgICB0aGlzLiRzZWxlY3Rpb24uZmluZCgnLnNlbGVjdDItc2VsZWN0aW9uX19yZW5kZXJlZCcpLnByZXBlbmQoJHJlbW92ZSk7XHJcbiAgfTtcclxuXHJcbiAgcmV0dXJuIEFsbG93Q2xlYXI7XHJcbn0pO1xyXG5cblMyLmRlZmluZSgnc2VsZWN0Mi9zZWxlY3Rpb24vc2VhcmNoJyxbXHJcbiAgJ2pxdWVyeScsXHJcbiAgJy4uL3V0aWxzJyxcclxuICAnLi4va2V5cydcclxuXSwgZnVuY3Rpb24gKCQsIFV0aWxzLCBLRVlTKSB7XHJcbiAgZnVuY3Rpb24gU2VhcmNoIChkZWNvcmF0ZWQsICRlbGVtZW50LCBvcHRpb25zKSB7XHJcbiAgICBkZWNvcmF0ZWQuY2FsbCh0aGlzLCAkZWxlbWVudCwgb3B0aW9ucyk7XHJcbiAgfVxyXG5cclxuICBTZWFyY2gucHJvdG90eXBlLnJlbmRlciA9IGZ1bmN0aW9uIChkZWNvcmF0ZWQpIHtcclxuICAgIHZhciAkc2VhcmNoID0gJChcclxuICAgICAgJzxsaSBjbGFzcz1cInNlbGVjdDItc2VhcmNoIHNlbGVjdDItc2VhcmNoLS1pbmxpbmVcIj4nICtcclxuICAgICAgICAnPGlucHV0IGNsYXNzPVwic2VsZWN0Mi1zZWFyY2hfX2ZpZWxkXCIgdHlwZT1cInNlYXJjaFwiIHRhYmluZGV4PVwiLTFcIicgK1xyXG4gICAgICAgICcgYXV0b2NvbXBsZXRlPVwib2ZmXCIgYXV0b2NvcnJlY3Q9XCJvZmZcIiBhdXRvY2FwaXRhbGl6ZT1cIm9mZlwiJyArXHJcbiAgICAgICAgJyBzcGVsbGNoZWNrPVwiZmFsc2VcIiByb2xlPVwidGV4dGJveFwiIGFyaWEtYXV0b2NvbXBsZXRlPVwibGlzdFwiIC8+JyArXHJcbiAgICAgICc8L2xpPidcclxuICAgICk7XHJcblxyXG4gICAgdGhpcy4kc2VhcmNoQ29udGFpbmVyID0gJHNlYXJjaDtcclxuICAgIHRoaXMuJHNlYXJjaCA9ICRzZWFyY2guZmluZCgnaW5wdXQnKTtcclxuXHJcbiAgICB2YXIgJHJlbmRlcmVkID0gZGVjb3JhdGVkLmNhbGwodGhpcyk7XHJcblxyXG4gICAgdGhpcy5fdHJhbnNmZXJUYWJJbmRleCgpO1xyXG5cclxuICAgIHJldHVybiAkcmVuZGVyZWQ7XHJcbiAgfTtcclxuXHJcbiAgU2VhcmNoLnByb3RvdHlwZS5iaW5kID0gZnVuY3Rpb24gKGRlY29yYXRlZCwgY29udGFpbmVyLCAkY29udGFpbmVyKSB7XHJcbiAgICB2YXIgc2VsZiA9IHRoaXM7XHJcblxyXG4gICAgZGVjb3JhdGVkLmNhbGwodGhpcywgY29udGFpbmVyLCAkY29udGFpbmVyKTtcclxuXHJcbiAgICBjb250YWluZXIub24oJ29wZW4nLCBmdW5jdGlvbiAoKSB7XHJcbiAgICAgIHNlbGYuJHNlYXJjaC50cmlnZ2VyKCdmb2N1cycpO1xyXG4gICAgfSk7XHJcblxyXG4gICAgY29udGFpbmVyLm9uKCdjbG9zZScsIGZ1bmN0aW9uICgpIHtcclxuICAgICAgc2VsZi4kc2VhcmNoLnZhbCgnJyk7XHJcbiAgICAgIHNlbGYuJHNlYXJjaC5yZW1vdmVBdHRyKCdhcmlhLWFjdGl2ZWRlc2NlbmRhbnQnKTtcclxuICAgICAgc2VsZi4kc2VhcmNoLnRyaWdnZXIoJ2ZvY3VzJyk7XHJcbiAgICB9KTtcclxuXHJcbiAgICBjb250YWluZXIub24oJ2VuYWJsZScsIGZ1bmN0aW9uICgpIHtcclxuICAgICAgc2VsZi4kc2VhcmNoLnByb3AoJ2Rpc2FibGVkJywgZmFsc2UpO1xyXG5cclxuICAgICAgc2VsZi5fdHJhbnNmZXJUYWJJbmRleCgpO1xyXG4gICAgfSk7XHJcblxyXG4gICAgY29udGFpbmVyLm9uKCdkaXNhYmxlJywgZnVuY3Rpb24gKCkge1xyXG4gICAgICBzZWxmLiRzZWFyY2gucHJvcCgnZGlzYWJsZWQnLCB0cnVlKTtcclxuICAgIH0pO1xyXG5cclxuICAgIGNvbnRhaW5lci5vbignZm9jdXMnLCBmdW5jdGlvbiAoZXZ0KSB7XHJcbiAgICAgIHNlbGYuJHNlYXJjaC50cmlnZ2VyKCdmb2N1cycpO1xyXG4gICAgfSk7XHJcblxyXG4gICAgY29udGFpbmVyLm9uKCdyZXN1bHRzOmZvY3VzJywgZnVuY3Rpb24gKHBhcmFtcykge1xyXG4gICAgICBzZWxmLiRzZWFyY2guYXR0cignYXJpYS1hY3RpdmVkZXNjZW5kYW50JywgcGFyYW1zLmlkKTtcclxuICAgIH0pO1xyXG5cclxuICAgIHRoaXMuJHNlbGVjdGlvbi5vbignZm9jdXNpbicsICcuc2VsZWN0Mi1zZWFyY2gtLWlubGluZScsIGZ1bmN0aW9uIChldnQpIHtcclxuICAgICAgc2VsZi50cmlnZ2VyKCdmb2N1cycsIGV2dCk7XHJcbiAgICB9KTtcclxuXHJcbiAgICB0aGlzLiRzZWxlY3Rpb24ub24oJ2ZvY3Vzb3V0JywgJy5zZWxlY3QyLXNlYXJjaC0taW5saW5lJywgZnVuY3Rpb24gKGV2dCkge1xyXG4gICAgICBzZWxmLl9oYW5kbGVCbHVyKGV2dCk7XHJcbiAgICB9KTtcclxuXHJcbiAgICB0aGlzLiRzZWxlY3Rpb24ub24oJ2tleWRvd24nLCAnLnNlbGVjdDItc2VhcmNoLS1pbmxpbmUnLCBmdW5jdGlvbiAoZXZ0KSB7XHJcbiAgICAgIGV2dC5zdG9wUHJvcGFnYXRpb24oKTtcclxuXHJcbiAgICAgIHNlbGYudHJpZ2dlcigna2V5cHJlc3MnLCBldnQpO1xyXG5cclxuICAgICAgc2VsZi5fa2V5VXBQcmV2ZW50ZWQgPSBldnQuaXNEZWZhdWx0UHJldmVudGVkKCk7XHJcblxyXG4gICAgICB2YXIga2V5ID0gZXZ0LndoaWNoO1xyXG5cclxuICAgICAgaWYgKGtleSA9PT0gS0VZUy5CQUNLU1BBQ0UgJiYgc2VsZi4kc2VhcmNoLnZhbCgpID09PSAnJykge1xyXG4gICAgICAgIHZhciAkcHJldmlvdXNDaG9pY2UgPSBzZWxmLiRzZWFyY2hDb250YWluZXJcclxuICAgICAgICAgIC5wcmV2KCcuc2VsZWN0Mi1zZWxlY3Rpb25fX2Nob2ljZScpO1xyXG5cclxuICAgICAgICBpZiAoJHByZXZpb3VzQ2hvaWNlLmxlbmd0aCA+IDApIHtcclxuICAgICAgICAgIHZhciBpdGVtID0gJHByZXZpb3VzQ2hvaWNlLmRhdGEoJ2RhdGEnKTtcclxuXHJcbiAgICAgICAgICBzZWxmLnNlYXJjaFJlbW92ZUNob2ljZShpdGVtKTtcclxuXHJcbiAgICAgICAgICBldnQucHJldmVudERlZmF1bHQoKTtcclxuICAgICAgICB9XHJcbiAgICAgIH1cclxuICAgIH0pO1xyXG5cclxuICAgIC8vIFRyeSB0byBkZXRlY3QgdGhlIElFIHZlcnNpb24gc2hvdWxkIHRoZSBgZG9jdW1lbnRNb2RlYCBwcm9wZXJ0eSB0aGF0XHJcbiAgICAvLyBpcyBzdG9yZWQgb24gdGhlIGRvY3VtZW50LiBUaGlzIGlzIG9ubHkgaW1wbGVtZW50ZWQgaW4gSUUgYW5kIGlzXHJcbiAgICAvLyBzbGlnaHRseSBjbGVhbmVyIHRoYW4gZG9pbmcgYSB1c2VyIGFnZW50IGNoZWNrLlxyXG4gICAgLy8gVGhpcyBwcm9wZXJ0eSBpcyBub3QgYXZhaWxhYmxlIGluIEVkZ2UsIGJ1dCBFZGdlIGFsc28gZG9lc24ndCBoYXZlXHJcbiAgICAvLyB0aGlzIGJ1Zy5cclxuICAgIHZhciBtc2llID0gZG9jdW1lbnQuZG9jdW1lbnRNb2RlO1xyXG4gICAgdmFyIGRpc2FibGVJbnB1dEV2ZW50cyA9IG1zaWUgJiYgbXNpZSA8PSAxMTtcclxuXHJcbiAgICAvLyBXb3JrYXJvdW5kIGZvciBicm93c2VycyB3aGljaCBkbyBub3Qgc3VwcG9ydCB0aGUgYGlucHV0YCBldmVudFxyXG4gICAgLy8gVGhpcyB3aWxsIHByZXZlbnQgZG91YmxlLXRyaWdnZXJpbmcgb2YgZXZlbnRzIGZvciBicm93c2VycyB3aGljaCBzdXBwb3J0XHJcbiAgICAvLyBib3RoIHRoZSBga2V5dXBgIGFuZCBgaW5wdXRgIGV2ZW50cy5cclxuICAgIHRoaXMuJHNlbGVjdGlvbi5vbihcclxuICAgICAgJ2lucHV0LnNlYXJjaGNoZWNrJyxcclxuICAgICAgJy5zZWxlY3QyLXNlYXJjaC0taW5saW5lJyxcclxuICAgICAgZnVuY3Rpb24gKGV2dCkge1xyXG4gICAgICAgIC8vIElFIHdpbGwgdHJpZ2dlciB0aGUgYGlucHV0YCBldmVudCB3aGVuIGEgcGxhY2Vob2xkZXIgaXMgdXNlZCBvbiBhXHJcbiAgICAgICAgLy8gc2VhcmNoIGJveC4gVG8gZ2V0IGFyb3VuZCB0aGlzIGlzc3VlLCB3ZSBhcmUgZm9yY2VkIHRvIGlnbm9yZSBhbGxcclxuICAgICAgICAvLyBgaW5wdXRgIGV2ZW50cyBpbiBJRSBhbmQga2VlcCB1c2luZyBga2V5dXBgLlxyXG4gICAgICAgIGlmIChkaXNhYmxlSW5wdXRFdmVudHMpIHtcclxuICAgICAgICAgIHNlbGYuJHNlbGVjdGlvbi5vZmYoJ2lucHV0LnNlYXJjaCBpbnB1dC5zZWFyY2hjaGVjaycpO1xyXG4gICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgLy8gVW5iaW5kIHRoZSBkdXBsaWNhdGVkIGBrZXl1cGAgZXZlbnRcclxuICAgICAgICBzZWxmLiRzZWxlY3Rpb24ub2ZmKCdrZXl1cC5zZWFyY2gnKTtcclxuICAgICAgfVxyXG4gICAgKTtcclxuXHJcbiAgICB0aGlzLiRzZWxlY3Rpb24ub24oXHJcbiAgICAgICdrZXl1cC5zZWFyY2ggaW5wdXQuc2VhcmNoJyxcclxuICAgICAgJy5zZWxlY3QyLXNlYXJjaC0taW5saW5lJyxcclxuICAgICAgZnVuY3Rpb24gKGV2dCkge1xyXG4gICAgICAgIC8vIElFIHdpbGwgdHJpZ2dlciB0aGUgYGlucHV0YCBldmVudCB3aGVuIGEgcGxhY2Vob2xkZXIgaXMgdXNlZCBvbiBhXHJcbiAgICAgICAgLy8gc2VhcmNoIGJveC4gVG8gZ2V0IGFyb3VuZCB0aGlzIGlzc3VlLCB3ZSBhcmUgZm9yY2VkIHRvIGlnbm9yZSBhbGxcclxuICAgICAgICAvLyBgaW5wdXRgIGV2ZW50cyBpbiBJRSBhbmQga2VlcCB1c2luZyBga2V5dXBgLlxyXG4gICAgICAgIGlmIChkaXNhYmxlSW5wdXRFdmVudHMgJiYgZXZ0LnR5cGUgPT09ICdpbnB1dCcpIHtcclxuICAgICAgICAgIHNlbGYuJHNlbGVjdGlvbi5vZmYoJ2lucHV0LnNlYXJjaCBpbnB1dC5zZWFyY2hjaGVjaycpO1xyXG4gICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgdmFyIGtleSA9IGV2dC53aGljaDtcclxuXHJcbiAgICAgICAgLy8gV2UgY2FuIGZyZWVseSBpZ25vcmUgZXZlbnRzIGZyb20gbW9kaWZpZXIga2V5c1xyXG4gICAgICAgIGlmIChrZXkgPT0gS0VZUy5TSElGVCB8fCBrZXkgPT0gS0VZUy5DVFJMIHx8IGtleSA9PSBLRVlTLkFMVCkge1xyXG4gICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgLy8gVGFiYmluZyB3aWxsIGJlIGhhbmRsZWQgZHVyaW5nIHRoZSBga2V5ZG93bmAgcGhhc2VcclxuICAgICAgICBpZiAoa2V5ID09IEtFWVMuVEFCKSB7XHJcbiAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBzZWxmLmhhbmRsZVNlYXJjaChldnQpO1xyXG4gICAgICB9XHJcbiAgICApO1xyXG4gIH07XHJcblxyXG4gIC8qKlxyXG4gICAqIFRoaXMgbWV0aG9kIHdpbGwgdHJhbnNmZXIgdGhlIHRhYmluZGV4IGF0dHJpYnV0ZSBmcm9tIHRoZSByZW5kZXJlZFxyXG4gICAqIHNlbGVjdGlvbiB0byB0aGUgc2VhcmNoIGJveC4gVGhpcyBhbGxvd3MgZm9yIHRoZSBzZWFyY2ggYm94IHRvIGJlIHVzZWQgYXNcclxuICAgKiB0aGUgcHJpbWFyeSBmb2N1cyBpbnN0ZWFkIG9mIHRoZSBzZWxlY3Rpb24gY29udGFpbmVyLlxyXG4gICAqXHJcbiAgICogQHByaXZhdGVcclxuICAgKi9cclxuICBTZWFyY2gucHJvdG90eXBlLl90cmFuc2ZlclRhYkluZGV4ID0gZnVuY3Rpb24gKGRlY29yYXRlZCkge1xyXG4gICAgdGhpcy4kc2VhcmNoLmF0dHIoJ3RhYmluZGV4JywgdGhpcy4kc2VsZWN0aW9uLmF0dHIoJ3RhYmluZGV4JykpO1xyXG4gICAgdGhpcy4kc2VsZWN0aW9uLmF0dHIoJ3RhYmluZGV4JywgJy0xJyk7XHJcbiAgfTtcclxuXHJcbiAgU2VhcmNoLnByb3RvdHlwZS5jcmVhdGVQbGFjZWhvbGRlciA9IGZ1bmN0aW9uIChkZWNvcmF0ZWQsIHBsYWNlaG9sZGVyKSB7XHJcbiAgICB0aGlzLiRzZWFyY2guYXR0cigncGxhY2Vob2xkZXInLCBwbGFjZWhvbGRlci50ZXh0KTtcclxuICB9O1xyXG5cclxuICBTZWFyY2gucHJvdG90eXBlLnVwZGF0ZSA9IGZ1bmN0aW9uIChkZWNvcmF0ZWQsIGRhdGEpIHtcclxuICAgIHZhciBzZWFyY2hIYWRGb2N1cyA9IHRoaXMuJHNlYXJjaFswXSA9PSBkb2N1bWVudC5hY3RpdmVFbGVtZW50O1xyXG5cclxuICAgIHRoaXMuJHNlYXJjaC5hdHRyKCdwbGFjZWhvbGRlcicsICcnKTtcclxuXHJcbiAgICBkZWNvcmF0ZWQuY2FsbCh0aGlzLCBkYXRhKTtcclxuXHJcbiAgICB0aGlzLiRzZWxlY3Rpb24uZmluZCgnLnNlbGVjdDItc2VsZWN0aW9uX19yZW5kZXJlZCcpXHJcbiAgICAgICAgICAgICAgICAgICAuYXBwZW5kKHRoaXMuJHNlYXJjaENvbnRhaW5lcik7XHJcblxyXG4gICAgdGhpcy5yZXNpemVTZWFyY2goKTtcclxuICAgIGlmIChzZWFyY2hIYWRGb2N1cykge1xyXG4gICAgICB0aGlzLiRzZWFyY2guZm9jdXMoKTtcclxuICAgIH1cclxuICB9O1xyXG5cclxuICBTZWFyY2gucHJvdG90eXBlLmhhbmRsZVNlYXJjaCA9IGZ1bmN0aW9uICgpIHtcclxuICAgIHRoaXMucmVzaXplU2VhcmNoKCk7XHJcblxyXG4gICAgaWYgKCF0aGlzLl9rZXlVcFByZXZlbnRlZCkge1xyXG4gICAgICB2YXIgaW5wdXQgPSB0aGlzLiRzZWFyY2gudmFsKCk7XHJcblxyXG4gICAgICB0aGlzLnRyaWdnZXIoJ3F1ZXJ5Jywge1xyXG4gICAgICAgIHRlcm06IGlucHV0XHJcbiAgICAgIH0pO1xyXG4gICAgfVxyXG5cclxuICAgIHRoaXMuX2tleVVwUHJldmVudGVkID0gZmFsc2U7XHJcbiAgfTtcclxuXHJcbiAgU2VhcmNoLnByb3RvdHlwZS5zZWFyY2hSZW1vdmVDaG9pY2UgPSBmdW5jdGlvbiAoZGVjb3JhdGVkLCBpdGVtKSB7XHJcbiAgICB0aGlzLnRyaWdnZXIoJ3Vuc2VsZWN0Jywge1xyXG4gICAgICBkYXRhOiBpdGVtXHJcbiAgICB9KTtcclxuXHJcbiAgICB0aGlzLiRzZWFyY2gudmFsKGl0ZW0udGV4dCk7XHJcbiAgICB0aGlzLmhhbmRsZVNlYXJjaCgpO1xyXG4gIH07XHJcblxyXG4gIFNlYXJjaC5wcm90b3R5cGUucmVzaXplU2VhcmNoID0gZnVuY3Rpb24gKCkge1xyXG4gICAgdGhpcy4kc2VhcmNoLmNzcygnd2lkdGgnLCAnMjVweCcpO1xyXG5cclxuICAgIHZhciB3aWR0aCA9ICcnO1xyXG5cclxuICAgIGlmICh0aGlzLiRzZWFyY2guYXR0cigncGxhY2Vob2xkZXInKSAhPT0gJycpIHtcclxuICAgICAgd2lkdGggPSB0aGlzLiRzZWxlY3Rpb24uZmluZCgnLnNlbGVjdDItc2VsZWN0aW9uX19yZW5kZXJlZCcpLmlubmVyV2lkdGgoKTtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIHZhciBtaW5pbXVtV2lkdGggPSB0aGlzLiRzZWFyY2gudmFsKCkubGVuZ3RoICsgMTtcclxuXHJcbiAgICAgIHdpZHRoID0gKG1pbmltdW1XaWR0aCAqIDAuNzUpICsgJ2VtJztcclxuICAgIH1cclxuXHJcbiAgICB0aGlzLiRzZWFyY2guY3NzKCd3aWR0aCcsIHdpZHRoKTtcclxuICB9O1xyXG5cclxuICByZXR1cm4gU2VhcmNoO1xyXG59KTtcclxuXG5TMi5kZWZpbmUoJ3NlbGVjdDIvc2VsZWN0aW9uL2V2ZW50UmVsYXknLFtcclxuICAnanF1ZXJ5J1xyXG5dLCBmdW5jdGlvbiAoJCkge1xyXG4gIGZ1bmN0aW9uIEV2ZW50UmVsYXkgKCkgeyB9XHJcblxyXG4gIEV2ZW50UmVsYXkucHJvdG90eXBlLmJpbmQgPSBmdW5jdGlvbiAoZGVjb3JhdGVkLCBjb250YWluZXIsICRjb250YWluZXIpIHtcclxuICAgIHZhciBzZWxmID0gdGhpcztcclxuICAgIHZhciByZWxheUV2ZW50cyA9IFtcclxuICAgICAgJ29wZW4nLCAnb3BlbmluZycsXHJcbiAgICAgICdjbG9zZScsICdjbG9zaW5nJyxcclxuICAgICAgJ3NlbGVjdCcsICdzZWxlY3RpbmcnLFxyXG4gICAgICAndW5zZWxlY3QnLCAndW5zZWxlY3RpbmcnXHJcbiAgICBdO1xyXG5cclxuICAgIHZhciBwcmV2ZW50YWJsZUV2ZW50cyA9IFsnb3BlbmluZycsICdjbG9zaW5nJywgJ3NlbGVjdGluZycsICd1bnNlbGVjdGluZyddO1xyXG5cclxuICAgIGRlY29yYXRlZC5jYWxsKHRoaXMsIGNvbnRhaW5lciwgJGNvbnRhaW5lcik7XHJcblxyXG4gICAgY29udGFpbmVyLm9uKCcqJywgZnVuY3Rpb24gKG5hbWUsIHBhcmFtcykge1xyXG4gICAgICAvLyBJZ25vcmUgZXZlbnRzIHRoYXQgc2hvdWxkIG5vdCBiZSByZWxheWVkXHJcbiAgICAgIGlmICgkLmluQXJyYXkobmFtZSwgcmVsYXlFdmVudHMpID09PSAtMSkge1xyXG4gICAgICAgIHJldHVybjtcclxuICAgICAgfVxyXG5cclxuICAgICAgLy8gVGhlIHBhcmFtZXRlcnMgc2hvdWxkIGFsd2F5cyBiZSBhbiBvYmplY3RcclxuICAgICAgcGFyYW1zID0gcGFyYW1zIHx8IHt9O1xyXG5cclxuICAgICAgLy8gR2VuZXJhdGUgdGhlIGpRdWVyeSBldmVudCBmb3IgdGhlIFNlbGVjdDIgZXZlbnRcclxuICAgICAgdmFyIGV2dCA9ICQuRXZlbnQoJ3NlbGVjdDI6JyArIG5hbWUsIHtcclxuICAgICAgICBwYXJhbXM6IHBhcmFtc1xyXG4gICAgICB9KTtcclxuXHJcbiAgICAgIHNlbGYuJGVsZW1lbnQudHJpZ2dlcihldnQpO1xyXG5cclxuICAgICAgLy8gT25seSBoYW5kbGUgcHJldmVudGFibGUgZXZlbnRzIGlmIGl0IHdhcyBvbmVcclxuICAgICAgaWYgKCQuaW5BcnJheShuYW1lLCBwcmV2ZW50YWJsZUV2ZW50cykgPT09IC0xKSB7XHJcbiAgICAgICAgcmV0dXJuO1xyXG4gICAgICB9XHJcblxyXG4gICAgICBwYXJhbXMucHJldmVudGVkID0gZXZ0LmlzRGVmYXVsdFByZXZlbnRlZCgpO1xyXG4gICAgfSk7XHJcbiAgfTtcclxuXHJcbiAgcmV0dXJuIEV2ZW50UmVsYXk7XHJcbn0pO1xyXG5cblMyLmRlZmluZSgnc2VsZWN0Mi90cmFuc2xhdGlvbicsW1xyXG4gICdqcXVlcnknLFxyXG4gICdyZXF1aXJlJ1xyXG5dLCBmdW5jdGlvbiAoJCwgcmVxdWlyZSkge1xyXG4gIGZ1bmN0aW9uIFRyYW5zbGF0aW9uIChkaWN0KSB7XHJcbiAgICB0aGlzLmRpY3QgPSBkaWN0IHx8IHt9O1xyXG4gIH1cclxuXHJcbiAgVHJhbnNsYXRpb24ucHJvdG90eXBlLmFsbCA9IGZ1bmN0aW9uICgpIHtcclxuICAgIHJldHVybiB0aGlzLmRpY3Q7XHJcbiAgfTtcclxuXHJcbiAgVHJhbnNsYXRpb24ucHJvdG90eXBlLmdldCA9IGZ1bmN0aW9uIChrZXkpIHtcclxuICAgIHJldHVybiB0aGlzLmRpY3Rba2V5XTtcclxuICB9O1xyXG5cclxuICBUcmFuc2xhdGlvbi5wcm90b3R5cGUuZXh0ZW5kID0gZnVuY3Rpb24gKHRyYW5zbGF0aW9uKSB7XHJcbiAgICB0aGlzLmRpY3QgPSAkLmV4dGVuZCh7fSwgdHJhbnNsYXRpb24uYWxsKCksIHRoaXMuZGljdCk7XHJcbiAgfTtcclxuXHJcbiAgLy8gU3RhdGljIGZ1bmN0aW9uc1xyXG5cclxuICBUcmFuc2xhdGlvbi5fY2FjaGUgPSB7fTtcclxuXHJcbiAgVHJhbnNsYXRpb24ubG9hZFBhdGggPSBmdW5jdGlvbiAocGF0aCkge1xyXG4gICAgaWYgKCEocGF0aCBpbiBUcmFuc2xhdGlvbi5fY2FjaGUpKSB7XHJcbiAgICAgIHZhciB0cmFuc2xhdGlvbnMgPSByZXF1aXJlKHBhdGgpO1xyXG5cclxuICAgICAgVHJhbnNsYXRpb24uX2NhY2hlW3BhdGhdID0gdHJhbnNsYXRpb25zO1xyXG4gICAgfVxyXG5cclxuICAgIHJldHVybiBuZXcgVHJhbnNsYXRpb24oVHJhbnNsYXRpb24uX2NhY2hlW3BhdGhdKTtcclxuICB9O1xyXG5cclxuICByZXR1cm4gVHJhbnNsYXRpb247XHJcbn0pO1xyXG5cblMyLmRlZmluZSgnc2VsZWN0Mi9kaWFjcml0aWNzJyxbXHJcblxyXG5dLCBmdW5jdGlvbiAoKSB7XHJcbiAgdmFyIGRpYWNyaXRpY3MgPSB7XHJcbiAgICAnXFx1MjRCNic6ICdBJyxcclxuICAgICdcXHVGRjIxJzogJ0EnLFxyXG4gICAgJ1xcdTAwQzAnOiAnQScsXHJcbiAgICAnXFx1MDBDMSc6ICdBJyxcclxuICAgICdcXHUwMEMyJzogJ0EnLFxyXG4gICAgJ1xcdTFFQTYnOiAnQScsXHJcbiAgICAnXFx1MUVBNCc6ICdBJyxcclxuICAgICdcXHUxRUFBJzogJ0EnLFxyXG4gICAgJ1xcdTFFQTgnOiAnQScsXHJcbiAgICAnXFx1MDBDMyc6ICdBJyxcclxuICAgICdcXHUwMTAwJzogJ0EnLFxyXG4gICAgJ1xcdTAxMDInOiAnQScsXHJcbiAgICAnXFx1MUVCMCc6ICdBJyxcclxuICAgICdcXHUxRUFFJzogJ0EnLFxyXG4gICAgJ1xcdTFFQjQnOiAnQScsXHJcbiAgICAnXFx1MUVCMic6ICdBJyxcclxuICAgICdcXHUwMjI2JzogJ0EnLFxyXG4gICAgJ1xcdTAxRTAnOiAnQScsXHJcbiAgICAnXFx1MDBDNCc6ICdBJyxcclxuICAgICdcXHUwMURFJzogJ0EnLFxyXG4gICAgJ1xcdTFFQTInOiAnQScsXHJcbiAgICAnXFx1MDBDNSc6ICdBJyxcclxuICAgICdcXHUwMUZBJzogJ0EnLFxyXG4gICAgJ1xcdTAxQ0QnOiAnQScsXHJcbiAgICAnXFx1MDIwMCc6ICdBJyxcclxuICAgICdcXHUwMjAyJzogJ0EnLFxyXG4gICAgJ1xcdTFFQTAnOiAnQScsXHJcbiAgICAnXFx1MUVBQyc6ICdBJyxcclxuICAgICdcXHUxRUI2JzogJ0EnLFxyXG4gICAgJ1xcdTFFMDAnOiAnQScsXHJcbiAgICAnXFx1MDEwNCc6ICdBJyxcclxuICAgICdcXHUwMjNBJzogJ0EnLFxyXG4gICAgJ1xcdTJDNkYnOiAnQScsXHJcbiAgICAnXFx1QTczMic6ICdBQScsXHJcbiAgICAnXFx1MDBDNic6ICdBRScsXHJcbiAgICAnXFx1MDFGQyc6ICdBRScsXHJcbiAgICAnXFx1MDFFMic6ICdBRScsXHJcbiAgICAnXFx1QTczNCc6ICdBTycsXHJcbiAgICAnXFx1QTczNic6ICdBVScsXHJcbiAgICAnXFx1QTczOCc6ICdBVicsXHJcbiAgICAnXFx1QTczQSc6ICdBVicsXHJcbiAgICAnXFx1QTczQyc6ICdBWScsXHJcbiAgICAnXFx1MjRCNyc6ICdCJyxcclxuICAgICdcXHVGRjIyJzogJ0InLFxyXG4gICAgJ1xcdTFFMDInOiAnQicsXHJcbiAgICAnXFx1MUUwNCc6ICdCJyxcclxuICAgICdcXHUxRTA2JzogJ0InLFxyXG4gICAgJ1xcdTAyNDMnOiAnQicsXHJcbiAgICAnXFx1MDE4Mic6ICdCJyxcclxuICAgICdcXHUwMTgxJzogJ0InLFxyXG4gICAgJ1xcdTI0QjgnOiAnQycsXHJcbiAgICAnXFx1RkYyMyc6ICdDJyxcclxuICAgICdcXHUwMTA2JzogJ0MnLFxyXG4gICAgJ1xcdTAxMDgnOiAnQycsXHJcbiAgICAnXFx1MDEwQSc6ICdDJyxcclxuICAgICdcXHUwMTBDJzogJ0MnLFxyXG4gICAgJ1xcdTAwQzcnOiAnQycsXHJcbiAgICAnXFx1MUUwOCc6ICdDJyxcclxuICAgICdcXHUwMTg3JzogJ0MnLFxyXG4gICAgJ1xcdTAyM0InOiAnQycsXHJcbiAgICAnXFx1QTczRSc6ICdDJyxcclxuICAgICdcXHUyNEI5JzogJ0QnLFxyXG4gICAgJ1xcdUZGMjQnOiAnRCcsXHJcbiAgICAnXFx1MUUwQSc6ICdEJyxcclxuICAgICdcXHUwMTBFJzogJ0QnLFxyXG4gICAgJ1xcdTFFMEMnOiAnRCcsXHJcbiAgICAnXFx1MUUxMCc6ICdEJyxcclxuICAgICdcXHUxRTEyJzogJ0QnLFxyXG4gICAgJ1xcdTFFMEUnOiAnRCcsXHJcbiAgICAnXFx1MDExMCc6ICdEJyxcclxuICAgICdcXHUwMThCJzogJ0QnLFxyXG4gICAgJ1xcdTAxOEEnOiAnRCcsXHJcbiAgICAnXFx1MDE4OSc6ICdEJyxcclxuICAgICdcXHVBNzc5JzogJ0QnLFxyXG4gICAgJ1xcdTAxRjEnOiAnRFonLFxyXG4gICAgJ1xcdTAxQzQnOiAnRFonLFxyXG4gICAgJ1xcdTAxRjInOiAnRHonLFxyXG4gICAgJ1xcdTAxQzUnOiAnRHonLFxyXG4gICAgJ1xcdTI0QkEnOiAnRScsXHJcbiAgICAnXFx1RkYyNSc6ICdFJyxcclxuICAgICdcXHUwMEM4JzogJ0UnLFxyXG4gICAgJ1xcdTAwQzknOiAnRScsXHJcbiAgICAnXFx1MDBDQSc6ICdFJyxcclxuICAgICdcXHUxRUMwJzogJ0UnLFxyXG4gICAgJ1xcdTFFQkUnOiAnRScsXHJcbiAgICAnXFx1MUVDNCc6ICdFJyxcclxuICAgICdcXHUxRUMyJzogJ0UnLFxyXG4gICAgJ1xcdTFFQkMnOiAnRScsXHJcbiAgICAnXFx1MDExMic6ICdFJyxcclxuICAgICdcXHUxRTE0JzogJ0UnLFxyXG4gICAgJ1xcdTFFMTYnOiAnRScsXHJcbiAgICAnXFx1MDExNCc6ICdFJyxcclxuICAgICdcXHUwMTE2JzogJ0UnLFxyXG4gICAgJ1xcdTAwQ0InOiAnRScsXHJcbiAgICAnXFx1MUVCQSc6ICdFJyxcclxuICAgICdcXHUwMTFBJzogJ0UnLFxyXG4gICAgJ1xcdTAyMDQnOiAnRScsXHJcbiAgICAnXFx1MDIwNic6ICdFJyxcclxuICAgICdcXHUxRUI4JzogJ0UnLFxyXG4gICAgJ1xcdTFFQzYnOiAnRScsXHJcbiAgICAnXFx1MDIyOCc6ICdFJyxcclxuICAgICdcXHUxRTFDJzogJ0UnLFxyXG4gICAgJ1xcdTAxMTgnOiAnRScsXHJcbiAgICAnXFx1MUUxOCc6ICdFJyxcclxuICAgICdcXHUxRTFBJzogJ0UnLFxyXG4gICAgJ1xcdTAxOTAnOiAnRScsXHJcbiAgICAnXFx1MDE4RSc6ICdFJyxcclxuICAgICdcXHUyNEJCJzogJ0YnLFxyXG4gICAgJ1xcdUZGMjYnOiAnRicsXHJcbiAgICAnXFx1MUUxRSc6ICdGJyxcclxuICAgICdcXHUwMTkxJzogJ0YnLFxyXG4gICAgJ1xcdUE3N0InOiAnRicsXHJcbiAgICAnXFx1MjRCQyc6ICdHJyxcclxuICAgICdcXHVGRjI3JzogJ0cnLFxyXG4gICAgJ1xcdTAxRjQnOiAnRycsXHJcbiAgICAnXFx1MDExQyc6ICdHJyxcclxuICAgICdcXHUxRTIwJzogJ0cnLFxyXG4gICAgJ1xcdTAxMUUnOiAnRycsXHJcbiAgICAnXFx1MDEyMCc6ICdHJyxcclxuICAgICdcXHUwMUU2JzogJ0cnLFxyXG4gICAgJ1xcdTAxMjInOiAnRycsXHJcbiAgICAnXFx1MDFFNCc6ICdHJyxcclxuICAgICdcXHUwMTkzJzogJ0cnLFxyXG4gICAgJ1xcdUE3QTAnOiAnRycsXHJcbiAgICAnXFx1QTc3RCc6ICdHJyxcclxuICAgICdcXHVBNzdFJzogJ0cnLFxyXG4gICAgJ1xcdTI0QkQnOiAnSCcsXHJcbiAgICAnXFx1RkYyOCc6ICdIJyxcclxuICAgICdcXHUwMTI0JzogJ0gnLFxyXG4gICAgJ1xcdTFFMjInOiAnSCcsXHJcbiAgICAnXFx1MUUyNic6ICdIJyxcclxuICAgICdcXHUwMjFFJzogJ0gnLFxyXG4gICAgJ1xcdTFFMjQnOiAnSCcsXHJcbiAgICAnXFx1MUUyOCc6ICdIJyxcclxuICAgICdcXHUxRTJBJzogJ0gnLFxyXG4gICAgJ1xcdTAxMjYnOiAnSCcsXHJcbiAgICAnXFx1MkM2Nyc6ICdIJyxcclxuICAgICdcXHUyQzc1JzogJ0gnLFxyXG4gICAgJ1xcdUE3OEQnOiAnSCcsXHJcbiAgICAnXFx1MjRCRSc6ICdJJyxcclxuICAgICdcXHVGRjI5JzogJ0knLFxyXG4gICAgJ1xcdTAwQ0MnOiAnSScsXHJcbiAgICAnXFx1MDBDRCc6ICdJJyxcclxuICAgICdcXHUwMENFJzogJ0knLFxyXG4gICAgJ1xcdTAxMjgnOiAnSScsXHJcbiAgICAnXFx1MDEyQSc6ICdJJyxcclxuICAgICdcXHUwMTJDJzogJ0knLFxyXG4gICAgJ1xcdTAxMzAnOiAnSScsXHJcbiAgICAnXFx1MDBDRic6ICdJJyxcclxuICAgICdcXHUxRTJFJzogJ0knLFxyXG4gICAgJ1xcdTFFQzgnOiAnSScsXHJcbiAgICAnXFx1MDFDRic6ICdJJyxcclxuICAgICdcXHUwMjA4JzogJ0knLFxyXG4gICAgJ1xcdTAyMEEnOiAnSScsXHJcbiAgICAnXFx1MUVDQSc6ICdJJyxcclxuICAgICdcXHUwMTJFJzogJ0knLFxyXG4gICAgJ1xcdTFFMkMnOiAnSScsXHJcbiAgICAnXFx1MDE5Nyc6ICdJJyxcclxuICAgICdcXHUyNEJGJzogJ0onLFxyXG4gICAgJ1xcdUZGMkEnOiAnSicsXHJcbiAgICAnXFx1MDEzNCc6ICdKJyxcclxuICAgICdcXHUwMjQ4JzogJ0onLFxyXG4gICAgJ1xcdTI0QzAnOiAnSycsXHJcbiAgICAnXFx1RkYyQic6ICdLJyxcclxuICAgICdcXHUxRTMwJzogJ0snLFxyXG4gICAgJ1xcdTAxRTgnOiAnSycsXHJcbiAgICAnXFx1MUUzMic6ICdLJyxcclxuICAgICdcXHUwMTM2JzogJ0snLFxyXG4gICAgJ1xcdTFFMzQnOiAnSycsXHJcbiAgICAnXFx1MDE5OCc6ICdLJyxcclxuICAgICdcXHUyQzY5JzogJ0snLFxyXG4gICAgJ1xcdUE3NDAnOiAnSycsXHJcbiAgICAnXFx1QTc0Mic6ICdLJyxcclxuICAgICdcXHVBNzQ0JzogJ0snLFxyXG4gICAgJ1xcdUE3QTInOiAnSycsXHJcbiAgICAnXFx1MjRDMSc6ICdMJyxcclxuICAgICdcXHVGRjJDJzogJ0wnLFxyXG4gICAgJ1xcdTAxM0YnOiAnTCcsXHJcbiAgICAnXFx1MDEzOSc6ICdMJyxcclxuICAgICdcXHUwMTNEJzogJ0wnLFxyXG4gICAgJ1xcdTFFMzYnOiAnTCcsXHJcbiAgICAnXFx1MUUzOCc6ICdMJyxcclxuICAgICdcXHUwMTNCJzogJ0wnLFxyXG4gICAgJ1xcdTFFM0MnOiAnTCcsXHJcbiAgICAnXFx1MUUzQSc6ICdMJyxcclxuICAgICdcXHUwMTQxJzogJ0wnLFxyXG4gICAgJ1xcdTAyM0QnOiAnTCcsXHJcbiAgICAnXFx1MkM2Mic6ICdMJyxcclxuICAgICdcXHUyQzYwJzogJ0wnLFxyXG4gICAgJ1xcdUE3NDgnOiAnTCcsXHJcbiAgICAnXFx1QTc0Nic6ICdMJyxcclxuICAgICdcXHVBNzgwJzogJ0wnLFxyXG4gICAgJ1xcdTAxQzcnOiAnTEonLFxyXG4gICAgJ1xcdTAxQzgnOiAnTGonLFxyXG4gICAgJ1xcdTI0QzInOiAnTScsXHJcbiAgICAnXFx1RkYyRCc6ICdNJyxcclxuICAgICdcXHUxRTNFJzogJ00nLFxyXG4gICAgJ1xcdTFFNDAnOiAnTScsXHJcbiAgICAnXFx1MUU0Mic6ICdNJyxcclxuICAgICdcXHUyQzZFJzogJ00nLFxyXG4gICAgJ1xcdTAxOUMnOiAnTScsXHJcbiAgICAnXFx1MjRDMyc6ICdOJyxcclxuICAgICdcXHVGRjJFJzogJ04nLFxyXG4gICAgJ1xcdTAxRjgnOiAnTicsXHJcbiAgICAnXFx1MDE0Myc6ICdOJyxcclxuICAgICdcXHUwMEQxJzogJ04nLFxyXG4gICAgJ1xcdTFFNDQnOiAnTicsXHJcbiAgICAnXFx1MDE0Nyc6ICdOJyxcclxuICAgICdcXHUxRTQ2JzogJ04nLFxyXG4gICAgJ1xcdTAxNDUnOiAnTicsXHJcbiAgICAnXFx1MUU0QSc6ICdOJyxcclxuICAgICdcXHUxRTQ4JzogJ04nLFxyXG4gICAgJ1xcdTAyMjAnOiAnTicsXHJcbiAgICAnXFx1MDE5RCc6ICdOJyxcclxuICAgICdcXHVBNzkwJzogJ04nLFxyXG4gICAgJ1xcdUE3QTQnOiAnTicsXHJcbiAgICAnXFx1MDFDQSc6ICdOSicsXHJcbiAgICAnXFx1MDFDQic6ICdOaicsXHJcbiAgICAnXFx1MjRDNCc6ICdPJyxcclxuICAgICdcXHVGRjJGJzogJ08nLFxyXG4gICAgJ1xcdTAwRDInOiAnTycsXHJcbiAgICAnXFx1MDBEMyc6ICdPJyxcclxuICAgICdcXHUwMEQ0JzogJ08nLFxyXG4gICAgJ1xcdTFFRDInOiAnTycsXHJcbiAgICAnXFx1MUVEMCc6ICdPJyxcclxuICAgICdcXHUxRUQ2JzogJ08nLFxyXG4gICAgJ1xcdTFFRDQnOiAnTycsXHJcbiAgICAnXFx1MDBENSc6ICdPJyxcclxuICAgICdcXHUxRTRDJzogJ08nLFxyXG4gICAgJ1xcdTAyMkMnOiAnTycsXHJcbiAgICAnXFx1MUU0RSc6ICdPJyxcclxuICAgICdcXHUwMTRDJzogJ08nLFxyXG4gICAgJ1xcdTFFNTAnOiAnTycsXHJcbiAgICAnXFx1MUU1Mic6ICdPJyxcclxuICAgICdcXHUwMTRFJzogJ08nLFxyXG4gICAgJ1xcdTAyMkUnOiAnTycsXHJcbiAgICAnXFx1MDIzMCc6ICdPJyxcclxuICAgICdcXHUwMEQ2JzogJ08nLFxyXG4gICAgJ1xcdTAyMkEnOiAnTycsXHJcbiAgICAnXFx1MUVDRSc6ICdPJyxcclxuICAgICdcXHUwMTUwJzogJ08nLFxyXG4gICAgJ1xcdTAxRDEnOiAnTycsXHJcbiAgICAnXFx1MDIwQyc6ICdPJyxcclxuICAgICdcXHUwMjBFJzogJ08nLFxyXG4gICAgJ1xcdTAxQTAnOiAnTycsXHJcbiAgICAnXFx1MUVEQyc6ICdPJyxcclxuICAgICdcXHUxRURBJzogJ08nLFxyXG4gICAgJ1xcdTFFRTAnOiAnTycsXHJcbiAgICAnXFx1MUVERSc6ICdPJyxcclxuICAgICdcXHUxRUUyJzogJ08nLFxyXG4gICAgJ1xcdTFFQ0MnOiAnTycsXHJcbiAgICAnXFx1MUVEOCc6ICdPJyxcclxuICAgICdcXHUwMUVBJzogJ08nLFxyXG4gICAgJ1xcdTAxRUMnOiAnTycsXHJcbiAgICAnXFx1MDBEOCc6ICdPJyxcclxuICAgICdcXHUwMUZFJzogJ08nLFxyXG4gICAgJ1xcdTAxODYnOiAnTycsXHJcbiAgICAnXFx1MDE5Ric6ICdPJyxcclxuICAgICdcXHVBNzRBJzogJ08nLFxyXG4gICAgJ1xcdUE3NEMnOiAnTycsXHJcbiAgICAnXFx1MDFBMic6ICdPSScsXHJcbiAgICAnXFx1QTc0RSc6ICdPTycsXHJcbiAgICAnXFx1MDIyMic6ICdPVScsXHJcbiAgICAnXFx1MjRDNSc6ICdQJyxcclxuICAgICdcXHVGRjMwJzogJ1AnLFxyXG4gICAgJ1xcdTFFNTQnOiAnUCcsXHJcbiAgICAnXFx1MUU1Nic6ICdQJyxcclxuICAgICdcXHUwMUE0JzogJ1AnLFxyXG4gICAgJ1xcdTJDNjMnOiAnUCcsXHJcbiAgICAnXFx1QTc1MCc6ICdQJyxcclxuICAgICdcXHVBNzUyJzogJ1AnLFxyXG4gICAgJ1xcdUE3NTQnOiAnUCcsXHJcbiAgICAnXFx1MjRDNic6ICdRJyxcclxuICAgICdcXHVGRjMxJzogJ1EnLFxyXG4gICAgJ1xcdUE3NTYnOiAnUScsXHJcbiAgICAnXFx1QTc1OCc6ICdRJyxcclxuICAgICdcXHUwMjRBJzogJ1EnLFxyXG4gICAgJ1xcdTI0QzcnOiAnUicsXHJcbiAgICAnXFx1RkYzMic6ICdSJyxcclxuICAgICdcXHUwMTU0JzogJ1InLFxyXG4gICAgJ1xcdTFFNTgnOiAnUicsXHJcbiAgICAnXFx1MDE1OCc6ICdSJyxcclxuICAgICdcXHUwMjEwJzogJ1InLFxyXG4gICAgJ1xcdTAyMTInOiAnUicsXHJcbiAgICAnXFx1MUU1QSc6ICdSJyxcclxuICAgICdcXHUxRTVDJzogJ1InLFxyXG4gICAgJ1xcdTAxNTYnOiAnUicsXHJcbiAgICAnXFx1MUU1RSc6ICdSJyxcclxuICAgICdcXHUwMjRDJzogJ1InLFxyXG4gICAgJ1xcdTJDNjQnOiAnUicsXHJcbiAgICAnXFx1QTc1QSc6ICdSJyxcclxuICAgICdcXHVBN0E2JzogJ1InLFxyXG4gICAgJ1xcdUE3ODInOiAnUicsXHJcbiAgICAnXFx1MjRDOCc6ICdTJyxcclxuICAgICdcXHVGRjMzJzogJ1MnLFxyXG4gICAgJ1xcdTFFOUUnOiAnUycsXHJcbiAgICAnXFx1MDE1QSc6ICdTJyxcclxuICAgICdcXHUxRTY0JzogJ1MnLFxyXG4gICAgJ1xcdTAxNUMnOiAnUycsXHJcbiAgICAnXFx1MUU2MCc6ICdTJyxcclxuICAgICdcXHUwMTYwJzogJ1MnLFxyXG4gICAgJ1xcdTFFNjYnOiAnUycsXHJcbiAgICAnXFx1MUU2Mic6ICdTJyxcclxuICAgICdcXHUxRTY4JzogJ1MnLFxyXG4gICAgJ1xcdTAyMTgnOiAnUycsXHJcbiAgICAnXFx1MDE1RSc6ICdTJyxcclxuICAgICdcXHUyQzdFJzogJ1MnLFxyXG4gICAgJ1xcdUE3QTgnOiAnUycsXHJcbiAgICAnXFx1QTc4NCc6ICdTJyxcclxuICAgICdcXHUyNEM5JzogJ1QnLFxyXG4gICAgJ1xcdUZGMzQnOiAnVCcsXHJcbiAgICAnXFx1MUU2QSc6ICdUJyxcclxuICAgICdcXHUwMTY0JzogJ1QnLFxyXG4gICAgJ1xcdTFFNkMnOiAnVCcsXHJcbiAgICAnXFx1MDIxQSc6ICdUJyxcclxuICAgICdcXHUwMTYyJzogJ1QnLFxyXG4gICAgJ1xcdTFFNzAnOiAnVCcsXHJcbiAgICAnXFx1MUU2RSc6ICdUJyxcclxuICAgICdcXHUwMTY2JzogJ1QnLFxyXG4gICAgJ1xcdTAxQUMnOiAnVCcsXHJcbiAgICAnXFx1MDFBRSc6ICdUJyxcclxuICAgICdcXHUwMjNFJzogJ1QnLFxyXG4gICAgJ1xcdUE3ODYnOiAnVCcsXHJcbiAgICAnXFx1QTcyOCc6ICdUWicsXHJcbiAgICAnXFx1MjRDQSc6ICdVJyxcclxuICAgICdcXHVGRjM1JzogJ1UnLFxyXG4gICAgJ1xcdTAwRDknOiAnVScsXHJcbiAgICAnXFx1MDBEQSc6ICdVJyxcclxuICAgICdcXHUwMERCJzogJ1UnLFxyXG4gICAgJ1xcdTAxNjgnOiAnVScsXHJcbiAgICAnXFx1MUU3OCc6ICdVJyxcclxuICAgICdcXHUwMTZBJzogJ1UnLFxyXG4gICAgJ1xcdTFFN0EnOiAnVScsXHJcbiAgICAnXFx1MDE2Qyc6ICdVJyxcclxuICAgICdcXHUwMERDJzogJ1UnLFxyXG4gICAgJ1xcdTAxREInOiAnVScsXHJcbiAgICAnXFx1MDFENyc6ICdVJyxcclxuICAgICdcXHUwMUQ1JzogJ1UnLFxyXG4gICAgJ1xcdTAxRDknOiAnVScsXHJcbiAgICAnXFx1MUVFNic6ICdVJyxcclxuICAgICdcXHUwMTZFJzogJ1UnLFxyXG4gICAgJ1xcdTAxNzAnOiAnVScsXHJcbiAgICAnXFx1MDFEMyc6ICdVJyxcclxuICAgICdcXHUwMjE0JzogJ1UnLFxyXG4gICAgJ1xcdTAyMTYnOiAnVScsXHJcbiAgICAnXFx1MDFBRic6ICdVJyxcclxuICAgICdcXHUxRUVBJzogJ1UnLFxyXG4gICAgJ1xcdTFFRTgnOiAnVScsXHJcbiAgICAnXFx1MUVFRSc6ICdVJyxcclxuICAgICdcXHUxRUVDJzogJ1UnLFxyXG4gICAgJ1xcdTFFRjAnOiAnVScsXHJcbiAgICAnXFx1MUVFNCc6ICdVJyxcclxuICAgICdcXHUxRTcyJzogJ1UnLFxyXG4gICAgJ1xcdTAxNzInOiAnVScsXHJcbiAgICAnXFx1MUU3Nic6ICdVJyxcclxuICAgICdcXHUxRTc0JzogJ1UnLFxyXG4gICAgJ1xcdTAyNDQnOiAnVScsXHJcbiAgICAnXFx1MjRDQic6ICdWJyxcclxuICAgICdcXHVGRjM2JzogJ1YnLFxyXG4gICAgJ1xcdTFFN0MnOiAnVicsXHJcbiAgICAnXFx1MUU3RSc6ICdWJyxcclxuICAgICdcXHUwMUIyJzogJ1YnLFxyXG4gICAgJ1xcdUE3NUUnOiAnVicsXHJcbiAgICAnXFx1MDI0NSc6ICdWJyxcclxuICAgICdcXHVBNzYwJzogJ1ZZJyxcclxuICAgICdcXHUyNENDJzogJ1cnLFxyXG4gICAgJ1xcdUZGMzcnOiAnVycsXHJcbiAgICAnXFx1MUU4MCc6ICdXJyxcclxuICAgICdcXHUxRTgyJzogJ1cnLFxyXG4gICAgJ1xcdTAxNzQnOiAnVycsXHJcbiAgICAnXFx1MUU4Nic6ICdXJyxcclxuICAgICdcXHUxRTg0JzogJ1cnLFxyXG4gICAgJ1xcdTFFODgnOiAnVycsXHJcbiAgICAnXFx1MkM3Mic6ICdXJyxcclxuICAgICdcXHUyNENEJzogJ1gnLFxyXG4gICAgJ1xcdUZGMzgnOiAnWCcsXHJcbiAgICAnXFx1MUU4QSc6ICdYJyxcclxuICAgICdcXHUxRThDJzogJ1gnLFxyXG4gICAgJ1xcdTI0Q0UnOiAnWScsXHJcbiAgICAnXFx1RkYzOSc6ICdZJyxcclxuICAgICdcXHUxRUYyJzogJ1knLFxyXG4gICAgJ1xcdTAwREQnOiAnWScsXHJcbiAgICAnXFx1MDE3Nic6ICdZJyxcclxuICAgICdcXHUxRUY4JzogJ1knLFxyXG4gICAgJ1xcdTAyMzInOiAnWScsXHJcbiAgICAnXFx1MUU4RSc6ICdZJyxcclxuICAgICdcXHUwMTc4JzogJ1knLFxyXG4gICAgJ1xcdTFFRjYnOiAnWScsXHJcbiAgICAnXFx1MUVGNCc6ICdZJyxcclxuICAgICdcXHUwMUIzJzogJ1knLFxyXG4gICAgJ1xcdTAyNEUnOiAnWScsXHJcbiAgICAnXFx1MUVGRSc6ICdZJyxcclxuICAgICdcXHUyNENGJzogJ1onLFxyXG4gICAgJ1xcdUZGM0EnOiAnWicsXHJcbiAgICAnXFx1MDE3OSc6ICdaJyxcclxuICAgICdcXHUxRTkwJzogJ1onLFxyXG4gICAgJ1xcdTAxN0InOiAnWicsXHJcbiAgICAnXFx1MDE3RCc6ICdaJyxcclxuICAgICdcXHUxRTkyJzogJ1onLFxyXG4gICAgJ1xcdTFFOTQnOiAnWicsXHJcbiAgICAnXFx1MDFCNSc6ICdaJyxcclxuICAgICdcXHUwMjI0JzogJ1onLFxyXG4gICAgJ1xcdTJDN0YnOiAnWicsXHJcbiAgICAnXFx1MkM2Qic6ICdaJyxcclxuICAgICdcXHVBNzYyJzogJ1onLFxyXG4gICAgJ1xcdTI0RDAnOiAnYScsXHJcbiAgICAnXFx1RkY0MSc6ICdhJyxcclxuICAgICdcXHUxRTlBJzogJ2EnLFxyXG4gICAgJ1xcdTAwRTAnOiAnYScsXHJcbiAgICAnXFx1MDBFMSc6ICdhJyxcclxuICAgICdcXHUwMEUyJzogJ2EnLFxyXG4gICAgJ1xcdTFFQTcnOiAnYScsXHJcbiAgICAnXFx1MUVBNSc6ICdhJyxcclxuICAgICdcXHUxRUFCJzogJ2EnLFxyXG4gICAgJ1xcdTFFQTknOiAnYScsXHJcbiAgICAnXFx1MDBFMyc6ICdhJyxcclxuICAgICdcXHUwMTAxJzogJ2EnLFxyXG4gICAgJ1xcdTAxMDMnOiAnYScsXHJcbiAgICAnXFx1MUVCMSc6ICdhJyxcclxuICAgICdcXHUxRUFGJzogJ2EnLFxyXG4gICAgJ1xcdTFFQjUnOiAnYScsXHJcbiAgICAnXFx1MUVCMyc6ICdhJyxcclxuICAgICdcXHUwMjI3JzogJ2EnLFxyXG4gICAgJ1xcdTAxRTEnOiAnYScsXHJcbiAgICAnXFx1MDBFNCc6ICdhJyxcclxuICAgICdcXHUwMURGJzogJ2EnLFxyXG4gICAgJ1xcdTFFQTMnOiAnYScsXHJcbiAgICAnXFx1MDBFNSc6ICdhJyxcclxuICAgICdcXHUwMUZCJzogJ2EnLFxyXG4gICAgJ1xcdTAxQ0UnOiAnYScsXHJcbiAgICAnXFx1MDIwMSc6ICdhJyxcclxuICAgICdcXHUwMjAzJzogJ2EnLFxyXG4gICAgJ1xcdTFFQTEnOiAnYScsXHJcbiAgICAnXFx1MUVBRCc6ICdhJyxcclxuICAgICdcXHUxRUI3JzogJ2EnLFxyXG4gICAgJ1xcdTFFMDEnOiAnYScsXHJcbiAgICAnXFx1MDEwNSc6ICdhJyxcclxuICAgICdcXHUyQzY1JzogJ2EnLFxyXG4gICAgJ1xcdTAyNTAnOiAnYScsXHJcbiAgICAnXFx1QTczMyc6ICdhYScsXHJcbiAgICAnXFx1MDBFNic6ICdhZScsXHJcbiAgICAnXFx1MDFGRCc6ICdhZScsXHJcbiAgICAnXFx1MDFFMyc6ICdhZScsXHJcbiAgICAnXFx1QTczNSc6ICdhbycsXHJcbiAgICAnXFx1QTczNyc6ICdhdScsXHJcbiAgICAnXFx1QTczOSc6ICdhdicsXHJcbiAgICAnXFx1QTczQic6ICdhdicsXHJcbiAgICAnXFx1QTczRCc6ICdheScsXHJcbiAgICAnXFx1MjREMSc6ICdiJyxcclxuICAgICdcXHVGRjQyJzogJ2InLFxyXG4gICAgJ1xcdTFFMDMnOiAnYicsXHJcbiAgICAnXFx1MUUwNSc6ICdiJyxcclxuICAgICdcXHUxRTA3JzogJ2InLFxyXG4gICAgJ1xcdTAxODAnOiAnYicsXHJcbiAgICAnXFx1MDE4Myc6ICdiJyxcclxuICAgICdcXHUwMjUzJzogJ2InLFxyXG4gICAgJ1xcdTI0RDInOiAnYycsXHJcbiAgICAnXFx1RkY0Myc6ICdjJyxcclxuICAgICdcXHUwMTA3JzogJ2MnLFxyXG4gICAgJ1xcdTAxMDknOiAnYycsXHJcbiAgICAnXFx1MDEwQic6ICdjJyxcclxuICAgICdcXHUwMTBEJzogJ2MnLFxyXG4gICAgJ1xcdTAwRTcnOiAnYycsXHJcbiAgICAnXFx1MUUwOSc6ICdjJyxcclxuICAgICdcXHUwMTg4JzogJ2MnLFxyXG4gICAgJ1xcdTAyM0MnOiAnYycsXHJcbiAgICAnXFx1QTczRic6ICdjJyxcclxuICAgICdcXHUyMTg0JzogJ2MnLFxyXG4gICAgJ1xcdTI0RDMnOiAnZCcsXHJcbiAgICAnXFx1RkY0NCc6ICdkJyxcclxuICAgICdcXHUxRTBCJzogJ2QnLFxyXG4gICAgJ1xcdTAxMEYnOiAnZCcsXHJcbiAgICAnXFx1MUUwRCc6ICdkJyxcclxuICAgICdcXHUxRTExJzogJ2QnLFxyXG4gICAgJ1xcdTFFMTMnOiAnZCcsXHJcbiAgICAnXFx1MUUwRic6ICdkJyxcclxuICAgICdcXHUwMTExJzogJ2QnLFxyXG4gICAgJ1xcdTAxOEMnOiAnZCcsXHJcbiAgICAnXFx1MDI1Nic6ICdkJyxcclxuICAgICdcXHUwMjU3JzogJ2QnLFxyXG4gICAgJ1xcdUE3N0EnOiAnZCcsXHJcbiAgICAnXFx1MDFGMyc6ICdkeicsXHJcbiAgICAnXFx1MDFDNic6ICdkeicsXHJcbiAgICAnXFx1MjRENCc6ICdlJyxcclxuICAgICdcXHVGRjQ1JzogJ2UnLFxyXG4gICAgJ1xcdTAwRTgnOiAnZScsXHJcbiAgICAnXFx1MDBFOSc6ICdlJyxcclxuICAgICdcXHUwMEVBJzogJ2UnLFxyXG4gICAgJ1xcdTFFQzEnOiAnZScsXHJcbiAgICAnXFx1MUVCRic6ICdlJyxcclxuICAgICdcXHUxRUM1JzogJ2UnLFxyXG4gICAgJ1xcdTFFQzMnOiAnZScsXHJcbiAgICAnXFx1MUVCRCc6ICdlJyxcclxuICAgICdcXHUwMTEzJzogJ2UnLFxyXG4gICAgJ1xcdTFFMTUnOiAnZScsXHJcbiAgICAnXFx1MUUxNyc6ICdlJyxcclxuICAgICdcXHUwMTE1JzogJ2UnLFxyXG4gICAgJ1xcdTAxMTcnOiAnZScsXHJcbiAgICAnXFx1MDBFQic6ICdlJyxcclxuICAgICdcXHUxRUJCJzogJ2UnLFxyXG4gICAgJ1xcdTAxMUInOiAnZScsXHJcbiAgICAnXFx1MDIwNSc6ICdlJyxcclxuICAgICdcXHUwMjA3JzogJ2UnLFxyXG4gICAgJ1xcdTFFQjknOiAnZScsXHJcbiAgICAnXFx1MUVDNyc6ICdlJyxcclxuICAgICdcXHUwMjI5JzogJ2UnLFxyXG4gICAgJ1xcdTFFMUQnOiAnZScsXHJcbiAgICAnXFx1MDExOSc6ICdlJyxcclxuICAgICdcXHUxRTE5JzogJ2UnLFxyXG4gICAgJ1xcdTFFMUInOiAnZScsXHJcbiAgICAnXFx1MDI0Nyc6ICdlJyxcclxuICAgICdcXHUwMjVCJzogJ2UnLFxyXG4gICAgJ1xcdTAxREQnOiAnZScsXHJcbiAgICAnXFx1MjRENSc6ICdmJyxcclxuICAgICdcXHVGRjQ2JzogJ2YnLFxyXG4gICAgJ1xcdTFFMUYnOiAnZicsXHJcbiAgICAnXFx1MDE5Mic6ICdmJyxcclxuICAgICdcXHVBNzdDJzogJ2YnLFxyXG4gICAgJ1xcdTI0RDYnOiAnZycsXHJcbiAgICAnXFx1RkY0Nyc6ICdnJyxcclxuICAgICdcXHUwMUY1JzogJ2cnLFxyXG4gICAgJ1xcdTAxMUQnOiAnZycsXHJcbiAgICAnXFx1MUUyMSc6ICdnJyxcclxuICAgICdcXHUwMTFGJzogJ2cnLFxyXG4gICAgJ1xcdTAxMjEnOiAnZycsXHJcbiAgICAnXFx1MDFFNyc6ICdnJyxcclxuICAgICdcXHUwMTIzJzogJ2cnLFxyXG4gICAgJ1xcdTAxRTUnOiAnZycsXHJcbiAgICAnXFx1MDI2MCc6ICdnJyxcclxuICAgICdcXHVBN0ExJzogJ2cnLFxyXG4gICAgJ1xcdTFENzknOiAnZycsXHJcbiAgICAnXFx1QTc3Ric6ICdnJyxcclxuICAgICdcXHUyNEQ3JzogJ2gnLFxyXG4gICAgJ1xcdUZGNDgnOiAnaCcsXHJcbiAgICAnXFx1MDEyNSc6ICdoJyxcclxuICAgICdcXHUxRTIzJzogJ2gnLFxyXG4gICAgJ1xcdTFFMjcnOiAnaCcsXHJcbiAgICAnXFx1MDIxRic6ICdoJyxcclxuICAgICdcXHUxRTI1JzogJ2gnLFxyXG4gICAgJ1xcdTFFMjknOiAnaCcsXHJcbiAgICAnXFx1MUUyQic6ICdoJyxcclxuICAgICdcXHUxRTk2JzogJ2gnLFxyXG4gICAgJ1xcdTAxMjcnOiAnaCcsXHJcbiAgICAnXFx1MkM2OCc6ICdoJyxcclxuICAgICdcXHUyQzc2JzogJ2gnLFxyXG4gICAgJ1xcdTAyNjUnOiAnaCcsXHJcbiAgICAnXFx1MDE5NSc6ICdodicsXHJcbiAgICAnXFx1MjREOCc6ICdpJyxcclxuICAgICdcXHVGRjQ5JzogJ2knLFxyXG4gICAgJ1xcdTAwRUMnOiAnaScsXHJcbiAgICAnXFx1MDBFRCc6ICdpJyxcclxuICAgICdcXHUwMEVFJzogJ2knLFxyXG4gICAgJ1xcdTAxMjknOiAnaScsXHJcbiAgICAnXFx1MDEyQic6ICdpJyxcclxuICAgICdcXHUwMTJEJzogJ2knLFxyXG4gICAgJ1xcdTAwRUYnOiAnaScsXHJcbiAgICAnXFx1MUUyRic6ICdpJyxcclxuICAgICdcXHUxRUM5JzogJ2knLFxyXG4gICAgJ1xcdTAxRDAnOiAnaScsXHJcbiAgICAnXFx1MDIwOSc6ICdpJyxcclxuICAgICdcXHUwMjBCJzogJ2knLFxyXG4gICAgJ1xcdTFFQ0InOiAnaScsXHJcbiAgICAnXFx1MDEyRic6ICdpJyxcclxuICAgICdcXHUxRTJEJzogJ2knLFxyXG4gICAgJ1xcdTAyNjgnOiAnaScsXHJcbiAgICAnXFx1MDEzMSc6ICdpJyxcclxuICAgICdcXHUyNEQ5JzogJ2onLFxyXG4gICAgJ1xcdUZGNEEnOiAnaicsXHJcbiAgICAnXFx1MDEzNSc6ICdqJyxcclxuICAgICdcXHUwMUYwJzogJ2onLFxyXG4gICAgJ1xcdTAyNDknOiAnaicsXHJcbiAgICAnXFx1MjREQSc6ICdrJyxcclxuICAgICdcXHVGRjRCJzogJ2snLFxyXG4gICAgJ1xcdTFFMzEnOiAnaycsXHJcbiAgICAnXFx1MDFFOSc6ICdrJyxcclxuICAgICdcXHUxRTMzJzogJ2snLFxyXG4gICAgJ1xcdTAxMzcnOiAnaycsXHJcbiAgICAnXFx1MUUzNSc6ICdrJyxcclxuICAgICdcXHUwMTk5JzogJ2snLFxyXG4gICAgJ1xcdTJDNkEnOiAnaycsXHJcbiAgICAnXFx1QTc0MSc6ICdrJyxcclxuICAgICdcXHVBNzQzJzogJ2snLFxyXG4gICAgJ1xcdUE3NDUnOiAnaycsXHJcbiAgICAnXFx1QTdBMyc6ICdrJyxcclxuICAgICdcXHUyNERCJzogJ2wnLFxyXG4gICAgJ1xcdUZGNEMnOiAnbCcsXHJcbiAgICAnXFx1MDE0MCc6ICdsJyxcclxuICAgICdcXHUwMTNBJzogJ2wnLFxyXG4gICAgJ1xcdTAxM0UnOiAnbCcsXHJcbiAgICAnXFx1MUUzNyc6ICdsJyxcclxuICAgICdcXHUxRTM5JzogJ2wnLFxyXG4gICAgJ1xcdTAxM0MnOiAnbCcsXHJcbiAgICAnXFx1MUUzRCc6ICdsJyxcclxuICAgICdcXHUxRTNCJzogJ2wnLFxyXG4gICAgJ1xcdTAxN0YnOiAnbCcsXHJcbiAgICAnXFx1MDE0Mic6ICdsJyxcclxuICAgICdcXHUwMTlBJzogJ2wnLFxyXG4gICAgJ1xcdTAyNkInOiAnbCcsXHJcbiAgICAnXFx1MkM2MSc6ICdsJyxcclxuICAgICdcXHVBNzQ5JzogJ2wnLFxyXG4gICAgJ1xcdUE3ODEnOiAnbCcsXHJcbiAgICAnXFx1QTc0Nyc6ICdsJyxcclxuICAgICdcXHUwMUM5JzogJ2xqJyxcclxuICAgICdcXHUyNERDJzogJ20nLFxyXG4gICAgJ1xcdUZGNEQnOiAnbScsXHJcbiAgICAnXFx1MUUzRic6ICdtJyxcclxuICAgICdcXHUxRTQxJzogJ20nLFxyXG4gICAgJ1xcdTFFNDMnOiAnbScsXHJcbiAgICAnXFx1MDI3MSc6ICdtJyxcclxuICAgICdcXHUwMjZGJzogJ20nLFxyXG4gICAgJ1xcdTI0REQnOiAnbicsXHJcbiAgICAnXFx1RkY0RSc6ICduJyxcclxuICAgICdcXHUwMUY5JzogJ24nLFxyXG4gICAgJ1xcdTAxNDQnOiAnbicsXHJcbiAgICAnXFx1MDBGMSc6ICduJyxcclxuICAgICdcXHUxRTQ1JzogJ24nLFxyXG4gICAgJ1xcdTAxNDgnOiAnbicsXHJcbiAgICAnXFx1MUU0Nyc6ICduJyxcclxuICAgICdcXHUwMTQ2JzogJ24nLFxyXG4gICAgJ1xcdTFFNEInOiAnbicsXHJcbiAgICAnXFx1MUU0OSc6ICduJyxcclxuICAgICdcXHUwMTlFJzogJ24nLFxyXG4gICAgJ1xcdTAyNzInOiAnbicsXHJcbiAgICAnXFx1MDE0OSc6ICduJyxcclxuICAgICdcXHVBNzkxJzogJ24nLFxyXG4gICAgJ1xcdUE3QTUnOiAnbicsXHJcbiAgICAnXFx1MDFDQyc6ICduaicsXHJcbiAgICAnXFx1MjRERSc6ICdvJyxcclxuICAgICdcXHVGRjRGJzogJ28nLFxyXG4gICAgJ1xcdTAwRjInOiAnbycsXHJcbiAgICAnXFx1MDBGMyc6ICdvJyxcclxuICAgICdcXHUwMEY0JzogJ28nLFxyXG4gICAgJ1xcdTFFRDMnOiAnbycsXHJcbiAgICAnXFx1MUVEMSc6ICdvJyxcclxuICAgICdcXHUxRUQ3JzogJ28nLFxyXG4gICAgJ1xcdTFFRDUnOiAnbycsXHJcbiAgICAnXFx1MDBGNSc6ICdvJyxcclxuICAgICdcXHUxRTREJzogJ28nLFxyXG4gICAgJ1xcdTAyMkQnOiAnbycsXHJcbiAgICAnXFx1MUU0Ric6ICdvJyxcclxuICAgICdcXHUwMTREJzogJ28nLFxyXG4gICAgJ1xcdTFFNTEnOiAnbycsXHJcbiAgICAnXFx1MUU1Myc6ICdvJyxcclxuICAgICdcXHUwMTRGJzogJ28nLFxyXG4gICAgJ1xcdTAyMkYnOiAnbycsXHJcbiAgICAnXFx1MDIzMSc6ICdvJyxcclxuICAgICdcXHUwMEY2JzogJ28nLFxyXG4gICAgJ1xcdTAyMkInOiAnbycsXHJcbiAgICAnXFx1MUVDRic6ICdvJyxcclxuICAgICdcXHUwMTUxJzogJ28nLFxyXG4gICAgJ1xcdTAxRDInOiAnbycsXHJcbiAgICAnXFx1MDIwRCc6ICdvJyxcclxuICAgICdcXHUwMjBGJzogJ28nLFxyXG4gICAgJ1xcdTAxQTEnOiAnbycsXHJcbiAgICAnXFx1MUVERCc6ICdvJyxcclxuICAgICdcXHUxRURCJzogJ28nLFxyXG4gICAgJ1xcdTFFRTEnOiAnbycsXHJcbiAgICAnXFx1MUVERic6ICdvJyxcclxuICAgICdcXHUxRUUzJzogJ28nLFxyXG4gICAgJ1xcdTFFQ0QnOiAnbycsXHJcbiAgICAnXFx1MUVEOSc6ICdvJyxcclxuICAgICdcXHUwMUVCJzogJ28nLFxyXG4gICAgJ1xcdTAxRUQnOiAnbycsXHJcbiAgICAnXFx1MDBGOCc6ICdvJyxcclxuICAgICdcXHUwMUZGJzogJ28nLFxyXG4gICAgJ1xcdTAyNTQnOiAnbycsXHJcbiAgICAnXFx1QTc0Qic6ICdvJyxcclxuICAgICdcXHVBNzREJzogJ28nLFxyXG4gICAgJ1xcdTAyNzUnOiAnbycsXHJcbiAgICAnXFx1MDFBMyc6ICdvaScsXHJcbiAgICAnXFx1MDIyMyc6ICdvdScsXHJcbiAgICAnXFx1QTc0Ric6ICdvbycsXHJcbiAgICAnXFx1MjRERic6ICdwJyxcclxuICAgICdcXHVGRjUwJzogJ3AnLFxyXG4gICAgJ1xcdTFFNTUnOiAncCcsXHJcbiAgICAnXFx1MUU1Nyc6ICdwJyxcclxuICAgICdcXHUwMUE1JzogJ3AnLFxyXG4gICAgJ1xcdTFEN0QnOiAncCcsXHJcbiAgICAnXFx1QTc1MSc6ICdwJyxcclxuICAgICdcXHVBNzUzJzogJ3AnLFxyXG4gICAgJ1xcdUE3NTUnOiAncCcsXHJcbiAgICAnXFx1MjRFMCc6ICdxJyxcclxuICAgICdcXHVGRjUxJzogJ3EnLFxyXG4gICAgJ1xcdTAyNEInOiAncScsXHJcbiAgICAnXFx1QTc1Nyc6ICdxJyxcclxuICAgICdcXHVBNzU5JzogJ3EnLFxyXG4gICAgJ1xcdTI0RTEnOiAncicsXHJcbiAgICAnXFx1RkY1Mic6ICdyJyxcclxuICAgICdcXHUwMTU1JzogJ3InLFxyXG4gICAgJ1xcdTFFNTknOiAncicsXHJcbiAgICAnXFx1MDE1OSc6ICdyJyxcclxuICAgICdcXHUwMjExJzogJ3InLFxyXG4gICAgJ1xcdTAyMTMnOiAncicsXHJcbiAgICAnXFx1MUU1Qic6ICdyJyxcclxuICAgICdcXHUxRTVEJzogJ3InLFxyXG4gICAgJ1xcdTAxNTcnOiAncicsXHJcbiAgICAnXFx1MUU1Ric6ICdyJyxcclxuICAgICdcXHUwMjREJzogJ3InLFxyXG4gICAgJ1xcdTAyN0QnOiAncicsXHJcbiAgICAnXFx1QTc1Qic6ICdyJyxcclxuICAgICdcXHVBN0E3JzogJ3InLFxyXG4gICAgJ1xcdUE3ODMnOiAncicsXHJcbiAgICAnXFx1MjRFMic6ICdzJyxcclxuICAgICdcXHVGRjUzJzogJ3MnLFxyXG4gICAgJ1xcdTAwREYnOiAncycsXHJcbiAgICAnXFx1MDE1Qic6ICdzJyxcclxuICAgICdcXHUxRTY1JzogJ3MnLFxyXG4gICAgJ1xcdTAxNUQnOiAncycsXHJcbiAgICAnXFx1MUU2MSc6ICdzJyxcclxuICAgICdcXHUwMTYxJzogJ3MnLFxyXG4gICAgJ1xcdTFFNjcnOiAncycsXHJcbiAgICAnXFx1MUU2Myc6ICdzJyxcclxuICAgICdcXHUxRTY5JzogJ3MnLFxyXG4gICAgJ1xcdTAyMTknOiAncycsXHJcbiAgICAnXFx1MDE1Ric6ICdzJyxcclxuICAgICdcXHUwMjNGJzogJ3MnLFxyXG4gICAgJ1xcdUE3QTknOiAncycsXHJcbiAgICAnXFx1QTc4NSc6ICdzJyxcclxuICAgICdcXHUxRTlCJzogJ3MnLFxyXG4gICAgJ1xcdTI0RTMnOiAndCcsXHJcbiAgICAnXFx1RkY1NCc6ICd0JyxcclxuICAgICdcXHUxRTZCJzogJ3QnLFxyXG4gICAgJ1xcdTFFOTcnOiAndCcsXHJcbiAgICAnXFx1MDE2NSc6ICd0JyxcclxuICAgICdcXHUxRTZEJzogJ3QnLFxyXG4gICAgJ1xcdTAyMUInOiAndCcsXHJcbiAgICAnXFx1MDE2Myc6ICd0JyxcclxuICAgICdcXHUxRTcxJzogJ3QnLFxyXG4gICAgJ1xcdTFFNkYnOiAndCcsXHJcbiAgICAnXFx1MDE2Nyc6ICd0JyxcclxuICAgICdcXHUwMUFEJzogJ3QnLFxyXG4gICAgJ1xcdTAyODgnOiAndCcsXHJcbiAgICAnXFx1MkM2Nic6ICd0JyxcclxuICAgICdcXHVBNzg3JzogJ3QnLFxyXG4gICAgJ1xcdUE3MjknOiAndHonLFxyXG4gICAgJ1xcdTI0RTQnOiAndScsXHJcbiAgICAnXFx1RkY1NSc6ICd1JyxcclxuICAgICdcXHUwMEY5JzogJ3UnLFxyXG4gICAgJ1xcdTAwRkEnOiAndScsXHJcbiAgICAnXFx1MDBGQic6ICd1JyxcclxuICAgICdcXHUwMTY5JzogJ3UnLFxyXG4gICAgJ1xcdTFFNzknOiAndScsXHJcbiAgICAnXFx1MDE2Qic6ICd1JyxcclxuICAgICdcXHUxRTdCJzogJ3UnLFxyXG4gICAgJ1xcdTAxNkQnOiAndScsXHJcbiAgICAnXFx1MDBGQyc6ICd1JyxcclxuICAgICdcXHUwMURDJzogJ3UnLFxyXG4gICAgJ1xcdTAxRDgnOiAndScsXHJcbiAgICAnXFx1MDFENic6ICd1JyxcclxuICAgICdcXHUwMURBJzogJ3UnLFxyXG4gICAgJ1xcdTFFRTcnOiAndScsXHJcbiAgICAnXFx1MDE2Ric6ICd1JyxcclxuICAgICdcXHUwMTcxJzogJ3UnLFxyXG4gICAgJ1xcdTAxRDQnOiAndScsXHJcbiAgICAnXFx1MDIxNSc6ICd1JyxcclxuICAgICdcXHUwMjE3JzogJ3UnLFxyXG4gICAgJ1xcdTAxQjAnOiAndScsXHJcbiAgICAnXFx1MUVFQic6ICd1JyxcclxuICAgICdcXHUxRUU5JzogJ3UnLFxyXG4gICAgJ1xcdTFFRUYnOiAndScsXHJcbiAgICAnXFx1MUVFRCc6ICd1JyxcclxuICAgICdcXHUxRUYxJzogJ3UnLFxyXG4gICAgJ1xcdTFFRTUnOiAndScsXHJcbiAgICAnXFx1MUU3Myc6ICd1JyxcclxuICAgICdcXHUwMTczJzogJ3UnLFxyXG4gICAgJ1xcdTFFNzcnOiAndScsXHJcbiAgICAnXFx1MUU3NSc6ICd1JyxcclxuICAgICdcXHUwMjg5JzogJ3UnLFxyXG4gICAgJ1xcdTI0RTUnOiAndicsXHJcbiAgICAnXFx1RkY1Nic6ICd2JyxcclxuICAgICdcXHUxRTdEJzogJ3YnLFxyXG4gICAgJ1xcdTFFN0YnOiAndicsXHJcbiAgICAnXFx1MDI4Qic6ICd2JyxcclxuICAgICdcXHVBNzVGJzogJ3YnLFxyXG4gICAgJ1xcdTAyOEMnOiAndicsXHJcbiAgICAnXFx1QTc2MSc6ICd2eScsXHJcbiAgICAnXFx1MjRFNic6ICd3JyxcclxuICAgICdcXHVGRjU3JzogJ3cnLFxyXG4gICAgJ1xcdTFFODEnOiAndycsXHJcbiAgICAnXFx1MUU4Myc6ICd3JyxcclxuICAgICdcXHUwMTc1JzogJ3cnLFxyXG4gICAgJ1xcdTFFODcnOiAndycsXHJcbiAgICAnXFx1MUU4NSc6ICd3JyxcclxuICAgICdcXHUxRTk4JzogJ3cnLFxyXG4gICAgJ1xcdTFFODknOiAndycsXHJcbiAgICAnXFx1MkM3Myc6ICd3JyxcclxuICAgICdcXHUyNEU3JzogJ3gnLFxyXG4gICAgJ1xcdUZGNTgnOiAneCcsXHJcbiAgICAnXFx1MUU4Qic6ICd4JyxcclxuICAgICdcXHUxRThEJzogJ3gnLFxyXG4gICAgJ1xcdTI0RTgnOiAneScsXHJcbiAgICAnXFx1RkY1OSc6ICd5JyxcclxuICAgICdcXHUxRUYzJzogJ3knLFxyXG4gICAgJ1xcdTAwRkQnOiAneScsXHJcbiAgICAnXFx1MDE3Nyc6ICd5JyxcclxuICAgICdcXHUxRUY5JzogJ3knLFxyXG4gICAgJ1xcdTAyMzMnOiAneScsXHJcbiAgICAnXFx1MUU4Ric6ICd5JyxcclxuICAgICdcXHUwMEZGJzogJ3knLFxyXG4gICAgJ1xcdTFFRjcnOiAneScsXHJcbiAgICAnXFx1MUU5OSc6ICd5JyxcclxuICAgICdcXHUxRUY1JzogJ3knLFxyXG4gICAgJ1xcdTAxQjQnOiAneScsXHJcbiAgICAnXFx1MDI0Ric6ICd5JyxcclxuICAgICdcXHUxRUZGJzogJ3knLFxyXG4gICAgJ1xcdTI0RTknOiAneicsXHJcbiAgICAnXFx1RkY1QSc6ICd6JyxcclxuICAgICdcXHUwMTdBJzogJ3onLFxyXG4gICAgJ1xcdTFFOTEnOiAneicsXHJcbiAgICAnXFx1MDE3Qyc6ICd6JyxcclxuICAgICdcXHUwMTdFJzogJ3onLFxyXG4gICAgJ1xcdTFFOTMnOiAneicsXHJcbiAgICAnXFx1MUU5NSc6ICd6JyxcclxuICAgICdcXHUwMUI2JzogJ3onLFxyXG4gICAgJ1xcdTAyMjUnOiAneicsXHJcbiAgICAnXFx1MDI0MCc6ICd6JyxcclxuICAgICdcXHUyQzZDJzogJ3onLFxyXG4gICAgJ1xcdUE3NjMnOiAneicsXHJcbiAgICAnXFx1MDM4Nic6ICdcXHUwMzkxJyxcclxuICAgICdcXHUwMzg4JzogJ1xcdTAzOTUnLFxyXG4gICAgJ1xcdTAzODknOiAnXFx1MDM5NycsXHJcbiAgICAnXFx1MDM4QSc6ICdcXHUwMzk5JyxcclxuICAgICdcXHUwM0FBJzogJ1xcdTAzOTknLFxyXG4gICAgJ1xcdTAzOEMnOiAnXFx1MDM5RicsXHJcbiAgICAnXFx1MDM4RSc6ICdcXHUwM0E1JyxcclxuICAgICdcXHUwM0FCJzogJ1xcdTAzQTUnLFxyXG4gICAgJ1xcdTAzOEYnOiAnXFx1MDNBOScsXHJcbiAgICAnXFx1MDNBQyc6ICdcXHUwM0IxJyxcclxuICAgICdcXHUwM0FEJzogJ1xcdTAzQjUnLFxyXG4gICAgJ1xcdTAzQUUnOiAnXFx1MDNCNycsXHJcbiAgICAnXFx1MDNBRic6ICdcXHUwM0I5JyxcclxuICAgICdcXHUwM0NBJzogJ1xcdTAzQjknLFxyXG4gICAgJ1xcdTAzOTAnOiAnXFx1MDNCOScsXHJcbiAgICAnXFx1MDNDQyc6ICdcXHUwM0JGJyxcclxuICAgICdcXHUwM0NEJzogJ1xcdTAzQzUnLFxyXG4gICAgJ1xcdTAzQ0InOiAnXFx1MDNDNScsXHJcbiAgICAnXFx1MDNCMCc6ICdcXHUwM0M1JyxcclxuICAgICdcXHUwM0M5JzogJ1xcdTAzQzknLFxyXG4gICAgJ1xcdTAzQzInOiAnXFx1MDNDMydcclxuICB9O1xyXG5cclxuICByZXR1cm4gZGlhY3JpdGljcztcclxufSk7XHJcblxuUzIuZGVmaW5lKCdzZWxlY3QyL2RhdGEvYmFzZScsW1xyXG4gICcuLi91dGlscydcclxuXSwgZnVuY3Rpb24gKFV0aWxzKSB7XHJcbiAgZnVuY3Rpb24gQmFzZUFkYXB0ZXIgKCRlbGVtZW50LCBvcHRpb25zKSB7XHJcbiAgICBCYXNlQWRhcHRlci5fX3N1cGVyX18uY29uc3RydWN0b3IuY2FsbCh0aGlzKTtcclxuICB9XHJcblxyXG4gIFV0aWxzLkV4dGVuZChCYXNlQWRhcHRlciwgVXRpbHMuT2JzZXJ2YWJsZSk7XHJcblxyXG4gIEJhc2VBZGFwdGVyLnByb3RvdHlwZS5jdXJyZW50ID0gZnVuY3Rpb24gKGNhbGxiYWNrKSB7XHJcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ1RoZSBgY3VycmVudGAgbWV0aG9kIG11c3QgYmUgZGVmaW5lZCBpbiBjaGlsZCBjbGFzc2VzLicpO1xyXG4gIH07XHJcblxyXG4gIEJhc2VBZGFwdGVyLnByb3RvdHlwZS5xdWVyeSA9IGZ1bmN0aW9uIChwYXJhbXMsIGNhbGxiYWNrKSB7XHJcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ1RoZSBgcXVlcnlgIG1ldGhvZCBtdXN0IGJlIGRlZmluZWQgaW4gY2hpbGQgY2xhc3Nlcy4nKTtcclxuICB9O1xyXG5cclxuICBCYXNlQWRhcHRlci5wcm90b3R5cGUuYmluZCA9IGZ1bmN0aW9uIChjb250YWluZXIsICRjb250YWluZXIpIHtcclxuICAgIC8vIENhbiBiZSBpbXBsZW1lbnRlZCBpbiBzdWJjbGFzc2VzXHJcbiAgfTtcclxuXHJcbiAgQmFzZUFkYXB0ZXIucHJvdG90eXBlLmRlc3Ryb3kgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAvLyBDYW4gYmUgaW1wbGVtZW50ZWQgaW4gc3ViY2xhc3Nlc1xyXG4gIH07XHJcblxyXG4gIEJhc2VBZGFwdGVyLnByb3RvdHlwZS5nZW5lcmF0ZVJlc3VsdElkID0gZnVuY3Rpb24gKGNvbnRhaW5lciwgZGF0YSkge1xyXG4gICAgdmFyIGlkID0gY29udGFpbmVyLmlkICsgJy1yZXN1bHQtJztcclxuXHJcbiAgICBpZCArPSBVdGlscy5nZW5lcmF0ZUNoYXJzKDQpO1xyXG5cclxuICAgIGlmIChkYXRhLmlkICE9IG51bGwpIHtcclxuICAgICAgaWQgKz0gJy0nICsgZGF0YS5pZC50b1N0cmluZygpO1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgaWQgKz0gJy0nICsgVXRpbHMuZ2VuZXJhdGVDaGFycyg0KTtcclxuICAgIH1cclxuICAgIHJldHVybiBpZDtcclxuICB9O1xyXG5cclxuICByZXR1cm4gQmFzZUFkYXB0ZXI7XHJcbn0pO1xyXG5cblMyLmRlZmluZSgnc2VsZWN0Mi9kYXRhL3NlbGVjdCcsW1xyXG4gICcuL2Jhc2UnLFxyXG4gICcuLi91dGlscycsXHJcbiAgJ2pxdWVyeSdcclxuXSwgZnVuY3Rpb24gKEJhc2VBZGFwdGVyLCBVdGlscywgJCkge1xyXG4gIGZ1bmN0aW9uIFNlbGVjdEFkYXB0ZXIgKCRlbGVtZW50LCBvcHRpb25zKSB7XHJcbiAgICB0aGlzLiRlbGVtZW50ID0gJGVsZW1lbnQ7XHJcbiAgICB0aGlzLm9wdGlvbnMgPSBvcHRpb25zO1xyXG5cclxuICAgIFNlbGVjdEFkYXB0ZXIuX19zdXBlcl9fLmNvbnN0cnVjdG9yLmNhbGwodGhpcyk7XHJcbiAgfVxyXG5cclxuICBVdGlscy5FeHRlbmQoU2VsZWN0QWRhcHRlciwgQmFzZUFkYXB0ZXIpO1xyXG5cclxuICBTZWxlY3RBZGFwdGVyLnByb3RvdHlwZS5jdXJyZW50ID0gZnVuY3Rpb24gKGNhbGxiYWNrKSB7XHJcbiAgICB2YXIgZGF0YSA9IFtdO1xyXG4gICAgdmFyIHNlbGYgPSB0aGlzO1xyXG5cclxuICAgIHRoaXMuJGVsZW1lbnQuZmluZCgnOnNlbGVjdGVkJykuZWFjaChmdW5jdGlvbiAoKSB7XHJcbiAgICAgIHZhciAkb3B0aW9uID0gJCh0aGlzKTtcclxuXHJcbiAgICAgIHZhciBvcHRpb24gPSBzZWxmLml0ZW0oJG9wdGlvbik7XHJcblxyXG4gICAgICBkYXRhLnB1c2gob3B0aW9uKTtcclxuICAgIH0pO1xyXG5cclxuICAgIGNhbGxiYWNrKGRhdGEpO1xyXG4gIH07XHJcblxyXG4gIFNlbGVjdEFkYXB0ZXIucHJvdG90eXBlLnNlbGVjdCA9IGZ1bmN0aW9uIChkYXRhKSB7XHJcbiAgICB2YXIgc2VsZiA9IHRoaXM7XHJcblxyXG4gICAgZGF0YS5zZWxlY3RlZCA9IHRydWU7XHJcblxyXG4gICAgLy8gSWYgZGF0YS5lbGVtZW50IGlzIGEgRE9NIG5vZGUsIHVzZSBpdCBpbnN0ZWFkXHJcbiAgICBpZiAoJChkYXRhLmVsZW1lbnQpLmlzKCdvcHRpb24nKSkge1xyXG4gICAgICBkYXRhLmVsZW1lbnQuc2VsZWN0ZWQgPSB0cnVlO1xyXG5cclxuICAgICAgdGhpcy4kZWxlbWVudC50cmlnZ2VyKCdjaGFuZ2UnKTtcclxuXHJcbiAgICAgIHJldHVybjtcclxuICAgIH1cclxuXHJcbiAgICBpZiAodGhpcy4kZWxlbWVudC5wcm9wKCdtdWx0aXBsZScpKSB7XHJcbiAgICAgIHRoaXMuY3VycmVudChmdW5jdGlvbiAoY3VycmVudERhdGEpIHtcclxuICAgICAgICB2YXIgdmFsID0gW107XHJcblxyXG4gICAgICAgIGRhdGEgPSBbZGF0YV07XHJcbiAgICAgICAgZGF0YS5wdXNoLmFwcGx5KGRhdGEsIGN1cnJlbnREYXRhKTtcclxuXHJcbiAgICAgICAgZm9yICh2YXIgZCA9IDA7IGQgPCBkYXRhLmxlbmd0aDsgZCsrKSB7XHJcbiAgICAgICAgICB2YXIgaWQgPSBkYXRhW2RdLmlkO1xyXG5cclxuICAgICAgICAgIGlmICgkLmluQXJyYXkoaWQsIHZhbCkgPT09IC0xKSB7XHJcbiAgICAgICAgICAgIHZhbC5wdXNoKGlkKTtcclxuICAgICAgICAgIH1cclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHNlbGYuJGVsZW1lbnQudmFsKHZhbCk7XHJcbiAgICAgICAgc2VsZi4kZWxlbWVudC50cmlnZ2VyKCdjaGFuZ2UnKTtcclxuICAgICAgfSk7XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICB2YXIgdmFsID0gZGF0YS5pZDtcclxuXHJcbiAgICAgIHRoaXMuJGVsZW1lbnQudmFsKHZhbCk7XHJcbiAgICAgIHRoaXMuJGVsZW1lbnQudHJpZ2dlcignY2hhbmdlJyk7XHJcbiAgICB9XHJcbiAgfTtcclxuXHJcbiAgU2VsZWN0QWRhcHRlci5wcm90b3R5cGUudW5zZWxlY3QgPSBmdW5jdGlvbiAoZGF0YSkge1xyXG4gICAgdmFyIHNlbGYgPSB0aGlzO1xyXG5cclxuICAgIGlmICghdGhpcy4kZWxlbWVudC5wcm9wKCdtdWx0aXBsZScpKSB7XHJcbiAgICAgIHJldHVybjtcclxuICAgIH1cclxuXHJcbiAgICBkYXRhLnNlbGVjdGVkID0gZmFsc2U7XHJcblxyXG4gICAgaWYgKCQoZGF0YS5lbGVtZW50KS5pcygnb3B0aW9uJykpIHtcclxuICAgICAgZGF0YS5lbGVtZW50LnNlbGVjdGVkID0gZmFsc2U7XHJcblxyXG4gICAgICB0aGlzLiRlbGVtZW50LnRyaWdnZXIoJ2NoYW5nZScpO1xyXG5cclxuICAgICAgcmV0dXJuO1xyXG4gICAgfVxyXG5cclxuICAgIHRoaXMuY3VycmVudChmdW5jdGlvbiAoY3VycmVudERhdGEpIHtcclxuICAgICAgdmFyIHZhbCA9IFtdO1xyXG5cclxuICAgICAgZm9yICh2YXIgZCA9IDA7IGQgPCBjdXJyZW50RGF0YS5sZW5ndGg7IGQrKykge1xyXG4gICAgICAgIHZhciBpZCA9IGN1cnJlbnREYXRhW2RdLmlkO1xyXG5cclxuICAgICAgICBpZiAoaWQgIT09IGRhdGEuaWQgJiYgJC5pbkFycmF5KGlkLCB2YWwpID09PSAtMSkge1xyXG4gICAgICAgICAgdmFsLnB1c2goaWQpO1xyXG4gICAgICAgIH1cclxuICAgICAgfVxyXG5cclxuICAgICAgc2VsZi4kZWxlbWVudC52YWwodmFsKTtcclxuXHJcbiAgICAgIHNlbGYuJGVsZW1lbnQudHJpZ2dlcignY2hhbmdlJyk7XHJcbiAgICB9KTtcclxuICB9O1xyXG5cclxuICBTZWxlY3RBZGFwdGVyLnByb3RvdHlwZS5iaW5kID0gZnVuY3Rpb24gKGNvbnRhaW5lciwgJGNvbnRhaW5lcikge1xyXG4gICAgdmFyIHNlbGYgPSB0aGlzO1xyXG5cclxuICAgIHRoaXMuY29udGFpbmVyID0gY29udGFpbmVyO1xyXG5cclxuICAgIGNvbnRhaW5lci5vbignc2VsZWN0JywgZnVuY3Rpb24gKHBhcmFtcykge1xyXG4gICAgICBzZWxmLnNlbGVjdChwYXJhbXMuZGF0YSk7XHJcbiAgICB9KTtcclxuXHJcbiAgICBjb250YWluZXIub24oJ3Vuc2VsZWN0JywgZnVuY3Rpb24gKHBhcmFtcykge1xyXG4gICAgICBzZWxmLnVuc2VsZWN0KHBhcmFtcy5kYXRhKTtcclxuICAgIH0pO1xyXG4gIH07XHJcblxyXG4gIFNlbGVjdEFkYXB0ZXIucHJvdG90eXBlLmRlc3Ryb3kgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAvLyBSZW1vdmUgYW55dGhpbmcgYWRkZWQgdG8gY2hpbGQgZWxlbWVudHNcclxuICAgIHRoaXMuJGVsZW1lbnQuZmluZCgnKicpLmVhY2goZnVuY3Rpb24gKCkge1xyXG4gICAgICAvLyBSZW1vdmUgYW55IGN1c3RvbSBkYXRhIHNldCBieSBTZWxlY3QyXHJcbiAgICAgICQucmVtb3ZlRGF0YSh0aGlzLCAnZGF0YScpO1xyXG4gICAgfSk7XHJcbiAgfTtcclxuXHJcbiAgU2VsZWN0QWRhcHRlci5wcm90b3R5cGUucXVlcnkgPSBmdW5jdGlvbiAocGFyYW1zLCBjYWxsYmFjaykge1xyXG4gICAgdmFyIGRhdGEgPSBbXTtcclxuICAgIHZhciBzZWxmID0gdGhpcztcclxuXHJcbiAgICB2YXIgJG9wdGlvbnMgPSB0aGlzLiRlbGVtZW50LmNoaWxkcmVuKCk7XHJcblxyXG4gICAgJG9wdGlvbnMuZWFjaChmdW5jdGlvbiAoKSB7XHJcbiAgICAgIHZhciAkb3B0aW9uID0gJCh0aGlzKTtcclxuXHJcbiAgICAgIGlmICghJG9wdGlvbi5pcygnb3B0aW9uJykgJiYgISRvcHRpb24uaXMoJ29wdGdyb3VwJykpIHtcclxuICAgICAgICByZXR1cm47XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIHZhciBvcHRpb24gPSBzZWxmLml0ZW0oJG9wdGlvbik7XHJcblxyXG4gICAgICB2YXIgbWF0Y2hlcyA9IHNlbGYubWF0Y2hlcyhwYXJhbXMsIG9wdGlvbik7XHJcblxyXG4gICAgICBpZiAobWF0Y2hlcyAhPT0gbnVsbCkge1xyXG4gICAgICAgIGRhdGEucHVzaChtYXRjaGVzKTtcclxuICAgICAgfVxyXG4gICAgfSk7XHJcblxyXG4gICAgY2FsbGJhY2soe1xyXG4gICAgICByZXN1bHRzOiBkYXRhXHJcbiAgICB9KTtcclxuICB9O1xyXG5cclxuICBTZWxlY3RBZGFwdGVyLnByb3RvdHlwZS5hZGRPcHRpb25zID0gZnVuY3Rpb24gKCRvcHRpb25zKSB7XHJcbiAgICBVdGlscy5hcHBlbmRNYW55KHRoaXMuJGVsZW1lbnQsICRvcHRpb25zKTtcclxuICB9O1xyXG5cclxuICBTZWxlY3RBZGFwdGVyLnByb3RvdHlwZS5vcHRpb24gPSBmdW5jdGlvbiAoZGF0YSkge1xyXG4gICAgdmFyIG9wdGlvbjtcclxuXHJcbiAgICBpZiAoZGF0YS5jaGlsZHJlbikge1xyXG4gICAgICBvcHRpb24gPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdvcHRncm91cCcpO1xyXG4gICAgICBvcHRpb24ubGFiZWwgPSBkYXRhLnRleHQ7XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICBvcHRpb24gPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdvcHRpb24nKTtcclxuXHJcbiAgICAgIGlmIChvcHRpb24udGV4dENvbnRlbnQgIT09IHVuZGVmaW5lZCkge1xyXG4gICAgICAgIG9wdGlvbi50ZXh0Q29udGVudCA9IGRhdGEudGV4dDtcclxuICAgICAgfSBlbHNlIHtcclxuICAgICAgICBvcHRpb24uaW5uZXJUZXh0ID0gZGF0YS50ZXh0O1xyXG4gICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKGRhdGEuaWQpIHtcclxuICAgICAgb3B0aW9uLnZhbHVlID0gZGF0YS5pZDtcclxuICAgIH1cclxuXHJcbiAgICBpZiAoZGF0YS5kaXNhYmxlZCkge1xyXG4gICAgICBvcHRpb24uZGlzYWJsZWQgPSB0cnVlO1xyXG4gICAgfVxyXG5cclxuICAgIGlmIChkYXRhLnNlbGVjdGVkKSB7XHJcbiAgICAgIG9wdGlvbi5zZWxlY3RlZCA9IHRydWU7XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKGRhdGEudGl0bGUpIHtcclxuICAgICAgb3B0aW9uLnRpdGxlID0gZGF0YS50aXRsZTtcclxuICAgIH1cclxuXHJcbiAgICB2YXIgJG9wdGlvbiA9ICQob3B0aW9uKTtcclxuXHJcbiAgICB2YXIgbm9ybWFsaXplZERhdGEgPSB0aGlzLl9ub3JtYWxpemVJdGVtKGRhdGEpO1xyXG4gICAgbm9ybWFsaXplZERhdGEuZWxlbWVudCA9IG9wdGlvbjtcclxuXHJcbiAgICAvLyBPdmVycmlkZSB0aGUgb3B0aW9uJ3MgZGF0YSB3aXRoIHRoZSBjb21iaW5lZCBkYXRhXHJcbiAgICAkLmRhdGEob3B0aW9uLCAnZGF0YScsIG5vcm1hbGl6ZWREYXRhKTtcclxuXHJcbiAgICByZXR1cm4gJG9wdGlvbjtcclxuICB9O1xyXG5cclxuICBTZWxlY3RBZGFwdGVyLnByb3RvdHlwZS5pdGVtID0gZnVuY3Rpb24gKCRvcHRpb24pIHtcclxuICAgIHZhciBkYXRhID0ge307XHJcblxyXG4gICAgZGF0YSA9ICQuZGF0YSgkb3B0aW9uWzBdLCAnZGF0YScpO1xyXG5cclxuICAgIGlmIChkYXRhICE9IG51bGwpIHtcclxuICAgICAgcmV0dXJuIGRhdGE7XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKCRvcHRpb24uaXMoJ29wdGlvbicpKSB7XHJcbiAgICAgIGRhdGEgPSB7XHJcbiAgICAgICAgaWQ6ICRvcHRpb24udmFsKCksXHJcbiAgICAgICAgdGV4dDogJG9wdGlvbi50ZXh0KCksXHJcbiAgICAgICAgZGlzYWJsZWQ6ICRvcHRpb24ucHJvcCgnZGlzYWJsZWQnKSxcclxuICAgICAgICBzZWxlY3RlZDogJG9wdGlvbi5wcm9wKCdzZWxlY3RlZCcpLFxyXG4gICAgICAgIHRpdGxlOiAkb3B0aW9uLnByb3AoJ3RpdGxlJylcclxuICAgICAgfTtcclxuICAgIH0gZWxzZSBpZiAoJG9wdGlvbi5pcygnb3B0Z3JvdXAnKSkge1xyXG4gICAgICBkYXRhID0ge1xyXG4gICAgICAgIHRleHQ6ICRvcHRpb24ucHJvcCgnbGFiZWwnKSxcclxuICAgICAgICBjaGlsZHJlbjogW10sXHJcbiAgICAgICAgdGl0bGU6ICRvcHRpb24ucHJvcCgndGl0bGUnKVxyXG4gICAgICB9O1xyXG5cclxuICAgICAgdmFyICRjaGlsZHJlbiA9ICRvcHRpb24uY2hpbGRyZW4oJ29wdGlvbicpO1xyXG4gICAgICB2YXIgY2hpbGRyZW4gPSBbXTtcclxuXHJcbiAgICAgIGZvciAodmFyIGMgPSAwOyBjIDwgJGNoaWxkcmVuLmxlbmd0aDsgYysrKSB7XHJcbiAgICAgICAgdmFyICRjaGlsZCA9ICQoJGNoaWxkcmVuW2NdKTtcclxuXHJcbiAgICAgICAgdmFyIGNoaWxkID0gdGhpcy5pdGVtKCRjaGlsZCk7XHJcblxyXG4gICAgICAgIGNoaWxkcmVuLnB1c2goY2hpbGQpO1xyXG4gICAgICB9XHJcblxyXG4gICAgICBkYXRhLmNoaWxkcmVuID0gY2hpbGRyZW47XHJcbiAgICB9XHJcblxyXG4gICAgZGF0YSA9IHRoaXMuX25vcm1hbGl6ZUl0ZW0oZGF0YSk7XHJcbiAgICBkYXRhLmVsZW1lbnQgPSAkb3B0aW9uWzBdO1xyXG5cclxuICAgICQuZGF0YSgkb3B0aW9uWzBdLCAnZGF0YScsIGRhdGEpO1xyXG5cclxuICAgIHJldHVybiBkYXRhO1xyXG4gIH07XHJcblxyXG4gIFNlbGVjdEFkYXB0ZXIucHJvdG90eXBlLl9ub3JtYWxpemVJdGVtID0gZnVuY3Rpb24gKGl0ZW0pIHtcclxuICAgIGlmICghJC5pc1BsYWluT2JqZWN0KGl0ZW0pKSB7XHJcbiAgICAgIGl0ZW0gPSB7XHJcbiAgICAgICAgaWQ6IGl0ZW0sXHJcbiAgICAgICAgdGV4dDogaXRlbVxyXG4gICAgICB9O1xyXG4gICAgfVxyXG5cclxuICAgIGl0ZW0gPSAkLmV4dGVuZCh7fSwge1xyXG4gICAgICB0ZXh0OiAnJ1xyXG4gICAgfSwgaXRlbSk7XHJcblxyXG4gICAgdmFyIGRlZmF1bHRzID0ge1xyXG4gICAgICBzZWxlY3RlZDogZmFsc2UsXHJcbiAgICAgIGRpc2FibGVkOiBmYWxzZVxyXG4gICAgfTtcclxuXHJcbiAgICBpZiAoaXRlbS5pZCAhPSBudWxsKSB7XHJcbiAgICAgIGl0ZW0uaWQgPSBpdGVtLmlkLnRvU3RyaW5nKCk7XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKGl0ZW0udGV4dCAhPSBudWxsKSB7XHJcbiAgICAgIGl0ZW0udGV4dCA9IGl0ZW0udGV4dC50b1N0cmluZygpO1xyXG4gICAgfVxyXG5cclxuICAgIGlmIChpdGVtLl9yZXN1bHRJZCA9PSBudWxsICYmIGl0ZW0uaWQgJiYgdGhpcy5jb250YWluZXIgIT0gbnVsbCkge1xyXG4gICAgICBpdGVtLl9yZXN1bHRJZCA9IHRoaXMuZ2VuZXJhdGVSZXN1bHRJZCh0aGlzLmNvbnRhaW5lciwgaXRlbSk7XHJcbiAgICB9XHJcblxyXG4gICAgcmV0dXJuICQuZXh0ZW5kKHt9LCBkZWZhdWx0cywgaXRlbSk7XHJcbiAgfTtcclxuXHJcbiAgU2VsZWN0QWRhcHRlci5wcm90b3R5cGUubWF0Y2hlcyA9IGZ1bmN0aW9uIChwYXJhbXMsIGRhdGEpIHtcclxuICAgIHZhciBtYXRjaGVyID0gdGhpcy5vcHRpb25zLmdldCgnbWF0Y2hlcicpO1xyXG5cclxuICAgIHJldHVybiBtYXRjaGVyKHBhcmFtcywgZGF0YSk7XHJcbiAgfTtcclxuXHJcbiAgcmV0dXJuIFNlbGVjdEFkYXB0ZXI7XHJcbn0pO1xyXG5cblMyLmRlZmluZSgnc2VsZWN0Mi9kYXRhL2FycmF5JyxbXHJcbiAgJy4vc2VsZWN0JyxcclxuICAnLi4vdXRpbHMnLFxyXG4gICdqcXVlcnknXHJcbl0sIGZ1bmN0aW9uIChTZWxlY3RBZGFwdGVyLCBVdGlscywgJCkge1xyXG4gIGZ1bmN0aW9uIEFycmF5QWRhcHRlciAoJGVsZW1lbnQsIG9wdGlvbnMpIHtcclxuICAgIHZhciBkYXRhID0gb3B0aW9ucy5nZXQoJ2RhdGEnKSB8fCBbXTtcclxuXHJcbiAgICBBcnJheUFkYXB0ZXIuX19zdXBlcl9fLmNvbnN0cnVjdG9yLmNhbGwodGhpcywgJGVsZW1lbnQsIG9wdGlvbnMpO1xyXG5cclxuICAgIHRoaXMuYWRkT3B0aW9ucyh0aGlzLmNvbnZlcnRUb09wdGlvbnMoZGF0YSkpO1xyXG4gIH1cclxuXHJcbiAgVXRpbHMuRXh0ZW5kKEFycmF5QWRhcHRlciwgU2VsZWN0QWRhcHRlcik7XHJcblxyXG4gIEFycmF5QWRhcHRlci5wcm90b3R5cGUuc2VsZWN0ID0gZnVuY3Rpb24gKGRhdGEpIHtcclxuICAgIHZhciAkb3B0aW9uID0gdGhpcy4kZWxlbWVudC5maW5kKCdvcHRpb24nKS5maWx0ZXIoZnVuY3Rpb24gKGksIGVsbSkge1xyXG4gICAgICByZXR1cm4gZWxtLnZhbHVlID09IGRhdGEuaWQudG9TdHJpbmcoKTtcclxuICAgIH0pO1xyXG5cclxuICAgIGlmICgkb3B0aW9uLmxlbmd0aCA9PT0gMCkge1xyXG4gICAgICAkb3B0aW9uID0gdGhpcy5vcHRpb24oZGF0YSk7XHJcblxyXG4gICAgICB0aGlzLmFkZE9wdGlvbnMoJG9wdGlvbik7XHJcbiAgICB9XHJcblxyXG4gICAgQXJyYXlBZGFwdGVyLl9fc3VwZXJfXy5zZWxlY3QuY2FsbCh0aGlzLCBkYXRhKTtcclxuICB9O1xyXG5cclxuICBBcnJheUFkYXB0ZXIucHJvdG90eXBlLmNvbnZlcnRUb09wdGlvbnMgPSBmdW5jdGlvbiAoZGF0YSkge1xyXG4gICAgdmFyIHNlbGYgPSB0aGlzO1xyXG5cclxuICAgIHZhciAkZXhpc3RpbmcgPSB0aGlzLiRlbGVtZW50LmZpbmQoJ29wdGlvbicpO1xyXG4gICAgdmFyIGV4aXN0aW5nSWRzID0gJGV4aXN0aW5nLm1hcChmdW5jdGlvbiAoKSB7XHJcbiAgICAgIHJldHVybiBzZWxmLml0ZW0oJCh0aGlzKSkuaWQ7XHJcbiAgICB9KS5nZXQoKTtcclxuXHJcbiAgICB2YXIgJG9wdGlvbnMgPSBbXTtcclxuXHJcbiAgICAvLyBGaWx0ZXIgb3V0IGFsbCBpdGVtcyBleGNlcHQgZm9yIHRoZSBvbmUgcGFzc2VkIGluIHRoZSBhcmd1bWVudFxyXG4gICAgZnVuY3Rpb24gb25seUl0ZW0gKGl0ZW0pIHtcclxuICAgICAgcmV0dXJuIGZ1bmN0aW9uICgpIHtcclxuICAgICAgICByZXR1cm4gJCh0aGlzKS52YWwoKSA9PSBpdGVtLmlkO1xyXG4gICAgICB9O1xyXG4gICAgfVxyXG5cclxuICAgIGZvciAodmFyIGQgPSAwOyBkIDwgZGF0YS5sZW5ndGg7IGQrKykge1xyXG4gICAgICB2YXIgaXRlbSA9IHRoaXMuX25vcm1hbGl6ZUl0ZW0oZGF0YVtkXSk7XHJcblxyXG4gICAgICAvLyBTa2lwIGl0ZW1zIHdoaWNoIHdlcmUgcHJlLWxvYWRlZCwgb25seSBtZXJnZSB0aGUgZGF0YVxyXG4gICAgICBpZiAoJC5pbkFycmF5KGl0ZW0uaWQsIGV4aXN0aW5nSWRzKSA+PSAwKSB7XHJcbiAgICAgICAgdmFyICRleGlzdGluZ09wdGlvbiA9ICRleGlzdGluZy5maWx0ZXIob25seUl0ZW0oaXRlbSkpO1xyXG5cclxuICAgICAgICB2YXIgZXhpc3RpbmdEYXRhID0gdGhpcy5pdGVtKCRleGlzdGluZ09wdGlvbik7XHJcbiAgICAgICAgdmFyIG5ld0RhdGEgPSAkLmV4dGVuZCh0cnVlLCB7fSwgaXRlbSwgZXhpc3RpbmdEYXRhKTtcclxuXHJcbiAgICAgICAgdmFyICRuZXdPcHRpb24gPSB0aGlzLm9wdGlvbihuZXdEYXRhKTtcclxuXHJcbiAgICAgICAgJGV4aXN0aW5nT3B0aW9uLnJlcGxhY2VXaXRoKCRuZXdPcHRpb24pO1xyXG5cclxuICAgICAgICBjb250aW51ZTtcclxuICAgICAgfVxyXG5cclxuICAgICAgdmFyICRvcHRpb24gPSB0aGlzLm9wdGlvbihpdGVtKTtcclxuXHJcbiAgICAgIGlmIChpdGVtLmNoaWxkcmVuKSB7XHJcbiAgICAgICAgdmFyICRjaGlsZHJlbiA9IHRoaXMuY29udmVydFRvT3B0aW9ucyhpdGVtLmNoaWxkcmVuKTtcclxuXHJcbiAgICAgICAgVXRpbHMuYXBwZW5kTWFueSgkb3B0aW9uLCAkY2hpbGRyZW4pO1xyXG4gICAgICB9XHJcblxyXG4gICAgICAkb3B0aW9ucy5wdXNoKCRvcHRpb24pO1xyXG4gICAgfVxyXG5cclxuICAgIHJldHVybiAkb3B0aW9ucztcclxuICB9O1xyXG5cclxuICByZXR1cm4gQXJyYXlBZGFwdGVyO1xyXG59KTtcclxuXG5TMi5kZWZpbmUoJ3NlbGVjdDIvZGF0YS9hamF4JyxbXHJcbiAgJy4vYXJyYXknLFxyXG4gICcuLi91dGlscycsXHJcbiAgJ2pxdWVyeSdcclxuXSwgZnVuY3Rpb24gKEFycmF5QWRhcHRlciwgVXRpbHMsICQpIHtcclxuICBmdW5jdGlvbiBBamF4QWRhcHRlciAoJGVsZW1lbnQsIG9wdGlvbnMpIHtcclxuICAgIHRoaXMuYWpheE9wdGlvbnMgPSB0aGlzLl9hcHBseURlZmF1bHRzKG9wdGlvbnMuZ2V0KCdhamF4JykpO1xyXG5cclxuICAgIGlmICh0aGlzLmFqYXhPcHRpb25zLnByb2Nlc3NSZXN1bHRzICE9IG51bGwpIHtcclxuICAgICAgdGhpcy5wcm9jZXNzUmVzdWx0cyA9IHRoaXMuYWpheE9wdGlvbnMucHJvY2Vzc1Jlc3VsdHM7XHJcbiAgICB9XHJcblxyXG4gICAgQWpheEFkYXB0ZXIuX19zdXBlcl9fLmNvbnN0cnVjdG9yLmNhbGwodGhpcywgJGVsZW1lbnQsIG9wdGlvbnMpO1xyXG4gIH1cclxuXHJcbiAgVXRpbHMuRXh0ZW5kKEFqYXhBZGFwdGVyLCBBcnJheUFkYXB0ZXIpO1xyXG5cclxuICBBamF4QWRhcHRlci5wcm90b3R5cGUuX2FwcGx5RGVmYXVsdHMgPSBmdW5jdGlvbiAob3B0aW9ucykge1xyXG4gICAgdmFyIGRlZmF1bHRzID0ge1xyXG4gICAgICBkYXRhOiBmdW5jdGlvbiAocGFyYW1zKSB7XHJcbiAgICAgICAgcmV0dXJuICQuZXh0ZW5kKHt9LCBwYXJhbXMsIHtcclxuICAgICAgICAgIHE6IHBhcmFtcy50ZXJtXHJcbiAgICAgICAgfSk7XHJcbiAgICAgIH0sXHJcbiAgICAgIHRyYW5zcG9ydDogZnVuY3Rpb24gKHBhcmFtcywgc3VjY2VzcywgZmFpbHVyZSkge1xyXG4gICAgICAgIHZhciAkcmVxdWVzdCA9ICQuYWpheChwYXJhbXMpO1xyXG5cclxuICAgICAgICAkcmVxdWVzdC50aGVuKHN1Y2Nlc3MpO1xyXG4gICAgICAgICRyZXF1ZXN0LmZhaWwoZmFpbHVyZSk7XHJcblxyXG4gICAgICAgIHJldHVybiAkcmVxdWVzdDtcclxuICAgICAgfVxyXG4gICAgfTtcclxuXHJcbiAgICByZXR1cm4gJC5leHRlbmQoe30sIGRlZmF1bHRzLCBvcHRpb25zLCB0cnVlKTtcclxuICB9O1xyXG5cclxuICBBamF4QWRhcHRlci5wcm90b3R5cGUucHJvY2Vzc1Jlc3VsdHMgPSBmdW5jdGlvbiAocmVzdWx0cykge1xyXG4gICAgcmV0dXJuIHJlc3VsdHM7XHJcbiAgfTtcclxuXHJcbiAgQWpheEFkYXB0ZXIucHJvdG90eXBlLnF1ZXJ5ID0gZnVuY3Rpb24gKHBhcmFtcywgY2FsbGJhY2spIHtcclxuICAgIHZhciBtYXRjaGVzID0gW107XHJcbiAgICB2YXIgc2VsZiA9IHRoaXM7XHJcblxyXG4gICAgaWYgKHRoaXMuX3JlcXVlc3QgIT0gbnVsbCkge1xyXG4gICAgICAvLyBKU09OUCByZXF1ZXN0cyBjYW5ub3QgYWx3YXlzIGJlIGFib3J0ZWRcclxuICAgICAgaWYgKCQuaXNGdW5jdGlvbih0aGlzLl9yZXF1ZXN0LmFib3J0KSkge1xyXG4gICAgICAgIHRoaXMuX3JlcXVlc3QuYWJvcnQoKTtcclxuICAgICAgfVxyXG5cclxuICAgICAgdGhpcy5fcmVxdWVzdCA9IG51bGw7XHJcbiAgICB9XHJcblxyXG4gICAgdmFyIG9wdGlvbnMgPSAkLmV4dGVuZCh7XHJcbiAgICAgIHR5cGU6ICdHRVQnXHJcbiAgICB9LCB0aGlzLmFqYXhPcHRpb25zKTtcclxuXHJcbiAgICBpZiAodHlwZW9mIG9wdGlvbnMudXJsID09PSAnZnVuY3Rpb24nKSB7XHJcbiAgICAgIG9wdGlvbnMudXJsID0gb3B0aW9ucy51cmwuY2FsbCh0aGlzLiRlbGVtZW50LCBwYXJhbXMpO1xyXG4gICAgfVxyXG5cclxuICAgIGlmICh0eXBlb2Ygb3B0aW9ucy5kYXRhID09PSAnZnVuY3Rpb24nKSB7XHJcbiAgICAgIG9wdGlvbnMuZGF0YSA9IG9wdGlvbnMuZGF0YS5jYWxsKHRoaXMuJGVsZW1lbnQsIHBhcmFtcyk7XHJcbiAgICB9XHJcblxyXG4gICAgZnVuY3Rpb24gcmVxdWVzdCAoKSB7XHJcbiAgICAgIHZhciAkcmVxdWVzdCA9IG9wdGlvbnMudHJhbnNwb3J0KG9wdGlvbnMsIGZ1bmN0aW9uIChkYXRhKSB7XHJcbiAgICAgICAgdmFyIHJlc3VsdHMgPSBzZWxmLnByb2Nlc3NSZXN1bHRzKGRhdGEsIHBhcmFtcyk7XHJcblxyXG4gICAgICAgIGlmIChzZWxmLm9wdGlvbnMuZ2V0KCdkZWJ1ZycpICYmIHdpbmRvdy5jb25zb2xlICYmIGNvbnNvbGUuZXJyb3IpIHtcclxuICAgICAgICAgIC8vIENoZWNrIHRvIG1ha2Ugc3VyZSB0aGF0IHRoZSByZXNwb25zZSBpbmNsdWRlZCBhIGByZXN1bHRzYCBrZXkuXHJcbiAgICAgICAgICBpZiAoIXJlc3VsdHMgfHwgIXJlc3VsdHMucmVzdWx0cyB8fCAhJC5pc0FycmF5KHJlc3VsdHMucmVzdWx0cykpIHtcclxuICAgICAgICAgICAgY29uc29sZS5lcnJvcihcclxuICAgICAgICAgICAgICAnU2VsZWN0MjogVGhlIEFKQVggcmVzdWx0cyBkaWQgbm90IHJldHVybiBhbiBhcnJheSBpbiB0aGUgJyArXHJcbiAgICAgICAgICAgICAgJ2ByZXN1bHRzYCBrZXkgb2YgdGhlIHJlc3BvbnNlLidcclxuICAgICAgICAgICAgKTtcclxuICAgICAgICAgIH1cclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGNhbGxiYWNrKHJlc3VsdHMpO1xyXG4gICAgICB9LCBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgLy8gQXR0ZW1wdCB0byBkZXRlY3QgaWYgYSByZXF1ZXN0IHdhcyBhYm9ydGVkXHJcbiAgICAgICAgLy8gT25seSB3b3JrcyBpZiB0aGUgdHJhbnNwb3J0IGV4cG9zZXMgYSBzdGF0dXMgcHJvcGVydHlcclxuICAgICAgICBpZiAoJHJlcXVlc3Quc3RhdHVzICYmICRyZXF1ZXN0LnN0YXR1cyA9PT0gJzAnKSB7XHJcbiAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBzZWxmLnRyaWdnZXIoJ3Jlc3VsdHM6bWVzc2FnZScsIHtcclxuICAgICAgICAgIG1lc3NhZ2U6ICdlcnJvckxvYWRpbmcnXHJcbiAgICAgICAgfSk7XHJcbiAgICAgIH0pO1xyXG5cclxuICAgICAgc2VsZi5fcmVxdWVzdCA9ICRyZXF1ZXN0O1xyXG4gICAgfVxyXG5cclxuICAgIGlmICh0aGlzLmFqYXhPcHRpb25zLmRlbGF5ICYmIHBhcmFtcy50ZXJtICE9IG51bGwpIHtcclxuICAgICAgaWYgKHRoaXMuX3F1ZXJ5VGltZW91dCkge1xyXG4gICAgICAgIHdpbmRvdy5jbGVhclRpbWVvdXQodGhpcy5fcXVlcnlUaW1lb3V0KTtcclxuICAgICAgfVxyXG5cclxuICAgICAgdGhpcy5fcXVlcnlUaW1lb3V0ID0gd2luZG93LnNldFRpbWVvdXQocmVxdWVzdCwgdGhpcy5hamF4T3B0aW9ucy5kZWxheSk7XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICByZXF1ZXN0KCk7XHJcbiAgICB9XHJcbiAgfTtcclxuXHJcbiAgcmV0dXJuIEFqYXhBZGFwdGVyO1xyXG59KTtcclxuXG5TMi5kZWZpbmUoJ3NlbGVjdDIvZGF0YS90YWdzJyxbXHJcbiAgJ2pxdWVyeSdcclxuXSwgZnVuY3Rpb24gKCQpIHtcclxuICBmdW5jdGlvbiBUYWdzIChkZWNvcmF0ZWQsICRlbGVtZW50LCBvcHRpb25zKSB7XHJcbiAgICB2YXIgdGFncyA9IG9wdGlvbnMuZ2V0KCd0YWdzJyk7XHJcblxyXG4gICAgdmFyIGNyZWF0ZVRhZyA9IG9wdGlvbnMuZ2V0KCdjcmVhdGVUYWcnKTtcclxuXHJcbiAgICBpZiAoY3JlYXRlVGFnICE9PSB1bmRlZmluZWQpIHtcclxuICAgICAgdGhpcy5jcmVhdGVUYWcgPSBjcmVhdGVUYWc7XHJcbiAgICB9XHJcblxyXG4gICAgdmFyIGluc2VydFRhZyA9IG9wdGlvbnMuZ2V0KCdpbnNlcnRUYWcnKTtcclxuXHJcbiAgICBpZiAoaW5zZXJ0VGFnICE9PSB1bmRlZmluZWQpIHtcclxuICAgICAgICB0aGlzLmluc2VydFRhZyA9IGluc2VydFRhZztcclxuICAgIH1cclxuXHJcbiAgICBkZWNvcmF0ZWQuY2FsbCh0aGlzLCAkZWxlbWVudCwgb3B0aW9ucyk7XHJcblxyXG4gICAgaWYgKCQuaXNBcnJheSh0YWdzKSkge1xyXG4gICAgICBmb3IgKHZhciB0ID0gMDsgdCA8IHRhZ3MubGVuZ3RoOyB0KyspIHtcclxuICAgICAgICB2YXIgdGFnID0gdGFnc1t0XTtcclxuICAgICAgICB2YXIgaXRlbSA9IHRoaXMuX25vcm1hbGl6ZUl0ZW0odGFnKTtcclxuXHJcbiAgICAgICAgdmFyICRvcHRpb24gPSB0aGlzLm9wdGlvbihpdGVtKTtcclxuXHJcbiAgICAgICAgdGhpcy4kZWxlbWVudC5hcHBlbmQoJG9wdGlvbik7XHJcbiAgICAgIH1cclxuICAgIH1cclxuICB9XHJcblxyXG4gIFRhZ3MucHJvdG90eXBlLnF1ZXJ5ID0gZnVuY3Rpb24gKGRlY29yYXRlZCwgcGFyYW1zLCBjYWxsYmFjaykge1xyXG4gICAgdmFyIHNlbGYgPSB0aGlzO1xyXG5cclxuICAgIHRoaXMuX3JlbW92ZU9sZFRhZ3MoKTtcclxuXHJcbiAgICBpZiAocGFyYW1zLnRlcm0gPT0gbnVsbCB8fCBwYXJhbXMucGFnZSAhPSBudWxsKSB7XHJcbiAgICAgIGRlY29yYXRlZC5jYWxsKHRoaXMsIHBhcmFtcywgY2FsbGJhY2spO1xyXG4gICAgICByZXR1cm47XHJcbiAgICB9XHJcblxyXG4gICAgZnVuY3Rpb24gd3JhcHBlciAob2JqLCBjaGlsZCkge1xyXG4gICAgICB2YXIgZGF0YSA9IG9iai5yZXN1bHRzO1xyXG5cclxuICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBkYXRhLmxlbmd0aDsgaSsrKSB7XHJcbiAgICAgICAgdmFyIG9wdGlvbiA9IGRhdGFbaV07XHJcblxyXG4gICAgICAgIHZhciBjaGVja0NoaWxkcmVuID0gKFxyXG4gICAgICAgICAgb3B0aW9uLmNoaWxkcmVuICE9IG51bGwgJiZcclxuICAgICAgICAgICF3cmFwcGVyKHtcclxuICAgICAgICAgICAgcmVzdWx0czogb3B0aW9uLmNoaWxkcmVuXHJcbiAgICAgICAgICB9LCB0cnVlKVxyXG4gICAgICAgICk7XHJcblxyXG4gICAgICAgIHZhciBjaGVja1RleHQgPSBvcHRpb24udGV4dCA9PT0gcGFyYW1zLnRlcm07XHJcblxyXG4gICAgICAgIGlmIChjaGVja1RleHQgfHwgY2hlY2tDaGlsZHJlbikge1xyXG4gICAgICAgICAgaWYgKGNoaWxkKSB7XHJcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcclxuICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICBvYmouZGF0YSA9IGRhdGE7XHJcbiAgICAgICAgICBjYWxsYmFjayhvYmopO1xyXG5cclxuICAgICAgICAgIHJldHVybjtcclxuICAgICAgICB9XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIGlmIChjaGlsZCkge1xyXG4gICAgICAgIHJldHVybiB0cnVlO1xyXG4gICAgICB9XHJcblxyXG4gICAgICB2YXIgdGFnID0gc2VsZi5jcmVhdGVUYWcocGFyYW1zKTtcclxuXHJcbiAgICAgIGlmICh0YWcgIT0gbnVsbCkge1xyXG4gICAgICAgIHZhciAkb3B0aW9uID0gc2VsZi5vcHRpb24odGFnKTtcclxuICAgICAgICAkb3B0aW9uLmF0dHIoJ2RhdGEtc2VsZWN0Mi10YWcnLCB0cnVlKTtcclxuXHJcbiAgICAgICAgc2VsZi5hZGRPcHRpb25zKFskb3B0aW9uXSk7XHJcblxyXG4gICAgICAgIHNlbGYuaW5zZXJ0VGFnKGRhdGEsIHRhZyk7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIG9iai5yZXN1bHRzID0gZGF0YTtcclxuXHJcbiAgICAgIGNhbGxiYWNrKG9iaik7XHJcbiAgICB9XHJcblxyXG4gICAgZGVjb3JhdGVkLmNhbGwodGhpcywgcGFyYW1zLCB3cmFwcGVyKTtcclxuICB9O1xyXG5cclxuICBUYWdzLnByb3RvdHlwZS5jcmVhdGVUYWcgPSBmdW5jdGlvbiAoZGVjb3JhdGVkLCBwYXJhbXMpIHtcclxuICAgIHZhciB0ZXJtID0gJC50cmltKHBhcmFtcy50ZXJtKTtcclxuXHJcbiAgICBpZiAodGVybSA9PT0gJycpIHtcclxuICAgICAgcmV0dXJuIG51bGw7XHJcbiAgICB9XHJcblxyXG4gICAgcmV0dXJuIHtcclxuICAgICAgaWQ6IHRlcm0sXHJcbiAgICAgIHRleHQ6IHRlcm1cclxuICAgIH07XHJcbiAgfTtcclxuXHJcbiAgVGFncy5wcm90b3R5cGUuaW5zZXJ0VGFnID0gZnVuY3Rpb24gKF8sIGRhdGEsIHRhZykge1xyXG4gICAgZGF0YS51bnNoaWZ0KHRhZyk7XHJcbiAgfTtcclxuXHJcbiAgVGFncy5wcm90b3R5cGUuX3JlbW92ZU9sZFRhZ3MgPSBmdW5jdGlvbiAoXykge1xyXG4gICAgdmFyIHRhZyA9IHRoaXMuX2xhc3RUYWc7XHJcblxyXG4gICAgdmFyICRvcHRpb25zID0gdGhpcy4kZWxlbWVudC5maW5kKCdvcHRpb25bZGF0YS1zZWxlY3QyLXRhZ10nKTtcclxuXHJcbiAgICAkb3B0aW9ucy5lYWNoKGZ1bmN0aW9uICgpIHtcclxuICAgICAgaWYgKHRoaXMuc2VsZWN0ZWQpIHtcclxuICAgICAgICByZXR1cm47XHJcbiAgICAgIH1cclxuXHJcbiAgICAgICQodGhpcykucmVtb3ZlKCk7XHJcbiAgICB9KTtcclxuICB9O1xyXG5cclxuICByZXR1cm4gVGFncztcclxufSk7XHJcblxuUzIuZGVmaW5lKCdzZWxlY3QyL2RhdGEvdG9rZW5pemVyJyxbXHJcbiAgJ2pxdWVyeSdcclxuXSwgZnVuY3Rpb24gKCQpIHtcclxuICBmdW5jdGlvbiBUb2tlbml6ZXIgKGRlY29yYXRlZCwgJGVsZW1lbnQsIG9wdGlvbnMpIHtcclxuICAgIHZhciB0b2tlbml6ZXIgPSBvcHRpb25zLmdldCgndG9rZW5pemVyJyk7XHJcblxyXG4gICAgaWYgKHRva2VuaXplciAhPT0gdW5kZWZpbmVkKSB7XHJcbiAgICAgIHRoaXMudG9rZW5pemVyID0gdG9rZW5pemVyO1xyXG4gICAgfVxyXG5cclxuICAgIGRlY29yYXRlZC5jYWxsKHRoaXMsICRlbGVtZW50LCBvcHRpb25zKTtcclxuICB9XHJcblxyXG4gIFRva2VuaXplci5wcm90b3R5cGUuYmluZCA9IGZ1bmN0aW9uIChkZWNvcmF0ZWQsIGNvbnRhaW5lciwgJGNvbnRhaW5lcikge1xyXG4gICAgZGVjb3JhdGVkLmNhbGwodGhpcywgY29udGFpbmVyLCAkY29udGFpbmVyKTtcclxuXHJcbiAgICB0aGlzLiRzZWFyY2ggPSAgY29udGFpbmVyLmRyb3Bkb3duLiRzZWFyY2ggfHwgY29udGFpbmVyLnNlbGVjdGlvbi4kc2VhcmNoIHx8XHJcbiAgICAgICRjb250YWluZXIuZmluZCgnLnNlbGVjdDItc2VhcmNoX19maWVsZCcpO1xyXG4gIH07XHJcblxyXG4gIFRva2VuaXplci5wcm90b3R5cGUucXVlcnkgPSBmdW5jdGlvbiAoZGVjb3JhdGVkLCBwYXJhbXMsIGNhbGxiYWNrKSB7XHJcbiAgICB2YXIgc2VsZiA9IHRoaXM7XHJcblxyXG4gICAgZnVuY3Rpb24gY3JlYXRlQW5kU2VsZWN0IChkYXRhKSB7XHJcbiAgICAgIC8vIE5vcm1hbGl6ZSB0aGUgZGF0YSBvYmplY3Qgc28gd2UgY2FuIHVzZSBpdCBmb3IgY2hlY2tzXHJcbiAgICAgIHZhciBpdGVtID0gc2VsZi5fbm9ybWFsaXplSXRlbShkYXRhKTtcclxuXHJcbiAgICAgIC8vIENoZWNrIGlmIHRoZSBkYXRhIG9iamVjdCBhbHJlYWR5IGV4aXN0cyBhcyBhIHRhZ1xyXG4gICAgICAvLyBTZWxlY3QgaXQgaWYgaXQgZG9lc24ndFxyXG4gICAgICB2YXIgJGV4aXN0aW5nT3B0aW9ucyA9IHNlbGYuJGVsZW1lbnQuZmluZCgnb3B0aW9uJykuZmlsdGVyKGZ1bmN0aW9uICgpIHtcclxuICAgICAgICByZXR1cm4gJCh0aGlzKS52YWwoKSA9PT0gaXRlbS5pZDtcclxuICAgICAgfSk7XHJcblxyXG4gICAgICAvLyBJZiBhbiBleGlzdGluZyBvcHRpb24gd2Fzbid0IGZvdW5kIGZvciBpdCwgY3JlYXRlIHRoZSBvcHRpb25cclxuICAgICAgaWYgKCEkZXhpc3RpbmdPcHRpb25zLmxlbmd0aCkge1xyXG4gICAgICAgIHZhciAkb3B0aW9uID0gc2VsZi5vcHRpb24oaXRlbSk7XHJcbiAgICAgICAgJG9wdGlvbi5hdHRyKCdkYXRhLXNlbGVjdDItdGFnJywgdHJ1ZSk7XHJcblxyXG4gICAgICAgIHNlbGYuX3JlbW92ZU9sZFRhZ3MoKTtcclxuICAgICAgICBzZWxmLmFkZE9wdGlvbnMoWyRvcHRpb25dKTtcclxuICAgICAgfVxyXG5cclxuICAgICAgLy8gU2VsZWN0IHRoZSBpdGVtLCBub3cgdGhhdCB3ZSBrbm93IHRoZXJlIGlzIGFuIG9wdGlvbiBmb3IgaXRcclxuICAgICAgc2VsZWN0KGl0ZW0pO1xyXG4gICAgfVxyXG5cclxuICAgIGZ1bmN0aW9uIHNlbGVjdCAoZGF0YSkge1xyXG4gICAgICBzZWxmLnRyaWdnZXIoJ3NlbGVjdCcsIHtcclxuICAgICAgICBkYXRhOiBkYXRhXHJcbiAgICAgIH0pO1xyXG4gICAgfVxyXG5cclxuICAgIHBhcmFtcy50ZXJtID0gcGFyYW1zLnRlcm0gfHwgJyc7XHJcblxyXG4gICAgdmFyIHRva2VuRGF0YSA9IHRoaXMudG9rZW5pemVyKHBhcmFtcywgdGhpcy5vcHRpb25zLCBjcmVhdGVBbmRTZWxlY3QpO1xyXG5cclxuICAgIGlmICh0b2tlbkRhdGEudGVybSAhPT0gcGFyYW1zLnRlcm0pIHtcclxuICAgICAgLy8gUmVwbGFjZSB0aGUgc2VhcmNoIHRlcm0gaWYgd2UgaGF2ZSB0aGUgc2VhcmNoIGJveFxyXG4gICAgICBpZiAodGhpcy4kc2VhcmNoLmxlbmd0aCkge1xyXG4gICAgICAgIHRoaXMuJHNlYXJjaC52YWwodG9rZW5EYXRhLnRlcm0pO1xyXG4gICAgICAgIHRoaXMuJHNlYXJjaC5mb2N1cygpO1xyXG4gICAgICB9XHJcblxyXG4gICAgICBwYXJhbXMudGVybSA9IHRva2VuRGF0YS50ZXJtO1xyXG4gICAgfVxyXG5cclxuICAgIGRlY29yYXRlZC5jYWxsKHRoaXMsIHBhcmFtcywgY2FsbGJhY2spO1xyXG4gIH07XHJcblxyXG4gIFRva2VuaXplci5wcm90b3R5cGUudG9rZW5pemVyID0gZnVuY3Rpb24gKF8sIHBhcmFtcywgb3B0aW9ucywgY2FsbGJhY2spIHtcclxuICAgIHZhciBzZXBhcmF0b3JzID0gb3B0aW9ucy5nZXQoJ3Rva2VuU2VwYXJhdG9ycycpIHx8IFtdO1xyXG4gICAgdmFyIHRlcm0gPSBwYXJhbXMudGVybTtcclxuICAgIHZhciBpID0gMDtcclxuXHJcbiAgICB2YXIgY3JlYXRlVGFnID0gdGhpcy5jcmVhdGVUYWcgfHwgZnVuY3Rpb24gKHBhcmFtcykge1xyXG4gICAgICByZXR1cm4ge1xyXG4gICAgICAgIGlkOiBwYXJhbXMudGVybSxcclxuICAgICAgICB0ZXh0OiBwYXJhbXMudGVybVxyXG4gICAgICB9O1xyXG4gICAgfTtcclxuXHJcbiAgICB3aGlsZSAoaSA8IHRlcm0ubGVuZ3RoKSB7XHJcbiAgICAgIHZhciB0ZXJtQ2hhciA9IHRlcm1baV07XHJcblxyXG4gICAgICBpZiAoJC5pbkFycmF5KHRlcm1DaGFyLCBzZXBhcmF0b3JzKSA9PT0gLTEpIHtcclxuICAgICAgICBpKys7XHJcblxyXG4gICAgICAgIGNvbnRpbnVlO1xyXG4gICAgICB9XHJcblxyXG4gICAgICB2YXIgcGFydCA9IHRlcm0uc3Vic3RyKDAsIGkpO1xyXG4gICAgICB2YXIgcGFydFBhcmFtcyA9ICQuZXh0ZW5kKHt9LCBwYXJhbXMsIHtcclxuICAgICAgICB0ZXJtOiBwYXJ0XHJcbiAgICAgIH0pO1xyXG5cclxuICAgICAgdmFyIGRhdGEgPSBjcmVhdGVUYWcocGFydFBhcmFtcyk7XHJcblxyXG4gICAgICBpZiAoZGF0YSA9PSBudWxsKSB7XHJcbiAgICAgICAgaSsrO1xyXG4gICAgICAgIGNvbnRpbnVlO1xyXG4gICAgICB9XHJcblxyXG4gICAgICBjYWxsYmFjayhkYXRhKTtcclxuXHJcbiAgICAgIC8vIFJlc2V0IHRoZSB0ZXJtIHRvIG5vdCBpbmNsdWRlIHRoZSB0b2tlbml6ZWQgcG9ydGlvblxyXG4gICAgICB0ZXJtID0gdGVybS5zdWJzdHIoaSArIDEpIHx8ICcnO1xyXG4gICAgICBpID0gMDtcclxuICAgIH1cclxuXHJcbiAgICByZXR1cm4ge1xyXG4gICAgICB0ZXJtOiB0ZXJtXHJcbiAgICB9O1xyXG4gIH07XHJcblxyXG4gIHJldHVybiBUb2tlbml6ZXI7XHJcbn0pO1xyXG5cblMyLmRlZmluZSgnc2VsZWN0Mi9kYXRhL21pbmltdW1JbnB1dExlbmd0aCcsW1xyXG5cclxuXSwgZnVuY3Rpb24gKCkge1xyXG4gIGZ1bmN0aW9uIE1pbmltdW1JbnB1dExlbmd0aCAoZGVjb3JhdGVkLCAkZSwgb3B0aW9ucykge1xyXG4gICAgdGhpcy5taW5pbXVtSW5wdXRMZW5ndGggPSBvcHRpb25zLmdldCgnbWluaW11bUlucHV0TGVuZ3RoJyk7XHJcblxyXG4gICAgZGVjb3JhdGVkLmNhbGwodGhpcywgJGUsIG9wdGlvbnMpO1xyXG4gIH1cclxuXHJcbiAgTWluaW11bUlucHV0TGVuZ3RoLnByb3RvdHlwZS5xdWVyeSA9IGZ1bmN0aW9uIChkZWNvcmF0ZWQsIHBhcmFtcywgY2FsbGJhY2spIHtcclxuICAgIHBhcmFtcy50ZXJtID0gcGFyYW1zLnRlcm0gfHwgJyc7XHJcblxyXG4gICAgaWYgKHBhcmFtcy50ZXJtLmxlbmd0aCA8IHRoaXMubWluaW11bUlucHV0TGVuZ3RoKSB7XHJcbiAgICAgIHRoaXMudHJpZ2dlcigncmVzdWx0czptZXNzYWdlJywge1xyXG4gICAgICAgIG1lc3NhZ2U6ICdpbnB1dFRvb1Nob3J0JyxcclxuICAgICAgICBhcmdzOiB7XHJcbiAgICAgICAgICBtaW5pbXVtOiB0aGlzLm1pbmltdW1JbnB1dExlbmd0aCxcclxuICAgICAgICAgIGlucHV0OiBwYXJhbXMudGVybSxcclxuICAgICAgICAgIHBhcmFtczogcGFyYW1zXHJcbiAgICAgICAgfVxyXG4gICAgICB9KTtcclxuXHJcbiAgICAgIHJldHVybjtcclxuICAgIH1cclxuXHJcbiAgICBkZWNvcmF0ZWQuY2FsbCh0aGlzLCBwYXJhbXMsIGNhbGxiYWNrKTtcclxuICB9O1xyXG5cclxuICByZXR1cm4gTWluaW11bUlucHV0TGVuZ3RoO1xyXG59KTtcclxuXG5TMi5kZWZpbmUoJ3NlbGVjdDIvZGF0YS9tYXhpbXVtSW5wdXRMZW5ndGgnLFtcclxuXHJcbl0sIGZ1bmN0aW9uICgpIHtcclxuICBmdW5jdGlvbiBNYXhpbXVtSW5wdXRMZW5ndGggKGRlY29yYXRlZCwgJGUsIG9wdGlvbnMpIHtcclxuICAgIHRoaXMubWF4aW11bUlucHV0TGVuZ3RoID0gb3B0aW9ucy5nZXQoJ21heGltdW1JbnB1dExlbmd0aCcpO1xyXG5cclxuICAgIGRlY29yYXRlZC5jYWxsKHRoaXMsICRlLCBvcHRpb25zKTtcclxuICB9XHJcblxyXG4gIE1heGltdW1JbnB1dExlbmd0aC5wcm90b3R5cGUucXVlcnkgPSBmdW5jdGlvbiAoZGVjb3JhdGVkLCBwYXJhbXMsIGNhbGxiYWNrKSB7XHJcbiAgICBwYXJhbXMudGVybSA9IHBhcmFtcy50ZXJtIHx8ICcnO1xyXG5cclxuICAgIGlmICh0aGlzLm1heGltdW1JbnB1dExlbmd0aCA+IDAgJiZcclxuICAgICAgICBwYXJhbXMudGVybS5sZW5ndGggPiB0aGlzLm1heGltdW1JbnB1dExlbmd0aCkge1xyXG4gICAgICB0aGlzLnRyaWdnZXIoJ3Jlc3VsdHM6bWVzc2FnZScsIHtcclxuICAgICAgICBtZXNzYWdlOiAnaW5wdXRUb29Mb25nJyxcclxuICAgICAgICBhcmdzOiB7XHJcbiAgICAgICAgICBtYXhpbXVtOiB0aGlzLm1heGltdW1JbnB1dExlbmd0aCxcclxuICAgICAgICAgIGlucHV0OiBwYXJhbXMudGVybSxcclxuICAgICAgICAgIHBhcmFtczogcGFyYW1zXHJcbiAgICAgICAgfVxyXG4gICAgICB9KTtcclxuXHJcbiAgICAgIHJldHVybjtcclxuICAgIH1cclxuXHJcbiAgICBkZWNvcmF0ZWQuY2FsbCh0aGlzLCBwYXJhbXMsIGNhbGxiYWNrKTtcclxuICB9O1xyXG5cclxuICByZXR1cm4gTWF4aW11bUlucHV0TGVuZ3RoO1xyXG59KTtcclxuXG5TMi5kZWZpbmUoJ3NlbGVjdDIvZGF0YS9tYXhpbXVtU2VsZWN0aW9uTGVuZ3RoJyxbXHJcblxyXG5dLCBmdW5jdGlvbiAoKXtcclxuICBmdW5jdGlvbiBNYXhpbXVtU2VsZWN0aW9uTGVuZ3RoIChkZWNvcmF0ZWQsICRlLCBvcHRpb25zKSB7XHJcbiAgICB0aGlzLm1heGltdW1TZWxlY3Rpb25MZW5ndGggPSBvcHRpb25zLmdldCgnbWF4aW11bVNlbGVjdGlvbkxlbmd0aCcpO1xyXG5cclxuICAgIGRlY29yYXRlZC5jYWxsKHRoaXMsICRlLCBvcHRpb25zKTtcclxuICB9XHJcblxyXG4gIE1heGltdW1TZWxlY3Rpb25MZW5ndGgucHJvdG90eXBlLnF1ZXJ5ID1cclxuICAgIGZ1bmN0aW9uIChkZWNvcmF0ZWQsIHBhcmFtcywgY2FsbGJhY2spIHtcclxuICAgICAgdmFyIHNlbGYgPSB0aGlzO1xyXG5cclxuICAgICAgdGhpcy5jdXJyZW50KGZ1bmN0aW9uIChjdXJyZW50RGF0YSkge1xyXG4gICAgICAgIHZhciBjb3VudCA9IGN1cnJlbnREYXRhICE9IG51bGwgPyBjdXJyZW50RGF0YS5sZW5ndGggOiAwO1xyXG4gICAgICAgIGlmIChzZWxmLm1heGltdW1TZWxlY3Rpb25MZW5ndGggPiAwICYmXHJcbiAgICAgICAgICBjb3VudCA+PSBzZWxmLm1heGltdW1TZWxlY3Rpb25MZW5ndGgpIHtcclxuICAgICAgICAgIHNlbGYudHJpZ2dlcigncmVzdWx0czptZXNzYWdlJywge1xyXG4gICAgICAgICAgICBtZXNzYWdlOiAnbWF4aW11bVNlbGVjdGVkJyxcclxuICAgICAgICAgICAgYXJnczoge1xyXG4gICAgICAgICAgICAgIG1heGltdW06IHNlbGYubWF4aW11bVNlbGVjdGlvbkxlbmd0aFxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICB9KTtcclxuICAgICAgICAgIHJldHVybjtcclxuICAgICAgICB9XHJcbiAgICAgICAgZGVjb3JhdGVkLmNhbGwoc2VsZiwgcGFyYW1zLCBjYWxsYmFjayk7XHJcbiAgICAgIH0pO1xyXG4gIH07XHJcblxyXG4gIHJldHVybiBNYXhpbXVtU2VsZWN0aW9uTGVuZ3RoO1xyXG59KTtcclxuXG5TMi5kZWZpbmUoJ3NlbGVjdDIvZHJvcGRvd24nLFtcclxuICAnanF1ZXJ5JyxcclxuICAnLi91dGlscydcclxuXSwgZnVuY3Rpb24gKCQsIFV0aWxzKSB7XHJcbiAgZnVuY3Rpb24gRHJvcGRvd24gKCRlbGVtZW50LCBvcHRpb25zKSB7XHJcbiAgICB0aGlzLiRlbGVtZW50ID0gJGVsZW1lbnQ7XHJcbiAgICB0aGlzLm9wdGlvbnMgPSBvcHRpb25zO1xyXG5cclxuICAgIERyb3Bkb3duLl9fc3VwZXJfXy5jb25zdHJ1Y3Rvci5jYWxsKHRoaXMpO1xyXG4gIH1cclxuXHJcbiAgVXRpbHMuRXh0ZW5kKERyb3Bkb3duLCBVdGlscy5PYnNlcnZhYmxlKTtcclxuXHJcbiAgRHJvcGRvd24ucHJvdG90eXBlLnJlbmRlciA9IGZ1bmN0aW9uICgpIHtcclxuICAgIHZhciAkZHJvcGRvd24gPSAkKFxyXG4gICAgICAnPHNwYW4gY2xhc3M9XCJzZWxlY3QyLWRyb3Bkb3duXCI+JyArXHJcbiAgICAgICAgJzxzcGFuIGNsYXNzPVwic2VsZWN0Mi1yZXN1bHRzXCI+PC9zcGFuPicgK1xyXG4gICAgICAnPC9zcGFuPidcclxuICAgICk7XHJcblxyXG4gICAgJGRyb3Bkb3duLmF0dHIoJ2RpcicsIHRoaXMub3B0aW9ucy5nZXQoJ2RpcicpKTtcclxuXHJcbiAgICB0aGlzLiRkcm9wZG93biA9ICRkcm9wZG93bjtcclxuXHJcbiAgICByZXR1cm4gJGRyb3Bkb3duO1xyXG4gIH07XHJcblxyXG4gIERyb3Bkb3duLnByb3RvdHlwZS5iaW5kID0gZnVuY3Rpb24gKCkge1xyXG4gICAgLy8gU2hvdWxkIGJlIGltcGxlbWVudGVkIGluIHN1YmNsYXNzZXNcclxuICB9O1xyXG5cclxuICBEcm9wZG93bi5wcm90b3R5cGUucG9zaXRpb24gPSBmdW5jdGlvbiAoJGRyb3Bkb3duLCAkY29udGFpbmVyKSB7XHJcbiAgICAvLyBTaG91bGQgYmUgaW1wbG1lbnRlZCBpbiBzdWJjbGFzc2VzXHJcbiAgfTtcclxuXHJcbiAgRHJvcGRvd24ucHJvdG90eXBlLmRlc3Ryb3kgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAvLyBSZW1vdmUgdGhlIGRyb3Bkb3duIGZyb20gdGhlIERPTVxyXG4gICAgdGhpcy4kZHJvcGRvd24ucmVtb3ZlKCk7XHJcbiAgfTtcclxuXHJcbiAgcmV0dXJuIERyb3Bkb3duO1xyXG59KTtcclxuXG5TMi5kZWZpbmUoJ3NlbGVjdDIvZHJvcGRvd24vc2VhcmNoJyxbXHJcbiAgJ2pxdWVyeScsXHJcbiAgJy4uL3V0aWxzJ1xyXG5dLCBmdW5jdGlvbiAoJCwgVXRpbHMpIHtcclxuICBmdW5jdGlvbiBTZWFyY2ggKCkgeyB9XHJcblxyXG4gIFNlYXJjaC5wcm90b3R5cGUucmVuZGVyID0gZnVuY3Rpb24gKGRlY29yYXRlZCkge1xyXG4gICAgdmFyICRyZW5kZXJlZCA9IGRlY29yYXRlZC5jYWxsKHRoaXMpO1xyXG5cclxuICAgIHZhciAkc2VhcmNoID0gJChcclxuICAgICAgJzxzcGFuIGNsYXNzPVwic2VsZWN0Mi1zZWFyY2ggc2VsZWN0Mi1zZWFyY2gtLWRyb3Bkb3duXCI+JyArXHJcbiAgICAgICAgJzxpbnB1dCBjbGFzcz1cInNlbGVjdDItc2VhcmNoX19maWVsZFwiIHR5cGU9XCJzZWFyY2hcIiB0YWJpbmRleD1cIi0xXCInICtcclxuICAgICAgICAnIGF1dG9jb21wbGV0ZT1cIm9mZlwiIGF1dG9jb3JyZWN0PVwib2ZmXCIgYXV0b2NhcGl0YWxpemU9XCJvZmZcIicgK1xyXG4gICAgICAgICcgc3BlbGxjaGVjaz1cImZhbHNlXCIgcm9sZT1cInRleHRib3hcIiAvPicgK1xyXG4gICAgICAnPC9zcGFuPidcclxuICAgICk7XHJcblxyXG4gICAgdGhpcy4kc2VhcmNoQ29udGFpbmVyID0gJHNlYXJjaDtcclxuICAgIHRoaXMuJHNlYXJjaCA9ICRzZWFyY2guZmluZCgnaW5wdXQnKTtcclxuXHJcbiAgICAkcmVuZGVyZWQucHJlcGVuZCgkc2VhcmNoKTtcclxuXHJcbiAgICByZXR1cm4gJHJlbmRlcmVkO1xyXG4gIH07XHJcblxyXG4gIFNlYXJjaC5wcm90b3R5cGUuYmluZCA9IGZ1bmN0aW9uIChkZWNvcmF0ZWQsIGNvbnRhaW5lciwgJGNvbnRhaW5lcikge1xyXG4gICAgdmFyIHNlbGYgPSB0aGlzO1xyXG5cclxuICAgIGRlY29yYXRlZC5jYWxsKHRoaXMsIGNvbnRhaW5lciwgJGNvbnRhaW5lcik7XHJcblxyXG4gICAgdGhpcy4kc2VhcmNoLm9uKCdrZXlkb3duJywgZnVuY3Rpb24gKGV2dCkge1xyXG4gICAgICBzZWxmLnRyaWdnZXIoJ2tleXByZXNzJywgZXZ0KTtcclxuXHJcbiAgICAgIHNlbGYuX2tleVVwUHJldmVudGVkID0gZXZ0LmlzRGVmYXVsdFByZXZlbnRlZCgpO1xyXG4gICAgfSk7XHJcblxyXG4gICAgLy8gV29ya2Fyb3VuZCBmb3IgYnJvd3NlcnMgd2hpY2ggZG8gbm90IHN1cHBvcnQgdGhlIGBpbnB1dGAgZXZlbnRcclxuICAgIC8vIFRoaXMgd2lsbCBwcmV2ZW50IGRvdWJsZS10cmlnZ2VyaW5nIG9mIGV2ZW50cyBmb3IgYnJvd3NlcnMgd2hpY2ggc3VwcG9ydFxyXG4gICAgLy8gYm90aCB0aGUgYGtleXVwYCBhbmQgYGlucHV0YCBldmVudHMuXHJcbiAgICB0aGlzLiRzZWFyY2gub24oJ2lucHV0JywgZnVuY3Rpb24gKGV2dCkge1xyXG4gICAgICAvLyBVbmJpbmQgdGhlIGR1cGxpY2F0ZWQgYGtleXVwYCBldmVudFxyXG4gICAgICAkKHRoaXMpLm9mZigna2V5dXAnKTtcclxuICAgIH0pO1xyXG5cclxuICAgIHRoaXMuJHNlYXJjaC5vbigna2V5dXAgaW5wdXQnLCBmdW5jdGlvbiAoZXZ0KSB7XHJcbiAgICAgIHNlbGYuaGFuZGxlU2VhcmNoKGV2dCk7XHJcbiAgICB9KTtcclxuXHJcbiAgICBjb250YWluZXIub24oJ29wZW4nLCBmdW5jdGlvbiAoKSB7XHJcbiAgICAgIHNlbGYuJHNlYXJjaC5hdHRyKCd0YWJpbmRleCcsIDApO1xyXG5cclxuICAgICAgc2VsZi4kc2VhcmNoLmZvY3VzKCk7XHJcblxyXG4gICAgICB3aW5kb3cuc2V0VGltZW91dChmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgc2VsZi4kc2VhcmNoLmZvY3VzKCk7XHJcbiAgICAgIH0sIDApO1xyXG4gICAgfSk7XHJcblxyXG4gICAgY29udGFpbmVyLm9uKCdjbG9zZScsIGZ1bmN0aW9uICgpIHtcclxuICAgICAgc2VsZi4kc2VhcmNoLmF0dHIoJ3RhYmluZGV4JywgLTEpO1xyXG5cclxuICAgICAgc2VsZi4kc2VhcmNoLnZhbCgnJyk7XHJcbiAgICB9KTtcclxuXHJcbiAgICBjb250YWluZXIub24oJ2ZvY3VzJywgZnVuY3Rpb24gKCkge1xyXG4gICAgICBpZiAoY29udGFpbmVyLmlzT3BlbigpKSB7XHJcbiAgICAgICAgc2VsZi4kc2VhcmNoLmZvY3VzKCk7XHJcbiAgICAgIH1cclxuICAgIH0pO1xyXG5cclxuICAgIGNvbnRhaW5lci5vbigncmVzdWx0czphbGwnLCBmdW5jdGlvbiAocGFyYW1zKSB7XHJcbiAgICAgIGlmIChwYXJhbXMucXVlcnkudGVybSA9PSBudWxsIHx8IHBhcmFtcy5xdWVyeS50ZXJtID09PSAnJykge1xyXG4gICAgICAgIHZhciBzaG93U2VhcmNoID0gc2VsZi5zaG93U2VhcmNoKHBhcmFtcyk7XHJcblxyXG4gICAgICAgIGlmIChzaG93U2VhcmNoKSB7XHJcbiAgICAgICAgICBzZWxmLiRzZWFyY2hDb250YWluZXIucmVtb3ZlQ2xhc3MoJ3NlbGVjdDItc2VhcmNoLS1oaWRlJyk7XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgIHNlbGYuJHNlYXJjaENvbnRhaW5lci5hZGRDbGFzcygnc2VsZWN0Mi1zZWFyY2gtLWhpZGUnKTtcclxuICAgICAgICB9XHJcbiAgICAgIH1cclxuICAgIH0pO1xyXG4gIH07XHJcblxyXG4gIFNlYXJjaC5wcm90b3R5cGUuaGFuZGxlU2VhcmNoID0gZnVuY3Rpb24gKGV2dCkge1xyXG4gICAgaWYgKCF0aGlzLl9rZXlVcFByZXZlbnRlZCkge1xyXG4gICAgICB2YXIgaW5wdXQgPSB0aGlzLiRzZWFyY2gudmFsKCk7XHJcblxyXG4gICAgICB0aGlzLnRyaWdnZXIoJ3F1ZXJ5Jywge1xyXG4gICAgICAgIHRlcm06IGlucHV0XHJcbiAgICAgIH0pO1xyXG4gICAgfVxyXG5cclxuICAgIHRoaXMuX2tleVVwUHJldmVudGVkID0gZmFsc2U7XHJcbiAgfTtcclxuXHJcbiAgU2VhcmNoLnByb3RvdHlwZS5zaG93U2VhcmNoID0gZnVuY3Rpb24gKF8sIHBhcmFtcykge1xyXG4gICAgcmV0dXJuIHRydWU7XHJcbiAgfTtcclxuXHJcbiAgcmV0dXJuIFNlYXJjaDtcclxufSk7XHJcblxuUzIuZGVmaW5lKCdzZWxlY3QyL2Ryb3Bkb3duL2hpZGVQbGFjZWhvbGRlcicsW1xyXG5cclxuXSwgZnVuY3Rpb24gKCkge1xyXG4gIGZ1bmN0aW9uIEhpZGVQbGFjZWhvbGRlciAoZGVjb3JhdGVkLCAkZWxlbWVudCwgb3B0aW9ucywgZGF0YUFkYXB0ZXIpIHtcclxuICAgIHRoaXMucGxhY2Vob2xkZXIgPSB0aGlzLm5vcm1hbGl6ZVBsYWNlaG9sZGVyKG9wdGlvbnMuZ2V0KCdwbGFjZWhvbGRlcicpKTtcclxuXHJcbiAgICBkZWNvcmF0ZWQuY2FsbCh0aGlzLCAkZWxlbWVudCwgb3B0aW9ucywgZGF0YUFkYXB0ZXIpO1xyXG4gIH1cclxuXHJcbiAgSGlkZVBsYWNlaG9sZGVyLnByb3RvdHlwZS5hcHBlbmQgPSBmdW5jdGlvbiAoZGVjb3JhdGVkLCBkYXRhKSB7XHJcbiAgICBkYXRhLnJlc3VsdHMgPSB0aGlzLnJlbW92ZVBsYWNlaG9sZGVyKGRhdGEucmVzdWx0cyk7XHJcblxyXG4gICAgZGVjb3JhdGVkLmNhbGwodGhpcywgZGF0YSk7XHJcbiAgfTtcclxuXHJcbiAgSGlkZVBsYWNlaG9sZGVyLnByb3RvdHlwZS5ub3JtYWxpemVQbGFjZWhvbGRlciA9IGZ1bmN0aW9uIChfLCBwbGFjZWhvbGRlcikge1xyXG4gICAgaWYgKHR5cGVvZiBwbGFjZWhvbGRlciA9PT0gJ3N0cmluZycpIHtcclxuICAgICAgcGxhY2Vob2xkZXIgPSB7XHJcbiAgICAgICAgaWQ6ICcnLFxyXG4gICAgICAgIHRleHQ6IHBsYWNlaG9sZGVyXHJcbiAgICAgIH07XHJcbiAgICB9XHJcblxyXG4gICAgcmV0dXJuIHBsYWNlaG9sZGVyO1xyXG4gIH07XHJcblxyXG4gIEhpZGVQbGFjZWhvbGRlci5wcm90b3R5cGUucmVtb3ZlUGxhY2Vob2xkZXIgPSBmdW5jdGlvbiAoXywgZGF0YSkge1xyXG4gICAgdmFyIG1vZGlmaWVkRGF0YSA9IGRhdGEuc2xpY2UoMCk7XHJcblxyXG4gICAgZm9yICh2YXIgZCA9IGRhdGEubGVuZ3RoIC0gMTsgZCA+PSAwOyBkLS0pIHtcclxuICAgICAgdmFyIGl0ZW0gPSBkYXRhW2RdO1xyXG5cclxuICAgICAgaWYgKHRoaXMucGxhY2Vob2xkZXIuaWQgPT09IGl0ZW0uaWQpIHtcclxuICAgICAgICBtb2RpZmllZERhdGEuc3BsaWNlKGQsIDEpO1xyXG4gICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgcmV0dXJuIG1vZGlmaWVkRGF0YTtcclxuICB9O1xyXG5cclxuICByZXR1cm4gSGlkZVBsYWNlaG9sZGVyO1xyXG59KTtcclxuXG5TMi5kZWZpbmUoJ3NlbGVjdDIvZHJvcGRvd24vaW5maW5pdGVTY3JvbGwnLFtcclxuICAnanF1ZXJ5J1xyXG5dLCBmdW5jdGlvbiAoJCkge1xyXG4gIGZ1bmN0aW9uIEluZmluaXRlU2Nyb2xsIChkZWNvcmF0ZWQsICRlbGVtZW50LCBvcHRpb25zLCBkYXRhQWRhcHRlcikge1xyXG4gICAgdGhpcy5sYXN0UGFyYW1zID0ge307XHJcblxyXG4gICAgZGVjb3JhdGVkLmNhbGwodGhpcywgJGVsZW1lbnQsIG9wdGlvbnMsIGRhdGFBZGFwdGVyKTtcclxuXHJcbiAgICB0aGlzLiRsb2FkaW5nTW9yZSA9IHRoaXMuY3JlYXRlTG9hZGluZ01vcmUoKTtcclxuICAgIHRoaXMubG9hZGluZyA9IGZhbHNlO1xyXG4gIH1cclxuXHJcbiAgSW5maW5pdGVTY3JvbGwucHJvdG90eXBlLmFwcGVuZCA9IGZ1bmN0aW9uIChkZWNvcmF0ZWQsIGRhdGEpIHtcclxuICAgIHRoaXMuJGxvYWRpbmdNb3JlLnJlbW92ZSgpO1xyXG4gICAgdGhpcy5sb2FkaW5nID0gZmFsc2U7XHJcblxyXG4gICAgZGVjb3JhdGVkLmNhbGwodGhpcywgZGF0YSk7XHJcblxyXG4gICAgaWYgKHRoaXMuc2hvd0xvYWRpbmdNb3JlKGRhdGEpKSB7XHJcbiAgICAgIHRoaXMuJHJlc3VsdHMuYXBwZW5kKHRoaXMuJGxvYWRpbmdNb3JlKTtcclxuICAgIH1cclxuICB9O1xyXG5cclxuICBJbmZpbml0ZVNjcm9sbC5wcm90b3R5cGUuYmluZCA9IGZ1bmN0aW9uIChkZWNvcmF0ZWQsIGNvbnRhaW5lciwgJGNvbnRhaW5lcikge1xyXG4gICAgdmFyIHNlbGYgPSB0aGlzO1xyXG5cclxuICAgIGRlY29yYXRlZC5jYWxsKHRoaXMsIGNvbnRhaW5lciwgJGNvbnRhaW5lcik7XHJcblxyXG4gICAgY29udGFpbmVyLm9uKCdxdWVyeScsIGZ1bmN0aW9uIChwYXJhbXMpIHtcclxuICAgICAgc2VsZi5sYXN0UGFyYW1zID0gcGFyYW1zO1xyXG4gICAgICBzZWxmLmxvYWRpbmcgPSB0cnVlO1xyXG4gICAgfSk7XHJcblxyXG4gICAgY29udGFpbmVyLm9uKCdxdWVyeTphcHBlbmQnLCBmdW5jdGlvbiAocGFyYW1zKSB7XHJcbiAgICAgIHNlbGYubGFzdFBhcmFtcyA9IHBhcmFtcztcclxuICAgICAgc2VsZi5sb2FkaW5nID0gdHJ1ZTtcclxuICAgIH0pO1xyXG5cclxuICAgIHRoaXMuJHJlc3VsdHMub24oJ3Njcm9sbCcsIGZ1bmN0aW9uICgpIHtcclxuICAgICAgdmFyIGlzTG9hZE1vcmVWaXNpYmxlID0gJC5jb250YWlucyhcclxuICAgICAgICBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQsXHJcbiAgICAgICAgc2VsZi4kbG9hZGluZ01vcmVbMF1cclxuICAgICAgKTtcclxuXHJcbiAgICAgIGlmIChzZWxmLmxvYWRpbmcgfHwgIWlzTG9hZE1vcmVWaXNpYmxlKSB7XHJcbiAgICAgICAgcmV0dXJuO1xyXG4gICAgICB9XHJcblxyXG4gICAgICB2YXIgY3VycmVudE9mZnNldCA9IHNlbGYuJHJlc3VsdHMub2Zmc2V0KCkudG9wICtcclxuICAgICAgICBzZWxmLiRyZXN1bHRzLm91dGVySGVpZ2h0KGZhbHNlKTtcclxuICAgICAgdmFyIGxvYWRpbmdNb3JlT2Zmc2V0ID0gc2VsZi4kbG9hZGluZ01vcmUub2Zmc2V0KCkudG9wICtcclxuICAgICAgICBzZWxmLiRsb2FkaW5nTW9yZS5vdXRlckhlaWdodChmYWxzZSk7XHJcblxyXG4gICAgICBpZiAoY3VycmVudE9mZnNldCArIDUwID49IGxvYWRpbmdNb3JlT2Zmc2V0KSB7XHJcbiAgICAgICAgc2VsZi5sb2FkTW9yZSgpO1xyXG4gICAgICB9XHJcbiAgICB9KTtcclxuICB9O1xyXG5cclxuICBJbmZpbml0ZVNjcm9sbC5wcm90b3R5cGUubG9hZE1vcmUgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICB0aGlzLmxvYWRpbmcgPSB0cnVlO1xyXG5cclxuICAgIHZhciBwYXJhbXMgPSAkLmV4dGVuZCh7fSwge3BhZ2U6IDF9LCB0aGlzLmxhc3RQYXJhbXMpO1xyXG5cclxuICAgIHBhcmFtcy5wYWdlKys7XHJcblxyXG4gICAgdGhpcy50cmlnZ2VyKCdxdWVyeTphcHBlbmQnLCBwYXJhbXMpO1xyXG4gIH07XHJcblxyXG4gIEluZmluaXRlU2Nyb2xsLnByb3RvdHlwZS5zaG93TG9hZGluZ01vcmUgPSBmdW5jdGlvbiAoXywgZGF0YSkge1xyXG4gICAgcmV0dXJuIGRhdGEucGFnaW5hdGlvbiAmJiBkYXRhLnBhZ2luYXRpb24ubW9yZTtcclxuICB9O1xyXG5cclxuICBJbmZpbml0ZVNjcm9sbC5wcm90b3R5cGUuY3JlYXRlTG9hZGluZ01vcmUgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICB2YXIgJG9wdGlvbiA9ICQoXHJcbiAgICAgICc8bGkgJyArXHJcbiAgICAgICdjbGFzcz1cInNlbGVjdDItcmVzdWx0c19fb3B0aW9uIHNlbGVjdDItcmVzdWx0c19fb3B0aW9uLS1sb2FkLW1vcmVcIicgK1xyXG4gICAgICAncm9sZT1cInRyZWVpdGVtXCIgYXJpYS1kaXNhYmxlZD1cInRydWVcIj48L2xpPidcclxuICAgICk7XHJcblxyXG4gICAgdmFyIG1lc3NhZ2UgPSB0aGlzLm9wdGlvbnMuZ2V0KCd0cmFuc2xhdGlvbnMnKS5nZXQoJ2xvYWRpbmdNb3JlJyk7XHJcblxyXG4gICAgJG9wdGlvbi5odG1sKG1lc3NhZ2UodGhpcy5sYXN0UGFyYW1zKSk7XHJcblxyXG4gICAgcmV0dXJuICRvcHRpb247XHJcbiAgfTtcclxuXHJcbiAgcmV0dXJuIEluZmluaXRlU2Nyb2xsO1xyXG59KTtcclxuXG5TMi5kZWZpbmUoJ3NlbGVjdDIvZHJvcGRvd24vYXR0YWNoQm9keScsW1xyXG4gICdqcXVlcnknLFxyXG4gICcuLi91dGlscydcclxuXSwgZnVuY3Rpb24gKCQsIFV0aWxzKSB7XHJcbiAgZnVuY3Rpb24gQXR0YWNoQm9keSAoZGVjb3JhdGVkLCAkZWxlbWVudCwgb3B0aW9ucykge1xyXG4gICAgdGhpcy4kZHJvcGRvd25QYXJlbnQgPSBvcHRpb25zLmdldCgnZHJvcGRvd25QYXJlbnQnKSB8fCAkKGRvY3VtZW50LmJvZHkpO1xyXG5cclxuICAgIGRlY29yYXRlZC5jYWxsKHRoaXMsICRlbGVtZW50LCBvcHRpb25zKTtcclxuICB9XHJcblxyXG4gIEF0dGFjaEJvZHkucHJvdG90eXBlLmJpbmQgPSBmdW5jdGlvbiAoZGVjb3JhdGVkLCBjb250YWluZXIsICRjb250YWluZXIpIHtcclxuICAgIHZhciBzZWxmID0gdGhpcztcclxuXHJcbiAgICB2YXIgc2V0dXBSZXN1bHRzRXZlbnRzID0gZmFsc2U7XHJcblxyXG4gICAgZGVjb3JhdGVkLmNhbGwodGhpcywgY29udGFpbmVyLCAkY29udGFpbmVyKTtcclxuXHJcbiAgICBjb250YWluZXIub24oJ29wZW4nLCBmdW5jdGlvbiAoKSB7XHJcbiAgICAgIHNlbGYuX3Nob3dEcm9wZG93bigpO1xyXG4gICAgICBzZWxmLl9hdHRhY2hQb3NpdGlvbmluZ0hhbmRsZXIoY29udGFpbmVyKTtcclxuXHJcbiAgICAgIGlmICghc2V0dXBSZXN1bHRzRXZlbnRzKSB7XHJcbiAgICAgICAgc2V0dXBSZXN1bHRzRXZlbnRzID0gdHJ1ZTtcclxuXHJcbiAgICAgICAgY29udGFpbmVyLm9uKCdyZXN1bHRzOmFsbCcsIGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgIHNlbGYuX3Bvc2l0aW9uRHJvcGRvd24oKTtcclxuICAgICAgICAgIHNlbGYuX3Jlc2l6ZURyb3Bkb3duKCk7XHJcbiAgICAgICAgfSk7XHJcblxyXG4gICAgICAgIGNvbnRhaW5lci5vbigncmVzdWx0czphcHBlbmQnLCBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICBzZWxmLl9wb3NpdGlvbkRyb3Bkb3duKCk7XHJcbiAgICAgICAgICBzZWxmLl9yZXNpemVEcm9wZG93bigpO1xyXG4gICAgICAgIH0pO1xyXG4gICAgICB9XHJcbiAgICB9KTtcclxuXHJcbiAgICBjb250YWluZXIub24oJ2Nsb3NlJywgZnVuY3Rpb24gKCkge1xyXG4gICAgICBzZWxmLl9oaWRlRHJvcGRvd24oKTtcclxuICAgICAgc2VsZi5fZGV0YWNoUG9zaXRpb25pbmdIYW5kbGVyKGNvbnRhaW5lcik7XHJcbiAgICB9KTtcclxuXHJcbiAgICB0aGlzLiRkcm9wZG93bkNvbnRhaW5lci5vbignbW91c2Vkb3duJywgZnVuY3Rpb24gKGV2dCkge1xyXG4gICAgICBldnQuc3RvcFByb3BhZ2F0aW9uKCk7XHJcbiAgICB9KTtcclxuICB9O1xyXG5cclxuICBBdHRhY2hCb2R5LnByb3RvdHlwZS5kZXN0cm95ID0gZnVuY3Rpb24gKGRlY29yYXRlZCkge1xyXG4gICAgZGVjb3JhdGVkLmNhbGwodGhpcyk7XHJcblxyXG4gICAgdGhpcy4kZHJvcGRvd25Db250YWluZXIucmVtb3ZlKCk7XHJcbiAgfTtcclxuXHJcbiAgQXR0YWNoQm9keS5wcm90b3R5cGUucG9zaXRpb24gPSBmdW5jdGlvbiAoZGVjb3JhdGVkLCAkZHJvcGRvd24sICRjb250YWluZXIpIHtcclxuICAgIC8vIENsb25lIGFsbCBvZiB0aGUgY29udGFpbmVyIGNsYXNzZXNcclxuICAgICRkcm9wZG93bi5hdHRyKCdjbGFzcycsICRjb250YWluZXIuYXR0cignY2xhc3MnKSk7XHJcblxyXG4gICAgJGRyb3Bkb3duLnJlbW92ZUNsYXNzKCdzZWxlY3QyJyk7XHJcbiAgICAkZHJvcGRvd24uYWRkQ2xhc3MoJ3NlbGVjdDItY29udGFpbmVyLS1vcGVuJyk7XHJcblxyXG4gICAgJGRyb3Bkb3duLmNzcyh7XHJcbiAgICAgIHBvc2l0aW9uOiAnYWJzb2x1dGUnLFxyXG4gICAgICB0b3A6IC05OTk5OTlcclxuICAgIH0pO1xyXG5cclxuICAgIHRoaXMuJGNvbnRhaW5lciA9ICRjb250YWluZXI7XHJcbiAgfTtcclxuXHJcbiAgQXR0YWNoQm9keS5wcm90b3R5cGUucmVuZGVyID0gZnVuY3Rpb24gKGRlY29yYXRlZCkge1xyXG4gICAgdmFyICRjb250YWluZXIgPSAkKCc8c3Bhbj48L3NwYW4+Jyk7XHJcblxyXG4gICAgdmFyICRkcm9wZG93biA9IGRlY29yYXRlZC5jYWxsKHRoaXMpO1xyXG4gICAgJGNvbnRhaW5lci5hcHBlbmQoJGRyb3Bkb3duKTtcclxuXHJcbiAgICB0aGlzLiRkcm9wZG93bkNvbnRhaW5lciA9ICRjb250YWluZXI7XHJcblxyXG4gICAgcmV0dXJuICRjb250YWluZXI7XHJcbiAgfTtcclxuXHJcbiAgQXR0YWNoQm9keS5wcm90b3R5cGUuX2hpZGVEcm9wZG93biA9IGZ1bmN0aW9uIChkZWNvcmF0ZWQpIHtcclxuICAgIHRoaXMuJGRyb3Bkb3duQ29udGFpbmVyLmRldGFjaCgpO1xyXG4gIH07XHJcblxyXG4gIEF0dGFjaEJvZHkucHJvdG90eXBlLl9hdHRhY2hQb3NpdGlvbmluZ0hhbmRsZXIgPVxyXG4gICAgICBmdW5jdGlvbiAoZGVjb3JhdGVkLCBjb250YWluZXIpIHtcclxuICAgIHZhciBzZWxmID0gdGhpcztcclxuXHJcbiAgICB2YXIgc2Nyb2xsRXZlbnQgPSAnc2Nyb2xsLnNlbGVjdDIuJyArIGNvbnRhaW5lci5pZDtcclxuICAgIHZhciByZXNpemVFdmVudCA9ICdyZXNpemUuc2VsZWN0Mi4nICsgY29udGFpbmVyLmlkO1xyXG4gICAgdmFyIG9yaWVudGF0aW9uRXZlbnQgPSAnb3JpZW50YXRpb25jaGFuZ2Uuc2VsZWN0Mi4nICsgY29udGFpbmVyLmlkO1xyXG5cclxuICAgIHZhciAkd2F0Y2hlcnMgPSB0aGlzLiRjb250YWluZXIucGFyZW50cygpLmZpbHRlcihVdGlscy5oYXNTY3JvbGwpO1xyXG4gICAgJHdhdGNoZXJzLmVhY2goZnVuY3Rpb24gKCkge1xyXG4gICAgICAkKHRoaXMpLmRhdGEoJ3NlbGVjdDItc2Nyb2xsLXBvc2l0aW9uJywge1xyXG4gICAgICAgIHg6ICQodGhpcykuc2Nyb2xsTGVmdCgpLFxyXG4gICAgICAgIHk6ICQodGhpcykuc2Nyb2xsVG9wKClcclxuICAgICAgfSk7XHJcbiAgICB9KTtcclxuXHJcbiAgICAkd2F0Y2hlcnMub24oc2Nyb2xsRXZlbnQsIGZ1bmN0aW9uIChldikge1xyXG4gICAgICB2YXIgcG9zaXRpb24gPSAkKHRoaXMpLmRhdGEoJ3NlbGVjdDItc2Nyb2xsLXBvc2l0aW9uJyk7XHJcbiAgICAgICQodGhpcykuc2Nyb2xsVG9wKHBvc2l0aW9uLnkpO1xyXG4gICAgfSk7XHJcblxyXG4gICAgJCh3aW5kb3cpLm9uKHNjcm9sbEV2ZW50ICsgJyAnICsgcmVzaXplRXZlbnQgKyAnICcgKyBvcmllbnRhdGlvbkV2ZW50LFxyXG4gICAgICBmdW5jdGlvbiAoZSkge1xyXG4gICAgICBzZWxmLl9wb3NpdGlvbkRyb3Bkb3duKCk7XHJcbiAgICAgIHNlbGYuX3Jlc2l6ZURyb3Bkb3duKCk7XHJcbiAgICB9KTtcclxuICB9O1xyXG5cclxuICBBdHRhY2hCb2R5LnByb3RvdHlwZS5fZGV0YWNoUG9zaXRpb25pbmdIYW5kbGVyID1cclxuICAgICAgZnVuY3Rpb24gKGRlY29yYXRlZCwgY29udGFpbmVyKSB7XHJcbiAgICB2YXIgc2Nyb2xsRXZlbnQgPSAnc2Nyb2xsLnNlbGVjdDIuJyArIGNvbnRhaW5lci5pZDtcclxuICAgIHZhciByZXNpemVFdmVudCA9ICdyZXNpemUuc2VsZWN0Mi4nICsgY29udGFpbmVyLmlkO1xyXG4gICAgdmFyIG9yaWVudGF0aW9uRXZlbnQgPSAnb3JpZW50YXRpb25jaGFuZ2Uuc2VsZWN0Mi4nICsgY29udGFpbmVyLmlkO1xyXG5cclxuICAgIHZhciAkd2F0Y2hlcnMgPSB0aGlzLiRjb250YWluZXIucGFyZW50cygpLmZpbHRlcihVdGlscy5oYXNTY3JvbGwpO1xyXG4gICAgJHdhdGNoZXJzLm9mZihzY3JvbGxFdmVudCk7XHJcblxyXG4gICAgJCh3aW5kb3cpLm9mZihzY3JvbGxFdmVudCArICcgJyArIHJlc2l6ZUV2ZW50ICsgJyAnICsgb3JpZW50YXRpb25FdmVudCk7XHJcbiAgfTtcclxuXHJcbiAgQXR0YWNoQm9keS5wcm90b3R5cGUuX3Bvc2l0aW9uRHJvcGRvd24gPSBmdW5jdGlvbiAoKSB7XHJcbiAgICB2YXIgJHdpbmRvdyA9ICQod2luZG93KTtcclxuXHJcbiAgICB2YXIgaXNDdXJyZW50bHlBYm92ZSA9IHRoaXMuJGRyb3Bkb3duLmhhc0NsYXNzKCdzZWxlY3QyLWRyb3Bkb3duLS1hYm92ZScpO1xyXG4gICAgdmFyIGlzQ3VycmVudGx5QmVsb3cgPSB0aGlzLiRkcm9wZG93bi5oYXNDbGFzcygnc2VsZWN0Mi1kcm9wZG93bi0tYmVsb3cnKTtcclxuXHJcbiAgICB2YXIgbmV3RGlyZWN0aW9uID0gbnVsbDtcclxuXHJcbiAgICB2YXIgb2Zmc2V0ID0gdGhpcy4kY29udGFpbmVyLm9mZnNldCgpO1xyXG5cclxuICAgIG9mZnNldC5ib3R0b20gPSBvZmZzZXQudG9wICsgdGhpcy4kY29udGFpbmVyLm91dGVySGVpZ2h0KGZhbHNlKTtcclxuXHJcbiAgICB2YXIgY29udGFpbmVyID0ge1xyXG4gICAgICBoZWlnaHQ6IHRoaXMuJGNvbnRhaW5lci5vdXRlckhlaWdodChmYWxzZSlcclxuICAgIH07XHJcblxyXG4gICAgY29udGFpbmVyLnRvcCA9IG9mZnNldC50b3A7XHJcbiAgICBjb250YWluZXIuYm90dG9tID0gb2Zmc2V0LnRvcCArIGNvbnRhaW5lci5oZWlnaHQ7XHJcblxyXG4gICAgdmFyIGRyb3Bkb3duID0ge1xyXG4gICAgICBoZWlnaHQ6IHRoaXMuJGRyb3Bkb3duLm91dGVySGVpZ2h0KGZhbHNlKVxyXG4gICAgfTtcclxuXHJcbiAgICB2YXIgdmlld3BvcnQgPSB7XHJcbiAgICAgIHRvcDogJHdpbmRvdy5zY3JvbGxUb3AoKSxcclxuICAgICAgYm90dG9tOiAkd2luZG93LnNjcm9sbFRvcCgpICsgJHdpbmRvdy5oZWlnaHQoKVxyXG4gICAgfTtcclxuXHJcbiAgICB2YXIgZW5vdWdoUm9vbUFib3ZlID0gdmlld3BvcnQudG9wIDwgKG9mZnNldC50b3AgLSBkcm9wZG93bi5oZWlnaHQpO1xyXG4gICAgdmFyIGVub3VnaFJvb21CZWxvdyA9IHZpZXdwb3J0LmJvdHRvbSA+IChvZmZzZXQuYm90dG9tICsgZHJvcGRvd24uaGVpZ2h0KTtcclxuXHJcbiAgICB2YXIgY3NzID0ge1xyXG4gICAgICBsZWZ0OiBvZmZzZXQubGVmdCxcclxuICAgICAgdG9wOiBjb250YWluZXIuYm90dG9tXHJcbiAgICB9O1xyXG5cclxuICAgIC8vIERldGVybWluZSB3aGF0IHRoZSBwYXJlbnQgZWxlbWVudCBpcyB0byB1c2UgZm9yIGNhbGNpdWxhdGluZyB0aGUgb2Zmc2V0XHJcbiAgICB2YXIgJG9mZnNldFBhcmVudCA9IHRoaXMuJGRyb3Bkb3duUGFyZW50O1xyXG5cclxuICAgIC8vIEZvciBzdGF0aWNhbGx5IHBvc2l0b25lZCBlbGVtZW50cywgd2UgbmVlZCB0byBnZXQgdGhlIGVsZW1lbnRcclxuICAgIC8vIHRoYXQgaXMgZGV0ZXJtaW5pbmcgdGhlIG9mZnNldFxyXG4gICAgaWYgKCRvZmZzZXRQYXJlbnQuY3NzKCdwb3NpdGlvbicpID09PSAnc3RhdGljJykge1xyXG4gICAgICAkb2Zmc2V0UGFyZW50ID0gJG9mZnNldFBhcmVudC5vZmZzZXRQYXJlbnQoKTtcclxuICAgIH1cclxuXHJcbiAgICB2YXIgcGFyZW50T2Zmc2V0ID0gJG9mZnNldFBhcmVudC5vZmZzZXQoKTtcclxuXHJcbiAgICBjc3MudG9wIC09IHBhcmVudE9mZnNldC50b3A7XHJcbiAgICBjc3MubGVmdCAtPSBwYXJlbnRPZmZzZXQubGVmdDtcclxuXHJcbiAgICBpZiAoIWlzQ3VycmVudGx5QWJvdmUgJiYgIWlzQ3VycmVudGx5QmVsb3cpIHtcclxuICAgICAgbmV3RGlyZWN0aW9uID0gJ2JlbG93JztcclxuICAgIH1cclxuXHJcbiAgICBpZiAoIWVub3VnaFJvb21CZWxvdyAmJiBlbm91Z2hSb29tQWJvdmUgJiYgIWlzQ3VycmVudGx5QWJvdmUpIHtcclxuICAgICAgbmV3RGlyZWN0aW9uID0gJ2Fib3ZlJztcclxuICAgIH0gZWxzZSBpZiAoIWVub3VnaFJvb21BYm92ZSAmJiBlbm91Z2hSb29tQmVsb3cgJiYgaXNDdXJyZW50bHlBYm92ZSkge1xyXG4gICAgICBuZXdEaXJlY3Rpb24gPSAnYmVsb3cnO1xyXG4gICAgfVxyXG5cclxuICAgIGlmIChuZXdEaXJlY3Rpb24gPT0gJ2Fib3ZlJyB8fFxyXG4gICAgICAoaXNDdXJyZW50bHlBYm92ZSAmJiBuZXdEaXJlY3Rpb24gIT09ICdiZWxvdycpKSB7XHJcbiAgICAgIGNzcy50b3AgPSBjb250YWluZXIudG9wIC0gcGFyZW50T2Zmc2V0LnRvcCAtIGRyb3Bkb3duLmhlaWdodDtcclxuICAgIH1cclxuXHJcbiAgICBpZiAobmV3RGlyZWN0aW9uICE9IG51bGwpIHtcclxuICAgICAgdGhpcy4kZHJvcGRvd25cclxuICAgICAgICAucmVtb3ZlQ2xhc3MoJ3NlbGVjdDItZHJvcGRvd24tLWJlbG93IHNlbGVjdDItZHJvcGRvd24tLWFib3ZlJylcclxuICAgICAgICAuYWRkQ2xhc3MoJ3NlbGVjdDItZHJvcGRvd24tLScgKyBuZXdEaXJlY3Rpb24pO1xyXG4gICAgICB0aGlzLiRjb250YWluZXJcclxuICAgICAgICAucmVtb3ZlQ2xhc3MoJ3NlbGVjdDItY29udGFpbmVyLS1iZWxvdyBzZWxlY3QyLWNvbnRhaW5lci0tYWJvdmUnKVxyXG4gICAgICAgIC5hZGRDbGFzcygnc2VsZWN0Mi1jb250YWluZXItLScgKyBuZXdEaXJlY3Rpb24pO1xyXG4gICAgfVxyXG5cclxuICAgIHRoaXMuJGRyb3Bkb3duQ29udGFpbmVyLmNzcyhjc3MpO1xyXG4gIH07XHJcblxyXG4gIEF0dGFjaEJvZHkucHJvdG90eXBlLl9yZXNpemVEcm9wZG93biA9IGZ1bmN0aW9uICgpIHtcclxuICAgIHZhciBjc3MgPSB7XHJcbiAgICAgIHdpZHRoOiB0aGlzLiRjb250YWluZXIub3V0ZXJXaWR0aChmYWxzZSkgKyAncHgnXHJcbiAgICB9O1xyXG5cclxuICAgIGlmICh0aGlzLm9wdGlvbnMuZ2V0KCdkcm9wZG93bkF1dG9XaWR0aCcpKSB7XHJcbiAgICAgIGNzcy5taW5XaWR0aCA9IGNzcy53aWR0aDtcclxuICAgICAgY3NzLnBvc2l0aW9uID0gJ3JlbGF0aXZlJztcclxuICAgICAgY3NzLndpZHRoID0gJ2F1dG8nO1xyXG4gICAgfVxyXG5cclxuICAgIHRoaXMuJGRyb3Bkb3duLmNzcyhjc3MpO1xyXG4gIH07XHJcblxyXG4gIEF0dGFjaEJvZHkucHJvdG90eXBlLl9zaG93RHJvcGRvd24gPSBmdW5jdGlvbiAoZGVjb3JhdGVkKSB7XHJcbiAgICB0aGlzLiRkcm9wZG93bkNvbnRhaW5lci5hcHBlbmRUbyh0aGlzLiRkcm9wZG93blBhcmVudCk7XHJcblxyXG4gICAgdGhpcy5fcG9zaXRpb25Ecm9wZG93bigpO1xyXG4gICAgdGhpcy5fcmVzaXplRHJvcGRvd24oKTtcclxuICB9O1xyXG5cclxuICByZXR1cm4gQXR0YWNoQm9keTtcclxufSk7XHJcblxuUzIuZGVmaW5lKCdzZWxlY3QyL2Ryb3Bkb3duL21pbmltdW1SZXN1bHRzRm9yU2VhcmNoJyxbXHJcblxyXG5dLCBmdW5jdGlvbiAoKSB7XHJcbiAgZnVuY3Rpb24gY291bnRSZXN1bHRzIChkYXRhKSB7XHJcbiAgICB2YXIgY291bnQgPSAwO1xyXG5cclxuICAgIGZvciAodmFyIGQgPSAwOyBkIDwgZGF0YS5sZW5ndGg7IGQrKykge1xyXG4gICAgICB2YXIgaXRlbSA9IGRhdGFbZF07XHJcblxyXG4gICAgICBpZiAoaXRlbS5jaGlsZHJlbikge1xyXG4gICAgICAgIGNvdW50ICs9IGNvdW50UmVzdWx0cyhpdGVtLmNoaWxkcmVuKTtcclxuICAgICAgfSBlbHNlIHtcclxuICAgICAgICBjb3VudCsrO1xyXG4gICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgcmV0dXJuIGNvdW50O1xyXG4gIH1cclxuXHJcbiAgZnVuY3Rpb24gTWluaW11bVJlc3VsdHNGb3JTZWFyY2ggKGRlY29yYXRlZCwgJGVsZW1lbnQsIG9wdGlvbnMsIGRhdGFBZGFwdGVyKSB7XHJcbiAgICB0aGlzLm1pbmltdW1SZXN1bHRzRm9yU2VhcmNoID0gb3B0aW9ucy5nZXQoJ21pbmltdW1SZXN1bHRzRm9yU2VhcmNoJyk7XHJcblxyXG4gICAgaWYgKHRoaXMubWluaW11bVJlc3VsdHNGb3JTZWFyY2ggPCAwKSB7XHJcbiAgICAgIHRoaXMubWluaW11bVJlc3VsdHNGb3JTZWFyY2ggPSBJbmZpbml0eTtcclxuICAgIH1cclxuXHJcbiAgICBkZWNvcmF0ZWQuY2FsbCh0aGlzLCAkZWxlbWVudCwgb3B0aW9ucywgZGF0YUFkYXB0ZXIpO1xyXG4gIH1cclxuXHJcbiAgTWluaW11bVJlc3VsdHNGb3JTZWFyY2gucHJvdG90eXBlLnNob3dTZWFyY2ggPSBmdW5jdGlvbiAoZGVjb3JhdGVkLCBwYXJhbXMpIHtcclxuICAgIGlmIChjb3VudFJlc3VsdHMocGFyYW1zLmRhdGEucmVzdWx0cykgPCB0aGlzLm1pbmltdW1SZXN1bHRzRm9yU2VhcmNoKSB7XHJcbiAgICAgIHJldHVybiBmYWxzZTtcclxuICAgIH1cclxuXHJcbiAgICByZXR1cm4gZGVjb3JhdGVkLmNhbGwodGhpcywgcGFyYW1zKTtcclxuICB9O1xyXG5cclxuICByZXR1cm4gTWluaW11bVJlc3VsdHNGb3JTZWFyY2g7XHJcbn0pO1xyXG5cblMyLmRlZmluZSgnc2VsZWN0Mi9kcm9wZG93bi9zZWxlY3RPbkNsb3NlJyxbXHJcblxyXG5dLCBmdW5jdGlvbiAoKSB7XHJcbiAgZnVuY3Rpb24gU2VsZWN0T25DbG9zZSAoKSB7IH1cclxuXHJcbiAgU2VsZWN0T25DbG9zZS5wcm90b3R5cGUuYmluZCA9IGZ1bmN0aW9uIChkZWNvcmF0ZWQsIGNvbnRhaW5lciwgJGNvbnRhaW5lcikge1xyXG4gICAgdmFyIHNlbGYgPSB0aGlzO1xyXG5cclxuICAgIGRlY29yYXRlZC5jYWxsKHRoaXMsIGNvbnRhaW5lciwgJGNvbnRhaW5lcik7XHJcblxyXG4gICAgY29udGFpbmVyLm9uKCdjbG9zZScsIGZ1bmN0aW9uIChwYXJhbXMpIHtcclxuICAgICAgc2VsZi5faGFuZGxlU2VsZWN0T25DbG9zZShwYXJhbXMpO1xyXG4gICAgfSk7XHJcbiAgfTtcclxuXHJcbiAgU2VsZWN0T25DbG9zZS5wcm90b3R5cGUuX2hhbmRsZVNlbGVjdE9uQ2xvc2UgPSBmdW5jdGlvbiAoXywgcGFyYW1zKSB7XHJcbiAgICBpZiAocGFyYW1zICYmIHBhcmFtcy5vcmlnaW5hbFNlbGVjdDJFdmVudCAhPSBudWxsKSB7XHJcbiAgICAgIHZhciBldmVudCA9IHBhcmFtcy5vcmlnaW5hbFNlbGVjdDJFdmVudDtcclxuXHJcbiAgICAgIC8vIERvbid0IHNlbGVjdCBhbiBpdGVtIGlmIHRoZSBjbG9zZSBldmVudCB3YXMgdHJpZ2dlcmVkIGZyb20gYSBzZWxlY3Qgb3JcclxuICAgICAgLy8gdW5zZWxlY3QgZXZlbnRcclxuICAgICAgaWYgKGV2ZW50Ll90eXBlID09PSAnc2VsZWN0JyB8fCBldmVudC5fdHlwZSA9PT0gJ3Vuc2VsZWN0Jykge1xyXG4gICAgICAgIHJldHVybjtcclxuICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIHZhciAkaGlnaGxpZ2h0ZWRSZXN1bHRzID0gdGhpcy5nZXRIaWdobGlnaHRlZFJlc3VsdHMoKTtcclxuXHJcbiAgICAvLyBPbmx5IHNlbGVjdCBoaWdobGlnaHRlZCByZXN1bHRzXHJcbiAgICBpZiAoJGhpZ2hsaWdodGVkUmVzdWx0cy5sZW5ndGggPCAxKSB7XHJcbiAgICAgIHJldHVybjtcclxuICAgIH1cclxuXHJcbiAgICB2YXIgZGF0YSA9ICRoaWdobGlnaHRlZFJlc3VsdHMuZGF0YSgnZGF0YScpO1xyXG5cclxuICAgIC8vIERvbid0IHJlLXNlbGVjdCBhbHJlYWR5IHNlbGVjdGVkIHJlc3VsdGVcclxuICAgIGlmIChcclxuICAgICAgKGRhdGEuZWxlbWVudCAhPSBudWxsICYmIGRhdGEuZWxlbWVudC5zZWxlY3RlZCkgfHxcclxuICAgICAgKGRhdGEuZWxlbWVudCA9PSBudWxsICYmIGRhdGEuc2VsZWN0ZWQpXHJcbiAgICApIHtcclxuICAgICAgcmV0dXJuO1xyXG4gICAgfVxyXG5cclxuICAgIHRoaXMudHJpZ2dlcignc2VsZWN0Jywge1xyXG4gICAgICAgIGRhdGE6IGRhdGFcclxuICAgIH0pO1xyXG4gIH07XHJcblxyXG4gIHJldHVybiBTZWxlY3RPbkNsb3NlO1xyXG59KTtcclxuXG5TMi5kZWZpbmUoJ3NlbGVjdDIvZHJvcGRvd24vY2xvc2VPblNlbGVjdCcsW1xyXG5cclxuXSwgZnVuY3Rpb24gKCkge1xyXG4gIGZ1bmN0aW9uIENsb3NlT25TZWxlY3QgKCkgeyB9XHJcblxyXG4gIENsb3NlT25TZWxlY3QucHJvdG90eXBlLmJpbmQgPSBmdW5jdGlvbiAoZGVjb3JhdGVkLCBjb250YWluZXIsICRjb250YWluZXIpIHtcclxuICAgIHZhciBzZWxmID0gdGhpcztcclxuXHJcbiAgICBkZWNvcmF0ZWQuY2FsbCh0aGlzLCBjb250YWluZXIsICRjb250YWluZXIpO1xyXG5cclxuICAgIGNvbnRhaW5lci5vbignc2VsZWN0JywgZnVuY3Rpb24gKGV2dCkge1xyXG4gICAgICBzZWxmLl9zZWxlY3RUcmlnZ2VyZWQoZXZ0KTtcclxuICAgIH0pO1xyXG5cclxuICAgIGNvbnRhaW5lci5vbigndW5zZWxlY3QnLCBmdW5jdGlvbiAoZXZ0KSB7XHJcbiAgICAgIHNlbGYuX3NlbGVjdFRyaWdnZXJlZChldnQpO1xyXG4gICAgfSk7XHJcbiAgfTtcclxuXHJcbiAgQ2xvc2VPblNlbGVjdC5wcm90b3R5cGUuX3NlbGVjdFRyaWdnZXJlZCA9IGZ1bmN0aW9uIChfLCBldnQpIHtcclxuICAgIHZhciBvcmlnaW5hbEV2ZW50ID0gZXZ0Lm9yaWdpbmFsRXZlbnQ7XHJcblxyXG4gICAgLy8gRG9uJ3QgY2xvc2UgaWYgdGhlIGNvbnRyb2wga2V5IGlzIGJlaW5nIGhlbGRcclxuICAgIGlmIChvcmlnaW5hbEV2ZW50ICYmIG9yaWdpbmFsRXZlbnQuY3RybEtleSkge1xyXG4gICAgICByZXR1cm47XHJcbiAgICB9XHJcblxyXG4gICAgdGhpcy50cmlnZ2VyKCdjbG9zZScsIHtcclxuICAgICAgb3JpZ2luYWxFdmVudDogb3JpZ2luYWxFdmVudCxcclxuICAgICAgb3JpZ2luYWxTZWxlY3QyRXZlbnQ6IGV2dFxyXG4gICAgfSk7XHJcbiAgfTtcclxuXHJcbiAgcmV0dXJuIENsb3NlT25TZWxlY3Q7XHJcbn0pO1xyXG5cblMyLmRlZmluZSgnc2VsZWN0Mi9pMThuL2VuJyxbXSxmdW5jdGlvbiAoKSB7XHJcbiAgLy8gRW5nbGlzaFxyXG4gIHJldHVybiB7XHJcbiAgICBlcnJvckxvYWRpbmc6IGZ1bmN0aW9uICgpIHtcclxuICAgICAgcmV0dXJuICdUaGUgcmVzdWx0cyBjb3VsZCBub3QgYmUgbG9hZGVkLic7XHJcbiAgICB9LFxyXG4gICAgaW5wdXRUb29Mb25nOiBmdW5jdGlvbiAoYXJncykge1xyXG4gICAgICB2YXIgb3ZlckNoYXJzID0gYXJncy5pbnB1dC5sZW5ndGggLSBhcmdzLm1heGltdW07XHJcblxyXG4gICAgICB2YXIgbWVzc2FnZSA9ICdQbGVhc2UgZGVsZXRlICcgKyBvdmVyQ2hhcnMgKyAnIGNoYXJhY3Rlcic7XHJcblxyXG4gICAgICBpZiAob3ZlckNoYXJzICE9IDEpIHtcclxuICAgICAgICBtZXNzYWdlICs9ICdzJztcclxuICAgICAgfVxyXG5cclxuICAgICAgcmV0dXJuIG1lc3NhZ2U7XHJcbiAgICB9LFxyXG4gICAgaW5wdXRUb29TaG9ydDogZnVuY3Rpb24gKGFyZ3MpIHtcclxuICAgICAgdmFyIHJlbWFpbmluZ0NoYXJzID0gYXJncy5taW5pbXVtIC0gYXJncy5pbnB1dC5sZW5ndGg7XHJcblxyXG4gICAgICB2YXIgbWVzc2FnZSA9ICdQbGVhc2UgZW50ZXIgJyArIHJlbWFpbmluZ0NoYXJzICsgJyBvciBtb3JlIGNoYXJhY3RlcnMnO1xyXG5cclxuICAgICAgcmV0dXJuIG1lc3NhZ2U7XHJcbiAgICB9LFxyXG4gICAgbG9hZGluZ01vcmU6IGZ1bmN0aW9uICgpIHtcclxuICAgICAgcmV0dXJuICdMb2FkaW5nIG1vcmUgcmVzdWx0c+KApic7XHJcbiAgICB9LFxyXG4gICAgbWF4aW11bVNlbGVjdGVkOiBmdW5jdGlvbiAoYXJncykge1xyXG4gICAgICB2YXIgbWVzc2FnZSA9ICdZb3UgY2FuIG9ubHkgc2VsZWN0ICcgKyBhcmdzLm1heGltdW0gKyAnIGl0ZW0nO1xyXG5cclxuICAgICAgaWYgKGFyZ3MubWF4aW11bSAhPSAxKSB7XHJcbiAgICAgICAgbWVzc2FnZSArPSAncyc7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIHJldHVybiBtZXNzYWdlO1xyXG4gICAgfSxcclxuICAgIG5vUmVzdWx0czogZnVuY3Rpb24gKCkge1xyXG4gICAgICByZXR1cm4gJ05vIHJlc3VsdHMgZm91bmQnO1xyXG4gICAgfSxcclxuICAgIHNlYXJjaGluZzogZnVuY3Rpb24gKCkge1xyXG4gICAgICByZXR1cm4gJ1NlYXJjaGluZ+KApic7XHJcbiAgICB9XHJcbiAgfTtcclxufSk7XHJcblxuUzIuZGVmaW5lKCdzZWxlY3QyL2RlZmF1bHRzJyxbXHJcbiAgJ2pxdWVyeScsXHJcbiAgJ3JlcXVpcmUnLFxyXG5cclxuICAnLi9yZXN1bHRzJyxcclxuXHJcbiAgJy4vc2VsZWN0aW9uL3NpbmdsZScsXHJcbiAgJy4vc2VsZWN0aW9uL211bHRpcGxlJyxcclxuICAnLi9zZWxlY3Rpb24vcGxhY2Vob2xkZXInLFxyXG4gICcuL3NlbGVjdGlvbi9hbGxvd0NsZWFyJyxcclxuICAnLi9zZWxlY3Rpb24vc2VhcmNoJyxcclxuICAnLi9zZWxlY3Rpb24vZXZlbnRSZWxheScsXHJcblxyXG4gICcuL3V0aWxzJyxcclxuICAnLi90cmFuc2xhdGlvbicsXHJcbiAgJy4vZGlhY3JpdGljcycsXHJcblxyXG4gICcuL2RhdGEvc2VsZWN0JyxcclxuICAnLi9kYXRhL2FycmF5JyxcclxuICAnLi9kYXRhL2FqYXgnLFxyXG4gICcuL2RhdGEvdGFncycsXHJcbiAgJy4vZGF0YS90b2tlbml6ZXInLFxyXG4gICcuL2RhdGEvbWluaW11bUlucHV0TGVuZ3RoJyxcclxuICAnLi9kYXRhL21heGltdW1JbnB1dExlbmd0aCcsXHJcbiAgJy4vZGF0YS9tYXhpbXVtU2VsZWN0aW9uTGVuZ3RoJyxcclxuXHJcbiAgJy4vZHJvcGRvd24nLFxyXG4gICcuL2Ryb3Bkb3duL3NlYXJjaCcsXHJcbiAgJy4vZHJvcGRvd24vaGlkZVBsYWNlaG9sZGVyJyxcclxuICAnLi9kcm9wZG93bi9pbmZpbml0ZVNjcm9sbCcsXHJcbiAgJy4vZHJvcGRvd24vYXR0YWNoQm9keScsXHJcbiAgJy4vZHJvcGRvd24vbWluaW11bVJlc3VsdHNGb3JTZWFyY2gnLFxyXG4gICcuL2Ryb3Bkb3duL3NlbGVjdE9uQ2xvc2UnLFxyXG4gICcuL2Ryb3Bkb3duL2Nsb3NlT25TZWxlY3QnLFxyXG5cclxuICAnLi9pMThuL2VuJ1xyXG5dLCBmdW5jdGlvbiAoJCwgcmVxdWlyZSxcclxuXHJcbiAgICAgICAgICAgICBSZXN1bHRzTGlzdCxcclxuXHJcbiAgICAgICAgICAgICBTaW5nbGVTZWxlY3Rpb24sIE11bHRpcGxlU2VsZWN0aW9uLCBQbGFjZWhvbGRlciwgQWxsb3dDbGVhcixcclxuICAgICAgICAgICAgIFNlbGVjdGlvblNlYXJjaCwgRXZlbnRSZWxheSxcclxuXHJcbiAgICAgICAgICAgICBVdGlscywgVHJhbnNsYXRpb24sIERJQUNSSVRJQ1MsXHJcblxyXG4gICAgICAgICAgICAgU2VsZWN0RGF0YSwgQXJyYXlEYXRhLCBBamF4RGF0YSwgVGFncywgVG9rZW5pemVyLFxyXG4gICAgICAgICAgICAgTWluaW11bUlucHV0TGVuZ3RoLCBNYXhpbXVtSW5wdXRMZW5ndGgsIE1heGltdW1TZWxlY3Rpb25MZW5ndGgsXHJcblxyXG4gICAgICAgICAgICAgRHJvcGRvd24sIERyb3Bkb3duU2VhcmNoLCBIaWRlUGxhY2Vob2xkZXIsIEluZmluaXRlU2Nyb2xsLFxyXG4gICAgICAgICAgICAgQXR0YWNoQm9keSwgTWluaW11bVJlc3VsdHNGb3JTZWFyY2gsIFNlbGVjdE9uQ2xvc2UsIENsb3NlT25TZWxlY3QsXHJcblxyXG4gICAgICAgICAgICAgRW5nbGlzaFRyYW5zbGF0aW9uKSB7XHJcbiAgZnVuY3Rpb24gRGVmYXVsdHMgKCkge1xyXG4gICAgdGhpcy5yZXNldCgpO1xyXG4gIH1cclxuXHJcbiAgRGVmYXVsdHMucHJvdG90eXBlLmFwcGx5ID0gZnVuY3Rpb24gKG9wdGlvbnMpIHtcclxuICAgIG9wdGlvbnMgPSAkLmV4dGVuZCh0cnVlLCB7fSwgdGhpcy5kZWZhdWx0cywgb3B0aW9ucyk7XHJcblxyXG4gICAgaWYgKG9wdGlvbnMuZGF0YUFkYXB0ZXIgPT0gbnVsbCkge1xyXG4gICAgICBpZiAob3B0aW9ucy5hamF4ICE9IG51bGwpIHtcclxuICAgICAgICBvcHRpb25zLmRhdGFBZGFwdGVyID0gQWpheERhdGE7XHJcbiAgICAgIH0gZWxzZSBpZiAob3B0aW9ucy5kYXRhICE9IG51bGwpIHtcclxuICAgICAgICBvcHRpb25zLmRhdGFBZGFwdGVyID0gQXJyYXlEYXRhO1xyXG4gICAgICB9IGVsc2Uge1xyXG4gICAgICAgIG9wdGlvbnMuZGF0YUFkYXB0ZXIgPSBTZWxlY3REYXRhO1xyXG4gICAgICB9XHJcblxyXG4gICAgICBpZiAob3B0aW9ucy5taW5pbXVtSW5wdXRMZW5ndGggPiAwKSB7XHJcbiAgICAgICAgb3B0aW9ucy5kYXRhQWRhcHRlciA9IFV0aWxzLkRlY29yYXRlKFxyXG4gICAgICAgICAgb3B0aW9ucy5kYXRhQWRhcHRlcixcclxuICAgICAgICAgIE1pbmltdW1JbnB1dExlbmd0aFxyXG4gICAgICAgICk7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIGlmIChvcHRpb25zLm1heGltdW1JbnB1dExlbmd0aCA+IDApIHtcclxuICAgICAgICBvcHRpb25zLmRhdGFBZGFwdGVyID0gVXRpbHMuRGVjb3JhdGUoXHJcbiAgICAgICAgICBvcHRpb25zLmRhdGFBZGFwdGVyLFxyXG4gICAgICAgICAgTWF4aW11bUlucHV0TGVuZ3RoXHJcbiAgICAgICAgKTtcclxuICAgICAgfVxyXG5cclxuICAgICAgaWYgKG9wdGlvbnMubWF4aW11bVNlbGVjdGlvbkxlbmd0aCA+IDApIHtcclxuICAgICAgICBvcHRpb25zLmRhdGFBZGFwdGVyID0gVXRpbHMuRGVjb3JhdGUoXHJcbiAgICAgICAgICBvcHRpb25zLmRhdGFBZGFwdGVyLFxyXG4gICAgICAgICAgTWF4aW11bVNlbGVjdGlvbkxlbmd0aFxyXG4gICAgICAgICk7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIGlmIChvcHRpb25zLnRhZ3MpIHtcclxuICAgICAgICBvcHRpb25zLmRhdGFBZGFwdGVyID0gVXRpbHMuRGVjb3JhdGUob3B0aW9ucy5kYXRhQWRhcHRlciwgVGFncyk7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIGlmIChvcHRpb25zLnRva2VuU2VwYXJhdG9ycyAhPSBudWxsIHx8IG9wdGlvbnMudG9rZW5pemVyICE9IG51bGwpIHtcclxuICAgICAgICBvcHRpb25zLmRhdGFBZGFwdGVyID0gVXRpbHMuRGVjb3JhdGUoXHJcbiAgICAgICAgICBvcHRpb25zLmRhdGFBZGFwdGVyLFxyXG4gICAgICAgICAgVG9rZW5pemVyXHJcbiAgICAgICAgKTtcclxuICAgICAgfVxyXG5cclxuICAgICAgaWYgKG9wdGlvbnMucXVlcnkgIT0gbnVsbCkge1xyXG4gICAgICAgIHZhciBRdWVyeSA9IHJlcXVpcmUob3B0aW9ucy5hbWRCYXNlICsgJ2NvbXBhdC9xdWVyeScpO1xyXG5cclxuICAgICAgICBvcHRpb25zLmRhdGFBZGFwdGVyID0gVXRpbHMuRGVjb3JhdGUoXHJcbiAgICAgICAgICBvcHRpb25zLmRhdGFBZGFwdGVyLFxyXG4gICAgICAgICAgUXVlcnlcclxuICAgICAgICApO1xyXG4gICAgICB9XHJcblxyXG4gICAgICBpZiAob3B0aW9ucy5pbml0U2VsZWN0aW9uICE9IG51bGwpIHtcclxuICAgICAgICB2YXIgSW5pdFNlbGVjdGlvbiA9IHJlcXVpcmUob3B0aW9ucy5hbWRCYXNlICsgJ2NvbXBhdC9pbml0U2VsZWN0aW9uJyk7XHJcblxyXG4gICAgICAgIG9wdGlvbnMuZGF0YUFkYXB0ZXIgPSBVdGlscy5EZWNvcmF0ZShcclxuICAgICAgICAgIG9wdGlvbnMuZGF0YUFkYXB0ZXIsXHJcbiAgICAgICAgICBJbml0U2VsZWN0aW9uXHJcbiAgICAgICAgKTtcclxuICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIGlmIChvcHRpb25zLnJlc3VsdHNBZGFwdGVyID09IG51bGwpIHtcclxuICAgICAgb3B0aW9ucy5yZXN1bHRzQWRhcHRlciA9IFJlc3VsdHNMaXN0O1xyXG5cclxuICAgICAgaWYgKG9wdGlvbnMuYWpheCAhPSBudWxsKSB7XHJcbiAgICAgICAgb3B0aW9ucy5yZXN1bHRzQWRhcHRlciA9IFV0aWxzLkRlY29yYXRlKFxyXG4gICAgICAgICAgb3B0aW9ucy5yZXN1bHRzQWRhcHRlcixcclxuICAgICAgICAgIEluZmluaXRlU2Nyb2xsXHJcbiAgICAgICAgKTtcclxuICAgICAgfVxyXG5cclxuICAgICAgaWYgKG9wdGlvbnMucGxhY2Vob2xkZXIgIT0gbnVsbCkge1xyXG4gICAgICAgIG9wdGlvbnMucmVzdWx0c0FkYXB0ZXIgPSBVdGlscy5EZWNvcmF0ZShcclxuICAgICAgICAgIG9wdGlvbnMucmVzdWx0c0FkYXB0ZXIsXHJcbiAgICAgICAgICBIaWRlUGxhY2Vob2xkZXJcclxuICAgICAgICApO1xyXG4gICAgICB9XHJcblxyXG4gICAgICBpZiAob3B0aW9ucy5zZWxlY3RPbkNsb3NlKSB7XHJcbiAgICAgICAgb3B0aW9ucy5yZXN1bHRzQWRhcHRlciA9IFV0aWxzLkRlY29yYXRlKFxyXG4gICAgICAgICAgb3B0aW9ucy5yZXN1bHRzQWRhcHRlcixcclxuICAgICAgICAgIFNlbGVjdE9uQ2xvc2VcclxuICAgICAgICApO1xyXG4gICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKG9wdGlvbnMuZHJvcGRvd25BZGFwdGVyID09IG51bGwpIHtcclxuICAgICAgaWYgKG9wdGlvbnMubXVsdGlwbGUpIHtcclxuICAgICAgICBvcHRpb25zLmRyb3Bkb3duQWRhcHRlciA9IERyb3Bkb3duO1xyXG4gICAgICB9IGVsc2Uge1xyXG4gICAgICAgIHZhciBTZWFyY2hhYmxlRHJvcGRvd24gPSBVdGlscy5EZWNvcmF0ZShEcm9wZG93biwgRHJvcGRvd25TZWFyY2gpO1xyXG5cclxuICAgICAgICBvcHRpb25zLmRyb3Bkb3duQWRhcHRlciA9IFNlYXJjaGFibGVEcm9wZG93bjtcclxuICAgICAgfVxyXG5cclxuICAgICAgaWYgKG9wdGlvbnMubWluaW11bVJlc3VsdHNGb3JTZWFyY2ggIT09IDApIHtcclxuICAgICAgICBvcHRpb25zLmRyb3Bkb3duQWRhcHRlciA9IFV0aWxzLkRlY29yYXRlKFxyXG4gICAgICAgICAgb3B0aW9ucy5kcm9wZG93bkFkYXB0ZXIsXHJcbiAgICAgICAgICBNaW5pbXVtUmVzdWx0c0ZvclNlYXJjaFxyXG4gICAgICAgICk7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIGlmIChvcHRpb25zLmNsb3NlT25TZWxlY3QpIHtcclxuICAgICAgICBvcHRpb25zLmRyb3Bkb3duQWRhcHRlciA9IFV0aWxzLkRlY29yYXRlKFxyXG4gICAgICAgICAgb3B0aW9ucy5kcm9wZG93bkFkYXB0ZXIsXHJcbiAgICAgICAgICBDbG9zZU9uU2VsZWN0XHJcbiAgICAgICAgKTtcclxuICAgICAgfVxyXG5cclxuICAgICAgaWYgKFxyXG4gICAgICAgIG9wdGlvbnMuZHJvcGRvd25Dc3NDbGFzcyAhPSBudWxsIHx8XHJcbiAgICAgICAgb3B0aW9ucy5kcm9wZG93bkNzcyAhPSBudWxsIHx8XHJcbiAgICAgICAgb3B0aW9ucy5hZGFwdERyb3Bkb3duQ3NzQ2xhc3MgIT0gbnVsbFxyXG4gICAgICApIHtcclxuICAgICAgICB2YXIgRHJvcGRvd25DU1MgPSByZXF1aXJlKG9wdGlvbnMuYW1kQmFzZSArICdjb21wYXQvZHJvcGRvd25Dc3MnKTtcclxuXHJcbiAgICAgICAgb3B0aW9ucy5kcm9wZG93bkFkYXB0ZXIgPSBVdGlscy5EZWNvcmF0ZShcclxuICAgICAgICAgIG9wdGlvbnMuZHJvcGRvd25BZGFwdGVyLFxyXG4gICAgICAgICAgRHJvcGRvd25DU1NcclxuICAgICAgICApO1xyXG4gICAgICB9XHJcblxyXG4gICAgICBvcHRpb25zLmRyb3Bkb3duQWRhcHRlciA9IFV0aWxzLkRlY29yYXRlKFxyXG4gICAgICAgIG9wdGlvbnMuZHJvcGRvd25BZGFwdGVyLFxyXG4gICAgICAgIEF0dGFjaEJvZHlcclxuICAgICAgKTtcclxuICAgIH1cclxuXHJcbiAgICBpZiAob3B0aW9ucy5zZWxlY3Rpb25BZGFwdGVyID09IG51bGwpIHtcclxuICAgICAgaWYgKG9wdGlvbnMubXVsdGlwbGUpIHtcclxuICAgICAgICBvcHRpb25zLnNlbGVjdGlvbkFkYXB0ZXIgPSBNdWx0aXBsZVNlbGVjdGlvbjtcclxuICAgICAgfSBlbHNlIHtcclxuICAgICAgICBvcHRpb25zLnNlbGVjdGlvbkFkYXB0ZXIgPSBTaW5nbGVTZWxlY3Rpb247XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIC8vIEFkZCB0aGUgcGxhY2Vob2xkZXIgbWl4aW4gaWYgYSBwbGFjZWhvbGRlciB3YXMgc3BlY2lmaWVkXHJcbiAgICAgIGlmIChvcHRpb25zLnBsYWNlaG9sZGVyICE9IG51bGwpIHtcclxuICAgICAgICBvcHRpb25zLnNlbGVjdGlvbkFkYXB0ZXIgPSBVdGlscy5EZWNvcmF0ZShcclxuICAgICAgICAgIG9wdGlvbnMuc2VsZWN0aW9uQWRhcHRlcixcclxuICAgICAgICAgIFBsYWNlaG9sZGVyXHJcbiAgICAgICAgKTtcclxuICAgICAgfVxyXG5cclxuICAgICAgaWYgKG9wdGlvbnMuYWxsb3dDbGVhcikge1xyXG4gICAgICAgIG9wdGlvbnMuc2VsZWN0aW9uQWRhcHRlciA9IFV0aWxzLkRlY29yYXRlKFxyXG4gICAgICAgICAgb3B0aW9ucy5zZWxlY3Rpb25BZGFwdGVyLFxyXG4gICAgICAgICAgQWxsb3dDbGVhclxyXG4gICAgICAgICk7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIGlmIChvcHRpb25zLm11bHRpcGxlKSB7XHJcbiAgICAgICAgb3B0aW9ucy5zZWxlY3Rpb25BZGFwdGVyID0gVXRpbHMuRGVjb3JhdGUoXHJcbiAgICAgICAgICBvcHRpb25zLnNlbGVjdGlvbkFkYXB0ZXIsXHJcbiAgICAgICAgICBTZWxlY3Rpb25TZWFyY2hcclxuICAgICAgICApO1xyXG4gICAgICB9XHJcblxyXG4gICAgICBpZiAoXHJcbiAgICAgICAgb3B0aW9ucy5jb250YWluZXJDc3NDbGFzcyAhPSBudWxsIHx8XHJcbiAgICAgICAgb3B0aW9ucy5jb250YWluZXJDc3MgIT0gbnVsbCB8fFxyXG4gICAgICAgIG9wdGlvbnMuYWRhcHRDb250YWluZXJDc3NDbGFzcyAhPSBudWxsXHJcbiAgICAgICkge1xyXG4gICAgICAgIHZhciBDb250YWluZXJDU1MgPSByZXF1aXJlKG9wdGlvbnMuYW1kQmFzZSArICdjb21wYXQvY29udGFpbmVyQ3NzJyk7XHJcblxyXG4gICAgICAgIG9wdGlvbnMuc2VsZWN0aW9uQWRhcHRlciA9IFV0aWxzLkRlY29yYXRlKFxyXG4gICAgICAgICAgb3B0aW9ucy5zZWxlY3Rpb25BZGFwdGVyLFxyXG4gICAgICAgICAgQ29udGFpbmVyQ1NTXHJcbiAgICAgICAgKTtcclxuICAgICAgfVxyXG5cclxuICAgICAgb3B0aW9ucy5zZWxlY3Rpb25BZGFwdGVyID0gVXRpbHMuRGVjb3JhdGUoXHJcbiAgICAgICAgb3B0aW9ucy5zZWxlY3Rpb25BZGFwdGVyLFxyXG4gICAgICAgIEV2ZW50UmVsYXlcclxuICAgICAgKTtcclxuICAgIH1cclxuXHJcbiAgICBpZiAodHlwZW9mIG9wdGlvbnMubGFuZ3VhZ2UgPT09ICdzdHJpbmcnKSB7XHJcbiAgICAgIC8vIENoZWNrIGlmIHRoZSBsYW5ndWFnZSBpcyBzcGVjaWZpZWQgd2l0aCBhIHJlZ2lvblxyXG4gICAgICBpZiAob3B0aW9ucy5sYW5ndWFnZS5pbmRleE9mKCctJykgPiAwKSB7XHJcbiAgICAgICAgLy8gRXh0cmFjdCB0aGUgcmVnaW9uIGluZm9ybWF0aW9uIGlmIGl0IGlzIGluY2x1ZGVkXHJcbiAgICAgICAgdmFyIGxhbmd1YWdlUGFydHMgPSBvcHRpb25zLmxhbmd1YWdlLnNwbGl0KCctJyk7XHJcbiAgICAgICAgdmFyIGJhc2VMYW5ndWFnZSA9IGxhbmd1YWdlUGFydHNbMF07XHJcblxyXG4gICAgICAgIG9wdGlvbnMubGFuZ3VhZ2UgPSBbb3B0aW9ucy5sYW5ndWFnZSwgYmFzZUxhbmd1YWdlXTtcclxuICAgICAgfSBlbHNlIHtcclxuICAgICAgICBvcHRpb25zLmxhbmd1YWdlID0gW29wdGlvbnMubGFuZ3VhZ2VdO1xyXG4gICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKCQuaXNBcnJheShvcHRpb25zLmxhbmd1YWdlKSkge1xyXG4gICAgICB2YXIgbGFuZ3VhZ2VzID0gbmV3IFRyYW5zbGF0aW9uKCk7XHJcbiAgICAgIG9wdGlvbnMubGFuZ3VhZ2UucHVzaCgnZW4nKTtcclxuXHJcbiAgICAgIHZhciBsYW5ndWFnZU5hbWVzID0gb3B0aW9ucy5sYW5ndWFnZTtcclxuXHJcbiAgICAgIGZvciAodmFyIGwgPSAwOyBsIDwgbGFuZ3VhZ2VOYW1lcy5sZW5ndGg7IGwrKykge1xyXG4gICAgICAgIHZhciBuYW1lID0gbGFuZ3VhZ2VOYW1lc1tsXTtcclxuICAgICAgICB2YXIgbGFuZ3VhZ2UgPSB7fTtcclxuXHJcbiAgICAgICAgdHJ5IHtcclxuICAgICAgICAgIC8vIFRyeSB0byBsb2FkIGl0IHdpdGggdGhlIG9yaWdpbmFsIG5hbWVcclxuICAgICAgICAgIGxhbmd1YWdlID0gVHJhbnNsYXRpb24ubG9hZFBhdGgobmFtZSk7XHJcbiAgICAgICAgfSBjYXRjaCAoZSkge1xyXG4gICAgICAgICAgdHJ5IHtcclxuICAgICAgICAgICAgLy8gSWYgd2UgY291bGRuJ3QgbG9hZCBpdCwgY2hlY2sgaWYgaXQgd2Fzbid0IHRoZSBmdWxsIHBhdGhcclxuICAgICAgICAgICAgbmFtZSA9IHRoaXMuZGVmYXVsdHMuYW1kTGFuZ3VhZ2VCYXNlICsgbmFtZTtcclxuICAgICAgICAgICAgbGFuZ3VhZ2UgPSBUcmFuc2xhdGlvbi5sb2FkUGF0aChuYW1lKTtcclxuICAgICAgICAgIH0gY2F0Y2ggKGV4KSB7XHJcbiAgICAgICAgICAgIC8vIFRoZSB0cmFuc2xhdGlvbiBjb3VsZCBub3QgYmUgbG9hZGVkIGF0IGFsbC4gU29tZXRpbWVzIHRoaXMgaXNcclxuICAgICAgICAgICAgLy8gYmVjYXVzZSBvZiBhIGNvbmZpZ3VyYXRpb24gcHJvYmxlbSwgb3RoZXIgdGltZXMgdGhpcyBjYW4gYmVcclxuICAgICAgICAgICAgLy8gYmVjYXVzZSBvZiBob3cgU2VsZWN0MiBoZWxwcyBsb2FkIGFsbCBwb3NzaWJsZSB0cmFuc2xhdGlvbiBmaWxlcy5cclxuICAgICAgICAgICAgaWYgKG9wdGlvbnMuZGVidWcgJiYgd2luZG93LmNvbnNvbGUgJiYgY29uc29sZS53YXJuKSB7XHJcbiAgICAgICAgICAgICAgY29uc29sZS53YXJuKFxyXG4gICAgICAgICAgICAgICAgJ1NlbGVjdDI6IFRoZSBsYW5ndWFnZSBmaWxlIGZvciBcIicgKyBuYW1lICsgJ1wiIGNvdWxkIG5vdCBiZSAnICtcclxuICAgICAgICAgICAgICAgICdhdXRvbWF0aWNhbGx5IGxvYWRlZC4gQSBmYWxsYmFjayB3aWxsIGJlIHVzZWQgaW5zdGVhZC4nXHJcbiAgICAgICAgICAgICAgKTtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgY29udGludWU7XHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBsYW5ndWFnZXMuZXh0ZW5kKGxhbmd1YWdlKTtcclxuICAgICAgfVxyXG5cclxuICAgICAgb3B0aW9ucy50cmFuc2xhdGlvbnMgPSBsYW5ndWFnZXM7XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICB2YXIgYmFzZVRyYW5zbGF0aW9uID0gVHJhbnNsYXRpb24ubG9hZFBhdGgoXHJcbiAgICAgICAgdGhpcy5kZWZhdWx0cy5hbWRMYW5ndWFnZUJhc2UgKyAnZW4nXHJcbiAgICAgICk7XHJcbiAgICAgIHZhciBjdXN0b21UcmFuc2xhdGlvbiA9IG5ldyBUcmFuc2xhdGlvbihvcHRpb25zLmxhbmd1YWdlKTtcclxuXHJcbiAgICAgIGN1c3RvbVRyYW5zbGF0aW9uLmV4dGVuZChiYXNlVHJhbnNsYXRpb24pO1xyXG5cclxuICAgICAgb3B0aW9ucy50cmFuc2xhdGlvbnMgPSBjdXN0b21UcmFuc2xhdGlvbjtcclxuICAgIH1cclxuXHJcbiAgICByZXR1cm4gb3B0aW9ucztcclxuICB9O1xyXG5cclxuICBEZWZhdWx0cy5wcm90b3R5cGUucmVzZXQgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICBmdW5jdGlvbiBzdHJpcERpYWNyaXRpY3MgKHRleHQpIHtcclxuICAgICAgLy8gVXNlZCAndW5pIHJhbmdlICsgbmFtZWQgZnVuY3Rpb24nIGZyb20gaHR0cDovL2pzcGVyZi5jb20vZGlhY3JpdGljcy8xOFxyXG4gICAgICBmdW5jdGlvbiBtYXRjaChhKSB7XHJcbiAgICAgICAgcmV0dXJuIERJQUNSSVRJQ1NbYV0gfHwgYTtcclxuICAgICAgfVxyXG5cclxuICAgICAgcmV0dXJuIHRleHQucmVwbGFjZSgvW15cXHUwMDAwLVxcdTAwN0VdL2csIG1hdGNoKTtcclxuICAgIH1cclxuXHJcbiAgICBmdW5jdGlvbiBtYXRjaGVyIChwYXJhbXMsIGRhdGEpIHtcclxuICAgICAgLy8gQWx3YXlzIHJldHVybiB0aGUgb2JqZWN0IGlmIHRoZXJlIGlzIG5vdGhpbmcgdG8gY29tcGFyZVxyXG4gICAgICBpZiAoJC50cmltKHBhcmFtcy50ZXJtKSA9PT0gJycpIHtcclxuICAgICAgICByZXR1cm4gZGF0YTtcclxuICAgICAgfVxyXG5cclxuICAgICAgLy8gRG8gYSByZWN1cnNpdmUgY2hlY2sgZm9yIG9wdGlvbnMgd2l0aCBjaGlsZHJlblxyXG4gICAgICBpZiAoZGF0YS5jaGlsZHJlbiAmJiBkYXRhLmNoaWxkcmVuLmxlbmd0aCA+IDApIHtcclxuICAgICAgICAvLyBDbG9uZSB0aGUgZGF0YSBvYmplY3QgaWYgdGhlcmUgYXJlIGNoaWxkcmVuXHJcbiAgICAgICAgLy8gVGhpcyBpcyByZXF1aXJlZCBhcyB3ZSBtb2RpZnkgdGhlIG9iamVjdCB0byByZW1vdmUgYW55IG5vbi1tYXRjaGVzXHJcbiAgICAgICAgdmFyIG1hdGNoID0gJC5leHRlbmQodHJ1ZSwge30sIGRhdGEpO1xyXG5cclxuICAgICAgICAvLyBDaGVjayBlYWNoIGNoaWxkIG9mIHRoZSBvcHRpb25cclxuICAgICAgICBmb3IgKHZhciBjID0gZGF0YS5jaGlsZHJlbi5sZW5ndGggLSAxOyBjID49IDA7IGMtLSkge1xyXG4gICAgICAgICAgdmFyIGNoaWxkID0gZGF0YS5jaGlsZHJlbltjXTtcclxuXHJcbiAgICAgICAgICB2YXIgbWF0Y2hlcyA9IG1hdGNoZXIocGFyYW1zLCBjaGlsZCk7XHJcblxyXG4gICAgICAgICAgLy8gSWYgdGhlcmUgd2Fzbid0IGEgbWF0Y2gsIHJlbW92ZSB0aGUgb2JqZWN0IGluIHRoZSBhcnJheVxyXG4gICAgICAgICAgaWYgKG1hdGNoZXMgPT0gbnVsbCkge1xyXG4gICAgICAgICAgICBtYXRjaC5jaGlsZHJlbi5zcGxpY2UoYywgMSk7XHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICAvLyBJZiBhbnkgY2hpbGRyZW4gbWF0Y2hlZCwgcmV0dXJuIHRoZSBuZXcgb2JqZWN0XHJcbiAgICAgICAgaWYgKG1hdGNoLmNoaWxkcmVuLmxlbmd0aCA+IDApIHtcclxuICAgICAgICAgIHJldHVybiBtYXRjaDtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIC8vIElmIHRoZXJlIHdlcmUgbm8gbWF0Y2hpbmcgY2hpbGRyZW4sIGNoZWNrIGp1c3QgdGhlIHBsYWluIG9iamVjdFxyXG4gICAgICAgIHJldHVybiBtYXRjaGVyKHBhcmFtcywgbWF0Y2gpO1xyXG4gICAgICB9XHJcblxyXG4gICAgICB2YXIgb3JpZ2luYWwgPSBzdHJpcERpYWNyaXRpY3MoZGF0YS50ZXh0KS50b1VwcGVyQ2FzZSgpO1xyXG4gICAgICB2YXIgdGVybSA9IHN0cmlwRGlhY3JpdGljcyhwYXJhbXMudGVybSkudG9VcHBlckNhc2UoKTtcclxuXHJcbiAgICAgIC8vIENoZWNrIGlmIHRoZSB0ZXh0IGNvbnRhaW5zIHRoZSB0ZXJtXHJcbiAgICAgIGlmIChvcmlnaW5hbC5pbmRleE9mKHRlcm0pID4gLTEpIHtcclxuICAgICAgICByZXR1cm4gZGF0YTtcclxuICAgICAgfVxyXG5cclxuICAgICAgLy8gSWYgaXQgZG9lc24ndCBjb250YWluIHRoZSB0ZXJtLCBkb24ndCByZXR1cm4gYW55dGhpbmdcclxuICAgICAgcmV0dXJuIG51bGw7XHJcbiAgICB9XHJcblxyXG4gICAgdGhpcy5kZWZhdWx0cyA9IHtcclxuICAgICAgYW1kQmFzZTogJy4vJyxcclxuICAgICAgYW1kTGFuZ3VhZ2VCYXNlOiAnLi9pMThuLycsXHJcbiAgICAgIGNsb3NlT25TZWxlY3Q6IHRydWUsXHJcbiAgICAgIGRlYnVnOiBmYWxzZSxcclxuICAgICAgZHJvcGRvd25BdXRvV2lkdGg6IGZhbHNlLFxyXG4gICAgICBlc2NhcGVNYXJrdXA6IFV0aWxzLmVzY2FwZU1hcmt1cCxcclxuICAgICAgbGFuZ3VhZ2U6IEVuZ2xpc2hUcmFuc2xhdGlvbixcclxuICAgICAgbWF0Y2hlcjogbWF0Y2hlcixcclxuICAgICAgbWluaW11bUlucHV0TGVuZ3RoOiAwLFxyXG4gICAgICBtYXhpbXVtSW5wdXRMZW5ndGg6IDAsXHJcbiAgICAgIG1heGltdW1TZWxlY3Rpb25MZW5ndGg6IDAsXHJcbiAgICAgIG1pbmltdW1SZXN1bHRzRm9yU2VhcmNoOiAwLFxyXG4gICAgICBzZWxlY3RPbkNsb3NlOiBmYWxzZSxcclxuICAgICAgc29ydGVyOiBmdW5jdGlvbiAoZGF0YSkge1xyXG4gICAgICAgIHJldHVybiBkYXRhO1xyXG4gICAgICB9LFxyXG4gICAgICB0ZW1wbGF0ZVJlc3VsdDogZnVuY3Rpb24gKHJlc3VsdCkge1xyXG4gICAgICAgIHJldHVybiByZXN1bHQudGV4dDtcclxuICAgICAgfSxcclxuICAgICAgdGVtcGxhdGVTZWxlY3Rpb246IGZ1bmN0aW9uIChzZWxlY3Rpb24pIHtcclxuICAgICAgICByZXR1cm4gc2VsZWN0aW9uLnRleHQ7XHJcbiAgICAgIH0sXHJcbiAgICAgIHRoZW1lOiAnZGVmYXVsdCcsXHJcbiAgICAgIHdpZHRoOiAncmVzb2x2ZSdcclxuICAgIH07XHJcbiAgfTtcclxuXHJcbiAgRGVmYXVsdHMucHJvdG90eXBlLnNldCA9IGZ1bmN0aW9uIChrZXksIHZhbHVlKSB7XHJcbiAgICB2YXIgY2FtZWxLZXkgPSAkLmNhbWVsQ2FzZShrZXkpO1xyXG5cclxuICAgIHZhciBkYXRhID0ge307XHJcbiAgICBkYXRhW2NhbWVsS2V5XSA9IHZhbHVlO1xyXG5cclxuICAgIHZhciBjb252ZXJ0ZWREYXRhID0gVXRpbHMuX2NvbnZlcnREYXRhKGRhdGEpO1xyXG5cclxuICAgICQuZXh0ZW5kKHRoaXMuZGVmYXVsdHMsIGNvbnZlcnRlZERhdGEpO1xyXG4gIH07XHJcblxyXG4gIHZhciBkZWZhdWx0cyA9IG5ldyBEZWZhdWx0cygpO1xyXG5cclxuICByZXR1cm4gZGVmYXVsdHM7XHJcbn0pO1xyXG5cblMyLmRlZmluZSgnc2VsZWN0Mi9vcHRpb25zJyxbXHJcbiAgJ3JlcXVpcmUnLFxyXG4gICdqcXVlcnknLFxyXG4gICcuL2RlZmF1bHRzJyxcclxuICAnLi91dGlscydcclxuXSwgZnVuY3Rpb24gKHJlcXVpcmUsICQsIERlZmF1bHRzLCBVdGlscykge1xyXG4gIGZ1bmN0aW9uIE9wdGlvbnMgKG9wdGlvbnMsICRlbGVtZW50KSB7XHJcbiAgICB0aGlzLm9wdGlvbnMgPSBvcHRpb25zO1xyXG5cclxuICAgIGlmICgkZWxlbWVudCAhPSBudWxsKSB7XHJcbiAgICAgIHRoaXMuZnJvbUVsZW1lbnQoJGVsZW1lbnQpO1xyXG4gICAgfVxyXG5cclxuICAgIHRoaXMub3B0aW9ucyA9IERlZmF1bHRzLmFwcGx5KHRoaXMub3B0aW9ucyk7XHJcblxyXG4gICAgaWYgKCRlbGVtZW50ICYmICRlbGVtZW50LmlzKCdpbnB1dCcpKSB7XHJcbiAgICAgIHZhciBJbnB1dENvbXBhdCA9IHJlcXVpcmUodGhpcy5nZXQoJ2FtZEJhc2UnKSArICdjb21wYXQvaW5wdXREYXRhJyk7XHJcblxyXG4gICAgICB0aGlzLm9wdGlvbnMuZGF0YUFkYXB0ZXIgPSBVdGlscy5EZWNvcmF0ZShcclxuICAgICAgICB0aGlzLm9wdGlvbnMuZGF0YUFkYXB0ZXIsXHJcbiAgICAgICAgSW5wdXRDb21wYXRcclxuICAgICAgKTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIE9wdGlvbnMucHJvdG90eXBlLmZyb21FbGVtZW50ID0gZnVuY3Rpb24gKCRlKSB7XHJcbiAgICB2YXIgZXhjbHVkZWREYXRhID0gWydzZWxlY3QyJ107XHJcblxyXG4gICAgaWYgKHRoaXMub3B0aW9ucy5tdWx0aXBsZSA9PSBudWxsKSB7XHJcbiAgICAgIHRoaXMub3B0aW9ucy5tdWx0aXBsZSA9ICRlLnByb3AoJ211bHRpcGxlJyk7XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKHRoaXMub3B0aW9ucy5kaXNhYmxlZCA9PSBudWxsKSB7XHJcbiAgICAgIHRoaXMub3B0aW9ucy5kaXNhYmxlZCA9ICRlLnByb3AoJ2Rpc2FibGVkJyk7XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKHRoaXMub3B0aW9ucy5sYW5ndWFnZSA9PSBudWxsKSB7XHJcbiAgICAgIGlmICgkZS5wcm9wKCdsYW5nJykpIHtcclxuICAgICAgICB0aGlzLm9wdGlvbnMubGFuZ3VhZ2UgPSAkZS5wcm9wKCdsYW5nJykudG9Mb3dlckNhc2UoKTtcclxuICAgICAgfSBlbHNlIGlmICgkZS5jbG9zZXN0KCdbbGFuZ10nKS5wcm9wKCdsYW5nJykpIHtcclxuICAgICAgICB0aGlzLm9wdGlvbnMubGFuZ3VhZ2UgPSAkZS5jbG9zZXN0KCdbbGFuZ10nKS5wcm9wKCdsYW5nJyk7XHJcbiAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBpZiAodGhpcy5vcHRpb25zLmRpciA9PSBudWxsKSB7XHJcbiAgICAgIGlmICgkZS5wcm9wKCdkaXInKSkge1xyXG4gICAgICAgIHRoaXMub3B0aW9ucy5kaXIgPSAkZS5wcm9wKCdkaXInKTtcclxuICAgICAgfSBlbHNlIGlmICgkZS5jbG9zZXN0KCdbZGlyXScpLnByb3AoJ2RpcicpKSB7XHJcbiAgICAgICAgdGhpcy5vcHRpb25zLmRpciA9ICRlLmNsb3Nlc3QoJ1tkaXJdJykucHJvcCgnZGlyJyk7XHJcbiAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgdGhpcy5vcHRpb25zLmRpciA9ICdsdHInO1xyXG4gICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgJGUucHJvcCgnZGlzYWJsZWQnLCB0aGlzLm9wdGlvbnMuZGlzYWJsZWQpO1xyXG4gICAgJGUucHJvcCgnbXVsdGlwbGUnLCB0aGlzLm9wdGlvbnMubXVsdGlwbGUpO1xyXG5cclxuICAgIGlmICgkZS5kYXRhKCdzZWxlY3QyVGFncycpKSB7XHJcbiAgICAgIGlmICh0aGlzLm9wdGlvbnMuZGVidWcgJiYgd2luZG93LmNvbnNvbGUgJiYgY29uc29sZS53YXJuKSB7XHJcbiAgICAgICAgY29uc29sZS53YXJuKFxyXG4gICAgICAgICAgJ1NlbGVjdDI6IFRoZSBgZGF0YS1zZWxlY3QyLXRhZ3NgIGF0dHJpYnV0ZSBoYXMgYmVlbiBjaGFuZ2VkIHRvICcgK1xyXG4gICAgICAgICAgJ3VzZSB0aGUgYGRhdGEtZGF0YWAgYW5kIGBkYXRhLXRhZ3M9XCJ0cnVlXCJgIGF0dHJpYnV0ZXMgYW5kIHdpbGwgYmUgJyArXHJcbiAgICAgICAgICAncmVtb3ZlZCBpbiBmdXR1cmUgdmVyc2lvbnMgb2YgU2VsZWN0Mi4nXHJcbiAgICAgICAgKTtcclxuICAgICAgfVxyXG5cclxuICAgICAgJGUuZGF0YSgnZGF0YScsICRlLmRhdGEoJ3NlbGVjdDJUYWdzJykpO1xyXG4gICAgICAkZS5kYXRhKCd0YWdzJywgdHJ1ZSk7XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKCRlLmRhdGEoJ2FqYXhVcmwnKSkge1xyXG4gICAgICBpZiAodGhpcy5vcHRpb25zLmRlYnVnICYmIHdpbmRvdy5jb25zb2xlICYmIGNvbnNvbGUud2Fybikge1xyXG4gICAgICAgIGNvbnNvbGUud2FybihcclxuICAgICAgICAgICdTZWxlY3QyOiBUaGUgYGRhdGEtYWpheC11cmxgIGF0dHJpYnV0ZSBoYXMgYmVlbiBjaGFuZ2VkIHRvICcgK1xyXG4gICAgICAgICAgJ2BkYXRhLWFqYXgtLXVybGAgYW5kIHN1cHBvcnQgZm9yIHRoZSBvbGQgYXR0cmlidXRlIHdpbGwgYmUgcmVtb3ZlZCcgK1xyXG4gICAgICAgICAgJyBpbiBmdXR1cmUgdmVyc2lvbnMgb2YgU2VsZWN0Mi4nXHJcbiAgICAgICAgKTtcclxuICAgICAgfVxyXG5cclxuICAgICAgJGUuYXR0cignYWpheC0tdXJsJywgJGUuZGF0YSgnYWpheFVybCcpKTtcclxuICAgICAgJGUuZGF0YSgnYWpheC0tdXJsJywgJGUuZGF0YSgnYWpheFVybCcpKTtcclxuICAgIH1cclxuXHJcbiAgICB2YXIgZGF0YXNldCA9IHt9O1xyXG5cclxuICAgIC8vIFByZWZlciB0aGUgZWxlbWVudCdzIGBkYXRhc2V0YCBhdHRyaWJ1dGUgaWYgaXQgZXhpc3RzXHJcbiAgICAvLyBqUXVlcnkgMS54IGRvZXMgbm90IGNvcnJlY3RseSBoYW5kbGUgZGF0YSBhdHRyaWJ1dGVzIHdpdGggbXVsdGlwbGUgZGFzaGVzXHJcbiAgICBpZiAoJC5mbi5qcXVlcnkgJiYgJC5mbi5qcXVlcnkuc3Vic3RyKDAsIDIpID09ICcxLicgJiYgJGVbMF0uZGF0YXNldCkge1xyXG4gICAgICBkYXRhc2V0ID0gJC5leHRlbmQodHJ1ZSwge30sICRlWzBdLmRhdGFzZXQsICRlLmRhdGEoKSk7XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICBkYXRhc2V0ID0gJGUuZGF0YSgpO1xyXG4gICAgfVxyXG5cclxuICAgIHZhciBkYXRhID0gJC5leHRlbmQodHJ1ZSwge30sIGRhdGFzZXQpO1xyXG5cclxuICAgIGRhdGEgPSBVdGlscy5fY29udmVydERhdGEoZGF0YSk7XHJcblxyXG4gICAgZm9yICh2YXIga2V5IGluIGRhdGEpIHtcclxuICAgICAgaWYgKCQuaW5BcnJheShrZXksIGV4Y2x1ZGVkRGF0YSkgPiAtMSkge1xyXG4gICAgICAgIGNvbnRpbnVlO1xyXG4gICAgICB9XHJcblxyXG4gICAgICBpZiAoJC5pc1BsYWluT2JqZWN0KHRoaXMub3B0aW9uc1trZXldKSkge1xyXG4gICAgICAgICQuZXh0ZW5kKHRoaXMub3B0aW9uc1trZXldLCBkYXRhW2tleV0pO1xyXG4gICAgICB9IGVsc2Uge1xyXG4gICAgICAgIHRoaXMub3B0aW9uc1trZXldID0gZGF0YVtrZXldO1xyXG4gICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgcmV0dXJuIHRoaXM7XHJcbiAgfTtcclxuXHJcbiAgT3B0aW9ucy5wcm90b3R5cGUuZ2V0ID0gZnVuY3Rpb24gKGtleSkge1xyXG4gICAgcmV0dXJuIHRoaXMub3B0aW9uc1trZXldO1xyXG4gIH07XHJcblxyXG4gIE9wdGlvbnMucHJvdG90eXBlLnNldCA9IGZ1bmN0aW9uIChrZXksIHZhbCkge1xyXG4gICAgdGhpcy5vcHRpb25zW2tleV0gPSB2YWw7XHJcbiAgfTtcclxuXHJcbiAgcmV0dXJuIE9wdGlvbnM7XHJcbn0pO1xyXG5cblMyLmRlZmluZSgnc2VsZWN0Mi9jb3JlJyxbXHJcbiAgJ2pxdWVyeScsXHJcbiAgJy4vb3B0aW9ucycsXHJcbiAgJy4vdXRpbHMnLFxyXG4gICcuL2tleXMnXHJcbl0sIGZ1bmN0aW9uICgkLCBPcHRpb25zLCBVdGlscywgS0VZUykge1xyXG4gIHZhciBTZWxlY3QyID0gZnVuY3Rpb24gKCRlbGVtZW50LCBvcHRpb25zKSB7XHJcbiAgICBpZiAoJGVsZW1lbnQuZGF0YSgnc2VsZWN0MicpICE9IG51bGwpIHtcclxuICAgICAgJGVsZW1lbnQuZGF0YSgnc2VsZWN0MicpLmRlc3Ryb3koKTtcclxuICAgIH1cclxuXHJcbiAgICB0aGlzLiRlbGVtZW50ID0gJGVsZW1lbnQ7XHJcblxyXG4gICAgdGhpcy5pZCA9IHRoaXMuX2dlbmVyYXRlSWQoJGVsZW1lbnQpO1xyXG5cclxuICAgIG9wdGlvbnMgPSBvcHRpb25zIHx8IHt9O1xyXG5cclxuICAgIHRoaXMub3B0aW9ucyA9IG5ldyBPcHRpb25zKG9wdGlvbnMsICRlbGVtZW50KTtcclxuXHJcbiAgICBTZWxlY3QyLl9fc3VwZXJfXy5jb25zdHJ1Y3Rvci5jYWxsKHRoaXMpO1xyXG5cclxuICAgIC8vIFNldCB1cCB0aGUgdGFiaW5kZXhcclxuXHJcbiAgICB2YXIgdGFiaW5kZXggPSAkZWxlbWVudC5hdHRyKCd0YWJpbmRleCcpIHx8IDA7XHJcbiAgICAkZWxlbWVudC5kYXRhKCdvbGQtdGFiaW5kZXgnLCB0YWJpbmRleCk7XHJcbiAgICAkZWxlbWVudC5hdHRyKCd0YWJpbmRleCcsICctMScpO1xyXG5cclxuICAgIC8vIFNldCB1cCBjb250YWluZXJzIGFuZCBhZGFwdGVyc1xyXG5cclxuICAgIHZhciBEYXRhQWRhcHRlciA9IHRoaXMub3B0aW9ucy5nZXQoJ2RhdGFBZGFwdGVyJyk7XHJcbiAgICB0aGlzLmRhdGFBZGFwdGVyID0gbmV3IERhdGFBZGFwdGVyKCRlbGVtZW50LCB0aGlzLm9wdGlvbnMpO1xyXG5cclxuICAgIHZhciAkY29udGFpbmVyID0gdGhpcy5yZW5kZXIoKTtcclxuXHJcbiAgICB0aGlzLl9wbGFjZUNvbnRhaW5lcigkY29udGFpbmVyKTtcclxuXHJcbiAgICB2YXIgU2VsZWN0aW9uQWRhcHRlciA9IHRoaXMub3B0aW9ucy5nZXQoJ3NlbGVjdGlvbkFkYXB0ZXInKTtcclxuICAgIHRoaXMuc2VsZWN0aW9uID0gbmV3IFNlbGVjdGlvbkFkYXB0ZXIoJGVsZW1lbnQsIHRoaXMub3B0aW9ucyk7XHJcbiAgICB0aGlzLiRzZWxlY3Rpb24gPSB0aGlzLnNlbGVjdGlvbi5yZW5kZXIoKTtcclxuXHJcbiAgICB0aGlzLnNlbGVjdGlvbi5wb3NpdGlvbih0aGlzLiRzZWxlY3Rpb24sICRjb250YWluZXIpO1xyXG5cclxuICAgIHZhciBEcm9wZG93bkFkYXB0ZXIgPSB0aGlzLm9wdGlvbnMuZ2V0KCdkcm9wZG93bkFkYXB0ZXInKTtcclxuICAgIHRoaXMuZHJvcGRvd24gPSBuZXcgRHJvcGRvd25BZGFwdGVyKCRlbGVtZW50LCB0aGlzLm9wdGlvbnMpO1xyXG4gICAgdGhpcy4kZHJvcGRvd24gPSB0aGlzLmRyb3Bkb3duLnJlbmRlcigpO1xyXG5cclxuICAgIHRoaXMuZHJvcGRvd24ucG9zaXRpb24odGhpcy4kZHJvcGRvd24sICRjb250YWluZXIpO1xyXG5cclxuICAgIHZhciBSZXN1bHRzQWRhcHRlciA9IHRoaXMub3B0aW9ucy5nZXQoJ3Jlc3VsdHNBZGFwdGVyJyk7XHJcbiAgICB0aGlzLnJlc3VsdHMgPSBuZXcgUmVzdWx0c0FkYXB0ZXIoJGVsZW1lbnQsIHRoaXMub3B0aW9ucywgdGhpcy5kYXRhQWRhcHRlcik7XHJcbiAgICB0aGlzLiRyZXN1bHRzID0gdGhpcy5yZXN1bHRzLnJlbmRlcigpO1xyXG5cclxuICAgIHRoaXMucmVzdWx0cy5wb3NpdGlvbih0aGlzLiRyZXN1bHRzLCB0aGlzLiRkcm9wZG93bik7XHJcblxyXG4gICAgLy8gQmluZCBldmVudHNcclxuXHJcbiAgICB2YXIgc2VsZiA9IHRoaXM7XHJcblxyXG4gICAgLy8gQmluZCB0aGUgY29udGFpbmVyIHRvIGFsbCBvZiB0aGUgYWRhcHRlcnNcclxuICAgIHRoaXMuX2JpbmRBZGFwdGVycygpO1xyXG5cclxuICAgIC8vIFJlZ2lzdGVyIGFueSBET00gZXZlbnQgaGFuZGxlcnNcclxuICAgIHRoaXMuX3JlZ2lzdGVyRG9tRXZlbnRzKCk7XHJcblxyXG4gICAgLy8gUmVnaXN0ZXIgYW55IGludGVybmFsIGV2ZW50IGhhbmRsZXJzXHJcbiAgICB0aGlzLl9yZWdpc3RlckRhdGFFdmVudHMoKTtcclxuICAgIHRoaXMuX3JlZ2lzdGVyU2VsZWN0aW9uRXZlbnRzKCk7XHJcbiAgICB0aGlzLl9yZWdpc3RlckRyb3Bkb3duRXZlbnRzKCk7XHJcbiAgICB0aGlzLl9yZWdpc3RlclJlc3VsdHNFdmVudHMoKTtcclxuICAgIHRoaXMuX3JlZ2lzdGVyRXZlbnRzKCk7XHJcblxyXG4gICAgLy8gU2V0IHRoZSBpbml0aWFsIHN0YXRlXHJcbiAgICB0aGlzLmRhdGFBZGFwdGVyLmN1cnJlbnQoZnVuY3Rpb24gKGluaXRpYWxEYXRhKSB7XHJcbiAgICAgIHNlbGYudHJpZ2dlcignc2VsZWN0aW9uOnVwZGF0ZScsIHtcclxuICAgICAgICBkYXRhOiBpbml0aWFsRGF0YVxyXG4gICAgICB9KTtcclxuICAgIH0pO1xyXG5cclxuICAgIC8vIEhpZGUgdGhlIG9yaWdpbmFsIHNlbGVjdFxyXG4gICAgJGVsZW1lbnQuYWRkQ2xhc3MoJ3NlbGVjdDItaGlkZGVuLWFjY2Vzc2libGUnKTtcclxuICAgICRlbGVtZW50LmF0dHIoJ2FyaWEtaGlkZGVuJywgJ3RydWUnKTtcclxuXHJcbiAgICAvLyBTeW5jaHJvbml6ZSBhbnkgbW9uaXRvcmVkIGF0dHJpYnV0ZXNcclxuICAgIHRoaXMuX3N5bmNBdHRyaWJ1dGVzKCk7XHJcblxyXG4gICAgJGVsZW1lbnQuZGF0YSgnc2VsZWN0MicsIHRoaXMpO1xyXG4gIH07XHJcblxyXG4gIFV0aWxzLkV4dGVuZChTZWxlY3QyLCBVdGlscy5PYnNlcnZhYmxlKTtcclxuXHJcbiAgU2VsZWN0Mi5wcm90b3R5cGUuX2dlbmVyYXRlSWQgPSBmdW5jdGlvbiAoJGVsZW1lbnQpIHtcclxuICAgIHZhciBpZCA9ICcnO1xyXG5cclxuICAgIGlmICgkZWxlbWVudC5hdHRyKCdpZCcpICE9IG51bGwpIHtcclxuICAgICAgaWQgPSAkZWxlbWVudC5hdHRyKCdpZCcpO1xyXG4gICAgfSBlbHNlIGlmICgkZWxlbWVudC5hdHRyKCduYW1lJykgIT0gbnVsbCkge1xyXG4gICAgICBpZCA9ICRlbGVtZW50LmF0dHIoJ25hbWUnKSArICctJyArIFV0aWxzLmdlbmVyYXRlQ2hhcnMoMik7XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICBpZCA9IFV0aWxzLmdlbmVyYXRlQ2hhcnMoNCk7XHJcbiAgICB9XHJcblxyXG4gICAgaWQgPSBpZC5yZXBsYWNlKC8oOnxcXC58XFxbfFxcXXwsKS9nLCAnJyk7XHJcbiAgICBpZCA9ICdzZWxlY3QyLScgKyBpZDtcclxuXHJcbiAgICByZXR1cm4gaWQ7XHJcbiAgfTtcclxuXHJcbiAgU2VsZWN0Mi5wcm90b3R5cGUuX3BsYWNlQ29udGFpbmVyID0gZnVuY3Rpb24gKCRjb250YWluZXIpIHtcclxuICAgICRjb250YWluZXIuaW5zZXJ0QWZ0ZXIodGhpcy4kZWxlbWVudCk7XHJcblxyXG4gICAgdmFyIHdpZHRoID0gdGhpcy5fcmVzb2x2ZVdpZHRoKHRoaXMuJGVsZW1lbnQsIHRoaXMub3B0aW9ucy5nZXQoJ3dpZHRoJykpO1xyXG5cclxuICAgIGlmICh3aWR0aCAhPSBudWxsKSB7XHJcbiAgICAgICRjb250YWluZXIuY3NzKCd3aWR0aCcsIHdpZHRoKTtcclxuICAgIH1cclxuICB9O1xyXG5cclxuICBTZWxlY3QyLnByb3RvdHlwZS5fcmVzb2x2ZVdpZHRoID0gZnVuY3Rpb24gKCRlbGVtZW50LCBtZXRob2QpIHtcclxuICAgIHZhciBXSURUSCA9IC9ed2lkdGg6KChbLStdPyhbMC05XSpcXC4pP1swLTldKykocHh8ZW18ZXh8JXxpbnxjbXxtbXxwdHxwYykpL2k7XHJcblxyXG4gICAgaWYgKG1ldGhvZCA9PSAncmVzb2x2ZScpIHtcclxuICAgICAgdmFyIHN0eWxlV2lkdGggPSB0aGlzLl9yZXNvbHZlV2lkdGgoJGVsZW1lbnQsICdzdHlsZScpO1xyXG5cclxuICAgICAgaWYgKHN0eWxlV2lkdGggIT0gbnVsbCkge1xyXG4gICAgICAgIHJldHVybiBzdHlsZVdpZHRoO1xyXG4gICAgICB9XHJcblxyXG4gICAgICByZXR1cm4gdGhpcy5fcmVzb2x2ZVdpZHRoKCRlbGVtZW50LCAnZWxlbWVudCcpO1xyXG4gICAgfVxyXG5cclxuICAgIGlmIChtZXRob2QgPT0gJ2VsZW1lbnQnKSB7XHJcbiAgICAgIHZhciBlbGVtZW50V2lkdGggPSAkZWxlbWVudC5vdXRlcldpZHRoKGZhbHNlKTtcclxuXHJcbiAgICAgIGlmIChlbGVtZW50V2lkdGggPD0gMCkge1xyXG4gICAgICAgIHJldHVybiAnYXV0byc7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIHJldHVybiBlbGVtZW50V2lkdGggKyAncHgnO1xyXG4gICAgfVxyXG5cclxuICAgIGlmIChtZXRob2QgPT0gJ3N0eWxlJykge1xyXG4gICAgICB2YXIgc3R5bGUgPSAkZWxlbWVudC5hdHRyKCdzdHlsZScpO1xyXG5cclxuICAgICAgaWYgKHR5cGVvZihzdHlsZSkgIT09ICdzdHJpbmcnKSB7XHJcbiAgICAgICAgcmV0dXJuIG51bGw7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIHZhciBhdHRycyA9IHN0eWxlLnNwbGl0KCc7Jyk7XHJcblxyXG4gICAgICBmb3IgKHZhciBpID0gMCwgbCA9IGF0dHJzLmxlbmd0aDsgaSA8IGw7IGkgPSBpICsgMSkge1xyXG4gICAgICAgIHZhciBhdHRyID0gYXR0cnNbaV0ucmVwbGFjZSgvXFxzL2csICcnKTtcclxuICAgICAgICB2YXIgbWF0Y2hlcyA9IGF0dHIubWF0Y2goV0lEVEgpO1xyXG5cclxuICAgICAgICBpZiAobWF0Y2hlcyAhPT0gbnVsbCAmJiBtYXRjaGVzLmxlbmd0aCA+PSAxKSB7XHJcbiAgICAgICAgICByZXR1cm4gbWF0Y2hlc1sxXTtcclxuICAgICAgICB9XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIHJldHVybiBudWxsO1xyXG4gICAgfVxyXG5cclxuICAgIHJldHVybiBtZXRob2Q7XHJcbiAgfTtcclxuXHJcbiAgU2VsZWN0Mi5wcm90b3R5cGUuX2JpbmRBZGFwdGVycyA9IGZ1bmN0aW9uICgpIHtcclxuICAgIHRoaXMuZGF0YUFkYXB0ZXIuYmluZCh0aGlzLCB0aGlzLiRjb250YWluZXIpO1xyXG4gICAgdGhpcy5zZWxlY3Rpb24uYmluZCh0aGlzLCB0aGlzLiRjb250YWluZXIpO1xyXG5cclxuICAgIHRoaXMuZHJvcGRvd24uYmluZCh0aGlzLCB0aGlzLiRjb250YWluZXIpO1xyXG4gICAgdGhpcy5yZXN1bHRzLmJpbmQodGhpcywgdGhpcy4kY29udGFpbmVyKTtcclxuICB9O1xyXG5cclxuICBTZWxlY3QyLnByb3RvdHlwZS5fcmVnaXN0ZXJEb21FdmVudHMgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICB2YXIgc2VsZiA9IHRoaXM7XHJcblxyXG4gICAgdGhpcy4kZWxlbWVudC5vbignY2hhbmdlLnNlbGVjdDInLCBmdW5jdGlvbiAoKSB7XHJcbiAgICAgIHNlbGYuZGF0YUFkYXB0ZXIuY3VycmVudChmdW5jdGlvbiAoZGF0YSkge1xyXG4gICAgICAgIHNlbGYudHJpZ2dlcignc2VsZWN0aW9uOnVwZGF0ZScsIHtcclxuICAgICAgICAgIGRhdGE6IGRhdGFcclxuICAgICAgICB9KTtcclxuICAgICAgfSk7XHJcbiAgICB9KTtcclxuXHJcbiAgICB0aGlzLiRlbGVtZW50Lm9uKCdmb2N1cy5zZWxlY3QyJywgZnVuY3Rpb24gKGV2dCkge1xyXG4gICAgICBzZWxmLnRyaWdnZXIoJ2ZvY3VzJywgZXZ0KTtcclxuICAgIH0pO1xyXG5cclxuICAgIHRoaXMuX3N5bmNBID0gVXRpbHMuYmluZCh0aGlzLl9zeW5jQXR0cmlidXRlcywgdGhpcyk7XHJcbiAgICB0aGlzLl9zeW5jUyA9IFV0aWxzLmJpbmQodGhpcy5fc3luY1N1YnRyZWUsIHRoaXMpO1xyXG5cclxuICAgIGlmICh0aGlzLiRlbGVtZW50WzBdLmF0dGFjaEV2ZW50KSB7XHJcbiAgICAgIHRoaXMuJGVsZW1lbnRbMF0uYXR0YWNoRXZlbnQoJ29ucHJvcGVydHljaGFuZ2UnLCB0aGlzLl9zeW5jQSk7XHJcbiAgICB9XHJcblxyXG4gICAgdmFyIG9ic2VydmVyID0gd2luZG93Lk11dGF0aW9uT2JzZXJ2ZXIgfHxcclxuICAgICAgd2luZG93LldlYktpdE11dGF0aW9uT2JzZXJ2ZXIgfHxcclxuICAgICAgd2luZG93Lk1vek11dGF0aW9uT2JzZXJ2ZXJcclxuICAgIDtcclxuXHJcbiAgICBpZiAob2JzZXJ2ZXIgIT0gbnVsbCkge1xyXG4gICAgICB0aGlzLl9vYnNlcnZlciA9IG5ldyBvYnNlcnZlcihmdW5jdGlvbiAobXV0YXRpb25zKSB7XHJcbiAgICAgICAgJC5lYWNoKG11dGF0aW9ucywgc2VsZi5fc3luY0EpO1xyXG4gICAgICAgICQuZWFjaChtdXRhdGlvbnMsIHNlbGYuX3N5bmNTKTtcclxuICAgICAgfSk7XHJcbiAgICAgIHRoaXMuX29ic2VydmVyLm9ic2VydmUodGhpcy4kZWxlbWVudFswXSwge1xyXG4gICAgICAgIGF0dHJpYnV0ZXM6IHRydWUsXHJcbiAgICAgICAgY2hpbGRMaXN0OiB0cnVlLFxyXG4gICAgICAgIHN1YnRyZWU6IGZhbHNlXHJcbiAgICAgIH0pO1xyXG4gICAgfSBlbHNlIGlmICh0aGlzLiRlbGVtZW50WzBdLmFkZEV2ZW50TGlzdGVuZXIpIHtcclxuICAgICAgdGhpcy4kZWxlbWVudFswXS5hZGRFdmVudExpc3RlbmVyKFxyXG4gICAgICAgICdET01BdHRyTW9kaWZpZWQnLFxyXG4gICAgICAgIHNlbGYuX3N5bmNBLFxyXG4gICAgICAgIGZhbHNlXHJcbiAgICAgICk7XHJcbiAgICAgIHRoaXMuJGVsZW1lbnRbMF0uYWRkRXZlbnRMaXN0ZW5lcihcclxuICAgICAgICAnRE9NTm9kZUluc2VydGVkJyxcclxuICAgICAgICBzZWxmLl9zeW5jUyxcclxuICAgICAgICBmYWxzZVxyXG4gICAgICApO1xyXG4gICAgICB0aGlzLiRlbGVtZW50WzBdLmFkZEV2ZW50TGlzdGVuZXIoXHJcbiAgICAgICAgJ0RPTU5vZGVSZW1vdmVkJyxcclxuICAgICAgICBzZWxmLl9zeW5jUyxcclxuICAgICAgICBmYWxzZVxyXG4gICAgICApO1xyXG4gICAgfVxyXG4gIH07XHJcblxyXG4gIFNlbGVjdDIucHJvdG90eXBlLl9yZWdpc3RlckRhdGFFdmVudHMgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICB2YXIgc2VsZiA9IHRoaXM7XHJcblxyXG4gICAgdGhpcy5kYXRhQWRhcHRlci5vbignKicsIGZ1bmN0aW9uIChuYW1lLCBwYXJhbXMpIHtcclxuICAgICAgc2VsZi50cmlnZ2VyKG5hbWUsIHBhcmFtcyk7XHJcbiAgICB9KTtcclxuICB9O1xyXG5cclxuICBTZWxlY3QyLnByb3RvdHlwZS5fcmVnaXN0ZXJTZWxlY3Rpb25FdmVudHMgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICB2YXIgc2VsZiA9IHRoaXM7XHJcbiAgICB2YXIgbm9uUmVsYXlFdmVudHMgPSBbJ3RvZ2dsZScsICdmb2N1cyddO1xyXG5cclxuICAgIHRoaXMuc2VsZWN0aW9uLm9uKCd0b2dnbGUnLCBmdW5jdGlvbiAoKSB7XHJcbiAgICAgIHNlbGYudG9nZ2xlRHJvcGRvd24oKTtcclxuICAgIH0pO1xyXG5cclxuICAgIHRoaXMuc2VsZWN0aW9uLm9uKCdmb2N1cycsIGZ1bmN0aW9uIChwYXJhbXMpIHtcclxuICAgICAgc2VsZi5mb2N1cyhwYXJhbXMpO1xyXG4gICAgfSk7XHJcblxyXG4gICAgdGhpcy5zZWxlY3Rpb24ub24oJyonLCBmdW5jdGlvbiAobmFtZSwgcGFyYW1zKSB7XHJcbiAgICAgIGlmICgkLmluQXJyYXkobmFtZSwgbm9uUmVsYXlFdmVudHMpICE9PSAtMSkge1xyXG4gICAgICAgIHJldHVybjtcclxuICAgICAgfVxyXG5cclxuICAgICAgc2VsZi50cmlnZ2VyKG5hbWUsIHBhcmFtcyk7XHJcbiAgICB9KTtcclxuICB9O1xyXG5cclxuICBTZWxlY3QyLnByb3RvdHlwZS5fcmVnaXN0ZXJEcm9wZG93bkV2ZW50cyA9IGZ1bmN0aW9uICgpIHtcclxuICAgIHZhciBzZWxmID0gdGhpcztcclxuXHJcbiAgICB0aGlzLmRyb3Bkb3duLm9uKCcqJywgZnVuY3Rpb24gKG5hbWUsIHBhcmFtcykge1xyXG4gICAgICBzZWxmLnRyaWdnZXIobmFtZSwgcGFyYW1zKTtcclxuICAgIH0pO1xyXG4gIH07XHJcblxyXG4gIFNlbGVjdDIucHJvdG90eXBlLl9yZWdpc3RlclJlc3VsdHNFdmVudHMgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICB2YXIgc2VsZiA9IHRoaXM7XHJcblxyXG4gICAgdGhpcy5yZXN1bHRzLm9uKCcqJywgZnVuY3Rpb24gKG5hbWUsIHBhcmFtcykge1xyXG4gICAgICBzZWxmLnRyaWdnZXIobmFtZSwgcGFyYW1zKTtcclxuICAgIH0pO1xyXG4gIH07XHJcblxyXG4gIFNlbGVjdDIucHJvdG90eXBlLl9yZWdpc3RlckV2ZW50cyA9IGZ1bmN0aW9uICgpIHtcclxuICAgIHZhciBzZWxmID0gdGhpcztcclxuXHJcbiAgICB0aGlzLm9uKCdvcGVuJywgZnVuY3Rpb24gKCkge1xyXG4gICAgICBzZWxmLiRjb250YWluZXIuYWRkQ2xhc3MoJ3NlbGVjdDItY29udGFpbmVyLS1vcGVuJyk7XHJcbiAgICB9KTtcclxuXHJcbiAgICB0aGlzLm9uKCdjbG9zZScsIGZ1bmN0aW9uICgpIHtcclxuICAgICAgc2VsZi4kY29udGFpbmVyLnJlbW92ZUNsYXNzKCdzZWxlY3QyLWNvbnRhaW5lci0tb3BlbicpO1xyXG4gICAgfSk7XHJcblxyXG4gICAgdGhpcy5vbignZW5hYmxlJywgZnVuY3Rpb24gKCkge1xyXG4gICAgICBzZWxmLiRjb250YWluZXIucmVtb3ZlQ2xhc3MoJ3NlbGVjdDItY29udGFpbmVyLS1kaXNhYmxlZCcpO1xyXG4gICAgfSk7XHJcblxyXG4gICAgdGhpcy5vbignZGlzYWJsZScsIGZ1bmN0aW9uICgpIHtcclxuICAgICAgc2VsZi4kY29udGFpbmVyLmFkZENsYXNzKCdzZWxlY3QyLWNvbnRhaW5lci0tZGlzYWJsZWQnKTtcclxuICAgIH0pO1xyXG5cclxuICAgIHRoaXMub24oJ2JsdXInLCBmdW5jdGlvbiAoKSB7XHJcbiAgICAgIHNlbGYuJGNvbnRhaW5lci5yZW1vdmVDbGFzcygnc2VsZWN0Mi1jb250YWluZXItLWZvY3VzJyk7XHJcbiAgICB9KTtcclxuXHJcbiAgICB0aGlzLm9uKCdxdWVyeScsIGZ1bmN0aW9uIChwYXJhbXMpIHtcclxuICAgICAgaWYgKCFzZWxmLmlzT3BlbigpKSB7XHJcbiAgICAgICAgc2VsZi50cmlnZ2VyKCdvcGVuJywge30pO1xyXG4gICAgICB9XHJcblxyXG4gICAgICB0aGlzLmRhdGFBZGFwdGVyLnF1ZXJ5KHBhcmFtcywgZnVuY3Rpb24gKGRhdGEpIHtcclxuICAgICAgICBzZWxmLnRyaWdnZXIoJ3Jlc3VsdHM6YWxsJywge1xyXG4gICAgICAgICAgZGF0YTogZGF0YSxcclxuICAgICAgICAgIHF1ZXJ5OiBwYXJhbXNcclxuICAgICAgICB9KTtcclxuICAgICAgfSk7XHJcbiAgICB9KTtcclxuXHJcbiAgICB0aGlzLm9uKCdxdWVyeTphcHBlbmQnLCBmdW5jdGlvbiAocGFyYW1zKSB7XHJcbiAgICAgIHRoaXMuZGF0YUFkYXB0ZXIucXVlcnkocGFyYW1zLCBmdW5jdGlvbiAoZGF0YSkge1xyXG4gICAgICAgIHNlbGYudHJpZ2dlcigncmVzdWx0czphcHBlbmQnLCB7XHJcbiAgICAgICAgICBkYXRhOiBkYXRhLFxyXG4gICAgICAgICAgcXVlcnk6IHBhcmFtc1xyXG4gICAgICAgIH0pO1xyXG4gICAgICB9KTtcclxuICAgIH0pO1xyXG5cclxuICAgIHRoaXMub24oJ2tleXByZXNzJywgZnVuY3Rpb24gKGV2dCkge1xyXG4gICAgICB2YXIga2V5ID0gZXZ0LndoaWNoO1xyXG5cclxuICAgICAgaWYgKHNlbGYuaXNPcGVuKCkpIHtcclxuICAgICAgICBpZiAoa2V5ID09PSBLRVlTLkVTQyB8fCBrZXkgPT09IEtFWVMuVEFCIHx8XHJcbiAgICAgICAgICAgIChrZXkgPT09IEtFWVMuVVAgJiYgZXZ0LmFsdEtleSkpIHtcclxuICAgICAgICAgIHNlbGYuY2xvc2UoKTtcclxuXHJcbiAgICAgICAgICBldnQucHJldmVudERlZmF1bHQoKTtcclxuICAgICAgICB9IGVsc2UgaWYgKGtleSA9PT0gS0VZUy5FTlRFUikge1xyXG4gICAgICAgICAgc2VsZi50cmlnZ2VyKCdyZXN1bHRzOnNlbGVjdCcsIHt9KTtcclxuXHJcbiAgICAgICAgICBldnQucHJldmVudERlZmF1bHQoKTtcclxuICAgICAgICB9IGVsc2UgaWYgKChrZXkgPT09IEtFWVMuU1BBQ0UgJiYgZXZ0LmN0cmxLZXkpKSB7XHJcbiAgICAgICAgICBzZWxmLnRyaWdnZXIoJ3Jlc3VsdHM6dG9nZ2xlJywge30pO1xyXG5cclxuICAgICAgICAgIGV2dC5wcmV2ZW50RGVmYXVsdCgpO1xyXG4gICAgICAgIH0gZWxzZSBpZiAoa2V5ID09PSBLRVlTLlVQKSB7XHJcbiAgICAgICAgICBzZWxmLnRyaWdnZXIoJ3Jlc3VsdHM6cHJldmlvdXMnLCB7fSk7XHJcblxyXG4gICAgICAgICAgZXZ0LnByZXZlbnREZWZhdWx0KCk7XHJcbiAgICAgICAgfSBlbHNlIGlmIChrZXkgPT09IEtFWVMuRE9XTikge1xyXG4gICAgICAgICAgc2VsZi50cmlnZ2VyKCdyZXN1bHRzOm5leHQnLCB7fSk7XHJcblxyXG4gICAgICAgICAgZXZ0LnByZXZlbnREZWZhdWx0KCk7XHJcbiAgICAgICAgfVxyXG4gICAgICB9IGVsc2Uge1xyXG4gICAgICAgIGlmIChrZXkgPT09IEtFWVMuRU5URVIgfHwga2V5ID09PSBLRVlTLlNQQUNFIHx8XHJcbiAgICAgICAgICAgIChrZXkgPT09IEtFWVMuRE9XTiAmJiBldnQuYWx0S2V5KSkge1xyXG4gICAgICAgICAgc2VsZi5vcGVuKCk7XHJcblxyXG4gICAgICAgICAgZXZ0LnByZXZlbnREZWZhdWx0KCk7XHJcbiAgICAgICAgfVxyXG4gICAgICB9XHJcbiAgICB9KTtcclxuICB9O1xyXG5cclxuICBTZWxlY3QyLnByb3RvdHlwZS5fc3luY0F0dHJpYnV0ZXMgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICB0aGlzLm9wdGlvbnMuc2V0KCdkaXNhYmxlZCcsIHRoaXMuJGVsZW1lbnQucHJvcCgnZGlzYWJsZWQnKSk7XHJcblxyXG4gICAgaWYgKHRoaXMub3B0aW9ucy5nZXQoJ2Rpc2FibGVkJykpIHtcclxuICAgICAgaWYgKHRoaXMuaXNPcGVuKCkpIHtcclxuICAgICAgICB0aGlzLmNsb3NlKCk7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIHRoaXMudHJpZ2dlcignZGlzYWJsZScsIHt9KTtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIHRoaXMudHJpZ2dlcignZW5hYmxlJywge30pO1xyXG4gICAgfVxyXG4gIH07XHJcblxyXG4gIFNlbGVjdDIucHJvdG90eXBlLl9zeW5jU3VidHJlZSA9IGZ1bmN0aW9uIChldnQsIG11dGF0aW9ucykge1xyXG4gICAgdmFyIGNoYW5nZWQgPSBmYWxzZTtcclxuICAgIHZhciBzZWxmID0gdGhpcztcclxuXHJcbiAgICAvLyBJZ25vcmUgYW55IG11dGF0aW9uIGV2ZW50cyByYWlzZWQgZm9yIGVsZW1lbnRzIHRoYXQgYXJlbid0IG9wdGlvbnMgb3JcclxuICAgIC8vIG9wdGdyb3Vwcy4gVGhpcyBoYW5kbGVzIHRoZSBjYXNlIHdoZW4gdGhlIHNlbGVjdCBlbGVtZW50IGlzIGRlc3Ryb3llZFxyXG4gICAgaWYgKFxyXG4gICAgICBldnQgJiYgZXZ0LnRhcmdldCAmJiAoXHJcbiAgICAgICAgZXZ0LnRhcmdldC5ub2RlTmFtZSAhPT0gJ09QVElPTicgJiYgZXZ0LnRhcmdldC5ub2RlTmFtZSAhPT0gJ09QVEdST1VQJ1xyXG4gICAgICApXHJcbiAgICApIHtcclxuICAgICAgcmV0dXJuO1xyXG4gICAgfVxyXG5cclxuICAgIGlmICghbXV0YXRpb25zKSB7XHJcbiAgICAgIC8vIElmIG11dGF0aW9uIGV2ZW50cyBhcmVuJ3Qgc3VwcG9ydGVkLCB0aGVuIHdlIGNhbiBvbmx5IGFzc3VtZSB0aGF0IHRoZVxyXG4gICAgICAvLyBjaGFuZ2UgYWZmZWN0ZWQgdGhlIHNlbGVjdGlvbnNcclxuICAgICAgY2hhbmdlZCA9IHRydWU7XHJcbiAgICB9IGVsc2UgaWYgKG11dGF0aW9ucy5hZGRlZE5vZGVzICYmIG11dGF0aW9ucy5hZGRlZE5vZGVzLmxlbmd0aCA+IDApIHtcclxuICAgICAgZm9yICh2YXIgbiA9IDA7IG4gPCBtdXRhdGlvbnMuYWRkZWROb2Rlcy5sZW5ndGg7IG4rKykge1xyXG4gICAgICAgIHZhciBub2RlID0gbXV0YXRpb25zLmFkZGVkTm9kZXNbbl07XHJcblxyXG4gICAgICAgIGlmIChub2RlLnNlbGVjdGVkKSB7XHJcbiAgICAgICAgICBjaGFuZ2VkID0gdHJ1ZTtcclxuICAgICAgICB9XHJcbiAgICAgIH1cclxuICAgIH0gZWxzZSBpZiAobXV0YXRpb25zLnJlbW92ZWROb2RlcyAmJiBtdXRhdGlvbnMucmVtb3ZlZE5vZGVzLmxlbmd0aCA+IDApIHtcclxuICAgICAgY2hhbmdlZCA9IHRydWU7XHJcbiAgICB9XHJcblxyXG4gICAgLy8gT25seSByZS1wdWxsIHRoZSBkYXRhIGlmIHdlIHRoaW5rIHRoZXJlIGlzIGEgY2hhbmdlXHJcbiAgICBpZiAoY2hhbmdlZCkge1xyXG4gICAgICB0aGlzLmRhdGFBZGFwdGVyLmN1cnJlbnQoZnVuY3Rpb24gKGN1cnJlbnREYXRhKSB7XHJcbiAgICAgICAgc2VsZi50cmlnZ2VyKCdzZWxlY3Rpb246dXBkYXRlJywge1xyXG4gICAgICAgICAgZGF0YTogY3VycmVudERhdGFcclxuICAgICAgICB9KTtcclxuICAgICAgfSk7XHJcbiAgICB9XHJcbiAgfTtcclxuXHJcbiAgLyoqXHJcbiAgICogT3ZlcnJpZGUgdGhlIHRyaWdnZXIgbWV0aG9kIHRvIGF1dG9tYXRpY2FsbHkgdHJpZ2dlciBwcmUtZXZlbnRzIHdoZW5cclxuICAgKiB0aGVyZSBhcmUgZXZlbnRzIHRoYXQgY2FuIGJlIHByZXZlbnRlZC5cclxuICAgKi9cclxuICBTZWxlY3QyLnByb3RvdHlwZS50cmlnZ2VyID0gZnVuY3Rpb24gKG5hbWUsIGFyZ3MpIHtcclxuICAgIHZhciBhY3R1YWxUcmlnZ2VyID0gU2VsZWN0Mi5fX3N1cGVyX18udHJpZ2dlcjtcclxuICAgIHZhciBwcmVUcmlnZ2VyTWFwID0ge1xyXG4gICAgICAnb3Blbic6ICdvcGVuaW5nJyxcclxuICAgICAgJ2Nsb3NlJzogJ2Nsb3NpbmcnLFxyXG4gICAgICAnc2VsZWN0JzogJ3NlbGVjdGluZycsXHJcbiAgICAgICd1bnNlbGVjdCc6ICd1bnNlbGVjdGluZydcclxuICAgIH07XHJcblxyXG4gICAgaWYgKGFyZ3MgPT09IHVuZGVmaW5lZCkge1xyXG4gICAgICBhcmdzID0ge307XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKG5hbWUgaW4gcHJlVHJpZ2dlck1hcCkge1xyXG4gICAgICB2YXIgcHJlVHJpZ2dlck5hbWUgPSBwcmVUcmlnZ2VyTWFwW25hbWVdO1xyXG4gICAgICB2YXIgcHJlVHJpZ2dlckFyZ3MgPSB7XHJcbiAgICAgICAgcHJldmVudGVkOiBmYWxzZSxcclxuICAgICAgICBuYW1lOiBuYW1lLFxyXG4gICAgICAgIGFyZ3M6IGFyZ3NcclxuICAgICAgfTtcclxuXHJcbiAgICAgIGFjdHVhbFRyaWdnZXIuY2FsbCh0aGlzLCBwcmVUcmlnZ2VyTmFtZSwgcHJlVHJpZ2dlckFyZ3MpO1xyXG5cclxuICAgICAgaWYgKHByZVRyaWdnZXJBcmdzLnByZXZlbnRlZCkge1xyXG4gICAgICAgIGFyZ3MucHJldmVudGVkID0gdHJ1ZTtcclxuXHJcbiAgICAgICAgcmV0dXJuO1xyXG4gICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgYWN0dWFsVHJpZ2dlci5jYWxsKHRoaXMsIG5hbWUsIGFyZ3MpO1xyXG4gIH07XHJcblxyXG4gIFNlbGVjdDIucHJvdG90eXBlLnRvZ2dsZURyb3Bkb3duID0gZnVuY3Rpb24gKCkge1xyXG4gICAgaWYgKHRoaXMub3B0aW9ucy5nZXQoJ2Rpc2FibGVkJykpIHtcclxuICAgICAgcmV0dXJuO1xyXG4gICAgfVxyXG5cclxuICAgIGlmICh0aGlzLmlzT3BlbigpKSB7XHJcbiAgICAgIHRoaXMuY2xvc2UoKTtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIHRoaXMub3BlbigpO1xyXG4gICAgfVxyXG4gIH07XHJcblxyXG4gIFNlbGVjdDIucHJvdG90eXBlLm9wZW4gPSBmdW5jdGlvbiAoKSB7XHJcbiAgICBpZiAodGhpcy5pc09wZW4oKSkge1xyXG4gICAgICByZXR1cm47XHJcbiAgICB9XHJcblxyXG4gICAgdGhpcy50cmlnZ2VyKCdxdWVyeScsIHt9KTtcclxuICB9O1xyXG5cclxuICBTZWxlY3QyLnByb3RvdHlwZS5jbG9zZSA9IGZ1bmN0aW9uICgpIHtcclxuICAgIGlmICghdGhpcy5pc09wZW4oKSkge1xyXG4gICAgICByZXR1cm47XHJcbiAgICB9XHJcblxyXG4gICAgdGhpcy50cmlnZ2VyKCdjbG9zZScsIHt9KTtcclxuICB9O1xyXG5cclxuICBTZWxlY3QyLnByb3RvdHlwZS5pc09wZW4gPSBmdW5jdGlvbiAoKSB7XHJcbiAgICByZXR1cm4gdGhpcy4kY29udGFpbmVyLmhhc0NsYXNzKCdzZWxlY3QyLWNvbnRhaW5lci0tb3BlbicpO1xyXG4gIH07XHJcblxyXG4gIFNlbGVjdDIucHJvdG90eXBlLmhhc0ZvY3VzID0gZnVuY3Rpb24gKCkge1xyXG4gICAgcmV0dXJuIHRoaXMuJGNvbnRhaW5lci5oYXNDbGFzcygnc2VsZWN0Mi1jb250YWluZXItLWZvY3VzJyk7XHJcbiAgfTtcclxuXHJcbiAgU2VsZWN0Mi5wcm90b3R5cGUuZm9jdXMgPSBmdW5jdGlvbiAoZGF0YSkge1xyXG4gICAgLy8gTm8gbmVlZCB0byByZS10cmlnZ2VyIGZvY3VzIGV2ZW50cyBpZiB3ZSBhcmUgYWxyZWFkeSBmb2N1c2VkXHJcbiAgICBpZiAodGhpcy5oYXNGb2N1cygpKSB7XHJcbiAgICAgIHJldHVybjtcclxuICAgIH1cclxuXHJcbiAgICB0aGlzLiRjb250YWluZXIuYWRkQ2xhc3MoJ3NlbGVjdDItY29udGFpbmVyLS1mb2N1cycpO1xyXG4gICAgdGhpcy50cmlnZ2VyKCdmb2N1cycsIHt9KTtcclxuICB9O1xyXG5cclxuICBTZWxlY3QyLnByb3RvdHlwZS5lbmFibGUgPSBmdW5jdGlvbiAoYXJncykge1xyXG4gICAgaWYgKHRoaXMub3B0aW9ucy5nZXQoJ2RlYnVnJykgJiYgd2luZG93LmNvbnNvbGUgJiYgY29uc29sZS53YXJuKSB7XHJcbiAgICAgIGNvbnNvbGUud2FybihcclxuICAgICAgICAnU2VsZWN0MjogVGhlIGBzZWxlY3QyKFwiZW5hYmxlXCIpYCBtZXRob2QgaGFzIGJlZW4gZGVwcmVjYXRlZCBhbmQgd2lsbCcgK1xyXG4gICAgICAgICcgYmUgcmVtb3ZlZCBpbiBsYXRlciBTZWxlY3QyIHZlcnNpb25zLiBVc2UgJGVsZW1lbnQucHJvcChcImRpc2FibGVkXCIpJyArXHJcbiAgICAgICAgJyBpbnN0ZWFkLidcclxuICAgICAgKTtcclxuICAgIH1cclxuXHJcbiAgICBpZiAoYXJncyA9PSBudWxsIHx8IGFyZ3MubGVuZ3RoID09PSAwKSB7XHJcbiAgICAgIGFyZ3MgPSBbdHJ1ZV07XHJcbiAgICB9XHJcblxyXG4gICAgdmFyIGRpc2FibGVkID0gIWFyZ3NbMF07XHJcblxyXG4gICAgdGhpcy4kZWxlbWVudC5wcm9wKCdkaXNhYmxlZCcsIGRpc2FibGVkKTtcclxuICB9O1xyXG5cclxuICBTZWxlY3QyLnByb3RvdHlwZS5kYXRhID0gZnVuY3Rpb24gKCkge1xyXG4gICAgaWYgKHRoaXMub3B0aW9ucy5nZXQoJ2RlYnVnJykgJiZcclxuICAgICAgICBhcmd1bWVudHMubGVuZ3RoID4gMCAmJiB3aW5kb3cuY29uc29sZSAmJiBjb25zb2xlLndhcm4pIHtcclxuICAgICAgY29uc29sZS53YXJuKFxyXG4gICAgICAgICdTZWxlY3QyOiBEYXRhIGNhbiBubyBsb25nZXIgYmUgc2V0IHVzaW5nIGBzZWxlY3QyKFwiZGF0YVwiKWAuIFlvdSAnICtcclxuICAgICAgICAnc2hvdWxkIGNvbnNpZGVyIHNldHRpbmcgdGhlIHZhbHVlIGluc3RlYWQgdXNpbmcgYCRlbGVtZW50LnZhbCgpYC4nXHJcbiAgICAgICk7XHJcbiAgICB9XHJcblxyXG4gICAgdmFyIGRhdGEgPSBbXTtcclxuXHJcbiAgICB0aGlzLmRhdGFBZGFwdGVyLmN1cnJlbnQoZnVuY3Rpb24gKGN1cnJlbnREYXRhKSB7XHJcbiAgICAgIGRhdGEgPSBjdXJyZW50RGF0YTtcclxuICAgIH0pO1xyXG5cclxuICAgIHJldHVybiBkYXRhO1xyXG4gIH07XHJcblxyXG4gIFNlbGVjdDIucHJvdG90eXBlLnZhbCA9IGZ1bmN0aW9uIChhcmdzKSB7XHJcbiAgICBpZiAodGhpcy5vcHRpb25zLmdldCgnZGVidWcnKSAmJiB3aW5kb3cuY29uc29sZSAmJiBjb25zb2xlLndhcm4pIHtcclxuICAgICAgY29uc29sZS53YXJuKFxyXG4gICAgICAgICdTZWxlY3QyOiBUaGUgYHNlbGVjdDIoXCJ2YWxcIilgIG1ldGhvZCBoYXMgYmVlbiBkZXByZWNhdGVkIGFuZCB3aWxsIGJlJyArXHJcbiAgICAgICAgJyByZW1vdmVkIGluIGxhdGVyIFNlbGVjdDIgdmVyc2lvbnMuIFVzZSAkZWxlbWVudC52YWwoKSBpbnN0ZWFkLidcclxuICAgICAgKTtcclxuICAgIH1cclxuXHJcbiAgICBpZiAoYXJncyA9PSBudWxsIHx8IGFyZ3MubGVuZ3RoID09PSAwKSB7XHJcbiAgICAgIHJldHVybiB0aGlzLiRlbGVtZW50LnZhbCgpO1xyXG4gICAgfVxyXG5cclxuICAgIHZhciBuZXdWYWwgPSBhcmdzWzBdO1xyXG5cclxuICAgIGlmICgkLmlzQXJyYXkobmV3VmFsKSkge1xyXG4gICAgICBuZXdWYWwgPSAkLm1hcChuZXdWYWwsIGZ1bmN0aW9uIChvYmopIHtcclxuICAgICAgICByZXR1cm4gb2JqLnRvU3RyaW5nKCk7XHJcbiAgICAgIH0pO1xyXG4gICAgfVxyXG5cclxuICAgIHRoaXMuJGVsZW1lbnQudmFsKG5ld1ZhbCkudHJpZ2dlcignY2hhbmdlJyk7XHJcbiAgfTtcclxuXHJcbiAgU2VsZWN0Mi5wcm90b3R5cGUuZGVzdHJveSA9IGZ1bmN0aW9uICgpIHtcclxuICAgIHRoaXMuJGNvbnRhaW5lci5yZW1vdmUoKTtcclxuXHJcbiAgICBpZiAodGhpcy4kZWxlbWVudFswXS5kZXRhY2hFdmVudCkge1xyXG4gICAgICB0aGlzLiRlbGVtZW50WzBdLmRldGFjaEV2ZW50KCdvbnByb3BlcnR5Y2hhbmdlJywgdGhpcy5fc3luY0EpO1xyXG4gICAgfVxyXG5cclxuICAgIGlmICh0aGlzLl9vYnNlcnZlciAhPSBudWxsKSB7XHJcbiAgICAgIHRoaXMuX29ic2VydmVyLmRpc2Nvbm5lY3QoKTtcclxuICAgICAgdGhpcy5fb2JzZXJ2ZXIgPSBudWxsO1xyXG4gICAgfSBlbHNlIGlmICh0aGlzLiRlbGVtZW50WzBdLnJlbW92ZUV2ZW50TGlzdGVuZXIpIHtcclxuICAgICAgdGhpcy4kZWxlbWVudFswXVxyXG4gICAgICAgIC5yZW1vdmVFdmVudExpc3RlbmVyKCdET01BdHRyTW9kaWZpZWQnLCB0aGlzLl9zeW5jQSwgZmFsc2UpO1xyXG4gICAgICB0aGlzLiRlbGVtZW50WzBdXHJcbiAgICAgICAgLnJlbW92ZUV2ZW50TGlzdGVuZXIoJ0RPTU5vZGVJbnNlcnRlZCcsIHRoaXMuX3N5bmNTLCBmYWxzZSk7XHJcbiAgICAgIHRoaXMuJGVsZW1lbnRbMF1cclxuICAgICAgICAucmVtb3ZlRXZlbnRMaXN0ZW5lcignRE9NTm9kZVJlbW92ZWQnLCB0aGlzLl9zeW5jUywgZmFsc2UpO1xyXG4gICAgfVxyXG5cclxuICAgIHRoaXMuX3N5bmNBID0gbnVsbDtcclxuICAgIHRoaXMuX3N5bmNTID0gbnVsbDtcclxuXHJcbiAgICB0aGlzLiRlbGVtZW50Lm9mZignLnNlbGVjdDInKTtcclxuICAgIHRoaXMuJGVsZW1lbnQuYXR0cigndGFiaW5kZXgnLCB0aGlzLiRlbGVtZW50LmRhdGEoJ29sZC10YWJpbmRleCcpKTtcclxuXHJcbiAgICB0aGlzLiRlbGVtZW50LnJlbW92ZUNsYXNzKCdzZWxlY3QyLWhpZGRlbi1hY2Nlc3NpYmxlJyk7XHJcbiAgICB0aGlzLiRlbGVtZW50LmF0dHIoJ2FyaWEtaGlkZGVuJywgJ2ZhbHNlJyk7XHJcbiAgICB0aGlzLiRlbGVtZW50LnJlbW92ZURhdGEoJ3NlbGVjdDInKTtcclxuXHJcbiAgICB0aGlzLmRhdGFBZGFwdGVyLmRlc3Ryb3koKTtcclxuICAgIHRoaXMuc2VsZWN0aW9uLmRlc3Ryb3koKTtcclxuICAgIHRoaXMuZHJvcGRvd24uZGVzdHJveSgpO1xyXG4gICAgdGhpcy5yZXN1bHRzLmRlc3Ryb3koKTtcclxuXHJcbiAgICB0aGlzLmRhdGFBZGFwdGVyID0gbnVsbDtcclxuICAgIHRoaXMuc2VsZWN0aW9uID0gbnVsbDtcclxuICAgIHRoaXMuZHJvcGRvd24gPSBudWxsO1xyXG4gICAgdGhpcy5yZXN1bHRzID0gbnVsbDtcclxuICB9O1xyXG5cclxuICBTZWxlY3QyLnByb3RvdHlwZS5yZW5kZXIgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICB2YXIgJGNvbnRhaW5lciA9ICQoXHJcbiAgICAgICc8c3BhbiBjbGFzcz1cInNlbGVjdDIgc2VsZWN0Mi1jb250YWluZXJcIj4nICtcclxuICAgICAgICAnPHNwYW4gY2xhc3M9XCJzZWxlY3Rpb25cIj48L3NwYW4+JyArXHJcbiAgICAgICAgJzxzcGFuIGNsYXNzPVwiZHJvcGRvd24td3JhcHBlclwiIGFyaWEtaGlkZGVuPVwidHJ1ZVwiPjwvc3Bhbj4nICtcclxuICAgICAgJzwvc3Bhbj4nXHJcbiAgICApO1xyXG5cclxuICAgICRjb250YWluZXIuYXR0cignZGlyJywgdGhpcy5vcHRpb25zLmdldCgnZGlyJykpO1xyXG5cclxuICAgIHRoaXMuJGNvbnRhaW5lciA9ICRjb250YWluZXI7XHJcblxyXG4gICAgdGhpcy4kY29udGFpbmVyLmFkZENsYXNzKCdzZWxlY3QyLWNvbnRhaW5lci0tJyArIHRoaXMub3B0aW9ucy5nZXQoJ3RoZW1lJykpO1xyXG5cclxuICAgICRjb250YWluZXIuZGF0YSgnZWxlbWVudCcsIHRoaXMuJGVsZW1lbnQpO1xyXG5cclxuICAgIHJldHVybiAkY29udGFpbmVyO1xyXG4gIH07XHJcblxyXG4gIHJldHVybiBTZWxlY3QyO1xyXG59KTtcclxuXG5TMi5kZWZpbmUoJ2pxdWVyeS1tb3VzZXdoZWVsJyxbXHJcbiAgJ2pxdWVyeSdcclxuXSwgZnVuY3Rpb24gKCQpIHtcclxuICAvLyBVc2VkIHRvIHNoaW0galF1ZXJ5Lm1vdXNld2hlZWwgZm9yIG5vbi1mdWxsIGJ1aWxkcy5cclxuICByZXR1cm4gJDtcclxufSk7XHJcblxuUzIuZGVmaW5lKCdqcXVlcnkuc2VsZWN0MicsW1xyXG4gICdqcXVlcnknLFxyXG4gICdqcXVlcnktbW91c2V3aGVlbCcsXHJcblxyXG4gICcuL3NlbGVjdDIvY29yZScsXHJcbiAgJy4vc2VsZWN0Mi9kZWZhdWx0cydcclxuXSwgZnVuY3Rpb24gKCQsIF8sIFNlbGVjdDIsIERlZmF1bHRzKSB7XHJcbiAgaWYgKCQuZm4uc2VsZWN0MiA9PSBudWxsKSB7XHJcbiAgICAvLyBBbGwgbWV0aG9kcyB0aGF0IHNob3VsZCByZXR1cm4gdGhlIGVsZW1lbnRcclxuICAgIHZhciB0aGlzTWV0aG9kcyA9IFsnb3BlbicsICdjbG9zZScsICdkZXN0cm95J107XHJcblxyXG4gICAgJC5mbi5zZWxlY3QyID0gZnVuY3Rpb24gKG9wdGlvbnMpIHtcclxuICAgICAgb3B0aW9ucyA9IG9wdGlvbnMgfHwge307XHJcblxyXG4gICAgICBpZiAodHlwZW9mIG9wdGlvbnMgPT09ICdvYmplY3QnKSB7XHJcbiAgICAgICAgdGhpcy5lYWNoKGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgIHZhciBpbnN0YW5jZU9wdGlvbnMgPSAkLmV4dGVuZCh0cnVlLCB7fSwgb3B0aW9ucyk7XHJcblxyXG4gICAgICAgICAgdmFyIGluc3RhbmNlID0gbmV3IFNlbGVjdDIoJCh0aGlzKSwgaW5zdGFuY2VPcHRpb25zKTtcclxuICAgICAgICB9KTtcclxuXHJcbiAgICAgICAgcmV0dXJuIHRoaXM7XHJcbiAgICAgIH0gZWxzZSBpZiAodHlwZW9mIG9wdGlvbnMgPT09ICdzdHJpbmcnKSB7XHJcbiAgICAgICAgdmFyIHJldDtcclxuICAgICAgICB2YXIgYXJncyA9IEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cywgMSk7XHJcblxyXG4gICAgICAgIHRoaXMuZWFjaChmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICB2YXIgaW5zdGFuY2UgPSAkKHRoaXMpLmRhdGEoJ3NlbGVjdDInKTtcclxuXHJcbiAgICAgICAgICBpZiAoaW5zdGFuY2UgPT0gbnVsbCAmJiB3aW5kb3cuY29uc29sZSAmJiBjb25zb2xlLmVycm9yKSB7XHJcbiAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoXHJcbiAgICAgICAgICAgICAgJ1RoZSBzZWxlY3QyKFxcJycgKyBvcHRpb25zICsgJ1xcJykgbWV0aG9kIHdhcyBjYWxsZWQgb24gYW4gJyArXHJcbiAgICAgICAgICAgICAgJ2VsZW1lbnQgdGhhdCBpcyBub3QgdXNpbmcgU2VsZWN0Mi4nXHJcbiAgICAgICAgICAgICk7XHJcbiAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgcmV0ID0gaW5zdGFuY2Vbb3B0aW9uc10uYXBwbHkoaW5zdGFuY2UsIGFyZ3MpO1xyXG4gICAgICAgIH0pO1xyXG5cclxuICAgICAgICAvLyBDaGVjayBpZiB3ZSBzaG91bGQgYmUgcmV0dXJuaW5nIGB0aGlzYFxyXG4gICAgICAgIGlmICgkLmluQXJyYXkob3B0aW9ucywgdGhpc01ldGhvZHMpID4gLTEpIHtcclxuICAgICAgICAgIHJldHVybiB0aGlzO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgcmV0dXJuIHJldDtcclxuICAgICAgfSBlbHNlIHtcclxuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgYXJndW1lbnRzIGZvciBTZWxlY3QyOiAnICsgb3B0aW9ucyk7XHJcbiAgICAgIH1cclxuICAgIH07XHJcbiAgfVxyXG5cclxuICBpZiAoJC5mbi5zZWxlY3QyLmRlZmF1bHRzID09IG51bGwpIHtcclxuICAgICQuZm4uc2VsZWN0Mi5kZWZhdWx0cyA9IERlZmF1bHRzO1xyXG4gIH1cclxuXHJcbiAgcmV0dXJuIFNlbGVjdDI7XHJcbn0pO1xyXG5cbiAgLy8gUmV0dXJuIHRoZSBBTUQgbG9hZGVyIGNvbmZpZ3VyYXRpb24gc28gaXQgY2FuIGJlIHVzZWQgb3V0c2lkZSBvZiB0aGlzIGZpbGVcclxuICByZXR1cm4ge1xyXG4gICAgZGVmaW5lOiBTMi5kZWZpbmUsXHJcbiAgICByZXF1aXJlOiBTMi5yZXF1aXJlXHJcbiAgfTtcclxufSgpKTtcclxuXHJcbiAgLy8gQXV0b2xvYWQgdGhlIGpRdWVyeSBiaW5kaW5nc1xyXG4gIC8vIFdlIGtub3cgdGhhdCBhbGwgb2YgdGhlIG1vZHVsZXMgZXhpc3QgYWJvdmUgdGhpcywgc28gd2UncmUgc2FmZVxyXG4gIHZhciBzZWxlY3QyID0gUzIucmVxdWlyZSgnanF1ZXJ5LnNlbGVjdDInKTtcclxuXHJcbiAgLy8gSG9sZCB0aGUgQU1EIG1vZHVsZSByZWZlcmVuY2VzIG9uIHRoZSBqUXVlcnkgZnVuY3Rpb24gdGhhdCB3YXMganVzdCBsb2FkZWRcclxuICAvLyBUaGlzIGFsbG93cyBTZWxlY3QyIHRvIHVzZSB0aGUgaW50ZXJuYWwgbG9hZGVyIG91dHNpZGUgb2YgdGhpcyBmaWxlLCBzdWNoXHJcbiAgLy8gYXMgaW4gdGhlIGxhbmd1YWdlIGZpbGVzLlxyXG4gIGpRdWVyeS5mbi5zZWxlY3QyLmFtZCA9IFMyO1xyXG5cclxuICAvLyBSZXR1cm4gdGhlIFNlbGVjdDIgaW5zdGFuY2UgZm9yIGFueW9uZSB3aG8gaXMgaW1wb3J0aW5nIGl0LlxyXG4gIHJldHVybiBzZWxlY3QyO1xyXG59KSk7XHJcblxuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIC4vbm9kZV9tb2R1bGVzL3NlbGVjdDIvZGlzdC9qcy9zZWxlY3QyLmpzXG4vLyBtb2R1bGUgaWQgPSA1NlxuLy8gbW9kdWxlIGNodW5rcyA9IDAiLCJtb2R1bGUuZXhwb3J0cz17cmVuZGVyOmZ1bmN0aW9uICgpe3ZhciBfdm09dGhpczt2YXIgX2g9X3ZtLiRjcmVhdGVFbGVtZW50O3ZhciBfYz1fdm0uX3NlbGYuX2N8fF9oO1xuICByZXR1cm4gX2MoJ3NlbGVjdCcsIHtcbiAgICBzdGF0aWNTdHlsZToge1xuICAgICAgXCJ3aWR0aFwiOiBcIjEwMCVcIlxuICAgIH1cbiAgfSwgW192bS5fdChcImRlZmF1bHRcIildLCAyKVxufSxzdGF0aWNSZW5kZXJGbnM6IFtdfVxubW9kdWxlLmV4cG9ydHMucmVuZGVyLl93aXRoU3RyaXBwZWQgPSB0cnVlXG5pZiAobW9kdWxlLmhvdCkge1xuICBtb2R1bGUuaG90LmFjY2VwdCgpXG4gIGlmIChtb2R1bGUuaG90LmRhdGEpIHtcbiAgICAgcmVxdWlyZShcInZ1ZS1ob3QtcmVsb2FkLWFwaVwiKS5yZXJlbmRlcihcImRhdGEtdi1mZjU2NGE4NlwiLCBtb2R1bGUuZXhwb3J0cylcbiAgfVxufVxuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIC4vbm9kZV9tb2R1bGVzL3Z1ZS1sb2FkZXIvbGliL3RlbXBsYXRlLWNvbXBpbGVyP3tcImlkXCI6XCJkYXRhLXYtZmY1NjRhODZcIixcImhhc1Njb3BlZFwiOnRydWV9IS4vbm9kZV9tb2R1bGVzL3Z1ZS1sb2FkZXIvbGliL3NlbGVjdG9yLmpzP3R5cGU9dGVtcGxhdGUmaW5kZXg9MCEuL3Jlc291cmNlcy9hc3NldHMvanMvY29tcG9uZW50cy9zZWxlY3QyLnZ1ZVxuLy8gbW9kdWxlIGlkID0gNTdcbi8vIG1vZHVsZSBjaHVua3MgPSAwIiwibW9kdWxlLmV4cG9ydHM9e3JlbmRlcjpmdW5jdGlvbiAoKXt2YXIgX3ZtPXRoaXM7dmFyIF9oPV92bS4kY3JlYXRlRWxlbWVudDt2YXIgX2M9X3ZtLl9zZWxmLl9jfHxfaDtcbiAgcmV0dXJuIF9jKCd0cicsIHtcbiAgICBkaXJlY3RpdmVzOiBbe1xuICAgICAgbmFtZTogXCJzaG93XCIsXG4gICAgICByYXdOYW1lOiBcInYtc2hvd1wiLFxuICAgICAgdmFsdWU6IChfdm0ucHJvY2Vzc0RldGFpbCksXG4gICAgICBleHByZXNzaW9uOiBcInByb2Nlc3NEZXRhaWxcIlxuICAgIH1dXG4gIH0sIFtfYygndGQnLCB7XG4gICAgYXR0cnM6IHtcbiAgICAgIFwiY29sc3BhblwiOiBcIjNcIlxuICAgIH1cbiAgfSwgW19jKCdoNCcsIHtcbiAgICBzdGF0aWNDbGFzczogXCJtb2RhbC10aXRsZVwiXG4gIH0sIFtfdm0uX3YoXCJJbXBvcnQgRmlsZTpcIildKSwgX3ZtLl92KFwiIFwiKSwgX2MoJ2RpdicsIHtcbiAgICBzdGF0aWNDbGFzczogXCJkeW5hbWljLWZvcm0tcm93XCJcbiAgfSwgW192bS5fbSgwKSwgX3ZtLl92KFwiIFwiKSwgX2MoJ2RpdicsIHtcbiAgICBzdGF0aWNDbGFzczogXCJjb2wtbWQtNCBjb2wteHMtMTJcIlxuICB9LCBbX2MoJ3NlbGVjdDInLCB7XG4gICAgYXR0cnM6IHtcbiAgICAgIFwib3B0aW9uc1wiOiBfdm0ub3B0aW9ucy5pbXBvcnRUeXBlc1xuICAgIH0sXG4gICAgbW9kZWw6IHtcbiAgICAgIHZhbHVlOiAoX3ZtLm9wdGlvbnMuaW1wb3J0VHlwZSksXG4gICAgICBjYWxsYmFjazogZnVuY3Rpb24oJCR2KSB7XG4gICAgICAgIF92bS5vcHRpb25zLmltcG9ydFR5cGUgPSAkJHZcbiAgICAgIH0sXG4gICAgICBleHByZXNzaW9uOiBcIm9wdGlvbnMuaW1wb3J0VHlwZVwiXG4gICAgfVxuICB9LCBbX2MoJ29wdGlvbicsIHtcbiAgICBhdHRyczoge1xuICAgICAgXCJkaXNhYmxlZFwiOiBcIlwiLFxuICAgICAgXCJ2YWx1ZVwiOiBcIjBcIlxuICAgIH1cbiAgfSldKV0sIDEpXSksIF92bS5fdihcIiBcIiksIF9jKCdkaXYnLCB7XG4gICAgc3RhdGljQ2xhc3M6IFwiZHluYW1pYy1mb3JtLXJvd1wiXG4gIH0sIFtfdm0uX20oMSksIF92bS5fdihcIiBcIiksIF9jKCdkaXYnLCB7XG4gICAgc3RhdGljQ2xhc3M6IFwiY29sLW1kLTQgY29sLXhzLTEyXCJcbiAgfSwgW19jKCdpbnB1dCcsIHtcbiAgICBkaXJlY3RpdmVzOiBbe1xuICAgICAgbmFtZTogXCJtb2RlbFwiLFxuICAgICAgcmF3TmFtZTogXCJ2LW1vZGVsXCIsXG4gICAgICB2YWx1ZTogKF92bS5vcHRpb25zLnVwZGF0ZSksXG4gICAgICBleHByZXNzaW9uOiBcIm9wdGlvbnMudXBkYXRlXCJcbiAgICB9XSxcbiAgICBhdHRyczoge1xuICAgICAgXCJ0eXBlXCI6IFwiY2hlY2tib3hcIixcbiAgICAgIFwibmFtZVwiOiBcImltcG9ydC11cGRhdGVcIlxuICAgIH0sXG4gICAgZG9tUHJvcHM6IHtcbiAgICAgIFwiY2hlY2tlZFwiOiBBcnJheS5pc0FycmF5KF92bS5vcHRpb25zLnVwZGF0ZSkgPyBfdm0uX2koX3ZtLm9wdGlvbnMudXBkYXRlLCBudWxsKSA+IC0xIDogKF92bS5vcHRpb25zLnVwZGF0ZSlcbiAgICB9LFxuICAgIG9uOiB7XG4gICAgICBcIl9fY1wiOiBmdW5jdGlvbigkZXZlbnQpIHtcbiAgICAgICAgdmFyICQkYSA9IF92bS5vcHRpb25zLnVwZGF0ZSxcbiAgICAgICAgICAkJGVsID0gJGV2ZW50LnRhcmdldCxcbiAgICAgICAgICAkJGMgPSAkJGVsLmNoZWNrZWQgPyAodHJ1ZSkgOiAoZmFsc2UpO1xuICAgICAgICBpZiAoQXJyYXkuaXNBcnJheSgkJGEpKSB7XG4gICAgICAgICAgdmFyICQkdiA9IG51bGwsXG4gICAgICAgICAgICAkJGkgPSBfdm0uX2koJCRhLCAkJHYpO1xuICAgICAgICAgIGlmICgkJGVsLmNoZWNrZWQpIHtcbiAgICAgICAgICAgICQkaSA8IDAgJiYgKF92bS5vcHRpb25zLnVwZGF0ZSA9ICQkYS5jb25jYXQoWyQkdl0pKVxuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAkJGkgPiAtMSAmJiAoX3ZtLm9wdGlvbnMudXBkYXRlID0gJCRhLnNsaWNlKDAsICQkaSkuY29uY2F0KCQkYS5zbGljZSgkJGkgKyAxKSkpXG4gICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIF92bS5vcHRpb25zLnVwZGF0ZSA9ICQkY1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9KV0pXSksIF92bS5fdihcIiBcIiksIF9jKCdkaXYnLCB7XG4gICAgc3RhdGljQ2xhc3M6IFwiY29sLW1kLTEyXCIsXG4gICAgc3RhdGljU3R5bGU6IHtcbiAgICAgIFwicGFkZGluZy10b3BcIjogXCIzMHB4XCJcbiAgICB9XG4gIH0sIFtfYygndGFibGUnLCB7XG4gICAgc3RhdGljQ2xhc3M6IFwidGFibGVcIlxuICB9LCBbX3ZtLl9tKDIpLCBfdm0uX3YoXCIgXCIpLCBfYygndGJvZHknLCBbX3ZtLl9sKChfdm0uZmlsZS5oZWFkZXJfcm93KSwgZnVuY3Rpb24oaGVhZGVyLCBpbmRleCkge1xuICAgIHJldHVybiBbX2MoJ3RyJywgW19jKCd0ZCcsIFtfYygnbGFiZWwnLCB7XG4gICAgICBzdGF0aWNDbGFzczogXCJjb250cm9sbGFiZWxcIixcbiAgICAgIGF0dHJzOiB7XG4gICAgICAgIFwiZm9yXCI6IGhlYWRlclxuICAgICAgfVxuICAgIH0sIFtfdm0uX3YoX3ZtLl9zKGhlYWRlcikpXSldKSwgX3ZtLl92KFwiIFwiKSwgX2MoJ3RkJywgW19jKCdkaXYnLCB7XG4gICAgICBhdHRyczoge1xuICAgICAgICBcInJlcXVpcmVkXCI6IFwiXCJcbiAgICAgIH1cbiAgICB9LCBbX2MoJ3NlbGVjdDInLCB7XG4gICAgICBhdHRyczoge1xuICAgICAgICBcIm9wdGlvbnNcIjogX3ZtLmNvbHVtbnNcbiAgICAgIH0sXG4gICAgICBtb2RlbDoge1xuICAgICAgICB2YWx1ZTogKF92bS5jb2x1bW5NYXBwaW5nc1toZWFkZXJdKSxcbiAgICAgICAgY2FsbGJhY2s6IGZ1bmN0aW9uKCQkdikge1xuICAgICAgICAgIF92bS4kc2V0KF92bS5jb2x1bW5NYXBwaW5ncywgaGVhZGVyLCAkJHYpXG4gICAgICAgIH0sXG4gICAgICAgIGV4cHJlc3Npb246IFwiY29sdW1uTWFwcGluZ3NbaGVhZGVyXVwiXG4gICAgICB9XG4gICAgfSwgW19jKCdvcHRpb24nLCB7XG4gICAgICBhdHRyczoge1xuICAgICAgICBcInZhbHVlXCI6IFwiMFwiXG4gICAgICB9XG4gICAgfSwgW192bS5fdihcIkRvIE5vdCBJbXBvcnRcIildKV0pXSwgMSldKSwgX3ZtLl92KFwiIFwiKSwgX2MoJ3RkJywgW19jKCdkaXYnLCBbX3ZtLl92KF92bS5fcyhfdm0uYWN0aXZlRmlsZS5maXJzdF9yb3dbaW5kZXhdKSldKV0pXSldXG4gIH0pXSwgMildKV0pXSksIF92bS5fdihcIiBcIiksIF9jKCd0ZCcsIFtfYygnYnV0dG9uJywge1xuICAgIHN0YXRpY0NsYXNzOiBcImJ0biBidG4tZGVmYXVsdFwiLFxuICAgIGF0dHJzOiB7XG4gICAgICBcInR5cGVcIjogXCJidXR0b25cIlxuICAgIH0sXG4gICAgb246IHtcbiAgICAgIFwiY2xpY2tcIjogZnVuY3Rpb24oJGV2ZW50KSB7XG4gICAgICAgIF92bS5wcm9jZXNzRGV0YWlsID0gZmFsc2VcbiAgICAgIH1cbiAgICB9XG4gIH0sIFtfdm0uX3YoXCJDYW5jZWxcIildKSwgX3ZtLl92KFwiIFwiKSwgX2MoJ2J1dHRvbicsIHtcbiAgICBzdGF0aWNDbGFzczogXCJidG4gYnRuLXByaW1hcnlcIixcbiAgICBhdHRyczoge1xuICAgICAgXCJ0eXBlXCI6IFwic3VibWl0XCJcbiAgICB9LFxuICAgIG9uOiB7XG4gICAgICBcImNsaWNrXCI6IF92bS5wb3N0U2F2ZVxuICAgIH1cbiAgfSwgW192bS5fdihcIkltcG9ydFwiKV0pLCBfdm0uX3YoXCIgXCIpLCAoX3ZtLnN0YXR1c1RleHQpID8gX2MoJ2RpdicsIHtcbiAgICBzdGF0aWNDbGFzczogXCJhbGVydCBhbGVydC1zdWNjZXNzIGNvbC1tZC01IGNvbC1tZC1vZmZzZXQtMVwiLFxuICAgIHN0YXRpY1N0eWxlOiB7XG4gICAgICBcInRleHQtYWxpZ25cIjogXCJsZWZ0XCJcbiAgICB9XG4gIH0sIFtfdm0uX3YoX3ZtLl9zKHRoaXMuc3RhdHVzVGV4dCkpXSkgOiBfdm0uX2UoKV0pXSlcbn0sc3RhdGljUmVuZGVyRm5zOiBbZnVuY3Rpb24gKCl7dmFyIF92bT10aGlzO3ZhciBfaD1fdm0uJGNyZWF0ZUVsZW1lbnQ7dmFyIF9jPV92bS5fc2VsZi5fY3x8X2g7XG4gIHJldHVybiBfYygnZGl2Jywge1xuICAgIHN0YXRpY0NsYXNzOiBcImNvbC1tZC00IGNvbC14cy0xMlwiXG4gIH0sIFtfYygnbGFiZWwnLCB7XG4gICAgYXR0cnM6IHtcbiAgICAgIFwiZm9yXCI6IFwiaW1wb3J0LXR5cGVcIlxuICAgIH1cbiAgfSwgW192bS5fdihcIkltcG9ydCBUeXBlOlwiKV0pXSlcbn0sZnVuY3Rpb24gKCl7dmFyIF92bT10aGlzO3ZhciBfaD1fdm0uJGNyZWF0ZUVsZW1lbnQ7dmFyIF9jPV92bS5fc2VsZi5fY3x8X2g7XG4gIHJldHVybiBfYygnZGl2Jywge1xuICAgIHN0YXRpY0NsYXNzOiBcImNvbC1tZC00IGNvbC14cy0xMlwiXG4gIH0sIFtfYygnbGFiZWwnLCB7XG4gICAgYXR0cnM6IHtcbiAgICAgIFwiZm9yXCI6IFwiaW1wb3J0LXVwZGF0ZVwiXG4gICAgfVxuICB9LCBbX3ZtLl92KFwiVXBkYXRlIEV4aXN0aW5nIFZhbHVlcz86XCIpXSldKVxufSxmdW5jdGlvbiAoKXt2YXIgX3ZtPXRoaXM7dmFyIF9oPV92bS4kY3JlYXRlRWxlbWVudDt2YXIgX2M9X3ZtLl9zZWxmLl9jfHxfaDtcbiAgcmV0dXJuIF9jKCd0aGVhZCcsIFtfYygndGgnLCBbX3ZtLl92KFwiSGVhZGVyIEZpZWxkXCIpXSksIF92bS5fdihcIiBcIiksIF9jKCd0aCcsIFtfdm0uX3YoXCJJbXBvcnQgRmllbGRcIildKSwgX3ZtLl92KFwiIFwiKSwgX2MoJ3RoJywgW192bS5fdihcIlNhbXBsZSBWYWx1ZVwiKV0pXSlcbn1dfVxubW9kdWxlLmV4cG9ydHMucmVuZGVyLl93aXRoU3RyaXBwZWQgPSB0cnVlXG5pZiAobW9kdWxlLmhvdCkge1xuICBtb2R1bGUuaG90LmFjY2VwdCgpXG4gIGlmIChtb2R1bGUuaG90LmRhdGEpIHtcbiAgICAgcmVxdWlyZShcInZ1ZS1ob3QtcmVsb2FkLWFwaVwiKS5yZXJlbmRlcihcImRhdGEtdi05MTYxOWYzYVwiLCBtb2R1bGUuZXhwb3J0cylcbiAgfVxufVxuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIC4vbm9kZV9tb2R1bGVzL3Z1ZS1sb2FkZXIvbGliL3RlbXBsYXRlLWNvbXBpbGVyP3tcImlkXCI6XCJkYXRhLXYtOTE2MTlmM2FcIixcImhhc1Njb3BlZFwiOmZhbHNlfSEuL25vZGVfbW9kdWxlcy92dWUtbG9hZGVyL2xpYi9zZWxlY3Rvci5qcz90eXBlPXRlbXBsYXRlJmluZGV4PTAhLi9yZXNvdXJjZXMvYXNzZXRzL2pzL2NvbXBvbmVudHMvaW1wb3J0ZXIvaW1wb3J0ZXItZmlsZS52dWVcbi8vIG1vZHVsZSBpZCA9IDU4XG4vLyBtb2R1bGUgY2h1bmtzID0gMCIsIi8vIHJlbW92ZWQgYnkgZXh0cmFjdC10ZXh0LXdlYnBhY2stcGx1Z2luXG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gLi9yZXNvdXJjZXMvYXNzZXRzL2xlc3MvQWRtaW5MVEUubGVzc1xuLy8gbW9kdWxlIGlkID0gNTlcbi8vIG1vZHVsZSBjaHVua3MgPSAwIiwiLy8gcmVtb3ZlZCBieSBleHRyYWN0LXRleHQtd2VicGFjay1wbHVnaW5cblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyAuL3Jlc291cmNlcy9hc3NldHMvbGVzcy9hcHAubGVzc1xuLy8gbW9kdWxlIGlkID0gNjBcbi8vIG1vZHVsZSBjaHVua3MgPSAwIiwiLy8gcmVtb3ZlZCBieSBleHRyYWN0LXRleHQtd2VicGFjay1wbHVnaW5cblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyAuL3Jlc291cmNlcy9hc3NldHMvbGVzcy9vdmVycmlkZXMubGVzc1xuLy8gbW9kdWxlIGlkID0gNjFcbi8vIG1vZHVsZSBjaHVua3MgPSAwIl0sInNvdXJjZVJvb3QiOiIifQ== |