commit 1b3c5235fee9f103a75c44b6962de1ef4c00f30f Author: YoVinchen Date: Thu Aug 31 11:30:31 2023 +0800 no message diff --git a/.obsidian/app.json b/.obsidian/app.json new file mode 100644 index 0000000..bc993c4 --- /dev/null +++ b/.obsidian/app.json @@ -0,0 +1,11 @@ +{ + "promptDelete": false, + "alwaysUpdateLinks": true, + "showUnsupportedFiles": true, + "readableLineLength": false, + "strictLineBreaks": true, + "showLineNumber": true, + "rightToLeft": false, + "showFrontmatter": true, + "attachmentFolderPath": "照片" +} \ No newline at end of file diff --git a/.obsidian/appearance.json b/.obsidian/appearance.json new file mode 100644 index 0000000..0f87e9c --- /dev/null +++ b/.obsidian/appearance.json @@ -0,0 +1,5 @@ +{ + "accentColor": "#d9d9d9", + "theme": "system", + "translucency": false +} \ No newline at end of file diff --git a/.obsidian/community-plugins.json b/.obsidian/community-plugins.json new file mode 100644 index 0000000..f0aa204 --- /dev/null +++ b/.obsidian/community-plugins.json @@ -0,0 +1,3 @@ +[ + "obsidian-image-auto-upload-plugin" +] \ No newline at end of file diff --git a/.obsidian/core-plugins-migration.json b/.obsidian/core-plugins-migration.json new file mode 100644 index 0000000..5c13490 --- /dev/null +++ b/.obsidian/core-plugins-migration.json @@ -0,0 +1,29 @@ +{ + "file-explorer": true, + "global-search": true, + "switcher": true, + "graph": true, + "backlink": true, + "canvas": true, + "outgoing-link": true, + "tag-pane": true, + "page-preview": true, + "daily-notes": true, + "templates": true, + "note-composer": true, + "command-palette": true, + "slash-command": false, + "editor-status": true, + "bookmarks": true, + "markdown-importer": false, + "zk-prefixer": false, + "random-note": false, + "outline": true, + "word-count": true, + "slides": false, + "audio-recorder": false, + "workspaces": false, + "file-recovery": true, + "publish": false, + "sync": false +} \ No newline at end of file diff --git a/.obsidian/core-plugins.json b/.obsidian/core-plugins.json new file mode 100644 index 0000000..9405bfd --- /dev/null +++ b/.obsidian/core-plugins.json @@ -0,0 +1,20 @@ +[ + "file-explorer", + "global-search", + "switcher", + "graph", + "backlink", + "canvas", + "outgoing-link", + "tag-pane", + "page-preview", + "daily-notes", + "templates", + "note-composer", + "command-palette", + "editor-status", + "bookmarks", + "outline", + "word-count", + "file-recovery" +] \ No newline at end of file diff --git a/.obsidian/graph.json b/.obsidian/graph.json new file mode 100644 index 0000000..c1d5722 --- /dev/null +++ b/.obsidian/graph.json @@ -0,0 +1,22 @@ +{ + "collapse-filter": true, + "search": "", + "showTags": false, + "showAttachments": false, + "hideUnresolved": false, + "showOrphans": true, + "collapse-color-groups": true, + "colorGroups": [], + "collapse-display": true, + "showArrow": false, + "textFadeMultiplier": 0, + "nodeSizeMultiplier": 1, + "lineSizeMultiplier": 1, + "collapse-forces": false, + "centerStrength": 0.518713248970312, + "repelStrength": 10, + "linkStrength": 1, + "linkDistance": 250, + "scale": 0.0078125, + "close": true +} \ No newline at end of file diff --git a/.obsidian/hotkeys.json b/.obsidian/hotkeys.json new file mode 100644 index 0000000..9e26dfe --- /dev/null +++ b/.obsidian/hotkeys.json @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/.obsidian/plugins/obsidian-image-auto-upload-plugin/data.json b/.obsidian/plugins/obsidian-image-auto-upload-plugin/data.json new file mode 100644 index 0000000..7d4a053 --- /dev/null +++ b/.obsidian/plugins/obsidian-image-auto-upload-plugin/data.json @@ -0,0 +1,14 @@ +{ + "uploadByClipSwitch": true, + "uploader": "PicGo", + "uploadServer": "http://127.0.0.1:36677/upload", + "deleteServer": "http://127.0.0.1:36677/delete", + "imageSizeSuffix": "", + "picgoCorePath": "", + "workOnNetWork": false, + "fixPath": false, + "applyImage": false, + "newWorkBlackDomains": "", + "deleteSource": false, + "imageDesc": "origin" +} \ No newline at end of file diff --git a/.obsidian/plugins/obsidian-image-auto-upload-plugin/main.js b/.obsidian/plugins/obsidian-image-auto-upload-plugin/main.js new file mode 100644 index 0000000..c10fb31 --- /dev/null +++ b/.obsidian/plugins/obsidian-image-auto-upload-plugin/main.js @@ -0,0 +1,9798 @@ +'use strict'; + +var obsidian = require('obsidian'); +var require$$0$1 = require('path'); +var require$$0 = require('fs'); +var process$2 = require('node:process'); +var require$$0$2 = require('child_process'); +var require$$0$3 = require('os'); +var require$$0$4 = require('assert'); +var require$$2 = require('events'); +var require$$0$6 = require('buffer'); +var require$$0$5 = require('stream'); +var require$$2$1 = require('util'); +var node_os = require('node:os'); +var node_buffer = require('node:buffer'); +require('electron'); + +/****************************************************************************** +Copyright (c) Microsoft Corporation. + +Permission to use, copy, modify, and/or distribute this software for any +purpose with or without fee is hereby granted. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH +REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY +AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, +INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR +OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +PERFORMANCE OF THIS SOFTWARE. +***************************************************************************** */ +/* global Reflect, Promise */ + +var extendStatics = function(d, b) { + extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; }; + return extendStatics(d, b); +}; + +function __extends(d, b) { + if (typeof b !== "function" && b !== null) + throw new TypeError("Class extends value " + String(b) + " is not a constructor or null"); + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); +} + +function __awaiter(thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +} + +function __generator(thisArg, body) { + var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; + return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; + function verb(n) { return function (v) { return step([n, v]); }; } + function step(op) { + if (f) throw new TypeError("Generator is already executing."); + while (g && (g = 0, op[0] && (_ = 0)), _) try { + if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; + if (y = 0, t) op = [op[0] & 2, t.value]; + switch (op[0]) { + case 0: case 1: t = op; break; + case 4: _.label++; return { value: op[1], done: false }; + case 5: _.label++; y = op[1]; op = [0]; continue; + case 7: op = _.ops.pop(); _.trys.pop(); continue; + default: + if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } + if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } + if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } + if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } + if (t[2]) _.ops.pop(); + _.trys.pop(); continue; + } + op = body.call(thisArg, _); + } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } + if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; + } +} + +function __values(o) { + var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0; + if (m) return m.call(o); + if (o && typeof o.length === "number") return { + next: function () { + if (o && i >= o.length) o = void 0; + return { value: o && o[i++], done: !o }; + } + }; + throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined."); +} + +function __read(o, n) { + var m = typeof Symbol === "function" && o[Symbol.iterator]; + if (!m) return o; + var i = m.call(o), r, ar = [], e; + try { + while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value); + } + catch (error) { e = { error: error }; } + finally { + try { + if (r && !r.done && (m = i["return"])) m.call(i); + } + finally { if (e) throw e.error; } + } + return ar; +} + +function __spreadArray(to, from, pack) { + if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) { + if (ar || !(i in from)) { + if (!ar) ar = Array.prototype.slice.call(from, 0, i); + ar[i] = from[i]; + } + } + return to.concat(ar || Array.prototype.slice.call(from)); +} + +function __asyncValues(o) { + if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); + var m = o[Symbol.asyncIterator], i; + return m ? m.call(o) : (o = typeof __values === "function" ? __values(o) : o[Symbol.iterator](), i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i); + function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; } + function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); } +} + +var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {}; + +function getDefaultExportFromCjs (x) { + return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x; +} + +var execa$2 = {exports: {}}; + +var crossSpawn$1 = {exports: {}}; + +var windows; +var hasRequiredWindows; + +function requireWindows () { + if (hasRequiredWindows) return windows; + hasRequiredWindows = 1; + windows = isexe; + isexe.sync = sync; + + var fs = require$$0; + + function checkPathExt (path, options) { + var pathext = options.pathExt !== undefined ? + options.pathExt : process.env.PATHEXT; + + if (!pathext) { + return true + } + + pathext = pathext.split(';'); + if (pathext.indexOf('') !== -1) { + return true + } + for (var i = 0; i < pathext.length; i++) { + var p = pathext[i].toLowerCase(); + if (p && path.substr(-p.length).toLowerCase() === p) { + return true + } + } + return false + } + + function checkStat (stat, path, options) { + if (!stat.isSymbolicLink() && !stat.isFile()) { + return false + } + return checkPathExt(path, options) + } + + function isexe (path, options, cb) { + fs.stat(path, function (er, stat) { + cb(er, er ? false : checkStat(stat, path, options)); + }); + } + + function sync (path, options) { + return checkStat(fs.statSync(path), path, options) + } + return windows; +} + +var mode; +var hasRequiredMode; + +function requireMode () { + if (hasRequiredMode) return mode; + hasRequiredMode = 1; + mode = isexe; + isexe.sync = sync; + + var fs = require$$0; + + function isexe (path, options, cb) { + fs.stat(path, function (er, stat) { + cb(er, er ? false : checkStat(stat, options)); + }); + } + + function sync (path, options) { + return checkStat(fs.statSync(path), options) + } + + function checkStat (stat, options) { + return stat.isFile() && checkMode(stat, options) + } + + function checkMode (stat, options) { + var mod = stat.mode; + var uid = stat.uid; + var gid = stat.gid; + + var myUid = options.uid !== undefined ? + options.uid : process.getuid && process.getuid(); + var myGid = options.gid !== undefined ? + options.gid : process.getgid && process.getgid(); + + var u = parseInt('100', 8); + var g = parseInt('010', 8); + var o = parseInt('001', 8); + var ug = u | g; + + var ret = (mod & o) || + (mod & g) && gid === myGid || + (mod & u) && uid === myUid || + (mod & ug) && myUid === 0; + + return ret + } + return mode; +} + +var core$1; +if (process.platform === 'win32' || commonjsGlobal.TESTING_WINDOWS) { + core$1 = requireWindows(); +} else { + core$1 = requireMode(); +} + +var isexe_1 = isexe$1; +isexe$1.sync = sync; + +function isexe$1 (path, options, cb) { + if (typeof options === 'function') { + cb = options; + options = {}; + } + + if (!cb) { + if (typeof Promise !== 'function') { + throw new TypeError('callback not provided') + } + + return new Promise(function (resolve, reject) { + isexe$1(path, options || {}, function (er, is) { + if (er) { + reject(er); + } else { + resolve(is); + } + }); + }) + } + + core$1(path, options || {}, function (er, is) { + // ignore EACCES because that just means we aren't allowed to run it + if (er) { + if (er.code === 'EACCES' || options && options.ignoreErrors) { + er = null; + is = false; + } + } + cb(er, is); + }); +} + +function sync (path, options) { + // my kingdom for a filtered catch + try { + return core$1.sync(path, options || {}) + } catch (er) { + if (options && options.ignoreErrors || er.code === 'EACCES') { + return false + } else { + throw er + } + } +} + +const isWindows = process.platform === 'win32' || + process.env.OSTYPE === 'cygwin' || + process.env.OSTYPE === 'msys'; + +const path$3 = require$$0$1; +const COLON = isWindows ? ';' : ':'; +const isexe = isexe_1; + +const getNotFoundError = (cmd) => + Object.assign(new Error(`not found: ${cmd}`), { code: 'ENOENT' }); + +const getPathInfo = (cmd, opt) => { + const colon = opt.colon || COLON; + + // If it has a slash, then we don't bother searching the pathenv. + // just check the file itself, and that's it. + const pathEnv = cmd.match(/\//) || isWindows && cmd.match(/\\/) ? [''] + : ( + [ + // windows always checks the cwd first + ...(isWindows ? [process.cwd()] : []), + ...(opt.path || process.env.PATH || + /* istanbul ignore next: very unusual */ '').split(colon), + ] + ); + const pathExtExe = isWindows + ? opt.pathExt || process.env.PATHEXT || '.EXE;.CMD;.BAT;.COM' + : ''; + const pathExt = isWindows ? pathExtExe.split(colon) : ['']; + + if (isWindows) { + if (cmd.indexOf('.') !== -1 && pathExt[0] !== '') + pathExt.unshift(''); + } + + return { + pathEnv, + pathExt, + pathExtExe, + } +}; + +const which$1 = (cmd, opt, cb) => { + if (typeof opt === 'function') { + cb = opt; + opt = {}; + } + if (!opt) + opt = {}; + + const { pathEnv, pathExt, pathExtExe } = getPathInfo(cmd, opt); + const found = []; + + const step = i => new Promise((resolve, reject) => { + if (i === pathEnv.length) + return opt.all && found.length ? resolve(found) + : reject(getNotFoundError(cmd)) + + const ppRaw = pathEnv[i]; + const pathPart = /^".*"$/.test(ppRaw) ? ppRaw.slice(1, -1) : ppRaw; + + const pCmd = path$3.join(pathPart, cmd); + const p = !pathPart && /^\.[\\\/]/.test(cmd) ? cmd.slice(0, 2) + pCmd + : pCmd; + + resolve(subStep(p, i, 0)); + }); + + const subStep = (p, i, ii) => new Promise((resolve, reject) => { + if (ii === pathExt.length) + return resolve(step(i + 1)) + const ext = pathExt[ii]; + isexe(p + ext, { pathExt: pathExtExe }, (er, is) => { + if (!er && is) { + if (opt.all) + found.push(p + ext); + else + return resolve(p + ext) + } + return resolve(subStep(p, i, ii + 1)) + }); + }); + + return cb ? step(0).then(res => cb(null, res), cb) : step(0) +}; + +const whichSync = (cmd, opt) => { + opt = opt || {}; + + const { pathEnv, pathExt, pathExtExe } = getPathInfo(cmd, opt); + const found = []; + + for (let i = 0; i < pathEnv.length; i ++) { + const ppRaw = pathEnv[i]; + const pathPart = /^".*"$/.test(ppRaw) ? ppRaw.slice(1, -1) : ppRaw; + + const pCmd = path$3.join(pathPart, cmd); + const p = !pathPart && /^\.[\\\/]/.test(cmd) ? cmd.slice(0, 2) + pCmd + : pCmd; + + for (let j = 0; j < pathExt.length; j ++) { + const cur = p + pathExt[j]; + try { + const is = isexe.sync(cur, { pathExt: pathExtExe }); + if (is) { + if (opt.all) + found.push(cur); + else + return cur + } + } catch (ex) {} + } + } + + if (opt.all && found.length) + return found + + if (opt.nothrow) + return null + + throw getNotFoundError(cmd) +}; + +var which_1 = which$1; +which$1.sync = whichSync; + +var pathKey$1 = {exports: {}}; + +const pathKey = (options = {}) => { + const environment = options.env || process.env; + const platform = options.platform || process.platform; + + if (platform !== 'win32') { + return 'PATH'; + } + + return Object.keys(environment).reverse().find(key => key.toUpperCase() === 'PATH') || 'Path'; +}; + +pathKey$1.exports = pathKey; +// TODO: Remove this for the next major release +pathKey$1.exports.default = pathKey; + +var pathKeyExports = pathKey$1.exports; + +const path$2 = require$$0$1; +const which = which_1; +const getPathKey = pathKeyExports; + +function resolveCommandAttempt(parsed, withoutPathExt) { + const env = parsed.options.env || process.env; + const cwd = process.cwd(); + const hasCustomCwd = parsed.options.cwd != null; + // Worker threads do not have process.chdir() + const shouldSwitchCwd = hasCustomCwd && process.chdir !== undefined && !process.chdir.disabled; + + // If a custom `cwd` was specified, we need to change the process cwd + // because `which` will do stat calls but does not support a custom cwd + if (shouldSwitchCwd) { + try { + process.chdir(parsed.options.cwd); + } catch (err) { + /* Empty */ + } + } + + let resolved; + + try { + resolved = which.sync(parsed.command, { + path: env[getPathKey({ env })], + pathExt: withoutPathExt ? path$2.delimiter : undefined, + }); + } catch (e) { + /* Empty */ + } finally { + if (shouldSwitchCwd) { + process.chdir(cwd); + } + } + + // If we successfully resolved, ensure that an absolute path is returned + // Note that when a custom `cwd` was used, we need to resolve to an absolute path based on it + if (resolved) { + resolved = path$2.resolve(hasCustomCwd ? parsed.options.cwd : '', resolved); + } + + return resolved; +} + +function resolveCommand$1(parsed) { + return resolveCommandAttempt(parsed) || resolveCommandAttempt(parsed, true); +} + +var resolveCommand_1 = resolveCommand$1; + +var _escape = {}; + +// See http://www.robvanderwoude.com/escapechars.php +const metaCharsRegExp = /([()\][%!^"`<>&|;, *?])/g; + +function escapeCommand(arg) { + // Escape meta chars + arg = arg.replace(metaCharsRegExp, '^$1'); + + return arg; +} + +function escapeArgument(arg, doubleEscapeMetaChars) { + // Convert to string + arg = `${arg}`; + + // Algorithm below is based on https://qntm.org/cmd + + // Sequence of backslashes followed by a double quote: + // double up all the backslashes and escape the double quote + arg = arg.replace(/(\\*)"/g, '$1$1\\"'); + + // Sequence of backslashes followed by the end of the string + // (which will become a double quote later): + // double up all the backslashes + arg = arg.replace(/(\\*)$/, '$1$1'); + + // All other backslashes occur literally + + // Quote the whole thing: + arg = `"${arg}"`; + + // Escape meta chars + arg = arg.replace(metaCharsRegExp, '^$1'); + + // Double escape meta chars if necessary + if (doubleEscapeMetaChars) { + arg = arg.replace(metaCharsRegExp, '^$1'); + } + + return arg; +} + +_escape.command = escapeCommand; +_escape.argument = escapeArgument; + +var shebangRegex$1 = /^#!(.*)/; + +const shebangRegex = shebangRegex$1; + +var shebangCommand$1 = (string = '') => { + const match = string.match(shebangRegex); + + if (!match) { + return null; + } + + const [path, argument] = match[0].replace(/#! ?/, '').split(' '); + const binary = path.split('/').pop(); + + if (binary === 'env') { + return argument; + } + + return argument ? `${binary} ${argument}` : binary; +}; + +const fs = require$$0; +const shebangCommand = shebangCommand$1; + +function readShebang$1(command) { + // Read the first 150 bytes from the file + const size = 150; + const buffer = Buffer.alloc(size); + + let fd; + + try { + fd = fs.openSync(command, 'r'); + fs.readSync(fd, buffer, 0, size, 0); + fs.closeSync(fd); + } catch (e) { /* Empty */ } + + // Attempt to extract shebang (null is returned if not a shebang) + return shebangCommand(buffer.toString()); +} + +var readShebang_1 = readShebang$1; + +const path$1 = require$$0$1; +const resolveCommand = resolveCommand_1; +const escape = _escape; +const readShebang = readShebang_1; + +const isWin$2 = process.platform === 'win32'; +const isExecutableRegExp = /\.(?:com|exe)$/i; +const isCmdShimRegExp = /node_modules[\\/].bin[\\/][^\\/]+\.cmd$/i; + +function detectShebang(parsed) { + parsed.file = resolveCommand(parsed); + + const shebang = parsed.file && readShebang(parsed.file); + + if (shebang) { + parsed.args.unshift(parsed.file); + parsed.command = shebang; + + return resolveCommand(parsed); + } + + return parsed.file; +} + +function parseNonShell(parsed) { + if (!isWin$2) { + return parsed; + } + + // Detect & add support for shebangs + const commandFile = detectShebang(parsed); + + // We don't need a shell if the command filename is an executable + const needsShell = !isExecutableRegExp.test(commandFile); + + // If a shell is required, use cmd.exe and take care of escaping everything correctly + // Note that `forceShell` is an hidden option used only in tests + if (parsed.options.forceShell || needsShell) { + // Need to double escape meta chars if the command is a cmd-shim located in `node_modules/.bin/` + // The cmd-shim simply calls execute the package bin file with NodeJS, proxying any argument + // Because the escape of metachars with ^ gets interpreted when the cmd.exe is first called, + // we need to double escape them + const needsDoubleEscapeMetaChars = isCmdShimRegExp.test(commandFile); + + // Normalize posix paths into OS compatible paths (e.g.: foo/bar -> foo\bar) + // This is necessary otherwise it will always fail with ENOENT in those cases + parsed.command = path$1.normalize(parsed.command); + + // Escape command & arguments + parsed.command = escape.command(parsed.command); + parsed.args = parsed.args.map((arg) => escape.argument(arg, needsDoubleEscapeMetaChars)); + + const shellCommand = [parsed.command].concat(parsed.args).join(' '); + + parsed.args = ['/d', '/s', '/c', `"${shellCommand}"`]; + parsed.command = process.env.comspec || 'cmd.exe'; + parsed.options.windowsVerbatimArguments = true; // Tell node's spawn that the arguments are already escaped + } + + return parsed; +} + +function parse$1(command, args, options) { + // Normalize arguments, similar to nodejs + if (args && !Array.isArray(args)) { + options = args; + args = null; + } + + args = args ? args.slice(0) : []; // Clone array to avoid changing the original + options = Object.assign({}, options); // Clone object to avoid changing the original + + // Build our parsed object + const parsed = { + command, + args, + options, + file: undefined, + original: { + command, + args, + }, + }; + + // Delegate further parsing to shell or non-shell + return options.shell ? parsed : parseNonShell(parsed); +} + +var parse_1 = parse$1; + +const isWin$1 = process.platform === 'win32'; + +function notFoundError(original, syscall) { + return Object.assign(new Error(`${syscall} ${original.command} ENOENT`), { + code: 'ENOENT', + errno: 'ENOENT', + syscall: `${syscall} ${original.command}`, + path: original.command, + spawnargs: original.args, + }); +} + +function hookChildProcess(cp, parsed) { + if (!isWin$1) { + return; + } + + const originalEmit = cp.emit; + + cp.emit = function (name, arg1) { + // If emitting "exit" event and exit code is 1, we need to check if + // the command exists and emit an "error" instead + // See https://github.com/IndigoUnited/node-cross-spawn/issues/16 + if (name === 'exit') { + const err = verifyENOENT(arg1, parsed); + + if (err) { + return originalEmit.call(cp, 'error', err); + } + } + + return originalEmit.apply(cp, arguments); // eslint-disable-line prefer-rest-params + }; +} + +function verifyENOENT(status, parsed) { + if (isWin$1 && status === 1 && !parsed.file) { + return notFoundError(parsed.original, 'spawn'); + } + + return null; +} + +function verifyENOENTSync(status, parsed) { + if (isWin$1 && status === 1 && !parsed.file) { + return notFoundError(parsed.original, 'spawnSync'); + } + + return null; +} + +var enoent$1 = { + hookChildProcess, + verifyENOENT, + verifyENOENTSync, + notFoundError, +}; + +const cp = require$$0$2; +const parse = parse_1; +const enoent = enoent$1; + +function spawn(command, args, options) { + // Parse the arguments + const parsed = parse(command, args, options); + + // Spawn the child process + const spawned = cp.spawn(parsed.command, parsed.args, parsed.options); + + // Hook into child process "exit" event to emit an error if the command + // does not exists, see: https://github.com/IndigoUnited/node-cross-spawn/issues/16 + enoent.hookChildProcess(spawned, parsed); + + return spawned; +} + +function spawnSync(command, args, options) { + // Parse the arguments + const parsed = parse(command, args, options); + + // Spawn the child process + const result = cp.spawnSync(parsed.command, parsed.args, parsed.options); + + // Analyze if the command does not exist, see: https://github.com/IndigoUnited/node-cross-spawn/issues/16 + result.error = result.error || enoent.verifyENOENTSync(result.status, parsed); + + return result; +} + +crossSpawn$1.exports = spawn; +crossSpawn$1.exports.spawn = spawn; +crossSpawn$1.exports.sync = spawnSync; + +crossSpawn$1.exports._parse = parse; +crossSpawn$1.exports._enoent = enoent; + +var crossSpawnExports = crossSpawn$1.exports; + +var stripFinalNewline$1 = input => { + const LF = typeof input === 'string' ? '\n' : '\n'.charCodeAt(); + const CR = typeof input === 'string' ? '\r' : '\r'.charCodeAt(); + + if (input[input.length - 1] === LF) { + input = input.slice(0, input.length - 1); + } + + if (input[input.length - 1] === CR) { + input = input.slice(0, input.length - 1); + } + + return input; +}; + +var npmRunPath$1 = {exports: {}}; + +npmRunPath$1.exports; + +(function (module) { + const path = require$$0$1; + const pathKey = pathKeyExports; + + const npmRunPath = options => { + options = { + cwd: process.cwd(), + path: process.env[pathKey()], + execPath: process.execPath, + ...options + }; + + let previous; + let cwdPath = path.resolve(options.cwd); + const result = []; + + while (previous !== cwdPath) { + result.push(path.join(cwdPath, 'node_modules/.bin')); + previous = cwdPath; + cwdPath = path.resolve(cwdPath, '..'); + } + + // Ensure the running `node` binary is used + const execPathDir = path.resolve(options.cwd, options.execPath, '..'); + result.push(execPathDir); + + return result.concat(options.path).join(path.delimiter); + }; + + module.exports = npmRunPath; + // TODO: Remove this for the next major release + module.exports.default = npmRunPath; + + module.exports.env = options => { + options = { + env: process.env, + ...options + }; + + const env = {...options.env}; + const path = pathKey({env}); + + options.path = env[path]; + env[path] = module.exports(options); + + return env; + }; +} (npmRunPath$1)); + +var npmRunPathExports = npmRunPath$1.exports; + +var onetime$2 = {exports: {}}; + +var mimicFn$2 = {exports: {}}; + +const mimicFn$1 = (to, from) => { + for (const prop of Reflect.ownKeys(from)) { + Object.defineProperty(to, prop, Object.getOwnPropertyDescriptor(from, prop)); + } + + return to; +}; + +mimicFn$2.exports = mimicFn$1; +// TODO: Remove this for the next major release +mimicFn$2.exports.default = mimicFn$1; + +var mimicFnExports = mimicFn$2.exports; + +const mimicFn = mimicFnExports; + +const calledFunctions = new WeakMap(); + +const onetime$1 = (function_, options = {}) => { + if (typeof function_ !== 'function') { + throw new TypeError('Expected a function'); + } + + let returnValue; + let callCount = 0; + const functionName = function_.displayName || function_.name || ''; + + const onetime = function (...arguments_) { + calledFunctions.set(onetime, ++callCount); + + if (callCount === 1) { + returnValue = function_.apply(this, arguments_); + function_ = null; + } else if (options.throw === true) { + throw new Error(`Function \`${functionName}\` can only be called once`); + } + + return returnValue; + }; + + mimicFn(onetime, function_); + calledFunctions.set(onetime, callCount); + + return onetime; +}; + +onetime$2.exports = onetime$1; +// TODO: Remove this for the next major release +onetime$2.exports.default = onetime$1; + +onetime$2.exports.callCount = function_ => { + if (!calledFunctions.has(function_)) { + throw new Error(`The given function \`${function_.name}\` is not wrapped by the \`onetime\` package`); + } + + return calledFunctions.get(function_); +}; + +var onetimeExports = onetime$2.exports; + +var main = {}; + +var signals$2 = {}; + +var core = {}; + +Object.defineProperty(core,"__esModule",{value:true});core.SIGNALS=void 0; + +const SIGNALS=[ +{ +name:"SIGHUP", +number:1, +action:"terminate", +description:"Terminal closed", +standard:"posix"}, + +{ +name:"SIGINT", +number:2, +action:"terminate", +description:"User interruption with CTRL-C", +standard:"ansi"}, + +{ +name:"SIGQUIT", +number:3, +action:"core", +description:"User interruption with CTRL-\\", +standard:"posix"}, + +{ +name:"SIGILL", +number:4, +action:"core", +description:"Invalid machine instruction", +standard:"ansi"}, + +{ +name:"SIGTRAP", +number:5, +action:"core", +description:"Debugger breakpoint", +standard:"posix"}, + +{ +name:"SIGABRT", +number:6, +action:"core", +description:"Aborted", +standard:"ansi"}, + +{ +name:"SIGIOT", +number:6, +action:"core", +description:"Aborted", +standard:"bsd"}, + +{ +name:"SIGBUS", +number:7, +action:"core", +description: +"Bus error due to misaligned, non-existing address or paging error", +standard:"bsd"}, + +{ +name:"SIGEMT", +number:7, +action:"terminate", +description:"Command should be emulated but is not implemented", +standard:"other"}, + +{ +name:"SIGFPE", +number:8, +action:"core", +description:"Floating point arithmetic error", +standard:"ansi"}, + +{ +name:"SIGKILL", +number:9, +action:"terminate", +description:"Forced termination", +standard:"posix", +forced:true}, + +{ +name:"SIGUSR1", +number:10, +action:"terminate", +description:"Application-specific signal", +standard:"posix"}, + +{ +name:"SIGSEGV", +number:11, +action:"core", +description:"Segmentation fault", +standard:"ansi"}, + +{ +name:"SIGUSR2", +number:12, +action:"terminate", +description:"Application-specific signal", +standard:"posix"}, + +{ +name:"SIGPIPE", +number:13, +action:"terminate", +description:"Broken pipe or socket", +standard:"posix"}, + +{ +name:"SIGALRM", +number:14, +action:"terminate", +description:"Timeout or timer", +standard:"posix"}, + +{ +name:"SIGTERM", +number:15, +action:"terminate", +description:"Termination", +standard:"ansi"}, + +{ +name:"SIGSTKFLT", +number:16, +action:"terminate", +description:"Stack is empty or overflowed", +standard:"other"}, + +{ +name:"SIGCHLD", +number:17, +action:"ignore", +description:"Child process terminated, paused or unpaused", +standard:"posix"}, + +{ +name:"SIGCLD", +number:17, +action:"ignore", +description:"Child process terminated, paused or unpaused", +standard:"other"}, + +{ +name:"SIGCONT", +number:18, +action:"unpause", +description:"Unpaused", +standard:"posix", +forced:true}, + +{ +name:"SIGSTOP", +number:19, +action:"pause", +description:"Paused", +standard:"posix", +forced:true}, + +{ +name:"SIGTSTP", +number:20, +action:"pause", +description:"Paused using CTRL-Z or \"suspend\"", +standard:"posix"}, + +{ +name:"SIGTTIN", +number:21, +action:"pause", +description:"Background process cannot read terminal input", +standard:"posix"}, + +{ +name:"SIGBREAK", +number:21, +action:"terminate", +description:"User interruption with CTRL-BREAK", +standard:"other"}, + +{ +name:"SIGTTOU", +number:22, +action:"pause", +description:"Background process cannot write to terminal output", +standard:"posix"}, + +{ +name:"SIGURG", +number:23, +action:"ignore", +description:"Socket received out-of-band data", +standard:"bsd"}, + +{ +name:"SIGXCPU", +number:24, +action:"core", +description:"Process timed out", +standard:"bsd"}, + +{ +name:"SIGXFSZ", +number:25, +action:"core", +description:"File too big", +standard:"bsd"}, + +{ +name:"SIGVTALRM", +number:26, +action:"terminate", +description:"Timeout or timer", +standard:"bsd"}, + +{ +name:"SIGPROF", +number:27, +action:"terminate", +description:"Timeout or timer", +standard:"bsd"}, + +{ +name:"SIGWINCH", +number:28, +action:"ignore", +description:"Terminal window size changed", +standard:"bsd"}, + +{ +name:"SIGIO", +number:29, +action:"terminate", +description:"I/O is available", +standard:"other"}, + +{ +name:"SIGPOLL", +number:29, +action:"terminate", +description:"Watched event", +standard:"other"}, + +{ +name:"SIGINFO", +number:29, +action:"ignore", +description:"Request for process information", +standard:"other"}, + +{ +name:"SIGPWR", +number:30, +action:"terminate", +description:"Device running out of power", +standard:"systemv"}, + +{ +name:"SIGSYS", +number:31, +action:"core", +description:"Invalid system call", +standard:"other"}, + +{ +name:"SIGUNUSED", +number:31, +action:"terminate", +description:"Invalid system call", +standard:"other"}];core.SIGNALS=SIGNALS; + +var realtime = {}; + +Object.defineProperty(realtime,"__esModule",{value:true});realtime.SIGRTMAX=realtime.getRealtimeSignals=void 0; +const getRealtimeSignals=function(){ +const length=SIGRTMAX-SIGRTMIN+1; +return Array.from({length},getRealtimeSignal); +};realtime.getRealtimeSignals=getRealtimeSignals; + +const getRealtimeSignal=function(value,index){ +return { +name:`SIGRT${index+1}`, +number:SIGRTMIN+index, +action:"terminate", +description:"Application-specific signal (realtime)", +standard:"posix"}; + +}; + +const SIGRTMIN=34; +const SIGRTMAX=64;realtime.SIGRTMAX=SIGRTMAX; + +Object.defineProperty(signals$2,"__esModule",{value:true});signals$2.getSignals=void 0;var _os$1=require$$0$3; + +var _core=core; +var _realtime$1=realtime; + + + +const getSignals=function(){ +const realtimeSignals=(0, _realtime$1.getRealtimeSignals)(); +const signals=[..._core.SIGNALS,...realtimeSignals].map(normalizeSignal); +return signals; +};signals$2.getSignals=getSignals; + + + + + + + +const normalizeSignal=function({ +name, +number:defaultNumber, +description, +action, +forced=false, +standard}) +{ +const{ +signals:{[name]:constantSignal}}= +_os$1.constants; +const supported=constantSignal!==undefined; +const number=supported?constantSignal:defaultNumber; +return {name,number,description,supported,action,forced,standard}; +}; + +Object.defineProperty(main,"__esModule",{value:true});main.signalsByNumber=main.signalsByName=void 0;var _os=require$$0$3; + +var _signals=signals$2; +var _realtime=realtime; + + + +const getSignalsByName=function(){ +const signals=(0, _signals.getSignals)(); +return signals.reduce(getSignalByName,{}); +}; + +const getSignalByName=function( +signalByNameMemo, +{name,number,description,supported,action,forced,standard}) +{ +return { +...signalByNameMemo, +[name]:{name,number,description,supported,action,forced,standard}}; + +}; + +const signalsByName$1=getSignalsByName();main.signalsByName=signalsByName$1; + + + + +const getSignalsByNumber=function(){ +const signals=(0, _signals.getSignals)(); +const length=_realtime.SIGRTMAX+1; +const signalsA=Array.from({length},(value,number)=> +getSignalByNumber(number,signals)); + +return Object.assign({},...signalsA); +}; + +const getSignalByNumber=function(number,signals){ +const signal=findSignalByNumber(number,signals); + +if(signal===undefined){ +return {}; +} + +const{name,description,supported,action,forced,standard}=signal; +return { +[number]:{ +name, +number, +description, +supported, +action, +forced, +standard}}; + + +}; + + + +const findSignalByNumber=function(number,signals){ +const signal=signals.find(({name})=>_os.constants.signals[name]===number); + +if(signal!==undefined){ +return signal; +} + +return signals.find(signalA=>signalA.number===number); +}; + +const signalsByNumber=getSignalsByNumber();main.signalsByNumber=signalsByNumber; + +const {signalsByName} = main; + +const getErrorPrefix = ({timedOut, timeout, errorCode, signal, signalDescription, exitCode, isCanceled}) => { + if (timedOut) { + return `timed out after ${timeout} milliseconds`; + } + + if (isCanceled) { + return 'was canceled'; + } + + if (errorCode !== undefined) { + return `failed with ${errorCode}`; + } + + if (signal !== undefined) { + return `was killed with ${signal} (${signalDescription})`; + } + + if (exitCode !== undefined) { + return `failed with exit code ${exitCode}`; + } + + return 'failed'; +}; + +const makeError$1 = ({ + stdout, + stderr, + all, + error, + signal, + exitCode, + command, + escapedCommand, + timedOut, + isCanceled, + killed, + parsed: {options: {timeout}} +}) => { + // `signal` and `exitCode` emitted on `spawned.on('exit')` event can be `null`. + // We normalize them to `undefined` + exitCode = exitCode === null ? undefined : exitCode; + signal = signal === null ? undefined : signal; + const signalDescription = signal === undefined ? undefined : signalsByName[signal].description; + + const errorCode = error && error.code; + + const prefix = getErrorPrefix({timedOut, timeout, errorCode, signal, signalDescription, exitCode, isCanceled}); + const execaMessage = `Command ${prefix}: ${command}`; + const isError = Object.prototype.toString.call(error) === '[object Error]'; + const shortMessage = isError ? `${execaMessage}\n${error.message}` : execaMessage; + const message = [shortMessage, stderr, stdout].filter(Boolean).join('\n'); + + if (isError) { + error.originalMessage = error.message; + error.message = message; + } else { + error = new Error(message); + } + + error.shortMessage = shortMessage; + error.command = command; + error.escapedCommand = escapedCommand; + error.exitCode = exitCode; + error.signal = signal; + error.signalDescription = signalDescription; + error.stdout = stdout; + error.stderr = stderr; + + if (all !== undefined) { + error.all = all; + } + + if ('bufferedData' in error) { + delete error.bufferedData; + } + + error.failed = true; + error.timedOut = Boolean(timedOut); + error.isCanceled = isCanceled; + error.killed = killed && !timedOut; + + return error; +}; + +var error = makeError$1; + +var stdio = {exports: {}}; + +const aliases = ['stdin', 'stdout', 'stderr']; + +const hasAlias = options => aliases.some(alias => options[alias] !== undefined); + +const normalizeStdio$1 = options => { + if (!options) { + return; + } + + const {stdio} = options; + + if (stdio === undefined) { + return aliases.map(alias => options[alias]); + } + + if (hasAlias(options)) { + throw new Error(`It's not possible to provide \`stdio\` in combination with one of ${aliases.map(alias => `\`${alias}\``).join(', ')}`); + } + + if (typeof stdio === 'string') { + return stdio; + } + + if (!Array.isArray(stdio)) { + throw new TypeError(`Expected \`stdio\` to be of type \`string\` or \`Array\`, got \`${typeof stdio}\``); + } + + const length = Math.max(stdio.length, aliases.length); + return Array.from({length}, (value, index) => stdio[index]); +}; + +stdio.exports = normalizeStdio$1; + +// `ipc` is pushed unless it is already present +stdio.exports.node = options => { + const stdio = normalizeStdio$1(options); + + if (stdio === 'ipc') { + return 'ipc'; + } + + if (stdio === undefined || typeof stdio === 'string') { + return [stdio, stdio, stdio, 'ipc']; + } + + if (stdio.includes('ipc')) { + return stdio; + } + + return [...stdio, 'ipc']; +}; + +var stdioExports = stdio.exports; + +var signalExit = {exports: {}}; + +var signals$1 = {exports: {}}; + +var hasRequiredSignals; + +function requireSignals () { + if (hasRequiredSignals) return signals$1.exports; + hasRequiredSignals = 1; + (function (module) { + // This is not the set of all possible signals. + // + // It IS, however, the set of all signals that trigger + // an exit on either Linux or BSD systems. Linux is a + // superset of the signal names supported on BSD, and + // the unknown signals just fail to register, so we can + // catch that easily enough. + // + // Don't bother with SIGKILL. It's uncatchable, which + // means that we can't fire any callbacks anyway. + // + // If a user does happen to register a handler on a non- + // fatal signal like SIGWINCH or something, and then + // exit, it'll end up firing `process.emit('exit')`, so + // the handler will be fired anyway. + // + // SIGBUS, SIGFPE, SIGSEGV and SIGILL, when not raised + // artificially, inherently leave the process in a + // state from which it is not safe to try and enter JS + // listeners. + module.exports = [ + 'SIGABRT', + 'SIGALRM', + 'SIGHUP', + 'SIGINT', + 'SIGTERM' + ]; + + if (process.platform !== 'win32') { + module.exports.push( + 'SIGVTALRM', + 'SIGXCPU', + 'SIGXFSZ', + 'SIGUSR2', + 'SIGTRAP', + 'SIGSYS', + 'SIGQUIT', + 'SIGIOT' + // should detect profiler and enable/disable accordingly. + // see #21 + // 'SIGPROF' + ); + } + + if (process.platform === 'linux') { + module.exports.push( + 'SIGIO', + 'SIGPOLL', + 'SIGPWR', + 'SIGSTKFLT', + 'SIGUNUSED' + ); + } + } (signals$1)); + return signals$1.exports; +} + +// Note: since nyc uses this module to output coverage, any lines +// that are in the direct sync flow of nyc's outputCoverage are +// ignored, since we can never get coverage for them. +// grab a reference to node's real process object right away +var process$1 = commonjsGlobal.process; + +const processOk = function (process) { + return process && + typeof process === 'object' && + typeof process.removeListener === 'function' && + typeof process.emit === 'function' && + typeof process.reallyExit === 'function' && + typeof process.listeners === 'function' && + typeof process.kill === 'function' && + typeof process.pid === 'number' && + typeof process.on === 'function' +}; + +// some kind of non-node environment, just no-op +/* istanbul ignore if */ +if (!processOk(process$1)) { + signalExit.exports = function () { + return function () {} + }; +} else { + var assert = require$$0$4; + var signals = requireSignals(); + var isWin = /^win/i.test(process$1.platform); + + var EE = require$$2; + /* istanbul ignore if */ + if (typeof EE !== 'function') { + EE = EE.EventEmitter; + } + + var emitter; + if (process$1.__signal_exit_emitter__) { + emitter = process$1.__signal_exit_emitter__; + } else { + emitter = process$1.__signal_exit_emitter__ = new EE(); + emitter.count = 0; + emitter.emitted = {}; + } + + // Because this emitter is a global, we have to check to see if a + // previous version of this library failed to enable infinite listeners. + // I know what you're about to say. But literally everything about + // signal-exit is a compromise with evil. Get used to it. + if (!emitter.infinite) { + emitter.setMaxListeners(Infinity); + emitter.infinite = true; + } + + signalExit.exports = function (cb, opts) { + /* istanbul ignore if */ + if (!processOk(commonjsGlobal.process)) { + return function () {} + } + assert.equal(typeof cb, 'function', 'a callback must be provided for exit handler'); + + if (loaded === false) { + load(); + } + + var ev = 'exit'; + if (opts && opts.alwaysLast) { + ev = 'afterexit'; + } + + var remove = function () { + emitter.removeListener(ev, cb); + if (emitter.listeners('exit').length === 0 && + emitter.listeners('afterexit').length === 0) { + unload(); + } + }; + emitter.on(ev, cb); + + return remove + }; + + var unload = function unload () { + if (!loaded || !processOk(commonjsGlobal.process)) { + return + } + loaded = false; + + signals.forEach(function (sig) { + try { + process$1.removeListener(sig, sigListeners[sig]); + } catch (er) {} + }); + process$1.emit = originalProcessEmit; + process$1.reallyExit = originalProcessReallyExit; + emitter.count -= 1; + }; + signalExit.exports.unload = unload; + + var emit = function emit (event, code, signal) { + /* istanbul ignore if */ + if (emitter.emitted[event]) { + return + } + emitter.emitted[event] = true; + emitter.emit(event, code, signal); + }; + + // { : , ... } + var sigListeners = {}; + signals.forEach(function (sig) { + sigListeners[sig] = function listener () { + /* istanbul ignore if */ + if (!processOk(commonjsGlobal.process)) { + return + } + // If there are no other listeners, an exit is coming! + // Simplest way: remove us and then re-send the signal. + // We know that this will kill the process, so we can + // safely emit now. + var listeners = process$1.listeners(sig); + if (listeners.length === emitter.count) { + unload(); + emit('exit', null, sig); + /* istanbul ignore next */ + emit('afterexit', null, sig); + /* istanbul ignore next */ + if (isWin && sig === 'SIGHUP') { + // "SIGHUP" throws an `ENOSYS` error on Windows, + // so use a supported signal instead + sig = 'SIGINT'; + } + /* istanbul ignore next */ + process$1.kill(process$1.pid, sig); + } + }; + }); + + signalExit.exports.signals = function () { + return signals + }; + + var loaded = false; + + var load = function load () { + if (loaded || !processOk(commonjsGlobal.process)) { + return + } + loaded = true; + + // This is the number of onSignalExit's that are in play. + // It's important so that we can count the correct number of + // listeners on signals, and don't wait for the other one to + // handle it instead of us. + emitter.count += 1; + + signals = signals.filter(function (sig) { + try { + process$1.on(sig, sigListeners[sig]); + return true + } catch (er) { + return false + } + }); + + process$1.emit = processEmit; + process$1.reallyExit = processReallyExit; + }; + signalExit.exports.load = load; + + var originalProcessReallyExit = process$1.reallyExit; + var processReallyExit = function processReallyExit (code) { + /* istanbul ignore if */ + if (!processOk(commonjsGlobal.process)) { + return + } + process$1.exitCode = code || /* istanbul ignore next */ 0; + emit('exit', process$1.exitCode, null); + /* istanbul ignore next */ + emit('afterexit', process$1.exitCode, null); + /* istanbul ignore next */ + originalProcessReallyExit.call(process$1, process$1.exitCode); + }; + + var originalProcessEmit = process$1.emit; + var processEmit = function processEmit (ev, arg) { + if (ev === 'exit' && processOk(commonjsGlobal.process)) { + /* istanbul ignore else */ + if (arg !== undefined) { + process$1.exitCode = arg; + } + var ret = originalProcessEmit.apply(this, arguments); + /* istanbul ignore next */ + emit('exit', process$1.exitCode, null); + /* istanbul ignore next */ + emit('afterexit', process$1.exitCode, null); + /* istanbul ignore next */ + return ret + } else { + return originalProcessEmit.apply(this, arguments) + } + }; +} + +var signalExitExports = signalExit.exports; + +const os = require$$0$3; +const onExit = signalExitExports; + +const DEFAULT_FORCE_KILL_TIMEOUT = 1000 * 5; + +// Monkey-patches `childProcess.kill()` to add `forceKillAfterTimeout` behavior +const spawnedKill$1 = (kill, signal = 'SIGTERM', options = {}) => { + const killResult = kill(signal); + setKillTimeout(kill, signal, options, killResult); + return killResult; +}; + +const setKillTimeout = (kill, signal, options, killResult) => { + if (!shouldForceKill(signal, options, killResult)) { + return; + } + + const timeout = getForceKillAfterTimeout(options); + const t = setTimeout(() => { + kill('SIGKILL'); + }, timeout); + + // Guarded because there's no `.unref()` when `execa` is used in the renderer + // process in Electron. This cannot be tested since we don't run tests in + // Electron. + // istanbul ignore else + if (t.unref) { + t.unref(); + } +}; + +const shouldForceKill = (signal, {forceKillAfterTimeout}, killResult) => { + return isSigterm(signal) && forceKillAfterTimeout !== false && killResult; +}; + +const isSigterm = signal => { + return signal === os.constants.signals.SIGTERM || + (typeof signal === 'string' && signal.toUpperCase() === 'SIGTERM'); +}; + +const getForceKillAfterTimeout = ({forceKillAfterTimeout = true}) => { + if (forceKillAfterTimeout === true) { + return DEFAULT_FORCE_KILL_TIMEOUT; + } + + if (!Number.isFinite(forceKillAfterTimeout) || forceKillAfterTimeout < 0) { + throw new TypeError(`Expected the \`forceKillAfterTimeout\` option to be a non-negative integer, got \`${forceKillAfterTimeout}\` (${typeof forceKillAfterTimeout})`); + } + + return forceKillAfterTimeout; +}; + +// `childProcess.cancel()` +const spawnedCancel$1 = (spawned, context) => { + const killResult = spawned.kill(); + + if (killResult) { + context.isCanceled = true; + } +}; + +const timeoutKill = (spawned, signal, reject) => { + spawned.kill(signal); + reject(Object.assign(new Error('Timed out'), {timedOut: true, signal})); +}; + +// `timeout` option handling +const setupTimeout$1 = (spawned, {timeout, killSignal = 'SIGTERM'}, spawnedPromise) => { + if (timeout === 0 || timeout === undefined) { + return spawnedPromise; + } + + let timeoutId; + const timeoutPromise = new Promise((resolve, reject) => { + timeoutId = setTimeout(() => { + timeoutKill(spawned, killSignal, reject); + }, timeout); + }); + + const safeSpawnedPromise = spawnedPromise.finally(() => { + clearTimeout(timeoutId); + }); + + return Promise.race([timeoutPromise, safeSpawnedPromise]); +}; + +const validateTimeout$1 = ({timeout}) => { + if (timeout !== undefined && (!Number.isFinite(timeout) || timeout < 0)) { + throw new TypeError(`Expected the \`timeout\` option to be a non-negative integer, got \`${timeout}\` (${typeof timeout})`); + } +}; + +// `cleanup` option handling +const setExitHandler$1 = async (spawned, {cleanup, detached}, timedPromise) => { + if (!cleanup || detached) { + return timedPromise; + } + + const removeExitHandler = onExit(() => { + spawned.kill(); + }); + + return timedPromise.finally(() => { + removeExitHandler(); + }); +}; + +var kill = { + spawnedKill: spawnedKill$1, + spawnedCancel: spawnedCancel$1, + setupTimeout: setupTimeout$1, + validateTimeout: validateTimeout$1, + setExitHandler: setExitHandler$1 +}; + +const isStream$1 = stream => + stream !== null && + typeof stream === 'object' && + typeof stream.pipe === 'function'; + +isStream$1.writable = stream => + isStream$1(stream) && + stream.writable !== false && + typeof stream._write === 'function' && + typeof stream._writableState === 'object'; + +isStream$1.readable = stream => + isStream$1(stream) && + stream.readable !== false && + typeof stream._read === 'function' && + typeof stream._readableState === 'object'; + +isStream$1.duplex = stream => + isStream$1.writable(stream) && + isStream$1.readable(stream); + +isStream$1.transform = stream => + isStream$1.duplex(stream) && + typeof stream._transform === 'function'; + +var isStream_1 = isStream$1; + +var getStream$2 = {exports: {}}; + +const {PassThrough: PassThroughStream} = require$$0$5; + +var bufferStream$1 = options => { + options = {...options}; + + const {array} = options; + let {encoding} = options; + const isBuffer = encoding === 'buffer'; + let objectMode = false; + + if (array) { + objectMode = !(encoding || isBuffer); + } else { + encoding = encoding || 'utf8'; + } + + if (isBuffer) { + encoding = null; + } + + const stream = new PassThroughStream({objectMode}); + + if (encoding) { + stream.setEncoding(encoding); + } + + let length = 0; + const chunks = []; + + stream.on('data', chunk => { + chunks.push(chunk); + + if (objectMode) { + length = chunks.length; + } else { + length += chunk.length; + } + }); + + stream.getBufferedValue = () => { + if (array) { + return chunks; + } + + return isBuffer ? Buffer.concat(chunks, length) : chunks.join(''); + }; + + stream.getBufferedLength = () => length; + + return stream; +}; + +const {constants: BufferConstants} = require$$0$6; +const stream$2 = require$$0$5; +const {promisify} = require$$2$1; +const bufferStream = bufferStream$1; + +const streamPipelinePromisified = promisify(stream$2.pipeline); + +class MaxBufferError extends Error { + constructor() { + super('maxBuffer exceeded'); + this.name = 'MaxBufferError'; + } +} + +async function getStream$1(inputStream, options) { + if (!inputStream) { + throw new Error('Expected a stream'); + } + + options = { + maxBuffer: Infinity, + ...options + }; + + const {maxBuffer} = options; + const stream = bufferStream(options); + + await new Promise((resolve, reject) => { + const rejectPromise = error => { + // Don't retrieve an oversized buffer. + if (error && stream.getBufferedLength() <= BufferConstants.MAX_LENGTH) { + error.bufferedData = stream.getBufferedValue(); + } + + reject(error); + }; + + (async () => { + try { + await streamPipelinePromisified(inputStream, stream); + resolve(); + } catch (error) { + rejectPromise(error); + } + })(); + + stream.on('data', () => { + if (stream.getBufferedLength() > maxBuffer) { + rejectPromise(new MaxBufferError()); + } + }); + }); + + return stream.getBufferedValue(); +} + +getStream$2.exports = getStream$1; +getStream$2.exports.buffer = (stream, options) => getStream$1(stream, {...options, encoding: 'buffer'}); +getStream$2.exports.array = (stream, options) => getStream$1(stream, {...options, array: true}); +getStream$2.exports.MaxBufferError = MaxBufferError; + +var getStreamExports = getStream$2.exports; + +const { PassThrough } = require$$0$5; + +var mergeStream$1 = function (/*streams...*/) { + var sources = []; + var output = new PassThrough({objectMode: true}); + + output.setMaxListeners(0); + + output.add = add; + output.isEmpty = isEmpty; + + output.on('unpipe', remove); + + Array.prototype.slice.call(arguments).forEach(add); + + return output + + function add (source) { + if (Array.isArray(source)) { + source.forEach(add); + return this + } + + sources.push(source); + source.once('end', remove.bind(null, source)); + source.once('error', output.emit.bind(output, 'error')); + source.pipe(output, {end: false}); + return this + } + + function isEmpty () { + return sources.length == 0; + } + + function remove (source) { + sources = sources.filter(function (it) { return it !== source }); + if (!sources.length && output.readable) { output.end(); } + } +}; + +const isStream = isStream_1; +const getStream = getStreamExports; +const mergeStream = mergeStream$1; + +// `input` option +const handleInput$1 = (spawned, input) => { + // Checking for stdin is workaround for https://github.com/nodejs/node/issues/26852 + // @todo remove `|| spawned.stdin === undefined` once we drop support for Node.js <=12.2.0 + if (input === undefined || spawned.stdin === undefined) { + return; + } + + if (isStream(input)) { + input.pipe(spawned.stdin); + } else { + spawned.stdin.end(input); + } +}; + +// `all` interleaves `stdout` and `stderr` +const makeAllStream$1 = (spawned, {all}) => { + if (!all || (!spawned.stdout && !spawned.stderr)) { + return; + } + + const mixed = mergeStream(); + + if (spawned.stdout) { + mixed.add(spawned.stdout); + } + + if (spawned.stderr) { + mixed.add(spawned.stderr); + } + + return mixed; +}; + +// On failure, `result.stdout|stderr|all` should contain the currently buffered stream +const getBufferedData = async (stream, streamPromise) => { + if (!stream) { + return; + } + + stream.destroy(); + + try { + return await streamPromise; + } catch (error) { + return error.bufferedData; + } +}; + +const getStreamPromise = (stream, {encoding, buffer, maxBuffer}) => { + if (!stream || !buffer) { + return; + } + + if (encoding) { + return getStream(stream, {encoding, maxBuffer}); + } + + return getStream.buffer(stream, {maxBuffer}); +}; + +// Retrieve result of child process: exit code, signal, error, streams (stdout/stderr/all) +const getSpawnedResult$1 = async ({stdout, stderr, all}, {encoding, buffer, maxBuffer}, processDone) => { + const stdoutPromise = getStreamPromise(stdout, {encoding, buffer, maxBuffer}); + const stderrPromise = getStreamPromise(stderr, {encoding, buffer, maxBuffer}); + const allPromise = getStreamPromise(all, {encoding, buffer, maxBuffer: maxBuffer * 2}); + + try { + return await Promise.all([processDone, stdoutPromise, stderrPromise, allPromise]); + } catch (error) { + return Promise.all([ + {error, signal: error.signal, timedOut: error.timedOut}, + getBufferedData(stdout, stdoutPromise), + getBufferedData(stderr, stderrPromise), + getBufferedData(all, allPromise) + ]); + } +}; + +const validateInputSync$1 = ({input}) => { + if (isStream(input)) { + throw new TypeError('The `input` option cannot be a stream in sync mode'); + } +}; + +var stream$1 = { + handleInput: handleInput$1, + makeAllStream: makeAllStream$1, + getSpawnedResult: getSpawnedResult$1, + validateInputSync: validateInputSync$1 +}; + +const nativePromisePrototype = (async () => {})().constructor.prototype; +const descriptors = ['then', 'catch', 'finally'].map(property => [ + property, + Reflect.getOwnPropertyDescriptor(nativePromisePrototype, property) +]); + +// The return value is a mixin of `childProcess` and `Promise` +const mergePromise$1 = (spawned, promise) => { + for (const [property, descriptor] of descriptors) { + // Starting the main `promise` is deferred to avoid consuming streams + const value = typeof promise === 'function' ? + (...args) => Reflect.apply(descriptor.value, promise(), args) : + descriptor.value.bind(promise); + + Reflect.defineProperty(spawned, property, {...descriptor, value}); + } + + return spawned; +}; + +// Use promises instead of `child_process` events +const getSpawnedPromise$1 = spawned => { + return new Promise((resolve, reject) => { + spawned.on('exit', (exitCode, signal) => { + resolve({exitCode, signal}); + }); + + spawned.on('error', error => { + reject(error); + }); + + if (spawned.stdin) { + spawned.stdin.on('error', error => { + reject(error); + }); + } + }); +}; + +var promise = { + mergePromise: mergePromise$1, + getSpawnedPromise: getSpawnedPromise$1 +}; + +const normalizeArgs = (file, args = []) => { + if (!Array.isArray(args)) { + return [file]; + } + + return [file, ...args]; +}; + +const NO_ESCAPE_REGEXP = /^[\w.-]+$/; +const DOUBLE_QUOTES_REGEXP = /"/g; + +const escapeArg = arg => { + if (typeof arg !== 'string' || NO_ESCAPE_REGEXP.test(arg)) { + return arg; + } + + return `"${arg.replace(DOUBLE_QUOTES_REGEXP, '\\"')}"`; +}; + +const joinCommand$1 = (file, args) => { + return normalizeArgs(file, args).join(' '); +}; + +const getEscapedCommand$1 = (file, args) => { + return normalizeArgs(file, args).map(arg => escapeArg(arg)).join(' '); +}; + +const SPACES_REGEXP = / +/g; + +// Handle `execa.command()` +const parseCommand$1 = command => { + const tokens = []; + for (const token of command.trim().split(SPACES_REGEXP)) { + // Allow spaces to be escaped by a backslash if not meant as a delimiter + const previousToken = tokens[tokens.length - 1]; + if (previousToken && previousToken.endsWith('\\')) { + // Merge previous token with current one + tokens[tokens.length - 1] = `${previousToken.slice(0, -1)} ${token}`; + } else { + tokens.push(token); + } + } + + return tokens; +}; + +var command = { + joinCommand: joinCommand$1, + getEscapedCommand: getEscapedCommand$1, + parseCommand: parseCommand$1 +}; + +const path = require$$0$1; +const childProcess = require$$0$2; +const crossSpawn = crossSpawnExports; +const stripFinalNewline = stripFinalNewline$1; +const npmRunPath = npmRunPathExports; +const onetime = onetimeExports; +const makeError = error; +const normalizeStdio = stdioExports; +const {spawnedKill, spawnedCancel, setupTimeout, validateTimeout, setExitHandler} = kill; +const {handleInput, getSpawnedResult, makeAllStream, validateInputSync} = stream$1; +const {mergePromise, getSpawnedPromise} = promise; +const {joinCommand, parseCommand, getEscapedCommand} = command; + +const DEFAULT_MAX_BUFFER = 1000 * 1000 * 100; + +const getEnv = ({env: envOption, extendEnv, preferLocal, localDir, execPath}) => { + const env = extendEnv ? {...process.env, ...envOption} : envOption; + + if (preferLocal) { + return npmRunPath.env({env, cwd: localDir, execPath}); + } + + return env; +}; + +const handleArguments = (file, args, options = {}) => { + const parsed = crossSpawn._parse(file, args, options); + file = parsed.command; + args = parsed.args; + options = parsed.options; + + options = { + maxBuffer: DEFAULT_MAX_BUFFER, + buffer: true, + stripFinalNewline: true, + extendEnv: true, + preferLocal: false, + localDir: options.cwd || process.cwd(), + execPath: process.execPath, + encoding: 'utf8', + reject: true, + cleanup: true, + all: false, + windowsHide: true, + ...options + }; + + options.env = getEnv(options); + + options.stdio = normalizeStdio(options); + + if (process.platform === 'win32' && path.basename(file, '.exe') === 'cmd') { + // #116 + args.unshift('/q'); + } + + return {file, args, options, parsed}; +}; + +const handleOutput = (options, value, error) => { + if (typeof value !== 'string' && !Buffer.isBuffer(value)) { + // When `execa.sync()` errors, we normalize it to '' to mimic `execa()` + return error === undefined ? undefined : ''; + } + + if (options.stripFinalNewline) { + return stripFinalNewline(value); + } + + return value; +}; + +const execa = (file, args, options) => { + const parsed = handleArguments(file, args, options); + const command = joinCommand(file, args); + const escapedCommand = getEscapedCommand(file, args); + + validateTimeout(parsed.options); + + let spawned; + try { + spawned = childProcess.spawn(parsed.file, parsed.args, parsed.options); + } catch (error) { + // Ensure the returned error is always both a promise and a child process + const dummySpawned = new childProcess.ChildProcess(); + const errorPromise = Promise.reject(makeError({ + error, + stdout: '', + stderr: '', + all: '', + command, + escapedCommand, + parsed, + timedOut: false, + isCanceled: false, + killed: false + })); + return mergePromise(dummySpawned, errorPromise); + } + + const spawnedPromise = getSpawnedPromise(spawned); + const timedPromise = setupTimeout(spawned, parsed.options, spawnedPromise); + const processDone = setExitHandler(spawned, parsed.options, timedPromise); + + const context = {isCanceled: false}; + + spawned.kill = spawnedKill.bind(null, spawned.kill.bind(spawned)); + spawned.cancel = spawnedCancel.bind(null, spawned, context); + + const handlePromise = async () => { + const [{error, exitCode, signal, timedOut}, stdoutResult, stderrResult, allResult] = await getSpawnedResult(spawned, parsed.options, processDone); + const stdout = handleOutput(parsed.options, stdoutResult); + const stderr = handleOutput(parsed.options, stderrResult); + const all = handleOutput(parsed.options, allResult); + + if (error || exitCode !== 0 || signal !== null) { + const returnedError = makeError({ + error, + exitCode, + signal, + stdout, + stderr, + all, + command, + escapedCommand, + parsed, + timedOut, + isCanceled: context.isCanceled, + killed: spawned.killed + }); + + if (!parsed.options.reject) { + return returnedError; + } + + throw returnedError; + } + + return { + command, + escapedCommand, + exitCode: 0, + stdout, + stderr, + all, + failed: false, + timedOut: false, + isCanceled: false, + killed: false + }; + }; + + const handlePromiseOnce = onetime(handlePromise); + + handleInput(spawned, parsed.options.input); + + spawned.all = makeAllStream(spawned, parsed.options); + + return mergePromise(spawned, handlePromiseOnce); +}; + +execa$2.exports = execa; + +execa$2.exports.sync = (file, args, options) => { + const parsed = handleArguments(file, args, options); + const command = joinCommand(file, args); + const escapedCommand = getEscapedCommand(file, args); + + validateInputSync(parsed.options); + + let result; + try { + result = childProcess.spawnSync(parsed.file, parsed.args, parsed.options); + } catch (error) { + throw makeError({ + error, + stdout: '', + stderr: '', + all: '', + command, + escapedCommand, + parsed, + timedOut: false, + isCanceled: false, + killed: false + }); + } + + const stdout = handleOutput(parsed.options, result.stdout, result.error); + const stderr = handleOutput(parsed.options, result.stderr, result.error); + + if (result.error || result.status !== 0 || result.signal !== null) { + const error = makeError({ + stdout, + stderr, + error: result.error, + signal: result.signal, + exitCode: result.status, + command, + escapedCommand, + parsed, + timedOut: result.error && result.error.code === 'ETIMEDOUT', + isCanceled: false, + killed: result.signal !== null + }); + + if (!parsed.options.reject) { + return error; + } + + throw error; + } + + return { + command, + escapedCommand, + exitCode: 0, + stdout, + stderr, + failed: false, + timedOut: false, + isCanceled: false, + killed: false + }; +}; + +execa$2.exports.command = (command, options) => { + const [file, ...args] = parseCommand(command); + return execa(file, args, options); +}; + +execa$2.exports.commandSync = (command, options) => { + const [file, ...args] = parseCommand(command); + return execa.sync(file, args, options); +}; + +execa$2.exports.node = (scriptPath, args, options = {}) => { + if (args && !Array.isArray(args) && typeof args === 'object') { + options = args; + args = []; + } + + const stdio = normalizeStdio.node(options); + const defaultExecArgv = process.execArgv.filter(arg => !arg.startsWith('--inspect')); + + const { + nodePath = process.execPath, + nodeOptions = defaultExecArgv + } = options; + + return execa( + nodePath, + [ + ...nodeOptions, + scriptPath, + ...(Array.isArray(args) ? args : []) + ], + { + ...options, + stdin: undefined, + stdout: undefined, + stderr: undefined, + stdio, + shell: false + } + ); +}; + +var execaExports = execa$2.exports; +var execa$1 = /*@__PURE__*/getDefaultExportFromCjs(execaExports); + +function ansiRegex({onlyFirst = false} = {}) { + const pattern = [ + '[\\u001B\\u009B][[\\]()#;?]*(?:(?:(?:(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]+)*|[a-zA-Z\\d]+(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]*)*)?\\u0007)', + '(?:(?:\\d{1,4}(?:;\\d{0,4})*)?[\\dA-PR-TZcf-ntqry=><~]))' + ].join('|'); + + return new RegExp(pattern, onlyFirst ? undefined : 'g'); +} + +function stripAnsi(string) { + if (typeof string !== 'string') { + throw new TypeError(`Expected a \`string\`, got \`${typeof string}\``); + } + + return string.replace(ansiRegex(), ''); +} + +const detectDefaultShell = () => { + const {env} = process$2; + + if (process$2.platform === 'win32') { + return env.COMSPEC || 'cmd.exe'; + } + + try { + const {shell} = node_os.userInfo(); + if (shell) { + return shell; + } + } catch {} + + if (process$2.platform === 'darwin') { + return env.SHELL || '/bin/zsh'; + } + + return env.SHELL || '/bin/sh'; +}; + +// Stores default shell when imported. +const defaultShell = detectDefaultShell(); + +const args = [ + '-ilc', + 'echo -n "_SHELL_ENV_DELIMITER_"; env; echo -n "_SHELL_ENV_DELIMITER_"; exit', +]; + +const env = { + // Disables Oh My Zsh auto-update thing that can block the process. + DISABLE_AUTO_UPDATE: 'true', +}; + +const parseEnv = env => { + env = env.split('_SHELL_ENV_DELIMITER_')[1]; + const returnValue = {}; + + for (const line of stripAnsi(env).split('\n').filter(line => Boolean(line))) { + const [key, ...values] = line.split('='); + returnValue[key] = values.join('='); + } + + return returnValue; +}; + +function shellEnvSync(shell) { + if (process$2.platform === 'win32') { + return process$2.env; + } + + try { + const {stdout} = execa$1.sync(shell || defaultShell, args, {env}); + return parseEnv(stdout); + } catch (error) { + if (shell) { + throw error; + } else { + return process$2.env; + } + } +} + +function shellPathSync() { + const {PATH} = shellEnvSync(); + return PATH; +} + +function fixPath() { + if (process$2.platform === 'win32') { + return; + } + + process$2.env.PATH = shellPathSync() || [ + './node_modules/.bin', + '/.nodebrew/current/bin', + '/usr/local/bin', + process$2.env.PATH, + ].join(':'); +} + +var lib = {}; + +var readable = {exports: {}}; + +var stream; +var hasRequiredStream; + +function requireStream () { + if (hasRequiredStream) return stream; + hasRequiredStream = 1; + stream = require$$0$5; + return stream; +} + +var buffer_list; +var hasRequiredBuffer_list; + +function requireBuffer_list () { + if (hasRequiredBuffer_list) return buffer_list; + hasRequiredBuffer_list = 1; + + function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; } + function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; } + function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } + function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, _toPropertyKey(descriptor.key), descriptor); } } + function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, "prototype", { writable: false }); return Constructor; } + function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return typeof key === "symbol" ? key : String(key); } + function _toPrimitive(input, hint) { if (typeof input !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (typeof res !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); } + var _require = require$$0$6, + Buffer = _require.Buffer; + var _require2 = require$$2$1, + inspect = _require2.inspect; + var custom = inspect && inspect.custom || 'inspect'; + function copyBuffer(src, target, offset) { + Buffer.prototype.copy.call(src, target, offset); + } + buffer_list = /*#__PURE__*/function () { + function BufferList() { + _classCallCheck(this, BufferList); + this.head = null; + this.tail = null; + this.length = 0; + } + _createClass(BufferList, [{ + key: "push", + value: function push(v) { + var entry = { + data: v, + next: null + }; + if (this.length > 0) this.tail.next = entry;else this.head = entry; + this.tail = entry; + ++this.length; + } + }, { + key: "unshift", + value: function unshift(v) { + var entry = { + data: v, + next: this.head + }; + if (this.length === 0) this.tail = entry; + this.head = entry; + ++this.length; + } + }, { + key: "shift", + value: function shift() { + if (this.length === 0) return; + var ret = this.head.data; + if (this.length === 1) this.head = this.tail = null;else this.head = this.head.next; + --this.length; + return ret; + } + }, { + key: "clear", + value: function clear() { + this.head = this.tail = null; + this.length = 0; + } + }, { + key: "join", + value: function join(s) { + if (this.length === 0) return ''; + var p = this.head; + var ret = '' + p.data; + while (p = p.next) ret += s + p.data; + return ret; + } + }, { + key: "concat", + value: function concat(n) { + if (this.length === 0) return Buffer.alloc(0); + var ret = Buffer.allocUnsafe(n >>> 0); + var p = this.head; + var i = 0; + while (p) { + copyBuffer(p.data, ret, i); + i += p.data.length; + p = p.next; + } + return ret; + } + + // Consumes a specified amount of bytes or characters from the buffered data. + }, { + key: "consume", + value: function consume(n, hasStrings) { + var ret; + if (n < this.head.data.length) { + // `slice` is the same for buffers and strings. + ret = this.head.data.slice(0, n); + this.head.data = this.head.data.slice(n); + } else if (n === this.head.data.length) { + // First chunk is a perfect match. + ret = this.shift(); + } else { + // Result spans more than one buffer. + ret = hasStrings ? this._getString(n) : this._getBuffer(n); + } + return ret; + } + }, { + key: "first", + value: function first() { + return this.head.data; + } + + // Consumes a specified amount of characters from the buffered data. + }, { + key: "_getString", + value: function _getString(n) { + var p = this.head; + var c = 1; + var ret = p.data; + n -= ret.length; + while (p = p.next) { + var str = p.data; + var nb = n > str.length ? str.length : n; + if (nb === str.length) ret += str;else ret += str.slice(0, n); + n -= nb; + if (n === 0) { + if (nb === str.length) { + ++c; + if (p.next) this.head = p.next;else this.head = this.tail = null; + } else { + this.head = p; + p.data = str.slice(nb); + } + break; + } + ++c; + } + this.length -= c; + return ret; + } + + // Consumes a specified amount of bytes from the buffered data. + }, { + key: "_getBuffer", + value: function _getBuffer(n) { + var ret = Buffer.allocUnsafe(n); + var p = this.head; + var c = 1; + p.data.copy(ret); + n -= p.data.length; + while (p = p.next) { + var buf = p.data; + var nb = n > buf.length ? buf.length : n; + buf.copy(ret, ret.length - n, 0, nb); + n -= nb; + if (n === 0) { + if (nb === buf.length) { + ++c; + if (p.next) this.head = p.next;else this.head = this.tail = null; + } else { + this.head = p; + p.data = buf.slice(nb); + } + break; + } + ++c; + } + this.length -= c; + return ret; + } + + // Make sure the linked list only shows the minimal necessary information. + }, { + key: custom, + value: function value(_, options) { + return inspect(this, _objectSpread(_objectSpread({}, options), {}, { + // Only inspect one level. + depth: 0, + // It should not recurse. + customInspect: false + })); + } + }]); + return BufferList; + }(); + return buffer_list; +} + +var destroy_1; +var hasRequiredDestroy; + +function requireDestroy () { + if (hasRequiredDestroy) return destroy_1; + hasRequiredDestroy = 1; + + // undocumented cb() API, needed for core, not for public API + function destroy(err, cb) { + var _this = this; + var readableDestroyed = this._readableState && this._readableState.destroyed; + var writableDestroyed = this._writableState && this._writableState.destroyed; + if (readableDestroyed || writableDestroyed) { + if (cb) { + cb(err); + } else if (err) { + if (!this._writableState) { + process.nextTick(emitErrorNT, this, err); + } else if (!this._writableState.errorEmitted) { + this._writableState.errorEmitted = true; + process.nextTick(emitErrorNT, this, err); + } + } + return this; + } + + // we set destroyed to true before firing error callbacks in order + // to make it re-entrance safe in case destroy() is called within callbacks + + if (this._readableState) { + this._readableState.destroyed = true; + } + + // if this is a duplex stream mark the writable part as destroyed as well + if (this._writableState) { + this._writableState.destroyed = true; + } + this._destroy(err || null, function (err) { + if (!cb && err) { + if (!_this._writableState) { + process.nextTick(emitErrorAndCloseNT, _this, err); + } else if (!_this._writableState.errorEmitted) { + _this._writableState.errorEmitted = true; + process.nextTick(emitErrorAndCloseNT, _this, err); + } else { + process.nextTick(emitCloseNT, _this); + } + } else if (cb) { + process.nextTick(emitCloseNT, _this); + cb(err); + } else { + process.nextTick(emitCloseNT, _this); + } + }); + return this; + } + function emitErrorAndCloseNT(self, err) { + emitErrorNT(self, err); + emitCloseNT(self); + } + function emitCloseNT(self) { + if (self._writableState && !self._writableState.emitClose) return; + if (self._readableState && !self._readableState.emitClose) return; + self.emit('close'); + } + function undestroy() { + if (this._readableState) { + this._readableState.destroyed = false; + this._readableState.reading = false; + this._readableState.ended = false; + this._readableState.endEmitted = false; + } + if (this._writableState) { + this._writableState.destroyed = false; + this._writableState.ended = false; + this._writableState.ending = false; + this._writableState.finalCalled = false; + this._writableState.prefinished = false; + this._writableState.finished = false; + this._writableState.errorEmitted = false; + } + } + function emitErrorNT(self, err) { + self.emit('error', err); + } + function errorOrDestroy(stream, err) { + // We have tests that rely on errors being emitted + // in the same tick, so changing this is semver major. + // For now when you opt-in to autoDestroy we allow + // the error to be emitted nextTick. In a future + // semver major update we should change the default to this. + + var rState = stream._readableState; + var wState = stream._writableState; + if (rState && rState.autoDestroy || wState && wState.autoDestroy) stream.destroy(err);else stream.emit('error', err); + } + destroy_1 = { + destroy: destroy, + undestroy: undestroy, + errorOrDestroy: errorOrDestroy + }; + return destroy_1; +} + +var errors = {}; + +var hasRequiredErrors; + +function requireErrors () { + if (hasRequiredErrors) return errors; + hasRequiredErrors = 1; + + const codes = {}; + + function createErrorType(code, message, Base) { + if (!Base) { + Base = Error; + } + + function getMessage (arg1, arg2, arg3) { + if (typeof message === 'string') { + return message + } else { + return message(arg1, arg2, arg3) + } + } + + class NodeError extends Base { + constructor (arg1, arg2, arg3) { + super(getMessage(arg1, arg2, arg3)); + } + } + + NodeError.prototype.name = Base.name; + NodeError.prototype.code = code; + + codes[code] = NodeError; + } + + // https://github.com/nodejs/node/blob/v10.8.0/lib/internal/errors.js + function oneOf(expected, thing) { + if (Array.isArray(expected)) { + const len = expected.length; + expected = expected.map((i) => String(i)); + if (len > 2) { + return `one of ${thing} ${expected.slice(0, len - 1).join(', ')}, or ` + + expected[len - 1]; + } else if (len === 2) { + return `one of ${thing} ${expected[0]} or ${expected[1]}`; + } else { + return `of ${thing} ${expected[0]}`; + } + } else { + return `of ${thing} ${String(expected)}`; + } + } + + // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/startsWith + function startsWith(str, search, pos) { + return str.substr(!pos || pos < 0 ? 0 : +pos, search.length) === search; + } + + // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/endsWith + function endsWith(str, search, this_len) { + if (this_len === undefined || this_len > str.length) { + this_len = str.length; + } + return str.substring(this_len - search.length, this_len) === search; + } + + // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/includes + function includes(str, search, start) { + if (typeof start !== 'number') { + start = 0; + } + + if (start + search.length > str.length) { + return false; + } else { + return str.indexOf(search, start) !== -1; + } + } + + createErrorType('ERR_INVALID_OPT_VALUE', function (name, value) { + return 'The value "' + value + '" is invalid for option "' + name + '"' + }, TypeError); + createErrorType('ERR_INVALID_ARG_TYPE', function (name, expected, actual) { + // determiner: 'must be' or 'must not be' + let determiner; + if (typeof expected === 'string' && startsWith(expected, 'not ')) { + determiner = 'must not be'; + expected = expected.replace(/^not /, ''); + } else { + determiner = 'must be'; + } + + let msg; + if (endsWith(name, ' argument')) { + // For cases like 'first argument' + msg = `The ${name} ${determiner} ${oneOf(expected, 'type')}`; + } else { + const type = includes(name, '.') ? 'property' : 'argument'; + msg = `The "${name}" ${type} ${determiner} ${oneOf(expected, 'type')}`; + } + + msg += `. Received type ${typeof actual}`; + return msg; + }, TypeError); + createErrorType('ERR_STREAM_PUSH_AFTER_EOF', 'stream.push() after EOF'); + createErrorType('ERR_METHOD_NOT_IMPLEMENTED', function (name) { + return 'The ' + name + ' method is not implemented' + }); + createErrorType('ERR_STREAM_PREMATURE_CLOSE', 'Premature close'); + createErrorType('ERR_STREAM_DESTROYED', function (name) { + return 'Cannot call ' + name + ' after a stream was destroyed'; + }); + createErrorType('ERR_MULTIPLE_CALLBACK', 'Callback called multiple times'); + createErrorType('ERR_STREAM_CANNOT_PIPE', 'Cannot pipe, not readable'); + createErrorType('ERR_STREAM_WRITE_AFTER_END', 'write after end'); + createErrorType('ERR_STREAM_NULL_VALUES', 'May not write null values to stream', TypeError); + createErrorType('ERR_UNKNOWN_ENCODING', function (arg) { + return 'Unknown encoding: ' + arg + }, TypeError); + createErrorType('ERR_STREAM_UNSHIFT_AFTER_END_EVENT', 'stream.unshift() after end event'); + + errors.codes = codes; + return errors; +} + +var state; +var hasRequiredState; + +function requireState () { + if (hasRequiredState) return state; + hasRequiredState = 1; + + var ERR_INVALID_OPT_VALUE = requireErrors().codes.ERR_INVALID_OPT_VALUE; + function highWaterMarkFrom(options, isDuplex, duplexKey) { + return options.highWaterMark != null ? options.highWaterMark : isDuplex ? options[duplexKey] : null; + } + function getHighWaterMark(state, options, duplexKey, isDuplex) { + var hwm = highWaterMarkFrom(options, isDuplex, duplexKey); + if (hwm != null) { + if (!(isFinite(hwm) && Math.floor(hwm) === hwm) || hwm < 0) { + var name = isDuplex ? duplexKey : 'highWaterMark'; + throw new ERR_INVALID_OPT_VALUE(name, hwm); + } + return Math.floor(hwm); + } + + // Default value + return state.objectMode ? 16 : 16 * 1024; + } + state = { + getHighWaterMark: getHighWaterMark + }; + return state; +} + +var inherits = {exports: {}}; + +var inherits_browser = {exports: {}}; + +var hasRequiredInherits_browser; + +function requireInherits_browser () { + if (hasRequiredInherits_browser) return inherits_browser.exports; + hasRequiredInherits_browser = 1; + if (typeof Object.create === 'function') { + // implementation from standard node.js 'util' module + inherits_browser.exports = function inherits(ctor, superCtor) { + if (superCtor) { + ctor.super_ = superCtor; + ctor.prototype = Object.create(superCtor.prototype, { + constructor: { + value: ctor, + enumerable: false, + writable: true, + configurable: true + } + }); + } + }; + } else { + // old school shim for old browsers + inherits_browser.exports = function inherits(ctor, superCtor) { + if (superCtor) { + ctor.super_ = superCtor; + var TempCtor = function () {}; + TempCtor.prototype = superCtor.prototype; + ctor.prototype = new TempCtor(); + ctor.prototype.constructor = ctor; + } + }; + } + return inherits_browser.exports; +} + +var hasRequiredInherits; + +function requireInherits () { + if (hasRequiredInherits) return inherits.exports; + hasRequiredInherits = 1; + try { + var util = require('util'); + /* istanbul ignore next */ + if (typeof util.inherits !== 'function') throw ''; + inherits.exports = util.inherits; + } catch (e) { + /* istanbul ignore next */ + inherits.exports = requireInherits_browser(); + } + return inherits.exports; +} + +var node; +var hasRequiredNode; + +function requireNode () { + if (hasRequiredNode) return node; + hasRequiredNode = 1; + /** + * For Node.js, simply re-export the core `util.deprecate` function. + */ + + node = require$$2$1.deprecate; + return node; +} + +var _stream_writable; +var hasRequired_stream_writable; + +function require_stream_writable () { + if (hasRequired_stream_writable) return _stream_writable; + hasRequired_stream_writable = 1; + + _stream_writable = Writable; + + // It seems a linked list but it is not + // there will be only 2 of these for each stream + function CorkedRequest(state) { + var _this = this; + this.next = null; + this.entry = null; + this.finish = function () { + onCorkedFinish(_this, state); + }; + } + /* */ + + /**/ + var Duplex; + /**/ + + Writable.WritableState = WritableState; + + /**/ + var internalUtil = { + deprecate: requireNode() + }; + /**/ + + /**/ + var Stream = requireStream(); + /**/ + + var Buffer = require$$0$6.Buffer; + var OurUint8Array = (typeof commonjsGlobal !== 'undefined' ? commonjsGlobal : typeof window !== 'undefined' ? window : typeof self !== 'undefined' ? self : {}).Uint8Array || function () {}; + function _uint8ArrayToBuffer(chunk) { + return Buffer.from(chunk); + } + function _isUint8Array(obj) { + return Buffer.isBuffer(obj) || obj instanceof OurUint8Array; + } + var destroyImpl = requireDestroy(); + var _require = requireState(), + getHighWaterMark = _require.getHighWaterMark; + var _require$codes = requireErrors().codes, + ERR_INVALID_ARG_TYPE = _require$codes.ERR_INVALID_ARG_TYPE, + ERR_METHOD_NOT_IMPLEMENTED = _require$codes.ERR_METHOD_NOT_IMPLEMENTED, + ERR_MULTIPLE_CALLBACK = _require$codes.ERR_MULTIPLE_CALLBACK, + ERR_STREAM_CANNOT_PIPE = _require$codes.ERR_STREAM_CANNOT_PIPE, + ERR_STREAM_DESTROYED = _require$codes.ERR_STREAM_DESTROYED, + ERR_STREAM_NULL_VALUES = _require$codes.ERR_STREAM_NULL_VALUES, + ERR_STREAM_WRITE_AFTER_END = _require$codes.ERR_STREAM_WRITE_AFTER_END, + ERR_UNKNOWN_ENCODING = _require$codes.ERR_UNKNOWN_ENCODING; + var errorOrDestroy = destroyImpl.errorOrDestroy; + requireInherits()(Writable, Stream); + function nop() {} + function WritableState(options, stream, isDuplex) { + Duplex = Duplex || require_stream_duplex(); + options = options || {}; + + // Duplex streams are both readable and writable, but share + // the same options object. + // However, some cases require setting options to different + // values for the readable and the writable sides of the duplex stream, + // e.g. options.readableObjectMode vs. options.writableObjectMode, etc. + if (typeof isDuplex !== 'boolean') isDuplex = stream instanceof Duplex; + + // object stream flag to indicate whether or not this stream + // contains buffers or objects. + this.objectMode = !!options.objectMode; + if (isDuplex) this.objectMode = this.objectMode || !!options.writableObjectMode; + + // the point at which write() starts returning false + // Note: 0 is a valid value, means that we always return false if + // the entire buffer is not flushed immediately on write() + this.highWaterMark = getHighWaterMark(this, options, 'writableHighWaterMark', isDuplex); + + // if _final has been called + this.finalCalled = false; + + // drain event flag. + this.needDrain = false; + // at the start of calling end() + this.ending = false; + // when end() has been called, and returned + this.ended = false; + // when 'finish' is emitted + this.finished = false; + + // has it been destroyed + this.destroyed = false; + + // should we decode strings into buffers before passing to _write? + // this is here so that some node-core streams can optimize string + // handling at a lower level. + var noDecode = options.decodeStrings === false; + this.decodeStrings = !noDecode; + + // Crypto is kind of old and crusty. Historically, its default string + // encoding is 'binary' so we have to make this configurable. + // Everything else in the universe uses 'utf8', though. + this.defaultEncoding = options.defaultEncoding || 'utf8'; + + // not an actual buffer we keep track of, but a measurement + // of how much we're waiting to get pushed to some underlying + // socket or file. + this.length = 0; + + // a flag to see when we're in the middle of a write. + this.writing = false; + + // when true all writes will be buffered until .uncork() call + this.corked = 0; + + // a flag to be able to tell if the onwrite cb is called immediately, + // or on a later tick. We set this to true at first, because any + // actions that shouldn't happen until "later" should generally also + // not happen before the first write call. + this.sync = true; + + // a flag to know if we're processing previously buffered items, which + // may call the _write() callback in the same tick, so that we don't + // end up in an overlapped onwrite situation. + this.bufferProcessing = false; + + // the callback that's passed to _write(chunk,cb) + this.onwrite = function (er) { + onwrite(stream, er); + }; + + // the callback that the user supplies to write(chunk,encoding,cb) + this.writecb = null; + + // the amount that is being written when _write is called. + this.writelen = 0; + this.bufferedRequest = null; + this.lastBufferedRequest = null; + + // number of pending user-supplied write callbacks + // this must be 0 before 'finish' can be emitted + this.pendingcb = 0; + + // emit prefinish if the only thing we're waiting for is _write cbs + // This is relevant for synchronous Transform streams + this.prefinished = false; + + // True if the error was already emitted and should not be thrown again + this.errorEmitted = false; + + // Should close be emitted on destroy. Defaults to true. + this.emitClose = options.emitClose !== false; + + // Should .destroy() be called after 'finish' (and potentially 'end') + this.autoDestroy = !!options.autoDestroy; + + // count buffered requests + this.bufferedRequestCount = 0; + + // allocate the first CorkedRequest, there is always + // one allocated and free to use, and we maintain at most two + this.corkedRequestsFree = new CorkedRequest(this); + } + WritableState.prototype.getBuffer = function getBuffer() { + var current = this.bufferedRequest; + var out = []; + while (current) { + out.push(current); + current = current.next; + } + return out; + }; + (function () { + try { + Object.defineProperty(WritableState.prototype, 'buffer', { + get: internalUtil.deprecate(function writableStateBufferGetter() { + return this.getBuffer(); + }, '_writableState.buffer is deprecated. Use _writableState.getBuffer ' + 'instead.', 'DEP0003') + }); + } catch (_) {} + })(); + + // Test _writableState for inheritance to account for Duplex streams, + // whose prototype chain only points to Readable. + var realHasInstance; + if (typeof Symbol === 'function' && Symbol.hasInstance && typeof Function.prototype[Symbol.hasInstance] === 'function') { + realHasInstance = Function.prototype[Symbol.hasInstance]; + Object.defineProperty(Writable, Symbol.hasInstance, { + value: function value(object) { + if (realHasInstance.call(this, object)) return true; + if (this !== Writable) return false; + return object && object._writableState instanceof WritableState; + } + }); + } else { + realHasInstance = function realHasInstance(object) { + return object instanceof this; + }; + } + function Writable(options) { + Duplex = Duplex || require_stream_duplex(); + + // Writable ctor is applied to Duplexes, too. + // `realHasInstance` is necessary because using plain `instanceof` + // would return false, as no `_writableState` property is attached. + + // Trying to use the custom `instanceof` for Writable here will also break the + // Node.js LazyTransform implementation, which has a non-trivial getter for + // `_writableState` that would lead to infinite recursion. + + // Checking for a Stream.Duplex instance is faster here instead of inside + // the WritableState constructor, at least with V8 6.5 + var isDuplex = this instanceof Duplex; + if (!isDuplex && !realHasInstance.call(Writable, this)) return new Writable(options); + this._writableState = new WritableState(options, this, isDuplex); + + // legacy. + this.writable = true; + if (options) { + if (typeof options.write === 'function') this._write = options.write; + if (typeof options.writev === 'function') this._writev = options.writev; + if (typeof options.destroy === 'function') this._destroy = options.destroy; + if (typeof options.final === 'function') this._final = options.final; + } + Stream.call(this); + } + + // Otherwise people can pipe Writable streams, which is just wrong. + Writable.prototype.pipe = function () { + errorOrDestroy(this, new ERR_STREAM_CANNOT_PIPE()); + }; + function writeAfterEnd(stream, cb) { + var er = new ERR_STREAM_WRITE_AFTER_END(); + // TODO: defer error events consistently everywhere, not just the cb + errorOrDestroy(stream, er); + process.nextTick(cb, er); + } + + // Checks that a user-supplied chunk is valid, especially for the particular + // mode the stream is in. Currently this means that `null` is never accepted + // and undefined/non-string values are only allowed in object mode. + function validChunk(stream, state, chunk, cb) { + var er; + if (chunk === null) { + er = new ERR_STREAM_NULL_VALUES(); + } else if (typeof chunk !== 'string' && !state.objectMode) { + er = new ERR_INVALID_ARG_TYPE('chunk', ['string', 'Buffer'], chunk); + } + if (er) { + errorOrDestroy(stream, er); + process.nextTick(cb, er); + return false; + } + return true; + } + Writable.prototype.write = function (chunk, encoding, cb) { + var state = this._writableState; + var ret = false; + var isBuf = !state.objectMode && _isUint8Array(chunk); + if (isBuf && !Buffer.isBuffer(chunk)) { + chunk = _uint8ArrayToBuffer(chunk); + } + if (typeof encoding === 'function') { + cb = encoding; + encoding = null; + } + if (isBuf) encoding = 'buffer';else if (!encoding) encoding = state.defaultEncoding; + if (typeof cb !== 'function') cb = nop; + if (state.ending) writeAfterEnd(this, cb);else if (isBuf || validChunk(this, state, chunk, cb)) { + state.pendingcb++; + ret = writeOrBuffer(this, state, isBuf, chunk, encoding, cb); + } + return ret; + }; + Writable.prototype.cork = function () { + this._writableState.corked++; + }; + Writable.prototype.uncork = function () { + var state = this._writableState; + if (state.corked) { + state.corked--; + if (!state.writing && !state.corked && !state.bufferProcessing && state.bufferedRequest) clearBuffer(this, state); + } + }; + Writable.prototype.setDefaultEncoding = function setDefaultEncoding(encoding) { + // node::ParseEncoding() requires lower case. + if (typeof encoding === 'string') encoding = encoding.toLowerCase(); + if (!(['hex', 'utf8', 'utf-8', 'ascii', 'binary', 'base64', 'ucs2', 'ucs-2', 'utf16le', 'utf-16le', 'raw'].indexOf((encoding + '').toLowerCase()) > -1)) throw new ERR_UNKNOWN_ENCODING(encoding); + this._writableState.defaultEncoding = encoding; + return this; + }; + Object.defineProperty(Writable.prototype, 'writableBuffer', { + // making it explicit this property is not enumerable + // because otherwise some prototype manipulation in + // userland will fail + enumerable: false, + get: function get() { + return this._writableState && this._writableState.getBuffer(); + } + }); + function decodeChunk(state, chunk, encoding) { + if (!state.objectMode && state.decodeStrings !== false && typeof chunk === 'string') { + chunk = Buffer.from(chunk, encoding); + } + return chunk; + } + Object.defineProperty(Writable.prototype, 'writableHighWaterMark', { + // making it explicit this property is not enumerable + // because otherwise some prototype manipulation in + // userland will fail + enumerable: false, + get: function get() { + return this._writableState.highWaterMark; + } + }); + + // if we're already writing something, then just put this + // in the queue, and wait our turn. Otherwise, call _write + // If we return false, then we need a drain event, so set that flag. + function writeOrBuffer(stream, state, isBuf, chunk, encoding, cb) { + if (!isBuf) { + var newChunk = decodeChunk(state, chunk, encoding); + if (chunk !== newChunk) { + isBuf = true; + encoding = 'buffer'; + chunk = newChunk; + } + } + var len = state.objectMode ? 1 : chunk.length; + state.length += len; + var ret = state.length < state.highWaterMark; + // we must ensure that previous needDrain will not be reset to false. + if (!ret) state.needDrain = true; + if (state.writing || state.corked) { + var last = state.lastBufferedRequest; + state.lastBufferedRequest = { + chunk: chunk, + encoding: encoding, + isBuf: isBuf, + callback: cb, + next: null + }; + if (last) { + last.next = state.lastBufferedRequest; + } else { + state.bufferedRequest = state.lastBufferedRequest; + } + state.bufferedRequestCount += 1; + } else { + doWrite(stream, state, false, len, chunk, encoding, cb); + } + return ret; + } + function doWrite(stream, state, writev, len, chunk, encoding, cb) { + state.writelen = len; + state.writecb = cb; + state.writing = true; + state.sync = true; + if (state.destroyed) state.onwrite(new ERR_STREAM_DESTROYED('write'));else if (writev) stream._writev(chunk, state.onwrite);else stream._write(chunk, encoding, state.onwrite); + state.sync = false; + } + function onwriteError(stream, state, sync, er, cb) { + --state.pendingcb; + if (sync) { + // defer the callback if we are being called synchronously + // to avoid piling up things on the stack + process.nextTick(cb, er); + // this can emit finish, and it will always happen + // after error + process.nextTick(finishMaybe, stream, state); + stream._writableState.errorEmitted = true; + errorOrDestroy(stream, er); + } else { + // the caller expect this to happen before if + // it is async + cb(er); + stream._writableState.errorEmitted = true; + errorOrDestroy(stream, er); + // this can emit finish, but finish must + // always follow error + finishMaybe(stream, state); + } + } + function onwriteStateUpdate(state) { + state.writing = false; + state.writecb = null; + state.length -= state.writelen; + state.writelen = 0; + } + function onwrite(stream, er) { + var state = stream._writableState; + var sync = state.sync; + var cb = state.writecb; + if (typeof cb !== 'function') throw new ERR_MULTIPLE_CALLBACK(); + onwriteStateUpdate(state); + if (er) onwriteError(stream, state, sync, er, cb);else { + // Check if we're actually ready to finish, but don't emit yet + var finished = needFinish(state) || stream.destroyed; + if (!finished && !state.corked && !state.bufferProcessing && state.bufferedRequest) { + clearBuffer(stream, state); + } + if (sync) { + process.nextTick(afterWrite, stream, state, finished, cb); + } else { + afterWrite(stream, state, finished, cb); + } + } + } + function afterWrite(stream, state, finished, cb) { + if (!finished) onwriteDrain(stream, state); + state.pendingcb--; + cb(); + finishMaybe(stream, state); + } + + // Must force callback to be called on nextTick, so that we don't + // emit 'drain' before the write() consumer gets the 'false' return + // value, and has a chance to attach a 'drain' listener. + function onwriteDrain(stream, state) { + if (state.length === 0 && state.needDrain) { + state.needDrain = false; + stream.emit('drain'); + } + } + + // if there's something in the buffer waiting, then process it + function clearBuffer(stream, state) { + state.bufferProcessing = true; + var entry = state.bufferedRequest; + if (stream._writev && entry && entry.next) { + // Fast case, write everything using _writev() + var l = state.bufferedRequestCount; + var buffer = new Array(l); + var holder = state.corkedRequestsFree; + holder.entry = entry; + var count = 0; + var allBuffers = true; + while (entry) { + buffer[count] = entry; + if (!entry.isBuf) allBuffers = false; + entry = entry.next; + count += 1; + } + buffer.allBuffers = allBuffers; + doWrite(stream, state, true, state.length, buffer, '', holder.finish); + + // doWrite is almost always async, defer these to save a bit of time + // as the hot path ends with doWrite + state.pendingcb++; + state.lastBufferedRequest = null; + if (holder.next) { + state.corkedRequestsFree = holder.next; + holder.next = null; + } else { + state.corkedRequestsFree = new CorkedRequest(state); + } + state.bufferedRequestCount = 0; + } else { + // Slow case, write chunks one-by-one + while (entry) { + var chunk = entry.chunk; + var encoding = entry.encoding; + var cb = entry.callback; + var len = state.objectMode ? 1 : chunk.length; + doWrite(stream, state, false, len, chunk, encoding, cb); + entry = entry.next; + state.bufferedRequestCount--; + // if we didn't call the onwrite immediately, then + // it means that we need to wait until it does. + // also, that means that the chunk and cb are currently + // being processed, so move the buffer counter past them. + if (state.writing) { + break; + } + } + if (entry === null) state.lastBufferedRequest = null; + } + state.bufferedRequest = entry; + state.bufferProcessing = false; + } + Writable.prototype._write = function (chunk, encoding, cb) { + cb(new ERR_METHOD_NOT_IMPLEMENTED('_write()')); + }; + Writable.prototype._writev = null; + Writable.prototype.end = function (chunk, encoding, cb) { + var state = this._writableState; + if (typeof chunk === 'function') { + cb = chunk; + chunk = null; + encoding = null; + } else if (typeof encoding === 'function') { + cb = encoding; + encoding = null; + } + if (chunk !== null && chunk !== undefined) this.write(chunk, encoding); + + // .end() fully uncorks + if (state.corked) { + state.corked = 1; + this.uncork(); + } + + // ignore unnecessary end() calls. + if (!state.ending) endWritable(this, state, cb); + return this; + }; + Object.defineProperty(Writable.prototype, 'writableLength', { + // making it explicit this property is not enumerable + // because otherwise some prototype manipulation in + // userland will fail + enumerable: false, + get: function get() { + return this._writableState.length; + } + }); + function needFinish(state) { + return state.ending && state.length === 0 && state.bufferedRequest === null && !state.finished && !state.writing; + } + function callFinal(stream, state) { + stream._final(function (err) { + state.pendingcb--; + if (err) { + errorOrDestroy(stream, err); + } + state.prefinished = true; + stream.emit('prefinish'); + finishMaybe(stream, state); + }); + } + function prefinish(stream, state) { + if (!state.prefinished && !state.finalCalled) { + if (typeof stream._final === 'function' && !state.destroyed) { + state.pendingcb++; + state.finalCalled = true; + process.nextTick(callFinal, stream, state); + } else { + state.prefinished = true; + stream.emit('prefinish'); + } + } + } + function finishMaybe(stream, state) { + var need = needFinish(state); + if (need) { + prefinish(stream, state); + if (state.pendingcb === 0) { + state.finished = true; + stream.emit('finish'); + if (state.autoDestroy) { + // In case of duplex streams we need a way to detect + // if the readable side is ready for autoDestroy as well + var rState = stream._readableState; + if (!rState || rState.autoDestroy && rState.endEmitted) { + stream.destroy(); + } + } + } + } + return need; + } + function endWritable(stream, state, cb) { + state.ending = true; + finishMaybe(stream, state); + if (cb) { + if (state.finished) process.nextTick(cb);else stream.once('finish', cb); + } + state.ended = true; + stream.writable = false; + } + function onCorkedFinish(corkReq, state, err) { + var entry = corkReq.entry; + corkReq.entry = null; + while (entry) { + var cb = entry.callback; + state.pendingcb--; + cb(err); + entry = entry.next; + } + + // reuse the free corkReq. + state.corkedRequestsFree.next = corkReq; + } + Object.defineProperty(Writable.prototype, 'destroyed', { + // making it explicit this property is not enumerable + // because otherwise some prototype manipulation in + // userland will fail + enumerable: false, + get: function get() { + if (this._writableState === undefined) { + return false; + } + return this._writableState.destroyed; + }, + set: function set(value) { + // we ignore the value if the stream + // has not been initialized yet + if (!this._writableState) { + return; + } + + // backward compatibility, the user is explicitly + // managing destroyed + this._writableState.destroyed = value; + } + }); + Writable.prototype.destroy = destroyImpl.destroy; + Writable.prototype._undestroy = destroyImpl.undestroy; + Writable.prototype._destroy = function (err, cb) { + cb(err); + }; + return _stream_writable; +} + +var _stream_duplex; +var hasRequired_stream_duplex; + +function require_stream_duplex () { + if (hasRequired_stream_duplex) return _stream_duplex; + hasRequired_stream_duplex = 1; + + /**/ + var objectKeys = Object.keys || function (obj) { + var keys = []; + for (var key in obj) keys.push(key); + return keys; + }; + /**/ + + _stream_duplex = Duplex; + var Readable = require_stream_readable(); + var Writable = require_stream_writable(); + requireInherits()(Duplex, Readable); + { + // Allow the keys array to be GC'ed. + var keys = objectKeys(Writable.prototype); + for (var v = 0; v < keys.length; v++) { + var method = keys[v]; + if (!Duplex.prototype[method]) Duplex.prototype[method] = Writable.prototype[method]; + } + } + function Duplex(options) { + if (!(this instanceof Duplex)) return new Duplex(options); + Readable.call(this, options); + Writable.call(this, options); + this.allowHalfOpen = true; + if (options) { + if (options.readable === false) this.readable = false; + if (options.writable === false) this.writable = false; + if (options.allowHalfOpen === false) { + this.allowHalfOpen = false; + this.once('end', onend); + } + } + } + Object.defineProperty(Duplex.prototype, 'writableHighWaterMark', { + // making it explicit this property is not enumerable + // because otherwise some prototype manipulation in + // userland will fail + enumerable: false, + get: function get() { + return this._writableState.highWaterMark; + } + }); + Object.defineProperty(Duplex.prototype, 'writableBuffer', { + // making it explicit this property is not enumerable + // because otherwise some prototype manipulation in + // userland will fail + enumerable: false, + get: function get() { + return this._writableState && this._writableState.getBuffer(); + } + }); + Object.defineProperty(Duplex.prototype, 'writableLength', { + // making it explicit this property is not enumerable + // because otherwise some prototype manipulation in + // userland will fail + enumerable: false, + get: function get() { + return this._writableState.length; + } + }); + + // the no-half-open enforcer + function onend() { + // If the writable side ended, then we're ok. + if (this._writableState.ended) return; + + // no more data can be written. + // But allow more writes to happen in this tick. + process.nextTick(onEndNT, this); + } + function onEndNT(self) { + self.end(); + } + Object.defineProperty(Duplex.prototype, 'destroyed', { + // making it explicit this property is not enumerable + // because otherwise some prototype manipulation in + // userland will fail + enumerable: false, + get: function get() { + if (this._readableState === undefined || this._writableState === undefined) { + return false; + } + return this._readableState.destroyed && this._writableState.destroyed; + }, + set: function set(value) { + // we ignore the value if the stream + // has not been initialized yet + if (this._readableState === undefined || this._writableState === undefined) { + return; + } + + // backward compatibility, the user is explicitly + // managing destroyed + this._readableState.destroyed = value; + this._writableState.destroyed = value; + } + }); + return _stream_duplex; +} + +var string_decoder = {}; + +var safeBuffer = {exports: {}}; + +/*! safe-buffer. MIT License. Feross Aboukhadijeh */ + +var hasRequiredSafeBuffer; + +function requireSafeBuffer () { + if (hasRequiredSafeBuffer) return safeBuffer.exports; + hasRequiredSafeBuffer = 1; + (function (module, exports) { + /* eslint-disable node/no-deprecated-api */ + var buffer = require$$0$6; + var Buffer = buffer.Buffer; + + // alternative to using Object.keys for old browsers + function copyProps (src, dst) { + for (var key in src) { + dst[key] = src[key]; + } + } + if (Buffer.from && Buffer.alloc && Buffer.allocUnsafe && Buffer.allocUnsafeSlow) { + module.exports = buffer; + } else { + // Copy properties from require('buffer') + copyProps(buffer, exports); + exports.Buffer = SafeBuffer; + } + + function SafeBuffer (arg, encodingOrOffset, length) { + return Buffer(arg, encodingOrOffset, length) + } + + SafeBuffer.prototype = Object.create(Buffer.prototype); + + // Copy static methods from Buffer + copyProps(Buffer, SafeBuffer); + + SafeBuffer.from = function (arg, encodingOrOffset, length) { + if (typeof arg === 'number') { + throw new TypeError('Argument must not be a number') + } + return Buffer(arg, encodingOrOffset, length) + }; + + SafeBuffer.alloc = function (size, fill, encoding) { + if (typeof size !== 'number') { + throw new TypeError('Argument must be a number') + } + var buf = Buffer(size); + if (fill !== undefined) { + if (typeof encoding === 'string') { + buf.fill(fill, encoding); + } else { + buf.fill(fill); + } + } else { + buf.fill(0); + } + return buf + }; + + SafeBuffer.allocUnsafe = function (size) { + if (typeof size !== 'number') { + throw new TypeError('Argument must be a number') + } + return Buffer(size) + }; + + SafeBuffer.allocUnsafeSlow = function (size) { + if (typeof size !== 'number') { + throw new TypeError('Argument must be a number') + } + return buffer.SlowBuffer(size) + }; + } (safeBuffer, safeBuffer.exports)); + return safeBuffer.exports; +} + +var hasRequiredString_decoder; + +function requireString_decoder () { + if (hasRequiredString_decoder) return string_decoder; + hasRequiredString_decoder = 1; + + /**/ + + var Buffer = requireSafeBuffer().Buffer; + /**/ + + var isEncoding = Buffer.isEncoding || function (encoding) { + encoding = '' + encoding; + switch (encoding && encoding.toLowerCase()) { + case 'hex':case 'utf8':case 'utf-8':case 'ascii':case 'binary':case 'base64':case 'ucs2':case 'ucs-2':case 'utf16le':case 'utf-16le':case 'raw': + return true; + default: + return false; + } + }; + + function _normalizeEncoding(enc) { + if (!enc) return 'utf8'; + var retried; + while (true) { + switch (enc) { + case 'utf8': + case 'utf-8': + return 'utf8'; + case 'ucs2': + case 'ucs-2': + case 'utf16le': + case 'utf-16le': + return 'utf16le'; + case 'latin1': + case 'binary': + return 'latin1'; + case 'base64': + case 'ascii': + case 'hex': + return enc; + default: + if (retried) return; // undefined + enc = ('' + enc).toLowerCase(); + retried = true; + } + } + } + // Do not cache `Buffer.isEncoding` when checking encoding names as some + // modules monkey-patch it to support additional encodings + function normalizeEncoding(enc) { + var nenc = _normalizeEncoding(enc); + if (typeof nenc !== 'string' && (Buffer.isEncoding === isEncoding || !isEncoding(enc))) throw new Error('Unknown encoding: ' + enc); + return nenc || enc; + } + + // StringDecoder provides an interface for efficiently splitting a series of + // buffers into a series of JS strings without breaking apart multi-byte + // characters. + string_decoder.StringDecoder = StringDecoder; + function StringDecoder(encoding) { + this.encoding = normalizeEncoding(encoding); + var nb; + switch (this.encoding) { + case 'utf16le': + this.text = utf16Text; + this.end = utf16End; + nb = 4; + break; + case 'utf8': + this.fillLast = utf8FillLast; + nb = 4; + break; + case 'base64': + this.text = base64Text; + this.end = base64End; + nb = 3; + break; + default: + this.write = simpleWrite; + this.end = simpleEnd; + return; + } + this.lastNeed = 0; + this.lastTotal = 0; + this.lastChar = Buffer.allocUnsafe(nb); + } + + StringDecoder.prototype.write = function (buf) { + if (buf.length === 0) return ''; + var r; + var i; + if (this.lastNeed) { + r = this.fillLast(buf); + if (r === undefined) return ''; + i = this.lastNeed; + this.lastNeed = 0; + } else { + i = 0; + } + if (i < buf.length) return r ? r + this.text(buf, i) : this.text(buf, i); + return r || ''; + }; + + StringDecoder.prototype.end = utf8End; + + // Returns only complete characters in a Buffer + StringDecoder.prototype.text = utf8Text; + + // Attempts to complete a partial non-UTF-8 character using bytes from a Buffer + StringDecoder.prototype.fillLast = function (buf) { + if (this.lastNeed <= buf.length) { + buf.copy(this.lastChar, this.lastTotal - this.lastNeed, 0, this.lastNeed); + return this.lastChar.toString(this.encoding, 0, this.lastTotal); + } + buf.copy(this.lastChar, this.lastTotal - this.lastNeed, 0, buf.length); + this.lastNeed -= buf.length; + }; + + // Checks the type of a UTF-8 byte, whether it's ASCII, a leading byte, or a + // continuation byte. If an invalid byte is detected, -2 is returned. + function utf8CheckByte(byte) { + if (byte <= 0x7F) return 0;else if (byte >> 5 === 0x06) return 2;else if (byte >> 4 === 0x0E) return 3;else if (byte >> 3 === 0x1E) return 4; + return byte >> 6 === 0x02 ? -1 : -2; + } + + // Checks at most 3 bytes at the end of a Buffer in order to detect an + // incomplete multi-byte UTF-8 character. The total number of bytes (2, 3, or 4) + // needed to complete the UTF-8 character (if applicable) are returned. + function utf8CheckIncomplete(self, buf, i) { + var j = buf.length - 1; + if (j < i) return 0; + var nb = utf8CheckByte(buf[j]); + if (nb >= 0) { + if (nb > 0) self.lastNeed = nb - 1; + return nb; + } + if (--j < i || nb === -2) return 0; + nb = utf8CheckByte(buf[j]); + if (nb >= 0) { + if (nb > 0) self.lastNeed = nb - 2; + return nb; + } + if (--j < i || nb === -2) return 0; + nb = utf8CheckByte(buf[j]); + if (nb >= 0) { + if (nb > 0) { + if (nb === 2) nb = 0;else self.lastNeed = nb - 3; + } + return nb; + } + return 0; + } + + // Validates as many continuation bytes for a multi-byte UTF-8 character as + // needed or are available. If we see a non-continuation byte where we expect + // one, we "replace" the validated continuation bytes we've seen so far with + // a single UTF-8 replacement character ('\ufffd'), to match v8's UTF-8 decoding + // behavior. The continuation byte check is included three times in the case + // where all of the continuation bytes for a character exist in the same buffer. + // It is also done this way as a slight performance increase instead of using a + // loop. + function utf8CheckExtraBytes(self, buf, p) { + if ((buf[0] & 0xC0) !== 0x80) { + self.lastNeed = 0; + return '\ufffd'; + } + if (self.lastNeed > 1 && buf.length > 1) { + if ((buf[1] & 0xC0) !== 0x80) { + self.lastNeed = 1; + return '\ufffd'; + } + if (self.lastNeed > 2 && buf.length > 2) { + if ((buf[2] & 0xC0) !== 0x80) { + self.lastNeed = 2; + return '\ufffd'; + } + } + } + } + + // Attempts to complete a multi-byte UTF-8 character using bytes from a Buffer. + function utf8FillLast(buf) { + var p = this.lastTotal - this.lastNeed; + var r = utf8CheckExtraBytes(this, buf); + if (r !== undefined) return r; + if (this.lastNeed <= buf.length) { + buf.copy(this.lastChar, p, 0, this.lastNeed); + return this.lastChar.toString(this.encoding, 0, this.lastTotal); + } + buf.copy(this.lastChar, p, 0, buf.length); + this.lastNeed -= buf.length; + } + + // Returns all complete UTF-8 characters in a Buffer. If the Buffer ended on a + // partial character, the character's bytes are buffered until the required + // number of bytes are available. + function utf8Text(buf, i) { + var total = utf8CheckIncomplete(this, buf, i); + if (!this.lastNeed) return buf.toString('utf8', i); + this.lastTotal = total; + var end = buf.length - (total - this.lastNeed); + buf.copy(this.lastChar, 0, end); + return buf.toString('utf8', i, end); + } + + // For UTF-8, a replacement character is added when ending on a partial + // character. + function utf8End(buf) { + var r = buf && buf.length ? this.write(buf) : ''; + if (this.lastNeed) return r + '\ufffd'; + return r; + } + + // UTF-16LE typically needs two bytes per character, but even if we have an even + // number of bytes available, we need to check if we end on a leading/high + // surrogate. In that case, we need to wait for the next two bytes in order to + // decode the last character properly. + function utf16Text(buf, i) { + if ((buf.length - i) % 2 === 0) { + var r = buf.toString('utf16le', i); + if (r) { + var c = r.charCodeAt(r.length - 1); + if (c >= 0xD800 && c <= 0xDBFF) { + this.lastNeed = 2; + this.lastTotal = 4; + this.lastChar[0] = buf[buf.length - 2]; + this.lastChar[1] = buf[buf.length - 1]; + return r.slice(0, -1); + } + } + return r; + } + this.lastNeed = 1; + this.lastTotal = 2; + this.lastChar[0] = buf[buf.length - 1]; + return buf.toString('utf16le', i, buf.length - 1); + } + + // For UTF-16LE we do not explicitly append special replacement characters if we + // end on a partial character, we simply let v8 handle that. + function utf16End(buf) { + var r = buf && buf.length ? this.write(buf) : ''; + if (this.lastNeed) { + var end = this.lastTotal - this.lastNeed; + return r + this.lastChar.toString('utf16le', 0, end); + } + return r; + } + + function base64Text(buf, i) { + var n = (buf.length - i) % 3; + if (n === 0) return buf.toString('base64', i); + this.lastNeed = 3 - n; + this.lastTotal = 3; + if (n === 1) { + this.lastChar[0] = buf[buf.length - 1]; + } else { + this.lastChar[0] = buf[buf.length - 2]; + this.lastChar[1] = buf[buf.length - 1]; + } + return buf.toString('base64', i, buf.length - n); + } + + function base64End(buf) { + var r = buf && buf.length ? this.write(buf) : ''; + if (this.lastNeed) return r + this.lastChar.toString('base64', 0, 3 - this.lastNeed); + return r; + } + + // Pass bytes on through for single-byte encodings (e.g. ascii, latin1, hex) + function simpleWrite(buf) { + return buf.toString(this.encoding); + } + + function simpleEnd(buf) { + return buf && buf.length ? this.write(buf) : ''; + } + return string_decoder; +} + +var endOfStream; +var hasRequiredEndOfStream; + +function requireEndOfStream () { + if (hasRequiredEndOfStream) return endOfStream; + hasRequiredEndOfStream = 1; + + var ERR_STREAM_PREMATURE_CLOSE = requireErrors().codes.ERR_STREAM_PREMATURE_CLOSE; + function once(callback) { + var called = false; + return function () { + if (called) return; + called = true; + for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) { + args[_key] = arguments[_key]; + } + callback.apply(this, args); + }; + } + function noop() {} + function isRequest(stream) { + return stream.setHeader && typeof stream.abort === 'function'; + } + function eos(stream, opts, callback) { + if (typeof opts === 'function') return eos(stream, null, opts); + if (!opts) opts = {}; + callback = once(callback || noop); + var readable = opts.readable || opts.readable !== false && stream.readable; + var writable = opts.writable || opts.writable !== false && stream.writable; + var onlegacyfinish = function onlegacyfinish() { + if (!stream.writable) onfinish(); + }; + var writableEnded = stream._writableState && stream._writableState.finished; + var onfinish = function onfinish() { + writable = false; + writableEnded = true; + if (!readable) callback.call(stream); + }; + var readableEnded = stream._readableState && stream._readableState.endEmitted; + var onend = function onend() { + readable = false; + readableEnded = true; + if (!writable) callback.call(stream); + }; + var onerror = function onerror(err) { + callback.call(stream, err); + }; + var onclose = function onclose() { + var err; + if (readable && !readableEnded) { + if (!stream._readableState || !stream._readableState.ended) err = new ERR_STREAM_PREMATURE_CLOSE(); + return callback.call(stream, err); + } + if (writable && !writableEnded) { + if (!stream._writableState || !stream._writableState.ended) err = new ERR_STREAM_PREMATURE_CLOSE(); + return callback.call(stream, err); + } + }; + var onrequest = function onrequest() { + stream.req.on('finish', onfinish); + }; + if (isRequest(stream)) { + stream.on('complete', onfinish); + stream.on('abort', onclose); + if (stream.req) onrequest();else stream.on('request', onrequest); + } else if (writable && !stream._writableState) { + // legacy streams + stream.on('end', onlegacyfinish); + stream.on('close', onlegacyfinish); + } + stream.on('end', onend); + stream.on('finish', onfinish); + if (opts.error !== false) stream.on('error', onerror); + stream.on('close', onclose); + return function () { + stream.removeListener('complete', onfinish); + stream.removeListener('abort', onclose); + stream.removeListener('request', onrequest); + if (stream.req) stream.req.removeListener('finish', onfinish); + stream.removeListener('end', onlegacyfinish); + stream.removeListener('close', onlegacyfinish); + stream.removeListener('finish', onfinish); + stream.removeListener('end', onend); + stream.removeListener('error', onerror); + stream.removeListener('close', onclose); + }; + } + endOfStream = eos; + return endOfStream; +} + +var async_iterator; +var hasRequiredAsync_iterator; + +function requireAsync_iterator () { + if (hasRequiredAsync_iterator) return async_iterator; + hasRequiredAsync_iterator = 1; + + var _Object$setPrototypeO; + function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } + function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return typeof key === "symbol" ? key : String(key); } + function _toPrimitive(input, hint) { if (typeof input !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (typeof res !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); } + var finished = requireEndOfStream(); + var kLastResolve = Symbol('lastResolve'); + var kLastReject = Symbol('lastReject'); + var kError = Symbol('error'); + var kEnded = Symbol('ended'); + var kLastPromise = Symbol('lastPromise'); + var kHandlePromise = Symbol('handlePromise'); + var kStream = Symbol('stream'); + function createIterResult(value, done) { + return { + value: value, + done: done + }; + } + function readAndResolve(iter) { + var resolve = iter[kLastResolve]; + if (resolve !== null) { + var data = iter[kStream].read(); + // we defer if data is null + // we can be expecting either 'end' or + // 'error' + if (data !== null) { + iter[kLastPromise] = null; + iter[kLastResolve] = null; + iter[kLastReject] = null; + resolve(createIterResult(data, false)); + } + } + } + function onReadable(iter) { + // we wait for the next tick, because it might + // emit an error with process.nextTick + process.nextTick(readAndResolve, iter); + } + function wrapForNext(lastPromise, iter) { + return function (resolve, reject) { + lastPromise.then(function () { + if (iter[kEnded]) { + resolve(createIterResult(undefined, true)); + return; + } + iter[kHandlePromise](resolve, reject); + }, reject); + }; + } + var AsyncIteratorPrototype = Object.getPrototypeOf(function () {}); + var ReadableStreamAsyncIteratorPrototype = Object.setPrototypeOf((_Object$setPrototypeO = { + get stream() { + return this[kStream]; + }, + next: function next() { + var _this = this; + // if we have detected an error in the meanwhile + // reject straight away + var error = this[kError]; + if (error !== null) { + return Promise.reject(error); + } + if (this[kEnded]) { + return Promise.resolve(createIterResult(undefined, true)); + } + if (this[kStream].destroyed) { + // We need to defer via nextTick because if .destroy(err) is + // called, the error will be emitted via nextTick, and + // we cannot guarantee that there is no error lingering around + // waiting to be emitted. + return new Promise(function (resolve, reject) { + process.nextTick(function () { + if (_this[kError]) { + reject(_this[kError]); + } else { + resolve(createIterResult(undefined, true)); + } + }); + }); + } + + // if we have multiple next() calls + // we will wait for the previous Promise to finish + // this logic is optimized to support for await loops, + // where next() is only called once at a time + var lastPromise = this[kLastPromise]; + var promise; + if (lastPromise) { + promise = new Promise(wrapForNext(lastPromise, this)); + } else { + // fast path needed to support multiple this.push() + // without triggering the next() queue + var data = this[kStream].read(); + if (data !== null) { + return Promise.resolve(createIterResult(data, false)); + } + promise = new Promise(this[kHandlePromise]); + } + this[kLastPromise] = promise; + return promise; + } + }, _defineProperty(_Object$setPrototypeO, Symbol.asyncIterator, function () { + return this; + }), _defineProperty(_Object$setPrototypeO, "return", function _return() { + var _this2 = this; + // destroy(err, cb) is a private API + // we can guarantee we have that here, because we control the + // Readable class this is attached to + return new Promise(function (resolve, reject) { + _this2[kStream].destroy(null, function (err) { + if (err) { + reject(err); + return; + } + resolve(createIterResult(undefined, true)); + }); + }); + }), _Object$setPrototypeO), AsyncIteratorPrototype); + var createReadableStreamAsyncIterator = function createReadableStreamAsyncIterator(stream) { + var _Object$create; + var iterator = Object.create(ReadableStreamAsyncIteratorPrototype, (_Object$create = {}, _defineProperty(_Object$create, kStream, { + value: stream, + writable: true + }), _defineProperty(_Object$create, kLastResolve, { + value: null, + writable: true + }), _defineProperty(_Object$create, kLastReject, { + value: null, + writable: true + }), _defineProperty(_Object$create, kError, { + value: null, + writable: true + }), _defineProperty(_Object$create, kEnded, { + value: stream._readableState.endEmitted, + writable: true + }), _defineProperty(_Object$create, kHandlePromise, { + value: function value(resolve, reject) { + var data = iterator[kStream].read(); + if (data) { + iterator[kLastPromise] = null; + iterator[kLastResolve] = null; + iterator[kLastReject] = null; + resolve(createIterResult(data, false)); + } else { + iterator[kLastResolve] = resolve; + iterator[kLastReject] = reject; + } + }, + writable: true + }), _Object$create)); + iterator[kLastPromise] = null; + finished(stream, function (err) { + if (err && err.code !== 'ERR_STREAM_PREMATURE_CLOSE') { + var reject = iterator[kLastReject]; + // reject if we are waiting for data in the Promise + // returned by next() and store the error + if (reject !== null) { + iterator[kLastPromise] = null; + iterator[kLastResolve] = null; + iterator[kLastReject] = null; + reject(err); + } + iterator[kError] = err; + return; + } + var resolve = iterator[kLastResolve]; + if (resolve !== null) { + iterator[kLastPromise] = null; + iterator[kLastResolve] = null; + iterator[kLastReject] = null; + resolve(createIterResult(undefined, true)); + } + iterator[kEnded] = true; + }); + stream.on('readable', onReadable.bind(null, iterator)); + return iterator; + }; + async_iterator = createReadableStreamAsyncIterator; + return async_iterator; +} + +var from_1; +var hasRequiredFrom; + +function requireFrom () { + if (hasRequiredFrom) return from_1; + hasRequiredFrom = 1; + + function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } } + function _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }; } + function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; } + function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; } + function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } + function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return typeof key === "symbol" ? key : String(key); } + function _toPrimitive(input, hint) { if (typeof input !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (typeof res !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); } + var ERR_INVALID_ARG_TYPE = requireErrors().codes.ERR_INVALID_ARG_TYPE; + function from(Readable, iterable, opts) { + var iterator; + if (iterable && typeof iterable.next === 'function') { + iterator = iterable; + } else if (iterable && iterable[Symbol.asyncIterator]) iterator = iterable[Symbol.asyncIterator]();else if (iterable && iterable[Symbol.iterator]) iterator = iterable[Symbol.iterator]();else throw new ERR_INVALID_ARG_TYPE('iterable', ['Iterable'], iterable); + var readable = new Readable(_objectSpread({ + objectMode: true + }, opts)); + // Reading boolean to protect against _read + // being called before last iteration completion. + var reading = false; + readable._read = function () { + if (!reading) { + reading = true; + next(); + } + }; + function next() { + return _next2.apply(this, arguments); + } + function _next2() { + _next2 = _asyncToGenerator(function* () { + try { + var _yield$iterator$next = yield iterator.next(), + value = _yield$iterator$next.value, + done = _yield$iterator$next.done; + if (done) { + readable.push(null); + } else if (readable.push(yield value)) { + next(); + } else { + reading = false; + } + } catch (err) { + readable.destroy(err); + } + }); + return _next2.apply(this, arguments); + } + return readable; + } + from_1 = from; + return from_1; +} + +var _stream_readable; +var hasRequired_stream_readable; + +function require_stream_readable () { + if (hasRequired_stream_readable) return _stream_readable; + hasRequired_stream_readable = 1; + + _stream_readable = Readable; + + /**/ + var Duplex; + /**/ + + Readable.ReadableState = ReadableState; + + /**/ + require$$2.EventEmitter; + var EElistenerCount = function EElistenerCount(emitter, type) { + return emitter.listeners(type).length; + }; + /**/ + + /**/ + var Stream = requireStream(); + /**/ + + var Buffer = require$$0$6.Buffer; + var OurUint8Array = (typeof commonjsGlobal !== 'undefined' ? commonjsGlobal : typeof window !== 'undefined' ? window : typeof self !== 'undefined' ? self : {}).Uint8Array || function () {}; + function _uint8ArrayToBuffer(chunk) { + return Buffer.from(chunk); + } + function _isUint8Array(obj) { + return Buffer.isBuffer(obj) || obj instanceof OurUint8Array; + } + + /**/ + var debugUtil = require$$2$1; + var debug; + if (debugUtil && debugUtil.debuglog) { + debug = debugUtil.debuglog('stream'); + } else { + debug = function debug() {}; + } + /**/ + + var BufferList = requireBuffer_list(); + var destroyImpl = requireDestroy(); + var _require = requireState(), + getHighWaterMark = _require.getHighWaterMark; + var _require$codes = requireErrors().codes, + ERR_INVALID_ARG_TYPE = _require$codes.ERR_INVALID_ARG_TYPE, + ERR_STREAM_PUSH_AFTER_EOF = _require$codes.ERR_STREAM_PUSH_AFTER_EOF, + ERR_METHOD_NOT_IMPLEMENTED = _require$codes.ERR_METHOD_NOT_IMPLEMENTED, + ERR_STREAM_UNSHIFT_AFTER_END_EVENT = _require$codes.ERR_STREAM_UNSHIFT_AFTER_END_EVENT; + + // Lazy loaded to improve the startup performance. + var StringDecoder; + var createReadableStreamAsyncIterator; + var from; + requireInherits()(Readable, Stream); + var errorOrDestroy = destroyImpl.errorOrDestroy; + var kProxyEvents = ['error', 'close', 'destroy', 'pause', 'resume']; + function prependListener(emitter, event, fn) { + // Sadly this is not cacheable as some libraries bundle their own + // event emitter implementation with them. + if (typeof emitter.prependListener === 'function') return emitter.prependListener(event, fn); + + // This is a hack to make sure that our error handler is attached before any + // userland ones. NEVER DO THIS. This is here only because this code needs + // to continue to work with older versions of Node.js that do not include + // the prependListener() method. The goal is to eventually remove this hack. + if (!emitter._events || !emitter._events[event]) emitter.on(event, fn);else if (Array.isArray(emitter._events[event])) emitter._events[event].unshift(fn);else emitter._events[event] = [fn, emitter._events[event]]; + } + function ReadableState(options, stream, isDuplex) { + Duplex = Duplex || require_stream_duplex(); + options = options || {}; + + // Duplex streams are both readable and writable, but share + // the same options object. + // However, some cases require setting options to different + // values for the readable and the writable sides of the duplex stream. + // These options can be provided separately as readableXXX and writableXXX. + if (typeof isDuplex !== 'boolean') isDuplex = stream instanceof Duplex; + + // object stream flag. Used to make read(n) ignore n and to + // make all the buffer merging and length checks go away + this.objectMode = !!options.objectMode; + if (isDuplex) this.objectMode = this.objectMode || !!options.readableObjectMode; + + // the point at which it stops calling _read() to fill the buffer + // Note: 0 is a valid value, means "don't call _read preemptively ever" + this.highWaterMark = getHighWaterMark(this, options, 'readableHighWaterMark', isDuplex); + + // A linked list is used to store data chunks instead of an array because the + // linked list can remove elements from the beginning faster than + // array.shift() + this.buffer = new BufferList(); + this.length = 0; + this.pipes = null; + this.pipesCount = 0; + this.flowing = null; + this.ended = false; + this.endEmitted = false; + this.reading = false; + + // a flag to be able to tell if the event 'readable'/'data' is emitted + // immediately, or on a later tick. We set this to true at first, because + // any actions that shouldn't happen until "later" should generally also + // not happen before the first read call. + this.sync = true; + + // whenever we return null, then we set a flag to say + // that we're awaiting a 'readable' event emission. + this.needReadable = false; + this.emittedReadable = false; + this.readableListening = false; + this.resumeScheduled = false; + this.paused = true; + + // Should close be emitted on destroy. Defaults to true. + this.emitClose = options.emitClose !== false; + + // Should .destroy() be called after 'end' (and potentially 'finish') + this.autoDestroy = !!options.autoDestroy; + + // has it been destroyed + this.destroyed = false; + + // Crypto is kind of old and crusty. Historically, its default string + // encoding is 'binary' so we have to make this configurable. + // Everything else in the universe uses 'utf8', though. + this.defaultEncoding = options.defaultEncoding || 'utf8'; + + // the number of writers that are awaiting a drain event in .pipe()s + this.awaitDrain = 0; + + // if true, a maybeReadMore has been scheduled + this.readingMore = false; + this.decoder = null; + this.encoding = null; + if (options.encoding) { + if (!StringDecoder) StringDecoder = requireString_decoder().StringDecoder; + this.decoder = new StringDecoder(options.encoding); + this.encoding = options.encoding; + } + } + function Readable(options) { + Duplex = Duplex || require_stream_duplex(); + if (!(this instanceof Readable)) return new Readable(options); + + // Checking for a Stream.Duplex instance is faster here instead of inside + // the ReadableState constructor, at least with V8 6.5 + var isDuplex = this instanceof Duplex; + this._readableState = new ReadableState(options, this, isDuplex); + + // legacy + this.readable = true; + if (options) { + if (typeof options.read === 'function') this._read = options.read; + if (typeof options.destroy === 'function') this._destroy = options.destroy; + } + Stream.call(this); + } + Object.defineProperty(Readable.prototype, 'destroyed', { + // making it explicit this property is not enumerable + // because otherwise some prototype manipulation in + // userland will fail + enumerable: false, + get: function get() { + if (this._readableState === undefined) { + return false; + } + return this._readableState.destroyed; + }, + set: function set(value) { + // we ignore the value if the stream + // has not been initialized yet + if (!this._readableState) { + return; + } + + // backward compatibility, the user is explicitly + // managing destroyed + this._readableState.destroyed = value; + } + }); + Readable.prototype.destroy = destroyImpl.destroy; + Readable.prototype._undestroy = destroyImpl.undestroy; + Readable.prototype._destroy = function (err, cb) { + cb(err); + }; + + // Manually shove something into the read() buffer. + // This returns true if the highWaterMark has not been hit yet, + // similar to how Writable.write() returns true if you should + // write() some more. + Readable.prototype.push = function (chunk, encoding) { + var state = this._readableState; + var skipChunkCheck; + if (!state.objectMode) { + if (typeof chunk === 'string') { + encoding = encoding || state.defaultEncoding; + if (encoding !== state.encoding) { + chunk = Buffer.from(chunk, encoding); + encoding = ''; + } + skipChunkCheck = true; + } + } else { + skipChunkCheck = true; + } + return readableAddChunk(this, chunk, encoding, false, skipChunkCheck); + }; + + // Unshift should *always* be something directly out of read() + Readable.prototype.unshift = function (chunk) { + return readableAddChunk(this, chunk, null, true, false); + }; + function readableAddChunk(stream, chunk, encoding, addToFront, skipChunkCheck) { + debug('readableAddChunk', chunk); + var state = stream._readableState; + if (chunk === null) { + state.reading = false; + onEofChunk(stream, state); + } else { + var er; + if (!skipChunkCheck) er = chunkInvalid(state, chunk); + if (er) { + errorOrDestroy(stream, er); + } else if (state.objectMode || chunk && chunk.length > 0) { + if (typeof chunk !== 'string' && !state.objectMode && Object.getPrototypeOf(chunk) !== Buffer.prototype) { + chunk = _uint8ArrayToBuffer(chunk); + } + if (addToFront) { + if (state.endEmitted) errorOrDestroy(stream, new ERR_STREAM_UNSHIFT_AFTER_END_EVENT());else addChunk(stream, state, chunk, true); + } else if (state.ended) { + errorOrDestroy(stream, new ERR_STREAM_PUSH_AFTER_EOF()); + } else if (state.destroyed) { + return false; + } else { + state.reading = false; + if (state.decoder && !encoding) { + chunk = state.decoder.write(chunk); + if (state.objectMode || chunk.length !== 0) addChunk(stream, state, chunk, false);else maybeReadMore(stream, state); + } else { + addChunk(stream, state, chunk, false); + } + } + } else if (!addToFront) { + state.reading = false; + maybeReadMore(stream, state); + } + } + + // We can push more data if we are below the highWaterMark. + // Also, if we have no data yet, we can stand some more bytes. + // This is to work around cases where hwm=0, such as the repl. + return !state.ended && (state.length < state.highWaterMark || state.length === 0); + } + function addChunk(stream, state, chunk, addToFront) { + if (state.flowing && state.length === 0 && !state.sync) { + state.awaitDrain = 0; + stream.emit('data', chunk); + } else { + // update the buffer info. + state.length += state.objectMode ? 1 : chunk.length; + if (addToFront) state.buffer.unshift(chunk);else state.buffer.push(chunk); + if (state.needReadable) emitReadable(stream); + } + maybeReadMore(stream, state); + } + function chunkInvalid(state, chunk) { + var er; + if (!_isUint8Array(chunk) && typeof chunk !== 'string' && chunk !== undefined && !state.objectMode) { + er = new ERR_INVALID_ARG_TYPE('chunk', ['string', 'Buffer', 'Uint8Array'], chunk); + } + return er; + } + Readable.prototype.isPaused = function () { + return this._readableState.flowing === false; + }; + + // backwards compatibility. + Readable.prototype.setEncoding = function (enc) { + if (!StringDecoder) StringDecoder = requireString_decoder().StringDecoder; + var decoder = new StringDecoder(enc); + this._readableState.decoder = decoder; + // If setEncoding(null), decoder.encoding equals utf8 + this._readableState.encoding = this._readableState.decoder.encoding; + + // Iterate over current buffer to convert already stored Buffers: + var p = this._readableState.buffer.head; + var content = ''; + while (p !== null) { + content += decoder.write(p.data); + p = p.next; + } + this._readableState.buffer.clear(); + if (content !== '') this._readableState.buffer.push(content); + this._readableState.length = content.length; + return this; + }; + + // Don't raise the hwm > 1GB + var MAX_HWM = 0x40000000; + function computeNewHighWaterMark(n) { + if (n >= MAX_HWM) { + // TODO(ronag): Throw ERR_VALUE_OUT_OF_RANGE. + n = MAX_HWM; + } else { + // Get the next highest power of 2 to prevent increasing hwm excessively in + // tiny amounts + n--; + n |= n >>> 1; + n |= n >>> 2; + n |= n >>> 4; + n |= n >>> 8; + n |= n >>> 16; + n++; + } + return n; + } + + // This function is designed to be inlinable, so please take care when making + // changes to the function body. + function howMuchToRead(n, state) { + if (n <= 0 || state.length === 0 && state.ended) return 0; + if (state.objectMode) return 1; + if (n !== n) { + // Only flow one buffer at a time + if (state.flowing && state.length) return state.buffer.head.data.length;else return state.length; + } + // If we're asking for more than the current hwm, then raise the hwm. + if (n > state.highWaterMark) state.highWaterMark = computeNewHighWaterMark(n); + if (n <= state.length) return n; + // Don't have enough + if (!state.ended) { + state.needReadable = true; + return 0; + } + return state.length; + } + + // you can override either this method, or the async _read(n) below. + Readable.prototype.read = function (n) { + debug('read', n); + n = parseInt(n, 10); + var state = this._readableState; + var nOrig = n; + if (n !== 0) state.emittedReadable = false; + + // if we're doing read(0) to trigger a readable event, but we + // already have a bunch of data in the buffer, then just trigger + // the 'readable' event and move on. + if (n === 0 && state.needReadable && ((state.highWaterMark !== 0 ? state.length >= state.highWaterMark : state.length > 0) || state.ended)) { + debug('read: emitReadable', state.length, state.ended); + if (state.length === 0 && state.ended) endReadable(this);else emitReadable(this); + return null; + } + n = howMuchToRead(n, state); + + // if we've ended, and we're now clear, then finish it up. + if (n === 0 && state.ended) { + if (state.length === 0) endReadable(this); + return null; + } + + // All the actual chunk generation logic needs to be + // *below* the call to _read. The reason is that in certain + // synthetic stream cases, such as passthrough streams, _read + // may be a completely synchronous operation which may change + // the state of the read buffer, providing enough data when + // before there was *not* enough. + // + // So, the steps are: + // 1. Figure out what the state of things will be after we do + // a read from the buffer. + // + // 2. If that resulting state will trigger a _read, then call _read. + // Note that this may be asynchronous, or synchronous. Yes, it is + // deeply ugly to write APIs this way, but that still doesn't mean + // that the Readable class should behave improperly, as streams are + // designed to be sync/async agnostic. + // Take note if the _read call is sync or async (ie, if the read call + // has returned yet), so that we know whether or not it's safe to emit + // 'readable' etc. + // + // 3. Actually pull the requested chunks out of the buffer and return. + + // if we need a readable event, then we need to do some reading. + var doRead = state.needReadable; + debug('need readable', doRead); + + // if we currently have less than the highWaterMark, then also read some + if (state.length === 0 || state.length - n < state.highWaterMark) { + doRead = true; + debug('length less than watermark', doRead); + } + + // however, if we've ended, then there's no point, and if we're already + // reading, then it's unnecessary. + if (state.ended || state.reading) { + doRead = false; + debug('reading or ended', doRead); + } else if (doRead) { + debug('do read'); + state.reading = true; + state.sync = true; + // if the length is currently zero, then we *need* a readable event. + if (state.length === 0) state.needReadable = true; + // call internal read method + this._read(state.highWaterMark); + state.sync = false; + // If _read pushed data synchronously, then `reading` will be false, + // and we need to re-evaluate how much data we can return to the user. + if (!state.reading) n = howMuchToRead(nOrig, state); + } + var ret; + if (n > 0) ret = fromList(n, state);else ret = null; + if (ret === null) { + state.needReadable = state.length <= state.highWaterMark; + n = 0; + } else { + state.length -= n; + state.awaitDrain = 0; + } + if (state.length === 0) { + // If we have nothing in the buffer, then we want to know + // as soon as we *do* get something into the buffer. + if (!state.ended) state.needReadable = true; + + // If we tried to read() past the EOF, then emit end on the next tick. + if (nOrig !== n && state.ended) endReadable(this); + } + if (ret !== null) this.emit('data', ret); + return ret; + }; + function onEofChunk(stream, state) { + debug('onEofChunk'); + if (state.ended) return; + if (state.decoder) { + var chunk = state.decoder.end(); + if (chunk && chunk.length) { + state.buffer.push(chunk); + state.length += state.objectMode ? 1 : chunk.length; + } + } + state.ended = true; + if (state.sync) { + // if we are sync, wait until next tick to emit the data. + // Otherwise we risk emitting data in the flow() + // the readable code triggers during a read() call + emitReadable(stream); + } else { + // emit 'readable' now to make sure it gets picked up. + state.needReadable = false; + if (!state.emittedReadable) { + state.emittedReadable = true; + emitReadable_(stream); + } + } + } + + // Don't emit readable right away in sync mode, because this can trigger + // another read() call => stack overflow. This way, it might trigger + // a nextTick recursion warning, but that's not so bad. + function emitReadable(stream) { + var state = stream._readableState; + debug('emitReadable', state.needReadable, state.emittedReadable); + state.needReadable = false; + if (!state.emittedReadable) { + debug('emitReadable', state.flowing); + state.emittedReadable = true; + process.nextTick(emitReadable_, stream); + } + } + function emitReadable_(stream) { + var state = stream._readableState; + debug('emitReadable_', state.destroyed, state.length, state.ended); + if (!state.destroyed && (state.length || state.ended)) { + stream.emit('readable'); + state.emittedReadable = false; + } + + // The stream needs another readable event if + // 1. It is not flowing, as the flow mechanism will take + // care of it. + // 2. It is not ended. + // 3. It is below the highWaterMark, so we can schedule + // another readable later. + state.needReadable = !state.flowing && !state.ended && state.length <= state.highWaterMark; + flow(stream); + } + + // at this point, the user has presumably seen the 'readable' event, + // and called read() to consume some data. that may have triggered + // in turn another _read(n) call, in which case reading = true if + // it's in progress. + // However, if we're not ended, or reading, and the length < hwm, + // then go ahead and try to read some more preemptively. + function maybeReadMore(stream, state) { + if (!state.readingMore) { + state.readingMore = true; + process.nextTick(maybeReadMore_, stream, state); + } + } + function maybeReadMore_(stream, state) { + // Attempt to read more data if we should. + // + // The conditions for reading more data are (one of): + // - Not enough data buffered (state.length < state.highWaterMark). The loop + // is responsible for filling the buffer with enough data if such data + // is available. If highWaterMark is 0 and we are not in the flowing mode + // we should _not_ attempt to buffer any extra data. We'll get more data + // when the stream consumer calls read() instead. + // - No data in the buffer, and the stream is in flowing mode. In this mode + // the loop below is responsible for ensuring read() is called. Failing to + // call read here would abort the flow and there's no other mechanism for + // continuing the flow if the stream consumer has just subscribed to the + // 'data' event. + // + // In addition to the above conditions to keep reading data, the following + // conditions prevent the data from being read: + // - The stream has ended (state.ended). + // - There is already a pending 'read' operation (state.reading). This is a + // case where the the stream has called the implementation defined _read() + // method, but they are processing the call asynchronously and have _not_ + // called push() with new data. In this case we skip performing more + // read()s. The execution ends in this method again after the _read() ends + // up calling push() with more data. + while (!state.reading && !state.ended && (state.length < state.highWaterMark || state.flowing && state.length === 0)) { + var len = state.length; + debug('maybeReadMore read 0'); + stream.read(0); + if (len === state.length) + // didn't get any data, stop spinning. + break; + } + state.readingMore = false; + } + + // abstract method. to be overridden in specific implementation classes. + // call cb(er, data) where data is <= n in length. + // for virtual (non-string, non-buffer) streams, "length" is somewhat + // arbitrary, and perhaps not very meaningful. + Readable.prototype._read = function (n) { + errorOrDestroy(this, new ERR_METHOD_NOT_IMPLEMENTED('_read()')); + }; + Readable.prototype.pipe = function (dest, pipeOpts) { + var src = this; + var state = this._readableState; + switch (state.pipesCount) { + case 0: + state.pipes = dest; + break; + case 1: + state.pipes = [state.pipes, dest]; + break; + default: + state.pipes.push(dest); + break; + } + state.pipesCount += 1; + debug('pipe count=%d opts=%j', state.pipesCount, pipeOpts); + var doEnd = (!pipeOpts || pipeOpts.end !== false) && dest !== process.stdout && dest !== process.stderr; + var endFn = doEnd ? onend : unpipe; + if (state.endEmitted) process.nextTick(endFn);else src.once('end', endFn); + dest.on('unpipe', onunpipe); + function onunpipe(readable, unpipeInfo) { + debug('onunpipe'); + if (readable === src) { + if (unpipeInfo && unpipeInfo.hasUnpiped === false) { + unpipeInfo.hasUnpiped = true; + cleanup(); + } + } + } + function onend() { + debug('onend'); + dest.end(); + } + + // when the dest drains, it reduces the awaitDrain counter + // on the source. This would be more elegant with a .once() + // handler in flow(), but adding and removing repeatedly is + // too slow. + var ondrain = pipeOnDrain(src); + dest.on('drain', ondrain); + var cleanedUp = false; + function cleanup() { + debug('cleanup'); + // cleanup event handlers once the pipe is broken + dest.removeListener('close', onclose); + dest.removeListener('finish', onfinish); + dest.removeListener('drain', ondrain); + dest.removeListener('error', onerror); + dest.removeListener('unpipe', onunpipe); + src.removeListener('end', onend); + src.removeListener('end', unpipe); + src.removeListener('data', ondata); + cleanedUp = true; + + // if the reader is waiting for a drain event from this + // specific writer, then it would cause it to never start + // flowing again. + // So, if this is awaiting a drain, then we just call it now. + // If we don't know, then assume that we are waiting for one. + if (state.awaitDrain && (!dest._writableState || dest._writableState.needDrain)) ondrain(); + } + src.on('data', ondata); + function ondata(chunk) { + debug('ondata'); + var ret = dest.write(chunk); + debug('dest.write', ret); + if (ret === false) { + // If the user unpiped during `dest.write()`, it is possible + // to get stuck in a permanently paused state if that write + // also returned false. + // => Check whether `dest` is still a piping destination. + if ((state.pipesCount === 1 && state.pipes === dest || state.pipesCount > 1 && indexOf(state.pipes, dest) !== -1) && !cleanedUp) { + debug('false write response, pause', state.awaitDrain); + state.awaitDrain++; + } + src.pause(); + } + } + + // if the dest has an error, then stop piping into it. + // however, don't suppress the throwing behavior for this. + function onerror(er) { + debug('onerror', er); + unpipe(); + dest.removeListener('error', onerror); + if (EElistenerCount(dest, 'error') === 0) errorOrDestroy(dest, er); + } + + // Make sure our error handler is attached before userland ones. + prependListener(dest, 'error', onerror); + + // Both close and finish should trigger unpipe, but only once. + function onclose() { + dest.removeListener('finish', onfinish); + unpipe(); + } + dest.once('close', onclose); + function onfinish() { + debug('onfinish'); + dest.removeListener('close', onclose); + unpipe(); + } + dest.once('finish', onfinish); + function unpipe() { + debug('unpipe'); + src.unpipe(dest); + } + + // tell the dest that it's being piped to + dest.emit('pipe', src); + + // start the flow if it hasn't been started already. + if (!state.flowing) { + debug('pipe resume'); + src.resume(); + } + return dest; + }; + function pipeOnDrain(src) { + return function pipeOnDrainFunctionResult() { + var state = src._readableState; + debug('pipeOnDrain', state.awaitDrain); + if (state.awaitDrain) state.awaitDrain--; + if (state.awaitDrain === 0 && EElistenerCount(src, 'data')) { + state.flowing = true; + flow(src); + } + }; + } + Readable.prototype.unpipe = function (dest) { + var state = this._readableState; + var unpipeInfo = { + hasUnpiped: false + }; + + // if we're not piping anywhere, then do nothing. + if (state.pipesCount === 0) return this; + + // just one destination. most common case. + if (state.pipesCount === 1) { + // passed in one, but it's not the right one. + if (dest && dest !== state.pipes) return this; + if (!dest) dest = state.pipes; + + // got a match. + state.pipes = null; + state.pipesCount = 0; + state.flowing = false; + if (dest) dest.emit('unpipe', this, unpipeInfo); + return this; + } + + // slow case. multiple pipe destinations. + + if (!dest) { + // remove all. + var dests = state.pipes; + var len = state.pipesCount; + state.pipes = null; + state.pipesCount = 0; + state.flowing = false; + for (var i = 0; i < len; i++) dests[i].emit('unpipe', this, { + hasUnpiped: false + }); + return this; + } + + // try to find the right one. + var index = indexOf(state.pipes, dest); + if (index === -1) return this; + state.pipes.splice(index, 1); + state.pipesCount -= 1; + if (state.pipesCount === 1) state.pipes = state.pipes[0]; + dest.emit('unpipe', this, unpipeInfo); + return this; + }; + + // set up data events if they are asked for + // Ensure readable listeners eventually get something + Readable.prototype.on = function (ev, fn) { + var res = Stream.prototype.on.call(this, ev, fn); + var state = this._readableState; + if (ev === 'data') { + // update readableListening so that resume() may be a no-op + // a few lines down. This is needed to support once('readable'). + state.readableListening = this.listenerCount('readable') > 0; + + // Try start flowing on next tick if stream isn't explicitly paused + if (state.flowing !== false) this.resume(); + } else if (ev === 'readable') { + if (!state.endEmitted && !state.readableListening) { + state.readableListening = state.needReadable = true; + state.flowing = false; + state.emittedReadable = false; + debug('on readable', state.length, state.reading); + if (state.length) { + emitReadable(this); + } else if (!state.reading) { + process.nextTick(nReadingNextTick, this); + } + } + } + return res; + }; + Readable.prototype.addListener = Readable.prototype.on; + Readable.prototype.removeListener = function (ev, fn) { + var res = Stream.prototype.removeListener.call(this, ev, fn); + if (ev === 'readable') { + // We need to check if there is someone still listening to + // readable and reset the state. However this needs to happen + // after readable has been emitted but before I/O (nextTick) to + // support once('readable', fn) cycles. This means that calling + // resume within the same tick will have no + // effect. + process.nextTick(updateReadableListening, this); + } + return res; + }; + Readable.prototype.removeAllListeners = function (ev) { + var res = Stream.prototype.removeAllListeners.apply(this, arguments); + if (ev === 'readable' || ev === undefined) { + // We need to check if there is someone still listening to + // readable and reset the state. However this needs to happen + // after readable has been emitted but before I/O (nextTick) to + // support once('readable', fn) cycles. This means that calling + // resume within the same tick will have no + // effect. + process.nextTick(updateReadableListening, this); + } + return res; + }; + function updateReadableListening(self) { + var state = self._readableState; + state.readableListening = self.listenerCount('readable') > 0; + if (state.resumeScheduled && !state.paused) { + // flowing needs to be set to true now, otherwise + // the upcoming resume will not flow. + state.flowing = true; + + // crude way to check if we should resume + } else if (self.listenerCount('data') > 0) { + self.resume(); + } + } + function nReadingNextTick(self) { + debug('readable nexttick read 0'); + self.read(0); + } + + // pause() and resume() are remnants of the legacy readable stream API + // If the user uses them, then switch into old mode. + Readable.prototype.resume = function () { + var state = this._readableState; + if (!state.flowing) { + debug('resume'); + // we flow only if there is no one listening + // for readable, but we still have to call + // resume() + state.flowing = !state.readableListening; + resume(this, state); + } + state.paused = false; + return this; + }; + function resume(stream, state) { + if (!state.resumeScheduled) { + state.resumeScheduled = true; + process.nextTick(resume_, stream, state); + } + } + function resume_(stream, state) { + debug('resume', state.reading); + if (!state.reading) { + stream.read(0); + } + state.resumeScheduled = false; + stream.emit('resume'); + flow(stream); + if (state.flowing && !state.reading) stream.read(0); + } + Readable.prototype.pause = function () { + debug('call pause flowing=%j', this._readableState.flowing); + if (this._readableState.flowing !== false) { + debug('pause'); + this._readableState.flowing = false; + this.emit('pause'); + } + this._readableState.paused = true; + return this; + }; + function flow(stream) { + var state = stream._readableState; + debug('flow', state.flowing); + while (state.flowing && stream.read() !== null); + } + + // wrap an old-style stream as the async data source. + // This is *not* part of the readable stream interface. + // It is an ugly unfortunate mess of history. + Readable.prototype.wrap = function (stream) { + var _this = this; + var state = this._readableState; + var paused = false; + stream.on('end', function () { + debug('wrapped end'); + if (state.decoder && !state.ended) { + var chunk = state.decoder.end(); + if (chunk && chunk.length) _this.push(chunk); + } + _this.push(null); + }); + stream.on('data', function (chunk) { + debug('wrapped data'); + if (state.decoder) chunk = state.decoder.write(chunk); + + // don't skip over falsy values in objectMode + if (state.objectMode && (chunk === null || chunk === undefined)) return;else if (!state.objectMode && (!chunk || !chunk.length)) return; + var ret = _this.push(chunk); + if (!ret) { + paused = true; + stream.pause(); + } + }); + + // proxy all the other methods. + // important when wrapping filters and duplexes. + for (var i in stream) { + if (this[i] === undefined && typeof stream[i] === 'function') { + this[i] = function methodWrap(method) { + return function methodWrapReturnFunction() { + return stream[method].apply(stream, arguments); + }; + }(i); + } + } + + // proxy certain important events. + for (var n = 0; n < kProxyEvents.length; n++) { + stream.on(kProxyEvents[n], this.emit.bind(this, kProxyEvents[n])); + } + + // when we try to consume some more bytes, simply unpause the + // underlying stream. + this._read = function (n) { + debug('wrapped _read', n); + if (paused) { + paused = false; + stream.resume(); + } + }; + return this; + }; + if (typeof Symbol === 'function') { + Readable.prototype[Symbol.asyncIterator] = function () { + if (createReadableStreamAsyncIterator === undefined) { + createReadableStreamAsyncIterator = requireAsync_iterator(); + } + return createReadableStreamAsyncIterator(this); + }; + } + Object.defineProperty(Readable.prototype, 'readableHighWaterMark', { + // making it explicit this property is not enumerable + // because otherwise some prototype manipulation in + // userland will fail + enumerable: false, + get: function get() { + return this._readableState.highWaterMark; + } + }); + Object.defineProperty(Readable.prototype, 'readableBuffer', { + // making it explicit this property is not enumerable + // because otherwise some prototype manipulation in + // userland will fail + enumerable: false, + get: function get() { + return this._readableState && this._readableState.buffer; + } + }); + Object.defineProperty(Readable.prototype, 'readableFlowing', { + // making it explicit this property is not enumerable + // because otherwise some prototype manipulation in + // userland will fail + enumerable: false, + get: function get() { + return this._readableState.flowing; + }, + set: function set(state) { + if (this._readableState) { + this._readableState.flowing = state; + } + } + }); + + // exposed for testing purposes only. + Readable._fromList = fromList; + Object.defineProperty(Readable.prototype, 'readableLength', { + // making it explicit this property is not enumerable + // because otherwise some prototype manipulation in + // userland will fail + enumerable: false, + get: function get() { + return this._readableState.length; + } + }); + + // Pluck off n bytes from an array of buffers. + // Length is the combined lengths of all the buffers in the list. + // This function is designed to be inlinable, so please take care when making + // changes to the function body. + function fromList(n, state) { + // nothing buffered + if (state.length === 0) return null; + var ret; + if (state.objectMode) ret = state.buffer.shift();else if (!n || n >= state.length) { + // read it all, truncate the list + if (state.decoder) ret = state.buffer.join('');else if (state.buffer.length === 1) ret = state.buffer.first();else ret = state.buffer.concat(state.length); + state.buffer.clear(); + } else { + // read part of list + ret = state.buffer.consume(n, state.decoder); + } + return ret; + } + function endReadable(stream) { + var state = stream._readableState; + debug('endReadable', state.endEmitted); + if (!state.endEmitted) { + state.ended = true; + process.nextTick(endReadableNT, state, stream); + } + } + function endReadableNT(state, stream) { + debug('endReadableNT', state.endEmitted, state.length); + + // Check that we didn't get one last unshift. + if (!state.endEmitted && state.length === 0) { + state.endEmitted = true; + stream.readable = false; + stream.emit('end'); + if (state.autoDestroy) { + // In case of duplex streams we need a way to detect + // if the writable side is ready for autoDestroy as well + var wState = stream._writableState; + if (!wState || wState.autoDestroy && wState.finished) { + stream.destroy(); + } + } + } + } + if (typeof Symbol === 'function') { + Readable.from = function (iterable, opts) { + if (from === undefined) { + from = requireFrom(); + } + return from(Readable, iterable, opts); + }; + } + function indexOf(xs, x) { + for (var i = 0, l = xs.length; i < l; i++) { + if (xs[i] === x) return i; + } + return -1; + } + return _stream_readable; +} + +var _stream_transform; +var hasRequired_stream_transform; + +function require_stream_transform () { + if (hasRequired_stream_transform) return _stream_transform; + hasRequired_stream_transform = 1; + + _stream_transform = Transform; + var _require$codes = requireErrors().codes, + ERR_METHOD_NOT_IMPLEMENTED = _require$codes.ERR_METHOD_NOT_IMPLEMENTED, + ERR_MULTIPLE_CALLBACK = _require$codes.ERR_MULTIPLE_CALLBACK, + ERR_TRANSFORM_ALREADY_TRANSFORMING = _require$codes.ERR_TRANSFORM_ALREADY_TRANSFORMING, + ERR_TRANSFORM_WITH_LENGTH_0 = _require$codes.ERR_TRANSFORM_WITH_LENGTH_0; + var Duplex = require_stream_duplex(); + requireInherits()(Transform, Duplex); + function afterTransform(er, data) { + var ts = this._transformState; + ts.transforming = false; + var cb = ts.writecb; + if (cb === null) { + return this.emit('error', new ERR_MULTIPLE_CALLBACK()); + } + ts.writechunk = null; + ts.writecb = null; + if (data != null) + // single equals check for both `null` and `undefined` + this.push(data); + cb(er); + var rs = this._readableState; + rs.reading = false; + if (rs.needReadable || rs.length < rs.highWaterMark) { + this._read(rs.highWaterMark); + } + } + function Transform(options) { + if (!(this instanceof Transform)) return new Transform(options); + Duplex.call(this, options); + this._transformState = { + afterTransform: afterTransform.bind(this), + needTransform: false, + transforming: false, + writecb: null, + writechunk: null, + writeencoding: null + }; + + // start out asking for a readable event once data is transformed. + this._readableState.needReadable = true; + + // we have implemented the _read method, and done the other things + // that Readable wants before the first _read call, so unset the + // sync guard flag. + this._readableState.sync = false; + if (options) { + if (typeof options.transform === 'function') this._transform = options.transform; + if (typeof options.flush === 'function') this._flush = options.flush; + } + + // When the writable side finishes, then flush out anything remaining. + this.on('prefinish', prefinish); + } + function prefinish() { + var _this = this; + if (typeof this._flush === 'function' && !this._readableState.destroyed) { + this._flush(function (er, data) { + done(_this, er, data); + }); + } else { + done(this, null, null); + } + } + Transform.prototype.push = function (chunk, encoding) { + this._transformState.needTransform = false; + return Duplex.prototype.push.call(this, chunk, encoding); + }; + + // This is the part where you do stuff! + // override this function in implementation classes. + // 'chunk' is an input chunk. + // + // Call `push(newChunk)` to pass along transformed output + // to the readable side. You may call 'push' zero or more times. + // + // Call `cb(err)` when you are done with this chunk. If you pass + // an error, then that'll put the hurt on the whole operation. If you + // never call cb(), then you'll never get another chunk. + Transform.prototype._transform = function (chunk, encoding, cb) { + cb(new ERR_METHOD_NOT_IMPLEMENTED('_transform()')); + }; + Transform.prototype._write = function (chunk, encoding, cb) { + var ts = this._transformState; + ts.writecb = cb; + ts.writechunk = chunk; + ts.writeencoding = encoding; + if (!ts.transforming) { + var rs = this._readableState; + if (ts.needTransform || rs.needReadable || rs.length < rs.highWaterMark) this._read(rs.highWaterMark); + } + }; + + // Doesn't matter what the args are here. + // _transform does all the work. + // That we got here means that the readable side wants more data. + Transform.prototype._read = function (n) { + var ts = this._transformState; + if (ts.writechunk !== null && !ts.transforming) { + ts.transforming = true; + this._transform(ts.writechunk, ts.writeencoding, ts.afterTransform); + } else { + // mark that we need a transform, so that any data that comes in + // will get processed, now that we've asked for it. + ts.needTransform = true; + } + }; + Transform.prototype._destroy = function (err, cb) { + Duplex.prototype._destroy.call(this, err, function (err2) { + cb(err2); + }); + }; + function done(stream, er, data) { + if (er) return stream.emit('error', er); + if (data != null) + // single equals check for both `null` and `undefined` + stream.push(data); + + // TODO(BridgeAR): Write a test for these two error cases + // if there's nothing in the write buffer, then that means + // that nothing more will ever be provided + if (stream._writableState.length) throw new ERR_TRANSFORM_WITH_LENGTH_0(); + if (stream._transformState.transforming) throw new ERR_TRANSFORM_ALREADY_TRANSFORMING(); + return stream.push(null); + } + return _stream_transform; +} + +var _stream_passthrough; +var hasRequired_stream_passthrough; + +function require_stream_passthrough () { + if (hasRequired_stream_passthrough) return _stream_passthrough; + hasRequired_stream_passthrough = 1; + + _stream_passthrough = PassThrough; + var Transform = require_stream_transform(); + requireInherits()(PassThrough, Transform); + function PassThrough(options) { + if (!(this instanceof PassThrough)) return new PassThrough(options); + Transform.call(this, options); + } + PassThrough.prototype._transform = function (chunk, encoding, cb) { + cb(null, chunk); + }; + return _stream_passthrough; +} + +var pipeline_1; +var hasRequiredPipeline; + +function requirePipeline () { + if (hasRequiredPipeline) return pipeline_1; + hasRequiredPipeline = 1; + + var eos; + function once(callback) { + var called = false; + return function () { + if (called) return; + called = true; + callback.apply(void 0, arguments); + }; + } + var _require$codes = requireErrors().codes, + ERR_MISSING_ARGS = _require$codes.ERR_MISSING_ARGS, + ERR_STREAM_DESTROYED = _require$codes.ERR_STREAM_DESTROYED; + function noop(err) { + // Rethrow the error if it exists to avoid swallowing it + if (err) throw err; + } + function isRequest(stream) { + return stream.setHeader && typeof stream.abort === 'function'; + } + function destroyer(stream, reading, writing, callback) { + callback = once(callback); + var closed = false; + stream.on('close', function () { + closed = true; + }); + if (eos === undefined) eos = requireEndOfStream(); + eos(stream, { + readable: reading, + writable: writing + }, function (err) { + if (err) return callback(err); + closed = true; + callback(); + }); + var destroyed = false; + return function (err) { + if (closed) return; + if (destroyed) return; + destroyed = true; + + // request.destroy just do .end - .abort is what we want + if (isRequest(stream)) return stream.abort(); + if (typeof stream.destroy === 'function') return stream.destroy(); + callback(err || new ERR_STREAM_DESTROYED('pipe')); + }; + } + function call(fn) { + fn(); + } + function pipe(from, to) { + return from.pipe(to); + } + function popCallback(streams) { + if (!streams.length) return noop; + if (typeof streams[streams.length - 1] !== 'function') return noop; + return streams.pop(); + } + function pipeline() { + for (var _len = arguments.length, streams = new Array(_len), _key = 0; _key < _len; _key++) { + streams[_key] = arguments[_key]; + } + var callback = popCallback(streams); + if (Array.isArray(streams[0])) streams = streams[0]; + if (streams.length < 2) { + throw new ERR_MISSING_ARGS('streams'); + } + var error; + var destroys = streams.map(function (stream, i) { + var reading = i < streams.length - 1; + var writing = i > 0; + return destroyer(stream, reading, writing, function (err) { + if (!error) error = err; + if (err) destroys.forEach(call); + if (reading) return; + destroys.forEach(call); + callback(error); + }); + }); + return streams.reduce(pipe); + } + pipeline_1 = pipeline; + return pipeline_1; +} + +(function (module, exports) { + var Stream = require$$0$5; + if (process.env.READABLE_STREAM === 'disable' && Stream) { + module.exports = Stream.Readable; + Object.assign(module.exports, Stream); + module.exports.Stream = Stream; + } else { + exports = module.exports = require_stream_readable(); + exports.Stream = Stream || exports; + exports.Readable = exports; + exports.Writable = require_stream_writable(); + exports.Duplex = require_stream_duplex(); + exports.Transform = require_stream_transform(); + exports.PassThrough = require_stream_passthrough(); + exports.finished = requireEndOfStream(); + exports.pipeline = requirePipeline(); + } +} (readable, readable.exports)); + +var readableExports = readable.exports; + +Object.defineProperty(lib, "__esModule", { value: true }); +lib.ReadableWebToNodeStream = void 0; +const readable_stream_1 = readableExports; +/** + * Converts a Web-API stream into Node stream.Readable class + * Node stream readable: https://nodejs.org/api/stream.html#stream_readable_streams + * Web API readable-stream: https://developer.mozilla.org/en-US/docs/Web/API/ReadableStream + * Node readable stream: https://nodejs.org/api/stream.html#stream_readable_streams + */ +class ReadableWebToNodeStream extends readable_stream_1.Readable { + /** + * + * @param stream Readable​Stream: https://developer.mozilla.org/en-US/docs/Web/API/ReadableStream + */ + constructor(stream) { + super(); + this.bytesRead = 0; + this.released = false; + this.reader = stream.getReader(); + } + /** + * Implementation of readable._read(size). + * When readable._read() is called, if data is available from the resource, + * the implementation should begin pushing that data into the read queue + * https://nodejs.org/api/stream.html#stream_readable_read_size_1 + */ + async _read() { + // Should start pushing data into the queue + // Read data from the underlying Web-API-readable-stream + if (this.released) { + this.push(null); // Signal EOF + return; + } + this.pendingRead = this.reader.read(); + const data = await this.pendingRead; + // clear the promise before pushing pushing new data to the queue and allow sequential calls to _read() + delete this.pendingRead; + if (data.done || this.released) { + this.push(null); // Signal EOF + } + else { + this.bytesRead += data.value.length; + this.push(data.value); // Push new data to the queue + } + } + /** + * If there is no unresolved read call to Web-API Readable​Stream immediately returns; + * otherwise will wait until the read is resolved. + */ + async waitForReadToComplete() { + if (this.pendingRead) { + await this.pendingRead; + } + } + /** + * Close wrapper + */ + async close() { + await this.syncAndRelease(); + } + async syncAndRelease() { + this.released = true; + await this.waitForReadToComplete(); + await this.reader.releaseLock(); + } +} +lib.ReadableWebToNodeStream = ReadableWebToNodeStream; + +// Primitive types +function dv(array) { + return new DataView(array.buffer, array.byteOffset); +} +/** + * 8-bit unsigned integer + */ +const UINT8 = { + len: 1, + get(array, offset) { + return dv(array).getUint8(offset); + }, + put(array, offset, value) { + dv(array).setUint8(offset, value); + return offset + 1; + } +}; +/** + * 16-bit unsigned integer, Little Endian byte order + */ +const UINT16_LE = { + len: 2, + get(array, offset) { + return dv(array).getUint16(offset, true); + }, + put(array, offset, value) { + dv(array).setUint16(offset, value, true); + return offset + 2; + } +}; +/** + * 16-bit unsigned integer, Big Endian byte order + */ +const UINT16_BE = { + len: 2, + get(array, offset) { + return dv(array).getUint16(offset); + }, + put(array, offset, value) { + dv(array).setUint16(offset, value); + return offset + 2; + } +}; +/** + * 32-bit unsigned integer, Little Endian byte order + */ +const UINT32_LE = { + len: 4, + get(array, offset) { + return dv(array).getUint32(offset, true); + }, + put(array, offset, value) { + dv(array).setUint32(offset, value, true); + return offset + 4; + } +}; +/** + * 32-bit unsigned integer, Big Endian byte order + */ +const UINT32_BE = { + len: 4, + get(array, offset) { + return dv(array).getUint32(offset); + }, + put(array, offset, value) { + dv(array).setUint32(offset, value); + return offset + 4; + } +}; +/** + * 32-bit signed integer, Big Endian byte order + */ +const INT32_BE = { + len: 4, + get(array, offset) { + return dv(array).getInt32(offset); + }, + put(array, offset, value) { + dv(array).setInt32(offset, value); + return offset + 4; + } +}; +/** + * 64-bit unsigned integer, Little Endian byte order + */ +const UINT64_LE = { + len: 8, + get(array, offset) { + return dv(array).getBigUint64(offset, true); + }, + put(array, offset, value) { + dv(array).setBigUint64(offset, value, true); + return offset + 8; + } +}; +/** + * Consume a fixed number of bytes from the stream and return a string with a specified encoding. + */ +class StringType { + constructor(len, encoding) { + this.len = len; + this.encoding = encoding; + } + get(uint8Array, offset) { + return node_buffer.Buffer.from(uint8Array).toString(this.encoding, offset, offset + this.len); + } +} + +const defaultMessages = 'End-Of-Stream'; +/** + * Thrown on read operation of the end of file or stream has been reached + */ +class EndOfStreamError extends Error { + constructor() { + super(defaultMessages); + } +} + +/** + * Core tokenizer + */ +class AbstractTokenizer { + constructor(fileInfo) { + /** + * Tokenizer-stream position + */ + this.position = 0; + this.numBuffer = new Uint8Array(8); + this.fileInfo = fileInfo ? fileInfo : {}; + } + /** + * Read a token from the tokenizer-stream + * @param token - The token to read + * @param position - If provided, the desired position in the tokenizer-stream + * @returns Promise with token data + */ + async readToken(token, position = this.position) { + const uint8Array = node_buffer.Buffer.alloc(token.len); + const len = await this.readBuffer(uint8Array, { position }); + if (len < token.len) + throw new EndOfStreamError(); + return token.get(uint8Array, 0); + } + /** + * Peek a token from the tokenizer-stream. + * @param token - Token to peek from the tokenizer-stream. + * @param position - Offset where to begin reading within the file. If position is null, data will be read from the current file position. + * @returns Promise with token data + */ + async peekToken(token, position = this.position) { + const uint8Array = node_buffer.Buffer.alloc(token.len); + const len = await this.peekBuffer(uint8Array, { position }); + if (len < token.len) + throw new EndOfStreamError(); + return token.get(uint8Array, 0); + } + /** + * Read a numeric token from the stream + * @param token - Numeric token + * @returns Promise with number + */ + async readNumber(token) { + const len = await this.readBuffer(this.numBuffer, { length: token.len }); + if (len < token.len) + throw new EndOfStreamError(); + return token.get(this.numBuffer, 0); + } + /** + * Read a numeric token from the stream + * @param token - Numeric token + * @returns Promise with number + */ + async peekNumber(token) { + const len = await this.peekBuffer(this.numBuffer, { length: token.len }); + if (len < token.len) + throw new EndOfStreamError(); + return token.get(this.numBuffer, 0); + } + /** + * Ignore number of bytes, advances the pointer in under tokenizer-stream. + * @param length - Number of bytes to ignore + * @return resolves the number of bytes ignored, equals length if this available, otherwise the number of bytes available + */ + async ignore(length) { + if (this.fileInfo.size !== undefined) { + const bytesLeft = this.fileInfo.size - this.position; + if (length > bytesLeft) { + this.position += bytesLeft; + return bytesLeft; + } + } + this.position += length; + return length; + } + async close() { + // empty + } + normalizeOptions(uint8Array, options) { + if (options && options.position !== undefined && options.position < this.position) { + throw new Error('`options.position` must be equal or greater than `tokenizer.position`'); + } + if (options) { + return { + mayBeLess: options.mayBeLess === true, + offset: options.offset ? options.offset : 0, + length: options.length ? options.length : (uint8Array.length - (options.offset ? options.offset : 0)), + position: options.position ? options.position : this.position + }; + } + return { + mayBeLess: false, + offset: 0, + length: uint8Array.length, + position: this.position + }; + } +} + +class BufferTokenizer extends AbstractTokenizer { + /** + * Construct BufferTokenizer + * @param uint8Array - Uint8Array to tokenize + * @param fileInfo - Pass additional file information to the tokenizer + */ + constructor(uint8Array, fileInfo) { + super(fileInfo); + this.uint8Array = uint8Array; + this.fileInfo.size = this.fileInfo.size ? this.fileInfo.size : uint8Array.length; + } + /** + * Read buffer from tokenizer + * @param uint8Array - Uint8Array to tokenize + * @param options - Read behaviour options + * @returns {Promise} + */ + async readBuffer(uint8Array, options) { + if (options && options.position) { + if (options.position < this.position) { + throw new Error('`options.position` must be equal or greater than `tokenizer.position`'); + } + this.position = options.position; + } + const bytesRead = await this.peekBuffer(uint8Array, options); + this.position += bytesRead; + return bytesRead; + } + /** + * Peek (read ahead) buffer from tokenizer + * @param uint8Array + * @param options - Read behaviour options + * @returns {Promise} + */ + async peekBuffer(uint8Array, options) { + const normOptions = this.normalizeOptions(uint8Array, options); + const bytes2read = Math.min(this.uint8Array.length - normOptions.position, normOptions.length); + if ((!normOptions.mayBeLess) && bytes2read < normOptions.length) { + throw new EndOfStreamError(); + } + else { + uint8Array.set(this.uint8Array.subarray(normOptions.position, normOptions.position + bytes2read), normOptions.offset); + return bytes2read; + } + } + async close() { + // empty + } +} + +/** + * Construct ReadStreamTokenizer from given Buffer. + * @param uint8Array - Uint8Array to tokenize + * @param fileInfo - Pass additional file information to the tokenizer + * @returns BufferTokenizer + */ +function fromBuffer(uint8Array, fileInfo) { + return new BufferTokenizer(uint8Array, fileInfo); +} + +function stringToBytes(string) { + return [...string].map(character => character.charCodeAt(0)); // eslint-disable-line unicorn/prefer-code-point +} + +/** +Checks whether the TAR checksum is valid. + +@param {Buffer} buffer - The TAR header `[offset ... offset + 512]`. +@param {number} offset - TAR header offset. +@returns {boolean} `true` if the TAR checksum is valid, otherwise `false`. +*/ +function tarHeaderChecksumMatches(buffer, offset = 0) { + const readSum = Number.parseInt(buffer.toString('utf8', 148, 154).replace(/\0.*$/, '').trim(), 8); // Read sum in header + if (Number.isNaN(readSum)) { + return false; + } + + let sum = 8 * 0x20; // Initialize signed bit sum + + for (let index = offset; index < offset + 148; index++) { + sum += buffer[index]; + } + + for (let index = offset + 156; index < offset + 512; index++) { + sum += buffer[index]; + } + + return readSum === sum; +} + +/** +ID3 UINT32 sync-safe tokenizer token. +28 bits (representing up to 256MB) integer, the msb is 0 to avoid "false syncsignals". +*/ +const uint32SyncSafeToken = { + get: (buffer, offset) => (buffer[offset + 3] & 0x7F) | ((buffer[offset + 2]) << 7) | ((buffer[offset + 1]) << 14) | ((buffer[offset]) << 21), + len: 4, +}; + +const extensions = [ + 'jpg', + 'png', + 'apng', + 'gif', + 'webp', + 'flif', + 'xcf', + 'cr2', + 'cr3', + 'orf', + 'arw', + 'dng', + 'nef', + 'rw2', + 'raf', + 'tif', + 'bmp', + 'icns', + 'jxr', + 'psd', + 'indd', + 'zip', + 'tar', + 'rar', + 'gz', + 'bz2', + '7z', + 'dmg', + 'mp4', + 'mid', + 'mkv', + 'webm', + 'mov', + 'avi', + 'mpg', + 'mp2', + 'mp3', + 'm4a', + 'oga', + 'ogg', + 'ogv', + 'opus', + 'flac', + 'wav', + 'spx', + 'amr', + 'pdf', + 'epub', + 'elf', + 'exe', + 'swf', + 'rtf', + 'wasm', + 'woff', + 'woff2', + 'eot', + 'ttf', + 'otf', + 'ico', + 'flv', + 'ps', + 'xz', + 'sqlite', + 'nes', + 'crx', + 'xpi', + 'cab', + 'deb', + 'ar', + 'rpm', + 'Z', + 'lz', + 'cfb', + 'mxf', + 'mts', + 'blend', + 'bpg', + 'docx', + 'pptx', + 'xlsx', + '3gp', + '3g2', + 'j2c', + 'jp2', + 'jpm', + 'jpx', + 'mj2', + 'aif', + 'qcp', + 'odt', + 'ods', + 'odp', + 'xml', + 'mobi', + 'heic', + 'cur', + 'ktx', + 'ape', + 'wv', + 'dcm', + 'ics', + 'glb', + 'pcap', + 'dsf', + 'lnk', + 'alias', + 'voc', + 'ac3', + 'm4v', + 'm4p', + 'm4b', + 'f4v', + 'f4p', + 'f4b', + 'f4a', + 'mie', + 'asf', + 'ogm', + 'ogx', + 'mpc', + 'arrow', + 'shp', + 'aac', + 'mp1', + 'it', + 's3m', + 'xm', + 'ai', + 'skp', + 'avif', + 'eps', + 'lzh', + 'pgp', + 'asar', + 'stl', + 'chm', + '3mf', + 'zst', + 'jxl', + 'vcf', + 'jls', + 'pst', + 'dwg', + 'parquet', + 'class', + 'arj', + 'cpio', + 'ace', + 'avro', +]; + +const mimeTypes = [ + 'image/jpeg', + 'image/png', + 'image/gif', + 'image/webp', + 'image/flif', + 'image/x-xcf', + 'image/x-canon-cr2', + 'image/x-canon-cr3', + 'image/tiff', + 'image/bmp', + 'image/vnd.ms-photo', + 'image/vnd.adobe.photoshop', + 'application/x-indesign', + 'application/epub+zip', + 'application/x-xpinstall', + 'application/vnd.oasis.opendocument.text', + 'application/vnd.oasis.opendocument.spreadsheet', + 'application/vnd.oasis.opendocument.presentation', + 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', + 'application/vnd.openxmlformats-officedocument.presentationml.presentation', + 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', + 'application/zip', + 'application/x-tar', + 'application/x-rar-compressed', + 'application/gzip', + 'application/x-bzip2', + 'application/x-7z-compressed', + 'application/x-apple-diskimage', + 'application/x-apache-arrow', + 'video/mp4', + 'audio/midi', + 'video/x-matroska', + 'video/webm', + 'video/quicktime', + 'video/vnd.avi', + 'audio/vnd.wave', + 'audio/qcelp', + 'audio/x-ms-asf', + 'video/x-ms-asf', + 'application/vnd.ms-asf', + 'video/mpeg', + 'video/3gpp', + 'audio/mpeg', + 'audio/mp4', // RFC 4337 + 'audio/opus', + 'video/ogg', + 'audio/ogg', + 'application/ogg', + 'audio/x-flac', + 'audio/ape', + 'audio/wavpack', + 'audio/amr', + 'application/pdf', + 'application/x-elf', + 'application/x-msdownload', + 'application/x-shockwave-flash', + 'application/rtf', + 'application/wasm', + 'font/woff', + 'font/woff2', + 'application/vnd.ms-fontobject', + 'font/ttf', + 'font/otf', + 'image/x-icon', + 'video/x-flv', + 'application/postscript', + 'application/eps', + 'application/x-xz', + 'application/x-sqlite3', + 'application/x-nintendo-nes-rom', + 'application/x-google-chrome-extension', + 'application/vnd.ms-cab-compressed', + 'application/x-deb', + 'application/x-unix-archive', + 'application/x-rpm', + 'application/x-compress', + 'application/x-lzip', + 'application/x-cfb', + 'application/x-mie', + 'application/mxf', + 'video/mp2t', + 'application/x-blender', + 'image/bpg', + 'image/j2c', + 'image/jp2', + 'image/jpx', + 'image/jpm', + 'image/mj2', + 'audio/aiff', + 'application/xml', + 'application/x-mobipocket-ebook', + 'image/heif', + 'image/heif-sequence', + 'image/heic', + 'image/heic-sequence', + 'image/icns', + 'image/ktx', + 'application/dicom', + 'audio/x-musepack', + 'text/calendar', + 'text/vcard', + 'model/gltf-binary', + 'application/vnd.tcpdump.pcap', + 'audio/x-dsf', // Non-standard + 'application/x.ms.shortcut', // Invented by us + 'application/x.apple.alias', // Invented by us + 'audio/x-voc', + 'audio/vnd.dolby.dd-raw', + 'audio/x-m4a', + 'image/apng', + 'image/x-olympus-orf', + 'image/x-sony-arw', + 'image/x-adobe-dng', + 'image/x-nikon-nef', + 'image/x-panasonic-rw2', + 'image/x-fujifilm-raf', + 'video/x-m4v', + 'video/3gpp2', + 'application/x-esri-shape', + 'audio/aac', + 'audio/x-it', + 'audio/x-s3m', + 'audio/x-xm', + 'video/MP1S', + 'video/MP2P', + 'application/vnd.sketchup.skp', + 'image/avif', + 'application/x-lzh-compressed', + 'application/pgp-encrypted', + 'application/x-asar', + 'model/stl', + 'application/vnd.ms-htmlhelp', + 'model/3mf', + 'image/jxl', + 'application/zstd', + 'image/jls', + 'application/vnd.ms-outlook', + 'image/vnd.dwg', + 'application/x-parquet', + 'application/java-vm', + 'application/x-arj', + 'application/x-cpio', + 'application/x-ace-compressed', + 'application/avro', +]; + +const minimumBytes = 4100; // A fair amount of file-types are detectable within this range. + +async function fileTypeFromBuffer(input) { + if (!(input instanceof Uint8Array || input instanceof ArrayBuffer)) { + throw new TypeError(`Expected the \`input\` argument to be of type \`Uint8Array\` or \`Buffer\` or \`ArrayBuffer\`, got \`${typeof input}\``); + } + + const buffer = input instanceof Uint8Array ? input : new Uint8Array(input); + + if (!(buffer?.length > 1)) { + return; + } + + return fileTypeFromTokenizer(fromBuffer(buffer)); +} + +function _check(buffer, headers, options) { + options = { + offset: 0, + ...options, + }; + + for (const [index, header] of headers.entries()) { + // If a bitmask is set + if (options.mask) { + // If header doesn't equal `buf` with bits masked off + if (header !== (options.mask[index] & buffer[index + options.offset])) { + return false; + } + } else if (header !== buffer[index + options.offset]) { + return false; + } + } + + return true; +} + +async function fileTypeFromTokenizer(tokenizer) { + try { + return new FileTypeParser().parse(tokenizer); + } catch (error) { + if (!(error instanceof EndOfStreamError)) { + throw error; + } + } +} + +class FileTypeParser { + check(header, options) { + return _check(this.buffer, header, options); + } + + checkString(header, options) { + return this.check(stringToBytes(header), options); + } + + async parse(tokenizer) { + this.buffer = node_buffer.Buffer.alloc(minimumBytes); + + // Keep reading until EOF if the file size is unknown. + if (tokenizer.fileInfo.size === undefined) { + tokenizer.fileInfo.size = Number.MAX_SAFE_INTEGER; + } + + this.tokenizer = tokenizer; + + await tokenizer.peekBuffer(this.buffer, {length: 12, mayBeLess: true}); + + // -- 2-byte signatures -- + + if (this.check([0x42, 0x4D])) { + return { + ext: 'bmp', + mime: 'image/bmp', + }; + } + + if (this.check([0x0B, 0x77])) { + return { + ext: 'ac3', + mime: 'audio/vnd.dolby.dd-raw', + }; + } + + if (this.check([0x78, 0x01])) { + return { + ext: 'dmg', + mime: 'application/x-apple-diskimage', + }; + } + + if (this.check([0x4D, 0x5A])) { + return { + ext: 'exe', + mime: 'application/x-msdownload', + }; + } + + if (this.check([0x25, 0x21])) { + await tokenizer.peekBuffer(this.buffer, {length: 24, mayBeLess: true}); + + if ( + this.checkString('PS-Adobe-', {offset: 2}) + && this.checkString(' EPSF-', {offset: 14}) + ) { + return { + ext: 'eps', + mime: 'application/eps', + }; + } + + return { + ext: 'ps', + mime: 'application/postscript', + }; + } + + if ( + this.check([0x1F, 0xA0]) + || this.check([0x1F, 0x9D]) + ) { + return { + ext: 'Z', + mime: 'application/x-compress', + }; + } + + if (this.check([0xC7, 0x71])) { + return { + ext: 'cpio', + mime: 'application/x-cpio', + }; + } + + if (this.check([0x60, 0xEA])) { + return { + ext: 'arj', + mime: 'application/x-arj', + }; + } + + // -- 3-byte signatures -- + + if (this.check([0xEF, 0xBB, 0xBF])) { // UTF-8-BOM + // Strip off UTF-8-BOM + this.tokenizer.ignore(3); + return this.parse(tokenizer); + } + + if (this.check([0x47, 0x49, 0x46])) { + return { + ext: 'gif', + mime: 'image/gif', + }; + } + + if (this.check([0x49, 0x49, 0xBC])) { + return { + ext: 'jxr', + mime: 'image/vnd.ms-photo', + }; + } + + if (this.check([0x1F, 0x8B, 0x8])) { + return { + ext: 'gz', + mime: 'application/gzip', + }; + } + + if (this.check([0x42, 0x5A, 0x68])) { + return { + ext: 'bz2', + mime: 'application/x-bzip2', + }; + } + + if (this.checkString('ID3')) { + await tokenizer.ignore(6); // Skip ID3 header until the header size + const id3HeaderLength = await tokenizer.readToken(uint32SyncSafeToken); + if (tokenizer.position + id3HeaderLength > tokenizer.fileInfo.size) { + // Guess file type based on ID3 header for backward compatibility + return { + ext: 'mp3', + mime: 'audio/mpeg', + }; + } + + await tokenizer.ignore(id3HeaderLength); + return fileTypeFromTokenizer(tokenizer); // Skip ID3 header, recursion + } + + // Musepack, SV7 + if (this.checkString('MP+')) { + return { + ext: 'mpc', + mime: 'audio/x-musepack', + }; + } + + if ( + (this.buffer[0] === 0x43 || this.buffer[0] === 0x46) + && this.check([0x57, 0x53], {offset: 1}) + ) { + return { + ext: 'swf', + mime: 'application/x-shockwave-flash', + }; + } + + // -- 4-byte signatures -- + + // Requires a sample size of 4 bytes + if (this.check([0xFF, 0xD8, 0xFF])) { + if (this.check([0xF7], {offset: 3})) { // JPG7/SOF55, indicating a ISO/IEC 14495 / JPEG-LS file + return { + ext: 'jls', + mime: 'image/jls', + }; + } + + return { + ext: 'jpg', + mime: 'image/jpeg', + }; + } + + if (this.check([0x4F, 0x62, 0x6A, 0x01])) { + return { + ext: 'avro', + mime: 'application/avro', + }; + } + + if (this.checkString('FLIF')) { + return { + ext: 'flif', + mime: 'image/flif', + }; + } + + if (this.checkString('8BPS')) { + return { + ext: 'psd', + mime: 'image/vnd.adobe.photoshop', + }; + } + + if (this.checkString('WEBP', {offset: 8})) { + return { + ext: 'webp', + mime: 'image/webp', + }; + } + + // Musepack, SV8 + if (this.checkString('MPCK')) { + return { + ext: 'mpc', + mime: 'audio/x-musepack', + }; + } + + if (this.checkString('FORM')) { + return { + ext: 'aif', + mime: 'audio/aiff', + }; + } + + if (this.checkString('icns', {offset: 0})) { + return { + ext: 'icns', + mime: 'image/icns', + }; + } + + // Zip-based file formats + // Need to be before the `zip` check + if (this.check([0x50, 0x4B, 0x3, 0x4])) { // Local file header signature + try { + while (tokenizer.position + 30 < tokenizer.fileInfo.size) { + await tokenizer.readBuffer(this.buffer, {length: 30}); + + // https://en.wikipedia.org/wiki/Zip_(file_format)#File_headers + const zipHeader = { + compressedSize: this.buffer.readUInt32LE(18), + uncompressedSize: this.buffer.readUInt32LE(22), + filenameLength: this.buffer.readUInt16LE(26), + extraFieldLength: this.buffer.readUInt16LE(28), + }; + + zipHeader.filename = await tokenizer.readToken(new StringType(zipHeader.filenameLength, 'utf-8')); + await tokenizer.ignore(zipHeader.extraFieldLength); + + // Assumes signed `.xpi` from addons.mozilla.org + if (zipHeader.filename === 'META-INF/mozilla.rsa') { + return { + ext: 'xpi', + mime: 'application/x-xpinstall', + }; + } + + if (zipHeader.filename.endsWith('.rels') || zipHeader.filename.endsWith('.xml')) { + const type = zipHeader.filename.split('/')[0]; + switch (type) { + case '_rels': + break; + case 'word': + return { + ext: 'docx', + mime: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', + }; + case 'ppt': + return { + ext: 'pptx', + mime: 'application/vnd.openxmlformats-officedocument.presentationml.presentation', + }; + case 'xl': + return { + ext: 'xlsx', + mime: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', + }; + default: + break; + } + } + + if (zipHeader.filename.startsWith('xl/')) { + return { + ext: 'xlsx', + mime: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', + }; + } + + if (zipHeader.filename.startsWith('3D/') && zipHeader.filename.endsWith('.model')) { + return { + ext: '3mf', + mime: 'model/3mf', + }; + } + + // The docx, xlsx and pptx file types extend the Office Open XML file format: + // https://en.wikipedia.org/wiki/Office_Open_XML_file_formats + // We look for: + // - one entry named '[Content_Types].xml' or '_rels/.rels', + // - one entry indicating specific type of file. + // MS Office, OpenOffice and LibreOffice may put the parts in different order, so the check should not rely on it. + if (zipHeader.filename === 'mimetype' && zipHeader.compressedSize === zipHeader.uncompressedSize) { + let mimeType = await tokenizer.readToken(new StringType(zipHeader.compressedSize, 'utf-8')); + mimeType = mimeType.trim(); + + switch (mimeType) { + case 'application/epub+zip': + return { + ext: 'epub', + mime: 'application/epub+zip', + }; + case 'application/vnd.oasis.opendocument.text': + return { + ext: 'odt', + mime: 'application/vnd.oasis.opendocument.text', + }; + case 'application/vnd.oasis.opendocument.spreadsheet': + return { + ext: 'ods', + mime: 'application/vnd.oasis.opendocument.spreadsheet', + }; + case 'application/vnd.oasis.opendocument.presentation': + return { + ext: 'odp', + mime: 'application/vnd.oasis.opendocument.presentation', + }; + default: + } + } + + // Try to find next header manually when current one is corrupted + if (zipHeader.compressedSize === 0) { + let nextHeaderIndex = -1; + + while (nextHeaderIndex < 0 && (tokenizer.position < tokenizer.fileInfo.size)) { + await tokenizer.peekBuffer(this.buffer, {mayBeLess: true}); + + nextHeaderIndex = this.buffer.indexOf('504B0304', 0, 'hex'); + // Move position to the next header if found, skip the whole buffer otherwise + await tokenizer.ignore(nextHeaderIndex >= 0 ? nextHeaderIndex : this.buffer.length); + } + } else { + await tokenizer.ignore(zipHeader.compressedSize); + } + } + } catch (error) { + if (!(error instanceof EndOfStreamError)) { + throw error; + } + } + + return { + ext: 'zip', + mime: 'application/zip', + }; + } + + if (this.checkString('OggS')) { + // This is an OGG container + await tokenizer.ignore(28); + const type = node_buffer.Buffer.alloc(8); + await tokenizer.readBuffer(type); + + // Needs to be before `ogg` check + if (_check(type, [0x4F, 0x70, 0x75, 0x73, 0x48, 0x65, 0x61, 0x64])) { + return { + ext: 'opus', + mime: 'audio/opus', + }; + } + + // If ' theora' in header. + if (_check(type, [0x80, 0x74, 0x68, 0x65, 0x6F, 0x72, 0x61])) { + return { + ext: 'ogv', + mime: 'video/ogg', + }; + } + + // If '\x01video' in header. + if (_check(type, [0x01, 0x76, 0x69, 0x64, 0x65, 0x6F, 0x00])) { + return { + ext: 'ogm', + mime: 'video/ogg', + }; + } + + // If ' FLAC' in header https://xiph.org/flac/faq.html + if (_check(type, [0x7F, 0x46, 0x4C, 0x41, 0x43])) { + return { + ext: 'oga', + mime: 'audio/ogg', + }; + } + + // 'Speex ' in header https://en.wikipedia.org/wiki/Speex + if (_check(type, [0x53, 0x70, 0x65, 0x65, 0x78, 0x20, 0x20])) { + return { + ext: 'spx', + mime: 'audio/ogg', + }; + } + + // If '\x01vorbis' in header + if (_check(type, [0x01, 0x76, 0x6F, 0x72, 0x62, 0x69, 0x73])) { + return { + ext: 'ogg', + mime: 'audio/ogg', + }; + } + + // Default OGG container https://www.iana.org/assignments/media-types/application/ogg + return { + ext: 'ogx', + mime: 'application/ogg', + }; + } + + if ( + this.check([0x50, 0x4B]) + && (this.buffer[2] === 0x3 || this.buffer[2] === 0x5 || this.buffer[2] === 0x7) + && (this.buffer[3] === 0x4 || this.buffer[3] === 0x6 || this.buffer[3] === 0x8) + ) { + return { + ext: 'zip', + mime: 'application/zip', + }; + } + + // + + // File Type Box (https://en.wikipedia.org/wiki/ISO_base_media_file_format) + // It's not required to be first, but it's recommended to be. Almost all ISO base media files start with `ftyp` box. + // `ftyp` box must contain a brand major identifier, which must consist of ISO 8859-1 printable characters. + // Here we check for 8859-1 printable characters (for simplicity, it's a mask which also catches one non-printable character). + if ( + this.checkString('ftyp', {offset: 4}) + && (this.buffer[8] & 0x60) !== 0x00 // Brand major, first character ASCII? + ) { + // They all can have MIME `video/mp4` except `application/mp4` special-case which is hard to detect. + // For some cases, we're specific, everything else falls to `video/mp4` with `mp4` extension. + const brandMajor = this.buffer.toString('binary', 8, 12).replace('\0', ' ').trim(); + switch (brandMajor) { + case 'avif': + case 'avis': + return {ext: 'avif', mime: 'image/avif'}; + case 'mif1': + return {ext: 'heic', mime: 'image/heif'}; + case 'msf1': + return {ext: 'heic', mime: 'image/heif-sequence'}; + case 'heic': + case 'heix': + return {ext: 'heic', mime: 'image/heic'}; + case 'hevc': + case 'hevx': + return {ext: 'heic', mime: 'image/heic-sequence'}; + case 'qt': + return {ext: 'mov', mime: 'video/quicktime'}; + case 'M4V': + case 'M4VH': + case 'M4VP': + return {ext: 'm4v', mime: 'video/x-m4v'}; + case 'M4P': + return {ext: 'm4p', mime: 'video/mp4'}; + case 'M4B': + return {ext: 'm4b', mime: 'audio/mp4'}; + case 'M4A': + return {ext: 'm4a', mime: 'audio/x-m4a'}; + case 'F4V': + return {ext: 'f4v', mime: 'video/mp4'}; + case 'F4P': + return {ext: 'f4p', mime: 'video/mp4'}; + case 'F4A': + return {ext: 'f4a', mime: 'audio/mp4'}; + case 'F4B': + return {ext: 'f4b', mime: 'audio/mp4'}; + case 'crx': + return {ext: 'cr3', mime: 'image/x-canon-cr3'}; + default: + if (brandMajor.startsWith('3g')) { + if (brandMajor.startsWith('3g2')) { + return {ext: '3g2', mime: 'video/3gpp2'}; + } + + return {ext: '3gp', mime: 'video/3gpp'}; + } + + return {ext: 'mp4', mime: 'video/mp4'}; + } + } + + if (this.checkString('MThd')) { + return { + ext: 'mid', + mime: 'audio/midi', + }; + } + + if ( + this.checkString('wOFF') + && ( + this.check([0x00, 0x01, 0x00, 0x00], {offset: 4}) + || this.checkString('OTTO', {offset: 4}) + ) + ) { + return { + ext: 'woff', + mime: 'font/woff', + }; + } + + if ( + this.checkString('wOF2') + && ( + this.check([0x00, 0x01, 0x00, 0x00], {offset: 4}) + || this.checkString('OTTO', {offset: 4}) + ) + ) { + return { + ext: 'woff2', + mime: 'font/woff2', + }; + } + + if (this.check([0xD4, 0xC3, 0xB2, 0xA1]) || this.check([0xA1, 0xB2, 0xC3, 0xD4])) { + return { + ext: 'pcap', + mime: 'application/vnd.tcpdump.pcap', + }; + } + + // Sony DSD Stream File (DSF) + if (this.checkString('DSD ')) { + return { + ext: 'dsf', + mime: 'audio/x-dsf', // Non-standard + }; + } + + if (this.checkString('LZIP')) { + return { + ext: 'lz', + mime: 'application/x-lzip', + }; + } + + if (this.checkString('fLaC')) { + return { + ext: 'flac', + mime: 'audio/x-flac', + }; + } + + if (this.check([0x42, 0x50, 0x47, 0xFB])) { + return { + ext: 'bpg', + mime: 'image/bpg', + }; + } + + if (this.checkString('wvpk')) { + return { + ext: 'wv', + mime: 'audio/wavpack', + }; + } + + if (this.checkString('%PDF')) { + try { + await tokenizer.ignore(1350); + const maxBufferSize = 10 * 1024 * 1024; + const buffer = node_buffer.Buffer.alloc(Math.min(maxBufferSize, tokenizer.fileInfo.size)); + await tokenizer.readBuffer(buffer, {mayBeLess: true}); + + // Check if this is an Adobe Illustrator file + if (buffer.includes(node_buffer.Buffer.from('AIPrivateData'))) { + return { + ext: 'ai', + mime: 'application/postscript', + }; + } + } catch (error) { + // Swallow end of stream error if file is too small for the Adobe AI check + if (!(error instanceof EndOfStreamError)) { + throw error; + } + } + + // Assume this is just a normal PDF + return { + ext: 'pdf', + mime: 'application/pdf', + }; + } + + if (this.check([0x00, 0x61, 0x73, 0x6D])) { + return { + ext: 'wasm', + mime: 'application/wasm', + }; + } + + // TIFF, little-endian type + if (this.check([0x49, 0x49])) { + const fileType = await this.readTiffHeader(false); + if (fileType) { + return fileType; + } + } + + // TIFF, big-endian type + if (this.check([0x4D, 0x4D])) { + const fileType = await this.readTiffHeader(true); + if (fileType) { + return fileType; + } + } + + if (this.checkString('MAC ')) { + return { + ext: 'ape', + mime: 'audio/ape', + }; + } + + // https://github.com/threatstack/libmagic/blob/master/magic/Magdir/matroska + if (this.check([0x1A, 0x45, 0xDF, 0xA3])) { // Root element: EBML + async function readField() { + const msb = await tokenizer.peekNumber(UINT8); + let mask = 0x80; + let ic = 0; // 0 = A, 1 = B, 2 = C, 3 + // = D + + while ((msb & mask) === 0 && mask !== 0) { + ++ic; + mask >>= 1; + } + + const id = node_buffer.Buffer.alloc(ic + 1); + await tokenizer.readBuffer(id); + return id; + } + + async function readElement() { + const id = await readField(); + const lengthField = await readField(); + lengthField[0] ^= 0x80 >> (lengthField.length - 1); + const nrLength = Math.min(6, lengthField.length); // JavaScript can max read 6 bytes integer + return { + id: id.readUIntBE(0, id.length), + len: lengthField.readUIntBE(lengthField.length - nrLength, nrLength), + }; + } + + async function readChildren(children) { + while (children > 0) { + const element = await readElement(); + if (element.id === 0x42_82) { + const rawValue = await tokenizer.readToken(new StringType(element.len, 'utf-8')); + return rawValue.replace(/\00.*$/g, ''); // Return DocType + } + + await tokenizer.ignore(element.len); // ignore payload + --children; + } + } + + const re = await readElement(); + const docType = await readChildren(re.len); + + switch (docType) { + case 'webm': + return { + ext: 'webm', + mime: 'video/webm', + }; + + case 'matroska': + return { + ext: 'mkv', + mime: 'video/x-matroska', + }; + + default: + return; + } + } + + // RIFF file format which might be AVI, WAV, QCP, etc + if (this.check([0x52, 0x49, 0x46, 0x46])) { + if (this.check([0x41, 0x56, 0x49], {offset: 8})) { + return { + ext: 'avi', + mime: 'video/vnd.avi', + }; + } + + if (this.check([0x57, 0x41, 0x56, 0x45], {offset: 8})) { + return { + ext: 'wav', + mime: 'audio/vnd.wave', + }; + } + + // QLCM, QCP file + if (this.check([0x51, 0x4C, 0x43, 0x4D], {offset: 8})) { + return { + ext: 'qcp', + mime: 'audio/qcelp', + }; + } + } + + if (this.checkString('SQLi')) { + return { + ext: 'sqlite', + mime: 'application/x-sqlite3', + }; + } + + if (this.check([0x4E, 0x45, 0x53, 0x1A])) { + return { + ext: 'nes', + mime: 'application/x-nintendo-nes-rom', + }; + } + + if (this.checkString('Cr24')) { + return { + ext: 'crx', + mime: 'application/x-google-chrome-extension', + }; + } + + if ( + this.checkString('MSCF') + || this.checkString('ISc(') + ) { + return { + ext: 'cab', + mime: 'application/vnd.ms-cab-compressed', + }; + } + + if (this.check([0xED, 0xAB, 0xEE, 0xDB])) { + return { + ext: 'rpm', + mime: 'application/x-rpm', + }; + } + + if (this.check([0xC5, 0xD0, 0xD3, 0xC6])) { + return { + ext: 'eps', + mime: 'application/eps', + }; + } + + if (this.check([0x28, 0xB5, 0x2F, 0xFD])) { + return { + ext: 'zst', + mime: 'application/zstd', + }; + } + + if (this.check([0x7F, 0x45, 0x4C, 0x46])) { + return { + ext: 'elf', + mime: 'application/x-elf', + }; + } + + if (this.check([0x21, 0x42, 0x44, 0x4E])) { + return { + ext: 'pst', + mime: 'application/vnd.ms-outlook', + }; + } + + if (this.checkString('PAR1')) { + return { + ext: 'parquet', + mime: 'application/x-parquet', + }; + } + + // -- 5-byte signatures -- + + if (this.check([0x4F, 0x54, 0x54, 0x4F, 0x00])) { + return { + ext: 'otf', + mime: 'font/otf', + }; + } + + if (this.checkString('#!AMR')) { + return { + ext: 'amr', + mime: 'audio/amr', + }; + } + + if (this.checkString('{\\rtf')) { + return { + ext: 'rtf', + mime: 'application/rtf', + }; + } + + if (this.check([0x46, 0x4C, 0x56, 0x01])) { + return { + ext: 'flv', + mime: 'video/x-flv', + }; + } + + if (this.checkString('IMPM')) { + return { + ext: 'it', + mime: 'audio/x-it', + }; + } + + if ( + this.checkString('-lh0-', {offset: 2}) + || this.checkString('-lh1-', {offset: 2}) + || this.checkString('-lh2-', {offset: 2}) + || this.checkString('-lh3-', {offset: 2}) + || this.checkString('-lh4-', {offset: 2}) + || this.checkString('-lh5-', {offset: 2}) + || this.checkString('-lh6-', {offset: 2}) + || this.checkString('-lh7-', {offset: 2}) + || this.checkString('-lzs-', {offset: 2}) + || this.checkString('-lz4-', {offset: 2}) + || this.checkString('-lz5-', {offset: 2}) + || this.checkString('-lhd-', {offset: 2}) + ) { + return { + ext: 'lzh', + mime: 'application/x-lzh-compressed', + }; + } + + // MPEG program stream (PS or MPEG-PS) + if (this.check([0x00, 0x00, 0x01, 0xBA])) { + // MPEG-PS, MPEG-1 Part 1 + if (this.check([0x21], {offset: 4, mask: [0xF1]})) { + return { + ext: 'mpg', // May also be .ps, .mpeg + mime: 'video/MP1S', + }; + } + + // MPEG-PS, MPEG-2 Part 1 + if (this.check([0x44], {offset: 4, mask: [0xC4]})) { + return { + ext: 'mpg', // May also be .mpg, .m2p, .vob or .sub + mime: 'video/MP2P', + }; + } + } + + if (this.checkString('ITSF')) { + return { + ext: 'chm', + mime: 'application/vnd.ms-htmlhelp', + }; + } + + if (this.check([0xCA, 0xFE, 0xBA, 0xBE])) { + return { + ext: 'class', + mime: 'application/java-vm', + }; + } + + // -- 6-byte signatures -- + + if (this.check([0xFD, 0x37, 0x7A, 0x58, 0x5A, 0x00])) { + return { + ext: 'xz', + mime: 'application/x-xz', + }; + } + + if (this.checkString('= 1000 && version <= 1050) { + return { + ext: 'dwg', + mime: 'image/vnd.dwg', + }; + } + } + + if (this.checkString('070707')) { + return { + ext: 'cpio', + mime: 'application/x-cpio', + }; + } + + // -- 7-byte signatures -- + + if (this.checkString('BLENDER')) { + return { + ext: 'blend', + mime: 'application/x-blender', + }; + } + + if (this.checkString('!')) { + await tokenizer.ignore(8); + const string = await tokenizer.readToken(new StringType(13, 'ascii')); + if (string === 'debian-binary') { + return { + ext: 'deb', + mime: 'application/x-deb', + }; + } + + return { + ext: 'ar', + mime: 'application/x-unix-archive', + }; + } + + if (this.checkString('**ACE', {offset: 7})) { + await tokenizer.peekBuffer(this.buffer, {length: 14, mayBeLess: true}); + if (this.checkString('**', {offset: 12})) { + return { + ext: 'ace', + mime: 'application/x-ace-compressed', + }; + } + } + + // -- 8-byte signatures -- + + if (this.check([0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A])) { + // APNG format (https://wiki.mozilla.org/APNG_Specification) + // 1. Find the first IDAT (image data) chunk (49 44 41 54) + // 2. Check if there is an "acTL" chunk before the IDAT one (61 63 54 4C) + + // Offset calculated as follows: + // - 8 bytes: PNG signature + // - 4 (length) + 4 (chunk type) + 13 (chunk data) + 4 (CRC): IHDR chunk + + await tokenizer.ignore(8); // ignore PNG signature + + async function readChunkHeader() { + return { + length: await tokenizer.readToken(INT32_BE), + type: await tokenizer.readToken(new StringType(4, 'binary')), + }; + } + + do { + const chunk = await readChunkHeader(); + if (chunk.length < 0) { + return; // Invalid chunk length + } + + switch (chunk.type) { + case 'IDAT': + return { + ext: 'png', + mime: 'image/png', + }; + case 'acTL': + return { + ext: 'apng', + mime: 'image/apng', + }; + default: + await tokenizer.ignore(chunk.length + 4); // Ignore chunk-data + CRC + } + } while (tokenizer.position + 8 < tokenizer.fileInfo.size); + + return { + ext: 'png', + mime: 'image/png', + }; + } + + if (this.check([0x41, 0x52, 0x52, 0x4F, 0x57, 0x31, 0x00, 0x00])) { + return { + ext: 'arrow', + mime: 'application/x-apache-arrow', + }; + } + + if (this.check([0x67, 0x6C, 0x54, 0x46, 0x02, 0x00, 0x00, 0x00])) { + return { + ext: 'glb', + mime: 'model/gltf-binary', + }; + } + + // `mov` format variants + if ( + this.check([0x66, 0x72, 0x65, 0x65], {offset: 4}) // `free` + || this.check([0x6D, 0x64, 0x61, 0x74], {offset: 4}) // `mdat` MJPEG + || this.check([0x6D, 0x6F, 0x6F, 0x76], {offset: 4}) // `moov` + || this.check([0x77, 0x69, 0x64, 0x65], {offset: 4}) // `wide` + ) { + return { + ext: 'mov', + mime: 'video/quicktime', + }; + } + + // -- 9-byte signatures -- + + if (this.check([0x49, 0x49, 0x52, 0x4F, 0x08, 0x00, 0x00, 0x00, 0x18])) { + return { + ext: 'orf', + mime: 'image/x-olympus-orf', + }; + } + + if (this.checkString('gimp xcf ')) { + return { + ext: 'xcf', + mime: 'image/x-xcf', + }; + } + + // -- 12-byte signatures -- + + if (this.check([0x49, 0x49, 0x55, 0x00, 0x18, 0x00, 0x00, 0x00, 0x88, 0xE7, 0x74, 0xD8])) { + return { + ext: 'rw2', + mime: 'image/x-panasonic-rw2', + }; + } + + // ASF_Header_Object first 80 bytes + if (this.check([0x30, 0x26, 0xB2, 0x75, 0x8E, 0x66, 0xCF, 0x11, 0xA6, 0xD9])) { + async function readHeader() { + const guid = node_buffer.Buffer.alloc(16); + await tokenizer.readBuffer(guid); + return { + id: guid, + size: Number(await tokenizer.readToken(UINT64_LE)), + }; + } + + await tokenizer.ignore(30); + // Search for header should be in first 1KB of file. + while (tokenizer.position + 24 < tokenizer.fileInfo.size) { + const header = await readHeader(); + let payload = header.size - 24; + if (_check(header.id, [0x91, 0x07, 0xDC, 0xB7, 0xB7, 0xA9, 0xCF, 0x11, 0x8E, 0xE6, 0x00, 0xC0, 0x0C, 0x20, 0x53, 0x65])) { + // Sync on Stream-Properties-Object (B7DC0791-A9B7-11CF-8EE6-00C00C205365) + const typeId = node_buffer.Buffer.alloc(16); + payload -= await tokenizer.readBuffer(typeId); + + if (_check(typeId, [0x40, 0x9E, 0x69, 0xF8, 0x4D, 0x5B, 0xCF, 0x11, 0xA8, 0xFD, 0x00, 0x80, 0x5F, 0x5C, 0x44, 0x2B])) { + // Found audio: + return { + ext: 'asf', + mime: 'audio/x-ms-asf', + }; + } + + if (_check(typeId, [0xC0, 0xEF, 0x19, 0xBC, 0x4D, 0x5B, 0xCF, 0x11, 0xA8, 0xFD, 0x00, 0x80, 0x5F, 0x5C, 0x44, 0x2B])) { + // Found video: + return { + ext: 'asf', + mime: 'video/x-ms-asf', + }; + } + + break; + } + + await tokenizer.ignore(payload); + } + + // Default to ASF generic extension + return { + ext: 'asf', + mime: 'application/vnd.ms-asf', + }; + } + + if (this.check([0xAB, 0x4B, 0x54, 0x58, 0x20, 0x31, 0x31, 0xBB, 0x0D, 0x0A, 0x1A, 0x0A])) { + return { + ext: 'ktx', + mime: 'image/ktx', + }; + } + + if ((this.check([0x7E, 0x10, 0x04]) || this.check([0x7E, 0x18, 0x04])) && this.check([0x30, 0x4D, 0x49, 0x45], {offset: 4})) { + return { + ext: 'mie', + mime: 'application/x-mie', + }; + } + + if (this.check([0x27, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00], {offset: 2})) { + return { + ext: 'shp', + mime: 'application/x-esri-shape', + }; + } + + if (this.check([0xFF, 0x4F, 0xFF, 0x51])) { + return { + ext: 'j2c', + mime: 'image/j2c', + }; + } + + if (this.check([0x00, 0x00, 0x00, 0x0C, 0x6A, 0x50, 0x20, 0x20, 0x0D, 0x0A, 0x87, 0x0A])) { + // JPEG-2000 family + + await tokenizer.ignore(20); + const type = await tokenizer.readToken(new StringType(4, 'ascii')); + switch (type) { + case 'jp2 ': + return { + ext: 'jp2', + mime: 'image/jp2', + }; + case 'jpx ': + return { + ext: 'jpx', + mime: 'image/jpx', + }; + case 'jpm ': + return { + ext: 'jpm', + mime: 'image/jpm', + }; + case 'mjp2': + return { + ext: 'mj2', + mime: 'image/mj2', + }; + default: + return; + } + } + + if ( + this.check([0xFF, 0x0A]) + || this.check([0x00, 0x00, 0x00, 0x0C, 0x4A, 0x58, 0x4C, 0x20, 0x0D, 0x0A, 0x87, 0x0A]) + ) { + return { + ext: 'jxl', + mime: 'image/jxl', + }; + } + + if (this.check([0xFE, 0xFF])) { // UTF-16-BOM-LE + if (this.check([0, 60, 0, 63, 0, 120, 0, 109, 0, 108], {offset: 2})) { + return { + ext: 'xml', + mime: 'application/xml', + }; + } + + return undefined; // Some unknown text based format + } + + // -- Unsafe signatures -- + + if ( + this.check([0x0, 0x0, 0x1, 0xBA]) + || this.check([0x0, 0x0, 0x1, 0xB3]) + ) { + return { + ext: 'mpg', + mime: 'video/mpeg', + }; + } + + if (this.check([0x00, 0x01, 0x00, 0x00, 0x00])) { + return { + ext: 'ttf', + mime: 'font/ttf', + }; + } + + if (this.check([0x00, 0x00, 0x01, 0x00])) { + return { + ext: 'ico', + mime: 'image/x-icon', + }; + } + + if (this.check([0x00, 0x00, 0x02, 0x00])) { + return { + ext: 'cur', + mime: 'image/x-icon', + }; + } + + if (this.check([0xD0, 0xCF, 0x11, 0xE0, 0xA1, 0xB1, 0x1A, 0xE1])) { + // Detected Microsoft Compound File Binary File (MS-CFB) Format. + return { + ext: 'cfb', + mime: 'application/x-cfb', + }; + } + + // Increase sample size from 12 to 256. + await tokenizer.peekBuffer(this.buffer, {length: Math.min(256, tokenizer.fileInfo.size), mayBeLess: true}); + + // -- 15-byte signatures -- + + if (this.checkString('BEGIN:')) { + if (this.checkString('VCARD', {offset: 6})) { + return { + ext: 'vcf', + mime: 'text/vcard', + }; + } + + if (this.checkString('VCALENDAR', {offset: 6})) { + return { + ext: 'ics', + mime: 'text/calendar', + }; + } + } + + // `raf` is here just to keep all the raw image detectors together. + if (this.checkString('FUJIFILMCCD-RAW')) { + return { + ext: 'raf', + mime: 'image/x-fujifilm-raf', + }; + } + + if (this.checkString('Extended Module:')) { + return { + ext: 'xm', + mime: 'audio/x-xm', + }; + } + + if (this.checkString('Creative Voice File')) { + return { + ext: 'voc', + mime: 'audio/x-voc', + }; + } + + if (this.check([0x04, 0x00, 0x00, 0x00]) && this.buffer.length >= 16) { // Rough & quick check Pickle/ASAR + const jsonSize = this.buffer.readUInt32LE(12); + if (jsonSize > 12 && this.buffer.length >= jsonSize + 16) { + try { + const header = this.buffer.slice(16, jsonSize + 16).toString(); + const json = JSON.parse(header); + // Check if Pickle is ASAR + if (json.files) { // Final check, assuring Pickle/ASAR format + return { + ext: 'asar', + mime: 'application/x-asar', + }; + } + } catch {} + } + } + + if (this.check([0x06, 0x0E, 0x2B, 0x34, 0x02, 0x05, 0x01, 0x01, 0x0D, 0x01, 0x02, 0x01, 0x01, 0x02])) { + return { + ext: 'mxf', + mime: 'application/mxf', + }; + } + + if (this.checkString('SCRM', {offset: 44})) { + return { + ext: 's3m', + mime: 'audio/x-s3m', + }; + } + + // Raw MPEG-2 transport stream (188-byte packets) + if (this.check([0x47]) && this.check([0x47], {offset: 188})) { + return { + ext: 'mts', + mime: 'video/mp2t', + }; + } + + // Blu-ray Disc Audio-Video (BDAV) MPEG-2 transport stream has 4-byte TP_extra_header before each 188-byte packet + if (this.check([0x47], {offset: 4}) && this.check([0x47], {offset: 196})) { + return { + ext: 'mts', + mime: 'video/mp2t', + }; + } + + if (this.check([0x42, 0x4F, 0x4F, 0x4B, 0x4D, 0x4F, 0x42, 0x49], {offset: 60})) { + return { + ext: 'mobi', + mime: 'application/x-mobipocket-ebook', + }; + } + + if (this.check([0x44, 0x49, 0x43, 0x4D], {offset: 128})) { + return { + ext: 'dcm', + mime: 'application/dicom', + }; + } + + if (this.check([0x4C, 0x00, 0x00, 0x00, 0x01, 0x14, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46])) { + return { + ext: 'lnk', + mime: 'application/x.ms.shortcut', // Invented by us + }; + } + + if (this.check([0x62, 0x6F, 0x6F, 0x6B, 0x00, 0x00, 0x00, 0x00, 0x6D, 0x61, 0x72, 0x6B, 0x00, 0x00, 0x00, 0x00])) { + return { + ext: 'alias', + mime: 'application/x.apple.alias', // Invented by us + }; + } + + if ( + this.check([0x4C, 0x50], {offset: 34}) + && ( + this.check([0x00, 0x00, 0x01], {offset: 8}) + || this.check([0x01, 0x00, 0x02], {offset: 8}) + || this.check([0x02, 0x00, 0x02], {offset: 8}) + ) + ) { + return { + ext: 'eot', + mime: 'application/vnd.ms-fontobject', + }; + } + + if (this.check([0x06, 0x06, 0xED, 0xF5, 0xD8, 0x1D, 0x46, 0xE5, 0xBD, 0x31, 0xEF, 0xE7, 0xFE, 0x74, 0xB7, 0x1D])) { + return { + ext: 'indd', + mime: 'application/x-indesign', + }; + } + + // Increase sample size from 256 to 512 + await tokenizer.peekBuffer(this.buffer, {length: Math.min(512, tokenizer.fileInfo.size), mayBeLess: true}); + + // Requires a buffer size of 512 bytes + if (tarHeaderChecksumMatches(this.buffer)) { + return { + ext: 'tar', + mime: 'application/x-tar', + }; + } + + if (this.check([0xFF, 0xFE])) { // UTF-16-BOM-BE + if (this.check([60, 0, 63, 0, 120, 0, 109, 0, 108, 0], {offset: 2})) { + return { + ext: 'xml', + mime: 'application/xml', + }; + } + + if (this.check([0xFF, 0x0E, 0x53, 0x00, 0x6B, 0x00, 0x65, 0x00, 0x74, 0x00, 0x63, 0x00, 0x68, 0x00, 0x55, 0x00, 0x70, 0x00, 0x20, 0x00, 0x4D, 0x00, 0x6F, 0x00, 0x64, 0x00, 0x65, 0x00, 0x6C, 0x00], {offset: 2})) { + return { + ext: 'skp', + mime: 'application/vnd.sketchup.skp', + }; + } + + return undefined; // Some text based format + } + + if (this.checkString('-----BEGIN PGP MESSAGE-----')) { + return { + ext: 'pgp', + mime: 'application/pgp-encrypted', + }; + } + + // Check MPEG 1 or 2 Layer 3 header, or 'layer 0' for ADTS (MPEG sync-word 0xFFE) + if (this.buffer.length >= 2 && this.check([0xFF, 0xE0], {offset: 0, mask: [0xFF, 0xE0]})) { + if (this.check([0x10], {offset: 1, mask: [0x16]})) { + // Check for (ADTS) MPEG-2 + if (this.check([0x08], {offset: 1, mask: [0x08]})) { + return { + ext: 'aac', + mime: 'audio/aac', + }; + } + + // Must be (ADTS) MPEG-4 + return { + ext: 'aac', + mime: 'audio/aac', + }; + } + + // MPEG 1 or 2 Layer 3 header + // Check for MPEG layer 3 + if (this.check([0x02], {offset: 1, mask: [0x06]})) { + return { + ext: 'mp3', + mime: 'audio/mpeg', + }; + } + + // Check for MPEG layer 2 + if (this.check([0x04], {offset: 1, mask: [0x06]})) { + return { + ext: 'mp2', + mime: 'audio/mpeg', + }; + } + + // Check for MPEG layer 1 + if (this.check([0x06], {offset: 1, mask: [0x06]})) { + return { + ext: 'mp1', + mime: 'audio/mpeg', + }; + } + } + } + + async readTiffTag(bigEndian) { + const tagId = await this.tokenizer.readToken(bigEndian ? UINT16_BE : UINT16_LE); + this.tokenizer.ignore(10); + switch (tagId) { + case 50_341: + return { + ext: 'arw', + mime: 'image/x-sony-arw', + }; + case 50_706: + return { + ext: 'dng', + mime: 'image/x-adobe-dng', + }; + } + } + + async readTiffIFD(bigEndian) { + const numberOfTags = await this.tokenizer.readToken(bigEndian ? UINT16_BE : UINT16_LE); + for (let n = 0; n < numberOfTags; ++n) { + const fileType = await this.readTiffTag(bigEndian); + if (fileType) { + return fileType; + } + } + } + + async readTiffHeader(bigEndian) { + const version = (bigEndian ? UINT16_BE : UINT16_LE).get(this.buffer, 2); + const ifdOffset = (bigEndian ? UINT32_BE : UINT32_LE).get(this.buffer, 4); + + if (version === 42) { + // TIFF file header + if (ifdOffset >= 6) { + if (this.checkString('CR', {offset: 8})) { + return { + ext: 'cr2', + mime: 'image/x-canon-cr2', + }; + } + + if (ifdOffset >= 8 && (this.check([0x1C, 0x00, 0xFE, 0x00], {offset: 8}) || this.check([0x1F, 0x00, 0x0B, 0x00], {offset: 8}))) { + return { + ext: 'nef', + mime: 'image/x-nikon-nef', + }; + } + } + + await this.tokenizer.ignore(ifdOffset); + const fileType = await this.readTiffIFD(bigEndian); + return fileType ?? { + ext: 'tif', + mime: 'image/tiff', + }; + } + + if (version === 43) { // Big TIFF file header + return { + ext: 'tif', + mime: 'image/tiff', + }; + } + } +} + +new Set(extensions); +new Set(mimeTypes); + +const imageExtensions = new Set([ + 'jpg', + 'png', + 'gif', + 'webp', + 'flif', + 'cr2', + 'tif', + 'bmp', + 'jxr', + 'psd', + 'ico', + 'bpg', + 'jp2', + 'jpm', + 'jpx', + 'heic', + 'cur', + 'dcm', + 'avif', +]); + +async function imageType(input) { + const result = await fileTypeFromBuffer(input); + return imageExtensions.has(result?.ext) && result; +} + +var IMAGE_EXT_LIST = [ + ".png", + ".jpg", + ".jpeg", + ".bmp", + ".gif", + ".svg", + ".tiff", + ".webp", + ".avif", +]; +function isAnImage(ext) { + return IMAGE_EXT_LIST.includes(ext.toLowerCase()); +} +function isAssetTypeAnImage(path) { + return isAnImage(require$$0$1.extname(path)); +} +function getOS() { + var appVersion = navigator.appVersion; + if (appVersion.indexOf("Win") !== -1) { + return "Windows"; + } + else if (appVersion.indexOf("Mac") !== -1) { + return "MacOS"; + } + else if (appVersion.indexOf("X11") !== -1) { + return "Linux"; + } + else { + return "Unknown OS"; + } +} +function streamToString(stream) { + var _a, stream_1, stream_1_1; + var _b, e_1, _c, _d; + return __awaiter(this, void 0, void 0, function () { + var chunks, chunk, e_1_1; + return __generator(this, function (_e) { + switch (_e.label) { + case 0: + chunks = []; + _e.label = 1; + case 1: + _e.trys.push([1, 6, 7, 12]); + _a = true, stream_1 = __asyncValues(stream); + _e.label = 2; + case 2: return [4 /*yield*/, stream_1.next()]; + case 3: + if (!(stream_1_1 = _e.sent(), _b = stream_1_1.done, !_b)) return [3 /*break*/, 5]; + _d = stream_1_1.value; + _a = false; + try { + chunk = _d; + chunks.push(Buffer.from(chunk)); + } + finally { + _a = true; + } + _e.label = 4; + case 4: return [3 /*break*/, 2]; + case 5: return [3 /*break*/, 12]; + case 6: + e_1_1 = _e.sent(); + e_1 = { error: e_1_1 }; + return [3 /*break*/, 12]; + case 7: + _e.trys.push([7, , 10, 11]); + if (!(!_a && !_b && (_c = stream_1.return))) return [3 /*break*/, 9]; + return [4 /*yield*/, _c.call(stream_1)]; + case 8: + _e.sent(); + _e.label = 9; + case 9: return [3 /*break*/, 11]; + case 10: + if (e_1) throw e_1.error; + return [7 /*endfinally*/]; + case 11: return [7 /*endfinally*/]; + case 12: return [2 /*return*/, Buffer.concat(chunks).toString("utf-8")]; + } + }); + }); +} +function getUrlAsset(url) { + return (url = url.substr(1 + url.lastIndexOf("/")).split("?")[0]).split("#")[0]; +} +function getLastImage(list) { + var reversedList = list.reverse(); + var lastImage; + reversedList.forEach(function (item) { + if (item && item.startsWith("http")) { + lastImage = item; + return item; + } + }); + return lastImage; +} +function arrayToObject(arr, key) { + var obj = {}; + arr.forEach(function (element) { + obj[element[key]] = element; + }); + return obj; +} + +var PicGoUploader = /** @class */ (function () { + function PicGoUploader(settings, plugin) { + this.settings = settings; + this.plugin = plugin; + } + PicGoUploader.prototype.uploadFiles = function (fileList) { + return __awaiter(this, void 0, void 0, function () { + var response, data, uploadUrlFullResultList; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, obsidian.requestUrl({ + url: this.settings.uploadServer, + method: "POST", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ list: fileList }), + })]; + case 1: + response = _a.sent(); + return [4 /*yield*/, response.json]; + case 2: + data = _a.sent(); + // piclist + if (data.fullResult) { + uploadUrlFullResultList = data.fullResult || []; + this.settings.uploadedImages = __spreadArray(__spreadArray([], __read((this.settings.uploadedImages || [])), false), __read(uploadUrlFullResultList), false); + } + return [2 /*return*/, data]; + } + }); + }); + }; + PicGoUploader.prototype.uploadFileByClipboard = function () { + return __awaiter(this, void 0, void 0, function () { + var res, data, uploadUrlFullResultList; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, obsidian.requestUrl({ + url: this.settings.uploadServer, + method: "POST", + })]; + case 1: + res = _a.sent(); + return [4 /*yield*/, res.json]; + case 2: + data = _a.sent(); + // piclist + if (data.fullResult) { + uploadUrlFullResultList = data.fullResult || []; + this.settings.uploadedImages = __spreadArray(__spreadArray([], __read((this.settings.uploadedImages || [])), false), __read(uploadUrlFullResultList), false); + this.plugin.saveSettings(); + } + if (res.status !== 200) { + ({ response: data, body: data.msg }); + return [2 /*return*/, { + code: -1, + msg: data.msg, + data: "", + }]; + } + else { + return [2 /*return*/, { + code: 0, + msg: "success", + data: typeof data.result == "string" ? data.result : data.result[0], + }]; + } + } + }); + }); + }; + return PicGoUploader; +}()); +var PicGoCoreUploader = /** @class */ (function () { + function PicGoCoreUploader(settings, plugin) { + this.settings = settings; + this.plugin = plugin; + } + PicGoCoreUploader.prototype.uploadFiles = function (fileList) { + return __awaiter(this, void 0, void 0, function () { + var length, cli, command, res, splitList, splitListLength, data; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: + length = fileList.length; + cli = this.settings.picgoCorePath || "picgo"; + command = "".concat(cli, " upload ").concat(fileList + .map(function (item) { return "\"".concat(item, "\""); }) + .join(" ")); + return [4 /*yield*/, this.exec(command)]; + case 1: + res = _a.sent(); + splitList = res.split("\n"); + splitListLength = splitList.length; + data = splitList.splice(splitListLength - 1 - length, length); + if (res.includes("PicGo ERROR")) { + console.log(command, res); + return [2 /*return*/, { + success: false, + msg: "失败", + }]; + } + else { + return [2 /*return*/, { + success: true, + result: data, + }]; + } + } + }); + }); + }; + // PicGo-Core 上传处理 + PicGoCoreUploader.prototype.uploadFileByClipboard = function () { + return __awaiter(this, void 0, void 0, function () { + var res, splitList, lastImage; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, this.uploadByClip()]; + case 1: + res = _a.sent(); + splitList = res.split("\n"); + lastImage = getLastImage(splitList); + if (lastImage) { + return [2 /*return*/, { + code: 0, + msg: "success", + data: lastImage, + }]; + } + else { + console.log(splitList); + // new Notice(`"Please check PicGo-Core config"\n${res}`); + return [2 /*return*/, { + code: -1, + msg: "\"Please check PicGo-Core config\"\n".concat(res), + data: "", + }]; + } + } + }); + }); + }; + // PicGo-Core的剪切上传反馈 + PicGoCoreUploader.prototype.uploadByClip = function () { + return __awaiter(this, void 0, void 0, function () { + var command, res; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: + if (this.settings.picgoCorePath) { + command = "".concat(this.settings.picgoCorePath, " upload"); + } + else { + command = "picgo upload"; + } + return [4 /*yield*/, this.exec(command)]; + case 1: + res = _a.sent(); + // const res = await this.spawnChild(); + return [2 /*return*/, res]; + } + }); + }); + }; + PicGoCoreUploader.prototype.exec = function (command) { + return __awaiter(this, void 0, void 0, function () { + var stdout, res; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, require$$0$2.exec(command)]; + case 1: + stdout = (_a.sent()).stdout; + return [4 /*yield*/, streamToString(stdout)]; + case 2: + res = _a.sent(); + return [2 /*return*/, res]; + } + }); + }); + }; + PicGoCoreUploader.prototype.spawnChild = function () { + var _a, e_1, _b, _c, _d, e_2, _e, _f; + return __awaiter(this, void 0, void 0, function () { + var spawn, child, data, _g, _h, _j, chunk, e_1_1, error, _k, _l, _m, chunk, e_2_1, exitCode; + return __generator(this, function (_o) { + switch (_o.label) { + case 0: + spawn = require("child_process").spawn; + child = spawn("picgo", ["upload"], { + shell: true, + }); + data = ""; + _o.label = 1; + case 1: + _o.trys.push([1, 6, 7, 12]); + _g = true, _h = __asyncValues(child.stdout); + _o.label = 2; + case 2: return [4 /*yield*/, _h.next()]; + case 3: + if (!(_j = _o.sent(), _a = _j.done, !_a)) return [3 /*break*/, 5]; + _c = _j.value; + _g = false; + try { + chunk = _c; + data += chunk; + } + finally { + _g = true; + } + _o.label = 4; + case 4: return [3 /*break*/, 2]; + case 5: return [3 /*break*/, 12]; + case 6: + e_1_1 = _o.sent(); + e_1 = { error: e_1_1 }; + return [3 /*break*/, 12]; + case 7: + _o.trys.push([7, , 10, 11]); + if (!(!_g && !_a && (_b = _h.return))) return [3 /*break*/, 9]; + return [4 /*yield*/, _b.call(_h)]; + case 8: + _o.sent(); + _o.label = 9; + case 9: return [3 /*break*/, 11]; + case 10: + if (e_1) throw e_1.error; + return [7 /*endfinally*/]; + case 11: return [7 /*endfinally*/]; + case 12: + error = ""; + _o.label = 13; + case 13: + _o.trys.push([13, 18, 19, 24]); + _k = true, _l = __asyncValues(child.stderr); + _o.label = 14; + case 14: return [4 /*yield*/, _l.next()]; + case 15: + if (!(_m = _o.sent(), _d = _m.done, !_d)) return [3 /*break*/, 17]; + _f = _m.value; + _k = false; + try { + chunk = _f; + error += chunk; + } + finally { + _k = true; + } + _o.label = 16; + case 16: return [3 /*break*/, 14]; + case 17: return [3 /*break*/, 24]; + case 18: + e_2_1 = _o.sent(); + e_2 = { error: e_2_1 }; + return [3 /*break*/, 24]; + case 19: + _o.trys.push([19, , 22, 23]); + if (!(!_k && !_d && (_e = _l.return))) return [3 /*break*/, 21]; + return [4 /*yield*/, _e.call(_l)]; + case 20: + _o.sent(); + _o.label = 21; + case 21: return [3 /*break*/, 23]; + case 22: + if (e_2) throw e_2.error; + return [7 /*endfinally*/]; + case 23: return [7 /*endfinally*/]; + case 24: return [4 /*yield*/, new Promise(function (resolve, reject) { + child.on("close", resolve); + })]; + case 25: + exitCode = _o.sent(); + if (exitCode) { + throw new Error("subprocess error exit ".concat(exitCode, ", ").concat(error)); + } + return [2 /*return*/, data]; + } + }); + }); + }; + return PicGoCoreUploader; +}()); + +var PicGoDeleter = /** @class */ (function () { + function PicGoDeleter(plugin) { + this.plugin = plugin; + } + PicGoDeleter.prototype.deleteImage = function (configMap) { + return __awaiter(this, void 0, void 0, function () { + var response, data; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, obsidian.requestUrl({ + url: this.plugin.settings.deleteServer, + method: "POST", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ + list: configMap, + }), + })]; + case 1: + response = _a.sent(); + data = response.json; + return [2 /*return*/, data]; + } + }); + }); + }; + return PicGoDeleter; +}()); + +// ![](./dsa/aa.png) local image should has ext +// ![](https://dasdasda) internet image should not has ext +var REGEX_FILE = /\!\[(.*?)\]\((\S+\.\w+)\)|\!\[(.*?)\]\((https?:\/\/.*?)\)/g; +var REGEX_WIKI_FILE = /\!\[\[(.*?)(\s*?\|.*?)?\]\]/g; +var Helper = /** @class */ (function () { + function Helper(app) { + this.app = app; + } + Helper.prototype.getFrontmatterValue = function (key, defaultValue) { + if (defaultValue === void 0) { defaultValue = undefined; } + var file = this.app.workspace.getActiveFile(); + if (!file) { + return undefined; + } + var path = file.path; + var cache = this.app.metadataCache.getCache(path); + var value = defaultValue; + if ((cache === null || cache === void 0 ? void 0 : cache.frontmatter) && cache.frontmatter.hasOwnProperty(key)) { + value = cache.frontmatter[key]; + } + return value; + }; + Helper.prototype.getEditor = function () { + var mdView = this.app.workspace.getActiveViewOfType(obsidian.MarkdownView); + if (mdView) { + return mdView.editor; + } + else { + return null; + } + }; + Helper.prototype.getValue = function () { + var editor = this.getEditor(); + return editor.getValue(); + }; + Helper.prototype.setValue = function (value) { + var editor = this.getEditor(); + var _a = editor.getScrollInfo(), left = _a.left, top = _a.top; + var position = editor.getCursor(); + editor.setValue(value); + editor.scrollTo(left, top); + editor.setCursor(position); + }; + // get all file urls, include local and internet + Helper.prototype.getAllFiles = function () { + var editor = this.getEditor(); + var value = editor.getValue(); + return this.getImageLink(value); + }; + Helper.prototype.getImageLink = function (value) { + var e_1, _a, e_2, _b; + var matches = value.matchAll(REGEX_FILE); + var WikiMatches = value.matchAll(REGEX_WIKI_FILE); + var fileArray = []; + try { + for (var matches_1 = __values(matches), matches_1_1 = matches_1.next(); !matches_1_1.done; matches_1_1 = matches_1.next()) { + var match = matches_1_1.value; + var source = match[0]; + var name_1 = match[1]; + var path = match[2]; + if (name_1 === undefined) { + name_1 = match[3]; + } + if (path === undefined) { + path = match[4]; + } + fileArray.push({ + path: path, + name: name_1, + source: source, + }); + } + } + catch (e_1_1) { e_1 = { error: e_1_1 }; } + finally { + try { + if (matches_1_1 && !matches_1_1.done && (_a = matches_1.return)) _a.call(matches_1); + } + finally { if (e_1) throw e_1.error; } + } + try { + for (var WikiMatches_1 = __values(WikiMatches), WikiMatches_1_1 = WikiMatches_1.next(); !WikiMatches_1_1.done; WikiMatches_1_1 = WikiMatches_1.next()) { + var match = WikiMatches_1_1.value; + console.log(match); + var name_2 = require$$0$1.parse(match[1]).name; + var path = match[1]; + var source = match[0]; + if (match[2]) { + name_2 = "".concat(name_2).concat(match[2]); + } + fileArray.push({ + path: path, + name: name_2, + source: source, + }); + } + } + catch (e_2_1) { e_2 = { error: e_2_1 }; } + finally { + try { + if (WikiMatches_1_1 && !WikiMatches_1_1.done && (_b = WikiMatches_1.return)) _b.call(WikiMatches_1); + } + finally { if (e_2) throw e_2.error; } + } + console.log(fileArray); + return fileArray; + }; + Helper.prototype.hasBlackDomain = function (src, blackDomains) { + if (blackDomains.trim() === "") { + return false; + } + var blackDomainList = blackDomains.split(",").filter(function (item) { return item !== ""; }); + var url = new URL(src); + var domain = url.hostname; + return blackDomainList.some(function (blackDomain) { return domain.includes(blackDomain); }); + }; + return Helper; +}()); + +// العربية +var ar = {}; + +// čeština +var cz = {}; + +// Dansk +var da = {}; + +// Deutsch +var de = {}; + +// English +var en = { + // setting.ts + "Plugin Settings": "Plugin Settings", + "Auto pasted upload": "Auto pasted upload", + "If you set this value true, when you paste image, it will be auto uploaded(you should set the picGo server rightly)": "If you set this value true, when you paste image, it will be auto uploaded(you should set the picGo server rightly)", + "Default uploader": "Default uploader", + "PicGo server": "PicGo server", + "Please input PicGo server": "Please input PicGo server", + "PicGo delete server": "PicGo server delete route(you need to use PicList app)", + "PicList desc": "Search PicList on Github to download and install", + "Please input PicGo delete server": "Please input PicGo delete server", + "Delete image using PicList": "Delete image using PicList", + "PicGo-Core path": "PicGo-Core path", + "Delete successfully": "Delete successfully", + "Delete failed": "Delete failed", + "Image size suffix": "Image size suffix", + "Image size suffix Description": "like |300 for resize image in ob.", + "Please input image size suffix": "Please input image size suffix", + "Error, could not delete": "Error, could not delete", + "Please input PicGo-Core path, default using environment variables": "Please input PicGo-Core path, default using environment variables", + "Work on network": "Work on network", + "Work on network Description": "Allow upload network image by 'Upload all' command.\n Or when you paste, md standard image link in your clipboard will be auto upload.", + fixPath: "fixPath", + fixPathWarning: "This option is used to fix PicGo-core upload failures on Linux and Mac. It modifies the PATH variable within Obsidian. If Obsidian encounters any bugs, turn off the option, try again! ", + "Upload when clipboard has image and text together": "Upload when clipboard has image and text together", + "When you copy, some application like Excel will image and text to clipboard, you can upload or not.": "When you copy, some application like Excel will image and text to clipboard, you can upload or not.", + "Network Domain Black List": "Network Domain Black List", + "Network Domain Black List Description": "Image in the domain list will not be upload,use comma separated", + "Delete source file after you upload file": "Delete source file after you upload file", + "Delete source file in ob assets after you upload file.": "Delete source file in ob assets after you upload file.", + "Image desc": "Image desc", + reserve: "default", + "remove all": "none", + "remove default": "remove image.png", +}; + +// British English +var enGB = {}; + +// Español +var es = {}; + +// français +var fr = {}; + +// हिन्दी +var hi = {}; + +// Bahasa Indonesia +var id = {}; + +// Italiano +var it = {}; + +// 日本語 +var ja = {}; + +// 한국어 +var ko = {}; + +// Nederlands +var nl = {}; + +// Norsk +var no = {}; + +// język polski +var pl = {}; + +// Português +var pt = {}; + +// Português do Brasil +// Brazilian Portuguese +var ptBR = {}; + +// Română +var ro = {}; + +// русский +var ru = {}; + +// Türkçe +var tr = {}; + +// 简体中文 +var zhCN = { + // setting.ts + "Plugin Settings": "插件设置", + "Auto pasted upload": "剪切板自动上传", + "If you set this value true, when you paste image, it will be auto uploaded(you should set the picGo server rightly)": "启用该选项后,黏贴图片时会自动上传(你需要正确配置picgo)", + "Default uploader": "默认上传器", + "PicGo server": "PicGo server", + "Please input PicGo server": "请输入 PicGo server", + "PicGo delete server": "PicGo server 删除接口(请使用PicList来启用此功能)", + "PicList desc": "PicList是PicGo二次开发版,请Github搜索PicList下载", + "Please input PicGo delete server": "请输入 PicGo server 删除接口", + "Delete image using PicList": "使用 PicList 删除图片", + "PicGo-Core path": "PicGo-Core 路径", + "Delete successfully": "删除成功", + "Delete failed": "删除失败", + "Error, could not delete": "错误,无法删除", + "Image size suffix": "图片大小后缀", + "Image size suffix Description": "比如:|300 用于调整图片大小", + "Please input image size suffix": "请输入图片大小后缀", + "Please input PicGo-Core path, default using environment variables": "请输入 PicGo-Core path,默认使用环境变量", + "Work on network": "应用网络图片", + "Work on network Description": "当你上传所有图片时,也会上传网络图片。以及当你进行黏贴时,剪切板中的标准 md 图片会被上传", + fixPath: "修正PATH变量", + fixPathWarning: "此选项用于修复Linux和Mac上 PicGo-Core 上传失败的问题。它会修改 Obsidian 内的 PATH 变量,如果 Obsidian 遇到任何BUG,先关闭这个选项试试!", + "Upload when clipboard has image and text together": "当剪切板同时拥有文本和图片剪切板数据时是否上传图片", + "When you copy, some application like Excel will image and text to clipboard, you can upload or not.": "当你复制时,某些应用例如 Excel 会在剪切板同时文本和图像数据,确认是否上传。", + "Network Domain Black List": "网络图片域名黑名单", + "Network Domain Black List Description": "黑名单域名中的图片将不会被上传,用英文逗号分割", + "Delete source file after you upload file": "上传文件后移除源文件", + "Delete source file in ob assets after you upload file.": "上传文件后移除在ob附件文件夹中的文件", + "Image desc": "图片描述", + reserve: "默认", + "remove all": "无", + "remove default": "移除image.png", +}; + +// 繁體中文 +var zhTW = {}; + +var localeMap = { + ar: ar, + cs: cz, + da: da, + de: de, + en: en, + 'en-gb': enGB, + es: es, + fr: fr, + hi: hi, + id: id, + it: it, + ja: ja, + ko: ko, + nl: nl, + nn: no, + pl: pl, + pt: pt, + 'pt-br': ptBR, + ro: ro, + ru: ru, + tr: tr, + 'zh-cn': zhCN, + 'zh-tw': zhTW, +}; +var locale = localeMap[obsidian.moment.locale()]; +function t(str) { + return (locale && locale[str]) || en[str]; +} + +var DEFAULT_SETTINGS = { + uploadByClipSwitch: true, + uploader: "PicGo", + uploadServer: "http://127.0.0.1:36677/upload", + deleteServer: "http://127.0.0.1:36677/delete", + imageSizeSuffix: "", + picgoCorePath: "", + workOnNetWork: false, + fixPath: false, + applyImage: true, + newWorkBlackDomains: "", + deleteSource: false, + imageDesc: "origin", +}; +var SettingTab = /** @class */ (function (_super) { + __extends(SettingTab, _super); + function SettingTab(app, plugin) { + var _this = _super.call(this, app, plugin) || this; + _this.plugin = plugin; + return _this; + } + SettingTab.prototype.display = function () { + var _this = this; + var containerEl = this.containerEl; + var os = getOS(); + containerEl.empty(); + containerEl.createEl("h2", { text: t("Plugin Settings") }); + new obsidian.Setting(containerEl) + .setName(t("Auto pasted upload")) + .setDesc(t("If you set this value true, when you paste image, it will be auto uploaded(you should set the picGo server rightly)")) + .addToggle(function (toggle) { + return toggle + .setValue(_this.plugin.settings.uploadByClipSwitch) + .onChange(function (value) { return __awaiter(_this, void 0, void 0, function () { + return __generator(this, function (_a) { + switch (_a.label) { + case 0: + this.plugin.settings.uploadByClipSwitch = value; + return [4 /*yield*/, this.plugin.saveSettings()]; + case 1: + _a.sent(); + return [2 /*return*/]; + } + }); + }); }); + }); + new obsidian.Setting(containerEl) + .setName(t("Default uploader")) + .setDesc(t("Default uploader")) + .addDropdown(function (cb) { + return cb + .addOption("PicGo", "PicGo(app)") + .addOption("PicGo-Core", "PicGo-Core") + .setValue(_this.plugin.settings.uploader) + .onChange(function (value) { return __awaiter(_this, void 0, void 0, function () { + return __generator(this, function (_a) { + switch (_a.label) { + case 0: + this.plugin.settings.uploader = value; + this.display(); + return [4 /*yield*/, this.plugin.saveSettings()]; + case 1: + _a.sent(); + return [2 /*return*/]; + } + }); + }); }); + }); + if (this.plugin.settings.uploader === "PicGo") { + new obsidian.Setting(containerEl) + .setName(t("PicGo server")) + .setDesc(t("PicGo server")) + .addText(function (text) { + return text + .setPlaceholder(t("Please input PicGo server")) + .setValue(_this.plugin.settings.uploadServer) + .onChange(function (key) { return __awaiter(_this, void 0, void 0, function () { + return __generator(this, function (_a) { + switch (_a.label) { + case 0: + this.plugin.settings.uploadServer = key; + return [4 /*yield*/, this.plugin.saveSettings()]; + case 1: + _a.sent(); + return [2 /*return*/]; + } + }); + }); }); + }); + new obsidian.Setting(containerEl) + .setName(t("PicGo delete server")) + .setDesc(t("PicList desc")) + .addText(function (text) { + return text + .setPlaceholder(t("Please input PicGo delete server")) + .setValue(_this.plugin.settings.deleteServer) + .onChange(function (key) { return __awaiter(_this, void 0, void 0, function () { + return __generator(this, function (_a) { + switch (_a.label) { + case 0: + this.plugin.settings.deleteServer = key; + return [4 /*yield*/, this.plugin.saveSettings()]; + case 1: + _a.sent(); + return [2 /*return*/]; + } + }); + }); }); + }); + } + if (this.plugin.settings.uploader === "PicGo-Core") { + new obsidian.Setting(containerEl) + .setName(t("PicGo-Core path")) + .setDesc(t("Please input PicGo-Core path, default using environment variables")) + .addText(function (text) { + return text + .setPlaceholder("") + .setValue(_this.plugin.settings.picgoCorePath) + .onChange(function (value) { return __awaiter(_this, void 0, void 0, function () { + return __generator(this, function (_a) { + switch (_a.label) { + case 0: + this.plugin.settings.picgoCorePath = value; + return [4 /*yield*/, this.plugin.saveSettings()]; + case 1: + _a.sent(); + return [2 /*return*/]; + } + }); + }); }); + }); + if (os !== "Windows") { + new obsidian.Setting(containerEl) + .setName(t("fixPath")) + .setDesc(t("fixPathWarning")) + .addToggle(function (toggle) { + return toggle + .setValue(_this.plugin.settings.fixPath) + .onChange(function (value) { return __awaiter(_this, void 0, void 0, function () { + return __generator(this, function (_a) { + switch (_a.label) { + case 0: + this.plugin.settings.fixPath = value; + return [4 /*yield*/, this.plugin.saveSettings()]; + case 1: + _a.sent(); + return [2 /*return*/]; + } + }); + }); }); + }); + } + } + // image desc setting + new obsidian.Setting(containerEl) + .setName(t("Image desc")) + .setDesc(t("Image desc")) + .addDropdown(function (cb) { + return cb + .addOption("origin", t("reserve")) // 保留全部 + .addOption("none", t("remove all")) // 移除全部 + .addOption("removeDefault", t("remove default")) // 只移除默认即 image.png + .setValue(_this.plugin.settings.imageDesc) + .onChange(function (value) { return __awaiter(_this, void 0, void 0, function () { + return __generator(this, function (_a) { + switch (_a.label) { + case 0: + this.plugin.settings.imageDesc = value; + this.display(); + return [4 /*yield*/, this.plugin.saveSettings()]; + case 1: + _a.sent(); + return [2 /*return*/]; + } + }); + }); }); + }); + new obsidian.Setting(containerEl) + .setName(t("Image size suffix")) + .setDesc(t("Image size suffix Description")) + .addText(function (text) { + return text + .setPlaceholder(t("Please input image size suffix")) + .setValue(_this.plugin.settings.imageSizeSuffix) + .onChange(function (key) { return __awaiter(_this, void 0, void 0, function () { + return __generator(this, function (_a) { + switch (_a.label) { + case 0: + this.plugin.settings.imageSizeSuffix = key; + return [4 /*yield*/, this.plugin.saveSettings()]; + case 1: + _a.sent(); + return [2 /*return*/]; + } + }); + }); }); + }); + new obsidian.Setting(containerEl) + .setName(t("Work on network")) + .setDesc(t("Work on network Description")) + .addToggle(function (toggle) { + return toggle + .setValue(_this.plugin.settings.workOnNetWork) + .onChange(function (value) { return __awaiter(_this, void 0, void 0, function () { + return __generator(this, function (_a) { + switch (_a.label) { + case 0: + this.plugin.settings.workOnNetWork = value; + this.display(); + return [4 /*yield*/, this.plugin.saveSettings()]; + case 1: + _a.sent(); + return [2 /*return*/]; + } + }); + }); }); + }); + new obsidian.Setting(containerEl) + .setName(t("Network Domain Black List")) + .setDesc(t("Network Domain Black List Description")) + .addTextArea(function (textArea) { + return textArea + .setValue(_this.plugin.settings.newWorkBlackDomains) + .onChange(function (value) { return __awaiter(_this, void 0, void 0, function () { + return __generator(this, function (_a) { + switch (_a.label) { + case 0: + this.plugin.settings.newWorkBlackDomains = value; + return [4 /*yield*/, this.plugin.saveSettings()]; + case 1: + _a.sent(); + return [2 /*return*/]; + } + }); + }); }); + }); + new obsidian.Setting(containerEl) + .setName(t("Upload when clipboard has image and text together")) + .setDesc(t("When you copy, some application like Excel will image and text to clipboard, you can upload or not.")) + .addToggle(function (toggle) { + return toggle + .setValue(_this.plugin.settings.applyImage) + .onChange(function (value) { return __awaiter(_this, void 0, void 0, function () { + return __generator(this, function (_a) { + switch (_a.label) { + case 0: + this.plugin.settings.applyImage = value; + this.display(); + return [4 /*yield*/, this.plugin.saveSettings()]; + case 1: + _a.sent(); + return [2 /*return*/]; + } + }); + }); }); + }); + new obsidian.Setting(containerEl) + .setName(t("Delete source file after you upload file")) + .setDesc(t("Delete source file in ob assets after you upload file.")) + .addToggle(function (toggle) { + return toggle + .setValue(_this.plugin.settings.deleteSource) + .onChange(function (value) { return __awaiter(_this, void 0, void 0, function () { + return __generator(this, function (_a) { + switch (_a.label) { + case 0: + this.plugin.settings.deleteSource = value; + this.display(); + return [4 /*yield*/, this.plugin.saveSettings()]; + case 1: + _a.sent(); + return [2 /*return*/]; + } + }); + }); }); + }); + }; + return SettingTab; +}(obsidian.PluginSettingTab)); + +var imageAutoUploadPlugin = /** @class */ (function (_super) { + __extends(imageAutoUploadPlugin, _super); + function imageAutoUploadPlugin() { + var _this = _super !== null && _super.apply(this, arguments) || this; + _this.addMenu = function (menu, imgPath, editor) { + menu.addItem(function (item) { + return item + .setIcon("trash-2") + .setTitle(t("Delete image using PicList")) + .onClick(function () { return __awaiter(_this, void 0, void 0, function () { + var selectedItem, res, selection; + return __generator(this, function (_b) { + switch (_b.label) { + case 0: + _b.trys.push([0, 3, , 4]); + selectedItem = this.settings.uploadedImages.find(function (item) { return item.imgUrl === imgPath; }); + if (!selectedItem) return [3 /*break*/, 2]; + return [4 /*yield*/, this.picGoDeleter.deleteImage([selectedItem])]; + case 1: + res = _b.sent(); + if (res.success) { + new obsidian.Notice(t("Delete successfully")); + selection = editor.getSelection(); + if (selection) { + editor.replaceSelection(""); + } + this.settings.uploadedImages = + this.settings.uploadedImages.filter(function (item) { return item.imgUrl !== imgPath; }); + this.saveSettings(); + } + else { + new obsidian.Notice(t("Delete failed")); + } + _b.label = 2; + case 2: return [3 /*break*/, 4]; + case 3: + _b.sent(); + new obsidian.Notice(t("Error, could not delete")); + return [3 /*break*/, 4]; + case 4: return [2 /*return*/]; + } + }); + }); }); + }); + }; + return _this; + } + imageAutoUploadPlugin.prototype.loadSettings = function () { + return __awaiter(this, void 0, void 0, function () { + var _a, _b, _c, _d; + return __generator(this, function (_e) { + switch (_e.label) { + case 0: + _a = this; + _c = (_b = Object).assign; + _d = [DEFAULT_SETTINGS]; + return [4 /*yield*/, this.loadData()]; + case 1: + _a.settings = _c.apply(_b, _d.concat([_e.sent()])); + return [2 /*return*/]; + } + }); + }); + }; + imageAutoUploadPlugin.prototype.saveSettings = function () { + return __awaiter(this, void 0, void 0, function () { + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, this.saveData(this.settings)]; + case 1: + _a.sent(); + return [2 /*return*/]; + } + }); + }); + }; + imageAutoUploadPlugin.prototype.onunload = function () { }; + imageAutoUploadPlugin.prototype.onload = function () { + return __awaiter(this, void 0, void 0, function () { + var _this = this; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, this.loadSettings()]; + case 1: + _a.sent(); + this.helper = new Helper(this.app); + this.picGoUploader = new PicGoUploader(this.settings, this); + this.picGoDeleter = new PicGoDeleter(this); + this.picGoCoreUploader = new PicGoCoreUploader(this.settings, this); + if (this.settings.uploader === "PicGo") { + this.uploader = this.picGoUploader; + } + else if (this.settings.uploader === "PicGo-Core") { + this.uploader = this.picGoCoreUploader; + if (this.settings.fixPath) { + fixPath(); + } + } + else { + new obsidian.Notice("unknown uploader"); + } + obsidian.addIcon("upload", "\n \n "); + this.addSettingTab(new SettingTab(this.app, this)); + this.addCommand({ + id: "Upload all images", + name: "Upload all images", + checkCallback: function (checking) { + var leaf = _this.app.workspace.activeLeaf; + if (leaf) { + if (!checking) { + _this.uploadAllFile(); + } + return true; + } + return false; + }, + }); + this.addCommand({ + id: "Download all images", + name: "Download all images", + checkCallback: function (checking) { + var leaf = _this.app.workspace.activeLeaf; + if (leaf) { + if (!checking) { + _this.downloadAllImageFiles(); + } + return true; + } + return false; + }, + }); + this.setupPasteHandler(); + this.registerFileMenu(); + this.registerSelection(); + return [2 /*return*/]; + } + }); + }); + }; + imageAutoUploadPlugin.prototype.registerSelection = function () { + var _this = this; + this.registerEvent(this.app.workspace.on("editor-menu", function (menu, editor, info) { + if (_this.app.workspace.getLeavesOfType("markdown").length === 0) { + return; + } + var selection = editor.getSelection(); + if (selection) { + var markdownRegex = /!\[.*\]\((.*)\)/g; + var markdownMatch = markdownRegex.exec(selection); + if (markdownMatch && markdownMatch.length > 1) { + var markdownUrl_1 = markdownMatch[1]; + if (_this.settings.uploadedImages.find(function (item) { return item.imgUrl === markdownUrl_1; })) { + _this.addMenu(menu, markdownUrl_1, editor); + } + } + } + })); + }; + imageAutoUploadPlugin.prototype.downloadAllImageFiles = function () { + return __awaiter(this, void 0, void 0, function () { + var folderPath, fileArray, imageArray, nameSet, fileArray_1, fileArray_1_1, file, url, asset, name_1, response, activeFolder, abstractActiveFolder, e_1_1, value; + var e_1, _a; + var _this = this; + return __generator(this, function (_b) { + switch (_b.label) { + case 0: + folderPath = this.getFileAssetPath(); + fileArray = this.helper.getAllFiles(); + if (!require$$0.existsSync(folderPath)) { + require$$0.mkdirSync(folderPath); + } + imageArray = []; + nameSet = new Set(); + _b.label = 1; + case 1: + _b.trys.push([1, 6, 7, 8]); + fileArray_1 = __values(fileArray), fileArray_1_1 = fileArray_1.next(); + _b.label = 2; + case 2: + if (!!fileArray_1_1.done) return [3 /*break*/, 5]; + file = fileArray_1_1.value; + if (!file.path.startsWith("http")) { + return [3 /*break*/, 4]; + } + url = file.path; + asset = getUrlAsset(url); + name_1 = decodeURI(require$$0$1.parse(asset).name).replaceAll(/[\\\\/:*?\"<>|]/g, "-"); + // 如果文件名已存在,则用随机值替换,不对文件后缀进行判断 + if (require$$0.existsSync(require$$0$1.join(folderPath))) { + name_1 = (Math.random() + 1).toString(36).substr(2, 5); + } + if (nameSet.has(name_1)) { + name_1 = "".concat(name_1, "-").concat((Math.random() + 1).toString(36).substr(2, 5)); + } + nameSet.add(name_1); + return [4 /*yield*/, this.download(url, folderPath, name_1)]; + case 3: + response = _b.sent(); + if (response.ok) { + activeFolder = obsidian.normalizePath(this.app.workspace.getActiveFile().parent.path); + abstractActiveFolder = this.app.vault.adapter.getFullPath(activeFolder); + imageArray.push({ + source: file.source, + name: name_1, + path: obsidian.normalizePath(require$$0$1.relative(abstractActiveFolder, response.path)), + }); + } + _b.label = 4; + case 4: + fileArray_1_1 = fileArray_1.next(); + return [3 /*break*/, 2]; + case 5: return [3 /*break*/, 8]; + case 6: + e_1_1 = _b.sent(); + e_1 = { error: e_1_1 }; + return [3 /*break*/, 8]; + case 7: + try { + if (fileArray_1_1 && !fileArray_1_1.done && (_a = fileArray_1.return)) _a.call(fileArray_1); + } + finally { if (e_1) throw e_1.error; } + return [7 /*endfinally*/]; + case 8: + value = this.helper.getValue(); + imageArray.map(function (image) { + var name = _this.handleName(image.name); + value = value.replace(image.source, "![".concat(name, "](").concat(encodeURI(image.path), ")")); + }); + this.helper.setValue(value); + new obsidian.Notice("all: ".concat(fileArray.length, "\nsuccess: ").concat(imageArray.length, "\nfailed: ").concat(fileArray.length - imageArray.length)); + return [2 /*return*/]; + } + }); + }); + }; + // 获取当前文件所属的附件文件夹 + imageAutoUploadPlugin.prototype.getFileAssetPath = function () { + var basePath = this.app.vault.adapter.getBasePath(); + // @ts-ignore + var assetFolder = this.app.vault.config.attachmentFolderPath; + var activeFile = this.app.vault.getAbstractFileByPath(this.app.workspace.getActiveFile().path); + // 当前文件夹下的子文件夹 + if (assetFolder.startsWith("./")) { + var activeFolder = decodeURI(require$$0$1.resolve(basePath, activeFile.parent.path)); + return require$$0$1.join(activeFolder, assetFolder); + } + else { + // 根文件夹 + return require$$0$1.join(basePath, assetFolder); + } + }; + imageAutoUploadPlugin.prototype.download = function (url, folderPath, name) { + return __awaiter(this, void 0, void 0, function () { + var response, type, buffer, path; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, obsidian.requestUrl({ url: url })]; + case 1: + response = _a.sent(); + return [4 /*yield*/, imageType(new Uint8Array(response.arrayBuffer))]; + case 2: + type = _a.sent(); + if (response.status !== 200) { + return [2 /*return*/, { + ok: false, + msg: "error", + }]; + } + if (!type) { + return [2 /*return*/, { + ok: false, + msg: "error", + }]; + } + buffer = Buffer.from(response.arrayBuffer); + try { + path = require$$0$1.join(folderPath, "".concat(name, ".").concat(type.ext)); + require$$0.writeFileSync(path, buffer); + return [2 /*return*/, { + ok: true, + msg: "ok", + path: path, + type: type, + }]; + } + catch (err) { + return [2 /*return*/, { + ok: false, + msg: err, + }]; + } + return [2 /*return*/]; + } + }); + }); + }; + imageAutoUploadPlugin.prototype.registerFileMenu = function () { + var _this = this; + this.registerEvent(this.app.workspace.on("file-menu", function (menu, file, source, leaf) { + if (source === "canvas-menu") + return false; + if (!isAssetTypeAnImage(file.path)) + return false; + menu.addItem(function (item) { + item + .setTitle("Upload") + .setIcon("upload") + .onClick(function () { + if (!(file instanceof obsidian.TFile)) { + return false; + } + _this.fileMenuUpload(file); + }); + }); + })); + }; + imageAutoUploadPlugin.prototype.fileMenuUpload = function (file) { + var e_2, _a; + var _this = this; + var content = this.helper.getValue(); + var basePath = this.app.vault.adapter.getBasePath(); + var imageList = []; + var fileArray = this.helper.getAllFiles(); + try { + for (var fileArray_2 = __values(fileArray), fileArray_2_1 = fileArray_2.next(); !fileArray_2_1.done; fileArray_2_1 = fileArray_2.next()) { + var match = fileArray_2_1.value; + var imageName = match.name; + var encodedUri = match.path; + var fileName = require$$0$1.basename(decodeURI(encodedUri)); + if (file && file.name === fileName) { + var abstractImageFile = require$$0$1.join(basePath, file.path); + if (isAssetTypeAnImage(abstractImageFile)) { + imageList.push({ + path: abstractImageFile, + name: imageName, + source: match.source, + }); + } + } + } + } + catch (e_2_1) { e_2 = { error: e_2_1 }; } + finally { + try { + if (fileArray_2_1 && !fileArray_2_1.done && (_a = fileArray_2.return)) _a.call(fileArray_2); + } + finally { if (e_2) throw e_2.error; } + } + if (imageList.length === 0) { + new obsidian.Notice("没有解析到图像文件"); + return; + } + this.uploader.uploadFiles(imageList.map(function (item) { return item.path; })).then(function (res) { + if (res.success) { + var uploadUrlList_1 = res.result; + imageList.map(function (item) { + var uploadImage = uploadUrlList_1.shift(); + var name = _this.handleName(item.name); + content = content.replaceAll(item.source, "![".concat(name, "](").concat(uploadImage, ")")); + }); + _this.helper.setValue(content); + if (_this.settings.deleteSource) { + imageList.map(function (image) { + if (!image.path.startsWith("http")) { + require$$0.unlink(image.path, function () { }); + } + }); + } + } + else { + new obsidian.Notice("Upload error"); + } + }); + }; + imageAutoUploadPlugin.prototype.filterFile = function (fileArray) { + var e_3, _a; + var imageList = []; + try { + for (var fileArray_3 = __values(fileArray), fileArray_3_1 = fileArray_3.next(); !fileArray_3_1.done; fileArray_3_1 = fileArray_3.next()) { + var match = fileArray_3_1.value; + if (match.path.startsWith("http")) { + if (this.settings.workOnNetWork) { + if (!this.helper.hasBlackDomain(match.path, this.settings.newWorkBlackDomains)) { + imageList.push({ + path: match.path, + name: match.name, + source: match.source, + }); + } + } + } + else { + imageList.push({ + path: match.path, + name: match.name, + source: match.source, + }); + } + } + } + catch (e_3_1) { e_3 = { error: e_3_1 }; } + finally { + try { + if (fileArray_3_1 && !fileArray_3_1.done && (_a = fileArray_3.return)) _a.call(fileArray_3); + } + finally { if (e_3) throw e_3.error; } + } + return imageList; + }; + imageAutoUploadPlugin.prototype.getFile = function (fileName, fileMap) { + if (!fileMap) { + fileMap = arrayToObject(this.app.vault.getFiles(), "name"); + } + return fileMap[fileName]; + }; + // uploda all file + imageAutoUploadPlugin.prototype.uploadAllFile = function () { + var e_4, _a; + var _this = this; + var content = this.helper.getValue(); + var basePath = this.app.vault.adapter.getBasePath(); + var activeFile = this.app.workspace.getActiveFile(); + var fileMap = arrayToObject(this.app.vault.getFiles(), "name"); + var filePathMap = arrayToObject(this.app.vault.getFiles(), "path"); + var imageList = []; + var fileArray = this.filterFile(this.helper.getAllFiles()); + try { + for (var fileArray_4 = __values(fileArray), fileArray_4_1 = fileArray_4.next(); !fileArray_4_1.done; fileArray_4_1 = fileArray_4.next()) { + var match = fileArray_4_1.value; + var imageName = match.name; + var encodedUri = match.path; + if (encodedUri.startsWith("http")) { + imageList.push({ + path: match.path, + name: imageName, + source: match.source, + }); + } + else { + var fileName = require$$0$1.basename(decodeURI(encodedUri)); + var file = void 0; + // 绝对路径 + if (filePathMap[decodeURI(encodedUri)]) { + file = filePathMap[decodeURI(encodedUri)]; + } + // 相对路径 + if ((!file && decodeURI(encodedUri).startsWith("./")) || + decodeURI(encodedUri).startsWith("../")) { + var filePath = require$$0$1.resolve(require$$0$1.join(basePath, require$$0$1.dirname(activeFile.path)), decodeURI(encodedUri)); + if (require$$0.existsSync(filePath)) { + var path = obsidian.normalizePath(require$$0$1.relative(basePath, require$$0$1.resolve(require$$0$1.join(basePath, require$$0$1.dirname(activeFile.path)), decodeURI(encodedUri)))); + file = filePathMap[path]; + } + } + // 尽可能短路径 + if (!file) { + file = this.getFile(fileName, fileMap); + } + if (file) { + var abstractImageFile = require$$0$1.join(basePath, file.path); + if (isAssetTypeAnImage(abstractImageFile)) { + imageList.push({ + path: abstractImageFile, + name: imageName, + source: match.source, + }); + } + } + } + } + } + catch (e_4_1) { e_4 = { error: e_4_1 }; } + finally { + try { + if (fileArray_4_1 && !fileArray_4_1.done && (_a = fileArray_4.return)) _a.call(fileArray_4); + } + finally { if (e_4) throw e_4.error; } + } + if (imageList.length === 0) { + new obsidian.Notice("没有解析到图像文件"); + return; + } + else { + new obsidian.Notice("\u5171\u627E\u5230".concat(imageList.length, "\u4E2A\u56FE\u50CF\u6587\u4EF6\uFF0C\u5F00\u59CB\u4E0A\u4F20")); + } + this.uploader.uploadFiles(imageList.map(function (item) { return item.path; })).then(function (res) { + if (res.success) { + var uploadUrlList_2 = res.result; + imageList.map(function (item) { + var uploadImage = uploadUrlList_2.shift(); + var name = _this.handleName(item.name); + content = content.replaceAll(item.source, "![".concat(name, "](").concat(uploadImage, ")")); + }); + _this.helper.setValue(content); + if (_this.settings.deleteSource) { + imageList.map(function (image) { + if (!image.path.startsWith("http")) { + require$$0.unlink(image.path, function () { }); + } + }); + } + } + else { + new obsidian.Notice("Upload error"); + } + }); + }; + imageAutoUploadPlugin.prototype.setupPasteHandler = function () { + var _this = this; + this.registerEvent(this.app.workspace.on("editor-paste", function (evt, editor, markdownView) { + var allowUpload = _this.helper.getFrontmatterValue("image-auto-upload", _this.settings.uploadByClipSwitch); + evt.clipboardData.files; + if (!allowUpload) { + return; + } + // 剪贴板内容有md格式的图片时 + if (_this.settings.workOnNetWork) { + var clipboardValue = evt.clipboardData.getData("text/plain"); + var imageList_1 = _this.helper + .getImageLink(clipboardValue) + .filter(function (image) { return image.path.startsWith("http"); }) + .filter(function (image) { + return !_this.helper.hasBlackDomain(image.path, _this.settings.newWorkBlackDomains); + }); + if (imageList_1.length !== 0) { + _this.uploader + .uploadFiles(imageList_1.map(function (item) { return item.path; })) + .then(function (res) { + var value = _this.helper.getValue(); + if (res.success) { + var uploadUrlList_3 = res.result; + imageList_1.map(function (item) { + var uploadImage = uploadUrlList_3.shift(); + var name = _this.handleName(item.name); + value = value.replaceAll(item.source, "![".concat(name, "](").concat(uploadImage, ")")); + }); + _this.helper.setValue(value); + } + else { + new obsidian.Notice("Upload error"); + } + }); + } + } + // 剪贴板中是图片时进行上传 + if (_this.canUpload(evt.clipboardData)) { + _this.uploadFileAndEmbedImgurImage(editor, function (editor, pasteId) { return __awaiter(_this, void 0, void 0, function () { + var res, url; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, this.uploader.uploadFileByClipboard()]; + case 1: + res = _a.sent(); + if (res.code !== 0) { + this.handleFailedUpload(editor, pasteId, res.msg); + return [2 /*return*/]; + } + url = res.data; + return [2 /*return*/, url]; + } + }); + }); }, evt.clipboardData).catch(); + evt.preventDefault(); + } + })); + this.registerEvent(this.app.workspace.on("editor-drop", function (evt, editor, markdownView) { return __awaiter(_this, void 0, void 0, function () { + var allowUpload, files, sendFiles_1, files_1, data; + var _this = this; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: + allowUpload = this.helper.getFrontmatterValue("image-auto-upload", this.settings.uploadByClipSwitch); + files = evt.dataTransfer.files; + if (!allowUpload) { + return [2 /*return*/]; + } + if (!(files.length !== 0 && files[0].type.startsWith("image"))) return [3 /*break*/, 2]; + sendFiles_1 = []; + files_1 = evt.dataTransfer.files; + Array.from(files_1).forEach(function (item, index) { + sendFiles_1.push(item.path); + }); + evt.preventDefault(); + return [4 /*yield*/, this.uploader.uploadFiles(sendFiles_1)]; + case 1: + data = _a.sent(); + if (data.success) { + data.result.map(function (value) { + var pasteId = (Math.random() + 1).toString(36).substr(2, 5); + _this.insertTemporaryText(editor, pasteId); + _this.embedMarkDownImage(editor, pasteId, value, files_1[0].name); + }); + } + else { + new obsidian.Notice("Upload error"); + } + _a.label = 2; + case 2: return [2 /*return*/]; + } + }); + }); })); + }; + imageAutoUploadPlugin.prototype.canUpload = function (clipboardData) { + this.settings.applyImage; + var files = clipboardData.files; + var text = clipboardData.getData("text"); + var hasImageFile = files.length !== 0 && files[0].type.startsWith("image"); + if (hasImageFile) { + if (!!text) { + return this.settings.applyImage; + } + else { + return true; + } + } + else { + return false; + } + }; + imageAutoUploadPlugin.prototype.uploadFileAndEmbedImgurImage = function (editor, callback, clipboardData) { + return __awaiter(this, void 0, void 0, function () { + var pasteId, name, url, e_5; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: + pasteId = (Math.random() + 1).toString(36).substr(2, 5); + this.insertTemporaryText(editor, pasteId); + name = clipboardData.files[0].name; + _a.label = 1; + case 1: + _a.trys.push([1, 3, , 4]); + return [4 /*yield*/, callback(editor, pasteId)]; + case 2: + url = _a.sent(); + this.embedMarkDownImage(editor, pasteId, url, name); + return [3 /*break*/, 4]; + case 3: + e_5 = _a.sent(); + this.handleFailedUpload(editor, pasteId, e_5); + return [3 /*break*/, 4]; + case 4: return [2 /*return*/]; + } + }); + }); + }; + imageAutoUploadPlugin.prototype.insertTemporaryText = function (editor, pasteId) { + var progressText = imageAutoUploadPlugin.progressTextFor(pasteId); + editor.replaceSelection(progressText + "\n"); + }; + imageAutoUploadPlugin.progressTextFor = function (id) { + return "![Uploading file...".concat(id, "]()"); + }; + imageAutoUploadPlugin.prototype.embedMarkDownImage = function (editor, pasteId, imageUrl, name) { + if (name === void 0) { name = ""; } + var progressText = imageAutoUploadPlugin.progressTextFor(pasteId); + name = this.handleName(name); + var markDownImage = "![".concat(name, "](").concat(imageUrl, ")"); + imageAutoUploadPlugin.replaceFirstOccurrence(editor, progressText, markDownImage); + }; + imageAutoUploadPlugin.prototype.handleFailedUpload = function (editor, pasteId, reason) { + new obsidian.Notice(reason); + console.error("Failed request: ", reason); + var progressText = imageAutoUploadPlugin.progressTextFor(pasteId); + imageAutoUploadPlugin.replaceFirstOccurrence(editor, progressText, "⚠️upload failed, check dev console"); + }; + imageAutoUploadPlugin.prototype.handleName = function (name) { + var imageSizeSuffix = this.settings.imageSizeSuffix || ""; + if (this.settings.imageDesc === "origin") { + return "".concat(name).concat(imageSizeSuffix); + } + else if (this.settings.imageDesc === "none") { + return ""; + } + else if (this.settings.imageDesc === "removeDefault") { + if (name === "image.png") { + return ""; + } + else { + return "".concat(name).concat(imageSizeSuffix); + } + } + else { + return "".concat(name).concat(imageSizeSuffix); + } + }; + imageAutoUploadPlugin.replaceFirstOccurrence = function (editor, target, replacement) { + var lines = editor.getValue().split("\n"); + for (var i = 0; i < lines.length; i++) { + var ch = lines[i].indexOf(target); + if (ch != -1) { + var from = { line: i, ch: ch }; + var to = { line: i, ch: ch + target.length }; + editor.replaceRange(replacement, from, to); + break; + } + } + }; + return imageAutoUploadPlugin; +}(obsidian.Plugin)); + +module.exports = imageAutoUploadPlugin; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWFpbi5qcyIsInNvdXJjZXMiOlsibm9kZV9tb2R1bGVzL3RzbGliL3RzbGliLmVzNi5qcyIsIm5vZGVfbW9kdWxlcy9pc2V4ZS93aW5kb3dzLmpzIiwibm9kZV9tb2R1bGVzL2lzZXhlL21vZGUuanMiLCJub2RlX21vZHVsZXMvaXNleGUvaW5kZXguanMiLCJub2RlX21vZHVsZXMvd2hpY2gvd2hpY2guanMiLCJub2RlX21vZHVsZXMvcGF0aC1rZXkvaW5kZXguanMiLCJub2RlX21vZHVsZXMvY3Jvc3Mtc3Bhd24vbGliL3V0aWwvcmVzb2x2ZUNvbW1hbmQuanMiLCJub2RlX21vZHVsZXMvY3Jvc3Mtc3Bhd24vbGliL3V0aWwvZXNjYXBlLmpzIiwibm9kZV9tb2R1bGVzL3NoZWJhbmctcmVnZXgvaW5kZXguanMiLCJub2RlX21vZHVsZXMvc2hlYmFuZy1jb21tYW5kL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL2Nyb3NzLXNwYXduL2xpYi91dGlsL3JlYWRTaGViYW5nLmpzIiwibm9kZV9tb2R1bGVzL2Nyb3NzLXNwYXduL2xpYi9wYXJzZS5qcyIsIm5vZGVfbW9kdWxlcy9jcm9zcy1zcGF3bi9saWIvZW5vZW50LmpzIiwibm9kZV9tb2R1bGVzL2Nyb3NzLXNwYXduL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL3N0cmlwLWZpbmFsLW5ld2xpbmUvaW5kZXguanMiLCJub2RlX21vZHVsZXMvbnBtLXJ1bi1wYXRoL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL21pbWljLWZuL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL29uZXRpbWUvaW5kZXguanMiLCJub2RlX21vZHVsZXMvaHVtYW4tc2lnbmFscy9idWlsZC9zcmMvY29yZS5qcyIsIm5vZGVfbW9kdWxlcy9odW1hbi1zaWduYWxzL2J1aWxkL3NyYy9yZWFsdGltZS5qcyIsIm5vZGVfbW9kdWxlcy9odW1hbi1zaWduYWxzL2J1aWxkL3NyYy9zaWduYWxzLmpzIiwibm9kZV9tb2R1bGVzL2h1bWFuLXNpZ25hbHMvYnVpbGQvc3JjL21haW4uanMiLCJub2RlX21vZHVsZXMvZXhlY2EvbGliL2Vycm9yLmpzIiwibm9kZV9tb2R1bGVzL2V4ZWNhL2xpYi9zdGRpby5qcyIsIm5vZGVfbW9kdWxlcy9zaWduYWwtZXhpdC9zaWduYWxzLmpzIiwibm9kZV9tb2R1bGVzL3NpZ25hbC1leGl0L2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL2V4ZWNhL2xpYi9raWxsLmpzIiwibm9kZV9tb2R1bGVzL2lzLXN0cmVhbS9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9leGVjYS9ub2RlX21vZHVsZXMvZ2V0LXN0cmVhbS9idWZmZXItc3RyZWFtLmpzIiwibm9kZV9tb2R1bGVzL2V4ZWNhL25vZGVfbW9kdWxlcy9nZXQtc3RyZWFtL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL21lcmdlLXN0cmVhbS9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9leGVjYS9saWIvc3RyZWFtLmpzIiwibm9kZV9tb2R1bGVzL2V4ZWNhL2xpYi9wcm9taXNlLmpzIiwibm9kZV9tb2R1bGVzL2V4ZWNhL2xpYi9jb21tYW5kLmpzIiwibm9kZV9tb2R1bGVzL2V4ZWNhL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL2Fuc2ktcmVnZXgvaW5kZXguanMiLCJub2RlX21vZHVsZXMvc3RyaXAtYW5zaS9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9kZWZhdWx0LXNoZWxsL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL3NoZWxsLWVudi9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9zaGVsbC1wYXRoL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL2ZpeC1wYXRoL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL3JlYWRhYmxlLXN0cmVhbS9saWIvaW50ZXJuYWwvc3RyZWFtcy9zdHJlYW0uanMiLCJub2RlX21vZHVsZXMvcmVhZGFibGUtc3RyZWFtL2xpYi9pbnRlcm5hbC9zdHJlYW1zL2J1ZmZlcl9saXN0LmpzIiwibm9kZV9tb2R1bGVzL3JlYWRhYmxlLXN0cmVhbS9saWIvaW50ZXJuYWwvc3RyZWFtcy9kZXN0cm95LmpzIiwibm9kZV9tb2R1bGVzL3JlYWRhYmxlLXN0cmVhbS9lcnJvcnMuanMiLCJub2RlX21vZHVsZXMvcmVhZGFibGUtc3RyZWFtL2xpYi9pbnRlcm5hbC9zdHJlYW1zL3N0YXRlLmpzIiwibm9kZV9tb2R1bGVzL2luaGVyaXRzL2luaGVyaXRzX2Jyb3dzZXIuanMiLCJub2RlX21vZHVsZXMvaW5oZXJpdHMvaW5oZXJpdHMuanMiLCJub2RlX21vZHVsZXMvdXRpbC1kZXByZWNhdGUvbm9kZS5qcyIsIm5vZGVfbW9kdWxlcy9yZWFkYWJsZS1zdHJlYW0vbGliL19zdHJlYW1fd3JpdGFibGUuanMiLCJub2RlX21vZHVsZXMvcmVhZGFibGUtc3RyZWFtL2xpYi9fc3RyZWFtX2R1cGxleC5qcyIsIm5vZGVfbW9kdWxlcy9zYWZlLWJ1ZmZlci9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9zdHJpbmdfZGVjb2Rlci9saWIvc3RyaW5nX2RlY29kZXIuanMiLCJub2RlX21vZHVsZXMvcmVhZGFibGUtc3RyZWFtL2xpYi9pbnRlcm5hbC9zdHJlYW1zL2VuZC1vZi1zdHJlYW0uanMiLCJub2RlX21vZHVsZXMvcmVhZGFibGUtc3RyZWFtL2xpYi9pbnRlcm5hbC9zdHJlYW1zL2FzeW5jX2l0ZXJhdG9yLmpzIiwibm9kZV9tb2R1bGVzL3JlYWRhYmxlLXN0cmVhbS9saWIvaW50ZXJuYWwvc3RyZWFtcy9mcm9tLmpzIiwibm9kZV9tb2R1bGVzL3JlYWRhYmxlLXN0cmVhbS9saWIvX3N0cmVhbV9yZWFkYWJsZS5qcyIsIm5vZGVfbW9kdWxlcy9yZWFkYWJsZS1zdHJlYW0vbGliL19zdHJlYW1fdHJhbnNmb3JtLmpzIiwibm9kZV9tb2R1bGVzL3JlYWRhYmxlLXN0cmVhbS9saWIvX3N0cmVhbV9wYXNzdGhyb3VnaC5qcyIsIm5vZGVfbW9kdWxlcy9yZWFkYWJsZS1zdHJlYW0vbGliL2ludGVybmFsL3N0cmVhbXMvcGlwZWxpbmUuanMiLCJub2RlX21vZHVsZXMvcmVhZGFibGUtc3RyZWFtL3JlYWRhYmxlLmpzIiwibm9kZV9tb2R1bGVzL3JlYWRhYmxlLXdlYi10by1ub2RlLXN0cmVhbS9saWIvaW5kZXguanMiLCJub2RlX21vZHVsZXMvdG9rZW4tdHlwZXMvbGliL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL3BlZWstcmVhZGFibGUvbGliL0VuZE9mRmlsZVN0cmVhbS5qcyIsIm5vZGVfbW9kdWxlcy9zdHJ0b2szL2xpYi9BYnN0cmFjdFRva2VuaXplci5qcyIsIm5vZGVfbW9kdWxlcy9zdHJ0b2szL2xpYi9CdWZmZXJUb2tlbml6ZXIuanMiLCJub2RlX21vZHVsZXMvc3RydG9rMy9saWIvY29yZS5qcyIsIm5vZGVfbW9kdWxlcy9maWxlLXR5cGUvdXRpbC5qcyIsIm5vZGVfbW9kdWxlcy9maWxlLXR5cGUvc3VwcG9ydGVkLmpzIiwibm9kZV9tb2R1bGVzL2ZpbGUtdHlwZS9jb3JlLmpzIiwibm9kZV9tb2R1bGVzL2ltYWdlLXR5cGUvaW5kZXguanMiLCJzcmMvdXRpbHMudHMiLCJzcmMvdXBsb2FkZXIudHMiLCJzcmMvZGVsZXRlci50cyIsInNyYy9oZWxwZXIudHMiLCJzcmMvbGFuZy9sb2NhbGUvYXIudHMiLCJzcmMvbGFuZy9sb2NhbGUvY3oudHMiLCJzcmMvbGFuZy9sb2NhbGUvZGEudHMiLCJzcmMvbGFuZy9sb2NhbGUvZGUudHMiLCJzcmMvbGFuZy9sb2NhbGUvZW4udHMiLCJzcmMvbGFuZy9sb2NhbGUvZW4tZ2IudHMiLCJzcmMvbGFuZy9sb2NhbGUvZXMudHMiLCJzcmMvbGFuZy9sb2NhbGUvZnIudHMiLCJzcmMvbGFuZy9sb2NhbGUvaGkudHMiLCJzcmMvbGFuZy9sb2NhbGUvaWQudHMiLCJzcmMvbGFuZy9sb2NhbGUvaXQudHMiLCJzcmMvbGFuZy9sb2NhbGUvamEudHMiLCJzcmMvbGFuZy9sb2NhbGUva28udHMiLCJzcmMvbGFuZy9sb2NhbGUvbmwudHMiLCJzcmMvbGFuZy9sb2NhbGUvbm8udHMiLCJzcmMvbGFuZy9sb2NhbGUvcGwudHMiLCJzcmMvbGFuZy9sb2NhbGUvcHQudHMiLCJzcmMvbGFuZy9sb2NhbGUvcHQtYnIudHMiLCJzcmMvbGFuZy9sb2NhbGUvcm8udHMiLCJzcmMvbGFuZy9sb2NhbGUvcnUudHMiLCJzcmMvbGFuZy9sb2NhbGUvdHIudHMiLCJzcmMvbGFuZy9sb2NhbGUvemgtY24udHMiLCJzcmMvbGFuZy9sb2NhbGUvemgtdHcudHMiLCJzcmMvbGFuZy9oZWxwZXJzLnRzIiwic3JjL3NldHRpbmcudHMiLCJzcmMvbWFpbi50cyJdLCJzb3VyY2VzQ29udGVudCI6WyIvKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqXHJcbkNvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLlxyXG5cclxuUGVybWlzc2lvbiB0byB1c2UsIGNvcHksIG1vZGlmeSwgYW5kL29yIGRpc3RyaWJ1dGUgdGhpcyBzb2Z0d2FyZSBmb3IgYW55XHJcbnB1cnBvc2Ugd2l0aCBvciB3aXRob3V0IGZlZSBpcyBoZXJlYnkgZ3JhbnRlZC5cclxuXHJcblRIRSBTT0ZUV0FSRSBJUyBQUk9WSURFRCBcIkFTIElTXCIgQU5EIFRIRSBBVVRIT1IgRElTQ0xBSU1TIEFMTCBXQVJSQU5USUVTIFdJVEhcclxuUkVHQVJEIFRPIFRISVMgU09GVFdBUkUgSU5DTFVESU5HIEFMTCBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZXHJcbkFORCBGSVRORVNTLiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVVUSE9SIEJFIExJQUJMRSBGT1IgQU5ZIFNQRUNJQUwsIERJUkVDVCxcclxuSU5ESVJFQ1QsIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyBPUiBBTlkgREFNQUdFUyBXSEFUU09FVkVSIFJFU1VMVElORyBGUk9NXHJcbkxPU1MgT0YgVVNFLCBEQVRBIE9SIFBST0ZJVFMsIFdIRVRIRVIgSU4gQU4gQUNUSU9OIE9GIENPTlRSQUNULCBORUdMSUdFTkNFIE9SXHJcbk9USEVSIFRPUlRJT1VTIEFDVElPTiwgQVJJU0lORyBPVVQgT0YgT1IgSU4gQ09OTkVDVElPTiBXSVRIIFRIRSBVU0UgT1JcclxuUEVSRk9STUFOQ0UgT0YgVEhJUyBTT0ZUV0FSRS5cclxuKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiogKi9cclxuLyogZ2xvYmFsIFJlZmxlY3QsIFByb21pc2UgKi9cclxuXHJcbnZhciBleHRlbmRTdGF0aWNzID0gZnVuY3Rpb24oZCwgYikge1xyXG4gICAgZXh0ZW5kU3RhdGljcyA9IE9iamVjdC5zZXRQcm90b3R5cGVPZiB8fFxyXG4gICAgICAgICh7IF9fcHJvdG9fXzogW10gfSBpbnN0YW5jZW9mIEFycmF5ICYmIGZ1bmN0aW9uIChkLCBiKSB7IGQuX19wcm90b19fID0gYjsgfSkgfHxcclxuICAgICAgICBmdW5jdGlvbiAoZCwgYikgeyBmb3IgKHZhciBwIGluIGIpIGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoYiwgcCkpIGRbcF0gPSBiW3BdOyB9O1xyXG4gICAgcmV0dXJuIGV4dGVuZFN0YXRpY3MoZCwgYik7XHJcbn07XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19leHRlbmRzKGQsIGIpIHtcclxuICAgIGlmICh0eXBlb2YgYiAhPT0gXCJmdW5jdGlvblwiICYmIGIgIT09IG51bGwpXHJcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkNsYXNzIGV4dGVuZHMgdmFsdWUgXCIgKyBTdHJpbmcoYikgKyBcIiBpcyBub3QgYSBjb25zdHJ1Y3RvciBvciBudWxsXCIpO1xyXG4gICAgZXh0ZW5kU3RhdGljcyhkLCBiKTtcclxuICAgIGZ1bmN0aW9uIF9fKCkgeyB0aGlzLmNvbnN0cnVjdG9yID0gZDsgfVxyXG4gICAgZC5wcm90b3R5cGUgPSBiID09PSBudWxsID8gT2JqZWN0LmNyZWF0ZShiKSA6IChfXy5wcm90b3R5cGUgPSBiLnByb3RvdHlwZSwgbmV3IF9fKCkpO1xyXG59XHJcblxyXG5leHBvcnQgdmFyIF9fYXNzaWduID0gZnVuY3Rpb24oKSB7XHJcbiAgICBfX2Fzc2lnbiA9IE9iamVjdC5hc3NpZ24gfHwgZnVuY3Rpb24gX19hc3NpZ24odCkge1xyXG4gICAgICAgIGZvciAodmFyIHMsIGkgPSAxLCBuID0gYXJndW1lbnRzLmxlbmd0aDsgaSA8IG47IGkrKykge1xyXG4gICAgICAgICAgICBzID0gYXJndW1lbnRzW2ldO1xyXG4gICAgICAgICAgICBmb3IgKHZhciBwIGluIHMpIGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwocywgcCkpIHRbcF0gPSBzW3BdO1xyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gdDtcclxuICAgIH1cclxuICAgIHJldHVybiBfX2Fzc2lnbi5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19yZXN0KHMsIGUpIHtcclxuICAgIHZhciB0ID0ge307XHJcbiAgICBmb3IgKHZhciBwIGluIHMpIGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwocywgcCkgJiYgZS5pbmRleE9mKHApIDwgMClcclxuICAgICAgICB0W3BdID0gc1twXTtcclxuICAgIGlmIChzICE9IG51bGwgJiYgdHlwZW9mIE9iamVjdC5nZXRPd25Qcm9wZXJ0eVN5bWJvbHMgPT09IFwiZnVuY3Rpb25cIilcclxuICAgICAgICBmb3IgKHZhciBpID0gMCwgcCA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eVN5bWJvbHMocyk7IGkgPCBwLmxlbmd0aDsgaSsrKSB7XHJcbiAgICAgICAgICAgIGlmIChlLmluZGV4T2YocFtpXSkgPCAwICYmIE9iamVjdC5wcm90b3R5cGUucHJvcGVydHlJc0VudW1lcmFibGUuY2FsbChzLCBwW2ldKSlcclxuICAgICAgICAgICAgICAgIHRbcFtpXV0gPSBzW3BbaV1dO1xyXG4gICAgICAgIH1cclxuICAgIHJldHVybiB0O1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19kZWNvcmF0ZShkZWNvcmF0b3JzLCB0YXJnZXQsIGtleSwgZGVzYykge1xyXG4gICAgdmFyIGMgPSBhcmd1bWVudHMubGVuZ3RoLCByID0gYyA8IDMgPyB0YXJnZXQgOiBkZXNjID09PSBudWxsID8gZGVzYyA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IodGFyZ2V0LCBrZXkpIDogZGVzYywgZDtcclxuICAgIGlmICh0eXBlb2YgUmVmbGVjdCA9PT0gXCJvYmplY3RcIiAmJiB0eXBlb2YgUmVmbGVjdC5kZWNvcmF0ZSA9PT0gXCJmdW5jdGlvblwiKSByID0gUmVmbGVjdC5kZWNvcmF0ZShkZWNvcmF0b3JzLCB0YXJnZXQsIGtleSwgZGVzYyk7XHJcbiAgICBlbHNlIGZvciAodmFyIGkgPSBkZWNvcmF0b3JzLmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKSBpZiAoZCA9IGRlY29yYXRvcnNbaV0pIHIgPSAoYyA8IDMgPyBkKHIpIDogYyA+IDMgPyBkKHRhcmdldCwga2V5LCByKSA6IGQodGFyZ2V0LCBrZXkpKSB8fCByO1xyXG4gICAgcmV0dXJuIGMgPiAzICYmIHIgJiYgT2JqZWN0LmRlZmluZVByb3BlcnR5KHRhcmdldCwga2V5LCByKSwgcjtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fcGFyYW0ocGFyYW1JbmRleCwgZGVjb3JhdG9yKSB7XHJcbiAgICByZXR1cm4gZnVuY3Rpb24gKHRhcmdldCwga2V5KSB7IGRlY29yYXRvcih0YXJnZXQsIGtleSwgcGFyYW1JbmRleCk7IH1cclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fZXNEZWNvcmF0ZShjdG9yLCBkZXNjcmlwdG9ySW4sIGRlY29yYXRvcnMsIGNvbnRleHRJbiwgaW5pdGlhbGl6ZXJzLCBleHRyYUluaXRpYWxpemVycykge1xyXG4gICAgZnVuY3Rpb24gYWNjZXB0KGYpIHsgaWYgKGYgIT09IHZvaWQgMCAmJiB0eXBlb2YgZiAhPT0gXCJmdW5jdGlvblwiKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiRnVuY3Rpb24gZXhwZWN0ZWRcIik7IHJldHVybiBmOyB9XHJcbiAgICB2YXIga2luZCA9IGNvbnRleHRJbi5raW5kLCBrZXkgPSBraW5kID09PSBcImdldHRlclwiID8gXCJnZXRcIiA6IGtpbmQgPT09IFwic2V0dGVyXCIgPyBcInNldFwiIDogXCJ2YWx1ZVwiO1xyXG4gICAgdmFyIHRhcmdldCA9ICFkZXNjcmlwdG9ySW4gJiYgY3RvciA/IGNvbnRleHRJbltcInN0YXRpY1wiXSA/IGN0b3IgOiBjdG9yLnByb3RvdHlwZSA6IG51bGw7XHJcbiAgICB2YXIgZGVzY3JpcHRvciA9IGRlc2NyaXB0b3JJbiB8fCAodGFyZ2V0ID8gT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcih0YXJnZXQsIGNvbnRleHRJbi5uYW1lKSA6IHt9KTtcclxuICAgIHZhciBfLCBkb25lID0gZmFsc2U7XHJcbiAgICBmb3IgKHZhciBpID0gZGVjb3JhdG9ycy5sZW5ndGggLSAxOyBpID49IDA7IGktLSkge1xyXG4gICAgICAgIHZhciBjb250ZXh0ID0ge307XHJcbiAgICAgICAgZm9yICh2YXIgcCBpbiBjb250ZXh0SW4pIGNvbnRleHRbcF0gPSBwID09PSBcImFjY2Vzc1wiID8ge30gOiBjb250ZXh0SW5bcF07XHJcbiAgICAgICAgZm9yICh2YXIgcCBpbiBjb250ZXh0SW4uYWNjZXNzKSBjb250ZXh0LmFjY2Vzc1twXSA9IGNvbnRleHRJbi5hY2Nlc3NbcF07XHJcbiAgICAgICAgY29udGV4dC5hZGRJbml0aWFsaXplciA9IGZ1bmN0aW9uIChmKSB7IGlmIChkb25lKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiQ2Fubm90IGFkZCBpbml0aWFsaXplcnMgYWZ0ZXIgZGVjb3JhdGlvbiBoYXMgY29tcGxldGVkXCIpOyBleHRyYUluaXRpYWxpemVycy5wdXNoKGFjY2VwdChmIHx8IG51bGwpKTsgfTtcclxuICAgICAgICB2YXIgcmVzdWx0ID0gKDAsIGRlY29yYXRvcnNbaV0pKGtpbmQgPT09IFwiYWNjZXNzb3JcIiA/IHsgZ2V0OiBkZXNjcmlwdG9yLmdldCwgc2V0OiBkZXNjcmlwdG9yLnNldCB9IDogZGVzY3JpcHRvcltrZXldLCBjb250ZXh0KTtcclxuICAgICAgICBpZiAoa2luZCA9PT0gXCJhY2Nlc3NvclwiKSB7XHJcbiAgICAgICAgICAgIGlmIChyZXN1bHQgPT09IHZvaWQgMCkgY29udGludWU7XHJcbiAgICAgICAgICAgIGlmIChyZXN1bHQgPT09IG51bGwgfHwgdHlwZW9mIHJlc3VsdCAhPT0gXCJvYmplY3RcIikgdGhyb3cgbmV3IFR5cGVFcnJvcihcIk9iamVjdCBleHBlY3RlZFwiKTtcclxuICAgICAgICAgICAgaWYgKF8gPSBhY2NlcHQocmVzdWx0LmdldCkpIGRlc2NyaXB0b3IuZ2V0ID0gXztcclxuICAgICAgICAgICAgaWYgKF8gPSBhY2NlcHQocmVzdWx0LnNldCkpIGRlc2NyaXB0b3Iuc2V0ID0gXztcclxuICAgICAgICAgICAgaWYgKF8gPSBhY2NlcHQocmVzdWx0LmluaXQpKSBpbml0aWFsaXplcnMucHVzaChfKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgZWxzZSBpZiAoXyA9IGFjY2VwdChyZXN1bHQpKSB7XHJcbiAgICAgICAgICAgIGlmIChraW5kID09PSBcImZpZWxkXCIpIGluaXRpYWxpemVycy5wdXNoKF8pO1xyXG4gICAgICAgICAgICBlbHNlIGRlc2NyaXB0b3Jba2V5XSA9IF87XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG4gICAgaWYgKHRhcmdldCkgT2JqZWN0LmRlZmluZVByb3BlcnR5KHRhcmdldCwgY29udGV4dEluLm5hbWUsIGRlc2NyaXB0b3IpO1xyXG4gICAgZG9uZSA9IHRydWU7XHJcbn07XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19ydW5Jbml0aWFsaXplcnModGhpc0FyZywgaW5pdGlhbGl6ZXJzLCB2YWx1ZSkge1xyXG4gICAgdmFyIHVzZVZhbHVlID0gYXJndW1lbnRzLmxlbmd0aCA+IDI7XHJcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGluaXRpYWxpemVycy5sZW5ndGg7IGkrKykge1xyXG4gICAgICAgIHZhbHVlID0gdXNlVmFsdWUgPyBpbml0aWFsaXplcnNbaV0uY2FsbCh0aGlzQXJnLCB2YWx1ZSkgOiBpbml0aWFsaXplcnNbaV0uY2FsbCh0aGlzQXJnKTtcclxuICAgIH1cclxuICAgIHJldHVybiB1c2VWYWx1ZSA/IHZhbHVlIDogdm9pZCAwO1xyXG59O1xyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fcHJvcEtleSh4KSB7XHJcbiAgICByZXR1cm4gdHlwZW9mIHggPT09IFwic3ltYm9sXCIgPyB4IDogXCJcIi5jb25jYXQoeCk7XHJcbn07XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19zZXRGdW5jdGlvbk5hbWUoZiwgbmFtZSwgcHJlZml4KSB7XHJcbiAgICBpZiAodHlwZW9mIG5hbWUgPT09IFwic3ltYm9sXCIpIG5hbWUgPSBuYW1lLmRlc2NyaXB0aW9uID8gXCJbXCIuY29uY2F0KG5hbWUuZGVzY3JpcHRpb24sIFwiXVwiKSA6IFwiXCI7XHJcbiAgICByZXR1cm4gT2JqZWN0LmRlZmluZVByb3BlcnR5KGYsIFwibmFtZVwiLCB7IGNvbmZpZ3VyYWJsZTogdHJ1ZSwgdmFsdWU6IHByZWZpeCA/IFwiXCIuY29uY2F0KHByZWZpeCwgXCIgXCIsIG5hbWUpIDogbmFtZSB9KTtcclxufTtcclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX21ldGFkYXRhKG1ldGFkYXRhS2V5LCBtZXRhZGF0YVZhbHVlKSB7XHJcbiAgICBpZiAodHlwZW9mIFJlZmxlY3QgPT09IFwib2JqZWN0XCIgJiYgdHlwZW9mIFJlZmxlY3QubWV0YWRhdGEgPT09IFwiZnVuY3Rpb25cIikgcmV0dXJuIFJlZmxlY3QubWV0YWRhdGEobWV0YWRhdGFLZXksIG1ldGFkYXRhVmFsdWUpO1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19hd2FpdGVyKHRoaXNBcmcsIF9hcmd1bWVudHMsIFAsIGdlbmVyYXRvcikge1xyXG4gICAgZnVuY3Rpb24gYWRvcHQodmFsdWUpIHsgcmV0dXJuIHZhbHVlIGluc3RhbmNlb2YgUCA/IHZhbHVlIDogbmV3IFAoZnVuY3Rpb24gKHJlc29sdmUpIHsgcmVzb2x2ZSh2YWx1ZSk7IH0pOyB9XHJcbiAgICByZXR1cm4gbmV3IChQIHx8IChQID0gUHJvbWlzZSkpKGZ1bmN0aW9uIChyZXNvbHZlLCByZWplY3QpIHtcclxuICAgICAgICBmdW5jdGlvbiBmdWxmaWxsZWQodmFsdWUpIHsgdHJ5IHsgc3RlcChnZW5lcmF0b3IubmV4dCh2YWx1ZSkpOyB9IGNhdGNoIChlKSB7IHJlamVjdChlKTsgfSB9XHJcbiAgICAgICAgZnVuY3Rpb24gcmVqZWN0ZWQodmFsdWUpIHsgdHJ5IHsgc3RlcChnZW5lcmF0b3JbXCJ0aHJvd1wiXSh2YWx1ZSkpOyB9IGNhdGNoIChlKSB7IHJlamVjdChlKTsgfSB9XHJcbiAgICAgICAgZnVuY3Rpb24gc3RlcChyZXN1bHQpIHsgcmVzdWx0LmRvbmUgPyByZXNvbHZlKHJlc3VsdC52YWx1ZSkgOiBhZG9wdChyZXN1bHQudmFsdWUpLnRoZW4oZnVsZmlsbGVkLCByZWplY3RlZCk7IH1cclxuICAgICAgICBzdGVwKChnZW5lcmF0b3IgPSBnZW5lcmF0b3IuYXBwbHkodGhpc0FyZywgX2FyZ3VtZW50cyB8fCBbXSkpLm5leHQoKSk7XHJcbiAgICB9KTtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fZ2VuZXJhdG9yKHRoaXNBcmcsIGJvZHkpIHtcclxuICAgIHZhciBfID0geyBsYWJlbDogMCwgc2VudDogZnVuY3Rpb24oKSB7IGlmICh0WzBdICYgMSkgdGhyb3cgdFsxXTsgcmV0dXJuIHRbMV07IH0sIHRyeXM6IFtdLCBvcHM6IFtdIH0sIGYsIHksIHQsIGc7XHJcbiAgICByZXR1cm4gZyA9IHsgbmV4dDogdmVyYigwKSwgXCJ0aHJvd1wiOiB2ZXJiKDEpLCBcInJldHVyblwiOiB2ZXJiKDIpIH0sIHR5cGVvZiBTeW1ib2wgPT09IFwiZnVuY3Rpb25cIiAmJiAoZ1tTeW1ib2wuaXRlcmF0b3JdID0gZnVuY3Rpb24oKSB7IHJldHVybiB0aGlzOyB9KSwgZztcclxuICAgIGZ1bmN0aW9uIHZlcmIobikgeyByZXR1cm4gZnVuY3Rpb24gKHYpIHsgcmV0dXJuIHN0ZXAoW24sIHZdKTsgfTsgfVxyXG4gICAgZnVuY3Rpb24gc3RlcChvcCkge1xyXG4gICAgICAgIGlmIChmKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiR2VuZXJhdG9yIGlzIGFscmVhZHkgZXhlY3V0aW5nLlwiKTtcclxuICAgICAgICB3aGlsZSAoZyAmJiAoZyA9IDAsIG9wWzBdICYmIChfID0gMCkpLCBfKSB0cnkge1xyXG4gICAgICAgICAgICBpZiAoZiA9IDEsIHkgJiYgKHQgPSBvcFswXSAmIDIgPyB5W1wicmV0dXJuXCJdIDogb3BbMF0gPyB5W1widGhyb3dcIl0gfHwgKCh0ID0geVtcInJldHVyblwiXSkgJiYgdC5jYWxsKHkpLCAwKSA6IHkubmV4dCkgJiYgISh0ID0gdC5jYWxsKHksIG9wWzFdKSkuZG9uZSkgcmV0dXJuIHQ7XHJcbiAgICAgICAgICAgIGlmICh5ID0gMCwgdCkgb3AgPSBbb3BbMF0gJiAyLCB0LnZhbHVlXTtcclxuICAgICAgICAgICAgc3dpdGNoIChvcFswXSkge1xyXG4gICAgICAgICAgICAgICAgY2FzZSAwOiBjYXNlIDE6IHQgPSBvcDsgYnJlYWs7XHJcbiAgICAgICAgICAgICAgICBjYXNlIDQ6IF8ubGFiZWwrKzsgcmV0dXJuIHsgdmFsdWU6IG9wWzFdLCBkb25lOiBmYWxzZSB9O1xyXG4gICAgICAgICAgICAgICAgY2FzZSA1OiBfLmxhYmVsKys7IHkgPSBvcFsxXTsgb3AgPSBbMF07IGNvbnRpbnVlO1xyXG4gICAgICAgICAgICAgICAgY2FzZSA3OiBvcCA9IF8ub3BzLnBvcCgpOyBfLnRyeXMucG9wKCk7IGNvbnRpbnVlO1xyXG4gICAgICAgICAgICAgICAgZGVmYXVsdDpcclxuICAgICAgICAgICAgICAgICAgICBpZiAoISh0ID0gXy50cnlzLCB0ID0gdC5sZW5ndGggPiAwICYmIHRbdC5sZW5ndGggLSAxXSkgJiYgKG9wWzBdID09PSA2IHx8IG9wWzBdID09PSAyKSkgeyBfID0gMDsgY29udGludWU7IH1cclxuICAgICAgICAgICAgICAgICAgICBpZiAob3BbMF0gPT09IDMgJiYgKCF0IHx8IChvcFsxXSA+IHRbMF0gJiYgb3BbMV0gPCB0WzNdKSkpIHsgXy5sYWJlbCA9IG9wWzFdOyBicmVhazsgfVxyXG4gICAgICAgICAgICAgICAgICAgIGlmIChvcFswXSA9PT0gNiAmJiBfLmxhYmVsIDwgdFsxXSkgeyBfLmxhYmVsID0gdFsxXTsgdCA9IG9wOyBicmVhazsgfVxyXG4gICAgICAgICAgICAgICAgICAgIGlmICh0ICYmIF8ubGFiZWwgPCB0WzJdKSB7IF8ubGFiZWwgPSB0WzJdOyBfLm9wcy5wdXNoKG9wKTsgYnJlYWs7IH1cclxuICAgICAgICAgICAgICAgICAgICBpZiAodFsyXSkgXy5vcHMucG9wKCk7XHJcbiAgICAgICAgICAgICAgICAgICAgXy50cnlzLnBvcCgpOyBjb250aW51ZTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBvcCA9IGJvZHkuY2FsbCh0aGlzQXJnLCBfKTtcclxuICAgICAgICB9IGNhdGNoIChlKSB7IG9wID0gWzYsIGVdOyB5ID0gMDsgfSBmaW5hbGx5IHsgZiA9IHQgPSAwOyB9XHJcbiAgICAgICAgaWYgKG9wWzBdICYgNSkgdGhyb3cgb3BbMV07IHJldHVybiB7IHZhbHVlOiBvcFswXSA/IG9wWzFdIDogdm9pZCAwLCBkb25lOiB0cnVlIH07XHJcbiAgICB9XHJcbn1cclxuXHJcbmV4cG9ydCB2YXIgX19jcmVhdGVCaW5kaW5nID0gT2JqZWN0LmNyZWF0ZSA/IChmdW5jdGlvbihvLCBtLCBrLCBrMikge1xyXG4gICAgaWYgKGsyID09PSB1bmRlZmluZWQpIGsyID0gaztcclxuICAgIHZhciBkZXNjID0gT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcihtLCBrKTtcclxuICAgIGlmICghZGVzYyB8fCAoXCJnZXRcIiBpbiBkZXNjID8gIW0uX19lc01vZHVsZSA6IGRlc2Mud3JpdGFibGUgfHwgZGVzYy5jb25maWd1cmFibGUpKSB7XHJcbiAgICAgICAgZGVzYyA9IHsgZW51bWVyYWJsZTogdHJ1ZSwgZ2V0OiBmdW5jdGlvbigpIHsgcmV0dXJuIG1ba107IH0gfTtcclxuICAgIH1cclxuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShvLCBrMiwgZGVzYyk7XHJcbn0pIDogKGZ1bmN0aW9uKG8sIG0sIGssIGsyKSB7XHJcbiAgICBpZiAoazIgPT09IHVuZGVmaW5lZCkgazIgPSBrO1xyXG4gICAgb1trMl0gPSBtW2tdO1xyXG59KTtcclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX2V4cG9ydFN0YXIobSwgbykge1xyXG4gICAgZm9yICh2YXIgcCBpbiBtKSBpZiAocCAhPT0gXCJkZWZhdWx0XCIgJiYgIU9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChvLCBwKSkgX19jcmVhdGVCaW5kaW5nKG8sIG0sIHApO1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX192YWx1ZXMobykge1xyXG4gICAgdmFyIHMgPSB0eXBlb2YgU3ltYm9sID09PSBcImZ1bmN0aW9uXCIgJiYgU3ltYm9sLml0ZXJhdG9yLCBtID0gcyAmJiBvW3NdLCBpID0gMDtcclxuICAgIGlmIChtKSByZXR1cm4gbS5jYWxsKG8pO1xyXG4gICAgaWYgKG8gJiYgdHlwZW9mIG8ubGVuZ3RoID09PSBcIm51bWJlclwiKSByZXR1cm4ge1xyXG4gICAgICAgIG5leHQ6IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgaWYgKG8gJiYgaSA+PSBvLmxlbmd0aCkgbyA9IHZvaWQgMDtcclxuICAgICAgICAgICAgcmV0dXJuIHsgdmFsdWU6IG8gJiYgb1tpKytdLCBkb25lOiAhbyB9O1xyXG4gICAgICAgIH1cclxuICAgIH07XHJcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKHMgPyBcIk9iamVjdCBpcyBub3QgaXRlcmFibGUuXCIgOiBcIlN5bWJvbC5pdGVyYXRvciBpcyBub3QgZGVmaW5lZC5cIik7XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX3JlYWQobywgbikge1xyXG4gICAgdmFyIG0gPSB0eXBlb2YgU3ltYm9sID09PSBcImZ1bmN0aW9uXCIgJiYgb1tTeW1ib2wuaXRlcmF0b3JdO1xyXG4gICAgaWYgKCFtKSByZXR1cm4gbztcclxuICAgIHZhciBpID0gbS5jYWxsKG8pLCByLCBhciA9IFtdLCBlO1xyXG4gICAgdHJ5IHtcclxuICAgICAgICB3aGlsZSAoKG4gPT09IHZvaWQgMCB8fCBuLS0gPiAwKSAmJiAhKHIgPSBpLm5leHQoKSkuZG9uZSkgYXIucHVzaChyLnZhbHVlKTtcclxuICAgIH1cclxuICAgIGNhdGNoIChlcnJvcikgeyBlID0geyBlcnJvcjogZXJyb3IgfTsgfVxyXG4gICAgZmluYWxseSB7XHJcbiAgICAgICAgdHJ5IHtcclxuICAgICAgICAgICAgaWYgKHIgJiYgIXIuZG9uZSAmJiAobSA9IGlbXCJyZXR1cm5cIl0pKSBtLmNhbGwoaSk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGZpbmFsbHkgeyBpZiAoZSkgdGhyb3cgZS5lcnJvcjsgfVxyXG4gICAgfVxyXG4gICAgcmV0dXJuIGFyO1xyXG59XHJcblxyXG4vKiogQGRlcHJlY2F0ZWQgKi9cclxuZXhwb3J0IGZ1bmN0aW9uIF9fc3ByZWFkKCkge1xyXG4gICAgZm9yICh2YXIgYXIgPSBbXSwgaSA9IDA7IGkgPCBhcmd1bWVudHMubGVuZ3RoOyBpKyspXHJcbiAgICAgICAgYXIgPSBhci5jb25jYXQoX19yZWFkKGFyZ3VtZW50c1tpXSkpO1xyXG4gICAgcmV0dXJuIGFyO1xyXG59XHJcblxyXG4vKiogQGRlcHJlY2F0ZWQgKi9cclxuZXhwb3J0IGZ1bmN0aW9uIF9fc3ByZWFkQXJyYXlzKCkge1xyXG4gICAgZm9yICh2YXIgcyA9IDAsIGkgPSAwLCBpbCA9IGFyZ3VtZW50cy5sZW5ndGg7IGkgPCBpbDsgaSsrKSBzICs9IGFyZ3VtZW50c1tpXS5sZW5ndGg7XHJcbiAgICBmb3IgKHZhciByID0gQXJyYXkocyksIGsgPSAwLCBpID0gMDsgaSA8IGlsOyBpKyspXHJcbiAgICAgICAgZm9yICh2YXIgYSA9IGFyZ3VtZW50c1tpXSwgaiA9IDAsIGpsID0gYS5sZW5ndGg7IGogPCBqbDsgaisrLCBrKyspXHJcbiAgICAgICAgICAgIHJba10gPSBhW2pdO1xyXG4gICAgcmV0dXJuIHI7XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX3NwcmVhZEFycmF5KHRvLCBmcm9tLCBwYWNrKSB7XHJcbiAgICBpZiAocGFjayB8fCBhcmd1bWVudHMubGVuZ3RoID09PSAyKSBmb3IgKHZhciBpID0gMCwgbCA9IGZyb20ubGVuZ3RoLCBhcjsgaSA8IGw7IGkrKykge1xyXG4gICAgICAgIGlmIChhciB8fCAhKGkgaW4gZnJvbSkpIHtcclxuICAgICAgICAgICAgaWYgKCFhcikgYXIgPSBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChmcm9tLCAwLCBpKTtcclxuICAgICAgICAgICAgYXJbaV0gPSBmcm9tW2ldO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuICAgIHJldHVybiB0by5jb25jYXQoYXIgfHwgQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoZnJvbSkpO1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19hd2FpdCh2KSB7XHJcbiAgICByZXR1cm4gdGhpcyBpbnN0YW5jZW9mIF9fYXdhaXQgPyAodGhpcy52ID0gdiwgdGhpcykgOiBuZXcgX19hd2FpdCh2KTtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fYXN5bmNHZW5lcmF0b3IodGhpc0FyZywgX2FyZ3VtZW50cywgZ2VuZXJhdG9yKSB7XHJcbiAgICBpZiAoIVN5bWJvbC5hc3luY0l0ZXJhdG9yKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiU3ltYm9sLmFzeW5jSXRlcmF0b3IgaXMgbm90IGRlZmluZWQuXCIpO1xyXG4gICAgdmFyIGcgPSBnZW5lcmF0b3IuYXBwbHkodGhpc0FyZywgX2FyZ3VtZW50cyB8fCBbXSksIGksIHEgPSBbXTtcclxuICAgIHJldHVybiBpID0ge30sIHZlcmIoXCJuZXh0XCIpLCB2ZXJiKFwidGhyb3dcIiksIHZlcmIoXCJyZXR1cm5cIiksIGlbU3ltYm9sLmFzeW5jSXRlcmF0b3JdID0gZnVuY3Rpb24gKCkgeyByZXR1cm4gdGhpczsgfSwgaTtcclxuICAgIGZ1bmN0aW9uIHZlcmIobikgeyBpZiAoZ1tuXSkgaVtuXSA9IGZ1bmN0aW9uICh2KSB7IHJldHVybiBuZXcgUHJvbWlzZShmdW5jdGlvbiAoYSwgYikgeyBxLnB1c2goW24sIHYsIGEsIGJdKSA+IDEgfHwgcmVzdW1lKG4sIHYpOyB9KTsgfTsgfVxyXG4gICAgZnVuY3Rpb24gcmVzdW1lKG4sIHYpIHsgdHJ5IHsgc3RlcChnW25dKHYpKTsgfSBjYXRjaCAoZSkgeyBzZXR0bGUocVswXVszXSwgZSk7IH0gfVxyXG4gICAgZnVuY3Rpb24gc3RlcChyKSB7IHIudmFsdWUgaW5zdGFuY2VvZiBfX2F3YWl0ID8gUHJvbWlzZS5yZXNvbHZlKHIudmFsdWUudikudGhlbihmdWxmaWxsLCByZWplY3QpIDogc2V0dGxlKHFbMF1bMl0sIHIpOyB9XHJcbiAgICBmdW5jdGlvbiBmdWxmaWxsKHZhbHVlKSB7IHJlc3VtZShcIm5leHRcIiwgdmFsdWUpOyB9XHJcbiAgICBmdW5jdGlvbiByZWplY3QodmFsdWUpIHsgcmVzdW1lKFwidGhyb3dcIiwgdmFsdWUpOyB9XHJcbiAgICBmdW5jdGlvbiBzZXR0bGUoZiwgdikgeyBpZiAoZih2KSwgcS5zaGlmdCgpLCBxLmxlbmd0aCkgcmVzdW1lKHFbMF1bMF0sIHFbMF1bMV0pOyB9XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX2FzeW5jRGVsZWdhdG9yKG8pIHtcclxuICAgIHZhciBpLCBwO1xyXG4gICAgcmV0dXJuIGkgPSB7fSwgdmVyYihcIm5leHRcIiksIHZlcmIoXCJ0aHJvd1wiLCBmdW5jdGlvbiAoZSkgeyB0aHJvdyBlOyB9KSwgdmVyYihcInJldHVyblwiKSwgaVtTeW1ib2wuaXRlcmF0b3JdID0gZnVuY3Rpb24gKCkgeyByZXR1cm4gdGhpczsgfSwgaTtcclxuICAgIGZ1bmN0aW9uIHZlcmIobiwgZikgeyBpW25dID0gb1tuXSA/IGZ1bmN0aW9uICh2KSB7IHJldHVybiAocCA9ICFwKSA/IHsgdmFsdWU6IF9fYXdhaXQob1tuXSh2KSksIGRvbmU6IGZhbHNlIH0gOiBmID8gZih2KSA6IHY7IH0gOiBmOyB9XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX2FzeW5jVmFsdWVzKG8pIHtcclxuICAgIGlmICghU3ltYm9sLmFzeW5jSXRlcmF0b3IpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJTeW1ib2wuYXN5bmNJdGVyYXRvciBpcyBub3QgZGVmaW5lZC5cIik7XHJcbiAgICB2YXIgbSA9IG9bU3ltYm9sLmFzeW5jSXRlcmF0b3JdLCBpO1xyXG4gICAgcmV0dXJuIG0gPyBtLmNhbGwobykgOiAobyA9IHR5cGVvZiBfX3ZhbHVlcyA9PT0gXCJmdW5jdGlvblwiID8gX192YWx1ZXMobykgOiBvW1N5bWJvbC5pdGVyYXRvcl0oKSwgaSA9IHt9LCB2ZXJiKFwibmV4dFwiKSwgdmVyYihcInRocm93XCIpLCB2ZXJiKFwicmV0dXJuXCIpLCBpW1N5bWJvbC5hc3luY0l0ZXJhdG9yXSA9IGZ1bmN0aW9uICgpIHsgcmV0dXJuIHRoaXM7IH0sIGkpO1xyXG4gICAgZnVuY3Rpb24gdmVyYihuKSB7IGlbbl0gPSBvW25dICYmIGZ1bmN0aW9uICh2KSB7IHJldHVybiBuZXcgUHJvbWlzZShmdW5jdGlvbiAocmVzb2x2ZSwgcmVqZWN0KSB7IHYgPSBvW25dKHYpLCBzZXR0bGUocmVzb2x2ZSwgcmVqZWN0LCB2LmRvbmUsIHYudmFsdWUpOyB9KTsgfTsgfVxyXG4gICAgZnVuY3Rpb24gc2V0dGxlKHJlc29sdmUsIHJlamVjdCwgZCwgdikgeyBQcm9taXNlLnJlc29sdmUodikudGhlbihmdW5jdGlvbih2KSB7IHJlc29sdmUoeyB2YWx1ZTogdiwgZG9uZTogZCB9KTsgfSwgcmVqZWN0KTsgfVxyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19tYWtlVGVtcGxhdGVPYmplY3QoY29va2VkLCByYXcpIHtcclxuICAgIGlmIChPYmplY3QuZGVmaW5lUHJvcGVydHkpIHsgT2JqZWN0LmRlZmluZVByb3BlcnR5KGNvb2tlZCwgXCJyYXdcIiwgeyB2YWx1ZTogcmF3IH0pOyB9IGVsc2UgeyBjb29rZWQucmF3ID0gcmF3OyB9XHJcbiAgICByZXR1cm4gY29va2VkO1xyXG59O1xyXG5cclxudmFyIF9fc2V0TW9kdWxlRGVmYXVsdCA9IE9iamVjdC5jcmVhdGUgPyAoZnVuY3Rpb24obywgdikge1xyXG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KG8sIFwiZGVmYXVsdFwiLCB7IGVudW1lcmFibGU6IHRydWUsIHZhbHVlOiB2IH0pO1xyXG59KSA6IGZ1bmN0aW9uKG8sIHYpIHtcclxuICAgIG9bXCJkZWZhdWx0XCJdID0gdjtcclxufTtcclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX2ltcG9ydFN0YXIobW9kKSB7XHJcbiAgICBpZiAobW9kICYmIG1vZC5fX2VzTW9kdWxlKSByZXR1cm4gbW9kO1xyXG4gICAgdmFyIHJlc3VsdCA9IHt9O1xyXG4gICAgaWYgKG1vZCAhPSBudWxsKSBmb3IgKHZhciBrIGluIG1vZCkgaWYgKGsgIT09IFwiZGVmYXVsdFwiICYmIE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChtb2QsIGspKSBfX2NyZWF0ZUJpbmRpbmcocmVzdWx0LCBtb2QsIGspO1xyXG4gICAgX19zZXRNb2R1bGVEZWZhdWx0KHJlc3VsdCwgbW9kKTtcclxuICAgIHJldHVybiByZXN1bHQ7XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX2ltcG9ydERlZmF1bHQobW9kKSB7XHJcbiAgICByZXR1cm4gKG1vZCAmJiBtb2QuX19lc01vZHVsZSkgPyBtb2QgOiB7IGRlZmF1bHQ6IG1vZCB9O1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19jbGFzc1ByaXZhdGVGaWVsZEdldChyZWNlaXZlciwgc3RhdGUsIGtpbmQsIGYpIHtcclxuICAgIGlmIChraW5kID09PSBcImFcIiAmJiAhZikgdGhyb3cgbmV3IFR5cGVFcnJvcihcIlByaXZhdGUgYWNjZXNzb3Igd2FzIGRlZmluZWQgd2l0aG91dCBhIGdldHRlclwiKTtcclxuICAgIGlmICh0eXBlb2Ygc3RhdGUgPT09IFwiZnVuY3Rpb25cIiA/IHJlY2VpdmVyICE9PSBzdGF0ZSB8fCAhZiA6ICFzdGF0ZS5oYXMocmVjZWl2ZXIpKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiQ2Fubm90IHJlYWQgcHJpdmF0ZSBtZW1iZXIgZnJvbSBhbiBvYmplY3Qgd2hvc2UgY2xhc3MgZGlkIG5vdCBkZWNsYXJlIGl0XCIpO1xyXG4gICAgcmV0dXJuIGtpbmQgPT09IFwibVwiID8gZiA6IGtpbmQgPT09IFwiYVwiID8gZi5jYWxsKHJlY2VpdmVyKSA6IGYgPyBmLnZhbHVlIDogc3RhdGUuZ2V0KHJlY2VpdmVyKTtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fY2xhc3NQcml2YXRlRmllbGRTZXQocmVjZWl2ZXIsIHN0YXRlLCB2YWx1ZSwga2luZCwgZikge1xyXG4gICAgaWYgKGtpbmQgPT09IFwibVwiKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiUHJpdmF0ZSBtZXRob2QgaXMgbm90IHdyaXRhYmxlXCIpO1xyXG4gICAgaWYgKGtpbmQgPT09IFwiYVwiICYmICFmKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiUHJpdmF0ZSBhY2Nlc3NvciB3YXMgZGVmaW5lZCB3aXRob3V0IGEgc2V0dGVyXCIpO1xyXG4gICAgaWYgKHR5cGVvZiBzdGF0ZSA9PT0gXCJmdW5jdGlvblwiID8gcmVjZWl2ZXIgIT09IHN0YXRlIHx8ICFmIDogIXN0YXRlLmhhcyhyZWNlaXZlcikpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJDYW5ub3Qgd3JpdGUgcHJpdmF0ZSBtZW1iZXIgdG8gYW4gb2JqZWN0IHdob3NlIGNsYXNzIGRpZCBub3QgZGVjbGFyZSBpdFwiKTtcclxuICAgIHJldHVybiAoa2luZCA9PT0gXCJhXCIgPyBmLmNhbGwocmVjZWl2ZXIsIHZhbHVlKSA6IGYgPyBmLnZhbHVlID0gdmFsdWUgOiBzdGF0ZS5zZXQocmVjZWl2ZXIsIHZhbHVlKSksIHZhbHVlO1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19jbGFzc1ByaXZhdGVGaWVsZEluKHN0YXRlLCByZWNlaXZlcikge1xyXG4gICAgaWYgKHJlY2VpdmVyID09PSBudWxsIHx8ICh0eXBlb2YgcmVjZWl2ZXIgIT09IFwib2JqZWN0XCIgJiYgdHlwZW9mIHJlY2VpdmVyICE9PSBcImZ1bmN0aW9uXCIpKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiQ2Fubm90IHVzZSAnaW4nIG9wZXJhdG9yIG9uIG5vbi1vYmplY3RcIik7XHJcbiAgICByZXR1cm4gdHlwZW9mIHN0YXRlID09PSBcImZ1bmN0aW9uXCIgPyByZWNlaXZlciA9PT0gc3RhdGUgOiBzdGF0ZS5oYXMocmVjZWl2ZXIpO1xyXG59XHJcbiIsIm1vZHVsZS5leHBvcnRzID0gaXNleGVcbmlzZXhlLnN5bmMgPSBzeW5jXG5cbnZhciBmcyA9IHJlcXVpcmUoJ2ZzJylcblxuZnVuY3Rpb24gY2hlY2tQYXRoRXh0IChwYXRoLCBvcHRpb25zKSB7XG4gIHZhciBwYXRoZXh0ID0gb3B0aW9ucy5wYXRoRXh0ICE9PSB1bmRlZmluZWQgP1xuICAgIG9wdGlvbnMucGF0aEV4dCA6IHByb2Nlc3MuZW52LlBBVEhFWFRcblxuICBpZiAoIXBhdGhleHQpIHtcbiAgICByZXR1cm4gdHJ1ZVxuICB9XG5cbiAgcGF0aGV4dCA9IHBhdGhleHQuc3BsaXQoJzsnKVxuICBpZiAocGF0aGV4dC5pbmRleE9mKCcnKSAhPT0gLTEpIHtcbiAgICByZXR1cm4gdHJ1ZVxuICB9XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgcGF0aGV4dC5sZW5ndGg7IGkrKykge1xuICAgIHZhciBwID0gcGF0aGV4dFtpXS50b0xvd2VyQ2FzZSgpXG4gICAgaWYgKHAgJiYgcGF0aC5zdWJzdHIoLXAubGVuZ3RoKS50b0xvd2VyQ2FzZSgpID09PSBwKSB7XG4gICAgICByZXR1cm4gdHJ1ZVxuICAgIH1cbiAgfVxuICByZXR1cm4gZmFsc2Vcbn1cblxuZnVuY3Rpb24gY2hlY2tTdGF0IChzdGF0LCBwYXRoLCBvcHRpb25zKSB7XG4gIGlmICghc3RhdC5pc1N5bWJvbGljTGluaygpICYmICFzdGF0LmlzRmlsZSgpKSB7XG4gICAgcmV0dXJuIGZhbHNlXG4gIH1cbiAgcmV0dXJuIGNoZWNrUGF0aEV4dChwYXRoLCBvcHRpb25zKVxufVxuXG5mdW5jdGlvbiBpc2V4ZSAocGF0aCwgb3B0aW9ucywgY2IpIHtcbiAgZnMuc3RhdChwYXRoLCBmdW5jdGlvbiAoZXIsIHN0YXQpIHtcbiAgICBjYihlciwgZXIgPyBmYWxzZSA6IGNoZWNrU3RhdChzdGF0LCBwYXRoLCBvcHRpb25zKSlcbiAgfSlcbn1cblxuZnVuY3Rpb24gc3luYyAocGF0aCwgb3B0aW9ucykge1xuICByZXR1cm4gY2hlY2tTdGF0KGZzLnN0YXRTeW5jKHBhdGgpLCBwYXRoLCBvcHRpb25zKVxufVxuIiwibW9kdWxlLmV4cG9ydHMgPSBpc2V4ZVxuaXNleGUuc3luYyA9IHN5bmNcblxudmFyIGZzID0gcmVxdWlyZSgnZnMnKVxuXG5mdW5jdGlvbiBpc2V4ZSAocGF0aCwgb3B0aW9ucywgY2IpIHtcbiAgZnMuc3RhdChwYXRoLCBmdW5jdGlvbiAoZXIsIHN0YXQpIHtcbiAgICBjYihlciwgZXIgPyBmYWxzZSA6IGNoZWNrU3RhdChzdGF0LCBvcHRpb25zKSlcbiAgfSlcbn1cblxuZnVuY3Rpb24gc3luYyAocGF0aCwgb3B0aW9ucykge1xuICByZXR1cm4gY2hlY2tTdGF0KGZzLnN0YXRTeW5jKHBhdGgpLCBvcHRpb25zKVxufVxuXG5mdW5jdGlvbiBjaGVja1N0YXQgKHN0YXQsIG9wdGlvbnMpIHtcbiAgcmV0dXJuIHN0YXQuaXNGaWxlKCkgJiYgY2hlY2tNb2RlKHN0YXQsIG9wdGlvbnMpXG59XG5cbmZ1bmN0aW9uIGNoZWNrTW9kZSAoc3RhdCwgb3B0aW9ucykge1xuICB2YXIgbW9kID0gc3RhdC5tb2RlXG4gIHZhciB1aWQgPSBzdGF0LnVpZFxuICB2YXIgZ2lkID0gc3RhdC5naWRcblxuICB2YXIgbXlVaWQgPSBvcHRpb25zLnVpZCAhPT0gdW5kZWZpbmVkID9cbiAgICBvcHRpb25zLnVpZCA6IHByb2Nlc3MuZ2V0dWlkICYmIHByb2Nlc3MuZ2V0dWlkKClcbiAgdmFyIG15R2lkID0gb3B0aW9ucy5naWQgIT09IHVuZGVmaW5lZCA/XG4gICAgb3B0aW9ucy5naWQgOiBwcm9jZXNzLmdldGdpZCAmJiBwcm9jZXNzLmdldGdpZCgpXG5cbiAgdmFyIHUgPSBwYXJzZUludCgnMTAwJywgOClcbiAgdmFyIGcgPSBwYXJzZUludCgnMDEwJywgOClcbiAgdmFyIG8gPSBwYXJzZUludCgnMDAxJywgOClcbiAgdmFyIHVnID0gdSB8IGdcblxuICB2YXIgcmV0ID0gKG1vZCAmIG8pIHx8XG4gICAgKG1vZCAmIGcpICYmIGdpZCA9PT0gbXlHaWQgfHxcbiAgICAobW9kICYgdSkgJiYgdWlkID09PSBteVVpZCB8fFxuICAgIChtb2QgJiB1ZykgJiYgbXlVaWQgPT09IDBcblxuICByZXR1cm4gcmV0XG59XG4iLCJ2YXIgZnMgPSByZXF1aXJlKCdmcycpXG52YXIgY29yZVxuaWYgKHByb2Nlc3MucGxhdGZvcm0gPT09ICd3aW4zMicgfHwgZ2xvYmFsLlRFU1RJTkdfV0lORE9XUykge1xuICBjb3JlID0gcmVxdWlyZSgnLi93aW5kb3dzLmpzJylcbn0gZWxzZSB7XG4gIGNvcmUgPSByZXF1aXJlKCcuL21vZGUuanMnKVxufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGlzZXhlXG5pc2V4ZS5zeW5jID0gc3luY1xuXG5mdW5jdGlvbiBpc2V4ZSAocGF0aCwgb3B0aW9ucywgY2IpIHtcbiAgaWYgKHR5cGVvZiBvcHRpb25zID09PSAnZnVuY3Rpb24nKSB7XG4gICAgY2IgPSBvcHRpb25zXG4gICAgb3B0aW9ucyA9IHt9XG4gIH1cblxuICBpZiAoIWNiKSB7XG4gICAgaWYgKHR5cGVvZiBQcm9taXNlICE9PSAnZnVuY3Rpb24nKSB7XG4gICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdjYWxsYmFjayBub3QgcHJvdmlkZWQnKVxuICAgIH1cblxuICAgIHJldHVybiBuZXcgUHJvbWlzZShmdW5jdGlvbiAocmVzb2x2ZSwgcmVqZWN0KSB7XG4gICAgICBpc2V4ZShwYXRoLCBvcHRpb25zIHx8IHt9LCBmdW5jdGlvbiAoZXIsIGlzKSB7XG4gICAgICAgIGlmIChlcikge1xuICAgICAgICAgIHJlamVjdChlcilcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICByZXNvbHZlKGlzKVxuICAgICAgICB9XG4gICAgICB9KVxuICAgIH0pXG4gIH1cblxuICBjb3JlKHBhdGgsIG9wdGlvbnMgfHwge30sIGZ1bmN0aW9uIChlciwgaXMpIHtcbiAgICAvLyBpZ25vcmUgRUFDQ0VTIGJlY2F1c2UgdGhhdCBqdXN0IG1lYW5zIHdlIGFyZW4ndCBhbGxvd2VkIHRvIHJ1biBpdFxuICAgIGlmIChlcikge1xuICAgICAgaWYgKGVyLmNvZGUgPT09ICdFQUNDRVMnIHx8IG9wdGlvbnMgJiYgb3B0aW9ucy5pZ25vcmVFcnJvcnMpIHtcbiAgICAgICAgZXIgPSBudWxsXG4gICAgICAgIGlzID0gZmFsc2VcbiAgICAgIH1cbiAgICB9XG4gICAgY2IoZXIsIGlzKVxuICB9KVxufVxuXG5mdW5jdGlvbiBzeW5jIChwYXRoLCBvcHRpb25zKSB7XG4gIC8vIG15IGtpbmdkb20gZm9yIGEgZmlsdGVyZWQgY2F0Y2hcbiAgdHJ5IHtcbiAgICByZXR1cm4gY29yZS5zeW5jKHBhdGgsIG9wdGlvbnMgfHwge30pXG4gIH0gY2F0Y2ggKGVyKSB7XG4gICAgaWYgKG9wdGlvbnMgJiYgb3B0aW9ucy5pZ25vcmVFcnJvcnMgfHwgZXIuY29kZSA9PT0gJ0VBQ0NFUycpIHtcbiAgICAgIHJldHVybiBmYWxzZVxuICAgIH0gZWxzZSB7XG4gICAgICB0aHJvdyBlclxuICAgIH1cbiAgfVxufVxuIiwiY29uc3QgaXNXaW5kb3dzID0gcHJvY2Vzcy5wbGF0Zm9ybSA9PT0gJ3dpbjMyJyB8fFxuICAgIHByb2Nlc3MuZW52Lk9TVFlQRSA9PT0gJ2N5Z3dpbicgfHxcbiAgICBwcm9jZXNzLmVudi5PU1RZUEUgPT09ICdtc3lzJ1xuXG5jb25zdCBwYXRoID0gcmVxdWlyZSgncGF0aCcpXG5jb25zdCBDT0xPTiA9IGlzV2luZG93cyA/ICc7JyA6ICc6J1xuY29uc3QgaXNleGUgPSByZXF1aXJlKCdpc2V4ZScpXG5cbmNvbnN0IGdldE5vdEZvdW5kRXJyb3IgPSAoY21kKSA9PlxuICBPYmplY3QuYXNzaWduKG5ldyBFcnJvcihgbm90IGZvdW5kOiAke2NtZH1gKSwgeyBjb2RlOiAnRU5PRU5UJyB9KVxuXG5jb25zdCBnZXRQYXRoSW5mbyA9IChjbWQsIG9wdCkgPT4ge1xuICBjb25zdCBjb2xvbiA9IG9wdC5jb2xvbiB8fCBDT0xPTlxuXG4gIC8vIElmIGl0IGhhcyBhIHNsYXNoLCB0aGVuIHdlIGRvbid0IGJvdGhlciBzZWFyY2hpbmcgdGhlIHBhdGhlbnYuXG4gIC8vIGp1c3QgY2hlY2sgdGhlIGZpbGUgaXRzZWxmLCBhbmQgdGhhdCdzIGl0LlxuICBjb25zdCBwYXRoRW52ID0gY21kLm1hdGNoKC9cXC8vKSB8fCBpc1dpbmRvd3MgJiYgY21kLm1hdGNoKC9cXFxcLykgPyBbJyddXG4gICAgOiAoXG4gICAgICBbXG4gICAgICAgIC8vIHdpbmRvd3MgYWx3YXlzIGNoZWNrcyB0aGUgY3dkIGZpcnN0XG4gICAgICAgIC4uLihpc1dpbmRvd3MgPyBbcHJvY2Vzcy5jd2QoKV0gOiBbXSksXG4gICAgICAgIC4uLihvcHQucGF0aCB8fCBwcm9jZXNzLmVudi5QQVRIIHx8XG4gICAgICAgICAgLyogaXN0YW5idWwgaWdub3JlIG5leHQ6IHZlcnkgdW51c3VhbCAqLyAnJykuc3BsaXQoY29sb24pLFxuICAgICAgXVxuICAgIClcbiAgY29uc3QgcGF0aEV4dEV4ZSA9IGlzV2luZG93c1xuICAgID8gb3B0LnBhdGhFeHQgfHwgcHJvY2Vzcy5lbnYuUEFUSEVYVCB8fCAnLkVYRTsuQ01EOy5CQVQ7LkNPTSdcbiAgICA6ICcnXG4gIGNvbnN0IHBhdGhFeHQgPSBpc1dpbmRvd3MgPyBwYXRoRXh0RXhlLnNwbGl0KGNvbG9uKSA6IFsnJ11cblxuICBpZiAoaXNXaW5kb3dzKSB7XG4gICAgaWYgKGNtZC5pbmRleE9mKCcuJykgIT09IC0xICYmIHBhdGhFeHRbMF0gIT09ICcnKVxuICAgICAgcGF0aEV4dC51bnNoaWZ0KCcnKVxuICB9XG5cbiAgcmV0dXJuIHtcbiAgICBwYXRoRW52LFxuICAgIHBhdGhFeHQsXG4gICAgcGF0aEV4dEV4ZSxcbiAgfVxufVxuXG5jb25zdCB3aGljaCA9IChjbWQsIG9wdCwgY2IpID0+IHtcbiAgaWYgKHR5cGVvZiBvcHQgPT09ICdmdW5jdGlvbicpIHtcbiAgICBjYiA9IG9wdFxuICAgIG9wdCA9IHt9XG4gIH1cbiAgaWYgKCFvcHQpXG4gICAgb3B0ID0ge31cblxuICBjb25zdCB7IHBhdGhFbnYsIHBhdGhFeHQsIHBhdGhFeHRFeGUgfSA9IGdldFBhdGhJbmZvKGNtZCwgb3B0KVxuICBjb25zdCBmb3VuZCA9IFtdXG5cbiAgY29uc3Qgc3RlcCA9IGkgPT4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgIGlmIChpID09PSBwYXRoRW52Lmxlbmd0aClcbiAgICAgIHJldHVybiBvcHQuYWxsICYmIGZvdW5kLmxlbmd0aCA/IHJlc29sdmUoZm91bmQpXG4gICAgICAgIDogcmVqZWN0KGdldE5vdEZvdW5kRXJyb3IoY21kKSlcblxuICAgIGNvbnN0IHBwUmF3ID0gcGF0aEVudltpXVxuICAgIGNvbnN0IHBhdGhQYXJ0ID0gL15cIi4qXCIkLy50ZXN0KHBwUmF3KSA/IHBwUmF3LnNsaWNlKDEsIC0xKSA6IHBwUmF3XG5cbiAgICBjb25zdCBwQ21kID0gcGF0aC5qb2luKHBhdGhQYXJ0LCBjbWQpXG4gICAgY29uc3QgcCA9ICFwYXRoUGFydCAmJiAvXlxcLltcXFxcXFwvXS8udGVzdChjbWQpID8gY21kLnNsaWNlKDAsIDIpICsgcENtZFxuICAgICAgOiBwQ21kXG5cbiAgICByZXNvbHZlKHN1YlN0ZXAocCwgaSwgMCkpXG4gIH0pXG5cbiAgY29uc3Qgc3ViU3RlcCA9IChwLCBpLCBpaSkgPT4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgIGlmIChpaSA9PT0gcGF0aEV4dC5sZW5ndGgpXG4gICAgICByZXR1cm4gcmVzb2x2ZShzdGVwKGkgKyAxKSlcbiAgICBjb25zdCBleHQgPSBwYXRoRXh0W2lpXVxuICAgIGlzZXhlKHAgKyBleHQsIHsgcGF0aEV4dDogcGF0aEV4dEV4ZSB9LCAoZXIsIGlzKSA9PiB7XG4gICAgICBpZiAoIWVyICYmIGlzKSB7XG4gICAgICAgIGlmIChvcHQuYWxsKVxuICAgICAgICAgIGZvdW5kLnB1c2gocCArIGV4dClcbiAgICAgICAgZWxzZVxuICAgICAgICAgIHJldHVybiByZXNvbHZlKHAgKyBleHQpXG4gICAgICB9XG4gICAgICByZXR1cm4gcmVzb2x2ZShzdWJTdGVwKHAsIGksIGlpICsgMSkpXG4gICAgfSlcbiAgfSlcblxuICByZXR1cm4gY2IgPyBzdGVwKDApLnRoZW4ocmVzID0+IGNiKG51bGwsIHJlcyksIGNiKSA6IHN0ZXAoMClcbn1cblxuY29uc3Qgd2hpY2hTeW5jID0gKGNtZCwgb3B0KSA9PiB7XG4gIG9wdCA9IG9wdCB8fCB7fVxuXG4gIGNvbnN0IHsgcGF0aEVudiwgcGF0aEV4dCwgcGF0aEV4dEV4ZSB9ID0gZ2V0UGF0aEluZm8oY21kLCBvcHQpXG4gIGNvbnN0IGZvdW5kID0gW11cblxuICBmb3IgKGxldCBpID0gMDsgaSA8IHBhdGhFbnYubGVuZ3RoOyBpICsrKSB7XG4gICAgY29uc3QgcHBSYXcgPSBwYXRoRW52W2ldXG4gICAgY29uc3QgcGF0aFBhcnQgPSAvXlwiLipcIiQvLnRlc3QocHBSYXcpID8gcHBSYXcuc2xpY2UoMSwgLTEpIDogcHBSYXdcblxuICAgIGNvbnN0IHBDbWQgPSBwYXRoLmpvaW4ocGF0aFBhcnQsIGNtZClcbiAgICBjb25zdCBwID0gIXBhdGhQYXJ0ICYmIC9eXFwuW1xcXFxcXC9dLy50ZXN0KGNtZCkgPyBjbWQuc2xpY2UoMCwgMikgKyBwQ21kXG4gICAgICA6IHBDbWRcblxuICAgIGZvciAobGV0IGogPSAwOyBqIDwgcGF0aEV4dC5sZW5ndGg7IGogKyspIHtcbiAgICAgIGNvbnN0IGN1ciA9IHAgKyBwYXRoRXh0W2pdXG4gICAgICB0cnkge1xuICAgICAgICBjb25zdCBpcyA9IGlzZXhlLnN5bmMoY3VyLCB7IHBhdGhFeHQ6IHBhdGhFeHRFeGUgfSlcbiAgICAgICAgaWYgKGlzKSB7XG4gICAgICAgICAgaWYgKG9wdC5hbGwpXG4gICAgICAgICAgICBmb3VuZC5wdXNoKGN1cilcbiAgICAgICAgICBlbHNlXG4gICAgICAgICAgICByZXR1cm4gY3VyXG4gICAgICAgIH1cbiAgICAgIH0gY2F0Y2ggKGV4KSB7fVxuICAgIH1cbiAgfVxuXG4gIGlmIChvcHQuYWxsICYmIGZvdW5kLmxlbmd0aClcbiAgICByZXR1cm4gZm91bmRcblxuICBpZiAob3B0Lm5vdGhyb3cpXG4gICAgcmV0dXJuIG51bGxcblxuICB0aHJvdyBnZXROb3RGb3VuZEVycm9yKGNtZClcbn1cblxubW9kdWxlLmV4cG9ydHMgPSB3aGljaFxud2hpY2guc3luYyA9IHdoaWNoU3luY1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG5jb25zdCBwYXRoS2V5ID0gKG9wdGlvbnMgPSB7fSkgPT4ge1xuXHRjb25zdCBlbnZpcm9ubWVudCA9IG9wdGlvbnMuZW52IHx8IHByb2Nlc3MuZW52O1xuXHRjb25zdCBwbGF0Zm9ybSA9IG9wdGlvbnMucGxhdGZvcm0gfHwgcHJvY2Vzcy5wbGF0Zm9ybTtcblxuXHRpZiAocGxhdGZvcm0gIT09ICd3aW4zMicpIHtcblx0XHRyZXR1cm4gJ1BBVEgnO1xuXHR9XG5cblx0cmV0dXJuIE9iamVjdC5rZXlzKGVudmlyb25tZW50KS5yZXZlcnNlKCkuZmluZChrZXkgPT4ga2V5LnRvVXBwZXJDYXNlKCkgPT09ICdQQVRIJykgfHwgJ1BhdGgnO1xufTtcblxubW9kdWxlLmV4cG9ydHMgPSBwYXRoS2V5O1xuLy8gVE9ETzogUmVtb3ZlIHRoaXMgZm9yIHRoZSBuZXh0IG1ham9yIHJlbGVhc2Vcbm1vZHVsZS5leHBvcnRzLmRlZmF1bHQgPSBwYXRoS2V5O1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG5jb25zdCBwYXRoID0gcmVxdWlyZSgncGF0aCcpO1xuY29uc3Qgd2hpY2ggPSByZXF1aXJlKCd3aGljaCcpO1xuY29uc3QgZ2V0UGF0aEtleSA9IHJlcXVpcmUoJ3BhdGgta2V5Jyk7XG5cbmZ1bmN0aW9uIHJlc29sdmVDb21tYW5kQXR0ZW1wdChwYXJzZWQsIHdpdGhvdXRQYXRoRXh0KSB7XG4gICAgY29uc3QgZW52ID0gcGFyc2VkLm9wdGlvbnMuZW52IHx8IHByb2Nlc3MuZW52O1xuICAgIGNvbnN0IGN3ZCA9IHByb2Nlc3MuY3dkKCk7XG4gICAgY29uc3QgaGFzQ3VzdG9tQ3dkID0gcGFyc2VkLm9wdGlvbnMuY3dkICE9IG51bGw7XG4gICAgLy8gV29ya2VyIHRocmVhZHMgZG8gbm90IGhhdmUgcHJvY2Vzcy5jaGRpcigpXG4gICAgY29uc3Qgc2hvdWxkU3dpdGNoQ3dkID0gaGFzQ3VzdG9tQ3dkICYmIHByb2Nlc3MuY2hkaXIgIT09IHVuZGVmaW5lZCAmJiAhcHJvY2Vzcy5jaGRpci5kaXNhYmxlZDtcblxuICAgIC8vIElmIGEgY3VzdG9tIGBjd2RgIHdhcyBzcGVjaWZpZWQsIHdlIG5lZWQgdG8gY2hhbmdlIHRoZSBwcm9jZXNzIGN3ZFxuICAgIC8vIGJlY2F1c2UgYHdoaWNoYCB3aWxsIGRvIHN0YXQgY2FsbHMgYnV0IGRvZXMgbm90IHN1cHBvcnQgYSBjdXN0b20gY3dkXG4gICAgaWYgKHNob3VsZFN3aXRjaEN3ZCkge1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgcHJvY2Vzcy5jaGRpcihwYXJzZWQub3B0aW9ucy5jd2QpO1xuICAgICAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgICAgICAgIC8qIEVtcHR5ICovXG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBsZXQgcmVzb2x2ZWQ7XG5cbiAgICB0cnkge1xuICAgICAgICByZXNvbHZlZCA9IHdoaWNoLnN5bmMocGFyc2VkLmNvbW1hbmQsIHtcbiAgICAgICAgICAgIHBhdGg6IGVudltnZXRQYXRoS2V5KHsgZW52IH0pXSxcbiAgICAgICAgICAgIHBhdGhFeHQ6IHdpdGhvdXRQYXRoRXh0ID8gcGF0aC5kZWxpbWl0ZXIgOiB1bmRlZmluZWQsXG4gICAgICAgIH0pO1xuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgLyogRW1wdHkgKi9cbiAgICB9IGZpbmFsbHkge1xuICAgICAgICBpZiAoc2hvdWxkU3dpdGNoQ3dkKSB7XG4gICAgICAgICAgICBwcm9jZXNzLmNoZGlyKGN3ZCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBJZiB3ZSBzdWNjZXNzZnVsbHkgcmVzb2x2ZWQsIGVuc3VyZSB0aGF0IGFuIGFic29sdXRlIHBhdGggaXMgcmV0dXJuZWRcbiAgICAvLyBOb3RlIHRoYXQgd2hlbiBhIGN1c3RvbSBgY3dkYCB3YXMgdXNlZCwgd2UgbmVlZCB0byByZXNvbHZlIHRvIGFuIGFic29sdXRlIHBhdGggYmFzZWQgb24gaXRcbiAgICBpZiAocmVzb2x2ZWQpIHtcbiAgICAgICAgcmVzb2x2ZWQgPSBwYXRoLnJlc29sdmUoaGFzQ3VzdG9tQ3dkID8gcGFyc2VkLm9wdGlvbnMuY3dkIDogJycsIHJlc29sdmVkKTtcbiAgICB9XG5cbiAgICByZXR1cm4gcmVzb2x2ZWQ7XG59XG5cbmZ1bmN0aW9uIHJlc29sdmVDb21tYW5kKHBhcnNlZCkge1xuICAgIHJldHVybiByZXNvbHZlQ29tbWFuZEF0dGVtcHQocGFyc2VkKSB8fCByZXNvbHZlQ29tbWFuZEF0dGVtcHQocGFyc2VkLCB0cnVlKTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSByZXNvbHZlQ29tbWFuZDtcbiIsIid1c2Ugc3RyaWN0JztcblxuLy8gU2VlIGh0dHA6Ly93d3cucm9idmFuZGVyd291ZGUuY29tL2VzY2FwZWNoYXJzLnBocFxuY29uc3QgbWV0YUNoYXJzUmVnRXhwID0gLyhbKClcXF1bJSFeXCJgPD4mfDssICo/XSkvZztcblxuZnVuY3Rpb24gZXNjYXBlQ29tbWFuZChhcmcpIHtcbiAgICAvLyBFc2NhcGUgbWV0YSBjaGFyc1xuICAgIGFyZyA9IGFyZy5yZXBsYWNlKG1ldGFDaGFyc1JlZ0V4cCwgJ14kMScpO1xuXG4gICAgcmV0dXJuIGFyZztcbn1cblxuZnVuY3Rpb24gZXNjYXBlQXJndW1lbnQoYXJnLCBkb3VibGVFc2NhcGVNZXRhQ2hhcnMpIHtcbiAgICAvLyBDb252ZXJ0IHRvIHN0cmluZ1xuICAgIGFyZyA9IGAke2FyZ31gO1xuXG4gICAgLy8gQWxnb3JpdGhtIGJlbG93IGlzIGJhc2VkIG9uIGh0dHBzOi8vcW50bS5vcmcvY21kXG5cbiAgICAvLyBTZXF1ZW5jZSBvZiBiYWNrc2xhc2hlcyBmb2xsb3dlZCBieSBhIGRvdWJsZSBxdW90ZTpcbiAgICAvLyBkb3VibGUgdXAgYWxsIHRoZSBiYWNrc2xhc2hlcyBhbmQgZXNjYXBlIHRoZSBkb3VibGUgcXVvdGVcbiAgICBhcmcgPSBhcmcucmVwbGFjZSgvKFxcXFwqKVwiL2csICckMSQxXFxcXFwiJyk7XG5cbiAgICAvLyBTZXF1ZW5jZSBvZiBiYWNrc2xhc2hlcyBmb2xsb3dlZCBieSB0aGUgZW5kIG9mIHRoZSBzdHJpbmdcbiAgICAvLyAod2hpY2ggd2lsbCBiZWNvbWUgYSBkb3VibGUgcXVvdGUgbGF0ZXIpOlxuICAgIC8vIGRvdWJsZSB1cCBhbGwgdGhlIGJhY2tzbGFzaGVzXG4gICAgYXJnID0gYXJnLnJlcGxhY2UoLyhcXFxcKikkLywgJyQxJDEnKTtcblxuICAgIC8vIEFsbCBvdGhlciBiYWNrc2xhc2hlcyBvY2N1ciBsaXRlcmFsbHlcblxuICAgIC8vIFF1b3RlIHRoZSB3aG9sZSB0aGluZzpcbiAgICBhcmcgPSBgXCIke2FyZ31cImA7XG5cbiAgICAvLyBFc2NhcGUgbWV0YSBjaGFyc1xuICAgIGFyZyA9IGFyZy5yZXBsYWNlKG1ldGFDaGFyc1JlZ0V4cCwgJ14kMScpO1xuXG4gICAgLy8gRG91YmxlIGVzY2FwZSBtZXRhIGNoYXJzIGlmIG5lY2Vzc2FyeVxuICAgIGlmIChkb3VibGVFc2NhcGVNZXRhQ2hhcnMpIHtcbiAgICAgICAgYXJnID0gYXJnLnJlcGxhY2UobWV0YUNoYXJzUmVnRXhwLCAnXiQxJyk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGFyZztcbn1cblxubW9kdWxlLmV4cG9ydHMuY29tbWFuZCA9IGVzY2FwZUNvbW1hbmQ7XG5tb2R1bGUuZXhwb3J0cy5hcmd1bWVudCA9IGVzY2FwZUFyZ3VtZW50O1xuIiwiJ3VzZSBzdHJpY3QnO1xubW9kdWxlLmV4cG9ydHMgPSAvXiMhKC4qKS87XG4iLCIndXNlIHN0cmljdCc7XG5jb25zdCBzaGViYW5nUmVnZXggPSByZXF1aXJlKCdzaGViYW5nLXJlZ2V4Jyk7XG5cbm1vZHVsZS5leHBvcnRzID0gKHN0cmluZyA9ICcnKSA9PiB7XG5cdGNvbnN0IG1hdGNoID0gc3RyaW5nLm1hdGNoKHNoZWJhbmdSZWdleCk7XG5cblx0aWYgKCFtYXRjaCkge1xuXHRcdHJldHVybiBudWxsO1xuXHR9XG5cblx0Y29uc3QgW3BhdGgsIGFyZ3VtZW50XSA9IG1hdGNoWzBdLnJlcGxhY2UoLyMhID8vLCAnJykuc3BsaXQoJyAnKTtcblx0Y29uc3QgYmluYXJ5ID0gcGF0aC5zcGxpdCgnLycpLnBvcCgpO1xuXG5cdGlmIChiaW5hcnkgPT09ICdlbnYnKSB7XG5cdFx0cmV0dXJuIGFyZ3VtZW50O1xuXHR9XG5cblx0cmV0dXJuIGFyZ3VtZW50ID8gYCR7YmluYXJ5fSAke2FyZ3VtZW50fWAgOiBiaW5hcnk7XG59O1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG5jb25zdCBmcyA9IHJlcXVpcmUoJ2ZzJyk7XG5jb25zdCBzaGViYW5nQ29tbWFuZCA9IHJlcXVpcmUoJ3NoZWJhbmctY29tbWFuZCcpO1xuXG5mdW5jdGlvbiByZWFkU2hlYmFuZyhjb21tYW5kKSB7XG4gICAgLy8gUmVhZCB0aGUgZmlyc3QgMTUwIGJ5dGVzIGZyb20gdGhlIGZpbGVcbiAgICBjb25zdCBzaXplID0gMTUwO1xuICAgIGNvbnN0IGJ1ZmZlciA9IEJ1ZmZlci5hbGxvYyhzaXplKTtcblxuICAgIGxldCBmZDtcblxuICAgIHRyeSB7XG4gICAgICAgIGZkID0gZnMub3BlblN5bmMoY29tbWFuZCwgJ3InKTtcbiAgICAgICAgZnMucmVhZFN5bmMoZmQsIGJ1ZmZlciwgMCwgc2l6ZSwgMCk7XG4gICAgICAgIGZzLmNsb3NlU3luYyhmZCk7XG4gICAgfSBjYXRjaCAoZSkgeyAvKiBFbXB0eSAqLyB9XG5cbiAgICAvLyBBdHRlbXB0IHRvIGV4dHJhY3Qgc2hlYmFuZyAobnVsbCBpcyByZXR1cm5lZCBpZiBub3QgYSBzaGViYW5nKVxuICAgIHJldHVybiBzaGViYW5nQ29tbWFuZChidWZmZXIudG9TdHJpbmcoKSk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gcmVhZFNoZWJhbmc7XG4iLCIndXNlIHN0cmljdCc7XG5cbmNvbnN0IHBhdGggPSByZXF1aXJlKCdwYXRoJyk7XG5jb25zdCByZXNvbHZlQ29tbWFuZCA9IHJlcXVpcmUoJy4vdXRpbC9yZXNvbHZlQ29tbWFuZCcpO1xuY29uc3QgZXNjYXBlID0gcmVxdWlyZSgnLi91dGlsL2VzY2FwZScpO1xuY29uc3QgcmVhZFNoZWJhbmcgPSByZXF1aXJlKCcuL3V0aWwvcmVhZFNoZWJhbmcnKTtcblxuY29uc3QgaXNXaW4gPSBwcm9jZXNzLnBsYXRmb3JtID09PSAnd2luMzInO1xuY29uc3QgaXNFeGVjdXRhYmxlUmVnRXhwID0gL1xcLig/OmNvbXxleGUpJC9pO1xuY29uc3QgaXNDbWRTaGltUmVnRXhwID0gL25vZGVfbW9kdWxlc1tcXFxcL10uYmluW1xcXFwvXVteXFxcXC9dK1xcLmNtZCQvaTtcblxuZnVuY3Rpb24gZGV0ZWN0U2hlYmFuZyhwYXJzZWQpIHtcbiAgICBwYXJzZWQuZmlsZSA9IHJlc29sdmVDb21tYW5kKHBhcnNlZCk7XG5cbiAgICBjb25zdCBzaGViYW5nID0gcGFyc2VkLmZpbGUgJiYgcmVhZFNoZWJhbmcocGFyc2VkLmZpbGUpO1xuXG4gICAgaWYgKHNoZWJhbmcpIHtcbiAgICAgICAgcGFyc2VkLmFyZ3MudW5zaGlmdChwYXJzZWQuZmlsZSk7XG4gICAgICAgIHBhcnNlZC5jb21tYW5kID0gc2hlYmFuZztcblxuICAgICAgICByZXR1cm4gcmVzb2x2ZUNvbW1hbmQocGFyc2VkKTtcbiAgICB9XG5cbiAgICByZXR1cm4gcGFyc2VkLmZpbGU7XG59XG5cbmZ1bmN0aW9uIHBhcnNlTm9uU2hlbGwocGFyc2VkKSB7XG4gICAgaWYgKCFpc1dpbikge1xuICAgICAgICByZXR1cm4gcGFyc2VkO1xuICAgIH1cblxuICAgIC8vIERldGVjdCAmIGFkZCBzdXBwb3J0IGZvciBzaGViYW5nc1xuICAgIGNvbnN0IGNvbW1hbmRGaWxlID0gZGV0ZWN0U2hlYmFuZyhwYXJzZWQpO1xuXG4gICAgLy8gV2UgZG9uJ3QgbmVlZCBhIHNoZWxsIGlmIHRoZSBjb21tYW5kIGZpbGVuYW1lIGlzIGFuIGV4ZWN1dGFibGVcbiAgICBjb25zdCBuZWVkc1NoZWxsID0gIWlzRXhlY3V0YWJsZVJlZ0V4cC50ZXN0KGNvbW1hbmRGaWxlKTtcblxuICAgIC8vIElmIGEgc2hlbGwgaXMgcmVxdWlyZWQsIHVzZSBjbWQuZXhlIGFuZCB0YWtlIGNhcmUgb2YgZXNjYXBpbmcgZXZlcnl0aGluZyBjb3JyZWN0bHlcbiAgICAvLyBOb3RlIHRoYXQgYGZvcmNlU2hlbGxgIGlzIGFuIGhpZGRlbiBvcHRpb24gdXNlZCBvbmx5IGluIHRlc3RzXG4gICAgaWYgKHBhcnNlZC5vcHRpb25zLmZvcmNlU2hlbGwgfHwgbmVlZHNTaGVsbCkge1xuICAgICAgICAvLyBOZWVkIHRvIGRvdWJsZSBlc2NhcGUgbWV0YSBjaGFycyBpZiB0aGUgY29tbWFuZCBpcyBhIGNtZC1zaGltIGxvY2F0ZWQgaW4gYG5vZGVfbW9kdWxlcy8uYmluL2BcbiAgICAgICAgLy8gVGhlIGNtZC1zaGltIHNpbXBseSBjYWxscyBleGVjdXRlIHRoZSBwYWNrYWdlIGJpbiBmaWxlIHdpdGggTm9kZUpTLCBwcm94eWluZyBhbnkgYXJndW1lbnRcbiAgICAgICAgLy8gQmVjYXVzZSB0aGUgZXNjYXBlIG9mIG1ldGFjaGFycyB3aXRoIF4gZ2V0cyBpbnRlcnByZXRlZCB3aGVuIHRoZSBjbWQuZXhlIGlzIGZpcnN0IGNhbGxlZCxcbiAgICAgICAgLy8gd2UgbmVlZCB0byBkb3VibGUgZXNjYXBlIHRoZW1cbiAgICAgICAgY29uc3QgbmVlZHNEb3VibGVFc2NhcGVNZXRhQ2hhcnMgPSBpc0NtZFNoaW1SZWdFeHAudGVzdChjb21tYW5kRmlsZSk7XG5cbiAgICAgICAgLy8gTm9ybWFsaXplIHBvc2l4IHBhdGhzIGludG8gT1MgY29tcGF0aWJsZSBwYXRocyAoZS5nLjogZm9vL2JhciAtPiBmb29cXGJhcilcbiAgICAgICAgLy8gVGhpcyBpcyBuZWNlc3Nhcnkgb3RoZXJ3aXNlIGl0IHdpbGwgYWx3YXlzIGZhaWwgd2l0aCBFTk9FTlQgaW4gdGhvc2UgY2FzZXNcbiAgICAgICAgcGFyc2VkLmNvbW1hbmQgPSBwYXRoLm5vcm1hbGl6ZShwYXJzZWQuY29tbWFuZCk7XG5cbiAgICAgICAgLy8gRXNjYXBlIGNvbW1hbmQgJiBhcmd1bWVudHNcbiAgICAgICAgcGFyc2VkLmNvbW1hbmQgPSBlc2NhcGUuY29tbWFuZChwYXJzZWQuY29tbWFuZCk7XG4gICAgICAgIHBhcnNlZC5hcmdzID0gcGFyc2VkLmFyZ3MubWFwKChhcmcpID0+IGVzY2FwZS5hcmd1bWVudChhcmcsIG5lZWRzRG91YmxlRXNjYXBlTWV0YUNoYXJzKSk7XG5cbiAgICAgICAgY29uc3Qgc2hlbGxDb21tYW5kID0gW3BhcnNlZC5jb21tYW5kXS5jb25jYXQocGFyc2VkLmFyZ3MpLmpvaW4oJyAnKTtcblxuICAgICAgICBwYXJzZWQuYXJncyA9IFsnL2QnLCAnL3MnLCAnL2MnLCBgXCIke3NoZWxsQ29tbWFuZH1cImBdO1xuICAgICAgICBwYXJzZWQuY29tbWFuZCA9IHByb2Nlc3MuZW52LmNvbXNwZWMgfHwgJ2NtZC5leGUnO1xuICAgICAgICBwYXJzZWQub3B0aW9ucy53aW5kb3dzVmVyYmF0aW1Bcmd1bWVudHMgPSB0cnVlOyAvLyBUZWxsIG5vZGUncyBzcGF3biB0aGF0IHRoZSBhcmd1bWVudHMgYXJlIGFscmVhZHkgZXNjYXBlZFxuICAgIH1cblxuICAgIHJldHVybiBwYXJzZWQ7XG59XG5cbmZ1bmN0aW9uIHBhcnNlKGNvbW1hbmQsIGFyZ3MsIG9wdGlvbnMpIHtcbiAgICAvLyBOb3JtYWxpemUgYXJndW1lbnRzLCBzaW1pbGFyIHRvIG5vZGVqc1xuICAgIGlmIChhcmdzICYmICFBcnJheS5pc0FycmF5KGFyZ3MpKSB7XG4gICAgICAgIG9wdGlvbnMgPSBhcmdzO1xuICAgICAgICBhcmdzID0gbnVsbDtcbiAgICB9XG5cbiAgICBhcmdzID0gYXJncyA/IGFyZ3Muc2xpY2UoMCkgOiBbXTsgLy8gQ2xvbmUgYXJyYXkgdG8gYXZvaWQgY2hhbmdpbmcgdGhlIG9yaWdpbmFsXG4gICAgb3B0aW9ucyA9IE9iamVjdC5hc3NpZ24oe30sIG9wdGlvbnMpOyAvLyBDbG9uZSBvYmplY3QgdG8gYXZvaWQgY2hhbmdpbmcgdGhlIG9yaWdpbmFsXG5cbiAgICAvLyBCdWlsZCBvdXIgcGFyc2VkIG9iamVjdFxuICAgIGNvbnN0IHBhcnNlZCA9IHtcbiAgICAgICAgY29tbWFuZCxcbiAgICAgICAgYXJncyxcbiAgICAgICAgb3B0aW9ucyxcbiAgICAgICAgZmlsZTogdW5kZWZpbmVkLFxuICAgICAgICBvcmlnaW5hbDoge1xuICAgICAgICAgICAgY29tbWFuZCxcbiAgICAgICAgICAgIGFyZ3MsXG4gICAgICAgIH0sXG4gICAgfTtcblxuICAgIC8vIERlbGVnYXRlIGZ1cnRoZXIgcGFyc2luZyB0byBzaGVsbCBvciBub24tc2hlbGxcbiAgICByZXR1cm4gb3B0aW9ucy5zaGVsbCA/IHBhcnNlZCA6IHBhcnNlTm9uU2hlbGwocGFyc2VkKTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBwYXJzZTtcbiIsIid1c2Ugc3RyaWN0JztcblxuY29uc3QgaXNXaW4gPSBwcm9jZXNzLnBsYXRmb3JtID09PSAnd2luMzInO1xuXG5mdW5jdGlvbiBub3RGb3VuZEVycm9yKG9yaWdpbmFsLCBzeXNjYWxsKSB7XG4gICAgcmV0dXJuIE9iamVjdC5hc3NpZ24obmV3IEVycm9yKGAke3N5c2NhbGx9ICR7b3JpZ2luYWwuY29tbWFuZH0gRU5PRU5UYCksIHtcbiAgICAgICAgY29kZTogJ0VOT0VOVCcsXG4gICAgICAgIGVycm5vOiAnRU5PRU5UJyxcbiAgICAgICAgc3lzY2FsbDogYCR7c3lzY2FsbH0gJHtvcmlnaW5hbC5jb21tYW5kfWAsXG4gICAgICAgIHBhdGg6IG9yaWdpbmFsLmNvbW1hbmQsXG4gICAgICAgIHNwYXduYXJnczogb3JpZ2luYWwuYXJncyxcbiAgICB9KTtcbn1cblxuZnVuY3Rpb24gaG9va0NoaWxkUHJvY2VzcyhjcCwgcGFyc2VkKSB7XG4gICAgaWYgKCFpc1dpbikge1xuICAgICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29uc3Qgb3JpZ2luYWxFbWl0ID0gY3AuZW1pdDtcblxuICAgIGNwLmVtaXQgPSBmdW5jdGlvbiAobmFtZSwgYXJnMSkge1xuICAgICAgICAvLyBJZiBlbWl0dGluZyBcImV4aXRcIiBldmVudCBhbmQgZXhpdCBjb2RlIGlzIDEsIHdlIG5lZWQgdG8gY2hlY2sgaWZcbiAgICAgICAgLy8gdGhlIGNvbW1hbmQgZXhpc3RzIGFuZCBlbWl0IGFuIFwiZXJyb3JcIiBpbnN0ZWFkXG4gICAgICAgIC8vIFNlZSBodHRwczovL2dpdGh1Yi5jb20vSW5kaWdvVW5pdGVkL25vZGUtY3Jvc3Mtc3Bhd24vaXNzdWVzLzE2XG4gICAgICAgIGlmIChuYW1lID09PSAnZXhpdCcpIHtcbiAgICAgICAgICAgIGNvbnN0IGVyciA9IHZlcmlmeUVOT0VOVChhcmcxLCBwYXJzZWQsICdzcGF3bicpO1xuXG4gICAgICAgICAgICBpZiAoZXJyKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIG9yaWdpbmFsRW1pdC5jYWxsKGNwLCAnZXJyb3InLCBlcnIpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIG9yaWdpbmFsRW1pdC5hcHBseShjcCwgYXJndW1lbnRzKTsgLy8gZXNsaW50LWRpc2FibGUtbGluZSBwcmVmZXItcmVzdC1wYXJhbXNcbiAgICB9O1xufVxuXG5mdW5jdGlvbiB2ZXJpZnlFTk9FTlQoc3RhdHVzLCBwYXJzZWQpIHtcbiAgICBpZiAoaXNXaW4gJiYgc3RhdHVzID09PSAxICYmICFwYXJzZWQuZmlsZSkge1xuICAgICAgICByZXR1cm4gbm90Rm91bmRFcnJvcihwYXJzZWQub3JpZ2luYWwsICdzcGF3bicpO1xuICAgIH1cblxuICAgIHJldHVybiBudWxsO1xufVxuXG5mdW5jdGlvbiB2ZXJpZnlFTk9FTlRTeW5jKHN0YXR1cywgcGFyc2VkKSB7XG4gICAgaWYgKGlzV2luICYmIHN0YXR1cyA9PT0gMSAmJiAhcGFyc2VkLmZpbGUpIHtcbiAgICAgICAgcmV0dXJuIG5vdEZvdW5kRXJyb3IocGFyc2VkLm9yaWdpbmFsLCAnc3Bhd25TeW5jJyk7XG4gICAgfVxuXG4gICAgcmV0dXJuIG51bGw7XG59XG5cbm1vZHVsZS5leHBvcnRzID0ge1xuICAgIGhvb2tDaGlsZFByb2Nlc3MsXG4gICAgdmVyaWZ5RU5PRU5ULFxuICAgIHZlcmlmeUVOT0VOVFN5bmMsXG4gICAgbm90Rm91bmRFcnJvcixcbn07XG4iLCIndXNlIHN0cmljdCc7XG5cbmNvbnN0IGNwID0gcmVxdWlyZSgnY2hpbGRfcHJvY2VzcycpO1xuY29uc3QgcGFyc2UgPSByZXF1aXJlKCcuL2xpYi9wYXJzZScpO1xuY29uc3QgZW5vZW50ID0gcmVxdWlyZSgnLi9saWIvZW5vZW50Jyk7XG5cbmZ1bmN0aW9uIHNwYXduKGNvbW1hbmQsIGFyZ3MsIG9wdGlvbnMpIHtcbiAgICAvLyBQYXJzZSB0aGUgYXJndW1lbnRzXG4gICAgY29uc3QgcGFyc2VkID0gcGFyc2UoY29tbWFuZCwgYXJncywgb3B0aW9ucyk7XG5cbiAgICAvLyBTcGF3biB0aGUgY2hpbGQgcHJvY2Vzc1xuICAgIGNvbnN0IHNwYXduZWQgPSBjcC5zcGF3bihwYXJzZWQuY29tbWFuZCwgcGFyc2VkLmFyZ3MsIHBhcnNlZC5vcHRpb25zKTtcblxuICAgIC8vIEhvb2sgaW50byBjaGlsZCBwcm9jZXNzIFwiZXhpdFwiIGV2ZW50IHRvIGVtaXQgYW4gZXJyb3IgaWYgdGhlIGNvbW1hbmRcbiAgICAvLyBkb2VzIG5vdCBleGlzdHMsIHNlZTogaHR0cHM6Ly9naXRodWIuY29tL0luZGlnb1VuaXRlZC9ub2RlLWNyb3NzLXNwYXduL2lzc3Vlcy8xNlxuICAgIGVub2VudC5ob29rQ2hpbGRQcm9jZXNzKHNwYXduZWQsIHBhcnNlZCk7XG5cbiAgICByZXR1cm4gc3Bhd25lZDtcbn1cblxuZnVuY3Rpb24gc3Bhd25TeW5jKGNvbW1hbmQsIGFyZ3MsIG9wdGlvbnMpIHtcbiAgICAvLyBQYXJzZSB0aGUgYXJndW1lbnRzXG4gICAgY29uc3QgcGFyc2VkID0gcGFyc2UoY29tbWFuZCwgYXJncywgb3B0aW9ucyk7XG5cbiAgICAvLyBTcGF3biB0aGUgY2hpbGQgcHJvY2Vzc1xuICAgIGNvbnN0IHJlc3VsdCA9IGNwLnNwYXduU3luYyhwYXJzZWQuY29tbWFuZCwgcGFyc2VkLmFyZ3MsIHBhcnNlZC5vcHRpb25zKTtcblxuICAgIC8vIEFuYWx5emUgaWYgdGhlIGNvbW1hbmQgZG9lcyBub3QgZXhpc3QsIHNlZTogaHR0cHM6Ly9naXRodWIuY29tL0luZGlnb1VuaXRlZC9ub2RlLWNyb3NzLXNwYXduL2lzc3Vlcy8xNlxuICAgIHJlc3VsdC5lcnJvciA9IHJlc3VsdC5lcnJvciB8fCBlbm9lbnQudmVyaWZ5RU5PRU5UU3luYyhyZXN1bHQuc3RhdHVzLCBwYXJzZWQpO1xuXG4gICAgcmV0dXJuIHJlc3VsdDtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBzcGF3bjtcbm1vZHVsZS5leHBvcnRzLnNwYXduID0gc3Bhd247XG5tb2R1bGUuZXhwb3J0cy5zeW5jID0gc3Bhd25TeW5jO1xuXG5tb2R1bGUuZXhwb3J0cy5fcGFyc2UgPSBwYXJzZTtcbm1vZHVsZS5leHBvcnRzLl9lbm9lbnQgPSBlbm9lbnQ7XG4iLCIndXNlIHN0cmljdCc7XG5cbm1vZHVsZS5leHBvcnRzID0gaW5wdXQgPT4ge1xuXHRjb25zdCBMRiA9IHR5cGVvZiBpbnB1dCA9PT0gJ3N0cmluZycgPyAnXFxuJyA6ICdcXG4nLmNoYXJDb2RlQXQoKTtcblx0Y29uc3QgQ1IgPSB0eXBlb2YgaW5wdXQgPT09ICdzdHJpbmcnID8gJ1xccicgOiAnXFxyJy5jaGFyQ29kZUF0KCk7XG5cblx0aWYgKGlucHV0W2lucHV0Lmxlbmd0aCAtIDFdID09PSBMRikge1xuXHRcdGlucHV0ID0gaW5wdXQuc2xpY2UoMCwgaW5wdXQubGVuZ3RoIC0gMSk7XG5cdH1cblxuXHRpZiAoaW5wdXRbaW5wdXQubGVuZ3RoIC0gMV0gPT09IENSKSB7XG5cdFx0aW5wdXQgPSBpbnB1dC5zbGljZSgwLCBpbnB1dC5sZW5ndGggLSAxKTtcblx0fVxuXG5cdHJldHVybiBpbnB1dDtcbn07XG4iLCIndXNlIHN0cmljdCc7XG5jb25zdCBwYXRoID0gcmVxdWlyZSgncGF0aCcpO1xuY29uc3QgcGF0aEtleSA9IHJlcXVpcmUoJ3BhdGgta2V5Jyk7XG5cbmNvbnN0IG5wbVJ1blBhdGggPSBvcHRpb25zID0+IHtcblx0b3B0aW9ucyA9IHtcblx0XHRjd2Q6IHByb2Nlc3MuY3dkKCksXG5cdFx0cGF0aDogcHJvY2Vzcy5lbnZbcGF0aEtleSgpXSxcblx0XHRleGVjUGF0aDogcHJvY2Vzcy5leGVjUGF0aCxcblx0XHQuLi5vcHRpb25zXG5cdH07XG5cblx0bGV0IHByZXZpb3VzO1xuXHRsZXQgY3dkUGF0aCA9IHBhdGgucmVzb2x2ZShvcHRpb25zLmN3ZCk7XG5cdGNvbnN0IHJlc3VsdCA9IFtdO1xuXG5cdHdoaWxlIChwcmV2aW91cyAhPT0gY3dkUGF0aCkge1xuXHRcdHJlc3VsdC5wdXNoKHBhdGguam9pbihjd2RQYXRoLCAnbm9kZV9tb2R1bGVzLy5iaW4nKSk7XG5cdFx0cHJldmlvdXMgPSBjd2RQYXRoO1xuXHRcdGN3ZFBhdGggPSBwYXRoLnJlc29sdmUoY3dkUGF0aCwgJy4uJyk7XG5cdH1cblxuXHQvLyBFbnN1cmUgdGhlIHJ1bm5pbmcgYG5vZGVgIGJpbmFyeSBpcyB1c2VkXG5cdGNvbnN0IGV4ZWNQYXRoRGlyID0gcGF0aC5yZXNvbHZlKG9wdGlvbnMuY3dkLCBvcHRpb25zLmV4ZWNQYXRoLCAnLi4nKTtcblx0cmVzdWx0LnB1c2goZXhlY1BhdGhEaXIpO1xuXG5cdHJldHVybiByZXN1bHQuY29uY2F0KG9wdGlvbnMucGF0aCkuam9pbihwYXRoLmRlbGltaXRlcik7XG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IG5wbVJ1blBhdGg7XG4vLyBUT0RPOiBSZW1vdmUgdGhpcyBmb3IgdGhlIG5leHQgbWFqb3IgcmVsZWFzZVxubW9kdWxlLmV4cG9ydHMuZGVmYXVsdCA9IG5wbVJ1blBhdGg7XG5cbm1vZHVsZS5leHBvcnRzLmVudiA9IG9wdGlvbnMgPT4ge1xuXHRvcHRpb25zID0ge1xuXHRcdGVudjogcHJvY2Vzcy5lbnYsXG5cdFx0Li4ub3B0aW9uc1xuXHR9O1xuXG5cdGNvbnN0IGVudiA9IHsuLi5vcHRpb25zLmVudn07XG5cdGNvbnN0IHBhdGggPSBwYXRoS2V5KHtlbnZ9KTtcblxuXHRvcHRpb25zLnBhdGggPSBlbnZbcGF0aF07XG5cdGVudltwYXRoXSA9IG1vZHVsZS5leHBvcnRzKG9wdGlvbnMpO1xuXG5cdHJldHVybiBlbnY7XG59O1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG5jb25zdCBtaW1pY0ZuID0gKHRvLCBmcm9tKSA9PiB7XG5cdGZvciAoY29uc3QgcHJvcCBvZiBSZWZsZWN0Lm93bktleXMoZnJvbSkpIHtcblx0XHRPYmplY3QuZGVmaW5lUHJvcGVydHkodG8sIHByb3AsIE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IoZnJvbSwgcHJvcCkpO1xuXHR9XG5cblx0cmV0dXJuIHRvO1xufTtcblxubW9kdWxlLmV4cG9ydHMgPSBtaW1pY0ZuO1xuLy8gVE9ETzogUmVtb3ZlIHRoaXMgZm9yIHRoZSBuZXh0IG1ham9yIHJlbGVhc2Vcbm1vZHVsZS5leHBvcnRzLmRlZmF1bHQgPSBtaW1pY0ZuO1xuIiwiJ3VzZSBzdHJpY3QnO1xuY29uc3QgbWltaWNGbiA9IHJlcXVpcmUoJ21pbWljLWZuJyk7XG5cbmNvbnN0IGNhbGxlZEZ1bmN0aW9ucyA9IG5ldyBXZWFrTWFwKCk7XG5cbmNvbnN0IG9uZXRpbWUgPSAoZnVuY3Rpb25fLCBvcHRpb25zID0ge30pID0+IHtcblx0aWYgKHR5cGVvZiBmdW5jdGlvbl8gIT09ICdmdW5jdGlvbicpIHtcblx0XHR0aHJvdyBuZXcgVHlwZUVycm9yKCdFeHBlY3RlZCBhIGZ1bmN0aW9uJyk7XG5cdH1cblxuXHRsZXQgcmV0dXJuVmFsdWU7XG5cdGxldCBjYWxsQ291bnQgPSAwO1xuXHRjb25zdCBmdW5jdGlvbk5hbWUgPSBmdW5jdGlvbl8uZGlzcGxheU5hbWUgfHwgZnVuY3Rpb25fLm5hbWUgfHwgJzxhbm9ueW1vdXM+JztcblxuXHRjb25zdCBvbmV0aW1lID0gZnVuY3Rpb24gKC4uLmFyZ3VtZW50c18pIHtcblx0XHRjYWxsZWRGdW5jdGlvbnMuc2V0KG9uZXRpbWUsICsrY2FsbENvdW50KTtcblxuXHRcdGlmIChjYWxsQ291bnQgPT09IDEpIHtcblx0XHRcdHJldHVyblZhbHVlID0gZnVuY3Rpb25fLmFwcGx5KHRoaXMsIGFyZ3VtZW50c18pO1xuXHRcdFx0ZnVuY3Rpb25fID0gbnVsbDtcblx0XHR9IGVsc2UgaWYgKG9wdGlvbnMudGhyb3cgPT09IHRydWUpIHtcblx0XHRcdHRocm93IG5ldyBFcnJvcihgRnVuY3Rpb24gXFxgJHtmdW5jdGlvbk5hbWV9XFxgIGNhbiBvbmx5IGJlIGNhbGxlZCBvbmNlYCk7XG5cdFx0fVxuXG5cdFx0cmV0dXJuIHJldHVyblZhbHVlO1xuXHR9O1xuXG5cdG1pbWljRm4ob25ldGltZSwgZnVuY3Rpb25fKTtcblx0Y2FsbGVkRnVuY3Rpb25zLnNldChvbmV0aW1lLCBjYWxsQ291bnQpO1xuXG5cdHJldHVybiBvbmV0aW1lO1xufTtcblxubW9kdWxlLmV4cG9ydHMgPSBvbmV0aW1lO1xuLy8gVE9ETzogUmVtb3ZlIHRoaXMgZm9yIHRoZSBuZXh0IG1ham9yIHJlbGVhc2Vcbm1vZHVsZS5leHBvcnRzLmRlZmF1bHQgPSBvbmV0aW1lO1xuXG5tb2R1bGUuZXhwb3J0cy5jYWxsQ291bnQgPSBmdW5jdGlvbl8gPT4ge1xuXHRpZiAoIWNhbGxlZEZ1bmN0aW9ucy5oYXMoZnVuY3Rpb25fKSkge1xuXHRcdHRocm93IG5ldyBFcnJvcihgVGhlIGdpdmVuIGZ1bmN0aW9uIFxcYCR7ZnVuY3Rpb25fLm5hbWV9XFxgIGlzIG5vdCB3cmFwcGVkIGJ5IHRoZSBcXGBvbmV0aW1lXFxgIHBhY2thZ2VgKTtcblx0fVxuXG5cdHJldHVybiBjYWxsZWRGdW5jdGlvbnMuZ2V0KGZ1bmN0aW9uXyk7XG59O1xuIiwiXCJ1c2Ugc3RyaWN0XCI7T2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsXCJfX2VzTW9kdWxlXCIse3ZhbHVlOnRydWV9KTtleHBvcnRzLlNJR05BTFM9dm9pZCAwO1xuXG5jb25zdCBTSUdOQUxTPVtcbntcbm5hbWU6XCJTSUdIVVBcIixcbm51bWJlcjoxLFxuYWN0aW9uOlwidGVybWluYXRlXCIsXG5kZXNjcmlwdGlvbjpcIlRlcm1pbmFsIGNsb3NlZFwiLFxuc3RhbmRhcmQ6XCJwb3NpeFwifSxcblxue1xubmFtZTpcIlNJR0lOVFwiLFxubnVtYmVyOjIsXG5hY3Rpb246XCJ0ZXJtaW5hdGVcIixcbmRlc2NyaXB0aW9uOlwiVXNlciBpbnRlcnJ1cHRpb24gd2l0aCBDVFJMLUNcIixcbnN0YW5kYXJkOlwiYW5zaVwifSxcblxue1xubmFtZTpcIlNJR1FVSVRcIixcbm51bWJlcjozLFxuYWN0aW9uOlwiY29yZVwiLFxuZGVzY3JpcHRpb246XCJVc2VyIGludGVycnVwdGlvbiB3aXRoIENUUkwtXFxcXFwiLFxuc3RhbmRhcmQ6XCJwb3NpeFwifSxcblxue1xubmFtZTpcIlNJR0lMTFwiLFxubnVtYmVyOjQsXG5hY3Rpb246XCJjb3JlXCIsXG5kZXNjcmlwdGlvbjpcIkludmFsaWQgbWFjaGluZSBpbnN0cnVjdGlvblwiLFxuc3RhbmRhcmQ6XCJhbnNpXCJ9LFxuXG57XG5uYW1lOlwiU0lHVFJBUFwiLFxubnVtYmVyOjUsXG5hY3Rpb246XCJjb3JlXCIsXG5kZXNjcmlwdGlvbjpcIkRlYnVnZ2VyIGJyZWFrcG9pbnRcIixcbnN0YW5kYXJkOlwicG9zaXhcIn0sXG5cbntcbm5hbWU6XCJTSUdBQlJUXCIsXG5udW1iZXI6NixcbmFjdGlvbjpcImNvcmVcIixcbmRlc2NyaXB0aW9uOlwiQWJvcnRlZFwiLFxuc3RhbmRhcmQ6XCJhbnNpXCJ9LFxuXG57XG5uYW1lOlwiU0lHSU9UXCIsXG5udW1iZXI6NixcbmFjdGlvbjpcImNvcmVcIixcbmRlc2NyaXB0aW9uOlwiQWJvcnRlZFwiLFxuc3RhbmRhcmQ6XCJic2RcIn0sXG5cbntcbm5hbWU6XCJTSUdCVVNcIixcbm51bWJlcjo3LFxuYWN0aW9uOlwiY29yZVwiLFxuZGVzY3JpcHRpb246XG5cIkJ1cyBlcnJvciBkdWUgdG8gbWlzYWxpZ25lZCwgbm9uLWV4aXN0aW5nIGFkZHJlc3Mgb3IgcGFnaW5nIGVycm9yXCIsXG5zdGFuZGFyZDpcImJzZFwifSxcblxue1xubmFtZTpcIlNJR0VNVFwiLFxubnVtYmVyOjcsXG5hY3Rpb246XCJ0ZXJtaW5hdGVcIixcbmRlc2NyaXB0aW9uOlwiQ29tbWFuZCBzaG91bGQgYmUgZW11bGF0ZWQgYnV0IGlzIG5vdCBpbXBsZW1lbnRlZFwiLFxuc3RhbmRhcmQ6XCJvdGhlclwifSxcblxue1xubmFtZTpcIlNJR0ZQRVwiLFxubnVtYmVyOjgsXG5hY3Rpb246XCJjb3JlXCIsXG5kZXNjcmlwdGlvbjpcIkZsb2F0aW5nIHBvaW50IGFyaXRobWV0aWMgZXJyb3JcIixcbnN0YW5kYXJkOlwiYW5zaVwifSxcblxue1xubmFtZTpcIlNJR0tJTExcIixcbm51bWJlcjo5LFxuYWN0aW9uOlwidGVybWluYXRlXCIsXG5kZXNjcmlwdGlvbjpcIkZvcmNlZCB0ZXJtaW5hdGlvblwiLFxuc3RhbmRhcmQ6XCJwb3NpeFwiLFxuZm9yY2VkOnRydWV9LFxuXG57XG5uYW1lOlwiU0lHVVNSMVwiLFxubnVtYmVyOjEwLFxuYWN0aW9uOlwidGVybWluYXRlXCIsXG5kZXNjcmlwdGlvbjpcIkFwcGxpY2F0aW9uLXNwZWNpZmljIHNpZ25hbFwiLFxuc3RhbmRhcmQ6XCJwb3NpeFwifSxcblxue1xubmFtZTpcIlNJR1NFR1ZcIixcbm51bWJlcjoxMSxcbmFjdGlvbjpcImNvcmVcIixcbmRlc2NyaXB0aW9uOlwiU2VnbWVudGF0aW9uIGZhdWx0XCIsXG5zdGFuZGFyZDpcImFuc2lcIn0sXG5cbntcbm5hbWU6XCJTSUdVU1IyXCIsXG5udW1iZXI6MTIsXG5hY3Rpb246XCJ0ZXJtaW5hdGVcIixcbmRlc2NyaXB0aW9uOlwiQXBwbGljYXRpb24tc3BlY2lmaWMgc2lnbmFsXCIsXG5zdGFuZGFyZDpcInBvc2l4XCJ9LFxuXG57XG5uYW1lOlwiU0lHUElQRVwiLFxubnVtYmVyOjEzLFxuYWN0aW9uOlwidGVybWluYXRlXCIsXG5kZXNjcmlwdGlvbjpcIkJyb2tlbiBwaXBlIG9yIHNvY2tldFwiLFxuc3RhbmRhcmQ6XCJwb3NpeFwifSxcblxue1xubmFtZTpcIlNJR0FMUk1cIixcbm51bWJlcjoxNCxcbmFjdGlvbjpcInRlcm1pbmF0ZVwiLFxuZGVzY3JpcHRpb246XCJUaW1lb3V0IG9yIHRpbWVyXCIsXG5zdGFuZGFyZDpcInBvc2l4XCJ9LFxuXG57XG5uYW1lOlwiU0lHVEVSTVwiLFxubnVtYmVyOjE1LFxuYWN0aW9uOlwidGVybWluYXRlXCIsXG5kZXNjcmlwdGlvbjpcIlRlcm1pbmF0aW9uXCIsXG5zdGFuZGFyZDpcImFuc2lcIn0sXG5cbntcbm5hbWU6XCJTSUdTVEtGTFRcIixcbm51bWJlcjoxNixcbmFjdGlvbjpcInRlcm1pbmF0ZVwiLFxuZGVzY3JpcHRpb246XCJTdGFjayBpcyBlbXB0eSBvciBvdmVyZmxvd2VkXCIsXG5zdGFuZGFyZDpcIm90aGVyXCJ9LFxuXG57XG5uYW1lOlwiU0lHQ0hMRFwiLFxubnVtYmVyOjE3LFxuYWN0aW9uOlwiaWdub3JlXCIsXG5kZXNjcmlwdGlvbjpcIkNoaWxkIHByb2Nlc3MgdGVybWluYXRlZCwgcGF1c2VkIG9yIHVucGF1c2VkXCIsXG5zdGFuZGFyZDpcInBvc2l4XCJ9LFxuXG57XG5uYW1lOlwiU0lHQ0xEXCIsXG5udW1iZXI6MTcsXG5hY3Rpb246XCJpZ25vcmVcIixcbmRlc2NyaXB0aW9uOlwiQ2hpbGQgcHJvY2VzcyB0ZXJtaW5hdGVkLCBwYXVzZWQgb3IgdW5wYXVzZWRcIixcbnN0YW5kYXJkOlwib3RoZXJcIn0sXG5cbntcbm5hbWU6XCJTSUdDT05UXCIsXG5udW1iZXI6MTgsXG5hY3Rpb246XCJ1bnBhdXNlXCIsXG5kZXNjcmlwdGlvbjpcIlVucGF1c2VkXCIsXG5zdGFuZGFyZDpcInBvc2l4XCIsXG5mb3JjZWQ6dHJ1ZX0sXG5cbntcbm5hbWU6XCJTSUdTVE9QXCIsXG5udW1iZXI6MTksXG5hY3Rpb246XCJwYXVzZVwiLFxuZGVzY3JpcHRpb246XCJQYXVzZWRcIixcbnN0YW5kYXJkOlwicG9zaXhcIixcbmZvcmNlZDp0cnVlfSxcblxue1xubmFtZTpcIlNJR1RTVFBcIixcbm51bWJlcjoyMCxcbmFjdGlvbjpcInBhdXNlXCIsXG5kZXNjcmlwdGlvbjpcIlBhdXNlZCB1c2luZyBDVFJMLVogb3IgXFxcInN1c3BlbmRcXFwiXCIsXG5zdGFuZGFyZDpcInBvc2l4XCJ9LFxuXG57XG5uYW1lOlwiU0lHVFRJTlwiLFxubnVtYmVyOjIxLFxuYWN0aW9uOlwicGF1c2VcIixcbmRlc2NyaXB0aW9uOlwiQmFja2dyb3VuZCBwcm9jZXNzIGNhbm5vdCByZWFkIHRlcm1pbmFsIGlucHV0XCIsXG5zdGFuZGFyZDpcInBvc2l4XCJ9LFxuXG57XG5uYW1lOlwiU0lHQlJFQUtcIixcbm51bWJlcjoyMSxcbmFjdGlvbjpcInRlcm1pbmF0ZVwiLFxuZGVzY3JpcHRpb246XCJVc2VyIGludGVycnVwdGlvbiB3aXRoIENUUkwtQlJFQUtcIixcbnN0YW5kYXJkOlwib3RoZXJcIn0sXG5cbntcbm5hbWU6XCJTSUdUVE9VXCIsXG5udW1iZXI6MjIsXG5hY3Rpb246XCJwYXVzZVwiLFxuZGVzY3JpcHRpb246XCJCYWNrZ3JvdW5kIHByb2Nlc3MgY2Fubm90IHdyaXRlIHRvIHRlcm1pbmFsIG91dHB1dFwiLFxuc3RhbmRhcmQ6XCJwb3NpeFwifSxcblxue1xubmFtZTpcIlNJR1VSR1wiLFxubnVtYmVyOjIzLFxuYWN0aW9uOlwiaWdub3JlXCIsXG5kZXNjcmlwdGlvbjpcIlNvY2tldCByZWNlaXZlZCBvdXQtb2YtYmFuZCBkYXRhXCIsXG5zdGFuZGFyZDpcImJzZFwifSxcblxue1xubmFtZTpcIlNJR1hDUFVcIixcbm51bWJlcjoyNCxcbmFjdGlvbjpcImNvcmVcIixcbmRlc2NyaXB0aW9uOlwiUHJvY2VzcyB0aW1lZCBvdXRcIixcbnN0YW5kYXJkOlwiYnNkXCJ9LFxuXG57XG5uYW1lOlwiU0lHWEZTWlwiLFxubnVtYmVyOjI1LFxuYWN0aW9uOlwiY29yZVwiLFxuZGVzY3JpcHRpb246XCJGaWxlIHRvbyBiaWdcIixcbnN0YW5kYXJkOlwiYnNkXCJ9LFxuXG57XG5uYW1lOlwiU0lHVlRBTFJNXCIsXG5udW1iZXI6MjYsXG5hY3Rpb246XCJ0ZXJtaW5hdGVcIixcbmRlc2NyaXB0aW9uOlwiVGltZW91dCBvciB0aW1lclwiLFxuc3RhbmRhcmQ6XCJic2RcIn0sXG5cbntcbm5hbWU6XCJTSUdQUk9GXCIsXG5udW1iZXI6MjcsXG5hY3Rpb246XCJ0ZXJtaW5hdGVcIixcbmRlc2NyaXB0aW9uOlwiVGltZW91dCBvciB0aW1lclwiLFxuc3RhbmRhcmQ6XCJic2RcIn0sXG5cbntcbm5hbWU6XCJTSUdXSU5DSFwiLFxubnVtYmVyOjI4LFxuYWN0aW9uOlwiaWdub3JlXCIsXG5kZXNjcmlwdGlvbjpcIlRlcm1pbmFsIHdpbmRvdyBzaXplIGNoYW5nZWRcIixcbnN0YW5kYXJkOlwiYnNkXCJ9LFxuXG57XG5uYW1lOlwiU0lHSU9cIixcbm51bWJlcjoyOSxcbmFjdGlvbjpcInRlcm1pbmF0ZVwiLFxuZGVzY3JpcHRpb246XCJJL08gaXMgYXZhaWxhYmxlXCIsXG5zdGFuZGFyZDpcIm90aGVyXCJ9LFxuXG57XG5uYW1lOlwiU0lHUE9MTFwiLFxubnVtYmVyOjI5LFxuYWN0aW9uOlwidGVybWluYXRlXCIsXG5kZXNjcmlwdGlvbjpcIldhdGNoZWQgZXZlbnRcIixcbnN0YW5kYXJkOlwib3RoZXJcIn0sXG5cbntcbm5hbWU6XCJTSUdJTkZPXCIsXG5udW1iZXI6MjksXG5hY3Rpb246XCJpZ25vcmVcIixcbmRlc2NyaXB0aW9uOlwiUmVxdWVzdCBmb3IgcHJvY2VzcyBpbmZvcm1hdGlvblwiLFxuc3RhbmRhcmQ6XCJvdGhlclwifSxcblxue1xubmFtZTpcIlNJR1BXUlwiLFxubnVtYmVyOjMwLFxuYWN0aW9uOlwidGVybWluYXRlXCIsXG5kZXNjcmlwdGlvbjpcIkRldmljZSBydW5uaW5nIG91dCBvZiBwb3dlclwiLFxuc3RhbmRhcmQ6XCJzeXN0ZW12XCJ9LFxuXG57XG5uYW1lOlwiU0lHU1lTXCIsXG5udW1iZXI6MzEsXG5hY3Rpb246XCJjb3JlXCIsXG5kZXNjcmlwdGlvbjpcIkludmFsaWQgc3lzdGVtIGNhbGxcIixcbnN0YW5kYXJkOlwib3RoZXJcIn0sXG5cbntcbm5hbWU6XCJTSUdVTlVTRURcIixcbm51bWJlcjozMSxcbmFjdGlvbjpcInRlcm1pbmF0ZVwiLFxuZGVzY3JpcHRpb246XCJJbnZhbGlkIHN5c3RlbSBjYWxsXCIsXG5zdGFuZGFyZDpcIm90aGVyXCJ9XTtleHBvcnRzLlNJR05BTFM9U0lHTkFMUztcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWNvcmUuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7T2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsXCJfX2VzTW9kdWxlXCIse3ZhbHVlOnRydWV9KTtleHBvcnRzLlNJR1JUTUFYPWV4cG9ydHMuZ2V0UmVhbHRpbWVTaWduYWxzPXZvaWQgMDtcbmNvbnN0IGdldFJlYWx0aW1lU2lnbmFscz1mdW5jdGlvbigpe1xuY29uc3QgbGVuZ3RoPVNJR1JUTUFYLVNJR1JUTUlOKzE7XG5yZXR1cm4gQXJyYXkuZnJvbSh7bGVuZ3RofSxnZXRSZWFsdGltZVNpZ25hbCk7XG59O2V4cG9ydHMuZ2V0UmVhbHRpbWVTaWduYWxzPWdldFJlYWx0aW1lU2lnbmFscztcblxuY29uc3QgZ2V0UmVhbHRpbWVTaWduYWw9ZnVuY3Rpb24odmFsdWUsaW5kZXgpe1xucmV0dXJue1xubmFtZTpgU0lHUlQke2luZGV4KzF9YCxcbm51bWJlcjpTSUdSVE1JTitpbmRleCxcbmFjdGlvbjpcInRlcm1pbmF0ZVwiLFxuZGVzY3JpcHRpb246XCJBcHBsaWNhdGlvbi1zcGVjaWZpYyBzaWduYWwgKHJlYWx0aW1lKVwiLFxuc3RhbmRhcmQ6XCJwb3NpeFwifTtcblxufTtcblxuY29uc3QgU0lHUlRNSU49MzQ7XG5jb25zdCBTSUdSVE1BWD02NDtleHBvcnRzLlNJR1JUTUFYPVNJR1JUTUFYO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9cmVhbHRpbWUuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7T2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsXCJfX2VzTW9kdWxlXCIse3ZhbHVlOnRydWV9KTtleHBvcnRzLmdldFNpZ25hbHM9dm9pZCAwO3ZhciBfb3M9cmVxdWlyZShcIm9zXCIpO1xuXG52YXIgX2NvcmU9cmVxdWlyZShcIi4vY29yZS5qc1wiKTtcbnZhciBfcmVhbHRpbWU9cmVxdWlyZShcIi4vcmVhbHRpbWUuanNcIik7XG5cblxuXG5jb25zdCBnZXRTaWduYWxzPWZ1bmN0aW9uKCl7XG5jb25zdCByZWFsdGltZVNpZ25hbHM9KDAsX3JlYWx0aW1lLmdldFJlYWx0aW1lU2lnbmFscykoKTtcbmNvbnN0IHNpZ25hbHM9Wy4uLl9jb3JlLlNJR05BTFMsLi4ucmVhbHRpbWVTaWduYWxzXS5tYXAobm9ybWFsaXplU2lnbmFsKTtcbnJldHVybiBzaWduYWxzO1xufTtleHBvcnRzLmdldFNpZ25hbHM9Z2V0U2lnbmFscztcblxuXG5cblxuXG5cblxuY29uc3Qgbm9ybWFsaXplU2lnbmFsPWZ1bmN0aW9uKHtcbm5hbWUsXG5udW1iZXI6ZGVmYXVsdE51bWJlcixcbmRlc2NyaXB0aW9uLFxuYWN0aW9uLFxuZm9yY2VkPWZhbHNlLFxuc3RhbmRhcmR9KVxue1xuY29uc3R7XG5zaWduYWxzOntbbmFtZV06Y29uc3RhbnRTaWduYWx9fT1cbl9vcy5jb25zdGFudHM7XG5jb25zdCBzdXBwb3J0ZWQ9Y29uc3RhbnRTaWduYWwhPT11bmRlZmluZWQ7XG5jb25zdCBudW1iZXI9c3VwcG9ydGVkP2NvbnN0YW50U2lnbmFsOmRlZmF1bHROdW1iZXI7XG5yZXR1cm57bmFtZSxudW1iZXIsZGVzY3JpcHRpb24sc3VwcG9ydGVkLGFjdGlvbixmb3JjZWQsc3RhbmRhcmR9O1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPXNpZ25hbHMuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7T2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsXCJfX2VzTW9kdWxlXCIse3ZhbHVlOnRydWV9KTtleHBvcnRzLnNpZ25hbHNCeU51bWJlcj1leHBvcnRzLnNpZ25hbHNCeU5hbWU9dm9pZCAwO3ZhciBfb3M9cmVxdWlyZShcIm9zXCIpO1xuXG52YXIgX3NpZ25hbHM9cmVxdWlyZShcIi4vc2lnbmFscy5qc1wiKTtcbnZhciBfcmVhbHRpbWU9cmVxdWlyZShcIi4vcmVhbHRpbWUuanNcIik7XG5cblxuXG5jb25zdCBnZXRTaWduYWxzQnlOYW1lPWZ1bmN0aW9uKCl7XG5jb25zdCBzaWduYWxzPSgwLF9zaWduYWxzLmdldFNpZ25hbHMpKCk7XG5yZXR1cm4gc2lnbmFscy5yZWR1Y2UoZ2V0U2lnbmFsQnlOYW1lLHt9KTtcbn07XG5cbmNvbnN0IGdldFNpZ25hbEJ5TmFtZT1mdW5jdGlvbihcbnNpZ25hbEJ5TmFtZU1lbW8sXG57bmFtZSxudW1iZXIsZGVzY3JpcHRpb24sc3VwcG9ydGVkLGFjdGlvbixmb3JjZWQsc3RhbmRhcmR9KVxue1xucmV0dXJue1xuLi4uc2lnbmFsQnlOYW1lTWVtbyxcbltuYW1lXTp7bmFtZSxudW1iZXIsZGVzY3JpcHRpb24sc3VwcG9ydGVkLGFjdGlvbixmb3JjZWQsc3RhbmRhcmR9fTtcblxufTtcblxuY29uc3Qgc2lnbmFsc0J5TmFtZT1nZXRTaWduYWxzQnlOYW1lKCk7ZXhwb3J0cy5zaWduYWxzQnlOYW1lPXNpZ25hbHNCeU5hbWU7XG5cblxuXG5cbmNvbnN0IGdldFNpZ25hbHNCeU51bWJlcj1mdW5jdGlvbigpe1xuY29uc3Qgc2lnbmFscz0oMCxfc2lnbmFscy5nZXRTaWduYWxzKSgpO1xuY29uc3QgbGVuZ3RoPV9yZWFsdGltZS5TSUdSVE1BWCsxO1xuY29uc3Qgc2lnbmFsc0E9QXJyYXkuZnJvbSh7bGVuZ3RofSwodmFsdWUsbnVtYmVyKT0+XG5nZXRTaWduYWxCeU51bWJlcihudW1iZXIsc2lnbmFscykpO1xuXG5yZXR1cm4gT2JqZWN0LmFzc2lnbih7fSwuLi5zaWduYWxzQSk7XG59O1xuXG5jb25zdCBnZXRTaWduYWxCeU51bWJlcj1mdW5jdGlvbihudW1iZXIsc2lnbmFscyl7XG5jb25zdCBzaWduYWw9ZmluZFNpZ25hbEJ5TnVtYmVyKG51bWJlcixzaWduYWxzKTtcblxuaWYoc2lnbmFsPT09dW5kZWZpbmVkKXtcbnJldHVybnt9O1xufVxuXG5jb25zdHtuYW1lLGRlc2NyaXB0aW9uLHN1cHBvcnRlZCxhY3Rpb24sZm9yY2VkLHN0YW5kYXJkfT1zaWduYWw7XG5yZXR1cm57XG5bbnVtYmVyXTp7XG5uYW1lLFxubnVtYmVyLFxuZGVzY3JpcHRpb24sXG5zdXBwb3J0ZWQsXG5hY3Rpb24sXG5mb3JjZWQsXG5zdGFuZGFyZH19O1xuXG5cbn07XG5cblxuXG5jb25zdCBmaW5kU2lnbmFsQnlOdW1iZXI9ZnVuY3Rpb24obnVtYmVyLHNpZ25hbHMpe1xuY29uc3Qgc2lnbmFsPXNpZ25hbHMuZmluZCgoe25hbWV9KT0+X29zLmNvbnN0YW50cy5zaWduYWxzW25hbWVdPT09bnVtYmVyKTtcblxuaWYoc2lnbmFsIT09dW5kZWZpbmVkKXtcbnJldHVybiBzaWduYWw7XG59XG5cbnJldHVybiBzaWduYWxzLmZpbmQoc2lnbmFsQT0+c2lnbmFsQS5udW1iZXI9PT1udW1iZXIpO1xufTtcblxuY29uc3Qgc2lnbmFsc0J5TnVtYmVyPWdldFNpZ25hbHNCeU51bWJlcigpO2V4cG9ydHMuc2lnbmFsc0J5TnVtYmVyPXNpZ25hbHNCeU51bWJlcjtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPW1haW4uanMubWFwIiwiJ3VzZSBzdHJpY3QnO1xuY29uc3Qge3NpZ25hbHNCeU5hbWV9ID0gcmVxdWlyZSgnaHVtYW4tc2lnbmFscycpO1xuXG5jb25zdCBnZXRFcnJvclByZWZpeCA9ICh7dGltZWRPdXQsIHRpbWVvdXQsIGVycm9yQ29kZSwgc2lnbmFsLCBzaWduYWxEZXNjcmlwdGlvbiwgZXhpdENvZGUsIGlzQ2FuY2VsZWR9KSA9PiB7XG5cdGlmICh0aW1lZE91dCkge1xuXHRcdHJldHVybiBgdGltZWQgb3V0IGFmdGVyICR7dGltZW91dH0gbWlsbGlzZWNvbmRzYDtcblx0fVxuXG5cdGlmIChpc0NhbmNlbGVkKSB7XG5cdFx0cmV0dXJuICd3YXMgY2FuY2VsZWQnO1xuXHR9XG5cblx0aWYgKGVycm9yQ29kZSAhPT0gdW5kZWZpbmVkKSB7XG5cdFx0cmV0dXJuIGBmYWlsZWQgd2l0aCAke2Vycm9yQ29kZX1gO1xuXHR9XG5cblx0aWYgKHNpZ25hbCAhPT0gdW5kZWZpbmVkKSB7XG5cdFx0cmV0dXJuIGB3YXMga2lsbGVkIHdpdGggJHtzaWduYWx9ICgke3NpZ25hbERlc2NyaXB0aW9ufSlgO1xuXHR9XG5cblx0aWYgKGV4aXRDb2RlICE9PSB1bmRlZmluZWQpIHtcblx0XHRyZXR1cm4gYGZhaWxlZCB3aXRoIGV4aXQgY29kZSAke2V4aXRDb2RlfWA7XG5cdH1cblxuXHRyZXR1cm4gJ2ZhaWxlZCc7XG59O1xuXG5jb25zdCBtYWtlRXJyb3IgPSAoe1xuXHRzdGRvdXQsXG5cdHN0ZGVycixcblx0YWxsLFxuXHRlcnJvcixcblx0c2lnbmFsLFxuXHRleGl0Q29kZSxcblx0Y29tbWFuZCxcblx0ZXNjYXBlZENvbW1hbmQsXG5cdHRpbWVkT3V0LFxuXHRpc0NhbmNlbGVkLFxuXHRraWxsZWQsXG5cdHBhcnNlZDoge29wdGlvbnM6IHt0aW1lb3V0fX1cbn0pID0+IHtcblx0Ly8gYHNpZ25hbGAgYW5kIGBleGl0Q29kZWAgZW1pdHRlZCBvbiBgc3Bhd25lZC5vbignZXhpdCcpYCBldmVudCBjYW4gYmUgYG51bGxgLlxuXHQvLyBXZSBub3JtYWxpemUgdGhlbSB0byBgdW5kZWZpbmVkYFxuXHRleGl0Q29kZSA9IGV4aXRDb2RlID09PSBudWxsID8gdW5kZWZpbmVkIDogZXhpdENvZGU7XG5cdHNpZ25hbCA9IHNpZ25hbCA9PT0gbnVsbCA/IHVuZGVmaW5lZCA6IHNpZ25hbDtcblx0Y29uc3Qgc2lnbmFsRGVzY3JpcHRpb24gPSBzaWduYWwgPT09IHVuZGVmaW5lZCA/IHVuZGVmaW5lZCA6IHNpZ25hbHNCeU5hbWVbc2lnbmFsXS5kZXNjcmlwdGlvbjtcblxuXHRjb25zdCBlcnJvckNvZGUgPSBlcnJvciAmJiBlcnJvci5jb2RlO1xuXG5cdGNvbnN0IHByZWZpeCA9IGdldEVycm9yUHJlZml4KHt0aW1lZE91dCwgdGltZW91dCwgZXJyb3JDb2RlLCBzaWduYWwsIHNpZ25hbERlc2NyaXB0aW9uLCBleGl0Q29kZSwgaXNDYW5jZWxlZH0pO1xuXHRjb25zdCBleGVjYU1lc3NhZ2UgPSBgQ29tbWFuZCAke3ByZWZpeH06ICR7Y29tbWFuZH1gO1xuXHRjb25zdCBpc0Vycm9yID0gT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKGVycm9yKSA9PT0gJ1tvYmplY3QgRXJyb3JdJztcblx0Y29uc3Qgc2hvcnRNZXNzYWdlID0gaXNFcnJvciA/IGAke2V4ZWNhTWVzc2FnZX1cXG4ke2Vycm9yLm1lc3NhZ2V9YCA6IGV4ZWNhTWVzc2FnZTtcblx0Y29uc3QgbWVzc2FnZSA9IFtzaG9ydE1lc3NhZ2UsIHN0ZGVyciwgc3Rkb3V0XS5maWx0ZXIoQm9vbGVhbikuam9pbignXFxuJyk7XG5cblx0aWYgKGlzRXJyb3IpIHtcblx0XHRlcnJvci5vcmlnaW5hbE1lc3NhZ2UgPSBlcnJvci5tZXNzYWdlO1xuXHRcdGVycm9yLm1lc3NhZ2UgPSBtZXNzYWdlO1xuXHR9IGVsc2Uge1xuXHRcdGVycm9yID0gbmV3IEVycm9yKG1lc3NhZ2UpO1xuXHR9XG5cblx0ZXJyb3Iuc2hvcnRNZXNzYWdlID0gc2hvcnRNZXNzYWdlO1xuXHRlcnJvci5jb21tYW5kID0gY29tbWFuZDtcblx0ZXJyb3IuZXNjYXBlZENvbW1hbmQgPSBlc2NhcGVkQ29tbWFuZDtcblx0ZXJyb3IuZXhpdENvZGUgPSBleGl0Q29kZTtcblx0ZXJyb3Iuc2lnbmFsID0gc2lnbmFsO1xuXHRlcnJvci5zaWduYWxEZXNjcmlwdGlvbiA9IHNpZ25hbERlc2NyaXB0aW9uO1xuXHRlcnJvci5zdGRvdXQgPSBzdGRvdXQ7XG5cdGVycm9yLnN0ZGVyciA9IHN0ZGVycjtcblxuXHRpZiAoYWxsICE9PSB1bmRlZmluZWQpIHtcblx0XHRlcnJvci5hbGwgPSBhbGw7XG5cdH1cblxuXHRpZiAoJ2J1ZmZlcmVkRGF0YScgaW4gZXJyb3IpIHtcblx0XHRkZWxldGUgZXJyb3IuYnVmZmVyZWREYXRhO1xuXHR9XG5cblx0ZXJyb3IuZmFpbGVkID0gdHJ1ZTtcblx0ZXJyb3IudGltZWRPdXQgPSBCb29sZWFuKHRpbWVkT3V0KTtcblx0ZXJyb3IuaXNDYW5jZWxlZCA9IGlzQ2FuY2VsZWQ7XG5cdGVycm9yLmtpbGxlZCA9IGtpbGxlZCAmJiAhdGltZWRPdXQ7XG5cblx0cmV0dXJuIGVycm9yO1xufTtcblxubW9kdWxlLmV4cG9ydHMgPSBtYWtlRXJyb3I7XG4iLCIndXNlIHN0cmljdCc7XG5jb25zdCBhbGlhc2VzID0gWydzdGRpbicsICdzdGRvdXQnLCAnc3RkZXJyJ107XG5cbmNvbnN0IGhhc0FsaWFzID0gb3B0aW9ucyA9PiBhbGlhc2VzLnNvbWUoYWxpYXMgPT4gb3B0aW9uc1thbGlhc10gIT09IHVuZGVmaW5lZCk7XG5cbmNvbnN0IG5vcm1hbGl6ZVN0ZGlvID0gb3B0aW9ucyA9PiB7XG5cdGlmICghb3B0aW9ucykge1xuXHRcdHJldHVybjtcblx0fVxuXG5cdGNvbnN0IHtzdGRpb30gPSBvcHRpb25zO1xuXG5cdGlmIChzdGRpbyA9PT0gdW5kZWZpbmVkKSB7XG5cdFx0cmV0dXJuIGFsaWFzZXMubWFwKGFsaWFzID0+IG9wdGlvbnNbYWxpYXNdKTtcblx0fVxuXG5cdGlmIChoYXNBbGlhcyhvcHRpb25zKSkge1xuXHRcdHRocm93IG5ldyBFcnJvcihgSXQncyBub3QgcG9zc2libGUgdG8gcHJvdmlkZSBcXGBzdGRpb1xcYCBpbiBjb21iaW5hdGlvbiB3aXRoIG9uZSBvZiAke2FsaWFzZXMubWFwKGFsaWFzID0+IGBcXGAke2FsaWFzfVxcYGApLmpvaW4oJywgJyl9YCk7XG5cdH1cblxuXHRpZiAodHlwZW9mIHN0ZGlvID09PSAnc3RyaW5nJykge1xuXHRcdHJldHVybiBzdGRpbztcblx0fVxuXG5cdGlmICghQXJyYXkuaXNBcnJheShzdGRpbykpIHtcblx0XHR0aHJvdyBuZXcgVHlwZUVycm9yKGBFeHBlY3RlZCBcXGBzdGRpb1xcYCB0byBiZSBvZiB0eXBlIFxcYHN0cmluZ1xcYCBvciBcXGBBcnJheVxcYCwgZ290IFxcYCR7dHlwZW9mIHN0ZGlvfVxcYGApO1xuXHR9XG5cblx0Y29uc3QgbGVuZ3RoID0gTWF0aC5tYXgoc3RkaW8ubGVuZ3RoLCBhbGlhc2VzLmxlbmd0aCk7XG5cdHJldHVybiBBcnJheS5mcm9tKHtsZW5ndGh9LCAodmFsdWUsIGluZGV4KSA9PiBzdGRpb1tpbmRleF0pO1xufTtcblxubW9kdWxlLmV4cG9ydHMgPSBub3JtYWxpemVTdGRpbztcblxuLy8gYGlwY2AgaXMgcHVzaGVkIHVubGVzcyBpdCBpcyBhbHJlYWR5IHByZXNlbnRcbm1vZHVsZS5leHBvcnRzLm5vZGUgPSBvcHRpb25zID0+IHtcblx0Y29uc3Qgc3RkaW8gPSBub3JtYWxpemVTdGRpbyhvcHRpb25zKTtcblxuXHRpZiAoc3RkaW8gPT09ICdpcGMnKSB7XG5cdFx0cmV0dXJuICdpcGMnO1xuXHR9XG5cblx0aWYgKHN0ZGlvID09PSB1bmRlZmluZWQgfHwgdHlwZW9mIHN0ZGlvID09PSAnc3RyaW5nJykge1xuXHRcdHJldHVybiBbc3RkaW8sIHN0ZGlvLCBzdGRpbywgJ2lwYyddO1xuXHR9XG5cblx0aWYgKHN0ZGlvLmluY2x1ZGVzKCdpcGMnKSkge1xuXHRcdHJldHVybiBzdGRpbztcblx0fVxuXG5cdHJldHVybiBbLi4uc3RkaW8sICdpcGMnXTtcbn07XG4iLCIvLyBUaGlzIGlzIG5vdCB0aGUgc2V0IG9mIGFsbCBwb3NzaWJsZSBzaWduYWxzLlxuLy9cbi8vIEl0IElTLCBob3dldmVyLCB0aGUgc2V0IG9mIGFsbCBzaWduYWxzIHRoYXQgdHJpZ2dlclxuLy8gYW4gZXhpdCBvbiBlaXRoZXIgTGludXggb3IgQlNEIHN5c3RlbXMuICBMaW51eCBpcyBhXG4vLyBzdXBlcnNldCBvZiB0aGUgc2lnbmFsIG5hbWVzIHN1cHBvcnRlZCBvbiBCU0QsIGFuZFxuLy8gdGhlIHVua25vd24gc2lnbmFscyBqdXN0IGZhaWwgdG8gcmVnaXN0ZXIsIHNvIHdlIGNhblxuLy8gY2F0Y2ggdGhhdCBlYXNpbHkgZW5vdWdoLlxuLy9cbi8vIERvbid0IGJvdGhlciB3aXRoIFNJR0tJTEwuICBJdCdzIHVuY2F0Y2hhYmxlLCB3aGljaFxuLy8gbWVhbnMgdGhhdCB3ZSBjYW4ndCBmaXJlIGFueSBjYWxsYmFja3MgYW55d2F5LlxuLy9cbi8vIElmIGEgdXNlciBkb2VzIGhhcHBlbiB0byByZWdpc3RlciBhIGhhbmRsZXIgb24gYSBub24tXG4vLyBmYXRhbCBzaWduYWwgbGlrZSBTSUdXSU5DSCBvciBzb21ldGhpbmcsIGFuZCB0aGVuXG4vLyBleGl0LCBpdCdsbCBlbmQgdXAgZmlyaW5nIGBwcm9jZXNzLmVtaXQoJ2V4aXQnKWAsIHNvXG4vLyB0aGUgaGFuZGxlciB3aWxsIGJlIGZpcmVkIGFueXdheS5cbi8vXG4vLyBTSUdCVVMsIFNJR0ZQRSwgU0lHU0VHViBhbmQgU0lHSUxMLCB3aGVuIG5vdCByYWlzZWRcbi8vIGFydGlmaWNpYWxseSwgaW5oZXJlbnRseSBsZWF2ZSB0aGUgcHJvY2VzcyBpbiBhXG4vLyBzdGF0ZSBmcm9tIHdoaWNoIGl0IGlzIG5vdCBzYWZlIHRvIHRyeSBhbmQgZW50ZXIgSlNcbi8vIGxpc3RlbmVycy5cbm1vZHVsZS5leHBvcnRzID0gW1xuICAnU0lHQUJSVCcsXG4gICdTSUdBTFJNJyxcbiAgJ1NJR0hVUCcsXG4gICdTSUdJTlQnLFxuICAnU0lHVEVSTSdcbl1cblxuaWYgKHByb2Nlc3MucGxhdGZvcm0gIT09ICd3aW4zMicpIHtcbiAgbW9kdWxlLmV4cG9ydHMucHVzaChcbiAgICAnU0lHVlRBTFJNJyxcbiAgICAnU0lHWENQVScsXG4gICAgJ1NJR1hGU1onLFxuICAgICdTSUdVU1IyJyxcbiAgICAnU0lHVFJBUCcsXG4gICAgJ1NJR1NZUycsXG4gICAgJ1NJR1FVSVQnLFxuICAgICdTSUdJT1QnXG4gICAgLy8gc2hvdWxkIGRldGVjdCBwcm9maWxlciBhbmQgZW5hYmxlL2Rpc2FibGUgYWNjb3JkaW5nbHkuXG4gICAgLy8gc2VlICMyMVxuICAgIC8vICdTSUdQUk9GJ1xuICApXG59XG5cbmlmIChwcm9jZXNzLnBsYXRmb3JtID09PSAnbGludXgnKSB7XG4gIG1vZHVsZS5leHBvcnRzLnB1c2goXG4gICAgJ1NJR0lPJyxcbiAgICAnU0lHUE9MTCcsXG4gICAgJ1NJR1BXUicsXG4gICAgJ1NJR1NUS0ZMVCcsXG4gICAgJ1NJR1VOVVNFRCdcbiAgKVxufVxuIiwiLy8gTm90ZTogc2luY2UgbnljIHVzZXMgdGhpcyBtb2R1bGUgdG8gb3V0cHV0IGNvdmVyYWdlLCBhbnkgbGluZXNcbi8vIHRoYXQgYXJlIGluIHRoZSBkaXJlY3Qgc3luYyBmbG93IG9mIG55YydzIG91dHB1dENvdmVyYWdlIGFyZVxuLy8gaWdub3JlZCwgc2luY2Ugd2UgY2FuIG5ldmVyIGdldCBjb3ZlcmFnZSBmb3IgdGhlbS5cbi8vIGdyYWIgYSByZWZlcmVuY2UgdG8gbm9kZSdzIHJlYWwgcHJvY2VzcyBvYmplY3QgcmlnaHQgYXdheVxudmFyIHByb2Nlc3MgPSBnbG9iYWwucHJvY2Vzc1xuXG5jb25zdCBwcm9jZXNzT2sgPSBmdW5jdGlvbiAocHJvY2Vzcykge1xuICByZXR1cm4gcHJvY2VzcyAmJlxuICAgIHR5cGVvZiBwcm9jZXNzID09PSAnb2JqZWN0JyAmJlxuICAgIHR5cGVvZiBwcm9jZXNzLnJlbW92ZUxpc3RlbmVyID09PSAnZnVuY3Rpb24nICYmXG4gICAgdHlwZW9mIHByb2Nlc3MuZW1pdCA9PT0gJ2Z1bmN0aW9uJyAmJlxuICAgIHR5cGVvZiBwcm9jZXNzLnJlYWxseUV4aXQgPT09ICdmdW5jdGlvbicgJiZcbiAgICB0eXBlb2YgcHJvY2Vzcy5saXN0ZW5lcnMgPT09ICdmdW5jdGlvbicgJiZcbiAgICB0eXBlb2YgcHJvY2Vzcy5raWxsID09PSAnZnVuY3Rpb24nICYmXG4gICAgdHlwZW9mIHByb2Nlc3MucGlkID09PSAnbnVtYmVyJyAmJlxuICAgIHR5cGVvZiBwcm9jZXNzLm9uID09PSAnZnVuY3Rpb24nXG59XG5cbi8vIHNvbWUga2luZCBvZiBub24tbm9kZSBlbnZpcm9ubWVudCwganVzdCBuby1vcFxuLyogaXN0YW5idWwgaWdub3JlIGlmICovXG5pZiAoIXByb2Nlc3NPayhwcm9jZXNzKSkge1xuICBtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gZnVuY3Rpb24gKCkge31cbiAgfVxufSBlbHNlIHtcbiAgdmFyIGFzc2VydCA9IHJlcXVpcmUoJ2Fzc2VydCcpXG4gIHZhciBzaWduYWxzID0gcmVxdWlyZSgnLi9zaWduYWxzLmpzJylcbiAgdmFyIGlzV2luID0gL153aW4vaS50ZXN0KHByb2Nlc3MucGxhdGZvcm0pXG5cbiAgdmFyIEVFID0gcmVxdWlyZSgnZXZlbnRzJylcbiAgLyogaXN0YW5idWwgaWdub3JlIGlmICovXG4gIGlmICh0eXBlb2YgRUUgIT09ICdmdW5jdGlvbicpIHtcbiAgICBFRSA9IEVFLkV2ZW50RW1pdHRlclxuICB9XG5cbiAgdmFyIGVtaXR0ZXJcbiAgaWYgKHByb2Nlc3MuX19zaWduYWxfZXhpdF9lbWl0dGVyX18pIHtcbiAgICBlbWl0dGVyID0gcHJvY2Vzcy5fX3NpZ25hbF9leGl0X2VtaXR0ZXJfX1xuICB9IGVsc2Uge1xuICAgIGVtaXR0ZXIgPSBwcm9jZXNzLl9fc2lnbmFsX2V4aXRfZW1pdHRlcl9fID0gbmV3IEVFKClcbiAgICBlbWl0dGVyLmNvdW50ID0gMFxuICAgIGVtaXR0ZXIuZW1pdHRlZCA9IHt9XG4gIH1cblxuICAvLyBCZWNhdXNlIHRoaXMgZW1pdHRlciBpcyBhIGdsb2JhbCwgd2UgaGF2ZSB0byBjaGVjayB0byBzZWUgaWYgYVxuICAvLyBwcmV2aW91cyB2ZXJzaW9uIG9mIHRoaXMgbGlicmFyeSBmYWlsZWQgdG8gZW5hYmxlIGluZmluaXRlIGxpc3RlbmVycy5cbiAgLy8gSSBrbm93IHdoYXQgeW91J3JlIGFib3V0IHRvIHNheS4gIEJ1dCBsaXRlcmFsbHkgZXZlcnl0aGluZyBhYm91dFxuICAvLyBzaWduYWwtZXhpdCBpcyBhIGNvbXByb21pc2Ugd2l0aCBldmlsLiAgR2V0IHVzZWQgdG8gaXQuXG4gIGlmICghZW1pdHRlci5pbmZpbml0ZSkge1xuICAgIGVtaXR0ZXIuc2V0TWF4TGlzdGVuZXJzKEluZmluaXR5KVxuICAgIGVtaXR0ZXIuaW5maW5pdGUgPSB0cnVlXG4gIH1cblxuICBtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChjYiwgb3B0cykge1xuICAgIC8qIGlzdGFuYnVsIGlnbm9yZSBpZiAqL1xuICAgIGlmICghcHJvY2Vzc09rKGdsb2JhbC5wcm9jZXNzKSkge1xuICAgICAgcmV0dXJuIGZ1bmN0aW9uICgpIHt9XG4gICAgfVxuICAgIGFzc2VydC5lcXVhbCh0eXBlb2YgY2IsICdmdW5jdGlvbicsICdhIGNhbGxiYWNrIG11c3QgYmUgcHJvdmlkZWQgZm9yIGV4aXQgaGFuZGxlcicpXG5cbiAgICBpZiAobG9hZGVkID09PSBmYWxzZSkge1xuICAgICAgbG9hZCgpXG4gICAgfVxuXG4gICAgdmFyIGV2ID0gJ2V4aXQnXG4gICAgaWYgKG9wdHMgJiYgb3B0cy5hbHdheXNMYXN0KSB7XG4gICAgICBldiA9ICdhZnRlcmV4aXQnXG4gICAgfVxuXG4gICAgdmFyIHJlbW92ZSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgIGVtaXR0ZXIucmVtb3ZlTGlzdGVuZXIoZXYsIGNiKVxuICAgICAgaWYgKGVtaXR0ZXIubGlzdGVuZXJzKCdleGl0JykubGVuZ3RoID09PSAwICYmXG4gICAgICAgICAgZW1pdHRlci5saXN0ZW5lcnMoJ2FmdGVyZXhpdCcpLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICB1bmxvYWQoKVxuICAgICAgfVxuICAgIH1cbiAgICBlbWl0dGVyLm9uKGV2LCBjYilcblxuICAgIHJldHVybiByZW1vdmVcbiAgfVxuXG4gIHZhciB1bmxvYWQgPSBmdW5jdGlvbiB1bmxvYWQgKCkge1xuICAgIGlmICghbG9hZGVkIHx8ICFwcm9jZXNzT2soZ2xvYmFsLnByb2Nlc3MpKSB7XG4gICAgICByZXR1cm5cbiAgICB9XG4gICAgbG9hZGVkID0gZmFsc2VcblxuICAgIHNpZ25hbHMuZm9yRWFjaChmdW5jdGlvbiAoc2lnKSB7XG4gICAgICB0cnkge1xuICAgICAgICBwcm9jZXNzLnJlbW92ZUxpc3RlbmVyKHNpZywgc2lnTGlzdGVuZXJzW3NpZ10pXG4gICAgICB9IGNhdGNoIChlcikge31cbiAgICB9KVxuICAgIHByb2Nlc3MuZW1pdCA9IG9yaWdpbmFsUHJvY2Vzc0VtaXRcbiAgICBwcm9jZXNzLnJlYWxseUV4aXQgPSBvcmlnaW5hbFByb2Nlc3NSZWFsbHlFeGl0XG4gICAgZW1pdHRlci5jb3VudCAtPSAxXG4gIH1cbiAgbW9kdWxlLmV4cG9ydHMudW5sb2FkID0gdW5sb2FkXG5cbiAgdmFyIGVtaXQgPSBmdW5jdGlvbiBlbWl0IChldmVudCwgY29kZSwgc2lnbmFsKSB7XG4gICAgLyogaXN0YW5idWwgaWdub3JlIGlmICovXG4gICAgaWYgKGVtaXR0ZXIuZW1pdHRlZFtldmVudF0pIHtcbiAgICAgIHJldHVyblxuICAgIH1cbiAgICBlbWl0dGVyLmVtaXR0ZWRbZXZlbnRdID0gdHJ1ZVxuICAgIGVtaXR0ZXIuZW1pdChldmVudCwgY29kZSwgc2lnbmFsKVxuICB9XG5cbiAgLy8geyA8c2lnbmFsPjogPGxpc3RlbmVyIGZuPiwgLi4uIH1cbiAgdmFyIHNpZ0xpc3RlbmVycyA9IHt9XG4gIHNpZ25hbHMuZm9yRWFjaChmdW5jdGlvbiAoc2lnKSB7XG4gICAgc2lnTGlzdGVuZXJzW3NpZ10gPSBmdW5jdGlvbiBsaXN0ZW5lciAoKSB7XG4gICAgICAvKiBpc3RhbmJ1bCBpZ25vcmUgaWYgKi9cbiAgICAgIGlmICghcHJvY2Vzc09rKGdsb2JhbC5wcm9jZXNzKSkge1xuICAgICAgICByZXR1cm5cbiAgICAgIH1cbiAgICAgIC8vIElmIHRoZXJlIGFyZSBubyBvdGhlciBsaXN0ZW5lcnMsIGFuIGV4aXQgaXMgY29taW5nIVxuICAgICAgLy8gU2ltcGxlc3Qgd2F5OiByZW1vdmUgdXMgYW5kIHRoZW4gcmUtc2VuZCB0aGUgc2lnbmFsLlxuICAgICAgLy8gV2Uga25vdyB0aGF0IHRoaXMgd2lsbCBraWxsIHRoZSBwcm9jZXNzLCBzbyB3ZSBjYW5cbiAgICAgIC8vIHNhZmVseSBlbWl0IG5vdy5cbiAgICAgIHZhciBsaXN0ZW5lcnMgPSBwcm9jZXNzLmxpc3RlbmVycyhzaWcpXG4gICAgICBpZiAobGlzdGVuZXJzLmxlbmd0aCA9PT0gZW1pdHRlci5jb3VudCkge1xuICAgICAgICB1bmxvYWQoKVxuICAgICAgICBlbWl0KCdleGl0JywgbnVsbCwgc2lnKVxuICAgICAgICAvKiBpc3RhbmJ1bCBpZ25vcmUgbmV4dCAqL1xuICAgICAgICBlbWl0KCdhZnRlcmV4aXQnLCBudWxsLCBzaWcpXG4gICAgICAgIC8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0ICovXG4gICAgICAgIGlmIChpc1dpbiAmJiBzaWcgPT09ICdTSUdIVVAnKSB7XG4gICAgICAgICAgLy8gXCJTSUdIVVBcIiB0aHJvd3MgYW4gYEVOT1NZU2AgZXJyb3Igb24gV2luZG93cyxcbiAgICAgICAgICAvLyBzbyB1c2UgYSBzdXBwb3J0ZWQgc2lnbmFsIGluc3RlYWRcbiAgICAgICAgICBzaWcgPSAnU0lHSU5UJ1xuICAgICAgICB9XG4gICAgICAgIC8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0ICovXG4gICAgICAgIHByb2Nlc3Mua2lsbChwcm9jZXNzLnBpZCwgc2lnKVxuICAgICAgfVxuICAgIH1cbiAgfSlcblxuICBtb2R1bGUuZXhwb3J0cy5zaWduYWxzID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiBzaWduYWxzXG4gIH1cblxuICB2YXIgbG9hZGVkID0gZmFsc2VcblxuICB2YXIgbG9hZCA9IGZ1bmN0aW9uIGxvYWQgKCkge1xuICAgIGlmIChsb2FkZWQgfHwgIXByb2Nlc3NPayhnbG9iYWwucHJvY2VzcykpIHtcbiAgICAgIHJldHVyblxuICAgIH1cbiAgICBsb2FkZWQgPSB0cnVlXG5cbiAgICAvLyBUaGlzIGlzIHRoZSBudW1iZXIgb2Ygb25TaWduYWxFeGl0J3MgdGhhdCBhcmUgaW4gcGxheS5cbiAgICAvLyBJdCdzIGltcG9ydGFudCBzbyB0aGF0IHdlIGNhbiBjb3VudCB0aGUgY29ycmVjdCBudW1iZXIgb2ZcbiAgICAvLyBsaXN0ZW5lcnMgb24gc2lnbmFscywgYW5kIGRvbid0IHdhaXQgZm9yIHRoZSBvdGhlciBvbmUgdG9cbiAgICAvLyBoYW5kbGUgaXQgaW5zdGVhZCBvZiB1cy5cbiAgICBlbWl0dGVyLmNvdW50ICs9IDFcblxuICAgIHNpZ25hbHMgPSBzaWduYWxzLmZpbHRlcihmdW5jdGlvbiAoc2lnKSB7XG4gICAgICB0cnkge1xuICAgICAgICBwcm9jZXNzLm9uKHNpZywgc2lnTGlzdGVuZXJzW3NpZ10pXG4gICAgICAgIHJldHVybiB0cnVlXG4gICAgICB9IGNhdGNoIChlcikge1xuICAgICAgICByZXR1cm4gZmFsc2VcbiAgICAgIH1cbiAgICB9KVxuXG4gICAgcHJvY2Vzcy5lbWl0ID0gcHJvY2Vzc0VtaXRcbiAgICBwcm9jZXNzLnJlYWxseUV4aXQgPSBwcm9jZXNzUmVhbGx5RXhpdFxuICB9XG4gIG1vZHVsZS5leHBvcnRzLmxvYWQgPSBsb2FkXG5cbiAgdmFyIG9yaWdpbmFsUHJvY2Vzc1JlYWxseUV4aXQgPSBwcm9jZXNzLnJlYWxseUV4aXRcbiAgdmFyIHByb2Nlc3NSZWFsbHlFeGl0ID0gZnVuY3Rpb24gcHJvY2Vzc1JlYWxseUV4aXQgKGNvZGUpIHtcbiAgICAvKiBpc3RhbmJ1bCBpZ25vcmUgaWYgKi9cbiAgICBpZiAoIXByb2Nlc3NPayhnbG9iYWwucHJvY2VzcykpIHtcbiAgICAgIHJldHVyblxuICAgIH1cbiAgICBwcm9jZXNzLmV4aXRDb2RlID0gY29kZSB8fCAvKiBpc3RhbmJ1bCBpZ25vcmUgbmV4dCAqLyAwXG4gICAgZW1pdCgnZXhpdCcsIHByb2Nlc3MuZXhpdENvZGUsIG51bGwpXG4gICAgLyogaXN0YW5idWwgaWdub3JlIG5leHQgKi9cbiAgICBlbWl0KCdhZnRlcmV4aXQnLCBwcm9jZXNzLmV4aXRDb2RlLCBudWxsKVxuICAgIC8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0ICovXG4gICAgb3JpZ2luYWxQcm9jZXNzUmVhbGx5RXhpdC5jYWxsKHByb2Nlc3MsIHByb2Nlc3MuZXhpdENvZGUpXG4gIH1cblxuICB2YXIgb3JpZ2luYWxQcm9jZXNzRW1pdCA9IHByb2Nlc3MuZW1pdFxuICB2YXIgcHJvY2Vzc0VtaXQgPSBmdW5jdGlvbiBwcm9jZXNzRW1pdCAoZXYsIGFyZykge1xuICAgIGlmIChldiA9PT0gJ2V4aXQnICYmIHByb2Nlc3NPayhnbG9iYWwucHJvY2VzcykpIHtcbiAgICAgIC8qIGlzdGFuYnVsIGlnbm9yZSBlbHNlICovXG4gICAgICBpZiAoYXJnICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgcHJvY2Vzcy5leGl0Q29kZSA9IGFyZ1xuICAgICAgfVxuICAgICAgdmFyIHJldCA9IG9yaWdpbmFsUHJvY2Vzc0VtaXQuYXBwbHkodGhpcywgYXJndW1lbnRzKVxuICAgICAgLyogaXN0YW5idWwgaWdub3JlIG5leHQgKi9cbiAgICAgIGVtaXQoJ2V4aXQnLCBwcm9jZXNzLmV4aXRDb2RlLCBudWxsKVxuICAgICAgLyogaXN0YW5idWwgaWdub3JlIG5leHQgKi9cbiAgICAgIGVtaXQoJ2FmdGVyZXhpdCcsIHByb2Nlc3MuZXhpdENvZGUsIG51bGwpXG4gICAgICAvKiBpc3RhbmJ1bCBpZ25vcmUgbmV4dCAqL1xuICAgICAgcmV0dXJuIHJldFxuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gb3JpZ2luYWxQcm9jZXNzRW1pdC5hcHBseSh0aGlzLCBhcmd1bWVudHMpXG4gICAgfVxuICB9XG59XG4iLCIndXNlIHN0cmljdCc7XG5jb25zdCBvcyA9IHJlcXVpcmUoJ29zJyk7XG5jb25zdCBvbkV4aXQgPSByZXF1aXJlKCdzaWduYWwtZXhpdCcpO1xuXG5jb25zdCBERUZBVUxUX0ZPUkNFX0tJTExfVElNRU9VVCA9IDEwMDAgKiA1O1xuXG4vLyBNb25rZXktcGF0Y2hlcyBgY2hpbGRQcm9jZXNzLmtpbGwoKWAgdG8gYWRkIGBmb3JjZUtpbGxBZnRlclRpbWVvdXRgIGJlaGF2aW9yXG5jb25zdCBzcGF3bmVkS2lsbCA9IChraWxsLCBzaWduYWwgPSAnU0lHVEVSTScsIG9wdGlvbnMgPSB7fSkgPT4ge1xuXHRjb25zdCBraWxsUmVzdWx0ID0ga2lsbChzaWduYWwpO1xuXHRzZXRLaWxsVGltZW91dChraWxsLCBzaWduYWwsIG9wdGlvbnMsIGtpbGxSZXN1bHQpO1xuXHRyZXR1cm4ga2lsbFJlc3VsdDtcbn07XG5cbmNvbnN0IHNldEtpbGxUaW1lb3V0ID0gKGtpbGwsIHNpZ25hbCwgb3B0aW9ucywga2lsbFJlc3VsdCkgPT4ge1xuXHRpZiAoIXNob3VsZEZvcmNlS2lsbChzaWduYWwsIG9wdGlvbnMsIGtpbGxSZXN1bHQpKSB7XG5cdFx0cmV0dXJuO1xuXHR9XG5cblx0Y29uc3QgdGltZW91dCA9IGdldEZvcmNlS2lsbEFmdGVyVGltZW91dChvcHRpb25zKTtcblx0Y29uc3QgdCA9IHNldFRpbWVvdXQoKCkgPT4ge1xuXHRcdGtpbGwoJ1NJR0tJTEwnKTtcblx0fSwgdGltZW91dCk7XG5cblx0Ly8gR3VhcmRlZCBiZWNhdXNlIHRoZXJlJ3Mgbm8gYC51bnJlZigpYCB3aGVuIGBleGVjYWAgaXMgdXNlZCBpbiB0aGUgcmVuZGVyZXJcblx0Ly8gcHJvY2VzcyBpbiBFbGVjdHJvbi4gVGhpcyBjYW5ub3QgYmUgdGVzdGVkIHNpbmNlIHdlIGRvbid0IHJ1biB0ZXN0cyBpblxuXHQvLyBFbGVjdHJvbi5cblx0Ly8gaXN0YW5idWwgaWdub3JlIGVsc2Vcblx0aWYgKHQudW5yZWYpIHtcblx0XHR0LnVucmVmKCk7XG5cdH1cbn07XG5cbmNvbnN0IHNob3VsZEZvcmNlS2lsbCA9IChzaWduYWwsIHtmb3JjZUtpbGxBZnRlclRpbWVvdXR9LCBraWxsUmVzdWx0KSA9PiB7XG5cdHJldHVybiBpc1NpZ3Rlcm0oc2lnbmFsKSAmJiBmb3JjZUtpbGxBZnRlclRpbWVvdXQgIT09IGZhbHNlICYmIGtpbGxSZXN1bHQ7XG59O1xuXG5jb25zdCBpc1NpZ3Rlcm0gPSBzaWduYWwgPT4ge1xuXHRyZXR1cm4gc2lnbmFsID09PSBvcy5jb25zdGFudHMuc2lnbmFscy5TSUdURVJNIHx8XG5cdFx0KHR5cGVvZiBzaWduYWwgPT09ICdzdHJpbmcnICYmIHNpZ25hbC50b1VwcGVyQ2FzZSgpID09PSAnU0lHVEVSTScpO1xufTtcblxuY29uc3QgZ2V0Rm9yY2VLaWxsQWZ0ZXJUaW1lb3V0ID0gKHtmb3JjZUtpbGxBZnRlclRpbWVvdXQgPSB0cnVlfSkgPT4ge1xuXHRpZiAoZm9yY2VLaWxsQWZ0ZXJUaW1lb3V0ID09PSB0cnVlKSB7XG5cdFx0cmV0dXJuIERFRkFVTFRfRk9SQ0VfS0lMTF9USU1FT1VUO1xuXHR9XG5cblx0aWYgKCFOdW1iZXIuaXNGaW5pdGUoZm9yY2VLaWxsQWZ0ZXJUaW1lb3V0KSB8fCBmb3JjZUtpbGxBZnRlclRpbWVvdXQgPCAwKSB7XG5cdFx0dGhyb3cgbmV3IFR5cGVFcnJvcihgRXhwZWN0ZWQgdGhlIFxcYGZvcmNlS2lsbEFmdGVyVGltZW91dFxcYCBvcHRpb24gdG8gYmUgYSBub24tbmVnYXRpdmUgaW50ZWdlciwgZ290IFxcYCR7Zm9yY2VLaWxsQWZ0ZXJUaW1lb3V0fVxcYCAoJHt0eXBlb2YgZm9yY2VLaWxsQWZ0ZXJUaW1lb3V0fSlgKTtcblx0fVxuXG5cdHJldHVybiBmb3JjZUtpbGxBZnRlclRpbWVvdXQ7XG59O1xuXG4vLyBgY2hpbGRQcm9jZXNzLmNhbmNlbCgpYFxuY29uc3Qgc3Bhd25lZENhbmNlbCA9IChzcGF3bmVkLCBjb250ZXh0KSA9PiB7XG5cdGNvbnN0IGtpbGxSZXN1bHQgPSBzcGF3bmVkLmtpbGwoKTtcblxuXHRpZiAoa2lsbFJlc3VsdCkge1xuXHRcdGNvbnRleHQuaXNDYW5jZWxlZCA9IHRydWU7XG5cdH1cbn07XG5cbmNvbnN0IHRpbWVvdXRLaWxsID0gKHNwYXduZWQsIHNpZ25hbCwgcmVqZWN0KSA9PiB7XG5cdHNwYXduZWQua2lsbChzaWduYWwpO1xuXHRyZWplY3QoT2JqZWN0LmFzc2lnbihuZXcgRXJyb3IoJ1RpbWVkIG91dCcpLCB7dGltZWRPdXQ6IHRydWUsIHNpZ25hbH0pKTtcbn07XG5cbi8vIGB0aW1lb3V0YCBvcHRpb24gaGFuZGxpbmdcbmNvbnN0IHNldHVwVGltZW91dCA9IChzcGF3bmVkLCB7dGltZW91dCwga2lsbFNpZ25hbCA9ICdTSUdURVJNJ30sIHNwYXduZWRQcm9taXNlKSA9PiB7XG5cdGlmICh0aW1lb3V0ID09PSAwIHx8IHRpbWVvdXQgPT09IHVuZGVmaW5lZCkge1xuXHRcdHJldHVybiBzcGF3bmVkUHJvbWlzZTtcblx0fVxuXG5cdGxldCB0aW1lb3V0SWQ7XG5cdGNvbnN0IHRpbWVvdXRQcm9taXNlID0gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuXHRcdHRpbWVvdXRJZCA9IHNldFRpbWVvdXQoKCkgPT4ge1xuXHRcdFx0dGltZW91dEtpbGwoc3Bhd25lZCwga2lsbFNpZ25hbCwgcmVqZWN0KTtcblx0XHR9LCB0aW1lb3V0KTtcblx0fSk7XG5cblx0Y29uc3Qgc2FmZVNwYXduZWRQcm9taXNlID0gc3Bhd25lZFByb21pc2UuZmluYWxseSgoKSA9PiB7XG5cdFx0Y2xlYXJUaW1lb3V0KHRpbWVvdXRJZCk7XG5cdH0pO1xuXG5cdHJldHVybiBQcm9taXNlLnJhY2UoW3RpbWVvdXRQcm9taXNlLCBzYWZlU3Bhd25lZFByb21pc2VdKTtcbn07XG5cbmNvbnN0IHZhbGlkYXRlVGltZW91dCA9ICh7dGltZW91dH0pID0+IHtcblx0aWYgKHRpbWVvdXQgIT09IHVuZGVmaW5lZCAmJiAoIU51bWJlci5pc0Zpbml0ZSh0aW1lb3V0KSB8fCB0aW1lb3V0IDwgMCkpIHtcblx0XHR0aHJvdyBuZXcgVHlwZUVycm9yKGBFeHBlY3RlZCB0aGUgXFxgdGltZW91dFxcYCBvcHRpb24gdG8gYmUgYSBub24tbmVnYXRpdmUgaW50ZWdlciwgZ290IFxcYCR7dGltZW91dH1cXGAgKCR7dHlwZW9mIHRpbWVvdXR9KWApO1xuXHR9XG59O1xuXG4vLyBgY2xlYW51cGAgb3B0aW9uIGhhbmRsaW5nXG5jb25zdCBzZXRFeGl0SGFuZGxlciA9IGFzeW5jIChzcGF3bmVkLCB7Y2xlYW51cCwgZGV0YWNoZWR9LCB0aW1lZFByb21pc2UpID0+IHtcblx0aWYgKCFjbGVhbnVwIHx8IGRldGFjaGVkKSB7XG5cdFx0cmV0dXJuIHRpbWVkUHJvbWlzZTtcblx0fVxuXG5cdGNvbnN0IHJlbW92ZUV4aXRIYW5kbGVyID0gb25FeGl0KCgpID0+IHtcblx0XHRzcGF3bmVkLmtpbGwoKTtcblx0fSk7XG5cblx0cmV0dXJuIHRpbWVkUHJvbWlzZS5maW5hbGx5KCgpID0+IHtcblx0XHRyZW1vdmVFeGl0SGFuZGxlcigpO1xuXHR9KTtcbn07XG5cbm1vZHVsZS5leHBvcnRzID0ge1xuXHRzcGF3bmVkS2lsbCxcblx0c3Bhd25lZENhbmNlbCxcblx0c2V0dXBUaW1lb3V0LFxuXHR2YWxpZGF0ZVRpbWVvdXQsXG5cdHNldEV4aXRIYW5kbGVyXG59O1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG5jb25zdCBpc1N0cmVhbSA9IHN0cmVhbSA9PlxuXHRzdHJlYW0gIT09IG51bGwgJiZcblx0dHlwZW9mIHN0cmVhbSA9PT0gJ29iamVjdCcgJiZcblx0dHlwZW9mIHN0cmVhbS5waXBlID09PSAnZnVuY3Rpb24nO1xuXG5pc1N0cmVhbS53cml0YWJsZSA9IHN0cmVhbSA9PlxuXHRpc1N0cmVhbShzdHJlYW0pICYmXG5cdHN0cmVhbS53cml0YWJsZSAhPT0gZmFsc2UgJiZcblx0dHlwZW9mIHN0cmVhbS5fd3JpdGUgPT09ICdmdW5jdGlvbicgJiZcblx0dHlwZW9mIHN0cmVhbS5fd3JpdGFibGVTdGF0ZSA9PT0gJ29iamVjdCc7XG5cbmlzU3RyZWFtLnJlYWRhYmxlID0gc3RyZWFtID0+XG5cdGlzU3RyZWFtKHN0cmVhbSkgJiZcblx0c3RyZWFtLnJlYWRhYmxlICE9PSBmYWxzZSAmJlxuXHR0eXBlb2Ygc3RyZWFtLl9yZWFkID09PSAnZnVuY3Rpb24nICYmXG5cdHR5cGVvZiBzdHJlYW0uX3JlYWRhYmxlU3RhdGUgPT09ICdvYmplY3QnO1xuXG5pc1N0cmVhbS5kdXBsZXggPSBzdHJlYW0gPT5cblx0aXNTdHJlYW0ud3JpdGFibGUoc3RyZWFtKSAmJlxuXHRpc1N0cmVhbS5yZWFkYWJsZShzdHJlYW0pO1xuXG5pc1N0cmVhbS50cmFuc2Zvcm0gPSBzdHJlYW0gPT5cblx0aXNTdHJlYW0uZHVwbGV4KHN0cmVhbSkgJiZcblx0dHlwZW9mIHN0cmVhbS5fdHJhbnNmb3JtID09PSAnZnVuY3Rpb24nO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGlzU3RyZWFtO1xuIiwiJ3VzZSBzdHJpY3QnO1xuY29uc3Qge1Bhc3NUaHJvdWdoOiBQYXNzVGhyb3VnaFN0cmVhbX0gPSByZXF1aXJlKCdzdHJlYW0nKTtcblxubW9kdWxlLmV4cG9ydHMgPSBvcHRpb25zID0+IHtcblx0b3B0aW9ucyA9IHsuLi5vcHRpb25zfTtcblxuXHRjb25zdCB7YXJyYXl9ID0gb3B0aW9ucztcblx0bGV0IHtlbmNvZGluZ30gPSBvcHRpb25zO1xuXHRjb25zdCBpc0J1ZmZlciA9IGVuY29kaW5nID09PSAnYnVmZmVyJztcblx0bGV0IG9iamVjdE1vZGUgPSBmYWxzZTtcblxuXHRpZiAoYXJyYXkpIHtcblx0XHRvYmplY3RNb2RlID0gIShlbmNvZGluZyB8fCBpc0J1ZmZlcik7XG5cdH0gZWxzZSB7XG5cdFx0ZW5jb2RpbmcgPSBlbmNvZGluZyB8fCAndXRmOCc7XG5cdH1cblxuXHRpZiAoaXNCdWZmZXIpIHtcblx0XHRlbmNvZGluZyA9IG51bGw7XG5cdH1cblxuXHRjb25zdCBzdHJlYW0gPSBuZXcgUGFzc1Rocm91Z2hTdHJlYW0oe29iamVjdE1vZGV9KTtcblxuXHRpZiAoZW5jb2RpbmcpIHtcblx0XHRzdHJlYW0uc2V0RW5jb2RpbmcoZW5jb2RpbmcpO1xuXHR9XG5cblx0bGV0IGxlbmd0aCA9IDA7XG5cdGNvbnN0IGNodW5rcyA9IFtdO1xuXG5cdHN0cmVhbS5vbignZGF0YScsIGNodW5rID0+IHtcblx0XHRjaHVua3MucHVzaChjaHVuayk7XG5cblx0XHRpZiAob2JqZWN0TW9kZSkge1xuXHRcdFx0bGVuZ3RoID0gY2h1bmtzLmxlbmd0aDtcblx0XHR9IGVsc2Uge1xuXHRcdFx0bGVuZ3RoICs9IGNodW5rLmxlbmd0aDtcblx0XHR9XG5cdH0pO1xuXG5cdHN0cmVhbS5nZXRCdWZmZXJlZFZhbHVlID0gKCkgPT4ge1xuXHRcdGlmIChhcnJheSkge1xuXHRcdFx0cmV0dXJuIGNodW5rcztcblx0XHR9XG5cblx0XHRyZXR1cm4gaXNCdWZmZXIgPyBCdWZmZXIuY29uY2F0KGNodW5rcywgbGVuZ3RoKSA6IGNodW5rcy5qb2luKCcnKTtcblx0fTtcblxuXHRzdHJlYW0uZ2V0QnVmZmVyZWRMZW5ndGggPSAoKSA9PiBsZW5ndGg7XG5cblx0cmV0dXJuIHN0cmVhbTtcbn07XG4iLCIndXNlIHN0cmljdCc7XG5jb25zdCB7Y29uc3RhbnRzOiBCdWZmZXJDb25zdGFudHN9ID0gcmVxdWlyZSgnYnVmZmVyJyk7XG5jb25zdCBzdHJlYW0gPSByZXF1aXJlKCdzdHJlYW0nKTtcbmNvbnN0IHtwcm9taXNpZnl9ID0gcmVxdWlyZSgndXRpbCcpO1xuY29uc3QgYnVmZmVyU3RyZWFtID0gcmVxdWlyZSgnLi9idWZmZXItc3RyZWFtJyk7XG5cbmNvbnN0IHN0cmVhbVBpcGVsaW5lUHJvbWlzaWZpZWQgPSBwcm9taXNpZnkoc3RyZWFtLnBpcGVsaW5lKTtcblxuY2xhc3MgTWF4QnVmZmVyRXJyb3IgZXh0ZW5kcyBFcnJvciB7XG5cdGNvbnN0cnVjdG9yKCkge1xuXHRcdHN1cGVyKCdtYXhCdWZmZXIgZXhjZWVkZWQnKTtcblx0XHR0aGlzLm5hbWUgPSAnTWF4QnVmZmVyRXJyb3InO1xuXHR9XG59XG5cbmFzeW5jIGZ1bmN0aW9uIGdldFN0cmVhbShpbnB1dFN0cmVhbSwgb3B0aW9ucykge1xuXHRpZiAoIWlucHV0U3RyZWFtKSB7XG5cdFx0dGhyb3cgbmV3IEVycm9yKCdFeHBlY3RlZCBhIHN0cmVhbScpO1xuXHR9XG5cblx0b3B0aW9ucyA9IHtcblx0XHRtYXhCdWZmZXI6IEluZmluaXR5LFxuXHRcdC4uLm9wdGlvbnNcblx0fTtcblxuXHRjb25zdCB7bWF4QnVmZmVyfSA9IG9wdGlvbnM7XG5cdGNvbnN0IHN0cmVhbSA9IGJ1ZmZlclN0cmVhbShvcHRpb25zKTtcblxuXHRhd2FpdCBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG5cdFx0Y29uc3QgcmVqZWN0UHJvbWlzZSA9IGVycm9yID0+IHtcblx0XHRcdC8vIERvbid0IHJldHJpZXZlIGFuIG92ZXJzaXplZCBidWZmZXIuXG5cdFx0XHRpZiAoZXJyb3IgJiYgc3RyZWFtLmdldEJ1ZmZlcmVkTGVuZ3RoKCkgPD0gQnVmZmVyQ29uc3RhbnRzLk1BWF9MRU5HVEgpIHtcblx0XHRcdFx0ZXJyb3IuYnVmZmVyZWREYXRhID0gc3RyZWFtLmdldEJ1ZmZlcmVkVmFsdWUoKTtcblx0XHRcdH1cblxuXHRcdFx0cmVqZWN0KGVycm9yKTtcblx0XHR9O1xuXG5cdFx0KGFzeW5jICgpID0+IHtcblx0XHRcdHRyeSB7XG5cdFx0XHRcdGF3YWl0IHN0cmVhbVBpcGVsaW5lUHJvbWlzaWZpZWQoaW5wdXRTdHJlYW0sIHN0cmVhbSk7XG5cdFx0XHRcdHJlc29sdmUoKTtcblx0XHRcdH0gY2F0Y2ggKGVycm9yKSB7XG5cdFx0XHRcdHJlamVjdFByb21pc2UoZXJyb3IpO1xuXHRcdFx0fVxuXHRcdH0pKCk7XG5cblx0XHRzdHJlYW0ub24oJ2RhdGEnLCAoKSA9PiB7XG5cdFx0XHRpZiAoc3RyZWFtLmdldEJ1ZmZlcmVkTGVuZ3RoKCkgPiBtYXhCdWZmZXIpIHtcblx0XHRcdFx0cmVqZWN0UHJvbWlzZShuZXcgTWF4QnVmZmVyRXJyb3IoKSk7XG5cdFx0XHR9XG5cdFx0fSk7XG5cdH0pO1xuXG5cdHJldHVybiBzdHJlYW0uZ2V0QnVmZmVyZWRWYWx1ZSgpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGdldFN0cmVhbTtcbm1vZHVsZS5leHBvcnRzLmJ1ZmZlciA9IChzdHJlYW0sIG9wdGlvbnMpID0+IGdldFN0cmVhbShzdHJlYW0sIHsuLi5vcHRpb25zLCBlbmNvZGluZzogJ2J1ZmZlcid9KTtcbm1vZHVsZS5leHBvcnRzLmFycmF5ID0gKHN0cmVhbSwgb3B0aW9ucykgPT4gZ2V0U3RyZWFtKHN0cmVhbSwgey4uLm9wdGlvbnMsIGFycmF5OiB0cnVlfSk7XG5tb2R1bGUuZXhwb3J0cy5NYXhCdWZmZXJFcnJvciA9IE1heEJ1ZmZlckVycm9yO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG5jb25zdCB7IFBhc3NUaHJvdWdoIH0gPSByZXF1aXJlKCdzdHJlYW0nKTtcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoLypzdHJlYW1zLi4uKi8pIHtcbiAgdmFyIHNvdXJjZXMgPSBbXVxuICB2YXIgb3V0cHV0ICA9IG5ldyBQYXNzVGhyb3VnaCh7b2JqZWN0TW9kZTogdHJ1ZX0pXG5cbiAgb3V0cHV0LnNldE1heExpc3RlbmVycygwKVxuXG4gIG91dHB1dC5hZGQgPSBhZGRcbiAgb3V0cHV0LmlzRW1wdHkgPSBpc0VtcHR5XG5cbiAgb3V0cHV0Lm9uKCd1bnBpcGUnLCByZW1vdmUpXG5cbiAgQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzKS5mb3JFYWNoKGFkZClcblxuICByZXR1cm4gb3V0cHV0XG5cbiAgZnVuY3Rpb24gYWRkIChzb3VyY2UpIHtcbiAgICBpZiAoQXJyYXkuaXNBcnJheShzb3VyY2UpKSB7XG4gICAgICBzb3VyY2UuZm9yRWFjaChhZGQpXG4gICAgICByZXR1cm4gdGhpc1xuICAgIH1cblxuICAgIHNvdXJjZXMucHVzaChzb3VyY2UpO1xuICAgIHNvdXJjZS5vbmNlKCdlbmQnLCByZW1vdmUuYmluZChudWxsLCBzb3VyY2UpKVxuICAgIHNvdXJjZS5vbmNlKCdlcnJvcicsIG91dHB1dC5lbWl0LmJpbmQob3V0cHV0LCAnZXJyb3InKSlcbiAgICBzb3VyY2UucGlwZShvdXRwdXQsIHtlbmQ6IGZhbHNlfSlcbiAgICByZXR1cm4gdGhpc1xuICB9XG5cbiAgZnVuY3Rpb24gaXNFbXB0eSAoKSB7XG4gICAgcmV0dXJuIHNvdXJjZXMubGVuZ3RoID09IDA7XG4gIH1cblxuICBmdW5jdGlvbiByZW1vdmUgKHNvdXJjZSkge1xuICAgIHNvdXJjZXMgPSBzb3VyY2VzLmZpbHRlcihmdW5jdGlvbiAoaXQpIHsgcmV0dXJuIGl0ICE9PSBzb3VyY2UgfSlcbiAgICBpZiAoIXNvdXJjZXMubGVuZ3RoICYmIG91dHB1dC5yZWFkYWJsZSkgeyBvdXRwdXQuZW5kKCkgfVxuICB9XG59XG4iLCIndXNlIHN0cmljdCc7XG5jb25zdCBpc1N0cmVhbSA9IHJlcXVpcmUoJ2lzLXN0cmVhbScpO1xuY29uc3QgZ2V0U3RyZWFtID0gcmVxdWlyZSgnZ2V0LXN0cmVhbScpO1xuY29uc3QgbWVyZ2VTdHJlYW0gPSByZXF1aXJlKCdtZXJnZS1zdHJlYW0nKTtcblxuLy8gYGlucHV0YCBvcHRpb25cbmNvbnN0IGhhbmRsZUlucHV0ID0gKHNwYXduZWQsIGlucHV0KSA9PiB7XG5cdC8vIENoZWNraW5nIGZvciBzdGRpbiBpcyB3b3JrYXJvdW5kIGZvciBodHRwczovL2dpdGh1Yi5jb20vbm9kZWpzL25vZGUvaXNzdWVzLzI2ODUyXG5cdC8vIEB0b2RvIHJlbW92ZSBgfHwgc3Bhd25lZC5zdGRpbiA9PT0gdW5kZWZpbmVkYCBvbmNlIHdlIGRyb3Agc3VwcG9ydCBmb3IgTm9kZS5qcyA8PTEyLjIuMFxuXHRpZiAoaW5wdXQgPT09IHVuZGVmaW5lZCB8fCBzcGF3bmVkLnN0ZGluID09PSB1bmRlZmluZWQpIHtcblx0XHRyZXR1cm47XG5cdH1cblxuXHRpZiAoaXNTdHJlYW0oaW5wdXQpKSB7XG5cdFx0aW5wdXQucGlwZShzcGF3bmVkLnN0ZGluKTtcblx0fSBlbHNlIHtcblx0XHRzcGF3bmVkLnN0ZGluLmVuZChpbnB1dCk7XG5cdH1cbn07XG5cbi8vIGBhbGxgIGludGVybGVhdmVzIGBzdGRvdXRgIGFuZCBgc3RkZXJyYFxuY29uc3QgbWFrZUFsbFN0cmVhbSA9IChzcGF3bmVkLCB7YWxsfSkgPT4ge1xuXHRpZiAoIWFsbCB8fCAoIXNwYXduZWQuc3Rkb3V0ICYmICFzcGF3bmVkLnN0ZGVycikpIHtcblx0XHRyZXR1cm47XG5cdH1cblxuXHRjb25zdCBtaXhlZCA9IG1lcmdlU3RyZWFtKCk7XG5cblx0aWYgKHNwYXduZWQuc3Rkb3V0KSB7XG5cdFx0bWl4ZWQuYWRkKHNwYXduZWQuc3Rkb3V0KTtcblx0fVxuXG5cdGlmIChzcGF3bmVkLnN0ZGVycikge1xuXHRcdG1peGVkLmFkZChzcGF3bmVkLnN0ZGVycik7XG5cdH1cblxuXHRyZXR1cm4gbWl4ZWQ7XG59O1xuXG4vLyBPbiBmYWlsdXJlLCBgcmVzdWx0LnN0ZG91dHxzdGRlcnJ8YWxsYCBzaG91bGQgY29udGFpbiB0aGUgY3VycmVudGx5IGJ1ZmZlcmVkIHN0cmVhbVxuY29uc3QgZ2V0QnVmZmVyZWREYXRhID0gYXN5bmMgKHN0cmVhbSwgc3RyZWFtUHJvbWlzZSkgPT4ge1xuXHRpZiAoIXN0cmVhbSkge1xuXHRcdHJldHVybjtcblx0fVxuXG5cdHN0cmVhbS5kZXN0cm95KCk7XG5cblx0dHJ5IHtcblx0XHRyZXR1cm4gYXdhaXQgc3RyZWFtUHJvbWlzZTtcblx0fSBjYXRjaCAoZXJyb3IpIHtcblx0XHRyZXR1cm4gZXJyb3IuYnVmZmVyZWREYXRhO1xuXHR9XG59O1xuXG5jb25zdCBnZXRTdHJlYW1Qcm9taXNlID0gKHN0cmVhbSwge2VuY29kaW5nLCBidWZmZXIsIG1heEJ1ZmZlcn0pID0+IHtcblx0aWYgKCFzdHJlYW0gfHwgIWJ1ZmZlcikge1xuXHRcdHJldHVybjtcblx0fVxuXG5cdGlmIChlbmNvZGluZykge1xuXHRcdHJldHVybiBnZXRTdHJlYW0oc3RyZWFtLCB7ZW5jb2RpbmcsIG1heEJ1ZmZlcn0pO1xuXHR9XG5cblx0cmV0dXJuIGdldFN0cmVhbS5idWZmZXIoc3RyZWFtLCB7bWF4QnVmZmVyfSk7XG59O1xuXG4vLyBSZXRyaWV2ZSByZXN1bHQgb2YgY2hpbGQgcHJvY2VzczogZXhpdCBjb2RlLCBzaWduYWwsIGVycm9yLCBzdHJlYW1zIChzdGRvdXQvc3RkZXJyL2FsbClcbmNvbnN0IGdldFNwYXduZWRSZXN1bHQgPSBhc3luYyAoe3N0ZG91dCwgc3RkZXJyLCBhbGx9LCB7ZW5jb2RpbmcsIGJ1ZmZlciwgbWF4QnVmZmVyfSwgcHJvY2Vzc0RvbmUpID0+IHtcblx0Y29uc3Qgc3Rkb3V0UHJvbWlzZSA9IGdldFN0cmVhbVByb21pc2Uoc3Rkb3V0LCB7ZW5jb2RpbmcsIGJ1ZmZlciwgbWF4QnVmZmVyfSk7XG5cdGNvbnN0IHN0ZGVyclByb21pc2UgPSBnZXRTdHJlYW1Qcm9taXNlKHN0ZGVyciwge2VuY29kaW5nLCBidWZmZXIsIG1heEJ1ZmZlcn0pO1xuXHRjb25zdCBhbGxQcm9taXNlID0gZ2V0U3RyZWFtUHJvbWlzZShhbGwsIHtlbmNvZGluZywgYnVmZmVyLCBtYXhCdWZmZXI6IG1heEJ1ZmZlciAqIDJ9KTtcblxuXHR0cnkge1xuXHRcdHJldHVybiBhd2FpdCBQcm9taXNlLmFsbChbcHJvY2Vzc0RvbmUsIHN0ZG91dFByb21pc2UsIHN0ZGVyclByb21pc2UsIGFsbFByb21pc2VdKTtcblx0fSBjYXRjaCAoZXJyb3IpIHtcblx0XHRyZXR1cm4gUHJvbWlzZS5hbGwoW1xuXHRcdFx0e2Vycm9yLCBzaWduYWw6IGVycm9yLnNpZ25hbCwgdGltZWRPdXQ6IGVycm9yLnRpbWVkT3V0fSxcblx0XHRcdGdldEJ1ZmZlcmVkRGF0YShzdGRvdXQsIHN0ZG91dFByb21pc2UpLFxuXHRcdFx0Z2V0QnVmZmVyZWREYXRhKHN0ZGVyciwgc3RkZXJyUHJvbWlzZSksXG5cdFx0XHRnZXRCdWZmZXJlZERhdGEoYWxsLCBhbGxQcm9taXNlKVxuXHRcdF0pO1xuXHR9XG59O1xuXG5jb25zdCB2YWxpZGF0ZUlucHV0U3luYyA9ICh7aW5wdXR9KSA9PiB7XG5cdGlmIChpc1N0cmVhbShpbnB1dCkpIHtcblx0XHR0aHJvdyBuZXcgVHlwZUVycm9yKCdUaGUgYGlucHV0YCBvcHRpb24gY2Fubm90IGJlIGEgc3RyZWFtIGluIHN5bmMgbW9kZScpO1xuXHR9XG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IHtcblx0aGFuZGxlSW5wdXQsXG5cdG1ha2VBbGxTdHJlYW0sXG5cdGdldFNwYXduZWRSZXN1bHQsXG5cdHZhbGlkYXRlSW5wdXRTeW5jXG59O1xuXG4iLCIndXNlIHN0cmljdCc7XG5cbmNvbnN0IG5hdGl2ZVByb21pc2VQcm90b3R5cGUgPSAoYXN5bmMgKCkgPT4ge30pKCkuY29uc3RydWN0b3IucHJvdG90eXBlO1xuY29uc3QgZGVzY3JpcHRvcnMgPSBbJ3RoZW4nLCAnY2F0Y2gnLCAnZmluYWxseSddLm1hcChwcm9wZXJ0eSA9PiBbXG5cdHByb3BlcnR5LFxuXHRSZWZsZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcihuYXRpdmVQcm9taXNlUHJvdG90eXBlLCBwcm9wZXJ0eSlcbl0pO1xuXG4vLyBUaGUgcmV0dXJuIHZhbHVlIGlzIGEgbWl4aW4gb2YgYGNoaWxkUHJvY2Vzc2AgYW5kIGBQcm9taXNlYFxuY29uc3QgbWVyZ2VQcm9taXNlID0gKHNwYXduZWQsIHByb21pc2UpID0+IHtcblx0Zm9yIChjb25zdCBbcHJvcGVydHksIGRlc2NyaXB0b3JdIG9mIGRlc2NyaXB0b3JzKSB7XG5cdFx0Ly8gU3RhcnRpbmcgdGhlIG1haW4gYHByb21pc2VgIGlzIGRlZmVycmVkIHRvIGF2b2lkIGNvbnN1bWluZyBzdHJlYW1zXG5cdFx0Y29uc3QgdmFsdWUgPSB0eXBlb2YgcHJvbWlzZSA9PT0gJ2Z1bmN0aW9uJyA/XG5cdFx0XHQoLi4uYXJncykgPT4gUmVmbGVjdC5hcHBseShkZXNjcmlwdG9yLnZhbHVlLCBwcm9taXNlKCksIGFyZ3MpIDpcblx0XHRcdGRlc2NyaXB0b3IudmFsdWUuYmluZChwcm9taXNlKTtcblxuXHRcdFJlZmxlY3QuZGVmaW5lUHJvcGVydHkoc3Bhd25lZCwgcHJvcGVydHksIHsuLi5kZXNjcmlwdG9yLCB2YWx1ZX0pO1xuXHR9XG5cblx0cmV0dXJuIHNwYXduZWQ7XG59O1xuXG4vLyBVc2UgcHJvbWlzZXMgaW5zdGVhZCBvZiBgY2hpbGRfcHJvY2Vzc2AgZXZlbnRzXG5jb25zdCBnZXRTcGF3bmVkUHJvbWlzZSA9IHNwYXduZWQgPT4ge1xuXHRyZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuXHRcdHNwYXduZWQub24oJ2V4aXQnLCAoZXhpdENvZGUsIHNpZ25hbCkgPT4ge1xuXHRcdFx0cmVzb2x2ZSh7ZXhpdENvZGUsIHNpZ25hbH0pO1xuXHRcdH0pO1xuXG5cdFx0c3Bhd25lZC5vbignZXJyb3InLCBlcnJvciA9PiB7XG5cdFx0XHRyZWplY3QoZXJyb3IpO1xuXHRcdH0pO1xuXG5cdFx0aWYgKHNwYXduZWQuc3RkaW4pIHtcblx0XHRcdHNwYXduZWQuc3RkaW4ub24oJ2Vycm9yJywgZXJyb3IgPT4ge1xuXHRcdFx0XHRyZWplY3QoZXJyb3IpO1xuXHRcdFx0fSk7XG5cdFx0fVxuXHR9KTtcbn07XG5cbm1vZHVsZS5leHBvcnRzID0ge1xuXHRtZXJnZVByb21pc2UsXG5cdGdldFNwYXduZWRQcm9taXNlXG59O1xuXG4iLCIndXNlIHN0cmljdCc7XG5jb25zdCBub3JtYWxpemVBcmdzID0gKGZpbGUsIGFyZ3MgPSBbXSkgPT4ge1xuXHRpZiAoIUFycmF5LmlzQXJyYXkoYXJncykpIHtcblx0XHRyZXR1cm4gW2ZpbGVdO1xuXHR9XG5cblx0cmV0dXJuIFtmaWxlLCAuLi5hcmdzXTtcbn07XG5cbmNvbnN0IE5PX0VTQ0FQRV9SRUdFWFAgPSAvXltcXHcuLV0rJC87XG5jb25zdCBET1VCTEVfUVVPVEVTX1JFR0VYUCA9IC9cIi9nO1xuXG5jb25zdCBlc2NhcGVBcmcgPSBhcmcgPT4ge1xuXHRpZiAodHlwZW9mIGFyZyAhPT0gJ3N0cmluZycgfHwgTk9fRVNDQVBFX1JFR0VYUC50ZXN0KGFyZykpIHtcblx0XHRyZXR1cm4gYXJnO1xuXHR9XG5cblx0cmV0dXJuIGBcIiR7YXJnLnJlcGxhY2UoRE9VQkxFX1FVT1RFU19SRUdFWFAsICdcXFxcXCInKX1cImA7XG59O1xuXG5jb25zdCBqb2luQ29tbWFuZCA9IChmaWxlLCBhcmdzKSA9PiB7XG5cdHJldHVybiBub3JtYWxpemVBcmdzKGZpbGUsIGFyZ3MpLmpvaW4oJyAnKTtcbn07XG5cbmNvbnN0IGdldEVzY2FwZWRDb21tYW5kID0gKGZpbGUsIGFyZ3MpID0+IHtcblx0cmV0dXJuIG5vcm1hbGl6ZUFyZ3MoZmlsZSwgYXJncykubWFwKGFyZyA9PiBlc2NhcGVBcmcoYXJnKSkuam9pbignICcpO1xufTtcblxuY29uc3QgU1BBQ0VTX1JFR0VYUCA9IC8gKy9nO1xuXG4vLyBIYW5kbGUgYGV4ZWNhLmNvbW1hbmQoKWBcbmNvbnN0IHBhcnNlQ29tbWFuZCA9IGNvbW1hbmQgPT4ge1xuXHRjb25zdCB0b2tlbnMgPSBbXTtcblx0Zm9yIChjb25zdCB0b2tlbiBvZiBjb21tYW5kLnRyaW0oKS5zcGxpdChTUEFDRVNfUkVHRVhQKSkge1xuXHRcdC8vIEFsbG93IHNwYWNlcyB0byBiZSBlc2NhcGVkIGJ5IGEgYmFja3NsYXNoIGlmIG5vdCBtZWFudCBhcyBhIGRlbGltaXRlclxuXHRcdGNvbnN0IHByZXZpb3VzVG9rZW4gPSB0b2tlbnNbdG9rZW5zLmxlbmd0aCAtIDFdO1xuXHRcdGlmIChwcmV2aW91c1Rva2VuICYmIHByZXZpb3VzVG9rZW4uZW5kc1dpdGgoJ1xcXFwnKSkge1xuXHRcdFx0Ly8gTWVyZ2UgcHJldmlvdXMgdG9rZW4gd2l0aCBjdXJyZW50IG9uZVxuXHRcdFx0dG9rZW5zW3Rva2Vucy5sZW5ndGggLSAxXSA9IGAke3ByZXZpb3VzVG9rZW4uc2xpY2UoMCwgLTEpfSAke3Rva2VufWA7XG5cdFx0fSBlbHNlIHtcblx0XHRcdHRva2Vucy5wdXNoKHRva2VuKTtcblx0XHR9XG5cdH1cblxuXHRyZXR1cm4gdG9rZW5zO1xufTtcblxubW9kdWxlLmV4cG9ydHMgPSB7XG5cdGpvaW5Db21tYW5kLFxuXHRnZXRFc2NhcGVkQ29tbWFuZCxcblx0cGFyc2VDb21tYW5kXG59O1xuIiwiJ3VzZSBzdHJpY3QnO1xuY29uc3QgcGF0aCA9IHJlcXVpcmUoJ3BhdGgnKTtcbmNvbnN0IGNoaWxkUHJvY2VzcyA9IHJlcXVpcmUoJ2NoaWxkX3Byb2Nlc3MnKTtcbmNvbnN0IGNyb3NzU3Bhd24gPSByZXF1aXJlKCdjcm9zcy1zcGF3bicpO1xuY29uc3Qgc3RyaXBGaW5hbE5ld2xpbmUgPSByZXF1aXJlKCdzdHJpcC1maW5hbC1uZXdsaW5lJyk7XG5jb25zdCBucG1SdW5QYXRoID0gcmVxdWlyZSgnbnBtLXJ1bi1wYXRoJyk7XG5jb25zdCBvbmV0aW1lID0gcmVxdWlyZSgnb25ldGltZScpO1xuY29uc3QgbWFrZUVycm9yID0gcmVxdWlyZSgnLi9saWIvZXJyb3InKTtcbmNvbnN0IG5vcm1hbGl6ZVN0ZGlvID0gcmVxdWlyZSgnLi9saWIvc3RkaW8nKTtcbmNvbnN0IHtzcGF3bmVkS2lsbCwgc3Bhd25lZENhbmNlbCwgc2V0dXBUaW1lb3V0LCB2YWxpZGF0ZVRpbWVvdXQsIHNldEV4aXRIYW5kbGVyfSA9IHJlcXVpcmUoJy4vbGliL2tpbGwnKTtcbmNvbnN0IHtoYW5kbGVJbnB1dCwgZ2V0U3Bhd25lZFJlc3VsdCwgbWFrZUFsbFN0cmVhbSwgdmFsaWRhdGVJbnB1dFN5bmN9ID0gcmVxdWlyZSgnLi9saWIvc3RyZWFtJyk7XG5jb25zdCB7bWVyZ2VQcm9taXNlLCBnZXRTcGF3bmVkUHJvbWlzZX0gPSByZXF1aXJlKCcuL2xpYi9wcm9taXNlJyk7XG5jb25zdCB7am9pbkNvbW1hbmQsIHBhcnNlQ29tbWFuZCwgZ2V0RXNjYXBlZENvbW1hbmR9ID0gcmVxdWlyZSgnLi9saWIvY29tbWFuZCcpO1xuXG5jb25zdCBERUZBVUxUX01BWF9CVUZGRVIgPSAxMDAwICogMTAwMCAqIDEwMDtcblxuY29uc3QgZ2V0RW52ID0gKHtlbnY6IGVudk9wdGlvbiwgZXh0ZW5kRW52LCBwcmVmZXJMb2NhbCwgbG9jYWxEaXIsIGV4ZWNQYXRofSkgPT4ge1xuXHRjb25zdCBlbnYgPSBleHRlbmRFbnYgPyB7Li4ucHJvY2Vzcy5lbnYsIC4uLmVudk9wdGlvbn0gOiBlbnZPcHRpb247XG5cblx0aWYgKHByZWZlckxvY2FsKSB7XG5cdFx0cmV0dXJuIG5wbVJ1blBhdGguZW52KHtlbnYsIGN3ZDogbG9jYWxEaXIsIGV4ZWNQYXRofSk7XG5cdH1cblxuXHRyZXR1cm4gZW52O1xufTtcblxuY29uc3QgaGFuZGxlQXJndW1lbnRzID0gKGZpbGUsIGFyZ3MsIG9wdGlvbnMgPSB7fSkgPT4ge1xuXHRjb25zdCBwYXJzZWQgPSBjcm9zc1NwYXduLl9wYXJzZShmaWxlLCBhcmdzLCBvcHRpb25zKTtcblx0ZmlsZSA9IHBhcnNlZC5jb21tYW5kO1xuXHRhcmdzID0gcGFyc2VkLmFyZ3M7XG5cdG9wdGlvbnMgPSBwYXJzZWQub3B0aW9ucztcblxuXHRvcHRpb25zID0ge1xuXHRcdG1heEJ1ZmZlcjogREVGQVVMVF9NQVhfQlVGRkVSLFxuXHRcdGJ1ZmZlcjogdHJ1ZSxcblx0XHRzdHJpcEZpbmFsTmV3bGluZTogdHJ1ZSxcblx0XHRleHRlbmRFbnY6IHRydWUsXG5cdFx0cHJlZmVyTG9jYWw6IGZhbHNlLFxuXHRcdGxvY2FsRGlyOiBvcHRpb25zLmN3ZCB8fCBwcm9jZXNzLmN3ZCgpLFxuXHRcdGV4ZWNQYXRoOiBwcm9jZXNzLmV4ZWNQYXRoLFxuXHRcdGVuY29kaW5nOiAndXRmOCcsXG5cdFx0cmVqZWN0OiB0cnVlLFxuXHRcdGNsZWFudXA6IHRydWUsXG5cdFx0YWxsOiBmYWxzZSxcblx0XHR3aW5kb3dzSGlkZTogdHJ1ZSxcblx0XHQuLi5vcHRpb25zXG5cdH07XG5cblx0b3B0aW9ucy5lbnYgPSBnZXRFbnYob3B0aW9ucyk7XG5cblx0b3B0aW9ucy5zdGRpbyA9IG5vcm1hbGl6ZVN0ZGlvKG9wdGlvbnMpO1xuXG5cdGlmIChwcm9jZXNzLnBsYXRmb3JtID09PSAnd2luMzInICYmIHBhdGguYmFzZW5hbWUoZmlsZSwgJy5leGUnKSA9PT0gJ2NtZCcpIHtcblx0XHQvLyAjMTE2XG5cdFx0YXJncy51bnNoaWZ0KCcvcScpO1xuXHR9XG5cblx0cmV0dXJuIHtmaWxlLCBhcmdzLCBvcHRpb25zLCBwYXJzZWR9O1xufTtcblxuY29uc3QgaGFuZGxlT3V0cHV0ID0gKG9wdGlvbnMsIHZhbHVlLCBlcnJvcikgPT4ge1xuXHRpZiAodHlwZW9mIHZhbHVlICE9PSAnc3RyaW5nJyAmJiAhQnVmZmVyLmlzQnVmZmVyKHZhbHVlKSkge1xuXHRcdC8vIFdoZW4gYGV4ZWNhLnN5bmMoKWAgZXJyb3JzLCB3ZSBub3JtYWxpemUgaXQgdG8gJycgdG8gbWltaWMgYGV4ZWNhKClgXG5cdFx0cmV0dXJuIGVycm9yID09PSB1bmRlZmluZWQgPyB1bmRlZmluZWQgOiAnJztcblx0fVxuXG5cdGlmIChvcHRpb25zLnN0cmlwRmluYWxOZXdsaW5lKSB7XG5cdFx0cmV0dXJuIHN0cmlwRmluYWxOZXdsaW5lKHZhbHVlKTtcblx0fVxuXG5cdHJldHVybiB2YWx1ZTtcbn07XG5cbmNvbnN0IGV4ZWNhID0gKGZpbGUsIGFyZ3MsIG9wdGlvbnMpID0+IHtcblx0Y29uc3QgcGFyc2VkID0gaGFuZGxlQXJndW1lbnRzKGZpbGUsIGFyZ3MsIG9wdGlvbnMpO1xuXHRjb25zdCBjb21tYW5kID0gam9pbkNvbW1hbmQoZmlsZSwgYXJncyk7XG5cdGNvbnN0IGVzY2FwZWRDb21tYW5kID0gZ2V0RXNjYXBlZENvbW1hbmQoZmlsZSwgYXJncyk7XG5cblx0dmFsaWRhdGVUaW1lb3V0KHBhcnNlZC5vcHRpb25zKTtcblxuXHRsZXQgc3Bhd25lZDtcblx0dHJ5IHtcblx0XHRzcGF3bmVkID0gY2hpbGRQcm9jZXNzLnNwYXduKHBhcnNlZC5maWxlLCBwYXJzZWQuYXJncywgcGFyc2VkLm9wdGlvbnMpO1xuXHR9IGNhdGNoIChlcnJvcikge1xuXHRcdC8vIEVuc3VyZSB0aGUgcmV0dXJuZWQgZXJyb3IgaXMgYWx3YXlzIGJvdGggYSBwcm9taXNlIGFuZCBhIGNoaWxkIHByb2Nlc3Ncblx0XHRjb25zdCBkdW1teVNwYXduZWQgPSBuZXcgY2hpbGRQcm9jZXNzLkNoaWxkUHJvY2VzcygpO1xuXHRcdGNvbnN0IGVycm9yUHJvbWlzZSA9IFByb21pc2UucmVqZWN0KG1ha2VFcnJvcih7XG5cdFx0XHRlcnJvcixcblx0XHRcdHN0ZG91dDogJycsXG5cdFx0XHRzdGRlcnI6ICcnLFxuXHRcdFx0YWxsOiAnJyxcblx0XHRcdGNvbW1hbmQsXG5cdFx0XHRlc2NhcGVkQ29tbWFuZCxcblx0XHRcdHBhcnNlZCxcblx0XHRcdHRpbWVkT3V0OiBmYWxzZSxcblx0XHRcdGlzQ2FuY2VsZWQ6IGZhbHNlLFxuXHRcdFx0a2lsbGVkOiBmYWxzZVxuXHRcdH0pKTtcblx0XHRyZXR1cm4gbWVyZ2VQcm9taXNlKGR1bW15U3Bhd25lZCwgZXJyb3JQcm9taXNlKTtcblx0fVxuXG5cdGNvbnN0IHNwYXduZWRQcm9taXNlID0gZ2V0U3Bhd25lZFByb21pc2Uoc3Bhd25lZCk7XG5cdGNvbnN0IHRpbWVkUHJvbWlzZSA9IHNldHVwVGltZW91dChzcGF3bmVkLCBwYXJzZWQub3B0aW9ucywgc3Bhd25lZFByb21pc2UpO1xuXHRjb25zdCBwcm9jZXNzRG9uZSA9IHNldEV4aXRIYW5kbGVyKHNwYXduZWQsIHBhcnNlZC5vcHRpb25zLCB0aW1lZFByb21pc2UpO1xuXG5cdGNvbnN0IGNvbnRleHQgPSB7aXNDYW5jZWxlZDogZmFsc2V9O1xuXG5cdHNwYXduZWQua2lsbCA9IHNwYXduZWRLaWxsLmJpbmQobnVsbCwgc3Bhd25lZC5raWxsLmJpbmQoc3Bhd25lZCkpO1xuXHRzcGF3bmVkLmNhbmNlbCA9IHNwYXduZWRDYW5jZWwuYmluZChudWxsLCBzcGF3bmVkLCBjb250ZXh0KTtcblxuXHRjb25zdCBoYW5kbGVQcm9taXNlID0gYXN5bmMgKCkgPT4ge1xuXHRcdGNvbnN0IFt7ZXJyb3IsIGV4aXRDb2RlLCBzaWduYWwsIHRpbWVkT3V0fSwgc3Rkb3V0UmVzdWx0LCBzdGRlcnJSZXN1bHQsIGFsbFJlc3VsdF0gPSBhd2FpdCBnZXRTcGF3bmVkUmVzdWx0KHNwYXduZWQsIHBhcnNlZC5vcHRpb25zLCBwcm9jZXNzRG9uZSk7XG5cdFx0Y29uc3Qgc3Rkb3V0ID0gaGFuZGxlT3V0cHV0KHBhcnNlZC5vcHRpb25zLCBzdGRvdXRSZXN1bHQpO1xuXHRcdGNvbnN0IHN0ZGVyciA9IGhhbmRsZU91dHB1dChwYXJzZWQub3B0aW9ucywgc3RkZXJyUmVzdWx0KTtcblx0XHRjb25zdCBhbGwgPSBoYW5kbGVPdXRwdXQocGFyc2VkLm9wdGlvbnMsIGFsbFJlc3VsdCk7XG5cblx0XHRpZiAoZXJyb3IgfHwgZXhpdENvZGUgIT09IDAgfHwgc2lnbmFsICE9PSBudWxsKSB7XG5cdFx0XHRjb25zdCByZXR1cm5lZEVycm9yID0gbWFrZUVycm9yKHtcblx0XHRcdFx0ZXJyb3IsXG5cdFx0XHRcdGV4aXRDb2RlLFxuXHRcdFx0XHRzaWduYWwsXG5cdFx0XHRcdHN0ZG91dCxcblx0XHRcdFx0c3RkZXJyLFxuXHRcdFx0XHRhbGwsXG5cdFx0XHRcdGNvbW1hbmQsXG5cdFx0XHRcdGVzY2FwZWRDb21tYW5kLFxuXHRcdFx0XHRwYXJzZWQsXG5cdFx0XHRcdHRpbWVkT3V0LFxuXHRcdFx0XHRpc0NhbmNlbGVkOiBjb250ZXh0LmlzQ2FuY2VsZWQsXG5cdFx0XHRcdGtpbGxlZDogc3Bhd25lZC5raWxsZWRcblx0XHRcdH0pO1xuXG5cdFx0XHRpZiAoIXBhcnNlZC5vcHRpb25zLnJlamVjdCkge1xuXHRcdFx0XHRyZXR1cm4gcmV0dXJuZWRFcnJvcjtcblx0XHRcdH1cblxuXHRcdFx0dGhyb3cgcmV0dXJuZWRFcnJvcjtcblx0XHR9XG5cblx0XHRyZXR1cm4ge1xuXHRcdFx0Y29tbWFuZCxcblx0XHRcdGVzY2FwZWRDb21tYW5kLFxuXHRcdFx0ZXhpdENvZGU6IDAsXG5cdFx0XHRzdGRvdXQsXG5cdFx0XHRzdGRlcnIsXG5cdFx0XHRhbGwsXG5cdFx0XHRmYWlsZWQ6IGZhbHNlLFxuXHRcdFx0dGltZWRPdXQ6IGZhbHNlLFxuXHRcdFx0aXNDYW5jZWxlZDogZmFsc2UsXG5cdFx0XHRraWxsZWQ6IGZhbHNlXG5cdFx0fTtcblx0fTtcblxuXHRjb25zdCBoYW5kbGVQcm9taXNlT25jZSA9IG9uZXRpbWUoaGFuZGxlUHJvbWlzZSk7XG5cblx0aGFuZGxlSW5wdXQoc3Bhd25lZCwgcGFyc2VkLm9wdGlvbnMuaW5wdXQpO1xuXG5cdHNwYXduZWQuYWxsID0gbWFrZUFsbFN0cmVhbShzcGF3bmVkLCBwYXJzZWQub3B0aW9ucyk7XG5cblx0cmV0dXJuIG1lcmdlUHJvbWlzZShzcGF3bmVkLCBoYW5kbGVQcm9taXNlT25jZSk7XG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IGV4ZWNhO1xuXG5tb2R1bGUuZXhwb3J0cy5zeW5jID0gKGZpbGUsIGFyZ3MsIG9wdGlvbnMpID0+IHtcblx0Y29uc3QgcGFyc2VkID0gaGFuZGxlQXJndW1lbnRzKGZpbGUsIGFyZ3MsIG9wdGlvbnMpO1xuXHRjb25zdCBjb21tYW5kID0gam9pbkNvbW1hbmQoZmlsZSwgYXJncyk7XG5cdGNvbnN0IGVzY2FwZWRDb21tYW5kID0gZ2V0RXNjYXBlZENvbW1hbmQoZmlsZSwgYXJncyk7XG5cblx0dmFsaWRhdGVJbnB1dFN5bmMocGFyc2VkLm9wdGlvbnMpO1xuXG5cdGxldCByZXN1bHQ7XG5cdHRyeSB7XG5cdFx0cmVzdWx0ID0gY2hpbGRQcm9jZXNzLnNwYXduU3luYyhwYXJzZWQuZmlsZSwgcGFyc2VkLmFyZ3MsIHBhcnNlZC5vcHRpb25zKTtcblx0fSBjYXRjaCAoZXJyb3IpIHtcblx0XHR0aHJvdyBtYWtlRXJyb3Ioe1xuXHRcdFx0ZXJyb3IsXG5cdFx0XHRzdGRvdXQ6ICcnLFxuXHRcdFx0c3RkZXJyOiAnJyxcblx0XHRcdGFsbDogJycsXG5cdFx0XHRjb21tYW5kLFxuXHRcdFx0ZXNjYXBlZENvbW1hbmQsXG5cdFx0XHRwYXJzZWQsXG5cdFx0XHR0aW1lZE91dDogZmFsc2UsXG5cdFx0XHRpc0NhbmNlbGVkOiBmYWxzZSxcblx0XHRcdGtpbGxlZDogZmFsc2Vcblx0XHR9KTtcblx0fVxuXG5cdGNvbnN0IHN0ZG91dCA9IGhhbmRsZU91dHB1dChwYXJzZWQub3B0aW9ucywgcmVzdWx0LnN0ZG91dCwgcmVzdWx0LmVycm9yKTtcblx0Y29uc3Qgc3RkZXJyID0gaGFuZGxlT3V0cHV0KHBhcnNlZC5vcHRpb25zLCByZXN1bHQuc3RkZXJyLCByZXN1bHQuZXJyb3IpO1xuXG5cdGlmIChyZXN1bHQuZXJyb3IgfHwgcmVzdWx0LnN0YXR1cyAhPT0gMCB8fCByZXN1bHQuc2lnbmFsICE9PSBudWxsKSB7XG5cdFx0Y29uc3QgZXJyb3IgPSBtYWtlRXJyb3Ioe1xuXHRcdFx0c3Rkb3V0LFxuXHRcdFx0c3RkZXJyLFxuXHRcdFx0ZXJyb3I6IHJlc3VsdC5lcnJvcixcblx0XHRcdHNpZ25hbDogcmVzdWx0LnNpZ25hbCxcblx0XHRcdGV4aXRDb2RlOiByZXN1bHQuc3RhdHVzLFxuXHRcdFx0Y29tbWFuZCxcblx0XHRcdGVzY2FwZWRDb21tYW5kLFxuXHRcdFx0cGFyc2VkLFxuXHRcdFx0dGltZWRPdXQ6IHJlc3VsdC5lcnJvciAmJiByZXN1bHQuZXJyb3IuY29kZSA9PT0gJ0VUSU1FRE9VVCcsXG5cdFx0XHRpc0NhbmNlbGVkOiBmYWxzZSxcblx0XHRcdGtpbGxlZDogcmVzdWx0LnNpZ25hbCAhPT0gbnVsbFxuXHRcdH0pO1xuXG5cdFx0aWYgKCFwYXJzZWQub3B0aW9ucy5yZWplY3QpIHtcblx0XHRcdHJldHVybiBlcnJvcjtcblx0XHR9XG5cblx0XHR0aHJvdyBlcnJvcjtcblx0fVxuXG5cdHJldHVybiB7XG5cdFx0Y29tbWFuZCxcblx0XHRlc2NhcGVkQ29tbWFuZCxcblx0XHRleGl0Q29kZTogMCxcblx0XHRzdGRvdXQsXG5cdFx0c3RkZXJyLFxuXHRcdGZhaWxlZDogZmFsc2UsXG5cdFx0dGltZWRPdXQ6IGZhbHNlLFxuXHRcdGlzQ2FuY2VsZWQ6IGZhbHNlLFxuXHRcdGtpbGxlZDogZmFsc2Vcblx0fTtcbn07XG5cbm1vZHVsZS5leHBvcnRzLmNvbW1hbmQgPSAoY29tbWFuZCwgb3B0aW9ucykgPT4ge1xuXHRjb25zdCBbZmlsZSwgLi4uYXJnc10gPSBwYXJzZUNvbW1hbmQoY29tbWFuZCk7XG5cdHJldHVybiBleGVjYShmaWxlLCBhcmdzLCBvcHRpb25zKTtcbn07XG5cbm1vZHVsZS5leHBvcnRzLmNvbW1hbmRTeW5jID0gKGNvbW1hbmQsIG9wdGlvbnMpID0+IHtcblx0Y29uc3QgW2ZpbGUsIC4uLmFyZ3NdID0gcGFyc2VDb21tYW5kKGNvbW1hbmQpO1xuXHRyZXR1cm4gZXhlY2Euc3luYyhmaWxlLCBhcmdzLCBvcHRpb25zKTtcbn07XG5cbm1vZHVsZS5leHBvcnRzLm5vZGUgPSAoc2NyaXB0UGF0aCwgYXJncywgb3B0aW9ucyA9IHt9KSA9PiB7XG5cdGlmIChhcmdzICYmICFBcnJheS5pc0FycmF5KGFyZ3MpICYmIHR5cGVvZiBhcmdzID09PSAnb2JqZWN0Jykge1xuXHRcdG9wdGlvbnMgPSBhcmdzO1xuXHRcdGFyZ3MgPSBbXTtcblx0fVxuXG5cdGNvbnN0IHN0ZGlvID0gbm9ybWFsaXplU3RkaW8ubm9kZShvcHRpb25zKTtcblx0Y29uc3QgZGVmYXVsdEV4ZWNBcmd2ID0gcHJvY2Vzcy5leGVjQXJndi5maWx0ZXIoYXJnID0+ICFhcmcuc3RhcnRzV2l0aCgnLS1pbnNwZWN0JykpO1xuXG5cdGNvbnN0IHtcblx0XHRub2RlUGF0aCA9IHByb2Nlc3MuZXhlY1BhdGgsXG5cdFx0bm9kZU9wdGlvbnMgPSBkZWZhdWx0RXhlY0FyZ3Zcblx0fSA9IG9wdGlvbnM7XG5cblx0cmV0dXJuIGV4ZWNhKFxuXHRcdG5vZGVQYXRoLFxuXHRcdFtcblx0XHRcdC4uLm5vZGVPcHRpb25zLFxuXHRcdFx0c2NyaXB0UGF0aCxcblx0XHRcdC4uLihBcnJheS5pc0FycmF5KGFyZ3MpID8gYXJncyA6IFtdKVxuXHRcdF0sXG5cdFx0e1xuXHRcdFx0Li4ub3B0aW9ucyxcblx0XHRcdHN0ZGluOiB1bmRlZmluZWQsXG5cdFx0XHRzdGRvdXQ6IHVuZGVmaW5lZCxcblx0XHRcdHN0ZGVycjogdW5kZWZpbmVkLFxuXHRcdFx0c3RkaW8sXG5cdFx0XHRzaGVsbDogZmFsc2Vcblx0XHR9XG5cdCk7XG59O1xuIiwiZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gYW5zaVJlZ2V4KHtvbmx5Rmlyc3QgPSBmYWxzZX0gPSB7fSkge1xuXHRjb25zdCBwYXR0ZXJuID0gW1xuXHQgICAgJ1tcXFxcdTAwMUJcXFxcdTAwOUJdW1tcXFxcXSgpIzs/XSooPzooPzooPzooPzo7Wy1hLXpBLVpcXFxcZFxcXFwvIyYuOj0/JUB+X10rKSp8W2EtekEtWlxcXFxkXSsoPzo7Wy1hLXpBLVpcXFxcZFxcXFwvIyYuOj0/JUB+X10qKSopP1xcXFx1MDAwNyknLFxuXHRcdCcoPzooPzpcXFxcZHsxLDR9KD86O1xcXFxkezAsNH0pKik/W1xcXFxkQS1QUi1UWmNmLW50cXJ5PT48fl0pKSdcblx0XS5qb2luKCd8Jyk7XG5cblx0cmV0dXJuIG5ldyBSZWdFeHAocGF0dGVybiwgb25seUZpcnN0ID8gdW5kZWZpbmVkIDogJ2cnKTtcbn1cbiIsImltcG9ydCBhbnNpUmVnZXggZnJvbSAnYW5zaS1yZWdleCc7XG5cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIHN0cmlwQW5zaShzdHJpbmcpIHtcblx0aWYgKHR5cGVvZiBzdHJpbmcgIT09ICdzdHJpbmcnKSB7XG5cdFx0dGhyb3cgbmV3IFR5cGVFcnJvcihgRXhwZWN0ZWQgYSBcXGBzdHJpbmdcXGAsIGdvdCBcXGAke3R5cGVvZiBzdHJpbmd9XFxgYCk7XG5cdH1cblxuXHRyZXR1cm4gc3RyaW5nLnJlcGxhY2UoYW5zaVJlZ2V4KCksICcnKTtcbn1cbiIsImltcG9ydCBwcm9jZXNzIGZyb20gJ25vZGU6cHJvY2Vzcyc7XG5pbXBvcnQge3VzZXJJbmZvfSBmcm9tICdub2RlOm9zJztcblxuZXhwb3J0IGNvbnN0IGRldGVjdERlZmF1bHRTaGVsbCA9ICgpID0+IHtcblx0Y29uc3Qge2Vudn0gPSBwcm9jZXNzO1xuXG5cdGlmIChwcm9jZXNzLnBsYXRmb3JtID09PSAnd2luMzInKSB7XG5cdFx0cmV0dXJuIGVudi5DT01TUEVDIHx8ICdjbWQuZXhlJztcblx0fVxuXG5cdHRyeSB7XG5cdFx0Y29uc3Qge3NoZWxsfSA9IHVzZXJJbmZvKCk7XG5cdFx0aWYgKHNoZWxsKSB7XG5cdFx0XHRyZXR1cm4gc2hlbGw7XG5cdFx0fVxuXHR9IGNhdGNoIHt9XG5cblx0aWYgKHByb2Nlc3MucGxhdGZvcm0gPT09ICdkYXJ3aW4nKSB7XG5cdFx0cmV0dXJuIGVudi5TSEVMTCB8fCAnL2Jpbi96c2gnO1xuXHR9XG5cblx0cmV0dXJuIGVudi5TSEVMTCB8fCAnL2Jpbi9zaCc7XG59O1xuXG4vLyBTdG9yZXMgZGVmYXVsdCBzaGVsbCB3aGVuIGltcG9ydGVkLlxuY29uc3QgZGVmYXVsdFNoZWxsID0gZGV0ZWN0RGVmYXVsdFNoZWxsKCk7XG5cbmV4cG9ydCBkZWZhdWx0IGRlZmF1bHRTaGVsbDtcbiIsImltcG9ydCBwcm9jZXNzIGZyb20gJ25vZGU6cHJvY2Vzcyc7XG5pbXBvcnQgZXhlY2EgZnJvbSAnZXhlY2EnO1xuaW1wb3J0IHN0cmlwQW5zaSBmcm9tICdzdHJpcC1hbnNpJztcbmltcG9ydCBkZWZhdWx0U2hlbGwgZnJvbSAnZGVmYXVsdC1zaGVsbCc7XG5cbmNvbnN0IGFyZ3MgPSBbXG5cdCctaWxjJyxcblx0J2VjaG8gLW4gXCJfU0hFTExfRU5WX0RFTElNSVRFUl9cIjsgZW52OyBlY2hvIC1uIFwiX1NIRUxMX0VOVl9ERUxJTUlURVJfXCI7IGV4aXQnLFxuXTtcblxuY29uc3QgZW52ID0ge1xuXHQvLyBEaXNhYmxlcyBPaCBNeSBac2ggYXV0by11cGRhdGUgdGhpbmcgdGhhdCBjYW4gYmxvY2sgdGhlIHByb2Nlc3MuXG5cdERJU0FCTEVfQVVUT19VUERBVEU6ICd0cnVlJyxcbn07XG5cbmNvbnN0IHBhcnNlRW52ID0gZW52ID0+IHtcblx0ZW52ID0gZW52LnNwbGl0KCdfU0hFTExfRU5WX0RFTElNSVRFUl8nKVsxXTtcblx0Y29uc3QgcmV0dXJuVmFsdWUgPSB7fTtcblxuXHRmb3IgKGNvbnN0IGxpbmUgb2Ygc3RyaXBBbnNpKGVudikuc3BsaXQoJ1xcbicpLmZpbHRlcihsaW5lID0+IEJvb2xlYW4obGluZSkpKSB7XG5cdFx0Y29uc3QgW2tleSwgLi4udmFsdWVzXSA9IGxpbmUuc3BsaXQoJz0nKTtcblx0XHRyZXR1cm5WYWx1ZVtrZXldID0gdmFsdWVzLmpvaW4oJz0nKTtcblx0fVxuXG5cdHJldHVybiByZXR1cm5WYWx1ZTtcbn07XG5cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBzaGVsbEVudihzaGVsbCkge1xuXHRpZiAocHJvY2Vzcy5wbGF0Zm9ybSA9PT0gJ3dpbjMyJykge1xuXHRcdHJldHVybiBwcm9jZXNzLmVudjtcblx0fVxuXG5cdHRyeSB7XG5cdFx0Y29uc3Qge3N0ZG91dH0gPSBhd2FpdCBleGVjYShzaGVsbCB8fCBkZWZhdWx0U2hlbGwsIGFyZ3MsIHtlbnZ9KTtcblx0XHRyZXR1cm4gcGFyc2VFbnYoc3Rkb3V0KTtcblx0fSBjYXRjaCAoZXJyb3IpIHtcblx0XHRpZiAoc2hlbGwpIHtcblx0XHRcdHRocm93IGVycm9yO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHRyZXR1cm4gcHJvY2Vzcy5lbnY7XG5cdFx0fVxuXHR9XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBzaGVsbEVudlN5bmMoc2hlbGwpIHtcblx0aWYgKHByb2Nlc3MucGxhdGZvcm0gPT09ICd3aW4zMicpIHtcblx0XHRyZXR1cm4gcHJvY2Vzcy5lbnY7XG5cdH1cblxuXHR0cnkge1xuXHRcdGNvbnN0IHtzdGRvdXR9ID0gZXhlY2Euc3luYyhzaGVsbCB8fCBkZWZhdWx0U2hlbGwsIGFyZ3MsIHtlbnZ9KTtcblx0XHRyZXR1cm4gcGFyc2VFbnYoc3Rkb3V0KTtcblx0fSBjYXRjaCAoZXJyb3IpIHtcblx0XHRpZiAoc2hlbGwpIHtcblx0XHRcdHRocm93IGVycm9yO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHRyZXR1cm4gcHJvY2Vzcy5lbnY7XG5cdFx0fVxuXHR9XG59XG4iLCJpbXBvcnQge3NoZWxsRW52LCBzaGVsbEVudlN5bmN9IGZyb20gJ3NoZWxsLWVudic7XG5cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBzaGVsbFBhdGgoKSB7XG5cdGNvbnN0IHtQQVRIfSA9IGF3YWl0IHNoZWxsRW52KCk7XG5cdHJldHVybiBQQVRIO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gc2hlbGxQYXRoU3luYygpIHtcblx0Y29uc3Qge1BBVEh9ID0gc2hlbGxFbnZTeW5jKCk7XG5cdHJldHVybiBQQVRIO1xufVxuIiwiaW1wb3J0IHByb2Nlc3MgZnJvbSAnbm9kZTpwcm9jZXNzJztcbmltcG9ydCB7c2hlbGxQYXRoU3luY30gZnJvbSAnc2hlbGwtcGF0aCc7XG5cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIGZpeFBhdGgoKSB7XG5cdGlmIChwcm9jZXNzLnBsYXRmb3JtID09PSAnd2luMzInKSB7XG5cdFx0cmV0dXJuO1xuXHR9XG5cblx0cHJvY2Vzcy5lbnYuUEFUSCA9IHNoZWxsUGF0aFN5bmMoKSB8fCBbXG5cdFx0Jy4vbm9kZV9tb2R1bGVzLy5iaW4nLFxuXHRcdCcvLm5vZGVicmV3L2N1cnJlbnQvYmluJyxcblx0XHQnL3Vzci9sb2NhbC9iaW4nLFxuXHRcdHByb2Nlc3MuZW52LlBBVEgsXG5cdF0uam9pbignOicpO1xufVxuIiwibW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKCdzdHJlYW0nKTtcbiIsIid1c2Ugc3RyaWN0JztcblxuZnVuY3Rpb24gb3duS2V5cyhvYmplY3QsIGVudW1lcmFibGVPbmx5KSB7IHZhciBrZXlzID0gT2JqZWN0LmtleXMob2JqZWN0KTsgaWYgKE9iamVjdC5nZXRPd25Qcm9wZXJ0eVN5bWJvbHMpIHsgdmFyIHN5bWJvbHMgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlTeW1ib2xzKG9iamVjdCk7IGVudW1lcmFibGVPbmx5ICYmIChzeW1ib2xzID0gc3ltYm9scy5maWx0ZXIoZnVuY3Rpb24gKHN5bSkgeyByZXR1cm4gT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcihvYmplY3QsIHN5bSkuZW51bWVyYWJsZTsgfSkpLCBrZXlzLnB1c2guYXBwbHkoa2V5cywgc3ltYm9scyk7IH0gcmV0dXJuIGtleXM7IH1cbmZ1bmN0aW9uIF9vYmplY3RTcHJlYWQodGFyZ2V0KSB7IGZvciAodmFyIGkgPSAxOyBpIDwgYXJndW1lbnRzLmxlbmd0aDsgaSsrKSB7IHZhciBzb3VyY2UgPSBudWxsICE9IGFyZ3VtZW50c1tpXSA/IGFyZ3VtZW50c1tpXSA6IHt9OyBpICUgMiA/IG93bktleXMoT2JqZWN0KHNvdXJjZSksICEwKS5mb3JFYWNoKGZ1bmN0aW9uIChrZXkpIHsgX2RlZmluZVByb3BlcnR5KHRhcmdldCwga2V5LCBzb3VyY2Vba2V5XSk7IH0pIDogT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcnMgPyBPYmplY3QuZGVmaW5lUHJvcGVydGllcyh0YXJnZXQsIE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3JzKHNvdXJjZSkpIDogb3duS2V5cyhPYmplY3Qoc291cmNlKSkuZm9yRWFjaChmdW5jdGlvbiAoa2V5KSB7IE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0YXJnZXQsIGtleSwgT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcihzb3VyY2UsIGtleSkpOyB9KTsgfSByZXR1cm4gdGFyZ2V0OyB9XG5mdW5jdGlvbiBfZGVmaW5lUHJvcGVydHkob2JqLCBrZXksIHZhbHVlKSB7IGtleSA9IF90b1Byb3BlcnR5S2V5KGtleSk7IGlmIChrZXkgaW4gb2JqKSB7IE9iamVjdC5kZWZpbmVQcm9wZXJ0eShvYmosIGtleSwgeyB2YWx1ZTogdmFsdWUsIGVudW1lcmFibGU6IHRydWUsIGNvbmZpZ3VyYWJsZTogdHJ1ZSwgd3JpdGFibGU6IHRydWUgfSk7IH0gZWxzZSB7IG9ialtrZXldID0gdmFsdWU7IH0gcmV0dXJuIG9iajsgfVxuZnVuY3Rpb24gX2NsYXNzQ2FsbENoZWNrKGluc3RhbmNlLCBDb25zdHJ1Y3RvcikgeyBpZiAoIShpbnN0YW5jZSBpbnN0YW5jZW9mIENvbnN0cnVjdG9yKSkgeyB0aHJvdyBuZXcgVHlwZUVycm9yKFwiQ2Fubm90IGNhbGwgYSBjbGFzcyBhcyBhIGZ1bmN0aW9uXCIpOyB9IH1cbmZ1bmN0aW9uIF9kZWZpbmVQcm9wZXJ0aWVzKHRhcmdldCwgcHJvcHMpIHsgZm9yICh2YXIgaSA9IDA7IGkgPCBwcm9wcy5sZW5ndGg7IGkrKykgeyB2YXIgZGVzY3JpcHRvciA9IHByb3BzW2ldOyBkZXNjcmlwdG9yLmVudW1lcmFibGUgPSBkZXNjcmlwdG9yLmVudW1lcmFibGUgfHwgZmFsc2U7IGRlc2NyaXB0b3IuY29uZmlndXJhYmxlID0gdHJ1ZTsgaWYgKFwidmFsdWVcIiBpbiBkZXNjcmlwdG9yKSBkZXNjcmlwdG9yLndyaXRhYmxlID0gdHJ1ZTsgT2JqZWN0LmRlZmluZVByb3BlcnR5KHRhcmdldCwgX3RvUHJvcGVydHlLZXkoZGVzY3JpcHRvci5rZXkpLCBkZXNjcmlwdG9yKTsgfSB9XG5mdW5jdGlvbiBfY3JlYXRlQ2xhc3MoQ29uc3RydWN0b3IsIHByb3RvUHJvcHMsIHN0YXRpY1Byb3BzKSB7IGlmIChwcm90b1Byb3BzKSBfZGVmaW5lUHJvcGVydGllcyhDb25zdHJ1Y3Rvci5wcm90b3R5cGUsIHByb3RvUHJvcHMpOyBpZiAoc3RhdGljUHJvcHMpIF9kZWZpbmVQcm9wZXJ0aWVzKENvbnN0cnVjdG9yLCBzdGF0aWNQcm9wcyk7IE9iamVjdC5kZWZpbmVQcm9wZXJ0eShDb25zdHJ1Y3RvciwgXCJwcm90b3R5cGVcIiwgeyB3cml0YWJsZTogZmFsc2UgfSk7IHJldHVybiBDb25zdHJ1Y3RvcjsgfVxuZnVuY3Rpb24gX3RvUHJvcGVydHlLZXkoYXJnKSB7IHZhciBrZXkgPSBfdG9QcmltaXRpdmUoYXJnLCBcInN0cmluZ1wiKTsgcmV0dXJuIHR5cGVvZiBrZXkgPT09IFwic3ltYm9sXCIgPyBrZXkgOiBTdHJpbmcoa2V5KTsgfVxuZnVuY3Rpb24gX3RvUHJpbWl0aXZlKGlucHV0LCBoaW50KSB7IGlmICh0eXBlb2YgaW5wdXQgIT09IFwib2JqZWN0XCIgfHwgaW5wdXQgPT09IG51bGwpIHJldHVybiBpbnB1dDsgdmFyIHByaW0gPSBpbnB1dFtTeW1ib2wudG9QcmltaXRpdmVdOyBpZiAocHJpbSAhPT0gdW5kZWZpbmVkKSB7IHZhciByZXMgPSBwcmltLmNhbGwoaW5wdXQsIGhpbnQgfHwgXCJkZWZhdWx0XCIpOyBpZiAodHlwZW9mIHJlcyAhPT0gXCJvYmplY3RcIikgcmV0dXJuIHJlczsgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkBAdG9QcmltaXRpdmUgbXVzdCByZXR1cm4gYSBwcmltaXRpdmUgdmFsdWUuXCIpOyB9IHJldHVybiAoaGludCA9PT0gXCJzdHJpbmdcIiA/IFN0cmluZyA6IE51bWJlcikoaW5wdXQpOyB9XG52YXIgX3JlcXVpcmUgPSByZXF1aXJlKCdidWZmZXInKSxcbiAgQnVmZmVyID0gX3JlcXVpcmUuQnVmZmVyO1xudmFyIF9yZXF1aXJlMiA9IHJlcXVpcmUoJ3V0aWwnKSxcbiAgaW5zcGVjdCA9IF9yZXF1aXJlMi5pbnNwZWN0O1xudmFyIGN1c3RvbSA9IGluc3BlY3QgJiYgaW5zcGVjdC5jdXN0b20gfHwgJ2luc3BlY3QnO1xuZnVuY3Rpb24gY29weUJ1ZmZlcihzcmMsIHRhcmdldCwgb2Zmc2V0KSB7XG4gIEJ1ZmZlci5wcm90b3R5cGUuY29weS5jYWxsKHNyYywgdGFyZ2V0LCBvZmZzZXQpO1xufVxubW9kdWxlLmV4cG9ydHMgPSAvKiNfX1BVUkVfXyovZnVuY3Rpb24gKCkge1xuICBmdW5jdGlvbiBCdWZmZXJMaXN0KCkge1xuICAgIF9jbGFzc0NhbGxDaGVjayh0aGlzLCBCdWZmZXJMaXN0KTtcbiAgICB0aGlzLmhlYWQgPSBudWxsO1xuICAgIHRoaXMudGFpbCA9IG51bGw7XG4gICAgdGhpcy5sZW5ndGggPSAwO1xuICB9XG4gIF9jcmVhdGVDbGFzcyhCdWZmZXJMaXN0LCBbe1xuICAgIGtleTogXCJwdXNoXCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uIHB1c2godikge1xuICAgICAgdmFyIGVudHJ5ID0ge1xuICAgICAgICBkYXRhOiB2LFxuICAgICAgICBuZXh0OiBudWxsXG4gICAgICB9O1xuICAgICAgaWYgKHRoaXMubGVuZ3RoID4gMCkgdGhpcy50YWlsLm5leHQgPSBlbnRyeTtlbHNlIHRoaXMuaGVhZCA9IGVudHJ5O1xuICAgICAgdGhpcy50YWlsID0gZW50cnk7XG4gICAgICArK3RoaXMubGVuZ3RoO1xuICAgIH1cbiAgfSwge1xuICAgIGtleTogXCJ1bnNoaWZ0XCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uIHVuc2hpZnQodikge1xuICAgICAgdmFyIGVudHJ5ID0ge1xuICAgICAgICBkYXRhOiB2LFxuICAgICAgICBuZXh0OiB0aGlzLmhlYWRcbiAgICAgIH07XG4gICAgICBpZiAodGhpcy5sZW5ndGggPT09IDApIHRoaXMudGFpbCA9IGVudHJ5O1xuICAgICAgdGhpcy5oZWFkID0gZW50cnk7XG4gICAgICArK3RoaXMubGVuZ3RoO1xuICAgIH1cbiAgfSwge1xuICAgIGtleTogXCJzaGlmdFwiLFxuICAgIHZhbHVlOiBmdW5jdGlvbiBzaGlmdCgpIHtcbiAgICAgIGlmICh0aGlzLmxlbmd0aCA9PT0gMCkgcmV0dXJuO1xuICAgICAgdmFyIHJldCA9IHRoaXMuaGVhZC5kYXRhO1xuICAgICAgaWYgKHRoaXMubGVuZ3RoID09PSAxKSB0aGlzLmhlYWQgPSB0aGlzLnRhaWwgPSBudWxsO2Vsc2UgdGhpcy5oZWFkID0gdGhpcy5oZWFkLm5leHQ7XG4gICAgICAtLXRoaXMubGVuZ3RoO1xuICAgICAgcmV0dXJuIHJldDtcbiAgICB9XG4gIH0sIHtcbiAgICBrZXk6IFwiY2xlYXJcIixcbiAgICB2YWx1ZTogZnVuY3Rpb24gY2xlYXIoKSB7XG4gICAgICB0aGlzLmhlYWQgPSB0aGlzLnRhaWwgPSBudWxsO1xuICAgICAgdGhpcy5sZW5ndGggPSAwO1xuICAgIH1cbiAgfSwge1xuICAgIGtleTogXCJqb2luXCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uIGpvaW4ocykge1xuICAgICAgaWYgKHRoaXMubGVuZ3RoID09PSAwKSByZXR1cm4gJyc7XG4gICAgICB2YXIgcCA9IHRoaXMuaGVhZDtcbiAgICAgIHZhciByZXQgPSAnJyArIHAuZGF0YTtcbiAgICAgIHdoaWxlIChwID0gcC5uZXh0KSByZXQgKz0gcyArIHAuZGF0YTtcbiAgICAgIHJldHVybiByZXQ7XG4gICAgfVxuICB9LCB7XG4gICAga2V5OiBcImNvbmNhdFwiLFxuICAgIHZhbHVlOiBmdW5jdGlvbiBjb25jYXQobikge1xuICAgICAgaWYgKHRoaXMubGVuZ3RoID09PSAwKSByZXR1cm4gQnVmZmVyLmFsbG9jKDApO1xuICAgICAgdmFyIHJldCA9IEJ1ZmZlci5hbGxvY1Vuc2FmZShuID4+PiAwKTtcbiAgICAgIHZhciBwID0gdGhpcy5oZWFkO1xuICAgICAgdmFyIGkgPSAwO1xuICAgICAgd2hpbGUgKHApIHtcbiAgICAgICAgY29weUJ1ZmZlcihwLmRhdGEsIHJldCwgaSk7XG4gICAgICAgIGkgKz0gcC5kYXRhLmxlbmd0aDtcbiAgICAgICAgcCA9IHAubmV4dDtcbiAgICAgIH1cbiAgICAgIHJldHVybiByZXQ7XG4gICAgfVxuXG4gICAgLy8gQ29uc3VtZXMgYSBzcGVjaWZpZWQgYW1vdW50IG9mIGJ5dGVzIG9yIGNoYXJhY3RlcnMgZnJvbSB0aGUgYnVmZmVyZWQgZGF0YS5cbiAgfSwge1xuICAgIGtleTogXCJjb25zdW1lXCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uIGNvbnN1bWUobiwgaGFzU3RyaW5ncykge1xuICAgICAgdmFyIHJldDtcbiAgICAgIGlmIChuIDwgdGhpcy5oZWFkLmRhdGEubGVuZ3RoKSB7XG4gICAgICAgIC8vIGBzbGljZWAgaXMgdGhlIHNhbWUgZm9yIGJ1ZmZlcnMgYW5kIHN0cmluZ3MuXG4gICAgICAgIHJldCA9IHRoaXMuaGVhZC5kYXRhLnNsaWNlKDAsIG4pO1xuICAgICAgICB0aGlzLmhlYWQuZGF0YSA9IHRoaXMuaGVhZC5kYXRhLnNsaWNlKG4pO1xuICAgICAgfSBlbHNlIGlmIChuID09PSB0aGlzLmhlYWQuZGF0YS5sZW5ndGgpIHtcbiAgICAgICAgLy8gRmlyc3QgY2h1bmsgaXMgYSBwZXJmZWN0IG1hdGNoLlxuICAgICAgICByZXQgPSB0aGlzLnNoaWZ0KCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICAvLyBSZXN1bHQgc3BhbnMgbW9yZSB0aGFuIG9uZSBidWZmZXIuXG4gICAgICAgIHJldCA9IGhhc1N0cmluZ3MgPyB0aGlzLl9nZXRTdHJpbmcobikgOiB0aGlzLl9nZXRCdWZmZXIobik7XG4gICAgICB9XG4gICAgICByZXR1cm4gcmV0O1xuICAgIH1cbiAgfSwge1xuICAgIGtleTogXCJmaXJzdFwiLFxuICAgIHZhbHVlOiBmdW5jdGlvbiBmaXJzdCgpIHtcbiAgICAgIHJldHVybiB0aGlzLmhlYWQuZGF0YTtcbiAgICB9XG5cbiAgICAvLyBDb25zdW1lcyBhIHNwZWNpZmllZCBhbW91bnQgb2YgY2hhcmFjdGVycyBmcm9tIHRoZSBidWZmZXJlZCBkYXRhLlxuICB9LCB7XG4gICAga2V5OiBcIl9nZXRTdHJpbmdcIixcbiAgICB2YWx1ZTogZnVuY3Rpb24gX2dldFN0cmluZyhuKSB7XG4gICAgICB2YXIgcCA9IHRoaXMuaGVhZDtcbiAgICAgIHZhciBjID0gMTtcbiAgICAgIHZhciByZXQgPSBwLmRhdGE7XG4gICAgICBuIC09IHJldC5sZW5ndGg7XG4gICAgICB3aGlsZSAocCA9IHAubmV4dCkge1xuICAgICAgICB2YXIgc3RyID0gcC5kYXRhO1xuICAgICAgICB2YXIgbmIgPSBuID4gc3RyLmxlbmd0aCA/IHN0ci5sZW5ndGggOiBuO1xuICAgICAgICBpZiAobmIgPT09IHN0ci5sZW5ndGgpIHJldCArPSBzdHI7ZWxzZSByZXQgKz0gc3RyLnNsaWNlKDAsIG4pO1xuICAgICAgICBuIC09IG5iO1xuICAgICAgICBpZiAobiA9PT0gMCkge1xuICAgICAgICAgIGlmIChuYiA9PT0gc3RyLmxlbmd0aCkge1xuICAgICAgICAgICAgKytjO1xuICAgICAgICAgICAgaWYgKHAubmV4dCkgdGhpcy5oZWFkID0gcC5uZXh0O2Vsc2UgdGhpcy5oZWFkID0gdGhpcy50YWlsID0gbnVsbDtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5oZWFkID0gcDtcbiAgICAgICAgICAgIHAuZGF0YSA9IHN0ci5zbGljZShuYik7XG4gICAgICAgICAgfVxuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICAgICsrYztcbiAgICAgIH1cbiAgICAgIHRoaXMubGVuZ3RoIC09IGM7XG4gICAgICByZXR1cm4gcmV0O1xuICAgIH1cblxuICAgIC8vIENvbnN1bWVzIGEgc3BlY2lmaWVkIGFtb3VudCBvZiBieXRlcyBmcm9tIHRoZSBidWZmZXJlZCBkYXRhLlxuICB9LCB7XG4gICAga2V5OiBcIl9nZXRCdWZmZXJcIixcbiAgICB2YWx1ZTogZnVuY3Rpb24gX2dldEJ1ZmZlcihuKSB7XG4gICAgICB2YXIgcmV0ID0gQnVmZmVyLmFsbG9jVW5zYWZlKG4pO1xuICAgICAgdmFyIHAgPSB0aGlzLmhlYWQ7XG4gICAgICB2YXIgYyA9IDE7XG4gICAgICBwLmRhdGEuY29weShyZXQpO1xuICAgICAgbiAtPSBwLmRhdGEubGVuZ3RoO1xuICAgICAgd2hpbGUgKHAgPSBwLm5leHQpIHtcbiAgICAgICAgdmFyIGJ1ZiA9IHAuZGF0YTtcbiAgICAgICAgdmFyIG5iID0gbiA+IGJ1Zi5sZW5ndGggPyBidWYubGVuZ3RoIDogbjtcbiAgICAgICAgYnVmLmNvcHkocmV0LCByZXQubGVuZ3RoIC0gbiwgMCwgbmIpO1xuICAgICAgICBuIC09IG5iO1xuICAgICAgICBpZiAobiA9PT0gMCkge1xuICAgICAgICAgIGlmIChuYiA9PT0gYnVmLmxlbmd0aCkge1xuICAgICAgICAgICAgKytjO1xuICAgICAgICAgICAgaWYgKHAubmV4dCkgdGhpcy5oZWFkID0gcC5uZXh0O2Vsc2UgdGhpcy5oZWFkID0gdGhpcy50YWlsID0gbnVsbDtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5oZWFkID0gcDtcbiAgICAgICAgICAgIHAuZGF0YSA9IGJ1Zi5zbGljZShuYik7XG4gICAgICAgICAgfVxuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICAgICsrYztcbiAgICAgIH1cbiAgICAgIHRoaXMubGVuZ3RoIC09IGM7XG4gICAgICByZXR1cm4gcmV0O1xuICAgIH1cblxuICAgIC8vIE1ha2Ugc3VyZSB0aGUgbGlua2VkIGxpc3Qgb25seSBzaG93cyB0aGUgbWluaW1hbCBuZWNlc3NhcnkgaW5mb3JtYXRpb24uXG4gIH0sIHtcbiAgICBrZXk6IGN1c3RvbSxcbiAgICB2YWx1ZTogZnVuY3Rpb24gdmFsdWUoXywgb3B0aW9ucykge1xuICAgICAgcmV0dXJuIGluc3BlY3QodGhpcywgX29iamVjdFNwcmVhZChfb2JqZWN0U3ByZWFkKHt9LCBvcHRpb25zKSwge30sIHtcbiAgICAgICAgLy8gT25seSBpbnNwZWN0IG9uZSBsZXZlbC5cbiAgICAgICAgZGVwdGg6IDAsXG4gICAgICAgIC8vIEl0IHNob3VsZCBub3QgcmVjdXJzZS5cbiAgICAgICAgY3VzdG9tSW5zcGVjdDogZmFsc2VcbiAgICAgIH0pKTtcbiAgICB9XG4gIH1dKTtcbiAgcmV0dXJuIEJ1ZmZlckxpc3Q7XG59KCk7IiwiJ3VzZSBzdHJpY3QnO1xuXG4vLyB1bmRvY3VtZW50ZWQgY2IoKSBBUEksIG5lZWRlZCBmb3IgY29yZSwgbm90IGZvciBwdWJsaWMgQVBJXG5mdW5jdGlvbiBkZXN0cm95KGVyciwgY2IpIHtcbiAgdmFyIF90aGlzID0gdGhpcztcbiAgdmFyIHJlYWRhYmxlRGVzdHJveWVkID0gdGhpcy5fcmVhZGFibGVTdGF0ZSAmJiB0aGlzLl9yZWFkYWJsZVN0YXRlLmRlc3Ryb3llZDtcbiAgdmFyIHdyaXRhYmxlRGVzdHJveWVkID0gdGhpcy5fd3JpdGFibGVTdGF0ZSAmJiB0aGlzLl93cml0YWJsZVN0YXRlLmRlc3Ryb3llZDtcbiAgaWYgKHJlYWRhYmxlRGVzdHJveWVkIHx8IHdyaXRhYmxlRGVzdHJveWVkKSB7XG4gICAgaWYgKGNiKSB7XG4gICAgICBjYihlcnIpO1xuICAgIH0gZWxzZSBpZiAoZXJyKSB7XG4gICAgICBpZiAoIXRoaXMuX3dyaXRhYmxlU3RhdGUpIHtcbiAgICAgICAgcHJvY2Vzcy5uZXh0VGljayhlbWl0RXJyb3JOVCwgdGhpcywgZXJyKTtcbiAgICAgIH0gZWxzZSBpZiAoIXRoaXMuX3dyaXRhYmxlU3RhdGUuZXJyb3JFbWl0dGVkKSB7XG4gICAgICAgIHRoaXMuX3dyaXRhYmxlU3RhdGUuZXJyb3JFbWl0dGVkID0gdHJ1ZTtcbiAgICAgICAgcHJvY2Vzcy5uZXh0VGljayhlbWl0RXJyb3JOVCwgdGhpcywgZXJyKTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICAvLyB3ZSBzZXQgZGVzdHJveWVkIHRvIHRydWUgYmVmb3JlIGZpcmluZyBlcnJvciBjYWxsYmFja3MgaW4gb3JkZXJcbiAgLy8gdG8gbWFrZSBpdCByZS1lbnRyYW5jZSBzYWZlIGluIGNhc2UgZGVzdHJveSgpIGlzIGNhbGxlZCB3aXRoaW4gY2FsbGJhY2tzXG5cbiAgaWYgKHRoaXMuX3JlYWRhYmxlU3RhdGUpIHtcbiAgICB0aGlzLl9yZWFkYWJsZVN0YXRlLmRlc3Ryb3llZCA9IHRydWU7XG4gIH1cblxuICAvLyBpZiB0aGlzIGlzIGEgZHVwbGV4IHN0cmVhbSBtYXJrIHRoZSB3cml0YWJsZSBwYXJ0IGFzIGRlc3Ryb3llZCBhcyB3ZWxsXG4gIGlmICh0aGlzLl93cml0YWJsZVN0YXRlKSB7XG4gICAgdGhpcy5fd3JpdGFibGVTdGF0ZS5kZXN0cm95ZWQgPSB0cnVlO1xuICB9XG4gIHRoaXMuX2Rlc3Ryb3koZXJyIHx8IG51bGwsIGZ1bmN0aW9uIChlcnIpIHtcbiAgICBpZiAoIWNiICYmIGVycikge1xuICAgICAgaWYgKCFfdGhpcy5fd3JpdGFibGVTdGF0ZSkge1xuICAgICAgICBwcm9jZXNzLm5leHRUaWNrKGVtaXRFcnJvckFuZENsb3NlTlQsIF90aGlzLCBlcnIpO1xuICAgICAgfSBlbHNlIGlmICghX3RoaXMuX3dyaXRhYmxlU3RhdGUuZXJyb3JFbWl0dGVkKSB7XG4gICAgICAgIF90aGlzLl93cml0YWJsZVN0YXRlLmVycm9yRW1pdHRlZCA9IHRydWU7XG4gICAgICAgIHByb2Nlc3MubmV4dFRpY2soZW1pdEVycm9yQW5kQ2xvc2VOVCwgX3RoaXMsIGVycik7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBwcm9jZXNzLm5leHRUaWNrKGVtaXRDbG9zZU5ULCBfdGhpcyk7XG4gICAgICB9XG4gICAgfSBlbHNlIGlmIChjYikge1xuICAgICAgcHJvY2Vzcy5uZXh0VGljayhlbWl0Q2xvc2VOVCwgX3RoaXMpO1xuICAgICAgY2IoZXJyKTtcbiAgICB9IGVsc2Uge1xuICAgICAgcHJvY2Vzcy5uZXh0VGljayhlbWl0Q2xvc2VOVCwgX3RoaXMpO1xuICAgIH1cbiAgfSk7XG4gIHJldHVybiB0aGlzO1xufVxuZnVuY3Rpb24gZW1pdEVycm9yQW5kQ2xvc2VOVChzZWxmLCBlcnIpIHtcbiAgZW1pdEVycm9yTlQoc2VsZiwgZXJyKTtcbiAgZW1pdENsb3NlTlQoc2VsZik7XG59XG5mdW5jdGlvbiBlbWl0Q2xvc2VOVChzZWxmKSB7XG4gIGlmIChzZWxmLl93cml0YWJsZVN0YXRlICYmICFzZWxmLl93cml0YWJsZVN0YXRlLmVtaXRDbG9zZSkgcmV0dXJuO1xuICBpZiAoc2VsZi5fcmVhZGFibGVTdGF0ZSAmJiAhc2VsZi5fcmVhZGFibGVTdGF0ZS5lbWl0Q2xvc2UpIHJldHVybjtcbiAgc2VsZi5lbWl0KCdjbG9zZScpO1xufVxuZnVuY3Rpb24gdW5kZXN0cm95KCkge1xuICBpZiAodGhpcy5fcmVhZGFibGVTdGF0ZSkge1xuICAgIHRoaXMuX3JlYWRhYmxlU3RhdGUuZGVzdHJveWVkID0gZmFsc2U7XG4gICAgdGhpcy5fcmVhZGFibGVTdGF0ZS5yZWFkaW5nID0gZmFsc2U7XG4gICAgdGhpcy5fcmVhZGFibGVTdGF0ZS5lbmRlZCA9IGZhbHNlO1xuICAgIHRoaXMuX3JlYWRhYmxlU3RhdGUuZW5kRW1pdHRlZCA9IGZhbHNlO1xuICB9XG4gIGlmICh0aGlzLl93cml0YWJsZVN0YXRlKSB7XG4gICAgdGhpcy5fd3JpdGFibGVTdGF0ZS5kZXN0cm95ZWQgPSBmYWxzZTtcbiAgICB0aGlzLl93cml0YWJsZVN0YXRlLmVuZGVkID0gZmFsc2U7XG4gICAgdGhpcy5fd3JpdGFibGVTdGF0ZS5lbmRpbmcgPSBmYWxzZTtcbiAgICB0aGlzLl93cml0YWJsZVN0YXRlLmZpbmFsQ2FsbGVkID0gZmFsc2U7XG4gICAgdGhpcy5fd3JpdGFibGVTdGF0ZS5wcmVmaW5pc2hlZCA9IGZhbHNlO1xuICAgIHRoaXMuX3dyaXRhYmxlU3RhdGUuZmluaXNoZWQgPSBmYWxzZTtcbiAgICB0aGlzLl93cml0YWJsZVN0YXRlLmVycm9yRW1pdHRlZCA9IGZhbHNlO1xuICB9XG59XG5mdW5jdGlvbiBlbWl0RXJyb3JOVChzZWxmLCBlcnIpIHtcbiAgc2VsZi5lbWl0KCdlcnJvcicsIGVycik7XG59XG5mdW5jdGlvbiBlcnJvck9yRGVzdHJveShzdHJlYW0sIGVycikge1xuICAvLyBXZSBoYXZlIHRlc3RzIHRoYXQgcmVseSBvbiBlcnJvcnMgYmVpbmcgZW1pdHRlZFxuICAvLyBpbiB0aGUgc2FtZSB0aWNrLCBzbyBjaGFuZ2luZyB0aGlzIGlzIHNlbXZlciBtYWpvci5cbiAgLy8gRm9yIG5vdyB3aGVuIHlvdSBvcHQtaW4gdG8gYXV0b0Rlc3Ryb3kgd2UgYWxsb3dcbiAgLy8gdGhlIGVycm9yIHRvIGJlIGVtaXR0ZWQgbmV4dFRpY2suIEluIGEgZnV0dXJlXG4gIC8vIHNlbXZlciBtYWpvciB1cGRhdGUgd2Ugc2hvdWxkIGNoYW5nZSB0aGUgZGVmYXVsdCB0byB0aGlzLlxuXG4gIHZhciByU3RhdGUgPSBzdHJlYW0uX3JlYWRhYmxlU3RhdGU7XG4gIHZhciB3U3RhdGUgPSBzdHJlYW0uX3dyaXRhYmxlU3RhdGU7XG4gIGlmIChyU3RhdGUgJiYgclN0YXRlLmF1dG9EZXN0cm95IHx8IHdTdGF0ZSAmJiB3U3RhdGUuYXV0b0Rlc3Ryb3kpIHN0cmVhbS5kZXN0cm95KGVycik7ZWxzZSBzdHJlYW0uZW1pdCgnZXJyb3InLCBlcnIpO1xufVxubW9kdWxlLmV4cG9ydHMgPSB7XG4gIGRlc3Ryb3k6IGRlc3Ryb3ksXG4gIHVuZGVzdHJveTogdW5kZXN0cm95LFxuICBlcnJvck9yRGVzdHJveTogZXJyb3JPckRlc3Ryb3lcbn07IiwiJ3VzZSBzdHJpY3QnO1xuXG5jb25zdCBjb2RlcyA9IHt9O1xuXG5mdW5jdGlvbiBjcmVhdGVFcnJvclR5cGUoY29kZSwgbWVzc2FnZSwgQmFzZSkge1xuICBpZiAoIUJhc2UpIHtcbiAgICBCYXNlID0gRXJyb3JcbiAgfVxuXG4gIGZ1bmN0aW9uIGdldE1lc3NhZ2UgKGFyZzEsIGFyZzIsIGFyZzMpIHtcbiAgICBpZiAodHlwZW9mIG1lc3NhZ2UgPT09ICdzdHJpbmcnKSB7XG4gICAgICByZXR1cm4gbWVzc2FnZVxuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gbWVzc2FnZShhcmcxLCBhcmcyLCBhcmczKVxuICAgIH1cbiAgfVxuXG4gIGNsYXNzIE5vZGVFcnJvciBleHRlbmRzIEJhc2Uge1xuICAgIGNvbnN0cnVjdG9yIChhcmcxLCBhcmcyLCBhcmczKSB7XG4gICAgICBzdXBlcihnZXRNZXNzYWdlKGFyZzEsIGFyZzIsIGFyZzMpKTtcbiAgICB9XG4gIH1cblxuICBOb2RlRXJyb3IucHJvdG90eXBlLm5hbWUgPSBCYXNlLm5hbWU7XG4gIE5vZGVFcnJvci5wcm90b3R5cGUuY29kZSA9IGNvZGU7XG5cbiAgY29kZXNbY29kZV0gPSBOb2RlRXJyb3I7XG59XG5cbi8vIGh0dHBzOi8vZ2l0aHViLmNvbS9ub2RlanMvbm9kZS9ibG9iL3YxMC44LjAvbGliL2ludGVybmFsL2Vycm9ycy5qc1xuZnVuY3Rpb24gb25lT2YoZXhwZWN0ZWQsIHRoaW5nKSB7XG4gIGlmIChBcnJheS5pc0FycmF5KGV4cGVjdGVkKSkge1xuICAgIGNvbnN0IGxlbiA9IGV4cGVjdGVkLmxlbmd0aDtcbiAgICBleHBlY3RlZCA9IGV4cGVjdGVkLm1hcCgoaSkgPT4gU3RyaW5nKGkpKTtcbiAgICBpZiAobGVuID4gMikge1xuICAgICAgcmV0dXJuIGBvbmUgb2YgJHt0aGluZ30gJHtleHBlY3RlZC5zbGljZSgwLCBsZW4gLSAxKS5qb2luKCcsICcpfSwgb3IgYCArXG4gICAgICAgICAgICAgZXhwZWN0ZWRbbGVuIC0gMV07XG4gICAgfSBlbHNlIGlmIChsZW4gPT09IDIpIHtcbiAgICAgIHJldHVybiBgb25lIG9mICR7dGhpbmd9ICR7ZXhwZWN0ZWRbMF19IG9yICR7ZXhwZWN0ZWRbMV19YDtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIGBvZiAke3RoaW5nfSAke2V4cGVjdGVkWzBdfWA7XG4gICAgfVxuICB9IGVsc2Uge1xuICAgIHJldHVybiBgb2YgJHt0aGluZ30gJHtTdHJpbmcoZXhwZWN0ZWQpfWA7XG4gIH1cbn1cblxuLy8gaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvSmF2YVNjcmlwdC9SZWZlcmVuY2UvR2xvYmFsX09iamVjdHMvU3RyaW5nL3N0YXJ0c1dpdGhcbmZ1bmN0aW9uIHN0YXJ0c1dpdGgoc3RyLCBzZWFyY2gsIHBvcykge1xuXHRyZXR1cm4gc3RyLnN1YnN0cighcG9zIHx8IHBvcyA8IDAgPyAwIDogK3Bvcywgc2VhcmNoLmxlbmd0aCkgPT09IHNlYXJjaDtcbn1cblxuLy8gaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvSmF2YVNjcmlwdC9SZWZlcmVuY2UvR2xvYmFsX09iamVjdHMvU3RyaW5nL2VuZHNXaXRoXG5mdW5jdGlvbiBlbmRzV2l0aChzdHIsIHNlYXJjaCwgdGhpc19sZW4pIHtcblx0aWYgKHRoaXNfbGVuID09PSB1bmRlZmluZWQgfHwgdGhpc19sZW4gPiBzdHIubGVuZ3RoKSB7XG5cdFx0dGhpc19sZW4gPSBzdHIubGVuZ3RoO1xuXHR9XG5cdHJldHVybiBzdHIuc3Vic3RyaW5nKHRoaXNfbGVuIC0gc2VhcmNoLmxlbmd0aCwgdGhpc19sZW4pID09PSBzZWFyY2g7XG59XG5cbi8vIGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0phdmFTY3JpcHQvUmVmZXJlbmNlL0dsb2JhbF9PYmplY3RzL1N0cmluZy9pbmNsdWRlc1xuZnVuY3Rpb24gaW5jbHVkZXMoc3RyLCBzZWFyY2gsIHN0YXJ0KSB7XG4gIGlmICh0eXBlb2Ygc3RhcnQgIT09ICdudW1iZXInKSB7XG4gICAgc3RhcnQgPSAwO1xuICB9XG5cbiAgaWYgKHN0YXJ0ICsgc2VhcmNoLmxlbmd0aCA+IHN0ci5sZW5ndGgpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIHN0ci5pbmRleE9mKHNlYXJjaCwgc3RhcnQpICE9PSAtMTtcbiAgfVxufVxuXG5jcmVhdGVFcnJvclR5cGUoJ0VSUl9JTlZBTElEX09QVF9WQUxVRScsIGZ1bmN0aW9uIChuYW1lLCB2YWx1ZSkge1xuICByZXR1cm4gJ1RoZSB2YWx1ZSBcIicgKyB2YWx1ZSArICdcIiBpcyBpbnZhbGlkIGZvciBvcHRpb24gXCInICsgbmFtZSArICdcIidcbn0sIFR5cGVFcnJvcik7XG5jcmVhdGVFcnJvclR5cGUoJ0VSUl9JTlZBTElEX0FSR19UWVBFJywgZnVuY3Rpb24gKG5hbWUsIGV4cGVjdGVkLCBhY3R1YWwpIHtcbiAgLy8gZGV0ZXJtaW5lcjogJ211c3QgYmUnIG9yICdtdXN0IG5vdCBiZSdcbiAgbGV0IGRldGVybWluZXI7XG4gIGlmICh0eXBlb2YgZXhwZWN0ZWQgPT09ICdzdHJpbmcnICYmIHN0YXJ0c1dpdGgoZXhwZWN0ZWQsICdub3QgJykpIHtcbiAgICBkZXRlcm1pbmVyID0gJ211c3Qgbm90IGJlJztcbiAgICBleHBlY3RlZCA9IGV4cGVjdGVkLnJlcGxhY2UoL15ub3QgLywgJycpO1xuICB9IGVsc2Uge1xuICAgIGRldGVybWluZXIgPSAnbXVzdCBiZSc7XG4gIH1cblxuICBsZXQgbXNnO1xuICBpZiAoZW5kc1dpdGgobmFtZSwgJyBhcmd1bWVudCcpKSB7XG4gICAgLy8gRm9yIGNhc2VzIGxpa2UgJ2ZpcnN0IGFyZ3VtZW50J1xuICAgIG1zZyA9IGBUaGUgJHtuYW1lfSAke2RldGVybWluZXJ9ICR7b25lT2YoZXhwZWN0ZWQsICd0eXBlJyl9YDtcbiAgfSBlbHNlIHtcbiAgICBjb25zdCB0eXBlID0gaW5jbHVkZXMobmFtZSwgJy4nKSA/ICdwcm9wZXJ0eScgOiAnYXJndW1lbnQnO1xuICAgIG1zZyA9IGBUaGUgXCIke25hbWV9XCIgJHt0eXBlfSAke2RldGVybWluZXJ9ICR7b25lT2YoZXhwZWN0ZWQsICd0eXBlJyl9YDtcbiAgfVxuXG4gIG1zZyArPSBgLiBSZWNlaXZlZCB0eXBlICR7dHlwZW9mIGFjdHVhbH1gO1xuICByZXR1cm4gbXNnO1xufSwgVHlwZUVycm9yKTtcbmNyZWF0ZUVycm9yVHlwZSgnRVJSX1NUUkVBTV9QVVNIX0FGVEVSX0VPRicsICdzdHJlYW0ucHVzaCgpIGFmdGVyIEVPRicpO1xuY3JlYXRlRXJyb3JUeXBlKCdFUlJfTUVUSE9EX05PVF9JTVBMRU1FTlRFRCcsIGZ1bmN0aW9uIChuYW1lKSB7XG4gIHJldHVybiAnVGhlICcgKyBuYW1lICsgJyBtZXRob2QgaXMgbm90IGltcGxlbWVudGVkJ1xufSk7XG5jcmVhdGVFcnJvclR5cGUoJ0VSUl9TVFJFQU1fUFJFTUFUVVJFX0NMT1NFJywgJ1ByZW1hdHVyZSBjbG9zZScpO1xuY3JlYXRlRXJyb3JUeXBlKCdFUlJfU1RSRUFNX0RFU1RST1lFRCcsIGZ1bmN0aW9uIChuYW1lKSB7XG4gIHJldHVybiAnQ2Fubm90IGNhbGwgJyArIG5hbWUgKyAnIGFmdGVyIGEgc3RyZWFtIHdhcyBkZXN0cm95ZWQnO1xufSk7XG5jcmVhdGVFcnJvclR5cGUoJ0VSUl9NVUxUSVBMRV9DQUxMQkFDSycsICdDYWxsYmFjayBjYWxsZWQgbXVsdGlwbGUgdGltZXMnKTtcbmNyZWF0ZUVycm9yVHlwZSgnRVJSX1NUUkVBTV9DQU5OT1RfUElQRScsICdDYW5ub3QgcGlwZSwgbm90IHJlYWRhYmxlJyk7XG5jcmVhdGVFcnJvclR5cGUoJ0VSUl9TVFJFQU1fV1JJVEVfQUZURVJfRU5EJywgJ3dyaXRlIGFmdGVyIGVuZCcpO1xuY3JlYXRlRXJyb3JUeXBlKCdFUlJfU1RSRUFNX05VTExfVkFMVUVTJywgJ01heSBub3Qgd3JpdGUgbnVsbCB2YWx1ZXMgdG8gc3RyZWFtJywgVHlwZUVycm9yKTtcbmNyZWF0ZUVycm9yVHlwZSgnRVJSX1VOS05PV05fRU5DT0RJTkcnLCBmdW5jdGlvbiAoYXJnKSB7XG4gIHJldHVybiAnVW5rbm93biBlbmNvZGluZzogJyArIGFyZ1xufSwgVHlwZUVycm9yKTtcbmNyZWF0ZUVycm9yVHlwZSgnRVJSX1NUUkVBTV9VTlNISUZUX0FGVEVSX0VORF9FVkVOVCcsICdzdHJlYW0udW5zaGlmdCgpIGFmdGVyIGVuZCBldmVudCcpO1xuXG5tb2R1bGUuZXhwb3J0cy5jb2RlcyA9IGNvZGVzO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgRVJSX0lOVkFMSURfT1BUX1ZBTFVFID0gcmVxdWlyZSgnLi4vLi4vLi4vZXJyb3JzJykuY29kZXMuRVJSX0lOVkFMSURfT1BUX1ZBTFVFO1xuZnVuY3Rpb24gaGlnaFdhdGVyTWFya0Zyb20ob3B0aW9ucywgaXNEdXBsZXgsIGR1cGxleEtleSkge1xuICByZXR1cm4gb3B0aW9ucy5oaWdoV2F0ZXJNYXJrICE9IG51bGwgPyBvcHRpb25zLmhpZ2hXYXRlck1hcmsgOiBpc0R1cGxleCA/IG9wdGlvbnNbZHVwbGV4S2V5XSA6IG51bGw7XG59XG5mdW5jdGlvbiBnZXRIaWdoV2F0ZXJNYXJrKHN0YXRlLCBvcHRpb25zLCBkdXBsZXhLZXksIGlzRHVwbGV4KSB7XG4gIHZhciBod20gPSBoaWdoV2F0ZXJNYXJrRnJvbShvcHRpb25zLCBpc0R1cGxleCwgZHVwbGV4S2V5KTtcbiAgaWYgKGh3bSAhPSBudWxsKSB7XG4gICAgaWYgKCEoaXNGaW5pdGUoaHdtKSAmJiBNYXRoLmZsb29yKGh3bSkgPT09IGh3bSkgfHwgaHdtIDwgMCkge1xuICAgICAgdmFyIG5hbWUgPSBpc0R1cGxleCA/IGR1cGxleEtleSA6ICdoaWdoV2F0ZXJNYXJrJztcbiAgICAgIHRocm93IG5ldyBFUlJfSU5WQUxJRF9PUFRfVkFMVUUobmFtZSwgaHdtKTtcbiAgICB9XG4gICAgcmV0dXJuIE1hdGguZmxvb3IoaHdtKTtcbiAgfVxuXG4gIC8vIERlZmF1bHQgdmFsdWVcbiAgcmV0dXJuIHN0YXRlLm9iamVjdE1vZGUgPyAxNiA6IDE2ICogMTAyNDtcbn1cbm1vZHVsZS5leHBvcnRzID0ge1xuICBnZXRIaWdoV2F0ZXJNYXJrOiBnZXRIaWdoV2F0ZXJNYXJrXG59OyIsImlmICh0eXBlb2YgT2JqZWN0LmNyZWF0ZSA9PT0gJ2Z1bmN0aW9uJykge1xuICAvLyBpbXBsZW1lbnRhdGlvbiBmcm9tIHN0YW5kYXJkIG5vZGUuanMgJ3V0aWwnIG1vZHVsZVxuICBtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIGluaGVyaXRzKGN0b3IsIHN1cGVyQ3Rvcikge1xuICAgIGlmIChzdXBlckN0b3IpIHtcbiAgICAgIGN0b3Iuc3VwZXJfID0gc3VwZXJDdG9yXG4gICAgICBjdG9yLnByb3RvdHlwZSA9IE9iamVjdC5jcmVhdGUoc3VwZXJDdG9yLnByb3RvdHlwZSwge1xuICAgICAgICBjb25zdHJ1Y3Rvcjoge1xuICAgICAgICAgIHZhbHVlOiBjdG9yLFxuICAgICAgICAgIGVudW1lcmFibGU6IGZhbHNlLFxuICAgICAgICAgIHdyaXRhYmxlOiB0cnVlLFxuICAgICAgICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZVxuICAgICAgICB9XG4gICAgICB9KVxuICAgIH1cbiAgfTtcbn0gZWxzZSB7XG4gIC8vIG9sZCBzY2hvb2wgc2hpbSBmb3Igb2xkIGJyb3dzZXJzXG4gIG1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gaW5oZXJpdHMoY3Rvciwgc3VwZXJDdG9yKSB7XG4gICAgaWYgKHN1cGVyQ3Rvcikge1xuICAgICAgY3Rvci5zdXBlcl8gPSBzdXBlckN0b3JcbiAgICAgIHZhciBUZW1wQ3RvciA9IGZ1bmN0aW9uICgpIHt9XG4gICAgICBUZW1wQ3Rvci5wcm90b3R5cGUgPSBzdXBlckN0b3IucHJvdG90eXBlXG4gICAgICBjdG9yLnByb3RvdHlwZSA9IG5ldyBUZW1wQ3RvcigpXG4gICAgICBjdG9yLnByb3RvdHlwZS5jb25zdHJ1Y3RvciA9IGN0b3JcbiAgICB9XG4gIH1cbn1cbiIsInRyeSB7XG4gIHZhciB1dGlsID0gcmVxdWlyZSgndXRpbCcpO1xuICAvKiBpc3RhbmJ1bCBpZ25vcmUgbmV4dCAqL1xuICBpZiAodHlwZW9mIHV0aWwuaW5oZXJpdHMgIT09ICdmdW5jdGlvbicpIHRocm93ICcnO1xuICBtb2R1bGUuZXhwb3J0cyA9IHV0aWwuaW5oZXJpdHM7XG59IGNhdGNoIChlKSB7XG4gIC8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0ICovXG4gIG1vZHVsZS5leHBvcnRzID0gcmVxdWlyZSgnLi9pbmhlcml0c19icm93c2VyLmpzJyk7XG59XG4iLCJcbi8qKlxuICogRm9yIE5vZGUuanMsIHNpbXBseSByZS1leHBvcnQgdGhlIGNvcmUgYHV0aWwuZGVwcmVjYXRlYCBmdW5jdGlvbi5cbiAqL1xuXG5tb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoJ3V0aWwnKS5kZXByZWNhdGU7XG4iLCIvLyBDb3B5cmlnaHQgSm95ZW50LCBJbmMuIGFuZCBvdGhlciBOb2RlIGNvbnRyaWJ1dG9ycy5cbi8vXG4vLyBQZXJtaXNzaW9uIGlzIGhlcmVieSBncmFudGVkLCBmcmVlIG9mIGNoYXJnZSwgdG8gYW55IHBlcnNvbiBvYnRhaW5pbmcgYVxuLy8gY29weSBvZiB0aGlzIHNvZnR3YXJlIGFuZCBhc3NvY2lhdGVkIGRvY3VtZW50YXRpb24gZmlsZXMgKHRoZVxuLy8gXCJTb2Z0d2FyZVwiKSwgdG8gZGVhbCBpbiB0aGUgU29mdHdhcmUgd2l0aG91dCByZXN0cmljdGlvbiwgaW5jbHVkaW5nXG4vLyB3aXRob3V0IGxpbWl0YXRpb24gdGhlIHJpZ2h0cyB0byB1c2UsIGNvcHksIG1vZGlmeSwgbWVyZ2UsIHB1Ymxpc2gsXG4vLyBkaXN0cmlidXRlLCBzdWJsaWNlbnNlLCBhbmQvb3Igc2VsbCBjb3BpZXMgb2YgdGhlIFNvZnR3YXJlLCBhbmQgdG8gcGVybWl0XG4vLyBwZXJzb25zIHRvIHdob20gdGhlIFNvZnR3YXJlIGlzIGZ1cm5pc2hlZCB0byBkbyBzbywgc3ViamVjdCB0byB0aGVcbi8vIGZvbGxvd2luZyBjb25kaXRpb25zOlxuLy9cbi8vIFRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGFuZCB0aGlzIHBlcm1pc3Npb24gbm90aWNlIHNoYWxsIGJlIGluY2x1ZGVkXG4vLyBpbiBhbGwgY29waWVzIG9yIHN1YnN0YW50aWFsIHBvcnRpb25zIG9mIHRoZSBTb2Z0d2FyZS5cbi8vXG4vLyBUSEUgU09GVFdBUkUgSVMgUFJPVklERUQgXCJBUyBJU1wiLCBXSVRIT1VUIFdBUlJBTlRZIE9GIEFOWSBLSU5ELCBFWFBSRVNTXG4vLyBPUiBJTVBMSUVELCBJTkNMVURJTkcgQlVUIE5PVCBMSU1JVEVEIFRPIFRIRSBXQVJSQU5USUVTIE9GXG4vLyBNRVJDSEFOVEFCSUxJVFksIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFORCBOT05JTkZSSU5HRU1FTlQuIElOXG4vLyBOTyBFVkVOVCBTSEFMTCBUSEUgQVVUSE9SUyBPUiBDT1BZUklHSFQgSE9MREVSUyBCRSBMSUFCTEUgRk9SIEFOWSBDTEFJTSxcbi8vIERBTUFHRVMgT1IgT1RIRVIgTElBQklMSVRZLCBXSEVUSEVSIElOIEFOIEFDVElPTiBPRiBDT05UUkFDVCwgVE9SVCBPUlxuLy8gT1RIRVJXSVNFLCBBUklTSU5HIEZST00sIE9VVCBPRiBPUiBJTiBDT05ORUNUSU9OIFdJVEggVEhFIFNPRlRXQVJFIE9SIFRIRVxuLy8gVVNFIE9SIE9USEVSIERFQUxJTkdTIElOIFRIRSBTT0ZUV0FSRS5cblxuLy8gQSBiaXQgc2ltcGxlciB0aGFuIHJlYWRhYmxlIHN0cmVhbXMuXG4vLyBJbXBsZW1lbnQgYW4gYXN5bmMgLl93cml0ZShjaHVuaywgZW5jb2RpbmcsIGNiKSwgYW5kIGl0J2xsIGhhbmRsZSBhbGxcbi8vIHRoZSBkcmFpbiBldmVudCBlbWlzc2lvbiBhbmQgYnVmZmVyaW5nLlxuXG4ndXNlIHN0cmljdCc7XG5cbm1vZHVsZS5leHBvcnRzID0gV3JpdGFibGU7XG5cbi8qIDxyZXBsYWNlbWVudD4gKi9cbmZ1bmN0aW9uIFdyaXRlUmVxKGNodW5rLCBlbmNvZGluZywgY2IpIHtcbiAgdGhpcy5jaHVuayA9IGNodW5rO1xuICB0aGlzLmVuY29kaW5nID0gZW5jb2Rpbmc7XG4gIHRoaXMuY2FsbGJhY2sgPSBjYjtcbiAgdGhpcy5uZXh0ID0gbnVsbDtcbn1cblxuLy8gSXQgc2VlbXMgYSBsaW5rZWQgbGlzdCBidXQgaXQgaXMgbm90XG4vLyB0aGVyZSB3aWxsIGJlIG9ubHkgMiBvZiB0aGVzZSBmb3IgZWFjaCBzdHJlYW1cbmZ1bmN0aW9uIENvcmtlZFJlcXVlc3Qoc3RhdGUpIHtcbiAgdmFyIF90aGlzID0gdGhpcztcbiAgdGhpcy5uZXh0ID0gbnVsbDtcbiAgdGhpcy5lbnRyeSA9IG51bGw7XG4gIHRoaXMuZmluaXNoID0gZnVuY3Rpb24gKCkge1xuICAgIG9uQ29ya2VkRmluaXNoKF90aGlzLCBzdGF0ZSk7XG4gIH07XG59XG4vKiA8L3JlcGxhY2VtZW50PiAqL1xuXG4vKjxyZXBsYWNlbWVudD4qL1xudmFyIER1cGxleDtcbi8qPC9yZXBsYWNlbWVudD4qL1xuXG5Xcml0YWJsZS5Xcml0YWJsZVN0YXRlID0gV3JpdGFibGVTdGF0ZTtcblxuLyo8cmVwbGFjZW1lbnQ+Ki9cbnZhciBpbnRlcm5hbFV0aWwgPSB7XG4gIGRlcHJlY2F0ZTogcmVxdWlyZSgndXRpbC1kZXByZWNhdGUnKVxufTtcbi8qPC9yZXBsYWNlbWVudD4qL1xuXG4vKjxyZXBsYWNlbWVudD4qL1xudmFyIFN0cmVhbSA9IHJlcXVpcmUoJy4vaW50ZXJuYWwvc3RyZWFtcy9zdHJlYW0nKTtcbi8qPC9yZXBsYWNlbWVudD4qL1xuXG52YXIgQnVmZmVyID0gcmVxdWlyZSgnYnVmZmVyJykuQnVmZmVyO1xudmFyIE91clVpbnQ4QXJyYXkgPSAodHlwZW9mIGdsb2JhbCAhPT0gJ3VuZGVmaW5lZCcgPyBnbG9iYWwgOiB0eXBlb2Ygd2luZG93ICE9PSAndW5kZWZpbmVkJyA/IHdpbmRvdyA6IHR5cGVvZiBzZWxmICE9PSAndW5kZWZpbmVkJyA/IHNlbGYgOiB7fSkuVWludDhBcnJheSB8fCBmdW5jdGlvbiAoKSB7fTtcbmZ1bmN0aW9uIF91aW50OEFycmF5VG9CdWZmZXIoY2h1bmspIHtcbiAgcmV0dXJuIEJ1ZmZlci5mcm9tKGNodW5rKTtcbn1cbmZ1bmN0aW9uIF9pc1VpbnQ4QXJyYXkob2JqKSB7XG4gIHJldHVybiBCdWZmZXIuaXNCdWZmZXIob2JqKSB8fCBvYmogaW5zdGFuY2VvZiBPdXJVaW50OEFycmF5O1xufVxudmFyIGRlc3Ryb3lJbXBsID0gcmVxdWlyZSgnLi9pbnRlcm5hbC9zdHJlYW1zL2Rlc3Ryb3knKTtcbnZhciBfcmVxdWlyZSA9IHJlcXVpcmUoJy4vaW50ZXJuYWwvc3RyZWFtcy9zdGF0ZScpLFxuICBnZXRIaWdoV2F0ZXJNYXJrID0gX3JlcXVpcmUuZ2V0SGlnaFdhdGVyTWFyaztcbnZhciBfcmVxdWlyZSRjb2RlcyA9IHJlcXVpcmUoJy4uL2Vycm9ycycpLmNvZGVzLFxuICBFUlJfSU5WQUxJRF9BUkdfVFlQRSA9IF9yZXF1aXJlJGNvZGVzLkVSUl9JTlZBTElEX0FSR19UWVBFLFxuICBFUlJfTUVUSE9EX05PVF9JTVBMRU1FTlRFRCA9IF9yZXF1aXJlJGNvZGVzLkVSUl9NRVRIT0RfTk9UX0lNUExFTUVOVEVELFxuICBFUlJfTVVMVElQTEVfQ0FMTEJBQ0sgPSBfcmVxdWlyZSRjb2Rlcy5FUlJfTVVMVElQTEVfQ0FMTEJBQ0ssXG4gIEVSUl9TVFJFQU1fQ0FOTk9UX1BJUEUgPSBfcmVxdWlyZSRjb2Rlcy5FUlJfU1RSRUFNX0NBTk5PVF9QSVBFLFxuICBFUlJfU1RSRUFNX0RFU1RST1lFRCA9IF9yZXF1aXJlJGNvZGVzLkVSUl9TVFJFQU1fREVTVFJPWUVELFxuICBFUlJfU1RSRUFNX05VTExfVkFMVUVTID0gX3JlcXVpcmUkY29kZXMuRVJSX1NUUkVBTV9OVUxMX1ZBTFVFUyxcbiAgRVJSX1NUUkVBTV9XUklURV9BRlRFUl9FTkQgPSBfcmVxdWlyZSRjb2Rlcy5FUlJfU1RSRUFNX1dSSVRFX0FGVEVSX0VORCxcbiAgRVJSX1VOS05PV05fRU5DT0RJTkcgPSBfcmVxdWlyZSRjb2Rlcy5FUlJfVU5LTk9XTl9FTkNPRElORztcbnZhciBlcnJvck9yRGVzdHJveSA9IGRlc3Ryb3lJbXBsLmVycm9yT3JEZXN0cm95O1xucmVxdWlyZSgnaW5oZXJpdHMnKShXcml0YWJsZSwgU3RyZWFtKTtcbmZ1bmN0aW9uIG5vcCgpIHt9XG5mdW5jdGlvbiBXcml0YWJsZVN0YXRlKG9wdGlvbnMsIHN0cmVhbSwgaXNEdXBsZXgpIHtcbiAgRHVwbGV4ID0gRHVwbGV4IHx8IHJlcXVpcmUoJy4vX3N0cmVhbV9kdXBsZXgnKTtcbiAgb3B0aW9ucyA9IG9wdGlvbnMgfHwge307XG5cbiAgLy8gRHVwbGV4IHN0cmVhbXMgYXJlIGJvdGggcmVhZGFibGUgYW5kIHdyaXRhYmxlLCBidXQgc2hhcmVcbiAgLy8gdGhlIHNhbWUgb3B0aW9ucyBvYmplY3QuXG4gIC8vIEhvd2V2ZXIsIHNvbWUgY2FzZXMgcmVxdWlyZSBzZXR0aW5nIG9wdGlvbnMgdG8gZGlmZmVyZW50XG4gIC8vIHZhbHVlcyBmb3IgdGhlIHJlYWRhYmxlIGFuZCB0aGUgd3JpdGFibGUgc2lkZXMgb2YgdGhlIGR1cGxleCBzdHJlYW0sXG4gIC8vIGUuZy4gb3B0aW9ucy5yZWFkYWJsZU9iamVjdE1vZGUgdnMuIG9wdGlvbnMud3JpdGFibGVPYmplY3RNb2RlLCBldGMuXG4gIGlmICh0eXBlb2YgaXNEdXBsZXggIT09ICdib29sZWFuJykgaXNEdXBsZXggPSBzdHJlYW0gaW5zdGFuY2VvZiBEdXBsZXg7XG5cbiAgLy8gb2JqZWN0IHN0cmVhbSBmbGFnIHRvIGluZGljYXRlIHdoZXRoZXIgb3Igbm90IHRoaXMgc3RyZWFtXG4gIC8vIGNvbnRhaW5zIGJ1ZmZlcnMgb3Igb2JqZWN0cy5cbiAgdGhpcy5vYmplY3RNb2RlID0gISFvcHRpb25zLm9iamVjdE1vZGU7XG4gIGlmIChpc0R1cGxleCkgdGhpcy5vYmplY3RNb2RlID0gdGhpcy5vYmplY3RNb2RlIHx8ICEhb3B0aW9ucy53cml0YWJsZU9iamVjdE1vZGU7XG5cbiAgLy8gdGhlIHBvaW50IGF0IHdoaWNoIHdyaXRlKCkgc3RhcnRzIHJldHVybmluZyBmYWxzZVxuICAvLyBOb3RlOiAwIGlzIGEgdmFsaWQgdmFsdWUsIG1lYW5zIHRoYXQgd2UgYWx3YXlzIHJldHVybiBmYWxzZSBpZlxuICAvLyB0aGUgZW50aXJlIGJ1ZmZlciBpcyBub3QgZmx1c2hlZCBpbW1lZGlhdGVseSBvbiB3cml0ZSgpXG4gIHRoaXMuaGlnaFdhdGVyTWFyayA9IGdldEhpZ2hXYXRlck1hcmsodGhpcywgb3B0aW9ucywgJ3dyaXRhYmxlSGlnaFdhdGVyTWFyaycsIGlzRHVwbGV4KTtcblxuICAvLyBpZiBfZmluYWwgaGFzIGJlZW4gY2FsbGVkXG4gIHRoaXMuZmluYWxDYWxsZWQgPSBmYWxzZTtcblxuICAvLyBkcmFpbiBldmVudCBmbGFnLlxuICB0aGlzLm5lZWREcmFpbiA9IGZhbHNlO1xuICAvLyBhdCB0aGUgc3RhcnQgb2YgY2FsbGluZyBlbmQoKVxuICB0aGlzLmVuZGluZyA9IGZhbHNlO1xuICAvLyB3aGVuIGVuZCgpIGhhcyBiZWVuIGNhbGxlZCwgYW5kIHJldHVybmVkXG4gIHRoaXMuZW5kZWQgPSBmYWxzZTtcbiAgLy8gd2hlbiAnZmluaXNoJyBpcyBlbWl0dGVkXG4gIHRoaXMuZmluaXNoZWQgPSBmYWxzZTtcblxuICAvLyBoYXMgaXQgYmVlbiBkZXN0cm95ZWRcbiAgdGhpcy5kZXN0cm95ZWQgPSBmYWxzZTtcblxuICAvLyBzaG91bGQgd2UgZGVjb2RlIHN0cmluZ3MgaW50byBidWZmZXJzIGJlZm9yZSBwYXNzaW5nIHRvIF93cml0ZT9cbiAgLy8gdGhpcyBpcyBoZXJlIHNvIHRoYXQgc29tZSBub2RlLWNvcmUgc3RyZWFtcyBjYW4gb3B0aW1pemUgc3RyaW5nXG4gIC8vIGhhbmRsaW5nIGF0IGEgbG93ZXIgbGV2ZWwuXG4gIHZhciBub0RlY29kZSA9IG9wdGlvbnMuZGVjb2RlU3RyaW5ncyA9PT0gZmFsc2U7XG4gIHRoaXMuZGVjb2RlU3RyaW5ncyA9ICFub0RlY29kZTtcblxuICAvLyBDcnlwdG8gaXMga2luZCBvZiBvbGQgYW5kIGNydXN0eS4gIEhpc3RvcmljYWxseSwgaXRzIGRlZmF1bHQgc3RyaW5nXG4gIC8vIGVuY29kaW5nIGlzICdiaW5hcnknIHNvIHdlIGhhdmUgdG8gbWFrZSB0aGlzIGNvbmZpZ3VyYWJsZS5cbiAgLy8gRXZlcnl0aGluZyBlbHNlIGluIHRoZSB1bml2ZXJzZSB1c2VzICd1dGY4JywgdGhvdWdoLlxuICB0aGlzLmRlZmF1bHRFbmNvZGluZyA9IG9wdGlvbnMuZGVmYXVsdEVuY29kaW5nIHx8ICd1dGY4JztcblxuICAvLyBub3QgYW4gYWN0dWFsIGJ1ZmZlciB3ZSBrZWVwIHRyYWNrIG9mLCBidXQgYSBtZWFzdXJlbWVudFxuICAvLyBvZiBob3cgbXVjaCB3ZSdyZSB3YWl0aW5nIHRvIGdldCBwdXNoZWQgdG8gc29tZSB1bmRlcmx5aW5nXG4gIC8vIHNvY2tldCBvciBmaWxlLlxuICB0aGlzLmxlbmd0aCA9IDA7XG5cbiAgLy8gYSBmbGFnIHRvIHNlZSB3aGVuIHdlJ3JlIGluIHRoZSBtaWRkbGUgb2YgYSB3cml0ZS5cbiAgdGhpcy53cml0aW5nID0gZmFsc2U7XG5cbiAgLy8gd2hlbiB0cnVlIGFsbCB3cml0ZXMgd2lsbCBiZSBidWZmZXJlZCB1bnRpbCAudW5jb3JrKCkgY2FsbFxuICB0aGlzLmNvcmtlZCA9IDA7XG5cbiAgLy8gYSBmbGFnIHRvIGJlIGFibGUgdG8gdGVsbCBpZiB0aGUgb253cml0ZSBjYiBpcyBjYWxsZWQgaW1tZWRpYXRlbHksXG4gIC8vIG9yIG9uIGEgbGF0ZXIgdGljay4gIFdlIHNldCB0aGlzIHRvIHRydWUgYXQgZmlyc3QsIGJlY2F1c2UgYW55XG4gIC8vIGFjdGlvbnMgdGhhdCBzaG91bGRuJ3QgaGFwcGVuIHVudGlsIFwibGF0ZXJcIiBzaG91bGQgZ2VuZXJhbGx5IGFsc29cbiAgLy8gbm90IGhhcHBlbiBiZWZvcmUgdGhlIGZpcnN0IHdyaXRlIGNhbGwuXG4gIHRoaXMuc3luYyA9IHRydWU7XG5cbiAgLy8gYSBmbGFnIHRvIGtub3cgaWYgd2UncmUgcHJvY2Vzc2luZyBwcmV2aW91c2x5IGJ1ZmZlcmVkIGl0ZW1zLCB3aGljaFxuICAvLyBtYXkgY2FsbCB0aGUgX3dyaXRlKCkgY2FsbGJhY2sgaW4gdGhlIHNhbWUgdGljaywgc28gdGhhdCB3ZSBkb24ndFxuICAvLyBlbmQgdXAgaW4gYW4gb3ZlcmxhcHBlZCBvbndyaXRlIHNpdHVhdGlvbi5cbiAgdGhpcy5idWZmZXJQcm9jZXNzaW5nID0gZmFsc2U7XG5cbiAgLy8gdGhlIGNhbGxiYWNrIHRoYXQncyBwYXNzZWQgdG8gX3dyaXRlKGNodW5rLGNiKVxuICB0aGlzLm9ud3JpdGUgPSBmdW5jdGlvbiAoZXIpIHtcbiAgICBvbndyaXRlKHN0cmVhbSwgZXIpO1xuICB9O1xuXG4gIC8vIHRoZSBjYWxsYmFjayB0aGF0IHRoZSB1c2VyIHN1cHBsaWVzIHRvIHdyaXRlKGNodW5rLGVuY29kaW5nLGNiKVxuICB0aGlzLndyaXRlY2IgPSBudWxsO1xuXG4gIC8vIHRoZSBhbW91bnQgdGhhdCBpcyBiZWluZyB3cml0dGVuIHdoZW4gX3dyaXRlIGlzIGNhbGxlZC5cbiAgdGhpcy53cml0ZWxlbiA9IDA7XG4gIHRoaXMuYnVmZmVyZWRSZXF1ZXN0ID0gbnVsbDtcbiAgdGhpcy5sYXN0QnVmZmVyZWRSZXF1ZXN0ID0gbnVsbDtcblxuICAvLyBudW1iZXIgb2YgcGVuZGluZyB1c2VyLXN1cHBsaWVkIHdyaXRlIGNhbGxiYWNrc1xuICAvLyB0aGlzIG11c3QgYmUgMCBiZWZvcmUgJ2ZpbmlzaCcgY2FuIGJlIGVtaXR0ZWRcbiAgdGhpcy5wZW5kaW5nY2IgPSAwO1xuXG4gIC8vIGVtaXQgcHJlZmluaXNoIGlmIHRoZSBvbmx5IHRoaW5nIHdlJ3JlIHdhaXRpbmcgZm9yIGlzIF93cml0ZSBjYnNcbiAgLy8gVGhpcyBpcyByZWxldmFudCBmb3Igc3luY2hyb25vdXMgVHJhbnNmb3JtIHN0cmVhbXNcbiAgdGhpcy5wcmVmaW5pc2hlZCA9IGZhbHNlO1xuXG4gIC8vIFRydWUgaWYgdGhlIGVycm9yIHdhcyBhbHJlYWR5IGVtaXR0ZWQgYW5kIHNob3VsZCBub3QgYmUgdGhyb3duIGFnYWluXG4gIHRoaXMuZXJyb3JFbWl0dGVkID0gZmFsc2U7XG5cbiAgLy8gU2hvdWxkIGNsb3NlIGJlIGVtaXR0ZWQgb24gZGVzdHJveS4gRGVmYXVsdHMgdG8gdHJ1ZS5cbiAgdGhpcy5lbWl0Q2xvc2UgPSBvcHRpb25zLmVtaXRDbG9zZSAhPT0gZmFsc2U7XG5cbiAgLy8gU2hvdWxkIC5kZXN0cm95KCkgYmUgY2FsbGVkIGFmdGVyICdmaW5pc2gnIChhbmQgcG90ZW50aWFsbHkgJ2VuZCcpXG4gIHRoaXMuYXV0b0Rlc3Ryb3kgPSAhIW9wdGlvbnMuYXV0b0Rlc3Ryb3k7XG5cbiAgLy8gY291bnQgYnVmZmVyZWQgcmVxdWVzdHNcbiAgdGhpcy5idWZmZXJlZFJlcXVlc3RDb3VudCA9IDA7XG5cbiAgLy8gYWxsb2NhdGUgdGhlIGZpcnN0IENvcmtlZFJlcXVlc3QsIHRoZXJlIGlzIGFsd2F5c1xuICAvLyBvbmUgYWxsb2NhdGVkIGFuZCBmcmVlIHRvIHVzZSwgYW5kIHdlIG1haW50YWluIGF0IG1vc3QgdHdvXG4gIHRoaXMuY29ya2VkUmVxdWVzdHNGcmVlID0gbmV3IENvcmtlZFJlcXVlc3QodGhpcyk7XG59XG5Xcml0YWJsZVN0YXRlLnByb3RvdHlwZS5nZXRCdWZmZXIgPSBmdW5jdGlvbiBnZXRCdWZmZXIoKSB7XG4gIHZhciBjdXJyZW50ID0gdGhpcy5idWZmZXJlZFJlcXVlc3Q7XG4gIHZhciBvdXQgPSBbXTtcbiAgd2hpbGUgKGN1cnJlbnQpIHtcbiAgICBvdXQucHVzaChjdXJyZW50KTtcbiAgICBjdXJyZW50ID0gY3VycmVudC5uZXh0O1xuICB9XG4gIHJldHVybiBvdXQ7XG59O1xuKGZ1bmN0aW9uICgpIHtcbiAgdHJ5IHtcbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoV3JpdGFibGVTdGF0ZS5wcm90b3R5cGUsICdidWZmZXInLCB7XG4gICAgICBnZXQ6IGludGVybmFsVXRpbC5kZXByZWNhdGUoZnVuY3Rpb24gd3JpdGFibGVTdGF0ZUJ1ZmZlckdldHRlcigpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0QnVmZmVyKCk7XG4gICAgICB9LCAnX3dyaXRhYmxlU3RhdGUuYnVmZmVyIGlzIGRlcHJlY2F0ZWQuIFVzZSBfd3JpdGFibGVTdGF0ZS5nZXRCdWZmZXIgJyArICdpbnN0ZWFkLicsICdERVAwMDAzJylcbiAgICB9KTtcbiAgfSBjYXRjaCAoXykge31cbn0pKCk7XG5cbi8vIFRlc3QgX3dyaXRhYmxlU3RhdGUgZm9yIGluaGVyaXRhbmNlIHRvIGFjY291bnQgZm9yIER1cGxleCBzdHJlYW1zLFxuLy8gd2hvc2UgcHJvdG90eXBlIGNoYWluIG9ubHkgcG9pbnRzIHRvIFJlYWRhYmxlLlxudmFyIHJlYWxIYXNJbnN0YW5jZTtcbmlmICh0eXBlb2YgU3ltYm9sID09PSAnZnVuY3Rpb24nICYmIFN5bWJvbC5oYXNJbnN0YW5jZSAmJiB0eXBlb2YgRnVuY3Rpb24ucHJvdG90eXBlW1N5bWJvbC5oYXNJbnN0YW5jZV0gPT09ICdmdW5jdGlvbicpIHtcbiAgcmVhbEhhc0luc3RhbmNlID0gRnVuY3Rpb24ucHJvdG90eXBlW1N5bWJvbC5oYXNJbnN0YW5jZV07XG4gIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShXcml0YWJsZSwgU3ltYm9sLmhhc0luc3RhbmNlLCB7XG4gICAgdmFsdWU6IGZ1bmN0aW9uIHZhbHVlKG9iamVjdCkge1xuICAgICAgaWYgKHJlYWxIYXNJbnN0YW5jZS5jYWxsKHRoaXMsIG9iamVjdCkpIHJldHVybiB0cnVlO1xuICAgICAgaWYgKHRoaXMgIT09IFdyaXRhYmxlKSByZXR1cm4gZmFsc2U7XG4gICAgICByZXR1cm4gb2JqZWN0ICYmIG9iamVjdC5fd3JpdGFibGVTdGF0ZSBpbnN0YW5jZW9mIFdyaXRhYmxlU3RhdGU7XG4gICAgfVxuICB9KTtcbn0gZWxzZSB7XG4gIHJlYWxIYXNJbnN0YW5jZSA9IGZ1bmN0aW9uIHJlYWxIYXNJbnN0YW5jZShvYmplY3QpIHtcbiAgICByZXR1cm4gb2JqZWN0IGluc3RhbmNlb2YgdGhpcztcbiAgfTtcbn1cbmZ1bmN0aW9uIFdyaXRhYmxlKG9wdGlvbnMpIHtcbiAgRHVwbGV4ID0gRHVwbGV4IHx8IHJlcXVpcmUoJy4vX3N0cmVhbV9kdXBsZXgnKTtcblxuICAvLyBXcml0YWJsZSBjdG9yIGlzIGFwcGxpZWQgdG8gRHVwbGV4ZXMsIHRvby5cbiAgLy8gYHJlYWxIYXNJbnN0YW5jZWAgaXMgbmVjZXNzYXJ5IGJlY2F1c2UgdXNpbmcgcGxhaW4gYGluc3RhbmNlb2ZgXG4gIC8vIHdvdWxkIHJldHVybiBmYWxzZSwgYXMgbm8gYF93cml0YWJsZVN0YXRlYCBwcm9wZXJ0eSBpcyBhdHRhY2hlZC5cblxuICAvLyBUcnlpbmcgdG8gdXNlIHRoZSBjdXN0b20gYGluc3RhbmNlb2ZgIGZvciBXcml0YWJsZSBoZXJlIHdpbGwgYWxzbyBicmVhayB0aGVcbiAgLy8gTm9kZS5qcyBMYXp5VHJhbnNmb3JtIGltcGxlbWVudGF0aW9uLCB3aGljaCBoYXMgYSBub24tdHJpdmlhbCBnZXR0ZXIgZm9yXG4gIC8vIGBfd3JpdGFibGVTdGF0ZWAgdGhhdCB3b3VsZCBsZWFkIHRvIGluZmluaXRlIHJlY3Vyc2lvbi5cblxuICAvLyBDaGVja2luZyBmb3IgYSBTdHJlYW0uRHVwbGV4IGluc3RhbmNlIGlzIGZhc3RlciBoZXJlIGluc3RlYWQgb2YgaW5zaWRlXG4gIC8vIHRoZSBXcml0YWJsZVN0YXRlIGNvbnN0cnVjdG9yLCBhdCBsZWFzdCB3aXRoIFY4IDYuNVxuICB2YXIgaXNEdXBsZXggPSB0aGlzIGluc3RhbmNlb2YgRHVwbGV4O1xuICBpZiAoIWlzRHVwbGV4ICYmICFyZWFsSGFzSW5zdGFuY2UuY2FsbChXcml0YWJsZSwgdGhpcykpIHJldHVybiBuZXcgV3JpdGFibGUob3B0aW9ucyk7XG4gIHRoaXMuX3dyaXRhYmxlU3RhdGUgPSBuZXcgV3JpdGFibGVTdGF0ZShvcHRpb25zLCB0aGlzLCBpc0R1cGxleCk7XG5cbiAgLy8gbGVnYWN5LlxuICB0aGlzLndyaXRhYmxlID0gdHJ1ZTtcbiAgaWYgKG9wdGlvbnMpIHtcbiAgICBpZiAodHlwZW9mIG9wdGlvbnMud3JpdGUgPT09ICdmdW5jdGlvbicpIHRoaXMuX3dyaXRlID0gb3B0aW9ucy53cml0ZTtcbiAgICBpZiAodHlwZW9mIG9wdGlvbnMud3JpdGV2ID09PSAnZnVuY3Rpb24nKSB0aGlzLl93cml0ZXYgPSBvcHRpb25zLndyaXRldjtcbiAgICBpZiAodHlwZW9mIG9wdGlvbnMuZGVzdHJveSA9PT0gJ2Z1bmN0aW9uJykgdGhpcy5fZGVzdHJveSA9IG9wdGlvbnMuZGVzdHJveTtcbiAgICBpZiAodHlwZW9mIG9wdGlvbnMuZmluYWwgPT09ICdmdW5jdGlvbicpIHRoaXMuX2ZpbmFsID0gb3B0aW9ucy5maW5hbDtcbiAgfVxuICBTdHJlYW0uY2FsbCh0aGlzKTtcbn1cblxuLy8gT3RoZXJ3aXNlIHBlb3BsZSBjYW4gcGlwZSBXcml0YWJsZSBzdHJlYW1zLCB3aGljaCBpcyBqdXN0IHdyb25nLlxuV3JpdGFibGUucHJvdG90eXBlLnBpcGUgPSBmdW5jdGlvbiAoKSB7XG4gIGVycm9yT3JEZXN0cm95KHRoaXMsIG5ldyBFUlJfU1RSRUFNX0NBTk5PVF9QSVBFKCkpO1xufTtcbmZ1bmN0aW9uIHdyaXRlQWZ0ZXJFbmQoc3RyZWFtLCBjYikge1xuICB2YXIgZXIgPSBuZXcgRVJSX1NUUkVBTV9XUklURV9BRlRFUl9FTkQoKTtcbiAgLy8gVE9ETzogZGVmZXIgZXJyb3IgZXZlbnRzIGNvbnNpc3RlbnRseSBldmVyeXdoZXJlLCBub3QganVzdCB0aGUgY2JcbiAgZXJyb3JPckRlc3Ryb3koc3RyZWFtLCBlcik7XG4gIHByb2Nlc3MubmV4dFRpY2soY2IsIGVyKTtcbn1cblxuLy8gQ2hlY2tzIHRoYXQgYSB1c2VyLXN1cHBsaWVkIGNodW5rIGlzIHZhbGlkLCBlc3BlY2lhbGx5IGZvciB0aGUgcGFydGljdWxhclxuLy8gbW9kZSB0aGUgc3RyZWFtIGlzIGluLiBDdXJyZW50bHkgdGhpcyBtZWFucyB0aGF0IGBudWxsYCBpcyBuZXZlciBhY2NlcHRlZFxuLy8gYW5kIHVuZGVmaW5lZC9ub24tc3RyaW5nIHZhbHVlcyBhcmUgb25seSBhbGxvd2VkIGluIG9iamVjdCBtb2RlLlxuZnVuY3Rpb24gdmFsaWRDaHVuayhzdHJlYW0sIHN0YXRlLCBjaHVuaywgY2IpIHtcbiAgdmFyIGVyO1xuICBpZiAoY2h1bmsgPT09IG51bGwpIHtcbiAgICBlciA9IG5ldyBFUlJfU1RSRUFNX05VTExfVkFMVUVTKCk7XG4gIH0gZWxzZSBpZiAodHlwZW9mIGNodW5rICE9PSAnc3RyaW5nJyAmJiAhc3RhdGUub2JqZWN0TW9kZSkge1xuICAgIGVyID0gbmV3IEVSUl9JTlZBTElEX0FSR19UWVBFKCdjaHVuaycsIFsnc3RyaW5nJywgJ0J1ZmZlciddLCBjaHVuayk7XG4gIH1cbiAgaWYgKGVyKSB7XG4gICAgZXJyb3JPckRlc3Ryb3koc3RyZWFtLCBlcik7XG4gICAgcHJvY2Vzcy5uZXh0VGljayhjYiwgZXIpO1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuICByZXR1cm4gdHJ1ZTtcbn1cbldyaXRhYmxlLnByb3RvdHlwZS53cml0ZSA9IGZ1bmN0aW9uIChjaHVuaywgZW5jb2RpbmcsIGNiKSB7XG4gIHZhciBzdGF0ZSA9IHRoaXMuX3dyaXRhYmxlU3RhdGU7XG4gIHZhciByZXQgPSBmYWxzZTtcbiAgdmFyIGlzQnVmID0gIXN0YXRlLm9iamVjdE1vZGUgJiYgX2lzVWludDhBcnJheShjaHVuayk7XG4gIGlmIChpc0J1ZiAmJiAhQnVmZmVyLmlzQnVmZmVyKGNodW5rKSkge1xuICAgIGNodW5rID0gX3VpbnQ4QXJyYXlUb0J1ZmZlcihjaHVuayk7XG4gIH1cbiAgaWYgKHR5cGVvZiBlbmNvZGluZyA9PT0gJ2Z1bmN0aW9uJykge1xuICAgIGNiID0gZW5jb2Rpbmc7XG4gICAgZW5jb2RpbmcgPSBudWxsO1xuICB9XG4gIGlmIChpc0J1ZikgZW5jb2RpbmcgPSAnYnVmZmVyJztlbHNlIGlmICghZW5jb2RpbmcpIGVuY29kaW5nID0gc3RhdGUuZGVmYXVsdEVuY29kaW5nO1xuICBpZiAodHlwZW9mIGNiICE9PSAnZnVuY3Rpb24nKSBjYiA9IG5vcDtcbiAgaWYgKHN0YXRlLmVuZGluZykgd3JpdGVBZnRlckVuZCh0aGlzLCBjYik7ZWxzZSBpZiAoaXNCdWYgfHwgdmFsaWRDaHVuayh0aGlzLCBzdGF0ZSwgY2h1bmssIGNiKSkge1xuICAgIHN0YXRlLnBlbmRpbmdjYisrO1xuICAgIHJldCA9IHdyaXRlT3JCdWZmZXIodGhpcywgc3RhdGUsIGlzQnVmLCBjaHVuaywgZW5jb2RpbmcsIGNiKTtcbiAgfVxuICByZXR1cm4gcmV0O1xufTtcbldyaXRhYmxlLnByb3RvdHlwZS5jb3JrID0gZnVuY3Rpb24gKCkge1xuICB0aGlzLl93cml0YWJsZVN0YXRlLmNvcmtlZCsrO1xufTtcbldyaXRhYmxlLnByb3RvdHlwZS51bmNvcmsgPSBmdW5jdGlvbiAoKSB7XG4gIHZhciBzdGF0ZSA9IHRoaXMuX3dyaXRhYmxlU3RhdGU7XG4gIGlmIChzdGF0ZS5jb3JrZWQpIHtcbiAgICBzdGF0ZS5jb3JrZWQtLTtcbiAgICBpZiAoIXN0YXRlLndyaXRpbmcgJiYgIXN0YXRlLmNvcmtlZCAmJiAhc3RhdGUuYnVmZmVyUHJvY2Vzc2luZyAmJiBzdGF0ZS5idWZmZXJlZFJlcXVlc3QpIGNsZWFyQnVmZmVyKHRoaXMsIHN0YXRlKTtcbiAgfVxufTtcbldyaXRhYmxlLnByb3RvdHlwZS5zZXREZWZhdWx0RW5jb2RpbmcgPSBmdW5jdGlvbiBzZXREZWZhdWx0RW5jb2RpbmcoZW5jb2RpbmcpIHtcbiAgLy8gbm9kZTo6UGFyc2VFbmNvZGluZygpIHJlcXVpcmVzIGxvd2VyIGNhc2UuXG4gIGlmICh0eXBlb2YgZW5jb2RpbmcgPT09ICdzdHJpbmcnKSBlbmNvZGluZyA9IGVuY29kaW5nLnRvTG93ZXJDYXNlKCk7XG4gIGlmICghKFsnaGV4JywgJ3V0ZjgnLCAndXRmLTgnLCAnYXNjaWknLCAnYmluYXJ5JywgJ2Jhc2U2NCcsICd1Y3MyJywgJ3Vjcy0yJywgJ3V0ZjE2bGUnLCAndXRmLTE2bGUnLCAncmF3J10uaW5kZXhPZigoZW5jb2RpbmcgKyAnJykudG9Mb3dlckNhc2UoKSkgPiAtMSkpIHRocm93IG5ldyBFUlJfVU5LTk9XTl9FTkNPRElORyhlbmNvZGluZyk7XG4gIHRoaXMuX3dyaXRhYmxlU3RhdGUuZGVmYXVsdEVuY29kaW5nID0gZW5jb2Rpbmc7XG4gIHJldHVybiB0aGlzO1xufTtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShXcml0YWJsZS5wcm90b3R5cGUsICd3cml0YWJsZUJ1ZmZlcicsIHtcbiAgLy8gbWFraW5nIGl0IGV4cGxpY2l0IHRoaXMgcHJvcGVydHkgaXMgbm90IGVudW1lcmFibGVcbiAgLy8gYmVjYXVzZSBvdGhlcndpc2Ugc29tZSBwcm90b3R5cGUgbWFuaXB1bGF0aW9uIGluXG4gIC8vIHVzZXJsYW5kIHdpbGwgZmFpbFxuICBlbnVtZXJhYmxlOiBmYWxzZSxcbiAgZ2V0OiBmdW5jdGlvbiBnZXQoKSB7XG4gICAgcmV0dXJuIHRoaXMuX3dyaXRhYmxlU3RhdGUgJiYgdGhpcy5fd3JpdGFibGVTdGF0ZS5nZXRCdWZmZXIoKTtcbiAgfVxufSk7XG5mdW5jdGlvbiBkZWNvZGVDaHVuayhzdGF0ZSwgY2h1bmssIGVuY29kaW5nKSB7XG4gIGlmICghc3RhdGUub2JqZWN0TW9kZSAmJiBzdGF0ZS5kZWNvZGVTdHJpbmdzICE9PSBmYWxzZSAmJiB0eXBlb2YgY2h1bmsgPT09ICdzdHJpbmcnKSB7XG4gICAgY2h1bmsgPSBCdWZmZXIuZnJvbShjaHVuaywgZW5jb2RpbmcpO1xuICB9XG4gIHJldHVybiBjaHVuaztcbn1cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShXcml0YWJsZS5wcm90b3R5cGUsICd3cml0YWJsZUhpZ2hXYXRlck1hcmsnLCB7XG4gIC8vIG1ha2luZyBpdCBleHBsaWNpdCB0aGlzIHByb3BlcnR5IGlzIG5vdCBlbnVtZXJhYmxlXG4gIC8vIGJlY2F1c2Ugb3RoZXJ3aXNlIHNvbWUgcHJvdG90eXBlIG1hbmlwdWxhdGlvbiBpblxuICAvLyB1c2VybGFuZCB3aWxsIGZhaWxcbiAgZW51bWVyYWJsZTogZmFsc2UsXG4gIGdldDogZnVuY3Rpb24gZ2V0KCkge1xuICAgIHJldHVybiB0aGlzLl93cml0YWJsZVN0YXRlLmhpZ2hXYXRlck1hcms7XG4gIH1cbn0pO1xuXG4vLyBpZiB3ZSdyZSBhbHJlYWR5IHdyaXRpbmcgc29tZXRoaW5nLCB0aGVuIGp1c3QgcHV0IHRoaXNcbi8vIGluIHRoZSBxdWV1ZSwgYW5kIHdhaXQgb3VyIHR1cm4uICBPdGhlcndpc2UsIGNhbGwgX3dyaXRlXG4vLyBJZiB3ZSByZXR1cm4gZmFsc2UsIHRoZW4gd2UgbmVlZCBhIGRyYWluIGV2ZW50LCBzbyBzZXQgdGhhdCBmbGFnLlxuZnVuY3Rpb24gd3JpdGVPckJ1ZmZlcihzdHJlYW0sIHN0YXRlLCBpc0J1ZiwgY2h1bmssIGVuY29kaW5nLCBjYikge1xuICBpZiAoIWlzQnVmKSB7XG4gICAgdmFyIG5ld0NodW5rID0gZGVjb2RlQ2h1bmsoc3RhdGUsIGNodW5rLCBlbmNvZGluZyk7XG4gICAgaWYgKGNodW5rICE9PSBuZXdDaHVuaykge1xuICAgICAgaXNCdWYgPSB0cnVlO1xuICAgICAgZW5jb2RpbmcgPSAnYnVmZmVyJztcbiAgICAgIGNodW5rID0gbmV3Q2h1bms7XG4gICAgfVxuICB9XG4gIHZhciBsZW4gPSBzdGF0ZS5vYmplY3RNb2RlID8gMSA6IGNodW5rLmxlbmd0aDtcbiAgc3RhdGUubGVuZ3RoICs9IGxlbjtcbiAgdmFyIHJldCA9IHN0YXRlLmxlbmd0aCA8IHN0YXRlLmhpZ2hXYXRlck1hcms7XG4gIC8vIHdlIG11c3QgZW5zdXJlIHRoYXQgcHJldmlvdXMgbmVlZERyYWluIHdpbGwgbm90IGJlIHJlc2V0IHRvIGZhbHNlLlxuICBpZiAoIXJldCkgc3RhdGUubmVlZERyYWluID0gdHJ1ZTtcbiAgaWYgKHN0YXRlLndyaXRpbmcgfHwgc3RhdGUuY29ya2VkKSB7XG4gICAgdmFyIGxhc3QgPSBzdGF0ZS5sYXN0QnVmZmVyZWRSZXF1ZXN0O1xuICAgIHN0YXRlLmxhc3RCdWZmZXJlZFJlcXVlc3QgPSB7XG4gICAgICBjaHVuazogY2h1bmssXG4gICAgICBlbmNvZGluZzogZW5jb2RpbmcsXG4gICAgICBpc0J1ZjogaXNCdWYsXG4gICAgICBjYWxsYmFjazogY2IsXG4gICAgICBuZXh0OiBudWxsXG4gICAgfTtcbiAgICBpZiAobGFzdCkge1xuICAgICAgbGFzdC5uZXh0ID0gc3RhdGUubGFzdEJ1ZmZlcmVkUmVxdWVzdDtcbiAgICB9IGVsc2Uge1xuICAgICAgc3RhdGUuYnVmZmVyZWRSZXF1ZXN0ID0gc3RhdGUubGFzdEJ1ZmZlcmVkUmVxdWVzdDtcbiAgICB9XG4gICAgc3RhdGUuYnVmZmVyZWRSZXF1ZXN0Q291bnQgKz0gMTtcbiAgfSBlbHNlIHtcbiAgICBkb1dyaXRlKHN0cmVhbSwgc3RhdGUsIGZhbHNlLCBsZW4sIGNodW5rLCBlbmNvZGluZywgY2IpO1xuICB9XG4gIHJldHVybiByZXQ7XG59XG5mdW5jdGlvbiBkb1dyaXRlKHN0cmVhbSwgc3RhdGUsIHdyaXRldiwgbGVuLCBjaHVuaywgZW5jb2RpbmcsIGNiKSB7XG4gIHN0YXRlLndyaXRlbGVuID0gbGVuO1xuICBzdGF0ZS53cml0ZWNiID0gY2I7XG4gIHN0YXRlLndyaXRpbmcgPSB0cnVlO1xuICBzdGF0ZS5zeW5jID0gdHJ1ZTtcbiAgaWYgKHN0YXRlLmRlc3Ryb3llZCkgc3RhdGUub253cml0ZShuZXcgRVJSX1NUUkVBTV9ERVNUUk9ZRUQoJ3dyaXRlJykpO2Vsc2UgaWYgKHdyaXRldikgc3RyZWFtLl93cml0ZXYoY2h1bmssIHN0YXRlLm9ud3JpdGUpO2Vsc2Ugc3RyZWFtLl93cml0ZShjaHVuaywgZW5jb2RpbmcsIHN0YXRlLm9ud3JpdGUpO1xuICBzdGF0ZS5zeW5jID0gZmFsc2U7XG59XG5mdW5jdGlvbiBvbndyaXRlRXJyb3Ioc3RyZWFtLCBzdGF0ZSwgc3luYywgZXIsIGNiKSB7XG4gIC0tc3RhdGUucGVuZGluZ2NiO1xuICBpZiAoc3luYykge1xuICAgIC8vIGRlZmVyIHRoZSBjYWxsYmFjayBpZiB3ZSBhcmUgYmVpbmcgY2FsbGVkIHN5bmNocm9ub3VzbHlcbiAgICAvLyB0byBhdm9pZCBwaWxpbmcgdXAgdGhpbmdzIG9uIHRoZSBzdGFja1xuICAgIHByb2Nlc3MubmV4dFRpY2soY2IsIGVyKTtcbiAgICAvLyB0aGlzIGNhbiBlbWl0IGZpbmlzaCwgYW5kIGl0IHdpbGwgYWx3YXlzIGhhcHBlblxuICAgIC8vIGFmdGVyIGVycm9yXG4gICAgcHJvY2Vzcy5uZXh0VGljayhmaW5pc2hNYXliZSwgc3RyZWFtLCBzdGF0ZSk7XG4gICAgc3RyZWFtLl93cml0YWJsZVN0YXRlLmVycm9yRW1pdHRlZCA9IHRydWU7XG4gICAgZXJyb3JPckRlc3Ryb3koc3RyZWFtLCBlcik7XG4gIH0gZWxzZSB7XG4gICAgLy8gdGhlIGNhbGxlciBleHBlY3QgdGhpcyB0byBoYXBwZW4gYmVmb3JlIGlmXG4gICAgLy8gaXQgaXMgYXN5bmNcbiAgICBjYihlcik7XG4gICAgc3RyZWFtLl93cml0YWJsZVN0YXRlLmVycm9yRW1pdHRlZCA9IHRydWU7XG4gICAgZXJyb3JPckRlc3Ryb3koc3RyZWFtLCBlcik7XG4gICAgLy8gdGhpcyBjYW4gZW1pdCBmaW5pc2gsIGJ1dCBmaW5pc2ggbXVzdFxuICAgIC8vIGFsd2F5cyBmb2xsb3cgZXJyb3JcbiAgICBmaW5pc2hNYXliZShzdHJlYW0sIHN0YXRlKTtcbiAgfVxufVxuZnVuY3Rpb24gb253cml0ZVN0YXRlVXBkYXRlKHN0YXRlKSB7XG4gIHN0YXRlLndyaXRpbmcgPSBmYWxzZTtcbiAgc3RhdGUud3JpdGVjYiA9IG51bGw7XG4gIHN0YXRlLmxlbmd0aCAtPSBzdGF0ZS53cml0ZWxlbjtcbiAgc3RhdGUud3JpdGVsZW4gPSAwO1xufVxuZnVuY3Rpb24gb253cml0ZShzdHJlYW0sIGVyKSB7XG4gIHZhciBzdGF0ZSA9IHN0cmVhbS5fd3JpdGFibGVTdGF0ZTtcbiAgdmFyIHN5bmMgPSBzdGF0ZS5zeW5jO1xuICB2YXIgY2IgPSBzdGF0ZS53cml0ZWNiO1xuICBpZiAodHlwZW9mIGNiICE9PSAnZnVuY3Rpb24nKSB0aHJvdyBuZXcgRVJSX01VTFRJUExFX0NBTExCQUNLKCk7XG4gIG9ud3JpdGVTdGF0ZVVwZGF0ZShzdGF0ZSk7XG4gIGlmIChlcikgb253cml0ZUVycm9yKHN0cmVhbSwgc3RhdGUsIHN5bmMsIGVyLCBjYik7ZWxzZSB7XG4gICAgLy8gQ2hlY2sgaWYgd2UncmUgYWN0dWFsbHkgcmVhZHkgdG8gZmluaXNoLCBidXQgZG9uJ3QgZW1pdCB5ZXRcbiAgICB2YXIgZmluaXNoZWQgPSBuZWVkRmluaXNoKHN0YXRlKSB8fCBzdHJlYW0uZGVzdHJveWVkO1xuICAgIGlmICghZmluaXNoZWQgJiYgIXN0YXRlLmNvcmtlZCAmJiAhc3RhdGUuYnVmZmVyUHJvY2Vzc2luZyAmJiBzdGF0ZS5idWZmZXJlZFJlcXVlc3QpIHtcbiAgICAgIGNsZWFyQnVmZmVyKHN0cmVhbSwgc3RhdGUpO1xuICAgIH1cbiAgICBpZiAoc3luYykge1xuICAgICAgcHJvY2Vzcy5uZXh0VGljayhhZnRlcldyaXRlLCBzdHJlYW0sIHN0YXRlLCBmaW5pc2hlZCwgY2IpO1xuICAgIH0gZWxzZSB7XG4gICAgICBhZnRlcldyaXRlKHN0cmVhbSwgc3RhdGUsIGZpbmlzaGVkLCBjYik7XG4gICAgfVxuICB9XG59XG5mdW5jdGlvbiBhZnRlcldyaXRlKHN0cmVhbSwgc3RhdGUsIGZpbmlzaGVkLCBjYikge1xuICBpZiAoIWZpbmlzaGVkKSBvbndyaXRlRHJhaW4oc3RyZWFtLCBzdGF0ZSk7XG4gIHN0YXRlLnBlbmRpbmdjYi0tO1xuICBjYigpO1xuICBmaW5pc2hNYXliZShzdHJlYW0sIHN0YXRlKTtcbn1cblxuLy8gTXVzdCBmb3JjZSBjYWxsYmFjayB0byBiZSBjYWxsZWQgb24gbmV4dFRpY2ssIHNvIHRoYXQgd2UgZG9uJ3Rcbi8vIGVtaXQgJ2RyYWluJyBiZWZvcmUgdGhlIHdyaXRlKCkgY29uc3VtZXIgZ2V0cyB0aGUgJ2ZhbHNlJyByZXR1cm5cbi8vIHZhbHVlLCBhbmQgaGFzIGEgY2hhbmNlIHRvIGF0dGFjaCBhICdkcmFpbicgbGlzdGVuZXIuXG5mdW5jdGlvbiBvbndyaXRlRHJhaW4oc3RyZWFtLCBzdGF0ZSkge1xuICBpZiAoc3RhdGUubGVuZ3RoID09PSAwICYmIHN0YXRlLm5lZWREcmFpbikge1xuICAgIHN0YXRlLm5lZWREcmFpbiA9IGZhbHNlO1xuICAgIHN0cmVhbS5lbWl0KCdkcmFpbicpO1xuICB9XG59XG5cbi8vIGlmIHRoZXJlJ3Mgc29tZXRoaW5nIGluIHRoZSBidWZmZXIgd2FpdGluZywgdGhlbiBwcm9jZXNzIGl0XG5mdW5jdGlvbiBjbGVhckJ1ZmZlcihzdHJlYW0sIHN0YXRlKSB7XG4gIHN0YXRlLmJ1ZmZlclByb2Nlc3NpbmcgPSB0cnVlO1xuICB2YXIgZW50cnkgPSBzdGF0ZS5idWZmZXJlZFJlcXVlc3Q7XG4gIGlmIChzdHJlYW0uX3dyaXRldiAmJiBlbnRyeSAmJiBlbnRyeS5uZXh0KSB7XG4gICAgLy8gRmFzdCBjYXNlLCB3cml0ZSBldmVyeXRoaW5nIHVzaW5nIF93cml0ZXYoKVxuICAgIHZhciBsID0gc3RhdGUuYnVmZmVyZWRSZXF1ZXN0Q291bnQ7XG4gICAgdmFyIGJ1ZmZlciA9IG5ldyBBcnJheShsKTtcbiAgICB2YXIgaG9sZGVyID0gc3RhdGUuY29ya2VkUmVxdWVzdHNGcmVlO1xuICAgIGhvbGRlci5lbnRyeSA9IGVudHJ5O1xuICAgIHZhciBjb3VudCA9IDA7XG4gICAgdmFyIGFsbEJ1ZmZlcnMgPSB0cnVlO1xuICAgIHdoaWxlIChlbnRyeSkge1xuICAgICAgYnVmZmVyW2NvdW50XSA9IGVudHJ5O1xuICAgICAgaWYgKCFlbnRyeS5pc0J1ZikgYWxsQnVmZmVycyA9IGZhbHNlO1xuICAgICAgZW50cnkgPSBlbnRyeS5uZXh0O1xuICAgICAgY291bnQgKz0gMTtcbiAgICB9XG4gICAgYnVmZmVyLmFsbEJ1ZmZlcnMgPSBhbGxCdWZmZXJzO1xuICAgIGRvV3JpdGUoc3RyZWFtLCBzdGF0ZSwgdHJ1ZSwgc3RhdGUubGVuZ3RoLCBidWZmZXIsICcnLCBob2xkZXIuZmluaXNoKTtcblxuICAgIC8vIGRvV3JpdGUgaXMgYWxtb3N0IGFsd2F5cyBhc3luYywgZGVmZXIgdGhlc2UgdG8gc2F2ZSBhIGJpdCBvZiB0aW1lXG4gICAgLy8gYXMgdGhlIGhvdCBwYXRoIGVuZHMgd2l0aCBkb1dyaXRlXG4gICAgc3RhdGUucGVuZGluZ2NiKys7XG4gICAgc3RhdGUubGFzdEJ1ZmZlcmVkUmVxdWVzdCA9IG51bGw7XG4gICAgaWYgKGhvbGRlci5uZXh0KSB7XG4gICAgICBzdGF0ZS5jb3JrZWRSZXF1ZXN0c0ZyZWUgPSBob2xkZXIubmV4dDtcbiAgICAgIGhvbGRlci5uZXh0ID0gbnVsbDtcbiAgICB9IGVsc2Uge1xuICAgICAgc3RhdGUuY29ya2VkUmVxdWVzdHNGcmVlID0gbmV3IENvcmtlZFJlcXVlc3Qoc3RhdGUpO1xuICAgIH1cbiAgICBzdGF0ZS5idWZmZXJlZFJlcXVlc3RDb3VudCA9IDA7XG4gIH0gZWxzZSB7XG4gICAgLy8gU2xvdyBjYXNlLCB3cml0ZSBjaHVua3Mgb25lLWJ5LW9uZVxuICAgIHdoaWxlIChlbnRyeSkge1xuICAgICAgdmFyIGNodW5rID0gZW50cnkuY2h1bms7XG4gICAgICB2YXIgZW5jb2RpbmcgPSBlbnRyeS5lbmNvZGluZztcbiAgICAgIHZhciBjYiA9IGVudHJ5LmNhbGxiYWNrO1xuICAgICAgdmFyIGxlbiA9IHN0YXRlLm9iamVjdE1vZGUgPyAxIDogY2h1bmsubGVuZ3RoO1xuICAgICAgZG9Xcml0ZShzdHJlYW0sIHN0YXRlLCBmYWxzZSwgbGVuLCBjaHVuaywgZW5jb2RpbmcsIGNiKTtcbiAgICAgIGVudHJ5ID0gZW50cnkubmV4dDtcbiAgICAgIHN0YXRlLmJ1ZmZlcmVkUmVxdWVzdENvdW50LS07XG4gICAgICAvLyBpZiB3ZSBkaWRuJ3QgY2FsbCB0aGUgb253cml0ZSBpbW1lZGlhdGVseSwgdGhlblxuICAgICAgLy8gaXQgbWVhbnMgdGhhdCB3ZSBuZWVkIHRvIHdhaXQgdW50aWwgaXQgZG9lcy5cbiAgICAgIC8vIGFsc28sIHRoYXQgbWVhbnMgdGhhdCB0aGUgY2h1bmsgYW5kIGNiIGFyZSBjdXJyZW50bHlcbiAgICAgIC8vIGJlaW5nIHByb2Nlc3NlZCwgc28gbW92ZSB0aGUgYnVmZmVyIGNvdW50ZXIgcGFzdCB0aGVtLlxuICAgICAgaWYgKHN0YXRlLndyaXRpbmcpIHtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgfVxuICAgIGlmIChlbnRyeSA9PT0gbnVsbCkgc3RhdGUubGFzdEJ1ZmZlcmVkUmVxdWVzdCA9IG51bGw7XG4gIH1cbiAgc3RhdGUuYnVmZmVyZWRSZXF1ZXN0ID0gZW50cnk7XG4gIHN0YXRlLmJ1ZmZlclByb2Nlc3NpbmcgPSBmYWxzZTtcbn1cbldyaXRhYmxlLnByb3RvdHlwZS5fd3JpdGUgPSBmdW5jdGlvbiAoY2h1bmssIGVuY29kaW5nLCBjYikge1xuICBjYihuZXcgRVJSX01FVEhPRF9OT1RfSU1QTEVNRU5URUQoJ193cml0ZSgpJykpO1xufTtcbldyaXRhYmxlLnByb3RvdHlwZS5fd3JpdGV2ID0gbnVsbDtcbldyaXRhYmxlLnByb3RvdHlwZS5lbmQgPSBmdW5jdGlvbiAoY2h1bmssIGVuY29kaW5nLCBjYikge1xuICB2YXIgc3RhdGUgPSB0aGlzLl93cml0YWJsZVN0YXRlO1xuICBpZiAodHlwZW9mIGNodW5rID09PSAnZnVuY3Rpb24nKSB7XG4gICAgY2IgPSBjaHVuaztcbiAgICBjaHVuayA9IG51bGw7XG4gICAgZW5jb2RpbmcgPSBudWxsO1xuICB9IGVsc2UgaWYgKHR5cGVvZiBlbmNvZGluZyA9PT0gJ2Z1bmN0aW9uJykge1xuICAgIGNiID0gZW5jb2Rpbmc7XG4gICAgZW5jb2RpbmcgPSBudWxsO1xuICB9XG4gIGlmIChjaHVuayAhPT0gbnVsbCAmJiBjaHVuayAhPT0gdW5kZWZpbmVkKSB0aGlzLndyaXRlKGNodW5rLCBlbmNvZGluZyk7XG5cbiAgLy8gLmVuZCgpIGZ1bGx5IHVuY29ya3NcbiAgaWYgKHN0YXRlLmNvcmtlZCkge1xuICAgIHN0YXRlLmNvcmtlZCA9IDE7XG4gICAgdGhpcy51bmNvcmsoKTtcbiAgfVxuXG4gIC8vIGlnbm9yZSB1bm5lY2Vzc2FyeSBlbmQoKSBjYWxscy5cbiAgaWYgKCFzdGF0ZS5lbmRpbmcpIGVuZFdyaXRhYmxlKHRoaXMsIHN0YXRlLCBjYik7XG4gIHJldHVybiB0aGlzO1xufTtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShXcml0YWJsZS5wcm90b3R5cGUsICd3cml0YWJsZUxlbmd0aCcsIHtcbiAgLy8gbWFraW5nIGl0IGV4cGxpY2l0IHRoaXMgcHJvcGVydHkgaXMgbm90IGVudW1lcmFibGVcbiAgLy8gYmVjYXVzZSBvdGhlcndpc2Ugc29tZSBwcm90b3R5cGUgbWFuaXB1bGF0aW9uIGluXG4gIC8vIHVzZXJsYW5kIHdpbGwgZmFpbFxuICBlbnVtZXJhYmxlOiBmYWxzZSxcbiAgZ2V0OiBmdW5jdGlvbiBnZXQoKSB7XG4gICAgcmV0dXJuIHRoaXMuX3dyaXRhYmxlU3RhdGUubGVuZ3RoO1xuICB9XG59KTtcbmZ1bmN0aW9uIG5lZWRGaW5pc2goc3RhdGUpIHtcbiAgcmV0dXJuIHN0YXRlLmVuZGluZyAmJiBzdGF0ZS5sZW5ndGggPT09IDAgJiYgc3RhdGUuYnVmZmVyZWRSZXF1ZXN0ID09PSBudWxsICYmICFzdGF0ZS5maW5pc2hlZCAmJiAhc3RhdGUud3JpdGluZztcbn1cbmZ1bmN0aW9uIGNhbGxGaW5hbChzdHJlYW0sIHN0YXRlKSB7XG4gIHN0cmVhbS5fZmluYWwoZnVuY3Rpb24gKGVycikge1xuICAgIHN0YXRlLnBlbmRpbmdjYi0tO1xuICAgIGlmIChlcnIpIHtcbiAgICAgIGVycm9yT3JEZXN0cm95KHN0cmVhbSwgZXJyKTtcbiAgICB9XG4gICAgc3RhdGUucHJlZmluaXNoZWQgPSB0cnVlO1xuICAgIHN0cmVhbS5lbWl0KCdwcmVmaW5pc2gnKTtcbiAgICBmaW5pc2hNYXliZShzdHJlYW0sIHN0YXRlKTtcbiAgfSk7XG59XG5mdW5jdGlvbiBwcmVmaW5pc2goc3RyZWFtLCBzdGF0ZSkge1xuICBpZiAoIXN0YXRlLnByZWZpbmlzaGVkICYmICFzdGF0ZS5maW5hbENhbGxlZCkge1xuICAgIGlmICh0eXBlb2Ygc3RyZWFtLl9maW5hbCA9PT0gJ2Z1bmN0aW9uJyAmJiAhc3RhdGUuZGVzdHJveWVkKSB7XG4gICAgICBzdGF0ZS5wZW5kaW5nY2IrKztcbiAgICAgIHN0YXRlLmZpbmFsQ2FsbGVkID0gdHJ1ZTtcbiAgICAgIHByb2Nlc3MubmV4dFRpY2soY2FsbEZpbmFsLCBzdHJlYW0sIHN0YXRlKTtcbiAgICB9IGVsc2Uge1xuICAgICAgc3RhdGUucHJlZmluaXNoZWQgPSB0cnVlO1xuICAgICAgc3RyZWFtLmVtaXQoJ3ByZWZpbmlzaCcpO1xuICAgIH1cbiAgfVxufVxuZnVuY3Rpb24gZmluaXNoTWF5YmUoc3RyZWFtLCBzdGF0ZSkge1xuICB2YXIgbmVlZCA9IG5lZWRGaW5pc2goc3RhdGUpO1xuICBpZiAobmVlZCkge1xuICAgIHByZWZpbmlzaChzdHJlYW0sIHN0YXRlKTtcbiAgICBpZiAoc3RhdGUucGVuZGluZ2NiID09PSAwKSB7XG4gICAgICBzdGF0ZS5maW5pc2hlZCA9IHRydWU7XG4gICAgICBzdHJlYW0uZW1pdCgnZmluaXNoJyk7XG4gICAgICBpZiAoc3RhdGUuYXV0b0Rlc3Ryb3kpIHtcbiAgICAgICAgLy8gSW4gY2FzZSBvZiBkdXBsZXggc3RyZWFtcyB3ZSBuZWVkIGEgd2F5IHRvIGRldGVjdFxuICAgICAgICAvLyBpZiB0aGUgcmVhZGFibGUgc2lkZSBpcyByZWFkeSBmb3IgYXV0b0Rlc3Ryb3kgYXMgd2VsbFxuICAgICAgICB2YXIgclN0YXRlID0gc3RyZWFtLl9yZWFkYWJsZVN0YXRlO1xuICAgICAgICBpZiAoIXJTdGF0ZSB8fCByU3RhdGUuYXV0b0Rlc3Ryb3kgJiYgclN0YXRlLmVuZEVtaXR0ZWQpIHtcbiAgICAgICAgICBzdHJlYW0uZGVzdHJveSgpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9XG4gIHJldHVybiBuZWVkO1xufVxuZnVuY3Rpb24gZW5kV3JpdGFibGUoc3RyZWFtLCBzdGF0ZSwgY2IpIHtcbiAgc3RhdGUuZW5kaW5nID0gdHJ1ZTtcbiAgZmluaXNoTWF5YmUoc3RyZWFtLCBzdGF0ZSk7XG4gIGlmIChjYikge1xuICAgIGlmIChzdGF0ZS5maW5pc2hlZCkgcHJvY2Vzcy5uZXh0VGljayhjYik7ZWxzZSBzdHJlYW0ub25jZSgnZmluaXNoJywgY2IpO1xuICB9XG4gIHN0YXRlLmVuZGVkID0gdHJ1ZTtcbiAgc3RyZWFtLndyaXRhYmxlID0gZmFsc2U7XG59XG5mdW5jdGlvbiBvbkNvcmtlZEZpbmlzaChjb3JrUmVxLCBzdGF0ZSwgZXJyKSB7XG4gIHZhciBlbnRyeSA9IGNvcmtSZXEuZW50cnk7XG4gIGNvcmtSZXEuZW50cnkgPSBudWxsO1xuICB3aGlsZSAoZW50cnkpIHtcbiAgICB2YXIgY2IgPSBlbnRyeS5jYWxsYmFjaztcbiAgICBzdGF0ZS5wZW5kaW5nY2ItLTtcbiAgICBjYihlcnIpO1xuICAgIGVudHJ5ID0gZW50cnkubmV4dDtcbiAgfVxuXG4gIC8vIHJldXNlIHRoZSBmcmVlIGNvcmtSZXEuXG4gIHN0YXRlLmNvcmtlZFJlcXVlc3RzRnJlZS5uZXh0ID0gY29ya1JlcTtcbn1cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShXcml0YWJsZS5wcm90b3R5cGUsICdkZXN0cm95ZWQnLCB7XG4gIC8vIG1ha2luZyBpdCBleHBsaWNpdCB0aGlzIHByb3BlcnR5IGlzIG5vdCBlbnVtZXJhYmxlXG4gIC8vIGJlY2F1c2Ugb3RoZXJ3aXNlIHNvbWUgcHJvdG90eXBlIG1hbmlwdWxhdGlvbiBpblxuICAvLyB1c2VybGFuZCB3aWxsIGZhaWxcbiAgZW51bWVyYWJsZTogZmFsc2UsXG4gIGdldDogZnVuY3Rpb24gZ2V0KCkge1xuICAgIGlmICh0aGlzLl93cml0YWJsZVN0YXRlID09PSB1bmRlZmluZWQpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuX3dyaXRhYmxlU3RhdGUuZGVzdHJveWVkO1xuICB9LFxuICBzZXQ6IGZ1bmN0aW9uIHNldCh2YWx1ZSkge1xuICAgIC8vIHdlIGlnbm9yZSB0aGUgdmFsdWUgaWYgdGhlIHN0cmVhbVxuICAgIC8vIGhhcyBub3QgYmVlbiBpbml0aWFsaXplZCB5ZXRcbiAgICBpZiAoIXRoaXMuX3dyaXRhYmxlU3RhdGUpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICAvLyBiYWNrd2FyZCBjb21wYXRpYmlsaXR5LCB0aGUgdXNlciBpcyBleHBsaWNpdGx5XG4gICAgLy8gbWFuYWdpbmcgZGVzdHJveWVkXG4gICAgdGhpcy5fd3JpdGFibGVTdGF0ZS5kZXN0cm95ZWQgPSB2YWx1ZTtcbiAgfVxufSk7XG5Xcml0YWJsZS5wcm90b3R5cGUuZGVzdHJveSA9IGRlc3Ryb3lJbXBsLmRlc3Ryb3k7XG5Xcml0YWJsZS5wcm90b3R5cGUuX3VuZGVzdHJveSA9IGRlc3Ryb3lJbXBsLnVuZGVzdHJveTtcbldyaXRhYmxlLnByb3RvdHlwZS5fZGVzdHJveSA9IGZ1bmN0aW9uIChlcnIsIGNiKSB7XG4gIGNiKGVycik7XG59OyIsIi8vIENvcHlyaWdodCBKb3llbnQsIEluYy4gYW5kIG90aGVyIE5vZGUgY29udHJpYnV0b3JzLlxuLy9cbi8vIFBlcm1pc3Npb24gaXMgaGVyZWJ5IGdyYW50ZWQsIGZyZWUgb2YgY2hhcmdlLCB0byBhbnkgcGVyc29uIG9idGFpbmluZyBhXG4vLyBjb3B5IG9mIHRoaXMgc29mdHdhcmUgYW5kIGFzc29jaWF0ZWQgZG9jdW1lbnRhdGlvbiBmaWxlcyAodGhlXG4vLyBcIlNvZnR3YXJlXCIpLCB0byBkZWFsIGluIHRoZSBTb2Z0d2FyZSB3aXRob3V0IHJlc3RyaWN0aW9uLCBpbmNsdWRpbmdcbi8vIHdpdGhvdXQgbGltaXRhdGlvbiB0aGUgcmlnaHRzIHRvIHVzZSwgY29weSwgbW9kaWZ5LCBtZXJnZSwgcHVibGlzaCxcbi8vIGRpc3RyaWJ1dGUsIHN1YmxpY2Vuc2UsIGFuZC9vciBzZWxsIGNvcGllcyBvZiB0aGUgU29mdHdhcmUsIGFuZCB0byBwZXJtaXRcbi8vIHBlcnNvbnMgdG8gd2hvbSB0aGUgU29mdHdhcmUgaXMgZnVybmlzaGVkIHRvIGRvIHNvLCBzdWJqZWN0IHRvIHRoZVxuLy8gZm9sbG93aW5nIGNvbmRpdGlvbnM6XG4vL1xuLy8gVGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UgYW5kIHRoaXMgcGVybWlzc2lvbiBub3RpY2Ugc2hhbGwgYmUgaW5jbHVkZWRcbi8vIGluIGFsbCBjb3BpZXMgb3Igc3Vic3RhbnRpYWwgcG9ydGlvbnMgb2YgdGhlIFNvZnR3YXJlLlxuLy9cbi8vIFRIRSBTT0ZUV0FSRSBJUyBQUk9WSURFRCBcIkFTIElTXCIsIFdJVEhPVVQgV0FSUkFOVFkgT0YgQU5ZIEtJTkQsIEVYUFJFU1Ncbi8vIE9SIElNUExJRUQsIElOQ0xVRElORyBCVVQgTk9UIExJTUlURUQgVE8gVEhFIFdBUlJBTlRJRVMgT0Zcbi8vIE1FUkNIQU5UQUJJTElUWSwgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQU5EIE5PTklORlJJTkdFTUVOVC4gSU5cbi8vIE5PIEVWRU5UIFNIQUxMIFRIRSBBVVRIT1JTIE9SIENPUFlSSUdIVCBIT0xERVJTIEJFIExJQUJMRSBGT1IgQU5ZIENMQUlNLFxuLy8gREFNQUdFUyBPUiBPVEhFUiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQU4gQUNUSU9OIE9GIENPTlRSQUNULCBUT1JUIE9SXG4vLyBPVEhFUldJU0UsIEFSSVNJTkcgRlJPTSwgT1VUIE9GIE9SIElOIENPTk5FQ1RJT04gV0lUSCBUSEUgU09GVFdBUkUgT1IgVEhFXG4vLyBVU0UgT1IgT1RIRVIgREVBTElOR1MgSU4gVEhFIFNPRlRXQVJFLlxuXG4vLyBhIGR1cGxleCBzdHJlYW0gaXMganVzdCBhIHN0cmVhbSB0aGF0IGlzIGJvdGggcmVhZGFibGUgYW5kIHdyaXRhYmxlLlxuLy8gU2luY2UgSlMgZG9lc24ndCBoYXZlIG11bHRpcGxlIHByb3RvdHlwYWwgaW5oZXJpdGFuY2UsIHRoaXMgY2xhc3Ncbi8vIHByb3RvdHlwYWxseSBpbmhlcml0cyBmcm9tIFJlYWRhYmxlLCBhbmQgdGhlbiBwYXJhc2l0aWNhbGx5IGZyb21cbi8vIFdyaXRhYmxlLlxuXG4ndXNlIHN0cmljdCc7XG5cbi8qPHJlcGxhY2VtZW50PiovXG52YXIgb2JqZWN0S2V5cyA9IE9iamVjdC5rZXlzIHx8IGZ1bmN0aW9uIChvYmopIHtcbiAgdmFyIGtleXMgPSBbXTtcbiAgZm9yICh2YXIga2V5IGluIG9iaikga2V5cy5wdXNoKGtleSk7XG4gIHJldHVybiBrZXlzO1xufTtcbi8qPC9yZXBsYWNlbWVudD4qL1xuXG5tb2R1bGUuZXhwb3J0cyA9IER1cGxleDtcbnZhciBSZWFkYWJsZSA9IHJlcXVpcmUoJy4vX3N0cmVhbV9yZWFkYWJsZScpO1xudmFyIFdyaXRhYmxlID0gcmVxdWlyZSgnLi9fc3RyZWFtX3dyaXRhYmxlJyk7XG5yZXF1aXJlKCdpbmhlcml0cycpKER1cGxleCwgUmVhZGFibGUpO1xue1xuICAvLyBBbGxvdyB0aGUga2V5cyBhcnJheSB0byBiZSBHQydlZC5cbiAgdmFyIGtleXMgPSBvYmplY3RLZXlzKFdyaXRhYmxlLnByb3RvdHlwZSk7XG4gIGZvciAodmFyIHYgPSAwOyB2IDwga2V5cy5sZW5ndGg7IHYrKykge1xuICAgIHZhciBtZXRob2QgPSBrZXlzW3ZdO1xuICAgIGlmICghRHVwbGV4LnByb3RvdHlwZVttZXRob2RdKSBEdXBsZXgucHJvdG90eXBlW21ldGhvZF0gPSBXcml0YWJsZS5wcm90b3R5cGVbbWV0aG9kXTtcbiAgfVxufVxuZnVuY3Rpb24gRHVwbGV4KG9wdGlvbnMpIHtcbiAgaWYgKCEodGhpcyBpbnN0YW5jZW9mIER1cGxleCkpIHJldHVybiBuZXcgRHVwbGV4KG9wdGlvbnMpO1xuICBSZWFkYWJsZS5jYWxsKHRoaXMsIG9wdGlvbnMpO1xuICBXcml0YWJsZS5jYWxsKHRoaXMsIG9wdGlvbnMpO1xuICB0aGlzLmFsbG93SGFsZk9wZW4gPSB0cnVlO1xuICBpZiAob3B0aW9ucykge1xuICAgIGlmIChvcHRpb25zLnJlYWRhYmxlID09PSBmYWxzZSkgdGhpcy5yZWFkYWJsZSA9IGZhbHNlO1xuICAgIGlmIChvcHRpb25zLndyaXRhYmxlID09PSBmYWxzZSkgdGhpcy53cml0YWJsZSA9IGZhbHNlO1xuICAgIGlmIChvcHRpb25zLmFsbG93SGFsZk9wZW4gPT09IGZhbHNlKSB7XG4gICAgICB0aGlzLmFsbG93SGFsZk9wZW4gPSBmYWxzZTtcbiAgICAgIHRoaXMub25jZSgnZW5kJywgb25lbmQpO1xuICAgIH1cbiAgfVxufVxuT2JqZWN0LmRlZmluZVByb3BlcnR5KER1cGxleC5wcm90b3R5cGUsICd3cml0YWJsZUhpZ2hXYXRlck1hcmsnLCB7XG4gIC8vIG1ha2luZyBpdCBleHBsaWNpdCB0aGlzIHByb3BlcnR5IGlzIG5vdCBlbnVtZXJhYmxlXG4gIC8vIGJlY2F1c2Ugb3RoZXJ3aXNlIHNvbWUgcHJvdG90eXBlIG1hbmlwdWxhdGlvbiBpblxuICAvLyB1c2VybGFuZCB3aWxsIGZhaWxcbiAgZW51bWVyYWJsZTogZmFsc2UsXG4gIGdldDogZnVuY3Rpb24gZ2V0KCkge1xuICAgIHJldHVybiB0aGlzLl93cml0YWJsZVN0YXRlLmhpZ2hXYXRlck1hcms7XG4gIH1cbn0pO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KER1cGxleC5wcm90b3R5cGUsICd3cml0YWJsZUJ1ZmZlcicsIHtcbiAgLy8gbWFraW5nIGl0IGV4cGxpY2l0IHRoaXMgcHJvcGVydHkgaXMgbm90IGVudW1lcmFibGVcbiAgLy8gYmVjYXVzZSBvdGhlcndpc2Ugc29tZSBwcm90b3R5cGUgbWFuaXB1bGF0aW9uIGluXG4gIC8vIHVzZXJsYW5kIHdpbGwgZmFpbFxuICBlbnVtZXJhYmxlOiBmYWxzZSxcbiAgZ2V0OiBmdW5jdGlvbiBnZXQoKSB7XG4gICAgcmV0dXJuIHRoaXMuX3dyaXRhYmxlU3RhdGUgJiYgdGhpcy5fd3JpdGFibGVTdGF0ZS5nZXRCdWZmZXIoKTtcbiAgfVxufSk7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoRHVwbGV4LnByb3RvdHlwZSwgJ3dyaXRhYmxlTGVuZ3RoJywge1xuICAvLyBtYWtpbmcgaXQgZXhwbGljaXQgdGhpcyBwcm9wZXJ0eSBpcyBub3QgZW51bWVyYWJsZVxuICAvLyBiZWNhdXNlIG90aGVyd2lzZSBzb21lIHByb3RvdHlwZSBtYW5pcHVsYXRpb24gaW5cbiAgLy8gdXNlcmxhbmQgd2lsbCBmYWlsXG4gIGVudW1lcmFibGU6IGZhbHNlLFxuICBnZXQ6IGZ1bmN0aW9uIGdldCgpIHtcbiAgICByZXR1cm4gdGhpcy5fd3JpdGFibGVTdGF0ZS5sZW5ndGg7XG4gIH1cbn0pO1xuXG4vLyB0aGUgbm8taGFsZi1vcGVuIGVuZm9yY2VyXG5mdW5jdGlvbiBvbmVuZCgpIHtcbiAgLy8gSWYgdGhlIHdyaXRhYmxlIHNpZGUgZW5kZWQsIHRoZW4gd2UncmUgb2suXG4gIGlmICh0aGlzLl93cml0YWJsZVN0YXRlLmVuZGVkKSByZXR1cm47XG5cbiAgLy8gbm8gbW9yZSBkYXRhIGNhbiBiZSB3cml0dGVuLlxuICAvLyBCdXQgYWxsb3cgbW9yZSB3cml0ZXMgdG8gaGFwcGVuIGluIHRoaXMgdGljay5cbiAgcHJvY2Vzcy5uZXh0VGljayhvbkVuZE5ULCB0aGlzKTtcbn1cbmZ1bmN0aW9uIG9uRW5kTlQoc2VsZikge1xuICBzZWxmLmVuZCgpO1xufVxuT2JqZWN0LmRlZmluZVByb3BlcnR5KER1cGxleC5wcm90b3R5cGUsICdkZXN0cm95ZWQnLCB7XG4gIC8vIG1ha2luZyBpdCBleHBsaWNpdCB0aGlzIHByb3BlcnR5IGlzIG5vdCBlbnVtZXJhYmxlXG4gIC8vIGJlY2F1c2Ugb3RoZXJ3aXNlIHNvbWUgcHJvdG90eXBlIG1hbmlwdWxhdGlvbiBpblxuICAvLyB1c2VybGFuZCB3aWxsIGZhaWxcbiAgZW51bWVyYWJsZTogZmFsc2UsXG4gIGdldDogZnVuY3Rpb24gZ2V0KCkge1xuICAgIGlmICh0aGlzLl9yZWFkYWJsZVN0YXRlID09PSB1bmRlZmluZWQgfHwgdGhpcy5fd3JpdGFibGVTdGF0ZSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLl9yZWFkYWJsZVN0YXRlLmRlc3Ryb3llZCAmJiB0aGlzLl93cml0YWJsZVN0YXRlLmRlc3Ryb3llZDtcbiAgfSxcbiAgc2V0OiBmdW5jdGlvbiBzZXQodmFsdWUpIHtcbiAgICAvLyB3ZSBpZ25vcmUgdGhlIHZhbHVlIGlmIHRoZSBzdHJlYW1cbiAgICAvLyBoYXMgbm90IGJlZW4gaW5pdGlhbGl6ZWQgeWV0XG4gICAgaWYgKHRoaXMuX3JlYWRhYmxlU3RhdGUgPT09IHVuZGVmaW5lZCB8fCB0aGlzLl93cml0YWJsZVN0YXRlID09PSB1bmRlZmluZWQpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICAvLyBiYWNrd2FyZCBjb21wYXRpYmlsaXR5LCB0aGUgdXNlciBpcyBleHBsaWNpdGx5XG4gICAgLy8gbWFuYWdpbmcgZGVzdHJveWVkXG4gICAgdGhpcy5fcmVhZGFibGVTdGF0ZS5kZXN0cm95ZWQgPSB2YWx1ZTtcbiAgICB0aGlzLl93cml0YWJsZVN0YXRlLmRlc3Ryb3llZCA9IHZhbHVlO1xuICB9XG59KTsiLCIvKiEgc2FmZS1idWZmZXIuIE1JVCBMaWNlbnNlLiBGZXJvc3MgQWJvdWtoYWRpamVoIDxodHRwczovL2Zlcm9zcy5vcmcvb3BlbnNvdXJjZT4gKi9cbi8qIGVzbGludC1kaXNhYmxlIG5vZGUvbm8tZGVwcmVjYXRlZC1hcGkgKi9cbnZhciBidWZmZXIgPSByZXF1aXJlKCdidWZmZXInKVxudmFyIEJ1ZmZlciA9IGJ1ZmZlci5CdWZmZXJcblxuLy8gYWx0ZXJuYXRpdmUgdG8gdXNpbmcgT2JqZWN0LmtleXMgZm9yIG9sZCBicm93c2Vyc1xuZnVuY3Rpb24gY29weVByb3BzIChzcmMsIGRzdCkge1xuICBmb3IgKHZhciBrZXkgaW4gc3JjKSB7XG4gICAgZHN0W2tleV0gPSBzcmNba2V5XVxuICB9XG59XG5pZiAoQnVmZmVyLmZyb20gJiYgQnVmZmVyLmFsbG9jICYmIEJ1ZmZlci5hbGxvY1Vuc2FmZSAmJiBCdWZmZXIuYWxsb2NVbnNhZmVTbG93KSB7XG4gIG1vZHVsZS5leHBvcnRzID0gYnVmZmVyXG59IGVsc2Uge1xuICAvLyBDb3B5IHByb3BlcnRpZXMgZnJvbSByZXF1aXJlKCdidWZmZXInKVxuICBjb3B5UHJvcHMoYnVmZmVyLCBleHBvcnRzKVxuICBleHBvcnRzLkJ1ZmZlciA9IFNhZmVCdWZmZXJcbn1cblxuZnVuY3Rpb24gU2FmZUJ1ZmZlciAoYXJnLCBlbmNvZGluZ09yT2Zmc2V0LCBsZW5ndGgpIHtcbiAgcmV0dXJuIEJ1ZmZlcihhcmcsIGVuY29kaW5nT3JPZmZzZXQsIGxlbmd0aClcbn1cblxuU2FmZUJ1ZmZlci5wcm90b3R5cGUgPSBPYmplY3QuY3JlYXRlKEJ1ZmZlci5wcm90b3R5cGUpXG5cbi8vIENvcHkgc3RhdGljIG1ldGhvZHMgZnJvbSBCdWZmZXJcbmNvcHlQcm9wcyhCdWZmZXIsIFNhZmVCdWZmZXIpXG5cblNhZmVCdWZmZXIuZnJvbSA9IGZ1bmN0aW9uIChhcmcsIGVuY29kaW5nT3JPZmZzZXQsIGxlbmd0aCkge1xuICBpZiAodHlwZW9mIGFyZyA9PT0gJ251bWJlcicpIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdBcmd1bWVudCBtdXN0IG5vdCBiZSBhIG51bWJlcicpXG4gIH1cbiAgcmV0dXJuIEJ1ZmZlcihhcmcsIGVuY29kaW5nT3JPZmZzZXQsIGxlbmd0aClcbn1cblxuU2FmZUJ1ZmZlci5hbGxvYyA9IGZ1bmN0aW9uIChzaXplLCBmaWxsLCBlbmNvZGluZykge1xuICBpZiAodHlwZW9mIHNpemUgIT09ICdudW1iZXInKSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcignQXJndW1lbnQgbXVzdCBiZSBhIG51bWJlcicpXG4gIH1cbiAgdmFyIGJ1ZiA9IEJ1ZmZlcihzaXplKVxuICBpZiAoZmlsbCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgaWYgKHR5cGVvZiBlbmNvZGluZyA9PT0gJ3N0cmluZycpIHtcbiAgICAgIGJ1Zi5maWxsKGZpbGwsIGVuY29kaW5nKVxuICAgIH0gZWxzZSB7XG4gICAgICBidWYuZmlsbChmaWxsKVxuICAgIH1cbiAgfSBlbHNlIHtcbiAgICBidWYuZmlsbCgwKVxuICB9XG4gIHJldHVybiBidWZcbn1cblxuU2FmZUJ1ZmZlci5hbGxvY1Vuc2FmZSA9IGZ1bmN0aW9uIChzaXplKSB7XG4gIGlmICh0eXBlb2Ygc2l6ZSAhPT0gJ251bWJlcicpIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdBcmd1bWVudCBtdXN0IGJlIGEgbnVtYmVyJylcbiAgfVxuICByZXR1cm4gQnVmZmVyKHNpemUpXG59XG5cblNhZmVCdWZmZXIuYWxsb2NVbnNhZmVTbG93ID0gZnVuY3Rpb24gKHNpemUpIHtcbiAgaWYgKHR5cGVvZiBzaXplICE9PSAnbnVtYmVyJykge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ0FyZ3VtZW50IG11c3QgYmUgYSBudW1iZXInKVxuICB9XG4gIHJldHVybiBidWZmZXIuU2xvd0J1ZmZlcihzaXplKVxufVxuIiwiLy8gQ29weXJpZ2h0IEpveWVudCwgSW5jLiBhbmQgb3RoZXIgTm9kZSBjb250cmlidXRvcnMuXG4vL1xuLy8gUGVybWlzc2lvbiBpcyBoZXJlYnkgZ3JhbnRlZCwgZnJlZSBvZiBjaGFyZ2UsIHRvIGFueSBwZXJzb24gb2J0YWluaW5nIGFcbi8vIGNvcHkgb2YgdGhpcyBzb2Z0d2FyZSBhbmQgYXNzb2NpYXRlZCBkb2N1bWVudGF0aW9uIGZpbGVzICh0aGVcbi8vIFwiU29mdHdhcmVcIiksIHRvIGRlYWwgaW4gdGhlIFNvZnR3YXJlIHdpdGhvdXQgcmVzdHJpY3Rpb24sIGluY2x1ZGluZ1xuLy8gd2l0aG91dCBsaW1pdGF0aW9uIHRoZSByaWdodHMgdG8gdXNlLCBjb3B5LCBtb2RpZnksIG1lcmdlLCBwdWJsaXNoLFxuLy8gZGlzdHJpYnV0ZSwgc3VibGljZW5zZSwgYW5kL29yIHNlbGwgY29waWVzIG9mIHRoZSBTb2Z0d2FyZSwgYW5kIHRvIHBlcm1pdFxuLy8gcGVyc29ucyB0byB3aG9tIHRoZSBTb2Z0d2FyZSBpcyBmdXJuaXNoZWQgdG8gZG8gc28sIHN1YmplY3QgdG8gdGhlXG4vLyBmb2xsb3dpbmcgY29uZGl0aW9uczpcbi8vXG4vLyBUaGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSBhbmQgdGhpcyBwZXJtaXNzaW9uIG5vdGljZSBzaGFsbCBiZSBpbmNsdWRlZFxuLy8gaW4gYWxsIGNvcGllcyBvciBzdWJzdGFudGlhbCBwb3J0aW9ucyBvZiB0aGUgU29mdHdhcmUuXG4vL1xuLy8gVEhFIFNPRlRXQVJFIElTIFBST1ZJREVEIFwiQVMgSVNcIiwgV0lUSE9VVCBXQVJSQU5UWSBPRiBBTlkgS0lORCwgRVhQUkVTU1xuLy8gT1IgSU1QTElFRCwgSU5DTFVESU5HIEJVVCBOT1QgTElNSVRFRCBUTyBUSEUgV0FSUkFOVElFUyBPRlxuLy8gTUVSQ0hBTlRBQklMSVRZLCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBTkQgTk9OSU5GUklOR0VNRU5ULiBJTlxuLy8gTk8gRVZFTlQgU0hBTEwgVEhFIEFVVEhPUlMgT1IgQ09QWVJJR0hUIEhPTERFUlMgQkUgTElBQkxFIEZPUiBBTlkgQ0xBSU0sXG4vLyBEQU1BR0VTIE9SIE9USEVSIExJQUJJTElUWSwgV0hFVEhFUiBJTiBBTiBBQ1RJT04gT0YgQ09OVFJBQ1QsIFRPUlQgT1Jcbi8vIE9USEVSV0lTRSwgQVJJU0lORyBGUk9NLCBPVVQgT0YgT1IgSU4gQ09OTkVDVElPTiBXSVRIIFRIRSBTT0ZUV0FSRSBPUiBUSEVcbi8vIFVTRSBPUiBPVEhFUiBERUFMSU5HUyBJTiBUSEUgU09GVFdBUkUuXG5cbid1c2Ugc3RyaWN0JztcblxuLyo8cmVwbGFjZW1lbnQ+Ki9cblxudmFyIEJ1ZmZlciA9IHJlcXVpcmUoJ3NhZmUtYnVmZmVyJykuQnVmZmVyO1xuLyo8L3JlcGxhY2VtZW50PiovXG5cbnZhciBpc0VuY29kaW5nID0gQnVmZmVyLmlzRW5jb2RpbmcgfHwgZnVuY3Rpb24gKGVuY29kaW5nKSB7XG4gIGVuY29kaW5nID0gJycgKyBlbmNvZGluZztcbiAgc3dpdGNoIChlbmNvZGluZyAmJiBlbmNvZGluZy50b0xvd2VyQ2FzZSgpKSB7XG4gICAgY2FzZSAnaGV4JzpjYXNlICd1dGY4JzpjYXNlICd1dGYtOCc6Y2FzZSAnYXNjaWknOmNhc2UgJ2JpbmFyeSc6Y2FzZSAnYmFzZTY0JzpjYXNlICd1Y3MyJzpjYXNlICd1Y3MtMic6Y2FzZSAndXRmMTZsZSc6Y2FzZSAndXRmLTE2bGUnOmNhc2UgJ3Jhdyc6XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICBkZWZhdWx0OlxuICAgICAgcmV0dXJuIGZhbHNlO1xuICB9XG59O1xuXG5mdW5jdGlvbiBfbm9ybWFsaXplRW5jb2RpbmcoZW5jKSB7XG4gIGlmICghZW5jKSByZXR1cm4gJ3V0ZjgnO1xuICB2YXIgcmV0cmllZDtcbiAgd2hpbGUgKHRydWUpIHtcbiAgICBzd2l0Y2ggKGVuYykge1xuICAgICAgY2FzZSAndXRmOCc6XG4gICAgICBjYXNlICd1dGYtOCc6XG4gICAgICAgIHJldHVybiAndXRmOCc7XG4gICAgICBjYXNlICd1Y3MyJzpcbiAgICAgIGNhc2UgJ3Vjcy0yJzpcbiAgICAgIGNhc2UgJ3V0ZjE2bGUnOlxuICAgICAgY2FzZSAndXRmLTE2bGUnOlxuICAgICAgICByZXR1cm4gJ3V0ZjE2bGUnO1xuICAgICAgY2FzZSAnbGF0aW4xJzpcbiAgICAgIGNhc2UgJ2JpbmFyeSc6XG4gICAgICAgIHJldHVybiAnbGF0aW4xJztcbiAgICAgIGNhc2UgJ2Jhc2U2NCc6XG4gICAgICBjYXNlICdhc2NpaSc6XG4gICAgICBjYXNlICdoZXgnOlxuICAgICAgICByZXR1cm4gZW5jO1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgaWYgKHJldHJpZWQpIHJldHVybjsgLy8gdW5kZWZpbmVkXG4gICAgICAgIGVuYyA9ICgnJyArIGVuYykudG9Mb3dlckNhc2UoKTtcbiAgICAgICAgcmV0cmllZCA9IHRydWU7XG4gICAgfVxuICB9XG59O1xuXG4vLyBEbyBub3QgY2FjaGUgYEJ1ZmZlci5pc0VuY29kaW5nYCB3aGVuIGNoZWNraW5nIGVuY29kaW5nIG5hbWVzIGFzIHNvbWVcbi8vIG1vZHVsZXMgbW9ua2V5LXBhdGNoIGl0IHRvIHN1cHBvcnQgYWRkaXRpb25hbCBlbmNvZGluZ3NcbmZ1bmN0aW9uIG5vcm1hbGl6ZUVuY29kaW5nKGVuYykge1xuICB2YXIgbmVuYyA9IF9ub3JtYWxpemVFbmNvZGluZyhlbmMpO1xuICBpZiAodHlwZW9mIG5lbmMgIT09ICdzdHJpbmcnICYmIChCdWZmZXIuaXNFbmNvZGluZyA9PT0gaXNFbmNvZGluZyB8fCAhaXNFbmNvZGluZyhlbmMpKSkgdGhyb3cgbmV3IEVycm9yKCdVbmtub3duIGVuY29kaW5nOiAnICsgZW5jKTtcbiAgcmV0dXJuIG5lbmMgfHwgZW5jO1xufVxuXG4vLyBTdHJpbmdEZWNvZGVyIHByb3ZpZGVzIGFuIGludGVyZmFjZSBmb3IgZWZmaWNpZW50bHkgc3BsaXR0aW5nIGEgc2VyaWVzIG9mXG4vLyBidWZmZXJzIGludG8gYSBzZXJpZXMgb2YgSlMgc3RyaW5ncyB3aXRob3V0IGJyZWFraW5nIGFwYXJ0IG11bHRpLWJ5dGVcbi8vIGNoYXJhY3RlcnMuXG5leHBvcnRzLlN0cmluZ0RlY29kZXIgPSBTdHJpbmdEZWNvZGVyO1xuZnVuY3Rpb24gU3RyaW5nRGVjb2RlcihlbmNvZGluZykge1xuICB0aGlzLmVuY29kaW5nID0gbm9ybWFsaXplRW5jb2RpbmcoZW5jb2RpbmcpO1xuICB2YXIgbmI7XG4gIHN3aXRjaCAodGhpcy5lbmNvZGluZykge1xuICAgIGNhc2UgJ3V0ZjE2bGUnOlxuICAgICAgdGhpcy50ZXh0ID0gdXRmMTZUZXh0O1xuICAgICAgdGhpcy5lbmQgPSB1dGYxNkVuZDtcbiAgICAgIG5iID0gNDtcbiAgICAgIGJyZWFrO1xuICAgIGNhc2UgJ3V0ZjgnOlxuICAgICAgdGhpcy5maWxsTGFzdCA9IHV0ZjhGaWxsTGFzdDtcbiAgICAgIG5iID0gNDtcbiAgICAgIGJyZWFrO1xuICAgIGNhc2UgJ2Jhc2U2NCc6XG4gICAgICB0aGlzLnRleHQgPSBiYXNlNjRUZXh0O1xuICAgICAgdGhpcy5lbmQgPSBiYXNlNjRFbmQ7XG4gICAgICBuYiA9IDM7XG4gICAgICBicmVhaztcbiAgICBkZWZhdWx0OlxuICAgICAgdGhpcy53cml0ZSA9IHNpbXBsZVdyaXRlO1xuICAgICAgdGhpcy5lbmQgPSBzaW1wbGVFbmQ7XG4gICAgICByZXR1cm47XG4gIH1cbiAgdGhpcy5sYXN0TmVlZCA9IDA7XG4gIHRoaXMubGFzdFRvdGFsID0gMDtcbiAgdGhpcy5sYXN0Q2hhciA9IEJ1ZmZlci5hbGxvY1Vuc2FmZShuYik7XG59XG5cblN0cmluZ0RlY29kZXIucHJvdG90eXBlLndyaXRlID0gZnVuY3Rpb24gKGJ1Zikge1xuICBpZiAoYnVmLmxlbmd0aCA9PT0gMCkgcmV0dXJuICcnO1xuICB2YXIgcjtcbiAgdmFyIGk7XG4gIGlmICh0aGlzLmxhc3ROZWVkKSB7XG4gICAgciA9IHRoaXMuZmlsbExhc3QoYnVmKTtcbiAgICBpZiAociA9PT0gdW5kZWZpbmVkKSByZXR1cm4gJyc7XG4gICAgaSA9IHRoaXMubGFzdE5lZWQ7XG4gICAgdGhpcy5sYXN0TmVlZCA9IDA7XG4gIH0gZWxzZSB7XG4gICAgaSA9IDA7XG4gIH1cbiAgaWYgKGkgPCBidWYubGVuZ3RoKSByZXR1cm4gciA/IHIgKyB0aGlzLnRleHQoYnVmLCBpKSA6IHRoaXMudGV4dChidWYsIGkpO1xuICByZXR1cm4gciB8fCAnJztcbn07XG5cblN0cmluZ0RlY29kZXIucHJvdG90eXBlLmVuZCA9IHV0ZjhFbmQ7XG5cbi8vIFJldHVybnMgb25seSBjb21wbGV0ZSBjaGFyYWN0ZXJzIGluIGEgQnVmZmVyXG5TdHJpbmdEZWNvZGVyLnByb3RvdHlwZS50ZXh0ID0gdXRmOFRleHQ7XG5cbi8vIEF0dGVtcHRzIHRvIGNvbXBsZXRlIGEgcGFydGlhbCBub24tVVRGLTggY2hhcmFjdGVyIHVzaW5nIGJ5dGVzIGZyb20gYSBCdWZmZXJcblN0cmluZ0RlY29kZXIucHJvdG90eXBlLmZpbGxMYXN0ID0gZnVuY3Rpb24gKGJ1Zikge1xuICBpZiAodGhpcy5sYXN0TmVlZCA8PSBidWYubGVuZ3RoKSB7XG4gICAgYnVmLmNvcHkodGhpcy5sYXN0Q2hhciwgdGhpcy5sYXN0VG90YWwgLSB0aGlzLmxhc3ROZWVkLCAwLCB0aGlzLmxhc3ROZWVkKTtcbiAgICByZXR1cm4gdGhpcy5sYXN0Q2hhci50b1N0cmluZyh0aGlzLmVuY29kaW5nLCAwLCB0aGlzLmxhc3RUb3RhbCk7XG4gIH1cbiAgYnVmLmNvcHkodGhpcy5sYXN0Q2hhciwgdGhpcy5sYXN0VG90YWwgLSB0aGlzLmxhc3ROZWVkLCAwLCBidWYubGVuZ3RoKTtcbiAgdGhpcy5sYXN0TmVlZCAtPSBidWYubGVuZ3RoO1xufTtcblxuLy8gQ2hlY2tzIHRoZSB0eXBlIG9mIGEgVVRGLTggYnl0ZSwgd2hldGhlciBpdCdzIEFTQ0lJLCBhIGxlYWRpbmcgYnl0ZSwgb3IgYVxuLy8gY29udGludWF0aW9uIGJ5dGUuIElmIGFuIGludmFsaWQgYnl0ZSBpcyBkZXRlY3RlZCwgLTIgaXMgcmV0dXJuZWQuXG5mdW5jdGlvbiB1dGY4Q2hlY2tCeXRlKGJ5dGUpIHtcbiAgaWYgKGJ5dGUgPD0gMHg3RikgcmV0dXJuIDA7ZWxzZSBpZiAoYnl0ZSA+PiA1ID09PSAweDA2KSByZXR1cm4gMjtlbHNlIGlmIChieXRlID4+IDQgPT09IDB4MEUpIHJldHVybiAzO2Vsc2UgaWYgKGJ5dGUgPj4gMyA9PT0gMHgxRSkgcmV0dXJuIDQ7XG4gIHJldHVybiBieXRlID4+IDYgPT09IDB4MDIgPyAtMSA6IC0yO1xufVxuXG4vLyBDaGVja3MgYXQgbW9zdCAzIGJ5dGVzIGF0IHRoZSBlbmQgb2YgYSBCdWZmZXIgaW4gb3JkZXIgdG8gZGV0ZWN0IGFuXG4vLyBpbmNvbXBsZXRlIG11bHRpLWJ5dGUgVVRGLTggY2hhcmFjdGVyLiBUaGUgdG90YWwgbnVtYmVyIG9mIGJ5dGVzICgyLCAzLCBvciA0KVxuLy8gbmVlZGVkIHRvIGNvbXBsZXRlIHRoZSBVVEYtOCBjaGFyYWN0ZXIgKGlmIGFwcGxpY2FibGUpIGFyZSByZXR1cm5lZC5cbmZ1bmN0aW9uIHV0ZjhDaGVja0luY29tcGxldGUoc2VsZiwgYnVmLCBpKSB7XG4gIHZhciBqID0gYnVmLmxlbmd0aCAtIDE7XG4gIGlmIChqIDwgaSkgcmV0dXJuIDA7XG4gIHZhciBuYiA9IHV0ZjhDaGVja0J5dGUoYnVmW2pdKTtcbiAgaWYgKG5iID49IDApIHtcbiAgICBpZiAobmIgPiAwKSBzZWxmLmxhc3ROZWVkID0gbmIgLSAxO1xuICAgIHJldHVybiBuYjtcbiAgfVxuICBpZiAoLS1qIDwgaSB8fCBuYiA9PT0gLTIpIHJldHVybiAwO1xuICBuYiA9IHV0ZjhDaGVja0J5dGUoYnVmW2pdKTtcbiAgaWYgKG5iID49IDApIHtcbiAgICBpZiAobmIgPiAwKSBzZWxmLmxhc3ROZWVkID0gbmIgLSAyO1xuICAgIHJldHVybiBuYjtcbiAgfVxuICBpZiAoLS1qIDwgaSB8fCBuYiA9PT0gLTIpIHJldHVybiAwO1xuICBuYiA9IHV0ZjhDaGVja0J5dGUoYnVmW2pdKTtcbiAgaWYgKG5iID49IDApIHtcbiAgICBpZiAobmIgPiAwKSB7XG4gICAgICBpZiAobmIgPT09IDIpIG5iID0gMDtlbHNlIHNlbGYubGFzdE5lZWQgPSBuYiAtIDM7XG4gICAgfVxuICAgIHJldHVybiBuYjtcbiAgfVxuICByZXR1cm4gMDtcbn1cblxuLy8gVmFsaWRhdGVzIGFzIG1hbnkgY29udGludWF0aW9uIGJ5dGVzIGZvciBhIG11bHRpLWJ5dGUgVVRGLTggY2hhcmFjdGVyIGFzXG4vLyBuZWVkZWQgb3IgYXJlIGF2YWlsYWJsZS4gSWYgd2Ugc2VlIGEgbm9uLWNvbnRpbnVhdGlvbiBieXRlIHdoZXJlIHdlIGV4cGVjdFxuLy8gb25lLCB3ZSBcInJlcGxhY2VcIiB0aGUgdmFsaWRhdGVkIGNvbnRpbnVhdGlvbiBieXRlcyB3ZSd2ZSBzZWVuIHNvIGZhciB3aXRoXG4vLyBhIHNpbmdsZSBVVEYtOCByZXBsYWNlbWVudCBjaGFyYWN0ZXIgKCdcXHVmZmZkJyksIHRvIG1hdGNoIHY4J3MgVVRGLTggZGVjb2Rpbmdcbi8vIGJlaGF2aW9yLiBUaGUgY29udGludWF0aW9uIGJ5dGUgY2hlY2sgaXMgaW5jbHVkZWQgdGhyZWUgdGltZXMgaW4gdGhlIGNhc2Vcbi8vIHdoZXJlIGFsbCBvZiB0aGUgY29udGludWF0aW9uIGJ5dGVzIGZvciBhIGNoYXJhY3RlciBleGlzdCBpbiB0aGUgc2FtZSBidWZmZXIuXG4vLyBJdCBpcyBhbHNvIGRvbmUgdGhpcyB3YXkgYXMgYSBzbGlnaHQgcGVyZm9ybWFuY2UgaW5jcmVhc2UgaW5zdGVhZCBvZiB1c2luZyBhXG4vLyBsb29wLlxuZnVuY3Rpb24gdXRmOENoZWNrRXh0cmFCeXRlcyhzZWxmLCBidWYsIHApIHtcbiAgaWYgKChidWZbMF0gJiAweEMwKSAhPT0gMHg4MCkge1xuICAgIHNlbGYubGFzdE5lZWQgPSAwO1xuICAgIHJldHVybiAnXFx1ZmZmZCc7XG4gIH1cbiAgaWYgKHNlbGYubGFzdE5lZWQgPiAxICYmIGJ1Zi5sZW5ndGggPiAxKSB7XG4gICAgaWYgKChidWZbMV0gJiAweEMwKSAhPT0gMHg4MCkge1xuICAgICAgc2VsZi5sYXN0TmVlZCA9IDE7XG4gICAgICByZXR1cm4gJ1xcdWZmZmQnO1xuICAgIH1cbiAgICBpZiAoc2VsZi5sYXN0TmVlZCA+IDIgJiYgYnVmLmxlbmd0aCA+IDIpIHtcbiAgICAgIGlmICgoYnVmWzJdICYgMHhDMCkgIT09IDB4ODApIHtcbiAgICAgICAgc2VsZi5sYXN0TmVlZCA9IDI7XG4gICAgICAgIHJldHVybiAnXFx1ZmZmZCc7XG4gICAgICB9XG4gICAgfVxuICB9XG59XG5cbi8vIEF0dGVtcHRzIHRvIGNvbXBsZXRlIGEgbXVsdGktYnl0ZSBVVEYtOCBjaGFyYWN0ZXIgdXNpbmcgYnl0ZXMgZnJvbSBhIEJ1ZmZlci5cbmZ1bmN0aW9uIHV0ZjhGaWxsTGFzdChidWYpIHtcbiAgdmFyIHAgPSB0aGlzLmxhc3RUb3RhbCAtIHRoaXMubGFzdE5lZWQ7XG4gIHZhciByID0gdXRmOENoZWNrRXh0cmFCeXRlcyh0aGlzLCBidWYsIHApO1xuICBpZiAociAhPT0gdW5kZWZpbmVkKSByZXR1cm4gcjtcbiAgaWYgKHRoaXMubGFzdE5lZWQgPD0gYnVmLmxlbmd0aCkge1xuICAgIGJ1Zi5jb3B5KHRoaXMubGFzdENoYXIsIHAsIDAsIHRoaXMubGFzdE5lZWQpO1xuICAgIHJldHVybiB0aGlzLmxhc3RDaGFyLnRvU3RyaW5nKHRoaXMuZW5jb2RpbmcsIDAsIHRoaXMubGFzdFRvdGFsKTtcbiAgfVxuICBidWYuY29weSh0aGlzLmxhc3RDaGFyLCBwLCAwLCBidWYubGVuZ3RoKTtcbiAgdGhpcy5sYXN0TmVlZCAtPSBidWYubGVuZ3RoO1xufVxuXG4vLyBSZXR1cm5zIGFsbCBjb21wbGV0ZSBVVEYtOCBjaGFyYWN0ZXJzIGluIGEgQnVmZmVyLiBJZiB0aGUgQnVmZmVyIGVuZGVkIG9uIGFcbi8vIHBhcnRpYWwgY2hhcmFjdGVyLCB0aGUgY2hhcmFjdGVyJ3MgYnl0ZXMgYXJlIGJ1ZmZlcmVkIHVudGlsIHRoZSByZXF1aXJlZFxuLy8gbnVtYmVyIG9mIGJ5dGVzIGFyZSBhdmFpbGFibGUuXG5mdW5jdGlvbiB1dGY4VGV4dChidWYsIGkpIHtcbiAgdmFyIHRvdGFsID0gdXRmOENoZWNrSW5jb21wbGV0ZSh0aGlzLCBidWYsIGkpO1xuICBpZiAoIXRoaXMubGFzdE5lZWQpIHJldHVybiBidWYudG9TdHJpbmcoJ3V0ZjgnLCBpKTtcbiAgdGhpcy5sYXN0VG90YWwgPSB0b3RhbDtcbiAgdmFyIGVuZCA9IGJ1Zi5sZW5ndGggLSAodG90YWwgLSB0aGlzLmxhc3ROZWVkKTtcbiAgYnVmLmNvcHkodGhpcy5sYXN0Q2hhciwgMCwgZW5kKTtcbiAgcmV0dXJuIGJ1Zi50b1N0cmluZygndXRmOCcsIGksIGVuZCk7XG59XG5cbi8vIEZvciBVVEYtOCwgYSByZXBsYWNlbWVudCBjaGFyYWN0ZXIgaXMgYWRkZWQgd2hlbiBlbmRpbmcgb24gYSBwYXJ0aWFsXG4vLyBjaGFyYWN0ZXIuXG5mdW5jdGlvbiB1dGY4RW5kKGJ1Zikge1xuICB2YXIgciA9IGJ1ZiAmJiBidWYubGVuZ3RoID8gdGhpcy53cml0ZShidWYpIDogJyc7XG4gIGlmICh0aGlzLmxhc3ROZWVkKSByZXR1cm4gciArICdcXHVmZmZkJztcbiAgcmV0dXJuIHI7XG59XG5cbi8vIFVURi0xNkxFIHR5cGljYWxseSBuZWVkcyB0d28gYnl0ZXMgcGVyIGNoYXJhY3RlciwgYnV0IGV2ZW4gaWYgd2UgaGF2ZSBhbiBldmVuXG4vLyBudW1iZXIgb2YgYnl0ZXMgYXZhaWxhYmxlLCB3ZSBuZWVkIHRvIGNoZWNrIGlmIHdlIGVuZCBvbiBhIGxlYWRpbmcvaGlnaFxuLy8gc3Vycm9nYXRlLiBJbiB0aGF0IGNhc2UsIHdlIG5lZWQgdG8gd2FpdCBmb3IgdGhlIG5leHQgdHdvIGJ5dGVzIGluIG9yZGVyIHRvXG4vLyBkZWNvZGUgdGhlIGxhc3QgY2hhcmFjdGVyIHByb3Blcmx5LlxuZnVuY3Rpb24gdXRmMTZUZXh0KGJ1ZiwgaSkge1xuICBpZiAoKGJ1Zi5sZW5ndGggLSBpKSAlIDIgPT09IDApIHtcbiAgICB2YXIgciA9IGJ1Zi50b1N0cmluZygndXRmMTZsZScsIGkpO1xuICAgIGlmIChyKSB7XG4gICAgICB2YXIgYyA9IHIuY2hhckNvZGVBdChyLmxlbmd0aCAtIDEpO1xuICAgICAgaWYgKGMgPj0gMHhEODAwICYmIGMgPD0gMHhEQkZGKSB7XG4gICAgICAgIHRoaXMubGFzdE5lZWQgPSAyO1xuICAgICAgICB0aGlzLmxhc3RUb3RhbCA9IDQ7XG4gICAgICAgIHRoaXMubGFzdENoYXJbMF0gPSBidWZbYnVmLmxlbmd0aCAtIDJdO1xuICAgICAgICB0aGlzLmxhc3RDaGFyWzFdID0gYnVmW2J1Zi5sZW5ndGggLSAxXTtcbiAgICAgICAgcmV0dXJuIHIuc2xpY2UoMCwgLTEpO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gcjtcbiAgfVxuICB0aGlzLmxhc3ROZWVkID0gMTtcbiAgdGhpcy5sYXN0VG90YWwgPSAyO1xuICB0aGlzLmxhc3RDaGFyWzBdID0gYnVmW2J1Zi5sZW5ndGggLSAxXTtcbiAgcmV0dXJuIGJ1Zi50b1N0cmluZygndXRmMTZsZScsIGksIGJ1Zi5sZW5ndGggLSAxKTtcbn1cblxuLy8gRm9yIFVURi0xNkxFIHdlIGRvIG5vdCBleHBsaWNpdGx5IGFwcGVuZCBzcGVjaWFsIHJlcGxhY2VtZW50IGNoYXJhY3RlcnMgaWYgd2Vcbi8vIGVuZCBvbiBhIHBhcnRpYWwgY2hhcmFjdGVyLCB3ZSBzaW1wbHkgbGV0IHY4IGhhbmRsZSB0aGF0LlxuZnVuY3Rpb24gdXRmMTZFbmQoYnVmKSB7XG4gIHZhciByID0gYnVmICYmIGJ1Zi5sZW5ndGggPyB0aGlzLndyaXRlKGJ1ZikgOiAnJztcbiAgaWYgKHRoaXMubGFzdE5lZWQpIHtcbiAgICB2YXIgZW5kID0gdGhpcy5sYXN0VG90YWwgLSB0aGlzLmxhc3ROZWVkO1xuICAgIHJldHVybiByICsgdGhpcy5sYXN0Q2hhci50b1N0cmluZygndXRmMTZsZScsIDAsIGVuZCk7XG4gIH1cbiAgcmV0dXJuIHI7XG59XG5cbmZ1bmN0aW9uIGJhc2U2NFRleHQoYnVmLCBpKSB7XG4gIHZhciBuID0gKGJ1Zi5sZW5ndGggLSBpKSAlIDM7XG4gIGlmIChuID09PSAwKSByZXR1cm4gYnVmLnRvU3RyaW5nKCdiYXNlNjQnLCBpKTtcbiAgdGhpcy5sYXN0TmVlZCA9IDMgLSBuO1xuICB0aGlzLmxhc3RUb3RhbCA9IDM7XG4gIGlmIChuID09PSAxKSB7XG4gICAgdGhpcy5sYXN0Q2hhclswXSA9IGJ1ZltidWYubGVuZ3RoIC0gMV07XG4gIH0gZWxzZSB7XG4gICAgdGhpcy5sYXN0Q2hhclswXSA9IGJ1ZltidWYubGVuZ3RoIC0gMl07XG4gICAgdGhpcy5sYXN0Q2hhclsxXSA9IGJ1ZltidWYubGVuZ3RoIC0gMV07XG4gIH1cbiAgcmV0dXJuIGJ1Zi50b1N0cmluZygnYmFzZTY0JywgaSwgYnVmLmxlbmd0aCAtIG4pO1xufVxuXG5mdW5jdGlvbiBiYXNlNjRFbmQoYnVmKSB7XG4gIHZhciByID0gYnVmICYmIGJ1Zi5sZW5ndGggPyB0aGlzLndyaXRlKGJ1ZikgOiAnJztcbiAgaWYgKHRoaXMubGFzdE5lZWQpIHJldHVybiByICsgdGhpcy5sYXN0Q2hhci50b1N0cmluZygnYmFzZTY0JywgMCwgMyAtIHRoaXMubGFzdE5lZWQpO1xuICByZXR1cm4gcjtcbn1cblxuLy8gUGFzcyBieXRlcyBvbiB0aHJvdWdoIGZvciBzaW5nbGUtYnl0ZSBlbmNvZGluZ3MgKGUuZy4gYXNjaWksIGxhdGluMSwgaGV4KVxuZnVuY3Rpb24gc2ltcGxlV3JpdGUoYnVmKSB7XG4gIHJldHVybiBidWYudG9TdHJpbmcodGhpcy5lbmNvZGluZyk7XG59XG5cbmZ1bmN0aW9uIHNpbXBsZUVuZChidWYpIHtcbiAgcmV0dXJuIGJ1ZiAmJiBidWYubGVuZ3RoID8gdGhpcy53cml0ZShidWYpIDogJyc7XG59IiwiLy8gUG9ydGVkIGZyb20gaHR0cHM6Ly9naXRodWIuY29tL21hZmludG9zaC9lbmQtb2Ytc3RyZWFtIHdpdGhcbi8vIHBlcm1pc3Npb24gZnJvbSB0aGUgYXV0aG9yLCBNYXRoaWFzIEJ1dXMgKEBtYWZpbnRvc2gpLlxuXG4ndXNlIHN0cmljdCc7XG5cbnZhciBFUlJfU1RSRUFNX1BSRU1BVFVSRV9DTE9TRSA9IHJlcXVpcmUoJy4uLy4uLy4uL2Vycm9ycycpLmNvZGVzLkVSUl9TVFJFQU1fUFJFTUFUVVJFX0NMT1NFO1xuZnVuY3Rpb24gb25jZShjYWxsYmFjaykge1xuICB2YXIgY2FsbGVkID0gZmFsc2U7XG4gIHJldHVybiBmdW5jdGlvbiAoKSB7XG4gICAgaWYgKGNhbGxlZCkgcmV0dXJuO1xuICAgIGNhbGxlZCA9IHRydWU7XG4gICAgZm9yICh2YXIgX2xlbiA9IGFyZ3VtZW50cy5sZW5ndGgsIGFyZ3MgPSBuZXcgQXJyYXkoX2xlbiksIF9rZXkgPSAwOyBfa2V5IDwgX2xlbjsgX2tleSsrKSB7XG4gICAgICBhcmdzW19rZXldID0gYXJndW1lbnRzW19rZXldO1xuICAgIH1cbiAgICBjYWxsYmFjay5hcHBseSh0aGlzLCBhcmdzKTtcbiAgfTtcbn1cbmZ1bmN0aW9uIG5vb3AoKSB7fVxuZnVuY3Rpb24gaXNSZXF1ZXN0KHN0cmVhbSkge1xuICByZXR1cm4gc3RyZWFtLnNldEhlYWRlciAmJiB0eXBlb2Ygc3RyZWFtLmFib3J0ID09PSAnZnVuY3Rpb24nO1xufVxuZnVuY3Rpb24gZW9zKHN0cmVhbSwgb3B0cywgY2FsbGJhY2spIHtcbiAgaWYgKHR5cGVvZiBvcHRzID09PSAnZnVuY3Rpb24nKSByZXR1cm4gZW9zKHN0cmVhbSwgbnVsbCwgb3B0cyk7XG4gIGlmICghb3B0cykgb3B0cyA9IHt9O1xuICBjYWxsYmFjayA9IG9uY2UoY2FsbGJhY2sgfHwgbm9vcCk7XG4gIHZhciByZWFkYWJsZSA9IG9wdHMucmVhZGFibGUgfHwgb3B0cy5yZWFkYWJsZSAhPT0gZmFsc2UgJiYgc3RyZWFtLnJlYWRhYmxlO1xuICB2YXIgd3JpdGFibGUgPSBvcHRzLndyaXRhYmxlIHx8IG9wdHMud3JpdGFibGUgIT09IGZhbHNlICYmIHN0cmVhbS53cml0YWJsZTtcbiAgdmFyIG9ubGVnYWN5ZmluaXNoID0gZnVuY3Rpb24gb25sZWdhY3lmaW5pc2goKSB7XG4gICAgaWYgKCFzdHJlYW0ud3JpdGFibGUpIG9uZmluaXNoKCk7XG4gIH07XG4gIHZhciB3cml0YWJsZUVuZGVkID0gc3RyZWFtLl93cml0YWJsZVN0YXRlICYmIHN0cmVhbS5fd3JpdGFibGVTdGF0ZS5maW5pc2hlZDtcbiAgdmFyIG9uZmluaXNoID0gZnVuY3Rpb24gb25maW5pc2goKSB7XG4gICAgd3JpdGFibGUgPSBmYWxzZTtcbiAgICB3cml0YWJsZUVuZGVkID0gdHJ1ZTtcbiAgICBpZiAoIXJlYWRhYmxlKSBjYWxsYmFjay5jYWxsKHN0cmVhbSk7XG4gIH07XG4gIHZhciByZWFkYWJsZUVuZGVkID0gc3RyZWFtLl9yZWFkYWJsZVN0YXRlICYmIHN0cmVhbS5fcmVhZGFibGVTdGF0ZS5lbmRFbWl0dGVkO1xuICB2YXIgb25lbmQgPSBmdW5jdGlvbiBvbmVuZCgpIHtcbiAgICByZWFkYWJsZSA9IGZhbHNlO1xuICAgIHJlYWRhYmxlRW5kZWQgPSB0cnVlO1xuICAgIGlmICghd3JpdGFibGUpIGNhbGxiYWNrLmNhbGwoc3RyZWFtKTtcbiAgfTtcbiAgdmFyIG9uZXJyb3IgPSBmdW5jdGlvbiBvbmVycm9yKGVycikge1xuICAgIGNhbGxiYWNrLmNhbGwoc3RyZWFtLCBlcnIpO1xuICB9O1xuICB2YXIgb25jbG9zZSA9IGZ1bmN0aW9uIG9uY2xvc2UoKSB7XG4gICAgdmFyIGVycjtcbiAgICBpZiAocmVhZGFibGUgJiYgIXJlYWRhYmxlRW5kZWQpIHtcbiAgICAgIGlmICghc3RyZWFtLl9yZWFkYWJsZVN0YXRlIHx8ICFzdHJlYW0uX3JlYWRhYmxlU3RhdGUuZW5kZWQpIGVyciA9IG5ldyBFUlJfU1RSRUFNX1BSRU1BVFVSRV9DTE9TRSgpO1xuICAgICAgcmV0dXJuIGNhbGxiYWNrLmNhbGwoc3RyZWFtLCBlcnIpO1xuICAgIH1cbiAgICBpZiAod3JpdGFibGUgJiYgIXdyaXRhYmxlRW5kZWQpIHtcbiAgICAgIGlmICghc3RyZWFtLl93cml0YWJsZVN0YXRlIHx8ICFzdHJlYW0uX3dyaXRhYmxlU3RhdGUuZW5kZWQpIGVyciA9IG5ldyBFUlJfU1RSRUFNX1BSRU1BVFVSRV9DTE9TRSgpO1xuICAgICAgcmV0dXJuIGNhbGxiYWNrLmNhbGwoc3RyZWFtLCBlcnIpO1xuICAgIH1cbiAgfTtcbiAgdmFyIG9ucmVxdWVzdCA9IGZ1bmN0aW9uIG9ucmVxdWVzdCgpIHtcbiAgICBzdHJlYW0ucmVxLm9uKCdmaW5pc2gnLCBvbmZpbmlzaCk7XG4gIH07XG4gIGlmIChpc1JlcXVlc3Qoc3RyZWFtKSkge1xuICAgIHN0cmVhbS5vbignY29tcGxldGUnLCBvbmZpbmlzaCk7XG4gICAgc3RyZWFtLm9uKCdhYm9ydCcsIG9uY2xvc2UpO1xuICAgIGlmIChzdHJlYW0ucmVxKSBvbnJlcXVlc3QoKTtlbHNlIHN0cmVhbS5vbigncmVxdWVzdCcsIG9ucmVxdWVzdCk7XG4gIH0gZWxzZSBpZiAod3JpdGFibGUgJiYgIXN0cmVhbS5fd3JpdGFibGVTdGF0ZSkge1xuICAgIC8vIGxlZ2FjeSBzdHJlYW1zXG4gICAgc3RyZWFtLm9uKCdlbmQnLCBvbmxlZ2FjeWZpbmlzaCk7XG4gICAgc3RyZWFtLm9uKCdjbG9zZScsIG9ubGVnYWN5ZmluaXNoKTtcbiAgfVxuICBzdHJlYW0ub24oJ2VuZCcsIG9uZW5kKTtcbiAgc3RyZWFtLm9uKCdmaW5pc2gnLCBvbmZpbmlzaCk7XG4gIGlmIChvcHRzLmVycm9yICE9PSBmYWxzZSkgc3RyZWFtLm9uKCdlcnJvcicsIG9uZXJyb3IpO1xuICBzdHJlYW0ub24oJ2Nsb3NlJywgb25jbG9zZSk7XG4gIHJldHVybiBmdW5jdGlvbiAoKSB7XG4gICAgc3RyZWFtLnJlbW92ZUxpc3RlbmVyKCdjb21wbGV0ZScsIG9uZmluaXNoKTtcbiAgICBzdHJlYW0ucmVtb3ZlTGlzdGVuZXIoJ2Fib3J0Jywgb25jbG9zZSk7XG4gICAgc3RyZWFtLnJlbW92ZUxpc3RlbmVyKCdyZXF1ZXN0Jywgb25yZXF1ZXN0KTtcbiAgICBpZiAoc3RyZWFtLnJlcSkgc3RyZWFtLnJlcS5yZW1vdmVMaXN0ZW5lcignZmluaXNoJywgb25maW5pc2gpO1xuICAgIHN0cmVhbS5yZW1vdmVMaXN0ZW5lcignZW5kJywgb25sZWdhY3lmaW5pc2gpO1xuICAgIHN0cmVhbS5yZW1vdmVMaXN0ZW5lcignY2xvc2UnLCBvbmxlZ2FjeWZpbmlzaCk7XG4gICAgc3RyZWFtLnJlbW92ZUxpc3RlbmVyKCdmaW5pc2gnLCBvbmZpbmlzaCk7XG4gICAgc3RyZWFtLnJlbW92ZUxpc3RlbmVyKCdlbmQnLCBvbmVuZCk7XG4gICAgc3RyZWFtLnJlbW92ZUxpc3RlbmVyKCdlcnJvcicsIG9uZXJyb3IpO1xuICAgIHN0cmVhbS5yZW1vdmVMaXN0ZW5lcignY2xvc2UnLCBvbmNsb3NlKTtcbiAgfTtcbn1cbm1vZHVsZS5leHBvcnRzID0gZW9zOyIsIid1c2Ugc3RyaWN0JztcblxudmFyIF9PYmplY3Qkc2V0UHJvdG90eXBlTztcbmZ1bmN0aW9uIF9kZWZpbmVQcm9wZXJ0eShvYmosIGtleSwgdmFsdWUpIHsga2V5ID0gX3RvUHJvcGVydHlLZXkoa2V5KTsgaWYgKGtleSBpbiBvYmopIHsgT2JqZWN0LmRlZmluZVByb3BlcnR5KG9iaiwga2V5LCB7IHZhbHVlOiB2YWx1ZSwgZW51bWVyYWJsZTogdHJ1ZSwgY29uZmlndXJhYmxlOiB0cnVlLCB3cml0YWJsZTogdHJ1ZSB9KTsgfSBlbHNlIHsgb2JqW2tleV0gPSB2YWx1ZTsgfSByZXR1cm4gb2JqOyB9XG5mdW5jdGlvbiBfdG9Qcm9wZXJ0eUtleShhcmcpIHsgdmFyIGtleSA9IF90b1ByaW1pdGl2ZShhcmcsIFwic3RyaW5nXCIpOyByZXR1cm4gdHlwZW9mIGtleSA9PT0gXCJzeW1ib2xcIiA/IGtleSA6IFN0cmluZyhrZXkpOyB9XG5mdW5jdGlvbiBfdG9QcmltaXRpdmUoaW5wdXQsIGhpbnQpIHsgaWYgKHR5cGVvZiBpbnB1dCAhPT0gXCJvYmplY3RcIiB8fCBpbnB1dCA9PT0gbnVsbCkgcmV0dXJuIGlucHV0OyB2YXIgcHJpbSA9IGlucHV0W1N5bWJvbC50b1ByaW1pdGl2ZV07IGlmIChwcmltICE9PSB1bmRlZmluZWQpIHsgdmFyIHJlcyA9IHByaW0uY2FsbChpbnB1dCwgaGludCB8fCBcImRlZmF1bHRcIik7IGlmICh0eXBlb2YgcmVzICE9PSBcIm9iamVjdFwiKSByZXR1cm4gcmVzOyB0aHJvdyBuZXcgVHlwZUVycm9yKFwiQEB0b1ByaW1pdGl2ZSBtdXN0IHJldHVybiBhIHByaW1pdGl2ZSB2YWx1ZS5cIik7IH0gcmV0dXJuIChoaW50ID09PSBcInN0cmluZ1wiID8gU3RyaW5nIDogTnVtYmVyKShpbnB1dCk7IH1cbnZhciBmaW5pc2hlZCA9IHJlcXVpcmUoJy4vZW5kLW9mLXN0cmVhbScpO1xudmFyIGtMYXN0UmVzb2x2ZSA9IFN5bWJvbCgnbGFzdFJlc29sdmUnKTtcbnZhciBrTGFzdFJlamVjdCA9IFN5bWJvbCgnbGFzdFJlamVjdCcpO1xudmFyIGtFcnJvciA9IFN5bWJvbCgnZXJyb3InKTtcbnZhciBrRW5kZWQgPSBTeW1ib2woJ2VuZGVkJyk7XG52YXIga0xhc3RQcm9taXNlID0gU3ltYm9sKCdsYXN0UHJvbWlzZScpO1xudmFyIGtIYW5kbGVQcm9taXNlID0gU3ltYm9sKCdoYW5kbGVQcm9taXNlJyk7XG52YXIga1N0cmVhbSA9IFN5bWJvbCgnc3RyZWFtJyk7XG5mdW5jdGlvbiBjcmVhdGVJdGVyUmVzdWx0KHZhbHVlLCBkb25lKSB7XG4gIHJldHVybiB7XG4gICAgdmFsdWU6IHZhbHVlLFxuICAgIGRvbmU6IGRvbmVcbiAgfTtcbn1cbmZ1bmN0aW9uIHJlYWRBbmRSZXNvbHZlKGl0ZXIpIHtcbiAgdmFyIHJlc29sdmUgPSBpdGVyW2tMYXN0UmVzb2x2ZV07XG4gIGlmIChyZXNvbHZlICE9PSBudWxsKSB7XG4gICAgdmFyIGRhdGEgPSBpdGVyW2tTdHJlYW1dLnJlYWQoKTtcbiAgICAvLyB3ZSBkZWZlciBpZiBkYXRhIGlzIG51bGxcbiAgICAvLyB3ZSBjYW4gYmUgZXhwZWN0aW5nIGVpdGhlciAnZW5kJyBvclxuICAgIC8vICdlcnJvcidcbiAgICBpZiAoZGF0YSAhPT0gbnVsbCkge1xuICAgICAgaXRlcltrTGFzdFByb21pc2VdID0gbnVsbDtcbiAgICAgIGl0ZXJba0xhc3RSZXNvbHZlXSA9IG51bGw7XG4gICAgICBpdGVyW2tMYXN0UmVqZWN0XSA9IG51bGw7XG4gICAgICByZXNvbHZlKGNyZWF0ZUl0ZXJSZXN1bHQoZGF0YSwgZmFsc2UpKTtcbiAgICB9XG4gIH1cbn1cbmZ1bmN0aW9uIG9uUmVhZGFibGUoaXRlcikge1xuICAvLyB3ZSB3YWl0IGZvciB0aGUgbmV4dCB0aWNrLCBiZWNhdXNlIGl0IG1pZ2h0XG4gIC8vIGVtaXQgYW4gZXJyb3Igd2l0aCBwcm9jZXNzLm5leHRUaWNrXG4gIHByb2Nlc3MubmV4dFRpY2socmVhZEFuZFJlc29sdmUsIGl0ZXIpO1xufVxuZnVuY3Rpb24gd3JhcEZvck5leHQobGFzdFByb21pc2UsIGl0ZXIpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uIChyZXNvbHZlLCByZWplY3QpIHtcbiAgICBsYXN0UHJvbWlzZS50aGVuKGZ1bmN0aW9uICgpIHtcbiAgICAgIGlmIChpdGVyW2tFbmRlZF0pIHtcbiAgICAgICAgcmVzb2x2ZShjcmVhdGVJdGVyUmVzdWx0KHVuZGVmaW5lZCwgdHJ1ZSkpO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICBpdGVyW2tIYW5kbGVQcm9taXNlXShyZXNvbHZlLCByZWplY3QpO1xuICAgIH0sIHJlamVjdCk7XG4gIH07XG59XG52YXIgQXN5bmNJdGVyYXRvclByb3RvdHlwZSA9IE9iamVjdC5nZXRQcm90b3R5cGVPZihmdW5jdGlvbiAoKSB7fSk7XG52YXIgUmVhZGFibGVTdHJlYW1Bc3luY0l0ZXJhdG9yUHJvdG90eXBlID0gT2JqZWN0LnNldFByb3RvdHlwZU9mKChfT2JqZWN0JHNldFByb3RvdHlwZU8gPSB7XG4gIGdldCBzdHJlYW0oKSB7XG4gICAgcmV0dXJuIHRoaXNba1N0cmVhbV07XG4gIH0sXG4gIG5leHQ6IGZ1bmN0aW9uIG5leHQoKSB7XG4gICAgdmFyIF90aGlzID0gdGhpcztcbiAgICAvLyBpZiB3ZSBoYXZlIGRldGVjdGVkIGFuIGVycm9yIGluIHRoZSBtZWFud2hpbGVcbiAgICAvLyByZWplY3Qgc3RyYWlnaHQgYXdheVxuICAgIHZhciBlcnJvciA9IHRoaXNba0Vycm9yXTtcbiAgICBpZiAoZXJyb3IgIT09IG51bGwpIHtcbiAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdChlcnJvcik7XG4gICAgfVxuICAgIGlmICh0aGlzW2tFbmRlZF0pIHtcbiAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoY3JlYXRlSXRlclJlc3VsdCh1bmRlZmluZWQsIHRydWUpKTtcbiAgICB9XG4gICAgaWYgKHRoaXNba1N0cmVhbV0uZGVzdHJveWVkKSB7XG4gICAgICAvLyBXZSBuZWVkIHRvIGRlZmVyIHZpYSBuZXh0VGljayBiZWNhdXNlIGlmIC5kZXN0cm95KGVycikgaXNcbiAgICAgIC8vIGNhbGxlZCwgdGhlIGVycm9yIHdpbGwgYmUgZW1pdHRlZCB2aWEgbmV4dFRpY2ssIGFuZFxuICAgICAgLy8gd2UgY2Fubm90IGd1YXJhbnRlZSB0aGF0IHRoZXJlIGlzIG5vIGVycm9yIGxpbmdlcmluZyBhcm91bmRcbiAgICAgIC8vIHdhaXRpbmcgdG8gYmUgZW1pdHRlZC5cbiAgICAgIHJldHVybiBuZXcgUHJvbWlzZShmdW5jdGlvbiAocmVzb2x2ZSwgcmVqZWN0KSB7XG4gICAgICAgIHByb2Nlc3MubmV4dFRpY2soZnVuY3Rpb24gKCkge1xuICAgICAgICAgIGlmIChfdGhpc1trRXJyb3JdKSB7XG4gICAgICAgICAgICByZWplY3QoX3RoaXNba0Vycm9yXSk7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJlc29sdmUoY3JlYXRlSXRlclJlc3VsdCh1bmRlZmluZWQsIHRydWUpKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgfSk7XG4gICAgfVxuXG4gICAgLy8gaWYgd2UgaGF2ZSBtdWx0aXBsZSBuZXh0KCkgY2FsbHNcbiAgICAvLyB3ZSB3aWxsIHdhaXQgZm9yIHRoZSBwcmV2aW91cyBQcm9taXNlIHRvIGZpbmlzaFxuICAgIC8vIHRoaXMgbG9naWMgaXMgb3B0aW1pemVkIHRvIHN1cHBvcnQgZm9yIGF3YWl0IGxvb3BzLFxuICAgIC8vIHdoZXJlIG5leHQoKSBpcyBvbmx5IGNhbGxlZCBvbmNlIGF0IGEgdGltZVxuICAgIHZhciBsYXN0UHJvbWlzZSA9IHRoaXNba0xhc3RQcm9taXNlXTtcbiAgICB2YXIgcHJvbWlzZTtcbiAgICBpZiAobGFzdFByb21pc2UpIHtcbiAgICAgIHByb21pc2UgPSBuZXcgUHJvbWlzZSh3cmFwRm9yTmV4dChsYXN0UHJvbWlzZSwgdGhpcykpO1xuICAgIH0gZWxzZSB7XG4gICAgICAvLyBmYXN0IHBhdGggbmVlZGVkIHRvIHN1cHBvcnQgbXVsdGlwbGUgdGhpcy5wdXNoKClcbiAgICAgIC8vIHdpdGhvdXQgdHJpZ2dlcmluZyB0aGUgbmV4dCgpIHF1ZXVlXG4gICAgICB2YXIgZGF0YSA9IHRoaXNba1N0cmVhbV0ucmVhZCgpO1xuICAgICAgaWYgKGRhdGEgIT09IG51bGwpIHtcbiAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZShjcmVhdGVJdGVyUmVzdWx0KGRhdGEsIGZhbHNlKSk7XG4gICAgICB9XG4gICAgICBwcm9taXNlID0gbmV3IFByb21pc2UodGhpc1trSGFuZGxlUHJvbWlzZV0pO1xuICAgIH1cbiAgICB0aGlzW2tMYXN0UHJvbWlzZV0gPSBwcm9taXNlO1xuICAgIHJldHVybiBwcm9taXNlO1xuICB9XG59LCBfZGVmaW5lUHJvcGVydHkoX09iamVjdCRzZXRQcm90b3R5cGVPLCBTeW1ib2wuYXN5bmNJdGVyYXRvciwgZnVuY3Rpb24gKCkge1xuICByZXR1cm4gdGhpcztcbn0pLCBfZGVmaW5lUHJvcGVydHkoX09iamVjdCRzZXRQcm90b3R5cGVPLCBcInJldHVyblwiLCBmdW5jdGlvbiBfcmV0dXJuKCkge1xuICB2YXIgX3RoaXMyID0gdGhpcztcbiAgLy8gZGVzdHJveShlcnIsIGNiKSBpcyBhIHByaXZhdGUgQVBJXG4gIC8vIHdlIGNhbiBndWFyYW50ZWUgd2UgaGF2ZSB0aGF0IGhlcmUsIGJlY2F1c2Ugd2UgY29udHJvbCB0aGVcbiAgLy8gUmVhZGFibGUgY2xhc3MgdGhpcyBpcyBhdHRhY2hlZCB0b1xuICByZXR1cm4gbmV3IFByb21pc2UoZnVuY3Rpb24gKHJlc29sdmUsIHJlamVjdCkge1xuICAgIF90aGlzMltrU3RyZWFtXS5kZXN0cm95KG51bGwsIGZ1bmN0aW9uIChlcnIpIHtcbiAgICAgIGlmIChlcnIpIHtcbiAgICAgICAgcmVqZWN0KGVycik7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIHJlc29sdmUoY3JlYXRlSXRlclJlc3VsdCh1bmRlZmluZWQsIHRydWUpKTtcbiAgICB9KTtcbiAgfSk7XG59KSwgX09iamVjdCRzZXRQcm90b3R5cGVPKSwgQXN5bmNJdGVyYXRvclByb3RvdHlwZSk7XG52YXIgY3JlYXRlUmVhZGFibGVTdHJlYW1Bc3luY0l0ZXJhdG9yID0gZnVuY3Rpb24gY3JlYXRlUmVhZGFibGVTdHJlYW1Bc3luY0l0ZXJhdG9yKHN0cmVhbSkge1xuICB2YXIgX09iamVjdCRjcmVhdGU7XG4gIHZhciBpdGVyYXRvciA9IE9iamVjdC5jcmVhdGUoUmVhZGFibGVTdHJlYW1Bc3luY0l0ZXJhdG9yUHJvdG90eXBlLCAoX09iamVjdCRjcmVhdGUgPSB7fSwgX2RlZmluZVByb3BlcnR5KF9PYmplY3QkY3JlYXRlLCBrU3RyZWFtLCB7XG4gICAgdmFsdWU6IHN0cmVhbSxcbiAgICB3cml0YWJsZTogdHJ1ZVxuICB9KSwgX2RlZmluZVByb3BlcnR5KF9PYmplY3QkY3JlYXRlLCBrTGFzdFJlc29sdmUsIHtcbiAgICB2YWx1ZTogbnVsbCxcbiAgICB3cml0YWJsZTogdHJ1ZVxuICB9KSwgX2RlZmluZVByb3BlcnR5KF9PYmplY3QkY3JlYXRlLCBrTGFzdFJlamVjdCwge1xuICAgIHZhbHVlOiBudWxsLFxuICAgIHdyaXRhYmxlOiB0cnVlXG4gIH0pLCBfZGVmaW5lUHJvcGVydHkoX09iamVjdCRjcmVhdGUsIGtFcnJvciwge1xuICAgIHZhbHVlOiBudWxsLFxuICAgIHdyaXRhYmxlOiB0cnVlXG4gIH0pLCBfZGVmaW5lUHJvcGVydHkoX09iamVjdCRjcmVhdGUsIGtFbmRlZCwge1xuICAgIHZhbHVlOiBzdHJlYW0uX3JlYWRhYmxlU3RhdGUuZW5kRW1pdHRlZCxcbiAgICB3cml0YWJsZTogdHJ1ZVxuICB9KSwgX2RlZmluZVByb3BlcnR5KF9PYmplY3QkY3JlYXRlLCBrSGFuZGxlUHJvbWlzZSwge1xuICAgIHZhbHVlOiBmdW5jdGlvbiB2YWx1ZShyZXNvbHZlLCByZWplY3QpIHtcbiAgICAgIHZhciBkYXRhID0gaXRlcmF0b3Jba1N0cmVhbV0ucmVhZCgpO1xuICAgICAgaWYgKGRhdGEpIHtcbiAgICAgICAgaXRlcmF0b3Jba0xhc3RQcm9taXNlXSA9IG51bGw7XG4gICAgICAgIGl0ZXJhdG9yW2tMYXN0UmVzb2x2ZV0gPSBudWxsO1xuICAgICAgICBpdGVyYXRvcltrTGFzdFJlamVjdF0gPSBudWxsO1xuICAgICAgICByZXNvbHZlKGNyZWF0ZUl0ZXJSZXN1bHQoZGF0YSwgZmFsc2UpKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGl0ZXJhdG9yW2tMYXN0UmVzb2x2ZV0gPSByZXNvbHZlO1xuICAgICAgICBpdGVyYXRvcltrTGFzdFJlamVjdF0gPSByZWplY3Q7XG4gICAgICB9XG4gICAgfSxcbiAgICB3cml0YWJsZTogdHJ1ZVxuICB9KSwgX09iamVjdCRjcmVhdGUpKTtcbiAgaXRlcmF0b3Jba0xhc3RQcm9taXNlXSA9IG51bGw7XG4gIGZpbmlzaGVkKHN0cmVhbSwgZnVuY3Rpb24gKGVycikge1xuICAgIGlmIChlcnIgJiYgZXJyLmNvZGUgIT09ICdFUlJfU1RSRUFNX1BSRU1BVFVSRV9DTE9TRScpIHtcbiAgICAgIHZhciByZWplY3QgPSBpdGVyYXRvcltrTGFzdFJlamVjdF07XG4gICAgICAvLyByZWplY3QgaWYgd2UgYXJlIHdhaXRpbmcgZm9yIGRhdGEgaW4gdGhlIFByb21pc2VcbiAgICAgIC8vIHJldHVybmVkIGJ5IG5leHQoKSBhbmQgc3RvcmUgdGhlIGVycm9yXG4gICAgICBpZiAocmVqZWN0ICE9PSBudWxsKSB7XG4gICAgICAgIGl0ZXJhdG9yW2tMYXN0UHJvbWlzZV0gPSBudWxsO1xuICAgICAgICBpdGVyYXRvcltrTGFzdFJlc29sdmVdID0gbnVsbDtcbiAgICAgICAgaXRlcmF0b3Jba0xhc3RSZWplY3RdID0gbnVsbDtcbiAgICAgICAgcmVqZWN0KGVycik7XG4gICAgICB9XG4gICAgICBpdGVyYXRvcltrRXJyb3JdID0gZXJyO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB2YXIgcmVzb2x2ZSA9IGl0ZXJhdG9yW2tMYXN0UmVzb2x2ZV07XG4gICAgaWYgKHJlc29sdmUgIT09IG51bGwpIHtcbiAgICAgIGl0ZXJhdG9yW2tMYXN0UHJvbWlzZV0gPSBudWxsO1xuICAgICAgaXRlcmF0b3Jba0xhc3RSZXNvbHZlXSA9IG51bGw7XG4gICAgICBpdGVyYXRvcltrTGFzdFJlamVjdF0gPSBudWxsO1xuICAgICAgcmVzb2x2ZShjcmVhdGVJdGVyUmVzdWx0KHVuZGVmaW5lZCwgdHJ1ZSkpO1xuICAgIH1cbiAgICBpdGVyYXRvcltrRW5kZWRdID0gdHJ1ZTtcbiAgfSk7XG4gIHN0cmVhbS5vbigncmVhZGFibGUnLCBvblJlYWRhYmxlLmJpbmQobnVsbCwgaXRlcmF0b3IpKTtcbiAgcmV0dXJuIGl0ZXJhdG9yO1xufTtcbm1vZHVsZS5leHBvcnRzID0gY3JlYXRlUmVhZGFibGVTdHJlYW1Bc3luY0l0ZXJhdG9yOyIsIid1c2Ugc3RyaWN0JztcblxuZnVuY3Rpb24gYXN5bmNHZW5lcmF0b3JTdGVwKGdlbiwgcmVzb2x2ZSwgcmVqZWN0LCBfbmV4dCwgX3Rocm93LCBrZXksIGFyZykgeyB0cnkgeyB2YXIgaW5mbyA9IGdlbltrZXldKGFyZyk7IHZhciB2YWx1ZSA9IGluZm8udmFsdWU7IH0gY2F0Y2ggKGVycm9yKSB7IHJlamVjdChlcnJvcik7IHJldHVybjsgfSBpZiAoaW5mby5kb25lKSB7IHJlc29sdmUodmFsdWUpOyB9IGVsc2UgeyBQcm9taXNlLnJlc29sdmUodmFsdWUpLnRoZW4oX25leHQsIF90aHJvdyk7IH0gfVxuZnVuY3Rpb24gX2FzeW5jVG9HZW5lcmF0b3IoZm4pIHsgcmV0dXJuIGZ1bmN0aW9uICgpIHsgdmFyIHNlbGYgPSB0aGlzLCBhcmdzID0gYXJndW1lbnRzOyByZXR1cm4gbmV3IFByb21pc2UoZnVuY3Rpb24gKHJlc29sdmUsIHJlamVjdCkgeyB2YXIgZ2VuID0gZm4uYXBwbHkoc2VsZiwgYXJncyk7IGZ1bmN0aW9uIF9uZXh0KHZhbHVlKSB7IGFzeW5jR2VuZXJhdG9yU3RlcChnZW4sIHJlc29sdmUsIHJlamVjdCwgX25leHQsIF90aHJvdywgXCJuZXh0XCIsIHZhbHVlKTsgfSBmdW5jdGlvbiBfdGhyb3coZXJyKSB7IGFzeW5jR2VuZXJhdG9yU3RlcChnZW4sIHJlc29sdmUsIHJlamVjdCwgX25leHQsIF90aHJvdywgXCJ0aHJvd1wiLCBlcnIpOyB9IF9uZXh0KHVuZGVmaW5lZCk7IH0pOyB9OyB9XG5mdW5jdGlvbiBvd25LZXlzKG9iamVjdCwgZW51bWVyYWJsZU9ubHkpIHsgdmFyIGtleXMgPSBPYmplY3Qua2V5cyhvYmplY3QpOyBpZiAoT2JqZWN0LmdldE93blByb3BlcnR5U3ltYm9scykgeyB2YXIgc3ltYm9scyA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eVN5bWJvbHMob2JqZWN0KTsgZW51bWVyYWJsZU9ubHkgJiYgKHN5bWJvbHMgPSBzeW1ib2xzLmZpbHRlcihmdW5jdGlvbiAoc3ltKSB7IHJldHVybiBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKG9iamVjdCwgc3ltKS5lbnVtZXJhYmxlOyB9KSksIGtleXMucHVzaC5hcHBseShrZXlzLCBzeW1ib2xzKTsgfSByZXR1cm4ga2V5czsgfVxuZnVuY3Rpb24gX29iamVjdFNwcmVhZCh0YXJnZXQpIHsgZm9yICh2YXIgaSA9IDE7IGkgPCBhcmd1bWVudHMubGVuZ3RoOyBpKyspIHsgdmFyIHNvdXJjZSA9IG51bGwgIT0gYXJndW1lbnRzW2ldID8gYXJndW1lbnRzW2ldIDoge307IGkgJSAyID8gb3duS2V5cyhPYmplY3Qoc291cmNlKSwgITApLmZvckVhY2goZnVuY3Rpb24gKGtleSkgeyBfZGVmaW5lUHJvcGVydHkodGFyZ2V0LCBrZXksIHNvdXJjZVtrZXldKTsgfSkgOiBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9ycyA/IE9iamVjdC5kZWZpbmVQcm9wZXJ0aWVzKHRhcmdldCwgT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcnMoc291cmNlKSkgOiBvd25LZXlzKE9iamVjdChzb3VyY2UpKS5mb3JFYWNoKGZ1bmN0aW9uIChrZXkpIHsgT2JqZWN0LmRlZmluZVByb3BlcnR5KHRhcmdldCwga2V5LCBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKHNvdXJjZSwga2V5KSk7IH0pOyB9IHJldHVybiB0YXJnZXQ7IH1cbmZ1bmN0aW9uIF9kZWZpbmVQcm9wZXJ0eShvYmosIGtleSwgdmFsdWUpIHsga2V5ID0gX3RvUHJvcGVydHlLZXkoa2V5KTsgaWYgKGtleSBpbiBvYmopIHsgT2JqZWN0LmRlZmluZVByb3BlcnR5KG9iaiwga2V5LCB7IHZhbHVlOiB2YWx1ZSwgZW51bWVyYWJsZTogdHJ1ZSwgY29uZmlndXJhYmxlOiB0cnVlLCB3cml0YWJsZTogdHJ1ZSB9KTsgfSBlbHNlIHsgb2JqW2tleV0gPSB2YWx1ZTsgfSByZXR1cm4gb2JqOyB9XG5mdW5jdGlvbiBfdG9Qcm9wZXJ0eUtleShhcmcpIHsgdmFyIGtleSA9IF90b1ByaW1pdGl2ZShhcmcsIFwic3RyaW5nXCIpOyByZXR1cm4gdHlwZW9mIGtleSA9PT0gXCJzeW1ib2xcIiA/IGtleSA6IFN0cmluZyhrZXkpOyB9XG5mdW5jdGlvbiBfdG9QcmltaXRpdmUoaW5wdXQsIGhpbnQpIHsgaWYgKHR5cGVvZiBpbnB1dCAhPT0gXCJvYmplY3RcIiB8fCBpbnB1dCA9PT0gbnVsbCkgcmV0dXJuIGlucHV0OyB2YXIgcHJpbSA9IGlucHV0W1N5bWJvbC50b1ByaW1pdGl2ZV07IGlmIChwcmltICE9PSB1bmRlZmluZWQpIHsgdmFyIHJlcyA9IHByaW0uY2FsbChpbnB1dCwgaGludCB8fCBcImRlZmF1bHRcIik7IGlmICh0eXBlb2YgcmVzICE9PSBcIm9iamVjdFwiKSByZXR1cm4gcmVzOyB0aHJvdyBuZXcgVHlwZUVycm9yKFwiQEB0b1ByaW1pdGl2ZSBtdXN0IHJldHVybiBhIHByaW1pdGl2ZSB2YWx1ZS5cIik7IH0gcmV0dXJuIChoaW50ID09PSBcInN0cmluZ1wiID8gU3RyaW5nIDogTnVtYmVyKShpbnB1dCk7IH1cbnZhciBFUlJfSU5WQUxJRF9BUkdfVFlQRSA9IHJlcXVpcmUoJy4uLy4uLy4uL2Vycm9ycycpLmNvZGVzLkVSUl9JTlZBTElEX0FSR19UWVBFO1xuZnVuY3Rpb24gZnJvbShSZWFkYWJsZSwgaXRlcmFibGUsIG9wdHMpIHtcbiAgdmFyIGl0ZXJhdG9yO1xuICBpZiAoaXRlcmFibGUgJiYgdHlwZW9mIGl0ZXJhYmxlLm5leHQgPT09ICdmdW5jdGlvbicpIHtcbiAgICBpdGVyYXRvciA9IGl0ZXJhYmxlO1xuICB9IGVsc2UgaWYgKGl0ZXJhYmxlICYmIGl0ZXJhYmxlW1N5bWJvbC5hc3luY0l0ZXJhdG9yXSkgaXRlcmF0b3IgPSBpdGVyYWJsZVtTeW1ib2wuYXN5bmNJdGVyYXRvcl0oKTtlbHNlIGlmIChpdGVyYWJsZSAmJiBpdGVyYWJsZVtTeW1ib2wuaXRlcmF0b3JdKSBpdGVyYXRvciA9IGl0ZXJhYmxlW1N5bWJvbC5pdGVyYXRvcl0oKTtlbHNlIHRocm93IG5ldyBFUlJfSU5WQUxJRF9BUkdfVFlQRSgnaXRlcmFibGUnLCBbJ0l0ZXJhYmxlJ10sIGl0ZXJhYmxlKTtcbiAgdmFyIHJlYWRhYmxlID0gbmV3IFJlYWRhYmxlKF9vYmplY3RTcHJlYWQoe1xuICAgIG9iamVjdE1vZGU6IHRydWVcbiAgfSwgb3B0cykpO1xuICAvLyBSZWFkaW5nIGJvb2xlYW4gdG8gcHJvdGVjdCBhZ2FpbnN0IF9yZWFkXG4gIC8vIGJlaW5nIGNhbGxlZCBiZWZvcmUgbGFzdCBpdGVyYXRpb24gY29tcGxldGlvbi5cbiAgdmFyIHJlYWRpbmcgPSBmYWxzZTtcbiAgcmVhZGFibGUuX3JlYWQgPSBmdW5jdGlvbiAoKSB7XG4gICAgaWYgKCFyZWFkaW5nKSB7XG4gICAgICByZWFkaW5nID0gdHJ1ZTtcbiAgICAgIG5leHQoKTtcbiAgICB9XG4gIH07XG4gIGZ1bmN0aW9uIG5leHQoKSB7XG4gICAgcmV0dXJuIF9uZXh0Mi5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICB9XG4gIGZ1bmN0aW9uIF9uZXh0MigpIHtcbiAgICBfbmV4dDIgPSBfYXN5bmNUb0dlbmVyYXRvcihmdW5jdGlvbiogKCkge1xuICAgICAgdHJ5IHtcbiAgICAgICAgdmFyIF95aWVsZCRpdGVyYXRvciRuZXh0ID0geWllbGQgaXRlcmF0b3IubmV4dCgpLFxuICAgICAgICAgIHZhbHVlID0gX3lpZWxkJGl0ZXJhdG9yJG5leHQudmFsdWUsXG4gICAgICAgICAgZG9uZSA9IF95aWVsZCRpdGVyYXRvciRuZXh0LmRvbmU7XG4gICAgICAgIGlmIChkb25lKSB7XG4gICAgICAgICAgcmVhZGFibGUucHVzaChudWxsKTtcbiAgICAgICAgfSBlbHNlIGlmIChyZWFkYWJsZS5wdXNoKHlpZWxkIHZhbHVlKSkge1xuICAgICAgICAgIG5leHQoKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICByZWFkaW5nID0gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgICByZWFkYWJsZS5kZXN0cm95KGVycik7XG4gICAgICB9XG4gICAgfSk7XG4gICAgcmV0dXJuIF9uZXh0Mi5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICB9XG4gIHJldHVybiByZWFkYWJsZTtcbn1cbm1vZHVsZS5leHBvcnRzID0gZnJvbTtcbiIsIi8vIENvcHlyaWdodCBKb3llbnQsIEluYy4gYW5kIG90aGVyIE5vZGUgY29udHJpYnV0b3JzLlxuLy9cbi8vIFBlcm1pc3Npb24gaXMgaGVyZWJ5IGdyYW50ZWQsIGZyZWUgb2YgY2hhcmdlLCB0byBhbnkgcGVyc29uIG9idGFpbmluZyBhXG4vLyBjb3B5IG9mIHRoaXMgc29mdHdhcmUgYW5kIGFzc29jaWF0ZWQgZG9jdW1lbnRhdGlvbiBmaWxlcyAodGhlXG4vLyBcIlNvZnR3YXJlXCIpLCB0byBkZWFsIGluIHRoZSBTb2Z0d2FyZSB3aXRob3V0IHJlc3RyaWN0aW9uLCBpbmNsdWRpbmdcbi8vIHdpdGhvdXQgbGltaXRhdGlvbiB0aGUgcmlnaHRzIHRvIHVzZSwgY29weSwgbW9kaWZ5LCBtZXJnZSwgcHVibGlzaCxcbi8vIGRpc3RyaWJ1dGUsIHN1YmxpY2Vuc2UsIGFuZC9vciBzZWxsIGNvcGllcyBvZiB0aGUgU29mdHdhcmUsIGFuZCB0byBwZXJtaXRcbi8vIHBlcnNvbnMgdG8gd2hvbSB0aGUgU29mdHdhcmUgaXMgZnVybmlzaGVkIHRvIGRvIHNvLCBzdWJqZWN0IHRvIHRoZVxuLy8gZm9sbG93aW5nIGNvbmRpdGlvbnM6XG4vL1xuLy8gVGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UgYW5kIHRoaXMgcGVybWlzc2lvbiBub3RpY2Ugc2hhbGwgYmUgaW5jbHVkZWRcbi8vIGluIGFsbCBjb3BpZXMgb3Igc3Vic3RhbnRpYWwgcG9ydGlvbnMgb2YgdGhlIFNvZnR3YXJlLlxuLy9cbi8vIFRIRSBTT0ZUV0FSRSBJUyBQUk9WSURFRCBcIkFTIElTXCIsIFdJVEhPVVQgV0FSUkFOVFkgT0YgQU5ZIEtJTkQsIEVYUFJFU1Ncbi8vIE9SIElNUExJRUQsIElOQ0xVRElORyBCVVQgTk9UIExJTUlURUQgVE8gVEhFIFdBUlJBTlRJRVMgT0Zcbi8vIE1FUkNIQU5UQUJJTElUWSwgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQU5EIE5PTklORlJJTkdFTUVOVC4gSU5cbi8vIE5PIEVWRU5UIFNIQUxMIFRIRSBBVVRIT1JTIE9SIENPUFlSSUdIVCBIT0xERVJTIEJFIExJQUJMRSBGT1IgQU5ZIENMQUlNLFxuLy8gREFNQUdFUyBPUiBPVEhFUiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQU4gQUNUSU9OIE9GIENPTlRSQUNULCBUT1JUIE9SXG4vLyBPVEhFUldJU0UsIEFSSVNJTkcgRlJPTSwgT1VUIE9GIE9SIElOIENPTk5FQ1RJT04gV0lUSCBUSEUgU09GVFdBUkUgT1IgVEhFXG4vLyBVU0UgT1IgT1RIRVIgREVBTElOR1MgSU4gVEhFIFNPRlRXQVJFLlxuXG4ndXNlIHN0cmljdCc7XG5cbm1vZHVsZS5leHBvcnRzID0gUmVhZGFibGU7XG5cbi8qPHJlcGxhY2VtZW50PiovXG52YXIgRHVwbGV4O1xuLyo8L3JlcGxhY2VtZW50PiovXG5cblJlYWRhYmxlLlJlYWRhYmxlU3RhdGUgPSBSZWFkYWJsZVN0YXRlO1xuXG4vKjxyZXBsYWNlbWVudD4qL1xudmFyIEVFID0gcmVxdWlyZSgnZXZlbnRzJykuRXZlbnRFbWl0dGVyO1xudmFyIEVFbGlzdGVuZXJDb3VudCA9IGZ1bmN0aW9uIEVFbGlzdGVuZXJDb3VudChlbWl0dGVyLCB0eXBlKSB7XG4gIHJldHVybiBlbWl0dGVyLmxpc3RlbmVycyh0eXBlKS5sZW5ndGg7XG59O1xuLyo8L3JlcGxhY2VtZW50PiovXG5cbi8qPHJlcGxhY2VtZW50PiovXG52YXIgU3RyZWFtID0gcmVxdWlyZSgnLi9pbnRlcm5hbC9zdHJlYW1zL3N0cmVhbScpO1xuLyo8L3JlcGxhY2VtZW50PiovXG5cbnZhciBCdWZmZXIgPSByZXF1aXJlKCdidWZmZXInKS5CdWZmZXI7XG52YXIgT3VyVWludDhBcnJheSA9ICh0eXBlb2YgZ2xvYmFsICE9PSAndW5kZWZpbmVkJyA/IGdsb2JhbCA6IHR5cGVvZiB3aW5kb3cgIT09ICd1bmRlZmluZWQnID8gd2luZG93IDogdHlwZW9mIHNlbGYgIT09ICd1bmRlZmluZWQnID8gc2VsZiA6IHt9KS5VaW50OEFycmF5IHx8IGZ1bmN0aW9uICgpIHt9O1xuZnVuY3Rpb24gX3VpbnQ4QXJyYXlUb0J1ZmZlcihjaHVuaykge1xuICByZXR1cm4gQnVmZmVyLmZyb20oY2h1bmspO1xufVxuZnVuY3Rpb24gX2lzVWludDhBcnJheShvYmopIHtcbiAgcmV0dXJuIEJ1ZmZlci5pc0J1ZmZlcihvYmopIHx8IG9iaiBpbnN0YW5jZW9mIE91clVpbnQ4QXJyYXk7XG59XG5cbi8qPHJlcGxhY2VtZW50PiovXG52YXIgZGVidWdVdGlsID0gcmVxdWlyZSgndXRpbCcpO1xudmFyIGRlYnVnO1xuaWYgKGRlYnVnVXRpbCAmJiBkZWJ1Z1V0aWwuZGVidWdsb2cpIHtcbiAgZGVidWcgPSBkZWJ1Z1V0aWwuZGVidWdsb2coJ3N0cmVhbScpO1xufSBlbHNlIHtcbiAgZGVidWcgPSBmdW5jdGlvbiBkZWJ1ZygpIHt9O1xufVxuLyo8L3JlcGxhY2VtZW50PiovXG5cbnZhciBCdWZmZXJMaXN0ID0gcmVxdWlyZSgnLi9pbnRlcm5hbC9zdHJlYW1zL2J1ZmZlcl9saXN0Jyk7XG52YXIgZGVzdHJveUltcGwgPSByZXF1aXJlKCcuL2ludGVybmFsL3N0cmVhbXMvZGVzdHJveScpO1xudmFyIF9yZXF1aXJlID0gcmVxdWlyZSgnLi9pbnRlcm5hbC9zdHJlYW1zL3N0YXRlJyksXG4gIGdldEhpZ2hXYXRlck1hcmsgPSBfcmVxdWlyZS5nZXRIaWdoV2F0ZXJNYXJrO1xudmFyIF9yZXF1aXJlJGNvZGVzID0gcmVxdWlyZSgnLi4vZXJyb3JzJykuY29kZXMsXG4gIEVSUl9JTlZBTElEX0FSR19UWVBFID0gX3JlcXVpcmUkY29kZXMuRVJSX0lOVkFMSURfQVJHX1RZUEUsXG4gIEVSUl9TVFJFQU1fUFVTSF9BRlRFUl9FT0YgPSBfcmVxdWlyZSRjb2Rlcy5FUlJfU1RSRUFNX1BVU0hfQUZURVJfRU9GLFxuICBFUlJfTUVUSE9EX05PVF9JTVBMRU1FTlRFRCA9IF9yZXF1aXJlJGNvZGVzLkVSUl9NRVRIT0RfTk9UX0lNUExFTUVOVEVELFxuICBFUlJfU1RSRUFNX1VOU0hJRlRfQUZURVJfRU5EX0VWRU5UID0gX3JlcXVpcmUkY29kZXMuRVJSX1NUUkVBTV9VTlNISUZUX0FGVEVSX0VORF9FVkVOVDtcblxuLy8gTGF6eSBsb2FkZWQgdG8gaW1wcm92ZSB0aGUgc3RhcnR1cCBwZXJmb3JtYW5jZS5cbnZhciBTdHJpbmdEZWNvZGVyO1xudmFyIGNyZWF0ZVJlYWRhYmxlU3RyZWFtQXN5bmNJdGVyYXRvcjtcbnZhciBmcm9tO1xucmVxdWlyZSgnaW5oZXJpdHMnKShSZWFkYWJsZSwgU3RyZWFtKTtcbnZhciBlcnJvck9yRGVzdHJveSA9IGRlc3Ryb3lJbXBsLmVycm9yT3JEZXN0cm95O1xudmFyIGtQcm94eUV2ZW50cyA9IFsnZXJyb3InLCAnY2xvc2UnLCAnZGVzdHJveScsICdwYXVzZScsICdyZXN1bWUnXTtcbmZ1bmN0aW9uIHByZXBlbmRMaXN0ZW5lcihlbWl0dGVyLCBldmVudCwgZm4pIHtcbiAgLy8gU2FkbHkgdGhpcyBpcyBub3QgY2FjaGVhYmxlIGFzIHNvbWUgbGlicmFyaWVzIGJ1bmRsZSB0aGVpciBvd25cbiAgLy8gZXZlbnQgZW1pdHRlciBpbXBsZW1lbnRhdGlvbiB3aXRoIHRoZW0uXG4gIGlmICh0eXBlb2YgZW1pdHRlci5wcmVwZW5kTGlzdGVuZXIgPT09ICdmdW5jdGlvbicpIHJldHVybiBlbWl0dGVyLnByZXBlbmRMaXN0ZW5lcihldmVudCwgZm4pO1xuXG4gIC8vIFRoaXMgaXMgYSBoYWNrIHRvIG1ha2Ugc3VyZSB0aGF0IG91ciBlcnJvciBoYW5kbGVyIGlzIGF0dGFjaGVkIGJlZm9yZSBhbnlcbiAgLy8gdXNlcmxhbmQgb25lcy4gIE5FVkVSIERPIFRISVMuIFRoaXMgaXMgaGVyZSBvbmx5IGJlY2F1c2UgdGhpcyBjb2RlIG5lZWRzXG4gIC8vIHRvIGNvbnRpbnVlIHRvIHdvcmsgd2l0aCBvbGRlciB2ZXJzaW9ucyBvZiBOb2RlLmpzIHRoYXQgZG8gbm90IGluY2x1ZGVcbiAgLy8gdGhlIHByZXBlbmRMaXN0ZW5lcigpIG1ldGhvZC4gVGhlIGdvYWwgaXMgdG8gZXZlbnR1YWxseSByZW1vdmUgdGhpcyBoYWNrLlxuICBpZiAoIWVtaXR0ZXIuX2V2ZW50cyB8fCAhZW1pdHRlci5fZXZlbnRzW2V2ZW50XSkgZW1pdHRlci5vbihldmVudCwgZm4pO2Vsc2UgaWYgKEFycmF5LmlzQXJyYXkoZW1pdHRlci5fZXZlbnRzW2V2ZW50XSkpIGVtaXR0ZXIuX2V2ZW50c1tldmVudF0udW5zaGlmdChmbik7ZWxzZSBlbWl0dGVyLl9ldmVudHNbZXZlbnRdID0gW2ZuLCBlbWl0dGVyLl9ldmVudHNbZXZlbnRdXTtcbn1cbmZ1bmN0aW9uIFJlYWRhYmxlU3RhdGUob3B0aW9ucywgc3RyZWFtLCBpc0R1cGxleCkge1xuICBEdXBsZXggPSBEdXBsZXggfHwgcmVxdWlyZSgnLi9fc3RyZWFtX2R1cGxleCcpO1xuICBvcHRpb25zID0gb3B0aW9ucyB8fCB7fTtcblxuICAvLyBEdXBsZXggc3RyZWFtcyBhcmUgYm90aCByZWFkYWJsZSBhbmQgd3JpdGFibGUsIGJ1dCBzaGFyZVxuICAvLyB0aGUgc2FtZSBvcHRpb25zIG9iamVjdC5cbiAgLy8gSG93ZXZlciwgc29tZSBjYXNlcyByZXF1aXJlIHNldHRpbmcgb3B0aW9ucyB0byBkaWZmZXJlbnRcbiAgLy8gdmFsdWVzIGZvciB0aGUgcmVhZGFibGUgYW5kIHRoZSB3cml0YWJsZSBzaWRlcyBvZiB0aGUgZHVwbGV4IHN0cmVhbS5cbiAgLy8gVGhlc2Ugb3B0aW9ucyBjYW4gYmUgcHJvdmlkZWQgc2VwYXJhdGVseSBhcyByZWFkYWJsZVhYWCBhbmQgd3JpdGFibGVYWFguXG4gIGlmICh0eXBlb2YgaXNEdXBsZXggIT09ICdib29sZWFuJykgaXNEdXBsZXggPSBzdHJlYW0gaW5zdGFuY2VvZiBEdXBsZXg7XG5cbiAgLy8gb2JqZWN0IHN0cmVhbSBmbGFnLiBVc2VkIHRvIG1ha2UgcmVhZChuKSBpZ25vcmUgbiBhbmQgdG9cbiAgLy8gbWFrZSBhbGwgdGhlIGJ1ZmZlciBtZXJnaW5nIGFuZCBsZW5ndGggY2hlY2tzIGdvIGF3YXlcbiAgdGhpcy5vYmplY3RNb2RlID0gISFvcHRpb25zLm9iamVjdE1vZGU7XG4gIGlmIChpc0R1cGxleCkgdGhpcy5vYmplY3RNb2RlID0gdGhpcy5vYmplY3RNb2RlIHx8ICEhb3B0aW9ucy5yZWFkYWJsZU9iamVjdE1vZGU7XG5cbiAgLy8gdGhlIHBvaW50IGF0IHdoaWNoIGl0IHN0b3BzIGNhbGxpbmcgX3JlYWQoKSB0byBmaWxsIHRoZSBidWZmZXJcbiAgLy8gTm90ZTogMCBpcyBhIHZhbGlkIHZhbHVlLCBtZWFucyBcImRvbid0IGNhbGwgX3JlYWQgcHJlZW1wdGl2ZWx5IGV2ZXJcIlxuICB0aGlzLmhpZ2hXYXRlck1hcmsgPSBnZXRIaWdoV2F0ZXJNYXJrKHRoaXMsIG9wdGlvbnMsICdyZWFkYWJsZUhpZ2hXYXRlck1hcmsnLCBpc0R1cGxleCk7XG5cbiAgLy8gQSBsaW5rZWQgbGlzdCBpcyB1c2VkIHRvIHN0b3JlIGRhdGEgY2h1bmtzIGluc3RlYWQgb2YgYW4gYXJyYXkgYmVjYXVzZSB0aGVcbiAgLy8gbGlua2VkIGxpc3QgY2FuIHJlbW92ZSBlbGVtZW50cyBmcm9tIHRoZSBiZWdpbm5pbmcgZmFzdGVyIHRoYW5cbiAgLy8gYXJyYXkuc2hpZnQoKVxuICB0aGlzLmJ1ZmZlciA9IG5ldyBCdWZmZXJMaXN0KCk7XG4gIHRoaXMubGVuZ3RoID0gMDtcbiAgdGhpcy5waXBlcyA9IG51bGw7XG4gIHRoaXMucGlwZXNDb3VudCA9IDA7XG4gIHRoaXMuZmxvd2luZyA9IG51bGw7XG4gIHRoaXMuZW5kZWQgPSBmYWxzZTtcbiAgdGhpcy5lbmRFbWl0dGVkID0gZmFsc2U7XG4gIHRoaXMucmVhZGluZyA9IGZhbHNlO1xuXG4gIC8vIGEgZmxhZyB0byBiZSBhYmxlIHRvIHRlbGwgaWYgdGhlIGV2ZW50ICdyZWFkYWJsZScvJ2RhdGEnIGlzIGVtaXR0ZWRcbiAgLy8gaW1tZWRpYXRlbHksIG9yIG9uIGEgbGF0ZXIgdGljay4gIFdlIHNldCB0aGlzIHRvIHRydWUgYXQgZmlyc3QsIGJlY2F1c2VcbiAgLy8gYW55IGFjdGlvbnMgdGhhdCBzaG91bGRuJ3QgaGFwcGVuIHVudGlsIFwibGF0ZXJcIiBzaG91bGQgZ2VuZXJhbGx5IGFsc29cbiAgLy8gbm90IGhhcHBlbiBiZWZvcmUgdGhlIGZpcnN0IHJlYWQgY2FsbC5cbiAgdGhpcy5zeW5jID0gdHJ1ZTtcblxuICAvLyB3aGVuZXZlciB3ZSByZXR1cm4gbnVsbCwgdGhlbiB3ZSBzZXQgYSBmbGFnIHRvIHNheVxuICAvLyB0aGF0IHdlJ3JlIGF3YWl0aW5nIGEgJ3JlYWRhYmxlJyBldmVudCBlbWlzc2lvbi5cbiAgdGhpcy5uZWVkUmVhZGFibGUgPSBmYWxzZTtcbiAgdGhpcy5lbWl0dGVkUmVhZGFibGUgPSBmYWxzZTtcbiAgdGhpcy5yZWFkYWJsZUxpc3RlbmluZyA9IGZhbHNlO1xuICB0aGlzLnJlc3VtZVNjaGVkdWxlZCA9IGZhbHNlO1xuICB0aGlzLnBhdXNlZCA9IHRydWU7XG5cbiAgLy8gU2hvdWxkIGNsb3NlIGJlIGVtaXR0ZWQgb24gZGVzdHJveS4gRGVmYXVsdHMgdG8gdHJ1ZS5cbiAgdGhpcy5lbWl0Q2xvc2UgPSBvcHRpb25zLmVtaXRDbG9zZSAhPT0gZmFsc2U7XG5cbiAgLy8gU2hvdWxkIC5kZXN0cm95KCkgYmUgY2FsbGVkIGFmdGVyICdlbmQnIChhbmQgcG90ZW50aWFsbHkgJ2ZpbmlzaCcpXG4gIHRoaXMuYXV0b0Rlc3Ryb3kgPSAhIW9wdGlvbnMuYXV0b0Rlc3Ryb3k7XG5cbiAgLy8gaGFzIGl0IGJlZW4gZGVzdHJveWVkXG4gIHRoaXMuZGVzdHJveWVkID0gZmFsc2U7XG5cbiAgLy8gQ3J5cHRvIGlzIGtpbmQgb2Ygb2xkIGFuZCBjcnVzdHkuICBIaXN0b3JpY2FsbHksIGl0cyBkZWZhdWx0IHN0cmluZ1xuICAvLyBlbmNvZGluZyBpcyAnYmluYXJ5JyBzbyB3ZSBoYXZlIHRvIG1ha2UgdGhpcyBjb25maWd1cmFibGUuXG4gIC8vIEV2ZXJ5dGhpbmcgZWxzZSBpbiB0aGUgdW5pdmVyc2UgdXNlcyAndXRmOCcsIHRob3VnaC5cbiAgdGhpcy5kZWZhdWx0RW5jb2RpbmcgPSBvcHRpb25zLmRlZmF1bHRFbmNvZGluZyB8fCAndXRmOCc7XG5cbiAgLy8gdGhlIG51bWJlciBvZiB3cml0ZXJzIHRoYXQgYXJlIGF3YWl0aW5nIGEgZHJhaW4gZXZlbnQgaW4gLnBpcGUoKXNcbiAgdGhpcy5hd2FpdERyYWluID0gMDtcblxuICAvLyBpZiB0cnVlLCBhIG1heWJlUmVhZE1vcmUgaGFzIGJlZW4gc2NoZWR1bGVkXG4gIHRoaXMucmVhZGluZ01vcmUgPSBmYWxzZTtcbiAgdGhpcy5kZWNvZGVyID0gbnVsbDtcbiAgdGhpcy5lbmNvZGluZyA9IG51bGw7XG4gIGlmIChvcHRpb25zLmVuY29kaW5nKSB7XG4gICAgaWYgKCFTdHJpbmdEZWNvZGVyKSBTdHJpbmdEZWNvZGVyID0gcmVxdWlyZSgnc3RyaW5nX2RlY29kZXIvJykuU3RyaW5nRGVjb2RlcjtcbiAgICB0aGlzLmRlY29kZXIgPSBuZXcgU3RyaW5nRGVjb2RlcihvcHRpb25zLmVuY29kaW5nKTtcbiAgICB0aGlzLmVuY29kaW5nID0gb3B0aW9ucy5lbmNvZGluZztcbiAgfVxufVxuZnVuY3Rpb24gUmVhZGFibGUob3B0aW9ucykge1xuICBEdXBsZXggPSBEdXBsZXggfHwgcmVxdWlyZSgnLi9fc3RyZWFtX2R1cGxleCcpO1xuICBpZiAoISh0aGlzIGluc3RhbmNlb2YgUmVhZGFibGUpKSByZXR1cm4gbmV3IFJlYWRhYmxlKG9wdGlvbnMpO1xuXG4gIC8vIENoZWNraW5nIGZvciBhIFN0cmVhbS5EdXBsZXggaW5zdGFuY2UgaXMgZmFzdGVyIGhlcmUgaW5zdGVhZCBvZiBpbnNpZGVcbiAgLy8gdGhlIFJlYWRhYmxlU3RhdGUgY29uc3RydWN0b3IsIGF0IGxlYXN0IHdpdGggVjggNi41XG4gIHZhciBpc0R1cGxleCA9IHRoaXMgaW5zdGFuY2VvZiBEdXBsZXg7XG4gIHRoaXMuX3JlYWRhYmxlU3RhdGUgPSBuZXcgUmVhZGFibGVTdGF0ZShvcHRpb25zLCB0aGlzLCBpc0R1cGxleCk7XG5cbiAgLy8gbGVnYWN5XG4gIHRoaXMucmVhZGFibGUgPSB0cnVlO1xuICBpZiAob3B0aW9ucykge1xuICAgIGlmICh0eXBlb2Ygb3B0aW9ucy5yZWFkID09PSAnZnVuY3Rpb24nKSB0aGlzLl9yZWFkID0gb3B0aW9ucy5yZWFkO1xuICAgIGlmICh0eXBlb2Ygb3B0aW9ucy5kZXN0cm95ID09PSAnZnVuY3Rpb24nKSB0aGlzLl9kZXN0cm95ID0gb3B0aW9ucy5kZXN0cm95O1xuICB9XG4gIFN0cmVhbS5jYWxsKHRoaXMpO1xufVxuT2JqZWN0LmRlZmluZVByb3BlcnR5KFJlYWRhYmxlLnByb3RvdHlwZSwgJ2Rlc3Ryb3llZCcsIHtcbiAgLy8gbWFraW5nIGl0IGV4cGxpY2l0IHRoaXMgcHJvcGVydHkgaXMgbm90IGVudW1lcmFibGVcbiAgLy8gYmVjYXVzZSBvdGhlcndpc2Ugc29tZSBwcm90b3R5cGUgbWFuaXB1bGF0aW9uIGluXG4gIC8vIHVzZXJsYW5kIHdpbGwgZmFpbFxuICBlbnVtZXJhYmxlOiBmYWxzZSxcbiAgZ2V0OiBmdW5jdGlvbiBnZXQoKSB7XG4gICAgaWYgKHRoaXMuX3JlYWRhYmxlU3RhdGUgPT09IHVuZGVmaW5lZCkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy5fcmVhZGFibGVTdGF0ZS5kZXN0cm95ZWQ7XG4gIH0sXG4gIHNldDogZnVuY3Rpb24gc2V0KHZhbHVlKSB7XG4gICAgLy8gd2UgaWdub3JlIHRoZSB2YWx1ZSBpZiB0aGUgc3RyZWFtXG4gICAgLy8gaGFzIG5vdCBiZWVuIGluaXRpYWxpemVkIHlldFxuICAgIGlmICghdGhpcy5fcmVhZGFibGVTdGF0ZSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIC8vIGJhY2t3YXJkIGNvbXBhdGliaWxpdHksIHRoZSB1c2VyIGlzIGV4cGxpY2l0bHlcbiAgICAvLyBtYW5hZ2luZyBkZXN0cm95ZWRcbiAgICB0aGlzLl9yZWFkYWJsZVN0YXRlLmRlc3Ryb3llZCA9IHZhbHVlO1xuICB9XG59KTtcblJlYWRhYmxlLnByb3RvdHlwZS5kZXN0cm95ID0gZGVzdHJveUltcGwuZGVzdHJveTtcblJlYWRhYmxlLnByb3RvdHlwZS5fdW5kZXN0cm95ID0gZGVzdHJveUltcGwudW5kZXN0cm95O1xuUmVhZGFibGUucHJvdG90eXBlLl9kZXN0cm95ID0gZnVuY3Rpb24gKGVyciwgY2IpIHtcbiAgY2IoZXJyKTtcbn07XG5cbi8vIE1hbnVhbGx5IHNob3ZlIHNvbWV0aGluZyBpbnRvIHRoZSByZWFkKCkgYnVmZmVyLlxuLy8gVGhpcyByZXR1cm5zIHRydWUgaWYgdGhlIGhpZ2hXYXRlck1hcmsgaGFzIG5vdCBiZWVuIGhpdCB5ZXQsXG4vLyBzaW1pbGFyIHRvIGhvdyBXcml0YWJsZS53cml0ZSgpIHJldHVybnMgdHJ1ZSBpZiB5b3Ugc2hvdWxkXG4vLyB3cml0ZSgpIHNvbWUgbW9yZS5cblJlYWRhYmxlLnByb3RvdHlwZS5wdXNoID0gZnVuY3Rpb24gKGNodW5rLCBlbmNvZGluZykge1xuICB2YXIgc3RhdGUgPSB0aGlzLl9yZWFkYWJsZVN0YXRlO1xuICB2YXIgc2tpcENodW5rQ2hlY2s7XG4gIGlmICghc3RhdGUub2JqZWN0TW9kZSkge1xuICAgIGlmICh0eXBlb2YgY2h1bmsgPT09ICdzdHJpbmcnKSB7XG4gICAgICBlbmNvZGluZyA9IGVuY29kaW5nIHx8IHN0YXRlLmRlZmF1bHRFbmNvZGluZztcbiAgICAgIGlmIChlbmNvZGluZyAhPT0gc3RhdGUuZW5jb2RpbmcpIHtcbiAgICAgICAgY2h1bmsgPSBCdWZmZXIuZnJvbShjaHVuaywgZW5jb2RpbmcpO1xuICAgICAgICBlbmNvZGluZyA9ICcnO1xuICAgICAgfVxuICAgICAgc2tpcENodW5rQ2hlY2sgPSB0cnVlO1xuICAgIH1cbiAgfSBlbHNlIHtcbiAgICBza2lwQ2h1bmtDaGVjayA9IHRydWU7XG4gIH1cbiAgcmV0dXJuIHJlYWRhYmxlQWRkQ2h1bmsodGhpcywgY2h1bmssIGVuY29kaW5nLCBmYWxzZSwgc2tpcENodW5rQ2hlY2spO1xufTtcblxuLy8gVW5zaGlmdCBzaG91bGQgKmFsd2F5cyogYmUgc29tZXRoaW5nIGRpcmVjdGx5IG91dCBvZiByZWFkKClcblJlYWRhYmxlLnByb3RvdHlwZS51bnNoaWZ0ID0gZnVuY3Rpb24gKGNodW5rKSB7XG4gIHJldHVybiByZWFkYWJsZUFkZENodW5rKHRoaXMsIGNodW5rLCBudWxsLCB0cnVlLCBmYWxzZSk7XG59O1xuZnVuY3Rpb24gcmVhZGFibGVBZGRDaHVuayhzdHJlYW0sIGNodW5rLCBlbmNvZGluZywgYWRkVG9Gcm9udCwgc2tpcENodW5rQ2hlY2spIHtcbiAgZGVidWcoJ3JlYWRhYmxlQWRkQ2h1bmsnLCBjaHVuayk7XG4gIHZhciBzdGF0ZSA9IHN0cmVhbS5fcmVhZGFibGVTdGF0ZTtcbiAgaWYgKGNodW5rID09PSBudWxsKSB7XG4gICAgc3RhdGUucmVhZGluZyA9IGZhbHNlO1xuICAgIG9uRW9mQ2h1bmsoc3RyZWFtLCBzdGF0ZSk7XG4gIH0gZWxzZSB7XG4gICAgdmFyIGVyO1xuICAgIGlmICghc2tpcENodW5rQ2hlY2spIGVyID0gY2h1bmtJbnZhbGlkKHN0YXRlLCBjaHVuayk7XG4gICAgaWYgKGVyKSB7XG4gICAgICBlcnJvck9yRGVzdHJveShzdHJlYW0sIGVyKTtcbiAgICB9IGVsc2UgaWYgKHN0YXRlLm9iamVjdE1vZGUgfHwgY2h1bmsgJiYgY2h1bmsubGVuZ3RoID4gMCkge1xuICAgICAgaWYgKHR5cGVvZiBjaHVuayAhPT0gJ3N0cmluZycgJiYgIXN0YXRlLm9iamVjdE1vZGUgJiYgT2JqZWN0LmdldFByb3RvdHlwZU9mKGNodW5rKSAhPT0gQnVmZmVyLnByb3RvdHlwZSkge1xuICAgICAgICBjaHVuayA9IF91aW50OEFycmF5VG9CdWZmZXIoY2h1bmspO1xuICAgICAgfVxuICAgICAgaWYgKGFkZFRvRnJvbnQpIHtcbiAgICAgICAgaWYgKHN0YXRlLmVuZEVtaXR0ZWQpIGVycm9yT3JEZXN0cm95KHN0cmVhbSwgbmV3IEVSUl9TVFJFQU1fVU5TSElGVF9BRlRFUl9FTkRfRVZFTlQoKSk7ZWxzZSBhZGRDaHVuayhzdHJlYW0sIHN0YXRlLCBjaHVuaywgdHJ1ZSk7XG4gICAgICB9IGVsc2UgaWYgKHN0YXRlLmVuZGVkKSB7XG4gICAgICAgIGVycm9yT3JEZXN0cm95KHN0cmVhbSwgbmV3IEVSUl9TVFJFQU1fUFVTSF9BRlRFUl9FT0YoKSk7XG4gICAgICB9IGVsc2UgaWYgKHN0YXRlLmRlc3Ryb3llZCkge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBzdGF0ZS5yZWFkaW5nID0gZmFsc2U7XG4gICAgICAgIGlmIChzdGF0ZS5kZWNvZGVyICYmICFlbmNvZGluZykge1xuICAgICAgICAgIGNodW5rID0gc3RhdGUuZGVjb2Rlci53cml0ZShjaHVuayk7XG4gICAgICAgICAgaWYgKHN0YXRlLm9iamVjdE1vZGUgfHwgY2h1bmsubGVuZ3RoICE9PSAwKSBhZGRDaHVuayhzdHJlYW0sIHN0YXRlLCBjaHVuaywgZmFsc2UpO2Vsc2UgbWF5YmVSZWFkTW9yZShzdHJlYW0sIHN0YXRlKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBhZGRDaHVuayhzdHJlYW0sIHN0YXRlLCBjaHVuaywgZmFsc2UpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSBlbHNlIGlmICghYWRkVG9Gcm9udCkge1xuICAgICAgc3RhdGUucmVhZGluZyA9IGZhbHNlO1xuICAgICAgbWF5YmVSZWFkTW9yZShzdHJlYW0sIHN0YXRlKTtcbiAgICB9XG4gIH1cblxuICAvLyBXZSBjYW4gcHVzaCBtb3JlIGRhdGEgaWYgd2UgYXJlIGJlbG93IHRoZSBoaWdoV2F0ZXJNYXJrLlxuICAvLyBBbHNvLCBpZiB3ZSBoYXZlIG5vIGRhdGEgeWV0LCB3ZSBjYW4gc3RhbmQgc29tZSBtb3JlIGJ5dGVzLlxuICAvLyBUaGlzIGlzIHRvIHdvcmsgYXJvdW5kIGNhc2VzIHdoZXJlIGh3bT0wLCBzdWNoIGFzIHRoZSByZXBsLlxuICByZXR1cm4gIXN0YXRlLmVuZGVkICYmIChzdGF0ZS5sZW5ndGggPCBzdGF0ZS5oaWdoV2F0ZXJNYXJrIHx8IHN0YXRlLmxlbmd0aCA9PT0gMCk7XG59XG5mdW5jdGlvbiBhZGRDaHVuayhzdHJlYW0sIHN0YXRlLCBjaHVuaywgYWRkVG9Gcm9udCkge1xuICBpZiAoc3RhdGUuZmxvd2luZyAmJiBzdGF0ZS5sZW5ndGggPT09IDAgJiYgIXN0YXRlLnN5bmMpIHtcbiAgICBzdGF0ZS5hd2FpdERyYWluID0gMDtcbiAgICBzdHJlYW0uZW1pdCgnZGF0YScsIGNodW5rKTtcbiAgfSBlbHNlIHtcbiAgICAvLyB1cGRhdGUgdGhlIGJ1ZmZlciBpbmZvLlxuICAgIHN0YXRlLmxlbmd0aCArPSBzdGF0ZS5vYmplY3RNb2RlID8gMSA6IGNodW5rLmxlbmd0aDtcbiAgICBpZiAoYWRkVG9Gcm9udCkgc3RhdGUuYnVmZmVyLnVuc2hpZnQoY2h1bmspO2Vsc2Ugc3RhdGUuYnVmZmVyLnB1c2goY2h1bmspO1xuICAgIGlmIChzdGF0ZS5uZWVkUmVhZGFibGUpIGVtaXRSZWFkYWJsZShzdHJlYW0pO1xuICB9XG4gIG1heWJlUmVhZE1vcmUoc3RyZWFtLCBzdGF0ZSk7XG59XG5mdW5jdGlvbiBjaHVua0ludmFsaWQoc3RhdGUsIGNodW5rKSB7XG4gIHZhciBlcjtcbiAgaWYgKCFfaXNVaW50OEFycmF5KGNodW5rKSAmJiB0eXBlb2YgY2h1bmsgIT09ICdzdHJpbmcnICYmIGNodW5rICE9PSB1bmRlZmluZWQgJiYgIXN0YXRlLm9iamVjdE1vZGUpIHtcbiAgICBlciA9IG5ldyBFUlJfSU5WQUxJRF9BUkdfVFlQRSgnY2h1bmsnLCBbJ3N0cmluZycsICdCdWZmZXInLCAnVWludDhBcnJheSddLCBjaHVuayk7XG4gIH1cbiAgcmV0dXJuIGVyO1xufVxuUmVhZGFibGUucHJvdG90eXBlLmlzUGF1c2VkID0gZnVuY3Rpb24gKCkge1xuICByZXR1cm4gdGhpcy5fcmVhZGFibGVTdGF0ZS5mbG93aW5nID09PSBmYWxzZTtcbn07XG5cbi8vIGJhY2t3YXJkcyBjb21wYXRpYmlsaXR5LlxuUmVhZGFibGUucHJvdG90eXBlLnNldEVuY29kaW5nID0gZnVuY3Rpb24gKGVuYykge1xuICBpZiAoIVN0cmluZ0RlY29kZXIpIFN0cmluZ0RlY29kZXIgPSByZXF1aXJlKCdzdHJpbmdfZGVjb2Rlci8nKS5TdHJpbmdEZWNvZGVyO1xuICB2YXIgZGVjb2RlciA9IG5ldyBTdHJpbmdEZWNvZGVyKGVuYyk7XG4gIHRoaXMuX3JlYWRhYmxlU3RhdGUuZGVjb2RlciA9IGRlY29kZXI7XG4gIC8vIElmIHNldEVuY29kaW5nKG51bGwpLCBkZWNvZGVyLmVuY29kaW5nIGVxdWFscyB1dGY4XG4gIHRoaXMuX3JlYWRhYmxlU3RhdGUuZW5jb2RpbmcgPSB0aGlzLl9yZWFkYWJsZVN0YXRlLmRlY29kZXIuZW5jb2Rpbmc7XG5cbiAgLy8gSXRlcmF0ZSBvdmVyIGN1cnJlbnQgYnVmZmVyIHRvIGNvbnZlcnQgYWxyZWFkeSBzdG9yZWQgQnVmZmVyczpcbiAgdmFyIHAgPSB0aGlzLl9yZWFkYWJsZVN0YXRlLmJ1ZmZlci5oZWFkO1xuICB2YXIgY29udGVudCA9ICcnO1xuICB3aGlsZSAocCAhPT0gbnVsbCkge1xuICAgIGNvbnRlbnQgKz0gZGVjb2Rlci53cml0ZShwLmRhdGEpO1xuICAgIHAgPSBwLm5leHQ7XG4gIH1cbiAgdGhpcy5fcmVhZGFibGVTdGF0ZS5idWZmZXIuY2xlYXIoKTtcbiAgaWYgKGNvbnRlbnQgIT09ICcnKSB0aGlzLl9yZWFkYWJsZVN0YXRlLmJ1ZmZlci5wdXNoKGNvbnRlbnQpO1xuICB0aGlzLl9yZWFkYWJsZVN0YXRlLmxlbmd0aCA9IGNvbnRlbnQubGVuZ3RoO1xuICByZXR1cm4gdGhpcztcbn07XG5cbi8vIERvbid0IHJhaXNlIHRoZSBod20gPiAxR0JcbnZhciBNQVhfSFdNID0gMHg0MDAwMDAwMDtcbmZ1bmN0aW9uIGNvbXB1dGVOZXdIaWdoV2F0ZXJNYXJrKG4pIHtcbiAgaWYgKG4gPj0gTUFYX0hXTSkge1xuICAgIC8vIFRPRE8ocm9uYWcpOiBUaHJvdyBFUlJfVkFMVUVfT1VUX09GX1JBTkdFLlxuICAgIG4gPSBNQVhfSFdNO1xuICB9IGVsc2Uge1xuICAgIC8vIEdldCB0aGUgbmV4dCBoaWdoZXN0IHBvd2VyIG9mIDIgdG8gcHJldmVudCBpbmNyZWFzaW5nIGh3bSBleGNlc3NpdmVseSBpblxuICAgIC8vIHRpbnkgYW1vdW50c1xuICAgIG4tLTtcbiAgICBuIHw9IG4gPj4+IDE7XG4gICAgbiB8PSBuID4+PiAyO1xuICAgIG4gfD0gbiA+Pj4gNDtcbiAgICBuIHw9IG4gPj4+IDg7XG4gICAgbiB8PSBuID4+PiAxNjtcbiAgICBuKys7XG4gIH1cbiAgcmV0dXJuIG47XG59XG5cbi8vIFRoaXMgZnVuY3Rpb24gaXMgZGVzaWduZWQgdG8gYmUgaW5saW5hYmxlLCBzbyBwbGVhc2UgdGFrZSBjYXJlIHdoZW4gbWFraW5nXG4vLyBjaGFuZ2VzIHRvIHRoZSBmdW5jdGlvbiBib2R5LlxuZnVuY3Rpb24gaG93TXVjaFRvUmVhZChuLCBzdGF0ZSkge1xuICBpZiAobiA8PSAwIHx8IHN0YXRlLmxlbmd0aCA9PT0gMCAmJiBzdGF0ZS5lbmRlZCkgcmV0dXJuIDA7XG4gIGlmIChzdGF0ZS5vYmplY3RNb2RlKSByZXR1cm4gMTtcbiAgaWYgKG4gIT09IG4pIHtcbiAgICAvLyBPbmx5IGZsb3cgb25lIGJ1ZmZlciBhdCBhIHRpbWVcbiAgICBpZiAoc3RhdGUuZmxvd2luZyAmJiBzdGF0ZS5sZW5ndGgpIHJldHVybiBzdGF0ZS5idWZmZXIuaGVhZC5kYXRhLmxlbmd0aDtlbHNlIHJldHVybiBzdGF0ZS5sZW5ndGg7XG4gIH1cbiAgLy8gSWYgd2UncmUgYXNraW5nIGZvciBtb3JlIHRoYW4gdGhlIGN1cnJlbnQgaHdtLCB0aGVuIHJhaXNlIHRoZSBod20uXG4gIGlmIChuID4gc3RhdGUuaGlnaFdhdGVyTWFyaykgc3RhdGUuaGlnaFdhdGVyTWFyayA9IGNvbXB1dGVOZXdIaWdoV2F0ZXJNYXJrKG4pO1xuICBpZiAobiA8PSBzdGF0ZS5sZW5ndGgpIHJldHVybiBuO1xuICAvLyBEb24ndCBoYXZlIGVub3VnaFxuICBpZiAoIXN0YXRlLmVuZGVkKSB7XG4gICAgc3RhdGUubmVlZFJlYWRhYmxlID0gdHJ1ZTtcbiAgICByZXR1cm4gMDtcbiAgfVxuICByZXR1cm4gc3RhdGUubGVuZ3RoO1xufVxuXG4vLyB5b3UgY2FuIG92ZXJyaWRlIGVpdGhlciB0aGlzIG1ldGhvZCwgb3IgdGhlIGFzeW5jIF9yZWFkKG4pIGJlbG93LlxuUmVhZGFibGUucHJvdG90eXBlLnJlYWQgPSBmdW5jdGlvbiAobikge1xuICBkZWJ1ZygncmVhZCcsIG4pO1xuICBuID0gcGFyc2VJbnQobiwgMTApO1xuICB2YXIgc3RhdGUgPSB0aGlzLl9yZWFkYWJsZVN0YXRlO1xuICB2YXIgbk9yaWcgPSBuO1xuICBpZiAobiAhPT0gMCkgc3RhdGUuZW1pdHRlZFJlYWRhYmxlID0gZmFsc2U7XG5cbiAgLy8gaWYgd2UncmUgZG9pbmcgcmVhZCgwKSB0byB0cmlnZ2VyIGEgcmVhZGFibGUgZXZlbnQsIGJ1dCB3ZVxuICAvLyBhbHJlYWR5IGhhdmUgYSBidW5jaCBvZiBkYXRhIGluIHRoZSBidWZmZXIsIHRoZW4ganVzdCB0cmlnZ2VyXG4gIC8vIHRoZSAncmVhZGFibGUnIGV2ZW50IGFuZCBtb3ZlIG9uLlxuICBpZiAobiA9PT0gMCAmJiBzdGF0ZS5uZWVkUmVhZGFibGUgJiYgKChzdGF0ZS5oaWdoV2F0ZXJNYXJrICE9PSAwID8gc3RhdGUubGVuZ3RoID49IHN0YXRlLmhpZ2hXYXRlck1hcmsgOiBzdGF0ZS5sZW5ndGggPiAwKSB8fCBzdGF0ZS5lbmRlZCkpIHtcbiAgICBkZWJ1ZygncmVhZDogZW1pdFJlYWRhYmxlJywgc3RhdGUubGVuZ3RoLCBzdGF0ZS5lbmRlZCk7XG4gICAgaWYgKHN0YXRlLmxlbmd0aCA9PT0gMCAmJiBzdGF0ZS5lbmRlZCkgZW5kUmVhZGFibGUodGhpcyk7ZWxzZSBlbWl0UmVhZGFibGUodGhpcyk7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cbiAgbiA9IGhvd011Y2hUb1JlYWQobiwgc3RhdGUpO1xuXG4gIC8vIGlmIHdlJ3ZlIGVuZGVkLCBhbmQgd2UncmUgbm93IGNsZWFyLCB0aGVuIGZpbmlzaCBpdCB1cC5cbiAgaWYgKG4gPT09IDAgJiYgc3RhdGUuZW5kZWQpIHtcbiAgICBpZiAoc3RhdGUubGVuZ3RoID09PSAwKSBlbmRSZWFkYWJsZSh0aGlzKTtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIC8vIEFsbCB0aGUgYWN0dWFsIGNodW5rIGdlbmVyYXRpb24gbG9naWMgbmVlZHMgdG8gYmVcbiAgLy8gKmJlbG93KiB0aGUgY2FsbCB0byBfcmVhZC4gIFRoZSByZWFzb24gaXMgdGhhdCBpbiBjZXJ0YWluXG4gIC8vIHN5bnRoZXRpYyBzdHJlYW0gY2FzZXMsIHN1Y2ggYXMgcGFzc3Rocm91Z2ggc3RyZWFtcywgX3JlYWRcbiAgLy8gbWF5IGJlIGEgY29tcGxldGVseSBzeW5jaHJvbm91cyBvcGVyYXRpb24gd2hpY2ggbWF5IGNoYW5nZVxuICAvLyB0aGUgc3RhdGUgb2YgdGhlIHJlYWQgYnVmZmVyLCBwcm92aWRpbmcgZW5vdWdoIGRhdGEgd2hlblxuICAvLyBiZWZvcmUgdGhlcmUgd2FzICpub3QqIGVub3VnaC5cbiAgLy9cbiAgLy8gU28sIHRoZSBzdGVwcyBhcmU6XG4gIC8vIDEuIEZpZ3VyZSBvdXQgd2hhdCB0aGUgc3RhdGUgb2YgdGhpbmdzIHdpbGwgYmUgYWZ0ZXIgd2UgZG9cbiAgLy8gYSByZWFkIGZyb20gdGhlIGJ1ZmZlci5cbiAgLy9cbiAgLy8gMi4gSWYgdGhhdCByZXN1bHRpbmcgc3RhdGUgd2lsbCB0cmlnZ2VyIGEgX3JlYWQsIHRoZW4gY2FsbCBfcmVhZC5cbiAgLy8gTm90ZSB0aGF0IHRoaXMgbWF5IGJlIGFzeW5jaHJvbm91cywgb3Igc3luY2hyb25vdXMuICBZZXMsIGl0IGlzXG4gIC8vIGRlZXBseSB1Z2x5IHRvIHdyaXRlIEFQSXMgdGhpcyB3YXksIGJ1dCB0aGF0IHN0aWxsIGRvZXNuJ3QgbWVhblxuICAvLyB0aGF0IHRoZSBSZWFkYWJsZSBjbGFzcyBzaG91bGQgYmVoYXZlIGltcHJvcGVybHksIGFzIHN0cmVhbXMgYXJlXG4gIC8vIGRlc2lnbmVkIHRvIGJlIHN5bmMvYXN5bmMgYWdub3N0aWMuXG4gIC8vIFRha2Ugbm90ZSBpZiB0aGUgX3JlYWQgY2FsbCBpcyBzeW5jIG9yIGFzeW5jIChpZSwgaWYgdGhlIHJlYWQgY2FsbFxuICAvLyBoYXMgcmV0dXJuZWQgeWV0KSwgc28gdGhhdCB3ZSBrbm93IHdoZXRoZXIgb3Igbm90IGl0J3Mgc2FmZSB0byBlbWl0XG4gIC8vICdyZWFkYWJsZScgZXRjLlxuICAvL1xuICAvLyAzLiBBY3R1YWxseSBwdWxsIHRoZSByZXF1ZXN0ZWQgY2h1bmtzIG91dCBvZiB0aGUgYnVmZmVyIGFuZCByZXR1cm4uXG5cbiAgLy8gaWYgd2UgbmVlZCBhIHJlYWRhYmxlIGV2ZW50LCB0aGVuIHdlIG5lZWQgdG8gZG8gc29tZSByZWFkaW5nLlxuICB2YXIgZG9SZWFkID0gc3RhdGUubmVlZFJlYWRhYmxlO1xuICBkZWJ1ZygnbmVlZCByZWFkYWJsZScsIGRvUmVhZCk7XG5cbiAgLy8gaWYgd2UgY3VycmVudGx5IGhhdmUgbGVzcyB0aGFuIHRoZSBoaWdoV2F0ZXJNYXJrLCB0aGVuIGFsc28gcmVhZCBzb21lXG4gIGlmIChzdGF0ZS5sZW5ndGggPT09IDAgfHwgc3RhdGUubGVuZ3RoIC0gbiA8IHN0YXRlLmhpZ2hXYXRlck1hcmspIHtcbiAgICBkb1JlYWQgPSB0cnVlO1xuICAgIGRlYnVnKCdsZW5ndGggbGVzcyB0aGFuIHdhdGVybWFyaycsIGRvUmVhZCk7XG4gIH1cblxuICAvLyBob3dldmVyLCBpZiB3ZSd2ZSBlbmRlZCwgdGhlbiB0aGVyZSdzIG5vIHBvaW50LCBhbmQgaWYgd2UncmUgYWxyZWFkeVxuICAvLyByZWFkaW5nLCB0aGVuIGl0J3MgdW5uZWNlc3NhcnkuXG4gIGlmIChzdGF0ZS5lbmRlZCB8fCBzdGF0ZS5yZWFkaW5nKSB7XG4gICAgZG9SZWFkID0gZmFsc2U7XG4gICAgZGVidWcoJ3JlYWRpbmcgb3IgZW5kZWQnLCBkb1JlYWQpO1xuICB9IGVsc2UgaWYgKGRvUmVhZCkge1xuICAgIGRlYnVnKCdkbyByZWFkJyk7XG4gICAgc3RhdGUucmVhZGluZyA9IHRydWU7XG4gICAgc3RhdGUuc3luYyA9IHRydWU7XG4gICAgLy8gaWYgdGhlIGxlbmd0aCBpcyBjdXJyZW50bHkgemVybywgdGhlbiB3ZSAqbmVlZCogYSByZWFkYWJsZSBldmVudC5cbiAgICBpZiAoc3RhdGUubGVuZ3RoID09PSAwKSBzdGF0ZS5uZWVkUmVhZGFibGUgPSB0cnVlO1xuICAgIC8vIGNhbGwgaW50ZXJuYWwgcmVhZCBtZXRob2RcbiAgICB0aGlzLl9yZWFkKHN0YXRlLmhpZ2hXYXRlck1hcmspO1xuICAgIHN0YXRlLnN5bmMgPSBmYWxzZTtcbiAgICAvLyBJZiBfcmVhZCBwdXNoZWQgZGF0YSBzeW5jaHJvbm91c2x5LCB0aGVuIGByZWFkaW5nYCB3aWxsIGJlIGZhbHNlLFxuICAgIC8vIGFuZCB3ZSBuZWVkIHRvIHJlLWV2YWx1YXRlIGhvdyBtdWNoIGRhdGEgd2UgY2FuIHJldHVybiB0byB0aGUgdXNlci5cbiAgICBpZiAoIXN0YXRlLnJlYWRpbmcpIG4gPSBob3dNdWNoVG9SZWFkKG5PcmlnLCBzdGF0ZSk7XG4gIH1cbiAgdmFyIHJldDtcbiAgaWYgKG4gPiAwKSByZXQgPSBmcm9tTGlzdChuLCBzdGF0ZSk7ZWxzZSByZXQgPSBudWxsO1xuICBpZiAocmV0ID09PSBudWxsKSB7XG4gICAgc3RhdGUubmVlZFJlYWRhYmxlID0gc3RhdGUubGVuZ3RoIDw9IHN0YXRlLmhpZ2hXYXRlck1hcms7XG4gICAgbiA9IDA7XG4gIH0gZWxzZSB7XG4gICAgc3RhdGUubGVuZ3RoIC09IG47XG4gICAgc3RhdGUuYXdhaXREcmFpbiA9IDA7XG4gIH1cbiAgaWYgKHN0YXRlLmxlbmd0aCA9PT0gMCkge1xuICAgIC8vIElmIHdlIGhhdmUgbm90aGluZyBpbiB0aGUgYnVmZmVyLCB0aGVuIHdlIHdhbnQgdG8ga25vd1xuICAgIC8vIGFzIHNvb24gYXMgd2UgKmRvKiBnZXQgc29tZXRoaW5nIGludG8gdGhlIGJ1ZmZlci5cbiAgICBpZiAoIXN0YXRlLmVuZGVkKSBzdGF0ZS5uZWVkUmVhZGFibGUgPSB0cnVlO1xuXG4gICAgLy8gSWYgd2UgdHJpZWQgdG8gcmVhZCgpIHBhc3QgdGhlIEVPRiwgdGhlbiBlbWl0IGVuZCBvbiB0aGUgbmV4dCB0aWNrLlxuICAgIGlmIChuT3JpZyAhPT0gbiAmJiBzdGF0ZS5lbmRlZCkgZW5kUmVhZGFibGUodGhpcyk7XG4gIH1cbiAgaWYgKHJldCAhPT0gbnVsbCkgdGhpcy5lbWl0KCdkYXRhJywgcmV0KTtcbiAgcmV0dXJuIHJldDtcbn07XG5mdW5jdGlvbiBvbkVvZkNodW5rKHN0cmVhbSwgc3RhdGUpIHtcbiAgZGVidWcoJ29uRW9mQ2h1bmsnKTtcbiAgaWYgKHN0YXRlLmVuZGVkKSByZXR1cm47XG4gIGlmIChzdGF0ZS5kZWNvZGVyKSB7XG4gICAgdmFyIGNodW5rID0gc3RhdGUuZGVjb2Rlci5lbmQoKTtcbiAgICBpZiAoY2h1bmsgJiYgY2h1bmsubGVuZ3RoKSB7XG4gICAgICBzdGF0ZS5idWZmZXIucHVzaChjaHVuayk7XG4gICAgICBzdGF0ZS5sZW5ndGggKz0gc3RhdGUub2JqZWN0TW9kZSA/IDEgOiBjaHVuay5sZW5ndGg7XG4gICAgfVxuICB9XG4gIHN0YXRlLmVuZGVkID0gdHJ1ZTtcbiAgaWYgKHN0YXRlLnN5bmMpIHtcbiAgICAvLyBpZiB3ZSBhcmUgc3luYywgd2FpdCB1bnRpbCBuZXh0IHRpY2sgdG8gZW1pdCB0aGUgZGF0YS5cbiAgICAvLyBPdGhlcndpc2Ugd2UgcmlzayBlbWl0dGluZyBkYXRhIGluIHRoZSBmbG93KClcbiAgICAvLyB0aGUgcmVhZGFibGUgY29kZSB0cmlnZ2VycyBkdXJpbmcgYSByZWFkKCkgY2FsbFxuICAgIGVtaXRSZWFkYWJsZShzdHJlYW0pO1xuICB9IGVsc2Uge1xuICAgIC8vIGVtaXQgJ3JlYWRhYmxlJyBub3cgdG8gbWFrZSBzdXJlIGl0IGdldHMgcGlja2VkIHVwLlxuICAgIHN0YXRlLm5lZWRSZWFkYWJsZSA9IGZhbHNlO1xuICAgIGlmICghc3RhdGUuZW1pdHRlZFJlYWRhYmxlKSB7XG4gICAgICBzdGF0ZS5lbWl0dGVkUmVhZGFibGUgPSB0cnVlO1xuICAgICAgZW1pdFJlYWRhYmxlXyhzdHJlYW0pO1xuICAgIH1cbiAgfVxufVxuXG4vLyBEb24ndCBlbWl0IHJlYWRhYmxlIHJpZ2h0IGF3YXkgaW4gc3luYyBtb2RlLCBiZWNhdXNlIHRoaXMgY2FuIHRyaWdnZXJcbi8vIGFub3RoZXIgcmVhZCgpIGNhbGwgPT4gc3RhY2sgb3ZlcmZsb3cuICBUaGlzIHdheSwgaXQgbWlnaHQgdHJpZ2dlclxuLy8gYSBuZXh0VGljayByZWN1cnNpb24gd2FybmluZywgYnV0IHRoYXQncyBub3Qgc28gYmFkLlxuZnVuY3Rpb24gZW1pdFJlYWRhYmxlKHN0cmVhbSkge1xuICB2YXIgc3RhdGUgPSBzdHJlYW0uX3JlYWRhYmxlU3RhdGU7XG4gIGRlYnVnKCdlbWl0UmVhZGFibGUnLCBzdGF0ZS5uZWVkUmVhZGFibGUsIHN0YXRlLmVtaXR0ZWRSZWFkYWJsZSk7XG4gIHN0YXRlLm5lZWRSZWFkYWJsZSA9IGZhbHNlO1xuICBpZiAoIXN0YXRlLmVtaXR0ZWRSZWFkYWJsZSkge1xuICAgIGRlYnVnKCdlbWl0UmVhZGFibGUnLCBzdGF0ZS5mbG93aW5nKTtcbiAgICBzdGF0ZS5lbWl0dGVkUmVhZGFibGUgPSB0cnVlO1xuICAgIHByb2Nlc3MubmV4dFRpY2soZW1pdFJlYWRhYmxlXywgc3RyZWFtKTtcbiAgfVxufVxuZnVuY3Rpb24gZW1pdFJlYWRhYmxlXyhzdHJlYW0pIHtcbiAgdmFyIHN0YXRlID0gc3RyZWFtLl9yZWFkYWJsZVN0YXRlO1xuICBkZWJ1ZygnZW1pdFJlYWRhYmxlXycsIHN0YXRlLmRlc3Ryb3llZCwgc3RhdGUubGVuZ3RoLCBzdGF0ZS5lbmRlZCk7XG4gIGlmICghc3RhdGUuZGVzdHJveWVkICYmIChzdGF0ZS5sZW5ndGggfHwgc3RhdGUuZW5kZWQpKSB7XG4gICAgc3RyZWFtLmVtaXQoJ3JlYWRhYmxlJyk7XG4gICAgc3RhdGUuZW1pdHRlZFJlYWRhYmxlID0gZmFsc2U7XG4gIH1cblxuICAvLyBUaGUgc3RyZWFtIG5lZWRzIGFub3RoZXIgcmVhZGFibGUgZXZlbnQgaWZcbiAgLy8gMS4gSXQgaXMgbm90IGZsb3dpbmcsIGFzIHRoZSBmbG93IG1lY2hhbmlzbSB3aWxsIHRha2VcbiAgLy8gICAgY2FyZSBvZiBpdC5cbiAgLy8gMi4gSXQgaXMgbm90IGVuZGVkLlxuICAvLyAzLiBJdCBpcyBiZWxvdyB0aGUgaGlnaFdhdGVyTWFyaywgc28gd2UgY2FuIHNjaGVkdWxlXG4gIC8vICAgIGFub3RoZXIgcmVhZGFibGUgbGF0ZXIuXG4gIHN0YXRlLm5lZWRSZWFkYWJsZSA9ICFzdGF0ZS5mbG93aW5nICYmICFzdGF0ZS5lbmRlZCAmJiBzdGF0ZS5sZW5ndGggPD0gc3RhdGUuaGlnaFdhdGVyTWFyaztcbiAgZmxvdyhzdHJlYW0pO1xufVxuXG4vLyBhdCB0aGlzIHBvaW50LCB0aGUgdXNlciBoYXMgcHJlc3VtYWJseSBzZWVuIHRoZSAncmVhZGFibGUnIGV2ZW50LFxuLy8gYW5kIGNhbGxlZCByZWFkKCkgdG8gY29uc3VtZSBzb21lIGRhdGEuICB0aGF0IG1heSBoYXZlIHRyaWdnZXJlZFxuLy8gaW4gdHVybiBhbm90aGVyIF9yZWFkKG4pIGNhbGwsIGluIHdoaWNoIGNhc2UgcmVhZGluZyA9IHRydWUgaWZcbi8vIGl0J3MgaW4gcHJvZ3Jlc3MuXG4vLyBIb3dldmVyLCBpZiB3ZSdyZSBub3QgZW5kZWQsIG9yIHJlYWRpbmcsIGFuZCB0aGUgbGVuZ3RoIDwgaHdtLFxuLy8gdGhlbiBnbyBhaGVhZCBhbmQgdHJ5IHRvIHJlYWQgc29tZSBtb3JlIHByZWVtcHRpdmVseS5cbmZ1bmN0aW9uIG1heWJlUmVhZE1vcmUoc3RyZWFtLCBzdGF0ZSkge1xuICBpZiAoIXN0YXRlLnJlYWRpbmdNb3JlKSB7XG4gICAgc3RhdGUucmVhZGluZ01vcmUgPSB0cnVlO1xuICAgIHByb2Nlc3MubmV4dFRpY2sobWF5YmVSZWFkTW9yZV8sIHN0cmVhbSwgc3RhdGUpO1xuICB9XG59XG5mdW5jdGlvbiBtYXliZVJlYWRNb3JlXyhzdHJlYW0sIHN0YXRlKSB7XG4gIC8vIEF0dGVtcHQgdG8gcmVhZCBtb3JlIGRhdGEgaWYgd2Ugc2hvdWxkLlxuICAvL1xuICAvLyBUaGUgY29uZGl0aW9ucyBmb3IgcmVhZGluZyBtb3JlIGRhdGEgYXJlIChvbmUgb2YpOlxuICAvLyAtIE5vdCBlbm91Z2ggZGF0YSBidWZmZXJlZCAoc3RhdGUubGVuZ3RoIDwgc3RhdGUuaGlnaFdhdGVyTWFyaykuIFRoZSBsb29wXG4gIC8vICAgaXMgcmVzcG9uc2libGUgZm9yIGZpbGxpbmcgdGhlIGJ1ZmZlciB3aXRoIGVub3VnaCBkYXRhIGlmIHN1Y2ggZGF0YVxuICAvLyAgIGlzIGF2YWlsYWJsZS4gSWYgaGlnaFdhdGVyTWFyayBpcyAwIGFuZCB3ZSBhcmUgbm90IGluIHRoZSBmbG93aW5nIG1vZGVcbiAgLy8gICB3ZSBzaG91bGQgX25vdF8gYXR0ZW1wdCB0byBidWZmZXIgYW55IGV4dHJhIGRhdGEuIFdlJ2xsIGdldCBtb3JlIGRhdGFcbiAgLy8gICB3aGVuIHRoZSBzdHJlYW0gY29uc3VtZXIgY2FsbHMgcmVhZCgpIGluc3RlYWQuXG4gIC8vIC0gTm8gZGF0YSBpbiB0aGUgYnVmZmVyLCBhbmQgdGhlIHN0cmVhbSBpcyBpbiBmbG93aW5nIG1vZGUuIEluIHRoaXMgbW9kZVxuICAvLyAgIHRoZSBsb29wIGJlbG93IGlzIHJlc3BvbnNpYmxlIGZvciBlbnN1cmluZyByZWFkKCkgaXMgY2FsbGVkLiBGYWlsaW5nIHRvXG4gIC8vICAgY2FsbCByZWFkIGhlcmUgd291bGQgYWJvcnQgdGhlIGZsb3cgYW5kIHRoZXJlJ3Mgbm8gb3RoZXIgbWVjaGFuaXNtIGZvclxuICAvLyAgIGNvbnRpbnVpbmcgdGhlIGZsb3cgaWYgdGhlIHN0cmVhbSBjb25zdW1lciBoYXMganVzdCBzdWJzY3JpYmVkIHRvIHRoZVxuICAvLyAgICdkYXRhJyBldmVudC5cbiAgLy9cbiAgLy8gSW4gYWRkaXRpb24gdG8gdGhlIGFib3ZlIGNvbmRpdGlvbnMgdG8ga2VlcCByZWFkaW5nIGRhdGEsIHRoZSBmb2xsb3dpbmdcbiAgLy8gY29uZGl0aW9ucyBwcmV2ZW50IHRoZSBkYXRhIGZyb20gYmVpbmcgcmVhZDpcbiAgLy8gLSBUaGUgc3RyZWFtIGhhcyBlbmRlZCAoc3RhdGUuZW5kZWQpLlxuICAvLyAtIFRoZXJlIGlzIGFscmVhZHkgYSBwZW5kaW5nICdyZWFkJyBvcGVyYXRpb24gKHN0YXRlLnJlYWRpbmcpLiBUaGlzIGlzIGFcbiAgLy8gICBjYXNlIHdoZXJlIHRoZSB0aGUgc3RyZWFtIGhhcyBjYWxsZWQgdGhlIGltcGxlbWVudGF0aW9uIGRlZmluZWQgX3JlYWQoKVxuICAvLyAgIG1ldGhvZCwgYnV0IHRoZXkgYXJlIHByb2Nlc3NpbmcgdGhlIGNhbGwgYXN5bmNocm9ub3VzbHkgYW5kIGhhdmUgX25vdF9cbiAgLy8gICBjYWxsZWQgcHVzaCgpIHdpdGggbmV3IGRhdGEuIEluIHRoaXMgY2FzZSB3ZSBza2lwIHBlcmZvcm1pbmcgbW9yZVxuICAvLyAgIHJlYWQoKXMuIFRoZSBleGVjdXRpb24gZW5kcyBpbiB0aGlzIG1ldGhvZCBhZ2FpbiBhZnRlciB0aGUgX3JlYWQoKSBlbmRzXG4gIC8vICAgdXAgY2FsbGluZyBwdXNoKCkgd2l0aCBtb3JlIGRhdGEuXG4gIHdoaWxlICghc3RhdGUucmVhZGluZyAmJiAhc3RhdGUuZW5kZWQgJiYgKHN0YXRlLmxlbmd0aCA8IHN0YXRlLmhpZ2hXYXRlck1hcmsgfHwgc3RhdGUuZmxvd2luZyAmJiBzdGF0ZS5sZW5ndGggPT09IDApKSB7XG4gICAgdmFyIGxlbiA9IHN0YXRlLmxlbmd0aDtcbiAgICBkZWJ1ZygnbWF5YmVSZWFkTW9yZSByZWFkIDAnKTtcbiAgICBzdHJlYW0ucmVhZCgwKTtcbiAgICBpZiAobGVuID09PSBzdGF0ZS5sZW5ndGgpXG4gICAgICAvLyBkaWRuJ3QgZ2V0IGFueSBkYXRhLCBzdG9wIHNwaW5uaW5nLlxuICAgICAgYnJlYWs7XG4gIH1cbiAgc3RhdGUucmVhZGluZ01vcmUgPSBmYWxzZTtcbn1cblxuLy8gYWJzdHJhY3QgbWV0aG9kLiAgdG8gYmUgb3ZlcnJpZGRlbiBpbiBzcGVjaWZpYyBpbXBsZW1lbnRhdGlvbiBjbGFzc2VzLlxuLy8gY2FsbCBjYihlciwgZGF0YSkgd2hlcmUgZGF0YSBpcyA8PSBuIGluIGxlbmd0aC5cbi8vIGZvciB2aXJ0dWFsIChub24tc3RyaW5nLCBub24tYnVmZmVyKSBzdHJlYW1zLCBcImxlbmd0aFwiIGlzIHNvbWV3aGF0XG4vLyBhcmJpdHJhcnksIGFuZCBwZXJoYXBzIG5vdCB2ZXJ5IG1lYW5pbmdmdWwuXG5SZWFkYWJsZS5wcm90b3R5cGUuX3JlYWQgPSBmdW5jdGlvbiAobikge1xuICBlcnJvck9yRGVzdHJveSh0aGlzLCBuZXcgRVJSX01FVEhPRF9OT1RfSU1QTEVNRU5URUQoJ19yZWFkKCknKSk7XG59O1xuUmVhZGFibGUucHJvdG90eXBlLnBpcGUgPSBmdW5jdGlvbiAoZGVzdCwgcGlwZU9wdHMpIHtcbiAgdmFyIHNyYyA9IHRoaXM7XG4gIHZhciBzdGF0ZSA9IHRoaXMuX3JlYWRhYmxlU3RhdGU7XG4gIHN3aXRjaCAoc3RhdGUucGlwZXNDb3VudCkge1xuICAgIGNhc2UgMDpcbiAgICAgIHN0YXRlLnBpcGVzID0gZGVzdDtcbiAgICAgIGJyZWFrO1xuICAgIGNhc2UgMTpcbiAgICAgIHN0YXRlLnBpcGVzID0gW3N0YXRlLnBpcGVzLCBkZXN0XTtcbiAgICAgIGJyZWFrO1xuICAgIGRlZmF1bHQ6XG4gICAgICBzdGF0ZS5waXBlcy5wdXNoKGRlc3QpO1xuICAgICAgYnJlYWs7XG4gIH1cbiAgc3RhdGUucGlwZXNDb3VudCArPSAxO1xuICBkZWJ1ZygncGlwZSBjb3VudD0lZCBvcHRzPSVqJywgc3RhdGUucGlwZXNDb3VudCwgcGlwZU9wdHMpO1xuICB2YXIgZG9FbmQgPSAoIXBpcGVPcHRzIHx8IHBpcGVPcHRzLmVuZCAhPT0gZmFsc2UpICYmIGRlc3QgIT09IHByb2Nlc3Muc3Rkb3V0ICYmIGRlc3QgIT09IHByb2Nlc3Muc3RkZXJyO1xuICB2YXIgZW5kRm4gPSBkb0VuZCA/IG9uZW5kIDogdW5waXBlO1xuICBpZiAoc3RhdGUuZW5kRW1pdHRlZCkgcHJvY2Vzcy5uZXh0VGljayhlbmRGbik7ZWxzZSBzcmMub25jZSgnZW5kJywgZW5kRm4pO1xuICBkZXN0Lm9uKCd1bnBpcGUnLCBvbnVucGlwZSk7XG4gIGZ1bmN0aW9uIG9udW5waXBlKHJlYWRhYmxlLCB1bnBpcGVJbmZvKSB7XG4gICAgZGVidWcoJ29udW5waXBlJyk7XG4gICAgaWYgKHJlYWRhYmxlID09PSBzcmMpIHtcbiAgICAgIGlmICh1bnBpcGVJbmZvICYmIHVucGlwZUluZm8uaGFzVW5waXBlZCA9PT0gZmFsc2UpIHtcbiAgICAgICAgdW5waXBlSW5mby5oYXNVbnBpcGVkID0gdHJ1ZTtcbiAgICAgICAgY2xlYW51cCgpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuICBmdW5jdGlvbiBvbmVuZCgpIHtcbiAgICBkZWJ1Zygnb25lbmQnKTtcbiAgICBkZXN0LmVuZCgpO1xuICB9XG5cbiAgLy8gd2hlbiB0aGUgZGVzdCBkcmFpbnMsIGl0IHJlZHVjZXMgdGhlIGF3YWl0RHJhaW4gY291bnRlclxuICAvLyBvbiB0aGUgc291cmNlLiAgVGhpcyB3b3VsZCBiZSBtb3JlIGVsZWdhbnQgd2l0aCBhIC5vbmNlKClcbiAgLy8gaGFuZGxlciBpbiBmbG93KCksIGJ1dCBhZGRpbmcgYW5kIHJlbW92aW5nIHJlcGVhdGVkbHkgaXNcbiAgLy8gdG9vIHNsb3cuXG4gIHZhciBvbmRyYWluID0gcGlwZU9uRHJhaW4oc3JjKTtcbiAgZGVzdC5vbignZHJhaW4nLCBvbmRyYWluKTtcbiAgdmFyIGNsZWFuZWRVcCA9IGZhbHNlO1xuICBmdW5jdGlvbiBjbGVhbnVwKCkge1xuICAgIGRlYnVnKCdjbGVhbnVwJyk7XG4gICAgLy8gY2xlYW51cCBldmVudCBoYW5kbGVycyBvbmNlIHRoZSBwaXBlIGlzIGJyb2tlblxuICAgIGRlc3QucmVtb3ZlTGlzdGVuZXIoJ2Nsb3NlJywgb25jbG9zZSk7XG4gICAgZGVzdC5yZW1vdmVMaXN0ZW5lcignZmluaXNoJywgb25maW5pc2gpO1xuICAgIGRlc3QucmVtb3ZlTGlzdGVuZXIoJ2RyYWluJywgb25kcmFpbik7XG4gICAgZGVzdC5yZW1vdmVMaXN0ZW5lcignZXJyb3InLCBvbmVycm9yKTtcbiAgICBkZXN0LnJlbW92ZUxpc3RlbmVyKCd1bnBpcGUnLCBvbnVucGlwZSk7XG4gICAgc3JjLnJlbW92ZUxpc3RlbmVyKCdlbmQnLCBvbmVuZCk7XG4gICAgc3JjLnJlbW92ZUxpc3RlbmVyKCdlbmQnLCB1bnBpcGUpO1xuICAgIHNyYy5yZW1vdmVMaXN0ZW5lcignZGF0YScsIG9uZGF0YSk7XG4gICAgY2xlYW5lZFVwID0gdHJ1ZTtcblxuICAgIC8vIGlmIHRoZSByZWFkZXIgaXMgd2FpdGluZyBmb3IgYSBkcmFpbiBldmVudCBmcm9tIHRoaXNcbiAgICAvLyBzcGVjaWZpYyB3cml0ZXIsIHRoZW4gaXQgd291bGQgY2F1c2UgaXQgdG8gbmV2ZXIgc3RhcnRcbiAgICAvLyBmbG93aW5nIGFnYWluLlxuICAgIC8vIFNvLCBpZiB0aGlzIGlzIGF3YWl0aW5nIGEgZHJhaW4sIHRoZW4gd2UganVzdCBjYWxsIGl0IG5vdy5cbiAgICAvLyBJZiB3ZSBkb24ndCBrbm93LCB0aGVuIGFzc3VtZSB0aGF0IHdlIGFyZSB3YWl0aW5nIGZvciBvbmUuXG4gICAgaWYgKHN0YXRlLmF3YWl0RHJhaW4gJiYgKCFkZXN0Ll93cml0YWJsZVN0YXRlIHx8IGRlc3QuX3dyaXRhYmxlU3RhdGUubmVlZERyYWluKSkgb25kcmFpbigpO1xuICB9XG4gIHNyYy5vbignZGF0YScsIG9uZGF0YSk7XG4gIGZ1bmN0aW9uIG9uZGF0YShjaHVuaykge1xuICAgIGRlYnVnKCdvbmRhdGEnKTtcbiAgICB2YXIgcmV0ID0gZGVzdC53cml0ZShjaHVuayk7XG4gICAgZGVidWcoJ2Rlc3Qud3JpdGUnLCByZXQpO1xuICAgIGlmIChyZXQgPT09IGZhbHNlKSB7XG4gICAgICAvLyBJZiB0aGUgdXNlciB1bnBpcGVkIGR1cmluZyBgZGVzdC53cml0ZSgpYCwgaXQgaXMgcG9zc2libGVcbiAgICAgIC8vIHRvIGdldCBzdHVjayBpbiBhIHBlcm1hbmVudGx5IHBhdXNlZCBzdGF0ZSBpZiB0aGF0IHdyaXRlXG4gICAgICAvLyBhbHNvIHJldHVybmVkIGZhbHNlLlxuICAgICAgLy8gPT4gQ2hlY2sgd2hldGhlciBgZGVzdGAgaXMgc3RpbGwgYSBwaXBpbmcgZGVzdGluYXRpb24uXG4gICAgICBpZiAoKHN0YXRlLnBpcGVzQ291bnQgPT09IDEgJiYgc3RhdGUucGlwZXMgPT09IGRlc3QgfHwgc3RhdGUucGlwZXNDb3VudCA+IDEgJiYgaW5kZXhPZihzdGF0ZS5waXBlcywgZGVzdCkgIT09IC0xKSAmJiAhY2xlYW5lZFVwKSB7XG4gICAgICAgIGRlYnVnKCdmYWxzZSB3cml0ZSByZXNwb25zZSwgcGF1c2UnLCBzdGF0ZS5hd2FpdERyYWluKTtcbiAgICAgICAgc3RhdGUuYXdhaXREcmFpbisrO1xuICAgICAgfVxuICAgICAgc3JjLnBhdXNlKCk7XG4gICAgfVxuICB9XG5cbiAgLy8gaWYgdGhlIGRlc3QgaGFzIGFuIGVycm9yLCB0aGVuIHN0b3AgcGlwaW5nIGludG8gaXQuXG4gIC8vIGhvd2V2ZXIsIGRvbid0IHN1cHByZXNzIHRoZSB0aHJvd2luZyBiZWhhdmlvciBmb3IgdGhpcy5cbiAgZnVuY3Rpb24gb25lcnJvcihlcikge1xuICAgIGRlYnVnKCdvbmVycm9yJywgZXIpO1xuICAgIHVucGlwZSgpO1xuICAgIGRlc3QucmVtb3ZlTGlzdGVuZXIoJ2Vycm9yJywgb25lcnJvcik7XG4gICAgaWYgKEVFbGlzdGVuZXJDb3VudChkZXN0LCAnZXJyb3InKSA9PT0gMCkgZXJyb3JPckRlc3Ryb3koZGVzdCwgZXIpO1xuICB9XG5cbiAgLy8gTWFrZSBzdXJlIG91ciBlcnJvciBoYW5kbGVyIGlzIGF0dGFjaGVkIGJlZm9yZSB1c2VybGFuZCBvbmVzLlxuICBwcmVwZW5kTGlzdGVuZXIoZGVzdCwgJ2Vycm9yJywgb25lcnJvcik7XG5cbiAgLy8gQm90aCBjbG9zZSBhbmQgZmluaXNoIHNob3VsZCB0cmlnZ2VyIHVucGlwZSwgYnV0IG9ubHkgb25jZS5cbiAgZnVuY3Rpb24gb25jbG9zZSgpIHtcbiAgICBkZXN0LnJlbW92ZUxpc3RlbmVyKCdmaW5pc2gnLCBvbmZpbmlzaCk7XG4gICAgdW5waXBlKCk7XG4gIH1cbiAgZGVzdC5vbmNlKCdjbG9zZScsIG9uY2xvc2UpO1xuICBmdW5jdGlvbiBvbmZpbmlzaCgpIHtcbiAgICBkZWJ1Zygnb25maW5pc2gnKTtcbiAgICBkZXN0LnJlbW92ZUxpc3RlbmVyKCdjbG9zZScsIG9uY2xvc2UpO1xuICAgIHVucGlwZSgpO1xuICB9XG4gIGRlc3Qub25jZSgnZmluaXNoJywgb25maW5pc2gpO1xuICBmdW5jdGlvbiB1bnBpcGUoKSB7XG4gICAgZGVidWcoJ3VucGlwZScpO1xuICAgIHNyYy51bnBpcGUoZGVzdCk7XG4gIH1cblxuICAvLyB0ZWxsIHRoZSBkZXN0IHRoYXQgaXQncyBiZWluZyBwaXBlZCB0b1xuICBkZXN0LmVtaXQoJ3BpcGUnLCBzcmMpO1xuXG4gIC8vIHN0YXJ0IHRoZSBmbG93IGlmIGl0IGhhc24ndCBiZWVuIHN0YXJ0ZWQgYWxyZWFkeS5cbiAgaWYgKCFzdGF0ZS5mbG93aW5nKSB7XG4gICAgZGVidWcoJ3BpcGUgcmVzdW1lJyk7XG4gICAgc3JjLnJlc3VtZSgpO1xuICB9XG4gIHJldHVybiBkZXN0O1xufTtcbmZ1bmN0aW9uIHBpcGVPbkRyYWluKHNyYykge1xuICByZXR1cm4gZnVuY3Rpb24gcGlwZU9uRHJhaW5GdW5jdGlvblJlc3VsdCgpIHtcbiAgICB2YXIgc3RhdGUgPSBzcmMuX3JlYWRhYmxlU3RhdGU7XG4gICAgZGVidWcoJ3BpcGVPbkRyYWluJywgc3RhdGUuYXdhaXREcmFpbik7XG4gICAgaWYgKHN0YXRlLmF3YWl0RHJhaW4pIHN0YXRlLmF3YWl0RHJhaW4tLTtcbiAgICBpZiAoc3RhdGUuYXdhaXREcmFpbiA9PT0gMCAmJiBFRWxpc3RlbmVyQ291bnQoc3JjLCAnZGF0YScpKSB7XG4gICAgICBzdGF0ZS5mbG93aW5nID0gdHJ1ZTtcbiAgICAgIGZsb3coc3JjKTtcbiAgICB9XG4gIH07XG59XG5SZWFkYWJsZS5wcm90b3R5cGUudW5waXBlID0gZnVuY3Rpb24gKGRlc3QpIHtcbiAgdmFyIHN0YXRlID0gdGhpcy5fcmVhZGFibGVTdGF0ZTtcbiAgdmFyIHVucGlwZUluZm8gPSB7XG4gICAgaGFzVW5waXBlZDogZmFsc2VcbiAgfTtcblxuICAvLyBpZiB3ZSdyZSBub3QgcGlwaW5nIGFueXdoZXJlLCB0aGVuIGRvIG5vdGhpbmcuXG4gIGlmIChzdGF0ZS5waXBlc0NvdW50ID09PSAwKSByZXR1cm4gdGhpcztcblxuICAvLyBqdXN0IG9uZSBkZXN0aW5hdGlvbi4gIG1vc3QgY29tbW9uIGNhc2UuXG4gIGlmIChzdGF0ZS5waXBlc0NvdW50ID09PSAxKSB7XG4gICAgLy8gcGFzc2VkIGluIG9uZSwgYnV0IGl0J3Mgbm90IHRoZSByaWdodCBvbmUuXG4gICAgaWYgKGRlc3QgJiYgZGVzdCAhPT0gc3RhdGUucGlwZXMpIHJldHVybiB0aGlzO1xuICAgIGlmICghZGVzdCkgZGVzdCA9IHN0YXRlLnBpcGVzO1xuXG4gICAgLy8gZ290IGEgbWF0Y2guXG4gICAgc3RhdGUucGlwZXMgPSBudWxsO1xuICAgIHN0YXRlLnBpcGVzQ291bnQgPSAwO1xuICAgIHN0YXRlLmZsb3dpbmcgPSBmYWxzZTtcbiAgICBpZiAoZGVzdCkgZGVzdC5lbWl0KCd1bnBpcGUnLCB0aGlzLCB1bnBpcGVJbmZvKTtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIC8vIHNsb3cgY2FzZS4gbXVsdGlwbGUgcGlwZSBkZXN0aW5hdGlvbnMuXG5cbiAgaWYgKCFkZXN0KSB7XG4gICAgLy8gcmVtb3ZlIGFsbC5cbiAgICB2YXIgZGVzdHMgPSBzdGF0ZS5waXBlcztcbiAgICB2YXIgbGVuID0gc3RhdGUucGlwZXNDb3VudDtcbiAgICBzdGF0ZS5waXBlcyA9IG51bGw7XG4gICAgc3RhdGUucGlwZXNDb3VudCA9IDA7XG4gICAgc3RhdGUuZmxvd2luZyA9IGZhbHNlO1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuOyBpKyspIGRlc3RzW2ldLmVtaXQoJ3VucGlwZScsIHRoaXMsIHtcbiAgICAgIGhhc1VucGlwZWQ6IGZhbHNlXG4gICAgfSk7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICAvLyB0cnkgdG8gZmluZCB0aGUgcmlnaHQgb25lLlxuICB2YXIgaW5kZXggPSBpbmRleE9mKHN0YXRlLnBpcGVzLCBkZXN0KTtcbiAgaWYgKGluZGV4ID09PSAtMSkgcmV0dXJuIHRoaXM7XG4gIHN0YXRlLnBpcGVzLnNwbGljZShpbmRleCwgMSk7XG4gIHN0YXRlLnBpcGVzQ291bnQgLT0gMTtcbiAgaWYgKHN0YXRlLnBpcGVzQ291bnQgPT09IDEpIHN0YXRlLnBpcGVzID0gc3RhdGUucGlwZXNbMF07XG4gIGRlc3QuZW1pdCgndW5waXBlJywgdGhpcywgdW5waXBlSW5mbyk7XG4gIHJldHVybiB0aGlzO1xufTtcblxuLy8gc2V0IHVwIGRhdGEgZXZlbnRzIGlmIHRoZXkgYXJlIGFza2VkIGZvclxuLy8gRW5zdXJlIHJlYWRhYmxlIGxpc3RlbmVycyBldmVudHVhbGx5IGdldCBzb21ldGhpbmdcblJlYWRhYmxlLnByb3RvdHlwZS5vbiA9IGZ1bmN0aW9uIChldiwgZm4pIHtcbiAgdmFyIHJlcyA9IFN0cmVhbS5wcm90b3R5cGUub24uY2FsbCh0aGlzLCBldiwgZm4pO1xuICB2YXIgc3RhdGUgPSB0aGlzLl9yZWFkYWJsZVN0YXRlO1xuICBpZiAoZXYgPT09ICdkYXRhJykge1xuICAgIC8vIHVwZGF0ZSByZWFkYWJsZUxpc3RlbmluZyBzbyB0aGF0IHJlc3VtZSgpIG1heSBiZSBhIG5vLW9wXG4gICAgLy8gYSBmZXcgbGluZXMgZG93bi4gVGhpcyBpcyBuZWVkZWQgdG8gc3VwcG9ydCBvbmNlKCdyZWFkYWJsZScpLlxuICAgIHN0YXRlLnJlYWRhYmxlTGlzdGVuaW5nID0gdGhpcy5saXN0ZW5lckNvdW50KCdyZWFkYWJsZScpID4gMDtcblxuICAgIC8vIFRyeSBzdGFydCBmbG93aW5nIG9uIG5leHQgdGljayBpZiBzdHJlYW0gaXNuJ3QgZXhwbGljaXRseSBwYXVzZWRcbiAgICBpZiAoc3RhdGUuZmxvd2luZyAhPT0gZmFsc2UpIHRoaXMucmVzdW1lKCk7XG4gIH0gZWxzZSBpZiAoZXYgPT09ICdyZWFkYWJsZScpIHtcbiAgICBpZiAoIXN0YXRlLmVuZEVtaXR0ZWQgJiYgIXN0YXRlLnJlYWRhYmxlTGlzdGVuaW5nKSB7XG4gICAgICBzdGF0ZS5yZWFkYWJsZUxpc3RlbmluZyA9IHN0YXRlLm5lZWRSZWFkYWJsZSA9IHRydWU7XG4gICAgICBzdGF0ZS5mbG93aW5nID0gZmFsc2U7XG4gICAgICBzdGF0ZS5lbWl0dGVkUmVhZGFibGUgPSBmYWxzZTtcbiAgICAgIGRlYnVnKCdvbiByZWFkYWJsZScsIHN0YXRlLmxlbmd0aCwgc3RhdGUucmVhZGluZyk7XG4gICAgICBpZiAoc3RhdGUubGVuZ3RoKSB7XG4gICAgICAgIGVtaXRSZWFkYWJsZSh0aGlzKTtcbiAgICAgIH0gZWxzZSBpZiAoIXN0YXRlLnJlYWRpbmcpIHtcbiAgICAgICAgcHJvY2Vzcy5uZXh0VGljayhuUmVhZGluZ05leHRUaWNrLCB0aGlzKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cbiAgcmV0dXJuIHJlcztcbn07XG5SZWFkYWJsZS5wcm90b3R5cGUuYWRkTGlzdGVuZXIgPSBSZWFkYWJsZS5wcm90b3R5cGUub247XG5SZWFkYWJsZS5wcm90b3R5cGUucmVtb3ZlTGlzdGVuZXIgPSBmdW5jdGlvbiAoZXYsIGZuKSB7XG4gIHZhciByZXMgPSBTdHJlYW0ucHJvdG90eXBlLnJlbW92ZUxpc3RlbmVyLmNhbGwodGhpcywgZXYsIGZuKTtcbiAgaWYgKGV2ID09PSAncmVhZGFibGUnKSB7XG4gICAgLy8gV2UgbmVlZCB0byBjaGVjayBpZiB0aGVyZSBpcyBzb21lb25lIHN0aWxsIGxpc3RlbmluZyB0b1xuICAgIC8vIHJlYWRhYmxlIGFuZCByZXNldCB0aGUgc3RhdGUuIEhvd2V2ZXIgdGhpcyBuZWVkcyB0byBoYXBwZW5cbiAgICAvLyBhZnRlciByZWFkYWJsZSBoYXMgYmVlbiBlbWl0dGVkIGJ1dCBiZWZvcmUgSS9PIChuZXh0VGljaykgdG9cbiAgICAvLyBzdXBwb3J0IG9uY2UoJ3JlYWRhYmxlJywgZm4pIGN5Y2xlcy4gVGhpcyBtZWFucyB0aGF0IGNhbGxpbmdcbiAgICAvLyByZXN1bWUgd2l0aGluIHRoZSBzYW1lIHRpY2sgd2lsbCBoYXZlIG5vXG4gICAgLy8gZWZmZWN0LlxuICAgIHByb2Nlc3MubmV4dFRpY2sodXBkYXRlUmVhZGFibGVMaXN0ZW5pbmcsIHRoaXMpO1xuICB9XG4gIHJldHVybiByZXM7XG59O1xuUmVhZGFibGUucHJvdG90eXBlLnJlbW92ZUFsbExpc3RlbmVycyA9IGZ1bmN0aW9uIChldikge1xuICB2YXIgcmVzID0gU3RyZWFtLnByb3RvdHlwZS5yZW1vdmVBbGxMaXN0ZW5lcnMuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgaWYgKGV2ID09PSAncmVhZGFibGUnIHx8IGV2ID09PSB1bmRlZmluZWQpIHtcbiAgICAvLyBXZSBuZWVkIHRvIGNoZWNrIGlmIHRoZXJlIGlzIHNvbWVvbmUgc3RpbGwgbGlzdGVuaW5nIHRvXG4gICAgLy8gcmVhZGFibGUgYW5kIHJlc2V0IHRoZSBzdGF0ZS4gSG93ZXZlciB0aGlzIG5lZWRzIHRvIGhhcHBlblxuICAgIC8vIGFmdGVyIHJlYWRhYmxlIGhhcyBiZWVuIGVtaXR0ZWQgYnV0IGJlZm9yZSBJL08gKG5leHRUaWNrKSB0b1xuICAgIC8vIHN1cHBvcnQgb25jZSgncmVhZGFibGUnLCBmbikgY3ljbGVzLiBUaGlzIG1lYW5zIHRoYXQgY2FsbGluZ1xuICAgIC8vIHJlc3VtZSB3aXRoaW4gdGhlIHNhbWUgdGljayB3aWxsIGhhdmUgbm9cbiAgICAvLyBlZmZlY3QuXG4gICAgcHJvY2Vzcy5uZXh0VGljayh1cGRhdGVSZWFkYWJsZUxpc3RlbmluZywgdGhpcyk7XG4gIH1cbiAgcmV0dXJuIHJlcztcbn07XG5mdW5jdGlvbiB1cGRhdGVSZWFkYWJsZUxpc3RlbmluZyhzZWxmKSB7XG4gIHZhciBzdGF0ZSA9IHNlbGYuX3JlYWRhYmxlU3RhdGU7XG4gIHN0YXRlLnJlYWRhYmxlTGlzdGVuaW5nID0gc2VsZi5saXN0ZW5lckNvdW50KCdyZWFkYWJsZScpID4gMDtcbiAgaWYgKHN0YXRlLnJlc3VtZVNjaGVkdWxlZCAmJiAhc3RhdGUucGF1c2VkKSB7XG4gICAgLy8gZmxvd2luZyBuZWVkcyB0byBiZSBzZXQgdG8gdHJ1ZSBub3csIG90aGVyd2lzZVxuICAgIC8vIHRoZSB1cGNvbWluZyByZXN1bWUgd2lsbCBub3QgZmxvdy5cbiAgICBzdGF0ZS5mbG93aW5nID0gdHJ1ZTtcblxuICAgIC8vIGNydWRlIHdheSB0byBjaGVjayBpZiB3ZSBzaG91bGQgcmVzdW1lXG4gIH0gZWxzZSBpZiAoc2VsZi5saXN0ZW5lckNvdW50KCdkYXRhJykgPiAwKSB7XG4gICAgc2VsZi5yZXN1bWUoKTtcbiAgfVxufVxuZnVuY3Rpb24gblJlYWRpbmdOZXh0VGljayhzZWxmKSB7XG4gIGRlYnVnKCdyZWFkYWJsZSBuZXh0dGljayByZWFkIDAnKTtcbiAgc2VsZi5yZWFkKDApO1xufVxuXG4vLyBwYXVzZSgpIGFuZCByZXN1bWUoKSBhcmUgcmVtbmFudHMgb2YgdGhlIGxlZ2FjeSByZWFkYWJsZSBzdHJlYW0gQVBJXG4vLyBJZiB0aGUgdXNlciB1c2VzIHRoZW0sIHRoZW4gc3dpdGNoIGludG8gb2xkIG1vZGUuXG5SZWFkYWJsZS5wcm90b3R5cGUucmVzdW1lID0gZnVuY3Rpb24gKCkge1xuICB2YXIgc3RhdGUgPSB0aGlzLl9yZWFkYWJsZVN0YXRlO1xuICBpZiAoIXN0YXRlLmZsb3dpbmcpIHtcbiAgICBkZWJ1ZygncmVzdW1lJyk7XG4gICAgLy8gd2UgZmxvdyBvbmx5IGlmIHRoZXJlIGlzIG5vIG9uZSBsaXN0ZW5pbmdcbiAgICAvLyBmb3IgcmVhZGFibGUsIGJ1dCB3ZSBzdGlsbCBoYXZlIHRvIGNhbGxcbiAgICAvLyByZXN1bWUoKVxuICAgIHN0YXRlLmZsb3dpbmcgPSAhc3RhdGUucmVhZGFibGVMaXN0ZW5pbmc7XG4gICAgcmVzdW1lKHRoaXMsIHN0YXRlKTtcbiAgfVxuICBzdGF0ZS5wYXVzZWQgPSBmYWxzZTtcbiAgcmV0dXJuIHRoaXM7XG59O1xuZnVuY3Rpb24gcmVzdW1lKHN0cmVhbSwgc3RhdGUpIHtcbiAgaWYgKCFzdGF0ZS5yZXN1bWVTY2hlZHVsZWQpIHtcbiAgICBzdGF0ZS5yZXN1bWVTY2hlZHVsZWQgPSB0cnVlO1xuICAgIHByb2Nlc3MubmV4dFRpY2socmVzdW1lXywgc3RyZWFtLCBzdGF0ZSk7XG4gIH1cbn1cbmZ1bmN0aW9uIHJlc3VtZV8oc3RyZWFtLCBzdGF0ZSkge1xuICBkZWJ1ZygncmVzdW1lJywgc3RhdGUucmVhZGluZyk7XG4gIGlmICghc3RhdGUucmVhZGluZykge1xuICAgIHN0cmVhbS5yZWFkKDApO1xuICB9XG4gIHN0YXRlLnJlc3VtZVNjaGVkdWxlZCA9IGZhbHNlO1xuICBzdHJlYW0uZW1pdCgncmVzdW1lJyk7XG4gIGZsb3coc3RyZWFtKTtcbiAgaWYgKHN0YXRlLmZsb3dpbmcgJiYgIXN0YXRlLnJlYWRpbmcpIHN0cmVhbS5yZWFkKDApO1xufVxuUmVhZGFibGUucHJvdG90eXBlLnBhdXNlID0gZnVuY3Rpb24gKCkge1xuICBkZWJ1ZygnY2FsbCBwYXVzZSBmbG93aW5nPSVqJywgdGhpcy5fcmVhZGFibGVTdGF0ZS5mbG93aW5nKTtcbiAgaWYgKHRoaXMuX3JlYWRhYmxlU3RhdGUuZmxvd2luZyAhPT0gZmFsc2UpIHtcbiAgICBkZWJ1ZygncGF1c2UnKTtcbiAgICB0aGlzLl9yZWFkYWJsZVN0YXRlLmZsb3dpbmcgPSBmYWxzZTtcbiAgICB0aGlzLmVtaXQoJ3BhdXNlJyk7XG4gIH1cbiAgdGhpcy5fcmVhZGFibGVTdGF0ZS5wYXVzZWQgPSB0cnVlO1xuICByZXR1cm4gdGhpcztcbn07XG5mdW5jdGlvbiBmbG93KHN0cmVhbSkge1xuICB2YXIgc3RhdGUgPSBzdHJlYW0uX3JlYWRhYmxlU3RhdGU7XG4gIGRlYnVnKCdmbG93Jywgc3RhdGUuZmxvd2luZyk7XG4gIHdoaWxlIChzdGF0ZS5mbG93aW5nICYmIHN0cmVhbS5yZWFkKCkgIT09IG51bGwpO1xufVxuXG4vLyB3cmFwIGFuIG9sZC1zdHlsZSBzdHJlYW0gYXMgdGhlIGFzeW5jIGRhdGEgc291cmNlLlxuLy8gVGhpcyBpcyAqbm90KiBwYXJ0IG9mIHRoZSByZWFkYWJsZSBzdHJlYW0gaW50ZXJmYWNlLlxuLy8gSXQgaXMgYW4gdWdseSB1bmZvcnR1bmF0ZSBtZXNzIG9mIGhpc3RvcnkuXG5SZWFkYWJsZS5wcm90b3R5cGUud3JhcCA9IGZ1bmN0aW9uIChzdHJlYW0pIHtcbiAgdmFyIF90aGlzID0gdGhpcztcbiAgdmFyIHN0YXRlID0gdGhpcy5fcmVhZGFibGVTdGF0ZTtcbiAgdmFyIHBhdXNlZCA9IGZhbHNlO1xuICBzdHJlYW0ub24oJ2VuZCcsIGZ1bmN0aW9uICgpIHtcbiAgICBkZWJ1Zygnd3JhcHBlZCBlbmQnKTtcbiAgICBpZiAoc3RhdGUuZGVjb2RlciAmJiAhc3RhdGUuZW5kZWQpIHtcbiAgICAgIHZhciBjaHVuayA9IHN0YXRlLmRlY29kZXIuZW5kKCk7XG4gICAgICBpZiAoY2h1bmsgJiYgY2h1bmsubGVuZ3RoKSBfdGhpcy5wdXNoKGNodW5rKTtcbiAgICB9XG4gICAgX3RoaXMucHVzaChudWxsKTtcbiAgfSk7XG4gIHN0cmVhbS5vbignZGF0YScsIGZ1bmN0aW9uIChjaHVuaykge1xuICAgIGRlYnVnKCd3cmFwcGVkIGRhdGEnKTtcbiAgICBpZiAoc3RhdGUuZGVjb2RlcikgY2h1bmsgPSBzdGF0ZS5kZWNvZGVyLndyaXRlKGNodW5rKTtcblxuICAgIC8vIGRvbid0IHNraXAgb3ZlciBmYWxzeSB2YWx1ZXMgaW4gb2JqZWN0TW9kZVxuICAgIGlmIChzdGF0ZS5vYmplY3RNb2RlICYmIChjaHVuayA9PT0gbnVsbCB8fCBjaHVuayA9PT0gdW5kZWZpbmVkKSkgcmV0dXJuO2Vsc2UgaWYgKCFzdGF0ZS5vYmplY3RNb2RlICYmICghY2h1bmsgfHwgIWNodW5rLmxlbmd0aCkpIHJldHVybjtcbiAgICB2YXIgcmV0ID0gX3RoaXMucHVzaChjaHVuayk7XG4gICAgaWYgKCFyZXQpIHtcbiAgICAgIHBhdXNlZCA9IHRydWU7XG4gICAgICBzdHJlYW0ucGF1c2UoKTtcbiAgICB9XG4gIH0pO1xuXG4gIC8vIHByb3h5IGFsbCB0aGUgb3RoZXIgbWV0aG9kcy5cbiAgLy8gaW1wb3J0YW50IHdoZW4gd3JhcHBpbmcgZmlsdGVycyBhbmQgZHVwbGV4ZXMuXG4gIGZvciAodmFyIGkgaW4gc3RyZWFtKSB7XG4gICAgaWYgKHRoaXNbaV0gPT09IHVuZGVmaW5lZCAmJiB0eXBlb2Ygc3RyZWFtW2ldID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICB0aGlzW2ldID0gZnVuY3Rpb24gbWV0aG9kV3JhcChtZXRob2QpIHtcbiAgICAgICAgcmV0dXJuIGZ1bmN0aW9uIG1ldGhvZFdyYXBSZXR1cm5GdW5jdGlvbigpIHtcbiAgICAgICAgICByZXR1cm4gc3RyZWFtW21ldGhvZF0uYXBwbHkoc3RyZWFtLCBhcmd1bWVudHMpO1xuICAgICAgICB9O1xuICAgICAgfShpKTtcbiAgICB9XG4gIH1cblxuICAvLyBwcm94eSBjZXJ0YWluIGltcG9ydGFudCBldmVudHMuXG4gIGZvciAodmFyIG4gPSAwOyBuIDwga1Byb3h5RXZlbnRzLmxlbmd0aDsgbisrKSB7XG4gICAgc3RyZWFtLm9uKGtQcm94eUV2ZW50c1tuXSwgdGhpcy5lbWl0LmJpbmQodGhpcywga1Byb3h5RXZlbnRzW25dKSk7XG4gIH1cblxuICAvLyB3aGVuIHdlIHRyeSB0byBjb25zdW1lIHNvbWUgbW9yZSBieXRlcywgc2ltcGx5IHVucGF1c2UgdGhlXG4gIC8vIHVuZGVybHlpbmcgc3RyZWFtLlxuICB0aGlzLl9yZWFkID0gZnVuY3Rpb24gKG4pIHtcbiAgICBkZWJ1Zygnd3JhcHBlZCBfcmVhZCcsIG4pO1xuICAgIGlmIChwYXVzZWQpIHtcbiAgICAgIHBhdXNlZCA9IGZhbHNlO1xuICAgICAgc3RyZWFtLnJlc3VtZSgpO1xuICAgIH1cbiAgfTtcbiAgcmV0dXJuIHRoaXM7XG59O1xuaWYgKHR5cGVvZiBTeW1ib2wgPT09ICdmdW5jdGlvbicpIHtcbiAgUmVhZGFibGUucHJvdG90eXBlW1N5bWJvbC5hc3luY0l0ZXJhdG9yXSA9IGZ1bmN0aW9uICgpIHtcbiAgICBpZiAoY3JlYXRlUmVhZGFibGVTdHJlYW1Bc3luY0l0ZXJhdG9yID09PSB1bmRlZmluZWQpIHtcbiAgICAgIGNyZWF0ZVJlYWRhYmxlU3RyZWFtQXN5bmNJdGVyYXRvciA9IHJlcXVpcmUoJy4vaW50ZXJuYWwvc3RyZWFtcy9hc3luY19pdGVyYXRvcicpO1xuICAgIH1cbiAgICByZXR1cm4gY3JlYXRlUmVhZGFibGVTdHJlYW1Bc3luY0l0ZXJhdG9yKHRoaXMpO1xuICB9O1xufVxuT2JqZWN0LmRlZmluZVByb3BlcnR5KFJlYWRhYmxlLnByb3RvdHlwZSwgJ3JlYWRhYmxlSGlnaFdhdGVyTWFyaycsIHtcbiAgLy8gbWFraW5nIGl0IGV4cGxpY2l0IHRoaXMgcHJvcGVydHkgaXMgbm90IGVudW1lcmFibGVcbiAgLy8gYmVjYXVzZSBvdGhlcndpc2Ugc29tZSBwcm90b3R5cGUgbWFuaXB1bGF0aW9uIGluXG4gIC8vIHVzZXJsYW5kIHdpbGwgZmFpbFxuICBlbnVtZXJhYmxlOiBmYWxzZSxcbiAgZ2V0OiBmdW5jdGlvbiBnZXQoKSB7XG4gICAgcmV0dXJuIHRoaXMuX3JlYWRhYmxlU3RhdGUuaGlnaFdhdGVyTWFyaztcbiAgfVxufSk7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoUmVhZGFibGUucHJvdG90eXBlLCAncmVhZGFibGVCdWZmZXInLCB7XG4gIC8vIG1ha2luZyBpdCBleHBsaWNpdCB0aGlzIHByb3BlcnR5IGlzIG5vdCBlbnVtZXJhYmxlXG4gIC8vIGJlY2F1c2Ugb3RoZXJ3aXNlIHNvbWUgcHJvdG90eXBlIG1hbmlwdWxhdGlvbiBpblxuICAvLyB1c2VybGFuZCB3aWxsIGZhaWxcbiAgZW51bWVyYWJsZTogZmFsc2UsXG4gIGdldDogZnVuY3Rpb24gZ2V0KCkge1xuICAgIHJldHVybiB0aGlzLl9yZWFkYWJsZVN0YXRlICYmIHRoaXMuX3JlYWRhYmxlU3RhdGUuYnVmZmVyO1xuICB9XG59KTtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShSZWFkYWJsZS5wcm90b3R5cGUsICdyZWFkYWJsZUZsb3dpbmcnLCB7XG4gIC8vIG1ha2luZyBpdCBleHBsaWNpdCB0aGlzIHByb3BlcnR5IGlzIG5vdCBlbnVtZXJhYmxlXG4gIC8vIGJlY2F1c2Ugb3RoZXJ3aXNlIHNvbWUgcHJvdG90eXBlIG1hbmlwdWxhdGlvbiBpblxuICAvLyB1c2VybGFuZCB3aWxsIGZhaWxcbiAgZW51bWVyYWJsZTogZmFsc2UsXG4gIGdldDogZnVuY3Rpb24gZ2V0KCkge1xuICAgIHJldHVybiB0aGlzLl9yZWFkYWJsZVN0YXRlLmZsb3dpbmc7XG4gIH0sXG4gIHNldDogZnVuY3Rpb24gc2V0KHN0YXRlKSB7XG4gICAgaWYgKHRoaXMuX3JlYWRhYmxlU3RhdGUpIHtcbiAgICAgIHRoaXMuX3JlYWRhYmxlU3RhdGUuZmxvd2luZyA9IHN0YXRlO1xuICAgIH1cbiAgfVxufSk7XG5cbi8vIGV4cG9zZWQgZm9yIHRlc3RpbmcgcHVycG9zZXMgb25seS5cblJlYWRhYmxlLl9mcm9tTGlzdCA9IGZyb21MaXN0O1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KFJlYWRhYmxlLnByb3RvdHlwZSwgJ3JlYWRhYmxlTGVuZ3RoJywge1xuICAvLyBtYWtpbmcgaXQgZXhwbGljaXQgdGhpcyBwcm9wZXJ0eSBpcyBub3QgZW51bWVyYWJsZVxuICAvLyBiZWNhdXNlIG90aGVyd2lzZSBzb21lIHByb3RvdHlwZSBtYW5pcHVsYXRpb24gaW5cbiAgLy8gdXNlcmxhbmQgd2lsbCBmYWlsXG4gIGVudW1lcmFibGU6IGZhbHNlLFxuICBnZXQ6IGZ1bmN0aW9uIGdldCgpIHtcbiAgICByZXR1cm4gdGhpcy5fcmVhZGFibGVTdGF0ZS5sZW5ndGg7XG4gIH1cbn0pO1xuXG4vLyBQbHVjayBvZmYgbiBieXRlcyBmcm9tIGFuIGFycmF5IG9mIGJ1ZmZlcnMuXG4vLyBMZW5ndGggaXMgdGhlIGNvbWJpbmVkIGxlbmd0aHMgb2YgYWxsIHRoZSBidWZmZXJzIGluIHRoZSBsaXN0LlxuLy8gVGhpcyBmdW5jdGlvbiBpcyBkZXNpZ25lZCB0byBiZSBpbmxpbmFibGUsIHNvIHBsZWFzZSB0YWtlIGNhcmUgd2hlbiBtYWtpbmdcbi8vIGNoYW5nZXMgdG8gdGhlIGZ1bmN0aW9uIGJvZHkuXG5mdW5jdGlvbiBmcm9tTGlzdChuLCBzdGF0ZSkge1xuICAvLyBub3RoaW5nIGJ1ZmZlcmVkXG4gIGlmIChzdGF0ZS5sZW5ndGggPT09IDApIHJldHVybiBudWxsO1xuICB2YXIgcmV0O1xuICBpZiAoc3RhdGUub2JqZWN0TW9kZSkgcmV0ID0gc3RhdGUuYnVmZmVyLnNoaWZ0KCk7ZWxzZSBpZiAoIW4gfHwgbiA+PSBzdGF0ZS5sZW5ndGgpIHtcbiAgICAvLyByZWFkIGl0IGFsbCwgdHJ1bmNhdGUgdGhlIGxpc3RcbiAgICBpZiAoc3RhdGUuZGVjb2RlcikgcmV0ID0gc3RhdGUuYnVmZmVyLmpvaW4oJycpO2Vsc2UgaWYgKHN0YXRlLmJ1ZmZlci5sZW5ndGggPT09IDEpIHJldCA9IHN0YXRlLmJ1ZmZlci5maXJzdCgpO2Vsc2UgcmV0ID0gc3RhdGUuYnVmZmVyLmNvbmNhdChzdGF0ZS5sZW5ndGgpO1xuICAgIHN0YXRlLmJ1ZmZlci5jbGVhcigpO1xuICB9IGVsc2Uge1xuICAgIC8vIHJlYWQgcGFydCBvZiBsaXN0XG4gICAgcmV0ID0gc3RhdGUuYnVmZmVyLmNvbnN1bWUobiwgc3RhdGUuZGVjb2Rlcik7XG4gIH1cbiAgcmV0dXJuIHJldDtcbn1cbmZ1bmN0aW9uIGVuZFJlYWRhYmxlKHN0cmVhbSkge1xuICB2YXIgc3RhdGUgPSBzdHJlYW0uX3JlYWRhYmxlU3RhdGU7XG4gIGRlYnVnKCdlbmRSZWFkYWJsZScsIHN0YXRlLmVuZEVtaXR0ZWQpO1xuICBpZiAoIXN0YXRlLmVuZEVtaXR0ZWQpIHtcbiAgICBzdGF0ZS5lbmRlZCA9IHRydWU7XG4gICAgcHJvY2Vzcy5uZXh0VGljayhlbmRSZWFkYWJsZU5ULCBzdGF0ZSwgc3RyZWFtKTtcbiAgfVxufVxuZnVuY3Rpb24gZW5kUmVhZGFibGVOVChzdGF0ZSwgc3RyZWFtKSB7XG4gIGRlYnVnKCdlbmRSZWFkYWJsZU5UJywgc3RhdGUuZW5kRW1pdHRlZCwgc3RhdGUubGVuZ3RoKTtcblxuICAvLyBDaGVjayB0aGF0IHdlIGRpZG4ndCBnZXQgb25lIGxhc3QgdW5zaGlmdC5cbiAgaWYgKCFzdGF0ZS5lbmRFbWl0dGVkICYmIHN0YXRlLmxlbmd0aCA9PT0gMCkge1xuICAgIHN0YXRlLmVuZEVtaXR0ZWQgPSB0cnVlO1xuICAgIHN0cmVhbS5yZWFkYWJsZSA9IGZhbHNlO1xuICAgIHN0cmVhbS5lbWl0KCdlbmQnKTtcbiAgICBpZiAoc3RhdGUuYXV0b0Rlc3Ryb3kpIHtcbiAgICAgIC8vIEluIGNhc2Ugb2YgZHVwbGV4IHN0cmVhbXMgd2UgbmVlZCBhIHdheSB0byBkZXRlY3RcbiAgICAgIC8vIGlmIHRoZSB3cml0YWJsZSBzaWRlIGlzIHJlYWR5IGZvciBhdXRvRGVzdHJveSBhcyB3ZWxsXG4gICAgICB2YXIgd1N0YXRlID0gc3RyZWFtLl93cml0YWJsZVN0YXRlO1xuICAgICAgaWYgKCF3U3RhdGUgfHwgd1N0YXRlLmF1dG9EZXN0cm95ICYmIHdTdGF0ZS5maW5pc2hlZCkge1xuICAgICAgICBzdHJlYW0uZGVzdHJveSgpO1xuICAgICAgfVxuICAgIH1cbiAgfVxufVxuaWYgKHR5cGVvZiBTeW1ib2wgPT09ICdmdW5jdGlvbicpIHtcbiAgUmVhZGFibGUuZnJvbSA9IGZ1bmN0aW9uIChpdGVyYWJsZSwgb3B0cykge1xuICAgIGlmIChmcm9tID09PSB1bmRlZmluZWQpIHtcbiAgICAgIGZyb20gPSByZXF1aXJlKCcuL2ludGVybmFsL3N0cmVhbXMvZnJvbScpO1xuICAgIH1cbiAgICByZXR1cm4gZnJvbShSZWFkYWJsZSwgaXRlcmFibGUsIG9wdHMpO1xuICB9O1xufVxuZnVuY3Rpb24gaW5kZXhPZih4cywgeCkge1xuICBmb3IgKHZhciBpID0gMCwgbCA9IHhzLmxlbmd0aDsgaSA8IGw7IGkrKykge1xuICAgIGlmICh4c1tpXSA9PT0geCkgcmV0dXJuIGk7XG4gIH1cbiAgcmV0dXJuIC0xO1xufSIsIi8vIENvcHlyaWdodCBKb3llbnQsIEluYy4gYW5kIG90aGVyIE5vZGUgY29udHJpYnV0b3JzLlxuLy9cbi8vIFBlcm1pc3Npb24gaXMgaGVyZWJ5IGdyYW50ZWQsIGZyZWUgb2YgY2hhcmdlLCB0byBhbnkgcGVyc29uIG9idGFpbmluZyBhXG4vLyBjb3B5IG9mIHRoaXMgc29mdHdhcmUgYW5kIGFzc29jaWF0ZWQgZG9jdW1lbnRhdGlvbiBmaWxlcyAodGhlXG4vLyBcIlNvZnR3YXJlXCIpLCB0byBkZWFsIGluIHRoZSBTb2Z0d2FyZSB3aXRob3V0IHJlc3RyaWN0aW9uLCBpbmNsdWRpbmdcbi8vIHdpdGhvdXQgbGltaXRhdGlvbiB0aGUgcmlnaHRzIHRvIHVzZSwgY29weSwgbW9kaWZ5LCBtZXJnZSwgcHVibGlzaCxcbi8vIGRpc3RyaWJ1dGUsIHN1YmxpY2Vuc2UsIGFuZC9vciBzZWxsIGNvcGllcyBvZiB0aGUgU29mdHdhcmUsIGFuZCB0byBwZXJtaXRcbi8vIHBlcnNvbnMgdG8gd2hvbSB0aGUgU29mdHdhcmUgaXMgZnVybmlzaGVkIHRvIGRvIHNvLCBzdWJqZWN0IHRvIHRoZVxuLy8gZm9sbG93aW5nIGNvbmRpdGlvbnM6XG4vL1xuLy8gVGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UgYW5kIHRoaXMgcGVybWlzc2lvbiBub3RpY2Ugc2hhbGwgYmUgaW5jbHVkZWRcbi8vIGluIGFsbCBjb3BpZXMgb3Igc3Vic3RhbnRpYWwgcG9ydGlvbnMgb2YgdGhlIFNvZnR3YXJlLlxuLy9cbi8vIFRIRSBTT0ZUV0FSRSBJUyBQUk9WSURFRCBcIkFTIElTXCIsIFdJVEhPVVQgV0FSUkFOVFkgT0YgQU5ZIEtJTkQsIEVYUFJFU1Ncbi8vIE9SIElNUExJRUQsIElOQ0xVRElORyBCVVQgTk9UIExJTUlURUQgVE8gVEhFIFdBUlJBTlRJRVMgT0Zcbi8vIE1FUkNIQU5UQUJJTElUWSwgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQU5EIE5PTklORlJJTkdFTUVOVC4gSU5cbi8vIE5PIEVWRU5UIFNIQUxMIFRIRSBBVVRIT1JTIE9SIENPUFlSSUdIVCBIT0xERVJTIEJFIExJQUJMRSBGT1IgQU5ZIENMQUlNLFxuLy8gREFNQUdFUyBPUiBPVEhFUiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQU4gQUNUSU9OIE9GIENPTlRSQUNULCBUT1JUIE9SXG4vLyBPVEhFUldJU0UsIEFSSVNJTkcgRlJPTSwgT1VUIE9GIE9SIElOIENPTk5FQ1RJT04gV0lUSCBUSEUgU09GVFdBUkUgT1IgVEhFXG4vLyBVU0UgT1IgT1RIRVIgREVBTElOR1MgSU4gVEhFIFNPRlRXQVJFLlxuXG4vLyBhIHRyYW5zZm9ybSBzdHJlYW0gaXMgYSByZWFkYWJsZS93cml0YWJsZSBzdHJlYW0gd2hlcmUgeW91IGRvXG4vLyBzb21ldGhpbmcgd2l0aCB0aGUgZGF0YS4gIFNvbWV0aW1lcyBpdCdzIGNhbGxlZCBhIFwiZmlsdGVyXCIsXG4vLyBidXQgdGhhdCdzIG5vdCBhIGdyZWF0IG5hbWUgZm9yIGl0LCBzaW5jZSB0aGF0IGltcGxpZXMgYSB0aGluZyB3aGVyZVxuLy8gc29tZSBiaXRzIHBhc3MgdGhyb3VnaCwgYW5kIG90aGVycyBhcmUgc2ltcGx5IGlnbm9yZWQuICAoVGhhdCB3b3VsZFxuLy8gYmUgYSB2YWxpZCBleGFtcGxlIG9mIGEgdHJhbnNmb3JtLCBvZiBjb3Vyc2UuKVxuLy9cbi8vIFdoaWxlIHRoZSBvdXRwdXQgaXMgY2F1c2FsbHkgcmVsYXRlZCB0byB0aGUgaW5wdXQsIGl0J3Mgbm90IGFcbi8vIG5lY2Vzc2FyaWx5IHN5bW1ldHJpYyBvciBzeW5jaHJvbm91cyB0cmFuc2Zvcm1hdGlvbi4gIEZvciBleGFtcGxlLFxuLy8gYSB6bGliIHN0cmVhbSBtaWdodCB0YWtlIG11bHRpcGxlIHBsYWluLXRleHQgd3JpdGVzKCksIGFuZCB0aGVuXG4vLyBlbWl0IGEgc2luZ2xlIGNvbXByZXNzZWQgY2h1bmsgc29tZSB0aW1lIGluIHRoZSBmdXR1cmUuXG4vL1xuLy8gSGVyZSdzIGhvdyB0aGlzIHdvcmtzOlxuLy9cbi8vIFRoZSBUcmFuc2Zvcm0gc3RyZWFtIGhhcyBhbGwgdGhlIGFzcGVjdHMgb2YgdGhlIHJlYWRhYmxlIGFuZCB3cml0YWJsZVxuLy8gc3RyZWFtIGNsYXNzZXMuICBXaGVuIHlvdSB3cml0ZShjaHVuayksIHRoYXQgY2FsbHMgX3dyaXRlKGNodW5rLGNiKVxuLy8gaW50ZXJuYWxseSwgYW5kIHJldHVybnMgZmFsc2UgaWYgdGhlcmUncyBhIGxvdCBvZiBwZW5kaW5nIHdyaXRlc1xuLy8gYnVmZmVyZWQgdXAuICBXaGVuIHlvdSBjYWxsIHJlYWQoKSwgdGhhdCBjYWxscyBfcmVhZChuKSB1bnRpbFxuLy8gdGhlcmUncyBlbm91Z2ggcGVuZGluZyByZWFkYWJsZSBkYXRhIGJ1ZmZlcmVkIHVwLlxuLy9cbi8vIEluIGEgdHJhbnNmb3JtIHN0cmVhbSwgdGhlIHdyaXR0ZW4gZGF0YSBpcyBwbGFjZWQgaW4gYSBidWZmZXIuICBXaGVuXG4vLyBfcmVhZChuKSBpcyBjYWxsZWQsIGl0IHRyYW5zZm9ybXMgdGhlIHF1ZXVlZCB1cCBkYXRhLCBjYWxsaW5nIHRoZVxuLy8gYnVmZmVyZWQgX3dyaXRlIGNiJ3MgYXMgaXQgY29uc3VtZXMgY2h1bmtzLiAgSWYgY29uc3VtaW5nIGEgc2luZ2xlXG4vLyB3cml0dGVuIGNodW5rIHdvdWxkIHJlc3VsdCBpbiBtdWx0aXBsZSBvdXRwdXQgY2h1bmtzLCB0aGVuIHRoZSBmaXJzdFxuLy8gb3V0cHV0dGVkIGJpdCBjYWxscyB0aGUgcmVhZGNiLCBhbmQgc3Vic2VxdWVudCBjaHVua3MganVzdCBnbyBpbnRvXG4vLyB0aGUgcmVhZCBidWZmZXIsIGFuZCB3aWxsIGNhdXNlIGl0IHRvIGVtaXQgJ3JlYWRhYmxlJyBpZiBuZWNlc3NhcnkuXG4vL1xuLy8gVGhpcyB3YXksIGJhY2stcHJlc3N1cmUgaXMgYWN0dWFsbHkgZGV0ZXJtaW5lZCBieSB0aGUgcmVhZGluZyBzaWRlLFxuLy8gc2luY2UgX3JlYWQgaGFzIHRvIGJlIGNhbGxlZCB0byBzdGFydCBwcm9jZXNzaW5nIGEgbmV3IGNodW5rLiAgSG93ZXZlcixcbi8vIGEgcGF0aG9sb2dpY2FsIGluZmxhdGUgdHlwZSBvZiB0cmFuc2Zvcm0gY2FuIGNhdXNlIGV4Y2Vzc2l2ZSBidWZmZXJpbmdcbi8vIGhlcmUuICBGb3IgZXhhbXBsZSwgaW1hZ2luZSBhIHN0cmVhbSB3aGVyZSBldmVyeSBieXRlIG9mIGlucHV0IGlzXG4vLyBpbnRlcnByZXRlZCBhcyBhbiBpbnRlZ2VyIGZyb20gMC0yNTUsIGFuZCB0aGVuIHJlc3VsdHMgaW4gdGhhdCBtYW55XG4vLyBieXRlcyBvZiBvdXRwdXQuICBXcml0aW5nIHRoZSA0IGJ5dGVzIHtmZixmZixmZixmZn0gd291bGQgcmVzdWx0IGluXG4vLyAxa2Igb2YgZGF0YSBiZWluZyBvdXRwdXQuICBJbiB0aGlzIGNhc2UsIHlvdSBjb3VsZCB3cml0ZSBhIHZlcnkgc21hbGxcbi8vIGFtb3VudCBvZiBpbnB1dCwgYW5kIGVuZCB1cCB3aXRoIGEgdmVyeSBsYXJnZSBhbW91bnQgb2Ygb3V0cHV0LiAgSW5cbi8vIHN1Y2ggYSBwYXRob2xvZ2ljYWwgaW5mbGF0aW5nIG1lY2hhbmlzbSwgdGhlcmUnZCBiZSBubyB3YXkgdG8gdGVsbFxuLy8gdGhlIHN5c3RlbSB0byBzdG9wIGRvaW5nIHRoZSB0cmFuc2Zvcm0uICBBIHNpbmdsZSA0TUIgd3JpdGUgY291bGRcbi8vIGNhdXNlIHRoZSBzeXN0ZW0gdG8gcnVuIG91dCBvZiBtZW1vcnkuXG4vL1xuLy8gSG93ZXZlciwgZXZlbiBpbiBzdWNoIGEgcGF0aG9sb2dpY2FsIGNhc2UsIG9ubHkgYSBzaW5nbGUgd3JpdHRlbiBjaHVua1xuLy8gd291bGQgYmUgY29uc3VtZWQsIGFuZCB0aGVuIHRoZSByZXN0IHdvdWxkIHdhaXQgKHVuLXRyYW5zZm9ybWVkKSB1bnRpbFxuLy8gdGhlIHJlc3VsdHMgb2YgdGhlIHByZXZpb3VzIHRyYW5zZm9ybWVkIGNodW5rIHdlcmUgY29uc3VtZWQuXG5cbid1c2Ugc3RyaWN0JztcblxubW9kdWxlLmV4cG9ydHMgPSBUcmFuc2Zvcm07XG52YXIgX3JlcXVpcmUkY29kZXMgPSByZXF1aXJlKCcuLi9lcnJvcnMnKS5jb2RlcyxcbiAgRVJSX01FVEhPRF9OT1RfSU1QTEVNRU5URUQgPSBfcmVxdWlyZSRjb2Rlcy5FUlJfTUVUSE9EX05PVF9JTVBMRU1FTlRFRCxcbiAgRVJSX01VTFRJUExFX0NBTExCQUNLID0gX3JlcXVpcmUkY29kZXMuRVJSX01VTFRJUExFX0NBTExCQUNLLFxuICBFUlJfVFJBTlNGT1JNX0FMUkVBRFlfVFJBTlNGT1JNSU5HID0gX3JlcXVpcmUkY29kZXMuRVJSX1RSQU5TRk9STV9BTFJFQURZX1RSQU5TRk9STUlORyxcbiAgRVJSX1RSQU5TRk9STV9XSVRIX0xFTkdUSF8wID0gX3JlcXVpcmUkY29kZXMuRVJSX1RSQU5TRk9STV9XSVRIX0xFTkdUSF8wO1xudmFyIER1cGxleCA9IHJlcXVpcmUoJy4vX3N0cmVhbV9kdXBsZXgnKTtcbnJlcXVpcmUoJ2luaGVyaXRzJykoVHJhbnNmb3JtLCBEdXBsZXgpO1xuZnVuY3Rpb24gYWZ0ZXJUcmFuc2Zvcm0oZXIsIGRhdGEpIHtcbiAgdmFyIHRzID0gdGhpcy5fdHJhbnNmb3JtU3RhdGU7XG4gIHRzLnRyYW5zZm9ybWluZyA9IGZhbHNlO1xuICB2YXIgY2IgPSB0cy53cml0ZWNiO1xuICBpZiAoY2IgPT09IG51bGwpIHtcbiAgICByZXR1cm4gdGhpcy5lbWl0KCdlcnJvcicsIG5ldyBFUlJfTVVMVElQTEVfQ0FMTEJBQ0soKSk7XG4gIH1cbiAgdHMud3JpdGVjaHVuayA9IG51bGw7XG4gIHRzLndyaXRlY2IgPSBudWxsO1xuICBpZiAoZGF0YSAhPSBudWxsKVxuICAgIC8vIHNpbmdsZSBlcXVhbHMgY2hlY2sgZm9yIGJvdGggYG51bGxgIGFuZCBgdW5kZWZpbmVkYFxuICAgIHRoaXMucHVzaChkYXRhKTtcbiAgY2IoZXIpO1xuICB2YXIgcnMgPSB0aGlzLl9yZWFkYWJsZVN0YXRlO1xuICBycy5yZWFkaW5nID0gZmFsc2U7XG4gIGlmIChycy5uZWVkUmVhZGFibGUgfHwgcnMubGVuZ3RoIDwgcnMuaGlnaFdhdGVyTWFyaykge1xuICAgIHRoaXMuX3JlYWQocnMuaGlnaFdhdGVyTWFyayk7XG4gIH1cbn1cbmZ1bmN0aW9uIFRyYW5zZm9ybShvcHRpb25zKSB7XG4gIGlmICghKHRoaXMgaW5zdGFuY2VvZiBUcmFuc2Zvcm0pKSByZXR1cm4gbmV3IFRyYW5zZm9ybShvcHRpb25zKTtcbiAgRHVwbGV4LmNhbGwodGhpcywgb3B0aW9ucyk7XG4gIHRoaXMuX3RyYW5zZm9ybVN0YXRlID0ge1xuICAgIGFmdGVyVHJhbnNmb3JtOiBhZnRlclRyYW5zZm9ybS5iaW5kKHRoaXMpLFxuICAgIG5lZWRUcmFuc2Zvcm06IGZhbHNlLFxuICAgIHRyYW5zZm9ybWluZzogZmFsc2UsXG4gICAgd3JpdGVjYjogbnVsbCxcbiAgICB3cml0ZWNodW5rOiBudWxsLFxuICAgIHdyaXRlZW5jb2Rpbmc6IG51bGxcbiAgfTtcblxuICAvLyBzdGFydCBvdXQgYXNraW5nIGZvciBhIHJlYWRhYmxlIGV2ZW50IG9uY2UgZGF0YSBpcyB0cmFuc2Zvcm1lZC5cbiAgdGhpcy5fcmVhZGFibGVTdGF0ZS5uZWVkUmVhZGFibGUgPSB0cnVlO1xuXG4gIC8vIHdlIGhhdmUgaW1wbGVtZW50ZWQgdGhlIF9yZWFkIG1ldGhvZCwgYW5kIGRvbmUgdGhlIG90aGVyIHRoaW5nc1xuICAvLyB0aGF0IFJlYWRhYmxlIHdhbnRzIGJlZm9yZSB0aGUgZmlyc3QgX3JlYWQgY2FsbCwgc28gdW5zZXQgdGhlXG4gIC8vIHN5bmMgZ3VhcmQgZmxhZy5cbiAgdGhpcy5fcmVhZGFibGVTdGF0ZS5zeW5jID0gZmFsc2U7XG4gIGlmIChvcHRpb25zKSB7XG4gICAgaWYgKHR5cGVvZiBvcHRpb25zLnRyYW5zZm9ybSA9PT0gJ2Z1bmN0aW9uJykgdGhpcy5fdHJhbnNmb3JtID0gb3B0aW9ucy50cmFuc2Zvcm07XG4gICAgaWYgKHR5cGVvZiBvcHRpb25zLmZsdXNoID09PSAnZnVuY3Rpb24nKSB0aGlzLl9mbHVzaCA9IG9wdGlvbnMuZmx1c2g7XG4gIH1cblxuICAvLyBXaGVuIHRoZSB3cml0YWJsZSBzaWRlIGZpbmlzaGVzLCB0aGVuIGZsdXNoIG91dCBhbnl0aGluZyByZW1haW5pbmcuXG4gIHRoaXMub24oJ3ByZWZpbmlzaCcsIHByZWZpbmlzaCk7XG59XG5mdW5jdGlvbiBwcmVmaW5pc2goKSB7XG4gIHZhciBfdGhpcyA9IHRoaXM7XG4gIGlmICh0eXBlb2YgdGhpcy5fZmx1c2ggPT09ICdmdW5jdGlvbicgJiYgIXRoaXMuX3JlYWRhYmxlU3RhdGUuZGVzdHJveWVkKSB7XG4gICAgdGhpcy5fZmx1c2goZnVuY3Rpb24gKGVyLCBkYXRhKSB7XG4gICAgICBkb25lKF90aGlzLCBlciwgZGF0YSk7XG4gICAgfSk7XG4gIH0gZWxzZSB7XG4gICAgZG9uZSh0aGlzLCBudWxsLCBudWxsKTtcbiAgfVxufVxuVHJhbnNmb3JtLnByb3RvdHlwZS5wdXNoID0gZnVuY3Rpb24gKGNodW5rLCBlbmNvZGluZykge1xuICB0aGlzLl90cmFuc2Zvcm1TdGF0ZS5uZWVkVHJhbnNmb3JtID0gZmFsc2U7XG4gIHJldHVybiBEdXBsZXgucHJvdG90eXBlLnB1c2guY2FsbCh0aGlzLCBjaHVuaywgZW5jb2RpbmcpO1xufTtcblxuLy8gVGhpcyBpcyB0aGUgcGFydCB3aGVyZSB5b3UgZG8gc3R1ZmYhXG4vLyBvdmVycmlkZSB0aGlzIGZ1bmN0aW9uIGluIGltcGxlbWVudGF0aW9uIGNsYXNzZXMuXG4vLyAnY2h1bmsnIGlzIGFuIGlucHV0IGNodW5rLlxuLy9cbi8vIENhbGwgYHB1c2gobmV3Q2h1bmspYCB0byBwYXNzIGFsb25nIHRyYW5zZm9ybWVkIG91dHB1dFxuLy8gdG8gdGhlIHJlYWRhYmxlIHNpZGUuICBZb3UgbWF5IGNhbGwgJ3B1c2gnIHplcm8gb3IgbW9yZSB0aW1lcy5cbi8vXG4vLyBDYWxsIGBjYihlcnIpYCB3aGVuIHlvdSBhcmUgZG9uZSB3aXRoIHRoaXMgY2h1bmsuICBJZiB5b3UgcGFzc1xuLy8gYW4gZXJyb3IsIHRoZW4gdGhhdCdsbCBwdXQgdGhlIGh1cnQgb24gdGhlIHdob2xlIG9wZXJhdGlvbi4gIElmIHlvdVxuLy8gbmV2ZXIgY2FsbCBjYigpLCB0aGVuIHlvdSdsbCBuZXZlciBnZXQgYW5vdGhlciBjaHVuay5cblRyYW5zZm9ybS5wcm90b3R5cGUuX3RyYW5zZm9ybSA9IGZ1bmN0aW9uIChjaHVuaywgZW5jb2RpbmcsIGNiKSB7XG4gIGNiKG5ldyBFUlJfTUVUSE9EX05PVF9JTVBMRU1FTlRFRCgnX3RyYW5zZm9ybSgpJykpO1xufTtcblRyYW5zZm9ybS5wcm90b3R5cGUuX3dyaXRlID0gZnVuY3Rpb24gKGNodW5rLCBlbmNvZGluZywgY2IpIHtcbiAgdmFyIHRzID0gdGhpcy5fdHJhbnNmb3JtU3RhdGU7XG4gIHRzLndyaXRlY2IgPSBjYjtcbiAgdHMud3JpdGVjaHVuayA9IGNodW5rO1xuICB0cy53cml0ZWVuY29kaW5nID0gZW5jb2Rpbmc7XG4gIGlmICghdHMudHJhbnNmb3JtaW5nKSB7XG4gICAgdmFyIHJzID0gdGhpcy5fcmVhZGFibGVTdGF0ZTtcbiAgICBpZiAodHMubmVlZFRyYW5zZm9ybSB8fCBycy5uZWVkUmVhZGFibGUgfHwgcnMubGVuZ3RoIDwgcnMuaGlnaFdhdGVyTWFyaykgdGhpcy5fcmVhZChycy5oaWdoV2F0ZXJNYXJrKTtcbiAgfVxufTtcblxuLy8gRG9lc24ndCBtYXR0ZXIgd2hhdCB0aGUgYXJncyBhcmUgaGVyZS5cbi8vIF90cmFuc2Zvcm0gZG9lcyBhbGwgdGhlIHdvcmsuXG4vLyBUaGF0IHdlIGdvdCBoZXJlIG1lYW5zIHRoYXQgdGhlIHJlYWRhYmxlIHNpZGUgd2FudHMgbW9yZSBkYXRhLlxuVHJhbnNmb3JtLnByb3RvdHlwZS5fcmVhZCA9IGZ1bmN0aW9uIChuKSB7XG4gIHZhciB0cyA9IHRoaXMuX3RyYW5zZm9ybVN0YXRlO1xuICBpZiAodHMud3JpdGVjaHVuayAhPT0gbnVsbCAmJiAhdHMudHJhbnNmb3JtaW5nKSB7XG4gICAgdHMudHJhbnNmb3JtaW5nID0gdHJ1ZTtcbiAgICB0aGlzLl90cmFuc2Zvcm0odHMud3JpdGVjaHVuaywgdHMud3JpdGVlbmNvZGluZywgdHMuYWZ0ZXJUcmFuc2Zvcm0pO1xuICB9IGVsc2Uge1xuICAgIC8vIG1hcmsgdGhhdCB3ZSBuZWVkIGEgdHJhbnNmb3JtLCBzbyB0aGF0IGFueSBkYXRhIHRoYXQgY29tZXMgaW5cbiAgICAvLyB3aWxsIGdldCBwcm9jZXNzZWQsIG5vdyB0aGF0IHdlJ3ZlIGFza2VkIGZvciBpdC5cbiAgICB0cy5uZWVkVHJhbnNmb3JtID0gdHJ1ZTtcbiAgfVxufTtcblRyYW5zZm9ybS5wcm90b3R5cGUuX2Rlc3Ryb3kgPSBmdW5jdGlvbiAoZXJyLCBjYikge1xuICBEdXBsZXgucHJvdG90eXBlLl9kZXN0cm95LmNhbGwodGhpcywgZXJyLCBmdW5jdGlvbiAoZXJyMikge1xuICAgIGNiKGVycjIpO1xuICB9KTtcbn07XG5mdW5jdGlvbiBkb25lKHN0cmVhbSwgZXIsIGRhdGEpIHtcbiAgaWYgKGVyKSByZXR1cm4gc3RyZWFtLmVtaXQoJ2Vycm9yJywgZXIpO1xuICBpZiAoZGF0YSAhPSBudWxsKVxuICAgIC8vIHNpbmdsZSBlcXVhbHMgY2hlY2sgZm9yIGJvdGggYG51bGxgIGFuZCBgdW5kZWZpbmVkYFxuICAgIHN0cmVhbS5wdXNoKGRhdGEpO1xuXG4gIC8vIFRPRE8oQnJpZGdlQVIpOiBXcml0ZSBhIHRlc3QgZm9yIHRoZXNlIHR3byBlcnJvciBjYXNlc1xuICAvLyBpZiB0aGVyZSdzIG5vdGhpbmcgaW4gdGhlIHdyaXRlIGJ1ZmZlciwgdGhlbiB0aGF0IG1lYW5zXG4gIC8vIHRoYXQgbm90aGluZyBtb3JlIHdpbGwgZXZlciBiZSBwcm92aWRlZFxuICBpZiAoc3RyZWFtLl93cml0YWJsZVN0YXRlLmxlbmd0aCkgdGhyb3cgbmV3IEVSUl9UUkFOU0ZPUk1fV0lUSF9MRU5HVEhfMCgpO1xuICBpZiAoc3RyZWFtLl90cmFuc2Zvcm1TdGF0ZS50cmFuc2Zvcm1pbmcpIHRocm93IG5ldyBFUlJfVFJBTlNGT1JNX0FMUkVBRFlfVFJBTlNGT1JNSU5HKCk7XG4gIHJldHVybiBzdHJlYW0ucHVzaChudWxsKTtcbn0iLCIvLyBDb3B5cmlnaHQgSm95ZW50LCBJbmMuIGFuZCBvdGhlciBOb2RlIGNvbnRyaWJ1dG9ycy5cbi8vXG4vLyBQZXJtaXNzaW9uIGlzIGhlcmVieSBncmFudGVkLCBmcmVlIG9mIGNoYXJnZSwgdG8gYW55IHBlcnNvbiBvYnRhaW5pbmcgYVxuLy8gY29weSBvZiB0aGlzIHNvZnR3YXJlIGFuZCBhc3NvY2lhdGVkIGRvY3VtZW50YXRpb24gZmlsZXMgKHRoZVxuLy8gXCJTb2Z0d2FyZVwiKSwgdG8gZGVhbCBpbiB0aGUgU29mdHdhcmUgd2l0aG91dCByZXN0cmljdGlvbiwgaW5jbHVkaW5nXG4vLyB3aXRob3V0IGxpbWl0YXRpb24gdGhlIHJpZ2h0cyB0byB1c2UsIGNvcHksIG1vZGlmeSwgbWVyZ2UsIHB1Ymxpc2gsXG4vLyBkaXN0cmlidXRlLCBzdWJsaWNlbnNlLCBhbmQvb3Igc2VsbCBjb3BpZXMgb2YgdGhlIFNvZnR3YXJlLCBhbmQgdG8gcGVybWl0XG4vLyBwZXJzb25zIHRvIHdob20gdGhlIFNvZnR3YXJlIGlzIGZ1cm5pc2hlZCB0byBkbyBzbywgc3ViamVjdCB0byB0aGVcbi8vIGZvbGxvd2luZyBjb25kaXRpb25zOlxuLy9cbi8vIFRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGFuZCB0aGlzIHBlcm1pc3Npb24gbm90aWNlIHNoYWxsIGJlIGluY2x1ZGVkXG4vLyBpbiBhbGwgY29waWVzIG9yIHN1YnN0YW50aWFsIHBvcnRpb25zIG9mIHRoZSBTb2Z0d2FyZS5cbi8vXG4vLyBUSEUgU09GVFdBUkUgSVMgUFJPVklERUQgXCJBUyBJU1wiLCBXSVRIT1VUIFdBUlJBTlRZIE9GIEFOWSBLSU5ELCBFWFBSRVNTXG4vLyBPUiBJTVBMSUVELCBJTkNMVURJTkcgQlVUIE5PVCBMSU1JVEVEIFRPIFRIRSBXQVJSQU5USUVTIE9GXG4vLyBNRVJDSEFOVEFCSUxJVFksIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFORCBOT05JTkZSSU5HRU1FTlQuIElOXG4vLyBOTyBFVkVOVCBTSEFMTCBUSEUgQVVUSE9SUyBPUiBDT1BZUklHSFQgSE9MREVSUyBCRSBMSUFCTEUgRk9SIEFOWSBDTEFJTSxcbi8vIERBTUFHRVMgT1IgT1RIRVIgTElBQklMSVRZLCBXSEVUSEVSIElOIEFOIEFDVElPTiBPRiBDT05UUkFDVCwgVE9SVCBPUlxuLy8gT1RIRVJXSVNFLCBBUklTSU5HIEZST00sIE9VVCBPRiBPUiBJTiBDT05ORUNUSU9OIFdJVEggVEhFIFNPRlRXQVJFIE9SIFRIRVxuLy8gVVNFIE9SIE9USEVSIERFQUxJTkdTIElOIFRIRSBTT0ZUV0FSRS5cblxuLy8gYSBwYXNzdGhyb3VnaCBzdHJlYW0uXG4vLyBiYXNpY2FsbHkganVzdCB0aGUgbW9zdCBtaW5pbWFsIHNvcnQgb2YgVHJhbnNmb3JtIHN0cmVhbS5cbi8vIEV2ZXJ5IHdyaXR0ZW4gY2h1bmsgZ2V0cyBvdXRwdXQgYXMtaXMuXG5cbid1c2Ugc3RyaWN0JztcblxubW9kdWxlLmV4cG9ydHMgPSBQYXNzVGhyb3VnaDtcbnZhciBUcmFuc2Zvcm0gPSByZXF1aXJlKCcuL19zdHJlYW1fdHJhbnNmb3JtJyk7XG5yZXF1aXJlKCdpbmhlcml0cycpKFBhc3NUaHJvdWdoLCBUcmFuc2Zvcm0pO1xuZnVuY3Rpb24gUGFzc1Rocm91Z2gob3B0aW9ucykge1xuICBpZiAoISh0aGlzIGluc3RhbmNlb2YgUGFzc1Rocm91Z2gpKSByZXR1cm4gbmV3IFBhc3NUaHJvdWdoKG9wdGlvbnMpO1xuICBUcmFuc2Zvcm0uY2FsbCh0aGlzLCBvcHRpb25zKTtcbn1cblBhc3NUaHJvdWdoLnByb3RvdHlwZS5fdHJhbnNmb3JtID0gZnVuY3Rpb24gKGNodW5rLCBlbmNvZGluZywgY2IpIHtcbiAgY2IobnVsbCwgY2h1bmspO1xufTsiLCIvLyBQb3J0ZWQgZnJvbSBodHRwczovL2dpdGh1Yi5jb20vbWFmaW50b3NoL3B1bXAgd2l0aFxuLy8gcGVybWlzc2lvbiBmcm9tIHRoZSBhdXRob3IsIE1hdGhpYXMgQnV1cyAoQG1hZmludG9zaCkuXG5cbid1c2Ugc3RyaWN0JztcblxudmFyIGVvcztcbmZ1bmN0aW9uIG9uY2UoY2FsbGJhY2spIHtcbiAgdmFyIGNhbGxlZCA9IGZhbHNlO1xuICByZXR1cm4gZnVuY3Rpb24gKCkge1xuICAgIGlmIChjYWxsZWQpIHJldHVybjtcbiAgICBjYWxsZWQgPSB0cnVlO1xuICAgIGNhbGxiYWNrLmFwcGx5KHZvaWQgMCwgYXJndW1lbnRzKTtcbiAgfTtcbn1cbnZhciBfcmVxdWlyZSRjb2RlcyA9IHJlcXVpcmUoJy4uLy4uLy4uL2Vycm9ycycpLmNvZGVzLFxuICBFUlJfTUlTU0lOR19BUkdTID0gX3JlcXVpcmUkY29kZXMuRVJSX01JU1NJTkdfQVJHUyxcbiAgRVJSX1NUUkVBTV9ERVNUUk9ZRUQgPSBfcmVxdWlyZSRjb2Rlcy5FUlJfU1RSRUFNX0RFU1RST1lFRDtcbmZ1bmN0aW9uIG5vb3AoZXJyKSB7XG4gIC8vIFJldGhyb3cgdGhlIGVycm9yIGlmIGl0IGV4aXN0cyB0byBhdm9pZCBzd2FsbG93aW5nIGl0XG4gIGlmIChlcnIpIHRocm93IGVycjtcbn1cbmZ1bmN0aW9uIGlzUmVxdWVzdChzdHJlYW0pIHtcbiAgcmV0dXJuIHN0cmVhbS5zZXRIZWFkZXIgJiYgdHlwZW9mIHN0cmVhbS5hYm9ydCA9PT0gJ2Z1bmN0aW9uJztcbn1cbmZ1bmN0aW9uIGRlc3Ryb3llcihzdHJlYW0sIHJlYWRpbmcsIHdyaXRpbmcsIGNhbGxiYWNrKSB7XG4gIGNhbGxiYWNrID0gb25jZShjYWxsYmFjayk7XG4gIHZhciBjbG9zZWQgPSBmYWxzZTtcbiAgc3RyZWFtLm9uKCdjbG9zZScsIGZ1bmN0aW9uICgpIHtcbiAgICBjbG9zZWQgPSB0cnVlO1xuICB9KTtcbiAgaWYgKGVvcyA9PT0gdW5kZWZpbmVkKSBlb3MgPSByZXF1aXJlKCcuL2VuZC1vZi1zdHJlYW0nKTtcbiAgZW9zKHN0cmVhbSwge1xuICAgIHJlYWRhYmxlOiByZWFkaW5nLFxuICAgIHdyaXRhYmxlOiB3cml0aW5nXG4gIH0sIGZ1bmN0aW9uIChlcnIpIHtcbiAgICBpZiAoZXJyKSByZXR1cm4gY2FsbGJhY2soZXJyKTtcbiAgICBjbG9zZWQgPSB0cnVlO1xuICAgIGNhbGxiYWNrKCk7XG4gIH0pO1xuICB2YXIgZGVzdHJveWVkID0gZmFsc2U7XG4gIHJldHVybiBmdW5jdGlvbiAoZXJyKSB7XG4gICAgaWYgKGNsb3NlZCkgcmV0dXJuO1xuICAgIGlmIChkZXN0cm95ZWQpIHJldHVybjtcbiAgICBkZXN0cm95ZWQgPSB0cnVlO1xuXG4gICAgLy8gcmVxdWVzdC5kZXN0cm95IGp1c3QgZG8gLmVuZCAtIC5hYm9ydCBpcyB3aGF0IHdlIHdhbnRcbiAgICBpZiAoaXNSZXF1ZXN0KHN0cmVhbSkpIHJldHVybiBzdHJlYW0uYWJvcnQoKTtcbiAgICBpZiAodHlwZW9mIHN0cmVhbS5kZXN0cm95ID09PSAnZnVuY3Rpb24nKSByZXR1cm4gc3RyZWFtLmRlc3Ryb3koKTtcbiAgICBjYWxsYmFjayhlcnIgfHwgbmV3IEVSUl9TVFJFQU1fREVTVFJPWUVEKCdwaXBlJykpO1xuICB9O1xufVxuZnVuY3Rpb24gY2FsbChmbikge1xuICBmbigpO1xufVxuZnVuY3Rpb24gcGlwZShmcm9tLCB0bykge1xuICByZXR1cm4gZnJvbS5waXBlKHRvKTtcbn1cbmZ1bmN0aW9uIHBvcENhbGxiYWNrKHN0cmVhbXMpIHtcbiAgaWYgKCFzdHJlYW1zLmxlbmd0aCkgcmV0dXJuIG5vb3A7XG4gIGlmICh0eXBlb2Ygc3RyZWFtc1tzdHJlYW1zLmxlbmd0aCAtIDFdICE9PSAnZnVuY3Rpb24nKSByZXR1cm4gbm9vcDtcbiAgcmV0dXJuIHN0cmVhbXMucG9wKCk7XG59XG5mdW5jdGlvbiBwaXBlbGluZSgpIHtcbiAgZm9yICh2YXIgX2xlbiA9IGFyZ3VtZW50cy5sZW5ndGgsIHN0cmVhbXMgPSBuZXcgQXJyYXkoX2xlbiksIF9rZXkgPSAwOyBfa2V5IDwgX2xlbjsgX2tleSsrKSB7XG4gICAgc3RyZWFtc1tfa2V5XSA9IGFyZ3VtZW50c1tfa2V5XTtcbiAgfVxuICB2YXIgY2FsbGJhY2sgPSBwb3BDYWxsYmFjayhzdHJlYW1zKTtcbiAgaWYgKEFycmF5LmlzQXJyYXkoc3RyZWFtc1swXSkpIHN0cmVhbXMgPSBzdHJlYW1zWzBdO1xuICBpZiAoc3RyZWFtcy5sZW5ndGggPCAyKSB7XG4gICAgdGhyb3cgbmV3IEVSUl9NSVNTSU5HX0FSR1MoJ3N0cmVhbXMnKTtcbiAgfVxuICB2YXIgZXJyb3I7XG4gIHZhciBkZXN0cm95cyA9IHN0cmVhbXMubWFwKGZ1bmN0aW9uIChzdHJlYW0sIGkpIHtcbiAgICB2YXIgcmVhZGluZyA9IGkgPCBzdHJlYW1zLmxlbmd0aCAtIDE7XG4gICAgdmFyIHdyaXRpbmcgPSBpID4gMDtcbiAgICByZXR1cm4gZGVzdHJveWVyKHN0cmVhbSwgcmVhZGluZywgd3JpdGluZywgZnVuY3Rpb24gKGVycikge1xuICAgICAgaWYgKCFlcnJvcikgZXJyb3IgPSBlcnI7XG4gICAgICBpZiAoZXJyKSBkZXN0cm95cy5mb3JFYWNoKGNhbGwpO1xuICAgICAgaWYgKHJlYWRpbmcpIHJldHVybjtcbiAgICAgIGRlc3Ryb3lzLmZvckVhY2goY2FsbCk7XG4gICAgICBjYWxsYmFjayhlcnJvcik7XG4gICAgfSk7XG4gIH0pO1xuICByZXR1cm4gc3RyZWFtcy5yZWR1Y2UocGlwZSk7XG59XG5tb2R1bGUuZXhwb3J0cyA9IHBpcGVsaW5lOyIsInZhciBTdHJlYW0gPSByZXF1aXJlKCdzdHJlYW0nKTtcbmlmIChwcm9jZXNzLmVudi5SRUFEQUJMRV9TVFJFQU0gPT09ICdkaXNhYmxlJyAmJiBTdHJlYW0pIHtcbiAgbW9kdWxlLmV4cG9ydHMgPSBTdHJlYW0uUmVhZGFibGU7XG4gIE9iamVjdC5hc3NpZ24obW9kdWxlLmV4cG9ydHMsIFN0cmVhbSk7XG4gIG1vZHVsZS5leHBvcnRzLlN0cmVhbSA9IFN0cmVhbTtcbn0gZWxzZSB7XG4gIGV4cG9ydHMgPSBtb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoJy4vbGliL19zdHJlYW1fcmVhZGFibGUuanMnKTtcbiAgZXhwb3J0cy5TdHJlYW0gPSBTdHJlYW0gfHwgZXhwb3J0cztcbiAgZXhwb3J0cy5SZWFkYWJsZSA9IGV4cG9ydHM7XG4gIGV4cG9ydHMuV3JpdGFibGUgPSByZXF1aXJlKCcuL2xpYi9fc3RyZWFtX3dyaXRhYmxlLmpzJyk7XG4gIGV4cG9ydHMuRHVwbGV4ID0gcmVxdWlyZSgnLi9saWIvX3N0cmVhbV9kdXBsZXguanMnKTtcbiAgZXhwb3J0cy5UcmFuc2Zvcm0gPSByZXF1aXJlKCcuL2xpYi9fc3RyZWFtX3RyYW5zZm9ybS5qcycpO1xuICBleHBvcnRzLlBhc3NUaHJvdWdoID0gcmVxdWlyZSgnLi9saWIvX3N0cmVhbV9wYXNzdGhyb3VnaC5qcycpO1xuICBleHBvcnRzLmZpbmlzaGVkID0gcmVxdWlyZSgnLi9saWIvaW50ZXJuYWwvc3RyZWFtcy9lbmQtb2Ytc3RyZWFtLmpzJyk7XG4gIGV4cG9ydHMucGlwZWxpbmUgPSByZXF1aXJlKCcuL2xpYi9pbnRlcm5hbC9zdHJlYW1zL3BpcGVsaW5lLmpzJyk7XG59XG4iLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbmV4cG9ydHMuUmVhZGFibGVXZWJUb05vZGVTdHJlYW0gPSB2b2lkIDA7XG5jb25zdCByZWFkYWJsZV9zdHJlYW1fMSA9IHJlcXVpcmUoXCJyZWFkYWJsZS1zdHJlYW1cIik7XG4vKipcbiAqIENvbnZlcnRzIGEgV2ViLUFQSSBzdHJlYW0gaW50byBOb2RlIHN0cmVhbS5SZWFkYWJsZSBjbGFzc1xuICogTm9kZSBzdHJlYW0gcmVhZGFibGU6IGh0dHBzOi8vbm9kZWpzLm9yZy9hcGkvc3RyZWFtLmh0bWwjc3RyZWFtX3JlYWRhYmxlX3N0cmVhbXNcbiAqIFdlYiBBUEkgcmVhZGFibGUtc3RyZWFtOiBodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9BUEkvUmVhZGFibGVTdHJlYW1cbiAqIE5vZGUgcmVhZGFibGUgc3RyZWFtOiBodHRwczovL25vZGVqcy5vcmcvYXBpL3N0cmVhbS5odG1sI3N0cmVhbV9yZWFkYWJsZV9zdHJlYW1zXG4gKi9cbmNsYXNzIFJlYWRhYmxlV2ViVG9Ob2RlU3RyZWFtIGV4dGVuZHMgcmVhZGFibGVfc3RyZWFtXzEuUmVhZGFibGUge1xuICAgIC8qKlxuICAgICAqXG4gICAgICogQHBhcmFtIHN0cmVhbSBSZWFkYWJsZeKAi1N0cmVhbTogaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvQVBJL1JlYWRhYmxlU3RyZWFtXG4gICAgICovXG4gICAgY29uc3RydWN0b3Ioc3RyZWFtKSB7XG4gICAgICAgIHN1cGVyKCk7XG4gICAgICAgIHRoaXMuYnl0ZXNSZWFkID0gMDtcbiAgICAgICAgdGhpcy5yZWxlYXNlZCA9IGZhbHNlO1xuICAgICAgICB0aGlzLnJlYWRlciA9IHN0cmVhbS5nZXRSZWFkZXIoKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogSW1wbGVtZW50YXRpb24gb2YgcmVhZGFibGUuX3JlYWQoc2l6ZSkuXG4gICAgICogV2hlbiByZWFkYWJsZS5fcmVhZCgpIGlzIGNhbGxlZCwgaWYgZGF0YSBpcyBhdmFpbGFibGUgZnJvbSB0aGUgcmVzb3VyY2UsXG4gICAgICogdGhlIGltcGxlbWVudGF0aW9uIHNob3VsZCBiZWdpbiBwdXNoaW5nIHRoYXQgZGF0YSBpbnRvIHRoZSByZWFkIHF1ZXVlXG4gICAgICogaHR0cHM6Ly9ub2RlanMub3JnL2FwaS9zdHJlYW0uaHRtbCNzdHJlYW1fcmVhZGFibGVfcmVhZF9zaXplXzFcbiAgICAgKi9cbiAgICBhc3luYyBfcmVhZCgpIHtcbiAgICAgICAgLy8gU2hvdWxkIHN0YXJ0IHB1c2hpbmcgZGF0YSBpbnRvIHRoZSBxdWV1ZVxuICAgICAgICAvLyBSZWFkIGRhdGEgZnJvbSB0aGUgdW5kZXJseWluZyBXZWItQVBJLXJlYWRhYmxlLXN0cmVhbVxuICAgICAgICBpZiAodGhpcy5yZWxlYXNlZCkge1xuICAgICAgICAgICAgdGhpcy5wdXNoKG51bGwpOyAvLyBTaWduYWwgRU9GXG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5wZW5kaW5nUmVhZCA9IHRoaXMucmVhZGVyLnJlYWQoKTtcbiAgICAgICAgY29uc3QgZGF0YSA9IGF3YWl0IHRoaXMucGVuZGluZ1JlYWQ7XG4gICAgICAgIC8vIGNsZWFyIHRoZSBwcm9taXNlIGJlZm9yZSBwdXNoaW5nIHB1c2hpbmcgbmV3IGRhdGEgdG8gdGhlIHF1ZXVlIGFuZCBhbGxvdyBzZXF1ZW50aWFsIGNhbGxzIHRvIF9yZWFkKClcbiAgICAgICAgZGVsZXRlIHRoaXMucGVuZGluZ1JlYWQ7XG4gICAgICAgIGlmIChkYXRhLmRvbmUgfHwgdGhpcy5yZWxlYXNlZCkge1xuICAgICAgICAgICAgdGhpcy5wdXNoKG51bGwpOyAvLyBTaWduYWwgRU9GXG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICB0aGlzLmJ5dGVzUmVhZCArPSBkYXRhLnZhbHVlLmxlbmd0aDtcbiAgICAgICAgICAgIHRoaXMucHVzaChkYXRhLnZhbHVlKTsgLy8gUHVzaCBuZXcgZGF0YSB0byB0aGUgcXVldWVcbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBJZiB0aGVyZSBpcyBubyB1bnJlc29sdmVkIHJlYWQgY2FsbCB0byBXZWItQVBJIFJlYWRhYmxl4oCLU3RyZWFtIGltbWVkaWF0ZWx5IHJldHVybnM7XG4gICAgICogb3RoZXJ3aXNlIHdpbGwgd2FpdCB1bnRpbCB0aGUgcmVhZCBpcyByZXNvbHZlZC5cbiAgICAgKi9cbiAgICBhc3luYyB3YWl0Rm9yUmVhZFRvQ29tcGxldGUoKSB7XG4gICAgICAgIGlmICh0aGlzLnBlbmRpbmdSZWFkKSB7XG4gICAgICAgICAgICBhd2FpdCB0aGlzLnBlbmRpbmdSZWFkO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgICAqIENsb3NlIHdyYXBwZXJcbiAgICAgKi9cbiAgICBhc3luYyBjbG9zZSgpIHtcbiAgICAgICAgYXdhaXQgdGhpcy5zeW5jQW5kUmVsZWFzZSgpO1xuICAgIH1cbiAgICBhc3luYyBzeW5jQW5kUmVsZWFzZSgpIHtcbiAgICAgICAgdGhpcy5yZWxlYXNlZCA9IHRydWU7XG4gICAgICAgIGF3YWl0IHRoaXMud2FpdEZvclJlYWRUb0NvbXBsZXRlKCk7XG4gICAgICAgIGF3YWl0IHRoaXMucmVhZGVyLnJlbGVhc2VMb2NrKCk7XG4gICAgfVxufVxuZXhwb3J0cy5SZWFkYWJsZVdlYlRvTm9kZVN0cmVhbSA9IFJlYWRhYmxlV2ViVG9Ob2RlU3RyZWFtO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9aW5kZXguanMubWFwIiwiaW1wb3J0ICogYXMgaWVlZTc1NCBmcm9tICdpZWVlNzU0JztcbmltcG9ydCB7IEJ1ZmZlciB9IGZyb20gJ25vZGU6YnVmZmVyJztcbi8vIFByaW1pdGl2ZSB0eXBlc1xuZnVuY3Rpb24gZHYoYXJyYXkpIHtcbiAgICByZXR1cm4gbmV3IERhdGFWaWV3KGFycmF5LmJ1ZmZlciwgYXJyYXkuYnl0ZU9mZnNldCk7XG59XG4vKipcbiAqIDgtYml0IHVuc2lnbmVkIGludGVnZXJcbiAqL1xuZXhwb3J0IGNvbnN0IFVJTlQ4ID0ge1xuICAgIGxlbjogMSxcbiAgICBnZXQoYXJyYXksIG9mZnNldCkge1xuICAgICAgICByZXR1cm4gZHYoYXJyYXkpLmdldFVpbnQ4KG9mZnNldCk7XG4gICAgfSxcbiAgICBwdXQoYXJyYXksIG9mZnNldCwgdmFsdWUpIHtcbiAgICAgICAgZHYoYXJyYXkpLnNldFVpbnQ4KG9mZnNldCwgdmFsdWUpO1xuICAgICAgICByZXR1cm4gb2Zmc2V0ICsgMTtcbiAgICB9XG59O1xuLyoqXG4gKiAxNi1iaXQgdW5zaWduZWQgaW50ZWdlciwgTGl0dGxlIEVuZGlhbiBieXRlIG9yZGVyXG4gKi9cbmV4cG9ydCBjb25zdCBVSU5UMTZfTEUgPSB7XG4gICAgbGVuOiAyLFxuICAgIGdldChhcnJheSwgb2Zmc2V0KSB7XG4gICAgICAgIHJldHVybiBkdihhcnJheSkuZ2V0VWludDE2KG9mZnNldCwgdHJ1ZSk7XG4gICAgfSxcbiAgICBwdXQoYXJyYXksIG9mZnNldCwgdmFsdWUpIHtcbiAgICAgICAgZHYoYXJyYXkpLnNldFVpbnQxNihvZmZzZXQsIHZhbHVlLCB0cnVlKTtcbiAgICAgICAgcmV0dXJuIG9mZnNldCArIDI7XG4gICAgfVxufTtcbi8qKlxuICogMTYtYml0IHVuc2lnbmVkIGludGVnZXIsIEJpZyBFbmRpYW4gYnl0ZSBvcmRlclxuICovXG5leHBvcnQgY29uc3QgVUlOVDE2X0JFID0ge1xuICAgIGxlbjogMixcbiAgICBnZXQoYXJyYXksIG9mZnNldCkge1xuICAgICAgICByZXR1cm4gZHYoYXJyYXkpLmdldFVpbnQxNihvZmZzZXQpO1xuICAgIH0sXG4gICAgcHV0KGFycmF5LCBvZmZzZXQsIHZhbHVlKSB7XG4gICAgICAgIGR2KGFycmF5KS5zZXRVaW50MTYob2Zmc2V0LCB2YWx1ZSk7XG4gICAgICAgIHJldHVybiBvZmZzZXQgKyAyO1xuICAgIH1cbn07XG4vKipcbiAqIDI0LWJpdCB1bnNpZ25lZCBpbnRlZ2VyLCBMaXR0bGUgRW5kaWFuIGJ5dGUgb3JkZXJcbiAqL1xuZXhwb3J0IGNvbnN0IFVJTlQyNF9MRSA9IHtcbiAgICBsZW46IDMsXG4gICAgZ2V0KGFycmF5LCBvZmZzZXQpIHtcbiAgICAgICAgY29uc3QgZGF0YVZpZXcgPSBkdihhcnJheSk7XG4gICAgICAgIHJldHVybiBkYXRhVmlldy5nZXRVaW50OChvZmZzZXQpICsgKGRhdGFWaWV3LmdldFVpbnQxNihvZmZzZXQgKyAxLCB0cnVlKSA8PCA4KTtcbiAgICB9LFxuICAgIHB1dChhcnJheSwgb2Zmc2V0LCB2YWx1ZSkge1xuICAgICAgICBjb25zdCBkYXRhVmlldyA9IGR2KGFycmF5KTtcbiAgICAgICAgZGF0YVZpZXcuc2V0VWludDgob2Zmc2V0LCB2YWx1ZSAmIDB4ZmYpO1xuICAgICAgICBkYXRhVmlldy5zZXRVaW50MTYob2Zmc2V0ICsgMSwgdmFsdWUgPj4gOCwgdHJ1ZSk7XG4gICAgICAgIHJldHVybiBvZmZzZXQgKyAzO1xuICAgIH1cbn07XG4vKipcbiAqIDI0LWJpdCB1bnNpZ25lZCBpbnRlZ2VyLCBCaWcgRW5kaWFuIGJ5dGUgb3JkZXJcbiAqL1xuZXhwb3J0IGNvbnN0IFVJTlQyNF9CRSA9IHtcbiAgICBsZW46IDMsXG4gICAgZ2V0KGFycmF5LCBvZmZzZXQpIHtcbiAgICAgICAgY29uc3QgZGF0YVZpZXcgPSBkdihhcnJheSk7XG4gICAgICAgIHJldHVybiAoZGF0YVZpZXcuZ2V0VWludDE2KG9mZnNldCkgPDwgOCkgKyBkYXRhVmlldy5nZXRVaW50OChvZmZzZXQgKyAyKTtcbiAgICB9LFxuICAgIHB1dChhcnJheSwgb2Zmc2V0LCB2YWx1ZSkge1xuICAgICAgICBjb25zdCBkYXRhVmlldyA9IGR2KGFycmF5KTtcbiAgICAgICAgZGF0YVZpZXcuc2V0VWludDE2KG9mZnNldCwgdmFsdWUgPj4gOCk7XG4gICAgICAgIGRhdGFWaWV3LnNldFVpbnQ4KG9mZnNldCArIDIsIHZhbHVlICYgMHhmZik7XG4gICAgICAgIHJldHVybiBvZmZzZXQgKyAzO1xuICAgIH1cbn07XG4vKipcbiAqIDMyLWJpdCB1bnNpZ25lZCBpbnRlZ2VyLCBMaXR0bGUgRW5kaWFuIGJ5dGUgb3JkZXJcbiAqL1xuZXhwb3J0IGNvbnN0IFVJTlQzMl9MRSA9IHtcbiAgICBsZW46IDQsXG4gICAgZ2V0KGFycmF5LCBvZmZzZXQpIHtcbiAgICAgICAgcmV0dXJuIGR2KGFycmF5KS5nZXRVaW50MzIob2Zmc2V0LCB0cnVlKTtcbiAgICB9LFxuICAgIHB1dChhcnJheSwgb2Zmc2V0LCB2YWx1ZSkge1xuICAgICAgICBkdihhcnJheSkuc2V0VWludDMyKG9mZnNldCwgdmFsdWUsIHRydWUpO1xuICAgICAgICByZXR1cm4gb2Zmc2V0ICsgNDtcbiAgICB9XG59O1xuLyoqXG4gKiAzMi1iaXQgdW5zaWduZWQgaW50ZWdlciwgQmlnIEVuZGlhbiBieXRlIG9yZGVyXG4gKi9cbmV4cG9ydCBjb25zdCBVSU5UMzJfQkUgPSB7XG4gICAgbGVuOiA0LFxuICAgIGdldChhcnJheSwgb2Zmc2V0KSB7XG4gICAgICAgIHJldHVybiBkdihhcnJheSkuZ2V0VWludDMyKG9mZnNldCk7XG4gICAgfSxcbiAgICBwdXQoYXJyYXksIG9mZnNldCwgdmFsdWUpIHtcbiAgICAgICAgZHYoYXJyYXkpLnNldFVpbnQzMihvZmZzZXQsIHZhbHVlKTtcbiAgICAgICAgcmV0dXJuIG9mZnNldCArIDQ7XG4gICAgfVxufTtcbi8qKlxuICogOC1iaXQgc2lnbmVkIGludGVnZXJcbiAqL1xuZXhwb3J0IGNvbnN0IElOVDggPSB7XG4gICAgbGVuOiAxLFxuICAgIGdldChhcnJheSwgb2Zmc2V0KSB7XG4gICAgICAgIHJldHVybiBkdihhcnJheSkuZ2V0SW50OChvZmZzZXQpO1xuICAgIH0sXG4gICAgcHV0KGFycmF5LCBvZmZzZXQsIHZhbHVlKSB7XG4gICAgICAgIGR2KGFycmF5KS5zZXRJbnQ4KG9mZnNldCwgdmFsdWUpO1xuICAgICAgICByZXR1cm4gb2Zmc2V0ICsgMTtcbiAgICB9XG59O1xuLyoqXG4gKiAxNi1iaXQgc2lnbmVkIGludGVnZXIsIEJpZyBFbmRpYW4gYnl0ZSBvcmRlclxuICovXG5leHBvcnQgY29uc3QgSU5UMTZfQkUgPSB7XG4gICAgbGVuOiAyLFxuICAgIGdldChhcnJheSwgb2Zmc2V0KSB7XG4gICAgICAgIHJldHVybiBkdihhcnJheSkuZ2V0SW50MTYob2Zmc2V0KTtcbiAgICB9LFxuICAgIHB1dChhcnJheSwgb2Zmc2V0LCB2YWx1ZSkge1xuICAgICAgICBkdihhcnJheSkuc2V0SW50MTYob2Zmc2V0LCB2YWx1ZSk7XG4gICAgICAgIHJldHVybiBvZmZzZXQgKyAyO1xuICAgIH1cbn07XG4vKipcbiAqIDE2LWJpdCBzaWduZWQgaW50ZWdlciwgTGl0dGxlIEVuZGlhbiBieXRlIG9yZGVyXG4gKi9cbmV4cG9ydCBjb25zdCBJTlQxNl9MRSA9IHtcbiAgICBsZW46IDIsXG4gICAgZ2V0KGFycmF5LCBvZmZzZXQpIHtcbiAgICAgICAgcmV0dXJuIGR2KGFycmF5KS5nZXRJbnQxNihvZmZzZXQsIHRydWUpO1xuICAgIH0sXG4gICAgcHV0KGFycmF5LCBvZmZzZXQsIHZhbHVlKSB7XG4gICAgICAgIGR2KGFycmF5KS5zZXRJbnQxNihvZmZzZXQsIHZhbHVlLCB0cnVlKTtcbiAgICAgICAgcmV0dXJuIG9mZnNldCArIDI7XG4gICAgfVxufTtcbi8qKlxuICogMjQtYml0IHNpZ25lZCBpbnRlZ2VyLCBMaXR0bGUgRW5kaWFuIGJ5dGUgb3JkZXJcbiAqL1xuZXhwb3J0IGNvbnN0IElOVDI0X0xFID0ge1xuICAgIGxlbjogMyxcbiAgICBnZXQoYXJyYXksIG9mZnNldCkge1xuICAgICAgICBjb25zdCB1bnNpZ25lZCA9IFVJTlQyNF9MRS5nZXQoYXJyYXksIG9mZnNldCk7XG4gICAgICAgIHJldHVybiB1bnNpZ25lZCA+IDB4N2ZmZmZmID8gdW5zaWduZWQgLSAweDEwMDAwMDAgOiB1bnNpZ25lZDtcbiAgICB9LFxuICAgIHB1dChhcnJheSwgb2Zmc2V0LCB2YWx1ZSkge1xuICAgICAgICBjb25zdCBkYXRhVmlldyA9IGR2KGFycmF5KTtcbiAgICAgICAgZGF0YVZpZXcuc2V0VWludDgob2Zmc2V0LCB2YWx1ZSAmIDB4ZmYpO1xuICAgICAgICBkYXRhVmlldy5zZXRVaW50MTYob2Zmc2V0ICsgMSwgdmFsdWUgPj4gOCwgdHJ1ZSk7XG4gICAgICAgIHJldHVybiBvZmZzZXQgKyAzO1xuICAgIH1cbn07XG4vKipcbiAqIDI0LWJpdCBzaWduZWQgaW50ZWdlciwgQmlnIEVuZGlhbiBieXRlIG9yZGVyXG4gKi9cbmV4cG9ydCBjb25zdCBJTlQyNF9CRSA9IHtcbiAgICBsZW46IDMsXG4gICAgZ2V0KGFycmF5LCBvZmZzZXQpIHtcbiAgICAgICAgY29uc3QgdW5zaWduZWQgPSBVSU5UMjRfQkUuZ2V0KGFycmF5LCBvZmZzZXQpO1xuICAgICAgICByZXR1cm4gdW5zaWduZWQgPiAweDdmZmZmZiA/IHVuc2lnbmVkIC0gMHgxMDAwMDAwIDogdW5zaWduZWQ7XG4gICAgfSxcbiAgICBwdXQoYXJyYXksIG9mZnNldCwgdmFsdWUpIHtcbiAgICAgICAgY29uc3QgZGF0YVZpZXcgPSBkdihhcnJheSk7XG4gICAgICAgIGRhdGFWaWV3LnNldFVpbnQxNihvZmZzZXQsIHZhbHVlID4+IDgpO1xuICAgICAgICBkYXRhVmlldy5zZXRVaW50OChvZmZzZXQgKyAyLCB2YWx1ZSAmIDB4ZmYpO1xuICAgICAgICByZXR1cm4gb2Zmc2V0ICsgMztcbiAgICB9XG59O1xuLyoqXG4gKiAzMi1iaXQgc2lnbmVkIGludGVnZXIsIEJpZyBFbmRpYW4gYnl0ZSBvcmRlclxuICovXG5leHBvcnQgY29uc3QgSU5UMzJfQkUgPSB7XG4gICAgbGVuOiA0LFxuICAgIGdldChhcnJheSwgb2Zmc2V0KSB7XG4gICAgICAgIHJldHVybiBkdihhcnJheSkuZ2V0SW50MzIob2Zmc2V0KTtcbiAgICB9LFxuICAgIHB1dChhcnJheSwgb2Zmc2V0LCB2YWx1ZSkge1xuICAgICAgICBkdihhcnJheSkuc2V0SW50MzIob2Zmc2V0LCB2YWx1ZSk7XG4gICAgICAgIHJldHVybiBvZmZzZXQgKyA0O1xuICAgIH1cbn07XG4vKipcbiAqIDMyLWJpdCBzaWduZWQgaW50ZWdlciwgQmlnIEVuZGlhbiBieXRlIG9yZGVyXG4gKi9cbmV4cG9ydCBjb25zdCBJTlQzMl9MRSA9IHtcbiAgICBsZW46IDQsXG4gICAgZ2V0KGFycmF5LCBvZmZzZXQpIHtcbiAgICAgICAgcmV0dXJuIGR2KGFycmF5KS5nZXRJbnQzMihvZmZzZXQsIHRydWUpO1xuICAgIH0sXG4gICAgcHV0KGFycmF5LCBvZmZzZXQsIHZhbHVlKSB7XG4gICAgICAgIGR2KGFycmF5KS5zZXRJbnQzMihvZmZzZXQsIHZhbHVlLCB0cnVlKTtcbiAgICAgICAgcmV0dXJuIG9mZnNldCArIDQ7XG4gICAgfVxufTtcbi8qKlxuICogNjQtYml0IHVuc2lnbmVkIGludGVnZXIsIExpdHRsZSBFbmRpYW4gYnl0ZSBvcmRlclxuICovXG5leHBvcnQgY29uc3QgVUlOVDY0X0xFID0ge1xuICAgIGxlbjogOCxcbiAgICBnZXQoYXJyYXksIG9mZnNldCkge1xuICAgICAgICByZXR1cm4gZHYoYXJyYXkpLmdldEJpZ1VpbnQ2NChvZmZzZXQsIHRydWUpO1xuICAgIH0sXG4gICAgcHV0KGFycmF5LCBvZmZzZXQsIHZhbHVlKSB7XG4gICAgICAgIGR2KGFycmF5KS5zZXRCaWdVaW50NjQob2Zmc2V0LCB2YWx1ZSwgdHJ1ZSk7XG4gICAgICAgIHJldHVybiBvZmZzZXQgKyA4O1xuICAgIH1cbn07XG4vKipcbiAqIDY0LWJpdCBzaWduZWQgaW50ZWdlciwgTGl0dGxlIEVuZGlhbiBieXRlIG9yZGVyXG4gKi9cbmV4cG9ydCBjb25zdCBJTlQ2NF9MRSA9IHtcbiAgICBsZW46IDgsXG4gICAgZ2V0KGFycmF5LCBvZmZzZXQpIHtcbiAgICAgICAgcmV0dXJuIGR2KGFycmF5KS5nZXRCaWdJbnQ2NChvZmZzZXQsIHRydWUpO1xuICAgIH0sXG4gICAgcHV0KGFycmF5LCBvZmZzZXQsIHZhbHVlKSB7XG4gICAgICAgIGR2KGFycmF5KS5zZXRCaWdJbnQ2NChvZmZzZXQsIHZhbHVlLCB0cnVlKTtcbiAgICAgICAgcmV0dXJuIG9mZnNldCArIDg7XG4gICAgfVxufTtcbi8qKlxuICogNjQtYml0IHVuc2lnbmVkIGludGVnZXIsIEJpZyBFbmRpYW4gYnl0ZSBvcmRlclxuICovXG5leHBvcnQgY29uc3QgVUlOVDY0X0JFID0ge1xuICAgIGxlbjogOCxcbiAgICBnZXQoYXJyYXksIG9mZnNldCkge1xuICAgICAgICByZXR1cm4gZHYoYXJyYXkpLmdldEJpZ1VpbnQ2NChvZmZzZXQpO1xuICAgIH0sXG4gICAgcHV0KGFycmF5LCBvZmZzZXQsIHZhbHVlKSB7XG4gICAgICAgIGR2KGFycmF5KS5zZXRCaWdVaW50NjQob2Zmc2V0LCB2YWx1ZSk7XG4gICAgICAgIHJldHVybiBvZmZzZXQgKyA4O1xuICAgIH1cbn07XG4vKipcbiAqIDY0LWJpdCBzaWduZWQgaW50ZWdlciwgQmlnIEVuZGlhbiBieXRlIG9yZGVyXG4gKi9cbmV4cG9ydCBjb25zdCBJTlQ2NF9CRSA9IHtcbiAgICBsZW46IDgsXG4gICAgZ2V0KGFycmF5LCBvZmZzZXQpIHtcbiAgICAgICAgcmV0dXJuIGR2KGFycmF5KS5nZXRCaWdJbnQ2NChvZmZzZXQpO1xuICAgIH0sXG4gICAgcHV0KGFycmF5LCBvZmZzZXQsIHZhbHVlKSB7XG4gICAgICAgIGR2KGFycmF5KS5zZXRCaWdJbnQ2NChvZmZzZXQsIHZhbHVlKTtcbiAgICAgICAgcmV0dXJuIG9mZnNldCArIDg7XG4gICAgfVxufTtcbi8qKlxuICogSUVFRSA3NTQgMTYtYml0IChoYWxmIHByZWNpc2lvbikgZmxvYXQsIGJpZyBlbmRpYW5cbiAqL1xuZXhwb3J0IGNvbnN0IEZsb2F0MTZfQkUgPSB7XG4gICAgbGVuOiAyLFxuICAgIGdldChkYXRhVmlldywgb2Zmc2V0KSB7XG4gICAgICAgIHJldHVybiBpZWVlNzU0LnJlYWQoZGF0YVZpZXcsIG9mZnNldCwgZmFsc2UsIDEwLCB0aGlzLmxlbik7XG4gICAgfSxcbiAgICBwdXQoZGF0YVZpZXcsIG9mZnNldCwgdmFsdWUpIHtcbiAgICAgICAgaWVlZTc1NC53cml0ZShkYXRhVmlldywgdmFsdWUsIG9mZnNldCwgZmFsc2UsIDEwLCB0aGlzLmxlbik7XG4gICAgICAgIHJldHVybiBvZmZzZXQgKyB0aGlzLmxlbjtcbiAgICB9XG59O1xuLyoqXG4gKiBJRUVFIDc1NCAxNi1iaXQgKGhhbGYgcHJlY2lzaW9uKSBmbG9hdCwgbGl0dGxlIGVuZGlhblxuICovXG5leHBvcnQgY29uc3QgRmxvYXQxNl9MRSA9IHtcbiAgICBsZW46IDIsXG4gICAgZ2V0KGFycmF5LCBvZmZzZXQpIHtcbiAgICAgICAgcmV0dXJuIGllZWU3NTQucmVhZChhcnJheSwgb2Zmc2V0LCB0cnVlLCAxMCwgdGhpcy5sZW4pO1xuICAgIH0sXG4gICAgcHV0KGFycmF5LCBvZmZzZXQsIHZhbHVlKSB7XG4gICAgICAgIGllZWU3NTQud3JpdGUoYXJyYXksIHZhbHVlLCBvZmZzZXQsIHRydWUsIDEwLCB0aGlzLmxlbik7XG4gICAgICAgIHJldHVybiBvZmZzZXQgKyB0aGlzLmxlbjtcbiAgICB9XG59O1xuLyoqXG4gKiBJRUVFIDc1NCAzMi1iaXQgKHNpbmdsZSBwcmVjaXNpb24pIGZsb2F0LCBiaWcgZW5kaWFuXG4gKi9cbmV4cG9ydCBjb25zdCBGbG9hdDMyX0JFID0ge1xuICAgIGxlbjogNCxcbiAgICBnZXQoYXJyYXksIG9mZnNldCkge1xuICAgICAgICByZXR1cm4gZHYoYXJyYXkpLmdldEZsb2F0MzIob2Zmc2V0KTtcbiAgICB9LFxuICAgIHB1dChhcnJheSwgb2Zmc2V0LCB2YWx1ZSkge1xuICAgICAgICBkdihhcnJheSkuc2V0RmxvYXQzMihvZmZzZXQsIHZhbHVlKTtcbiAgICAgICAgcmV0dXJuIG9mZnNldCArIDQ7XG4gICAgfVxufTtcbi8qKlxuICogSUVFRSA3NTQgMzItYml0IChzaW5nbGUgcHJlY2lzaW9uKSBmbG9hdCwgbGl0dGxlIGVuZGlhblxuICovXG5leHBvcnQgY29uc3QgRmxvYXQzMl9MRSA9IHtcbiAgICBsZW46IDQsXG4gICAgZ2V0KGFycmF5LCBvZmZzZXQpIHtcbiAgICAgICAgcmV0dXJuIGR2KGFycmF5KS5nZXRGbG9hdDMyKG9mZnNldCwgdHJ1ZSk7XG4gICAgfSxcbiAgICBwdXQoYXJyYXksIG9mZnNldCwgdmFsdWUpIHtcbiAgICAgICAgZHYoYXJyYXkpLnNldEZsb2F0MzIob2Zmc2V0LCB2YWx1ZSwgdHJ1ZSk7XG4gICAgICAgIHJldHVybiBvZmZzZXQgKyA0O1xuICAgIH1cbn07XG4vKipcbiAqIElFRUUgNzU0IDY0LWJpdCAoZG91YmxlIHByZWNpc2lvbikgZmxvYXQsIGJpZyBlbmRpYW5cbiAqL1xuZXhwb3J0IGNvbnN0IEZsb2F0NjRfQkUgPSB7XG4gICAgbGVuOiA4LFxuICAgIGdldChhcnJheSwgb2Zmc2V0KSB7XG4gICAgICAgIHJldHVybiBkdihhcnJheSkuZ2V0RmxvYXQ2NChvZmZzZXQpO1xuICAgIH0sXG4gICAgcHV0KGFycmF5LCBvZmZzZXQsIHZhbHVlKSB7XG4gICAgICAgIGR2KGFycmF5KS5zZXRGbG9hdDY0KG9mZnNldCwgdmFsdWUpO1xuICAgICAgICByZXR1cm4gb2Zmc2V0ICsgODtcbiAgICB9XG59O1xuLyoqXG4gKiBJRUVFIDc1NCA2NC1iaXQgKGRvdWJsZSBwcmVjaXNpb24pIGZsb2F0LCBsaXR0bGUgZW5kaWFuXG4gKi9cbmV4cG9ydCBjb25zdCBGbG9hdDY0X0xFID0ge1xuICAgIGxlbjogOCxcbiAgICBnZXQoYXJyYXksIG9mZnNldCkge1xuICAgICAgICByZXR1cm4gZHYoYXJyYXkpLmdldEZsb2F0NjQob2Zmc2V0LCB0cnVlKTtcbiAgICB9LFxuICAgIHB1dChhcnJheSwgb2Zmc2V0LCB2YWx1ZSkge1xuICAgICAgICBkdihhcnJheSkuc2V0RmxvYXQ2NChvZmZzZXQsIHZhbHVlLCB0cnVlKTtcbiAgICAgICAgcmV0dXJuIG9mZnNldCArIDg7XG4gICAgfVxufTtcbi8qKlxuICogSUVFRSA3NTQgODAtYml0IChleHRlbmRlZCBwcmVjaXNpb24pIGZsb2F0LCBiaWcgZW5kaWFuXG4gKi9cbmV4cG9ydCBjb25zdCBGbG9hdDgwX0JFID0ge1xuICAgIGxlbjogMTAsXG4gICAgZ2V0KGFycmF5LCBvZmZzZXQpIHtcbiAgICAgICAgcmV0dXJuIGllZWU3NTQucmVhZChhcnJheSwgb2Zmc2V0LCBmYWxzZSwgNjMsIHRoaXMubGVuKTtcbiAgICB9LFxuICAgIHB1dChhcnJheSwgb2Zmc2V0LCB2YWx1ZSkge1xuICAgICAgICBpZWVlNzU0LndyaXRlKGFycmF5LCB2YWx1ZSwgb2Zmc2V0LCBmYWxzZSwgNjMsIHRoaXMubGVuKTtcbiAgICAgICAgcmV0dXJuIG9mZnNldCArIHRoaXMubGVuO1xuICAgIH1cbn07XG4vKipcbiAqIElFRUUgNzU0IDgwLWJpdCAoZXh0ZW5kZWQgcHJlY2lzaW9uKSBmbG9hdCwgbGl0dGxlIGVuZGlhblxuICovXG5leHBvcnQgY29uc3QgRmxvYXQ4MF9MRSA9IHtcbiAgICBsZW46IDEwLFxuICAgIGdldChhcnJheSwgb2Zmc2V0KSB7XG4gICAgICAgIHJldHVybiBpZWVlNzU0LnJlYWQoYXJyYXksIG9mZnNldCwgdHJ1ZSwgNjMsIHRoaXMubGVuKTtcbiAgICB9LFxuICAgIHB1dChhcnJheSwgb2Zmc2V0LCB2YWx1ZSkge1xuICAgICAgICBpZWVlNzU0LndyaXRlKGFycmF5LCB2YWx1ZSwgb2Zmc2V0LCB0cnVlLCA2MywgdGhpcy5sZW4pO1xuICAgICAgICByZXR1cm4gb2Zmc2V0ICsgdGhpcy5sZW47XG4gICAgfVxufTtcbi8qKlxuICogSWdub3JlIGEgZ2l2ZW4gbnVtYmVyIG9mIGJ5dGVzXG4gKi9cbmV4cG9ydCBjbGFzcyBJZ25vcmVUeXBlIHtcbiAgICAvKipcbiAgICAgKiBAcGFyYW0gbGVuIG51bWJlciBvZiBieXRlcyB0byBpZ25vcmVcbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvcihsZW4pIHtcbiAgICAgICAgdGhpcy5sZW4gPSBsZW47XG4gICAgfVxuICAgIC8vIFRvRG86IGRvbid0IHJlYWQsIGJ1dCBza2lwIGRhdGFcbiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLWVtcHR5LWZ1bmN0aW9uXG4gICAgZ2V0KGFycmF5LCBvZmYpIHtcbiAgICB9XG59XG5leHBvcnQgY2xhc3MgVWludDhBcnJheVR5cGUge1xuICAgIGNvbnN0cnVjdG9yKGxlbikge1xuICAgICAgICB0aGlzLmxlbiA9IGxlbjtcbiAgICB9XG4gICAgZ2V0KGFycmF5LCBvZmZzZXQpIHtcbiAgICAgICAgcmV0dXJuIGFycmF5LnN1YmFycmF5KG9mZnNldCwgb2Zmc2V0ICsgdGhpcy5sZW4pO1xuICAgIH1cbn1cbmV4cG9ydCBjbGFzcyBCdWZmZXJUeXBlIHtcbiAgICBjb25zdHJ1Y3RvcihsZW4pIHtcbiAgICAgICAgdGhpcy5sZW4gPSBsZW47XG4gICAgfVxuICAgIGdldCh1aW50OEFycmF5LCBvZmYpIHtcbiAgICAgICAgcmV0dXJuIEJ1ZmZlci5mcm9tKHVpbnQ4QXJyYXkuc3ViYXJyYXkob2ZmLCBvZmYgKyB0aGlzLmxlbikpO1xuICAgIH1cbn1cbi8qKlxuICogQ29uc3VtZSBhIGZpeGVkIG51bWJlciBvZiBieXRlcyBmcm9tIHRoZSBzdHJlYW0gYW5kIHJldHVybiBhIHN0cmluZyB3aXRoIGEgc3BlY2lmaWVkIGVuY29kaW5nLlxuICovXG5leHBvcnQgY2xhc3MgU3RyaW5nVHlwZSB7XG4gICAgY29uc3RydWN0b3IobGVuLCBlbmNvZGluZykge1xuICAgICAgICB0aGlzLmxlbiA9IGxlbjtcbiAgICAgICAgdGhpcy5lbmNvZGluZyA9IGVuY29kaW5nO1xuICAgIH1cbiAgICBnZXQodWludDhBcnJheSwgb2Zmc2V0KSB7XG4gICAgICAgIHJldHVybiBCdWZmZXIuZnJvbSh1aW50OEFycmF5KS50b1N0cmluZyh0aGlzLmVuY29kaW5nLCBvZmZzZXQsIG9mZnNldCArIHRoaXMubGVuKTtcbiAgICB9XG59XG4vKipcbiAqIEFOU0kgTGF0aW4gMSBTdHJpbmdcbiAqIFVzaW5nIHdpbmRvd3MtMTI1MiAvIElTTyA4ODU5LTEgZGVjb2RpbmdcbiAqL1xuZXhwb3J0IGNsYXNzIEFuc2lTdHJpbmdUeXBlIHtcbiAgICBjb25zdHJ1Y3RvcihsZW4pIHtcbiAgICAgICAgdGhpcy5sZW4gPSBsZW47XG4gICAgfVxuICAgIHN0YXRpYyBkZWNvZGUoYnVmZmVyLCBvZmZzZXQsIHVudGlsKSB7XG4gICAgICAgIGxldCBzdHIgPSAnJztcbiAgICAgICAgZm9yIChsZXQgaSA9IG9mZnNldDsgaSA8IHVudGlsOyArK2kpIHtcbiAgICAgICAgICAgIHN0ciArPSBBbnNpU3RyaW5nVHlwZS5jb2RlUG9pbnRUb1N0cmluZyhBbnNpU3RyaW5nVHlwZS5zaW5nbGVCeXRlRGVjb2RlcihidWZmZXJbaV0pKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gc3RyO1xuICAgIH1cbiAgICBzdGF0aWMgaW5SYW5nZShhLCBtaW4sIG1heCkge1xuICAgICAgICByZXR1cm4gbWluIDw9IGEgJiYgYSA8PSBtYXg7XG4gICAgfVxuICAgIHN0YXRpYyBjb2RlUG9pbnRUb1N0cmluZyhjcCkge1xuICAgICAgICBpZiAoY3AgPD0gMHhGRkZGKSB7XG4gICAgICAgICAgICByZXR1cm4gU3RyaW5nLmZyb21DaGFyQ29kZShjcCk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBjcCAtPSAweDEwMDAwO1xuICAgICAgICAgICAgcmV0dXJuIFN0cmluZy5mcm9tQ2hhckNvZGUoKGNwID4+IDEwKSArIDB4RDgwMCwgKGNwICYgMHgzRkYpICsgMHhEQzAwKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBzdGF0aWMgc2luZ2xlQnl0ZURlY29kZXIoYml0ZSkge1xuICAgICAgICBpZiAoQW5zaVN0cmluZ1R5cGUuaW5SYW5nZShiaXRlLCAweDAwLCAweDdGKSkge1xuICAgICAgICAgICAgcmV0dXJuIGJpdGU7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgY29kZVBvaW50ID0gQW5zaVN0cmluZ1R5cGUud2luZG93czEyNTJbYml0ZSAtIDB4ODBdO1xuICAgICAgICBpZiAoY29kZVBvaW50ID09PSBudWxsKSB7XG4gICAgICAgICAgICB0aHJvdyBFcnJvcignaW52YWxpZGluZyBlbmNvZGluZycpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBjb2RlUG9pbnQ7XG4gICAgfVxuICAgIGdldChidWZmZXIsIG9mZnNldCA9IDApIHtcbiAgICAgICAgcmV0dXJuIEFuc2lTdHJpbmdUeXBlLmRlY29kZShidWZmZXIsIG9mZnNldCwgb2Zmc2V0ICsgdGhpcy5sZW4pO1xuICAgIH1cbn1cbkFuc2lTdHJpbmdUeXBlLndpbmRvd3MxMjUyID0gWzgzNjQsIDEyOSwgODIxOCwgNDAyLCA4MjIyLCA4MjMwLCA4MjI0LCA4MjI1LCA3MTAsIDgyNDAsIDM1MixcbiAgICA4MjQ5LCAzMzgsIDE0MSwgMzgxLCAxNDMsIDE0NCwgODIxNiwgODIxNywgODIyMCwgODIyMSwgODIyNiwgODIxMSwgODIxMiwgNzMyLFxuICAgIDg0ODIsIDM1MywgODI1MCwgMzM5LCAxNTcsIDM4MiwgMzc2LCAxNjAsIDE2MSwgMTYyLCAxNjMsIDE2NCwgMTY1LCAxNjYsIDE2NywgMTY4LFxuICAgIDE2OSwgMTcwLCAxNzEsIDE3MiwgMTczLCAxNzQsIDE3NSwgMTc2LCAxNzcsIDE3OCwgMTc5LCAxODAsIDE4MSwgMTgyLCAxODMsIDE4NCxcbiAgICAxODUsIDE4NiwgMTg3LCAxODgsIDE4OSwgMTkwLCAxOTEsIDE5MiwgMTkzLCAxOTQsIDE5NSwgMTk2LCAxOTcsIDE5OCwgMTk5LCAyMDAsXG4gICAgMjAxLCAyMDIsIDIwMywgMjA0LCAyMDUsIDIwNiwgMjA3LCAyMDgsIDIwOSwgMjEwLCAyMTEsIDIxMiwgMjEzLCAyMTQsIDIxNSwgMjE2LFxuICAgIDIxNywgMjE4LCAyMTksIDIyMCwgMjIxLCAyMjIsIDIyMywgMjI0LCAyMjUsIDIyNiwgMjI3LCAyMjgsIDIyOSwgMjMwLCAyMzEsIDIzMixcbiAgICAyMzMsIDIzNCwgMjM1LCAyMzYsIDIzNywgMjM4LCAyMzksIDI0MCwgMjQxLCAyNDIsIDI0MywgMjQ0LCAyNDUsIDI0NiwgMjQ3LFxuICAgIDI0OCwgMjQ5LCAyNTAsIDI1MSwgMjUyLCAyNTMsIDI1NCwgMjU1XTtcbiIsImV4cG9ydCBjb25zdCBkZWZhdWx0TWVzc2FnZXMgPSAnRW5kLU9mLVN0cmVhbSc7XG4vKipcbiAqIFRocm93biBvbiByZWFkIG9wZXJhdGlvbiBvZiB0aGUgZW5kIG9mIGZpbGUgb3Igc3RyZWFtIGhhcyBiZWVuIHJlYWNoZWRcbiAqL1xuZXhwb3J0IGNsYXNzIEVuZE9mU3RyZWFtRXJyb3IgZXh0ZW5kcyBFcnJvciB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKGRlZmF1bHRNZXNzYWdlcyk7XG4gICAgfVxufVxuIiwiaW1wb3J0IHsgRW5kT2ZTdHJlYW1FcnJvciB9IGZyb20gJ3BlZWstcmVhZGFibGUnO1xuaW1wb3J0IHsgQnVmZmVyIH0gZnJvbSAnbm9kZTpidWZmZXInO1xuLyoqXG4gKiBDb3JlIHRva2VuaXplclxuICovXG5leHBvcnQgY2xhc3MgQWJzdHJhY3RUb2tlbml6ZXIge1xuICAgIGNvbnN0cnVjdG9yKGZpbGVJbmZvKSB7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUb2tlbml6ZXItc3RyZWFtIHBvc2l0aW9uXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLnBvc2l0aW9uID0gMDtcbiAgICAgICAgdGhpcy5udW1CdWZmZXIgPSBuZXcgVWludDhBcnJheSg4KTtcbiAgICAgICAgdGhpcy5maWxlSW5mbyA9IGZpbGVJbmZvID8gZmlsZUluZm8gOiB7fTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmVhZCBhIHRva2VuIGZyb20gdGhlIHRva2VuaXplci1zdHJlYW1cbiAgICAgKiBAcGFyYW0gdG9rZW4gLSBUaGUgdG9rZW4gdG8gcmVhZFxuICAgICAqIEBwYXJhbSBwb3NpdGlvbiAtIElmIHByb3ZpZGVkLCB0aGUgZGVzaXJlZCBwb3NpdGlvbiBpbiB0aGUgdG9rZW5pemVyLXN0cmVhbVxuICAgICAqIEByZXR1cm5zIFByb21pc2Ugd2l0aCB0b2tlbiBkYXRhXG4gICAgICovXG4gICAgYXN5bmMgcmVhZFRva2VuKHRva2VuLCBwb3NpdGlvbiA9IHRoaXMucG9zaXRpb24pIHtcbiAgICAgICAgY29uc3QgdWludDhBcnJheSA9IEJ1ZmZlci5hbGxvYyh0b2tlbi5sZW4pO1xuICAgICAgICBjb25zdCBsZW4gPSBhd2FpdCB0aGlzLnJlYWRCdWZmZXIodWludDhBcnJheSwgeyBwb3NpdGlvbiB9KTtcbiAgICAgICAgaWYgKGxlbiA8IHRva2VuLmxlbilcbiAgICAgICAgICAgIHRocm93IG5ldyBFbmRPZlN0cmVhbUVycm9yKCk7XG4gICAgICAgIHJldHVybiB0b2tlbi5nZXQodWludDhBcnJheSwgMCk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFBlZWsgYSB0b2tlbiBmcm9tIHRoZSB0b2tlbml6ZXItc3RyZWFtLlxuICAgICAqIEBwYXJhbSB0b2tlbiAtIFRva2VuIHRvIHBlZWsgZnJvbSB0aGUgdG9rZW5pemVyLXN0cmVhbS5cbiAgICAgKiBAcGFyYW0gcG9zaXRpb24gLSBPZmZzZXQgd2hlcmUgdG8gYmVnaW4gcmVhZGluZyB3aXRoaW4gdGhlIGZpbGUuIElmIHBvc2l0aW9uIGlzIG51bGwsIGRhdGEgd2lsbCBiZSByZWFkIGZyb20gdGhlIGN1cnJlbnQgZmlsZSBwb3NpdGlvbi5cbiAgICAgKiBAcmV0dXJucyBQcm9taXNlIHdpdGggdG9rZW4gZGF0YVxuICAgICAqL1xuICAgIGFzeW5jIHBlZWtUb2tlbih0b2tlbiwgcG9zaXRpb24gPSB0aGlzLnBvc2l0aW9uKSB7XG4gICAgICAgIGNvbnN0IHVpbnQ4QXJyYXkgPSBCdWZmZXIuYWxsb2ModG9rZW4ubGVuKTtcbiAgICAgICAgY29uc3QgbGVuID0gYXdhaXQgdGhpcy5wZWVrQnVmZmVyKHVpbnQ4QXJyYXksIHsgcG9zaXRpb24gfSk7XG4gICAgICAgIGlmIChsZW4gPCB0b2tlbi5sZW4pXG4gICAgICAgICAgICB0aHJvdyBuZXcgRW5kT2ZTdHJlYW1FcnJvcigpO1xuICAgICAgICByZXR1cm4gdG9rZW4uZ2V0KHVpbnQ4QXJyYXksIDApO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZWFkIGEgbnVtZXJpYyB0b2tlbiBmcm9tIHRoZSBzdHJlYW1cbiAgICAgKiBAcGFyYW0gdG9rZW4gLSBOdW1lcmljIHRva2VuXG4gICAgICogQHJldHVybnMgUHJvbWlzZSB3aXRoIG51bWJlclxuICAgICAqL1xuICAgIGFzeW5jIHJlYWROdW1iZXIodG9rZW4pIHtcbiAgICAgICAgY29uc3QgbGVuID0gYXdhaXQgdGhpcy5yZWFkQnVmZmVyKHRoaXMubnVtQnVmZmVyLCB7IGxlbmd0aDogdG9rZW4ubGVuIH0pO1xuICAgICAgICBpZiAobGVuIDwgdG9rZW4ubGVuKVxuICAgICAgICAgICAgdGhyb3cgbmV3IEVuZE9mU3RyZWFtRXJyb3IoKTtcbiAgICAgICAgcmV0dXJuIHRva2VuLmdldCh0aGlzLm51bUJ1ZmZlciwgMCk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJlYWQgYSBudW1lcmljIHRva2VuIGZyb20gdGhlIHN0cmVhbVxuICAgICAqIEBwYXJhbSB0b2tlbiAtIE51bWVyaWMgdG9rZW5cbiAgICAgKiBAcmV0dXJucyBQcm9taXNlIHdpdGggbnVtYmVyXG4gICAgICovXG4gICAgYXN5bmMgcGVla051bWJlcih0b2tlbikge1xuICAgICAgICBjb25zdCBsZW4gPSBhd2FpdCB0aGlzLnBlZWtCdWZmZXIodGhpcy5udW1CdWZmZXIsIHsgbGVuZ3RoOiB0b2tlbi5sZW4gfSk7XG4gICAgICAgIGlmIChsZW4gPCB0b2tlbi5sZW4pXG4gICAgICAgICAgICB0aHJvdyBuZXcgRW5kT2ZTdHJlYW1FcnJvcigpO1xuICAgICAgICByZXR1cm4gdG9rZW4uZ2V0KHRoaXMubnVtQnVmZmVyLCAwKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogSWdub3JlIG51bWJlciBvZiBieXRlcywgYWR2YW5jZXMgdGhlIHBvaW50ZXIgaW4gdW5kZXIgdG9rZW5pemVyLXN0cmVhbS5cbiAgICAgKiBAcGFyYW0gbGVuZ3RoIC0gTnVtYmVyIG9mIGJ5dGVzIHRvIGlnbm9yZVxuICAgICAqIEByZXR1cm4gcmVzb2x2ZXMgdGhlIG51bWJlciBvZiBieXRlcyBpZ25vcmVkLCBlcXVhbHMgbGVuZ3RoIGlmIHRoaXMgYXZhaWxhYmxlLCBvdGhlcndpc2UgdGhlIG51bWJlciBvZiBieXRlcyBhdmFpbGFibGVcbiAgICAgKi9cbiAgICBhc3luYyBpZ25vcmUobGVuZ3RoKSB7XG4gICAgICAgIGlmICh0aGlzLmZpbGVJbmZvLnNpemUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgY29uc3QgYnl0ZXNMZWZ0ID0gdGhpcy5maWxlSW5mby5zaXplIC0gdGhpcy5wb3NpdGlvbjtcbiAgICAgICAgICAgIGlmIChsZW5ndGggPiBieXRlc0xlZnQpIHtcbiAgICAgICAgICAgICAgICB0aGlzLnBvc2l0aW9uICs9IGJ5dGVzTGVmdDtcbiAgICAgICAgICAgICAgICByZXR1cm4gYnl0ZXNMZWZ0O1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHRoaXMucG9zaXRpb24gKz0gbGVuZ3RoO1xuICAgICAgICByZXR1cm4gbGVuZ3RoO1xuICAgIH1cbiAgICBhc3luYyBjbG9zZSgpIHtcbiAgICAgICAgLy8gZW1wdHlcbiAgICB9XG4gICAgbm9ybWFsaXplT3B0aW9ucyh1aW50OEFycmF5LCBvcHRpb25zKSB7XG4gICAgICAgIGlmIChvcHRpb25zICYmIG9wdGlvbnMucG9zaXRpb24gIT09IHVuZGVmaW5lZCAmJiBvcHRpb25zLnBvc2l0aW9uIDwgdGhpcy5wb3NpdGlvbikge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdgb3B0aW9ucy5wb3NpdGlvbmAgbXVzdCBiZSBlcXVhbCBvciBncmVhdGVyIHRoYW4gYHRva2VuaXplci5wb3NpdGlvbmAnKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAob3B0aW9ucykge1xuICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgICBtYXlCZUxlc3M6IG9wdGlvbnMubWF5QmVMZXNzID09PSB0cnVlLFxuICAgICAgICAgICAgICAgIG9mZnNldDogb3B0aW9ucy5vZmZzZXQgPyBvcHRpb25zLm9mZnNldCA6IDAsXG4gICAgICAgICAgICAgICAgbGVuZ3RoOiBvcHRpb25zLmxlbmd0aCA/IG9wdGlvbnMubGVuZ3RoIDogKHVpbnQ4QXJyYXkubGVuZ3RoIC0gKG9wdGlvbnMub2Zmc2V0ID8gb3B0aW9ucy5vZmZzZXQgOiAwKSksXG4gICAgICAgICAgICAgICAgcG9zaXRpb246IG9wdGlvbnMucG9zaXRpb24gPyBvcHRpb25zLnBvc2l0aW9uIDogdGhpcy5wb3NpdGlvblxuICAgICAgICAgICAgfTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgbWF5QmVMZXNzOiBmYWxzZSxcbiAgICAgICAgICAgIG9mZnNldDogMCxcbiAgICAgICAgICAgIGxlbmd0aDogdWludDhBcnJheS5sZW5ndGgsXG4gICAgICAgICAgICBwb3NpdGlvbjogdGhpcy5wb3NpdGlvblxuICAgICAgICB9O1xuICAgIH1cbn1cbiIsImltcG9ydCB7IEVuZE9mU3RyZWFtRXJyb3IgfSBmcm9tICdwZWVrLXJlYWRhYmxlJztcbmltcG9ydCB7IEFic3RyYWN0VG9rZW5pemVyIH0gZnJvbSAnLi9BYnN0cmFjdFRva2VuaXplci5qcyc7XG5leHBvcnQgY2xhc3MgQnVmZmVyVG9rZW5pemVyIGV4dGVuZHMgQWJzdHJhY3RUb2tlbml6ZXIge1xuICAgIC8qKlxuICAgICAqIENvbnN0cnVjdCBCdWZmZXJUb2tlbml6ZXJcbiAgICAgKiBAcGFyYW0gdWludDhBcnJheSAtIFVpbnQ4QXJyYXkgdG8gdG9rZW5pemVcbiAgICAgKiBAcGFyYW0gZmlsZUluZm8gLSBQYXNzIGFkZGl0aW9uYWwgZmlsZSBpbmZvcm1hdGlvbiB0byB0aGUgdG9rZW5pemVyXG4gICAgICovXG4gICAgY29uc3RydWN0b3IodWludDhBcnJheSwgZmlsZUluZm8pIHtcbiAgICAgICAgc3VwZXIoZmlsZUluZm8pO1xuICAgICAgICB0aGlzLnVpbnQ4QXJyYXkgPSB1aW50OEFycmF5O1xuICAgICAgICB0aGlzLmZpbGVJbmZvLnNpemUgPSB0aGlzLmZpbGVJbmZvLnNpemUgPyB0aGlzLmZpbGVJbmZvLnNpemUgOiB1aW50OEFycmF5Lmxlbmd0aDtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmVhZCBidWZmZXIgZnJvbSB0b2tlbml6ZXJcbiAgICAgKiBAcGFyYW0gdWludDhBcnJheSAtIFVpbnQ4QXJyYXkgdG8gdG9rZW5pemVcbiAgICAgKiBAcGFyYW0gb3B0aW9ucyAtIFJlYWQgYmVoYXZpb3VyIG9wdGlvbnNcbiAgICAgKiBAcmV0dXJucyB7UHJvbWlzZTxudW1iZXI+fVxuICAgICAqL1xuICAgIGFzeW5jIHJlYWRCdWZmZXIodWludDhBcnJheSwgb3B0aW9ucykge1xuICAgICAgICBpZiAob3B0aW9ucyAmJiBvcHRpb25zLnBvc2l0aW9uKSB7XG4gICAgICAgICAgICBpZiAob3B0aW9ucy5wb3NpdGlvbiA8IHRoaXMucG9zaXRpb24pIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ2BvcHRpb25zLnBvc2l0aW9uYCBtdXN0IGJlIGVxdWFsIG9yIGdyZWF0ZXIgdGhhbiBgdG9rZW5pemVyLnBvc2l0aW9uYCcpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhpcy5wb3NpdGlvbiA9IG9wdGlvbnMucG9zaXRpb247XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgYnl0ZXNSZWFkID0gYXdhaXQgdGhpcy5wZWVrQnVmZmVyKHVpbnQ4QXJyYXksIG9wdGlvbnMpO1xuICAgICAgICB0aGlzLnBvc2l0aW9uICs9IGJ5dGVzUmVhZDtcbiAgICAgICAgcmV0dXJuIGJ5dGVzUmVhZDtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUGVlayAocmVhZCBhaGVhZCkgYnVmZmVyIGZyb20gdG9rZW5pemVyXG4gICAgICogQHBhcmFtIHVpbnQ4QXJyYXlcbiAgICAgKiBAcGFyYW0gb3B0aW9ucyAtIFJlYWQgYmVoYXZpb3VyIG9wdGlvbnNcbiAgICAgKiBAcmV0dXJucyB7UHJvbWlzZTxudW1iZXI+fVxuICAgICAqL1xuICAgIGFzeW5jIHBlZWtCdWZmZXIodWludDhBcnJheSwgb3B0aW9ucykge1xuICAgICAgICBjb25zdCBub3JtT3B0aW9ucyA9IHRoaXMubm9ybWFsaXplT3B0aW9ucyh1aW50OEFycmF5LCBvcHRpb25zKTtcbiAgICAgICAgY29uc3QgYnl0ZXMycmVhZCA9IE1hdGgubWluKHRoaXMudWludDhBcnJheS5sZW5ndGggLSBub3JtT3B0aW9ucy5wb3NpdGlvbiwgbm9ybU9wdGlvbnMubGVuZ3RoKTtcbiAgICAgICAgaWYgKCghbm9ybU9wdGlvbnMubWF5QmVMZXNzKSAmJiBieXRlczJyZWFkIDwgbm9ybU9wdGlvbnMubGVuZ3RoKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRW5kT2ZTdHJlYW1FcnJvcigpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgdWludDhBcnJheS5zZXQodGhpcy51aW50OEFycmF5LnN1YmFycmF5KG5vcm1PcHRpb25zLnBvc2l0aW9uLCBub3JtT3B0aW9ucy5wb3NpdGlvbiArIGJ5dGVzMnJlYWQpLCBub3JtT3B0aW9ucy5vZmZzZXQpO1xuICAgICAgICAgICAgcmV0dXJuIGJ5dGVzMnJlYWQ7XG4gICAgICAgIH1cbiAgICB9XG4gICAgYXN5bmMgY2xvc2UoKSB7XG4gICAgICAgIC8vIGVtcHR5XG4gICAgfVxufVxuIiwiaW1wb3J0IHsgUmVhZFN0cmVhbVRva2VuaXplciB9IGZyb20gJy4vUmVhZFN0cmVhbVRva2VuaXplci5qcyc7XG5pbXBvcnQgeyBCdWZmZXJUb2tlbml6ZXIgfSBmcm9tICcuL0J1ZmZlclRva2VuaXplci5qcyc7XG5leHBvcnQgeyBFbmRPZlN0cmVhbUVycm9yIH0gZnJvbSAncGVlay1yZWFkYWJsZSc7XG4vKipcbiAqIENvbnN0cnVjdCBSZWFkU3RyZWFtVG9rZW5pemVyIGZyb20gZ2l2ZW4gU3RyZWFtLlxuICogV2lsbCBzZXQgZmlsZVNpemUsIGlmIHByb3ZpZGVkIGdpdmVuIFN0cmVhbSBoYXMgc2V0IHRoZSAucGF0aCBwcm9wZXJ0eS9cbiAqIEBwYXJhbSBzdHJlYW0gLSBSZWFkIGZyb20gTm9kZS5qcyBTdHJlYW0uUmVhZGFibGVcbiAqIEBwYXJhbSBmaWxlSW5mbyAtIFBhc3MgdGhlIGZpbGUgaW5mb3JtYXRpb24sIGxpa2Ugc2l6ZSBhbmQgTUlNRS10eXBlIG9mIHRoZSBjb3JyZXNwb25kaW5nIHN0cmVhbS5cbiAqIEByZXR1cm5zIFJlYWRTdHJlYW1Ub2tlbml6ZXJcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGZyb21TdHJlYW0oc3RyZWFtLCBmaWxlSW5mbykge1xuICAgIGZpbGVJbmZvID0gZmlsZUluZm8gPyBmaWxlSW5mbyA6IHt9O1xuICAgIHJldHVybiBuZXcgUmVhZFN0cmVhbVRva2VuaXplcihzdHJlYW0sIGZpbGVJbmZvKTtcbn1cbi8qKlxuICogQ29uc3RydWN0IFJlYWRTdHJlYW1Ub2tlbml6ZXIgZnJvbSBnaXZlbiBCdWZmZXIuXG4gKiBAcGFyYW0gdWludDhBcnJheSAtIFVpbnQ4QXJyYXkgdG8gdG9rZW5pemVcbiAqIEBwYXJhbSBmaWxlSW5mbyAtIFBhc3MgYWRkaXRpb25hbCBmaWxlIGluZm9ybWF0aW9uIHRvIHRoZSB0b2tlbml6ZXJcbiAqIEByZXR1cm5zIEJ1ZmZlclRva2VuaXplclxuICovXG5leHBvcnQgZnVuY3Rpb24gZnJvbUJ1ZmZlcih1aW50OEFycmF5LCBmaWxlSW5mbykge1xuICAgIHJldHVybiBuZXcgQnVmZmVyVG9rZW5pemVyKHVpbnQ4QXJyYXksIGZpbGVJbmZvKTtcbn1cbiIsImV4cG9ydCBmdW5jdGlvbiBzdHJpbmdUb0J5dGVzKHN0cmluZykge1xuXHRyZXR1cm4gWy4uLnN0cmluZ10ubWFwKGNoYXJhY3RlciA9PiBjaGFyYWN0ZXIuY2hhckNvZGVBdCgwKSk7IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgdW5pY29ybi9wcmVmZXItY29kZS1wb2ludFxufVxuXG4vKipcbkNoZWNrcyB3aGV0aGVyIHRoZSBUQVIgY2hlY2tzdW0gaXMgdmFsaWQuXG5cbkBwYXJhbSB7QnVmZmVyfSBidWZmZXIgLSBUaGUgVEFSIGhlYWRlciBgW29mZnNldCAuLi4gb2Zmc2V0ICsgNTEyXWAuXG5AcGFyYW0ge251bWJlcn0gb2Zmc2V0IC0gVEFSIGhlYWRlciBvZmZzZXQuXG5AcmV0dXJucyB7Ym9vbGVhbn0gYHRydWVgIGlmIHRoZSBUQVIgY2hlY2tzdW0gaXMgdmFsaWQsIG90aGVyd2lzZSBgZmFsc2VgLlxuKi9cbmV4cG9ydCBmdW5jdGlvbiB0YXJIZWFkZXJDaGVja3N1bU1hdGNoZXMoYnVmZmVyLCBvZmZzZXQgPSAwKSB7XG5cdGNvbnN0IHJlYWRTdW0gPSBOdW1iZXIucGFyc2VJbnQoYnVmZmVyLnRvU3RyaW5nKCd1dGY4JywgMTQ4LCAxNTQpLnJlcGxhY2UoL1xcMC4qJC8sICcnKS50cmltKCksIDgpOyAvLyBSZWFkIHN1bSBpbiBoZWFkZXJcblx0aWYgKE51bWJlci5pc05hTihyZWFkU3VtKSkge1xuXHRcdHJldHVybiBmYWxzZTtcblx0fVxuXG5cdGxldCBzdW0gPSA4ICogMHgyMDsgLy8gSW5pdGlhbGl6ZSBzaWduZWQgYml0IHN1bVxuXG5cdGZvciAobGV0IGluZGV4ID0gb2Zmc2V0OyBpbmRleCA8IG9mZnNldCArIDE0ODsgaW5kZXgrKykge1xuXHRcdHN1bSArPSBidWZmZXJbaW5kZXhdO1xuXHR9XG5cblx0Zm9yIChsZXQgaW5kZXggPSBvZmZzZXQgKyAxNTY7IGluZGV4IDwgb2Zmc2V0ICsgNTEyOyBpbmRleCsrKSB7XG5cdFx0c3VtICs9IGJ1ZmZlcltpbmRleF07XG5cdH1cblxuXHRyZXR1cm4gcmVhZFN1bSA9PT0gc3VtO1xufVxuXG4vKipcbklEMyBVSU5UMzIgc3luYy1zYWZlIHRva2VuaXplciB0b2tlbi5cbjI4IGJpdHMgKHJlcHJlc2VudGluZyB1cCB0byAyNTZNQikgaW50ZWdlciwgdGhlIG1zYiBpcyAwIHRvIGF2b2lkIFwiZmFsc2Ugc3luY3NpZ25hbHNcIi5cbiovXG5leHBvcnQgY29uc3QgdWludDMyU3luY1NhZmVUb2tlbiA9IHtcblx0Z2V0OiAoYnVmZmVyLCBvZmZzZXQpID0+IChidWZmZXJbb2Zmc2V0ICsgM10gJiAweDdGKSB8ICgoYnVmZmVyW29mZnNldCArIDJdKSA8PCA3KSB8ICgoYnVmZmVyW29mZnNldCArIDFdKSA8PCAxNCkgfCAoKGJ1ZmZlcltvZmZzZXRdKSA8PCAyMSksXG5cdGxlbjogNCxcbn07XG4iLCJleHBvcnQgY29uc3QgZXh0ZW5zaW9ucyA9IFtcblx0J2pwZycsXG5cdCdwbmcnLFxuXHQnYXBuZycsXG5cdCdnaWYnLFxuXHQnd2VicCcsXG5cdCdmbGlmJyxcblx0J3hjZicsXG5cdCdjcjInLFxuXHQnY3IzJyxcblx0J29yZicsXG5cdCdhcncnLFxuXHQnZG5nJyxcblx0J25lZicsXG5cdCdydzInLFxuXHQncmFmJyxcblx0J3RpZicsXG5cdCdibXAnLFxuXHQnaWNucycsXG5cdCdqeHInLFxuXHQncHNkJyxcblx0J2luZGQnLFxuXHQnemlwJyxcblx0J3RhcicsXG5cdCdyYXInLFxuXHQnZ3onLFxuXHQnYnoyJyxcblx0Jzd6Jyxcblx0J2RtZycsXG5cdCdtcDQnLFxuXHQnbWlkJyxcblx0J21rdicsXG5cdCd3ZWJtJyxcblx0J21vdicsXG5cdCdhdmknLFxuXHQnbXBnJyxcblx0J21wMicsXG5cdCdtcDMnLFxuXHQnbTRhJyxcblx0J29nYScsXG5cdCdvZ2cnLFxuXHQnb2d2Jyxcblx0J29wdXMnLFxuXHQnZmxhYycsXG5cdCd3YXYnLFxuXHQnc3B4Jyxcblx0J2FtcicsXG5cdCdwZGYnLFxuXHQnZXB1YicsXG5cdCdlbGYnLFxuXHQnZXhlJyxcblx0J3N3ZicsXG5cdCdydGYnLFxuXHQnd2FzbScsXG5cdCd3b2ZmJyxcblx0J3dvZmYyJyxcblx0J2VvdCcsXG5cdCd0dGYnLFxuXHQnb3RmJyxcblx0J2ljbycsXG5cdCdmbHYnLFxuXHQncHMnLFxuXHQneHonLFxuXHQnc3FsaXRlJyxcblx0J25lcycsXG5cdCdjcngnLFxuXHQneHBpJyxcblx0J2NhYicsXG5cdCdkZWInLFxuXHQnYXInLFxuXHQncnBtJyxcblx0J1onLFxuXHQnbHonLFxuXHQnY2ZiJyxcblx0J214ZicsXG5cdCdtdHMnLFxuXHQnYmxlbmQnLFxuXHQnYnBnJyxcblx0J2RvY3gnLFxuXHQncHB0eCcsXG5cdCd4bHN4Jyxcblx0JzNncCcsXG5cdCczZzInLFxuXHQnajJjJyxcblx0J2pwMicsXG5cdCdqcG0nLFxuXHQnanB4Jyxcblx0J21qMicsXG5cdCdhaWYnLFxuXHQncWNwJyxcblx0J29kdCcsXG5cdCdvZHMnLFxuXHQnb2RwJyxcblx0J3htbCcsXG5cdCdtb2JpJyxcblx0J2hlaWMnLFxuXHQnY3VyJyxcblx0J2t0eCcsXG5cdCdhcGUnLFxuXHQnd3YnLFxuXHQnZGNtJyxcblx0J2ljcycsXG5cdCdnbGInLFxuXHQncGNhcCcsXG5cdCdkc2YnLFxuXHQnbG5rJyxcblx0J2FsaWFzJyxcblx0J3ZvYycsXG5cdCdhYzMnLFxuXHQnbTR2Jyxcblx0J200cCcsXG5cdCdtNGInLFxuXHQnZjR2Jyxcblx0J2Y0cCcsXG5cdCdmNGInLFxuXHQnZjRhJyxcblx0J21pZScsXG5cdCdhc2YnLFxuXHQnb2dtJyxcblx0J29neCcsXG5cdCdtcGMnLFxuXHQnYXJyb3cnLFxuXHQnc2hwJyxcblx0J2FhYycsXG5cdCdtcDEnLFxuXHQnaXQnLFxuXHQnczNtJyxcblx0J3htJyxcblx0J2FpJyxcblx0J3NrcCcsXG5cdCdhdmlmJyxcblx0J2VwcycsXG5cdCdsemgnLFxuXHQncGdwJyxcblx0J2FzYXInLFxuXHQnc3RsJyxcblx0J2NobScsXG5cdCczbWYnLFxuXHQnenN0Jyxcblx0J2p4bCcsXG5cdCd2Y2YnLFxuXHQnamxzJyxcblx0J3BzdCcsXG5cdCdkd2cnLFxuXHQncGFycXVldCcsXG5cdCdjbGFzcycsXG5cdCdhcmonLFxuXHQnY3BpbycsXG5cdCdhY2UnLFxuXHQnYXZybycsXG5dO1xuXG5leHBvcnQgY29uc3QgbWltZVR5cGVzID0gW1xuXHQnaW1hZ2UvanBlZycsXG5cdCdpbWFnZS9wbmcnLFxuXHQnaW1hZ2UvZ2lmJyxcblx0J2ltYWdlL3dlYnAnLFxuXHQnaW1hZ2UvZmxpZicsXG5cdCdpbWFnZS94LXhjZicsXG5cdCdpbWFnZS94LWNhbm9uLWNyMicsXG5cdCdpbWFnZS94LWNhbm9uLWNyMycsXG5cdCdpbWFnZS90aWZmJyxcblx0J2ltYWdlL2JtcCcsXG5cdCdpbWFnZS92bmQubXMtcGhvdG8nLFxuXHQnaW1hZ2Uvdm5kLmFkb2JlLnBob3Rvc2hvcCcsXG5cdCdhcHBsaWNhdGlvbi94LWluZGVzaWduJyxcblx0J2FwcGxpY2F0aW9uL2VwdWIremlwJyxcblx0J2FwcGxpY2F0aW9uL3gteHBpbnN0YWxsJyxcblx0J2FwcGxpY2F0aW9uL3ZuZC5vYXNpcy5vcGVuZG9jdW1lbnQudGV4dCcsXG5cdCdhcHBsaWNhdGlvbi92bmQub2FzaXMub3BlbmRvY3VtZW50LnNwcmVhZHNoZWV0Jyxcblx0J2FwcGxpY2F0aW9uL3ZuZC5vYXNpcy5vcGVuZG9jdW1lbnQucHJlc2VudGF0aW9uJyxcblx0J2FwcGxpY2F0aW9uL3ZuZC5vcGVueG1sZm9ybWF0cy1vZmZpY2Vkb2N1bWVudC53b3JkcHJvY2Vzc2luZ21sLmRvY3VtZW50Jyxcblx0J2FwcGxpY2F0aW9uL3ZuZC5vcGVueG1sZm9ybWF0cy1vZmZpY2Vkb2N1bWVudC5wcmVzZW50YXRpb25tbC5wcmVzZW50YXRpb24nLFxuXHQnYXBwbGljYXRpb24vdm5kLm9wZW54bWxmb3JtYXRzLW9mZmljZWRvY3VtZW50LnNwcmVhZHNoZWV0bWwuc2hlZXQnLFxuXHQnYXBwbGljYXRpb24vemlwJyxcblx0J2FwcGxpY2F0aW9uL3gtdGFyJyxcblx0J2FwcGxpY2F0aW9uL3gtcmFyLWNvbXByZXNzZWQnLFxuXHQnYXBwbGljYXRpb24vZ3ppcCcsXG5cdCdhcHBsaWNhdGlvbi94LWJ6aXAyJyxcblx0J2FwcGxpY2F0aW9uL3gtN3otY29tcHJlc3NlZCcsXG5cdCdhcHBsaWNhdGlvbi94LWFwcGxlLWRpc2tpbWFnZScsXG5cdCdhcHBsaWNhdGlvbi94LWFwYWNoZS1hcnJvdycsXG5cdCd2aWRlby9tcDQnLFxuXHQnYXVkaW8vbWlkaScsXG5cdCd2aWRlby94LW1hdHJvc2thJyxcblx0J3ZpZGVvL3dlYm0nLFxuXHQndmlkZW8vcXVpY2t0aW1lJyxcblx0J3ZpZGVvL3ZuZC5hdmknLFxuXHQnYXVkaW8vdm5kLndhdmUnLFxuXHQnYXVkaW8vcWNlbHAnLFxuXHQnYXVkaW8veC1tcy1hc2YnLFxuXHQndmlkZW8veC1tcy1hc2YnLFxuXHQnYXBwbGljYXRpb24vdm5kLm1zLWFzZicsXG5cdCd2aWRlby9tcGVnJyxcblx0J3ZpZGVvLzNncHAnLFxuXHQnYXVkaW8vbXBlZycsXG5cdCdhdWRpby9tcDQnLCAvLyBSRkMgNDMzN1xuXHQnYXVkaW8vb3B1cycsXG5cdCd2aWRlby9vZ2cnLFxuXHQnYXVkaW8vb2dnJyxcblx0J2FwcGxpY2F0aW9uL29nZycsXG5cdCdhdWRpby94LWZsYWMnLFxuXHQnYXVkaW8vYXBlJyxcblx0J2F1ZGlvL3dhdnBhY2snLFxuXHQnYXVkaW8vYW1yJyxcblx0J2FwcGxpY2F0aW9uL3BkZicsXG5cdCdhcHBsaWNhdGlvbi94LWVsZicsXG5cdCdhcHBsaWNhdGlvbi94LW1zZG93bmxvYWQnLFxuXHQnYXBwbGljYXRpb24veC1zaG9ja3dhdmUtZmxhc2gnLFxuXHQnYXBwbGljYXRpb24vcnRmJyxcblx0J2FwcGxpY2F0aW9uL3dhc20nLFxuXHQnZm9udC93b2ZmJyxcblx0J2ZvbnQvd29mZjInLFxuXHQnYXBwbGljYXRpb24vdm5kLm1zLWZvbnRvYmplY3QnLFxuXHQnZm9udC90dGYnLFxuXHQnZm9udC9vdGYnLFxuXHQnaW1hZ2UveC1pY29uJyxcblx0J3ZpZGVvL3gtZmx2Jyxcblx0J2FwcGxpY2F0aW9uL3Bvc3RzY3JpcHQnLFxuXHQnYXBwbGljYXRpb24vZXBzJyxcblx0J2FwcGxpY2F0aW9uL3gteHonLFxuXHQnYXBwbGljYXRpb24veC1zcWxpdGUzJyxcblx0J2FwcGxpY2F0aW9uL3gtbmludGVuZG8tbmVzLXJvbScsXG5cdCdhcHBsaWNhdGlvbi94LWdvb2dsZS1jaHJvbWUtZXh0ZW5zaW9uJyxcblx0J2FwcGxpY2F0aW9uL3ZuZC5tcy1jYWItY29tcHJlc3NlZCcsXG5cdCdhcHBsaWNhdGlvbi94LWRlYicsXG5cdCdhcHBsaWNhdGlvbi94LXVuaXgtYXJjaGl2ZScsXG5cdCdhcHBsaWNhdGlvbi94LXJwbScsXG5cdCdhcHBsaWNhdGlvbi94LWNvbXByZXNzJyxcblx0J2FwcGxpY2F0aW9uL3gtbHppcCcsXG5cdCdhcHBsaWNhdGlvbi94LWNmYicsXG5cdCdhcHBsaWNhdGlvbi94LW1pZScsXG5cdCdhcHBsaWNhdGlvbi9teGYnLFxuXHQndmlkZW8vbXAydCcsXG5cdCdhcHBsaWNhdGlvbi94LWJsZW5kZXInLFxuXHQnaW1hZ2UvYnBnJyxcblx0J2ltYWdlL2oyYycsXG5cdCdpbWFnZS9qcDInLFxuXHQnaW1hZ2UvanB4Jyxcblx0J2ltYWdlL2pwbScsXG5cdCdpbWFnZS9tajInLFxuXHQnYXVkaW8vYWlmZicsXG5cdCdhcHBsaWNhdGlvbi94bWwnLFxuXHQnYXBwbGljYXRpb24veC1tb2JpcG9ja2V0LWVib29rJyxcblx0J2ltYWdlL2hlaWYnLFxuXHQnaW1hZ2UvaGVpZi1zZXF1ZW5jZScsXG5cdCdpbWFnZS9oZWljJyxcblx0J2ltYWdlL2hlaWMtc2VxdWVuY2UnLFxuXHQnaW1hZ2UvaWNucycsXG5cdCdpbWFnZS9rdHgnLFxuXHQnYXBwbGljYXRpb24vZGljb20nLFxuXHQnYXVkaW8veC1tdXNlcGFjaycsXG5cdCd0ZXh0L2NhbGVuZGFyJyxcblx0J3RleHQvdmNhcmQnLFxuXHQnbW9kZWwvZ2x0Zi1iaW5hcnknLFxuXHQnYXBwbGljYXRpb24vdm5kLnRjcGR1bXAucGNhcCcsXG5cdCdhdWRpby94LWRzZicsIC8vIE5vbi1zdGFuZGFyZFxuXHQnYXBwbGljYXRpb24veC5tcy5zaG9ydGN1dCcsIC8vIEludmVudGVkIGJ5IHVzXG5cdCdhcHBsaWNhdGlvbi94LmFwcGxlLmFsaWFzJywgLy8gSW52ZW50ZWQgYnkgdXNcblx0J2F1ZGlvL3gtdm9jJyxcblx0J2F1ZGlvL3ZuZC5kb2xieS5kZC1yYXcnLFxuXHQnYXVkaW8veC1tNGEnLFxuXHQnaW1hZ2UvYXBuZycsXG5cdCdpbWFnZS94LW9seW1wdXMtb3JmJyxcblx0J2ltYWdlL3gtc29ueS1hcncnLFxuXHQnaW1hZ2UveC1hZG9iZS1kbmcnLFxuXHQnaW1hZ2UveC1uaWtvbi1uZWYnLFxuXHQnaW1hZ2UveC1wYW5hc29uaWMtcncyJyxcblx0J2ltYWdlL3gtZnVqaWZpbG0tcmFmJyxcblx0J3ZpZGVvL3gtbTR2Jyxcblx0J3ZpZGVvLzNncHAyJyxcblx0J2FwcGxpY2F0aW9uL3gtZXNyaS1zaGFwZScsXG5cdCdhdWRpby9hYWMnLFxuXHQnYXVkaW8veC1pdCcsXG5cdCdhdWRpby94LXMzbScsXG5cdCdhdWRpby94LXhtJyxcblx0J3ZpZGVvL01QMVMnLFxuXHQndmlkZW8vTVAyUCcsXG5cdCdhcHBsaWNhdGlvbi92bmQuc2tldGNodXAuc2twJyxcblx0J2ltYWdlL2F2aWYnLFxuXHQnYXBwbGljYXRpb24veC1semgtY29tcHJlc3NlZCcsXG5cdCdhcHBsaWNhdGlvbi9wZ3AtZW5jcnlwdGVkJyxcblx0J2FwcGxpY2F0aW9uL3gtYXNhcicsXG5cdCdtb2RlbC9zdGwnLFxuXHQnYXBwbGljYXRpb24vdm5kLm1zLWh0bWxoZWxwJyxcblx0J21vZGVsLzNtZicsXG5cdCdpbWFnZS9qeGwnLFxuXHQnYXBwbGljYXRpb24venN0ZCcsXG5cdCdpbWFnZS9qbHMnLFxuXHQnYXBwbGljYXRpb24vdm5kLm1zLW91dGxvb2snLFxuXHQnaW1hZ2Uvdm5kLmR3ZycsXG5cdCdhcHBsaWNhdGlvbi94LXBhcnF1ZXQnLFxuXHQnYXBwbGljYXRpb24vamF2YS12bScsXG5cdCdhcHBsaWNhdGlvbi94LWFyaicsXG5cdCdhcHBsaWNhdGlvbi94LWNwaW8nLFxuXHQnYXBwbGljYXRpb24veC1hY2UtY29tcHJlc3NlZCcsXG5cdCdhcHBsaWNhdGlvbi9hdnJvJyxcbl07XG4iLCJpbXBvcnQge0J1ZmZlcn0gZnJvbSAnbm9kZTpidWZmZXInO1xuaW1wb3J0ICogYXMgVG9rZW4gZnJvbSAndG9rZW4tdHlwZXMnO1xuaW1wb3J0ICogYXMgc3RydG9rMyBmcm9tICdzdHJ0b2szL2NvcmUnOyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIG4vZmlsZS1leHRlbnNpb24taW4taW1wb3J0XG5pbXBvcnQge1xuXHRzdHJpbmdUb0J5dGVzLFxuXHR0YXJIZWFkZXJDaGVja3N1bU1hdGNoZXMsXG5cdHVpbnQzMlN5bmNTYWZlVG9rZW4sXG59IGZyb20gJy4vdXRpbC5qcyc7XG5pbXBvcnQge2V4dGVuc2lvbnMsIG1pbWVUeXBlc30gZnJvbSAnLi9zdXBwb3J0ZWQuanMnO1xuXG5jb25zdCBtaW5pbXVtQnl0ZXMgPSA0MTAwOyAvLyBBIGZhaXIgYW1vdW50IG9mIGZpbGUtdHlwZXMgYXJlIGRldGVjdGFibGUgd2l0aGluIHRoaXMgcmFuZ2UuXG5cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBmaWxlVHlwZUZyb21TdHJlYW0oc3RyZWFtKSB7XG5cdGNvbnN0IHRva2VuaXplciA9IGF3YWl0IHN0cnRvazMuZnJvbVN0cmVhbShzdHJlYW0pO1xuXHR0cnkge1xuXHRcdHJldHVybiBhd2FpdCBmaWxlVHlwZUZyb21Ub2tlbml6ZXIodG9rZW5pemVyKTtcblx0fSBmaW5hbGx5IHtcblx0XHRhd2FpdCB0b2tlbml6ZXIuY2xvc2UoKTtcblx0fVxufVxuXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gZmlsZVR5cGVGcm9tQnVmZmVyKGlucHV0KSB7XG5cdGlmICghKGlucHV0IGluc3RhbmNlb2YgVWludDhBcnJheSB8fCBpbnB1dCBpbnN0YW5jZW9mIEFycmF5QnVmZmVyKSkge1xuXHRcdHRocm93IG5ldyBUeXBlRXJyb3IoYEV4cGVjdGVkIHRoZSBcXGBpbnB1dFxcYCBhcmd1bWVudCB0byBiZSBvZiB0eXBlIFxcYFVpbnQ4QXJyYXlcXGAgb3IgXFxgQnVmZmVyXFxgIG9yIFxcYEFycmF5QnVmZmVyXFxgLCBnb3QgXFxgJHt0eXBlb2YgaW5wdXR9XFxgYCk7XG5cdH1cblxuXHRjb25zdCBidWZmZXIgPSBpbnB1dCBpbnN0YW5jZW9mIFVpbnQ4QXJyYXkgPyBpbnB1dCA6IG5ldyBVaW50OEFycmF5KGlucHV0KTtcblxuXHRpZiAoIShidWZmZXI/Lmxlbmd0aCA+IDEpKSB7XG5cdFx0cmV0dXJuO1xuXHR9XG5cblx0cmV0dXJuIGZpbGVUeXBlRnJvbVRva2VuaXplcihzdHJ0b2szLmZyb21CdWZmZXIoYnVmZmVyKSk7XG59XG5cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBmaWxlVHlwZUZyb21CbG9iKGJsb2IpIHtcblx0Y29uc3QgYnVmZmVyID0gYXdhaXQgYmxvYi5hcnJheUJ1ZmZlcigpO1xuXHRyZXR1cm4gZmlsZVR5cGVGcm9tQnVmZmVyKG5ldyBVaW50OEFycmF5KGJ1ZmZlcikpO1xufVxuXG5mdW5jdGlvbiBfY2hlY2soYnVmZmVyLCBoZWFkZXJzLCBvcHRpb25zKSB7XG5cdG9wdGlvbnMgPSB7XG5cdFx0b2Zmc2V0OiAwLFxuXHRcdC4uLm9wdGlvbnMsXG5cdH07XG5cblx0Zm9yIChjb25zdCBbaW5kZXgsIGhlYWRlcl0gb2YgaGVhZGVycy5lbnRyaWVzKCkpIHtcblx0XHQvLyBJZiBhIGJpdG1hc2sgaXMgc2V0XG5cdFx0aWYgKG9wdGlvbnMubWFzaykge1xuXHRcdFx0Ly8gSWYgaGVhZGVyIGRvZXNuJ3QgZXF1YWwgYGJ1ZmAgd2l0aCBiaXRzIG1hc2tlZCBvZmZcblx0XHRcdGlmIChoZWFkZXIgIT09IChvcHRpb25zLm1hc2tbaW5kZXhdICYgYnVmZmVyW2luZGV4ICsgb3B0aW9ucy5vZmZzZXRdKSkge1xuXHRcdFx0XHRyZXR1cm4gZmFsc2U7XG5cdFx0XHR9XG5cdFx0fSBlbHNlIGlmIChoZWFkZXIgIT09IGJ1ZmZlcltpbmRleCArIG9wdGlvbnMub2Zmc2V0XSkge1xuXHRcdFx0cmV0dXJuIGZhbHNlO1xuXHRcdH1cblx0fVxuXG5cdHJldHVybiB0cnVlO1xufVxuXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gZmlsZVR5cGVGcm9tVG9rZW5pemVyKHRva2VuaXplcikge1xuXHR0cnkge1xuXHRcdHJldHVybiBuZXcgRmlsZVR5cGVQYXJzZXIoKS5wYXJzZSh0b2tlbml6ZXIpO1xuXHR9IGNhdGNoIChlcnJvcikge1xuXHRcdGlmICghKGVycm9yIGluc3RhbmNlb2Ygc3RydG9rMy5FbmRPZlN0cmVhbUVycm9yKSkge1xuXHRcdFx0dGhyb3cgZXJyb3I7XG5cdFx0fVxuXHR9XG59XG5cbmNsYXNzIEZpbGVUeXBlUGFyc2VyIHtcblx0Y2hlY2soaGVhZGVyLCBvcHRpb25zKSB7XG5cdFx0cmV0dXJuIF9jaGVjayh0aGlzLmJ1ZmZlciwgaGVhZGVyLCBvcHRpb25zKTtcblx0fVxuXG5cdGNoZWNrU3RyaW5nKGhlYWRlciwgb3B0aW9ucykge1xuXHRcdHJldHVybiB0aGlzLmNoZWNrKHN0cmluZ1RvQnl0ZXMoaGVhZGVyKSwgb3B0aW9ucyk7XG5cdH1cblxuXHRhc3luYyBwYXJzZSh0b2tlbml6ZXIpIHtcblx0XHR0aGlzLmJ1ZmZlciA9IEJ1ZmZlci5hbGxvYyhtaW5pbXVtQnl0ZXMpO1xuXG5cdFx0Ly8gS2VlcCByZWFkaW5nIHVudGlsIEVPRiBpZiB0aGUgZmlsZSBzaXplIGlzIHVua25vd24uXG5cdFx0aWYgKHRva2VuaXplci5maWxlSW5mby5zaXplID09PSB1bmRlZmluZWQpIHtcblx0XHRcdHRva2VuaXplci5maWxlSW5mby5zaXplID0gTnVtYmVyLk1BWF9TQUZFX0lOVEVHRVI7XG5cdFx0fVxuXG5cdFx0dGhpcy50b2tlbml6ZXIgPSB0b2tlbml6ZXI7XG5cblx0XHRhd2FpdCB0b2tlbml6ZXIucGVla0J1ZmZlcih0aGlzLmJ1ZmZlciwge2xlbmd0aDogMTIsIG1heUJlTGVzczogdHJ1ZX0pO1xuXG5cdFx0Ly8gLS0gMi1ieXRlIHNpZ25hdHVyZXMgLS1cblxuXHRcdGlmICh0aGlzLmNoZWNrKFsweDQyLCAweDREXSkpIHtcblx0XHRcdHJldHVybiB7XG5cdFx0XHRcdGV4dDogJ2JtcCcsXG5cdFx0XHRcdG1pbWU6ICdpbWFnZS9ibXAnLFxuXHRcdFx0fTtcblx0XHR9XG5cblx0XHRpZiAodGhpcy5jaGVjayhbMHgwQiwgMHg3N10pKSB7XG5cdFx0XHRyZXR1cm4ge1xuXHRcdFx0XHRleHQ6ICdhYzMnLFxuXHRcdFx0XHRtaW1lOiAnYXVkaW8vdm5kLmRvbGJ5LmRkLXJhdycsXG5cdFx0XHR9O1xuXHRcdH1cblxuXHRcdGlmICh0aGlzLmNoZWNrKFsweDc4LCAweDAxXSkpIHtcblx0XHRcdHJldHVybiB7XG5cdFx0XHRcdGV4dDogJ2RtZycsXG5cdFx0XHRcdG1pbWU6ICdhcHBsaWNhdGlvbi94LWFwcGxlLWRpc2tpbWFnZScsXG5cdFx0XHR9O1xuXHRcdH1cblxuXHRcdGlmICh0aGlzLmNoZWNrKFsweDRELCAweDVBXSkpIHtcblx0XHRcdHJldHVybiB7XG5cdFx0XHRcdGV4dDogJ2V4ZScsXG5cdFx0XHRcdG1pbWU6ICdhcHBsaWNhdGlvbi94LW1zZG93bmxvYWQnLFxuXHRcdFx0fTtcblx0XHR9XG5cblx0XHRpZiAodGhpcy5jaGVjayhbMHgyNSwgMHgyMV0pKSB7XG5cdFx0XHRhd2FpdCB0b2tlbml6ZXIucGVla0J1ZmZlcih0aGlzLmJ1ZmZlciwge2xlbmd0aDogMjQsIG1heUJlTGVzczogdHJ1ZX0pO1xuXG5cdFx0XHRpZiAoXG5cdFx0XHRcdHRoaXMuY2hlY2tTdHJpbmcoJ1BTLUFkb2JlLScsIHtvZmZzZXQ6IDJ9KVxuXHRcdFx0XHQmJiB0aGlzLmNoZWNrU3RyaW5nKCcgRVBTRi0nLCB7b2Zmc2V0OiAxNH0pXG5cdFx0XHQpIHtcblx0XHRcdFx0cmV0dXJuIHtcblx0XHRcdFx0XHRleHQ6ICdlcHMnLFxuXHRcdFx0XHRcdG1pbWU6ICdhcHBsaWNhdGlvbi9lcHMnLFxuXHRcdFx0XHR9O1xuXHRcdFx0fVxuXG5cdFx0XHRyZXR1cm4ge1xuXHRcdFx0XHRleHQ6ICdwcycsXG5cdFx0XHRcdG1pbWU6ICdhcHBsaWNhdGlvbi9wb3N0c2NyaXB0Jyxcblx0XHRcdH07XG5cdFx0fVxuXG5cdFx0aWYgKFxuXHRcdFx0dGhpcy5jaGVjayhbMHgxRiwgMHhBMF0pXG5cdFx0XHR8fCB0aGlzLmNoZWNrKFsweDFGLCAweDlEXSlcblx0XHQpIHtcblx0XHRcdHJldHVybiB7XG5cdFx0XHRcdGV4dDogJ1onLFxuXHRcdFx0XHRtaW1lOiAnYXBwbGljYXRpb24veC1jb21wcmVzcycsXG5cdFx0XHR9O1xuXHRcdH1cblxuXHRcdGlmICh0aGlzLmNoZWNrKFsweEM3LCAweDcxXSkpIHtcblx0XHRcdHJldHVybiB7XG5cdFx0XHRcdGV4dDogJ2NwaW8nLFxuXHRcdFx0XHRtaW1lOiAnYXBwbGljYXRpb24veC1jcGlvJyxcblx0XHRcdH07XG5cdFx0fVxuXG5cdFx0aWYgKHRoaXMuY2hlY2soWzB4NjAsIDB4RUFdKSkge1xuXHRcdFx0cmV0dXJuIHtcblx0XHRcdFx0ZXh0OiAnYXJqJyxcblx0XHRcdFx0bWltZTogJ2FwcGxpY2F0aW9uL3gtYXJqJyxcblx0XHRcdH07XG5cdFx0fVxuXG5cdFx0Ly8gLS0gMy1ieXRlIHNpZ25hdHVyZXMgLS1cblxuXHRcdGlmICh0aGlzLmNoZWNrKFsweEVGLCAweEJCLCAweEJGXSkpIHsgLy8gVVRGLTgtQk9NXG5cdFx0XHQvLyBTdHJpcCBvZmYgVVRGLTgtQk9NXG5cdFx0XHR0aGlzLnRva2VuaXplci5pZ25vcmUoMyk7XG5cdFx0XHRyZXR1cm4gdGhpcy5wYXJzZSh0b2tlbml6ZXIpO1xuXHRcdH1cblxuXHRcdGlmICh0aGlzLmNoZWNrKFsweDQ3LCAweDQ5LCAweDQ2XSkpIHtcblx0XHRcdHJldHVybiB7XG5cdFx0XHRcdGV4dDogJ2dpZicsXG5cdFx0XHRcdG1pbWU6ICdpbWFnZS9naWYnLFxuXHRcdFx0fTtcblx0XHR9XG5cblx0XHRpZiAodGhpcy5jaGVjayhbMHg0OSwgMHg0OSwgMHhCQ10pKSB7XG5cdFx0XHRyZXR1cm4ge1xuXHRcdFx0XHRleHQ6ICdqeHInLFxuXHRcdFx0XHRtaW1lOiAnaW1hZ2Uvdm5kLm1zLXBob3RvJyxcblx0XHRcdH07XG5cdFx0fVxuXG5cdFx0aWYgKHRoaXMuY2hlY2soWzB4MUYsIDB4OEIsIDB4OF0pKSB7XG5cdFx0XHRyZXR1cm4ge1xuXHRcdFx0XHRleHQ6ICdneicsXG5cdFx0XHRcdG1pbWU6ICdhcHBsaWNhdGlvbi9nemlwJyxcblx0XHRcdH07XG5cdFx0fVxuXG5cdFx0aWYgKHRoaXMuY2hlY2soWzB4NDIsIDB4NUEsIDB4NjhdKSkge1xuXHRcdFx0cmV0dXJuIHtcblx0XHRcdFx0ZXh0OiAnYnoyJyxcblx0XHRcdFx0bWltZTogJ2FwcGxpY2F0aW9uL3gtYnppcDInLFxuXHRcdFx0fTtcblx0XHR9XG5cblx0XHRpZiAodGhpcy5jaGVja1N0cmluZygnSUQzJykpIHtcblx0XHRcdGF3YWl0IHRva2VuaXplci5pZ25vcmUoNik7IC8vIFNraXAgSUQzIGhlYWRlciB1bnRpbCB0aGUgaGVhZGVyIHNpemVcblx0XHRcdGNvbnN0IGlkM0hlYWRlckxlbmd0aCA9IGF3YWl0IHRva2VuaXplci5yZWFkVG9rZW4odWludDMyU3luY1NhZmVUb2tlbik7XG5cdFx0XHRpZiAodG9rZW5pemVyLnBvc2l0aW9uICsgaWQzSGVhZGVyTGVuZ3RoID4gdG9rZW5pemVyLmZpbGVJbmZvLnNpemUpIHtcblx0XHRcdFx0Ly8gR3Vlc3MgZmlsZSB0eXBlIGJhc2VkIG9uIElEMyBoZWFkZXIgZm9yIGJhY2t3YXJkIGNvbXBhdGliaWxpdHlcblx0XHRcdFx0cmV0dXJuIHtcblx0XHRcdFx0XHRleHQ6ICdtcDMnLFxuXHRcdFx0XHRcdG1pbWU6ICdhdWRpby9tcGVnJyxcblx0XHRcdFx0fTtcblx0XHRcdH1cblxuXHRcdFx0YXdhaXQgdG9rZW5pemVyLmlnbm9yZShpZDNIZWFkZXJMZW5ndGgpO1xuXHRcdFx0cmV0dXJuIGZpbGVUeXBlRnJvbVRva2VuaXplcih0b2tlbml6ZXIpOyAvLyBTa2lwIElEMyBoZWFkZXIsIHJlY3Vyc2lvblxuXHRcdH1cblxuXHRcdC8vIE11c2VwYWNrLCBTVjdcblx0XHRpZiAodGhpcy5jaGVja1N0cmluZygnTVArJykpIHtcblx0XHRcdHJldHVybiB7XG5cdFx0XHRcdGV4dDogJ21wYycsXG5cdFx0XHRcdG1pbWU6ICdhdWRpby94LW11c2VwYWNrJyxcblx0XHRcdH07XG5cdFx0fVxuXG5cdFx0aWYgKFxuXHRcdFx0KHRoaXMuYnVmZmVyWzBdID09PSAweDQzIHx8IHRoaXMuYnVmZmVyWzBdID09PSAweDQ2KVxuXHRcdFx0JiYgdGhpcy5jaGVjayhbMHg1NywgMHg1M10sIHtvZmZzZXQ6IDF9KVxuXHRcdCkge1xuXHRcdFx0cmV0dXJuIHtcblx0XHRcdFx0ZXh0OiAnc3dmJyxcblx0XHRcdFx0bWltZTogJ2FwcGxpY2F0aW9uL3gtc2hvY2t3YXZlLWZsYXNoJyxcblx0XHRcdH07XG5cdFx0fVxuXG5cdFx0Ly8gLS0gNC1ieXRlIHNpZ25hdHVyZXMgLS1cblxuXHRcdC8vIFJlcXVpcmVzIGEgc2FtcGxlIHNpemUgb2YgNCBieXRlc1xuXHRcdGlmICh0aGlzLmNoZWNrKFsweEZGLCAweEQ4LCAweEZGXSkpIHtcblx0XHRcdGlmICh0aGlzLmNoZWNrKFsweEY3XSwge29mZnNldDogM30pKSB7IC8vIEpQRzcvU09GNTUsIGluZGljYXRpbmcgYSBJU08vSUVDIDE0NDk1IC8gSlBFRy1MUyBmaWxlXG5cdFx0XHRcdHJldHVybiB7XG5cdFx0XHRcdFx0ZXh0OiAnamxzJyxcblx0XHRcdFx0XHRtaW1lOiAnaW1hZ2UvamxzJyxcblx0XHRcdFx0fTtcblx0XHRcdH1cblxuXHRcdFx0cmV0dXJuIHtcblx0XHRcdFx0ZXh0OiAnanBnJyxcblx0XHRcdFx0bWltZTogJ2ltYWdlL2pwZWcnLFxuXHRcdFx0fTtcblx0XHR9XG5cblx0XHRpZiAodGhpcy5jaGVjayhbMHg0RiwgMHg2MiwgMHg2QSwgMHgwMV0pKSB7XG5cdFx0XHRyZXR1cm4ge1xuXHRcdFx0XHRleHQ6ICdhdnJvJyxcblx0XHRcdFx0bWltZTogJ2FwcGxpY2F0aW9uL2F2cm8nLFxuXHRcdFx0fTtcblx0XHR9XG5cblx0XHRpZiAodGhpcy5jaGVja1N0cmluZygnRkxJRicpKSB7XG5cdFx0XHRyZXR1cm4ge1xuXHRcdFx0XHRleHQ6ICdmbGlmJyxcblx0XHRcdFx0bWltZTogJ2ltYWdlL2ZsaWYnLFxuXHRcdFx0fTtcblx0XHR9XG5cblx0XHRpZiAodGhpcy5jaGVja1N0cmluZygnOEJQUycpKSB7XG5cdFx0XHRyZXR1cm4ge1xuXHRcdFx0XHRleHQ6ICdwc2QnLFxuXHRcdFx0XHRtaW1lOiAnaW1hZ2Uvdm5kLmFkb2JlLnBob3Rvc2hvcCcsXG5cdFx0XHR9O1xuXHRcdH1cblxuXHRcdGlmICh0aGlzLmNoZWNrU3RyaW5nKCdXRUJQJywge29mZnNldDogOH0pKSB7XG5cdFx0XHRyZXR1cm4ge1xuXHRcdFx0XHRleHQ6ICd3ZWJwJyxcblx0XHRcdFx0bWltZTogJ2ltYWdlL3dlYnAnLFxuXHRcdFx0fTtcblx0XHR9XG5cblx0XHQvLyBNdXNlcGFjaywgU1Y4XG5cdFx0aWYgKHRoaXMuY2hlY2tTdHJpbmcoJ01QQ0snKSkge1xuXHRcdFx0cmV0dXJuIHtcblx0XHRcdFx0ZXh0OiAnbXBjJyxcblx0XHRcdFx0bWltZTogJ2F1ZGlvL3gtbXVzZXBhY2snLFxuXHRcdFx0fTtcblx0XHR9XG5cblx0XHRpZiAodGhpcy5jaGVja1N0cmluZygnRk9STScpKSB7XG5cdFx0XHRyZXR1cm4ge1xuXHRcdFx0XHRleHQ6ICdhaWYnLFxuXHRcdFx0XHRtaW1lOiAnYXVkaW8vYWlmZicsXG5cdFx0XHR9O1xuXHRcdH1cblxuXHRcdGlmICh0aGlzLmNoZWNrU3RyaW5nKCdpY25zJywge29mZnNldDogMH0pKSB7XG5cdFx0XHRyZXR1cm4ge1xuXHRcdFx0XHRleHQ6ICdpY25zJyxcblx0XHRcdFx0bWltZTogJ2ltYWdlL2ljbnMnLFxuXHRcdFx0fTtcblx0XHR9XG5cblx0XHQvLyBaaXAtYmFzZWQgZmlsZSBmb3JtYXRzXG5cdFx0Ly8gTmVlZCB0byBiZSBiZWZvcmUgdGhlIGB6aXBgIGNoZWNrXG5cdFx0aWYgKHRoaXMuY2hlY2soWzB4NTAsIDB4NEIsIDB4MywgMHg0XSkpIHsgLy8gTG9jYWwgZmlsZSBoZWFkZXIgc2lnbmF0dXJlXG5cdFx0XHR0cnkge1xuXHRcdFx0XHR3aGlsZSAodG9rZW5pemVyLnBvc2l0aW9uICsgMzAgPCB0b2tlbml6ZXIuZmlsZUluZm8uc2l6ZSkge1xuXHRcdFx0XHRcdGF3YWl0IHRva2VuaXplci5yZWFkQnVmZmVyKHRoaXMuYnVmZmVyLCB7bGVuZ3RoOiAzMH0pO1xuXG5cdFx0XHRcdFx0Ly8gaHR0cHM6Ly9lbi53aWtpcGVkaWEub3JnL3dpa2kvWmlwXyhmaWxlX2Zvcm1hdCkjRmlsZV9oZWFkZXJzXG5cdFx0XHRcdFx0Y29uc3QgemlwSGVhZGVyID0ge1xuXHRcdFx0XHRcdFx0Y29tcHJlc3NlZFNpemU6IHRoaXMuYnVmZmVyLnJlYWRVSW50MzJMRSgxOCksXG5cdFx0XHRcdFx0XHR1bmNvbXByZXNzZWRTaXplOiB0aGlzLmJ1ZmZlci5yZWFkVUludDMyTEUoMjIpLFxuXHRcdFx0XHRcdFx0ZmlsZW5hbWVMZW5ndGg6IHRoaXMuYnVmZmVyLnJlYWRVSW50MTZMRSgyNiksXG5cdFx0XHRcdFx0XHRleHRyYUZpZWxkTGVuZ3RoOiB0aGlzLmJ1ZmZlci5yZWFkVUludDE2TEUoMjgpLFxuXHRcdFx0XHRcdH07XG5cblx0XHRcdFx0XHR6aXBIZWFkZXIuZmlsZW5hbWUgPSBhd2FpdCB0b2tlbml6ZXIucmVhZFRva2VuKG5ldyBUb2tlbi5TdHJpbmdUeXBlKHppcEhlYWRlci5maWxlbmFtZUxlbmd0aCwgJ3V0Zi04JykpO1xuXHRcdFx0XHRcdGF3YWl0IHRva2VuaXplci5pZ25vcmUoemlwSGVhZGVyLmV4dHJhRmllbGRMZW5ndGgpO1xuXG5cdFx0XHRcdFx0Ly8gQXNzdW1lcyBzaWduZWQgYC54cGlgIGZyb20gYWRkb25zLm1vemlsbGEub3JnXG5cdFx0XHRcdFx0aWYgKHppcEhlYWRlci5maWxlbmFtZSA9PT0gJ01FVEEtSU5GL21vemlsbGEucnNhJykge1xuXHRcdFx0XHRcdFx0cmV0dXJuIHtcblx0XHRcdFx0XHRcdFx0ZXh0OiAneHBpJyxcblx0XHRcdFx0XHRcdFx0bWltZTogJ2FwcGxpY2F0aW9uL3gteHBpbnN0YWxsJyxcblx0XHRcdFx0XHRcdH07XG5cdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0aWYgKHppcEhlYWRlci5maWxlbmFtZS5lbmRzV2l0aCgnLnJlbHMnKSB8fCB6aXBIZWFkZXIuZmlsZW5hbWUuZW5kc1dpdGgoJy54bWwnKSkge1xuXHRcdFx0XHRcdFx0Y29uc3QgdHlwZSA9IHppcEhlYWRlci5maWxlbmFtZS5zcGxpdCgnLycpWzBdO1xuXHRcdFx0XHRcdFx0c3dpdGNoICh0eXBlKSB7XG5cdFx0XHRcdFx0XHRcdGNhc2UgJ19yZWxzJzpcblx0XHRcdFx0XHRcdFx0XHRicmVhaztcblx0XHRcdFx0XHRcdFx0Y2FzZSAnd29yZCc6XG5cdFx0XHRcdFx0XHRcdFx0cmV0dXJuIHtcblx0XHRcdFx0XHRcdFx0XHRcdGV4dDogJ2RvY3gnLFxuXHRcdFx0XHRcdFx0XHRcdFx0bWltZTogJ2FwcGxpY2F0aW9uL3ZuZC5vcGVueG1sZm9ybWF0cy1vZmZpY2Vkb2N1bWVudC53b3JkcHJvY2Vzc2luZ21sLmRvY3VtZW50Jyxcblx0XHRcdFx0XHRcdFx0XHR9O1xuXHRcdFx0XHRcdFx0XHRjYXNlICdwcHQnOlxuXHRcdFx0XHRcdFx0XHRcdHJldHVybiB7XG5cdFx0XHRcdFx0XHRcdFx0XHRleHQ6ICdwcHR4Jyxcblx0XHRcdFx0XHRcdFx0XHRcdG1pbWU6ICdhcHBsaWNhdGlvbi92bmQub3BlbnhtbGZvcm1hdHMtb2ZmaWNlZG9jdW1lbnQucHJlc2VudGF0aW9ubWwucHJlc2VudGF0aW9uJyxcblx0XHRcdFx0XHRcdFx0XHR9O1xuXHRcdFx0XHRcdFx0XHRjYXNlICd4bCc6XG5cdFx0XHRcdFx0XHRcdFx0cmV0dXJuIHtcblx0XHRcdFx0XHRcdFx0XHRcdGV4dDogJ3hsc3gnLFxuXHRcdFx0XHRcdFx0XHRcdFx0bWltZTogJ2FwcGxpY2F0aW9uL3ZuZC5vcGVueG1sZm9ybWF0cy1vZmZpY2Vkb2N1bWVudC5zcHJlYWRzaGVldG1sLnNoZWV0Jyxcblx0XHRcdFx0XHRcdFx0XHR9O1xuXHRcdFx0XHRcdFx0XHRkZWZhdWx0OlxuXHRcdFx0XHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdGlmICh6aXBIZWFkZXIuZmlsZW5hbWUuc3RhcnRzV2l0aCgneGwvJykpIHtcblx0XHRcdFx0XHRcdHJldHVybiB7XG5cdFx0XHRcdFx0XHRcdGV4dDogJ3hsc3gnLFxuXHRcdFx0XHRcdFx0XHRtaW1lOiAnYXBwbGljYXRpb24vdm5kLm9wZW54bWxmb3JtYXRzLW9mZmljZWRvY3VtZW50LnNwcmVhZHNoZWV0bWwuc2hlZXQnLFxuXHRcdFx0XHRcdFx0fTtcblx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHRpZiAoemlwSGVhZGVyLmZpbGVuYW1lLnN0YXJ0c1dpdGgoJzNELycpICYmIHppcEhlYWRlci5maWxlbmFtZS5lbmRzV2l0aCgnLm1vZGVsJykpIHtcblx0XHRcdFx0XHRcdHJldHVybiB7XG5cdFx0XHRcdFx0XHRcdGV4dDogJzNtZicsXG5cdFx0XHRcdFx0XHRcdG1pbWU6ICdtb2RlbC8zbWYnLFxuXHRcdFx0XHRcdFx0fTtcblx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHQvLyBUaGUgZG9jeCwgeGxzeCBhbmQgcHB0eCBmaWxlIHR5cGVzIGV4dGVuZCB0aGUgT2ZmaWNlIE9wZW4gWE1MIGZpbGUgZm9ybWF0OlxuXHRcdFx0XHRcdC8vIGh0dHBzOi8vZW4ud2lraXBlZGlhLm9yZy93aWtpL09mZmljZV9PcGVuX1hNTF9maWxlX2Zvcm1hdHNcblx0XHRcdFx0XHQvLyBXZSBsb29rIGZvcjpcblx0XHRcdFx0XHQvLyAtIG9uZSBlbnRyeSBuYW1lZCAnW0NvbnRlbnRfVHlwZXNdLnhtbCcgb3IgJ19yZWxzLy5yZWxzJyxcblx0XHRcdFx0XHQvLyAtIG9uZSBlbnRyeSBpbmRpY2F0aW5nIHNwZWNpZmljIHR5cGUgb2YgZmlsZS5cblx0XHRcdFx0XHQvLyBNUyBPZmZpY2UsIE9wZW5PZmZpY2UgYW5kIExpYnJlT2ZmaWNlIG1heSBwdXQgdGhlIHBhcnRzIGluIGRpZmZlcmVudCBvcmRlciwgc28gdGhlIGNoZWNrIHNob3VsZCBub3QgcmVseSBvbiBpdC5cblx0XHRcdFx0XHRpZiAoemlwSGVhZGVyLmZpbGVuYW1lID09PSAnbWltZXR5cGUnICYmIHppcEhlYWRlci5jb21wcmVzc2VkU2l6ZSA9PT0gemlwSGVhZGVyLnVuY29tcHJlc3NlZFNpemUpIHtcblx0XHRcdFx0XHRcdGxldCBtaW1lVHlwZSA9IGF3YWl0IHRva2VuaXplci5yZWFkVG9rZW4obmV3IFRva2VuLlN0cmluZ1R5cGUoemlwSGVhZGVyLmNvbXByZXNzZWRTaXplLCAndXRmLTgnKSk7XG5cdFx0XHRcdFx0XHRtaW1lVHlwZSA9IG1pbWVUeXBlLnRyaW0oKTtcblxuXHRcdFx0XHRcdFx0c3dpdGNoIChtaW1lVHlwZSkge1xuXHRcdFx0XHRcdFx0XHRjYXNlICdhcHBsaWNhdGlvbi9lcHViK3ppcCc6XG5cdFx0XHRcdFx0XHRcdFx0cmV0dXJuIHtcblx0XHRcdFx0XHRcdFx0XHRcdGV4dDogJ2VwdWInLFxuXHRcdFx0XHRcdFx0XHRcdFx0bWltZTogJ2FwcGxpY2F0aW9uL2VwdWIremlwJyxcblx0XHRcdFx0XHRcdFx0XHR9O1xuXHRcdFx0XHRcdFx0XHRjYXNlICdhcHBsaWNhdGlvbi92bmQub2FzaXMub3BlbmRvY3VtZW50LnRleHQnOlxuXHRcdFx0XHRcdFx0XHRcdHJldHVybiB7XG5cdFx0XHRcdFx0XHRcdFx0XHRleHQ6ICdvZHQnLFxuXHRcdFx0XHRcdFx0XHRcdFx0bWltZTogJ2FwcGxpY2F0aW9uL3ZuZC5vYXNpcy5vcGVuZG9jdW1lbnQudGV4dCcsXG5cdFx0XHRcdFx0XHRcdFx0fTtcblx0XHRcdFx0XHRcdFx0Y2FzZSAnYXBwbGljYXRpb24vdm5kLm9hc2lzLm9wZW5kb2N1bWVudC5zcHJlYWRzaGVldCc6XG5cdFx0XHRcdFx0XHRcdFx0cmV0dXJuIHtcblx0XHRcdFx0XHRcdFx0XHRcdGV4dDogJ29kcycsXG5cdFx0XHRcdFx0XHRcdFx0XHRtaW1lOiAnYXBwbGljYXRpb24vdm5kLm9hc2lzLm9wZW5kb2N1bWVudC5zcHJlYWRzaGVldCcsXG5cdFx0XHRcdFx0XHRcdFx0fTtcblx0XHRcdFx0XHRcdFx0Y2FzZSAnYXBwbGljYXRpb24vdm5kLm9hc2lzLm9wZW5kb2N1bWVudC5wcmVzZW50YXRpb24nOlxuXHRcdFx0XHRcdFx0XHRcdHJldHVybiB7XG5cdFx0XHRcdFx0XHRcdFx0XHRleHQ6ICdvZHAnLFxuXHRcdFx0XHRcdFx0XHRcdFx0bWltZTogJ2FwcGxpY2F0aW9uL3ZuZC5vYXNpcy5vcGVuZG9jdW1lbnQucHJlc2VudGF0aW9uJyxcblx0XHRcdFx0XHRcdFx0XHR9O1xuXHRcdFx0XHRcdFx0XHRkZWZhdWx0OlxuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdC8vIFRyeSB0byBmaW5kIG5leHQgaGVhZGVyIG1hbnVhbGx5IHdoZW4gY3VycmVudCBvbmUgaXMgY29ycnVwdGVkXG5cdFx0XHRcdFx0aWYgKHppcEhlYWRlci5jb21wcmVzc2VkU2l6ZSA9PT0gMCkge1xuXHRcdFx0XHRcdFx0bGV0IG5leHRIZWFkZXJJbmRleCA9IC0xO1xuXG5cdFx0XHRcdFx0XHR3aGlsZSAobmV4dEhlYWRlckluZGV4IDwgMCAmJiAodG9rZW5pemVyLnBvc2l0aW9uIDwgdG9rZW5pemVyLmZpbGVJbmZvLnNpemUpKSB7XG5cdFx0XHRcdFx0XHRcdGF3YWl0IHRva2VuaXplci5wZWVrQnVmZmVyKHRoaXMuYnVmZmVyLCB7bWF5QmVMZXNzOiB0cnVlfSk7XG5cblx0XHRcdFx0XHRcdFx0bmV4dEhlYWRlckluZGV4ID0gdGhpcy5idWZmZXIuaW5kZXhPZignNTA0QjAzMDQnLCAwLCAnaGV4Jyk7XG5cdFx0XHRcdFx0XHRcdC8vIE1vdmUgcG9zaXRpb24gdG8gdGhlIG5leHQgaGVhZGVyIGlmIGZvdW5kLCBza2lwIHRoZSB3aG9sZSBidWZmZXIgb3RoZXJ3aXNlXG5cdFx0XHRcdFx0XHRcdGF3YWl0IHRva2VuaXplci5pZ25vcmUobmV4dEhlYWRlckluZGV4ID49IDAgPyBuZXh0SGVhZGVySW5kZXggOiB0aGlzLmJ1ZmZlci5sZW5ndGgpO1xuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0XHRhd2FpdCB0b2tlbml6ZXIuaWdub3JlKHppcEhlYWRlci5jb21wcmVzc2VkU2l6ZSk7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cdFx0XHR9IGNhdGNoIChlcnJvcikge1xuXHRcdFx0XHRpZiAoIShlcnJvciBpbnN0YW5jZW9mIHN0cnRvazMuRW5kT2ZTdHJlYW1FcnJvcikpIHtcblx0XHRcdFx0XHR0aHJvdyBlcnJvcjtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXG5cdFx0XHRyZXR1cm4ge1xuXHRcdFx0XHRleHQ6ICd6aXAnLFxuXHRcdFx0XHRtaW1lOiAnYXBwbGljYXRpb24vemlwJyxcblx0XHRcdH07XG5cdFx0fVxuXG5cdFx0aWYgKHRoaXMuY2hlY2tTdHJpbmcoJ09nZ1MnKSkge1xuXHRcdFx0Ly8gVGhpcyBpcyBhbiBPR0cgY29udGFpbmVyXG5cdFx0XHRhd2FpdCB0b2tlbml6ZXIuaWdub3JlKDI4KTtcblx0XHRcdGNvbnN0IHR5cGUgPSBCdWZmZXIuYWxsb2MoOCk7XG5cdFx0XHRhd2FpdCB0b2tlbml6ZXIucmVhZEJ1ZmZlcih0eXBlKTtcblxuXHRcdFx0Ly8gTmVlZHMgdG8gYmUgYmVmb3JlIGBvZ2dgIGNoZWNrXG5cdFx0XHRpZiAoX2NoZWNrKHR5cGUsIFsweDRGLCAweDcwLCAweDc1LCAweDczLCAweDQ4LCAweDY1LCAweDYxLCAweDY0XSkpIHtcblx0XHRcdFx0cmV0dXJuIHtcblx0XHRcdFx0XHRleHQ6ICdvcHVzJyxcblx0XHRcdFx0XHRtaW1lOiAnYXVkaW8vb3B1cycsXG5cdFx0XHRcdH07XG5cdFx0XHR9XG5cblx0XHRcdC8vIElmICcgdGhlb3JhJyBpbiBoZWFkZXIuXG5cdFx0XHRpZiAoX2NoZWNrKHR5cGUsIFsweDgwLCAweDc0LCAweDY4LCAweDY1LCAweDZGLCAweDcyLCAweDYxXSkpIHtcblx0XHRcdFx0cmV0dXJuIHtcblx0XHRcdFx0XHRleHQ6ICdvZ3YnLFxuXHRcdFx0XHRcdG1pbWU6ICd2aWRlby9vZ2cnLFxuXHRcdFx0XHR9O1xuXHRcdFx0fVxuXG5cdFx0XHQvLyBJZiAnXFx4MDF2aWRlbycgaW4gaGVhZGVyLlxuXHRcdFx0aWYgKF9jaGVjayh0eXBlLCBbMHgwMSwgMHg3NiwgMHg2OSwgMHg2NCwgMHg2NSwgMHg2RiwgMHgwMF0pKSB7XG5cdFx0XHRcdHJldHVybiB7XG5cdFx0XHRcdFx0ZXh0OiAnb2dtJyxcblx0XHRcdFx0XHRtaW1lOiAndmlkZW8vb2dnJyxcblx0XHRcdFx0fTtcblx0XHRcdH1cblxuXHRcdFx0Ly8gSWYgJyBGTEFDJyBpbiBoZWFkZXIgIGh0dHBzOi8veGlwaC5vcmcvZmxhYy9mYXEuaHRtbFxuXHRcdFx0aWYgKF9jaGVjayh0eXBlLCBbMHg3RiwgMHg0NiwgMHg0QywgMHg0MSwgMHg0M10pKSB7XG5cdFx0XHRcdHJldHVybiB7XG5cdFx0XHRcdFx0ZXh0OiAnb2dhJyxcblx0XHRcdFx0XHRtaW1lOiAnYXVkaW8vb2dnJyxcblx0XHRcdFx0fTtcblx0XHRcdH1cblxuXHRcdFx0Ly8gJ1NwZWV4ICAnIGluIGhlYWRlciBodHRwczovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9TcGVleFxuXHRcdFx0aWYgKF9jaGVjayh0eXBlLCBbMHg1MywgMHg3MCwgMHg2NSwgMHg2NSwgMHg3OCwgMHgyMCwgMHgyMF0pKSB7XG5cdFx0XHRcdHJldHVybiB7XG5cdFx0XHRcdFx0ZXh0OiAnc3B4Jyxcblx0XHRcdFx0XHRtaW1lOiAnYXVkaW8vb2dnJyxcblx0XHRcdFx0fTtcblx0XHRcdH1cblxuXHRcdFx0Ly8gSWYgJ1xceDAxdm9yYmlzJyBpbiBoZWFkZXJcblx0XHRcdGlmIChfY2hlY2sodHlwZSwgWzB4MDEsIDB4NzYsIDB4NkYsIDB4NzIsIDB4NjIsIDB4NjksIDB4NzNdKSkge1xuXHRcdFx0XHRyZXR1cm4ge1xuXHRcdFx0XHRcdGV4dDogJ29nZycsXG5cdFx0XHRcdFx0bWltZTogJ2F1ZGlvL29nZycsXG5cdFx0XHRcdH07XG5cdFx0XHR9XG5cblx0XHRcdC8vIERlZmF1bHQgT0dHIGNvbnRhaW5lciBodHRwczovL3d3dy5pYW5hLm9yZy9hc3NpZ25tZW50cy9tZWRpYS10eXBlcy9hcHBsaWNhdGlvbi9vZ2dcblx0XHRcdHJldHVybiB7XG5cdFx0XHRcdGV4dDogJ29neCcsXG5cdFx0XHRcdG1pbWU6ICdhcHBsaWNhdGlvbi9vZ2cnLFxuXHRcdFx0fTtcblx0XHR9XG5cblx0XHRpZiAoXG5cdFx0XHR0aGlzLmNoZWNrKFsweDUwLCAweDRCXSlcblx0XHRcdCYmICh0aGlzLmJ1ZmZlclsyXSA9PT0gMHgzIHx8IHRoaXMuYnVmZmVyWzJdID09PSAweDUgfHwgdGhpcy5idWZmZXJbMl0gPT09IDB4Nylcblx0XHRcdCYmICh0aGlzLmJ1ZmZlclszXSA9PT0gMHg0IHx8IHRoaXMuYnVmZmVyWzNdID09PSAweDYgfHwgdGhpcy5idWZmZXJbM10gPT09IDB4OClcblx0XHQpIHtcblx0XHRcdHJldHVybiB7XG5cdFx0XHRcdGV4dDogJ3ppcCcsXG5cdFx0XHRcdG1pbWU6ICdhcHBsaWNhdGlvbi96aXAnLFxuXHRcdFx0fTtcblx0XHR9XG5cblx0XHQvL1xuXG5cdFx0Ly8gRmlsZSBUeXBlIEJveCAoaHR0cHM6Ly9lbi53aWtpcGVkaWEub3JnL3dpa2kvSVNPX2Jhc2VfbWVkaWFfZmlsZV9mb3JtYXQpXG5cdFx0Ly8gSXQncyBub3QgcmVxdWlyZWQgdG8gYmUgZmlyc3QsIGJ1dCBpdCdzIHJlY29tbWVuZGVkIHRvIGJlLiBBbG1vc3QgYWxsIElTTyBiYXNlIG1lZGlhIGZpbGVzIHN0YXJ0IHdpdGggYGZ0eXBgIGJveC5cblx0XHQvLyBgZnR5cGAgYm94IG11c3QgY29udGFpbiBhIGJyYW5kIG1ham9yIGlkZW50aWZpZXIsIHdoaWNoIG11c3QgY29uc2lzdCBvZiBJU08gODg1OS0xIHByaW50YWJsZSBjaGFyYWN0ZXJzLlxuXHRcdC8vIEhlcmUgd2UgY2hlY2sgZm9yIDg4NTktMSBwcmludGFibGUgY2hhcmFjdGVycyAoZm9yIHNpbXBsaWNpdHksIGl0J3MgYSBtYXNrIHdoaWNoIGFsc28gY2F0Y2hlcyBvbmUgbm9uLXByaW50YWJsZSBjaGFyYWN0ZXIpLlxuXHRcdGlmIChcblx0XHRcdHRoaXMuY2hlY2tTdHJpbmcoJ2Z0eXAnLCB7b2Zmc2V0OiA0fSlcblx0XHRcdCYmICh0aGlzLmJ1ZmZlcls4XSAmIDB4NjApICE9PSAweDAwIC8vIEJyYW5kIG1ham9yLCBmaXJzdCBjaGFyYWN0ZXIgQVNDSUk/XG5cdFx0KSB7XG5cdFx0XHQvLyBUaGV5IGFsbCBjYW4gaGF2ZSBNSU1FIGB2aWRlby9tcDRgIGV4Y2VwdCBgYXBwbGljYXRpb24vbXA0YCBzcGVjaWFsLWNhc2Ugd2hpY2ggaXMgaGFyZCB0byBkZXRlY3QuXG5cdFx0XHQvLyBGb3Igc29tZSBjYXNlcywgd2UncmUgc3BlY2lmaWMsIGV2ZXJ5dGhpbmcgZWxzZSBmYWxscyB0byBgdmlkZW8vbXA0YCB3aXRoIGBtcDRgIGV4dGVuc2lvbi5cblx0XHRcdGNvbnN0IGJyYW5kTWFqb3IgPSB0aGlzLmJ1ZmZlci50b1N0cmluZygnYmluYXJ5JywgOCwgMTIpLnJlcGxhY2UoJ1xcMCcsICcgJykudHJpbSgpO1xuXHRcdFx0c3dpdGNoIChicmFuZE1ham9yKSB7XG5cdFx0XHRcdGNhc2UgJ2F2aWYnOlxuXHRcdFx0XHRjYXNlICdhdmlzJzpcblx0XHRcdFx0XHRyZXR1cm4ge2V4dDogJ2F2aWYnLCBtaW1lOiAnaW1hZ2UvYXZpZid9O1xuXHRcdFx0XHRjYXNlICdtaWYxJzpcblx0XHRcdFx0XHRyZXR1cm4ge2V4dDogJ2hlaWMnLCBtaW1lOiAnaW1hZ2UvaGVpZid9O1xuXHRcdFx0XHRjYXNlICdtc2YxJzpcblx0XHRcdFx0XHRyZXR1cm4ge2V4dDogJ2hlaWMnLCBtaW1lOiAnaW1hZ2UvaGVpZi1zZXF1ZW5jZSd9O1xuXHRcdFx0XHRjYXNlICdoZWljJzpcblx0XHRcdFx0Y2FzZSAnaGVpeCc6XG5cdFx0XHRcdFx0cmV0dXJuIHtleHQ6ICdoZWljJywgbWltZTogJ2ltYWdlL2hlaWMnfTtcblx0XHRcdFx0Y2FzZSAnaGV2Yyc6XG5cdFx0XHRcdGNhc2UgJ2hldngnOlxuXHRcdFx0XHRcdHJldHVybiB7ZXh0OiAnaGVpYycsIG1pbWU6ICdpbWFnZS9oZWljLXNlcXVlbmNlJ307XG5cdFx0XHRcdGNhc2UgJ3F0Jzpcblx0XHRcdFx0XHRyZXR1cm4ge2V4dDogJ21vdicsIG1pbWU6ICd2aWRlby9xdWlja3RpbWUnfTtcblx0XHRcdFx0Y2FzZSAnTTRWJzpcblx0XHRcdFx0Y2FzZSAnTTRWSCc6XG5cdFx0XHRcdGNhc2UgJ000VlAnOlxuXHRcdFx0XHRcdHJldHVybiB7ZXh0OiAnbTR2JywgbWltZTogJ3ZpZGVvL3gtbTR2J307XG5cdFx0XHRcdGNhc2UgJ000UCc6XG5cdFx0XHRcdFx0cmV0dXJuIHtleHQ6ICdtNHAnLCBtaW1lOiAndmlkZW8vbXA0J307XG5cdFx0XHRcdGNhc2UgJ000Qic6XG5cdFx0XHRcdFx0cmV0dXJuIHtleHQ6ICdtNGInLCBtaW1lOiAnYXVkaW8vbXA0J307XG5cdFx0XHRcdGNhc2UgJ000QSc6XG5cdFx0XHRcdFx0cmV0dXJuIHtleHQ6ICdtNGEnLCBtaW1lOiAnYXVkaW8veC1tNGEnfTtcblx0XHRcdFx0Y2FzZSAnRjRWJzpcblx0XHRcdFx0XHRyZXR1cm4ge2V4dDogJ2Y0dicsIG1pbWU6ICd2aWRlby9tcDQnfTtcblx0XHRcdFx0Y2FzZSAnRjRQJzpcblx0XHRcdFx0XHRyZXR1cm4ge2V4dDogJ2Y0cCcsIG1pbWU6ICd2aWRlby9tcDQnfTtcblx0XHRcdFx0Y2FzZSAnRjRBJzpcblx0XHRcdFx0XHRyZXR1cm4ge2V4dDogJ2Y0YScsIG1pbWU6ICdhdWRpby9tcDQnfTtcblx0XHRcdFx0Y2FzZSAnRjRCJzpcblx0XHRcdFx0XHRyZXR1cm4ge2V4dDogJ2Y0YicsIG1pbWU6ICdhdWRpby9tcDQnfTtcblx0XHRcdFx0Y2FzZSAnY3J4Jzpcblx0XHRcdFx0XHRyZXR1cm4ge2V4dDogJ2NyMycsIG1pbWU6ICdpbWFnZS94LWNhbm9uLWNyMyd9O1xuXHRcdFx0XHRkZWZhdWx0OlxuXHRcdFx0XHRcdGlmIChicmFuZE1ham9yLnN0YXJ0c1dpdGgoJzNnJykpIHtcblx0XHRcdFx0XHRcdGlmIChicmFuZE1ham9yLnN0YXJ0c1dpdGgoJzNnMicpKSB7XG5cdFx0XHRcdFx0XHRcdHJldHVybiB7ZXh0OiAnM2cyJywgbWltZTogJ3ZpZGVvLzNncHAyJ307XG5cdFx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHRcdHJldHVybiB7ZXh0OiAnM2dwJywgbWltZTogJ3ZpZGVvLzNncHAnfTtcblx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHRyZXR1cm4ge2V4dDogJ21wNCcsIG1pbWU6ICd2aWRlby9tcDQnfTtcblx0XHRcdH1cblx0XHR9XG5cblx0XHRpZiAodGhpcy5jaGVja1N0cmluZygnTVRoZCcpKSB7XG5cdFx0XHRyZXR1cm4ge1xuXHRcdFx0XHRleHQ6ICdtaWQnLFxuXHRcdFx0XHRtaW1lOiAnYXVkaW8vbWlkaScsXG5cdFx0XHR9O1xuXHRcdH1cblxuXHRcdGlmIChcblx0XHRcdHRoaXMuY2hlY2tTdHJpbmcoJ3dPRkYnKVxuXHRcdFx0JiYgKFxuXHRcdFx0XHR0aGlzLmNoZWNrKFsweDAwLCAweDAxLCAweDAwLCAweDAwXSwge29mZnNldDogNH0pXG5cdFx0XHRcdHx8IHRoaXMuY2hlY2tTdHJpbmcoJ09UVE8nLCB7b2Zmc2V0OiA0fSlcblx0XHRcdClcblx0XHQpIHtcblx0XHRcdHJldHVybiB7XG5cdFx0XHRcdGV4dDogJ3dvZmYnLFxuXHRcdFx0XHRtaW1lOiAnZm9udC93b2ZmJyxcblx0XHRcdH07XG5cdFx0fVxuXG5cdFx0aWYgKFxuXHRcdFx0dGhpcy5jaGVja1N0cmluZygnd09GMicpXG5cdFx0XHQmJiAoXG5cdFx0XHRcdHRoaXMuY2hlY2soWzB4MDAsIDB4MDEsIDB4MDAsIDB4MDBdLCB7b2Zmc2V0OiA0fSlcblx0XHRcdFx0fHwgdGhpcy5jaGVja1N0cmluZygnT1RUTycsIHtvZmZzZXQ6IDR9KVxuXHRcdFx0KVxuXHRcdCkge1xuXHRcdFx0cmV0dXJuIHtcblx0XHRcdFx0ZXh0OiAnd29mZjInLFxuXHRcdFx0XHRtaW1lOiAnZm9udC93b2ZmMicsXG5cdFx0XHR9O1xuXHRcdH1cblxuXHRcdGlmICh0aGlzLmNoZWNrKFsweEQ0LCAweEMzLCAweEIyLCAweEExXSkgfHwgdGhpcy5jaGVjayhbMHhBMSwgMHhCMiwgMHhDMywgMHhENF0pKSB7XG5cdFx0XHRyZXR1cm4ge1xuXHRcdFx0XHRleHQ6ICdwY2FwJyxcblx0XHRcdFx0bWltZTogJ2FwcGxpY2F0aW9uL3ZuZC50Y3BkdW1wLnBjYXAnLFxuXHRcdFx0fTtcblx0XHR9XG5cblx0XHQvLyBTb255IERTRCBTdHJlYW0gRmlsZSAoRFNGKVxuXHRcdGlmICh0aGlzLmNoZWNrU3RyaW5nKCdEU0QgJykpIHtcblx0XHRcdHJldHVybiB7XG5cdFx0XHRcdGV4dDogJ2RzZicsXG5cdFx0XHRcdG1pbWU6ICdhdWRpby94LWRzZicsIC8vIE5vbi1zdGFuZGFyZFxuXHRcdFx0fTtcblx0XHR9XG5cblx0XHRpZiAodGhpcy5jaGVja1N0cmluZygnTFpJUCcpKSB7XG5cdFx0XHRyZXR1cm4ge1xuXHRcdFx0XHRleHQ6ICdseicsXG5cdFx0XHRcdG1pbWU6ICdhcHBsaWNhdGlvbi94LWx6aXAnLFxuXHRcdFx0fTtcblx0XHR9XG5cblx0XHRpZiAodGhpcy5jaGVja1N0cmluZygnZkxhQycpKSB7XG5cdFx0XHRyZXR1cm4ge1xuXHRcdFx0XHRleHQ6ICdmbGFjJyxcblx0XHRcdFx0bWltZTogJ2F1ZGlvL3gtZmxhYycsXG5cdFx0XHR9O1xuXHRcdH1cblxuXHRcdGlmICh0aGlzLmNoZWNrKFsweDQyLCAweDUwLCAweDQ3LCAweEZCXSkpIHtcblx0XHRcdHJldHVybiB7XG5cdFx0XHRcdGV4dDogJ2JwZycsXG5cdFx0XHRcdG1pbWU6ICdpbWFnZS9icGcnLFxuXHRcdFx0fTtcblx0XHR9XG5cblx0XHRpZiAodGhpcy5jaGVja1N0cmluZygnd3ZwaycpKSB7XG5cdFx0XHRyZXR1cm4ge1xuXHRcdFx0XHRleHQ6ICd3dicsXG5cdFx0XHRcdG1pbWU6ICdhdWRpby93YXZwYWNrJyxcblx0XHRcdH07XG5cdFx0fVxuXG5cdFx0aWYgKHRoaXMuY2hlY2tTdHJpbmcoJyVQREYnKSkge1xuXHRcdFx0dHJ5IHtcblx0XHRcdFx0YXdhaXQgdG9rZW5pemVyLmlnbm9yZSgxMzUwKTtcblx0XHRcdFx0Y29uc3QgbWF4QnVmZmVyU2l6ZSA9IDEwICogMTAyNCAqIDEwMjQ7XG5cdFx0XHRcdGNvbnN0IGJ1ZmZlciA9IEJ1ZmZlci5hbGxvYyhNYXRoLm1pbihtYXhCdWZmZXJTaXplLCB0b2tlbml6ZXIuZmlsZUluZm8uc2l6ZSkpO1xuXHRcdFx0XHRhd2FpdCB0b2tlbml6ZXIucmVhZEJ1ZmZlcihidWZmZXIsIHttYXlCZUxlc3M6IHRydWV9KTtcblxuXHRcdFx0XHQvLyBDaGVjayBpZiB0aGlzIGlzIGFuIEFkb2JlIElsbHVzdHJhdG9yIGZpbGVcblx0XHRcdFx0aWYgKGJ1ZmZlci5pbmNsdWRlcyhCdWZmZXIuZnJvbSgnQUlQcml2YXRlRGF0YScpKSkge1xuXHRcdFx0XHRcdHJldHVybiB7XG5cdFx0XHRcdFx0XHRleHQ6ICdhaScsXG5cdFx0XHRcdFx0XHRtaW1lOiAnYXBwbGljYXRpb24vcG9zdHNjcmlwdCcsXG5cdFx0XHRcdFx0fTtcblx0XHRcdFx0fVxuXHRcdFx0fSBjYXRjaCAoZXJyb3IpIHtcblx0XHRcdFx0Ly8gU3dhbGxvdyBlbmQgb2Ygc3RyZWFtIGVycm9yIGlmIGZpbGUgaXMgdG9vIHNtYWxsIGZvciB0aGUgQWRvYmUgQUkgY2hlY2tcblx0XHRcdFx0aWYgKCEoZXJyb3IgaW5zdGFuY2VvZiBzdHJ0b2szLkVuZE9mU3RyZWFtRXJyb3IpKSB7XG5cdFx0XHRcdFx0dGhyb3cgZXJyb3I7XG5cdFx0XHRcdH1cblx0XHRcdH1cblxuXHRcdFx0Ly8gQXNzdW1lIHRoaXMgaXMganVzdCBhIG5vcm1hbCBQREZcblx0XHRcdHJldHVybiB7XG5cdFx0XHRcdGV4dDogJ3BkZicsXG5cdFx0XHRcdG1pbWU6ICdhcHBsaWNhdGlvbi9wZGYnLFxuXHRcdFx0fTtcblx0XHR9XG5cblx0XHRpZiAodGhpcy5jaGVjayhbMHgwMCwgMHg2MSwgMHg3MywgMHg2RF0pKSB7XG5cdFx0XHRyZXR1cm4ge1xuXHRcdFx0XHRleHQ6ICd3YXNtJyxcblx0XHRcdFx0bWltZTogJ2FwcGxpY2F0aW9uL3dhc20nLFxuXHRcdFx0fTtcblx0XHR9XG5cblx0XHQvLyBUSUZGLCBsaXR0bGUtZW5kaWFuIHR5cGVcblx0XHRpZiAodGhpcy5jaGVjayhbMHg0OSwgMHg0OV0pKSB7XG5cdFx0XHRjb25zdCBmaWxlVHlwZSA9IGF3YWl0IHRoaXMucmVhZFRpZmZIZWFkZXIoZmFsc2UpO1xuXHRcdFx0aWYgKGZpbGVUeXBlKSB7XG5cdFx0XHRcdHJldHVybiBmaWxlVHlwZTtcblx0XHRcdH1cblx0XHR9XG5cblx0XHQvLyBUSUZGLCBiaWctZW5kaWFuIHR5cGVcblx0XHRpZiAodGhpcy5jaGVjayhbMHg0RCwgMHg0RF0pKSB7XG5cdFx0XHRjb25zdCBmaWxlVHlwZSA9IGF3YWl0IHRoaXMucmVhZFRpZmZIZWFkZXIodHJ1ZSk7XG5cdFx0XHRpZiAoZmlsZVR5cGUpIHtcblx0XHRcdFx0cmV0dXJuIGZpbGVUeXBlO1xuXHRcdFx0fVxuXHRcdH1cblxuXHRcdGlmICh0aGlzLmNoZWNrU3RyaW5nKCdNQUMgJykpIHtcblx0XHRcdHJldHVybiB7XG5cdFx0XHRcdGV4dDogJ2FwZScsXG5cdFx0XHRcdG1pbWU6ICdhdWRpby9hcGUnLFxuXHRcdFx0fTtcblx0XHR9XG5cblx0XHQvLyBodHRwczovL2dpdGh1Yi5jb20vdGhyZWF0c3RhY2svbGlibWFnaWMvYmxvYi9tYXN0ZXIvbWFnaWMvTWFnZGlyL21hdHJvc2thXG5cdFx0aWYgKHRoaXMuY2hlY2soWzB4MUEsIDB4NDUsIDB4REYsIDB4QTNdKSkgeyAvLyBSb290IGVsZW1lbnQ6IEVCTUxcblx0XHRcdGFzeW5jIGZ1bmN0aW9uIHJlYWRGaWVsZCgpIHtcblx0XHRcdFx0Y29uc3QgbXNiID0gYXdhaXQgdG9rZW5pemVyLnBlZWtOdW1iZXIoVG9rZW4uVUlOVDgpO1xuXHRcdFx0XHRsZXQgbWFzayA9IDB4ODA7XG5cdFx0XHRcdGxldCBpYyA9IDA7IC8vIDAgPSBBLCAxID0gQiwgMiA9IEMsIDNcblx0XHRcdFx0Ly8gPSBEXG5cblx0XHRcdFx0d2hpbGUgKChtc2IgJiBtYXNrKSA9PT0gMCAmJiBtYXNrICE9PSAwKSB7XG5cdFx0XHRcdFx0KytpYztcblx0XHRcdFx0XHRtYXNrID4+PSAxO1xuXHRcdFx0XHR9XG5cblx0XHRcdFx0Y29uc3QgaWQgPSBCdWZmZXIuYWxsb2MoaWMgKyAxKTtcblx0XHRcdFx0YXdhaXQgdG9rZW5pemVyLnJlYWRCdWZmZXIoaWQpO1xuXHRcdFx0XHRyZXR1cm4gaWQ7XG5cdFx0XHR9XG5cblx0XHRcdGFzeW5jIGZ1bmN0aW9uIHJlYWRFbGVtZW50KCkge1xuXHRcdFx0XHRjb25zdCBpZCA9IGF3YWl0IHJlYWRGaWVsZCgpO1xuXHRcdFx0XHRjb25zdCBsZW5ndGhGaWVsZCA9IGF3YWl0IHJlYWRGaWVsZCgpO1xuXHRcdFx0XHRsZW5ndGhGaWVsZFswXSBePSAweDgwID4+IChsZW5ndGhGaWVsZC5sZW5ndGggLSAxKTtcblx0XHRcdFx0Y29uc3QgbnJMZW5ndGggPSBNYXRoLm1pbig2LCBsZW5ndGhGaWVsZC5sZW5ndGgpOyAvLyBKYXZhU2NyaXB0IGNhbiBtYXggcmVhZCA2IGJ5dGVzIGludGVnZXJcblx0XHRcdFx0cmV0dXJuIHtcblx0XHRcdFx0XHRpZDogaWQucmVhZFVJbnRCRSgwLCBpZC5sZW5ndGgpLFxuXHRcdFx0XHRcdGxlbjogbGVuZ3RoRmllbGQucmVhZFVJbnRCRShsZW5ndGhGaWVsZC5sZW5ndGggLSBuckxlbmd0aCwgbnJMZW5ndGgpLFxuXHRcdFx0XHR9O1xuXHRcdFx0fVxuXG5cdFx0XHRhc3luYyBmdW5jdGlvbiByZWFkQ2hpbGRyZW4oY2hpbGRyZW4pIHtcblx0XHRcdFx0d2hpbGUgKGNoaWxkcmVuID4gMCkge1xuXHRcdFx0XHRcdGNvbnN0IGVsZW1lbnQgPSBhd2FpdCByZWFkRWxlbWVudCgpO1xuXHRcdFx0XHRcdGlmIChlbGVtZW50LmlkID09PSAweDQyXzgyKSB7XG5cdFx0XHRcdFx0XHRjb25zdCByYXdWYWx1ZSA9IGF3YWl0IHRva2VuaXplci5yZWFkVG9rZW4obmV3IFRva2VuLlN0cmluZ1R5cGUoZWxlbWVudC5sZW4sICd1dGYtOCcpKTtcblx0XHRcdFx0XHRcdHJldHVybiByYXdWYWx1ZS5yZXBsYWNlKC9cXDAwLiokL2csICcnKTsgLy8gUmV0dXJuIERvY1R5cGVcblx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHRhd2FpdCB0b2tlbml6ZXIuaWdub3JlKGVsZW1lbnQubGVuKTsgLy8gaWdub3JlIHBheWxvYWRcblx0XHRcdFx0XHQtLWNoaWxkcmVuO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cblx0XHRcdGNvbnN0IHJlID0gYXdhaXQgcmVhZEVsZW1lbnQoKTtcblx0XHRcdGNvbnN0IGRvY1R5cGUgPSBhd2FpdCByZWFkQ2hpbGRyZW4ocmUubGVuKTtcblxuXHRcdFx0c3dpdGNoIChkb2NUeXBlKSB7XG5cdFx0XHRcdGNhc2UgJ3dlYm0nOlxuXHRcdFx0XHRcdHJldHVybiB7XG5cdFx0XHRcdFx0XHRleHQ6ICd3ZWJtJyxcblx0XHRcdFx0XHRcdG1pbWU6ICd2aWRlby93ZWJtJyxcblx0XHRcdFx0XHR9O1xuXG5cdFx0XHRcdGNhc2UgJ21hdHJvc2thJzpcblx0XHRcdFx0XHRyZXR1cm4ge1xuXHRcdFx0XHRcdFx0ZXh0OiAnbWt2Jyxcblx0XHRcdFx0XHRcdG1pbWU6ICd2aWRlby94LW1hdHJvc2thJyxcblx0XHRcdFx0XHR9O1xuXG5cdFx0XHRcdGRlZmF1bHQ6XG5cdFx0XHRcdFx0cmV0dXJuO1xuXHRcdFx0fVxuXHRcdH1cblxuXHRcdC8vIFJJRkYgZmlsZSBmb3JtYXQgd2hpY2ggbWlnaHQgYmUgQVZJLCBXQVYsIFFDUCwgZXRjXG5cdFx0aWYgKHRoaXMuY2hlY2soWzB4NTIsIDB4NDksIDB4NDYsIDB4NDZdKSkge1xuXHRcdFx0aWYgKHRoaXMuY2hlY2soWzB4NDEsIDB4NTYsIDB4NDldLCB7b2Zmc2V0OiA4fSkpIHtcblx0XHRcdFx0cmV0dXJuIHtcblx0XHRcdFx0XHRleHQ6ICdhdmknLFxuXHRcdFx0XHRcdG1pbWU6ICd2aWRlby92bmQuYXZpJyxcblx0XHRcdFx0fTtcblx0XHRcdH1cblxuXHRcdFx0aWYgKHRoaXMuY2hlY2soWzB4NTcsIDB4NDEsIDB4NTYsIDB4NDVdLCB7b2Zmc2V0OiA4fSkpIHtcblx0XHRcdFx0cmV0dXJuIHtcblx0XHRcdFx0XHRleHQ6ICd3YXYnLFxuXHRcdFx0XHRcdG1pbWU6ICdhdWRpby92bmQud2F2ZScsXG5cdFx0XHRcdH07XG5cdFx0XHR9XG5cblx0XHRcdC8vIFFMQ00sIFFDUCBmaWxlXG5cdFx0XHRpZiAodGhpcy5jaGVjayhbMHg1MSwgMHg0QywgMHg0MywgMHg0RF0sIHtvZmZzZXQ6IDh9KSkge1xuXHRcdFx0XHRyZXR1cm4ge1xuXHRcdFx0XHRcdGV4dDogJ3FjcCcsXG5cdFx0XHRcdFx0bWltZTogJ2F1ZGlvL3FjZWxwJyxcblx0XHRcdFx0fTtcblx0XHRcdH1cblx0XHR9XG5cblx0XHRpZiAodGhpcy5jaGVja1N0cmluZygnU1FMaScpKSB7XG5cdFx0XHRyZXR1cm4ge1xuXHRcdFx0XHRleHQ6ICdzcWxpdGUnLFxuXHRcdFx0XHRtaW1lOiAnYXBwbGljYXRpb24veC1zcWxpdGUzJyxcblx0XHRcdH07XG5cdFx0fVxuXG5cdFx0aWYgKHRoaXMuY2hlY2soWzB4NEUsIDB4NDUsIDB4NTMsIDB4MUFdKSkge1xuXHRcdFx0cmV0dXJuIHtcblx0XHRcdFx0ZXh0OiAnbmVzJyxcblx0XHRcdFx0bWltZTogJ2FwcGxpY2F0aW9uL3gtbmludGVuZG8tbmVzLXJvbScsXG5cdFx0XHR9O1xuXHRcdH1cblxuXHRcdGlmICh0aGlzLmNoZWNrU3RyaW5nKCdDcjI0JykpIHtcblx0XHRcdHJldHVybiB7XG5cdFx0XHRcdGV4dDogJ2NyeCcsXG5cdFx0XHRcdG1pbWU6ICdhcHBsaWNhdGlvbi94LWdvb2dsZS1jaHJvbWUtZXh0ZW5zaW9uJyxcblx0XHRcdH07XG5cdFx0fVxuXG5cdFx0aWYgKFxuXHRcdFx0dGhpcy5jaGVja1N0cmluZygnTVNDRicpXG5cdFx0XHR8fCB0aGlzLmNoZWNrU3RyaW5nKCdJU2MoJylcblx0XHQpIHtcblx0XHRcdHJldHVybiB7XG5cdFx0XHRcdGV4dDogJ2NhYicsXG5cdFx0XHRcdG1pbWU6ICdhcHBsaWNhdGlvbi92bmQubXMtY2FiLWNvbXByZXNzZWQnLFxuXHRcdFx0fTtcblx0XHR9XG5cblx0XHRpZiAodGhpcy5jaGVjayhbMHhFRCwgMHhBQiwgMHhFRSwgMHhEQl0pKSB7XG5cdFx0XHRyZXR1cm4ge1xuXHRcdFx0XHRleHQ6ICdycG0nLFxuXHRcdFx0XHRtaW1lOiAnYXBwbGljYXRpb24veC1ycG0nLFxuXHRcdFx0fTtcblx0XHR9XG5cblx0XHRpZiAodGhpcy5jaGVjayhbMHhDNSwgMHhEMCwgMHhEMywgMHhDNl0pKSB7XG5cdFx0XHRyZXR1cm4ge1xuXHRcdFx0XHRleHQ6ICdlcHMnLFxuXHRcdFx0XHRtaW1lOiAnYXBwbGljYXRpb24vZXBzJyxcblx0XHRcdH07XG5cdFx0fVxuXG5cdFx0aWYgKHRoaXMuY2hlY2soWzB4MjgsIDB4QjUsIDB4MkYsIDB4RkRdKSkge1xuXHRcdFx0cmV0dXJuIHtcblx0XHRcdFx0ZXh0OiAnenN0Jyxcblx0XHRcdFx0bWltZTogJ2FwcGxpY2F0aW9uL3pzdGQnLFxuXHRcdFx0fTtcblx0XHR9XG5cblx0XHRpZiAodGhpcy5jaGVjayhbMHg3RiwgMHg0NSwgMHg0QywgMHg0Nl0pKSB7XG5cdFx0XHRyZXR1cm4ge1xuXHRcdFx0XHRleHQ6ICdlbGYnLFxuXHRcdFx0XHRtaW1lOiAnYXBwbGljYXRpb24veC1lbGYnLFxuXHRcdFx0fTtcblx0XHR9XG5cblx0XHRpZiAodGhpcy5jaGVjayhbMHgyMSwgMHg0MiwgMHg0NCwgMHg0RV0pKSB7XG5cdFx0XHRyZXR1cm4ge1xuXHRcdFx0XHRleHQ6ICdwc3QnLFxuXHRcdFx0XHRtaW1lOiAnYXBwbGljYXRpb24vdm5kLm1zLW91dGxvb2snLFxuXHRcdFx0fTtcblx0XHR9XG5cblx0XHRpZiAodGhpcy5jaGVja1N0cmluZygnUEFSMScpKSB7XG5cdFx0XHRyZXR1cm4ge1xuXHRcdFx0XHRleHQ6ICdwYXJxdWV0Jyxcblx0XHRcdFx0bWltZTogJ2FwcGxpY2F0aW9uL3gtcGFycXVldCcsXG5cdFx0XHR9O1xuXHRcdH1cblxuXHRcdC8vIC0tIDUtYnl0ZSBzaWduYXR1cmVzIC0tXG5cblx0XHRpZiAodGhpcy5jaGVjayhbMHg0RiwgMHg1NCwgMHg1NCwgMHg0RiwgMHgwMF0pKSB7XG5cdFx0XHRyZXR1cm4ge1xuXHRcdFx0XHRleHQ6ICdvdGYnLFxuXHRcdFx0XHRtaW1lOiAnZm9udC9vdGYnLFxuXHRcdFx0fTtcblx0XHR9XG5cblx0XHRpZiAodGhpcy5jaGVja1N0cmluZygnIyFBTVInKSkge1xuXHRcdFx0cmV0dXJuIHtcblx0XHRcdFx0ZXh0OiAnYW1yJyxcblx0XHRcdFx0bWltZTogJ2F1ZGlvL2FtcicsXG5cdFx0XHR9O1xuXHRcdH1cblxuXHRcdGlmICh0aGlzLmNoZWNrU3RyaW5nKCd7XFxcXHJ0ZicpKSB7XG5cdFx0XHRyZXR1cm4ge1xuXHRcdFx0XHRleHQ6ICdydGYnLFxuXHRcdFx0XHRtaW1lOiAnYXBwbGljYXRpb24vcnRmJyxcblx0XHRcdH07XG5cdFx0fVxuXG5cdFx0aWYgKHRoaXMuY2hlY2soWzB4NDYsIDB4NEMsIDB4NTYsIDB4MDFdKSkge1xuXHRcdFx0cmV0dXJuIHtcblx0XHRcdFx0ZXh0OiAnZmx2Jyxcblx0XHRcdFx0bWltZTogJ3ZpZGVvL3gtZmx2Jyxcblx0XHRcdH07XG5cdFx0fVxuXG5cdFx0aWYgKHRoaXMuY2hlY2tTdHJpbmcoJ0lNUE0nKSkge1xuXHRcdFx0cmV0dXJuIHtcblx0XHRcdFx0ZXh0OiAnaXQnLFxuXHRcdFx0XHRtaW1lOiAnYXVkaW8veC1pdCcsXG5cdFx0XHR9O1xuXHRcdH1cblxuXHRcdGlmIChcblx0XHRcdHRoaXMuY2hlY2tTdHJpbmcoJy1saDAtJywge29mZnNldDogMn0pXG5cdFx0XHR8fCB0aGlzLmNoZWNrU3RyaW5nKCctbGgxLScsIHtvZmZzZXQ6IDJ9KVxuXHRcdFx0fHwgdGhpcy5jaGVja1N0cmluZygnLWxoMi0nLCB7b2Zmc2V0OiAyfSlcblx0XHRcdHx8IHRoaXMuY2hlY2tTdHJpbmcoJy1saDMtJywge29mZnNldDogMn0pXG5cdFx0XHR8fCB0aGlzLmNoZWNrU3RyaW5nKCctbGg0LScsIHtvZmZzZXQ6IDJ9KVxuXHRcdFx0fHwgdGhpcy5jaGVja1N0cmluZygnLWxoNS0nLCB7b2Zmc2V0OiAyfSlcblx0XHRcdHx8IHRoaXMuY2hlY2tTdHJpbmcoJy1saDYtJywge29mZnNldDogMn0pXG5cdFx0XHR8fCB0aGlzLmNoZWNrU3RyaW5nKCctbGg3LScsIHtvZmZzZXQ6IDJ9KVxuXHRcdFx0fHwgdGhpcy5jaGVja1N0cmluZygnLWx6cy0nLCB7b2Zmc2V0OiAyfSlcblx0XHRcdHx8IHRoaXMuY2hlY2tTdHJpbmcoJy1sejQtJywge29mZnNldDogMn0pXG5cdFx0XHR8fCB0aGlzLmNoZWNrU3RyaW5nKCctbHo1LScsIHtvZmZzZXQ6IDJ9KVxuXHRcdFx0fHwgdGhpcy5jaGVja1N0cmluZygnLWxoZC0nLCB7b2Zmc2V0OiAyfSlcblx0XHQpIHtcblx0XHRcdHJldHVybiB7XG5cdFx0XHRcdGV4dDogJ2x6aCcsXG5cdFx0XHRcdG1pbWU6ICdhcHBsaWNhdGlvbi94LWx6aC1jb21wcmVzc2VkJyxcblx0XHRcdH07XG5cdFx0fVxuXG5cdFx0Ly8gTVBFRyBwcm9ncmFtIHN0cmVhbSAoUFMgb3IgTVBFRy1QUylcblx0XHRpZiAodGhpcy5jaGVjayhbMHgwMCwgMHgwMCwgMHgwMSwgMHhCQV0pKSB7XG5cdFx0XHQvLyAgTVBFRy1QUywgTVBFRy0xIFBhcnQgMVxuXHRcdFx0aWYgKHRoaXMuY2hlY2soWzB4MjFdLCB7b2Zmc2V0OiA0LCBtYXNrOiBbMHhGMV19KSkge1xuXHRcdFx0XHRyZXR1cm4ge1xuXHRcdFx0XHRcdGV4dDogJ21wZycsIC8vIE1heSBhbHNvIGJlIC5wcywgLm1wZWdcblx0XHRcdFx0XHRtaW1lOiAndmlkZW8vTVAxUycsXG5cdFx0XHRcdH07XG5cdFx0XHR9XG5cblx0XHRcdC8vIE1QRUctUFMsIE1QRUctMiBQYXJ0IDFcblx0XHRcdGlmICh0aGlzLmNoZWNrKFsweDQ0XSwge29mZnNldDogNCwgbWFzazogWzB4QzRdfSkpIHtcblx0XHRcdFx0cmV0dXJuIHtcblx0XHRcdFx0XHRleHQ6ICdtcGcnLCAvLyBNYXkgYWxzbyBiZSAubXBnLCAubTJwLCAudm9iIG9yIC5zdWJcblx0XHRcdFx0XHRtaW1lOiAndmlkZW8vTVAyUCcsXG5cdFx0XHRcdH07XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0aWYgKHRoaXMuY2hlY2tTdHJpbmcoJ0lUU0YnKSkge1xuXHRcdFx0cmV0dXJuIHtcblx0XHRcdFx0ZXh0OiAnY2htJyxcblx0XHRcdFx0bWltZTogJ2FwcGxpY2F0aW9uL3ZuZC5tcy1odG1saGVscCcsXG5cdFx0XHR9O1xuXHRcdH1cblxuXHRcdGlmICh0aGlzLmNoZWNrKFsweENBLCAweEZFLCAweEJBLCAweEJFXSkpIHtcblx0XHRcdHJldHVybiB7XG5cdFx0XHRcdGV4dDogJ2NsYXNzJyxcblx0XHRcdFx0bWltZTogJ2FwcGxpY2F0aW9uL2phdmEtdm0nLFxuXHRcdFx0fTtcblx0XHR9XG5cblx0XHQvLyAtLSA2LWJ5dGUgc2lnbmF0dXJlcyAtLVxuXG5cdFx0aWYgKHRoaXMuY2hlY2soWzB4RkQsIDB4MzcsIDB4N0EsIDB4NTgsIDB4NUEsIDB4MDBdKSkge1xuXHRcdFx0cmV0dXJuIHtcblx0XHRcdFx0ZXh0OiAneHonLFxuXHRcdFx0XHRtaW1lOiAnYXBwbGljYXRpb24veC14eicsXG5cdFx0XHR9O1xuXHRcdH1cblxuXHRcdGlmICh0aGlzLmNoZWNrU3RyaW5nKCc8P3htbCAnKSkge1xuXHRcdFx0cmV0dXJuIHtcblx0XHRcdFx0ZXh0OiAneG1sJyxcblx0XHRcdFx0bWltZTogJ2FwcGxpY2F0aW9uL3htbCcsXG5cdFx0XHR9O1xuXHRcdH1cblxuXHRcdGlmICh0aGlzLmNoZWNrKFsweDM3LCAweDdBLCAweEJDLCAweEFGLCAweDI3LCAweDFDXSkpIHtcblx0XHRcdHJldHVybiB7XG5cdFx0XHRcdGV4dDogJzd6Jyxcblx0XHRcdFx0bWltZTogJ2FwcGxpY2F0aW9uL3gtN3otY29tcHJlc3NlZCcsXG5cdFx0XHR9O1xuXHRcdH1cblxuXHRcdGlmIChcblx0XHRcdHRoaXMuY2hlY2soWzB4NTIsIDB4NjEsIDB4NzIsIDB4MjEsIDB4MUEsIDB4N10pXG5cdFx0XHQmJiAodGhpcy5idWZmZXJbNl0gPT09IDB4MCB8fCB0aGlzLmJ1ZmZlcls2XSA9PT0gMHgxKVxuXHRcdCkge1xuXHRcdFx0cmV0dXJuIHtcblx0XHRcdFx0ZXh0OiAncmFyJyxcblx0XHRcdFx0bWltZTogJ2FwcGxpY2F0aW9uL3gtcmFyLWNvbXByZXNzZWQnLFxuXHRcdFx0fTtcblx0XHR9XG5cblx0XHRpZiAodGhpcy5jaGVja1N0cmluZygnc29saWQgJykpIHtcblx0XHRcdHJldHVybiB7XG5cdFx0XHRcdGV4dDogJ3N0bCcsXG5cdFx0XHRcdG1pbWU6ICdtb2RlbC9zdGwnLFxuXHRcdFx0fTtcblx0XHR9XG5cblx0XHRpZiAodGhpcy5jaGVja1N0cmluZygnQUMnKSkge1xuXHRcdFx0Y29uc3QgdmVyc2lvbiA9IHRoaXMuYnVmZmVyLnRvU3RyaW5nKCdiaW5hcnknLCAyLCA2KTtcblx0XHRcdGlmICh2ZXJzaW9uLm1hdGNoKCdeZConKSAmJiB2ZXJzaW9uID49IDEwMDAgJiYgdmVyc2lvbiA8PSAxMDUwKSB7XG5cdFx0XHRcdHJldHVybiB7XG5cdFx0XHRcdFx0ZXh0OiAnZHdnJyxcblx0XHRcdFx0XHRtaW1lOiAnaW1hZ2Uvdm5kLmR3ZycsXG5cdFx0XHRcdH07XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0aWYgKHRoaXMuY2hlY2tTdHJpbmcoJzA3MDcwNycpKSB7XG5cdFx0XHRyZXR1cm4ge1xuXHRcdFx0XHRleHQ6ICdjcGlvJyxcblx0XHRcdFx0bWltZTogJ2FwcGxpY2F0aW9uL3gtY3BpbycsXG5cdFx0XHR9O1xuXHRcdH1cblxuXHRcdC8vIC0tIDctYnl0ZSBzaWduYXR1cmVzIC0tXG5cblx0XHRpZiAodGhpcy5jaGVja1N0cmluZygnQkxFTkRFUicpKSB7XG5cdFx0XHRyZXR1cm4ge1xuXHRcdFx0XHRleHQ6ICdibGVuZCcsXG5cdFx0XHRcdG1pbWU6ICdhcHBsaWNhdGlvbi94LWJsZW5kZXInLFxuXHRcdFx0fTtcblx0XHR9XG5cblx0XHRpZiAodGhpcy5jaGVja1N0cmluZygnITxhcmNoPicpKSB7XG5cdFx0XHRhd2FpdCB0b2tlbml6ZXIuaWdub3JlKDgpO1xuXHRcdFx0Y29uc3Qgc3RyaW5nID0gYXdhaXQgdG9rZW5pemVyLnJlYWRUb2tlbihuZXcgVG9rZW4uU3RyaW5nVHlwZSgxMywgJ2FzY2lpJykpO1xuXHRcdFx0aWYgKHN0cmluZyA9PT0gJ2RlYmlhbi1iaW5hcnknKSB7XG5cdFx0XHRcdHJldHVybiB7XG5cdFx0XHRcdFx0ZXh0OiAnZGViJyxcblx0XHRcdFx0XHRtaW1lOiAnYXBwbGljYXRpb24veC1kZWInLFxuXHRcdFx0XHR9O1xuXHRcdFx0fVxuXG5cdFx0XHRyZXR1cm4ge1xuXHRcdFx0XHRleHQ6ICdhcicsXG5cdFx0XHRcdG1pbWU6ICdhcHBsaWNhdGlvbi94LXVuaXgtYXJjaGl2ZScsXG5cdFx0XHR9O1xuXHRcdH1cblxuXHRcdGlmICh0aGlzLmNoZWNrU3RyaW5nKCcqKkFDRScsIHtvZmZzZXQ6IDd9KSkge1xuXHRcdFx0YXdhaXQgdG9rZW5pemVyLnBlZWtCdWZmZXIodGhpcy5idWZmZXIsIHtsZW5ndGg6IDE0LCBtYXlCZUxlc3M6IHRydWV9KTtcblx0XHRcdGlmICh0aGlzLmNoZWNrU3RyaW5nKCcqKicsIHtvZmZzZXQ6IDEyfSkpIHtcblx0XHRcdFx0cmV0dXJuIHtcblx0XHRcdFx0XHRleHQ6ICdhY2UnLFxuXHRcdFx0XHRcdG1pbWU6ICdhcHBsaWNhdGlvbi94LWFjZS1jb21wcmVzc2VkJyxcblx0XHRcdFx0fTtcblx0XHRcdH1cblx0XHR9XG5cblx0XHQvLyAtLSA4LWJ5dGUgc2lnbmF0dXJlcyAtLVxuXG5cdFx0aWYgKHRoaXMuY2hlY2soWzB4ODksIDB4NTAsIDB4NEUsIDB4NDcsIDB4MEQsIDB4MEEsIDB4MUEsIDB4MEFdKSkge1xuXHRcdFx0Ly8gQVBORyBmb3JtYXQgKGh0dHBzOi8vd2lraS5tb3ppbGxhLm9yZy9BUE5HX1NwZWNpZmljYXRpb24pXG5cdFx0XHQvLyAxLiBGaW5kIHRoZSBmaXJzdCBJREFUIChpbWFnZSBkYXRhKSBjaHVuayAoNDkgNDQgNDEgNTQpXG5cdFx0XHQvLyAyLiBDaGVjayBpZiB0aGVyZSBpcyBhbiBcImFjVExcIiBjaHVuayBiZWZvcmUgdGhlIElEQVQgb25lICg2MSA2MyA1NCA0QylcblxuXHRcdFx0Ly8gT2Zmc2V0IGNhbGN1bGF0ZWQgYXMgZm9sbG93czpcblx0XHRcdC8vIC0gOCBieXRlczogUE5HIHNpZ25hdHVyZVxuXHRcdFx0Ly8gLSA0IChsZW5ndGgpICsgNCAoY2h1bmsgdHlwZSkgKyAxMyAoY2h1bmsgZGF0YSkgKyA0IChDUkMpOiBJSERSIGNodW5rXG5cblx0XHRcdGF3YWl0IHRva2VuaXplci5pZ25vcmUoOCk7IC8vIGlnbm9yZSBQTkcgc2lnbmF0dXJlXG5cblx0XHRcdGFzeW5jIGZ1bmN0aW9uIHJlYWRDaHVua0hlYWRlcigpIHtcblx0XHRcdFx0cmV0dXJuIHtcblx0XHRcdFx0XHRsZW5ndGg6IGF3YWl0IHRva2VuaXplci5yZWFkVG9rZW4oVG9rZW4uSU5UMzJfQkUpLFxuXHRcdFx0XHRcdHR5cGU6IGF3YWl0IHRva2VuaXplci5yZWFkVG9rZW4obmV3IFRva2VuLlN0cmluZ1R5cGUoNCwgJ2JpbmFyeScpKSxcblx0XHRcdFx0fTtcblx0XHRcdH1cblxuXHRcdFx0ZG8ge1xuXHRcdFx0XHRjb25zdCBjaHVuayA9IGF3YWl0IHJlYWRDaHVua0hlYWRlcigpO1xuXHRcdFx0XHRpZiAoY2h1bmsubGVuZ3RoIDwgMCkge1xuXHRcdFx0XHRcdHJldHVybjsgLy8gSW52YWxpZCBjaHVuayBsZW5ndGhcblx0XHRcdFx0fVxuXG5cdFx0XHRcdHN3aXRjaCAoY2h1bmsudHlwZSkge1xuXHRcdFx0XHRcdGNhc2UgJ0lEQVQnOlxuXHRcdFx0XHRcdFx0cmV0dXJuIHtcblx0XHRcdFx0XHRcdFx0ZXh0OiAncG5nJyxcblx0XHRcdFx0XHRcdFx0bWltZTogJ2ltYWdlL3BuZycsXG5cdFx0XHRcdFx0XHR9O1xuXHRcdFx0XHRcdGNhc2UgJ2FjVEwnOlxuXHRcdFx0XHRcdFx0cmV0dXJuIHtcblx0XHRcdFx0XHRcdFx0ZXh0OiAnYXBuZycsXG5cdFx0XHRcdFx0XHRcdG1pbWU6ICdpbWFnZS9hcG5nJyxcblx0XHRcdFx0XHRcdH07XG5cdFx0XHRcdFx0ZGVmYXVsdDpcblx0XHRcdFx0XHRcdGF3YWl0IHRva2VuaXplci5pZ25vcmUoY2h1bmsubGVuZ3RoICsgNCk7IC8vIElnbm9yZSBjaHVuay1kYXRhICsgQ1JDXG5cdFx0XHRcdH1cblx0XHRcdH0gd2hpbGUgKHRva2VuaXplci5wb3NpdGlvbiArIDggPCB0b2tlbml6ZXIuZmlsZUluZm8uc2l6ZSk7XG5cblx0XHRcdHJldHVybiB7XG5cdFx0XHRcdGV4dDogJ3BuZycsXG5cdFx0XHRcdG1pbWU6ICdpbWFnZS9wbmcnLFxuXHRcdFx0fTtcblx0XHR9XG5cblx0XHRpZiAodGhpcy5jaGVjayhbMHg0MSwgMHg1MiwgMHg1MiwgMHg0RiwgMHg1NywgMHgzMSwgMHgwMCwgMHgwMF0pKSB7XG5cdFx0XHRyZXR1cm4ge1xuXHRcdFx0XHRleHQ6ICdhcnJvdycsXG5cdFx0XHRcdG1pbWU6ICdhcHBsaWNhdGlvbi94LWFwYWNoZS1hcnJvdycsXG5cdFx0XHR9O1xuXHRcdH1cblxuXHRcdGlmICh0aGlzLmNoZWNrKFsweDY3LCAweDZDLCAweDU0LCAweDQ2LCAweDAyLCAweDAwLCAweDAwLCAweDAwXSkpIHtcblx0XHRcdHJldHVybiB7XG5cdFx0XHRcdGV4dDogJ2dsYicsXG5cdFx0XHRcdG1pbWU6ICdtb2RlbC9nbHRmLWJpbmFyeScsXG5cdFx0XHR9O1xuXHRcdH1cblxuXHRcdC8vIGBtb3ZgIGZvcm1hdCB2YXJpYW50c1xuXHRcdGlmIChcblx0XHRcdHRoaXMuY2hlY2soWzB4NjYsIDB4NzIsIDB4NjUsIDB4NjVdLCB7b2Zmc2V0OiA0fSkgLy8gYGZyZWVgXG5cdFx0XHR8fCB0aGlzLmNoZWNrKFsweDZELCAweDY0LCAweDYxLCAweDc0XSwge29mZnNldDogNH0pIC8vIGBtZGF0YCBNSlBFR1xuXHRcdFx0fHwgdGhpcy5jaGVjayhbMHg2RCwgMHg2RiwgMHg2RiwgMHg3Nl0sIHtvZmZzZXQ6IDR9KSAvLyBgbW9vdmBcblx0XHRcdHx8IHRoaXMuY2hlY2soWzB4NzcsIDB4NjksIDB4NjQsIDB4NjVdLCB7b2Zmc2V0OiA0fSkgLy8gYHdpZGVgXG5cdFx0KSB7XG5cdFx0XHRyZXR1cm4ge1xuXHRcdFx0XHRleHQ6ICdtb3YnLFxuXHRcdFx0XHRtaW1lOiAndmlkZW8vcXVpY2t0aW1lJyxcblx0XHRcdH07XG5cdFx0fVxuXG5cdFx0Ly8gLS0gOS1ieXRlIHNpZ25hdHVyZXMgLS1cblxuXHRcdGlmICh0aGlzLmNoZWNrKFsweDQ5LCAweDQ5LCAweDUyLCAweDRGLCAweDA4LCAweDAwLCAweDAwLCAweDAwLCAweDE4XSkpIHtcblx0XHRcdHJldHVybiB7XG5cdFx0XHRcdGV4dDogJ29yZicsXG5cdFx0XHRcdG1pbWU6ICdpbWFnZS94LW9seW1wdXMtb3JmJyxcblx0XHRcdH07XG5cdFx0fVxuXG5cdFx0aWYgKHRoaXMuY2hlY2tTdHJpbmcoJ2dpbXAgeGNmICcpKSB7XG5cdFx0XHRyZXR1cm4ge1xuXHRcdFx0XHRleHQ6ICd4Y2YnLFxuXHRcdFx0XHRtaW1lOiAnaW1hZ2UveC14Y2YnLFxuXHRcdFx0fTtcblx0XHR9XG5cblx0XHQvLyAtLSAxMi1ieXRlIHNpZ25hdHVyZXMgLS1cblxuXHRcdGlmICh0aGlzLmNoZWNrKFsweDQ5LCAweDQ5LCAweDU1LCAweDAwLCAweDE4LCAweDAwLCAweDAwLCAweDAwLCAweDg4LCAweEU3LCAweDc0LCAweEQ4XSkpIHtcblx0XHRcdHJldHVybiB7XG5cdFx0XHRcdGV4dDogJ3J3MicsXG5cdFx0XHRcdG1pbWU6ICdpbWFnZS94LXBhbmFzb25pYy1ydzInLFxuXHRcdFx0fTtcblx0XHR9XG5cblx0XHQvLyBBU0ZfSGVhZGVyX09iamVjdCBmaXJzdCA4MCBieXRlc1xuXHRcdGlmICh0aGlzLmNoZWNrKFsweDMwLCAweDI2LCAweEIyLCAweDc1LCAweDhFLCAweDY2LCAweENGLCAweDExLCAweEE2LCAweEQ5XSkpIHtcblx0XHRcdGFzeW5jIGZ1bmN0aW9uIHJlYWRIZWFkZXIoKSB7XG5cdFx0XHRcdGNvbnN0IGd1aWQgPSBCdWZmZXIuYWxsb2MoMTYpO1xuXHRcdFx0XHRhd2FpdCB0b2tlbml6ZXIucmVhZEJ1ZmZlcihndWlkKTtcblx0XHRcdFx0cmV0dXJuIHtcblx0XHRcdFx0XHRpZDogZ3VpZCxcblx0XHRcdFx0XHRzaXplOiBOdW1iZXIoYXdhaXQgdG9rZW5pemVyLnJlYWRUb2tlbihUb2tlbi5VSU5UNjRfTEUpKSxcblx0XHRcdFx0fTtcblx0XHRcdH1cblxuXHRcdFx0YXdhaXQgdG9rZW5pemVyLmlnbm9yZSgzMCk7XG5cdFx0XHQvLyBTZWFyY2ggZm9yIGhlYWRlciBzaG91bGQgYmUgaW4gZmlyc3QgMUtCIG9mIGZpbGUuXG5cdFx0XHR3aGlsZSAodG9rZW5pemVyLnBvc2l0aW9uICsgMjQgPCB0b2tlbml6ZXIuZmlsZUluZm8uc2l6ZSkge1xuXHRcdFx0XHRjb25zdCBoZWFkZXIgPSBhd2FpdCByZWFkSGVhZGVyKCk7XG5cdFx0XHRcdGxldCBwYXlsb2FkID0gaGVhZGVyLnNpemUgLSAyNDtcblx0XHRcdFx0aWYgKF9jaGVjayhoZWFkZXIuaWQsIFsweDkxLCAweDA3LCAweERDLCAweEI3LCAweEI3LCAweEE5LCAweENGLCAweDExLCAweDhFLCAweEU2LCAweDAwLCAweEMwLCAweDBDLCAweDIwLCAweDUzLCAweDY1XSkpIHtcblx0XHRcdFx0XHQvLyBTeW5jIG9uIFN0cmVhbS1Qcm9wZXJ0aWVzLU9iamVjdCAoQjdEQzA3OTEtQTlCNy0xMUNGLThFRTYtMDBDMDBDMjA1MzY1KVxuXHRcdFx0XHRcdGNvbnN0IHR5cGVJZCA9IEJ1ZmZlci5hbGxvYygxNik7XG5cdFx0XHRcdFx0cGF5bG9hZCAtPSBhd2FpdCB0b2tlbml6ZXIucmVhZEJ1ZmZlcih0eXBlSWQpO1xuXG5cdFx0XHRcdFx0aWYgKF9jaGVjayh0eXBlSWQsIFsweDQwLCAweDlFLCAweDY5LCAweEY4LCAweDRELCAweDVCLCAweENGLCAweDExLCAweEE4LCAweEZELCAweDAwLCAweDgwLCAweDVGLCAweDVDLCAweDQ0LCAweDJCXSkpIHtcblx0XHRcdFx0XHRcdC8vIEZvdW5kIGF1ZGlvOlxuXHRcdFx0XHRcdFx0cmV0dXJuIHtcblx0XHRcdFx0XHRcdFx0ZXh0OiAnYXNmJyxcblx0XHRcdFx0XHRcdFx0bWltZTogJ2F1ZGlvL3gtbXMtYXNmJyxcblx0XHRcdFx0XHRcdH07XG5cdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0aWYgKF9jaGVjayh0eXBlSWQsIFsweEMwLCAweEVGLCAweDE5LCAweEJDLCAweDRELCAweDVCLCAweENGLCAweDExLCAweEE4LCAweEZELCAweDAwLCAweDgwLCAweDVGLCAweDVDLCAweDQ0LCAweDJCXSkpIHtcblx0XHRcdFx0XHRcdC8vIEZvdW5kIHZpZGVvOlxuXHRcdFx0XHRcdFx0cmV0dXJuIHtcblx0XHRcdFx0XHRcdFx0ZXh0OiAnYXNmJyxcblx0XHRcdFx0XHRcdFx0bWltZTogJ3ZpZGVvL3gtbXMtYXNmJyxcblx0XHRcdFx0XHRcdH07XG5cdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHRcdH1cblxuXHRcdFx0XHRhd2FpdCB0b2tlbml6ZXIuaWdub3JlKHBheWxvYWQpO1xuXHRcdFx0fVxuXG5cdFx0XHQvLyBEZWZhdWx0IHRvIEFTRiBnZW5lcmljIGV4dGVuc2lvblxuXHRcdFx0cmV0dXJuIHtcblx0XHRcdFx0ZXh0OiAnYXNmJyxcblx0XHRcdFx0bWltZTogJ2FwcGxpY2F0aW9uL3ZuZC5tcy1hc2YnLFxuXHRcdFx0fTtcblx0XHR9XG5cblx0XHRpZiAodGhpcy5jaGVjayhbMHhBQiwgMHg0QiwgMHg1NCwgMHg1OCwgMHgyMCwgMHgzMSwgMHgzMSwgMHhCQiwgMHgwRCwgMHgwQSwgMHgxQSwgMHgwQV0pKSB7XG5cdFx0XHRyZXR1cm4ge1xuXHRcdFx0XHRleHQ6ICdrdHgnLFxuXHRcdFx0XHRtaW1lOiAnaW1hZ2Uva3R4Jyxcblx0XHRcdH07XG5cdFx0fVxuXG5cdFx0aWYgKCh0aGlzLmNoZWNrKFsweDdFLCAweDEwLCAweDA0XSkgfHwgdGhpcy5jaGVjayhbMHg3RSwgMHgxOCwgMHgwNF0pKSAmJiB0aGlzLmNoZWNrKFsweDMwLCAweDRELCAweDQ5LCAweDQ1XSwge29mZnNldDogNH0pKSB7XG5cdFx0XHRyZXR1cm4ge1xuXHRcdFx0XHRleHQ6ICdtaWUnLFxuXHRcdFx0XHRtaW1lOiAnYXBwbGljYXRpb24veC1taWUnLFxuXHRcdFx0fTtcblx0XHR9XG5cblx0XHRpZiAodGhpcy5jaGVjayhbMHgyNywgMHgwQSwgMHgwMCwgMHgwMCwgMHgwMCwgMHgwMCwgMHgwMCwgMHgwMCwgMHgwMCwgMHgwMCwgMHgwMCwgMHgwMF0sIHtvZmZzZXQ6IDJ9KSkge1xuXHRcdFx0cmV0dXJuIHtcblx0XHRcdFx0ZXh0OiAnc2hwJyxcblx0XHRcdFx0bWltZTogJ2FwcGxpY2F0aW9uL3gtZXNyaS1zaGFwZScsXG5cdFx0XHR9O1xuXHRcdH1cblxuXHRcdGlmICh0aGlzLmNoZWNrKFsweEZGLCAweDRGLCAweEZGLCAweDUxXSkpIHtcblx0XHRcdHJldHVybiB7XG5cdFx0XHRcdGV4dDogJ2oyYycsXG5cdFx0XHRcdG1pbWU6ICdpbWFnZS9qMmMnLFxuXHRcdFx0fTtcblx0XHR9XG5cblx0XHRpZiAodGhpcy5jaGVjayhbMHgwMCwgMHgwMCwgMHgwMCwgMHgwQywgMHg2QSwgMHg1MCwgMHgyMCwgMHgyMCwgMHgwRCwgMHgwQSwgMHg4NywgMHgwQV0pKSB7XG5cdFx0XHQvLyBKUEVHLTIwMDAgZmFtaWx5XG5cblx0XHRcdGF3YWl0IHRva2VuaXplci5pZ25vcmUoMjApO1xuXHRcdFx0Y29uc3QgdHlwZSA9IGF3YWl0IHRva2VuaXplci5yZWFkVG9rZW4obmV3IFRva2VuLlN0cmluZ1R5cGUoNCwgJ2FzY2lpJykpO1xuXHRcdFx0c3dpdGNoICh0eXBlKSB7XG5cdFx0XHRcdGNhc2UgJ2pwMiAnOlxuXHRcdFx0XHRcdHJldHVybiB7XG5cdFx0XHRcdFx0XHRleHQ6ICdqcDInLFxuXHRcdFx0XHRcdFx0bWltZTogJ2ltYWdlL2pwMicsXG5cdFx0XHRcdFx0fTtcblx0XHRcdFx0Y2FzZSAnanB4ICc6XG5cdFx0XHRcdFx0cmV0dXJuIHtcblx0XHRcdFx0XHRcdGV4dDogJ2pweCcsXG5cdFx0XHRcdFx0XHRtaW1lOiAnaW1hZ2UvanB4Jyxcblx0XHRcdFx0XHR9O1xuXHRcdFx0XHRjYXNlICdqcG0gJzpcblx0XHRcdFx0XHRyZXR1cm4ge1xuXHRcdFx0XHRcdFx0ZXh0OiAnanBtJyxcblx0XHRcdFx0XHRcdG1pbWU6ICdpbWFnZS9qcG0nLFxuXHRcdFx0XHRcdH07XG5cdFx0XHRcdGNhc2UgJ21qcDInOlxuXHRcdFx0XHRcdHJldHVybiB7XG5cdFx0XHRcdFx0XHRleHQ6ICdtajInLFxuXHRcdFx0XHRcdFx0bWltZTogJ2ltYWdlL21qMicsXG5cdFx0XHRcdFx0fTtcblx0XHRcdFx0ZGVmYXVsdDpcblx0XHRcdFx0XHRyZXR1cm47XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0aWYgKFxuXHRcdFx0dGhpcy5jaGVjayhbMHhGRiwgMHgwQV0pXG5cdFx0XHR8fCB0aGlzLmNoZWNrKFsweDAwLCAweDAwLCAweDAwLCAweDBDLCAweDRBLCAweDU4LCAweDRDLCAweDIwLCAweDBELCAweDBBLCAweDg3LCAweDBBXSlcblx0XHQpIHtcblx0XHRcdHJldHVybiB7XG5cdFx0XHRcdGV4dDogJ2p4bCcsXG5cdFx0XHRcdG1pbWU6ICdpbWFnZS9qeGwnLFxuXHRcdFx0fTtcblx0XHR9XG5cblx0XHRpZiAodGhpcy5jaGVjayhbMHhGRSwgMHhGRl0pKSB7IC8vIFVURi0xNi1CT00tTEVcblx0XHRcdGlmICh0aGlzLmNoZWNrKFswLCA2MCwgMCwgNjMsIDAsIDEyMCwgMCwgMTA5LCAwLCAxMDhdLCB7b2Zmc2V0OiAyfSkpIHtcblx0XHRcdFx0cmV0dXJuIHtcblx0XHRcdFx0XHRleHQ6ICd4bWwnLFxuXHRcdFx0XHRcdG1pbWU6ICdhcHBsaWNhdGlvbi94bWwnLFxuXHRcdFx0XHR9O1xuXHRcdFx0fVxuXG5cdFx0XHRyZXR1cm4gdW5kZWZpbmVkOyAvLyBTb21lIHVua25vd24gdGV4dCBiYXNlZCBmb3JtYXRcblx0XHR9XG5cblx0XHQvLyAtLSBVbnNhZmUgc2lnbmF0dXJlcyAtLVxuXG5cdFx0aWYgKFxuXHRcdFx0dGhpcy5jaGVjayhbMHgwLCAweDAsIDB4MSwgMHhCQV0pXG5cdFx0XHR8fCB0aGlzLmNoZWNrKFsweDAsIDB4MCwgMHgxLCAweEIzXSlcblx0XHQpIHtcblx0XHRcdHJldHVybiB7XG5cdFx0XHRcdGV4dDogJ21wZycsXG5cdFx0XHRcdG1pbWU6ICd2aWRlby9tcGVnJyxcblx0XHRcdH07XG5cdFx0fVxuXG5cdFx0aWYgKHRoaXMuY2hlY2soWzB4MDAsIDB4MDEsIDB4MDAsIDB4MDAsIDB4MDBdKSkge1xuXHRcdFx0cmV0dXJuIHtcblx0XHRcdFx0ZXh0OiAndHRmJyxcblx0XHRcdFx0bWltZTogJ2ZvbnQvdHRmJyxcblx0XHRcdH07XG5cdFx0fVxuXG5cdFx0aWYgKHRoaXMuY2hlY2soWzB4MDAsIDB4MDAsIDB4MDEsIDB4MDBdKSkge1xuXHRcdFx0cmV0dXJuIHtcblx0XHRcdFx0ZXh0OiAnaWNvJyxcblx0XHRcdFx0bWltZTogJ2ltYWdlL3gtaWNvbicsXG5cdFx0XHR9O1xuXHRcdH1cblxuXHRcdGlmICh0aGlzLmNoZWNrKFsweDAwLCAweDAwLCAweDAyLCAweDAwXSkpIHtcblx0XHRcdHJldHVybiB7XG5cdFx0XHRcdGV4dDogJ2N1cicsXG5cdFx0XHRcdG1pbWU6ICdpbWFnZS94LWljb24nLFxuXHRcdFx0fTtcblx0XHR9XG5cblx0XHRpZiAodGhpcy5jaGVjayhbMHhEMCwgMHhDRiwgMHgxMSwgMHhFMCwgMHhBMSwgMHhCMSwgMHgxQSwgMHhFMV0pKSB7XG5cdFx0XHQvLyBEZXRlY3RlZCBNaWNyb3NvZnQgQ29tcG91bmQgRmlsZSBCaW5hcnkgRmlsZSAoTVMtQ0ZCKSBGb3JtYXQuXG5cdFx0XHRyZXR1cm4ge1xuXHRcdFx0XHRleHQ6ICdjZmInLFxuXHRcdFx0XHRtaW1lOiAnYXBwbGljYXRpb24veC1jZmInLFxuXHRcdFx0fTtcblx0XHR9XG5cblx0XHQvLyBJbmNyZWFzZSBzYW1wbGUgc2l6ZSBmcm9tIDEyIHRvIDI1Ni5cblx0XHRhd2FpdCB0b2tlbml6ZXIucGVla0J1ZmZlcih0aGlzLmJ1ZmZlciwge2xlbmd0aDogTWF0aC5taW4oMjU2LCB0b2tlbml6ZXIuZmlsZUluZm8uc2l6ZSksIG1heUJlTGVzczogdHJ1ZX0pO1xuXG5cdFx0Ly8gLS0gMTUtYnl0ZSBzaWduYXR1cmVzIC0tXG5cblx0XHRpZiAodGhpcy5jaGVja1N0cmluZygnQkVHSU46JykpIHtcblx0XHRcdGlmICh0aGlzLmNoZWNrU3RyaW5nKCdWQ0FSRCcsIHtvZmZzZXQ6IDZ9KSkge1xuXHRcdFx0XHRyZXR1cm4ge1xuXHRcdFx0XHRcdGV4dDogJ3ZjZicsXG5cdFx0XHRcdFx0bWltZTogJ3RleHQvdmNhcmQnLFxuXHRcdFx0XHR9O1xuXHRcdFx0fVxuXG5cdFx0XHRpZiAodGhpcy5jaGVja1N0cmluZygnVkNBTEVOREFSJywge29mZnNldDogNn0pKSB7XG5cdFx0XHRcdHJldHVybiB7XG5cdFx0XHRcdFx0ZXh0OiAnaWNzJyxcblx0XHRcdFx0XHRtaW1lOiAndGV4dC9jYWxlbmRhcicsXG5cdFx0XHRcdH07XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0Ly8gYHJhZmAgaXMgaGVyZSBqdXN0IHRvIGtlZXAgYWxsIHRoZSByYXcgaW1hZ2UgZGV0ZWN0b3JzIHRvZ2V0aGVyLlxuXHRcdGlmICh0aGlzLmNoZWNrU3RyaW5nKCdGVUpJRklMTUNDRC1SQVcnKSkge1xuXHRcdFx0cmV0dXJuIHtcblx0XHRcdFx0ZXh0OiAncmFmJyxcblx0XHRcdFx0bWltZTogJ2ltYWdlL3gtZnVqaWZpbG0tcmFmJyxcblx0XHRcdH07XG5cdFx0fVxuXG5cdFx0aWYgKHRoaXMuY2hlY2tTdHJpbmcoJ0V4dGVuZGVkIE1vZHVsZTonKSkge1xuXHRcdFx0cmV0dXJuIHtcblx0XHRcdFx0ZXh0OiAneG0nLFxuXHRcdFx0XHRtaW1lOiAnYXVkaW8veC14bScsXG5cdFx0XHR9O1xuXHRcdH1cblxuXHRcdGlmICh0aGlzLmNoZWNrU3RyaW5nKCdDcmVhdGl2ZSBWb2ljZSBGaWxlJykpIHtcblx0XHRcdHJldHVybiB7XG5cdFx0XHRcdGV4dDogJ3ZvYycsXG5cdFx0XHRcdG1pbWU6ICdhdWRpby94LXZvYycsXG5cdFx0XHR9O1xuXHRcdH1cblxuXHRcdGlmICh0aGlzLmNoZWNrKFsweDA0LCAweDAwLCAweDAwLCAweDAwXSkgJiYgdGhpcy5idWZmZXIubGVuZ3RoID49IDE2KSB7IC8vIFJvdWdoICYgcXVpY2sgY2hlY2sgUGlja2xlL0FTQVJcblx0XHRcdGNvbnN0IGpzb25TaXplID0gdGhpcy5idWZmZXIucmVhZFVJbnQzMkxFKDEyKTtcblx0XHRcdGlmIChqc29uU2l6ZSA+IDEyICYmIHRoaXMuYnVmZmVyLmxlbmd0aCA+PSBqc29uU2l6ZSArIDE2KSB7XG5cdFx0XHRcdHRyeSB7XG5cdFx0XHRcdFx0Y29uc3QgaGVhZGVyID0gdGhpcy5idWZmZXIuc2xpY2UoMTYsIGpzb25TaXplICsgMTYpLnRvU3RyaW5nKCk7XG5cdFx0XHRcdFx0Y29uc3QganNvbiA9IEpTT04ucGFyc2UoaGVhZGVyKTtcblx0XHRcdFx0XHQvLyBDaGVjayBpZiBQaWNrbGUgaXMgQVNBUlxuXHRcdFx0XHRcdGlmIChqc29uLmZpbGVzKSB7IC8vIEZpbmFsIGNoZWNrLCBhc3N1cmluZyBQaWNrbGUvQVNBUiBmb3JtYXRcblx0XHRcdFx0XHRcdHJldHVybiB7XG5cdFx0XHRcdFx0XHRcdGV4dDogJ2FzYXInLFxuXHRcdFx0XHRcdFx0XHRtaW1lOiAnYXBwbGljYXRpb24veC1hc2FyJyxcblx0XHRcdFx0XHRcdH07XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9IGNhdGNoIHt9XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0aWYgKHRoaXMuY2hlY2soWzB4MDYsIDB4MEUsIDB4MkIsIDB4MzQsIDB4MDIsIDB4MDUsIDB4MDEsIDB4MDEsIDB4MEQsIDB4MDEsIDB4MDIsIDB4MDEsIDB4MDEsIDB4MDJdKSkge1xuXHRcdFx0cmV0dXJuIHtcblx0XHRcdFx0ZXh0OiAnbXhmJyxcblx0XHRcdFx0bWltZTogJ2FwcGxpY2F0aW9uL214ZicsXG5cdFx0XHR9O1xuXHRcdH1cblxuXHRcdGlmICh0aGlzLmNoZWNrU3RyaW5nKCdTQ1JNJywge29mZnNldDogNDR9KSkge1xuXHRcdFx0cmV0dXJuIHtcblx0XHRcdFx0ZXh0OiAnczNtJyxcblx0XHRcdFx0bWltZTogJ2F1ZGlvL3gtczNtJyxcblx0XHRcdH07XG5cdFx0fVxuXG5cdFx0Ly8gUmF3IE1QRUctMiB0cmFuc3BvcnQgc3RyZWFtICgxODgtYnl0ZSBwYWNrZXRzKVxuXHRcdGlmICh0aGlzLmNoZWNrKFsweDQ3XSkgJiYgdGhpcy5jaGVjayhbMHg0N10sIHtvZmZzZXQ6IDE4OH0pKSB7XG5cdFx0XHRyZXR1cm4ge1xuXHRcdFx0XHRleHQ6ICdtdHMnLFxuXHRcdFx0XHRtaW1lOiAndmlkZW8vbXAydCcsXG5cdFx0XHR9O1xuXHRcdH1cblxuXHRcdC8vIEJsdS1yYXkgRGlzYyBBdWRpby1WaWRlbyAoQkRBVikgTVBFRy0yIHRyYW5zcG9ydCBzdHJlYW0gaGFzIDQtYnl0ZSBUUF9leHRyYV9oZWFkZXIgYmVmb3JlIGVhY2ggMTg4LWJ5dGUgcGFja2V0XG5cdFx0aWYgKHRoaXMuY2hlY2soWzB4NDddLCB7b2Zmc2V0OiA0fSkgJiYgdGhpcy5jaGVjayhbMHg0N10sIHtvZmZzZXQ6IDE5Nn0pKSB7XG5cdFx0XHRyZXR1cm4ge1xuXHRcdFx0XHRleHQ6ICdtdHMnLFxuXHRcdFx0XHRtaW1lOiAndmlkZW8vbXAydCcsXG5cdFx0XHR9O1xuXHRcdH1cblxuXHRcdGlmICh0aGlzLmNoZWNrKFsweDQyLCAweDRGLCAweDRGLCAweDRCLCAweDRELCAweDRGLCAweDQyLCAweDQ5XSwge29mZnNldDogNjB9KSkge1xuXHRcdFx0cmV0dXJuIHtcblx0XHRcdFx0ZXh0OiAnbW9iaScsXG5cdFx0XHRcdG1pbWU6ICdhcHBsaWNhdGlvbi94LW1vYmlwb2NrZXQtZWJvb2snLFxuXHRcdFx0fTtcblx0XHR9XG5cblx0XHRpZiAodGhpcy5jaGVjayhbMHg0NCwgMHg0OSwgMHg0MywgMHg0RF0sIHtvZmZzZXQ6IDEyOH0pKSB7XG5cdFx0XHRyZXR1cm4ge1xuXHRcdFx0XHRleHQ6ICdkY20nLFxuXHRcdFx0XHRtaW1lOiAnYXBwbGljYXRpb24vZGljb20nLFxuXHRcdFx0fTtcblx0XHR9XG5cblx0XHRpZiAodGhpcy5jaGVjayhbMHg0QywgMHgwMCwgMHgwMCwgMHgwMCwgMHgwMSwgMHgxNCwgMHgwMiwgMHgwMCwgMHgwMCwgMHgwMCwgMHgwMCwgMHgwMCwgMHhDMCwgMHgwMCwgMHgwMCwgMHgwMCwgMHgwMCwgMHgwMCwgMHgwMCwgMHg0Nl0pKSB7XG5cdFx0XHRyZXR1cm4ge1xuXHRcdFx0XHRleHQ6ICdsbmsnLFxuXHRcdFx0XHRtaW1lOiAnYXBwbGljYXRpb24veC5tcy5zaG9ydGN1dCcsIC8vIEludmVudGVkIGJ5IHVzXG5cdFx0XHR9O1xuXHRcdH1cblxuXHRcdGlmICh0aGlzLmNoZWNrKFsweDYyLCAweDZGLCAweDZGLCAweDZCLCAweDAwLCAweDAwLCAweDAwLCAweDAwLCAweDZELCAweDYxLCAweDcyLCAweDZCLCAweDAwLCAweDAwLCAweDAwLCAweDAwXSkpIHtcblx0XHRcdHJldHVybiB7XG5cdFx0XHRcdGV4dDogJ2FsaWFzJyxcblx0XHRcdFx0bWltZTogJ2FwcGxpY2F0aW9uL3guYXBwbGUuYWxpYXMnLCAvLyBJbnZlbnRlZCBieSB1c1xuXHRcdFx0fTtcblx0XHR9XG5cblx0XHRpZiAoXG5cdFx0XHR0aGlzLmNoZWNrKFsweDRDLCAweDUwXSwge29mZnNldDogMzR9KVxuXHRcdFx0JiYgKFxuXHRcdFx0XHR0aGlzLmNoZWNrKFsweDAwLCAweDAwLCAweDAxXSwge29mZnNldDogOH0pXG5cdFx0XHRcdHx8IHRoaXMuY2hlY2soWzB4MDEsIDB4MDAsIDB4MDJdLCB7b2Zmc2V0OiA4fSlcblx0XHRcdFx0fHwgdGhpcy5jaGVjayhbMHgwMiwgMHgwMCwgMHgwMl0sIHtvZmZzZXQ6IDh9KVxuXHRcdFx0KVxuXHRcdCkge1xuXHRcdFx0cmV0dXJuIHtcblx0XHRcdFx0ZXh0OiAnZW90Jyxcblx0XHRcdFx0bWltZTogJ2FwcGxpY2F0aW9uL3ZuZC5tcy1mb250b2JqZWN0Jyxcblx0XHRcdH07XG5cdFx0fVxuXG5cdFx0aWYgKHRoaXMuY2hlY2soWzB4MDYsIDB4MDYsIDB4RUQsIDB4RjUsIDB4RDgsIDB4MUQsIDB4NDYsIDB4RTUsIDB4QkQsIDB4MzEsIDB4RUYsIDB4RTcsIDB4RkUsIDB4NzQsIDB4QjcsIDB4MURdKSkge1xuXHRcdFx0cmV0dXJuIHtcblx0XHRcdFx0ZXh0OiAnaW5kZCcsXG5cdFx0XHRcdG1pbWU6ICdhcHBsaWNhdGlvbi94LWluZGVzaWduJyxcblx0XHRcdH07XG5cdFx0fVxuXG5cdFx0Ly8gSW5jcmVhc2Ugc2FtcGxlIHNpemUgZnJvbSAyNTYgdG8gNTEyXG5cdFx0YXdhaXQgdG9rZW5pemVyLnBlZWtCdWZmZXIodGhpcy5idWZmZXIsIHtsZW5ndGg6IE1hdGgubWluKDUxMiwgdG9rZW5pemVyLmZpbGVJbmZvLnNpemUpLCBtYXlCZUxlc3M6IHRydWV9KTtcblxuXHRcdC8vIFJlcXVpcmVzIGEgYnVmZmVyIHNpemUgb2YgNTEyIGJ5dGVzXG5cdFx0aWYgKHRhckhlYWRlckNoZWNrc3VtTWF0Y2hlcyh0aGlzLmJ1ZmZlcikpIHtcblx0XHRcdHJldHVybiB7XG5cdFx0XHRcdGV4dDogJ3RhcicsXG5cdFx0XHRcdG1pbWU6ICdhcHBsaWNhdGlvbi94LXRhcicsXG5cdFx0XHR9O1xuXHRcdH1cblxuXHRcdGlmICh0aGlzLmNoZWNrKFsweEZGLCAweEZFXSkpIHsgLy8gVVRGLTE2LUJPTS1CRVxuXHRcdFx0aWYgKHRoaXMuY2hlY2soWzYwLCAwLCA2MywgMCwgMTIwLCAwLCAxMDksIDAsIDEwOCwgMF0sIHtvZmZzZXQ6IDJ9KSkge1xuXHRcdFx0XHRyZXR1cm4ge1xuXHRcdFx0XHRcdGV4dDogJ3htbCcsXG5cdFx0XHRcdFx0bWltZTogJ2FwcGxpY2F0aW9uL3htbCcsXG5cdFx0XHRcdH07XG5cdFx0XHR9XG5cblx0XHRcdGlmICh0aGlzLmNoZWNrKFsweEZGLCAweDBFLCAweDUzLCAweDAwLCAweDZCLCAweDAwLCAweDY1LCAweDAwLCAweDc0LCAweDAwLCAweDYzLCAweDAwLCAweDY4LCAweDAwLCAweDU1LCAweDAwLCAweDcwLCAweDAwLCAweDIwLCAweDAwLCAweDRELCAweDAwLCAweDZGLCAweDAwLCAweDY0LCAweDAwLCAweDY1LCAweDAwLCAweDZDLCAweDAwXSwge29mZnNldDogMn0pKSB7XG5cdFx0XHRcdHJldHVybiB7XG5cdFx0XHRcdFx0ZXh0OiAnc2twJyxcblx0XHRcdFx0XHRtaW1lOiAnYXBwbGljYXRpb24vdm5kLnNrZXRjaHVwLnNrcCcsXG5cdFx0XHRcdH07XG5cdFx0XHR9XG5cblx0XHRcdHJldHVybiB1bmRlZmluZWQ7IC8vIFNvbWUgdGV4dCBiYXNlZCBmb3JtYXRcblx0XHR9XG5cblx0XHRpZiAodGhpcy5jaGVja1N0cmluZygnLS0tLS1CRUdJTiBQR1AgTUVTU0FHRS0tLS0tJykpIHtcblx0XHRcdHJldHVybiB7XG5cdFx0XHRcdGV4dDogJ3BncCcsXG5cdFx0XHRcdG1pbWU6ICdhcHBsaWNhdGlvbi9wZ3AtZW5jcnlwdGVkJyxcblx0XHRcdH07XG5cdFx0fVxuXG5cdFx0Ly8gQ2hlY2sgTVBFRyAxIG9yIDIgTGF5ZXIgMyBoZWFkZXIsIG9yICdsYXllciAwJyBmb3IgQURUUyAoTVBFRyBzeW5jLXdvcmQgMHhGRkUpXG5cdFx0aWYgKHRoaXMuYnVmZmVyLmxlbmd0aCA+PSAyICYmIHRoaXMuY2hlY2soWzB4RkYsIDB4RTBdLCB7b2Zmc2V0OiAwLCBtYXNrOiBbMHhGRiwgMHhFMF19KSkge1xuXHRcdFx0aWYgKHRoaXMuY2hlY2soWzB4MTBdLCB7b2Zmc2V0OiAxLCBtYXNrOiBbMHgxNl19KSkge1xuXHRcdFx0XHQvLyBDaGVjayBmb3IgKEFEVFMpIE1QRUctMlxuXHRcdFx0XHRpZiAodGhpcy5jaGVjayhbMHgwOF0sIHtvZmZzZXQ6IDEsIG1hc2s6IFsweDA4XX0pKSB7XG5cdFx0XHRcdFx0cmV0dXJuIHtcblx0XHRcdFx0XHRcdGV4dDogJ2FhYycsXG5cdFx0XHRcdFx0XHRtaW1lOiAnYXVkaW8vYWFjJyxcblx0XHRcdFx0XHR9O1xuXHRcdFx0XHR9XG5cblx0XHRcdFx0Ly8gTXVzdCBiZSAoQURUUykgTVBFRy00XG5cdFx0XHRcdHJldHVybiB7XG5cdFx0XHRcdFx0ZXh0OiAnYWFjJyxcblx0XHRcdFx0XHRtaW1lOiAnYXVkaW8vYWFjJyxcblx0XHRcdFx0fTtcblx0XHRcdH1cblxuXHRcdFx0Ly8gTVBFRyAxIG9yIDIgTGF5ZXIgMyBoZWFkZXJcblx0XHRcdC8vIENoZWNrIGZvciBNUEVHIGxheWVyIDNcblx0XHRcdGlmICh0aGlzLmNoZWNrKFsweDAyXSwge29mZnNldDogMSwgbWFzazogWzB4MDZdfSkpIHtcblx0XHRcdFx0cmV0dXJuIHtcblx0XHRcdFx0XHRleHQ6ICdtcDMnLFxuXHRcdFx0XHRcdG1pbWU6ICdhdWRpby9tcGVnJyxcblx0XHRcdFx0fTtcblx0XHRcdH1cblxuXHRcdFx0Ly8gQ2hlY2sgZm9yIE1QRUcgbGF5ZXIgMlxuXHRcdFx0aWYgKHRoaXMuY2hlY2soWzB4MDRdLCB7b2Zmc2V0OiAxLCBtYXNrOiBbMHgwNl19KSkge1xuXHRcdFx0XHRyZXR1cm4ge1xuXHRcdFx0XHRcdGV4dDogJ21wMicsXG5cdFx0XHRcdFx0bWltZTogJ2F1ZGlvL21wZWcnLFxuXHRcdFx0XHR9O1xuXHRcdFx0fVxuXG5cdFx0XHQvLyBDaGVjayBmb3IgTVBFRyBsYXllciAxXG5cdFx0XHRpZiAodGhpcy5jaGVjayhbMHgwNl0sIHtvZmZzZXQ6IDEsIG1hc2s6IFsweDA2XX0pKSB7XG5cdFx0XHRcdHJldHVybiB7XG5cdFx0XHRcdFx0ZXh0OiAnbXAxJyxcblx0XHRcdFx0XHRtaW1lOiAnYXVkaW8vbXBlZycsXG5cdFx0XHRcdH07XG5cdFx0XHR9XG5cdFx0fVxuXHR9XG5cblx0YXN5bmMgcmVhZFRpZmZUYWcoYmlnRW5kaWFuKSB7XG5cdFx0Y29uc3QgdGFnSWQgPSBhd2FpdCB0aGlzLnRva2VuaXplci5yZWFkVG9rZW4oYmlnRW5kaWFuID8gVG9rZW4uVUlOVDE2X0JFIDogVG9rZW4uVUlOVDE2X0xFKTtcblx0XHR0aGlzLnRva2VuaXplci5pZ25vcmUoMTApO1xuXHRcdHN3aXRjaCAodGFnSWQpIHtcblx0XHRcdGNhc2UgNTBfMzQxOlxuXHRcdFx0XHRyZXR1cm4ge1xuXHRcdFx0XHRcdGV4dDogJ2FydycsXG5cdFx0XHRcdFx0bWltZTogJ2ltYWdlL3gtc29ueS1hcncnLFxuXHRcdFx0XHR9O1xuXHRcdFx0Y2FzZSA1MF83MDY6XG5cdFx0XHRcdHJldHVybiB7XG5cdFx0XHRcdFx0ZXh0OiAnZG5nJyxcblx0XHRcdFx0XHRtaW1lOiAnaW1hZ2UveC1hZG9iZS1kbmcnLFxuXHRcdFx0XHR9O1xuXHRcdFx0ZGVmYXVsdDpcblx0XHR9XG5cdH1cblxuXHRhc3luYyByZWFkVGlmZklGRChiaWdFbmRpYW4pIHtcblx0XHRjb25zdCBudW1iZXJPZlRhZ3MgPSBhd2FpdCB0aGlzLnRva2VuaXplci5yZWFkVG9rZW4oYmlnRW5kaWFuID8gVG9rZW4uVUlOVDE2X0JFIDogVG9rZW4uVUlOVDE2X0xFKTtcblx0XHRmb3IgKGxldCBuID0gMDsgbiA8IG51bWJlck9mVGFnczsgKytuKSB7XG5cdFx0XHRjb25zdCBmaWxlVHlwZSA9IGF3YWl0IHRoaXMucmVhZFRpZmZUYWcoYmlnRW5kaWFuKTtcblx0XHRcdGlmIChmaWxlVHlwZSkge1xuXHRcdFx0XHRyZXR1cm4gZmlsZVR5cGU7XG5cdFx0XHR9XG5cdFx0fVxuXHR9XG5cblx0YXN5bmMgcmVhZFRpZmZIZWFkZXIoYmlnRW5kaWFuKSB7XG5cdFx0Y29uc3QgdmVyc2lvbiA9IChiaWdFbmRpYW4gPyBUb2tlbi5VSU5UMTZfQkUgOiBUb2tlbi5VSU5UMTZfTEUpLmdldCh0aGlzLmJ1ZmZlciwgMik7XG5cdFx0Y29uc3QgaWZkT2Zmc2V0ID0gKGJpZ0VuZGlhbiA/IFRva2VuLlVJTlQzMl9CRSA6IFRva2VuLlVJTlQzMl9MRSkuZ2V0KHRoaXMuYnVmZmVyLCA0KTtcblxuXHRcdGlmICh2ZXJzaW9uID09PSA0Mikge1xuXHRcdFx0Ly8gVElGRiBmaWxlIGhlYWRlclxuXHRcdFx0aWYgKGlmZE9mZnNldCA+PSA2KSB7XG5cdFx0XHRcdGlmICh0aGlzLmNoZWNrU3RyaW5nKCdDUicsIHtvZmZzZXQ6IDh9KSkge1xuXHRcdFx0XHRcdHJldHVybiB7XG5cdFx0XHRcdFx0XHRleHQ6ICdjcjInLFxuXHRcdFx0XHRcdFx0bWltZTogJ2ltYWdlL3gtY2Fub24tY3IyJyxcblx0XHRcdFx0XHR9O1xuXHRcdFx0XHR9XG5cblx0XHRcdFx0aWYgKGlmZE9mZnNldCA+PSA4ICYmICh0aGlzLmNoZWNrKFsweDFDLCAweDAwLCAweEZFLCAweDAwXSwge29mZnNldDogOH0pIHx8IHRoaXMuY2hlY2soWzB4MUYsIDB4MDAsIDB4MEIsIDB4MDBdLCB7b2Zmc2V0OiA4fSkpKSB7XG5cdFx0XHRcdFx0cmV0dXJuIHtcblx0XHRcdFx0XHRcdGV4dDogJ25lZicsXG5cdFx0XHRcdFx0XHRtaW1lOiAnaW1hZ2UveC1uaWtvbi1uZWYnLFxuXHRcdFx0XHRcdH07XG5cdFx0XHRcdH1cblx0XHRcdH1cblxuXHRcdFx0YXdhaXQgdGhpcy50b2tlbml6ZXIuaWdub3JlKGlmZE9mZnNldCk7XG5cdFx0XHRjb25zdCBmaWxlVHlwZSA9IGF3YWl0IHRoaXMucmVhZFRpZmZJRkQoYmlnRW5kaWFuKTtcblx0XHRcdHJldHVybiBmaWxlVHlwZSA/PyB7XG5cdFx0XHRcdGV4dDogJ3RpZicsXG5cdFx0XHRcdG1pbWU6ICdpbWFnZS90aWZmJyxcblx0XHRcdH07XG5cdFx0fVxuXG5cdFx0aWYgKHZlcnNpb24gPT09IDQzKSB7XHQvLyBCaWcgVElGRiBmaWxlIGhlYWRlclxuXHRcdFx0cmV0dXJuIHtcblx0XHRcdFx0ZXh0OiAndGlmJyxcblx0XHRcdFx0bWltZTogJ2ltYWdlL3RpZmYnLFxuXHRcdFx0fTtcblx0XHR9XG5cdH1cbn1cblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGZpbGVUeXBlU3RyZWFtKHJlYWRhYmxlU3RyZWFtLCB7c2FtcGxlU2l6ZSA9IG1pbmltdW1CeXRlc30gPSB7fSkge1xuXHRjb25zdCB7ZGVmYXVsdDogc3RyZWFtfSA9IGF3YWl0IGltcG9ydCgnbm9kZTpzdHJlYW0nKTtcblxuXHRyZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuXHRcdHJlYWRhYmxlU3RyZWFtLm9uKCdlcnJvcicsIHJlamVjdCk7XG5cblx0XHRyZWFkYWJsZVN0cmVhbS5vbmNlKCdyZWFkYWJsZScsICgpID0+IHtcblx0XHRcdChhc3luYyAoKSA9PiB7XG5cdFx0XHRcdHRyeSB7XG5cdFx0XHRcdFx0Ly8gU2V0IHVwIG91dHB1dCBzdHJlYW1cblx0XHRcdFx0XHRjb25zdCBwYXNzID0gbmV3IHN0cmVhbS5QYXNzVGhyb3VnaCgpO1xuXHRcdFx0XHRcdGNvbnN0IG91dHB1dFN0cmVhbSA9IHN0cmVhbS5waXBlbGluZSA/IHN0cmVhbS5waXBlbGluZShyZWFkYWJsZVN0cmVhbSwgcGFzcywgKCkgPT4ge30pIDogcmVhZGFibGVTdHJlYW0ucGlwZShwYXNzKTtcblxuXHRcdFx0XHRcdC8vIFJlYWQgdGhlIGlucHV0IHN0cmVhbSBhbmQgZGV0ZWN0IHRoZSBmaWxldHlwZVxuXHRcdFx0XHRcdGNvbnN0IGNodW5rID0gcmVhZGFibGVTdHJlYW0ucmVhZChzYW1wbGVTaXplKSA/PyByZWFkYWJsZVN0cmVhbS5yZWFkKCkgPz8gQnVmZmVyLmFsbG9jKDApO1xuXHRcdFx0XHRcdHRyeSB7XG5cdFx0XHRcdFx0XHRjb25zdCBmaWxlVHlwZSA9IGF3YWl0IGZpbGVUeXBlRnJvbUJ1ZmZlcihjaHVuayk7XG5cdFx0XHRcdFx0XHRwYXNzLmZpbGVUeXBlID0gZmlsZVR5cGU7XG5cdFx0XHRcdFx0fSBjYXRjaCAoZXJyb3IpIHtcblx0XHRcdFx0XHRcdGlmIChlcnJvciBpbnN0YW5jZW9mIHN0cnRvazMuRW5kT2ZTdHJlYW1FcnJvcikge1xuXHRcdFx0XHRcdFx0XHRwYXNzLmZpbGVUeXBlID0gdW5kZWZpbmVkO1xuXHRcdFx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRcdFx0cmVqZWN0KGVycm9yKTtcblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHRyZXNvbHZlKG91dHB1dFN0cmVhbSk7XG5cdFx0XHRcdH0gY2F0Y2ggKGVycm9yKSB7XG5cdFx0XHRcdFx0cmVqZWN0KGVycm9yKTtcblx0XHRcdFx0fVxuXHRcdFx0fSkoKTtcblx0XHR9KTtcblx0fSk7XG59XG5cbmV4cG9ydCBjb25zdCBzdXBwb3J0ZWRFeHRlbnNpb25zID0gbmV3IFNldChleHRlbnNpb25zKTtcbmV4cG9ydCBjb25zdCBzdXBwb3J0ZWRNaW1lVHlwZXMgPSBuZXcgU2V0KG1pbWVUeXBlcyk7XG4iLCJpbXBvcnQge2ZpbGVUeXBlRnJvbUJ1ZmZlcn0gZnJvbSAnZmlsZS10eXBlJztcblxuY29uc3QgaW1hZ2VFeHRlbnNpb25zID0gbmV3IFNldChbXG5cdCdqcGcnLFxuXHQncG5nJyxcblx0J2dpZicsXG5cdCd3ZWJwJyxcblx0J2ZsaWYnLFxuXHQnY3IyJyxcblx0J3RpZicsXG5cdCdibXAnLFxuXHQnanhyJyxcblx0J3BzZCcsXG5cdCdpY28nLFxuXHQnYnBnJyxcblx0J2pwMicsXG5cdCdqcG0nLFxuXHQnanB4Jyxcblx0J2hlaWMnLFxuXHQnY3VyJyxcblx0J2RjbScsXG5cdCdhdmlmJyxcbl0pO1xuXG5leHBvcnQgZGVmYXVsdCBhc3luYyBmdW5jdGlvbiBpbWFnZVR5cGUoaW5wdXQpIHtcblx0Y29uc3QgcmVzdWx0ID0gYXdhaXQgZmlsZVR5cGVGcm9tQnVmZmVyKGlucHV0KTtcblx0cmV0dXJuIGltYWdlRXh0ZW5zaW9ucy5oYXMocmVzdWx0Py5leHQpICYmIHJlc3VsdDtcbn1cblxuZXhwb3J0IGNvbnN0IG1pbmltdW1CeXRlcyA9IDQxMDA7XG4iLCJpbXBvcnQgeyByZXNvbHZlLCBleHRuYW1lLCByZWxhdGl2ZSwgam9pbiwgcGFyc2UsIHBvc2l4IH0gZnJvbSBcInBhdGhcIjtcbmltcG9ydCB7IFJlYWRhYmxlIH0gZnJvbSBcInN0cmVhbVwiO1xuaW1wb3J0IHsgY2xpcGJvYXJkIH0gZnJvbSBcImVsZWN0cm9uXCI7XG5cbmV4cG9ydCBpbnRlcmZhY2UgSVN0cmluZ0tleU1hcDxUPiB7XG4gIFtrZXk6IHN0cmluZ106IFQ7XG59XG5cbmNvbnN0IElNQUdFX0VYVF9MSVNUID0gW1xuICBcIi5wbmdcIixcbiAgXCIuanBnXCIsXG4gIFwiLmpwZWdcIixcbiAgXCIuYm1wXCIsXG4gIFwiLmdpZlwiLFxuICBcIi5zdmdcIixcbiAgXCIudGlmZlwiLFxuICBcIi53ZWJwXCIsXG4gIFwiLmF2aWZcIixcbl07XG5cbmV4cG9ydCBmdW5jdGlvbiBpc0FuSW1hZ2UoZXh0OiBzdHJpbmcpIHtcbiAgcmV0dXJuIElNQUdFX0VYVF9MSVNULmluY2x1ZGVzKGV4dC50b0xvd2VyQ2FzZSgpKTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBpc0Fzc2V0VHlwZUFuSW1hZ2UocGF0aDogc3RyaW5nKTogQm9vbGVhbiB7XG4gIHJldHVybiBpc0FuSW1hZ2UoZXh0bmFtZShwYXRoKSk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRPUygpIHtcbiAgY29uc3QgeyBhcHBWZXJzaW9uIH0gPSBuYXZpZ2F0b3I7XG4gIGlmIChhcHBWZXJzaW9uLmluZGV4T2YoXCJXaW5cIikgIT09IC0xKSB7XG4gICAgcmV0dXJuIFwiV2luZG93c1wiO1xuICB9IGVsc2UgaWYgKGFwcFZlcnNpb24uaW5kZXhPZihcIk1hY1wiKSAhPT0gLTEpIHtcbiAgICByZXR1cm4gXCJNYWNPU1wiO1xuICB9IGVsc2UgaWYgKGFwcFZlcnNpb24uaW5kZXhPZihcIlgxMVwiKSAhPT0gLTEpIHtcbiAgICByZXR1cm4gXCJMaW51eFwiO1xuICB9IGVsc2Uge1xuICAgIHJldHVybiBcIlVua25vd24gT1NcIjtcbiAgfVxufVxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHN0cmVhbVRvU3RyaW5nKHN0cmVhbTogUmVhZGFibGUpIHtcbiAgY29uc3QgY2h1bmtzID0gW107XG5cbiAgZm9yIGF3YWl0IChjb25zdCBjaHVuayBvZiBzdHJlYW0pIHtcbiAgICBjaHVua3MucHVzaChCdWZmZXIuZnJvbShjaHVuaykpO1xuICB9XG5cbiAgcmV0dXJuIEJ1ZmZlci5jb25jYXQoY2h1bmtzKS50b1N0cmluZyhcInV0Zi04XCIpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZ2V0VXJsQXNzZXQodXJsOiBzdHJpbmcpIHtcbiAgcmV0dXJuICh1cmwgPSB1cmwuc3Vic3RyKDEgKyB1cmwubGFzdEluZGV4T2YoXCIvXCIpKS5zcGxpdChcIj9cIilbMF0pLnNwbGl0KFxuICAgIFwiI1wiXG4gIClbMF07XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBpc0NvcHlJbWFnZUZpbGUoKSB7XG4gIGxldCBmaWxlUGF0aCA9IFwiXCI7XG4gIGNvbnN0IG9zID0gZ2V0T1MoKTtcblxuICBpZiAob3MgPT09IFwiV2luZG93c1wiKSB7XG4gICAgdmFyIHJhd0ZpbGVQYXRoID0gY2xpcGJvYXJkLnJlYWQoXCJGaWxlTmFtZVdcIik7XG4gICAgZmlsZVBhdGggPSByYXdGaWxlUGF0aC5yZXBsYWNlKG5ldyBSZWdFeHAoU3RyaW5nLmZyb21DaGFyQ29kZSgwKSwgXCJnXCIpLCBcIlwiKTtcbiAgfSBlbHNlIGlmIChvcyA9PT0gXCJNYWNPU1wiKSB7XG4gICAgZmlsZVBhdGggPSBjbGlwYm9hcmQucmVhZChcInB1YmxpYy5maWxlLXVybFwiKS5yZXBsYWNlKFwiZmlsZTovL1wiLCBcIlwiKTtcbiAgfSBlbHNlIHtcbiAgICBmaWxlUGF0aCA9IFwiXCI7XG4gIH1cbiAgcmV0dXJuIGlzQXNzZXRUeXBlQW5JbWFnZShmaWxlUGF0aCk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRMYXN0SW1hZ2UobGlzdDogc3RyaW5nW10pIHtcbiAgY29uc3QgcmV2ZXJzZWRMaXN0ID0gbGlzdC5yZXZlcnNlKCk7XG4gIGxldCBsYXN0SW1hZ2U7XG4gIHJldmVyc2VkTGlzdC5mb3JFYWNoKGl0ZW0gPT4ge1xuICAgIGlmIChpdGVtICYmIGl0ZW0uc3RhcnRzV2l0aChcImh0dHBcIikpIHtcbiAgICAgIGxhc3RJbWFnZSA9IGl0ZW07XG4gICAgICByZXR1cm4gaXRlbTtcbiAgICB9XG4gIH0pO1xuICByZXR1cm4gbGFzdEltYWdlO1xufVxuXG5pbnRlcmZhY2UgQW55T2JqIHtcbiAgW2tleTogc3RyaW5nXTogYW55O1xufVxuXG5leHBvcnQgZnVuY3Rpb24gYXJyYXlUb09iamVjdDxUIGV4dGVuZHMgQW55T2JqPihcbiAgYXJyOiBUW10sXG4gIGtleTogc3RyaW5nXG4pOiB7IFtrZXk6IHN0cmluZ106IFQgfSB7XG4gIGNvbnN0IG9iajogeyBba2V5OiBzdHJpbmddOiBUIH0gPSB7fTtcbiAgYXJyLmZvckVhY2goZWxlbWVudCA9PiB7XG4gICAgb2JqW2VsZW1lbnRba2V5XV0gPSBlbGVtZW50O1xuICB9KTtcbiAgcmV0dXJuIG9iajtcbn1cbiIsImltcG9ydCB7IFBsdWdpblNldHRpbmdzIH0gZnJvbSBcIi4vc2V0dGluZ1wiO1xuaW1wb3J0IHsgc3RyZWFtVG9TdHJpbmcsIGdldExhc3RJbWFnZSB9IGZyb20gXCIuL3V0aWxzXCI7XG5pbXBvcnQgeyBleGVjLCBzcGF3blN5bmMsIHNwYXduIH0gZnJvbSBcImNoaWxkX3Byb2Nlc3NcIjtcbmltcG9ydCB7IE5vdGljZSwgcmVxdWVzdFVybCB9IGZyb20gXCJvYnNpZGlhblwiO1xuaW1wb3J0IGltYWdlQXV0b1VwbG9hZFBsdWdpbiBmcm9tIFwiLi9tYWluXCI7XG5cbmV4cG9ydCBpbnRlcmZhY2UgUGljR29SZXNwb25zZSB7XG4gIHN1Y2Nlc3M6IHN0cmluZztcbiAgbXNnOiBzdHJpbmc7XG4gIHJlc3VsdDogc3RyaW5nW107XG4gIGZ1bGxSZXN1bHQ6IFJlY29yZDxzdHJpbmcsIGFueT5bXTtcbn1cblxuZXhwb3J0IGNsYXNzIFBpY0dvVXBsb2FkZXIge1xuICBzZXR0aW5nczogUGx1Z2luU2V0dGluZ3M7XG4gIHBsdWdpbjogaW1hZ2VBdXRvVXBsb2FkUGx1Z2luO1xuXG4gIGNvbnN0cnVjdG9yKHNldHRpbmdzOiBQbHVnaW5TZXR0aW5ncywgcGx1Z2luOiBpbWFnZUF1dG9VcGxvYWRQbHVnaW4pIHtcbiAgICB0aGlzLnNldHRpbmdzID0gc2V0dGluZ3M7XG4gICAgdGhpcy5wbHVnaW4gPSBwbHVnaW47XG4gIH1cblxuICBhc3luYyB1cGxvYWRGaWxlcyhmaWxlTGlzdDogQXJyYXk8U3RyaW5nPik6IFByb21pc2U8YW55PiB7XG4gICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCByZXF1ZXN0VXJsKHtcbiAgICAgIHVybDogdGhpcy5zZXR0aW5ncy51cGxvYWRTZXJ2ZXIsXG4gICAgICBtZXRob2Q6IFwiUE9TVFwiLFxuICAgICAgaGVhZGVyczogeyBcIkNvbnRlbnQtVHlwZVwiOiBcImFwcGxpY2F0aW9uL2pzb25cIiB9LFxuICAgICAgYm9keTogSlNPTi5zdHJpbmdpZnkoeyBsaXN0OiBmaWxlTGlzdCB9KSxcbiAgICB9KTtcblxuICAgIGNvbnN0IGRhdGEgPSBhd2FpdCByZXNwb25zZS5qc29uO1xuXG4gICAgLy8gcGljbGlzdFxuICAgIGlmIChkYXRhLmZ1bGxSZXN1bHQpIHtcbiAgICAgIGNvbnN0IHVwbG9hZFVybEZ1bGxSZXN1bHRMaXN0ID0gZGF0YS5mdWxsUmVzdWx0IHx8IFtdO1xuICAgICAgdGhpcy5zZXR0aW5ncy51cGxvYWRlZEltYWdlcyA9IFtcbiAgICAgICAgLi4uKHRoaXMuc2V0dGluZ3MudXBsb2FkZWRJbWFnZXMgfHwgW10pLFxuICAgICAgICAuLi51cGxvYWRVcmxGdWxsUmVzdWx0TGlzdCxcbiAgICAgIF07XG4gICAgfVxuXG4gICAgcmV0dXJuIGRhdGE7XG4gIH1cblxuICBhc3luYyB1cGxvYWRGaWxlQnlDbGlwYm9hcmQoKTogUHJvbWlzZTxhbnk+IHtcbiAgICBjb25zdCByZXMgPSBhd2FpdCByZXF1ZXN0VXJsKHtcbiAgICAgIHVybDogdGhpcy5zZXR0aW5ncy51cGxvYWRTZXJ2ZXIsXG4gICAgICBtZXRob2Q6IFwiUE9TVFwiLFxuICAgIH0pO1xuXG4gICAgbGV0IGRhdGE6IFBpY0dvUmVzcG9uc2UgPSBhd2FpdCByZXMuanNvbjtcblxuICAgIC8vIHBpY2xpc3RcbiAgICBpZiAoZGF0YS5mdWxsUmVzdWx0KSB7XG4gICAgICBjb25zdCB1cGxvYWRVcmxGdWxsUmVzdWx0TGlzdCA9IGRhdGEuZnVsbFJlc3VsdCB8fCBbXTtcbiAgICAgIHRoaXMuc2V0dGluZ3MudXBsb2FkZWRJbWFnZXMgPSBbXG4gICAgICAgIC4uLih0aGlzLnNldHRpbmdzLnVwbG9hZGVkSW1hZ2VzIHx8IFtdKSxcbiAgICAgICAgLi4udXBsb2FkVXJsRnVsbFJlc3VsdExpc3QsXG4gICAgICBdO1xuICAgICAgdGhpcy5wbHVnaW4uc2F2ZVNldHRpbmdzKCk7XG4gICAgfVxuXG4gICAgaWYgKHJlcy5zdGF0dXMgIT09IDIwMCkge1xuICAgICAgbGV0IGVyciA9IHsgcmVzcG9uc2U6IGRhdGEsIGJvZHk6IGRhdGEubXNnIH07XG4gICAgICByZXR1cm4ge1xuICAgICAgICBjb2RlOiAtMSxcbiAgICAgICAgbXNnOiBkYXRhLm1zZyxcbiAgICAgICAgZGF0YTogXCJcIixcbiAgICAgIH07XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIGNvZGU6IDAsXG4gICAgICAgIG1zZzogXCJzdWNjZXNzXCIsXG4gICAgICAgIGRhdGE6IHR5cGVvZiBkYXRhLnJlc3VsdCA9PSBcInN0cmluZ1wiID8gZGF0YS5yZXN1bHQgOiBkYXRhLnJlc3VsdFswXSxcbiAgICAgIH07XG4gICAgfVxuICB9XG59XG5cbmV4cG9ydCBjbGFzcyBQaWNHb0NvcmVVcGxvYWRlciB7XG4gIHNldHRpbmdzOiBQbHVnaW5TZXR0aW5ncztcbiAgcGx1Z2luOiBpbWFnZUF1dG9VcGxvYWRQbHVnaW47XG5cbiAgY29uc3RydWN0b3Ioc2V0dGluZ3M6IFBsdWdpblNldHRpbmdzLCBwbHVnaW46IGltYWdlQXV0b1VwbG9hZFBsdWdpbikge1xuICAgIHRoaXMuc2V0dGluZ3MgPSBzZXR0aW5ncztcbiAgICB0aGlzLnBsdWdpbiA9IHBsdWdpbjtcbiAgfVxuXG4gIGFzeW5jIHVwbG9hZEZpbGVzKGZpbGVMaXN0OiBBcnJheTxTdHJpbmc+KTogUHJvbWlzZTxhbnk+IHtcbiAgICBjb25zdCBsZW5ndGggPSBmaWxlTGlzdC5sZW5ndGg7XG4gICAgbGV0IGNsaSA9IHRoaXMuc2V0dGluZ3MucGljZ29Db3JlUGF0aCB8fCBcInBpY2dvXCI7XG4gICAgbGV0IGNvbW1hbmQgPSBgJHtjbGl9IHVwbG9hZCAke2ZpbGVMaXN0XG4gICAgICAubWFwKGl0ZW0gPT4gYFwiJHtpdGVtfVwiYClcbiAgICAgIC5qb2luKFwiIFwiKX1gO1xuXG4gICAgY29uc3QgcmVzID0gYXdhaXQgdGhpcy5leGVjKGNvbW1hbmQpO1xuICAgIGNvbnN0IHNwbGl0TGlzdCA9IHJlcy5zcGxpdChcIlxcblwiKTtcbiAgICBjb25zdCBzcGxpdExpc3RMZW5ndGggPSBzcGxpdExpc3QubGVuZ3RoO1xuXG4gICAgY29uc3QgZGF0YSA9IHNwbGl0TGlzdC5zcGxpY2Uoc3BsaXRMaXN0TGVuZ3RoIC0gMSAtIGxlbmd0aCwgbGVuZ3RoKTtcblxuICAgIGlmIChyZXMuaW5jbHVkZXMoXCJQaWNHbyBFUlJPUlwiKSkge1xuICAgICAgY29uc29sZS5sb2coY29tbWFuZCwgcmVzKTtcblxuICAgICAgcmV0dXJuIHtcbiAgICAgICAgc3VjY2VzczogZmFsc2UsXG4gICAgICAgIG1zZzogXCLlpLHotKVcIixcbiAgICAgIH07XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIHN1Y2Nlc3M6IHRydWUsXG4gICAgICAgIHJlc3VsdDogZGF0YSxcbiAgICAgIH07XG4gICAgfVxuICAgIC8vIHtzdWNjZXNzOnRydWUscmVzdWx0OltdfVxuICB9XG5cbiAgLy8gUGljR28tQ29yZSDkuIrkvKDlpITnkIZcbiAgYXN5bmMgdXBsb2FkRmlsZUJ5Q2xpcGJvYXJkKCkge1xuICAgIGNvbnN0IHJlcyA9IGF3YWl0IHRoaXMudXBsb2FkQnlDbGlwKCk7XG4gICAgY29uc3Qgc3BsaXRMaXN0ID0gcmVzLnNwbGl0KFwiXFxuXCIpO1xuICAgIGNvbnN0IGxhc3RJbWFnZSA9IGdldExhc3RJbWFnZShzcGxpdExpc3QpO1xuXG4gICAgaWYgKGxhc3RJbWFnZSkge1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgY29kZTogMCxcbiAgICAgICAgbXNnOiBcInN1Y2Nlc3NcIixcbiAgICAgICAgZGF0YTogbGFzdEltYWdlLFxuICAgICAgfTtcbiAgICB9IGVsc2Uge1xuICAgICAgY29uc29sZS5sb2coc3BsaXRMaXN0KTtcblxuICAgICAgLy8gbmV3IE5vdGljZShgXCJQbGVhc2UgY2hlY2sgUGljR28tQ29yZSBjb25maWdcIlxcbiR7cmVzfWApO1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgY29kZTogLTEsXG4gICAgICAgIG1zZzogYFwiUGxlYXNlIGNoZWNrIFBpY0dvLUNvcmUgY29uZmlnXCJcXG4ke3Jlc31gLFxuICAgICAgICBkYXRhOiBcIlwiLFxuICAgICAgfTtcbiAgICB9XG4gIH1cblxuICAvLyBQaWNHby1Db3Jl55qE5Ymq5YiH5LiK5Lyg5Y+N6aaIXG4gIGFzeW5jIHVwbG9hZEJ5Q2xpcCgpIHtcbiAgICBsZXQgY29tbWFuZDtcbiAgICBpZiAodGhpcy5zZXR0aW5ncy5waWNnb0NvcmVQYXRoKSB7XG4gICAgICBjb21tYW5kID0gYCR7dGhpcy5zZXR0aW5ncy5waWNnb0NvcmVQYXRofSB1cGxvYWRgO1xuICAgIH0gZWxzZSB7XG4gICAgICBjb21tYW5kID0gYHBpY2dvIHVwbG9hZGA7XG4gICAgfVxuICAgIGNvbnN0IHJlcyA9IGF3YWl0IHRoaXMuZXhlYyhjb21tYW5kKTtcbiAgICAvLyBjb25zdCByZXMgPSBhd2FpdCB0aGlzLnNwYXduQ2hpbGQoKTtcblxuICAgIHJldHVybiByZXM7XG4gIH1cblxuICBhc3luYyBleGVjKGNvbW1hbmQ6IHN0cmluZykge1xuICAgIGxldCB7IHN0ZG91dCB9ID0gYXdhaXQgZXhlYyhjb21tYW5kKTtcbiAgICBjb25zdCByZXMgPSBhd2FpdCBzdHJlYW1Ub1N0cmluZyhzdGRvdXQpO1xuICAgIHJldHVybiByZXM7XG4gIH1cblxuICBhc3luYyBzcGF3bkNoaWxkKCkge1xuICAgIGNvbnN0IHsgc3Bhd24gfSA9IHJlcXVpcmUoXCJjaGlsZF9wcm9jZXNzXCIpO1xuICAgIGNvbnN0IGNoaWxkID0gc3Bhd24oXCJwaWNnb1wiLCBbXCJ1cGxvYWRcIl0sIHtcbiAgICAgIHNoZWxsOiB0cnVlLFxuICAgIH0pO1xuXG4gICAgbGV0IGRhdGEgPSBcIlwiO1xuICAgIGZvciBhd2FpdCAoY29uc3QgY2h1bmsgb2YgY2hpbGQuc3Rkb3V0KSB7XG4gICAgICBkYXRhICs9IGNodW5rO1xuICAgIH1cbiAgICBsZXQgZXJyb3IgPSBcIlwiO1xuICAgIGZvciBhd2FpdCAoY29uc3QgY2h1bmsgb2YgY2hpbGQuc3RkZXJyKSB7XG4gICAgICBlcnJvciArPSBjaHVuaztcbiAgICB9XG4gICAgY29uc3QgZXhpdENvZGUgPSBhd2FpdCBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICBjaGlsZC5vbihcImNsb3NlXCIsIHJlc29sdmUpO1xuICAgIH0pO1xuXG4gICAgaWYgKGV4aXRDb2RlKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYHN1YnByb2Nlc3MgZXJyb3IgZXhpdCAke2V4aXRDb2RlfSwgJHtlcnJvcn1gKTtcbiAgICB9XG4gICAgcmV0dXJuIGRhdGE7XG4gIH1cbn1cbiIsImltcG9ydCB7IElTdHJpbmdLZXlNYXAgfSBmcm9tIFwiLi91dGlsc1wiO1xuaW1wb3J0IHsgQXBwLCByZXF1ZXN0VXJsIH0gZnJvbSBcIm9ic2lkaWFuXCI7XG5pbXBvcnQgaW1hZ2VBdXRvVXBsb2FkUGx1Z2luIGZyb20gXCIuL21haW5cIjtcblxuZXhwb3J0IGNsYXNzIFBpY0dvRGVsZXRlciB7XG4gIHBsdWdpbjogaW1hZ2VBdXRvVXBsb2FkUGx1Z2luO1xuXG4gIGNvbnN0cnVjdG9yKHBsdWdpbjogaW1hZ2VBdXRvVXBsb2FkUGx1Z2luKSB7XG4gICAgdGhpcy5wbHVnaW4gPSBwbHVnaW47XG4gIH1cblxuICBhc3luYyBkZWxldGVJbWFnZShjb25maWdNYXA6IElTdHJpbmdLZXlNYXA8YW55PltdKSB7XG4gICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCByZXF1ZXN0VXJsKHtcbiAgICAgIHVybDogdGhpcy5wbHVnaW4uc2V0dGluZ3MuZGVsZXRlU2VydmVyLFxuICAgICAgbWV0aG9kOiBcIlBPU1RcIixcbiAgICAgIGhlYWRlcnM6IHsgXCJDb250ZW50LVR5cGVcIjogXCJhcHBsaWNhdGlvbi9qc29uXCIgfSxcbiAgICAgIGJvZHk6IEpTT04uc3RyaW5naWZ5KHtcbiAgICAgICAgbGlzdDogY29uZmlnTWFwLFxuICAgICAgfSksXG4gICAgfSk7XG4gICAgY29uc3QgZGF0YSA9IHJlc3BvbnNlLmpzb247XG4gICAgcmV0dXJuIGRhdGE7XG4gIH1cbn1cbiIsImltcG9ydCB7IE1hcmtkb3duVmlldywgQXBwIH0gZnJvbSBcIm9ic2lkaWFuXCI7XG5pbXBvcnQgeyBwYXJzZSB9IGZyb20gXCJwYXRoXCI7XG5cbmludGVyZmFjZSBJbWFnZSB7XG4gIHBhdGg6IHN0cmluZztcbiAgbmFtZTogc3RyaW5nO1xuICBzb3VyY2U6IHN0cmluZztcbn1cbi8vICFbXSguL2RzYS9hYS5wbmcpIGxvY2FsIGltYWdlIHNob3VsZCBoYXMgZXh0XG4vLyAhW10oaHR0cHM6Ly9kYXNkYXNkYSkgaW50ZXJuZXQgaW1hZ2Ugc2hvdWxkIG5vdCBoYXMgZXh0XG5jb25zdCBSRUdFWF9GSUxFID0gL1xcIVxcWyguKj8pXFxdXFwoKFxcUytcXC5cXHcrKVxcKXxcXCFcXFsoLio/KVxcXVxcKChodHRwcz86XFwvXFwvLio/KVxcKS9nO1xuY29uc3QgUkVHRVhfV0lLSV9GSUxFID0gL1xcIVxcW1xcWyguKj8pKFxccyo/XFx8Lio/KT9cXF1cXF0vZztcbmV4cG9ydCBkZWZhdWx0IGNsYXNzIEhlbHBlciB7XG4gIGFwcDogQXBwO1xuXG4gIGNvbnN0cnVjdG9yKGFwcDogQXBwKSB7XG4gICAgdGhpcy5hcHAgPSBhcHA7XG4gIH1cbiAgZ2V0RnJvbnRtYXR0ZXJWYWx1ZShrZXk6IHN0cmluZywgZGVmYXVsdFZhbHVlOiBhbnkgPSB1bmRlZmluZWQpIHtcbiAgICBjb25zdCBmaWxlID0gdGhpcy5hcHAud29ya3NwYWNlLmdldEFjdGl2ZUZpbGUoKTtcbiAgICBpZiAoIWZpbGUpIHtcbiAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgfVxuICAgIGNvbnN0IHBhdGggPSBmaWxlLnBhdGg7XG4gICAgY29uc3QgY2FjaGUgPSB0aGlzLmFwcC5tZXRhZGF0YUNhY2hlLmdldENhY2hlKHBhdGgpO1xuXG4gICAgbGV0IHZhbHVlID0gZGVmYXVsdFZhbHVlO1xuICAgIGlmIChjYWNoZT8uZnJvbnRtYXR0ZXIgJiYgY2FjaGUuZnJvbnRtYXR0ZXIuaGFzT3duUHJvcGVydHkoa2V5KSkge1xuICAgICAgdmFsdWUgPSBjYWNoZS5mcm9udG1hdHRlcltrZXldO1xuICAgIH1cbiAgICByZXR1cm4gdmFsdWU7XG4gIH1cblxuICBnZXRFZGl0b3IoKSB7XG4gICAgY29uc3QgbWRWaWV3ID0gdGhpcy5hcHAud29ya3NwYWNlLmdldEFjdGl2ZVZpZXdPZlR5cGUoTWFya2Rvd25WaWV3KTtcbiAgICBpZiAobWRWaWV3KSB7XG4gICAgICByZXR1cm4gbWRWaWV3LmVkaXRvcjtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuICB9XG4gIGdldFZhbHVlKCkge1xuICAgIGNvbnN0IGVkaXRvciA9IHRoaXMuZ2V0RWRpdG9yKCk7XG4gICAgcmV0dXJuIGVkaXRvci5nZXRWYWx1ZSgpO1xuICB9XG5cbiAgc2V0VmFsdWUodmFsdWU6IHN0cmluZykge1xuICAgIGNvbnN0IGVkaXRvciA9IHRoaXMuZ2V0RWRpdG9yKCk7XG4gICAgY29uc3QgeyBsZWZ0LCB0b3AgfSA9IGVkaXRvci5nZXRTY3JvbGxJbmZvKCk7XG4gICAgY29uc3QgcG9zaXRpb24gPSBlZGl0b3IuZ2V0Q3Vyc29yKCk7XG5cbiAgICBlZGl0b3Iuc2V0VmFsdWUodmFsdWUpO1xuICAgIGVkaXRvci5zY3JvbGxUbyhsZWZ0LCB0b3ApO1xuICAgIGVkaXRvci5zZXRDdXJzb3IocG9zaXRpb24pO1xuICB9XG5cbiAgLy8gZ2V0IGFsbCBmaWxlIHVybHMsIGluY2x1ZGUgbG9jYWwgYW5kIGludGVybmV0XG4gIGdldEFsbEZpbGVzKCk6IEltYWdlW10ge1xuICAgIGNvbnN0IGVkaXRvciA9IHRoaXMuZ2V0RWRpdG9yKCk7XG4gICAgbGV0IHZhbHVlID0gZWRpdG9yLmdldFZhbHVlKCk7XG4gICAgcmV0dXJuIHRoaXMuZ2V0SW1hZ2VMaW5rKHZhbHVlKTtcbiAgfVxuICBnZXRJbWFnZUxpbmsodmFsdWU6IHN0cmluZyk6IEltYWdlW10ge1xuICAgIGNvbnN0IG1hdGNoZXMgPSB2YWx1ZS5tYXRjaEFsbChSRUdFWF9GSUxFKTtcbiAgICBjb25zdCBXaWtpTWF0Y2hlcyA9IHZhbHVlLm1hdGNoQWxsKFJFR0VYX1dJS0lfRklMRSk7XG5cbiAgICBsZXQgZmlsZUFycmF5OiBJbWFnZVtdID0gW107XG5cbiAgICBmb3IgKGNvbnN0IG1hdGNoIG9mIG1hdGNoZXMpIHtcbiAgICAgIGNvbnN0IHNvdXJjZSA9IG1hdGNoWzBdO1xuXG4gICAgICBsZXQgbmFtZSA9IG1hdGNoWzFdO1xuICAgICAgbGV0IHBhdGggPSBtYXRjaFsyXTtcbiAgICAgIGlmIChuYW1lID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgbmFtZSA9IG1hdGNoWzNdO1xuICAgICAgfVxuICAgICAgaWYgKHBhdGggPT09IHVuZGVmaW5lZCkge1xuICAgICAgICBwYXRoID0gbWF0Y2hbNF07XG4gICAgICB9XG5cbiAgICAgIGZpbGVBcnJheS5wdXNoKHtcbiAgICAgICAgcGF0aDogcGF0aCxcbiAgICAgICAgbmFtZTogbmFtZSxcbiAgICAgICAgc291cmNlOiBzb3VyY2UsXG4gICAgICB9KTtcbiAgICB9XG5cbiAgICBmb3IgKGNvbnN0IG1hdGNoIG9mIFdpa2lNYXRjaGVzKSB7XG4gICAgICBjb25zb2xlLmxvZyhtYXRjaCk7XG5cbiAgICAgIGxldCBuYW1lID0gcGFyc2UobWF0Y2hbMV0pLm5hbWU7XG4gICAgICBjb25zdCBwYXRoID0gbWF0Y2hbMV07XG4gICAgICBjb25zdCBzb3VyY2UgPSBtYXRjaFswXTtcbiAgICAgIGlmIChtYXRjaFsyXSkge1xuICAgICAgICBuYW1lID0gYCR7bmFtZX0ke21hdGNoWzJdfWA7XG4gICAgICB9XG4gICAgICBmaWxlQXJyYXkucHVzaCh7XG4gICAgICAgIHBhdGg6IHBhdGgsXG4gICAgICAgIG5hbWU6IG5hbWUsXG4gICAgICAgIHNvdXJjZTogc291cmNlLFxuICAgICAgfSk7XG4gICAgfVxuICAgIGNvbnNvbGUubG9nKGZpbGVBcnJheSk7XG5cbiAgICByZXR1cm4gZmlsZUFycmF5O1xuICB9XG5cbiAgaGFzQmxhY2tEb21haW4oc3JjOiBzdHJpbmcsIGJsYWNrRG9tYWluczogc3RyaW5nKSB7XG4gICAgaWYgKGJsYWNrRG9tYWlucy50cmltKCkgPT09IFwiXCIpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgY29uc3QgYmxhY2tEb21haW5MaXN0ID0gYmxhY2tEb21haW5zLnNwbGl0KFwiLFwiKS5maWx0ZXIoaXRlbSA9PiBpdGVtICE9PSBcIlwiKTtcbiAgICBsZXQgdXJsID0gbmV3IFVSTChzcmMpO1xuICAgIGNvbnN0IGRvbWFpbiA9IHVybC5ob3N0bmFtZTtcblxuICAgIHJldHVybiBibGFja0RvbWFpbkxpc3Quc29tZShibGFja0RvbWFpbiA9PiBkb21haW4uaW5jbHVkZXMoYmxhY2tEb21haW4pKTtcbiAgfVxufVxuIiwiLy8g2KfZhNi52LHYqNmK2KlcblxuZXhwb3J0IGRlZmF1bHQge307XG4iLCIvLyDEjWXFoXRpbmFcblxuZXhwb3J0IGRlZmF1bHQge307XG4iLCIvLyBEYW5za1xuXG5leHBvcnQgZGVmYXVsdCB7fTtcbiIsIi8vIERldXRzY2hcblxuZXhwb3J0IGRlZmF1bHQge307IiwiLy8gRW5nbGlzaFxuXG5leHBvcnQgZGVmYXVsdCB7XG4gIC8vIHNldHRpbmcudHNcbiAgXCJQbHVnaW4gU2V0dGluZ3NcIjogXCJQbHVnaW4gU2V0dGluZ3NcIixcbiAgXCJBdXRvIHBhc3RlZCB1cGxvYWRcIjogXCJBdXRvIHBhc3RlZCB1cGxvYWRcIixcbiAgXCJJZiB5b3Ugc2V0IHRoaXMgdmFsdWUgdHJ1ZSwgd2hlbiB5b3UgcGFzdGUgaW1hZ2UsIGl0IHdpbGwgYmUgYXV0byB1cGxvYWRlZCh5b3Ugc2hvdWxkIHNldCB0aGUgcGljR28gc2VydmVyIHJpZ2h0bHkpXCI6XG4gICAgXCJJZiB5b3Ugc2V0IHRoaXMgdmFsdWUgdHJ1ZSwgd2hlbiB5b3UgcGFzdGUgaW1hZ2UsIGl0IHdpbGwgYmUgYXV0byB1cGxvYWRlZCh5b3Ugc2hvdWxkIHNldCB0aGUgcGljR28gc2VydmVyIHJpZ2h0bHkpXCIsXG4gIFwiRGVmYXVsdCB1cGxvYWRlclwiOiBcIkRlZmF1bHQgdXBsb2FkZXJcIixcbiAgXCJQaWNHbyBzZXJ2ZXJcIjogXCJQaWNHbyBzZXJ2ZXJcIixcbiAgXCJQbGVhc2UgaW5wdXQgUGljR28gc2VydmVyXCI6IFwiUGxlYXNlIGlucHV0IFBpY0dvIHNlcnZlclwiLFxuICBcIlBpY0dvIGRlbGV0ZSBzZXJ2ZXJcIjpcbiAgICBcIlBpY0dvIHNlcnZlciBkZWxldGUgcm91dGUoeW91IG5lZWQgdG8gdXNlIFBpY0xpc3QgYXBwKVwiLFxuICBcIlBpY0xpc3QgZGVzY1wiOiBcIlNlYXJjaCBQaWNMaXN0IG9uIEdpdGh1YiB0byBkb3dubG9hZCBhbmQgaW5zdGFsbFwiLFxuICBcIlBsZWFzZSBpbnB1dCBQaWNHbyBkZWxldGUgc2VydmVyXCI6IFwiUGxlYXNlIGlucHV0IFBpY0dvIGRlbGV0ZSBzZXJ2ZXJcIixcbiAgXCJEZWxldGUgaW1hZ2UgdXNpbmcgUGljTGlzdFwiOiBcIkRlbGV0ZSBpbWFnZSB1c2luZyBQaWNMaXN0XCIsXG4gIFwiUGljR28tQ29yZSBwYXRoXCI6IFwiUGljR28tQ29yZSBwYXRoXCIsXG4gIFwiRGVsZXRlIHN1Y2Nlc3NmdWxseVwiOiBcIkRlbGV0ZSBzdWNjZXNzZnVsbHlcIixcbiAgXCJEZWxldGUgZmFpbGVkXCI6IFwiRGVsZXRlIGZhaWxlZFwiLFxuICBcIkltYWdlIHNpemUgc3VmZml4XCI6IFwiSW1hZ2Ugc2l6ZSBzdWZmaXhcIixcbiAgXCJJbWFnZSBzaXplIHN1ZmZpeCBEZXNjcmlwdGlvblwiOiBcImxpa2UgfDMwMCBmb3IgcmVzaXplIGltYWdlIGluIG9iLlwiLFxuICBcIlBsZWFzZSBpbnB1dCBpbWFnZSBzaXplIHN1ZmZpeFwiOiBcIlBsZWFzZSBpbnB1dCBpbWFnZSBzaXplIHN1ZmZpeFwiLFxuICBcIkVycm9yLCBjb3VsZCBub3QgZGVsZXRlXCI6IFwiRXJyb3IsIGNvdWxkIG5vdCBkZWxldGVcIixcbiAgXCJQbGVhc2UgaW5wdXQgUGljR28tQ29yZSBwYXRoLCBkZWZhdWx0IHVzaW5nIGVudmlyb25tZW50IHZhcmlhYmxlc1wiOlxuICAgIFwiUGxlYXNlIGlucHV0IFBpY0dvLUNvcmUgcGF0aCwgZGVmYXVsdCB1c2luZyBlbnZpcm9ubWVudCB2YXJpYWJsZXNcIixcbiAgXCJXb3JrIG9uIG5ldHdvcmtcIjogXCJXb3JrIG9uIG5ldHdvcmtcIixcbiAgXCJXb3JrIG9uIG5ldHdvcmsgRGVzY3JpcHRpb25cIjpcbiAgICBcIkFsbG93IHVwbG9hZCBuZXR3b3JrIGltYWdlIGJ5ICdVcGxvYWQgYWxsJyBjb21tYW5kLlxcbiBPciB3aGVuIHlvdSBwYXN0ZSwgbWQgc3RhbmRhcmQgaW1hZ2UgbGluayBpbiB5b3VyIGNsaXBib2FyZCB3aWxsIGJlIGF1dG8gdXBsb2FkLlwiLFxuICBmaXhQYXRoOiBcImZpeFBhdGhcIixcbiAgZml4UGF0aFdhcm5pbmc6XG4gICAgXCJUaGlzIG9wdGlvbiBpcyB1c2VkIHRvIGZpeCBQaWNHby1jb3JlIHVwbG9hZCBmYWlsdXJlcyBvbiBMaW51eCBhbmQgTWFjLiBJdCBtb2RpZmllcyB0aGUgUEFUSCB2YXJpYWJsZSB3aXRoaW4gT2JzaWRpYW4uIElmIE9ic2lkaWFuIGVuY291bnRlcnMgYW55IGJ1Z3MsIHR1cm4gb2ZmIHRoZSBvcHRpb24sIHRyeSBhZ2FpbiEgXCIsXG4gIFwiVXBsb2FkIHdoZW4gY2xpcGJvYXJkIGhhcyBpbWFnZSBhbmQgdGV4dCB0b2dldGhlclwiOlxuICAgIFwiVXBsb2FkIHdoZW4gY2xpcGJvYXJkIGhhcyBpbWFnZSBhbmQgdGV4dCB0b2dldGhlclwiLFxuICBcIldoZW4geW91IGNvcHksIHNvbWUgYXBwbGljYXRpb24gbGlrZSBFeGNlbCB3aWxsIGltYWdlIGFuZCB0ZXh0IHRvIGNsaXBib2FyZCwgeW91IGNhbiB1cGxvYWQgb3Igbm90LlwiOlxuICAgIFwiV2hlbiB5b3UgY29weSwgc29tZSBhcHBsaWNhdGlvbiBsaWtlIEV4Y2VsIHdpbGwgaW1hZ2UgYW5kIHRleHQgdG8gY2xpcGJvYXJkLCB5b3UgY2FuIHVwbG9hZCBvciBub3QuXCIsXG4gIFwiTmV0d29yayBEb21haW4gQmxhY2sgTGlzdFwiOiBcIk5ldHdvcmsgRG9tYWluIEJsYWNrIExpc3RcIixcbiAgXCJOZXR3b3JrIERvbWFpbiBCbGFjayBMaXN0IERlc2NyaXB0aW9uXCI6XG4gICAgXCJJbWFnZSBpbiB0aGUgZG9tYWluIGxpc3Qgd2lsbCBub3QgYmUgdXBsb2FkLHVzZSBjb21tYSBzZXBhcmF0ZWRcIixcbiAgXCJEZWxldGUgc291cmNlIGZpbGUgYWZ0ZXIgeW91IHVwbG9hZCBmaWxlXCI6XG4gICAgXCJEZWxldGUgc291cmNlIGZpbGUgYWZ0ZXIgeW91IHVwbG9hZCBmaWxlXCIsXG4gIFwiRGVsZXRlIHNvdXJjZSBmaWxlIGluIG9iIGFzc2V0cyBhZnRlciB5b3UgdXBsb2FkIGZpbGUuXCI6XG4gICAgXCJEZWxldGUgc291cmNlIGZpbGUgaW4gb2IgYXNzZXRzIGFmdGVyIHlvdSB1cGxvYWQgZmlsZS5cIixcbiAgXCJJbWFnZSBkZXNjXCI6IFwiSW1hZ2UgZGVzY1wiLFxuICByZXNlcnZlOiBcImRlZmF1bHRcIixcbiAgXCJyZW1vdmUgYWxsXCI6IFwibm9uZVwiLFxuICBcInJlbW92ZSBkZWZhdWx0XCI6IFwicmVtb3ZlIGltYWdlLnBuZ1wiLFxufTtcbiIsIi8vIEJyaXRpc2ggRW5nbGlzaFxuXG5leHBvcnQgZGVmYXVsdCB7fTtcbiIsIi8vIEVzcGHDsW9sXG5cbmV4cG9ydCBkZWZhdWx0IHt9O1xuIiwiLy8gZnJhbsOnYWlzXG5cbmV4cG9ydCBkZWZhdWx0IHt9O1xuIiwiLy8g4KS54KS/4KSo4KWN4KSm4KWAXG5cbmV4cG9ydCBkZWZhdWx0IHt9O1xuIiwiLy8gQmFoYXNhIEluZG9uZXNpYVxuXG5leHBvcnQgZGVmYXVsdCB7fTtcbiIsIi8vIEl0YWxpYW5vXG5cbmV4cG9ydCBkZWZhdWx0IHt9O1xuIiwiLy8g5pel5pys6KqeXG5cbmV4cG9ydCBkZWZhdWx0IHt9OyIsIi8vIO2VnOq1reyWtFxuXG5leHBvcnQgZGVmYXVsdCB7fTtcbiIsIi8vIE5lZGVybGFuZHNcblxuZXhwb3J0IGRlZmF1bHQge307XG4iLCIvLyBOb3Jza1xuXG5leHBvcnQgZGVmYXVsdCB7fTtcbiIsIi8vIGrEmXp5ayBwb2xza2lcblxuZXhwb3J0IGRlZmF1bHQge307XG4iLCIvLyBQb3J0dWd1w6pzXG5cbmV4cG9ydCBkZWZhdWx0IHt9O1xuIiwiLy8gUG9ydHVndcOqcyBkbyBCcmFzaWxcbi8vIEJyYXppbGlhbiBQb3J0dWd1ZXNlXG5cbmV4cG9ydCBkZWZhdWx0IHt9OyIsIi8vIFJvbcOibsSDXG5cbmV4cG9ydCBkZWZhdWx0IHt9O1xuIiwiLy8g0YDRg9GB0YHQutC40LlcblxuZXhwb3J0IGRlZmF1bHQge307XG4iLCIvLyBUw7xya8OnZVxuXG5leHBvcnQgZGVmYXVsdCB7fTtcbiIsIi8vIOeugOS9k+S4reaWh1xuXG5leHBvcnQgZGVmYXVsdCB7XG4gIC8vIHNldHRpbmcudHNcbiAgXCJQbHVnaW4gU2V0dGluZ3NcIjogXCLmj5Lku7borr7nva5cIixcbiAgXCJBdXRvIHBhc3RlZCB1cGxvYWRcIjogXCLliarliIfmnb/oh6rliqjkuIrkvKBcIixcbiAgXCJJZiB5b3Ugc2V0IHRoaXMgdmFsdWUgdHJ1ZSwgd2hlbiB5b3UgcGFzdGUgaW1hZ2UsIGl0IHdpbGwgYmUgYXV0byB1cGxvYWRlZCh5b3Ugc2hvdWxkIHNldCB0aGUgcGljR28gc2VydmVyIHJpZ2h0bHkpXCI6XG4gICAgXCLlkK/nlKjor6XpgInpobnlkI7vvIzpu4/otLTlm77niYfml7bkvJroh6rliqjkuIrkvKDvvIjkvaDpnIDopoHmraPnoa7phY3nva5waWNnb++8iVwiLFxuICBcIkRlZmF1bHQgdXBsb2FkZXJcIjogXCLpu5jorqTkuIrkvKDlmahcIixcbiAgXCJQaWNHbyBzZXJ2ZXJcIjogXCJQaWNHbyBzZXJ2ZXJcIixcbiAgXCJQbGVhc2UgaW5wdXQgUGljR28gc2VydmVyXCI6IFwi6K+36L6T5YWlIFBpY0dvIHNlcnZlclwiLFxuICBcIlBpY0dvIGRlbGV0ZSBzZXJ2ZXJcIjogXCJQaWNHbyBzZXJ2ZXIg5Yig6Zmk5o6l5Y+jKOivt+S9v+eUqFBpY0xpc3TmnaXlkK/nlKjmraTlip/og70pXCIsXG4gIFwiUGljTGlzdCBkZXNjXCI6IFwiUGljTGlzdOaYr1BpY0dv5LqM5qyh5byA5Y+R54mI77yM6K+3R2l0aHVi5pCc57SiUGljTGlzdOS4i+i9vVwiLFxuICBcIlBsZWFzZSBpbnB1dCBQaWNHbyBkZWxldGUgc2VydmVyXCI6IFwi6K+36L6T5YWlIFBpY0dvIHNlcnZlciDliKDpmaTmjqXlj6NcIixcbiAgXCJEZWxldGUgaW1hZ2UgdXNpbmcgUGljTGlzdFwiOiBcIuS9v+eUqCBQaWNMaXN0IOWIoOmZpOWbvueJh1wiLFxuICBcIlBpY0dvLUNvcmUgcGF0aFwiOiBcIlBpY0dvLUNvcmUg6Lev5b6EXCIsXG4gIFwiRGVsZXRlIHN1Y2Nlc3NmdWxseVwiOiBcIuWIoOmZpOaIkOWKn1wiLFxuICBcIkRlbGV0ZSBmYWlsZWRcIjogXCLliKDpmaTlpLHotKVcIixcbiAgXCJFcnJvciwgY291bGQgbm90IGRlbGV0ZVwiOiBcIumUmeivr++8jOaXoOazleWIoOmZpFwiLFxuICBcIkltYWdlIHNpemUgc3VmZml4XCI6IFwi5Zu+54mH5aSn5bCP5ZCO57yAXCIsXG4gIFwiSW1hZ2Ugc2l6ZSBzdWZmaXggRGVzY3JpcHRpb25cIjogXCLmr5TlpoLvvJp8MzAwIOeUqOS6juiwg+aVtOWbvueJh+Wkp+Wwj1wiLFxuICBcIlBsZWFzZSBpbnB1dCBpbWFnZSBzaXplIHN1ZmZpeFwiOiBcIuivt+i+k+WFpeWbvueJh+Wkp+Wwj+WQjue8gFwiLFxuICBcIlBsZWFzZSBpbnB1dCBQaWNHby1Db3JlIHBhdGgsIGRlZmF1bHQgdXNpbmcgZW52aXJvbm1lbnQgdmFyaWFibGVzXCI6XG4gICAgXCLor7fovpPlhaUgUGljR28tQ29yZSBwYXRo77yM6buY6K6k5L2/55So546v5aKD5Y+Y6YePXCIsXG4gIFwiV29yayBvbiBuZXR3b3JrXCI6IFwi5bqU55So572R57uc5Zu+54mHXCIsXG4gIFwiV29yayBvbiBuZXR3b3JrIERlc2NyaXB0aW9uXCI6XG4gICAgXCLlvZPkvaDkuIrkvKDmiYDmnInlm77niYfml7bvvIzkuZ/kvJrkuIrkvKDnvZHnu5zlm77niYfjgILku6Xlj4rlvZPkvaDov5vooYzpu4/otLTml7bvvIzliarliIfmnb/kuK3nmoTmoIflh4YgbWQg5Zu+54mH5Lya6KKr5LiK5LygXCIsXG4gIGZpeFBhdGg6IFwi5L+u5q2jUEFUSOWPmOmHj1wiLFxuICBmaXhQYXRoV2FybmluZzpcbiAgICBcIuatpOmAiemhueeUqOS6juS/ruWkjUxpbnV45ZKMTWFj5LiKIFBpY0dvLUNvcmUg5LiK5Lyg5aSx6LSl55qE6Zeu6aKY44CC5a6D5Lya5L+u5pS5IE9ic2lkaWFuIOWGheeahCBQQVRIIOWPmOmHj++8jOWmguaenCBPYnNpZGlhbiDpgYfliLDku7vkvZVCVUfvvIzlhYjlhbPpl63ov5nkuKrpgInpobnor5Xor5XvvIFcIixcbiAgXCJVcGxvYWQgd2hlbiBjbGlwYm9hcmQgaGFzIGltYWdlIGFuZCB0ZXh0IHRvZ2V0aGVyXCI6XG4gICAgXCLlvZPliarliIfmnb/lkIzml7bmi6XmnInmlofmnKzlkozlm77niYfliarliIfmnb/mlbDmja7ml7bmmK/lkKbkuIrkvKDlm77niYdcIixcbiAgXCJXaGVuIHlvdSBjb3B5LCBzb21lIGFwcGxpY2F0aW9uIGxpa2UgRXhjZWwgd2lsbCBpbWFnZSBhbmQgdGV4dCB0byBjbGlwYm9hcmQsIHlvdSBjYW4gdXBsb2FkIG9yIG5vdC5cIjpcbiAgICBcIuW9k+S9oOWkjeWItuaXtu+8jOafkOS6m+W6lOeUqOS+i+WmgiBFeGNlbCDkvJrlnKjliarliIfmnb/lkIzml7bmlofmnKzlkozlm77lg4/mlbDmja7vvIznoa7orqTmmK/lkKbkuIrkvKDjgIJcIixcbiAgXCJOZXR3b3JrIERvbWFpbiBCbGFjayBMaXN0XCI6IFwi572R57uc5Zu+54mH5Z+f5ZCN6buR5ZCN5Y2VXCIsXG4gIFwiTmV0d29yayBEb21haW4gQmxhY2sgTGlzdCBEZXNjcmlwdGlvblwiOlxuICAgIFwi6buR5ZCN5Y2V5Z+f5ZCN5Lit55qE5Zu+54mH5bCG5LiN5Lya6KKr5LiK5Lyg77yM55So6Iux5paH6YCX5Y+35YiG5YmyXCIsXG4gIFwiRGVsZXRlIHNvdXJjZSBmaWxlIGFmdGVyIHlvdSB1cGxvYWQgZmlsZVwiOiBcIuS4iuS8oOaWh+S7tuWQjuenu+mZpOa6kOaWh+S7tlwiLFxuICBcIkRlbGV0ZSBzb3VyY2UgZmlsZSBpbiBvYiBhc3NldHMgYWZ0ZXIgeW91IHVwbG9hZCBmaWxlLlwiOlxuICAgIFwi5LiK5Lyg5paH5Lu25ZCO56e76Zmk5Zyob2LpmYTku7bmlofku7blpLnkuK3nmoTmlofku7ZcIixcbiAgXCJJbWFnZSBkZXNjXCI6IFwi5Zu+54mH5o+P6L+wXCIsXG4gIHJlc2VydmU6IFwi6buY6K6kXCIsXG4gIFwicmVtb3ZlIGFsbFwiOiBcIuaXoFwiLFxuICBcInJlbW92ZSBkZWZhdWx0XCI6IFwi56e76ZmkaW1hZ2UucG5nXCIsXG59O1xuIiwiLy8g57mB6auU5Lit5paHXG5cbmV4cG9ydCBkZWZhdWx0IHt9O1xuIiwiaW1wb3J0IHsgbW9tZW50IH0gZnJvbSAnb2JzaWRpYW4nO1xuXG5pbXBvcnQgYXIgZnJvbSAnLi9sb2NhbGUvYXInO1xuaW1wb3J0IGN6IGZyb20gJy4vbG9jYWxlL2N6JztcbmltcG9ydCBkYSBmcm9tICcuL2xvY2FsZS9kYSc7XG5pbXBvcnQgZGUgZnJvbSAnLi9sb2NhbGUvZGUnO1xuaW1wb3J0IGVuIGZyb20gJy4vbG9jYWxlL2VuJztcbmltcG9ydCBlbkdCIGZyb20gJy4vbG9jYWxlL2VuLWdiJztcbmltcG9ydCBlcyBmcm9tICcuL2xvY2FsZS9lcyc7XG5pbXBvcnQgZnIgZnJvbSAnLi9sb2NhbGUvZnInO1xuaW1wb3J0IGhpIGZyb20gJy4vbG9jYWxlL2hpJztcbmltcG9ydCBpZCBmcm9tICcuL2xvY2FsZS9pZCc7XG5pbXBvcnQgaXQgZnJvbSAnLi9sb2NhbGUvaXQnO1xuaW1wb3J0IGphIGZyb20gJy4vbG9jYWxlL2phJztcbmltcG9ydCBrbyBmcm9tICcuL2xvY2FsZS9rbyc7XG5pbXBvcnQgbmwgZnJvbSAnLi9sb2NhbGUvbmwnO1xuaW1wb3J0IG5vIGZyb20gJy4vbG9jYWxlL25vJztcbmltcG9ydCBwbCBmcm9tICcuL2xvY2FsZS9wbCc7XG5pbXBvcnQgcHQgZnJvbSAnLi9sb2NhbGUvcHQnO1xuaW1wb3J0IHB0QlIgZnJvbSAnLi9sb2NhbGUvcHQtYnInO1xuaW1wb3J0IHJvIGZyb20gJy4vbG9jYWxlL3JvJztcbmltcG9ydCBydSBmcm9tICcuL2xvY2FsZS9ydSc7XG5pbXBvcnQgdHIgZnJvbSAnLi9sb2NhbGUvdHInO1xuaW1wb3J0IHpoQ04gZnJvbSAnLi9sb2NhbGUvemgtY24nO1xuaW1wb3J0IHpoVFcgZnJvbSAnLi9sb2NhbGUvemgtdHcnO1xuXG5jb25zdCBsb2NhbGVNYXA6IHsgW2s6IHN0cmluZ106IFBhcnRpYWw8dHlwZW9mIGVuPiB9ID0ge1xuICBhcixcbiAgY3M6IGN6LFxuICBkYSxcbiAgZGUsXG4gIGVuLFxuICAnZW4tZ2InOiBlbkdCLFxuICBlcyxcbiAgZnIsXG4gIGhpLFxuICBpZCxcbiAgaXQsXG4gIGphLFxuICBrbyxcbiAgbmwsXG4gIG5uOiBubyxcbiAgcGwsXG4gIHB0LFxuICAncHQtYnInOiBwdEJSLFxuICBybyxcbiAgcnUsXG4gIHRyLFxuICAnemgtY24nOiB6aENOLFxuICAnemgtdHcnOiB6aFRXLFxufTtcblxuY29uc3QgbG9jYWxlID0gbG9jYWxlTWFwW21vbWVudC5sb2NhbGUoKV07XG5cbmV4cG9ydCBmdW5jdGlvbiB0KHN0cjoga2V5b2YgdHlwZW9mIGVuKTogc3RyaW5nIHtcbiAgcmV0dXJuIChsb2NhbGUgJiYgbG9jYWxlW3N0cl0pIHx8IGVuW3N0cl07XG59XG4iLCJpbXBvcnQgeyBBcHAsIFBsdWdpblNldHRpbmdUYWIsIFNldHRpbmcgfSBmcm9tIFwib2JzaWRpYW5cIjtcbmltcG9ydCBpbWFnZUF1dG9VcGxvYWRQbHVnaW4gZnJvbSBcIi4vbWFpblwiO1xuaW1wb3J0IHsgdCB9IGZyb20gXCIuL2xhbmcvaGVscGVyc1wiO1xuaW1wb3J0IHsgZ2V0T1MgfSBmcm9tIFwiLi91dGlsc1wiO1xuXG5leHBvcnQgaW50ZXJmYWNlIFBsdWdpblNldHRpbmdzIHtcbiAgdXBsb2FkQnlDbGlwU3dpdGNoOiBib29sZWFuO1xuICB1cGxvYWRTZXJ2ZXI6IHN0cmluZztcbiAgZGVsZXRlU2VydmVyOiBzdHJpbmc7XG4gIGltYWdlU2l6ZVN1ZmZpeDogc3RyaW5nO1xuICB1cGxvYWRlcjogc3RyaW5nO1xuICBwaWNnb0NvcmVQYXRoOiBzdHJpbmc7XG4gIHdvcmtPbk5ldFdvcms6IGJvb2xlYW47XG4gIG5ld1dvcmtCbGFja0RvbWFpbnM6IHN0cmluZztcbiAgZml4UGF0aDogYm9vbGVhbjtcbiAgYXBwbHlJbWFnZTogYm9vbGVhbjtcbiAgZGVsZXRlU291cmNlOiBib29sZWFuO1xuICBpbWFnZURlc2M6IFwib3JpZ2luXCIgfCBcIm5vbmVcIiB8IFwicmVtb3ZlRGVmYXVsdFwiO1xuICBbcHJvcE5hbWU6IHN0cmluZ106IGFueTtcbn1cblxuZXhwb3J0IGNvbnN0IERFRkFVTFRfU0VUVElOR1M6IFBsdWdpblNldHRpbmdzID0ge1xuICB1cGxvYWRCeUNsaXBTd2l0Y2g6IHRydWUsXG4gIHVwbG9hZGVyOiBcIlBpY0dvXCIsXG4gIHVwbG9hZFNlcnZlcjogXCJodHRwOi8vMTI3LjAuMC4xOjM2Njc3L3VwbG9hZFwiLFxuICBkZWxldGVTZXJ2ZXI6IFwiaHR0cDovLzEyNy4wLjAuMTozNjY3Ny9kZWxldGVcIixcbiAgaW1hZ2VTaXplU3VmZml4OiBcIlwiLFxuICBwaWNnb0NvcmVQYXRoOiBcIlwiLFxuICB3b3JrT25OZXRXb3JrOiBmYWxzZSxcbiAgZml4UGF0aDogZmFsc2UsXG4gIGFwcGx5SW1hZ2U6IHRydWUsXG4gIG5ld1dvcmtCbGFja0RvbWFpbnM6IFwiXCIsXG4gIGRlbGV0ZVNvdXJjZTogZmFsc2UsXG4gIGltYWdlRGVzYzogXCJvcmlnaW5cIixcbn07XG5cbmV4cG9ydCBjbGFzcyBTZXR0aW5nVGFiIGV4dGVuZHMgUGx1Z2luU2V0dGluZ1RhYiB7XG4gIHBsdWdpbjogaW1hZ2VBdXRvVXBsb2FkUGx1Z2luO1xuXG4gIGNvbnN0cnVjdG9yKGFwcDogQXBwLCBwbHVnaW46IGltYWdlQXV0b1VwbG9hZFBsdWdpbikge1xuICAgIHN1cGVyKGFwcCwgcGx1Z2luKTtcbiAgICB0aGlzLnBsdWdpbiA9IHBsdWdpbjtcbiAgfVxuXG4gIGRpc3BsYXkoKTogdm9pZCB7XG4gICAgbGV0IHsgY29udGFpbmVyRWwgfSA9IHRoaXM7XG5cbiAgICBjb25zdCBvcyA9IGdldE9TKCk7XG5cbiAgICBjb250YWluZXJFbC5lbXB0eSgpO1xuICAgIGNvbnRhaW5lckVsLmNyZWF0ZUVsKFwiaDJcIiwgeyB0ZXh0OiB0KFwiUGx1Z2luIFNldHRpbmdzXCIpIH0pO1xuICAgIG5ldyBTZXR0aW5nKGNvbnRhaW5lckVsKVxuICAgICAgLnNldE5hbWUodChcIkF1dG8gcGFzdGVkIHVwbG9hZFwiKSlcbiAgICAgIC5zZXREZXNjKFxuICAgICAgICB0KFxuICAgICAgICAgIFwiSWYgeW91IHNldCB0aGlzIHZhbHVlIHRydWUsIHdoZW4geW91IHBhc3RlIGltYWdlLCBpdCB3aWxsIGJlIGF1dG8gdXBsb2FkZWQoeW91IHNob3VsZCBzZXQgdGhlIHBpY0dvIHNlcnZlciByaWdodGx5KVwiXG4gICAgICAgIClcbiAgICAgIClcbiAgICAgIC5hZGRUb2dnbGUodG9nZ2xlID0+XG4gICAgICAgIHRvZ2dsZVxuICAgICAgICAgIC5zZXRWYWx1ZSh0aGlzLnBsdWdpbi5zZXR0aW5ncy51cGxvYWRCeUNsaXBTd2l0Y2gpXG4gICAgICAgICAgLm9uQ2hhbmdlKGFzeW5jIHZhbHVlID0+IHtcbiAgICAgICAgICAgIHRoaXMucGx1Z2luLnNldHRpbmdzLnVwbG9hZEJ5Q2xpcFN3aXRjaCA9IHZhbHVlO1xuICAgICAgICAgICAgYXdhaXQgdGhpcy5wbHVnaW4uc2F2ZVNldHRpbmdzKCk7XG4gICAgICAgICAgfSlcbiAgICAgICk7XG5cbiAgICBuZXcgU2V0dGluZyhjb250YWluZXJFbClcbiAgICAgIC5zZXROYW1lKHQoXCJEZWZhdWx0IHVwbG9hZGVyXCIpKVxuICAgICAgLnNldERlc2ModChcIkRlZmF1bHQgdXBsb2FkZXJcIikpXG4gICAgICAuYWRkRHJvcGRvd24oY2IgPT5cbiAgICAgICAgY2JcbiAgICAgICAgICAuYWRkT3B0aW9uKFwiUGljR29cIiwgXCJQaWNHbyhhcHApXCIpXG4gICAgICAgICAgLmFkZE9wdGlvbihcIlBpY0dvLUNvcmVcIiwgXCJQaWNHby1Db3JlXCIpXG4gICAgICAgICAgLnNldFZhbHVlKHRoaXMucGx1Z2luLnNldHRpbmdzLnVwbG9hZGVyKVxuICAgICAgICAgIC5vbkNoYW5nZShhc3luYyB2YWx1ZSA9PiB7XG4gICAgICAgICAgICB0aGlzLnBsdWdpbi5zZXR0aW5ncy51cGxvYWRlciA9IHZhbHVlO1xuICAgICAgICAgICAgdGhpcy5kaXNwbGF5KCk7XG4gICAgICAgICAgICBhd2FpdCB0aGlzLnBsdWdpbi5zYXZlU2V0dGluZ3MoKTtcbiAgICAgICAgICB9KVxuICAgICAgKTtcblxuICAgIGlmICh0aGlzLnBsdWdpbi5zZXR0aW5ncy51cGxvYWRlciA9PT0gXCJQaWNHb1wiKSB7XG4gICAgICBuZXcgU2V0dGluZyhjb250YWluZXJFbClcbiAgICAgICAgLnNldE5hbWUodChcIlBpY0dvIHNlcnZlclwiKSlcbiAgICAgICAgLnNldERlc2ModChcIlBpY0dvIHNlcnZlclwiKSlcbiAgICAgICAgLmFkZFRleHQodGV4dCA9PlxuICAgICAgICAgIHRleHRcbiAgICAgICAgICAgIC5zZXRQbGFjZWhvbGRlcih0KFwiUGxlYXNlIGlucHV0IFBpY0dvIHNlcnZlclwiKSlcbiAgICAgICAgICAgIC5zZXRWYWx1ZSh0aGlzLnBsdWdpbi5zZXR0aW5ncy51cGxvYWRTZXJ2ZXIpXG4gICAgICAgICAgICAub25DaGFuZ2UoYXN5bmMga2V5ID0+IHtcbiAgICAgICAgICAgICAgdGhpcy5wbHVnaW4uc2V0dGluZ3MudXBsb2FkU2VydmVyID0ga2V5O1xuICAgICAgICAgICAgICBhd2FpdCB0aGlzLnBsdWdpbi5zYXZlU2V0dGluZ3MoKTtcbiAgICAgICAgICAgIH0pXG4gICAgICAgICk7XG5cbiAgICAgIG5ldyBTZXR0aW5nKGNvbnRhaW5lckVsKVxuICAgICAgICAuc2V0TmFtZSh0KFwiUGljR28gZGVsZXRlIHNlcnZlclwiKSlcbiAgICAgICAgLnNldERlc2ModChcIlBpY0xpc3QgZGVzY1wiKSlcbiAgICAgICAgLmFkZFRleHQodGV4dCA9PlxuICAgICAgICAgIHRleHRcbiAgICAgICAgICAgIC5zZXRQbGFjZWhvbGRlcih0KFwiUGxlYXNlIGlucHV0IFBpY0dvIGRlbGV0ZSBzZXJ2ZXJcIikpXG4gICAgICAgICAgICAuc2V0VmFsdWUodGhpcy5wbHVnaW4uc2V0dGluZ3MuZGVsZXRlU2VydmVyKVxuICAgICAgICAgICAgLm9uQ2hhbmdlKGFzeW5jIGtleSA9PiB7XG4gICAgICAgICAgICAgIHRoaXMucGx1Z2luLnNldHRpbmdzLmRlbGV0ZVNlcnZlciA9IGtleTtcbiAgICAgICAgICAgICAgYXdhaXQgdGhpcy5wbHVnaW4uc2F2ZVNldHRpbmdzKCk7XG4gICAgICAgICAgICB9KVxuICAgICAgICApO1xuICAgIH1cblxuICAgIGlmICh0aGlzLnBsdWdpbi5zZXR0aW5ncy51cGxvYWRlciA9PT0gXCJQaWNHby1Db3JlXCIpIHtcbiAgICAgIG5ldyBTZXR0aW5nKGNvbnRhaW5lckVsKVxuICAgICAgICAuc2V0TmFtZSh0KFwiUGljR28tQ29yZSBwYXRoXCIpKVxuICAgICAgICAuc2V0RGVzYyhcbiAgICAgICAgICB0KFwiUGxlYXNlIGlucHV0IFBpY0dvLUNvcmUgcGF0aCwgZGVmYXVsdCB1c2luZyBlbnZpcm9ubWVudCB2YXJpYWJsZXNcIilcbiAgICAgICAgKVxuICAgICAgICAuYWRkVGV4dCh0ZXh0ID0+XG4gICAgICAgICAgdGV4dFxuICAgICAgICAgICAgLnNldFBsYWNlaG9sZGVyKFwiXCIpXG4gICAgICAgICAgICAuc2V0VmFsdWUodGhpcy5wbHVnaW4uc2V0dGluZ3MucGljZ29Db3JlUGF0aClcbiAgICAgICAgICAgIC5vbkNoYW5nZShhc3luYyB2YWx1ZSA9PiB7XG4gICAgICAgICAgICAgIHRoaXMucGx1Z2luLnNldHRpbmdzLnBpY2dvQ29yZVBhdGggPSB2YWx1ZTtcbiAgICAgICAgICAgICAgYXdhaXQgdGhpcy5wbHVnaW4uc2F2ZVNldHRpbmdzKCk7XG4gICAgICAgICAgICB9KVxuICAgICAgICApO1xuXG4gICAgICBpZiAob3MgIT09IFwiV2luZG93c1wiKSB7XG4gICAgICAgIG5ldyBTZXR0aW5nKGNvbnRhaW5lckVsKVxuICAgICAgICAgIC5zZXROYW1lKHQoXCJmaXhQYXRoXCIpKVxuICAgICAgICAgIC5zZXREZXNjKHQoXCJmaXhQYXRoV2FybmluZ1wiKSlcbiAgICAgICAgICAuYWRkVG9nZ2xlKHRvZ2dsZSA9PlxuICAgICAgICAgICAgdG9nZ2xlXG4gICAgICAgICAgICAgIC5zZXRWYWx1ZSh0aGlzLnBsdWdpbi5zZXR0aW5ncy5maXhQYXRoKVxuICAgICAgICAgICAgICAub25DaGFuZ2UoYXN5bmMgdmFsdWUgPT4ge1xuICAgICAgICAgICAgICAgIHRoaXMucGx1Z2luLnNldHRpbmdzLmZpeFBhdGggPSB2YWx1ZTtcbiAgICAgICAgICAgICAgICBhd2FpdCB0aGlzLnBsdWdpbi5zYXZlU2V0dGluZ3MoKTtcbiAgICAgICAgICAgICAgfSlcbiAgICAgICAgICApO1xuICAgICAgfVxuICAgIH1cblxuICAgIC8vIGltYWdlIGRlc2Mgc2V0dGluZ1xuICAgIG5ldyBTZXR0aW5nKGNvbnRhaW5lckVsKVxuICAgICAgLnNldE5hbWUodChcIkltYWdlIGRlc2NcIikpXG4gICAgICAuc2V0RGVzYyh0KFwiSW1hZ2UgZGVzY1wiKSlcbiAgICAgIC5hZGREcm9wZG93bihjYiA9PlxuICAgICAgICBjYlxuICAgICAgICAgIC5hZGRPcHRpb24oXCJvcmlnaW5cIiwgdChcInJlc2VydmVcIikpIC8vIOS/neeVmeWFqOmDqFxuICAgICAgICAgIC5hZGRPcHRpb24oXCJub25lXCIsIHQoXCJyZW1vdmUgYWxsXCIpKSAvLyDnp7vpmaTlhajpg6hcbiAgICAgICAgICAuYWRkT3B0aW9uKFwicmVtb3ZlRGVmYXVsdFwiLCB0KFwicmVtb3ZlIGRlZmF1bHRcIikpIC8vIOWPquenu+mZpOm7mOiupOWNsyBpbWFnZS5wbmdcbiAgICAgICAgICAuc2V0VmFsdWUodGhpcy5wbHVnaW4uc2V0dGluZ3MuaW1hZ2VEZXNjKVxuICAgICAgICAgIC5vbkNoYW5nZShhc3luYyAodmFsdWU6IFwib3JpZ2luXCIgfCBcIm5vbmVcIiB8IFwicmVtb3ZlRGVmYXVsdFwiKSA9PiB7XG4gICAgICAgICAgICB0aGlzLnBsdWdpbi5zZXR0aW5ncy5pbWFnZURlc2MgPSB2YWx1ZTtcbiAgICAgICAgICAgIHRoaXMuZGlzcGxheSgpO1xuICAgICAgICAgICAgYXdhaXQgdGhpcy5wbHVnaW4uc2F2ZVNldHRpbmdzKCk7XG4gICAgICAgICAgfSlcbiAgICAgICk7XG5cbiAgICBuZXcgU2V0dGluZyhjb250YWluZXJFbClcbiAgICAgIC5zZXROYW1lKHQoXCJJbWFnZSBzaXplIHN1ZmZpeFwiKSlcbiAgICAgIC5zZXREZXNjKHQoXCJJbWFnZSBzaXplIHN1ZmZpeCBEZXNjcmlwdGlvblwiKSlcbiAgICAgIC5hZGRUZXh0KHRleHQgPT5cbiAgICAgICAgdGV4dFxuICAgICAgICAgIC5zZXRQbGFjZWhvbGRlcih0KFwiUGxlYXNlIGlucHV0IGltYWdlIHNpemUgc3VmZml4XCIpKVxuICAgICAgICAgIC5zZXRWYWx1ZSh0aGlzLnBsdWdpbi5zZXR0aW5ncy5pbWFnZVNpemVTdWZmaXgpXG4gICAgICAgICAgLm9uQ2hhbmdlKGFzeW5jIGtleSA9PiB7XG4gICAgICAgICAgICB0aGlzLnBsdWdpbi5zZXR0aW5ncy5pbWFnZVNpemVTdWZmaXggPSBrZXk7XG4gICAgICAgICAgICBhd2FpdCB0aGlzLnBsdWdpbi5zYXZlU2V0dGluZ3MoKTtcbiAgICAgICAgICB9KVxuICAgICAgKTtcblxuICAgIG5ldyBTZXR0aW5nKGNvbnRhaW5lckVsKVxuICAgICAgLnNldE5hbWUodChcIldvcmsgb24gbmV0d29ya1wiKSlcbiAgICAgIC5zZXREZXNjKHQoXCJXb3JrIG9uIG5ldHdvcmsgRGVzY3JpcHRpb25cIikpXG4gICAgICAuYWRkVG9nZ2xlKHRvZ2dsZSA9PlxuICAgICAgICB0b2dnbGVcbiAgICAgICAgICAuc2V0VmFsdWUodGhpcy5wbHVnaW4uc2V0dGluZ3Mud29ya09uTmV0V29yaylcbiAgICAgICAgICAub25DaGFuZ2UoYXN5bmMgdmFsdWUgPT4ge1xuICAgICAgICAgICAgdGhpcy5wbHVnaW4uc2V0dGluZ3Mud29ya09uTmV0V29yayA9IHZhbHVlO1xuICAgICAgICAgICAgdGhpcy5kaXNwbGF5KCk7XG4gICAgICAgICAgICBhd2FpdCB0aGlzLnBsdWdpbi5zYXZlU2V0dGluZ3MoKTtcbiAgICAgICAgICB9KVxuICAgICAgKTtcblxuICAgIG5ldyBTZXR0aW5nKGNvbnRhaW5lckVsKVxuICAgICAgLnNldE5hbWUodChcIk5ldHdvcmsgRG9tYWluIEJsYWNrIExpc3RcIikpXG4gICAgICAuc2V0RGVzYyh0KFwiTmV0d29yayBEb21haW4gQmxhY2sgTGlzdCBEZXNjcmlwdGlvblwiKSlcbiAgICAgIC5hZGRUZXh0QXJlYSh0ZXh0QXJlYSA9PlxuICAgICAgICB0ZXh0QXJlYVxuICAgICAgICAgIC5zZXRWYWx1ZSh0aGlzLnBsdWdpbi5zZXR0aW5ncy5uZXdXb3JrQmxhY2tEb21haW5zKVxuICAgICAgICAgIC5vbkNoYW5nZShhc3luYyB2YWx1ZSA9PiB7XG4gICAgICAgICAgICB0aGlzLnBsdWdpbi5zZXR0aW5ncy5uZXdXb3JrQmxhY2tEb21haW5zID0gdmFsdWU7XG4gICAgICAgICAgICBhd2FpdCB0aGlzLnBsdWdpbi5zYXZlU2V0dGluZ3MoKTtcbiAgICAgICAgICB9KVxuICAgICAgKTtcblxuICAgIG5ldyBTZXR0aW5nKGNvbnRhaW5lckVsKVxuICAgICAgLnNldE5hbWUodChcIlVwbG9hZCB3aGVuIGNsaXBib2FyZCBoYXMgaW1hZ2UgYW5kIHRleHQgdG9nZXRoZXJcIikpXG4gICAgICAuc2V0RGVzYyhcbiAgICAgICAgdChcbiAgICAgICAgICBcIldoZW4geW91IGNvcHksIHNvbWUgYXBwbGljYXRpb24gbGlrZSBFeGNlbCB3aWxsIGltYWdlIGFuZCB0ZXh0IHRvIGNsaXBib2FyZCwgeW91IGNhbiB1cGxvYWQgb3Igbm90LlwiXG4gICAgICAgIClcbiAgICAgIClcbiAgICAgIC5hZGRUb2dnbGUodG9nZ2xlID0+XG4gICAgICAgIHRvZ2dsZVxuICAgICAgICAgIC5zZXRWYWx1ZSh0aGlzLnBsdWdpbi5zZXR0aW5ncy5hcHBseUltYWdlKVxuICAgICAgICAgIC5vbkNoYW5nZShhc3luYyB2YWx1ZSA9PiB7XG4gICAgICAgICAgICB0aGlzLnBsdWdpbi5zZXR0aW5ncy5hcHBseUltYWdlID0gdmFsdWU7XG4gICAgICAgICAgICB0aGlzLmRpc3BsYXkoKTtcbiAgICAgICAgICAgIGF3YWl0IHRoaXMucGx1Z2luLnNhdmVTZXR0aW5ncygpO1xuICAgICAgICAgIH0pXG4gICAgICApO1xuXG4gICAgbmV3IFNldHRpbmcoY29udGFpbmVyRWwpXG4gICAgICAuc2V0TmFtZSh0KFwiRGVsZXRlIHNvdXJjZSBmaWxlIGFmdGVyIHlvdSB1cGxvYWQgZmlsZVwiKSlcbiAgICAgIC5zZXREZXNjKHQoXCJEZWxldGUgc291cmNlIGZpbGUgaW4gb2IgYXNzZXRzIGFmdGVyIHlvdSB1cGxvYWQgZmlsZS5cIikpXG4gICAgICAuYWRkVG9nZ2xlKHRvZ2dsZSA9PlxuICAgICAgICB0b2dnbGVcbiAgICAgICAgICAuc2V0VmFsdWUodGhpcy5wbHVnaW4uc2V0dGluZ3MuZGVsZXRlU291cmNlKVxuICAgICAgICAgIC5vbkNoYW5nZShhc3luYyB2YWx1ZSA9PiB7XG4gICAgICAgICAgICB0aGlzLnBsdWdpbi5zZXR0aW5ncy5kZWxldGVTb3VyY2UgPSB2YWx1ZTtcbiAgICAgICAgICAgIHRoaXMuZGlzcGxheSgpO1xuICAgICAgICAgICAgYXdhaXQgdGhpcy5wbHVnaW4uc2F2ZVNldHRpbmdzKCk7XG4gICAgICAgICAgfSlcbiAgICAgICk7XG4gIH1cbn1cbiIsImltcG9ydCB7XG4gIE1hcmtkb3duVmlldyxcbiAgUGx1Z2luLFxuICBGaWxlU3lzdGVtQWRhcHRlcixcbiAgRWRpdG9yLFxuICBNZW51LFxuICBNZW51SXRlbSxcbiAgVEZpbGUsXG4gIG5vcm1hbGl6ZVBhdGgsXG4gIE5vdGljZSxcbiAgYWRkSWNvbixcbiAgcmVxdWVzdFVybCxcbiAgTWFya2Rvd25GaWxlSW5mbyxcbn0gZnJvbSBcIm9ic2lkaWFuXCI7XG5cbmltcG9ydCB7IHJlc29sdmUsIHJlbGF0aXZlLCBqb2luLCBwYXJzZSwgcG9zaXgsIGJhc2VuYW1lLCBkaXJuYW1lIH0gZnJvbSBcInBhdGhcIjtcbmltcG9ydCB7IGV4aXN0c1N5bmMsIG1rZGlyU3luYywgd3JpdGVGaWxlU3luYywgdW5saW5rIH0gZnJvbSBcImZzXCI7XG5cbmltcG9ydCBmaXhQYXRoIGZyb20gXCJmaXgtcGF0aFwiO1xuaW1wb3J0IGltYWdlVHlwZSBmcm9tIFwiaW1hZ2UtdHlwZVwiO1xuXG5pbXBvcnQge1xuICBpc0Fzc2V0VHlwZUFuSW1hZ2UsXG4gIGlzQW5JbWFnZSxcbiAgZ2V0VXJsQXNzZXQsXG4gIGFycmF5VG9PYmplY3QsXG59IGZyb20gXCIuL3V0aWxzXCI7XG5pbXBvcnQgeyBQaWNHb1VwbG9hZGVyLCBQaWNHb0NvcmVVcGxvYWRlciB9IGZyb20gXCIuL3VwbG9hZGVyXCI7XG5pbXBvcnQgeyBQaWNHb0RlbGV0ZXIgfSBmcm9tIFwiLi9kZWxldGVyXCI7XG5pbXBvcnQgSGVscGVyIGZyb20gXCIuL2hlbHBlclwiO1xuaW1wb3J0IHsgdCB9IGZyb20gXCIuL2xhbmcvaGVscGVyc1wiO1xuXG5pbXBvcnQgeyBTZXR0aW5nVGFiLCBQbHVnaW5TZXR0aW5ncywgREVGQVVMVF9TRVRUSU5HUyB9IGZyb20gXCIuL3NldHRpbmdcIjtcblxuaW50ZXJmYWNlIEltYWdlIHtcbiAgcGF0aDogc3RyaW5nO1xuICBuYW1lOiBzdHJpbmc7XG4gIHNvdXJjZTogc3RyaW5nO1xufVxuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBpbWFnZUF1dG9VcGxvYWRQbHVnaW4gZXh0ZW5kcyBQbHVnaW4ge1xuICBzZXR0aW5nczogUGx1Z2luU2V0dGluZ3M7XG4gIGhlbHBlcjogSGVscGVyO1xuICBlZGl0b3I6IEVkaXRvcjtcbiAgcGljR29VcGxvYWRlcjogUGljR29VcGxvYWRlcjtcbiAgcGljR29EZWxldGVyOiBQaWNHb0RlbGV0ZXI7XG4gIHBpY0dvQ29yZVVwbG9hZGVyOiBQaWNHb0NvcmVVcGxvYWRlcjtcbiAgdXBsb2FkZXI6IFBpY0dvVXBsb2FkZXIgfCBQaWNHb0NvcmVVcGxvYWRlcjtcblxuICBhc3luYyBsb2FkU2V0dGluZ3MoKSB7XG4gICAgdGhpcy5zZXR0aW5ncyA9IE9iamVjdC5hc3NpZ24oREVGQVVMVF9TRVRUSU5HUywgYXdhaXQgdGhpcy5sb2FkRGF0YSgpKTtcbiAgfVxuXG4gIGFzeW5jIHNhdmVTZXR0aW5ncygpIHtcbiAgICBhd2FpdCB0aGlzLnNhdmVEYXRhKHRoaXMuc2V0dGluZ3MpO1xuICB9XG5cbiAgb251bmxvYWQoKSB7fVxuXG4gIGFzeW5jIG9ubG9hZCgpIHtcbiAgICBhd2FpdCB0aGlzLmxvYWRTZXR0aW5ncygpO1xuXG4gICAgdGhpcy5oZWxwZXIgPSBuZXcgSGVscGVyKHRoaXMuYXBwKTtcbiAgICB0aGlzLnBpY0dvVXBsb2FkZXIgPSBuZXcgUGljR29VcGxvYWRlcih0aGlzLnNldHRpbmdzLCB0aGlzKTtcbiAgICB0aGlzLnBpY0dvRGVsZXRlciA9IG5ldyBQaWNHb0RlbGV0ZXIodGhpcyk7XG4gICAgdGhpcy5waWNHb0NvcmVVcGxvYWRlciA9IG5ldyBQaWNHb0NvcmVVcGxvYWRlcih0aGlzLnNldHRpbmdzLCB0aGlzKTtcblxuICAgIGlmICh0aGlzLnNldHRpbmdzLnVwbG9hZGVyID09PSBcIlBpY0dvXCIpIHtcbiAgICAgIHRoaXMudXBsb2FkZXIgPSB0aGlzLnBpY0dvVXBsb2FkZXI7XG4gICAgfSBlbHNlIGlmICh0aGlzLnNldHRpbmdzLnVwbG9hZGVyID09PSBcIlBpY0dvLUNvcmVcIikge1xuICAgICAgdGhpcy51cGxvYWRlciA9IHRoaXMucGljR29Db3JlVXBsb2FkZXI7XG4gICAgICBpZiAodGhpcy5zZXR0aW5ncy5maXhQYXRoKSB7XG4gICAgICAgIGZpeFBhdGgoKTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgbmV3IE5vdGljZShcInVua25vd24gdXBsb2FkZXJcIik7XG4gICAgfVxuXG4gICAgYWRkSWNvbihcbiAgICAgIFwidXBsb2FkXCIsXG4gICAgICBgPHN2ZyB0PVwiMTYzNjYzMDc4MzQyOVwiIGNsYXNzPVwiaWNvblwiIHZpZXdCb3g9XCIwIDAgMTAwIDEwMFwiIHZlcnNpb249XCIxLjFcIiBwLWlkPVwiNDY0OVwiIHhtbG5zPVwiaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmdcIj5cbiAgICAgIDxwYXRoIGQ9XCJNIDcxLjYzOCAzNS4zMzYgTCA3OS40MDggMzUuMzM2IEMgODMuNyAzNS4zMzYgODcuMTc4IDM4LjY2MiA4Ny4xNzggNDIuNzY1IEwgODcuMTc4IDg0Ljg2NCBDIDg3LjE3OCA4OC45NjkgODMuNyA5Mi4yOTUgNzkuNDA4IDkyLjI5NSBMIDE3LjI0OSA5Mi4yOTUgQyAxMi45NTcgOTIuMjk1IDkuNDc5IDg4Ljk2OSA5LjQ3OSA4NC44NjQgTCA5LjQ3OSA0Mi43NjUgQyA5LjQ3OSAzOC42NjIgMTIuOTU3IDM1LjMzNiAxNy4yNDkgMzUuMzM2IEwgMjUuMDE5IDM1LjMzNiBMIDI1LjAxOSA0Mi43NjUgTCAxNy4yNDkgNDIuNzY1IEwgMTcuMjQ5IDg0Ljg2NCBMIDc5LjQwOCA4NC44NjQgTCA3OS40MDggNDIuNzY1IEwgNzEuNjM4IDQyLjc2NSBMIDcxLjYzOCAzNS4zMzYgWiBNIDQ5LjAxNCAxMC4xNzkgTCA2Ny4zMjYgMjcuNjg4IEwgNjEuODM1IDMyLjk0MiBMIDUyLjg0OSAyNC4zNTIgTCA1Mi44NDkgNTkuNzMxIEwgNDUuMDc4IDU5LjczMSBMIDQ1LjA3OCAyNC40NTUgTCAzNi4xOTQgMzIuOTQ3IEwgMzAuNzAyIDI3LjY5MiBMIDQ5LjAxMiAxMC4xODEgWlwiIHAtaWQ9XCI0NjUwXCIgZmlsbD1cIiM4YThhOGFcIj48L3BhdGg+XG4gICAgPC9zdmc+YFxuICAgICk7XG5cbiAgICB0aGlzLmFkZFNldHRpbmdUYWIobmV3IFNldHRpbmdUYWIodGhpcy5hcHAsIHRoaXMpKTtcblxuICAgIHRoaXMuYWRkQ29tbWFuZCh7XG4gICAgICBpZDogXCJVcGxvYWQgYWxsIGltYWdlc1wiLFxuICAgICAgbmFtZTogXCJVcGxvYWQgYWxsIGltYWdlc1wiLFxuICAgICAgY2hlY2tDYWxsYmFjazogKGNoZWNraW5nOiBib29sZWFuKSA9PiB7XG4gICAgICAgIGxldCBsZWFmID0gdGhpcy5hcHAud29ya3NwYWNlLmFjdGl2ZUxlYWY7XG4gICAgICAgIGlmIChsZWFmKSB7XG4gICAgICAgICAgaWYgKCFjaGVja2luZykge1xuICAgICAgICAgICAgdGhpcy51cGxvYWRBbGxGaWxlKCk7XG4gICAgICAgICAgfVxuICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH0sXG4gICAgfSk7XG4gICAgdGhpcy5hZGRDb21tYW5kKHtcbiAgICAgIGlkOiBcIkRvd25sb2FkIGFsbCBpbWFnZXNcIixcbiAgICAgIG5hbWU6IFwiRG93bmxvYWQgYWxsIGltYWdlc1wiLFxuICAgICAgY2hlY2tDYWxsYmFjazogKGNoZWNraW5nOiBib29sZWFuKSA9PiB7XG4gICAgICAgIGxldCBsZWFmID0gdGhpcy5hcHAud29ya3NwYWNlLmFjdGl2ZUxlYWY7XG4gICAgICAgIGlmIChsZWFmKSB7XG4gICAgICAgICAgaWYgKCFjaGVja2luZykge1xuICAgICAgICAgICAgdGhpcy5kb3dubG9hZEFsbEltYWdlRmlsZXMoKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfSxcbiAgICB9KTtcblxuICAgIHRoaXMuc2V0dXBQYXN0ZUhhbmRsZXIoKTtcbiAgICB0aGlzLnJlZ2lzdGVyRmlsZU1lbnUoKTtcblxuICAgIHRoaXMucmVnaXN0ZXJTZWxlY3Rpb24oKTtcbiAgfVxuXG4gIHJlZ2lzdGVyU2VsZWN0aW9uKCkge1xuICAgIHRoaXMucmVnaXN0ZXJFdmVudChcbiAgICAgIHRoaXMuYXBwLndvcmtzcGFjZS5vbihcbiAgICAgICAgXCJlZGl0b3ItbWVudVwiLFxuICAgICAgICAobWVudTogTWVudSwgZWRpdG9yOiBFZGl0b3IsIGluZm86IE1hcmtkb3duVmlldyB8IE1hcmtkb3duRmlsZUluZm8pID0+IHtcbiAgICAgICAgICBpZiAodGhpcy5hcHAud29ya3NwYWNlLmdldExlYXZlc09mVHlwZShcIm1hcmtkb3duXCIpLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgIH1cbiAgICAgICAgICBjb25zdCBzZWxlY3Rpb24gPSBlZGl0b3IuZ2V0U2VsZWN0aW9uKCk7XG4gICAgICAgICAgaWYgKHNlbGVjdGlvbikge1xuICAgICAgICAgICAgY29uc3QgbWFya2Rvd25SZWdleCA9IC8hXFxbLipcXF1cXCgoLiopXFwpL2c7XG4gICAgICAgICAgICBjb25zdCBtYXJrZG93bk1hdGNoID0gbWFya2Rvd25SZWdleC5leGVjKHNlbGVjdGlvbik7XG4gICAgICAgICAgICBpZiAobWFya2Rvd25NYXRjaCAmJiBtYXJrZG93bk1hdGNoLmxlbmd0aCA+IDEpIHtcbiAgICAgICAgICAgICAgY29uc3QgbWFya2Rvd25VcmwgPSBtYXJrZG93bk1hdGNoWzFdO1xuICAgICAgICAgICAgICBpZiAoXG4gICAgICAgICAgICAgICAgdGhpcy5zZXR0aW5ncy51cGxvYWRlZEltYWdlcy5maW5kKFxuICAgICAgICAgICAgICAgICAgKGl0ZW06IHsgaW1nVXJsOiBzdHJpbmcgfSkgPT4gaXRlbS5pbWdVcmwgPT09IG1hcmtkb3duVXJsXG4gICAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgICApIHtcbiAgICAgICAgICAgICAgICB0aGlzLmFkZE1lbnUobWVudSwgbWFya2Rvd25VcmwsIGVkaXRvcik7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIClcbiAgICApO1xuICB9XG5cbiAgYWRkTWVudSA9IChtZW51OiBNZW51LCBpbWdQYXRoOiBzdHJpbmcsIGVkaXRvcjogRWRpdG9yKSA9PiB7XG4gICAgbWVudS5hZGRJdGVtKChpdGVtOiBNZW51SXRlbSkgPT5cbiAgICAgIGl0ZW1cbiAgICAgICAgLnNldEljb24oXCJ0cmFzaC0yXCIpXG4gICAgICAgIC5zZXRUaXRsZSh0KFwiRGVsZXRlIGltYWdlIHVzaW5nIFBpY0xpc3RcIikpXG4gICAgICAgIC5vbkNsaWNrKGFzeW5jICgpID0+IHtcbiAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgY29uc3Qgc2VsZWN0ZWRJdGVtID0gdGhpcy5zZXR0aW5ncy51cGxvYWRlZEltYWdlcy5maW5kKFxuICAgICAgICAgICAgICAoaXRlbTogeyBpbWdVcmw6IHN0cmluZyB9KSA9PiBpdGVtLmltZ1VybCA9PT0gaW1nUGF0aFxuICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIGlmIChzZWxlY3RlZEl0ZW0pIHtcbiAgICAgICAgICAgICAgY29uc3QgcmVzID0gYXdhaXQgdGhpcy5waWNHb0RlbGV0ZXIuZGVsZXRlSW1hZ2UoW3NlbGVjdGVkSXRlbV0pO1xuICAgICAgICAgICAgICBpZiAocmVzLnN1Y2Nlc3MpIHtcbiAgICAgICAgICAgICAgICBuZXcgTm90aWNlKHQoXCJEZWxldGUgc3VjY2Vzc2Z1bGx5XCIpKTtcbiAgICAgICAgICAgICAgICBjb25zdCBzZWxlY3Rpb24gPSBlZGl0b3IuZ2V0U2VsZWN0aW9uKCk7XG4gICAgICAgICAgICAgICAgaWYgKHNlbGVjdGlvbikge1xuICAgICAgICAgICAgICAgICAgZWRpdG9yLnJlcGxhY2VTZWxlY3Rpb24oXCJcIik7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHRoaXMuc2V0dGluZ3MudXBsb2FkZWRJbWFnZXMgPVxuICAgICAgICAgICAgICAgICAgdGhpcy5zZXR0aW5ncy51cGxvYWRlZEltYWdlcy5maWx0ZXIoXG4gICAgICAgICAgICAgICAgICAgIChpdGVtOiB7IGltZ1VybDogc3RyaW5nIH0pID0+IGl0ZW0uaW1nVXJsICE9PSBpbWdQYXRoXG4gICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgIHRoaXMuc2F2ZVNldHRpbmdzKCk7XG4gICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgbmV3IE5vdGljZSh0KFwiRGVsZXRlIGZhaWxlZFwiKSk7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9IGNhdGNoIHtcbiAgICAgICAgICAgIG5ldyBOb3RpY2UodChcIkVycm9yLCBjb3VsZCBub3QgZGVsZXRlXCIpKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0pXG4gICAgKTtcbiAgfTtcblxuICBhc3luYyBkb3dubG9hZEFsbEltYWdlRmlsZXMoKSB7XG4gICAgY29uc3QgZm9sZGVyUGF0aCA9IHRoaXMuZ2V0RmlsZUFzc2V0UGF0aCgpO1xuICAgIGNvbnN0IGZpbGVBcnJheSA9IHRoaXMuaGVscGVyLmdldEFsbEZpbGVzKCk7XG4gICAgaWYgKCFleGlzdHNTeW5jKGZvbGRlclBhdGgpKSB7XG4gICAgICBta2RpclN5bmMoZm9sZGVyUGF0aCk7XG4gICAgfVxuXG4gICAgbGV0IGltYWdlQXJyYXkgPSBbXTtcbiAgICBjb25zdCBuYW1lU2V0ID0gbmV3IFNldCgpO1xuICAgIGZvciAoY29uc3QgZmlsZSBvZiBmaWxlQXJyYXkpIHtcbiAgICAgIGlmICghZmlsZS5wYXRoLnN0YXJ0c1dpdGgoXCJodHRwXCIpKSB7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuXG4gICAgICBjb25zdCB1cmwgPSBmaWxlLnBhdGg7XG4gICAgICBjb25zdCBhc3NldCA9IGdldFVybEFzc2V0KHVybCk7XG4gICAgICBsZXQgbmFtZSA9IGRlY29kZVVSSShwYXJzZShhc3NldCkubmFtZSkucmVwbGFjZUFsbChcbiAgICAgICAgL1tcXFxcXFxcXC86Kj9cXFwiPD58XS9nLFxuICAgICAgICBcIi1cIlxuICAgICAgKTtcblxuICAgICAgLy8g5aaC5p6c5paH5Lu25ZCN5bey5a2Y5Zyo77yM5YiZ55So6ZqP5py65YC85pu/5o2i77yM5LiN5a+55paH5Lu25ZCO57yA6L+b6KGM5Yik5patXG4gICAgICBpZiAoZXhpc3RzU3luYyhqb2luKGZvbGRlclBhdGgpKSkge1xuICAgICAgICBuYW1lID0gKE1hdGgucmFuZG9tKCkgKyAxKS50b1N0cmluZygzNikuc3Vic3RyKDIsIDUpO1xuICAgICAgfVxuICAgICAgaWYgKG5hbWVTZXQuaGFzKG5hbWUpKSB7XG4gICAgICAgIG5hbWUgPSBgJHtuYW1lfS0keyhNYXRoLnJhbmRvbSgpICsgMSkudG9TdHJpbmcoMzYpLnN1YnN0cigyLCA1KX1gO1xuICAgICAgfVxuICAgICAgbmFtZVNldC5hZGQobmFtZSk7XG5cbiAgICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgdGhpcy5kb3dubG9hZCh1cmwsIGZvbGRlclBhdGgsIG5hbWUpO1xuICAgICAgaWYgKHJlc3BvbnNlLm9rKSB7XG4gICAgICAgIGNvbnN0IGFjdGl2ZUZvbGRlciA9IG5vcm1hbGl6ZVBhdGgoXG4gICAgICAgICAgdGhpcy5hcHAud29ya3NwYWNlLmdldEFjdGl2ZUZpbGUoKS5wYXJlbnQucGF0aFxuICAgICAgICApO1xuICAgICAgICBjb25zdCBhYnN0cmFjdEFjdGl2ZUZvbGRlciA9IChcbiAgICAgICAgICB0aGlzLmFwcC52YXVsdC5hZGFwdGVyIGFzIEZpbGVTeXN0ZW1BZGFwdGVyXG4gICAgICAgICkuZ2V0RnVsbFBhdGgoYWN0aXZlRm9sZGVyKTtcblxuICAgICAgICBpbWFnZUFycmF5LnB1c2goe1xuICAgICAgICAgIHNvdXJjZTogZmlsZS5zb3VyY2UsXG4gICAgICAgICAgbmFtZTogbmFtZSxcbiAgICAgICAgICBwYXRoOiBub3JtYWxpemVQYXRoKHJlbGF0aXZlKGFic3RyYWN0QWN0aXZlRm9sZGVyLCByZXNwb25zZS5wYXRoKSksXG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgIH1cblxuICAgIGxldCB2YWx1ZSA9IHRoaXMuaGVscGVyLmdldFZhbHVlKCk7XG4gICAgaW1hZ2VBcnJheS5tYXAoaW1hZ2UgPT4ge1xuICAgICAgbGV0IG5hbWUgPSB0aGlzLmhhbmRsZU5hbWUoaW1hZ2UubmFtZSk7XG5cbiAgICAgIHZhbHVlID0gdmFsdWUucmVwbGFjZShcbiAgICAgICAgaW1hZ2Uuc291cmNlLFxuICAgICAgICBgIVske25hbWV9XSgke2VuY29kZVVSSShpbWFnZS5wYXRoKX0pYFxuICAgICAgKTtcbiAgICB9KTtcblxuICAgIHRoaXMuaGVscGVyLnNldFZhbHVlKHZhbHVlKTtcblxuICAgIG5ldyBOb3RpY2UoXG4gICAgICBgYWxsOiAke2ZpbGVBcnJheS5sZW5ndGh9XFxuc3VjY2VzczogJHtpbWFnZUFycmF5Lmxlbmd0aH1cXG5mYWlsZWQ6ICR7XG4gICAgICAgIGZpbGVBcnJheS5sZW5ndGggLSBpbWFnZUFycmF5Lmxlbmd0aFxuICAgICAgfWBcbiAgICApO1xuICB9XG5cbiAgLy8g6I635Y+W5b2T5YmN5paH5Lu25omA5bGe55qE6ZmE5Lu25paH5Lu25aS5XG4gIGdldEZpbGVBc3NldFBhdGgoKSB7XG4gICAgY29uc3QgYmFzZVBhdGggPSAoXG4gICAgICB0aGlzLmFwcC52YXVsdC5hZGFwdGVyIGFzIEZpbGVTeXN0ZW1BZGFwdGVyXG4gICAgKS5nZXRCYXNlUGF0aCgpO1xuXG4gICAgLy8gQHRzLWlnbm9yZVxuICAgIGNvbnN0IGFzc2V0Rm9sZGVyOiBzdHJpbmcgPSB0aGlzLmFwcC52YXVsdC5jb25maWcuYXR0YWNobWVudEZvbGRlclBhdGg7XG4gICAgY29uc3QgYWN0aXZlRmlsZSA9IHRoaXMuYXBwLnZhdWx0LmdldEFic3RyYWN0RmlsZUJ5UGF0aChcbiAgICAgIHRoaXMuYXBwLndvcmtzcGFjZS5nZXRBY3RpdmVGaWxlKCkucGF0aFxuICAgICk7XG5cbiAgICAvLyDlvZPliY3mlofku7blpLnkuIvnmoTlrZDmlofku7blpLlcbiAgICBpZiAoYXNzZXRGb2xkZXIuc3RhcnRzV2l0aChcIi4vXCIpKSB7XG4gICAgICBjb25zdCBhY3RpdmVGb2xkZXIgPSBkZWNvZGVVUkkocmVzb2x2ZShiYXNlUGF0aCwgYWN0aXZlRmlsZS5wYXJlbnQucGF0aCkpO1xuICAgICAgcmV0dXJuIGpvaW4oYWN0aXZlRm9sZGVyLCBhc3NldEZvbGRlcik7XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIOagueaWh+S7tuWkuVxuICAgICAgcmV0dXJuIGpvaW4oYmFzZVBhdGgsIGFzc2V0Rm9sZGVyKTtcbiAgICB9XG4gIH1cblxuICBhc3luYyBkb3dubG9hZCh1cmw6IHN0cmluZywgZm9sZGVyUGF0aDogc3RyaW5nLCBuYW1lOiBzdHJpbmcpIHtcbiAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IHJlcXVlc3RVcmwoeyB1cmwgfSk7XG4gICAgY29uc3QgdHlwZSA9IGF3YWl0IGltYWdlVHlwZShuZXcgVWludDhBcnJheShyZXNwb25zZS5hcnJheUJ1ZmZlcikpO1xuXG4gICAgaWYgKHJlc3BvbnNlLnN0YXR1cyAhPT0gMjAwKSB7XG4gICAgICByZXR1cm4ge1xuICAgICAgICBvazogZmFsc2UsXG4gICAgICAgIG1zZzogXCJlcnJvclwiLFxuICAgICAgfTtcbiAgICB9XG4gICAgaWYgKCF0eXBlKSB7XG4gICAgICByZXR1cm4ge1xuICAgICAgICBvazogZmFsc2UsXG4gICAgICAgIG1zZzogXCJlcnJvclwiLFxuICAgICAgfTtcbiAgICB9XG5cbiAgICBjb25zdCBidWZmZXIgPSBCdWZmZXIuZnJvbShyZXNwb25zZS5hcnJheUJ1ZmZlcik7XG5cbiAgICB0cnkge1xuICAgICAgY29uc3QgcGF0aCA9IGpvaW4oZm9sZGVyUGF0aCwgYCR7bmFtZX0uJHt0eXBlLmV4dH1gKTtcblxuICAgICAgd3JpdGVGaWxlU3luYyhwYXRoLCBidWZmZXIpO1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgb2s6IHRydWUsXG4gICAgICAgIG1zZzogXCJva1wiLFxuICAgICAgICBwYXRoOiBwYXRoLFxuICAgICAgICB0eXBlLFxuICAgICAgfTtcbiAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIG9rOiBmYWxzZSxcbiAgICAgICAgbXNnOiBlcnIsXG4gICAgICB9O1xuICAgIH1cbiAgfVxuXG4gIHJlZ2lzdGVyRmlsZU1lbnUoKSB7XG4gICAgdGhpcy5yZWdpc3RlckV2ZW50KFxuICAgICAgdGhpcy5hcHAud29ya3NwYWNlLm9uKFxuICAgICAgICBcImZpbGUtbWVudVwiLFxuICAgICAgICAobWVudTogTWVudSwgZmlsZTogVEZpbGUsIHNvdXJjZTogc3RyaW5nLCBsZWFmKSA9PiB7XG4gICAgICAgICAgaWYgKHNvdXJjZSA9PT0gXCJjYW52YXMtbWVudVwiKSByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgaWYgKCFpc0Fzc2V0VHlwZUFuSW1hZ2UoZmlsZS5wYXRoKSkgcmV0dXJuIGZhbHNlO1xuXG4gICAgICAgICAgbWVudS5hZGRJdGVtKChpdGVtOiBNZW51SXRlbSkgPT4ge1xuICAgICAgICAgICAgaXRlbVxuICAgICAgICAgICAgICAuc2V0VGl0bGUoXCJVcGxvYWRcIilcbiAgICAgICAgICAgICAgLnNldEljb24oXCJ1cGxvYWRcIilcbiAgICAgICAgICAgICAgLm9uQ2xpY2soKCkgPT4ge1xuICAgICAgICAgICAgICAgIGlmICghKGZpbGUgaW5zdGFuY2VvZiBURmlsZSkpIHtcbiAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgdGhpcy5maWxlTWVudVVwbG9hZChmaWxlKTtcbiAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgIClcbiAgICApO1xuICB9XG5cbiAgZmlsZU1lbnVVcGxvYWQoZmlsZTogVEZpbGUpIHtcbiAgICBsZXQgY29udGVudCA9IHRoaXMuaGVscGVyLmdldFZhbHVlKCk7XG5cbiAgICBjb25zdCBiYXNlUGF0aCA9IChcbiAgICAgIHRoaXMuYXBwLnZhdWx0LmFkYXB0ZXIgYXMgRmlsZVN5c3RlbUFkYXB0ZXJcbiAgICApLmdldEJhc2VQYXRoKCk7XG4gICAgbGV0IGltYWdlTGlzdDogSW1hZ2VbXSA9IFtdO1xuICAgIGNvbnN0IGZpbGVBcnJheSA9IHRoaXMuaGVscGVyLmdldEFsbEZpbGVzKCk7XG5cbiAgICBmb3IgKGNvbnN0IG1hdGNoIG9mIGZpbGVBcnJheSkge1xuICAgICAgY29uc3QgaW1hZ2VOYW1lID0gbWF0Y2gubmFtZTtcbiAgICAgIGNvbnN0IGVuY29kZWRVcmkgPSBtYXRjaC5wYXRoO1xuXG4gICAgICBjb25zdCBmaWxlTmFtZSA9IGJhc2VuYW1lKGRlY29kZVVSSShlbmNvZGVkVXJpKSk7XG5cbiAgICAgIGlmIChmaWxlICYmIGZpbGUubmFtZSA9PT0gZmlsZU5hbWUpIHtcbiAgICAgICAgY29uc3QgYWJzdHJhY3RJbWFnZUZpbGUgPSBqb2luKGJhc2VQYXRoLCBmaWxlLnBhdGgpO1xuXG4gICAgICAgIGlmIChpc0Fzc2V0VHlwZUFuSW1hZ2UoYWJzdHJhY3RJbWFnZUZpbGUpKSB7XG4gICAgICAgICAgaW1hZ2VMaXN0LnB1c2goe1xuICAgICAgICAgICAgcGF0aDogYWJzdHJhY3RJbWFnZUZpbGUsXG4gICAgICAgICAgICBuYW1lOiBpbWFnZU5hbWUsXG4gICAgICAgICAgICBzb3VyY2U6IG1hdGNoLnNvdXJjZSxcbiAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIGlmIChpbWFnZUxpc3QubGVuZ3RoID09PSAwKSB7XG4gICAgICBuZXcgTm90aWNlKFwi5rKh5pyJ6Kej5p6Q5Yiw5Zu+5YOP5paH5Lu2XCIpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHRoaXMudXBsb2FkZXIudXBsb2FkRmlsZXMoaW1hZ2VMaXN0Lm1hcChpdGVtID0+IGl0ZW0ucGF0aCkpLnRoZW4ocmVzID0+IHtcbiAgICAgIGlmIChyZXMuc3VjY2Vzcykge1xuICAgICAgICBsZXQgdXBsb2FkVXJsTGlzdCA9IHJlcy5yZXN1bHQ7XG4gICAgICAgIGltYWdlTGlzdC5tYXAoaXRlbSA9PiB7XG4gICAgICAgICAgY29uc3QgdXBsb2FkSW1hZ2UgPSB1cGxvYWRVcmxMaXN0LnNoaWZ0KCk7XG4gICAgICAgICAgbGV0IG5hbWUgPSB0aGlzLmhhbmRsZU5hbWUoaXRlbS5uYW1lKTtcblxuICAgICAgICAgIGNvbnRlbnQgPSBjb250ZW50LnJlcGxhY2VBbGwoXG4gICAgICAgICAgICBpdGVtLnNvdXJjZSxcbiAgICAgICAgICAgIGAhWyR7bmFtZX1dKCR7dXBsb2FkSW1hZ2V9KWBcbiAgICAgICAgICApO1xuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5oZWxwZXIuc2V0VmFsdWUoY29udGVudCk7XG5cbiAgICAgICAgaWYgKHRoaXMuc2V0dGluZ3MuZGVsZXRlU291cmNlKSB7XG4gICAgICAgICAgaW1hZ2VMaXN0Lm1hcChpbWFnZSA9PiB7XG4gICAgICAgICAgICBpZiAoIWltYWdlLnBhdGguc3RhcnRzV2l0aChcImh0dHBcIikpIHtcbiAgICAgICAgICAgICAgdW5saW5rKGltYWdlLnBhdGgsICgpID0+IHt9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgbmV3IE5vdGljZShcIlVwbG9hZCBlcnJvclwiKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuXG4gIGZpbHRlckZpbGUoZmlsZUFycmF5OiBJbWFnZVtdKSB7XG4gICAgY29uc3QgaW1hZ2VMaXN0OiBJbWFnZVtdID0gW107XG5cbiAgICBmb3IgKGNvbnN0IG1hdGNoIG9mIGZpbGVBcnJheSkge1xuICAgICAgaWYgKG1hdGNoLnBhdGguc3RhcnRzV2l0aChcImh0dHBcIikpIHtcbiAgICAgICAgaWYgKHRoaXMuc2V0dGluZ3Mud29ya09uTmV0V29yaykge1xuICAgICAgICAgIGlmIChcbiAgICAgICAgICAgICF0aGlzLmhlbHBlci5oYXNCbGFja0RvbWFpbihcbiAgICAgICAgICAgICAgbWF0Y2gucGF0aCxcbiAgICAgICAgICAgICAgdGhpcy5zZXR0aW5ncy5uZXdXb3JrQmxhY2tEb21haW5zXG4gICAgICAgICAgICApXG4gICAgICAgICAgKSB7XG4gICAgICAgICAgICBpbWFnZUxpc3QucHVzaCh7XG4gICAgICAgICAgICAgIHBhdGg6IG1hdGNoLnBhdGgsXG4gICAgICAgICAgICAgIG5hbWU6IG1hdGNoLm5hbWUsXG4gICAgICAgICAgICAgIHNvdXJjZTogbWF0Y2guc291cmNlLFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBpbWFnZUxpc3QucHVzaCh7XG4gICAgICAgICAgcGF0aDogbWF0Y2gucGF0aCxcbiAgICAgICAgICBuYW1lOiBtYXRjaC5uYW1lLFxuICAgICAgICAgIHNvdXJjZTogbWF0Y2guc291cmNlLFxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gaW1hZ2VMaXN0O1xuICB9XG4gIGdldEZpbGUoZmlsZU5hbWU6IHN0cmluZywgZmlsZU1hcDogYW55KSB7XG4gICAgaWYgKCFmaWxlTWFwKSB7XG4gICAgICBmaWxlTWFwID0gYXJyYXlUb09iamVjdCh0aGlzLmFwcC52YXVsdC5nZXRGaWxlcygpLCBcIm5hbWVcIik7XG4gICAgfVxuICAgIHJldHVybiBmaWxlTWFwW2ZpbGVOYW1lXTtcbiAgfVxuICAvLyB1cGxvZGEgYWxsIGZpbGVcbiAgdXBsb2FkQWxsRmlsZSgpIHtcbiAgICBsZXQgY29udGVudCA9IHRoaXMuaGVscGVyLmdldFZhbHVlKCk7XG5cbiAgICBjb25zdCBiYXNlUGF0aCA9IChcbiAgICAgIHRoaXMuYXBwLnZhdWx0LmFkYXB0ZXIgYXMgRmlsZVN5c3RlbUFkYXB0ZXJcbiAgICApLmdldEJhc2VQYXRoKCk7XG4gICAgY29uc3QgYWN0aXZlRmlsZSA9IHRoaXMuYXBwLndvcmtzcGFjZS5nZXRBY3RpdmVGaWxlKCk7XG4gICAgY29uc3QgZmlsZU1hcCA9IGFycmF5VG9PYmplY3QodGhpcy5hcHAudmF1bHQuZ2V0RmlsZXMoKSwgXCJuYW1lXCIpO1xuICAgIGNvbnN0IGZpbGVQYXRoTWFwID0gYXJyYXlUb09iamVjdCh0aGlzLmFwcC52YXVsdC5nZXRGaWxlcygpLCBcInBhdGhcIik7XG4gICAgbGV0IGltYWdlTGlzdDogSW1hZ2VbXSA9IFtdO1xuICAgIGNvbnN0IGZpbGVBcnJheSA9IHRoaXMuZmlsdGVyRmlsZSh0aGlzLmhlbHBlci5nZXRBbGxGaWxlcygpKTtcblxuICAgIGZvciAoY29uc3QgbWF0Y2ggb2YgZmlsZUFycmF5KSB7XG4gICAgICBjb25zdCBpbWFnZU5hbWUgPSBtYXRjaC5uYW1lO1xuICAgICAgY29uc3QgZW5jb2RlZFVyaSA9IG1hdGNoLnBhdGg7XG5cbiAgICAgIGlmIChlbmNvZGVkVXJpLnN0YXJ0c1dpdGgoXCJodHRwXCIpKSB7XG4gICAgICAgIGltYWdlTGlzdC5wdXNoKHtcbiAgICAgICAgICBwYXRoOiBtYXRjaC5wYXRoLFxuICAgICAgICAgIG5hbWU6IGltYWdlTmFtZSxcbiAgICAgICAgICBzb3VyY2U6IG1hdGNoLnNvdXJjZSxcbiAgICAgICAgfSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBjb25zdCBmaWxlTmFtZSA9IGJhc2VuYW1lKGRlY29kZVVSSShlbmNvZGVkVXJpKSk7XG4gICAgICAgIGxldCBmaWxlO1xuICAgICAgICAvLyDnu53lr7not6/lvoRcbiAgICAgICAgaWYgKGZpbGVQYXRoTWFwW2RlY29kZVVSSShlbmNvZGVkVXJpKV0pIHtcbiAgICAgICAgICBmaWxlID0gZmlsZVBhdGhNYXBbZGVjb2RlVVJJKGVuY29kZWRVcmkpXTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIOebuOWvuei3r+W+hFxuICAgICAgICBpZiAoXG4gICAgICAgICAgKCFmaWxlICYmIGRlY29kZVVSSShlbmNvZGVkVXJpKS5zdGFydHNXaXRoKFwiLi9cIikpIHx8XG4gICAgICAgICAgZGVjb2RlVVJJKGVuY29kZWRVcmkpLnN0YXJ0c1dpdGgoXCIuLi9cIilcbiAgICAgICAgKSB7XG4gICAgICAgICAgY29uc3QgZmlsZVBhdGggPSByZXNvbHZlKFxuICAgICAgICAgICAgam9pbihiYXNlUGF0aCwgZGlybmFtZShhY3RpdmVGaWxlLnBhdGgpKSxcbiAgICAgICAgICAgIGRlY29kZVVSSShlbmNvZGVkVXJpKVxuICAgICAgICAgICk7XG5cbiAgICAgICAgICBpZiAoZXhpc3RzU3luYyhmaWxlUGF0aCkpIHtcbiAgICAgICAgICAgIGNvbnN0IHBhdGggPSBub3JtYWxpemVQYXRoKFxuICAgICAgICAgICAgICByZWxhdGl2ZShcbiAgICAgICAgICAgICAgICBiYXNlUGF0aCxcbiAgICAgICAgICAgICAgICByZXNvbHZlKFxuICAgICAgICAgICAgICAgICAgam9pbihiYXNlUGF0aCwgZGlybmFtZShhY3RpdmVGaWxlLnBhdGgpKSxcbiAgICAgICAgICAgICAgICAgIGRlY29kZVVSSShlbmNvZGVkVXJpKVxuICAgICAgICAgICAgICAgIClcbiAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgKTtcblxuICAgICAgICAgICAgZmlsZSA9IGZpbGVQYXRoTWFwW3BhdGhdO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICAvLyDlsL3lj6/og73nn63ot6/lvoRcbiAgICAgICAgaWYgKCFmaWxlKSB7XG4gICAgICAgICAgZmlsZSA9IHRoaXMuZ2V0RmlsZShmaWxlTmFtZSwgZmlsZU1hcCk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoZmlsZSkge1xuICAgICAgICAgIGNvbnN0IGFic3RyYWN0SW1hZ2VGaWxlID0gam9pbihiYXNlUGF0aCwgZmlsZS5wYXRoKTtcblxuICAgICAgICAgIGlmIChpc0Fzc2V0VHlwZUFuSW1hZ2UoYWJzdHJhY3RJbWFnZUZpbGUpKSB7XG4gICAgICAgICAgICBpbWFnZUxpc3QucHVzaCh7XG4gICAgICAgICAgICAgIHBhdGg6IGFic3RyYWN0SW1hZ2VGaWxlLFxuICAgICAgICAgICAgICBuYW1lOiBpbWFnZU5hbWUsXG4gICAgICAgICAgICAgIHNvdXJjZTogbWF0Y2guc291cmNlLFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKGltYWdlTGlzdC5sZW5ndGggPT09IDApIHtcbiAgICAgIG5ldyBOb3RpY2UoXCLmsqHmnInop6PmnpDliLDlm77lg4/mlofku7ZcIik7XG4gICAgICByZXR1cm47XG4gICAgfSBlbHNlIHtcbiAgICAgIG5ldyBOb3RpY2UoYOWFseaJvuWIsCR7aW1hZ2VMaXN0Lmxlbmd0aH3kuKrlm77lg4/mlofku7bvvIzlvIDlp4vkuIrkvKBgKTtcbiAgICB9XG5cbiAgICB0aGlzLnVwbG9hZGVyLnVwbG9hZEZpbGVzKGltYWdlTGlzdC5tYXAoaXRlbSA9PiBpdGVtLnBhdGgpKS50aGVuKHJlcyA9PiB7XG4gICAgICBpZiAocmVzLnN1Y2Nlc3MpIHtcbiAgICAgICAgbGV0IHVwbG9hZFVybExpc3QgPSByZXMucmVzdWx0O1xuXG4gICAgICAgIGltYWdlTGlzdC5tYXAoaXRlbSA9PiB7XG4gICAgICAgICAgY29uc3QgdXBsb2FkSW1hZ2UgPSB1cGxvYWRVcmxMaXN0LnNoaWZ0KCk7XG5cbiAgICAgICAgICBsZXQgbmFtZSA9IHRoaXMuaGFuZGxlTmFtZShpdGVtLm5hbWUpO1xuICAgICAgICAgIGNvbnRlbnQgPSBjb250ZW50LnJlcGxhY2VBbGwoXG4gICAgICAgICAgICBpdGVtLnNvdXJjZSxcbiAgICAgICAgICAgIGAhWyR7bmFtZX1dKCR7dXBsb2FkSW1hZ2V9KWBcbiAgICAgICAgICApO1xuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5oZWxwZXIuc2V0VmFsdWUoY29udGVudCk7XG5cbiAgICAgICAgaWYgKHRoaXMuc2V0dGluZ3MuZGVsZXRlU291cmNlKSB7XG4gICAgICAgICAgaW1hZ2VMaXN0Lm1hcChpbWFnZSA9PiB7XG4gICAgICAgICAgICBpZiAoIWltYWdlLnBhdGguc3RhcnRzV2l0aChcImh0dHBcIikpIHtcbiAgICAgICAgICAgICAgdW5saW5rKGltYWdlLnBhdGgsICgpID0+IHt9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgbmV3IE5vdGljZShcIlVwbG9hZCBlcnJvclwiKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuXG4gIHNldHVwUGFzdGVIYW5kbGVyKCkge1xuICAgIHRoaXMucmVnaXN0ZXJFdmVudChcbiAgICAgIHRoaXMuYXBwLndvcmtzcGFjZS5vbihcbiAgICAgICAgXCJlZGl0b3ItcGFzdGVcIixcbiAgICAgICAgKGV2dDogQ2xpcGJvYXJkRXZlbnQsIGVkaXRvcjogRWRpdG9yLCBtYXJrZG93blZpZXc6IE1hcmtkb3duVmlldykgPT4ge1xuICAgICAgICAgIGNvbnN0IGFsbG93VXBsb2FkID0gdGhpcy5oZWxwZXIuZ2V0RnJvbnRtYXR0ZXJWYWx1ZShcbiAgICAgICAgICAgIFwiaW1hZ2UtYXV0by11cGxvYWRcIixcbiAgICAgICAgICAgIHRoaXMuc2V0dGluZ3MudXBsb2FkQnlDbGlwU3dpdGNoXG4gICAgICAgICAgKTtcblxuICAgICAgICAgIGxldCBmaWxlcyA9IGV2dC5jbGlwYm9hcmREYXRhLmZpbGVzO1xuICAgICAgICAgIGlmICghYWxsb3dVcGxvYWQpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICAvLyDliarotLTmnb/lhoXlrrnmnIltZOagvOW8j+eahOWbvueJh+aXtlxuICAgICAgICAgIGlmICh0aGlzLnNldHRpbmdzLndvcmtPbk5ldFdvcmspIHtcbiAgICAgICAgICAgIGNvbnN0IGNsaXBib2FyZFZhbHVlID0gZXZ0LmNsaXBib2FyZERhdGEuZ2V0RGF0YShcInRleHQvcGxhaW5cIik7XG4gICAgICAgICAgICBjb25zdCBpbWFnZUxpc3QgPSB0aGlzLmhlbHBlclxuICAgICAgICAgICAgICAuZ2V0SW1hZ2VMaW5rKGNsaXBib2FyZFZhbHVlKVxuICAgICAgICAgICAgICAuZmlsdGVyKGltYWdlID0+IGltYWdlLnBhdGguc3RhcnRzV2l0aChcImh0dHBcIikpXG4gICAgICAgICAgICAgIC5maWx0ZXIoXG4gICAgICAgICAgICAgICAgaW1hZ2UgPT5cbiAgICAgICAgICAgICAgICAgICF0aGlzLmhlbHBlci5oYXNCbGFja0RvbWFpbihcbiAgICAgICAgICAgICAgICAgICAgaW1hZ2UucGF0aCxcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5zZXR0aW5ncy5uZXdXb3JrQmxhY2tEb21haW5zXG4gICAgICAgICAgICAgICAgICApXG4gICAgICAgICAgICAgICk7XG5cbiAgICAgICAgICAgIGlmIChpbWFnZUxpc3QubGVuZ3RoICE9PSAwKSB7XG4gICAgICAgICAgICAgIHRoaXMudXBsb2FkZXJcbiAgICAgICAgICAgICAgICAudXBsb2FkRmlsZXMoaW1hZ2VMaXN0Lm1hcChpdGVtID0+IGl0ZW0ucGF0aCkpXG4gICAgICAgICAgICAgICAgLnRoZW4ocmVzID0+IHtcbiAgICAgICAgICAgICAgICAgIGxldCB2YWx1ZSA9IHRoaXMuaGVscGVyLmdldFZhbHVlKCk7XG4gICAgICAgICAgICAgICAgICBpZiAocmVzLnN1Y2Nlc3MpIHtcbiAgICAgICAgICAgICAgICAgICAgbGV0IHVwbG9hZFVybExpc3QgPSByZXMucmVzdWx0O1xuICAgICAgICAgICAgICAgICAgICBpbWFnZUxpc3QubWFwKGl0ZW0gPT4ge1xuICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHVwbG9hZEltYWdlID0gdXBsb2FkVXJsTGlzdC5zaGlmdCgpO1xuICAgICAgICAgICAgICAgICAgICAgIGxldCBuYW1lID0gdGhpcy5oYW5kbGVOYW1lKGl0ZW0ubmFtZSk7XG5cbiAgICAgICAgICAgICAgICAgICAgICB2YWx1ZSA9IHZhbHVlLnJlcGxhY2VBbGwoXG4gICAgICAgICAgICAgICAgICAgICAgICBpdGVtLnNvdXJjZSxcbiAgICAgICAgICAgICAgICAgICAgICAgIGAhWyR7bmFtZX1dKCR7dXBsb2FkSW1hZ2V9KWBcbiAgICAgICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5oZWxwZXIuc2V0VmFsdWUodmFsdWUpO1xuICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgbmV3IE5vdGljZShcIlVwbG9hZCBlcnJvclwiKTtcbiAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG5cbiAgICAgICAgICAvLyDliarotLTmnb/kuK3mmK/lm77niYfml7bov5vooYzkuIrkvKBcbiAgICAgICAgICBpZiAodGhpcy5jYW5VcGxvYWQoZXZ0LmNsaXBib2FyZERhdGEpKSB7XG4gICAgICAgICAgICB0aGlzLnVwbG9hZEZpbGVBbmRFbWJlZEltZ3VySW1hZ2UoXG4gICAgICAgICAgICAgIGVkaXRvcixcbiAgICAgICAgICAgICAgYXN5bmMgKGVkaXRvcjogRWRpdG9yLCBwYXN0ZUlkOiBzdHJpbmcpID0+IHtcbiAgICAgICAgICAgICAgICBsZXQgcmVzID0gYXdhaXQgdGhpcy51cGxvYWRlci51cGxvYWRGaWxlQnlDbGlwYm9hcmQoKTtcbiAgICAgICAgICAgICAgICBpZiAocmVzLmNvZGUgIT09IDApIHtcbiAgICAgICAgICAgICAgICAgIHRoaXMuaGFuZGxlRmFpbGVkVXBsb2FkKGVkaXRvciwgcGFzdGVJZCwgcmVzLm1zZyk7XG4gICAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGNvbnN0IHVybCA9IHJlcy5kYXRhO1xuXG4gICAgICAgICAgICAgICAgcmV0dXJuIHVybDtcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgZXZ0LmNsaXBib2FyZERhdGFcbiAgICAgICAgICAgICkuY2F0Y2goKTtcbiAgICAgICAgICAgIGV2dC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgKVxuICAgICk7XG4gICAgdGhpcy5yZWdpc3RlckV2ZW50KFxuICAgICAgdGhpcy5hcHAud29ya3NwYWNlLm9uKFxuICAgICAgICBcImVkaXRvci1kcm9wXCIsXG4gICAgICAgIGFzeW5jIChldnQ6IERyYWdFdmVudCwgZWRpdG9yOiBFZGl0b3IsIG1hcmtkb3duVmlldzogTWFya2Rvd25WaWV3KSA9PiB7XG4gICAgICAgICAgY29uc3QgYWxsb3dVcGxvYWQgPSB0aGlzLmhlbHBlci5nZXRGcm9udG1hdHRlclZhbHVlKFxuICAgICAgICAgICAgXCJpbWFnZS1hdXRvLXVwbG9hZFwiLFxuICAgICAgICAgICAgdGhpcy5zZXR0aW5ncy51cGxvYWRCeUNsaXBTd2l0Y2hcbiAgICAgICAgICApO1xuICAgICAgICAgIGxldCBmaWxlcyA9IGV2dC5kYXRhVHJhbnNmZXIuZmlsZXM7XG5cbiAgICAgICAgICBpZiAoIWFsbG93VXBsb2FkKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgaWYgKGZpbGVzLmxlbmd0aCAhPT0gMCAmJiBmaWxlc1swXS50eXBlLnN0YXJ0c1dpdGgoXCJpbWFnZVwiKSkge1xuICAgICAgICAgICAgbGV0IHNlbmRGaWxlczogQXJyYXk8U3RyaW5nPiA9IFtdO1xuICAgICAgICAgICAgbGV0IGZpbGVzID0gZXZ0LmRhdGFUcmFuc2Zlci5maWxlcztcbiAgICAgICAgICAgIEFycmF5LmZyb20oZmlsZXMpLmZvckVhY2goKGl0ZW0sIGluZGV4KSA9PiB7XG4gICAgICAgICAgICAgIHNlbmRGaWxlcy5wdXNoKGl0ZW0ucGF0aCk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIGV2dC5wcmV2ZW50RGVmYXVsdCgpO1xuXG4gICAgICAgICAgICBjb25zdCBkYXRhID0gYXdhaXQgdGhpcy51cGxvYWRlci51cGxvYWRGaWxlcyhzZW5kRmlsZXMpO1xuXG4gICAgICAgICAgICBpZiAoZGF0YS5zdWNjZXNzKSB7XG4gICAgICAgICAgICAgIGRhdGEucmVzdWx0Lm1hcCgodmFsdWU6IHN0cmluZykgPT4ge1xuICAgICAgICAgICAgICAgIGxldCBwYXN0ZUlkID0gKE1hdGgucmFuZG9tKCkgKyAxKS50b1N0cmluZygzNikuc3Vic3RyKDIsIDUpO1xuICAgICAgICAgICAgICAgIHRoaXMuaW5zZXJ0VGVtcG9yYXJ5VGV4dChlZGl0b3IsIHBhc3RlSWQpO1xuICAgICAgICAgICAgICAgIHRoaXMuZW1iZWRNYXJrRG93bkltYWdlKGVkaXRvciwgcGFzdGVJZCwgdmFsdWUsIGZpbGVzWzBdLm5hbWUpO1xuICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIG5ldyBOb3RpY2UoXCJVcGxvYWQgZXJyb3JcIik7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICApXG4gICAgKTtcbiAgfVxuXG4gIGNhblVwbG9hZChjbGlwYm9hcmREYXRhOiBEYXRhVHJhbnNmZXIpIHtcbiAgICB0aGlzLnNldHRpbmdzLmFwcGx5SW1hZ2U7XG4gICAgY29uc3QgZmlsZXMgPSBjbGlwYm9hcmREYXRhLmZpbGVzO1xuICAgIGNvbnN0IHRleHQgPSBjbGlwYm9hcmREYXRhLmdldERhdGEoXCJ0ZXh0XCIpO1xuXG4gICAgY29uc3QgaGFzSW1hZ2VGaWxlID1cbiAgICAgIGZpbGVzLmxlbmd0aCAhPT0gMCAmJiBmaWxlc1swXS50eXBlLnN0YXJ0c1dpdGgoXCJpbWFnZVwiKTtcbiAgICBpZiAoaGFzSW1hZ2VGaWxlKSB7XG4gICAgICBpZiAoISF0ZXh0KSB7XG4gICAgICAgIHJldHVybiB0aGlzLnNldHRpbmdzLmFwcGx5SW1hZ2U7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgfVxuXG4gIGFzeW5jIHVwbG9hZEZpbGVBbmRFbWJlZEltZ3VySW1hZ2UoXG4gICAgZWRpdG9yOiBFZGl0b3IsXG4gICAgY2FsbGJhY2s6IEZ1bmN0aW9uLFxuICAgIGNsaXBib2FyZERhdGE6IERhdGFUcmFuc2ZlclxuICApIHtcbiAgICBsZXQgcGFzdGVJZCA9IChNYXRoLnJhbmRvbSgpICsgMSkudG9TdHJpbmcoMzYpLnN1YnN0cigyLCA1KTtcbiAgICB0aGlzLmluc2VydFRlbXBvcmFyeVRleHQoZWRpdG9yLCBwYXN0ZUlkKTtcbiAgICBjb25zdCBuYW1lID0gY2xpcGJvYXJkRGF0YS5maWxlc1swXS5uYW1lO1xuXG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IHVybCA9IGF3YWl0IGNhbGxiYWNrKGVkaXRvciwgcGFzdGVJZCk7XG4gICAgICB0aGlzLmVtYmVkTWFya0Rvd25JbWFnZShlZGl0b3IsIHBhc3RlSWQsIHVybCwgbmFtZSk7XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgdGhpcy5oYW5kbGVGYWlsZWRVcGxvYWQoZWRpdG9yLCBwYXN0ZUlkLCBlKTtcbiAgICB9XG4gIH1cblxuICBpbnNlcnRUZW1wb3JhcnlUZXh0KGVkaXRvcjogRWRpdG9yLCBwYXN0ZUlkOiBzdHJpbmcpIHtcbiAgICBsZXQgcHJvZ3Jlc3NUZXh0ID0gaW1hZ2VBdXRvVXBsb2FkUGx1Z2luLnByb2dyZXNzVGV4dEZvcihwYXN0ZUlkKTtcbiAgICBlZGl0b3IucmVwbGFjZVNlbGVjdGlvbihwcm9ncmVzc1RleHQgKyBcIlxcblwiKTtcbiAgfVxuXG4gIHByaXZhdGUgc3RhdGljIHByb2dyZXNzVGV4dEZvcihpZDogc3RyaW5nKSB7XG4gICAgcmV0dXJuIGAhW1VwbG9hZGluZyBmaWxlLi4uJHtpZH1dKClgO1xuICB9XG5cbiAgZW1iZWRNYXJrRG93bkltYWdlKFxuICAgIGVkaXRvcjogRWRpdG9yLFxuICAgIHBhc3RlSWQ6IHN0cmluZyxcbiAgICBpbWFnZVVybDogYW55LFxuICAgIG5hbWU6IHN0cmluZyA9IFwiXCJcbiAgKSB7XG4gICAgbGV0IHByb2dyZXNzVGV4dCA9IGltYWdlQXV0b1VwbG9hZFBsdWdpbi5wcm9ncmVzc1RleHRGb3IocGFzdGVJZCk7XG4gICAgbmFtZSA9IHRoaXMuaGFuZGxlTmFtZShuYW1lKTtcblxuICAgIGxldCBtYXJrRG93bkltYWdlID0gYCFbJHtuYW1lfV0oJHtpbWFnZVVybH0pYDtcblxuICAgIGltYWdlQXV0b1VwbG9hZFBsdWdpbi5yZXBsYWNlRmlyc3RPY2N1cnJlbmNlKFxuICAgICAgZWRpdG9yLFxuICAgICAgcHJvZ3Jlc3NUZXh0LFxuICAgICAgbWFya0Rvd25JbWFnZVxuICAgICk7XG4gIH1cblxuICBoYW5kbGVGYWlsZWRVcGxvYWQoZWRpdG9yOiBFZGl0b3IsIHBhc3RlSWQ6IHN0cmluZywgcmVhc29uOiBhbnkpIHtcbiAgICBuZXcgTm90aWNlKHJlYXNvbik7XG4gICAgY29uc29sZS5lcnJvcihcIkZhaWxlZCByZXF1ZXN0OiBcIiwgcmVhc29uKTtcbiAgICBsZXQgcHJvZ3Jlc3NUZXh0ID0gaW1hZ2VBdXRvVXBsb2FkUGx1Z2luLnByb2dyZXNzVGV4dEZvcihwYXN0ZUlkKTtcbiAgICBpbWFnZUF1dG9VcGxvYWRQbHVnaW4ucmVwbGFjZUZpcnN0T2NjdXJyZW5jZShcbiAgICAgIGVkaXRvcixcbiAgICAgIHByb2dyZXNzVGV4dCxcbiAgICAgIFwi4pqg77iPdXBsb2FkIGZhaWxlZCwgY2hlY2sgZGV2IGNvbnNvbGVcIlxuICAgICk7XG4gIH1cblxuICBoYW5kbGVOYW1lKG5hbWU6IHN0cmluZykge1xuICAgIGNvbnN0IGltYWdlU2l6ZVN1ZmZpeCA9IHRoaXMuc2V0dGluZ3MuaW1hZ2VTaXplU3VmZml4IHx8IFwiXCI7XG5cbiAgICBpZiAodGhpcy5zZXR0aW5ncy5pbWFnZURlc2MgPT09IFwib3JpZ2luXCIpIHtcbiAgICAgIHJldHVybiBgJHtuYW1lfSR7aW1hZ2VTaXplU3VmZml4fWA7XG4gICAgfSBlbHNlIGlmICh0aGlzLnNldHRpbmdzLmltYWdlRGVzYyA9PT0gXCJub25lXCIpIHtcbiAgICAgIHJldHVybiBcIlwiO1xuICAgIH0gZWxzZSBpZiAodGhpcy5zZXR0aW5ncy5pbWFnZURlc2MgPT09IFwicmVtb3ZlRGVmYXVsdFwiKSB7XG4gICAgICBpZiAobmFtZSA9PT0gXCJpbWFnZS5wbmdcIikge1xuICAgICAgICByZXR1cm4gXCJcIjtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiBgJHtuYW1lfSR7aW1hZ2VTaXplU3VmZml4fWA7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiBgJHtuYW1lfSR7aW1hZ2VTaXplU3VmZml4fWA7XG4gICAgfVxuICB9XG5cbiAgc3RhdGljIHJlcGxhY2VGaXJzdE9jY3VycmVuY2UoXG4gICAgZWRpdG9yOiBFZGl0b3IsXG4gICAgdGFyZ2V0OiBzdHJpbmcsXG4gICAgcmVwbGFjZW1lbnQ6IHN0cmluZ1xuICApIHtcbiAgICBsZXQgbGluZXMgPSBlZGl0b3IuZ2V0VmFsdWUoKS5zcGxpdChcIlxcblwiKTtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IGxpbmVzLmxlbmd0aDsgaSsrKSB7XG4gICAgICBsZXQgY2ggPSBsaW5lc1tpXS5pbmRleE9mKHRhcmdldCk7XG4gICAgICBpZiAoY2ggIT0gLTEpIHtcbiAgICAgICAgbGV0IGZyb20gPSB7IGxpbmU6IGksIGNoOiBjaCB9O1xuICAgICAgICBsZXQgdG8gPSB7IGxpbmU6IGksIGNoOiBjaCArIHRhcmdldC5sZW5ndGggfTtcbiAgICAgICAgZWRpdG9yLnJlcGxhY2VSYW5nZShyZXBsYWNlbWVudCwgZnJvbSwgdG8pO1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICB9XG4gIH1cbn1cbiJdLCJuYW1lcyI6WyJjb3JlIiwiZ2xvYmFsIiwicmVxdWlyZSQkMSIsInJlcXVpcmUkJDIiLCJpc2V4ZSIsInBhdGgiLCJyZXF1aXJlJCQwIiwid2hpY2giLCJwYXRoS2V5TW9kdWxlIiwicmVzb2x2ZUNvbW1hbmQiLCJzaGViYW5nUmVnZXgiLCJzaGViYW5nQ29tbWFuZCIsInJlYWRTaGViYW5nIiwicmVxdWlyZSQkMyIsImlzV2luIiwicGFyc2UiLCJlbm9lbnQiLCJjcm9zc1NwYXduTW9kdWxlIiwic3RyaXBGaW5hbE5ld2xpbmUiLCJtaW1pY0ZuIiwibWltaWNGbk1vZHVsZSIsIm9uZXRpbWUiLCJvbmV0aW1lTW9kdWxlIiwic2lnbmFscyIsIl9vcyIsIl9yZWFsdGltZSIsInNpZ25hbHNCeU5hbWUiLCJtYWtlRXJyb3IiLCJub3JtYWxpemVTdGRpbyIsInN0ZGlvTW9kdWxlIiwicHJvY2VzcyIsInNpZ25hbEV4aXRNb2R1bGUiLCJzcGF3bmVkS2lsbCIsInNwYXduZWRDYW5jZWwiLCJzZXR1cFRpbWVvdXQiLCJ2YWxpZGF0ZVRpbWVvdXQiLCJzZXRFeGl0SGFuZGxlciIsImlzU3RyZWFtIiwiYnVmZmVyU3RyZWFtIiwic3RyZWFtIiwiZ2V0U3RyZWFtIiwiZ2V0U3RyZWFtTW9kdWxlIiwibWVyZ2VTdHJlYW0iLCJoYW5kbGVJbnB1dCIsIm1ha2VBbGxTdHJlYW0iLCJnZXRTcGF3bmVkUmVzdWx0IiwidmFsaWRhdGVJbnB1dFN5bmMiLCJtZXJnZVByb21pc2UiLCJnZXRTcGF3bmVkUHJvbWlzZSIsImpvaW5Db21tYW5kIiwiZ2V0RXNjYXBlZENvbW1hbmQiLCJwYXJzZUNvbW1hbmQiLCJyZXF1aXJlJCQ0IiwicmVxdWlyZSQkNSIsInJlcXVpcmUkJDYiLCJyZXF1aXJlJCQ3IiwicmVxdWlyZSQkOCIsInJlcXVpcmUkJDkiLCJyZXF1aXJlJCQxMCIsInJlcXVpcmUkJDExIiwiZXhlY2FNb2R1bGUiLCJ1c2VySW5mbyIsImV4ZWNhIiwiaW5oZXJpdHNfYnJvd3Nlck1vZHVsZSIsImluaGVyaXRzTW9kdWxlIiwicmVxdWlyZSQkMTIiLCJCdWZmZXIiLCJzdHJ0b2szLmZyb21CdWZmZXIiLCJzdHJ0b2szLkVuZE9mU3RyZWFtRXJyb3IiLCJUb2tlbi5TdHJpbmdUeXBlIiwiVG9rZW4uVUlOVDgiLCJUb2tlbi5JTlQzMl9CRSIsIlRva2VuLlVJTlQ2NF9MRSIsIlRva2VuLlVJTlQxNl9CRSIsIlRva2VuLlVJTlQxNl9MRSIsIlRva2VuLlVJTlQzMl9CRSIsIlRva2VuLlVJTlQzMl9MRSIsImV4dG5hbWUiLCJyZXF1ZXN0VXJsIiwiZXhlYyIsIk1hcmtkb3duVmlldyIsIm1vbWVudCIsIlNldHRpbmciLCJQbHVnaW5TZXR0aW5nVGFiIiwiTm90aWNlIiwiYWRkSWNvbiIsImV4aXN0c1N5bmMiLCJta2RpclN5bmMiLCJqb2luIiwibm9ybWFsaXplUGF0aCIsInJlbGF0aXZlIiwicmVzb2x2ZSIsIndyaXRlRmlsZVN5bmMiLCJURmlsZSIsImJhc2VuYW1lIiwidW5saW5rIiwi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QUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQyxJQUFJLENBQUMsU0FBUyxFQUFFLFFBQVEsQ0FBQyxDQUFDLEVBQUU7QUFDdEgsUUFBUSxJQUFJLENBQUMsQ0FBQyxTQUFTLEdBQUcsU0FBUyxDQUFDLEtBQUssQ0FBQyxPQUFPLEVBQUUsVUFBVSxJQUFJLEVBQUUsQ0FBQyxFQUFFLElBQUksRUFBRSxDQUFDLENBQUM7QUFDOUUsS0FBSyxDQUFDLENBQUM7QUFDUCxDQUFDO0FBQ0Q7QUFDTyxTQUFTLFdBQVcsQ0FBQyxPQUFPLEVBQUUsSUFBSSxFQUFFO0FBQzNDLElBQUksSUFBSSxDQUFDLEdBQUcsRUFBRSxLQUFLLEVBQUUsQ0FBQyxFQUFFLElBQUksRUFBRSxXQUFXLEVBQUUsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxFQUFFLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLElBQUksRUFBRSxFQUFFLEVBQUUsR0FBRyxFQUFFLEVBQUUsRUFBRSxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQztBQUNySCxJQUFJLE9BQU8sQ0FBQyxHQUFHLEVBQUUsSUFBSSxFQUFFLElBQUksQ0FBQyxDQUFDLENBQUMsRUFBRSxPQUFPLEVBQUUsSUFBSSxDQUFDLENBQUMsQ0FBQyxFQUFFLFFBQVEsRUFBRSxJQUFJLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxPQUFPLE1BQU0sS0FBSyxVQUFVLEtBQUssQ0FBQyxDQUFDLE1BQU0sQ0FBQyxRQUFRLENBQUMsR0FBRyxXQUFXLEVBQUUsT0FBTyxJQUFJLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDO0FBQzdKLElBQUksU0FBUyxJQUFJLENBQUMsQ0FBQyxFQUFFLEVBQUUsT0FBTyxVQUFVLENBQUMsRUFBRSxFQUFFLE9BQU8sSUFBSSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUU7QUFDdEUsSUFBSSxTQUFTLElBQUksQ0FBQyxFQUFFLEVBQUU7QUFDdEIsUUFBUSxJQUFJLENBQUMsRUFBRSxNQUFNLElBQUksU0FBUyxDQUFDLGlDQUFpQyxDQUFDLENBQUM7QUFDdEUsUUFBUSxPQUFPLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsSUFBSTtBQUN0RCxZQUFZLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEtBQUssQ0FBQyxHQUFHLEVBQUUsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxLQUFLLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUUsSUFBSSxFQUFFLE9BQU8sQ0FBQyxDQUFDO0FBQ3pLLFlBQVksSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsRUFBRSxFQUFFLEdBQUcsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQztBQUNwRCxZQUFZLFFBQVEsRUFBRSxDQUFDLENBQUMsQ0FBQztBQUN6QixnQkFBZ0IsS0FBSyxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsRUFBRSxDQUFDLEdBQUcsRUFBRSxDQUFDLENBQUMsTUFBTTtBQUM5QyxnQkFBZ0IsS0FBSyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEtBQUssRUFBRSxDQUFDLENBQUMsT0FBTyxFQUFFLEtBQUssRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLEVBQUUsSUFBSSxFQUFFLEtBQUssRUFBRSxDQUFDO0FBQ3hFLGdCQUFnQixLQUFLLENBQUMsRUFBRSxDQUFDLENBQUMsS0FBSyxFQUFFLENBQUMsQ0FBQyxDQUFDLEdBQUcsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxTQUFTO0FBQ2pFLGdCQUFnQixLQUFLLENBQUMsRUFBRSxFQUFFLEdBQUcsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsR0FBRyxFQUFFLENBQUMsQ0FBQyxTQUFTO0FBQ2pFLGdCQUFnQjtBQUNoQixvQkFBb0IsSUFBSSxFQUFFLENBQUMsR0FBRyxDQUFDLENBQUMsSUFBSSxFQUFFLENBQUMsR0FBRyxDQUFDLENBQUMsTUFBTSxHQUFHLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLE1BQU0sR0FBRyxDQUFDLENBQUMsQ0FBQyxLQUFLLEVBQUUsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLElBQUksRUFBRSxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLFNBQVMsRUFBRTtBQUNoSSxvQkFBb0IsSUFBSSxFQUFFLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxLQUFLLENBQUMsQ0FBQyxLQUFLLEVBQUUsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksRUFBRSxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsS0FBSyxHQUFHLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLE1BQU0sRUFBRTtBQUMxRyxvQkFBb0IsSUFBSSxFQUFFLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsQ0FBQyxLQUFLLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLEtBQUssR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsRUFBRSxDQUFDLENBQUMsTUFBTSxFQUFFO0FBQ3pGLG9CQUFvQixJQUFJLENBQUMsSUFBSSxDQUFDLENBQUMsS0FBSyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxLQUFLLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxNQUFNLEVBQUU7QUFDdkYsb0JBQW9CLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxHQUFHLENBQUMsR0FBRyxFQUFFLENBQUM7QUFDMUMsb0JBQW9CLENBQUMsQ0FBQyxJQUFJLENBQUMsR0FBRyxFQUFFLENBQUMsQ0FBQyxTQUFTO0FBQzNDLGFBQWE7QUFDYixZQUFZLEVBQUUsR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDLE9BQU8sRUFBRSxDQUFDLENBQUMsQ0FBQztBQUN2QyxTQUFTLENBQUMsT0FBTyxDQUFDLEVBQUUsRUFBRSxFQUFFLEdBQUcsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLEVBQUUsU0FBUyxFQUFFLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDLEVBQUU7QUFDbEUsUUFBUSxJQUFJLEVBQUUsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLEVBQUUsTUFBTSxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxPQUFPLEVBQUUsS0FBSyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsR0FBRyxFQUFFLENBQUMsQ0FBQyxDQUFDLEdBQUcsS0FBSyxDQUFDLEVBQUUsSUFBSSxFQUFFLElBQUksRUFBRSxDQUFDO0FBQ3pGLEtBQUs7QUFDTCxDQUFDO0FBaUJEO0FBQ08sU0FBUyxRQUFRLENBQUMsQ0FBQyxFQUFFO0FBQzVCLElBQUksSUFBSSxDQUFDLEdBQUcsT0FBTyxNQUFNLEtBQUssVUFBVSxJQUFJLE1BQU0sQ0FBQyxRQUFRLEVBQUUsQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxHQUFHLENBQUMsQ0FBQztBQUNsRixJQUFJLElBQUksQ0FBQyxFQUFFLE9BQU8sQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUM1QixJQUFJLElBQUksQ0FBQyxJQUFJLE9BQU8sQ0FBQyxDQUFDLE1BQU0sS0FBSyxRQUFRLEVBQUUsT0FBTztBQUNsRCxRQUFRLElBQUksRUFBRSxZQUFZO0FBQzFCLFlBQVksSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxHQUFHLEtBQUssQ0FBQyxDQUFDO0FBQy9DLFlBQVksT0FBTyxFQUFFLEtBQUssRUFBRSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUM7QUFDcEQsU0FBUztBQUNULEtBQUssQ0FBQztBQUNOLElBQUksTUFBTSxJQUFJLFNBQVMsQ0FBQyxDQUFDLEdBQUcseUJBQXlCLEdBQUcsaUNBQWlDLENBQUMsQ0FBQztBQUMzRixDQUFDO0FBQ0Q7QUFDTyxTQUFTLE1BQU0sQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFO0FBQzdCLElBQUksSUFBSSxDQUFDLEdBQUcsT0FBTyxNQUFNLEtBQUssVUFBVSxJQUFJLENBQUMsQ0FBQyxNQUFNLENBQUMsUUFBUSxDQUFDLENBQUM7QUFDL0QsSUFBSSxJQUFJLENBQUMsQ0FBQyxFQUFFLE9BQU8sQ0FBQyxDQUFDO0FBQ3JCLElBQUksSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsRUFBRSxHQUFHLEVBQUUsRUFBRSxDQUFDLENBQUM7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RCxRQUFRLE1BQU0sQ0FBQyxJQUFJLEdBQUcsTUFBTSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxHQUFHLEtBQUssTUFBTSxDQUFDLFFBQVEsQ0FBQyxHQUFHLEVBQUUsMEJBQTBCLENBQUMsQ0FBQyxDQUFDO0FBQ2pHO0FBQ0EsUUFBUSxNQUFNLFlBQVksR0FBRyxDQUFDLE1BQU0sQ0FBQyxPQUFPLENBQUMsQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQztBQUM1RTtBQUNBLFFBQVEsTUFBTSxDQUFDLElBQUksR0FBRyxDQUFDLElBQUksRUFBRSxJQUFJLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQyxFQUFFLFlBQVksQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQzlELFFBQVEsTUFBTSxDQUFDLE9BQU8sR0FBRyxPQUFPLENBQUMsR0FBRyxDQUFDLE9BQU8sSUFBSSxTQUFTLENBQUM7QUFDMUQsUUFBUSxNQUFNLENBQUMsT0FBTyxDQUFDLHdCQUF3QixHQUFHLElBQUksQ0FBQztBQUN2RCxLQUFLO0FBQ0w7QUFDQSxJQUFJLE9BQU8sTUFBTSxDQUFDO0FBQ2xCLENBQUM7QUFDRDtBQUNBLFNBQVNVLE9BQUssQ0FBQyxPQUFPLEVBQUUsSUFBSSxFQUFFLE9BQU8sRUFBRTtBQUN2QztBQUNBLElBQUksSUFBSSxJQUFJLElBQUksQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxFQUFFO0FBQ3RDLFFBQVEsT0FBTyxHQUFHLElBQUksQ0FBQztBQUN2QixRQUFRLElBQUksR0FBRyxJQUFJLENBQUM7QUFDcEIsS0FBSztBQUNMO0FBQ0EsSUFBSSxJQUFJLEdBQUcsSUFBSSxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLEdBQUcsRUFBRSxDQUFDO0FBQ3JDLElBQUksT0FBTyxHQUFHLE1BQU0sQ0FBQyxNQUFNLENBQUMsRUFBRSxFQUFFLE9BQU8sQ0FBQyxDQUFDO0FBQ3pDO0FBQ0E7QUFDQSxJ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LEtBQUssU0FBUyxJQUFJLE9BQU8sQ0FBQyxLQUFLLEtBQUssU0FBUyxFQUFFO0FBQ3pELEVBQUUsT0FBTztBQUNULEVBQUU7QUFDRjtBQUNBLENBQUMsSUFBSSxRQUFRLENBQUMsS0FBSyxDQUFDLEVBQUU7QUFDdEIsRUFBRSxLQUFLLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsQ0FBQztBQUM1QixFQUFFLE1BQU07QUFDUixFQUFFLE9BQU8sQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQyxDQUFDO0FBQzNCLEVBQUU7QUFDRixDQUFDLENBQUM7QUFDRjtBQUNBO0FBQ0EsTUFBTUMsZUFBYSxHQUFHLENBQUMsT0FBTyxFQUFFLENBQUMsR0FBRyxDQUFDLEtBQUs7QUFDMUMsQ0FBQyxJQUFJLENBQUMsR0FBRyxLQUFLLENBQUMsT0FBTyxDQUFDLE1BQU0sSUFBSSxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUMsRUFBRTtBQUNuRCxFQUFFLE9BQU87QUFDVCxFQUFFO0FBQ0Y7QUFDQSxDQUFDLE1BQU0sS0FBSyxHQUFHLFdBQVcsRUFBRSxDQUFDO0FBQzdCO0FBQ0EsQ0FBQyxJQUFJLE9BQU8sQ0FBQyxNQUFNLEVBQUU7QUFDckIsRUFBRSxLQUFLLENBQUMsR0FBRyxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUMsQ0FBQztBQUM1QixFQUFFO0FBQ0Y7QUFDQSxDQUFDLElBQUksT0FBTyxDQUFDLE1BQU0sRUFBRTtBQUNyQixFQUFFLEtBQUssQ0FBQyxHQUFHLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxDQUFDO0FBQzVCLEVBQUU7QUFDRjtBQUNBLENBQUMsT0FBTyxLQUFLLENBQUM7QUFDZCxDQUFDLENBQUM7QUFDRjtBQUNBO0FBQ0EsTUFBTSxlQUFlLEdBQUcsT0FBTyxNQUFNLEVBQUUsYUFBYSxLQUFLO0FBQ3pELENBQUMsSUFBSSxDQUFDLE1BQU0sRUFBRTtBQUNkLEVBQUUsT0FBTztBQUNULEVBQUU7QUFDRjtBQUNBLENBQUMsTUFBTSxDQUFDLE9BQU8sRUFBRSxDQUFDO0FBQ2xCO0FBQ0EsQ0FBQyxJQUFJO0FBQ0wsRUFBRSxPQUFPLE1BQU0sYUFBYSxDQUFDO0FBQzdCLEVBQUUsQ0FBQyxPQUFPLEtBQUssRUFBRTtBQUNqQixFQUFFLE9BQU8sS0FBSyxDQUFDLFlBQVksQ0FBQztBQUM1QixFQUFFO0FBQ0YsQ0FBQyxDQUFDO0FBQ0Y7QUFDQSxNQUFNLGdCQUFnQixHQUFHLENBQUMsTUFBTSxFQUFFLENBQUMsUUFBUSxFQUFFLE1BQU0sRUFBRSxTQUFTLENBQUMsS0FBSztBQUNwRSxDQUFDLElBQUksQ0FBQyxNQUFNLElBQUksQ0FBQyxNQUFNLEVBQUU7QUFDekIsRUFBRSxPQUFPO0FBQ1QsRUFBRTtBQUNGO0FBQ0EsQ0FBQyxJQUFJLFFBQVEsRUFBRTtBQUNmLEVBQUUsT0FBTyxTQUFTLENBQUMsTUFBTSxFQUFFLENBQUMsUUFBUSxFQUFFLFNBQVMsQ0FBQyxDQUFDLENBQUM7QUFDbEQsRUFBRTtBQUNGO0FBQ0EsQ0FBQyxPQUFPLFNBQVMsQ0FBQyxNQUFNLENBQUMsTUFBTSxFQUFFLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQztBQUM5QyxDQUFDLENBQUM7QUFDRjtBQUNBO0FBQ0EsTUFBTUMsa0JBQWdCLEdBQUcsT0FBTyxDQUFDLE1BQU0sRUFBRSxNQUFNLEVBQUUsR0FBRyxDQUFDLEVBQUUsQ0FBQyxRQUFRLEVBQUUsTUFBTSxFQUFFLFNBQVMsQ0FBQyxFQUFFLFdBQVcsS0FBSztBQUN0RyxDQUFDLE1BQU0sYUFBYSxHQUFHLGdCQUFnQixDQUFDLE1BQU0sRUFBRSxDQUFDLFFBQVEsRUFBRSxNQUFNLEVBQUUsU0FBUyxDQUFDLENBQUMsQ0FBQztBQUMvRSxDQUFDLE1BQU0sYUFBYSxHQUFHLGdCQUFnQixDQUFDLE1BQU0sRUFBRSxDQUFDLFFBQVEsRUFBRSxNQUFNLEVBQUUsU0FBUyxDQUFDLENBQUMsQ0FBQztBQUMvRSxDQUFDLE1BQU0sVUFBVSxHQUFHLGdCQUFnQixDQUFDLEdBQUcsRUFBRSxDQUFDLFFBQVEsRUFBRSxNQUFNLEVBQUUsU0FBUyxFQUFFLFNBQVMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ3hGO0FBQ0EsQ0FBQyxJQUFJO0FBQ0wsRUFBRSxPQUFPLE1BQU0sT0FBTyxDQUFDLEdBQUcsQ0FBQyxDQUFDLFdBQVcsRUFBRSxhQUFhLEVBQUUsYUFBYSxFQUFFLFVBQVUsQ0FBQyxDQUFDLENBQUM7QUFDcEYsRUFBRSxDQUFDLE9BQU8sS0FBSyxFQUFFO0FBQ2pCLEVBQUUsT0FBTyxPQUFPLENBQUMsR0FBRyxDQUFDO0FBQ3JCLEdBQUcsQ0FBQyxLQUFLLEVBQUUsTUFBTSxFQUFFLEtBQUssQ0FBQyxNQUFNLEVBQUUsUUFBUSxFQUFFLEtBQUssQ0FBQyxRQUFRLENBQUM7QUFDMUQsR0FBRyxlQUFlLENBQUMsTUFBTSxFQUFFLGFBQWEsQ0FBQztBQUN6QyxHQUFHLGVBQWUsQ0FBQyxNQUFNLEVBQUUsYUFBYSxDQUFDO0FBQ3pDLEdBQUcsZUFBZSxDQUFDLEdBQUcsRUFBRSxVQUFVLENBQUM7QUFDbkMsR0FBRyxDQUFDLENBQUM7QUFDTCxFQUFFO0FBQ0YsQ0FBQyxDQUFDO0FBQ0Y7QUFDQSxNQUFNQyxtQkFBaUIsR0FBRyxDQUFDLENBQUMsS0FBSyxDQUFDLEtBQUs7QUFDdkMsQ0FBQyxJQUFJLFFBQVEsQ0FBQyxLQUFLLENBQUMsRUFBRTtBQUN0QixFQUFFLE1BQU0sSUFBSSxTQUFTLENBQUMsb0RBQW9ELENBQUMsQ0FBQztBQUM1RSxFQUFFO0FBQ0YsQ0FBQyxDQUFDO0FBQ0Y7QUFDQSxJQUFBUCxRQUFjLEdBQUc7QUFDakIsY0FBQ0ksYUFBVztBQUNaLGdCQUFDQyxlQUFhO0FBQ2QsbUJBQUNDLGtCQUFnQjtBQUNqQixvQkFBQ0MsbUJBQWlCO0FBQ2xCLENBQUM7O0FDN0ZELE1BQU0sc0JBQXNCLEdBQUcsQ0FBQyxZQUFZLEVBQUUsR0FBRyxDQUFDLFdBQVcsQ0FBQyxTQUFTLENBQUM7QUFDeEUsTUFBTSxXQUFXLEdBQUcsQ0FBQyxNQUFNLEVBQUUsT0FBTyxFQUFFLFNBQVMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxRQUFRLElBQUk7QUFDakUsQ0FBQyxRQUFRO0FBQ1QsQ0FBQyxPQUFPLENBQUMsd0JBQXdCLENBQUMsc0JBQXNCLEVBQUUsUUFBUSxDQUFDO0FBQ25FLENBQUMsQ0FBQyxDQUFDO0FBQ0g7QUFDQTtBQUNBLE1BQU1DLGNBQVksR0FBRyxDQUFDLE9BQU8sRUFBRSxPQUFPLEtBQUs7QUFDM0MsQ0FBQyxLQUFLLE1BQU0sQ0FBQyxRQUFRLEVBQUUsVUFBVSxDQUFDLElBQUksV0FBVyxFQUFFO0FBQ25EO0FBQ0EsRUFBRSxNQUFNLEtBQUssR0FBRyxPQUFPLE9BQU8sS0FBSyxVQUFVO0FBQzdDLEdBQUcsQ0FBQyxHQUFHLElBQUksS0FBSyxPQUFPLENBQUMsS0FBSyxDQUFDLFVBQVUsQ0FBQyxLQUFLLEVBQUUsT0FBTyxFQUFFLEVBQUUsSUFBSSxDQUFDO0FBQ2hFLEdBQUcsVUFBVSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUM7QUFDbEM7QUFDQSxFQUFFLE9BQU8sQ0FBQyxjQUFjLENBQUMsT0FBTyxFQUFFLFFBQVEsRUFBRSxDQUFDLEdBQUcsVUFBVSxFQUFFLEtBQUssQ0FBQyxDQUFDLENBQUM7QUFDcEUsRUFBRTtBQUNGO0FBQ0EsQ0FBQyxPQUFPLE9BQU8sQ0FBQztBQUNoQixDQUFDLENBQUM7QUFDRjtBQUNBO0FBQ0EsTUFBTUMsbUJBQWlCLEdBQUcsT0FBTyxJQUFJO0FBQ3JDLENBQUMsT0FBTyxJQUFJLE9BQU8sQ0FBQyxDQUFDLE9BQU8sRUFBRSxNQUFNLEtBQUs7QUFDekMsRUFBRSxPQUFPLENBQUMsRUFBRSxDQUFDLE1BQU0sRUFBRSxDQUFDLFFBQVEsRUFBRSxNQUFNLEtBQUs7QUFDM0MsR0FBRyxPQUFPLENBQUMsQ0FBQyxRQUFRLEVBQUUsTUFBTSxDQUFDLENBQUMsQ0FBQztBQUMvQixHQUFHLENBQUMsQ0FBQztBQUNMO0FBQ0EsRUFBRSxPQUFPLENBQUMsRUFBRSxDQUFDLE9BQU8sRUFBRSxLQUFLLElBQUk7QUFDL0IsR0FBRyxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUM7QUFDakIsR0FBRyxDQUFDLENBQUM7QUFDTDtBQUNBLEVBQUUsSUFBSSxPQUFPLENBQUMsS0FBSyxFQUFFO0FBQ3JCLEdBQUcsT0FBTyxDQUFDLEtBQUssQ0FBQyxFQUFFLENBQUMsT0FBTyxFQUFFLEtBQUssSUFBSTtBQUN0QyxJQUFJLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQztBQUNsQixJQUFJLENBQUMsQ0FBQztBQUNOLEdBQUc7QUFDSCxFQUFFLENBQUMsQ0FBQztBQUNKLENBQUMsQ0FBQztBQUNGO0FBQ0EsSUFBQSxPQUFjLEdBQUc7QUFDakIsZUFBQ0QsY0FBWTtBQUNiLG9CQUFDQyxtQkFBaUI7QUFDbEIsQ0FBQzs7QUMzQ0QsTUFBTSxhQUFhLEdBQUcsQ0FBQyxJQUFJLEVBQUUsSUFBSSxHQUFHLEVBQUUsS0FBSztBQUMzQyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxFQUFFO0FBQzNCLEVBQUUsT0FBTyxDQUFDLElBQUksQ0FBQyxDQUFDO0FBQ2hCLEVBQUU7QUFDRjtBQUNBLENBQUMsT0FBTyxDQUFDLElBQUksRUFBRSxHQUFHLElBQUksQ0FBQyxDQUFDO0FBQ3hCLENBQUMsQ0FBQztBQUNGO0FBQ0EsTUFBTSxnQkFBZ0IsR0FBRyxXQUFXLENBQUM7QUFDckMsTUFBTSxvQkFBb0IsR0FBRyxJQUFJLENBQUM7QUFDbEM7QUFDQSxNQUFNLFNBQVMsR0FBRyxHQUFHLElBQUk7QUFDekIsQ0FBQyxJQUFJLE9BQU8sR0FBRyxLQUFLLFFBQVEsSUFBSSxnQkFBZ0IsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUU7QUFDNUQsRUFBRSxPQUFPLEdBQUcsQ0FBQztBQUNiLEVBQUU7QUFDRjtBQUNBLENBQUMsT0FBTyxDQUFDLENBQUMsRUFBRSxHQUFHLENBQUMsT0FBTyxDQUFDLG9CQUFvQixFQUFFLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ3hELENBQUMsQ0FBQztBQUNGO0FBQ0EsTUFBTUMsYUFBVyxHQUFHLENBQUMsSUFBSSxFQUFFLElBQUksS0FBSztBQUNwQyxDQUFDLE9BQU8sYUFBYSxDQUFDLElBQUksRUFBRSxJQUFJLENBQUMsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDNUMsQ0FBQyxDQUFDO0FBQ0Y7QUFDQSxNQUFNQyxtQkFBaUIsR0FBRyxDQUFDLElBQUksRUFBRSxJQUFJLEtBQUs7QUFDMUMsQ0FBQyxPQUFPLGFBQWEsQ0FBQyxJQUFJLEVBQUUsSUFBSSxDQUFDLENBQUMsR0FBRyxDQUFDLEdBQUcsSUFBSSxTQUFTLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDdkUsQ0FBQyxDQUFDO0FBQ0Y7QUFDQSxNQUFNLGFBQWEsR0FBRyxLQUFLLENBQUM7QUFDNUI7QUFDQTtBQUNBLE1BQU1DLGNBQVksR0FBRyxPQUFPLElBQUk7QUFDaEMsQ0FBQyxNQUFNLE1BQU0sR0FBRyxFQUFFLENBQUM7QUFDbkIsQ0FBQyxLQUFLLE1BQU0sS0FBSyxJQUFJLE9BQU8sQ0FBQyxJQUFJLEVBQUUsQ0FBQyxLQUFLLENBQUMsYUFBYSxDQUFDLEVBQUU7QUFDMUQ7QUFDQSxFQUFFLE1BQU0sYUFBYSxHQUFHLE1BQU0sQ0FBQyxNQUFNLENBQUMsTUFBTSxHQUFHLENBQUMsQ0FBQyxDQUFDO0FBQ2xELEVBQUUsSUFBSSxhQUFhLElBQUksYUFBYSxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsRUFBRTtBQUNyRDtBQUNBLEdBQUcsTUFBTSxDQUFDLE1BQU0sQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxFQUFFLGFBQWEsQ0FBQyxLQUFLLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLEtBQUssQ0FBQyxDQUFDLENBQUM7QUFDeEUsR0FBRyxNQUFNO0FBQ1QsR0FBRyxNQUFNLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDO0FBQ3RCLEdBQUc7QUFDSCxFQUFFO0FBQ0Y7QUFDQSxDQUFDLE9BQU8sTUFBTSxDQUFDO0FBQ2YsQ0FBQyxDQUFDO0FBQ0Y7QUFDQSxJQUFBLE9BQWMsR0FBRztBQUNqQixjQUFDRixhQUFXO0FBQ1osb0JBQUNDLG1CQUFpQjtBQUNsQixlQUFDQyxjQUFZO0FBQ2IsQ0FBQzs7QUNsREQsTUFBTSxJQUFJLEdBQUc3QyxZQUFlLENBQUM7QUFDN0IsTUFBTSxZQUFZLEdBQUdKLFlBQXdCLENBQUM7QUFDOUMsTUFBTSxVQUFVLEdBQUdDLGlCQUFzQixDQUFDO0FBQzFDLE1BQU0saUJBQWlCLEdBQUdVLG1CQUE4QixDQUFDO0FBQ3pELE1BQU0sVUFBVSxHQUFHdUMsaUJBQXVCLENBQUM7QUFDM0MsTUFBTSxPQUFPLEdBQUdDLGNBQWtCLENBQUM7QUFDbkMsTUFBTSxTQUFTLEdBQUdDLEtBQXNCLENBQUM7QUFDekMsTUFBTSxjQUFjLEdBQUdDLFlBQXNCLENBQUM7QUFDOUMsTUFBTSxDQUFDLFdBQVcsRUFBRSxhQUFhLEVBQUUsWUFBWSxFQUFFLGVBQWUsRUFBRSxjQUFjLENBQUMsR0FBR0MsSUFBcUIsQ0FBQztBQUMxRyxNQUFNLENBQUMsV0FBVyxFQUFFLGdCQUFnQixFQUFFLGFBQWEsRUFBRSxpQkFBaUIsQ0FBQyxHQUFHQyxRQUF1QixDQUFDO0FBQ2xHLE1BQU0sQ0FBQyxZQUFZLEVBQUUsaUJBQWlCLENBQUMsR0FBR0MsT0FBd0IsQ0FBQztBQUNuRSxNQUFNLENBQUMsV0FBVyxFQUFFLFlBQVksRUFBRSxpQkFBaUIsQ0FBQyxHQUFHQyxPQUF3QixDQUFDO0FBQ2hGO0FBQ0EsTUFBTSxrQkFBa0IsR0FBRyxJQUFJLEdBQUcsSUFBSSxHQUFHLEdBQUcsQ0FBQztBQUM3QztBQUNBLE1BQU0sTUFBTSxHQUFHLENBQUMsQ0FBQyxHQUFHLEVBQUUsU0FBUyxFQUFFLFNBQVMsRUFBRSxXQUFXLEVBQUUsUUFBUSxFQUFFLFFBQVEsQ0FBQyxLQUFLO0FBQ2pGLENBQUMsTUFBTSxHQUFHLEdBQUcsU0FBUyxHQUFHLENBQUMsR0FBRyxPQUFPLENBQUMsR0FBRyxFQUFFLEdBQUcsU0FBUyxDQUFDLEdBQUcsU0FBUyxDQUFDO0FBQ3BFO0FBQ0EsQ0FBQyxJQUFJLFdBQVcsRUFBRTtBQUNsQixFQUFFLE9BQU8sVUFBVSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEdBQUcsRUFBRSxHQUFHLEVBQUUsUUFBUSxFQUFFLFFBQVEsQ0FBQyxDQUFDLENBQUM7QUFDeEQsRUFBRTtBQUNGO0FBQ0EsQ0FBQyxPQUFPLEdBQUcsQ0FBQztBQUNaLENBQUMsQ0FBQztBQUNGO0FBQ0EsTUFBTSxlQUFlLEdBQUcsQ0FBQyxJQUFJLEVBQUUsSUFBSSxFQUFFLE9BQU8sR0FBRyxFQUFFLEtBQUs7QUFDdEQsQ0FBQyxNQUFNLE1BQU0sR0FBRyxVQUFVLENBQUMsTUFBTSxDQUFDLElBQUksRUFBRSxJQUFJLEVBQUUsT0FBTyxDQUFDLENBQUM7QUFDdkQsQ0FBQyxJQUFJLEdBQUcsTUFBTSxDQUFDLE9BQU8sQ0FBQztBQUN2QixDQUFDLElBQUksR0FBRyxNQUFNLENBQUMsSUFBSSxDQUFDO0FBQ3BCLENBQUMsT0FBTyxHQUFHLE1BQU0sQ0FBQyxPQUFPLENBQUM7QUFDMUI7QUFDQSxDQUFDLE9BQU8sR0FBRztBQUNYLEVBQUUsU0FBUyxFQUFFLGtCQUFrQjtBQUMvQixFQUFFLE1BQU0sRUFBRSxJQUFJO0FBQ2QsRUFBRSxpQkFBaUIsRUFBRSxJQUFJO0FBQ3pCLEVBQUUsU0FBUyxFQUFFLElBQUk7QUFDakIsRUFBRSxXQUFXLEVBQUUsS0FBSztBQUNwQixFQUFFLFFBQVEsRUFBRSxPQUFPLENBQUMsR0FBRyxJQUFJLE9BQU8sQ0FBQyxHQUFHLEVBQUU7QUFDeEMsRUFBRSxRQUFRLEVBQUUsT0FBTyxDQUFDLFFBQVE7QUFDNUIsRUFBRSxRQUFRLEVBQUUsTUFBTTtBQUNsQixFQUFFLE1BQU0sRUFBRSxJQUFJO0FBQ2QsRUFBRSxPQUFPLEVBQUUsSUFBSTtBQUNmLEVBQUUsR0FBRyxFQUFFLEtBQUs7QUFDWixFQUFFLFdBQVcsRUFBRSxJQUFJO0FBQ25CLEVBQUUsR0FBRyxPQUFPO0FBQ1osRUFBRSxDQUFDO0FBQ0g7QUFDQSxDQUFDLE9BQU8sQ0FBQyxHQUFHLEdBQUcsTUFBTSxDQUFDLE9BQU8sQ0FBQyxDQUFDO0FBQy9CO0FBQ0EsQ0FBQyxPQUFPLENBQUMsS0FBSyxHQUFHLGNBQWMsQ0FBQyxPQUFPLENBQUMsQ0FBQztBQUN6QztBQUNBLENBQUMsSUFBSSxPQUFPLENBQUMsUUFBUSxLQUFLLE9BQU8sSUFBSSxJQUFJLENBQUMsUUFBUSxDQUFDLElBQUksRUFBRSxNQUFNLENBQUMsS0FBSyxLQUFLLEVBQUU7QUFDNUU7QUFDQSxFQUFFLElBQUksQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLENBQUM7QUFDckIsRUFBRTtBQUNGO0FBQ0EsQ0FBQyxPQUFPLENBQUMsSUFBSSxFQUFFLElBQUksRUFBRSxPQUFPLEVBQUUsTUFBTSxDQUFDLENBQUM7QUFDdEMsQ0FBQyxDQUFDO0FBQ0Y7QUFDQSxNQUFNLFlBQVksR0FBRyxDQUFDLE9BQU8sRUFBRSxLQUFLLEVBQUUsS0FBSyxLQUFLO0FBQ2hELENBQUMsSUFBSSxPQUFPLEtBQUssS0FBSyxRQUFRLElBQUksQ0FBQyxNQUFNLENBQUMsUUFBUSxDQUFDLEtBQUssQ0FBQyxFQUFFO0FBQzNEO0FBQ0EsRUFBRSxPQUFPLEtBQUssS0FBSyxTQUFTLEdBQUcsU0FBUyxHQUFHLEVBQUUsQ0FBQztBQUM5QyxFQUFFO0FBQ0Y7QUFDQSxDQUFDLElBQUksT0FBTyxDQUFDLGlCQUFpQixFQUFFO0FBQ2hDLEVBQUUsT0FBTyxpQkFBaUIsQ0FBQyxLQUFLLENBQUMsQ0FBQztBQUNsQyxFQUFFO0FBQ0Y7QUFDQSxDQUFDLE9BQU8sS0FBSyxDQUFDO0FBQ2QsQ0FBQyxDQUFDO0FBQ0Y7QUFDQSxNQUFNLEtBQUssR0FBRyxDQUFDLElBQUksRUFBRSxJQUFJLEVBQUUsT0FBTyxLQUFLO0FBQ3ZDLENBQUMsTUFBTSxNQUFNLEdBQUcsZUFBZSxDQUFDLElBQUksRUFBRSxJQUFJLEVBQUUsT0FBTyxDQUFDLENBQUM7QUFDckQsQ0FBQyxNQUFNLE9BQU8sR0FBRyxXQUFXLENBQUMsSUFBSSxFQUFFLElBQUksQ0FBQyxDQUFDO0FBQ3pDLENBQUMsTUFBTSxjQUFjLEdBQUcsaUJBQWlCLENBQUMsSUFBSSxFQUFFLElBQUksQ0FBQyxDQUFDO0FBQ3REO0FBQ0EsQ0FBQyxlQUFlLENBQUMsTUFBTSxDQUFDLE9BQU8sQ0FBQyxDQUFDO0FBQ2pDO0FBQ0EsQ0FBQyxJQUFJLE9BQU8sQ0FBQztBQUNiLENBQUMsSUFBSTtBQUNMLEVBQUUsT0FBTyxHQUFHLFlBQVksQ0FBQyxLQUFLLENBQUMsTUFBTSxDQUFDLElBQUksRUFBRSxNQUFNLENBQUMsSUFBSSxFQUFFLE1BQU0sQ0FBQyxPQUFPLENBQUMsQ0FBQztBQUN6RSxFQUFFLENBQUMsT0FBTyxLQUFLLEVBQUU7QUFDakI7QUFDQSxFQUFFLE1BQU0sWUFBWSxHQUFHLElBQUksWUFBWSxDQUFDLFlBQVksRUFBRSxDQUFDO0FBQ3ZELEVBQUUsTUFBTSxZQUFZLEdBQUcsT0FBTyxDQUFDLE1BQU0sQ0FBQyxTQUFTLENBQUM7QUFDaEQsR0FBRyxLQUFLO0FBQ1IsR0FBRyxNQUFNLEVBQUUsRUFBRTtBQUNiLEdBQUcsTUFBTSxFQUFFLEVBQUU7QUFDYixHQUFHLEdBQUcsRUFBRSxFQUFFO0FBQ1YsR0FBRyxPQUFPO0FBQ1YsR0FBRyxjQUFjO0FBQ2pCLEdBQUcsTUFBTTtBQUNULEdBQUcsUUFBUSxFQUFFLEtBQUs7QUFDbEIsR0FBRyxVQUFVLEVBQUUsS0FBSztBQUNwQixHQUFHLE1BQU0sRUFBRSxLQUFLO0FBQ2hCLEdBQUcsQ0FBQyxDQUFDLENBQUM7QUFDTixFQUFFLE9BQU8sWUFBWSxDQUFDLFlBQVksRUFBRSxZQUFZLENBQUMsQ0FBQztBQUNsRCxFQUFFO0FBQ0Y7QUFDQSxDQUFDLE1BQU0sY0FBYyxHQUFHLGlCQUFpQixDQUFDLE9BQU8sQ0FBQyxDQUFDO0FBQ25ELENBQUMsTUFBTSxZQUFZLEdBQUcsWUFBWSxDQUFDLE9BQU8sRUFBRSxNQUFNLENBQUMsT0FBTyxFQUFFLGNBQWMsQ0FBQyxDQUFDO0FBQzVFLENBQUMsTUFBTSxXQUFXLEdBQUcsY0FBYyxDQUFDLE9BQU8sRUFBRSxNQUFNLENBQUMsT0FBTyxFQUFFLFlBQVksQ0FBQyxDQUFDO0FBQzNFO0FBQ0EsQ0FBQyxNQUFNLE9BQU8sR0FBRyxDQUFDLFVBQVUsRUFBRSxLQUFLLENBQUMsQ0FBQztBQUNyQztBQUNBLENBQUMsT0FBTyxDQUFDLElBQUksR0FBRyxXQUFXLENBQUMsSUFBSSxDQUFDLElBQUksRUFBRSxPQUFPLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDO0FBQ25FLENBQUMsT0FBTyxDQUFDLE1BQU0sR0FBRyxhQUFhLENBQUMsSUFBSSxDQUFDLElBQUksRUFBRSxPQUFPLEVBQUUsT0FBTyxDQUFDLENBQUM7QUFDN0Q7QUFDQSxDQUFDLE1BQU0sYUFBYSxHQUFHLFlBQVk7QUFDbkMsRUFBRSxNQUFNLENBQUMsQ0FBQyxLQUFLLEVBQUUsUUFBUSxFQUFFLE1BQU0sRUFBRSxRQUFRLENBQUMsRUFBRSxZQUFZLEVBQUUsWUFBWSxFQUFFLFNBQVMsQ0FBQyxHQUFHLE1BQU0sZ0JBQWdCLENBQUMsT0FBTyxFQUFFLE1BQU0sQ0FBQyxPQUFPLEVBQUUsV0FBVyxDQUFDLENBQUM7QUFDcEosRUFBRSxNQUFNLE1BQU0sR0FBRyxZQUFZLENBQUMsTUFBTSxDQUFDLE9BQU8sRUFBRSxZQUFZLENBQUMsQ0FBQztBQUM1RCxFQUFFLE1BQU0sTUFBTSxHQUFHLFlBQVksQ0FBQyxNQUFNLENBQUMsT0FBTyxFQUFFLFlBQVksQ0FBQyxDQUFDO0FBQzVELEVBQUUsTUFBTSxHQUFHLEdBQUcsWUFBWSxDQUFDLE1BQU0sQ0FBQyxPQUFPLEVBQUUsU0FBUyxDQUFDLENBQUM7QUFDdEQ7QUFDQSxFQUFFLElBQUksS0FBSyxJQUFJLFFBQVEsS0FBSyxDQUFDLElBQUksTUFBTSxLQUFLLElBQUksRUFBRTtBQUNsRCxHQUFHLE1BQU0sYUFBYSxHQUFHLFNBQVMsQ0FBQztBQUNuQyxJQUFJLEtBQUs7QUFDVCxJQUFJLFFBQVE7QUFDWixJQUFJLE1BQU07QUFDVixJQUFJLE1BQU07QUFDVixJQUFJLE1BQU07QUFDVixJQUFJLEdBQUc7QUFDUCxJQUFJLE9BQU87QUFDWCxJQUFJLGNBQWM7QUFDbEIsSUFBSSxNQUFNO0FBQ1YsSUFBSSxRQUFRO0FBQ1osSUFBSSxVQUFVLEVBQUUsT0FBTyxDQUFDLFVBQVU7QUFDbEMsSUFBSSxNQUFNLEVBQUUsT0FBTyxDQUFDLE1BQU07QUFDMUIsSUFBSSxDQUFDLENBQUM7QUFDTjtBQUNBLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQyxPQUFPLENBQUMsTUFBTSxFQUFFO0FBQy9CLElBQUksT0FBTyxhQUFhLENBQUM7QUFDekIsSUFBSTtBQUNKO0FBQ0EsR0FBRyxNQUFNLGFBQWEsQ0FBQztBQUN2QixHQUFHO0FBQ0g7QUFDQSxFQUFFLE9BQU87QUFDVCxHQUFHLE9BQU87QUFDVixHQUFHLGNBQWM7QUFDakIsR0FBRyxRQUFRLEVBQUUsQ0FBQztBQUNkLEdBQUcsTUFBTTtBQUNULEdBQUcsTUFBTTtBQUNULEdBQUcsR0FBRztBQUNOLEdBQUcsTUFBTSxFQUFFLEtBQUs7QUFDaEIsR0FBRyxRQUFRLEVBQUUsS0FBSztBQUNsQixHQUFHLFVBQVUsRUFBRSxLQUFLO0FBQ3BCLEdBQUcsTUFBTSxFQUFFLEtBQUs7QUFDaEIsR0FBRyxDQUFDO0FBQ0osRUFBRSxDQUFDO0FBQ0g7QUFDQSxDQUFDLE1BQU0saUJBQWlCLEdBQUcsT0FBTyxDQUFDLGFBQWEsQ0FBQyxDQUFDO0FBQ2xEO0FBQ0EsQ0FBQyxXQUFXLENBQUMsT0FBTyxFQUFFLE1BQU0sQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLENBQUM7QUFDNUM7QUFDQSxDQUFDLE9BQU8sQ0FBQyxHQUFHLEdBQUcsYUFBYSxDQUFDLE9BQU8sRUFBRSxNQUFNLENBQUMsT0FBTyxDQUFDLENBQUM7QUFDdEQ7QUFDQSxDQUFDLE9BQU8sWUFBWSxDQUFDLE9BQU8sRUFBRSxpQkFBaUIsQ0FBQyxDQUFDO0FBQ2pELENBQUMsQ0FBQztBQUNGO0FBQ0FDLE9BQWMsQ0FBQSxPQUFBLEdBQUcsS0FBSyxDQUFDO0FBQ3ZCO0FBQ0FBLE9BQUEsQ0FBQSxPQUFBLENBQUEsSUFBbUIsR0FBRyxDQUFDLElBQUksRUFBRSxJQUFJLEVBQUUsT0FBTyxLQUFLO0FBQy9DLENBQUMsTUFBTSxNQUFNLEdBQUcsZUFBZSxDQUFDLElBQUksRUFBRSxJQUFJLEVBQUUsT0FBTyxDQUFDLENBQUM7QUFDckQsQ0FBQyxNQUFNLE9BQU8sR0FBRyxXQUFXLENBQUMsSUFBSSxFQUFFLElBQUksQ0FBQyxDQUFDO0FBQ3pDLENBQUMsTUFBTSxjQUFjLEdBQUcsaUJBQWlCLENBQUMsSUFBSSxFQUFFLElBQUksQ0FBQyxDQUFDO0FBQ3REO0FBQ0EsQ0FBQyxpQkFBaUIsQ0FBQyxNQUFNLENBQUMsT0FBTyxDQUFDLENBQUM7QUFDbkM7QUFDQSxDQUFDLElBQUksTUFBTSxDQUFDO0FBQ1osQ0FBQyxJQUFJO0FBQ0wsRUFBRSxNQUFNLEdBQUcsWUFBWSxDQUFDLFNBQVMsQ0FBQyxNQUFNLENBQUMsSUFBSSxFQUFFLE1BQU0sQ0FBQyxJQUFJLEVBQUUsTUFBTSxDQUFDLE9BQU8sQ0FBQyxDQUFDO0FBQzVFLEVBQUUsQ0FBQyxPQUFPLEtBQUssRUFBRTtBQUNqQixFQUFFLE1BQU0sU0FBUyxDQUFDO0FBQ2xCLEdBQUcsS0FBSztBQUNSLEdBQUcsTUFBTSxFQUFFLEVBQUU7QUFDYixHQUFHLE1BQU0sRUFBRSxFQUFFO0FBQ2IsR0FBRyxHQUFHLEVBQUUsRUFBRTtBQUNWLEdBQUcsT0FBTztBQUNWLEdBQUcsY0FBYztBQUNqQixHQUFHLE1BQU07QUFDVCxHQUFHLFFBQVEsRUFBRSxLQUFLO0FBQ2xCLEdBQUcsVUFBVSxFQUFFLEtBQUs7QUFDcEIsR0FBRyxNQUFNLEVBQUUsS0FBSztBQUNoQixHQUFHLENBQUMsQ0FBQztBQUNMLEVBQUU7QUFDRjtBQUNBLENBQUMsTUFBTSxNQUFNLEdBQUcsWUFBWSxDQUFDLE1BQU0sQ0FBQyxPQUFPLEVBQUUsTUFBTSxDQUFDLE1BQU0sRUFBRSxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUM7QUFDMUUsQ0FBQyxNQUFNLE1BQU0sR0FBRyxZQUFZLENBQUMsTUFBTSxDQUFDLE9BQU8sRUFBRSxNQUFNLENBQUMsTUFBTSxFQUFFLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQztBQUMxRTtBQUNBLENBQUMsSUFBSSxNQUFNLENBQUMsS0FBSyxJQUFJLE1BQU0sQ0FBQyxNQUFNLEtBQUssQ0FBQyxJQUFJLE1BQU0sQ0FBQyxNQUFNLEtBQUssSUFBSSxFQUFFO0FBQ3BFLEVBQUUsTUFBTSxLQUFLLEdBQUcsU0FBUyxDQUFDO0FBQzFCLEdBQUcsTUFBTTtBQUNULEdBQUcsTUFBTTtBQUNULEdBQUcsS0FBSyxFQUFFLE1BQU0sQ0FBQyxLQUFLO0FBQ3RCLEdBQUcsTUFBTSxFQUFFLE1BQU0sQ0FBQyxNQUFNO0FBQ3hCLEdBQUcsUUFBUSxFQUFFLE1BQU0sQ0FBQyxNQUFNO0FBQzFCLEdBQUcsT0FBTztBQUNWLEdBQUcsY0FBYztBQUNqQixHQUFHLE1BQU07QUFDVCxHQUFHLFFBQVEsRUFBRSxNQUFNLENBQUMsS0FBSyxJQUFJLE1BQU0sQ0FBQyxLQUFLLENBQUMsSUFBSSxLQUFLLFdBQVc7QUFDOUQsR0FBRyxVQUFVLEVBQUUsS0FBSztBQUNwQixHQUFHLE1BQU0sRUFBRSxNQUFNLENBQUMsTUFBTSxLQUFLLElBQUk7QUFDakMsR0FBRyxDQUFDLENBQUM7QUFDTDtBQUNBLEVBQUUsSUFBSSxDQUFDLE1BQU0sQ0FBQyxPQUFPLENBQUMsTUFBTSxFQUFFO0FBQzlCLEdBQUcsT0FBTyxLQUFLLENBQUM7QUFDaEIsR0FBRztBQUNIO0FBQ0EsRUFBRSxNQUFNLEtBQUssQ0FBQztBQUNkLEVBQUU7QUFDRjtBQUNBLENBQUMsT0FBTztBQUNSLEVBQUUsT0FBTztBQUNULEVBQUUsY0FBYztBQUNoQixFQUFFLFFBQVEsRUFBRSxDQUFDO0FBQ2IsRUFBRSxNQUFNO0FBQ1IsRUFBRSxNQUFNO0FBQ1IsRUFBRSxNQUFNLEVBQUUsS0FBSztBQUNmLEVBQUUsUUFBUSxFQUFFLEtBQUs7QUFDakIsRUFBRSxVQUFVLEVBQUUsS0FBSztBQUNuQixFQUFFLE1BQU0sRUFBRSxLQUFLO0FBQ2YsRUFBRSxDQUFDO0FBQ0gsRUFBRTtBQUNGO0FBQ0FBLE9BQUEsQ0FBQSxPQUFBLENBQUEsT0FBc0IsR0FBRyxDQUFDLE9BQU8sRUFBRSxPQUFPLEtBQUs7QUFDL0MsQ0FBQyxNQUFNLENBQUMsSUFBSSxFQUFFLEdBQUcsSUFBSSxDQUFDLEdBQUcsWUFBWSxDQUFDLE9BQU8sQ0FBQyxDQUFDO0FBQy9DLENBQUMsT0FBTyxLQUFLLENBQUMsSUFBSSxFQUFFLElBQUksRUFBRSxPQUFPLENBQUMsQ0FBQztBQUNuQyxFQUFFO0FBQ0Y7QUFDQUEsT0FBQSxDQUFBLE9BQUEsQ0FBQSxXQUEwQixHQUFHLENBQUMsT0FBTyxFQUFFLE9BQU8sS0FBSztBQUNuRCxDQUFDLE1BQU0sQ0FBQyxJQUFJLEVBQUUsR0FBRyxJQUFJLENBQUMsR0FBRyxZQUFZLENBQUMsT0FBTyxDQUFDLENBQUM7QUFDL0MsQ0FBQyxPQUFPLEtBQUssQ0FBQyxJQUFJLENBQUMsSUFBSSxFQUFFLElBQUksRUFBRSxPQUFPLENBQUMsQ0FBQztBQUN4QyxFQUFFO0FBQ0Y7QUFDbUJBLE9BQUEsQ0FBQSxPQUFBLENBQUEsSUFBQSxHQUFHLENBQUMsVUFBVSxFQUFFLElBQUksRUFBRSxPQUFPLEdBQUcsRUFBRSxLQUFLO0FBQzFELENBQUMsSUFBSSxJQUFJLElBQUksQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxJQUFJLE9BQU8sSUFBSSxLQUFLLFFBQVEsRUFBRTtBQUMvRCxFQUFFLE9BQU8sR0FBRyxJQUFJLENBQUM7QUFDakIsRUFBRSxJQUFJLEdBQUcsRUFBRSxDQUFDO0FBQ1osRUFBRTtBQUNGO0FBQ0EsQ0FBQyxNQUFNLEtBQUssR0FBRyxjQUFjLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDO0FBQzVDLENBQUMsTUFBTSxlQUFlLEdBQUcsT0FBTyxDQUFDLFFBQVEsQ0FBQyxNQUFNLENBQUMsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLFVBQVUsQ0FBQyxXQUFXLENBQUMsQ0FBQyxDQUFDO0FBQ3RGO0FBQ0EsQ0FBQyxNQUFNO0FBQ1AsRUFBRSxRQUFRLEdBQUcsT0FBTyxDQUFDLFFBQVE7QUFDN0IsRUFBRSxXQUFXLEdBQUcsZUFBZTtBQUMvQixFQUFFLEdBQUcsT0FBTyxDQUFDO0FBQ2I7QUFDQSxDQUFDLE9BQU8sS0FBSztBQUNiLEVBQUUsUUFBUTtBQUNWLEVBQUU7QUFDRixHQUFHLEdBQUcsV0FBVztBQUNqQixHQUFHLFVBQVU7QUFDYixHQUFHLElBQUksS0FBSyxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsR0FBRyxJQUFJLEdBQUcsRUFBRSxDQUFDO0FBQ3ZDLEdBQUc7QUFDSCxFQUFFO0FBQ0YsR0FBRyxHQUFHLE9BQU87QUFDYixHQUFHLEtBQUssRUFBRSxTQUFTO0FBQ25CLEdBQUcsTUFBTSxFQUFFLFNBQVM7QUFDcEIsR0FBRyxNQUFNLEVBQUUsU0FBUztBQUNwQixHQUFHLEtBQUs7QUFDUixHQUFHLEtBQUssRUFBRSxLQUFLO0FBQ2YsR0FBRztBQUNILEVBQUUsQ0FBQztBQUNILEVBQUM7Ozs7O0FDM1FjLFNBQVMsU0FBUyxDQUFDLENBQUMsU0FBUyxHQUFHLEtBQUssQ0FBQyxHQUFHLEVBQUUsRUFBRTtBQUM1RCxDQUFDLE1BQU0sT0FBTyxHQUFHO0FBQ2pCLEtBQUssOEhBQThIO0FBQ25JLEVBQUUsMERBQTBEO0FBQzVELEVBQUUsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDYjtBQUNBLENBQUMsT0FBTyxJQUFJLE1BQU0sQ0FBQyxPQUFPLEVBQUUsU0FBUyxHQUFHLFNBQVMsR0FBRyxHQUFHLENBQUMsQ0FBQztBQUN6RDs7QUNMZSxTQUFTLFNBQVMsQ0FBQyxNQUFNLEVBQUU7QUFDMUMsQ0FBQyxJQUFJLE9BQU8sTUFBTSxLQUFLLFFBQVEsRUFBRTtBQUNqQyxFQUFFLE1BQU0sSUFBSSxTQUFTLENBQUMsQ0FBQyw2QkFBNkIsRUFBRSxPQUFPLE1BQU0sQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDO0FBQ3pFLEVBQUU7QUFDRjtBQUNBLENBQUMsT0FBTyxNQUFNLENBQUMsT0FBTyxDQUFDLFNBQVMsRUFBRSxFQUFFLEVBQUUsQ0FBQyxDQUFDO0FBQ3hDOztBQ0xPLE1BQU0sa0JBQWtCLEdBQUcsTUFBTTtBQUN4QyxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsR0FBRzlCLFNBQU8sQ0FBQztBQUN2QjtBQUNBLENBQUMsSUFBSUEsU0FBTyxDQUFDLFFBQVEsS0FBSyxPQUFPLEVBQUU7QUFDbkMsRUFBRSxPQUFPLEdBQUcsQ0FBQyxPQUFPLElBQUksU0FBUyxDQUFDO0FBQ2xDLEVBQUU7QUFDRjtBQUNBLENBQUMsSUFBSTtBQUNMLEVBQUUsTUFBTSxDQUFDLEtBQUssQ0FBQyxHQUFHK0IsZ0JBQVEsRUFBRSxDQUFDO0FBQzdCLEVBQUUsSUFBSSxLQUFLLEVBQUU7QUFDYixHQUFHLE9BQU8sS0FBSyxDQUFDO0FBQ2hCLEdBQUc7QUFDSCxFQUFFLENBQUMsTUFBTSxFQUFFO0FBQ1g7QUFDQSxDQUFDLElBQUkvQixTQUFPLENBQUMsUUFBUSxLQUFLLFFBQVEsRUFBRTtBQUNwQyxFQUFFLE9BQU8sR0FBRyxDQUFDLEtBQUssSUFBSSxVQUFVLENBQUM7QUFDakMsRUFBRTtBQUNGO0FBQ0EsQ0FBQyxPQUFPLEdBQUcsQ0FBQyxLQUFLLElBQUksU0FBUyxDQUFDO0FBQy9CLENBQUMsQ0FBQztBQUNGO0FBQ0E7QUFDQSxNQUFNLFlBQVksR0FBRyxrQkFBa0IsRUFBRTs7QUNwQnpDLE1BQU0sSUFBSSxHQUFHO0FBQ2IsQ0FBQyxNQUFNO0FBQ1AsQ0FBQyw2RUFBNkU7QUFDOUUsQ0FBQyxDQUFDO0FBQ0Y7QUFDQSxNQUFNLEdBQUcsR0FBRztBQUNaO0FBQ0EsQ0FBQyxtQkFBbUIsRUFBRSxNQUFNO0FBQzVCLENBQUMsQ0FBQztBQUNGO0FBQ0EsTUFBTSxRQUFRLEdBQUcsR0FBRyxJQUFJO0FBQ3hCLENBQUMsR0FBRyxHQUFHLEdBQUcsQ0FBQyxLQUFLLENBQUMsdUJBQXVCLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUM3QyxDQUFDLE1BQU0sV0FBVyxHQUFHLEVBQUUsQ0FBQztBQUN4QjtBQUNBLENBQUMsS0FBSyxNQUFNLElBQUksSUFBSSxTQUFTLENBQUMsR0FBRyxDQUFDLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxDQUFDLE1BQU0sQ0FBQyxJQUFJLElBQUksT0FBTyxDQUFDLElBQUksQ0FBQyxDQUFDLEVBQUU7QUFDOUUsRUFBRSxNQUFNLENBQUMsR0FBRyxFQUFFLEdBQUcsTUFBTSxDQUFDLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQztBQUMzQyxFQUFFLFdBQVcsQ0FBQyxHQUFHLENBQUMsR0FBRyxNQUFNLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ3RDLEVBQUU7QUFDRjtBQUNBLENBQUMsT0FBTyxXQUFXLENBQUM7QUFDcEIsQ0FBQyxDQUFDO0FBa0JGO0FBQ08sU0FBUyxZQUFZLENBQUMsS0FBSyxFQUFFO0FBQ3BDLENBQUMsSUFBSUEsU0FBTyxDQUFDLFFBQVEsS0FBSyxPQUFPLEVBQUU7QUFDbkMsRUFBRSxPQUFPQSxTQUFPLENBQUMsR0FBRyxDQUFDO0FBQ3JCLEVBQUU7QUFDRjtBQUNBLENBQUMsSUFBSTtBQUNMLEVBQUUsTUFBTSxDQUFDLE1BQU0sQ0FBQyxHQUFHZ0MsT0FBSyxDQUFDLElBQUksQ0FBQyxLQUFLLElBQUksWUFBWSxFQUFFLElBQUksRUFBRSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUM7QUFDbEUsRUFBRSxPQUFPLFFBQVEsQ0FBQyxNQUFNLENBQUMsQ0FBQztBQUMxQixFQUFFLENBQUMsT0FBTyxLQUFLLEVBQUU7QUFDakIsRUFBRSxJQUFJLEtBQUssRUFBRTtBQUNiLEdBQUcsTUFBTSxLQUFLLENBQUM7QUFDZixHQUFHLE1BQU07QUFDVCxHQUFHLE9BQU9oQyxTQUFPLENBQUMsR0FBRyxDQUFDO0FBQ3RCLEdBQUc7QUFDSCxFQUFFO0FBQ0Y7O0FDcERPLFNBQVMsYUFBYSxHQUFHO0FBQ2hDLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxHQUFHLFlBQVksRUFBRSxDQUFDO0FBQy9CLENBQUMsT0FBTyxJQUFJLENBQUM7QUFDYjs7QUNQZSxTQUFTLE9BQU8sR0FBRztBQUNsQyxDQUFDLElBQUlBLFNBQU8sQ0FBQyxRQUFRLEtBQUssT0FBTyxFQUFFO0FBQ25DLEVBQUUsT0FBTztBQUNULEVBQUU7QUFDRjtBQUNBLENBQUNBLFNBQU8sQ0FBQyxHQUFHLENBQUMsSUFBSSxHQUFHLGFBQWEsRUFBRSxJQUFJO0FBQ3ZDLEVBQUUscUJBQXFCO0FBQ3ZCLEVBQUUsd0JBQXdCO0FBQzFCLEVBQUUsZ0JBQWdCO0FBQ2xCLEVBQUVBLFNBQU8sQ0FBQyxHQUFHLENBQUMsSUFBSTtBQUNsQixFQUFFLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ2I7Ozs7Ozs7Ozs7OztBQ2RBLENBQUEsTUFBYyxHQUFHeEIsWUFBaUIsQ0FBQTs7Ozs7Ozs7OztBQ0NsQztBQUNBLENBQUEsU0FBUyxPQUFPLENBQUMsTUFBTSxFQUFFLGNBQWMsRUFBRSxFQUFFLElBQUksSUFBSSxHQUFHLE1BQU0sQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxJQUFJLE1BQU0sQ0FBQyxxQkFBcUIsRUFBRSxFQUFFLElBQUksT0FBTyxHQUFHLE1BQU0sQ0FBQyxxQkFBcUIsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLGNBQWMsS0FBSyxPQUFPLEdBQUcsT0FBTyxDQUFDLE1BQU0sQ0FBQyxVQUFVLEdBQUcsRUFBRSxFQUFFLE9BQU8sTUFBTSxDQUFDLHdCQUF3QixDQUFDLE1BQU0sRUFBRSxHQUFHLENBQUMsQ0FBQyxVQUFVLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxJQUFJLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLEVBQUUsT0FBTyxDQUFDLENBQUMsRUFBRSxDQUFDLE9BQU8sSUFBSSxDQUFDLEVBQUU7QUFDclYsQ0FBQSxTQUFTLGFBQWEsQ0FBQyxNQUFNLEVBQUUsRUFBRSxLQUFLLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsU0FBUyxDQUFDLE1BQU0sRUFBRSxDQUFDLEVBQUUsRUFBRSxFQUFFLElBQUksTUFBTSxHQUFHLElBQUksSUFBSSxTQUFTLENBQUMsQ0FBQyxDQUFDLEdBQUcsU0FBUyxDQUFDLENBQUMsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLEdBQUcsT0FBTyxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxVQUFVLEdBQUcsRUFBRSxFQUFFLGVBQWUsQ0FBQyxNQUFNLEVBQUUsR0FBRyxFQUFFLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxHQUFHLE1BQU0sQ0FBQyx5QkFBeUIsR0FBRyxNQUFNLENBQUMsZ0JBQWdCLENBQUMsTUFBTSxFQUFFLE1BQU0sQ0FBQyx5QkFBeUIsQ0FBQyxNQUFNLENBQUMsQ0FBQyxHQUFHLE9BQU8sQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUMsVUFBVSxHQUFHLEVBQUUsRUFBRSxNQUFNLENBQUMsY0FBYyxDQUFDLE1BQU0sRUFBRSxHQUFHLEVBQUUsTUFBTSxDQUFDLHdCQUF3QixDQUFDLE1BQU0sRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxPQUFPLE1BQU0sQ0FBQyxFQUFFO0FBQzFmLENBQUEsU0FBUyxlQUFlLENBQUMsR0FBRyxFQUFFLEdBQUcsRUFBRSxLQUFLLEVBQUUsRUFBRSxHQUFHLEdBQUcsY0FBYyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsSUFBSSxHQUFHLElBQUksR0FBRyxFQUFFLEVBQUUsTUFBTSxDQUFDLGNBQWMsQ0FBQyxHQUFHLEVBQUUsR0FBRyxFQUFFLEVBQUUsS0FBSyxFQUFFLEtBQUssRUFBRSxVQUFVLEVBQUUsSUFBSSxFQUFFLFlBQVksRUFBRSxJQUFJLEVBQUUsUUFBUSxFQUFFLElBQUksRUFBRSxDQUFDLENBQUMsRUFBRSxNQUFNLEVBQUUsR0FBRyxDQUFDLEdBQUcsQ0FBQyxHQUFHLEtBQUssQ0FBQyxFQUFFLENBQUMsT0FBTyxHQUFHLENBQUMsRUFBRTtDQUM1TyxTQUFTLGVBQWUsQ0FBQyxRQUFRLEVBQUUsV0FBVyxFQUFFLEVBQUUsSUFBSSxFQUFFLFFBQVEsWUFBWSxXQUFXLENBQUMsRUFBRSxFQUFFLE1BQU0sSUFBSSxTQUFTLENBQUMsbUNBQW1DLENBQUMsQ0FBQyxFQUFFLEVBQUU7QUFDekosQ0FBQSxTQUFTLGlCQUFpQixDQUFDLE1BQU0sRUFBRSxLQUFLLEVBQUUsRUFBRSxLQUFLLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsS0FBSyxDQUFDLE1BQU0sRUFBRSxDQUFDLEVBQUUsRUFBRSxFQUFFLElBQUksVUFBVSxHQUFHLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLFVBQVUsQ0FBQyxVQUFVLEdBQUcsVUFBVSxDQUFDLFVBQVUsSUFBSSxLQUFLLENBQUMsQ0FBQyxVQUFVLENBQUMsWUFBWSxHQUFHLElBQUksQ0FBQyxDQUFDLElBQUksT0FBTyxJQUFJLFVBQVUsRUFBRSxVQUFVLENBQUMsUUFBUSxHQUFHLElBQUksQ0FBQyxDQUFDLE1BQU0sQ0FBQyxjQUFjLENBQUMsTUFBTSxFQUFFLGNBQWMsQ0FBQyxVQUFVLENBQUMsR0FBRyxDQUFDLEVBQUUsVUFBVSxDQUFDLENBQUMsRUFBRSxFQUFFO0NBQzdVLFNBQVMsWUFBWSxDQUFDLFdBQVcsRUFBRSxVQUFVLEVBQUUsV0FBVyxFQUFFLEVBQUUsSUFBSSxVQUFVLEVBQUUsaUJBQWlCLENBQUMsV0FBVyxDQUFDLFNBQVMsRUFBRSxVQUFVLENBQUMsQ0FBQyxDQUFDLElBQUksV0FBVyxFQUFFLGlCQUFpQixDQUFDLFdBQVcsRUFBRSxXQUFXLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxjQUFjLENBQUMsV0FBVyxFQUFFLFdBQVcsRUFBRSxFQUFFLFFBQVEsRUFBRSxLQUFLLEVBQUUsQ0FBQyxDQUFDLENBQUMsT0FBTyxXQUFXLENBQUMsRUFBRTtBQUM3UixDQUFBLFNBQVMsY0FBYyxDQUFDLEdBQUcsRUFBRSxFQUFFLElBQUksR0FBRyxHQUFHLFlBQVksQ0FBQyxHQUFHLEVBQUUsUUFBUSxDQUFDLENBQUMsQ0FBQyxPQUFPLE9BQU8sR0FBRyxLQUFLLFFBQVEsR0FBRyxHQUFHLEdBQUcsTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEVBQUU7QUFDM0gsQ0FBQSxTQUFTLFlBQVksQ0FBQyxLQUFLLEVBQUUsSUFBSSxFQUFFLEVBQUUsSUFBSSxPQUFPLEtBQUssS0FBSyxRQUFRLElBQUksS0FBSyxLQUFLLElBQUksRUFBRSxPQUFPLEtBQUssQ0FBQyxDQUFDLElBQUksSUFBSSxHQUFHLEtBQUssQ0FBQyxNQUFNLENBQUMsV0FBVyxDQUFDLENBQUMsQ0FBQyxJQUFJLElBQUksS0FBSyxTQUFTLEVBQUUsRUFBRSxJQUFJLEdBQUcsR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDLEtBQUssRUFBRSxJQUFJLElBQUksU0FBUyxDQUFDLENBQUMsQ0FBQyxJQUFJLE9BQU8sR0FBRyxLQUFLLFFBQVEsRUFBRSxPQUFPLEdBQUcsQ0FBQyxDQUFDLE1BQU0sSUFBSSxTQUFTLENBQUMsOENBQThDLENBQUMsQ0FBQyxFQUFFLENBQUMsT0FBTyxDQUFDLElBQUksS0FBSyxRQUFRLEdBQUcsTUFBTSxHQUFHLE1BQU0sRUFBRSxLQUFLLENBQUMsQ0FBQyxFQUFFO0NBQ3pYLElBQUksUUFBUSxHQUFHQSxZQUFpQjtBQUNoQyxHQUFFLE1BQU0sR0FBRyxRQUFRLENBQUMsTUFBTSxDQUFDO0NBQzNCLElBQUksU0FBUyxHQUFHSixZQUFlO0FBQy9CLEdBQUUsT0FBTyxHQUFHLFNBQVMsQ0FBQyxPQUFPLENBQUM7Q0FDOUIsSUFBSSxNQUFNLEdBQUcsT0FBTyxJQUFJLE9BQU8sQ0FBQyxNQUFNLElBQUksU0FBUyxDQUFDO0FBQ3BELENBQUEsU0FBUyxVQUFVLENBQUMsR0FBRyxFQUFFLE1BQU0sRUFBRSxNQUFNLEVBQUU7QUFDekMsR0FBRSxNQUFNLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsR0FBRyxFQUFFLE1BQU0sRUFBRSxNQUFNLENBQUMsQ0FBQztFQUNqRDtBQUNELENBQWMsV0FBQSxnQkFBZ0IsWUFBWTtHQUN4QyxTQUFTLFVBQVUsR0FBRztBQUN4QixLQUFJLGVBQWUsQ0FBQyxJQUFJLEVBQUUsVUFBVSxDQUFDLENBQUM7QUFDdEMsS0FBSSxJQUFJLENBQUMsSUFBSSxHQUFHLElBQUksQ0FBQztBQUNyQixLQUFJLElBQUksQ0FBQyxJQUFJLEdBQUcsSUFBSSxDQUFDO0FBQ3JCLEtBQUksSUFBSSxDQUFDLE1BQU0sR0FBRyxDQUFDLENBQUM7SUFDakI7QUFDSCxHQUFFLFlBQVksQ0FBQyxVQUFVLEVBQUUsQ0FBQztLQUN4QixHQUFHLEVBQUUsTUFBTTtBQUNmLEtBQUksS0FBSyxFQUFFLFNBQVMsSUFBSSxDQUFDLENBQUMsRUFBRTtPQUN0QixJQUFJLEtBQUssR0FBRztTQUNWLElBQUksRUFBRSxDQUFDO1NBQ1AsSUFBSSxFQUFFLElBQUk7QUFDbEIsUUFBTyxDQUFDO09BQ0YsSUFBSSxJQUFJLENBQUMsTUFBTSxHQUFHLENBQUMsRUFBRSxJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksR0FBRyxLQUFLLENBQUMsS0FBSyxJQUFJLENBQUMsSUFBSSxHQUFHLEtBQUssQ0FBQztBQUN6RSxPQUFNLElBQUksQ0FBQyxJQUFJLEdBQUcsS0FBSyxDQUFDO0FBQ3hCLE9BQU0sRUFBRSxJQUFJLENBQUMsTUFBTSxDQUFDO01BQ2Y7QUFDTCxJQUFHLEVBQUU7S0FDRCxHQUFHLEVBQUUsU0FBUztBQUNsQixLQUFJLEtBQUssRUFBRSxTQUFTLE9BQU8sQ0FBQyxDQUFDLEVBQUU7T0FDekIsSUFBSSxLQUFLLEdBQUc7U0FDVixJQUFJLEVBQUUsQ0FBQztBQUNmLFNBQVEsSUFBSSxFQUFFLElBQUksQ0FBQyxJQUFJO0FBQ3ZCLFFBQU8sQ0FBQztBQUNSLE9BQU0sSUFBSSxJQUFJLENBQUMsTUFBTSxLQUFLLENBQUMsRUFBRSxJQUFJLENBQUMsSUFBSSxHQUFHLEtBQUssQ0FBQztBQUMvQyxPQUFNLElBQUksQ0FBQyxJQUFJLEdBQUcsS0FBSyxDQUFDO0FBQ3hCLE9BQU0sRUFBRSxJQUFJLENBQUMsTUFBTSxDQUFDO01BQ2Y7QUFDTCxJQUFHLEVBQUU7S0FDRCxHQUFHLEVBQUUsT0FBTztBQUNoQixLQUFJLEtBQUssRUFBRSxTQUFTLEtBQUssR0FBRztBQUM1QixPQUFNLElBQUksSUFBSSxDQUFDLE1BQU0sS0FBSyxDQUFDLEVBQUUsT0FBTztPQUM5QixJQUFJLEdBQUcsR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQztPQUN6QixJQUFJLElBQUksQ0FBQyxNQUFNLEtBQUssQ0FBQyxFQUFFLElBQUksQ0FBQyxJQUFJLEdBQUcsSUFBSSxDQUFDLElBQUksR0FBRyxJQUFJLENBQUMsS0FBSyxJQUFJLENBQUMsSUFBSSxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDO0FBQzFGLE9BQU0sRUFBRSxJQUFJLENBQUMsTUFBTSxDQUFDO09BQ2QsT0FBTyxHQUFHLENBQUM7TUFDWjtBQUNMLElBQUcsRUFBRTtLQUNELEdBQUcsRUFBRSxPQUFPO0FBQ2hCLEtBQUksS0FBSyxFQUFFLFNBQVMsS0FBSyxHQUFHO09BQ3RCLElBQUksQ0FBQyxJQUFJLEdBQUcsSUFBSSxDQUFDLElBQUksR0FBRyxJQUFJLENBQUM7QUFDbkMsT0FBTSxJQUFJLENBQUMsTUFBTSxHQUFHLENBQUMsQ0FBQztNQUNqQjtBQUNMLElBQUcsRUFBRTtLQUNELEdBQUcsRUFBRSxNQUFNO0FBQ2YsS0FBSSxLQUFLLEVBQUUsU0FBUyxJQUFJLENBQUMsQ0FBQyxFQUFFO09BQ3RCLElBQUksSUFBSSxDQUFDLE1BQU0sS0FBSyxDQUFDLEVBQUUsT0FBTyxFQUFFLENBQUM7QUFDdkMsT0FBTSxJQUFJLENBQUMsR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDO09BQ2xCLElBQUksR0FBRyxHQUFHLEVBQUUsR0FBRyxDQUFDLENBQUMsSUFBSSxDQUFDO0FBQzVCLE9BQU0sT0FBTyxDQUFDLEdBQUcsQ0FBQyxDQUFDLElBQUksRUFBRSxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxJQUFJLENBQUM7T0FDckMsT0FBTyxHQUFHLENBQUM7TUFDWjtBQUNMLElBQUcsRUFBRTtLQUNELEdBQUcsRUFBRSxRQUFRO0FBQ2pCLEtBQUksS0FBSyxFQUFFLFNBQVMsTUFBTSxDQUFDLENBQUMsRUFBRTtBQUM5QixPQUFNLElBQUksSUFBSSxDQUFDLE1BQU0sS0FBSyxDQUFDLEVBQUUsT0FBTyxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDO09BQzlDLElBQUksR0FBRyxHQUFHLE1BQU0sQ0FBQyxXQUFXLENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDO0FBQzVDLE9BQU0sSUFBSSxDQUFDLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQztBQUN4QixPQUFNLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQztPQUNWLE9BQU8sQ0FBQyxFQUFFO1NBQ1IsVUFBVSxDQUFDLENBQUMsQ0FBQyxJQUFJLEVBQUUsR0FBRyxFQUFFLENBQUMsQ0FBQyxDQUFDO0FBQ25DLFNBQVEsQ0FBQyxJQUFJLENBQUMsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDO0FBQzNCLFNBQVEsQ0FBQyxHQUFHLENBQUMsQ0FBQyxJQUFJLENBQUM7UUFDWjtPQUNELE9BQU8sR0FBRyxDQUFDO01BQ1o7QUFDTDtBQUNBO0FBQ0EsSUFBRyxFQUFFO0tBQ0QsR0FBRyxFQUFFLFNBQVM7S0FDZCxLQUFLLEVBQUUsU0FBUyxPQUFPLENBQUMsQ0FBQyxFQUFFLFVBQVUsRUFBRTtPQUNyQyxJQUFJLEdBQUcsQ0FBQztPQUNSLElBQUksQ0FBQyxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLE1BQU0sRUFBRTtBQUNyQztBQUNBLFNBQVEsR0FBRyxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUM7QUFDekMsU0FBUSxJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDMUMsTUFBTSxJQUFJLENBQUMsS0FBSyxJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxNQUFNLEVBQUU7QUFDOUM7QUFDQSxTQUFRLEdBQUcsR0FBRyxJQUFJLENBQUMsS0FBSyxFQUFFLENBQUM7QUFDM0IsUUFBTyxNQUFNO0FBQ2I7QUFDQSxTQUFRLEdBQUcsR0FBRyxVQUFVLEdBQUcsSUFBSSxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsVUFBVSxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQzVEO09BQ0QsT0FBTyxHQUFHLENBQUM7TUFDWjtBQUNMLElBQUcsRUFBRTtLQUNELEdBQUcsRUFBRSxPQUFPO0FBQ2hCLEtBQUksS0FBSyxFQUFFLFNBQVMsS0FBSyxHQUFHO0FBQzVCLE9BQU0sT0FBTyxJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQztNQUN2QjtBQUNMO0FBQ0E7QUFDQSxJQUFHLEVBQUU7S0FDRCxHQUFHLEVBQUUsWUFBWTtBQUNyQixLQUFJLEtBQUssRUFBRSxTQUFTLFVBQVUsQ0FBQyxDQUFDLEVBQUU7QUFDbEMsT0FBTSxJQUFJLENBQUMsR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDO0FBQ3hCLE9BQU0sSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ2hCLE9BQU0sSUFBSSxHQUFHLEdBQUcsQ0FBQyxDQUFDLElBQUksQ0FBQztBQUN2QixPQUFNLENBQUMsSUFBSSxHQUFHLENBQUMsTUFBTSxDQUFDO0FBQ3RCLE9BQU0sT0FBTyxDQUFDLEdBQUcsQ0FBQyxDQUFDLElBQUksRUFBRTtBQUN6QixTQUFRLElBQUksR0FBRyxHQUFHLENBQUMsQ0FBQyxJQUFJLENBQUM7QUFDekIsU0FBUSxJQUFJLEVBQUUsR0FBRyxDQUFDLEdBQUcsR0FBRyxDQUFDLE1BQU0sR0FBRyxHQUFHLENBQUMsTUFBTSxHQUFHLENBQUMsQ0FBQztTQUN6QyxJQUFJLEVBQUUsS0FBSyxHQUFHLENBQUMsTUFBTSxFQUFFLEdBQUcsSUFBSSxHQUFHLENBQUMsS0FBSyxHQUFHLElBQUksR0FBRyxDQUFDLEtBQUssQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUM7U0FDOUQsQ0FBQyxJQUFJLEVBQUUsQ0FBQztBQUNoQixTQUFRLElBQUksQ0FBQyxLQUFLLENBQUMsRUFBRTtBQUNyQixXQUFVLElBQUksRUFBRSxLQUFLLEdBQUcsQ0FBQyxNQUFNLEVBQUU7YUFDckIsRUFBRSxDQUFDLENBQUM7YUFDSixJQUFJLENBQUMsQ0FBQyxJQUFJLEVBQUUsSUFBSSxDQUFDLElBQUksR0FBRyxDQUFDLENBQUMsSUFBSSxDQUFDLEtBQUssSUFBSSxDQUFDLElBQUksR0FBRyxJQUFJLENBQUMsSUFBSSxHQUFHLElBQUksQ0FBQztBQUM3RSxZQUFXLE1BQU07QUFDakIsYUFBWSxJQUFJLENBQUMsSUFBSSxHQUFHLENBQUMsQ0FBQzthQUNkLENBQUMsQ0FBQyxJQUFJLEdBQUcsR0FBRyxDQUFDLEtBQUssQ0FBQyxFQUFFLENBQUMsQ0FBQztZQUN4QjtBQUNYLFdBQVUsTUFBTTtVQUNQO1NBQ0QsRUFBRSxDQUFDLENBQUM7UUFDTDtBQUNQLE9BQU0sSUFBSSxDQUFDLE1BQU0sSUFBSSxDQUFDLENBQUM7T0FDakIsT0FBTyxHQUFHLENBQUM7TUFDWjtBQUNMO0FBQ0E7QUFDQSxJQUFHLEVBQUU7S0FDRCxHQUFHLEVBQUUsWUFBWTtBQUNyQixLQUFJLEtBQUssRUFBRSxTQUFTLFVBQVUsQ0FBQyxDQUFDLEVBQUU7T0FDNUIsSUFBSSxHQUFHLEdBQUcsTUFBTSxDQUFDLFdBQVcsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUN0QyxPQUFNLElBQUksQ0FBQyxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUM7QUFDeEIsT0FBTSxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUM7T0FDVixDQUFDLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQztBQUN2QixPQUFNLENBQUMsSUFBSSxDQUFDLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQztBQUN6QixPQUFNLE9BQU8sQ0FBQyxHQUFHLENBQUMsQ0FBQyxJQUFJLEVBQUU7QUFDekIsU0FBUSxJQUFJLEdBQUcsR0FBRyxDQUFDLENBQUMsSUFBSSxDQUFDO0FBQ3pCLFNBQVEsSUFBSSxFQUFFLEdBQUcsQ0FBQyxHQUFHLEdBQUcsQ0FBQyxNQUFNLEdBQUcsR0FBRyxDQUFDLE1BQU0sR0FBRyxDQUFDLENBQUM7QUFDakQsU0FBUSxHQUFHLENBQUMsSUFBSSxDQUFDLEdBQUcsRUFBRSxHQUFHLENBQUMsTUFBTSxHQUFHLENBQUMsRUFBRSxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUM7U0FDckMsQ0FBQyxJQUFJLEVBQUUsQ0FBQztBQUNoQixTQUFRLElBQUksQ0FBQyxLQUFLLENBQUMsRUFBRTtBQUNyQixXQUFVLElBQUksRUFBRSxLQUFLLEdBQUcsQ0FBQyxNQUFNLEVBQUU7YUFDckIsRUFBRSxDQUFDLENBQUM7YUFDSixJQUFJLENBQUMsQ0FBQyxJQUFJLEVBQUUsSUFBSSxDQUFDLElBQUksR0FBRyxDQUFDLENBQUMsSUFBSSxDQUFDLEtBQUssSUFBSSxDQUFDLElBQUksR0FBRyxJQUFJLENBQUMsSUFBSSxHQUFHLElBQUksQ0FBQztBQUM3RSxZQUFXLE1BQU07QUFDakIsYUFBWSxJQUFJLENBQUMsSUFBSSxHQUFHLENBQUMsQ0FBQzthQUNkLENBQUMsQ0FBQyxJQUFJLEdBQUcsR0FBRyxDQUFDLEtBQUssQ0FBQyxFQUFFLENBQUMsQ0FBQztZQUN4QjtBQUNYLFdBQVUsTUFBTTtVQUNQO1NBQ0QsRUFBRSxDQUFDLENBQUM7UUFDTDtBQUNQLE9BQU0sSUFBSSxDQUFDLE1BQU0sSUFBSSxDQUFDLENBQUM7T0FDakIsT0FBTyxHQUFHLENBQUM7TUFDWjtBQUNMO0FBQ0E7QUFDQSxJQUFHLEVBQUU7S0FDRCxHQUFHLEVBQUUsTUFBTTtLQUNYLEtBQUssRUFBRSxTQUFTLEtBQUssQ0FBQyxDQUFDLEVBQUUsT0FBTyxFQUFFO0FBQ3RDLE9BQU0sT0FBTyxPQUFPLENBQUMsSUFBSSxFQUFFLGFBQWEsQ0FBQyxhQUFhLENBQUMsRUFBRSxFQUFFLE9BQU8sQ0FBQyxFQUFFLEVBQUUsRUFBRTtBQUN6RTtTQUNRLEtBQUssRUFBRSxDQUFDO0FBQ2hCO1NBQ1EsYUFBYSxFQUFFLEtBQUs7UUFDckIsQ0FBQyxDQUFDLENBQUM7TUFDTDtJQUNGLENBQUMsQ0FBQyxDQUFDO0dBQ0osT0FBTyxVQUFVLENBQUM7QUFDcEIsRUFBQyxFQUFFLENBQUE7Ozs7Ozs7Ozs7QUNyTEg7QUFDQTtBQUNBLENBQUEsU0FBUyxPQUFPLENBQUMsR0FBRyxFQUFFLEVBQUUsRUFBRTtBQUMxQixHQUFFLElBQUksS0FBSyxHQUFHLElBQUksQ0FBQztBQUNuQixHQUFFLElBQUksaUJBQWlCLEdBQUcsSUFBSSxDQUFDLGNBQWMsSUFBSSxJQUFJLENBQUMsY0FBYyxDQUFDLFNBQVMsQ0FBQztBQUMvRSxHQUFFLElBQUksaUJBQWlCLEdBQUcsSUFBSSxDQUFDLGNBQWMsSUFBSSxJQUFJLENBQUMsY0FBYyxDQUFDLFNBQVMsQ0FBQztBQUMvRSxHQUFFLElBQUksaUJBQWlCLElBQUksaUJBQWlCLEVBQUU7S0FDMUMsSUFBSSxFQUFFLEVBQUU7QUFDWixPQUFNLEVBQUUsQ0FBQyxHQUFHLENBQUMsQ0FBQztNQUNULE1BQU0sSUFBSSxHQUFHLEVBQUU7QUFDcEIsT0FBTSxJQUFJLENBQUMsSUFBSSxDQUFDLGNBQWMsRUFBRTtTQUN4QixPQUFPLENBQUMsUUFBUSxDQUFDLFdBQVcsRUFBRSxJQUFJLEVBQUUsR0FBRyxDQUFDLENBQUM7UUFDMUMsTUFBTSxJQUFJLENBQUMsSUFBSSxDQUFDLGNBQWMsQ0FBQyxZQUFZLEVBQUU7QUFDcEQsU0FBUSxJQUFJLENBQUMsY0FBYyxDQUFDLFlBQVksR0FBRyxJQUFJLENBQUM7U0FDeEMsT0FBTyxDQUFDLFFBQVEsQ0FBQyxXQUFXLEVBQUUsSUFBSSxFQUFFLEdBQUcsQ0FBQyxDQUFDO1FBQzFDO01BQ0Y7S0FDRCxPQUFPLElBQUksQ0FBQztJQUNiO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFFLElBQUksSUFBSSxDQUFDLGNBQWMsRUFBRTtBQUMzQixLQUFJLElBQUksQ0FBQyxjQUFjLENBQUMsU0FBUyxHQUFHLElBQUksQ0FBQztJQUN0QztBQUNIO0FBQ0E7QUFDQSxHQUFFLElBQUksSUFBSSxDQUFDLGNBQWMsRUFBRTtBQUMzQixLQUFJLElBQUksQ0FBQyxjQUFjLENBQUMsU0FBUyxHQUFHLElBQUksQ0FBQztJQUN0QztHQUNELElBQUksQ0FBQyxRQUFRLENBQUMsR0FBRyxJQUFJLElBQUksRUFBRSxVQUFVLEdBQUcsRUFBRTtBQUM1QyxLQUFJLElBQUksQ0FBQyxFQUFFLElBQUksR0FBRyxFQUFFO0FBQ3BCLE9BQU0sSUFBSSxDQUFDLEtBQUssQ0FBQyxjQUFjLEVBQUU7U0FDekIsT0FBTyxDQUFDLFFBQVEsQ0FBQyxtQkFBbUIsRUFBRSxLQUFLLEVBQUUsR0FBRyxDQUFDLENBQUM7UUFDbkQsTUFBTSxJQUFJLENBQUMsS0FBSyxDQUFDLGNBQWMsQ0FBQyxZQUFZLEVBQUU7QUFDckQsU0FBUSxLQUFLLENBQUMsY0FBYyxDQUFDLFlBQVksR0FBRyxJQUFJLENBQUM7U0FDekMsT0FBTyxDQUFDLFFBQVEsQ0FBQyxtQkFBbUIsRUFBRSxLQUFLLEVBQUUsR0FBRyxDQUFDLENBQUM7QUFDMUQsUUFBTyxNQUFNO1NBQ0wsT0FBTyxDQUFDLFFBQVEsQ0FBQyxXQUFXLEVBQUUsS0FBSyxDQUFDLENBQUM7UUFDdEM7TUFDRixNQUFNLElBQUksRUFBRSxFQUFFO09BQ2IsT0FBTyxDQUFDLFFBQVEsQ0FBQyxXQUFXLEVBQUUsS0FBSyxDQUFDLENBQUM7QUFDM0MsT0FBTSxFQUFFLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDZCxNQUFLLE1BQU07T0FDTCxPQUFPLENBQUMsUUFBUSxDQUFDLFdBQVcsRUFBRSxLQUFLLENBQUMsQ0FBQztNQUN0QztBQUNMLElBQUcsQ0FBQyxDQUFDO0dBQ0gsT0FBTyxJQUFJLENBQUM7RUFDYjtBQUNELENBQUEsU0FBUyxtQkFBbUIsQ0FBQyxJQUFJLEVBQUUsR0FBRyxFQUFFO0FBQ3hDLEdBQUUsV0FBVyxDQUFDLElBQUksRUFBRSxHQUFHLENBQUMsQ0FBQztBQUN6QixHQUFFLFdBQVcsQ0FBQyxJQUFJLENBQUMsQ0FBQztFQUNuQjtDQUNELFNBQVMsV0FBVyxDQUFDLElBQUksRUFBRTtBQUMzQixHQUFFLElBQUksSUFBSSxDQUFDLGNBQWMsSUFBSSxDQUFDLElBQUksQ0FBQyxjQUFjLENBQUMsU0FBUyxFQUFFLE9BQU87QUFDcEUsR0FBRSxJQUFJLElBQUksQ0FBQyxjQUFjLElBQUksQ0FBQyxJQUFJLENBQUMsY0FBYyxDQUFDLFNBQVMsRUFBRSxPQUFPO0FBQ3BFLEdBQUUsSUFBSSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQztFQUNwQjtBQUNELENBQUEsU0FBUyxTQUFTLEdBQUc7QUFDckIsR0FBRSxJQUFJLElBQUksQ0FBQyxjQUFjLEVBQUU7QUFDM0IsS0FBSSxJQUFJLENBQUMsY0FBYyxDQUFDLFNBQVMsR0FBRyxLQUFLLENBQUM7QUFDMUMsS0FBSSxJQUFJLENBQUMsY0FBYyxDQUFDLE9BQU8sR0FBRyxLQUFLLENBQUM7QUFDeEMsS0FBSSxJQUFJLENBQUMsY0FBYyxDQUFDLEtBQUssR0FBRyxLQUFLLENBQUM7QUFDdEMsS0FBSSxJQUFJLENBQUMsY0FBYyxDQUFDLFVBQVUsR0FBRyxLQUFLLENBQUM7SUFDeEM7QUFDSCxHQUFFLElBQUksSUFBSSxDQUFDLGNBQWMsRUFBRTtBQUMzQixLQUFJLElBQUksQ0FBQyxjQUFjLENBQUMsU0FBUyxHQUFHLEtBQUssQ0FBQztBQUMxQyxLQUFJLElBQUksQ0FBQyxjQUFjLENBQUMsS0FBSyxHQUFHLEtBQUssQ0FBQztBQUN0QyxLQUFJLElBQUksQ0FBQyxjQUFjLENBQUMsTUFBTSxHQUFHLEtBQUssQ0FBQztBQUN2QyxLQUFJLElBQUksQ0FBQyxjQUFjLENBQUMsV0FBVyxHQUFHLEtBQUssQ0FBQztBQUM1QyxLQUFJLElBQUksQ0FBQyxjQUFjLENBQUMsV0FBVyxHQUFHLEtBQUssQ0FBQztBQUM1QyxLQUFJLElBQUksQ0FBQyxjQUFjLENBQUMsUUFBUSxHQUFHLEtBQUssQ0FBQztBQUN6QyxLQUFJLElBQUksQ0FBQyxjQUFjLENBQUMsWUFBWSxHQUFHLEtBQUssQ0FBQztJQUMxQztFQUNGO0FBQ0QsQ0FBQSxTQUFTLFdBQVcsQ0FBQyxJQUFJLEVBQUUsR0FBRyxFQUFFO0dBQzlCLElBQUksQ0FBQyxJQUFJLENBQUMsT0FBTyxFQUFFLEdBQUcsQ0FBQyxDQUFDO0VBQ3pCO0FBQ0QsQ0FBQSxTQUFTLGNBQWMsQ0FBQyxNQUFNLEVBQUUsR0FBRyxFQUFFO0FBQ3JDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUUsSUFBSSxNQUFNLEdBQUcsTUFBTSxDQUFDLGNBQWMsQ0FBQztBQUNyQyxHQUFFLElBQUksTUFBTSxHQUFHLE1BQU0sQ0FBQyxjQUFjLENBQUM7QUFDckMsR0FBRSxJQUFJLE1BQU0sSUFBSSxNQUFNLENBQUMsV0FBVyxJQUFJLE1BQU0sSUFBSSxNQUFNLENBQUMsV0FBVyxFQUFFLE1BQU0sQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLENBQUMsS0FBSyxNQUFNLENBQUMsSUFBSSxDQUFDLE9BQU8sRUFBRSxHQUFHLENBQUMsQ0FBQztFQUN0SDtBQUNELENBQUEsU0FBYyxHQUFHO0dBQ2YsT0FBTyxFQUFFLE9BQU87R0FDaEIsU0FBUyxFQUFFLFNBQVM7R0FDcEIsY0FBYyxFQUFFLGNBQWM7RUFDL0IsQ0FBQTs7Ozs7Ozs7Ozs7QUM5RkQ7Q0FDQSxNQUFNLEtBQUssR0FBRyxFQUFFLENBQUM7QUFDakI7QUFDQSxDQUFBLFNBQVMsZUFBZSxDQUFDLElBQUksRUFBRSxPQUFPLEVBQUUsSUFBSSxFQUFFO0dBQzVDLElBQUksQ0FBQyxJQUFJLEVBQUU7S0FDVCxJQUFJLEdBQUcsTUFBSztJQUNiO0FBQ0g7R0FDRSxTQUFTLFVBQVUsRUFBRSxJQUFJLEVBQUUsSUFBSSxFQUFFLElBQUksRUFBRTtBQUN6QyxLQUFJLElBQUksT0FBTyxPQUFPLEtBQUssUUFBUSxFQUFFO0FBQ3JDLE9BQU0sT0FBTyxPQUFPO0FBQ3BCLE1BQUssTUFBTTtPQUNMLE9BQU8sT0FBTyxDQUFDLElBQUksRUFBRSxJQUFJLEVBQUUsSUFBSSxDQUFDO01BQ2pDO0lBQ0Y7QUFDSDtBQUNBLEdBQUUsTUFBTSxTQUFTLFNBQVMsSUFBSSxDQUFDO0tBQzNCLFdBQVcsQ0FBQyxDQUFDLElBQUksRUFBRSxJQUFJLEVBQUUsSUFBSSxFQUFFO09BQzdCLEtBQUssQ0FBQyxVQUFVLENBQUMsSUFBSSxFQUFFLElBQUksRUFBRSxJQUFJLENBQUMsQ0FBQyxDQUFDO01BQ3JDO0lBQ0Y7QUFDSDtHQUNFLFNBQVMsQ0FBQyxTQUFTLENBQUMsSUFBSSxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUM7QUFDdkMsR0FBRSxTQUFTLENBQUMsU0FBUyxDQUFDLElBQUksR0FBRyxJQUFJLENBQUM7QUFDbEM7QUFDQSxHQUFFLEtBQUssQ0FBQyxJQUFJLENBQUMsR0FBRyxTQUFTLENBQUM7RUFDekI7QUFDRDtBQUNBO0FBQ0EsQ0FBQSxTQUFTLEtBQUssQ0FBQyxRQUFRLEVBQUUsS0FBSyxFQUFFO0FBQ2hDLEdBQUUsSUFBSSxLQUFLLENBQUMsT0FBTyxDQUFDLFFBQVEsQ0FBQyxFQUFFO0FBQy9CLEtBQUksTUFBTSxHQUFHLEdBQUcsUUFBUSxDQUFDLE1BQU0sQ0FBQztBQUNoQyxLQUFJLFFBQVEsR0FBRyxRQUFRLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxLQUFLLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQzlDLEtBQUksSUFBSSxHQUFHLEdBQUcsQ0FBQyxFQUFFO09BQ1gsT0FBTyxDQUFDLE9BQU8sRUFBRSxLQUFLLENBQUMsQ0FBQyxFQUFFLFFBQVEsQ0FBQyxLQUFLLENBQUMsQ0FBQyxFQUFFLEdBQUcsR0FBRyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUMsS0FBSyxDQUFDO0FBQzVFLGNBQWEsUUFBUSxDQUFDLEdBQUcsR0FBRyxDQUFDLENBQUMsQ0FBQztBQUMvQixNQUFLLE1BQU0sSUFBSSxHQUFHLEtBQUssQ0FBQyxFQUFFO09BQ3BCLE9BQU8sQ0FBQyxPQUFPLEVBQUUsS0FBSyxDQUFDLENBQUMsRUFBRSxRQUFRLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxFQUFFLFFBQVEsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDaEUsTUFBSyxNQUFNO0FBQ1gsT0FBTSxPQUFPLENBQUMsR0FBRyxFQUFFLEtBQUssQ0FBQyxDQUFDLEVBQUUsUUFBUSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztNQUNyQztBQUNMLElBQUcsTUFBTTtBQUNULEtBQUksT0FBTyxDQUFDLEdBQUcsRUFBRSxLQUFLLENBQUMsQ0FBQyxFQUFFLE1BQU0sQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFDMUM7RUFDRjtBQUNEO0FBQ0E7QUFDQSxDQUFBLFNBQVMsVUFBVSxDQUFDLEdBQUcsRUFBRSxNQUFNLEVBQUUsR0FBRyxFQUFFO0VBQ3JDLE9BQU8sR0FBRyxDQUFDLE1BQU0sQ0FBQyxDQUFDLEdBQUcsSUFBSSxHQUFHLEdBQUcsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLEdBQUcsRUFBRSxNQUFNLENBQUMsTUFBTSxDQUFDLEtBQUssTUFBTSxDQUFDO0VBQ3hFO0FBQ0Q7QUFDQTtBQUNBLENBQUEsU0FBUyxRQUFRLENBQUMsR0FBRyxFQUFFLE1BQU0sRUFBRSxRQUFRLEVBQUU7RUFDeEMsSUFBSSxRQUFRLEtBQUssU0FBUyxJQUFJLFFBQVEsR0FBRyxHQUFHLENBQUMsTUFBTSxFQUFFO0FBQ3RELEdBQUUsUUFBUSxHQUFHLEdBQUcsQ0FBQyxNQUFNLENBQUM7R0FDdEI7QUFDRixFQUFDLE9BQU8sR0FBRyxDQUFDLFNBQVMsQ0FBQyxRQUFRLEdBQUcsTUFBTSxDQUFDLE1BQU0sRUFBRSxRQUFRLENBQUMsS0FBSyxNQUFNLENBQUM7RUFDcEU7QUFDRDtBQUNBO0FBQ0EsQ0FBQSxTQUFTLFFBQVEsQ0FBQyxHQUFHLEVBQUUsTUFBTSxFQUFFLEtBQUssRUFBRTtBQUN0QyxHQUFFLElBQUksT0FBTyxLQUFLLEtBQUssUUFBUSxFQUFFO0tBQzdCLEtBQUssR0FBRyxDQUFDLENBQUM7SUFDWDtBQUNIO0dBQ0UsSUFBSSxLQUFLLEdBQUcsTUFBTSxDQUFDLE1BQU0sR0FBRyxHQUFHLENBQUMsTUFBTSxFQUFFO0tBQ3RDLE9BQU8sS0FBSyxDQUFDO0FBQ2pCLElBQUcsTUFBTTtBQUNULEtBQUksT0FBTyxHQUFHLENBQUMsT0FBTyxDQUFDLE1BQU0sRUFBRSxLQUFLLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQztJQUMxQztFQUNGO0FBQ0Q7QUFDQSxDQUFBLGVBQWUsQ0FBQyx1QkFBdUIsRUFBRSxVQUFVLElBQUksRUFBRSxLQUFLLEVBQUU7R0FDOUQsT0FBTyxhQUFhLEdBQUcsS0FBSyxHQUFHLDJCQUEyQixHQUFHLElBQUksR0FBRyxHQUFHO0VBQ3hFLEVBQUUsU0FBUyxDQUFDLENBQUM7Q0FDZCxlQUFlLENBQUMsc0JBQXNCLEVBQUUsVUFBVSxJQUFJLEVBQUUsUUFBUSxFQUFFLE1BQU0sRUFBRTtBQUMxRTtHQUNFLElBQUksVUFBVSxDQUFDO0FBQ2pCLEdBQUUsSUFBSSxPQUFPLFFBQVEsS0FBSyxRQUFRLElBQUksVUFBVSxDQUFDLFFBQVEsRUFBRSxNQUFNLENBQUMsRUFBRTtLQUNoRSxVQUFVLEdBQUcsYUFBYSxDQUFDO0tBQzNCLFFBQVEsR0FBRyxRQUFRLENBQUMsT0FBTyxDQUFDLE9BQU8sRUFBRSxFQUFFLENBQUMsQ0FBQztBQUM3QyxJQUFHLE1BQU07S0FDTCxVQUFVLEdBQUcsU0FBUyxDQUFDO0lBQ3hCO0FBQ0g7R0FDRSxJQUFJLEdBQUcsQ0FBQztBQUNWLEdBQUUsSUFBSSxRQUFRLENBQUMsSUFBSSxFQUFFLFdBQVcsQ0FBQyxFQUFFO0FBQ25DO0tBQ0ksR0FBRyxHQUFHLENBQUMsSUFBSSxFQUFFLElBQUksQ0FBQyxDQUFDLEVBQUUsVUFBVSxDQUFDLENBQUMsRUFBRSxLQUFLLENBQUMsUUFBUSxFQUFFLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNqRSxJQUFHLE1BQU07QUFDVCxLQUFJLE1BQU0sSUFBSSxHQUFHLFFBQVEsQ0FBQyxJQUFJLEVBQUUsR0FBRyxDQUFDLEdBQUcsVUFBVSxHQUFHLFVBQVUsQ0FBQztLQUMzRCxHQUFHLEdBQUcsQ0FBQyxLQUFLLEVBQUUsSUFBSSxDQUFDLEVBQUUsRUFBRSxJQUFJLENBQUMsQ0FBQyxFQUFFLFVBQVUsQ0FBQyxDQUFDLEVBQUUsS0FBSyxDQUFDLFFBQVEsRUFBRSxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFDeEU7QUFDSDtHQUNFLEdBQUcsSUFBSSxDQUFDLGdCQUFnQixFQUFFLE9BQU8sTUFBTSxDQUFDLENBQUMsQ0FBQztHQUMxQyxPQUFPLEdBQUcsQ0FBQztFQUNaLEVBQUUsU0FBUyxDQUFDLENBQUM7QUFDZCxDQUFBLGVBQWUsQ0FBQywyQkFBMkIsRUFBRSx5QkFBeUIsQ0FBQyxDQUFDO0FBQ3hFLENBQUEsZUFBZSxDQUFDLDRCQUE0QixFQUFFLFVBQVUsSUFBSSxFQUFFO0FBQzlELEdBQUUsT0FBTyxNQUFNLEdBQUcsSUFBSSxHQUFHLDRCQUE0QjtBQUNyRCxFQUFDLENBQUMsQ0FBQztBQUNILENBQUEsZUFBZSxDQUFDLDRCQUE0QixFQUFFLGlCQUFpQixDQUFDLENBQUM7QUFDakUsQ0FBQSxlQUFlLENBQUMsc0JBQXNCLEVBQUUsVUFBVSxJQUFJLEVBQUU7QUFDeEQsR0FBRSxPQUFPLGNBQWMsR0FBRyxJQUFJLEdBQUcsK0JBQStCLENBQUM7QUFDakUsRUFBQyxDQUFDLENBQUM7QUFDSCxDQUFBLGVBQWUsQ0FBQyx1QkFBdUIsRUFBRSxnQ0FBZ0MsQ0FBQyxDQUFDO0FBQzNFLENBQUEsZUFBZSxDQUFDLHdCQUF3QixFQUFFLDJCQUEyQixDQUFDLENBQUM7QUFDdkUsQ0FBQSxlQUFlLENBQUMsNEJBQTRCLEVBQUUsaUJBQWlCLENBQUMsQ0FBQztBQUNqRSxDQUFBLGVBQWUsQ0FBQyx3QkFBd0IsRUFBRSxxQ0FBcUMsRUFBRSxTQUFTLENBQUMsQ0FBQztBQUM1RixDQUFBLGVBQWUsQ0FBQyxzQkFBc0IsRUFBRSxVQUFVLEdBQUcsRUFBRTtHQUNyRCxPQUFPLG9CQUFvQixHQUFHLEdBQUc7RUFDbEMsRUFBRSxTQUFTLENBQUMsQ0FBQztBQUNkLENBQUEsZUFBZSxDQUFDLG9DQUFvQyxFQUFFLGtDQUFrQyxDQUFDLENBQUM7QUFDMUY7QUFDQSxDQUFBLE1BQUEsQ0FBQSxLQUFvQixHQUFHLEtBQUssQ0FBQTs7Ozs7Ozs7OztBQ2xINUI7QUFDQSxDQUFBLElBQUkscUJBQXFCLEdBQUdJLGFBQUEsRUFBMEIsQ0FBQyxLQUFLLENBQUMscUJBQXFCLENBQUM7QUFDbkYsQ0FBQSxTQUFTLGlCQUFpQixDQUFDLE9BQU8sRUFBRSxRQUFRLEVBQUUsU0FBUyxFQUFFO0FBQ3pELEdBQUUsT0FBTyxPQUFPLENBQUMsYUFBYSxJQUFJLElBQUksR0FBRyxPQUFPLENBQUMsYUFBYSxHQUFHLFFBQVEsR0FBRyxPQUFPLENBQUMsU0FBUyxDQUFDLEdBQUcsSUFBSSxDQUFDO0VBQ3JHO0NBQ0QsU0FBUyxnQkFBZ0IsQ0FBQyxLQUFLLEVBQUUsT0FBTyxFQUFFLFNBQVMsRUFBRSxRQUFRLEVBQUU7R0FDN0QsSUFBSSxHQUFHLEdBQUcsaUJBQWlCLENBQUMsT0FBTyxFQUFFLFFBQVEsRUFBRSxTQUFTLENBQUMsQ0FBQztBQUM1RCxHQUFFLElBQUksR0FBRyxJQUFJLElBQUksRUFBRTtLQUNmLElBQUksRUFBRSxRQUFRLENBQUMsR0FBRyxDQUFDLElBQUksSUFBSSxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsS0FBSyxHQUFHLENBQUMsSUFBSSxHQUFHLEdBQUcsQ0FBQyxFQUFFO09BQzFELElBQUksSUFBSSxHQUFHLFFBQVEsR0FBRyxTQUFTLEdBQUcsZUFBZSxDQUFDO09BQ2xELE1BQU0sSUFBSSxxQkFBcUIsQ0FBQyxJQUFJLEVBQUUsR0FBRyxDQUFDLENBQUM7TUFDNUM7QUFDTCxLQUFJLE9BQU8sSUFBSSxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQztJQUN4QjtBQUNIO0FBQ0E7R0FDRSxPQUFPLEtBQUssQ0FBQyxVQUFVLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxJQUFJLENBQUM7RUFDMUM7QUFDRCxDQUFBLEtBQWMsR0FBRztHQUNmLGdCQUFnQixFQUFFLGdCQUFnQjtFQUNuQyxDQUFBOzs7Ozs7Ozs7Ozs7O0FDckJELENBQUEsSUFBSSxPQUFPLE1BQU0sQ0FBQyxNQUFNLEtBQUssVUFBVSxFQUFFO0FBQ3pDO0dBQ0V5RCxnQkFBQSxDQUFBLE9BQWMsR0FBRyxTQUFTLFFBQVEsQ0FBQyxJQUFJLEVBQUUsU0FBUyxFQUFFO0tBQ2xELElBQUksU0FBUyxFQUFFO0FBQ25CLE9BQU0sSUFBSSxDQUFDLE1BQU0sR0FBRyxVQUFTO09BQ3ZCLElBQUksQ0FBQyxTQUFTLEdBQUcsTUFBTSxDQUFDLE1BQU0sQ0FBQyxTQUFTLENBQUMsU0FBUyxFQUFFO0FBQzFELFNBQVEsV0FBVyxFQUFFO1dBQ1gsS0FBSyxFQUFFLElBQUk7V0FDWCxVQUFVLEVBQUUsS0FBSztXQUNqQixRQUFRLEVBQUUsSUFBSTtXQUNkLFlBQVksRUFBRSxJQUFJO1VBQ25CO0FBQ1QsUUFBTyxFQUFDO01BQ0g7QUFDTCxJQUFHLENBQUM7QUFDSixFQUFDLE1BQU07QUFDUDtHQUNFQSxnQkFBQSxDQUFBLE9BQWMsR0FBRyxTQUFTLFFBQVEsQ0FBQyxJQUFJLEVBQUUsU0FBUyxFQUFFO0tBQ2xELElBQUksU0FBUyxFQUFFO0FBQ25CLE9BQU0sSUFBSSxDQUFDLE1BQU0sR0FBRyxVQUFTO0FBQzdCLE9BQU0sSUFBSSxRQUFRLEdBQUcsWUFBWSxHQUFFO0FBQ25DLE9BQU0sUUFBUSxDQUFDLFNBQVMsR0FBRyxTQUFTLENBQUMsVUFBUztBQUM5QyxPQUFNLElBQUksQ0FBQyxTQUFTLEdBQUcsSUFBSSxRQUFRLEdBQUU7QUFDckMsT0FBTSxJQUFJLENBQUMsU0FBUyxDQUFDLFdBQVcsR0FBRyxLQUFJO01BQ2xDO0tBQ0Y7QUFDSCxFQUFBOzs7Ozs7Ozs7Q0MxQkEsSUFBSTtBQUNKLEdBQUUsSUFBSSxJQUFJLEdBQUcsT0FBUSxDQUFBLE1BQU0sQ0FBQyxDQUFDO0FBQzdCO0dBQ0UsSUFBSSxPQUFPLElBQUksQ0FBQyxRQUFRLEtBQUssVUFBVSxFQUFFLE1BQU0sRUFBRSxDQUFDO0FBQ3BELEdBQUVDLFFBQWMsQ0FBQSxPQUFBLEdBQUcsSUFBSSxDQUFDLFFBQVEsQ0FBQztFQUNoQyxDQUFDLE9BQU8sQ0FBQyxFQUFFO0FBQ1o7R0FDRUEsUUFBQSxDQUFBLE9BQWMsR0FBRzlELHVCQUFBLEVBQWdDLENBQUM7QUFDcEQsRUFBQTs7Ozs7Ozs7OztBQ1BBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsQ0FBYyxJQUFBLEdBQUdJLFlBQWUsQ0FBQyxTQUFTLENBQUE7Ozs7Ozs7Ozs7QUNxQjFDO0FBQ0EsQ0FBYyxnQkFBQSxHQUFHLFFBQVEsQ0FBQztBQVMxQjtBQUNBO0FBQ0E7Q0FDQSxTQUFTLGFBQWEsQ0FBQyxLQUFLLEVBQUU7QUFDOUIsR0FBRSxJQUFJLEtBQUssR0FBRyxJQUFJLENBQUM7QUFDbkIsR0FBRSxJQUFJLENBQUMsSUFBSSxHQUFHLElBQUksQ0FBQztBQUNuQixHQUFFLElBQUksQ0FBQyxLQUFLLEdBQUcsSUFBSSxDQUFDO0FBQ3BCLEdBQUUsSUFBSSxDQUFDLE1BQU0sR0FBRyxZQUFZO0FBQzVCLEtBQUksY0FBYyxDQUFDLEtBQUssRUFBRSxLQUFLLENBQUMsQ0FBQztBQUNqQyxJQUFHLENBQUM7RUFDSDtBQUNEO0FBQ0E7QUFDQTtBQUNBLENBQUEsSUFBSSxNQUFNLENBQUM7QUFDWDtBQUNBO0FBQ0EsQ0FBQSxRQUFRLENBQUMsYUFBYSxHQUFHLGFBQWEsQ0FBQztBQUN2QztBQUNBO0FBQ0EsQ0FBQSxJQUFJLFlBQVksR0FBRztHQUNqQixTQUFTLEVBQUVBLFdBQXlCLEVBQUE7QUFDdEMsRUFBQyxDQUFDO0FBQ0Y7QUFDQTtBQUNBO0NBQ0EsSUFBSSxNQUFNLEdBQUdKLGFBQUEsRUFBb0MsQ0FBQztBQUNsRDtBQUNBO0FBQ0EsQ0FBQSxJQUFJLE1BQU0sR0FBR0MsWUFBaUIsQ0FBQyxNQUFNLENBQUM7QUFDdEMsQ0FBQSxJQUFJLGFBQWEsR0FBRyxDQUFDLE9BQU9GLGNBQU0sS0FBSyxXQUFXLEdBQUdBLGNBQU0sR0FBRyxPQUFPLE1BQU0sS0FBSyxXQUFXLEdBQUcsTUFBTSxHQUFHLE9BQU8sSUFBSSxLQUFLLFdBQVcsR0FBRyxJQUFJLEdBQUcsRUFBRSxFQUFFLFVBQVUsSUFBSSxZQUFZLEVBQUUsQ0FBQztDQUM3SyxTQUFTLG1CQUFtQixDQUFDLEtBQUssRUFBRTtBQUNwQyxHQUFFLE9BQU8sTUFBTSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQztFQUMzQjtDQUNELFNBQVMsYUFBYSxDQUFDLEdBQUcsRUFBRTtHQUMxQixPQUFPLE1BQU0sQ0FBQyxRQUFRLENBQUMsR0FBRyxDQUFDLElBQUksR0FBRyxZQUFZLGFBQWEsQ0FBQztFQUM3RDtDQUNELElBQUksV0FBVyxHQUFHWSxjQUFBLEVBQXFDLENBQUM7Q0FDeEQsSUFBSSxRQUFRLEdBQUd1QyxZQUFtQyxFQUFBO0FBQ2xELEdBQUUsZ0JBQWdCLEdBQUcsUUFBUSxDQUFDLGdCQUFnQixDQUFDO0FBQy9DLENBQUEsSUFBSSxjQUFjLEdBQUdDLGFBQW9CLEVBQUEsQ0FBQyxLQUFLO0FBQy9DLEdBQUUsb0JBQW9CLEdBQUcsY0FBYyxDQUFDLG9CQUFvQjtBQUM1RCxHQUFFLDBCQUEwQixHQUFHLGNBQWMsQ0FBQywwQkFBMEI7QUFDeEUsR0FBRSxxQkFBcUIsR0FBRyxjQUFjLENBQUMscUJBQXFCO0FBQzlELEdBQUUsc0JBQXNCLEdBQUcsY0FBYyxDQUFDLHNCQUFzQjtBQUNoRSxHQUFFLG9CQUFvQixHQUFHLGNBQWMsQ0FBQyxvQkFBb0I7QUFDNUQsR0FBRSxzQkFBc0IsR0FBRyxjQUFjLENBQUMsc0JBQXNCO0FBQ2hFLEdBQUUsMEJBQTBCLEdBQUcsY0FBYyxDQUFDLDBCQUEwQjtBQUN4RSxHQUFFLG9CQUFvQixHQUFHLGNBQWMsQ0FBQyxvQkFBb0IsQ0FBQztBQUM3RCxDQUFBLElBQUksY0FBYyxHQUFHLFdBQVcsQ0FBQyxjQUFjLENBQUM7QUFDaEQsQ0FBQUMsZUFBQSxFQUFtQixDQUFDLFFBQVEsRUFBRSxNQUFNLENBQUMsQ0FBQztDQUN0QyxTQUFTLEdBQUcsR0FBRyxFQUFFO0FBQ2pCLENBQUEsU0FBUyxhQUFhLENBQUMsT0FBTyxFQUFFLE1BQU0sRUFBRSxRQUFRLEVBQUU7QUFDbEQsR0FBRSxNQUFNLEdBQUcsTUFBTSxJQUFJQyx1QkFBMkIsQ0FBQztBQUNqRCxHQUFFLE9BQU8sR0FBRyxPQUFPLElBQUksRUFBRSxDQUFDO0FBQzFCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtHQUNFLElBQUksT0FBTyxRQUFRLEtBQUssU0FBUyxFQUFFLFFBQVEsR0FBRyxNQUFNLFlBQVksTUFBTSxDQUFDO0FBQ3pFO0FBQ0E7QUFDQTtHQUNFLElBQUksQ0FBQyxVQUFVLEdBQUcsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxVQUFVLENBQUM7QUFDekMsR0FBRSxJQUFJLFFBQVEsRUFBRSxJQUFJLENBQUMsVUFBVSxHQUFHLElBQUksQ0FBQyxVQUFVLElBQUksQ0FBQyxDQUFDLE9BQU8sQ0FBQyxrQkFBa0IsQ0FBQztBQUNsRjtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUUsSUFBSSxDQUFDLGFBQWEsR0FBRyxnQkFBZ0IsQ0FBQyxJQUFJLEVBQUUsT0FBTyxFQUFFLHVCQUF1QixFQUFFLFFBQVEsQ0FBQyxDQUFDO0FBQzFGO0FBQ0E7QUFDQSxHQUFFLElBQUksQ0FBQyxXQUFXLEdBQUcsS0FBSyxDQUFDO0FBQzNCO0FBQ0E7QUFDQSxHQUFFLElBQUksQ0FBQyxTQUFTLEdBQUcsS0FBSyxDQUFDO0FBQ3pCO0FBQ0EsR0FBRSxJQUFJLENBQUMsTUFBTSxHQUFHLEtBQUssQ0FBQztBQUN0QjtBQUNBLEdBQUUsSUFBSSxDQUFDLEtBQUssR0FBRyxLQUFLLENBQUM7QUFDckI7QUFDQSxHQUFFLElBQUksQ0FBQyxRQUFRLEdBQUcsS0FBSyxDQUFDO0FBQ3hCO0FBQ0E7QUFDQSxHQUFFLElBQUksQ0FBQyxTQUFTLEdBQUcsS0FBSyxDQUFDO0FBQ3pCO0FBQ0E7QUFDQTtBQUNBO0dBQ0UsSUFBSSxRQUFRLEdBQUcsT0FBTyxDQUFDLGFBQWEsS0FBSyxLQUFLLENBQUM7QUFDakQsR0FBRSxJQUFJLENBQUMsYUFBYSxHQUFHLENBQUMsUUFBUSxDQUFDO0FBQ2pDO0FBQ0E7QUFDQTtBQUNBO0dBQ0UsSUFBSSxDQUFDLGVBQWUsR0FBRyxPQUFPLENBQUMsZUFBZSxJQUFJLE1BQU0sQ0FBQztBQUMzRDtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUUsSUFBSSxDQUFDLE1BQU0sR0FBRyxDQUFDLENBQUM7QUFDbEI7QUFDQTtBQUNBLEdBQUUsSUFBSSxDQUFDLE9BQU8sR0FBRyxLQUFLLENBQUM7QUFDdkI7QUFDQTtBQUNBLEdBQUUsSUFBSSxDQUFDLE1BQU0sR0FBRyxDQUFDLENBQUM7QUFDbEI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUUsSUFBSSxDQUFDLElBQUksR0FBRyxJQUFJLENBQUM7QUFDbkI7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFFLElBQUksQ0FBQyxnQkFBZ0IsR0FBRyxLQUFLLENBQUM7QUFDaEM7QUFDQTtBQUNBLEdBQUUsSUFBSSxDQUFDLE9BQU8sR0FBRyxVQUFVLEVBQUUsRUFBRTtBQUMvQixLQUFJLE9BQU8sQ0FBQyxNQUFNLEVBQUUsRUFBRSxDQUFDLENBQUM7QUFDeEIsSUFBRyxDQUFDO0FBQ0o7QUFDQTtBQUNBLEdBQUUsSUFBSSxDQUFDLE9BQU8sR0FBRyxJQUFJLENBQUM7QUFDdEI7QUFDQTtBQUNBLEdBQUUsSUFBSSxDQUFDLFFBQVEsR0FBRyxDQUFDLENBQUM7QUFDcEIsR0FBRSxJQUFJLENBQUMsZUFBZSxHQUFHLElBQUksQ0FBQztBQUM5QixHQUFFLElBQUksQ0FBQyxtQkFBbUIsR0FBRyxJQUFJLENBQUM7QUFDbEM7QUFDQTtBQUNBO0FBQ0EsR0FBRSxJQUFJLENBQUMsU0FBUyxHQUFHLENBQUMsQ0FBQztBQUNyQjtBQUNBO0FBQ0E7QUFDQSxHQUFFLElBQUksQ0FBQyxXQUFXLEdBQUcsS0FBSyxDQUFDO0FBQzNCO0FBQ0E7QUFDQSxHQUFFLElBQUksQ0FBQyxZQUFZLEdBQUcsS0FBSyxDQUFDO0FBQzVCO0FBQ0E7R0FDRSxJQUFJLENBQUMsU0FBUyxHQUFHLE9BQU8sQ0FBQyxTQUFTLEtBQUssS0FBSyxDQUFDO0FBQy9DO0FBQ0E7R0FDRSxJQUFJLENBQUMsV0FBVyxHQUFHLENBQUMsQ0FBQyxPQUFPLENBQUMsV0FBVyxDQUFDO0FBQzNDO0FBQ0E7QUFDQSxHQUFFLElBQUksQ0FBQyxvQkFBb0IsR0FBRyxDQUFDLENBQUM7QUFDaEM7QUFDQTtBQUNBO0dBQ0UsSUFBSSxDQUFDLGtCQUFrQixHQUFHLElBQUksYUFBYSxDQUFDLElBQUksQ0FBQyxDQUFDO0VBQ25EO0FBQ0QsQ0FBQSxhQUFhLENBQUMsU0FBUyxDQUFDLFNBQVMsR0FBRyxTQUFTLFNBQVMsR0FBRztBQUN6RCxHQUFFLElBQUksT0FBTyxHQUFHLElBQUksQ0FBQyxlQUFlLENBQUM7QUFDckMsR0FBRSxJQUFJLEdBQUcsR0FBRyxFQUFFLENBQUM7R0FDYixPQUFPLE9BQU8sRUFBRTtBQUNsQixLQUFJLEdBQUcsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUM7QUFDdEIsS0FBSSxPQUFPLEdBQUcsT0FBTyxDQUFDLElBQUksQ0FBQztJQUN4QjtHQUNELE9BQU8sR0FBRyxDQUFDO0FBQ2IsRUFBQyxDQUFDO0FBQ0YsQ0FBQSxDQUFDLFlBQVk7QUFDYixHQUFFLElBQUk7S0FDRixNQUFNLENBQUMsY0FBYyxDQUFDLGFBQWEsQ0FBQyxTQUFTLEVBQUUsUUFBUSxFQUFFO09BQ3ZELEdBQUcsRUFBRSxZQUFZLENBQUMsU0FBUyxDQUFDLFNBQVMseUJBQXlCLEdBQUc7QUFDdkUsU0FBUSxPQUFPLElBQUksQ0FBQyxTQUFTLEVBQUUsQ0FBQztBQUNoQyxRQUFPLEVBQUUsb0VBQW9FLEdBQUcsVUFBVSxFQUFFLFNBQVMsQ0FBQztBQUN0RyxNQUFLLENBQUMsQ0FBQztBQUNQLElBQUcsQ0FBQyxPQUFPLENBQUMsRUFBRSxFQUFFO0FBQ2hCLEVBQUMsR0FBRyxDQUFDO0FBQ0w7QUFDQTtBQUNBO0FBQ0EsQ0FBQSxJQUFJLGVBQWUsQ0FBQztDQUNwQixJQUFJLE9BQU8sTUFBTSxLQUFLLFVBQVUsSUFBSSxNQUFNLENBQUMsV0FBVyxJQUFJLE9BQU8sUUFBUSxDQUFDLFNBQVMsQ0FBQyxNQUFNLENBQUMsV0FBVyxDQUFDLEtBQUssVUFBVSxFQUFFO0dBQ3RILGVBQWUsR0FBRyxRQUFRLENBQUMsU0FBUyxDQUFDLE1BQU0sQ0FBQyxXQUFXLENBQUMsQ0FBQztHQUN6RCxNQUFNLENBQUMsY0FBYyxDQUFDLFFBQVEsRUFBRSxNQUFNLENBQUMsV0FBVyxFQUFFO0FBQ3RELEtBQUksS0FBSyxFQUFFLFNBQVMsS0FBSyxDQUFDLE1BQU0sRUFBRTtBQUNsQyxPQUFNLElBQUksZUFBZSxDQUFDLElBQUksQ0FBQyxJQUFJLEVBQUUsTUFBTSxDQUFDLEVBQUUsT0FBTyxJQUFJLENBQUM7QUFDMUQsT0FBTSxJQUFJLElBQUksS0FBSyxRQUFRLEVBQUUsT0FBTyxLQUFLLENBQUM7T0FDcEMsT0FBTyxNQUFNLElBQUksTUFBTSxDQUFDLGNBQWMsWUFBWSxhQUFhLENBQUM7TUFDakU7QUFDTCxJQUFHLENBQUMsQ0FBQztBQUNMLEVBQUMsTUFBTTtBQUNQLEdBQUUsZUFBZSxHQUFHLFNBQVMsZUFBZSxDQUFDLE1BQU0sRUFBRTtBQUNyRCxLQUFJLE9BQU8sTUFBTSxZQUFZLElBQUksQ0FBQztBQUNsQyxJQUFHLENBQUM7RUFDSDtDQUNELFNBQVMsUUFBUSxDQUFDLE9BQU8sRUFBRTtBQUMzQixHQUFFLE1BQU0sR0FBRyxNQUFNLElBQUlBLHVCQUEyQixDQUFDO0FBQ2pEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFFLElBQUksUUFBUSxHQUFHLElBQUksWUFBWSxNQUFNLENBQUM7R0FDdEMsSUFBSSxDQUFDLFFBQVEsSUFBSSxDQUFDLGVBQWUsQ0FBQyxJQUFJLENBQUMsUUFBUSxFQUFFLElBQUksQ0FBQyxFQUFFLE9BQU8sSUFBSSxRQUFRLENBQUMsT0FBTyxDQUFDLENBQUM7QUFDdkYsR0FBRSxJQUFJLENBQUMsY0FBYyxHQUFHLElBQUksYUFBYSxDQUFDLE9BQU8sRUFBRSxJQUFJLEVBQUUsUUFBUSxDQUFDLENBQUM7QUFDbkU7QUFDQTtBQUNBLEdBQUUsSUFBSSxDQUFDLFFBQVEsR0FBRyxJQUFJLENBQUM7R0FDckIsSUFBSSxPQUFPLEVBQUU7QUFDZixLQUFJLElBQUksT0FBTyxPQUFPLENBQUMsS0FBSyxLQUFLLFVBQVUsRUFBRSxJQUFJLENBQUMsTUFBTSxHQUFHLE9BQU8sQ0FBQyxLQUFLLENBQUM7QUFDekUsS0FBSSxJQUFJLE9BQU8sT0FBTyxDQUFDLE1BQU0sS0FBSyxVQUFVLEVBQUUsSUFBSSxDQUFDLE9BQU8sR0FBRyxPQUFPLENBQUMsTUFBTSxDQUFDO0FBQzVFLEtBQUksSUFBSSxPQUFPLE9BQU8sQ0FBQyxPQUFPLEtBQUssVUFBVSxFQUFFLElBQUksQ0FBQyxRQUFRLEdBQUcsT0FBTyxDQUFDLE9BQU8sQ0FBQztBQUMvRSxLQUFJLElBQUksT0FBTyxPQUFPLENBQUMsS0FBSyxLQUFLLFVBQVUsRUFBRSxJQUFJLENBQUMsTUFBTSxHQUFHLE9BQU8sQ0FBQyxLQUFLLENBQUM7SUFDdEU7QUFDSCxHQUFFLE1BQU0sQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUM7RUFDbkI7QUFDRDtBQUNBO0FBQ0EsQ0FBQSxRQUFRLENBQUMsU0FBUyxDQUFDLElBQUksR0FBRyxZQUFZO0dBQ3BDLGNBQWMsQ0FBQyxJQUFJLEVBQUUsSUFBSSxzQkFBc0IsRUFBRSxDQUFDLENBQUM7QUFDckQsRUFBQyxDQUFDO0FBQ0YsQ0FBQSxTQUFTLGFBQWEsQ0FBQyxNQUFNLEVBQUUsRUFBRSxFQUFFO0FBQ25DLEdBQUUsSUFBSSxFQUFFLEdBQUcsSUFBSSwwQkFBMEIsRUFBRSxDQUFDO0FBQzVDO0FBQ0EsR0FBRSxjQUFjLENBQUMsTUFBTSxFQUFFLEVBQUUsQ0FBQyxDQUFDO0dBQzNCLE9BQU8sQ0FBQyxRQUFRLENBQUMsRUFBRSxFQUFFLEVBQUUsQ0FBQyxDQUFDO0VBQzFCO0FBQ0Q7QUFDQTtBQUNBO0FBQ0E7Q0FDQSxTQUFTLFVBQVUsQ0FBQyxNQUFNLEVBQUUsS0FBSyxFQUFFLEtBQUssRUFBRSxFQUFFLEVBQUU7R0FDNUMsSUFBSSxFQUFFLENBQUM7QUFDVCxHQUFFLElBQUksS0FBSyxLQUFLLElBQUksRUFBRTtBQUN0QixLQUFJLEVBQUUsR0FBRyxJQUFJLHNCQUFzQixFQUFFLENBQUM7SUFDbkMsTUFBTSxJQUFJLE9BQU8sS0FBSyxLQUFLLFFBQVEsSUFBSSxDQUFDLEtBQUssQ0FBQyxVQUFVLEVBQUU7QUFDN0QsS0FBSSxFQUFFLEdBQUcsSUFBSSxvQkFBb0IsQ0FBQyxPQUFPLEVBQUUsQ0FBQyxRQUFRLEVBQUUsUUFBUSxDQUFDLEVBQUUsS0FBSyxDQUFDLENBQUM7SUFDckU7R0FDRCxJQUFJLEVBQUUsRUFBRTtBQUNWLEtBQUksY0FBYyxDQUFDLE1BQU0sRUFBRSxFQUFFLENBQUMsQ0FBQztLQUMzQixPQUFPLENBQUMsUUFBUSxDQUFDLEVBQUUsRUFBRSxFQUFFLENBQUMsQ0FBQztLQUN6QixPQUFPLEtBQUssQ0FBQztJQUNkO0dBQ0QsT0FBTyxJQUFJLENBQUM7RUFDYjtDQUNELFFBQVEsQ0FBQyxTQUFTLENBQUMsS0FBSyxHQUFHLFVBQVUsS0FBSyxFQUFFLFFBQVEsRUFBRSxFQUFFLEVBQUU7QUFDMUQsR0FBRSxJQUFJLEtBQUssR0FBRyxJQUFJLENBQUMsY0FBYyxDQUFDO0FBQ2xDLEdBQUUsSUFBSSxHQUFHLEdBQUcsS0FBSyxDQUFDO0FBQ2xCLEdBQUUsSUFBSSxLQUFLLEdBQUcsQ0FBQyxLQUFLLENBQUMsVUFBVSxJQUFJLGFBQWEsQ0FBQyxLQUFLLENBQUMsQ0FBQztHQUN0RCxJQUFJLEtBQUssSUFBSSxDQUFDLE1BQU0sQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDLEVBQUU7QUFDeEMsS0FBSSxLQUFLLEdBQUcsbUJBQW1CLENBQUMsS0FBSyxDQUFDLENBQUM7SUFDcEM7QUFDSCxHQUFFLElBQUksT0FBTyxRQUFRLEtBQUssVUFBVSxFQUFFO0tBQ2xDLEVBQUUsR0FBRyxRQUFRLENBQUM7S0FDZCxRQUFRLEdBQUcsSUFBSSxDQUFDO0lBQ2pCO0FBQ0gsR0FBRSxJQUFJLEtBQUssRUFBRSxRQUFRLEdBQUcsUUFBUSxDQUFDLEtBQUssSUFBSSxDQUFDLFFBQVEsRUFBRSxRQUFRLEdBQUcsS0FBSyxDQUFDLGVBQWUsQ0FBQztHQUNwRixJQUFJLE9BQU8sRUFBRSxLQUFLLFVBQVUsRUFBRSxFQUFFLEdBQUcsR0FBRyxDQUFDO0dBQ3ZDLElBQUksS0FBSyxDQUFDLE1BQU0sRUFBRSxhQUFhLENBQUMsSUFBSSxFQUFFLEVBQUUsQ0FBQyxDQUFDLEtBQUssSUFBSSxLQUFLLElBQUksVUFBVSxDQUFDLElBQUksRUFBRSxLQUFLLEVBQUUsS0FBSyxFQUFFLEVBQUUsQ0FBQyxFQUFFO0FBQ2xHLEtBQUksS0FBSyxDQUFDLFNBQVMsRUFBRSxDQUFDO0FBQ3RCLEtBQUksR0FBRyxHQUFHLGFBQWEsQ0FBQyxJQUFJLEVBQUUsS0FBSyxFQUFFLEtBQUssRUFBRSxLQUFLLEVBQUUsUUFBUSxFQUFFLEVBQUUsQ0FBQyxDQUFDO0lBQzlEO0dBQ0QsT0FBTyxHQUFHLENBQUM7QUFDYixFQUFDLENBQUM7QUFDRixDQUFBLFFBQVEsQ0FBQyxTQUFTLENBQUMsSUFBSSxHQUFHLFlBQVk7QUFDdEMsR0FBRSxJQUFJLENBQUMsY0FBYyxDQUFDLE1BQU0sRUFBRSxDQUFDO0FBQy9CLEVBQUMsQ0FBQztBQUNGLENBQUEsUUFBUSxDQUFDLFNBQVMsQ0FBQyxNQUFNLEdBQUcsWUFBWTtBQUN4QyxHQUFFLElBQUksS0FBSyxHQUFHLElBQUksQ0FBQyxjQUFjLENBQUM7QUFDbEMsR0FBRSxJQUFJLEtBQUssQ0FBQyxNQUFNLEVBQUU7QUFDcEIsS0FBSSxLQUFLLENBQUMsTUFBTSxFQUFFLENBQUM7S0FDZixJQUFJLENBQUMsS0FBSyxDQUFDLE9BQU8sSUFBSSxDQUFDLEtBQUssQ0FBQyxNQUFNLElBQUksQ0FBQyxLQUFLLENBQUMsZ0JBQWdCLElBQUksS0FBSyxDQUFDLGVBQWUsRUFBRSxXQUFXLENBQUMsSUFBSSxFQUFFLEtBQUssQ0FBQyxDQUFDO0lBQ25IO0FBQ0gsRUFBQyxDQUFDO0NBQ0YsUUFBUSxDQUFDLFNBQVMsQ0FBQyxrQkFBa0IsR0FBRyxTQUFTLGtCQUFrQixDQUFDLFFBQVEsRUFBRTtBQUM5RTtBQUNBLEdBQUUsSUFBSSxPQUFPLFFBQVEsS0FBSyxRQUFRLEVBQUUsUUFBUSxHQUFHLFFBQVEsQ0FBQyxXQUFXLEVBQUUsQ0FBQztHQUNwRSxJQUFJLEVBQUUsQ0FBQyxLQUFLLEVBQUUsTUFBTSxFQUFFLE9BQU8sRUFBRSxPQUFPLEVBQUUsUUFBUSxFQUFFLFFBQVEsRUFBRSxNQUFNLEVBQUUsT0FBTyxFQUFFLFNBQVMsRUFBRSxVQUFVLEVBQUUsS0FBSyxDQUFDLENBQUMsT0FBTyxDQUFDLENBQUMsUUFBUSxHQUFHLEVBQUUsRUFBRSxXQUFXLEVBQUUsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsTUFBTSxJQUFJLG9CQUFvQixDQUFDLFFBQVEsQ0FBQyxDQUFDO0FBQ3BNLEdBQUUsSUFBSSxDQUFDLGNBQWMsQ0FBQyxlQUFlLEdBQUcsUUFBUSxDQUFDO0dBQy9DLE9BQU8sSUFBSSxDQUFDO0FBQ2QsRUFBQyxDQUFDO0NBQ0YsTUFBTSxDQUFDLGNBQWMsQ0FBQyxRQUFRLENBQUMsU0FBUyxFQUFFLGdCQUFnQixFQUFFO0FBQzVEO0FBQ0E7QUFDQTtHQUNFLFVBQVUsRUFBRSxLQUFLO0FBQ25CLEdBQUUsR0FBRyxFQUFFLFNBQVMsR0FBRyxHQUFHO0tBQ2xCLE9BQU8sSUFBSSxDQUFDLGNBQWMsSUFBSSxJQUFJLENBQUMsY0FBYyxDQUFDLFNBQVMsRUFBRSxDQUFDO0lBQy9EO0FBQ0gsRUFBQyxDQUFDLENBQUM7QUFDSCxDQUFBLFNBQVMsV0FBVyxDQUFDLEtBQUssRUFBRSxLQUFLLEVBQUUsUUFBUSxFQUFFO0FBQzdDLEdBQUUsSUFBSSxDQUFDLEtBQUssQ0FBQyxVQUFVLElBQUksS0FBSyxDQUFDLGFBQWEsS0FBSyxLQUFLLElBQUksT0FBTyxLQUFLLEtBQUssUUFBUSxFQUFFO0tBQ25GLEtBQUssR0FBRyxNQUFNLENBQUMsSUFBSSxDQUFDLEtBQUssRUFBRSxRQUFRLENBQUMsQ0FBQztJQUN0QztHQUNELE9BQU8sS0FBSyxDQUFDO0VBQ2Q7Q0FDRCxNQUFNLENBQUMsY0FBYyxDQUFDLFFBQVEsQ0FBQyxTQUFTLEVBQUUsdUJBQXVCLEVBQUU7QUFDbkU7QUFDQTtBQUNBO0dBQ0UsVUFBVSxFQUFFLEtBQUs7QUFDbkIsR0FBRSxHQUFHLEVBQUUsU0FBUyxHQUFHLEdBQUc7QUFDdEIsS0FBSSxPQUFPLElBQUksQ0FBQyxjQUFjLENBQUMsYUFBYSxDQUFDO0lBQzFDO0FBQ0gsRUFBQyxDQUFDLENBQUM7QUFDSDtBQUNBO0FBQ0E7QUFDQTtBQUNBLENBQUEsU0FBUyxhQUFhLENBQUMsTUFBTSxFQUFFLEtBQUssRUFBRSxLQUFLLEVBQUUsS0FBSyxFQUFFLFFBQVEsRUFBRSxFQUFFLEVBQUU7R0FDaEUsSUFBSSxDQUFDLEtBQUssRUFBRTtLQUNWLElBQUksUUFBUSxHQUFHLFdBQVcsQ0FBQyxLQUFLLEVBQUUsS0FBSyxFQUFFLFFBQVEsQ0FBQyxDQUFDO0FBQ3ZELEtBQUksSUFBSSxLQUFLLEtBQUssUUFBUSxFQUFFO09BQ3RCLEtBQUssR0FBRyxJQUFJLENBQUM7T0FDYixRQUFRLEdBQUcsUUFBUSxDQUFDO09BQ3BCLEtBQUssR0FBRyxRQUFRLENBQUM7TUFDbEI7SUFDRjtBQUNILEdBQUUsSUFBSSxHQUFHLEdBQUcsS0FBSyxDQUFDLFVBQVUsR0FBRyxDQUFDLEdBQUcsS0FBSyxDQUFDLE1BQU0sQ0FBQztBQUNoRCxHQUFFLEtBQUssQ0FBQyxNQUFNLElBQUksR0FBRyxDQUFDO0dBQ3BCLElBQUksR0FBRyxHQUFHLEtBQUssQ0FBQyxNQUFNLEdBQUcsS0FBSyxDQUFDLGFBQWEsQ0FBQztBQUMvQztHQUNFLElBQUksQ0FBQyxHQUFHLEVBQUUsS0FBSyxDQUFDLFNBQVMsR0FBRyxJQUFJLENBQUM7R0FDakMsSUFBSSxLQUFLLENBQUMsT0FBTyxJQUFJLEtBQUssQ0FBQyxNQUFNLEVBQUU7QUFDckMsS0FBSSxJQUFJLElBQUksR0FBRyxLQUFLLENBQUMsbUJBQW1CLENBQUM7S0FDckMsS0FBSyxDQUFDLG1CQUFtQixHQUFHO09BQzFCLEtBQUssRUFBRSxLQUFLO09BQ1osUUFBUSxFQUFFLFFBQVE7T0FDbEIsS0FBSyxFQUFFLEtBQUs7T0FDWixRQUFRLEVBQUUsRUFBRTtPQUNaLElBQUksRUFBRSxJQUFJO0FBQ2hCLE1BQUssQ0FBQztLQUNGLElBQUksSUFBSSxFQUFFO0FBQ2QsT0FBTSxJQUFJLENBQUMsSUFBSSxHQUFHLEtBQUssQ0FBQyxtQkFBbUIsQ0FBQztBQUM1QyxNQUFLLE1BQU07QUFDWCxPQUFNLEtBQUssQ0FBQyxlQUFlLEdBQUcsS0FBSyxDQUFDLG1CQUFtQixDQUFDO01BQ25EO0FBQ0wsS0FBSSxLQUFLLENBQUMsb0JBQW9CLElBQUksQ0FBQyxDQUFDO0FBQ3BDLElBQUcsTUFBTTtBQUNULEtBQUksT0FBTyxDQUFDLE1BQU0sRUFBRSxLQUFLLEVBQUUsS0FBSyxFQUFFLEdBQUcsRUFBRSxLQUFLLEVBQUUsUUFBUSxFQUFFLEVBQUUsQ0FBQyxDQUFDO0lBQ3pEO0dBQ0QsT0FBTyxHQUFHLENBQUM7RUFDWjtBQUNELENBQUEsU0FBUyxPQUFPLENBQUMsTUFBTSxFQUFFLEtBQUssRUFBRSxNQUFNLEVBQUUsR0FBRyxFQUFFLEtBQUssRUFBRSxRQUFRLEVBQUUsRUFBRSxFQUFFO0FBQ2xFLEdBQUUsS0FBSyxDQUFDLFFBQVEsR0FBRyxHQUFHLENBQUM7QUFDdkIsR0FBRSxLQUFLLENBQUMsT0FBTyxHQUFHLEVBQUUsQ0FBQztBQUNyQixHQUFFLEtBQUssQ0FBQyxPQUFPLEdBQUcsSUFBSSxDQUFDO0FBQ3ZCLEdBQUUsS0FBSyxDQUFDLElBQUksR0FBRyxJQUFJLENBQUM7R0FDbEIsSUFBSSxLQUFLLENBQUMsU0FBUyxFQUFFLEtBQUssQ0FBQyxPQUFPLENBQUMsSUFBSSxvQkFBb0IsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLEtBQUssSUFBSSxNQUFNLEVBQUUsTUFBTSxDQUFDLE9BQU8sQ0FBQyxLQUFLLEVBQUUsS0FBSyxDQUFDLE9BQU8sQ0FBQyxDQUFDLEtBQUssTUFBTSxDQUFDLE1BQU0sQ0FBQyxLQUFLLEVBQUUsUUFBUSxFQUFFLEtBQUssQ0FBQyxPQUFPLENBQUMsQ0FBQztBQUNqTCxHQUFFLEtBQUssQ0FBQyxJQUFJLEdBQUcsS0FBSyxDQUFDO0VBQ3BCO0NBQ0QsU0FBUyxZQUFZLENBQUMsTUFBTSxFQUFFLEtBQUssRUFBRSxJQUFJLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRTtBQUNuRCxHQUFFLEVBQUUsS0FBSyxDQUFDLFNBQVMsQ0FBQztHQUNsQixJQUFJLElBQUksRUFBRTtBQUNaO0FBQ0E7S0FDSSxPQUFPLENBQUMsUUFBUSxDQUFDLEVBQUUsRUFBRSxFQUFFLENBQUMsQ0FBQztBQUM3QjtBQUNBO0tBQ0ksT0FBTyxDQUFDLFFBQVEsQ0FBQyxXQUFXLEVBQUUsTUFBTSxFQUFFLEtBQUssQ0FBQyxDQUFDO0FBQ2pELEtBQUksTUFBTSxDQUFDLGNBQWMsQ0FBQyxZQUFZLEdBQUcsSUFBSSxDQUFDO0FBQzlDLEtBQUksY0FBYyxDQUFDLE1BQU0sRUFBRSxFQUFFLENBQUMsQ0FBQztBQUMvQixJQUFHLE1BQU07QUFDVDtBQUNBO0FBQ0EsS0FBSSxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUM7QUFDWCxLQUFJLE1BQU0sQ0FBQyxjQUFjLENBQUMsWUFBWSxHQUFHLElBQUksQ0FBQztBQUM5QyxLQUFJLGNBQWMsQ0FBQyxNQUFNLEVBQUUsRUFBRSxDQUFDLENBQUM7QUFDL0I7QUFDQTtBQUNBLEtBQUksV0FBVyxDQUFDLE1BQU0sRUFBRSxLQUFLLENBQUMsQ0FBQztJQUM1QjtFQUNGO0NBQ0QsU0FBUyxrQkFBa0IsQ0FBQyxLQUFLLEVBQUU7QUFDbkMsR0FBRSxLQUFLLENBQUMsT0FBTyxHQUFHLEtBQUssQ0FBQztBQUN4QixHQUFFLEtBQUssQ0FBQyxPQUFPLEdBQUcsSUFBSSxDQUFDO0FBQ3ZCLEdBQUUsS0FBSyxDQUFDLE1BQU0sSUFBSSxLQUFLLENBQUMsUUFBUSxDQUFDO0FBQ2pDLEdBQUUsS0FBSyxDQUFDLFFBQVEsR0FBRyxDQUFDLENBQUM7RUFDcEI7QUFDRCxDQUFBLFNBQVMsT0FBTyxDQUFDLE1BQU0sRUFBRSxFQUFFLEVBQUU7QUFDN0IsR0FBRSxJQUFJLEtBQUssR0FBRyxNQUFNLENBQUMsY0FBYyxDQUFDO0FBQ3BDLEdBQUUsSUFBSSxJQUFJLEdBQUcsS0FBSyxDQUFDLElBQUksQ0FBQztBQUN4QixHQUFFLElBQUksRUFBRSxHQUFHLEtBQUssQ0FBQyxPQUFPLENBQUM7R0FDdkIsSUFBSSxPQUFPLEVBQUUsS0FBSyxVQUFVLEVBQUUsTUFBTSxJQUFJLHFCQUFxQixFQUFFLENBQUM7QUFDbEUsR0FBRSxrQkFBa0IsQ0FBQyxLQUFLLENBQUMsQ0FBQztBQUM1QixHQUFFLElBQUksRUFBRSxFQUFFLFlBQVksQ0FBQyxNQUFNLEVBQUUsS0FBSyxFQUFFLElBQUksRUFBRSxFQUFFLEVBQUUsRUFBRSxDQUFDLENBQUMsS0FBSztBQUN6RDtLQUNJLElBQUksUUFBUSxHQUFHLFVBQVUsQ0FBQyxLQUFLLENBQUMsSUFBSSxNQUFNLENBQUMsU0FBUyxDQUFDO0FBQ3pELEtBQUksSUFBSSxDQUFDLFFBQVEsSUFBSSxDQUFDLEtBQUssQ0FBQyxNQUFNLElBQUksQ0FBQyxLQUFLLENBQUMsZ0JBQWdCLElBQUksS0FBSyxDQUFDLGVBQWUsRUFBRTtBQUN4RixPQUFNLFdBQVcsQ0FBQyxNQUFNLEVBQUUsS0FBSyxDQUFDLENBQUM7TUFDNUI7S0FDRCxJQUFJLElBQUksRUFBRTtBQUNkLE9BQU0sT0FBTyxDQUFDLFFBQVEsQ0FBQyxVQUFVLEVBQUUsTUFBTSxFQUFFLEtBQUssRUFBRSxRQUFRLEVBQUUsRUFBRSxDQUFDLENBQUM7QUFDaEUsTUFBSyxNQUFNO09BQ0wsVUFBVSxDQUFDLE1BQU0sRUFBRSxLQUFLLEVBQUUsUUFBUSxFQUFFLEVBQUUsQ0FBQyxDQUFDO01BQ3pDO0lBQ0Y7RUFDRjtDQUNELFNBQVMsVUFBVSxDQUFDLE1BQU0sRUFBRSxLQUFLLEVBQUUsUUFBUSxFQUFFLEVBQUUsRUFBRTtHQUMvQyxJQUFJLENBQUMsUUFBUSxFQUFFLFlBQVksQ0FBQyxNQUFNLEVBQUUsS0FBSyxDQUFDLENBQUM7QUFDN0MsR0FBRSxLQUFLLENBQUMsU0FBUyxFQUFFLENBQUM7R0FDbEIsRUFBRSxFQUFFLENBQUM7QUFDUCxHQUFFLFdBQVcsQ0FBQyxNQUFNLEVBQUUsS0FBSyxDQUFDLENBQUM7RUFDNUI7QUFDRDtBQUNBO0FBQ0E7QUFDQTtBQUNBLENBQUEsU0FBUyxZQUFZLENBQUMsTUFBTSxFQUFFLEtBQUssRUFBRTtHQUNuQyxJQUFJLEtBQUssQ0FBQyxNQUFNLEtBQUssQ0FBQyxJQUFJLEtBQUssQ0FBQyxTQUFTLEVBQUU7QUFDN0MsS0FBSSxLQUFLLENBQUMsU0FBUyxHQUFHLEtBQUssQ0FBQztBQUM1QixLQUFJLE1BQU0sQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUM7SUFDdEI7RUFDRjtBQUNEO0FBQ0E7QUFDQSxDQUFBLFNBQVMsV0FBVyxDQUFDLE1BQU0sRUFBRSxLQUFLLEVBQUU7QUFDcEMsR0FBRSxLQUFLLENBQUMsZ0JBQWdCLEdBQUcsSUFBSSxDQUFDO0FBQ2hDLEdBQUUsSUFBSSxLQUFLLEdBQUcsS0FBSyxDQUFDLGVBQWUsQ0FBQztHQUNsQyxJQUFJLE1BQU0sQ0FBQyxPQUFPLElBQUksS0FBSyxJQUFJLEtBQUssQ0FBQyxJQUFJLEVBQUU7QUFDN0M7QUFDQSxLQUFJLElBQUksQ0FBQyxHQUFHLEtBQUssQ0FBQyxvQkFBb0IsQ0FBQztLQUNuQyxJQUFJLE1BQU0sR0FBRyxJQUFJLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUM5QixLQUFJLElBQUksTUFBTSxHQUFHLEtBQUssQ0FBQyxrQkFBa0IsQ0FBQztBQUMxQyxLQUFJLE1BQU0sQ0FBQyxLQUFLLEdBQUcsS0FBSyxDQUFDO0FBQ3pCLEtBQUksSUFBSSxLQUFLLEdBQUcsQ0FBQyxDQUFDO0FBQ2xCLEtBQUksSUFBSSxVQUFVLEdBQUcsSUFBSSxDQUFDO0tBQ3RCLE9BQU8sS0FBSyxFQUFFO0FBQ2xCLE9BQU0sTUFBTSxDQUFDLEtBQUssQ0FBQyxHQUFHLEtBQUssQ0FBQztPQUN0QixJQUFJLENBQUMsS0FBSyxDQUFDLEtBQUssRUFBRSxVQUFVLEdBQUcsS0FBSyxDQUFDO0FBQzNDLE9BQU0sS0FBSyxHQUFHLEtBQUssQ0FBQyxJQUFJLENBQUM7T0FDbkIsS0FBSyxJQUFJLENBQUMsQ0FBQztNQUNaO0FBQ0wsS0FBSSxNQUFNLENBQUMsVUFBVSxHQUFHLFVBQVUsQ0FBQztLQUMvQixPQUFPLENBQUMsTUFBTSxFQUFFLEtBQUssRUFBRSxJQUFJLEVBQUUsS0FBSyxDQUFDLE1BQU0sRUFBRSxNQUFNLEVBQUUsRUFBRSxFQUFFLE1BQU0sQ0FBQyxNQUFNLENBQUMsQ0FBQztBQUMxRTtBQUNBO0FBQ0E7QUFDQSxLQUFJLEtBQUssQ0FBQyxTQUFTLEVBQUUsQ0FBQztBQUN0QixLQUFJLEtBQUssQ0FBQyxtQkFBbUIsR0FBRyxJQUFJLENBQUM7QUFDckMsS0FBSSxJQUFJLE1BQU0sQ0FBQyxJQUFJLEVBQUU7QUFDckIsT0FBTSxLQUFLLENBQUMsa0JBQWtCLEdBQUcsTUFBTSxDQUFDLElBQUksQ0FBQztBQUM3QyxPQUFNLE1BQU0sQ0FBQyxJQUFJLEdBQUcsSUFBSSxDQUFDO0FBQ3pCLE1BQUssTUFBTTtPQUNMLEtBQUssQ0FBQyxrQkFBa0IsR0FBRyxJQUFJLGFBQWEsQ0FBQyxLQUFLLENBQUMsQ0FBQztNQUNyRDtBQUNMLEtBQUksS0FBSyxDQUFDLG9CQUFvQixHQUFHLENBQUMsQ0FBQztBQUNuQyxJQUFHLE1BQU07QUFDVDtLQUNJLE9BQU8sS0FBSyxFQUFFO0FBQ2xCLE9BQU0sSUFBSSxLQUFLLEdBQUcsS0FBSyxDQUFDLEtBQUssQ0FBQztBQUM5QixPQUFNLElBQUksUUFBUSxHQUFHLEtBQUssQ0FBQyxRQUFRLENBQUM7QUFDcEMsT0FBTSxJQUFJLEVBQUUsR0FBRyxLQUFLLENBQUMsUUFBUSxDQUFDO0FBQzlCLE9BQU0sSUFBSSxHQUFHLEdBQUcsS0FBSyxDQUFDLFVBQVUsR0FBRyxDQUFDLEdBQUcsS0FBSyxDQUFDLE1BQU0sQ0FBQztBQUNwRCxPQUFNLE9BQU8sQ0FBQyxNQUFNLEVBQUUsS0FBSyxFQUFFLEtBQUssRUFBRSxHQUFHLEVBQUUsS0FBSyxFQUFFLFFBQVEsRUFBRSxFQUFFLENBQUMsQ0FBQztBQUM5RCxPQUFNLEtBQUssR0FBRyxLQUFLLENBQUMsSUFBSSxDQUFDO0FBQ3pCLE9BQU0sS0FBSyxDQUFDLG9CQUFvQixFQUFFLENBQUM7QUFDbkM7QUFDQTtBQUNBO0FBQ0E7QUFDQSxPQUFNLElBQUksS0FBSyxDQUFDLE9BQU8sRUFBRTtBQUN6QixTQUFRLE1BQU07UUFDUDtNQUNGO0tBQ0QsSUFBSSxLQUFLLEtBQUssSUFBSSxFQUFFLEtBQUssQ0FBQyxtQkFBbUIsR0FBRyxJQUFJLENBQUM7SUFDdEQ7QUFDSCxHQUFFLEtBQUssQ0FBQyxlQUFlLEdBQUcsS0FBSyxDQUFDO0FBQ2hDLEdBQUUsS0FBSyxDQUFDLGdCQUFnQixHQUFHLEtBQUssQ0FBQztFQUNoQztDQUNELFFBQVEsQ0FBQyxTQUFTLENBQUMsTUFBTSxHQUFHLFVBQVUsS0FBSyxFQUFFLFFBQVEsRUFBRSxFQUFFLEVBQUU7R0FDekQsRUFBRSxDQUFDLElBQUksMEJBQTBCLENBQUMsVUFBVSxDQUFDLENBQUMsQ0FBQztBQUNqRCxFQUFDLENBQUM7QUFDRixDQUFBLFFBQVEsQ0FBQyxTQUFTLENBQUMsT0FBTyxHQUFHLElBQUksQ0FBQztDQUNsQyxRQUFRLENBQUMsU0FBUyxDQUFDLEdBQUcsR0FBRyxVQUFVLEtBQUssRUFBRSxRQUFRLEVBQUUsRUFBRSxFQUFFO0FBQ3hELEdBQUUsSUFBSSxLQUFLLEdBQUcsSUFBSSxDQUFDLGNBQWMsQ0FBQztBQUNsQyxHQUFFLElBQUksT0FBTyxLQUFLLEtBQUssVUFBVSxFQUFFO0tBQy9CLEVBQUUsR0FBRyxLQUFLLENBQUM7S0FDWCxLQUFLLEdBQUcsSUFBSSxDQUFDO0tBQ2IsUUFBUSxHQUFHLElBQUksQ0FBQztBQUNwQixJQUFHLE1BQU0sSUFBSSxPQUFPLFFBQVEsS0FBSyxVQUFVLEVBQUU7S0FDekMsRUFBRSxHQUFHLFFBQVEsQ0FBQztLQUNkLFFBQVEsR0FBRyxJQUFJLENBQUM7SUFDakI7QUFDSCxHQUFFLElBQUksS0FBSyxLQUFLLElBQUksSUFBSSxLQUFLLEtBQUssU0FBUyxFQUFFLElBQUksQ0FBQyxLQUFLLENBQUMsS0FBSyxFQUFFLFFBQVEsQ0FBQyxDQUFDO0FBQ3pFO0FBQ0E7QUFDQSxHQUFFLElBQUksS0FBSyxDQUFDLE1BQU0sRUFBRTtBQUNwQixLQUFJLEtBQUssQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDO0FBQ3JCLEtBQUksSUFBSSxDQUFDLE1BQU0sRUFBRSxDQUFDO0lBQ2Y7QUFDSDtBQUNBO0FBQ0EsR0FBRSxJQUFJLENBQUMsS0FBSyxDQUFDLE1BQU0sRUFBRSxXQUFXLENBQUMsSUFBSSxFQUFFLEtBQUssRUFBRSxFQUFFLENBQUMsQ0FBQztHQUNoRCxPQUFPLElBQUksQ0FBQztBQUNkLEVBQUMsQ0FBQztDQUNGLE1BQU0sQ0FBQyxjQUFjLENBQUMsUUFBUSxDQUFDLFNBQVMsRUFBRSxnQkFBZ0IsRUFBRTtBQUM1RDtBQUNBO0FBQ0E7R0FDRSxVQUFVLEVBQUUsS0FBSztBQUNuQixHQUFFLEdBQUcsRUFBRSxTQUFTLEdBQUcsR0FBRztBQUN0QixLQUFJLE9BQU8sSUFBSSxDQUFDLGNBQWMsQ0FBQyxNQUFNLENBQUM7SUFDbkM7QUFDSCxFQUFDLENBQUMsQ0FBQztDQUNILFNBQVMsVUFBVSxDQUFDLEtBQUssRUFBRTtHQUN6QixPQUFPLEtBQUssQ0FBQyxNQUFNLElBQUksS0FBSyxDQUFDLE1BQU0sS0FBSyxDQUFDLElBQUksS0FBSyxDQUFDLGVBQWUsS0FBSyxJQUFJLElBQUksQ0FBQyxLQUFLLENBQUMsUUFBUSxJQUFJLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQztFQUNsSDtBQUNELENBQUEsU0FBUyxTQUFTLENBQUMsTUFBTSxFQUFFLEtBQUssRUFBRTtBQUNsQyxHQUFFLE1BQU0sQ0FBQyxNQUFNLENBQUMsVUFBVSxHQUFHLEVBQUU7QUFDL0IsS0FBSSxLQUFLLENBQUMsU0FBUyxFQUFFLENBQUM7S0FDbEIsSUFBSSxHQUFHLEVBQUU7QUFDYixPQUFNLGNBQWMsQ0FBQyxNQUFNLEVBQUUsR0FBRyxDQUFDLENBQUM7TUFDN0I7QUFDTCxLQUFJLEtBQUssQ0FBQyxXQUFXLEdBQUcsSUFBSSxDQUFDO0FBQzdCLEtBQUksTUFBTSxDQUFDLElBQUksQ0FBQyxXQUFXLENBQUMsQ0FBQztBQUM3QixLQUFJLFdBQVcsQ0FBQyxNQUFNLEVBQUUsS0FBSyxDQUFDLENBQUM7QUFDL0IsSUFBRyxDQUFDLENBQUM7RUFDSjtBQUNELENBQUEsU0FBUyxTQUFTLENBQUMsTUFBTSxFQUFFLEtBQUssRUFBRTtHQUNoQyxJQUFJLENBQUMsS0FBSyxDQUFDLFdBQVcsSUFBSSxDQUFDLEtBQUssQ0FBQyxXQUFXLEVBQUU7QUFDaEQsS0FBSSxJQUFJLE9BQU8sTUFBTSxDQUFDLE1BQU0sS0FBSyxVQUFVLElBQUksQ0FBQyxLQUFLLENBQUMsU0FBUyxFQUFFO0FBQ2pFLE9BQU0sS0FBSyxDQUFDLFNBQVMsRUFBRSxDQUFDO0FBQ3hCLE9BQU0sS0FBSyxDQUFDLFdBQVcsR0FBRyxJQUFJLENBQUM7T0FDekIsT0FBTyxDQUFDLFFBQVEsQ0FBQyxTQUFTLEVBQUUsTUFBTSxFQUFFLEtBQUssQ0FBQyxDQUFDO0FBQ2pELE1BQUssTUFBTTtBQUNYLE9BQU0sS0FBSyxDQUFDLFdBQVcsR0FBRyxJQUFJLENBQUM7QUFDL0IsT0FBTSxNQUFNLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxDQUFDO01BQzFCO0lBQ0Y7RUFDRjtBQUNELENBQUEsU0FBUyxXQUFXLENBQUMsTUFBTSxFQUFFLEtBQUssRUFBRTtBQUNwQyxHQUFFLElBQUksSUFBSSxHQUFHLFVBQVUsQ0FBQyxLQUFLLENBQUMsQ0FBQztHQUM3QixJQUFJLElBQUksRUFBRTtBQUNaLEtBQUksU0FBUyxDQUFDLE1BQU0sRUFBRSxLQUFLLENBQUMsQ0FBQztBQUM3QixLQUFJLElBQUksS0FBSyxDQUFDLFNBQVMsS0FBSyxDQUFDLEVBQUU7QUFDL0IsT0FBTSxLQUFLLENBQUMsUUFBUSxHQUFHLElBQUksQ0FBQztBQUM1QixPQUFNLE1BQU0sQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUM7QUFDNUIsT0FBTSxJQUFJLEtBQUssQ0FBQyxXQUFXLEVBQUU7QUFDN0I7QUFDQTtBQUNBLFNBQVEsSUFBSSxNQUFNLEdBQUcsTUFBTSxDQUFDLGNBQWMsQ0FBQztTQUNuQyxJQUFJLENBQUMsTUFBTSxJQUFJLE1BQU0sQ0FBQyxXQUFXLElBQUksTUFBTSxDQUFDLFVBQVUsRUFBRTtBQUNoRSxXQUFVLE1BQU0sQ0FBQyxPQUFPLEVBQUUsQ0FBQztVQUNsQjtRQUNGO01BQ0Y7SUFDRjtHQUNELE9BQU8sSUFBSSxDQUFDO0VBQ2I7QUFDRCxDQUFBLFNBQVMsV0FBVyxDQUFDLE1BQU0sRUFBRSxLQUFLLEVBQUUsRUFBRSxFQUFFO0FBQ3hDLEdBQUUsS0FBSyxDQUFDLE1BQU0sR0FBRyxJQUFJLENBQUM7QUFDdEIsR0FBRSxXQUFXLENBQUMsTUFBTSxFQUFFLEtBQUssQ0FBQyxDQUFDO0dBQzNCLElBQUksRUFBRSxFQUFFO0tBQ04sSUFBSSxLQUFLLENBQUMsUUFBUSxFQUFFLE9BQU8sQ0FBQyxRQUFRLENBQUMsRUFBRSxDQUFDLENBQUMsS0FBSyxNQUFNLENBQUMsSUFBSSxDQUFDLFFBQVEsRUFBRSxFQUFFLENBQUMsQ0FBQztJQUN6RTtBQUNILEdBQUUsS0FBSyxDQUFDLEtBQUssR0FBRyxJQUFJLENBQUM7QUFDckIsR0FBRSxNQUFNLENBQUMsUUFBUSxHQUFHLEtBQUssQ0FBQztFQUN6QjtBQUNELENBQUEsU0FBUyxjQUFjLENBQUMsT0FBTyxFQUFFLEtBQUssRUFBRSxHQUFHLEVBQUU7QUFDN0MsR0FBRSxJQUFJLEtBQUssR0FBRyxPQUFPLENBQUMsS0FBSyxDQUFDO0FBQzVCLEdBQUUsT0FBTyxDQUFDLEtBQUssR0FBRyxJQUFJLENBQUM7R0FDckIsT0FBTyxLQUFLLEVBQUU7QUFDaEIsS0FBSSxJQUFJLEVBQUUsR0FBRyxLQUFLLENBQUMsUUFBUSxDQUFDO0FBQzVCLEtBQUksS0FBSyxDQUFDLFNBQVMsRUFBRSxDQUFDO0FBQ3RCLEtBQUksRUFBRSxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ1osS0FBSSxLQUFLLEdBQUcsS0FBSyxDQUFDLElBQUksQ0FBQztJQUNwQjtBQUNIO0FBQ0E7QUFDQSxHQUFFLEtBQUssQ0FBQyxrQkFBa0IsQ0FBQyxJQUFJLEdBQUcsT0FBTyxDQUFDO0VBQ3pDO0NBQ0QsTUFBTSxDQUFDLGNBQWMsQ0FBQyxRQUFRLENBQUMsU0FBUyxFQUFFLFdBQVcsRUFBRTtBQUN2RDtBQUNBO0FBQ0E7R0FDRSxVQUFVLEVBQUUsS0FBSztBQUNuQixHQUFFLEdBQUcsRUFBRSxTQUFTLEdBQUcsR0FBRztBQUN0QixLQUFJLElBQUksSUFBSSxDQUFDLGNBQWMsS0FBSyxTQUFTLEVBQUU7T0FDckMsT0FBTyxLQUFLLENBQUM7TUFDZDtBQUNMLEtBQUksT0FBTyxJQUFJLENBQUMsY0FBYyxDQUFDLFNBQVMsQ0FBQztJQUN0QztBQUNILEdBQUUsR0FBRyxFQUFFLFNBQVMsR0FBRyxDQUFDLEtBQUssRUFBRTtBQUMzQjtBQUNBO0FBQ0EsS0FBSSxJQUFJLENBQUMsSUFBSSxDQUFDLGNBQWMsRUFBRTtBQUM5QixPQUFNLE9BQU87TUFDUjtBQUNMO0FBQ0E7QUFDQTtBQUNBLEtBQUksSUFBSSxDQUFDLGNBQWMsQ0FBQyxTQUFTLEdBQUcsS0FBSyxDQUFDO0lBQ3ZDO0FBQ0gsRUFBQyxDQUFDLENBQUM7Q0FDSCxRQUFRLENBQUMsU0FBUyxDQUFDLE9BQU8sR0FBRyxXQUFXLENBQUMsT0FBTyxDQUFDO0NBQ2pELFFBQVEsQ0FBQyxTQUFTLENBQUMsVUFBVSxHQUFHLFdBQVcsQ0FBQyxTQUFTLENBQUM7Q0FDdEQsUUFBUSxDQUFDLFNBQVMsQ0FBQyxRQUFRLEdBQUcsVUFBVSxHQUFHLEVBQUUsRUFBRSxFQUFFO0FBQ2pELEdBQUUsRUFBRSxDQUFDLEdBQUcsQ0FBQyxDQUFDO0VBQ1QsQ0FBQTs7Ozs7Ozs7OztBQ3JtQkQ7QUFDQTtDQUNBLElBQUksVUFBVSxHQUFHLE1BQU0sQ0FBQyxJQUFJLElBQUksVUFBVSxHQUFHLEVBQUU7QUFDL0MsR0FBRSxJQUFJLElBQUksR0FBRyxFQUFFLENBQUM7QUFDaEIsR0FBRSxLQUFLLElBQUksR0FBRyxJQUFJLEdBQUcsRUFBRSxJQUFJLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDO0dBQ3BDLE9BQU8sSUFBSSxDQUFDO0FBQ2QsRUFBQyxDQUFDO0FBQ0Y7QUFDQTtBQUNBLENBQWMsY0FBQSxHQUFHLE1BQU0sQ0FBQztDQUN4QixJQUFJLFFBQVEsR0FBR2pELHVCQUFBLEVBQTZCLENBQUM7Q0FDN0MsSUFBSSxRQUFRLEdBQUdKLHVCQUFBLEVBQTZCLENBQUM7QUFDN0MsQ0FBQUMsZUFBQSxFQUFtQixDQUFDLE1BQU0sRUFBRSxRQUFRLENBQUMsQ0FBQztBQUN0QyxDQUFBO0FBQ0E7R0FDRSxJQUFJLElBQUksR0FBRyxVQUFVLENBQUMsUUFBUSxDQUFDLFNBQVMsQ0FBQyxDQUFDO0FBQzVDLEdBQUUsS0FBSyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLElBQUksQ0FBQyxNQUFNLEVBQUUsQ0FBQyxFQUFFLEVBQUU7QUFDeEMsS0FBSSxJQUFJLE1BQU0sR0FBRyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUM7S0FDckIsSUFBSSxDQUFDLE1BQU0sQ0FBQyxTQUFTLENBQUMsTUFBTSxDQUFDLEVBQUUsTUFBTSxDQUFDLFNBQVMsQ0FBQyxNQUFNLENBQUMsR0FBRyxRQUFRLENBQUMsU0FBUyxDQUFDLE1BQU0sQ0FBQyxDQUFDO0lBQ3RGO0VBQ0Y7Q0FDRCxTQUFTLE1BQU0sQ0FBQyxPQUFPLEVBQUU7QUFDekIsR0FBRSxJQUFJLEVBQUUsSUFBSSxZQUFZLE1BQU0sQ0FBQyxFQUFFLE9BQU8sSUFBSSxNQUFNLENBQUMsT0FBTyxDQUFDLENBQUM7R0FDMUQsUUFBUSxDQUFDLElBQUksQ0FBQyxJQUFJLEVBQUUsT0FBTyxDQUFDLENBQUM7R0FDN0IsUUFBUSxDQUFDLElBQUksQ0FBQyxJQUFJLEVBQUUsT0FBTyxDQUFDLENBQUM7QUFDL0IsR0FBRSxJQUFJLENBQUMsYUFBYSxHQUFHLElBQUksQ0FBQztHQUMxQixJQUFJLE9BQU8sRUFBRTtBQUNmLEtBQUksSUFBSSxPQUFPLENBQUMsUUFBUSxLQUFLLEtBQUssRUFBRSxJQUFJLENBQUMsUUFBUSxHQUFHLEtBQUssQ0FBQztBQUMxRCxLQUFJLElBQUksT0FBTyxDQUFDLFFBQVEsS0FBSyxLQUFLLEVBQUUsSUFBSSxDQUFDLFFBQVEsR0FBRyxLQUFLLENBQUM7QUFDMUQsS0FBSSxJQUFJLE9BQU8sQ0FBQyxhQUFhLEtBQUssS0FBSyxFQUFFO0FBQ3pDLE9BQU0sSUFBSSxDQUFDLGFBQWEsR0FBRyxLQUFLLENBQUM7T0FDM0IsSUFBSSxDQUFDLElBQUksQ0FBQyxLQUFLLEVBQUUsS0FBSyxDQUFDLENBQUM7TUFDekI7SUFDRjtFQUNGO0NBQ0QsTUFBTSxDQUFDLGNBQWMsQ0FBQyxNQUFNLENBQUMsU0FBUyxFQUFFLHVCQUF1QixFQUFFO0FBQ2pFO0FBQ0E7QUFDQTtHQUNFLFVBQVUsRUFBRSxLQUFLO0FBQ25CLEdBQUUsR0FBRyxFQUFFLFNBQVMsR0FBRyxHQUFHO0FBQ3RCLEtBQUksT0FBTyxJQUFJLENBQUMsY0FBYyxDQUFDLGFBQWEsQ0FBQztJQUMxQztBQUNILEVBQUMsQ0FBQyxDQUFDO0NBQ0gsTUFBTSxDQUFDLGNBQWMsQ0FBQyxNQUFNLENBQUMsU0FBUyxFQUFFLGdCQUFnQixFQUFFO0FBQzFEO0FBQ0E7QUFDQTtHQUNFLFVBQVUsRUFBRSxLQUFLO0FBQ25CLEdBQUUsR0FBRyxFQUFFLFNBQVMsR0FBRyxHQUFHO0tBQ2xCLE9BQU8sSUFBSSxDQUFDLGNBQWMsSUFBSSxJQUFJLENBQUMsY0FBYyxDQUFDLFNBQVMsRUFBRSxDQUFDO0lBQy9EO0FBQ0gsRUFBQyxDQUFDLENBQUM7Q0FDSCxNQUFNLENBQUMsY0FBYyxDQUFDLE1BQU0sQ0FBQyxTQUFTLEVBQUUsZ0JBQWdCLEVBQUU7QUFDMUQ7QUFDQTtBQUNBO0dBQ0UsVUFBVSxFQUFFLEtBQUs7QUFDbkIsR0FBRSxHQUFHLEVBQUUsU0FBUyxHQUFHLEdBQUc7QUFDdEIsS0FBSSxPQUFPLElBQUksQ0FBQyxjQUFjLENBQUMsTUFBTSxDQUFDO0lBQ25DO0FBQ0gsRUFBQyxDQUFDLENBQUM7QUFDSDtBQUNBO0FBQ0EsQ0FBQSxTQUFTLEtBQUssR0FBRztBQUNqQjtBQUNBLEdBQUUsSUFBSSxJQUFJLENBQUMsY0FBYyxDQUFDLEtBQUssRUFBRSxPQUFPO0FBQ3hDO0FBQ0E7QUFDQTtHQUNFLE9BQU8sQ0FBQyxRQUFRLENBQUMsT0FBTyxFQUFFLElBQUksQ0FBQyxDQUFDO0VBQ2pDO0NBQ0QsU0FBUyxPQUFPLENBQUMsSUFBSSxFQUFFO0FBQ3ZCLEdBQUUsSUFBSSxDQUFDLEdBQUcsRUFBRSxDQUFDO0VBQ1o7Q0FDRCxNQUFNLENBQUMsY0FBYyxDQUFDLE1BQU0sQ0FBQyxTQUFTLEVBQUUsV0FBVyxFQUFFO0FBQ3JEO0FBQ0E7QUFDQTtHQUNFLFVBQVUsRUFBRSxLQUFLO0FBQ25CLEdBQUUsR0FBRyxFQUFFLFNBQVMsR0FBRyxHQUFHO0FBQ3RCLEtBQUksSUFBSSxJQUFJLENBQUMsY0FBYyxLQUFLLFNBQVMsSUFBSSxJQUFJLENBQUMsY0FBYyxLQUFLLFNBQVMsRUFBRTtPQUMxRSxPQUFPLEtBQUssQ0FBQztNQUNkO0FBQ0wsS0FBSSxPQUFPLElBQUksQ0FBQyxjQUFjLENBQUMsU0FBUyxJQUFJLElBQUksQ0FBQyxjQUFjLENBQUMsU0FBUyxDQUFDO0lBQ3ZFO0FBQ0gsR0FBRSxHQUFHLEVBQUUsU0FBUyxHQUFHLENBQUMsS0FBSyxFQUFFO0FBQzNCO0FBQ0E7QUFDQSxLQUFJLElBQUksSUFBSSxDQUFDLGNBQWMsS0FBSyxTQUFTLElBQUksSUFBSSxDQUFDLGNBQWMsS0FBSyxTQUFTLEVBQUU7QUFDaEYsT0FBTSxPQUFPO01BQ1I7QUFDTDtBQUNBO0FBQ0E7QUFDQSxLQUFJLElBQUksQ0FBQyxjQUFjLENBQUMsU0FBUyxHQUFHLEtBQUssQ0FBQztBQUMxQyxLQUFJLElBQUksQ0FBQyxjQUFjLENBQUMsU0FBUyxHQUFHLEtBQUssQ0FBQztJQUN2QztBQUNILEVBQUMsQ0FBQyxDQUFBOzs7Ozs7Ozs7Ozs7Ozs7O0FDNUhGO0VBQ0EsSUFBSSxNQUFNLEdBQUdHLGFBQWlCO0FBQzlCLEVBQUEsSUFBSSxNQUFNLEdBQUcsTUFBTSxDQUFDLE9BQU07QUFDMUI7QUFDQTtBQUNBLEVBQUEsU0FBUyxTQUFTLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRTtBQUM5QixJQUFFLEtBQUssSUFBSSxHQUFHLElBQUksR0FBRyxFQUFFO01BQ25CLEdBQUcsQ0FBQyxHQUFHLENBQUMsR0FBRyxHQUFHLENBQUMsR0FBRyxFQUFDO0tBQ3BCO0dBQ0Y7QUFDRCxFQUFBLElBQUksTUFBTSxDQUFDLElBQUksSUFBSSxNQUFNLENBQUMsS0FBSyxJQUFJLE1BQU0sQ0FBQyxXQUFXLElBQUksTUFBTSxDQUFDLGVBQWUsRUFBRTtBQUNqRixJQUFFLGlCQUFpQixPQUFNO0FBQ3pCLEdBQUMsTUFBTTtBQUNQO0FBQ0EsSUFBRSxTQUFTLENBQUMsTUFBTSxFQUFFLE9BQU8sRUFBQztBQUM1QixJQUFFLGlCQUFpQixXQUFVO0dBQzVCO0FBQ0Q7QUFDQSxFQUFBLFNBQVMsVUFBVSxFQUFFLEdBQUcsRUFBRSxnQkFBZ0IsRUFBRSxNQUFNLEVBQUU7SUFDbEQsT0FBTyxNQUFNLENBQUMsR0FBRyxFQUFFLGdCQUFnQixFQUFFLE1BQU0sQ0FBQztHQUM3QztBQUNEO0VBQ0EsVUFBVSxDQUFDLFNBQVMsR0FBRyxNQUFNLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxTQUFTLEVBQUM7QUFDdEQ7QUFDQTtBQUNBLEVBQUEsU0FBUyxDQUFDLE1BQU0sRUFBRSxVQUFVLEVBQUM7QUFDN0I7RUFDQSxVQUFVLENBQUMsSUFBSSxHQUFHLFVBQVUsR0FBRyxFQUFFLGdCQUFnQixFQUFFLE1BQU0sRUFBRTtBQUMzRCxJQUFFLElBQUksT0FBTyxHQUFHLEtBQUssUUFBUSxFQUFFO0FBQy9CLE1BQUksTUFBTSxJQUFJLFNBQVMsQ0FBQywrQkFBK0IsQ0FBQztLQUNyRDtJQUNELE9BQU8sTUFBTSxDQUFDLEdBQUcsRUFBRSxnQkFBZ0IsRUFBRSxNQUFNLENBQUM7SUFDN0M7QUFDRDtFQUNBLFVBQVUsQ0FBQyxLQUFLLEdBQUcsVUFBVSxJQUFJLEVBQUUsSUFBSSxFQUFFLFFBQVEsRUFBRTtBQUNuRCxJQUFFLElBQUksT0FBTyxJQUFJLEtBQUssUUFBUSxFQUFFO0FBQ2hDLE1BQUksTUFBTSxJQUFJLFNBQVMsQ0FBQywyQkFBMkIsQ0FBQztLQUNqRDtBQUNILElBQUUsSUFBSSxHQUFHLEdBQUcsTUFBTSxDQUFDLElBQUksRUFBQztBQUN4QixJQUFFLElBQUksSUFBSSxLQUFLLFNBQVMsRUFBRTtBQUMxQixNQUFJLElBQUksT0FBTyxRQUFRLEtBQUssUUFBUSxFQUFFO0FBQ3RDLFFBQU0sR0FBRyxDQUFDLElBQUksQ0FBQyxJQUFJLEVBQUUsUUFBUSxFQUFDO0FBQzlCLE9BQUssTUFBTTtBQUNYLFFBQU0sR0FBRyxDQUFDLElBQUksQ0FBQyxJQUFJLEVBQUM7T0FDZjtBQUNMLEtBQUcsTUFBTTtBQUNULE1BQUksR0FBRyxDQUFDLElBQUksQ0FBQyxDQUFDLEVBQUM7S0FDWjtBQUNILElBQUUsT0FBTyxHQUFHO0lBQ1g7QUFDRDtBQUNBLEVBQUEsVUFBVSxDQUFDLFdBQVcsR0FBRyxVQUFVLElBQUksRUFBRTtBQUN6QyxJQUFFLElBQUksT0FBTyxJQUFJLEtBQUssUUFBUSxFQUFFO0FBQ2hDLE1BQUksTUFBTSxJQUFJLFNBQVMsQ0FBQywyQkFBMkIsQ0FBQztLQUNqRDtBQUNILElBQUUsT0FBTyxNQUFNLENBQUMsSUFBSSxDQUFDO0lBQ3BCO0FBQ0Q7QUFDQSxFQUFBLFVBQVUsQ0FBQyxlQUFlLEdBQUcsVUFBVSxJQUFJLEVBQUU7QUFDN0MsSUFBRSxJQUFJLE9BQU8sSUFBSSxLQUFLLFFBQVEsRUFBRTtBQUNoQyxNQUFJLE1BQU0sSUFBSSxTQUFTLENBQUMsMkJBQTJCLENBQUM7S0FDakQ7QUFDSCxJQUFFLE9BQU8sTUFBTSxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUM7QUFDaEMsSUFBQTs7Ozs7Ozs7OztBQzFDQTtBQUNBO0FBQ0E7QUFDQSxDQUFBLElBQUksTUFBTSxHQUFHQSxpQkFBc0IsRUFBQSxDQUFDLE1BQU0sQ0FBQztBQUMzQztBQUNBO0NBQ0EsSUFBSSxVQUFVLEdBQUcsTUFBTSxDQUFDLFVBQVUsSUFBSSxVQUFVLFFBQVEsRUFBRTtBQUMxRCxHQUFFLFFBQVEsR0FBRyxFQUFFLEdBQUcsUUFBUSxDQUFDO0FBQzNCLEdBQUUsUUFBUSxRQUFRLElBQUksUUFBUSxDQUFDLFdBQVcsRUFBRTtBQUM1QyxLQUFJLEtBQUssS0FBSyxDQUFDLEtBQUssTUFBTSxDQUFDLEtBQUssT0FBTyxDQUFDLEtBQUssT0FBTyxDQUFDLEtBQUssUUFBUSxDQUFDLEtBQUssUUFBUSxDQUFDLEtBQUssTUFBTSxDQUFDLEtBQUssT0FBTyxDQUFDLEtBQUssU0FBUyxDQUFDLEtBQUssVUFBVSxDQUFDLEtBQUssS0FBSztPQUM3SSxPQUFPLElBQUksQ0FBQztLQUNkO09BQ0UsT0FBTyxLQUFLLENBQUM7SUFDaEI7QUFDSCxFQUFDLENBQUM7QUFDRjtDQUNBLFNBQVMsa0JBQWtCLENBQUMsR0FBRyxFQUFFO0FBQ2pDLEdBQUUsSUFBSSxDQUFDLEdBQUcsRUFBRSxPQUFPLE1BQU0sQ0FBQztHQUN4QixJQUFJLE9BQU8sQ0FBQztHQUNaLE9BQU8sSUFBSSxFQUFFO0FBQ2YsS0FBSSxRQUFRLEdBQUc7T0FDVCxLQUFLLE1BQU0sQ0FBQztBQUNsQixPQUFNLEtBQUssT0FBTztTQUNWLE9BQU8sTUFBTSxDQUFDO09BQ2hCLEtBQUssTUFBTSxDQUFDO09BQ1osS0FBSyxPQUFPLENBQUM7T0FDYixLQUFLLFNBQVMsQ0FBQztBQUNyQixPQUFNLEtBQUssVUFBVTtTQUNiLE9BQU8sU0FBUyxDQUFDO09BQ25CLEtBQUssUUFBUSxDQUFDO0FBQ3BCLE9BQU0sS0FBSyxRQUFRO1NBQ1gsT0FBTyxRQUFRLENBQUM7T0FDbEIsS0FBSyxRQUFRLENBQUM7T0FDZCxLQUFLLE9BQU8sQ0FBQztBQUNuQixPQUFNLEtBQUssS0FBSztTQUNSLE9BQU8sR0FBRyxDQUFDO09BQ2I7U0FDRSxJQUFJLE9BQU8sRUFBRSxPQUFPO1NBQ3BCLEdBQUcsR0FBRyxDQUFDLEVBQUUsR0FBRyxHQUFHLEVBQUUsV0FBVyxFQUFFLENBQUM7U0FDL0IsT0FBTyxHQUFHLElBQUksQ0FBQztNQUNsQjtJQUNGO0FBQ0gsRUFDQTtBQUNBO0FBQ0E7Q0FDQSxTQUFTLGlCQUFpQixDQUFDLEdBQUcsRUFBRTtBQUNoQyxHQUFFLElBQUksSUFBSSxHQUFHLGtCQUFrQixDQUFDLEdBQUcsQ0FBQyxDQUFDO0dBQ25DLElBQUksT0FBTyxJQUFJLEtBQUssUUFBUSxLQUFLLE1BQU0sQ0FBQyxVQUFVLEtBQUssVUFBVSxJQUFJLENBQUMsVUFBVSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEVBQUUsTUFBTSxJQUFJLEtBQUssQ0FBQyxvQkFBb0IsR0FBRyxHQUFHLENBQUMsQ0FBQztBQUN0SSxHQUFFLE9BQU8sSUFBSSxJQUFJLEdBQUcsQ0FBQztFQUNwQjtBQUNEO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsQ0FBcUIsY0FBQSxDQUFBLGFBQUEsR0FBRyxhQUFhLENBQUM7Q0FDdEMsU0FBUyxhQUFhLENBQUMsUUFBUSxFQUFFO0dBQy9CLElBQUksQ0FBQyxRQUFRLEdBQUcsaUJBQWlCLENBQUMsUUFBUSxDQUFDLENBQUM7R0FDNUMsSUFBSSxFQUFFLENBQUM7R0FDUCxRQUFRLElBQUksQ0FBQyxRQUFRO0FBQ3ZCLEtBQUksS0FBSyxTQUFTO0FBQ2xCLE9BQU0sSUFBSSxDQUFDLElBQUksR0FBRyxTQUFTLENBQUM7QUFDNUIsT0FBTSxJQUFJLENBQUMsR0FBRyxHQUFHLFFBQVEsQ0FBQztPQUNwQixFQUFFLEdBQUcsQ0FBQyxDQUFDO0FBQ2IsT0FBTSxNQUFNO0FBQ1osS0FBSSxLQUFLLE1BQU07QUFDZixPQUFNLElBQUksQ0FBQyxRQUFRLEdBQUcsWUFBWSxDQUFDO09BQzdCLEVBQUUsR0FBRyxDQUFDLENBQUM7QUFDYixPQUFNLE1BQU07QUFDWixLQUFJLEtBQUssUUFBUTtBQUNqQixPQUFNLElBQUksQ0FBQyxJQUFJLEdBQUcsVUFBVSxDQUFDO0FBQzdCLE9BQU0sSUFBSSxDQUFDLEdBQUcsR0FBRyxTQUFTLENBQUM7T0FDckIsRUFBRSxHQUFHLENBQUMsQ0FBQztBQUNiLE9BQU0sTUFBTTtLQUNSO0FBQ0osT0FBTSxJQUFJLENBQUMsS0FBSyxHQUFHLFdBQVcsQ0FBQztBQUMvQixPQUFNLElBQUksQ0FBQyxHQUFHLEdBQUcsU0FBUyxDQUFDO0FBQzNCLE9BQU0sT0FBTztJQUNWO0FBQ0gsR0FBRSxJQUFJLENBQUMsUUFBUSxHQUFHLENBQUMsQ0FBQztBQUNwQixHQUFFLElBQUksQ0FBQyxTQUFTLEdBQUcsQ0FBQyxDQUFDO0dBQ25CLElBQUksQ0FBQyxRQUFRLEdBQUcsTUFBTSxDQUFDLFdBQVcsQ0FBQyxFQUFFLENBQUMsQ0FBQztFQUN4QztBQUNEO0FBQ0EsQ0FBQSxhQUFhLENBQUMsU0FBUyxDQUFDLEtBQUssR0FBRyxVQUFVLEdBQUcsRUFBRTtHQUM3QyxJQUFJLEdBQUcsQ0FBQyxNQUFNLEtBQUssQ0FBQyxFQUFFLE9BQU8sRUFBRSxDQUFDO0dBQ2hDLElBQUksQ0FBQyxDQUFDO0dBQ04sSUFBSSxDQUFDLENBQUM7QUFDUixHQUFFLElBQUksSUFBSSxDQUFDLFFBQVEsRUFBRTtLQUNqQixDQUFDLEdBQUcsSUFBSSxDQUFDLFFBQVEsQ0FBQyxHQUFHLENBQUMsQ0FBQztBQUMzQixLQUFJLElBQUksQ0FBQyxLQUFLLFNBQVMsRUFBRSxPQUFPLEVBQUUsQ0FBQztBQUNuQyxLQUFJLENBQUMsR0FBRyxJQUFJLENBQUMsUUFBUSxDQUFDO0FBQ3RCLEtBQUksSUFBSSxDQUFDLFFBQVEsR0FBRyxDQUFDLENBQUM7QUFDdEIsSUFBRyxNQUFNO0tBQ0wsQ0FBQyxHQUFHLENBQUMsQ0FBQztJQUNQO0FBQ0gsR0FBRSxJQUFJLENBQUMsR0FBRyxHQUFHLENBQUMsTUFBTSxFQUFFLE9BQU8sQ0FBQyxHQUFHLENBQUMsR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDLEdBQUcsRUFBRSxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDLEdBQUcsRUFBRSxDQUFDLENBQUMsQ0FBQztBQUMzRSxHQUFFLE9BQU8sQ0FBQyxJQUFJLEVBQUUsQ0FBQztBQUNqQixFQUFDLENBQUM7QUFDRjtBQUNBLENBQUEsYUFBYSxDQUFDLFNBQVMsQ0FBQyxHQUFHLEdBQUcsT0FBTyxDQUFDO0FBQ3RDO0FBQ0E7QUFDQSxDQUFBLGFBQWEsQ0FBQyxTQUFTLENBQUMsSUFBSSxHQUFHLFFBQVEsQ0FBQztBQUN4QztBQUNBO0FBQ0EsQ0FBQSxhQUFhLENBQUMsU0FBUyxDQUFDLFFBQVEsR0FBRyxVQUFVLEdBQUcsRUFBRTtHQUNoRCxJQUFJLElBQUksQ0FBQyxRQUFRLElBQUksR0FBRyxDQUFDLE1BQU0sRUFBRTtLQUMvQixHQUFHLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxRQUFRLEVBQUUsSUFBSSxDQUFDLFNBQVMsR0FBRyxJQUFJLENBQUMsUUFBUSxFQUFFLENBQUMsRUFBRSxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUM7QUFDOUUsS0FBSSxPQUFPLElBQUksQ0FBQyxRQUFRLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxRQUFRLEVBQUUsQ0FBQyxFQUFFLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQztJQUNqRTtHQUNELEdBQUcsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLFFBQVEsRUFBRSxJQUFJLENBQUMsU0FBUyxHQUFHLElBQUksQ0FBQyxRQUFRLEVBQUUsQ0FBQyxFQUFFLEdBQUcsQ0FBQyxNQUFNLENBQUMsQ0FBQztBQUN6RSxHQUFFLElBQUksQ0FBQyxRQUFRLElBQUksR0FBRyxDQUFDLE1BQU0sQ0FBQztBQUM5QixFQUFDLENBQUM7QUFDRjtBQUNBO0FBQ0E7Q0FDQSxTQUFTLGFBQWEsQ0FBQyxJQUFJLEVBQUU7QUFDN0IsR0FBRSxJQUFJLElBQUksSUFBSSxJQUFJLEVBQUUsT0FBTyxDQUFDLENBQUMsS0FBSyxJQUFJLElBQUksSUFBSSxDQUFDLEtBQUssSUFBSSxFQUFFLE9BQU8sQ0FBQyxDQUFDLEtBQUssSUFBSSxJQUFJLElBQUksQ0FBQyxLQUFLLElBQUksRUFBRSxPQUFPLENBQUMsQ0FBQyxLQUFLLElBQUksSUFBSSxJQUFJLENBQUMsS0FBSyxJQUFJLEVBQUUsT0FBTyxDQUFDLENBQUM7QUFDL0ksR0FBRSxPQUFPLElBQUksSUFBSSxDQUFDLEtBQUssSUFBSSxHQUFHLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDO0VBQ3JDO0FBQ0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQSxDQUFBLFNBQVMsbUJBQW1CLENBQUMsSUFBSSxFQUFFLEdBQUcsRUFBRSxDQUFDLEVBQUU7R0FDekMsSUFBSSxDQUFDLEdBQUcsR0FBRyxDQUFDLE1BQU0sR0FBRyxDQUFDLENBQUM7QUFDekIsR0FBRSxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsT0FBTyxDQUFDLENBQUM7R0FDcEIsSUFBSSxFQUFFLEdBQUcsYUFBYSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2pDLEdBQUUsSUFBSSxFQUFFLElBQUksQ0FBQyxFQUFFO0FBQ2YsS0FBSSxJQUFJLEVBQUUsR0FBRyxDQUFDLEVBQUUsSUFBSSxDQUFDLFFBQVEsR0FBRyxFQUFFLEdBQUcsQ0FBQyxDQUFDO0tBQ25DLE9BQU8sRUFBRSxDQUFDO0lBQ1g7QUFDSCxHQUFFLElBQUksRUFBRSxDQUFDLEdBQUcsQ0FBQyxJQUFJLEVBQUUsS0FBSyxDQUFDLENBQUMsRUFBRSxPQUFPLENBQUMsQ0FBQztHQUNuQyxFQUFFLEdBQUcsYUFBYSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQzdCLEdBQUUsSUFBSSxFQUFFLElBQUksQ0FBQyxFQUFFO0FBQ2YsS0FBSSxJQUFJLEVBQUUsR0FBRyxDQUFDLEVBQUUsSUFBSSxDQUFDLFFBQVEsR0FBRyxFQUFFLEdBQUcsQ0FBQyxDQUFDO0tBQ25DLE9BQU8sRUFBRSxDQUFDO0lBQ1g7QUFDSCxHQUFFLElBQUksRUFBRSxDQUFDLEdBQUcsQ0FBQyxJQUFJLEVBQUUsS0FBSyxDQUFDLENBQUMsRUFBRSxPQUFPLENBQUMsQ0FBQztHQUNuQyxFQUFFLEdBQUcsYUFBYSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQzdCLEdBQUUsSUFBSSxFQUFFLElBQUksQ0FBQyxFQUFFO0FBQ2YsS0FBSSxJQUFJLEVBQUUsR0FBRyxDQUFDLEVBQUU7QUFDaEIsT0FBTSxJQUFJLEVBQUUsS0FBSyxDQUFDLEVBQUUsRUFBRSxHQUFHLENBQUMsQ0FBQyxLQUFLLElBQUksQ0FBQyxRQUFRLEdBQUcsRUFBRSxHQUFHLENBQUMsQ0FBQztNQUNsRDtLQUNELE9BQU8sRUFBRSxDQUFDO0lBQ1g7R0FDRCxPQUFPLENBQUMsQ0FBQztFQUNWO0FBQ0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsQ0FBQSxTQUFTLG1CQUFtQixDQUFDLElBQUksRUFBRSxHQUFHLEVBQUUsQ0FBQyxFQUFFO0dBQ3pDLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsSUFBSSxNQUFNLElBQUksRUFBRTtBQUNoQyxLQUFJLElBQUksQ0FBQyxRQUFRLEdBQUcsQ0FBQyxDQUFDO0tBQ2xCLE9BQU8sUUFBUSxDQUFDO0lBQ2pCO0FBQ0gsR0FBRSxJQUFJLElBQUksQ0FBQyxRQUFRLEdBQUcsQ0FBQyxJQUFJLEdBQUcsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxFQUFFO0tBQ3ZDLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsSUFBSSxNQUFNLElBQUksRUFBRTtBQUNsQyxPQUFNLElBQUksQ0FBQyxRQUFRLEdBQUcsQ0FBQyxDQUFDO09BQ2xCLE9BQU8sUUFBUSxDQUFDO01BQ2pCO0FBQ0wsS0FBSSxJQUFJLElBQUksQ0FBQyxRQUFRLEdBQUcsQ0FBQyxJQUFJLEdBQUcsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxFQUFFO09BQ3ZDLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsSUFBSSxNQUFNLElBQUksRUFBRTtBQUNwQyxTQUFRLElBQUksQ0FBQyxRQUFRLEdBQUcsQ0FBQyxDQUFDO1NBQ2xCLE9BQU8sUUFBUSxDQUFDO1FBQ2pCO01BQ0Y7SUFDRjtFQUNGO0FBQ0Q7QUFDQTtDQUNBLFNBQVMsWUFBWSxDQUFDLEdBQUcsRUFBRTtHQUN6QixJQUFJLENBQUMsR0FBRyxJQUFJLENBQUMsU0FBUyxHQUFHLElBQUksQ0FBQyxRQUFRLENBQUM7R0FDdkMsSUFBSSxDQUFDLEdBQUcsbUJBQW1CLENBQUMsSUFBSSxFQUFFLEdBQU0sQ0FBQyxDQUFDO0FBQzVDLEdBQUUsSUFBSSxDQUFDLEtBQUssU0FBUyxFQUFFLE9BQU8sQ0FBQyxDQUFDO0dBQzlCLElBQUksSUFBSSxDQUFDLFFBQVEsSUFBSSxHQUFHLENBQUMsTUFBTSxFQUFFO0FBQ25DLEtBQUksR0FBRyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsUUFBUSxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDO0FBQ2pELEtBQUksT0FBTyxJQUFJLENBQUMsUUFBUSxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsUUFBUSxFQUFFLENBQUMsRUFBRSxJQUFJLENBQUMsU0FBUyxDQUFDLENBQUM7SUFDakU7QUFDSCxHQUFFLEdBQUcsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLFFBQVEsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLEdBQUcsQ0FBQyxNQUFNLENBQUMsQ0FBQztBQUM1QyxHQUFFLElBQUksQ0FBQyxRQUFRLElBQUksR0FBRyxDQUFDLE1BQU0sQ0FBQztFQUM3QjtBQUNEO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsQ0FBQSxTQUFTLFFBQVEsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxFQUFFO0dBQ3hCLElBQUksS0FBSyxHQUFHLG1CQUFtQixDQUFDLElBQUksRUFBRSxHQUFHLEVBQUUsQ0FBQyxDQUFDLENBQUM7QUFDaEQsR0FBRSxJQUFJLENBQUMsSUFBSSxDQUFDLFFBQVEsRUFBRSxPQUFPLEdBQUcsQ0FBQyxRQUFRLENBQUMsTUFBTSxFQUFFLENBQUMsQ0FBQyxDQUFDO0FBQ3JELEdBQUUsSUFBSSxDQUFDLFNBQVMsR0FBRyxLQUFLLENBQUM7QUFDekIsR0FBRSxJQUFJLEdBQUcsR0FBRyxHQUFHLENBQUMsTUFBTSxJQUFJLEtBQUssR0FBRyxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUM7QUFDakQsR0FBRSxHQUFHLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxRQUFRLEVBQUUsQ0FBQyxFQUFFLEdBQUcsQ0FBQyxDQUFDO0dBQ2hDLE9BQU8sR0FBRyxDQUFDLFFBQVEsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxFQUFFLEdBQUcsQ0FBQyxDQUFDO0VBQ3JDO0FBQ0Q7QUFDQTtBQUNBO0NBQ0EsU0FBUyxPQUFPLENBQUMsR0FBRyxFQUFFO0FBQ3RCLEdBQUUsSUFBSSxDQUFDLEdBQUcsR0FBRyxJQUFJLEdBQUcsQ0FBQyxNQUFNLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsR0FBRyxFQUFFLENBQUM7R0FDakQsSUFBSSxJQUFJLENBQUMsUUFBUSxFQUFFLE9BQU8sQ0FBQyxHQUFHLFFBQVEsQ0FBQztHQUN2QyxPQUFPLENBQUMsQ0FBQztFQUNWO0FBQ0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLENBQUEsU0FBUyxTQUFTLENBQUMsR0FBRyxFQUFFLENBQUMsRUFBRTtHQUN6QixJQUFJLENBQUMsR0FBRyxDQUFDLE1BQU0sR0FBRyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsRUFBRTtLQUM5QixJQUFJLENBQUMsR0FBRyxHQUFHLENBQUMsUUFBUSxDQUFDLFNBQVMsRUFBRSxDQUFDLENBQUMsQ0FBQztLQUNuQyxJQUFJLENBQUMsRUFBRTtBQUNYLE9BQU0sSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsTUFBTSxHQUFHLENBQUMsQ0FBQyxDQUFDO09BQ25DLElBQUksQ0FBQyxJQUFJLE1BQU0sSUFBSSxDQUFDLElBQUksTUFBTSxFQUFFO0FBQ3RDLFNBQVEsSUFBSSxDQUFDLFFBQVEsR0FBRyxDQUFDLENBQUM7QUFDMUIsU0FBUSxJQUFJLENBQUMsU0FBUyxHQUFHLENBQUMsQ0FBQztBQUMzQixTQUFRLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDLEdBQUcsR0FBRyxDQUFDLEdBQUcsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDLENBQUM7QUFDL0MsU0FBUSxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxHQUFHLEdBQUcsQ0FBQyxHQUFHLENBQUMsTUFBTSxHQUFHLENBQUMsQ0FBQyxDQUFDO1NBQ3ZDLE9BQU8sQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUN2QjtNQUNGO0tBQ0QsT0FBTyxDQUFDLENBQUM7SUFDVjtBQUNILEdBQUUsSUFBSSxDQUFDLFFBQVEsR0FBRyxDQUFDLENBQUM7QUFDcEIsR0FBRSxJQUFJLENBQUMsU0FBUyxHQUFHLENBQUMsQ0FBQztBQUNyQixHQUFFLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDLEdBQUcsR0FBRyxDQUFDLEdBQUcsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDLENBQUM7QUFDekMsR0FBRSxPQUFPLEdBQUcsQ0FBQyxRQUFRLENBQUMsU0FBUyxFQUFFLENBQUMsRUFBRSxHQUFHLENBQUMsTUFBTSxHQUFHLENBQUMsQ0FBQyxDQUFDO0VBQ25EO0FBQ0Q7QUFDQTtBQUNBO0NBQ0EsU0FBUyxRQUFRLENBQUMsR0FBRyxFQUFFO0FBQ3ZCLEdBQUUsSUFBSSxDQUFDLEdBQUcsR0FBRyxJQUFJLEdBQUcsQ0FBQyxNQUFNLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsR0FBRyxFQUFFLENBQUM7QUFDbkQsR0FBRSxJQUFJLElBQUksQ0FBQyxRQUFRLEVBQUU7S0FDakIsSUFBSSxHQUFHLEdBQUcsSUFBSSxDQUFDLFNBQVMsR0FBRyxJQUFJLENBQUMsUUFBUSxDQUFDO0FBQzdDLEtBQUksT0FBTyxDQUFDLEdBQUcsSUFBSSxDQUFDLFFBQVEsQ0FBQyxRQUFRLENBQUMsU0FBUyxFQUFFLENBQUMsRUFBRSxHQUFHLENBQUMsQ0FBQztJQUN0RDtHQUNELE9BQU8sQ0FBQyxDQUFDO0VBQ1Y7QUFDRDtBQUNBLENBQUEsU0FBUyxVQUFVLENBQUMsR0FBRyxFQUFFLENBQUMsRUFBRTtHQUMxQixJQUFJLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxJQUFJLENBQUMsQ0FBQztBQUMvQixHQUFFLElBQUksQ0FBQyxLQUFLLENBQUMsRUFBRSxPQUFPLEdBQUcsQ0FBQyxRQUFRLENBQUMsUUFBUSxFQUFFLENBQUMsQ0FBQyxDQUFDO0FBQ2hELEdBQUUsSUFBSSxDQUFDLFFBQVEsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ3hCLEdBQUUsSUFBSSxDQUFDLFNBQVMsR0FBRyxDQUFDLENBQUM7QUFDckIsR0FBRSxJQUFJLENBQUMsS0FBSyxDQUFDLEVBQUU7QUFDZixLQUFJLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDLEdBQUcsR0FBRyxDQUFDLEdBQUcsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDLENBQUM7QUFDM0MsSUFBRyxNQUFNO0FBQ1QsS0FBSSxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxHQUFHLEdBQUcsQ0FBQyxHQUFHLENBQUMsTUFBTSxHQUFHLENBQUMsQ0FBQyxDQUFDO0FBQzNDLEtBQUksSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsR0FBRyxHQUFHLENBQUMsR0FBRyxDQUFDLE1BQU0sR0FBRyxDQUFDLENBQUMsQ0FBQztJQUN4QztBQUNILEdBQUUsT0FBTyxHQUFHLENBQUMsUUFBUSxDQUFDLFFBQVEsRUFBRSxDQUFDLEVBQUUsR0FBRyxDQUFDLE1BQU0sR0FBRyxDQUFDLENBQUMsQ0FBQztFQUNsRDtBQUNEO0NBQ0EsU0FBUyxTQUFTLENBQUMsR0FBRyxFQUFFO0FBQ3hCLEdBQUUsSUFBSSxDQUFDLEdBQUcsR0FBRyxJQUFJLEdBQUcsQ0FBQyxNQUFNLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsR0FBRyxFQUFFLENBQUM7R0FDakQsSUFBSSxJQUFJLENBQUMsUUFBUSxFQUFFLE9BQU8sQ0FBQyxHQUFHLElBQUksQ0FBQyxRQUFRLENBQUMsUUFBUSxDQUFDLFFBQVEsRUFBRSxDQUFDLEVBQUUsQ0FBQyxHQUFHLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQztHQUNyRixPQUFPLENBQUMsQ0FBQztFQUNWO0FBQ0Q7QUFDQTtDQUNBLFNBQVMsV0FBVyxDQUFDLEdBQUcsRUFBRTtHQUN4QixPQUFPLEdBQUcsQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDO0VBQ3BDO0FBQ0Q7Q0FDQSxTQUFTLFNBQVMsQ0FBQyxHQUFHLEVBQUU7QUFDeEIsR0FBRSxPQUFPLEdBQUcsSUFBSSxHQUFHLENBQUMsTUFBTSxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLEdBQUcsRUFBRSxDQUFDO0FBQ2xELEVBQUE7Ozs7Ozs7Ozs7QUNuU0E7QUFDQSxDQUFBLElBQUksMEJBQTBCLEdBQUdBLGFBQUEsRUFBMEIsQ0FBQyxLQUFLLENBQUMsMEJBQTBCLENBQUM7Q0FDN0YsU0FBUyxJQUFJLENBQUMsUUFBUSxFQUFFO0FBQ3hCLEdBQUUsSUFBSSxNQUFNLEdBQUcsS0FBSyxDQUFDO0FBQ3JCLEdBQUUsT0FBTyxZQUFZO0tBQ2pCLElBQUksTUFBTSxFQUFFLE9BQU87S0FDbkIsTUFBTSxHQUFHLElBQUksQ0FBQztLQUNkLEtBQUssSUFBSSxJQUFJLEdBQUcsU0FBUyxDQUFDLE1BQU0sRUFBRSxJQUFJLEdBQUcsSUFBSSxLQUFLLENBQUMsSUFBSSxDQUFDLEVBQUUsSUFBSSxHQUFHLENBQUMsRUFBRSxJQUFJLEdBQUcsSUFBSSxFQUFFLElBQUksRUFBRSxFQUFFO09BQ3ZGLElBQUksQ0FBQyxJQUFJLENBQUMsR0FBRyxTQUFTLENBQUMsSUFBSSxDQUFDLENBQUM7TUFDOUI7S0FDRCxRQUFRLENBQUMsS0FBSyxDQUFDLElBQUksRUFBRSxJQUFJLENBQUMsQ0FBQztBQUMvQixJQUFHLENBQUM7RUFDSDtDQUNELFNBQVMsSUFBSSxHQUFHLEVBQUU7Q0FDbEIsU0FBUyxTQUFTLENBQUMsTUFBTSxFQUFFO0dBQ3pCLE9BQU8sTUFBTSxDQUFDLFNBQVMsSUFBSSxPQUFPLE1BQU0sQ0FBQyxLQUFLLEtBQUssVUFBVSxDQUFDO0VBQy9EO0FBQ0QsQ0FBQSxTQUFTLEdBQUcsQ0FBQyxNQUFNLEVBQUUsSUFBSSxFQUFFLFFBQVEsRUFBRTtBQUNyQyxHQUFFLElBQUksT0FBTyxJQUFJLEtBQUssVUFBVSxFQUFFLE9BQU8sR0FBRyxDQUFDLE1BQU0sRUFBRSxJQUFJLEVBQUUsSUFBSSxDQUFDLENBQUM7QUFDakUsR0FBRSxJQUFJLENBQUMsSUFBSSxFQUFFLElBQUksR0FBRyxFQUFFLENBQUM7R0FDckIsUUFBUSxHQUFHLElBQUksQ0FBQyxRQUFRLElBQUksSUFBSSxDQUFDLENBQUM7QUFDcEMsR0FBRSxJQUFJLFFBQVEsR0FBRyxJQUFJLENBQUMsUUFBUSxJQUFJLElBQUksQ0FBQyxRQUFRLEtBQUssS0FBSyxJQUFJLE1BQU0sQ0FBQyxRQUFRLENBQUM7QUFDN0UsR0FBRSxJQUFJLFFBQVEsR0FBRyxJQUFJLENBQUMsUUFBUSxJQUFJLElBQUksQ0FBQyxRQUFRLEtBQUssS0FBSyxJQUFJLE1BQU0sQ0FBQyxRQUFRLENBQUM7QUFDN0UsR0FBRSxJQUFJLGNBQWMsR0FBRyxTQUFTLGNBQWMsR0FBRztLQUM3QyxJQUFJLENBQUMsTUFBTSxDQUFDLFFBQVEsRUFBRSxRQUFRLEVBQUUsQ0FBQztBQUNyQyxJQUFHLENBQUM7QUFDSixHQUFFLElBQUksYUFBYSxHQUFHLE1BQU0sQ0FBQyxjQUFjLElBQUksTUFBTSxDQUFDLGNBQWMsQ0FBQyxRQUFRLENBQUM7QUFDOUUsR0FBRSxJQUFJLFFBQVEsR0FBRyxTQUFTLFFBQVEsR0FBRztLQUNqQyxRQUFRLEdBQUcsS0FBSyxDQUFDO0tBQ2pCLGFBQWEsR0FBRyxJQUFJLENBQUM7S0FDckIsSUFBSSxDQUFDLFFBQVEsRUFBRSxRQUFRLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDO0FBQ3pDLElBQUcsQ0FBQztBQUNKLEdBQUUsSUFBSSxhQUFhLEdBQUcsTUFBTSxDQUFDLGNBQWMsSUFBSSxNQUFNLENBQUMsY0FBYyxDQUFDLFVBQVUsQ0FBQztBQUNoRixHQUFFLElBQUksS0FBSyxHQUFHLFNBQVMsS0FBSyxHQUFHO0tBQzNCLFFBQVEsR0FBRyxLQUFLLENBQUM7S0FDakIsYUFBYSxHQUFHLElBQUksQ0FBQztLQUNyQixJQUFJLENBQUMsUUFBUSxFQUFFLFFBQVEsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUM7QUFDekMsSUFBRyxDQUFDO0FBQ0osR0FBRSxJQUFJLE9BQU8sR0FBRyxTQUFTLE9BQU8sQ0FBQyxHQUFHLEVBQUU7S0FDbEMsUUFBUSxDQUFDLElBQUksQ0FBQyxNQUFNLEVBQUUsR0FBRyxDQUFDLENBQUM7QUFDL0IsSUFBRyxDQUFDO0FBQ0osR0FBRSxJQUFJLE9BQU8sR0FBRyxTQUFTLE9BQU8sR0FBRztLQUMvQixJQUFJLEdBQUcsQ0FBQztBQUNaLEtBQUksSUFBSSxRQUFRLElBQUksQ0FBQyxhQUFhLEVBQUU7QUFDcEMsT0FBTSxJQUFJLENBQUMsTUFBTSxDQUFDLGNBQWMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxjQUFjLENBQUMsS0FBSyxFQUFFLEdBQUcsR0FBRyxJQUFJLDBCQUEwQixFQUFFLENBQUM7T0FDbkcsT0FBTyxRQUFRLENBQUMsSUFBSSxDQUFDLE1BQU0sRUFBRSxHQUFHLENBQUMsQ0FBQztNQUNuQztBQUNMLEtBQUksSUFBSSxRQUFRLElBQUksQ0FBQyxhQUFhLEVBQUU7QUFDcEMsT0FBTSxJQUFJLENBQUMsTUFBTSxDQUFDLGNBQWMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxjQUFjLENBQUMsS0FBSyxFQUFFLEdBQUcsR0FBRyxJQUFJLDBCQUEwQixFQUFFLENBQUM7T0FDbkcsT0FBTyxRQUFRLENBQUMsSUFBSSxDQUFDLE1BQU0sRUFBRSxHQUFHLENBQUMsQ0FBQztNQUNuQztBQUNMLElBQUcsQ0FBQztBQUNKLEdBQUUsSUFBSSxTQUFTLEdBQUcsU0FBUyxTQUFTLEdBQUc7S0FDbkMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsUUFBUSxFQUFFLFFBQVEsQ0FBQyxDQUFDO0FBQ3RDLElBQUcsQ0FBQztBQUNKLEdBQUUsSUFBSSxTQUFTLENBQUMsTUFBTSxDQUFDLEVBQUU7S0FDckIsTUFBTSxDQUFDLEVBQUUsQ0FBQyxVQUFVLEVBQUUsUUFBUSxDQUFDLENBQUM7S0FDaEMsTUFBTSxDQUFDLEVBQUUsQ0FBQyxPQUFPLEVBQUUsT0FBTyxDQUFDLENBQUM7QUFDaEMsS0FBSSxJQUFJLE1BQU0sQ0FBQyxHQUFHLEVBQUUsU0FBUyxFQUFFLENBQUMsS0FBSyxNQUFNLENBQUMsRUFBRSxDQUFDLFNBQVMsRUFBRSxTQUFTLENBQUMsQ0FBQztJQUNsRSxNQUFNLElBQUksUUFBUSxJQUFJLENBQUMsTUFBTSxDQUFDLGNBQWMsRUFBRTtBQUNqRDtLQUNJLE1BQU0sQ0FBQyxFQUFFLENBQUMsS0FBSyxFQUFFLGNBQWMsQ0FBQyxDQUFDO0tBQ2pDLE1BQU0sQ0FBQyxFQUFFLENBQUMsT0FBTyxFQUFFLGNBQWMsQ0FBQyxDQUFDO0lBQ3BDO0dBQ0QsTUFBTSxDQUFDLEVBQUUsQ0FBQyxLQUFLLEVBQUUsS0FBSyxDQUFDLENBQUM7R0FDeEIsTUFBTSxDQUFDLEVBQUUsQ0FBQyxRQUFRLEVBQUUsUUFBUSxDQUFDLENBQUM7QUFDaEMsR0FBRSxJQUFJLElBQUksQ0FBQyxLQUFLLEtBQUssS0FBSyxFQUFFLE1BQU0sQ0FBQyxFQUFFLENBQUMsT0FBTyxFQUFFLE9BQU8sQ0FBQyxDQUFDO0dBQ3RELE1BQU0sQ0FBQyxFQUFFLENBQUMsT0FBTyxFQUFFLE9BQU8sQ0FBQyxDQUFDO0FBQzlCLEdBQUUsT0FBTyxZQUFZO0tBQ2pCLE1BQU0sQ0FBQyxjQUFjLENBQUMsVUFBVSxFQUFFLFFBQVEsQ0FBQyxDQUFDO0tBQzVDLE1BQU0sQ0FBQyxjQUFjLENBQUMsT0FBTyxFQUFFLE9BQU8sQ0FBQyxDQUFDO0tBQ3hDLE1BQU0sQ0FBQyxjQUFjLENBQUMsU0FBUyxFQUFFLFNBQVMsQ0FBQyxDQUFDO0FBQ2hELEtBQUksSUFBSSxNQUFNLENBQUMsR0FBRyxFQUFFLE1BQU0sQ0FBQyxHQUFHLENBQUMsY0FBYyxDQUFDLFFBQVEsRUFBRSxRQUFRLENBQUMsQ0FBQztLQUM5RCxNQUFNLENBQUMsY0FBYyxDQUFDLEtBQUssRUFBRSxjQUFjLENBQUMsQ0FBQztLQUM3QyxNQUFNLENBQUMsY0FBYyxDQUFDLE9BQU8sRUFBRSxjQUFjLENBQUMsQ0FBQztLQUMvQyxNQUFNLENBQUMsY0FBYyxDQUFDLFFBQVEsRUFBRSxRQUFRLENBQUMsQ0FBQztLQUMxQyxNQUFNLENBQUMsY0FBYyxDQUFDLEtBQUssRUFBRSxLQUFLLENBQUMsQ0FBQztLQUNwQyxNQUFNLENBQUMsY0FBYyxDQUFDLE9BQU8sRUFBRSxPQUFPLENBQUMsQ0FBQztLQUN4QyxNQUFNLENBQUMsY0FBYyxDQUFDLE9BQU8sRUFBRSxPQUFPLENBQUMsQ0FBQztBQUM1QyxJQUFHLENBQUM7RUFDSDtBQUNELENBQUEsV0FBYyxHQUFHLEdBQUcsQ0FBQTs7Ozs7Ozs7OztBQ3BGcEI7QUFDQSxDQUFBLElBQUkscUJBQXFCLENBQUM7QUFDMUIsQ0FBQSxTQUFTLGVBQWUsQ0FBQyxHQUFHLEVBQUUsR0FBRyxFQUFFLEtBQUssRUFBRSxFQUFFLEdBQUcsR0FBRyxjQUFjLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxJQUFJLEdBQUcsSUFBSSxHQUFHLEVBQUUsRUFBRSxNQUFNLENBQUMsY0FBYyxDQUFDLEdBQUcsRUFBRSxHQUFHLEVBQUUsRUFBRSxLQUFLLEVBQUUsS0FBSyxFQUFFLFVBQVUsRUFBRSxJQUFJLEVBQUUsWUFBWSxFQUFFLElBQUksRUFBRSxRQUFRLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQyxFQUFFLE1BQU0sRUFBRSxHQUFHLENBQUMsR0FBRyxDQUFDLEdBQUcsS0FBSyxDQUFDLEVBQUUsQ0FBQyxPQUFPLEdBQUcsQ0FBQyxFQUFFO0FBQzVPLENBQUEsU0FBUyxjQUFjLENBQUMsR0FBRyxFQUFFLEVBQUUsSUFBSSxHQUFHLEdBQUcsWUFBWSxDQUFDLEdBQUcsRUFBRSxRQUFRLENBQUMsQ0FBQyxDQUFDLE9BQU8sT0FBTyxHQUFHLEtBQUssUUFBUSxHQUFHLEdBQUcsR0FBRyxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUMsRUFBRTtBQUMzSCxDQUFBLFNBQVMsWUFBWSxDQUFDLEtBQUssRUFBRSxJQUFJLEVBQUUsRUFBRSxJQUFJLE9BQU8sS0FBSyxLQUFLLFFBQVEsSUFBSSxLQUFLLEtBQUssSUFBSSxFQUFFLE9BQU8sS0FBSyxDQUFDLENBQUMsSUFBSSxJQUFJLEdBQUcsS0FBSyxDQUFDLE1BQU0sQ0FBQyxXQUFXLENBQUMsQ0FBQyxDQUFDLElBQUksSUFBSSxLQUFLLFNBQVMsRUFBRSxFQUFFLElBQUksR0FBRyxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUMsS0FBSyxFQUFFLElBQUksSUFBSSxTQUFTLENBQUMsQ0FBQyxDQUFDLElBQUksT0FBTyxHQUFHLEtBQUssUUFBUSxFQUFFLE9BQU8sR0FBRyxDQUFDLENBQUMsTUFBTSxJQUFJLFNBQVMsQ0FBQyw4Q0FBOEMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxPQUFPLENBQUMsSUFBSSxLQUFLLFFBQVEsR0FBRyxNQUFNLEdBQUcsTUFBTSxFQUFFLEtBQUssQ0FBQyxDQUFDLEVBQUU7Q0FDelgsSUFBSSxRQUFRLEdBQUdBLGtCQUFBLEVBQTBCLENBQUM7QUFDMUMsQ0FBQSxJQUFJLFlBQVksR0FBRyxNQUFNLENBQUMsYUFBYSxDQUFDLENBQUM7QUFDekMsQ0FBQSxJQUFJLFdBQVcsR0FBRyxNQUFNLENBQUMsWUFBWSxDQUFDLENBQUM7QUFDdkMsQ0FBQSxJQUFJLE1BQU0sR0FBRyxNQUFNLENBQUMsT0FBTyxDQUFDLENBQUM7QUFDN0IsQ0FBQSxJQUFJLE1BQU0sR0FBRyxNQUFNLENBQUMsT0FBTyxDQUFDLENBQUM7QUFDN0IsQ0FBQSxJQUFJLFlBQVksR0FBRyxNQUFNLENBQUMsYUFBYSxDQUFDLENBQUM7QUFDekMsQ0FBQSxJQUFJLGNBQWMsR0FBRyxNQUFNLENBQUMsZUFBZSxDQUFDLENBQUM7QUFDN0MsQ0FBQSxJQUFJLE9BQU8sR0FBRyxNQUFNLENBQUMsUUFBUSxDQUFDLENBQUM7QUFDL0IsQ0FBQSxTQUFTLGdCQUFnQixDQUFDLEtBQUssRUFBRSxJQUFJLEVBQUU7QUFDdkMsR0FBRSxPQUFPO0tBQ0wsS0FBSyxFQUFFLEtBQUs7S0FDWixJQUFJLEVBQUUsSUFBSTtBQUNkLElBQUcsQ0FBQztFQUNIO0NBQ0QsU0FBUyxjQUFjLENBQUMsSUFBSSxFQUFFO0FBQzlCLEdBQUUsSUFBSSxPQUFPLEdBQUcsSUFBSSxDQUFDLFlBQVksQ0FBQyxDQUFDO0FBQ25DLEdBQUUsSUFBSSxPQUFPLEtBQUssSUFBSSxFQUFFO0tBQ3BCLElBQUksSUFBSSxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQyxJQUFJLEVBQUUsQ0FBQztBQUNwQztBQUNBO0FBQ0E7QUFDQSxLQUFJLElBQUksSUFBSSxLQUFLLElBQUksRUFBRTtBQUN2QixPQUFNLElBQUksQ0FBQyxZQUFZLENBQUMsR0FBRyxJQUFJLENBQUM7QUFDaEMsT0FBTSxJQUFJLENBQUMsWUFBWSxDQUFDLEdBQUcsSUFBSSxDQUFDO0FBQ2hDLE9BQU0sSUFBSSxDQUFDLFdBQVcsQ0FBQyxHQUFHLElBQUksQ0FBQztPQUN6QixPQUFPLENBQUMsZ0JBQWdCLENBQUMsSUFBSSxFQUFFLEtBQUssQ0FBQyxDQUFDLENBQUM7TUFDeEM7SUFDRjtFQUNGO0NBQ0QsU0FBUyxVQUFVLENBQUMsSUFBSSxFQUFFO0FBQzFCO0FBQ0E7R0FDRSxPQUFPLENBQUMsUUFBUSxDQUFDLGNBQWMsRUFBRSxJQUFJLENBQUMsQ0FBQztFQUN4QztBQUNELENBQUEsU0FBUyxXQUFXLENBQUMsV0FBVyxFQUFFLElBQUksRUFBRTtBQUN4QyxHQUFFLE9BQU8sVUFBVSxPQUFPLEVBQUUsTUFBTSxFQUFFO0FBQ3BDLEtBQUksV0FBVyxDQUFDLElBQUksQ0FBQyxZQUFZO0FBQ2pDLE9BQU0sSUFBSSxJQUFJLENBQUMsTUFBTSxDQUFDLEVBQUU7U0FDaEIsT0FBTyxDQUFDLGdCQUFnQixDQUFDLFNBQVMsRUFBRSxJQUFJLENBQUMsQ0FBQyxDQUFDO0FBQ25ELFNBQVEsT0FBTztRQUNSO09BQ0QsSUFBSSxDQUFDLGNBQWMsQ0FBQyxDQUFDLE9BQU8sRUFBRSxNQUFNLENBQUMsQ0FBQztNQUN2QyxFQUFFLE1BQU0sQ0FBQyxDQUFDO0FBQ2YsSUFBRyxDQUFDO0VBQ0g7Q0FDRCxJQUFJLHNCQUFzQixHQUFHLE1BQU0sQ0FBQyxjQUFjLENBQUMsWUFBWSxFQUFFLENBQUMsQ0FBQztBQUNuRSxDQUFBLElBQUksb0NBQW9DLEdBQUcsTUFBTSxDQUFDLGNBQWMsRUFBRSxxQkFBcUIsR0FBRztHQUN4RixJQUFJLE1BQU0sR0FBRztBQUNmLEtBQUksT0FBTyxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUM7SUFDdEI7QUFDSCxHQUFFLElBQUksRUFBRSxTQUFTLElBQUksR0FBRztBQUN4QixLQUFJLElBQUksS0FBSyxHQUFHLElBQUksQ0FBQztBQUNyQjtBQUNBO0FBQ0EsS0FBSSxJQUFJLEtBQUssR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUM7QUFDN0IsS0FBSSxJQUFJLEtBQUssS0FBSyxJQUFJLEVBQUU7QUFDeEIsT0FBTSxPQUFPLE9BQU8sQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUM7TUFDOUI7QUFDTCxLQUFJLElBQUksSUFBSSxDQUFDLE1BQU0sQ0FBQyxFQUFFO0FBQ3RCLE9BQU0sT0FBTyxPQUFPLENBQUMsT0FBTyxDQUFDLGdCQUFnQixDQUFDLFNBQVMsRUFBRSxJQUFJLENBQUMsQ0FBQyxDQUFDO01BQzNEO0FBQ0wsS0FBSSxJQUFJLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQyxTQUFTLEVBQUU7QUFDakM7QUFDQTtBQUNBO0FBQ0E7T0FDTSxPQUFPLElBQUksT0FBTyxDQUFDLFVBQVUsT0FBTyxFQUFFLE1BQU0sRUFBRTtBQUNwRCxTQUFRLE9BQU8sQ0FBQyxRQUFRLENBQUMsWUFBWTtBQUNyQyxXQUFVLElBQUksS0FBSyxDQUFDLE1BQU0sQ0FBQyxFQUFFO0FBQzdCLGFBQVksTUFBTSxDQUFDLEtBQUssQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDO0FBQ2xDLFlBQVcsTUFBTTthQUNMLE9BQU8sQ0FBQyxnQkFBZ0IsQ0FBQyxTQUFTLEVBQUUsSUFBSSxDQUFDLENBQUMsQ0FBQztZQUM1QztBQUNYLFVBQVMsQ0FBQyxDQUFDO0FBQ1gsUUFBTyxDQUFDLENBQUM7TUFDSjtBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFJLElBQUksV0FBVyxHQUFHLElBQUksQ0FBQyxZQUFZLENBQUMsQ0FBQztLQUNyQyxJQUFJLE9BQU8sQ0FBQztLQUNaLElBQUksV0FBVyxFQUFFO0FBQ3JCLE9BQU0sT0FBTyxHQUFHLElBQUksT0FBTyxDQUFDLFdBQVcsQ0FBQyxXQUFXLEVBQUUsSUFBSSxDQUFDLENBQUMsQ0FBQztBQUM1RCxNQUFLLE1BQU07QUFDWDtBQUNBO09BQ00sSUFBSSxJQUFJLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDLElBQUksRUFBRSxDQUFDO0FBQ3RDLE9BQU0sSUFBSSxJQUFJLEtBQUssSUFBSSxFQUFFO0FBQ3pCLFNBQVEsT0FBTyxPQUFPLENBQUMsT0FBTyxDQUFDLGdCQUFnQixDQUFDLElBQUksRUFBRSxLQUFLLENBQUMsQ0FBQyxDQUFDO1FBQ3ZEO09BQ0QsT0FBTyxHQUFHLElBQUksT0FBTyxDQUFDLElBQUksQ0FBQyxjQUFjLENBQUMsQ0FBQyxDQUFDO01BQzdDO0FBQ0wsS0FBSSxJQUFJLENBQUMsWUFBWSxDQUFDLEdBQUcsT0FBTyxDQUFDO0tBQzdCLE9BQU8sT0FBTyxDQUFDO0lBQ2hCO0VBQ0YsRUFBRSxlQUFlLENBQUMscUJBQXFCLEVBQUUsTUFBTSxDQUFDLGFBQWEsRUFBRSxZQUFZO0dBQzFFLE9BQU8sSUFBSSxDQUFDO0VBQ2IsQ0FBQyxFQUFFLGVBQWUsQ0FBQyxxQkFBcUIsRUFBRSxRQUFRLEVBQUUsU0FBUyxPQUFPLEdBQUc7QUFDeEUsR0FBRSxJQUFJLE1BQU0sR0FBRyxJQUFJLENBQUM7QUFDcEI7QUFDQTtBQUNBO0dBQ0UsT0FBTyxJQUFJLE9BQU8sQ0FBQyxVQUFVLE9BQU8sRUFBRSxNQUFNLEVBQUU7S0FDNUMsTUFBTSxDQUFDLE9BQU8sQ0FBQyxDQUFDLE9BQU8sQ0FBQyxJQUFJLEVBQUUsVUFBVSxHQUFHLEVBQUU7T0FDM0MsSUFBSSxHQUFHLEVBQUU7QUFDZixTQUFRLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQztBQUNwQixTQUFRLE9BQU87UUFDUjtPQUNELE9BQU8sQ0FBQyxnQkFBZ0IsQ0FBQyxTQUFTLEVBQUUsSUFBSSxDQUFDLENBQUMsQ0FBQztBQUNqRCxNQUFLLENBQUMsQ0FBQztBQUNQLElBQUcsQ0FBQyxDQUFDO0FBQ0wsRUFBQyxDQUFDLEVBQUUscUJBQXFCLEdBQUcsc0JBQXNCLENBQUMsQ0FBQztBQUNwRCxDQUFBLElBQUksaUNBQWlDLEdBQUcsU0FBUyxpQ0FBaUMsQ0FBQyxNQUFNLEVBQUU7R0FDekYsSUFBSSxjQUFjLENBQUM7QUFDckIsR0FBRSxJQUFJLFFBQVEsR0FBRyxNQUFNLENBQUMsTUFBTSxDQUFDLG9DQUFvQyxHQUFHLGNBQWMsR0FBRyxFQUFFLEVBQUUsZUFBZSxDQUFDLGNBQWMsRUFBRSxPQUFPLEVBQUU7S0FDaEksS0FBSyxFQUFFLE1BQU07S0FDYixRQUFRLEVBQUUsSUFBSTtBQUNsQixJQUFHLENBQUMsRUFBRSxlQUFlLENBQUMsY0FBYyxFQUFFLFlBQVksRUFBRTtLQUNoRCxLQUFLLEVBQUUsSUFBSTtLQUNYLFFBQVEsRUFBRSxJQUFJO0FBQ2xCLElBQUcsQ0FBQyxFQUFFLGVBQWUsQ0FBQyxjQUFjLEVBQUUsV0FBVyxFQUFFO0tBQy9DLEtBQUssRUFBRSxJQUFJO0tBQ1gsUUFBUSxFQUFFLElBQUk7QUFDbEIsSUFBRyxDQUFDLEVBQUUsZUFBZSxDQUFDLGNBQWMsRUFBRSxNQUFNLEVBQUU7S0FDMUMsS0FBSyxFQUFFLElBQUk7S0FDWCxRQUFRLEVBQUUsSUFBSTtBQUNsQixJQUFHLENBQUMsRUFBRSxlQUFlLENBQUMsY0FBYyxFQUFFLE1BQU0sRUFBRTtBQUM5QyxLQUFJLEtBQUssRUFBRSxNQUFNLENBQUMsY0FBYyxDQUFDLFVBQVU7S0FDdkMsUUFBUSxFQUFFLElBQUk7QUFDbEIsSUFBRyxDQUFDLEVBQUUsZUFBZSxDQUFDLGNBQWMsRUFBRSxjQUFjLEVBQUU7S0FDbEQsS0FBSyxFQUFFLFNBQVMsS0FBSyxDQUFDLE9BQU8sRUFBRSxNQUFNLEVBQUU7T0FDckMsSUFBSSxJQUFJLEdBQUcsUUFBUSxDQUFDLE9BQU8sQ0FBQyxDQUFDLElBQUksRUFBRSxDQUFDO09BQ3BDLElBQUksSUFBSSxFQUFFO0FBQ2hCLFNBQVEsUUFBUSxDQUFDLFlBQVksQ0FBQyxHQUFHLElBQUksQ0FBQztBQUN0QyxTQUFRLFFBQVEsQ0FBQyxZQUFZLENBQUMsR0FBRyxJQUFJLENBQUM7QUFDdEMsU0FBUSxRQUFRLENBQUMsV0FBVyxDQUFDLEdBQUcsSUFBSSxDQUFDO1NBQzdCLE9BQU8sQ0FBQyxnQkFBZ0IsQ0FBQyxJQUFJLEVBQUUsS0FBSyxDQUFDLENBQUMsQ0FBQztBQUMvQyxRQUFPLE1BQU07QUFDYixTQUFRLFFBQVEsQ0FBQyxZQUFZLENBQUMsR0FBRyxPQUFPLENBQUM7QUFDekMsU0FBUSxRQUFRLENBQUMsV0FBVyxDQUFDLEdBQUcsTUFBTSxDQUFDO1FBQ2hDO01BQ0Y7S0FDRCxRQUFRLEVBQUUsSUFBSTtBQUNsQixJQUFHLENBQUMsRUFBRSxjQUFjLEVBQUUsQ0FBQztBQUN2QixHQUFFLFFBQVEsQ0FBQyxZQUFZLENBQUMsR0FBRyxJQUFJLENBQUM7QUFDaEMsR0FBRSxRQUFRLENBQUMsTUFBTSxFQUFFLFVBQVUsR0FBRyxFQUFFO0tBQzlCLElBQUksR0FBRyxJQUFJLEdBQUcsQ0FBQyxJQUFJLEtBQUssNEJBQTRCLEVBQUU7QUFDMUQsT0FBTSxJQUFJLE1BQU0sR0FBRyxRQUFRLENBQUMsV0FBVyxDQUFDLENBQUM7QUFDekM7QUFDQTtBQUNBLE9BQU0sSUFBSSxNQUFNLEtBQUssSUFBSSxFQUFFO0FBQzNCLFNBQVEsUUFBUSxDQUFDLFlBQVksQ0FBQyxHQUFHLElBQUksQ0FBQztBQUN0QyxTQUFRLFFBQVEsQ0FBQyxZQUFZLENBQUMsR0FBRyxJQUFJLENBQUM7QUFDdEMsU0FBUSxRQUFRLENBQUMsV0FBVyxDQUFDLEdBQUcsSUFBSSxDQUFDO0FBQ3JDLFNBQVEsTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDO1FBQ2I7QUFDUCxPQUFNLFFBQVEsQ0FBQyxNQUFNLENBQUMsR0FBRyxHQUFHLENBQUM7QUFDN0IsT0FBTSxPQUFPO01BQ1I7QUFDTCxLQUFJLElBQUksT0FBTyxHQUFHLFFBQVEsQ0FBQyxZQUFZLENBQUMsQ0FBQztBQUN6QyxLQUFJLElBQUksT0FBTyxLQUFLLElBQUksRUFBRTtBQUMxQixPQUFNLFFBQVEsQ0FBQyxZQUFZLENBQUMsR0FBRyxJQUFJLENBQUM7QUFDcEMsT0FBTSxRQUFRLENBQUMsWUFBWSxDQUFDLEdBQUcsSUFBSSxDQUFDO0FBQ3BDLE9BQU0sUUFBUSxDQUFDLFdBQVcsQ0FBQyxHQUFHLElBQUksQ0FBQztPQUM3QixPQUFPLENBQUMsZ0JBQWdCLENBQUMsU0FBUyxFQUFFLElBQUksQ0FBQyxDQUFDLENBQUM7TUFDNUM7QUFDTCxLQUFJLFFBQVEsQ0FBQyxNQUFNLENBQUMsR0FBRyxJQUFJLENBQUM7QUFDNUIsSUFBRyxDQUFDLENBQUM7QUFDTCxHQUFFLE1BQU0sQ0FBQyxFQUFFLENBQUMsVUFBVSxFQUFFLFVBQVUsQ0FBQyxJQUFJLENBQUMsSUFBSSxFQUFFLFFBQVEsQ0FBQyxDQUFDLENBQUM7R0FDdkQsT0FBTyxRQUFRLENBQUM7QUFDbEIsRUFBQyxDQUFDO0FBQ0YsQ0FBQSxjQUFjLEdBQUcsaUNBQWlDLENBQUE7Ozs7Ozs7Ozs7QUNsTGxEO0FBQ0EsQ0FBQSxTQUFTLGtCQUFrQixDQUFDLEdBQUcsRUFBRSxPQUFPLEVBQUUsTUFBTSxFQUFFLEtBQUssRUFBRSxNQUFNLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxFQUFFLElBQUksRUFBRSxJQUFJLElBQUksR0FBRyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxJQUFJLEtBQUssR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLEVBQUUsQ0FBQyxPQUFPLEtBQUssRUFBRSxFQUFFLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLE9BQU8sRUFBRSxDQUFDLElBQUksSUFBSSxDQUFDLElBQUksRUFBRSxFQUFFLE9BQU8sQ0FBQyxLQUFLLENBQUMsQ0FBQyxFQUFFLE1BQU0sRUFBRSxPQUFPLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxDQUFDLElBQUksQ0FBQyxLQUFLLEVBQUUsTUFBTSxDQUFDLENBQUMsRUFBRSxFQUFFO0NBQ3pRLFNBQVMsaUJBQWlCLENBQUMsRUFBRSxFQUFFLEVBQUUsT0FBTyxZQUFZLEVBQUUsSUFBSSxJQUFJLEdBQUcsSUFBSSxFQUFFLElBQUksR0FBRyxTQUFTLENBQUMsQ0FBQyxPQUFPLElBQUksT0FBTyxDQUFDLFVBQVUsT0FBTyxFQUFFLE1BQU0sRUFBRSxFQUFFLElBQUksR0FBRyxHQUFHLEVBQUUsQ0FBQyxLQUFLLENBQUMsSUFBSSxFQUFFLElBQUksQ0FBQyxDQUFDLENBQUMsU0FBUyxLQUFLLENBQUMsS0FBSyxFQUFFLEVBQUUsa0JBQWtCLENBQUMsR0FBRyxFQUFFLE9BQU8sRUFBRSxNQUFNLEVBQUUsS0FBSyxFQUFFLE1BQU0sRUFBRSxNQUFNLEVBQUUsS0FBSyxDQUFDLENBQUMsRUFBRSxDQUFDLFNBQVMsTUFBTSxDQUFDLEdBQUcsRUFBRSxFQUFFLGtCQUFrQixDQUFDLEdBQUcsRUFBRSxPQUFPLEVBQUUsTUFBTSxFQUFFLEtBQUssRUFBRSxNQUFNLEVBQUUsT0FBTyxFQUFFLEdBQUcsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxLQUFLLENBQUMsU0FBUyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUU7QUFDclksQ0FBQSxTQUFTLE9BQU8sQ0FBQyxNQUFNLEVBQUUsY0FBYyxFQUFFLEVBQUUsSUFBSSxJQUFJLEdBQUcsTUFBTSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLElBQUksTUFBTSxDQUFDLHFCQUFxQixFQUFFLEVBQUUsSUFBSSxPQUFPLEdBQUcsTUFBTSxDQUFDLHFCQUFxQixDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsY0FBYyxLQUFLLE9BQU8sR0FBRyxPQUFPLENBQUMsTUFBTSxDQUFDLFVBQVUsR0FBRyxFQUFFLEVBQUUsT0FBTyxNQUFNLENBQUMsd0JBQXdCLENBQUMsTUFBTSxFQUFFLEdBQUcsQ0FBQyxDQUFDLFVBQVUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLElBQUksQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksRUFBRSxPQUFPLENBQUMsQ0FBQyxFQUFFLENBQUMsT0FBTyxJQUFJLENBQUMsRUFBRTtBQUNyVixDQUFBLFNBQVMsYUFBYSxDQUFDLE1BQU0sRUFBRSxFQUFFLEtBQUssSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxTQUFTLENBQUMsTUFBTSxFQUFFLENBQUMsRUFBRSxFQUFFLEVBQUUsSUFBSSxNQUFNLEdBQUcsSUFBSSxJQUFJLFNBQVMsQ0FBQyxDQUFDLENBQUMsR0FBRyxTQUFTLENBQUMsQ0FBQyxDQUFDLEdBQUcsRUFBRSxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsR0FBRyxPQUFPLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDLFVBQVUsR0FBRyxFQUFFLEVBQUUsZUFBZSxDQUFDLE1BQU0sRUFBRSxHQUFHLEVBQUUsTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLEdBQUcsTUFBTSxDQUFDLHlCQUF5QixHQUFHLE1BQU0sQ0FBQyxnQkFBZ0IsQ0FBQyxNQUFNLEVBQUUsTUFBTSxDQUFDLHlCQUF5QixDQUFDLE1BQU0sQ0FBQyxDQUFDLEdBQUcsT0FBTyxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxVQUFVLEdBQUcsRUFBRSxFQUFFLE1BQU0sQ0FBQyxjQUFjLENBQUMsTUFBTSxFQUFFLEdBQUcsRUFBRSxNQUFNLENBQUMsd0JBQXdCLENBQUMsTUFBTSxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLE9BQU8sTUFBTSxDQUFDLEVBQUU7QUFDMWYsQ0FBQSxTQUFTLGVBQWUsQ0FBQyxHQUFHLEVBQUUsR0FBRyxFQUFFLEtBQUssRUFBRSxFQUFFLEdBQUcsR0FBRyxjQUFjLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxJQUFJLEdBQUcsSUFBSSxHQUFHLEVBQUUsRUFBRSxNQUFNLENBQUMsY0FBYyxDQUFDLEdBQUcsRUFBRSxHQUFHLEVBQUUsRUFBRSxLQUFLLEVBQUUsS0FBSyxFQUFFLFVBQVUsRUFBRSxJQUFJLEVBQUUsWUFBWSxFQUFFLElBQUksRUFBRSxRQUFRLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQyxFQUFFLE1BQU0sRUFBRSxHQUFHLENBQUMsR0FBRyxDQUFDLEdBQUcsS0FBSyxDQUFDLEVBQUUsQ0FBQyxPQUFPLEdBQUcsQ0FBQyxFQUFFO0FBQzVPLENBQUEsU0FBUyxjQUFjLENBQUMsR0FBRyxFQUFFLEVBQUUsSUFBSSxHQUFHLEdBQUcsWUFBWSxDQUFDLEdBQUcsRUFBRSxRQUFRLENBQUMsQ0FBQyxDQUFDLE9BQU8sT0FBTyxHQUFHLEtBQUssUUFBUSxHQUFHLEdBQUcsR0FBRyxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUMsRUFBRTtBQUMzSCxDQUFBLFNBQVMsWUFBWSxDQUFDLEtBQUssRUFBRSxJQUFJLEVBQUUsRUFBRSxJQUFJLE9BQU8sS0FBSyxLQUFLLFFBQVEsSUFBSSxLQUFLLEtBQUssSUFBSSxFQUFFLE9BQU8sS0FBSyxDQUFDLENBQUMsSUFBSSxJQUFJLEdBQUcsS0FBSyxDQUFDLE1BQU0sQ0FBQyxXQUFXLENBQUMsQ0FBQyxDQUFDLElBQUksSUFBSSxLQUFLLFNBQVMsRUFBRSxFQUFFLElBQUksR0FBRyxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUMsS0FBSyxFQUFFLElBQUksSUFBSSxTQUFTLENBQUMsQ0FBQyxDQUFDLElBQUksT0FBTyxHQUFHLEtBQUssUUFBUSxFQUFFLE9B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RyxDQUFDLENBQUMsR0FBRyxJQUFJLEtBQUssQ0FBQyxNQUFNLENBQUMsTUFBTSxHQUFHLENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLE1BQU0sR0FBRyxDQUFDLENBQUMsS0FBSyxFQUFFLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsS0FBSyxFQUFFLENBQUM7QUFDN0ksQ0FBQyxHQUFHLEVBQUUsQ0FBQztBQUNQLENBQUM7O0FDckNNLE1BQU0sVUFBVSxHQUFHO0FBQzFCLENBQUMsS0FBSztBQUNOLENBQUMsS0FBSztBQUNOLENBQUMsTUFBTTtBQUNQLENBQUMsS0FBSztBQUNOLENBQUMsTUFBTTtBQUNQLENBQUMsTUFBTTtBQUNQLENBQUMsS0FBSztBQUNOLENBQUMsS0FBSztBQUNOLENBQUMsS0FBSztBQUNOLENBQUMsS0FBSztBQUNOLENBQUMsS0FBSztBQUNOLENBQUMsS0FBSztBQUNOLENBQUMsS0FBSztBQUNOLENBQUMsS0FBSztBQUNOLENBQUMsS0FBSztBQUNOLENBQUMsS0FBSztBQUNOLENBQUMsS0FBSztBQUNOLENBQUMsTUFBTTtBQUNQLENBQUMsS0FBSztBQUNOLENBQUMsS0FBSztBQUNOLENBQUMsTUFBTTtBQUNQLENBQUMsS0FBSztBQUNOLENBQUMsS0FBSztBQUNOLENBQUMsS0FBSztBQUNOLENBQUMsSUFBSTtBQUNMLENBQUMsS0FBSztBQUNOLENBQUMsSUFBSTtBQUNMLENBQUMsS0FBSztBQUNOLENBQUMsS0FBSztBQUNOLENBQUMsS0FBSztBQUNOLENBQUMsS0FBSztBQUNOLENBQUMsTUFBTTtBQUNQLENBQUMsS0FBSztBQUNOLENBQUMsS0FBSztBQUNOLENBQUMsS0FBSztBQUNOLENBQUMsS0FBSztBQUNOLENBQUMsS0FBSztBQUNOLENBQUMsS0FBSztBQUNOLENBQUMsS0FBSztBQUNOLENBQUMsS0FBSztBQUNOLENBQUMsS0FBSztBQUNOLENBQUMsTUFBTTtBQUNQLENBQUMsTUFBTTtBQUNQLENBQUMsS0FBSztBQUNOLENBQUMsS0FBSztBQUNOLENBQUMsS0FBSztBQUNOLENBQUMsS0FBSztBQUNOLENBQUMsTUFBTTtBQUNQLENBQUMsS0FBSztBQUNOLENBQUMsS0FBSztBQUNOLENBQUMsS0FBSztBQUNOLENBQUMsS0FBSztBQUNOLENBQUMsTUFBTTtBQUNQLENBQUMsTUFBTTtBQUNQLENBQUMsT0FBTztBQUNSLENBQUMsS0FBSztBQUNOLENBQUMsS0FBSztBQUNOLENBQUMsS0FBSztBQUNOLENBQUMsS0FBSztBQUNOLENBQUMsS0FBSztBQUNOLENBQUMsSUFBSTtBQUNMLENBQUMsSUFBSTtBQUNMLENBQUMsUUFBUTtBQUNULENBQUMsS0FBSztBQUNOLENBQUMsS0FBSztBQUNOLENBQUMsS0FBSztBQUNOLENBQUMsS0FBSztBQUNOLENBQUMsS0FBSztBQUNOLENBQUMsSUFBSTtBQUNMLENBQUMsS0FBSztBQUNOLENBQUMsR0FBRztBQUNKLENBQUMsSUFBSTtBQUNMLENBQUMsS0FBSztBQUNOLENBQUMsS0FBSztBQUNOLENBQUMsS0FBSztBQUNOLENBQUMsT0FBTztBQUNSLENBQUMsS0FBSztBQUNOLENBQUMsTUFBTTtBQUNQLENBQUMsTUFBTTtBQUNQLENBQUMsTUFBTTtBQUNQLENBQUMsS0FBSztBQUNOLENBQUMsS0FBSztBQUNOLENBQUMsS0FBSztBQUNOLENBQUMsS0FBSztBQUNOLENBQUMsS0FBSztBQUNOLENBQUMsS0FBSztBQUNOLENBQUMsS0FBSztBQUNOLENBQUMsS0FBSztBQUNOLENBQUMsS0FBSztBQUNOLENBQUMsS0FBSztBQUNOLENBQUMsS0FBSztBQUNOLENBQUMsS0FBSztBQUNOLENBQUMsS0FBSztBQUNOLENBQUMsTUFBTTtBQUNQLENBQUMsTUFBTTtBQUNQLENBQUMsS0FBSztBQUNOLENBQUMsS0FBSztBQUNOLENBQUMsS0FBSztBQUNOLENBQUMsSUFBSTtBQUNMLENBQUMsS0FBSztBQUNOLENBQUMsS0FBSztBQUNOLENBQUMsS0FBSztBQUNOLENBQUMsTUFBTTtBQUNQLENBQUMsS0FBSztBQUNOLENBQUMsS0FBSztBQUNOLENBQUMsT0FBTztBQUNSLENBQUMsS0FBSztBQUNOLENBQUMsS0FBSztBQUNOLENBQUMsS0FBSztBQUNOLENBQUMsS0FBSztBQUNOLENBQUMsS0FBSztBQUNOLENBQUMsS0FBSztBQUNOLENBQUMsS0FBSztBQUNOLENBQUMsS0FBSztBQUNOLENBQUMsS0FBSztBQUNOLENBQUMsS0FBSztBQUNOLENBQUMsS0FBSztBQUNOLENBQUMsS0FBSztBQUNOLENBQUMsS0FBSztBQUNOLENBQUMsS0FBSztBQUNOLENBQUMsT0FBTztBQUNSLENBQUMsS0FBSztBQUNOLENBQUMsS0FBSztBQUNOLENBQUMsS0FBSztBQUNOLENBQUMsSUFBSTtBQUNMLENBQUMsS0FBSztBQUNOLENBQUMsSUFBSTtBQUNMLENBQUMsSUFBSTtBQUNMLENBQUMsS0FBSztBQUNOLENBQUMsTUFBTTtBQUNQLENBQUMsS0FBSztBQUNOLENBQUMsS0FBSztBQUNOLENBQUMsS0FBSztBQUNOLENBQUMsTUFBTTtBQUNQLENBQUMsS0FBSztBQUNOLENBQUMsS0FBSztBQUNOLENBQUMsS0FBSztBQUNOLENBQUMsS0FBSztBQUNOLENBQUMsS0FBSztBQUNOLENBQUMsS0FBSztBQUNOLENBQUMsS0FBSztBQUNOLENBQUMsS0FBSztBQUNOLENBQUMsS0FBSztBQUNOLENBQUMsU0FBUztBQUNWLENBQUMsT0FBTztBQUNSLENBQUMsS0FBSztBQUNOLENBQUMsTUFBTTtBQUNQLENBQUMsS0FBSztBQUNOLENBQUMsTUFBTTtBQUNQLENBQUMsQ0FBQztBQUNGO0FBQ08sTUFBTSxTQUFTLEdBQUc7QUFDekIsQ0FBQyxZQUFZO0FBQ2IsQ0FBQyxXQUFXO0FBQ1osQ0FBQyxXQUFXO0FBQ1osQ0FBQyxZQUFZO0FBQ2IsQ0FBQyxZQUFZO0FBQ2IsQ0FBQyxhQUFhO0FBQ2QsQ0FBQyxtQkFBbUI7QUFDcEIsQ0FBQyxtQkFBbUI7QUFDcEIsQ0FBQyxZQUFZO0FBQ2IsQ0FBQyxXQUFXO0FBQ1osQ0FBQyxvQkFBb0I7QUFDckIsQ0FBQywyQkFB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QU8sRUFBRSxDQUFDLE1BQU0sRUFBRSxDQUFDLENBQUMsQ0FBQztBQUM1QyxNQUFNLElBQUksQ0FBQyxXQUFXLENBQUMsT0FBTyxFQUFFLENBQUMsTUFBTSxFQUFFLENBQUMsQ0FBQyxDQUFDO0FBQzVDLE1BQU0sSUFBSSxDQUFDLFdBQVcsQ0FBQyxPQUFPLEVBQUUsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxDQUFDLENBQUM7QUFDNUMsTUFBTSxJQUFJLENBQUMsV0FBVyxDQUFDLE9BQU8sRUFBRSxDQUFDLE1BQU0sRUFBRSxDQUFDLENBQUMsQ0FBQztBQUM1QyxNQUFNLElBQUksQ0FBQyxXQUFXLENBQUMsT0FBTyxFQUFFLENBQUMsTUFBTSxFQUFFLENBQUMsQ0FBQyxDQUFDO0FBQzVDLE1BQU0sSUFBSSxDQUFDLFdBQVcsQ0FBQyxPQUFPLEVBQUUsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxDQUFDLENBQUM7QUFDNUMsTUFBTSxJQUFJLENBQUMsV0FBVyxDQUFDLE9BQU8sRUFBRSxDQUFDLE1BQU0sRUFBRSxDQUFDLENBQUMsQ0FBQztBQUM1QyxNQUFNLElBQUksQ0FBQyxXQUFXLENBQUMsT0FBTyxFQUFFLENBQUMsTUFBTSxFQUFFLENBQUMsQ0FBQyxDQUFDO0FBQzVDLE1BQU0sSUFBSSxDQUFDLFdBQVcsQ0FBQyxPQUFPLEVBQUUsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxDQUFDLENBQUM7QUFDNUMsTUFBTSxJQUFJLENBQUMsV0FBVyxDQUFDLE9BQU8sRUFBRSxDQUFDLE1BQU0sRUFBRSxDQUFDLENBQUMsQ0FBQztBQUM1QyxJQUFJO0FBQ0osR0FBRyxPQUFPO0FBQ1YsSUFBSSxHQUFHLEVBQUUsS0FBSztBQUNkLElBQUksSUFBSSxFQUFFLDhCQUE4QjtBQUN4QyxJQUFJLENBQUM7QUFDTCxHQUFHO0FBQ0g7QUFDQTtBQUNBLEVBQUUsSUFBSSxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsSUFBSSxFQUFFLElBQUksRUFBRSxJQUFJLEVBQUUsSUFBSSxDQUFDLENBQUMsRUFBRTtBQUM1QztBQUNBLEdBQUcsSUFB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QUssV0FBVyxFQUFFO0FBQ3hCLGdCQUFBLE9BQU8sRUFBRSxDQUFDO0FBQ1gsYUFBQTtBQUFNLGlCQUFBO0FBQ0wsZ0JBQUEsT0FBTyxFQUFHLENBQUEsTUFBQSxDQUFBLElBQUksQ0FBRyxDQUFBLE1BQUEsQ0FBQSxlQUFlLENBQUUsQ0FBQztBQUNwQyxhQUFBO0FBQ0YsU0FBQTtBQUFNLGFBQUE7QUFDTCxZQUFBLE9BQU8sRUFBRyxDQUFBLE1BQUEsQ0FBQSxJQUFJLENBQUcsQ0FBQSxNQUFBLENBQUEsZUFBZSxDQUFFLENBQUM7QUFDcEMsU0FBQTtLQUNGLENBQUE7QUFFTSxJQUFBLHFCQUFBLENBQUEsc0JBQXNCLEdBQTdCLFVBQ0UsTUFBYyxFQUNkLE1BQWMsRUFDZCxXQUFtQixFQUFBO1FBRW5CLElBQUksS0FBSyxHQUFHLE1BQU0sQ0FBQyxRQUFRLEVBQUUsQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLENBQUM7QUFDMUMsUUFBQSxLQUFLLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsS0FBSyxDQUFDLE1BQU0sRUFBRSxDQUFDLEVBQUUsRUFBRTtZQUNyQyxJQUFJLEVBQUUsR0FBRyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxDQUFDO0FBQ2xDLFlBQUEsSUFBSSxFQUFFLElBQUksQ0FBQyxDQUFDLEVBQUU7Z0JBQ1osSUFBSSxJQUFJLEdBQUcsRUFBRSxJQUFJLEVBQUUsQ0FBQyxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsQ0FBQztBQUMvQixnQkFBQSxJQUFJLEVBQUUsR0FBRyxFQUFFLElBQUksRUFBRSxDQUFDLEVBQUUsRUFBRSxFQUFFLEVBQUUsR0FBRyxNQUFNLENBQUMsTUFBTSxFQUFFLENBQUM7Z0JBQzdDLE1BQU0sQ0FBQyxZQUFZLENBQUMsV0FBVyxFQUFFLElBQUksRUFBRSxFQUFFLENBQUMsQ0FBQztnQkFDM0MsTUFBTTtBQUNQLGFBQUE7QUFDRixTQUFBO0tBQ0YsQ0FBQTtJQUNILE9BQUMscUJBQUEsQ0FBQTtBQUFELENBOXNCQSxDQUFtRGEsZUFBTSxDQThzQnhEOzs7OyIsInhfZ29vZ2xlX2lnbm9yZUxpc3QiOlswLDEsMiwzLDQsNSw2LDcsOCw5LDEwLDExLDEyLDEzLDE0LDE1LDE2LDE3LDE4LDE5LDIwLDIxLDIyLDIzLDI0LDI1LDI2LDI3LDI4LDI5LDMwLDMxLDMyLDMzLDM0LDM1LDM2LDM3LDM4LDM5LDQwLDQxLDQyLDQzLDQ0LDQ1LDQ2LDQ3LDQ4LDQ5LDUwLDUxLDUyLDUzLDU0LDU1LDU2LDU3LDU4LDU5LDYwLDYxLDYyLDYzLDY0LDY1LDY2LDY3LDY4LDY5LDcwXX0= diff --git a/.obsidian/plugins/obsidian-image-auto-upload-plugin/manifest.json b/.obsidian/plugins/obsidian-image-auto-upload-plugin/manifest.json new file mode 100644 index 0000000..b98761f --- /dev/null +++ b/.obsidian/plugins/obsidian-image-auto-upload-plugin/manifest.json @@ -0,0 +1,10 @@ +{ + "id": "obsidian-image-auto-upload-plugin", + "name": "Image auto upload Plugin", + "version": "3.6.0", + "minAppVersion": "0.10.7", + "description": "This plugin uploads images from your clipboard by PicGo", + "author": "renmu", + "authorUrl": "https://github.com/renmu123/obsidian-image-auto-upload-plugin", + "isDesktopOnly": true +} diff --git a/.obsidian/workspace.json b/.obsidian/workspace.json new file mode 100644 index 0000000..0ed101e --- /dev/null +++ b/.obsidian/workspace.json @@ -0,0 +1,189 @@ +{ + "main": { + "id": "6515734ec8ec4856", + "type": "split", + "children": [ + { + "id": "9aac8742ad1c417c", + "type": "tabs", + "children": [ + { + "id": "1627d09ae486f69c", + "type": "leaf", + "state": { + "type": "markdown", + "state": { + "file": "软件测试/软件测试-软测基础.md", + "mode": "source", + "source": false + } + } + } + ] + } + ], + "direction": "vertical" + }, + "left": { + "id": "7d9cdd2c78820643", + "type": "split", + "children": [ + { + "id": "7bdf743935451396", + "type": "tabs", + "children": [ + { + "id": "7bdfd42654fb2c49", + "type": "leaf", + "state": { + "type": "file-explorer", + "state": { + "sortOrder": "alphabetical" + } + } + }, + { + "id": "04722c6153992570", + "type": "leaf", + "state": { + "type": "search", + "state": { + "query": "复制", + "matchingCase": false, + "explainSearch": false, + "collapseAll": false, + "extraContext": false, + "sortOrder": "alphabetical" + } + } + }, + { + "id": "aba0fce28dc49642", + "type": "leaf", + "state": { + "type": "bookmarks", + "state": {} + } + } + ] + } + ], + "direction": "horizontal", + "width": 352.5 + }, + "right": { + "id": "c478b4c7ee8a6580", + "type": "split", + "children": [ + { + "id": "7405d7cdf96c29e7", + "type": "tabs", + "children": [ + { + "id": "d8965d91c701cdd6", + "type": "leaf", + "state": { + "type": "backlink", + "state": { + "file": "软件测试/软件测试-软测基础.md", + "collapseAll": false, + "extraContext": false, + "sortOrder": "alphabetical", + "showSearch": false, + "searchQuery": "", + "backlinkCollapsed": false, + "unlinkedCollapsed": false + } + } + }, + { + "id": "32a0a6791f655e9d", + "type": "leaf", + "state": { + "type": "outgoing-link", + "state": { + "file": "软件测试/软件测试-软测基础.md", + "linksCollapsed": false, + "unlinkedCollapsed": true + } + } + }, + { + "id": "4f8c1d97ee46fc94", + "type": "leaf", + "state": { + "type": "tag", + "state": { + "sortOrder": "frequency", + "useHierarchy": true + } + } + }, + { + "id": "05c2a27f0f9ada08", + "type": "leaf", + "state": { + "type": "outline", + "state": { + "file": "软件测试/软件测试-软测基础.md" + } + } + } + ] + } + ], + "direction": "horizontal", + "width": 300, + "collapsed": true + }, + "left-ribbon": { + "hiddenItems": { + "switcher:打开快速切换": false, + "graph:查看关系图谱": false, + "canvas:新建白板": false, + "daily-notes:打开/创建今天的日记": false, + "templates:插入模板": false, + "command-palette:打开命令面板": false + } + }, + "active": "1627d09ae486f69c", + "lastOpenFiles": [ + "软件测试/软件测试-移动app特性.md", + "软件测试/软件测试-软测基础.md", + "软件测试/软件测试-黑白盒测试.md", + "软件测试/软件测试-安全测试.md", + "HomeBrew/Mac OS 神器 HomeBrew.md", + "开发工具/安装教程/Portainer.md", + "开发工具/Docker基本命令.md", + "开发工具/安装教程/RabbitMQ.md", + "开发工具/安装教程/Nginx.md", + "开发工具/安装教程/Mysql.md", + "Linux/LINUX常用命令总结.md", + "开发工具/安装教程/MongoDB.md", + "开发工具/安装教程/Redis.md", + "开发工具/Git基本命令.md", + "开发工具/安装教程/Tomcat.md", + "开发工具/Redis基本命令.md", + "开发工具/Node基本命令.md", + "开发工具/安装教程", + "HomeBrew/Git.md", + "青空笔记/Docker笔记/Docker容器技术.md", + "青空笔记/数据结构笔记/数据结构与算法(四).md", + "教程/mac命令.md", + "青空笔记/SpringCloud笔记/SpringCloud笔记(四).md", + "开发工具/Untitled.md", + "开发工具", + "青空笔记/SpringCloud笔记/SpringCloud笔记(三).md", + "青空笔记/SpringCloud笔记/SpringCould笔记(二).md", + "青空笔记/SpringCloud笔记/SpringCloud笔记(一).md", + "未命名.canvas", + "照片/Pasted image 20230803101741.png", + "照片", + "Pasted image 20230803101614.png", + "Pasted image 20230803101543.png", + "数据库系统原理/单元复习资料/数据库第二章.png", + "面试", + "教程/网站面板", + "教程" + ] +} \ No newline at end of file diff --git a/Activti 流程管理.md b/Activti 流程管理.md new file mode 100644 index 0000000..174e449 --- /dev/null +++ b/Activti 流程管理.md @@ -0,0 +1,474 @@ +# Activti流程管理 + + + + + +```java +Activti提供的主要的接口服务,其中主要用到 + +存储库服务(repositoryService):用于管理和操作流程定义和流程部署相关的数据。它提供了一系列方法来查询、创建、更新和删除流程定义、流程部署以及相关的资源文件。 + +运行时服务(runtimeService):用于管理和操作正在执行的流程实例和任务。它允许启动新的流程实例、对流程实例进行操作(如激活、挂起、删除等)、获取当前正在运行的流程实例信息等操作。 + +任务服务(taskService):用于管理和操作与用户任务相关的数据和操作。它允许查询、创建、更新和删除任务,以及对任务进行分配、完成、指派等操作。 + +历史服务(historyService):用于访问和查询与历史数据相关的信息。它提供了查询已完成流程实例、任务、变量等历史数据的能力。通过历史服务,可以获取对流程的审计跟踪和回顾,以及生成历史报告和统计数据。 + +//存储库服务 + +//运行时服务 + +//表单服务 + +//身份服务 + +//任务服务 + +//历史服务 + +//管理服务 + +``` + +## 1、存储库服务 repositoryService + +### 1.全部流程实例激活挂起 + +激活: + +```java +activateProcessDefinitionById(,,) +``` + +根据流程定义的ID激活流程定义。 +第一个参数 是要激活的流程定义的唯一标识符。 +第二个参数 `true` 表示级联激活,即同时激活与该流程定义关联的所有挂起的流程实例。 +第三个参数 `null` 表示没有要激活的特定日期。 + +挂起: + +```java +suspendProcessDefinitionById(,,) +``` + +根据流程定义的ID挂起流程定义。 +第一个参数 是要挂起的流程定义的唯一标识符。 +第二个参数 `true` 表示级联挂起,即同时挂起与该流程定义关联的所有正在执行的流程实例。 +第三个参数 `null` 表示没有要挂起的特定日期。 + +示例: + +```java + /** + * 全部流程实例挂起 + */ + @Test + public void suspendProcessInstance() { + ProcessDefinition leave = repositoryService.createProcessDefinitionQuery().processDefinitionKey("leave").singleResult(); + // 获取到当前流程定义是否为暂停状态 suspended方法为true是暂停的,suspended方法为false是运行的 + boolean suspended = leave.isSuspended(); + if (suspended) { + // 暂定,那就可以激活 + // 参数1:流程定义的id 参数2:是否激活 参数3:时间点 + //多个流程激活 + repositoryService.activateProcessDefinitionById(leave.getId(), true, null); + System.out.println("流程定义:" + leave.getId() + "激活"); + } else { + //多个流程挂起 + repositoryService.suspendProcessDefinitionById(leave.getId(), true, null); + System.out.println("流程定义:" + leave.getId() + "挂起"); + } + } +``` + +### 2.删除流程实例 + +单个删除 + + +```java +deleteDeployment() +``` + +根据流程部署的ID删除相应的流程定义和资源。如果该流程定义已经有流程实例启动,则会删除失败。 +第一个参数 是流程ID + +级联删除 + +```java +deleteDeployment(,true) +``` + +设置为级联删除方式,即使流程定义已经有流程实例启动,也会强制删除流程定义及其相关的流程实例和历史数据。 +第一个参数 是流程ID +第二个参数 true 表示开启级联删除 + +示例: + +```java + /** + * 删除流程定义 + */ + public void deleteDeployment() { + //部署id + String deploymentId = "ce1f3cc0-08cf-11ee-b8cb-e645a9a03302"; + //删除流程定义,如果该流程定义已有流程实例启动则删除时出错 + repositoryService.deleteDeployment(deploymentId); + //设置true 级联删除流程定义,即使该流程有流程实例启动也可以删除,设置为false非级别删除方式 + repositoryService.deleteDeployment(deploymentId, true); + } +``` + +### 3.查询流程实例 + +```java +createProcessDefinitionQuery() +``` + +创建一个流程定义查询对象,用于构建查询条件。 + +```java +orderByProcessDefinitionVersion() +``` +按照流程定义的版本进行排序。 + +```java +desc() +``` + +降序排列,即最新的版本排在前面。 + +```java +list() +``` + +执行查询,并返回符合条件的流程定义结果列表。 + +示例: + +```java + /** + * 查询流程定义 + */ + @Test + public void findProcessDefinitionList() { + List definitionList = repositoryService.createProcessDefinitionQuery() + .orderByProcessDefinitionVersion() + .desc() + .list(); + //输出流程定义信息 + for (ProcessDefinition processDefinition : definitionList) { + System.out.println("流程定义 id= " + processDefinition.getId()); + System.out.println("流程定义 name= " + processDefinition.getName()); + System.out.println("流程定义 key= " + processDefinition.getKey()); + System.out.println("流程定义 Version= " + processDefinition.getVersion()); + System.out.println("流程部署ID = " + processDefinition.getDeploymentId()); + } + } +``` + +### 4.单个文件部署 + +```java +createDeployment() +``` +创建一个流程部署对象,用于部署流程定义和相关资源。 +```java +addClasspathResource("") +``` +从类路径中添加一个 BPMN 文件资源到部署中,路径为 ""。该文件包含了请假申请流程的流程定义。 +参数 是bpmn文件路径 + +```java +addClasspathResource("") +``` +从类路径中添加一个 PNG 文件资源到部署中,路径为 ""。该文件用于流程定义的可视化展示。 +参数 是png文件路径 + +```java +name("") +``` +设置流程部署的名称为 ""。 +参数 流程部署名称 + +```java +deploy() +``` +执行部署操作,将流程定义和资源文件部署到流程引擎中。 + +示例: + +```java + /** + * 单个文件部署 + */ + @Test + public void deployProcess() { + // 流程部署 + Deployment deploy = repositoryService.createDeployment().addClasspathResource("process/leave.bpmn20.xml").addClasspathResource("process/leave.png").name("请假申请流程").deploy(); + System.out.println(deploy.getId()); + System.out.println(deploy.getName()); + } +``` + +## 2、运行时服务 runtimeService + +### 1.启动流程实例 + +```java +startProcessInstanceByKey("") +``` + +按照流程定义的名称(key)启动一个流程实例。流程定义的键通常是在部署流程时设置的唯一标识符。 +参数 是流程的名称 + +示例: + +```java +/** + * 启动流程实例 + */ + @Test + public void startUpProcess() { + //创建流程实例,我们需要知道流程定义的key + ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("leave"); + //输出实例的相关信息 + System.out.println("流程定义id:" + processInstance.getProcessDefinitionId()); + System.out.println("流程实例id:" + processInstance.getId()); + System.out.println("当前活动Id:" + processInstance.getActivityId()); + } +``` + +### 2.单个流程实例激活挂起 + +激活实例流程: + +```java +activateProcessInstanceById() +``` + +挂起实例流程: + +```java +suspendProcessInstanceById() +``` + +示例: + +```java + /** + * 单个流程挂起 + */ + @Test + public void SingleSuspendProcessInstance() { + String processInstanceId = "ce1f3cc0-08cf-11ee-b8cb-e645a9a03302"; + ProcessInstance processInstance = runtimeService.createProcessInstanceQuery().processInstanceId(processInstanceId).singleResult(); + //获取到当前流程定义是否为暂停状态 suspended方法为true代表为暂停 false就是运行的 + boolean suspended = processInstance.isSuspended(); + if (suspended) { + //单个流程激活 + runtimeService.activateProcessInstanceById(processInstanceId); + System.out.println("流程实例:" + processInstanceId + "激活"); + } else { + //单个流程挂起 + runtimeService.suspendProcessInstanceById(processInstanceId); + System.out.println("流程实例:" + processInstanceId + "挂起"); + } + } +``` + +### 3.启动实例流程 + +``` +startProcessInstanceByKey("", ) +``` + +启动一个流程实例 +第一个参数 是启动的流程定义的键(流程名称) +第二个参数 可选参数,表示与流程实例相关联的业务关键字 + +示例: + +```java + /** + * 启动流程实例,添加businessKey + */ + @Test + public void startUpProcessAddBusinessKey() { + String businessKey = "1"; + // 启动流程实例,指定业务标识businessKey,也就是请假申请单id + ProcessInstance processInstance = runtimeService. + startProcessInstanceByKey("leave", businessKey); + // 输出 + System.out.println("业务id:" + processInstance.getBusinessKey()); + } +``` + +### 4.查询流程定义 + + + +```java +runtimeService.createProcessInstanceQuery() +``` + +创建流程实例查询对象 + +```java +processInstanceId() +``` +设置流程实例ID为查询条件 +参数 是流程实例ID + +```java +singleResult() +``` + +执行查询并返回单个结果,即符合条件的唯一流程实例 + + + + +```java + /** + * 单个流程挂起 + */ + @Test + public void SingleSuspendProcessInstance() { + String processInstanceId = "ce1f3cc0-08cf-11ee-b8cb-e645a9a03302"; + ProcessInstance processInstance = runtimeService.createProcessInstanceQuery().processInstanceId(processInstanceId).singleResult(); + //获取到当前流程定义是否为暂停状态 suspended方法为true代表为暂停 false就是运行的 + boolean suspended = processInstance.isSuspended(); + if (suspended) { + //单个流程激活 + runtimeService.activateProcessInstanceById(processInstanceId); + System.out.println("流程实例:" + processInstanceId + "激活"); + } else { + //单个流程挂起 + runtimeService.suspendProcessInstanceById(processInstanceId); + System.out.println("流程实例:" + processInstanceId + "挂起"); + } + } +``` + + + +## 3、任务服务 taskService + +### 1.完成任务 + +```java +complete() +``` + +用于完成当前用户任务的方法 +参数 任务ID + +示例: + +```java + /** + * 完成任务 + */ + @Test + public void completTask() { + //要查询的负责人 + Task task = taskService.createTaskQuery().taskAssignee("zhangsan").singleResult();//返回一条 + + //完成任务,参数:任务id + taskService.complete(task.getId()); + } +``` + +### 2.查询当前个人待执行任务 + +```java +createTaskQuery +``` + +创建任务查询对象 + + taskAssignee(assignee) + +设置任务负责人的查询条件 +参数 是查询的任务负责人的名称 + +``` +list() +``` + +执行查询操作并返回查询结果 + +示例: + +```java + /** + * 查询当前个人待执行的任务 zhangsan + */ + @Test + public void findPendingTaskList() { + //任务负责人 + String assignee = "zhangsan"; + List list = taskService.createTaskQuery() + .taskAssignee(assignee)//只查询该任务负责人的任务 + .list(); + for (Task task : list) { + System.out.println("流程实例id:" + task.getProcessInstanceId()); + System.out.println("任务id:" + task.getId()); + System.out.println("任务负责人:" + task.getAssignee()); + System.out.println("任务名称:" + task.getName()); + } + } +``` + +## 4、历史服务 historyService + +### 1.查询已处理任务 + +```java +createHistoricTaskInstanceQuery() +``` + +创建一个历史任务实例查询对象,用于执行历史任务的查询操作 + + +```java +taskAssignee("") +``` + +设置查询条件,只返回指定负责人的历史任务 +参数 是指定负责人的名称 + + +```java +finished() +``` + +只返回已完成的历史任务 + + +```java +list() +``` + +执行查询操作并返回查询结果 + +示例: + +```java + /** + * 查询已处理历史任务 + */ + @Test + public void findProcessedTaskList() { + //张三已处理过的历史任务 + List list = historyService.createHistoricTaskInstanceQuery().taskAssignee("zhangsan").finished().list(); + for (HistoricTaskInstance historicTaskInstance : list) { + System.out.println("流程实例id:" + historicTaskInstance.getProcessInstanceId()); + System.out.println("任务id:" + historicTaskInstance.getId()); + System.out.println("任务负责人:" + historicTaskInstance.getAssignee()); + System.out.println("任务名称:" + historicTaskInstance.getName()); + } + } +``` diff --git a/HomeBrew/Git.md b/HomeBrew/Git.md new file mode 100644 index 0000000..ea0eb46 --- /dev/null +++ b/HomeBrew/Git.md @@ -0,0 +1,65 @@ +# HomeBrew 安装 Git + +Git 是一个开源的分布式版本控制系统,用于敏捷高效地处理任何或小或大的项目。Git 是 Linus Torvalds 为了帮助管理 Linux 内核开发而开发的一个开放源码的版本控制软件。Git 与常用的版本控制工具 CVS, Subversion 等不同,它采用了分布式版本库的方式,不必服务器端软件支持。 + +此处使用 homebrew 安装,先确保安装Homebrew后再进行后续操作 + +先在终端输入下面命令查看是否安装HomeBrew + +``` +brew -v +``` + +未安装可以看这篇文章安装 [Mac OS 神器 HomeBrew](https://blog.hhdxw.top/archives/242) + +### 查看搜索可安装 + +```shell +brew install git +``` + +### 安装Git + +```shell +brew install git +``` + +### 查看Git版本 + +```shell +git --version +``` + +### 配置 SSH key + +### 输入如下命令产生新的key + +```shell +ssh-keygen -t rsa -C "your_email@example.com" +``` + +### 将SSH key添加到Github + +登录到Github页面 -> 右上角Setttings -> SSH keys ->Add key + +查看生成的key内容: + +```shell +cat ~/.ssh/id_rsa.pub +``` + +将以上内容复制到 Github ==> Setting ==>Key 中完成添加新的key。 + +## 配置Git用户信息 + +```shell +git config --global user.name "你的名字或昵称" +git config --global user.email "你的邮箱" +``` + +### 卸载命令 + +```text +brew uninstall git +``` + diff --git a/HomeBrew/Mac OS 神器 HomeBrew.md b/HomeBrew/Mac OS 神器 HomeBrew.md new file mode 100644 index 0000000..7492fd8 --- /dev/null +++ b/HomeBrew/Mac OS 神器 HomeBrew.md @@ -0,0 +1,194 @@ +# Mac OS 开发神器 HomeBrew + +Homebrew 是一款适用于 macOS 系统的自由及开放源代码软件包管理系统,旨在使软件安装更加简单。Homebrew 提供了一个方便的命令行界面,允许用户通过简单的命令来安装、更新和卸载许多常用的开源软件包,如 Git、Python、Node.js 等等。Homebrew 可以帮助你轻松地维护你的软件环境,并且可以让你在使用 macOS 的同时也能够享受到 Linux 的软件包管理方式。使用 Homebrew,你可以避免手动编译和安装软件包,节省你的时间和精力。 + +首先是HomeBrew的官网 https://brew.sh/index_zh-cn + +那么我们就先来安装homebrew + +## Homebrew 安装命令 + +在 Mac 上安装 Homebrew: + +```shell +/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)" +``` + +在 Linux 上安装 Homebrew: + +```shell + /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)" +``` + +在 Windows 上安装 Homebrew: + +```shell +N/A(homebrew 暂时不支持windows) +``` + +上面的都是国外的镜像源没有科技的小伙伴们的速度都会比较慢,下面是一些国内镜像源的安装地址 + +中科大镜像源: + +```shell +/bin/bash -c "$(curl -fsSL https://mirrors.ustc.edu.cn/brew-install/install.sh)" +``` + +清华镜像源: + +```shell +/bin/bash -c "$(curl -fsSL https://mirrors.tuna.tsinghua.edu.cn/homebrew/install/master/install.sh)" +``` + +阿里云镜像源: + +```shell +/bin/bash -c "$(curl -fsSL https://mirrors.aliyun.com/homebrew/install/install.sh)" +``` + +## Homebrew 常用命令 + +其中``为需要安装的包名,例如:node + +### 1、搜索软件包: + +这个命令用于查找 Homebrew 中包含特定关键字的软件包。可以在 `` 参数中输入任何与要查找的软件包相关的词汇或名称,Homebrew 会返回所有包含该词的软件包列表 + +```shell +brew search +``` + +### 2、安装软件包: + +这个命令可以安装指定的软件包 + +```shell +brew install +``` + +### 3、卸载软件包: + +这个命令可以卸载指定的软件包 + +```shell +brew uninstall +``` + +### 4、更新 Homebrew: + +这个命令可以更新 Homebrew 自身,包括 Homebrew 的程序代码、依赖项和其他组件 + +```shell +brew update +``` + +### 5、查看哪些软件需要更新: + +这个命令用于显示已安装软件包中哪些需要更新 + +```shell +brew outdated +``` + +### 6、升级已安装的软件包: + +这个命令用于升级所有已安装的软件包。 + +```shell +brew upgrade +``` + +### 7、查看已安装的软件包: + +这个命令可以列出已安装的所有软件包。 + +```shell +brew list +``` + +### 8、更新指定的包 + +使用这个命令可以只升级指定的软件包。 + +``` +brew upgrade +``` + +### 9、清理所有包的旧版本 + +这个命令可以清理所有软件包的旧版本 + +``` +brew cleanup +``` + +### 10、显示软件包信息: + +这个命令可以显示有关指定软件包的详细信息,包括版本、依赖项和安装路径等 + +```shell +brew info +``` + +### 11、切换指定包版本: + +这个命令用于切换已经安装的软件包到指定版本 + +这个命令查看是否存在想要切换的版本 + +```shell +brew search +``` + +这个命令切断当前版本的链接 + +```shell +brew unlink @ +``` + +这个命令连接新版本的链接 + +```shell +brew link @ +``` + +### 12、显示已安装软件包的依赖关系 + +这个命令可以查看已安装软件包的依赖关系 + +```shell +brew deps +``` + +### 13、显示软件包安装目录 + +这个命令可以查看软件包的安装目录 + +```shell +brew --prefix +``` + +### 14、显示软件包的版本号 + +这个命令可以查看软件包的版本号、依赖关系和安装路径等信息 + +```shell +brew info +``` + +### 15、更改国内镜像源 + +由于某些网络限制或其他原因,Homebrew 在国内可能会受到网络访问不畅的影响。可以通过更改国内镜像源来解决这个问题。例如,要将 Homebrew 镜像源更改为中科大镜像源,可以使用以下命令: + +```shell +/bin/bash -c "$(curl -fsSL https://cdn.jsdelivr.net/gh/ineo6/homebrew-install/install/install.sh)" +``` + +### 16、查看 Homebrew 版本号 + +这个命令查看当前安装的 Homebrew 版本号。 + +```shell +brew --version +``` + diff --git a/HomeBrew/Node.md b/HomeBrew/Node.md new file mode 100644 index 0000000..198d7d3 --- /dev/null +++ b/HomeBrew/Node.md @@ -0,0 +1,82 @@ +# HomeBrew 安装 Node.js + +简单的说 Node.js 就是运行在服务端的 JavaScript。Node.js 是一个基于 Chrome JavaScript 运行时建立的一个平台。Node.js 是一个事件驱动 I/O 服务端 JavaScript 环境,基于 Google 的 V8 引擎,V8 引擎执行 Javascript 的速度非常快,性能非常好。 + +此处使用 homebrew 安装,先确保安装Homebrew后再进行后续操作 + +先在终端输入下面命令查看是否安装HomeBrew + +``` +brew -v +``` + +未安装可以看这篇文章安装 [Mac OS 神器 HomeBrew](https://blog.hhdxw.top/archives/242) + +### 搜索可安装的Node + +```shell +brew search node +``` + +### 安装Node + +安装默认版本 + +```shell +brew install node +``` + +安装指定版本 + +```shell l +brew install node@18 +``` + +### 卸载Node + +```shell +brew unistall node +``` + +### 查看Node版本 + +```shell +node -v +``` + +### 切换Node版本 + +切断16版本链接 + +```shell +brew unlink node@16 +``` + +链接18版本 + +```shell +brew link --overwrite --force node@18 +``` + +其中 Homebrew 包管理器中,`--overwrite` 和 `--force` 是两个选项,它们的作用如下: + +1. `--overwrite` 选项 + +当 Homebrew 安装一个包时,如果这个包已经存在于系统中,Homebrew 默认会跳过这个包的安装。但是,如果您希望强制安装一个已经存在的包,可以使用 `--overwrite` 选项。 + +使用 `--overwrite` 选项可能会覆盖您系统中已经存在的一些文件,因此需要小心使用。请确保在使用这个选项前,已经备份了您的系统数据。 + +1. `--force` 选项 + +`--force` 选项是针对在 Homebrew 中进行软件包安装或卸载时出现错误的情况。有时,当您尝试安装或卸载一个软件包时,Homebrew 会输出一些警告或错误,阻止您完成操作。如果您确定这个操作是安全的,可以使用 `--force` 选项强制执行这个操作。 + +和 `--overwrite` 选项一样,`--force` 选项可能会导致系统中的文件被覆盖或者删除,因此也需要小心使用。它可能会破坏系统的稳定性,因此必须谨慎使用。 + +总之,`--overwrite` 和 `--force` 选项都是使 Homebrew 绕过某些限制和警告的选项,并且需要小心使用。在进行任何系统操作之前,请务必了解它们的意义和作用,并且备份您的系统数据。 + +### 卸载命令 + +```text +brew uninstall node +``` + diff --git a/HomeBrew/smartctl 硬盘读写查看.md b/HomeBrew/smartctl 硬盘读写查看.md new file mode 100644 index 0000000..6e50584 --- /dev/null +++ b/HomeBrew/smartctl 硬盘读写查看.md @@ -0,0 +1,54 @@ +# smartctl 硬盘读写查看 + +`smartctl` 是一款基于命令行的磁盘自我监测分析报告技术(Self-Monitoring, Analysis and Reporting Technology,简称 SMART)工具,用于对硬盘进行读写测试、状态检查以及管理。它能够获取硬盘的各种指标信息,如温度、错误率、剩余寿命等,并通过判断这些指标信息来评估硬盘的健康状态。 + +此处使用 homebrew 安装,先确保安装Homebrew后再进行后续操作 + +先在终端输入下面命令查看是否安装HomeBrew + +``` +brew -v +``` + +未安装可以看这篇文章安装 [Mac OS 神器 HomeBrew](https://blog.hhdxw.top/archives/242) + +在 macOS 系统中,可以通过 Homebrew 软件包管理器安装 `smartctl` 命令,步骤如下: + +### 更新 Homebrew 软件包管理器 + +```shell +brew update +``` + +### 搜索可安装 + +``` +brew search smartmontools +``` + +### 安装 smartmontools + +```shell +brew install smartmontools +``` + +### 显示硬盘的 SMART 信息 + +```shell +smartctl -a /dev/disk0 +``` + +其中,`-a` 选项用于显示所有可用的 SMART 信息,`/dev/disk0` 表示要检测的硬盘设备文件。 + +![c87f114b790cfba15db88f5e1d1d9e96](https://yovinchen-1308133012.cos.ap-beijing.myqcloud.com/c87f114b790cfba15db88f5e1d1d9e96.png) + +结果如下,里面的Percentage Used 就是损耗值,Data Units Written 就是写入量。 + +其中这么大的写入读取量全部是由于 mac os 相对激进的 swap 策略 + +### 卸载命令 + +```text +brew uninstall smartmontools +``` + diff --git a/JAVA/JAVA EE/Web程序设计笔记01——第一章:Spring的基本应用.md b/JAVA/JAVA EE/Web程序设计笔记01——第一章:Spring的基本应用.md new file mode 100644 index 0000000..76643a2 --- /dev/null +++ b/JAVA/JAVA EE/Web程序设计笔记01——第一章:Spring的基本应用.md @@ -0,0 +1,283 @@ +# 2021版: + +## Spring的基本应用 + +### 一、idea创建maven项目的过程 + +#### 1.设置idea打开时欢迎页面 + +1.在idea的欢迎页面中点击 Customize 进入自定义设置 + +2.点击 settings 进入系统设置 + + + +![image-20220301163353065](https://yovinchen-1308133012.cos.ap-beijing.myqcloud.com/image-20220301163353065.png) + + + +3.在 settings 中搜索System Settings 并点击 + +4.将 Project 中的 Reopen projects on satrtup 对勾取消 + +5.将下面的 NEW windows 勾选上 + + + +![image-20220301163856266](https://yovinchen-1308133012.cos.ap-beijing.myqcloud.com/image-20220301163856266.png) + + + +即可完成设置欢迎页面。 + +#### 2.idea中创建Maven项目的过程 + +1.打开欢迎页面中的设置(同上面设置) + +2.再设置中搜索 Maven 并进入 + +3.按照图中箭头顺序2更换 apache-maven -3.6.3路径(最好将下载的maven文件解压到除C盘以外的根目录,文件可以在群里下载也可点击此下载) + +4.根据箭头3重写 User settings filer 和 Local repository 的路径(官网下载的maven无repository文件夹,需要自己新建并重命名,更改成和照片相同位置即可)点击OK,完成设置。 + + + +![image-20220301164904720](https://yovinchen-1308133012.cos.ap-beijing.myqcloud.com/image-20220301164904720.png) + + + +5.修改文件maven—conf—setting.xml,用记事本打开文件setting.xml,在其中搜索mirrors节点,找到如图代码区域其中蓝色部分是已经添加的代码,(添加阿里云下载镜像)(注意要添加在两个标签之间,其它配置同理)代码如下: + +```java + + alimaven + aliyun maven + http://maven.aliyun.com/nexus/content/groups/public/ + central + +``` + + + +![image-20220302110623820](https://yovinchen-1308133012.cos.ap-beijing.myqcloud.com/image-20220302110623820.png) + + + +6.搜索 localRepository 将其中路径改为自己仓库位置(蓝色部分,官网下载的maven无repository文件夹,需要自己新建并重命名),保存完成修改。 + + + +![image-20220301170612258](https://yovinchen-1308133012.cos.ap-beijing.myqcloud.com/image-20220301170612258.png) + + + +7.创建maven项目的过程,按照顺序依次选择点击最后next结束 + + + +![image-20220301171039307](https://yovinchen-1308133012.cos.ap-beijing.myqcloud.com/image-20220301171039307.png) + + + +8.其中1是项目名称c01,2.是项目存储路径,3.Groupld是项目名com.gzh(自己名字缩写),4.是版本号不用修改 + + + +![image-20220302110722790](https://yovinchen-1308133012.cos.ap-beijing.myqcloud.com/image-20220302110722790.png) + + + +9.这里应该是之前设置的默认项(如果不是如图所示应该重复上面的步骤进行maven配置),点击finish完成创建。 + + + +![image-20220301171713956](https://yovinchen-1308133012.cos.ap-beijing.myqcloud.com/image-20220301171713956.png) + + + +10.进入后会自动安装maven的文件,出现如图所示即安装成功 + + + +![image-20220301172210713](https://yovinchen-1308133012.cos.ap-beijing.myqcloud.com/image-20220301172210713.png) + +### 二、Spring的体系结构 + +#### 1、核心模块(CoreContainer) + +Spring核心模块包含有Core、Beans、Context和Expression Language四个小模块。其中,Core和Beans是整个Spring框架基础部分,也是Spring的核心依赖注入loC与DI的最基本实现,Spring的其他模块大多依赖这两个功能。 + +spring-core:其他模块的基础核心,包含Spring框架的核心工具类,Spring其他模块都要使用该包里面的类。 + +spring-beans:Spring定义bean的支持,负责访问配置文件、创建和管理bean,支持依赖注入和控制反转的相关操作。传说中的bean工厂类就在这个jar包中。 + +spring-context:spring运行时容器,在Core和Beans的基础上,提供对Spring的上下文支持,ApplicationContext是该包的关键,通过它,可以方便快捷的取出依赖注入的Bean。 + +spring-expression:spring表达式语言,帮助Spring在运行时查询和操作对象。支持设置获取对象的属性值,方法的调用 + +#### 2、AOP模块 + +spring-aop:对于代理AOP的支持 + +spring-Aspects:对于AspectJ的AOP支持 + +#### 3、Web模块 + +spring-web:提供基础的web功能,在Web项目中提供Spring的容器 + +spring-webmvc:提供基于Servlet的SpringMVC + +Spring-WebSocket:提供WebSocket功能 + +spring-webmvc-portlet:提供portlet的支持 + +#### 4:数据库模块 + +spring-jdbc:提供jdbc访问数据库的支持,包含Srping对数据库访问操作进行封装的所有类,它提供了一个DBC的抽象层,从而实现对其他厂商的支持。 + +spring-tx:提供对事物的支持 + +spring-orm:提供对象关系-映射的支持,使得Spring可以方便的整合 他第三方ORM库如JAP、Mybatis、Hibernate等 + +spring-oxm:提供对象xml映射支持 + +spring-jms:提供对java消息服务的支持 + +### 三、Spring的入门程序 + +#### 1.基于Java完成接口、实现类、方法的调用。 + +test: + +```java +项目分层: +控制层——调用服务层(用户操作控制层,发送url请求到控制层) +服务层——调用Dao层 +Dao层——和数据库打交道 +``` + +1.在 src->main 下创建两个新文件夹并重命名为 Java 和 resources + + + +![image-20220301180826354](https://yovinchen-1308133012.cos.ap-beijing.myqcloud.com/image-20220301180826354.png) + + + +2.右击名为 Java 的文件选择 Mark Directory as 属性中的 Sources Root (源根) + + + +![image-20220301223812386](https://yovinchen-1308133012.cos.ap-beijing.myqcloud.com/image-20220301223812386.png) + + + +3.右击名为 resources 的文件选择 Mark Directory as 属性中的 Resources Root (源根) + + + +![image-20220301223743212](https://yovinchen-1308133012.cos.ap-beijing.myqcloud.com/image-20220301223743212.png) + +4.在 Java 源包下创建名为 UserDao 接口、名为 UserDaoImpl 的 Java 以及Test测试类 + +代码分别如下 + +```java +// UserDao 接口 +public interface UserDao { + public void say (); +} +``` + +```java +// UserDaoImpl 实现类 +public class UserDaoImpl implements UserDao{ + @Override + public void say() { + System.out.println("UserDao say..."); + } +} + +``` + +```java +//Test 测试类 +public class test { + public static void main(String[] args) { + //调用say方法 + UserDao userDao = new UserDaoImpl(); + userDao.say(); + } +} +``` + + + +#### 2.使用Spring框架完成接口对象的创建及方法的调用。 + +1.导包,在idea中的目录中的pom.xml下找到如照片代码并添加蓝色区域代码(和标签同一级,都应该在标签中) + + + +![image-20220301225430222](https://yovinchen-1308133012.cos.ap-beijing.myqcloud.com/image-20220301225430222.png) + +代码如下: + +```java + + org.springframework + spring-context + 4.3.6.RELEASE + +``` + +完成导包后如图: + +![image-20220301230136985](https://yovinchen-1308133012.cos.ap-beijing.myqcloud.com/image-20220301230136985.png) + + + +可能有部分同学导包的时候保存代码之后未下载,可以试一试重启idea应该可以解决下载问题 + +2.导包完成后在resources文件夹下建立 applicationContext.xml + + + +![image-20220301230431966](https://yovinchen-1308133012.cos.ap-beijing.myqcloud.com/image-20220301230431966.png) + + + +3.并利用Spring框架创建com.wqx.UserDaoImpl类对象userDao,代码如下: + +```java + +``` + + + +![image-20220302102447695](https://yovinchen-1308133012.cos.ap-beijing.myqcloud.com/image-20220302102447695.png) + + + +#### 3.使用Spring框架创建的对象调用方法 + +1.在 Test 测试类下输入代码: + + + +```java +ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml"); + UserDao userDao = (UserDao) applicationContext.getBean("userDao"); + userDao.say(); +``` + + + +点击运行,完成并输出:UserDao say... + + + +![image-20220302104836410](https://yovinchen-1308133012.cos.ap-beijing.myqcloud.com/image-20220302104836410.png) + + + diff --git a/JAVA/JAVA EE/Web程序设计笔记02——第一章:依赖注入.md b/JAVA/JAVA EE/Web程序设计笔记02——第一章:依赖注入.md new file mode 100644 index 0000000..d55d725 --- /dev/null +++ b/JAVA/JAVA EE/Web程序设计笔记02——第一章:依赖注入.md @@ -0,0 +1,145 @@ +# 第一章:Spring的基本应用 + +## 四、依赖注入 + +依赖注入(Dependency Injection)建成DI,与控制反转(IoC)的含义相同 + +依赖注入的作用就是在使用Spring 框架创建对象时,动态地将其所依赖的对象注入Bean组件中,其实现方式通常有两种,一种是属性setter方法注入,另一种是构造方法注入,具体介绍如下: + +属性 setter方法注入:指Spring容器使用setter方法注入被依赖的实例。通过调用无参构造器或无参静态工厂方法实例化 Bean后,调用该Bean的setter 方法,即可实现基于 setter方法的依赖注入。 + +构造方法注入:指Spring容器使用构造方法注入被依赖的实例。基于构造方法的依赖注入通过调用带参数的构造方法来实现,每个参数代表着一个依赖。 + + + +在com.gzh的包下创建UserService接口并创建一个say方法,代码如下: + +```java +public interface UserService { + public void say(); +} +``` + +在com.gzh的包下创建UserServiceImpl实现类,代码如下: + +```java +public class UserServiceImpl implements UserService{ + + //声明UserDao的属性 + private UserDao userDao; + + //添加UserDao属性的setter方法,用于实现依赖注入 + public void setUserDao(UserDao userDao) { + this.userDao = userDao; + } + + //实现接口中的方法 + public void say(){ + //调用userDao中的say()方法,并执行输出语句 + this.userDao.say(); + System.out.println("UserService say Hellow World!"); + } +} +``` + +在applicationContext.xml里面创建一个id为userService的实例 + +```java + + + + +``` + +在com.gzh下创建TestDI实例 + +```java +public class TsetDI { + public static void main(String[] args) { + //1.初始化Spring容器,加载配置文件 + ApplicationContext applicationContext =new ClassPathXmlApplicationContext("applicationContext.xml"); + + //2.通过容器获取UserService实例 + UserService userService =(UserService) applicationContext.getBean("userService"); + + //3.调用实例中的say()方法 + userService.say(); + } +} +``` + +![image-20220303222001817](https://yovinchen-1308133012.cos.ap-beijing.myqcloud.com/image-20220303222001817.png) + +## 1.IOC(控制反转):类对象的创建由程序员转给了Spring框架 + +Spring框架创建类对象的步骤: + +(1)导包5个 + +commons_logging + +spring-context + +spring-beans + +spring-core + +spring-expression + +```java + + org.springframework + spring-context + 4.3.6.RELEASE + +``` + +(2)resources文件夹下创建applicationContext.xml + +```java + + + +``` + +(3)获取Spring框架创建的类对象 + +```java + //使用Spring框架创建对象调用方法 +ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml"); +UserDao userDao = (UserDao) applicationContext.getBean("userDao"); +userDao.say(); +``` + +## 2.DI:依赖注入 + +D:依赖(动词) + +```java +class B{} +class A{ + B b; + void a(){ + b.b(); + } +} +//类的对象作为A类的成员变量,就是A依赖B。 +``` + +I:注入:就是给成员变量赋值 + +Spring 框架如何实现依赖注入? + +直接在配置文件中写如下代码: + +```java + + + + + //name属性值是成员变量,ref属性值是id属性的值 +``` + +# \ No newline at end of file diff --git a/JAVA/JAVA EE/Web程序设计笔记03——第二章:Spring中的Bean.md b/JAVA/JAVA EE/Web程序设计笔记03——第二章:Spring中的Bean.md new file mode 100644 index 0000000..8d31a84 --- /dev/null +++ b/JAVA/JAVA EE/Web程序设计笔记03——第二章:Spring中的Bean.md @@ -0,0 +1,144 @@ +# 第二章:Spring中的Bean + +## 1、Bean的配置 + +如果把Spring看做一个大型工厂,则Spring容器中的Bean就是该工厂的产品。要想使用这个工厂生产和管理Bean,就需要在配置文件中告诉它需要哪些Bean,以及需要使用何种方式将这些Bean装配到一起。 + +**test:Bean的本质就是Java中的类,而Spring中的Bean其实就是对实体类的引用,来生产Java类对象,从而实现生产和管理Bean .** + +XML配置文件的根元素是中包含了多个子元素,每个子元素定义了一个Bean,并描述了该Bean如何被装配到Spring容器中 + +关于元素的常用属性如下表所示: + +| 属性或元素名称 | 描述 | +| :------------: | :----------------------------------------------------------: | +| id | 是一个Bean的唯一标识符,Spring容器对Bean的配置、管理都通过该属性来完成。 | +| name | Spring 容器同样可以通过此属性对容器中的 Bean 进行配置和管理,name 属性中可以为 Bean指定多个名称,每个名称之间用逗号或分号隔开。 | +| class | 该属性指定了 Bean 的具体实现类,它必须是一个完整的类名,使用类的全限定名。 | +| scopes | 用来设定 Bean 实例的作用域,其属性值有:singleton(单例)、prototype(原型)、request、session、global Session、application和 websocket。其默认值为 singleton。 | + +#### 作用域的种类 + +| 作用域名称 | 说明 | +| :---------------: | :----------------------------------------------------------: | +| singleton(单例) | 使用singleton定义的Bean在Spring容器中将只有一个穿例,也就是说,无论有多少个Bean 引用它,始终将指向同一个对象。这也是Spring 容器默认的作用域。 | +| prototype(原型) | 每次通过Spring容器获取的prototype定义的Bean时,容器都将创建一个新的 Bean 实例。 | + +**test:如果在Bean中未指定id和name,则Spring会将class值当作id使用。** + +## 2、构造器实例化 + +首先创建一个Maven项目然后导包 + +```java + + org.springframework + spring-context + 4.3.6.RELEASE + +``` + +然后在 main 文件下面创建Java源码包,并在包下创建名为 com.ssm.instance.constructor 包 并在其下创建 Bean1 类 + +然后在 main 文件创建名为 resources 的 Resources Root (源根)并配置 Bean1 的 id 和 class + +```java + +``` + +然后在 com.ssm.instance.constructor 包下创建 InstanceTest1 类 + +```java +public static void main(String[] args) { + //定义配置文件路径 + String xmlPath = "beans1.xml"; + //ApplicationContext在加载配置文件时,对Bean进行实例化 + ApplicationContext applicationContext = new ClassPathXmlApplicationContext(xmlPath); + Bean1 bean = (Bean1) applicationContext.getBean("bean1"); + System.out.println(bean); + } +``` + +程序执行截图: + +![image-20220309123304518](https://yovinchen-1308133012.cos.ap-beijing.myqcloud.com/image-20220309123304518.png) + +## 3、静态工厂实例化 + +首先在 Java 包下创建一个名为 com.ssm.instance.static_factory 包,然后在其包下创建一个 名为 Bean2 的类以及一个叫做 MyBean2Factory 的类 并在这个类中创建一个静态方法来实现返回 Bean2 实例 + +```java + //使用自己的工厂创建Bean实例 + public static Bean2 createBean(){ + return new Bean2(); + } +``` + +然后在 resources 下创建 beans2.xml 并输入以下代码: + +```java + +``` + +然后在 static_factory 下创建一个名为 InstanceTest2 的测试类, + +```java +public static void main(String[] args) { + + String xmlPath = "beans2.xml"; + + ApplicationContext applicationContext =new ClassPathXmlApplicationContext(xmlPath); + System.out.println(applicationContext.getBean("bean2")); + } +``` + +程序执行截图: + +![image-20220309142136727](https://yovinchen-1308133012.cos.ap-beijing.myqcloud.com/image-20220309142136727.png) + +## 4、实例工厂实例化 + +首先在 Java 文件下面创建一个名为 com.ssm.instance.factory 的包,并在其下面创建一个名为 Bean3 的类和一个名为 MyBean3Factory 的类,创建 Bean3 的实例方法,输入以下代码: + +```java + public MyBean3Factory (){ + System.out.println("Bean3 工厂实例化中"); + } + + //创建 Bean3 实例的方法 + public Bean3 createBean(){ + return new Bean3(); + } +``` + +在 resources 下创建 beans3.xml 并输入以下代码: + +```java + + + + + +``` + +然后在 factory 下创建一个名为 InstanceTest3 的测试类,并输入以下代码: + +```java +public static void main(String[] args) { + //指定配置文件路径 + String xmlPath = "beans3.xml"; + //ApplicationContext在加载配置文件时,对Bean进行实例化 + ApplicationContext applicationContext = new ClassPathXmlApplicationContext(xmlPath); + System.out.println(applicationContext.getBean("bean3")); +} +``` + +程序执行截图: + +![image-20220309144326438](https://yovinchen-1308133012.cos.ap-beijing.myqcloud.com/image-20220309144326438.png) \ No newline at end of file diff --git a/JAVA/JAVA EE/Web程序设计笔记04——第二章:Spring中的Bean.md b/JAVA/JAVA EE/Web程序设计笔记04——第二章:Spring中的Bean.md new file mode 100644 index 0000000..4751386 --- /dev/null +++ b/JAVA/JAVA EE/Web程序设计笔记04——第二章:Spring中的Bean.md @@ -0,0 +1,388 @@ +# 第二章:Spring中的Bean + +## 9.基于XML的装配 + +### 什么是Bean的装配? + +Bean的装配可以理解为依赖关系注入,Bean的装配方式即Bean依赖注入的方式。Spring容器支持多种形式的Bean的装配方式,如基于XML的装配、基于注解(Annotation)的装配和自动装配(其中最常用的是基于注解的装配),本节将主要讲解这三种装配方式的使用。 + + + +1.在 java 包下创建名为 com.ssm.assemble 的包并在包下创建名为 User 的类,输入(利用生成构造函数、setter方法和toString方法) + +代码如下: + +```java +private String username; + private Integer password; + private List list; + +// 1.使用构造注入 +// 1.1提供所有参数的有参构造方法。 + + public User(String username, Integer password, List list) { + this.username = username; + this.password = password; + this.list = list; + } + +// 2.使用设值注入 +// 2.2提供默认空参构造方法 +// 2.3为所有属性提供setter方法 + + + public User() { + super(); + } + + public void setUsername(String username) { + this.username = username; + } + + public void setPassword(Integer password) { + this.password = password; + } + + public void setList(List list) { + this.list = list; + } + + @Override + public String toString() { + return "User{" + + "username='" + username + '\'' + + ", password=" + password + + ", list=" + list + + '}'; + } +``` + +2.在 resources 文件下创建名为 beans5.xml 的文件并通过两种方法装配User实例 + +代码如下: + +```java + + + + + + + + "constructorvalue1 + "constructorvalue2 + + + + + + + + + + + + "setlistvalue1" + "setlistvalue2" + + + +``` + +3.在 com.ssm.assemble 包下创建 XmlBeanAssembleTest 测试类,并运行程序 + +代码如下: + +```java +// 定义配置文件路径 + String xmlPath = "beans5.xml"; +// 加载配置文件 + ApplicationContext applicationContext = new ClassPathXmlApplicationContext(xmlPath); +// 构造方法输出结果 + System.out.println(applicationContext.getBean("user1")); +// 构造方法输出结果 + System.out.println(applicationContext.getBean("user2")); +``` + +运行结果如图: + +![image-20220310180658138](https://yovinchen-1308133012.cos.ap-beijing.myqcloud.com/image-20220310180658138.png) + +### 总结:基于XML的装配使用方式: + +:one:创建 Java 类,提供有参无参构造方法以及属性 setter 方法 + +:two:创建 Spring 的 xml 配置文件使用两种方式配置Bean; + +:three:创建测试类,测试程序 + +## 10.基于Annotation的装配 + +通过在类上方和成员变量上方添加注解 + +SSM项目分三层: +Dao层:接口和实现类——和数据库打交道 + +```java +//UserDaoImpl 类注解 +@Repository("userDao") +``` + +服务层:接口和实现类——调用Dao层 + +```java +//UserServiceImpl 类注解 +@Service("userService") + +//UserServiceImpl 成员变量注解 +@Resource(name = "userDao") +``` + +控制层:类——调用服务层 + +```java +//UserController 类注解 +@Resource(name = "userDao") +//UserController 成员变量注解 +@Controller("userController") +``` + + + +### 1.首先实现三层结构: + +创建 com.ssm.annotation 包并在其包下进行以下操作 + +##### Dao层 + +创建 UserDao 接口,代码如下: + +```java +package com.ssm.annotation; + +public interface UserDao { + public void save(); +} +``` + +创建 UserDaoImpl 实现类,代码如下: + +```java +package com.ssm.annotation; + +public class UserDaoImpl implements UserDao { + @Override + public void save() { + System.out.println("userDao...save..."); + } +} +``` + +##### 服务层 + +创建 UserService 接口,代码如下: + +```java +package com.ssm.annotation; + +public interface UserService { + public void save(); +} +``` + +创建 UserServiceImpl 实现类,代码如下: + +```java +package com.ssm.annotation; + +public class UserServiceImpl implements UserService{ + private UserDao userDao; + @Override + public void save(){ + userDao.save(); + System.out.println("Userservice...save..."); + } +} +``` + +可以称为服务层调Dao层 + +##### 控制层 + +创建一个 UserController 控制器,代码如下: + +```java +package com.ssm.annotation; + +public class UserController { + private UserService userService; + public void save() { + userService.save(); + System.out.println("userController...save..."); + } +} +``` + +### 2.装配 + +对Dao层的实现类上方添加注解 + +```java +//相当于在xml文件中写 +@Repository("userDao") +//Repository 仓库 Dao层需要数据库打交道 +``` + +对服务层的实现类以及成员变量上方添加注解 + +```java +//相当于在xml文件中写 +@Service("userService") + +@Resource(name = "userDao") +``` + +对服务层的实现类和成员变量上方添加注解 + +```java +@Controller("userController") + +@Resource(name = "userService") +``` + +创建 beans6.xml 文件,利用xml文件扫描这些包来实现装配 + +```java + + + + + +``` + +创建 Test 测试类 + +```java +package com.ssm.annotation; + +import org.springframework.context.ApplicationContext; +import org.springframework.context.support.ClassPathXmlApplicationContext; + +public class Test { + public static void main(String[] args) { + ApplicationContext applicationContext = new ClassPathXmlApplicationContext("beans6.xml"); + UserController userController = (UserController) applicationContext.getBean("userController"); + userController.save(); + } +} +``` + +装配成功运行结果如截图如下: + +![image-20220311125821133](https://yovinchen-1308133012.cos.ap-beijing.myqcloud.com/image-20220311125821133.png) + +### 3.自动装配 + +将一个 Bean 自动的注入到其他 Bean 的 property 中,Spring 的元素中包含一个 autwire 属性,我们可以通过设置 autowire 的属性值来自动装配 Bean 。 + +| 属性值 | 说明 | +| :---------------: | :----------------------------------------------------------: | +| default(默认值) | 由的上级标签的 default-autowire 属性值确定。例如default-autowire="byName">,则该元素中的 autowire 属性对应的属性值就为byName。 | +| byNamee | 根据属性的名称自动装配。容器将根据名称查找与属性完全一致的Bean,并将其属性自动装配。 | +| byTypee | 根据属性的数据类型(Type)自动装配,如果一个Bean的数据类型,兼容另一个Bean中属性的数据类型,则自动装配。 | +| constructor | 根据构造函数参数的数据类型,进行byType模式的自动装配。 | +| no | 默认情况下,不使用自动装配,Bean 依赖必须通过 ref元素定义。 | + + +自动装配一定要有 setter 方法 + +分别创建类A、B + +```java +package com.ssm.autoware; + +public class A { + private B b; + + public void setB(B b) { + this.b = b; + } + + void a(){ + b.b(); + System.out.println("a"); + } +} +``` + +```java +package com.ssm.autoware; + +public class B { + void b(){ + System.out.println("b"); + } +} +``` + +填写 xml 装配文件 + +```java + + + + + + +``` + +最后通过 Test 文件测试 + +```java +package com.ssm.autoware; + +import org.springframework.context.ApplicationContext; +import org.springframework.context.support.ClassPathXmlApplicationContext; + +public class Test { + public static void main(String[] args) { + ApplicationContext applicationContext= new ClassPathXmlApplicationContext("beans7.xml"); + A a = (A) applicationContext.getBean("a"); + a.a(); + } +} +``` + +### 2.5作用域 + +| 作用域名称 | 说明 | +| :---------------: | :----------------------------------------------------------: | +| singleton(单例) | 使用singleton定义的Bean在Spring容器中将只有一个实例,也就是说,无论有多少个Bean引用它,始终将指同一个对象。这也是Spring容器默认的作用域。 | +| prototype(原型) | 每次通过 Spring 容器获取的 prototype 定义的 Bean 时,容器都将建一个新的 Bean实例。 | +| requesto | 在一次 HTTP 请求中,容器会返回该 Bean 的同一个实例。对不同的 HTTP 请求则会产生一个新的 Bean,而且该 Bean 仅在当前HTTP Request内有效。 | +| sessione | 在一次 HTTP Session 中,容器会返回该 Bean 的同一个实例。对不同的 HTTP 请求则会产生一个新的 Bean,且该 Bean 仅在当前 HTTP Session 内有效。 | +| globalSessione | 在一个全局的 HTTP Session 中,容器会返回该 Bean 的同一个实例。仅在使用portlet上下文时有效。 | +| applicatione | 为每个 ServletContext 对象创建一个实例。仅在 Web 相关的ApplicationContext中生效。 | +| websocket | 为每个 websocket对象创建一个实例。仅在 Web 相关的ApplicationContext中生效。 | + + + +### 2.8生命周期 + +了解Spring中Bean生命周期有何意义? + +了解Spring中Bean的生命周期的意义就在于,可以利用Bean在其存活期间的特定时刻完成一些相关操作。这种时刻可能有很多,但一般情况下,常会在Bean的postinitiation(初始化后)和predestruction(销毁前)执行一些相关操作。 + +| | | +| :-------------: | :----------------------------------------------------------: | +| singleton作用域 | Spring容器可以管理singleton作用域的Bean的生命周期在此作用域下,Spring能够精确的知道该Bean何时被创建,何时初始化完成,以及何时被销毁。 | +| prototype作用域 | prototype作用域的Bean,Spring只负责创建,当容器创建了Bean实例后,Bean的实例就交给客户端代码来管理,Spring容器将不再跟踪其生命周期。 | + diff --git a/JAVA/JAVA EE/Web程序设计笔记05——第三章:Spring AOP.md b/JAVA/JAVA EE/Web程序设计笔记05——第三章:Spring AOP.md new file mode 100644 index 0000000..6a2fcf5 --- /dev/null +++ b/JAVA/JAVA EE/Web程序设计笔记05——第三章:Spring AOP.md @@ -0,0 +1,272 @@ +# 第三章:Spring AOP + +代理: + +生活中的代理: 代购(代理对象):卖化妆品 代理 韩国卖化妆品的那个商店(被代理对象):卖化妆品 + +代理对象和被代理对象的区别? + +``` +代理对象可以完成被代理对象的功能,除此之外,代理对象还可以添加额外功能 +``` + +示例: + +```java +package com.gzh; +//韩国商店 +public class Shop { + void sell(){ + System.out.println("韩国商店卖化妆品100元"); + } +} + +``` + +```java +package com.gzh; + +public class Daigou { + private Shop shop; + + public void setShop(Shop shop) { + this.shop = shop; + } + + void sell(){ + System.out.println("代购要收十元小费"); + shop.sell(); + System.out.println("代购卖化妆品110元"); + } +} + +``` + +```java +package com.gzh; +//Test类模拟买化妆品的人 +public class Test { + public static void main(String[] args) { + Daigou daigou = new Daigou(); + daigou.setShop(new Shop()); + daigou.sell(); + } +} +``` + +运行截图: + +![image-20220323125142944](https://yovinchen-1308133012.cos.ap-beijing.myqcloud.com/image-20220323125142944.png) + +## AOP术语 + +AOP:面向切面编程 + +(1)Aspect(切面):本质就是类,例如:MyAspect,切面类完成额外功能或非核心业务功能。 + +(2)Joinpoint(连接点):目标方法的调用的前和后都可以称为连接点,目标方法在被代理类中 + +(3)pointcut(切入点):就是 切入了额外功能的 连接点 + +(4)Advice(通知、增强处理):就是额外功能 + +(5)Target Object(目标对象):被代理对象。例如:com.jdk.UserDaoImpl + +(6)Proxy(代理):代理对象 + +(7)Weaving(织入):产生代理对象的过程,例如;createProxy + +## 3.2.1 JDK动态代理 + +代理是谁?(或者说被代理对象是谁)?是实现了接口的类:com.jdk.UserDaoImpl + +额外功能所在的类? MyAspect类 + +如何产生代理对象? JdkProxy类 + +代理对象的额外功能是如何完成的? + +```java +package com.jdk; + +public interface UserDao { + void addUser(); + void deleteUser(); +} +``` + +```java +package com.jdk; +//被代理对象就是这个实现类,该类中的方法叫做目标方法 +public class UserDaoImpl implements UserDao{ + @Override + public void addUser() { + System.out.println("添加用户"); + } + + @Override + public void deleteUser() { + System.out.println("删除用户"); + } +} +``` + +```java +package com.jdk; +//额外的功能:在目标方法调用前,调用check_permission;在目标方法调用后条用log方法 +public class MyAspect { + public void check_permission(){ + System.out.println("模拟权限检查"); + } + public void log(){ + System.out.println("模拟记录日志"); + } +} +``` + +```java +package com.jdk; + +import java.lang.reflect.InvocationHandler; +import java.lang.reflect.Method; +import java.lang.reflect.Proxy; + +//产生代理对象的类 +public class JdkProxy implements InvocationHandler { + private UserDao userDao; + //方法的返回值是代理对象 + public Object createProxy(UserDao userDao){ + this.userDao=userDao; + ClassLoader classLoader= JdkProxy.class.getClassLoader(); + Class[] clazz=userDao.getClass().getInterfaces(); + return Proxy.newProxyInstance(classLoader,clazz,this); + } + //invoke方法就是代理对象完成目标功能和额外功能的方法 + @Override + public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { + MyAspect myAspect=new MyAspect(); + myAspect.check_permission(); + Object obj = method.invoke(userDao,args);//当程序指向到此语句时,转而调用目标方法 + myAspect.log(); + return obj; + } +} +``` + +```java +package com.jdk; + +public class JdkTest { + public static void main(String[] args) { + //被代理对象 + UserDao userDao = new UserDaoImpl(); + userDao.addUser(); + System.out.println("----------------"); + //生成代理对象 + JdkProxy jdkProxy = new JdkProxy(); + UserDao proxy = (UserDao) jdkProxy.createProxy(userDao); + proxy.addUser();//当程序指向到此语句时,转而执行invoke方法 + } +} +``` + +运行截图: + +![image-20220323150132535](https://yovinchen-1308133012.cos.ap-beijing.myqcloud.com/image-20220323150132535.png) + + + +## 3.2.2CGLIB代理 + +代理是谁?(或者说被代理对象是谁)?User类,有两个目标方法:addUser() deleteUser() + +额外功能所在的类? MyAspect类 + +如何产生代理对象? CglibProxy类中的方法 + +代理对象的额外功能是如何完成的? + +```java +package com.cglib; + +public class User { + void addUser() { + System.out.println("添加用户"); + } + + void deleteUser() { + System.out.println("删除用户"); + } +} +``` + +```java +package com.cglib; + +//额外的功能:在目标方法调用前,调用check_permission;在目标方法调用后条用log方法 +public class MyAspect { + public void check_permission() { + System.out.println("模拟权限检查"); + } + + public void log() { + System.out.println("模拟记录日志"); + } +} +``` + +```java +package com.cglib; + +import org.springframework.cglib.proxy.Enhancer; +import org.springframework.cglib.proxy.MethodInterceptor; +import org.springframework.cglib.proxy.MethodProxy; + +import java.lang.reflect.Method; + +public class Cglibproxy implements MethodInterceptor { + public Object createProxy(Object target) { + Enhancer enhancer = new Enhancer(); + enhancer.setSuperclass(target.getClass()); + enhancer.setCallback(this); + return enhancer.create(); + } + + @Override + public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable { + MyAspect myAspect = new MyAspect(); + myAspect.check_permission(); + Object obj = methodProxy.invokeSuper(proxy, args);//程序执行到此条语句时,转而执行目标方法 + myAspect.log(); + return obj; + } +} +``` + +```java +package com.cglib; + +public class cglibTest { + public static void main(String[] args) { + //被代理对象 + User user = new User(); + user.addUser(); + System.out.println("---------------"); + //代理对象 + Cglibproxy cglibProxy = new Cglibproxy(); + User proxy = (User) cglibProxy.createProxy(user); + proxy.addUser();//程序执行到此条语句时,转为执行intercept方法 + } +} + +``` + +运行截图如下: + +![image-20220324113512719](https://yovinchen-1308133012.cos.ap-beijing.myqcloud.com/image-20220324113512719.png) + +JDK代理和CGLIB代理方式的缺点? + +代理对象不管调用哪一种目标方法时,都会调用额外的功能。 + +能不能有一种手段:可以使得程序员自己自由指定那些目标被调用时,调用额外的功能呢?Spring \ No newline at end of file diff --git a/JAVA/JAVA EE/Web程序设计笔记06——第三章:从Spring的角度去实现代理.md b/JAVA/JAVA EE/Web程序设计笔记06——第三章:从Spring的角度去实现代理.md new file mode 100644 index 0000000..e49a394 --- /dev/null +++ b/JAVA/JAVA EE/Web程序设计笔记06——第三章:从Spring的角度去实现代理.md @@ -0,0 +1,277 @@ +# 第三章 + +### 1.代理 + +生活中的代理: 代购 + +从Java的角度去实现代理 + +### 3.2.1 JDK动态代理 + +被代理对象:实现了接口的类 写的就是核心的业务功能 + +切面类:写的是非核心的业务功能 + +生成代理对象的类:JdkProxy + +代码实现同上节课 + +### 3.2.2 CGLIB代理 + +被代理对象:某个类 + +切面类: + +生成代理对象的类:CglibProxy + +代码实现同上节课 + +### AOP 术语: + +AOP:面向切面编程 + +切面类:MyAspect + +连接点: addUser() deleteUser() 调用前或后 + +切入点:就是连接点 + +增强处理/通知:就是切面中的方法 check_permission() log() + +目标对象: 被代理对象 + +代理:代理对象 + +织入:生成代理对象的过程 + + + +### 从Spring的角度去实现代理 + +(1)导包: + 5个核心包:commons-logging spring-context spring-beans spring-core spring-expression + 2个包:spring-aop aoplliance +(2)创建接口和实现类 +(3)创建切面类 +(4)生成代理对象 xml文件 +(5)测试 + +pom.xml文件 + +```java + + org.springframework + spring-context + 4.3.6.RELEASE + + + aopalliance + aopalliance + 1.0 + +``` + +```java +package com.aop; + +public interface UserDao { + void addUser(); + void deleteUser(); +} +``` + +```java +package com.aop; + +public class UserDaoImpl implements UserDao { + @Override + public void addUser() { + System.out.println("添加用户"); + } + + @Override + public void deleteUser() { + System.out.println("删除用户"); + } +} +``` + +```java +package com.aop; + +import org.aopalliance.intercept.MethodInterceptor; +import org.aopalliance.intercept.MethodInvocation; + +public class MyAspect implements MethodInterceptor { + void check_permission() { + System.out.println("模拟权限检查"); + } + + void log() { + System.out.println("模拟记录日志"); + } + + @Override + public Object invoke(MethodInvocation methodInvocation) throws Throwable { + check_permission(); + Object proceed = methodInvocation.proceed();//调用目标方法 + log(); + return proceed; + } +} +``` + +```java + + + + + + + + + + + + + + + + + + + +``` + +```java +package com.aop; + +import org.springframework.context.ApplicationContext; +import org.springframework.context.support.ClassPathXmlApplicationContext; + +public class AopTest { + public static void main(String[] args) { + ApplicationContext applicationContext = + new ClassPathXmlApplicationContext("a.xml"); + //被代理对象 + UserDao userDao = (UserDao) applicationContext.getBean("userDao"); + userDao.addUser(); + System.out.println("------------------------------"); + //代理对象 + UserDao userDaoproxy = (UserDao) applicationContext.getBean("userDaoproxy"); + userDaoproxy.addUser(); + + } +} +``` + +代码实现截图: + +![image-20220324140614514](https://yovinchen-1308133012.cos.ap-beijing.myqcloud.com/image-20220324140614514.png) + + + +不管是从Java角度还是Spring角度实现的代理,有一个共同点(缺点): + +代理对象不管调用哪个目标方法,都会切入切面类中的方法。 + + + +有没有一种手段,可以让代理对象自由地决定调用哪个目标方法时才切入切面类中的方法? + +Aspectj框架实现代理 + +### 补充:异常 + +### 1.异常类 + +#### (1)算术异常: + +java.lang.ArithmeticException: / by zero + +```java +package com.exception; + +public class ExceptionTest { + static int divide(int x,int y){ + int result=x/y; + return result; + } + + public static void main(String[] args){ + int divide = divide(4,0); + System.out.println(divide); + } +} +``` + +![image-20220324142225871](https://yovinchen-1308133012.cos.ap-beijing.myqcloud.com/image-20220324142225871.png) + +#### (2)空指针异常: + +java.lang.NullPointerException + +```java +package com.exception; +class A{ + void a(){} +} +public class ExceptionTest2 { + static A a; + + public static void main(String[] args){ + a.a(); + } +} +``` + +![image-20220324143554018](https://yovinchen-1308133012.cos.ap-beijing.myqcloud.com/image-20220324143554018.png) + +### 2.处理异常 + +#### (1)捕获异常 + +​ try{}catch(){}finally{} +​ finally可以省略,catch可以有多个 + +```java +package com.exception; + +public class ExceptionTest5 { + static int divide(int x,int y) throws Exception{ + int result=x/y; + return result; + } + + public static void main(String[] args) { + try { + divide(4,0); + } catch (Exception e) { + e.printStackTrace(); + } + } +} +``` + +#### (2)抛异常 + +​ throws +​ 当调用了方法抛出异常的方法时,调用者可以继续抛异常,也可捕获异常 + +```java +package com.exception; + +public class ExceptionTest4 { + static int divide(int x,int y) throws Exception{ + int result=x/y; + return result; + } + + public static void main(String[] args) throws Exception { + divide(4,0); + } +} +``` \ No newline at end of file diff --git a/JAVA/JAVA EE/Web程序设计笔记07——第三章:基于AspectJ实现AOP.md b/JAVA/JAVA EE/Web程序设计笔记07——第三章:基于AspectJ实现AOP.md new file mode 100644 index 0000000..5cd7a67 --- /dev/null +++ b/JAVA/JAVA EE/Web程序设计笔记07——第三章:基于AspectJ实现AOP.md @@ -0,0 +1,328 @@ +# 第三章:Spring AOP + +## 复习知识 + +### 1.从java角度出发实现代理 + +JDK动态代理 和 CGLIB代理 的区别: +(1)被代理对象不同 +(2)产生代理对象的类不同 + +### 2.从Spring角度出发实现代理: + +(1)导包:7个包: 5个核心包:commons-logging spring-context spring-beans spring-core spring-expression + 2个包:spring-aop aoplliance +(2)创建被代理对象,实现了某个接口的类 +(3)切面类实现接口 +(4)产生代理对象方式:xml文件 +(5)测试 + +### 3.AOP术语:7个 + +切面类:MyAspect +连接点: addUser() deleteUser() 调用前或后 +切入点:就是连接点 +增强处理/通知:就是切面中的方法 check_permission() log() +目标对象: 被代理对象 +代理:代理对象 +织入:生成代理对象的过程 + +### 4.1和2中实现的代理有一个共同的特点(缺点): + +代理对象不管调用哪一个目标方法,都会切入切面类中的方法 + +### 5.有没有一种手段:让代理对象自由地选择调用哪一个目标方法时才切入切面类中的方法? + +—————————————————————————————————————————————————— + +## 基于AspectJ实现AOP(实现代理) + +### 一、基于xml + +(1)导包:5个核心包:commons-logging spring-context spring-core spring-beans spring-expression + 2个包:spring-aspects aspectjweaver +(2) 创建被代理对象 +(3) 创建切面类 +(4) 创建代理对象:xml文件使用aop编程 +(5) 测试 + +代码实现如下: + +```java +package com.aspectj.xml; + +public interface UserDao { + void addUser(); + void deleteUser(); +} +``` + +```java +package com.aspectj.xml; + +public class UserDaoImpl implements UserDao { + + @Override + public void addUser() { + System.out.println("添加用户"); +// 模拟异常 +// System.out.println(1/0); + } + + @Override + public void deleteUser() { + System.out.println("删除用户"); + } +} +``` + +```java +package com.aspectj.xml; + +import org.aspectj.lang.JoinPoint; +import org.aspectj.lang.ProceedingJoinPoint; + +public class MyAspect { + //前置通知 + public void myBefore(JoinPoint joinPoint){ + System.out.print("前置通知:模拟执行权限检查...,"); + System.out.print("目标类是:"+joinPoint.getTarget()); + System.out.println(",被植入增强处理的目标方法为:"+joinPoint.getSignature().getName()); + } + //后置通知 + public void myAfterRturning(JoinPoint joinPoint) { + System.out.print("后置通知:模拟记录日志..."); + System.out.println("被植入增强处理的目标方法为:" + joinPoint.getSignature().getName()); + } + +// 环绕通知 +// ProceedingJoinPoint 是 JoinPoint 子接口,表示可以执行目标方法 +// 1.必须是 Object 类型的返回值 +// 2.必须接收一个参数,类型为 ProceeddingJoinPoint +// 3.必须 throws Throwable + + public Object myAround(ProceedingJoinPoint proceedingJoinPoint)throws Throwable{ + //开始 + System.out.println("环绕开始:执行目标方法之前,模拟开始事务..."); +// 执行当前目标方法 + Object obj = proceedingJoinPoint.proceed(); + //结束 + System.out.println("环绕结束:执行目标方法之后,模拟关闭事物..."); + return obj; + } + + //异常通知 + public void myAfterThrowing(JoinPoint joinPoint,Throwable e){ + System.out.println("异常通知:"+"出错了"+e.getMessage()); + } + + //最终通知 + public void myAfter(){ + System.out.println("最终通知:模拟方法结束后的释放资源..."); + } +} +``` + +```java + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +``` + +```java +package com.aspectj.xml; + +import org.springframework.context.ApplicationContext; +import org.springframework.context.support.ClassPathXmlApplicationContext; + +public class XmlTest { + public static void main(String[] args) { + ApplicationContext applicationContext = new ClassPathXmlApplicationContext("a.xml"); + UserDao userDao = (UserDao) applicationContext.getBean("userDao"); + userDao.addUser(); + System.out.println("_______________"); + userDao.deleteUser(); + } +} +``` + +正常运行结果: + +![image-20220328214914512](https://yovinchen-1308133012.cos.ap-beijing.myqcloud.com/image-20220328214914512.png) + +运行发生异常截图:出现结果为零异常 + +![image-20220328214954611](https://yovinchen-1308133012.cos.ap-beijing.myqcloud.com/image-20220328214954611.png) + +### 二、基于注解(Annotation)-------减少xml中的代码量 + +(1) 导包 5个核心包:commons-logging spring-context spring-core spring-beans spring-expression + 2个包:spring-aspects aspectjweaver +(2) 创建被代理对象 +(3) 创建切面类 注意:切面类中的注解相当于a.xml文件中的哪一句代码 +(4) 创建xml文件:扫描所有的注解和开启AspectJ实现AOP + +```java +package com.aspectj.annotation; + +public interface UserDao { + void addUser(); + void deleteUser(); +} +``` + +```java +package com.aspectj.annotation; + +import org.springframework.stereotype.Repository; + +//注解实现 +//@Repository("userDao") +public class UserDaoImpl implements UserDao { + + @Override + public void addUser() { + System.out.println("添加用户"); +// 模拟异常 +// System.out.println(1/0); + } + + @Override + public void deleteUser() { + System.out.println("删除用户"); + } +} +``` + +```java +package com.aspectj.annotation; + + +import org.aspectj.lang.JoinPoint; +import org.aspectj.lang.ProceedingJoinPoint; +import org.aspectj.lang.annotation.*; +import org.springframework.stereotype.Component; + +//切面类,在此类中编写通知 +@Aspect +@Component +public class MyAspect { +// 定义切入点表达式 + @Pointcut("execution(* com.aspectj.annotation.*.*(..))") +// 使用一个返回值为 void 、方法体为空的方法来命名切入点 + private void myPointCut(){} +// 前置通知 + @Before("myPointCut()") + public void myBefore(JoinPoint joinPoint){ + System.out.println("前置通知:模拟执行权限检查...,"); + System.out.print("目标类是:"+joinPoint.getTarget()); + System.out.println(",被植入增强处理的目标方法为:"+joinPoint.getSignature().getName()); + } + //后置通知 + @AfterReturning("myPointCut()") + public void myAfterReturning(JoinPoint joinPoint){ + System.out.println("后置通知:模拟记录日志..."); + System.out.println("被植入增强处理的目标方法为:" + joinPoint.getSignature().getName()); + } + //环绕通知 + @Around("myPointCut()") + public Object myAround(ProceedingJoinPoint proceedingJoinPoint)throws Throwable{ + //开始 + System.out.println("环绕开始:执行目标方法之前,模拟开始事务..."); + //执行当前目标方法 + Object obj = proceedingJoinPoint.proceed(); + //结束 + System.out.println("环绕结束:执行目标方法之后,模拟关闭事物..."); + return obj ; + } + //异常通知 + @AfterThrowing(value = "myPointCut()",throwing = "e") + public void myAfterThrowing(JoinPoint joinPoint,Throwable e){ + System.out.println("异常通知:"+"出错了"+e.getMessage()); + } + + //最终通知 + @After("myPointCut()") + public void myAfter(){ + System.out.println("最终通知:模拟方法结束后的释放资源..."); + } +} +``` + +```java + + + + + + + + + +``` + +```java +package com.aspectj.annotation; + +import org.springframework.context.ApplicationContext; +import org.springframework.context.support.ClassPathXmlApplicationContext; + +public class AnnotationTest { + public static void main(String[] args) { + ApplicationContext applicationContext = new ClassPathXmlApplicationContext("b.xml"); + UserDao userDao = (UserDao) applicationContext.getBean("userDao"); + userDao.deleteUser(); + userDao.addUser(); + } +} +``` + +运行截图: + +![image-20220328215304530](https://yovinchen-1308133012.cos.ap-beijing.myqcloud.com/image-20220328215304530.png) \ No newline at end of file diff --git a/JAVA/JAVA EE/Web程序设计笔记08——第四章:Spring的数据库开发.md b/JAVA/JAVA EE/Web程序设计笔记08——第四章:Spring的数据库开发.md new file mode 100644 index 0000000..0d9ae55 --- /dev/null +++ b/JAVA/JAVA EE/Web程序设计笔记08——第四章:Spring的数据库开发.md @@ -0,0 +1,400 @@ +# 第四章:Spring的数据库开发 + +JDBC: Java Database Connector +JdbcTemplate方法 + +## 一、execute() + +#### (1)mysql创建数据库spring + +```mysql +create database spring; +``` + +#### (2)导包 + +五个核心包:commons-logging spring-core spring-beans spring-context spring-expression +其他两个包:spring-jdbc mysql-connector-java + +```java + + org.springframework + spring-context + 4.3.6.RELEASE + + + mysql + mysql-connector-java + 8.0.28 + + + org.springframework + spring-jdbc + 4.3.6.RELEASE + +``` + +#### (3)创建配置文件a.xml + +```java + + + + + + + + + + + + + + + + + + + +``` + +#### (4)测试execute()方法 + +```java +package com.gzh; + +import org.springframework.context.ApplicationContext; +import org.springframework.context.support.ClassPathXmlApplicationContext; +import org.springframework.jdbc.core.JdbcTemplate; + +public class JdbcTest { + public static void main(String[] args) { + ApplicationContext applicationContext =new ClassPathXmlApplicationContext("a.xml"); + JdbcTemplate jdbcTemplate = (JdbcTemplate) applicationContext.getBean("jdbcTemplate"); + String sql="create table account(id int primary key auto_increment,username varchar (50),balance double)"; + jdbcTemplate.execute(sql); + } +} +``` + +运行结果如下:数据库中已经成功创建表account + +![image-20220329195454770](https://yovinchen-1308133012.cos.ap-beijing.myqcloud.com/image-20220329195454770.png) + +## 二、update():增删改 + +实体类对象 转换 表中记录 + +### 实体类: + +​ (1)和表对应,一张表对应一个实体类 + +​ (2)实体类中的成员变量 表中字段一一对应(数据类型 名称) + +​ (3)实体类中的作用就是和表进行数据传输 + +SSM项目分三层:dao层 服务层 控制层,此代码为了简便,只创建dao层 + +​ dao层: +​ 接口:接口中所有方法就是系统的功能。 面向接口编程 +​ 实现类:声明了一个JdbcTemplate类对象 + +### 步骤: + +#### (1)创建实体类 + +```java +package com.gzh.domain; + +public class Account { + private int id; + private String username; + private double balance; + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public String getUsername() { + return username; + } + + public void setUsername(String username) { + this.username = username; + } + + public double getBalance() { + return balance; + } + + public void setBalance(double balance) { + this.balance = balance; + } + + @Override + public String toString() { + return "Account{" + + "id=" + id + + ", username='" + username + '\'' + + ", balance=" + balance + + '}'; + } +} +``` + +#### (2)创建接口 + +```java +package com.gzh.dao; + +import com.gzh.domain.Account; + +public interface AccountDao { + //增加记录 + int addAccount(Account account); + + //删除根据用户ID删除账户 + int deleteById(int id); + + //更新记录 + int updateAccount(Account account); +} +``` + +#### (3)实现接口 + +```java +package com.gzh.dao; + +import com.gzh.domain.Account; +import org.springframework.jdbc.core.JdbcTemplate; + +public class AccountDaoImpl implements AccountDao { + private JdbcTemplate jdbcTemplate; + + public void setJdbcTemplate(JdbcTemplate jdbcTemplate) { + this.jdbcTemplate = jdbcTemplate; + } + + //增加记录 + @Override + public int addAccount(Account account) { + String sql = "insert into account values(?,?,?)"; + int update = jdbcTemplate.update(sql, account.getId(), account.getUsername(), account.getBalance()); + return update; + } + + //删除根据用户ID删除账户 + @Override + public int deleteById(int id) { + String sql = "delete from account where id=?"; + int update = jdbcTemplate.update(sql, id); + return update; + } + + //更新记录 + @Override + public int updateAccount(Account account) { + String sql = "update account set username=?,balance=? where id=?"; + int update = jdbcTemplate.update(sql, account.getUsername(), account.getBalance(), account.getId()); + return update; + } +} +``` + +#### (4)写配置文件 + +```java + + + + + + + + + + + + + + + + + +``` + +#### (5)测试Test方法 + +```java +package com.gzh; + +import com.gzh.dao.AccountDao; +import com.gzh.domain.Account; +import org.junit.Test; +import org.springframework.context.ApplicationContext; +import org.springframework.context.support.ClassPathXmlApplicationContext; + +public class JdbcTest { + ApplicationContext applicationContext = new ClassPathXmlApplicationContext("a.xml"); + AccountDao accountDao = (AccountDao) applicationContext.getBean("accountDao"); + + @Test + //增加记录 + public void addAccountTets() { + Account account = new Account(); + account.setId(1); + account.setUsername("zhangsan"); + account.setBalance(1000); + accountDao.addAccount(account); + } + + @Test + //删除根据用户ID删除账户 + public void deleteByIdTest() { + accountDao.deleteById(1); + } + + @Test + //更新记录 + public void updateAccountTest() { + Account account = new Account(); + account.setUsername("zhangsan"); + account.setBalance(3000); + account.setId(1); + accountDao.updateAccount(account); + } +} +``` + +#### 运行截图: + +1.创建两个数据 + +![image-20220331221520933](https://yovinchen-1308133012.cos.ap-beijing.myqcloud.com/image-20220331221520933.png) + +2.测试删除数据 + +![image-20220331221604934](https://yovinchen-1308133012.cos.ap-beijing.myqcloud.com/image-20220331221604934.png) + +3.更新数据 + +![image-20220331221704292](https://yovinchen-1308133012.cos.ap-beijing.myqcloud.com/image-20220331221704292.png) + +### 补充: + +#### 1.Object + +当方法形参个数不确定的时候,可以使用Object...,代表的是多个多种类型的参数 + +#### 2.基本数据类型 包装类 + +​ int Integer +​ double Double + +``` +int a = 5; +Integer b = a; //装箱 +int c = b; //拆箱 +``` + +#### 3.单元测试 + +可以直接运行一个非main方法的方法 @Test + +```java +public class AccountDao{ + @Test + public void cat(){ + System.out.println("a"); + } + + @Test + public void cat(){ + System.out.println("b"); + } +} +``` + +## 三、query():查 + +表中的记录 转换 实体类对象 + +### 步骤: + +#### (1)创建实体类 + +同上 + +#### (2)创建接口 + +```java +//查询 根据id进行查询 单条记录 +Account findAccountById(int id); + +//查所有记录 +List findAllAccounts(); +``` + +#### (3)实现接口 + +```java +//查询 根据id进行查询 单条记录 +@Override +public Account findAccountById(int id) { + String sql = "select * from account where id =?"; + RowMapper rowMapper = new BeanPropertyRowMapper<>(Account.class); + Account account = jdbcTemplate.queryForObject(sql, rowMapper, id); + return account; +} + +//查所有记录 +@Override +public List findAllAccounts() { + String sql = "select * from account"; + RowMapper rowMapper = new BeanPropertyRowMapper(Account.class); + List account = jdbcTemplate.query(sql, rowMapper); + return account; +} +``` + +#### (4)写配置文件 + +同上 + +#### (5)测试Test方法 + +```java +@Test +//查询 根据id进行查询 单条记录 +public void findAccountByIdTest() { + Account accountById = accountDao.findAccountById(1); + System.out.println(accountById); +} + +@Test +//查所有记录 +public void findAllAccoundsTest() { + List accounts = accountDao.findAllAccounts(); + for (Account i : accounts) { + System.out.println(i); + } +} +``` + +#### 运行截图: + +1.单个查询 + +![image-20220331223326855](https://yovinchen-1308133012.cos.ap-beijing.myqcloud.com/image-20220331223326855.png) + +2.多项查询 + +![image-20220331223422159](https://yovinchen-1308133012.cos.ap-beijing.myqcloud.com/image-20220331223422159.png) + diff --git a/JAVA/JAVA EE/Web程序设计笔记09——第五章:Spring的事务管理.md b/JAVA/JAVA EE/Web程序设计笔记09——第五章:Spring的事务管理.md new file mode 100644 index 0000000..fffb967 --- /dev/null +++ b/JAVA/JAVA EE/Web程序设计笔记09——第五章:Spring的事务管理.md @@ -0,0 +1,145 @@ +# 第五章:Spring的事务管理 + +transfer()的语句要么全做,要么全不做? + +```java +把transfer方法做成事务方法。 + +事务方法:方法体中的代码要么全部,要么全不做。 +``` + +如何把transfer()做成事务方法呢? + +```java +1.基于xml文件 +2.基于注解 +``` + +AOP关键导包 + +```java + + org.aspectj + aspectjweaver + 1.8.7 + +``` + +以转钱为例,在未进行事务管理之前转账记录在遇到异常会将方法执行一半,这样会使部分资金转账失效,并且无退回,用事务管理之后方法不会因为异常而执行一半,只有**完全执行**和**不执行**。 + +## 一、基于XML方式的声明式事务 + +#### (1)创建实体类 + +同上 + +#### (2)创建接口 + +```java +//转钱outUser给inUser转money钱 +void transfer(String outUser, String inUser, double money); +``` + +#### (3)实现接口 + +```java +//转钱outUser给inUser转money钱 +@Override +public void transfer(String outUser, String inUser, double money) { + String sql = "update account set balance=balance-? where username=?"; + jdbcTemplate.update(sql, money, outUser); + //模拟异常 + System.out.println(1 / 0); + String sql1 = "update account set balance=balance+? where username=?"; + jdbcTemplate.update(sql1, money, inUser); +} +``` + +#### (4)写配置文件 + +在上一章文件中增添以下配置 + +```java + + + + + + + + + + + + + + + + +``` + +#### (5)测试Test方法 + +```java +@Test +//转钱outUser给inUser转money钱 +public void transferTest() { + accountDao.transfer("zhangsan", "lisi", 500); +} +``` + +#### 运行截图: + +1.无异常 + +![image-20220331225557619](https://yovinchen-1308133012.cos.ap-beijing.myqcloud.com/image-20220331225557619.png) + +2.有异常 + +![image-20220331225618374](https://yovinchen-1308133012.cos.ap-beijing.myqcloud.com/image-20220331225618374.png) + +## 二、基于Annotation(注解)方式的声明式事务 + +#### (1)创建实体类 + +同上 + +#### (2)创建接口 + +同上 + +#### (3)实现接口 + +```java +//在实现类上添加注解 +@Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.DEFAULT, readOnly = false) +``` + +#### (4)写配置文件 + +在上一章文件中增添以下配置 + +```java + + + + + + + +``` + +#### (5)测试Test方法 + +同上 + +#### 运行截图: + +1.无异常: + +![image-20220331225721435](https://yovinchen-1308133012.cos.ap-beijing.myqcloud.com/image-20220331225721435.png) + +2.有异常: + +![image-20220331225754769](https://yovinchen-1308133012.cos.ap-beijing.myqcloud.com/image-20220331225754769.png) + diff --git a/JAVA/JAVA EE/Web程序设计笔记10——第六章:初识MyBatis.md b/JAVA/JAVA EE/Web程序设计笔记10——第六章:初识MyBatis.md new file mode 100644 index 0000000..e65e886 --- /dev/null +++ b/JAVA/JAVA EE/Web程序设计笔记10——第六章:初识MyBatis.md @@ -0,0 +1,455 @@ +# 第6章:MyBatis + +Spring: 负责实现业务层的逻辑 + +MyBatis:主要和数据库打交道 + +Spring MVC:主要负责前端页面 + +## 6.1 MyBatis + +1.持久层框架: 负责数据库开发 + +2.ORM框架:Object/Relational Mapping + +3.POJO(Plain Old Java Object):普通的Java对象 + PO(Persisent Object):持久化对象 + +## 6.2 + +## 6.3 + +## 6.4 MyBatis的入门程序 + +基于MyBatis的客户管理系统的设计与实现 + +### 系统功能: + +```java +1. 根据id查询客户 +2. 根据姓名模糊查询 +3. 添加客户 +4. 更新客户 +5. 删除客户 +``` + +### 程序准备: + +#### (1)mysql中创建数据库mybatis,表t_customer,插入数据。 + +```mysql +create database mybatis; +``` + +```mysql +create table t_customer( +id int (32) primary key auto_increment, +username varchar(50), +jobs varchar(50), +phone varchar(16) +); +``` + +```mysql +insert into t_customer values +('1','joy','doctor','13745874578'), +('2','jack','teacher','13521210112'), +('3','tom','worker','15179405961'); +``` + +![image-20220405130626049](https://yovinchen-1308133012.cos.ap-beijing.myqcloud.com/image-20220405130626049.png) + +#### (2)创建项目,导2个包:mybatis mysql-connector-java + +```java + + + org.mybatis + mybatis + 3.4.2 + + + + mysql + mysql-connector-java + 8.0.28 + + +``` + +#### (3)创建持久化类(实体类) + +作用:和表进行数据转换 +-- 增:实体类对象 转换 表中的记录 +-- 查:表中的记录 转换 实体类对象 +注意:成员变量的名字、数据类型 需要和 表中字段的名字、数据类型 保持一致 + +生成setter、getter 和 toString()方法 + +```java +package com.gzh.po; + +public class Customer { + private int id; + private String username; + private String jobs; + private String phone; + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public String getUsername() { + return username; + } + + public void setUsername(String username) { + this.username = username; + } + + public String getJobs() { + return jobs; + } + + public void setJobs(String jobs) { + this.jobs = jobs; + } + + public String getPhone() { + return phone; + } + + public void setPhone(String phone) { + this.phone = phone; + } + + @Override + public String toString() { + return "Customer{" + + "id=" + id + + ", username='" + username + '\'' + + ", jobs='" + jobs + '\'' + + ", phone='" + phone + '\'' + + '}'; + } +} +``` + +#### (4)在resources文件夹下创建CustomerMapper.xml文件,用来写sql语句 + +##### 1.首先创建模板 + +在 file (文件)中的 setting (设置)中搜索 File and Code Templates (文件和代码模板),在其中首页 Files (文件)下创建文件 Mapper.xml,然后在下面填入以下代码,选择 OK (确定) 退出 + +```java + + + + + +``` + +![image-20220405131535640](https://yovinchen-1308133012.cos.ap-beijing.myqcloud.com/image-20220405131535640.png) + +##### 2.创建CustomerMapper.xml文件 + +在 resources 文件夹右击选择 new(新建)Mapper + +![image-20220405132203804](https://yovinchen-1308133012.cos.ap-beijing.myqcloud.com/image-20220405132203804.png) + +##### 3.写sql语句 + +```java +1.namespace属性的值:copy path(复制路径/引用)中 file name(文件名),去掉.xml + + + +2.#{id}占位符 +3.parameterType是来设置占位符对应的参数的数据类型 +4.resultType用来设置接收查询结果的持久化类,注意的是resultType属性值是全类名(全限定名) + + +``` + +![image-20220405132451651](https://yovinchen-1308133012.cos.ap-beijing.myqcloud.com/image-20220405132451651.png) + +#### (5)在resources文件夹下创建mybatis-config.xml文件,该文件是MyBatis框架的配置文件 + +##### 1.首先创建模板 + +在 file (文件)中的 setting (设置)中搜索 File and Code Templates (文件和代码模板),在其中首页 Files (文件)下创建文件 mybatis-config.xml,然后在下面填入以下代码,选择 OK (确定) 退出 + +```java + + + + + +``` + +![image-20220405131954150](https://yovinchen-1308133012.cos.ap-beijing.myqcloud.com/image-20220405131954150.png) + +##### 2.创建mybatis-config.xml文件 + +在 resources 文件夹右击选择 new(新建)mybatis-config + +![image-20220405132528897](https://yovinchen-1308133012.cos.ap-beijing.myqcloud.com/image-20220405132528897.png) + +##### 3.配置MyBatis框架 + +```java + + + + + + + + + + + + + + + + + + + + + +``` + +![image-20220405132915669](https://yovinchen-1308133012.cos.ap-beijing.myqcloud.com/image-20220405132915669.png) + +#### (6)单元测试:查询 + +在 com.gzh.po 包下创建测试类MybatisTest + +1.加载配置文件和 Mapper 文件 + +通过 CustomerMapper.xml 文件中的 select 的 id 的值来命名测试类 + +![image-20220405133745512](https://yovinchen-1308133012.cos.ap-beijing.myqcloud.com/image-20220405133745512.png) + +在输入 **Resources** 时通过提示导入名为 org 开头的包 + +![image-20220405134057509](https://yovinchen-1308133012.cos.ap-beijing.myqcloud.com/image-20220405134057509.png) + +在此输入完此行代码后 getResourceAsStream 会爆红,不用管后续处理 + +```java +InputStream resourceAsStream = Resources.getResourceAsStream("mybatis-config.xml"); +``` + +##### 2.构建会话工厂 + +```java +SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream); +``` + +##### 3.构建会话 SqlSession + +```java +SqlSession sqlSession = sqlSessionFactory.openSession(); +``` + +因为要测试多个方法,所以将以上构造剪切到**成员变量** + +![image-20220405134848712](https://yovinchen-1308133012.cos.ap-beijing.myqcloud.com/image-20220405134848712.png) + +##### 4.处理爆红错误 + +将鼠标放置到爆红的 resourceAsStream 处 Alt+回车 处理问题,选择添加类默认构造函数签名的异常 + +![image-20220405134938312](https://yovinchen-1308133012.cos.ap-beijing.myqcloud.com/image-20220405134938312.png) + +##### 5.导包 Test ,并写完查询类 + +selectOne()中的参数 = CustomerMapper.xml文件中 namespace + select id + +MybatisTest.java 总体代码如下: + +```java +package com.gzh.po; + +import org.apache.ibatis.io.Resources; +import org.apache.ibatis.session.SqlSession; +import org.apache.ibatis.session.SqlSessionFactory; +import org.apache.ibatis.session.SqlSessionFactoryBuilder; +import org.junit.Test; + +import java.io.IOException; +import java.io.InputStream; + +public class MybatisTest { + InputStream resourceAsStream = Resources.getResourceAsStream("mybatis-config.xml"); + SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream); + SqlSession sqlSession = sqlSessionFactory.openSession(); + + public MybatisTest() throws IOException { + } + + @Test + public void findCustomerById(){ +// s: = CustomerMapper.xml文件中 namespace + select id + Customer o = sqlSession.selectOne("CustomerMapper.findCustomerById", 1); + System.out.println(o); + } +} +``` + +运行结果如下: + +![image-20220405135447683](https://yovinchen-1308133012.cos.ap-beijing.myqcloud.com/image-20220405135447683.png) + +### 1.根据id查询客户 + +```java + +``` + +```java +@Test +public void findCustomerById() { + Customer o = sqlSession.selectOne("com.CustomerMapper.findCustomerById", 1); + System.out.println(o); +} +``` + +![image-20220407152029547](https://yovinchen-1308133012.cos.ap-beijing.myqcloud.com/image-20220407152029547.png) + +### 2.根据姓名模糊查询 + +```java + +``` + +```java +@Test +public void findCustomerByName() { + List o = sqlSession.selectList("CustomerMapper.findCustomerByName", "j"); + for (Customer customer : o){ + System.out.println(customer); + } +} +``` + +![image-20220407152044583](https://yovinchen-1308133012.cos.ap-beijing.myqcloud.com/image-20220407152044583.png) + +### 3.添加客户 + +```java + + insert into t_customer values (#{id},#{username},#{jobs},#{phone}) + +``` + +```java +@Test +public void addCustomer(){ + Customer customer = new Customer(); + customer.setId(1); + customer.setUsername("zhangsan"); + customer.setJobs("student"); + customer.setPhone("110"); + sqlSession.insert("CustomerMapper.addCustomer",customer); + sqlSession.commit();//只要更改数据库中的数据,就需要调用该方法完成数据的 + sqlSession.close();//关闭数据库的连接 +} +``` + +![image-20220407152231144](https://yovinchen-1308133012.cos.ap-beijing.myqcloud.com/image-20220407152231144.png) + +### 4.更新客户 + +```java + + update t_customer set username = #{username},jobs = #{jobs},phone = #{phone} where id = #{id} + +``` + +```java +@Test +public void updateCustomer() { + Customer customer = new Customer(); + customer.setId(4); + customer.setUsername("zhangsan"); + customer.setJobs("teacher"); + customer.setPhone("18888888888"); + sqlSession.update("CustomerMapper.updateCustomer", customer); + sqlSession.commit(); + sqlSession.close(); +} +``` + +![image-20220407152334704](https://yovinchen-1308133012.cos.ap-beijing.myqcloud.com/image-20220407152334704.png) + +### 5.删除客户 + +```java + + delete from t_customer where id = #{id} + +``` + +```java +@Test +public void deleteCustomer() { + sqlSession.delete("CustomerMapper.deleteCustomer", 1); + sqlSession.commit(); + sqlSession.close(); +} +``` + +![image-20220407152346163](https://yovinchen-1308133012.cos.ap-beijing.myqcloud.com/image-20220407152346163.png) + + + +### 如何在控制台输入SQL语句? + +(1) 导包 log4j + +```java + + log4j + log4j + 1.2.17 + +``` + +(2) 复制log4j.properties文件到resources.文件夹下 + +(3) resources下新建directory,名为com + +(4) 将CustomerMapper.xml文件复制到com下 + +![image-20220407152650898](https://yovinchen-1308133012.cos.ap-beijing.myqcloud.com/image-20220407152650898.png) + +(5) 复制后的CustomerMapper.Xml中的namespacel的值修改:com.CustomerMapper + +![image-20220407152719404](https://yovinchen-1308133012.cos.ap-beijing.myqcloud.com/image-20220407152719404.png) + +(6) 修改mybatis-config.xml文件中resource属性的值: + +![image-20220407152735127](https://yovinchen-1308133012.cos.ap-beijing.myqcloud.com/image-20220407152735127.png) + +(7) 修改测试方法中的值: + +![image-20220407152802930](https://yovinchen-1308133012.cos.ap-beijing.myqcloud.com/image-20220407152802930.png) + +运行测试结果如下: + +![image-20220407152822914](https://yovinchen-1308133012.cos.ap-beijing.myqcloud.com/image-20220407152822914.png) \ No newline at end of file diff --git a/JAVA/JAVA EE/Web程序设计笔记11——第七章:MyBatis核心配置.md b/JAVA/JAVA EE/Web程序设计笔记11——第七章:MyBatis核心配置.md new file mode 100644 index 0000000..9d767ff --- /dev/null +++ b/JAVA/JAVA EE/Web程序设计笔记11——第七章:MyBatis核心配置.md @@ -0,0 +1,385 @@ +# 第七章:MyBatis核心配置 + +## 7.1 核心对象 +### 1.复制第6章的代码 + +#### (1)导包 mybatis mysql + +```java + + org.mybatis + mybatis + 3.4.2 + + + + mysql + mysql-connector-java + 8.0.28 + +``` + +#### (2)准备数据 + +沿用上一章节数据 + +#### (3)复制实体类 + +```java +package com.gzh.po; + +public class Customer { + private int id; + private String username; + private String jobs; + private String phone; + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public String getUsername() { + return username; + } + + public void setUsername(String username) { + this.username = username; + } + + public String getJobs() { + return jobs; + } + + public void setJobs(String jobs) { + this.jobs = jobs; + } + + public String getPhone() { + return phone; + } + + public void setPhone(String phone) { + this.phone = phone; + } + + @Override + public String toString() { + return "Customer{" + + "id=" + id + + ", username='" + username + '\'' + + ", jobs='" + jobs + '\'' + + ", phone='" + phone + '\'' + + '}'; + } +} +``` + +#### (4)复制两个xml文件 + +mybatis-config.xml: + +```java + + + + + + + + + + + + + + + + + + + + + + + + + +``` + +CustomerMapper.xml: + +```java + + + + + + + + + + + insert into t_customer values (#{id},#{username},#{jobs},#{phone}) + + + + update t_customer set username = #{username},jobs = #{jobs},phone = #{phone} where id = #{id} + + + + delete from t_customer where id = #{id} + + +``` + +#### (5)测试类 + +```java +package com.gzh.po; + +import org.apache.ibatis.io.Resources; +import org.apache.ibatis.session.SqlSession; +import org.apache.ibatis.session.SqlSessionFactory; +import org.apache.ibatis.session.SqlSessionFactoryBuilder; +import org.junit.Test; + +import java.io.IOException; +import java.io.InputStream; +import java.util.List; + +public class MybatisTest { + InputStream resourceAsStream = Resources.getResourceAsStream("mybatis-config.xml"); + SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream); + SqlSession sqlSession = sqlSessionFactory.openSession(); + + public MybatisTest() throws IOException { + } + + @Test + public void findCustomerById() { + Customer o = sqlSession.selectOne("CustomerMapper.findCustomerById", 2); + System.out.println(o); + } +``` + +运行结果如下: + +![image-20220412211705869](https://yovinchen-1308133012.cos.ap-beijing.myqcloud.com/image-20220412211705869.png) + +### 2.创建工具类,对外提供SqlSession对象 + +在 main 下创建一个新的包 com.gzh.utils (通常为工具包),并创建类 MyBatisUtil + +```java +package com.gzh; + +import com.gzh.po.Customer; +import com.gzh.utils.MyBatisUtil; +import org.apache.ibatis.session.SqlSession; +import org.junit.Test; + +public class MyBatisTest { + SqlSession sqlSession=MyBatisUtil.getSession(); + + @Test + public void findCustomerByIdTest(){ + Customer o = sqlSession.selectOne("CustomerMapper.findCustomerById", 2); + System.out.println(o); + } +} +``` + +将 Test 测试类转移到 com.gzh 包下,代码如下: + +```java +public class MyBatisTest { + SqlSession sqlSession=MyBatisUtil.getSession(); + @Test + public void findCustomerByIdTest(){ + Customer o = sqlSession.selectOne("CustomerMapper.findCustomerById", 2); + System.out.println(o); + } +} +``` + +运行截图: + +![image-20220412213246062](https://yovinchen-1308133012.cos.ap-beijing.myqcloud.com/image-20220412213246062.png) + + + +## 7.2 配置文件 + +### 1.properties 元素 + +连接数据库,通过该元素进行内部配置外在化。 + +(1) 在resources下创建db.properties + +```java +jdbc.driver=com.mysql.cj.jdbc.Driver +jdbc.url=jdbc:mysql://localhost:3306/mybatis +jdbc.username=root +jdbc.password=8520 +``` + +(2) 修改配置文件 2处 + +1.在文件下添加 + +```java + +``` + +2.在标签中的 value 属性修改如下: + +```java + + + + +``` + +(3)测试运行截图 + +![image-20220413084844679](https://yovinchen-1308133012.cos.ap-beijing.myqcloud.com/image-20220413084844679.png) + +### 2.typeAliases元素 给实体类起别名 + +(1)修改CustomerMapper.xml中的:(修改resultType属性) + +```java + +``` + +(2)在mybatis-config.xml文件中起别名(添加) + +```java + + + + +``` + +(3)测试截图如下: + +![image-20220413090235983](https://yovinchen-1308133012.cos.ap-beijing.myqcloud.com/image-20220413090235983.png) + +## 7.3 映射文件 + +### 1.resultMap元素:将表中字段和实体类成员变量进行对应 + +(1)修改实体类 username->name + +重写getter and setter 以及 toString() + +(2)测试结果:当实体类中的成员变量名和表中字段名字不一致时,导致字段值不能被赋值给成员变量 + +Customer{id=2, name='null', jobs='teacher', phone='13521210112'} + +![image-20220413091252095](https://yovinchen-1308133012.cos.ap-beijing.myqcloud.com/image-20220413091252095.png) + +(3)如何解决当实体类中的成员变量名和表中字段名字不一致时,还可以将字段值赋值给成员变量? + +resultMap + +(4)修改CustomerMapper.xml + +添加 resultMap 和 修改 select 中主键的 resultType 属性改为 resultMap + +```java + + + + + + + +``` + + + + +---如何将sql语句显示到控制台? + +(1)log4j.properties + +```java +#Global logging configuration +log4j.rootLogger=ERROR,stdout +#MyBatis logging configuration... +log4j.logger.com=DEBUG +#Console output... +log4j.appender.stdout=org.apache.log4j.ConsoleAppender +log4j.appender.stdout.layout=org.apache.log4j.PatternLayout +log4j.appender.stdout.layout.ConversionPattern=%5p [%t]-%m%n +``` + +(2)导包 + +```java + + log4j + log4j + 1.2.17 + +``` + +(3)resources 下 创建com,把CustomerMapper.xml文件移动到com下 + +![image-20220413093052137](https://yovinchen-1308133012.cos.ap-beijing.myqcloud.com/image-20220413093052137.png) + +(4)修改两个xml文件 + +CustomerMapper.xml + +```java +namespace="com.CustomerMapper" +``` + +mybatis-config.xml + +```java +resource="com/CustomerMapper.xml" +``` + +(5)修改测试方法 + +```java +Customer o = sqlSession.selectOne("com.CustomerMapper.findCustomerById", 2); +``` + +(6)运行截图 + +![image-20220413092737690](https://yovinchen-1308133012.cos.ap-beijing.myqcloud.com/image-20220413092737690.png) \ No newline at end of file diff --git a/JAVA/JAVA EE/Web程序设计笔记12——第八章:动态SQL.md b/JAVA/JAVA EE/Web程序设计笔记12——第八章:动态SQL.md new file mode 100644 index 0000000..3ae9189 --- /dev/null +++ b/JAVA/JAVA EE/Web程序设计笔记12——第八章:动态SQL.md @@ -0,0 +1,233 @@ +# 第八章:动态SQL + +基于MyBatis的客户管理系统的设计与开发 + +## 1.复制第6章的代码 + +导包:mybatis mysql +准备数据 +数据库:mybatis 表 t_customer +创建实体类Customer +创建CustomerMapper.xml文件,写SQL语句的 +创建mybatis-config.xml文件,配置文件 +创建工具类,对外提供 +测试 +在上一章节中有所展示记录 + +## 2.系统功能 + +### 1. if 元素 + +如果姓名和职业都不为空,按姓名和职业查找客户 +如果姓名不为空职业为空,按姓名查找客户 +如果姓名为空职业不为空,按职业查找客户 +如果姓名和职业都为空,则查找所有客户。 + +#### 下面是 CustomerMapper.xml 文件中的 sql 语句: + +```java + + +test="username!=null and username!=''" +此处的username是实体类Customer的成员变量,如果test中条件成立,and这一行代码就会被拼接到1=1的后面,否则,就不拼接 + +and username like concat('%',#{username},'%') +此处的第一个username是字段名,第2个username.是实体类Customer的成员变量 concat函数 连接字符串 +``` + +```java + +``` + +#### 测试类,通过名字进行查询: + +```java +@Test +public void findCustomerByNameAndJobsTest(){ + Customer customer = new Customer(); + customer.setUsername("w"); + List objects = sqlSession.selectList("CustomerMapper.findCustomerByNameAndJobs", customer); + for (Customer object: objects) { + System.out.println(object); + } +} +``` + +#### 运行截图: + +传一个名字,按名字查询: + +![image-20220415134517801](https://yovinchen-1308133012.cos.ap-beijing.myqcloud.com/image-20220415134517801.png) + +不传参查询全部: + +![image-20220415134721203](https://yovinchen-1308133012.cos.ap-beijing.myqcloud.com/image-20220415134721203.png) + +### 2. choose - when - otherwise 元素 + +当客户名不为空,只根据客户名查询 +当客户名为空,职业不为空,则只根据职业查询 +当客户名和职业都为空,则查询电话不为空的客户 + +#### 下面是 CustomerMapper.xml 文件中的 sql 语句: + +```java + +``` + +```java + +``` + +#### 测试类,通过职业进行查询: + +```java +@Test +public void findCustomerByNameOrJobs(){ + Customer customer = new Customer(); + customer.setJobs("teacher"); + List objects = sqlSession.selectList("CustomerMapper.findCustomerByNameOrJobs", customer); + for (Customer object: objects) { + System.out.println(object); + } +} +``` + +#### 运行截图: + +传职业,按职业查询: + +![image-20220415134806665](https://yovinchen-1308133012.cos.ap-beijing.myqcloud.com/image-20220415134806665.png) + +不传参,查询有手机号: + +![image-20220415134848949](https://yovinchen-1308133012.cos.ap-beijing.myqcloud.com/image-20220415134848949.png) + +### 3. where 元素 + +> 根据需要自动添加 where ,而且会自动保留或去掉 and 关键字 + +如果姓名和职业都不为空,按姓名和职业查找客户 +如果姓名不为空职业为空,按姓名查找客户 +如果姓名为空职业不为空,按职业查找客户 +如果姓名和职业都为空,则查找所有客户。 + +#### 下面是 CustomerMapper.xml 文件中的 sql 语句: + +```java + +``` + +#### 测试类,通过姓名进行查询: + +```java +@Test +public void findCustomerByNameAndJobs1Test(){ + Customer customer = new Customer(); + customer.setUsername("j"); + List objects = sqlSession.selectList("CustomerMapper.findCustomerByNameAndJobs1", customer); + for (Customer object: objects) { + System.out.println(object); + } +} +``` + +#### 运行截图: + +传一个名字,按名字查询: + +![image-20220415135501209](https://yovinchen-1308133012.cos.ap-beijing.myqcloud.com/image-20220415135501209.png) + +不传参查询全部: + +![image-20220415135537915](https://yovinchen-1308133012.cos.ap-beijing.myqcloud.com/image-20220415135537915.png) + +### 4. set 元素 + +> 根据id更新客户信息 set元素根据需要自动去掉多余的逗号 + +通过 ID 更新信息 + +#### 下面是 CustomerMapper.xml 文件中的 sql 语句: + +```java + +``` + +测试类,通过 ID 进行修改: + +```java +@Test +public void updateCustomer(){ + Customer customer = new Customer(); + customer.setId(3); + customer.setUsername("maliu"); + sqlSession.selectList("CustomerMapper.updateCustomer", customer); + sqlSession.commit(); + sqlSession.close(); +} +``` + +运行截图: + +![image-20220415135735652](https://yovinchen-1308133012.cos.ap-beijing.myqcloud.com/image-20220415135735652.png) \ No newline at end of file diff --git a/JAVA/JAVA EE/Web程序设计笔记13——第九章:MyBatis 的关系映射.md b/JAVA/JAVA EE/Web程序设计笔记13——第九章:MyBatis 的关系映射.md new file mode 100644 index 0000000..af069b9 --- /dev/null +++ b/JAVA/JAVA EE/Web程序设计笔记13——第九章:MyBatis 的关系映射.md @@ -0,0 +1,231 @@ +# 第九章:MyBatis 的关系映射 + +> 实体和实体之间: 1:1 1:多 多:多 + +# 基于 MyBatis 的客户管理系统的设计与设计 + +## 功能: + +### 一、根据id查询客户的所有信息(id,name,age,sex,Car_id,code) + +> 进行关联查询的方式有两种: +> +> 1.嵌套查询:需要写多个Mapper文件,也就需要写多条SQL语句,但是每一条SQL语句都很简单。 +> +> 2.嵌套结果:只需要写一个Mapper文件,也就是只需要写一条SQL语句,但是这一条sQL语句比较复杂 + +#### 1.准备数据 + +创建数据库 tb_idcard 和 tb_person两个表 + +```mysql +create table tb_idcard( +id int primary key auto_increment, +code varchar(18) +); +``` + +```mysql +insert into tb_idcard(code) values +('154326874565214862'), +('13254868459587852'); +``` + +```mysql +create table tb_person( +id int primary key auto_increment, +name varchar(32), +age int, +sex varchar(8), +card_id int unique, +foreign key(card_id) references tb_idcard(id) +); +``` + +```mysql +insert into tb_person(name,age,sex,card_id) values +('Rose',20,'女',1), +('Tom',20,'男',2); +``` + +![image-20220419102233809](https://yovinchen-1308133012.cos.ap-beijing.myqcloud.com/image-20220419102233809.png) + +#### 2.创建项目,导入依赖:mybatis mysql + +```java + + org.mybatis + mybatis + 3.4.2 + + + + mysql + mysql-connector-java + 8.0.28 + +``` + +#### 3.创建实体类 + +```java +//tb_idcard +private int id; +private String Code; +利用 getter , setter 和 toString 方法生成代码 +``` + +```java +//tb_person +private int id; +private String name; +private int age; +private String sex; +//注意,此成员变量是另一个实体类的对象,反映的是实体脚erson.和实体类红dcard,的:1的关系 +private IdCard card; +利用 getter , setter 和 toString 方法生成代码 +``` + +#### 4.创建 IdCardMapper.xml PersonMapper.xml 文件 + +```java + + + + +``` + +```java + + + + + + + + + + + +``` + +#### 5.创建 mybatis-config.xml 文件 + +```java + + + + + + + + + + + + + + + + + + + +``` + +#### 6.复制工具类 MyBatisUtils + +```java +//对外提供 sqlSession 对象 +public class MyBatisUtils { + private static SqlSessionFactory sqlSessionFactory = null; + + static { + try { + InputStream inputStream = Resources.getResourceAsStream("mybatis-config.xml"); + sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); + } catch (IOException e) { + e.printStackTrace(); + } + } + + public static SqlSession getSession() { + return sqlSessionFactory.openSession(); + } +} +``` + +#### 7.测试类 + +```java +public class MyBatisTest { + SqlSession sqlSession = MyBatisUtils.getSession(); + @Test + public void findPersonByIdTest(){ + Person o = sqlSession.selectOne("PersonMapper.findPersonById",1); + System.out.println(o); + sqlSession.close(); + } +} +``` + +运行截图: + +![image-20220419112333746](https://yovinchen-1308133012.cos.ap-beijing.myqcloud.com/image-20220419112333746.png) + +### 二、使用嵌套结果:根据id查询客户的所有信息(id,name,age,sex,Car_id,code) + +#### 1.mybatis-config.xml 中修改:注释掉以下语句 + +```java + +``` + +#### 2.PersonMapper + +```java + + + + + + + + + + + + +``` + +#### 3.测试 + +```java +public class MyBatisTest { + SqlSession sqlSession = MyBatisUtils.getSession(); + @Test + public void findPersonByIdTest(){ + Person o = sqlSession.selectOne("PersonMapper.findPersonById2",1); + System.out.println(o); + sqlSession.close(); + } +} +``` + +![image-20220419120201332](https://yovinchen-1308133012.cos.ap-beijing.myqcloud.com/image-20220419120201332.png) + + + + + + + diff --git a/JAVA/JAVA EE/Web程序设计笔记14——第十章:Spring 和 MyBatis 的整合.md b/JAVA/JAVA EE/Web程序设计笔记14——第十章:Spring 和 MyBatis 的整合.md new file mode 100644 index 0000000..4b74f25 --- /dev/null +++ b/JAVA/JAVA EE/Web程序设计笔记14——第十章:Spring 和 MyBatis 的整合.md @@ -0,0 +1,289 @@ +# 第十章:Spring 和 MyBatis 的整合 + +基于SSM的用户管理系统的设计与实现 + +## 基于传统的DAO方式的整合 + +#### 0.导包 + +mybatis mybatis-spring spring mysql spring-tx spring-jdbc commons-dbcp2 + +```java + + org.mybatis + mybatis + 3.4.2 + + + org.mybatis + mybatis-spring + 1.3.1 + + + org.springframework + spring-context + 4.3.6.RELEASE + + + org.apache.commons + commons-dbcp2 + 2.1.1 + + + + mysql + mysql-connector-java + 8.0.28 + + + junit + junit + 4.12 + compile + + + org.springframework + spring-jdbc + 4.3.6.RELEASE + + + org.springframework + spring-tx + 4.3.6.RELEASE + +``` + +#### 1.准备数据 + +mybatis 中的 t_customer + +![image-20220426132557267](https://yovinchen-1308133012.cos.ap-beijing.myqcloud.com/image-20220426132557267.png) + +#### 2.创建实体类 + +```java +//在com.gzh.domain下创建 +private int id; +private String username; +private String jobs; +private String phone; +//利用 getter , setter 和 toString 方法生成代码 +``` + +#### 3.在resources下创建CustomerMapper.xml文件 + +```java + + + +``` + +#### 4.在resources下创建mybatis-config.xml文件 + +```java + + + + +``` + +#### 5.创建DAO层接口和实现类 + +```java +//在com.gzh.dao包下创建接口 +public interface CustomerDao { + Customer findCustomerById(int id); +} +``` + +```java +//在com.gzh.dao.impl包下创建实现类 +public class CustomerDaoImpl extends SqlSessionDaoSupport implements CustomerDao { + @Override + public Customer findCustomerById(int id){ + Customer o = getSqlSession().selectOne("CustomerMapper.findCustomerById", id); + return o; + } +} +``` + +#### 6.在resources下创建applicationContext.xml文件 + +```java + + + + + + + + + + + + + + + + +``` + +#### 7.测试 + +```java +//在com.gzh.domain包下创建测试类 +@Test +public void findCustomerByIdTest(){ + ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml"); + CustomerDao customerDao = (CustomerDao) applicationContext.getBean("customerDao"); + Customer customerById = customerDao.findCustomerById(1); + System.out.println(customerById); +} +``` + +![image-20220426134717655](https://yovinchen-1308133012.cos.ap-beijing.myqcloud.com/image-20220426134717655.png) + +## 基于Mapper方式的整合 + +### 基于MapperFactoryBean的整合 + +#### 0.导包 + +与DAO方式导包数量相同 + +#### 1.准备数据 + +同上数据 + +#### 2.创建实体类 + +```java +//在com.gzh.domain下创建 +private int id; +private String username; +private String jobs; +private String phone; +//利用 getter , setter 和 toString 方法生成代码 +``` + +#### 3.创建com.gzh.mapper. CustomerMapper接口文件 + +```java +public interface CustomerMapper { + Customer findCustomerById(int i); +} +``` + +#### 4.在resources下创建com->gzh->mapper->CustomerMapper.Xml文件 + +com.gzh.mapper 文件夹要一个一个创建,才能保证是嵌套的 + +```java + + + + +``` + +#### 5.在resources下创建mybatis-config.xml文件 + +```java + + + +``` + +#### 6.在resources下创建applicationContext.xml文件 + +```java + + + + + + + + + + + + + + + + + +``` + +#### 7.测试 + +```java +@Test +public void findCustomerById(){ + ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml"); + CustomerMapper factoryBean = (CustomerMapper) applicationContext.getBean("factoryBean"); + Customer customerById = factoryBean.findCustomerById(1); + System.out.println(customerById); +} +``` + +![image-20220426135752830](https://yovinchen-1308133012.cos.ap-beijing.myqcloud.com/image-20220426135752830.png) + +虽然使用Mapper接口编程的方式很简单,但是在具体使用时还是需要遵循以下规范。 + +> (I)Mapper接口的名称和对应的Mapper.xml映射文件的名称必须一致。 +> +> (2)Mapper,.xml文件中的namespace与Mapper接口的类路径相同(即接口文件和映射文件 +> 需要放在同一个包中)。 +> +> (3)Mapper接口中的方法名和Mapper.xml中定义的每个执行语句的id相同。 +> +> (4)Mapper接口中方法的输入参数类型要和Mapper,.xml中定义的每个sql的parameterType +> 的类型相同。 +> +> (5)Mapper接口方法的输出参数类型要和Mapper.xml中定义的每个sql的resultType的 +> 类型相同。 + +只要遵循了这些开发规范,MyBatis就可以自动生成Mapper接口实现类的代理对象,从而 +简化我们的开发。 + +### 基于MapperScannerConfigurer的整合 + +在上面的基础上修改 + +1.在 applicationContext 中注释以下代码 + +```java + + + + + +``` + +2.在 applicationContext 中添加以下代码 + +```java + + + + +``` + +3.创建新的测试类 + +```java +@Test +public void findCustomerById1(){ + ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml"); + CustomerMapper bean = applicationContext.getBean(CustomerMapper.class); + Customer customerById = bean.findCustomerById(1); + System.out.println(customerById); +} +``` + +![image-20220427102429052](https://yovinchen-1308133012.cos.ap-beijing.myqcloud.com/image-20220427102429052.png) \ No newline at end of file diff --git a/JAVA/JAVA EE/Web程序设计笔记15——第十一章:Spring MVC.md b/JAVA/JAVA EE/Web程序设计笔记15——第十一章:Spring MVC.md new file mode 100644 index 0000000..5fadb9a --- /dev/null +++ b/JAVA/JAVA EE/Web程序设计笔记15——第十一章:Spring MVC.md @@ -0,0 +1,191 @@ +# 第十一章:Spring MVC + +第一个spring应用 + +## 0.创建项目,导包 + +```java +FirstController 类的包 实现HttpServletResponse HttpServletRequest两个方法 + + javax.servlet + servlet-api + 2.5 + + + org.springframework + spring-web + 4.3.6.RELEASE + + + + org.springframework + spring-webmvc + 4.3.6.RELEASE + +``` + +### 1.main->webapp->WEB-INF->web.xml文件中配置前端控制器 + +> DispatcherServlet:就是一个Servlet +> +> 配置前端控制器就是给DispatcherServlet配置一个访问的url + + + +如何给一个java类配置访问它的url呢? + +```java + + 逻辑名 + Java类的全类名(物理名) + + + 逻辑名 + url + +``` + +> 补充: +> +> Java Web中有一个概念:Servlet:是什么?本质就是Java类,但是此类是通过url来访问的 + +```java + + apringmvc + org.springframework.web.servlet.DispatcherServlet + + contextConfigLocation + classpath:springmvc-config.xml + + + + apringmvc + / + +``` + +### 2.创建控制器 FirstController + +首先在 java 下创建包 com.gzh.controller ,然后创建 FirstController 类,实现接口选择 Controller 第一个 + +![image-20220430213958181](https://yovinchen-1308133012.cos.ap-beijing.myqcloud.com/image-20220430213958181.png) + +```java +public class FirstController implements Controller { + @Override + public ModelAndView handleRequest(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws Exception { + ModelAndView modelAndView = new ModelAndView(); + modelAndView.addObject("msg","这是我的第一个Spring MVC程序"); + modelAndView.setViewName("/WEB-INF/jsp/first.jsp"); + return modelAndView; + } +} +``` + +### 3.创建first.jsp + +在 WEB-INF 文件下创建 jsp 文件夹然后在下面创建一个名为 first 的 jsp 文件 + +然后在 body 标签中创建一个 `${msg}` 在上面的 FirstController 类中 `modelAndView.addObject("msg","这是我的第一个Spring MVC程序");`相对应 + +```jsp +<%@ page contentType="text/html;charset=UTF-8" language="java" %> + + + Title + + + ${msg} + + +``` + +### 4.在resources下创建springmvc-config.xml + +```java + + + + + + + + + + + +``` + +## 5.在 Tomcat 服务器上部署项目 + +首先将 Tomcat 解压到盘符下,然后在idea中添加 Tomcat + +(1)首先点击 add Configurations 添加 Tomcat 服务器 + +(2)点击加号添加服务器 + +(3)选择 Tomcat 服务区 本地服务(Local 本地 remote 远程服务) + +![image-20220430215445248](https://yovinchen-1308133012.cos.ap-beijing.myqcloud.com/image-20220430215445248.png) + +(4)点击配置服务器,选择 Tomcat 服务器的主目录 + +![image-20220430215956914](https://yovinchen-1308133012.cos.ap-beijing.myqcloud.com/image-20220430215956914.png) + +(5)点击部署,点击添加服务,选择工件(Artifact) + +![image-20220430220220555](https://yovinchen-1308133012.cos.ap-beijing.myqcloud.com/image-20220430220220555.png) + +(6)随便选择一个即可 + +![image-20220430220452741](https://yovinchen-1308133012.cos.ap-beijing.myqcloud.com/image-20220430220452741.png) + +(7)最好将 应用程序上下文 改为项目名称 + +![image-20220430220832300](https://yovinchen-1308133012.cos.ap-beijing.myqcloud.com/image-20220430220832300.png) + +(8)然后启用服务器就可以了 + +![image-20220430221340859](https://yovinchen-1308133012.cos.ap-beijing.myqcloud.com/image-20220430221340859.png) + +## 6.项目部署 + +在 `http://localhost:8080/c11/firstController` 链接中能够看到实现的语句 + +![image-20220430221617115](https://yovinchen-1308133012.cos.ap-beijing.myqcloud.com/image-20220430221617115.png) + +项目根目录:`http://localhost:8080/c11/` + +在上面中的 `/` 表示 `http://localhost:8080/c11/` + +`/firstController` 就代表 `http://localhost:8080/c11/firstController` + + + +![image-20220430221939788](https://yovinchen-1308133012.cos.ap-beijing.myqcloud.com/image-20220430221939788.png) + +(1)用户通过客户端向服务器发送请求,请求会被Spring MVC的前端控制器DispatcherServlet所拦截。 + +(2)DispatcherServlet拦截到请求后,会调用HandlerMapping处理器映射器。 + +(3)处理器映射器根据请求URL找到具体的处理器,生成处理器对象及处理器拦截器(如果有则生成)一并返回给DispatcherServlet。 + +(4)DispatcherServlet会通过返回信息选择合适的HandlerAdapter(处理器适配器)。 + +(5)HandlerAdapter会调用并执行Handler(处理器),这里的处理器指的就是程序中编写的Controller类,也被称之为后端控制器。 + +(6)Controller执行完成后,会返回一个ModelAndView对象,该对象中会包含视图名或包含模型和视图名。 + +(7)HandlerAdapter将ModelAndView对象返回给DispatcherServlet。 + +(8)DispatcherServlet会根据ModelAndView对象选择-个合适的ViewResolver(视图解析器)。 + +(9)ViewResolver解析后,会向DispatcherServlet中返回具体的View(视图)。 + +(10)DispatcherServlet对View进行渲染(即将模型数据填充至视图中)。 + +(11)视图渲染结果会返回给客户端浏览器显示。 \ No newline at end of file diff --git a/JAVA/JAVA EE/Web程序设计笔记16——第十二章:Spring MVC 的核心类和注解.md b/JAVA/JAVA EE/Web程序设计笔记16——第十二章:Spring MVC 的核心类和注解.md new file mode 100644 index 0000000..cb72dca --- /dev/null +++ b/JAVA/JAVA EE/Web程序设计笔记16——第十二章:Spring MVC 的核心类和注解.md @@ -0,0 +1,191 @@ +# 第十二章:Spring MVC 的核心类和注解 + +## 1.Spring MVC 配置文件的联众处理方式: + +--是在 resources 文件夹下创建,此时需要在 web.xml 中通过 元素来加载配置文件 + +```java + + contextConfigLocation + classpath:springmvc-config.xml + +``` + +--是在 WEB-INF 下创建 xxx-servlet.xml ,此时不需要在web.xml文件中加载了,也就是删掉 init-param 元素就可以。 + +```java + + + + + + + + +``` + +xxx是什么? + +是 DispatcherServlet 的逻辑名,中的文本。在这是指 springmvc + +## 2.实现控制器的两种方式: + +1.实现接口,重写handleRequest方法 + +2.使用注解 @Controlleri 可以将 ]ava 类标注成控制器 + + 使用注解 @RequestMapping 将url 映射到控制器的方法上 + +```java +@Controller +public class SecondController { + @RequestMapping("/second") + public ModelAndView handleRequest(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws Exception { + ModelAndView modelAndView = new ModelAndView(); + modelAndView.addObject("msg","这是我的第一个Spring MVC程序"); + modelAndView.setViewName("/WEB-INF/jsp/first.jsp"); + return modelAndView; + } +} +``` + +然后在 WEB-INF 下创建 springmvc-servlet.xml 文件 + +```java + +``` + +然后重新部署即可 + + + +> 使用注解比实现接口 实现的控制器 先进: +> 实现接口的控制器因为只重写了一个方法,所以只能处理一个请求。 +> 但是使用注解的控制器中可以定义多个方法,也就是可以处理多个请求。 + + + + + +## 3.基于注解的 Spring MVC 应用 + +### 1.创建项目,导包:spring-web spring-webmvc + +```java + + javax.servlet + servlet-api + 2.5 + + + org.springframework + spring-web + 4.3.6.RELEASE + + + + org.springframework + spring-webmvc + 4.3.6.RELEASE + +``` + +### 2.web.xml中配置前端控制器 + +```java + + + + + springmvc + org.springframework.web.servlet.DispatcherServlet + + + springmvc + / + + +``` + +### 3.使用注解的方式实现控制器 + +```java +@Controller +public class MyController { + @RequestMapping("/a") + public String a(){ + return "/WEB-INF/jsp/a.jsp"; + } + @RequestMapping("/b") + public String b(){ + return "/WEB-INF/jsp/b.jsp"; + } + @RequestMapping("/c") + public String c(){ + return "/WEB-INF/jsp/c.jsp"; + } +} +``` + +### 4.创建前端视图 + +在 webapp -> WEB-INF -> 下创建名为 jsp 的文件夹,在文件夹中创建 jsp 文件,分别创建三个前端视图,a.jsp b.jsp c.jsp + +### 5.创建配置文件 + +在 WEB-INF 文件夹下创建名为 springmvc-servlet 的 xml 文件 + +```java +添加扫描注解 + +``` + +### 6.在tomcat服务器上部署项目 + +![image-20220506092448960](https://yovinchen-1308133012.cos.ap-beijing.myqcloud.com/image-20220506092448960.png) + +### 7.成功发布项目 + +![image-20220506093333560](https://yovinchen-1308133012.cos.ap-beijing.myqcloud.com/image-20220506093333560.png) + +## 4.定义视图解析器(配置前后缀) + +### 1.修改前端控制器 + +```java +@Controller +public class MyController { + @RequestMapping("/a") + public String a(){ + return "a"; + } + @RequestMapping("/b") + public String b(){ + return "b"; + } + @RequestMapping("/c") + public String c(){ + return "c"; + } +} +``` + +### 2.修改配置文件 springmvc-servlet.xml + +```java +在下添加以下代码 + + + + + +``` + +### 3.重新发布项目 + +![image-20220506094644157](https://yovinchen-1308133012.cos.ap-beijing.myqcloud.com/image-20220506094644157.png) \ No newline at end of file diff --git a/JAVA/JAVA EE/Web程序设计笔记17——第十三章:数据绑定.md b/JAVA/JAVA EE/Web程序设计笔记17——第十三章:数据绑定.md new file mode 100644 index 0000000..c007058 --- /dev/null +++ b/JAVA/JAVA EE/Web程序设计笔记17——第十三章:数据绑定.md @@ -0,0 +1,410 @@ +# 第十三章:数据绑定 + +## 1.什么叫数据绑定 + +将请求消息数据 和 后台方法形参 建立连接的过程 就叫数据绑定。 + +请求消息数据: + + 可以通过url携带数据,比如localhost:8080/c14/get?id=1 + + 还可以通过表单提交数据 + +后台方法形参 + + 控制器中方法的形参 + +根据后台方法形参的类型,将数据绑定分为:简单数据绑定,复杂数据绑定 + +## 2.简单数据绑定 + +### (1)默认的数据类型 + +> HttpServletRequest:通过request对象获取请求信息。 +> +> HttpServletResponse:通过response处理响应信息。 +> +> HttpSession:通过session对象得到session中存储的对象。 +> +> Model//ModelMap:Model是一个接口,ModelMap是一个接口实现,作用是将model数据填充到request域。 + +后台方法形参的默认的数据类型有4个,以 HttpServletRequest 为例进行讲解 + +#### 1.创建项目,导包 spring-web spring-webmvc + +```java + + javax.servlet + servlet-api + 2.5 + + + org.springframework + spring-web + 4.3.6.RELEASE + + + + org.springframework + spring-webmvc + 4.3.6.RELEASE + +``` + +#### 2.web.xml 文件中配置前端控制器 + +```java + + + springmvc + org.springframework.web.servlet.DispatcherServlet + + contextConfigLocation + classpath:springmvc-config.xml + + + + springmvc + / + +``` + +#### 3.在 resources 下创建 springmvc-config.xml + +只创建文件 + +#### 4.创建控制器 + +```java +@Controller +public class UserController { + @RequestMapping("/selectUser") + public String selectUser(HttpServletRequest request) { + String id = request.getParameter("id"); + System.out.println("id=" + id); + return "success"; + } +} +``` + +#### 5.创建前端页面 success.jsp + +在 WEB-INF 文件夹下面创建 jsp 文件夹,然后创建前端页面 + +```html + +success + +``` + +#### 6.解析注解和配置视图解析器 + +```java + + + + + + + + + +``` + +#### 7.在 tomcat 服务器上部署项目,发布项目 + +![image-20220506220115521](https://yovinchen-1308133012.cos.ap-beijing.myqcloud.com/image-20220506220115521.png) + +#### 7.测试 发送: + +```java +http://localhost:8080/c15/selectUser?id=1 +``` + +![image-20220506220059705](https://yovinchen-1308133012.cos.ap-beijing.myqcloud.com/image-20220506220059705.png) + +### (2)简单的数据类型 int double float string + +#### 1.控制器: + +```java +@RequestMapping(value = "/getUser") +public String getUser(int id) { + System.out.println("id=" + id); + return "success"; +} +``` + +#### 2.测试 发送 + +```java +http://localhost:8080/c15/getUser?id=4 +``` + +![image-20220506221558058](https://yovinchen-1308133012.cos.ap-beijing.myqcloud.com/image-20220506221558058.png) + + + +### 注意: + +当 **getuser()** 中的参数 **i** 要和后面的一致,在绑定时也要进行相应更改 + +![image-20220506222128788](https://yovinchen-1308133012.cos.ap-beijing.myqcloud.com/image-20220506222128788.png) + +添加注解 **@RequestParam** 就可以将 **id** 参数的值绑定到 **a** 上 + +![image-20220506222455550](https://yovinchen-1308133012.cos.ap-beijing.myqcloud.com/image-20220506222455550.png) + +### (3)POJO plain old Java object + +### 以用户注册为例: + +#### 1.创建实体类User + +```java +private Integer id; +private String username; +private String password; +实现 getter setter 和 toString 方法 +``` + +#### 2.创建前端页面 register.jsp + +```html + +
+<%-- name 属性值 和 成员变量名 保持一致--%> + 用户名: + 密码: + +
+ +``` + +#### 3.控制器 + +```java +// 该方法是用来返回register.jsp页面 +@RequestMapping("/toRegister") +public String toRegister() { + return "register"; +} + +// 该方法是用来处理数据的 +@RequestMapping("/registerUser") +public String registerUser(User user) { + System.out.println(user.getUsername() + ":" + user.getPassword()); + return "success"; +} +``` + +#### 4.测试 发布 + +![image-20220506223113983](https://yovinchen-1308133012.cos.ap-beijing.myqcloud.com/image-20220506223113983.png) + +在中文的情况下可能会发生乱码,所以添加编码过滤器,将所有文件用 utf-8 格式编码 + +在 WEB-INF 文件夹下的 web.xml 文件下的 前端控制器代码下 添加以下代码 + +```java + + + CharacterEncodingFilter + org.springframework.web.filter.CharacterEncodingFilter + + encoding + UTF-8 + + + + CharacterEncodingFilter + /* + +``` + +测试 发布:中文不会产生乱码 + +![image-20220506223612935](https://yovinchen-1308133012.cos.ap-beijing.myqcloud.com/image-20220506223612935.png) + +### (4)包装的POJO类型 + +使用简单POO类型已经可以完成多数的数据绑定,但有时客户端请求中传递的参数会比较复杂。例如,在用户查询订单时,页面传递的参数可能包括订单编号、用户名称等信息,这就包含了订单和用户两个对象的信息。如果将订单和用户的所有查询条件都封装在一个简单POJO中,显然会比较混乱,这时就可以考虑使用包装POJO类型的数据绑定。 + +#### 1.在 com.gzh.domain 包下创建名为 Orders 的类 + +```java +private Integer ordersId; +private User user; +实现 getter 和 setter 方法 +``` + +#### 2.在 com.gzh.controller 包下创建控制器类 OrdersController + +编写一个跳转到订单查询页面的方法和一个查询订单及用户信息的方法 + +```java +@Controller +public class OrdersController { + @RequestMapping("/toFindOrdersWithUser") + public String toFindOrdersWithUser(){ + return "orders"; + } + + @RequestMapping("/") + public String findOrdersWithUser(Orders orders){ + Integer ordersId = orders.getOrdersId(); + User user = orders.getUser(); + String username = user.getUsername(); + System.out.println("ordersId" + ordersId); + System.out.println("username" + username); + return "success"; + } +} +``` + +#### 3.创建前端页面 orders.jsp + +在 WEB-INF 文件夹下的 jsp 文件夹下,创建前端页面 orders.jsp + +```html + +
+ 订单编号: + 所属用户: + +
+ +``` + +#### 4.测试 发布 + +![image-20220507091032381](https://yovinchen-1308133012.cos.ap-beijing.myqcloud.com/image-20220507091032381.png) + +## 3.复杂的数据绑定 + +### (1)绑定数组 + +#### 1.创建前端页面 user.jsp + +```html + +
+ + + + + + + + + + + + + +
选择用户名
tom
jack
+ +
+ +``` + +#### 2.编写批量删除用户的方法(同时添加一个向 user.jsp 页面跳转的方法) + +```java +// 该方法是返回user.jsp的 + @RequestMapping("/toUser") + public String toUser(){ + return "user"; + } + +// 该方法是来处理user.jsp页面传递的数据 + @RequestMapping("/delect") + public String delectUser(int[] ids){ + if (ids != null){ + for (int id : ids){ + System.out.println("删除了id为"+id+"的用户"); + } + }else { + System.out.println("数组ids为空"); + } + return "success"; + } +``` + +#### 3.测试 发布: + +![image-20220506224513695](https://yovinchen-1308133012.cos.ap-beijing.myqcloud.com/image-20220506224513695.png) + + + +![image-20220506224526191](https://yovinchen-1308133012.cos.ap-beijing.myqcloud.com/image-20220506224526191.png) + +### (2)绑定集合 + +以批量修改用户为例: + +#### 1.创建包装类 UsersVo + +```java +private List users; +实现 getter 和 setter 方法 +``` + +#### 2.编写控制器方法 + +```java + @RequestMapping("/toUserEdit") + public String toUserEdit() { + return "user_edit"; + } + + @RequestMapping("/editUsers") + public String editUsers(UserVo userList) { +// 将所有用户数据封装到集合中 + List users = userList.getUsers(); +// 循环输出信息 + for (User user : users) { +// 如果接收的用户id不为空,则表示对该用户进行了修改 + if (user.getId() != null) { + System.out.println("修改了id为" + user.getId() + "的用户名为:" + user.getUsername()); + } + } + return "success"; + } +``` + +#### 3.编写前端页面 user_edit.jsp + +```html + +
+ + + + + + + + + + + + + +
选择用户名
+ + + +
+ + + +
+ +
+ +``` + +#### 4.测试发布 + +![image-20220507121847120](https://yovinchen-1308133012.cos.ap-beijing.myqcloud.com/image-20220507121847120.png) \ No newline at end of file diff --git a/JAVA/JAVA EE/Web程序设计笔记18——第十四章:JSON 数据和 RESTful 风格的 url.md b/JAVA/JAVA EE/Web程序设计笔记18——第十四章:JSON 数据和 RESTful 风格的 url.md new file mode 100644 index 0000000..8d23a68 --- /dev/null +++ b/JAVA/JAVA EE/Web程序设计笔记18——第十四章:JSON 数据和 RESTful 风格的 url.md @@ -0,0 +1,222 @@ +# 第十四章:JSON 数据和 RESTful 风格的 url + +## 1.JSON: JavaSript Object Notation + +> JSON数据的两种数据结构: +> +> 1.对象结构 +> +> 2.数组结构 + +## 2.第13章和第14章的区别: + +第13章:发送ur1,请求控制器中的某个方法,该方法返回jsp页面 +第14章:发送url,请求webapp下的jsp页面,该页面中包含一个门S0N数据,该数据会被传递到控制器中的某个方法上,然后方法再将数据返回显示到浏览器中。 + +## 3.验证JS0N数据和Java类对象的转换 + +### 1.创建项目,导包: + +```java + + org.springframework + spring-web + 4.3.6.RELEASE + + + + org.springframework + spring-webmvc + 4.3.6.RELEASE + + + com.fasterxml.jackson.core + jackson-annotations + 2.8.8 + + + + com.fasterxml.jackson.core + jackson-core + 2.8.8 + + + + com.fasterxml.jackson.core + jackson-databind + 2.8.8 + +``` + +### 2.web.xml文件 + +```java + + + index.jsp + index1.jsp + + + + + springmvc + org.springframework.web.servlet.DispatcherServlet + + + springmvc + / + +``` + +### 3.springmvc-servlet.xml文件 + +```java + + + + + + + + + + + +``` + +### 4.创建实体类对象User + +```java +package com.gzh.po; + +private String username; +private String password; +通过 getter setter 和 toString 方法生成代码 +``` + +### 5.在WEB-INF下创建 index.jsp + +```html + + 测试JSON交互 + + + + + +
+ 用户名
+ 密码
+ +
+ +``` + +### 6.导入文件 jquery-1.11.3.min.js + +在webapp下创建文件夹 js 在文件夹下复制文件 + +![image-20220513233035481](https://yovinchen-1308133012.cos.ap-beijing.myqcloud.com/image-20220513233035481.png) + +### 7.创建UserController方法 + +```java +package com.gzh.controller; + +@Controller +public class UserController { + @RequestMapping("/testJson") + @ResponseBody + public User testJson(@RequestBody User user){ + System.out.println(user); + return user; + } +} +``` + +### 8.发布项目 + +![image-20220513231414012](https://yovinchen-1308133012.cos.ap-beijing.myqcloud.com/image-20220513231414012.png) + +## 4.RESTful支持 + +### 1.在 UserController 方法中添加查询方法 + +```java +/** + *接收RESTful风格的请求,其接收方式为GET + */ +@RequestMapping(value="/user/{id}",method= RequestMethod.GET) +@ResponseBody +public User selectUser(@PathVariable("id") String id){ + //查看数据接收 + System.out.println("id="+id); + User user=new User(); + //模拟根据id查询出到用户对象数据 + if(id.equals("1234")){ + user.setUsername("tom"); + } + //返回JSON格式的数据 + return user; +} +``` + +### 2.编写页面文件 restful.jsp + +```html + +RESTful测试 + + + + + +
+ 编号: + +
+ +``` + +### 3.发布项目 + +![image-20220513232938453](https://yovinchen-1308133012.cos.ap-beijing.myqcloud.com/image-20220513232938453.png) \ No newline at end of file diff --git a/JAVA/JAVA EE/Web程序设计笔记19——第十五章:拦截器.md b/JAVA/JAVA EE/Web程序设计笔记19——第十五章:拦截器.md new file mode 100644 index 0000000..51dd017 --- /dev/null +++ b/JAVA/JAVA EE/Web程序设计笔记19——第十五章:拦截器.md @@ -0,0 +1 @@ +![](https://yovinchen-1308133012.cos.ap-beijing.myqcloud.com/image-20220512145028013.png) \ No newline at end of file diff --git a/JAVA/JAVA EE/Web程序设计笔记20——第十六章:文件上传和下载.md b/JAVA/JAVA EE/Web程序设计笔记20——第十六章:文件上传和下载.md new file mode 100644 index 0000000..4dd8c78 --- /dev/null +++ b/JAVA/JAVA EE/Web程序设计笔记20——第十六章:文件上传和下载.md @@ -0,0 +1,282 @@ +# 第十六章:文件上传和下载 + +## 1.文件上传 + +### 1.创建项目,导包 + +```java + + org.springframework + spring-web + 4.3.6.RELEASE + + + + org.springframework + spring-webmvc + 4.3.6.RELEASE + + + + commons-io + commons-io + 2.5 + + + + commons-fileupload + commons-fileupload + 1.3.2 + + + javax.servlet + servlet-api + 2.5 + +``` + +### 2.web.xml + +```java + + springmvc + + org.springframework.web.servlet.DispatcherServlet + + + contextConfigLocation + classpath:springmvc-config.xml + + 1 + + + springmvc + / + +``` + +### 3.springmvc-config.xml + +```java + + + + + + + + + + + + + + + + +``` + +### 4.创建fileUpload.jsp + +webapp下的jsp文件可以通过url直接访问 +而WEB-INF下的js文件需要控制器中的方法返回才可以访问到 + +```html + + + Title + + + +
+ 上传人: + 请选择文件: + +
+ +``` + +### 5.创建success.jsp error.jsp + +```html + +上传失败 + +``` + +```html + +上传成功 + +``` + +![image-20220517103654553](https://yovinchen-1308133012.cos.ap-beijing.myqcloud.com/image-20220517103654553.png) + +### 6.创建控制器 + +```java +package com.gzh.controller; + +/** + * 文件上传 + */ +@Controller +public class FileUploadController { + /** + * 执行文件上传 + */ + @RequestMapping("/fileUpload") + public String handleFormUpload(@RequestParam("name") String name, + @RequestParam("uploadfile") List uploadfile, + HttpServletRequest request) { + // 判断所上传文件是否存在 + if (!uploadfile.isEmpty() && uploadfile.size() > 0) { + //循环输出上传的文件 + for (MultipartFile file : uploadfile) { + // 获取上传文件的原始名称 + String originalFilename = file.getOriginalFilename(); + // 设置上传文件的保存地址目录 + String dirPath = + request.getSession().getServletContext().getRealPath("/upload/"); + File filePath = new File(dirPath); + // 如果保存文件的地址不存在,就先创建目录 + if (!filePath.exists()) { + filePath.mkdirs(); + } + // 使用UUID重新命名上传的文件名称(上传人_uuid_原始文件名称) + String newFilename = name + "_" + UUID.randomUUID() + + "_" + originalFilename; + try { + // 使用MultipartFile接口的方法完成文件上传到指定位置 + file.transferTo(new File(dirPath + newFilename)); + } catch (Exception e) { + e.printStackTrace(); + return "error"; + } + } + // 跳转到成功页面 + return "success"; + } else { + return "error"; + } + } +} +``` + +### 7.发布项目 + +![image-20220517105222969](https://yovinchen-1308133012.cos.ap-beijing.myqcloud.com/image-20220517105222969.png) + +![image-20220517105211357](https://yovinchen-1308133012.cos.ap-beijing.myqcloud.com/image-20220517105211357.png) + +![image-20220517105334825](https://yovinchen-1308133012.cos.ap-beijing.myqcloud.com/image-20220517105334825.png) + +## 2.文件下载 + +### 1.创建download.jsp + +```html + + + 下载页面 + + + + 文件下载 + + +"> + 中文名称文件下载 + + +``` + +### 2.添加控制器 + +下载文件的名字会产生乱码 + +```java +@RequestMapping("/download") +public ResponseEntity fileDownload(HttpServletRequest request,String filename) throws Exception { + // 指定要下载的文件所在路径 + String path = request.getSession().getServletContext().getRealPath("/upload/"); + // 创建该文件对象 + File file = new File(path + File.separator + filename); + // 设置响应头 + HttpHeaders headers = new HttpHeaders(); + // 通知浏览器以下载的方式打开文件 + headers.setContentDispositionFormData("attachment", filename); + // 定义以流的形式下载返回文件数据 + headers.setContentType(MediaType.APPLICATION_OCTET_STREAM); + // 使用Sring MVC框架的ResponseEntity对象封装返回下载数据 + return new ResponseEntity(FileUtils.readFileToByteArray(file), + headers, HttpStatus.OK); +} +``` + +能保证下载的文件中文名字 + +```java +@RequestMapping("/download") +public ResponseEntity fileDownload(HttpServletRequest request,String filename) throws Exception { + // 指定要下载的文件所在路径 + String path = request.getSession().getServletContext().getRealPath("/upload/"); + // 创建该文件对象 + File file = new File(path + File.separator + filename); + // 对文件名编码,防止中文文件乱码 + filename = this.getFilename(request, filename); + // 设置响应头 + HttpHeaders headers = new HttpHeaders(); + // 通知浏览器以下载的方式打开文件 + headers.setContentDispositionFormData("attachment", filename); + // 定义以流的形式下载返回文件数据 + headers.setContentType(MediaType.APPLICATION_OCTET_STREAM); + // 使用Sring MVC框架的ResponseEntity对象封装返回下载数据 + return new ResponseEntity(FileUtils.readFileToByteArray(file), + headers, HttpStatus.OK); +} + +/** + * 根据浏览器的不同进行编码设置,返回编码后的文件名 + */ +public String getFilename(HttpServletRequest request,String filename) throws Exception { + // IE不同版本User-Agent中出现的关键词 + String[] IEBrowserKeyWords = {"MSIE", "Trident", "Edge"}; + // 获取请求头代理信息 + String userAgent = request.getHeader("User-Agent"); + for (String keyWord : IEBrowserKeyWords) { + if (userAgent.contains(keyWord)) { + //IE内核浏览器,统一为UTF-8编码显示 + return URLEncoder.encode(filename, "UTF-8"); + } + } + //火狐等其它浏览器统一为ISO-8859-1编码显示 + return new String(filename.getBytes("UTF-8"), "ISO-8859-1"); +} +``` + +### 3.发布项目 + +用第一个控制器,下载的文件不是中文名称 + +![image-20220517112749837](https://yovinchen-1308133012.cos.ap-beijing.myqcloud.com/image-20220517112749837.png) + +用第二个控制器,下载的文件是中文名称 + +![image-20220517113013424](https://yovinchen-1308133012.cos.ap-beijing.myqcloud.com/image-20220517113013424.png) \ No newline at end of file diff --git a/JAVA/Springboot/1.SpringBoot之项目文件作用.md b/JAVA/Springboot/1.SpringBoot之项目文件作用.md new file mode 100644 index 0000000..803435a --- /dev/null +++ b/JAVA/Springboot/1.SpringBoot之项目文件作用.md @@ -0,0 +1,54 @@ +## SpringBoot之项目文件作用 + +下面是一张SpringBoot的项目文件图,其中项目是由`.mvn`、`src`、`target` 文件夹和`.getignore`、`HELP.md`、`mvnw`、`mvnw.cmd`、`pom.xml`、`untitled.iml`组成。(此项目是包含四个模块,模块均相同,不影响文件功能) + +![image-20230301205134729](https://yovinchen-1308133012.cos.ap-beijing.myqcloud.com/image-20230301205134729.png) + +### 1、.mvn + +`.mvn`是Spring Boot 生成,用于一键通过 **Maven**构建、编译、打包和部署的文件目录。内部结构如下: + +![image-20230301205529767](https://yovinchen-1308133012.cos.ap-beijing.myqcloud.com/image-20230301205529767.png) + +### 2、src + + + +![image-20230301205636397](https://yovinchen-1308133012.cos.ap-beijing.myqcloud.com/image-20230301205636397.png) + +``` +├── main +│ ├── java +│ │ └── com.yv --- package包名 +│ └── resources --- 资源目录 +│ ├── static --- 静态资源、js、css等 +│ ├── templates --- html前端页面文件等 +│ └── application.properites --- spring的配置文件 +└── test --- 单元测试所在的目录 +``` + +### 3、target + +应用构建时生成,主要存放了源代码编译后的 class 文件,相关的配置文件以及打好的包文件等用于实际执行的文件。 + +![image-20230301210547502](https://yovinchen-1308133012.cos.ap-beijing.myqcloud.com/image-20230301210547502.png) + +### 4、.getignore + +`.gitignore`文件用来忽略被指定的文件或文件夹的改动,被记录在`.gitignore`文件里的文件或文件夹,是无法被git跟踪到的,即被忽略的文件是不会被放入到远程仓库里的。如果文件已经存在于远程仓库中,是无法通过`.gitignore`文件来忽略的。 + +### 5、HELP.md + +项目的帮助文档,比如可以写一些项目架构的说明等内容,删除对项目运行没有影响。 + +### 6、mvnw和mvnw.cmd + +`mvnw`和`mvnw.cmd`有相同的职责,引导.mvn/wrapper/maven-wrapper.jar下载Maven二进制文件,mvnw用于Linux系统,mvnw.cmd用于Windows系统 + +### 7、pom.xml + +maven的配置文件,我们需要依赖的jar包都在这里面配置并下载使用。 + +### 8、untitled.iml + +iml(infomation of module),也就是模块信息。它是我们项目的配置文件,存储一些模块配置信息,比如Maven组件、模块路径信息。 \ No newline at end of file diff --git a/JAVA/Springboot/2.整合JUnit、Mybatis.md b/JAVA/Springboot/2.整合JUnit、Mybatis.md new file mode 100644 index 0000000..2bc7a35 --- /dev/null +++ b/JAVA/Springboot/2.整合JUnit、Mybatis.md @@ -0,0 +1,65 @@ +Spring整合JUnit的制作方式 + +```java +//加载spring整合junit专用的类运行器 +@RunWith(SpringJUnit4ClassRunner.class) +//指定对应的配置信息 +@ContextConfiguration(classes = SpringConfig.class) +public class AccountServiceTestCase { + //注入你要测试的对象 + @Autowired + private AccountService accountService; + @Test + public void testGetById(){ + //执行要测试的对象对应的方法 + System.out.println(accountService.findById(2)); + } +} +``` + +Spring整合Mybatis的制作方式(yml格式) + +```yml +spring: + datasource: + driver-class-name: com.mysql.jdbc.Driver + url: jdbc:mysql://localhost:3306/ssm_db?useSSL=false + username: root + password: 8520 +``` + +实体类 + +```JAVA +public class Book { + private Integer id; + private String type; + private String name; + private String description; +} +``` + +映射接口(Dao) + +```JAVA +@Mapper +public interface BookDao { + @Select("select * from tbl_book where id = #{id}") + public Book getById(Integer id); +} +``` + +测试类 + +```JAVA +@SpringBootTest +class Springboot05MybatisApplicationTests { + @Autowired + private BookDao bookDao; + @Test + void contextLoads() { + System.out.println(bookDao.getById(1)); + } +} +``` + diff --git a/JAVA/Springboot/3.整合MyBatis-plus、Druid.md b/JAVA/Springboot/3.整合MyBatis-plus、Druid.md new file mode 100644 index 0000000..0b0e811 --- /dev/null +++ b/JAVA/Springboot/3.整合MyBatis-plus、Druid.md @@ -0,0 +1,60 @@ +## 1.整合MyBatis-Plus + +1.导入starter + +```xml + + com.baomidou + mybatis-plus-boot-starter + 3.4.3 + +``` + +2.配置数据源相关信息 + +```yaml +#2.配置相关信息 +spring: + datasource: + driver-class-name: com.mysql.cj.jdbc.Driver + url: jdbc:mysql://localhost:3306/ssm_db + username: root + password: root +``` + +3.前数据库的表名定义规则是tbl_模块名称,为了能和实体类相对应,需要做一个配置,相关知识各位小伙伴可以到MyBatisPlus课程中去学习,此处仅给出解决方案。配置application.yml文件,添加如下配置即可,设置所有表名的通用前缀名 + +```yaml +mybatis-plus: + global-config: + db-config: + #设置所有表的通用前缀名称为tbl_ + table-prefix: tbl_ +``` + +## 2.整合Druid + +1.导入对应的starter + +```XML + + + com.alibaba + druid-spring-boot-starter + 1.2.6 + + +``` + +2.修改配置 + +```YAML +spring: + datasource: + druid: + driver-class-name: com.mysql.cj.jdbc.Driver + url: jdbc:mysql://localhost:3306/ssm_db?serverTimezone=UTC + username: root + password: root +``` + diff --git a/JAVA/报错以及问题/Mybaits连接MySQL80版本的配置.md b/JAVA/报错以及问题/Mybaits连接MySQL80版本的配置.md new file mode 100644 index 0000000..70f86d0 --- /dev/null +++ b/JAVA/报错以及问题/Mybaits连接MySQL80版本的配置.md @@ -0,0 +1,94 @@ +--- +title: Mybaits连接MySQL8.0版本的配置 +date: 2022-04-13 00:15:50.985 +updated: 2022-09-05 00:15:50.985 +url: https://hhdxw.top/archives/36 +categories: +- JAVA EE +tags: +- JAVA EE +--- + +# Mybaits连接MySQL8.0版本的配置问题 + +## 特别要注意 properties 文件中不能有**任何**错误,以及空格 + +## 1.更改 maven 文件 + +```java + + mysql + mysql-connector-java + 8.0.28 + +``` + +## 2.修改 Maven 配置文件 + +mysql 8.0 以后的版本驱动为 + +```java +com.mysql.cj.jdbc.Dirver +``` + +url 一般为 + +```java +jdbc:mysql://localhost:3306/mybatis +``` + +如果不能用的话,添加以下代码 + +```java +?useUnicode=true&characterEncoding=utf-8&serverTimezone=GMT&nullCatalogMeansCurrent = true +``` + +来添加编码集 + +## 3.使用 xml 配置方式 + +```java + + + + + + + + + + + + + + +``` + +## 4.使用的是 properties 文件的配置方式 + +```java +jdbc.driver=com.mysql.cj.jdbc.Driver +jdbc.url=jdbc:mysql://localhost:3306/mybatis?useUnicode=true&characterEncoding=utf-8&serverTimezone=GMT&nullCatalogMeansCurrent = true +jdbc.username=root +jdbc.password=8520 +``` + +```java + + + + + + + + + + + + + + + + + +``` \ No newline at end of file diff --git a/JAVA/报错以及问题/Resource注解无法导入依赖.md b/JAVA/报错以及问题/Resource注解无法导入依赖.md new file mode 100644 index 0000000..6a08fbe --- /dev/null +++ b/JAVA/报错以及问题/Resource注解无法导入依赖.md @@ -0,0 +1,30 @@ +--- +title: Resource注解无法导入依赖使用 +date: 2022-03-15 00:15:53.726 +updated: 2022-09-05 00:15:53.726 +url: https://hhdxw.top/archives/40 +categories: +- JAVA EE +tags: +- JAVA EE +--- + +最近在学习Spring的过程中遇到了一个棘手的问题:使用Resource注解时报错了。 + +![image-20220315214739187](https://yovinchen-1308133012.cos.ap-beijing.myqcloud.com/image-20220315214739187.png) + +当时上面的**@Resource**爆红,忘了截图 + +问题出现了,那么怎么解决呢。在百度上找到答案说:这是因为没有导入tomcat的包,tomcat里面默认继承了这个包,只要在**pom.xml**增加这个包的依赖,问题就解决了 + +```java + + javax.annotation + jsr250-api + 1.0 + +``` + +![image-20220315215743445](https://yovinchen-1308133012.cos.ap-beijing.myqcloud.com/image-20220315215743445.png) + +但是我用了这个方法没有用,依旧爆红,后来我换了**JDK**从16,17,1.6,1.8,在最后**JDK9**能用了 \ No newline at end of file diff --git a/JAVA/报错以及问题/关于jdbc连接mysql URL上的常见问题.md b/JAVA/报错以及问题/关于jdbc连接mysql URL上的常见问题.md new file mode 100644 index 0000000..8d9f67e --- /dev/null +++ b/JAVA/报错以及问题/关于jdbc连接mysql URL上的常见问题.md @@ -0,0 +1,57 @@ +# 关于jdbc连接mysql URL上的常见问题 + +## 编码问题 + +在url ?的后面添加如下参数: + +```xml +useUnicode=true&characterEncoding=UTF-8 +``` + +## 时区问题 + +在url ? 的后面添加如下参数 + +```xml +serverTimezone=UTC +``` + +```xml +serverTimezone=Asia/Shanghai +``` + +使用上海的时区,也可以使用Hongkong的时区 + +具体时区可以去/usr/share/zoneinfo里查询。 + +```xml +serverTimezone=GMT%2B8 +``` + +表示设置MySQL服务器的时区为GMT+8,即东八区。 + +## 零值日期 + +在url ? 的后面添加如下的参数,会把零值日期转换为 null 值。 + +```xml +zeroDateTimeBehavior = convertToNull +``` + +## 密钥问题 + +在url ? 的后面添加如下的参数,允许从服务器检索公钥以进行密码验证。 + +``` +allowPublicKeyRetrieval=true +``` + +## SSL协议问题 + +在url ? 的后面添加如下的参数,表示不使用SSL协议进行加密连接。 + +```xml +useSSL=false +``` + +##### *注意:参数间使用 & 连接* \ No newline at end of file diff --git a/Linux/LINUX常用命令总结.md b/Linux/LINUX常用命令总结.md new file mode 100644 index 0000000..80a45f4 --- /dev/null +++ b/Linux/LINUX常用命令总结.md @@ -0,0 +1,6093 @@ +# LINUX常用命令总结 + +[TOC] + + + +### 一、查询及帮助命令 + +#### 1.1 man + +语法:man [命令] + +实例:`[root@node02 ~]# man ls` + +#### 1.2 help + +语法:命令 --help + +实例:`[root@node02 ~]# ls --help` + +### 二、文件和目录操作命令 + +#### 2.1 ls + +功能:是列出目录的内容及其内容属性信息 + +语法:`ls [-alrtAFR][name...]` + +参数: + +```javascript + -a 显示所有文件及目录 (ls内定将文件名或目录名称开头为"."的视为隐藏档,不会列出)-l 除文件名称外,亦将文件型态、权限、拥有者、文件大小等资讯详细列出-r 将文件以相反次序显示(原定依英文字母次序)-t 将文件依建立时间之先后次序列出-A 同 -a ,但不列出 "." (目前目录) 及 ".." (父目录)-F 在列出的文件名称后加一符号;例如可执行档则加 "*", 目录则加 "/"-R 若目录下有文件,则以下之文件亦皆依序列出 +``` + +#### 2.2 cd + +功能:功能是从当前工作目录切换到指定的工作目录。 + +语法:`cd [dirName]` + +补充: + +"~" 也表示为 home 目录 的意思,"." 则是表示目前所在的目录,".." 则表示目前目录位置的上一层目录。 + +#### 2.3 cp + +功能:复制文件或目录 + +语法:`cp [options] source dest` + +参数: + +```javascript + -a:此选项通常在复制目录时使用,它保留链接、文件属性,并复制目录下的所有内容。其作用等于dpR参数组合。-d:复制时保留链接。这里所说的链接相当于Windows系统中的快捷方式。-f:覆盖已经存在的目标文件而不给出提示。-i:与-f选项相反,在覆盖目标文件之前给出提示,要求用户确认是否覆盖,回答"y"时目标文件将被覆盖。-p:除复制文件的内容外,还把修改时间和访问权限也复制到新文件中。-r:若给出的源文件是一个目录文件,此时将复制该目录下所有的子目录和文件。-l:不复制文件,只是生成链接文件。 +``` + +#### 2.4 find + +功能:用于查找目录及目录下的文件。 + +语法:`find [路径][选项] [操作]` + +选项: + +```javascript + -name 根据文件名查找-perm 根据文件权限查找-prune 该选项可以排除某些查找目录-user 根据文件属主查找-group 根据文件属主查找-mtime -n | +n 根据文件更改时间查找-nogroup 查找无效属组的文件-nouser 查找无有效属主的文件-newer file1 ! file2 查找更改时间比file1新但比file2旧IDE文件-type 按文件类型查找-size -n +n 按文件大小查找-mindepth n 从n级子目录开始搜索-maxdepth n 最多搜索到n级子目录 +``` + +实例: + +- 查找 /etc 目录下以 conf 结尾的文件,文件名区分大小写 + +```javascript + find /etc -name '*.conf' +``` + +- 查找当前目录下所有文件名为 aa 的文件,文件名不区分大小写 + +```javascript + [root@node02 ~]# find . -iname aa./aa./AA[root@node02 ~]# +``` + +- 查找文件所属用户为moonrong的所有文件 + +```javascript + [root@node02 home]# find . -user moonrong./moonrong./moonrong/.mozilla./moonrong/.mozilla/extensions./moonrong/.mozilla/plugins./moonrong/.bash_logout./moonrong/.bash_profile./moonrong/.bashrc[root@node02 home]# +``` + +- 查找文件所属组为moonrong的所有文件 + +```javascript + find . -group moonrong +``` + + -type  根据类型查找:如下 + +```javascript + f   文件        find . -type fd  目录        find . -type dc  字符设备文件    find . -type cb  块设备文件     find . -type bl   链接文件      find . -type lp  管道文件      find . -type p +``` + + **-size**  根据文件大小查询 + +```javascript + -n  小于 大小为 n 的文件+n  大于 大小为 n 的文件 +``` + +- 查找 /ect 目录下,小于 10000 字节的文件 + +```javascript + find /etc -size +10000c +``` + +- 查找 /etc 目录下,大于 1M 的文件 + +```javascript + find /etc -size -1M +``` + + **-mtime** + +```javascript + -n  n 天以内修改的文件。+n  n 天以外修改的文件。n  正好 n天 修改的文件 +``` + +- 查询 /etc 目录下,5天以内修改 且以 conf 结尾的文件 + +```javascript + find /etc -mtime -5 -name '*.conf' +``` + +查询 /etc 目录下,10天之前修改,且属于moonrong 的文件 + +```javascript + find /etc -mtime +10 -user moonrong +``` + + **-mmin** + +```javascript +  -n  n 分钟以内修改过的文件 +n  n 分钟之前修改过的文件 +``` + +- 查询 /etc 目录下 30分钟 之前修改过的文件 + +```javascript + find /etc -mmin +30 +``` + +- 查询 /etc 目录下 30分钟 之前修改过的目录 + +```javascript + find /etc -mmin -30 -type d +``` + +**-mindepth n**  从第 n 级目录开始搜索 + +- 从 /etc 的第三级子目录开始搜索 + +```javascript + find /etc -mindepth 3 +``` + +**-maxdepth n**  表示至多搜索到第 n-1 级子目录。 + +- 在 /etc 中搜索符合条件的文件,但最多搜索到 2级 子目录 + +```javascript + find /etc -maxdepth 3 -name '*.conf'find /etc -type f -name '*.conf' -size +10k -maxdepthc 2 +``` + +- 将目前目录及其子目录下所有最近 20 天内更新过的文件列出 + +```javascript + find . -ctime -20 +``` + +- 查找/var/log目录中更改时间在7日以前的普通文件,并在删除之前询问它们: + +```javascript + find /var/log -type f -mtime +7 -ok rm {} \; +``` + +- 查找前目录中文件属主具有读、写权限,并且文件所属组的用户和其他用户具有读权限的文件: + +```javascript + find . -type f -perm 644 -exec ls -l {} \; +``` + +- 服务器磁盘满,一般由大的日志文件导致,需找到大文件并删除 + +```javascript + find / -size +500M -print0|xargs -0 du -m|sort -nr +``` + +#### 2.5 mv + +功能:用来为文件或目录改名、或将文件或目录移入其它位置 + +语法: + +```javascript + mv [options] source destmv [options] source... directory +``` + +参数: + +```javascript + -i: 若指定目录已有同名文件,则先询问是否覆盖旧文件-f: 在 mv 操作要覆盖某已有的目标文件时不给任何指示 +``` + +实例: + +- 将文件a.1b改名为a.2b + +```javascript + mv a.1b a.2b +``` + +- 将info目录放入logs目录中。注意,如果logs目录不存在,则该命令将info改名为logs + +```javascript + mv info/ logs +``` + +- 将/usr/student下的所有文件和目录移到当前目录下 + +```javascript + mv /usr/student/* . +``` + +#### 2.6 pwd + +功能:显示当前工作目录的绝对路径 + +#### 2.7 rm + +功能:删除一个或多个文件或目录 + +语法: + +```javascript + rm [options] name... +``` + +参数: + +```javascript + -i 删除前逐一询问确认。-f 即使原档案属性设为唯读,亦直接删除,无需逐一确认。-r 将目录及以下之档案亦逐一删除。 +``` + +实例: + +- 删除当前目录下的所有文件及目录 + +```javascript +rm -r * +``` + +- 删除当前目录下的所有文件及目录,并且是直接删除,无需逐一确认命令行为 + +```javascript +rm -rf 要删除的文件名或目录 +``` + +- 删除文件名 test.txt + +```javascript +rm -rf test.txt +``` + +- 删除目录 test,不管该目录下是否有子目录或文件,都直接删除 + +```javascript +rm -rf test/ +``` + +#### 2.8 rmdir + +功能:删除空目录 + +语法: + +```javascript +rmdir [-p] dirName +``` + +参数: + +```javascript +-p 是当子目录被删除后使它也成为空目录的话,则顺便一并删除 +``` + +实例: + +- 将工作目录下,名为 AAA 的子目录删除 + +```javascript +rmdir AAA +``` + +- 在工作目录下的 BBB 目录中,删除名为 Test 的子目录。若 Test 删除后,BBB 目录成为空目录,则 BBB 亦予删除 + +```javascript +rmdir -p BBB/Test +``` + +#### 2.9 mkdir + +功能:创建目录 + +语法: + +```javascript +mkdir [-p] dirName +``` + +参数: + +```javascript +-p 确保目录名称存在,不存在的就建一个 +``` + +实例: + +- 在工作目录下,建立一个名为 AAA 的子目录 + +```javascript +mkdir AAA +``` + +- 在工作目录下的 BBB 目录中,建立一个名为 Test 的子目录。 若 BBB 目录原本不存在,则建立一个 + +```javascript +mkdir -p BBB/Test +``` + +#### 2.10 touch + +功能:创建新的空文件,改变已有文件的时间戳属性 + +语法: + +```javascript +touch [-acfm][-d<日期时间>][-r<参考文件或目录>] [-t<日期时间>][--help][--version][文件或目录…] +``` + +参数: + +```javascript +a 改变档案的读取时间记录。 +m 改变档案的修改时间记录。 +c 假如目的档案不存在,不会建立新的档案。与 --no-create 的效果一样。 +f 不使用,是为了与其他 unix 系统的相容性而保留。 +r 使用参考档的时间记录,与 --file 的效果一样。 +d 设定时间与日期,可以使用各种不同的格式。 +t 设定档案的时间记录,格式与 date 指令相同。 +--no-create 不会建立新档案。 +--help 列出指令格式。 +--version 列出版本讯息。 +``` + +实例: + +- 使用指令"touch"修改文件"testfile"的时间属性为当前系统时间 + +```javascript +touch testfile +``` + +- 创建一个名为“file”的新的空白文件 + +```javascript +touch file +``` + +#### 2.11 tree + +功能:以树形结构显示目录下的内容 + +语法: + +```javascript +tree [-aACdDfFgilnNpqstux][-I <范本样式>][-P <范本样式>][目录...] +``` + +参数 + +```javascript +-a 显示所有文件和目录。 +-A 使用ASNI绘图字符显示树状图而非以ASCII字符组合。 +-C 在文件和目录清单加上色彩,便于区分各种类型。 +-d 显示目录名称而非内容。 +-D 列出文件或目录的更改时间。 +-f 在每个文件或目录之前,显示完整的相对路径名称。 +-F 在执行文件,目录,Socket,符号连接,管道名称名称,各自加上"*","/","=","@","|"号。 +-g 列出文件或目录的所属群组名称,没有对应的名称时,则显示群组识别码。 +-i 不以阶梯状列出文件或目录名称。 +-I<范本样式> 不显示符合范本样式的文件或目录名称。 +-l 如遇到性质为符号连接的目录,直接列出该连接所指向的原始目录。 +-n 不在文件和目录清单加上色彩。 +-N 直接列出文件和目录名称,包括控制字符。 +-p 列出权限标示。 +-P<范本样式> 只显示符合范本样式的文件或目录名称。 +-q 用"?"号取代控制字符,列出文件和目录名称。 +-s 列出文件或目录大小。 +-t 用文件和目录的更改时间排序。 +-u 列出文件或目录的拥有者名称,没有对应的名称时,则显示用户识别码。 +-x 将范围局限在现行的文件系统中,若指定目录下的某些子目录,其存放于另一个文件系统上,则将该子目录予以排除在寻找范围外。 +``` + +#### 2.12 file + +功能:辨识文件类型 + +语法:`file [-bcLvz][-f <名称文件>][-m <魔法数字文件>...][文件或目录...]` + +参数: + +```javascript +-b  列出辨识结果时,不显示文件名称。 +-c  详细显示指令执行过程,便于排错或分析程序执行的情形。 +-f<名称文件>  指定名称文件,其内容有一个或多个文件名称时,让file依序辨识这些文件,格式为每列一个文件名称。 +-L  直接显示符号连接所指向的文件的类别。 +-m<魔法数字文件>  指定魔法数字文件。 +-v  显示版本信息。 +-z  尝试去解读压缩文件的内容。 +[文件或目录...] 要确定类型的文件列表,多个文件之间使用空格分开,可以使用shell通配符匹配多个文件。 +``` + +### 三、查看文件及内容处理 + +#### 3.1 cat + +功能:cat 命令用于连接文件并打印到标准输出设备上 + +语法: + +```javascript +cat [-AbeEnstTuv] [--help] [--version] fileName +``` + +参数: + +```javascript +-n 或 --number:由 1 开始对所有输出的行数编号。 +-b 或 --number-nonblank:和 -n 相似,只不过对于空白行不编号。 +-s 或 --squeeze-blank:当遇到有连续两行以上的空白行,就代换为一行的空白行。 +-v 或 --show-nonprinting:使用 ^ 和 M- 符号,除了 LFD 和 TAB 之外。 +-E 或 --show-ends : 在每行结束处显示 $。 +-T 或 --show-tabs: 将 TAB 字符显示为 ^I。 +-A, --show-all:等价于 -vET。 +-e:等价于"-vE"选项; +-t:等价于"-vT"选项; +``` + +实例: + +- 把 textfile1 的文档内容加上行号后输入 textfile2 这个文档里: + +```javascript +cat -n textfile1 > textfile2 +``` + +- 把 textfile1 和 textfile2 的文档内容加上行号(空白行不加)之后将内容附加到 textfile3 文档里: + +```javascript +cat -b textfile1 textfile2 >> textfile3 +``` + +- 清空 /etc/test.txt 文档内容: + +```javascript +cat /dev/null > /etc/test.txt +``` + +#### 3.2 tac + +功能:反向显示文件内容 + +#### 3.3 more + +功能:分页显示文件内容 + +语法: + +```javascript +more [-dlfpcsu] [-num] [+/pattern] [+linenum] [fileNames..] +``` + +参数: + +```javascript +-num 一次显示的行数 +-d 提示使用者,在画面下方显示 [Press space to continue, 'q' to quit.] ,如果使用者按错键,则会显示 [Press 'h' for instructions.] 而不是 '哔' 声 +-l 取消遇见特殊字元 ^L(送纸字元)时会暂停的功能 +-f 计算行数时,以实际上的行数,而非自动换行过后的行数(有些单行字数太长的会被扩展为两行或两行以上) +-p 不以卷动的方式显示每一页,而是先清除萤幕后再显示内容 +-c 跟 -p 相似,不同的是先显示内容再清除其他旧资料 +-s 当遇到有连续两行以上的空白行,就代换为一行的空白行 +-u 不显示下引号 (根据环境变数 TERM 指定的 terminal 而有所不同) ++/pattern 在每个文档显示前搜寻该字串(pattern),然后从该字串之后开始显示 ++num 从第 num 行开始显示 +fileNames 欲显示内容的文档,可为复数个数 +``` + +实例: + +- 逐页显示 testfile 文档内容,如有连续两行以上空白行则以一行空白行显示。 + +```javascript +more -s testfile +``` + +- 从第 20 行开始显示 testfile 之文档内容。 + +```javascript +more +20 testfile +``` + +#### 3.4 less + +功能:分页显示文件内容,与more相反 + +用 less 可以随意浏览文件,而 more 仅能向前移动,却不能向后移动,而且 less 在查看之前不会加载整个文件 + +语法: + +```javascript +less [参数] 文件 +``` + +参数: + +```javascript +-b <缓冲区大小> 设置缓冲区的大小 +-e 当文件显示结束后,自动离开 +-f 强迫打开特殊文件,例如外围设备代号、目录和二进制文件 +-g 只标志最后搜索的关键词 +-i 忽略搜索时的大小写 +-m 显示类似more命令的百分比 +-N 显示每行的行号 +-o <文件名> 将less 输出的内容在指定文件中保存起来 +-Q 不使用警告音 +-s 显示连续空行为一行 +-S 行过长时间将超出部分舍弃 +-x <数字> 将"tab"键显示为规定的数字空格 +/字符串:向下搜索"字符串"的功能 +?字符串:向上搜索"字符串"的功能 +n:重复前一个搜索(与 / 或 ? 有关) +N:反向重复前一个搜索(与 / 或 ? 有关) +b 向后翻一页 +d 向后翻半页 +h 显示帮助界面 +Q 退出less 命令 +u 向前滚动半页 +y 向前滚动一行 +空格键 滚动一页 +回车键 滚动一行 +``` + +[pagedown] + +: 向下翻动一页 + +[pageup] + +: 向上翻动一页 + +实例: + +- 查看文件 + +```javascript +cat vmware-vmusr.log +``` + +- ps查看进程信息并通过less分页显示 + +```javascript +ps -ef |less +``` + +- 查看命令历史使用记录并通过less分页显示 + +```javascript +history | less +``` + +#### 3.5 head + +功能:head命令以行为单位,取文件的内容,后面不接参数时默认打印前10行 + +语法: + +```javascript +head [参数] [文件] +``` + +参数: + +```javascript +-n 后面接数字,代表显示几行的意思 +-c 指定显示头部内容的字符数 +-v 总是显示文件名的头信息 +-q 不显示文件名的头信息 +``` + +实例: + +- 显示前5行文件内容 + +```javascript +head -n 5 file +``` + +- 显示文件名信息,并显示文件前两行 + +```javascript +head -v -n 2 test.txt +``` + +- 显示文件前5个字符 + +```javascript +head -c 5 test.txt +``` + +#### 3.6 tail + +功能:显示文件尾部的内容,默认在屏幕上显示指定文件的末尾10行 + +语法: + +```javascript +tail [参数] [文件] +``` + +参数: + +```javascript +-f 循环读取 +-q 不显示处理信息 +-v 显示详细的处理信息 +-c<数目> 显示的字节数 +-n<行数> 显示文件的尾部 n 行内容 +--pid=PID 与-f合用,表示在进程ID,PID死掉之后结束 +-q, --quiet, --silent 从不输出给出文件名的首部 +-s, --sleep-interval=S 与-f合用,表示在每次反复的间隔休眠S秒 +``` + +实例: + +- 一直变化的文件总是显示后10行 + +```javascript + tail -f 10 file +``` + +- 显示文件file的最后10行 + +```javascript +tail file +``` + +- 显示文件file的内容,从第20行至文件末尾 + +```javascript +tail +20 file +``` + +- 显示文件file的最后10个字符 + +```javascript +tail -c 10 file +``` + +#### 3.7 cut + +功能:两个主要的功能,第一是显示文件内容,第二是连接多个或多个文件。 + + 若不指定file参数,该命令将读取标准输入。 必须指定 -b、-c 或 -f 标志之一。 + +语法: + +```javascript +cut [参数] [文件] +``` + +参数: + +```javascript +-b 以字节为单位进行分割 ,仅显示行中指定直接范围的内容 +-c 以字符为单位进行分割 , 仅显示行中指定范围的字符 +-d 自定义分隔符,默认为制表符”TAB” +-f 显示指定字段的内容 , 与-d一起使用 +-n 取消分割多字节字符 +--complement 补足被选择的字节、字符或字段 +--out-delimiter 指定输出内容是的字段分割符 +``` + +#### 3.8 wc + +功能:统计文件的行数、单词数或字节数 + +语法: + +```javascript +wc [参数] [文件] +``` + +参数: + +```javascript +-w 统计字数,或--words:只显示字数。一个字被定义为由空白、跳格或换行字符分隔的字符串 +-c 统计字节数,或--bytes或--chars:只显示Bytes数 +-l 统计行数,或--lines:只显示列数 +-m 统计字符数 +-L 打印最长行的长度 +``` + +实例: + +- 统计字数 + +```javascript +wc -w test.txt +``` + +- 统计字节数 + +```javascript +wc -c test.txt +``` + +- 统计字符数 + +```javascript +wc -m test.txt +``` + +- 统计行数 + +```javascript +wc -l test.txt +``` + +- 打印最长行的长度 + +```javascript +wc -L test.txt +``` + +#### 3.9 grep + +功能:强大的文本搜索工具 + +linux系统支持三种形式的grep命令,大儿子就是grep,标准,模仿的代表。二儿子兴趣爱好多-egrep,简称扩展grep命令,其实和grep -E等价,支持基本和扩展的正则表达式。小儿子跑的最快-fgrep,简称快速grep命令,其实和grep -F等价,不支持正则表达式,按照字符串表面意思进行匹配。 + +语法: + +```javascript +grep [参数] +``` + +参数: + +```javascript +-i 搜索时,忽略大小写 +-c 只输出匹配行的数量 +-l 只列出符合匹配的文件名,不列出具体的匹配行 +-n 列出所有的匹配行,显示行号 +-h 查询多文件时不显示文件名 +-s 不显示不存在、没有匹配文本的错误信息 +-v 显示不包含匹配文本的所有行 +-w 匹配整词 +-x 匹配整行 +-r 递归搜索 +-q 禁止输出任何结果,已退出状态表示搜索是否成功 +-b 打印匹配行距文件头部的偏移量,以字节为单位 +-o 与-b结合使用,打印匹配的词据文件头部的偏移量,以字节为单位 +``` + +实例: + +- 支持多文件查询并支持使用通配符 + +```javascript +grep zwx file_* /etc/hosts +``` + +待完善 + +#### 3.10 tr + +功能:将字符进行替换、压缩、删除 + +语法: + +```javascript +tr [参数] [字符串1] [字符串2] +``` + +参数: + +```javascript +-c 选定字符串1中字符集的补集,即反选字符串1的补集 +-d 删除字符串1中出现的所有字符 +-s 删除所有重复出现的字符序列,只保留一个 +``` + +实例: + +- 实现大小写字母的互换 + +```javascript +tr "[a-z]" "[A-Z]" 不压缩具有特定字尾字符串的文件 +``` + +实例: + +- 将 /home/html/ 这个目录下所有文件和文件夹打包为当前目录下的 html.zip + +```javascript +zip -q -r html.zip /home/html +``` + +- 压缩文件 cp.zip 中删除文件 a.c + +```javascript +zip -dv cp.zip a.c +``` + +- 把/home目录下面的mydata目录压缩为mydata.zip + +```javascript +zip -r mydata.zip mydata +``` + +- 把/home目录下面的abc文件夹和123.txt压缩成为abc123.zip + +```javascript +zip -r abc123.zip abc 123.txt +``` + +- 将 logs目录打包成 log.zip + +```javascript +zip -r log.zip ./logs +``` + +### 五、信息显示命令 + +#### 5.1 uname + +功能:用于显示系统相关信息,比如主机名、内核版本号、硬件架构等。 如果未指定任何选项,其效果相当于执行”uname -s”命令,即显示系统内核的名字。 + +语法: + +```javascript +uname [参数] +``` + +参数: + +```javascript +-a 显示系统所有相关信息 +-m 显示计算机硬件架构 +-n 显示主机名称 +-r 显示内核发行版本号 +-s 显示内核名称 +-v 显示内核版本 +-p 显示主机处理器类型 +-o 显示操作系统名称 +-i 显示硬件平台 +``` + +实例: + +- 显示系统主机名、内核版本号、CPU类型等信息 + +```javascript +uname -a +``` + +- 仅显示系统主机名 + +```javascript +uname -n +``` + +- 显示当前系统的内核版本 + +```javascript +uname -r +``` + +#### 5.2 hostname + +功能:显示和设置系统的主机名 + +在使用hostname命令设置主机名后,系统并不会永久保存新的主机名,重新启动机器之后还是原来的主机名。如果需要永久修改主机名,需要同时修改/etc/hosts和/etc/sysconfig/network的相关内容 + +语法: + +```javascript +hostname [参数] +``` + +参数: + +```javascript +-a 显示主机别名 +-d 显示DNS域名 +-f 显示FQDN名称 +-i 显示主机的ip地址 +-s 显示短主机名称,在第一个点处截断 +-y 显示NIS域名 +``` + +实例: + +- 使用-a参数显示主机别名 + +```javascript +hostname -a +``` + +- 使用-i参数显示主机的ip地址 + +```javascript +hostname -i +``` + +#### 5.3 dmesg + +功能:显示开机信息,用于诊断系统故障 + +语法: + +```javascript +dmesg [参数] +``` + +参数: + +```javascript +-c 显示信息后,清除ring buffer中的内容 +-s <缓冲区大小> 预设置为8196,刚好等于ring buffer的大小 +-n 设置记录信息的层级 +``` + +实例: + +- 搜索开机信息的关键词 + +```javascript +dmesg | grep sda +``` + +- 忽略大小写搜索关键词 + +```javascript +dmesg | grep -i memory +``` + +- 显示开机信息的前20行 + +```javascript +dmesg | head -20 +``` + +- 显示开机信息的最后20行 + +```javascript +dmesg | tail -20 +``` + +- 清空dmesg环形缓冲区中的日志 + +```javascript +dmesg -c +``` + +#### 5.4 uptime + +功能:获取主机运行时间和查询Linux系统负载等信息 + +uptime命令可以显示系统已经运行了多长时间,信息显示依次为:现在时间、系统已经运行了多长时间、目前有多少登录用户、系统在过去的1分钟、5分钟和15分钟内的平均负载。 + +语法: + +```javascript +uptime [参数] +``` + +参数: + +```javascript +-p 以漂亮的格式显示机器正常运行的时间 +-s 系统自开始运行时间,格式为yyyy-mm-dd hh:mm:ss +-h 显示帮助信息 +``` + +实例: + +- 显示当前系统运行负载情况 + +```javascript +uptime +``` + +- 使用-p参数显示机器正常运行的时间 + +```javascript +uptime -p +``` + +- 使用-s参数显示机器启动时间 + +```javascript +uptime -s +``` + +#### 5.5 stat + +功能:显示文件或文件系统的详细信息 + +语法: + +```javascript +stat [参数] +``` + +参数: + +```javascript +-L 支持符号链接 +-f 显示文件系统的信息 +-t 以简洁的方式输出 +--help 显示命令帮助信息 +--version 显示命令版本信息 +``` + +实例: + +- 查看该文件或目录的状态Access,Modify,Change + +```javascript +stat myfile +``` + +- 查看文件系统信息 + +```javascript +stat -f myfile +``` + +#### 5.6 du + +功能:查看磁盘占用空间,与df不同,不是分区 + +语法: + +```javascript +du [参数] [文件] +``` + +参数: + +```javascript +-a 显示目录中所有文件大小 +-k 以KB为单位显示文件大小 +-m 以MB为单位显示文件大小 +-g 以GB为单位显示文件大小 +-h 以易读方式显示文件大小 +-s 仅显示总计 +``` + +#### 5.7 df + +功能:报告文件系统磁盘空间的使用情况 + +语法: + +```javascript +df [参数] [指定文件] +``` + +参数: + +```javascript +-a 显示所有系统文件 +-B <块大小> 指定显示时的块大小 +-h 以容易阅读的方式显示 +-H 以1000字节为换算单位来显示 +-i 显示索引字节信息 +-k 指定块大小为1KB +-l 只显示本地文件系统 +-t <文件系统类型> 只显示指定类型的文件系统 +-T 输出时显示文件系统类型 +-- -sync 在取得磁盘使用信息前,先执行sync命令 +``` + +实例: + +- 显示磁盘分区使用情况 + +```javascript +[root@ecs-d2e4 ~]# df +Filesystem 1K-blocks Used Available Use% Mounted on +/dev/xvda2 37024320 12876632 22260304 37% / +devtmpfs 1919268 0 1919268 0% /dev +tmpfs 1723972 0 1723972 0% /dev/shm +tmpfs 1723972 188820 1535152 11% /run +tmpfs 1723972 0 1723972 0% /sys/fs/cgroup +tmpfs 334148 0 334148 0% /run/user/0 +``` + +[root@ecs-d2e4 ~] + +\# + +- 以容易阅读的方式显示磁盘分区使用情况 + +```javascript +[root@ecs-d2e4 ~]# df -h +Filesystem Size Used Avail Use% Mounted on +/dev/xvda2 36G 13G 22G 37% / +devtmpfs 1.9G 0 1.9G 0% /dev +tmpfs 1.7G 0 1.7G 0% /dev/shm +tmpfs 1.7G 185M 1.5G 11% /run +tmpfs 1.7G 0 1.7G 0% /sys/fs/cgroup +tmpfs 327M 0 327M 0% /run/user/0 +``` + +[root@ecs-d2e4 ~] + +\# + +- 显示文件类型为ext3的磁盘使用情况 + +```javascript +[root@ecs-d2e4 ~]# df -t ext3 +Filesystem 1K-blocks Used Available Use% Mounted on +/dev/xvda2 37024320 12876660 22260276 37% / +``` + +- 显示指定文件所在分区的磁盘使用情况 + +```javascript +[root@ecs-d2e4 ~]# df /etc/dhcp +Filesystem 1K-blocks Used Available Use% Mounted on +/dev/xvda2 37024320 12876660 22260276 37% / +``` + +[root@ecs-d2e4 ~] + +\# + +#### 5.8 top + +功能:实时显示系统资源使用情况 + +语法: + +```javascript +top [参数] +``` + +参数: + +```javascript +-d 改变显示的更新速度,或是在交谈式指令列( interactive command)按 s +-q 没有任何延迟的显示速度,如果使用者是有 superuser 的权限,则 top 将会以最高的优先序执行 +-c 切换显示模式 +-s 安全模式,将交谈式指令取消, 避免潜在的危机 +-i 不显示任何闲置 (idle) 或无用 (zombie) 的行程 +-n 更新的次数,完成后将会退出 top +-b 批次档模式,搭配 “n” 参数一起使用,可以用来将 top 的结果输出到档案内 +``` + +实例: + +- 显示完整的进程信息 + +```javascript +[root@ecs-d2e4 ~]# top -c +top - 22:14:19 up 80 days, 6:01, 1 user, load average: 0.00, 0.01, 0.05 +Tasks: 119 total, 1 running, 118 sleeping, 0 stopped, 0 zombie +%Cpu(s): 0.0 us, 0.2 sy, 0.0 ni, 99.8 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st +KiB Mem : 3341448 total, 921024 free, 584604 used, 1835820 buff/cache +KiB Swap: 4194300 total, 4194300 free, 0 used. 2226764 avail Mem +``` + +- 以批处理模式显示程序信息 + +```javascript +[root@ecs-d2e4 ~]# top -b +top - 22:16:23 up 80 days, 6:03, 1 user, load average: 0.00, 0.01, 0.05 +Tasks: 119 total, 1 running, 118 sleeping, 0 stopped, 0 zombie +%Cpu(s): 1.3 us, 0.1 sy, 0.0 ni, 98.6 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st +KiB Mem : 3341448 total, 921580 free, 583984 used, 1835884 buff/cache +KiB Swap: 4194300 total, 4194300 free, 0 used. 2227360 avail Mem +``` + +- 以累积模式显示程序信息 + +```javascript +[root@ecs-d2e4 ~]# top -s +top - 22:19:46 up 80 days, 6:06, 1 user, load average: 0.00, 0.01, 0.05 +Tasks: 119 total, 1 running, 118 sleeping, 0 stopped, 0 zombie +%Cpu(s): 0.0 us, 0.0 sy, 0.0 ni, 99.8 id, 0.2 wa, 0.0 hi, 0.0 si, 0.0 st +KiB Mem : 3341448 total, 921244 free, 584292 used, 1835912 buff/cache +KiB Swap: 4194300 total, 4194300 free, 0 used. 2227004 avail Mem +``` + +- 设置信息更新次数 + +```javascript +[root@ecs-d2e4 ~]# top -n 2 +top - 22:20:46 up 80 days, 6:07, 1 user, load average: 0.00, 0.01, 0.05 +Tasks: 121 total, 1 running, 120 sleeping, 0 stopped, 0 zombie +%Cpu(s): 1.3 us, 0.1 sy, 0.0 ni, 98.6 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st +KiB Mem : 3341448 total, 919160 free, 586324 used, 1835964 buff/cache +KiB Swap: 4194300 total, 4194300 free, 0 used. 2224968 avail Mem +``` + +#### 5.9 free + +功能:显示系统内存情况 + +语法: + +```javascript +free [参数] +``` + +参数: + +```javascript +-b 以Byte显示内存使用情况 +-k 以kb为单位显示内存使用情况 +-m 以mb为单位显示内存使用情况 +-g 以gb为单位显示内存使用情况 +-s 持续显示内存 +-t 显示内存使用总合 +``` + +实例: + +- 以总和的形式显示内存的使用信息 + +```javascript +[root@ecs-d2e4 ~]# free -t + total used free shared buff/cache available +Mem: 3341448 583832 921472 205696 1836144 2227400 +Swap: 4194300 0 4194300 +Total: 7535748 583832 5115772 +``` + +- 周期性查询内存使用情况 + +```javascript +[root@ecs-d2e4 ~]# free -s 10 + total used free shared buff/cache available +Mem: 3341448 583232 922064 205696 1836152 2228000 +Swap: 4194300 0 4194300 + + total used free shared buff/cache available +Mem: 3341448 583976 921320 205696 1836152 2227256 +Swap: 4194300 0 4194300 + + total used free shared buff/cache available +Mem: 3341448 584100 921196 205696 1836152 2227132 +Swap: 4194300 0 4194300 +…… +``` + +#### 5.10 date + +功能:显示日期与时间 + +语法: + +```javascript +date [选项] [+输出形式] +``` + +参数: + +```javascript +-d datestr 显示 datestr 中所设定的时间 (非系统时间) +-s datestr 将系统时间设为 datestr 中所设定的时间 +-u 显示目前的格林威治时间 +--help 显示帮助信息 +--version 显示版本编号 +``` + +实例: + +- 显示当前时间 + +```javascript +[root@ecs-d2e4 ~]# date +Sun Jan 26 22:33:55 CST 2020 +``` + +[root@ecs-d2e4 ~] + +\# date '+%c' Sun 26 Jan 2020 10:34:21 PM CST + +[root@ecs-d2e4 ~] + +\# + +- 显示时间后跳行,再显示目前日期 + +```javascript +[root@ecs-d2e4 ~]# date '+%T%n%D' +22:36:53 +01/26/20 +``` + +- 显示月份与日数 + +```javascript +[root@ecs-d2e4 ~]# date '+%B %d' +January 26 +``` + +- 显示日期与设定时间(12:34:56) + +```javascript +[root@ecs-d2e4 ~]# date --date '12:34:56' +Sun Jan 26 12:34:56 CST 2020 +``` + +#### 5.11 cal + +功能:显示日历 + +语法: + +```javascript +cal [参数] [月份] [年份] +``` + +参数: + +```javascript +-l 单月分输出日历 +-3 显示最近三个月的日历 +-s 将星期天作为月的第一天 +-m 将星期一作为月的第一天 +-j 显示在当年中的第几天(儒略日) +-y 显示当年的日历 +``` + +实例: + +- 显示当前月份的日历 + +```javascript +[root@ecs-d2e4 ~]# cal + January 2020 +Su Mo Tu We Th Fr Sa + 1 2 3 4 + 5 6 7 8 9 10 11 +12 13 14 15 16 17 18 +19 20 21 22 23 24 25 +26 27 28 29 30 31 +``` + +- 显示近期三个月的日历(当前月,上一个月和下一个月) + +```javascript +[root@ecs-d2e4 ~]# cal -3 + December 2019 January 2020 February 2020 +Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa + 1 2 3 4 5 6 7 1 2 3 4 1 + 8 9 10 11 12 13 14 5 6 7 8 9 10 11 2 3 4 5 6 7 8 +15 16 17 18 19 20 21 12 13 14 15 16 17 18 9 10 11 12 13 14 15 +22 23 24 25 26 27 28 19 20 21 22 23 24 25 16 17 18 19 20 21 22 +29 30 31 26 27 28 29 30 31 23 24 25 26 27 28 29 +``` + +- 显示指定年月的日历,如显示2020年2月的日历 + +```javascript +[root@ecs-d2e4 ~]# cal 2 2020 + February 2020 +Su Mo Tu We Th Fr Sa + 1 + 2 3 4 5 6 7 8 + 9 10 11 12 13 14 15 +16 17 18 19 20 21 22 +23 24 25 26 27 28 29 +``` + +### 六、搜索文件命令 + +#### 6.1 which + +功能:在PATH变量指定的路径中,搜索某个系统命令的位置,并且返回第一个搜索结果 + +实例: + +```javascript +[root@lvs ~]# which nginx +/usr/sbin/nginx +``` + +[root@lvs ~] + +\# + +#### 6.2 find + +功能:从磁盘遍历查找文件或目录。 + +find命令用来在指定目录下查找文件。任何位于参数之前的字符串都将被视为欲查找的目录名。如果使用该命令时,不设置任何参数,则find命令将在当前目录下查找子目录与文件。并且将查找到的子目录和文件全部进行显示。 + +语法: + +```javascript +find path -option [ -print ] [ -exec -ok command ] {} \; +``` + +参数: + +```javascript +find 根据下列规则判断 path 和 expression,在命令列上第一个 - ( ) , ! 之前的部份为 path,之后的是 expression。如果 path 是空字串则使用目前路径,如果 expression 是空字串则使用 -print 为预设 expression。 + +expression 中可使用的选项有二三十个之多,在此只介绍最常用的部份。 +-mount, -xdev : 只检查和指定目录在同一个文件系统下的文件,避免列出其它文件系统中的文件 +-amin n : 在过去 n 分钟内被读取过 +-anewer file : 比文件 file 更晚被读取过的文件 +-atime n : 在过去n天内被读取过的文件 +-cmin n : 在过去 n 分钟内被修改过 +-cnewer file :比文件 file 更新的文件 +-ctime n : 在过去n天内被修改过的文件 +-empty : 空的文件-gid n or -group name : gid 是 n 或是 group 名称是 name +-ipath p, -path p : 路径名称符合 p 的文件,ipath 会忽略大小写 +-name name, -iname name : 文件名称符合 name 的文件。iname 会忽略大小写 +-size n : 文件大小 是 n 单位,b 代表 512 位元组的区块,c 表示字元数,k 表示 kilo bytes,w 是二个位元组。-type c : 文件类型是 c 的文件。 +``` + +实例: + +- 按文件名查找: + +```javascript +root@192 ~]# find /etc /usr /home -name "ifcfg-en*" +/etc/sysconfig/network-scripts/ifcfg-ens33 +``` + +[root@192 ~] + +\# + +- 找大于5M的,找到后并列出来 + +```javascript +[root@LVS ~]# find /etc -size +5M -ls +101709377 7120 -r--r--r-- 1 root root 7289802 7月 5 2017 /etc/udev/hwdb.bin +``` + +找修改时间小于5天的文件 + +```javascript +[root@LVS ~]# find /etc -mtime -5 +/etc +/etc/resolv.conf +/etc/sysconfig +``` + +#### 6.3 whereis + +功能:查找二进制命令,按环境变量 PATH路径查找。 + +该指令会在特定目录中查找符合条件的文件。这些文件应属于原始代码、二进制文件,或是帮助文件。 + +该指令只能用于查找二进制文件、源代码文件和man手册页,一般文件的定位需使用locate命令。 + +语法: + +```javascript +whereis [-bfmsu][-B <目录>...][-M <目录>...][-S <目录>...][文件...] +``` + +参数: + +```javascript +-b  只查找二进制文件。 +-B<目录>  只在设置的目录下查找二进制文件。 +-f  不显示文件名前的路径名称。 +-m  只查找说明文件。 +-M<目录>  只在设置的目录下查找说明文件。 +-s  只查找原始代码文件。 +-S<目录>  只在设置的目录下查找原始代码文件。 +-u  查找不包含指定类型的文件。 +``` + +实例: + +- 查看指令"bash"的位置 + +```javascript +[root@LVS ~]# whereis bash +bash: /usr/bin/bash /usr/share/man/man1/bash.1.gz +``` + +[root@LVS ~] + +\# + +- 只查二进制文件 + +```javascript +[root@LVS ~]# whereis -b bash +bash: /usr/bin/bash +``` + +[root@LVS ~] + +\# + +#### 6.4 locate + +功能:从[数据库](https://cloud.tencent.com/solution/database?from=10680) (/var/lib/mlocate/mlocate.db) 查找命令,使用 updatedb 更新库。 + +语法: + +```javascript +locate [-d ][--help][--version][范本样式...] +``` + +实例: + +```javascript +[root@LVS ~]# locate passwd +/etc/passwd +/etc/passwd- +/etc/pam.d/passwd +/etc/security/opasswd +``` + +### 七、用户管理命令 + +#### 7.1 useradd + +功能:用于建立用户帐号 + +语法: + +```javascript +useradd [-mMnr][-c <备注>][-d <登入目录>][-e <有效期限>][-f <缓冲天数>][-g <群组>][-G <群组>][-s ][-u ][用户帐号] +``` + +或 + +```javascript +useradd -D [-b][-e <有效期限>][-f <缓冲天数>][-g <群组>][-G <群组>][-s ] +``` + +参数: + +```javascript +-c<备注>  加上备注文字。备注文字会保存在passwd的备注栏位中。 +-d<登入目录>  指定用户登入时的起始目录。 +-D  变更预设值. +-e<有效期限>  指定帐号的有效期限。 +-f<缓冲天数>  指定在密码过期后多少天即关闭该帐号。 +-g<群组>  指定用户所属的群组。 +-G<群组>  指定用户所属的附加群组。 +-m  自动建立用户的登入目录。 +-M  不要自动建立用户的登入目录。 +-n  取消建立以用户名称为名的群组. +-r  建立系统帐号。 +-s   指定用户登入后所使用的shell。 +-u  指定用户ID。 +``` + +实例: + +- 添加的用户指定相应的用户组 + +```javascript +[root@LVS ~]# useradd -g root rossum +``` + +[root@LVS ~] + +\# id rossum uid=1002(rossum) gid=0(root) 组=0(root) + +- 添加用户,指定shell,指定用户组,指定用户id + +```javascript +[root@LVS ~]# useradd rossuma -s /sbin/nologin -g root -u 1008 +``` + +[root@LVS ~] + +\# id 1008 uid=1008(rossuma) gid=0(root) 组=0(root) + +[root@LVS ~] + +\# tail -1 /etc/passwd rossuma:x:1008:0::/home/rossuma:/sbin/nologin + +- 建立用户指定目录等信息 + +```javascript +[root@LVS ~]# useradd -d /home/mytest -g root rossumc +``` + +[root@LVS ~] + +\# su rossumc + +[rossumc@LVS root] + +$ cd ~ + +[rossumc@LVS ~] + +$ pwd /home/mytest + +#### 7.2 usermod + +功能:修改系统已经存在的用户属性。 + +语法: + +```javascript +usermod [-LU][-c <备注>][-d <登入目录>][-e <有效期限>][-f <缓冲天数>][-g <群组>][-G <群组>][-l <帐号名称>][-s ][-u ][用户帐号] +``` + +参数: + +```javascript +-c<备注>  修改用户帐号的备注文字。 +-d登入目录>  修改用户登入时的目录。 +-e<有效期限>  修改帐号的有效期限。 +-f<缓冲天数>  修改在密码过期后多少天即关闭该帐号。 +-g<群组>  修改用户所属的群组。 +-G<群组>  修改用户所属的附加群组。 +-l<帐号名称>  修改用户帐号名称。 +-L  锁定用户密码,使密码无效。 +-s  修改用户登入后所使用的shell。 +-u  修改用户ID。 +-U  解除密码锁定。 +``` + +实例: + +- 锁定用户并查看,前面有!表示锁定 + +```javascript +[root@LVS ~]# usermod -L rossumc +``` + +[root@LVS ~] + +\# grep rossumc /etc/shadow rossumc:!$6$L8f/R75W$cnjhzGGvxdNM/QCB2ZeSTRvGCi0giV7j3TC7GRSOpJowN1oP3eNhQygZrZOfMLiZif1mVNvWViTDuUCthrpsh/:18366:0:99999:7::: + +[root@LVS ~] + +\# + +也可以这样查看用户的锁定状态 + +```javascript +[root@LVS ~]# passwd --status rossumc +rossumc LK 2020-04-14 0 99999 7 -1 (密码已被锁定。) +``` + +[root@LVS ~] + +\# + +- 解除以上用户的状态 + +```javascript +[root@LVS ~]# usermod -U rossumc +``` + +[root@LVS ~] + +\# tail -1 /etc/shadow rossumc:$6$L8f/R75W$cnjhzGGvxdNM/QCB2ZeSTRvGCi0giV7j3TC7GRSOpJowN1oP3eNhQygZrZOfMLiZif1mVNvWViTDuUCthrpsh/:18366:0:99999:7::: + +[root@LVS ~] + +\# + +- 设置用户过期时间 + +```javascript +[root@LVS ~]# usermod -e "2020-04-10" rossumc +``` + +- 修改用户属性 + +```javascript +[root@LVS ~]# groupadd hr +``` + +[root@LVS ~] + +\# usermod -G hr rossumc + +[root@LVS ~] + +\# id rossumc uid=1009(rossumc) gid=0(root) 组=0(root),1002(hr) + +[root@LVS ~] + +\# + +#### 7.3 userdel + +功能:删除用户。可删除用户帐号与相关的文件。若不加参数,则仅删除用户帐号,而不删除相关文件。 + +语法: + +```javascript +userdel [-r][用户帐号] +``` + +实例: + +```javascript +[root@LVS ~]# userdel -r rossumc +userdel: user rossumc is currently used by process 11385 +这里前面登录过,所以两次退出后自动删除 +``` + +[root@LVS ~] + +\# exit exit + +[rossumc@LVS ~] + +$ exit exit + +[root@LVS ~] + +\# userdel -r rossumc userdel:用户“rossumc”不存在 + +#### 7.4 groupadd + +功能:添加用户组。 + +groupadd 命令用于创建一个新的工作组,新工作组的信息将被添加到系统文件中。 + +相关文件: + +/etc/group 组账户信息。 /etc/gshadow 安全组账户信息。 /etc/login.defs Shadow密码套件配置。 + +语法: + +```javascript +groupadd [-g gid [-o]] [-r] [-f] group +``` + +参数: + +```javascript +-g:指定新建工作组的 id; +-r:创建系统工作组,系统工作组的组ID小于 1000; +-K:覆盖配置文件 "/ect/login.defs"; +-o:允许添加组 ID 号不唯一的工作组。 +-f,--force: 如果指定的组已经存在,此选项将失明了仅以成功状态退出。当与 -g 一起使用,并且指定的GID_MIN已经存在时,选择另一个唯一的GID(即-g关闭)。 +``` + +实例: + +- 添加net01组,并指定gid为2000 + +```javascript +[root@LVS ~]# groupadd net01 -g 2000 +``` + +[root@LVS ~] + +\# grep 'net01' /etc/group net01:x:2000: + +[root@LVS ~] + +\# + +#### 7.5 passwd + +功能: 修改用户密码。 + +语法: + +```javascript +passwd [-k] [-l] [-u [-f]] [-d] [-S] [username] +``` + +参数: + +```javascript +-d 删除密码 +-f 强制执行 +-k 更新只能发送在过期之后 +-l 停止账号使用 +-S 显示密码信息 +-u 启用已被停止的账户 +-x 设置密码的有效期 +-g 修改群组密码 +-i 过期后停止用户账号 +``` + +实例: + +- 修改rossuma的密码 + +```javascript +[root@LVS ~]# passwd rossuma +更改用户 rossuma 的密码 。 +新的 密码: +重新输入新的 密码: +passwd:所有的身份验证令牌已经成功更新。 +``` + +- 查看账户密码信息 + +```javascript +[root@LVS ~]# passwd -S rossuma +rossuma PS 2020-04-15 0 99999 7 -1 (密码已设置,使用 SHA512 算法。) +``` + +- 清除用户密码 + +```javascript +[root@LVS ~]# passwd -d rossuma +清除用户的密码 rossuma。 +passwd: 操作成功 +``` + +#### 7.6 chage + +功能:修改用户密码有效期限。 + +语法: + +```javascript +chage [options] user +``` + +参数: + +```javascript + -d, --lastday 最近日期 将最近一次密码设置时间设为“最近日期” + -E, --expiredate 过期日期 将帐户过期时间设为“过期日期” + -h, --help 显示此帮助信息并推出 + -I, --inactive INACITVE 过期 INACTIVE 天数后,设定密码为失效状态 + -l, --list 显示帐户年龄信息 + -m, --mindays 最小天数 将两次改变密码之间相距的最小天数设为“最小天数” + -M, --maxdays 最大天数 将两次改变密码之间相距的最大天数设为“最大天数” + -R, --root CHROOT_DIR chroot 到的目录 + -W, --warndays 警告天数 将过期警告天数设为“警告天数” +``` + +实例: + +- 查看mysql账户的密码及有效期 + +```javascript +[root@LVS ~]# chage -l mysql +最近一次密码修改时间 :3月 29, 2020 +密码过期时间 :从不 +密码失效时间 :从不 +帐户过期时间 :从不 +两次改变密码之间相距的最小天数 :-1 +两次改变密码之间相距的最大天数 :-1 +在密码过期之前警告的天数 :-1 +``` + +[root@LVS ~] + +\# + +```javascript +[root@LVS ~]# LANG='en_us' +``` + +[root@LVS ~] + +\# chage -l mysql Last password change : Mar 29, 2020 Password expires : never Password inactive : never Account expires : never Minimum number of days between password change : -1 Maximum number of days between password change : -1 Number of days of warning before password expires : -1 + +[root@LVS ~] + +\# + +- 设置mysql用户60天后密码过期,至少7天后才能修改密码,密码过期前7天开始收到告警信息。 + +```javascript +[root@LVS ~]# chage -M 60 -m 7 -W 7 mysql +``` + +[root@LVS ~] + +\# chage -l mysql Last password change : Mar 29, 2020 Password expires : May 28, 2020 Password inactive : never Account expires : never Minimum number of days between password change : 7 Maximum number of days between password change : 60 Number of days of warning before password expires : 7 + +[root@LVS ~] + +\# + +- 强制新建用户第一次登陆时修改密码 + +```javascript +[root@LVS ~]# chage -d 0 rossuma +``` + +[root@LVS ~] + +\# chage -l rossuma Last password change : password must be changed Password expires : password must be changed Password inactive : password must be changed Account expires : never Minimum number of days between password change : 0 Maximum number of days between password change : 99999 Number of days of warning before password expires : 7 + +[root@LVS ~] + +\# + +#### 7.7 id + +功能:查看用户的 uid,gid 及归属的用户组。 + +id会显示用户以及所属群组的实际与有效ID。若两个ID相同,则仅显示实际ID。若仅指定用户名称,则显示目前用户的ID。 + +语法: + +```javascript +id [-gGnru][--help][--version][用户名称] +``` + +参数: + +```javascript +-g或--group  显示用户所属群组的ID。 +-G或--groups  显示用户所属附加群组的ID。 +-n或--name  显示用户,所属群组或附加群组的名称。 +-r或--real  显示实际ID。 +-u或--user  显示用户ID。 +``` + +实例: + +- 显示当前用户和其他用户 + +```javascript +[root@LVS ~]# id +uid=0(root) gid=0(root) groups=0(root) context=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 +``` + +[root@LVS ~] + +\# id rossuma uid=1008(rossuma) gid=0(root) groups=0(root) + +[root@LVS ~] + +\# + +- 显示所有群组信息 + +```javascript +[root@LVS ~]# usermod -G hr rossuma +``` + +[root@LVS ~] + +\# id -G rossuma 0 1002 + +[root@LVS ~] + +\# + +#### 7.8 su + +功能:用于变更为其他使用者的身份,除 root 外,需要键入该使用者的密码。 + +语法: + +```javascript +su [-fmp] [-c command] [-s shell] [--help] [--version] [-] [USER [ARG]] +``` + +参数: + +```javascript +-f 或 --fast 不必读启动档(如 csh.cshrc 等),仅用于 csh 或 tcsh +-m -p 或 --preserve-environment 执行 su 时不改变环境变数 +-c command 或 --command=command 变更为帐号为 USER 的使用者并执行指令(command)后再变回原来使用者 +-s shell 或 --shell=shell 指定要执行的 shell (bash csh tcsh 等),预设值为 /etc/passwd 内的该使用者(USER) shell +--help 显示说明文件 +--version 显示版本资讯 +- -l 或 --login 这个参数加了之后,就好像是重新 login 为该使用者一样,大部份环境变数(HOME SHELL USER等等)都是以该使用者(USER)为主,并且工作目录也会改变,如果没有指定 USER ,内定是 root +USER 欲变更的使用者帐号 +ARG 传入新的 shell 参数 +``` + +实例: + +- 变更帐号为 root 并在执行 ls 指令后退出变回原使用者 + +```javascript +[rossuma@LVS ~]# su -c ls root +``` + +- 切换用户改变环境变量,不加-不改变环境变量 + +```javascript +[toma@LVS ~]$ whoami +toma +``` + +[toma@LVS ~] + +$ su - root Password: Last login: Wed Apr 15 09:12:37 CST 2020 on pts/2 + +[root@LVS ~] + +\# whoami root + +[root@LVS ~] + +\# pwd /root + +[root@LVS ~] + +\# + +- 切换用户,不改变环境变量 + +```javascript +[toma@LVS ~]$ whoami +toma +``` + +[toma@LVS ~] + +$ pwd /home/toma + +[toma@LVS ~] + +$ su root 密码: + +[root@LVS toma] + +\# whoami root + +[root@LVS toma] + +\# pwd /home/toma + +[root@LVS toma] + +\# + +#### 7.9 sudo + +功能: 以系统管理者的身份执行指令,也就是说,经由 sudo 所执行的指令就好像是 root 亲自执行。 + +严谨些说,sudo 允许一个已授权用户以超级用户或者其它用户的角色运行一个命令。当然,能做什么不能做什么都是通过安全策略来指定的。sudo 支持插件架构的安全策略,并能把输入输出写入日志。第三方可以开发并发布自己的安全策略和输入输出日志插件,并让它们无缝的和 sudo 一起工作。默认的安全策略记录在 /etc/sudoers 文件中。而安全策略可能需要用户通过密码来验证他们自己。也就是在用户执行 sudo 命令时要求用户输入自己账号的密码。如果验证失败,sudo 命令将会退出。 + +语法: + +```javascript +sudo [-bhHpV][-s ][-u <用户>][指令] +``` + +参数: + +```javascript + -b 在后台执行指令。 + -h 显示帮助。 + -H 将HOME环境变量设为新身份的HOME环境变量。 + -k 结束密码的有效期限,也就是下次再执行sudo时便需要输入密码。 + -l 列出目前用户可执行与无法执行的指令。 + -p 改变询问密码的提示符号。 + -s 执行指定的shell。 + -u <用户> 以指定的用户作为新的身份。若不加上此参数,则预设以root作为新的身份。 + -v 延长密码有效期限5分钟。 + -V 显示版本信息。 + -S 从标准输入流替代终端来获取密码 +``` + +实例: + +- 加入轮子组并添加用户 + +```javascript +[root@LVS ~]# su tomb +``` + +[tomb@LVS root] + +$ id uid=1010(tomb) gid=1010(tomb) groups=1010(tomb),10(wheel) context=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 + +[tomb@LVS root] + +$ useradd tomc bash: /usr/sbin/useradd: Permission denied + +[tomb@LVS root] + +$ sudo useradd tomc + +[sudo] + +password for tomb: + +[tomb@LVS root] + +$ id tomc uid=1011(tomc) gid=1011(tomc) groups=1011(tomc) + +### 八、基础网络操作命令 + +#### 8.1 scp + +功能:scp 全拼 secure copy,用于不同主机之间复制文件。 + +语法: + +```javascript +scp [-1246BCpqrv] [-c cipher] [-F ssh_config] [-i identity_file] +[-l limit] [-o ssh_option] [-P port] [-S program] +[[user@]host1:]file1 [...] [[user@]host2:]file2 +``` + +简易写法 + +```javascript +scp [可选参数] file_source file_target +``` + +参数: + +```javascript +-1: 强制scp命令使用协议ssh1 +-2: 强制scp命令使用协议ssh2 +-4: 强制scp命令只使用IPv4寻址 +-6: 强制scp命令只使用IPv6寻址 +-B: 使用批处理模式(传输过程中不询问传输口令或短语) +-C: 允许压缩。(将-C标志传递给ssh,从而打开压缩功能) +-p:保留原文件的修改时间,访问时间和访问权限。 +-q: 不显示传输进度条。 +-r: 递归复制整个目录。 +-v:详细方式显示输出。scp和ssh(1)会显示出整个过程的调试信息。这些信息用于调试连接,验证和配置问题。 +-c cipher: 以cipher将数据传输进行加密,这个选项将直接传递给ssh。 +-F ssh_config: 指定一个替代的ssh配置文件,此参数直接传递给ssh。 +-i identity_file: 从指定文件中读取传输时使用的密钥文件,此参数直接传递给ssh。 +-l limit: 限定用户所能使用的带宽,以Kbit/s为单位。 +-o ssh_option: 如果习惯于使用ssh_config(5)中的参数传递方式, +-P port:注意是大写的P, port是指定数据传输用到的端口号 +-S program: 指定加密传输时所使用的程序。此程序必须能够理解ssh(1)的选项。 +``` + +实例: + +- 从本地复制文件到远程服务器 + +```javascript +scp local_file remote_username@remote_ip:remote_folder +或者 +scp local_file remote_username@remote_ip:remote_file +或者 +scp local_file remote_ip:remote_folder +或者 +scp local_file remote_ip:remote_file +[root@LVS ~]# scp score.sql 192.168.100.106:/home/toma +root@192.168.100.106's password: +score.sql 100% 1936 1.9KB/s 00:00 +[root@LVS ~]# scp student1.txt root@192.168.100.106:/home/toma/ +root@192.168.100.106's password: +student1.txt 100% 198 0.2KB/s 00:00 +``` + +[root@LVS ~] + +\# + +- 从本地复制目录到远程服务器 + +```javascript +[root@LVS ~]# mkdir -p /mydira/mydir{1..5} +``` + +[root@LVS ~] + +\# tree /mydira /mydira ├── mydir1 ├── mydir2 ├── mydir3 ├── mydir4 └── mydir5 5 directories, 0 files + +[root@LVS ~] + +\# + +[root@LVS ~] + +\# scp -r /mydira root@192.168.100.106:/home/toma root@192.168.100.106's password: + +[root@LVS ~] + +\# + +#### 8.2 wget + +功能: 非交互式的网络文件下载工具。 + +语法: + +```javascript + wget [选项]... [URL]... +``` + +参数: + +```javascript +启动: + -V, --version 显示 Wget 的版本信息并退出。 + -h, --help 打印此帮助。 + -b, --background 启动后转入后台。 + -e, --execute=COMMAND 运行一个“.wgetrc”风格的命令。 + +日志和输入文件: + -o, --output-file=FILE 将日志信息写入 FILE。 + -a, --append-output=FILE 将信息添加至 FILE。 + -d, --debug 打印大量调试信息。 + -q, --quiet 安静模式 (无信息输出)。 + -v, --verbose 详尽的输出 (此为默认值)。 + -nv, --no-verbose 关闭详尽输出,但不进入安静模式。 + --report-speed=TYPE Output bandwidth as TYPE. TYPE can be bits. + -i, --input-file=FILE 下载本地或外部 FILE 中的 URLs。 + -F, --force-html 把输入文件当成 HTML 文件。 + -B, --base=URL 解析与 URL 相关的 + HTML 输入文件 (由 -i -F 选项指定)。 + --config=FILE Specify config file to use. + +下载: + -t, --tries=NUMBER 设置重试次数为 NUMBER (0 代表无限制)。 + --retry-connrefused 即使拒绝连接也是重试。 + -O, --output-document=FILE 将文档写入 FILE。 + -nc, --no-clobber skip downloads that would download to + existing files (overwriting them). + -c, --continue 断点续传下载文件。 + --progress=TYPE 选择进度条类型。 + -N, --timestamping 只获取比本地文件新的文件。 + --no-use-server-timestamps 不用服务器上的时间戳来设置本地文件。 + -S, --server-response 打印服务器响应。 + --spider 不下载任何文件。 + -T, --timeout=SECONDS 将所有超时设为 SECONDS 秒。 + --dns-timeout=SECS 设置 DNS 查寻超时为 SECS 秒。 + --connect-timeout=SECS 设置连接超时为 SECS 秒。 + --read-timeout=SECS 设置读取超时为 SECS 秒。 + -w, --wait=SECONDS 等待间隔为 SECONDS 秒。 + --waitretry=SECONDS 在获取文件的重试期间等待 1..SECONDS 秒。 + --random-wait 获取多个文件时,每次随机等待间隔 + 0.5*WAIT...1.5*WAIT 秒。 + --no-proxy 禁止使用代理。 + -Q, --quota=NUMBER 设置获取配额为 NUMBER 字节。 + --bind-address=ADDRESS 绑定至本地主机上的 ADDRESS (主机名或是 IP)。 + --limit-rate=RATE 限制下载速率为 RATE。 + --no-dns-cache 关闭 DNS 查寻缓存。 + --restrict-file-names=OS 限定文件名中的字符为 OS 允许的字符。 + --ignore-case 匹配文件/目录时忽略大小写。 + -4, --inet4-only 仅连接至 IPv4 地址。 + -6, --inet6-only 仅连接至 IPv6 地址。 + --prefer-family=FAMILY 首先连接至指定协议的地址 + FAMILY 为 IPv6,IPv4 或是 none。 + --user=USER 将 ftp 和 http 的用户名均设置为 USER。 + --password=PASS 将 ftp 和 http 的密码均设置为 PASS。 + --ask-password 提示输入密码。 + --no-iri 关闭 IRI 支持。 + --local-encoding=ENC IRI (国际化资源标识符) 使用 ENC 作为本地编码。 + --remote-encoding=ENC 使用 ENC 作为默认远程编码。 + --unlink remove file before clobber. + +目录: + -nd, --no-directories 不创建目录。 + -x, --force-directories 强制创建目录。 + -nH, --no-host-directories 不要创建主目录。 + --protocol-directories 在目录中使用协议名称。 + -P, --directory-prefix=PREFIX 以 PREFIX/... 保存文件 + --cut-dirs=NUMBER 忽略远程目录中 NUMBER 个目录层。 + +HTTP 选项: + --http-user=USER 设置 http 用户名为 USER。 + --http-password=PASS 设置 http 密码为 PASS。 + --no-cache 不在服务器上缓存数据。 + --default-page=NAME 改变默认页 + (默认页通常是“index.html”)。 + -E, --adjust-extension 以合适的扩展名保存 HTML/CSS 文档。 + --ignore-length 忽略头部的‘Content-Length’区域。 + --header=STRING 在头部插入 STRING。 + --max-redirect 每页所允许的最大重定向。 + --proxy-user=USER 使用 USER 作为代理用户名。 + --proxy-password=PASS 使用 PASS 作为代理密码。 + --referer=URL 在 HTTP 请求头包含‘Referer: URL’。 + --save-headers 将 HTTP 头保存至文件。 + -U, --user-agent=AGENT 标识为 AGENT 而不是 Wget/VERSION。 + --no-http-keep-alive 禁用 HTTP keep-alive (永久连接)。 + --no-cookies 不使用 cookies。 + --load-cookies=FILE 会话开始前从 FILE 中载入 cookies。 + --save-cookies=FILE 会话结束后保存 cookies 至 FILE。 + --keep-session-cookies 载入并保存会话 (非永久) cookies。 + --post-data=STRING 使用 POST 方式;把 STRING 作为数据发送。 + --post-file=FILE 使用 POST 方式;发送 FILE 内容。 + --content-disposition 当选中本地文件名时 + 允许 Content-Disposition 头部 (尚在实验)。 + --content-on-error output the received content on server errors. + --auth-no-challenge 发送不含服务器询问的首次等待 + 的基本 HTTP 验证信息。 + +HTTPS (SSL/TLS) 选项: + --secure-protocol=PR 选择安全协议,可以是 auto、SSLv2、 + SSLv3 或是 TLSv1 中的一个。 + --no-check-certificate 不要验证服务器的证书。 + --certificate=FILE 客户端证书文件。 + --certificate-type=TYPE 客户端证书类型,PEM 或 DER。 + --private-key=FILE 私钥文件。 + --private-key-type=TYPE 私钥文件类型,PEM 或 DER。 + --ca-certificate=FILE 带有一组 CA 认证的文件。 + --ca-directory=DIR 保存 CA 认证的哈希列表的目录。 + --random-file=FILE 带有生成 SSL PRNG 的随机数据的文件。 + --egd-file=FILE 用于命名带有随机数据的 EGD 套接字的文件。 + +FTP 选项: + --ftp-user=USER 设置 ftp 用户名为 USER。 + --ftp-password=PASS 设置 ftp 密码为 PASS。 + --no-remove-listing 不要删除‘.listing’文件。 + --no-glob 不在 FTP 文件名中使用通配符展开。 + --no-passive-ftp 禁用“passive”传输模式。 + --preserve-permissions 保留远程文件的权限。 + --retr-symlinks 递归目录时,获取链接的文件 (而非目录)。 + +WARC options: + --warc-file=FILENAME save request/response data to a .warc.gz file. + --warc-header=STRING insert STRING into the warcinfo record. + --warc-max-size=NUMBER set maximum size of WARC files to NUMBER. + --warc-cdx write CDX index files. + --warc-dedup=FILENAME do not store records listed in this CDX file. + --no-warc-compression do not compress WARC files with GZIP. + --no-warc-digests do not calculate SHA1 digests. + --no-warc-keep-log do not store the log file in a WARC record. + --warc-tempdir=DIRECTORY location for temporary files created by the + WARC writer. + +递归下载: + -r, --recursive 指定递归下载。 + -l, --level=NUMBER 最大递归深度 (inf 或 0 代表无限制,即全部下载)。 + --delete-after 下载完成后删除本地文件。 + -k, --convert-links 让下载得到的 HTML 或 CSS 中的链接指向本地文件。 + --backups=N before writing file X, rotate up to N backup files. + -K, --backup-converted 在转换文件 X 前先将它备份为 X.orig。 + -m, --mirror -N -r -l inf --no-remove-listing 的缩写形式。 + -p, --page-requisites 下载所有用于显示 HTML 页面的图片之类的元素。 + --strict-comments 用严格方式 (SGML) 处理 HTML 注释。 + +递归接受/拒绝: + -A, --accept=LIST 逗号分隔的可接受的扩展名列表。 + -R, --reject=LIST 逗号分隔的要拒绝的扩展名列表。 + --accept-regex=REGEX regex matching accepted URLs. + --reject-regex=REGEX regex matching rejected URLs. + --regex-type=TYPE regex type (posix|pcre). + -D, --domains=LIST 逗号分隔的可接受的域列表。 + --exclude-domains=LIST 逗号分隔的要拒绝的域列表。 + --follow-ftp 跟踪 HTML 文档中的 FTP 链接。 + --follow-tags=LIST 逗号分隔的跟踪的 HTML 标识列表。 + --ignore-tags=LIST 逗号分隔的忽略的 HTML 标识列表。 + -H, --span-hosts 递归时转向外部主机。 + -L, --relative 只跟踪有关系的链接。 + -I, --include-directories=LIST 允许目录的列表。 + --trust-server-names use the name specified by the redirection + url last component. + -X, --exclude-directories=LIST 排除目录的列表。 + -np, --no-parent 不追溯至父目录。 +``` + +实例: + +- 使用wget -O下载并以不同的文件名保存(-O:下载文件到对应目录,并且修改文件名称) + +```javascript +[root@LVS ~]# wget -O index.zip http://www.haopython.com +--2020-04-15 14:41:24-- http://www.haopython.com/ +正在解析主机 www.haopython.com (www.haopython.com)... 212.64.86.215 +正在连接 www.haopython.com (www.haopython.com)|212.64.86.215|:80... 已连接。 +已发出 HTTP 请求,正在等待回应... 200 OK +长度:未指定 [text/html] +正在保存至: “index.zip” + + [ <=> ] 90,566 221KB/s 用时 0.4s + +2020-04-15 14:41:25 (221 KB/s) - “index.zip” 已保存 [90566] +``` + +- 使用wget -b后台下载,可以使用tail -f wget-log查看进度 + +```javascript +[root@LVS ~]# wget -b http://www.haopython.com +继续在后台运行,pid 为 17404。 +将把输出写入至 “wget-log”。 +``` + +[root@LVS ~] + +\# tail -f wget-log 正在连接 www.haopython.com (www.haopython.com)|212.64.86.215|:80... 已连接。 已发出 HTTP 请求,正在等待回应... 200 OK 长度:未指定 [text/html] 正在保存至: “index.html.1” 0K .......... .......... .......... .......... .......... 174K 50K .......... .......... .......... ........ 321K=0.4s 2020-04-15 14:45:52 (217 KB/s) - “index.html.1” 已保存 [90566] + +- 利用-spider: 模拟下载 ,不会下载,只是会检查是否网站是否好着 + +```javascript +[root@LVS ~]# wget --spider http://www.haopython.com +开启 Spider 模式。检查是否存在远程文件。 +--2020-04-15 14:48:46-- http://www.haopython.com/ +正在解析主机 www.haopython.com (www.haopython.com)... 212.64.86.215 +正在连接 www.haopython.com (www.haopython.com)|212.64.86.215|:80... 已连接。 +已发出 HTTP 请求,正在等待回应... 200 OK +长度:未指定 [text/html] +存在远程文件且该文件可能含有更深层的链接, +但不能进行递归操作 -- 无法获取。 +``` + +- 模拟下载打印服务器响应 + +```javascript +[root@LVS ~]# wget -S http://www.haopython.com +--2020-04-15 14:50:48-- http://www.haopython.com/ +正在解析主机 www.haopython.com (www.haopython.com)... 212.64.86.215 +正在连接 www.haopython.com (www.haopython.com)|212.64.86.215|:80... 已连接。 +已发出 HTTP 请求,正在等待回应... + HTTP/1.1 200 OK + Server: nginx + Date: Wed, 15 Apr 2020 06:50:49 GMT + Content-Type: text/html; charset=UTF-8 + Transfer-Encoding: chunked + Connection: keep-alive + Keep-Alive: timeout=60 + Link: ; rel="https://api.w.org/" +长度:未指定 [text/html] +正在保存至: “index.html.2” + + [ <=> ] 90,566 217KB/s 用时 0.4s + +2020-04-15 14:50:49 (217 KB/s) - “index.html.2” 已保存 [90566] +``` + +- 设定指定次数 + +```javascript +[root@LVS ~]# wget -r --tries=2 www.haopython.com +--2020-04-15 14:53:45-- http://www.haopython.com/ +正在解析主机 www.haopython.com (www.haopython.com)... 212.64.86.215 +正在连接 www.haopython.com (www.haopython.com)|212.64.86.215|:80... 已连接。 +已发出 HTTP 请求,正在等待回应... 200 OK +长度:未指定 [text/html] +正在保存至: “www.haopython.com/index.html” + + [ <=> ] 90,566 231KB/s 用时 0.4s + +2020-04-15 14:53:45 (231 KB/s) - “www.haopython.com/index.html” 已保存 [90566] + +正在载入 robots.txt;请忽略错误消息。 +--2020-04-15 14:53:45-- http://www.haopython.com/robots.txt +再次使用存在的到 www.haopython.com:80 的连接。 +已发出 HTTP 请求,正在等待回应... 200 OK +长度:未指定 [text/plain] +正在保存至: “www.haopython.com/robots.txt” + + [ <=> ] 67 --.-K/s 用时 0s + +2020-04-15 14:53:46 (664 KB/s) - “www.haopython.com/robots.txt” 已保存 [67] +``` + +#### 8.3 ping + +功能: 测试主机之间网络的连通性。 + +语法: + +```javascript +ping [-dfnqrRv][-c<完成次数>][-i<间隔秒数>][-I<网络界面>][-l<前置载入>][-p<范本样式>][-s<数据包大小>][-t<存活数值>][主机名称或IP地址] +``` + +参数: + +```javascript +-d 使用Socket的SO_DEBUG功能。 +-c<完成次数> 设置完成要求回应的次数。 +-f 极限检测。 +-i<间隔秒数> 指定收发信息的间隔时间。 +-I<网络界面> 使用指定的网络接口送出数据包。 +-l<前置载入> 设置在送出要求信息之前,先行发出的数据包。 +-n 只输出数值。 +-p<范本样式> 设置填满数据包的范本样式。 +-q 不显示指令执行过程,开头和结尾的相关信息除外。 +-r 忽略普通的Routing Table,直接将数据包送到远端主机上。 +-R 记录路由过程。 +-s<数据包大小> 设置数据包的大小。 +-t<存活数值> 设置存活数值TTL的大小。 +-v 详细显示指令的执行过程。 +``` + +实例: + +- 检测是否与主机连通 + +```javascript +[root@LVS ~]# ping www.haopython.com +PING www.haopython.com (212.64.86.215) 56(84) bytes of data. +^C +--- www.haopython.com ping statistics --- +17 packets transmitted, 0 received, 100% packet loss, time 16013ms +``` + +[root@LVS ~] + +\# ping www.baidu.com PING www.a.shifen.com (220.181.38.150) 56(84) bytes of data. 64 bytes from 220.181.38.150 (220.181.38.150): icmp_seq=1 ttl=53 time=22.3 ms 64 bytes from 220.181.38.150 (220.181.38.150): icmp_seq=2 ttl=53 time=22.2 ms ^C --- www.a.shifen.com ping statistics --- 2 packets transmitted, 2 received, 0% packet loss, time 1001ms rtt min/avg/max/mdev = 22.249/22.295/22.342/0.156 ms + +[root@LVS ~] + +\# + +- 指定接收包的次数 + +```javascript +[root@LVS ~]# ping -c 6 www.baidu.com +PING www.baidu.com (220.181.38.150) 56(84) bytes of data. +64 bytes from 220.181.38.150 (220.181.38.150): icmp_seq=1 ttl=53 time=21.8 ms +64 bytes from 220.181.38.150 (220.181.38.150): icmp_seq=2 ttl=53 time=25.0 ms +64 bytes from 220.181.38.150 (220.181.38.150): icmp_seq=3 ttl=53 time=21.6 ms +64 bytes from 220.181.38.150 (220.181.38.150): icmp_seq=4 ttl=53 time=21.5 ms +64 bytes from 220.181.38.150 (220.181.38.150): icmp_seq=5 ttl=53 time=27.3 ms +64 bytes from 220.181.38.150 (220.181.38.150): icmp_seq=6 ttl=53 time=22.2 ms + +--- www.baidu.com ping statistics --- +6 packets transmitted, 6 received, 0% packet loss, time 5011ms +rtt min/avg/max/mdev = 21.526/23.265/27.315/2.171 ms +``` + +[root@LVS ~] + +\# + +- 指定发送周期为3秒包大小1000Byte和TTL时间linux下ping包的默认大小为64Byte,次数不限。但有时我们需要尝试ping[大数据](https://cloud.tencent.com/solution/bigdata?from=10680)包,来测试网络的状况,这时,就要指定ping包的大小了。 + +```javascript +[root@LVS ~]# ping -i 3 -s 1000 -t 255 -c 2 www.baidu.com +PING www.baidu.com (220.181.38.150) 1000(1028) bytes of data. +1008 bytes from 220.181.38.150 (220.181.38.150): icmp_seq=1 ttl=53 time=24.2 ms +1008 bytes from 220.181.38.150 (220.181.38.150): icmp_seq=2 ttl=53 time=27.0 ms + +--- www.baidu.com ping statistics --- +2 packets transmitted, 2 received, 0% packet loss, time 3004ms +rtt min/avg/max/mdev = 24.267/25.676/27.085/1.409 ms +``` + +#### 8.4 route + +功能:显示和设置 linux 系统的路由表。 + +实例: + +- 查看本机路由表 + +```javascript +[root@LVS ~]# route -n +Kernel IP routing table +Destination Gateway Genmask Flags Metric Ref Use Iface +0.0.0.0 192.168.100.1 0.0.0.0 UG 100 0 0 ens33 +192.168.100.0 0.0.0.0 255.255.255.0 U 100 0 0 ens33 +192.168.122.0 0.0.0.0 255.255.255.0 U 0 0 0 virbr0 +``` + +[root@LVS ~] + +\# + +#### 8.5 ifconfig + +功能: 命令用于显示或设置网络设备。 + +语法: + +```javascript +ifconfig [网络设备][down up -allmulti -arp -promisc][add<地址>][del<地址>][<硬件地址>][io_addr][irq][media<网络媒介类型>][mem_start<内存地址>][metric<数目>][mtu<字节>][netmask<子网掩码>][tunnel<地址>][-broadcast<地址>][-pointopoint<地址>][IP地址] +``` + +参数: + +```javascript +add<地址> 设置网络设备IPv6的IP地址。 +del<地址> 删除网络设备IPv6的IP地址。 +down 关闭指定的网络设备。 +<硬件地址> 设置网络设备的类型与硬件地址。 +io_addr 设置网络设备的I/O地址。 +irq 设置网络设备的IRQ。 +media<网络媒介类型> 设置网络设备的媒介类型。 +mem_start<内存地址> 设置网络设备在主内存所占用的起始地址。 +metric<数目> 指定在计算数据包的转送次数时,所要加上的数目。 +mtu<字节> 设置网络设备的MTU。 +netmask<子网掩码> 设置网络设备的子网掩码。 +tunnel<地址> 建立IPv4与IPv6之间的隧道通信地址。 +up 启动指定的网络设备。 +-broadcast<地址> 将要送往指定地址的数据包当成广播数据包来处理。 +-pointopoint<地址> 与指定地址的网络设备建立直接连线,此模式具有保密功能。 +-promisc 关闭或启动指定网络设备的promiscuous模式。 +[IP地址] 指定网络设备的IP地址。 +[网络设备] 指定网络设备的名称。 +``` + +实例: + +- 显示网络设备信息 + +```javascript +[root@LVS ~]# ifconfig +ens33: flags=4163 mtu 1500 + inet 192.168.100.106 netmask 255.255.255.0 broadcast 192.168.100.255 + inet6 fe80::e65:fc2a:ca83:27d0 prefixlen 64 scopeid 0x20 + ether 00:0c:29:68:45:f4 txqueuelen 1000 (Ethernet) + RX packets 129442 bytes 20024014 (19.0 MiB) + RX errors 0 dropped 0 overruns 0 frame 0 + TX packets 11350 bytes 1422667 (1.3 MiB) + TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 + +lo: flags=73 mtu 65536 + inet 127.0.0.1 netmask 255.0.0.0 + inet6 ::1 prefixlen 128 scopeid 0x10 + loop txqueuelen 1 (Local Loopback) + RX packets 4362 bytes 452809 (442.1 KiB) + RX errors 0 dropped 0 overruns 0 frame 0 + TX packets 4362 bytes 452809 (442.1 KiB) + TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 + +virbr0: flags=4099 mtu 1500 + inet 192.168.122.1 netmask 255.255.255.0 broadcast 192.168.122.255 + ether 52:54:00:a4:73:ea txqueuelen 1000 (Ethernet) + RX packets 0 bytes 0 (0.0 B) + RX errors 0 dropped 0 overruns 0 frame 0 + TX packets 0 bytes 0 (0.0 B) + TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 +``` + +- 启动关闭指定网卡 + +```javascript +[root@LVS ~]# ifconfig eth0 down +``` + +[root@LVS ~] + +\# ifconfig eth0 up + +[root@LVS ~] + +\# + +- 配置IP地址 + +```javascript +[root@LVS ~]# ifconfig ens33 192.168.100.106 netmask 255.255.255.0 broadcast 192.168.100.255 +``` + +[root@LVS ~] + +\# + +- 启用和关闭arp协议 + +```javascript + [root@LVS ~]# ifconfig ens33 arp[root@LVS ~]# ifconfig ens33 -arp #关闭后SSH无法连接[root@LVS ~]# +``` + +- 设置最大传输单元 + +```javascript + [root@LVS ~]# ifconfig ens33 mtu 1500 +``` + +补:启动和关闭网卡 + +```javascript +[root@LVS ~]# ifup ens33 +``` + +[root@LVS ~] + +\# ifdown ens33 + +#### 8.6 netstat + +功能:查看网络状态。 + +语法: + +```javascript +netstat [-acCeFghilMnNoprstuvVwx][-A<网络类型>][--ip] +``` + +参数: + +```javascript +-a或--all 显示所有连线中的Socket。 +-A<网络类型>或--<网络类型> 列出该网络类型连线中的相关地址。 +-c或--continuous 持续列出网络状态。 +-C或--cache 显示路由器配置的快取信息。 +-e或--extend 显示网络其他相关信息。 +-F或--fib 显示FIB。 +-g或--groups 显示多重广播功能群组组员名单。 +-h或--help 在线帮助。 +-i或--interfaces 显示网络界面信息表单。 +-l或--listening 显示监控中的服务器的Socket。 +-M或--masquerade 显示伪装的网络连线。 +-n或--numeric 直接使用IP地址,而不通过域名服务器。 +-N或--netlink或--symbolic 显示网络硬件外围设备的符号连接名称。 +-o或--timers 显示计时器。 +-p或--programs 显示正在使用Socket的程序识别码和程序名称。 +-r或--route 显示Routing Table。 +-s或--statistice 显示网络工作信息统计表。 +-t或--tcp 显示TCP传输协议的连线状况。 +-u或--udp 显示UDP传输协议的连线状况。 +-v或--verbose 显示指令执行过程。 +-V或--version 显示版本信息。 +-w或--raw 显示RAW传输协议的连线状况。 +-x或--unix 此参数的效果和指定"-A unix"参数相同。 +--ip或--inet 此参数的效果和指定"-A inet"参数相同。 +``` + +实例: + +- 显示详细的网络状况 + +```javascript +[root@LVS ~]# netstat -a +Active Internet connections (servers and established) +Proto Recv-Q Send-Q Local Address Foreign Address State +tcp 0 0 0.0.0.0:sunrpc 0.0.0.0:* LISTEN +tcp 0 0 LVS:domain 0.0.0.0:* LISTEN +tcp 0 0 0.0.0.0:ssh 0.0.0.0:* LISTEN +tcp 0 0 localhost:ipp 0.0.0.0:* LISTEN +tcp 0 0 localhost:6011 0.0.0.0:* LISTEN +tcp 0 0 localhost:6012 0.0.0.0:* LISTEN +tcp 0 0 localhost:6013 0.0.0.0:* LISTEN +tcp 0 0 localhost:6014 0.0.0.0:* LISTEN +``` + +- 显示当前户籍UDP连接状况 + +```javascript +[root@LVS ~]# netstat -nu +Active Internet connections (w/o servers) +Proto Recv-Q Send-Q Local Address Foreign Address State +udp 0 0 192.168.100.106:59819 111.230.189.174:123 ESTABLISHED +udp 0 0 192.168.100.106:46885 78.46.102.180:123 ESTABLISHED +udp 0 0 192.168.100.106:50997 162.159.200.123:123 ESTABLISHED +udp 0 0 192.168.100.106:39874 108.59.2.24:123 ESTABLISHED +``` + +[root@LVS ~] + +\# + +- 显示UDP端口号的使用情况 + +```javascript +[root@LVS ~]# netstat -apu +Active Internet connections (servers and established) +Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name +udp 0 0 0.0.0.0:mdns 0.0.0.0:* 588/avahi-daemon: r +udp 0 0 0.0.0.0:hpoms-dps-lstn 0.0.0.0:* 21193/dhclient +udp 0 0 localhost:323 0.0.0.0:* 572/chronyd +udp 0 0 LVS:59819 111.230.189.174:ntp ESTABLISHED 572/chronyd +udp 0 0 LVS:46885 78.46.102.180:ntp ESTABLISHED 572/chronyd +udp 0 0 LVS:50997 162.159.200.123:ntp ESTABLISHED 572/chronyd +``` + +- 显示网卡列表 + +```javascript +[root@LVS ~]# netstat -i +Kernel Interface table +Iface MTU RX-OK RX-ERR RX-DRP RX-OVR TX-OK TX-ERR TX-DRP TX-OVR Flg +ens33 1500 133114 0 0 0 12200 0 0 0 BMRU +lo 65536 4643 0 0 0 4643 0 0 0 LRU +virbr0 1500 0 0 0 0 0 0 0 0 BMU +``` + +[root@LVS ~] + +\# + +- 显示组播组的关系 + +```javascript +[root@LVS ~]# netstat -g +IPv6/IPv4 Group Memberships +Interface RefCnt Group +--------------- ------ --------------------- +lo 1 224.0.0.1 +ens33 1 224.0.0.251 +ens33 1 224.0.0.1 +virbr0 1 224.0.0.251 +virbr0 1 224.0.0.1 +``` + +- 显示网络统计信息 + +```javascript +[root@LVS ~]# netstat -s +Ip: + 118440 total packets received + 0 forwarded + 0 incoming packets discarded + 20653 incoming packets delivered + 15660 requests sent out + 31 outgoing packets dropped + 28 dropped because of missing route + 2 fragments received ok + 4 fragments created +Icmp: + 90 ICMP messages received + 0 input ICMP message failed. +``` + +- 显示监听的套接口 + +```javascript +[root@LVS ~]# netstat -l +Active Internet connections (only servers) +Proto Recv-Q Send-Q Local Address Foreign Address State +tcp 0 0 0.0.0.0:sunrpc 0.0.0.0:* LISTEN +tcp 0 0 LVS:domain 0.0.0.0:* LISTEN +tcp 0 0 0.0.0.0:ssh 0.0.0.0:* LISTEN +tcp 0 0 localhost:ipp 0.0.0.0:* LISTEN +tcp 0 0 localhost:6011 0.0.0.0:* LISTEN +tcp 0 0 localhost:6012 0.0.0.0:* LISTEN +tcp 0 0 localhost:6013 0.0.0.0:* LISTEN +tcp 0 0 localhost:6014 0.0.0.0:* LISTEN +``` + +### 九、高级网络操作命令 + +#### 9.1 ss + +功能:查看网络状态。 + +ss是Socket Statistics的缩写。顾名思义,ss命令可以用来获取socket统计信息,它可以显示和netstat类似的内容。ss的优势在于它能够显示更多更详细的有关TCP和连接状态的信息,而且比netstat更快速更高效。 + +当服务器的socket连接数量变得非常大时,无论是使用netstat命令还是直接cat /proc/net/tcp,执行速度都会很慢。 + +ss快的秘诀在于,它利用到了TCP协议栈中tcp_diag。tcp_diag是一个用于分析统计的模块,可以获得Linux 内核中第一手的信息,这就确保了ss的快捷高效。 + +语法: + +```javascript +ss [ OPTIONS ] +ss [ OPTIONS ] [ FILTER ] +``` + +参数: + +```javascript + -h, --help this message + -V, --version output version information + -n, --numeric don't resolve service names + -r, --resolve resolve host names + -a, --all display all sockets + -l, --listening display listening sockets + -o, --options show timer information + -e, --extended show detailed socket information + -m, --memory show socket memory usage + -p, --processes show process using socket + -i, --info show internal TCP information + -s, --summary show socket usage summary + -b, --bpf show bpf filter socket information + -Z, --context display process SELinux security contexts + -z, --contexts display process and socket SELinux security contexts + -N, --net switch to the specified network namespace name + + -4, --ipv4 display only IP version 4 sockets + -6, --ipv6 display only IP version 6 sockets + -0, --packet display PACKET sockets + -t, --tcp display only TCP sockets + -u, --udp display only UDP sockets + -d, --dccp display only DCCP sockets + -w, --raw display only RAW sockets + -x, --unix display only Unix domain sockets + -f, --family=FAMILY display sockets of type FAMILY +``` + +实例: + +- 显示TCP连接 + +```javascript +[root@LVS ~]# ss -t -a +State Recv-Q Send-Q Local Address:Port Peer Address:Port +LISTEN 0 128 *:sunrpc *:* +LISTEN 0 5 192.168.122.1:domain *:* +LISTEN 0 128 *:ssh *:* +LISTEN 0 128 127.0.0.1:ipp *:* +LISTEN 0 128 127.0.0.1:x11-ssh-offset *:* +LISTEN 0 128 127.0.0.1:6011 *:* +LISTEN 0 128 127.0.0.1:6012 *:* +LISTEN 0 128 127.0.0.1:6013 *:* +LISTEN 0 128 127.0.0.1:6014 *:* +ESTAB 0 0 192.168.100.106:ssh 192.168.100.103:59804 +ESTAB 0 0 192.168.100.106:ssh 192.168.100.103:53121 +ESTAB 0 0 192.168.100.106:ssh 192.168.100.103:59822 +ESTAB 0 52 192.168.100.106:ssh 192.168.100.103:60220 +ESTAB 0 0 192.168.100.106:ssh 192.168.100.103:59744 +LISTEN 0 128 :::sunrpc :::* +LISTEN 0 128 :::ssh :::* +LISTEN 0 128 :::telnet :::* +LISTEN 0 128 ::1:ipp :::* +LISTEN 0 128 ::1:x11-ssh-offset :::* +LISTEN 0 128 ::1:6011 :::* +LISTEN 0 128 ::1:6012 :::* +LISTEN 0 128 ::1:6013 :::* +LISTEN 0 128 ::1:6014 :::* +``` + +[root@LVS ~] + +\# + +#### 9.2 tcpdump + +功能:抓包工具 + +语法: + +```javascript +tcpdump [-adeflnNOpqStvx][-c<数据包数目>][-dd][-ddd][-F<表达文件>][-i<网络界面>][-r<数据包文件>][-s<数据包大小>][-tt][-T<数据包类型>][-vv][-w<数据包文件>][输出数据栏位] +``` + +参数: + +```javascript +-a 尝试将网络和广播地址转换成名称。 +-c<数据包数目> 收到指定的数据包数目后,就停止进行倾倒操作。 +-d 把编译过的数据包编码转换成可阅读的格式,并倾倒到标准输出。 +-dd 把编译过的数据包编码转换成C语言的格式,并倾倒到标准输出。 +-ddd 把编译过的数据包编码转换成十进制数字的格式,并倾倒到标准输出。 +-e 在每列倾倒资料上显示连接层级的文件头。 +-f 用数字显示网际网络地址。 +-F<表达文件> 指定内含表达方式的文件。 +-i<网络界面> 使用指定的网络截面送出数据包。 +-l 使用标准输出列的缓冲区。 +-n 不把主机的网络地址转换成名字。 +-N 不列出域名。 +-O 不将数据包编码最佳化。 +-p 不让网络界面进入混杂模式。 +-q 快速输出,仅列出少数的传输协议信息。 +-r<数据包文件> 从指定的文件读取数据包数据。 +-s<数据包大小> 设置每个数据包的大小。 +-S 用绝对而非相对数值列出TCP关联数。 +-t 在每列倾倒资料上不显示时间戳记。 +-tt 在每列倾倒资料上显示未经格式化的时间戳记。 +-T<数据包类型> 强制将表达方式所指定的数据包转译成设置的数据包类型。 +-v 详细显示指令执行过程。 +-vv 更详细显示指令执行过程。 +-x 用十六进制字码列出数据包资料。 +-w<数据包文件> 把数据包数据写入指定的文件。 +``` + +实例: + +- 显示TCP包信息 + +```javascript +[root@LVS ~]# tcpdump +tcpdump: verbose output suppressed, use -v or -vv for full protocol decode +listening on virbr0, link-type EN10MB (Ethernet), capture size 65535 bytes +``` + +- 显示指定数量包 + +```javascript +[root@LVS ~]# tcpdump -c 10 +``` + +- 转换阅读格式 + +```javascript +[root@LVS ~]# tcpdump -d +(000) ret #65535 +``` + +[root@LVS ~] + +\# + +#### 9.3 nmap + +功能:也就是Network Mapper,是Linux下的网络扫描和嗅探工具包。 + +语法: + +```javascript +nmap [Scan Type(s)] [Options] {target specification} +``` + +参数: + +```javascript +TARGET SPECIFICATION: + Can pass hostnames, IP addresses, networks, etc. + Ex: scanme.nmap.org, microsoft.com/24, 192.168.0.1; 10.0.0-255.1-254 + -iL : Input from list of hosts/networks + -iR : Choose random targets + --exclude : Exclude hosts/networks + --excludefile : Exclude list from file +HOST DISCOVERY: + -sL: List Scan - simply list targets to scan + -sn: Ping Scan - disable port scan + -Pn: Treat all hosts as online -- skip host discovery + -PS/PA/PU/PY[portlist]: TCP SYN/ACK, UDP or SCTP discovery to given ports + -PE/PP/PM: ICMP echo, timestamp, and netmask request discovery probes + -PO[protocol list]: IP Protocol Ping + -n/-R: Never do DNS resolution/Always resolve [default: sometimes] + --dns-servers : Specify custom DNS servers + --system-dns: Use OS's DNS resolver + --traceroute: Trace hop path to each host +SCAN TECHNIQUES: + -sS/sT/sA/sW/sM: TCP SYN/Connect()/ACK/Window/Maimon scans + -sU: UDP Scan + -sN/sF/sX: TCP Null, FIN, and Xmas scans + --scanflags : Customize TCP scan flags + -sI : Idle scan + -sY/sZ: SCTP INIT/COOKIE-ECHO scans + -sO: IP protocol scan + -b : FTP bounce scan +PORT SPECIFICATION AND SCAN ORDER: + -p : Only scan specified ports + Ex: -p22; -p1-65535; -p U:53,111,137,T:21-25,80,139,8080,S:9 + -F: Fast mode - Scan fewer ports than the default scan + -r: Scan ports consecutively - don't randomize + --top-ports : Scan most common ports + --port-ratio : Scan ports more common than +SERVICE/VERSION DETECTION: + -sV: Probe open ports to determine service/version info + --version-intensity : Set from 0 (light) to 9 (try all probes) + --version-light: Limit to most likely probes (intensity 2) + --version-all: Try every single probe (intensity 9) + --version-trace: Show detailed version scan activity (for debugging) +SCRIPT SCAN: + -sC: equivalent to --script=default + --script=: is a comma separated list of + directories, script-files or script-categories + --script-args=: provide arguments to scripts + --script-args-file=filename: provide NSE script args in a file + --script-trace: Show all data sent and received + --script-updatedb: Update the script database. + --script-help=: Show help about scripts. + is a comma separted list of script-files or + script-categories. +OS DETECTION: + -O: Enable OS detection + --osscan-limit: Limit OS detection to promising targets + --osscan-guess: Guess OS more aggressively +TIMING AND PERFORMANCE: + Options which take